mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2025-02-17 09:40:34 +08:00
【代码优化】工作流:BpmTaskService、BpmProcessInstanceService 区分读方法、写、event 方法的区域,提升可阅读性
This commit is contained in:
parent
32804d3e0b
commit
36a77251af
@ -34,7 +34,7 @@ public class BpmProcessInstanceEventListener extends AbstractFlowableEngineEvent
|
||||
|
||||
@Override
|
||||
protected void processCompleted(FlowableEngineEntityEvent event) {
|
||||
processInstanceService.updateProcessInstanceWhenCompleted((ProcessInstance)event.getEntity());
|
||||
processInstanceService.processProcessInstanceCompleted((ProcessInstance)event.getEntity());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -48,17 +48,16 @@ public class BpmTaskEventListener extends AbstractFlowableEngineEventListener {
|
||||
|
||||
@Override
|
||||
protected void taskCreated(FlowableEngineEntityEvent event) {
|
||||
taskService.updateTaskStatusWhenCreated((Task) event.getEntity());
|
||||
taskService.processTaskCreated((Task) event.getEntity());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void taskAssigned(FlowableEngineEntityEvent event) {
|
||||
taskService.updateTaskExtAssign((Task) event.getEntity());
|
||||
taskService.processTaskAssigned((Task) event.getEntity());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void activityCancelled(FlowableActivityCancelledEvent event) {
|
||||
// TODO @jason:如果用户主动取消,可能需要考虑这个
|
||||
List<HistoricActivityInstance> activityList = activityService.getHistoricActivityListByExecutionId(event.getExecutionId());
|
||||
if (CollUtil.isEmpty(activityList)) {
|
||||
log.error("[activityCancelled][使用 executionId({}) 查找不到对应的活动实例]", event.getExecutionId());
|
||||
@ -69,7 +68,7 @@ public class BpmTaskEventListener extends AbstractFlowableEngineEventListener {
|
||||
if (StrUtil.isEmpty(activity.getTaskId())) {
|
||||
return;
|
||||
}
|
||||
taskService.updateTaskStatusWhenCanceled(activity.getTaskId());
|
||||
taskService.processTaskCanceled(activity.getTaskId());
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,6 @@ public class BpmTimerFiredEventListener extends AbstractFlowableEngineEventListe
|
||||
@Resource
|
||||
@Lazy // 延迟加载,避免循环依赖
|
||||
private BpmModelService bpmModelService;
|
||||
|
||||
@Resource
|
||||
@Lazy // 延迟加载,避免循环依赖
|
||||
private BpmTaskService bpmTaskService;
|
||||
@ -67,7 +66,7 @@ public class BpmTimerFiredEventListener extends AbstractFlowableEngineEventListe
|
||||
// 如果是定时器边界事件
|
||||
if (element instanceof BoundaryEvent) {
|
||||
BoundaryEvent boundaryEvent = (BoundaryEvent) element;
|
||||
String boundaryEventType = BpmnModelUtils.parseBoundaryEventExtensionElement(boundaryEvent, BpmnModelConstants.BOUNDARY_EVENT_TYPE);
|
||||
String boundaryEventType = BpmnModelUtils.parseBoundaryEventExtensionElement(boundaryEvent, BpmnModelConstants.BOUNDARY_EVENT_TYPE);
|
||||
BpmBoundaryEventType bpmTimerBoundaryEventType = BpmBoundaryEventType.typeOf(NumberUtils.parseInt(boundaryEventType));
|
||||
// 类型为用户任务超时未处理的情况
|
||||
if (bpmTimerBoundaryEventType == BpmBoundaryEventType.USER_TASK_TIMEOUT) {
|
||||
@ -81,8 +80,7 @@ public class BpmTimerFiredEventListener extends AbstractFlowableEngineEventListe
|
||||
BpmUserTaskTimeoutActionEnum userTaskTimeoutAction = BpmUserTaskTimeoutActionEnum.actionOf(timeoutAction);
|
||||
if (userTaskTimeoutAction != null) {
|
||||
// 查询超时未处理的任务 TODO 加签的情况会不会有问题 ???
|
||||
List<Task> taskList = bpmTaskService.getRunningTaskListByProcessInstanceId(processInstanceId, true,
|
||||
null, taskDefKey);
|
||||
List<Task> taskList = bpmTaskService.getRunningTaskListByProcessInstanceId(processInstanceId, true, taskDefKey);
|
||||
taskList.forEach(task -> {
|
||||
// 自动提醒
|
||||
if (userTaskTimeoutAction == BpmUserTaskTimeoutActionEnum.REMINDER) {
|
||||
|
@ -22,6 +22,8 @@ import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.
|
||||
*/
|
||||
public interface BpmProcessInstanceService {
|
||||
|
||||
// ========== Query 查询相关方法 ==========
|
||||
|
||||
/**
|
||||
* 获得流程实例
|
||||
*
|
||||
@ -74,6 +76,8 @@ public interface BpmProcessInstanceService {
|
||||
return convertMap(getHistoricProcessInstances(ids), HistoricProcessInstance::getId);
|
||||
}
|
||||
|
||||
// ========== Update 写入相关方法 ==========
|
||||
|
||||
/**
|
||||
* 获得流程实例的分页
|
||||
*
|
||||
@ -126,11 +130,13 @@ public interface BpmProcessInstanceService {
|
||||
*/
|
||||
void updateProcessInstanceReject(ProcessInstance processInstance, String reason);
|
||||
|
||||
// ========== Event 事件相关方法 ==========
|
||||
|
||||
/**
|
||||
* 处理 ProcessInstance 完成(审批通过、不通过、取消)
|
||||
* 处理 ProcessInstance 完成事件,例如说:审批通过、不通过、取消
|
||||
*
|
||||
* @param instance 流程任务
|
||||
*/
|
||||
void updateProcessInstanceWhenCompleted(ProcessInstance instance);
|
||||
void processProcessInstanceCompleted(ProcessInstance instance);
|
||||
|
||||
}
|
||||
|
File diff suppressed because one or more lines are too long
@ -20,6 +20,8 @@ import java.util.Map;
|
||||
*/
|
||||
public interface BpmTaskService {
|
||||
|
||||
// ========== Query 查询相关方法 ==========
|
||||
|
||||
/**
|
||||
* 获得待办的流程任务分页
|
||||
*
|
||||
@ -74,6 +76,51 @@ public interface BpmTaskService {
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* 更新 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 位置
|
||||
*
|
||||
@ -187,20 +184,27 @@ public interface BpmTaskService {
|
||||
*/
|
||||
void deleteSignTask(Long userId, BpmTaskSignDeleteReqVO reqVO);
|
||||
|
||||
/**
|
||||
* 获取指定任务的子任务列表
|
||||
*
|
||||
* @param parentTaskId 父任务ID
|
||||
* @return 子任务列表
|
||||
*/
|
||||
List<Task> getTaskListByParentTaskId(String parentTaskId);
|
||||
// ========== Event 事件相关方法 ==========
|
||||
|
||||
/**
|
||||
* 通过任务 ID,查询任务名 Map
|
||||
* 处理 Task 创建事件,目前是更新它的状态为审批中
|
||||
*
|
||||
* @param taskIds 任务 ID
|
||||
* @return 任务 ID 与名字的 Map
|
||||
* @param task 任务实体
|
||||
*/
|
||||
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);
|
||||
|
||||
}
|
||||
|
@ -84,6 +84,8 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
||||
@Resource
|
||||
private AdminUserApi adminUserApi;
|
||||
|
||||
// ========== Query 查询相关方法 ==========
|
||||
|
||||
@Override
|
||||
public PageResult<Task> getTaskTodoPage(Long userId, BpmTaskPageReqVO pageVO) {
|
||||
TaskQuery taskQuery = taskService.createTaskQuery()
|
||||
@ -172,6 +174,156 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
||||
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
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验任务是否存在,并且是否是分配给自己的任务
|
||||
*
|
||||
* @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
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void returnTask(Long userId, BpmTaskReturnReqVO reqVO) {
|
||||
@ -645,7 +671,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
||||
|
||||
@Override
|
||||
public void moveTaskToEnd(String processInstanceId) {
|
||||
List<Task> taskList = getRunningTaskListByProcessInstanceId(processInstanceId, null, null, null);
|
||||
List<Task> taskList = getRunningTaskListByProcessInstanceId(processInstanceId, null, null);
|
||||
if (CollUtil.isEmpty(taskList)) {
|
||||
return;
|
||||
}
|
||||
@ -658,7 +684,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
||||
if (BpmTaskStatusEnum.isEndStatus(otherTaskStatus)) {
|
||||
return;
|
||||
}
|
||||
updateTaskStatusWhenCanceled(task.getId());
|
||||
processTaskCanceled(task.getId());
|
||||
});
|
||||
|
||||
// 2. 终止流程
|
||||
@ -842,84 +868,61 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
||||
return task;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得所有子任务列表
|
||||
*
|
||||
* @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);
|
||||
}
|
||||
// ========== 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;
|
||||
}
|
||||
return result;
|
||||
updateTaskStatus(task.getId(), BpmTaskStatusEnum.RUNNING.getStatus());
|
||||
}
|
||||
|
||||
/**
|
||||
* 重要补充说明:该方法目前主要有两个情况会调用到:
|
||||
*
|
||||
* 1. 或签场景 + 审批通过:一个或签有多个审批时,如果 A 审批通过,其它或签 B、C 等任务会被 Flowable 自动删除,此时需要通过该方法更新状态为已取消
|
||||
* 2. 审批不通过:在 {@link #rejectTask(Long, BpmTaskRejectReqVO)} 不通过时,对于加签的任务,不会被 Flowable 删除,此时需要通过该方法更新状态为已取消
|
||||
*/
|
||||
@Override
|
||||
public void processTaskCanceled(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 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();
|
||||
}
|
||||
public void processTaskAssigned(Task task) {
|
||||
// 发送通知。在事务提交时,批量执行操作,所以直接查询会无法查询到 ProcessInstance,所以这里是通过监听事务的提交来实现。
|
||||
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
|
||||
|
||||
/**
|
||||
* 获取子任务个数
|
||||
*
|
||||
* @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;
|
||||
@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));
|
||||
}
|
||||
}
|
||||
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);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user