From 943225cc7ff9a8e4bd34179420c4d9df52f12726 Mon Sep 17 00:00:00 2001 From: anghunk Date: Wed, 21 Jan 2026 13:30:59 +0800 Subject: [PATCH] =?UTF-8?q?feat(admin):=20=E6=B7=BB=E5=8A=A0=E8=AF=84?= =?UTF-8?q?=E8=AE=BA=E6=95=B0=E6=8D=AE=E7=9C=8B=E6=9D=BF=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增数据看板页面,展示评论统计信息 - 添加 echarts 依赖用于数据可视化 - 实现后端统计接口,包括总数、按域名和最近7天数据 - 完善前端统计页面样式和交互 - 更新文档说明和版本更新指南 --- cwd-admin/package.json | 3 +- cwd-admin/src/api/admin.ts | 24 ++ cwd-admin/src/router/index.ts | 7 +- cwd-admin/src/views/DataView.vue | 66 ++++++ cwd-admin/src/views/LayoutView.vue | 12 + cwd-admin/src/views/StatsView.vue | 339 +++++++++++++++++++++++++++++ cwd-api/src/api/admin/getStats.ts | 133 +++++++++++ cwd-api/src/index.ts | 2 + docs/guide/update-version.md | 10 +- docs/index.md | 2 +- 10 files changed, 592 insertions(+), 6 deletions(-) create mode 100644 cwd-admin/src/views/StatsView.vue create mode 100644 cwd-api/src/api/admin/getStats.ts diff --git a/cwd-admin/package.json b/cwd-admin/package.json index 6f592c3..ae3e89c 100644 --- a/cwd-admin/package.json +++ b/cwd-admin/package.json @@ -12,7 +12,8 @@ }, "dependencies": { "vue": "^3.5.13", - "vue-router": "^4.4.5" + "vue-router": "^4.4.5", + "echarts": "^5.5.0" }, "devDependencies": { "@vitejs/plugin-vue": "^5.1.4", diff --git a/cwd-admin/src/api/admin.ts b/cwd-admin/src/api/admin.ts index e91e3f9..5d86a8c 100644 --- a/cwd-admin/src/api/admin.ts +++ b/cwd-admin/src/api/admin.ts @@ -62,6 +62,26 @@ export type EmailNotifySettingsResponse = { }; }; +export type CommentStatsResponse = { + summary: { + total: number; + approved: number; + pending: number; + rejected: number; + }; + domains: { + domain: string; + total: number; + approved: number; + pending: number; + rejected: number; + }[]; + last7Days: { + date: string; + total: number; + }[]; +}; + export async function loginAdmin(name: string, password: string): Promise { const res = await post('/admin/login', { name, password }); const key = res.data.key; @@ -160,3 +180,7 @@ export function exportComments(): Promise { export function importComments(data: any[]): Promise<{ message: string }> { return post<{ message: string }>('/admin/comments/import', data); } + +export function fetchCommentStats(): Promise { + return get('/admin/stats/comments'); +} diff --git a/cwd-admin/src/router/index.ts b/cwd-admin/src/router/index.ts index 55c5e4b..52dc22e 100644 --- a/cwd-admin/src/router/index.ts +++ b/cwd-admin/src/router/index.ts @@ -4,6 +4,7 @@ import LayoutView from '../views/LayoutView.vue'; import CommentsView from '../views/CommentsView.vue'; import SettingsView from '../views/SettingsView.vue'; import DataView from '../views/DataView.vue'; +import StatsView from '../views/StatsView.vue'; const routes: RouteRecordRaw[] = [ { @@ -24,6 +25,11 @@ const routes: RouteRecordRaw[] = [ name: 'comments', component: CommentsView }, + { + path: 'stats', + name: 'stats', + component: StatsView + }, { path: 'settings', name: 'settings', @@ -55,4 +61,3 @@ router.beforeEach((to, from, next) => { } next(); }); - diff --git a/cwd-admin/src/views/DataView.vue b/cwd-admin/src/views/DataView.vue index c8084fc..a4c256f 100644 --- a/cwd-admin/src/views/DataView.vue +++ b/cwd-admin/src/views/DataView.vue @@ -425,6 +425,72 @@ async function executeImport(comments: any[]) { font-size: 15px; } +.stats-grid { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 12px; +} + +.stats-item { + padding: 10px 12px; + border-radius: 6px; + background-color: #f6f8fa; + border: 1px solid #d0d7de; +} + +.stats-label { + font-size: 12px; + color: #57606a; + margin-bottom: 4px; +} + +.stats-value { + font-size: 18px; + font-weight: 600; + color: #24292f; +} + +.stats-value-approved { + color: #1a7f37; +} + +.stats-value-pending { + color: #9a6700; +} + +.stats-value-rejected { + color: #d1242f; +} + +.domain-table { + border: 1px solid #d0d7de; + border-radius: 6px; + overflow: hidden; +} + +.domain-table-header { + display: flex; + background-color: #f6f8fa; +} + +.domain-table-row { + display: flex; + border-top: 1px solid #eaeae0; +} + +.domain-cell { + flex: 1; + padding: 8px 10px; + font-size: 13px; + color: #24292f; + box-sizing: border-box; +} + +.domain-cell-domain { + flex: 2; + font-weight: 500; +} + .card-desc { font-size: 14px; color: #57606a; diff --git a/cwd-admin/src/views/LayoutView.vue b/cwd-admin/src/views/LayoutView.vue index 7b7cb48..9c2525c 100644 --- a/cwd-admin/src/views/LayoutView.vue +++ b/cwd-admin/src/views/LayoutView.vue @@ -68,6 +68,13 @@ > 评论管理 +