From f00a59b4f30accf2b23ae0d58fac23d966a48d24 Mon Sep 17 00:00:00 2001
From: yuan <123@>
Date: 星期六, 13 六月 2026 20:11:51 +0800
Subject: [PATCH] fix: 优化生产订单查询

---
 src/main/java/com/ruoyi/production/service/impl/ProductionOrderServiceImpl.java |  103 ++++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 92 insertions(+), 11 deletions(-)

diff --git a/src/main/java/com/ruoyi/production/service/impl/ProductionOrderServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProductionOrderServiceImpl.java
index 920188e..0ec5ca8 100644
--- a/src/main/java/com/ruoyi/production/service/impl/ProductionOrderServiceImpl.java
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductionOrderServiceImpl.java
@@ -22,6 +22,8 @@
 import com.ruoyi.production.bean.vo.ProductionOrderVo;
 import com.ruoyi.production.bean.vo.ProductionPlanVo;
 import com.ruoyi.production.bean.vo.ProductionOrderWorkOrderDetailVo;
+import com.ruoyi.production.bean.vo.ProcessRouteStatusVo;
+import com.ruoyi.production.bean.vo.ProductionOrderProcessTaskVo;
 import com.ruoyi.production.enums.ProductOrderStatusEnum;
 import com.ruoyi.production.mapper.*;
 import com.ruoyi.production.pojo.*;
@@ -59,6 +61,7 @@
     private final ProductionOperationTaskMapper productionOperationTaskMapper;
     private final ProductionOrderBomMapper productionOrderBomMapper;
     private final ProductionBomStructureMapper productionBomStructureMapper;
+    private final ProductionOrderMapper productionOrderMapper;
     private final ProductionProductMainMapper productionProductMainMapper;
     private final ProductionProductOutputMapper productionProductOutputMapper;
     private final ProductionOrderPickMapper productionOrderPickMapper;
@@ -85,6 +88,7 @@
         // 鍒嗛〉鏌ヨ鐢熶骇璁㈠崟
         Page<ProductionOrderVo> result = (Page<ProductionOrderVo>) baseMapper.pageProductionOrder(page, dto);
         fillProductImages(result.getRecords());
+        fillProcessRouteStatus(result.getRecords());
         return result;
     }
 
@@ -93,6 +97,7 @@
         // 鏌ヨ鐢熶骇璁㈠崟鍒楄〃
         List<ProductionOrderVo> records = baseMapper.listProductionOrder(dto);
         fillProductImages(records);
+        fillProcessRouteStatus(records);
         return records;
     }
 
@@ -132,7 +137,7 @@
                 || !Objects.equals(oldOrder.getProductModelId(), productionOrder.getProductModelId())
                 || compareDecimal(oldOrder.getQuantity(), productionOrder.getQuantity()) != 0
                 || productionOrderRoutingMapper.selectCount(Wrappers.<ProductionOrderRouting>lambdaQuery()
-                        .eq(ProductionOrderRouting::getProductionOrderId, productionOrder.getId())) == 0);
+                .eq(ProductionOrderRouting::getProductionOrderId, productionOrder.getId())) == 0);
         if (needSync) {
             syncProductionOrderSnapshot(productionOrder.getId());
         }
@@ -258,7 +263,7 @@
         Map<String, BigDecimal> operationDemandedQuantityMap =
                 buildOperationDemandedQuantityMap(orderBomStructureList, rootProductModelId);
         Map<Long, String> operationNameMap = technologyOperationMapper.selectBatchIds(
-        // 閬嶅巻澶勭悊鏁版嵁骞剁粍瑁呯粨鏋�
+                        // 閬嶅巻澶勭悊鏁版嵁骞剁粍瑁呯粨鏋�
                         routingOperations.stream()
                                 .map(TechnologyRoutingOperation::getTechnologyOperationId)
                                 .filter(Objects::nonNull)
@@ -437,6 +442,7 @@
         productionOrderBomMapper.insert(orderBom);
 
         Map<Long, Long> idMap = new HashMap<>();
+        BigDecimal lastProcessDemandedQuantity = orderQuantity;
         for (TechnologyBomStructure source : structureList) {
             // 瀛愯妭鐐� parentId 闇�瑕佹槧灏勬垚鏂板揩鐓ц妭鐐� id锛屾墠鑳戒繚鐣欏師濮� BOM 灞傜骇銆�
             ProductionBomStructure target = new ProductionBomStructure();
@@ -446,10 +452,11 @@
             target.setProductModelId(source.getProductModelId());
             target.setTechnologyOperationId(source.getOperationId());
             target.setUnitQuantity(source.getUnitQuantity());
-            target.setDemandedQuantity(source.getUnitQuantity().multiply(orderQuantity));
+            target.setDemandedQuantity(lastProcessDemandedQuantity.multiply(source.getUnitQuantity()));
             target.setUnit(source.getUnit());
             productionBomStructureMapper.insert(target);
             idMap.put(source.getId(), target.getId());
+            lastProcessDemandedQuantity = target.getDemandedQuantity();
         }
         return orderBom;
     }
