From c116ace60244d86cb1d7d9412437b7ad817e0649 Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期四, 23 七月 2026 10:12:51 +0800
Subject: [PATCH] refactor(mes): 移除供应商服务相关代码并更新测试配置

---
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/feedback/MesProFeedbackServiceImpl.java |  196 ++++++++++++++++++++++++++++++++++++++----------
 1 files changed, 154 insertions(+), 42 deletions(-)

diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/feedback/MesProFeedbackServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/feedback/MesProFeedbackServiceImpl.java
index 71f0852..49b7c45 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/feedback/MesProFeedbackServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/feedback/MesProFeedbackServiceImpl.java
@@ -6,9 +6,10 @@
 import cn.hutool.core.util.ObjectUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
-import cn.iocoder.yudao.module.mes.dal.dataobject.md.workstation.MesMdWorkstationDO;
-import cn.iocoder.yudao.module.mes.controller.admin.pro.feedback.vo.MesProFeedbackPageReqVO;
-import cn.iocoder.yudao.module.mes.controller.admin.pro.feedback.vo.MesProFeedbackSaveReqVO;
+import cn.iocoder.yudao.module.mes.controller.admin.pro.feedback.vo.*;
+import cn.iocoder.yudao.module.mes.enums.md.autocode.MesMdAutoCodeRuleCodeEnum;
+import cn.iocoder.yudao.module.mes.enums.pro.MesProFeedbackTypeEnum;
+import cn.iocoder.yudao.module.mes.service.md.autocode.MesMdAutoCodeRecordService;
 import cn.iocoder.yudao.module.mes.dal.dataobject.pro.feedback.MesProFeedbackDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProcessDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProductBomDO;
@@ -20,7 +21,6 @@
 import cn.iocoder.yudao.module.mes.dal.mysql.pro.feedback.MesProFeedbackMapper;
 import cn.iocoder.yudao.module.mes.enums.pro.MesProFeedbackStatusEnum;
 import cn.iocoder.yudao.module.mes.enums.wm.MesWmQualityStatusEnum;
-import cn.iocoder.yudao.module.mes.service.md.workstation.MesMdWorkstationService;
 import cn.iocoder.yudao.module.mes.service.pro.route.MesProRouteProcessService;
 import cn.iocoder.yudao.module.mes.service.pro.route.MesProRouteProductBomService;
 import cn.iocoder.yudao.module.mes.service.pro.task.MesProTaskService;
@@ -28,13 +28,18 @@
 import cn.iocoder.yudao.module.mes.service.wm.itemconsume.MesWmItemConsumeService;
 import cn.iocoder.yudao.module.mes.service.wm.productproduce.MesWmProductProduceLineService;
 import cn.iocoder.yudao.module.mes.service.wm.productproduce.MesWmProductProduceService;
+import cn.iocoder.yudao.module.mes.api.mps.MesProMpsApi;
+import cn.iocoder.yudao.module.mes.api.mps.dto.MesProMpsRespDTO;
+import cn.iocoder.yudao.module.mes.api.event.ProductionFinishedEvent;
 import jakarta.annotation.Resource;
+import org.springframework.context.ApplicationEventPublisher;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
 
 import java.math.BigDecimal;
+import java.time.LocalDateTime;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
@@ -61,8 +66,6 @@
     @Resource
     private MesProRouteProductBomService routeProductBomService;
     @Resource
-    private MesMdWorkstationService workstationService;
-    @Resource
     @Lazy // 閬垮厤寰幆渚濊禆
     private MesProTaskService taskService;
     @Resource
@@ -71,6 +74,12 @@
     private MesWmProductProduceService productProduceService;
     @Resource
     private MesWmProductProduceLineService produceLineService;
+    @Resource
+    private MesProMpsApi mpsApi;
+    @Resource
+    private MesMdAutoCodeRecordService autoCodeRecordService;
+    @Resource
+    private ApplicationEventPublisher eventPublisher;
 
     @Override
     public Long createFeedback(MesProFeedbackSaveReqVO createReqVO) {
@@ -191,9 +200,14 @@
             }
         }
 
