Files
school-developer/src/views/purchase/purchasingrequisition/FileArchiveDialog.vue
吴红兵 bff8907f88 跟新
2026-03-05 09:37:01 +08:00

281 lines
6.4 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>