Files
school-developer/src/views/purchase/purchasingrequisition/UpdateFilesDialog.vue

212 lines
5.7 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 :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格式文件每个类型仅能上传1个文件如需更新请先删除原文件" type="info" :closable="false" style="margin-bottom: 16px" />
<el-empty v-if="uploadedFileTypes.length === 0" description="该采购申请暂无上传材料" />
<el-form v-else label-width="120px">
<el-form-item label="采购编号">
<el-input v-model="purchaseNo" disabled />
</el-form-item>
<el-form-item v-for="item in displayedFileTypes" :key="item.value" :label="item.label">
<upload-file
v-model="fileMap[item.value]"
:limit="1"
: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>
</template>
</el-dialog>
</template>
<script setup lang="ts">
import { ref, reactive, computed, nextTick } from 'vue';
import { Upload } from '@element-plus/icons-vue';
import { useMessage } from '/@/hooks/message';
import { updateFiles, getApplyFiles } 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 uploadedFileTypes = ref<string[]>([]);
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: '采购需求明细表' },
];
// 根据已上传文件类型过滤显示列表排除履约验收110和采购文件130
const displayedFileTypes = computed(() => {
return fileTypeList.filter(
(item) =>
uploadedFileTypes.value.includes(item.value) &&
item.value !== '110' &&
item.value !== '130'
);
});
const open = async (id: string, no?: string) => {
purchaseId.value = id || '';
purchaseNo.value = no || '';
visible.value = true;
// 清空文件列表
fileTypeList.forEach((item) => {
fileMap[item.value] = [];
});
uploadedFileTypes.value = [];
// 获取已上传的文件
try {
const res = await getApplyFiles(id);
const files = res?.data || [];
// 收集已上传的文件类型
const fileTypes = new Set<string>();
files.forEach((file: any) => {
if (file.fileType) {
fileTypes.add(String(file.fileType));
// 初始化已有文件的类型列表
if (!fileMap[file.fileType]) {
fileMap[file.fileType] = [];
}
fileMap[file.fileType].push({
id: file.id,
name: file.fileTitle || '附件',
url: file.fileUrl,
});
}
});
uploadedFileTypes.value = Array.from(fileTypes);
} catch (e) {
console.error('获取已上传文件失败', e);
}
};
const handleUploadSuccess = (res: any, fileType: string) => {
if (res && res.data) {
useMessage().success('上传成功');
// 自动提交更新
nextTick(() => {
handleSubmit();
});
}
};
const handleSubmit = async () => {
if (!purchaseId.value) {
useMessage().warning('无法获取采购申请ID');
return;
}
// 收集所有当前显示的文件ID排除履约验收110和采购文件130
const allFileIds: string[] = [];
uploadedFileTypes.value
.filter((ft) => ft !== '110' && ft !== '130')
.forEach((fileType) => {
const files = fileMap[fileType] || [];
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>