Compare commits

...

3 Commits

Author SHA1 Message Date
李玉东
ad420b3e8c Merge branch 'main' of http://git.hivekion.com:3000/liyudong/simulation-backend 2025-09-17 14:59:58 +08:00
李玉东
85435894fa 初次提交 2025-09-17 14:59:08 +08:00
李玉东
9338afe26d 初次提交 2025-09-17 13:58:20 +08:00
58 changed files with 926 additions and 1370 deletions

12
pom.xml
View File

@ -184,12 +184,12 @@
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>3.5.2</version>
</dependency>
<!--hutool工具-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.7.6</version>
</dependency>
<!-- &lt;!&ndash;hutool工具&ndash;&gt;-->
<!-- <dependency>-->
<!-- <groupId>cn.hutool</groupId>-->
<!-- <artifactId>hutool-all</artifactId>-->
<!-- <version>5.7.6</version>-->
<!-- </dependency>-->
<!--单元测试-->
<dependency>
<groupId>org.springframework.boot</groupId>

View File

@ -33,7 +33,7 @@ public class CodeGenerator {
basePath + "/src/main/resources/mapper/tbl")); // 设置mapperXml生成路径
})
.strategyConfig(builder -> {
builder.addInclude("TBL_BATTLE_SUPPLIER".toLowerCase()) // 设置需要生成的表名多个用逗号分隔
builder.addInclude("TBL_ROOM_LOG".toLowerCase()) // 设置需要生成的表名多个用逗号分隔
.addTablePrefix("tbl_"); // 设置过滤表前缀
})
.execute();

View File

@ -3,7 +3,7 @@ package com.hivekion;
import com.hivekion.common.entity.RequestCmdInfo;
import com.hivekion.common.entity.ResponseCmdInfo;
import com.hivekion.scenario.bean.ScenarioWsParam;
import java.util.HashMap;
import com.hivekion.scenario.entity.RoomLog;
import java.util.Map;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
@ -21,6 +21,6 @@ import java.util.concurrent.LinkedBlockingQueue;
public class Global {
public static BlockingQueue<RequestCmdInfo> receiveCmdInfoQueue = new LinkedBlockingQueue<>(10000);
public static BlockingQueue<ResponseCmdInfo<?>> sendCmdInfoQueue = new LinkedBlockingQueue<>();
public static Map<String,ScenarioWsParam> roomParamMap = new ConcurrentHashMap<>();
public static Map<String, ScenarioWsParam> roomParamMap = new ConcurrentHashMap<>();
public static BlockingQueue<RoomLog> roomLogQueue = new LinkedBlockingQueue<>(1000);
}

View File

@ -0,0 +1,24 @@
package com.hivekion;
/**
* [类的简要说明]
* <p>
* [详细描述可选]
* <p>
*
* @author LiDongYU
* @since 2025/7/22
*/
public class Test {
public static void main(String[] args) {
String test = "id\n"
+ "general_time\n"
+ "from_resource_id\n"
+ "supplier_type\n"
+ "supplier_num\n"
+ "lat\n"
+ "lng";
System.out.println(test.toUpperCase());
}
}

View File

@ -5,6 +5,7 @@ import com.hivekion.baseData.entity.Scenario;
import com.hivekion.power.bean.PowerBase;
import com.hivekion.power.bean.ScenarioPowerData;
import java.util.List;
import java.util.Map;
/**
* <p>
@ -68,5 +69,5 @@ public interface ScenarioService extends IService<Scenario> {
List<Scenario> allNoContent();
Scenario getScenarioById(Integer id);
Map<Integer,Scenario> scenarioMap();
}

View File

@ -7,29 +7,13 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hivekion.baseData.entity.Scenario;
import com.hivekion.baseData.mapper.ScenarioMapper;
import com.hivekion.baseData.service.ScenarioService;
import com.hivekion.common.redis.RedisUtil;
import com.hivekion.environment.entity.SimtoolWeather;
import com.hivekion.environment.service.SimtoolWeatherService;
import com.hivekion.power.bean.ActionInfo;
import com.hivekion.power.bean.AmmunitionInfo;
import com.hivekion.power.bean.MaterialNumInfo;
import com.hivekion.power.bean.PersonStatisticInfo;
import com.hivekion.power.bean.PositionInfo;
import com.hivekion.power.bean.PowerBase;
import com.hivekion.power.bean.PowerGroup;
import com.hivekion.power.bean.ScenarioPowerData;
import com.hivekion.scenario.bean.ArraysTag;
import com.hivekion.scenario.bean.Power;
import com.hivekion.scenario.bean.PowerSet;
import com.hivekion.scenario.bean.ScenarioData;
import com.hivekion.scenario.bean.Unit;
import com.hivekion.thread.SpringGlobalTaskManager;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
/**
@ -45,7 +29,6 @@ public class ScenarioServiceImpl extends ServiceImpl<ScenarioMapper, Scenario> i
ScenarioService {
@Override
public List<Scenario> List(Scenario scenario) {
return this.baseMapper.List(scenario);
@ -166,149 +149,6 @@ public class ScenarioServiceImpl extends ServiceImpl<ScenarioMapper, Scenario> i
// return scenarioPowerData;
}
private PowerGroup createPowGroup(PowerSet set, ScenarioData scenarioData) {
PowerGroup group = new PowerGroup();
//todo
group.setFight(makePowerbaseList(set.getFightPower(), scenarioData.getUnitList()));
group.setGuarantee(makePowerbaseList(set.getSafeguardPower(), scenarioData.getUnitList()));
return group;
}
private List<PowerBase> makePowerbaseList(List<ArraysTag> arraysTagList,
List<Unit> unitList) {
Map<String, PowerBase> map = new LinkedHashMap<>();
arraysTagList.forEach(arraysTag -> {
if (arraysTag.getArray() != null) {
arraysTag.getArray().forEach(a -> {
PowerBase base = new PowerBase();
base.setId(a.getUuid());
base.setName(a.getText());
map.put(a.getUuid(), base);
});
}
});
Map<String, Unit> unitMap = unitList.stream()
.collect(Collectors.toMap(Unit::getUuid, a -> a));
//获取组织
map.forEach((mapKey, mapValue) -> {
Unit unit = unitMap.get(mapKey);
if (unit != null) {
//设置位置信息
mapValue.setPosition(createPosition(unit));
//设置人员统计
mapValue.setPersonStatistic(createStatistic(unit));
//设置食品信息
mapValue.setFoodInfo(createFoodInfo(unit));
//设置水信息
mapValue.setWaterInfo(createWaterInfo(unit));
//油信息
mapValue.setOilInfo(createOilInfo(unit));
//药材信息
mapValue.setMedicalInfo(createMedicalInfo(unit));
//弹药信息
mapValue.setAmmunition(createAmmunitionInfo(unit));
//行动信息
mapValue.setActionList(createActionInfo(unit));
}
});
return new ArrayList<>(map.values());
}
//创建position
private PositionInfo createPosition(Unit unit) {
PositionInfo positionInfo = new PositionInfo();
positionInfo.setHeight(unit.getHeight() == null ? 0.0 : unit.getHeight().doubleValue());//高度
positionInfo.setLng(unit.getLongitude() == null ? "" : unit.getLongitude().toPlainString());//经度
positionInfo.setLat(unit.getLatitude() == null ? "" : unit.getLatitude().toPlainString());//纬度
positionInfo.setSpeed(unit.getSpeed());//速度
positionInfo.setDirection(unit.getCourse().doubleValue());//方向
positionInfo.setDeduceTypeName(unit.getDeducType() == 1 ? "红军" : "蓝军"); //推演方类型名称
positionInfo.setLogisticType(unit.getLogisticsSupportType());
return positionInfo;
}
//人员统计信息
private PersonStatisticInfo createStatistic(Unit unit) {
PersonStatisticInfo personStatisticInfo = new PersonStatisticInfo();
personStatisticInfo.setTotal(unit.getTeamPeopleNum());
personStatisticInfo.setCurrent(unit.getTeamPeopleNum() - unit.getDeadPeopleNum());
personStatisticInfo.setDeath(unit.getDeadPeopleNum());
personStatisticInfo.setInjured(unit.getHurtPeopleNum());
return personStatisticInfo;
}
//食品消耗信息
private MaterialNumInfo createFoodInfo(Unit unit) {
MaterialNumInfo materialNumInfo = new MaterialNumInfo();
materialNumInfo.setStartNum(unit.getTeamFieldOperationsFoodInfo());
materialNumInfo.setCurrentNum(
unit.getTeamFieldOperationsFoodInfo() - unit.getPeoFieldOperationsFoodConsume());
return materialNumInfo;
}
//水信息
private MaterialNumInfo createWaterInfo(Unit unit) {
MaterialNumInfo materialNumInfo = new MaterialNumInfo();
materialNumInfo.setStartNum(
unit.getTeamWaterInfo() == null ? 0 : unit.getTeamWaterInfo().doubleValue());
materialNumInfo.setCurrentNum(
materialNumInfo.getStartNum() - (unit.getPeoWaterConsume() == null ? 0
: unit.getPeoWaterConsume()));
return materialNumInfo;
}
//油信息
private MaterialNumInfo createOilInfo(Unit unit) {
MaterialNumInfo materialNumInfo = new MaterialNumInfo();
materialNumInfo.setStartNum(unit.getOilInfo() == null ? 0 : unit.getOilInfo().doubleValue());
//todo
materialNumInfo.setCurrentNum(unit.getOilInfo() == null ? 0 : unit.getOilInfo().doubleValue());
return materialNumInfo;
}
private MaterialNumInfo createMedicalInfo(Unit unit) {
MaterialNumInfo materialNumInfo = new MaterialNumInfo();
materialNumInfo.setStartNum(
unit.getTeamMedicinalInfo() == null ? 0 : unit.getTeamMedicinalInfo().doubleValue());
materialNumInfo.setStartNum(
materialNumInfo.getStartNum() - (unit.getPeoHerbMedicalConsume() == null ? 0
: unit.getPeoHerbMedicalConsume().doubleValue()) - (
unit.getPeoBloodMedicalConsume() == null ? 0
: unit.getPeoBloodMedicalConsume().doubleValue()));
return materialNumInfo;
}
private AmmunitionInfo createAmmunitionInfo(Unit unit) {
AmmunitionInfo ammunitionInfo = new AmmunitionInfo();
//设置轻武器
ammunitionInfo.setLightArms(
unit.getLightAmmunitionInfo() == null ? 0 : unit.getLightAmmunitionInfo().doubleValue());
//设置压制武器
ammunitionInfo.setSuppressing(
unit.getSuppressEquipNum() == null ? 0 : unit.getSuppressEquipNum().doubleValue());
return ammunitionInfo;
}
private List<ActionInfo> createActionInfo(Unit unit) {
List<ActionInfo> list = new ArrayList<>();
JSONArray jsonArray = unit.getFightActionInfo();
if (jsonArray != null) {
for (int i = 0; i < jsonArray.size(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
ActionInfo actionInfo = new ActionInfo();
actionInfo.setBeginDateTime(jsonObject.getString("StartTime"));
actionInfo.setEndDateTime(jsonObject.getString("EndTime"));
list.add(actionInfo);
}
}
return list;
}
@Override
public void modifyUnitInfo(PowerBase info, Scenario data) {
@ -370,38 +210,6 @@ public class ScenarioServiceImpl extends ServiceImpl<ScenarioMapper, Scenario> i
return unitMap;
}
private void modifyPower(String id, String name, Power power) {
modifyRole(id, name, power.getPower().getRed());
modifyRole(id, name, power.getPower().getBlue());
}
private void modifyRole(String id, String name, PowerSet role) {
if (role != null && role.getFightPower() != null) {
role.getFightPower().forEach(a -> {
if (a.getArray() != null && !a.getArray().isEmpty()) {
a.getArray().forEach(guidInfo -> {
if (guidInfo.getUuid().equals(id)) {
guidInfo.setText(name);
}
});
}
});
}
if (role != null && role.getSafeguardPower() != null) {
role.getSafeguardPower().forEach(a -> {
if (a.getArray() != null && !a.getArray().isEmpty()) {
a.getArray().forEach(guidInfo -> {
if (guidInfo.getUuid().equals(id)) {
guidInfo.setText(name);
}
});
}
});
}
}
@Override
public List<Scenario> allNoContent() {
@ -414,10 +222,13 @@ public class ScenarioServiceImpl extends ServiceImpl<ScenarioMapper, Scenario> i
@Override
public Scenario getScenarioById(Integer id) {
return this.baseMapper.selectByScenarioId(id);
return this.baseMapper.selectByScenarioId(id);
}
@Override
public Map<Integer, Scenario> scenarioMap() {
return this.allNoContent().stream()
.collect(Collectors.toMap(Scenario::getId, scenario -> scenario));
}
}

View File

@ -0,0 +1,26 @@
package com.hivekion.enums;
import lombok.Getter;
/**
* [类的简要说明]
* <p>
* [详细描述可选]
* <p>
*
* @author LiDongYU
* @since 2025/7/22
*/
public enum ScenarioRoomStatusEnum {
INIT(0),
STARTED(1),
BROKEN(2),
FINISHED(3);
@Getter
private final int code;
ScenarioRoomStatusEnum(int code) {
this.code = code;
}
}

