Commit 735ec9e3ac354172cc406eb782336bdcf677ce98
Merge remote-tracking branch 'yudao/feature/bpm' into feature/bpm-n
Showing
4 changed files
with
57 additions
and
40 deletions
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmListenerMapType.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/simple/BpmSimpleModelNodeVO.java
| @@ -36,24 +36,6 @@ public class BpmSimpleModelNodeVO { | @@ -36,24 +36,6 @@ public class BpmSimpleModelNodeVO { | ||
| 36 | @Schema(description = "子节点") | 36 | @Schema(description = "子节点") |
| 37 | private BpmSimpleModelNodeVO childNode; // 补充说明:在该模型下,子节点有且仅有一个,不会有多个 | 37 | private BpmSimpleModelNodeVO childNode; // 补充说明:在该模型下,子节点有且仅有一个,不会有多个 |
| 38 | 38 | ||
| 39 | - @Schema(description = "条件节点") | ||
| 40 | - private List<BpmSimpleModelNodeVO> conditionNodes; // 补充说明:有且仅有条件、并行、包容等分支会使用 | ||
| 41 | - | ||
| 42 | - // TODO @jason:conditionType、conditionExpression、defaultFlow、conditionGroups 搞成一个 condition 属性,会好点么? | ||
| 43 | - @Schema(description = "条件类型", example = "1") | ||
| 44 | - @InEnum(BpmSimpleModeConditionType.class) | ||
| 45 | - private Integer conditionType; // 仅用于条件节点 BpmSimpleModelNodeType.CONDITION_NODE | ||
| 46 | - | ||
| 47 | - @Schema(description = "条件表达式", example = "${day>3}") | ||
| 48 | - private String conditionExpression; // 仅用于条件节点 BpmSimpleModelNodeType.CONDITION_NODE | ||
| 49 | - | ||
| 50 | - @Schema(description = "是否默认条件", example = "true") | ||
| 51 | - private Boolean defaultFlow; // 仅用于条件节点 BpmSimpleModelNodeType.CONDITION_NODE | ||
| 52 | - /** | ||
| 53 | - * 条件组 | ||
| 54 | - */ | ||
| 55 | - private ConditionGroups conditionGroups; // 仅用于条件节点 BpmSimpleModelNodeType.CONDITION_NODE | ||
| 56 | - | ||
| 57 | @Schema(description = "候选人策略", example = "30") | 39 | @Schema(description = "候选人策略", example = "30") |
| 58 | @InEnum(BpmTaskCandidateStrategyEnum.class) | 40 | @InEnum(BpmTaskCandidateStrategyEnum.class) |
| 59 | private Integer candidateStrategy; // 用于审批,抄送节点 | 41 | private Integer candidateStrategy; // 用于审批,抄送节点 |
| @@ -110,6 +92,37 @@ public class BpmSimpleModelNodeVO { | @@ -110,6 +92,37 @@ public class BpmSimpleModelNodeVO { | ||
| 110 | */ | 92 | */ |
| 111 | private ListenerHandler taskCompleteListener; | 93 | private ListenerHandler taskCompleteListener; |
| 112 | 94 | ||
| 95 | + @Schema(description = "延迟器设置", example = "{}") | ||
| 96 | + private DelaySetting delaySetting; | ||
| 97 | + | ||
| 98 | + @Schema(description = "条件节点") | ||
| 99 | + private List<BpmSimpleModelNodeVO> conditionNodes; // 补充说明:有且仅有条件、并行、包容分支会使用 | ||
| 100 | + | ||
| 101 | + // TODO @jason:conditionType、conditionExpression、defaultFlow、conditionGroups 搞成一个 condition 属性,会好点么? | ||
| 102 | + @Schema(description = "条件类型", example = "1") | ||
| 103 | + @InEnum(BpmSimpleModeConditionType.class) | ||
| 104 | + private Integer conditionType; // 仅用于条件节点 BpmSimpleModelNodeType.CONDITION_NODE | ||
| 105 | + | ||
| 106 | + @Schema(description = "条件表达式", example = "${day>3}") | ||
| 107 | + private String conditionExpression; // 仅用于条件节点 BpmSimpleModelNodeType.CONDITION_NODE | ||
| 108 | + | ||
| 109 | + @Schema(description = "是否默认条件", example = "true") | ||
| 110 | + private Boolean defaultFlow; // 仅用于条件节点 BpmSimpleModelNodeType.CONDITION_NODE | ||
| 111 | + /** | ||
| 112 | + * 条件组 | ||
| 113 | + */ | ||
| 114 | + private ConditionGroups conditionGroups; // 仅用于条件节点 BpmSimpleModelNodeType.CONDITION_NODE | ||
| 115 | + | ||
| 116 | + // TODO @lesan:route 改成 router 会不会好点。因为触发器、延迟器,都带了类似 r | ||
| 117 | + | ||
| 118 | + // TODO @lesan:routeGroups | ||
| 119 | + @Schema(description = "路由分支组", example = "[]") | ||
| 120 | + private List<RouteCondition> routeGroup; | ||
| 121 | + | ||
| 122 | + // TODO @lesan:貌似没用??? | ||
| 123 | + @Schema(description = "默认分支 ID", example = "Flow_xxx") | ||
| 124 | + private String defaultFlowId; // 仅用于路由分支节点 BpmSimpleModelNodeType.ROUTE_BRANCH_NODE | ||
| 125 | + | ||
| 113 | @Schema(description = "任务监听器") | 126 | @Schema(description = "任务监听器") |
| 114 | @Valid | 127 | @Valid |
| 115 | @Data | 128 | @Data |
| @@ -130,17 +143,18 @@ public class BpmSimpleModelNodeVO { | @@ -130,17 +143,18 @@ public class BpmSimpleModelNodeVO { | ||
| 130 | 143 | ||
| 131 | // TODO @芋艿:这里后续要不要复用; | 144 | // TODO @芋艿:这里后续要不要复用; |
| 132 | 145 | ||
| 146 | + // TODO @lesan:ListenerParam 更合适哈。首先它是参数配置,然后形式是键值对 | ||
| 133 | @Schema(description = "任务监听器键值对") | 147 | @Schema(description = "任务监听器键值对") |
| 134 | @Data | 148 | @Data |
| 135 | public static class ListenerMap { | 149 | public static class ListenerMap { |
| 136 | 150 | ||
| 137 | - @Schema(description = "键", example = "xxx") | ||
| 138 | - private String key; | ||
| 139 | - | ||
| 140 | @Schema(description = "值类型", example = "1") | 151 | @Schema(description = "值类型", example = "1") |
| 141 | @InEnum(BpmListenerMapType.class) | 152 | @InEnum(BpmListenerMapType.class) |
| 142 | private Integer type; | 153 | private Integer type; |
| 143 | 154 | ||
| 155 | + @Schema(description = "键", example = "xxx") | ||
| 156 | + private String key; | ||
| 157 | + | ||
| 144 | @Schema(description = "值", example = "xxx") | 158 | @Schema(description = "值", example = "xxx") |
| 145 | private String value; | 159 | private String value; |
| 146 | 160 | ||
| @@ -261,9 +275,6 @@ public class BpmSimpleModelNodeVO { | @@ -261,9 +275,6 @@ public class BpmSimpleModelNodeVO { | ||
| 261 | 275 | ||
| 262 | } | 276 | } |
| 263 | 277 | ||
| 264 | - @Schema(description = "延迟器设置", example = "{}") | ||
| 265 | - private DelaySetting delaySetting; | ||
| 266 | - | ||
| 267 | @Schema(description = "延迟器") | 278 | @Schema(description = "延迟器") |
| 268 | @Data | 279 | @Data |
| 269 | @Valid | 280 | @Valid |
| @@ -280,22 +291,16 @@ public class BpmSimpleModelNodeVO { | @@ -280,22 +291,16 @@ public class BpmSimpleModelNodeVO { | ||
| 280 | 291 | ||
| 281 | } | 292 | } |
| 282 | 293 | ||
| 283 | - @Schema(description = "路由分支组", example = "[]") | ||
| 284 | - private List<RouteCondition> routeGroups; | ||
| 285 | - | ||
| 286 | - @Schema(description = "默认分支id", example = "Flow_xxx") | ||
| 287 | - private String defaultFlowId; // 仅用于路由分支节点 BpmSimpleModelNodeType.ROUTE_BRANCH_NODE | ||
| 288 | - | ||
| 289 | @Schema(description = "路由分支") | 294 | @Schema(description = "路由分支") |
| 290 | @Data | 295 | @Data |
| 291 | @Valid | 296 | @Valid |
| 292 | public static class RouteCondition { | 297 | public static class RouteCondition { |
| 293 | 298 | ||
| 294 | - @Schema(description = "节点 Id", example = "Activity_xxx") | 299 | + @Schema(description = "节点 Id", example = "Activity_xxx") // 跳转到该节点 |
| 295 | @NotEmpty(message = "节点 Id 不能为空") | 300 | @NotEmpty(message = "节点 Id 不能为空") |
| 296 | private String nodeId; | 301 | private String nodeId; |
| 297 | 302 | ||
| 298 | - // TODO @lesan:type、expression、groups;(可以晚点改,在和 conditionType、conditionExpression、defaultFlow、conditionGroups 讨论!) | 303 | + // TODO @lesan:type、expression、groups; |
| 299 | @Schema(description = "条件类型", example = "1") | 304 | @Schema(description = "条件类型", example = "1") |
| 300 | @InEnum(BpmSimpleModeConditionType.class) | 305 | @InEnum(BpmSimpleModeConditionType.class) |
| 301 | @NotNull(message = "条件类型不能为空") | 306 | @NotNull(message = "条件类型不能为空") |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/SimpleModelUtils.java
| @@ -439,28 +439,32 @@ public class SimpleModelUtils { | @@ -439,28 +439,32 @@ public class SimpleModelUtils { | ||
| 439 | } | 439 | } |
| 440 | // 设置监听器 | 440 | // 设置监听器 |
| 441 | addUserTaskListener(node, userTask); | 441 | addUserTaskListener(node, userTask); |
| 442 | - // 设置Simple设计器节点配置 | 442 | + // 设置 Simple 设计器节点配置 |
| 443 | + // TODO @lesan:只设置到 flowableListener 里面,整个 node 太大了!因为很多都保存过啦。 | ||
| 443 | addSimpleConfigInfo(userTask, node); | 444 | addSimpleConfigInfo(userTask, node); |
| 444 | return userTask; | 445 | return userTask; |
| 445 | } | 446 | } |
| 446 | 447 | ||
| 447 | private void addUserTaskListener(BpmSimpleModelNodeVO node, UserTask userTask) { | 448 | private void addUserTaskListener(BpmSimpleModelNodeVO node, UserTask userTask) { |
| 448 | List<FlowableListener> flowableListeners = new ArrayList<>(3); | 449 | List<FlowableListener> flowableListeners = new ArrayList<>(3); |
| 449 | - if (node.getTaskCreateListener().getEnable()) { | 450 | + if (node.getTaskCreateListener() != null |
| 451 | + && Boolean.TRUE.equals(node.getTaskCreateListener().getEnable())) { | ||
| 450 | FlowableListener flowableListener = new FlowableListener(); | 452 | FlowableListener flowableListener = new FlowableListener(); |
| 451 | flowableListener.setEvent(TaskListener.EVENTNAME_CREATE); | 453 | flowableListener.setEvent(TaskListener.EVENTNAME_CREATE); |
| 452 | flowableListener.setImplementationType(ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION); | 454 | flowableListener.setImplementationType(ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION); |
| 453 | flowableListener.setImplementation(DELEGATE_EXPRESSION); | 455 | flowableListener.setImplementation(DELEGATE_EXPRESSION); |
| 454 | flowableListeners.add(flowableListener); | 456 | flowableListeners.add(flowableListener); |
| 455 | } | 457 | } |
| 456 | - if (node.getTaskAssignListener().getEnable()) { | 458 | + if (node.getTaskAssignListener() != null |
| 459 | + && Boolean.TRUE.equals(node.getTaskAssignListener().getEnable())) { | ||
| 457 | FlowableListener flowableListener = new FlowableListener(); | 460 | FlowableListener flowableListener = new FlowableListener(); |
| 458 | flowableListener.setEvent(TaskListener.EVENTNAME_ASSIGNMENT); | 461 | flowableListener.setEvent(TaskListener.EVENTNAME_ASSIGNMENT); |
| 459 | flowableListener.setImplementationType(ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION); | 462 | flowableListener.setImplementationType(ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION); |
| 460 | flowableListener.setImplementation(DELEGATE_EXPRESSION); | 463 | flowableListener.setImplementation(DELEGATE_EXPRESSION); |
| 461 | flowableListeners.add(flowableListener); | 464 | flowableListeners.add(flowableListener); |
| 462 | } | 465 | } |
| 463 | - if (node.getTaskCompleteListener().getEnable()) { | 466 | + if (node.getTaskCompleteListener() != null |
| 467 | + && Boolean.TRUE.equals(node.getTaskCompleteListener().getEnable())) { | ||
| 464 | FlowableListener flowableListener = new FlowableListener(); | 468 | FlowableListener flowableListener = new FlowableListener(); |
| 465 | flowableListener.setEvent(TaskListener.EVENTNAME_COMPLETE); | 469 | flowableListener.setEvent(TaskListener.EVENTNAME_COMPLETE); |
| 466 | flowableListener.setImplementationType(ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION); | 470 | flowableListener.setImplementationType(ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION); |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/listener/BpmUserTaskListener.java
| 1 | package cn.iocoder.yudao.module.bpm.service.task.listener; | 1 | package cn.iocoder.yudao.module.bpm.service.task.listener; |
| 2 | 2 | ||
| 3 | import cn.hutool.core.collection.CollUtil; | 3 | import cn.hutool.core.collection.CollUtil; |
| 4 | +import cn.hutool.core.util.StrUtil; | ||
| 4 | import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO; | 5 | import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO; |
| 5 | import cn.iocoder.yudao.module.bpm.enums.definition.BpmListenerMapType; | 6 | import cn.iocoder.yudao.module.bpm.enums.definition.BpmListenerMapType; |
| 6 | import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils; | 7 | import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils; |
| @@ -24,6 +25,7 @@ import org.springframework.web.client.RestTemplate; | @@ -24,6 +25,7 @@ import org.springframework.web.client.RestTemplate; | ||
| 24 | import java.util.List; | 25 | import java.util.List; |
| 25 | import java.util.Map; | 26 | import java.util.Map; |
| 26 | 27 | ||
| 28 | +import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.HEADER_TENANT_ID; | ||
| 27 | import static cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils.parseSimpleConfigInfo; | 29 | import static cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils.parseSimpleConfigInfo; |
| 28 | 30 | ||
| 29 | /** | 31 | /** |
| @@ -62,18 +64,23 @@ public class BpmUserTaskListener implements TaskListener { | @@ -62,18 +64,23 @@ public class BpmUserTaskListener implements TaskListener { | ||
| 62 | parseListenerMap(listenerHandler.getHeader(), processVariables, headers); | 64 | parseListenerMap(listenerHandler.getHeader(), processVariables, headers); |
| 63 | parseListenerMap(listenerHandler.getBody(), processVariables, body); | 65 | parseListenerMap(listenerHandler.getBody(), processVariables, body); |
| 64 | // 2.1 请求头默认参数 | 66 | // 2.1 请求头默认参数 |
| 65 | - headers.add("tenant-id", delegateTask.getTenantId()); | 67 | + if (StrUtil.isNotEmpty(delegateTask.getTenantId())) { |
| 68 | + headers.add(HEADER_TENANT_ID, delegateTask.getTenantId()); | ||
| 69 | + } | ||
| 66 | // 2.2 请求体默认参数 | 70 | // 2.2 请求体默认参数 |
| 71 | + // TODO @芋艿:哪些默认参数,后续再调研下; | ||
| 67 | body.add("processInstanceId", delegateTask.getProcessInstanceId()); | 72 | body.add("processInstanceId", delegateTask.getProcessInstanceId()); |
| 68 | body.add("assignee", delegateTask.getAssignee()); | 73 | body.add("assignee", delegateTask.getAssignee()); |
| 69 | body.add("taskDefinitionKey", delegateTask.getTaskDefinitionKey()); | 74 | body.add("taskDefinitionKey", delegateTask.getTaskDefinitionKey()); |
| 70 | body.add("taskId", delegateTask.getId()); | 75 | body.add("taskId", delegateTask.getId()); |
| 71 | 76 | ||
| 72 | // 3. 异步发起请求 | 77 | // 3. 异步发起请求 |
| 78 | + // TODO @芋艿:确认要同步,还是异步 | ||
| 73 | HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(body, headers); | 79 | HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(body, headers); |
| 74 | ResponseEntity<String> responseEntity = restTemplate.exchange(listenerHandler.getPath(), HttpMethod.POST, | 80 | ResponseEntity<String> responseEntity = restTemplate.exchange(listenerHandler.getPath(), HttpMethod.POST, |
| 75 | requestEntity, String.class); | 81 | requestEntity, String.class); |
| 76 | - log.info("[BpmUserTaskListener][的响应结果({})]", responseEntity); | 82 | + // TODO @lesan:日志打印,可以更全哈,例如说,请求参数、对应的 task id,哪个 listener |
| 83 | + log.info("[notify][的响应结果({})]", responseEntity); | ||
| 77 | // 4. 是否需要后续操作?TODO 芋艿:待定! | 84 | // 4. 是否需要后续操作?TODO 芋艿:待定! |
| 78 | } | 85 | } |
| 79 | 86 | ||
| @@ -92,12 +99,13 @@ public class BpmUserTaskListener implements TaskListener { | @@ -92,12 +99,13 @@ public class BpmUserTaskListener implements TaskListener { | ||
| 92 | }); | 99 | }); |
| 93 | } | 100 | } |
| 94 | 101 | ||
| 102 | + // TODO @lesan:改成 jdk8 写法哈。主要考虑好兼容! | ||
| 95 | private BpmSimpleModelNodeVO.ListenerHandler getListenerHandlerByEvent(String eventName, BpmSimpleModelNodeVO node) { | 103 | private BpmSimpleModelNodeVO.ListenerHandler getListenerHandlerByEvent(String eventName, BpmSimpleModelNodeVO node) { |
| 96 | return switch (eventName) { | 104 | return switch (eventName) { |
| 97 | case TaskListener.EVENTNAME_CREATE -> node.getTaskCreateListener(); | 105 | case TaskListener.EVENTNAME_CREATE -> node.getTaskCreateListener(); |
| 98 | case TaskListener.EVENTNAME_ASSIGNMENT -> node.getTaskAssignListener(); | 106 | case TaskListener.EVENTNAME_ASSIGNMENT -> node.getTaskAssignListener(); |
| 99 | case TaskListener.EVENTNAME_COMPLETE -> node.getTaskCompleteListener(); | 107 | case TaskListener.EVENTNAME_COMPLETE -> node.getTaskCompleteListener(); |
| 100 | - default -> null; | 108 | + default -> null; // TODO @lesan:这个抛出异常,可控一点 |
| 101 | }; | 109 | }; |
| 102 | } | 110 | } |
| 103 | 111 |