Files
school-developer/src/views/purchase/purchasingrequisition/FileArchiveDialog.vue
吴红兵 b997b3ba48 fix
2026-03-07 12:35:45 +08:00

237 lines
5.9 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<el-dialog v-model="visible" title="文件归档" width="900px" destroy-on-close append-to-body>
<template #header>
<div class="dialog-header">
<span class="dialog-title">
<el-icon><FolderOpened /></el-icon>
文件归档 - {{ purchaseNo || purchaseId }}
</span>
<el-button type="primary" :loading="downloading" @click="handleDownloadAll">
<el-icon><Download /></el-icon>
下载全部文件
</el-button>
</div>
</template>
<el-table v-loading="loading" :data="fileList" stripe border max-height="500px" class="file-table">
<el-table-column type="index" label="序号" width="60" align="center" />
<el-table-column prop="fileTitle" label="文件名称" min-width="220" show-overflow-tooltip>
<template #default="{ row }">
<div class="file-name">
<el-icon class="file-icon"><Document /></el-icon>
<span>{{ row.fileTitle }}</span>
</div>
</template>
</el-table-column>
<el-table-column prop="fileTypeDesc" label="文件类型" width="160" align="center">
<template #default="{ row }">
<el-tag type="info">{{ row.fileTypeDesc || '未知类型' }}</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="150" align="center" fixed="right">
<template #default="{ row }">
<el-button type="primary" link icon="View" @click="handlePreview(row)"> 预览 </el-button>
<el-button type="primary" link icon="Download" @click="handleDownloadFile(row)"> 下载 </el-button>
</template>
</el-table-column>
</el-table>
<div v-if="!loading && fileList.length === 0" class="empty-tip">
<el-empty description="暂无文件" />
</div>
<template #footer>
<el-button @click="visible = false">关闭</el-button>
</template>
</el-dialog>
<!-- PDF预览弹窗 -->
<el-dialog v-model="previewVisible" title="文件预览" width="90%" top="5vh" destroy-on-close append-to-body class="preview-dialog">
<div class="preview-container">
<iframe v-if="previewUrl" :src="previewUrl" class="preview-iframe" frameborder="0" />
</div>
</el-dialog>
</template>
<script setup lang="ts">
import { ref, computed, onUnmounted } from 'vue';
import { FolderOpened, Download, Document } from '@element-plus/icons-vue';
import { useMessage } from '/@/hooks/message';
import { listDownloadUrls, getArchiveDownloadUrl, downloadFileById, previewFileById } from '/@/api/purchase/purchasingrequisition';
import other from '/@/utils/other';
interface FileItem {
id: string;
fileTitle: string;
fileType: string;
fileTypeDesc: string;
downloadUrl: string;
}
const visible = ref(false);
const loading = ref(false);
const downloading = ref(false);
const previewVisible = ref(false);
const previewUrl = ref('');
const previewLoading = ref(false);
const purchaseId = ref('');
const purchaseNo = ref('');
const fileList = ref<FileItem[]>([]);
const open = async (id: string, no?: string) => {
purchaseId.value = id || '';
purchaseNo.value = no || '';
visible.value = true;
await loadFileList();
};
const loadFileList = async () => {
if (!purchaseId.value) {
useMessage().warning('无法获取采购申请ID');
return;
}
loading.value = true;
try {
const res = await listDownloadUrls(purchaseId.value);
if (res && res.data) {
fileList.value = res.data as FileItem[];
} else {
fileList.value = [];
}
} catch (err: any) {
useMessage().error(err?.msg || '获取文件列表失败');
fileList.value = [];
} finally {
loading.value = false;
}
};
const isPdfFile = (fileName: string): boolean => {
if (!fileName) return false;
const ext = fileName.toLowerCase().split('.').pop();
return ext === 'pdf';
};
const handlePreview = async (row: FileItem) => {
if (!row.id) {
useMessage().warning('文件ID不存在');
return;
}
if (!isPdfFile(row.fileTitle)) {
useMessage().info('仅支持PDF格式文件预览将为您下载文件');
handleDownloadFile(row);
return;
}
previewLoading.value = true;
previewVisible.value = true;
previewUrl.value = '';
try {
const res = await previewFileById(row.id);
const blob = res as unknown as Blob;
const url = window.URL.createObjectURL(blob);
previewUrl.value = url;
} catch (err: any) {
useMessage().error(err?.msg || '预览失败');
previewVisible.value = false;
} finally {
previewLoading.value = false;
}
};
const handleDownloadFile = async (row: FileItem) => {
if (!row.id) {
useMessage().warning('文件ID不存在');
return;
}
try {
const res = await downloadFileById(row.id);
const blob = res as unknown as Blob;
const url = window.URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = row.fileTitle || 'download';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
window.URL.revokeObjectURL(url);
} catch (err: any) {
useMessage().error(err?.msg || '下载失败');
}
};
const handleDownloadAll = () => {
if (!purchaseId.value) {
useMessage().warning('无法获取采购申请ID');
return;
}
downloading.value = true;
try {
const url = getArchiveDownloadUrl(purchaseId.value);
const fileName = `归档_${purchaseNo.value || purchaseId.value}.zip`;
other.downBlobFile(url, {}, fileName);
} finally {
setTimeout(() => {
downloading.value = false;
}, 500);
}
};
onUnmounted(() => {
if (previewUrl.value) {
window.URL.revokeObjectURL(previewUrl.value);
}
});
defineExpose({
open,
});
</script>
<style scoped lang="scss">
.dialog-header {
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
}
.dialog-title {
display: flex;
align-items: center;
gap: 8px;
font-size: 16px;
font-weight: 500;
}
.file-table {
width: 100%;
}
.file-name {
display: flex;
align-items: center;
gap: 8px;
}
.file-icon {
color: #409eff;
}
.empty-tip {
padding: 40px 0;
}
.preview-container {
width: 100%;
height: calc(90vh - 120px);
}
.preview-iframe {
width: 100%;
height: 100%;
}
</style>