From 8ec2e993664739aecc95d1f666cb5001b9cb14b7 Mon Sep 17 00:00:00 2001 From: OuYingJun1024 <1034284404@qq.com> Date: Sun, 14 Jun 2026 14:21:47 +0800 Subject: [PATCH] =?UTF-8?q?fix(admin-web):=20=E6=97=B6=E9=97=B4=E6=B8=B2?= =?UTF-8?q?=E6=9F=93=E6=94=B6=E5=8F=A3=E5=88=B0=20formatUtcTime,=E6=B6=88?= =?UTF-8?q?=E7=81=AD=20new=20Date().toLocaleString?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit review 发现 4 处仍用 new Date(v).toLocaleString 渲染后端 UTC 口径时间戳—— 正是 lib/format.ts 头注释明令消灭的反模式(SQLite 本地/非中国浏览器会差 8h, 生产靠 +00:00 偏移侥幸正确)。统一改用 formatUtcTime 按北京显示: - admins: last_login_at - audit-logs: created_at - devices: completed_at - dashboard/HomeStatsConfig: ops_stat_config.updated_at 均为 server_default now()/datetime.now(utc) 的 UTC 口径字段。 HomeStatsConfig 的「下个更新时刻」用 epoch ms + 强制 Asia/Shanghai,正确,不动。 Co-Authored-By: Claude Opus 4.8 (1M context) --- src/app/(main)/admins/page.tsx | 4 +++- src/app/(main)/audit-logs/page.tsx | 4 +++- src/app/(main)/dashboard/HomeStatsConfig.tsx | 3 ++- src/app/(main)/devices/page.tsx | 4 +++- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/app/(main)/admins/page.tsx b/src/app/(main)/admins/page.tsx index f3ae92e..a8baa4e 100644 --- a/src/app/(main)/admins/page.tsx +++ b/src/app/(main)/admins/page.tsx @@ -4,6 +4,7 @@ import { useEffect, useState } from 'react'; import type { ColumnsType } from 'antd/es/table'; import { Button, Form, Input, Modal, Select, Table, Tag, message } from 'antd'; import { api, errMsg } from '@/lib/api'; +import { formatUtcTime } from '@/lib/format'; import type { AdminInfo } from '@/lib/types'; const ROLES = [ @@ -11,7 +12,8 @@ const ROLES = [ { value: 'finance', label: 'finance' }, { value: 'operator', label: 'operator' }, ]; -const dt = (v: string | null) => (v ? new Date(v).toLocaleString('zh-CN') : '从未'); +// last_login_at 为 UTC 口径(datetime.now(utc)),按北京显示(勿用 new Date().toLocaleString) +const dt = (v: string | null) => (v ? formatUtcTime(v, 'YYYY-MM-DD HH:mm:ss') : '从未'); export default function AdminsPage() { const [admins, setAdmins] = useState([]); diff --git a/src/app/(main)/audit-logs/page.tsx b/src/app/(main)/audit-logs/page.tsx index ebe1f93..6a8ce28 100644 --- a/src/app/(main)/audit-logs/page.tsx +++ b/src/app/(main)/audit-logs/page.tsx @@ -3,10 +3,12 @@ import { useState } from 'react'; import type { ColumnsType } from 'antd/es/table'; import { Button, Input, Space, Table, Tag } from 'antd'; +import { formatUtcTime } from '@/lib/format'; import { useCursorList } from '@/lib/useCursorList'; import type { AuditLog } from '@/lib/types'; -const dt = (v: string) => new Date(v).toLocaleString('zh-CN'); +// 审计 created_at 为 UTC 口径(server_default now()),按北京显示(勿用 new Date().toLocaleString) +const dt = (v: string) => formatUtcTime(v, 'YYYY-MM-DD HH:mm:ss'); export default function AuditLogsPage() { const [action, setAction] = useState(''); diff --git a/src/app/(main)/dashboard/HomeStatsConfig.tsx b/src/app/(main)/dashboard/HomeStatsConfig.tsx index cb6d6b5..9825843 100644 --- a/src/app/(main)/dashboard/HomeStatsConfig.tsx +++ b/src/app/(main)/dashboard/HomeStatsConfig.tsx @@ -19,6 +19,7 @@ import { message, } from 'antd'; import { api, errMsg } from '@/lib/api'; +import { formatUtcTime } from '@/lib/format'; interface StatItem { metric: string; // help_users / total_compares / total_saved @@ -601,7 +602,7 @@ export default function HomeStatsConfig() { {it.updated_at && ( - 更新于 {new Date(it.updated_at).toLocaleString('zh-CN')} + 更新于 {formatUtcTime(it.updated_at, 'YYYY-MM-DD HH:mm:ss')} )} diff --git a/src/app/(main)/devices/page.tsx b/src/app/(main)/devices/page.tsx index 105f340..f746de8 100644 --- a/src/app/(main)/devices/page.tsx +++ b/src/app/(main)/devices/page.tsx @@ -4,10 +4,12 @@ import type { ColumnsType } from 'antd/es/table'; import { Button, Modal, Popconfirm, Space, Table, message } from 'antd'; import { api, errMsg } from '@/lib/api'; import { canDo } from '@/lib/auth'; +import { formatUtcTime } from '@/lib/format'; import { useCursorList } from '@/lib/useCursorList'; import type { DeviceOnboardingItem } from '@/lib/types'; -const dt = (v: string) => new Date(v).toLocaleString('zh-CN'); +// completed_at 为 UTC 口径(server_default now()),按北京显示(勿用 new Date().toLocaleString) +const dt = (v: string) => formatUtcTime(v); const EMPTY: Record = {}; export default function DevicesPage() {