Commit 4958aaea8151137caa143fa10e8fb202604b00fb

Authored by jason
1 parent 1bd96eb1

仿钉钉流程设计- 调整排他网关和条件节点

yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmSimpleModeConditionType.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 + * 仿钉钉的流程器设计器条件节点的条件类型
  9 + *
  10 + * @author jason
  11 + */
  12 +@Getter
  13 +@AllArgsConstructor
  14 +public enum BpmSimpleModeConditionType {
  15 +
  16 + CUSTOM_EXPRESSION(1, "自定义条件表达式");
  17 +
  18 +
  19 + private final Integer type;
  20 + private final String name;
  21 +
  22 + public static BpmSimpleModeConditionType valueOf(Integer type) {
  23 + return ArrayUtil.firstMatch(nodeType -> nodeType.getType().equals(type), values());
  24 + }
  25 +}
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/enums/SimpleModelConstants.java
@@ -12,4 +12,19 @@ public interface SimpleModelConstants { @@ -12,4 +12,19 @@ public interface SimpleModelConstants {
12 * 审批方式属性 12 * 审批方式属性
13 */ 13 */
14 String APPROVE_METHOD_ATTRIBUTE = "approveMethod"; 14 String APPROVE_METHOD_ATTRIBUTE = "approveMethod";
  15 +
  16 + /**
  17 + * 网关节点默认序列流属性
  18 + */
  19 + String DEFAULT_FLOW_ATTRIBUTE = "defaultFlow";
  20 +
  21 + /**
  22 + * 条件节点的条件类型属性
  23 + */
  24 + String CONDITION_TYPE_ATTRIBUTE = "conditionType";
  25 +
  26 + /**
  27 + * 条件节点条件表达式属性
  28 + */
  29 + String CONDITION_EXPRESSION_ATTRIBUTE = "conditionExpression";
15 } 30 }
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/SimpleModelUtils.java
@@ -5,9 +5,11 @@ import cn.hutool.core.lang.Assert; @@ -5,9 +5,11 @@ import cn.hutool.core.lang.Assert;
5 import cn.hutool.core.lang.TypeReference; 5 import cn.hutool.core.lang.TypeReference;
6 import cn.hutool.core.map.MapUtil; 6 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.BooleanUtil;
8 import cn.hutool.core.util.StrUtil; 9 import cn.hutool.core.util.StrUtil;
9 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.simple.BpmSimpleModelNodeVO; 10 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.simple.BpmSimpleModelNodeVO;
10 import cn.iocoder.yudao.module.bpm.enums.definition.BpmApproveMethodEnum; 11 import cn.iocoder.yudao.module.bpm.enums.definition.BpmApproveMethodEnum;
  12 +import cn.iocoder.yudao.module.bpm.enums.definition.BpmSimpleModeConditionType;
11 import cn.iocoder.yudao.module.bpm.enums.definition.BpmSimpleModelNodeType; 13 import cn.iocoder.yudao.module.bpm.enums.definition.BpmSimpleModelNodeType;
12 import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants; 14 import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants;
13 import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.SimpleModelConstants; 15 import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.SimpleModelConstants;
@@ -20,6 +22,7 @@ import java.util.Map; @@ -20,6 +22,7 @@ import java.util.Map;
20 22
21 import static cn.iocoder.yudao.module.bpm.enums.definition.BpmSimpleModelNodeType.END_EVENT; 23 import static cn.iocoder.yudao.module.bpm.enums.definition.BpmSimpleModelNodeType.END_EVENT;
22 import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants.FORM_FIELD_PERMISSION_ELEMENT; 24 import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants.FORM_FIELD_PERMISSION_ELEMENT;
  25 +import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.SimpleModelConstants.*;
