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