import { reactive } from 'vue' import { StatsService } from '@/services' import type { DashboardViewData } from '@/types' import { formatFileSize } from '@/utils/common' const emptyDashboardData = (): DashboardViewData => ({ hasExtendedStats: false, totalFiles: 0, storageUsed: 0, yesterdayCount: 0, todayCount: 0, yesterdaySize: 0, todaySize: 0, sysUptime: null, activeCount: 0, expiredCount: 0, textCount: 0, fileCount: 0, chunkedCount: 0, usedCount: 0, storageBackend: '-', uploadSizeLimit: 0, openUpload: 0, enableChunk: 0, maxSaveSeconds: 0, topSuffixes: [], recentFiles: [], storageUsedText: '0 Bytes', yesterdaySizeText: '0 Bytes', todaySizeText: '0 Bytes', uploadSizeLimitText: '0 Bytes', sysUptimeText: '-', activeRatio: 0, textRatio: 0, fileRatio: 0, todaySizeRatio: 0 }) const toNumber = (value: number | string | null | undefined) => Number(value || 0) const clampRatio = (value: number) => Math.max(0, Math.min(100, Math.round(value))) const hasOwn = (target: object, key: string) => Object.prototype.hasOwnProperty.call(target, key) const formatDuration = (startTimestamp: number | null) => { if (!startTimestamp) return '-' const uptime = Date.now() - startTimestamp const days = Math.floor(uptime / (24 * 60 * 60 * 1000)) const hours = Math.floor((uptime % (24 * 60 * 60 * 1000)) / (60 * 60 * 1000)) return `${days}天${hours}小时` } export function useDashboardStats() { const dashboardData = reactive(emptyDashboardData()) const fetchDashboardData = async () => { const response = await StatsService.getDashboard() if (!response.detail) return const detail = response.detail dashboardData.totalFiles = toNumber(detail.totalFiles) dashboardData.storageUsed = toNumber(detail.storageUsed) dashboardData.yesterdayCount = toNumber(detail.yesterdayCount) dashboardData.todayCount = toNumber(detail.todayCount) dashboardData.yesterdaySize = toNumber(detail.yesterdaySize) dashboardData.todaySize = toNumber(detail.todaySize) dashboardData.sysUptime = detail.sysUptime dashboardData.hasExtendedStats = hasOwn(detail, 'activeCount') dashboardData.activeCount = dashboardData.hasExtendedStats ? toNumber(detail.activeCount) : dashboardData.totalFiles dashboardData.expiredCount = toNumber(detail.expiredCount) dashboardData.textCount = toNumber(detail.textCount) dashboardData.fileCount = toNumber(detail.fileCount) dashboardData.chunkedCount = toNumber(detail.chunkedCount) dashboardData.usedCount = toNumber(detail.usedCount) dashboardData.storageBackend = detail.storageBackend || '-' dashboardData.uploadSizeLimit = toNumber(detail.uploadSizeLimit) dashboardData.openUpload = toNumber(detail.openUpload) dashboardData.enableChunk = toNumber(detail.enableChunk) dashboardData.maxSaveSeconds = toNumber(detail.maxSaveSeconds) dashboardData.topSuffixes = detail.topSuffixes || [] dashboardData.recentFiles = detail.recentFiles || [] dashboardData.storageUsedText = formatFileSize(dashboardData.storageUsed) dashboardData.yesterdaySizeText = formatFileSize(dashboardData.yesterdaySize) dashboardData.todaySizeText = formatFileSize(dashboardData.todaySize) dashboardData.uploadSizeLimitText = formatFileSize(dashboardData.uploadSizeLimit) dashboardData.sysUptimeText = formatDuration(dashboardData.sysUptime) dashboardData.activeRatio = dashboardData.totalFiles ? clampRatio((dashboardData.activeCount / dashboardData.totalFiles) * 100) : 0 dashboardData.textRatio = dashboardData.totalFiles ? clampRatio((dashboardData.textCount / dashboardData.totalFiles) * 100) : 0 dashboardData.fileRatio = dashboardData.totalFiles ? clampRatio((dashboardData.fileCount / dashboardData.totalFiles) * 100) : 0 dashboardData.todaySizeRatio = dashboardData.uploadSizeLimit ? clampRatio((dashboardData.todaySize / dashboardData.uploadSizeLimit) * 100) : 0 } return { dashboardData, fetchDashboardData } }