技术要求:规则展示表格接口

This commit is contained in:
MHW
2026-04-14 16:45:49 +08:00
parent e82455a220
commit 6969fe5744
10 changed files with 600 additions and 27 deletions

View File

@@ -6,7 +6,10 @@ import com.solution.common.core.domain.AjaxResult;
import com.solution.common.core.page.TableDataInfo;
import com.solution.common.enums.BusinessType;
import com.solution.rule.domain.Rule;
import com.solution.rule.domain.config.RuleConfig;
import com.solution.rule.domain.config.RuleConfigQuery;
import com.solution.rule.service.IRuleService;
import com.solution.rule.service.IRuleConfigService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
@@ -22,6 +25,8 @@ public class RuleController extends BaseController {
@Autowired
private IRuleService ruleService;
@Autowired
private IRuleConfigService ruleConfigService;
@PreAuthorize("@ss.hasPermi('system:rule:list')")
@GetMapping("/list")
@@ -62,4 +67,50 @@ public class RuleController extends BaseController {
public AjaxResult remove(@PathVariable Integer[] ids) {
return toAjax(ruleService.deleteRuleByIds(ids));
}
@PreAuthorize("@ss.hasPermi('system:rule:list')")
@GetMapping("/config/list")
@ApiOperation("查询规则聚合列表")
public TableDataInfo configList(RuleConfigQuery query) {
startPage();
return getDataTable(ruleConfigService.selectRuleConfigList(query));
}
@PreAuthorize("@ss.hasPermi('system:rule:query')")
@GetMapping("/config/{ruleCode}")
@ApiOperation("查询规则聚合详情")
public AjaxResult configInfo(@PathVariable String ruleCode) {
return success(ruleConfigService.selectRuleConfigByCode(ruleCode));
}
@PreAuthorize("@ss.hasPermi('system:rule:add')")
@Log(title = "规则聚合管理", businessType = BusinessType.INSERT)
@PostMapping("/config")
@ApiOperation("新增规则聚合")
public AjaxResult addConfig(@RequestBody RuleConfig ruleConfig) {
return toAjax(ruleConfigService.insertRuleConfig(ruleConfig));
}
@PreAuthorize("@ss.hasPermi('system:rule:edit')")
@Log(title = "规则聚合管理", businessType = BusinessType.UPDATE)
@PutMapping("/config")
@ApiOperation("修改规则聚合")
public AjaxResult editConfig(@RequestBody RuleConfig ruleConfig) {
return toAjax(ruleConfigService.updateRuleConfig(ruleConfig));
}
@PreAuthorize("@ss.hasPermi('system:rule:remove')")
@Log(title = "规则聚合管理", businessType = BusinessType.DELETE)
@DeleteMapping("/config/{ruleCodes}")
@ApiOperation("删除规则聚合")
public AjaxResult removeConfig(@PathVariable String[] ruleCodes) {
return toAjax(ruleConfigService.deleteRuleConfigByCodes(ruleCodes));
}
@PreAuthorize("@ss.hasPermi('system:rule:query')")
@GetMapping("/config/dict/{dictType}")
@ApiOperation("按类型查询规则字典")
public AjaxResult dict(@PathVariable String dictType) {
return success(ruleConfigService.selectDictByType(dictType));
}
}

View File

@@ -0,0 +1,61 @@
package com.solution.rule.domain.config;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date;
import java.util.List;
@Data
@ApiModel("规则聚合对象")
public class RuleConfig {
@ApiModelProperty("主键ID")
private Long id;
@ApiModelProperty("规则编码")
private String ruleCode;
@ApiModelProperty("规则名称")
private String ruleName;
@ApiModelProperty("层级编码(task/action/platform)")
private String levelCode;
@ApiModelProperty("种类编码(select/assign/deploy/config/mode/spacetime/relation/limit)")
private String kindCode;
@ApiModelProperty("模块编码(equipment/target/position/track/group)")
private String moduleCode;
@ApiModelProperty("优先级(数字越小越先执行)")
private Integer priorityNo;
@ApiModelProperty("条件表达式")
private String conditionExpr;
@ApiModelProperty("动作表达式")
private String actionExpr;
@ApiModelProperty("版本号")
private Integer versionNo;
@ApiModelProperty("是否启用(1是0否)")
private Integer enabled;
@ApiModelProperty("备注")
private String remark;
@ApiModelProperty("创建时间")
private Date createdAt;
@ApiModelProperty("更新时间")
private Date updatedAt;
@ApiModelProperty("参数列表")
private List<RuleConfigParam> params;
@ApiModelProperty("适用任务类型编码列表")
private List<String> taskTypes;
}

View File

@@ -0,0 +1,34 @@
package com.solution.rule.domain.config;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel("规则参数对象")
public class RuleConfigParam {
@ApiModelProperty("规则编码")
private String ruleCode;
@ApiModelProperty("参数键")
private String paramKey;
@ApiModelProperty("参数值")
private String paramVal;
@ApiModelProperty("值类型(string/number/bool/json)")
private String valType;
@ApiModelProperty("参数名称")
private String paramName;
@ApiModelProperty("排序号")
private Integer sortNo;
@ApiModelProperty("是否启用(1是0否)")
private Integer enabled;
@ApiModelProperty("备注")
private String remark;
}

View File

@@ -0,0 +1,28 @@
package com.solution.rule.domain.config;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel("规则配置查询对象")
public class RuleConfigQuery {
@ApiModelProperty("规则编码")
private String ruleCode;
@ApiModelProperty("规则名称")
private String ruleName;
@ApiModelProperty("层级编码(task/action/platform)")
private String levelCode;
@ApiModelProperty("种类编码(select/assign/deploy/config/mode/spacetime/relation/limit)")
private String kindCode;
@ApiModelProperty("模块编码(equipment/target/position/track/group)")
private String moduleCode;
@ApiModelProperty("是否启用(1是0否)")
private Integer enabled;
}

View File

@@ -0,0 +1,28 @@
package com.solution.rule.domain.config;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel("规则字典项")
public class RuleDictItem {
@ApiModelProperty("字典类型")
private String dictType;
@ApiModelProperty("字典编码")
private String dictCode;
@ApiModelProperty("字典名称")
private String dictName;
@ApiModelProperty("排序号")
private Integer sortNo;
@ApiModelProperty("是否启用(1是0否)")
private Integer enabled;
@ApiModelProperty("备注")
private String remark;
}

View File

@@ -0,0 +1,38 @@
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.RuleDictItem;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface RuleConfigMapper {
List<RuleConfig> selectRuleConfigList(RuleConfigQuery query);
RuleConfig selectRuleConfigByCode(@Param("ruleCode") String ruleCode);
int countByRuleCode(@Param("ruleCode") String ruleCode);
int insertRuleConfig(RuleConfig ruleConfig);
int updateRuleConfig(RuleConfig ruleConfig);
int deleteRuleConfigByCodes(@Param("ruleCodes") String[] ruleCodes);
List<RuleConfigParam> selectParamsByRuleCode(@Param("ruleCode") String ruleCode);
int deleteParamsByRuleCodes(@Param("ruleCodes") String[] ruleCodes);
int insertParamsBatch(@Param("params") List<RuleConfigParam> params);
List<String> selectTaskTypesByRuleCode(@Param("ruleCode") String ruleCode);
int deleteTaskTypesByRuleCodes(@Param("ruleCodes") String[] ruleCodes);
int insertTaskTypesBatch(@Param("ruleCode") String ruleCode, @Param("taskTypes") List<String> taskTypes);
List<RuleDictItem> selectDictByType(@Param("dictType") String dictType);
}

View File

@@ -0,0 +1,22 @@
package com.solution.rule.service;
import com.solution.rule.domain.config.RuleConfig;
import com.solution.rule.domain.config.RuleConfigQuery;
import com.solution.rule.domain.config.RuleDictItem;
import java.util.List;
public interface IRuleConfigService {
List<RuleConfig> selectRuleConfigList(RuleConfigQuery query);
RuleConfig selectRuleConfigByCode(String ruleCode);
int insertRuleConfig(RuleConfig ruleConfig);
int updateRuleConfig(RuleConfig ruleConfig);
int deleteRuleConfigByCodes(String[] ruleCodes);
List<RuleDictItem> selectDictByType(String dictType);
}

View File

@@ -0,0 +1,139 @@
package com.solution.rule.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
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.RuleDictItem;
import com.solution.rule.mapper.RuleConfigMapper;
import com.solution.rule.service.IRuleConfigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@Service
public class RuleConfigServiceImpl implements IRuleConfigService {
@Autowired
private RuleConfigMapper ruleConfigMapper;
@Override
public List<RuleConfig> selectRuleConfigList(RuleConfigQuery query) {
return ruleConfigMapper.selectRuleConfigList(query);
}
@Override
public RuleConfig selectRuleConfigByCode(String ruleCode) {
RuleConfig config = ruleConfigMapper.selectRuleConfigByCode(ruleCode);
if (config == null) {
return null;
}
config.setParams(ruleConfigMapper.selectParamsByRuleCode(ruleCode));
config.setTaskTypes(ruleConfigMapper.selectTaskTypesByRuleCode(ruleCode));
return config;
}
@Override
@Transactional(rollbackFor = Exception.class)
public int insertRuleConfig(RuleConfig ruleConfig) {
validateBase(ruleConfig);
if (ruleConfigMapper.countByRuleCode(ruleConfig.getRuleCode()) > 0) {
throw new RuntimeException("规则编码已存在");
}
int rows = ruleConfigMapper.insertRuleConfig(fillDefault(ruleConfig));
saveChildren(ruleConfig);
return rows;
}
@Override
@Transactional(rollbackFor = Exception.class)
public int updateRuleConfig(RuleConfig ruleConfig) {
validateBase(ruleConfig);
if (ruleConfigMapper.countByRuleCode(ruleConfig.getRuleCode()) <= 0) {
throw new RuntimeException("规则编码不存在");
}
int rows = ruleConfigMapper.updateRuleConfig(fillDefault(ruleConfig));
String[] ruleCodes = {ruleConfig.getRuleCode()};
ruleConfigMapper.deleteParamsByRuleCodes(ruleCodes);
ruleConfigMapper.deleteTaskTypesByRuleCodes(ruleCodes);
saveChildren(ruleConfig);
return rows;
}
@Override
@Transactional(rollbackFor = Exception.class)
public int deleteRuleConfigByCodes(String[] ruleCodes) {
if (ruleCodes == null || ruleCodes.length == 0) {
return 0;
}
ruleConfigMapper.deleteParamsByRuleCodes(ruleCodes);
ruleConfigMapper.deleteTaskTypesByRuleCodes(ruleCodes);
return ruleConfigMapper.deleteRuleConfigByCodes(ruleCodes);
}
@Override
public List<RuleDictItem> selectDictByType(String dictType) {
if (ObjectUtil.isEmpty(dictType)) {
throw new RuntimeException(ExceptionConstants.PARAMETER_EXCEPTION);
}
return ruleConfigMapper.selectDictByType(dictType);
}
private void saveChildren(RuleConfig ruleConfig) {
if (CollUtil.isNotEmpty(ruleConfig.getParams())) {
Set<String> keys = new HashSet<>();
for (RuleConfigParam param : ruleConfig.getParams()) {
if (param == null || ObjectUtil.isEmpty(param.getParamKey())) {
throw new RuntimeException("参数键不能为空");
}
if (!keys.add(param.getParamKey())) {
throw new RuntimeException("参数键重复: " + param.getParamKey());
}
param.setRuleCode(ruleConfig.getRuleCode());
if (param.getSortNo() == null) {
param.setSortNo(0);
}
if (param.getEnabled() == null) {
param.setEnabled(1);
}
if (ObjectUtil.isEmpty(param.getValType())) {
param.setValType("string");
}
}
ruleConfigMapper.insertParamsBatch(ruleConfig.getParams());
}
if (CollUtil.isNotEmpty(ruleConfig.getTaskTypes())) {
ruleConfigMapper.insertTaskTypesBatch(ruleConfig.getRuleCode(), ruleConfig.getTaskTypes());
}
}
private RuleConfig fillDefault(RuleConfig ruleConfig) {
if (ruleConfig.getPriorityNo() == null) {
ruleConfig.setPriorityNo(100);
}
if (ruleConfig.getVersionNo() == null) {
ruleConfig.setVersionNo(1);
}
if (ruleConfig.getEnabled() == null) {
ruleConfig.setEnabled(1);
}
return ruleConfig;
}
private void validateBase(RuleConfig ruleConfig) {
if (ruleConfig == null
|| ObjectUtil.isEmpty(ruleConfig.getRuleCode())
|| ObjectUtil.isEmpty(ruleConfig.getRuleName())
|| ObjectUtil.isEmpty(ruleConfig.getLevelCode())
|| ObjectUtil.isEmpty(ruleConfig.getKindCode())
|| ObjectUtil.isEmpty(ruleConfig.getModuleCode())) {
throw new RuntimeException(ExceptionConstants.PARAMETER_EXCEPTION);
}
}
}

View File

@@ -0,0 +1,174 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.solution.rule.mapper.RuleConfigMapper">
<resultMap id="RuleConfigMap" type="com.solution.rule.domain.config.RuleConfig">
<id property="id" column="id"/>
<result property="ruleCode" column="rule_code"/>
<result property="ruleName" column="rule_name"/>
<result property="levelCode" column="level_code"/>
<result property="kindCode" column="kind_code"/>
<result property="moduleCode" column="module_code"/>
<result property="priorityNo" column="priority_no"/>
<result property="conditionExpr" column="condition_expr"/>
<result property="actionExpr" column="action_expr"/>
<result property="versionNo" column="version_no"/>
<result property="enabled" column="enabled"/>
<result property="remark" column="remark"/>
<result property="createdAt" column="created_at"/>
<result property="updatedAt" column="updated_at"/>
</resultMap>
<resultMap id="RuleConfigParamMap" type="com.solution.rule.domain.config.RuleConfigParam">
<result property="ruleCode" column="rule_code"/>
<result property="paramKey" column="param_key"/>
<result property="paramVal" column="param_val"/>
<result property="valType" column="val_type"/>
<result property="paramName" column="param_name"/>
<result property="sortNo" column="sort_no"/>
<result property="enabled" column="enabled"/>
<result property="remark" column="remark"/>
</resultMap>
<resultMap id="RuleDictItemMap" type="com.solution.rule.domain.config.RuleDictItem">
<result property="dictType" column="dict_type"/>
<result property="dictCode" column="dict_code"/>
<result property="dictName" column="dict_name"/>
<result property="sortNo" column="sort_no"/>
<result property="enabled" column="enabled"/>
<result property="remark" column="remark"/>
</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
FROM rule_item
<where>
<if test="ruleCode != null and ruleCode != ''">
AND rule_code = #{ruleCode}
</if>
<if test="ruleName != null and ruleName != ''">
AND rule_name LIKE CONCAT('%', #{ruleName}, '%')
</if>
<if test="levelCode != null and levelCode != ''">
AND level_code = #{levelCode}
</if>
<if test="kindCode != null and kindCode != ''">
AND kind_code = #{kindCode}
</if>
<if test="moduleCode != null and moduleCode != ''">
AND module_code = #{moduleCode}
</if>
<if test="enabled != null">
AND enabled = #{enabled}
</if>
</where>
ORDER BY priority_no ASC, updated_at DESC
</select>
<select id="selectRuleConfigByCode" 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
FROM rule_item
WHERE rule_code = #{ruleCode}
</select>
<select id="countByRuleCode" resultType="int">
SELECT COUNT(1)
FROM rule_item
WHERE rule_code = #{ruleCode}
</select>
<insert id="insertRuleConfig" parameterType="com.solution.rule.domain.config.RuleConfig">
INSERT INTO rule_item
(rule_code, rule_name, level_code, kind_code, module_code, priority_no, condition_expr,
action_expr, version_no, enabled, remark, created_at, updated_at)
VALUES
(#{ruleCode}, #{ruleName}, #{levelCode}, #{kindCode}, #{moduleCode}, #{priorityNo}, #{conditionExpr},
#{actionExpr}, #{versionNo}, #{enabled}, #{remark}, NOW(), NOW())
</insert>
<update id="updateRuleConfig" parameterType="com.solution.rule.domain.config.RuleConfig">
UPDATE rule_item
<set>
<if test="ruleName != null">rule_name = #{ruleName},</if>
<if test="levelCode != null">level_code = #{levelCode},</if>
<if test="kindCode != null">kind_code = #{kindCode},</if>
<if test="moduleCode != null">module_code = #{moduleCode},</if>
<if test="priorityNo != null">priority_no = #{priorityNo},</if>
<if test="conditionExpr != null">condition_expr = #{conditionExpr},</if>
<if test="actionExpr != null">action_expr = #{actionExpr},</if>
<if test="versionNo != null">version_no = #{versionNo},</if>
<if test="enabled != null">enabled = #{enabled},</if>
<if test="remark != null">remark = #{remark},</if>
updated_at = NOW()
</set>
WHERE rule_code = #{ruleCode}
</update>
<delete id="deleteRuleConfigByCodes">
DELETE FROM rule_item
WHERE rule_code IN
<foreach item="code" collection="ruleCodes" open="(" separator="," close=")">
#{code}
</foreach>
</delete>
<select id="selectParamsByRuleCode" resultMap="RuleConfigParamMap">
SELECT rule_code, param_key, param_val, val_type, param_name, sort_no, enabled, remark
FROM rule_item_param
WHERE rule_code = #{ruleCode}
ORDER BY sort_no ASC, id ASC
</select>
<delete id="deleteParamsByRuleCodes">
DELETE FROM rule_item_param
WHERE rule_code IN
<foreach item="code" collection="ruleCodes" open="(" separator="," close=")">
#{code}
</foreach>
</delete>
<insert id="insertParamsBatch">
INSERT INTO rule_item_param
(rule_code, param_key, param_val, val_type, param_name, sort_no, enabled, remark, created_at, updated_at)
VALUES
<foreach item="item" collection="params" separator=",">
(#{item.ruleCode}, #{item.paramKey}, #{item.paramVal}, #{item.valType}, #{item.paramName},
#{item.sortNo}, #{item.enabled}, #{item.remark}, NOW(), NOW())
</foreach>
</insert>
<select id="selectTaskTypesByRuleCode" resultType="string">
SELECT task_type_code
FROM rule_item_task_type
WHERE rule_code = #{ruleCode}
ORDER BY id ASC
</select>
<delete id="deleteTaskTypesByRuleCodes">
DELETE FROM rule_item_task_type
WHERE rule_code IN
<foreach item="code" collection="ruleCodes" open="(" separator="," close=")">
#{code}
</foreach>
</delete>
<insert id="insertTaskTypesBatch">
INSERT INTO rule_item_task_type (rule_code, task_type_code, created_at)
VALUES
<foreach item="taskType" collection="taskTypes" separator=",">
(#{ruleCode}, #{taskType}, NOW())
</foreach>
</insert>
<select id="selectDictByType" resultMap="RuleDictItemMap">
SELECT dict_type, dict_code, dict_name, sort_no, enabled, remark
FROM rule_dict
WHERE dict_type = #{dictType}
ORDER BY sort_no ASC, id ASC
</select>
</mapper>

View File

@@ -182,32 +182,30 @@ ON DUPLICATE KEY UPDATE
`remark` = VALUES(`remark`);
-- 4) 规则适用任务类型(默认全部规则覆盖五类任务,后续可在前端按需调整)
INSERT INTO `rule_item_task_type` (`rule_code`, `task_type_code`)
INSERT IGNORE INTO `rule_item_task_type` (`rule_code`, `task_type_code`)
SELECT r.rule_code, t.task_type_code
FROM (
SELECT 'R_TASK_SELECT_BASE' AS rule_code
UNION ALL SELECT 'R_TASK_SELECT_SLOT_1'
UNION ALL SELECT 'R_TASK_SELECT_SLOT_2'
UNION ALL SELECT 'R_TASK_SELECT_SLOT_3'
UNION ALL SELECT 'R_TASK_REL_AIR_PLATFORM'
UNION ALL SELECT 'R_TASK_REL_AIR_TASK'
UNION ALL SELECT 'R_TASK_REL_GROUND_TASK'
UNION ALL SELECT 'R_TASK_REL_TANK'
UNION ALL SELECT 'R_TASK_REL_MISSILE'
UNION ALL SELECT 'R_TASK_ASSIGN_TARGET'
UNION ALL SELECT 'R_TASK_LIMIT_SUPPLEMENT'
UNION ALL SELECT 'R_PLATFORM_DEPLOY'
UNION ALL SELECT 'R_PLATFORM_SPACETIME'
UNION ALL SELECT 'R_ACTION_TRACK_ROUTE'
UNION ALL SELECT 'R_ACTION_TRACK_SPACETIME'
UNION ALL SELECT 'R_ACTION_GROUP_FORMATION'
) r
CROSS JOIN (
SELECT 'strike' AS task_type_code
UNION ALL SELECT 'recon'
UNION ALL SELECT 'intercept'
UNION ALL SELECT 'support'
UNION ALL SELECT 'jamming'
) t
ON DUPLICATE KEY UPDATE
`task_type_code` = VALUES(`task_type_code`);
SELECT 'R_TASK_SELECT_BASE' AS rule_code
UNION ALL SELECT 'R_TASK_SELECT_SLOT_1'
UNION ALL SELECT 'R_TASK_SELECT_SLOT_2'
UNION ALL SELECT 'R_TASK_SELECT_SLOT_3'
UNION ALL SELECT 'R_TASK_REL_AIR_PLATFORM'
UNION ALL SELECT 'R_TASK_REL_AIR_TASK'
UNION ALL SELECT 'R_TASK_REL_GROUND_TASK'
UNION ALL SELECT 'R_TASK_REL_TANK'
UNION ALL SELECT 'R_TASK_REL_MISSILE'
UNION ALL SELECT 'R_TASK_ASSIGN_TARGET'
UNION ALL SELECT 'R_TASK_LIMIT_SUPPLEMENT'
UNION ALL SELECT 'R_PLATFORM_DEPLOY'
UNION ALL SELECT 'R_PLATFORM_SPACETIME'
UNION ALL SELECT 'R_ACTION_TRACK_ROUTE'
UNION ALL SELECT 'R_ACTION_TRACK_SPACETIME'
UNION ALL SELECT 'R_ACTION_GROUP_FORMATION'
) r
CROSS JOIN (
SELECT 'strike' AS task_type_code
UNION ALL SELECT 'recon'
UNION ALL SELECT 'intercept'
UNION ALL SELECT 'support'
UNION ALL SELECT 'jamming'
) t;