Przeglądaj źródła

上传发票对字段进行处理

huangguoce 3 miesięcy temu
rodzic
commit
5c691cbdd1
1 zmienionych plików z 249 dodań i 176 usunięć
  1. 249 176
      src/views/common/DigitalInvoiceUploadComponent.vue

+ 249 - 176
src/views/common/DigitalInvoiceUploadComponent.vue

@@ -171,6 +171,51 @@ export default {
 			noXmlFiles: [], // 存储非当前公司的文件名
 			// reNumFiles: [], // 存储重复发票号
 			toCompany: '', //用于区分属于哪个公司的数电发票,
+			fileLabel: [
+				"BasicInformationTotalTaxAm",//税额
+				"IssueTime",//
+				"IssuItemInformationTaxRate",//
+				// "IssuItemInformationTaxClassificationCode",
+				// "IssuItemInformationQuantity",
+				"InherentLabelEInvoiceTypeLabelName",//
+				// "InherentLabelInIssuTypeLabelName",
+				"SellerInformationSellerName",//开票单位
+				// "IssuItemInformationAmount",
+				// "InherentLabelTaxpayerTypeLabelCode",
+				"BuyerInformationBuyerIdNum",//
+				"BasicInformationTotalTaxincludedAmount",//合计
+				// "Version",
+				"InherentLabelGeneralOrSpecialVATLabelName",//发票类型
+				"BasicInformationRequestTime",//
+				"BasicInformationTotalTaxincludedAmountInChinese",//
+				// "UndefinedLabelLabelLabelName",
+				"IssuItemInformationTotaltaxIncludedAmount",//
+				"InvoiceNumber",// 发票号
+				// "TaxBureauCode",
+				"IssuItemInformationComTaxAm",//
+				// "EIid",
+				"IssuItemInformationItemName",//项目名
+				"SellerInformationSellerBankName",//
+				"BasicInformationDrawer",//
+				// "UndefinedLabelLabelLabelCode",
+				// "IssuItemInformationUnPrice",
+				"UndefinedLabelLabelLabelType",
+				"BuyerInformationBuyerName",//购买方	
+				// "SellerInformationSellerAddr",
+				"BasicInformationTotalAmWithoutTax",//金额
+				"SellerInformationSellerBankAccNum",//
+				"InherentLabelEInvoiceTypeLabelCode",//
+				"InherentLabelInIssuTypeLabelCode",
+				"SellerInformationSellerTelNum",//
+				// "AdditionalInformationRemark",
+				// "IssuItemInformationMeaUnits",
+				// "EInvoiceTag",
+				// "InherentLabelTaxpayerTypeLabelName",
+				"InherentLabelGeneralOrSpecialVATLabelCode",//
+				// "SellerInformationSellerIdNum",
+				// "IssuItemInformationSpecMod",
+				// "TaxBureauName"
+			]
 		}
 	},
 	watch: {
@@ -457,212 +502,220 @@ export default {
 			}
 		},
 		async changes(file, fileList) {
-			this.uploadKey = Math.random();
+			try {
 
-			// 用来存放没有重复且有有效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 中
-			}
+				this.uploadKey = Math.random();
 
-			// 2. 文件大小检查
-			if (!beforeAvatarUpload(file, fileList, this.maxValue)) {
-				this.$message.error('文件大小不能超过 ' + this.maxValue + ' MB!');
-				return;
-			}
+				// 用来存放没有重复且有有效URL的文件,准备上传
+				let filesToUpload = [];
+				let validFiles = [];
 
-			// 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);
+				// 用于存储已经上传的文件 `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); // 将文件标识加入已上传集合
 					}
-				} else {
-					// 文件没有重复,加入上传列表
-					filesToUpload.push(item);
-					uploadedFileIdentifiers.add(fileIdentifier); // 将文件标识加入已上传集合
 				}
-			}
 
-			// 4. 如果没有文件需要上传,则直接返回
-			// if (filesToUpload.length === 0) return;
+				// 4. 如果没有文件需要上传,则直接返回
+				// if (filesToUpload.length === 0) return;
 
-			// 5. 删除无效URL的文件
-			let invalidFiles = []; // 用于存储需要删除的文件
+				// 5. 删除无效URL的文件
+				let invalidFiles = []; // 用于存储需要删除的文件
 
-			// 使用异步操作来判断文件URL的有效性
-			for (let item of filesToUpload) {
-				const fileUrl = item.raw ? item.raw.url : item.url;
+				// 使用异步操作来判断文件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);
+					// 检查临时 URL 是否有效
+					if (fileUrl && fileUrl.trim() !== '') {
+						try {
+							const temporaryUrl = await this.ossService.getTemporaryUrl(fileUrl);
 
-						if (!temporaryUrl || temporaryUrl.trim() === '') {
-							// 如果临时 URL 无效,则标记该文件为无效并删除
+							if (!temporaryUrl || temporaryUrl.trim() === '') {
+								// 如果临时 URL 无效,则标记该文件为无效并删除
+								invalidFiles.push(item);
+							} else {
+								// 如果临时 URL 有效,继续添加文件到有效文件列表
+								validFiles.push(item);
+								item.lsUrl = temporaryUrl;
+							}
+						} catch (error) {
+							// 如果临时 URL 获取失败,也标记该文件为无效
 							invalidFiles.push(item);
-						} else {
-							// 如果临时 URL 有效,继续添加文件到有效文件列表
-							validFiles.push(item);
-							item.lsUrl = temporaryUrl;
 						}
-					} catch (error) {
-						// 如果临时 URL 获取失败,也标记该文件为无效
-						invalidFiles.push(item);
 					}
 				}
-			}
 
