Browse Source

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

YunaiV 11 months ago
parent
commit
36a77251af

+ 1 - 1
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmProcessInstanceEventListener.java

@@ -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());
     }
 
 }

+ 3 - 4
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmTaskEventListener.java

@@ -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());
         });
     }
 

+ 2 - 4
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmTimerFiredEventListener.java

@@ -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) {

+ 8 - 2
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceService.java

@@ -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 it is too large
+ 0 - 0
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java


+ 56 - 52
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java

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

+ 197 - 194
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java

@@ -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);
-            }
-        }
-        return result;
-    }
+    // ========== Event 事件相关方法 ==========
 
     @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();
+    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 task 任务
-     * @return 根任务的父任务编号
+     * 1. 或签场景 + 审批通过:一个或签有多个审批时,如果 A 审批通过,其它或签 B、C 等任务会被 Flowable 自动删除,此时需要通过该方法更新状态为已取消
+     * 2. 审批不通过:在 {@link #rejectTask(Long, BpmTaskRejectReqVO)} 不通过时,对于加签的任务,不会被 Flowable 删除,此时需要通过该方法更新状态为已取消
      */
-    private String getTaskRootParentId(Task task) {
-        if (task == null || task.getParentTaskId() == null) {
-            return null;
+    @Override
+    public void processTaskCanceled(String taskId) {
+        Task task = getTask(taskId);
+        // 1. 可能只是活动,不是任务,所以查询不到
+        if (task == null) {
+            log.error("[updateTaskStatusWhenCanceled][taskId({}) 任务不存在]", taskId);
+            return;
         }
-        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;
+
+        // 2. 更新 task 状态 + 原因
+        Integer status = (Integer) task.getTaskLocalVariables().get(BpmConstants.TASK_VARIABLE_STATUS);
+        if (BpmTaskStatusEnum.isEndStatus(status)) {
+            log.error("[updateTaskStatusWhenCanceled][taskId({}) 处于结果({}),无需进行更新]", taskId, status);
+            return;
         }
-        throw new IllegalArgumentException(String.format("Task(%s) 层级过深,无法获取父节点编号", task.getId()));
+        updateTaskStatusAndReason(taskId, BpmTaskStatusEnum.CANCEL.getStatus(), BpmReasonEnum.CANCEL_BY_SYSTEM.getReason());
+        // 补充说明:由于 Task 被删除成 HistoricTask 后,无法通过 taskService.addComment 添加理由,所以无法存储具体的取消理由
     }
 
     @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);
+    public void processTaskAssigned(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));
+                }
+            }
+
+        });
     }
 
 }

Some files were not shown because too many files changed in this diff