gongchunyi
5 天以前 4277ab30de3fedfd5bea68bfa0e111e21df73839
feat: 打印流程卡与获取销售订单绑定的工艺路线
已添加2个文件
已修改6个文件
395 ■■■■■ 文件已修改
src/main/java/com/ruoyi/sales/controller/SalesLedgerController.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/dto/SalesLedgerProcessRouteDto.java 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/dto/SalesProcessCardDto.java 106 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/mapper/SalesLedgerMapper.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/pojo/SalesLedgerProcessRoute.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/service/ISalesLedgerService.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java 183 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/sales/SalesLedgerMapper.xml 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/controller/SalesLedgerController.java
@@ -13,6 +13,8 @@
import com.ruoyi.framework.web.page.TableDataInfo;
import com.ruoyi.sales.dto.InvoiceLedgerDto;
import com.ruoyi.sales.dto.SalesLedgerDto;
import com.ruoyi.sales.dto.SalesLedgerProcessRouteDto;
import com.ruoyi.sales.dto.SalesProcessCardDto;
import com.ruoyi.sales.mapper.InvoiceLedgerMapper;
import com.ruoyi.sales.mapper.ReceiptPaymentMapper;
import com.ruoyi.sales.pojo.ReceiptPayment;
@@ -360,4 +362,19 @@
    public R getSalesLedgerWithProductsLoss(Long salesLedgerId) {
        return R.ok(salesLedgerService.getSalesLedgerWithProductsLoss(salesLedgerId));
    }
    @ApiOperation("获取销售订单绑定的工艺路线")
    @GetMapping("/salesProcess/{salesLedgerId}")
    public AjaxResult salesProcess(@PathVariable Long salesLedgerId) {
        SalesLedgerProcessRouteDto dto = salesLedgerService.salesProcess(salesLedgerId);
        return AjaxResult.success(dto);
    }
    @GetMapping("/processCard/{salesLedgerId}")
    @ApiOperation("打印生产流程卡")
    public AjaxResult processCard(@PathVariable Long salesLedgerId) {
        SalesProcessCardDto dto = salesLedgerService.processCard(salesLedgerId);
        return AjaxResult.success(dto);
    }
}
src/main/java/com/ruoyi/sales/dto/SalesLedgerProcessRouteDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,32 @@
package com.ruoyi.sales.dto;
import com.ruoyi.sales.pojo.SalesLedgerProcessRoute;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.List;
/**
 * <br>
 * é”€å”®è®¢å•绑定的工艺路线Dto
 * </br>
 *
 * @author deslrey
 * @version 1.0
 * @since 2026/03/27 9:54
 */
@Data
@EqualsAndHashCode(callSuper = false)
public class SalesLedgerProcessRouteDto extends SalesLedgerProcessRoute {
    @ApiModelProperty("工艺路线ID")
    private Long routeId;
    @ApiModelProperty(value = "路线名称")
    private String routeName;
    @ApiModelProperty("销售订单绑定的工艺路线")
    List<SalesLedgerProcessRoute> list;
}
src/main/java/com/ruoyi/sales/dto/SalesProcessCardDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,106 @@
package com.ruoyi.sales.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
/**
 * é”€å”®è®¢å•流程卡 DTO
 * æ•´åˆäº†å°è´¦ä¿¡æ¯ã€äº§å“åˆ—表以及绑定的工艺路线
 *
 * @author deslrey
 * @version 1.0
 * @since 2026/03/26
 */
