已修改17个文件
已添加20个文件
1361 ■■■■■ 文件已修改
src/main/java/com/ruoyi/basic/controller/CustomerController.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/controller/ProductController.java 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/controller/SupplierManageController.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/dto/ProductDto.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/dto/ProductModelDto.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/dto/ProductTreeDto.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/mapper/ProductMapper.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/mapper/ProductModelMapper.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/pojo/Product.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/pojo/ProductModel.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/service/IProductModelService.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/service/IProductService.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/service/ISupplierService.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/service/impl/ProductModelServiceImpl.java 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/service/impl/ProductServiceImpl.java 118 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/common/config/IgnoreTableConfig.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/purchase/controller/PaymentRegistrationController.java 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/purchase/dto/PaymentLedgerDto.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/purchase/dto/PaymentRegistrationDto.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/purchase/mapper/PaymentRegistrationMapper.java 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/purchase/pojo/PaymentRegistration.java 83 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/purchase/service/IPaymentRegistrationService.java 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/purchase/service/impl/PaymentRegistrationServiceImpl.java 246 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/controller/InvoiceLedgerController.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/controller/ReceiptPaymentController.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/controller/SalesLedgerController.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/dto/InvoiceLedgerDto.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/mapper/InvoiceLedgerMapper.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/service/ISalesLedgerService.java 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/service/InvoiceLedgerService.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/service/ReceiptPaymentService.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/service/impl/InvoiceLedgerServiceImpl.java 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/service/impl/ReceiptPaymentServiceImpl.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/purchase/PaymentRegistrationMapper.xml 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/sales/InvoiceLedgerMapper.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/sales/ReceiptPaymentMapper.xml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/controller/CustomerController.java
@@ -1,24 +1,18 @@
package com.ruoyi.basic.controller;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import com.ruoyi.basic.pojo.Customer;
import com.ruoyi.basic.service.ICustomerService;
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.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.utils.poi.ExcelUtil;
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.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.web.page.TableDataInfo;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
/**
 * å®¢æˆ·æ¡£æ¡ˆController
src/main/java/com/ruoyi/basic/controller/ProductController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,85 @@
package com.ruoyi.basic.controller;
import com.ruoyi.basic.dto.ProductDto;
import com.ruoyi.basic.dto.ProductModelDto;
import com.ruoyi.basic.dto.ProductTreeDto;
import com.ruoyi.basic.pojo.ProductModel;
import com.ruoyi.basic.service.IProductModelService;
import com.ruoyi.basic.service.IProductService;
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 lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@AllArgsConstructor
@RequestMapping("/basic/product")
public class ProductController extends BaseController {
    private IProductService productService;
    private IProductModelService productModelService;
    /**
     * æŸ¥è¯¢äº§å“
     */
    @GetMapping("/list")
    public List<ProductTreeDto> selectProductList(ProductDto productDto) {
        return productService.selectProductList(productDto);
    }
    /**
     * æ ¹æ®id查询产品规格
     */
    @GetMapping("/modelList")
    public List<ProductModel> selectModelList(ProductDto productDto) {
        return productModelService.selectModelList(productDto);
    }
    /**
     * æ–°å¢žæ›´æ–°äº§å“
     */
    @Log(title = "产品", businessType = BusinessType.INSERT)
    @PostMapping("/addOrEditProduct")
    public AjaxResult addOrEditProduct(@RequestBody ProductDto productDto) {
        return toAjax(productService.addOrEditProduct(productDto));
    }
    /**
     * æ–°å¢žæ›´æ–°äº§å“è§„格型号
     */
    @Log(title = "产品规格型号", businessType = BusinessType.INSERT)
    @PostMapping("/addOrEditProductModel")
    public AjaxResult addOrEditProductModel(@RequestBody ProductModelDto productModelDto) {
        return toAjax(productModelService.addOrEditProductModel(productModelDto));
    }
    /**
     * åˆ é™¤
     */
    @Log(title = "产品", businessType = BusinessType.DELETE)
    @DeleteMapping("/delProduct")
    public AjaxResult remove(@RequestBody Long[] ids) {
        if (ids == null || ids.length == 0) {
            return AjaxResult.error("请传入要删除的ID");
        }
        return toAjax(productService.delProductByIds(ids));
    }
    /**
     * åˆ é™¤äº§å“è§„格型号
     */
    @Log(title = "产品规格型号", businessType = BusinessType.DELETE)
    @DeleteMapping("/delProductModel")
    public AjaxResult delProductModel(@RequestBody Long[] ids) {
        if (ids == null || ids.length == 0) {
            return AjaxResult.error("请传入要删除的ID");
        }
        return toAjax(productModelService.delProductModel(ids));
    }
}
src/main/java/com/ruoyi/basic/controller/SupplierManageController.java
@@ -85,4 +85,13 @@
    public void supplierExport(HttpServletResponse response,SupplierManageDto supplierManageDto) {
        supplierService.supplierExport(response, supplierManageDto);
    }
    /**
     * ä¾›åº”商选项接口
     * @return
     */
    @GetMapping("/getOptions")
    public AjaxResult getOptions() {
        return AjaxResult.success(supplierService.list());
    }
}
src/main/java/com/ruoyi/basic/dto/ProductDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,13 @@
package com.ruoyi.basic.dto;
import com.ruoyi.basic.pojo.Product;
import com.ruoyi.basic.pojo.ProductModel;
import lombok.Data;
import java.util.List;
@Data
public class ProductDto extends Product {
    private List<ProductModel> productModelList;
}
src/main/java/com/ruoyi/basic/dto/ProductModelDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,8 @@
package com.ruoyi.basic.dto;
import com.ruoyi.basic.pojo.ProductModel;
import lombok.Data;
@Data
public class ProductModelDto extends ProductModel {
}
src/main/java/com/ruoyi/basic/dto/ProductTreeDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,14 @@
package com.ruoyi.basic.dto;
import lombok.Data;
import java.util.List;
@Data
public class ProductTreeDto {
    private Long id;
    private Long parentId;
    private String productName;
    private String label; // ç”¨äºŽæ ‘形结构的显示名称
    private List<ProductTreeDto> children;
}
src/main/java/com/ruoyi/basic/mapper/ProductMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,8 @@
package com.ruoyi.basic.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.basic.pojo.Product;
public interface ProductMapper extends BaseMapper<Product> {
}
src/main/java/com/ruoyi/basic/mapper/ProductModelMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,15 @@
package com.ruoyi.basic.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.basic.pojo.ProductModel;
/**
 * ã€è¯·å¡«å†™åŠŸèƒ½åç§°ã€‘Mapper接口
 *
 * @author ruoyi
 * @date 2025-05-19
 */
