From 5421b8af862890dcf187c2ad5ece55423959ba85 Mon Sep 17 00:00:00 2001
From: liu <2021943741@qq.com>
Date: 星期五, 23 十月 2026 19:27:14 +0800
Subject: [PATCH] feat(bpm): 全部业务审批流改回 BPM,审批统一进入协同办公

---
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pd/techconfirm/ProductTechConfirmServiceImpl.java |  103 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 101 insertions(+), 2 deletions(-)

diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pd/techconfirm/ProductTechConfirmServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pd/techconfirm/ProductTechConfirmServiceImpl.java
index 07a031f..8f03254 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pd/techconfirm/ProductTechConfirmServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pd/techconfirm/ProductTechConfirmServiceImpl.java
@@ -1,8 +1,17 @@
 package cn.iocoder.yudao.module.mes.service.pd.techconfirm;
 
+import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.StrUtil;
+import cn.iocoder.yudao.framework.common.exception.ServiceException;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi;
+import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
+import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskStatusEnum;
+import cn.iocoder.yudao.module.crm.api.customer.CrmCustomerApi;
+import cn.iocoder.yudao.module.crm.api.customer.dto.CrmCustomerRespDTO;
+import cn.iocoder.yudao.module.mes.controller.admin.pd.techconfirm.vo.ProductTechConfirmImportExcelVO;
+import cn.iocoder.yudao.module.mes.controller.admin.pd.techconfirm.vo.ProductTechConfirmImportRespVO;
 import cn.iocoder.yudao.module.mes.controller.admin.pd.techconfirm.vo.ProductTechConfirmPageReqVO;
 import cn.iocoder.yudao.module.mes.controller.admin.pd.techconfirm.vo.ProductTechConfirmSaveReqVO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.pd.techconfirm.ProductTechConfirmDO;
@@ -18,7 +27,11 @@
 import org.springframework.validation.annotation.Validated;
 
 import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
 import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
@@ -50,14 +63,25 @@
      */
     private static final String TECH_CONFIRM_APPROVE_BIZ_TYPE = "pd_tech_confirm_approve";
 
+    /**
+     * 鎶�鏈‘璁ゅ嚱瀹℃壒鐨� BPM 娴佺▼瀹氫箟 Key
+     */
+    private static final String TECH_CONFIRM_APPROVE_PROCESS_KEY = "pd_tech_confirm_approve";
+
     @Resource
     private ProductTechConfirmMapper techConfirmMapper;
+
+    @Resource
+    private BpmProcessInstanceApi bpmProcessInstanceApi;
 
     @Resource
     private AdminUserApi adminUserApi;
 
     @Resource
     private ApprovalConfigApi approvalConfigApi;
+
+    @Resource
+    private CrmCustomerApi customerApi;
 
     @Override
     @Transactional(rollbackFor = Exception.class)
@@ -132,6 +156,30 @@
         //    鐢� UpdateWrapper 鑰岄潪 updateById锛歁yBatis-Plus 榛樿鏇存柊绛栫暐浼氬拷鐣� null锛�
         //    鐩存帴 updateById 鏃犳硶鎶婂鏍镐笉閫氳繃鍚庢畫鐣欑殑瀹℃牳浜� / 瀹℃牳鏃堕棿 / 瀹℃牳鎰忚鐪熸娓呯┖銆�
         techConfirmMapper.submitAndResetAuditInfo(id, MesPdTechConfirmStatusEnum.PENDING_AUDIT.getStatus());
+        // 4. 鍒涘缓 BPM 娴佺▼瀹炰緥锛屼娇瀹℃壒鍑虹幇鍦ㄣ�屽崗鍚屽姙鍏� - 鎴戠殑娴佺▼銆�
+        bpmProcessInstanceApi.createProcessInstance(getLoginUserId(),
+                new BpmProcessInstanceCreateReqDTO()
+                        .setProcessDefinitionKey(TECH_CONFIRM_APPROVE_PROCESS_KEY)
+                        .setBusinessKey(String.valueOf(id)));
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void updateTechConfirmAuditStatus(Long id, Integer bpmStatus, String reason) {
+        // BPM 瀹℃壒缁撴灉鏄犲皠涓虹‘璁ゅ嚱鐘舵�侊細閫氳繃=宸插鏍� / 涓嶉�氳繃=瀹℃牳涓嶉�氳繃锛堝彲淇敼鍚庨噸鏂版彁浜わ級
+        Integer status;
+        if (BpmTaskStatusEnum.APPROVE.getStatus().equals(bpmStatus)) {
+            status = MesPdTechConfirmStatusEnum.AUDITED.getStatus();
+        } else if (BpmTaskStatusEnum.REJECT.getStatus().equals(bpmStatus)) {
+            status = MesPdTechConfirmStatusEnum.REJECTED.getStatus();
+        } else {
+            // 鎶�鏈‘璁ゅ嚱娌℃湁銆屽凡鍙栨秷銆嶇姸鎬侊紝鍏朵綑 BPM 缁撴灉锛堝鎾ゆ秷锛夊拷鐣�
+            log.warn("[updateTechConfirmAuditStatus] 蹇界暐涓嶆敮鎸佺殑 BPM 鐘舵��({})锛宼echConfirmId={}", bpmStatus, id);
+            return;
+        }
+        if (techConfirmMapper.updateAuditStatusByBpm(id, status, reason) != 1) {
+            log.warn("[updateTechConfirmAuditStatus] 鎶�鏈‘璁ゅ嚱({}) 涓嶅浜庡緟瀹℃牳鐘舵�侊紝蹇界暐 BPM 缁撴灉({})", id, bpmStatus);
+        }
     }
 
     @Override
