diff --git a/oms_web/oms_vue/src/components/GlobalFilePreview/index.vue b/oms_web/oms_vue/src/components/GlobalFilePreview/index.vue new file mode 100644 index 00000000..7feaf6f6 --- /dev/null +++ b/oms_web/oms_vue/src/components/GlobalFilePreview/index.vue @@ -0,0 +1,64 @@ + + + diff --git a/oms_web/oms_vue/src/views/finance/invoice/components/InvoiceDialog.vue b/oms_web/oms_vue/src/views/finance/invoice/components/InvoiceDialog.vue index abd28abe..6d79fb6c 100644 --- a/oms_web/oms_vue/src/views/finance/invoice/components/InvoiceDialog.vue +++ b/oms_web/oms_vue/src/views/finance/invoice/components/InvoiceDialog.vue @@ -8,11 +8,11 @@ 上传{{ titleText }} - + @@ -24,29 +24,34 @@
{{ titleText }} -
-
- -
- -
- +
+
+
+
+ +
+ +
+ +
+
+
作废
-
作废
下载{{ titleText }}
@@ -77,7 +82,7 @@
-->
备注 - {{ attachment.remark }} + {{ group.remark }}
@@ -123,7 +128,7 @@ > - +
- {{ uploadForm.file ? '重新上传' : '点击上传' }} + 点击上传
支持上传PNG、JPG、PDF文件格式
@@ -168,16 +175,21 @@ -
-
- - +
+
+
+
+ + +
+
{{ file.name }}
+
-
+
-
点击图片进入预览
+
上传文件后在此预览
@@ -225,8 +237,8 @@ export default { invoiceAmount: '', invoiceType: this.invoiceData.invoiceType, remark: '', - file: null }, + fileList: [], rules: { invoicePriceWithTax: [ { required: true, message: "请输入发票含税总价", trigger: "blur" } @@ -238,8 +250,6 @@ export default { { required: true, message: "请输入发票税额", trigger: "blur" } ] }, - previewUrl: '', - isPreviewPdf: false, // PDF Preview Data pdfUrls: {}, pdfPreviewVisible: false, @@ -260,6 +270,24 @@ export default { .filter(att => !this.isPdf(att.filePath)) .map(att => this.getImageUrl(att.filePath)); }, + groupedAttachments() { + if (!this.attachments || this.attachments.length === 0) return []; + + const groups = {}; + this.attachments.forEach(att => { + const time = att.createTime; + if (!groups[time]) { + groups[time] = { + createTime: time, + items: [], + remark: att.remark + }; + } + groups[time].items.push(att); + }); + + return Object.values(groups).sort((a, b) => new Date(b.createTime) - new Date(a.createTime)); + }, canUpload() { if (!this.attachments || this.attachments.length === 0) { return true; @@ -284,7 +312,7 @@ export default { getInvoiceAttachments(this.invoiceData.id, { type: 'invoice' }) .then(response => { const data = response.data || []; - data.sort((a, b) => new Date(b.createTime) - new Date(a.createTime)); + // data.sort((a, b) => new Date(b.createTime) - new Date(a.createTime)); // Sorting is handled in groupedAttachments this.attachments = data; this.loadPdfPreviews(); this.loading = false; @@ -321,6 +349,12 @@ export default { isPdf(filePath) { return filePath && filePath.toLowerCase().endsWith('.pdf'); }, + downloadFiles(items) { + if (!items || items.length === 0) return; + items.forEach(item => { + this.downloadFile(item); + }); + }, downloadFile(attachment) { const link = document.createElement('a'); link.href = this.getImageUrl(attachment.filePath); @@ -344,19 +378,19 @@ export default { invoiceAmount: '', invoiceType: this.invoiceData.invoiceType, remark: '', - file: null }; if (this.$refs.uploadForm) { this.$refs.uploadForm.clearValidate(); } - this.previewUrl = ''; - this.isPreviewPdf = false; + this.fileList = []; this.uploadDialogVisible = true; }, closeUploadDialog() { this.uploadDialogVisible = false; - this.uploadForm.file = null; - this.previewUrl = ''; + this.fileList.forEach(file => { + if (file.url) URL.revokeObjectURL(file.url); + }); + this.fileList = []; }, handleTypeChange(val) { if (val === '2') { @@ -378,32 +412,34 @@ export default { this.uploadForm.invoicePriceWithoutTax = (total - tax).toFixed(2); } }, - handleFileChange(file) { + handleFileChange(file, fileList) { const isLt2M = file.size / 1024 / 1024 < 2; const isAcceptedType = ['image/jpeg', 'image/png', 'application/pdf'].includes(file.raw.type); if (!isAcceptedType) { this.$message.error('上传文件只能是 JPG/PNG/PDF 格式!'); + const index = fileList.indexOf(file); + if (index > -1) fileList.splice(index, 1); return; } if (!isLt2M) { this.$message.error('上传文件大小不能超过 2MB!'); + const index = fileList.indexOf(file); + if (index > -1) fileList.splice(index, 1); return; } - this.uploadForm.file = file.raw; - this.isPreviewPdf = file.raw.type === 'application/pdf'; - - this.previewUrl = URL.createObjectURL(file.raw); + file.url = URL.createObjectURL(file.raw); + this.fileList = fileList; }, - handleFileRemove() { - this.uploadForm.file = null; - this.previewUrl = ''; + handleFileRemove(file, fileList) { + if (file.url) URL.revokeObjectURL(file.url); + this.fileList = fileList; }, submitNewUpload() { this.$refs.uploadForm.validate(valid => { if (valid) { - if (!this.uploadForm.file) { + if (this.fileList.length === 0) { this.$message.warning("请选择要上传的文件"); return; } @@ -442,16 +478,21 @@ export default { } } } - + if ((this.fileList||[]).length <=0 ){ + this.$message.warning("文件不能为空"); + return; + } const formData = new FormData(); - formData.append("file", this.uploadForm.file); + this.fileList.forEach(file => { + formData.append("file", file.raw); + }); formData.append("id", this.invoiceData.id); formData.append("remark", this.uploadForm.remark); formData.append("invoicePriceWithTax", this.uploadForm.invoicePriceWithTax); formData.append("invoicePriceWithoutTax", this.uploadForm.invoicePriceWithoutTax); formData.append("invoiceAmount", this.uploadForm.invoiceAmount); formData.append("invoiceType", this.uploadForm.invoiceType); - this.invoiceData.invoiceType=this.uploadForm.invoiceType + this.invoiceData.invoiceType=this.uploadForm.invoiceType uploadInvoiceAttachment(formData) .then(response => { this.$message.success("上传成功"); diff --git a/oms_web/oms_vue/src/views/finance/receivable/components/EditForm.vue b/oms_web/oms_vue/src/views/finance/receivable/components/EditForm.vue index 5428f90e..a4150ae5 100644 --- a/oms_web/oms_vue/src/views/finance/receivable/components/EditForm.vue +++ b/oms_web/oms_vue/src/views/finance/receivable/components/EditForm.vue @@ -147,10 +147,10 @@ @@ -224,8 +224,11 @@ export default { handlePreview(attachment) { this.$refs.filePreview.handlePreview(attachment); }, - downloadFile(attachment) { - this.$refs.filePreview.downloadFile(attachment); + downloadFile(attachments) { + attachments?.forEach(attachment => { + this.$refs.filePreview.downloadFile(attachment); + }) + }, getDetails() { getReceivable(this.data.id).then(res => { diff --git a/ruoyi-sip/src/main/java/com/ruoyi/sip/controller/OmsInvoiceBillController.java b/ruoyi-sip/src/main/java/com/ruoyi/sip/controller/OmsInvoiceBillController.java index b217b1c0..0351ab42 100644 --- a/ruoyi-sip/src/main/java/com/ruoyi/sip/controller/OmsInvoiceBillController.java +++ b/ruoyi-sip/src/main/java/com/ruoyi/sip/controller/OmsInvoiceBillController.java @@ -169,7 +169,7 @@ public class OmsInvoiceBillController extends BaseController @Log(title = "上传开票回执单", businessType = BusinessType.UPDATE) @PostMapping("/uploadReceipt") @ResponseBody - public AjaxResult uploadReceipt(OmsInvoiceBill invoiceBill, @RequestParam("file") MultipartFile file) + public AjaxResult uploadReceipt(OmsInvoiceBill invoiceBill, @RequestParam("file") MultipartFile[] file) { try { return omsInvoiceBillService.uploadReceipt(invoiceBill, file); diff --git a/ruoyi-sip/src/main/java/com/ruoyi/sip/domain/OmsReceivableInvoiceDetail.java b/ruoyi-sip/src/main/java/com/ruoyi/sip/domain/OmsReceivableInvoiceDetail.java index 926c6d66..299d8804 100644 --- a/ruoyi-sip/src/main/java/com/ruoyi/sip/domain/OmsReceivableInvoiceDetail.java +++ b/ruoyi-sip/src/main/java/com/ruoyi/sip/domain/OmsReceivableInvoiceDetail.java @@ -65,7 +65,7 @@ public class OmsReceivableInvoiceDetail extends BaseEntity private String invoiceStatus; private Long invoiceBillId; private Date actualInvoiceTime; - private OmsFinAttachment attachment; + private List attachments; private Long writeOffId; private List writeOffIdList; diff --git a/ruoyi-sip/src/main/java/com/ruoyi/sip/service/IOmsFinAttachmentService.java b/ruoyi-sip/src/main/java/com/ruoyi/sip/service/IOmsFinAttachmentService.java index 5bf03ba3..29aeaccb 100644 --- a/ruoyi-sip/src/main/java/com/ruoyi/sip/service/IOmsFinAttachmentService.java +++ b/ruoyi-sip/src/main/java/com/ruoyi/sip/service/IOmsFinAttachmentService.java @@ -71,9 +71,9 @@ public interface IOmsFinAttachmentService */ default OmsFinAttachment uploadAttachment(MultipartFile file, Long invoiceReceiptBillId, OmsFinAttachment.RelatedBillTypeEnum type) throws Exception { - return uploadAttachment(file, invoiceReceiptBillId, type,null); + return uploadAttachment(new MultipartFile[]{file}, invoiceReceiptBillId, type,null).get(0); } - public OmsFinAttachment uploadAttachment(MultipartFile file, Long invoiceReceiptBillId, OmsFinAttachment.RelatedBillTypeEnum type,String remark) throws Exception; + public List uploadAttachment(MultipartFile[] file, Long invoiceReceiptBillId, OmsFinAttachment.RelatedBillTypeEnum type,String remark) throws Exception; List list(List ids, String type); diff --git a/ruoyi-sip/src/main/java/com/ruoyi/sip/service/IOmsInvoiceBillService.java b/ruoyi-sip/src/main/java/com/ruoyi/sip/service/IOmsInvoiceBillService.java index 9c01631e..f750fbb5 100644 --- a/ruoyi-sip/src/main/java/com/ruoyi/sip/service/IOmsInvoiceBillService.java +++ b/ruoyi-sip/src/main/java/com/ruoyi/sip/service/IOmsInvoiceBillService.java @@ -72,7 +72,7 @@ public interface IOmsInvoiceBillService * @param file 回执文件 * @return 结果 */ - public AjaxResult uploadReceipt(OmsInvoiceBill bill, MultipartFile file) throws Exception; + public AjaxResult uploadReceipt(OmsInvoiceBill bill, MultipartFile[] file) throws Exception; /** * 查询待审批列表 diff --git a/ruoyi-sip/src/main/java/com/ruoyi/sip/service/impl/OmsFinAttachmentServiceImpl.java b/ruoyi-sip/src/main/java/com/ruoyi/sip/service/impl/OmsFinAttachmentServiceImpl.java index c92a0577..d916c8cb 100644 --- a/ruoyi-sip/src/main/java/com/ruoyi/sip/service/impl/OmsFinAttachmentServiceImpl.java +++ b/ruoyi-sip/src/main/java/com/ruoyi/sip/service/impl/OmsFinAttachmentServiceImpl.java @@ -1,6 +1,8 @@ package com.ruoyi.sip.service.impl; +import java.util.ArrayList; import java.util.Collections; +import java.util.Date; import java.util.List; import com.ruoyi.common.utils.DateUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -26,24 +28,31 @@ public class OmsFinAttachmentServiceImpl implements IOmsFinAttachmentService private OmsFinAttachmentMapper omsFinAttachmentMapper; @Override - public OmsFinAttachment uploadAttachment(MultipartFile file, Long relatedBillId, OmsFinAttachment.RelatedBillTypeEnum type,String remark) throws Exception + public List uploadAttachment(MultipartFile[] fileArray, Long relatedBillId, OmsFinAttachment.RelatedBillTypeEnum type,String remark) throws Exception { // 上传文件路径 String filePath = RuoYiConfig.getUploadPath(); + Date nowDate = DateUtils.getNowDate(); + List resultList=new ArrayList<>(); // 上传并返回新文件名称 - String fileName = FileUploadUtils.upload(filePath, file); + for (MultipartFile file : fileArray) { + String fileName = FileUploadUtils.upload(filePath, file); + + OmsFinAttachment attachment = new OmsFinAttachment(); + attachment.setFileName(fileName); + attachment.setFilePath(fileName); + attachment.setFileSize(file.getSize()); + attachment.setFileType(file.getContentType()); + attachment.setRelatedBillType(type.getCode()); + attachment.setRelatedBillId(relatedBillId); + attachment.setRemark(remark); + attachment.setCreateTime(nowDate); + attachment.setCreateBy(com.ruoyi.common.utils.ShiroUtils.getLoginName()); + this.insertOmsFinAttachment(attachment); + resultList.add( attachment); + } + return resultList; - OmsFinAttachment attachment = new OmsFinAttachment(); - attachment.setFileName(fileName); - attachment.setFilePath(fileName); - attachment.setFileSize(file.getSize()); - attachment.setFileType(file.getContentType()); - attachment.setRelatedBillType(type.getCode()); - attachment.setRelatedBillId(relatedBillId); - attachment.setRemark(remark); - attachment.setCreateBy(com.ruoyi.common.utils.ShiroUtils.getLoginName()); - this.insertOmsFinAttachment(attachment); - return attachment; } @Override @@ -97,7 +106,9 @@ public class OmsFinAttachmentServiceImpl implements IOmsFinAttachmentService @Override public int insertOmsFinAttachment(OmsFinAttachment omsFinAttachment) { - omsFinAttachment.setCreateTime(DateUtils.getNowDate()); + if (omsFinAttachment.getCreateTime()==null) { + omsFinAttachment.setCreateTime(DateUtils.getNowDate()); + } return omsFinAttachmentMapper.insertOmsFinAttachment(omsFinAttachment); } diff --git a/ruoyi-sip/src/main/java/com/ruoyi/sip/service/impl/OmsInvoiceBillServiceImpl.java b/ruoyi-sip/src/main/java/com/ruoyi/sip/service/impl/OmsInvoiceBillServiceImpl.java index 37737c24..87efa487 100644 --- a/ruoyi-sip/src/main/java/com/ruoyi/sip/service/impl/OmsInvoiceBillServiceImpl.java +++ b/ruoyi-sip/src/main/java/com/ruoyi/sip/service/impl/OmsInvoiceBillServiceImpl.java @@ -9,12 +9,14 @@ import java.util.stream.Collectors; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.date.DatePattern; import cn.hutool.core.date.DateUtil; +import com.ruoyi.common.config.RuoYiConfig; import com.ruoyi.common.config.flow.ProcessConfig; import com.ruoyi.common.enums.ApproveStatusEnum; import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.ShiroUtils; import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.file.FileUploadUtils; import com.ruoyi.sip.domain.*; import com.ruoyi.sip.domain.dto.InvoiceProductDto; import com.ruoyi.sip.domain.dto.ReceiptDetailDTO; @@ -192,7 +194,7 @@ public class OmsInvoiceBillServiceImpl implements IOmsInvoiceBillService, TodoCo */ @Override @Transactional(rollbackFor = Exception.class) - public AjaxResult uploadReceipt(OmsInvoiceBill bill, MultipartFile file) throws Exception { + public AjaxResult uploadReceipt(OmsInvoiceBill bill, MultipartFile[] fileArray) throws Exception { OmsInvoiceBill existBill = selectOmsInvoiceBillById(bill.getId()); if (existBill == null) { throw new ServiceException("开票单不存在"); @@ -204,7 +206,27 @@ public class OmsInvoiceBillServiceImpl implements IOmsInvoiceBillService, TodoCo } // 这里可以添加上传附件的逻辑 - omsFinAttachmentService.uploadAttachment(file, existBill.getId(), OmsFinAttachment.RelatedBillTypeEnum.RECEIVE_INVOICE, bill.getRemark()); + // 上传文件路径 + String filePath = RuoYiConfig.getUploadPath(); + Date nowDate = DateUtils.getNowDate(); + // 上传并返回新文件名称 + for (MultipartFile file : fileArray) { + String fileName = FileUploadUtils.upload(filePath, file); + OmsFinAttachment attachment = new OmsFinAttachment(); + attachment.setFileName(fileName); + attachment.setFilePath(fileName); + attachment.setFileSize(file.getSize()); + attachment.setFileType(file.getContentType()); + attachment.setRelatedBillType(OmsFinAttachment.RelatedBillTypeEnum.RECEIVE_INVOICE.getCode()); + attachment.setRelatedBillId(existBill.getId()); + attachment.setRemark(bill.getRemark()); + attachment.setCreateTime(nowDate); + attachment.setCreateBy(ShiroUtils.getUserId().toString()); + attachment.setPriceWithoutTax(bill.getInvoicePriceWithoutTax()); + attachment.setPriceWithTax(bill.getInvoicePriceWithTax()); + omsFinAttachmentService.insertOmsFinAttachment(attachment); + + } existBill.setActualInvoiceTime(DateUtils.getNowDate()); existBill.setInvoiceStatus(OmsInvoiceBill.InvoiceStatusEnum.INVOICE.getCode()); existBill.setInvoicePriceWithTax(bill.getInvoicePriceWithTax()); diff --git a/ruoyi-sip/src/main/java/com/ruoyi/sip/service/impl/OmsReceivableInvoiceDetailServiceImpl.java b/ruoyi-sip/src/main/java/com/ruoyi/sip/service/impl/OmsReceivableInvoiceDetailServiceImpl.java index b9c6b63a..a1c44748 100644 --- a/ruoyi-sip/src/main/java/com/ruoyi/sip/service/impl/OmsReceivableInvoiceDetailServiceImpl.java +++ b/ruoyi-sip/src/main/java/com/ruoyi/sip/service/impl/OmsReceivableInvoiceDetailServiceImpl.java @@ -126,9 +126,9 @@ public class OmsReceivableInvoiceDetailServiceImpl implements IOmsReceivableInvo omsFinAttachment.setRelatedBillType(OmsFinAttachment.RelatedBillTypeEnum.RECEIVE_INVOICE.getCode()); omsFinAttachment.setDelFlag("0"); List attachmentList = finAttachmentService.selectOmsFinAttachmentList(omsFinAttachment); - Map collect = attachmentList.stream().collect(Collectors.toMap(OmsFinAttachment::getRelatedBillId, Function.identity())); + Map> collect = attachmentList.stream().collect(Collectors.groupingBy(OmsFinAttachment::getRelatedBillId)); for (OmsReceivableInvoiceDetail detail : list) { - detail.setAttachment(collect.get(detail.getInvoiceBillId())); + detail.setAttachments(collect.get(detail.getInvoiceBillId())); } } diff --git a/ruoyi-sip/src/main/resources/mapper/sip/OmsReceivableInvoiceDetailMapper.xml b/ruoyi-sip/src/main/resources/mapper/sip/OmsReceivableInvoiceDetailMapper.xml index 273fc03e..3ce64af4 100644 --- a/ruoyi-sip/src/main/resources/mapper/sip/OmsReceivableInvoiceDetailMapper.xml +++ b/ruoyi-sip/src/main/resources/mapper/sip/OmsReceivableInvoiceDetailMapper.xml @@ -96,8 +96,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" select t1.receipt_amount, t2.receivable_bill_code, t4.project_name, t4.project_code, t2.total_price_with_tax,t2.product_type from (SELECT sum(invoice_amount) receipt_amount, receivable_bill_id - FROM oms_receivable_invoice_detail - WHERE write_off_id is null and invoice_bill_code in + FROM oms_receivable_invoice_detail t1 + left join oms_receivable_invoice_write_off t2 on t1.write_off_id=t2.id + WHERE (t1.write_off_id is null or t1.invoice_bill_code=t2.invoice_bill_code) and t1.invoice_bill_code in #{item}