public interface ProductModelMapper extends BaseMapper<ProductModel> {
}
src/main/java/com/ruoyi/basic/pojo/Product.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,29 @@
package com.ruoyi.basic.pojo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
@Data
@TableName("product")
public class Product {
    private static final long serialVersionUID = 1L;
    /**
     * åºå·
     */
    @TableId(type = IdType.AUTO)
    private Long id;
    /**
     * çˆ¶ID
     */
    private Long parentId;
    /**
     *  äº§å“åç§°
     */
    private String productName;
}
src/main/java/com/ruoyi/basic/pojo/ProductModel.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,29 @@
package com.ruoyi.basic.pojo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
@Data
@TableName("product_model")
public class ProductModel {
    private static final long serialVersionUID = 1L;
    /**
     * åºå·
     */
    @TableId(type = IdType.AUTO)
    private Long id;
    /**
     * å…³è”产品id
     */
    private Long productId;
    /**
     * è§„格型号
     */
    private String model;
}
src/main/java/com/ruoyi/basic/service/IProductModelService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,24 @@
package com.ruoyi.basic.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.basic.dto.ProductDto;
import com.ruoyi.basic.dto.ProductModelDto;
import com.ruoyi.basic.pojo.ProductModel;
import java.util.List;
/**
 * ã€è¯·å¡«å†™åŠŸèƒ½åç§°ã€‘Service接口
 *
 * @author ruoyi
 * @date 2025-05-19
 */
public interface IProductModelService extends IService<ProductModel> {
    int addOrEditProductModel(ProductModelDto productModelDto);
    int delProductModel(Long[] ids);
    List<ProductModel> selectModelList(ProductDto productDto);
}
src/main/java/com/ruoyi/basic/service/IProductService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,18 @@
package com.ruoyi.basic.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.basic.dto.ProductDto;
import com.ruoyi.basic.dto.ProductTreeDto;
import com.ruoyi.basic.pojo.Product;
import java.util.List;
public interface IProductService extends IService<Product> {
    int addOrEditProduct(ProductDto productDto);
    int delProductByIds(Long[] ids);
    List<ProductTreeDto> selectProductList(ProductDto productDto);
}
src/main/java/com/ruoyi/basic/service/ISupplierService.java
@@ -2,13 +2,14 @@
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.basic.dto.SupplierManageDto;
import com.ruoyi.basic.pojo.SupplierManage;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
public interface ISupplierService {
public interface ISupplierService extends IService<SupplierManage> {
    /**
     * ä¾›åº”商新增
src/main/java/com/ruoyi/basic/service/impl/ProductModelServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,52 @@
package com.ruoyi.basic.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.basic.dto.ProductDto;
import com.ruoyi.basic.dto.ProductModelDto;
import com.ruoyi.basic.mapper.ProductModelMapper;
import com.ruoyi.basic.pojo.ProductModel;
import com.ruoyi.basic.service.IProductModelService;
import com.ruoyi.common.utils.bean.BeanUtils;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.List;
/**
 * ã€è¯·å¡«å†™åŠŸèƒ½åç§°ã€‘Service业务层处理
 *
 * @author ruoyi
 * @date 2025-05-19
 */
@Service
@AllArgsConstructor
public class ProductModelServiceImpl extends ServiceImpl<ProductModelMapper, ProductModel> implements IProductModelService {
    private ProductModelMapper productModelMapper;
    @Override
    public int addOrEditProductModel(ProductModelDto productModelDto) {
        if (productModelDto.getId() == null) {
            ProductModel productModel = new ProductModel();
            BeanUtils.copyProperties(productModelDto,productModel);
            return productModelMapper.insert(productModel);
        } else {
            return productModelMapper.updateById(productModelDto);
        }
    }
    @Override
    public int delProductModel(Long[] ids) {
        return productModelMapper.deleteBatchIds(Arrays.asList(ids));
    }
    @Override
    public List<ProductModel> selectModelList(ProductDto productDto) {
        LambdaQueryWrapper<ProductModel> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ProductModel::getProductId, productDto.getId());
        return productModelMapper.selectList(queryWrapper);
    }
}
src/main/java/com/ruoyi/basic/service/impl/ProductServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,118 @@
package com.ruoyi.basic.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.basic.dto.ProductDto;
import com.ruoyi.basic.dto.ProductTreeDto;
import com.ruoyi.basic.mapper.ProductMapper;
import com.ruoyi.basic.mapper.ProductModelMapper;
import com.ruoyi.basic.pojo.Product;
import com.ruoyi.basic.pojo.ProductModel;
import com.ruoyi.basic.service.IProductService;
import com.ruoyi.common.utils.bean.BeanUtils;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@Service
@AllArgsConstructor
public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> implements IProductService {
    private ProductMapper productMapper;
    private ProductModelMapper productModelMapper;
    @Override
    public List<ProductTreeDto> selectProductList(ProductDto productDto) {
        // æŸ¥è¯¢æ ¹èŠ‚ç‚¹ï¼ˆparentId ä¸º null)
        LambdaQueryWrapper<Product> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.isNull(Product::getParentId);
        // å¦‚果有产品名称条件,添加到查询中
        if (productDto.getProductName() != null && !productDto.getProductName().isEmpty()) {
            queryWrapper.like(Product::getProductName, productDto.getProductName());
        }
        // æŸ¥è¯¢æ ¹èŠ‚ç‚¹åˆ—è¡¨
        List<Product> rootProducts = productMapper.selectList(queryWrapper);
        // è½¬æ¢ä¸ºæ ‘节点并递归构建子树
        List<ProductTreeDto> tree = new ArrayList<>();
        for (Product product : rootProducts) {
            ProductTreeDto node = convertToTreeDto(product);
            node.setChildren(buildChildrenNodes(product.getId()));
            tree.add(node);
        }
        return tree;
    }
    // é€’归构建子节点
    private List<ProductTreeDto> buildChildrenNodes(Long parentId) {
        // æŸ¥è¯¢å½“前父节点的子节点
        LambdaQueryWrapper<Product> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Product::getParentId, parentId);
        List<Product> childProducts = productMapper.selectList(queryWrapper);
        // è½¬æ¢å­èŠ‚ç‚¹å¹¶é€’å½’æž„å»ºå®ƒä»¬çš„å­æ ‘
        List<ProductTreeDto> children = new ArrayList<>();
        for (Product child : childProducts) {
            ProductTreeDto childNode = convertToTreeDto(child);
            childNode.setChildren(buildChildrenNodes(child.getId()));
            children.add(childNode);
        }
        return children;
    }
    // å°† Product è½¬æ¢ä¸º ProductTreeDto
    private ProductTreeDto convertToTreeDto(Product product) {
        ProductTreeDto dto = new ProductTreeDto();
        BeanUtils.copyProperties(product, dto);
        dto.setLabel(product.getProductName()); // è®¾ç½® label ä¸ºäº§å“åç§°
        dto.setChildren(new ArrayList<>());
        return dto;
    }
    @Override
    public int addOrEditProduct(ProductDto productDto) {
        if (productDto.getId() == null) {
            // æ–°å¢žäº§å“é€»è¾‘
            if (productDto.getParentId() == null) {
                // è‹¥æœªæŒ‡å®šçˆ¶èŠ‚ç‚¹ï¼Œé»˜è®¤ä¸ºæ ¹èŠ‚ç‚¹ï¼ˆparentId è®¾ä¸º null)
                productDto.setParentId(null);
            } else {
                // æ£€æŸ¥çˆ¶èŠ‚ç‚¹æ˜¯å¦å­˜åœ¨ï¼ˆå¯é€‰ï¼Œæ ¹æ®ä¸šåŠ¡éœ€æ±‚ï¼‰
                Product parent = productMapper.selectById(productDto.getParentId());
                if (parent == null) {
                    throw new IllegalArgumentException("父节点不存在,无法添加子产品");
                }
            }
            return productMapper.insert(productDto);
        } else {
            // ç¼–辑产品逻辑
            // æ£€æŸ¥äº§å“æ˜¯å¦å­˜åœ¨ï¼ˆå¯é€‰ï¼Œæ ¹æ®ä¸šåŠ¡éœ€æ±‚ï¼‰
            Product existingProduct = productMapper.selectById(productDto.getId());
            if (existingProduct == null) {
                throw new IllegalArgumentException("要编辑的产品不存在");
            }
            return productMapper.updateById(productDto);
        }
    }
    @Override
    public int delProductByIds(Long[] ids) {
        // 1. åˆ é™¤å­è¡¨ product_model ä¸­å…³è”的数据
        LambdaQueryWrapper<ProductModel> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(ProductModel::getProductId, ids);
        productModelMapper.delete(queryWrapper);
        // 2. åˆ é™¤ä¸»è¡¨ product æ•°æ®
        int deleteCount = productMapper.deleteBatchIds(Arrays.asList(ids));
        return deleteCount;
    }
}
src/main/java/com/ruoyi/common/config/IgnoreTableConfig.java
@@ -28,6 +28,8 @@
        IGNORE_TABLES.add("sales_ledger_product");
        IGNORE_TABLES.add("sales_ledger_file");
        IGNORE_TABLES.add("temp_file");
        IGNORE_TABLES.add("common_file");
    }
}
src/main/java/com/ruoyi/purchase/controller/PaymentRegistrationController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,110 @@
package com.ruoyi.purchase.controller;
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.PaymentLedgerDto;
import com.ruoyi.purchase.dto.PaymentRegistrationDto;
import com.ruoyi.purchase.pojo.PaymentRegistration;
import com.ruoyi.purchase.service.IPaymentRegistrationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
 * ä»˜æ¬¾ç™»è®°Controller
 *
 * @author ruoyi
 * @date 2025-05-15
 */
