Эх сурвалжийг харах

BPM 模型重构 8:修改部 model 部署逻辑,支付任务规则的复制

YunaiV 3 жил өмнө
parent
commit
fe651b42ec
12 өөрчлөгдсөн 132 нэмэгдсэн , 23 устгасан
  1. 4 4
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/convert/definition/BpmModelConvert.java
  2. 2 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/convert/definition/BpmTaskAssignRuleConvert.java
  3. 3 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/enums/BpmErrorCodeConstants.java
  4. 4 1
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/framework/activiti/config/BpmActivitiConfiguration.java
  5. 4 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/framework/activiti/core/behavior/BpmActivityBehaviorFactory.java
  6. 10 1
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/definition/BpmTaskAssignRuleService.java
  7. 26 1
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/definition/dto/BpmDefinitionCreateReqDTO.java
  8. 52 11
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/definition/impl/BpmModelServiceImpl.java
  9. 6 3
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/definition/impl/BpmProcessDefinitionServiceImpl.java
  10. 15 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/definition/impl/BpmTaskAssignRuleServiceImpl.java
  11. 1 2
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/dal/mysql/permission/SysUserRoleMapper.java
  12. 5 0
      yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/mapper/BaseMapperX.java

+ 4 - 4
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/convert/definition/BpmModelConvert.java

@@ -90,13 +90,13 @@ public interface BpmModelConvert {
         createReqDTO.setKey(model.getKey());
         createReqDTO.setCategory(model.getCategory());
         BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class);
-        if (metaInfo != null) {
-            createReqDTO.setDescription(metaInfo.getDescription());
-            createReqDTO.setFormId(metaInfo.getFormId());
-        }
+        // metaInfo
+        copyTo(metaInfo, createReqDTO);
         return createReqDTO;
     }
 
