【代码优化】工作流:BpmTaskService、BpmProcessInstanceService 区分读方法、写、event 方法的区域,提升可阅读性

This commit is contained in:
YunaiV
2024-08-12 09:03:49 +08:00
parent 32804d3e0b
commit 36a77251af
7 changed files with 282 additions and 272 deletions

View File

@ -34,7 +34,7 @@ public class BpmProcessInstanceEventListener extends AbstractFlowableEngineEvent
@Override @Override
protected void processCompleted(FlowableEngineEntityEvent event) { protected void processCompleted(FlowableEngineEntityEvent event) {
processInstanceService.updateProcessInstanceWhenCompleted((ProcessInstance)event.getEntity()); processInstanceService.processProcessInstanceCompleted((ProcessInstance)event.getEntity());
} }
} }

View File

@ -48,17 +48,16 @@ public class BpmTaskEventListener extends AbstractFlowableEngineEventListener {
@Override @Override
protected void taskCreated(FlowableEngineEntityEvent event) { protected void taskCreated(FlowableEngineEntityEvent event) {
taskService.updateTaskStatusWhenCreated((Task) event.getEntity()); taskService.processTaskCreated((Task) event.getEntity());
} }
@Override @Override
protected void taskAssigned(FlowableEngineEntityEvent event) { protected void taskAssigned(FlowableEngineEntityEvent event) {
taskService.updateTaskExtAssign((Task) event.getEntity()); taskService.processTaskAssigned((Task) event.getEntity());
} }
@Override @Override
protected void activityCancelled(FlowableActivityCancelledEvent event) { protected void activityCancelled(FlowableActivityCancelledEvent event) {
// TODO @jason如果用户主动取消可能需要考虑这个
List<HistoricActivityInstance> activityList = activityService.getHistoricActivityListByExecutionId(event.getExecutionId()); List<HistoricActivityInstance> activityList = activityService.getHistoricActivityListByExecutionId(event.getExecutionId());
if (CollUtil.isEmpty(activityList)) { if (CollUtil.isEmpty(activityList)) {
log.error("[activityCancelled][使用 executionId({}) 查找不到对应的活动实例]", event.getExecutionId()); log.error("[activityCancelled][使用 executionId({}) 查找不到对应的活动实例]", event.getExecutionId());
@ -69,7 +68,7 @@ public class BpmTaskEventListener extends AbstractFlowableEngineEventListener {
if (StrUtil.isEmpty(activity.getTaskId())) { if (StrUtil.isEmpty(activity.getTaskId())) {
return; return;
} }
taskService.updateTaskStatusWhenCanceled(activity.getTaskId()); taskService.processTaskCanceled(activity.getTaskId());
}); });
} }

View File

