liu
2 天以前 a08832337f8de6a53edebbab1fb0b5a3bd1785aa
feat(srm): 供应商准入审核接入协同办公(BPM)

采购/质量/财务审核由协同办公流程驱动,SRM 侧发起流程并监听结果回写:
- submitApply 启动 BPM 流程,新增 approve-process-list / 状态回写
- 状态简化为 5 态(待提交/审批中/已取消/已通过/已驳回)
- 新增 SrmSupplierApplyStatusListener 监听流程结果
- 移除硬编码三级审核接口 review-* / approve

数据库变更脚本(部署 supplier_apply_approve 流程定义)保留在本地
sql/srm_supplier_apply_bpm_approval.sql,不纳入版本控制,由使用者手动执行。

Co-Authored-By: Claude <noreply@anthropic.com>
已删除1个文件
已添加1个文件
已修改7个文件
343 ■■■■■ 文件已修改
yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/controller/admin/apply/SrmSupplierApplyController.java 48 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/controller/admin/apply/vo/SrmSupplierApplyRespVO.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/controller/admin/apply/vo/SrmSupplierApplyReviewReqVO.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/dal/dataobject/SrmSupplierApplyDO.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/enums/ErrorCodeConstants.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/enums/SupplierApplyStatusEnum.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/apply/SrmSupplierApplyService.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/apply/SrmSupplierApplyServiceImpl.java 173 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/apply/listener/SrmSupplierApplyStatusListener.java 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/controller/admin/apply/SrmSupplierApplyController.java
@@ -15,7 +15,11 @@
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
@Tag(name = "管理后台 - SRM ä¾›åº”商准入")
@RestController
@@ -66,45 +70,19 @@
    }
    @PutMapping("/submit")
    @Operation(summary = "提交申请")
    @Parameter(name = "id", description = "编号", required = true)
    @Operation(summary = "提交准入申请审批(启动协同办公流程)")
    @PreAuthorize("@ss.hasPermission('srm:supplier-apply:update')")
    public CommonResult<Boolean> submitApply(@RequestParam("id") Long id) {
        applyService.submitApply(id);
    public CommonResult<Boolean> submitApply(@RequestParam("id") Long id,
                                             @RequestParam("processDefinitionKey") String processDefinitionKey) {
        applyService.submitApply(id, processDefinitionKey, getLoginUserId());
        return success(true);
    }
    @PutMapping("/review-purchase")
    @Operation(summary = "采购审核")
    @PreAuthorize("@ss.hasPermission('srm:supplier-apply:update')")
    public CommonResult<Boolean> reviewPurchase(@Valid @RequestBody SrmSupplierApplyReviewReqVO reqVO) {
        applyService.reviewPurchase(reqVO.getId(), reqVO.getOpinion(), reqVO.getPassed());
        return success(true);
    }
    @PutMapping("/review-quality")
    @Operation(summary = "质量审核")
    @PreAuthorize("@ss.hasPermission('srm:supplier-apply:update')")
    public CommonResult<Boolean> reviewQuality(@Valid @RequestBody SrmSupplierApplyReviewReqVO reqVO) {
        applyService.reviewQuality(reqVO.getId(), reqVO.getOpinion(), reqVO.getPassed());
        return success(true);
    }
    @PutMapping("/review-finance")
    @Operation(summary = "财务审核")
    @PreAuthorize("@ss.hasPermission('srm:supplier-apply:update')")
    public CommonResult<Boolean> reviewFinance(@Valid @RequestBody SrmSupplierApplyReviewReqVO reqVO) {
        applyService.reviewFinance(reqVO.getId(), reqVO.getOpinion(), reqVO.getPassed());
        return success(true);
    }
    @PutMapping("/approve")
    @Operation(summary = "通过后自动创建供应商")
    @Parameter(name = "id", description = "编号", required = true)
    @PreAuthorize("@ss.hasPermission('srm:supplier-apply:update')")
    public CommonResult<Boolean> approve(@RequestParam("id") Long id) {
        applyService.approve(id);
        return success(true);
    @GetMapping("/approve-process-list")
    @Operation(summary = "获取准入申请审批流程列表")
    @PreAuthorize("@ss.hasPermission('srm:supplier-apply:query')")
    public CommonResult<List<Map<String, Object>>> getApproveProcessList() {
        return success(applyService.getSupplierApplyApproveProcessDefinitionList());
    }
}
yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/controller/admin/apply/vo/SrmSupplierApplyRespVO.java
@@ -70,6 +70,9 @@
    @Schema(description = "申请状态", example = "0")
    private Integer applyStatus;
    @Schema(description = "BPM æµç¨‹å®žä¾‹ç¼–号", example = "1a2b3c4d")
    private String processInstanceId;
    @Schema(description = "采购审核人ID", example = "2")
    private Long purchaseReviewerId;
yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/controller/admin/apply/vo/SrmSupplierApplyReviewReqVO.java
ÎļþÒÑɾ³ý
yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/dal/dataobject/SrmSupplierApplyDO.java
@@ -44,6 +44,7 @@
    private String applyUserName;
    private LocalDateTime applyTime;
    private Integer applyStatus;
    private String processInstanceId;
    private Long purchaseReviewerId;
    private LocalDateTime purchaseReviewTime;
yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/enums/ErrorCodeConstants.java
@@ -21,6 +21,8 @@
    ErrorCode APPLY_STATUS_NOT_PENDING = new ErrorCode(1_040_200_002, "当前状态不允许审核");
    ErrorCode APPLY_SUPPLIER_EXISTS = new ErrorCode(1_040_200_003, "该供应商已存在准入记录");
    ErrorCode APPLY_SUPPLIER_NAME_REQUIRED = new ErrorCode(1_040_200_004, "未选择SRM供应商时,供应商名称不能为空");
    ErrorCode APPLY_BPM_CATEGORY_NOT_EXISTS = new ErrorCode(1_040_200_005, "供应商准入审批分类不存在,请先在BPM模块创建供应商准入审批流程分类");
    ErrorCode APPLY_BPM_PROCESS_DEFINITION_NOT_EXISTS = new ErrorCode(1_040_200_006, "供应商准入审批分类下没有可用的流程模型,请先创建并发布流程");
    // ========== ä¾›åº”商资质 1_040_300_000 ==========
    ErrorCode CERTIFICATE_NOT_EXISTS = new ErrorCode(1_040_300_000, "资质证书不存在");
yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/enums/SupplierApplyStatusEnum.java
@@ -4,16 +4,19 @@
/**
 * ä¾›åº”商准入申请状态枚举
 *
 * æŽ¥å…¥ååŒåŠžå…¬(BPM)后,SRM ä¾§åªæ„ŸçŸ¥æµç¨‹æœ€ç»ˆç»“æžœ,当前审批进度在协同办公查看。
 * åŽ†å²çŠ¶æ€(待采购审核 10 / å¾…质量审核 20 / å¾…财务审核 30)已废弃,
 * ç”± SQL è„šæœ¬ç»Ÿä¸€è¿ç§»:历史审批中单据重置为「待提交」,重新提交走协同办公。
 */
@Getter
public enum SupplierApplyStatusEnum {
    DRAFT(0, "待提交"),
    PENDING_PURCHASE(10, "待采购审核"),
    PENDING_QUALITY(20, "待质量审核"),
    PENDING_FINANCE(30, "待财务审核"),
    PROCESS(10, "审批中"),
    CANCEL(30, "已取消"),
    APPROVED(40, "已通过"),
    REJECTED(50, "已拒绝");
    REJECTED(50, "已驳回");
    SupplierApplyStatusEnum(Integer code, String name) {
        this.code = code;
yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/apply/SrmSupplierApplyService.java
@@ -6,6 +6,9 @@
import cn.iocoder.yudao.module.srm.dal.dataobject.SrmSupplierApplyDO;
import jakarta.validation.Valid;
import java.util.List;
import java.util.Map;
/**
 * SRM ä¾›åº”商准入申请 Service æŽ¥å£
 */
@@ -37,32 +40,34 @@
    PageResult<SrmSupplierApplyDO> getApplyPage(SrmSupplierApplyPageReqVO pageReqVO);
    /**
     * æäº¤ç”³è¯·ï¼ˆå¾…采购审核)
     * æäº¤ç”³è¯·ï¼ˆå¯åŠ¨ååŒåŠžå…¬æµç¨‹ï¼ŒçŠ¶æ€ç½®ä¸ºå®¡æ‰¹ä¸­ï¼‰
     *
     * @param id                  ç”³è¯·ç¼–号
     * @param processDefinitionKey ååŒåŠžå…¬æµç¨‹å®šä¹‰ Key
     * @param userId              æäº¤äººç¼–号
     */
    void submitApply(Long id);
    void submitApply(Long id, String processDefinitionKey, Long userId);
    /**
     * é‡‡è´­å®¡æ ¸
     * èŽ·å–ä¾›åº”å•†å‡†å…¥å®¡æ‰¹æµç¨‹åˆ—è¡¨ï¼ˆååŒåŠžå…¬å·²å‘å¸ƒä¸”æ¿€æ´»çš„æµç¨‹ï¼‰
     */
    void reviewPurchase(Long id, String opinion, Boolean passed);
    List<Map<String, Object>> getSupplierApplyApproveProcessDefinitionList();
    /**
     * è´¨é‡å®¡æ ¸
     * ååŒåŠžå…¬æµç¨‹ç»“æžœå›žå†™
     *
     * @param id       ç”³è¯·ç¼–号
     * @param bpmResult æµç¨‹ç»“果({@link cn.iocoder.yudao.module.bpm.enums.task.BpmTaskStatusEnum})
     */
    void reviewQuality(Long id, String opinion, Boolean passed);
    void updateSupplierApplyAuditStatus(Long id, Integer bpmResult);
    /**
     * è´¢åŠ¡å®¡æ ¸
     */
    void reviewFinance(Long id, String opinion, Boolean passed);
    /**
     * é€šè¿‡åŽè‡ªåŠ¨åˆ›å»ºä¾›åº”å•†
     * å®¡æ‰¹é€šè¿‡åŽè‡ªåŠ¨åˆ›å»ºä¾›åº”å•†
     */
    void approve(Long id);
    /**
     * ç¡®ä¿ä¾›åº”商已准入:未准入则自动创建准入申请并置为已通过
     * ç¡®ä¿ä¾›åº”商已准入:未准入则自动创建准入申请并置为已通过(定标自动准入,不走协同办公)
     *
     * @param supplierId ä¾›åº”商编号
     */
yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/apply/SrmSupplierApplyServiceImpl.java
@@ -1,9 +1,17 @@
package cn.iocoder.yudao.module.srm.service.apply;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
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.dal.dataobject.definition.BpmCategoryDO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO;
import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskStatusEnum;
import cn.iocoder.yudao.module.bpm.service.definition.BpmCategoryService;
import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
import cn.iocoder.yudao.module.srm.controller.admin.apply.vo.SrmSupplierApplyPageReqVO;
import cn.iocoder.yudao.module.srm.controller.admin.apply.vo.SrmSupplierApplySaveReqVO;
import cn.iocoder.yudao.module.srm.dal.dataobject.SrmSupplierApplyDO;
@@ -13,24 +21,47 @@
import cn.iocoder.yudao.module.srm.enums.ErrorCodeConstants;
import cn.iocoder.yudao.module.srm.enums.SupplierApplyStatusEnum;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.repository.ProcessDefinition;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
 * SRM ä¾›åº”商准入申请 Service å®žçŽ°ç±»
 *
 * æŽ¥å…¥ååŒåŠžå…¬(BPM)后,采购/质量/财务审核在协同办公流程中完成,
 * SRM ä¾§åªè´Ÿè´£å‘起流程并接收流程结束事件回写状态。
 */
@Service
@Validated
@Slf4j
public class SrmSupplierApplyServiceImpl implements SrmSupplierApplyService {
    /**
     * BPM ä¾›åº”商准入审批分类编码
     */
    private static final String SUPPLIER_APPLY_APPROVE_CATEGORY_CODE = "supplier_apply_approve";
    @Resource
    private SrmSupplierApplyMapper supplierApplyMapper;
    @Resource
    private SrmSupplierMapper supplierMapper;
    @Resource
    private BpmProcessInstanceApi processInstanceApi;
    @Resource
    private BpmCategoryService bpmCategoryService;
    @Resource
    private BpmProcessDefinitionService bpmProcessDefinitionService;
    @Override
    public Long createApply(SrmSupplierApplySaveReqVO createReqVO) {
@@ -54,7 +85,9 @@
    @Override
    public void updateApply(SrmSupplierApplySaveReqVO updateReqVO) {
        SrmSupplierApplyDO apply = validateApplyExists(updateReqVO.getId());
        if (!SupplierApplyStatusEnum.DRAFT.getCode().equals(apply.getApplyStatus())) {
        // ä»…待提交/已驳回可编辑
        if (!SupplierApplyStatusEnum.DRAFT.getCode().equals(apply.getApplyStatus())
                && !SupplierApplyStatusEnum.REJECTED.getCode().equals(apply.getApplyStatus())) {
            throw ServiceExceptionUtil.exception(ErrorCodeConstants.APPLY_STATUS_NOT_DRAFT);
        }
        // æ ¡éªŒï¼šå¿…须选择 SRM ä¾›åº”商或手动填写供应商名称
@@ -72,7 +105,12 @@
    @Override
    public void deleteApply(Long id) {
        validateApplyExists(id);
        SrmSupplierApplyDO apply = validateApplyExists(id);
        // ä»…待提交/已驳回可删除
        if (!SupplierApplyStatusEnum.DRAFT.getCode().equals(apply.getApplyStatus())
                && !SupplierApplyStatusEnum.REJECTED.getCode().equals(apply.getApplyStatus())) {
            throw ServiceExceptionUtil.exception(ErrorCodeConstants.APPLY_STATUS_NOT_DRAFT);
        }
        supplierApplyMapper.deleteById(id);
    }
@@ -88,59 +126,83 @@
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void submitApply(Long id) {
    public void submitApply(Long id, String processDefinitionKey, Long userId) {
        // 1. æ ¡éªŒå­˜åœ¨ + å¾…提交/已驳回状态
        SrmSupplierApplyDO apply = validateApplyExists(id);
        if (!SupplierApplyStatusEnum.DRAFT.getCode().equals(apply.getApplyStatus())) {
        if (!SupplierApplyStatusEnum.DRAFT.getCode().equals(apply.getApplyStatus())
                && !SupplierApplyStatusEnum.REJECTED.getCode().equals(apply.getApplyStatus())) {
            throw ServiceExceptionUtil.exception(ErrorCodeConstants.APPLY_STATUS_NOT_DRAFT);
        }
        apply.setApplyStatus(SupplierApplyStatusEnum.PENDING_PURCHASE.getCode());
        apply.setApplyTime(LocalDateTime.now());
        supplierApplyMapper.updateById(apply);
        // 2. åˆ›å»º BPM æµç¨‹å®žä¾‹ï¼ˆé‡‡è´­å®¡æ ¸â†’质量审核→财务审核,流程与审批人在协同办公配置)
        String processInstanceId = processInstanceApi.createProcessInstance(userId,
                new BpmProcessInstanceCreateReqDTO()
                        .setProcessDefinitionKey(processDefinitionKey)
                        .setBusinessKey(String.valueOf(id)));
        // 3. æ›´æ–°ç”³è¯·çŠ¶æ€ä¸ºå®¡æ‰¹ä¸­ï¼Œå›žå­˜æµç¨‹å®žä¾‹ç¼–å·
        supplierApplyMapper.updateById(new SrmSupplierApplyDO()
                .setId(id)
                .setApplyStatus(SupplierApplyStatusEnum.PROCESS.getCode())
                .setProcessInstanceId(processInstanceId));
    }
    @Override
    public List<Map<String, Object>> getSupplierApplyApproveProcessDefinitionList() {
        // 1. æ ¡éªŒåˆ†ç±»å’Œæµç¨‹å®šä¹‰æ˜¯å¦å­˜åœ¨
        validateSupplierApplyApproveCategoryAndProcessDefinition();
        // 2. èŽ·å–åˆ†ç±»ä¸‹çš„æµç¨‹å®šä¹‰ä¿¡æ¯
        List<BpmProcessDefinitionInfoDO> definitionInfoList = bpmProcessDefinitionService
                .getProcessDefinitionInfoListByCategory(SUPPLIER_APPLY_APPROVE_CATEGORY_CODE);
        if (CollUtil.isEmpty(definitionInfoList)) {
            return Collections.emptyList();
        }
        // 3. éåŽ†èŽ·å–æµç¨‹å®šä¹‰è¯¦æƒ…ï¼Œè¿‡æ»¤æ¿€æ´»çŠ¶æ€ï¼Œä¿ç•™æœ€æ–°ç‰ˆæœ¬
        Map<String, ProcessDefinition> latestVersionMap = new HashMap<>();
        for (BpmProcessDefinitionInfoDO info : definitionInfoList) {
            ProcessDefinition pd = bpmProcessDefinitionService.getProcessDefinition(info.getProcessDefinitionId());
            if (pd == null || pd.isSuspended()) {
                continue;
            }
            ProcessDefinition existing = latestVersionMap.get(pd.getKey());
            if (existing == null || pd.getVersion() > existing.getVersion()) {
                latestVersionMap.put(pd.getKey(), pd);
            }
        }
        // 4. è¿”回流程定义列表
        List<Map<String, Object>> result = new ArrayList<>();
        for (ProcessDefinition pd : latestVersionMap.values()) {
            Map<String, Object> item = new HashMap<>();
            item.put("id", pd.getId());
            item.put("key", pd.getKey());
            item.put("name", pd.getName());
            result.add(item);
        }
        return result;
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void reviewPurchase(Long id, String opinion, Boolean passed) {
    public void updateSupplierApplyAuditStatus(Long id, Integer bpmResult) {
        // 1. æ ¡éªŒå­˜åœ¨
        SrmSupplierApplyDO apply = validateApplyExists(id);
        if (!SupplierApplyStatusEnum.PENDING_PURCHASE.getCode().equals(apply.getApplyStatus())) {
            throw ServiceExceptionUtil.exception(ErrorCodeConstants.APPLY_STATUS_NOT_PENDING);
        if (!SupplierApplyStatusEnum.PROCESS.getCode().equals(apply.getApplyStatus())) {
            log.warn("[updateSupplierApplyAuditStatus] å‡†å…¥ç”³è¯·({}) ä¸å¤„于审批中状态", id);
            return;
        }
        apply.setPurchaseReviewOpinion(opinion);
        apply.setPurchaseReviewTime(LocalDateTime.now());
        apply.setApplyStatus(Boolean.TRUE.equals(passed)
                ? SupplierApplyStatusEnum.PENDING_QUALITY.getCode()
                : SupplierApplyStatusEnum.REJECTED.getCode());
        supplierApplyMapper.updateById(apply);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void reviewQuality(Long id, String opinion, Boolean passed) {
        SrmSupplierApplyDO apply = validateApplyExists(id);
        if (!SupplierApplyStatusEnum.PENDING_QUALITY.getCode().equals(apply.getApplyStatus())) {
            throw ServiceExceptionUtil.exception(ErrorCodeConstants.APPLY_STATUS_NOT_PENDING);
        // 2. æ ¹æ®å®¡æ‰¹ç»“果更新状态
        Integer newStatus = convertBpmResultToStatus(bpmResult);
        if (newStatus != null) {
            supplierApplyMapper.updateById(new SrmSupplierApplyDO()
                    .setId(id).setApplyStatus(newStatus));
        }
        apply.setQualityReviewOpinion(opinion);
        apply.setQualityReviewTime(LocalDateTime.now());
        apply.setApplyStatus(Boolean.TRUE.equals(passed)
                ? SupplierApplyStatusEnum.PENDING_FINANCE.getCode()
                : SupplierApplyStatusEnum.REJECTED.getCode());
        supplierApplyMapper.updateById(apply);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void reviewFinance(Long id, String opinion, Boolean passed) {
        SrmSupplierApplyDO apply = validateApplyExists(id);
        if (!SupplierApplyStatusEnum.PENDING_FINANCE.getCode().equals(apply.getApplyStatus())) {
            throw ServiceExceptionUtil.exception(ErrorCodeConstants.APPLY_STATUS_NOT_PENDING);
        // 3. å®¡æ‰¹é€šè¿‡ï¼šè‡ªåŠ¨åˆ›å»º/关联供应商档案
        if (SupplierApplyStatusEnum.APPROVED.getCode().equals(newStatus)) {
            approve(id);
        }
        apply.setFinanceReviewOpinion(opinion);
        apply.setFinanceReviewTime(LocalDateTime.now());
        apply.setApplyStatus(Boolean.TRUE.equals(passed)
                ? SupplierApplyStatusEnum.APPROVED.getCode()
                : SupplierApplyStatusEnum.REJECTED.getCode());
        supplierApplyMapper.updateById(apply);
    }
    @Override
@@ -158,7 +220,7 @@
        if (supplierApplyMapper.existsApprovedBySupplierId(supplierId)) {
            return;
        }
        // è‡ªåŠ¨åˆ›å»ºå‡†å…¥ç”³è¯·å¹¶ç›´æŽ¥ç½®ä¸ºå·²é€šè¿‡
        // è‡ªåŠ¨åˆ›å»ºå‡†å…¥ç”³è¯·å¹¶ç›´æŽ¥ç½®ä¸ºå·²é€šè¿‡ï¼ˆå®šæ ‡è‡ªåŠ¨å‡†å…¥ï¼Œä¸èµ°ååŒåŠžå…¬ï¼‰
        SrmSupplierApplyDO apply = new SrmSupplierApplyDO();
        apply.setApplyNo(generateApplyNo());
        apply.setSupplierId(supplierId);
@@ -221,6 +283,31 @@
    }
    /**
     * æ ¡éªŒä¾›åº”商准入审批分类存在
     */
    private void validateSupplierApplyApproveCategoryAndProcessDefinition() {
        List<BpmCategoryDO> categories = bpmCategoryService.getCategoryListByCode(
                Collections.singletonList(SUPPLIER_APPLY_APPROVE_CATEGORY_CODE));
        if (CollUtil.isEmpty(categories)) {
            throw ServiceExceptionUtil.exception(ErrorCodeConstants.APPLY_BPM_CATEGORY_NOT_EXISTS);
        }
    }
    /**
     * è½¬æ¢ BPM å®¡æ‰¹ç»“果为业务状态
     */
    private Integer convertBpmResultToStatus(Integer bpmResult) {
        if (BpmTaskStatusEnum.APPROVE.getStatus().equals(bpmResult)) {
            return SupplierApplyStatusEnum.APPROVED.getCode();
        } else if (BpmTaskStatusEnum.REJECT.getStatus().equals(bpmResult)) {
            return SupplierApplyStatusEnum.REJECTED.getCode();
        } else if (BpmTaskStatusEnum.CANCEL.getStatus().equals(bpmResult)) {
            return SupplierApplyStatusEnum.CANCEL.getCode();
        }
        return null;
    }
    /**
     * ç”Ÿæˆç”³è¯·ç¼–号
     */
    private String generateApplyNo() {
yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/apply/listener/SrmSupplierApplyStatusListener.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,52 @@
package cn.iocoder.yudao.module.srm.service.apply.listener;
import cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEvent;
import cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEventListener;
import cn.iocoder.yudao.module.srm.service.apply.SrmSupplierApplyService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
 * ä¾›åº”商准入审批状态监听器
 *
 * ç›‘听 BPM æµç¨‹å®žä¾‹çŠ¶æ€å˜æ›´äº‹ä»¶ï¼Œæ›´æ–°å‡†å…¥ç”³è¯·çš„å®¡æ‰¹çŠ¶æ€ï¼ˆååŒåŠžå…¬å®¡æ‰¹åŽå›žå†™ï¼‰
 */
@Component
@Slf4j
public class SrmSupplierApplyStatusListener extends BpmProcessInstanceStatusEventListener {
    /**
     * ä¾›åº”商准入审批流程定义 Key
     */
    private static final String PROCESS_DEFINITION_KEY = "supplier_apply_approve";
    @Resource
    private SrmSupplierApplyService supplierApplyService;
    @Override
    protected String getProcessDefinitionKey() {
        return PROCESS_DEFINITION_KEY;
    }
    @Override
    protected void onEvent(BpmProcessInstanceStatusEvent event) {
        Long applyId;
        try {
            applyId = Long.parseLong(event.getBusinessKey());
        } catch (NumberFormatException e) {
            log.warn("[onEvent] businessKey({}) ä¸æ˜¯æœ‰æ•ˆçš„准入申请编号", event.getBusinessKey());
            return;
        }
        log.info("[onEvent] æ”¶åˆ°BPM审批事件,applyId={}, status={}", applyId, event.getStatus());
        try {
            supplierApplyService.updateSupplierApplyAuditStatus(applyId, event.getStatus());
            log.info("[onEvent] å‡†å…¥ç”³è¯·({}) å®¡æ‰¹çŠ¶æ€æ›´æ–°å®Œæˆ", applyId);
        } catch (Exception e) {
            log.error("[onEvent] æ›´æ–°å‡†å…¥ç”³è¯·å®¡æ‰¹çŠ¶æ€å¤±è´¥ï¼ŒapplyId={}", applyId, e);
        }
    }
}