From 705cf0e3c8432f7e5695322900e3717a99b19d36 Mon Sep 17 00:00:00 2001 From: anghunk Date: Wed, 21 Jan 2026 22:47:31 +0800 Subject: [PATCH] =?UTF-8?q?refactor(analytics):=20=E5=B0=86=E6=97=B6?= =?UTF-8?q?=E9=97=B4=E6=88=B3=E5=AD=98=E5=82=A8=E4=BB=8E=E5=AD=97=E7=AC=A6?= =?UTF-8?q?=E4=B8=B2=E6=94=B9=E4=B8=BA=E6=95=B0=E5=AD=97=E7=B1=BB=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 统一使用数字类型存储时间戳,提高时间处理效率和一致性。修改相关类型定义和格式化函数以支持新旧数据格式。 --- cwd-admin/src/api/admin.ts | 2 +- cwd-admin/src/views/AnalyticsVisitView.vue | 20 +++++++++++++++++--- cwd-api/src/api/admin/visitAnalytics.ts | 8 ++++---- cwd-api/src/api/public/trackVisit.ts | 13 +++++++------ 4 files changed, 29 insertions(+), 14 deletions(-) diff --git a/cwd-admin/src/api/admin.ts b/cwd-admin/src/api/admin.ts index 8547c44..2f4290a 100644 --- a/cwd-admin/src/api/admin.ts +++ b/cwd-admin/src/api/admin.ts @@ -97,7 +97,7 @@ export type VisitPageItem = { postTitle: string | null; postUrl: string | null; pv: number; - lastVisitAt: string | null; + lastVisitAt: number | null; }; export type VisitPagesResponse = { diff --git a/cwd-admin/src/views/AnalyticsVisitView.vue b/cwd-admin/src/views/AnalyticsVisitView.vue index c2c1b9c..0cd162e 100644 --- a/cwd-admin/src/views/AnalyticsVisitView.vue +++ b/cwd-admin/src/views/AnalyticsVisitView.vue @@ -127,13 +127,27 @@ function showToast(msg: string, type: "success" | "error" = "success") { }, 2000); } -function formatTime(value: string | null): string { +function formatTime(value: string | number | null | undefined): string { if (!value) { return "-"; } - const date = new Date(value); + let date: Date; + if (typeof value === "number") { + date = new Date(value); + } else { + const trimmed = value.trim(); + if (!trimmed) { + return "-"; + } + if (/^\d+$/.test(trimmed)) { + const ts = Number(trimmed); + date = new Date(ts); + } else { + date = new Date(trimmed); + } + } if (Number.isNaN(date.getTime())) { - return value; + return "-"; } const y = date.getFullYear(); const m = String(date.getMonth() + 1).padStart(2, "0"); diff --git a/cwd-api/src/api/admin/visitAnalytics.ts b/cwd-api/src/api/admin/visitAnalytics.ts index 3619665..0ad4857 100644 --- a/cwd-api/src/api/admin/visitAnalytics.ts +++ b/cwd-api/src/api/admin/visitAnalytics.ts @@ -45,7 +45,7 @@ export const getVisitOverview = async ( const domainFilter = rawDomain.trim().toLowerCase(); await c.env.CWD_DB.prepare( - 'CREATE TABLE IF NOT EXISTS page_stats (id INTEGER PRIMARY KEY AUTOINCREMENT, post_slug TEXT UNIQUE NOT NULL, post_title TEXT, post_url TEXT, pv INTEGER NOT NULL DEFAULT 0, last_visit_at TEXT, created_at TEXT NOT NULL, updated_at TEXT NOT NULL)' + 'CREATE TABLE IF NOT EXISTS page_stats (id INTEGER PRIMARY KEY AUTOINCREMENT, post_slug TEXT UNIQUE NOT NULL, post_title TEXT, post_url TEXT, pv INTEGER NOT NULL DEFAULT 0, last_visit_at INTEGER, created_at INTEGER NOT NULL, updated_at INTEGER NOT NULL)' ).run(); await c.env.CWD_DB.prepare( @@ -59,7 +59,7 @@ export const getVisitOverview = async ( post_title: string | null; post_url: string | null; pv: number; - last_visit_at: string | null; + last_visit_at: number | null; }>(); let totalPv = 0; @@ -150,7 +150,7 @@ export const getVisitPages = async (c: Context<{ Bindings: Bindings }>) => { const domainFilter = rawDomain.trim().toLowerCase(); await c.env.CWD_DB.prepare( - 'CREATE TABLE IF NOT EXISTS page_stats (id INTEGER PRIMARY KEY AUTOINCREMENT, post_slug TEXT UNIQUE NOT NULL, post_title TEXT, post_url TEXT, pv INTEGER NOT NULL DEFAULT 0, last_visit_at TEXT, created_at TEXT NOT NULL, updated_at TEXT NOT NULL)' + 'CREATE TABLE IF NOT EXISTS page_stats (id INTEGER PRIMARY KEY AUTOINCREMENT, post_slug TEXT UNIQUE NOT NULL, post_title TEXT, post_url TEXT, pv INTEGER NOT NULL DEFAULT 0, last_visit_at INTEGER, created_at INTEGER NOT NULL, updated_at INTEGER NOT NULL)' ).run(); const { results } = await c.env.CWD_DB.prepare( @@ -160,7 +160,7 @@ export const getVisitPages = async (c: Context<{ Bindings: Bindings }>) => { post_title: string | null; post_url: string | null; pv: number; - last_visit_at: string | null; + last_visit_at: number | null; }>(); const items: VisitPageItem[] = []; diff --git a/cwd-api/src/api/public/trackVisit.ts b/cwd-api/src/api/public/trackVisit.ts index 7cdf2c5..212407d 100644 --- a/cwd-api/src/api/public/trackVisit.ts +++ b/cwd-api/src/api/public/trackVisit.ts @@ -39,7 +39,7 @@ export const trackVisit = async (c: Context<{ Bindings: Bindings }>) => { } await c.env.CWD_DB.prepare( - 'CREATE TABLE IF NOT EXISTS page_stats (id INTEGER PRIMARY KEY AUTOINCREMENT, post_slug TEXT UNIQUE NOT NULL, post_title TEXT, post_url TEXT, pv INTEGER NOT NULL DEFAULT 0, last_visit_at TEXT, created_at TEXT NOT NULL, updated_at TEXT NOT NULL)' + 'CREATE TABLE IF NOT EXISTS page_stats (id INTEGER PRIMARY KEY AUTOINCREMENT, post_slug TEXT UNIQUE NOT NULL, post_title TEXT, post_url TEXT, pv INTEGER NOT NULL DEFAULT 0, last_visit_at INTEGER, created_at INTEGER NOT NULL, updated_at INTEGER NOT NULL)' ).run(); await c.env.CWD_DB.prepare( @@ -47,6 +47,7 @@ export const trackVisit = async (c: Context<{ Bindings: Bindings }>) => { ).run(); const nowDate = new Date(); + const nowTs = nowDate.getTime(); const nowIso = nowDate.toISOString(); const today = nowIso.slice(0, 10); @@ -70,9 +71,9 @@ export const trackVisit = async (c: Context<{ Bindings: Bindings }>) => { rawPostTitle || null, rawPostUrl || null, 1, - nowIso, - nowIso, - nowIso + nowTs, + nowTs, + nowTs ) .run(); } else { @@ -84,8 +85,8 @@ export const trackVisit = async (c: Context<{ Bindings: Bindings }>) => { rawPostTitle || null, rawPostUrl || null, newPv, - nowIso, - nowIso, + nowTs, + nowTs, existing.id ) .run();