+
+
+
+
![]()
+
+
+
{{ 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 @@
-
- 预览
+
+
下载
+ @click="downloadFile(scope.row.attachments)">下载
-
@@ -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}