|
|
@@ -27,6 +27,7 @@ import com.qqflow.engine.domain.flow.mapper.ApprovalTaskMapper;
|
|
|
import com.qqflow.engine.domain.flow.mapper.AttachmentMapper;
|
|
|
import com.qqflow.engine.domain.flow.mapper.ProcessDefinitionMapper;
|
|
|
import com.qqflow.engine.domain.flow.mapper.ProcessInstanceMapper;
|
|
|
+import com.qqflow.engine.domain.flow.model.FlowEdge;
|
|
|
import com.qqflow.engine.domain.flow.model.FlowModel;
|
|
|
import com.qqflow.engine.domain.flow.model.FlowNode;
|
|
|
import com.qqflow.engine.domain.flow.po.ApprovalRecord;
|
|
|
@@ -50,8 +51,12 @@ import java.time.LocalDate;
|
|
|
import java.time.LocalDateTime;
|
|
|
import java.time.format.DateTimeFormatter;
|
|
|
import java.util.ArrayList;
|
|
|
+import java.util.ArrayDeque;
|
|
|
import java.util.Collections;
|
|
|
+import java.util.Deque;
|
|
|
import java.util.HashMap;
|
|
|
+import java.util.HashSet;
|
|
|
+import java.util.LinkedHashMap;
|
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
|
import java.util.Objects;
|
|
|
@@ -110,9 +115,9 @@ public class ProcessInstanceServiceImpl implements ProcessInstanceService {
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- public PageResult<ProcessInstanceDTO> list(Long applicantId, Integer status, String definitionName, String currentNodeName, String applicantName, Integer pageNum, Integer pageSize) {
|
|
|
+ public PageResult<ProcessInstanceDTO> list(Long applicantId, Integer status, Long processDefinitionId, String definitionName, String currentNodeName, String applicantName, Integer pageNum, Integer pageSize) {
|
|
|
Page<ProcessInstance> page = new Page<>(pageNum, pageSize);
|
|
|
- this.processInstanceMapper.selectInstanceList(page, applicantId, status, definitionName, currentNodeName, applicantName, null);
|
|
|
+ this.processInstanceMapper.selectInstanceList(page, applicantId, status, definitionName, currentNodeName, applicantName, processDefinitionId);
|
|
|
List<ProcessInstanceDTO> records = this.enrichInstanceDtos(page.getRecords());
|
|
|
if (currentNodeName != null && !currentNodeName.isBlank()) {
|
|
|
records = records.stream()
|
|
|
@@ -214,11 +219,12 @@ public class ProcessInstanceServiceImpl implements ProcessInstanceService {
|
|
|
String currentNodeId = instance.getCurrentNodeId();
|
|
|
Integer instanceStatus = instance.getStatus();
|
|
|
|
|
|
- // 构建节点进度列表
|
|
|
+ // 构建节点进度列表(按流程拓扑顺序排序)
|
|
|
List<NodeProgressDTO> nodeProgressList = new ArrayList<>();
|
|
|
int remainingCount = 0;
|
|
|
|
|
|
- for (FlowNode node : model.getNodes()) {
|
|
|
+ List<FlowNode> sortedNodes = this.sortByFlowOrder(model.getNodes(), model.getEdges());
|
|
|
+ for (FlowNode node : sortedNodes) {
|
|
|
String type = node.getType();
|
|
|
if (NodeType.START.getCode().equals(type) || NodeType.END.getCode().equals(type)
|
|
|
|| NodeType.CONDITION.getCode().equals(type) || NodeType.CC.getCode().equals(type)) {
|
|
|
@@ -771,4 +777,53 @@ public class ProcessInstanceServiceImpl implements ProcessInstanceService {
|
|
|
}
|
|
|
return null;
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 按流程拓扑顺序排序节点:从 START 节点出发 BFS,沿 edges 遍历。
|
|
|
+ * 不可达节点(不应出现)追加在末尾。
|
|
|
+ */
|
|
|
+ private List<FlowNode> sortByFlowOrder(List<FlowNode> nodes, List<FlowEdge> edges) {
|
|
|
+ if (nodes == null || nodes.isEmpty()) return new ArrayList<>();
|
|
|
+ List<FlowEdge> safeEdges = edges != null ? edges : Collections.emptyList();
|
|
|
+
|
|
|
+ // 构建邻接表:sourceId → [targetIds]
|
|
|
+ Map<String, List<String>> adj = new LinkedHashMap<>();
|
|
|
+ for (FlowEdge edge : safeEdges) {
|
|
|
+ adj.computeIfAbsent(edge.getSourceNodeId(), k -> new ArrayList<>()).add(edge.getTargetNodeId());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 节点 ID → 节点映射
|
|
|
+ Map<String, FlowNode> nodeMap = nodes.stream()
|
|
|
+ .collect(Collectors.toMap(FlowNode::getId, n -> n, (a, b) -> a));
|
|
|
+
|
|
|
+ // 查找 START 节点
|
|
|
+ FlowNode startNode = nodes.stream()
|
|
|
+ .filter(n -> NodeType.START.getCode().equals(n.getType()))
|
|
|
+ .findFirst().orElse(null);
|
|
|
+ if (startNode == null) return new ArrayList<>(nodes);
|
|
|
+
|
|
|
+ // BFS
|
|
|
+ List<FlowNode> sorted = new ArrayList<>();
|
|
|
+ Set<String> visited = new HashSet<>();
|
|
|
+ Deque<String> queue = new ArrayDeque<>();
|
|
|
+ queue.add(startNode.getId());
|
|
|
+
|
|
|
+ while (!queue.isEmpty()) {
|
|
|
+ String id = queue.poll();
|
|
|
+ if (!visited.add(id)) continue;
|
|
|
+ FlowNode node = nodeMap.get(id);
|
|
|
+ if (node != null) sorted.add(node);
|
|
|
+
|
|
|
+ for (String nextId : adj.getOrDefault(id, Collections.emptyList())) {
|
|
|
+ if (!visited.contains(nextId)) queue.add(nextId);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 追加不可达节点
|
|
|
+ for (FlowNode node : nodes) {
|
|
|
+ if (!visited.contains(node.getId())) sorted.add(node);
|
|
|
+ }
|
|
|
+
|
|
|
+ return sorted;
|
|
|
+ }
|
|
|
}
|