package com.solution.rule.utils;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.solution.rule.domain.ultimately.dto.FireRuleInputRedSubComponentsDTO;
import com.solution.rule.domain.ultimately.vo.FireRuleLauncherConfigurationVO;
import com.solution.rule.domain.ultimately.vo.FireRuleMissionListItemVO;
import com.solution.rule.domain.ultimately.vo.FireRuleMountedWeaponRefVO;
import com.solution.rule.domain.ultimately.vo.FireRuleRedSubComponentsVO;
import com.solution.rule.domain.ultimately.vo.FireRuleRedWeaponEquipmentVO;
import com.solution.rule.domain.ultimately.vo.FireRuleRedWeaponSlotVO;
import com.solution.rule.domain.ultimately.vo.FireRuleSceneTaskNodeVO;
import com.solution.rule.domain.ultimately.vo.FireRuleSceneTaskPayloadVO;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
/**
* 将入参中的红方装备 {@code SubComponents}(DTO)转为输出 VO,保持与原始 JSON 结构一致。
*/
public final class FireRuleRedWeaponOutputFillHelper {
private static final ObjectMapper MAPPER = new ObjectMapper()
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
private FireRuleRedWeaponOutputFillHelper() {
}
/**
* DTO 与 VO 字段/JsonProperty 对齐,通过 Jackson 树转换实现原样输出。
*/
public static FireRuleRedSubComponentsVO toOutputSubComponents(FireRuleInputRedSubComponentsDTO src) {
if (src == null) {
return null;
}
return MAPPER.convertValue(src, FireRuleRedSubComponentsVO.class);
}
/**
* 将输出 redWeapons 单项映射为 Tasks 节点(一个装备 -> 一个任务节点)。
*
*
字段映射约定:
*
* - drawName = Name + \"打击任务\"
* - side = OwnerForceSide(按你的要求直接复制)
* - id 优先 EquipmentID,其次 PlatID,最后用 index 兜底
* - task.payload.weaponId = EquipmentID
* - task.payload.sideId = OwnerForceSide
* - missionList:尽量从 SubComponents.weapon[*] 中提取 mountedWeapon/name/number/launcherType
*
*/
public static FireRuleSceneTaskNodeVO toTaskNode(FireRuleRedWeaponEquipmentVO redWeapon, int index) {
FireRuleSceneTaskNodeVO node = new FireRuleSceneTaskNodeVO();
if (redWeapon == null) {
node.setId("redWeaponTask_" + index);
node.setDrawName("打击任务");
return node;
}
String name = nz(redWeapon.getName());
node.setName(name);
node.setDrawName(name + "打击任务");
node.setId(buildNodeId(redWeapon, index));
node.setSide(redWeapon.getOwnerForceSide());
// 按你的要求写死 Tasks 节点的展示字段
node.setColor("rgb(220, 39, 39)");
node.setDataType("taskPlane");
node.setGroupType("tasks");
node.setShow(true);
node.setIsSelected(false);
node.setSort((long) index);
FireRuleSceneTaskPayloadVO payload = new FireRuleSceneTaskPayloadVO();
payload.setName(name);
payload.setWeaponId(redWeapon.getEquipmentId());
payload.setSideId(redWeapon.getOwnerForceSide());
payload.setMissionList(buildMissionList(redWeapon));
node.setTask(payload);
return node;
}
/**
* 批量转换:redWeapons 有几个就生成几个 Tasks。
*/
public static List toTaskNodes(List redWeapons) {
if (redWeapons == null || redWeapons.isEmpty()) {
return Collections.emptyList();
}
List list = new ArrayList<>(redWeapons.size());
for (int i = 0; i < redWeapons.size(); i++) {
list.add(toTaskNode(redWeapons.get(i), i));
}
return list;
}
private static List buildMissionList(FireRuleRedWeaponEquipmentVO redWeapon) {
if (redWeapon == null || redWeapon.getSubComponents() == null || redWeapon.getSubComponents().getWeapon() == null) {
return null;
}
List result = new ArrayList<>();
for (FireRuleRedWeaponSlotVO slot : redWeapon.getSubComponents().getWeapon()) {
if (slot == null) {
continue;
}
FireRuleLauncherConfigurationVO cfg = slot.getConfiguration();
FireRuleMountedWeaponRefVO mounted = cfg != null ? cfg.getMountedWeapon() : null;
FireRuleMissionListItemVO item = new FireRuleMissionListItemVO();
// label:优先挂载武器名,其次 deviceName
String label = mounted != null ? mounted.getName() : null;
if (isBlank(label)) {
label = slot.getDeviceName();
}
item.setLabel(label);
item.setNumber(cfg != null ? cfg.getNumber() : null);
item.setValue(mounted != null ? mounted.getName() : null);
item.setLauncherType(extractLauncherType(slot.getTwiceModified()));
result.add(item);
}
return result.isEmpty() ? null : result;
}
private static String extractLauncherType(Map twiceModified) {
if (twiceModified == null || twiceModified.isEmpty()) {
return null;
}
Object v = twiceModified.get("launcherType");
return v == null ? null : String.valueOf(v);
}
private static String buildNodeId(FireRuleRedWeaponEquipmentVO redWeapon, int index) {
String id = nz(redWeapon.getEquipmentId());
if (!id.isEmpty()) {
return id;
}
id = nz(redWeapon.getPlatId());
if (!id.isEmpty()) {
return id;
}
return "redWeaponTask_" + index;
}
private static String nz(String s) {
return s == null ? "" : s;
}
private static boolean isBlank(String s) {
return s == null || s.trim().isEmpty();
}
}