From de4ca61aa27d7f284a03aebd801bcc3d6a75bc6a Mon Sep 17 00:00:00 2001
From: huminmin <mac@MacBook-Pro.local>
Date: 星期四, 21 五月 2026 15:03:35 +0800
Subject: [PATCH] 修改生产订单中的工艺路线项目是否生产后,更新生产工单数据

---
 src/main/java/com/ruoyi/production/service/impl/ProductionOrderRoutingOperationServiceImpl.java |  184 +++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 174 insertions(+), 10 deletions(-)

diff --git a/src/main/java/com/ruoyi/production/service/impl/ProductionOrderRoutingOperationServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProductionOrderRoutingOperationServiceImpl.java
index 489fc30..75d0696 100644
--- a/src/main/java/com/ruoyi/production/service/impl/ProductionOrderRoutingOperationServiceImpl.java
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductionOrderRoutingOperationServiceImpl.java
@@ -1,17 +1,18 @@
 package com.ruoyi.production.service.impl;
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.common.exception.ServiceException;
 import com.ruoyi.framework.web.domain.R;
-import com.ruoyi.production.mapper.ProductionOperationTaskMapper;
-import com.ruoyi.production.mapper.ProductionOrderRoutingOperationMapper;
-import com.ruoyi.production.mapper.ProductionProductMainMapper;
-import com.ruoyi.production.pojo.ProductionOperationTask;
-import com.ruoyi.production.pojo.ProductionOrderRoutingOperation;
-import com.ruoyi.production.pojo.ProductionProductMain;
+import com.ruoyi.production.mapper.*;
+import com.ruoyi.production.util.TaskPlanQuantityUtil;
+import com.ruoyi.technology.mapper.*;
+import com.ruoyi.production.pojo.*;
 import com.ruoyi.production.service.ProductionOrderRoutingOperationService;
 import com.ruoyi.production.service.ProductionProductMainService;
+import com.ruoyi.technology.pojo.*;
 import lombok.RequiredArgsConstructor;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -19,7 +20,7 @@
 import java.math.BigDecimal;
 import java.time.LocalDate;
 import java.time.format.DateTimeFormatter;
-import java.util.List;
+import java.util.*;
 
 @Service
 @Transactional(rollbackFor = Exception.class)
@@ -31,10 +32,44 @@
     private final ProductionOperationTaskMapper productionOperationTaskMapper;
     private final ProductionProductMainMapper productionProductMainMapper;
     private final ProductionProductMainService productionProductMainService;
