From a0f0c27c440d0af9fc425f3eed37949c8e3824b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E9=93=B6=E5=86=9B?= Date: Sat, 19 Sep 2026 21:58:44 +0800 Subject: [PATCH] =?UTF-8?q?fix(logs):=20=E5=BF=BD=E7=95=A5/=E5=8F=96?= =?UTF-8?q?=E6=B6=88=E5=BF=BD=E7=95=A5=E6=93=8D=E4=BD=9C=E5=86=99=E5=85=A5?= =?UTF-8?q?=E6=93=8D=E4=BD=9C=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 原 /api/ignore 与 /api/ignore/:pkgName 只写 ignored_packages 表不记日志, 导致操作日志页查不到忽略记录。logs 表新增 action 列区分操作类型 (clean/ignore/unignore,旧库运行时 ALTER TABLE 迁移),忽略与取消忽略 接口补写 addLog;日志页按操作类型展示徽标与详情,删除数量/释放空间对 非清理操作显示占位符。 --- backend/db.js | 13 ++++-- backend/server.js | 5 ++- frontend/src/api/index.js | 12 ++++++ frontend/src/mock/data.js | 8 ++-- frontend/src/views/LogsView.vue | 70 ++++++++++++++++++++++++--------- 5 files changed, 81 insertions(+), 27 deletions(-) diff --git a/backend/db.js b/backend/db.js index f6314fb..bd69e00 100644 --- a/backend/db.js +++ b/backend/db.js @@ -26,6 +26,7 @@ CREATE TABLE IF NOT EXISTS ignored_packages ( ); CREATE TABLE IF NOT EXISTS logs ( id INTEGER PRIMARY KEY AUTOINCREMENT, + action TEXT DEFAULT 'clean', pkg_name TEXT, deleted_versions TEXT, deleted_count INTEGER, @@ -34,6 +35,12 @@ CREATE TABLE IF NOT EXISTS logs ( ); `) +// 旧库迁移:早期 logs 表无 action 列,运行时补齐(忽略/取消忽略等操作依赖该列区分类型) +const logCols = db.prepare('PRAGMA table_info(logs)').all().map(c => c.name) +if (!logCols.includes('action')) { + db.exec("ALTER TABLE logs ADD COLUMN action TEXT DEFAULT 'clean'") +} + // —— settings —— export function getSetting(key, def = null) { const row = db.prepare('SELECT value FROM settings WHERE key = ?').get(key) @@ -70,10 +77,10 @@ export function removeIgnored(pkgName) { } // —— logs —— -export function addLog({ pkgName, deletedVersions, deletedCount, freedSpace }) { +export function addLog({ action = 'clean', pkgName, deletedVersions = null, deletedCount = 0, freedSpace = null }) { const info = db.prepare( - 'INSERT INTO logs (pkg_name, deleted_versions, deleted_count, freed_space) VALUES (?, ?, ?, ?)', - ).run(pkgName, deletedVersions, deletedCount, freedSpace) + 'INSERT INTO logs (action, pkg_name, deleted_versions, deleted_count, freed_space) VALUES (?, ?, ?, ?, ?)', + ).run(action, pkgName, deletedVersions, deletedCount, freedSpace) return info.lastInsertRowid } diff --git a/backend/server.js b/backend/server.js index 754483c..c715fd6 100644 --- a/backend/server.js +++ b/backend/server.js @@ -208,10 +208,13 @@ app.post('/api/ignore', (req, res) => { const { pkgName } = req.body || {} if (!pkgName) return res.status(400).json({ ok: false, message: '缺少 pkgName' }) addIgnored(String(pkgName)) + addLog({ action: 'ignore', pkgName: String(pkgName) }) res.json({ ok: true }) }) app.delete('/api/ignore/:pkgName', (req, res) => { - removeIgnored(req.params.pkgName) + const pkgName = decodeURIComponent(req.params.pkgName) + removeIgnored(pkgName) + addLog({ action: 'unignore', pkgName }) res.json({ ok: true }) }) diff --git a/frontend/src/api/index.js b/frontend/src/api/index.js index aef32b1..56d28b9 100644 --- a/frontend/src/api/index.js +++ b/frontend/src/api/index.js @@ -156,6 +156,12 @@ const api = { mockState.ignored.add(pkgName) const p = mockState.packages.find(x => x.name === pkgName) if (p) { p.status = 'ignored'; p.ignoredAt = new Date().toISOString().slice(0, 10) } + mockState.logs.unshift({ + id: Date.now(), + action: 'ignore', + pkgName, + created_at: new Date().toISOString().slice(0, 16).replace('T', ' '), + }) return { ok: true } } const r = await fetch('/api/ignore', { @@ -175,6 +181,12 @@ const api = { p.status = computeStatus(p, mockState.versionThreshold) delete p.ignoredAt } + mockState.logs.unshift({ + id: Date.now(), + action: 'unignore', + pkgName, + created_at: new Date().toISOString().slice(0, 16).replace('T', ' '), + }) return { ok: true } } const r = await fetch(`/api/ignore/${encodeURIComponent(pkgName)}`, { method: 'DELETE' }) diff --git a/frontend/src/mock/data.js b/frontend/src/mock/data.js index e63f34b..839e54d 100644 --- a/frontend/src/mock/data.js +++ b/frontend/src/mock/data.js @@ -143,11 +143,11 @@ function topMax(list) { return Math.max(...list.map(p => p.visits), 1) } -// 日志 +// 日志(action: clean=清理 / ignore=忽略 / unignore=取消忽略) const logs = [ - { id: 3, pkgName: '@antv/g2', deletedVersions: '1.0.0, 1.1.0, 1.2.0', deletedCount: 3, freedSpace: '36.5 MB', created_at: dateStr(0) + ' 09:12:04' }, - { id: 2, pkgName: 'lodash', deletedVersions: '4.0.0, 4.1.0, 4.2.0, 4.3.0', deletedCount: 4, freedSpace: '15.2 MB', created_at: dateStr(1) + ' 18:40:22' }, - { id: 1, pkgName: 'axios', deletedVersions: '0.19.0', deletedCount: 1, freedSpace: '1.1 MB', created_at: dateStr(2) + ' 11:05:47' }, + { id: 3, action: 'clean', pkgName: '@antv/g2', deletedVersions: '1.0.0, 1.1.0, 1.2.0', deletedCount: 3, freedSpace: '36.5 MB', created_at: dateStr(0) + ' 09:12:04' }, + { id: 2, action: 'ignore', pkgName: 'moment', created_at: dateStr(1) + ' 18:40:22' }, + { id: 1, action: 'clean', pkgName: 'axios', deletedVersions: '0.19.0', deletedCount: 1, freedSpace: '1.1 MB', created_at: dateStr(2) + ' 11:05:47' }, ] // 状态统计(与 overview 对齐) diff --git a/frontend/src/views/LogsView.vue b/frontend/src/views/LogsView.vue index 5853a6a..e9b93d9 100644 --- a/frontend/src/views/LogsView.vue +++ b/frontend/src/views/LogsView.vue @@ -10,13 +10,20 @@ onMounted(() => refreshLogs()) function fmtTime(t) { return (t || '').replace('T', ' ').slice(0, 19) } + +// 操作类型 → 徽标文案/class/emoji +function actionMeta(action) { + if (action === 'ignore') return { emo: '💤', text: '忽略', cls: 'ignore' } + if (action === 'unignore') return { emo: '↩️', text: '取消忽略', cls: 'unignore' } + return { emo: '🗑', text: '清理', cls: 'clean' } +}