-        // 4. 鍏抽敭宸ュ簭锛氱敓鎴愪骇鍑哄崟锛屽苟鏍规嵁鏄惁闇�瑕佹楠屽喅瀹氬叆搴撴柟寮�
+        // 5. 鍏堟洿鏂版姤宸ョ姸鎬佷负宸插畬鎴愶紙纭繚 checkAndFinishMps 妫�鏌ユ椂褰撳墠鎶ュ伐宸叉爣璁板畬鎴愶級
+        feedbackMapper.updateById(new MesProFeedbackDO().setId(id)
+                .setStatus(MesProFeedbackStatusEnum.FINISHED.getStatus())
+                .setUncheckQuantity(BigDecimal.ZERO));
+
+        // 6. 鍏抽敭宸ュ簭锛氱敓鎴愪骇鍑哄崟锛屽苟鏍规嵁鏄惁闇�瑕佹楠屽喅瀹氬叆搴撴柟寮�
         if (keyFlag) {
-            // 4.1 闇�瑕佹楠岋細鐢熸垚浜у嚭鍗曪紙璐ㄩ噺鐘舵��=寰呮楠岋級锛屾洿鏂版姤宸ョ姸鎬佷负寰呮楠岋紝绛夎川妫�瀹屾垚鍥炶皟鍚庡啀鍏ュ簱
+            // 6.1 闇�瑕佹楠岋細鐢熸垚浜у嚭鍗曪紙璐ㄩ噺鐘舵��=寰呮楠岋級锛屾洿鏂版姤宸ョ姸鎬佷负寰呮楠岋紝绛夎川妫�瀹屾垚鍥炶皟鍚庡啀鍏ュ簱
             if (checkFlag) {
                 // 瀹屾垚鏃跺洖璋冭锛歁esQcIpqcServiceImpl#finishIpqc 鈫� splitPendingAndFinishProduce + completeFeedbackFromIpqc
                 productProduceService.generateProductProduce(feedback, true);
@@ -201,16 +215,20 @@
                         .setStatus(MesProFeedbackStatusEnum.UNCHECK.getStatus()));
                 return false;
             }
-            // 4.2 鏃犻渶妫�楠岋細鐢熸垚浜у嚭鍗曪紙鎸夊悎鏍�/涓嶅悎鏍兼媶琛岋級锛岀洿鎺ュ畬鎴愬叆搴擄紝骞舵洿鏂颁换鍔�/宸ュ崟鐨勫凡鐢熶骇鏁伴噺
+            // 6.2 鏃犻渶妫�楠岋細鐢熸垚浜у嚭鍗曪紙鎸夊悎鏍�/涓嶅悎鏍兼媶琛岋級锛岀洿鎺ュ畬鎴愬叆搴擄紝骞舵洿鏂颁换鍔�/宸ュ崟鐨勫凡鐢熶骇鏁伴噺
             MesWmProductProduceDO produce = productProduceService.generateProductProduce(feedback, false);
             productProduceService.finishProductProduce(produce.getId());
             updateTaskAndWorkOrderByFeedback(feedback);
+        } else {
+            // 6.3 闈炲叧閿伐搴忥細鍙洿鏂颁换鍔$殑宸茬敓浜ф暟閲忥紙宸ュ崟涓嶆洿鏂帮紝宸ュ崟鍙湅鍏抽敭宸ュ簭浜у嚭锛�
+            taskService.updateProducedQuantity(feedback.getTaskId(),
+                    feedback.getFeedbackQuantity(),
+                    ObjectUtil.defaultIfNull(feedback.getQualifiedQuantity(), BigDecimal.ZERO),
+                    ObjectUtil.defaultIfNull(feedback.getUnqualifiedQuantity(), BigDecimal.ZERO));
+            // 6.4 闈炲叧閿伐搴忎篃闇�瑕佹鏌� MPS 瀹屾垚鐘舵�侊紙鎵�鏈夊伐搴忔姤宸ュ畬鎴愭墠绠楀畬鎴愶級
+            checkAndPublishProductionFinished(feedback.getWorkOrderId());
         }
 
