From b43ee777fc9609cfa8d8da10c505a87992dfc1b0 Mon Sep 17 00:00:00 2001 From: stefanfeng Date: Tue, 7 Apr 2026 14:51:59 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BA=92=E5=8A=A8=E8=AE=B0=E5=BD=95/?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E7=9C=8B=E6=9D=BF=E8=87=AA=E5=8A=A8=E5=88=B7?= =?UTF-8?q?=E6=96=B0=20+=20=E6=97=A5=E5=BF=97=E6=97=B6=E9=97=B4=E6=A0=BC?= =?UTF-8?q?=E5=BC=8F=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Interactions.vue: 每30秒自动刷新互动记录列表 2. Dashboard.vue: 每30秒自动刷新数据看板 3. Logs.vue: 时间格式修复(T→空格,去掉时区标识) 4. logs.py: created_at 改用 strftime 输出 +08:00 格式(而非 isoformat 的 +00:00) 页面保持浏览时自动获取最新数据,离开页面时自动清除定时器 --- backend/app/api/endpoints/logs.py | 2 +- frontend/src/views/Dashboard.vue | 3 +++ frontend/src/views/Interactions.vue | 9 ++++++++- frontend/src/views/Logs.vue | 2 +- 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/backend/app/api/endpoints/logs.py b/backend/app/api/endpoints/logs.py index a8909b5..66ce223 100755 --- a/backend/app/api/endpoints/logs.py +++ b/backend/app/api/endpoints/logs.py @@ -37,7 +37,7 @@ async def get_login_logs( items = [{ "id": l.id, "user_id": l.user_id, "user_account": l.user_account, "action": l.action, "session_id": l.session_id, - "error_msg": l.error_msg, "created_at": l.created_at.isoformat() + "error_msg": l.error_msg, "created_at": l.created_at.strftime("%Y-%m-%dT%H:%M:%S+08:00") if l.created_at else None } for l in logs] return ApiResponse(data={"total": total, "page": page, "page_size": page_size, "items": items}) diff --git a/frontend/src/views/Dashboard.vue b/frontend/src/views/Dashboard.vue index cf4504b..37a0908 100644 --- a/frontend/src/views/Dashboard.vue +++ b/frontend/src/views/Dashboard.vue @@ -216,10 +216,13 @@ onMounted(async () => { await loadMonthlyTrend() window.addEventListener('resize', handleResize) window.addEventListener('page-refresh', loadDashboard) + // 每30秒自动刷新数据看板 + _dashTimer = setInterval(loadDashboard, 30000) }) onUnmounted(() => { window.removeEventListener('resize', handleResize) window.removeEventListener('page-refresh', loadDashboard) + if (_dashTimer) clearInterval(_dashTimer) dailyChartInst?.dispose() monthlyChartInst?.dispose() }) diff --git a/frontend/src/views/Interactions.vue b/frontend/src/views/Interactions.vue index 053202e..59a9081 100644 --- a/frontend/src/views/Interactions.vue +++ b/frontend/src/views/Interactions.vue @@ -194,12 +194,19 @@ async function handleExport() { const a = document.createElement('a'); a.href = url; a.download = 'interactions.xlsx'; a.click() } +let _autoRefreshTimer = null + onMounted(async () => { await loadArticleDomain() // 先等域名加载完 load() window.addEventListener('page-refresh', load) + // 每30秒自动刷新互动记录 + _autoRefreshTimer = setInterval(load, 30000) +}) +onUnmounted(() => { + window.removeEventListener('page-refresh', load) + if (_autoRefreshTimer) clearInterval(_autoRefreshTimer) }) -onUnmounted(() => window.removeEventListener('page-refresh', load))