Commit 007639d61aeed2b1530b6d32555ac85980566c86

Authored by jason
1 parent d2750f08

仿钉钉流程设计- 简化审批节点拒绝处理

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 51 ErrorCode TASK_SIGN_DELETE_NO_PARENT = new ErrorCode(1_009_005_012, "任务减签失败,被减签的任务必须是通过加签生成的任务");
52 52 ErrorCode TASK_TRANSFER_FAIL_USER_REPEAT = new ErrorCode(1_009_005_013, "任务转办失败,转办人和当前审批人为同一人");
53 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 55 ErrorCode TASK_CREATE_FAIL_NO_CANDIDATE_USER = new ErrorCode(1_009_006_003, "操作失败,原因:找不到任务的审批人!");
55 56  
56 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 14 public enum BpmUserTaskRejectHandlerType {
15 15  
16 16 TERMINATION(1, "终止流程"),
17   - RETURN_PRE_USER_TASK(2, "驳回到用户任务");
  17 + RETURN_PRE_USER_TASK(2, "驳回到指定任务节点");
18 18  
19 19 private final Integer type;
20 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 2  
3 3 import cn.hutool.core.collection.CollUtil;
4 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 5 import cn.iocoder.yudao.module.bpm.service.task.BpmActivityService;
14   -import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
15 6 import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService;
16 7 import com.google.common.collect.ImmutableSet;
17 8 import jakarta.annotation.Resource;
18 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 10 import org.flowable.common.engine.api.delegate.event.FlowableEngineEntityEvent;
23 11 import org.flowable.common.engine.api.delegate.event.FlowableEngineEventType;
24 12 import org.flowable.engine.delegate.event.AbstractFlowableEngineEventListener;
25 13 import org.flowable.engine.delegate.event.FlowableActivityCancelledEvent;
26   -import org.flowable.engine.delegate.event.FlowableMessageEvent;
27 14 import org.flowable.engine.history.HistoricActivityInstance;
28 15 import org.flowable.task.api.Task;
29 16 import org.springframework.context.annotation.Lazy;
30 17 import org.springframework.stereotype.Component;
31 18  
32 19 import java.util.List;
33   -import java.util.Objects;
34 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 23 * 监听 {@link Task} 的开始与完成
42 24 *
... ... @@ -52,18 +34,12 @@ public class BpmTaskEventListener extends AbstractFlowableEngineEventListener {
52 34 @Resource
53 35 @Lazy // 解决循环依赖
54 36 private BpmActivityService activityService;
55   - @Resource
56   - @Lazy // 解决循环依赖
57   - private BpmProcessInstanceService processInstanceService;
58   - @Resource
59   - @Lazy // 延迟加载,避免循环依赖
60   - private BpmModelService bpmModelService;
61 37  
62 38 public static final Set<FlowableEngineEventType> TASK_EVENTS = ImmutableSet.<FlowableEngineEventType>builder()
63 39 .add(FlowableEngineEventType.TASK_CREATED)
64 40 .add(FlowableEngineEventType.TASK_ASSIGNED)
65 41 //.add(FlowableEngineEventType.TASK_COMPLETED) // 由于审批通过时,已经记录了 task 的 status 为通过,所以不需要监听了。
66   - .add(FlowableEngineEventType.ACTIVITY_MESSAGE_RECEIVED)
  42 +// .add(FlowableEngineEventType.ACTIVITY_MESSAGE_RECEIVED)
67 43 .add(FlowableEngineEventType.ACTIVITY_CANCELLED)
68 44 .build();
69 45  
... ... @@ -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 5 import cn.hutool.core.util.ArrayUtil;
6 6 import cn.hutool.core.util.StrUtil;
7 7 import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
8   -import cn.iocoder.yudao.module.bpm.enums.definition.BpmBoundaryEventType;
9 8 import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants;
10 9 import org.flowable.bpmn.converter.BpmnXMLConverter;
11 10 import org.flowable.bpmn.model.Process;
... ... @@ -43,6 +42,14 @@ public class BpmnModelUtils {
43 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 53 // TODO @jason:貌似这个没地方调用??? @芋艿 在 BpmTaskConvert里面。暂时注释掉了。
47 54 public static Map<String, Integer> parseFormFieldsPermission(BpmnModel bpmnModel, String flowElementId) {
48 55 FlowElement flowElement = getFlowElementById(bpmnModel, flowElementId);
... ... @@ -361,27 +368,6 @@ public class BpmnModelUtils {
361 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 371 public static String parseBoundaryEventExtensionElement(BoundaryEvent boundaryEvent, String customElement) {
386 372 if (boundaryEvent == null) {
387 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 23 import java.util.Map;
24 24 import java.util.Objects;
25 25  
26   -import static cn.iocoder.yudao.module.bpm.enums.definition.BpmBoundaryEventType.USER_TASK_REJECT_POST_PROCESS;
27 26 import static cn.iocoder.yudao.module.bpm.enums.definition.BpmBoundaryEventType.USER_TASK_TIMEOUT;
28 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 28 import static cn.iocoder.yudao.module.bpm.enums.definition.BpmUserTaskTimeoutActionEnum.AUTO_REMINDER;
31 29 import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants.*;
32 30 import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.SimpleModelConstants.*;
... ... @@ -222,12 +220,6 @@ public class SimpleModelUtils {
222 220 BoundaryEvent boundaryEvent = buildUserTaskTimerBoundaryEvent(userTask, userTaskConfig.getTimeoutHandler());
223 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 223 break;
232 224 }
233 225 case COPY_TASK: {
... ... @@ -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 279 private static BoundaryEvent buildUserTaskTimerBoundaryEvent(UserTask userTask, SimpleModelUserTaskConfig.TimeoutHandler timeoutHandler) {
305 280 // 定时器边界事件
306 281 BoundaryEvent boundaryEvent = new BoundaryEvent();
... ... @@ -406,9 +381,19 @@ public class SimpleModelUtils {
406 381 addFormFieldsPermission(userTaskConfig.getFieldsPermission(), userTask);
407 382 // 处理多实例
408 383 processMultiInstanceLoopCharacteristics(userTaskConfig.getApproveMethod(), userTask);
  384 + // 添加任务被拒绝的处理元素
  385 + addTaskRejectElements(userTaskConfig.getRejectHandler(), userTask);
409 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 397 private static void processMultiInstanceLoopCharacteristics(Integer approveMethod, UserTask userTask) {
413 398 BpmApproveMethodEnum bpmApproveMethodEnum = BpmApproveMethodEnum.valueOf(approveMethod);
414 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 12 import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
13 13 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*;
14 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 16 import cn.iocoder.yudao.module.bpm.enums.task.BpmCommentTypeEnum;
17 17 import cn.iocoder.yudao.module.bpm.enums.task.BpmDeleteReasonEnum;
18 18 import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskSignTypeEnum;
19 19 import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskStatusEnum;
20 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 21 import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils;
23 22 import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils;
24 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 27 import jakarta.annotation.Resource;
29 28 import jakarta.validation.Valid;
30 29 import lombok.extern.slf4j.Slf4j;
31   -import org.flowable.bpmn.model.BoundaryEvent;
32 30 import org.flowable.bpmn.model.BpmnModel;
33 31 import org.flowable.bpmn.model.FlowElement;
34 32 import org.flowable.bpmn.model.UserTask;
... ... @@ -36,7 +34,6 @@ import org.flowable.engine.HistoryService;
36 34 import org.flowable.engine.ManagementService;
37 35 import org.flowable.engine.RuntimeService;
38 36 import org.flowable.engine.TaskService;
39   -import org.flowable.engine.runtime.Execution;
40 37 import org.flowable.engine.runtime.ProcessInstance;
41 38 import org.flowable.task.api.DelegationState;
42 39 import org.flowable.task.api.Task;
... ... @@ -57,6 +54,8 @@ import java.util.stream.Stream;
57 54 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
58 55 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
59 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 61 * 流程任务实例 Service 实现类
... ... @@ -336,23 +335,23 @@ public class BpmTaskServiceImpl implements BpmTaskService {
336 335 // 2.2 添加评论
337 336 taskService.addComment(task.getId(), task.getProcessInstanceId(), BpmCommentTypeEnum.REJECT.getType(),
338 337 BpmCommentTypeEnum.REJECT.formatComment(reqVO.getReason()));
339   -
  338 + // 3.1 解析用户任务的拒绝处理类型
340 339 BpmnModel bpmnModel = bpmModelService.getBpmnModelByDefinitionId(task.getProcessDefinitionId());
341 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 355 processInstanceService.updateProcessInstanceReject(instance.getProcessInstanceId(), reqVO.getReason());
357 356 }
358 357  
... ...