Commit 15d0a11badab81b0338fac48d7b176e97bc93161
1 parent
dee2b7cb
feat: 子流程-超时设置
Showing
6 changed files
with
67 additions
and
3 deletions
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmBoundaryEventTypeEnum.java
| @@ -14,7 +14,8 @@ import lombok.Getter; | @@ -14,7 +14,8 @@ import lombok.Getter; | ||
| 14 | public enum BpmBoundaryEventTypeEnum { | 14 | public enum BpmBoundaryEventTypeEnum { |
| 15 | 15 | ||
| 16 | USER_TASK_TIMEOUT(1, "用户任务超时"), | 16 | USER_TASK_TIMEOUT(1, "用户任务超时"), |
| 17 | - DELAY_TIMER_TIMEOUT(2, "延迟器超时"); | 17 | + DELAY_TIMER_TIMEOUT(2, "延迟器超时"), |
| 18 | + CHILD_PROCESS_TIMEOUT(3, "子流程超时"); | ||
| 18 | 19 | ||
| 19 | private final Integer type; | 20 | private final Integer type; |
| 20 | private final String name; | 21 | private final String name; |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/simple/BpmSimpleModelNodeVO.java
| @@ -451,6 +451,9 @@ public class BpmSimpleModelNodeVO { | @@ -451,6 +451,9 @@ public class BpmSimpleModelNodeVO { | ||
| 451 | @NotNull(message = "子流程发起人配置不能为空") | 451 | @NotNull(message = "子流程发起人配置不能为空") |
| 452 | private StartUserSetting startUserSetting; | 452 | private StartUserSetting startUserSetting; |
| 453 | 453 | ||
| 454 | + @Schema(description = "超时设置", requiredMode = Schema.RequiredMode.REQUIRED, example = "{}") | ||
| 455 | + private TimeoutSetting timeoutSetting; | ||
| 456 | + | ||
| 454 | @Schema(description = "子流程发起人配置") | 457 | @Schema(description = "子流程发起人配置") |
| 455 | @Data | 458 | @Data |
| 456 | @Valid | 459 | @Valid |
| @@ -471,5 +474,23 @@ public class BpmSimpleModelNodeVO { | @@ -471,5 +474,23 @@ public class BpmSimpleModelNodeVO { | ||
| 471 | 474 | ||
| 472 | } | 475 | } |
| 473 | 476 | ||
| 477 | + @Schema(description = "超时设置") | ||
| 478 | + @Data | ||
| 479 | + @Valid | ||
| 480 | + public static class TimeoutSetting { | ||
| 481 | + | ||
| 482 | + @Schema(description = "是否开启超时设置", requiredMode = Schema.RequiredMode.REQUIRED, example = "false") | ||
| 483 | + @NotNull(message = "是否开启超时设置不能为空") | ||
| 484 | + private Boolean enable; | ||
| 485 | + | ||
| 486 | + @Schema(description = "时间类型", example = "1") | ||
| 487 | + @InEnum(BpmDelayTimerTypeEnum.class) | ||
| 488 | + private Integer type; | ||
| 489 | + | ||
| 490 | + @Schema(description = "时间表达式", example = "PT1H,2025-01-01T00:00:00") | ||
| 491 | + private String timeExpression; | ||
| 492 | + | ||
| 493 | + } | ||
| 494 | + | ||
| 474 | } | 495 | } |
| 475 | } | 496 | } |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmTaskEventListener.java
| @@ -110,6 +110,9 @@ public class BpmTaskEventListener extends AbstractFlowableEngineEventListener { | @@ -110,6 +110,9 @@ public class BpmTaskEventListener extends AbstractFlowableEngineEventListener { | ||
| 110 | } else if (ObjectUtil.equal(bpmTimerBoundaryEventType, BpmBoundaryEventTypeEnum.DELAY_TIMER_TIMEOUT)) { | 110 | } else if (ObjectUtil.equal(bpmTimerBoundaryEventType, BpmBoundaryEventTypeEnum.DELAY_TIMER_TIMEOUT)) { |
| 111 | String taskKey = boundaryEvent.getAttachedToRefId(); | 111 | String taskKey = boundaryEvent.getAttachedToRefId(); |
| 112 | taskService.triggerReceiveTask(event.getProcessInstanceId(), taskKey); | 112 | taskService.triggerReceiveTask(event.getProcessInstanceId(), taskKey); |
| 113 | + } else if (ObjectUtil.equal(bpmTimerBoundaryEventType, BpmBoundaryEventTypeEnum.CHILD_PROCESS_TIMEOUT)) { | ||
| 114 | + String taskKey = boundaryEvent.getAttachedToRefId(); | ||
| 115 | + taskService.processChildProcessTimeout(event.getProcessInstanceId(), taskKey); | ||
| 113 | } | 116 | } |
| 114 | } | 117 | } |
| 115 | } | 118 | } |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/SimpleModelUtils.java
| @@ -817,7 +817,8 @@ public class SimpleModelUtils { | @@ -817,7 +817,8 @@ public class SimpleModelUtils { | ||
| 817 | private static class ChildProcessConvert implements NodeConvert { | 817 | private static class ChildProcessConvert implements NodeConvert { |
| 818 | 818 | ||
| 819 | @Override | 819 | @Override |
| 820 | - public CallActivity convert(BpmSimpleModelNodeVO node) { | 820 | + public List<FlowElement> convertList(BpmSimpleModelNodeVO node) { |
| 821 | + List<FlowElement> flowElements = new ArrayList<>(2); | ||
| 821 | BpmSimpleModelNodeVO.ChildProcessSetting childProcessSetting = node.getChildProcessSetting(); | 822 | BpmSimpleModelNodeVO.ChildProcessSetting childProcessSetting = node.getChildProcessSetting(); |
| 822 | List<IOParameter> inVariables = childProcessSetting.getInVariables() == null ? | 823 | List<IOParameter> inVariables = childProcessSetting.getInVariables() == null ? |
| 823 | new ArrayList<>() : new ArrayList<>(childProcessSetting.getInVariables()); | 824 | new ArrayList<>() : new ArrayList<>(childProcessSetting.getInVariables()); |
| @@ -866,9 +867,27 @@ public class SimpleModelUtils { | @@ -866,9 +867,27 @@ public class SimpleModelUtils { | ||
| 866 | executionListeners.add(flowableListener); | 867 | executionListeners.add(flowableListener); |
| 867 | callActivity.setExecutionListeners(executionListeners); | 868 | callActivity.setExecutionListeners(executionListeners); |
| 868 | 869 | ||
| 870 | + // 7. 超时设置 | ||
| 871 | + if (childProcessSetting.getTimeoutSetting() != null) { | ||
| 872 | + BoundaryEvent boundaryEvent = new BoundaryEvent(); | ||
| 873 | + boundaryEvent.setId("Event-" + IdUtil.fastUUID()); | ||
| 874 | + boundaryEvent.setCancelActivity(false); | ||
| 875 | + boundaryEvent.setAttachedToRef(callActivity); | ||
| 876 | + TimerEventDefinition eventDefinition = new TimerEventDefinition(); | ||
| 877 | + if (childProcessSetting.getTimeoutSetting().getType().equals(BpmDelayTimerTypeEnum.FIXED_DATE_TIME.getType())) { | ||
| 878 | + eventDefinition.setTimeDuration(childProcessSetting.getTimeoutSetting().getTimeExpression()); | ||
| 879 | + } else if (childProcessSetting.getTimeoutSetting().getType().equals(BpmDelayTimerTypeEnum.FIXED_TIME_DURATION.getType())) { | ||
| 880 | + eventDefinition.setTimeDate(childProcessSetting.getTimeoutSetting().getTimeExpression()); | ||
| 881 | + } | ||
| 882 | + boundaryEvent.addEventDefinition(eventDefinition); | ||
| 883 | + addExtensionElement(boundaryEvent, BOUNDARY_EVENT_TYPE, BpmBoundaryEventTypeEnum.CHILD_PROCESS_TIMEOUT.getType()); | ||
| 884 | + flowElements.add(boundaryEvent); | ||
| 885 | + } | ||
| 886 | + | ||
| 869 | // 添加节点类型 | 887 | // 添加节点类型 |
| 870 | addNodeType(node.getType(), callActivity); | 888 | addNodeType(node.getType(), callActivity); |
| 871 | - return callActivity; | 889 | + flowElements.add(callActivity); |
| 890 | + return flowElements; | ||
| 872 | } | 891 | } |
| 873 | 892 | ||
| 874 | @Override | 893 | @Override |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java
| @@ -284,4 +284,12 @@ public interface BpmTaskService { | @@ -284,4 +284,12 @@ public interface BpmTaskService { | ||
| 284 | */ | 284 | */ |
| 285 | void triggerReceiveTask(String processInstanceId, String taskDefineKey); | 285 | void triggerReceiveTask(String processInstanceId, String taskDefineKey); |
| 286 | 286 | ||
| 287 | + /** | ||
| 288 | + * 处理 子流程 审批超时事件 | ||
| 289 | + * | ||
| 290 | + * @param processInstanceId 流程示例编号 | ||
| 291 | + * @param taskDefineKey 任务 Key | ||
| 292 | + */ | ||
| 293 | + void processChildProcessTimeout(String processInstanceId, String taskDefineKey); | ||
| 294 | + | ||
| 287 | } | 295 | } |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java
| @@ -41,6 +41,7 @@ import org.flowable.engine.ManagementService; | @@ -41,6 +41,7 @@ import org.flowable.engine.ManagementService; | ||
| 41 | import org.flowable.engine.RuntimeService; | 41 | import org.flowable.engine.RuntimeService; |
| 42 | import org.flowable.engine.TaskService; | 42 | import org.flowable.engine.TaskService; |
| 43 | import org.flowable.engine.history.HistoricActivityInstance; | 43 | import org.flowable.engine.history.HistoricActivityInstance; |
| 44 | +import org.flowable.engine.runtime.ActivityInstance; | ||
| 44 | import org.flowable.engine.runtime.Execution; | 45 | import org.flowable.engine.runtime.Execution; |
| 45 | import org.flowable.engine.runtime.ProcessInstance; | 46 | import org.flowable.engine.runtime.ProcessInstance; |
| 46 | import org.flowable.task.api.DelegationState; | 47 | import org.flowable.task.api.DelegationState; |
| @@ -1339,6 +1340,17 @@ public class BpmTaskServiceImpl implements BpmTaskService { | @@ -1339,6 +1340,17 @@ public class BpmTaskServiceImpl implements BpmTaskService { | ||
| 1339 | () -> runtimeService.trigger(execution.getId())); | 1340 | () -> runtimeService.trigger(execution.getId())); |
| 1340 | } | 1341 | } |
| 1341 | 1342 | ||
| 1343 | + @Override | ||
| 1344 | + @Transactional(rollbackFor = Exception.class) | ||
| 1345 | + public void processChildProcessTimeout(String processInstanceId, String taskDefineKey) { | ||
| 1346 | + List<ActivityInstance> activityInstances = runtimeService.createActivityInstanceQuery() | ||
| 1347 | + .processInstanceId(processInstanceId) | ||
| 1348 | + .activityId(taskDefineKey).list(); | ||
| 1349 | + activityInstances.forEach(activityInstance -> FlowableUtils.execute(activityInstance.getTenantId(), () -> { | ||
| 1350 | + moveTaskToEnd(activityInstance.getCalledProcessInstanceId(), BpmReasonEnum.TIMEOUT_APPROVE.getReason()); | ||
| 1351 | + })); | ||
| 1352 | + } | ||
| 1353 | + | ||
| 1342 | /** | 1354 | /** |
| 1343 | * 获得自身的代理对象,解决 AOP 生效问题 | 1355 | * 获得自身的代理对象,解决 AOP 生效问题 |
| 1344 | * | 1356 | * |