View File

@ -0,0 +1,31 @@
package com.hivekion.enums;
import lombok.Getter;
/**
* [类的简要说明]
* <p>
* [详细描述可选]
* <p>
*
* @author LiDongYU
* @since 2025/7/22
*/
public enum TaskEnum {
MOVE(1),
FIGHT(2),
SUPPLIER_WATER(5),
SUPPLIER_MEDICAL(8),
SUPPLIER_FOOD(7),
SUPPLIER_AMMO(4),
SUPPLIER_FUEL(6);
@Getter
private int code;
TaskEnum(int code) {
this.code = code;
}
}

View File

@ -0,0 +1,54 @@
package com.hivekion.room;
import com.hivekion.room.bean.Room;
import com.hivekion.room.func.TaskAction;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* [类的简要说明]
* <p>
* [详细描述可选]
* <p>
*
* @author LiDongYU
* @since 2025/7/22
*/
public class RoomManager {
private static final Map<String, Room> roomsMap = new ConcurrentHashMap<>();
public static void startRoom(String id, long time) {
Room room = new Room(id);
roomsMap.put(id, room);
room.start(time);
}
public static void stopRoom(String id) {
Room room = roomsMap.get(id);
if (room != null) {
room.stop();
}
}
public static void pauseRoom(String id) {
Room room = roomsMap.get(id);
if (room != null) {
room.pause();
}
}
public static void resumeRoom(String id) {
Room room = roomsMap.get(id);
if (room != null) {
room.resume();
}
}
public static void addAction(String id, long time, TaskAction action) {
Room room = roomsMap.get(id);
if (room != null) {
room.addAction(time, action);
}
}
}

View File

@ -0,0 +1,141 @@
package com.hivekion.room.bean;
import com.hivekion.common.uuid.IdUtils;
import com.hivekion.room.func.TaskAction;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import lombok.Data;
/**
* [类的简要说明]
* <p>
* [详细描述可选]
* <p>
*
* @author LiDongYU
* @since 2025/7/22
*/
@Data
public class Room implements AutoCloseable {
private ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
private ScheduledFuture<?> future;
private String roomId;
private Map<Long, Map<String, TaskAction>> actionMap = new ConcurrentHashMap<>();
//线程池
private final ExecutorService actionExecutor =
new ThreadPoolExecutor(
5, 5, // corePoolSize, maximumPoolSize
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<>(1000), // 有界队列只允许100个待执行任务
new ThreadPoolExecutor.AbortPolicy() // 超出直接抛异常
);
public Room(String roomId) {
this.roomId = roomId;
}
/**
* 剩余时间
*/
private AtomicLong duringTime = new AtomicLong(0);
private AtomicLong totalTime = new AtomicLong(0);
private int mag = 1;
//获取剩余时间
public long getDuringTime() {
return duringTime.get();
}
/**
* 启动
*
* @param time 总时间
*/
public void start(long time) {
totalTime.set(time);
startTask();
}
/**
* 停止
*/
public void stop() {
cancelTask();
}
/**
* 暂停
*/
public void pause() {
cancelTask();
}
public void resume() {
startTask();
}
/**
* 快进
*
* @param mag 放大倍数
*/
public void magChange(int mag) {
this.mag = mag;
}
// 启动定时任务
private void startTask() {
if (future == null || future.isCancelled()) {
future = scheduler.scheduleAtFixedRate(() -> {
long curTime = duringTime.addAndGet(this.mag); // 推荐用 addAndGet
Map<String, TaskAction> actions = actionMap.get(curTime);
if (actions != null && !actions.isEmpty()) {
// 先复制key避免并发删除问题
for (Map.Entry<String, TaskAction> entry : actions.entrySet()) {
actionExecutor.submit(entry.getValue()::doSomeThing);
}
// 全部执行后再清空
actions.clear();
// 或者 actionMap.remove(curTime); 如果你不需要重用这个 key
actionMap.remove(curTime);
}
}, 0, 1, TimeUnit.SECONDS);
}
}
// 取消定时任务
private void cancelTask() {
if (future != null && !future.isCancelled()) {
future.cancel(true);
}
}
public void addAction(long time, TaskAction action) {
actionMap.computeIfAbsent(time, k -> new ConcurrentHashMap<>())
.put(IdUtils.simpleUUID(), action);
}
@Override
public void close() throws Exception {
actionMap.clear();
if (future != null && !future.isCancelled()) {
future.cancel(true);
}
if (scheduler != null && !scheduler.isShutdown()) {
scheduler.shutdown();
}
}
}

View File

