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));