@RestController
@RequestMapping("/purchase/paymentRegistration")
public class PaymentRegistrationController extends BaseController
{
    @Autowired
    private IPaymentRegistrationService paymentRegistrationService;
    /**
     * æŸ¥è¯¢ä»˜æ¬¾ç™»è®°åˆ—表
     */
//    @PreAuthorize("@ss.hasPermi('system:registration:list')")
    @GetMapping("/list")
    public TableDataInfo list(PaymentRegistrationDto paymentRegistrationDto)
    {
        startPage();
        List<PaymentRegistrationDto> list = paymentRegistrationService.selectPaymentRegistrationList(paymentRegistrationDto);
        return getDataTable(list);
    }
    /**
     * å¯¼å‡ºä»˜æ¬¾ç™»è®°åˆ—表
     */
//    @Log(title = "付款登记", businessType = BusinessType.EXPORT)
//    @PostMapping("/export")
//    public void export(HttpServletResponse response, PaymentRegistrationDto paymentRegistrationDto)
//    {
//        List<PaymentRegistrationDto> list = paymentRegistrationService.selectPaymentRegistrationList(paymentRegistrationDto);
//        ExcelUtil<PaymentRegistration> util = new ExcelUtil<PaymentRegistration>(PaymentRegistration.class);
//        util.exportExcel(response, list, "付款登记数据");
//    }
    /**
     * èŽ·å–ä»˜æ¬¾ç™»è®°è¯¦ç»†ä¿¡æ¯
     */
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id)
    {
        return success(paymentRegistrationService.selectPaymentRegistrationById(id));
    }
    /**
     * æ–°å¢žä»˜æ¬¾ç™»è®°
     */
    @Log(title = "付款登记", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody PaymentRegistration paymentRegistration)
    {
        return toAjax(paymentRegistrationService.insertPaymentRegistration(paymentRegistration));
    }
    /**
     * ä¿®æ”¹ä»˜æ¬¾ç™»è®°
     */
    @Log(title = "付款登记", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody PaymentRegistration paymentRegistration)
    {
        return toAjax(paymentRegistrationService.updatePaymentRegistration(paymentRegistration));
    }
    /**
     * åˆ é™¤ä»˜æ¬¾ç™»è®°
     */
    @Log(title = "付款登记", businessType = BusinessType.DELETE)
    @DeleteMapping("/del")
    public AjaxResult remove(@RequestBody Long[] ids)
    {
        return toAjax(paymentRegistrationService.deletePaymentRegistrationByIds(ids));
    }
    /**
     * èŽ·å–ä»˜æ¬¾ç™»è®°è¯¦ç»†ä¿¡æ¯
     */
    @GetMapping(value = "/byPurchaseId/{id}")
    public AjaxResult getPurchaseInfo(@PathVariable("id") Long id)
    {
        return success(paymentRegistrationService.selectPaymentRegistrationByPurchaseId(id));
    }
    /**
     * èŽ·å–ä»˜æ¬¾ç™»è®°è¯¦ç»†ä¿¡æ¯
     */
    @GetMapping(value = "/paymentLedgerList")
    public AjaxResult paymentLedgerList(PaymentLedgerDto paymentLedgerDto)
    {
        return success(paymentRegistrationService.selectPaymentLedgerList(paymentLedgerDto));
    }
}
src/main/java/com/ruoyi/purchase/dto/PaymentLedgerDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,16 @@
package com.ruoyi.purchase.dto;
import lombok.Data;
@Data
public class PaymentLedgerDto {
    // ä¾›åº”商名称
    private String supplierName;
    // å¼€å§‹æ—¥æœŸ
    private String startDate;
    // ç»“束日期
    private String endDate;
}
src/main/java/com/ruoyi/purchase/dto/PaymentRegistrationDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,34 @@
package com.ruoyi.purchase.dto;
import com.ruoyi.purchase.pojo.PaymentRegistration;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class PaymentRegistrationDto extends PaymentRegistration {
    // æŸ¥è¯¢åˆ—表查询用供应商号和合同号
    private String supplierNameOrContractNo;
    // é”€å”®åˆåŒå·
    private String salesContractNo;
    // é‡‡è´­åˆåŒå·
    private String purchaseContractNumber;
    // ä¾›åº”商名称
    private String supplierName;
    // å‘票号
    private String invoiceNumber;
    // å‘票金额
    private BigDecimal invoiceAmount;
    // å¾…付款金额
    private BigDecimal unPaymentAmount;
    // ç¨Žçއ
    private BigDecimal taxRate;
}
src/main/java/com/ruoyi/purchase/mapper/PaymentRegistrationMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,32 @@
package com.ruoyi.purchase.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.purchase.dto.PaymentRegistrationDto;
import com.ruoyi.purchase.pojo.PaymentRegistration;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
 * ä»˜æ¬¾ç™»è®°Mapper接口
 *
 * @author ruoyi
 * @date 2025-05-15
 */
