diff --git a/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/ErrorCodeConstants.java b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/ErrorCodeConstants.java index 7fb85b7835..a8cc848e31 100644 --- a/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/ErrorCodeConstants.java +++ b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/ErrorCodeConstants.java @@ -24,6 +24,7 @@ public interface ErrorCodeConstants { ErrorCode MODEL_DEPLOY_FAIL_BPMN_START_EVENT_NOT_EXISTS = new ErrorCode(1_009_002_005, "部署流程失败,原因:BPMN 流程图中,没有开始事件"); ErrorCode MODEL_DEPLOY_FAIL_BPMN_USER_TASK_NAME_NOT_EXISTS = new ErrorCode(1_009_002_006, "部署流程失败,原因:BPMN 流程图中,用户任务({})的名字不存在"); ErrorCode MODEL_UPDATE_FAIL_NOT_MANAGER = new ErrorCode(1_009_002_007, "操作流程失败,原因:你不是该流程({})的管理员"); + ErrorCode MODEL_DEPLOY_FAIL_BPMN_USER_TASK_RULE_TYPE_NOT_APPROVE_USER_SELECT = new ErrorCode(1_009_002_008, "部署流程失败,原因:BPMN 流程图中,用户任务({})的规则类型不能是【审批人自选】"); // ========== 流程定义 1-009-003-000 ========== ErrorCode PROCESS_DEFINITION_KEY_NOT_MATCH = new ErrorCode(1_009_003_000, "流程定义的标识期望是({}),当前是({}),请修改 BPMN 流程图"); diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java index 9ccc2f2c92..df91df62ec 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java @@ -16,6 +16,7 @@ import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelFormTypeEnum; import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelTypeEnum; import cn.iocoder.yudao.module.bpm.enums.task.BpmReasonEnum; import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateInvoker; +import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum; import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils; import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils; import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.SimpleModelUtils; @@ -23,9 +24,7 @@ import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceCopyService; import jakarta.annotation.Resource; import jakarta.validation.Valid; import lombok.extern.slf4j.Slf4j; -import org.flowable.bpmn.model.BpmnModel; -import org.flowable.bpmn.model.StartEvent; -import org.flowable.bpmn.model.UserTask; +import org.flowable.bpmn.model.*; import org.flowable.common.engine.impl.db.SuspensionState; import org.flowable.engine.HistoryService; import org.flowable.engine.RepositoryService; @@ -48,6 +47,7 @@ import java.util.Objects; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*; +import static cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils.parseCandidateStrategy; /** * 流程模型实现:主要进行 Flowable {@link Model} 的维护 @@ -243,7 +243,18 @@ public class BpmModelServiceImpl implements BpmModelService { if (startEvent == null) { throw exception(MODEL_DEPLOY_FAIL_BPMN_START_EVENT_NOT_EXISTS); } - // 2. 校验 UserTask 的 name 都配置了 + // 2. 校验第一个用户任务的规则类型是否为 审批人自选,如果是则抛出异常,第一个用户任务的规则类型不允许是审批人自选,因为会出现无审批人的情况 + List outgoingFlows = startEvent.getOutgoingFlows(); + if (CollUtil.isNotEmpty(outgoingFlows)){ + // 2.1 获取第一个用户节点 + FlowElement targetFlowElement = outgoingFlows.get(0).getTargetFlowElement(); + // 2.2 获取审批人策略 + Integer candidateStrategy = parseCandidateStrategy(targetFlowElement); + if (ObjUtil.equals(candidateStrategy, BpmTaskCandidateStrategyEnum.APPROVE_USER_SELECT.getStrategy())){ + throw exception(MODEL_DEPLOY_FAIL_BPMN_USER_TASK_RULE_TYPE_NOT_APPROVE_USER_SELECT, targetFlowElement.getName()); + } + } + // 3. 校验 UserTask 的 name 都配置了 List userTasks = BpmnModelUtils.getBpmnModelElements(bpmnModel, UserTask.class); userTasks.forEach(userTask -> { if (StrUtil.isEmpty(userTask.getName())) {