From ccdebc5369c108e6616550bfbe1cd47ec1e05813 Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期一, 09 十一月 2026 11:44:31 +0800
Subject: [PATCH] feat(bpm): 接入询价单与项目用印审批流程

---
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/feedback/MesProFeedbackServiceImpl.java |   60 ++++++++++++++++++++++++++++++++++++++++++++++++++----------
 1 files changed, 50 insertions(+), 10 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 ded280e..cb90136 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
@@ -4,11 +4,14 @@
 import cn.hutool.core.util.ObjUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import cn.iocoder.yudao.framework.common.exception.ServiceException;
 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.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
+import org.flowable.engine.repository.ProcessDefinition;
 import cn.iocoder.yudao.module.mes.controller.admin.pro.feedback.vo.*;
 import cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants;
 import cn.iocoder.yudao.module.mes.enums.md.autocode.MesMdAutoCodeRuleCodeEnum;
@@ -76,6 +79,7 @@
 import java.util.List;
 import java.util.LinkedHashSet;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Set;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@@ -90,6 +94,8 @@
 @Validated
 @lombok.extern.slf4j.Slf4j
 public class MesProFeedbackServiceImpl implements MesProFeedbackService {
+
+    private static final String FEEDBACK_APPROVE_CATEGORY_CODE = "mes_pro_feedback_audit";
 
     @Resource
     private MesProFeedbackEquipmentService equipmentService;
@@ -147,6 +153,8 @@
     private MdmItemBatchConfigApi itemBatchConfigApi;
     @Resource
     private cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi processInstanceApi;
+    @Resource
+    private BpmProcessDefinitionService bpmProcessDefinitionService;
 
     @Override
     @Transactional(rollbackFor = Exception.class)
@@ -267,16 +275,28 @@
         }
 
         MesProWorkOrderDO workOrder = workOrderService.getWorkOrder(feedback.getWorkOrderId());
+        if (workOrder != null && Boolean.TRUE.equals(workOrder.getFeedbackApprove())
+                && StrUtil.isBlank(workOrder.getProcessDefinitionKey())) {
+            throw exception(PRO_FEEDBACK_APPROVAL_PROCESS_KEY_REQUIRED);
+        }
 
         // 1.2 鎶ュ伐涓庤川妫�鍒嗙锛氭彁浜ゆ姤宸ヤ笉鍐嶈嚜鍔ㄧ敓鎴愯繃绋嬫楠屽崟锛岃川妫�鐢辫川妫�閮ㄩ棬鎵嬪伐寤哄崟
         if (!processInstanceApi.isGlobalAutoApprove() && workOrder != null
                 && Boolean.TRUE.equals(workOrder.getFeedbackApprove())
-                && cn.hutool.core.util.StrUtil.isNotBlank(workOrder.getProcessDefinitionKey())) {
+                && StrUtil.isNotBlank(workOrder.getProcessDefinitionKey())) {
+            ProcessDefinition processDefinition = bpmProcessDefinitionService
+                    .getActiveProcessDefinition(workOrder.getProcessDefinitionKey());
+            if (processDefinition == null || bpmProcessDefinitionService
+                    .getProcessDefinitionInfoListByCategory(FEEDBACK_APPROVE_CATEGORY_CODE).stream()
+                    .noneMatch(info -> Objects.equals(info.getProcessDefinitionId(), processDefinition.getId()))) {
+                throw exception(PRO_FEEDBACK_APPROVAL_PROCESS_KEY_INVALID);
+            }
             // 2. 鏇存柊鐘舵�佷负瀹℃壒涓紝骞跺惎鍔ㄦ祦绋�
             String processInstanceId = processInstanceApi.createProcessInstance(cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId(),
                     new cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO()
                             .setProcessDefinitionKey(workOrder.getProcessDefinitionKey())
-                            .setBusinessKey(String.valueOf(id)));
+                            .setBusinessKey(String.valueOf(id))
+                            .setVariables(Map.of("businessNo", feedback.getCode())));
 
             feedbackMapper.updateById(new MesProFeedbackDO().setId(id)
                     .setStatus(MesProFeedbackStatusEnum.APPROVING.getStatus())
@@ -292,8 +312,11 @@
             }
 
             // 3. 鏇存柊鐘舵�佷负瀹℃壒涓紝鐒跺悗鐩存帴閫氳繃瀹℃壒
