diff --git a/app/pages/me/admin/media-storage.vue b/app/pages/me/admin/media-storage.vue index 773d396..5da2269 100644 --- a/app/pages/me/admin/media-storage.vue +++ b/app/pages/me/admin/media-storage.vue @@ -37,7 +37,7 @@ function formatRefSources(refs: RefDetail[]): string { } const { user, refresh } = useAuthSession() -const { fetchData } = useClientApi() +const { fetchData, getApiErrorMessage } = useClientApi() const toast = useToast() const loading = ref(false) @@ -45,6 +45,10 @@ const cleaning = ref(false) const report = ref(null) const cleanupOpen = ref(false) +const reuploadInput = ref(null) +const reuploadTargetId = ref(null) +const reuploadingId = ref(null) + async function ensureAdmin() { await refresh(true) if (user.value?.role !== 'admin') { @@ -52,16 +56,50 @@ async function ensureAdmin() { } } -async function runAudit() { +async function runAudit(showToast = true) { loading.value = true try { - report.value = await fetchData('/api/admin/media/storage-audit') - toast.add({ title: '校验完成', color: 'success' }) + report.value = await fetchData('/api/admin/media/storage-audit', { notify: false }) + if (showToast) { + toast.add({ title: '校验完成', color: 'success' }) + } } finally { loading.value = false } } +function openReuploadPicker(assetId: number) { + reuploadTargetId.value = assetId + nextTick(() => reuploadInput.value?.click()) +} + +async function onReuploadFile(ev: Event) { + const assetId = reuploadTargetId.value + reuploadTargetId.value = null + const input = ev.target as HTMLInputElement + const file = input.files?.[0] + input.value = '' + if (!assetId || !file) { + return + } + reuploadingId.value = assetId + try { + const form = new FormData() + form.append('file', file) + await fetchData<{ url: string; sizeBytes: number }>(`/api/admin/media/assets/${assetId}/reupload`, { + method: 'POST', + body: form, + notify: false, + }) + toast.add({ title: '已重新写入磁盘', color: 'success' }) + await runAudit(false) + } catch (e: unknown) { + toast.add({ title: getApiErrorMessage(e), color: 'error' }) + } finally { + reuploadingId.value = null + } +} + async function runCleanup() { cleaning.value = true try { @@ -103,6 +141,13 @@ onMounted(async () => {