From bf5f52656e128f578ed42c7979c31cf4b476ce46 Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期六, 31 十月 2026 19:04:40 +0800
Subject: [PATCH] feat: 优化业务导入及工艺流程管理

---
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/task/MesProTaskServiceImpl.java |   96 ++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 88 insertions(+), 8 deletions(-)

diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/task/MesProTaskServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/task/MesProTaskServiceImpl.java
index 1b7464f..b723f98 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/task/MesProTaskServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/task/MesProTaskServiceImpl.java
@@ -2,6 +2,10 @@
 
 import cn.hutool.core.collection.CollUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
+import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
+import cn.iocoder.yudao.module.mes.service.pd.processparamtemplate.MesPdProcessParamTemplateService;
+import cn.iocoder.yudao.module.mes.service.pro.feedback.dto.MesTaskParamSnapshot;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.module.mes.controller.admin.pro.task.vo.MesProTaskAutoGeneratePreviewRespVO;
 import cn.iocoder.yudao.module.mes.controller.admin.pro.task.vo.MesProTaskAutoGenerateReqVO;
@@ -45,7 +49,9 @@
 import java.time.LocalDateTime;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@@ -74,6 +80,8 @@
 
     @Resource
     private MesProTaskMapper taskMapper;
+    @Resource
+    private MesPdProcessParamTemplateService paramTemplateService;
 
     @Resource
     private MesProFeedbackMapper feedbackMapper;
@@ -114,6 +122,7 @@
     private MesCalTeamService teamService;
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public Long createTask(MesProTaskSaveReqVO createReqVO) {
         // 1. 鏍¢獙鍏宠仈鏁版嵁瀛樺湪
         MesProWorkOrderDO workOrder = workOrderService.validateWorkOrderExists(createReqVO.getWorkOrderId());
@@ -127,11 +136,7 @@
         if (itemId == null) {
             MesProRouteProcessDO routeProcess = routeProcessService
                     .getRouteProcessByRouteIdAndProcessId(createReqVO.getRouteId(), createReqVO.getProcessId());
-            if (routeProcess != null && routeProcess.getOutputItemId() != null) {
-                itemId = Long.valueOf(routeProcess.getOutputItemId().split(",")[0].trim());
-            } else {
-                itemId = workOrder.getProductId();
-            }
+            itemId = resolveTaskItemId(routeProcess, workOrder.getProductId());
         }
         MesMdItemDO item = itemService.validateItemExists(itemId);
 
@@ -145,14 +150,17 @@
             task.setClientId(workOrder.getClientId());
         }
         // 2.2 鎻掑叆