-        // 5. 闈炲叧閿伐搴� / 鍏抽敭闈炶川妫�宸ュ簭锛氱洿鎺ュ畬鎴愶紙娓呴浂 uncheckQuantity 闃叉 !key+check 鐣欒剰鏁版嵁锛�
-        feedbackMapper.updateById(new MesProFeedbackDO().setId(id)
-                .setStatus(MesProFeedbackStatusEnum.FINISHED.getStatus())
-                .setUncheckQuantity(BigDecimal.ZERO));
         return true; // 宸插畬鎴�
     }
 
@@ -245,6 +263,34 @@
         // 3. 鏇存柊宸ュ崟鐨勫凡鐢熶骇鏁伴噺
         workOrderService.updateProducedQuantity(feedback.getWorkOrderId(),
                 feedback.getFeedbackQuantity());
+
+        // 4. 鏇存柊 MPS 鐨勫凡鐢熶骇鏁伴噺锛堝鏋滄槸閿�鍞鍗曟潵婧愶級
+        MesProMpsRespDTO mps = mpsApi.getMpsByWorkOrderId(feedback.getWorkOrderId());
+        if (mps != null) {
+            mpsApi.updateMpsProducedQuantity(mps.getId(), feedback.getFeedbackQuantity());
+        }
+
+        // 5. 妫�鏌ュ苟鍙戝竷鐢熶骇瀹屾垚浜嬩欢
+        checkAndPublishProductionFinished(feedback.getWorkOrderId());
+    }
+
+    /**
+     * 妫�鏌ュ苟鍙戝竷鐢熶骇瀹屾垚浜嬩欢
+     */
+    private void checkAndPublishProductionFinished(Long workOrderId) {
+        // 1. 鑾峰彇宸ュ崟鍏宠仈鐨� MPS
+        MesProMpsRespDTO mps = mpsApi.getMpsByWorkOrderId(workOrderId);
+        if (mps == null || mps.getSaleOrderId() == null) {
+            return; // 闈為攢鍞鍗曟潵婧愮殑宸ュ崟锛岃烦杩�
+        }
+
+        // 2. 妫�鏌ュ苟鑷姩瀹屾垚 MPS锛堝鏋滄弧瓒虫潯浠讹級
+        mpsApi.checkAndFinishMps(mps.getId());
+
+        // 3. 妫�鏌ラ攢鍞鍗曟墍鏈夌敓浜ф槸鍚﹀畬鎴�
+        if (mpsApi.checkSaleOrderProductionFinished(mps.getSaleOrderId())) {
+            eventPublisher.publishEvent(new ProductionFinishedEvent(mps.getSaleOrderId(), java.time.LocalDateTime.now()));
+        }
     }
 
     // ==================== 鏍¢獙鏂规硶 ====================
@@ -277,23 +323,30 @@
     /**
      * 鏍¢獙鎶ュ伐鍗曠殑涓氬姟鏁版嵁锛堝垱寤� & 淇敼鍏辩敤锛�
      *
+     * <p>浠ョ敓浜т换鍔′负鏍稿績锛氬墠绔彧闇�浼� taskId锛寃orkOrderId銆乺outeId銆乸rocessId銆乮temId銆亀orkstationId
+     * 浠庝换鍔¤嚜鍔ㄥ~鍏咃紝鏃犻渶鍓嶇閲嶅浼犲叆銆�
+     *
      * @param reqVO 鎶ュ伐璇锋眰
      * @return 鍏宠仈鐨勭敓浜т换鍔�
      */
     private MesProTaskDO validateFeedbackData(MesProFeedbackSaveReqVO reqVO) {
-        // 1. 鏍¢獙宸ヤ綔绔欏瓨鍦�
-        MesMdWorkstationDO workstation = workstationService.validateWorkstationExists(reqVO.getWorkstationId());
-        if (ObjUtil.notEqual(workstation.getProcessId(), reqVO.getProcessId())) {
-            throw exception(PRO_WORKSTATION_PROCESS_MISMATCH);
-        }
+        // 1. 鏍¢獙浠诲姟瀛樺湪涓旀湭缁堟��
+        MesProTaskDO task = taskService.validateTaskNotFinished(reqVO.getTaskId());
 
-        // 2.1 鏍¢獙宸ヨ壓璺嚎 + 宸ュ簭閰嶇疆鏈夋晥
+        // 2. 浠庝换鍔¤嚜鍔ㄥ~鍏呭叧鑱斿瓧娈碉紙鍓嶇鏃犻渶浼犲叆锛屽悗绔粺涓�浠庝换鍔¤幏鍙栵級
+        reqVO.setWorkOrderId(task.getWorkOrderId());
+        reqVO.setRouteId(task.getRouteId());
+        reqVO.setProcessId(task.getProcessId());
+        reqVO.setItemId(task.getItemId());
+        reqVO.setWorkstationId(task.getWorkstationId());
+
+        // 3. 鏍¢獙宸ヨ壓璺嚎 + 宸ュ簭閰嶇疆鏈夋晥
         MesProRouteProcessDO routeProcess = routeProcessService.getRouteProcessByRouteIdAndProcessId(
-                reqVO.getRouteId(), reqVO.getProcessId());
+                task.getRouteId(), task.getProcessId());
         if (routeProcess == null) {
             throw exception(PRO_FEEDBACK_ROUTE_PROCESS_INVALID);
         }
