火力规则:java静态方法实现规则

This commit is contained in:
MHW
2026-04-07 11:23:27 +08:00
parent 3e871e2dbd
commit 866fd215f2
14 changed files with 3662 additions and 244 deletions

View File

@@ -1,6 +1,7 @@
package com.solution.rule.domain.ultimately.dto;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.util.List;
@@ -23,7 +24,14 @@ public class FireRuleInputDTO {
private List<FireRuleTaskInputDTO> tasks;
/**
* 红方侧异构条目列表(武器、场景任务节点、装备、指挥所、防区等
* 红方装备等条目列表,对应 JSON 键 {@code redWeapons}(当前 {@link FireRuleInputRedWeaponElementDTO} 与装备结构一致
*/
private List<FireRuleInputRedWeaponElementDTO> redWeapons;
@JsonProperty("equipments")
private List<FireRuleInputRedWeaponElementDTO> equipments;
/**
* 阵营与姿态关系列表,对应 JSON 键 {@code ForceSides}
*/
@JsonProperty("ForceSides")
private List<FireRuleInputForceSideDTO> forceSides;
}

View File

@@ -0,0 +1,19 @@
package com.solution.rule.domain.ultimately.dto;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
/**
* 阵营侧一方与其它方的姿态关系项
*/
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class FireRuleInputForcePostureDTO {
@JsonProperty("ObjectHandle")
private String objectHandle;
@JsonProperty("Type")
private Integer type;
}

View File

@@ -0,0 +1,26 @@
package com.solution.rule.domain.ultimately.dto;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.util.List;
/**
* 阵营侧ForceSides 数组中的一项)
*/
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class FireRuleInputForceSideDTO {
private String groupType;
@JsonProperty("Postures")
private List<FireRuleInputForcePostureDTO> postures;
@JsonProperty("ObjectHandle")
private String objectHandle;
@JsonProperty("ForceSideName")
private String forceSideName;
}

View File

@@ -1,20 +0,0 @@
package com.solution.rule.domain.ultimately.dto;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;
/**
* 防区圆形条目中 isWing 为对象时的样式字段
*/
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class FireRuleInputRedCircleStyleDTO {
private String outlineWidth;
private String lineType;
private String outlineColor;
private String color;
}

View File

@@ -1,34 +0,0 @@
package com.solution.rule.domain.ultimately.dto;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;
import java.util.List;
/**
* redWeapons 条目中 isLead可能是长机编队参数也可能是圆形防区参数字段并集
*/
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class FireRuleInputRedLeadPayloadDTO {
private String leader;
private String side;
private String supportType;
private List<FireRuleInputRedLeadPositionDTO> positions;
private String drawName;
private String airspaceType;
private String selectLonLat;
private String radius;
private String height;
private String extrudedHeight;
}

View File

@@ -1,18 +0,0 @@
package com.solution.rule.domain.ultimately.dto;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;
/**
* 长机/圆形等结构中的坐标点(示例中可能为数值或占位字符串)
*/
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class FireRuleInputRedLeadPositionDTO {
private String longitude;
private String latitude;
private String height;
}

View File

