feat: 优化更新材料页面,只显示已上传的文件类型
- 调用 getApplyFiles API 获取已上传文件 - 根据已上传文件类型过滤显示列表 - 无材料时显示空状态提示
This commit is contained in:
@@ -1,181 +1,201 @@
|
|||||||
<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"
|
<template #header>
|
||||||
title="更新材料"
|
<div class="dialog-header">
|
||||||
width="900px"
|
<span class="dialog-title">
|
||||||
destroy-on-close
|
<el-icon><Upload /></el-icon>
|
||||||
append-to-body
|
更新材料 - {{ purchaseNo || purchaseId }}
|
||||||
:close-on-click-modal="false"
|
</span>
|
||||||
>
|
</div>
|
||||||
<template #header>
|
</template>
|
||||||
<div class="dialog-header">
|
|
||||||
<span class="dialog-title">
|
|
||||||
<el-icon><Upload /></el-icon>
|
|
||||||
更新材料 - {{ purchaseNo || purchaseId }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</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-item label="采购编号">
|
|
||||||
<el-input v-model="purchaseNo" disabled />
|
|
||||||
</el-form-item>
|
|
||||||
|
|
||||||
<el-form-item
|
<el-form v-else label-width="120px">
|
||||||
v-for="item in fileTypeList"
|
<el-form-item label="采购编号">
|
||||||
:key="item.value"
|
<el-input v-model="purchaseNo" disabled />
|
||||||
:label="item.label"
|
</el-form-item>
|
||||||
>
|
|
||||||
<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-form-item v-for="item in displayedFileTypes" :key="item.value" :label="item.label">
|
||||||
<el-button @click="visible = false">取消</el-button>
|
<upload-file
|
||||||
<el-button type="primary" :loading="submitting" @click="handleSubmit">
|
v-model="fileMap[item.value]"
|
||||||
确认更新
|
:limit="5"
|
||||||
</el-button>
|
:file-type="['pdf']"
|
||||||
</template>
|
:data="{ fileType: item.value, purchaseId: purchaseId }"
|
||||||
</el-dialog>
|
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>
|
</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: '商务洽谈相关纪要文件' },
|
||||||
{ value: '20', label: '市场采购纪要', desc: '市场采购相关纪要文件' },
|
{ value: '20', label: '市场采购纪要', desc: '市场采购相关纪要文件' },
|
||||||
{ value: '30', label: '网上商城采购材料', desc: '网上商城采购相关材料' },
|
{ value: '30', label: '网上商城采购材料', desc: '网上商城采购相关材料' },
|
||||||
{ value: '40', label: '可行性论证报告', desc: '项目可行性论证报告' },
|
{ value: '40', label: '可行性论证报告', desc: '项目可行性论证报告' },
|
||||||
{ value: '50', label: '会议记录', desc: '相关会议记录文件' },
|
{ value: '50', label: '会议记录', desc: '相关会议记录文件' },
|
||||||
{ value: '60', label: '其他材料', desc: '其他相关材料' },
|
{ value: '60', label: '其他材料', desc: '其他相关材料' },
|
||||||
{ value: '70', label: '单一来源专家论证表', desc: '单一来源采购专家论证表' },
|
{ value: '70', label: '单一来源专家论证表', desc: '单一来源采购专家论证表' },
|
||||||
{ value: '80', label: '进口产品申请表', desc: '进口产品申请相关表格' },
|
{ value: '80', label: '进口产品申请表', desc: '进口产品申请相关表格' },
|
||||||
{ value: '90', label: '进口产品专家论证表', desc: '进口产品专家论证表' },
|
{ value: '90', label: '进口产品专家论证表', desc: '进口产品专家论证表' },
|
||||||
{ 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
|
});
|
||||||
// 清空文件列表
|
|
||||||
fileTypeList.forEach((item) => {
|
const open = async (id: string, no?: string) => {
|
||||||
fileMap[item.value] = []
|
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.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">
|
||||||
.dialog-header {
|
.dialog-header {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dialog-title {
|
.dialog-title {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
.file-tips {
|
.file-tips {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
color: #909399;
|
color: #909399;
|
||||||
margin-top: 4px;
|
margin-top: 4px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user