public interface PaymentRegistrationMapper extends BaseMapper<PaymentRegistration> {
    /**
     * æŸ¥è¯¢ä»˜æ¬¾ç™»è®°
     *
     * @param id ä»˜æ¬¾ç™»è®°ä¸»é”®
     * @return ä»˜æ¬¾ç™»è®°
     */
    public PaymentRegistrationDto selectPaymentRegistrationById(@Param("id") Long id);
    /**
     * æŸ¥è¯¢ä»˜æ¬¾ç™»è®°åˆ—表
     *
     * @param paymentRegistrationDto ä»˜æ¬¾ç™»è®°
     * @return ä»˜æ¬¾ç™»è®°é›†åˆ
     */
    public List<PaymentRegistrationDto> selectPaymentRegistrationList(PaymentRegistrationDto paymentRegistrationDto);
}
src/main/java/com/ruoyi/purchase/pojo/PaymentRegistration.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,83 @@
package com.ruoyi.purchase.pojo;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
/**
 * ä»˜æ¬¾ç™»è®°å¯¹è±¡ payment_registration
 *
 * @author ruoyi
 * @date 2025-05-15
 */
@Data
@TableName("payment_registration")
public class PaymentRegistration {
    private static final long serialVersionUID = 1L;
    /**
     * id
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    /**
     * é”€å”®å°è´¦id
     */
    private Long saleLedgerId;
    /**
     * é‡‡è´­å°è´¦id
     */
    private Long purchaseLedgerId;
    /**
     * ä¾›åº”商id
     */
    private Long supplierId;
    /**
     * å‘票id
     */
    private Long invoicePurchaseId;
    /**
     * æœ¬æ¬¡ä»˜æ¬¾é‡‘额
     */
    private BigDecimal currentPaymentAmount;
    /**
     * ä»˜æ¬¾å½¢å¼
     */
    private String paymentMethod;
    /**
     * ç™»è®°äºº
     */
    private Long registrantId;
    // ç§Ÿæˆ·id
    private Long tenantId;
    /**
     * ä»˜æ¬¾æ—¥æœŸ
     */
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date paymentDate;
    /**
     * åˆ›å»ºæ—¥æœŸ
     */
    @TableField(fill = FieldFill.INSERT)
    private Date createTime;
    /**
     * ä¿®æ”¹æ—¥æœŸ
     */
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Date updateTime;
}
src/main/java/com/ruoyi/purchase/service/IPaymentRegistrationService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,67 @@
package com.ruoyi.purchase.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.purchase.dto.PaymentLedgerDto;
import com.ruoyi.purchase.dto.PaymentRegistrationDto;
import com.ruoyi.purchase.pojo.PaymentRegistration;
import java.util.List;
import java.util.Map;
/**
 * ä»˜æ¬¾ç™»è®°Service接口
 *
 * @author ruoyi
 * @date 2025-05-15
 */
public interface IPaymentRegistrationService extends IService<PaymentRegistration> {
    /**
     * æŸ¥è¯¢ä»˜æ¬¾ç™»è®°
     *
     * @param id ä»˜æ¬¾ç™»è®°ä¸»é”®
     * @return ä»˜æ¬¾ç™»è®°
     */
    public PaymentRegistration selectPaymentRegistrationById(Long id);
    /**
     * æŸ¥è¯¢ä»˜æ¬¾ç™»è®°åˆ—表
     *
     * @param paymentRegistrationDto ä»˜æ¬¾ç™»è®°
     * @return ä»˜æ¬¾ç™»è®°é›†åˆ
     */
    public List<PaymentRegistrationDto> selectPaymentRegistrationList(PaymentRegistrationDto paymentRegistrationDto);
    /**
     * æ–°å¢žä»˜æ¬¾ç™»è®°
     *
     * @param paymentRegistration ä»˜æ¬¾ç™»è®°
     * @return ç»“æžœ
     */
    public int insertPaymentRegistration(PaymentRegistration paymentRegistration);
    /**
     * ä¿®æ”¹ä»˜æ¬¾ç™»è®°
     *
     * @param paymentRegistration ä»˜æ¬¾ç™»è®°
     * @return ç»“æžœ
     */
    public int updatePaymentRegistration(PaymentRegistration paymentRegistration);
    /**
     * æ‰¹é‡åˆ é™¤ä»˜æ¬¾ç™»è®°
     *
     * @param ids éœ€è¦åˆ é™¤çš„付款登记主键集合
     * @return ç»“æžœ
     */
    public int deletePaymentRegistrationByIds(Long[] ids);
    /**
     * é€šè¿‡é‡‡è´­åˆåŒå·æŸ¥è¯¢é”€å”®åˆåŒå·ï¼Œä¾›åº”商名称,发票号,发票金额,税率
     *
     * @param purchaseId é‡‡è´­åˆåŒid
     * @return ç»“æžœ
     */
    PaymentRegistration selectPaymentRegistrationByPurchaseId(Long purchaseId);
    List<Map<String, Object>> selectPaymentLedgerList(PaymentLedgerDto paymentLedgerDto);
}
src/main/java/com/ruoyi/purchase/service/impl/PaymentRegistrationServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,246 @@
package com.ruoyi.purchase.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.basic.mapper.SupplierManageMapper;
import com.ruoyi.basic.pojo.SupplierManage;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.framework.security.LoginUser;
import com.ruoyi.purchase.dto.PaymentLedgerDto;
import com.ruoyi.purchase.dto.PaymentRegistrationDto;
import com.ruoyi.purchase.mapper.InvoicePurchaseMapper;
import com.ruoyi.purchase.mapper.PaymentRegistrationMapper;
import com.ruoyi.purchase.mapper.PurchaseLedgerMapper;
import com.ruoyi.purchase.pojo.InvoicePurchase;
import com.ruoyi.purchase.pojo.PaymentRegistration;
import com.ruoyi.purchase.pojo.PurchaseLedger;
import com.ruoyi.purchase.service.IPaymentRegistrationService;
import com.ruoyi.sales.mapper.SalesLedgerMapper;
import com.ruoyi.sales.mapper.SalesLedgerProductMapper;
import com.ruoyi.sales.pojo.SalesLedger;
import com.ruoyi.sales.pojo.SalesLedgerProduct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
/**
 * ä»˜æ¬¾ç™»è®°Service业务层处理
 *
 * @author ruoyi
 * @date 2025-05-15
 */
