You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
114 lines
4.6 KiB
Java
114 lines
4.6 KiB
Java
package com.supervision.handler.graph;
|
|
|
|
import cn.hutool.core.collection.CollUtil;
|
|
import cn.hutool.core.util.ObjUtil;
|
|
import com.supervision.ngbatis.dao.CommonQueryDao;
|
|
import com.supervision.ngbatis.domain.tag.Condition;
|
|
import com.supervision.ngbatis.domain.tag.ProcessCondition;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import org.jgrapht.Graph;
|
|
import org.jgrapht.GraphPath;
|
|
import org.jgrapht.alg.shortestpath.AllDirectedPaths;
|
|
import org.jgrapht.graph.DefaultEdge;
|
|
import org.jgrapht.graph.builder.GraphTypeBuilder;
|
|
import org.springframework.stereotype.Component;
|
|
|
|
import javax.annotation.Resource;
|
|
import java.util.ArrayList;
|
|
import java.util.HashSet;
|
|
import java.util.List;
|
|
import java.util.Set;
|
|
|
|
/**
|
|
* 寻找判断节点的链条
|
|
*/
|
|
@Slf4j
|
|
@Component
|
|
public class FindConditionPathHandler {
|
|
|
|
@Resource
|
|
private CommonQueryDao commonQueryDao;
|
|
|
|
/**
|
|
* 根据某个办理条件节点,寻找所有路径,以用来判断是否符合
|
|
* @param itemLeafId 叶子节点的ID
|
|
* @return 所有路径
|
|
*/
|
|
public List<List<Condition>> findConditionPath(String itemLeafId) {
|
|
// 首先根据叶子节点,找到条件节点
|
|
ProcessCondition conditionVertexByLeafVertex = commonQueryDao.findConditionVertexByLeafVertex(itemLeafId);
|
|
if (ObjUtil.isEmpty(conditionVertexByLeafVertex)){
|
|
return new ArrayList<>();
|
|
}
|
|
// 构建一个图,用这个图来找属性结构
|
|
Graph<Condition, DefaultEdge> jGraph = buildJGraph();
|
|
// 定位终点的vertexId
|
|
Set<Condition> finalVertexSet = new HashSet<>();
|
|
// 从条件节点processConditionVid开始探索下一级节点列表,使用GO语句
|
|
List<Condition> sourceConditionList = commonQueryDao.findNextConditionByConditionEdge(conditionVertexByLeafVertex.getId());
|
|
// 如果没有任何绑定的条件节点,
|
|
if (CollUtil.isEmpty(sourceConditionList)) {
|
|
// TODO 如果没有任何绑定的条件节点,这里咋整?暂定返回一个空的集合
|
|
return new ArrayList<>();
|
|
}
|
|
for (Condition sourceVertex : sourceConditionList) {
|
|
jGraph.addVertex(sourceVertex);
|
|
}
|
|
// 下面开始使用递归,开始持续的找下级节点(递归增加次数限制,最多100次)
|
|
int recursionCount = 0;
|
|
recursionFindNext(sourceConditionList, jGraph, finalVertexSet, recursionCount);
|
|
// 根据图去找所有的路径
|
|
return findAllPath(jGraph, new HashSet<>(sourceConditionList), finalVertexSet);
|
|
|
|
}
|
|
|
|
private void recursionFindNext(List<Condition> sourceIdList, Graph<Condition, DefaultEdge> jGraph, Set<Condition> finalVertexSet, int recursionCount) {
|
|
// 防止死循环出现无限递归
|
|
if (recursionCount > 100) {
|
|
return;
|
|
}
|
|
recursionCount++;
|
|
for (Condition source : sourceIdList) {
|
|
List<Condition> nextVertxList = commonQueryDao.findNextConditionByConditionEdge(source.getId());
|
|
if (CollUtil.isNotEmpty(nextVertxList)) {
|
|
for (Condition nextVertex : nextVertxList) {
|
|
jGraph.addVertex(nextVertex);
|
|
jGraph.addEdge(nextVertex, nextVertex);
|
|
}
|
|
recursionFindNext(nextVertxList, jGraph, finalVertexSet, recursionCount);
|
|
} else {
|
|
finalVertexSet.add(source);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
private Graph<Condition, DefaultEdge> buildJGraph() {
|
|
// 创建一个树形结构
|
|
return GraphTypeBuilder
|
|
.directed()
|
|
.allowingMultipleEdges(false)
|
|
.allowingSelfLoops(false)
|
|
.edgeClass(DefaultEdge.class)
|
|
.vertexClass(Condition.class)
|
|
.weighted(false)
|
|
.buildGraph();
|
|
}
|
|
|
|
private List<List<Condition>> findAllPath(Graph<Condition, DefaultEdge> graph, Set<Condition> sourceSet, Set<Condition> targetIdSet) {
|
|
// 使用深度优先遍历来获取所有路径
|
|
AllDirectedPaths<Condition, DefaultEdge> directedPaths = new AllDirectedPaths<>(graph);
|
|
// 根据一个起始点和终止节点,开始找所有的路径
|
|
List<GraphPath<Condition, DefaultEdge>> allPaths = directedPaths.getAllPaths(sourceSet, targetIdSet, true, 100);
|
|
// 将所有判断的路径汇聚起来
|
|
List<List<Condition>> paths = new ArrayList<>();
|
|
for (GraphPath<Condition, DefaultEdge> path : allPaths) {
|
|
List<Condition> vertexList = path.getVertexList();
|
|
if (CollUtil.isNotEmpty(vertexList)) {
|
|
paths.add(vertexList);
|
|
}
|
|
}
|
|
return paths;
|
|
}
|
|
}
|