diff --git a/cwd-admin/src/api/admin.ts b/cwd-admin/src/api/admin.ts
index f3c1396..55dcd48 100644
--- a/cwd-admin/src/api/admin.ts
+++ b/cwd-admin/src/api/admin.ts
@@ -21,6 +21,7 @@ export type CommentItem = {
priority?: number;
likes?: number;
ua?: string | null;
+ isAdmin?: boolean;
};
export type CommentListResponse = {
diff --git a/cwd-admin/src/styles/components/stats.less b/cwd-admin/src/styles/components/stats.less
index fc5394b..2f712d7 100644
--- a/cwd-admin/src/styles/components/stats.less
+++ b/cwd-admin/src/styles/components/stats.less
@@ -88,10 +88,16 @@
color: var(--color-danger);
}
+.domain-stats-layout {
+ display: flex;
+ align-items: stretch;
+ gap: 16px;
+}
+
.domain-table-wrapper {
- width: 100%;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
+ flex: 1;
}
.domain-table {
@@ -125,6 +131,19 @@
font-weight: 500;
}
+.domain-pie-wrapper {
+ width: 40%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.domain-pie-chart {
+ width: 100%;
+ max-width: 400px;
+ height: 260px;
+}
+
.chart-wrapper {
margin-top: 4px;
}
@@ -138,4 +157,12 @@
.stats-grid {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
-}
\ No newline at end of file
+
+ .domain-stats-layout {
+ flex-direction: column;
+ }
+
+ .domain-pie-wrapper {
+ width: 100%;
+ }
+}
diff --git a/cwd-admin/src/views/StatsView/index.vue b/cwd-admin/src/views/StatsView/index.vue
index 252ae9b..caa9a5f 100644
--- a/cwd-admin/src/views/StatsView/index.vue
+++ b/cwd-admin/src/views/StatsView/index.vue
@@ -79,27 +79,32 @@
加载中...
-
-
-
域名
-
总数
-
已通过
-
待审核
-
已拒绝
-
-
-
{{ item.domain }}
-
{{ item.total }}
-
{{ item.approved }}
-
{{ item.pending }}
-
{{ item.rejected }}
+
+
+
+
+
域名
+
总数
+
已通过
+
待审核
+
已拒绝
+
+
+
{{ item.domain }}
+
{{ item.total }}
+
{{ item.approved }}
+
{{ item.pending }}
+
{{ item.rejected }}
+
+
@@ -140,7 +145,9 @@ const toastType = ref<"success" | "error">("success");
const toastVisible = ref(false);
const chartEl = ref
(null);
+const domainPieEl = ref(null);
let chartInstance: echarts.ECharts | null = null;
+let domainPieChartInstance: echarts.ECharts | null = null;
function loadChartRangeFromStorage() {
if (typeof window === "undefined") {
@@ -196,6 +203,7 @@ async function loadStats() {
await nextTick();
if (!statsError.value) {
renderChart();
+ renderDomainPieChart();
}
}
}
@@ -258,6 +266,45 @@ function renderChart() {
chartInstance.setOption(option);
}
+function renderDomainPieChart() {
+ const el = domainPieEl.value;
+ if (!el) {
+ return;
+ }
+ if (!domainPieChartInstance) {
+ domainPieChartInstance = echarts.init(el);
+ }
+ if (!domainStats.value.length) {
+ domainPieChartInstance.clear();
+ return;
+ }
+ const source = domainStats.value.slice().sort((a, b) => b.total - a.total);
+ const data = source.map((item) => ({
+ name: item.domain || "未知",
+ value: item.total,
+ }));
+ const option: echarts.EChartsOption = {
+ tooltip: {
+ trigger: "item",
+ formatter: "{b}: {c} ({d}%)",
+ },
+ legend: {
+ orient: "vertical",
+ left: "left",
+ },
+ series: [
+ {
+ type: "pie",
+ radius: ["40%", "70%"],
+ center: ["60%", "50%"],
+ avoidLabelOverlap: false,
+ data,
+ },
+ ],
+ };
+ domainPieChartInstance.setOption(option);
+}
+
function changeChartRange(range: "7" | "30") {
if (chartRange.value === range) {
return;
@@ -265,12 +312,16 @@ function changeChartRange(range: "7" | "30") {
chartRange.value = range;
saveChartRangeToStorage(range);
renderChart();
+ renderDomainPieChart();
}
function handleResize() {
if (chartInstance) {
chartInstance.resize();
}
+ if (domainPieChartInstance) {
+ domainPieChartInstance.resize();
+ }
}
onMounted(() => {
@@ -289,6 +340,10 @@ onBeforeUnmount(() => {
chartInstance.dispose();
chartInstance = null;
}
+ if (domainPieChartInstance) {
+ domainPieChartInstance.dispose();
+ domainPieChartInstance = null;
+ }
});