yys1.协同办公:关闭签字功能,除报销管理外,关闭其余附件功能。
2.营销管理:关闭销售台账附件功能。
3.仓储物料:需增加成品入库
4.生产管控:生产派工需要新增派工产线及生产人
5.设备管理:设备台账关闭设备品牌和存放位置
已添加7个文件
已修改13个文件
717 ■■■■■ 文件已修改
src/main/java/com/ruoyi/production/controller/ProductionLineController.java 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/dto/ProductionDispatchAddDto.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/dto/SalesLedgerSchedulingDto.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/dto/SalesLedgerSchedulingProcessDto.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/dto/SalesLedgerWorkDto.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/mapper/ProductionLineMapper.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/pojo/ProductionLine.java 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/pojo/SalesLedgerScheduling.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/pojo/SalesLedgerWork.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/ProductionLineService.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/impl/ProductionLineServiceImpl.java 99 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/impl/SalesLedgerProductionAccountingServiceImpl.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/impl/SalesLedgerSchedulingServiceImpl.java 95 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/impl/SalesLedgerWorkServiceImpl.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application-trsw.yml 219 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application.yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/production/ProductionLineMapper.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/production/SalesLedgerProductionAccountingMapper.xml 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/production/SalesLedgerSchedulingMapper.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/production/SalesLedgerWorkMapper.xml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/controller/ProductionLineController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,71 @@
package com.ruoyi.production.controller;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
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.production.pojo.ProductionLine;
import com.ruoyi.production.service.ProductionLineService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
 * @author :yys
 * @date : 2025/12/4 11:19
 */
@RestController
@Api(tags = "产线管理")
@RequestMapping("/productionLine")
public class ProductionLineController extends BaseController {
    @Autowired
    private ProductionLineService productionLineService;
    /**
     * é€’归查询产线树
     */
    @GetMapping("/listTree")
    @ApiOperation(value = "递归查询产线树")
    public AjaxResult listTree() {
        List<ProductionLine> productionLines = productionLineService.listTree();
        return AjaxResult.success(productionLines);
    }
    /**
     * åˆ†é¡µ-根据父节点ID查询子树(如查询ID=1的产线下的所有工序)
     */
    @GetMapping("/pageList")
    @ApiOperation(value = "分页-根据父节点ID查询子树")
    public AjaxResult getSubTree(Page page, ProductionLine productionLine) {
        return AjaxResult.success(productionLineService.getSubTreeByParentId(page ,productionLine));
    }
    @PostMapping("/add")
    @ApiOperation(value = "添加产线")
    @Log(title = "产线管理", businessType = BusinessType.INSERT)
    public AjaxResult add(@RequestBody ProductionLine productionLine) {
        return AjaxResult.success(productionLineService.save(productionLine));
    }
    @PostMapping("/update")
    @ApiOperation(value = "修改产线")
    @Log(title = "产线管理", businessType = BusinessType.UPDATE)
    public AjaxResult update(@RequestBody ProductionLine productionLine) {
        return AjaxResult.success(productionLineService.updateById(productionLine));
    }
    @DeleteMapping("/delete")
    @ApiOperation(value = "删除产线")
    @Log(title = "产线管理", businessType = BusinessType.DELETE)
    public AjaxResult delete(@RequestBody List<Long> ids) {
        if(CollectionUtils.isEmpty(ids)) return AjaxResult.error("请传入要删除的ID");
        return AjaxResult.success(productionLineService.removeBatchByIds(ids));
    }
}
src/main/java/com/ruoyi/production/dto/ProductionDispatchAddDto.java
@@ -34,6 +34,18 @@
    private Long schedulingUserId;
    /**
     * ç”Ÿäº§äºº
     */
    @ApiModelProperty(value = "生产人")
    private Long productionUserId;
    /**
     * äº§çº¿id
     */
    @ApiModelProperty(value = "产线id")
    private Long lineId;
    /**
     * æŽ’产日期
     */
    @ApiModelProperty(value = "排产日期")
