【功能修复】工作流:自动审批通过时,不能使用 TransactionSynchronizationManager 的 afterCommit 的情况

This commit is contained in:
YunaiV 2024-08-24 14:42:09 +08:00
parent 764a242d07
commit 70386263e4
3 changed files with 52 additions and 47 deletions

View File

@ -1,17 +1,8 @@
package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.extra.spring.SpringUtil;
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskApproveReqVO;
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskRejectReqVO;
import cn.iocoder.yudao.module.bpm.enums.definition.BpmUserTaskApproveTypeEnum;
import cn.iocoder.yudao.module.bpm.enums.definition.BpmUserTaskAssignEmptyHandlerTypeEnum;
import cn.iocoder.yudao.module.bpm.enums.task.BpmReasonEnum;
import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateInvoker;
import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils;
import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.flowable.bpmn.model.UserTask;
@ -22,8 +13,7 @@ import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.flowable.engine.impl.util.TaskHelper;
import org.flowable.task.service.TaskService;
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Set;
@ -46,6 +36,7 @@ public class BpmUserTaskActivityBehavior extends UserTaskActivityBehavior {
}
@Override
@Transactional(rollbackFor = Exception.class)
protected void handleAssignments(TaskService taskService, String assignee, String owner,
List<String> candidateUsers, List<String> candidateGroups, TaskEntity task, ExpressionManager expressionManager,
DelegateExecution execution, ProcessEngineConfigurationImpl processEngineConfiguration) {
@ -54,39 +45,7 @@ public class BpmUserTaskActivityBehavior extends UserTaskActivityBehavior {
// 第二步设置作为负责人
if (assigneeUserId != null) {
TaskHelper.changeTaskAssignee(task, String.valueOf(assigneeUserId));
return;
}
// 特殊处理需要自动通过不通过的情况
Integer approveType = BpmnModelUtils.parseApproveType(userTask);
Integer assignEmptyHandlerType = BpmnModelUtils.parseAssignEmptyHandlerType(userTask);
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
@Override
public void afterCommit() {
// 特殊情况一人工审核审批人为空根据配置是否要自动通过自动拒绝
if (ObjectUtil.equal(approveType, BpmUserTaskApproveTypeEnum.USER.getType())) {
if (ObjectUtil.equal(assignEmptyHandlerType, BpmUserTaskAssignEmptyHandlerTypeEnum.APPROVE.getType())) {
SpringUtil.getBean(BpmTaskService.class).approveTask(null, new BpmTaskApproveReqVO()
.setId(task.getId()).setReason(BpmReasonEnum.ASSIGN_EMPTY_APPROVE.getReason()));
} else if (ObjectUtil.equal(assignEmptyHandlerType, BpmUserTaskAssignEmptyHandlerTypeEnum.REJECT.getType())) {
SpringUtil.getBean(BpmTaskService.class).rejectTask(null, new BpmTaskRejectReqVO()
.setId(task.getId()).setReason(BpmReasonEnum.ASSIGN_EMPTY_REJECT.getReason()));
}
// 特殊情况二自动审核审批类型为自动通过不通过
} else {
if (ObjectUtil.equal(approveType, BpmUserTaskApproveTypeEnum.AUTO_APPROVE.getType())) {
SpringUtil.getBean(BpmTaskService.class).approveTask(null, new BpmTaskApproveReqVO()
.setId(task.getId()).setReason(BpmReasonEnum.APPROVE_TYPE_AUTO_APPROVE.getReason()));
} else if (ObjectUtil.equal(approveType, BpmUserTaskApproveTypeEnum.AUTO_REJECT.getType())) {
SpringUtil.getBean(BpmTaskService.class).rejectTask(null, new BpmTaskRejectReqVO()
.setId(task.getId()).setReason(BpmReasonEnum.APPROVE_TYPE_AUTO_REJECT.getReason()));
}
}
}
});
}
private Long calculateTaskCandidateUsers(DelegateExecution execution) {

View File

@ -188,7 +188,12 @@ public interface BpmTaskService {
// ========== Event 事件相关方法 ==========
/**
* 处理 Task 创建事件目前是更新它的状态为审批中
* 处理 Task 创建事件目前是
*
* 1. 更新它的状态为审批中
* 2. 处理自动通过的情况例如说1无审批人时是否自动通过不通过2人工审核是否自动通过不通过
*
* 注意它的触发时机晚于 {@link #processTaskAssigned(Task)} 之后
*
* @param task 任务实体
*/

View File

@ -12,9 +12,7 @@ import cn.iocoder.yudao.framework.common.util.object.PageUtils;
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.convert.task.BpmTaskConvert;
import cn.iocoder.yudao.module.bpm.enums.definition.BpmUserTaskAssignStartUserHandlerTypeEnum;
import cn.iocoder.yudao.module.bpm.enums.definition.BpmUserTaskRejectHandlerType;
import cn.iocoder.yudao.module.bpm.enums.definition.BpmUserTaskTimeoutHandlerTypeEnum;
import cn.iocoder.yudao.module.bpm.enums.definition.*;
import cn.iocoder.yudao.module.bpm.enums.task.BpmCommentTypeEnum;
import cn.iocoder.yudao.module.bpm.enums.task.BpmReasonEnum;
import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskSignTypeEnum;
@ -888,12 +886,55 @@ public class BpmTaskServiceImpl implements BpmTaskService {
@Override
public void processTaskCreated(Task task) {
// 1. 设置为待办中
Integer status = (Integer) task.getTaskLocalVariables().get(BpmnVariableConstants.TASK_VARIABLE_STATUS);
if (status != null) {
log.error("[updateTaskStatusWhenCreated][taskId({}) 已经有状态({})]", task.getId(), status);
return;
}
updateTaskStatus(task.getId(), BpmTaskStatusEnum.RUNNING.getStatus());
// 2. 处理自动通过的情况例如说1无审批人时是否自动通过不通过2人工审核是否自动通过不通过
ProcessInstance processInstance = processInstanceService.getProcessInstance(task.getProcessInstanceId());
if (processInstance == null) {
log.error("[processTaskCreated][taskId({}) 没有找到流程实例]", task.getId());
return;
}
BpmnModel bpmnModel = modelService.getBpmnModelByDefinitionId(processInstance.getProcessDefinitionId());
FlowElement userTaskElement = BpmnModelUtils.getFlowElementById(bpmnModel, task.getTaskDefinitionKey());
Integer approveType = BpmnModelUtils.parseApproveType(userTaskElement);
Integer assignEmptyHandlerType = BpmnModelUtils.parseAssignEmptyHandlerType(userTaskElement);
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
@Override
public void afterCompletion(int transactionStatus) {
// 特殊情况部分情况下TransactionSynchronizationManager 注册 afterCommit 监听时不会被调用但是 afterCompletion 可以
// 例如说第一个 task 就是配置自动通过或者自动拒绝
if (ObjectUtil.notEqual(transactionStatus, TransactionSynchronization.STATUS_COMMITTED)) {
return;
}
// 特殊情况一人工审核审批人为空根据配置是否要自动通过自动拒绝
if (ObjectUtil.equal(approveType, BpmUserTaskApproveTypeEnum.USER.getType())) {
if (ObjectUtil.equal(assignEmptyHandlerType, BpmUserTaskAssignEmptyHandlerTypeEnum.APPROVE.getType())) {
SpringUtil.getBean(BpmTaskService.class).approveTask(null, new BpmTaskApproveReqVO()
.setId(task.getId()).setReason(BpmReasonEnum.ASSIGN_EMPTY_APPROVE.getReason()));
} else if (ObjectUtil.equal(assignEmptyHandlerType, BpmUserTaskAssignEmptyHandlerTypeEnum.REJECT.getType())) {
SpringUtil.getBean(BpmTaskService.class).rejectTask(null, new BpmTaskRejectReqVO()
.setId(task.getId()).setReason(BpmReasonEnum.ASSIGN_EMPTY_REJECT.getReason()));
}
// 特殊情况二自动审核审批类型为自动通过不通过
} else {
if (ObjectUtil.equal(approveType, BpmUserTaskApproveTypeEnum.AUTO_APPROVE.getType())) {
SpringUtil.getBean(BpmTaskService.class).approveTask(null, new BpmTaskApproveReqVO()
.setId(task.getId()).setReason(BpmReasonEnum.APPROVE_TYPE_AUTO_APPROVE.getReason()));
} else if (ObjectUtil.equal(approveType, BpmUserTaskApproveTypeEnum.AUTO_REJECT.getType())) {
SpringUtil.getBean(BpmTaskService.class).rejectTask(null, new BpmTaskRejectReqVO()
.setId(task.getId()).setReason(BpmReasonEnum.APPROVE_TYPE_AUTO_REJECT.getReason()));
}
}
}
});
}
/**