@ -1,6 +1,4 @@
package com.hivekion.scenario.bean;
import lombok.Data;
package com.hivekion.room.func;
/**
* [类的简要说明]
@ -11,7 +9,8 @@ import lombok.Data;
* @author LiDongYU
* @since 2025/7/22
*/
@Data
public class EquipInfo {
@FunctionalInterface
public interface TaskAction {
void doSomeThing();
}

View File

@ -1,14 +0,0 @@
package com.hivekion.scenario;
/**
* [类的简要说明]
* <p>
* [详细描述可选]
* <p>
*
* @author LiDongYU
* @since 2025/7/22
*/
public interface TaskFinishedCall {
void doneTask();
}

View File

@ -1,18 +0,0 @@
package com.hivekion.scenario.bean;
import java.util.List;
import lombok.Data;
/**
* [类的简要说明]
* <p>
* [详细描述可选]
* <p>
*
* @author LiDongYU
* @since 2025/7/22
*/
@Data
public class ArraysTag {
private List<GuidInfo> Array;
}

View File

@ -1,17 +0,0 @@
package com.hivekion.scenario.bean;
import lombok.Data;
/**
* [类的简要说明]
* <p>
* [详细描述可选]
* <p>
*
* @author LiDongYU
* @since 2025/7/22
*/
@Data
public class Group {
}

View File

@ -1,20 +0,0 @@
package com.hivekion.scenario.bean;
import lombok.Data;
/**
* [类的简要说明]
* <p>
* [详细描述可选]
* <p>
*
* @author LiDongYU
* @since 2025/7/22
*/
@Data
public class GuidInfo {
private String Deduc;
private String OrMin;
private String Text;
private String Uuid;
}

View File

@ -1,20 +0,0 @@
package com.hivekion.scenario.bean;
import com.alibaba.fastjson.JSONArray;
import lombok.Data;
/**
* [类的简要说明]
* <p>
* [详细描述可选]
* <p>
*
* @author LiDongYU
* @since 2025/7/22
*/
@Data
public class Mount {
private String Uuid;
private JSONArray MountsData;
private Integer MsgType;
}

View File

@ -1,19 +0,0 @@
package com.hivekion.scenario.bean;
import lombok.Data;
/**
* [类的简要说明]
* <p>
* [详细描述可选]
* <p>
*
* @author LiDongYU
* @since 2025/7/22
*/
@Data
public class PostInfo {
private Integer PostCount;
private String PostName;
private Integer PostId;
}

View File

@ -1,19 +0,0 @@
package com.hivekion.scenario.bean;
import com.alibaba.fastjson2.JSONObject;
import lombok.Data;
/**
* [类的简要说明]
* <p>
* [详细描述可选]
* <p>
*
* @author LiDongYU
* @since 2025/7/22
*/
@Data
public class Power {
private PowerUnion Power;
private PowerTask Task;
}

View File

@ -1,21 +0,0 @@
package com.hivekion.scenario.bean;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import java.util.List;
import lombok.Data;
/**
* [类的简要说明]
* <p>
* [详细描述可选]
* <p>
*
* @author LiDongYU
* @since 2025/7/22
*/
@Data
public class PowerSet {
private List<ArraysTag> FightPower;
private List<ArraysTag> SafeguardPower;
}

View File

@ -1,19 +0,0 @@
package com.hivekion.scenario.bean;
import com.alibaba.fastjson2.JSONArray;
import lombok.Data;
/**
* [类的简要说明]
* <p>
* [详细描述可选]
* <p>
*
* @author LiDongYU
* @since 2025/7/22
*/
@Data
public class PowerTask {
private PowerTaskInfo Blue;
private PowerTaskInfo Red;
}

View File

@ -1,20 +0,0 @@
package com.hivekion.scenario.bean;
import com.alibaba.fastjson2.JSONArray;
import java.util.List;
import lombok.Data;
/**
* [类的简要说明]
* <p>
* [详细描述可选]
* <p>
*
* @author LiDongYU
* @since 2025/7/22
*/
@Data
public class PowerTaskInfo {
private List<ArraysTag> FightTask;
private List<ArraysTag> SafeguardTask;
}

View File

@ -1,18 +0,0 @@
package com.hivekion.scenario.bean;
import lombok.Data;
/**
* [类的简要说明]
* <p>
* [详细描述可选]
* <p>
*
* @author LiDongYU
* @since 2025/7/22
*/
@Data
public class PowerUnion {
private PowerSet Blue;
private PowerSet Red;
}

View File

@ -1,95 +0,0 @@
package com.hivekion.scenario.bean;
import lombok.Data;
/**
* [类的简要说明]
* <p>
* [详细描述可选]
* <p>
*
* @author LiDongYU
* @since 2025/7/22
*/
@Data
public class RegulationsRule {
private Integer KeepDistanceTarget;
private Boolean AttackDefendElecPowerEdit;
private Integer WeaControlToDive;
private Integer WeaControlToGround;
private Integer OilProvide;
private Integer AutoEvasion;
private Integer UseNWeapon;
private Boolean AlliedForcesOilProvideEdit;
private Integer WarAppearTarget;
private Integer OilStatusReturn;
private Boolean DiscardAmmunitionEdit;
private Integer AttackWeaponReturn;
private Integer UseShipAirMissile;
private Boolean WarAppearTargetEdit;
private Boolean OilStatusReturnEdit;
private Integer QuickDispatch;
private Integer AttackNeglectPlanLine;
private Boolean UseAIPPropulsionEdit;
private Integer DamageLevelRedeploy;
private Boolean WarFuzzyPositionTargetEdit;
private Integer AirActionTempo;
private Boolean SelectUnitOilProvideEdit;
private Boolean UnderAttckNeglectElecEdit;
private Integer WarFuzzyPositionTarget;
private Boolean UseNWeaponEdit;
private Integer WeaControlToSky;
private Integer DiscardAmmunition;
private Boolean SurveyMenaceToDiveEdit;
private Boolean WeaponStatusReturnEdit;
private Boolean OilStatusPlanEdit;
private Integer DeducType;
private Boolean VoyageCenterElecPowerEdit;
private Boolean OilProvideEdit;
private Integer SelectUnitOilProvide;
private Integer OilRedeploy;
private Integer UnderAttckNeglectElec;
private Integer DefendWeaponRedeploy;
private Boolean TorpedoPowerRangeEdit;
private Integer AutoLoadingTime;
private Integer AttackDefendElecPower;
private Boolean KeepDistanceTargetEdit;
private Integer UseAIPPropulsion;
private Integer OilReturn;
private Boolean WeaponStatusPlanEdit;
private Integer OilStatusPlan;
private Boolean HangSonarEdit;
private Integer SkyToGroundShot;
private Integer HangSonar;
private Integer Radar;
private Integer VoyageCenterElecPower;
private Boolean QuickDispatchEdit;
private Integer TorpedoPowerRange;
private Boolean AutoLoadingTimeEdit;
private Integer WeaControlToSea;
private Integer AlliedForcesOilProvide;
private Boolean AvoidSearchElementEdit;
private Boolean AttackNeglectPlanLineEdit;
private Integer Sonar;
private Boolean WeaControlToGroundEdit;
private Boolean WeaControlToDiveEdit;
private Boolean WeaControlToSeaEdit;
private Integer MsgType;
private Boolean AirActionTempoEdit;
private Boolean SkyToGroundShotEdit;
private Boolean WeaControlToSkyEdit;
private Integer AvoidSearchElement;
private Integer SurveyMenaceToDive;
private Integer AttackWeaponRedeploy;
private Boolean ConsistentSuperiors;
private Integer DefendWeaponReturn;
private Integer WeaponStatusReturn;
private Boolean AutoEvasionEdit;
private Integer Jammer;
private Integer WeaponStatusPlan;
private Integer Laser;
private Integer DamageLevelReturn;
private Integer RuleLevelType;
private Boolean UseShipAirMissileEdit;
}

View File

@ -1,21 +0,0 @@
package com.hivekion.scenario.bean;
import com.alibaba.fastjson.JSONArray;
import lombok.Data;
/**
* [类的简要说明]
* <p>
* [详细描述可选]
* <p>
*
* @author LiDongYU
* @since 2025/7/22
*/
@Data
public class Route {
private String Uuid;
private JSONArray FlyPath;
private Integer MsgType;
private JSONArray SupportPath;
}

View File

@ -1,68 +0,0 @@
package com.hivekion.scenario.bean;
import com.alibaba.fastjson.JSONArray;
import java.util.List;
import lombok.Data;
/**
* [类的简要说明]
* <p>
* [详细描述可选]
* <p>
*
* @author LiDongYU
* @since 2025/7/22
*/
@Data
public class ScenarioData {
private Integer continueTime;
private String planDesc;
private double leftDownLat;
private String treeList;
private String planName;
private double rightUpLon;
private double leftDownLon;
private long wasterTime;
private String planId;
private String startTime;
private String author;
private String planImage;
private double rightUpLat;
private String planTime;
private double leftUpLat;
private double rightDownLat;
private String startDate;
private double leftUpLon;
private String planDate;
private RegulationsRule regulationsRule;
private List<Unit> unitList; //编制
private List<Task> taskList;
private List<Weather> periodWeather;
private List<Route> routesList;
private List<Group> groupList;
private List<Mount> mountList;
private List<Sensors> sensorsList;
private Integer BlueGroupNum;
private String MetoEnvironment;
private JSONArray ProAreaList;
private Integer RedGroupNum;
private String WeatherInfo;
private JSONArray blockList;
private String scenTest;
}

View File

@ -1,20 +0,0 @@
package com.hivekion.scenario.bean;
import com.alibaba.fastjson.JSONArray;
import lombok.Data;
/**
* [类的简要说明]
* <p>
* [详细描述可选]
* <p>
*
* @author LiDongYU
* @since 2025/7/22
*/
@Data
public class Sensors {
private String Uuid;
private Integer MsgType;
private JSONArray SensorsData;
}

View File

@ -1,24 +0,0 @@
package com.hivekion.scenario.bean;
import com.alibaba.fastjson.JSONObject;
import lombok.Data;
/**
* [类的简要说明]
* <p>
* [详细描述可选]
* <p>
*
* @author LiDongYU
* @since 2025/7/22
*/
@Data
public class Task {
private JSONObject TargetDetailListInfo;
private JSONObject UnitAllocation;
private JSONObject TaskBaseInfo;
private String Guid;
private Integer MsgType;
private Integer DeducType;
private JSONObject RuleSetInfo;
}

View File

@ -1,21 +0,0 @@
package com.hivekion.scenario.bean;
import java.util.List;
import lombok.Data;
/**
* [类的简要说明]
* <p>
* [详细描述可选]
* <p>
*
* @author LiDongYU
* @since 2025/7/22
*/
@Data
public class TeamPeoWeaInfo {
private Integer OrganId;
private String OrganName;
private List<EquipInfo> EquipInfo;
private List<PostInfo> PostInfo;
}

View File

@ -1,131 +0,0 @@
package com.hivekion.scenario.bean;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import java.math.BigDecimal;
import java.util.List;
import lombok.Data;
/**
* [类的简要说明]
* <p>
* [详细描述可选]
* <p>
*
* @author LiDongYU
* @since 2025/7/22
*/
@Data
@JsonInclude(Include.ALWAYS)
public class Unit {
private Integer ChemicalEquipNum;
private Integer LogisticsSupportType;
private Integer TeamProvisionFoodInfo;
private Integer GenericEquipNum;
private Integer EngineerConsume;
private Integer CarEquipNum;
private String TrainLevel;
private Integer MinesweepAmmunitionInfo;
private Integer AirEquipNum;
private Integer PeoShroudBuryConsume;
private Integer DamageTargetType;
private Integer PeoBloodMedicalConsume;
private Integer AntitankAmmunitionConsume;
private BigDecimal Longitude;
private Integer MinesweepTotalConsume;
private Integer LightAmmunitionConsume;
private Integer PressAmmunitionInfo;
private Integer HitTarget;
private Integer TeamPeopleNum;
private Integer TeamSupportType;
private Integer TeamFieldOperationsFoodInfo;
private Integer TeamBurialBagInfo;
private String FormationName;
private Integer AntitankAmmunitionInfo;
private Boolean ElecStatus;
private Integer TeamBloodInfo;
private String UnitTeamTreeInfo;
private Integer AntitankTotalConsume;
private Integer OilWheelEquipNum;
private Integer WaterSafeDay;
private Integer StrikePosition;
private Integer PressAmmunitionConsume;
private Integer SuppressConsume;
private Integer ModelScale;
private Integer MaterialStrike;
private Integer ChemicalTotalConsume;
private Integer LightAmmunitionInfo;
private String Rname;
private Integer MsgType;
private Integer PressTotalConsume;
private Integer EngineerEquipNum;
private Integer TeamMedicinalInfo;
private Integer ExplosivesTotalConsume;
private Integer ArmorEquipNum;
private Integer PeoHerbMedicalConsume;
private Integer AirAmmunitionConsume;
private Integer LogisticsAspectType;
private Integer LaserCalType;
private Integer EquipOilConsume;
private Integer HurtPeopleNum;
private Integer ModelSizeChangeMultiple;
private Integer ChemicalConsume;
private Integer PeoFieldOperationsFoodConsume;
private BigDecimal Latitude;
private String Creator;
private Integer FoodSafeDay;
private String Guid;
private String Name;
private Integer TeamQuiltInfo;
private Integer DamageRusult;
private Integer SmokeFireTotalConsume;
private Integer SmokeFireAmmunitionConsume;
private Boolean FoodStatus;
private Integer UnitType;
private Integer ChemicalAmmunitionInfo;
private Integer PeoWaterConsume;
private Integer OilArmorEquipNum;
private BigDecimal Course;
private Integer AirConsume;
private Boolean OrNotWaterCar;
private Integer AirAmmunitionInfo;
private String Flag;
private Integer EntityType;
private Integer InveEquipNum;
private Integer LightTotalConsume;
private String State;
private JSONArray FightActionInfo;
private Integer TeamEquipNum;
private Integer DeducType;
private Integer InveConsume;
private Integer ReactorConsume;
private Integer ElecSafeDay;
private Integer ExplosivesAmmunitionInfo;
private BigDecimal TeamWaterInfo;
private Integer ArmorConsume;
private Integer ChemicalAmmunitionConsume;
private Integer GenericConsume;
private Integer MinesweepAmmunitionConsume;
private Integer SmokeFireAmmunitionInfo;
private Integer PeoProvisionFoodConsume;
private Integer OilInfo;
private Integer ExplosivesAmmunitionConsume;
private Boolean MedicalStatus;
private Boolean WaterStatus;
private Integer SuppressEquipNum;
private BigDecimal Height;
private Integer DeadPeopleNum;
private Integer PeoQuiltConsume;
private Integer ReactorEquipNum;
private Integer Speed;
private String Uuid;
private Integer CarConsume;
private Integer ThirdFunctionState;
private Integer MedicalSafeDay;
private Integer AirTotalConsume;
private List<TeamPeoWeaInfo> TeamPeoWeaInfo;
private RegulationsRule RegulationsRule;
}

View File

@ -1,18 +0,0 @@
package com.hivekion.scenario.bean;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
/**
* [类的简要说明]
* <p>
* [详细描述可选]
* <p>
*
* @author LiDongYU
* @since 2025/7/22
*/
@JsonInclude(Include.ALWAYS)
public class Weather {
}

View File

@ -0,0 +1,75 @@
package com.hivekion.scenario.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hivekion.common.entity.ResponseData;
import com.hivekion.common.uuid.IdUtils;
import com.hivekion.scenario.entity.BattleSupplier;
import com.hivekion.scenario.entity.ScenarioResource;
import com.hivekion.scenario.service.IBattleSupplierService;
import com.hivekion.scenario.service.ScenarioResourceService;
import com.hivekion.team.entity.Teaminfo;
import com.hivekion.team.service.ITeaminfoService;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* <p>
* 前端控制器
* </p>
*
* @author liDongYu
* @since 2025-09-15
*/
@Controller
@RequestMapping("/battleSupplier")
public class BattleSupplierController {
@Resource
private IBattleSupplierService battleSupplierService;
@Resource
private ITeaminfoService teamInfoService;
@Resource
private ScenarioResourceService resourceService;
@PostMapping("/save")
public ResponseData<Void> save(@RequestBody BattleSupplier battleSupplier) {
if (battleSupplier.getId() == null) {
battleSupplier.setId(IdUtils.simpleUUID());
battleSupplierService.save(battleSupplier);
} else {
battleSupplierService.updateById(battleSupplier);
}
return ResponseData.success(null);
}
@GetMapping("/remove/{id}")
public ResponseData<Void> remove(@PathVariable String id) {
battleSupplierService.removeById(id);
return ResponseData.success(null);
}
@GetMapping("/list")
public ResponseData<List<BattleSupplier>> list(String supplierId) {
Map<Integer, Teaminfo> map = teamInfoService.teamInfoMap();
Map<String, ScenarioResource> resourceMap = resourceService.resourceMap();
QueryWrapper<BattleSupplier> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("supplier_resource_id", supplierId);
List<BattleSupplier> list = battleSupplierService.list(queryWrapper);
list.forEach(item -> {
if (resourceMap.get(item.getBattleResourceId()) != null) {
ScenarioResource resource = resourceMap.get(item.getBattleResourceId());
if (map.get(resource.getResourceId()) != null) {
item.setSupplierResourceName(map.get(resource.getResourceId()).getName());
}
}
});
return ResponseData.success(list);
}
}

View File

@ -0,0 +1,37 @@
package com.hivekion.scenario.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hivekion.common.entity.ResponseData;
import com.hivekion.scenario.entity.RoomLog;
import com.hivekion.scenario.service.IRoomLogService;
import java.util.List;
import javax.annotation.Resource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* <p>
* 前端控制器
* </p>
*
* @author liDongYu
* @since 2025-09-17
*/
@RestController
@RequestMapping("/scenario/roomLog")
public class RoomLogController {
@Resource
private IRoomLogService roomLogService;
@GetMapping("/list")
public ResponseData<List<RoomLog>> list(String roomId) {
QueryWrapper<RoomLog> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("room_id", roomId==null?"0":roomId);
queryWrapper.orderByAsc("log_time");
queryWrapper.last("limit 10");
List<RoomLog> roomLogs = roomLogService.list(queryWrapper);
return ResponseData.success(roomLogs);
}
}

View File

@ -9,13 +9,16 @@ import com.hivekion.common.entity.ResponseData;
import com.hivekion.common.enums.ResultCodeEnum;
import com.hivekion.common.security.SecurityUtils;
import com.hivekion.common.uuid.IdUtils;
import com.hivekion.enums.ScenarioRoomStatusEnum;
import com.hivekion.scenario.bean.ScenarioWsParam;
import com.hivekion.scenario.entity.RoomLog;
import com.hivekion.scenario.entity.ScenarioRoom;
import com.hivekion.scenario.service.ScenarioRoomService;
import com.hivekion.scenario.service.ScenarioTaskService;
import io.swagger.annotations.ApiOperation;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
@ -38,12 +41,14 @@ import org.springframework.web.bind.annotation.RestController;
@RequestMapping("/scenario/room")
public class ScenarioRoomController extends BaseController {
@Resource
private ScenarioTaskService scenarioTaskService;
@Resource
private ScenarioRoomService scenarioRoomService;
@Resource
private ScenarioService scenarioService;
@Resource
private ScenarioTaskService scenarioTaskService;
/**
* 查询想定列表
*
@ -52,11 +57,16 @@ public class ScenarioRoomController extends BaseController {
@ApiOperation(value = "分页查询房间列表", notes = "")
@GetMapping("/list")
public PagedResultVo<ScenarioRoom> list(ScenarioRoom search) {
Map<Integer, Scenario> scenarioMap = scenarioService.scenarioMap();
//设置开始索引
search.setStart(search.getPageSize() * (search.getPageNum() - 1));
//查询结果列表
List<ScenarioRoom> list = scenarioRoomService.list(search);
for (ScenarioRoom scenarioRoom : list) {
if (scenarioMap.get(scenarioRoom.getScenarioId()) != null) {
scenarioRoom.setScenarioName(scenarioMap.get(scenarioRoom.getScenarioId()).getName());
}
}
//查询总数
Long total = scenarioRoomService.count(search);
return list(search, list, total);
@ -87,24 +97,31 @@ public class ScenarioRoomController extends BaseController {
public ResponseData<Void> start(@RequestBody ScenarioRoom room) {
//验证
Scenario scenario = scenarioService.getScenarioById(room.getScenarioId());
if(scenario==null){
return ResponseData.generator(ResultCodeEnum.PARAMETER_ERROR.getCode(),"想定不存在",null);
if (scenario == null) {
return ResponseData.generator(ResultCodeEnum.PARAMETER_ERROR.getCode(), "想定不存在", null);
}
if(scenarioRoomService.getById(room.getId())==null){
return ResponseData.generator(ResultCodeEnum.PARAMETER_ERROR.getCode(),"房间不存在",null);
};
if (scenarioRoomService.getById(room.getId()) == null) {
return ResponseData.generator(ResultCodeEnum.PARAMETER_ERROR.getCode(), "房间不存在", null);
}
Global.roomLogQueue.add(RoomLog.createRoomLog(room.getId(),"启动想定",SecurityUtils.getCurrentLoginUser().getUsername())) ;
scenarioRoomService.updateStatus(room.getId(), ScenarioRoomStatusEnum.STARTED.getCode());
scenarioTaskService.start(room.getScenarioId(), room.getId());
return ResponseData.success(null);
}
@PostMapping("/break")
public ResponseData<Void> breakAWhile(@RequestBody ScenarioRoom room) {
Global.roomLogQueue.add(RoomLog.createRoomLog(room.getId(),"暂停想定",SecurityUtils.getCurrentLoginUser().getUsername())) ;
scenarioRoomService.updateStatus(room.getId(), ScenarioRoomStatusEnum.BROKEN.getCode());
scenarioTaskService.sleepWhile(room.getScenarioId(), room.getId());
return ResponseData.success(null);
}
@PostMapping("/wakeUp")
public ResponseData<Void> wakeUp(@RequestBody ScenarioRoom room) {
Global.roomLogQueue.add(RoomLog.createRoomLog(room.getId(),"想定继续",SecurityUtils.getCurrentLoginUser().getUsername())) ;
scenarioRoomService.updateStatus(room.getId(), ScenarioRoomStatusEnum.STARTED.getCode());
scenarioTaskService.wakeup(room.getScenarioId(), room.getId());
return ResponseData.success(null);
}
@ -112,7 +129,7 @@ public class ScenarioRoomController extends BaseController {
@PostMapping("/mag")
public ResponseData<Void> mag(@RequestBody ScenarioRoom room) {
synchronized (this) {
Global.roomLogQueue.add(RoomLog.createRoomLog(room.getId(),"想定加速/减速",SecurityUtils.getCurrentLoginUser().getUsername())) ;
if (Global.roomParamMap.get(room.getScenarioId() + "_" + room.getId()) == null) {
Global.roomParamMap.put(room.getScenarioId() + "_" + room.getId(), new ScenarioWsParam());
}
@ -122,8 +139,13 @@ public class ScenarioRoomController extends BaseController {
return ResponseData.success(null);
}
@PostMapping("/stop")
public ResponseData<Void> stop(@RequestBody ScenarioRoom room) {
Global.roomLogQueue.add(RoomLog.createRoomLog(room.getId(),"想定结束",SecurityUtils.getCurrentLoginUser().getUsername())) ;
scenarioRoomService.updateStatus(room.getId(), ScenarioRoomStatusEnum.FINISHED.getCode());
scenarioTaskService.stop(room.getScenarioId(), room.getId());
return ResponseData.success(null);
}

View File

@ -0,0 +1,34 @@
package com.hivekion.scenario.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import java.io.Serializable;
import lombok.Data;
/**
* <p>
*
* </p>
*
* @author liDongYu
* @since 2025-09-15
*/
@TableName("TBL_BATTLE_SUPPLIER")
@ApiModel(value = "BattleSupplier对象", description = "")
@Data
public class BattleSupplier implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(type = IdType.INPUT)
private String id;
@TableField(value = "battle_resource_id")
private String battleResourceId;
@TableField(value = "supplier_resource_id")
private String supplierResourceId;
private String supplierResourceName;
}

View File

@ -0,0 +1,45 @@
package com.hivekion.scenario.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import java.io.Serializable;
import java.time.LocalDateTime;
import lombok.Data;
/**
* <p>
*
* </p>
*
* @author liDongYu
* @since 2025-09-17
*/
@TableName("TBL_ROOM_LOG")
@ApiModel(value = "RoomLog对象", description = "")
@Data
public class RoomLog implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(type = IdType.INPUT)
private String id;
@TableField(value = "room_id")
private String roomId;
@TableField(value = "log_time")
private LocalDateTime logTime;
private String message;
@TableField(value = "user_name")
private String userName;
public static RoomLog createRoomLog(String roomId, String message, String userName) {
RoomLog roomLog = new RoomLog();
roomLog.setRoomId(roomId);
roomLog.setLogTime(LocalDateTime.now());
roomLog.setMessage(message);
roomLog.setUserName(userName);
return roomLog;
}
}

