多文件上传表格展示
1、实现效果
新增/修改附件信息
展示附件信息
2、源码实现
<template>
<el-dialog
:title="title"
:visible.sync="visible"
:before-close="handleClose"
width="80%"
:close-on-click-modal="false"
>
<div v-if="type!=='review'" class="content-box">
<h3>附件信息</h3>
<el-table
border
stripe
:data="reportFileInfoList"
>
<el-table-column type="index" label="序号" width="55" align="center">
</el-table-column>
<el-table-column
v-for="(item, index) in attachmentColumns"
:key="index"
:prop="item.prop"
:label="item.label"
:min-width="item.width"
align="center"
>
<template v-slot="scope">
<div v-if="item.prop == 'fileName'">
<el-tag
v-for="(item, index) in scope.row.fileName"
:key="item"
type=""
closable
@close="handleRemoveTag(scope.row, item)"
>
{{item}}
</el-tag>
</div>
<span v-else> {{ scope.row[item.prop] }} </span>
</template>
</el-table-column>
<el-table-column
label="上传附件"
width="120"
align="center"
>
<template v-slot="scope">
<!-- <span class="opr-btn">上传附件</span> -->
<el-upload
class="upload-demo"
action="#"
:auto-upload="true"
:before-upload="beforeUpload"
:file-list="fileList"
:show-file-list="false"
>
<el-button size="mini" type="text" @click="selectRow(scope.row)">点击上传</el-button>
</el-upload>
</template>
</el-table-column>
</el-table>
</div>
<!-- 查看详情部分 -->
<div v-if="type == 'review'" class="content-box">
<h3>附件信息</h3>
<el-table
border
stripe
v-if="type == 'review'"
:data="reportFileInfoListTemp"
>
<el-table-column type="index" label="序号" width="55" align="center">
</el-table-column>
<el-table-column
v-for="(item, index) in attachmentColumnsReview"
:key="index"
:prop="item.prop"
:label="item.label"
:min-width="item.width"
align="center"
>
</el-table-column>
</el-table>
</div>
<div slot="footer" class="dialog-footer">
<el-button size="small" @click="handleClose">取 消</el-button>
<el-button size="small" type="primary" @click="handleSubmit">确 定</el-button>
</div>
</el-dialog>
</template>
<script>
import { uploadFile } from "@/api/xxxx/index.js"
export default {
data() {
return {
visible: false,
type: "add",
fileType: "",
reportFileInfoListTemp: [],
reportFileInfoList: [
{
type: "发票",
fileName: [],
fileId: [],
},
{
type: "附件信息",
fileName: [],
fileId: [],
},
{
type: "电子附件",
fileName: [],
fileId: [],
},
],
attachmentColumns: [
{
prop: "type",
label: "附件类型",
width: 120,
},
{
prop: "fileName",
label: "附件信息",
width: 260,
},
],
attachmentColumnsReview: [
{
prop: "type",
label: "附件类型",
width: 120,
},
{
prop: "fileName",
label: "附件信息",
width: 260,
},
{
prop: "fileFlowNo",
label: "文件流水号",
width: 120,
},
{
prop: "fileStatus",
label: "文件状态",
width: 100,
},
],
fileList: [],
reportDealHisList: [],
};
},
computed: {
disabled() {
return this.type === "review";
},
title() {
if(this.type == "review") {
return "查看信息"
} else if(this.type == "add") {
return "新增信息"
} else {
return "修改信息"
}
},
},
methods: {
handleClose() {
this.visible = false;
this.reportFileInfoList = [
{
type: "发票",
fileName: [],
fileId: [],
},
{
type: "附件信息",
fileName: [],
fileId: [],
},
{
type: "电子附件",
fileName: [],
fileId: [],
},
],
},
// 合并 reportFileInfoList
mergeReportFileInfoList(originalList) {
const mergedMap = new Map();
// 合并原始数据
originalList.forEach(item => {
if (mergedMap.has(item.type)) {
const mergedItem = mergedMap.get(item.type);
mergedItem.fileName.push(item.fileName);
mergedItem.fileId.push(item.fileId);
} else {
mergedMap.set(item.type, {
type: item.type,
fileName: [item.fileName],
fileId: [item.fileId]
});
}
});
// 确保包含 "发票", "附件信息", "电子附件" 类型
const defaultTypes = ["发票", "附件信息", "电子附件"];
defaultTypes.forEach(type => {
if (!mergedMap.has(type)) {
mergedMap.set(type, {
type: type,
fileName: [],
fileId: []
});
}
});
return Array.from(mergedMap.values());
},
handleOpen(val) {
this.visible = true;
this.type = val.type;
if(this.type == "add") {
this.reportExpensesInfo.reportingPeriod = this.$moment().format("YYYY-MM");
return
}
this.reportFileInfoListTemp = val.row.reportFileInfoList || [];
const originalReportFileInfoList = val.row.reportFileInfoList || [];
// 调用合并方法
this.reportFileInfoList = this.mergeReportFileInfoList(originalReportFileInfoList);
},
handleSubmit() {
this.$refs.form.validate((valid) => {
if (!valid) return
const params = {
reportFileInfoList: this.reportFileInfoListTemp,
}
this.$emit("handleSubmit", params);
this.handleClose();
})
},
beforeUpload(file) {
const params = new FormData()
params.append('file', file)
uploadFile(params).then(res => {
if(res.code == 200) {
this.$message.success(res.msg)
this.reportFileInfoListTemp.push({
type: this.fileType,
fileName: res.data.fileName,
fileId: res.data.fileId,
})
this.reportFileInfoList = this.reportFileInfoList.map(item => {
if(item.type == this.fileType) {
item.fileId.push(res.data.fileId);
item.fileName.push(res.data.fileName)
}
return item
})
}
})
return false;
},
selectRow(row) {
this.fileType = row.type
},
// 移除文件
handleRemoveTag(row, tag){
// 删除 reportFileInfoListTemp 中 filename 和 tag 匹配的项
this.reportFileInfoListTemp = this.reportFileInfoListTemp.filter(item => item.fileName !== tag);
// 删除表格中 filename 与 tag 匹配的项
this.reportFileInfoList= this.reportFileInfoList.map(item => {
if(item.type == row.type) {
const index = item.fileName.indexOf(tag);
if (index > -1) {
// 移除对应的文件名
item.fileName.splice(index, 1);
// 移除对应的文件ID
item.fileId.splice(index, 1);
}
}
return item
})
}
},
};
</script>
<style lang="scss" scoped>
.dialog-footer {
text-align: center;
}
.opr-btn {
cursor: pointer;
color: #409eff;
}
h3 {
margin: 10px 0;
}
.el-tag {
margin: 0 5px;
}
</style>