From 07fc182ccb35f91cb363bf6fb3a861e941e5cd7e Mon Sep 17 00:00:00 2001 From: keven Date: Sun, 19 Oct 2025 18:20:38 +0800 Subject: [PATCH] feat(front): enhance About page components to support shares and downloads statistics, improve layout, and add loading state --- front/components/About/AboutBaseInfo.vue | 20 +++++- front/components/About/AboutChartView.vue | 84 +++++++++++++++++------ front/i18n/locales/en.json | 3 + front/i18n/locales/zh-CN.json | 3 + 4 files changed, 89 insertions(+), 21 deletions(-) diff --git a/front/components/About/AboutBaseInfo.vue b/front/components/About/AboutBaseInfo.vue index f987719..15762b7 100644 --- a/front/components/About/AboutBaseInfo.vue +++ b/front/components/About/AboutBaseInfo.vue @@ -24,6 +24,7 @@ const { data, isLoading } = useQuery({ name?: string email?: string url?: string + content?: Record } }>('/api/about') return data?.data @@ -65,7 +66,7 @@ const genUserAvatar = (email: string) => { + + diff --git a/front/components/About/AboutChartView.vue b/front/components/About/AboutChartView.vue index 09ad79f..50a249a 100644 --- a/front/components/About/AboutChartView.vue +++ b/front/components/About/AboutChartView.vue @@ -8,9 +8,11 @@ import AboutChartTooltip from '@/components/AboutChartTooltip.vue' import dayjs from 'dayjs' import { times } from 'lodash-es' -interface FileChartData { +interface StatChartData { file_size: number file_num: number + share_num: number + download_num: number date: string } @@ -20,7 +22,7 @@ interface QueueChartData { date: string } -type ChartDataItem = FileChartData | QueueChartData +type ChartDataItem = StatChartData | QueueChartData type ChartConfig = { data: ChartDataItem[] @@ -35,7 +37,7 @@ const { data, isLoading } = useQuery({ const response = await $fetch<{ data: { chart: { - storage: Record + storage: Record queue: Record } } @@ -52,7 +54,21 @@ const chartTabs = computed(() => { label: t('about.file'), value: 'storage', total: data.value?.chart?.storage - ? Object.values(data.value.chart.storage).reduce((acc: number, curr: FileChartData) => acc + curr.file_num, 0) + ? Object.values(data.value.chart.storage).reduce((acc: number, curr: StatChartData) => acc + curr.file_num, 0) + : 0, + }, + { + label: t('about.share'), + value: 'share', + total: data.value?.chart?.storage + ? Object.values(data.value.chart.storage).reduce((acc: number, curr: StatChartData) => acc + curr.share_num, 0) + : 0, + }, + { + label: t('about.download'), + value: 'download', + total: data.value?.chart?.storage + ? Object.values(data.value.chart.storage).reduce((acc: number, curr: StatChartData) => acc + curr.download_num, 0) : 0, }, { @@ -65,36 +81,64 @@ const chartTabs = computed(() => { ] }) -const currentChartTab = ref<'storage' | 'queue'>('storage') +const currentChartTab = ref<'storage' | 'queue' | 'share' | 'download'>('storage') const currentChartData = computed((): ChartConfig => { const { storage, queue } = data.value?.chart || {} - if (currentChartTab.value === 'storage') { - const storageData = times(30, (i) => { + if (currentChartTab.value === 'queue') { + const queueData = times(30, (i) => { return { date: dayjs().subtract(i, 'day').format('YYYY-MM-DD'), - file_size: storage?.[dayjs().subtract(i, 'day').format('YYYY-MM-DD')]?.file_size || 0, - file_num: storage?.[dayjs().subtract(i, 'day').format('YYYY-MM-DD')]?.file_num || 0, + processed: queue?.[dayjs().subtract(i, 'day').format('YYYY-MM-DD')]?.processed || 0, + failed: queue?.[dayjs().subtract(i, 'day').format('YYYY-MM-DD')]?.failed || 0, } }) return { - data: storageData, + data: queueData, index: 'date' as const, - categories: ['file_size', 'file_num'] as const, - colors: ['#22d3ee', '#c084fc'], + categories: ['processed', 'failed'] as const, + colors: ['#4ade80', '#f87171'], } } - const queueData = times(30, (i) => { + const storageData = times(30, (i) => { + const base = { date: dayjs().subtract(i, 'day').format('YYYY-MM-DD') } + if (currentChartTab.value === 'share') { + return { + ...base, + share_num: storage?.[dayjs().subtract(i, 'day').format('YYYY-MM-DD')]?.share_num || 0, + } + } + if (currentChartTab.value === 'download') { + return { + ...base, + download_num: storage?.[dayjs().subtract(i, 'day').format('YYYY-MM-DD')]?.download_num || 0, + } + } return { - date: dayjs().subtract(i, 'day').format('YYYY-MM-DD'), - processed: queue?.[dayjs().subtract(i, 'day').format('YYYY-MM-DD')]?.processed || 0, - failed: queue?.[dayjs().subtract(i, 'day').format('YYYY-MM-DD')]?.failed || 0, + ...base, + file_size: storage?.[dayjs().subtract(i, 'day').format('YYYY-MM-DD')]?.file_size || 0, + file_num: storage?.[dayjs().subtract(i, 'day').format('YYYY-MM-DD')]?.file_num || 0, } }) + + let categories = ['file_size', 'file_num'] + if (currentChartTab.value === 'share') { + categories = ['share_num'] + } + if (currentChartTab.value === 'download') { + categories = ['download_num'] + } + let colors = ['#38bdf8', '#a78bfa'] + if (currentChartTab.value === 'share') { + colors = ['#ea580c'] + } + if (currentChartTab.value === 'download') { + colors = ['#a3e635'] + } return { - data: queueData, + data: storageData as ChartDataItem[], index: 'date' as const, - categories: ['processed', 'failed'] as const, - colors: ['#4ade80', '#f87171'], + categories, + colors, } }) @@ -108,7 +152,7 @@ const currentChartData = computed((): ChartConfig => {