@@ -457,7 +464,7 @@
     private void clearProductionSnapshot(Long productionOrderId) {
         // 娓呯悊璁㈠崟宸茬敓鎴愮殑宸ヨ壓涓嶣OM蹇収鏁版嵁
         boolean hasPickRecord = productionOrderPickRecordMapper.selectCount(
-        // 鏌ヨ骞跺噯澶囦笟鍔℃暟鎹�
+                // 鏌ヨ骞跺噯澶囦笟鍔℃暟鎹�
                 Wrappers.<ProductionOrderPickRecord>lambdaQuery()
                         .eq(ProductionOrderPickRecord::getProductionOrderId, productionOrderId)) > 0;
         // 鍙傛暟涓庡墠缃潯浠舵牎楠�
@@ -467,7 +474,7 @@
         List<Long> taskIds = productionOperationTaskMapper.selectList(
                         Wrappers.<ProductionOperationTask>lambdaQuery()
                                 .eq(ProductionOperationTask::getProductionOrderId, productionOrderId))
-        // 閬嶅巻澶勭悊鏁版嵁骞剁粍瑁呯粨鏋�
+                // 閬嶅巻澶勭悊鏁版嵁骞剁粍瑁呯粨鏋�
                 .stream().map(ProductionOperationTask::getId).collect(Collectors.toList());
         if (!taskIds.isEmpty()) {
             // 宸叉湁鎶ュ伐璁板綍璇存槑璁㈠崟宸插紑宸ワ紝姝ゆ椂涓嶅厑璁稿啀閲嶅缓蹇収銆�
@@ -809,6 +816,46 @@
         }
     }
 
+    private void fillProcessRouteStatus(List<ProductionOrderVo> records) {
+        if (records == null || records.isEmpty()) {
+            return;
+        }
+        List<Long> orderIds = records.stream()
+                .map(ProductionOrderVo::getId)
+                .filter(Objects::nonNull)
+                .distinct()
+                .collect(Collectors.toList());
+        if (orderIds.isEmpty()) {
+            return;
+        }
+
+        List<ProductionOrderProcessTaskVo> tasks = productionOperationTaskMapper.listProcessStatusByOrderIds(orderIds);
+        Map<Long, List<ProcessRouteStatusVo>> statusMap = new LinkedHashMap<>();
+        if (tasks != null) {
+            for (ProductionOrderProcessTaskVo task : tasks) {
+                if (task == null || task.getProductionOrderId() == null) {
+                    continue;
+                }
+                ProcessRouteStatusVo status = new ProcessRouteStatusVo();
+                status.setName(task.getOperationName() != null && !task.getOperationName().isBlank()
+                        ? task.getOperationName()
+                        : "鏈煡宸ュ簭");
+                BigDecimal percentage = task.getCompletionStatus() == null
+                        ? BigDecimal.ZERO
+                        : task.getCompletionStatus();
+                if (percentage.compareTo(new BigDecimal("100")) > 0) {
+                    percentage = new BigDecimal("100");
+                }
+                status.setPercentage(percentage);
+                statusMap.computeIfAbsent(task.getProductionOrderId(), key -> new ArrayList<>()).add(status);
+            }
+        }
+
+        for (ProductionOrderVo record : records) {
+            record.setProcessRouteStatus(statusMap.getOrDefault(record.getId(), Collections.emptyList()));
+        }
+    }
+
     private StorageBlobVO toStorageBlobVO(StorageBlob blob) {
         // 灏嗗瓨鍌ㄦ枃浠跺璞¤浆鎹负VO
         StorageBlobVO vo = BeanUtil.copyProperties(blob, StorageBlobVO.class);
@@ -836,7 +883,7 @@
                 new Page<ProductionOperationTaskVo>(1, -1), taskQuery);
         List<ProductionOperationTaskVo> workOrderList = workOrderPage == null || workOrderPage.getRecords() == null
                 ? Collections.emptyList()
-        // 閬嶅巻澶勭悊鏁版嵁骞剁粍瑁呯粨鏋�
+                // 閬嶅巻澶勭悊鏁版嵁骞剁粍瑁呯粨鏋�
                 : workOrderPage.getRecords().stream()
                 .filter(Objects::nonNull)
                 .sorted(Comparator.comparing(ProductionOperationTaskVo::getId, Comparator.nullsLast(Comparator.naturalOrder())))
@@ -852,7 +899,7 @@
                 .collect(Collectors.toList());
         List<ProductionProductMain> reportMainList = workOrderIdList.isEmpty()
                 ? Collections.emptyList()