-			filesToUpload = validFiles; // 只保留有效的文件
+				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,
-				};
-			}
+				// 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) {
-							data = this.capitalizeKeys(data);
-
-							// 如果文件的公司名称与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
-								}
-							}
+				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;
 
-							if (this.toCompany !== data.BuyerInformationBuyerName) {
-								this.noXmlFiles.push("文件名: " + item.raw.name + "—— 发票号:" + data.InvoiceNumber)
-								// this.$message.warning("仅可上传江苏兴光项目管理有限公司的报销数电发票");
-								continue;
-							}
-							if (this.commonJS.isNotEmpty(data.InvoiceNumber)) {
-								var flag = this.invoiceReimbursementDispose(data)
-								if (flag) {
-									this.duplicateFileNames.push(item.raw.name + "-" + data.InvoiceNumber)
-									continue;
+						// 仅处理 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
+									}
 								}
-								//查询当前发票号是否已经被报销
-								let isUsed = await this.ossService.isUsedByInvoiceNumber(data.InvoiceNumber);
-								if (isUsed) {
-									isUsedFiles.push("文件名: " + item.raw.name + "—— 发票号:" + data.InvoiceNumber)
+
+								if (this.toCompany !== data.BuyerInformationBuyerName) {
+									this.noXmlFiles.push("文件名: " + item.raw.name + "—— 发票号:" + data.InvoiceNumber)
+									// this.$message.warning("仅可上传江苏兴光项目管理有限公司的报销数电发票");
 									continue;
 								}
-								let inDate = this.formatDate(data.IssueTime)
-								if (inDate.indexOf("NaN") != -1 && this.commonJS.isNotEmpty(inDate)) {
-									errorDateFiles.push("文件名: " + item.raw.name + "—— 发票号:" + data.InvoiceNumber);
-									continue;
+								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);  // 符合条件的文件
 								}
-								validCompanyFiles.push(item);  // 符合条件的文件
-							}
 
+							}
 						}
 					}
 				}
-			}
-			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 });
+				filesToUpload = validCompanyFiles;
+				// 将新符合条件的文件追加到原文件列表上
+				this.dataListNew = [...this.dataList, ...filesToUpload];
+				this.fileList = [...filesToUpload];
+				// 记录上传文件的数量
+				this.totalCount = fileList.length;
+				//记录changes方法执行了多少次,此处加判定是为了处理防抖,change方法会对每一个文件执行两次,此处判定后只会增加一次
+				if (file.status !== 'ready') {
+					this.uploadingCount++
 				}
-				// 提示发票号重复文件
-				// 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 });
+
+				// 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
 				}
-				//已经被报销的文件
-				if (isUsedFiles.length > 0) {
-					this.$message.warning({ message: `数电发票: <br>${isUsedFiles.join('<br>')}<br>已经发起或已完成报销,无法重复报销`, dangerouslyUseHTMLString: true });
+				// 清空 fileList,如果 fileList 不为空
+				if (fileList && fileList.length > 0) {
+					this.fileList = [];
 				}
-				// 重置计数器
-				this.uploadingCount = 0;
-				this.totalCount = 0; // 可以根据需求来重置
-				this.duplicateFileNames = []; // 清空记录
-				this.noXmlFiles = []; // 清空记录
-				this.reNumFiles = []; // 清空记录
-				this.dataList = this.dataListNew
-			}
-			// 清空 fileList,如果 fileList 不为空
-			if (fileList && fileList.length > 0) {
-				this.fileList = [];
+				// 在 changes 完成后,手动调用 handleUploadSuccess
+				await this.handleUploadSuccess(null, null, this.fileList);  // 传入空参数或实际参数
+			} catch (error) {
+				this.$message.error({
+					message: `上传出错,${error.message}`
+				})
 			}
-			// 在 changes 完成后,手动调用 handleUploadSuccess
-			await this.handleUploadSuccess(null, null, this.fileList);  // 传入空参数或实际参数
 		},
 		// 处理返回结果字段大小写问题
 		capitalizeKeys(obj) {
@@ -672,6 +725,26 @@ export default {
 				return acc;
 			}, {});
 		},
+		fieldComparison(obj, fields) {
+			// 遍历字段数组,检查每个字段名是否在对象中存在
+			for (let field of fields) {
+				// 忽略大小写来匹配属性名
+				const fieldPattern = new RegExp(`^${field}$`, 'i');
+				const matchedKeys = Object.keys(obj).filter(key => fieldPattern.test(key));
+
+				// 如果没有找到匹配的字段,抛出错误
+				if (matchedKeys.length === 0) {
+					throw new Error(`未找到发票字段: ${field},请核对XML文件`)
+				}
+				// 替换属性名
+				for (let key of matchedKeys) {
+					if (key !== field) {
+						obj[field] = obj[key];
+						delete obj[key];
+					}
+				}
+			}
+		},
 		async handleUploadSuccess(response, file, fileList) {
 
 			// 遍历当前的数据列表
@@ -694,7 +767,7 @@ export default {
 								let data = await this.ossService.disposeXmlFile(formBody);
 								// 检查 data 是否包含 BuyerInformationBuyerName 属性
 								if (data && 'BuyerInformationBuyerName' in data) {
-									data = this.capitalizeKeys(data);
+									this.fieldComparison(data, this.fileLabel);
 									// 验证是否有效,并进行替换操作
 									if (typeof data.BuyerInformationBuyerName === 'string') {
 										var buyerInformationBuyerName = data.BuyerInformationBuyerName