仿钉钉流程设计- code review 修改。新增并行分支节点

This commit is contained in:
jason 2024-06-02 18:11:10 +08:00
parent 8a3b6c3eb9
commit d9a2849cce
2 changed files with 51 additions and 25 deletions

View File

@ -25,12 +25,14 @@ public enum BpmSimpleModelNodeType implements IntArrayValuable {
APPROVE_NODE(1, "审批人节点"), // TODO @jaosn是不是这里从 10 开始好点相当于说0-9 给开始和结束10-19 给各种节点20-29 给各种条件 TODO 后面改改 APPROVE_NODE(1, "审批人节点"), // TODO @jaosn是不是这里从 10 开始好点相当于说0-9 给开始和结束10-19 给各种节点20-29 给各种条件 TODO 后面改改
COPY_NODE(2, "抄送人节点"), COPY_NODE(2, "抄送人节点"),
CONDITION_NODE(3, "条件节点"), // 用于构建流转条件的表达式
CONDITION_BRANCH_NODE(4, "条件分支节点"), // TODO @jason是不是改成叫 条件分支 CONDITION_BRANCH_NODE(4, "条件分支节点"), // TODO @jason是不是改成叫 条件分支
PARALLEL_BRANCH_FORK_NODE(5, "并行分支分叉节点"), // TODO @jason是不是一个 并行分支 就可以啦 后面是否去掉并行网关只用包容网关 PARALLEL_BRANCH_NODE(5, "并行分支节点"), // TODO @jason是不是一个 并行分支 就可以啦 后面是否去掉并行网关只用包容网关
PARALLEL_BRANCH_JOIN_NODE(6, "并行分支聚合节点"), // PARALLEL_BRANCH_JOIN_NODE(6, "并行分支聚合节点"),
INCLUSIVE_BRANCH_FORK_NODE(7, "包容网关分叉节点"), INCLUSIVE_BRANCH_FORK_NODE(7, "包容网关分叉节点"),
INCLUSIVE_BRANCH_JOIN_NODE(8, "包容网关聚合节点"), INCLUSIVE_BRANCH_JOIN_NODE(8, "包容网关聚合节点"),
// TODO @jason建议整合 join最终只有 条件分支并行分支包容分支三种~ // TODO @jason建议整合 join最终只有 条件分支并行分支包容分支三种~
// TODO @芋艿 感觉还是分开好理解一点,也好处理一点前端结构中把聚合节点显示并传过来
; ;
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(BpmSimpleModelNodeType::getType).toArray(); public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(BpmSimpleModelNodeType::getType).toArray();
@ -45,7 +47,7 @@ public enum BpmSimpleModelNodeType implements IntArrayValuable {
*/ */
public static boolean isBranchNode(Integer type) { public static boolean isBranchNode(Integer type) {
return Objects.equals(CONDITION_BRANCH_NODE.getType(), type) return Objects.equals(CONDITION_BRANCH_NODE.getType(), type)
|| Objects.equals(PARALLEL_BRANCH_FORK_NODE.getType(), type) || Objects.equals(PARALLEL_BRANCH_NODE.getType(), type)
|| Objects.equals(INCLUSIVE_BRANCH_FORK_NODE.getType(), type) ; || Objects.equals(INCLUSIVE_BRANCH_FORK_NODE.getType(), type) ;
} }

View File

@ -38,6 +38,11 @@ import static org.flowable.bpmn.constants.BpmnXMLConstants.*;
*/ */
public class SimpleModelUtils { public class SimpleModelUtils {
/**
* 聚合网关节点 Id 后缀
*/
public static final String JOIN_GATE_WAY_NODE_ID_SUFFIX = "_join";
public static final String BPMN_SIMPLE_COPY_EXECUTION_SCRIPT = "#{bpmSimpleNodeService.copy(execution)}"; public static final String BPMN_SIMPLE_COPY_EXECUTION_SCRIPT = "#{bpmSimpleNodeService.copy(execution)}";
/** /**
@ -105,20 +110,20 @@ public class SimpleModelUtils {
// } // }
BpmSimpleModelNodeType nodeType = BpmSimpleModelNodeType.valueOf(node.getType()); BpmSimpleModelNodeType nodeType = BpmSimpleModelNodeType.valueOf(node.getType());
Assert.notNull(nodeType, "模型节点类型不支持"); Assert.notNull(nodeType, "模型节点类型不支持");
BpmSimpleModelNodeVO childNode = node.getChildNode();
// 2.1 普通节点
if (!BpmSimpleModelNodeType.isBranchNode(node.getType())) {
// 2.1.1 结束节点退出递归
if (nodeType == END_NODE) { if (nodeType == END_NODE) {
return; return;
} }
BpmSimpleModelNodeVO childNode = node.getChildNode();
// 2.1 普通节点
if (!BpmSimpleModelNodeType.isBranchNode(node.getType())) {
if (!isValidNode(childNode)) { if (!isValidNode(childNode)) {
// 2.1.2 普通节点且无孩子节点分两种情况 // 2.1.1 普通节点且无孩子节点分两种情况
// a.结束节点 b. 条件分支的最后一个节点.与分支节点的孩子节点或聚合节点建立连线 // a.结束节点 b. 条件分支的最后一个节点.与分支节点的孩子节点或聚合节点建立连线
SequenceFlow sequenceFlow = buildBpmnSequenceFlow(node.getId(), targetNodeId, null, null, null); SequenceFlow sequenceFlow = buildBpmnSequenceFlow(node.getId(), targetNodeId, null, null, null);
process.addFlowElement(sequenceFlow); process.addFlowElement(sequenceFlow);
} else { } else {
// 2.1.3 普通节点且有孩子节点建立连线 // 2.1.2 普通节点且有孩子节点建立连线
SequenceFlow sequenceFlow = buildBpmnSequenceFlow(node.getId(), childNode.getId(), null, null, null); SequenceFlow sequenceFlow = buildBpmnSequenceFlow(node.getId(), childNode.getId(), null, null, null);
process.addFlowElement(sequenceFlow); process.addFlowElement(sequenceFlow);
// 递归调用后续节点 // 递归调用后续节点
@ -128,31 +133,48 @@ public class SimpleModelUtils {
// 2.2 分支节点 // 2.2 分支节点
List<BpmSimpleModelNodeVO> conditionNodes = node.getConditionNodes(); List<BpmSimpleModelNodeVO> conditionNodes = node.getConditionNodes();
Assert.notEmpty(conditionNodes, "分支节点的条件节点不能为空"); Assert.notEmpty(conditionNodes, "分支节点的条件节点不能为空");
// 4.1 分支节点遍历分支节点. 如下情况: // 分支终点节点 Id
String branchEndNodeId = null;
if (nodeType == CONDITION_BRANCH_NODE) { // 条件分支
// 分两种情况 1. 分支节点有孩子节点为孩子节点 Id 2. 分支节点孩子为无效节点时 (分支嵌套且为分支最后一个节点) 为分支终点节点Id
branchEndNodeId = isValidNode(childNode) ? childNode.getId() : targetNodeId;
} else if (nodeType == PARALLEL_BRANCH_NODE) { // 并行分支
// 分支节点分支终点节点 Id 为程序创建的网关集合节点目前不会从前端传入
branchEndNodeId = node.getId() + JOIN_GATE_WAY_NODE_ID_SUFFIX;
}
// TODO 包容网关待实现
Assert.notEmpty(branchEndNodeId, "分支终点节点 Id 不能为空");
// 3.1 遍历分支节点. 如下情况:
// 分支1A->B->C->D->E 分支2A->D->E A为分支节点, D为A孩子节点 // 分支1A->B->C->D->E 分支2A->D->E A为分支节点, D为A孩子节点
// 分支终点节点 1. 分支节点有孩子节点时为孩子节点 2. 当分支节点孩子为无效节点时分支嵌套时并且为分支最后一个节点
String branchEndNodeId = isValidNode(childNode) ? childNode.getId() : targetNodeId ;
for (BpmSimpleModelNodeVO item : conditionNodes) { for (BpmSimpleModelNodeVO item : conditionNodes) {
// TODO @jason条件分支的情况下需要分 item 搞的条件 conditionNodes 搞的条件 // TODO @jason条件分支的情况下需要分 item 搞的条件 conditionNodes 搞的条件
// 构建表达式 // @芋艿 这个是啥意思 这里的 item 的节点类型为 BpmSimpleModelNodeType.CONDITION_NODE 类型没有对应的 bpmn 的节点 仅仅用于构建条件表达式
Assert.isTrue(Objects.equals(item.getType(), CONDITION_NODE.getType()), "条件节点类型不符合");
// 构建表达式,可以为空. 并行分支为空
String conditionExpression = buildConditionExpression(item); String conditionExpression = buildConditionExpression(item);
BpmSimpleModelNodeVO nextNodeOnCondition = item.getChildNode(); BpmSimpleModelNodeVO nextNodeOnCondition = item.getChildNode();
// 4.2 分支有后续节点, 分支1: A->B->C->D // 3.2 分支有后续节点, 分支1: A->B->C->D
if (isValidNode(nextNodeOnCondition)) { if (isValidNode(nextNodeOnCondition)) {
// 4.2.1 建立 A->B // 3.2.1 建立 A->B
SequenceFlow sequenceFlow = buildBpmnSequenceFlow(node.getId(), nextNodeOnCondition.getId(), SequenceFlow sequenceFlow = buildBpmnSequenceFlow(node.getId(), nextNodeOnCondition.getId(),
item.getId(), item.getName(), conditionExpression); item.getId(), item.getName(), conditionExpression);
process.addFlowElement(sequenceFlow); process.addFlowElement(sequenceFlow);
// 4.2.2 递归调用后续节点连线 建立 B->C->D 的连线 // 3.2.2 递归调用后续节点连线 建立 B->C->D 的连线
traverseNodeToBuildSequenceFlow(process, nextNodeOnCondition, branchEndNodeId); traverseNodeToBuildSequenceFlow(process, nextNodeOnCondition, branchEndNodeId);
} else { } else {
// 4.3 分支无后续节点 建立 A->D // 3.3 分支无后续节点 建立 A->D
SequenceFlow sequenceFlow = buildBpmnSequenceFlow(node.getId(), branchEndNodeId, SequenceFlow sequenceFlow = buildBpmnSequenceFlow(node.getId(), branchEndNodeId,
item.getId(), item.getName(), conditionExpression); item.getId(), item.getName(), conditionExpression);
process.addFlowElement(sequenceFlow); process.addFlowElement(sequenceFlow);
} }
} }
// 递归调用后续节点 继续递归建立 D->E 的连线 // 如果是并行分支由于是程序创建的聚合网关需要手工创建聚合网关和下一个节点的连线
if (nodeType == PARALLEL_BRANCH_NODE) {
String nextNodeId = isValidNode(childNode) ? childNode.getId() : targetNodeId;
SequenceFlow sequenceFlow = buildBpmnSequenceFlow(branchEndNodeId, nextNodeId, null, null, null);
process.addFlowElement(sequenceFlow);
}
// 4.递归调用后续节点 继续递归建立 D->E 的连线
traverseNodeToBuildSequenceFlow(process, childNode, targetNodeId); traverseNodeToBuildSequenceFlow(process, childNode, targetNodeId);
} }
@ -328,10 +350,9 @@ public class SimpleModelUtils {
list.add(exclusiveGateway); list.add(exclusiveGateway);
break; break;
} }
case PARALLEL_BRANCH_FORK_NODE: case PARALLEL_BRANCH_NODE: {
case PARALLEL_BRANCH_JOIN_NODE: { List<ParallelGateway> parallelGateways = convertParallelBranchNode(node);
ParallelGateway parallelGateway = convertParallelBranchNode(node); list.addAll(parallelGateways);
list.add(parallelGateway);
break; break;
} }
@ -392,14 +413,17 @@ public class SimpleModelUtils {
return boundaryEvent; return boundaryEvent;
} }
private static ParallelGateway convertParallelBranchNode(BpmSimpleModelNodeVO node) { private static List<ParallelGateway> convertParallelBranchNode(BpmSimpleModelNodeVO node) {
ParallelGateway parallelGateway = new ParallelGateway(); ParallelGateway parallelGateway = new ParallelGateway();
parallelGateway.setId(node.getId()); parallelGateway.setId(node.getId());
// TODO @jasonsetName // TODO @jasonsetName
// TODO @芋艿 + jason合并网关是不是要有条件啥的微信讨论 // TODO @芋艿 + jason合并网关是不是要有条件啥的微信讨论
// @芋艿 貌似并行网关没有条件的 // @芋艿 感觉聚合网关(合并网关)还是从前端传过来好理解一点
return parallelGateway; // 并行聚合网关
ParallelGateway joinParallelGateway = new ParallelGateway();
joinParallelGateway.setId(node.getId() + JOIN_GATE_WAY_NODE_ID_SUFFIX);
return CollUtil.newArrayList(parallelGateway, joinParallelGateway);
} }
private static ServiceTask convertCopyNode(BpmSimpleModelNodeVO node) { private static ServiceTask convertCopyNode(BpmSimpleModelNodeVO node) {