@ -42,7 +42,6 @@ public class BpmTimerFiredEventListener extends AbstractFlowableEngineEventListe
@Resource @Resource
@Lazy // 延迟加载,避免循环依赖 @Lazy // 延迟加载,避免循环依赖
private BpmModelService bpmModelService; private BpmModelService bpmModelService;
@Resource @Resource
@Lazy // 延迟加载,避免循环依赖 @Lazy // 延迟加载,避免循环依赖
private BpmTaskService bpmTaskService; private BpmTaskService bpmTaskService;
@ -81,8 +80,7 @@ public class BpmTimerFiredEventListener extends AbstractFlowableEngineEventListe
BpmUserTaskTimeoutActionEnum userTaskTimeoutAction = BpmUserTaskTimeoutActionEnum.actionOf(timeoutAction); BpmUserTaskTimeoutActionEnum userTaskTimeoutAction = BpmUserTaskTimeoutActionEnum.actionOf(timeoutAction);
if (userTaskTimeoutAction != null) { if (userTaskTimeoutAction != null) {
// 查询超时未处理的任务 TODO 加签的情况会不会有问题 ??? // 查询超时未处理的任务 TODO 加签的情况会不会有问题 ???
List<Task> taskList = bpmTaskService.getRunningTaskListByProcessInstanceId(processInstanceId, true, List<Task> taskList = bpmTaskService.getRunningTaskListByProcessInstanceId(processInstanceId, true, taskDefKey);
null, taskDefKey);
taskList.forEach(task -> { taskList.forEach(task -> {
// 自动提醒 // 自动提醒
if (userTaskTimeoutAction == BpmUserTaskTimeoutActionEnum.REMINDER) { if (userTaskTimeoutAction == BpmUserTaskTimeoutActionEnum.REMINDER) {

View File

@ -22,6 +22,8 @@ import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.
*/ */
public interface BpmProcessInstanceService { public interface BpmProcessInstanceService {
// ========== Query 查询相关方法 ==========
/** /**
* 获得流程实例 * 获得流程实例
* *
@ -74,6 +76,8 @@ public interface BpmProcessInstanceService {
return convertMap(getHistoricProcessInstances(ids), HistoricProcessInstance::getId); return convertMap(getHistoricProcessInstances(ids), HistoricProcessInstance::getId);
} }
// ========== Update 写入相关方法 ==========
/** /**
* 获得流程实例的分页 * 获得流程实例的分页
* *
@ -126,11 +130,13 @@ public interface BpmProcessInstanceService {
*/ */
void updateProcessInstanceReject(ProcessInstance processInstance, String reason); void updateProcessInstanceReject(ProcessInstance processInstance, String reason);
// ========== Event 事件相关方法 ==========
/** /**
* 处理 ProcessInstance 完成审批通过、不通过、取消 * 处理 ProcessInstance 完成事件,例如说:审批通过、不通过、取消
* *
* @param instance 流程任务 * @param instance 流程任务
*/ */
void updateProcessInstanceWhenCompleted(ProcessInstance instance); void processProcessInstanceCompleted(ProcessInstance instance);
} }

View File

@ -20,6 +20,8 @@ import java.util.Map;
*/ */
public interface BpmTaskService { public interface BpmTaskService {
// ========== Query 查询相关方法 ==========
/** /**
* 获得待办的流程任务分页 * 获得待办的流程任务分页
* *
@ -74,6 +76,51 @@ public interface BpmTaskService {
*/ */
List<HistoricTaskInstance> getTaskListByProcessInstanceId(String processInstanceId); List<HistoricTaskInstance> getTaskListByProcessInstanceId(String processInstanceId);
/**
* 获取任务
*
* @param id 任务编号
* @return 任务
*/
Task getTask(String id);
/**
* 根据条件查询正在进行中的任务
*
* @param processInstanceId 流程实例编号,不允许为空
* @param assigned 是否分配了审批人,允许空
* @param taskDefineKey 任务定义 Key允许空
*/
List<Task> getRunningTaskListByProcessInstanceId(String processInstanceId,
Boolean assigned,
String taskDefineKey);
/**
* 获取当前任务的可回退的 UserTask 集合
*
* @param id 当前的任务 ID
* @return 可以回退的节点列表
*/
List<UserTask> getUserTaskListByReturn(String id);
/**
* 获取指定任务的子任务列表
*
* @param parentTaskId 父任务ID
* @return 子任务列表
*/
List<Task> getTaskListByParentTaskId(String parentTaskId);
/**
* 通过任务 ID查询任务名 Map
*
* @param taskIds 任务 ID
* @return 任务 ID 与名字的 Map
*/
Map<String, String> getTaskNameByTaskIds(Collection<String> taskIds);
// ========== Update 写入相关方法 ==========
/** /**
* 通过任务 * 通过任务
* *
@ -105,56 +152,6 @@ public interface BpmTaskService {
*/ */
void moveTaskToEnd(String processInstanceId); void moveTaskToEnd(String processInstanceId);
/**
* 更新 Task 状态,在创建时
*
* @param task 任务实体
*/
void updateTaskStatusWhenCreated(Task task);
/**
* 更新 Task 状态,在取消时
*
* @param taskId 任务的编号
*/
void updateTaskStatusWhenCanceled(String taskId);
/**
* 更新 Task 拓展记录,并发送通知
*
* @param task 任务实体
*/
void updateTaskExtAssign(Task task);
/**
* 获取任务
*
* @param id 任务编号
* @return 任务
*/
Task getTask(String id);
/**
* 根据条件查询正在进行中的任务
*
* @param processInstanceId 流程实例编号,不允许为空
* @param assigned 是否分配了审批人,允许空
* @param executionId execution Id允许空
* @param taskDefineKey 任务定义 Key允许空
*/
List<Task> getRunningTaskListByProcessInstanceId(String processInstanceId,
Boolean assigned,
String executionId,
String taskDefineKey);
/**
* 获取当前任务的可回退的 UserTask 集合
*
* @param id 当前的任务 ID
* @return 可以回退的节点列表
*/
List<UserTask> getUserTaskListByReturn(String id);
/** /**
* 将任务回退到指定的 targetDefinitionKey 位置 * 将任务回退到指定的 targetDefinitionKey 位置
* *
@ -187,20 +184,27 @@ public interface BpmTaskService {
*/ */
void deleteSignTask(Long userId, BpmTaskSignDeleteReqVO reqVO); void deleteSignTask(Long userId, BpmTaskSignDeleteReqVO reqVO);
/** // ========== Event 事件相关方法 ==========
* 获取指定任务的子任务列表
*
* @param parentTaskId 父任务ID
* @return 子任务列表
*/
List<Task> getTaskListByParentTaskId(String parentTaskId);
/** /**
* 通过任务 ID查询任务名 Map * 处理 Task 创建事件,目前是更新它的状态为审批中
* *
* @param taskIds 任务 ID * @param task 任务实体
* @return 任务 ID 与名字的 Map
*/ */
Map<String, String> getTaskNameByTaskIds(Collection<String> taskIds); void processTaskCreated(Task task);
/**
* 处理 Task 取消事件,目前是更新它的状态为已取消
*
* @param taskId 任务的编号
*/
void processTaskCanceled(String taskId);
/**
* 处理 Task 设置审批人事件,目前是发送审批消息
*
* @param task 任务实体
*/
void processTaskAssigned(Task task);
} }

View File

@ -84,6 +84,8 @@ public class BpmTaskServiceImpl implements BpmTaskService {
@Resource @Resource
private AdminUserApi adminUserApi; private AdminUserApi adminUserApi;
// ========== Query 查询相关方法 ==========
@Override @Override
public PageResult<Task> getTaskTodoPage(Long userId, BpmTaskPageReqVO pageVO) { public PageResult<Task> getTaskTodoPage(Long userId, BpmTaskPageReqVO pageVO) {
TaskQuery taskQuery = taskService.createTaskQuery() TaskQuery taskQuery = taskService.createTaskQuery()
@ -172,6 +174,156 @@ public class BpmTaskServiceImpl implements BpmTaskService {
return tasks; return tasks;
} }
/**
* 校验任务是否存在,并且是否是分配给自己的任务
*
* @param userId 用户 id
* @param taskId task id
*/
private Task validateTask(Long userId, String taskId) {
Task task = validateTaskExist(taskId);
if (!Objects.equals(userId, NumberUtils.parseLong(task.getAssignee()))) {
throw exception(TASK_OPERATE_FAIL_ASSIGN_NOT_SELF);
}
return task;
}
private Task validateTaskExist(String id) {
Task task = getTask(id);
if (task == null) {
throw exception(TASK_NOT_EXISTS);
}
return task;
}
@Override
public Task getTask(String id) {
return taskService.createTaskQuery().taskId(id).includeTaskLocalVariables().singleResult();
}
@Override
public List<Task> getRunningTaskListByProcessInstanceId(String processInstanceId, Boolean assigned, String defineKey) {
Assert.notNull(processInstanceId, "processInstanceId 不能为空");
TaskQuery taskQuery = taskService.createTaskQuery().processInstanceId(processInstanceId).active()
.includeTaskLocalVariables();
if (BooleanUtil.isTrue(assigned)) {
taskQuery.taskAssigned();
} else if (BooleanUtil.isFalse(assigned)) {
taskQuery.taskUnassigned();
}
if (StrUtil.isNotEmpty(defineKey)) {
taskQuery.taskDefinitionKey(defineKey);
}
return taskQuery.list();
}
private HistoricTaskInstance getHistoricTask(String id) {
return historyService.createHistoricTaskInstanceQuery().taskId(id).includeTaskLocalVariables().singleResult();
}
@Override
public List<UserTask> getUserTaskListByReturn(String id) {
// 1.1 校验当前任务 task 存在
Task task = validateTaskExist(id);
// 1.2 根据流程定义获取流程模型信息
BpmnModel bpmnModel = bpmModelService.getBpmnModelByDefinitionId(task.getProcessDefinitionId());
FlowElement source = BpmnModelUtils.getFlowElementById(bpmnModel, task.getTaskDefinitionKey());
if (source == null) {
throw exception(TASK_NOT_EXISTS);
}
// 2.1 查询该任务的前置任务节点的 key 集合
List<UserTask> previousUserList = BpmnModelUtils.getPreviousUserTaskList(source, null, null);
if (CollUtil.isEmpty(previousUserList)) {
return Collections.emptyList();
}
// 2.2 过滤:只有串行可到达的节点,才可以回退。类似非串行、子流程无法退回
previousUserList.removeIf(userTask -> !BpmnModelUtils.isSequentialReachable(source, userTask, null));
return previousUserList;
}
/**
* 获得所有子任务列表
*
* @param parentTask 父任务
* @return 所有子任务列表
*/
private List<Task> getAllChildTaskList(Task parentTask) {
List<Task> result = new ArrayList<>();
// 1. 递归获取子级
Stack<Task> stack = new Stack<>();
stack.push(parentTask);
// 2. 递归遍历
for (int i = 0; i < Short.MAX_VALUE; i++) {
if (stack.isEmpty()) {
break;
}
// 2.1 获取子任务们
Task task = stack.pop();
List<Task> childTaskList = getTaskListByParentTaskId(task.getId());
// 2.2 如果非空,则添加到 stack 进一步递归
if (CollUtil.isNotEmpty(childTaskList)) {
stack.addAll(childTaskList);
result.addAll(childTaskList);
}
}
return result;
}
@Override
public List<Task> getTaskListByParentTaskId(String parentTaskId) {
String tableName = managementService.getTableName(TaskEntity.class);
// taskService.createTaskQuery() 没有 parentId 参数,所以写 sql 查询
String sql = "select ID_,NAME_,OWNER_,ASSIGNEE_ from " + tableName + " where PARENT_TASK_ID_=#{parentTaskId}";
return taskService.createNativeTaskQuery().sql(sql).parameter("parentTaskId", parentTaskId).list();
}
/**
* 获取子任务个数
*
* @param parentTaskId 父任务 ID
* @return 剩余子任务个数
*/
private Long getTaskCountByParentTaskId(String parentTaskId) {
String tableName = managementService.getTableName(TaskEntity.class);
String sql = "SELECT COUNT(1) from " + tableName + " WHERE PARENT_TASK_ID_=#{parentTaskId}";
return taskService.createNativeTaskQuery().sql(sql).parameter("parentTaskId", parentTaskId).count();
}
/**
* 获得任务根任务的父任务编号
*
* @param task 任务
* @return 根任务的父任务编号
*/
private String getTaskRootParentId(Task task) {
if (task == null || task.getParentTaskId() == null) {
return null;
}
for (int i = 0; i < Short.MAX_VALUE; i++) {
Task parentTask = getTask(task.getParentTaskId());
if (parentTask == null) {
return null;
}
if (parentTask.getParentTaskId() == null) {
return parentTask.getId();
}
task = parentTask;
}
throw new IllegalArgumentException(String.format("Task(%s) 层级过深,无法获取父节点编号", task.getId()));
}
@Override
public Map<String, String> getTaskNameByTaskIds(Collection<String> taskIds) {
if (CollUtil.isEmpty(taskIds)) {
return Collections.emptyMap();
}
List<Task> tasks = taskService.createTaskQuery().taskIds(taskIds).list();
return convertMap(tasks, Task::getId, Task::getName);
}
// ========== Update 写入相关方法 ==========
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void approveTask(Long userId, @Valid BpmTaskApproveReqVO reqVO) { public void approveTask(Long userId, @Valid BpmTaskApproveReqVO reqVO) {
@ -382,132 +534,6 @@ public class BpmTaskServiceImpl implements BpmTaskService {
taskService.setVariableLocal(id, BpmConstants.TASK_VARIABLE_REASON, reason); taskService.setVariableLocal(id, BpmConstants.TASK_VARIABLE_REASON, reason);
} }
/**
* 校验任务是否存在,并且是否是分配给自己的任务
*
* @param userId 用户 id
* @param taskId task id
*/
private Task validateTask(Long userId, String taskId) {
Task task = validateTaskExist(taskId);
if (!Objects.equals(userId, NumberUtils.parseLong(task.getAssignee()))) {
throw exception(TASK_OPERATE_FAIL_ASSIGN_NOT_SELF);
}
return task;
}
@Override
public void updateTaskStatusWhenCreated(Task task) {
Integer status = (Integer) task.getTaskLocalVariables().get(BpmConstants.TASK_VARIABLE_STATUS);
if (status != null) {
log.error("[updateTaskStatusWhenCreated][taskId({}) 已经有状态({})]", task.getId(), status);
return;
}
updateTaskStatus(task.getId(), BpmTaskStatusEnum.RUNNING.getStatus());
}
/**
* 重要补充说明:该方法目前主要有两个情况会调用到:
*
* 1. 或签场景 + 审批通过:一个或签有多个审批时,如果 A 审批通过,其它或签 B、C 等任务会被 Flowable 自动删除,此时需要通过该方法更新状态为已取消
* 2. 审批不通过:在 {@link #rejectTask(Long, BpmTaskRejectReqVO)} 不通过时,对于加签的任务,不会被 Flowable 删除,此时需要通过该方法更新状态为已取消
*/
@Override
public void updateTaskStatusWhenCanceled(String taskId) {
Task task = getTask(taskId);
// 1. 可能只是活动,不是任务,所以查询不到
if (task == null) {
log.error("[updateTaskStatusWhenCanceled][taskId({}) 任务不存在]", taskId);
return;
}
// 2. 更新 task 状态 + 原因
Integer status = (Integer) task.getTaskLocalVariables().get(BpmConstants.TASK_VARIABLE_STATUS);
if (BpmTaskStatusEnum.isEndStatus(status)) {
log.error("[updateTaskStatusWhenCanceled][taskId({}) 处于结果({}),无需进行更新]", taskId, status);
return;
}
updateTaskStatusAndReason(taskId, BpmTaskStatusEnum.CANCEL.getStatus(), BpmReasonEnum.CANCEL_BY_SYSTEM.getReason());
// 补充说明:由于 Task 被删除成 HistoricTask 后,无法通过 taskService.addComment 添加理由,所以无法存储具体的取消理由
}
@Override
public void updateTaskExtAssign(Task task) {
// 发送通知。在事务提交时,批量执行操作,所以直接查询会无法查询到 ProcessInstance所以这里是通过监听事务的提交来实现。
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
@Override
public void afterCommit() {
if (StrUtil.isEmpty(task.getAssignee())) {
return;
}
ProcessInstance processInstance = processInstanceService.getProcessInstance(task.getProcessInstanceId());
if (processInstance != null) {
AdminUserRespDTO startUser = adminUserApi.getUser(Long.valueOf(processInstance.getStartUserId()));
messageService.sendMessageWhenTaskAssigned(BpmTaskConvert.INSTANCE.convert(processInstance, startUser, task));
}
}
});
}
private Task validateTaskExist(String id) {
Task task = getTask(id);
if (task == null) {
throw exception(TASK_NOT_EXISTS);
}
return task;
}
@Override
public Task getTask(String id) {
return taskService.createTaskQuery().taskId(id).includeTaskLocalVariables().singleResult();
}
@Override
public List<Task> getRunningTaskListByProcessInstanceId(String processInstanceId, Boolean assigned, String executionId, String defineKey) {
Assert.notNull(processInstanceId, "processInstanceId 不能为空");
TaskQuery taskQuery = taskService.createTaskQuery().processInstanceId(processInstanceId).active()
.includeTaskLocalVariables();
if (BooleanUtil.isTrue(assigned)) {
taskQuery.taskAssigned();
} else if (BooleanUtil.isFalse(assigned)) {
taskQuery.taskUnassigned();
}
if (StrUtil.isNotEmpty(executionId)) {
taskQuery.executionId(executionId);
}
if (StrUtil.isNotEmpty(defineKey)) {
taskQuery.taskDefinitionKey(defineKey);
}
return taskQuery.list();
}
private HistoricTaskInstance getHistoricTask(String id) {
return historyService.createHistoricTaskInstanceQuery().taskId(id).includeTaskLocalVariables().singleResult();
}
@Override
public List<UserTask> getUserTaskListByReturn(String id) {
// 1.1 校验当前任务 task 存在
Task task = validateTaskExist(id);
// 1.2 根据流程定义获取流程模型信息
BpmnModel bpmnModel = bpmModelService.getBpmnModelByDefinitionId(task.getProcessDefinitionId());
FlowElement source = BpmnModelUtils.getFlowElementById(bpmnModel, task.getTaskDefinitionKey());
if (source == null) {
throw exception(TASK_NOT_EXISTS);
}
// 2.1 查询该任务的前置任务节点的 key 集合
List<UserTask> previousUserList = BpmnModelUtils.getPreviousUserTaskList(source, null, null);
if (CollUtil.isEmpty(previousUserList)) {
return Collections.emptyList();
}
// 2.2 过滤:只有串行可到达的节点,才可以回退。类似非串行、子流程无法退回
previousUserList.removeIf(userTask -> !BpmnModelUtils.isSequentialReachable(source, userTask, null));
return previousUserList;
}
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void returnTask(Long userId, BpmTaskReturnReqVO reqVO) { public void returnTask(Long userId, BpmTaskReturnReqVO reqVO) {
@ -645,7 +671,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
@Override @Override
public void moveTaskToEnd(String processInstanceId) { public void moveTaskToEnd(String processInstanceId) {
List<Task> taskList = getRunningTaskListByProcessInstanceId(processInstanceId, null, null, null); List<Task> taskList = getRunningTaskListByProcessInstanceId(processInstanceId, null, null);
if (CollUtil.isEmpty(taskList)) { if (CollUtil.isEmpty(taskList)) {
return; return;
} }
@ -658,7 +684,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
if (BpmTaskStatusEnum.isEndStatus(otherTaskStatus)) { if (BpmTaskStatusEnum.isEndStatus(otherTaskStatus)) {
return; return;
} }
updateTaskStatusWhenCanceled(task.getId()); processTaskCanceled(task.getId());
}); });
// 2. 终止流程 // 2. 终止流程
@ -842,84 +868,61 @@ public class BpmTaskServiceImpl implements BpmTaskService {
return task; return task;
} }
// ========== Event 事件相关方法 ==========
@Override
public void processTaskCreated(Task task) {
Integer status = (Integer) task.getTaskLocalVariables().get(BpmConstants.TASK_VARIABLE_STATUS);
if (status != null) {
log.error("[updateTaskStatusWhenCreated][taskId({}) 已经有状态({})]", task.getId(), status);
return;
}
updateTaskStatus(task.getId(), BpmTaskStatusEnum.RUNNING.getStatus());
}
/** /**
* 获得所有子任务列表 * 重要补充说明:该方法目前主要有两个情况会调用到:
* *
* @param parentTask 父任务 * 1. 或签场景 + 审批通过:一个或签有多个审批时,如果 A 审批通过,其它或签 B、C 等任务会被 Flowable 自动删除,此时需要通过该方法更新状态为已取消
* @return 所有子任务列表 * 2. 审批不通过:在 {@link #rejectTask(Long, BpmTaskRejectReqVO)} 不通过时,对于加签的任务,不会被 Flowable 删除,此时需要通过该方法更新状态为已取消
*/ */
private List<Task> getAllChildTaskList(Task parentTask) { @Override
List<Task> result = new ArrayList<>(); public void processTaskCanceled(String taskId) {
// 1. 递归获取子级 Task task = getTask(taskId);
Stack<Task> stack = new Stack<>(); // 1. 可能只是活动,不是任务,所以查询不到
stack.push(parentTask); if (task == null) {
// 2. 递归遍历 log.error("[updateTaskStatusWhenCanceled][taskId({}) 任务不存在]", taskId);
for (int i = 0; i < Short.MAX_VALUE; i++) { return;
if (stack.isEmpty()) {
break;
} }
// 2.1 获取子任务们
Task task = stack.pop(); // 2. 更新 task 状态 + 原因
List<Task> childTaskList = getTaskListByParentTaskId(task.getId()); Integer status = (Integer) task.getTaskLocalVariables().get(BpmConstants.TASK_VARIABLE_STATUS);
// 2.2 如果非空,则添加到 stack 进一步递归 if (BpmTaskStatusEnum.isEndStatus(status)) {
if (CollUtil.isNotEmpty(childTaskList)) { log.error("[updateTaskStatusWhenCanceled][taskId({}) 处于结果({}),无需进行更新]", taskId, status);
stack.addAll(childTaskList); return;
result.addAll(childTaskList);
} }
} updateTaskStatusAndReason(taskId, BpmTaskStatusEnum.CANCEL.getStatus(), BpmReasonEnum.CANCEL_BY_SYSTEM.getReason());
return result; // 补充说明:由于 Task 被删除成 HistoricTask 后,无法通过 taskService.addComment 添加理由,所以无法存储具体的取消理由
} }
@Override @Override
public List<Task> getTaskListByParentTaskId(String parentTaskId) { public void processTaskAssigned(Task task) {
String tableName = managementService.getTableName(TaskEntity.class); // 发送通知。在事务提交时,批量执行操作,所以直接查询会无法查询到 ProcessInstance所以这里是通过监听事务的提交来实现。
// taskService.createTaskQuery() 没有 parentId 参数,所以写 sql 查询 TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
String sql = "select ID_,NAME_,OWNER_,ASSIGNEE_ from " + tableName + " where PARENT_TASK_ID_=#{parentTaskId}";
return taskService.createNativeTaskQuery().sql(sql).parameter("parentTaskId", parentTaskId).list();
}
/**
* 获取子任务个数
*
* @param parentTaskId 父任务 ID
* @return 剩余子任务个数
*/
private Long getTaskCountByParentTaskId(String parentTaskId) {
String tableName = managementService.getTableName(TaskEntity.class);
String sql = "SELECT COUNT(1) from " + tableName + " WHERE PARENT_TASK_ID_=#{parentTaskId}";
return taskService.createNativeTaskQuery().sql(sql).parameter("parentTaskId", parentTaskId).count();
}
/**
* 获得任务根任务的父任务编号
*
* @param task 任务
* @return 根任务的父任务编号
*/
private String getTaskRootParentId(Task task) {
if (task == null || task.getParentTaskId() == null) {
return null;
}
for (int i = 0; i < Short.MAX_VALUE; i++) {
Task parentTask = getTask(task.getParentTaskId());
if (parentTask == null) {
return null;
}
if (parentTask.getParentTaskId() == null) {
return parentTask.getId();
}
task = parentTask;
}
throw new IllegalArgumentException(String.format("Task(%s) 层级过深,无法获取父节点编号", task.getId()));
}
@Override @Override
public Map<String, String> getTaskNameByTaskIds(Collection<String> taskIds) { public void afterCommit() {
if (CollUtil.isEmpty(taskIds)) { if (StrUtil.isEmpty(task.getAssignee())) {
return Collections.emptyMap(); return;
} }
List<Task> tasks = taskService.createTaskQuery().taskIds(taskIds).list(); ProcessInstance processInstance = processInstanceService.getProcessInstance(task.getProcessInstanceId());
return convertMap(tasks, Task::getId, Task::getName); if (processInstance != null) {
AdminUserRespDTO startUser = adminUserApi.getUser(Long.valueOf(processInstance.getStartUserId()));
messageService.sendMessageWhenTaskAssigned(BpmTaskConvert.INSTANCE.convert(processInstance, startUser, task));
}
}
});
} }
} }