liyong
6 天以前 9cc2ddd5012a448d6187250121ba7f0cd0c5663b
下发报错修改
已修改2个文件
142 ■■■■■ 文件已修改
src/main/java/com/ruoyi/production/service/impl/ProductionBomStructureServiceImpl.java 80 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/impl/ProductionOrderServiceImpl.java 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/impl/ProductionBomStructureServiceImpl.java
@@ -31,6 +31,7 @@
import com.ruoyi.technology.pojo.TechnologyOperationParam;
import com.ruoyi.technology.pojo.TechnologyParam;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -49,6 +50,7 @@
 * @author 芯导软件(江苏)有限公司
 * @since 2026-04-21 03:55:52
 */
@Slf4j
@Service
@RequiredArgsConstructor()
public class ProductionBomStructureServiceImpl extends ServiceImpl<ProductionBomStructureMapper, ProductionBomStructure> implements ProductionBomStructureService {
@@ -137,6 +139,9 @@
            entity.setProductionOrderBomId(orderBomId);
            if (item.getId() == null) {
                entity.setParentId(null);
                // 新增节点的需求量由后端按BOM树形结构重新计算,不清空可能导致前端传的值溢出
                entity.setDemandedQuantity(null);
                entity.setId(null);
                insertList.add(entity);
                tempEntityMap.put(item.getTempId(), entity);
            } else {
@@ -146,6 +151,11 @@
        // 批量新增,拿到数据库生成的真实ID
        if (!insertList.isEmpty()) {
            for (ProductionBomStructure entity : insertList) {
                log.info("准备新增BOM结构节点: productModelId={}, technologyOperationId={}, unitQuantity={}, demandedQuantity={}, unit={}",
                        entity.getProductModelId(), entity.getTechnologyOperationId(),
                        entity.getUnitQuantity(), entity.getDemandedQuantity(), entity.getUnit());
            }
            this.saveBatch(insertList);
        }
@@ -216,24 +226,76 @@
        if (structureList == null || structureList.isEmpty()) {
            return;
        }
        List<ProductionBomStructure> updateList = new ArrayList<>();
        BigDecimal lastProcessDemandedQuantity = orderQuantity;
        log.info("开始按BOM树形结构计算需求量,订单数量={}, BOM节点总数={}", orderQuantity, structureList.size());
        // 构建 id → structure 映射和 parentId → children 映射
        Map<Long, ProductionBomStructure> structureById = new HashMap<>();
        Map<Long, List<ProductionBomStructure>> childrenMap = new LinkedHashMap<>();
        for (ProductionBomStructure structure : structureList) {
            if (structure == null || structure.getId() == null) {
                continue;
            }
            structureById.put(structure.getId(), structure);
            Long parentId = structure.getParentId();
            childrenMap.computeIfAbsent(parentId, k -> new ArrayList<>()).add(structure);
        }
            BigDecimal demandedQuantity = lastProcessDemandedQuantity.multiply(defaultDecimal(structure.getUnitQuantity()));
//            if (compareDecimal(structure.getDemandedQuantity(), demandedQuantity) == 0) {
//                continue;
//            }
        List<ProductionBomStructure> updateList = new ArrayList<>();
        // 从根节点开始,按树形层级逐层计算需求量
        // 根节点 parentId 为 null 或 0
        Deque<Long> queue = new ArrayDeque<>();
        List<ProductionBomStructure> rootNodes = childrenMap.get(null);
        if (rootNodes != null) {
            for (ProductionBomStructure root : rootNodes) {
                queue.add(root.getId());
            }
        }
        // parentId=0 的也视为根节点
        List<ProductionBomStructure> zeroParentNodes = childrenMap.get(0L);
        if (zeroParentNodes != null) {
            for (ProductionBomStructure root : zeroParentNodes) {
                if (!queue.contains(root.getId())) {
                    queue.add(root.getId());
                }
            }
        }
        while (!queue.isEmpty()) {
            Long nodeId = queue.poll();
            ProductionBomStructure node = structureById.get(nodeId);
            if (node == null) {
                continue;
            }
            // 计算当前节点的需求数量 = 父节点需求量 × 自身 unitQuantity
            // 根节点:需求量 = 订单数量 × unitQuantity
            BigDecimal parentDemandedQuantity = orderQuantity;
            Long parentId = node.getParentId();
            if (parentId != null && parentId != 0L) {
                ProductionBomStructure parent = structureById.get(parentId);
                if (parent != null && parent.getDemandedQuantity() != null) {
                    parentDemandedQuantity = parent.getDemandedQuantity();
                }
            }
            BigDecimal demandedQuantity = parentDemandedQuantity.multiply(defaultDecimal(node.getUnitQuantity()));
            log.info("BOM需求量计算: nodeId={}, parentId={}, parentDemandedQuantity={}, unitQuantity={}, demandedQuantity={}",
                    node.getId(), node.getParentId(), parentDemandedQuantity,
                    defaultDecimal(node.getUnitQuantity()), demandedQuantity);
            ProductionBomStructure update = new ProductionBomStructure();
            update.setId(structure.getId());
            update.setId(node.getId());
            update.setDemandedQuantity(demandedQuantity);
            updateList.add(update);
            structure.setDemandedQuantity(demandedQuantity);
            lastProcessDemandedQuantity = demandedQuantity;
            node.setDemandedQuantity(demandedQuantity);
            // 将子节点加入队列
            List<ProductionBomStructure> children = childrenMap.get(nodeId);
            if (children != null) {
                for (ProductionBomStructure child : children) {
                    queue.add(child.getId());
                }
            }
        }
        if (!updateList.isEmpty()) {
            this.updateBatchById(updateList);
        }
src/main/java/com/ruoyi/production/service/impl/ProductionOrderServiceImpl.java
@@ -439,9 +439,54 @@
        productionOrderBomMapper.insert(orderBom);
        Map<Long, Long> idMap = new HashMap<>();
        BigDecimal lastProcessDemandedQuantity = orderQuantity;
        // 构建 sourceId → sourceNode 映射 和 parentId → children 映射
        Map<Long, TechnologyBomStructure> sourceById = new HashMap<>();
        Map<Long, List<TechnologyBomStructure>> childrenMap = new LinkedHashMap<>();
        for (TechnologyBomStructure source : structureList) {
            // 子节点 parentId 需要映射成新快照节点 id,才能保留原始 BOM 层级。
            if (source == null || source.getId() == null) {
                continue;
            }
            sourceById.put(source.getId(), source);
            Long parentId = source.getParentId();
            childrenMap.computeIfAbsent(parentId, k -> new ArrayList<>()).add(source);
        }
        // BFS 从根节点开始,父节点先于子节点处理
        Deque<TechnologyBomStructure> queue = new ArrayDeque<>();
        List<TechnologyBomStructure> rootNodes = childrenMap.get(null);
        if (rootNodes != null) {
            queue.addAll(rootNodes);
        }
        // parentId=0 的也视为根节点
        List<TechnologyBomStructure> zeroParentNodes = childrenMap.get(0L);
        if (zeroParentNodes != null) {
            for (TechnologyBomStructure node : zeroParentNodes) {
                if (!queue.contains(node)) {
                    queue.add(node);
                }
            }
        }
        while (!queue.isEmpty()) {
            TechnologyBomStructure source = queue.poll();
            if (source == null || source.getId() == null) {
                continue;
            }
            // 计算需求量 = 父节点需求量 × 自身 unitQuantity
            BigDecimal parentDemandedQuantity = orderQuantity;
            Long sourceParentId = source.getParentId();
            if (sourceParentId != null && sourceParentId != 0L) {
                Long parentTargetId = idMap.get(sourceParentId);
                if (parentTargetId != null) {
                    // 父节点已经插入,用父节点的 targetId 从已插入列表找
                    // 这里我们直接用存下来的父节点需求量
                    TechnologyBomStructure parentSource = sourceById.get(sourceParentId);
                    if (parentSource != null && parentSource.getDemandedQuantity() != null) {
                        parentDemandedQuantity = parentSource.getDemandedQuantity();
                    }
                }
            }
            ProductionBomStructure target = new ProductionBomStructure();
            target.setProductionOrderId(productionOrder.getId());
            target.setProductionOrderBomId(orderBom.getId());
@@ -449,11 +494,20 @@
            target.setProductModelId(source.getProductModelId());
            target.setTechnologyOperationId(source.getOperationId());
            target.setUnitQuantity(source.getUnitQuantity());
            target.setDemandedQuantity(lastProcessDemandedQuantity.multiply(source.getUnitQuantity()));
            target.setDemandedQuantity(parentDemandedQuantity.multiply(defaultDecimal(source.getUnitQuantity())));
            target.setUnit(source.getUnit());
            productionBomStructureMapper.insert(target);
            idMap.put(source.getId(), target.getId());
            lastProcessDemandedQuantity = target.getDemandedQuantity();
            // 将当前节点的 demandedQuantity 回写到 source 对象上,供子节点计算使用
            source.setDemandedQuantity(target.getDemandedQuantity());
            // 将子节点加入队列
            List<TechnologyBomStructure> children = childrenMap.get(source.getId());
            if (children != null) {
                for (TechnologyBomStructure child : children) {
                    queue.add(child);
                }
            }
        }
        return orderBom;
    }