diff --git a/app/pages/me/admin/media-storage.vue b/app/pages/me/admin/media-storage.vue index 6129047..773d396 100644 --- a/app/pages/me/admin/media-storage.vue +++ b/app/pages/me/admin/media-storage.vue @@ -3,15 +3,39 @@ import { useAuthSession } from '../../../composables/useAuthSession' definePageMeta({ title: '媒体存储校验' }) +type RefDetail = { ownerType: string; ownerId: number } + +type AuditRow = { + id: number + userId: number + storageKey: string + refCount: number + refs: RefDetail[] +} + type AuditReport = { scannedAt: string dbRowCount: number diskFileCount: number - missingOnDisk: Array<{ id: number; userId: number; storageKey: string; refCount: number }> - invalidStorageKey: Array<{ id: number; userId: number; storageKey: string; refCount: number }> + missingOnDisk: AuditRow[] + invalidStorageKey: AuditRow[] onDiskNotInDb: string[] } +function refSourceLabel(ownerType: string, ownerId: number): string { + if (ownerType === 'post') { + return `文章 #${ownerId}` + } + if (ownerType === 'profile') { + return `个人资料 #${ownerId}` + } + return `${ownerType} #${ownerId}` +} + +function formatRefSources(refs: RefDetail[]): string { + return refs.map((r) => refSourceLabel(r.ownerType, r.ownerId)).join(' · ') +} + const { user, refresh } = useAuthSession() const { fetchData } = useClientApi() const toast = useToast() @@ -45,7 +69,7 @@ async function runCleanup() { '/api/admin/media/storage-audit-cleanup', { method: 'POST', body: {} }, ) - toast.add({ title: `已移除 ${removed} 条失效记录(无引用且磁盘无文件)`, color: 'success' }) + toast.add({ title: `已移除 ${removed} 条失效记录(无 media_refs 且磁盘无文件)`, color: 'success' }) cleanupOpen.value = false await runAudit() } finally { @@ -69,7 +93,7 @@ const riskyMissingCount = computed(() => { const cleanupDescription = computed(() => { const n = safeToCleanupCount.value - return `将删除 ${n} 条 media_assets 记录:磁盘上无对应文件,且当前无任何文章引用。此操作不可撤销。` + return `将删除 ${n} 条 media_assets 记录:磁盘上无对应文件,且当前无任何 media_refs 引用(文章/个人资料等)。此操作不可撤销。` }) onMounted(async () => { @@ -87,7 +111,7 @@ onMounted(async () => {
比对 public/assets 与表 media_assets:
库中有记录但文件缺失、非法 storageKey、以及磁盘上未登记的文件。
- 「一键清理」仅删除无文章引用且磁盘上确实没有文件的库记录,不会删磁盘文件。
+ 「一键清理」仅删除无 media_refs 引用且磁盘上确实没有文件的库记录,不会删磁盘文件。
- 请先修改相关文章正文或封面中的图片地址,再处理库记录;勿使用「清理失效库记录」删除这些行(当前实现不会删除有引用的行)。 + 「引用来源」列出 media_refs 的 owner_type / owner_id(如文章 id、用户资料 user id)。请先修改对应正文、封面或个人资料中的图片,再处理库记录;勿使用「清理失效库记录」删除这些行。
| 引用数 | ++ 引用来源(owner_type) + | @@ -156,6 +183,9 @@ onMounted(async () => {{{ row.refCount }} | ++ {{ formatRefSources(row.refs) }} + |
|---|