@Service
public class PaymentRegistrationServiceImpl extends ServiceImpl<PaymentRegistrationMapper, PaymentRegistration> implements IPaymentRegistrationService {
    @Autowired
    private PaymentRegistrationMapper paymentRegistrationMapper;
    @Autowired
    private PurchaseLedgerMapper purchaseLedgerMapper;
    @Autowired
    private InvoicePurchaseMapper invoicePurchaseMapper;
    @Autowired
    private SalesLedgerMapper salesLedgerMapper;
    @Autowired
    private SupplierManageMapper supplierManageMapper;
    @Autowired
    private SalesLedgerProductMapper salesLedgerProductMapper;
    /**
     * æŸ¥è¯¢ä»˜æ¬¾ç™»è®°
     *
     * @param id ä»˜æ¬¾ç™»è®°ä¸»é”®
     * @return ä»˜æ¬¾ç™»è®°
     */
    @Override
    public PaymentRegistration selectPaymentRegistrationById(Long id) {
        return paymentRegistrationMapper.selectPaymentRegistrationById(id);
    }
    /**
     * æŸ¥è¯¢ä»˜æ¬¾ç™»è®°åˆ—表
     *
     * @param paymentRegistrationDto ä»˜æ¬¾ç™»è®°
     * @return ä»˜æ¬¾ç™»è®°
     */
    @Override
    public List<PaymentRegistrationDto> selectPaymentRegistrationList(PaymentRegistrationDto paymentRegistrationDto) {
        List<PaymentRegistrationDto> list = paymentRegistrationMapper.selectPaymentRegistrationList(paymentRegistrationDto);
        for (PaymentRegistrationDto registrationDto : list) {
            List<PaymentRegistration> paymentRegistrations = paymentRegistrationMapper.selectList(new QueryWrapper<PaymentRegistration>()
                    .eq("invoice_purchase_id", registrationDto.getInvoicePurchaseId()));
            BigDecimal total = paymentRegistrations.stream().map(PaymentRegistration::getCurrentPaymentAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
            registrationDto.setUnPaymentAmount(registrationDto.getInvoiceAmount().subtract(total));
        }
        return list;
    }
    /**
     * æ–°å¢žä»˜æ¬¾ç™»è®°
     *
     * @param paymentRegistration ä»˜æ¬¾ç™»è®°
     * @return ç»“æžœ
     */
    @Override
    public int insertPaymentRegistration(PaymentRegistration paymentRegistration) {
        PurchaseLedger purchaseLedger = purchaseLedgerMapper.selectById(paymentRegistration.getPurchaseLedgerId());
        SalesLedger salesLedger = salesLedgerMapper.selectOne(new QueryWrapper<SalesLedger>().
                eq("sales_contract_no", purchaseLedger.getSalesContractNo()));
        if (salesLedger == null) {
            throw new RuntimeException("关联销售合同号不存在");
        }
        paymentRegistration.setSaleLedgerId(salesLedger.getId());
        paymentRegistration.setSupplierId(purchaseLedger.getSupplierId());
        List<InvoicePurchase> invoicePurchases = invoicePurchaseMapper.selectList(new QueryWrapper<InvoicePurchase>().
                eq("purchase_contract_no", purchaseLedger.getPurchaseContractNumber()));
        if (invoicePurchases == null || invoicePurchases.size() == 0) {
            throw new RuntimeException("关联发票不存在");
        }
        paymentRegistration.setInvoicePurchaseId(invoicePurchases.get(0).getId());
        List<PaymentRegistration> paymentRegistrations = paymentRegistrationMapper.selectList(new QueryWrapper<PaymentRegistration>()
                .eq("invoice_purchase_id", invoicePurchases.get(0).getId()));
        BigDecimal total = paymentRegistrations.stream().map(PaymentRegistration::getCurrentPaymentAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        if (total.add(paymentRegistration.getCurrentPaymentAmount()).compareTo(invoicePurchases.get(0).getInvoiceAmount()) > 0) {
            throw new RuntimeException("付款金额超出发票金额");
        }
        LoginUser loginUser = SecurityUtils.getLoginUser();
        Integer tenantId = loginUser.getTenantId();
        paymentRegistration.setTenantId(tenantId.longValue());
        paymentRegistration.setCreateTime(DateUtils.getNowDate());
        paymentRegistration.setUpdateTime(DateUtils.getNowDate());
        return paymentRegistrationMapper.insert(paymentRegistration);
    }
    /**
     * ä¿®æ”¹ä»˜æ¬¾ç™»è®°
     *
     * @param paymentRegistration ä»˜æ¬¾ç™»è®°
     * @return ç»“æžœ
     */
    @Override
    public int updatePaymentRegistration(PaymentRegistration paymentRegistration) {
        InvoicePurchase invoicePurchase = invoicePurchaseMapper.selectById(paymentRegistration.getInvoicePurchaseId());
        List<PaymentRegistration> paymentRegistrations = paymentRegistrationMapper.selectList(new QueryWrapper<PaymentRegistration>()
                .eq("invoice_purchase_id", paymentRegistration.getInvoicePurchaseId()).ne("id", paymentRegistration.getId()));
        BigDecimal total = paymentRegistrations.stream().map(PaymentRegistration::getCurrentPaymentAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        if (total.add(paymentRegistration.getCurrentPaymentAmount()).compareTo(invoicePurchase.getInvoiceAmount()) > 0) {
            throw new RuntimeException("付款金额超出发票金额");
        }
        paymentRegistration.setUpdateTime(DateUtils.getNowDate());
        return paymentRegistrationMapper.updateById(paymentRegistration);
    }
    /**
     * æ‰¹é‡åˆ é™¤ä»˜æ¬¾ç™»è®°
     *
     * @param ids éœ€è¦åˆ é™¤çš„付款登记主键
     * @return ç»“æžœ
     */
    @Override
    public int deletePaymentRegistrationByIds(Long[] ids) {
        return paymentRegistrationMapper.delete(new QueryWrapper<PaymentRegistration>().in("id", ids));
    }
    @Override
    public PaymentRegistration selectPaymentRegistrationByPurchaseId(Long id) {
        PaymentRegistrationDto paymentRegistrationDto = new PaymentRegistrationDto();
        PurchaseLedger purchaseLedger = purchaseLedgerMapper.selectById(id);
        paymentRegistrationDto.setSalesContractNo(purchaseLedger.getSalesContractNo());
        paymentRegistrationDto.setSupplierName(purchaseLedger.getSupplierName());
        paymentRegistrationDto.setSupplierId(purchaseLedger.getSupplierId());
        List<InvoicePurchase> invoicePurchaseList = invoicePurchaseMapper.selectList(new QueryWrapper<InvoicePurchase>()
                .eq("purchase_contract_no", purchaseLedger.getPurchaseContractNumber()));
        if (invoicePurchaseList != null && invoicePurchaseList.size() > 0) {
            paymentRegistrationDto.setInvoiceNumber(invoicePurchaseList.get(0).getInvoiceNumber());
            paymentRegistrationDto.setInvoiceAmount(invoicePurchaseList.get(0).getInvoiceAmount());
            paymentRegistrationDto.setTaxRate(invoicePurchaseList.get(0).getTaxRate());
        }
        return paymentRegistrationDto;
    }
    @Override
    public List<Map<String, Object>> selectPaymentLedgerList(PaymentLedgerDto paymentLedgerDto) {
        List<Map<String, Object>> result = new ArrayList<>();
        LambdaQueryWrapper<SupplierManage> queryWrapper = new LambdaQueryWrapper<>();
        Optional.ofNullable(paymentLedgerDto)
                .ifPresent(dto -> {
                    if (StringUtils.hasText(dto.getSupplierName())) {
                        queryWrapper.like(SupplierManage::getSupplierName, dto.getSupplierName());
                    }
                });
        List<SupplierManage> supplierManages = supplierManageMapper.selectList(queryWrapper);
        for (SupplierManage supplierManage : supplierManages) {
            Map<String, Object> res = new HashMap<>();
            res.put("supplierName", supplierManage.getSupplierName());
            // åº”付金额
            BigDecimal payableAmount = BigDecimal.ZERO;
            List<SalesLedger> salesLedgers = salesLedgerMapper.selectList(new QueryWrapper<SalesLedger>().eq("customer_id", supplierManage.getId()));
            if (salesLedgers != null && salesLedgers.size() > 0) {
                List<SalesLedgerProduct> salesLedgerProducts = salesLedgerProductMapper.selectList(new QueryWrapper<SalesLedgerProduct>()
                        .in("sales_ledger_id", salesLedgers.stream().map(SalesLedger::getId).collect(Collectors.toList())));
                // åº”付金额
                payableAmount = salesLedgerProducts.stream().map(SalesLedgerProduct::getTaxInclusiveTotalPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
            }
            // å¼€ç¥¨é‡‘额
            BigDecimal invoiceAmount = salesLedgers.stream().map(SalesLedger::getContractAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
            // ä»˜æ¬¾é‡‘额
            List<PaymentRegistration> paymentRegistrations = paymentRegistrationMapper.selectList(new QueryWrapper<PaymentRegistration>()
                    .eq("supplier_id", supplierManage.getId()));
            BigDecimal paymentAmount = BigDecimal.ZERO;
            if (paymentRegistrations != null && paymentRegistrations.size() > 0) {
                paymentAmount = paymentRegistrations.stream().map(PaymentRegistration::getCurrentPaymentAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
            }
            res.put("invoiceAmount", invoiceAmount);
            res.put("payableAmount", payableAmount);
            res.put("paymentAmount", paymentAmount);
            // è¯¦æƒ…
            List<Map<String, Object>> details = new ArrayList<>();
            for (PaymentRegistration paymentRegistration : paymentRegistrations) {
                Map<String, Object> detail = new HashMap<>();
                detail.put("voteCount", 1); // ç¥¨æ•°ï¼ŒæœªçŸ¥æ•°æ®æºï¼Œæš‚时用1
                detail.put("paymentAmount", paymentRegistration.getCurrentPaymentAmount()); // ä»˜æ¬¾é‡‘额
                InvoicePurchase  invoicePurchase = invoicePurchaseMapper.selectById(paymentRegistration.getInvoicePurchaseId());
                detail.put("payableAmount", invoicePurchase.getInvoiceAmount()); // åº”付金额
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                String formattedDate = sdf.format(paymentRegistration.getPaymentDate());
                detail.put("createTime", formattedDate); // å‘生时间
                details.add(detail);
            }
            res.put("details", paymentRegistrations);
            result.add(res);
        }
        return result;
    }
}
src/main/java/com/ruoyi/sales/controller/InvoiceLedgerController.java
@@ -9,6 +9,7 @@
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.List;
@RestController
@@ -121,4 +122,28 @@
        return AjaxResult.success(invoiceLedgerService.invoiceLedgerList(invoiceLedgerDto));
    }
    /**
     * å®¢æˆ·é”€å”®è®°å½•
     * @param page
     * @param invoiceLedgerDto
     * @return
     */
    @GetMapping("/salesAccount")
    public AjaxResult invoiceLedgerSalesAccount(Page page, InvoiceLedgerDto invoiceLedgerDto) {
        return AjaxResult.success(invoiceLedgerService.invoiceLedgerSalesAccount(page,invoiceLedgerDto));
    }
    /**
     * æœ¬æœˆå¼€ç¥¨é‡‘额
     */
    @GetMapping("/getInvoiceAmount")
    public AjaxResult getInvoiceAmount() {
        try {
            BigDecimal amount = invoiceLedgerService.getInvoiceAmount();
            return AjaxResult.success(amount != null ? amount : BigDecimal.ZERO);
        } catch (Exception e) {
            return AjaxResult.error("获取开票金额失败:" + e.getMessage());
        }
    }
}
src/main/java/com/ruoyi/sales/controller/ReceiptPaymentController.java
@@ -8,6 +8,7 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.math.BigDecimal;
import java.util.List;
@RestController
@@ -69,5 +70,16 @@
        return AjaxResult.success(receiptPaymentService.receiptPaymentInfo(id));
    }
    /**
     * æœ¬æœˆå›žæ¬¾é‡‘额
     */
    @GetMapping("/getReceiptAmount")
    public AjaxResult getReceiptAmount() {
        try {
            BigDecimal amount = receiptPaymentService.getReceiptAmount();
            return AjaxResult.success(amount != null ? amount : BigDecimal.ZERO);
        } catch (Exception e) {
            return AjaxResult.error("获取合同金额失败:" + e.getMessage());
        }
    }
}
src/main/java/com/ruoyi/sales/controller/SalesLedgerController.java
@@ -14,6 +14,7 @@
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.List;
/**
@@ -83,11 +84,12 @@
    /**
     * æŸ¥è¯¢é”€å”®å°è´¦ä¸åˆ†é¡µ
     *
     * @param salesLedgerDto
     * @return
     */
    @GetMapping("/listNoPage")
    public AjaxResult listNoPage(SalesLedgerDto salesLedgerDto){
    public AjaxResult listNoPage(SalesLedgerDto salesLedgerDto) {
        List<SalesLedger> list = salesLedgerService.selectSalesLedgerList(salesLedgerDto);
        return AjaxResult.success(list);
    }
@@ -103,4 +105,25 @@
        }
        return toAjax(commonFileService.deleteSalesLedgerByIds(ids));
    }
    /**
     * æœ¬æœˆé”€å”®åˆåŒé‡‘额
     */
    @GetMapping("/getContractAmount")
    public AjaxResult getContractAmount() {
        try {
            BigDecimal amount = salesLedgerService.getContractAmount();
            return AjaxResult.success(amount != null ? amount : BigDecimal.ZERO);
        } catch (Exception e) {
            return AjaxResult.error("获取合同金额失败:" + e.getMessage());
        }
    }
    /**
     * å®¢æˆ·åˆåŒé‡‘额TOP5统计
     */
    @GetMapping("/getTopFiveList")
    public AjaxResult getTopFiveList() {
        return AjaxResult.success(salesLedgerService.getTopFiveList());
    }
}
src/main/java/com/ruoyi/sales/dto/InvoiceLedgerDto.java
@@ -4,6 +4,8 @@
import com.ruoyi.sales.pojo.InvoiceLedger;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
import java.util.List;
@Data
@@ -25,4 +27,10 @@
    @ApiModelProperty(value = "发票文件名")
    private String invoiceFileName;
    @ApiModelProperty(value = "回款金额")
    private BigDecimal receiptPaymentAmount;
    @ApiModelProperty(value = "未回款金额")
    private BigDecimal unReceiptPaymentAmount;
}
src/main/java/com/ruoyi/sales/mapper/InvoiceLedgerMapper.java
@@ -33,4 +33,12 @@
     */
    InvoiceLedgerDto invoiceLedgerInfo(Integer id);
    /**
     * å®¢æˆ·é”€å”®è®°å½•
     * @param page
     * @param invoiceLedgerDto
     * @return
     */
    IPage<InvoiceLedgerDto> invoiceLedgerSalesAccount(Page page, InvoiceLedgerDto invoiceLedgerDto);
}
src/main/java/com/ruoyi/sales/service/ISalesLedgerService.java
@@ -1,10 +1,11 @@
package com.ruoyi.sales.service;
import java.util.List;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.sales.dto.SalesLedgerDto;
import com.ruoyi.sales.pojo.SalesLedger;
import java.math.BigDecimal;
import java.util.List;
/**
 * é”€å”®å°è´¦Service接口
@@ -23,4 +24,8 @@
    SalesLedgerDto getSalesLedgerWithProducts(SalesLedgerDto salesLedgerDto);
    List getSalesNo();
    BigDecimal getContractAmount();
    List getTopFiveList();
}
src/main/java/com/ruoyi/sales/service/InvoiceLedgerService.java
@@ -2,13 +2,13 @@
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.basic.dto.SupplierManageDto;
import com.ruoyi.common.vo.FileVo;
import com.ruoyi.sales.dto.InvoiceLedgerDto;
import com.ruoyi.sales.pojo.InvoiceLedgerFile;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.List;
public interface InvoiceLedgerService {
@@ -77,4 +77,14 @@
     * @return
     */
    List<InvoiceLedgerDto> invoiceLedgerList(InvoiceLedgerDto invoiceLedgerDto);
    /**
     * å®¢æˆ·é”€å”®è®°å½•
     * @param page
     * @param invoiceLedgerDto
     * @return
     */
    IPage<InvoiceLedgerDto> invoiceLedgerSalesAccount(Page page, InvoiceLedgerDto invoiceLedgerDto);
    BigDecimal getInvoiceAmount();
}
src/main/java/com/ruoyi/sales/service/ReceiptPaymentService.java
@@ -5,6 +5,7 @@
import com.ruoyi.sales.dto.ReceiptPaymentDto;
import com.ruoyi.sales.pojo.ReceiptPayment;
import java.math.BigDecimal;
import java.util.List;
public interface ReceiptPaymentService {
@@ -44,4 +45,6 @@
     * @return
     */
    ReceiptPaymentDto receiptPaymentInfo(Integer id);
    BigDecimal getReceiptAmount();
}
src/main/java/com/ruoyi/sales/service/impl/InvoiceLedgerServiceImpl.java
@@ -5,15 +5,16 @@
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.dto.SupplierManageDto;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.vo.FileVo;
import com.ruoyi.sales.dto.InvoiceLedgerDto;
import com.ruoyi.sales.excel.InvoiceLedgerExcelDto;
import com.ruoyi.sales.mapper.InvoiceLedgerFileMapper;
import com.ruoyi.sales.mapper.InvoiceLedgerMapper;
import com.ruoyi.sales.mapper.ReceiptPaymentMapper;
import com.ruoyi.sales.pojo.InvoiceLedger;
import com.ruoyi.sales.pojo.InvoiceLedgerFile;
import com.ruoyi.sales.pojo.ReceiptPayment;
import com.ruoyi.sales.service.InvoiceLedgerService;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
@@ -26,8 +27,11 @@
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.util.Collections;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.YearMonth;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
import java.util.stream.Collectors;
@@ -42,6 +46,9 @@
    @Autowired
    private InvoiceLedgerFileMapper invoiceLedgerFileMapper;
    @Autowired
    private ReceiptPaymentMapper receiptPaymentMapper;
    /**
     * å¼€ç¥¨å°è´¦æ–°å¢ž
@@ -210,4 +217,51 @@
        return invoiceLedgerMapper.invoiceLedgerList(invoiceLedgerDto);
    }
    /**
     * å®¢æˆ·é”€å”®è®°å½•
     * @param page
     * @param invoiceLedgerDto
     * @return
     */
    @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);
        }
        return invoiceLedgerDtoIPage;
    }
    @Override
    public BigDecimal getInvoiceAmount() {
        LocalDate now = LocalDate.now();
        YearMonth currentMonth = YearMonth.from(now);
        // åˆ›å»ºLambdaQueryWrapper
        LambdaQueryWrapper<InvoiceLedger> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.ge(InvoiceLedger::getInvoiceDate, currentMonth.atDay(1).atStartOfDay())  // å¤§äºŽç­‰äºŽæœ¬æœˆç¬¬ä¸€å¤©
                .lt(InvoiceLedger::getInvoiceDate, currentMonth.plusMonths(1).atDay(1).atStartOfDay()); // å°äºŽä¸‹æœˆç¬¬ä¸€å¤©
        // æ‰§è¡ŒæŸ¥è¯¢å¹¶è®¡ç®—总和
        List<InvoiceLedger> invoiceLedgers = invoiceLedgerMapper.selectList(queryWrapper);
        BigDecimal totalContractAmount = invoiceLedgers.stream()
                .map(InvoiceLedger::getInvoiceAmount)
                .filter(Objects::nonNull)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        return totalContractAmount;
    }
}
src/main/java/com/ruoyi/sales/service/impl/ReceiptPaymentServiceImpl.java
@@ -11,7 +11,11 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.YearMonth;
import java.util.List;
import java.util.Objects;
@Service
public class ReceiptPaymentServiceImpl extends ServiceImpl<ReceiptPaymentMapper,ReceiptPayment> implements ReceiptPaymentService {
@@ -75,4 +79,25 @@
    public ReceiptPaymentDto receiptPaymentInfo(Integer id) {
        return receiptPaymentMapper.receiptPaymentInfo(id);
    }
    @Override
    public BigDecimal getReceiptAmount() {
        LocalDate now = LocalDate.now();
        YearMonth currentMonth = YearMonth.from(now);
        // åˆ›å»ºLambdaQueryWrapper
        LambdaQueryWrapper<ReceiptPayment> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.ge(ReceiptPayment::getReceiptPaymentDate, currentMonth.atDay(1).atStartOfDay())  // å¤§äºŽç­‰äºŽæœ¬æœˆç¬¬ä¸€å¤©
                .lt(ReceiptPayment::getReceiptPaymentDate, currentMonth.plusMonths(1).atDay(1).atStartOfDay()); // å°äºŽä¸‹æœˆç¬¬ä¸€å¤©
        // æ‰§è¡ŒæŸ¥è¯¢å¹¶è®¡ç®—总和
        List<ReceiptPayment> receiptPayments = receiptPaymentMapper.selectList(queryWrapper);
        BigDecimal totalContractAmount = receiptPayments.stream()
                .map(ReceiptPayment::getReceiptPaymentAmount)
                .filter(Objects::nonNull)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        return totalContractAmount;
    }
}
src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
@@ -32,9 +32,13 @@
import java.io.IOException;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.nio.file.*;
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.YearMonth;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.TimeUnit;
@@ -124,6 +128,33 @@
        ).collect(Collectors.toList());
    }
    @Override
    public BigDecimal getContractAmount() {
        LocalDate now = LocalDate.now();
        YearMonth currentMonth = YearMonth.from(now);
        // åˆ›å»ºLambdaQueryWrapper
        LambdaQueryWrapper<SalesLedger> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.ge(SalesLedger::getEntryDate, currentMonth.atDay(1).atStartOfDay())  // å¤§äºŽç­‰äºŽæœ¬æœˆç¬¬ä¸€å¤©
                .lt(SalesLedger::getEntryDate, currentMonth.plusMonths(1).atDay(1).atStartOfDay()); // å°äºŽä¸‹æœˆç¬¬ä¸€å¤©
        // æ‰§è¡ŒæŸ¥è¯¢å¹¶è®¡ç®—总和
        List<SalesLedger> salesLedgers = salesLedgerMapper.selectList(queryWrapper);
        BigDecimal totalContractAmount = salesLedgers.stream()
                .map(SalesLedger::getContractAmount)
                .filter(Objects::nonNull)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        return totalContractAmount;
    }
    @Override
    public List getTopFiveList() {
        return null;
    }
    /**
     * ä¸‹åˆ’线命名转驼峰命名
     */