23 import static org.flowable.bpmn.constants.BpmnXMLConstants.FLOWABLE_EXTENSIONS_NAMESPACE; 26 import static org.flowable.bpmn.constants.BpmnXMLConstants.FLOWABLE_EXTENSIONS_NAMESPACE;
24 import static org.flowable.bpmn.constants.BpmnXMLConstants.FLOWABLE_EXTENSIONS_PREFIX; 27 import static org.flowable.bpmn.constants.BpmnXMLConstants.FLOWABLE_EXTENSIONS_PREFIX;
25 28
@@ -57,16 +60,15 @@ public class SimpleModelUtils { @@ -57,16 +60,15 @@ public class SimpleModelUtils {
57 mainProcess.setName(processName); 60 mainProcess.setName(processName);
58 mainProcess.setExecutable(Boolean.TRUE); 61 mainProcess.setExecutable(Boolean.TRUE);
59 bpmnModel.addProcess(mainProcess); 62 bpmnModel.addProcess(mainProcess);
60 - // 前端模型数据结构。 有 start event 节点. 没有 end event 节点。 63 + // 前端模型数据结构。
61 // 从 SimpleModel 构建 FlowNode 并添加到 Main Process 64 // 从 SimpleModel 构建 FlowNode 并添加到 Main Process
62 buildAndAddBpmnFlowNode(simpleModelNode, mainProcess); 65 buildAndAddBpmnFlowNode(simpleModelNode, mainProcess);
63 // 找到 end event 66 // 找到 end event
64 EndEvent endEvent = (EndEvent) CollUtil.findOne(mainProcess.getFlowElements(), item -> item instanceof EndEvent); 67 EndEvent endEvent = (EndEvent) CollUtil.findOne(mainProcess.getFlowElements(), item -> item instanceof EndEvent);
65 if (endEvent == null) { 68 if (endEvent == null) {
66 - // 暂时为了兼容 单独构建 end event 节点 69 + // TODO 暂时为了兼容 单独构建 end event 节点. 后面去掉
67 endEvent = buildAndAddBpmnEndEvent(mainProcess); 70 endEvent = buildAndAddBpmnEndEvent(mainProcess);
68 } 71 }
69 -  
70 // 构建并添加节点之间的连线 Sequence Flow 72 // 构建并添加节点之间的连线 Sequence Flow
71 buildAndAddBpmnSequenceFlow(mainProcess, simpleModelNode, endEvent.getId()); 73 buildAndAddBpmnSequenceFlow(mainProcess, simpleModelNode, endEvent.getId());
72 // 自动布局 74 // 自动布局
@@ -75,14 +77,14 @@ public class SimpleModelUtils { @@ -75,14 +77,14 @@ public class SimpleModelUtils {
75 } 77 }
76 78
77 private static void buildAndAddBpmnSequenceFlow(Process mainProcess, BpmSimpleModelNodeVO node, String targetId) { 79 private static void buildAndAddBpmnSequenceFlow(Process mainProcess, BpmSimpleModelNodeVO node, String targetId) {
78 - // 节点为 null 退出 80 + // 节点为 null 或者 为END_EVENT 退出
79 if (node == null || node.getId() == null || END_EVENT.getType().equals(node.getType())) { 81 if (node == null || node.getId() == null || END_EVENT.getType().equals(node.getType())) {
80 return; 82 return;
81 } 83 }
82 BpmSimpleModelNodeVO childNode = node.getChildNode(); 84 BpmSimpleModelNodeVO childNode = node.getChildNode();
83 - // 如果不是网关节点、且后续节点为 null. 添加与结束节点的连线 85 + // 如果是网关分支节点. 后续节点可能为 null。但不是 END_EVENT 节点
84 if (!BpmSimpleModelNodeType.isBranchNode(node.getType()) && (childNode == null || childNode.getId() == null)) { 86 if (!BpmSimpleModelNodeType.isBranchNode(node.getType()) && (childNode == null || childNode.getId() == null)) {
85 - SequenceFlow sequenceFlow = buildBpmnSequenceFlow(node.getId(), targetId, null, null); 87 + SequenceFlow sequenceFlow = buildBpmnSequenceFlow(node.getId(), targetId, null, null, null);
86 mainProcess.addFlowElement(sequenceFlow); 88 mainProcess.addFlowElement(sequenceFlow);
87 return; 89 return;
88 } 90 }
@@ -94,7 +96,7 @@ public class SimpleModelUtils { @@ -94,7 +96,7 @@ public class SimpleModelUtils {
94 case COPY_TASK: 96 case COPY_TASK:
95 case PARALLEL_GATEWAY_JOIN: 97 case PARALLEL_GATEWAY_JOIN:
96 case INCLUSIVE_GATEWAY_JOIN: { 98 case INCLUSIVE_GATEWAY_JOIN: {
97 - SequenceFlow sequenceFlow = buildBpmnSequenceFlow(node.getId(), childNode.getId(), null, null); 99 + SequenceFlow sequenceFlow = buildBpmnSequenceFlow(node.getId(), childNode.getId(), null, null, null);
98 mainProcess.addFlowElement(sequenceFlow); 100 mainProcess.addFlowElement(sequenceFlow);
99 // 递归调用后续节点 101 // 递归调用后续节点
100 buildAndAddBpmnSequenceFlow(mainProcess, childNode, targetId); 102 buildAndAddBpmnSequenceFlow(mainProcess, childNode, targetId);
@@ -103,21 +105,21 @@ public class SimpleModelUtils { @@ -103,21 +105,21 @@ public class SimpleModelUtils {
103 case PARALLEL_GATEWAY_FORK: 105 case PARALLEL_GATEWAY_FORK:
104 case EXCLUSIVE_GATEWAY: 106 case EXCLUSIVE_GATEWAY:
105 case INCLUSIVE_GATEWAY_FORK: { 107 case INCLUSIVE_GATEWAY_FORK: {
106 - String sequenceFlowTargetId = (childNode == null || childNode.getId() == null) ? BpmnModelConstants.END_EVENT_ID : childNode.getId(); 108 + String sequenceFlowTargetId = (childNode == null || childNode.getId() == null) ? targetId : childNode.getId();
107 List<BpmSimpleModelNodeVO> conditionNodes = node.getConditionNodes(); 109 List<BpmSimpleModelNodeVO> conditionNodes = node.getConditionNodes();
108 Assert.notEmpty(conditionNodes, "网关节点的条件节点不能为空"); 110 Assert.notEmpty(conditionNodes, "网关节点的条件节点不能为空");
109 - for (int i = 0; i < conditionNodes.size(); i++) {  
110 - BpmSimpleModelNodeVO item = conditionNodes.get(i); 111 + for (BpmSimpleModelNodeVO item : conditionNodes) {
  112 + String conditionExpression = buildConditionExpression(item);
111 BpmSimpleModelNodeVO nextNodeOnCondition = item.getChildNode(); 113 BpmSimpleModelNodeVO nextNodeOnCondition = item.getChildNode();
112 if (nextNodeOnCondition != null && nextNodeOnCondition.getId() != null) { 114 if (nextNodeOnCondition != null && nextNodeOnCondition.getId() != null) {
113 SequenceFlow sequenceFlow = buildBpmnSequenceFlow(node.getId(), nextNodeOnCondition.getId(), 115 SequenceFlow sequenceFlow = buildBpmnSequenceFlow(node.getId(), nextNodeOnCondition.getId(),
114 - String.format("%s_SequenceFlow_%d", node.getId(), i + 1), null); 116 + item.getId(), item.getName(), conditionExpression);
115 mainProcess.addFlowElement(sequenceFlow); 117 mainProcess.addFlowElement(sequenceFlow);
116 // 递归调用后续节点 118 // 递归调用后续节点
117 buildAndAddBpmnSequenceFlow(mainProcess, nextNodeOnCondition, sequenceFlowTargetId); 119 buildAndAddBpmnSequenceFlow(mainProcess, nextNodeOnCondition, sequenceFlowTargetId);
118 } else { 120 } else {
119 SequenceFlow sequenceFlow = buildBpmnSequenceFlow(node.getId(), sequenceFlowTargetId, 121 SequenceFlow sequenceFlow = buildBpmnSequenceFlow(node.getId(), sequenceFlowTargetId,
120 - String.format("%s_SequenceFlow_%d", node.getId(), i + 1), null); 122 + item.getId(), item.getName(), conditionExpression);
121 mainProcess.addFlowElement(sequenceFlow); 123 mainProcess.addFlowElement(sequenceFlow);
122 } 124 }
123 } 125 }
@@ -132,7 +134,24 @@ public class SimpleModelUtils { @@ -132,7 +134,24 @@ public class SimpleModelUtils {
132 134
133 } 135 }
134 136
135 - private static SequenceFlow buildBpmnSequenceFlow(String sourceId, String targetId, String seqFlowId, String conditionExpression) { 137 + /**
  138 + * 构造条件表达式
  139 + *
  140 + * @param conditionNode 条件节点
  141 + */
  142 + private static String buildConditionExpression(BpmSimpleModelNodeVO conditionNode) {
  143 + Integer conditionType = MapUtil.getInt(conditionNode.getAttributes(), CONDITION_TYPE_ATTRIBUTE);
  144 + BpmSimpleModeConditionType conditionTypeEnum = BpmSimpleModeConditionType.valueOf(conditionType);
  145 + String conditionExpression = null;
  146 + if (conditionTypeEnum == BpmSimpleModeConditionType.CUSTOM_EXPRESSION) {
  147 + conditionExpression = MapUtil.getStr(conditionNode.getAttributes(), CONDITION_EXPRESSION_ATTRIBUTE);
  148 + }
  149 + // TODO 待增加其它类型
  150 + return conditionExpression;
  151 +
  152 + }
  153 +
  154 + private static SequenceFlow buildBpmnSequenceFlow(String sourceId, String targetId, String seqFlowId, String seqName, String conditionExpression) {
136 SequenceFlow sequenceFlow = new SequenceFlow(sourceId, targetId); 155 SequenceFlow sequenceFlow = new SequenceFlow(sourceId, targetId);
137 if (StrUtil.isNotEmpty(conditionExpression)) { 156 if (StrUtil.isNotEmpty(conditionExpression)) {
138 sequenceFlow.setConditionExpression(conditionExpression); 157 sequenceFlow.setConditionExpression(conditionExpression);
@@ -140,6 +159,9 @@ public class SimpleModelUtils { @@ -140,6 +159,9 @@ public class SimpleModelUtils {
140 if (StrUtil.isNotEmpty(seqFlowId)) { 159 if (StrUtil.isNotEmpty(seqFlowId)) {
141 sequenceFlow.setId(seqFlowId); 160 sequenceFlow.setId(seqFlowId);
142 } 161 }
  162 + if (StrUtil.isNotEmpty(seqName)) {
  163 + sequenceFlow.setName(seqName);
  164 + }
143 return sequenceFlow; 165 return sequenceFlow;
144 } 166 }
145 167
@@ -249,8 +271,12 @@ public class SimpleModelUtils { @@ -249,8 +271,12 @@ public class SimpleModelUtils {
249 Assert.notEmpty(node.getConditionNodes(), "网关节点的条件节点不能为空"); 271 Assert.notEmpty(node.getConditionNodes(), "网关节点的条件节点不能为空");
250 ExclusiveGateway exclusiveGateway = new ExclusiveGateway(); 272 ExclusiveGateway exclusiveGateway = new ExclusiveGateway();
251 exclusiveGateway.setId(node.getId()); 273 exclusiveGateway.setId(node.getId());
252 - // 网关的最后一个条件为 网关的 default sequence flow  
253 - exclusiveGateway.setDefaultFlow(String.format("%s_SequenceFlow_%d", node.getId(), node.getConditionNodes().size())); 274 + // 寻找默认的序列流
  275 + BpmSimpleModelNodeVO defaultSeqFlow = CollUtil.findOne(node.getConditionNodes(),
  276 + item -> BooleanUtil.isTrue(MapUtil.getBool(item.getAttributes(), DEFAULT_FLOW_ATTRIBUTE)));
  277 + if (defaultSeqFlow != null) {
  278 + exclusiveGateway.setDefaultFlow(defaultSeqFlow.getId());
  279 + }
254 return exclusiveGateway; 280 return exclusiveGateway;
255 } 281 }
256 282