+    void copyTo(BpmModelMetaInfoRespDTO from, @MappingTarget BpmDefinitionCreateReqDTO to);
+
     default void copy(Model model, BpmModelCreateReqVO bean) {
         model.setName(bean.getName());
         model.setKey(bean.getKey());

+ 2 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/convert/definition/BpmTaskAssignRuleConvert.java

@@ -39,4 +39,6 @@ public interface BpmTaskAssignRuleConvert {
 
     BpmTaskAssignRuleDO convert(BpmTaskAssignRuleUpdateReqVO bean);
 
+    List<BpmTaskAssignRuleDO> convertList2(List<BpmTaskAssignRuleRespVO> list);
+
 }

+ 3 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/enums/BpmErrorCodeConstants.java

@@ -25,6 +25,9 @@ public interface BpmErrorCodeConstants {
     ErrorCode MODEL_KEY_EXISTS = new ErrorCode(1009002000, "已经存在流程标识为【{}】的流程");
     ErrorCode MODEL_NOT_EXISTS = new ErrorCode(1009002001, "流程模型不存在");
     ErrorCode MODEL_KEY_VALID = new ErrorCode(1009002002, "流程标识格式不正确,需要以字母或下划线开头,后接任意字母、数字、中划线、下划线、句点!");
+    ErrorCode MODEL_DEPLOY_FAIL_FORM_NOT_CONFIG = new ErrorCode(1009002003, "部署流程失败,原因:流程表单未配置,请点击【修改流程】按钮进行配置");
+    ErrorCode MODEL_DEPLOY_FAIL_TASK_ASSIGN_RULE_NOT_CONFIG = new ErrorCode(1009002004, "部署流程失败," +
+            "原因:用户任务({})未配置分配规则,请点击【修改流程】按钮进行配置");
 
     // ========== 流程定义 1-009-003-000 ==========
     ErrorCode PROCESS_DEFINITION_KEY_NOT_MATCH = new ErrorCode(1009003000, "流程定义的标识期望是({}),当前是({}),请修改 BPMN 流程图");

+ 4 - 1
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/framework/activiti/config/BpmActivitiConfiguration.java

@@ -3,6 +3,7 @@ package cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.config;
 import cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.behavior.BpmActivityBehaviorFactory;
 import cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.listener.BpmTackActivitiEventListener;
 import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmTaskAssignRuleService;
+import cn.iocoder.yudao.adminserver.modules.system.service.permission.SysPermissionService;
 import org.activiti.spring.boot.ProcessEngineConfigurationConfigurer;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
@@ -45,9 +46,11 @@ public class BpmActivitiConfiguration {
     }
 
     @Bean
-    public BpmActivityBehaviorFactory bpmActivityBehaviorFactory(BpmTaskAssignRuleService taskRuleService) {
+    public BpmActivityBehaviorFactory bpmActivityBehaviorFactory(BpmTaskAssignRuleService taskRuleService,
+                                                                 SysPermissionService permissionService) {
         BpmActivityBehaviorFactory bpmActivityBehaviorFactory = new BpmActivityBehaviorFactory();
         bpmActivityBehaviorFactory.setBpmTaskRuleService(taskRuleService);
+        bpmActivityBehaviorFactory.setPermissionService(permissionService);
         return bpmActivityBehaviorFactory;
     }
 

+ 4 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/framework/activiti/core/behavior/BpmActivityBehaviorFactory.java

@@ -1,6 +1,7 @@
 package cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.behavior;
 
 import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmTaskAssignRuleService;
+import cn.iocoder.yudao.adminserver.modules.system.service.permission.SysPermissionService;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.Setter;
@@ -22,11 +23,14 @@ public class BpmActivityBehaviorFactory extends DefaultActivityBehaviorFactory {
 
     @Setter
     private BpmTaskAssignRuleService bpmTaskRuleService;
+    @Setter
+    private SysPermissionService permissionService;
 
     @Override
     public UserTaskActivityBehavior createUserTaskActivityBehavior(UserTask userTask) {
         BpmUserTaskActivitiBehavior userTaskActivityBehavior = new BpmUserTaskActivitiBehavior(userTask);
         userTaskActivityBehavior.setBpmTaskRuleService(bpmTaskRuleService);
+        userTaskActivityBehavior.setPermissionService(permissionService);
         return userTaskActivityBehavior;
     }
 

+ 10 - 1
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/definition/BpmTaskAssignRuleService.java

@@ -4,6 +4,7 @@ import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.rule.Bp
 import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.rule.BpmTaskAssignRuleRespVO;
 import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.rule.BpmTaskAssignRuleUpdateReqVO;
 import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO;
+import org.activiti.engine.repository.ProcessDefinition;
 import org.springframework.lang.Nullable;
 
 import javax.validation.Valid;
@@ -34,7 +35,6 @@ public interface BpmTaskAssignRuleService {
      */
     List<BpmTaskAssignRuleDO> getTaskAssignRuleListByModelId(String modelId);
 
-
     /**
      * 获得流程定义的任务分配规则数组
      *
@@ -59,4 +59,13 @@ public interface BpmTaskAssignRuleService {
      */
     void updateTaskAssignRule(@Valid BpmTaskAssignRuleUpdateReqVO reqVO);
 
+    /**
+     * 将流程流程模型的任务分配规则,复制一份给流程定义
+     * 目的:每次流程模型部署时,都会生成一个新的流程定义,此时考虑到每次部署的流程不可变性,所以需要复制一份给该流程定义
+     *
+     * @param fromModelId 流程模型编号
+     * @param toProcessDefinitionId 流程定义编号
+     */
+    void copyTaskAssignRules(String fromModelId, String toProcessDefinitionId);
+
 }

+ 26 - 1
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/definition/dto/BpmDefinitionCreateReqDTO.java

@@ -1,8 +1,10 @@
 package cn.iocoder.yudao.adminserver.modules.bpm.service.definition.dto;
 
+import cn.iocoder.yudao.adminserver.modules.bpm.enums.definition.BpmModelFormTypeEnum;
 import lombok.Data;
 
 import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
 
 /**
  * 流程定义创建 Request DTO
@@ -10,6 +12,8 @@ import javax.validation.constraints.NotEmpty;
 @Data
 public class BpmDefinitionCreateReqDTO {
 
+    // ========== 模型相关 ==========
+
     /**
      * 流程模型的编号
      */
@@ -40,9 +44,30 @@ public class BpmDefinitionCreateReqDTO {
      */
     @NotEmpty(message = "BPMN XML 不能为空")
     private String bpmnXml;
+
+    // ========== 表单相关 ==========
+
     /**
-     * 动态表单编号,允许空
+     * 表单类型
+     */
+    @NotNull(message = "表单类型不能为空")
+    private Integer formType;
+    /**
+     * 动态表单编号
+     * 在表单类型为 {@link BpmModelFormTypeEnum#NORMAL} 时
      */
     private Long formId;
+    /**
+     * 自定义表单的提交路径,使用 Vue 的路由地址
+     * 在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时
+     */
+    private String formCustomCreatePath;
+    /**
+     * 自定义表单的查看路径,使用 Vue 的路由地址
+     * 在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时
+     */
+    private String formCustomViewPath;
+
+
 
 }

+ 52 - 11
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/definition/impl/BpmModelServiceImpl.java

@@ -1,11 +1,14 @@
 package cn.iocoder.yudao.adminserver.modules.bpm.service.definition.impl;
 
+import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.ArrayUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.model.*;
+import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.rule.BpmTaskAssignRuleRespVO;
 import cn.iocoder.yudao.adminserver.modules.bpm.convert.definition.BpmModelConvert;
 import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmFormDO;
 import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmProcessDefinitionService;
+import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmTaskAssignRuleService;
 import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.dto.BpmDefinitionCreateReqDTO;
 import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmFormService;
 import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmModelService;
@@ -26,6 +29,7 @@ import org.activiti.engine.repository.Deployment;
 import org.activiti.engine.repository.Model;
 import org.activiti.engine.repository.ModelQuery;
 import org.activiti.engine.repository.ProcessDefinition;
+import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.ObjectUtils;
@@ -36,9 +40,11 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.function.Consumer;
 
 import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.*;
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception0;
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
 
 /**
@@ -55,9 +61,12 @@ public class BpmModelServiceImpl implements BpmModelService {
     @Resource
     private RepositoryService repositoryService;
     @Resource
-    private BpmFormService bpmFormService;
+    private BpmFormService formService;
     @Resource
-    private BpmProcessDefinitionService bpmProcessDefinitionService;
+    private BpmProcessDefinitionService processDefinitionService;
+    @Resource
+    @Lazy // 解决循环依赖
+    private BpmTaskAssignRuleService taskAssignRuleService;
 
     @Override
     public PageResult<BpmModelPageItemRespVO> getModelPage(ModelPageReqVO pageVO) {
@@ -80,14 +89,14 @@ public class BpmModelServiceImpl implements BpmModelService {
             BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class);
             return metaInfo != null ? metaInfo.getFormId() : null;
         });
-        Map<Long, BpmFormDO> formMap = bpmFormService.getFormMap(formIds);
+        Map<Long, BpmFormDO> formMap = formService.getFormMap(formIds);
 
         // 获得 Deployment Map
         Set<String> deploymentIds = new HashSet<>();
         models.forEach(model -> CollectionUtils.addIfNotNull(deploymentIds, model.getDeploymentId()));
-        Map<String, Deployment> deploymentMap = bpmProcessDefinitionService.getDeploymentMap(deploymentIds);
+        Map<String, Deployment> deploymentMap = processDefinitionService.getDeploymentMap(deploymentIds);
         // 获得 ProcessDefinition Map
-        List<ProcessDefinition> processDefinitions = bpmProcessDefinitionService.getProcessDefinitionListByDeploymentIds(deploymentIds);
+        List<ProcessDefinition> processDefinitions = processDefinitionService.getProcessDefinitionListByDeploymentIds(deploymentIds);
         Map<String, ProcessDefinition> processDefinitionMap = convertMap(processDefinitions, ProcessDefinition::getDeploymentId);
 
         // 拼接结果
@@ -160,28 +169,60 @@ public class BpmModelServiceImpl implements BpmModelService {
         if (ObjectUtils.isEmpty(model)) {
             throw exception(MODEL_NOT_EXISTS);
         }
+        // 校验流程图
         byte[] bpmnBytes = repositoryService.getModelEditorSource(model.getId());
         if (bpmnBytes == null) {
             throw exception(MODEL_NOT_EXISTS);
         }
+        // TODO 芋艿:校验流程图的有效性;例如说,是否有开始的元素,是否有结束的元素;
+        // 校验表单已配
+        BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class);
+        if (metaInfo == null || metaInfo.getFormType() == null) {
+            throw exception(MODEL_DEPLOY_FAIL_FORM_NOT_CONFIG);
+        }
+        // 校验任务分配规则已配置
+        checkTaskAssignRuleAllConfig(id);
 
         // 创建流程定义
         BpmDefinitionCreateReqDTO definitionCreateReqDTO = BpmModelConvert.INSTANCE.convert2(model)
                 .setBpmnXml(StrUtil.utf8Str(bpmnBytes));
-        String definitionId = bpmProcessDefinitionService.createProcessDefinition(definitionCreateReqDTO);
+        String definitionId = processDefinitionService.createProcessDefinition(definitionCreateReqDTO);
 
         // 将老的流程定义进行挂起。也就是说,只有最新部署的流程定义,才可以发起任务。
         if (StrUtil.isNotEmpty(model.getDeploymentId())) {
-            ProcessDefinition oldDefinition = bpmProcessDefinitionService.getProcessDefinitionByDeploymentId(model.getDeploymentId());
+            ProcessDefinition oldDefinition = processDefinitionService.getProcessDefinitionByDeploymentId(model.getDeploymentId());
             if (oldDefinition != null) {
-                bpmProcessDefinitionService.updateProcessDefinitionState(oldDefinition.getId(), SuspensionState.SUSPENDED.getStateCode());
+                processDefinitionService.updateProcessDefinitionState(oldDefinition.getId(), SuspensionState.SUSPENDED.getStateCode());
             }
         }
 
         // 更新 model 的 deploymentId,进行关联
-        ProcessDefinition definition = bpmProcessDefinitionService.getProcessDefinition(definitionId);
+        ProcessDefinition definition = processDefinitionService.getProcessDefinition(definitionId);
         model.setDeploymentId(definition.getDeploymentId());
         repositoryService.saveModel(model);
+
+        // 复制任务分配规则
+        taskAssignRuleService.copyTaskAssignRules(id, definition.getId());
+    }
+
+    /**
+     * 校验流程模型的任务分配规则全部都配置了
+     * 目的:如果有规则未配置,会导致流程任务找不到负责人,进而流程无法进行下去!
+     *
+     * @param id 流程模型编号
+     */
+    private void checkTaskAssignRuleAllConfig(String id) {
+        // 一个用户任务都没配置,所以无需配置规则
+        List<BpmTaskAssignRuleRespVO> taskAssignRules = taskAssignRuleService.getTaskAssignRuleList(id, null);
+        if (CollUtil.isEmpty(taskAssignRules)) {
+            return;
+        }
+        // 校验未配置规则的任务
+        taskAssignRules.forEach(rule -> {
+            if (CollUtil.isEmpty(rule.getOptions())) {
+                throw exception(MODEL_DEPLOY_FAIL_TASK_ASSIGN_RULE_NOT_CONFIG, rule.getTaskDefinitionName());
+            }
+        });
     }
 
     @Override
@@ -203,13 +244,13 @@ public class BpmModelServiceImpl implements BpmModelService {
             throw exception(MODEL_NOT_EXISTS);
         }
         // 校验流程定义存在
-        ProcessDefinition definition = bpmProcessDefinitionService.getProcessDefinitionByDeploymentId(model.getDeploymentId());
+        ProcessDefinition definition = processDefinitionService.getProcessDefinitionByDeploymentId(model.getDeploymentId());
         if (definition == null) {
             throw exception(PROCESS_DEFINITION_NOT_EXISTS);
         }
 
         // 更新状态
-        bpmProcessDefinitionService.updateProcessDefinitionState(definition.getId(), state);
+        processDefinitionService.updateProcessDefinitionState(definition.getId(), state);
     }
 
     @Override

+ 6 - 3
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/definition/impl/BpmProcessDefinitionServiceImpl.java

@@ -121,6 +121,7 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ
         if (bpmnModel == null) {
             return null;
         }
+        // TODO 芋艿:重构到 activi util 里
         byte[] bpmnBytes = BPMN_XML_CONVERTER.convertToXML(bpmnModel);
         return StrUtil.utf8Str(bpmnBytes);
     }
@@ -179,7 +180,7 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ
         // 创建 Deployment 部署
         Deployment deploy = repositoryService.createDeployment()
                 .key(createReqDTO.getKey()).name(createReqDTO.getName()).category(createReqDTO.getCategory())
-                .addString(createReqDTO.getName() + BPMN_FILE_SUFFIX, createReqDTO.getBpmnXml())
+                .addString(createReqDTO.getKey() + BPMN_FILE_SUFFIX, createReqDTO.getBpmnXml())
                 .deploy();
 
         // 设置 ProcessDefinition 的 category 分类
@@ -206,12 +207,14 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ
     public void updateProcessDefinitionState(String id, Integer state) {
         // 激活
         if (Objects.equals(SuspensionState.ACTIVE.getStateCode(), state)) {
-            repositoryService.activateProcessDefinitionById(id, true, null);
+            repositoryService.activateProcessDefinitionById(id, false, null);
             return;
         }
         // 挂起
         if (Objects.equals(SuspensionState.SUSPENDED.getStateCode(), state)) {
-            repositoryService.suspendProcessDefinitionById(id, true, null);
+            // suspendProcessInstances = false,进行中的任务,不进行挂起。
+            // 原因:只要新的流程不允许发起即可,老流程继续可以执行。
+            repositoryService.suspendProcessDefinitionById(id, false, null);
             return;
         }
         log.error("[updateProcessDefinitionState][流程定义({}) 修改未知状态({})]", id, state);

+ 15 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/definition/impl/BpmTaskAssignRuleServiceImpl.java

@@ -17,6 +17,7 @@ import cn.iocoder.yudao.framework.activiti.core.util.ActivitiUtils;
 import lombok.extern.slf4j.Slf4j;
 import org.activiti.bpmn.model.BpmnModel;
 import org.activiti.bpmn.model.UserTask;
+import org.activiti.engine.repository.ProcessDefinition;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
 import org.springframework.validation.annotation.Validated;
@@ -26,6 +27,7 @@ import java.util.Collections;
 import java.util.List;
 import java.util.Objects;
 import java.util.Set;
+import java.util.function.Consumer;
 
 import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.*;
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@@ -123,6 +125,19 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService {
         taskRuleMapper.updateById(BpmTaskAssignRuleConvert.INSTANCE.convert(reqVO));
     }
 
+    @Override
+    public void copyTaskAssignRules(String fromModelId, String toProcessDefinitionId) {
+        List<BpmTaskAssignRuleRespVO> rules = getTaskAssignRuleList(fromModelId, null);
+        if (CollUtil.isEmpty(rules)) {
+            return;
+        }
+        // 开始复制
+        List<BpmTaskAssignRuleDO> newRules = BpmTaskAssignRuleConvert.INSTANCE.convertList2(rules);
+        newRules.forEach(rule -> rule.setProcessDefinitionId(toProcessDefinitionId).setId(null)
+                .setCreateTime(null).setUpdateTime(null));
+        taskRuleMapper.insertBatch(newRules);
+    }
+
     private void validTaskAssignRuleOptions(Integer type, Set<Long> options) {
         if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.ROLE.getType())) {
             roleService.validRoles(options);

+ 1 - 2
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/dal/mysql/permission/SysUserRoleMapper.java

@@ -31,8 +31,7 @@ public interface SysUserRoleMapper extends BaseMapperX<SysUserRoleDO> {
             entity.setRoleId(roleId);
             return entity;
         }).collect(Collectors.toList());
-        // TODO 芋艿,mybatis plus 增加批量插入的功能
-        list.forEach(this::insert);
+        insertBatch(list);
     }
 
     default void deleteListByUserIdAndRoleIdIds(Long userId, Collection<Long> roleIds) {

+ 5 - 0
yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/mapper/BaseMapperX.java

@@ -49,4 +49,9 @@ public interface BaseMapperX<T> extends BaseMapper<T> {
         return selectList(new QueryWrapper<T>().in(field, values));
     }
 
+    default void insertBatch(Collection<T> entities) {
+        // TODO 芋艿:修改成支持批量的
+        entities.forEach(this::insert);
+    }
+
 }