@@ -192,7 +223,7 @@
            // 4. å¤„理子表数据
            List<SalesLedgerProduct> productList = salesLedgerDto.getProductData();
            if (productList != null && !productList.isEmpty()) {
                handleSalesLedgerProducts(salesLedger.getId(), productList,salesLedgerDto.getType());
                handleSalesLedgerProducts(salesLedger.getId(), productList, salesLedgerDto.getType());
                updateMainContractAmount(
                        salesLedger.getId(),
                        productList,
@@ -287,7 +318,7 @@
    }
    private void handleSalesLedgerProducts(Long salesLedgerId, List<SalesLedgerProduct> products,Integer type) {
    private void handleSalesLedgerProducts(Long salesLedgerId, List<SalesLedgerProduct> products, Integer type) {
        // æŒ‰ID分组,区分新增和更新的记录
        Map<Boolean, List<SalesLedgerProduct>> partitionedProducts = products.stream()
                .peek(p -> p.setSalesLedgerId(salesLedgerId))
src/main/resources/mapper/purchase/PaymentRegistrationMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,87 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.purchase.mapper.PaymentRegistrationMapper">
    <resultMap type="PaymentRegistration" id="PaymentRegistrationResult">
        <result property="id" column="id"/>
        <result property="saleLedgerId" column="sale_ledger_id"/>
        <result property="purchaseLedgerId" column="purchase_ledger_id"/>
        <result property="supplierId" column="supplier_id"/>
        <result property="invoicePurchaseId" column="invoice_purchase_id"/>
        <result property="currentPaymentAmount" column="current_payment_amount"/>
        <result property="paymentMethod" column="payment_method"/>
        <result property="registrantId" column="registrant_id"/>
        <result property="paymentDate" column="payment_date"/>
        <result property="createTime" column="create_time"/>
        <result property="updateTime" column="update_time"/>
        <result property="tenantId" column="tenant_id"/>
    </resultMap>
    <resultMap type="com.ruoyi.purchase.dto.PaymentRegistrationDto" id="PaymentRegistrationDtoResult">
        <result property="id" column="id"/>
        <result property="saleLedgerId" column="sale_ledger_id"/>
        <result property="purchaseLedgerId" column="purchase_ledger_id"/>
        <result property="supplierId" column="supplier_id"/>
        <result property="invoicePurchaseId" column="invoice_purchase_id"/>
        <result property="currentPaymentAmount" column="current_payment_amount"/>
        <result property="paymentMethod" column="payment_method"/>
        <result property="registrantId" column="registrant_id"/>
        <result property="paymentDate" column="payment_date"/>
        <result property="createTime" column="create_time"/>
        <result property="updateTime" column="update_time"/>
        <result property="salesContractNo" column="sales_contract_no"/>
        <result property="purchaseContractNumber" column="purchase_contract_number"/>
        <result property="supplierName" column="supplier_name"/>
        <result property="invoiceNumber" column="invoice_number"/>
        <result property="taxRate" column="tax_rate"/>
        <result property="invoiceAmount" column="invoice_amount"/>
        <result property="tenantId" column="tenant_id"/>
    </resultMap>
    <sql id="selectPaymentRegistrationVo">
        select pr.id,
               pr.sale_ledger_id,
               pr.purchase_ledger_id,
               pr.supplier_id,
               pr.invoice_purchase_id,
               pr.current_payment_amount,
               pr.payment_method,
               pr.registrant_id,
               pr.payment_date,
               pr.create_time,
               pr.update_time,
               pr.tenant_id,
               sl.sales_contract_no as sales_contract_no,
               pl.purchase_contract_number as purchase_contract_number,
               sm.supplier_name as supplier_name,
               ip.invoice_number as invoice_number,
               ip.tax_rate as tax_rate,
               ip.invoice_amount as invoice_amount
        from payment_registration pr
                 left join sales_ledger sl on pr.sale_ledger_id = sl.id
                 left join purchase_ledger pl on pr.purchase_ledger_id = pl.id
                 left join supplier_manage sm on pr.supplier_id = sm.id
                 left join invoice_purchase ip on pr.invoice_purchase_id = ip.id
                 left join sys_user su on pr.registrant_id = su.user_id
    </sql>
    <select id="selectPaymentRegistrationList" parameterType="com.ruoyi.purchase.dto.PaymentRegistrationDto"
            resultMap="PaymentRegistrationDtoResult">
        <include refid="selectPaymentRegistrationVo"/>
        <where>
            <if test="supplierNameOrContractNo != null  and supplierNameOrContractNo != ''">
                and sm.supplier_name LIKE CONCAT('%', #{supplierNameOrContractNo}, '%') or sl.sales_contract_no LIKE
                CONCAT('%', #{supplierNameOrContractNo}, '%')
                or pl.purchase_contract_number LIKE CONCAT('%', #{supplierNameOrContractNo}, '%')
            </if>
        </where>
    </select>
    <select id="selectPaymentRegistrationById" parameterType="Long" resultMap="PaymentRegistrationDtoResult">
        <include refid="selectPaymentRegistrationVo"/>
        where pr.id = #{id}
    </select>
</mapper>
src/main/resources/mapper/sales/InvoiceLedgerMapper.xml
@@ -109,5 +109,18 @@
        WHERE T1.id = #{id}
    </select>
    <select id="invoiceLedgerSalesAccount" resultType="com.ruoyi.sales.dto.InvoiceLedgerDto">
        SELECT
            customer_id,
            T2.customer_name,
            SUM( invoice_amount ) invoiceAmount
        FROM
            invoice_ledger T1
                LEFT JOIN customer T2 ON T1.customer_id = T2.id
        GROUP BY
            customer_id,
            T2.customer_name;
    </select>
</mapper>
src/main/resources/mapper/sales/ReceiptPaymentMapper.xml
@@ -33,7 +33,11 @@
                OR T1.sales_contract_no LIKE CONCAT('%',#{receiptPaymentDto.searchText},'%')
                )
            </if>
            <if test="receiptPaymentDto.customerId != null">
                AND T1.customer_id = #{receiptPaymentDto.customerId}
            </if>
        </where>
        ORDER BY  T1.receipt_payment_date ASC
    </select>
    <select id="receiptPaymentInfo" resultType="com.ruoyi.sales.dto.ReceiptPaymentDto">