fix: 清理/删除后对话框立即关闭,扫描期间使用缓存数据不中断页面
CI / Backend tests (push) Canceled after 0s
CI / Frontend build (push) Canceled after 0s

This commit is contained in:
yinjun.chen1
2026-09-29 14:48:23 +08:00
parent 0d6f7c9b2e
commit fd77b689e9
2 changed files with 13 additions and 8 deletions
+9 -5
View File
@@ -40,6 +40,7 @@ export const scanState = {
startupScanning: false,
pendingDailyScan: false, // 定时扫描被并发扫描挤掉时标记,扫描结束后自动补扫
_triggerSource: 'manual', // 'startup' | 'manual' | 'daily' | 'pending' | 'lazy'
dirty: false, // 缓存失效标记:invalidateScan 时置 true,扫描完成后清零
}
/** 磁盘占用(跨平台):递归统计目录内所有文件字节和
@@ -93,9 +94,10 @@ export async function runScanAsync() {
scanState.bytes = p.bytes // 目录内所有文件字节和
scanState.tgzBytes = p.tgzBytes || 0 // 仅 .tgz
})
rawCacheAt = new Date().toISOString()
rawCacheAt = new Date().toISOString()
scanState.done = true
scanState.error = null
scanState.dirty = false // 扫描完成,清除 dirty 标记
scanState.lastErrorAt = null // 成功后清除错误状态,解除冷却
scanState.finishedAt = rawCacheAt
scanState.diskBytes = await diskBytesOf(storage) // 磁盘占用(跨平台字节和)
@@ -205,10 +207,12 @@ rawCacheAt = new Date().toISOString()
// 扫描失败后冷却期:避免持续异常(目录权限/挂载问题)时每次请求都触发扫描
const SCAN_RETRY_COOLDOWN_MS = 5 * 60_000 // 5 分钟
// 确保扫描已启动(缓存缺失时懒触发,不阻塞当前请求)
// 确保扫描已启动(缓存缺失或 dirty 时懒触发,不阻塞当前请求)
export function ensureScan() {
if (isDemoMode()) return
if (rawCache || scanState.scanning) return
if (scanState.scanning) return
// rawCache 存在但 dirty 时,也需要触发扫描重建缓存
if (rawCache && !scanState.dirty) return
// 失败冷却期内不重试,手动 POST /api/scan 不受此限制
if (scanState.lastErrorAt) {
const elapsed = Date.now() - new Date(scanState.lastErrorAt).getTime()
@@ -228,8 +232,8 @@ export function hasScanCache() {
}
export function invalidateScan() {
rawCache = null
rawCacheAt = null
// 保留 rawCache 供扫描期间使用,只标记 dirty;扫描完成后自动替换
scanState.dirty = true
packagesCache = null // 清空包列表构建缓存
clearPkgCache() // storage 目录切换 / 清理动作后废弃增量缓存,避免旧目录条目残留
}
+4 -3
View File
@@ -34,8 +34,8 @@ export async function unignorePkg(name, versionCount) {
export async function cleanPkg(name, keep) {
const res = await api.clean(name, keep)
if (res.ok) {
// 删除触发 invalidateScan,下一次拉包会懒扫描重建缓存 → 静默提示并等待完成
await Promise.all([silentRefresh({ toast: true }), refreshLogs()])
// 不等待扫描完成,立即返回让对话框关闭;后台扫描完成后自动刷新
silentRefresh({ toast: true }).then(() => refreshLogs())
}
return res
}
@@ -43,7 +43,8 @@ export async function cleanPkg(name, keep) {
export async function deleteVersion(name, version) {
const res = await api.deleteVersion(name, version)
if (res.ok) {
await Promise.all([silentRefresh({ toast: true }), refreshLogs()])
// 不等待扫描完成,立即返回让对话框关闭;后台扫描完成后自动刷新
silentRefresh({ toast: true }).then(() => refreshLogs())
}
return res
}