Commit e4fbc11dc453e86097270a2131bd1314186f3cb0

Authored by jason
1 parent cb5cfd31

仿钉钉流程设计- 前端重构调整, 新增多人审批方式

yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmApproveMethodEnum.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.enums.definition;
  2 +
  3 +import cn.hutool.core.util.ArrayUtil;
  4 +import lombok.AllArgsConstructor;
  5 +import lombok.Getter;
  6 +
  7 +/**
  8 + * BPM 审批方式的枚举
  9 + *
  10 + * @author jason
  11 + */
  12 +@Getter
  13 +@AllArgsConstructor
  14 +public enum BpmApproveMethodEnum {
  15 +
  16 + SINGLE_PERSON_APPROVE(1, "单人审批"),
  17 + ALL_APPROVE(2, "多人会签(需所有审批人同意)"),
  18 + ANY_OF_APPROVE(3, "多人或签(一名审批人同意即可)"),
  19 + SEQUENTIAL_APPROVE(4, "依次审批");
  20 +
  21 + /**
  22 + * 审批方式
  23 + */
  24 + private final Integer method;
  25 + /**
  26 + * 名字
  27 + */
  28 + private final String name;
  29 +
  30 + public static BpmApproveMethodEnum valueOf(Integer method) {
  31 + return ArrayUtil.firstMatch(item -> item.getMethod().equals(method), values());
  32 + }
  33 +}
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/simple/BpmSimpleModelNodeVO.java
@@ -28,6 +28,9 @@ public class BpmSimpleModelNodeVO { @@ -28,6 +28,9 @@ public class BpmSimpleModelNodeVO {
28 @Schema(description = "模型节点名称", example = "领导审批") 28 @Schema(description = "模型节点名称", example = "领导审批")
29 private String name; 29 private String name;
30 30
  31 + @Schema(description = "节点展示内容", example = "指定成员: 芋道源码")
  32 + private String showText;
  33 +
31 @Schema(description = "孩子节点") 34 @Schema(description = "孩子节点")
32 private BpmSimpleModelNodeVO childNode; 35 private BpmSimpleModelNodeVO childNode;
33 36
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/enums/SimpleModelConstants.java
@@ -7,4 +7,8 @@ package cn.iocoder.yudao.module.bpm.framework.flowable.core.enums; @@ -7,4 +7,8 @@ package cn.iocoder.yudao.module.bpm.framework.flowable.core.enums;
7 */ 7 */
8 public interface SimpleModelConstants { 8 public interface SimpleModelConstants {
9 9
  10 + /**
  11 + * 审批方式属性
  12 + */
  13 + String APPROVE_METHOD_ATTRIBUTE = "approveMethod";
10 } 14 }
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/SimpleModelUtils.java
@@ -7,8 +7,10 @@ import cn.hutool.core.map.MapUtil; @@ -7,8 +7,10 @@ import cn.hutool.core.map.MapUtil;
7 import cn.hutool.core.util.ArrayUtil; 7 import cn.hutool.core.util.ArrayUtil;
8 import cn.hutool.core.util.StrUtil; 8 import cn.hutool.core.util.StrUtil;
9 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.simple.BpmSimpleModelNodeVO; 9 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.simple.BpmSimpleModelNodeVO;
  10 +import cn.iocoder.yudao.module.bpm.enums.definition.BpmApproveMethodEnum;
10 import cn.iocoder.yudao.module.bpm.enums.definition.BpmSimpleModelNodeType; 11 import cn.iocoder.yudao.module.bpm.enums.definition.BpmSimpleModelNodeType;
11 import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants; 12 import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants;
  13 +import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.SimpleModelConstants;
12 import org.flowable.bpmn.BpmnAutoLayout; 14 import org.flowable.bpmn.BpmnAutoLayout;
13 import org.flowable.bpmn.model.Process; 15 import org.flowable.bpmn.model.Process;
14 import org.flowable.bpmn.model.*; 16 import org.flowable.bpmn.model.*;
@@ -16,6 +18,7 @@ import org.flowable.bpmn.model.*; @@ -16,6 +18,7 @@ import org.flowable.bpmn.model.*;
16 import java.util.List; 18 import java.util.List;
17 import java.util.Map; 19 import java.util.Map;
18 20
  21 +import static cn.iocoder.yudao.module.bpm.enums.definition.BpmSimpleModelNodeType.END_EVENT;
19 import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants.FORM_FIELD_PERMISSION_ELEMENT; 22 import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants.FORM_FIELD_PERMISSION_ELEMENT;
20 import static org.flowable.bpmn.constants.BpmnXMLConstants.FLOWABLE_EXTENSIONS_NAMESPACE; 23 import static org.flowable.bpmn.constants.BpmnXMLConstants.FLOWABLE_EXTENSIONS_NAMESPACE;
21 import static org.flowable.bpmn.constants.BpmnXMLConstants.FLOWABLE_EXTENSIONS_PREFIX; 24 import static org.flowable.bpmn.constants.BpmnXMLConstants.FLOWABLE_EXTENSIONS_PREFIX;
@@ -30,6 +33,16 @@ public class SimpleModelUtils { @@ -30,6 +33,16 @@ public class SimpleModelUtils {
30 public static final String BPMN_SIMPLE_COPY_EXECUTION_SCRIPT = "#{bpmSimpleNodeService.copy(execution)}"; 33 public static final String BPMN_SIMPLE_COPY_EXECUTION_SCRIPT = "#{bpmSimpleNodeService.copy(execution)}";
31 34
32 /** 35 /**
  36 + * 所有审批人同意的表达式
  37 + */
  38 + public static final String ALL_APPROVE_COMPLETE_EXPRESSION = "${ nrOfCompletedInstances >= 0 }";
  39 +
  40 + /**
  41 + * 任一一名审批人同意的表达式
  42 + */
  43 + public static final String ANY_OF_APPROVE_COMPLETE_EXPRESSION = "${ nrOfCompletedInstances >= nrOfInstances }";
  44 +
  45 + /**
33 * 仿钉钉流程设计模型数据结构(json) 转换成 Bpmn Model (待完善) 46 * 仿钉钉流程设计模型数据结构(json) 转换成 Bpmn Model (待完善)
34 * 47 *
35 * @param processId 流程标识 48 * @param processId 流程标识
@@ -47,10 +60,15 @@ public class SimpleModelUtils { @@ -47,10 +60,15 @@ public class SimpleModelUtils {
47 // 前端模型数据结构。 有 start event 节点. 没有 end event 节点。 60 // 前端模型数据结构。 有 start event 节点. 没有 end event 节点。
48 // 从 SimpleModel 构建 FlowNode 并添加到 Main Process 61 // 从 SimpleModel 构建 FlowNode 并添加到 Main Process
49 buildAndAddBpmnFlowNode(simpleModelNode, mainProcess); 62 buildAndAddBpmnFlowNode(simpleModelNode, mainProcess);
50 - // 单独构建 end event 节点  
51 - buildAndAddBpmnEndEvent(mainProcess); 63 + // 找到 end event
  64 + EndEvent endEvent = (EndEvent) CollUtil.findOne(mainProcess.getFlowElements(), item -> item instanceof EndEvent);
  65 + if (endEvent == null) {
  66 + // 暂时为了兼容 单独构建 end event 节点
  67 + endEvent = buildAndAddBpmnEndEvent(mainProcess);
  68 + }
  69 +
52 // 构建并添加节点之间的连线 Sequence Flow 70 // 构建并添加节点之间的连线 Sequence Flow
53 - buildAndAddBpmnSequenceFlow(mainProcess, simpleModelNode, BpmnModelConstants.END_EVENT_ID); 71 + buildAndAddBpmnSequenceFlow(mainProcess, simpleModelNode, endEvent.getId());
54 // 自动布局 72 // 自动布局
55 new BpmnAutoLayout(bpmnModel).execute(); 73 new BpmnAutoLayout(bpmnModel).execute();
56 return bpmnModel; 74 return bpmnModel;
@@ -58,7 +76,7 @@ public class SimpleModelUtils { @@ -58,7 +76,7 @@ public class SimpleModelUtils {
58 76
59 private static void buildAndAddBpmnSequenceFlow(Process mainProcess, BpmSimpleModelNodeVO node, String targetId) { 77 private static void buildAndAddBpmnSequenceFlow(Process mainProcess, BpmSimpleModelNodeVO node, String targetId) {
60 // 节点为 null 退出 78 // 节点为 null 退出
61 - if (node == null || node.getId() == null) { 79 + if (node == null || node.getId() == null || END_EVENT.getType().equals(node.getType())) {
62 return; 80 return;
63 } 81 }
64 BpmSimpleModelNodeVO childNode = node.getChildNode(); 82 BpmSimpleModelNodeVO childNode = node.getChildNode();
@@ -169,6 +187,11 @@ public class SimpleModelUtils { @@ -169,6 +187,11 @@ public class SimpleModelUtils {
169 mainProcess.addFlowElement(inclusiveGateway); 187 mainProcess.addFlowElement(inclusiveGateway);
170 break; 188 break;
171 } 189 }
  190 + case END_EVENT: {
  191 + EndEvent endEvent = buildBpmnEndEvent(simpleModelNode);
  192 + mainProcess.addFlowElement(endEvent);
  193 + break;
  194 + }
172 default: { 195 default: {
173 // TODO 其它节点类型的实现 196 // TODO 其它节点类型的实现
174 } 197 }
@@ -242,32 +265,59 @@ public class SimpleModelUtils { @@ -242,32 +265,59 @@ public class SimpleModelUtils {
242 return inclusiveGateway; 265 return inclusiveGateway;
243 } 266 }
244 267
245 - private static void buildAndAddBpmnEndEvent(Process mainProcess) { 268 + private static EndEvent buildAndAddBpmnEndEvent(Process mainProcess) {
246 EndEvent endEvent = new EndEvent(); 269 EndEvent endEvent = new EndEvent();
247 endEvent.setId(BpmnModelConstants.END_EVENT_ID); 270 endEvent.setId(BpmnModelConstants.END_EVENT_ID);
248 endEvent.setName("结束"); 271 endEvent.setName("结束");
249 mainProcess.addFlowElement(endEvent); 272 mainProcess.addFlowElement(endEvent);
  273 + return endEvent;
250 } 274 }
251 275
252 private static UserTask buildBpmnUserTask(BpmSimpleModelNodeVO node) { 276 private static UserTask buildBpmnUserTask(BpmSimpleModelNodeVO node) {
253 UserTask userTask = new UserTask(); 277 UserTask userTask = new UserTask();
254 userTask.setId(node.getId()); 278 userTask.setId(node.getId());
255 userTask.setName(node.getName()); 279 userTask.setName(node.getName());
256 - // TODO 暂时测试,后面去掉  
257 - userTask.setFormKey("24");  
258 // 添加候选人元素 280 // 添加候选人元素
259 addCandidateElements(node, userTask); 281 addCandidateElements(node, userTask);
260 // 添加表单字段权限属性元素 282 // 添加表单字段权限属性元素
261 addFormFieldsPermission(node, userTask); 283 addFormFieldsPermission(node, userTask);
  284 + // 处理多实例
  285 + processMultiInstanceLoopCharacteristics(node, userTask);
262 return userTask; 286 return userTask;
263 } 287 }
264 288
  289 + private static void processMultiInstanceLoopCharacteristics(BpmSimpleModelNodeVO node, UserTask userTask) {
  290 + Integer approveMethod = MapUtil.getInt(node.getAttributes(), SimpleModelConstants.APPROVE_METHOD_ATTRIBUTE);
  291 + BpmApproveMethodEnum bpmApproveMethodEnum = BpmApproveMethodEnum.valueOf(approveMethod);
  292 + if (bpmApproveMethodEnum == null || bpmApproveMethodEnum == BpmApproveMethodEnum.SINGLE_PERSON_APPROVE) {
  293 + return;
  294 + }
  295 + MultiInstanceLoopCharacteristics multiInstanceCharacteristics = new MultiInstanceLoopCharacteristics();
  296 + // 设置 collectionVariable。本系统用不到。会在 仅仅为了校验。
  297 + multiInstanceCharacteristics.setInputDataItem("${coll_userList}");
  298 + if (bpmApproveMethodEnum == BpmApproveMethodEnum.ALL_APPROVE) {
  299 + multiInstanceCharacteristics.setCompletionCondition(ALL_APPROVE_COMPLETE_EXPRESSION);
  300 + multiInstanceCharacteristics.setSequential(false);
  301 + } else if (bpmApproveMethodEnum == BpmApproveMethodEnum.ANY_OF_APPROVE) {
  302 + multiInstanceCharacteristics.setCompletionCondition(ANY_OF_APPROVE_COMPLETE_EXPRESSION);
  303 + multiInstanceCharacteristics.setSequential(false);
  304 + userTask.setLoopCharacteristics(multiInstanceCharacteristics);
  305 + } else if (bpmApproveMethodEnum == BpmApproveMethodEnum.SEQUENTIAL_APPROVE) {
  306 + multiInstanceCharacteristics.setCompletionCondition(ALL_APPROVE_COMPLETE_EXPRESSION);
  307 + multiInstanceCharacteristics.setSequential(true);
  308 + multiInstanceCharacteristics.setLoopCardinality("1");
  309 + userTask.setLoopCharacteristics(multiInstanceCharacteristics);
  310 + }
  311 + userTask.setLoopCharacteristics(multiInstanceCharacteristics);
  312 + }
  313 +
265 /** 314 /**
266 * 给节点添加表单字段权限元素 315 * 给节点添加表单字段权限元素
267 */ 316 */
268 private static void addFormFieldsPermission(BpmSimpleModelNodeVO node, FlowElement flowElement) { 317 private static void addFormFieldsPermission(BpmSimpleModelNodeVO node, FlowElement flowElement) {
269 List<Map<String, String>> fieldsPermissions = MapUtil.get(node.getAttributes(), 318 List<Map<String, String>> fieldsPermissions = MapUtil.get(node.getAttributes(),
270 - FORM_FIELD_PERMISSION_ELEMENT, new TypeReference<>() {}); 319 + FORM_FIELD_PERMISSION_ELEMENT, new TypeReference<>() {
  320 + });
271 if (CollUtil.isNotEmpty(fieldsPermissions)) { 321 if (CollUtil.isNotEmpty(fieldsPermissions)) {
272 fieldsPermissions.forEach(item -> addExtensionElement(flowElement, FORM_FIELD_PERMISSION_ELEMENT, item)); 322 fieldsPermissions.forEach(item -> addExtensionElement(flowElement, FORM_FIELD_PERMISSION_ELEMENT, item));
273 } 323 }
@@ -307,4 +357,11 @@ public class SimpleModelUtils { @@ -307,4 +357,11 @@ public class SimpleModelUtils {
307 startEvent.setName(node.getName()); 357 startEvent.setName(node.getName());
308 return startEvent; 358 return startEvent;
309 } 359 }
  360 +
  361 + private static EndEvent buildBpmnEndEvent(BpmSimpleModelNodeVO node) {
  362 + EndEvent endEvent = new EndEvent();
  363 + endEvent.setId(node.getId());
  364 + endEvent.setName(node.getName());
  365 + return endEvent;
  366 + }
310 } 367 }