-            feedbackMapper.updateById(new MesProFeedbackDO().setId(id)
-                    .setStatus(MesProFeedbackStatusEnum.APPROVING.getStatus()));
+            feedbackMapper.update(null, new LambdaUpdateWrapper<MesProFeedbackDO>()
+                    .eq(MesProFeedbackDO::getId, id)
+                    .set(MesProFeedbackDO::getStatus, MesProFeedbackStatusEnum.APPROVING.getStatus())
+                    .set(MesProFeedbackDO::getProcessInstanceId, null)
+                    .set(MesProFeedbackDO::getProcessDefinitionKey, null));
             MesProFeedbackApproveReqVO approveReqVO = cn.iocoder.yudao.framework.common.util.object.BeanUtils.toBean(reqVO, MesProFeedbackApproveReqVO.class);
             // 鑷姩瀹℃壒锛氳繃绋嬫楠屽崟鍒氱敓鎴愬皻鏈~鍐欙紝涓嶅仛璐ㄦ宸ヨ祫鍓嶇疆鏍¢獙锛堣川閲忚皟鏁寸暀绌猴級
             approveFeedback(approveReqVO, false);
@@ -329,21 +352,29 @@
                  reqVO.setLotNumber(reason);
                }
             }
-            approveFeedback(reqVO);
+            // BPM 鍥炶皟鏃舵祦绋嬪疄渚嬩粛鍦ㄨ繍琛岋紝蹇呴』璧板唴閮ㄦ柟娉曪紝涓嶈兘琚�屽凡鍙戣捣娴佺▼銆嶇殑鏍¢獙鎷︿綇
+            doApproveFeedback(reqVO, feedback, true);
         } else if (cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceStatusEnum.REJECT.getStatus().equals(bpmResult) ||
                    cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceStatusEnum.CANCEL.getStatus().equals(bpmResult)) {
-            rejectFeedback(id);
+            doRejectFeedback(id);
         }
     }
 
     @Override
     @Transactional(rollbackFor = Exception.class)
     public void rejectFeedback(Long id) {
-        equipmentService.lock();
         // 1. 鏍¢獙瀛樺湪 + 瀹℃壒涓姸鎬�
-        validateFeedbackStatusApproving(id);
+        MesProFeedbackDO feedback = validateFeedbackStatusApproving(id);
+        // 1.1 宸插彂璧峰鎵规祦绋嬬殑鎶ュ伐鍗曞彧鑳界敱瀹℃壒浜洪�氳繃銆屽緟鍔炰换鍔°�嶅鐞嗭紝閬垮厤涓氬姟鎺ュ彛缁曡繃娴佺▼
+        if (StrUtil.isNotBlank(feedback.getProcessInstanceId())) {
+            throw exception(PRO_FEEDBACK_APPROVAL_HANDLE_IN_BPM);
+        }
+        doRejectFeedback(id);
+    }
 
-        // 2. 鏇存柊鐘舵�佷负鑽夌
+    private void doRejectFeedback(Long id) {
+        equipmentService.lock();
+        // 1. 鏇存柊鐘舵�佷负鑽夌
         feedbackMapper.updateById(new MesProFeedbackDO().setId(id)
                 .setStatus(MesProFeedbackStatusEnum.PREPARE.getStatus()));
     }
@@ -355,9 +386,18 @@
     }
 
     private boolean approveFeedback(MesProFeedbackApproveReqVO reqVO, boolean enforceQualityGate) {
-        equipmentService.lock();
         // 1.1 鏍¢獙瀛樺湪 + 瀹℃壒涓姸鎬�
         MesProFeedbackDO feedback = validateFeedbackStatusApproving(reqVO.getId());
+        // 1.2 宸插彂璧峰鎵规祦绋嬬殑鎶ュ伐鍗曞彧鑳界敱瀹℃壒浜洪�氳繃銆屽緟鍔炰换鍔°�嶅鐞嗭紝閬垮厤涓氬姟鎺ュ彛缁曡繃娴佺▼
+        if (StrUtil.isNotBlank(feedback.getProcessInstanceId())) {
+            throw exception(PRO_FEEDBACK_APPROVAL_HANDLE_IN_BPM);
+        }
+        return doApproveFeedback(reqVO, feedback, enforceQualityGate);
+    }
+
+    private boolean doApproveFeedback(MesProFeedbackApproveReqVO reqVO, MesProFeedbackDO feedback,
+                                      boolean enforceQualityGate) {
+        equipmentService.lock();
         equipmentService.validateApproval(feedback);
         try (var equipmentScope = equipmentService.beginApproval(feedback)) {
             return approveValidatedFeedback(reqVO, feedback, enforceQualityGate);

--
Gitblit v1.9.3