Commit b1d6baaad8a92c6de7364c2dffbe29ccd5392031

Authored by jason
1 parent d6a6a012

工作流 Flowable 发布流程, 删除模型 的实现

Showing 15 changed files with 611 additions and 133 deletions
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmAbstractModelService.java
1 package cn.iocoder.yudao.module.bpm.service.definition; 1 package cn.iocoder.yudao.module.bpm.service.definition;
2 2
  3 +import cn.hutool.core.collection.CollUtil;
3 import cn.iocoder.yudao.framework.common.util.json.JsonUtils; 4 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
4 import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils; 5 import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils;
  6 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleRespVO;
5 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO; 7 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
6 import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelFormTypeEnum; 8 import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelFormTypeEnum;
7 import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmModelMetaInfoRespDTO; 9 import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmModelMetaInfoRespDTO;
8 10
  11 +import java.util.List;
9 import java.util.Objects; 12 import java.util.Objects;
10 13
11 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 14 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@@ -21,8 +24,11 @@ public abstract class BpmAbstractModelService { @@ -21,8 +24,11 @@ public abstract class BpmAbstractModelService {
21 24
22 protected final BpmFormService bpmFormService; 25 protected final BpmFormService bpmFormService;
23 26
24 - public BpmAbstractModelService(BpmFormService bpmFormService) { 27 + protected final BpmTaskAssignRuleService taskAssignRuleService;
  28 +
  29 + public BpmAbstractModelService(BpmFormService bpmFormService,BpmTaskAssignRuleService taskAssignRuleService) {
25 this.bpmFormService = bpmFormService; 30 this.bpmFormService = bpmFormService;
  31 + this.taskAssignRuleService = taskAssignRuleService;
26 } 32 }
27 33
28 /** 34 /**
@@ -47,6 +53,26 @@ public abstract class BpmAbstractModelService { @@ -47,6 +53,26 @@ public abstract class BpmAbstractModelService {
47 return null; 53 return null;
48 } 54 }
49 55
  56 + /**
  57 + * 校验流程模型的任务分配规则全部都配置了
  58 + * 目的:如果有规则未配置,会导致流程任务找不到负责人,进而流程无法进行下去!
  59 + *
  60 + * @param id 流程模型编号
  61 + */
  62 + protected void checkTaskAssignRuleAllConfig(String id) {
  63 + // 一个用户任务都没配置,所以无需配置规则
  64 + List<BpmTaskAssignRuleRespVO> taskAssignRules = taskAssignRuleService.getTaskAssignRuleList(id, null);
  65 + if (CollUtil.isEmpty(taskAssignRules)) {
  66 + return;
  67 + }
  68 + // 校验未配置规则的任务
  69 + taskAssignRules.forEach(rule -> {
  70 + if (CollUtil.isEmpty(rule.getOptions())) {
  71 + throw exception(MODEL_DEPLOY_FAIL_TASK_ASSIGN_RULE_NOT_CONFIG, rule.getTaskDefinitionName());
  72 + }
  73 + });
  74 + }
  75 +
50 76
51 protected void checkKeyNCName(String key) { 77 protected void checkKeyNCName(String key) {
52 if (!ValidationUtils.isXmlNCName(key)) { 78 if (!ValidationUtils.isXmlNCName(key)) {
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionCommonService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.service.definition;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageItemRespVO;
  5 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageReqVO;
  6 +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO;
  7 +import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO;
  8 +
  9 +import javax.validation.Valid;
  10 +
  11 +/**
  12 + * 流程定义通用接口
  13 + * Activiti 和 flowable 通用的流程定义接口
  14 + *
  15 + * @author yunlong.li
  16 + * @author ZJQ
  17 + * @author 芋道源码
  18 + * @author jason
  19 + */
  20 +public interface BpmProcessDefinitionCommonService {
  21 +
  22 + /**
  23 + * 获得流程定义分页
  24 + *
  25 + * @param pageReqVO 分页入参
  26 + * @return 流程定义 Page
  27 + */
  28 + PageResult<BpmProcessDefinitionPageItemRespVO> getProcessDefinitionPage(BpmProcessDefinitionPageReqVO pageReqVO);
  29 +
  30 + /**
  31 + * 创建流程定义
  32 + *
  33 + * @param createReqDTO 创建信息
  34 + * @return 流程编号
  35 + */
  36 + String createProcessDefinition(@Valid BpmProcessDefinitionCreateReqDTO createReqDTO);
  37 +
  38 + /**
  39 + * 更新流程定义状态
  40 + *
  41 + * @param id 流程定义的编号
  42 + * @param state 状态
  43 + */
  44 + void updateProcessDefinitionState(String id, Integer state);
  45 +
  46 + /**
  47 + * 获得流程定义对应的 BPMN XML
  48 + *
  49 + * @param id 流程定义编号
  50 + * @return BPMN XML
  51 + */
  52 + String getProcessDefinitionBpmnXML(String id);
  53 +
  54 + /**
  55 + * 获得需要创建的流程定义,是否和当前激活的流程定义相等
  56 + *
  57 + * @param createReqDTO 创建信息
  58 + * @return 是否相等
  59 + */
  60 + boolean isProcessDefinitionEquals(@Valid BpmProcessDefinitionCreateReqDTO createReqDTO);
  61 +
  62 + /**
  63 + * 获得编号对应的 BpmProcessDefinitionExtDO
  64 + *
  65 + * @param id 编号
  66 + * @return 流程定义拓展
  67 + */
  68 + BpmProcessDefinitionExtDO getProcessDefinitionExt(String id);
  69 +}
yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleService.java renamed to yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleService.java
yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java
@@ -52,13 +52,9 @@ public class BpmModelServiceImpl extends BpmAbstractModelService implements BpmM @@ -52,13 +52,9 @@ public class BpmModelServiceImpl extends BpmAbstractModelService implements BpmM
52 52
53 @Resource 53 @Resource
54 private BpmProcessDefinitionService processDefinitionService; 54 private BpmProcessDefinitionService processDefinitionService;
55 - @Resource  
56 - @Lazy // 解决循环依赖  
57 - private BpmTaskAssignRuleService taskAssignRuleService;  
58 -  
59 55
60 - public BpmModelServiceImpl(BpmFormService bpmFormService) {  
61 - super(bpmFormService); 56 + public BpmModelServiceImpl(BpmFormService bpmFormService,BpmTaskAssignRuleService taskAssignRuleService) {
  57 + super(bpmFormService, taskAssignRuleService);
62 } 58 }
63 59
64 @Override 60 @Override
@@ -196,26 +192,6 @@ public class BpmModelServiceImpl extends BpmAbstractModelService implements BpmM @@ -196,26 +192,6 @@ public class BpmModelServiceImpl extends BpmAbstractModelService implements BpmM
196 taskAssignRuleService.copyTaskAssignRules(id, definition.getId()); 192 taskAssignRuleService.copyTaskAssignRules(id, definition.getId());
197 } 193 }
198 194
199 - /**  
200 - * 校验流程模型的任务分配规则全部都配置了  
201 - * 目的:如果有规则未配置,会导致流程任务找不到负责人,进而流程无法进行下去!  
202 - *  
203 - * @param id 流程模型编号  
204 - */  
205 - private void checkTaskAssignRuleAllConfig(String id) {  
206 - // 一个用户任务都没配置,所以无需配置规则  
207 - List<BpmTaskAssignRuleRespVO> taskAssignRules = taskAssignRuleService.getTaskAssignRuleList(id, null);  
208 - if (CollUtil.isEmpty(taskAssignRules)) {  
209 - return;  
210 - }  
211 - // 校验未配置规则的任务  
212 - taskAssignRules.forEach(rule -> {  
213 - if (CollUtil.isEmpty(rule.getOptions())) {  
214 - throw exception(MODEL_DEPLOY_FAIL_TASK_ASSIGN_RULE_NOT_CONFIG, rule.getTaskDefinitionName());  
215 - }  
216 - });  
217 - }  
218 -  
219 @Override 195 @Override
220 @Transactional(rollbackFor = Exception.class) 196 @Transactional(rollbackFor = Exception.class)
221 public void deleteModel(String id) { 197 public void deleteModel(String id) {
yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionService.java
@@ -24,15 +24,7 @@ import java.util.Set; @@ -24,15 +24,7 @@ import java.util.Set;
24 * @author ZJQ 24 * @author ZJQ
25 * @author 芋道源码 25 * @author 芋道源码
26 */ 26 */
27 -public interface BpmProcessDefinitionService {  
28 -  
29 - /**  
30 - * 获得流程定义分页  
31 - *  
32 - * @param pageReqVO 分页入参  
33 - * @return 流程定义 Page  
34 - */  
35 - PageResult<BpmProcessDefinitionPageItemRespVO> getProcessDefinitionPage(BpmProcessDefinitionPageReqVO pageReqVO); 27 +public interface BpmProcessDefinitionService extends BpmProcessDefinitionCommonService {
36 28
37 /** 29 /**
38 * 获得流程定义列表 30 * 获得流程定义列表
@@ -43,14 +35,6 @@ public interface BpmProcessDefinitionService { @@ -43,14 +35,6 @@ public interface BpmProcessDefinitionService {
43 List<BpmProcessDefinitionRespVO> getProcessDefinitionList(BpmProcessDefinitionListReqVO listReqVO); 35 List<BpmProcessDefinitionRespVO> getProcessDefinitionList(BpmProcessDefinitionListReqVO listReqVO);
44 36
45 /** 37 /**
46 - * 获得流程定义对应的 BPMN XML  
47 - *  
48 - * @param id 流程定义编号  
49 - * @return BPMN XML  
50 - */  
51 - String getProcessDefinitionBpmnXML(String id);  
52 -  
53 - /**  
54 * 获得 Bpmn 模型 38 * 获得 Bpmn 模型
55 * 39 *
56 * @param processDefinitionId 流程定义的编号 40 * @param processDefinitionId 流程定义的编号
@@ -85,14 +69,6 @@ public interface BpmProcessDefinitionService { @@ -85,14 +69,6 @@ public interface BpmProcessDefinitionService {
85 ProcessDefinition getActiveProcessDefinition(String key); 69 ProcessDefinition getActiveProcessDefinition(String key);
86 70
87 /** 71 /**
88 - * 获得编号对应的 BpmProcessDefinitionExtDO  
89 - *  
90 - * @param id 编号  
91 - * @return 流程定义拓展  
92 - */  
93 - BpmProcessDefinitionExtDO getProcessDefinitionExt(String id);  
94 -  
95 - /**  
96 * 获得 id 对应的 Deployment 72 * 获得 id 对应的 Deployment
97 * 73 *
98 * @param id 部署编号 74 * @param id 部署编号
@@ -134,28 +110,4 @@ public interface BpmProcessDefinitionService { @@ -134,28 +110,4 @@ public interface BpmProcessDefinitionService {
134 */ 110 */
135 List<ProcessDefinition> getProcessDefinitionListByDeploymentIds(Set<String> deploymentIds); 111 List<ProcessDefinition> getProcessDefinitionListByDeploymentIds(Set<String> deploymentIds);
136 112
137 - /**  
138 - * 获得需要创建的流程定义,是否和当前激活的流程定义相等  
139 - *  
140 - * @param createReqDTO 创建信息  
141 - * @return 是否相等  
142 - */  
143 - boolean isProcessDefinitionEquals(@Valid BpmProcessDefinitionCreateReqDTO createReqDTO);  
144 -  
145 - /**  
146 - * 创建流程定义  
147 - *  
148 - * @param createReqDTO 创建信息  
149 - * @return 流程编号  
150 - */  
151 - String createProcessDefinition(@Valid BpmProcessDefinitionCreateReqDTO createReqDTO);  
152 -  
153 - /**  
154 - * 更新流程定义的挂起状态  
155 - *  
156 - * @param id 流程定义的编号  
157 - * @param state 挂起状态 {@link org.activiti.engine.impl.persistence.entity.SuspensionState}  
158 - */  
159 - void updateProcessDefinitionState(String id, Integer state);  
160 -  
161 } 113 }
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/FlowableModelController.java renamed to yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmModelController.java
@@ -4,8 +4,8 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult; @@ -4,8 +4,8 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 import cn.iocoder.yudao.framework.common.pojo.PageResult; 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 import cn.iocoder.yudao.framework.common.util.io.IoUtils; 5 import cn.iocoder.yudao.framework.common.util.io.IoUtils;
6 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.*; 6 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.*;
7 -import cn.iocoder.yudao.module.bpm.convert.definition.ModelConvert;  
8 -import cn.iocoder.yudao.module.bpm.service.definition.FlowableModelService; 7 +import cn.iocoder.yudao.module.bpm.convert.definition.BpmModelConvert;
  8 +import cn.iocoder.yudao.module.bpm.service.definition.BpmModelService;
9 import io.swagger.annotations.Api; 9 import io.swagger.annotations.Api;
10 import io.swagger.annotations.ApiImplicitParam; 10 import io.swagger.annotations.ApiImplicitParam;
11 import io.swagger.annotations.ApiOperation; 11 import io.swagger.annotations.ApiOperation;
@@ -24,10 +24,10 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; @@ -24,10 +24,10 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
24 @RestController 24 @RestController
25 @RequestMapping("/bpm/model") 25 @RequestMapping("/bpm/model")
26 @Validated 26 @Validated
27 -public class FlowableModelController { 27 +public class BpmModelController {
28 28
29 @Resource 29 @Resource
30 - private FlowableModelService modelService; 30 + private BpmModelService modelService;
31 31
32 @GetMapping("/page") 32 @GetMapping("/page")
33 @ApiOperation(value = "获得模型分页") 33 @ApiOperation(value = "获得模型分页")
@@ -62,7 +62,7 @@ public class FlowableModelController { @@ -62,7 +62,7 @@ public class FlowableModelController {
62 @PostMapping("/import") 62 @PostMapping("/import")
63 @ApiOperation(value = "导入模型") 63 @ApiOperation(value = "导入模型")
64 public CommonResult<String> importModel(@Valid BpmModeImportReqVO importReqVO) throws IOException { 64 public CommonResult<String> importModel(@Valid BpmModeImportReqVO importReqVO) throws IOException {
65 - BpmModelCreateReqVO createReqVO = ModelConvert.INSTANCE.convert(importReqVO); 65 + BpmModelCreateReqVO createReqVO = BpmModelConvert.INSTANCE.convert(importReqVO);
66 // 读取文件 66 // 读取文件
67 String bpmnXml = IoUtils.readUtf8(importReqVO.getBpmnFile().getInputStream(), false); 67 String bpmnXml = IoUtils.readUtf8(importReqVO.getBpmnFile().getInputStream(), false);
68 return success(modelService.createModel(createReqVO, bpmnXml)); 68 return success(modelService.createModel(createReqVO, bpmnXml));
@@ -76,4 +76,21 @@ public class FlowableModelController { @@ -76,4 +76,21 @@ public class FlowableModelController {
76 modelService.deployModel(id); 76 modelService.deployModel(id);
77 return success(true); 77 return success(true);
78 } 78 }
  79 +
  80 + @PutMapping("/update-state")
  81 + @ApiOperation(value = "修改模型的状态", notes = "实际更新的部署的流程定义的状态")
  82 + @PreAuthorize("@ss.hasPermission('bpm:model:update')")
  83 + public CommonResult<Boolean> updateModelState(@Valid @RequestBody BpmModelUpdateStateReqVO reqVO) {
  84 + modelService.updateModelState(reqVO.getId(), reqVO.getState());
  85 + return success(true);
  86 + }
  87 +
  88 + @DeleteMapping("/delete")
  89 + @ApiOperation("删除模型")
  90 + @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = String.class)
  91 + @PreAuthorize("@ss.hasPermission('bpm:model:delete')")
  92 + public CommonResult<Boolean> deleteModel(@RequestParam("id") String id) {
  93 + modelService.deleteModel(id);
  94 + return success(true);
  95 + }
79 } 96 }
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmProcessDefinitionController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.controller.admin.definition;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  5 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageItemRespVO;
  6 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageReqVO;
  7 +import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
  8 +import io.swagger.annotations.Api;
  9 +import io.swagger.annotations.ApiImplicitParam;
  10 +import io.swagger.annotations.ApiOperation;
  11 +import org.springframework.security.access.prepost.PreAuthorize;
  12 +import org.springframework.validation.annotation.Validated;
  13 +import org.springframework.web.bind.annotation.GetMapping;
  14 +import org.springframework.web.bind.annotation.RequestMapping;
  15 +import org.springframework.web.bind.annotation.RequestParam;
  16 +import org.springframework.web.bind.annotation.RestController;
  17 +
  18 +import javax.annotation.Resource;
  19 +
  20 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  21 +
  22 +@Api(tags = "管理后台 - 流程定义")
  23 +@RestController
  24 +@RequestMapping("/bpm/process-definition")
  25 +@Validated
  26 +public class BpmProcessDefinitionController {
  27 +
  28 + @Resource
  29 + private BpmProcessDefinitionService bpmDefinitionService;
  30 +
  31 + @GetMapping("/page")
  32 + @ApiOperation(value = "获得流程定义分页")
  33 + @PreAuthorize("@ss.hasPermission('bpm:process-definition:query')")
  34 + public CommonResult<PageResult<BpmProcessDefinitionPageItemRespVO>> getProcessDefinitionPage(
  35 + BpmProcessDefinitionPageReqVO pageReqVO) {
  36 + return success(bpmDefinitionService.getProcessDefinitionPage(pageReqVO));
  37 + }
  38 +
  39 + @GetMapping ("/get-bpmn-xml")
  40 + @ApiOperation(value = "获得流程定义的 BPMN XML")
  41 + @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = String.class)
  42 + @PreAuthorize("@ss.hasPermission('bpm:process-definition:query')")
  43 + public CommonResult<String> getProcessDefinitionBpmnXML(@RequestParam("id") String id) {
  44 + String bpmnXML = bpmDefinitionService.getProcessDefinitionBpmnXML(id);
  45 + return success(bpmnXML);
  46 + }
  47 +}
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/ModelConvert.java renamed to yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmModelConvert.java
@@ -25,9 +25,9 @@ import java.util.Objects; @@ -25,9 +25,9 @@ import java.util.Objects;
25 * @author yunlongn 25 * @author yunlongn
26 */ 26 */
27 @Mapper 27 @Mapper
28 -public interface ModelConvert { 28 +public interface BpmModelConvert {
29 29
30 - ModelConvert INSTANCE = Mappers.getMapper(ModelConvert.class); 30 + BpmModelConvert INSTANCE = Mappers.getMapper(BpmModelConvert.class);
31 31
32 default List<BpmModelPageItemRespVO> convertList(List<Model> list, Map<Long, BpmFormDO> formMap, 32 default List<BpmModelPageItemRespVO> convertList(List<Model> list, Map<Long, BpmFormDO> formMap,
33 Map<String, Deployment> deploymentMap, 33 Map<String, Deployment> deploymentMap,
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmProcessDefinitionConvert.java
1 package cn.iocoder.yudao.module.bpm.convert.definition; 1 package cn.iocoder.yudao.module.bpm.convert.definition;
2 2
  3 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
  4 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageItemRespVO;
  5 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionRespVO;
  6 +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
3 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO; 7 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO;
4 import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO; 8 import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO;
  9 +import org.flowable.common.engine.impl.db.SuspensionState;
  10 +import org.flowable.engine.repository.Deployment;
  11 +import org.flowable.engine.repository.ProcessDefinition;
5 import org.mapstruct.Mapper; 12 import org.mapstruct.Mapper;
  13 +import org.mapstruct.Mapping;
  14 +import org.mapstruct.MappingTarget;
6 import org.mapstruct.factory.Mappers; 15 import org.mapstruct.factory.Mappers;
7 16
  17 +import java.util.List;
  18 +import java.util.Map;
  19 +
8 /** 20 /**
9 * Bpm 流程定义的 Convert 21 * Bpm 流程定义的 Convert
10 * 22 *
@@ -12,7 +24,38 @@ import org.mapstruct.factory.Mappers; @@ -12,7 +24,38 @@ import org.mapstruct.factory.Mappers;
12 */ 24 */
13 @Mapper 25 @Mapper
14 public interface BpmProcessDefinitionConvert { 26 public interface BpmProcessDefinitionConvert {
  27 +
15 BpmProcessDefinitionConvert INSTANCE = Mappers.getMapper(BpmProcessDefinitionConvert.class); 28 BpmProcessDefinitionConvert INSTANCE = Mappers.getMapper(BpmProcessDefinitionConvert.class);
16 29
  30 + BpmProcessDefinitionPageItemRespVO convert(ProcessDefinition bean);
  31 +
17 BpmProcessDefinitionExtDO convert2(BpmProcessDefinitionCreateReqDTO bean); 32 BpmProcessDefinitionExtDO convert2(BpmProcessDefinitionCreateReqDTO bean);
  33 +
  34 + default List<BpmProcessDefinitionPageItemRespVO> convertList(List<ProcessDefinition> list, Map<String, Deployment> deploymentMap,
  35 + Map<String, BpmProcessDefinitionExtDO> processDefinitionDOMap, Map<Long, BpmFormDO> formMap) {
  36 + return CollectionUtils.convertList(list, definition -> {
  37 + Deployment deployment = definition.getDeploymentId() != null ? deploymentMap.get(definition.getDeploymentId()) : null;
  38 + BpmProcessDefinitionExtDO definitionDO = processDefinitionDOMap.get(definition.getId());
  39 + BpmFormDO form = definitionDO != null ? formMap.get(definitionDO.getFormId()) : null;
  40 + return convert(definition, deployment, definitionDO, form);
  41 + });
  42 + }
  43 +
  44 + default BpmProcessDefinitionPageItemRespVO convert(ProcessDefinition bean, Deployment deployment,
  45 + BpmProcessDefinitionExtDO processDefinitionExtDO, BpmFormDO form) {
  46 + BpmProcessDefinitionPageItemRespVO respVO = convert(bean);
  47 + respVO.setSuspensionState(bean.isSuspended() ? SuspensionState.SUSPENDED.getStateCode() : SuspensionState.ACTIVE.getStateCode());
  48 + if (deployment != null) {
  49 + respVO.setDeploymentTime(deployment.getDeploymentTime());
  50 + }
  51 + if (form != null) {
  52 + respVO.setFormName(form.getName());
  53 + }
  54 + // 复制通用属性
  55 + copyTo(processDefinitionExtDO, respVO);
  56 + return respVO;
  57 + }
  58 +
  59 + @Mapping(source = "from.id", target = "to.id", ignore = true)
  60 + void copyTo(BpmProcessDefinitionExtDO from, @MappingTarget BpmProcessDefinitionRespVO to);
18 } 61 }
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmTaskAssignRuleConvert.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.convert.definition;
  2 +
  3 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
  4 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleRespVO;
  5 +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO;
  6 +import org.flowable.bpmn.model.UserTask;
  7 +import org.mapstruct.Mapper;
  8 +import org.mapstruct.factory.Mappers;
  9 +
  10 +import java.util.List;
  11 +import java.util.Map;
  12 +
  13 +@Mapper
  14 +public interface BpmTaskAssignRuleConvert {
  15 + BpmTaskAssignRuleConvert INSTANCE = Mappers.getMapper(BpmTaskAssignRuleConvert.class);
  16 +
  17 + default List<BpmTaskAssignRuleRespVO> convertList(List<UserTask> tasks, List<BpmTaskAssignRuleDO> rules) {
  18 + Map<String, BpmTaskAssignRuleDO> ruleMap = CollectionUtils.convertMap(rules, BpmTaskAssignRuleDO::getTaskDefinitionKey);
  19 + // 以 UserTask 为主维度,原因是:流程图编辑后,一些规则实际就没用了。
  20 + return CollectionUtils.convertList(tasks, task -> {
  21 + BpmTaskAssignRuleRespVO respVO = convert(ruleMap.get(task.getId()));
  22 + if (respVO == null) {
  23 + respVO = new BpmTaskAssignRuleRespVO();
  24 + respVO.setTaskDefinitionKey(task.getId());
  25 + }
  26 + respVO.setTaskDefinitionName(task.getName());
  27 + return respVO;
  28 + });
  29 + }
  30 +
  31 + BpmTaskAssignRuleRespVO convert(BpmTaskAssignRuleDO bean);
  32 +}
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/FlowableModelService.java renamed to yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelService.java
1 package cn.iocoder.yudao.module.bpm.service.definition; 1 package cn.iocoder.yudao.module.bpm.service.definition;
2 2
  3 +import org.flowable.bpmn.model.BpmnModel;
  4 +
3 /** 5 /**
4 * Flowable流程模型接口 6 * Flowable流程模型接口
5 * 7 *
6 * @author yunlongn 8 * @author yunlongn
7 */ 9 */
8 -public interface FlowableModelService extends BpmModelCommonService { 10 +public interface BpmModelService extends BpmModelCommonService {
  11 +
  12 + /**
  13 + * 获得流程模型编号对应的 BPMN Model
  14 + *
  15 + * @param id 流程模型编号
  16 + * @return BPMN Model
  17 + */
  18 + BpmnModel getBpmnModel(String id);
9 19
10 } 20 }
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/FlowableModelServiceImpl.java renamed to yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java
1 package cn.iocoder.yudao.module.bpm.service.definition; 1 package cn.iocoder.yudao.module.bpm.service.definition;
2 2
  3 +import cn.hutool.core.util.ArrayUtil;
3 import cn.hutool.core.util.StrUtil; 4 import cn.hutool.core.util.StrUtil;
4 import cn.iocoder.yudao.framework.common.pojo.PageResult; 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; 6 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
6 import cn.iocoder.yudao.framework.common.util.json.JsonUtils; 7 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
7 import cn.iocoder.yudao.framework.common.util.object.PageUtils; 8 import cn.iocoder.yudao.framework.common.util.object.PageUtils;
8 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.*; 9 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.*;
9 -import cn.iocoder.yudao.module.bpm.convert.definition.ModelConvert; 10 +import cn.iocoder.yudao.module.bpm.convert.definition.BpmModelConvert;
10 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO; 11 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
11 import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmModelMetaInfoRespDTO; 12 import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmModelMetaInfoRespDTO;
12 import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO; 13 import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO;
13 import lombok.extern.slf4j.Slf4j; 14 import lombok.extern.slf4j.Slf4j;
  15 +import org.flowable.bpmn.converter.BpmnXMLConverter;
  16 +import org.flowable.bpmn.model.BpmnModel;
14 import org.flowable.common.engine.impl.db.SuspensionState; 17 import org.flowable.common.engine.impl.db.SuspensionState;
  18 +import org.flowable.common.engine.impl.util.io.BytesStreamSource;
15 import org.flowable.engine.RepositoryService; 19 import org.flowable.engine.RepositoryService;
16 import org.flowable.engine.repository.Deployment; 20 import org.flowable.engine.repository.Deployment;
17 import org.flowable.engine.repository.Model; 21 import org.flowable.engine.repository.Model;
@@ -41,15 +45,15 @@ import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*; @@ -41,15 +45,15 @@ import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*;
41 @Service 45 @Service
42 @Validated 46 @Validated
43 @Slf4j 47 @Slf4j
44 -public class FlowableModelServiceImpl extends BpmAbstractModelService implements FlowableModelService { 48 +public class BpmModelServiceImpl extends BpmAbstractModelService implements BpmModelService {
45 49
46 @Resource 50 @Resource
47 private RepositoryService repositoryService; 51 private RepositoryService repositoryService;
48 @Resource 52 @Resource
49 - private FlowableProcessDefinitionService processDefinitionService; 53 + private BpmProcessDefinitionService processDefinitionService;
50 54
51 - public FlowableModelServiceImpl(BpmFormService bpmFormService){  
52 - super(bpmFormService); 55 + public BpmModelServiceImpl(BpmFormService bpmFormService, BpmTaskAssignRuleService taskAssignRuleService){
  56 + super(bpmFormService, taskAssignRuleService);
53 } 57 }
54 58
55 @Override 59 @Override
@@ -85,7 +89,7 @@ public class FlowableModelServiceImpl extends BpmAbstractModelService implements @@ -85,7 +89,7 @@ public class FlowableModelServiceImpl extends BpmAbstractModelService implements
85 89
86 // 拼接结果 90 // 拼接结果
87 long modelCount = modelQuery.count(); 91 long modelCount = modelQuery.count();
88 - return new PageResult<>(ModelConvert.INSTANCE.convertList(models, formMap, deploymentMap, processDefinitionMap), modelCount); 92 + return new PageResult<>(BpmModelConvert.INSTANCE.convertList(models, formMap, deploymentMap, processDefinitionMap), modelCount);
89 } 93 }
90 94
91 @Override 95 @Override
@@ -100,7 +104,7 @@ public class FlowableModelServiceImpl extends BpmAbstractModelService implements @@ -100,7 +104,7 @@ public class FlowableModelServiceImpl extends BpmAbstractModelService implements
100 104
101 // 创建流程定义 105 // 创建流程定义
102 Model model = repositoryService.newModel(); 106 Model model = repositoryService.newModel();
103 - ModelConvert.INSTANCE.copy(model, createReqVO); 107 + BpmModelConvert.INSTANCE.copy(model, createReqVO);
104 // 保存流程定义 108 // 保存流程定义
105 repositoryService.saveModel(model); 109 repositoryService.saveModel(model);
106 // 保存 BPMN XML 110 // 保存 BPMN XML
@@ -108,13 +112,17 @@ public class FlowableModelServiceImpl extends BpmAbstractModelService implements @@ -108,13 +112,17 @@ public class FlowableModelServiceImpl extends BpmAbstractModelService implements
108 return model.getId(); 112 return model.getId();
109 } 113 }
110 114
  115 + private Model getModelByKey(String key) {
  116 + return repositoryService.createModelQuery().modelKey(key).singleResult();
  117 + }
  118 +
111 @Override 119 @Override
112 public BpmModelRespVO getModel(String id) { 120 public BpmModelRespVO getModel(String id) {
113 Model model = repositoryService.getModel(id); 121 Model model = repositoryService.getModel(id);
114 if (model == null) { 122 if (model == null) {
115 return null; 123 return null;
116 } 124 }
117 - BpmModelRespVO modelRespVO = ModelConvert.INSTANCE.convert(model); 125 + BpmModelRespVO modelRespVO = BpmModelConvert.INSTANCE.convert(model);
118 // 拼接 bpmn XML 126 // 拼接 bpmn XML
119 byte[] bpmnBytes = repositoryService.getModelEditorSource(id); 127 byte[] bpmnBytes = repositoryService.getModelEditorSource(id);
120 modelRespVO.setBpmnXml(StrUtil.utf8Str(bpmnBytes)); 128 modelRespVO.setBpmnXml(StrUtil.utf8Str(bpmnBytes));
@@ -130,7 +138,7 @@ public class FlowableModelServiceImpl extends BpmAbstractModelService implements @@ -130,7 +138,7 @@ public class FlowableModelServiceImpl extends BpmAbstractModelService implements
130 } 138 }
131 139
132 // 修改流程定义 140 // 修改流程定义
133 - ModelConvert.INSTANCE.copy(model, updateReqVO); 141 + BpmModelConvert.INSTANCE.copy(model, updateReqVO);
134 // 更新模型 142 // 更新模型
135 repositoryService.saveModel(model); 143 repositoryService.saveModel(model);
136 // 更新 BPMN XML 144 // 更新 BPMN XML
@@ -152,17 +160,17 @@ public class FlowableModelServiceImpl extends BpmAbstractModelService implements @@ -152,17 +160,17 @@ public class FlowableModelServiceImpl extends BpmAbstractModelService implements
152 // TODO 芋艿:校验流程图的有效性;例如说,是否有开始的元素,是否有结束的元素; 160 // TODO 芋艿:校验流程图的有效性;例如说,是否有开始的元素,是否有结束的元素;
153 // 校验表单已配 161 // 校验表单已配
154 BpmFormDO form = checkFormConfig(model.getMetaInfo()); 162 BpmFormDO form = checkFormConfig(model.getMetaInfo());
155 - //TODO 校验任务分配规则已配置  
156 - //checkTaskAssignRuleAllConfig(id);  
157 -  
158 - BpmProcessDefinitionCreateReqDTO definitionCreateReqDTO = ModelConvert.INSTANCE.convert2(model, form).setBpmnBytes(bpmnBytes);  
159 - // TODO 校验模型是否发生修改。如果未修改,则不允许创建  
160 -// if (processDefinitionService.isProcessDefinitionEquals(definitionCreateReqDTO)) { // 流程定义的信息相等  
161 -// ProcessDefinition oldProcessInstance = processDefinitionService.getProcessDefinitionByDeploymentId(model.getDeploymentId());  
162 -// if (oldProcessInstance != null && taskAssignRuleService.isTaskAssignRulesEquals(model.getId(), oldProcessInstance.getId())) {  
163 -// throw exception(MODEL_DEPLOY_FAIL_TASK_INFO_EQUALS);  
164 -// }  
165 -// } 163 + //校验任务分配规则已配置
  164 + checkTaskAssignRuleAllConfig(id);
  165 +
  166 + BpmProcessDefinitionCreateReqDTO definitionCreateReqDTO = BpmModelConvert.INSTANCE.convert2(model, form).setBpmnBytes(bpmnBytes);
  167 + //校验模型是否发生修改。如果未修改,则不允许创建
  168 + if (processDefinitionService.isProcessDefinitionEquals(definitionCreateReqDTO)) { // 流程定义的信息相等
  169 + ProcessDefinition oldProcessInstance = processDefinitionService.getProcessDefinitionByDeploymentId(model.getDeploymentId());
  170 + if (oldProcessInstance != null && taskAssignRuleService.isTaskAssignRulesEquals(model.getId(), oldProcessInstance.getId())) {
  171 + throw exception(MODEL_DEPLOY_FAIL_TASK_INFO_EQUALS);
  172 + }
  173 + }
166 // 创建流程定义 174 // 创建流程定义
167 String definitionId = processDefinitionService.createProcessDefinition(definitionCreateReqDTO); 175 String definitionId = processDefinitionService.createProcessDefinition(definitionCreateReqDTO);
168 176
@@ -178,23 +186,38 @@ public class FlowableModelServiceImpl extends BpmAbstractModelService implements @@ -178,23 +186,38 @@ public class FlowableModelServiceImpl extends BpmAbstractModelService implements
178 //taskAssignRuleService.copyTaskAssignRules(id, definition.getId()); 186 //taskAssignRuleService.copyTaskAssignRules(id, definition.getId());
179 } 187 }
180 188
  189 +
181 @Override 190 @Override
  191 + @Transactional(rollbackFor = Exception.class)
182 public void deleteModel(String id) { 192 public void deleteModel(String id) {
183 - 193 + // 校验流程模型存在
  194 + Model model = repositoryService.getModel(id);
  195 + if (model == null) {
  196 + throw exception(MODEL_NOT_EXISTS);
  197 + }
  198 + // 执行删除
  199 + repositoryService.deleteModel(id);
  200 + // 禁用流程实例
  201 + updateProcessDefinitionSuspended(model.getDeploymentId());
184 } 202 }
185 203
186 @Override 204 @Override
187 public void updateModelState(String id, Integer state) { 205 public void updateModelState(String id, Integer state) {
  206 + // 校验流程模型存在
  207 + Model model = repositoryService.getModel(id);
  208 + if (model == null) {
  209 + throw exception(MODEL_NOT_EXISTS);
  210 + }
  211 + // 校验流程定义存在
  212 + ProcessDefinition definition = processDefinitionService.getProcessDefinitionByDeploymentId(model.getDeploymentId());
  213 + if (definition == null) {
  214 + throw exception(PROCESS_DEFINITION_NOT_EXISTS);
  215 + }
188 216
  217 + // 更新状态
  218 + processDefinitionService.updateProcessDefinitionState(definition.getId(), state);
189 } 219 }
190 220
191 -  
192 -  
193 - private Model getModelByKey(String key) {  
194 - return repositoryService.createModelQuery().modelKey(key).singleResult();  
195 - }  
196 -  
197 -  
198 private void saveModelBpmnXml(Model model, String bpmnXml) { 221 private void saveModelBpmnXml(Model model, String bpmnXml) {
199 if (StrUtil.isEmpty(bpmnXml)) { 222 if (StrUtil.isEmpty(bpmnXml)) {
200 return; 223 return;
@@ -202,6 +225,10 @@ public class FlowableModelServiceImpl extends BpmAbstractModelService implements @@ -202,6 +225,10 @@ public class FlowableModelServiceImpl extends BpmAbstractModelService implements
202 repositoryService.addModelEditorSource(model.getId(), StrUtil.utf8Bytes(bpmnXml)); 225 repositoryService.addModelEditorSource(model.getId(), StrUtil.utf8Bytes(bpmnXml));
203 } 226 }
204 227
  228 + /**
  229 + * 挂起 deploymentId 对应的流程定义。 这里一个deploymentId 只关联一个流程定义
  230 + * @param deploymentId 流程发布Id.
  231 + */
205 private void updateProcessDefinitionSuspended(String deploymentId) { 232 private void updateProcessDefinitionSuspended(String deploymentId) {
206 if (StrUtil.isEmpty(deploymentId)) { 233 if (StrUtil.isEmpty(deploymentId)) {
207 return; 234 return;
@@ -212,4 +239,14 @@ public class FlowableModelServiceImpl extends BpmAbstractModelService implements @@ -212,4 +239,14 @@ public class FlowableModelServiceImpl extends BpmAbstractModelService implements
212 } 239 }
213 processDefinitionService.updateProcessDefinitionState(oldDefinition.getId(), SuspensionState.SUSPENDED.getStateCode()); 240 processDefinitionService.updateProcessDefinitionState(oldDefinition.getId(), SuspensionState.SUSPENDED.getStateCode());
214 } 241 }
  242 +
  243 + @Override
  244 + public BpmnModel getBpmnModel(String id) {
  245 + byte[] bpmnBytes = repositoryService.getModelEditorSource(id);
  246 + if (ArrayUtil.isEmpty(bpmnBytes)) {
  247 + return null;
  248 + }
  249 + BpmnXMLConverter converter = new BpmnXMLConverter();
  250 + return converter.convertToBpmnModel(new BytesStreamSource(bpmnBytes), true, true);
  251 + }
215 } 252 }
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/FlowableProcessDefinitionService.java renamed to yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionService.java
1 package cn.iocoder.yudao.module.bpm.service.definition; 1 package cn.iocoder.yudao.module.bpm.service.definition;
2 2
3 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; 3 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
4 -import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO; 4 +import org.flowable.bpmn.model.BpmnModel;
5 import org.flowable.engine.repository.Deployment; 5 import org.flowable.engine.repository.Deployment;
6 import org.flowable.engine.repository.ProcessDefinition; 6 import org.flowable.engine.repository.ProcessDefinition;
7 7
8 -import javax.validation.Valid;  
9 import java.util.List; 8 import java.util.List;
10 import java.util.Map; 9 import java.util.Map;
11 import java.util.Set; 10 import java.util.Set;
@@ -16,7 +15,7 @@ import java.util.Set; @@ -16,7 +15,7 @@ import java.util.Set;
16 * @author ZJQ 15 * @author ZJQ
17 * @author 芋道源码 16 * @author 芋道源码
18 */ 17 */
19 -public interface FlowableProcessDefinitionService { 18 +public interface BpmProcessDefinitionService extends BpmProcessDefinitionCommonService {
20 19
21 /** 20 /**
22 * 获得编号对应的 ProcessDefinition 21 * 获得编号对应的 ProcessDefinition
@@ -43,6 +42,14 @@ public interface FlowableProcessDefinitionService { @@ -43,6 +42,14 @@ public interface FlowableProcessDefinitionService {
43 List<ProcessDefinition> getProcessDefinitionListByDeploymentIds(Set<String> deploymentIds); 42 List<ProcessDefinition> getProcessDefinitionListByDeploymentIds(Set<String> deploymentIds);
44 43
45 /** 44 /**
  45 + * 获得流程定义标识对应的激活的流程定义
  46 + *
  47 + * @param key 流程定义的标识
  48 + * @return 流程定义
  49 + */
  50 + ProcessDefinition getActiveProcessDefinition(String key);
  51 +
  52 + /**
46 * 获得 ids 对应的 Deployment Map 53 * 获得 ids 对应的 Deployment Map
47 * 54 *
48 * @param ids 部署编号的数组 55 * @param ids 部署编号的数组
@@ -69,18 +76,10 @@ public interface FlowableProcessDefinitionService { @@ -69,18 +76,10 @@ public interface FlowableProcessDefinitionService {
69 Deployment getDeployment(String id); 76 Deployment getDeployment(String id);
70 77
71 /** 78 /**
72 - * 创建流程定义  
73 - *  
74 - * @param createReqDTO 创建信息  
75 - * @return 流程编号  
76 - */  
77 - String createProcessDefinition(@Valid BpmProcessDefinitionCreateReqDTO createReqDTO);  
78 -  
79 - /**  
80 - * 更新流程定义状态 79 + * 获得 Bpmn 模型
81 * 80 *
82 - * @param id 流程定义的编号  
83 - * @param state 状态 81 + * @param processDefinitionId 流程定义的编号
  82 + * @return Bpmn 模型
84 */ 83 */
85 - void updateProcessDefinitionState(String id, Integer state); 84 + BpmnModel getBpmnModel(String processDefinitionId);
86 } 85 }
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/FlowableProcessDefinitionServiceImpl.java renamed to yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java
1 package cn.iocoder.yudao.module.bpm.service.definition; 1 package cn.iocoder.yudao.module.bpm.service.definition;
2 2
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
  4 +import cn.hutool.core.util.ObjectUtil;
4 import cn.hutool.core.util.StrUtil; 5 import cn.hutool.core.util.StrUtil;
  6 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  7 +import cn.iocoder.yudao.framework.common.util.object.PageUtils;
  8 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageItemRespVO;
  9 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageReqVO;
5 import cn.iocoder.yudao.module.bpm.convert.definition.BpmProcessDefinitionConvert; 10 import cn.iocoder.yudao.module.bpm.convert.definition.BpmProcessDefinitionConvert;
  11 +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
6 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO; 12 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO;
7 import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmProcessDefinitionExtMapper; 13 import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmProcessDefinitionExtMapper;
8 import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO; 14 import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO;
9 import lombok.extern.slf4j.Slf4j; 15 import lombok.extern.slf4j.Slf4j;
  16 +import org.flowable.bpmn.converter.BpmnXMLConverter;
  17 +import org.flowable.bpmn.model.BpmnModel;
10 import org.flowable.common.engine.impl.db.SuspensionState; 18 import org.flowable.common.engine.impl.db.SuspensionState;
  19 +import org.flowable.common.engine.impl.util.io.BytesStreamSource;
11 import org.flowable.engine.RepositoryService; 20 import org.flowable.engine.RepositoryService;
12 import org.flowable.engine.repository.Deployment; 21 import org.flowable.engine.repository.Deployment;
13 import org.flowable.engine.repository.ProcessDefinition; 22 import org.flowable.engine.repository.ProcessDefinition;
  23 +import org.flowable.engine.repository.ProcessDefinitionQuery;
14 import org.springframework.stereotype.Service; 24 import org.springframework.stereotype.Service;
15 import org.springframework.validation.annotation.Validated; 25 import org.springframework.validation.annotation.Validated;
16 26
17 import javax.annotation.Resource; 27 import javax.annotation.Resource;
18 import javax.validation.Valid; 28 import javax.validation.Valid;
19 -import java.util.ArrayList;  
20 -import java.util.List;  
21 -import java.util.Objects;  
22 -import java.util.Set; 29 +import java.util.*;
23 30
24 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 31 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
25 -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.addIfNotNull; 32 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
  33 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
26 import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_DEFINITION_KEY_NOT_MATCH; 34 import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_DEFINITION_KEY_NOT_MATCH;
27 import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_DEFINITION_NAME_NOT_MATCH; 35 import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_DEFINITION_NAME_NOT_MATCH;
28 import static java.util.Collections.emptyList; 36 import static java.util.Collections.emptyList;
@@ -38,7 +46,7 @@ import static java.util.Collections.emptyList; @@ -38,7 +46,7 @@ import static java.util.Collections.emptyList;
38 @Service 46 @Service
39 @Validated 47 @Validated
40 @Slf4j 48 @Slf4j
41 -public class FlowableProcessDefinitionServiceImpl implements FlowableProcessDefinitionService { 49 +public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionService {
42 50
43 private static final String BPMN_FILE_SUFFIX = ".bpmn"; 51 private static final String BPMN_FILE_SUFFIX = ".bpmn";
44 52
@@ -48,6 +56,9 @@ public class FlowableProcessDefinitionServiceImpl implements FlowableProcessDefi @@ -48,6 +56,9 @@ public class FlowableProcessDefinitionServiceImpl implements FlowableProcessDefi
48 @Resource 56 @Resource
49 private BpmProcessDefinitionExtMapper processDefinitionMapper; 57 private BpmProcessDefinitionExtMapper processDefinitionMapper;
50 58
  59 + @Resource
  60 + private BpmFormService formService;
  61 +
51 @Override 62 @Override
52 public ProcessDefinition getProcessDefinition(String id) { 63 public ProcessDefinition getProcessDefinition(String id) {
53 return repositoryService.getProcessDefinition(id); 64 return repositoryService.getProcessDefinition(id);
@@ -70,6 +81,11 @@ public class FlowableProcessDefinitionServiceImpl implements FlowableProcessDefi @@ -70,6 +81,11 @@ public class FlowableProcessDefinitionServiceImpl implements FlowableProcessDefi
70 } 81 }
71 82
72 @Override 83 @Override
  84 + public ProcessDefinition getActiveProcessDefinition(String key) {
  85 + return repositoryService.createProcessDefinitionQuery().processDefinitionKey(key).active().singleResult();
  86 + }
  87 +
  88 + @Override
73 public List<Deployment> getDeployments(Set<String> ids) { 89 public List<Deployment> getDeployments(Set<String> ids) {
74 if (CollUtil.isEmpty(ids)) { 90 if (CollUtil.isEmpty(ids)) {
75 return emptyList(); 91 return emptyList();
@@ -90,6 +106,11 @@ public class FlowableProcessDefinitionServiceImpl implements FlowableProcessDefi @@ -90,6 +106,11 @@ public class FlowableProcessDefinitionServiceImpl implements FlowableProcessDefi
90 } 106 }
91 107
92 @Override 108 @Override
  109 + public BpmnModel getBpmnModel(String processDefinitionId) {
  110 + return repositoryService.getBpmnModel(processDefinitionId);
  111 + }
  112 +
  113 + @Override
93 public String createProcessDefinition(@Valid BpmProcessDefinitionCreateReqDTO createReqDTO) { 114 public String createProcessDefinition(@Valid BpmProcessDefinitionCreateReqDTO createReqDTO) {
94 // 创建 Deployment 部署 115 // 创建 Deployment 部署
95 Deployment deploy = repositoryService.createDeployment() 116 Deployment deploy = repositoryService.createDeployment()
@@ -133,4 +154,112 @@ public class FlowableProcessDefinitionServiceImpl implements FlowableProcessDefi @@ -133,4 +154,112 @@ public class FlowableProcessDefinitionServiceImpl implements FlowableProcessDefi
133 } 154 }
134 log.error("[updateProcessDefinitionState][流程定义({}) 修改未知状态({})]", id, state); 155 log.error("[updateProcessDefinitionState][流程定义({}) 修改未知状态({})]", id, state);
135 } 156 }
  157 +
  158 + @Override
  159 + public String getProcessDefinitionBpmnXML(String id) {
  160 + BpmnModel bpmnModel = repositoryService.getBpmnModel(id);
  161 + if (bpmnModel == null) {
  162 + return null;
  163 + }
  164 + BpmnXMLConverter converter = new BpmnXMLConverter();
  165 + return StrUtil.utf8Str(converter.convertToXML(bpmnModel));
  166 + }
  167 +
  168 + @Override
  169 + public boolean isProcessDefinitionEquals(@Valid BpmProcessDefinitionCreateReqDTO createReqDTO) {
  170 + // 校验 name、description 是否更新
  171 + ProcessDefinition oldProcessDefinition = getActiveProcessDefinition(createReqDTO.getKey());
  172 + if (oldProcessDefinition == null) {
  173 + return false;
  174 + }
  175 + BpmProcessDefinitionExtDO oldProcessDefinitionExt = getProcessDefinitionExt(oldProcessDefinition.getId());
  176 + if (!StrUtil.equals(createReqDTO.getName(), oldProcessDefinition.getName())
  177 + || !StrUtil.equals(createReqDTO.getDescription(), oldProcessDefinitionExt.getDescription())
  178 + || !StrUtil.equals(createReqDTO.getCategory(), oldProcessDefinition.getCategory())) {
  179 + return false;
  180 + }
  181 + // 校验 form 信息是否更新
  182 + if (!ObjectUtil.equal(createReqDTO.getFormType(), oldProcessDefinitionExt.getFormType())
  183 + || !ObjectUtil.equal(createReqDTO.getFormId(), oldProcessDefinitionExt.getFormId())
  184 + || !ObjectUtil.equal(createReqDTO.getFormConf(), oldProcessDefinitionExt.getFormConf())
  185 + || !ObjectUtil.equal(createReqDTO.getFormFields(), oldProcessDefinitionExt.getFormFields())
  186 + || !ObjectUtil.equal(createReqDTO.getFormCustomCreatePath(), oldProcessDefinitionExt.getFormCustomCreatePath())
  187 + || !ObjectUtil.equal(createReqDTO.getFormCustomViewPath(), oldProcessDefinitionExt.getFormCustomViewPath())) {
  188 + return false;
  189 + }
  190 + // 校验 BPMN XML 信息
  191 + BpmnModel newModel = buildBpmnModel(createReqDTO.getBpmnBytes());
  192 + BpmnModel oldModel = getBpmnModel(oldProcessDefinition.getId());
  193 + //TODO 貌似 flowable 不修改这个也不同。需要看看。 sourceSystemId 不同
  194 + if (equals(oldModel, newModel)) {
  195 + return false;
  196 + }
  197 + // 最终发现都一致,则返回 true
  198 + return true;
  199 + }
  200 +
  201 + /**
  202 + * 构建对应的 BPMN Model
  203 + *
  204 + * @param bpmnBytes 原始的 BPMN XML 字节数组
  205 + * @return BPMN Model
  206 + */
  207 + private BpmnModel buildBpmnModel(byte[] bpmnBytes) {
  208 + // 转换成 BpmnModel 对象
  209 + BpmnXMLConverter converter = new BpmnXMLConverter();
  210 + return converter.convertToBpmnModel(new BytesStreamSource(bpmnBytes), true, true);
  211 + }
  212 + //TODO 移出去
  213 + public boolean equals(BpmnModel oldModel, BpmnModel newModel) {
  214 + // 由于 BpmnModel 未提供 equals 方法,所以只能转成字节数组,进行比较
  215 + return Arrays.equals(getBpmnBytes(oldModel), getBpmnBytes(newModel));
  216 + }
  217 + //TODO 移出去
  218 + public byte[] getBpmnBytes(BpmnModel model) {
  219 + if (model == null) {
  220 + return new byte[0];
  221 + }
  222 + BpmnXMLConverter converter = new BpmnXMLConverter();
  223 + return converter.convertToXML(model);
  224 + }
  225 +
  226 + @Override
  227 + public BpmProcessDefinitionExtDO getProcessDefinitionExt(String id) {
  228 + return processDefinitionMapper.selectByProcessDefinitionId(id);
  229 + }
  230 +
  231 + @Override
  232 + public PageResult<BpmProcessDefinitionPageItemRespVO> getProcessDefinitionPage(BpmProcessDefinitionPageReqVO pageVO) {
  233 + ProcessDefinitionQuery definitionQuery = repositoryService.createProcessDefinitionQuery();
  234 + if (StrUtil.isNotBlank(pageVO.getKey())) {
  235 + definitionQuery.processDefinitionKey(pageVO.getKey());
  236 + }
  237 +
  238 + // 执行查询
  239 + List<ProcessDefinition> processDefinitions = definitionQuery.orderByProcessDefinitionVersion().desc()
  240 + .listPage(PageUtils.getStart(pageVO), pageVO.getPageSize());
  241 +
  242 + if (CollUtil.isEmpty(processDefinitions)) {
  243 + return new PageResult<>(emptyList(), definitionQuery.count());
  244 + }
  245 + // 获得 Deployment Map
  246 + Set<String> deploymentIds = new HashSet<>();
  247 + processDefinitions.forEach(definition -> addIfNotNull(deploymentIds, definition.getDeploymentId()));
  248 + Map<String, Deployment> deploymentMap = getDeploymentMap(deploymentIds);
  249 +
  250 + // 获得 BpmProcessDefinitionDO Map
  251 + List<BpmProcessDefinitionExtDO> processDefinitionDOs = processDefinitionMapper.selectListByProcessDefinitionIds(
  252 + convertList(processDefinitions, ProcessDefinition::getId));
  253 + Map<String, BpmProcessDefinitionExtDO> processDefinitionDOMap = convertMap(processDefinitionDOs,
  254 + BpmProcessDefinitionExtDO::getProcessDefinitionId);
  255 +
  256 + // 获得 Form Map
  257 + Set<Long> formIds = convertSet(processDefinitionDOs, BpmProcessDefinitionExtDO::getFormId);
  258 + Map<Long, BpmFormDO> formMap = formService.getFormMap(formIds);
  259 +
  260 + // 拼接结果
  261 + long definitionCount = definitionQuery.count();
  262 + return new PageResult<>(BpmProcessDefinitionConvert.INSTANCE.convertList(processDefinitions, deploymentMap,
  263 + processDefinitionDOMap, formMap), definitionCount);
  264 + }
136 } 265 }
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.service.definition;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.hutool.core.util.ObjectUtil;
  5 +import cn.hutool.core.util.StrUtil;
  6 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
  7 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleCreateReqVO;
  8 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleRespVO;
  9 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleUpdateReqVO;
  10 +import cn.iocoder.yudao.module.bpm.convert.definition.BpmTaskAssignRuleConvert;
  11 +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO;
  12 +import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmTaskAssignRuleMapper;
  13 +import lombok.extern.slf4j.Slf4j;
  14 +import org.flowable.bpmn.model.BpmnModel;
  15 +import org.flowable.bpmn.model.FlowElement;
  16 +import org.flowable.bpmn.model.UserTask;
  17 +import org.springframework.context.annotation.Lazy;
  18 +import org.springframework.stereotype.Service;
  19 +import org.springframework.validation.annotation.Validated;
  20 +
  21 +import javax.annotation.Resource;
  22 +import javax.validation.Valid;
  23 +import java.util.ArrayList;
  24 +import java.util.Collections;
  25 +import java.util.List;
  26 +import java.util.Map;
  27 +
  28 +/**
  29 + * BPM 任务分配规则 Service 实现类
  30 + */
  31 +@Service
  32 +@Validated
  33 +@Slf4j
  34 +public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService{
  35 +
  36 + @Resource
  37 + private BpmTaskAssignRuleMapper taskRuleMapper;
  38 +
  39 + @Resource
  40 + @Lazy // 解决循环依赖
  41 + private BpmModelService modelService;
  42 +
  43 + @Resource
  44 + private BpmProcessDefinitionService processDefinitionService;
  45 +
  46 + @Override
  47 + public List<BpmTaskAssignRuleDO> getTaskAssignRuleListByProcessDefinitionId(String processDefinitionId, String taskDefinitionKey) {
  48 + return taskRuleMapper.selectListByProcessDefinitionId(processDefinitionId, taskDefinitionKey);
  49 + }
  50 +
  51 + @Override
  52 + public List<BpmTaskAssignRuleDO> getTaskAssignRuleListByModelId(String modelId) {
  53 + return taskRuleMapper.selectListByModelId(modelId);
  54 + }
  55 +
  56 + @Override
  57 + public List<BpmTaskAssignRuleRespVO> getTaskAssignRuleList(String modelId, String processDefinitionId) {
  58 + // 获得规则
  59 + List<BpmTaskAssignRuleDO> rules = Collections.emptyList();
  60 + BpmnModel model = null;
  61 + if (StrUtil.isNotEmpty(modelId)) {
  62 + rules = getTaskAssignRuleListByModelId(modelId);
  63 + model = modelService.getBpmnModel(modelId);
  64 + } else if (StrUtil.isNotEmpty(processDefinitionId)) {
  65 + rules = getTaskAssignRuleListByProcessDefinitionId(processDefinitionId, null);
  66 + model = processDefinitionService.getBpmnModel(processDefinitionId);
  67 + }
  68 + if (model == null) {
  69 + return Collections.emptyList();
  70 + }
  71 +
  72 + // 获得用户任务,只有用户任务才可以设置分配规则
  73 + List<UserTask> userTasks = getBpmnModelElements(model, UserTask.class);
  74 + if (CollUtil.isEmpty(userTasks)) {
  75 + return Collections.emptyList();
  76 + }
  77 +
  78 + // 转换数据
  79 + return BpmTaskAssignRuleConvert.INSTANCE.convertList(userTasks, rules);
  80 + }
  81 +
  82 + /**
  83 + * TODO 需要移出去
  84 + * 获得 BPMN 流程中,指定的元素们
  85 + *
  86 + * @param model
  87 + * @param clazz 指定元素。例如说,{@link org.flowable.bpmn.model.UserTask}、{@link org.flowable.bpmn.model.Gateway} 等等
  88 + * @return 元素们
  89 + */
  90 + public static <T extends FlowElement> List<T> getBpmnModelElements(BpmnModel model, Class<T> clazz) {
  91 + List<T> result = new ArrayList<>();
  92 + model.getProcesses().forEach(process -> {
  93 + process.getFlowElements().forEach(flowElement -> {
  94 + if (flowElement.getClass().isAssignableFrom(clazz)) {
  95 + result.add((T) flowElement);
  96 + }
  97 + });
  98 + });
  99 + return result;
  100 + }
  101 +
  102 + @Override
  103 + public Long createTaskAssignRule(@Valid BpmTaskAssignRuleCreateReqVO reqVO) {
  104 + return null;
  105 + }
  106 +
  107 + @Override
  108 + public void updateTaskAssignRule(@Valid BpmTaskAssignRuleUpdateReqVO reqVO) {
  109 +
  110 + }
  111 +
  112 + @Override
  113 + public boolean isTaskAssignRulesEquals(String modelId, String processDefinitionId) {
  114 + // 调用 VO 接口的原因是,过滤掉流程模型不需要的规则,保持和 copyTaskAssignRules 方法的一致性
  115 + List<BpmTaskAssignRuleRespVO> modelRules = getTaskAssignRuleList(modelId, null);
  116 + List<BpmTaskAssignRuleRespVO> processInstanceRules = getTaskAssignRuleList(null, processDefinitionId);
  117 + if (modelRules.size() != processInstanceRules.size()) {
  118 + return false;
  119 + }
  120 +
  121 + // 遍历,匹配对应的规则
  122 + Map<String, BpmTaskAssignRuleRespVO> processInstanceRuleMap = CollectionUtils.convertMap(processInstanceRules,
  123 + BpmTaskAssignRuleRespVO::getTaskDefinitionKey);
  124 + for (BpmTaskAssignRuleRespVO modelRule : modelRules) {
  125 + BpmTaskAssignRuleRespVO processInstanceRule = processInstanceRuleMap.get(modelRule.getTaskDefinitionKey());
  126 + if (processInstanceRule == null) {
  127 + return false;
  128 + }
  129 + if (!ObjectUtil.equals(modelRule.getType(), processInstanceRule.getType())
  130 + || !ObjectUtil.equal(modelRule.getOptions(), processInstanceRule.getOptions())) {
  131 + return false;
  132 + }
  133 + }
  134 + return true;
  135 + }
  136 +
  137 + @Override
  138 + public void copyTaskAssignRules(String fromModelId, String toProcessDefinitionId) {
  139 +
  140 + }
  141 +}