View File

@ -38,5 +38,8 @@ public class ScenarioRoom extends SearchInputVo {
private LocalDateTime createTime;
@TableField(exist = false)
private Integer mag;
private Integer status = 0;
@TableField(exist = false)
private String scenarioName;
}

View File

@ -0,0 +1,16 @@
package com.hivekion.scenario.mapper;
import com.hivekion.scenario.entity.BattleSupplier;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* Mapper 接口
* </p>
*
* @author liDongYu
* @since 2025-09-15
*/
public interface BattleSupplierMapper extends BaseMapper<BattleSupplier> {
}

View File

@ -0,0 +1,16 @@
package com.hivekion.scenario.mapper;
import com.hivekion.scenario.entity.RoomLog;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* Mapper 接口
* </p>
*
* @author liDongYu
* @since 2025-09-17
*/
public interface RoomLogMapper extends BaseMapper<RoomLog> {
}

View File

@ -0,0 +1,19 @@
package com.hivekion.scenario.service;
import com.hivekion.scenario.entity.BattleSupplier;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
import java.util.Set;
/**
* <p>
* 服务类
* </p>
*
* @author liDongYu
* @since 2025-09-15
*/
public interface IBattleSupplierService extends IService<BattleSupplier> {
public Set<String> getBattleResourceBySupplierId(String id);
public Set<String> getSupplierIdByBattleId(String id);
}

