Commit 007639d61aeed2b1530b6d32555ac85980566c86
1 parent
d2750f08
仿钉钉流程设计- 简化审批节点拒绝处理
Showing
6 changed files
with
79 additions
and
132 deletions
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/ErrorCodeConstants.java
| @@ -51,6 +51,7 @@ public interface ErrorCodeConstants { | @@ -51,6 +51,7 @@ public interface ErrorCodeConstants { | ||
| 51 | ErrorCode TASK_SIGN_DELETE_NO_PARENT = new ErrorCode(1_009_005_012, "任务减签失败,被减签的任务必须是通过加签生成的任务"); | 51 | ErrorCode TASK_SIGN_DELETE_NO_PARENT = new ErrorCode(1_009_005_012, "任务减签失败,被减签的任务必须是通过加签生成的任务"); |
| 52 | ErrorCode TASK_TRANSFER_FAIL_USER_REPEAT = new ErrorCode(1_009_005_013, "任务转办失败,转办人和当前审批人为同一人"); | 52 | ErrorCode TASK_TRANSFER_FAIL_USER_REPEAT = new ErrorCode(1_009_005_013, "任务转办失败,转办人和当前审批人为同一人"); |
| 53 | ErrorCode TASK_TRANSFER_FAIL_USER_NOT_EXISTS = new ErrorCode(1_009_005_014, "任务转办失败,转办人不存在"); | 53 | ErrorCode TASK_TRANSFER_FAIL_USER_NOT_EXISTS = new ErrorCode(1_009_005_014, "任务转办失败,转办人不存在"); |
| 54 | + ErrorCode TASK_RETURN_NOT_ASSIGN_TARGET_TASK_ID = new ErrorCode(1_009_005_015, "回退任务未指定目标任务编号"); | ||
| 54 | ErrorCode TASK_CREATE_FAIL_NO_CANDIDATE_USER = new ErrorCode(1_009_006_003, "操作失败,原因:找不到任务的审批人!"); | 55 | ErrorCode TASK_CREATE_FAIL_NO_CANDIDATE_USER = new ErrorCode(1_009_006_003, "操作失败,原因:找不到任务的审批人!"); |
| 55 | 56 | ||
| 56 | // ========== 动态表单模块 1-009-010-000 ========== | 57 | // ========== 动态表单模块 1-009-010-000 ========== |
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmUserTaskRejectHandlerType.java
| @@ -14,7 +14,7 @@ import lombok.Getter; | @@ -14,7 +14,7 @@ import lombok.Getter; | ||
| 14 | public enum BpmUserTaskRejectHandlerType { | 14 | public enum BpmUserTaskRejectHandlerType { |
| 15 | 15 | ||
| 16 | TERMINATION(1, "终止流程"), | 16 | TERMINATION(1, "终止流程"), |
| 17 | - RETURN_PRE_USER_TASK(2, "驳回到用户任务"); | 17 | + RETURN_PRE_USER_TASK(2, "驳回到指定任务节点"); |
| 18 | 18 | ||
| 19 | private final Integer type; | 19 | private final Integer type; |
| 20 | private final String name; | 20 | private final String name; |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmTaskEventListener.java
| @@ -2,41 +2,23 @@ package cn.iocoder.yudao.module.bpm.framework.flowable.core.listener; | @@ -2,41 +2,23 @@ package cn.iocoder.yudao.module.bpm.framework.flowable.core.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.hutool.core.util.StrUtil; |
| 5 | -import cn.iocoder.yudao.framework.common.util.number.NumberUtils; | ||
| 6 | -import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskReturnReqVO; | ||
| 7 | -import cn.iocoder.yudao.module.bpm.enums.definition.BpmUserTaskRejectHandlerType; | ||
| 8 | -import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskStatusEnum; | ||
| 9 | -import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants; | ||
| 10 | -import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils; | ||
| 11 | -import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils; | ||
| 12 | -import cn.iocoder.yudao.module.bpm.service.definition.BpmModelService; | ||
| 13 | import cn.iocoder.yudao.module.bpm.service.task.BpmActivityService; | 5 | import cn.iocoder.yudao.module.bpm.service.task.BpmActivityService; |
| 14 | -import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService; | ||
| 15 | import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService; | 6 | import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService; |
| 16 | import com.google.common.collect.ImmutableSet; | 7 | import com.google.common.collect.ImmutableSet; |
| 17 | import jakarta.annotation.Resource; | 8 | import jakarta.annotation.Resource; |
| 18 | import lombok.extern.slf4j.Slf4j; | 9 | import lombok.extern.slf4j.Slf4j; |
| 19 | -import org.flowable.bpmn.model.BoundaryEvent; | ||
| 20 | -import org.flowable.bpmn.model.BpmnModel; | ||
| 21 | -import org.flowable.bpmn.model.FlowElement; | ||
| 22 | import org.flowable.common.engine.api.delegate.event.FlowableEngineEntityEvent; | 10 | import org.flowable.common.engine.api.delegate.event.FlowableEngineEntityEvent; |
| 23 | import org.flowable.common.engine.api.delegate.event.FlowableEngineEventType; | 11 | import org.flowable.common.engine.api.delegate.event.FlowableEngineEventType; |
| 24 | import org.flowable.engine.delegate.event.AbstractFlowableEngineEventListener; | 12 | import org.flowable.engine.delegate.event.AbstractFlowableEngineEventListener; |
| 25 | import org.flowable.engine.delegate.event.FlowableActivityCancelledEvent; | 13 | import org.flowable.engine.delegate.event.FlowableActivityCancelledEvent; |
| 26 | -import org.flowable.engine.delegate.event.FlowableMessageEvent; | ||
| 27 | import org.flowable.engine.history.HistoricActivityInstance; | 14 | import org.flowable.engine.history.HistoricActivityInstance; |
| 28 | import org.flowable.task.api.Task; | 15 | import org.flowable.task.api.Task; |
| 29 | import org.springframework.context.annotation.Lazy; | 16 | import org.springframework.context.annotation.Lazy; |
| 30 | import org.springframework.stereotype.Component; | 17 | import org.springframework.stereotype.Component; |
| 31 | 18 | ||
| 32 | import java.util.List; | 19 | import java.util.List; |
| 33 | -import java.util.Objects; | ||
| 34 | import java.util.Set; | 20 | import java.util.Set; |
| 35 | 21 | ||
| 36 | -import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserId; | ||
| 37 | -import static cn.iocoder.yudao.module.bpm.enums.definition.BpmBoundaryEventType.USER_TASK_REJECT_POST_PROCESS; | ||
| 38 | -import static cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils.parseBoundaryEventExtensionElement; | ||
| 39 | - | ||
| 40 | /** | 22 | /** |
| 41 | * 监听 {@link Task} 的开始与完成 | 23 | * 监听 {@link Task} 的开始与完成 |
| 42 | * | 24 | * |
| @@ -52,18 +34,12 @@ public class BpmTaskEventListener extends AbstractFlowableEngineEventListener { | @@ -52,18 +34,12 @@ public class BpmTaskEventListener extends AbstractFlowableEngineEventListener { | ||
| 52 | @Resource | 34 | @Resource |
| 53 | @Lazy // 解决循环依赖 | 35 | @Lazy // 解决循环依赖 |
| 54 | private BpmActivityService activityService; | 36 | private BpmActivityService activityService; |
| 55 | - @Resource | ||
| 56 | - @Lazy // 解决循环依赖 | ||
| 57 | - private BpmProcessInstanceService processInstanceService; | ||
| 58 | - @Resource | ||
| 59 | - @Lazy // 延迟加载,避免循环依赖 | ||
| 60 | - private BpmModelService bpmModelService; | ||
| 61 | 37 | ||
| 62 | public static final Set<FlowableEngineEventType> TASK_EVENTS = ImmutableSet.<FlowableEngineEventType>builder() | 38 | public static final Set<FlowableEngineEventType> TASK_EVENTS = ImmutableSet.<FlowableEngineEventType>builder() |
| 63 | .add(FlowableEngineEventType.TASK_CREATED) | 39 | .add(FlowableEngineEventType.TASK_CREATED) |
| 64 | .add(FlowableEngineEventType.TASK_ASSIGNED) | 40 | .add(FlowableEngineEventType.TASK_ASSIGNED) |
| 65 | //.add(FlowableEngineEventType.TASK_COMPLETED) // 由于审批通过时,已经记录了 task 的 status 为通过,所以不需要监听了。 | 41 | //.add(FlowableEngineEventType.TASK_COMPLETED) // 由于审批通过时,已经记录了 task 的 status 为通过,所以不需要监听了。 |
| 66 | - .add(FlowableEngineEventType.ACTIVITY_MESSAGE_RECEIVED) | 42 | +// .add(FlowableEngineEventType.ACTIVITY_MESSAGE_RECEIVED) |
| 67 | .add(FlowableEngineEventType.ACTIVITY_CANCELLED) | 43 | .add(FlowableEngineEventType.ACTIVITY_CANCELLED) |
| 68 | .build(); | 44 | .build(); |
| 69 | 45 | ||
| @@ -97,47 +73,47 @@ public class BpmTaskEventListener extends AbstractFlowableEngineEventListener { | @@ -97,47 +73,47 @@ public class BpmTaskEventListener extends AbstractFlowableEngineEventListener { | ||
| 97 | }); | 73 | }); |
| 98 | } | 74 | } |
| 99 | 75 | ||
| 100 | - @Override | ||
| 101 | - protected void activityMessageReceived(FlowableMessageEvent event) { | ||
| 102 | - BpmnModel bpmnModel = bpmModelService.getBpmnModelByDefinitionId(event.getProcessDefinitionId()); | ||
| 103 | - FlowElement element = BpmnModelUtils.getFlowElementById(bpmnModel, event.getActivityId()); | ||
| 104 | - if (element instanceof BoundaryEvent) { | ||
| 105 | - BoundaryEvent boundaryEvent = (BoundaryEvent) element; | ||
| 106 | - String boundaryEventType = parseBoundaryEventExtensionElement(boundaryEvent, BpmnModelConstants.BOUNDARY_EVENT_TYPE); | ||
| 107 | - // 如果自定义类型为拒绝后处理,进行拒绝处理 | ||
| 108 | - if (Objects.equals(USER_TASK_REJECT_POST_PROCESS.getType(), NumberUtils.parseInt(boundaryEventType))) { | ||
| 109 | - String rejectHandlerType = parseBoundaryEventExtensionElement((BoundaryEvent) element, BpmnModelConstants.USER_TASK_REJECT_HANDLER_TYPE); | ||
| 110 | - rejectHandler(boundaryEvent, event.getProcessInstanceId(), boundaryEvent.getAttachedToRefId(), NumberUtils.parseInt(rejectHandlerType)); | ||
| 111 | - } | ||
| 112 | - } | ||
| 113 | - } | ||
| 114 | - | ||
| 115 | - private void rejectHandler(BoundaryEvent boundaryEvent, String processInstanceId, String taskDefineKey, Integer rejectHandlerType) { | ||
| 116 | - BpmUserTaskRejectHandlerType userTaskRejectHandlerType = BpmUserTaskRejectHandlerType.typeOf(rejectHandlerType); | ||
| 117 | - if (userTaskRejectHandlerType != null) { | ||
| 118 | - List<Task> taskList = taskService.getAssignedTaskListByConditions(processInstanceId, null, taskDefineKey); | ||
| 119 | - taskList.forEach(task -> { | ||
| 120 | - Integer taskStatus = FlowableUtils.getTaskStatus(task); | ||
| 121 | - // 只有处于拒绝状态下才处理 | ||
| 122 | - if (Objects.equals(BpmTaskStatusEnum.REJECT.getStatus(), taskStatus)) { | ||
| 123 | - // 终止流程 | ||
| 124 | - if (userTaskRejectHandlerType == BpmUserTaskRejectHandlerType.TERMINATION) { | ||
| 125 | - processInstanceService.updateProcessInstanceReject(task.getProcessInstanceId(), FlowableUtils.getTaskReason(task)); | ||
| 126 | - return; | ||
| 127 | - } | ||
| 128 | - // 驳回 | ||
| 129 | - if (userTaskRejectHandlerType == BpmUserTaskRejectHandlerType.RETURN_PRE_USER_TASK) { | ||
| 130 | - String returnTaskId = parseBoundaryEventExtensionElement(boundaryEvent, BpmnModelConstants.USER_TASK_REJECT_RETURN_TASK_ID); | ||
| 131 | - if (returnTaskId != null) { | ||
| 132 | - BpmTaskReturnReqVO reqVO = new BpmTaskReturnReqVO().setId(task.getId()) | ||
| 133 | - .setTargetTaskDefinitionKey(returnTaskId) | ||
| 134 | - .setReason("任务拒绝回退"); | ||
| 135 | - taskService.returnTask(getLoginUserId(), reqVO); | ||
| 136 | - } | ||
| 137 | - } | ||
| 138 | - } | ||
| 139 | - }); | ||
| 140 | - } | ||
| 141 | - } | 76 | +// @Override |
| 77 | +// protected void activityMessageReceived(FlowableMessageEvent event) { | ||
| 78 | +// BpmnModel bpmnModel = bpmModelService.getBpmnModelByDefinitionId(event.getProcessDefinitionId()); | ||
| 79 | +// FlowElement element = BpmnModelUtils.getFlowElementById(bpmnModel, event.getActivityId()); | ||
| 80 | +// if (element instanceof BoundaryEvent) { | ||
| 81 | +// BoundaryEvent boundaryEvent = (BoundaryEvent) element; | ||
| 82 | +// String boundaryEventType = parseBoundaryEventExtensionElement(boundaryEvent, BpmnModelConstants.BOUNDARY_EVENT_TYPE); | ||
| 83 | +// // 如果自定义类型为拒绝后处理,进行拒绝处理 | ||
| 84 | +// if (Objects.equals(USER_TASK_REJECT_POST_PROCESS.getType(), NumberUtils.parseInt(boundaryEventType))) { | ||
| 85 | +// String rejectHandlerType = parseBoundaryEventExtensionElement((BoundaryEvent) element, BpmnModelConstants.USER_TASK_REJECT_HANDLER_TYPE); | ||
| 86 | +// rejectHandler(boundaryEvent, event.getProcessInstanceId(), boundaryEvent.getAttachedToRefId(), NumberUtils.parseInt(rejectHandlerType)); | ||
| 87 | +// } | ||
| 88 | +// } | ||
| 89 | +// } | ||
| 90 | +// | ||
| 91 | +// private void rejectHandler(BoundaryEvent boundaryEvent, String processInstanceId, String taskDefineKey, Integer rejectHandlerType) { | ||
| 92 | +// BpmUserTaskRejectHandlerType userTaskRejectHandlerType = BpmUserTaskRejectHandlerType.typeOf(rejectHandlerType); | ||
| 93 | +// if (userTaskRejectHandlerType != null) { | ||
| 94 | +// List<Task> taskList = taskService.getAssignedTaskListByConditions(processInstanceId, null, taskDefineKey); | ||
| 95 | +// taskList.forEach(task -> { | ||
| 96 | +// Integer taskStatus = FlowableUtils.getTaskStatus(task); | ||
| 97 | +// // 只有处于拒绝状态下才处理 | ||
| 98 | +// if (Objects.equals(BpmTaskStatusEnum.REJECT.getStatus(), taskStatus)) { | ||
| 99 | +// // 终止流程 | ||
| 100 | +// if (userTaskRejectHandlerType == BpmUserTaskRejectHandlerType.TERMINATION) { | ||
| 101 | +// processInstanceService.updateProcessInstanceReject(task.getProcessInstanceId(), FlowableUtils.getTaskReason(task)); | ||
| 102 | +// return; | ||
| 103 | +// } | ||
| 104 | +// // 驳回 | ||
| 105 | +// if (userTaskRejectHandlerType == BpmUserTaskRejectHandlerType.RETURN_PRE_USER_TASK) { | ||
| 106 | +// String returnTaskId = parseBoundaryEventExtensionElement(boundaryEvent, BpmnModelConstants.USER_TASK_REJECT_RETURN_TASK_ID); | ||
| 107 | +// if (returnTaskId != null) { | ||
| 108 | +// BpmTaskReturnReqVO reqVO = new BpmTaskReturnReqVO().setId(task.getId()) | ||
| 109 | +// .setTargetTaskDefinitionKey(returnTaskId) | ||
| 110 | +// .setReason("任务拒绝回退"); | ||
| 111 | +// taskService.returnTask(getLoginUserId(), reqVO); | ||
| 112 | +// } | ||
| 113 | +// } | ||
| 114 | +// } | ||
| 115 | +// }); | ||
| 116 | +// } | ||
| 117 | +// } | ||
| 142 | 118 | ||
| 143 | } | 119 | } |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/BpmnModelUtils.java
| @@ -5,7 +5,6 @@ import cn.hutool.core.map.MapUtil; | @@ -5,7 +5,6 @@ import cn.hutool.core.map.MapUtil; | ||
| 5 | import cn.hutool.core.util.ArrayUtil; | 5 | import cn.hutool.core.util.ArrayUtil; |
| 6 | import cn.hutool.core.util.StrUtil; | 6 | import cn.hutool.core.util.StrUtil; |
| 7 | import cn.iocoder.yudao.framework.common.util.number.NumberUtils; | 7 | import cn.iocoder.yudao.framework.common.util.number.NumberUtils; |
| 8 | -import cn.iocoder.yudao.module.bpm.enums.definition.BpmBoundaryEventType; | ||
| 9 | import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants; | 8 | import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants; |
| 10 | import org.flowable.bpmn.converter.BpmnXMLConverter; | 9 | import org.flowable.bpmn.converter.BpmnXMLConverter; |
| 11 | import org.flowable.bpmn.model.Process; | 10 | import org.flowable.bpmn.model.Process; |
| @@ -43,6 +42,14 @@ public class BpmnModelUtils { | @@ -43,6 +42,14 @@ public class BpmnModelUtils { | ||
| 43 | return candidateParam; | 42 | return candidateParam; |
| 44 | } | 43 | } |
| 45 | 44 | ||
| 45 | + public static String parseExtensionElement(FlowElement flowElement, String elementName) { | ||
| 46 | + if (flowElement == null) { | ||
| 47 | + return null; | ||
| 48 | + } | ||
| 49 | + ExtensionElement element = CollUtil.getFirst(flowElement.getExtensionElements().get(elementName)); | ||
| 50 | + return Optional.ofNullable(element).map(ExtensionElement::getElementText).orElse(null); | ||
| 51 | + } | ||
| 52 | + | ||
| 46 | // TODO @jason:貌似这个没地方调用??? @芋艿 在 BpmTaskConvert里面。暂时注释掉了。 | 53 | // TODO @jason:貌似这个没地方调用??? @芋艿 在 BpmTaskConvert里面。暂时注释掉了。 |
| 47 | public static Map<String, Integer> parseFormFieldsPermission(BpmnModel bpmnModel, String flowElementId) { | 54 | public static Map<String, Integer> parseFormFieldsPermission(BpmnModel bpmnModel, String flowElementId) { |
| 48 | FlowElement flowElement = getFlowElementById(bpmnModel, flowElementId); | 55 | FlowElement flowElement = getFlowElementById(bpmnModel, flowElementId); |
| @@ -361,27 +368,6 @@ public class BpmnModelUtils { | @@ -361,27 +368,6 @@ public class BpmnModelUtils { | ||
| 361 | return userTaskList; | 368 | return userTaskList; |
| 362 | } | 369 | } |
| 363 | 370 | ||
| 364 | - /** | ||
| 365 | - * 在用户任务中查找自定义的边界事件 | ||
| 366 | - * | ||
| 367 | - * @param userTask 用户任务 | ||
| 368 | - * @param bpmBoundaryEventType 自定义的边界事件类型 | ||
| 369 | - */ | ||
| 370 | - public static BoundaryEvent findCustomBoundaryEventOfUserTask(UserTask userTask, BpmBoundaryEventType bpmBoundaryEventType) { | ||
| 371 | - if (userTask == null) { | ||
| 372 | - return null; | ||
| 373 | - } | ||
| 374 | - BoundaryEvent result = null; | ||
| 375 | - for (BoundaryEvent item : userTask.getBoundaryEvents()) { | ||
| 376 | - String boundaryEventType = parseBoundaryEventExtensionElement(item, BpmnModelConstants.BOUNDARY_EVENT_TYPE); | ||
| 377 | - if (Objects.equals(bpmBoundaryEventType.getType(), NumberUtils.parseInt(boundaryEventType))) { | ||
| 378 | - result = item; | ||
| 379 | - break; | ||
| 380 | - } | ||
| 381 | - } | ||
| 382 | - return result; | ||
| 383 | - } | ||
| 384 | - | ||
| 385 | public static String parseBoundaryEventExtensionElement(BoundaryEvent boundaryEvent, String customElement) { | 371 | public static String parseBoundaryEventExtensionElement(BoundaryEvent boundaryEvent, String customElement) { |
| 386 | if (boundaryEvent == null) { | 372 | if (boundaryEvent == null) { |
| 387 | return null; | 373 | return null; |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/SimpleModelUtils.java
| @@ -23,10 +23,8 @@ import java.util.List; | @@ -23,10 +23,8 @@ import java.util.List; | ||
| 23 | import java.util.Map; | 23 | import java.util.Map; |
| 24 | import java.util.Objects; | 24 | import java.util.Objects; |
| 25 | 25 | ||
| 26 | -import static cn.iocoder.yudao.module.bpm.enums.definition.BpmBoundaryEventType.USER_TASK_REJECT_POST_PROCESS; | ||
| 27 | import static cn.iocoder.yudao.module.bpm.enums.definition.BpmBoundaryEventType.USER_TASK_TIMEOUT; | 26 | import static cn.iocoder.yudao.module.bpm.enums.definition.BpmBoundaryEventType.USER_TASK_TIMEOUT; |
| 28 | import static cn.iocoder.yudao.module.bpm.enums.definition.BpmSimpleModelNodeType.END_EVENT; | 27 | import static cn.iocoder.yudao.module.bpm.enums.definition.BpmSimpleModelNodeType.END_EVENT; |
| 29 | -import static cn.iocoder.yudao.module.bpm.enums.definition.BpmUserTaskRejectHandlerType.RETURN_PRE_USER_TASK; | ||
| 30 | import static cn.iocoder.yudao.module.bpm.enums.definition.BpmUserTaskTimeoutActionEnum.AUTO_REMINDER; | 28 | import static cn.iocoder.yudao.module.bpm.enums.definition.BpmUserTaskTimeoutActionEnum.AUTO_REMINDER; |
| 31 | import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants.*; | 29 | import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants.*; |
| 32 | import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.SimpleModelConstants.*; | 30 | import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.SimpleModelConstants.*; |
| @@ -222,12 +220,6 @@ public class SimpleModelUtils { | @@ -222,12 +220,6 @@ public class SimpleModelUtils { | ||
| 222 | BoundaryEvent boundaryEvent = buildUserTaskTimerBoundaryEvent(userTask, userTaskConfig.getTimeoutHandler()); | 220 | BoundaryEvent boundaryEvent = buildUserTaskTimerBoundaryEvent(userTask, userTaskConfig.getTimeoutHandler()); |
| 223 | mainProcess.addFlowElement(boundaryEvent); | 221 | mainProcess.addFlowElement(boundaryEvent); |
| 224 | } | 222 | } |
| 225 | - if (userTaskConfig.getRejectHandler() != null) { | ||
| 226 | - // 添加用户任务拒绝 Message Boundary Event, 用于任务的拒绝处理 | ||
| 227 | - BoundaryEvent boundaryEvent = buildUserTaskRejectBoundaryEvent(userTask, userTaskConfig.getRejectHandler()); | ||
| 228 | - mainProcess.addFlowElement(boundaryEvent); | ||
| 229 | - } | ||
| 230 | - | ||
| 231 | break; | 223 | break; |
| 232 | } | 224 | } |
| 233 | case COPY_TASK: { | 225 | case COPY_TASK: { |
| @@ -284,23 +276,6 @@ public class SimpleModelUtils { | @@ -284,23 +276,6 @@ public class SimpleModelUtils { | ||
| 284 | } | 276 | } |
| 285 | } | 277 | } |
| 286 | 278 | ||
| 287 | - private static BoundaryEvent buildUserTaskRejectBoundaryEvent(UserTask userTask, RejectHandler rejectHandler) { | ||
| 288 | - BoundaryEvent messageBoundaryEvent = new BoundaryEvent(); | ||
| 289 | - messageBoundaryEvent.setId("Event-" + IdUtil.fastUUID()); | ||
| 290 | - // 设置关联的任务为不会被中断 | ||
| 291 | - messageBoundaryEvent.setCancelActivity(false); | ||
| 292 | - messageBoundaryEvent.setAttachedToRef(userTask); | ||
| 293 | - MessageEventDefinition messageEventDefinition = new MessageEventDefinition(); | ||
| 294 | - messageEventDefinition.setMessageRef(REJECT_POST_PROCESS_MESSAGE_NAME); | ||
| 295 | - messageBoundaryEvent.addEventDefinition(messageEventDefinition); | ||
| 296 | - addExtensionElement(messageBoundaryEvent, BOUNDARY_EVENT_TYPE, USER_TASK_REJECT_POST_PROCESS.getType().toString()); | ||
| 297 | - addExtensionElement(messageBoundaryEvent, USER_TASK_REJECT_HANDLER_TYPE, StrUtil.toStringOrNull(rejectHandler.getType())); | ||
| 298 | - if (Objects.equals(rejectHandler.getType(), RETURN_PRE_USER_TASK.getType())) { | ||
| 299 | - addExtensionElement(messageBoundaryEvent, USER_TASK_REJECT_RETURN_TASK_ID, rejectHandler.getReturnNodeId()); | ||
| 300 | - } | ||
| 301 | - return messageBoundaryEvent; | ||
| 302 | - } | ||
| 303 | - | ||
| 304 | private static BoundaryEvent buildUserTaskTimerBoundaryEvent(UserTask userTask, SimpleModelUserTaskConfig.TimeoutHandler timeoutHandler) { | 279 | private static BoundaryEvent buildUserTaskTimerBoundaryEvent(UserTask userTask, SimpleModelUserTaskConfig.TimeoutHandler timeoutHandler) { |
| 305 | // 定时器边界事件 | 280 | // 定时器边界事件 |
| 306 | BoundaryEvent boundaryEvent = new BoundaryEvent(); | 281 | BoundaryEvent boundaryEvent = new BoundaryEvent(); |
| @@ -406,9 +381,19 @@ public class SimpleModelUtils { | @@ -406,9 +381,19 @@ public class SimpleModelUtils { | ||
| 406 | addFormFieldsPermission(userTaskConfig.getFieldsPermission(), userTask); | 381 | addFormFieldsPermission(userTaskConfig.getFieldsPermission(), userTask); |
| 407 | // 处理多实例 | 382 | // 处理多实例 |
| 408 | processMultiInstanceLoopCharacteristics(userTaskConfig.getApproveMethod(), userTask); | 383 | processMultiInstanceLoopCharacteristics(userTaskConfig.getApproveMethod(), userTask); |
| 384 | + // 添加任务被拒绝的处理元素 | ||
| 385 | + addTaskRejectElements(userTaskConfig.getRejectHandler(), userTask); | ||
| 409 | return userTask; | 386 | return userTask; |
| 410 | } | 387 | } |
| 411 | 388 | ||
| 389 | + private static void addTaskRejectElements(RejectHandler rejectHandler, UserTask userTask) { | ||
| 390 | + if (rejectHandler == null) { | ||
| 391 | + return; | ||
| 392 | + } | ||
| 393 | + addExtensionElement(userTask, USER_TASK_REJECT_HANDLER_TYPE, StrUtil.toStringOrNull(rejectHandler.getType())); | ||
| 394 | + addExtensionElement(userTask, USER_TASK_REJECT_RETURN_TASK_ID, rejectHandler.getReturnNodeId()); | ||
| 395 | + } | ||
| 396 | + | ||
| 412 | private static void processMultiInstanceLoopCharacteristics(Integer approveMethod, UserTask userTask) { | 397 | private static void processMultiInstanceLoopCharacteristics(Integer approveMethod, UserTask userTask) { |
| 413 | BpmApproveMethodEnum bpmApproveMethodEnum = BpmApproveMethodEnum.valueOf(approveMethod); | 398 | BpmApproveMethodEnum bpmApproveMethodEnum = BpmApproveMethodEnum.valueOf(approveMethod); |
| 414 | if (bpmApproveMethodEnum == null || bpmApproveMethodEnum == BpmApproveMethodEnum.SINGLE_PERSON_APPROVE) { | 399 | if (bpmApproveMethodEnum == null || bpmApproveMethodEnum == BpmApproveMethodEnum.SINGLE_PERSON_APPROVE) { |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java
| @@ -12,13 +12,12 @@ import cn.iocoder.yudao.framework.common.util.object.PageUtils; | @@ -12,13 +12,12 @@ import cn.iocoder.yudao.framework.common.util.object.PageUtils; | ||
| 12 | import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils; | 12 | import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils; |
| 13 | import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*; | 13 | import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*; |
| 14 | import cn.iocoder.yudao.module.bpm.convert.task.BpmTaskConvert; | 14 | import cn.iocoder.yudao.module.bpm.convert.task.BpmTaskConvert; |
| 15 | -import cn.iocoder.yudao.module.bpm.enums.definition.BpmBoundaryEventType; | 15 | +import cn.iocoder.yudao.module.bpm.enums.definition.BpmUserTaskRejectHandlerType; |
| 16 | import cn.iocoder.yudao.module.bpm.enums.task.BpmCommentTypeEnum; | 16 | import cn.iocoder.yudao.module.bpm.enums.task.BpmCommentTypeEnum; |
| 17 | import cn.iocoder.yudao.module.bpm.enums.task.BpmDeleteReasonEnum; | 17 | import cn.iocoder.yudao.module.bpm.enums.task.BpmDeleteReasonEnum; |
| 18 | import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskSignTypeEnum; | 18 | import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskSignTypeEnum; |
| 19 | import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskStatusEnum; | 19 | import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskStatusEnum; |
| 20 | import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmConstants; | 20 | import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmConstants; |
| 21 | -import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants; | ||
| 22 | import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils; | 21 | import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils; |
| 23 | import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils; | 22 | import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils; |
| 24 | import cn.iocoder.yudao.module.bpm.service.definition.BpmModelService; | 23 | import cn.iocoder.yudao.module.bpm.service.definition.BpmModelService; |
| @@ -28,7 +27,6 @@ import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; | @@ -28,7 +27,6 @@ import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; | ||
| 28 | import jakarta.annotation.Resource; | 27 | import jakarta.annotation.Resource; |
| 29 | import jakarta.validation.Valid; | 28 | import jakarta.validation.Valid; |
| 30 | import lombok.extern.slf4j.Slf4j; | 29 | import lombok.extern.slf4j.Slf4j; |
| 31 | -import org.flowable.bpmn.model.BoundaryEvent; | ||
| 32 | import org.flowable.bpmn.model.BpmnModel; | 30 | import org.flowable.bpmn.model.BpmnModel; |
| 33 | import org.flowable.bpmn.model.FlowElement; | 31 | import org.flowable.bpmn.model.FlowElement; |
| 34 | import org.flowable.bpmn.model.UserTask; | 32 | import org.flowable.bpmn.model.UserTask; |
| @@ -36,7 +34,6 @@ import org.flowable.engine.HistoryService; | @@ -36,7 +34,6 @@ import org.flowable.engine.HistoryService; | ||
| 36 | import org.flowable.engine.ManagementService; | 34 | import org.flowable.engine.ManagementService; |
| 37 | import org.flowable.engine.RuntimeService; | 35 | import org.flowable.engine.RuntimeService; |
| 38 | import org.flowable.engine.TaskService; | 36 | import org.flowable.engine.TaskService; |
| 39 | -import org.flowable.engine.runtime.Execution; | ||
| 40 | import org.flowable.engine.runtime.ProcessInstance; | 37 | import org.flowable.engine.runtime.ProcessInstance; |
| 41 | import org.flowable.task.api.DelegationState; | 38 | import org.flowable.task.api.DelegationState; |
| 42 | import org.flowable.task.api.Task; | 39 | import org.flowable.task.api.Task; |
| @@ -57,6 +54,8 @@ import java.util.stream.Stream; | @@ -57,6 +54,8 @@ import java.util.stream.Stream; | ||
| 57 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | 54 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 58 | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; | 55 | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; |
| 59 | import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*; | 56 | import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*; |
| 57 | +import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants.USER_TASK_REJECT_HANDLER_TYPE; | ||
| 58 | +import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants.USER_TASK_REJECT_RETURN_TASK_ID; | ||
| 60 | 59 | ||
| 61 | /** | 60 | /** |
| 62 | * 流程任务实例 Service 实现类 | 61 | * 流程任务实例 Service 实现类 |
| @@ -336,23 +335,23 @@ public class BpmTaskServiceImpl implements BpmTaskService { | @@ -336,23 +335,23 @@ public class BpmTaskServiceImpl implements BpmTaskService { | ||
| 336 | // 2.2 添加评论 | 335 | // 2.2 添加评论 |
| 337 | taskService.addComment(task.getId(), task.getProcessInstanceId(), BpmCommentTypeEnum.REJECT.getType(), | 336 | taskService.addComment(task.getId(), task.getProcessInstanceId(), BpmCommentTypeEnum.REJECT.getType(), |
| 338 | BpmCommentTypeEnum.REJECT.formatComment(reqVO.getReason())); | 337 | BpmCommentTypeEnum.REJECT.formatComment(reqVO.getReason())); |
| 339 | - | 338 | + // 3.1 解析用户任务的拒绝处理类型 |
| 340 | BpmnModel bpmnModel = bpmModelService.getBpmnModelByDefinitionId(task.getProcessDefinitionId()); | 339 | BpmnModel bpmnModel = bpmModelService.getBpmnModelByDefinitionId(task.getProcessDefinitionId()); |
| 341 | FlowElement flowElement = BpmnModelUtils.getFlowElementById(bpmnModel, task.getTaskDefinitionKey()); | 340 | FlowElement flowElement = BpmnModelUtils.getFlowElementById(bpmnModel, task.getTaskDefinitionKey()); |
| 342 | - // 寻找用户任务的自定义拒绝后处理边界事件 | ||
| 343 | - BoundaryEvent rejectBoundaryEvent = BpmnModelUtils.findCustomBoundaryEventOfUserTask((UserTask) flowElement, | ||
| 344 | - BpmBoundaryEventType.USER_TASK_REJECT_POST_PROCESS); | ||
| 345 | - | ||
| 346 | - if (rejectBoundaryEvent != null) { | ||
| 347 | - Execution execution = runtimeService.createExecutionQuery().processInstanceId(task.getProcessInstanceId()) | ||
| 348 | - .activityId(rejectBoundaryEvent.getId()).singleResult(); | ||
| 349 | - if (execution != null) { | ||
| 350 | - // 3.1 触发消息边界事件. 进一步的处理交给 BpmTaskEventListener | ||
| 351 | - runtimeService.messageEventReceived(BpmnModelConstants.REJECT_POST_PROCESS_MESSAGE_NAME, execution.getId()); | ||
| 352 | - return; | 341 | + Integer rejectHandlerType = NumberUtils.parseInt(BpmnModelUtils.parseExtensionElement(flowElement, USER_TASK_REJECT_HANDLER_TYPE)); |
| 342 | + BpmUserTaskRejectHandlerType userTaskRejectHandlerType = BpmUserTaskRejectHandlerType.typeOf(rejectHandlerType); | ||
| 343 | + // 3.2 类型为驳回到指定的任务节点 | ||
| 344 | + if (userTaskRejectHandlerType == BpmUserTaskRejectHandlerType.RETURN_PRE_USER_TASK) { | ||
| 345 | + String returnTaskId = BpmnModelUtils.parseExtensionElement(flowElement, USER_TASK_REJECT_RETURN_TASK_ID); | ||
| 346 | + if (returnTaskId == null) { | ||
| 347 | + throw exception(TASK_RETURN_NOT_ASSIGN_TARGET_TASK_ID); | ||
| 353 | } | 348 | } |
| 349 | + BpmTaskReturnReqVO returnReq = new BpmTaskReturnReqVO().setId(task.getId()).setTargetTaskDefinitionKey(returnTaskId) | ||
| 350 | + .setReason(reqVO.getReason()); | ||
| 351 | + returnTask(userId, returnReq); | ||
| 352 | + return; | ||
| 354 | } | 353 | } |
| 355 | - // 3.2 没有找到拒绝后处理边界事件, 更新流程实例,审批不通过! | 354 | + // 3.3 其他情况 终止流程。 TODO 后续可能会增加处理类型 |
| 356 | processInstanceService.updateProcessInstanceReject(instance.getProcessInstanceId(), reqVO.getReason()); | 355 | processInstanceService.updateProcessInstanceReject(instance.getProcessInstanceId(), reqVO.getReason()); |
| 357 | } | 356 | } |
| 358 | 357 |