first commit
This commit is contained in:
@@ -0,0 +1,191 @@
|
||||
<!--
|
||||
* 平台软件
|
||||
-->
|
||||
<template>
|
||||
<view class="sub-page">
|
||||
<nav-bar title="平台软件" :show-back="true" @back="closeSub()" />
|
||||
|
||||
<scroll-view scroll-y class="page-content">
|
||||
<!-- Clients -->
|
||||
<text class="section-title">客户端下载</text>
|
||||
|
||||
<view class="client-card" v-for="(item, i) in downloads" :key="i">
|
||||
<view class="cc-left">
|
||||
<view class="cc-icon-wrap" :style="{ background: item.platform === 'windows' ? '#d1fae5' : '#dbeafe' }">
|
||||
<text class="cc-icon">{{ item.platform === 'windows' ? '🪟' : '🐧' }}</text>
|
||||
</view>
|
||||
<view class="cc-info">
|
||||
<text class="cc-name">{{ item.name }}</text>
|
||||
<text class="cc-version">v{{ item.version }}</text>
|
||||
<text class="cc-downloads">{{ formatThousands(item.download_count) }} 次下载</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="cc-btn" @click="downloadFile(item)">下载</view>
|
||||
</view>
|
||||
|
||||
<view v-if="downloads.length === 0" class="client-card" style="justify-content:center;">
|
||||
<text style="color:#999;font-size:26rpx;">暂无可用客户端</text>
|
||||
</view>
|
||||
<view class="load-more" v-if="hasMore" @click="loadMore">
|
||||
<text>{{ loadingMore ? '加载中...' : '加载更多' }}</text>
|
||||
</view>
|
||||
|
||||
<!-- Changelog -->
|
||||
<view class="changelog-card" v-if="allChangelogs.length">
|
||||
<text class="section-title">更新日志</text>
|
||||
|
||||
<view v-for="(log, i) in allChangelogs" :key="i" class="cl-item">
|
||||
<view class="cl-header">
|
||||
<text class="cl-version">{{ log.version }}</text>
|
||||
<text class="cl-date">{{ log.date }}</text>
|
||||
</view>
|
||||
<text class="cl-change">{{ log.changelog }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import NavBar from '@/components/NavBar.vue'
|
||||
import { ref, computed } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import { closeSub, parseSubParams } from '@/composables/useNavigation'
|
||||
import { formatThousands } from '@/utils/util'
|
||||
import request from '@/utils/request'
|
||||
|
||||
const downloads = ref([])
|
||||
const page = ref(1)
|
||||
const hasMore = ref(false)
|
||||
const loadingMore = ref(false)
|
||||
|
||||
onLoad(async (options) => {
|
||||
const params = parseSubParams(options)
|
||||
await fetchDownloads(1)
|
||||
})
|
||||
|
||||
const fetchDownloads = async (pageNum = 1) => {
|
||||
try {
|
||||
const res = await request.get('/c/downloads', { page: pageNum, showLoading: false })
|
||||
const items = res.data?.items || []
|
||||
downloads.value = pageNum === 1 ? items : downloads.value.concat(items)
|
||||
page.value = res.data?.current_page || pageNum
|
||||
hasMore.value = page.value < (res.data?.last_page || 1)
|
||||
} catch (e) { /* 忽略 */ }
|
||||
}
|
||||
|
||||
const loadMore = async () => {
|
||||
if (!hasMore.value || loadingMore.value) return
|
||||
loadingMore.value = true
|
||||
try { await fetchDownloads(page.value + 1) } finally { loadingMore.value = false }
|
||||
}
|
||||
|
||||
const goBack = () => closeSub()
|
||||
|
||||
const downloadFile = (item) => {
|
||||
if (item.file_path) {
|
||||
uni.showToast({ title: '开始下载 ' + item.name, icon: 'none' })
|
||||
} else {
|
||||
uni.showToast({ title: '暂无下载链接', icon: 'none' })
|
||||
}
|
||||
}
|
||||
|
||||
// 合并所有软件的更新日志,按日期倒序
|
||||
const allChangelogs = computed(() => {
|
||||
const logs = []
|
||||
downloads.value.forEach(d => {
|
||||
if (d.changelogs && d.changelogs.length) {
|
||||
d.changelogs.forEach(v => logs.push({ ...v, software: d.name }))
|
||||
}
|
||||
})
|
||||
logs.sort((a, b) => (b.date || '').localeCompare(a.date || ''))
|
||||
return logs
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.sub-page {
|
||||
min-height: 100vh;
|
||||
background: #F2F4F8;
|
||||
}
|
||||
.load-more { text-align: center; padding: 24rpx 0 40rpx; font-size: 24rpx; color: #1677FF; }
|
||||
.page-content {
|
||||
height: calc(100vh - 44px);
|
||||
padding: 20rpx 30rpx 40rpx;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 30rpx;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
display: block;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.client-card {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
background: #fff;
|
||||
border-radius: 16rpx;
|
||||
padding: 30rpx;
|
||||
margin-bottom: 16rpx;
|
||||
.cc-left { display: flex; align-items: center; gap: 20rpx; flex: 1; }
|
||||
.cc-icon-wrap {
|
||||
width: 72rpx; height: 72rpx; border-radius: 36rpx;
|
||||
display: flex; align-items: center; justify-content: center; flex-shrink: 0;
|
||||
}
|
||||
.cc-icon { font-size: 32rpx; }
|
||||
.cc-info { flex: 1; }
|
||||
.cc-name { font-size: 28rpx; font-weight: 500; color: #333; display: block; }
|
||||
.cc-version { font-size: 22rpx; color: #999; display: block; margin: 4rpx 0; }
|
||||
.cc-downloads { font-size: 22rpx; color: #999; }
|
||||
.cc-btn {
|
||||
padding: 12rpx 36rpx;
|
||||
background: linear-gradient(135deg, #3b82f6, #2563eb);
|
||||
color: #fff;
|
||||
font-size: 26rpx;
|
||||
border-radius: 32rpx;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.changelog-card {
|
||||
background: #fff;
|
||||
border-radius: 16rpx;
|
||||
padding: 30rpx;
|
||||
margin-top: 20rpx;
|
||||
.cl-item {
|
||||
margin-bottom: 24rpx;
|
||||
&:last-child { margin-bottom: 0; }
|
||||
}
|
||||
.cl-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16rpx;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
.cl-version {
|
||||
font-size: 28rpx; font-weight: 600; color: #3b82f6;
|
||||
}
|
||||
.cl-date { font-size: 22rpx; color: #999; }
|
||||
.cl-change {
|
||||
display: block;
|
||||
font-size: 26rpx;
|
||||
color: #666;
|
||||
padding: 6rpx 0;
|
||||
padding-left: 20rpx;
|
||||
position: relative;
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 16rpx;
|
||||
width: 8rpx;
|
||||
height: 8rpx;
|
||||
background: #d1d5db;
|
||||
border-radius: 4rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user