@@ -182,6 +230,56 @@
                 .build());
     }
 
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public ProductTechConfirmImportRespVO importTechConfirmList(List<ProductTechConfirmImportExcelVO> importList, boolean updateSupport) {
+        if (CollUtil.isEmpty(importList)) {
+            throw exception(PD_TECH_CONFIRM_IMPORT_LIST_IS_EMPTY);
+        }
+        ProductTechConfirmImportRespVO respVO = ProductTechConfirmImportRespVO.builder()
+                .createCodes(new ArrayList<>()).updateCodes(new ArrayList<>())
+                .failureCodes(new LinkedHashMap<>()).build();
+        AtomicInteger index = new AtomicInteger(1);
+        importList.forEach(importItem -> {
+            int currentIndex = index.getAndIncrement();
+            String key = StrUtil.blankToDefault(importItem.getConfirmNo(), "绗� " + currentIndex + " 琛�");
+            if (StrUtil.isBlank(importItem.getConfirmNo())) {
+                respVO.getFailureCodes().put(key, "纭鍑界紪鍙蜂笉鑳戒负绌�");
+                return;
+            }
+            // 1. 瑙f瀽瀹㈡埛鍚嶇О
+            Long customerId = null;
+            if (StrUtil.isNotBlank(importItem.getCustomerName())) {
+                CrmCustomerRespDTO customer = customerApi.getCustomerByName(importItem.getCustomerName().trim());
+                if (customer == null) {
+                    respVO.getFailureCodes().put(key, "瀹㈡埛鍚嶇О[" + importItem.getCustomerName() + "]涓嶅瓨鍦�");
+                    return;
+                }
+                customerId = customer.getId();
+            }
+            // 2. 鏋勫缓璇锋眰骞跺垱寤�/鏇存柊锛堝鐢ㄧ幇鏈� create/update 鏈嶅姟锛岀姸鎬佺敱 create 鍥哄畾涓鸿崏绋匡級
+            ProductTechConfirmSaveReqVO reqVO = BeanUtils.toBean(importItem, ProductTechConfirmSaveReqVO.class);
+            reqVO.setCustomerId(customerId);
+            try {
+                ProductTechConfirmDO exist = techConfirmMapper.selectByConfirmNo(importItem.getConfirmNo().trim());
+                if (exist == null) {
+                    reqVO.setId(null);
+                    createTechConfirm(reqVO);
+                    respVO.getCreateCodes().add(importItem.getConfirmNo());
+                } else if (updateSupport) {
+                    reqVO.setId(exist.getId());
+                    updateTechConfirm(reqVO);
+                    respVO.getUpdateCodes().add(importItem.getConfirmNo());
+                } else {
+                    respVO.getFailureCodes().put(key, "纭鍑界紪鍙峰凡瀛樺湪");
+                }
+            } catch (ServiceException e) {
+                respVO.getFailureCodes().put(key, e.getMessage());
+            }
+        });
+        return respVO;
+    }
+
     /**
      * 鑾峰彇鐢ㄦ埛鏄电О
      *
@@ -197,8 +295,9 @@
     }
 
     private void validateConfirmNoUnique(String confirmNo, Long excludeId) {
-        if (confirmNo == null) {
-            return;
+        // 纭鍑界紪鍙峰繀濉細VO 涓婄殑 @NotBlank 鍙鐩栨帴鍙e叆鍙傦紝Service 鍐咃紙鍚鍏ワ級浠嶉渶鏄惧紡鏍¢獙
+        if (StrUtil.isBlank(confirmNo)) {
+            throw exception(PD_TECH_CONFIRM_NO_REQUIRED);
         }
         ProductTechConfirmDO techConfirm = techConfirmMapper.selectOne(
                 ProductTechConfirmDO::getConfirmNo, confirmNo);

--
Gitblit v1.9.3