| | |
| | | return; |
| | | } |
| | | List<ProductionBomStructure> updateList = new ArrayList<>(); |
| | | BigDecimal lastProcessDemandedQuantity = orderQuantity; |
| | | for (ProductionBomStructure structure : structureList) { |
| | | if (structure == null || structure.getId() == null) { |
| | | continue; |
| | | } |
| | | BigDecimal demandedQuantity = defaultDecimal(structure.getUnitQuantity()).multiply(orderQuantity); |
| | | if (compareDecimal(structure.getDemandedQuantity(), demandedQuantity) == 0) { |
| | | continue; |
| | | } |
| | | |
| | | BigDecimal demandedQuantity = lastProcessDemandedQuantity.multiply(defaultDecimal(structure.getUnitQuantity())); |
| | | // if (compareDecimal(structure.getDemandedQuantity(), demandedQuantity) == 0) { |
| | | // continue; |
| | | // } |
| | | ProductionBomStructure update = new ProductionBomStructure(); |
| | | update.setId(structure.getId()); |
| | | update.setDemandedQuantity(demandedQuantity); |
| | | updateList.add(update); |
| | | structure.setDemandedQuantity(demandedQuantity); |
| | | lastProcessDemandedQuantity = demandedQuantity; |
| | | } |
| | | if (!updateList.isEmpty()) { |
| | | this.updateBatchById(updateList); |
| | |
| | | ProductionOrderBom orderBom, |
| | | List<ProductionBomStructure> structureList, |
| | | Long rootProductModelId) { |
| | | // 重新查询BOM结构,按子节点优先排序 |
| | | List<ProductionBomStructure> routingStructureList = this.list( |
| | | Wrappers.<ProductionBomStructure>lambdaQuery() |
| | | .eq(ProductionBomStructure::getProductionOrderBomId, orderBom.getId()) |
| | | .orderByDesc(ProductionBomStructure::getParentId) |
| | | .orderByAsc(ProductionBomStructure::getId)); |
| | | |
| | | ProductionOrderRouting orderRouting = getOrCreateOrderRoutingSnapshot(productionOrderId, productionOrder, orderBom, rootProductModelId); |
| | | List<ProductionOrderRoutingOperation> desiredOperationList = buildDesiredRoutingOperationList(structureList, rootProductModelId); |
| | | List<ProductionOrderRoutingOperation> desiredOperationList = buildDesiredRoutingOperationList(routingStructureList, rootProductModelId); |
| | | List<ProductionOrderRoutingOperation> existingOperationList = productionOrderRoutingOperationMapper.selectList( |
| | | Wrappers.<ProductionOrderRoutingOperation>lambdaQuery() |
| | | .eq(ProductionOrderRoutingOperation::getOrderRoutingId, orderRouting.getId()) |
| | |
| | | Map<Long, ProductionBomStructure> structureById = structureList.stream() |
| | | .filter(item -> item != null && item.getId() != null) |
| | | .collect(Collectors.toMap(ProductionBomStructure::getId, item -> item, (left, right) -> left)); |
| | | |
| | | // 构建父-子映射关系 |
| | | Map<Long, List<ProductionBomStructure>> treeMap = buildParentChildMap(structureList); |
| | | |
| | | // 使用后序遍历构建操作列表(先子后父,确保工艺路线顺序正确) |
| | | Map<String, ProductionBomStructure> uniqueOperationMap = new LinkedHashMap<>(); |
| | | for (ProductionBomStructure bomStructure : structureList) { |
| | | if (bomStructure == null || bomStructure.getTechnologyOperationId() == null) { |
| | | continue; |
| | | } |
| | | Long outputProductModelId = resolveOutputProductModelId(resolveOperationOutputNode(bomStructure, structureById), rootProductModelId); |
| | | uniqueOperationMap.putIfAbsent(buildBomOperationDedupKey(bomStructure, outputProductModelId), bomStructure); |
| | | } |
| | | buildOperationListPostOrder(null, treeMap, uniqueOperationMap, structureById, rootProductModelId); |
| | | |
| | | List<ProductionOrderRoutingOperation> desiredOperationList = new ArrayList<>(); |
| | | int dragSort = 1; |
| | | for (ProductionBomStructure bomStructure : uniqueOperationMap.values()) { |
| | |
| | | desiredOperationList.add(routingOperation); |
| | | } |
| | | return desiredOperationList; |
| | | } |
| | | |
| | | private Map<Long, List<ProductionBomStructure>> buildParentChildMap(List<ProductionBomStructure> structureList) { |
| | | Map<Long, List<ProductionBomStructure>> treeMap = new LinkedHashMap<>(); |
| | | Map<Long, Integer> childCountMap = new HashMap<>(); |
| | | |
| | | // 第一遍:统计每个节点的子节点数量,同时构建初始映射 |
| | | for (ProductionBomStructure structure : structureList) { |
| | | if (structure == null) continue; |
| | | Long parentId = structure.getParentId(); |
| | | childCountMap.merge(parentId, 1, Integer::sum); // 统计每个父节点有多少个子节点 |
| | | treeMap.computeIfAbsent(parentId, k -> new ArrayList<>()).add(structure); |
| | | } |
| | | |
| | | // 第二遍:对每个父节点下的子节点按子节点数量倒序排序(有子节点的优先) |
| | | for (Map.Entry<Long, List<ProductionBomStructure>> entry : treeMap.entrySet()) { |
| | | List<ProductionBomStructure> children = entry.getValue(); |
| | | children.sort((a, b) -> { |
| | | int countA = childCountMap.getOrDefault(a.getId(), 0); |
| | | int countB = childCountMap.getOrDefault(b.getId(), 0); |
| | | return Integer.compare(countB, countA); // 子节点多的排前面 |
| | | }); |
| | | } |
| | | |
| | | return treeMap; |
| | | } |
| | | |
| | | private void buildOperationListPostOrder(Long parentId, |
| | | Map<Long, List<ProductionBomStructure>> treeMap, |
| | | Map<String, ProductionBomStructure> uniqueOperationMap, |
| | | Map<Long, ProductionBomStructure> structureById, |
| | | Long rootProductModelId) { |
| | | List<ProductionBomStructure> children = treeMap.get(parentId); |
| | | if (children == null || children.isEmpty()) { |
| | | return; |
| | | } |
| | | for (ProductionBomStructure child : children) { |
| | | // 先递归处理子节点 |
| | | buildOperationListPostOrder(child.getId(), treeMap, uniqueOperationMap, structureById, rootProductModelId); |
| | | |
| | | // 再处理当前节点 |
| | | if (child.getTechnologyOperationId() != null) { |
| | | Long outputProductModelId = resolveOutputProductModelId(resolveOperationOutputNode(child, structureById), rootProductModelId); |
| | | uniqueOperationMap.putIfAbsent(buildBomOperationDedupKey(child, outputProductModelId), child); |
| | | } |
| | | } |
| | | } |
| | | |
| | | private Map<String, Deque<ProductionOrderRoutingOperation>> buildExistingRoutingOperationBucketMap(List<ProductionOrderRoutingOperation> existingOperationList) { |
| | |
| | | if (!Objects.equals(currentOperation.getIsProduction(), desiredOperation.getIsProduction())) { |
| | | update.setIsProduction(desiredOperation.getIsProduction()); |
| | | currentOperation.setIsProduction(desiredOperation.getIsProduction()); |
| | | changed = true; |
| | | } |
| | | // 更新 dragSort 字段,确保工艺路线顺序正确 |
| | | if (!Objects.equals(currentOperation.getDragSort(), desiredOperation.getDragSort())) { |
| | | update.setDragSort(desiredOperation.getDragSort()); |
| | | currentOperation.setDragSort(desiredOperation.getDragSort()); |
| | | changed = true; |
| | | } |
| | | if (!Objects.equals(currentOperation.getType(), desiredOperation.getType())) { |
| | |
| | | return; |
| | | } |
| | | for (ProductionBomStructureDto node : source) { |
| | | flattenTree(node.getChildren(), result); // 先递归添加子节点 |
| | | result.add(node); |
| | | flattenTree(node.getChildren(), result); |
| | | } |
| | | } |
| | | |