-        // 鏌ヨ骞跺噯澶囦笟鍔℃暟鎹�
+                // 鏌ヨ骞跺噯澶囦笟鍔℃暟鎹�
                 : productionProductMainMapper.selectList(
                 Wrappers.<ProductionProductMain>lambdaQuery()
                         .in(ProductionProductMain::getProductionOperationTaskId, workOrderIdList)
@@ -1027,13 +1074,46 @@
             return Collections.emptyList();
         }
 
-        List<ProductionBomStructureVo> bomStructureList = productionBomStructureMapper.pickByBomId(orderBom.getId());
+        // 鏌ヨ瀹屾暣鐨凚OM缁撴瀯锛堝寘鎷牴鑺傜偣锛夛紝鐢ㄤ簬璁$畻灞傜骇闇�姹傛暟閲�
+        List<ProductionBomStructureVo> bomStructureList = productionBomStructureMapper.listByBomId(orderBom.getId());
         if (bomStructureList == null || bomStructureList.isEmpty()) {
             return Collections.emptyList();
         }
 
+        // 鏌ヨ鐢熶骇璁㈠崟鑾峰彇璁㈠崟鏁伴噺
+        ProductionOrder productionOrder = productionOrderMapper.selectById(productionOrderId);
+        BigDecimal orderQuantity = productionOrder != null ? defaultDecimal(productionOrder.getQuantity()) : BigDecimal.ZERO;
+
+        // 鏋勫缓鏍戝舰缁撴瀯骞惰绠楀眰绾ч渶姹傛暟閲�
+        Map<Long, ProductionBomStructureVo> structureByIdMap = bomStructureList.stream()
+                .filter(s -> s != null && s.getId() != null)
+                .collect(Collectors.toMap(ProductionBomStructureVo::getId, s -> s));
+
+        // 鎸夊眰绾ц绠楅渶姹傛暟閲忥細瀛愮骇闇�姹傛暟閲� = 鐖剁骇闇�姹傛暟閲� 脳 瀛愮骇鍗曚綅浜у嚭鎵�闇�鏁伴噺
+        for (ProductionBomStructureVo structure : bomStructureList) {
+            if (structure == null) continue;
+
+            if (structure.getParentId() == null || structure.getParentId() == 0) {
+                // 鏍硅妭鐐癸細闇�姹傛暟閲� = 璁㈠崟鏁伴噺
+                structure.setDemandedQuantity(orderQuantity);
+            } else {
+                // 瀛愯妭鐐癸細闇�姹傛暟閲� = 鐖剁骇闇�姹傛暟閲� 脳 瀛愮骇鍗曚綅浜у嚭鎵�闇�鏁伴噺
+                ProductionBomStructureVo parent = structureByIdMap.get(structure.getParentId());
+                if (parent != null) {
+                    BigDecimal parentDemandedQty = defaultDecimal(parent.getDemandedQuantity());
+                    BigDecimal unitQuantity = defaultDecimal(structure.getUnitQuantity());
+                    structure.setDemandedQuantity(parentDemandedQty.multiply(unitQuantity));
+                }
+            }
+        }
+
+        // 杩囨护鍑洪潪鏍硅妭鐐癸紙瀹為檯棰嗘枡椤癸級
+        List<ProductionBomStructureVo> childStructureList = bomStructureList.stream()
+                .filter(s -> s != null && s.getParentId() != null && s.getParentId() != 0)
+                .collect(Collectors.toList());
+
         // 閬嶅巻澶勭悊鏁版嵁骞剁粍瑁呯粨鏋�
-        List<Long> productModelIds = bomStructureList.stream()
+        List<Long> productModelIds = childStructureList.stream()
                 .map(ProductionBomStructureVo::getProductModelId)
                 .filter(Objects::nonNull)
                 .distinct()
@@ -1043,7 +1123,8 @@
         if (!productModelIds.isEmpty()) {
             List<StockInventory> stockList = stockInventoryMapper.selectList(
                     Wrappers.<StockInventory>lambdaQuery()
-                            .in(StockInventory::getProductModelId, productModelIds));
+                            .in(StockInventory::getProductModelId, productModelIds)
+                            .gt(StockInventory::getQualitity, BigDecimal.ZERO));
             for (StockInventory stockItem : stockList) {
                 if (stockItem == null || stockItem.getProductModelId() == null) {
                     continue;
@@ -1058,7 +1139,7 @@
         }
 
         Map<String, ProductionOrderPickVo> mergedPickMap = new LinkedHashMap<>();
-        for (ProductionBomStructureVo structure : bomStructureList) {
+        for (ProductionBomStructureVo structure : childStructureList) {
             if (structure == null || structure.getProductModelId() == null) {
                 continue;
             }

--
Gitblit v1.9.3