mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2024-11-23 07:41:53 +08:00
仿钉钉流程设计- code review 构建节点连线修改
This commit is contained in:
parent
d9ca52a478
commit
65a09182e7
@ -25,7 +25,7 @@ import java.util.Map;
|
|||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.module.bpm.enums.definition.BpmBoundaryEventType.USER_TASK_TIMEOUT;
|
import static cn.iocoder.yudao.module.bpm.enums.definition.BpmBoundaryEventType.USER_TASK_TIMEOUT;
|
||||||
import static cn.iocoder.yudao.module.bpm.enums.definition.BpmSimpleModelNodeType.END_NODE;
|
import static cn.iocoder.yudao.module.bpm.enums.definition.BpmSimpleModelNodeType.*;
|
||||||
import static cn.iocoder.yudao.module.bpm.enums.definition.BpmUserTaskTimeoutActionEnum.AUTO_REMINDER;
|
import static cn.iocoder.yudao.module.bpm.enums.definition.BpmUserTaskTimeoutActionEnum.AUTO_REMINDER;
|
||||||
import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants.*;
|
import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants.*;
|
||||||
import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.SimpleModelConstants.*;
|
import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.SimpleModelConstants.*;
|
||||||
@ -84,78 +84,128 @@ public class SimpleModelUtils {
|
|||||||
EndEvent endEvent = (EndEvent) CollUtil.findOne(process.getFlowElements(), item -> item instanceof EndEvent);
|
EndEvent endEvent = (EndEvent) CollUtil.findOne(process.getFlowElements(), item -> item instanceof EndEvent);
|
||||||
|
|
||||||
// 构建并添加节点之间的连线 Sequence Flow
|
// 构建并添加节点之间的连线 Sequence Flow
|
||||||
buildAndAddBpmnSequenceFlow(process, simpleModelNode, endEvent.getId());
|
traverseNodeToBuildSequenceFlow(process, simpleModelNode, endEvent.getId());
|
||||||
// 自动布局
|
// 自动布局
|
||||||
new BpmnAutoLayout(bpmnModel).execute();
|
new BpmnAutoLayout(bpmnModel).execute();
|
||||||
return bpmnModel;
|
return bpmnModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void buildAndAddBpmnSequenceFlow(Process mainProcess, BpmSimpleModelNodeVO node, String targetId) {
|
private static void traverseNodeToBuildSequenceFlow(Process process, BpmSimpleModelNodeVO node, String targetNodeId) {
|
||||||
// 节点为 null 或者 为END_EVENT 退出
|
// 1.无效节点返回
|
||||||
// TODO @jason:isValidNode;然后把 END_NODE 是不是拿到 switch (nodeType) { 那 return 哈?这样出口更统一一点?
|
if (!isValidNode(node)) {
|
||||||
if (node == null || node.getId() == null || END_NODE.getType().equals(node.getType())) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
BpmSimpleModelNodeVO childNode = node.getChildNode();
|
|
||||||
// 如果是网关分支节点. 后续节点可能为 null。但不是 END_EVENT 节点
|
// 如果是网关分支节点. 后续节点可能为 null。但不是 END_EVENT 节点
|
||||||
// TODO @芋艿:这个要不要挪到 START_NODE - INCLUSIVE_BRANCH_JOIN_NODE 待定;感觉 switch 那最终是分三个情况;branch、子节点、结束了;(每种情况的注释,需要写的更完整)
|
// TODO-DONE @芋艿:这个要不要挪到 START_NODE - INCLUSIVE_BRANCH_JOIN_NODE 待定;感觉 switch 那最终是分三个情况;branch、子节点、结束了;(每种情况的注释,需要写的更完整)
|
||||||
if (!BpmSimpleModelNodeType.isBranchNode(node.getType()) && (childNode == null || childNode.getId() == null)) {
|
// if (!BpmSimpleModelNodeType.isBranchNode(node.getType()) && (childNode == null || childNode.getId() == null)) {
|
||||||
SequenceFlow sequenceFlow = buildBpmnSequenceFlow(node.getId(), targetId, null, null, null);
|
// SequenceFlow sequenceFlow = buildBpmnSequenceFlow(node.getId(), targetNodeId, null, null, null);
|
||||||
mainProcess.addFlowElement(sequenceFlow);
|
// process.addFlowElement(sequenceFlow);
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
BpmSimpleModelNodeType nodeType = BpmSimpleModelNodeType.valueOf(node.getType());
|
BpmSimpleModelNodeType nodeType = BpmSimpleModelNodeType.valueOf(node.getType());
|
||||||
Assert.notNull(nodeType, "模型节点类型不支持");
|
Assert.notNull(nodeType, "模型节点类型不支持");
|
||||||
// TODO @jason:下面的 PARALLEL_BRANCH_FORK_NODE、CONDITION_BRANCH_NODE、INCLUSIVE_BRANCH_FORK_NODE 是不是就是 isBranchNode?如果是的话,貌似不用 swtich,而是 if else 分类处理呢。
|
BpmSimpleModelNodeVO childNode = node.getChildNode();
|
||||||
switch (nodeType) {
|
// 2.1 普通节点
|
||||||
case START_NODE:
|
if (!BpmSimpleModelNodeType.isBranchNode(node.getType())) {
|
||||||
case APPROVE_NODE:
|
// 2.1.1 结束节点退出递归
|
||||||
case COPY_NODE:
|
if (nodeType == END_NODE) {
|
||||||
case PARALLEL_BRANCH_JOIN_NODE:
|
return;
|
||||||
case INCLUSIVE_BRANCH_JOIN_NODE: {
|
|
||||||
SequenceFlow sequenceFlow = buildBpmnSequenceFlow(node.getId(), childNode.getId(), null, null, null);
|
|
||||||
mainProcess.addFlowElement(sequenceFlow);
|
|
||||||
// 递归调用后续节点
|
|
||||||
buildAndAddBpmnSequenceFlow(mainProcess, childNode, targetId);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case PARALLEL_BRANCH_FORK_NODE:
|
if (!isValidNode(childNode)) {
|
||||||
case CONDITION_BRANCH_NODE:
|
// 2.1.2 普通节点且无孩子节点。分两种情况
|
||||||
case INCLUSIVE_BRANCH_FORK_NODE: {
|
// a.结束节点 b. 条件分支的最后一个节点.与分支节点的孩子节点或聚合节点建立连线。
|
||||||
// TODO @jason:这里 sequenceFlowTargetId 不建议做这样的 default。万一可能有 bug 哈;直接弄到对应的 136- 146 会更安全一点。
|
SequenceFlow sequenceFlow = buildBpmnSequenceFlow(node.getId(), targetNodeId, null, null, null);
|
||||||
String sequenceFlowTargetId = (childNode == null || childNode.getId() == null) ? targetId : childNode.getId();
|
process.addFlowElement(sequenceFlow);
|
||||||
|
} else {
|
||||||
|
// 2.1.3 普通节点且有孩子节点。建立连线
|
||||||
|
SequenceFlow sequenceFlow = buildBpmnSequenceFlow(node.getId(), childNode.getId(), null, null, null);
|
||||||
|
process.addFlowElement(sequenceFlow);
|
||||||
|
// 递归调用后续节点
|
||||||
|
traverseNodeToBuildSequenceFlow(process, childNode, targetNodeId);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 2.2 分支节点
|
||||||
List<BpmSimpleModelNodeVO> conditionNodes = node.getConditionNodes();
|
List<BpmSimpleModelNodeVO> conditionNodes = node.getConditionNodes();
|
||||||
Assert.notEmpty(conditionNodes, "网关节点的条件节点不能为空");
|
Assert.notEmpty(conditionNodes, "分支节点的条件节点不能为空");
|
||||||
|
// 4.1 分支节点,遍历分支节点. 如下情况:
|
||||||
|
// 分支1、A->B->C->D->E 和 分支2、A->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 搞的条件
|
||||||
|
// 构建表达式
|
||||||
String conditionExpression = buildConditionExpression(item);
|
String conditionExpression = buildConditionExpression(item);
|
||||||
|
|
||||||
BpmSimpleModelNodeVO nextNodeOnCondition = item.getChildNode();
|
BpmSimpleModelNodeVO nextNodeOnCondition = item.getChildNode();
|
||||||
// TODO @jason:isValidNode
|
// 4.2 分支有后续节点, 分支1: A->B->C->D
|
||||||
if (nextNodeOnCondition != null && nextNodeOnCondition.getId() != null) {
|
if (isValidNode(nextNodeOnCondition)) {
|
||||||
// TODO @jason:会存在 item.name 未空的情况么?这个时候,要不要兜底处理拼接
|
// 4.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);
|
||||||
mainProcess.addFlowElement(sequenceFlow);
|
process.addFlowElement(sequenceFlow);
|
||||||
// 递归调用后续节点
|
// 4.2.2 递归调用后续节点连线。 建立 B->C->D 的连线
|
||||||
// TODO @jason:最好也有个例子,嘿嘿;S4
|
traverseNodeToBuildSequenceFlow(process, nextNodeOnCondition, branchEndNodeId);
|
||||||
buildAndAddBpmnSequenceFlow(mainProcess, nextNodeOnCondition, sequenceFlowTargetId);
|
|
||||||
} else {
|
} else {
|
||||||
SequenceFlow sequenceFlow = buildBpmnSequenceFlow(node.getId(), sequenceFlowTargetId,
|
// 4.3 分支无后续节点 建立 A->D
|
||||||
|
SequenceFlow sequenceFlow = buildBpmnSequenceFlow(node.getId(), branchEndNodeId,
|
||||||
item.getId(), item.getName(), conditionExpression);
|
item.getId(), item.getName(), conditionExpression);
|
||||||
mainProcess.addFlowElement(sequenceFlow);
|
process.addFlowElement(sequenceFlow);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 递归调用后续节点 TODO @jason:最好有个例子哈
|
// 递归调用后续节点 继续递归建立 D->E 的连线
|
||||||
buildAndAddBpmnSequenceFlow(mainProcess, childNode, targetId);
|
traverseNodeToBuildSequenceFlow(process, childNode, targetNodeId);
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
// TODO 其它节点类型的实现
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO @jason:下面的 PARALLEL_BRANCH_FORK_NODE、CONDITION_BRANCH_NODE、INCLUSIVE_BRANCH_FORK_NODE 是不是就是 isBranchNode?如果是的话,貌似不用 swtich,而是 if else 分类处理呢。
|
||||||
|
// switch (nodeType) {
|
||||||
|
// case START_NODE:
|
||||||
|
// case APPROVE_NODE:
|
||||||
|
// case COPY_NODE:
|
||||||
|
// case PARALLEL_BRANCH_JOIN_NODE:
|
||||||
|
// case INCLUSIVE_BRANCH_JOIN_NODE: {
|
||||||
|
// SequenceFlow sequenceFlow = buildBpmnSequenceFlow(node.getId(), childNode.getId(), null, null, null);
|
||||||
|
// process.addFlowElement(sequenceFlow);
|
||||||
|
// // 递归调用后续节点
|
||||||
|
// buildAndAddBpmnSequenceFlow(process, childNode, targetNodeId);
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// case PARALLEL_BRANCH_FORK_NODE:
|
||||||
|
// case CONDITION_BRANCH_NODE:
|
||||||
|
// case INCLUSIVE_BRANCH_FORK_NODE: {
|
||||||
|
// // TODO @jason:这里 sequenceFlowTargetId 不建议做这样的 default。万一可能有 bug 哈;直接弄到对应的 136- 146 会更安全一点。
|
||||||
|
// String sequenceFlowTargetId = (childNode == null || childNode.getId() == null) ? targetNodeId : childNode.getId();
|
||||||
|
// List<BpmSimpleModelNodeVO> conditionNodes = node.getConditionNodes();
|
||||||
|
// Assert.notEmpty(conditionNodes, "网关节点的条件节点不能为空");
|
||||||
|
// for (BpmSimpleModelNodeVO item : conditionNodes) {
|
||||||
|
// // 构建表达式
|
||||||
|
// // TODO @jason:条件分支的情况下,需要分 item 搞的条件,和 conditionNodes 搞的条件
|
||||||
|
// String conditionExpression = buildConditionExpression(item);
|
||||||
|
//
|
||||||
|
// BpmSimpleModelNodeVO nextNodeOnCondition = item.getChildNode();
|
||||||
|
// // TODO @jason:isValidNode
|
||||||
|
// if (nextNodeOnCondition != null && nextNodeOnCondition.getId() != null) {
|
||||||
|
// // TODO @jason:会存在 item.name 未空的情况么?这个时候,要不要兜底处理拼接
|
||||||
|
// SequenceFlow sequenceFlow = buildBpmnSequenceFlow(node.getId(), nextNodeOnCondition.getId(),
|
||||||
|
// item.getId(), item.getName(), conditionExpression);
|
||||||
|
// process.addFlowElement(sequenceFlow);
|
||||||
|
// // 递归调用后续节点
|
||||||
|
// // TODO @jason:最好也有个例子,嘿嘿;S4
|
||||||
|
// buildAndAddBpmnSequenceFlow(process, nextNodeOnCondition, sequenceFlowTargetId);
|
||||||
|
// } else {
|
||||||
|
// SequenceFlow sequenceFlow = buildBpmnSequenceFlow(node.getId(), sequenceFlowTargetId,
|
||||||
|
// item.getId(), item.getName(), conditionExpression);
|
||||||
|
// process.addFlowElement(sequenceFlow);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// // 递归调用后续节点 TODO @jason:最好有个例子哈
|
||||||
|
// buildAndAddBpmnSequenceFlow(process, childNode, targetNodeId);
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// default: {
|
||||||
|
// // TODO 其它节点类型的实现
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -283,6 +333,7 @@ public class SimpleModelUtils {
|
|||||||
list.add(parallelGateway);
|
list.add(parallelGateway);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case INCLUSIVE_BRANCH_FORK_NODE: {
|
case INCLUSIVE_BRANCH_FORK_NODE: {
|
||||||
InclusiveGateway inclusiveGateway = convertInclusiveBranchNode(node, Boolean.TRUE);
|
InclusiveGateway inclusiveGateway = convertInclusiveBranchNode(node, Boolean.TRUE);
|
||||||
list.add(inclusiveGateway);
|
list.add(inclusiveGateway);
|
||||||
|
Loading…
Reference in New Issue
Block a user