-        // 2.2 鏍¢獙鏁伴噺
+        // 4.1 鏍¢獙鏁伴噺
         boolean checkFlag = Boolean.TRUE.equals(routeProcess.getCheckFlag());
         if (checkFlag) {
             // 闇�瑕佹楠岋細鍙渶濉姤宸ユ暟閲忥紝涓斿繀椤� > 0
@@ -310,33 +363,92 @@
             }
         }
 
-        // 3. 鏍¢獙宸ュ崟宸茬‘璁�
-        MesProWorkOrderDO workOrder = workOrderService.validateWorkOrderConfirmed(reqVO.getWorkOrderId());
-        if (ObjUtil.notEqual(workOrder.getProductId(), reqVO.getItemId())) {
-            throw exception(PRO_WORK_ORDER_PRODUCT_MISMATCH);
-        }
-
-        // 4. 鏍¢獙浠诲姟瀛樺湪涓旀湭缁堟�侊紙宸插畬鎴�/宸插彇娑堬級锛屽苟杩斿洖浠诲姟鐢ㄤ簬鍐椾綑 itemId
-        MesProTaskDO task = taskService.validateTaskNotFinished(reqVO.getTaskId());
-        validateTaskRelation(task, workstation, workOrder, reqVO);
         return task;
     }
 
