From 2fa0e04508adb60053ca909287471ba263b474dc Mon Sep 17 00:00:00 2001 From: anghunk Date: Thu, 22 Jan 2026 10:14:17 +0800 Subject: [PATCH] =?UTF-8?q?feat(admin):=20=E6=B7=BB=E5=8A=A0=E5=9F=9F?= =?UTF-8?q?=E5=90=8D=E5=88=97=E8=A1=A8=E8=8E=B7=E5=8F=96=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E7=94=A8=E4=BA=8E=E7=AD=9B=E9=80=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增获取域名列表的API端点,用于统一管理评论和访问统计中的域名筛选功能。修改了前端多个视图的域名获取逻辑,从原来的分散获取改为统一调用新接口,提高代码复用性和维护性。 docs: 添加反馈页面并更新侧边栏 --- cwd-admin/src/api/admin.ts | 8 +++ cwd-admin/src/views/AnalyticsVisitView.vue | 37 +++++------ cwd-admin/src/views/CommentsView.vue | 10 ++- cwd-admin/src/views/StatsView.vue | 32 ++++++---- cwd-api/src/api/admin/getDomains.ts | 74 ++++++++++++++++++++++ cwd-api/src/index.ts | 2 + docs/.vitepress/configs/sidebar.js | 1 + docs/api/admin.md | 47 ++++++++++++++ docs/feedback.md | 8 +++ 9 files changed, 182 insertions(+), 37 deletions(-) create mode 100644 cwd-api/src/api/admin/getDomains.ts create mode 100644 docs/feedback.md diff --git a/cwd-admin/src/api/admin.ts b/cwd-admin/src/api/admin.ts index 708a689..72ec767 100644 --- a/cwd-admin/src/api/admin.ts +++ b/cwd-admin/src/api/admin.ts @@ -107,6 +107,10 @@ export type VisitPagesResponse = { items: VisitPageItem[]; }; +export type DomainListResponse = { + domains: string[]; +}; + export async function loginAdmin(name: string, password: string): Promise { const res = await post('/admin/login', { name, password }); const key = res.data.key; @@ -265,3 +269,7 @@ export function fetchVisitPages(domain?: string, order?: 'pv' | 'latest'): Promi const url = query ? `/admin/analytics/pages?${query}` : '/admin/analytics/pages'; return get(url); } + +export function fetchDomainList(): Promise { + return get('/admin/stats/domains'); +} diff --git a/cwd-admin/src/views/AnalyticsVisitView.vue b/cwd-admin/src/views/AnalyticsVisitView.vue index 7a59410..c0984a3 100644 --- a/cwd-admin/src/views/AnalyticsVisitView.vue +++ b/cwd-admin/src/views/AnalyticsVisitView.vue @@ -55,7 +55,7 @@

最近 30 天访问趋势

加载中...
{{ error }}
-
+
@@ -127,6 +127,7 @@ import * as echarts from "echarts"; import { fetchVisitOverview, fetchVisitPages, + fetchDomainList, type VisitOverviewResponse, type VisitPageItem, } from "../api/admin"; @@ -252,20 +253,6 @@ async function loadData() { last30Days.value = Array.isArray(overviewRes.last30Days) ? overviewRes.last30Days : []; - - const domains = new Set(); - for (const item of items.value) { - const domainFromUrl = - extractDomain(item.postUrl) || extractDomain(item.postSlug); - if (domainFromUrl) { - domains.add(domainFromUrl); - } - } - const options = Array.from(domains); - if (domainFilter.value && !options.includes(domainFilter.value)) { - options.unshift(domainFilter.value); - } - domainOptions.value = options; } catch (e: any) { const msg = e.message || "加载访问统计数据失败"; error.value = msg; @@ -274,14 +261,27 @@ async function loadData() { loading.value = false; listLoading.value = false; await nextTick(); - if (!error.value && last30Days.value.length > 0) { + if (!error.value) { renderChart(); - } else if (chartInstance) { - chartInstance.clear(); } } } +async function loadDomains() { + try { + const res = await fetchDomainList(); + const domains = Array.isArray(res.domains) ? res.domains : []; + const set = new Set(domains); + if (domainFilter.value && !set.has(domainFilter.value)) { + set.add(domainFilter.value); + } + domainOptions.value = Array.from(set); + } catch (e: any) { + const msg = e.message || "加载域名列表失败"; + showToast(msg, "error"); + } +} + async function loadVisitPagesOnly() { listLoading.value = true; error.value = ""; @@ -370,6 +370,7 @@ function handleResize() { onMounted(() => { loadData(); + loadDomains(); window.addEventListener("resize", handleResize); }); diff --git a/cwd-admin/src/views/CommentsView.vue b/cwd-admin/src/views/CommentsView.vue index 4851246..683b288 100644 --- a/cwd-admin/src/views/CommentsView.vue +++ b/cwd-admin/src/views/CommentsView.vue @@ -257,12 +257,12 @@ import { CommentItem, CommentListResponse, fetchComments, - fetchCommentStats, deleteComment, updateCommentStatus, updateComment, blockIp, blockEmail, + fetchDomainList, } from "../api/admin"; const DOMAIN_STORAGE_KEY = "cwd_admin_domain_filter"; @@ -558,11 +558,9 @@ onMounted(() => { domainFilter.value = d.trim(); } - fetchCommentStats() - .then((res: CommentListResponse | any) => { - const domains = Array.isArray(res.domains) - ? res.domains.map((item: any) => item.domain) - : []; + fetchDomainList() + .then((res) => { + const domains = Array.isArray(res.domains) ? res.domains : []; domainOptions.value = Array.from(new Set(domains)); }) .catch(() => { diff --git a/cwd-admin/src/views/StatsView.vue b/cwd-admin/src/views/StatsView.vue index 2b79a15..75c687f 100644 --- a/cwd-admin/src/views/StatsView.vue +++ b/cwd-admin/src/views/StatsView.vue @@ -55,7 +55,7 @@

最近 30 天评论数趋势

加载中...
{{ statsError }}
-
+
@@ -94,7 +94,7 @@