View File

@ -0,0 +1,16 @@
package com.hivekion.scenario.service;
import com.hivekion.scenario.entity.RoomLog;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* <p>
* 服务类
* </p>
*
* @author liDongYu
* @since 2025-09-17
*/
public interface IRoomLogService extends IService<RoomLog> {
}

View File

@ -15,5 +15,6 @@ import java.util.List;
public interface ScenarioRoomService extends IService<ScenarioRoom> {
List<ScenarioRoom> list(ScenarioRoom room);
Long count(ScenarioRoom room);
void updateStatus(String id,Integer status);
}

View File

@ -17,5 +17,6 @@ public interface ScenarioTaskService extends IService<ScenarioTask> {
void stop(Integer id,String roomId);
void sleepWhile(Integer id,String roomId);
void wakeup(Integer id,String roomId);
List<ScenarioTask> queryTaskList(ScenarioTask task);
}

View File

@ -1,30 +0,0 @@
package com.hivekion.scenario.service;
import com.hivekion.baseData.entity.Scenario;
import com.hivekion.scenario.TaskFinishedCall;
import com.hivekion.scenario.entity.ScenarioTask;
import java.util.List;
/**
* [类的简要说明]
* <p>
* [详细描述可选]
* <p>
*
* @author LiDongYU
* @since 2025/7/22
*/
public interface TaskLogicService {
//移动任务
void handleMoveTask(ScenarioTask task, Scenario scenario, String roomId,double speed,
TaskFinishedCall call);
//战斗任务
void handleBattleTask(ScenarioTask task, Scenario scenario, String roomId,
List<Integer> injuredTimeList);
//保障任务
void supplierTask(ScenarioTask task,Scenario scenario, String roomId);
}

View File

@ -0,0 +1,41 @@
package com.hivekion.scenario.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hivekion.scenario.entity.BattleSupplier;
import com.hivekion.scenario.mapper.BattleSupplierMapper;
import com.hivekion.scenario.service.IBattleSupplierService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import org.springframework.stereotype.Service;
/**
* <p>
* 服务实现类
* </p>
*
* @author liDongYu
* @since 2025-09-15
*/
@Service
public class BattleSupplierServiceImpl extends ServiceImpl<BattleSupplierMapper, BattleSupplier> implements IBattleSupplierService {
@Override
public Set<String> getBattleResourceBySupplierId(String id) {
QueryWrapper<BattleSupplier> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("supplier_resource_id",id);
List<BattleSupplier> list = this.list(queryWrapper);
return list.stream().map(BattleSupplier::getBattleResourceId).collect(Collectors.toSet());
}
@Override
public Set<String> getSupplierIdByBattleId(String id) {
QueryWrapper<BattleSupplier> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("battle_resource_id",id);
List<BattleSupplier> list = this.list(queryWrapper);
return list.stream().map(BattleSupplier::getSupplierResourceId).collect(Collectors.toSet());
}
}

View File

@ -0,0 +1,20 @@
package com.hivekion.scenario.service.impl;
import com.hivekion.scenario.entity.RoomLog;
import com.hivekion.scenario.mapper.RoomLogMapper;
import com.hivekion.scenario.service.IRoomLogService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
* <p>
* 服务实现类
* </p>
*
* @author liDongYu
* @since 2025-09-17
*/
@Service
public class RoomLogServiceImpl extends ServiceImpl<RoomLogMapper, RoomLog> implements IRoomLogService {
}

View File

@ -1,10 +1,9 @@
package com.hivekion.scenario.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hivekion.scenario.entity.ScenarioRoom;
import com.hivekion.scenario.mapper.ScenarioRoomMapper;
import com.hivekion.scenario.service.ScenarioRoomService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import java.util.Collections;
import java.util.List;
import org.springframework.stereotype.Service;
@ -17,7 +16,8 @@ import org.springframework.stereotype.Service;
* @since 2025-09-03
*/
@Service
public class ScenarioRoomServiceImpl extends ServiceImpl<ScenarioRoomMapper, ScenarioRoom> implements
public class ScenarioRoomServiceImpl extends
ServiceImpl<ScenarioRoomMapper, ScenarioRoom> implements
ScenarioRoomService {
@Override
@ -30,4 +30,10 @@ public class ScenarioRoomServiceImpl extends ServiceImpl<ScenarioRoomMapper, Sce
return this.baseMapper.count(room);
}
@Override
public void updateStatus(String id, Integer status) {
ScenarioRoom room = this.getById(id);
room.setStatus(status);
updateById(room);
}
}

View File

