From 61f22238252c1aad5455d2f20f6b8aded4e8b88d Mon Sep 17 00:00:00 2001 From: anghunk Date: Tue, 27 Jan 2026 10:46:11 +0800 Subject: [PATCH] =?UTF-8?q?feat(analytics):=20=E4=B8=BA=E8=AE=BF=E9=97=AE?= =?UTF-8?q?=E5=92=8C=E8=AF=84=E8=AE=BA=E8=B6=8B=E5=8A=BF=E5=9B=BE=E8=A1=A8?= =?UTF-8?q?=E6=B7=BB=E5=8A=A07=E5=A4=A9/30=E5=A4=A9=E5=88=87=E6=8D=A2?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在访问趋势和评论数趋势卡片标题栏添加切换按钮 - 重构图表数据源处理逻辑,支持按时间范围筛选 - 添加对应的CSS样式实现标签式切换器 - 保持默认显示最近30天数据,点击切换时重新渲染图表 --- cwd-admin/src/views/AnalyticsVisitView.vue | 38 +++++++++++- cwd-admin/src/views/StatsView.vue | 71 +++++++++++++++++++++- 2 files changed, 103 insertions(+), 6 deletions(-) diff --git a/cwd-admin/src/views/AnalyticsVisitView.vue b/cwd-admin/src/views/AnalyticsVisitView.vue index af60b5c..b682fe2 100644 --- a/cwd-admin/src/views/AnalyticsVisitView.vue +++ b/cwd-admin/src/views/AnalyticsVisitView.vue @@ -42,7 +42,27 @@
-

最近 30 天访问趋势

+
+

访问趋势

+
+ + +
+
加载中...
{{ error }}
@@ -187,6 +207,7 @@ const injectedDomainFilter = inject | null>("domainFilter", null); const domainFilter = injectedDomainFilter ?? ref(""); const last30Days = ref<{ date: string; total: number }[]>([]); const likeStatsItems = ref([]); +const chartRange = ref<"7" | "30">("30"); const toastMessage = ref(""); const toastType = ref<"success" | "error">("success"); @@ -375,8 +396,11 @@ function renderChart() { if (!chartInstance) { chartInstance = echarts.init(el); } - const dates = last30Days.value.map((item) => item.date.slice(5)); - const values = last30Days.value.map((item) => item.total); + const source = last30Days.value; + const seriesData = + chartRange.value === "7" ? source.slice(-7) : source; + const dates = seriesData.map((item) => item.date.slice(5)); + const values = seriesData.map((item) => item.total); const option: echarts.EChartsOption = { tooltip: { trigger: "axis", @@ -422,6 +446,14 @@ function renderChart() { chartInstance.setOption(option); } +function changeChartRange(range: "7" | "30") { + if (chartRange.value === range) { + return; + } + chartRange.value = range; + renderChart(); +} + function handleResize() { if (chartInstance) { chartInstance.resize(); diff --git a/cwd-admin/src/views/StatsView.vue b/cwd-admin/src/views/StatsView.vue index 7f93d9b..48701a0 100644 --- a/cwd-admin/src/views/StatsView.vue +++ b/cwd-admin/src/views/StatsView.vue @@ -42,7 +42,27 @@
-

最近 30 天评论数趋势

+
+

评论数趋势

+
+ + +
+
加载中...
{{ statsError }}
@@ -105,6 +125,7 @@ const statsSummary = ref({ }); const domainStats = ref([]); const last7Days = ref<{ date: string; total: number }[]>([]); +const chartRange = ref<"7" | "30">("30"); const injectedDomainFilter = inject | null>("domainFilter", null); const domainFilter = injectedDomainFilter ?? ref(""); @@ -159,8 +180,11 @@ function renderChart() { if (!chartInstance) { chartInstance = echarts.init(el); } - const dates = last7Days.value.map((item) => item.date.slice(5)); - const values = last7Days.value.map((item) => item.total); + const source = last7Days.value; + const seriesData = + chartRange.value === "7" ? source.slice(-7) : source; + const dates = seriesData.map((item) => item.date.slice(5)); + const values = seriesData.map((item) => item.total); const option: echarts.EChartsOption = { tooltip: { trigger: "axis", @@ -206,6 +230,14 @@ function renderChart() { chartInstance.setOption(option); } +function changeChartRange(range: "7" | "30") { + if (chartRange.value === range) { + return; + } + chartRange.value = range; + renderChart(); +} + function handleResize() { if (chartInstance) { chartInstance.resize(); @@ -277,6 +309,14 @@ onBeforeUnmount(() => { font-size: 16px; } +.card-title-row { + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; + margin-bottom: 12px; +} + .page-hint { font-size: 14px; color: #57606a; @@ -287,6 +327,31 @@ onBeforeUnmount(() => { color: #d1242f; } +.chart-tabs { + display: inline-flex; + border-radius: 999px; + border: 1px solid #d0d7de; + overflow: hidden; +} + +.chart-tab { + padding: 4px 10px; + font-size: 12px; + border: none; + background-color: #ffffff; + color: #57606a; + cursor: pointer; +} + +.chart-tab + .chart-tab { + border-left: 1px solid #d0d7de; +} + +.chart-tab-active { + background-color: #0969da; + color: #ffffff; +} + .stats-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));