Compare commits

...

6 Commits

Author SHA1 Message Date
李玉东
ab69a278a4 Merge branch 'main' of http://git.hivekion.com:3000/liyudong/simulation-backend 2025-09-21 02:51:16 +08:00
李玉东
dc3c091a7c 任务相关 2025-09-21 02:50:53 +08:00
李玉东
7859078d72 Merge branch 'main' of http://git.hivekion.com:3000/liyudong/simulation-backend
# Conflicts:
#	src/main/java/com/hivekion/room/bean/MoveTask.java
2025-09-21 02:22:12 +08:00
李玉东
ddf9e082f2 任务相关 2025-09-21 02:21:29 +08:00
李玉东
e636f7d248 Merge branch 'main' of http://git.hivekion.com:3000/liyudong/simulation-backend 2025-09-21 01:53:59 +08:00
李玉东
2d218d905c 任务相关 2025-09-21 01:53:44 +08:00
9 changed files with 248 additions and 196 deletions

View File

@ -10,12 +10,21 @@ import com.hivekion.baseData.service.ScenarioService;
import com.hivekion.common.MultiPointGeoPosition; import com.hivekion.common.MultiPointGeoPosition;
import com.hivekion.common.entity.ResponseCmdInfo; import com.hivekion.common.entity.ResponseCmdInfo;
import com.hivekion.common.redis.RedisUtil; import com.hivekion.common.redis.RedisUtil;
import com.hivekion.common.uuid.IdUtils;
import com.hivekion.enums.WsCmdTypeEnum; import com.hivekion.enums.WsCmdTypeEnum;
import com.hivekion.room.RoomManager; import com.hivekion.room.RoomManager;
import com.hivekion.room.func.TaskAction; import com.hivekion.room.func.TaskAction;
import com.hivekion.scenario.entity.ScenarioResource;
import com.hivekion.scenario.entity.ScenarioTask; import com.hivekion.scenario.entity.ScenarioTask;
import com.hivekion.scenario.service.impl.BattleSupplierServiceImpl;
import com.hivekion.scenario.service.impl.ScenarioTaskServiceImpl;
import com.hivekion.statistic.bean.EditScenarioInfo;
import com.hivekion.statistic.bean.ScenarioInfo; import com.hivekion.statistic.bean.ScenarioInfo;
import java.time.Duration; import com.hivekion.statistic.bean.StatisticBean;
import com.hivekion.statistic.service.impl.StatisticServiceImpl;
import com.hivekion.supplier.entity.SupplierRequest;
import com.hivekion.supplier.service.impl.SupplierRequestServiceImpl;
import java.time.LocalDateTime;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@ -24,10 +33,8 @@ import java.util.Map.Entry;
import java.util.NavigableMap; import java.util.NavigableMap;
import java.util.TreeMap; import java.util.TreeMap;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
@ -50,6 +57,11 @@ import org.springframework.web.reactive.function.client.WebClient;
@Slf4j @Slf4j
public abstract class AbtParentTask implements TaskAction { public abstract class AbtParentTask implements TaskAction {
/**
* 油料消耗速率
*/
protected double fuelConsumption = 0;
protected double fuelThreshold = 0;
/** /**
* 开始点坐标 * 开始点坐标
*/ */
@ -64,31 +76,33 @@ public abstract class AbtParentTask implements TaskAction {
protected final String roomId; protected final String roomId;
//http请求 //http请求
protected WebClient webClient = WebClient.create(); protected WebClient webClient = WebClient.create();
protected final AtomicBoolean canMoved = new AtomicBoolean(true);
protected final AtomicReference<Coordinate> coordinateReference = new AtomicReference<>();
protected final AtomicReference<Coordinate> coordinateReference = new AtomicReference<>();
/** /**
* 任务相对与想定的开始时间 * 需求产生标志
*/ */
private long taskRelativeTime = 0; private final AtomicBoolean requestFlag = new AtomicBoolean(false);
private StatisticBean statisticBean;
//线程池 //线程池
protected ThreadPoolExecutor executor = new ThreadPoolExecutor( // protected ThreadPoolExecutor executor = new ThreadPoolExecutor(
5, // 核心线程数 // 5, // 核心线程数
10, // 最大线程数 // 10, // 最大线程数
60L, // 空闲线程存活时间 // 60L, // 空闲线程存活时间
TimeUnit.SECONDS, // 时间单位 // TimeUnit.SECONDS, // 时间单位
new LinkedBlockingQueue<>(100), // 任务队列 // new LinkedBlockingQueue<>(100), // 任务队列
new CustomThreadFactory("MyPool"), // 线程工厂 // new CustomThreadFactory("MyPool"), // 线程工厂
new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略 // new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略
); // );
public AbtParentTask(ScenarioTask scenarioTask, String roomId) { public AbtParentTask(ScenarioTask scenarioTask, String roomId) {
this.scenarioTask = scenarioTask; this.scenarioTask = scenarioTask;
this.roomId = roomId; this.roomId = roomId;
Scenario scenario = SpringUtil.getBean(ScenarioService.class) Scenario scenario = SpringUtil.getBean(ScenarioService.class)
.getScenarioById(scenarioTask.getScenarioId()); .getScenarioById(scenarioTask.getScenarioId());
taskRelativeTime = Math.abs( statisticBean = SpringUtil.getBean(StatisticServiceImpl.class)
Duration.between(scenario.getStartTime(), scenarioTask.getStartTime()).getSeconds()); .statistic(scenarioTask.getResourceId());
initEnv();
} }
public void addScheduledExecutorServiceRefenceToRoom( public void addScheduledExecutorServiceRefenceToRoom(
@ -131,6 +145,28 @@ public abstract class AbtParentTask implements TaskAction {
addScheduledExecutorServiceRefenceToRoom(schedule); addScheduledExecutorServiceRefenceToRoom(schedule);
} }
/**
* 初始化环境
*/
private void initEnv() {
try {
//获取油品消耗规则
String fuelConsumptionStr = SpringUtil.getBean(Environment.class)
.getProperty("fuel.spreed");
fuelConsumption = Double.parseDouble(fuelConsumptionStr == null ? "0" : fuelConsumptionStr);
fuelThreshold = Double.parseDouble(SpringUtil.getBean(Environment.class)
.getProperty("fuel.warn", "0"));
log.info("初始化::{}-油料消耗速度::{},油料最低阈值::{},当前油料::{}",
this.scenarioTask.getResourceId(),
fuelConsumptionStr, fuelThreshold, getCurrentFuel());
} catch (Exception e) {
log.error("init env exception", e);
}
}
protected void initPath() { protected void initPath() {
try { try {
@ -145,6 +181,8 @@ public abstract class AbtParentTask implements TaskAction {
+ "&points_encoded=false" + "&points_encoded=false"
+ "&algorithm=alternative_route&alternative_route.max_paths=3"; + "&algorithm=alternative_route&alternative_route.max_paths=3";
log.info("params:;{}", params); log.info("params:;{}", params);
Room room = RoomManager.getRoom(this.roomId);
Map<String, ScenarioResource> resourceMap = room.getScenarioResourceMap();
//获取路线信息 //获取路线信息
String result = webClient.get().uri(params) String result = webClient.get().uri(params)
.retrieve() .retrieve()
@ -161,9 +199,10 @@ public abstract class AbtParentTask implements TaskAction {
Map<String, Object> dataMap = new HashMap<>(); Map<String, Object> dataMap = new HashMap<>();
dataMap.put("resourceId", scenarioTask.getResourceId()); dataMap.put("resourceId", scenarioTask.getResourceId());
dataMap.put("points", coordinates); dataMap.put("points", coordinates);
dataMap.put("teamType", resourceMap.get(this.scenarioTask.getResourceId()).getType());
if(RoomManager.getRoom(roomId)!=null){ if (RoomManager.getRoom(roomId) != null) {
RoomManager.getRoom(roomId).addResourcePath(this.scenarioTask.getResourceId(),coordinates); RoomManager.getRoom(roomId)
.addResourcePath(this.scenarioTask.getResourceId(), coordinates);
} }
//推送路径任务 //推送路径任务
Global.sendCmdInfoQueue.add( Global.sendCmdInfoQueue.add(
@ -215,19 +254,41 @@ public abstract class AbtParentTask implements TaskAction {
schedule.scheduleWithFixedDelay(() -> { schedule.scheduleWithFixedDelay(() -> {
try { try {
if (this.getRoomStatus()) { if (this.getRoomStatus()) {
double currentFuel = getCurrentFuel();
double totalFuel = statisticBean.getFuel().getTotal();
if (currentFuel <= 0 || totalFuel <= 0) {
log.error("{}:油量为零停止移动", this.scenarioTask.getResourceId());
return;
}
log.info("{}-当前比值{},阈值{}", scenarioTask.getResourceId(),
currentFuel * 100 / totalFuel,
fuelThreshold);
if (currentFuel * 100 / totalFuel < fuelThreshold && !requestFlag.get()) {
log.info("{}-油料不足,需要补充,新建需求和任务", scenarioTask.getResourceId());
requestFlag.set(true);
//需要产生需求
produceFuelRequest();
//产生任务
produceTask(currentFuel);
return;
}
if (currentFuel * 100 / totalFuel < fuelThreshold) {
log.error("{}:油量不足停止移动,等待补给", this.scenarioTask.getResourceId());
return;
}
if (distanceInfoMap.isEmpty()) { if (distanceInfoMap.isEmpty()) {
return; return;
} }
if (!this.canMoved.get()) {
return;
}
log.info("{}-移动中,canRemove::{}", this.scenarioTask.getResourceId(),
this.canMoved.get());
if (duringAction != null) { if (duringAction != null) {
duringAction.doSomeThing(); duringAction.doSomeThing();
} }
log.info("移动中.....");
//跑动距离 //跑动距离
double distance = duringTime.getAndAdd(RoomManager.getMag(roomId)) * speed; double distance = duringTime.getAndAdd(RoomManager.getMag(roomId)) * speed;
@ -237,7 +298,6 @@ public abstract class AbtParentTask implements TaskAction {
endPoint = distanceInfoMap.lastEntry(); endPoint = distanceInfoMap.lastEntry();
} }
//ws数据 //ws数据
List<double[]> dataList = new ArrayList<>(); List<double[]> dataList = new ArrayList<>();
HashMap<Object, Object> dataMap = new HashMap<>(); HashMap<Object, Object> dataMap = new HashMap<>();
@ -280,6 +340,15 @@ public abstract class AbtParentTask implements TaskAction {
ResponseCmdInfo.create(WsCmdTypeEnum.PATH_UPDATE.getCode(), roomId, ResponseCmdInfo.create(WsCmdTypeEnum.PATH_UPDATE.getCode(), roomId,
scenarioTask.getScenarioId(), dataMap)); scenarioTask.getScenarioId(), dataMap));
//修改位置信息
EditScenarioInfo editScenarioInfo = getEditScenarioInfo(
this.scenarioTask.getResourceId());
editScenarioInfo.getJbxx().getTeam().setLat(coordinate.getLat() + "");
editScenarioInfo.getJbxx().getTeam().setLng(coordinate.getLng() + "");
setEditScenarioInfo(editScenarioInfo);
pushStatus(scenarioTask.getResourceId());
} else if (Double.compare(distance, endPoint.getKey()) == 0) { } else if (Double.compare(distance, endPoint.getKey()) == 0) {
NavigableMap<Double, Coordinate> subPathMap = distanceInfoMap.subMap(startPoint.get(), NavigableMap<Double, Coordinate> subPathMap = distanceInfoMap.subMap(startPoint.get(),
true, endPoint.getKey(), true); true, endPoint.getKey(), true);
@ -298,7 +367,6 @@ public abstract class AbtParentTask implements TaskAction {
finishedAction.doSomeThing(); finishedAction.doSomeThing();
} }
//完成路径 //完成路径
Global.sendCmdInfoQueue.add( Global.sendCmdInfoQueue.add(
ResponseCmdInfo.create(WsCmdTypeEnum.PATH_FINISHED.getCode(), roomId, ResponseCmdInfo.create(WsCmdTypeEnum.PATH_FINISHED.getCode(), roomId,
@ -322,6 +390,19 @@ public abstract class AbtParentTask implements TaskAction {
private RedisUtil redisUtil; private RedisUtil redisUtil;
protected EditScenarioInfo getEditScenarioInfo(String resourceId) {
String updJsonStr = (String) SpringUtil.getBean(RedisUtil.class).hget(
this.scenarioTask.getScenarioId() + "-" + roomId + "-" + resourceId,
"updScenarioInfo");
return JSON.parseObject(updJsonStr, EditScenarioInfo.class);
}
protected void setEditScenarioInfo(EditScenarioInfo editScenarioInfo) {
SpringUtil.getBean(RedisUtil.class).hset(
this.scenarioTask.getScenarioId() + "-" + roomId + "-" + scenarioTask.getResourceId(),
"updScenarioInfo", JSON.toJSONString(editScenarioInfo));
}
//统一推送方法 //统一推送方法
protected void pushStatus(String resourceId) { protected void pushStatus(String resourceId) {
if (StringUtils.isBlank(resourceId)) { if (StringUtils.isBlank(resourceId)) {
@ -339,7 +420,9 @@ public abstract class AbtParentTask implements TaskAction {
respObj.setScenarioId(scenarioTask.getScenarioId()); respObj.setScenarioId(scenarioTask.getScenarioId());
respObj.setCmdType("scenarioInfo"); respObj.setCmdType("scenarioInfo");
Global.sendCmdInfoQueue.add(respObj); Global.sendCmdInfoQueue.add(respObj);
String updJsonStr= (String) redisUtil.hget(this.scenarioTask.getScenarioId() + "-" + roomId + "-" + scenarioTask.getResourceId(),"updScenarioInfo"); String updJsonStr = (String) redisUtil.hget(
this.scenarioTask.getScenarioId() + "-" + roomId + "-" + scenarioTask.getResourceId(),
"updScenarioInfo");
ResponseCmdInfo<String> respUpdObj = new ResponseCmdInfo<>(); ResponseCmdInfo<String> respUpdObj = new ResponseCmdInfo<>();
respUpdObj.setData(updJsonStr); respUpdObj.setData(updJsonStr);
respUpdObj.setRoom(roomId); respUpdObj.setRoom(roomId);
@ -348,6 +431,71 @@ public abstract class AbtParentTask implements TaskAction {
Global.sendCmdInfoQueue.add(respUpdObj); Global.sendCmdInfoQueue.add(respUpdObj);
} }
protected double getCurrentFuel() {
Object statisticObj = SpringUtil.getBean(RedisUtil.class).hget(
scenarioTask.getScenarioId() + "-" + roomId + "-" + scenarioTask.getResourceId(),
"scenarioInfo");
if (statisticObj != null) {
ScenarioInfo scenarioInfo = JSON.parseObject(statisticObj.toString(), ScenarioInfo.class);
return scenarioInfo.getFuel().getCurrent();
}
return 0;
}
private void produceFuelRequest() {
log.info("{}-产生油料保障需求", this.scenarioTask.getResourceId());
SupplierRequest supplierRequest = new SupplierRequest();
supplierRequest.setId(IdUtils.simpleUUID());
supplierRequest.setFromResourceId(scenarioTask.getResourceId());
supplierRequest.setSupplierNum(String.valueOf(statisticBean.getFuel().getTotal()));
supplierRequest.setSupplierType("fuel");
supplierRequest.setGeneralTime(LocalDateTime.now());
supplierRequest.setLat(scenarioTask.getToLat());
supplierRequest.setLng(scenarioTask.getToLng());
supplierRequest.setHandleFlag(1);
SpringUtil.getBean(SupplierRequestServiceImpl.class).save(supplierRequest);
}
private void produceTask(double fuel) {
try {
log.info("{}-产生自动保障任务", this.scenarioTask.getResourceId());
List<ScenarioResource> resourceList = SpringUtil.getBean(BattleSupplierServiceImpl.class)
.selectSupplierResource(scenarioTask.getResourceId());
log.info("{}-可选保障分队长度{}", scenarioTask.getResourceId(), resourceList.size());
if (!resourceList.isEmpty()) {
ScenarioTask task = new ScenarioTask();
task.setId(IdUtils.simpleUUID());
task.setScenarioId(scenarioTask.getScenarioId());
task.setResourceId(resourceList.get(0).getId());
task.setTaskType("6");
task.setInsureResourceId(scenarioTask.getResourceId());
task.setSupplierNum(statisticBean.getFuel().getTotal() - fuel);
task.setToLat(this.coordinateReference.get().getLat() + "");
task.setToLng(this.coordinateReference.get().getLng() + "");
task.setStartTime(LocalDateTime.now());
task.setFromLat(resourceList.get(0).getLat());
task.setFromLng(resourceList.get(0).getLng());
task.setFromSource("general");
log.info("{}-保障分队id::{},from::{},to::{}", this.scenarioTask.getInsureResourceId(),
task.getResourceId(), task.getFromLat() + "," + task.getFromLng(),
task.getToLat() + "," + task.getToLng());
SpringUtil.getBean(ScenarioTaskServiceImpl.class).save(task);
//增加到房间任务
SupplierTask supplierTask = new SupplierTask(task, roomId);
//立即执行
RoomManager.addAction(roomId, 0, supplierTask);
} else {
log.error("{}-没有保障分队可以选择", scenarioTask.getResourceId());
}
} catch (Exception e) {
log.error("produceTask exception", e);
}
}
} }
interface BizTaskOnTiming { interface BizTaskOnTiming {

View File

@ -17,6 +17,7 @@ import com.hivekion.statistic.service.StatisticService;
import com.hivekion.statistic.service.impl.StatisticServiceImpl; import com.hivekion.statistic.service.impl.StatisticServiceImpl;
import com.hivekion.supplier.entity.SupplierRequest; import com.hivekion.supplier.entity.SupplierRequest;
import com.hivekion.supplier.service.ISupplierRequestService; import com.hivekion.supplier.service.ISupplierRequestService;
import java.util.concurrent.atomic.AtomicBoolean;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.core.env.Environment; import org.springframework.core.env.Environment;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
@ -47,15 +48,13 @@ public class BattleRootTask extends AbtParentTask {
private IBattleConsumeService battleConsumeService; private IBattleConsumeService battleConsumeService;
private static final Integer DEATH_SPREED = 3;
private static final Integer INJURED_SPREED = 3;
private static final Double AMMUNITION_SPREED = 2.6D;
private static final Double FOOD_SPREED = 2.3D; private static final Double FOOD_SPREED = 2.3D;
private static final Double WATER_SPREED = 3.6D; private static final Double WATER_SPREED = 3.6D;
private static final Double FUEL_SPREED = 3.6D; private static final Double FUEL_SPREED = 3.6D;
private static final Double MEDICAL_SPREED = 1.6D; private static final Double MEDICAL_SPREED = 1.6D;
private final AtomicBoolean isAlreadyProduceTask = new AtomicBoolean(false);
public BattleRootTask(ScenarioTask scenarioTask,String roomId) { public BattleRootTask(ScenarioTask scenarioTask,String roomId) {
super(scenarioTask,roomId); super(scenarioTask,roomId);
@ -216,6 +215,10 @@ public class BattleRootTask extends AbtParentTask {
battleConsume.setResourceId(scenarioTask.getResourceId()); battleConsume.setResourceId(scenarioTask.getResourceId());
battleConsume.setConsumeDate(currentDateTime); battleConsume.setConsumeDate(currentDateTime);
battleConsumeService.save(battleConsume); battleConsumeService.save(battleConsume);
if(injuredConsume>2&&!isAlreadyProduceTask.get()){
//产生一个
}
}catch (Exception ex){ }catch (Exception ex){
ex.printStackTrace(); ex.printStackTrace();
log.error("==================推送消耗數據 失败============================================",ex.getMessage()); log.error("==================推送消耗數據 失败============================================",ex.getMessage());

View File

@ -9,27 +9,17 @@ import com.hivekion.common.uuid.IdUtils;
import com.hivekion.room.RoomManager; import com.hivekion.room.RoomManager;
import com.hivekion.room.func.TaskAction; import com.hivekion.room.func.TaskAction;
import com.hivekion.scenario.entity.BattleConsume; import com.hivekion.scenario.entity.BattleConsume;
import com.hivekion.scenario.entity.ScenarioResource;
import com.hivekion.scenario.entity.ScenarioTask; import com.hivekion.scenario.entity.ScenarioTask;
import com.hivekion.scenario.service.impl.BattleConsumeServiceImpl; import com.hivekion.scenario.service.impl.BattleConsumeServiceImpl;
import com.hivekion.scenario.service.impl.BattleSupplierServiceImpl;
import com.hivekion.scenario.service.impl.ScenarioTaskServiceImpl;
import com.hivekion.statistic.bean.EditScenarioInfo; import com.hivekion.statistic.bean.EditScenarioInfo;
import com.hivekion.statistic.bean.ScenarioInfo; import com.hivekion.statistic.bean.ScenarioInfo;
import com.hivekion.statistic.bean.StatisticBean;
import com.hivekion.statistic.service.impl.StatisticServiceImpl;
import com.hivekion.supplier.entity.SupplierRequest;
import com.hivekion.supplier.service.impl.SupplierRequestServiceImpl;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.core.env.Environment;
/** /**
* [类的简要说明] * [类的简要说明]
@ -47,24 +37,14 @@ public class MoveTask extends AbtParentTask implements TaskAction {
* 速度 换算为100Km/小时 * 速度 换算为100Km/小时
*/ */
private final double SPEED = 27; private final double SPEED = 27;
/**
* 需求产生标志
*/
private final AtomicBoolean requestFlag = new AtomicBoolean(false);
/**
* 油料消耗速率
*/
private double fuelConsumption = 0;
private double fuelThreshold = 0;
/** /**
* 消耗任务间隔 * 消耗任务间隔
*/ */
private final int consumptionTaskInterval = 10; private final int consumptionTaskInterval = 5;
/**
* redis 服务类
*/
private final RedisUtil redis = SpringUtil.getBean(RedisUtil.class);
private StatisticBean statisticBean;
public MoveTask(ScenarioTask scenarioTask, String roomId) { public MoveTask(ScenarioTask scenarioTask, String roomId) {
@ -76,7 +56,7 @@ public class MoveTask extends AbtParentTask implements TaskAction {
public void doSomeThing() { public void doSomeThing() {
log.info("move task running:{},fuel::{}", scenarioTask.getResourceId(), getCurrentFuel()); log.info("move task running:{},fuel::{}", scenarioTask.getResourceId(), getCurrentFuel());
initEnv(); //初始化环境
initPath(); //初始化路径 initPath(); //初始化路径
updatePath(SPEED, new TaskAction() { updatePath(SPEED, new TaskAction() {
@Override @Override
@ -107,28 +87,7 @@ public class MoveTask extends AbtParentTask implements TaskAction {
fuelConsumption();//油品消耗 fuelConsumption();//油品消耗
} }
/**
* 初始化环境
*/
private void initEnv() {
try {
//获取油品消耗规则
String fuelConsumptionStr = SpringUtil.getBean(Environment.class)
.getProperty("fuel.spreed");
fuelConsumption = Double.parseDouble(fuelConsumptionStr == null ? "0" : fuelConsumptionStr);
fuelThreshold = Double.parseDouble(SpringUtil.getBean(Environment.class)
.getProperty("fuel.warn", "0"));
log.info("初始化::{}-油料消耗速度::{},油料最低阈值::{},当前油料::{}", this.scenarioTask.getResourceId(),
fuelConsumptionStr, fuelThreshold,getCurrentFuel());
statisticBean = SpringUtil.getBean(StatisticServiceImpl.class)
.statistic(scenarioTask.getResourceId());
} catch (Exception e) {
log.error("init env exception", e);
}
}
private void fuelConsumption() { private void fuelConsumption() {
@ -136,49 +95,33 @@ public class MoveTask extends AbtParentTask implements TaskAction {
ScheduledExecutorService schedule = Executors.newScheduledThreadPool( ScheduledExecutorService schedule = Executors.newScheduledThreadPool(
1); 1);
schedule.scheduleWithFixedDelay(() -> { schedule.scheduleWithFixedDelay(() -> {
if (getRoomStatus() && this.canMoved.get()) { if (getRoomStatus()) {
double currentUseUp = consumptionTaskInterval*RoomManager.getMag(roomId) * SPEED / 1000 * fuelConsumption; double currentFuel = getCurrentFuel();
if(currentFuel > 0) {
double currentUseUp = consumptionTaskInterval*RoomManager.getMag(roomId) * SPEED / 1000 * fuelConsumption;
double fuel = getCurrentFuel(); log.info("{}-当前消耗油料::{},当前剩余油料::{}", scenarioTask.getResourceId(),
log.info("{}-当前消耗油料::{},当前剩余油料::{}", scenarioTask.getResourceId(), currentUseUp, currentFuel);
currentUseUp, fuel);
fuel = fuel - currentUseUp; //修改油料
if (fuel <= 0) { EditScenarioInfo editScenarioInfo = getEditScenarioInfo(
log.error("{}-油料为空", scenarioTask.getResourceId()); this.scenarioTask.getResourceId());
this.canMoved.set(false); editScenarioInfo.getJbxx().getFuel().setCurrent(editScenarioInfo.getJbxx().getFuel().getCurrent()-currentUseUp);
log.info("{},can:{}", scenarioTask.getResourceId(), this.canMoved.get()); setEditScenarioInfo(editScenarioInfo);
return;
//插入消耗表
insertConsumption(currentUseUp);
setCurrentFuel(currentUseUp);
pushStatus(scenarioTask.getResourceId());
} }
setCurrentFuel(currentUseUp);
double totalFuel = statisticBean.getFuel().getTotal();
log.info("{}-当前比值{},阈值{}", scenarioTask.getResourceId(), fuel * 100 / totalFuel,
fuelThreshold);
if (fuel * 100 / totalFuel < fuelThreshold && !requestFlag.get()) {
log.info("{}-油料不足,需要补充,新建需求和任务", scenarioTask.getResourceId());
this.canMoved.set(false);
requestFlag.set(true);
//需要产生需求
produceFuelRequest();
//产生任务
produceTask(fuel);
}
//插入消耗表
insertConsumption(currentUseUp);
pushStatus(scenarioTask.getResourceId());
}
if (!this.canMoved.get()) {
//判断油料是否满足
double totalFuel = statisticBean.getFuel().getTotal();
if (Double.compare(this.getCurrentFuel(), totalFuel) >= 0) {
this.canMoved.set(true);
}
} }
}, 0, consumptionTaskInterval, TimeUnit.SECONDS); }, 0, consumptionTaskInterval, TimeUnit.SECONDS);
} catch (Exception e) { } catch (Exception e) {
log.error("fuel consumption exception", e); log.error("fuel consumption exception", e);
@ -187,59 +130,7 @@ public class MoveTask extends AbtParentTask implements TaskAction {
} }
private void produceFuelRequest() {
log.info("{}-产生油料保障需求", this.scenarioTask.getResourceId());
SupplierRequest supplierRequest = new SupplierRequest();
supplierRequest.setId(IdUtils.simpleUUID());
supplierRequest.setFromResourceId(scenarioTask.getResourceId());
supplierRequest.setSupplierNum(String.valueOf(statisticBean.getFuel().getTotal()));
supplierRequest.setSupplierType("fuel");
supplierRequest.setGeneralTime(LocalDateTime.now());
supplierRequest.setLat(scenarioTask.getToLat());
supplierRequest.setLng(scenarioTask.getToLng());
supplierRequest.setHandleFlag(1);
SpringUtil.getBean(SupplierRequestServiceImpl.class).save(supplierRequest);
}
private void produceTask(double fuel) {
try {
log.info("{}-产生自动保障任务", this.scenarioTask.getResourceId());
List<ScenarioResource> resourceList = SpringUtil.getBean(BattleSupplierServiceImpl.class)
.selectSupplierResource(scenarioTask.getResourceId());
log.info("{}-可选保障分队长度{}", scenarioTask.getResourceId(), resourceList.size());
if (!resourceList.isEmpty()) {
ScenarioTask task = new ScenarioTask();
task.setId(IdUtils.simpleUUID());
task.setScenarioId(scenarioTask.getScenarioId());
task.setResourceId(resourceList.get(0).getId());
task.setTaskType("6");
task.setInsureResourceId(scenarioTask.getResourceId());
task.setSupplierNum(statisticBean.getFuel().getTotal()-fuel);
task.setToLat(this.coordinateReference.get().getLat() + "");
task.setToLng(this.coordinateReference.get().getLng() + "");
task.setStartTime(LocalDateTime.now());
task.setFromLat(resourceList.get(0).getLat());
task.setFromLng(resourceList.get(0).getLng());
task.setFromSource("general");
log.info("{}-保障分队id::{},from::{},to::{}", this.scenarioTask.getInsureResourceId(),
task.getResourceId(), task.getFromLat() + "," + task.getFromLng(),
task.getToLat() + "," + task.getToLng());
SpringUtil.getBean(ScenarioTaskServiceImpl.class).save(task);
//增加到房间任务
SupplierTask supplierTask = new SupplierTask(task, roomId);
//立即执行
RoomManager.addAction(roomId, 0, supplierTask);
} else {
log.error("{}-没有保障分队可以选择", scenarioTask.getResourceId());
}
} catch (Exception e) {
log.error("produceTask exception", e);
}
}
private void insertConsumption(double num) { private void insertConsumption(double num) {
try{ try{
@ -256,32 +147,17 @@ public class MoveTask extends AbtParentTask implements TaskAction {
} }
private double getCurrentFuel() {
Object statisticObj = redis.hget(
scenarioTask.getScenarioId() + "-" + roomId + "-" + scenarioTask.getResourceId(),
"scenarioInfo");
if (statisticObj != null) {
ScenarioInfo scenarioInfo = JSON.parseObject(statisticObj.toString(), ScenarioInfo.class);
return scenarioInfo.getFuel().getCurrent();
}
return 0;
}
private void setCurrentFuel(double num) { private void setCurrentFuel(double num) {
Object statisticObj = redis.hget( Object statisticObj = SpringUtil.getBean(RedisUtil.class).hget(
scenarioTask.getScenarioId() + "-" + roomId + "-" + scenarioTask.getResourceId(), scenarioTask.getScenarioId() + "-" + roomId + "-" + scenarioTask.getResourceId(),
"scenarioInfo"); "scenarioInfo");
if (statisticObj != null) { if (statisticObj != null) {
ScenarioInfo scenarioInfo = JSON.parseObject(statisticObj.toString(), ScenarioInfo.class); ScenarioInfo scenarioInfo = JSON.parseObject(statisticObj.toString(), ScenarioInfo.class);
scenarioInfo.getFuel().setCurrent(scenarioInfo.getFuel().getCurrent() - num); scenarioInfo.getFuel().setCurrent(scenarioInfo.getFuel().getCurrent() - num);
redis.hset(scenarioTask.getScenarioId() + "-" + roomId + "-" + scenarioTask.getResourceId(), SpringUtil.getBean(RedisUtil.class).hset(scenarioTask.getScenarioId() + "-" + roomId + "-" + scenarioTask.getResourceId(),
"scenarioInfo", JSON.toJSONString(scenarioInfo)); "scenarioInfo", JSON.toJSONString(scenarioInfo));
String updJsonStr= (String) redis.hget(this.scenarioTask.getScenarioId() + "-" + roomId + "-" + scenarioTask.getResourceId(),"updScenarioInfo");
EditScenarioInfo updScenarioInfo = JSON.parseObject(updJsonStr, EditScenarioInfo.class);
updScenarioInfo.getJbxx().getFuel().setCurrent(updScenarioInfo.getJbxx().getFuel().getCurrent() - num);
redis.hset(scenarioTask.getScenarioId() + "-" + roomId + "-" + scenarioTask.getResourceId(),
"updScenarioInfo", JSON.toJSONString(updScenarioInfo));
} }
} }
} }

View File

@ -50,6 +50,7 @@ public class Room implements AutoCloseable {
private Map<String, Coordinate> resourceCoordinateMap = new ConcurrentHashMap<>(); private Map<String, Coordinate> resourceCoordinateMap = new ConcurrentHashMap<>();
//资源路线path //资源路线path
private Map<String, Object> resourcePathMap = new ConcurrentHashMap<>(); private Map<String, Object> resourcePathMap = new ConcurrentHashMap<>();
private Map<String,ScenarioResource> scenarioResourceMap = new ConcurrentHashMap<>();
/** /**
* 任务管理相关 * 任务管理相关
*/ */
@ -243,7 +244,9 @@ public class Room implements AutoCloseable {
scenarioResource.getScenarioId() + "-" + roomId + "-" + scenarioResource.getId(), scenarioResource.getScenarioId() + "-" + roomId + "-" + scenarioResource.getId(),
"updScenarioInfo", JSON.toJSONString(updScenarioInfo)); "updScenarioInfo", JSON.toJSONString(updScenarioInfo));
} }
scenario.getResourceList().forEach(resource -> {
scenarioResourceMap.put(resource.getId(), resource);
});
} }
@ -266,4 +269,7 @@ public class Room implements AutoCloseable {
public Map<String, Object> getPathMap() { public Map<String, Object> getPathMap() {
return resourcePathMap; return resourcePathMap;
} }
public Map<String, ScenarioResource> getScenarioResourceMap() {
return scenarioResourceMap;
}
} }

View File

@ -44,5 +44,7 @@ public class Teaminfo extends SearchInputVo {
private String iconId; private String iconId;
@TableField(value="team_type") @TableField(value="team_type")
private Integer teamType; private Integer teamType;
@TableField(value="role_code")
private String roleCode;
} }

View File

@ -4,9 +4,11 @@ import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.hivekion.Global; import com.hivekion.Global;
import com.hivekion.common.entity.RequestCmdInfo; import com.hivekion.common.entity.RequestCmdInfo;
import com.hivekion.common.entity.ResponseCmdInfo;
import com.hivekion.room.RoomManager; import com.hivekion.room.RoomManager;
import com.hivekion.room.bean.Room; import com.hivekion.room.bean.Room;
import com.hivekion.ws.WsServer; import com.hivekion.scenario.entity.ScenarioResource;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -28,7 +30,7 @@ public class HandleReceiveRunnable implements Runnable {
try { try {
RequestCmdInfo requestCmdInfo = Global.receiveCmdInfoQueue.take(); RequestCmdInfo requestCmdInfo = Global.receiveCmdInfoQueue.take();
handleMessage(requestCmdInfo);
//消息分发业务bean处理 //消息分发业务bean处理
if (SpringUtil.getBean(WebsocketMsgWrapper.class) != null) { if (SpringUtil.getBean(WebsocketMsgWrapper.class) != null) {
try { try {
@ -51,6 +53,7 @@ public class HandleReceiveRunnable implements Runnable {
} }
private void handleMessage(RequestCmdInfo requestCmdInfo) { private void handleMessage(RequestCmdInfo requestCmdInfo) {
try { try {
switch (requestCmdInfo.getCmdType()) { switch (requestCmdInfo.getCmdType()) {
case "get_init_path": case "get_init_path":
@ -68,17 +71,27 @@ public class HandleReceiveRunnable implements Runnable {
} }
private void handleGetInitPath(RequestCmdInfo requestCmdInfo) { private void handleGetInitPath(RequestCmdInfo requestCmdInfo) {
log.info("接收到请求路线信息::{}",JSON.toJSONString(requestCmdInfo)); log.info("接收到请求路线信息::{}", JSON.toJSONString(requestCmdInfo));
Room room = RoomManager.getRoom(requestCmdInfo.getRoom()); Room room = RoomManager.getRoom(requestCmdInfo.getRoom());
if(room!=null){ if (room != null) {
Map<String, Object> pathMap = room.getPathMap(); Map<String, Object> pathMap = room.getPathMap();
pathMap.forEach((k,v)->{ pathMap.forEach((k, v) -> {
try{ try {
WsServer.sendMessage(requestCmdInfo.getScenarioId(),requestCmdInfo.getRoom(), Map<String, Object> dataMap = new HashMap<>();
JSON.toJSONString(v)); Map<String, ScenarioResource> resourceMap = room.getScenarioResourceMap();
dataMap.put("teamType", resourceMap.get(k).getType());
ResponseCmdInfo<Object> respObj = new ResponseCmdInfo<>();
}catch (Exception e){ dataMap.put("resourceId", k);
log.error("error::",e); dataMap.put("points", v);
respObj.setData(dataMap);
respObj.setRoom(requestCmdInfo.getRoom());
respObj.setScenarioId(requestCmdInfo.getScenarioId());
respObj.setCmdType("path_init");
Global.sendCmdInfoQueue.add(respObj);
} catch (Exception e) {
log.error("error::", e);
} }
}); });

View File

@ -1,5 +1,6 @@
package com.hivekion.ws; package com.hivekion.ws;
import com.alibaba.fastjson2.JSON;
import com.hivekion.Global; import com.hivekion.Global;
import com.hivekion.common.entity.RequestCmdInfo; import com.hivekion.common.entity.RequestCmdInfo;
import java.util.Map; import java.util.Map;
@ -90,6 +91,8 @@ public class WsServer {
RequestCmdInfo requestCmdInfo = new RequestCmdInfo(); RequestCmdInfo requestCmdInfo = new RequestCmdInfo();
requestCmdInfo.setScenarioId((scenarioId)); requestCmdInfo.setScenarioId((scenarioId));
requestCmdInfo.setRoom(room); requestCmdInfo.setRoom(room);
requestCmdInfo.setCmdType(JSON.parseObject(message,RequestCmdInfo.class).getCmdType());
requestCmdInfo.setMessage(message); requestCmdInfo.setMessage(message);
Global.receiveCmdInfoQueue.add(requestCmdInfo); Global.receiveCmdInfoQueue.add(requestCmdInfo);
} catch (Exception e) { } catch (Exception e) {

View File

@ -3,7 +3,7 @@ death.warn = 56
ammunition.warn = 3 ammunition.warn = 3
food.warn = 3 food.warn = 3
water.warn = 3 water.warn = 3
fuel.warn = 99.6 fuel.warn = 80.6
medical.warn = 1 medical.warn = 1
death.spreed = 3 death.spreed = 3
injured.spreed = 3 injured.spreed = 3

View File

@ -9,6 +9,7 @@
<result property="mappingguid" column="mappingguid"/> <result property="mappingguid" column="mappingguid"/>
<result property="iconId" column="icon_id"/> <result property="iconId" column="icon_id"/>
<result property="teamType" column="team_type"/> <result property="teamType" column="team_type"/>
<result property="roleCode" column="role_code"/>
<!-- 其他字段 --> <!-- 其他字段 -->
</resultMap> </resultMap>
<select id="list" resultMap="DMTeamInfo" parameterType="com.hivekion.team.entity.Teaminfo" databaseId="dm"> <select id="list" resultMap="DMTeamInfo" parameterType="com.hivekion.team.entity.Teaminfo" databaseId="dm">