diff --git a/web/frontend/src/composables/useFilePreview.ts b/web/frontend/src/composables/useFilePreview.ts new file mode 100644 index 0000000..9ec773f --- /dev/null +++ b/web/frontend/src/composables/useFilePreview.ts @@ -0,0 +1,47 @@ +import { ref } from 'vue' +import { ElMessage } from 'element-plus' + +export function useFilePreview() { + const showPreview = ref(false) + const previewType = ref<'image' | 'excel' | ''>('') + const previewSrc = ref('') + const previewRows = ref([]) + + async function openPreview(dir: string, fname: string) { + const token = localStorage.getItem('token') + try { + const resp = await fetch(`/api/files/preview/${dir}/${encodeURIComponent(fname)}`, { + headers: { Authorization: `Bearer ${token}` } + }) + const ct = resp.headers.get('content-type') || '' + if (ct.includes('image')) { + previewType.value = 'image' + const blob = await resp.blob() + previewSrc.value = URL.createObjectURL(blob) + } else { + const data = await resp.json() + if (data.type === 'excel') { + previewType.value = 'excel' + previewRows.value = data.rows + } + } + showPreview.value = true + } catch { + ElMessage.error('预览失败') + } + } + + function cleanupPreview() { + if (previewSrc.value && previewSrc.value.startsWith('blob:')) { + URL.revokeObjectURL(previewSrc.value) + } + previewSrc.value = '' + previewType.value = '' + previewRows.value = [] + } + + return { + showPreview, previewType, previewSrc, previewRows, + openPreview, cleanupPreview + } +}