@ -1,6 +1,5 @@
package com.hivekion.scenario.service.impl;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hivekion.Global;
@ -9,16 +8,12 @@ import com.hivekion.baseData.entity.WeatherResource;
import com.hivekion.baseData.service.IWeatherResourceService;
import com.hivekion.baseData.service.ScenarioService;
import com.hivekion.common.entity.ResponseCmdInfo;
import com.hivekion.common.redis.RedisUtil;
import com.hivekion.room.RoomManager;
import com.hivekion.scenario.entity.ScenarioTask;
import com.hivekion.scenario.mapper.ScenarioTaskMapper;
import com.hivekion.scenario.service.ScenarioTaskService;
import com.hivekion.scenario.service.TaskLogicService;
import com.hivekion.thread.SpringGlobalTaskManager;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
@ -38,235 +33,42 @@ public class ScenarioTaskServiceImpl extends
ServiceImpl<ScenarioTaskMapper, ScenarioTask> implements
ScenarioTaskService {
@Resource
private SpringGlobalTaskManager springGlobalTaskManager;
@Resource
private RedisUtil redisUtil;
@Resource
private ScenarioService scenarioService;
@Resource
private IWeatherResourceService weatherResourceService;
@Resource
private TaskLogicService taskLogicService;
@Override
public void start(Integer scenarioId, String roomId) {
log.info("scenarioId::{},roomId::{}", scenarioId, roomId);
Scenario currentScenario = scenarioService.getScenarioById(scenarioId);
//想定当前持续时间
redisUtil.hset(roomId + "_" + scenarioId, "duringTime", "0");
//想定当前状态
redisUtil.hset(roomId + "_" + scenarioId, "status", "running");
//查询天气数据
List<WeatherResource> weatherList = weatherResourceService.list(
new QueryWrapper<WeatherResource>()
.eq("scenario_id", scenarioId));
//放入天气数据
redisUtil.hset(roomId + "_" + scenarioId, "weather", JSONArray.toJSONString(weatherList));
//查询任务
ScenarioTask queryTask = new ScenarioTask();
queryTask.setScenarioId(scenarioId);
redisUtil.hset(roomId + "_" + scenarioId, "taskList",
JSONArray.toJSONString(queryTaskList(queryTask)));
new Thread(() -> {
springGlobalTaskManager.startPerSecondTask(roomId + "_" + scenarioId + "_task", () -> {
//时间累计
increaseTime(currentScenario, roomId);
//天气触发
weatherTrigger(currentScenario, roomId);
//任务触发
// taskTrigger(currentScenario, roomId);
});
}).start();
//查询想定的持续时间
Scenario scenario = scenarioService.getScenarioById(scenarioId);
if (scenario != null) {
long duringTime = Duration.between(scenario.getStartTime(), scenario.getEndTime())
.getSeconds();
RoomManager.startRoom(roomId, duringTime);
addWeatherEvent(scenario, roomId);
addTaskEvent(scenario, roomId);
}
}
@Override
public void stop(Integer id, String roomId) {
if (Global.roomParamMap.get(id + "_" + roomId) != null) {
Global.roomParamMap.get(id + "_" + roomId).setMag(1);
}
springGlobalTaskManager.cancelTask(roomId + "_" + id + "_task");
RoomManager.stopRoom(roomId);
}
@Override
public void sleepWhile(Integer id, String roomId) {
redisUtil.hset(roomId + "_" + id, "states", "sleep");
RoomManager.stopRoom(roomId);
}
@Override
public void wakeup(Integer id, String roomId) {
redisUtil.hset(roomId + "_" + id, "states", "running");
RoomManager.resumeRoom(roomId);
}
private void increaseTime(Scenario currentScenario, String roomId) {
try {
int mag = Global.roomParamMap.get(currentScenario.getId() + "_" + roomId) == null ? 1
: Global.roomParamMap.get(currentScenario.getId() + "_" + roomId).getMag();
//获取当前状态
Object statusObj = redisUtil.hget(roomId + "_" + currentScenario.getId(), "status");
log.info("scenario_id:{},status::{}", currentScenario.getId(), statusObj);
if (statusObj != null && statusObj.toString().equals("running")) {
int duringTime = getCurrentDuringTime(currentScenario, roomId);
duringTime = duringTime + mag;
log.info("duringTime::{}", duringTime);
redisUtil.hset(roomId + "_" + currentScenario.getId(), "duringTime", duringTime + "");
}
} catch (
Exception e) {
log.error("error::", e);
}
}
/**
* 天气触发
*
* @param currentScenario 当前想定
* @param roomId 房间ID
*/
private void weatherTrigger(Scenario currentScenario, String roomId) {
try {
String weatherResources = (String) redisUtil.hget(roomId + "_" + currentScenario.getId(),
"weather");
List<WeatherResource> weatherList = JSONArray.parseArray(weatherResources,
WeatherResource.class);
int duringTime = getCurrentDuringTime(currentScenario, roomId);
for (WeatherResource resource : weatherList) {
if ("init".equals(resource.getStatus())) {
if (currentScenario.getStartTime().plusSeconds(duringTime)
.isAfter(resource.getLastBegTime())) {
log.info("{}", "start_" + resource.getWeatherType());
resource.setStatus("running");
ResponseCmdInfo<Void> responseCmdInfo = new ResponseCmdInfo<>();
responseCmdInfo.setScenarioId(currentScenario.getId());
responseCmdInfo.setRoom(roomId);
responseCmdInfo.setCmdType("start_" + resource.getWeatherType());
responseCmdInfo.setScenarioId(currentScenario.getId());
responseCmdInfo.setRoom(roomId);
Global.sendCmdInfoQueue.add(responseCmdInfo);
}
}
if ("running".equals(resource.getStatus())) {
if (currentScenario.getStartTime().plusSeconds(duringTime)
.isAfter(resource.getLastEndTime())) {
log.info("{}", "stopped_" + resource.getWeatherType());
resource.setStatus("stopped");
ResponseCmdInfo<Void> responseCmdInfo = new ResponseCmdInfo<>();
responseCmdInfo.setScenarioId(currentScenario.getId());
responseCmdInfo.setRoom(roomId);
responseCmdInfo.setCmdType("stop_" + resource.getWeatherType());
responseCmdInfo.setScenarioId(currentScenario.getId());
responseCmdInfo.setRoom(roomId);
Global.sendCmdInfoQueue.add(responseCmdInfo);
}
}
}
redisUtil.hset(roomId + "_" + currentScenario.getId(), "weather",
JSONArray.toJSONString(weatherList));
} catch (Exception ex) {
log.error(ex.getMessage());
}
}
/**
* 获取当前想定从开始到现在时间
*
* @param scenario
* @param roomId
* @return
*/
private int getCurrentDuringTime(Scenario scenario, String roomId) {
Object duringTime = redisUtil.hget(roomId + "_" + scenario.getId(), "duringTime");
if (duringTime != null) {
return Integer.parseInt(duringTime.toString());
}
return 0;
}
private void taskTrigger(Scenario currentScenario, String roomId) {
try {
Object statusObj = redisUtil.hget(roomId + "_" + currentScenario.getId(), "status");
if (statusObj != null && statusObj.toString().equals("running")) {
Object taskListObj = redisUtil.hget(roomId + "_" + currentScenario.getId(), "taskList");
List<ScenarioTask> taskList = JSONArray.parseArray(taskListObj.toString(),
ScenarioTask.class);
for (ScenarioTask scenarioTask : taskList) {
int duringTime = getCurrentDuringTime(currentScenario, roomId);
log.info("task duringTime::{},{},{}", duringTime,
currentScenario.getStartTime().plusSeconds(duringTime), scenarioTask.getStartTime());
if (currentScenario.getStartTime().plusSeconds(duringTime)
.isAfter(scenarioTask.getStartTime())) {
switch (scenarioTask.getTaskType()) {
case "1":
taskLogicService.handleMoveTask(scenarioTask, currentScenario, roomId, 18.0,
null);
break;
case "2":
Random random = new Random();
List<Integer> randomIntList = new ArrayList<>();
long continueSeconds =
Duration.between(scenarioTask.getStartTime(), scenarioTask.getEndTime())
.toMinutes() * 60;
for (int i = 0; i < 5; i++) {
randomIntList.add(random.nextInt((int) continueSeconds) + 1);
}
taskLogicService.handleBattleTask(scenarioTask, currentScenario, roomId,
randomIntList);
break;
case "4":
case "5":
case "6":
case "7":
default:
log.info("start a type=7 task");
taskLogicService.supplierTask(scenarioTask, currentScenario, roomId);
}
}
}
redisUtil.hset(roomId + "_" + currentScenario.getId(), "taskList",
JSONArray.toJSONString(taskList));
}
} catch (Exception e) {
log.error("error::", e);
}
}
@Override
@ -279,4 +81,44 @@ public class ScenarioTaskServiceImpl extends
return this.list(queryWrapper);
}
/**
* 增加天气任务
*/
private void addWeatherEvent(Scenario scenario, String roomId) {
List<WeatherResource> weatherList = weatherResourceService.list();
for (WeatherResource weatherResource : weatherList) {
long diff = Duration.between(weatherResource.getLastBegTime(), scenario.getStartTime())
.getSeconds();
//开始
RoomManager.addAction(roomId, diff, () -> {
Global.sendCmdInfoQueue.add(
create("start_" + weatherResource.getWeatherType(), scenario, roomId));
});
//结束
long duringTime = Duration.between(weatherResource.getLastBegTime(),
weatherResource.getLastEndTime())
.getSeconds();
RoomManager.addAction(roomId, diff + duringTime, () -> {
Global.sendCmdInfoQueue.add(
create("stop_" + weatherResource.getWeatherType(), scenario, roomId));
});
}
}
private void addTaskEvent(Scenario scenario, String roomId) {
}
private ResponseCmdInfo<Void> create(String type, Scenario scenario, String roomId) {
ResponseCmdInfo<Void> responseCmdInfo = new ResponseCmdInfo<>();
responseCmdInfo.setScenarioId(scenario.getId());
responseCmdInfo.setRoom(roomId);
responseCmdInfo.setCmdType(type);
responseCmdInfo.setScenarioId(scenario.getId());
responseCmdInfo.setRoom(roomId);
return responseCmdInfo;
}
}