+        freezeTaskParamConfig(task);
         taskMapper.insert(task);
         return task.getId();
     }
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public void updateTask(MesProTaskSaveReqVO updateReqVO) {
-        // 1.1 鏍¢獙瀛樺湪
-        MesProTaskDO task = validateTaskExists(updateReqVO.getId());
+        MesProTaskDO task = taskMapper.selectOne(new LambdaQueryWrapperX<MesProTaskDO>()
+                .eq(MesProTaskDO::getId, updateReqVO.getId()).last("FOR UPDATE"));
+        if (task == null) throw exception(PRO_TASK_NOT_EXISTS);
         // 1.2 鏍¢獙鍏宠仈鏁版嵁瀛樺湪
         if (updateReqVO.getWorkOrderId() != null) {
             workOrderService.validateWorkOrderExists(updateReqVO.getWorkOrderId());
@@ -178,7 +186,40 @@
         // 2. 鏇存柊
         MesProTaskDO updateObj = BeanUtils.toBean(updateReqVO, MesProTaskDO.class)
                 .setName(buildTaskName(item, quantity));
+        if (updateReqVO.getProcessId() != null && !updateReqVO.getProcessId().equals(task.getProcessId())) {
+            if (feedbackMapper.selectCountByTaskId(task.getId()) > 0) throw exception(PRO_TASK_HAS_FEEDBACK);
+            freezeTaskParamConfig(updateObj);
+        }
         taskMapper.updateById(updateObj);
+    }
+
+    /** 浠庡伐搴忓拰妯℃澘澶嶅埗瀹氫箟锛屽悗缁ā鏉跨淮鎶や笉鏀瑰彉宸叉帓浜т换鍔°�� */
+    private void freezeTaskParamConfig(MesProTaskDO task) {
+        var process = processService.getProcess(task.getProcessId());
+        if (process == null) throw exception(cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.PRO_PROCESS_NOT_EXISTS);
+        int mode = process.getParamCollectMode() == null ? 0 : process.getParamCollectMode();
+        task.setParamCollectMode(mode);
+        task.setParamTemplateSnapshot("");
+        task.setParamSharedSnapshot("");
+        if (mode == 0) return;
+        if ((mode != 1 && mode != 2) || process.getParamTemplateId() == null)
+            throw exception(cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.PRO_PROCESS_PARAM_CONFIG_INVALID);
+        var template = paramTemplateService.validateProcessParamTemplateExists(process.getParamTemplateId());
+        var details = paramTemplateService.getProcessParamTemplateDetailListByTemplateId(template.getId());
+        if (CollUtil.isEmpty(details)) throw exception(cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.PRO_WORK_ORDER_PARAM_RECORD_TEMPLATE_NO_DETAIL);
+        MesTaskParamSnapshot snapshot = new MesTaskParamSnapshot();
+        snapshot.setTemplateId(template.getId());
+        snapshot.setTemplateCode(template.getTemplateCode());
+        snapshot.setTemplateName(template.getTemplateName());
+        List<MesTaskParamSnapshot.Detail> frozenDetails = BeanUtils.toBean(details, MesTaskParamSnapshot.Detail.class);
+        for (MesTaskParamSnapshot.Detail detail : frozenDetails) {
+            if (detail.getUnitMeasureId() != null) {
+                var unit = unitMeasureService.getUnitMeasure(detail.getUnitMeasureId());
+                if (unit != null) detail.setUnitMeasureName(unit.getName());
+            }
+        }
+        snapshot.setDetails(frozenDetails);
+        task.setParamTemplateSnapshot(JsonUtils.toJsonString(snapshot));
     }
 
     /**
@@ -256,6 +297,30 @@
         return routeProcesses;
     }
 
+    /**
+     * 浠诲姟浜у嚭鐗╂枡锛氫紭鍏堝彇宸ュ簭鍦ㄥ綋鍓嶄骇鍝佷笅鐨勪骇鍑猴紙鎸夊綊灞炶繃婊わ級锛屾病鏈変骇鍑烘椂鍙栧伐鍗曟垚鍝�
+     */
+    private Long resolveTaskItemId(MesProRouteProcessDO routeProcess, Long productId) {
+        if (routeProcess == null) {
+            return productId;
+        }
+        if (routeProcess.getId() != null) {
+            // 宸ヨ壓璺嚎妯℃澘锛氭寜浜у嚭褰掑睘杩囨护鍑哄綋鍓嶄骇鍝佺殑浜у嚭
+            List<Long> outputIds = routeProcessService
+                    .getOutputItemIdsByRouteProcessId(routeProcess.getId(), productId);
+            if (outputIds != null) {
+                // 鏈夊綊灞為厤缃細璇ヤ骇鍝佹棤浜у嚭鏃跺彇宸ュ崟鎴愬搧锛沶ull 琛ㄧず瀛橀噺鏃犲綊灞炴暟鎹紝缁х画璧拌仛鍚堝厹搴�
+                return CollUtil.isNotEmpty(outputIds) ? outputIds.get(0) : productId;
+            }
+        }
+        // 宸ュ崟宸ュ簭蹇収 / 瀛橀噺鏃犲綊灞炴暟鎹細浜у嚭宸叉寜浜у搧杩囨护锛屽彇绗竴涓�
+        String outputItemId = routeProcess.getOutputItemId();
+        if (outputItemId != null && !outputItemId.isBlank()) {
+            return Long.valueOf(outputItemId.split(",")[0].trim());
+        }
+        return productId;
+    }
+
     @Override
     public void deleteTask(Long id) {
         // 1. 鏍¢獙瀛樺湪涓旈潪缁堟��
@@ -286,6 +351,20 @@
     @Override
     public PageResult<MesProTaskDO> getPendingFeedbackPage(MesProTaskPageReqVO pageReqVO) {
         return taskMapper.selectPendingFeedbackPage(pageReqVO);
+    }
+
+    @Override
+    public Map<Long, Long> getPendingFeedbackCountByWorkstation() {
+        List<Map<String, Object>> rows = taskMapper.selectPendingFeedbackCountByWorkstation();
+        Map<Long, Long> result = new HashMap<>(rows.size());
+        for (Map<String, Object> row : rows) {
+            Object workstationId = row.get("workstation_id");
+            Object count = row.get("pending_count");
+            if (workstationId instanceof Number && count instanceof Number) {
+                result.put(((Number) workstationId).longValue(), ((Number) count).longValue());
+            }
+        }
+        return result;
     }
 
     @Override
@@ -443,7 +522,7 @@
         List<Long> taskIds = new java.util.ArrayList<>();
         for (MesProRouteProcessDO rp : routeProcesses) {
             cn.iocoder.yudao.module.mes.dal.dataobject.pro.process.MesProProcessDO proc = procMap.get(rp.getProcessId());
-            Long itemId = rp.getOutputItemId() != null ? Long.valueOf(rp.getOutputItemId().split(",")[0].trim()) : workOrder.getProductId();
+            Long itemId = resolveTaskItemId(rp, workOrder.getProductId());
             cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO item = itemService.validateItemExists(itemId);
             MesProTaskDO task = new MesProTaskDO()
                     .setWorkOrderId(workOrder.getId())
@@ -456,6 +535,7 @@
                     .setStatus(MesProTaskStatusEnum.PREPARE.getStatus())
                     .setClientId(workOrder.getClientId())
                     .setColorCode(rp.getColorCode());
+            freezeTaskParamConfig(task);
             taskMapper.insert(task);
             taskIds.add(task.getId());
         }

--
Gitblit v1.9.3