feat: 添加更新材料弹窗组件

- 支持按文件类型分类上传
- 限制仅PDF格式文件
- 支持批量上传更新

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
吴红兵
2026-03-03 22:44:26 +08:00
parent 6a1cc54c8b
commit 36ad8f14e4

View File

@@ -0,0 +1,181 @@
<template>
<el-dialog
v-model="visible"
title="更新材料"
width="900px"
destroy-on-close
append-to-body
:close-on-click-modal="false"
>
<template #header>
<div class="dialog-header">
<span class="dialog-title">
<el-icon><Upload /></el-icon>
更新材料 - {{ purchaseNo || purchaseId }}
</span>
</div>
</template>
<el-alert
title="仅支持上传PDF格式文件上传新文件将替换原有同类型文件"
type="info"
:closable="false"
style="margin-bottom: 16px"
/>
<el-form label-width="120px">
<el-form-item label="采购编号">
<el-input v-model="purchaseNo" disabled />
</el-form-item>
<el-form-item
v-for="item in fileTypeList"
:key="item.value"
:label="item.label"
>
<upload-file
v-model="fileMap[item.value]"
:limit="5"
:file-type="['pdf']"
:data="{ fileType: item.value, purchaseId: purchaseId }"
upload-file-url="/purchase/purchasingfiles/upload"
@success="(res) => handleUploadSuccess(res, item.value)"
/>
<div class="file-tips">{{ item.desc }}</div>
</el-form-item>
</el-form>
<template #footer>
<el-button @click="visible = false">取消</el-button>
<el-button type="primary" :loading="submitting" @click="handleSubmit">
确认更新
</el-button>
</template>
</el-dialog>
</template>
<script setup lang="ts">
import { ref, reactive } from 'vue'
import { Upload } from '@element-plus/icons-vue'
import { useMessage } from '/@/hooks/message'
import { updateFiles } from '/@/api/purchase/purchasingrequisition'
interface FileItem {
id: string
name: string
url: string
}
interface FileTypeItem {
value: string
label: string
desc: string
}
const visible = ref(false)
const submitting = ref(false)
const purchaseId = ref('')
const purchaseNo = ref('')
const fileMap = reactive<Record<string, FileItem[]>>({})
const fileTypeList: FileTypeItem[] = [
{ value: '10', label: '商务洽谈纪要', desc: '商务洽谈相关纪要文件' },
{ value: '20', label: '市场采购纪要', desc: '市场采购相关纪要文件' },
{ value: '30', label: '网上商城采购材料', desc: '网上商城采购相关材料' },
{ value: '40', label: '可行性论证报告', desc: '项目可行性论证报告' },
{ value: '50', label: '会议记录', desc: '相关会议记录文件' },
{ value: '60', label: '其他材料', desc: '其他相关材料' },
{ value: '70', label: '单一来源专家论证表', desc: '单一来源采购专家论证表' },
{ value: '80', label: '进口产品申请表', desc: '进口产品申请相关表格' },
{ value: '90', label: '进口产品专家论证表', desc: '进口产品专家论证表' },
{ value: '100', label: '政府采购意向表', desc: '政府采购意向公示表' },
{ value: '110', label: '履约验收单', desc: '履约验收相关单据' },
{ value: '120', label: '采购需求表', desc: '采购需求明细表' },
]
const open = (id: string, no?: string) => {
purchaseId.value = id || ''
purchaseNo.value = no || ''
visible.value = true
// 清空文件列表
fileTypeList.forEach((item) => {
fileMap[item.value] = []
})
}
const handleUploadSuccess = (res: any, fileType: string) => {
if (res && res.data) {
useMessage().success('上传成功')
}
}
const handleSubmit = async () => {
if (!purchaseId.value) {
useMessage().warning('无法获取采购申请ID')
return
}
// 收集所有上传的文件ID
const allFileIds: string[] = []
fileTypeList.forEach((item) => {
const files = fileMap[item.value] || []
files.forEach((file) => {
if (file.id) {
allFileIds.push(file.id)
}
})
})
if (allFileIds.length === 0) {
useMessage().warning('请至少上传一个文件')
return
}
submitting.value = true
try {
await updateFiles({
purchaseId: purchaseId.value,
fileIds: allFileIds,
})
useMessage().success('更新材料成功')
visible.value = false
emit('refresh')
} catch (err: any) {
useMessage().error(err?.msg || '更新材料失败')
} finally {
submitting.value = false
}
}
const emit = defineEmits<{
(e: 'refresh'): void
}>()
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-tips {
font-size: 12px;
color: #909399;
margin-top: 4px;
}
</style>