|
@@ -2,8 +2,8 @@
|
|
|
<template>
|
|
|
<div :key="uploadKey">
|
|
|
<el-divider v-if="showDivider" content-position="left"><i class="el-icon-document"></i> {{ dividerName }}
|
|
|
- <el-upload ref="upload" style="display: inline-block; :show-header='status'" action="" :limit="999"
|
|
|
- :http-request="httpRequest" multiple :on-exceed="(files, fileList) => {
|
|
|
+ <el-upload ref="upload" style="display: inline-block;" :show-header="'status'" action="" :limit="999"
|
|
|
+ :on-success="handleSuccessUpload" :http-request="httpRequest" multiple :on-exceed="(files, fileList) => {
|
|
|
$message.warning(`当前限制选择 999 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`)
|
|
|
}" :show-file-list="false" :before-upload="beforeUpload" :on-change="changes" :on-progress="uploadVideoProcess"
|
|
|
:file-list="fileList">
|
|
@@ -165,10 +165,6 @@ export default {
|
|
|
loading: false,
|
|
|
dataListLength: '',
|
|
|
uploadDelFlag: false,
|
|
|
- uploadingCount: 0, // 记录当前正在上传的文件数量
|
|
|
- totalCount: 0, // 记录总的文件数量
|
|
|
- duplicateFileNames: [], // 存储重复文件名
|
|
|
- noXmlFiles: [], // 存储非当前公司的文件名
|
|
|
// reNumFiles: [], // 存储重复发票号
|
|
|
toCompany: '', //用于区分属于哪个公司的数电发票,
|
|
|
fileLabel: [
|
|
@@ -360,6 +356,11 @@ export default {
|
|
|
async httpRequest(file) {
|
|
|
await httpRequest(file, fileNameInvoice(file), this.directory, this.maxValue)
|
|
|
},
|
|
|
+ handleSuccessUpload(response, file, fileList) {
|
|
|
+ // console.log(response, file, fileList);
|
|
|
+
|
|
|
+
|
|
|
+ },
|
|
|
async beforeUpload(file) {
|
|
|
if (this.uploadDelFlag) {
|
|
|
this.$message.warning('该文件已上传,请勿重复上传');
|
|
@@ -502,209 +503,112 @@ export default {
|
|
|
}
|
|
|
},
|
|
|
async changes(file, fileList) {
|
|
|
- try {
|
|
|
-
|
|
|
+ if (file.status == 'ready') return //阻止上传多次触发changes
|
|
|
|
|
|
+ try {
|
|
|
this.uploadKey = Math.random();
|
|
|
-
|
|
|
- // 用来存放没有重复且有有效URL的文件,准备上传
|
|
|
- let filesToUpload = [];
|
|
|
- let validFiles = [];
|
|
|
-
|
|
|
- // 用于存储已经上传的文件 `lastModified` + `size` 作为唯一标识
|
|
|
- let uploadedFileIdentifiers = new Set();
|
|
|
- for (let existingFile of this.dataListNew) {
|
|
|
- const existingFileName = existingFile.name; // 假设每个文件有 `name` 属性
|
|
|
- uploadedFileIdentifiers.add(existingFileName); // 将已有文件的名称添加到 Set 中
|
|
|
- }
|
|
|
-
|
|
|
// 2. 文件大小检查
|
|
|
if (!beforeAvatarUpload(file, fileList, this.maxValue)) {
|
|
|
this.$message.error('文件大小不能超过 ' + this.maxValue + ' MB!');
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- // 3. 验证文件是否重复(使用 `lastModified` 和 `size` 来判断)
|
|
|
- for (let item of fileList) {
|
|
|
- const fileName = item.raw ? item.raw.name : item.name;
|
|
|
- const fileIdentifier = fileName; // 唯一标识:文件大小 + 修改时间
|
|
|
-
|
|
|
- // 检查该文件标识是否已存在
|
|
|
- if (uploadedFileIdentifiers.has(fileIdentifier)) {
|
|
|
- // 记录重复文件名
|
|
|
- const formBody = new FormData();
|
|
|
- formBody.append('file', item.raw);
|
|
|
- console.log(formBody)
|
|
|
- const data = await this.ossService.disposeXmlFile(formBody);
|
|
|
- if (this.commonJS.isNotEmpty(data.InvoiceNumber)) {
|
|
|
- this.duplicateFileNames.push("文件名: " + fileName + "—— 发票号:" + data.InvoiceNumber);
|
|
|
- }
|
|
|
- } else {
|
|
|
- // 文件没有重复,加入上传列表
|
|
|
- filesToUpload.push(item);
|
|
|
- uploadedFileIdentifiers.add(fileIdentifier); // 将文件标识加入已上传集合
|
|
|
+ const fileName = file.raw ? file.raw.name : file.name;
|
|
|
+ //判断文件是否重复
|
|
|
+ let fileIndex = this.dataList.findIndex(fileItem => {
|
|
|
+ return fileItem.name == file.name
|
|
|
+ })
|
|
|
+ if (fileIndex != -1) {
|
|
|
+ // 记录重复文件名
|
|
|
+ const formBody = new FormData();
|
|
|
+ formBody.append('file', file.raw);
|
|
|
+ const data1 = await this.ossService.disposeXmlFile(formBody);
|
|
|
+ if (this.commonJS.isNotEmpty(data1.InvoiceNumber)) {
|
|
|
+ this.$message.warning({ message: `数电发票:${fileName + "<br/>发票号:" + data1.InvoiceNumber}<br/>已经上传,请勿重复上传`, dangerouslyUseHTMLString: true });
|
|
|
+ return
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // 4. 如果没有文件需要上传,则直接返回
|
|
|
- // if (filesToUpload.length === 0) return;
|
|
|
-
|
|
|
- // 5. 删除无效URL的文件
|
|
|
- let invalidFiles = []; // 用于存储需要删除的文件
|
|
|
-
|
|
|
- // 使用异步操作来判断文件URL的有效性
|
|
|
- for (let item of filesToUpload) {
|
|
|
- const fileUrl = item.raw ? item.raw.url : item.url;
|
|
|
-
|
|
|
- // 检查临时 URL 是否有效
|
|
|
- if (fileUrl && fileUrl.trim() !== '') {
|
|
|
- try {
|
|
|
- const temporaryUrl = await this.ossService.getTemporaryUrl(fileUrl);
|
|
|
-
|
|
|
- if (!temporaryUrl || temporaryUrl.trim() === '') {
|
|
|
- // 如果临时 URL 无效,则标记该文件为无效并删除
|
|
|
- invalidFiles.push(item);
|
|
|
- } else {
|
|
|
- // 如果临时 URL 有效,继续添加文件到有效文件列表
|
|
|
- validFiles.push(item);
|
|
|
- item.lsUrl = temporaryUrl;
|
|
|
- }
|
|
|
- } catch (error) {
|
|
|
- // 如果临时 URL 获取失败,也标记该文件为无效
|
|
|
- invalidFiles.push(item);
|
|
|
+ const fileUrl = file.raw ? file.raw.url : file.url;
|
|
|
+ // 检查临时 URL 是否有效
|
|
|
+ if (fileUrl && fileUrl.trim() !== '') {
|
|
|
+ try {
|
|
|
+ const temporaryUrl = await this.ossService.getTemporaryUrl(fileUrl);
|
|
|
+
|
|
|
+ if (!temporaryUrl || temporaryUrl.trim() === '') {
|
|
|
+ // 如果临时 URL 无效,则标记该文件为无效并删除
|
|
|
+ this.$message.warning({ message: `数电发票:${file.name}获取失败,上传失败。` });
|
|
|
+ return
|
|
|
+ } else {
|
|
|
+ // 如果临时 URL 有效,继续添加文件到有效文件列表
|
|
|
+ file.lsUrl = temporaryUrl;
|
|
|
}
|
|
|
+ } catch (error) {
|
|
|
+ // 如果临时 URL 获取失败,也标记该文件为无效
|
|
|
+ this.$message.warning({ message: `数电发票:${file.name}获取失败,上传失败。` });
|
|
|
+ return
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- filesToUpload = validFiles; // 只保留有效的文件
|
|
|
-
|
|
|
// 6. 给文件添加上传时间和上传人
|
|
|
- for (let item of filesToUpload) {
|
|
|
- item.createTime = moment(new Date()).format('YYYY-MM-DD HH:mm:ss');
|
|
|
- item.createBy = {
|
|
|
- id: this.$store.state.user.id,
|
|
|
- name: this.$store.state.user.name,
|
|
|
- };
|
|
|
- }
|
|
|
-
|
|
|
- const validCompanyFiles = [];//存放符合公司的文件
|
|
|
- let errorFiles = [];//存放数据格式错误的文件
|
|
|
- let errorDateFiles = [];//存放日期格式错误的文件
|
|
|
- let isUsedFiles = [];//存放已经被报销的文件
|
|
|
- for (let i = 0; i < filesToUpload.length; i++) {
|
|
|
- const item = filesToUpload[i];
|
|
|
- if (item.raw !== undefined && item.raw !== null && item.raw !== {}) {
|
|
|
- // 设置文件的 URL
|
|
|
- item.url = item.raw.url;
|
|
|
-
|
|
|
- // 仅处理 XML 文件
|
|
|
- if (item.raw.name && item.raw.name.toLowerCase().endsWith(".xml")) {
|
|
|
- // 创建 FormData 对象并发送文件
|
|
|
- const formBody = new FormData();
|
|
|
- formBody.append('file', item.raw);
|
|
|
- // 调用后端接口解析 XML 文件
|
|
|
- let data = await this.ossService.disposeXmlFile(formBody);
|
|
|
- if (Object.keys(data).length > 0) {
|
|
|
- this.fieldComparison(data, this.fileLabel);
|
|
|
-
|
|
|
- // 如果文件的公司名称与this.toCompany不一致,则删除该文件
|
|
|
-
|
|
|
- // 检查 data 是否包含 BuyerInformationBuyerName 属性
|
|
|
- if (data && 'BuyerInformationBuyerName' in data) {
|
|
|
- // 验证是否有效,并进行替换操作
|
|
|
- if (typeof data.BuyerInformationBuyerName === 'string') {
|
|
|
- var buyerInformationBuyerName = data.BuyerInformationBuyerName
|
|
|
- .replace(/(/g, '(')
|
|
|
- .replace(/)/g, ')');
|
|
|
- data.BuyerInformationBuyerName = buyerInformationBuyerName
|
|
|
- }
|
|
|
+ file.createTime = moment(new Date()).format('YYYY-MM-DD HH:mm:ss');
|
|
|
+ file.createBy = {
|
|
|
+ id: this.$store.state.user.id,
|
|
|
+ name: this.$store.state.user.name,
|
|
|
+ };
|
|
|
+ if (file.raw !== undefined && file.raw !== null && file.raw !== {}) {
|
|
|
+ // 设置文件的 URL
|
|
|
+ file.url = file.raw.url;
|
|
|
+ // 仅处理 XML 文件
|
|
|
+ if (file.raw.name && file.raw.name.toLowerCase().endsWith(".xml")) {
|
|
|
+ // 创建 FormData 对象并发送文件
|
|
|
+ const formBody = new FormData();
|
|
|
+ formBody.append('file', file.raw);
|
|
|
+ // 调用后端接口解析 XML 文件
|
|
|
+ let data2 = await this.ossService.disposeXmlFile(formBody);
|
|
|
+ if (Object.keys(data2).length > 0) {
|
|
|
+ this.fieldComparison(data2, this.fileLabel);
|
|
|
+ // 检查 data 是否包含 BuyerInformationBuyerName 属性
|
|
|
+ if (data2 && 'BuyerInformationBuyerName' in data2) {
|
|
|
+ // 验证是否有效,并进行替换操作
|
|
|
+ if (typeof data2.BuyerInformationBuyerName === 'string') {
|
|
|
+ var buyerInformationBuyerName = data2.BuyerInformationBuyerName
|
|
|
+ .replace(/(/g, '(')
|
|
|
+ .replace(/)/g, ')');
|
|
|
+ data2.BuyerInformationBuyerName = buyerInformationBuyerName
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- if (this.toCompany !== data.BuyerInformationBuyerName) {
|
|
|
- this.noXmlFiles.push("文件名: " + item.raw.name + "—— 发票号:" + data.InvoiceNumber)
|
|
|
- // this.$message.warning("仅可上传江苏兴光项目管理有限公司的报销数电发票");
|
|
|
- continue;
|
|
|
+ if (this.toCompany !== data2.BuyerInformationBuyerName) {
|
|
|
+ this.$message.warning({ message: `仅可上传${this.toCompany}的报销数电发票:<br/>${"文件名: " + file.raw.name + "—— 发票号:" + data2.InvoiceNumber}<br>上传失败 `, dangerouslyUseHTMLString: true });
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if (this.commonJS.isNotEmpty(data2.InvoiceNumber)) {
|
|
|
+ var flag = this.invoiceReimbursementDispose(data2)
|
|
|
+ if (flag) {
|
|
|
+ this.$message.warning({ message: `数电发票:${file.raw.name + "-" + data2.InvoiceNumber}<br/>已经上传,请勿重复上传`, dangerouslyUseHTMLString: true });
|
|
|
+ return
|
|
|
}
|
|
|
- if (this.commonJS.isNotEmpty(data.InvoiceNumber)) {
|
|
|
- var flag = this.invoiceReimbursementDispose(data)
|
|
|
- if (flag) {
|
|
|
- this.duplicateFileNames.push(item.raw.name + "-" + data.InvoiceNumber)
|
|
|
- continue;
|
|
|
- }
|
|
|
- //查询当前发票号是否已经被报销
|
|
|
- let isUsed = await this.ossService.isUsedByInvoiceNumber(data.InvoiceNumber);
|
|
|
- if (isUsed) {
|
|
|
- isUsedFiles.push("文件名: " + item.raw.name + "—— 发票号:" + data.InvoiceNumber)
|
|
|
- continue;
|
|
|
- }
|
|
|
- let inDate = this.formatDate(data.IssueTime)
|
|
|
- if (inDate.indexOf("NaN") != -1 && this.commonJS.isNotEmpty(inDate)) {
|
|
|
- errorDateFiles.push("文件名: " + item.raw.name + "—— 发票号:" + data.InvoiceNumber);
|
|
|
- continue;
|
|
|
- }
|
|
|
- validCompanyFiles.push(item); // 符合条件的文件
|
|
|
+ //查询当前发票号是否已经被报销
|
|
|
+ let isUsed = await this.ossService.isUsedByInvoiceNumber(data2.InvoiceNumber);
|
|
|
+ if (isUsed) {
|
|
|
+ this.$message.warning({ message: `数电发票:${file.raw.name + "<br/> 发票号:" + data2.InvoiceNumber}<br/>已经发起或已完成报销,无法重复报销`, dangerouslyUseHTMLString: true });
|
|
|
+ return
|
|
|
+ }
|
|
|
+ let inDate = this.formatDate(data2.IssueTime)
|
|
|
+ if (inDate.indexOf("NaN") != -1 && this.commonJS.isNotEmpty(inDate)) {
|
|
|
+ this.$message.warning({ message: `数电发票:${file.raw.name + "<br/> 发票号:" + data2.InvoiceNumber}<br/>日期格式错误,上传失败。`, dangerouslyUseHTMLString: true });
|
|
|
+ return
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
+
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- filesToUpload = validCompanyFiles;
|
|
|
// 将新符合条件的文件追加到原文件列表上
|
|
|
- this.dataListNew = [...this.dataList, ...filesToUpload];
|
|
|
- this.fileList = [...filesToUpload];
|
|
|
- // 记录上传文件的数量
|
|
|
- this.totalCount = fileList.length;
|
|
|
- //记录changes方法执行了多少次,此处加判定是为了处理防抖,change方法会对每一个文件执行两次,此处判定后只会增加一次
|
|
|
- if (file.status !== 'ready') {
|
|
|
- this.uploadingCount++
|
|
|
- }
|
|
|
-
|
|
|
- // 9. 检查是否是最后一个文件上传,如果是,执行一次去重和提示
|
|
|
- if (this.uploadingCount === this.totalCount) {
|
|
|
- this.duplicateFileNames = [...new Set(this.duplicateFileNames)];
|
|
|
- this.noXmlFiles = [...new Set(this.noXmlFiles)];
|
|
|
- // this.reNumFiles = [...new Set(this.reNumFiles)];
|
|
|
- errorFiles = [...new Set(errorFiles)];
|
|
|
- invalidFiles = [...new Set(invalidFiles)];
|
|
|
- errorDateFiles = [...new Set(errorDateFiles)];
|
|
|
- isUsedFiles = [...new Set(isUsedFiles)];
|
|
|
- // 提示重复文件
|
|
|
- if (this.duplicateFileNames.length > 0) {
|
|
|
- this.$message.warning({ message: `以下文件已经上传,请勿重复上传:<br>${this.duplicateFileNames.join('<br>')} `, dangerouslyUseHTMLString: true });
|
|
|
- }
|
|
|
- // 提示xml文件不是当前公司报销的文件
|
|
|
- if (this.noXmlFiles.length > 0) {
|
|
|
- this.$message.warning({ message: `仅可上传${this.toCompany}的报销数电发票:<br>${this.noXmlFiles.join('<br>')}<br>上传失败 `, dangerouslyUseHTMLString: true });
|
|
|
- }
|
|
|
- // 提示发票号重复文件
|
|
|
- // if (this.reNumFiles.length > 0) {
|
|
|
- // this.$message.error(`发票号:\n${this.reNumFiles.join('\n')}已上传,请勿重复上传`);
|
|
|
- // }
|
|
|
- //数电发票格式错误的文件
|
|
|
- if (errorFiles.length > 0) {
|
|
|
- this.$message.warning({ message: `上传的数电发票格式错误:<br>${errorFiles.join('<br>')}`, dangerouslyUseHTMLString: true });
|
|
|
- }
|
|
|
- //临时路径错误的文件
|
|
|
- if (invalidFiles.length > 0) {
|
|
|
- this.$message.warning({ message: `数电发票: <br>${invalidFiles.join('<br>')}<br>获取失败,上传失败。`, dangerouslyUseHTMLString: true });
|
|
|
- }
|
|
|
- //临时路径错误的文件
|
|
|
- if (errorDateFiles.length > 0) {
|
|
|
- this.$message.warning({ message: `数电发票: <br>${errorDateFiles.join('<br>')}<br>日期格式错误,上传失败。`, dangerouslyUseHTMLString: true });
|
|
|
- }
|
|
|
- //已经被报销的文件
|
|
|
- if (isUsedFiles.length > 0) {
|
|
|
- this.$message.warning({ message: `数电发票: <br>${isUsedFiles.join('<br>')}<br>已经发起或已完成报销,无法重复报销`, dangerouslyUseHTMLString: true });
|
|
|
- }
|
|
|
- // 重置计数器
|
|
|
- this.uploadingCount = 0;
|
|
|
- this.totalCount = 0; // 可以根据需求来重置
|
|
|
- this.duplicateFileNames = []; // 清空记录
|
|
|
- this.noXmlFiles = []; // 清空记录
|
|
|
- this.reNumFiles = []; // 清空记录
|
|
|
- this.dataList = this.dataListNew
|
|
|
- }
|
|
|
+ this.dataListNew.push(file)
|
|
|
+ this.fileList.push(file)
|
|
|
+ this.dataList = this.dataListNew
|
|
|
// 清空 fileList,如果 fileList 不为空
|
|
|
if (fileList && fileList.length > 0) {
|
|
|
this.fileList = [];
|