diff --git a/src/views/dashboard/index.vue b/src/views/dashboard/index.vue index 6d0a26f9..e71679ca 100644 --- a/src/views/dashboard/index.vue +++ b/src/views/dashboard/index.vue @@ -1,6 +1,5 @@ @@ -111,26 +112,25 @@
{{ item.todayCount }} - {{ Math.abs(item.growthRate * 100).toFixed(2) }}% + {{ formatGrowthRate(item.growthRate) }}
- +
总{{ item.title }} - {{ item.totalCountOutput }} + {{ item.totalCount }}
@@ -168,8 +168,6 @@ defineOptions({ inheritAttrs: false, }); -import type { EpPropMergeType } from "element-plus/es/utils/vue/props/types"; - import { useUserStore } from "@/store/modules/user"; import { useTransition, TransitionPresets } from "@vueuse/core"; @@ -202,7 +200,7 @@ const statisticData = ref([ }, { value: 50, - iconClass: "todolist", + iconClass: "todo", title: "待办", suffix: "/100", key: "upcoming", @@ -244,24 +242,80 @@ const notices = ref([ const loading = ref(true); -const visitStatsList = ref(Array(3).fill({})); +const visitStatsList = ref(Array(3).fill({})); + +interface VisitStats { + title: string; + icon: string; + tagType: "primary" | "success" | "warning"; + growthRate: number; + /** 粒度 */ + granularity: string; + /** 今日数量输出文档 */ + todayCount: number; + totalCount: number; +} const loadVisitStatsData = async () => { - const list = await StatsAPI.getVisitStats(); + const list: VisitStatsVO[] = await StatsAPI.getVisitStats(); if (list) { - visitStatsList.value = list; - // 初始化动画输出 - list.forEach((item) => { - item.totalCountOutput = useTransition(item.totalCount, { - duration: 1000, - transition: TransitionPresets.easeOutExpo, - }).value; - }); + const tagTypes: ("primary" | "success" | "warning")[] = [ + "primary", + "success", + "warning", + ]; + const transformedList: VisitStats[] = list.map((item, index) => ({ + title: item.title, + icon: getVisitStatsIcon(item.type), + tagType: tagTypes[index % tagTypes.length], + growthRate: item.growthRate, + granularity: "日", + todayCount: item.todayCount, + totalCount: item.totalCount, + })); + visitStatsList.value = transformedList; loading.value = false; } }; +/** 格式化增长率 */ +const formatGrowthRate = (growthRate: number): string => { + if (growthRate === 0) { + return "-"; + } + + const formattedRate = Math.abs(growthRate * 100) + .toFixed(2) + .replace(/\.?0+$/, ""); + return formattedRate + "%"; +}; + +/** 获取增长率文本颜色类 */ +const getGrowthRateClass = (growthRate: number): string => { + if (growthRate > 0) { + return "color-[--el-color-danger]"; + } else if (growthRate < 0) { + return "color-[--el-color-success]"; + } else { + return "color-[--el-color-info]"; + } +}; + +/** 获取访问统计图标 */ +const getVisitStatsIcon = (type: string) => { + switch (type) { + case "pv": + return "pv"; + case "uv": + return "uv"; + case "ip": + return "ip"; + default: + return "pv"; + } +}; + onMounted(() => { loadVisitStatsData(); });