@Data
public class SalesProcessCardDto {
    @ApiModelProperty("订单编号")
    private String salesContractNo;
    @ApiModelProperty("客户名称")
    private String customerName;
    @ApiModelProperty("交货日期")
    @JsonFormat(pattern = "yyyy-MM-dd")
    private LocalDate deliveryDate;
    @ApiModelProperty("工艺路线总览")
    private String processPathDisplay;
    @ApiModelProperty("订单加工要求")
    private String orderProcessRequirement;
    @ApiModelProperty("该绑定的工艺路线节点")
    private List<ProcessNodeDto> routeNodes;
    @ApiModelProperty("流程卡行明细")
    private List<ProcessCardItemDto> items;
    //  åº•部信息
    @ApiModelProperty("总合计数量")
    private BigDecimal totalQuantity;
    @ApiModelProperty("总合计面积")
    private BigDecimal totalArea;
    @ApiModelProperty("制单员")
    private String register;
    @ApiModelProperty("制单日期")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime registerDate;
    /**
     * å†…部类:对应产品表格行
     */
    @Data
    public static class ProcessCardItemDto {
        @ApiModelProperty("楼层编号")
        private String floorCode;
        @ApiModelProperty("产品描述")
        private String productDescription;
        @ApiModelProperty("宽(弧长)")
        private BigDecimal width;
        @ApiModelProperty("高")
        private BigDecimal height;
        @ApiModelProperty("数量")
        private BigDecimal quantity;
        @ApiModelProperty("面积(㎡)")
        private BigDecimal area;
        @ApiModelProperty("明细加工要求")
        private String processRequirement;
        @ApiModelProperty("额外加工明细")
        private List<String> extraProcesses;
    }
    /**
     * å†…部类:对应 SalesLedgerProcessRoute çš„节点信息
     */
    @Data
    public static class ProcessNodeDto {
        @ApiModelProperty("工艺节点ID")
        private Long processRouteItemId;
        @ApiModelProperty("工艺节点名称")
        private String processRouteItemName;
        @ApiModelProperty("排序号")
        private Integer dragSort;
        @ApiModelProperty("备注")
        private String remark;
    }
}
src/main/java/com/ruoyi/sales/mapper/SalesLedgerMapper.java
@@ -10,6 +10,7 @@
import com.ruoyi.sales.dto.SalesTrendDto;
import com.ruoyi.sales.dto.StatisticsTableDto;
import com.ruoyi.sales.pojo.SalesLedger;
import com.ruoyi.sales.pojo.SalesLedgerProcessRoute;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
@@ -85,4 +86,7 @@
    List<SalesTrendDto> statisticsTable(@Param("statisticsTableDto")StatisticsTableDto statisticsTableDto);
    IPage<SalesLedgerDto> listSalesLedgerAndShipped(Page page, @Param("ew") SalesLedgerDto salesLedgerDto);
    List<SalesLedgerProcessRoute> selectSalesProcess(Long salesLedgerId);
}
src/main/java/com/ruoyi/sales/pojo/SalesLedgerProcessRoute.java
@@ -55,5 +55,8 @@
    @TableField(fill = FieldFill.INSERT)
    private Long tenantId;
    @TableField(exist = false)
    @ApiModelProperty(value = "工序名称")
    private String processName;
}
src/main/java/com/ruoyi/sales/service/ISalesLedgerService.java
@@ -6,9 +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.LossProductModelDto;
import com.ruoyi.sales.dto.MonthlyAmountDto;
import com.ruoyi.sales.dto.SalesLedgerDto;
import com.ruoyi.sales.dto.*;
import com.ruoyi.sales.pojo.SalesLedger;
import com.ruoyi.sales.pojo.SalesLedgerProcessRoute;
import com.ruoyi.sales.pojo.SalesLedgerProduct;
@@ -57,4 +55,8 @@
    IPage<SalesLedgerDto> listSalesLedger(SalesLedgerDto salesLedgerDto, Page page);
    void saleProcessBind(SalesLedgerProcessRoute salesLedgerProcessRoute);
    SalesProcessCardDto processCard(Long salesLedgerId);
    SalesLedgerProcessRouteDto salesProcess(Long salesLedgerId);
}
src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
@@ -4,7 +4,7 @@
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@@ -30,7 +30,7 @@
import com.ruoyi.production.pojo.ProcessRoute;
import com.ruoyi.production.pojo.ProcessRouteItem;
import com.ruoyi.production.service.ProductionProductMainService;
import com.ruoyi.project.system.domain.SysDept;
import com.ruoyi.project.system.domain.SysUser;
import com.ruoyi.project.system.mapper.SysDeptMapper;
import com.ruoyi.project.system.mapper.SysUserMapper;
@@ -543,7 +543,7 @@
            throw new ServiceException("绑定失败,工艺路线不存在");
        }
        //  æ¸…除已绑定的数据
        salesLedgerProcessRouteService.remove(new LambdaQueryWrapper<SalesLedgerProcessRoute>().eq(SalesLedgerProcessRoute::getSalesLedgerId, salesLedger.getId()).eq(SalesLedgerProcessRoute::getProcessRouteId, processRoute.getId()));
        salesLedgerProcessRouteService.remove(new LambdaQueryWrapper<SalesLedgerProcessRoute>().eq(SalesLedgerProcessRoute::getSalesLedgerId, salesLedger.getId()));
        //  å°†æ•°æ®è¿ç§»åˆ°sales_ledger_process_route
        List<ProcessRouteItem> routeItems = processRouteItemMapper.selectList(new LambdaQueryWrapper<ProcessRouteItem>().eq(ProcessRouteItem::getRouteId, processRoute.getId()));
