From f91d8f54187dc0514c90e0cf3147a90346b2b1c3 Mon Sep 17 00:00:00 2001 From: Hermes Agent Date: Tue, 15 Sep 2026 21:29:30 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E8=AE=BF=E9=97=AE=E5=9F=8B=E7=82=B9?= =?UTF-8?q?=E7=BB=9F=E8=AE=A1=E2=80=94=E2=80=94VisitLog=E6=A8=A1=E5=9E=8B+?= =?UTF-8?q?/api=20GET=E5=9F=8B=E7=82=B9=E4=B8=AD=E9=97=B4=E4=BB=B6(?= =?UTF-8?q?=E5=B0=8F=E7=A8=8B=E5=BA=8F/H5/=E7=9B=B4=E6=8E=A5=E8=AE=BF?= =?UTF-8?q?=E9=97=AE=E6=9D=A5=E6=BA=90=E8=AF=86=E5=88=AB)+=E8=AE=BF?= =?UTF-8?q?=E9=97=AE=E7=BB=9F=E8=AE=A1=E6=8E=A5=E5=8F=A3+=E7=9C=8B?= =?UTF-8?q?=E6=9D=BFPV/UV/=E6=9D=A5=E6=BA=90=E5=88=86=E5=B8=83=E5=8D=A1+?= =?UTF-8?q?=E6=97=A5=E5=BF=97=E9=A1=B5=E8=AE=BF=E9=97=AE=E5=9F=8B=E7=82=B9?= =?UTF-8?q?Tab?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- admin/src/views/Dashboard.vue | 21 +++++++++++++++ admin/src/views/Logs.vue | 13 ++++++++- server/src/index.js | 24 +++++++++++++++++ server/src/models/VisitLog.js | 28 ++++++++++++++++++++ server/src/models/index.js | 4 ++- server/src/routes/admin.js | 50 ++++++++++++++++++++++++++++++++++- 6 files changed, 137 insertions(+), 3 deletions(-) create mode 100644 server/src/models/VisitLog.js diff --git a/admin/src/views/Dashboard.vue b/admin/src/views/Dashboard.vue index 654b010..c3a193c 100644 --- a/admin/src/views/Dashboard.vue +++ b/admin/src/views/Dashboard.vue @@ -7,6 +7,21 @@
{{ d.stats?.aiChatUsed ?? '-' }}AI 问答次数{{ d.stats?.aiChatUsers ?? 0 }} 人用过
{{ d.stats?.totalTrends ?? '-' }}趋势资讯含人话解读 {{ d.stats?.trendsWithExplain ?? 0 }}
{{ d.stats?.paidOrders ?? '-' }}付费订单共 {{ d.stats?.totalOrders ?? 0 }} 单
+
{{ visit.pvToday ?? '-' }}今日访问 PV小程序 + H5
+
{{ visit.uvToday ?? '-' }}今日访客 UV按 IP 去重
+
{{ visit.h5Today ?? '-' }}H5 访问小程序 {{ visit.miniToday ?? 0 }} 次
+ + +
+
+

访问来源分布(近 7 天)

+
+ {{ s.source }} +
+ {{ s.count }} +
+
+
@@ -47,13 +62,19 @@ import { ref, onMounted } from 'vue' import { apiGet } from '../api' const d = ref({}) +const visit = ref({}) function pct(n) { const max = Math.max(1, ...(d.value.litByDim || []).map(b => b.count)) return Math.round((n / max) * 100) + '%' } +function srcPct(n) { + const max = Math.max(1, ...(visit.value.sources7d || []).map(s => s.count)) + return Math.round((n / max) * 100) + '%' +} function fmt(t) { return t ? new Date(t).toLocaleString('zh-CN', { hour12: false }) : '-' } onMounted(async () => { d.value = (await apiGet('/api/admin/dashboard-v2')) || {} + try { visit.value = (await apiGet('/api/admin/visit-stats')) || {} } catch (e) { visit.value = {} } }) diff --git a/admin/src/views/Logs.vue b/admin/src/views/Logs.vue index fe4e0a6..3620d5e 100644 --- a/admin/src/views/Logs.vue +++ b/admin/src/views/Logs.vue @@ -2,6 +2,7 @@
+ @@ -20,6 +21,16 @@ +