diff --git a/cwd-admin/src/api/admin.ts b/cwd-admin/src/api/admin.ts index f3c1396..55dcd48 100644 --- a/cwd-admin/src/api/admin.ts +++ b/cwd-admin/src/api/admin.ts @@ -21,6 +21,7 @@ export type CommentItem = { priority?: number; likes?: number; ua?: string | null; + isAdmin?: boolean; }; export type CommentListResponse = { diff --git a/cwd-admin/src/styles/components/stats.less b/cwd-admin/src/styles/components/stats.less index fc5394b..2f712d7 100644 --- a/cwd-admin/src/styles/components/stats.less +++ b/cwd-admin/src/styles/components/stats.less @@ -88,10 +88,16 @@ color: var(--color-danger); } +.domain-stats-layout { + display: flex; + align-items: stretch; + gap: 16px; +} + .domain-table-wrapper { - width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch; + flex: 1; } .domain-table { @@ -125,6 +131,19 @@ font-weight: 500; } +.domain-pie-wrapper { + width: 40%; + display: flex; + align-items: center; + justify-content: center; +} + +.domain-pie-chart { + width: 100%; + max-width: 400px; + height: 260px; +} + .chart-wrapper { margin-top: 4px; } @@ -138,4 +157,12 @@ .stats-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } -} \ No newline at end of file + + .domain-stats-layout { + flex-direction: column; + } + + .domain-pie-wrapper { + width: 100%; + } +} diff --git a/cwd-admin/src/views/StatsView/index.vue b/cwd-admin/src/views/StatsView/index.vue index 252ae9b..caa9a5f 100644 --- a/cwd-admin/src/views/StatsView/index.vue +++ b/cwd-admin/src/views/StatsView/index.vue @@ -79,27 +79,32 @@
加载中...
{{ statsError }}
暂无评论数据
-
-
-
-
域名
-
总数
-
已通过
-
待审核
-
已拒绝
-
-
-
{{ item.domain }}
-
{{ item.total }}
-
{{ item.approved }}
-
{{ item.pending }}
-
{{ item.rejected }}
+
+
+
+
+
域名
+
总数
+
已通过
+
待审核
+
已拒绝
+
+
+
{{ item.domain }}
+
{{ item.total }}
+
{{ item.approved }}
+
{{ item.pending }}
+
{{ item.rejected }}
+
+
+
+
@@ -140,7 +145,9 @@ const toastType = ref<"success" | "error">("success"); const toastVisible = ref(false); const chartEl = ref(null); +const domainPieEl = ref(null); let chartInstance: echarts.ECharts | null = null; +let domainPieChartInstance: echarts.ECharts | null = null; function loadChartRangeFromStorage() { if (typeof window === "undefined") { @@ -196,6 +203,7 @@ async function loadStats() { await nextTick(); if (!statsError.value) { renderChart(); + renderDomainPieChart(); } } } @@ -258,6 +266,45 @@ function renderChart() { chartInstance.setOption(option); } +function renderDomainPieChart() { + const el = domainPieEl.value; + if (!el) { + return; + } + if (!domainPieChartInstance) { + domainPieChartInstance = echarts.init(el); + } + if (!domainStats.value.length) { + domainPieChartInstance.clear(); + return; + } + const source = domainStats.value.slice().sort((a, b) => b.total - a.total); + const data = source.map((item) => ({ + name: item.domain || "未知", + value: item.total, + })); + const option: echarts.EChartsOption = { + tooltip: { + trigger: "item", + formatter: "{b}: {c} ({d}%)", + }, + legend: { + orient: "vertical", + left: "left", + }, + series: [ + { + type: "pie", + radius: ["40%", "70%"], + center: ["60%", "50%"], + avoidLabelOverlap: false, + data, + }, + ], + }; + domainPieChartInstance.setOption(option); +} + function changeChartRange(range: "7" | "30") { if (chartRange.value === range) { return; @@ -265,12 +312,16 @@ function changeChartRange(range: "7" | "30") { chartRange.value = range; saveChartRangeToStorage(range); renderChart(); + renderDomainPieChart(); } function handleResize() { if (chartInstance) { chartInstance.resize(); } + if (domainPieChartInstance) { + domainPieChartInstance.resize(); + } } onMounted(() => { @@ -289,6 +340,10 @@ onBeforeUnmount(() => { chartInstance.dispose(); chartInstance = null; } + if (domainPieChartInstance) { + domainPieChartInstance.dispose(); + domainPieChartInstance = null; + } });