diff --git a/ruoyi-system/src/main/java/com/ruoyi/workflow/domain/vo/WfViewerVo.java b/ruoyi-system/src/main/java/com/ruoyi/workflow/domain/vo/WfViewerVo.java index 50364f65..5676d8e6 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/workflow/domain/vo/WfViewerVo.java +++ b/ruoyi-system/src/main/java/com/ruoyi/workflow/domain/vo/WfViewerVo.java @@ -6,7 +6,7 @@ import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; -import java.util.List; +import java.util.Set; /** * 任务追踪视图对象 @@ -24,10 +24,20 @@ public class WfViewerVo { /** * 获取流程实例的历史节点(去重) */ - private List finishedTaskList; + private Set finishedTaskSet; + + /** + * 已完成 + */ + private Set finishedSequenceFlowSet; /** * 获取流程实例当前正在待办的节点(去重) */ - private List unfinishedTaskList; + private Set unfinishedTaskSet; + + /** + * 已拒绝 + */ + private Set rejectedTaskSet; } diff --git a/ruoyi-system/src/main/java/com/ruoyi/workflow/service/impl/WfTaskServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/workflow/service/impl/WfTaskServiceImpl.java index c53354db..bce733c9 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/workflow/service/impl/WfTaskServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/workflow/service/impl/WfTaskServiceImpl.java @@ -1,6 +1,8 @@ package com.ruoyi.workflow.service.impl; +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.collection.ListUtil; import cn.hutool.core.util.ObjectUtil; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.google.common.collect.Lists; @@ -20,14 +22,14 @@ import com.ruoyi.flowable.flow.FindNextNodeUtil; import com.ruoyi.flowable.flow.FlowableUtils; import com.ruoyi.system.service.ISysRoleService; import com.ruoyi.system.service.ISysUserService; +import com.ruoyi.workflow.domain.bo.WfTaskBo; import com.ruoyi.workflow.domain.dto.WfCommentDto; import com.ruoyi.workflow.domain.dto.WfNextDto; -import com.ruoyi.workflow.domain.vo.WfTaskVo; -import com.ruoyi.workflow.domain.bo.WfTaskBo; -import com.ruoyi.workflow.domain.vo.WfViewerVo; import com.ruoyi.workflow.domain.vo.WfFormVo; -import com.ruoyi.workflow.service.IWfTaskService; +import com.ruoyi.workflow.domain.vo.WfTaskVo; +import com.ruoyi.workflow.domain.vo.WfViewerVo; import com.ruoyi.workflow.service.IWfDeployFormService; +import com.ruoyi.workflow.service.IWfTaskService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; @@ -816,16 +818,79 @@ public class WfTaskServiceImpl extends FlowServiceFactory implements IWfTaskServ // 构建查询条件 HistoricActivityInstanceQuery query = historyService.createHistoricActivityInstanceQuery() .processInstanceId(procInsId); - // 获取流程实例已完成的节点 - List finishedTaskList = query.finished().list() - .stream().distinct().map(HistoricActivityInstance::getActivityId) - .collect(Collectors.toList()); - // 获取流程实例正在待办的节点 - List unfinishedTaskList = query.unfinished().list() - .stream().distinct().map(HistoricActivityInstance::getActivityId) - .collect(Collectors.toList()); - // 构建视图类 - return new WfViewerVo(finishedTaskList, unfinishedTaskList); + List allActivityInstanceList = query.list(); + if (CollUtil.isEmpty(allActivityInstanceList)) { + return new WfViewerVo(); + } + // 获取流程发布Id信息 + String processDefinitionId = allActivityInstanceList.get(0).getProcessDefinitionId(); + BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId); + if (ObjectUtil.isNull(bpmnModel)) { + throw new ServiceException("流程模型不存在"); + } + Map> sequenceElementMap = new HashMap<>(); + Map sequenceFlowMap = new HashMap<>(); + Collection flowElements = bpmnModel.getMainProcess().getFlowElements(); + for (FlowElement flowElement : flowElements) { + if (flowElement instanceof SequenceFlow) { + SequenceFlow sequenceFlow = (SequenceFlow) flowElement; + String sourceRef = sequenceFlow.getSourceRef(); + String targetRef = sequenceFlow.getTargetRef(); + List targetRefList = sequenceElementMap.get(sourceRef); + if (CollUtil.isEmpty(targetRefList)) { + sequenceElementMap.put(sourceRef, ListUtil.toList(targetRef)); + } else { + targetRefList.add(targetRef); + } + sequenceFlowMap.put(sourceRef + targetRef, sequenceFlow.getId()); + } + } + // 查询所有已完成的元素 + List finishedElementList = allActivityInstanceList.stream() + .filter(item -> ObjectUtil.isNotNull(item.getEndTime())).collect(Collectors.toList()); + // 所有已完成的连线 + Set finishedSequenceFlowSet = new HashSet<>(); + // 所有已完成的任务节点 + Set finishedTaskSet = new HashSet<>(); + finishedElementList.forEach(item -> { + if ("sequenceFlow".equals(item.getActivityType())) { + finishedSequenceFlowSet.add(item.getActivityId()); + } else { + finishedTaskSet.add(item.getActivityId()); + } + }); + // 查询所有未结束的节点 + Set unfinishedTaskSet = allActivityInstanceList.stream() + .filter(item -> ObjectUtil.isNull(item.getEndTime())) + .map(HistoricActivityInstance::getActivityId) + .collect(Collectors.toSet()); + + Set rejectedTaskSet = new LinkedHashSet<>(); + Set sourceTaskSet = unfinishedTaskSet; + while (true) { + Set nextIdSet = new HashSet<>(); + for (String previousId : sourceTaskSet) { + List nextIdList = sequenceElementMap.get(previousId); + if (CollUtil.isEmpty(nextIdList)) { + continue; + } + for (String childId : nextIdList) { + String rejectedSequenceFlow = sequenceFlowMap.get(previousId + childId); + if (finishedTaskSet.contains(childId)) { + nextIdSet.add(childId); + if (finishedSequenceFlowSet.contains(rejectedSequenceFlow)) { + nextIdSet.add(sequenceFlowMap.get(previousId + childId)); + } + } + } + } + if (CollUtil.isEmpty(nextIdSet)) { + break; + } + rejectedTaskSet.addAll(nextIdSet); + sourceTaskSet = nextIdSet; + } + return new WfViewerVo(finishedTaskSet, finishedSequenceFlowSet, unfinishedTaskSet, rejectedTaskSet); } /** diff --git a/ruoyi-ui/src/components/ProcessViewer/index.vue b/ruoyi-ui/src/components/ProcessViewer/index.vue index 89df2d9b..8fdd0a16 100644 --- a/ruoyi-ui/src/components/ProcessViewer/index.vue +++ b/ruoyi-ui/src/components/ProcessViewer/index.vue @@ -1,8 +1,8 @@