接口新增,知识图谱
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
package com.solution.rule.domain.config;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* rule_item_task_type 批量查询行
|
||||
*/
|
||||
@Data
|
||||
public class RuleConfigTaskTypeRow implements Serializable {
|
||||
|
||||
private String ruleCode;
|
||||
|
||||
private String taskTypeCode;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.solution.rule.domain.config.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
@ApiModel("规则知识图谱边")
|
||||
public class RuleGraphEdgeVO implements Serializable {
|
||||
|
||||
@ApiModelProperty("边 id")
|
||||
private String id;
|
||||
|
||||
@ApiModelProperty("起点节点 id")
|
||||
private String source;
|
||||
|
||||
@ApiModelProperty("终点节点 id")
|
||||
private String target;
|
||||
|
||||
@ApiModelProperty("边类型")
|
||||
private String edgeType;
|
||||
|
||||
@ApiModelProperty("边上展示文案")
|
||||
private String label;
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.solution.rule.domain.config.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Data
|
||||
@ApiModel("规则知识图谱节点")
|
||||
public class RuleGraphNodeVO implements Serializable {
|
||||
|
||||
@ApiModelProperty("全局唯一节点 id")
|
||||
private String id;
|
||||
|
||||
@ApiModelProperty("展示标题")
|
||||
private String label;
|
||||
|
||||
@ApiModelProperty("节点类型:level/kind/module/rule/param/taskType")
|
||||
private String nodeType;
|
||||
|
||||
@ApiModelProperty("附加属性(如 ruleCode、paramKey、字典编码等)")
|
||||
private Map<String, Object> payload;
|
||||
|
||||
public Map<String, Object> safePayload() {
|
||||
if (payload == null) {
|
||||
payload = new HashMap<>();
|
||||
}
|
||||
return payload;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.solution.rule.domain.config.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@ApiModel("规则知识图谱数据")
|
||||
public class RuleGraphVO implements Serializable {
|
||||
|
||||
@ApiModelProperty("节点列表")
|
||||
private List<RuleGraphNodeVO> nodes;
|
||||
|
||||
@ApiModelProperty("边列表")
|
||||
private List<RuleGraphEdgeVO> edges;
|
||||
|
||||
public List<RuleGraphNodeVO> safeNodes() {
|
||||
if (nodes == null) {
|
||||
nodes = new ArrayList<>();
|
||||
}
|
||||
return nodes;
|
||||
}
|
||||
|
||||
public List<RuleGraphEdgeVO> safeEdges() {
|
||||
if (edges == null) {
|
||||
edges = new ArrayList<>();
|
||||
}
|
||||
return edges;
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package com.solution.rule.mapper;
|
||||
import com.solution.rule.domain.config.RuleConfig;
|
||||
import com.solution.rule.domain.config.RuleConfigParam;
|
||||
import com.solution.rule.domain.config.RuleConfigQuery;
|
||||
import com.solution.rule.domain.config.RuleConfigTaskTypeRow;
|
||||
import com.solution.rule.domain.config.RuleDictItem;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
@@ -24,12 +25,16 @@ public interface RuleConfigMapper {
|
||||
|
||||
List<RuleConfigParam> selectParamsByRuleCode(@Param("ruleCode") String ruleCode);
|
||||
|
||||
List<RuleConfigParam> selectParamsByRuleCodes(@Param("ruleCodes") List<String> ruleCodes);
|
||||
|
||||
int deleteParamsByRuleCodes(@Param("ruleCodes") String[] ruleCodes);
|
||||
|
||||
int insertParamsBatch(@Param("params") List<RuleConfigParam> params);
|
||||
|
||||
List<String> selectTaskTypesByRuleCode(@Param("ruleCode") String ruleCode);
|
||||
|
||||
List<RuleConfigTaskTypeRow> selectTaskTypesByRuleCodes(@Param("ruleCodes") List<String> ruleCodes);
|
||||
|
||||
int deleteTaskTypesByRuleCodes(@Param("ruleCodes") String[] ruleCodes);
|
||||
|
||||
int insertTaskTypesBatch(@Param("ruleCode") String ruleCode, @Param("taskTypes") List<String> taskTypes);
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.solution.rule.domain.config.RuleConfig;
|
||||
import com.solution.rule.domain.config.RuleConfigQuery;
|
||||
import com.solution.rule.domain.config.RuleDictItem;
|
||||
import com.solution.rule.domain.config.RuleParamMeta;
|
||||
import com.solution.rule.domain.config.vo.RuleGraphVO;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -25,4 +26,9 @@ public interface IRuleConfigService {
|
||||
Map<String, Object> loadEnabledGlobalParams();
|
||||
|
||||
List<RuleParamMeta> selectParamMetaList();
|
||||
|
||||
/**
|
||||
* 根据当前页规则主数据构建知识图谱(节点与边),参数与任务类型从库批量加载。
|
||||
*/
|
||||
RuleGraphVO buildKnowledgeGraph(List<RuleConfig> ruleConfigs);
|
||||
}
|
||||
|
||||
@@ -6,8 +6,12 @@ import com.solution.common.constant.ExceptionConstants;
|
||||
import com.solution.rule.domain.config.RuleConfig;
|
||||
import com.solution.rule.domain.config.RuleConfigParam;
|
||||
import com.solution.rule.domain.config.RuleConfigQuery;
|
||||
import com.solution.rule.domain.config.RuleConfigTaskTypeRow;
|
||||
import com.solution.rule.domain.config.RuleDictItem;
|
||||
import com.solution.rule.domain.config.RuleParamMeta;
|
||||
import com.solution.rule.domain.config.vo.RuleGraphEdgeVO;
|
||||
import com.solution.rule.domain.config.vo.RuleGraphNodeVO;
|
||||
import com.solution.rule.domain.config.vo.RuleGraphVO;
|
||||
import com.solution.rule.mapper.RuleConfigMapper;
|
||||
import com.solution.rule.service.IRuleConfigService;
|
||||
import com.solution.rule.service.RuleDrlSyncService;
|
||||
@@ -17,6 +21,7 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
public class RuleConfigServiceImpl implements IRuleConfigService {
|
||||
@@ -24,6 +29,18 @@ public class RuleConfigServiceImpl implements IRuleConfigService {
|
||||
private static final Pattern RULE_SLOT_KEYS = Pattern.compile("^(blueRuleKeywords|redRuleKeywords|ruleScore)_\\d+$");
|
||||
private static final boolean ALLOW_UNKNOWN_PARAM_KEY = false;
|
||||
|
||||
private static final Map<String, String> MODULE_LABELS;
|
||||
|
||||
static {
|
||||
Map<String, String> m = new LinkedHashMap<>();
|
||||
m.put("equipment", "装备匹配");
|
||||
m.put("target", "目标分配");
|
||||
m.put("position", "阵位部署");
|
||||
m.put("track", "航迹生成");
|
||||
m.put("group", "编组");
|
||||
MODULE_LABELS = Collections.unmodifiableMap(m);
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private RuleConfigMapper ruleConfigMapper;
|
||||
@Autowired
|
||||
@@ -119,6 +136,193 @@ public class RuleConfigServiceImpl implements IRuleConfigService {
|
||||
return new ArrayList<>(metaMap().values());
|
||||
}
|
||||
|
||||
@Override
|
||||
public RuleGraphVO buildKnowledgeGraph(List<RuleConfig> ruleConfigs) {
|
||||
RuleGraphVO graph = new RuleGraphVO();
|
||||
List<RuleGraphNodeVO> nodes = graph.safeNodes();
|
||||
List<RuleGraphEdgeVO> edges = graph.safeEdges();
|
||||
if (CollUtil.isEmpty(ruleConfigs)) {
|
||||
return graph;
|
||||
}
|
||||
List<String> ruleCodes = ruleConfigs.stream()
|
||||
.map(RuleConfig::getRuleCode)
|
||||
.filter(ObjectUtil::isNotEmpty)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
List<RuleConfigParam> allParams = ruleCodes.isEmpty()
|
||||
? Collections.emptyList()
|
||||
: ruleConfigMapper.selectParamsByRuleCodes(ruleCodes);
|
||||
List<RuleConfigTaskTypeRow> allTaskRows = ruleCodes.isEmpty()
|
||||
? Collections.emptyList()
|
||||
: ruleConfigMapper.selectTaskTypesByRuleCodes(ruleCodes);
|
||||
|
||||
Map<String, List<RuleConfigParam>> paramsByRule = allParams.stream()
|
||||
.filter(p -> p != null && ObjectUtil.isNotEmpty(p.getRuleCode()))
|
||||
.collect(Collectors.groupingBy(RuleConfigParam::getRuleCode, LinkedHashMap::new, Collectors.toList()));
|
||||
Map<String, List<String>> taskTypesByRule = new LinkedHashMap<>();
|
||||
for (RuleConfigTaskTypeRow row : allTaskRows) {
|
||||
if (row == null || ObjectUtil.isEmpty(row.getRuleCode()) || ObjectUtil.isEmpty(row.getTaskTypeCode())) {
|
||||
continue;
|
||||
}
|
||||
taskTypesByRule.computeIfAbsent(row.getRuleCode(), k -> new ArrayList<>()).add(row.getTaskTypeCode());
|
||||
}
|
||||
|
||||
List<RuleDictItem> levelDict = safeDict("level");
|
||||
List<RuleDictItem> kindDict = safeDict("kind");
|
||||
List<RuleDictItem> taskTypeDict = safeDict("task_type");
|
||||
|
||||
Map<String, RuleGraphNodeVO> nodeById = new LinkedHashMap<>();
|
||||
Set<String> edgeIds = new LinkedHashSet<>();
|
||||
|
||||
for (RuleConfig rule : ruleConfigs) {
|
||||
if (rule == null || ObjectUtil.isEmpty(rule.getRuleCode())) {
|
||||
continue;
|
||||
}
|
||||
String ruleCode = rule.getRuleCode();
|
||||
String levelCode = ObjectUtil.defaultIfBlank(rule.getLevelCode(), "unknown");
|
||||
String kindCode = ObjectUtil.defaultIfBlank(rule.getKindCode(), "unknown");
|
||||
String moduleCode = ObjectUtil.defaultIfBlank(rule.getModuleCode(), "unknown");
|
||||
|
||||
String levelId = "level:" + levelCode;
|
||||
Map<String, Object> levelPayload = new LinkedHashMap<>();
|
||||
levelPayload.put("dictType", "level");
|
||||
levelPayload.put("dictCode", levelCode);
|
||||
putNode(nodeById, levelId, node(levelId, dictLabel(levelDict, levelCode, levelCode), "level", levelPayload));
|
||||
|
||||
String kindId = "kind:" + levelCode + ":" + kindCode;
|
||||
Map<String, Object> kindPayload = new LinkedHashMap<>();
|
||||
kindPayload.put("levelCode", levelCode);
|
||||
kindPayload.put("kindCode", kindCode);
|
||||
putNode(nodeById, kindId, node(kindId, dictLabel(kindDict, kindCode, kindCode), "kind", kindPayload));
|
||||
|
||||
String moduleId = "module:" + moduleCode;
|
||||
String moduleLabel = MODULE_LABELS.getOrDefault(moduleCode, moduleCode);
|
||||
Map<String, Object> modulePayload = new LinkedHashMap<>();
|
||||
modulePayload.put("moduleCode", moduleCode);
|
||||
putNode(nodeById, moduleId, node(moduleId, moduleLabel, "module", modulePayload));
|
||||
|
||||
String ruleId = "rule:" + ruleCode;
|
||||
String ruleLabel = ObjectUtil.defaultIfBlank(rule.getRuleName(), ruleCode);
|
||||
Map<String, Object> rulePayload = new LinkedHashMap<>();
|
||||
rulePayload.put("ruleCode", ruleCode);
|
||||
rulePayload.put("priorityNo", rule.getPriorityNo());
|
||||
rulePayload.put("moduleCode", moduleCode);
|
||||
rulePayload.put("levelCode", levelCode);
|
||||
rulePayload.put("kindCode", kindCode);
|
||||
if (ObjectUtil.isNotEmpty(rule.getConditionExpr())) {
|
||||
rulePayload.put("conditionExpr", rule.getConditionExpr());
|
||||
}
|
||||
if (ObjectUtil.isNotEmpty(rule.getActionExpr())) {
|
||||
rulePayload.put("actionExpr", rule.getActionExpr());
|
||||
}
|
||||
RuleGraphNodeVO ruleNode = node(ruleId, ruleLabel, "rule", rulePayload);
|
||||
putNode(nodeById, ruleId, ruleNode);
|
||||
|
||||
addEdge(edges, edgeIds, "belongs_level:" + ruleCode, ruleId, levelId, "rule_belongs_level", null);
|
||||
addEdge(edges, edgeIds, "belongs_kind:" + ruleCode, ruleId, kindId, "rule_belongs_kind", null);
|
||||
addEdge(edges, edgeIds, "has_module:" + ruleCode, ruleId, moduleId, "rule_has_module", null);
|
||||
|
||||
List<RuleConfigParam> plist = paramsByRule.getOrDefault(ruleCode, Collections.emptyList());
|
||||
for (RuleConfigParam param : plist) {
|
||||
if (param == null || ObjectUtil.isEmpty(param.getParamKey())) {
|
||||
continue;
|
||||
}
|
||||
String pk = param.getParamKey();
|
||||
String paramId = "param:" + ruleCode + ":" + pk;
|
||||
String pLabel = ObjectUtil.defaultIfBlank(param.getParamName(), pk);
|
||||
Map<String, Object> paramPayload = new LinkedHashMap<>();
|
||||
paramPayload.put("ruleCode", ruleCode);
|
||||
paramPayload.put("paramKey", pk);
|
||||
paramPayload.put("paramVal", param.getParamVal());
|
||||
paramPayload.put("valType", param.getValType());
|
||||
RuleGraphNodeVO pNode = node(paramId, pLabel, "param", paramPayload);
|
||||
putNode(nodeById, paramId, pNode);
|
||||
addEdge(edges, edgeIds, "has_param:" + ruleCode + ":" + pk, ruleId, paramId, "rule_has_param", null);
|
||||
}
|
||||
|
||||
List<String> tlist = taskTypesByRule.getOrDefault(ruleCode, Collections.emptyList());
|
||||
for (String tt : tlist) {
|
||||
if (ObjectUtil.isEmpty(tt)) {
|
||||
continue;
|
||||
}
|
||||
String taskId = "task:" + tt;
|
||||
Map<String, Object> taskPayload = new LinkedHashMap<>();
|
||||
taskPayload.put("taskTypeCode", tt);
|
||||
putNode(nodeById, taskId, node(taskId, dictLabel(taskTypeDict, tt, tt), "taskType", taskPayload));
|
||||
addEdge(edges, edgeIds, "applies_task:" + ruleCode + ":" + tt, ruleId, taskId, "rule_applies_task", null);
|
||||
}
|
||||
}
|
||||
|
||||
Comparator<RuleConfig> byPriority = Comparator.comparing(RuleConfig::getPriorityNo,
|
||||
Comparator.nullsLast(Integer::compareTo));
|
||||
Map<String, List<RuleConfig>> execGroups = ruleConfigs.stream()
|
||||
.filter(r -> r != null && ObjectUtil.isNotEmpty(r.getRuleCode()))
|
||||
.collect(Collectors.groupingBy(
|
||||
r -> ObjectUtil.defaultIfBlank(r.getLevelCode(), "") + "\0" + ObjectUtil.defaultIfBlank(r.getModuleCode(), ""),
|
||||
LinkedHashMap::new,
|
||||
Collectors.toList()));
|
||||
for (List<RuleConfig> group : execGroups.values()) {
|
||||
List<RuleConfig> sorted = new ArrayList<>(group);
|
||||
sorted.sort(byPriority);
|
||||
for (int i = 0; i < sorted.size() - 1; i++) {
|
||||
String from = "rule:" + sorted.get(i).getRuleCode();
|
||||
String to = "rule:" + sorted.get(i + 1).getRuleCode();
|
||||
if (from.equals(to)) {
|
||||
continue;
|
||||
}
|
||||
addEdge(edges, edgeIds, "exec:" + sorted.get(i).getRuleCode() + "->" + sorted.get(i + 1).getRuleCode(),
|
||||
from, to, "rule_exec_before", "执行顺序");
|
||||
}
|
||||
}
|
||||
|
||||
nodes.addAll(nodeById.values());
|
||||
return graph;
|
||||
}
|
||||
|
||||
private List<RuleDictItem> safeDict(String dictType) {
|
||||
List<RuleDictItem> list = ruleConfigMapper.selectDictByType(dictType);
|
||||
return list != null ? list : Collections.emptyList();
|
||||
}
|
||||
|
||||
private static void putNode(Map<String, RuleGraphNodeVO> map, String id, RuleGraphNodeVO n) {
|
||||
map.putIfAbsent(id, n);
|
||||
}
|
||||
|
||||
private static RuleGraphNodeVO node(String id, String label, String nodeType, Map<String, Object> payload) {
|
||||
RuleGraphNodeVO n = new RuleGraphNodeVO();
|
||||
n.setId(id);
|
||||
n.setLabel(label);
|
||||
n.setNodeType(nodeType);
|
||||
n.setPayload(payload);
|
||||
return n;
|
||||
}
|
||||
|
||||
private static void addEdge(List<RuleGraphEdgeVO> edges, Set<String> edgeIds, String id,
|
||||
String source, String target, String edgeType, String label) {
|
||||
if (!edgeIds.add(id)) {
|
||||
return;
|
||||
}
|
||||
RuleGraphEdgeVO e = new RuleGraphEdgeVO();
|
||||
e.setId(id);
|
||||
e.setSource(source);
|
||||
e.setTarget(target);
|
||||
e.setEdgeType(edgeType);
|
||||
e.setLabel(label);
|
||||
edges.add(e);
|
||||
}
|
||||
|
||||
private static String dictLabel(List<RuleDictItem> dict, String code, String fallback) {
|
||||
if (CollUtil.isEmpty(dict) || ObjectUtil.isEmpty(code)) {
|
||||
return fallback;
|
||||
}
|
||||
for (RuleDictItem item : dict) {
|
||||
if (item != null && code.equals(item.getDictCode())) {
|
||||
return ObjectUtil.defaultIfBlank(item.getDictName(), fallback);
|
||||
}
|
||||
}
|
||||
return fallback;
|
||||
}
|
||||
|
||||
private void saveChildren(RuleConfig ruleConfig) {
|
||||
if (CollUtil.isNotEmpty(ruleConfig.getParams())) {
|
||||
Set<String> keys = new HashSet<>();
|
||||
|
||||
@@ -41,6 +41,11 @@
|
||||
<result property="remark" column="remark"/>
|
||||
</resultMap>
|
||||
|
||||
<resultMap id="RuleConfigTaskTypeRowMap" type="com.solution.rule.domain.config.RuleConfigTaskTypeRow">
|
||||
<result property="ruleCode" column="rule_code"/>
|
||||
<result property="taskTypeCode" column="task_type_code"/>
|
||||
</resultMap>
|
||||
|
||||
<select id="selectRuleConfigList" resultMap="RuleConfigMap">
|
||||
SELECT id, rule_code, rule_name, level_code, kind_code, module_code, priority_no,
|
||||
condition_expr, action_expr, version_no, enabled, remark, created_at, updated_at
|
||||
@@ -123,6 +128,23 @@
|
||||
ORDER BY sort_no ASC, id ASC
|
||||
</select>
|
||||
|
||||
<select id="selectParamsByRuleCodes" resultMap="RuleConfigParamMap">
|
||||
SELECT rule_code, param_key, param_val, val_type, param_name, sort_no, enabled, remark
|
||||
FROM rule_item_param
|
||||
<where>
|
||||
<if test="ruleCodes != null and ruleCodes.size() > 0">
|
||||
rule_code IN
|
||||
<foreach collection="ruleCodes" item="c" open="(" separator="," close=")">
|
||||
#{c}
|
||||
</foreach>
|
||||
</if>
|
||||
<if test="ruleCodes == null or ruleCodes.size() == 0">
|
||||
1 = 0
|
||||
</if>
|
||||
</where>
|
||||
ORDER BY rule_code ASC, sort_no ASC, id ASC
|
||||
</select>
|
||||
|
||||
<delete id="deleteParamsByRuleCodes">
|
||||
DELETE FROM rule_item_param
|
||||
WHERE rule_code IN
|
||||
@@ -148,6 +170,23 @@
|
||||
ORDER BY id ASC
|
||||
</select>
|
||||
|
||||
<select id="selectTaskTypesByRuleCodes" resultMap="RuleConfigTaskTypeRowMap">
|
||||
SELECT rule_code, task_type_code
|
||||
FROM rule_item_task_type
|
||||
<where>
|
||||
<if test="ruleCodes != null and ruleCodes.size() > 0">
|
||||
rule_code IN
|
||||
<foreach collection="ruleCodes" item="c" open="(" separator="," close=")">
|
||||
#{c}
|
||||
</foreach>
|
||||
</if>
|
||||
<if test="ruleCodes == null or ruleCodes.size() == 0">
|
||||
1 = 0
|
||||
</if>
|
||||
</where>
|
||||
ORDER BY rule_code ASC, id ASC
|
||||
</select>
|
||||
|
||||
<delete id="deleteTaskTypesByRuleCodes">
|
||||
DELETE FROM rule_item_task_type
|
||||
WHERE rule_code IN
|
||||
|
||||
Reference in New Issue
Block a user