From 5618dea2a465996f9f456800a2f941e387278b5a Mon Sep 17 00:00:00 2001 From: anghunk Date: Thu, 29 Jan 2026 20:28:14 +0800 Subject: [PATCH] =?UTF-8?q?refactor(admin):=20=E6=8F=90=E5=8F=96=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=BA=93=E8=A1=A8=E5=88=9B=E5=BB=BA=E9=80=BB=E8=BE=91?= =?UTF-8?q?=E4=B8=BA=E5=85=B1=E4=BA=AB=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 重构导出和导入统计数据的 API,将重复的 CREATE TABLE 语句提取为独立的 ensureStatsTables 函数,以消除代码重复并提高可维护性。同时统一代码格式和缩进。 --- cwd-api/src/api/admin/exportStats.ts | 71 ++++----- cwd-api/src/api/admin/importStats.ts | 210 +++++++++++++-------------- 2 files changed, 129 insertions(+), 152 deletions(-) diff --git a/cwd-api/src/api/admin/exportStats.ts b/cwd-api/src/api/admin/exportStats.ts index f8b96ef..e5d30ca 100644 --- a/cwd-api/src/api/admin/exportStats.ts +++ b/cwd-api/src/api/admin/exportStats.ts @@ -1,52 +1,39 @@ import { Context } from 'hono'; import { Bindings } from '../../bindings'; +async function ensureStatsTables(env: Bindings) { + await 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 INTEGER, created_at INTEGER NOT NULL, updated_at INTEGER NOT NULL)' + ).run(); + + await env.CWD_DB.prepare( + 'CREATE TABLE IF NOT EXISTS page_visit_daily (id INTEGER PRIMARY KEY AUTOINCREMENT, date TEXT NOT NULL, domain TEXT, count INTEGER NOT NULL DEFAULT 0, created_at INTEGER NOT NULL, updated_at INTEGER NOT NULL)' + ).run(); + + await env.CWD_DB.prepare( + 'CREATE TABLE IF NOT EXISTS Likes (id INTEGER PRIMARY KEY AUTOINCREMENT, page_slug TEXT NOT NULL, user_id TEXT NOT NULL, created_at INTEGER NOT NULL, UNIQUE(page_slug, user_id))' + ).run(); +} + export const getStatsData = async (env: Bindings) => { - // Ensure tables exist - await env.CWD_DB.exec(` - 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 - ); - CREATE TABLE IF NOT EXISTS page_visit_daily ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - date TEXT NOT NULL, - domain TEXT, - count INTEGER NOT NULL DEFAULT 0, - created_at INTEGER NOT NULL, - updated_at INTEGER NOT NULL - ); - CREATE TABLE IF NOT EXISTS Likes ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - page_slug TEXT NOT NULL, - user_id TEXT NOT NULL, - created_at INTEGER NOT NULL, - UNIQUE(page_slug, user_id) - ); - `); + await ensureStatsTables(env); - const { results: pageStats } = await env.CWD_DB.prepare('SELECT * FROM page_stats').all(); - const { results: dailyVisits } = await env.CWD_DB.prepare('SELECT * FROM page_visit_daily').all(); - const { results: likes } = await env.CWD_DB.prepare('SELECT * FROM Likes').all(); + const { results: pageStats } = await env.CWD_DB.prepare('SELECT * FROM page_stats').all(); + const { results: dailyVisits } = await env.CWD_DB.prepare('SELECT * FROM page_visit_daily').all(); + const { results: likes } = await env.CWD_DB.prepare('SELECT * FROM Likes').all(); - return { - page_stats: pageStats, - page_visit_daily: dailyVisits, - likes: likes - }; + return { + page_stats: pageStats, + page_visit_daily: dailyVisits, + likes: likes + }; }; export const exportStats = async (c: Context<{ Bindings: Bindings }>) => { - try { - const data = await getStatsData(c.env); - return c.json(data); - } catch (e: any) { - return c.json({ message: e.message || '导出统计数据失败' }, 500); - } + try { + const data = await getStatsData(c.env); + return c.json(data); + } catch (e: any) { + return c.json({ message: e.message || '导出统计数据失败' }, 500); + } }; diff --git a/cwd-api/src/api/admin/importStats.ts b/cwd-api/src/api/admin/importStats.ts index 70ee1e9..e390664 100644 --- a/cwd-api/src/api/admin/importStats.ts +++ b/cwd-api/src/api/admin/importStats.ts @@ -1,125 +1,115 @@ import { Context } from 'hono'; import { Bindings } from '../../bindings'; +async function ensureStatsTables(env: Bindings) { + await 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 INTEGER, created_at INTEGER NOT NULL, updated_at INTEGER NOT NULL)' + ).run(); + + await env.CWD_DB.prepare( + 'CREATE TABLE IF NOT EXISTS page_visit_daily (id INTEGER PRIMARY KEY AUTOINCREMENT, date TEXT NOT NULL, domain TEXT, count INTEGER NOT NULL DEFAULT 0, created_at INTEGER NOT NULL, updated_at INTEGER NOT NULL)' + ).run(); + + await env.CWD_DB.prepare( + 'CREATE TABLE IF NOT EXISTS Likes (id INTEGER PRIMARY KEY AUTOINCREMENT, page_slug TEXT NOT NULL, user_id TEXT NOT NULL, created_at INTEGER NOT NULL, UNIQUE(page_slug, user_id))' + ).run(); +} + export const saveStatsData = async (env: Bindings, data: any) => { - // Ensure tables exist - await env.CWD_DB.exec(` - 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 - ); - CREATE TABLE IF NOT EXISTS page_visit_daily ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - date TEXT NOT NULL, - domain TEXT, - count INTEGER NOT NULL DEFAULT 0, - created_at INTEGER NOT NULL, - updated_at INTEGER NOT NULL - ); - CREATE TABLE IF NOT EXISTS Likes ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - page_slug TEXT NOT NULL, - user_id TEXT NOT NULL, - created_at INTEGER NOT NULL, - UNIQUE(page_slug, user_id) - ); - `); + await ensureStatsTables(env); - const stmts: any[] = []; + const stmts: any[] = []; - // 1. page_stats - if (Array.isArray(data.page_stats)) { - for (const item of data.page_stats) { - const fields = ['post_slug', 'post_title', 'post_url', 'pv', 'last_visit_at', 'created_at', 'updated_at']; - const values = [ - item.post_slug, - item.post_title, - item.post_url, - item.pv, - item.last_visit_at, - item.created_at, - item.updated_at - ]; - if (item.id) { - fields.unshift('id'); - values.unshift(item.id); - } - const placeholders = fields.map(() => '?').join(', '); - stmts.push( - env.CWD_DB.prepare(`INSERT OR REPLACE INTO page_stats (${fields.join(', ')}) VALUES (${placeholders})`).bind(...values) - ); - } - } + if (Array.isArray(data.page_stats)) { + for (const item of data.page_stats) { + const fields = [ + 'post_slug', + 'post_title', + 'post_url', + 'pv', + 'last_visit_at', + 'created_at', + 'updated_at' + ]; + const values = [ + item.post_slug, + item.post_title, + item.post_url, + item.pv, + item.last_visit_at, + item.created_at, + item.updated_at + ]; + if (item.id) { + fields.unshift('id'); + values.unshift(item.id); + } + const placeholders = fields.map(() => '?').join(', '); + stmts.push( + env.CWD_DB.prepare( + `INSERT OR REPLACE INTO page_stats (${fields.join(', ')}) VALUES (${placeholders})` + ).bind(...values) + ); + } + } - // 2. page_visit_daily - if (Array.isArray(data.page_visit_daily)) { - for (const item of data.page_visit_daily) { - const fields = ['date', 'domain', 'count', 'created_at', 'updated_at']; - const values = [ - item.date, - item.domain, - item.count, - item.created_at, - item.updated_at - ]; - if (item.id) { - fields.unshift('id'); - values.unshift(item.id); - } - const placeholders = fields.map(() => '?').join(', '); - stmts.push( - env.CWD_DB.prepare(`INSERT OR REPLACE INTO page_visit_daily (${fields.join(', ')}) VALUES (${placeholders})`).bind(...values) - ); - } - } + if (Array.isArray(data.page_visit_daily)) { + for (const item of data.page_visit_daily) { + const fields = ['date', 'domain', 'count', 'created_at', 'updated_at']; + const values = [item.date, item.domain, item.count, item.created_at, item.updated_at]; + if (item.id) { + fields.unshift('id'); + values.unshift(item.id); + } + const placeholders = fields.map(() => '?').join(', '); + stmts.push( + env.CWD_DB.prepare( + `INSERT OR REPLACE INTO page_visit_daily (${fields.join(', ')}) VALUES (${placeholders})` + ).bind(...values) + ); + } + } - // 3. Likes - if (Array.isArray(data.likes)) { - for (const item of data.likes) { - const fields = ['page_slug', 'user_id', 'created_at']; - const values = [ - item.page_slug, - item.user_id, - item.created_at - ]; - if (item.id) { - fields.unshift('id'); - values.unshift(item.id); - } - const placeholders = fields.map(() => '?').join(', '); - stmts.push( - env.CWD_DB.prepare(`INSERT OR REPLACE INTO Likes (${fields.join(', ')}) VALUES (${placeholders})`).bind(...values) - ); - } - } + if (Array.isArray(data.likes)) { + for (const item of data.likes) { + const fields = ['page_slug', 'user_id', 'created_at']; + const values = [item.page_slug, item.user_id, item.created_at]; + if (item.id) { + fields.unshift('id'); + values.unshift(item.id); + } + const placeholders = fields.map(() => '?').join(', '); + stmts.push( + env.CWD_DB.prepare( + `INSERT OR REPLACE INTO Likes (${fields.join(', ')}) VALUES (${placeholders})` + ).bind(...values) + ); + } + } - // Batch execute - const BATCH_SIZE = 50; - for (let i = 0; i < stmts.length; i += BATCH_SIZE) { - const batch = stmts.slice(i, i + BATCH_SIZE); - await env.CWD_DB.batch(batch); - } + const BATCH_SIZE = 50; + for (let i = 0; i < stmts.length; i += BATCH_SIZE) { + const batch = stmts.slice(i, i + BATCH_SIZE); + await env.CWD_DB.batch(batch); + } }; export const importStats = async (c: Context<{ Bindings: Bindings }>) => { - try { - const body = await c.req.json(); - if (!body || typeof body !== 'object') { - return c.json({ message: '数据格式错误' }, 400); - } + try { + const body = await c.req.json(); + if (!body || typeof body !== 'object') { + return c.json({ message: '数据格式错误' }, 400); + } - await saveStatsData(c.env, body); + await saveStatsData(c.env, body); - const statsCount = (body.page_stats?.length || 0) + (body.page_visit_daily?.length || 0) + (body.likes?.length || 0); - return c.json({ message: `成功导入 ${statsCount} 条统计数据` }); - } catch (e: any) { - console.error(e); - return c.json({ message: e.message || '导入统计数据失败' }, 500); - } + const statsCount = + (body.page_stats?.length || 0) + + (body.page_visit_daily?.length || 0) + + (body.likes?.length || 0); + return c.json({ message: `成功导入 ${statsCount} 条统计数据` }); + } catch (e: any) { + console.error(e); + return c.json({ message: e.message || '导入统计数据失败' }, 500); + } };