src/main/java/com/ruoyi/basic/pojo/ProductModel.java
@@ -26,4 +26,9 @@ * 规格型号 */ private String model; /** * 单位 */ private String unit; } src/main/java/com/ruoyi/purchase/controller/TicketRegistrationController.java
@@ -1,24 +1,21 @@ package com.ruoyi.purchase.controller; import javax.servlet.http.HttpServletResponse; import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.purchase.dto.TicketRegistrationDto; import com.ruoyi.purchase.pojo.TicketRegistration; import com.ruoyi.purchase.service.ITicketRegistrationService; import lombok.AllArgsConstructor; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.ruoyi.framework.aspectj.lang.annotation.Log; import com.ruoyi.framework.aspectj.lang.enums.BusinessType; import com.ruoyi.framework.web.controller.BaseController; import com.ruoyi.framework.web.domain.AjaxResult; import com.ruoyi.framework.web.page.TableDataInfo; import com.ruoyi.purchase.dto.TicketRegistrationDto; import com.ruoyi.purchase.pojo.TicketRegistration; import com.ruoyi.purchase.service.ITicketRegistrationService; import com.ruoyi.sales.service.ICommonFileService; import lombok.AllArgsConstructor; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.List; /** @@ -33,6 +30,8 @@ public class TicketRegistrationController extends BaseController { private ITicketRegistrationService ticketRegistrationService; private ICommonFileService commonFileService; /** * 查询来票登记列表 @@ -70,8 +69,7 @@ */ @Log(title = "来票登记", businessType = BusinessType.INSERT) @PostMapping ("/addOrUpdateRegistration") public AjaxResult addOrUpdateRegistration(@RequestBody TicketRegistrationDto ticketRegistrationDto) { public AjaxResult addOrUpdateRegistration(@RequestBody TicketRegistrationDto ticketRegistrationDto) throws IOException { return toAjax(ticketRegistrationService.addOrUpdateRegistration(ticketRegistrationDto)); } @@ -85,4 +83,13 @@ return toAjax(ticketRegistrationService.delRegistration(ids)); } @PostMapping("/upload") public AjaxResult uploadFile(MultipartFile file, Long id, String type) { try { return AjaxResult.success(commonFileService.uploadFile(file, id, type)); } catch (Exception e) { return AjaxResult.error(e.getMessage()); } } } src/main/java/com/ruoyi/purchase/dto/PurchaseLedgerDto.java
@@ -107,4 +107,13 @@ */ private Long businessPersonId; /** * 产品id */ private Long productId; /** * 产品规格id */ private Long productModelId; } src/main/java/com/ruoyi/purchase/dto/TicketRegistrationDto.java
@@ -1,5 +1,6 @@ package com.ruoyi.purchase.dto; import com.ruoyi.sales.pojo.CommonFile; import com.ruoyi.sales.pojo.SalesLedgerProduct; import lombok.Data; @@ -52,4 +53,9 @@ private Long salesContractNoId; private String supplierName; private List<String> tempFileIds; private List<CommonFile> CommonFiles; private String fileName; } src/main/java/com/ruoyi/purchase/pojo/PurchaseLedger.java
@@ -110,17 +110,17 @@ * 合同金额(产品含税总价) */ private BigDecimal contractAmount; /** * 业务员 */ @Excel(name = "业务员") private String businessPerson; /** * 业务员id */ private Long businessPersonId; // // /** // * 业务员 // */ // @Excel(name = "业务员") // private String businessPerson; // // /** // * 业务员id // */ // private Long businessPersonId; /** * 业务员手机号 src/main/java/com/ruoyi/purchase/pojo/TicketRegistration.java
@@ -1,12 +1,13 @@ package com.ruoyi.purchase.pojo; import java.math.BigDecimal; import java.util.Date; import com.baomidou.mybatisplus.annotation.*; import com.fasterxml.jackson.annotation.JsonFormat; import com.ruoyi.framework.aspectj.lang.annotation.Excel; import lombok.Data; import java.math.BigDecimal; import java.time.LocalDate; import java.util.Date; /** * 来票登记对象 ticket_registration @@ -53,16 +54,41 @@ */ private String customerName; /** * 业务员 */ @Excel(name = "业务员") private String businessPerson; // /** // * 业务员 // */ // @Excel(name = "业务员") // private String businessPerson; // // /** // * 业务员id // */ // private Long businessPersonId; /** * 业务员id * 发票号 */ private Long businessPersonId; @Excel(name = "发票号") private String invoiceNumber; /** * 发票金额(元) */ @Excel(name = "发票金额(元)") private BigDecimal invoiceAmount; /** * 开票人 */ @Excel(name = "开票人") private String issUer; /** * 开票日期 */ @JsonFormat(pattern = "yyyy-MM-dd" ,timezone = "GMT+8") @Excel(name = "开票日期", width = 30, dateFormat = "yyyy-MM-dd") private LocalDate issueDate; /** * 项目名称 src/main/java/com/ruoyi/purchase/service/ITicketRegistrationService.java
@@ -4,6 +4,7 @@ import com.ruoyi.purchase.dto.TicketRegistrationDto; import com.ruoyi.purchase.pojo.TicketRegistration; import java.io.IOException; import java.util.List; /** @@ -16,7 +17,7 @@ List<TicketRegistration> selectTicketRegistrationList(TicketRegistration ticketRegistration); int addOrUpdateRegistration(TicketRegistrationDto ticketRegistrationDto); int addOrUpdateRegistration(TicketRegistrationDto ticketRegistrationDto) throws IOException; int delRegistration(Long[] ids); src/main/java/com/ruoyi/purchase/service/impl/InvoicePurchaseServiceImpl.java
@@ -6,7 +6,6 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.common.utils.bean.BeanUtils; import com.ruoyi.other.mapper.TempFileMapper; import com.ruoyi.other.pojo.TempFile; import com.ruoyi.project.system.domain.SysUser; import com.ruoyi.project.system.mapper.SysUserMapper; import com.ruoyi.purchase.dto.InvoicePurchaseDto; @@ -19,19 +18,11 @@ import com.ruoyi.sales.pojo.CommonFile; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.io.FilenameUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardCopyOption; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.*; import java.util.stream.Collectors; @@ -141,79 +132,11 @@ } // 迁移临时文件到正式目录 if (invoicePurchaseDto.getTempFileIds() != null && !invoicePurchaseDto.getTempFileIds().isEmpty()) { migrateTempFilesToFormal(invoicePurchase.getId(), invoicePurchaseDto.getTempFileIds()); } // if (invoicePurchaseDto.getTempFileIds() != null && !invoicePurchaseDto.getTempFileIds().isEmpty()) { // migrateTempFilesToFormal(invoicePurchase.getId(), invoicePurchaseDto.getTempFileIds()); // } return i; } /** * 将临时文件迁移到正式目录 * * @param businessId 业务ID(销售台账ID) * @param tempFileIds 临时文件ID列表 * @throws IOException 文件操作异常 */ private void migrateTempFilesToFormal(Long businessId, List<String> tempFileIds) throws IOException { if (CollectionUtils.isEmpty(tempFileIds)) { return; } // 构建正式目录路径(按业务类型和日期分组) String formalDir = uploadDir + LocalDate.now().format(DateTimeFormatter.ISO_LOCAL_DATE); Path formalDirPath = Paths.get(formalDir); // 确保正式目录存在(递归创建) if (!Files.exists(formalDirPath)) { Files.createDirectories(formalDirPath); } for (String tempFileId : tempFileIds) { // 查询临时文件记录 TempFile tempFile = tempFileMapper.selectById(tempFileId); if (tempFile == null) { log.warn("临时文件不存在,跳过处理: {}", tempFileId); continue; } // 构建正式文件名(包含业务ID和时间戳,避免冲突) String originalFilename = tempFile.getOriginalName(); String fileExtension = FilenameUtils.getExtension(originalFilename); String formalFilename = businessId + "_" + System.currentTimeMillis() + "_" + UUID.randomUUID().toString().substring(0, 8) + (com.ruoyi.common.utils.StringUtils.hasText(fileExtension) ? "." + fileExtension : ""); Path formalFilePath = formalDirPath.resolve(formalFilename); try { // 执行文件迁移(使用原子操作确保安全性) Files.move( Paths.get(tempFile.getTempPath()), formalFilePath, StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.ATOMIC_MOVE ); log.info("文件迁移成功: {} -> {}", tempFile.getTempPath(), formalFilePath); // 更新文件记录(关联到业务ID) CommonFile fileRecord = new CommonFile(); fileRecord.setCommonId(businessId); fileRecord.setName(originalFilename); fileRecord.setUrl(formalFilePath.toString()); fileRecord.setCreateTime(LocalDateTime.now()); fileRecord.setType(tempFile.getType()); commonFileMapper.insert(fileRecord); log.info("文件迁移成功: {} -> {}", tempFile.getTempPath(), formalFilePath); } catch (IOException e) { log.error("文件迁移失败: {}", tempFile.getTempPath(), e); // 可选择回滚事务或记录失败文件 throw new IOException("文件迁移异常", e); } } } @Override src/main/java/com/ruoyi/purchase/service/impl/PurchaseLedgerServiceImpl.java
@@ -4,7 +4,11 @@ import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.basic.mapper.ProductMapper; import com.ruoyi.basic.mapper.ProductModelMapper; import com.ruoyi.basic.mapper.SupplierManageMapper; import com.ruoyi.basic.pojo.Product; import com.ruoyi.basic.pojo.ProductModel; import com.ruoyi.basic.pojo.SupplierManage; import com.ruoyi.common.exception.base.BaseException; import com.ruoyi.common.utils.StringUtils; @@ -65,6 +69,10 @@ private final SupplierManageMapper supplierManageMapper; private final ProductMapper productMapper; private final ProductModelMapper productModelMapper; @Value("${file.upload-dir}") private String uploadDir; @@ -72,7 +80,7 @@ public List<PurchaseLedger> selectPurchaseLedgerList(PurchaseLedger purchaseLedger) { LambdaQueryWrapper<PurchaseLedger> queryWrapper = new LambdaQueryWrapper<>(); if (StringUtils.isNotBlank(purchaseLedger.getPurchaseContractNumber())) { queryWrapper.like(PurchaseLedger::getPurchaseContractNumber,purchaseLedger.getPurchaseContractNumber()); queryWrapper.like(PurchaseLedger::getPurchaseContractNumber, purchaseLedger.getPurchaseContractNumber()); } return purchaseLedgerMapper.selectList(queryWrapper); } @@ -81,9 +89,6 @@ public int addOrEditPurchase(PurchaseLedgerDto purchaseLedgerDto) throws IOException { SalesLedger salesLedger = salesLedgerMapper.selectById(purchaseLedgerDto.getSalesLedgerId()); //业务员 SysUser businessPerson = userMapper.selectUserById(purchaseLedgerDto.getBusinessPersonId()); if (salesLedger == null) { throw new BaseException("销售台账不存在"); @@ -101,8 +106,6 @@ purchaseLedger.setSupplierName(supplierManage.getSupplierName()); purchaseLedger.setRecorderId(purchaseLedgerDto.getRecorderId()); purchaseLedger.setRecorderName(sysUser.getNickName()); purchaseLedger.setBusinessPersonId(purchaseLedgerDto.getBusinessPersonId()); purchaseLedger.setBusinessPerson(businessPerson.getNickName()); purchaseLedger.setPhoneNumber(sysUser.getPhonenumber()); // 3. 新增或更新主表 @@ -115,7 +118,7 @@ // 4. 处理子表数据 List<SalesLedgerProduct> productList = purchaseLedgerDto.getProductData(); if (productList != null && !productList.isEmpty()) { handleSalesLedgerProducts(purchaseLedger.getId(), productList, purchaseLedgerDto.getType()); handleSalesLedgerProducts(purchaseLedger.getId(), purchaseLedgerDto.getProductId(), purchaseLedgerDto.getProductModelId(), productList, purchaseLedgerDto.getType()); } // 5. 迁移临时文件到正式目录 @@ -126,10 +129,19 @@ return 1; } private void handleSalesLedgerProducts(Long salesLedgerId, List<SalesLedgerProduct> products, Integer type) { private void handleSalesLedgerProducts(Long salesLedgerId, Long productId, Long productModelId, List<SalesLedgerProduct> products, Integer type) { Product pro = productMapper.selectById(productId); ProductModel productModel = productModelMapper.selectById(productModelId); // 按ID分组,区分新增和更新的记录 Map<Boolean, List<SalesLedgerProduct>> partitionedProducts = products.stream() .peek(p -> p.setSalesLedgerId(salesLedgerId)) .peek(p -> { p.setSalesLedgerId(salesLedgerId); p.setProductId(productId); p.setProductCategory(pro.getProductName()); p.setProductModelId(productModelId); p.setSpecificationModel(productModel.getModel()); }) .collect(Collectors.partitioningBy(p -> p.getId() != null)); List<SalesLedgerProduct> updateList = partitionedProducts.get(true); @@ -297,7 +309,6 @@ resultDto.setSalesContractNo(purchaseLedger.getSalesContractNo()); resultDto.setSupplierName(purchaseLedger.getSupplierName()); resultDto.setProjectName(purchaseLedger.getProjectName()); resultDto.setBusinessPersonId(purchaseLedger.getBusinessPersonId()); // 查询并设置关联产品 LambdaQueryWrapper<SalesLedgerProduct> queryWrapper = new LambdaQueryWrapper<>(); @@ -312,7 +323,7 @@ @Override public List getPurchasesNo() { LambdaQueryWrapper<PurchaseLedger> queryWrapper = Wrappers.lambdaQuery(); queryWrapper.select(PurchaseLedger::getId, PurchaseLedger::getPurchaseContractNumber,PurchaseLedger::getSupplierId); queryWrapper.select(PurchaseLedger::getId, PurchaseLedger::getPurchaseContractNumber, PurchaseLedger::getSupplierId); // 获取原始查询结果 List<Map<String, Object>> result = purchaseLedgerMapper.selectMaps(queryWrapper); src/main/java/com/ruoyi/purchase/service/impl/TicketRegistrationServiceImpl.java
@@ -1,25 +1,41 @@ package com.ruoyi.purchase.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.common.exception.base.BaseException; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.bean.BeanUtils; import com.ruoyi.project.system.domain.SysUser; import com.ruoyi.project.system.mapper.SysUserMapper; import com.ruoyi.other.mapper.TempFileMapper; import com.ruoyi.other.pojo.TempFile; import com.ruoyi.purchase.dto.TicketRegistrationDto; import com.ruoyi.purchase.mapper.PurchaseLedgerMapper; import com.ruoyi.purchase.mapper.TicketRegistrationMapper; import com.ruoyi.purchase.pojo.PurchaseLedger; import com.ruoyi.purchase.pojo.TicketRegistration; import com.ruoyi.purchase.service.ITicketRegistrationService; import com.ruoyi.sales.mapper.CommonFileMapper; import com.ruoyi.sales.mapper.SalesLedgerProductMapper; import com.ruoyi.sales.pojo.CommonFile; import com.ruoyi.sales.pojo.SalesLedgerProduct; import lombok.AllArgsConstructor; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.io.FilenameUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import java.io.IOException; import java.math.BigDecimal; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardCopyOption; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.Arrays; import java.util.List; import java.util.UUID; import java.util.stream.Collectors; /** @@ -29,51 +45,131 @@ * @date 2025-05-13 */ @Service @AllArgsConstructor @RequiredArgsConstructor @Slf4j public class TicketRegistrationServiceImpl extends ServiceImpl<TicketRegistrationMapper, TicketRegistration> implements ITicketRegistrationService { private TicketRegistrationMapper ticketRegistrationMapper; private final TicketRegistrationMapper ticketRegistrationMapper; private PurchaseLedgerMapper purchaseLedgerMapper; private final PurchaseLedgerMapper purchaseLedgerMapper; private SalesLedgerProductMapper salesLedgerProductMapper; private final SalesLedgerProductMapper salesLedgerProductMapper; private SysUserMapper userMapper; private final CommonFileMapper commonFileMapper; private final TempFileMapper tempFileMapper; @Value("${file.upload-dir}") private String uploadDir; @Override public List<TicketRegistration> selectTicketRegistrationList(TicketRegistration ticketRegistration) { LambdaQueryWrapper<TicketRegistration> queryWrapper = new LambdaQueryWrapper<>(); if (StringUtils.isNotBlank(ticketRegistration.getPurchaseContractNumber())) { queryWrapper.like(TicketRegistration::getPurchaseContractNumber,ticketRegistration.getPurchaseContractNumber()); queryWrapper.like(TicketRegistration::getPurchaseContractNumber, ticketRegistration.getPurchaseContractNumber()); } return ticketRegistrationMapper.selectList(queryWrapper); } @Override public int addOrUpdateRegistration(TicketRegistrationDto ticketRegistrationDto) { public int addOrUpdateRegistration(TicketRegistrationDto ticketRegistrationDto) throws IOException { PurchaseLedger purchaseLedger = purchaseLedgerMapper.selectById(ticketRegistrationDto.getPurchaseLedgerId()); SysUser sysUser = userMapper.selectUserById(ticketRegistrationDto.getBusinessPersonId()); TicketRegistration ticketRegistration = new TicketRegistration(); BeanUtils.copyProperties(ticketRegistrationDto, ticketRegistration); ticketRegistration.setPurchaseContractNumber(purchaseLedger.getPurchaseContractNumber()); ticketRegistration.setBusinessPerson(sysUser.getNickName()); ticketRegistration.setTenantId(purchaseLedger.getTenantId()); ticketRegistration.setContractAmount(purchaseLedger.getContractAmount()); // 处理子表数据 List<SalesLedgerProduct> productData = ticketRegistrationDto.getProductData(); List<SalesLedgerProduct> productData = ticketRegistrationDto.getProductData(); if (productData != null && !productData.isEmpty()) { handleSalesLedgerProducts(purchaseLedger.getId(), productData, 2); } // 执行插入或更新操作 int i; if (ticketRegistrationDto.getId() == null) { return ticketRegistrationMapper.insert(ticketRegistration); i = ticketRegistrationMapper.insert(ticketRegistration); } else { return ticketRegistrationMapper.updateById(ticketRegistration); i = ticketRegistrationMapper.updateById(ticketRegistration); } // 迁移临时文件到正式目录 if (ticketRegistrationDto.getTempFileIds() != null && !ticketRegistrationDto.getTempFileIds().isEmpty()) { migrateTempFilesToFormal(ticketRegistration.getId(), ticketRegistrationDto.getTempFileIds()); } return i; } /** * 将临时文件迁移到正式目录 * * @param businessId 业务ID(销售台账ID) * @param tempFileIds 临时文件ID列表 * @throws IOException 文件操作异常 */ private void migrateTempFilesToFormal(Long businessId, List<String> tempFileIds) throws IOException { if (CollectionUtils.isEmpty(tempFileIds)) { return; } // 构建正式目录路径(按业务类型和日期分组) String formalDir = uploadDir + LocalDate.now().format(DateTimeFormatter.ISO_LOCAL_DATE); Path formalDirPath = Paths.get(formalDir); // 确保正式目录存在(递归创建) if (!Files.exists(formalDirPath)) { Files.createDirectories(formalDirPath); } for (String tempFileId : tempFileIds) { // 查询临时文件记录 TempFile tempFile = tempFileMapper.selectById(tempFileId); if (tempFile == null) { log.warn("临时文件不存在,跳过处理: {}", tempFileId); continue; } // 构建正式文件名(包含业务ID和时间戳,避免冲突) String originalFilename = tempFile.getOriginalName(); String fileExtension = FilenameUtils.getExtension(originalFilename); String formalFilename = businessId + "_" + System.currentTimeMillis() + "_" + UUID.randomUUID().toString().substring(0, 8) + (com.ruoyi.common.utils.StringUtils.hasText(fileExtension) ? "." + fileExtension : ""); Path formalFilePath = formalDirPath.resolve(formalFilename); try { // 执行文件迁移(使用原子操作确保安全性) Files.move( Paths.get(tempFile.getTempPath()), formalFilePath, StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.ATOMIC_MOVE ); log.info("文件迁移成功: {} -> {}", tempFile.getTempPath(), formalFilePath); // 更新文件记录(关联到业务ID) CommonFile fileRecord = new CommonFile(); fileRecord.setCommonId(businessId); fileRecord.setName(originalFilename); fileRecord.setUrl(formalFilePath.toString()); fileRecord.setCreateTime(LocalDateTime.now()); fileRecord.setType(tempFile.getType()); commonFileMapper.insert(fileRecord); log.info("文件迁移成功: {} -> {}", tempFile.getTempPath(), formalFilePath); } catch (IOException e) { log.error("文件迁移失败: {}", tempFile.getTempPath(), e); // 可选择回滚事务或记录失败文件 throw new IOException("文件迁移异常", e); } } } @Override public int delRegistration(Long[] ids) { @@ -84,14 +180,14 @@ public TicketRegistrationDto getRegistrationById(TicketRegistrationDto ticketRegistrationDto) { TicketRegistration ticketRegistration = ticketRegistrationMapper.selectById(ticketRegistrationDto.getId()); LambdaQueryWrapper<PurchaseLedger> purchaseQueryWrapper = new LambdaQueryWrapper<>(); purchaseQueryWrapper.eq(PurchaseLedger::getId,ticketRegistration.getPurchaseLedgerId()); purchaseQueryWrapper.eq(PurchaseLedger::getId, ticketRegistration.getPurchaseLedgerId()); PurchaseLedger purchaseLedger = purchaseLedgerMapper.selectOne(purchaseQueryWrapper); if (ticketRegistration == null) { throw new BaseException("采购台账不存在"); } // 创建并填充DTO TicketRegistrationDto resultDto = new TicketRegistrationDto(); BeanUtils.copyProperties(ticketRegistration,resultDto); BeanUtils.copyProperties(ticketRegistration, resultDto); // 查询并设置关联产品 LambdaQueryWrapper<SalesLedgerProduct> queryWrapper = new LambdaQueryWrapper<>(); @@ -115,11 +211,13 @@ p.setSalesLedgerId(salesLedgerId); p.setType(type); }) .collect(Collectors.toList()); // Java 8 兼容写法 .collect(Collectors.toList()); // 批量更新(需要 MyBatis 提供批量更新方法) if (!updateList.isEmpty()) { updateList.forEach(product -> { product.setFutureTickets(product.getQuantity().subtract(new BigDecimal(product.getTicketsNum())).longValue()); product.setFutureTicketsAmount(product.getTaxExclusiveTotalPrice().subtract(product.getTicketsAmount())); product.setType(type); salesLedgerProductMapper.updateById(product); }); src/main/java/com/ruoyi/sales/controller/CommonFileController.java
@@ -11,6 +11,9 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.io.IOException; import java.util.List; @RestController @RequestMapping("/commonFile") @AllArgsConstructor @@ -29,4 +32,10 @@ } return toAjax(commonFileService.delCommonFileByIds(ids)); } public void migrateTempFilesToFormal(Long businessId, List<String> tempFileIds) throws IOException{ } } src/main/java/com/ruoyi/sales/controller/InvoiceLedgerController.java
@@ -3,6 +3,9 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.framework.web.domain.AjaxResult; import com.ruoyi.sales.dto.InvoiceLedgerDto; import com.ruoyi.sales.dto.InvoiceRegistrationProductDto; import com.ruoyi.sales.mapper.InvoiceRegistrationProductMapper; import com.ruoyi.sales.pojo.InvoiceRegistrationProduct; import com.ruoyi.sales.service.InvoiceLedgerService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; @@ -19,14 +22,17 @@ @Autowired private InvoiceLedgerService invoiceLedgerService; @Autowired private InvoiceRegistrationProductMapper invoiceRegistrationProductMapper; /** * 开票台账新增 * @param invoiceLedgerDto * @param productDto * @return */ @PostMapping("/saveOrUpdate") public AjaxResult invoiceLedgerSaveOrUpdate(@RequestBody InvoiceLedgerDto invoiceLedgerDto) { invoiceLedgerService.invoiceLedgerSaveOrUpdate(invoiceLedgerDto); public AjaxResult invoiceLedgerSaveOrUpdate(@RequestBody InvoiceRegistrationProductDto productDto) { invoiceLedgerService.invoiceLedgerSaveOrUpdate(productDto); return AjaxResult.success(); } @@ -146,4 +152,25 @@ } } /** * 产品开票记录查询 * @param page * @param registrationProductDto * @return */ @GetMapping("/registrationProductPage") public AjaxResult registrationProductPage(Page page, InvoiceRegistrationProductDto registrationProductDto) { return AjaxResult.success(invoiceLedgerService.registrationProductPage(page,registrationProductDto)); } /** * 产品开票详情 * @param id * @return */ @GetMapping("/invoiceLedgerProductInfo") public AjaxResult invoiceLedgerProductDetail(Integer id) { return AjaxResult.success(invoiceLedgerService.invoiceLedgerProductDetail(id)); } } src/main/java/com/ruoyi/sales/controller/InvoiceRegistrationController.java
@@ -4,6 +4,7 @@ import com.ruoyi.framework.web.domain.AjaxResult; import com.ruoyi.sales.dto.InvoiceRegistrationDto; import com.ruoyi.sales.dto.InvoiceRegistrationProductDto; import com.ruoyi.sales.dto.SalesLedgerDto; import com.ruoyi.sales.service.InvoiceRegistrationService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; @@ -19,13 +20,13 @@ private InvoiceRegistrationService invoiceRegistrationService; /** * 开票登记新增 * @param invoiceRegistrationDto * 开票登记记录新增 * @param salesLedgerDto * @return */ @PostMapping("/saveOrUpdate") public AjaxResult invoiceRegistrationSaveOrUpdate(@RequestBody InvoiceRegistrationDto invoiceRegistrationDto) { invoiceRegistrationService.invoiceRegistrationSaveOrUpdate(invoiceRegistrationDto); @PostMapping("/save") public AjaxResult invoiceRegistrationSave(@RequestBody SalesLedgerDto salesLedgerDto) { invoiceRegistrationService.invoiceRegistrationSave(salesLedgerDto); return AjaxResult.success(); } src/main/java/com/ruoyi/sales/controller/SalesLedgerProductController.java
@@ -38,11 +38,10 @@ * 查询产品信息列表 */ @GetMapping("/list") public TableDataInfo list(SalesLedgerProduct salesLedgerProduct) public List<SalesLedgerProduct> list(SalesLedgerProduct salesLedgerProduct) { startPage(); List<SalesLedgerProduct> list = salesLedgerProductService.selectSalesLedgerProductList(salesLedgerProduct); return getDataTable(list); return list; } /** src/main/java/com/ruoyi/sales/dto/InvoiceRegistrationDto.java
@@ -23,4 +23,7 @@ @ApiModelProperty(name = "合同金额") private BigDecimal contractAmount; @ApiModelProperty(name = "未开票金额") private BigDecimal noInvoiceAmountTotal; } src/main/java/com/ruoyi/sales/dto/InvoiceRegistrationProductDto.java
@@ -1,9 +1,49 @@ package com.ruoyi.sales.dto; import com.fasterxml.jackson.annotation.JsonFormat; import com.ruoyi.common.vo.FileVo; import com.ruoyi.sales.pojo.InvoiceRegistrationProduct; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import org.springframework.format.annotation.DateTimeFormat; import java.math.BigDecimal; import java.time.LocalDate; import java.util.List; @Data public class InvoiceRegistrationProductDto extends InvoiceRegistrationProduct { @ApiModelProperty(name = "客户合同号") private String customerContractNo; @ApiModelProperty(name = "客户名称") private String customerName; @ApiModelProperty(name = "销售合同号") private String salesContractNo; @ApiModelProperty(name = "附件") private List<FileVo> fileList; @ApiModelProperty(value = "发票号") private String invoiceNo; @ApiModelProperty(value = "发票金额") private BigDecimal invoiceTotal; @ApiModelProperty(value = "开票人") private String invoicePerson; @ApiModelProperty(value = "开票时间") @JsonFormat(pattern = "yyyy-MM-dd") @DateTimeFormat(pattern = "yyyy-MM-dd") private LocalDate invoiceDate; @ApiModelProperty(value = "开票台账id") private Integer invoiceLedgerId; @ApiModelProperty(value = "发票文件名") private String invoiceFileName; } src/main/java/com/ruoyi/sales/mapper/InvoiceLedgerMapper.java
@@ -4,7 +4,9 @@ import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.sales.dto.InvoiceLedgerDto; import com.ruoyi.sales.dto.InvoiceRegistrationProductDto; import com.ruoyi.sales.pojo.InvoiceLedger; import com.ruoyi.sales.pojo.InvoiceRegistrationProduct; import org.apache.ibatis.annotations.Param; import java.util.List; @@ -41,4 +43,11 @@ */ IPage<InvoiceLedgerDto> invoiceLedgerSalesAccount(Page page, InvoiceLedgerDto invoiceLedgerDto); /** * 产品开票台账详情 * @param id * @return */ InvoiceRegistrationProductDto invoiceLedgerProductInfo(Integer id); } src/main/java/com/ruoyi/sales/mapper/InvoiceRegistrationProductMapper.java
@@ -1,7 +1,8 @@ package com.ruoyi.sales.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.ruoyi.sales.dto.InvoiceRegistrationDto; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.sales.dto.InvoiceRegistrationProductDto; import com.ruoyi.sales.pojo.InvoiceRegistrationProduct; import org.apache.ibatis.annotations.Param; @@ -16,4 +17,12 @@ * @return */ List<InvoiceRegistrationProductDto> invoiceRegistrationProductList(@Param("invoiceRegistrationProductDto") InvoiceRegistrationProductDto invoiceRegistrationProductDto); /** * 开票登记产品分页查询 * @param page * @param invoiceRegistrationProductDto * @return */ IPage<InvoiceRegistrationProductDto> invoiceRegistrationProductPage(Page page, @Param("invoiceRegistrationProductDto") InvoiceRegistrationProductDto invoiceRegistrationProductDto); } src/main/java/com/ruoyi/sales/pojo/InvoiceLedger.java
@@ -22,23 +22,14 @@ @TableId(type = IdType.AUTO) private Integer id; @ApiModelProperty(value = "销售台账sales_ledger") private Integer salesLedgerId; @ApiModelProperty(value = "销售合同号") private String salesContractNo; @ApiModelProperty(value = "客户名称ID") private Integer customerId; @ApiModelProperty(value = "invoice_registration_product表主键") private Integer invoiceRegistrationProductId; @ApiModelProperty(value = "发票号") private String invoiceNo; @ApiModelProperty(value = "发票金额") private BigDecimal invoiceAmount; @ApiModelProperty(value = "税率") private BigDecimal taxRate; private BigDecimal invoiceTotal; @ApiModelProperty(value = "开票人") private String invoicePerson; src/main/java/com/ruoyi/sales/pojo/SalesLedgerProduct.java
@@ -1,12 +1,14 @@ package com.ruoyi.sales.pojo; import java.math.BigDecimal; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import com.ruoyi.framework.aspectj.lang.annotation.Excel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.math.BigDecimal; /** * 产品信息对象 sales_ledger_product @@ -109,4 +111,34 @@ * 未来票金额(元) */ private BigDecimal futureTicketsAmount; @ApiModelProperty(value = "开票数") private Integer invoiceNum; @ApiModelProperty(value = "未开票数") private Integer noInvoiceNum; @ApiModelProperty(value = "开票金额") private BigDecimal invoiceAmount; @ApiModelProperty(value = "未开票金额") private BigDecimal noInvoiceAmount; @ApiModelProperty(value = "本次开票数") @TableField(exist = false) private Integer currentInvoiceNum; @TableField(exist = false) @ApiModelProperty(value = "本次开票金额") private BigDecimal currentInvoiceAmount; /** * 产品id */ private Long productId; /** * 产品规格id */ private Long productModelId; } src/main/java/com/ruoyi/sales/service/InvoiceLedgerService.java
@@ -4,7 +4,9 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.common.vo.FileVo; import com.ruoyi.sales.dto.InvoiceLedgerDto; import com.ruoyi.sales.dto.InvoiceRegistrationProductDto; import com.ruoyi.sales.pojo.InvoiceLedgerFile; import com.ruoyi.sales.pojo.InvoiceRegistrationProduct; import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletResponse; @@ -15,10 +17,10 @@ /** * 开票台账新增 * @param invoiceLedgerDto * @param productDto * @return */ int invoiceLedgerSaveOrUpdate( InvoiceLedgerDto invoiceLedgerDto); int invoiceLedgerSaveOrUpdate( InvoiceRegistrationProductDto productDto); /** * 开票台账删除 @@ -87,4 +89,19 @@ IPage<InvoiceLedgerDto> invoiceLedgerSalesAccount(Page page, InvoiceLedgerDto invoiceLedgerDto); BigDecimal getInvoiceAmount(); /** * 开票登记产品分页查询 * @param page * @param registrationProductDto * @return */ IPage<InvoiceRegistrationProductDto> registrationProductPage(Page page, InvoiceRegistrationProductDto registrationProductDto); /** * 产品开票台账详情 * @param id * @return */ InvoiceRegistrationProductDto invoiceLedgerProductDetail(Integer id); } src/main/java/com/ruoyi/sales/service/InvoiceRegistrationService.java
@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.sales.dto.InvoiceRegistrationDto; import com.ruoyi.sales.dto.InvoiceRegistrationProductDto; import com.ruoyi.sales.dto.SalesLedgerDto; import org.springframework.web.bind.annotation.RequestBody; import javax.servlet.http.HttpServletResponse; @@ -12,11 +13,11 @@ public interface InvoiceRegistrationService { /** * 开票登记新增 * @param invoiceRegistrationDto * 开票登记记录新增 * @param salesLedgerDto * @return */ void invoiceRegistrationSaveOrUpdate(InvoiceRegistrationDto invoiceRegistrationDto); void invoiceRegistrationSave(SalesLedgerDto salesLedgerDto); /** * 开票登记删除 src/main/java/com/ruoyi/sales/service/impl/CommonFileServiceImpl.java
@@ -1,26 +1,40 @@ package com.ruoyi.sales.service.impl; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.other.mapper.TempFileMapper; import com.ruoyi.other.pojo.TempFile; import com.ruoyi.sales.mapper.CommonFileMapper; import com.ruoyi.sales.pojo.CommonFile; import com.ruoyi.sales.service.ICommonFileService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.io.FilenameUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardCopyOption; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.Arrays; import java.util.List; import java.util.UUID; @Service @RequiredArgsConstructor @Slf4j public class CommonFileServiceImpl extends ServiceImpl<CommonFileMapper, CommonFile> implements ICommonFileService { private final CommonFileMapper commonFileMapper; private final TempFileMapper tempFileMapper; @Value("${file.upload-dir}") private String uploadDir; @@ -60,4 +74,73 @@ public int delCommonFileByIds(Long[] ids) { return commonFileMapper.deleteBatchIds(Arrays.asList(ids)); } /** * 将临时文件迁移到正式目录 * * @param businessId 业务ID(销售台账ID) * @param tempFileIds 临时文件ID列表 * @throws IOException 文件操作异常 */ @Transactional(rollbackFor = Exception.class) public void migrateTempFilesToFormal(Long businessId, List<String> tempFileIds) throws IOException { if (CollectionUtils.isEmpty(tempFileIds)) { return; } // 构建正式目录路径(按业务类型和日期分组) String formalDir = uploadDir + LocalDate.now().format(DateTimeFormatter.ISO_LOCAL_DATE); Path formalDirPath = Paths.get(formalDir); // 确保正式目录存在(递归创建) if (!Files.exists(formalDirPath)) { Files.createDirectories(formalDirPath); } for (String tempFileId : tempFileIds) { // 查询临时文件记录 TempFile tempFile = tempFileMapper.selectById(tempFileId); if (tempFile == null) { log.warn("临时文件不存在,跳过处理: {}", tempFileId); continue; } // 构建正式文件名(包含业务ID和时间戳,避免冲突) String originalFilename = tempFile.getOriginalName(); String fileExtension = FilenameUtils.getExtension(originalFilename); String formalFilename = businessId + "_" + System.currentTimeMillis() + "_" + UUID.randomUUID().toString().substring(0, 8) + (com.ruoyi.common.utils.StringUtils.hasText(fileExtension) ? "." + fileExtension : ""); Path formalFilePath = formalDirPath.resolve(formalFilename); try { // 执行文件迁移(使用原子操作确保安全性) Files.move( Paths.get(tempFile.getTempPath()), formalFilePath, StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.ATOMIC_MOVE ); log.info("文件迁移成功: {} -> {}", tempFile.getTempPath(), formalFilePath); // 更新文件记录(关联到业务ID) CommonFile fileRecord = new CommonFile(); fileRecord.setCommonId(businessId); fileRecord.setName(originalFilename); fileRecord.setUrl(formalFilePath.toString()); fileRecord.setCreateTime(LocalDateTime.now()); fileRecord.setType(tempFile.getType()); commonFileMapper.insert(fileRecord); log.info("文件迁移成功: {} -> {}", tempFile.getTempPath(), formalFilePath); } catch (IOException e) { log.error("文件迁移失败: {}", tempFile.getTempPath(), e); // 可选择回滚事务或记录失败文件 throw new IOException("文件迁移异常", e); } } } } src/main/java/com/ruoyi/sales/service/impl/InvoiceLedgerServiceImpl.java
@@ -8,12 +8,15 @@ import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.common.vo.FileVo; import com.ruoyi.sales.dto.InvoiceLedgerDto; import com.ruoyi.sales.dto.InvoiceRegistrationProductDto; import com.ruoyi.sales.excel.InvoiceLedgerExcelDto; import com.ruoyi.sales.mapper.InvoiceLedgerFileMapper; import com.ruoyi.sales.mapper.InvoiceLedgerMapper; import com.ruoyi.sales.mapper.InvoiceRegistrationProductMapper; import com.ruoyi.sales.mapper.ReceiptPaymentMapper; import com.ruoyi.sales.pojo.InvoiceLedger; import com.ruoyi.sales.pojo.InvoiceLedgerFile; import com.ruoyi.sales.pojo.InvoiceRegistrationProduct; import com.ruoyi.sales.pojo.ReceiptPayment; import com.ruoyi.sales.service.InvoiceLedgerService; import org.apache.commons.collections4.CollectionUtils; @@ -30,6 +33,7 @@ import java.math.BigDecimal; import java.time.LocalDate; import java.time.YearMonth; import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.UUID; @@ -48,36 +52,48 @@ private InvoiceLedgerFileMapper invoiceLedgerFileMapper; @Autowired private ReceiptPaymentMapper receiptPaymentMapper; private InvoiceRegistrationProductMapper invoiceRegistrationProductMapper; /** * 开票台账新增 * @param invoiceLedgerDto * @param productDto * @return */ @Override @Transactional(rollbackFor = Exception.class) public int invoiceLedgerSaveOrUpdate(InvoiceLedgerDto invoiceLedgerDto) { InvoiceLedger invoiceLedger = new InvoiceLedger(); BeanUtils.copyProperties(invoiceLedgerDto, invoiceLedger); public int invoiceLedgerSaveOrUpdate(InvoiceRegistrationProductDto productDto) { // 判断是否已经新增开票台账 QueryWrapper<InvoiceLedger> ledgerQueryWrapper = new QueryWrapper<>(); ledgerQueryWrapper.eq("invoice_registration_product_id", productDto.getId()); InvoiceLedger invoiceLedger = invoiceLedgerMapper.selectOne(ledgerQueryWrapper); int result; if(invoiceLedgerDto.getId() == null){ if(ObjectUtils.isEmpty(invoiceLedger)){ invoiceLedger = new InvoiceLedger(); invoiceLedger.setInvoiceRegistrationProductId(productDto.getId()); invoiceLedger.setInvoiceNo(productDto.getInvoiceNo()); invoiceLedger.setInvoiceTotal(productDto.getInvoiceTotal()); invoiceLedger.setInvoiceDate(productDto.getInvoiceDate()); invoiceLedger.setInvoicePerson(productDto.getInvoicePerson()); result = invoiceLedgerMapper.insert(invoiceLedger); }else { invoiceLedger.setInvoiceNo(productDto.getInvoiceNo()); invoiceLedger.setInvoiceTotal(productDto.getInvoiceTotal()); invoiceLedger.setInvoiceDate(productDto.getInvoiceDate()); invoiceLedger.setInvoicePerson(productDto.getInvoicePerson()); result = invoiceLedgerMapper.updateById(invoiceLedger); //删除所有附件关联 LambdaQueryWrapper<InvoiceLedgerFile> delWrapper = new LambdaQueryWrapper<>(); delWrapper.eq(InvoiceLedgerFile::getInvoiceLedgerId, invoiceLedgerDto.getId()); delWrapper.eq(InvoiceLedgerFile::getInvoiceLedgerId, invoiceLedger.getId()); invoiceLedgerFileMapper.delete(delWrapper); } List<FileVo> fileList = invoiceLedgerDto.getFileList(); List<FileVo> fileList = productDto.getFileList(); if(CollectionUtils.isNotEmpty(fileList)){ fileList.forEach(fileVo -> { for (FileVo fileVo : fileList) { InvoiceLedgerFile invoiceLedgerFile = new InvoiceLedgerFile(); BeanUtils.copyProperties(fileVo, invoiceLedgerFile); invoiceLedgerFile.setInvoiceLedgerId(invoiceLedger.getId()); invoiceLedgerFileMapper.insert(invoiceLedgerFile); }); } } return result; } @@ -226,20 +242,20 @@ @Override public IPage<InvoiceLedgerDto> invoiceLedgerSalesAccount(Page page, InvoiceLedgerDto invoiceLedgerDto) { IPage<InvoiceLedgerDto> invoiceLedgerDtoIPage = invoiceLedgerMapper.invoiceLedgerSalesAccount(page, invoiceLedgerDto); for (InvoiceLedgerDto record : invoiceLedgerDtoIPage.getRecords()) { QueryWrapper<ReceiptPayment> queryWrapper = new QueryWrapper<>(); queryWrapper.eq("customer_id", record.getCustomerId()); List<ReceiptPayment> receiptPaymentList = receiptPaymentMapper.selectList(queryWrapper); BigDecimal totalAmount = BigDecimal.ZERO; if(!CollectionUtils.isEmpty(receiptPaymentList)){ for (ReceiptPayment receiptPayment : receiptPaymentList) { totalAmount = totalAmount.add(receiptPayment.getInvoiceAmount()); } } BigDecimal unReceiptPaymentAmount = record.getInvoiceAmount().subtract(totalAmount); record.setReceiptPaymentAmount(totalAmount); record.setUnReceiptPaymentAmount(unReceiptPaymentAmount); } // for (InvoiceLedgerDto record : invoiceLedgerDtoIPage.getRecords()) { // QueryWrapper<ReceiptPayment> queryWrapper = new QueryWrapper<>(); // queryWrapper.eq("customer_id", record.getCustomerId()); // List<ReceiptPayment> receiptPaymentList = receiptPaymentMapper.selectList(queryWrapper); // BigDecimal totalAmount = BigDecimal.ZERO; // if(!CollectionUtils.isEmpty(receiptPaymentList)){ // for (ReceiptPayment receiptPayment : receiptPaymentList) { // totalAmount = totalAmount.add(receiptPayment.getInvoiceAmount()); // } // } // BigDecimal unReceiptPaymentAmount = record.getInvoiceAmount().subtract(totalAmount); // record.setReceiptPaymentAmount(totalAmount); // record.setUnReceiptPaymentAmount(unReceiptPaymentAmount); // } return invoiceLedgerDtoIPage; } @@ -256,12 +272,48 @@ // 执行查询并计算总和 List<InvoiceLedger> invoiceLedgers = invoiceLedgerMapper.selectList(queryWrapper); BigDecimal totalContractAmount = invoiceLedgers.stream() .map(InvoiceLedger::getInvoiceAmount) .filter(Objects::nonNull) .reduce(BigDecimal.ZERO, BigDecimal::add); // BigDecimal totalContractAmount = invoiceLedgers.stream() // .map(InvoiceLedger::getInvoiceAmount) // .filter(Objects::nonNull) // .reduce(BigDecimal.ZERO, BigDecimal::add); // // return totalContractAmount; return null; } return totalContractAmount; /** * 开票登记产品分页查询 * @param page * @param registrationProductDto * @return */ @Override public IPage<InvoiceRegistrationProductDto> registrationProductPage(Page page, InvoiceRegistrationProductDto registrationProductDto) { return invoiceRegistrationProductMapper.invoiceRegistrationProductPage(page,registrationProductDto); } /** * 产品开票台账详情 * @param id * @return */ @Override public InvoiceRegistrationProductDto invoiceLedgerProductDetail(Integer id) { InvoiceRegistrationProductDto invoiceRegistrationProductDto = invoiceLedgerMapper.invoiceLedgerProductInfo(id); if(ObjectUtils.isEmpty(invoiceRegistrationProductDto)){ throw new RuntimeException("产品开票台账查找失败"); } // 查询附件 QueryWrapper<InvoiceLedgerFile> queryWrapper = new QueryWrapper<>(); queryWrapper.eq("invoice_ledger_id", invoiceRegistrationProductDto.getInvoiceLedgerId()); List<InvoiceLedgerFile> invoiceLedgerFileList = invoiceLedgerFileMapper.selectList(queryWrapper); List<FileVo> fileList = invoiceLedgerFileList.stream().map(item -> { FileVo fileVo = new FileVo(); BeanUtils.copyProperties(item, fileVo); return fileVo; }).collect(Collectors.toList()); invoiceRegistrationProductDto.setFileList(fileList); return invoiceRegistrationProductDto; } } src/main/java/com/ruoyi/sales/service/impl/InvoiceRegistrationServiceImpl.java
@@ -5,15 +5,17 @@ import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.basic.excel.SupplierManageExcelDto; import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.sales.dto.InvoiceRegistrationDto; import com.ruoyi.sales.dto.InvoiceRegistrationProductDto; import com.ruoyi.sales.dto.SalesLedgerDto; import com.ruoyi.sales.excel.InvoiceRegisAndProductExcelDto; import com.ruoyi.sales.mapper.InvoiceRegistrationMapper; import com.ruoyi.sales.mapper.InvoiceRegistrationProductMapper; import com.ruoyi.sales.mapper.SalesLedgerProductMapper; import com.ruoyi.sales.pojo.InvoiceRegistration; import com.ruoyi.sales.pojo.InvoiceRegistrationProduct; import com.ruoyi.sales.pojo.SalesLedgerProduct; import com.ruoyi.sales.service.InvoiceRegistrationService; import org.apache.commons.collections4.CollectionUtils; import org.springframework.beans.BeanUtils; @@ -35,38 +37,41 @@ @Autowired private InvoiceRegistrationProductMapper invoiceRegistrationProductMapper; @Autowired private SalesLedgerProductMapper salesLedgerProductMapper; /** * 开票登记新增 * @param invoiceRegistrationDto * 开票登记记录新增 * @param salesLedgerDto * @return */ @Override @Transactional(rollbackFor = Exception.class) public void invoiceRegistrationSaveOrUpdate(InvoiceRegistrationDto invoiceRegistrationDto) { public void invoiceRegistrationSave(SalesLedgerDto salesLedgerDto) { InvoiceRegistration invoiceRegistration = new InvoiceRegistration(); BeanUtils.copyProperties(invoiceRegistrationDto, invoiceRegistration); List<InvoiceRegistrationProductDto> productDtoList = invoiceRegistrationDto.getProductDtoList(); // 新增开票登记 if(invoiceRegistrationDto.getId() == null){ invoiceRegistrationMapper.insert(invoiceRegistration); // 新增开票产品登记 if(CollectionUtils.isNotEmpty(productDtoList)){ for (InvoiceRegistrationProductDto invoiceRegistrationProductDto : productDtoList) { InvoiceRegistrationProduct invoiceRegistrationProduct = new InvoiceRegistrationProduct(); BeanUtils.copyProperties(invoiceRegistrationProductDto, invoiceRegistrationProduct); invoiceRegistrationProduct.setInvoiceRegistrationId(invoiceRegistration.getId()); invoiceRegistrationProductMapper.insert(invoiceRegistrationProduct); BeanUtils.copyProperties(salesLedgerDto, invoiceRegistration); invoiceRegistration.setId(null); invoiceRegistration.setCustomerId(salesLedgerDto.getCustomerId().intValue()); invoiceRegistration.setSalesLedgerId(salesLedgerDto.getId().intValue()); invoiceRegistrationMapper.insert(invoiceRegistration); List<SalesLedgerProduct> productData = salesLedgerDto.getProductData(); if(CollectionUtils.isNotEmpty(productData)){ for (SalesLedgerProduct productDatum : productData) { // 如果开票数为0 跳过 Integer currentInvoiceNum = productDatum.getCurrentInvoiceNum(); if(null == currentInvoiceNum || currentInvoiceNum == 0){ continue; } } // 开票登记修改 }else { if(CollectionUtils.isNotEmpty(productDtoList)){ for (InvoiceRegistrationProductDto invoiceRegistrationProductDto : productDtoList) { InvoiceRegistrationProduct invoiceRegistrationProduct = new InvoiceRegistrationProduct(); BeanUtils.copyProperties(invoiceRegistrationProductDto, invoiceRegistrationProduct); invoiceRegistrationProductMapper.updateById(invoiceRegistrationProduct); } InvoiceRegistrationProduct invoiceRegistrationProduct = new InvoiceRegistrationProduct(); BeanUtils.copyProperties(productDatum, invoiceRegistrationProduct); invoiceRegistrationProduct.setId(null); invoiceRegistrationProduct.setSalesLedgerId(salesLedgerDto.getId().intValue()); invoiceRegistrationProduct.setInvoiceRegistrationId(invoiceRegistration.getId()); invoiceRegistrationProduct.setInvoiceAmount(productDatum.getCurrentInvoiceAmount()); invoiceRegistrationProduct.setInvoiceNum(productDatum.getCurrentInvoiceNum()); invoiceRegistrationProduct.setSalesLedgerProductId(productDatum.getId().intValue()); invoiceRegistrationProductMapper.insert(invoiceRegistrationProduct); salesLedgerProductMapper.updateById(productDatum); } } } src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
@@ -1,6 +1,7 @@ package com.ruoyi.sales.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.Wrappers; @@ -13,9 +14,11 @@ import com.ruoyi.other.pojo.TempFile; import com.ruoyi.sales.dto.SalesLedgerDto; import com.ruoyi.sales.mapper.CommonFileMapper; import com.ruoyi.sales.mapper.InvoiceRegistrationProductMapper; import com.ruoyi.sales.mapper.SalesLedgerMapper; import com.ruoyi.sales.mapper.SalesLedgerProductMapper; import com.ruoyi.sales.pojo.CommonFile; import com.ruoyi.sales.pojo.InvoiceRegistrationProduct; import com.ruoyi.sales.pojo.SalesLedger; import com.ruoyi.sales.pojo.SalesLedgerProduct; import com.ruoyi.sales.service.ISalesLedgerService; @@ -23,11 +26,13 @@ import lombok.extern.slf4j.Slf4j; import org.apache.commons.io.FilenameUtils; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.script.DefaultRedisScript; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.ObjectUtils; import java.io.IOException; import java.lang.reflect.Field; @@ -65,6 +70,9 @@ private final CommonFileMapper commonFileMapper; private final TempFileMapper tempFileMapper; @Autowired private InvoiceRegistrationProductMapper invoiceRegistrationProductMapper; @Value("${file.upload-dir}") private String uploadDir; @@ -237,7 +245,6 @@ if (salesLedgerDto.getTempFileIds() != null && !salesLedgerDto.getTempFileIds().isEmpty()) { migrateTempFilesToFormal(salesLedger.getId(), salesLedgerDto.getTempFileIds()); } return 1; } catch (IOException e) { throw new BaseException("文件迁移失败: " + e.getMessage()); @@ -338,6 +345,8 @@ if (!insertList.isEmpty()) { for (SalesLedgerProduct salesLedgerProduct : insertList) { salesLedgerProduct.setType(type); salesLedgerProduct.setNoInvoiceNum(salesLedgerProduct.getQuantity().intValue()); salesLedgerProduct.setNoInvoiceAmount(salesLedgerProduct.getTaxInclusiveTotalPrice()); salesLedgerProductMapper.insert(salesLedgerProduct); } } src/main/resources/mapper/sales/InvoiceLedgerMapper.xml
@@ -122,5 +122,43 @@ T2.customer_name; </select> <select id="invoiceLedgerProductInfo" resultType="com.ruoyi.sales.dto.InvoiceRegistrationProductDto"> SELECT T1.id , T1.sales_ledger_id , T1.sales_ledger_product_id , T1.invoice_registration_id , T1.product_category , T1.specification_model , T1.unit , T1.quantity , T1.tax_rate , T1.tax_inclusive_unit_price , T1.tax_inclusive_total_price , T1.tax_exclusive_total_price , T1.invoice_type , T1.invoice_num , T1.invoice_amount , T1.no_invoice_num , T1.no_invoice_amount , T1.create_time , T1.create_user , T1.update_time , T1.update_user , T1.tenant_id, T2.sales_contract_no, T2.customer_contract_no, T2.customer_name, T3.invoice_no, T3.invoice_total, T3.invoice_person, T3.invoice_date, T3.id AS invoice_ledger_id FROM invoice_registration_product T1 LEFT JOIN sales_ledger T2 ON T1.sales_ledger_id = T2.id LEFT JOIN invoice_ledger T3 ON T1.id = T3.invoice_registration_product_id WHERE T1.id = #{id} </select> </mapper> src/main/resources/mapper/sales/InvoiceRegistrationMapper.xml
@@ -18,10 +18,20 @@ T1.tenant_id, T2.customer_contract_no, T3.customer_name, T2.contract_amount T2.contract_amount, CASE WHEN T4.noInvoiceAmountTotal IS NULL THEN 0 ELSE T4.noInvoiceAmountTotal END AS noInvoiceAmountTotal FROM invoice_registration T1 LEFT JOIN sales_ledger T2 ON T1.sales_ledger_id = T2.id LEFT JOIN customer T3 ON T1.customer_id = T3.id LEFT JOIN ( SELECT SUM( no_invoice_amount ) AS noInvoiceAmountTotal , invoice_registration_id FROM invoice_registration_product GROUP BY invoice_registration_id ) T4 ON T1.id = T4.invoice_registration_id </select> <select id="invoiceRegisAndProductExcelDtoList" resultType="com.ruoyi.sales.excel.InvoiceRegisAndProductExcelDto"> src/main/resources/mapper/sales/InvoiceRegistrationProductMapper.xml
@@ -35,4 +35,48 @@ </if> </where> </select> <select id="invoiceRegistrationProductPage" resultType="com.ruoyi.sales.dto.InvoiceRegistrationProductDto"> SELECT T1.id , T1.sales_ledger_id , T1.sales_ledger_product_id , T1.invoice_registration_id , T1.product_category , T1.specification_model , T1.unit , T1.quantity , T1.tax_rate , T1.tax_inclusive_unit_price , T1.tax_inclusive_total_price , T1.tax_exclusive_total_price , T1.invoice_type , T1.invoice_num , T1.invoice_amount , T1.no_invoice_num , T1.no_invoice_amount , T1.create_time , T1.create_user , T1.update_time , T1.update_user , T1.tenant_id, T2.sales_contract_no, T2.customer_contract_no, T2.customer_name, T3.invoice_no, T3.invoice_total, T3.invoice_person, T3.invoice_date, T4.invoiceFileName FROM invoice_registration_product T1 LEFT JOIN sales_ledger T2 ON T1.sales_ledger_id = T2.id LEFT JOIN invoice_ledger T3 ON T1.id = T3.invoice_registration_product_id LEFT JOIN ( SELECT invoice_ledger_id, GROUP_CONCAT( name ORDER BY id ASC SEPARATOR ' | ') AS invoiceFileName FROM invoice_ledger_file GROUP BY invoice_ledger_id ) T4 ON T4.invoice_ledger_id = T3.id ORDER BY T1.create_time DESC </select> </mapper>