mirror of
https://gitee.com/hhyykk/ipms-sjy.git
synced 2025-07-24 07:55:06 +08:00
仿钉钉流程设计- 简化审批节点拒绝处理
This commit is contained in:
@ -51,6 +51,7 @@ public interface ErrorCodeConstants {
|
|||||||
ErrorCode TASK_SIGN_DELETE_NO_PARENT = new ErrorCode(1_009_005_012, "任务减签失败,被减签的任务必须是通过加签生成的任务");
|
ErrorCode TASK_SIGN_DELETE_NO_PARENT = new ErrorCode(1_009_005_012, "任务减签失败,被减签的任务必须是通过加签生成的任务");
|
||||||
ErrorCode TASK_TRANSFER_FAIL_USER_REPEAT = new ErrorCode(1_009_005_013, "任务转办失败,转办人和当前审批人为同一人");
|
ErrorCode TASK_TRANSFER_FAIL_USER_REPEAT = new ErrorCode(1_009_005_013, "任务转办失败,转办人和当前审批人为同一人");
|
||||||
ErrorCode TASK_TRANSFER_FAIL_USER_NOT_EXISTS = new ErrorCode(1_009_005_014, "任务转办失败,转办人不存在");
|
ErrorCode TASK_TRANSFER_FAIL_USER_NOT_EXISTS = new ErrorCode(1_009_005_014, "任务转办失败,转办人不存在");
|
||||||
|
ErrorCode TASK_RETURN_NOT_ASSIGN_TARGET_TASK_ID = new ErrorCode(1_009_005_015, "回退任务未指定目标任务编号");
|
||||||
ErrorCode TASK_CREATE_FAIL_NO_CANDIDATE_USER = new ErrorCode(1_009_006_003, "操作失败,原因:找不到任务的审批人!");
|
ErrorCode TASK_CREATE_FAIL_NO_CANDIDATE_USER = new ErrorCode(1_009_006_003, "操作失败,原因:找不到任务的审批人!");
|
||||||
|
|
||||||
// ========== 动态表单模块 1-009-010-000 ==========
|
// ========== 动态表单模块 1-009-010-000 ==========
|
||||||
|
@ -14,7 +14,7 @@ import lombok.Getter;
|
|||||||
public enum BpmUserTaskRejectHandlerType {
|
public enum BpmUserTaskRejectHandlerType {
|
||||||
|
|
||||||
TERMINATION(1, "终止流程"),
|
TERMINATION(1, "终止流程"),
|
||||||
RETURN_PRE_USER_TASK(2, "驳回到用户任务");
|
RETURN_PRE_USER_TASK(2, "驳回到指定任务节点");
|
||||||
|
|
||||||
private final Integer type;
|
private final Integer type;
|
||||||
private final String name;
|
private final String name;
|
||||||
|
@ -2,41 +2,23 @@ package cn.iocoder.yudao.module.bpm.framework.flowable.core.listener;
|
|||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
|
|
||||||
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskReturnReqVO;
|
|
||||||
import cn.iocoder.yudao.module.bpm.enums.definition.BpmUserTaskRejectHandlerType;
|
|
||||||
import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskStatusEnum;
|
|
||||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants;
|
|
||||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils;
|
|
||||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils;
|
|
||||||
import cn.iocoder.yudao.module.bpm.service.definition.BpmModelService;
|
|
||||||
import cn.iocoder.yudao.module.bpm.service.task.BpmActivityService;
|
import cn.iocoder.yudao.module.bpm.service.task.BpmActivityService;
|
||||||
import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
|
|
||||||
import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService;
|
import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.flowable.bpmn.model.BoundaryEvent;
|
|
||||||
import org.flowable.bpmn.model.BpmnModel;
|
|
||||||
import org.flowable.bpmn.model.FlowElement;
|
|
||||||
import org.flowable.common.engine.api.delegate.event.FlowableEngineEntityEvent;
|
import org.flowable.common.engine.api.delegate.event.FlowableEngineEntityEvent;
|
||||||
import org.flowable.common.engine.api.delegate.event.FlowableEngineEventType;
|
import org.flowable.common.engine.api.delegate.event.FlowableEngineEventType;
|
||||||
import org.flowable.engine.delegate.event.AbstractFlowableEngineEventListener;
|
import org.flowable.engine.delegate.event.AbstractFlowableEngineEventListener;
|
||||||
import org.flowable.engine.delegate.event.FlowableActivityCancelledEvent;
|
import org.flowable.engine.delegate.event.FlowableActivityCancelledEvent;
|
||||||
import org.flowable.engine.delegate.event.FlowableMessageEvent;
|
|
||||||
import org.flowable.engine.history.HistoricActivityInstance;
|
import org.flowable.engine.history.HistoricActivityInstance;
|
||||||
import org.flowable.task.api.Task;
|
import org.flowable.task.api.Task;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserId;
|
|
||||||
import static cn.iocoder.yudao.module.bpm.enums.definition.BpmBoundaryEventType.USER_TASK_REJECT_POST_PROCESS;
|
|
||||||
import static cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils.parseBoundaryEventExtensionElement;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 监听 {@link Task} 的开始与完成
|
* 监听 {@link Task} 的开始与完成
|
||||||
*
|
*
|
||||||
@ -52,18 +34,12 @@ public class BpmTaskEventListener extends AbstractFlowableEngineEventListener {
|
|||||||
@Resource
|
@Resource
|
||||||
@Lazy // 解决循环依赖
|
@Lazy // 解决循环依赖
|
||||||
private BpmActivityService activityService;
|
private BpmActivityService activityService;
|
||||||
@Resource
|
|
||||||
@Lazy // 解决循环依赖
|
|
||||||
private BpmProcessInstanceService processInstanceService;
|
|
||||||
@Resource
|
|
||||||
@Lazy // 延迟加载,避免循环依赖
|
|
||||||
private BpmModelService bpmModelService;
|
|
||||||
|
|
||||||
public static final Set<FlowableEngineEventType> TASK_EVENTS = ImmutableSet.<FlowableEngineEventType>builder()
|
public static final Set<FlowableEngineEventType> TASK_EVENTS = ImmutableSet.<FlowableEngineEventType>builder()
|
||||||
.add(FlowableEngineEventType.TASK_CREATED)
|
.add(FlowableEngineEventType.TASK_CREATED)
|
||||||
.add(FlowableEngineEventType.TASK_ASSIGNED)
|
.add(FlowableEngineEventType.TASK_ASSIGNED)
|
||||||
//.add(FlowableEngineEventType.TASK_COMPLETED) // 由于审批通过时,已经记录了 task 的 status 为通过,所以不需要监听了。
|
//.add(FlowableEngineEventType.TASK_COMPLETED) // 由于审批通过时,已经记录了 task 的 status 为通过,所以不需要监听了。
|
||||||
.add(FlowableEngineEventType.ACTIVITY_MESSAGE_RECEIVED)
|
// .add(FlowableEngineEventType.ACTIVITY_MESSAGE_RECEIVED)
|
||||||
.add(FlowableEngineEventType.ACTIVITY_CANCELLED)
|
.add(FlowableEngineEventType.ACTIVITY_CANCELLED)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
@ -97,47 +73,47 @@ public class BpmTaskEventListener extends AbstractFlowableEngineEventListener {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
// @Override
|
||||||
protected void activityMessageReceived(FlowableMessageEvent event) {
|
// protected void activityMessageReceived(FlowableMessageEvent event) {
|
||||||
BpmnModel bpmnModel = bpmModelService.getBpmnModelByDefinitionId(event.getProcessDefinitionId());
|
// BpmnModel bpmnModel = bpmModelService.getBpmnModelByDefinitionId(event.getProcessDefinitionId());
|
||||||
FlowElement element = BpmnModelUtils.getFlowElementById(bpmnModel, event.getActivityId());
|
// FlowElement element = BpmnModelUtils.getFlowElementById(bpmnModel, event.getActivityId());
|
||||||
if (element instanceof BoundaryEvent) {
|
// if (element instanceof BoundaryEvent) {
|
||||||
BoundaryEvent boundaryEvent = (BoundaryEvent) element;
|
// BoundaryEvent boundaryEvent = (BoundaryEvent) element;
|
||||||
String boundaryEventType = parseBoundaryEventExtensionElement(boundaryEvent, BpmnModelConstants.BOUNDARY_EVENT_TYPE);
|
// String boundaryEventType = parseBoundaryEventExtensionElement(boundaryEvent, BpmnModelConstants.BOUNDARY_EVENT_TYPE);
|
||||||
// 如果自定义类型为拒绝后处理,进行拒绝处理
|
// // 如果自定义类型为拒绝后处理,进行拒绝处理
|
||||||
if (Objects.equals(USER_TASK_REJECT_POST_PROCESS.getType(), NumberUtils.parseInt(boundaryEventType))) {
|
// if (Objects.equals(USER_TASK_REJECT_POST_PROCESS.getType(), NumberUtils.parseInt(boundaryEventType))) {
|
||||||
String rejectHandlerType = parseBoundaryEventExtensionElement((BoundaryEvent) element, BpmnModelConstants.USER_TASK_REJECT_HANDLER_TYPE);
|
// String rejectHandlerType = parseBoundaryEventExtensionElement((BoundaryEvent) element, BpmnModelConstants.USER_TASK_REJECT_HANDLER_TYPE);
|
||||||
rejectHandler(boundaryEvent, event.getProcessInstanceId(), boundaryEvent.getAttachedToRefId(), NumberUtils.parseInt(rejectHandlerType));
|
// rejectHandler(boundaryEvent, event.getProcessInstanceId(), boundaryEvent.getAttachedToRefId(), NumberUtils.parseInt(rejectHandlerType));
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
private void rejectHandler(BoundaryEvent boundaryEvent, String processInstanceId, String taskDefineKey, Integer rejectHandlerType) {
|
// private void rejectHandler(BoundaryEvent boundaryEvent, String processInstanceId, String taskDefineKey, Integer rejectHandlerType) {
|
||||||
BpmUserTaskRejectHandlerType userTaskRejectHandlerType = BpmUserTaskRejectHandlerType.typeOf(rejectHandlerType);
|
// BpmUserTaskRejectHandlerType userTaskRejectHandlerType = BpmUserTaskRejectHandlerType.typeOf(rejectHandlerType);
|
||||||
if (userTaskRejectHandlerType != null) {
|
// if (userTaskRejectHandlerType != null) {
|
||||||
List<Task> taskList = taskService.getAssignedTaskListByConditions(processInstanceId, null, taskDefineKey);
|
// List<Task> taskList = taskService.getAssignedTaskListByConditions(processInstanceId, null, taskDefineKey);
|
||||||
taskList.forEach(task -> {
|
// taskList.forEach(task -> {
|
||||||
Integer taskStatus = FlowableUtils.getTaskStatus(task);
|
// Integer taskStatus = FlowableUtils.getTaskStatus(task);
|
||||||
// 只有处于拒绝状态下才处理
|
// // 只有处于拒绝状态下才处理
|
||||||
if (Objects.equals(BpmTaskStatusEnum.REJECT.getStatus(), taskStatus)) {
|
// if (Objects.equals(BpmTaskStatusEnum.REJECT.getStatus(), taskStatus)) {
|
||||||
// 终止流程
|
// // 终止流程
|
||||||
if (userTaskRejectHandlerType == BpmUserTaskRejectHandlerType.TERMINATION) {
|
// if (userTaskRejectHandlerType == BpmUserTaskRejectHandlerType.TERMINATION) {
|
||||||
processInstanceService.updateProcessInstanceReject(task.getProcessInstanceId(), FlowableUtils.getTaskReason(task));
|
// processInstanceService.updateProcessInstanceReject(task.getProcessInstanceId(), FlowableUtils.getTaskReason(task));
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
// 驳回
|
// // 驳回
|
||||||
if (userTaskRejectHandlerType == BpmUserTaskRejectHandlerType.RETURN_PRE_USER_TASK) {
|
// if (userTaskRejectHandlerType == BpmUserTaskRejectHandlerType.RETURN_PRE_USER_TASK) {
|
||||||
String returnTaskId = parseBoundaryEventExtensionElement(boundaryEvent, BpmnModelConstants.USER_TASK_REJECT_RETURN_TASK_ID);
|
// String returnTaskId = parseBoundaryEventExtensionElement(boundaryEvent, BpmnModelConstants.USER_TASK_REJECT_RETURN_TASK_ID);
|
||||||
if (returnTaskId != null) {
|
// if (returnTaskId != null) {
|
||||||
BpmTaskReturnReqVO reqVO = new BpmTaskReturnReqVO().setId(task.getId())
|
// BpmTaskReturnReqVO reqVO = new BpmTaskReturnReqVO().setId(task.getId())
|
||||||
.setTargetTaskDefinitionKey(returnTaskId)
|
// .setTargetTaskDefinitionKey(returnTaskId)
|
||||||
.setReason("任务拒绝回退");
|
// .setReason("任务拒绝回退");
|
||||||
taskService.returnTask(getLoginUserId(), reqVO);
|
// taskService.returnTask(getLoginUserId(), reqVO);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@ import cn.hutool.core.map.MapUtil;
|
|||||||
import cn.hutool.core.util.ArrayUtil;
|
import cn.hutool.core.util.ArrayUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
|
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
|
||||||
import cn.iocoder.yudao.module.bpm.enums.definition.BpmBoundaryEventType;
|
|
||||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants;
|
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants;
|
||||||
import org.flowable.bpmn.converter.BpmnXMLConverter;
|
import org.flowable.bpmn.converter.BpmnXMLConverter;
|
||||||
import org.flowable.bpmn.model.Process;
|
import org.flowable.bpmn.model.Process;
|
||||||
@ -43,6 +42,14 @@ public class BpmnModelUtils {
|
|||||||
return candidateParam;
|
return candidateParam;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String parseExtensionElement(FlowElement flowElement, String elementName) {
|
||||||
|
if (flowElement == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
ExtensionElement element = CollUtil.getFirst(flowElement.getExtensionElements().get(elementName));
|
||||||
|
return Optional.ofNullable(element).map(ExtensionElement::getElementText).orElse(null);
|
||||||
|
}
|
||||||
|
|
||||||
// TODO @jason:貌似这个没地方调用??? @芋艿 在 BpmTaskConvert里面。暂时注释掉了。
|
// TODO @jason:貌似这个没地方调用??? @芋艿 在 BpmTaskConvert里面。暂时注释掉了。
|
||||||
public static Map<String, Integer> parseFormFieldsPermission(BpmnModel bpmnModel, String flowElementId) {
|
public static Map<String, Integer> parseFormFieldsPermission(BpmnModel bpmnModel, String flowElementId) {
|
||||||
FlowElement flowElement = getFlowElementById(bpmnModel, flowElementId);
|
FlowElement flowElement = getFlowElementById(bpmnModel, flowElementId);
|
||||||
@ -361,27 +368,6 @@ public class BpmnModelUtils {
|
|||||||
return userTaskList;
|
return userTaskList;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 在用户任务中查找自定义的边界事件
|
|
||||||
*
|
|
||||||
* @param userTask 用户任务
|
|
||||||
* @param bpmBoundaryEventType 自定义的边界事件类型
|
|
||||||
*/
|
|
||||||
public static BoundaryEvent findCustomBoundaryEventOfUserTask(UserTask userTask, BpmBoundaryEventType bpmBoundaryEventType) {
|
|
||||||
if (userTask == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
BoundaryEvent result = null;
|
|
||||||
for (BoundaryEvent item : userTask.getBoundaryEvents()) {
|
|
||||||
String boundaryEventType = parseBoundaryEventExtensionElement(item, BpmnModelConstants.BOUNDARY_EVENT_TYPE);
|
|
||||||
if (Objects.equals(bpmBoundaryEventType.getType(), NumberUtils.parseInt(boundaryEventType))) {
|
|
||||||
result = item;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String parseBoundaryEventExtensionElement(BoundaryEvent boundaryEvent, String customElement) {
|
public static String parseBoundaryEventExtensionElement(BoundaryEvent boundaryEvent, String customElement) {
|
||||||
if (boundaryEvent == null) {
|
if (boundaryEvent == null) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -23,10 +23,8 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.module.bpm.enums.definition.BpmBoundaryEventType.USER_TASK_REJECT_POST_PROCESS;
|
|
||||||
import static cn.iocoder.yudao.module.bpm.enums.definition.BpmBoundaryEventType.USER_TASK_TIMEOUT;
|
import static cn.iocoder.yudao.module.bpm.enums.definition.BpmBoundaryEventType.USER_TASK_TIMEOUT;
|
||||||
import static cn.iocoder.yudao.module.bpm.enums.definition.BpmSimpleModelNodeType.END_EVENT;
|
import static cn.iocoder.yudao.module.bpm.enums.definition.BpmSimpleModelNodeType.END_EVENT;
|
||||||
import static cn.iocoder.yudao.module.bpm.enums.definition.BpmUserTaskRejectHandlerType.RETURN_PRE_USER_TASK;
|
|
||||||
import static cn.iocoder.yudao.module.bpm.enums.definition.BpmUserTaskTimeoutActionEnum.AUTO_REMINDER;
|
import static cn.iocoder.yudao.module.bpm.enums.definition.BpmUserTaskTimeoutActionEnum.AUTO_REMINDER;
|
||||||
import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants.*;
|
import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants.*;
|
||||||
import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.SimpleModelConstants.*;
|
import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.SimpleModelConstants.*;
|
||||||
@ -222,12 +220,6 @@ public class SimpleModelUtils {
|
|||||||
BoundaryEvent boundaryEvent = buildUserTaskTimerBoundaryEvent(userTask, userTaskConfig.getTimeoutHandler());
|
BoundaryEvent boundaryEvent = buildUserTaskTimerBoundaryEvent(userTask, userTaskConfig.getTimeoutHandler());
|
||||||
mainProcess.addFlowElement(boundaryEvent);
|
mainProcess.addFlowElement(boundaryEvent);
|
||||||
}
|
}
|
||||||
if (userTaskConfig.getRejectHandler() != null) {
|
|
||||||
// 添加用户任务拒绝 Message Boundary Event, 用于任务的拒绝处理
|
|
||||||
BoundaryEvent boundaryEvent = buildUserTaskRejectBoundaryEvent(userTask, userTaskConfig.getRejectHandler());
|
|
||||||
mainProcess.addFlowElement(boundaryEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case COPY_TASK: {
|
case COPY_TASK: {
|
||||||
@ -284,23 +276,6 @@ public class SimpleModelUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static BoundaryEvent buildUserTaskRejectBoundaryEvent(UserTask userTask, RejectHandler rejectHandler) {
|
|
||||||
BoundaryEvent messageBoundaryEvent = new BoundaryEvent();
|
|
||||||
messageBoundaryEvent.setId("Event-" + IdUtil.fastUUID());
|
|
||||||
// 设置关联的任务为不会被中断
|
|
||||||
messageBoundaryEvent.setCancelActivity(false);
|
|
||||||
messageBoundaryEvent.setAttachedToRef(userTask);
|
|
||||||
MessageEventDefinition messageEventDefinition = new MessageEventDefinition();
|
|
||||||
messageEventDefinition.setMessageRef(REJECT_POST_PROCESS_MESSAGE_NAME);
|
|
||||||
messageBoundaryEvent.addEventDefinition(messageEventDefinition);
|
|
||||||
addExtensionElement(messageBoundaryEvent, BOUNDARY_EVENT_TYPE, USER_TASK_REJECT_POST_PROCESS.getType().toString());
|
|
||||||
addExtensionElement(messageBoundaryEvent, USER_TASK_REJECT_HANDLER_TYPE, StrUtil.toStringOrNull(rejectHandler.getType()));
|
|
||||||
if (Objects.equals(rejectHandler.getType(), RETURN_PRE_USER_TASK.getType())) {
|
|
||||||
addExtensionElement(messageBoundaryEvent, USER_TASK_REJECT_RETURN_TASK_ID, rejectHandler.getReturnNodeId());
|
|
||||||
}
|
|
||||||
return messageBoundaryEvent;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static BoundaryEvent buildUserTaskTimerBoundaryEvent(UserTask userTask, SimpleModelUserTaskConfig.TimeoutHandler timeoutHandler) {
|
private static BoundaryEvent buildUserTaskTimerBoundaryEvent(UserTask userTask, SimpleModelUserTaskConfig.TimeoutHandler timeoutHandler) {
|
||||||
// 定时器边界事件
|
// 定时器边界事件
|
||||||
BoundaryEvent boundaryEvent = new BoundaryEvent();
|
BoundaryEvent boundaryEvent = new BoundaryEvent();
|
||||||
@ -406,9 +381,19 @@ public class SimpleModelUtils {
|
|||||||
addFormFieldsPermission(userTaskConfig.getFieldsPermission(), userTask);
|
addFormFieldsPermission(userTaskConfig.getFieldsPermission(), userTask);
|
||||||
// 处理多实例
|
// 处理多实例
|
||||||
processMultiInstanceLoopCharacteristics(userTaskConfig.getApproveMethod(), userTask);
|
processMultiInstanceLoopCharacteristics(userTaskConfig.getApproveMethod(), userTask);
|
||||||
|
// 添加任务被拒绝的处理元素
|
||||||
|
addTaskRejectElements(userTaskConfig.getRejectHandler(), userTask);
|
||||||
return userTask;
|
return userTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void addTaskRejectElements(RejectHandler rejectHandler, UserTask userTask) {
|
||||||
|
if (rejectHandler == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
addExtensionElement(userTask, USER_TASK_REJECT_HANDLER_TYPE, StrUtil.toStringOrNull(rejectHandler.getType()));
|
||||||
|
addExtensionElement(userTask, USER_TASK_REJECT_RETURN_TASK_ID, rejectHandler.getReturnNodeId());
|
||||||
|
}
|
||||||
|
|
||||||
private static void processMultiInstanceLoopCharacteristics(Integer approveMethod, UserTask userTask) {
|
private static void processMultiInstanceLoopCharacteristics(Integer approveMethod, UserTask userTask) {
|
||||||
BpmApproveMethodEnum bpmApproveMethodEnum = BpmApproveMethodEnum.valueOf(approveMethod);
|
BpmApproveMethodEnum bpmApproveMethodEnum = BpmApproveMethodEnum.valueOf(approveMethod);
|
||||||
if (bpmApproveMethodEnum == null || bpmApproveMethodEnum == BpmApproveMethodEnum.SINGLE_PERSON_APPROVE) {
|
if (bpmApproveMethodEnum == null || bpmApproveMethodEnum == BpmApproveMethodEnum.SINGLE_PERSON_APPROVE) {
|
||||||
|
@ -12,13 +12,12 @@ import cn.iocoder.yudao.framework.common.util.object.PageUtils;
|
|||||||
import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
|
import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
|
||||||
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*;
|
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*;
|
||||||
import cn.iocoder.yudao.module.bpm.convert.task.BpmTaskConvert;
|
import cn.iocoder.yudao.module.bpm.convert.task.BpmTaskConvert;
|
||||||
import cn.iocoder.yudao.module.bpm.enums.definition.BpmBoundaryEventType;
|
import cn.iocoder.yudao.module.bpm.enums.definition.BpmUserTaskRejectHandlerType;
|
||||||
import cn.iocoder.yudao.module.bpm.enums.task.BpmCommentTypeEnum;
|
import cn.iocoder.yudao.module.bpm.enums.task.BpmCommentTypeEnum;
|
||||||
import cn.iocoder.yudao.module.bpm.enums.task.BpmDeleteReasonEnum;
|
import cn.iocoder.yudao.module.bpm.enums.task.BpmDeleteReasonEnum;
|
||||||
import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskSignTypeEnum;
|
import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskSignTypeEnum;
|
||||||
import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskStatusEnum;
|
import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskStatusEnum;
|
||||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmConstants;
|
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmConstants;
|
||||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants;
|
|
||||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils;
|
import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils;
|
||||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils;
|
import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils;
|
||||||
import cn.iocoder.yudao.module.bpm.service.definition.BpmModelService;
|
import cn.iocoder.yudao.module.bpm.service.definition.BpmModelService;
|
||||||
@ -28,7 +27,6 @@ import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
|||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.flowable.bpmn.model.BoundaryEvent;
|
|
||||||
import org.flowable.bpmn.model.BpmnModel;
|
import org.flowable.bpmn.model.BpmnModel;
|
||||||
import org.flowable.bpmn.model.FlowElement;
|
import org.flowable.bpmn.model.FlowElement;
|
||||||
import org.flowable.bpmn.model.UserTask;
|
import org.flowable.bpmn.model.UserTask;
|
||||||
@ -36,7 +34,6 @@ import org.flowable.engine.HistoryService;
|
|||||||
import org.flowable.engine.ManagementService;
|
import org.flowable.engine.ManagementService;
|
||||||
import org.flowable.engine.RuntimeService;
|
import org.flowable.engine.RuntimeService;
|
||||||
import org.flowable.engine.TaskService;
|
import org.flowable.engine.TaskService;
|
||||||
import org.flowable.engine.runtime.Execution;
|
|
||||||
import org.flowable.engine.runtime.ProcessInstance;
|
import org.flowable.engine.runtime.ProcessInstance;
|
||||||
import org.flowable.task.api.DelegationState;
|
import org.flowable.task.api.DelegationState;
|
||||||
import org.flowable.task.api.Task;
|
import org.flowable.task.api.Task;
|
||||||
@ -57,6 +54,8 @@ import java.util.stream.Stream;
|
|||||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
|
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
|
||||||
import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*;
|
import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*;
|
||||||
|
import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants.USER_TASK_REJECT_HANDLER_TYPE;
|
||||||
|
import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants.USER_TASK_REJECT_RETURN_TASK_ID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 流程任务实例 Service 实现类
|
* 流程任务实例 Service 实现类
|
||||||
@ -336,23 +335,23 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
|||||||
// 2.2 添加评论
|
// 2.2 添加评论
|
||||||
taskService.addComment(task.getId(), task.getProcessInstanceId(), BpmCommentTypeEnum.REJECT.getType(),
|
taskService.addComment(task.getId(), task.getProcessInstanceId(), BpmCommentTypeEnum.REJECT.getType(),
|
||||||
BpmCommentTypeEnum.REJECT.formatComment(reqVO.getReason()));
|
BpmCommentTypeEnum.REJECT.formatComment(reqVO.getReason()));
|
||||||
|
// 3.1 解析用户任务的拒绝处理类型
|
||||||
BpmnModel bpmnModel = bpmModelService.getBpmnModelByDefinitionId(task.getProcessDefinitionId());
|
BpmnModel bpmnModel = bpmModelService.getBpmnModelByDefinitionId(task.getProcessDefinitionId());
|
||||||
FlowElement flowElement = BpmnModelUtils.getFlowElementById(bpmnModel, task.getTaskDefinitionKey());
|
FlowElement flowElement = BpmnModelUtils.getFlowElementById(bpmnModel, task.getTaskDefinitionKey());
|
||||||
// 寻找用户任务的自定义拒绝后处理边界事件
|
Integer rejectHandlerType = NumberUtils.parseInt(BpmnModelUtils.parseExtensionElement(flowElement, USER_TASK_REJECT_HANDLER_TYPE));
|
||||||
BoundaryEvent rejectBoundaryEvent = BpmnModelUtils.findCustomBoundaryEventOfUserTask((UserTask) flowElement,
|
BpmUserTaskRejectHandlerType userTaskRejectHandlerType = BpmUserTaskRejectHandlerType.typeOf(rejectHandlerType);
|
||||||
BpmBoundaryEventType.USER_TASK_REJECT_POST_PROCESS);
|
// 3.2 类型为驳回到指定的任务节点
|
||||||
|
if (userTaskRejectHandlerType == BpmUserTaskRejectHandlerType.RETURN_PRE_USER_TASK) {
|
||||||
if (rejectBoundaryEvent != null) {
|
String returnTaskId = BpmnModelUtils.parseExtensionElement(flowElement, USER_TASK_REJECT_RETURN_TASK_ID);
|
||||||
Execution execution = runtimeService.createExecutionQuery().processInstanceId(task.getProcessInstanceId())
|
if (returnTaskId == null) {
|
||||||
.activityId(rejectBoundaryEvent.getId()).singleResult();
|
throw exception(TASK_RETURN_NOT_ASSIGN_TARGET_TASK_ID);
|
||||||
if (execution != null) {
|
|
||||||
// 3.1 触发消息边界事件. 进一步的处理交给 BpmTaskEventListener
|
|
||||||
runtimeService.messageEventReceived(BpmnModelConstants.REJECT_POST_PROCESS_MESSAGE_NAME, execution.getId());
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
BpmTaskReturnReqVO returnReq = new BpmTaskReturnReqVO().setId(task.getId()).setTargetTaskDefinitionKey(returnTaskId)
|
||||||
|
.setReason(reqVO.getReason());
|
||||||
|
returnTask(userId, returnReq);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
// 3.2 没有找到拒绝后处理边界事件, 更新流程实例,审批不通过!
|
// 3.3 其他情况 终止流程。 TODO 后续可能会增加处理类型
|
||||||
processInstanceService.updateProcessInstanceReject(instance.getProcessInstanceId(), reqVO.getReason());
|
processInstanceService.updateProcessInstanceReject(instance.getProcessInstanceId(), reqVO.getReason());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user