View File

@ -1,27 +1,6 @@
package com.hivekion.scenario.service.impl;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.hivekion.Global;
import com.hivekion.baseData.entity.Scenario;
import com.hivekion.common.MultiPointGeoPosition;
import com.hivekion.common.MultiPointGeoPosition.PositionResult;
import com.hivekion.common.entity.ResponseCmdInfo;
import com.hivekion.common.redis.RedisUtil;
import com.hivekion.scenario.TaskFinishedCall;
import com.hivekion.scenario.entity.ScenarioTask;
import com.hivekion.scenario.service.TaskLogicService;
import com.hivekion.statistic.bean.StatisticBean;
import com.hivekion.statistic.service.StatisticService;
import java.time.Duration;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
/**
* [类的简要说明]
@ -33,190 +12,156 @@ import org.springframework.web.reactive.function.client.WebClient;
* @since 2025/7/22
*/
@Service
public class TaskLogicServiceImpl implements TaskLogicService {
public class TaskLogicServiceImpl {
@Resource
private RedisUtil redisUtil;
@Value("${path.planning.url}")
private String pathPlanningUrl;
private final WebClient webClient = WebClient.create();
@Resource
private StatisticService statisticService;
private final static double fuelUseUpPerSecond = 0.1;
private final static double medicalUseUpPerSecond = 0.1;
private final static double ammunitionUsePerSecond = 0.1;
@Override
public void handleMoveTask(ScenarioTask scenarioTask, Scenario currentScenario, String roomId,
double speed, TaskFinishedCall call) {
ResponseCmdInfo<Map<String, Object>> cmdInfo = new ResponseCmdInfo<>();
Map<String, Object> dataMap = new HashMap<>();
cmdInfo.setData(dataMap);
dataMap.put("resourceId", scenarioTask.getResourceId());
cmdInfo.setScenarioId(scenarioTask.getScenarioId());
cmdInfo.setRoom(roomId);
if ("init".equals(scenarioTask.getStatus())) {
scenarioTask.setStatus("running");
String url = pathPlanningUrl + "?profile=car&point=" + scenarioTask.getFromLat() + ","
+ scenarioTask.getFromLng()
+ "&point=" + scenarioTask.getToLat() + "," + scenarioTask.getToLng()
+ "&points_encoded=false&algorithm=alternative_route&alternative_route.max_paths=3";
String result = webClient.get()
.uri(url)
.retrieve()
.bodyToMono(String.class)
.block();
com.alibaba.fastjson2.JSONObject resultObject = JSON.parseObject(result);
if (result != null) {
cmdInfo.setCmdType("init_path_planning");
dataMap.put("points", resultObject);
redisUtil.hset(roomId + "_" + currentScenario.getId(),
scenarioTask.getId() + "_path_points", result);
}
Global.sendCmdInfoQueue.add(cmdInfo);
//设置获取物资信息
StatisticBean statistic = statisticService.statistic(scenarioTask.getResourceId());
redisUtil.hset(roomId + "_" + currentScenario.getId(),
"resourceId_statistic_" + scenarioTask.getResourceId(), JSON.toJSONString(statistic));
} else if ("running".equals(scenarioTask.getStatus())) {
//消耗油料
StatisticBean statistic = getStatistic(scenarioTask, currentScenario, roomId);
//获取想定持续时间
int duringTime = getCurrentDuringTime(currentScenario, roomId);
long seconds =
duringTime - Duration.between(scenarioTask.getStartTime(), currentScenario.getStartTime())
.getSeconds();
if (seconds > 0) {
double useUp = seconds * fuelUseUpPerSecond;
statistic.getFuel().setCurrent(statistic.getFuel().getTotal() - useUp);
setStatistic(scenarioTask, currentScenario, roomId, statistic);
}
//更新坐标
// List<double[]> points = new ArrayList<>();
// cmdInfo.setCmdType("current_position");
// Object pathsObj = redisUtil.hget(roomId + "_" + currentScenario.getId(),
// scenarioTask.getId() + "_path_points");
// if (pathsObj != null) {
// JSONObject paths = JSONObject.parseObject(pathsObj.toString());
// @Resource
// private RedisUtil redisUtil;
// @Value("${path.planning.url}")
// private String pathPlanningUrl;
// private final WebClient webClient = WebClient.create();
// @Resource
// private StatisticService statisticService;
// private final static double fuelUseUpPerSecond = 0.1;
// private final static double medicalUseUpPerSecond = 0.1;
// private final static double ammunitionUsePerSecond = 0.1;
//
// com.alibaba.fastjson2.JSONArray pointsArray = paths.getJSONArray("paths").getJSONObject(0)
// .getJSONObject("points").getJSONArray("coordinates");
// @Override
// public void handleMoveTask(ScenarioTask scenarioTask, Scenario currentScenario, String roomId,
// double speed, TaskFinishedCall call) {
// ResponseCmdInfo<Map<String, Object>> cmdInfo = new ResponseCmdInfo<>();
// Map<String, Object> dataMap = new HashMap<>();
// cmdInfo.setData(dataMap);
// dataMap.put("resourceId", scenarioTask.getResourceId());
// cmdInfo.setScenarioId(scenarioTask.getScenarioId());
// cmdInfo.setRoom(roomId);
// if ("init".equals(scenarioTask.getStatus())) {
// scenarioTask.setStatus("running");
//
// for (int i = 0; i < pointsArray.size(); i++) {
// com.alibaba.fastjson2.JSONArray coordinateArray = pointsArray.getJSONArray(i);
// double[] data = new double[coordinateArray.size()];
// for (int j = 0; j < coordinateArray.size(); j++) {
// data[j] = coordinateArray.getDouble(j);
// }
// points.add(data);
// }
// }
// //查看当前想定持续的时间
// Object duringObj = redisUtil.hget(roomId + "_" + currentScenario.getId(),
// "duringTime");
// if (duringObj != null) {
// int oldValue = duringObj instanceof Integer ? (Integer) duringObj : 0;
// PositionResult result = MultiPointGeoPosition.getPosition(points, speed,
// oldValue);
// dataMap.put("currentPosition", result);
// if (result.reached) {
// if (call != null) {
// call.doneTask();
// }
// }
// String url = pathPlanningUrl + "?profile=car&point=" + scenarioTask.getFromLat() + ","
// + scenarioTask.getFromLng()
// + "&point=" + scenarioTask.getToLat() + "," + scenarioTask.getToLng()
// + "&points_encoded=false&algorithm=alternative_route&alternative_route.max_paths=3";
// String result = webClient.get()
// .uri(url)
// .retrieve()
// .bodyToMono(String.class)
// .block();
// com.alibaba.fastjson2.JSONObject resultObject = JSON.parseObject(result);
// if (result != null) {
// cmdInfo.setCmdType("init_path_planning");
//
//
// dataMap.put("points", resultObject);
//
// redisUtil.hset(roomId + "_" + currentScenario.getId(),
// scenarioTask.getId() + "_path_points", result);
// }
//
// Global.sendCmdInfoQueue.add(cmdInfo);
}
}
@Override
public void handleBattleTask(ScenarioTask task, Scenario scenario, String roomId,
List<Integer> injuredTime) {
StatisticBean statistic = getStatistic(task, scenario, roomId);
int duringTime = getCurrentDuringTime(scenario, roomId);
long seconds =
duringTime - Duration.between(task.getStartTime(), scenario.getStartTime())
.getSeconds();
if (seconds > 0) {
statistic.getMedical()
.setCurrent(statistic.getMedical().getTotal() - seconds * medicalUseUpPerSecond);
statistic.getAmmunition()
.setCurrent(statistic.getAmmunition().getTotal() - seconds * ammunitionUsePerSecond);
setStatistic(task, scenario, roomId, statistic);
}
//受伤
injuredTime.forEach(time -> {
if (time == seconds) {
if (statistic.getPerson().getCurrent() > 0) {
statistic.getPerson().setCurrent(statistic.getPerson().getCurrent() - 1);
}
}
});
//产生任务
setStatistic(task, scenario, roomId, statistic);
}
@Override
public void supplierTask(ScenarioTask task, Scenario scenario, String roomId) {
//运20速度
handleMoveTask(task, scenario, roomId, 217, () -> {
//更新想定的物资
});
}
private StatisticBean getStatistic(ScenarioTask task, Scenario scenario, String roomId) {
synchronized (this) {
Object statisticObj = redisUtil.hget(roomId + "_" + scenario.getId(),
"resourceId_statistic_" + task.getResourceId());
if (statisticObj != null) {
return JSON.parseObject(statisticObj.toString(), StatisticBean.class);
}
return new StatisticBean();
}
}
private void setStatistic(ScenarioTask task, Scenario scenario, String roomId,
StatisticBean bean) {
redisUtil.hset(roomId + "_" + scenario.getId(),
"resourceId_statistic_" + task.getResourceId(), JSON.toJSONString(bean));
//推送到前端
ResponseCmdInfo<Map<String, Object>> cmdInfo = new ResponseCmdInfo<>();
Map<String, Object> dataMap = new HashMap<>();
cmdInfo.setData(dataMap);
cmdInfo.setScenarioId(scenario.getId());
cmdInfo.setRoom(roomId);
dataMap.put("resourceId", task.getResourceId());
dataMap.put("statistic", bean);
Global.sendCmdInfoQueue.add(cmdInfo);
}
/**
* 获取当前想定从开始到现在时间
*
* @param scenario
* @param roomId
* @return
*/
private int getCurrentDuringTime(Scenario scenario, String roomId) {
Object duringTime = redisUtil.hget(roomId + "_" + scenario.getId(), "duringTime");
if (duringTime != null) {
return Integer.parseInt(duringTime.toString());
}
return 0;
}
// //设置获取物资信息
// StatisticBean statistic = statisticService.statistic(scenarioTask.getResourceId());
// redisUtil.hset(roomId + "_" + currentScenario.getId(),
// "resourceId_statistic_" + scenarioTask.getResourceId(), JSON.toJSONString(statistic));
// } else if ("running".equals(scenarioTask.getStatus())) {
//
// //消耗油料
// StatisticBean statistic = getStatistic(scenarioTask, currentScenario, roomId);
// //获取想定持续时间
// int duringTime = getCurrentDuringTime(currentScenario, roomId);
// long seconds =
// duringTime - Duration.between(scenarioTask.getStartTime(), currentScenario.getStartTime())
// .getSeconds();
// if (seconds > 0) {
// double useUp = seconds * fuelUseUpPerSecond;
// statistic.getFuel().setCurrent(statistic.getFuel().getTotal() - useUp);
// setStatistic(scenarioTask, currentScenario, roomId, statistic);
// }
//
// }
//
// }
//
// @Override
// public void handleBattleTask(ScenarioTask task, Scenario scenario, String roomId,
// List<Integer> injuredTime) {
// StatisticBean statistic = getStatistic(task, scenario, roomId);
// int duringTime = getCurrentDuringTime(scenario, roomId);
// long seconds =
// duringTime - Duration.between(task.getStartTime(), scenario.getStartTime())
// .getSeconds();
// if (seconds > 0) {
// statistic.getMedical()
// .setCurrent(statistic.getMedical().getTotal() - seconds * medicalUseUpPerSecond);
// statistic.getAmmunition()
// .setCurrent(statistic.getAmmunition().getTotal() - seconds * ammunitionUsePerSecond);
// setStatistic(task, scenario, roomId, statistic);
//
// }
// //受伤
// injuredTime.forEach(time -> {
// if (time == seconds) {
// if (statistic.getPerson().getCurrent() > 0) {
// statistic.getPerson().setCurrent(statistic.getPerson().getCurrent() - 1);
// }
//
// }
// });
// //产生任务
//
// setStatistic(task, scenario, roomId, statistic);
// }
//
//
// @Override
// public void supplierTask(ScenarioTask task, Scenario scenario, String roomId) {
//
// //运20速度
// handleMoveTask(task, scenario, roomId, 217, () -> {
// //更新想定的物资
// });
//
//
// }
//
// private StatisticBean getStatistic(ScenarioTask task, Scenario scenario, String roomId) {
// synchronized (this) {
// Object statisticObj = redisUtil.hget(roomId + "_" + scenario.getId(),
// "resourceId_statistic_" + task.getResourceId());
// if (statisticObj != null) {
// return JSON.parseObject(statisticObj.toString(), StatisticBean.class);
// }
// return new StatisticBean();
// }
// }
//
// private void setStatistic(ScenarioTask task, Scenario scenario, String roomId,
// StatisticBean bean) {
// redisUtil.hset(roomId + "_" + scenario.getId(),
// "resourceId_statistic_" + task.getResourceId(), JSON.toJSONString(bean));
// //推送到前端
// ResponseCmdInfo<Map<String, Object>> cmdInfo = new ResponseCmdInfo<>();
// Map<String, Object> dataMap = new HashMap<>();
// cmdInfo.setData(dataMap);
// cmdInfo.setScenarioId(scenario.getId());
// cmdInfo.setRoom(roomId);
// dataMap.put("resourceId", task.getResourceId());
// dataMap.put("statistic", bean);
// Global.sendCmdInfoQueue.add(cmdInfo);
// }
//
// /**
// * 获取当前想定从开始到现在时间
// *
// * @param scenario
// * @param roomId
// * @return
// */
// private int getCurrentDuringTime(Scenario scenario, String roomId) {
// Object duringTime = redisUtil.hget(roomId + "_" + scenario.getId(), "duringTime");
// if (duringTime != null) {
// return Integer.parseInt(duringTime.toString());
// }
// return 0;
// }
}

View File

@ -1,8 +1,11 @@
package com.hivekion.startup;
import com.hivekion.thread.HandleReceiveThread;
import com.hivekion.thread.HandleSendThread;
import com.hivekion.scenario.service.IRoomLogService;
import com.hivekion.thread.HandleReceiveRunnable;
import com.hivekion.thread.HandleSendRunable;
import com.hivekion.thread.RoomLogRunnable;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@ -18,11 +21,13 @@ import org.springframework.stereotype.Component;
@Component
@Slf4j
public class Init {
@Resource
private IRoomLogService roomLogService;
@PostConstruct
public void appInit() {
log.info("Init start");
new Thread(new HandleSendThread()).start();
new Thread(new HandleReceiveThread()).start();
new Thread(new HandleSendRunable()).start();
new Thread(new HandleReceiveRunnable()).start();
new Thread(new RoomLogRunnable(roomLogService)).start();
}
}

View File

@ -9,7 +9,7 @@ package com.hivekion.thread;
* @author LiDongYU
* @since 2025/7/22
*/
public class HandleReceiveThread implements Runnable {
public class HandleReceiveRunnable implements Runnable {
@Override
public void run() {

View File

@ -16,16 +16,16 @@ import lombok.extern.slf4j.Slf4j;
* @since 2025/7/22
*/
@Slf4j
public class HandleSendThread implements Runnable {
public class HandleSendRunable implements Runnable {
@Override
public void run() {
log.info("HandleSendThread start .....................");
while (!Thread.currentThread().isInterrupted()) {
try {
log.info("waiting message");
ResponseCmdInfo<?> response = Global.sendCmdInfoQueue.take();
log.info("send response");
WsServer.sendMessage(response.getScenarioId(), response.getRoom(), JSON.toJSONString(response));
} catch (Exception e) {
log.error("error::", e);

View File

@ -0,0 +1,39 @@
package com.hivekion.thread;
import com.hivekion.Global;
import com.hivekion.common.uuid.IdUtils;
import com.hivekion.scenario.entity.RoomLog;
import com.hivekion.scenario.service.IRoomLogService;
import lombok.extern.slf4j.Slf4j;
/**
* [类的简要说明]
* <p>
* [详细描述可选]
* <p>
*
* @author LiDongYU
* @since 2025/7/22
*/
@Slf4j
public class RoomLogRunnable implements Runnable {
private final IRoomLogService roomLogService;
public RoomLogRunnable(IRoomLogService roomLogService) {
this.roomLogService = roomLogService;
}
@Override
public void run() {
while(!Thread.currentThread().isInterrupted()){
try{
RoomLog roomLog = Global.roomLogQueue.take();
roomLog.setId(IdUtils.simpleUUID());
roomLogService.save(roomLog);
} catch (Exception e) {
log.error("error::",e);
}
}
}
}

View File

@ -1,5 +1,6 @@
package com.hivekion.thread;
import cn.hutool.extra.spring.SpringUtil;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;

View File

@ -0,0 +1,5 @@
<?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.hivekion.scenario.mapper.BattleSupplierMapper">
</mapper>

View File

@ -0,0 +1,5 @@
<?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.hivekion.scenario.mapper.RoomLogMapper">
</mapper>

View File

@ -1,14 +1,7 @@
package com.hivekion;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.hivekion.baseData.entity.ModuleStatus;
import com.hivekion.baseData.entity.Scenario;
import com.hivekion.baseData.service.ModuleStatusService;
import com.hivekion.baseData.service.ScenarioService;
import com.hivekion.scenario.bean.ScenarioData;
import java.io.UnsupportedEncodingException;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;

View File

@ -4,24 +4,7 @@ import cn.hutool.core.io.FileUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.hivekion.power.bean.ActionInfo;
import com.hivekion.power.bean.AmmunitionInfo;
import com.hivekion.power.bean.MaterialNumInfo;
import com.hivekion.power.bean.PersonStatisticInfo;
import com.hivekion.power.bean.PositionInfo;
import com.hivekion.power.bean.PowerBase;
import com.hivekion.power.bean.PowerGroup;
import com.hivekion.power.bean.ScenarioPowerData;
import com.hivekion.scenario.bean.ArraysTag;
import com.hivekion.scenario.bean.Power;
import com.hivekion.scenario.bean.PowerSet;
import com.hivekion.scenario.bean.ScenarioData;
import com.hivekion.scenario.bean.Unit;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* [类的简要说明]

View File

@ -1,68 +0,0 @@
package com.hivekion;
import com.alibaba.fastjson.JSONArray;
import com.hivekion.scenario.bean.Group;
import com.hivekion.scenario.bean.Mount;
import com.hivekion.scenario.bean.RegulationsRule;
import com.hivekion.scenario.bean.Route;
import com.hivekion.scenario.bean.Sensors;
import com.hivekion.scenario.bean.Task;
import com.hivekion.scenario.bean.Unit;
import com.hivekion.scenario.bean.Weather;
import java.util.List;
import lombok.Data;
/**
* [类的简要说明]
* <p>
* [详细描述可选]
* <p>
*
* @author LiDongYU
* @since 2025/7/22
*/
@Data
public class YY {
private Integer continueTime;
private String planDesc;
private double leftDownLat;
private String treeList;
private String planName;
private double rightUpLon;
private double leftDownLon;
private long wasterTime;
private String planId;
private String startTime;
private String author;
private String planImage;
private double rightUpLat;
private String planTime;
private double leftUpLat;
private double rightDownLat;
private String startDate;
private double leftUpLon;
private String planDate;
private String regulationsRule;
private List<Unit> unitList; //编制
// private List<Task> taskList;
// private List<Weather> periodWeather;
// private List<Route> routesList;
// private List<Group> groupList;
// private List<Mount> mountList;
// private List<Sensors> sensorsList;
//
//
//
// private Integer BlueGroupNum;
// private String MetoEnvironment;
// private JSONArray ProAreaList;
// private Integer RedGroupNum;
// private String WeatherInfo;
//
// private JSONArray blockList;
//
//
//
// private String scenTest;
}