src/main/java/com/ruoyi/production/dto/SalesLedgerSchedulingDto.java
@@ -128,4 +128,8 @@
    @ApiModelProperty(value = "租户ID")
    private Long tenantId;
    private Long productionUserId;
    private String productionUserName;
}
src/main/java/com/ruoyi/production/dto/SalesLedgerSchedulingProcessDto.java
@@ -125,6 +125,31 @@
    private Long schedulingUserId;
    /**
     * ç”Ÿäº§äººid
     */
    @ApiModelProperty(value = "生产人id")
    private Long productionUserId;
    /**
     * ç”Ÿäº§äººåç§°
     */
    @Excel(name = "生产人名称")
    @ApiModelProperty(value = "生产人名称")
    private String productionUserName;
    /**
     * ç”Ÿäº§äº§çº¿
     */
    @Excel(name = "生产产线")
    @ApiModelProperty(value = "生产产线")
    private String productionLineName;
    @ApiModelProperty(value = "生产产线id")
    private Long productionLineId;
    /**
     * æŽ’产数量
     */
src/main/java/com/ruoyi/production/dto/SalesLedgerWorkDto.java
@@ -24,6 +24,9 @@
    @ApiModelProperty(value = "排产人id")
    private Long schedulingUserId;
    @ApiModelProperty(value = "生产人id")
    private Long productionUserId;
    /**
     * æŽ’产人名称
     */
src/main/java/com/ruoyi/production/mapper/ProductionLineMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,11 @@
package com.ruoyi.production.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.production.pojo.ProductionLine;
/**
 * @author :yys
 * @date : 2025/12/4 11:17
 */
public interface ProductionLineMapper extends BaseMapper<ProductionLine> {
}
src/main/java/com/ruoyi/production/pojo/ProductionLine.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,92 @@
package com.ruoyi.production.pojo;
import com.baomidou.mybatisplus.annotation.*;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
/**
 * @author :yys
 * @date : 2025/12/4 11:13
 */
@Data
@TableName("production_line")
public class ProductionLine {
    private static final long serialVersionUID = 1L;
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    /**
     * åç§°
     */
    @ApiModelProperty("名称")
    private String name;
    /**
     * çˆ¶çº§id
     */
    @ApiModelProperty("父级id")
    private Integer parentId;
    /**
     * ç±»åž‹ 1-产线 2-工序
     */
    @ApiModelProperty("类型 1-产线 2-工序")
    private Integer type;
    /**
     * æŽ’序
     */
    @ApiModelProperty("排序")
    private Integer sort;
    /**
     * å¤‡æ³¨
     */
    @ApiModelProperty("备注")
    private String remark;
    /**
     * å­æ•°æ®
     */
    @TableField(exist = false)
    @ApiModelProperty("子数据")
    private List<ProductionLine> children;
    /**
     * åˆ›å»ºè€…
     */
    @TableField(fill = FieldFill.INSERT)
    private Integer createUser;
    /**
     * åˆ›å»ºæ—¶é—´
     */
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    /**
     * ä¿®æ”¹è€…
     */
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Integer updateUser;
    /**
     * ä¿®æ”¹æ—¶é—´
     */
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
    /**
     * ç§Ÿæˆ·ID
     */
    @TableField(fill = FieldFill.INSERT)
    private Long tenantId;
}
src/main/java/com/ruoyi/production/pojo/SalesLedgerScheduling.java
@@ -39,6 +39,22 @@
    private Long schedulingUserId;
    /**
     * ç”Ÿäº§äº§çº¿id
     */
    private Long productionLineId;
    /**
     * ç”Ÿäº§äººid
     */
    private Long productionUserId;
    /**
     * ç”Ÿäº§äººåç§°
     */
    private String productionUserName;
    /**
     * ç”Ÿäº§ç‚’机
     */
    private String speculativeTradingName;
src/main/java/com/ruoyi/production/pojo/SalesLedgerWork.java
@@ -48,6 +48,18 @@
    private String schedulingUserName;
    /**
     * ç”Ÿäº§äººid
     */
    private Long productionUserId;
    /**
     * ç”Ÿäº§äººåç§°
     */
    private String productionUserName;
    /**
     * æŽ’产数量
     */
src/main/java/com/ruoyi/production/service/ProductionLineService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,28 @@
package com.ruoyi.production.service;
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.production.pojo.ProductionLine;
import java.util.List;
/**
 * @author :yys
 * @date : 2025/12/4 11:18
 */
