瀏覽代碼

bpm:简化获得可回退节点的实现

YunaiV 1 年之前
父節點
當前提交
0b649fd3e1

+ 4 - 6
yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/core/util/ModelUtils.java

@@ -1,13 +1,12 @@
 package cn.iocoder.yudao.framework.flowable.core.util;
 
-import cn.hutool.core.util.ObjectUtil;
-import cn.hutool.core.util.StrUtil;
-import org.flowable.bpmn.converter.BpmnXMLConverter;
 import org.flowable.bpmn.model.Process;
 import org.flowable.bpmn.model.*;
-import org.flowable.common.engine.impl.util.io.StringStreamSource;
 
-import java.util.*;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
 
 /**
  * 流程模型转操作工具类
@@ -56,7 +55,6 @@ public class ModelUtils {
         return process.getFlowElement(flowElementId);
     }
 
-
     /**
      * 找到 source 节点之前的所有用户任务节点
      *

+ 4 - 3
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/ErrorCodeConstants.java

@@ -47,9 +47,10 @@ public interface ErrorCodeConstants {
     ErrorCode TASK_COMPLETE_FAIL_ASSIGN_NOT_SELF = new ErrorCode(1_009_005_001, "审批任务失败,原因:该任务的审批人不是你");
     ErrorCode TASK_NOT_EXISTS = new ErrorCode(1_009_005_002, "流程任务不存在");
     ErrorCode TASK_IS_PENDING = new ErrorCode(1_009_005_003, "当前任务处于挂起状态,不能操作");
-    ErrorCode TASK_SOURCE_TARGET_ERROR = new ErrorCode(1_009_005_004, "目标节点是在并行网关上或非同一路线上,不可跳转");
-    ErrorCode TASK_TARGET_NODE_NOT_EXISTS = new ErrorCode(1_009_005_005, " 目标节点不存在");
-    ErrorCode TASK_RETURN_FAIL = new ErrorCode(1_009_005_006, "回退任务失败,选择回退的节点没有需要回滚的任务!请重新选择其他任务节点");
+    ErrorCode TASK_TARGET_NODE_NOT_EXISTS = new ErrorCode(1_009_005_004, " 目标节点不存在");
+    ErrorCode TASK_RETURN_FAIL_NO_RETURN_TASK = new ErrorCode(1_009_005_005, "回退任务失败,选择回退的节点没有需要回滚的任务!请重新选择其他任务节点");
+    ErrorCode TASK_RETURN_FAIL_SOURCE_TARGET_ERROR = new ErrorCode(1_009_005_006, "回退任务失败,目标节点是在并行网关上或非同一路线上,不可跳转");
+
     // ========== 流程任务分配规则 1-009-006-000 ==========
     ErrorCode TASK_ASSIGN_RULE_EXISTS = new ErrorCode(1_009_006_000, "流程({}) 的任务({}) 已经存在分配规则");
     ErrorCode TASK_ASSIGN_RULE_NOT_EXISTS = new ErrorCode(1_009_006_001, "流程任务分配规则不存在");

+ 2 - 2
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskReturnReqVO.java

@@ -14,10 +14,10 @@ public class BpmTaskReturnReqVO {
     private String id;
 
     @Schema(description = "回退到的任务 Key", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
-    @NotEmpty(message = "回退到的任务Key不能为空")
+    @NotEmpty(message = "回退到的任务 Key 不能为空")
     private String targetDefinitionKey;
 
-    @Schema(description = "回退意见", example = "")
+    @Schema(description = "回退意见", example = "我就是想驳回")
     private String reason;
 
 }

+ 2 - 4
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskSimpleRespVO.java

@@ -3,10 +3,7 @@ package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 
-/**
- *
- */
-@Schema(description = "管理后台 - 流程任务的 可回退的节点 Response VO")
+@Schema(description = "管理后台 - 流程任务的精简 Response VO")
 @Data
 public class BpmTaskSimpleRespVO {
 
@@ -15,4 +12,5 @@ public class BpmTaskSimpleRespVO {
 
     @Schema(description = "任务名词", requiredMode = Schema.RequiredMode.REQUIRED, example = "经理审批")
     private String name;
+
 }

+ 1 - 2
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java

@@ -140,8 +140,7 @@ public interface BpmTaskConvert {
         return reqDTO;
     }
 
-    @Mapping(source = "taskDefinitionKey", target = "id")
-    default List<BpmTaskSimpleRespVO> convertList(List<FlowElement> elementList) {
+    default List<BpmTaskSimpleRespVO> convertList(List<? extends FlowElement> elementList) {
         return CollectionUtils.convertList(elementList, element -> new BpmTaskSimpleRespVO()
                 .setName(element.getName())
                 .setDefinitionKey(element.getId()));

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

@@ -125,7 +125,7 @@ public interface BpmTaskService {
     /**
      * 获取当前任务的可回退的流程集合
      *
-     * @param taskId 当前的任务ID
+     * @param taskId 当前的任务 ID
      * @return 可以回退的节点列表
      */
     List<BpmTaskSimpleRespVO> getReturnTaskList(String taskId);

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

@@ -327,49 +327,25 @@ public class BpmTaskServiceImpl implements BpmTaskService {
 
     @Override
     public List<BpmTaskSimpleRespVO> getReturnTaskList(String taskId) {
-        // 当前任务 task
+        // 1. 校验当前任务 task 存在
         Task task = getTask(taskId);
-        if (null == task) {
+        if (task == null) {
             throw exception(TASK_NOT_EXISTS);
         }
-        // 根据流程定义获取流程模型信息
         BpmnModel bpmnModel = bpmModelService.getBpmnModelByDefinitionId(task.getProcessDefinitionId());
-        // 查询该任务的前置任务节点的key集合
-        Set<String> historyTaksDefinitionKeySet = getPreTaskByCurrentTask(task, bpmnModel);
-        if (CollUtil.isEmpty(historyTaksDefinitionKeySet)) {
-            return Collections.emptyList();
-        }
-        // 获取当前任务节点元素
         FlowElement source = ModelUtils.getFlowElementById(bpmnModel, task.getTaskDefinitionKey());
-        List<FlowElement> elementList = new ArrayList<>();
-        for (String activityId : historyTaksDefinitionKeySet) {
-            FlowElement target = ModelUtils.getFlowElementById(bpmnModel, activityId);
-            //非 串行和子流程则加入返回节点 elementList
-            boolean isSequential = ModelUtils.isSequentialReachable(source, target, new HashSet<>());
-            if (isSequential) {
-                elementList.add(target);
-            }
+        if (source == null) {
+            throw exception(TASK_NOT_EXISTS);
         }
-        return BpmTaskConvert.INSTANCE.convertList(elementList);
-    }
 
-    /**
-     * 查询当前流程实例符合条件可回退的 taskDefinitionKey 集合
-     *
-     * @param task      当前任务
-     * @param bpmnModel 当前流程定义对应的流程模型
-     * @return 符合条件的已去重的 taskDefinitionKey集合
-     */
-    private Set<String> getPreTaskByCurrentTask(Task task, BpmnModel bpmnModel) {
-        // 获取当前任务节点元素
-        FlowElement source = ModelUtils.getFlowElementById(bpmnModel, task.getTaskDefinitionKey());
-        //拿到当前任务节点的前置节点集合
-        List<UserTask> preUserTaskList = ModelUtils.getPreUserTaskList(source, null, null);
-        //需要保证这些节点都是在该source节点之前的
-        if (CollUtil.isNotEmpty(preUserTaskList)) {
-            return convertSet(preUserTaskList, UserTask::getId);
+        // 2.1 查询该任务的前置任务节点的 key 集合
+        List<UserTask> previousUserList = ModelUtils.getPreUserTaskList(source, null, null);
+        if (CollUtil.isEmpty(previousUserList)) {
+            return Collections.emptyList();
         }
-        return Collections.emptySet();
+        // 2.2 过滤:只有串行可到达的节点,才可以回退。类似非串行、子流程无法退回
+        previousUserList.removeIf(userTask -> ModelUtils.isSequentialReachable(source, userTask, null));
+        return BpmTaskConvert.INSTANCE.convertList(previousUserList);
     }
 
     @Transactional(rollbackFor = Exception.class)
@@ -426,7 +402,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
         // 从当前节点向前扫描,判断当前节点与目标节点是否属于串行,若目标节点是在并行网关上或非同一路线上,不可跳转
         boolean isSequential = ModelUtils.isSequentialReachable(source, target, new HashSet<>());
         if (!isSequential) {
-            throw exception(TASK_SOURCE_TARGET_ERROR);
+            throw exception(TASK_RETURN_FAIL_SOURCE_TARGET_ERROR);
         }
         return target;
     }
@@ -455,7 +431,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
             }
         }));
         if (CollUtil.isEmpty(currentTaskIds)) {
-            throw exception(TASK_RETURN_FAIL);
+            throw exception(TASK_RETURN_FAIL_NO_RETURN_TASK);
         }
         // 设置回退意见
         for (String currentTaskId : currentTaskIds) {