Commit d9ca52a478a4c56344b042914d3dfa548fdd29d3
1 parent
4bd399cd
【代码评审】BPM:review simple 字段、seq 连线
Showing
4 changed files
with
33 additions
and
7 deletions
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmSimpleModelNodeType.java
| ... | ... | @@ -30,6 +30,7 @@ public enum BpmSimpleModelNodeType implements IntArrayValuable { |
| 30 | 30 | PARALLEL_BRANCH_JOIN_NODE(6, "并行分支聚合节点"), |
| 31 | 31 | INCLUSIVE_BRANCH_FORK_NODE(7, "包容网关分叉节点"), |
| 32 | 32 | INCLUSIVE_BRANCH_JOIN_NODE(8, "包容网关聚合节点"), |
| 33 | + // TODO @jason:建议整合 join,最终只有 条件分支、并行分支、包容分支,三种~ | |
| 33 | 34 | ; |
| 34 | 35 | |
| 35 | 36 | public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(BpmSimpleModelNodeType::getType).toArray(); |
| ... | ... | @@ -43,7 +44,8 @@ public enum BpmSimpleModelNodeType implements IntArrayValuable { |
| 43 | 44 | * @param type 节点类型 |
| 44 | 45 | */ |
| 45 | 46 | public static boolean isBranchNode(Integer type) { |
| 46 | - return Objects.equals(CONDITION_BRANCH_NODE.getType(), type) || Objects.equals(PARALLEL_BRANCH_FORK_NODE.getType(), type) | |
| 47 | + return Objects.equals(CONDITION_BRANCH_NODE.getType(), type) | |
| 48 | + || Objects.equals(PARALLEL_BRANCH_FORK_NODE.getType(), type) | |
| 47 | 49 | || Objects.equals(INCLUSIVE_BRANCH_FORK_NODE.getType(), type) ; |
| 48 | 50 | } |
| 49 | 51 | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/simple/BpmSimpleModelNodeVO.java
| ... | ... | @@ -28,16 +28,25 @@ public class BpmSimpleModelNodeVO { |
| 28 | 28 | @Schema(description = "模型节点名称", example = "领导审批") |
| 29 | 29 | private String name; |
| 30 | 30 | |
| 31 | + // TODO @jason:要不改成 placeholder 和一般 Element-Plus 组件一致。占位符,用于展示。 | |
| 31 | 32 | @Schema(description = "节点展示内容", example = "指定成员: 芋道源码") |
| 32 | 33 | private String showText; |
| 33 | 34 | |
| 34 | - @Schema(description = "孩子节点") | |
| 35 | - private BpmSimpleModelNodeVO childNode; | |
| 35 | + @Schema(description = "子节点") | |
| 36 | + private BpmSimpleModelNodeVO childNode; // 补充说明:在该模型下,子节点有且仅有一个,不会有多个 | |
| 36 | 37 | |
| 37 | - @Schema(description = "网关节点的条件节点") | |
| 38 | - private List<BpmSimpleModelNodeVO> conditionNodes; | |
| 38 | + @Schema(description = "条件节点") | |
| 39 | + private List<BpmSimpleModelNodeVO> conditionNodes; // 补充说明:有且仅有条件、并行、包容等分支会使用 | |
| 39 | 40 | |
| 40 | 41 | @Schema(description = "节点的属性") |
| 41 | - private Map<String, Object> attributes; | |
| 42 | + private Map<String, Object> attributes; // TODO @jason:建议是字段分拆下;类似说: | |
| 43 | + // Map<String, Integer> formPermissions; 表单权限;仅发起、审批、抄送节点会使用 | |
| 44 | + // Integer approveMethod; 审批方式;仅审批节点会使用 | |
| 45 | + // TODO @芋艿:审批人的选择; | |
| 46 | + // TODO @芋艿:没有人的策略? | |
| 47 | + // TODO @芋艿:审批拒绝的策略? | |
| 48 | + // TODO @芋艿:配置的可操作列表? | |
| 49 | + // TODO @芋艿:超时配置;要支持指定时间点、指定时间间隔; | |
| 50 | + // TODO @芋艿:条件;建议可以固化的一些选项;然后有个表达式兜底;要支持 | |
| 42 | 51 | |
| 43 | 52 | } | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/simple/BpmSimpleModelUpdateReqVO.java
| ... | ... | @@ -6,6 +6,7 @@ import jakarta.validation.constraints.NotEmpty; |
| 6 | 6 | import jakarta.validation.constraints.NotNull; |
| 7 | 7 | import lombok.Data; |
| 8 | 8 | |
| 9 | +// TODO @jason:需要考虑,如果某个节点的配置不正确,需要有提示;具体怎么实现,可以讨论下; | |
| 9 | 10 | @Schema(description = "管理后台 - 仿钉钉流程设计模型的新增/修改 Request VO") |
| 10 | 11 | @Data |
| 11 | 12 | public class BpmSimpleModelUpdateReqVO { |
| ... | ... | @@ -14,6 +15,7 @@ public class BpmSimpleModelUpdateReqVO { |
| 14 | 15 | @NotEmpty(message = "流程模型编号不能为空") |
| 15 | 16 | private String modelId; // 对应 Flowable act_re_model 表 ID_ 字段 |
| 16 | 17 | |
| 18 | + // TODO @jason:simpleModel 要不? | |
| 17 | 19 | @Schema(description = "仿钉钉流程设计模型对象", requiredMode = Schema.RequiredMode.REQUIRED) |
| 18 | 20 | @NotNull(message = "仿钉钉流程设计模型对象不能为空") |
| 19 | 21 | @Valid | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/SimpleModelUtils.java
| ... | ... | @@ -92,11 +92,13 @@ public class SimpleModelUtils { |
| 92 | 92 | |
| 93 | 93 | private static void buildAndAddBpmnSequenceFlow(Process mainProcess, BpmSimpleModelNodeVO node, String targetId) { |
| 94 | 94 | // 节点为 null 或者 为END_EVENT 退出 |
| 95 | + // TODO @jason:isValidNode;然后把 END_NODE 是不是拿到 switch (nodeType) { 那 return 哈?这样出口更统一一点? | |
| 95 | 96 | if (node == null || node.getId() == null || END_NODE.getType().equals(node.getType())) { |
| 96 | 97 | return; |
| 97 | 98 | } |
| 98 | 99 | BpmSimpleModelNodeVO childNode = node.getChildNode(); |
| 99 | 100 | // 如果是网关分支节点. 后续节点可能为 null。但不是 END_EVENT 节点 |
| 101 | + // TODO @芋艿:这个要不要挪到 START_NODE - INCLUSIVE_BRANCH_JOIN_NODE 待定;感觉 switch 那最终是分三个情况;branch、子节点、结束了;(每种情况的注释,需要写的更完整) | |
| 100 | 102 | if (!BpmSimpleModelNodeType.isBranchNode(node.getType()) && (childNode == null || childNode.getId() == null)) { |
| 101 | 103 | SequenceFlow sequenceFlow = buildBpmnSequenceFlow(node.getId(), targetId, null, null, null); |
| 102 | 104 | mainProcess.addFlowElement(sequenceFlow); |
| ... | ... | @@ -104,6 +106,7 @@ public class SimpleModelUtils { |
| 104 | 106 | } |
| 105 | 107 | BpmSimpleModelNodeType nodeType = BpmSimpleModelNodeType.valueOf(node.getType()); |
| 106 | 108 | Assert.notNull(nodeType, "模型节点类型不支持"); |
| 109 | + // TODO @jason:下面的 PARALLEL_BRANCH_FORK_NODE、CONDITION_BRANCH_NODE、INCLUSIVE_BRANCH_FORK_NODE 是不是就是 isBranchNode?如果是的话,貌似不用 swtich,而是 if else 分类处理呢。 | |
| 107 | 110 | switch (nodeType) { |
| 108 | 111 | case START_NODE: |
| 109 | 112 | case APPROVE_NODE: |
| ... | ... | @@ -119,17 +122,24 @@ public class SimpleModelUtils { |
| 119 | 122 | case PARALLEL_BRANCH_FORK_NODE: |
| 120 | 123 | case CONDITION_BRANCH_NODE: |
| 121 | 124 | case INCLUSIVE_BRANCH_FORK_NODE: { |
| 125 | + // TODO @jason:这里 sequenceFlowTargetId 不建议做这样的 default。万一可能有 bug 哈;直接弄到对应的 136- 146 会更安全一点。 | |
| 122 | 126 | String sequenceFlowTargetId = (childNode == null || childNode.getId() == null) ? targetId : childNode.getId(); |
| 123 | 127 | List<BpmSimpleModelNodeVO> conditionNodes = node.getConditionNodes(); |
| 124 | 128 | Assert.notEmpty(conditionNodes, "网关节点的条件节点不能为空"); |
| 125 | 129 | for (BpmSimpleModelNodeVO item : conditionNodes) { |
| 130 | + // 构建表达式 | |
| 131 | + // TODO @jason:条件分支的情况下,需要分 item 搞的条件,和 conditionNodes 搞的条件 | |
| 126 | 132 | String conditionExpression = buildConditionExpression(item); |
| 133 | + | |
| 127 | 134 | BpmSimpleModelNodeVO nextNodeOnCondition = item.getChildNode(); |
| 135 | + // TODO @jason:isValidNode | |
| 128 | 136 | if (nextNodeOnCondition != null && nextNodeOnCondition.getId() != null) { |
| 137 | + // TODO @jason:会存在 item.name 未空的情况么?这个时候,要不要兜底处理拼接 | |
| 129 | 138 | SequenceFlow sequenceFlow = buildBpmnSequenceFlow(node.getId(), nextNodeOnCondition.getId(), |
| 130 | 139 | item.getId(), item.getName(), conditionExpression); |
| 131 | 140 | mainProcess.addFlowElement(sequenceFlow); |
| 132 | 141 | // 递归调用后续节点 |
| 142 | + // TODO @jason:最好也有个例子,嘿嘿;S4 | |
| 133 | 143 | buildAndAddBpmnSequenceFlow(mainProcess, nextNodeOnCondition, sequenceFlowTargetId); |
| 134 | 144 | } else { |
| 135 | 145 | SequenceFlow sequenceFlow = buildBpmnSequenceFlow(node.getId(), sequenceFlowTargetId, |
| ... | ... | @@ -137,7 +147,7 @@ public class SimpleModelUtils { |
| 137 | 147 | mainProcess.addFlowElement(sequenceFlow); |
| 138 | 148 | } |
| 139 | 149 | } |
| 140 | - // 递归调用后续节点 | |
| 150 | + // 递归调用后续节点 TODO @jason:最好有个例子哈 | |
| 141 | 151 | buildAndAddBpmnSequenceFlow(mainProcess, childNode, targetId); |
| 142 | 152 | break; |
| 143 | 153 | } |
| ... | ... | @@ -188,6 +198,9 @@ public class SimpleModelUtils { |
| 188 | 198 | } |
| 189 | 199 | |
| 190 | 200 | private static SequenceFlow buildBpmnSequenceFlow(String sourceId, String targetId, String seqFlowId, String seqName, String conditionExpression) { |
| 201 | + // TODO @jason:最好断言下,sourceId、targetId 必须存在! | |
| 202 | + // TODO @jason:如果 seqFlowId 不存在的时候,是不是要生成一个默认的 seqFlowId? | |
| 203 | + // TODO @jason:如果 name 不存在的时候,是不是要生成一个默认的 name? | |
| 191 | 204 | SequenceFlow sequenceFlow = new SequenceFlow(sourceId, targetId); |
| 192 | 205 | if (StrUtil.isNotEmpty(conditionExpression)) { |
| 193 | 206 | sequenceFlow.setConditionExpression(conditionExpression); | ... | ... |