public interface ProductionLineService extends IService<ProductionLine> {
    /**
     * é€’归查询产线树
     * @return
     */
    List<ProductionLine> listTree();
    /**
     * æ ¹æ®çˆ¶èŠ‚ç‚¹ID递归查询子树
     * @param parentId çˆ¶èŠ‚ç‚¹ID
     * @return åŒ…含子节点的父节点对象
     */
    IPage<ProductionLine> getSubTreeByParentId(Page page, ProductionLine productionLine);
}
src/main/java/com/ruoyi/production/service/impl/ProductionLineServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,99 @@
package com.ruoyi.production.service.impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.production.mapper.ProductionLineMapper;
import com.ruoyi.production.pojo.ProductionLine;
import com.ruoyi.production.service.ProductionLineService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
/**
 * @author :yys
 * @date : 2025/12/4 11:19
 */
@Service
@Slf4j
public class ProductionLineServiceImpl extends ServiceImpl<ProductionLineMapper, ProductionLine> implements ProductionLineService {
    @Autowired
    private ProductionLineMapper productionLineMapper;
    /**
     * é€’归查询产线树
     * @return
     */
    @Override
    public List<ProductionLine> listTree() {
        List<ProductionLine> productionLines = productionLineMapper.selectList(Wrappers.lambdaQuery(ProductionLine.class)
                .eq(ProductionLine::getParentId, 0)
                .eq(ProductionLine::getType, 1));
        // 2. é€’归为每个根节点加载子节点(工序/子产线)
        for (ProductionLine rootLine : productionLines) {
            loadChildren(rootLine,1);
        }
        return productionLines;
    }
    /**
     * é€’归加载子节点(核心方法)
     * @param parentNode çˆ¶èŠ‚ç‚¹å¯¹è±¡
     */
    private void loadChildren(ProductionLine parentNode,Integer type) {
        // 1. æŸ¥è¯¢å½“前父节点的所有子节点
        List<ProductionLine> children = productionLineMapper.selectList(Wrappers.lambdaQuery(ProductionLine.class)
                .eq(ProductionLine::getParentId, parentNode.getId())
                .eq(ProductionLine::getType, type));
        // 2. è‹¥æœ‰å­èŠ‚ç‚¹ï¼Œç»§ç»­é€’å½’åŠ è½½å­èŠ‚ç‚¹çš„å­èŠ‚ç‚¹
        if (!children.isEmpty()) {
            parentNode.setChildren(children); // è®¾ç½®å­èŠ‚ç‚¹
            for (ProductionLine child : children) {
                loadChildren(child,type); // é€’归调用,加载孙子节点
            }
        }
    }
    /**
     * æŒ‰éœ€æä¾›ï¼šæ ¹æ®çˆ¶èŠ‚ç‚¹ID查询单个子树(如查询某个产线下的所有工序)
     */
    @Override
    public IPage<ProductionLine> getSubTreeByParentId(Page page, ProductionLine productionLine) {
        // 1. æŸ¥è¯¢çˆ¶èŠ‚ç‚¹æœ¬èº«
        ProductionLine parentNode = productionLineMapper.selectById(productionLine.getId());
        if (parentNode == null) {
            return null;
        }
        // 2. é€’归加载子节点
        loadChildren(productionLine,1);
        List<Long> ids = new ArrayList<>();
        ids.add(productionLine.getId());
        if(CollectionUtils.isNotEmpty(productionLine.getChildren())){
            // é€’归获取所有子节点的id
            getAllChildIds(productionLine,ids);
        }
        return productionLineMapper.selectPage(page, Wrappers.lambdaQuery(ProductionLine.class)
                .in(ProductionLine::getParentId, ids)
                .eq(ProductionLine::getType, 2));
    }
    /**
     * é€’归获取所有子节点的id
     */
    public List<Long> getAllChildIds(ProductionLine node,List<Long> ids) {
        if (node.getChildren() != null) {
            for (ProductionLine child : node.getChildren()) {
                ids.add(child.getId());
                ids.addAll(getAllChildIds(child,ids));
            }
        }
        return ids;
    }
}
src/main/java/com/ruoyi/production/service/impl/SalesLedgerProductionAccountingServiceImpl.java
@@ -3,6 +3,7 @@
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.common.utils.SecurityUtils;
import com.ruoyi.production.dto.SalesLedgerProductionAccountingDto;
import com.ruoyi.production.mapper.SalesLedgerProductionAccountingMapper;
import com.ruoyi.production.pojo.SalesLedgerProductionAccounting;
@@ -26,6 +27,7 @@
  
    @Override
    public IPage<SalesLedgerProductionAccountingDto> listPage(Page page, SalesLedgerProductionAccountingDto salesLedgerProductionAccountingDto) {
        salesLedgerProductionAccountingDto.setSchedulingUserId(SecurityUtils.getLoginUser().getUser().getUserId());
        IPage<SalesLedgerProductionAccountingDto> list = salesLedgerProductionAccountingMapper.listPage(page, salesLedgerProductionAccountingDto);
        list.getRecords().forEach(item -> {
            String[] split = item.getSpecificationModel().split("\\*");
src/main/java/com/ruoyi/production/service/impl/SalesLedgerSchedulingServiceImpl.java
@@ -33,6 +33,7 @@
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
@@ -57,6 +58,8 @@
    @Override
    public IPage<SalesLedgerSchedulingDto> listPage(Page page, SalesLedgerSchedulingDto salesLedgerSchedulingDto) {
        salesLedgerSchedulingDto.setProductionUserId(SecurityUtils.getLoginUser().getUser().getUserId());
        salesLedgerSchedulingDto.setProductionUserName(SecurityUtils.getLoginUser().getUser().getNickName());
        IPage<SalesLedgerSchedulingDto> list = salesLedgerSchedulingMapper.listPage(page, salesLedgerSchedulingDto);
        if(list.getTotal() == 0){
            return list;
@@ -145,52 +148,60 @@
                i++;
                continue;
            }
            // èŽ·å–ç©ºä½™ç‚’æœº
            String[] split = productionDispatchAddDto.getSpeculativeTradingName().split(",");
            if(split != null && split.length == 0){
            SysUser sysUser1 = sysUserMapper.selectUserById(productionDispatchAddDto.getProductionUserId() == null ? loginUser.getUser().getUserId() : productionDispatchAddDto.getSchedulingUserId());
            if(sysUser1 == null){
                i++;
                continue;
            }
            List<SpeculativeTradingInfo> speculativeTradingInfos = speculativeTradingInfoMapper.selectList(new LambdaQueryWrapper<SpeculativeTradingInfo>()
                    .in(SpeculativeTradingInfo::getName, Arrays.asList(split))
                    .orderByAsc(SpeculativeTradingInfo::getSort));
            if(CollectionUtils.isEmpty(speculativeTradingInfos)){
                i++;
                continue;
            }
            AtomicReference<String> name = new AtomicReference<>("");  //需要绑定的炒机
            //通过规格型号和排产数量计算本次生产产量
            String[] split1 = productionDispatchAddDto.getSpecificationModel().split("\\*");
            if(split1.length != 2){
                i++;
                continue;
            }
            // æœ¬æ¬¡ç”Ÿäº§äº§é‡
            BigDecimal productionNum = new BigDecimal(split1[0])
                    .multiply(new BigDecimal(split1[1]).multiply(productionDispatchAddDto.getSchedulingNum()));
            // å¤šä¸ªç‚’机情况
            if(speculativeTradingInfos.size() > 1){
                for (SpeculativeTradingInfo speculativeTradingInfo : speculativeTradingInfos) {
                    // èŽ·å–è¯¥ç‚’æœºæ­£åœ¨æŽ’äº§é‡
                    BigDecimal schedulingNumBySpeculativeTradingName = getSchedulingNumBySpeculativeTradingName(speculativeTradingInfo.getName());
                    // å¦‚果该炒机总量(单位kg需要乘1000) - æ­£åœ¨æŽ’产量 >=本次生产产量就分配此炒机
                    if(speculativeTradingInfo.getWorkLoad().multiply(new BigDecimal(1000)).subtract(schedulingNumBySpeculativeTradingName).compareTo(productionNum) >= 0){
                        name.set(speculativeTradingInfo.getName());
                        break;
                    }
                }
            }else{
                // å•个炒机情况
                name.set(speculativeTradingInfos.get(0).getName());
            }
            if(name.get().isEmpty()){
                i++;
                continue;
            }
//            // èŽ·å–ç©ºä½™ç‚’æœº
//            String[] split = productionDispatchAddDto.getSpeculativeTradingName().split(",");
//            if(split != null && split.length == 0){
//                i++;
//                continue;
//            }
//            List<SpeculativeTradingInfo> speculativeTradingInfos = speculativeTradingInfoMapper.selectList(new LambdaQueryWrapper<SpeculativeTradingInfo>()
//                    .in(SpeculativeTradingInfo::getName, Arrays.asList(split))
//                    .orderByAsc(SpeculativeTradingInfo::getSort));
//            if(CollectionUtils.isEmpty(speculativeTradingInfos)){
//                i++;
//                continue;
//            }
//            AtomicReference<String> name = new AtomicReference<>("");  //需要绑定的炒机
//            //通过规格型号和排产数量计算本次生产产量
//            String[] split1 = productionDispatchAddDto.getSpecificationModel().split("\\*");
//            if(split1.length != 2){
//                i++;
//                continue;
//            }
//            // æœ¬æ¬¡ç”Ÿäº§äº§é‡
//            BigDecimal productionNum = new BigDecimal(split1[0])
//                    .multiply(new BigDecimal(split1[1]).multiply(productionDispatchAddDto.getSchedulingNum()));
//            // å¤šä¸ªç‚’机情况
//            if(speculativeTradingInfos.size() > 1){
//                for (SpeculativeTradingInfo speculativeTradingInfo : speculativeTradingInfos) {
//                    // èŽ·å–è¯¥ç‚’æœºæ­£åœ¨æŽ’äº§é‡
//                    BigDecimal schedulingNumBySpeculativeTradingName = getSchedulingNumBySpeculativeTradingName(speculativeTradingInfo.getName());
//                    // å¦‚果该炒机总量(单位kg需要乘1000) - æ­£åœ¨æŽ’产量 >=本次生产产量就分配此炒机
//                    if(speculativeTradingInfo.getWorkLoad().multiply(new BigDecimal(1000)).subtract(schedulingNumBySpeculativeTradingName).compareTo(productionNum) >= 0){
//                        name.set(speculativeTradingInfo.getName());
//                        break;
//                    }
//                }
//            }else{
//                // å•个炒机情况
//                name.set(speculativeTradingInfos.get(0).getName());
//            }
//            if(name.get().isEmpty()){
//                i++;
//                continue;
//            }
            SalesLedgerScheduling salesLedgerScheduling = SalesLedgerScheduling.builder()
                    .salesLedgerId(productionDispatchAddDto.getSalesLedgerId())
                    .salesLedgerProductId(productionDispatchAddDto.getSalesLedgerProductId())
                    .speculativeTradingName(name.get())
//                    .speculativeTradingName(name.get())
                    .productionUserId(sysUser1.getUserId())
                    .productionUserName(sysUser1.getNickName())
                    .productionLineId(productionDispatchAddDto.getLineId())
                    .schedulingUserId(sysUser.getUserId())
                    .schedulingUserName(sysUser.getNickName())
                    .schedulingNum(productionDispatchAddDto.getSchedulingNum())
@@ -281,6 +292,8 @@
    @Override
    public IPage<SalesLedgerSchedulingProcessDto> listPageProcess(Page page, SalesLedgerSchedulingProcessDto salesLedgerSchedulingDto) {
        Long userId = SecurityUtils.getLoginUser().getUserId();
        salesLedgerSchedulingDto.setProductionUserId(userId);
        IPage<SalesLedgerSchedulingProcessDto> list = salesLedgerSchedulingMapper.listPageProcess(page, salesLedgerSchedulingDto);
//        Set<Long> collect = list.getRecords().stream().map(SalesLedgerSchedulingProcessDto::getId).collect(Collectors.toSet());
//        if(CollectionUtils.isEmpty(collect)) return list;
@@ -338,6 +351,8 @@
            SalesLedgerWork.SalesLedgerWorkBuilder salesLedgerWorkBuilder = SalesLedgerWork.builder()
                    .salesLedgerSchedulingId(salesLedgerScheduling.getId())
                    .salesLedgerId(salesLedgerScheduling.getSalesLedgerId())
                    .productionUserId(salesLedgerScheduling.getProductionUserId())
                    .productionUserName(salesLedgerScheduling.getProductionUserName())
                    .remark(processSchedulingDto.getRemark())
                    .type(processSchedulingDto.getType())
                    .loss(processSchedulingDto.getLoss())
src/main/java/com/ruoyi/production/service/impl/SalesLedgerWorkServiceImpl.java
@@ -57,6 +57,7 @@
    @Override
    public IPage<SalesLedgerWorkDto> listPage(Page page, SalesLedgerWorkDto salesLedgerWorkDto) {
        salesLedgerWorkDto.setProductionUserId(SecurityUtils.getLoginUser().getUserId());
        IPage<SalesLedgerWorkDto> iPage = salesLedgerWorkMapper.listPage(page, salesLedgerWorkDto);
        List<Loss> losses = lossMapper.selectList(null);
        if(!CollectionUtils.isEmpty(losses)){
src/main/resources/application-trsw.yml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,219 @@
# é¡¹ç›®ç›¸å…³é…ç½®
ruoyi:
  # åç§°
  name: RuoYi
  # ç‰ˆæœ¬
  version: 3.8.9
  # ç‰ˆæƒå¹´ä»½
  copyrightYear: 2025
  # æ–‡ä»¶è·¯å¾„ ç¤ºä¾‹ï¼ˆ Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
  profile: /javaWork/product-inventory-management/file
  # èŽ·å–ip地址开关
  addressEnabled: false
  # éªŒè¯ç ç±»åž‹ math æ•°å­—计算 char å­—符验证
  captchaType: math
# å¼€å‘环境配置
server:
  # æœåŠ¡å™¨çš„HTTP端口,默认为8080
  port: 9129
  servlet:
    # åº”用的访问路径
    context-path: /
  tomcat:
    # tomcat的URI编码
    uri-encoding: UTF-8
    # è¿žæŽ¥æ•°æ»¡åŽçš„æŽ’队数,默认为100
    accept-count: 1000
    threads:
      # tomcat最大线程数,默认为200
      max: 800
      # Tomcat启动初始化的线程数,默认值10
      min-spare: 100
# æ—¥å¿—配置
logging:
  level:
    com.ruoyi: warn
    org.springframework: warn
minio:
  endpoint: http://114.132.189.42/
  port: 7019
  secure: false
  accessKey: admin
  secretKey: 12345678
  preview-expiry: 24 # é¢„览地址默认24小时
  default-bucket: demo-product
# ç”¨æˆ·é…ç½®
user:
  password:
    # å¯†ç æœ€å¤§é”™è¯¯æ¬¡æ•°
    maxRetryCount: 5
    # å¯†ç é”å®šæ—¶é—´ï¼ˆé»˜è®¤10分钟)
    lockTime: 10
# Spring配置
spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driverClassName: com.mysql.cj.jdbc.Driver
    druid:
      # ä¸»åº“数据源
      master:
        url: jdbc:mysql://172.17.0.1:3306/product-inventory-management-trsw?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
        username: root
        password: xd@123456..
      # ä»Žåº“数据源
      slave:
        # ä»Žæ•°æ®æºå¼€å…³/默认关闭
        enabled: false
        url:
        username:
        password:
      # åˆå§‹è¿žæŽ¥æ•°
      initialSize: 5
      # æœ€å°è¿žæŽ¥æ± æ•°é‡
      minIdle: 10
      # æœ€å¤§è¿žæŽ¥æ± æ•°é‡
      maxActive: 20
      # é…ç½®èŽ·å–è¿žæŽ¥ç­‰å¾…è¶…æ—¶çš„æ—¶é—´
      maxWait: 60000
      # é…ç½®è¿žæŽ¥è¶…æ—¶æ—¶é—´
      connectTimeout: 30000
      # é…ç½®ç½‘络超时时间
      socketTimeout: 60000
      # é…ç½®é—´éš”多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
      timeBetweenEvictionRunsMillis: 60000
      # é…ç½®ä¸€ä¸ªè¿žæŽ¥åœ¨æ± ä¸­æœ€å°ç”Ÿå­˜çš„æ—¶é—´ï¼Œå•位是毫秒
      minEvictableIdleTimeMillis: 300000
      # é…ç½®ä¸€ä¸ªè¿žæŽ¥åœ¨æ± ä¸­æœ€å¤§ç”Ÿå­˜çš„æ—¶é—´ï¼Œå•位是毫秒
      maxEvictableIdleTimeMillis: 900000
      # é…ç½®æ£€æµ‹è¿žæŽ¥æ˜¯å¦æœ‰æ•ˆ
      validationQuery: SELECT 1 FROM DUAL
      testWhileIdle: true
      testOnBorrow: false
      testOnReturn: false
      webStatFilter:
        enabled: true
      statViewServlet:
        enabled: true
        # è®¾ç½®ç™½åå•,不填则允许所有访问
        allow:
        url-pattern: /druid/*
        # æŽ§åˆ¶å°ç®¡ç†ç”¨æˆ·åå’Œå¯†ç 
        login-username: ruoyi
        login-password: 123456
      filter:
        stat:
          enabled: true
          # æ…¢SQL记录
          log-slow-sql: true
          slow-sql-millis: 1000
          merge-sql: true
        wall:
          config:
            multi-statement-allow: true
  # èµ„源信息
  messages:
    # å›½é™…化资源文件路径
    basename: i18n/messages
  # æ–‡ä»¶ä¸Šä¼ 
  servlet:
    multipart:
      # å•个文件大小
      max-file-size: 1GB
      # è®¾ç½®æ€»ä¸Šä¼ çš„æ–‡ä»¶å¤§å°
      max-request-size: 2GB
  # æœåŠ¡æ¨¡å—
  devtools:
    restart:
      # çƒ­éƒ¨ç½²å¼€å…³
      enabled: false
  # redis é…ç½®
  redis:
    # åœ°å€
    #    host: 127.0.0.1
    host: 172.17.0.1
    # ç«¯å£ï¼Œé»˜è®¤ä¸º6379
    port: 6380
    # æ•°æ®åº“索引
    database: 13
    # å¯†ç 
    #    password: root2022!
    password:
    # è¿žæŽ¥è¶…æ—¶æ—¶é—´
    timeout: 10s
    lettuce:
      pool:
        # è¿žæŽ¥æ± ä¸­çš„æœ€å°ç©ºé—²è¿žæŽ¥
        min-idle: 0
        # è¿žæŽ¥æ± ä¸­çš„æœ€å¤§ç©ºé—²è¿žæŽ¥
        max-idle: 8
        # è¿žæŽ¥æ± çš„æœ€å¤§æ•°æ®åº“连接数
        max-active: 8
        # #连接池最大阻塞等待时间(使用负值表示没有限制)
        max-wait: -1ms
# token配置
token:
  # ä»¤ç‰Œè‡ªå®šä¹‰æ ‡è¯†
  header: Authorization
  # ä»¤ç‰Œå¯†é’¥
  secret: abcdefghijklmnopqrstuvwxyz
  # ä»¤ç‰Œæœ‰æ•ˆæœŸï¼ˆé»˜è®¤30分钟)
  expireTime: 450
# MyBatis Plus配置
mybatis-plus:
  # æœç´¢æŒ‡å®šåŒ…别名   æ ¹æ®è‡ªå·±çš„项目来
  typeAliasesPackage: com.ruoyi.**.pojo
  # é…ç½®mapper的扫描,找到所有的mapper.xml映射文件
  mapperLocations: classpath*:mapper/**/*Mapper.xml
  # åŠ è½½å…¨å±€çš„é…ç½®æ–‡ä»¶
  configLocation: classpath:mybatis/mybatis-config.xml
  global-config:
    enable-sql-runner: true
    db-config:
      id-type: auto
# PageHelper分页插件
pagehelper:
  helperDialect: mysql
  supportMethodsArguments: true
  params: count=countSql
# Swagger配置
swagger:
  # æ˜¯å¦å¼€å¯swagger
  enabled: true
  # è¯·æ±‚前缀
  pathMapping: /dev-api
# é˜²æ­¢XSS攻击
xss:
  # è¿‡æ»¤å¼€å…³
  enabled: true
  # æŽ’除链接(多个用逗号分隔)
  excludes: /system/notice
  # åŒ¹é…é“¾æŽ¥
  urlPatterns: /system/*,/monitor/*,/tool/*
# ä»£ç ç”Ÿæˆ
gen:
  # ä½œè€…
  author: ruoyi
  # é»˜è®¤ç”ŸæˆåŒ…路径 system éœ€æ”¹æˆè‡ªå·±çš„æ¨¡å—名称 å¦‚ system monitor tool
  packageName: com.ruoyi.project.system
  # è‡ªåŠ¨åŽ»é™¤è¡¨å‰ç¼€ï¼Œé»˜è®¤æ˜¯true
  autoRemovePre: false
  # è¡¨å‰ç¼€ï¼ˆç”Ÿæˆç±»åä¸ä¼šåŒ…含表前缀,多个用逗号分隔)
  tablePrefix: sys_
  # æ˜¯å¦å…è®¸ç”Ÿæˆæ–‡ä»¶è¦†ç›–到本地(自定义路径),默认不允许
  allowOverwrite: false
file:
  temp-dir: /javaWork/product-inventory-management/file/temp/uploads
  upload-dir: /javaWork/product-inventory-management/file/prod/uploads
src/main/resources/application.yml
@@ -1,4 +1,4 @@
# Spring配置
spring:
  profiles:
    active: hckxTest
    active: dev
src/main/resources/mapper/production/ProductionLineMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,5 @@
<?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.production.mapper.ProductionLineMapper">
</mapper>
src/main/resources/mapper/production/SalesLedgerProductionAccountingMapper.xml
@@ -28,6 +28,9 @@
            <if test="salesLedgerDto.schedulingUserName != null and salesLedgerDto.schedulingUserName != '' ">
                AND  t4.scheduling_user_name LIKE CONCAT('%',#{salesLedgerDto.schedulingUserName},'%')
            </if>
            <if test="salesLedgerDto.schedulingUserId != null and salesLedgerDto.schedulingUserId != '' ">
                AND  t4.scheduling_user_id LIKE CONCAT('%',#{salesLedgerDto.schedulingUserId},'%')
            </if>
            <if test="salesLedgerDto.customerName != null and salesLedgerDto.customerName != '' ">
                AND  T1.customer_name LIKE CONCAT('%',#{salesLedgerDto.customerName},'%')
            </if>
src/main/resources/mapper/production/SalesLedgerSchedulingMapper.xml
@@ -41,6 +41,9 @@
            <if test="salesLedgerDto.entryDateEnd != null and salesLedgerDto.entryDateEnd != '' ">
                AND  T1.entry_date &lt;= DATE_FORMAT(#{salesLedgerDto.entryDateEnd},'%Y-%m-%d')
            </if>
            <if test="salesLedgerDto.productionUserId != null and salesLedgerDto.productionUserId != '' ">
                AND  T1.entry_person = #{salesLedgerDto.productionUserId}
            </if>
        </where>
        GROUP BY T2.id
    </select>
@@ -82,11 +85,16 @@
        T1.customer_name,
        t3.product_category,
        t3.specification_model,
        t3.unit
        t3.unit,
        t4.name as productionLineName,
        t4.id as productionLineId,
        T2.production_user_name,
        T2.production_user_id
        FROM
        sales_ledger_scheduling T2
        LEFT JOIN sales_ledger T1 ON T1.id = T2.sales_ledger_id
        left join sales_ledger_product t3 on T2.sales_ledger_product_id = t3.id
        left join production_line t4 on t4.id = T2.production_line_id
        <where>
            t3.type = 1
            <if test="salesLedgerDto.status != null and salesLedgerDto.status != '' ">
@@ -110,6 +118,9 @@
            <if test="salesLedgerDto.entryDateEnd != null and salesLedgerDto.entryDateEnd != '' ">
                AND  T2.scheduling_date &lt;= DATE_FORMAT(#{salesLedgerDto.entryDateEnd},'%Y-%m-%d')
            </if>
            <if test="salesLedgerDto.productionUserId != null and salesLedgerDto.productionUserId != '' ">
                AND  T2.production_user_id = #{salesLedgerDto.productionUserId}
            </if>
        </where>
        order by T2.status asc
    </select>
src/main/resources/mapper/production/SalesLedgerWorkMapper.xml
@@ -8,6 +8,7 @@
        t4.status,
        t4.scheduling_user_id,
        t4.scheduling_user_name,
        t4.production_user_id,
        t4.scheduling_date,
        t4.scheduling_num,
        t4.finished_num,
@@ -34,6 +35,9 @@
            <if test="salesLedgerDto.status != null and salesLedgerDto.status != '' ">
                AND  t4.status = #{salesLedgerDto.status}
            </if>
            <if test="salesLedgerDto.productionUserId != null and salesLedgerDto.productionUserId != '' ">
                AND  t4.production_user_id = #{salesLedgerDto.productionUserId}
            </if>
            <if test="salesLedgerDto.customerName != null and salesLedgerDto.customerName != '' ">
                AND  T1.customer_name LIKE CONCAT('%',#{salesLedgerDto.customerName},'%')
            </if>