-    private void validateTaskRelation(MesProTaskDO task, MesMdWorkstationDO workstation,
-                                      MesProWorkOrderDO workOrder, MesProFeedbackSaveReqVO reqVO) {
-        if (ObjUtil.notEqual(task.getWorkOrderId(), workOrder.getId())) {
-            throw exception(PRO_TASK_WORK_ORDER_MISMATCH);
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public MesProFeedbackQuickCreateRespVO quickCreateFeedback(MesProFeedbackQuickCreateReqVO reqVO) {
+        // 1. 鏍¢獙浠诲姟瀛樺湪涓旈潪缁堟��
+        MesProTaskDO task = taskService.validateTaskNotFinished(reqVO.getTaskId());
+        // 2. 鏍¢獙宸ヨ壓璺嚎宸ュ簭閰嶇疆
+        MesProRouteProcessDO routeProcess = routeProcessService.getRouteProcessByRouteIdAndProcessId(
+                task.getRouteId(), task.getProcessId());
+        if (routeProcess == null) {
+            throw exception(PRO_FEEDBACK_ROUTE_PROCESS_INVALID);
         }
-        if (ObjUtil.notEqual(task.getWorkstationId(), workstation.getId())) {
-            throw exception(PRO_TASK_WORKSTATION_MISMATCH);
+        // 3. 鏍¢獙鏁伴噺
+        boolean checkFlag = Boolean.TRUE.equals(routeProcess.getCheckFlag());
+        if (checkFlag) {
+            if (reqVO.getFeedbackQuantity() == null
+                    || reqVO.getFeedbackQuantity().compareTo(BigDecimal.ZERO) <= 0) {
+                throw exception(PRO_FEEDBACK_QUANTITY_MUST_POSITIVE);
+            }
+        } else {
+            BigDecimal qualified = ObjectUtil.defaultIfNull(reqVO.getQualifiedQuantity(), BigDecimal.ZERO);
+            BigDecimal unqualified = ObjectUtil.defaultIfNull(reqVO.getUnqualifiedQuantity(), BigDecimal.ZERO);
+            if (qualified.add(unqualified).compareTo(BigDecimal.ZERO) <= 0) {
+                throw exception(PRO_FEEDBACK_QUALIFIED_UNQUALIFIED_REQUIRED);
+            }
         }
-        if (ObjUtil.notEqual(task.getRouteId(), reqVO.getRouteId())
-                || ObjUtil.notEqual(task.getProcessId(), reqVO.getProcessId())) {
-            throw exception(PRO_TASK_ROUTE_PROCESS_MISMATCH);
+        // 4. 鏋勫缓鎶ュ伐DO
+        MesProFeedbackDO feedback = new MesProFeedbackDO()
+                .setCode(autoCodeRecordService.generateAutoCode(MesMdAutoCodeRuleCodeEnum.PRO_FEEDBACK_CODE.getCode()))
+                .setType(MesProFeedbackTypeEnum.SELF.getType())
+                .setWorkstationId(task.getWorkstationId())
+                .setRouteId(task.getRouteId())
+                .setProcessId(task.getProcessId())
+                .setWorkOrderId(task.getWorkOrderId())
+                .setTaskId(reqVO.getTaskId())
+                .setItemId(task.getItemId())
+                .setFeedbackQuantity(reqVO.getFeedbackQuantity())
+                .setQualifiedQuantity(reqVO.getQualifiedQuantity())
+                .setUnqualifiedQuantity(reqVO.getUnqualifiedQuantity())
+                .setScheduledQuantity(task.getQuantity())
+                .setFeedbackTime(LocalDateTime.now())
+                .setStatus(MesProFeedbackStatusEnum.APPROVING.getStatus())
+                .setRemark(reqVO.getRemark());
+        feedbackMapper.insert(feedback);
+        // 5. 杩斿洖缁撴灉
+        MesProWorkOrderDO workOrder = workOrderService.getWorkOrder(task.getWorkOrderId());
+        return new MesProFeedbackQuickCreateRespVO()
+                .setFeedbackId(feedback.getId())
+                .setTaskStatus(task.getStatus())
+                .setWorkOrderStatus(workOrder != null ? workOrder.getStatus() : null);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public MesProFeedbackBatchCreateRespVO batchCreateFeedback(MesProFeedbackBatchCreateReqVO reqVO) {
+        List<MesProFeedbackBatchCreateRespVO.BatchResult> results = new java.util.ArrayList<>();
+        int successCount = 0;
+        int failCount = 0;
+        for (Long taskId : reqVO.getTaskIds()) {
+            try {
+                MesProFeedbackQuickCreateReqVO singleReq = new MesProFeedbackQuickCreateReqVO();
+                singleReq.setTaskId(taskId);
+                singleReq.setFeedbackQuantity(reqVO.getFeedbackQuantity());
+                singleReq.setQualifiedQuantity(reqVO.getQualifiedQuantity());
+                singleReq.setUnqualifiedQuantity(reqVO.getUnqualifiedQuantity());
+                singleReq.setRemark(reqVO.getRemark());
+                MesProFeedbackQuickCreateRespVO resp = quickCreateFeedback(singleReq);
+                results.add(new MesProFeedbackBatchCreateRespVO.BatchResult()
+                        .setTaskId(taskId)
+                        .setSuccess(true)
+                        .setFeedbackId(resp.getFeedbackId()));
+                successCount++;
+            } catch (Exception e) {
+                results.add(new MesProFeedbackBatchCreateRespVO.BatchResult()
+                        .setTaskId(taskId)
+                        .setSuccess(false)
+                        .setErrorMsg(e.getMessage()));
+                failCount++;
+            }
         }
-        if (ObjUtil.notEqual(task.getItemId(), reqVO.getItemId())) {
-            throw exception(PRO_TASK_ITEM_MISMATCH);
-        }
+        return new MesProFeedbackBatchCreateRespVO()
+                .setSuccessCount(successCount)
+                .setFailCount(failCount)
+                .setResults(results);
     }
 
     @Override

--
Gitblit v1.9.3