@@ -554,6 +554,7 @@
            ledgerProcessRoute.setProcessRouteId(processRoute.getId());
            ledgerProcessRoute.setSalesLedgerId(salesLedger.getId());
            ledgerProcessRoute.setProcessRouteItemId(routeItem.getId());
            ledgerProcessRoute.setDragSort(routeItem.getDragSort());
            salesLedgerProcessRouteList.add(ledgerProcessRoute);
        }
        salesLedgerProcessRouteService.saveBatch(salesLedgerProcessRouteList);
@@ -844,19 +845,20 @@
                }
            }
            if (!redisTemplate.hasKey(lockKey)) {
            if (Boolean.FALSE.equals(redisTemplate.hasKey(lockKey))) {
                throw new RuntimeException("获取合同编号生成锁失败:超时");
            }
            // 2. æŸ¥è¯¢å½“天/公司已存在的序列号(与原逻辑一致)
            Long tenantId = SecurityUtils.getLoginUser().getTenantId();
            if (null != tenantId) {
                //获取公司编号
                SysDept sysDept = sysDeptMapper.selectDeptById(tenantId.longValue());
                if (!ObjectUtils.isEmpty(sysDept)) {
                    datePart = (StringUtils.isEmpty(sysDept.getDeptNick()) ? "" : sysDept.getDeptNick()) + datePart;
                }
            }
//            Long tenantId = SecurityUtils.getLoginUser().getTenantId();
//            if (null != tenantId) {
//                //获取公司编号
//                SysDept sysDept = sysDeptMapper.selectDeptById(tenantId);
//                if (!ObjectUtils.isEmpty(sysDept)) {
//                    datePart = (StringUtils.isEmpty(sysDept.getDeptNick()) ? "" : sysDept.getDeptNick()) + datePart;
//                }
//            }
            datePart = "D" + datePart;
            List<Integer> existingSequences = salesLedgerMapper.selectSequencesByDate(datePart);
            int nextSequence = findFirstMissingSequence(existingSequences);
@@ -872,6 +874,163 @@
        }
    }
    @Override
    public SalesLedgerProcessRouteDto salesProcess(Long salesLedgerId) {
        SalesLedgerProcessRouteDto dto = new SalesLedgerProcessRouteDto();
        List<SalesLedgerProcessRoute> list = baseMapper.selectSalesProcess(salesLedgerId);
        if (CollectionUtils.isNotEmpty(list)) {
            Long processRouteId = list.get(0).getProcessRouteId();
            ProcessRoute processRoute = processRouteMapper.selectById(processRouteId);
            if (processRoute != null) {
                dto.setRouteId(processRoute.getId());
                dto.setRouteName(processRoute.getProcessRouteName());
            }
        } else {
            //  è¦æ˜¯list查询为空的话,就查询默认的工艺路线返回
            ProcessRoute defaultRoute = processRouteMapper.selectOne(new LambdaQueryWrapper<ProcessRoute>().eq(ProcessRoute::getIsDefault, 1).last("limit 1"));
            if (defaultRoute != null) {
                dto.setRouteId(defaultRoute.getId());
                dto.setRouteName(defaultRoute.getProcessRouteName());
                List<ProcessRouteItem> routeItems = processRouteItemMapper.selectList(new LambdaQueryWrapper<ProcessRouteItem>().eq(ProcessRouteItem::getRouteId, defaultRoute.getId()).orderByAsc(ProcessRouteItem::getDragSort));
                list = routeItems.stream().map(item -> {
                    SalesLedgerProcessRoute salesLedgerProcessRoute = new SalesLedgerProcessRoute();
                    salesLedgerProcessRoute.setProcessRouteId(defaultRoute.getId());
                    salesLedgerProcessRoute.setSalesLedgerId(salesLedgerId);
                    salesLedgerProcessRoute.setProcessRouteItemId(item.getId());
                    salesLedgerProcessRoute.setProcessName(item.getProcessName());
                    salesLedgerProcessRoute.setDragSort(item.getDragSort());
                    return salesLedgerProcessRoute;
                }).collect(Collectors.toList());
            }
        }
        dto.setList(list);
        return dto;
    }
    @Override
    public SalesProcessCardDto processCard(Long salesLedgerId) {
        if (salesLedgerId == null) {
            throw new ServiceException("流程卡打印失败,打印销售订单不能为空");
        }
        //  æŸ¥è¯¢é”€å”®è®¢å•
        SalesLedger salesLedger = baseMapper.selectById(salesLedgerId);
        if (salesLedger == null) {
            throw new ServiceException("流程卡打印失败,销售订单不存在");
        }
        SalesProcessCardDto dto = new SalesProcessCardDto();
        dto.setSalesContractNo(salesLedger.getSalesContractNo());
        dto.setCustomerName(salesLedger.getCustomerName());
        dto.setDeliveryDate(salesLedger.getDeliveryDate());
        dto.setRegister(SecurityUtils.getLoginUser().getUser().getNickName());
        dto.setRegisterDate(LocalDateTime.now());
        dto.setOrderProcessRequirement(salesLedger.getRemarks());
        //  æŸ¥è¯¢äº§å“åˆ—表
        List<SalesLedgerProduct> products = salesLedgerProductMapper.selectList(
                new LambdaQueryWrapper<SalesLedgerProduct>().eq(SalesLedgerProduct::getSalesLedgerId, salesLedgerId));
        BigDecimal totalQuantity = BigDecimal.ZERO;
        BigDecimal totalArea = BigDecimal.ZERO;
        List<SalesProcessCardDto.ProcessCardItemDto> itemDtos = new ArrayList<>();
        for (SalesLedgerProduct p : products) {
            SalesProcessCardDto.ProcessCardItemDto itemDto = new SalesProcessCardDto.ProcessCardItemDto();
            itemDto.setFloorCode(p.getFloorCode());
            // ç»„装产品描述:大类 + (规格)
            String desc = (p.getProductCategory() != null ? p.getProductCategory() : "") +
                    (StringUtils.isNotBlank(p.getSpecificationModel()) ? " " + p.getSpecificationModel() : "");
            itemDto.setProductDescription(desc.trim());
            itemDto.setWidth(p.getWidth());
            itemDto.setHeight(p.getHeight());
            itemDto.setQuantity(p.getQuantity());
            // é¢ç§¯è®¡ç®—(平米)
            BigDecimal area = p.getActualPieceArea() != null ? p.getActualPieceArea() : p.getSettlePieceArea();
            if (area == null && p.getWidth() != null && p.getHeight() != null) {
                area = p.getWidth().multiply(p.getHeight()).divide(new BigDecimal(1000000), 2, RoundingMode.HALF_UP);
            }
            itemDto.setArea(area);
            itemDto.setProcessRequirement(p.getProcessRequirement());
            BigDecimal qty = p.getQuantity() != null ? p.getQuantity() : BigDecimal.ZERO;
            totalQuantity = totalQuantity.add(qty);
            if (area != null) {
                totalArea = totalArea.add(area.multiply(qty));
            }
            itemDtos.add(itemDto);
        }
        dto.setItems(itemDtos);
        dto.setTotalQuantity(totalQuantity);
        dto.setTotalArea(totalArea.setScale(2, RoundingMode.HALF_UP));
        //  å·¥è‰ºè·¯çº¿
        List<SalesLedgerProcessRoute> salesLedgerProcessRoutes = salesLedgerProcessRouteService.list(
                new LambdaQueryWrapper<SalesLedgerProcessRoute>()
                        .eq(SalesLedgerProcessRoute::getSalesLedgerId, salesLedgerId)
                        .orderByAsc(SalesLedgerProcessRoute::getDragSort));
        List<SalesProcessCardDto.ProcessNodeDto> nodeDtos = new ArrayList<>();
        if (CollectionUtils.isEmpty(salesLedgerProcessRoutes)) {
            // æ— è‡ªå®šä¹‰è·¯çº¿ï¼Œå–默认路线
            ProcessRoute defaultRoute = processRouteMapper.selectOne(
                    new LambdaQueryWrapper<ProcessRoute>().eq(ProcessRoute::getIsDefault, 1).last("LIMIT 1"));
            if (defaultRoute != null) {
                List<ProcessRouteItem> routeItems = processRouteItemMapper.selectList(
                        new LambdaQueryWrapper<ProcessRouteItem>()
                                .eq(ProcessRouteItem::getRouteId, defaultRoute.getId())
                                .orderByAsc(ProcessRouteItem::getDragSort));
                for (ProcessRouteItem i : routeItems) {
                    SalesProcessCardDto.ProcessNodeDto node = new SalesProcessCardDto.ProcessNodeDto();
                    node.setProcessRouteItemId(i.getId());
                    node.setProcessRouteItemName(i.getProcessName());
                    node.setDragSort(i.getDragSort());
                    nodeDtos.add(node);
                }
            }
        } else {
            // ä½¿ç”¨è‡ªå®šä¹‰è·¯çº¿ç»‘定的节点
            List<Long> itemIds = salesLedgerProcessRoutes.stream()
                    .map(SalesLedgerProcessRoute::getProcessRouteItemId)
                    .collect(Collectors.toList());
            List<ProcessRouteItem> rawItems = processRouteItemMapper.selectBatchIds(itemIds);
            Map<Long, ProcessRouteItem> itemMap = rawItems.stream()
                    .collect(Collectors.toMap(ProcessRouteItem::getId, i -> i, (a, b) -> a));
            for (SalesLedgerProcessRoute r : salesLedgerProcessRoutes) {
                ProcessRouteItem pi = itemMap.get(r.getProcessRouteItemId());
                if (pi != null) {
                    SalesProcessCardDto.ProcessNodeDto node = new SalesProcessCardDto.ProcessNodeDto();
                    node.setProcessRouteItemId(pi.getId());
                    node.setProcessRouteItemName(pi.getProcessName());
                    node.setDragSort(r.getDragSort() != null ? r.getDragSort() : pi.getDragSort());
                    node.setRemark(r.getRemark());
                    nodeDtos.add(node);
                }
            }
        }
        if (!nodeDtos.isEmpty()) {
            //  dragSort è¿›è¡Œå‡åºæŽ’序
            nodeDtos.sort(Comparator.comparing(
                    SalesProcessCardDto.ProcessNodeDto::getDragSort,
                    Comparator.nullsLast(Comparator.naturalOrder())
            ));
            //  é‡æ–°ç”ŸæˆæŽ’序后的路径名称列表
            List<String> sortedPathNames = nodeDtos.stream()
                    .map(SalesProcessCardDto.ProcessNodeDto::getProcessRouteItemName)
                    .collect(Collectors.toList());
            //  æ‹¼æŽ¥å­—符串
            dto.setProcessPathDisplay(String.join(" -> ", sortedPathNames));
            // è®¾ç½®é¡¶å±‚节点的工艺路线
            dto.setRouteNodes(nodeDtos);
        }
        return dto;
    }
    private int findFirstMissingSequence(List<Integer> sequences) {
        if (sequences.isEmpty()) {
            return 1;
src/main/resources/mapper/sales/SalesLedgerMapper.xml
@@ -5,12 +5,12 @@
<mapper namespace="com.ruoyi.sales.mapper.SalesLedgerMapper">
    <select id="selectSequencesByDate" resultType="java.lang.Integer">
        SELECT CAST(SUBSTR(sales_contract_no,LENGTH(#{datePart})+1 , 3) AS SIGNED)
        SELECT CAST(SUBSTR(sales_contract_no, LENGTH(#{datePart}) + 1, 3) AS SIGNED)
        FROM sales_ledger
        WHERE sales_contract_no LIKE CONCAT('%',#{datePart},'%')
        WHERE sales_contract_no LIKE CONCAT('%', #{datePart}, '%')
    </select>
    <select id="getSalesNo" resultType="com.ruoyi.sales.pojo.SalesLedger">
    </select>
    <select id="selectSalesLedgerList" resultType="com.ruoyi.sales.pojo.SalesLedger">
@@ -56,9 +56,9 @@
        T1.attachment_materials,
        T1.tenant_id,
        T1.contract_amount,
        T1.contract_amount                    as noInvoiceAmountTotal,
        T1.contract_amount as noInvoiceAmountTotal,
        T1.execution_date,
        T2.nick_name                          AS entry_person_name,
        T2.nick_name AS entry_person_name,
        T1.payment_method,
        T1.delivery_date,
        DATEDIFF(T1.delivery_date, CURDATE()) AS delivery_days_diff,
@@ -78,25 +78,25 @@
        ) shipping_status_counts ON T1.id = shipping_status_counts.sales_ledger_id
        <where>
            <if test="salesLedgerDto.customerName != null and salesLedgerDto.customerName != '' ">
                AND  T1.customer_name LIKE CONCAT('%',#{salesLedgerDto.customerName},'%')
                AND T1.customer_name LIKE CONCAT('%',#{salesLedgerDto.customerName},'%')
            </if>
            <if test="salesLedgerDto.customerContractNo != null and salesLedgerDto.customerContractNo !='' ">
                AND  T1.customer_contract_no LIKE CONCAT('%',#{salesLedgerDto.customerContractNo},'%')
                AND T1.customer_contract_no LIKE CONCAT('%',#{salesLedgerDto.customerContractNo},'%')
            </if>
            <if test="salesLedgerDto.salesContractNo != null and salesLedgerDto.salesContractNo != '' ">
                AND  T1.sales_contract_no LIKE CONCAT('%',#{salesLedgerDto.salesContractNo},'%')
                AND T1.sales_contract_no LIKE CONCAT('%',#{salesLedgerDto.salesContractNo},'%')
            </if>
            <if test="salesLedgerDto.projectName != null and salesLedgerDto.projectName != '' ">
                AND T1.project_name LIKE CONCAT('%',#{salesLedgerDto.projectName},'%')
            </if>
            <if test="salesLedgerDto.entryDateStart != null and salesLedgerDto.entryDateStart != '' ">
               AND T1.entry_date &gt;= DATE_FORMAT(#{salesLedgerDto.entryDateStart},'%Y-%m-%d')
                AND T1.entry_date &gt;= DATE_FORMAT(#{salesLedgerDto.entryDateStart},'%Y-%m-%d')
            </if>
            <if test="salesLedgerDto.entryDateEnd != null and salesLedgerDto.entryDateEnd != '' ">
                AND  T1.entry_date &lt;= DATE_FORMAT(#{salesLedgerDto.entryDateEnd},'%Y-%m-%d')
                AND T1.entry_date &lt;= DATE_FORMAT(#{salesLedgerDto.entryDateEnd},'%Y-%m-%d')
            </if>
        </where>
    order by T1.entry_date desc
        order by T1.entry_date desc
    </select>
    <select id="selectIncomeStats" resultType="com.ruoyi.home.dto.IncomeExpenseAnalysisDto">
@@ -117,10 +117,26 @@
        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
        where si.status = '已发货'
            <if test="ew.customerName != null and ew.customerName != '' ">
        <if test="ew.customerName != null and ew.customerName != '' ">
            and sl.customer_name like concat('%',#{ew.customerName},'%')
            </if>
        </if>
        order by sl.execution_date desc
    </select>
    <select id="selectSalesProcess" resultType="com.ruoyi.sales.pojo.SalesLedgerProcessRoute"
            parameterType="java.lang.Long">
        select slpr.*,
        pri.process_name as processName
        from sales_ledger_process_route slpr
        left join process_route_item pri on pri.id = slpr.process_route_item_id
        <where>
            <if test="salesLedgerId != null">
                AND slpr.sales_ledger_id = #{salesLedgerId}
            </if>
            <if test="salesLedgerId == null">
                AND 1 = 2
            </if>
        </where>
    </select>
</mapper>