Merge branch 'feature-purchase' into developer

This commit is contained in:
吴红兵
2026-03-04 13:15:25 +08:00

View File

@@ -1,12 +1,5 @@
<template> <template>
<el-dialog <el-dialog v-model="visible" title="更新材料" width="900px" destroy-on-close append-to-body :close-on-click-modal="false">
v-model="visible"
title="更新材料"
width="900px"
destroy-on-close
append-to-body
:close-on-click-modal="false"
>
<template #header> <template #header>
<div class="dialog-header"> <div class="dialog-header">
<span class="dialog-title"> <span class="dialog-title">
@@ -16,23 +9,16 @@
</div> </div>
</template> </template>
<el-alert <el-alert title="仅支持上传PDF格式文件上传新文件将替换原有同类型文件" type="info" :closable="false" style="margin-bottom: 16px" />
title="仅支持上传PDF格式文件上传新文件将替换原有同类型文件"
type="info"
:closable="false"
style="margin-bottom: 16px"
/>
<el-form label-width="120px"> <el-empty v-if="uploadedFileTypes.length === 0" description="该采购申请暂无上传材料" />
<el-form v-else label-width="120px">
<el-form-item label="采购编号"> <el-form-item label="采购编号">
<el-input v-model="purchaseNo" disabled /> <el-input v-model="purchaseNo" disabled />
</el-form-item> </el-form-item>
<el-form-item <el-form-item v-for="item in displayedFileTypes" :key="item.value" :label="item.label">
v-for="item in fileTypeList"
:key="item.value"
:label="item.label"
>
<upload-file <upload-file
v-model="fileMap[item.value]" v-model="fileMap[item.value]"
:limit="5" :limit="5"
@@ -47,37 +33,38 @@
<template #footer> <template #footer>
<el-button @click="visible = false">取消</el-button> <el-button @click="visible = false">取消</el-button>
<el-button type="primary" :loading="submitting" @click="handleSubmit"> <el-button type="primary" :loading="submitting" @click="handleSubmit"> 确认更新 </el-button>
确认更新
</el-button>
</template> </template>
</el-dialog> </el-dialog>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, reactive } from 'vue' import { ref, reactive, computed, nextTick } from 'vue';
import { Upload } from '@element-plus/icons-vue' import { Upload } from '@element-plus/icons-vue';
import { useMessage } from '/@/hooks/message' import { useMessage } from '/@/hooks/message';
import { updateFiles } from '/@/api/purchase/purchasingrequisition' import { updateFiles, getApplyFiles } from '/@/api/purchase/purchasingrequisition';
interface FileItem { interface FileItem {
id: string id: string;
name: string name: string;
url: string url: string;
} }
interface FileTypeItem { interface FileTypeItem {
value: string value: string;
label: string label: string;
desc: string desc: string;
} }
const visible = ref(false) const visible = ref(false);
const submitting = ref(false) const submitting = ref(false);
const purchaseId = ref('') const purchaseId = ref('');
const purchaseNo = ref('') const purchaseNo = ref('');
const fileMap = reactive<Record<string, FileItem[]>>({}) const fileMap = reactive<Record<string, FileItem[]>>({});
// 已上传文件类型列表(只显示有文件的类型)
const uploadedFileTypes = ref<string[]>([]);
const fileTypeList: FileTypeItem[] = [ const fileTypeList: FileTypeItem[] = [
{ value: '10', label: '商务洽谈纪要', desc: '商务洽谈相关纪要文件' }, { value: '10', label: '商务洽谈纪要', desc: '商务洽谈相关纪要文件' },
@@ -92,69 +79,102 @@ const fileTypeList: FileTypeItem[] = [
{ value: '100', label: '政府采购意向表', desc: '政府采购意向公示表' }, { value: '100', label: '政府采购意向表', desc: '政府采购意向公示表' },
{ value: '110', label: '履约验收单', desc: '履约验收相关单据' }, { value: '110', label: '履约验收单', desc: '履约验收相关单据' },
{ value: '120', label: '采购需求表', desc: '采购需求明细表' }, { value: '120', label: '采购需求表', desc: '采购需求明细表' },
] ];
const open = (id: string, no?: string) => { // 根据已上传文件类型过滤显示列表
purchaseId.value = id || '' const displayedFileTypes = computed(() => {
purchaseNo.value = no || '' return fileTypeList.filter((item) => uploadedFileTypes.value.includes(item.value));
visible.value = true });
const open = async (id: string, no?: string) => {
purchaseId.value = id || '';
purchaseNo.value = no || '';
visible.value = true;
// 清空文件列表 // 清空文件列表
fileTypeList.forEach((item) => { fileTypeList.forEach((item) => {
fileMap[item.value] = [] 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.fileName,
url: file.fileUrl,
});
}
});
uploadedFileTypes.value = Array.from(fileTypes);
} catch (e) {
console.error('获取已上传文件失败', e);
}
};
const handleUploadSuccess = (res: any, fileType: string) => { const handleUploadSuccess = (res: any, fileType: string) => {
if (res && res.data) { if (res && res.data) {
useMessage().success('上传成功') useMessage().success('上传成功');
} }
} };
const handleSubmit = async () => { const handleSubmit = async () => {
if (!purchaseId.value) { if (!purchaseId.value) {
useMessage().warning('无法获取采购申请ID') useMessage().warning('无法获取采购申请ID');
return return;
} }
// 收集所有上传的文件ID // 收集所有当前显示的文件ID
const allFileIds: string[] = [] const allFileIds: string[] = [];
fileTypeList.forEach((item) => { uploadedFileTypes.value.forEach((fileType) => {
const files = fileMap[item.value] || [] const files = fileMap[fileType] || [];
files.forEach((file) => { files.forEach((file) => {
if (file.id) { if (file.id) {
allFileIds.push(file.id) allFileIds.push(file.id);
} }
}) });
}) });
if (allFileIds.length === 0) { if (allFileIds.length === 0) {
useMessage().warning('请至少上传一个文件') useMessage().warning('请至少保留或上传一个文件');
return return;
} }
submitting.value = true submitting.value = true;
try { try {
await updateFiles({ await updateFiles({
purchaseId: purchaseId.value, purchaseId: purchaseId.value,
fileIds: allFileIds, fileIds: allFileIds,
}) });
useMessage().success('更新材料成功') useMessage().success('更新材料成功');
visible.value = false visible.value = false;
emit('refresh') emit('refresh');
} catch (err: any) { } catch (err: any) {
useMessage().error(err?.msg || '更新材料失败') useMessage().error(err?.msg || '更新材料失败');
} finally { } finally {
submitting.value = false submitting.value = false;
} }
} };
const emit = defineEmits<{ const emit = defineEmits<{
(e: 'refresh'): void (e: 'refresh'): void;
}>() }>();
defineExpose({ defineExpose({
open, open,
}) });
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">