| | |
| | | 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()); |
| | |
| | | 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; |
| | | } |