Commit fe651b42ec0bf9b99acfcedbd91b93386aabea97

Authored by YunaiV
1 parent 8e9cb110

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

Showing 12 changed files with 132 additions and 23 deletions
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/convert/definition/BpmModelConvert.java
@@ -90,13 +90,13 @@ public interface BpmModelConvert { @@ -90,13 +90,13 @@ public interface BpmModelConvert {
90 createReqDTO.setKey(model.getKey()); 90 createReqDTO.setKey(model.getKey());
91 createReqDTO.setCategory(model.getCategory()); 91 createReqDTO.setCategory(model.getCategory());
92 BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class); 92 BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class);
93 - if (metaInfo != null) {  
94 - createReqDTO.setDescription(metaInfo.getDescription());  
95 - createReqDTO.setFormId(metaInfo.getFormId());  
96 - } 93 + // metaInfo
  94 + copyTo(metaInfo, createReqDTO);
97 return createReqDTO; 95 return createReqDTO;
98 } 96 }
99 97
  98 + void copyTo(BpmModelMetaInfoRespDTO from, @MappingTarget BpmDefinitionCreateReqDTO to);
  99 +
100 default void copy(Model model, BpmModelCreateReqVO bean) { 100 default void copy(Model model, BpmModelCreateReqVO bean) {
101 model.setName(bean.getName()); 101 model.setName(bean.getName());
102 model.setKey(bean.getKey()); 102 model.setKey(bean.getKey());
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/convert/definition/BpmTaskAssignRuleConvert.java
@@ -39,4 +39,6 @@ public interface BpmTaskAssignRuleConvert { @@ -39,4 +39,6 @@ public interface BpmTaskAssignRuleConvert {
39 39
40 BpmTaskAssignRuleDO convert(BpmTaskAssignRuleUpdateReqVO bean); 40 BpmTaskAssignRuleDO convert(BpmTaskAssignRuleUpdateReqVO bean);
41 41
  42 + List<BpmTaskAssignRuleDO> convertList2(List<BpmTaskAssignRuleRespVO> list);
  43 +
42 } 44 }
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/enums/BpmErrorCodeConstants.java
@@ -25,6 +25,9 @@ public interface BpmErrorCodeConstants { @@ -25,6 +25,9 @@ public interface BpmErrorCodeConstants {
25 ErrorCode MODEL_KEY_EXISTS = new ErrorCode(1009002000, "已经存在流程标识为【{}】的流程"); 25 ErrorCode MODEL_KEY_EXISTS = new ErrorCode(1009002000, "已经存在流程标识为【{}】的流程");
26 ErrorCode MODEL_NOT_EXISTS = new ErrorCode(1009002001, "流程模型不存在"); 26 ErrorCode MODEL_NOT_EXISTS = new ErrorCode(1009002001, "流程模型不存在");
27 ErrorCode MODEL_KEY_VALID = new ErrorCode(1009002002, "流程标识格式不正确,需要以字母或下划线开头,后接任意字母、数字、中划线、下划线、句点!"); 27 ErrorCode MODEL_KEY_VALID = new ErrorCode(1009002002, "流程标识格式不正确,需要以字母或下划线开头,后接任意字母、数字、中划线、下划线、句点!");
  28 + ErrorCode MODEL_DEPLOY_FAIL_FORM_NOT_CONFIG = new ErrorCode(1009002003, "部署流程失败,原因:流程表单未配置,请点击【修改流程】按钮进行配置");
  29 + ErrorCode MODEL_DEPLOY_FAIL_TASK_ASSIGN_RULE_NOT_CONFIG = new ErrorCode(1009002004, "部署流程失败," +
  30 + "原因:用户任务({})未配置分配规则,请点击【修改流程】按钮进行配置");
28 31
29 // ========== 流程定义 1-009-003-000 ========== 32 // ========== 流程定义 1-009-003-000 ==========
30 ErrorCode PROCESS_DEFINITION_KEY_NOT_MATCH = new ErrorCode(1009003000, "流程定义的标识期望是({}),当前是({}),请修改 BPMN 流程图"); 33 ErrorCode PROCESS_DEFINITION_KEY_NOT_MATCH = new ErrorCode(1009003000, "流程定义的标识期望是({}),当前是({}),请修改 BPMN 流程图");
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; @@ -3,6 +3,7 @@ package cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.config;
3 import cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.behavior.BpmActivityBehaviorFactory; 3 import cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.behavior.BpmActivityBehaviorFactory;
4 import cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.listener.BpmTackActivitiEventListener; 4 import cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.listener.BpmTackActivitiEventListener;
5 import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmTaskAssignRuleService; 5 import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmTaskAssignRuleService;
  6 +import cn.iocoder.yudao.adminserver.modules.system.service.permission.SysPermissionService;
6 import org.activiti.spring.boot.ProcessEngineConfigurationConfigurer; 7 import org.activiti.spring.boot.ProcessEngineConfigurationConfigurer;
7 import org.springframework.context.annotation.Bean; 8 import org.springframework.context.annotation.Bean;
8 import org.springframework.context.annotation.Configuration; 9 import org.springframework.context.annotation.Configuration;
@@ -45,9 +46,11 @@ public class BpmActivitiConfiguration { @@ -45,9 +46,11 @@ public class BpmActivitiConfiguration {
45 } 46 }
46 47
47 @Bean 48 @Bean
48 - public BpmActivityBehaviorFactory bpmActivityBehaviorFactory(BpmTaskAssignRuleService taskRuleService) { 49 + public BpmActivityBehaviorFactory bpmActivityBehaviorFactory(BpmTaskAssignRuleService taskRuleService,
  50 + SysPermissionService permissionService) {
49 BpmActivityBehaviorFactory bpmActivityBehaviorFactory = new BpmActivityBehaviorFactory(); 51 BpmActivityBehaviorFactory bpmActivityBehaviorFactory = new BpmActivityBehaviorFactory();
50 bpmActivityBehaviorFactory.setBpmTaskRuleService(taskRuleService); 52 bpmActivityBehaviorFactory.setBpmTaskRuleService(taskRuleService);
  53 + bpmActivityBehaviorFactory.setPermissionService(permissionService);
51 return bpmActivityBehaviorFactory; 54 return bpmActivityBehaviorFactory;
52 } 55 }
53 56
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/framework/activiti/core/behavior/BpmActivityBehaviorFactory.java
1 package cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.behavior; 1 package cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.behavior;
2 2
3 import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmTaskAssignRuleService; 3 import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmTaskAssignRuleService;
  4 +import cn.iocoder.yudao.adminserver.modules.system.service.permission.SysPermissionService;
4 import lombok.Data; 5 import lombok.Data;
5 import lombok.EqualsAndHashCode; 6 import lombok.EqualsAndHashCode;
6 import lombok.Setter; 7 import lombok.Setter;
@@ -22,11 +23,14 @@ public class BpmActivityBehaviorFactory extends DefaultActivityBehaviorFactory { @@ -22,11 +23,14 @@ public class BpmActivityBehaviorFactory extends DefaultActivityBehaviorFactory {
22 23
23 @Setter 24 @Setter
24 private BpmTaskAssignRuleService bpmTaskRuleService; 25 private BpmTaskAssignRuleService bpmTaskRuleService;
  26 + @Setter
  27 + private SysPermissionService permissionService;
25 28
26 @Override 29 @Override
27 public UserTaskActivityBehavior createUserTaskActivityBehavior(UserTask userTask) { 30 public UserTaskActivityBehavior createUserTaskActivityBehavior(UserTask userTask) {
28 BpmUserTaskActivitiBehavior userTaskActivityBehavior = new BpmUserTaskActivitiBehavior(userTask); 31 BpmUserTaskActivitiBehavior userTaskActivityBehavior = new BpmUserTaskActivitiBehavior(userTask);
29 userTaskActivityBehavior.setBpmTaskRuleService(bpmTaskRuleService); 32 userTaskActivityBehavior.setBpmTaskRuleService(bpmTaskRuleService);
  33 + userTaskActivityBehavior.setPermissionService(permissionService);
30 return userTaskActivityBehavior; 34 return userTaskActivityBehavior;
31 } 35 }
32 36
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 @@ -4,6 +4,7 @@ import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.rule.Bp
4 import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.rule.BpmTaskAssignRuleRespVO; 4 import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.rule.BpmTaskAssignRuleRespVO;
5 import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.rule.BpmTaskAssignRuleUpdateReqVO; 5 import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.rule.BpmTaskAssignRuleUpdateReqVO;
6 import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO; 6 import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO;
  7 +import org.activiti.engine.repository.ProcessDefinition;
7 import org.springframework.lang.Nullable; 8 import org.springframework.lang.Nullable;
8 9
9 import javax.validation.Valid; 10 import javax.validation.Valid;
@@ -34,7 +35,6 @@ public interface BpmTaskAssignRuleService { @@ -34,7 +35,6 @@ public interface BpmTaskAssignRuleService {
34 */ 35 */
35 List<BpmTaskAssignRuleDO> getTaskAssignRuleListByModelId(String modelId); 36 List<BpmTaskAssignRuleDO> getTaskAssignRuleListByModelId(String modelId);
36 37
37 -  
38 /** 38 /**
39 * 获得流程定义的任务分配规则数组 39 * 获得流程定义的任务分配规则数组
40 * 40 *
@@ -59,4 +59,13 @@ public interface BpmTaskAssignRuleService { @@ -59,4 +59,13 @@ public interface BpmTaskAssignRuleService {
59 */ 59 */
60 void updateTaskAssignRule(@Valid BpmTaskAssignRuleUpdateReqVO reqVO); 60 void updateTaskAssignRule(@Valid BpmTaskAssignRuleUpdateReqVO reqVO);
61 61
  62 + /**
  63 + * 将流程流程模型的任务分配规则,复制一份给流程定义
  64 + * 目的:每次流程模型部署时,都会生成一个新的流程定义,此时考虑到每次部署的流程不可变性,所以需要复制一份给该流程定义
  65 + *
  66 + * @param fromModelId 流程模型编号
  67 + * @param toProcessDefinitionId 流程定义编号
  68 + */
  69 + void copyTaskAssignRules(String fromModelId, String toProcessDefinitionId);
  70 +
62 } 71 }
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/definition/dto/BpmDefinitionCreateReqDTO.java
1 package cn.iocoder.yudao.adminserver.modules.bpm.service.definition.dto; 1 package cn.iocoder.yudao.adminserver.modules.bpm.service.definition.dto;
2 2
  3 +import cn.iocoder.yudao.adminserver.modules.bpm.enums.definition.BpmModelFormTypeEnum;
3 import lombok.Data; 4 import lombok.Data;
4 5
5 import javax.validation.constraints.NotEmpty; 6 import javax.validation.constraints.NotEmpty;
  7 +import javax.validation.constraints.NotNull;
6 8
7 /** 9 /**
8 * 流程定义创建 Request DTO 10 * 流程定义创建 Request DTO
@@ -10,6 +12,8 @@ import javax.validation.constraints.NotEmpty; @@ -10,6 +12,8 @@ import javax.validation.constraints.NotEmpty;
10 @Data 12 @Data
11 public class BpmDefinitionCreateReqDTO { 13 public class BpmDefinitionCreateReqDTO {
12 14
  15 + // ========== 模型相关 ==========
  16 +
13 /** 17 /**
14 * 流程模型的编号 18 * 流程模型的编号
15 */ 19 */
@@ -40,9 +44,30 @@ public class BpmDefinitionCreateReqDTO { @@ -40,9 +44,30 @@ public class BpmDefinitionCreateReqDTO {
40 */ 44 */
41 @NotEmpty(message = "BPMN XML 不能为空") 45 @NotEmpty(message = "BPMN XML 不能为空")
42 private String bpmnXml; 46 private String bpmnXml;
  47 +
  48 + // ========== 表单相关 ==========
  49 +
43 /** 50 /**
44 - * 动态表单编号,允许空 51 + * 表单类型
  52 + */
  53 + @NotNull(message = "表单类型不能为空")
  54 + private Integer formType;
  55 + /**
  56 + * 动态表单编号
  57 + * 在表单类型为 {@link BpmModelFormTypeEnum#NORMAL} 时
45 */ 58 */
46 private Long formId; 59 private Long formId;
  60 + /**
  61 + * 自定义表单的提交路径,使用 Vue 的路由地址
  62 + * 在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时
  63 + */
  64 + private String formCustomCreatePath;
  65 + /**
  66 + * 自定义表单的查看路径,使用 Vue 的路由地址
  67 + * 在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时
  68 + */
  69 + private String formCustomViewPath;
  70 +
  71 +
47 72
48 } 73 }
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/definition/impl/BpmModelServiceImpl.java
1 package cn.iocoder.yudao.adminserver.modules.bpm.service.definition.impl; 1 package cn.iocoder.yudao.adminserver.modules.bpm.service.definition.impl;
2 2
  3 +import cn.hutool.core.collection.CollUtil;
3 import cn.hutool.core.util.ArrayUtil; 4 import cn.hutool.core.util.ArrayUtil;
4 import cn.hutool.core.util.StrUtil; 5 import cn.hutool.core.util.StrUtil;
5 import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.model.*; 6 import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.model.*;
  7 +import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.rule.BpmTaskAssignRuleRespVO;
6 import cn.iocoder.yudao.adminserver.modules.bpm.convert.definition.BpmModelConvert; 8 import cn.iocoder.yudao.adminserver.modules.bpm.convert.definition.BpmModelConvert;
7 import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmFormDO; 9 import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmFormDO;
8 import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmProcessDefinitionService; 10 import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmProcessDefinitionService;
  11 +import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmTaskAssignRuleService;
9 import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.dto.BpmDefinitionCreateReqDTO; 12 import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.dto.BpmDefinitionCreateReqDTO;
10 import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmFormService; 13 import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmFormService;
11 import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmModelService; 14 import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmModelService;
@@ -26,6 +29,7 @@ import org.activiti.engine.repository.Deployment; @@ -26,6 +29,7 @@ import org.activiti.engine.repository.Deployment;
26 import org.activiti.engine.repository.Model; 29 import org.activiti.engine.repository.Model;
27 import org.activiti.engine.repository.ModelQuery; 30 import org.activiti.engine.repository.ModelQuery;
28 import org.activiti.engine.repository.ProcessDefinition; 31 import org.activiti.engine.repository.ProcessDefinition;
  32 +import org.springframework.context.annotation.Lazy;
29 import org.springframework.stereotype.Service; 33 import org.springframework.stereotype.Service;
30 import org.springframework.transaction.annotation.Transactional; 34 import org.springframework.transaction.annotation.Transactional;
31 import org.springframework.util.ObjectUtils; 35 import org.springframework.util.ObjectUtils;
@@ -36,9 +40,11 @@ import java.util.HashSet; @@ -36,9 +40,11 @@ import java.util.HashSet;
36 import java.util.List; 40 import java.util.List;
37 import java.util.Map; 41 import java.util.Map;
38 import java.util.Set; 42 import java.util.Set;
  43 +import java.util.function.Consumer;
39 44
40 import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.*; 45 import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.*;
41 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 46 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  47 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception0;
42 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; 48 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
43 49
44 /** 50 /**
@@ -55,9 +61,12 @@ public class BpmModelServiceImpl implements BpmModelService { @@ -55,9 +61,12 @@ public class BpmModelServiceImpl implements BpmModelService {
55 @Resource 61 @Resource
56 private RepositoryService repositoryService; 62 private RepositoryService repositoryService;
57 @Resource 63 @Resource
58 - private BpmFormService bpmFormService; 64 + private BpmFormService formService;
59 @Resource 65 @Resource
60 - private BpmProcessDefinitionService bpmProcessDefinitionService; 66 + private BpmProcessDefinitionService processDefinitionService;
  67 + @Resource
  68 + @Lazy // 解决循环依赖
  69 + private BpmTaskAssignRuleService taskAssignRuleService;
61 70
62 @Override 71 @Override
63 public PageResult<BpmModelPageItemRespVO> getModelPage(ModelPageReqVO pageVO) { 72 public PageResult<BpmModelPageItemRespVO> getModelPage(ModelPageReqVO pageVO) {
@@ -80,14 +89,14 @@ public class BpmModelServiceImpl implements BpmModelService { @@ -80,14 +89,14 @@ public class BpmModelServiceImpl implements BpmModelService {
80 BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class); 89 BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class);
81 return metaInfo != null ? metaInfo.getFormId() : null; 90 return metaInfo != null ? metaInfo.getFormId() : null;
82 }); 91 });
83 - Map<Long, BpmFormDO> formMap = bpmFormService.getFormMap(formIds); 92 + Map<Long, BpmFormDO> formMap = formService.getFormMap(formIds);
84 93
85 // 获得 Deployment Map 94 // 获得 Deployment Map
86 Set<String> deploymentIds = new HashSet<>(); 95 Set<String> deploymentIds = new HashSet<>();
87 models.forEach(model -> CollectionUtils.addIfNotNull(deploymentIds, model.getDeploymentId())); 96 models.forEach(model -> CollectionUtils.addIfNotNull(deploymentIds, model.getDeploymentId()));
88 - Map<String, Deployment> deploymentMap = bpmProcessDefinitionService.getDeploymentMap(deploymentIds); 97 + Map<String, Deployment> deploymentMap = processDefinitionService.getDeploymentMap(deploymentIds);
89 // 获得 ProcessDefinition Map 98 // 获得 ProcessDefinition Map
90 - List<ProcessDefinition> processDefinitions = bpmProcessDefinitionService.getProcessDefinitionListByDeploymentIds(deploymentIds); 99 + List<ProcessDefinition> processDefinitions = processDefinitionService.getProcessDefinitionListByDeploymentIds(deploymentIds);
91 Map<String, ProcessDefinition> processDefinitionMap = convertMap(processDefinitions, ProcessDefinition::getDeploymentId); 100 Map<String, ProcessDefinition> processDefinitionMap = convertMap(processDefinitions, ProcessDefinition::getDeploymentId);
92 101
93 // 拼接结果 102 // 拼接结果
@@ -160,28 +169,60 @@ public class BpmModelServiceImpl implements BpmModelService { @@ -160,28 +169,60 @@ public class BpmModelServiceImpl implements BpmModelService {
160 if (ObjectUtils.isEmpty(model)) { 169 if (ObjectUtils.isEmpty(model)) {
161 throw exception(MODEL_NOT_EXISTS); 170 throw exception(MODEL_NOT_EXISTS);
162 } 171 }
  172 + // 校验流程图
163 byte[] bpmnBytes = repositoryService.getModelEditorSource(model.getId()); 173 byte[] bpmnBytes = repositoryService.getModelEditorSource(model.getId());
164 if (bpmnBytes == null) { 174 if (bpmnBytes == null) {
165 throw exception(MODEL_NOT_EXISTS); 175 throw exception(MODEL_NOT_EXISTS);
166 } 176 }
  177 + // TODO 芋艿:校验流程图的有效性;例如说,是否有开始的元素,是否有结束的元素;
  178 + // 校验表单已配
  179 + BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class);
  180 + if (metaInfo == null || metaInfo.getFormType() == null) {
  181 + throw exception(MODEL_DEPLOY_FAIL_FORM_NOT_CONFIG);
  182 + }
  183 + // 校验任务分配规则已配置
  184 + checkTaskAssignRuleAllConfig(id);
167 185
168 // 创建流程定义 186 // 创建流程定义
169 BpmDefinitionCreateReqDTO definitionCreateReqDTO = BpmModelConvert.INSTANCE.convert2(model) 187 BpmDefinitionCreateReqDTO definitionCreateReqDTO = BpmModelConvert.INSTANCE.convert2(model)
170 .setBpmnXml(StrUtil.utf8Str(bpmnBytes)); 188 .setBpmnXml(StrUtil.utf8Str(bpmnBytes));
171 - String definitionId = bpmProcessDefinitionService.createProcessDefinition(definitionCreateReqDTO); 189 + String definitionId = processDefinitionService.createProcessDefinition(definitionCreateReqDTO);
172 190
173 // 将老的流程定义进行挂起。也就是说,只有最新部署的流程定义,才可以发起任务。 191 // 将老的流程定义进行挂起。也就是说,只有最新部署的流程定义,才可以发起任务。
174 if (StrUtil.isNotEmpty(model.getDeploymentId())) { 192 if (StrUtil.isNotEmpty(model.getDeploymentId())) {
175 - ProcessDefinition oldDefinition = bpmProcessDefinitionService.getProcessDefinitionByDeploymentId(model.getDeploymentId()); 193 + ProcessDefinition oldDefinition = processDefinitionService.getProcessDefinitionByDeploymentId(model.getDeploymentId());
176 if (oldDefinition != null) { 194 if (oldDefinition != null) {
177 - bpmProcessDefinitionService.updateProcessDefinitionState(oldDefinition.getId(), SuspensionState.SUSPENDED.getStateCode()); 195 + processDefinitionService.updateProcessDefinitionState(oldDefinition.getId(), SuspensionState.SUSPENDED.getStateCode());
178 } 196 }
179 } 197 }
180 198
181 // 更新 model 的 deploymentId,进行关联 199 // 更新 model 的 deploymentId,进行关联
182 - ProcessDefinition definition = bpmProcessDefinitionService.getProcessDefinition(definitionId); 200 + ProcessDefinition definition = processDefinitionService.getProcessDefinition(definitionId);
183 model.setDeploymentId(definition.getDeploymentId()); 201 model.setDeploymentId(definition.getDeploymentId());
184 repositoryService.saveModel(model); 202 repositoryService.saveModel(model);
  203 +
  204 + // 复制任务分配规则
  205 + taskAssignRuleService.copyTaskAssignRules(id, definition.getId());
  206 + }
  207 +
  208 + /**
  209 + * 校验流程模型的任务分配规则全部都配置了
  210 + * 目的:如果有规则未配置,会导致流程任务找不到负责人,进而流程无法进行下去!
  211 + *
  212 + * @param id 流程模型编号
  213 + */
  214 + private void checkTaskAssignRuleAllConfig(String id) {
  215 + // 一个用户任务都没配置,所以无需配置规则
  216 + List<BpmTaskAssignRuleRespVO> taskAssignRules = taskAssignRuleService.getTaskAssignRuleList(id, null);
  217 + if (CollUtil.isEmpty(taskAssignRules)) {
  218 + return;
  219 + }
  220 + // 校验未配置规则的任务
  221 + taskAssignRules.forEach(rule -> {
  222 + if (CollUtil.isEmpty(rule.getOptions())) {
  223 + throw exception(MODEL_DEPLOY_FAIL_TASK_ASSIGN_RULE_NOT_CONFIG, rule.getTaskDefinitionName());
  224 + }
  225 + });
185 } 226 }
186 227
187 @Override 228 @Override
@@ -203,13 +244,13 @@ public class BpmModelServiceImpl implements BpmModelService { @@ -203,13 +244,13 @@ public class BpmModelServiceImpl implements BpmModelService {
203 throw exception(MODEL_NOT_EXISTS); 244 throw exception(MODEL_NOT_EXISTS);
204 } 245 }
205 // 校验流程定义存在 246 // 校验流程定义存在
206 - ProcessDefinition definition = bpmProcessDefinitionService.getProcessDefinitionByDeploymentId(model.getDeploymentId()); 247 + ProcessDefinition definition = processDefinitionService.getProcessDefinitionByDeploymentId(model.getDeploymentId());
207 if (definition == null) { 248 if (definition == null) {
208 throw exception(PROCESS_DEFINITION_NOT_EXISTS); 249 throw exception(PROCESS_DEFINITION_NOT_EXISTS);
209 } 250 }
210 251
211 // 更新状态 252 // 更新状态
212 - bpmProcessDefinitionService.updateProcessDefinitionState(definition.getId(), state); 253 + processDefinitionService.updateProcessDefinitionState(definition.getId(), state);
213 } 254 }
214 255
215 @Override 256 @Override
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 @@ -121,6 +121,7 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ
121 if (bpmnModel == null) { 121 if (bpmnModel == null) {
122 return null; 122 return null;
123 } 123 }
  124 + // TODO 芋艿:重构到 activi util 里
124 byte[] bpmnBytes = BPMN_XML_CONVERTER.convertToXML(bpmnModel); 125 byte[] bpmnBytes = BPMN_XML_CONVERTER.convertToXML(bpmnModel);
125 return StrUtil.utf8Str(bpmnBytes); 126 return StrUtil.utf8Str(bpmnBytes);
126 } 127 }
@@ -179,7 +180,7 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ @@ -179,7 +180,7 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ
179 // 创建 Deployment 部署 180 // 创建 Deployment 部署
180 Deployment deploy = repositoryService.createDeployment() 181 Deployment deploy = repositoryService.createDeployment()
181 .key(createReqDTO.getKey()).name(createReqDTO.getName()).category(createReqDTO.getCategory()) 182 .key(createReqDTO.getKey()).name(createReqDTO.getName()).category(createReqDTO.getCategory())
182 - .addString(createReqDTO.getName() + BPMN_FILE_SUFFIX, createReqDTO.getBpmnXml()) 183 + .addString(createReqDTO.getKey() + BPMN_FILE_SUFFIX, createReqDTO.getBpmnXml())
183 .deploy(); 184 .deploy();
184 185
185 // 设置 ProcessDefinition 的 category 分类 186 // 设置 ProcessDefinition 的 category 分类
@@ -206,12 +207,14 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ @@ -206,12 +207,14 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ
206 public void updateProcessDefinitionState(String id, Integer state) { 207 public void updateProcessDefinitionState(String id, Integer state) {
207 // 激活 208 // 激活
208 if (Objects.equals(SuspensionState.ACTIVE.getStateCode(), state)) { 209 if (Objects.equals(SuspensionState.ACTIVE.getStateCode(), state)) {
209 - repositoryService.activateProcessDefinitionById(id, true, null); 210 + repositoryService.activateProcessDefinitionById(id, false, null);
210 return; 211 return;
211 } 212 }
212 // 挂起 213 // 挂起
213 if (Objects.equals(SuspensionState.SUSPENDED.getStateCode(), state)) { 214 if (Objects.equals(SuspensionState.SUSPENDED.getStateCode(), state)) {
214 - repositoryService.suspendProcessDefinitionById(id, true, null); 215 + // suspendProcessInstances = false,进行中的任务,不进行挂起。
  216 + // 原因:只要新的流程不允许发起即可,老流程继续可以执行。
  217 + repositoryService.suspendProcessDefinitionById(id, false, null);
215 return; 218 return;
216 } 219 }
217 log.error("[updateProcessDefinitionState][流程定义({}) 修改未知状态({})]", id, state); 220 log.error("[updateProcessDefinitionState][流程定义({}) 修改未知状态({})]", id, state);
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; @@ -17,6 +17,7 @@ import cn.iocoder.yudao.framework.activiti.core.util.ActivitiUtils;
17 import lombok.extern.slf4j.Slf4j; 17 import lombok.extern.slf4j.Slf4j;
18 import org.activiti.bpmn.model.BpmnModel; 18 import org.activiti.bpmn.model.BpmnModel;
19 import org.activiti.bpmn.model.UserTask; 19 import org.activiti.bpmn.model.UserTask;
  20 +import org.activiti.engine.repository.ProcessDefinition;
20 import org.springframework.context.annotation.Lazy; 21 import org.springframework.context.annotation.Lazy;
21 import org.springframework.stereotype.Service; 22 import org.springframework.stereotype.Service;
22 import org.springframework.validation.annotation.Validated; 23 import org.springframework.validation.annotation.Validated;
@@ -26,6 +27,7 @@ import java.util.Collections; @@ -26,6 +27,7 @@ import java.util.Collections;
26 import java.util.List; 27 import java.util.List;
27 import java.util.Objects; 28 import java.util.Objects;
28 import java.util.Set; 29 import java.util.Set;
  30 +import java.util.function.Consumer;
29 31
30 import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.*; 32 import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.*;
31 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 33 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@@ -123,6 +125,19 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService { @@ -123,6 +125,19 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService {
123 taskRuleMapper.updateById(BpmTaskAssignRuleConvert.INSTANCE.convert(reqVO)); 125 taskRuleMapper.updateById(BpmTaskAssignRuleConvert.INSTANCE.convert(reqVO));
124 } 126 }
125 127
  128 + @Override
  129 + public void copyTaskAssignRules(String fromModelId, String toProcessDefinitionId) {
  130 + List<BpmTaskAssignRuleRespVO> rules = getTaskAssignRuleList(fromModelId, null);
  131 + if (CollUtil.isEmpty(rules)) {
  132 + return;
  133 + }
  134 + // 开始复制
  135 + List<BpmTaskAssignRuleDO> newRules = BpmTaskAssignRuleConvert.INSTANCE.convertList2(rules);
  136 + newRules.forEach(rule -> rule.setProcessDefinitionId(toProcessDefinitionId).setId(null)
  137 + .setCreateTime(null).setUpdateTime(null));
  138 + taskRuleMapper.insertBatch(newRules);
  139 + }
  140 +
126 private void validTaskAssignRuleOptions(Integer type, Set<Long> options) { 141 private void validTaskAssignRuleOptions(Integer type, Set<Long> options) {
127 if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.ROLE.getType())) { 142 if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.ROLE.getType())) {
128 roleService.validRoles(options); 143 roleService.validRoles(options);
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&lt;SysUserRoleDO&gt; { @@ -31,8 +31,7 @@ public interface SysUserRoleMapper extends BaseMapperX&lt;SysUserRoleDO&gt; {
31 entity.setRoleId(roleId); 31 entity.setRoleId(roleId);
32 return entity; 32 return entity;
33 }).collect(Collectors.toList()); 33 }).collect(Collectors.toList());
34 - // TODO 芋艿,mybatis plus 增加批量插入的功能  
35 - list.forEach(this::insert); 34 + insertBatch(list);
36 } 35 }
37 36
38 default void deleteListByUserIdAndRoleIdIds(Long userId, Collection<Long> roleIds) { 37 default void deleteListByUserIdAndRoleIdIds(Long userId, Collection<Long> roleIds) {
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&lt;T&gt; extends BaseMapper&lt;T&gt; { @@ -49,4 +49,9 @@ public interface BaseMapperX&lt;T&gt; extends BaseMapper&lt;T&gt; {
49 return selectList(new QueryWrapper<T>().in(field, values)); 49 return selectList(new QueryWrapper<T>().in(field, values));
50 } 50 }
51 51
  52 + default void insertBatch(Collection<T> entities) {
  53 + // TODO 芋艿:修改成支持批量的
  54 + entities.forEach(this::insert);
  55 + }
  56 +
52 } 57 }