@@ -4,44 +4,16 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.util.List;
import java.util.Map;
/**
* 输入 JSON 中 {@code redWeapons} 数组元素并集:武器摘要、红方装备、营指挥所、防区圆形等形态共用此类。
* <p>
* {@code isWing} 在 JSON 中可能为僚机数组或圆形样式对象,故使用 {@link Object} 承接;可结合
* {@link FireRuleInputRedWingItemDTO}、{@link FireRuleInputRedCircleStyleDTO} 在业务层转型。
* {@code redWeapons} 中红方装备platform条目与 {@code 火力规则输入-无注释.json} 中带
* {@code SubComponents} 的装备对象字段一致。
*/
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class FireRuleInputRedWeaponElementDTO {
private String name;
@JsonProperty("Name")
private String displayName;
private String id;
@JsonProperty("EquipmentID")
private String equipmentId;
private List<FireRuleWeaponComponentDTO> components;
private Object number;
private String successTargetRad;
private FireRuleInputRedLeadPayloadDTO isLead;
private Object isWing;
/**
* 装备类条目中为 {@code equipment} 等
*/
private String groupType;
@JsonProperty("SupportType")
private String supportType;
@@ -59,6 +31,14 @@ public class FireRuleInputRedWeaponElementDTO {
private Boolean isDefendImportantPlace;
private String groupType;
@JsonProperty("EquipmentID")
private String equipmentId;
@JsonProperty("Name")
private String name;
@JsonProperty("OwnerForceSide")
private String ownerForceSide;

View File

@@ -1,17 +0,0 @@
package com.solution.rule.domain.ultimately.dto;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class FireRuleInputRedWingItemDTO {
private String name;
private String distance;
private String angle;
private String alt;
}

View File

@@ -1,7 +1,6 @@
/**
* 火力规则输入侧 DTO与 {@code resources/json/火力规则输入-无注释.json} 对齐。
* <p>
* {@code redWeapons} 数组元素为并集类型 {@link com.solution.rule.domain.ultimately.dto.FireRuleInputRedWeaponElementDTO}
* 常见形态包括:武器摘要、红方装备(含子组件)、营指挥所、防区圆形等。
* {@code redWeapons} 中装备项为 {@link com.solution.rule.domain.ultimately.dto.FireRuleInputRedWeaponElementDTO}(含 {@code SubComponents})。
*/
package com.solution.rule.domain.ultimately.dto;

View File

@@ -1,120 +0,0 @@
//package com.solution.rule.parser;
//
//import com.fasterxml.jackson.core.JsonParser;
//import com.fasterxml.jackson.core.JsonToken;
//import com.fasterxml.jackson.databind.ObjectMapper;
//import javax.servlet.http.HttpServletRequest;
//import java.io.IOException;
//import java.util.*;
//
//public class JsonStreamParser {
//
// // 核心:解析所有集合 → 内存关联ID → 组装完整数据
// public List<AssembledWeapon> parseAndAssemble(HttpServletRequest request) throws IOException {
// ObjectMapper mapper = new ObjectMapper();
// try (JsonParser parser = mapper.getFactory().createParser(request.getInputStream())) {
//
// // ========== 步骤1流式解析把所有关联集合存到内存 ==========
// String version = null;
// // 存储所有集合key=集合名(weaponList/weaponParams)value=数据列表
// Map<String, List<Map<String, Object>>> allCollections = new HashMap<>();
//
// // 解析状态
// String currentCollection = null;
// Map<String, Object> currentItem = null;
//
// JsonToken token;
// while ((token = parser.nextToken()) != null) {
// switch (token) {
// case START_OBJECT:
// if (currentCollection != null) currentItem = new HashMap<>();
// break;
// case END_OBJECT:
// if (currentCollection != null && currentItem != null) {
// allCollections.get(currentCollection).add(currentItem);
// currentItem = null;
// }
// break;
// case START_ARRAY:
// currentCollection = parser.getCurrentName();
// allCollections.putIfAbsent(currentCollection, new ArrayList<>());
// break;
// case END_ARRAY:
// currentCollection = null;
// break;
// case FIELD_NAME:
// String field = parser.getCurrentName();
// // 解析版本号
// if ("version".equals(field) && isInMeta(parser)) {
// version = parser.nextTextValue();
// break;
// }
// // 解析普通字段
// if (currentItem != null) {
// parser.nextToken();
// currentItem.put(field, getValue(parser));
// }
// break;
// }
// }
//
// // ========== 步骤2核心通过ID关联匹配组装完整数据 ==========
// return assembleFullWeaponData(allCollections);
// }
// }
//
// /**
// * 【核心逻辑】ID关联匹配武器列表 + 参数列表 → 完整武器
// */
// private List<AssembledWeapon> assembleFullWeaponData(Map<String, List<Map<String, Object>>> allCollections) {
// List<AssembledWeapon> result = new ArrayList<>();
//
// // 1. 获取武器主列表
// List<Map<String, Object>> weaponList = allCollections.getOrDefault("weaponList", Collections.emptyList());
// // 2. 获取武器参数列表
// List<Map<String, Object>> paramList = allCollections.getOrDefault("weaponParams", Collections.emptyList());
//
// // 3. 构建【ID -> 参数】索引MapO(1)快速匹配,效率最高)
// Map<Long, Map<String, Object>> paramIndex = new HashMap<>();
// for (Map<String, Object> param : paramList) {
// Long weaponId = Long.valueOf(param.get("weaponId").toString());
// paramIndex.put(weaponId, param);
// }
//
// // 4. 遍历武器通过ID匹配参数组装完整对象
// for (Map<String, Object> weapon : weaponList) {
// AssembledWeapon fullWeapon = new AssembledWeapon();
// Long weaponId = Long.valueOf(weapon.get("id").toString());
//
// // 填充基础信息
// fullWeapon.setId(weaponId);
// fullWeapon.setName((String) weapon.get("name"));
//
// // 匹配参数通过ID
// Map<String, Object> param = paramIndex.get(weaponId);
// if (param != null) {
// fullWeapon.setDamage(Integer.valueOf(param.get("damage").toString()));
// fullWeapon.setMagazine(Integer.valueOf(param.get("magazine").toString()));
// fullWeapon.setType((String) param.get("type"));
// }
//
// result.add(fullWeapon);
// }
//
// return result;
// }
//
// // ---------------- 工具方法 ----------------
// private boolean isInMeta(JsonParser parser) {
// return parser.getParsingContext().getParent() != null
// && "meta".equals(parser.getParsingContext().getParent().getCurrentName());
// }
//
// private Object getValue(JsonParser parser) throws IOException {
// if (parser.getCurrentToken().isNumeric()) return parser.getLongValue();
// if (parser.getCurrentToken() == JsonToken.VALUE_STRING) return parser.getText();
// if (parser.getCurrentToken() == JsonToken.VALUE_TRUE) return true;
// if (parser.getCurrentToken() == JsonToken.VALUE_FALSE) return false;
// return null;
// }
//}

View File

@@ -9,6 +9,7 @@ import com.solution.rule.domain.simplerulepojo.Task;
import com.solution.rule.domain.simplerulepojo.Weapon;
import com.solution.rule.domain.simplerulepojo.fact.FactTask;
import com.solution.rule.domain.ultimately.dto.FireRuleInputDTO;
import com.solution.rule.domain.ultimately.dto.FireRuleInputForceSideDTO;
import com.solution.rule.domain.ultimately.dto.FireRuleInputRedWeaponElementDTO;
import com.solution.rule.domain.ultimately.dto.FireRuleTaskInputDTO;
import com.solution.rule.domain.ultimately.fact.DroolsFact;
@@ -209,8 +210,20 @@ public class FireRuleServiceImpl implements FireRuleService {
//设置Drools全局变量
Map<String, Object> globalParams = new HashMap<>();
kieSession.setGlobal("globalParams", globalParams);
kieSession.insert(globalParams);
//获取红方阵营id
String redObjectHandleId = getObjectHandle(task);
if(ObjectUtil.isEmpty(redObjectHandleId)){
throw new RuntimeException(ExceptionConstants.PARAMETER_EXCEPTION);
}
//获取所有武器库
List<FireRuleInputRedWeaponElementDTO> allWeapons = task.getEquipments();
//获取红方武器库
List<FireRuleInputRedWeaponElementDTO> redWeapons = task.getRedWeapons();
List<FireRuleInputRedWeaponElementDTO> redWeapons = allWeapons.stream()
.filter(weapon -> redObjectHandleId.equals(weapon.getOwnerForceSide()))
.collect(Collectors.toList());
//创建返回数据
FireRuleOutputVO fireRuleOutputVO = new FireRuleOutputVO();
fireRuleOutputVO.setSourceFile(task.getSourceFile());
@@ -259,4 +272,15 @@ public class FireRuleServiceImpl implements FireRuleService {
return ruleMapper.findAllBasicPlatformComponents();
}
/**
* 获取红方阵营id
* @param task
* @return
*/
private String getObjectHandle(FireRuleInputDTO task){
List<FireRuleInputForceSideDTO> forceSides = task.getForceSides();
List<FireRuleInputForceSideDTO> collect = forceSides.stream().filter(f -> "红方".equals(f.getForceSideName())).collect(Collectors.toList());
return collect.get(0).getObjectHandle();
}
}

View File

@@ -0,0 +1,34 @@
package com.solution.rule.utils;
import com.solution.rule.domain.ultimately.dto.FireRuleTaskInputDTO;
import com.solution.rule.domain.ultimately.fact.DroolsFact;
import java.util.Map;
/**
* 规则函数方法
*/
public class RuleFunction {
/**
* 装备匹配
*/
public static void equipmentRule(DroolsFact task, Map globalParams){
//空中总分数
Integer airScore = 0;
//反坦克总分数
Integer antitankScore = 0;
//远程打击总分数
Integer remoteScore = 0;
FireRuleTaskInputDTO blueTask = task.getTask();
//权重因子
Integer weight = (Integer) globalParams.get("weight");
String drawName = blueTask.getDrawName();
if("".contains(drawName)){
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,37 @@
package rules;
import com.solution.rule.domain.ultimately.fact.DroolsFact;
import java.util.Map;
import com.solution.rule.utils.RuleFunction.equipmentRule;
global java.util.Map globalParams;
function Map buildParam(){
Map param = new java.util.HashMap();
//权重因子
param.put("weight", 1);
//最低入选分数
param.put("minSelectedScore",1);
//蓝方坦克类 -> 红方反坦克加分
param.put("tankScore", 1);
//蓝方空中类 -> 红方反空中加分
param.put("airScore", 2);
//蓝方地面类 -> 红方远程打击加分
param.put("groundScore", 1);
//蓝方有导弹 -> 红方防空加分
param.put("missileScore", 1);
//蓝方是空中任务 -> 红方防空加分
param.put("airTaskScore", 10);
}
rule "装备匹配"
salience 100
when
$fact : DroolsFact(task.side != "")
then
//如何引入Java静态方法
equipmentRule($fact, globalParams);
end