liyong
2026-04-21 7ec9b6c159fcb52b35910bca508ad730ab645267
feat(sales): 新增售后台账功能并优化发货流程

- 创建 AfterSalesLedgerDto 数据传输对象
- 修改 AfterSalesServiceController 中的 listSalesLedger 接口路径和参数类型
- 更新 ISalesLedgerService 接口方法签名以使用新的 DTO 类型
- 调整 SalesLedgerMapper 中的查询方法返回类型
- 重构 listSalesLedgerAndShipped 查询 SQL 以适配新字段结构
- 实现 SalesLedgerServiceImpl 中的台账列表查询逻辑
- 简化 ShippingInfoController 中的发货添加流程,移除审批环节
已添加1个文件
已修改6个文件
127 ■■■■ 文件已修改
src/main/java/com/ruoyi/aftersalesservice/controller/AfterSalesServiceController.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/controller/ShippingInfoController.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/dto/AfterSalesLedgerDto.java 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/mapper/SalesLedgerMapper.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/service/ISalesLedgerService.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java 24 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/sales/SalesLedgerMapper.xml 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/aftersalesservice/controller/AfterSalesServiceController.java
@@ -13,6 +13,7 @@
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.project.system.domain.SysUser;
import com.ruoyi.project.system.mapper.SysUserMapper;
import com.ruoyi.sales.dto.AfterSalesLedgerDto;
import com.ruoyi.sales.dto.SalesLedgerDto;
import com.ruoyi.sales.service.ISalesLedgerService;
import io.swagger.annotations.Api;
@@ -134,10 +135,10 @@
    }
    @GetMapping("listSalesLedger")
    @GetMapping("/listSalesLedger")
    @ApiOperation("售后服务-获取销售台账")
    public AjaxResult listSalesLedger(SalesLedgerDto salesLedgerDto, Page page) {
        IPage<SalesLedgerDto> list = salesLedgerService.listSalesLedger(salesLedgerDto,page);
    public AjaxResult listSalesLedger(AfterSalesLedgerDto salesLedgerDto, Page page) {
        IPage<AfterSalesLedgerDto> list = salesLedgerService.listSalesLedger(salesLedgerDto,page);
        return AjaxResult.success(list);
    }
src/main/java/com/ruoyi/sales/controller/ShippingInfoController.java
@@ -73,20 +73,10 @@
    @Transactional(rollbackFor = Exception.class)
    @Log(title = "发货信息管理", businessType = BusinessType.INSERT)
    public AjaxResult add(@RequestBody ShippingInfoDto req) throws Exception {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        String sh = OrderUtils.countTodayByCreateTime(shippingInfoMapper, "SH","shipping_no");
        // å‘货审批
        ApproveProcessVO approveProcessVO = new ApproveProcessVO();
        approveProcessVO.setApproveType(7);
        approveProcessVO.setApproveDeptId(loginUser.getCurrentDeptId());
        approveProcessVO.setApproveReason(req.getType() + ":" +sh);
        approveProcessVO.setApproveUserIds(req.getApproveUserIds());
        approveProcessVO.setApproveUser(loginUser.getUserId());
        approveProcessVO.setApproveTime(LocalDate.now().toString());
        approveProcessService.addApprove(approveProcessVO);
        // æ·»åŠ å‘è´§æ¶ˆæ¯
        req.setShippingNo(sh);
        req.setStatus("待审核");
        req.setStatus("审核完成");
        boolean save = shippingInfoService.save(req);
        return save ? AjaxResult.success() : AjaxResult.error();
    }
src/main/java/com/ruoyi/sales/dto/AfterSalesLedgerDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,64 @@
package com.ruoyi.sales.dto;
import com.baomidou.mybatisplus.annotation.TableField;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.sales.pojo.CommonFile;
import com.ruoyi.sales.pojo.SalesLedgerProduct;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.time.LocalDate;
import java.util.Date;
import java.util.List;
@Data
public class AfterSalesLedgerDto {
    private Long id;
    private Long salesLedgerId;
    private Long salesLedgerProductId;
    private String salesContractNo;
    private String customerContractNo;
    private String projectName;
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date entryDate;
    private String entryDateStart;
    private String entryDateEnd;
    private String salesman;
    private Long customerId;
    private String customerName;
    private String entryPerson;
    private String remarks;
    private String attachmentMaterials;
    @TableField(exist = false)
    @JsonFormat(pattern = "yyyy-MM-dd")
    private LocalDate issueDate;
    @TableField(exist = false)
    private String invoiceNo;
    @TableField(exist = false)
    private String createUser;
    private Boolean hasChildren = false;
    private List<SalesLedgerProduct> productData;
    private List<SalesLedgerProductDto> productDtoData;
    private List<String> tempFileIds;
    private List<CommonFile> SalesLedgerFiles;
    private String type;
    @ApiModelProperty(value = "签订日期")
    private LocalDate executionDate;
    private String status;
    @ApiModelProperty(value = "付款方式")
    private String paymentMethod;
    @ApiModelProperty(value = "交货日期")
    private LocalDate deliveryDate;
}
src/main/java/com/ruoyi/sales/mapper/SalesLedgerMapper.java
@@ -6,6 +6,7 @@
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.home.dto.IncomeExpenseAnalysisDto;
import com.ruoyi.sales.dto.AfterSalesLedgerDto;
import com.ruoyi.sales.dto.SalesLedgerDto;
import com.ruoyi.sales.dto.SalesTrendDto;
import com.ruoyi.sales.dto.StatisticsTableDto;
@@ -84,5 +85,5 @@
            "</script>")
    List<SalesTrendDto> statisticsTable(@Param("statisticsTableDto")StatisticsTableDto statisticsTableDto);
    IPage<SalesLedgerDto> listSalesLedgerAndShipped(Page page, @Param("ew") SalesLedgerDto salesLedgerDto);
    IPage<AfterSalesLedgerDto> listSalesLedgerAndShipped(Page page, @Param("ew") AfterSalesLedgerDto salesLedgerDto);
}
src/main/java/com/ruoyi/sales/service/ISalesLedgerService.java
@@ -6,6 +6,7 @@
import com.ruoyi.aftersalesservice.pojo.AfterSalesService;
import com.ruoyi.common.enums.SaleEnum;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.sales.dto.AfterSalesLedgerDto;
import com.ruoyi.sales.dto.LossProductModelDto;
import com.ruoyi.sales.dto.MonthlyAmountDto;
import com.ruoyi.sales.dto.SalesLedgerDto;
@@ -53,7 +54,7 @@
    List<LossProductModelDto> getSalesLedgerWithProductsLoss(Long salesLedgerId);
    IPage<SalesLedgerDto> listSalesLedger(SalesLedgerDto salesLedgerDto, Page page);
    IPage<AfterSalesLedgerDto> listSalesLedger(AfterSalesLedgerDto salesLedgerDto, Page page);
    SalesLedgerDto getSalesByCode(SalesLedgerDto salesLedgerDto);
}
src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
@@ -498,14 +498,10 @@
    }
    @Override
    public IPage<SalesLedgerDto> listSalesLedger(SalesLedgerDto salesLedgerDto, Page page) {
        IPage<SalesLedgerDto> salesLedgerDtoIPage = salesLedgerMapper.listSalesLedgerAndShipped(page, salesLedgerDto);
        for (SalesLedgerDto salesLedger : salesLedgerDtoIPage.getRecords()) {
            LambdaQueryWrapper<SalesLedgerProduct> productWrapper = new LambdaQueryWrapper<>();
            productWrapper.eq(SalesLedgerProduct::getSalesLedgerId, salesLedger.getId());
            productWrapper.eq(SalesLedgerProduct::getType, 1);
            List<SalesLedgerProduct> products = salesLedgerProductMapper.selectList(productWrapper);
            for (SalesLedgerProduct product : products) {
    public IPage<AfterSalesLedgerDto> listSalesLedger(AfterSalesLedgerDto salesLedgerDto, Page page) {
        IPage<AfterSalesLedgerDto> salesLedgerDtoIPage = salesLedgerMapper.listSalesLedgerAndShipped(page, salesLedgerDto);
        for (AfterSalesLedgerDto salesLedger : salesLedgerDtoIPage.getRecords()) {
            SalesLedgerProduct product = salesLedgerProductMapper.selectById(salesLedger.getSalesLedgerProductId());
                product.setOriginalNoInvoiceNum(product.getNoInvoiceNum());
                // æä¾›ä¸´æ—¶æœªå¼€ç¥¨æ•°ï¼Œæœªå¼€ç¥¨é‡‘额供前段计算
                product.setTempnoInvoiceAmount(product.getNoInvoiceAmount());
@@ -522,16 +518,10 @@
                if (shippingInfo != null) {
                    product.setShippingStatus(shippingInfo.getStatus());
                }
            List<SalesLedgerProduct> afterSalesLedgerDtos = new ArrayList<>();
            afterSalesLedgerDtos.add(product);
            salesLedger.setProductData(afterSalesLedgerDtos);
            }
            // è¿‡æ»¤åªä¿ç•™å‘货记录
            products = products.stream().filter(product -> "已发货".equals(product.getShippingStatus())).collect(Collectors.toList());
            if (!products.isEmpty()) {
                salesLedger.setHasChildren(true);
                salesLedger.setProductData(products);
            }
        }
        return salesLedgerDtoIPage;
    }
src/main/resources/mapper/sales/SalesLedgerMapper.xml
@@ -118,11 +118,15 @@
        FROM sales_ledger
        GROUP BY customer_name
    </select>
    <select id="listSalesLedgerAndShipped" resultType="com.ruoyi.sales.dto.SalesLedgerDto">
        select distinct sl.id as 'disId', sl.* from
        sales_ledger sl
        left join sales_ledger_product slp on sl.id = slp.sales_ledger_id
        left join shipping_info si on slp.id = si.sales_ledger_product_id
    <select id="listSalesLedgerAndShipped" resultType="com.ruoyi.sales.dto.AfterSalesLedgerDto">
        select
        si.*,sl.sales_contract_no,sl.customer_contract_no,
        sl.project_name,sl.entry_date,sl.salesman,sl.customer_id,sl.customer_name,
        sl.entry_person,sl.remarks,sl.attachment_materials,sl.tenant_id,
        sl.contract_amount,sl.execution_date,sl.payment_method,sl.delivery_date
        from shipping_info si
        left join sales_ledger_product slp on slp.id = si.sales_ledger_product_id
        left join sales_ledger sl on sl.id = slp.sales_ledger_id
        where si.status = '已发货'
        <if test="ew.customerName != null and ew.customerName != '' ">
            and sl.customer_name like concat('%',#{ew.customerName},'%')