Ver Fonte

feat:新增获取下一个执行的流程节点接口

smallNorthLee há 5 meses atrás
pai
commit
1b08e6828f

+ 11 - 0
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceController.java

@@ -178,4 +178,15 @@ public class BpmProcessInstanceController {
     public CommonResult<BpmProcessInstanceBpmnModelViewRespVO> getProcessInstanceBpmnModelView(@RequestParam(value = "id") String id) {
         return success(processInstanceService.getProcessInstanceBpmnModelView(id));
     }
+
+    @GetMapping("/get-next-flow-nodes")
+    @Operation(summary = "获取下一个执行的流程节点")
+    @PreAuthorize("@ss.hasPermission('bpm:process-instance:query')")
+    @SuppressWarnings("unchecked")
+    public CommonResult<List<BpmApprovalDetailRespVO.ActivityNode>> getNextFlowNodes(@Valid BpmApprovalDetailReqVO reqVO) {
+        if (StrUtil.isNotEmpty(reqVO.getProcessVariablesStr())) {
+            reqVO.setProcessVariables(JsonUtils.parseObject(reqVO.getProcessVariablesStr(), Map.class));
+        }
+        return success(processInstanceService.getNextFlowNodes(getLoginUserId(), reqVO));
+    }
 }

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

@@ -97,6 +97,15 @@ public interface BpmProcessInstanceService {
      */
     BpmApprovalDetailRespVO getApprovalDetail(Long loginUserId, @Valid BpmApprovalDetailReqVO reqVO);
 
+    /**
+     * 获取下一个执行节点信息。
+     *
+     * @param loginUserId 登录人的用户编号
+     * @param reqVO 请求信息
+     * @return 下一个执行节点信息
+     */
+    List<BpmApprovalDetailRespVO.ActivityNode> getNextFlowNodes(Long loginUserId, @Valid BpmApprovalDetailReqVO reqVO);
+
     /**
      * 获取流程实例的 BPMN 模型视图
      *
@@ -173,4 +182,5 @@ public interface BpmProcessInstanceService {
      * @param instance 流程任务
      */
     void processProcessInstanceCompleted(ProcessInstance instance);
+
 }

+ 45 - 0
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java

@@ -11,6 +11,7 @@ import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.date.DateUtils;
 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
+import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
 import cn.iocoder.yudao.framework.common.util.object.PageUtils;
 import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
@@ -55,6 +56,7 @@ import org.flowable.engine.history.HistoricProcessInstanceQuery;
 import org.flowable.engine.repository.ProcessDefinition;
 import org.flowable.engine.runtime.ProcessInstance;
 import org.flowable.engine.runtime.ProcessInstanceBuilder;
+import org.flowable.task.api.Task;
 import org.flowable.task.api.history.HistoricTaskInstance;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
@@ -225,6 +227,49 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
                 processInstanceStatus, endActivityNodes, runActivityNodes, simulateActivityNodes, todoTask);
     }
 
+    @Override
+    public List<ActivityNode> getNextFlowNodes(Long loginUserId, BpmApprovalDetailReqVO reqVO) {
+        // 1 校验任务存在
+        Task task = taskService.getTask(reqVO.getTaskId());
+        if (task == null) {
+            throw exception(TASK_NOT_EXISTS);
+        }
+        // 2 校验任务是否由当前用户审批
+        if (StrUtil.isNotBlank(task.getAssignee())
+                && ObjectUtil.notEqual(loginUserId, NumberUtils.parseLong(task.getAssignee()))) {
+            throw exception(TASK_OPERATE_FAIL_ASSIGN_NOT_SELF);
+        }
+        // 3 校验流程实例存在
+        ProcessInstance instance = getProcessInstance(task.getProcessInstanceId());
+        if (instance == null) {
+            throw exception(PROCESS_INSTANCE_NOT_EXISTS);
+        }
+        // 4 获取 BpmnModel
+        BpmnModel bpmnModel = processDefinitionService.getProcessDefinitionBpmnModel(task.getProcessDefinitionId());
+        if (bpmnModel == null) {
+            return null;
+        }
+        // 5. 获取当前任务节点的信息
+        FlowElement flowElement = bpmnModel.getFlowElement(task.getTaskDefinitionKey());
+        List<FlowNode> nextFlowNodes = BpmnModelUtils.getNextFlowNodes(flowElement, bpmnModel, reqVO.getProcessVariables());
+        return convertList(nextFlowNodes, nodes -> {
+            FlowElement flowNode = BpmnModelUtils.getFlowElementById(bpmnModel, nodes.getId());
+            ActivityNode activityNode = new ActivityNode().setId(nodes.getId()).setName(nodes.getName())
+                    .setNodeType(START_USER_NODE_ID.equals(nodes.getId())
+                            ? BpmSimpleModelNodeTypeEnum.START_USER_NODE.getType()
+                            : ObjUtil.defaultIfNull(parseNodeType(flowNode), // 目的:解决“办理节点”的识别
+                            BpmSimpleModelNodeTypeEnum.APPROVE_NODE.getType()))
+                    .setStatus(FlowableUtils.getTaskStatus(task))
+                    .setCandidateStrategy(BpmnModelUtils.parseCandidateStrategy(flowNode));
+
+            // 如果是取消状态,则跳过
+            if (BpmTaskStatusEnum.isCancelStatus(activityNode.getStatus())) {
+                return null;
+            }
+            return activityNode;
+        });
+    }
+
     @Override
     @SuppressWarnings("unchecked")
     public PageResult<HistoricProcessInstance> getProcessInstancePage(Long userId,