+    private final TechnologyOperationParamMapper technologyOperationParamMapper;
+    private final TechnologyParamMapper technologyParamMapper;
+    private final ProductionOrderRoutingOperationParamMapper productionOrderRoutingOperationParamMapper;
+    private final ProductionOrderMapper productionOrderMapper;
+    private final ProductionOrderRoutingMapper productionOrderRoutingMapper;
+    private final ProductionOrderBomMapper productionOrderBomMapper;
+    private final ProductionBomStructureMapper productionBomStructureMapper;
+    private final TechnologyRoutingOperationMapper technologyRoutingOperationMapper;
 
     @Override
     public R addRouteItem(ProductionOrderRoutingOperation productionOrderRoutingOperation) {
+        // 鏂板宸ヨ壓璺嚎
         int insert = productionOrderRoutingOperationMapper.insert(productionOrderRoutingOperation);
+        //宸ュ簭鍏宠仈鐨勫弬鏁伴渶瑕佸悓姝ユ柊澧�
+        List<TechnologyOperationParam> technologyOperationParams = technologyOperationParamMapper.selectList(Wrappers.<TechnologyOperationParam>lambdaQuery()
+                .eq(TechnologyOperationParam::getTechnologyOperationId, productionOrderRoutingOperation.getTechnologyOperationId()));
+        // 鍙傛暟涓庡墠缃潯浠舵牎楠�
+        if (CollectionUtils.isNotEmpty(technologyOperationParams)){
+            ArrayList<ProductionOrderRoutingOperationParam> productionOrderRoutingOperationParams = new ArrayList<>();
+        // 閬嶅巻澶勭悊鏁版嵁骞剁粍瑁呯粨鏋�
+            for (TechnologyOperationParam technologyOperationParam : technologyOperationParams) {
+                TechnologyParam technologyParam = technologyParamMapper.selectById(technologyOperationParam.getTechnologyParamId());
+                ProductionOrderRoutingOperationParam productionOrderRoutingOperationParam = new ProductionOrderRoutingOperationParam();
+                productionOrderRoutingOperationParam.setProductionOrderId(productionOrderRoutingOperation.getProductionOrderId());
+                productionOrderRoutingOperationParam.setProductionOrderRoutingOperationId(productionOrderRoutingOperation.getId());
+                productionOrderRoutingOperationParam.setParamCode(technologyParam.getParamCode());
+                productionOrderRoutingOperationParam.setParamName(technologyParam.getParamName());
+                productionOrderRoutingOperationParam.setParamType(technologyParam.getParamType());
+                productionOrderRoutingOperationParam.setParamFormat(technologyParam.getParamFormat());
+                productionOrderRoutingOperationParam.setUnit(technologyParam.getUnit());
+                productionOrderRoutingOperationParam.setIsRequired(technologyParam.getIsRequired());
+                productionOrderRoutingOperationParam.setRemark(technologyParam.getRemark());
+                productionOrderRoutingOperationParam.setParamId(technologyParam.getId());
+                productionOrderRoutingOperationParam.setTechnologyOperationId(productionOrderRoutingOperation.getTechnologyOperationId());
+                productionOrderRoutingOperationParams.add(productionOrderRoutingOperationParam);
+            }
+            productionOrderRoutingOperationParamMapper.insert(productionOrderRoutingOperationParams);
+        }
         String datePrefix = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
         if (insert > 0) {
             ProductionOperationTask lastTask = productionOperationTaskMapper.selectOne(
@@ -56,7 +91,7 @@
             }
             String workOrderNoStr = "GD" + String.format("%s%03d", datePrefix, sequenceNumber);
             ProductionOperationTask productionOperationTask = new ProductionOperationTask();
-            productionOperationTask.setTechnologyRoutingOperationId(productionOrderRoutingOperation.getId());
+            productionOperationTask.setProductionOrderRoutingOperationId(productionOrderRoutingOperation.getId());
             productionOperationTask.setProductionOrderId(productionOrderRoutingOperation.getProductionOrderId());
             productionOperationTask.setPlanQuantity(BigDecimal.ZERO);
             productionOperationTask.setCompleteQuantity(BigDecimal.ZERO);
@@ -68,12 +103,118 @@
     }
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
+    public R updateRouteItem(ProductionOrderRoutingOperation productionOrderRoutingOperation) {
+        Long operationId = productionOrderRoutingOperation.getId();
+
+        // 鏇存柊宸ヨ壓璺嚎宸ュ簭
+        productionOrderRoutingOperationMapper.updateById(productionOrderRoutingOperation);
+
+        // 閲嶆柊鏌ヨ瀹屾暣璁板綍锛堝墠绔彲鑳芥病鏈変紶閫掓墍鏈夊瓧娈碉紝濡� productionOrderId锛�
+        ProductionOrderRoutingOperation updatedOperation = productionOrderRoutingOperationMapper.selectById(operationId);
+        if (updatedOperation == null) {
+            throw new ServiceException("宸ヨ壓璺嚎宸ュ簭涓嶅瓨鍦�");
+        }
+
+        // 鏌ヨ鏄惁瀛樺湪宸ュ崟
+        ProductionOperationTask productionOperationTask = productionOperationTaskMapper.selectOne(
+                new LambdaQueryWrapper<ProductionOperationTask>()
+                        .eq(ProductionOperationTask::getProductionOrderRoutingOperationId, operationId)
+                        .last("limit 1"));
+
+        // 鏍规嵁鏄惁闇�瑕佺敓浜ц繘琛屽鐞�
+        Boolean isProduction = updatedOperation.getIsProduction();
+
+        if (Boolean.TRUE.equals(isProduction)) {
+            // 闇�瑕佺敓浜э細妫�鏌ュ伐鍗曟槸鍚﹀瓨鍦紝涓嶅瓨鍦ㄥ垯鐢熸垚
+            if (productionOperationTask == null) {
+                ProductionOperationTask task = new ProductionOperationTask();
+                task.setProductionOrderRoutingOperationId(updatedOperation.getId());
+                task.setProductionOrderId(updatedOperation.getProductionOrderId());
+                // 鑾峰彇鐢熶骇璁㈠崟
+                ProductionOrder productionOrder = productionOrderMapper.selectById(updatedOperation.getProductionOrderId());
+                if (productionOrder == null) {
+                    throw new ServiceException("鐢熶骇璁㈠崟涓嶅瓨鍦�");
+                }
+
+                // 鑾峰彇璁㈠崟BOM
+                ProductionOrderBom orderBom = productionOrderBomMapper.selectOne(
+                        Wrappers.<ProductionOrderBom>lambdaQuery()
+                                .eq(ProductionOrderBom::getProductionOrderId, productionOrder.getId()));
+
+                // 纭畾鏍逛骇鍝佽鏍糏D
+                Long rootProductModelId = orderBom != null && orderBom.getProductModelId() != null
+                        ? orderBom.getProductModelId()
+                        : productionOrder.getProductModelId();
+
+                // 鑾峰彇BOM缁撴瀯鍒楄〃
+                List<ProductionBomStructure> orderBomStructureList = orderBom == null || orderBom.getId() == null
+                        ? Collections.emptyList()
+                        : productionBomStructureMapper.selectList(
+                        Wrappers.<ProductionBomStructure>lambdaQuery()
+                                .eq(ProductionBomStructure::getProductionOrderBomId, orderBom.getId())
+                                .orderByAsc(ProductionBomStructure::getId));
+
+                // 鏋勫缓宸ュ簭闇�姹傞噺鏄犲皠
+                Map<String, BigDecimal> operationDemandedQuantityMap =
+                        TaskPlanQuantityUtil.buildOperationDemandedQuantityMap(orderBomStructureList, rootProductModelId);
+
+                // 鑾峰彇宸ヨ壓璺嚎宸ュ簭锛堢敤浜庤绠楄鍒掓暟閲忥級
+                TechnologyRoutingOperation sourceOperation = technologyRoutingOperationMapper.selectById(
+                        updatedOperation.getTechnologyRoutingOperationId());
+                // 灏嗗師鏉ョ殑绉佹湁鏂规硶鏇挎崲涓鸿皟鐢ㄥ伐鍏风被
+                BigDecimal planQuantity = TaskPlanQuantityUtil.resolveTaskPlanQuantity(
+                        sourceOperation,
+                        operationDemandedQuantityMap,
+                        productionOrder,
+                        rootProductModelId);
+                task.setPlanQuantity(planQuantity);
+                task.setCompleteQuantity(BigDecimal.ZERO);
+                task.setWorkOrderNo(generateNextTaskNo());
+                task.setStatus(2);
+                productionOperationTaskMapper.insert(task);
+            }
+        } else {
+            // 涓嶉渶瑕佺敓浜э細妫�鏌ュ伐鍗曟槸鍚﹀瓨鍦�
+            if (productionOperationTask != null) {
+                validateTaskCanRemove(productionOperationTask);
+                // 娌℃湁鎶ュ伐锛屽垯鍒犻櫎宸ュ崟
+                productionOperationTaskMapper.deleteById(productionOperationTask.getId());
+            }
+        }
+
+        return R.ok();
+    }
+
+    private void validateTaskCanRemove(ProductionOperationTask task) {
+        if (task == null || task.getId() == null) {
+            return;
+        }
+        if (defaultDecimal(task.getCompleteQuantity()).compareTo(BigDecimal.ZERO) > 0) {
+            throw new ServiceException("宸ュ簭宸蹭骇鐢熸姤宸ヨ褰曪紝鏃犳硶鏍规嵁 BOM 鍙樻洿鍒犻櫎瀵瑰簲宸ュ簭蹇収");
+        }
+        long reportCount = productionProductMainMapper.selectCount(
+                Wrappers.<ProductionProductMain>lambdaQuery()
+                        .eq(ProductionProductMain::getProductionOperationTaskId, task.getId()));
+        if (reportCount > 0) {
+            throw new ServiceException("宸ュ簭宸蹭骇鐢熸姤宸ヨ褰曪紝鏃犳硶鏍规嵁 BOM 鍙樻洿鍒犻櫎瀵瑰簲宸ュ崟");
+        }
+    }
+
+    private BigDecimal defaultDecimal(BigDecimal value) {
+        return value == null ? BigDecimal.ZERO : value;
+    }
+
+    @Override
     public R deleteRouteItem(Long id) {
+        // 鍒犻櫎宸ヨ壓璺嚎
         try {
+        // 鏌ヨ骞跺噯澶囦笟鍔℃暟鎹�
             ProductionOperationTask productionOperationTask = productionOperationTaskMapper.selectOne(
                     new LambdaQueryWrapper<ProductionOperationTask>()
-                            .eq(ProductionOperationTask::getTechnologyRoutingOperationId, id)
+                            .eq(ProductionOperationTask::getProductionOrderRoutingOperationId, id)
                             .last("limit 1"));
+        // 鍙傛暟涓庡墠缃潯浠舵牎楠�
             if (productionOperationTask == null) {
                 throw new RuntimeException("鍒犻櫎澶辫触锛氭湭鎵惧埌鍏宠仈鐨勭敓浜у伐鍗�");
             }
@@ -84,6 +225,7 @@
             List<ProductionProductMain> productionProductMains = productionProductMainMapper.selectList(
                     new LambdaQueryWrapper<ProductionProductMain>()
                             .eq(ProductionProductMain::getProductionOperationTaskId, productionOperationTask.getId()));
+        // 閬嶅巻澶勭悊鏁版嵁骞剁粍瑁呯粨鏋�
             for (ProductionProductMain main : productionProductMains) {
                 productionProductMainService.removeProductMain(main.getId());
             }
@@ -94,7 +236,7 @@
                 routingId = deleteItem.getOrderRoutingId();
             }
             productionOperationTaskMapper.delete(new LambdaQueryWrapper<ProductionOperationTask>()
-                    .eq(ProductionOperationTask::getTechnologyRoutingOperationId, id));
+                    .eq(ProductionOperationTask::getProductionOrderRoutingOperationId, id));
             productionOrderRoutingOperationMapper.deleteById(id);
             if (routingId != null) {
                 List<ProductionOrderRoutingOperation> operationList = productionOrderRoutingOperationMapper.selectList(
@@ -106,6 +248,7 @@
                     ProductionOrderRoutingOperation item = operationList.get(i);
                     if (!Integer.valueOf(i + 1).equals(item.getDragSort())) {
                         item.setDragSort(i + 1);
+        // 鎸佷箙鍖栨垨杈撳嚭澶勭悊缁撴灉
                         productionOrderRoutingOperationMapper.updateById(item);
                     }
                 }
@@ -118,6 +261,7 @@
 
     @Override
     public int sortRouteItem(ProductionOrderRoutingOperation productionOrderRoutingOperation) {
+        // 鎺掑簭宸ヨ壓璺嚎
         ProductionOrderRoutingOperation oldItem = productionOrderRoutingOperationMapper.selectById(productionOrderRoutingOperation.getId());
         List<ProductionOrderRoutingOperation> operationList = productionOrderRoutingOperationMapper.selectList(
                 Wrappers.<ProductionOrderRoutingOperation>lambdaQuery()
@@ -139,4 +283,24 @@
         }
         return 0;
     }
+
+    private String generateNextTaskNo() {
+        // 鐢熸垚涓嬩竴涓敓浜у伐鍗曞彿
+        String datePrefix = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
+        String prefix = "GD" + datePrefix;
+        ProductionOperationTask lastTask = productionOperationTaskMapper.selectOne(
+                Wrappers.<ProductionOperationTask>lambdaQuery()
+                        .likeRight(ProductionOperationTask::getWorkOrderNo, prefix)
+                        .orderByDesc(ProductionOperationTask::getWorkOrderNo)
+                        .last("limit 1"));
+        int sequence = 1;
+        if (lastTask != null && lastTask.getWorkOrderNo() != null && lastTask.getWorkOrderNo().startsWith(prefix)) {
+            try {
+                sequence = Integer.parseInt(lastTask.getWorkOrderNo().substring(prefix.length())) + 1;
+            } catch (NumberFormatException ignored) {
+                sequence = 1;
+            }
+        }
+        return prefix + String.format("%03d", sequence);
+    }
 }

--
Gitblit v1.9.3