Merge branch 'main' of http://git.hivekion.com:3000/liyudong/simulation-backend into main
This commit is contained in:
commit
d1255da3db
8
pom.xml
8
pom.xml
|
|
@ -51,11 +51,11 @@
|
|||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>5.1.47</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<!-- <dependency>
|
||||
<groupId>io.lettuce</groupId>
|
||||
<artifactId>lettuce-core</artifactId>
|
||||
<version>6.2.4.RELEASE</version>
|
||||
</dependency>
|
||||
</dependency>-->
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-pool2</artifactId>
|
||||
|
|
@ -190,11 +190,11 @@
|
|||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<!-- <dependency>
|
||||
<groupId>io.lettuce</groupId>
|
||||
<artifactId>lettuce-core</artifactId>
|
||||
<version>6.2.4.RELEASE</version>
|
||||
</dependency>
|
||||
</dependency>-->
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
|
||||
|
|
|
|||
|
|
@ -28,12 +28,12 @@ public class CodeGenerator {
|
|||
})
|
||||
.packageConfig(builder -> {
|
||||
builder.parent("com.hivekion") // 设置父包名
|
||||
.moduleName("basedata") // 设置模块名(可选)
|
||||
.moduleName("supplier") // 设置模块名(可选)
|
||||
.pathInfo(Collections.singletonMap(OutputFile.xml,
|
||||
basePath + "/src/main/resources/mapper/tbl")); // 设置mapperXml生成路径
|
||||
})
|
||||
.strategyConfig(builder -> {
|
||||
builder.addInclude("IMG_VEHICLE_IMAGE".toLowerCase()) // 设置需要生成的表名(多个用逗号分隔)
|
||||
builder.addInclude("TBL_BATTLE_SUPPLIER".toLowerCase()) // 设置需要生成的表名(多个用逗号分隔)
|
||||
.addTablePrefix("tbl_"); // 设置过滤表前缀
|
||||
})
|
||||
.execute();
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import lombok.Getter;
|
|||
public enum WsCmdTypeEnum {
|
||||
PATH_UPDATE("path_update"),
|
||||
PATH_FINISHED("path_finished"),
|
||||
STATISTIC("statistic"),
|
||||
PATH_INIT("path_init");
|
||||
@Getter
|
||||
private final String code;
|
||||
|
|
|
|||
|
|
@ -1,11 +1,37 @@
|
|||
package com.hivekion.room.bean;
|
||||
|
||||
import cn.hutool.extra.spring.SpringUtil;
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONArray;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.hivekion.Global;
|
||||
import com.hivekion.baseData.entity.Scenario;
|
||||
import com.hivekion.baseData.service.ScenarioService;
|
||||
import com.hivekion.common.MultiPointGeoPosition;
|
||||
import com.hivekion.common.entity.ResponseCmdInfo;
|
||||
import com.hivekion.common.redis.RedisUtil;
|
||||
import com.hivekion.enums.WsCmdTypeEnum;
|
||||
import com.hivekion.room.RoomManager;
|
||||
import com.hivekion.room.func.TaskAction;
|
||||
import com.hivekion.scenario.entity.ScenarioTask;
|
||||
|
||||
import java.util.concurrent.*;
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.NavigableMap;
|
||||
import java.util.TreeMap;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
|
||||
/**
|
||||
|
|
@ -17,16 +43,27 @@ import org.springframework.web.reactive.function.client.WebClient;
|
|||
* @author LiDongYU
|
||||
* @since 2025/7/22
|
||||
*/
|
||||
|
||||
@Slf4j
|
||||
public abstract class AbtParentTask implements TaskAction {
|
||||
|
||||
|
||||
/**
|
||||
* 开始点坐标
|
||||
*/
|
||||
private final AtomicReference<Double> startPoint = new AtomicReference<>();
|
||||
/**
|
||||
* 距离和坐标的对应关系
|
||||
*/
|
||||
protected final TreeMap<Double, Coordinate> distanceInfoMap = new TreeMap<>();
|
||||
//任务数据
|
||||
protected final ScenarioTask scenarioTask;
|
||||
//房间ID
|
||||
protected final String roomId;
|
||||
//http请求
|
||||
protected WebClient webClient = WebClient.create();
|
||||
/**
|
||||
* 任务相对与想定的开始时间
|
||||
*/
|
||||
private long taskRelativeTime = 0;
|
||||
//线程池
|
||||
protected ThreadPoolExecutor executor = new ThreadPoolExecutor(
|
||||
5, // 核心线程数
|
||||
|
|
@ -41,7 +78,10 @@ public abstract class AbtParentTask implements TaskAction {
|
|||
public AbtParentTask(ScenarioTask scenarioTask, String roomId) {
|
||||
this.scenarioTask = scenarioTask;
|
||||
this.roomId = roomId;
|
||||
|
||||
Scenario scenario = SpringUtil.getBean(ScenarioService.class)
|
||||
.getScenarioById(scenarioTask.getScenarioId());
|
||||
taskRelativeTime = Math.abs(
|
||||
Duration.between(scenario.getStartTime(), scenarioTask.getStartTime()).getSeconds());
|
||||
}
|
||||
|
||||
public void addScheduledExecutorServiceRefenceToRoom(
|
||||
|
|
@ -68,14 +108,15 @@ public abstract class AbtParentTask implements TaskAction {
|
|||
public long getDuringTime() {
|
||||
return RoomManager.getRoomDuringTime(this.roomId);
|
||||
}
|
||||
|
||||
//获取房间状态
|
||||
public boolean getRoomStatus() {
|
||||
return RoomManager.isRunning(roomId);
|
||||
}
|
||||
|
||||
public void createBattleTaskOnTimingHandle(BizTaskOnTiming bizTaskOnTiming){
|
||||
public void createBattleTaskOnTimingHandle(BizTaskOnTiming bizTaskOnTiming) {
|
||||
ScheduledExecutorService schedule = Executors.newScheduledThreadPool(
|
||||
1);
|
||||
1);
|
||||
schedule.scheduleWithFixedDelay(() -> {
|
||||
bizTaskOnTiming.execTask();
|
||||
}, 0, 10, TimeUnit.SECONDS);
|
||||
|
|
@ -83,9 +124,186 @@ public abstract class AbtParentTask implements TaskAction {
|
|||
addScheduledExecutorServiceRefenceToRoom(schedule);
|
||||
}
|
||||
|
||||
|
||||
protected void initPath() {
|
||||
try {
|
||||
log.info("init path");
|
||||
String url = SpringUtil.getBean(Environment.class).getProperty("path.planning.url");
|
||||
String params = url + "?"
|
||||
+ "profile=car"
|
||||
+ "&point=" + scenarioTask.getFromLat() + ","
|
||||
+ scenarioTask.getFromLng()
|
||||
+ "&point=" + scenarioTask.getToLat() + ","
|
||||
+ scenarioTask.getToLng()
|
||||
+ "&points_encoded=false"
|
||||
+ "&algorithm=alternative_route&alternative_route.max_paths=3";
|
||||
log.info("params:;{}", params);
|
||||
//获取路线信息
|
||||
String result = webClient.get().uri(params)
|
||||
.retrieve()
|
||||
.bodyToMono(String.class)
|
||||
.block();
|
||||
log.info("init path finished ::{}", result);
|
||||
JSONObject pointJson = JSON.parseObject(result);
|
||||
//获取路径点
|
||||
if (pointJson != null) {
|
||||
JSONObject pointsObj = pointJson.getJSONArray("paths").getJSONObject(0)
|
||||
.getJSONObject("points");
|
||||
JSONArray coordinates = pointsObj.getJSONArray("coordinates");
|
||||
//组装信息
|
||||
Map<String, Object> dataMap = new HashMap<>();
|
||||
dataMap.put("resourceId", scenarioTask.getResourceId());
|
||||
dataMap.put("points", coordinates);
|
||||
//推送路径任务
|
||||
Global.sendCmdInfoQueue.add(
|
||||
ResponseCmdInfo.create(WsCmdTypeEnum.PATH_INIT.getCode(), roomId,
|
||||
scenarioTask.getScenarioId(), dataMap));
|
||||
|
||||
SpringUtil.getBean(RedisUtil.class).hset(
|
||||
scenarioTask.getScenarioId() + "-" + roomId + "-" + scenarioTask.getResourceId(),
|
||||
"init_path", JSON.toJSONString(coordinates));
|
||||
|
||||
//计算各个点的累计距离和坐标的对应关系
|
||||
double beforeLng = Double.parseDouble(scenarioTask.getFromLng());
|
||||
double beforeLat = Double.parseDouble(scenarioTask.getFromLat());
|
||||
double total = 0;
|
||||
for (int i = 0; i < coordinates.size(); i++) {
|
||||
JSONArray coordinate = coordinates.getJSONArray(i);
|
||||
Double lng = coordinate.getDouble(0);
|
||||
|
||||
Double lat = coordinate.getDouble(1);
|
||||
|
||||
double distance = MultiPointGeoPosition.haversine(beforeLat, beforeLng, lat, lng);
|
||||
//当前总距离
|
||||
total = total + distance;
|
||||
//定义坐标对象
|
||||
Coordinate coordinateInfo = new Coordinate();
|
||||
coordinateInfo.setLat(lat);
|
||||
coordinateInfo.setLng(lng);
|
||||
|
||||
//记录距离和数组列表直接的索引关系
|
||||
distanceInfoMap.put(total, coordinateInfo);
|
||||
|
||||
beforeLng = lng;
|
||||
beforeLat = lat;
|
||||
|
||||
}
|
||||
//设置第一个开始位置
|
||||
startPoint.set(distanceInfoMap.firstKey());
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("error::", e);
|
||||
}
|
||||
}
|
||||
|
||||
protected void updatePath(double speed, TaskAction action) {
|
||||
|
||||
ScheduledExecutorService schedule = Executors.newScheduledThreadPool(
|
||||
1);
|
||||
schedule.scheduleWithFixedDelay(() -> {
|
||||
|
||||
try {
|
||||
if (this.getRoomStatus()) {
|
||||
if (distanceInfoMap.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
long duringTime = getDuringTime() - taskRelativeTime;
|
||||
if (duringTime <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
//跑动距离
|
||||
double distance = duringTime * speed;
|
||||
|
||||
//获取大与此距离的第一个路线点key
|
||||
Entry<Double, Coordinate> endPoint = distanceInfoMap.ceilingEntry(distance);
|
||||
if (endPoint == null) {
|
||||
endPoint = distanceInfoMap.lastEntry();
|
||||
}
|
||||
|
||||
// log.info("enPoint::{}",endPoint);
|
||||
//ws数据
|
||||
List<double[]> dataList = new ArrayList<>();
|
||||
HashMap<Object, Object> dataMap = new HashMap<>();
|
||||
dataMap.put("resourceId", scenarioTask.getResourceId());
|
||||
dataMap.put("points", dataList);
|
||||
|
||||
if (Double.compare(distance, endPoint.getKey()) < 0) {
|
||||
//获取小于最大值的第一个key
|
||||
Double lowerKey = distanceInfoMap.lowerKey(endPoint.getKey());
|
||||
if(lowerKey==null){
|
||||
lowerKey = endPoint.getKey();
|
||||
}
|
||||
|
||||
NavigableMap<Double, Coordinate> subPathMap = distanceInfoMap.subMap(startPoint.get(),
|
||||
true, lowerKey, true);
|
||||
for (Double key : subPathMap.keySet()) {
|
||||
Coordinate coordinate = subPathMap.get(key);
|
||||
dataList.add(new double[]{coordinate.getLng(), coordinate.getLat()});
|
||||
}
|
||||
double diff = distance - lowerKey;
|
||||
|
||||
//插入值
|
||||
double[] insertPoints = MultiPointGeoPosition.pointAlong(
|
||||
distanceInfoMap.get(lowerKey).getLat(), distanceInfoMap.get(lowerKey).getLng(),
|
||||
endPoint.getValue().getLat(), endPoint.getValue().getLng(), diff);
|
||||
|
||||
dataList.add(new double[]{insertPoints[1], insertPoints[0]});
|
||||
|
||||
Coordinate coordinate = new Coordinate();
|
||||
coordinate.setLat(insertPoints[0]);
|
||||
coordinate.setLng(insertPoints[1]);
|
||||
distanceInfoMap.put(distance, coordinate);
|
||||
startPoint.set(distance);
|
||||
SpringUtil.getBean(RedisUtil.class).hset(
|
||||
scenarioTask.getScenarioId() + "-" + roomId + "-" + scenarioTask.getResourceId(),
|
||||
"position", JSON.toJSONString(coordinate));
|
||||
|
||||
Global.sendCmdInfoQueue.add(
|
||||
ResponseCmdInfo.create(WsCmdTypeEnum.PATH_UPDATE.getCode(), roomId,
|
||||
scenarioTask.getScenarioId(), dataMap));
|
||||
|
||||
} else if (Double.compare(distance, endPoint.getKey()) == 0) {
|
||||
NavigableMap<Double, Coordinate> subPathMap = distanceInfoMap.subMap(startPoint.get(),
|
||||
true, endPoint.getKey(), true);
|
||||
for (Double key : subPathMap.keySet()) {
|
||||
Coordinate coordinate = subPathMap.get(key);
|
||||
dataList.add(new double[]{coordinate.getLng(), coordinate.getLat()});
|
||||
}
|
||||
|
||||
startPoint.set(endPoint.getKey());
|
||||
Global.sendCmdInfoQueue.add(
|
||||
ResponseCmdInfo.create(WsCmdTypeEnum.PATH_UPDATE.getCode(), roomId,
|
||||
scenarioTask.getScenarioId(), dataMap));
|
||||
|
||||
} else {
|
||||
if (action != null) {
|
||||
action.doSomeThing();
|
||||
}
|
||||
//完成路径
|
||||
Global.sendCmdInfoQueue.add(
|
||||
ResponseCmdInfo.create(WsCmdTypeEnum.PATH_FINISHED.getCode(), roomId,
|
||||
scenarioTask.getScenarioId(), dataMap));
|
||||
//任务终止
|
||||
schedule.shutdown();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("error::", e);
|
||||
}
|
||||
|
||||
|
||||
}, 0, 1, TimeUnit.SECONDS);
|
||||
|
||||
//房间统一管理定时器;房间关闭后,定时器销毁
|
||||
addScheduledExecutorServiceRefenceToRoom(schedule);
|
||||
}
|
||||
}
|
||||
|
||||
interface BizTaskOnTiming{
|
||||
interface BizTaskOnTiming {
|
||||
|
||||
public void execTask();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,9 @@ import com.hivekion.Global;
|
|||
import com.hivekion.common.entity.ResponseCmdInfo;
|
||||
import com.hivekion.common.redis.RedisUtil;
|
||||
import com.hivekion.common.uuid.IdUtils;
|
||||
import com.hivekion.scenario.entity.BattleConsume;
|
||||
import com.hivekion.scenario.entity.ScenarioTask;
|
||||
import com.hivekion.scenario.service.IBattleConsumeService;
|
||||
import com.hivekion.statistic.bean.*;
|
||||
import com.hivekion.statistic.service.StatisticService;
|
||||
import com.hivekion.statistic.service.impl.StatisticServiceImpl;
|
||||
|
|
@ -18,6 +20,7 @@ import lombok.extern.slf4j.Slf4j;
|
|||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.util.*;
|
||||
|
|
@ -42,6 +45,8 @@ public class BattleRootTask extends AbtParentTask {
|
|||
|
||||
private ISupplierRequestService supplierRequestService;
|
||||
|
||||
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;
|
||||
|
|
@ -66,6 +71,9 @@ public class BattleRootTask extends AbtParentTask {
|
|||
if(supplierRequestService == null){
|
||||
supplierRequestService = SpringUtil.getBean(ISupplierRequestService.class);
|
||||
}
|
||||
if(battleConsumeService == null){
|
||||
battleConsumeService = SpringUtil.getBean(IBattleConsumeService.class);
|
||||
}
|
||||
}
|
||||
//执行一次
|
||||
@Override
|
||||
|
|
@ -85,13 +93,14 @@ public class BattleRootTask extends AbtParentTask {
|
|||
|
||||
// statisticBean.getAmmunition().getCurrent()
|
||||
//初始化本次战斗任务各种资源数
|
||||
battleParams.put("ammunition",Double.valueOf(statisticBean.getAmmunition().getCurrent()).toString());
|
||||
battleParams.put("food",Double.valueOf(statisticBean.getFood().getCurrent()).toString());
|
||||
battleParams.put("fuel",Double.valueOf(statisticBean.getFuel().getCurrent()).toString());
|
||||
battleParams.put("medical",Double.valueOf(statisticBean.getMedical().getCurrent()).toString());
|
||||
battleParams.put("water",Double.valueOf(statisticBean.getWater().getCurrent()).toString());
|
||||
battleParams.put("death",Double.valueOf(statisticBean.getPerson().getDeath()).toString());
|
||||
battleParams.put("injured",Double.valueOf(statisticBean.getPerson().getInjured()).toString());
|
||||
battleParams.put("ammunition",Double.valueOf(statisticBean.getAmmunition().getTotal()).toString());
|
||||
battleParams.put("food",Double.valueOf(statisticBean.getFood().getTotal()).toString());
|
||||
battleParams.put("fuel",Double.valueOf(statisticBean.getFuel().getTotal()).toString());
|
||||
battleParams.put("medical",Double.valueOf(statisticBean.getMedical().getTotal()).toString());
|
||||
battleParams.put("water",Double.valueOf(statisticBean.getWater().getTotal()).toString());
|
||||
battleParams.put("person",Integer.valueOf(statisticBean.getPerson().getTotal()).toString());
|
||||
battleParams.put("death",Integer.valueOf(statisticBean.getPerson().getDeath()).toString());
|
||||
battleParams.put("injured",Integer.valueOf(statisticBean.getPerson().getInjured()).toString());
|
||||
battleParams.put("teamLat",statisticBean.getTeam().getLat().toString());
|
||||
battleParams.put("teamLng",statisticBean.getTeam().getLng().toString());
|
||||
battleParams.put("duringTime",Long.valueOf(initDuringTime).toString());
|
||||
|
|
@ -148,8 +157,8 @@ public class BattleRootTask extends AbtParentTask {
|
|||
battleParams.put("fuel",Double.valueOf(fuel - fuelConsume).toString());
|
||||
battleParams.put("medical",Double.valueOf(medical - medicalConsume).toString());
|
||||
battleParams.put("water",Double.valueOf(water - waterConsume).toString());
|
||||
battleParams.put("death",Long.valueOf(death - deathConsume).toString());
|
||||
battleParams.put("injured",Long.valueOf(injured - injuredConsume).toString());
|
||||
battleParams.put("death",Long.valueOf(death+deathConsume).toString());
|
||||
battleParams.put("injured",Long.valueOf(injured +injuredConsume).toString());
|
||||
battleParams.put("duringTime",Long.valueOf(duringTime).toString());
|
||||
redisUtil.hset(scenarioTask.getScenarioId() + "-" + roomId + "-" + scenarioTask.getResourceId(), battleParams);
|
||||
}catch (Exception ex){
|
||||
|
|
@ -167,25 +176,41 @@ public class BattleRootTask extends AbtParentTask {
|
|||
jsonObject.put("medicalConsume", medicalConsume);
|
||||
jsonObject.put("teamLat",teamLat);
|
||||
jsonObject.put("teamLng",teamLng);
|
||||
jsonObject.put("resourceId",scenarioTask.getResourceId());
|
||||
sendConsumeMsg.setData(jsonObject);
|
||||
sendConsumeMsg.setRoom(roomId);
|
||||
sendConsumeMsg.setScenarioId(scenarioTask.getScenarioId());
|
||||
sendConsumeMsg.setCmdType("battleConsume");
|
||||
Global.sendCmdInfoQueue.add(sendConsumeMsg);
|
||||
BattleConsume battleConsume = new BattleConsume();
|
||||
battleConsume.setLat(teamLat);
|
||||
battleConsume.setLng(teamLng);
|
||||
battleConsume.setId(IdUtils.simpleUUID());
|
||||
battleConsume.setAmmunition(ammunitionConsume);
|
||||
battleConsume.setDeath(Integer.valueOf(Double.valueOf(deathConsume).intValue()));
|
||||
battleConsume.setInjured(Integer.valueOf(Double.valueOf(injuredConsume).intValue()));
|
||||
battleConsume.setFood(foodConsume);
|
||||
battleConsume.setFuel(fuelConsume);
|
||||
battleConsume.setMedical(medicalConsume);
|
||||
battleConsume.setWater(waterConsume);
|
||||
battleConsume.setResourceId(scenarioTask.getResourceId());
|
||||
battleConsumeService.save(battleConsume);
|
||||
}catch (Exception ex){
|
||||
ex.printStackTrace();
|
||||
log.error("==================推送消耗數據 失败============================================",ex.getMessage());
|
||||
}
|
||||
|
||||
try {
|
||||
LocalDateTime currentDateTime = new Date().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
|
||||
String death = SpringUtil.getBean(Environment.class).getProperty("battle.death.warn");
|
||||
String injured = SpringUtil.getBean(Environment.class).getProperty("battle.injured.warn");
|
||||
String ammunition = SpringUtil.getBean(Environment.class).getProperty("battle.ammunition.warn");
|
||||
String death = SpringUtil.getBean(Environment.class).getProperty("death.warn");
|
||||
String injured = SpringUtil.getBean(Environment.class).getProperty("injured.warn");
|
||||
String ammunition = SpringUtil.getBean(Environment.class).getProperty("ammunition.warn");
|
||||
log.info("===========person ammunition==={}===={}====={}========",death,injured,ammunition);
|
||||
// String food = SpringUtil.getBean(Environment.class).getProperty("battle.food.warn");
|
||||
// String water = SpringUtil.getBean(Environment.class).getProperty("battle.water.warn");
|
||||
// String fuel = SpringUtil.getBean(Environment.class).getProperty("battle.fuel.warn");
|
||||
// String medical = SpringUtil.getBean(Environment.class).getProperty("battle.medical.warn");
|
||||
|
||||
if(Double.valueOf(battleParams.get("ammunition").toString()) <= Double.valueOf(ammunition) && suppleFlagMap.get("ammunition") == false){
|
||||
|
||||
HashMap<String,Object> battleConsumeMap = (HashMap<String, Object>) redisUtil.hget(scenarioTask.getScenarioId() + "-" + roomId + "-" + scenarioTask.getResourceId());
|
||||
Double restAmmunition = Double.valueOf(battleConsumeMap.get("ammunition").toString());
|
||||
StatisticBean battleResourceStat = statisticService.statistic(scenarioTask.getResourceId());
|
||||
Double ammunitionConsumeRate = restAmmunition/battleResourceStat.getAmmunition().getTotal()*100;
|
||||
if(Double.valueOf(ammunitionConsumeRate) <= Double.valueOf(ammunition) && suppleFlagMap.get("ammunition") == false){
|
||||
SupplierRequest supplierRequest = new SupplierRequest();
|
||||
supplierRequest.setId(IdUtils.simpleUUID());
|
||||
supplierRequest.setFromResourceId(scenarioTask.getResourceId());
|
||||
|
|
@ -197,7 +222,9 @@ public class BattleRootTask extends AbtParentTask {
|
|||
supplierRequestService.save(supplierRequest);
|
||||
suppleFlagMap.put("ammunition",true) ;
|
||||
}
|
||||
if(Long.valueOf(battleParams.get("death").toString()) <= Long.valueOf(death) && suppleFlagMap.get("death") == false){
|
||||
Long restDeath = Long.valueOf(battleConsumeMap.get("death").toString());
|
||||
Long deathConsumeRate = restDeath*100/battleResourceStat.getPerson().getTotal();
|
||||
if(deathConsumeRate >= Long.valueOf(death) && suppleFlagMap.get("death") == false){
|
||||
SupplierRequest supplierRequest = new SupplierRequest();
|
||||
supplierRequest.setId(IdUtils.simpleUUID());
|
||||
supplierRequest.setFromResourceId(scenarioTask.getResourceId());
|
||||
|
|
@ -209,7 +236,9 @@ public class BattleRootTask extends AbtParentTask {
|
|||
supplierRequestService.save(supplierRequest);
|
||||
suppleFlagMap.put("death",true) ;
|
||||
}
|
||||
if(Long.valueOf(battleParams.get("injured").toString()) <= Long.valueOf(injured) && suppleFlagMap.get("injured") == false){
|
||||
Long restInjured = Long.valueOf(battleConsumeMap.get("injured").toString());
|
||||
Long injuredConsumeRate = restInjured*100/battleResourceStat.getPerson().getTotal();
|
||||
if(Long.valueOf(injuredConsumeRate) <= Long.valueOf(injured) && suppleFlagMap.get("injured") == false){
|
||||
SupplierRequest supplierRequest = new SupplierRequest();
|
||||
supplierRequest.setId(IdUtils.simpleUUID());
|
||||
supplierRequest.setFromResourceId(scenarioTask.getResourceId());
|
||||
|
|
@ -229,14 +258,11 @@ public class BattleRootTask extends AbtParentTask {
|
|||
}
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
19
src/main/java/com/hivekion/room/bean/Coordinate.java
Normal file
19
src/main/java/com/hivekion/room/bean/Coordinate.java
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
package com.hivekion.room.bean;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* [类的简要说明]
|
||||
* <p>
|
||||
* [详细描述,可选]
|
||||
* <p>
|
||||
*
|
||||
* @author LiDongYU
|
||||
* @since 2025/7/22
|
||||
*/
|
||||
@Data
|
||||
public class Coordinate {
|
||||
|
||||
private double lng;
|
||||
private double lat;
|
||||
}
|
||||
|
|
@ -1,27 +1,24 @@
|
|||
package com.hivekion.room.bean;
|
||||
|
||||
import cn.hutool.extra.spring.SpringUtil;
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONArray;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.hivekion.Global;
|
||||
import com.hivekion.common.MultiPointGeoPosition;
|
||||
import com.hivekion.common.entity.ResponseCmdInfo;
|
||||
import com.hivekion.enums.WsCmdTypeEnum;
|
||||
import com.hivekion.common.redis.RedisUtil;
|
||||
import com.hivekion.common.uuid.IdUtils;
|
||||
import com.hivekion.room.RoomManager;
|
||||
import com.hivekion.room.func.TaskAction;
|
||||
import com.hivekion.scenario.entity.ScenarioResource;
|
||||
import com.hivekion.scenario.entity.ScenarioTask;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import com.hivekion.scenario.service.impl.BattleSupplierServiceImpl;
|
||||
import com.hivekion.scenario.service.impl.ScenarioTaskServiceImpl;
|
||||
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.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.NavigableMap;
|
||||
import java.util.TreeMap;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import lombok.Data;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.core.env.Environment;
|
||||
|
||||
|
|
@ -42,13 +39,23 @@ public class MoveRootTask extends AbtParentTask implements TaskAction {
|
|||
*/
|
||||
private final double SPEED = 27;
|
||||
/**
|
||||
* 距离和坐标的对应关系
|
||||
* 需求产生标志
|
||||
*/
|
||||
private final TreeMap<Double, Coordinate> distanceInfoMap = new TreeMap<>();
|
||||
private final AtomicBoolean requestFlag = new AtomicBoolean(false);
|
||||
/**
|
||||
* 开始点坐标
|
||||
* 油料消耗速率
|
||||
*/
|
||||
private final AtomicReference<Double> startPoint = new AtomicReference<>();
|
||||
private double fuelConsumption = 0;
|
||||
private double fuelThreshold = 0;
|
||||
/**
|
||||
* 消耗任务间隔
|
||||
*/
|
||||
private final int consumptionTaskInterval = 5;
|
||||
/**
|
||||
* redis 服务类
|
||||
*/
|
||||
private final RedisUtil redis = SpringUtil.getBean(RedisUtil.class);
|
||||
private StatisticBean statisticBean;
|
||||
|
||||
|
||||
public MoveRootTask(ScenarioTask scenarioTask, String roomId) {
|
||||
|
|
@ -58,176 +65,113 @@ public class MoveRootTask extends AbtParentTask implements TaskAction {
|
|||
|
||||
@Override
|
||||
public void doSomeThing() {
|
||||
log.info("move task running");
|
||||
log.info("move task running:{}",scenarioTask.getResourceId());
|
||||
|
||||
initEnv(); //初始化环境
|
||||
initPath(); //初始化路径
|
||||
updatePath(); //更新路径
|
||||
updatePath(SPEED, null); //更新路径
|
||||
fuelConsumption();//油品消耗
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化路径
|
||||
* 初始化环境
|
||||
*/
|
||||
private void initPath() {
|
||||
try {
|
||||
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"));
|
||||
statisticBean = SpringUtil.getBean(StatisticServiceImpl.class)
|
||||
.statistic(scenarioTask.getResourceId());
|
||||
}catch (Exception e){
|
||||
log.error("init env exception",e);
|
||||
}
|
||||
|
||||
String url = SpringUtil.getBean(Environment.class).getProperty("path.planning.url");
|
||||
String params = url + "?"
|
||||
+ "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(params)
|
||||
.retrieve()
|
||||
.bodyToMono(String.class)
|
||||
.block();
|
||||
}
|
||||
|
||||
JSONObject pointJson = JSON.parseObject(result);
|
||||
//获取路径点
|
||||
if (pointJson != null) {
|
||||
JSONObject pointsObj = pointJson.getJSONArray("paths").getJSONObject(0)
|
||||
.getJSONObject("points");
|
||||
JSONArray coordinates = pointsObj.getJSONArray("coordinates");
|
||||
//组装信息
|
||||
Map<String, Object> dataMap = new HashMap<>();
|
||||
dataMap.put("resourceId", scenarioTask.getResourceId());
|
||||
dataMap.put("points", coordinates);
|
||||
//推送路径任务
|
||||
Global.sendCmdInfoQueue.add(
|
||||
ResponseCmdInfo.create(WsCmdTypeEnum.PATH_INIT.getCode(), roomId,
|
||||
scenarioTask.getScenarioId(), dataMap));
|
||||
log.info("init::{}", JSON.toJSONString(coordinates));
|
||||
//计算各个点的累计距离和坐标的对应关系
|
||||
double beforeLng = Double.parseDouble(scenarioTask.getFromLng());
|
||||
double beforeLat = Double.parseDouble(scenarioTask.getFromLat());
|
||||
double total = 0;
|
||||
for (int i = 0; i < coordinates.size(); i++) {
|
||||
JSONArray coordinate = coordinates.getJSONArray(i);
|
||||
Double lng = coordinate.getDouble(0);
|
||||
|
||||
Double lat = coordinate.getDouble(1);
|
||||
private void fuelConsumption() {
|
||||
try{
|
||||
ScheduledExecutorService schedule = Executors.newScheduledThreadPool(
|
||||
1);
|
||||
schedule.scheduleWithFixedDelay(() -> {
|
||||
if (getRoomStatus()) {
|
||||
double currentUseUp = consumptionTaskInterval * SPEED / 1000 * fuelConsumption;
|
||||
|
||||
double distance = MultiPointGeoPosition.haversine(beforeLat, beforeLng, lat, lng);
|
||||
//当前总距离
|
||||
total = total + distance;
|
||||
//定义坐标对象
|
||||
Coordinate coordinateInfo = new Coordinate();
|
||||
coordinateInfo.setLat(lat);
|
||||
coordinateInfo.setLng(lng);
|
||||
//更新redis中油品的消耗
|
||||
Object currentFuelObj = redis.hget(
|
||||
scenarioTask.getScenarioId() + "-" + roomId + "-" + scenarioTask.getResourceId(),
|
||||
"fuel");
|
||||
if (currentFuelObj != null) {
|
||||
double fuel = Double.parseDouble(currentFuelObj.toString());
|
||||
fuel = fuel - currentUseUp;
|
||||
|
||||
//记录距离和数组列表直接的索引关系
|
||||
distanceInfoMap.put(total, coordinateInfo);
|
||||
redis.hset(
|
||||
scenarioTask.getScenarioId() + "-" + roomId + "-" + scenarioTask.getResourceId(),
|
||||
"fuelConsume", fuel);
|
||||
|
||||
beforeLng = lng;
|
||||
beforeLat = lat;
|
||||
double totalFuel = statisticBean.getFuel().getTotal();
|
||||
if (fuel * 100 / totalFuel < fuelThreshold && !requestFlag.get()) {
|
||||
requestFlag.set(true);
|
||||
//需要产生需求
|
||||
produceFuelRequest();
|
||||
//产生任务
|
||||
produceTask();
|
||||
|
||||
}
|
||||
}
|
||||
//插入消耗表
|
||||
}
|
||||
//设置第一个开始位置
|
||||
startPoint.set(distanceInfoMap.firstKey());
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("error::", e);
|
||||
|
||||
}, 0, consumptionTaskInterval, TimeUnit.SECONDS);
|
||||
}catch (Exception e){
|
||||
log.error("fuel consumption exception",e);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void produceFuelRequest() {
|
||||
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() {
|
||||
|
||||
List<ScenarioResource> resourceList = SpringUtil.getBean(BattleSupplierServiceImpl.class)
|
||||
.selectSupplierResource(scenarioTask.getResourceId());
|
||||
if (!resourceList.isEmpty()) {
|
||||
ScenarioTask task = new ScenarioTask();
|
||||
task.setId(IdUtils.simpleUUID());
|
||||
task.setScenarioId(scenarioTask.getScenarioId());
|
||||
task.setResourceId(scenarioTask.getResourceId());
|
||||
task.setTaskType("6");
|
||||
task.setSupplierNum(statisticBean.getFuel().getTotal());
|
||||
task.setToLat(scenarioTask.getToLat());
|
||||
task.setToLng(scenarioTask.getToLng());
|
||||
task.setStartTime(LocalDateTime.now());
|
||||
task.setFromLat(resourceList.get(0).getLat());
|
||||
task.setFromLng(resourceList.get(0).getLng());
|
||||
task.setFromSource("general");
|
||||
SpringUtil.getBean(ScenarioTaskServiceImpl.class).save(task);
|
||||
//增加到房间任务
|
||||
SupplierTask supplierTask = new SupplierTask(task, roomId);
|
||||
//立即执行
|
||||
RoomManager.addAction(roomId, 0, supplierTask);
|
||||
}
|
||||
}
|
||||
|
||||
private void updatePath() {
|
||||
|
||||
ScheduledExecutorService schedule = Executors.newScheduledThreadPool(
|
||||
1);
|
||||
schedule.scheduleWithFixedDelay(() -> {
|
||||
|
||||
try {
|
||||
if (this.getRoomStatus()) {
|
||||
|
||||
long duringTime = getDuringTime();
|
||||
log.info("duringTime::{}", duringTime);
|
||||
//跑动距离
|
||||
double distance = duringTime * SPEED;
|
||||
//获取大与此距离的第一个路线点key
|
||||
Entry<Double, Coordinate> endPoint = distanceInfoMap.ceilingEntry(distance);
|
||||
//ws数据
|
||||
List<double[]> dataList = new ArrayList<>();
|
||||
HashMap<Object, Object> dataMap = new HashMap<>();
|
||||
dataMap.put("resourceId", scenarioTask.getResourceId());
|
||||
dataMap.put("points", dataList);
|
||||
|
||||
if (Double.compare(distance, endPoint.getKey()) < 0) {
|
||||
//获取小于最大值的第一个key
|
||||
Double lowerKey = distanceInfoMap.lowerKey(endPoint.getKey());
|
||||
// log.info("distance::{},lowerKey::{},endPoint{}",distance,lowerKey,endPoint.getKey());
|
||||
//获取从上一个开始节点到lowKey的数据
|
||||
NavigableMap<Double, Coordinate> subPathMap = distanceInfoMap.subMap(startPoint.get(),
|
||||
true, lowerKey, true);
|
||||
for (Double key : subPathMap.keySet()) {
|
||||
Coordinate coordinate = subPathMap.get(key);
|
||||
dataList.add(new double[]{coordinate.getLng(), coordinate.getLat()});
|
||||
}
|
||||
double diff =distance - lowerKey ;
|
||||
|
||||
//插入值
|
||||
double[] insertPoints = MultiPointGeoPosition.pointAlong(
|
||||
distanceInfoMap.get(lowerKey).getLat(), distanceInfoMap.get(lowerKey).getLng(),
|
||||
endPoint.getValue().getLat(), endPoint.getValue().getLng(), diff);
|
||||
|
||||
|
||||
|
||||
dataList.add(new double[]{insertPoints[1], insertPoints[0]});
|
||||
|
||||
Coordinate coordinate = new Coordinate();
|
||||
coordinate.setLat(insertPoints[0]);
|
||||
coordinate.setLng(insertPoints[1]);
|
||||
distanceInfoMap.put(distance, coordinate);
|
||||
startPoint.set(distance);
|
||||
|
||||
|
||||
Global.sendCmdInfoQueue.add(
|
||||
ResponseCmdInfo.create(WsCmdTypeEnum.PATH_UPDATE.getCode(), roomId,
|
||||
scenarioTask.getScenarioId(), dataMap));
|
||||
|
||||
} else if (Double.compare(distance, endPoint.getKey()) == 0) {
|
||||
NavigableMap<Double, Coordinate> subPathMap = distanceInfoMap.subMap(startPoint.get(),
|
||||
true, endPoint.getKey(), true);
|
||||
for (Double key : subPathMap.keySet()) {
|
||||
Coordinate coordinate = subPathMap.get(key);
|
||||
dataList.add(new double[]{coordinate.getLng(), coordinate.getLat()});
|
||||
}
|
||||
|
||||
startPoint.set(endPoint.getKey());
|
||||
Global.sendCmdInfoQueue.add(
|
||||
ResponseCmdInfo.create(WsCmdTypeEnum.PATH_UPDATE.getCode(), roomId,
|
||||
scenarioTask.getScenarioId(), dataMap));
|
||||
|
||||
} else {
|
||||
//完成路径
|
||||
Global.sendCmdInfoQueue.add(
|
||||
ResponseCmdInfo.create(WsCmdTypeEnum.PATH_FINISHED.getCode(), roomId,
|
||||
scenarioTask.getScenarioId(), dataMap));
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("error::", e);
|
||||
}
|
||||
|
||||
|
||||
}, 0, 1, TimeUnit.SECONDS);
|
||||
|
||||
//房间统一管理定时器;房间关闭后,定时器销毁
|
||||
addScheduledExecutorServiceRefenceToRoom(schedule);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Data
|
||||
class Coordinate {
|
||||
|
||||
double lng;
|
||||
double lat;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ public class Room implements AutoCloseable {
|
|||
//线程池
|
||||
private final ExecutorService actionExecutor =
|
||||
new ThreadPoolExecutor(
|
||||
5, 5, // corePoolSize, maximumPoolSize
|
||||
5, 100, // corePoolSize, maximumPoolSize
|
||||
0L, TimeUnit.MILLISECONDS,
|
||||
new LinkedBlockingQueue<>(1000), // 有界队列,只允许100个待执行任务
|
||||
new ThreadPoolExecutor.AbortPolicy() // 超出直接抛异常
|
||||
|
|
@ -119,9 +119,7 @@ public class Room implements AutoCloseable {
|
|||
return duringTime.get();
|
||||
}
|
||||
|
||||
public long getTotalTime() {
|
||||
return totalTime.get();
|
||||
}
|
||||
|
||||
|
||||
// 启动定时任务
|
||||
private void startTask() {
|
||||
|
|
@ -132,7 +130,7 @@ public class Room implements AutoCloseable {
|
|||
if (magValue != null) {
|
||||
this.mag = magValue.getMag();
|
||||
}
|
||||
log.info("mag:{}", mag);
|
||||
|
||||
long curTime = duringTime.addAndGet(this.mag);
|
||||
|
||||
sendRemainTime((totalTime.get() - curTime));
|
||||
|
|
|
|||
|
|
@ -1,7 +1,11 @@
|
|||
package com.hivekion.room.bean;
|
||||
|
||||
import cn.hutool.extra.spring.SpringUtil;
|
||||
import com.hivekion.common.redis.RedisUtil;
|
||||
import com.hivekion.room.func.TaskAction;
|
||||
import com.hivekion.scenario.entity.ScenarioTask;
|
||||
import com.hivekion.statistic.bean.StatisticBean;
|
||||
import com.hivekion.statistic.service.StatisticService;
|
||||
|
||||
/**
|
||||
* [类的简要说明]
|
||||
|
|
@ -14,19 +18,94 @@ import com.hivekion.scenario.entity.ScenarioTask;
|
|||
*/
|
||||
public class SupplierTask extends AbtParentTask implements TaskAction {
|
||||
|
||||
public SupplierTask(ScenarioTask scenarioTask,String roomId) {
|
||||
super(scenarioTask,roomId);
|
||||
public SupplierTask(ScenarioTask scenarioTask, String roomId) {
|
||||
super(scenarioTask, roomId);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void doSomeThing() {
|
||||
StatisticBean statistic = SpringUtil.getBean(StatisticService.class)
|
||||
.statistic(scenarioTask.getResourceId());
|
||||
initPath(); //初始化路径
|
||||
updatePath(30, new TaskAction() {
|
||||
|
||||
@Override
|
||||
public void doSomeThing() {
|
||||
//达到终点点后,给目标补充物资
|
||||
switch (scenarioTask.getTaskType()) {
|
||||
case "4":
|
||||
supplierAmmunition(statistic);
|
||||
break;
|
||||
case "5":
|
||||
supplierWater(statistic);
|
||||
break;
|
||||
case "6":
|
||||
supplierFuel(statistic);
|
||||
break;
|
||||
case "7":
|
||||
supplierFood(statistic);
|
||||
break;
|
||||
case "8":
|
||||
supplierMedical(statistic);
|
||||
break;
|
||||
}
|
||||
//推送最新状态信息
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return "";
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void supplierMedical(StatisticBean statistic) {
|
||||
|
||||
SpringUtil.getBean(RedisUtil.class)
|
||||
.hset(scenarioTask.getScenarioId() + "-" + roomId + "-" + scenarioTask.getResourceId(),
|
||||
"medical", statistic.getMedical().getTotal()+"");
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void supplierFuel(StatisticBean statistic) {
|
||||
|
||||
SpringUtil.getBean(RedisUtil.class)
|
||||
.hset(scenarioTask.getScenarioId() + "-" + roomId + "-" + scenarioTask.getResourceId(),
|
||||
"fuel", statistic.getFuel().getTotal()+"");
|
||||
|
||||
}
|
||||
|
||||
private void supplierAmmunition(StatisticBean statistic) {
|
||||
|
||||
SpringUtil.getBean(RedisUtil.class)
|
||||
.hset(scenarioTask.getScenarioId() + "-" + roomId + "-" + scenarioTask.getResourceId(),
|
||||
"ammunition", statistic.getAmmunition().getTotal()+"");
|
||||
|
||||
}
|
||||
|
||||
private void supplierWater(StatisticBean statistic) {
|
||||
|
||||
SpringUtil.getBean(RedisUtil.class)
|
||||
.hset(scenarioTask.getScenarioId() + "-" + roomId + "-" + scenarioTask.getResourceId(),
|
||||
"water", statistic.getWater().getTotal()+"");
|
||||
|
||||
}
|
||||
|
||||
private void supplierFood(StatisticBean statistic) {
|
||||
|
||||
SpringUtil.getBean(RedisUtil.class)
|
||||
.hset(scenarioTask.getScenarioId() + "-" + roomId + "-" + scenarioTask.getResourceId(),
|
||||
"food", statistic.getFood().getTotal()+"");
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
package com.hivekion.scenario.controller;
|
||||
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.stereotype.Controller;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 战斗消耗 前端控制器
|
||||
* </p>
|
||||
*
|
||||
* @author liDongYu
|
||||
* @since 2025-09-19
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping("/scenario/battleConsume")
|
||||
public class BattleConsumeController {
|
||||
|
||||
}
|
||||
155
src/main/java/com/hivekion/scenario/entity/BattleConsume.java
Normal file
155
src/main/java/com/hivekion/scenario/entity/BattleConsume.java
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
package com.hivekion.scenario.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 战斗消耗
|
||||
* </p>
|
||||
*
|
||||
* @author liDongYu
|
||||
* @since 2025-09-19
|
||||
*/
|
||||
@TableName("TBL_BATTLE_CONSUME")
|
||||
@ApiModel(value = "BattleConsume对象", description = "战斗消耗")
|
||||
public class BattleConsume implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@ApiModelProperty("物理主键")
|
||||
private String id;
|
||||
|
||||
@ApiModelProperty("资源编号")
|
||||
@TableField(value = "resource_id")
|
||||
private String resourceId;
|
||||
|
||||
private Double ammunition;
|
||||
|
||||
private Integer death;
|
||||
|
||||
private Integer injured;
|
||||
|
||||
private Double fuel;
|
||||
|
||||
private Double food;
|
||||
|
||||
private Double water;
|
||||
|
||||
private Double medical;
|
||||
|
||||
private String lat;
|
||||
|
||||
private String lng;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getResourceId() {
|
||||
return resourceId;
|
||||
}
|
||||
|
||||
public void setResourceId(String resourceId) {
|
||||
this.resourceId = resourceId;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public Integer getDeath() {
|
||||
return death;
|
||||
}
|
||||
|
||||
public void setDeath(Integer death) {
|
||||
this.death = death;
|
||||
}
|
||||
|
||||
public Integer getInjured() {
|
||||
return injured;
|
||||
}
|
||||
|
||||
public void setInjured(Integer injured) {
|
||||
this.injured = injured;
|
||||
}
|
||||
|
||||
public Double getAmmunition() {
|
||||
return ammunition;
|
||||
}
|
||||
|
||||
public void setAmmunition(Double ammunition) {
|
||||
this.ammunition = ammunition;
|
||||
}
|
||||
|
||||
public Double getFuel() {
|
||||
return fuel;
|
||||
}
|
||||
|
||||
public void setFuel(Double fuel) {
|
||||
this.fuel = fuel;
|
||||
}
|
||||
|
||||
public Double getFood() {
|
||||
return food;
|
||||
}
|
||||
|
||||
public void setFood(Double food) {
|
||||
this.food = food;
|
||||
}
|
||||
|
||||
public Double getWater() {
|
||||
return water;
|
||||
}
|
||||
|
||||
public void setWater(Double water) {
|
||||
this.water = water;
|
||||
}
|
||||
|
||||
public Double getMedical() {
|
||||
return medical;
|
||||
}
|
||||
|
||||
public void setMedical(Double medical) {
|
||||
this.medical = medical;
|
||||
}
|
||||
|
||||
public String getLat() {
|
||||
return lat;
|
||||
}
|
||||
|
||||
public void setLat(String lat) {
|
||||
this.lat = lat;
|
||||
}
|
||||
|
||||
public String getLng() {
|
||||
return lng;
|
||||
}
|
||||
|
||||
public void setLng(String lng) {
|
||||
this.lng = lng;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "BattleConsume{" +
|
||||
"id = " + id +
|
||||
", resourceId = " + resourceId +
|
||||
", ammunition = " + ammunition +
|
||||
", death = " + death +
|
||||
", injured = " + injured +
|
||||
", fuel = " + fuel +
|
||||
", food = " + food +
|
||||
", water = " + water +
|
||||
", medical = " + medical +
|
||||
", lat = " + lat +
|
||||
", lng = " + lng +
|
||||
"}";
|
||||
}
|
||||
}
|
||||
|
|
@ -64,5 +64,6 @@ public class ScenarioTask implements Serializable {
|
|||
private String supplierResourceId;
|
||||
@TableField(value = "supplier_num")
|
||||
private double supplierNum;
|
||||
|
||||
@TableField(value="from_source")
|
||||
private String fromSource;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
package com.hivekion.scenario.mapper;
|
||||
|
||||
import com.hivekion.scenario.entity.BattleConsume;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 战斗消耗 Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author liDongYu
|
||||
* @since 2025-09-19
|
||||
*/
|
||||
public interface BattleConsumeMapper extends BaseMapper<BattleConsume> {
|
||||
|
||||
}
|
||||
|
|
@ -2,6 +2,8 @@ package com.hivekion.scenario.mapper;
|
|||
|
||||
import com.hivekion.scenario.entity.BattleSupplier;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.hivekion.scenario.entity.ScenarioResource;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
|
|
@ -12,5 +14,5 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
|||
* @since 2025-09-15
|
||||
*/
|
||||
public interface BattleSupplierMapper extends BaseMapper<BattleSupplier> {
|
||||
|
||||
List<ScenarioResource> selectSupplierResource(String battleResourceId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
package com.hivekion.scenario.service;
|
||||
|
||||
import com.hivekion.scenario.entity.BattleConsume;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 战斗消耗 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author liDongYu
|
||||
* @since 2025-09-19
|
||||
*/
|
||||
public interface IBattleConsumeService extends IService<BattleConsume> {
|
||||
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@ package com.hivekion.scenario.service;
|
|||
|
||||
import com.hivekion.scenario.entity.BattleSupplier;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.hivekion.scenario.entity.ScenarioResource;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
|
|
@ -16,4 +17,5 @@ import java.util.Set;
|
|||
public interface IBattleSupplierService extends IService<BattleSupplier> {
|
||||
public Set<String> getBattleResourceBySupplierId(String id);
|
||||
public Set<String> getSupplierIdByBattleId(String id);
|
||||
List<ScenarioResource> selectSupplierResource(String battleResourceId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
package com.hivekion.scenario.service.impl;
|
||||
|
||||
import com.hivekion.scenario.entity.BattleConsume;
|
||||
import com.hivekion.scenario.mapper.BattleConsumeMapper;
|
||||
import com.hivekion.scenario.service.IBattleConsumeService;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 战斗消耗 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author liDongYu
|
||||
* @since 2025-09-19
|
||||
*/
|
||||
@Service
|
||||
public class BattleConsumeServiceImpl extends ServiceImpl<BattleConsumeMapper, BattleConsume> implements IBattleConsumeService {
|
||||
|
||||
}
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
package com.hivekion.scenario.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.hivekion.scenario.entity.BattleSupplier;
|
||||
import com.hivekion.scenario.entity.ScenarioResource;
|
||||
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;
|
||||
|
|
@ -13,19 +13,20 @@ import org.springframework.stereotype.Service;
|
|||
|
||||
/**
|
||||
* <p>
|
||||
* 服务实现类
|
||||
* 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author liDongYu
|
||||
* @since 2025-09-15
|
||||
*/
|
||||
@Service
|
||||
public class BattleSupplierServiceImpl extends ServiceImpl<BattleSupplierMapper, BattleSupplier> implements IBattleSupplierService {
|
||||
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);
|
||||
queryWrapper.eq("supplier_resource_id", id);
|
||||
List<BattleSupplier> list = this.list(queryWrapper);
|
||||
return list.stream().map(BattleSupplier::getBattleResourceId).collect(Collectors.toSet());
|
||||
}
|
||||
|
|
@ -33,9 +34,14 @@ public class BattleSupplierServiceImpl extends ServiceImpl<BattleSupplierMapper,
|
|||
@Override
|
||||
public Set<String> getSupplierIdByBattleId(String id) {
|
||||
QueryWrapper<BattleSupplier> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("battle_resource_id",id);
|
||||
queryWrapper.eq("battle_resource_id", id);
|
||||
List<BattleSupplier> list = this.list(queryWrapper);
|
||||
|
||||
return list.stream().map(BattleSupplier::getSupplierResourceId).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ScenarioResource> selectSupplierResource(String battleResourceId) {
|
||||
return this.baseMapper.selectSupplierResource(battleResourceId);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -144,6 +144,7 @@ public class ScenarioTaskServiceImpl extends
|
|||
ScenarioTask scenarioTask = new ScenarioTask();
|
||||
scenarioTask.setScenarioId(scenario.getId());
|
||||
List<ScenarioTask> taskList = this.queryTaskList(scenarioTask);
|
||||
log.info("taskList.size ::{}", taskList.size());
|
||||
for (ScenarioTask task : taskList) {
|
||||
try {
|
||||
long diff = Duration.between(scenario.getStartTime(),task.getStartTime())
|
||||
|
|
@ -152,6 +153,7 @@ public class ScenarioTaskServiceImpl extends
|
|||
switch (task.getTaskType()) {
|
||||
//移动任务
|
||||
case "1":
|
||||
log.info("move task::{}",diff);
|
||||
MoveRootTask moveRootTask = new MoveRootTask(task, roomId);
|
||||
RoomManager.addAction(roomId, diff, moveRootTask);
|
||||
break;
|
||||
|
|
@ -166,6 +168,7 @@ public class ScenarioTaskServiceImpl extends
|
|||
case "6":
|
||||
case "7":
|
||||
case "8":
|
||||
log.info("supplier task::{}",diff);
|
||||
SupplierTask supplierTask = new SupplierTask(task, roomId);
|
||||
RoomManager.addAction(roomId, diff, supplierTask);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -2,103 +2,54 @@ package com.hivekion.supplier.entity;
|
|||
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
*
|
||||
*
|
||||
* </p>
|
||||
*
|
||||
* @author liDongYu
|
||||
* @since 2025-09-18
|
||||
*/
|
||||
@Data
|
||||
@TableName("TBL_SUPPLIER_REQUEST")
|
||||
@ApiModel(value = "SupplierRequest对象", description = "")
|
||||
public class SupplierRequest implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@TableField(value="ID")
|
||||
private String id;
|
||||
@TableField(value = "ID")
|
||||
private String id;
|
||||
|
||||
@TableField(value="GENERAL_TIME")
|
||||
private LocalDateTime generalTime;
|
||||
@TableField(value = "GENERAL_TIME")
|
||||
private LocalDateTime generalTime;
|
||||
|
||||
@TableField(value="FROM_RESOURCE_ID")
|
||||
private String fromResourceId;
|
||||
@TableField(value = "FROM_RESOURCE_ID")
|
||||
private String fromResourceId;
|
||||
|
||||
@TableField(value="SUPPLIER_TYPE")
|
||||
private String supplierType;
|
||||
@TableField(value="SUPPLIER_NUM")
|
||||
private String supplierNum;
|
||||
@TableField(value = "SUPPLIER_TYPE")
|
||||
private String supplierType;
|
||||
@TableField(value = "SUPPLIER_NUM")
|
||||
private String supplierNum;
|
||||
@TableField(value = "LAT")
|
||||
private String lat;
|
||||
@TableField(value = "LNG")
|
||||
private String lng;
|
||||
/**
|
||||
* 0 未处理 ;1 处理
|
||||
*/
|
||||
@TableField(value = "handle_flag")
|
||||
private int handleFlag;
|
||||
|
||||
@TableField(value="LAT")
|
||||
private String lat;
|
||||
@TableField(value="LNG")
|
||||
private String lng;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public LocalDateTime getGeneralTime() {
|
||||
return generalTime;
|
||||
}
|
||||
|
||||
public void setGeneralTime(LocalDateTime generalTime) {
|
||||
this.generalTime = generalTime;
|
||||
}
|
||||
|
||||
public String getFromResourceId() {
|
||||
return fromResourceId;
|
||||
}
|
||||
|
||||
public void setFromResourceId(String fromResourceId) {
|
||||
this.fromResourceId = fromResourceId;
|
||||
}
|
||||
|
||||
public String getSupplierType() {
|
||||
return supplierType;
|
||||
}
|
||||
|
||||
public void setSupplierType(String supplierType) {
|
||||
this.supplierType = supplierType;
|
||||
}
|
||||
|
||||
public String getSupplierNum() {
|
||||
return supplierNum;
|
||||
}
|
||||
|
||||
public void setSupplierNum(String supplierNum) {
|
||||
this.supplierNum = supplierNum;
|
||||
}
|
||||
|
||||
public String getLat() {
|
||||
return lat;
|
||||
}
|
||||
|
||||
public void setLat(String lat) {
|
||||
this.lat = lat;
|
||||
}
|
||||
|
||||
public String getLng() {
|
||||
return lng;
|
||||
}
|
||||
|
||||
public void setLng(String lng) {
|
||||
this.lng = lng;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SupplierRequest{" +
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SupplierRequest{" +
|
||||
"id = " + id +
|
||||
", generalTime = " + generalTime +
|
||||
", fromResourceId = " + fromResourceId +
|
||||
|
|
@ -107,5 +58,5 @@ public class SupplierRequest implements Serializable {
|
|||
", lat = " + lat +
|
||||
", lng = " + lng +
|
||||
"}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ import java.util.stream.Collectors;
|
|||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
|
@ -49,6 +50,7 @@ import org.springframework.web.bind.annotation.RestController;
|
|||
@Validated
|
||||
@RestController
|
||||
@Api(value = "登录管理", tags = {"认证管理-登录"})
|
||||
@Slf4j
|
||||
public class UserLoginController {
|
||||
|
||||
@Autowired
|
||||
|
|
@ -161,6 +163,7 @@ public class UserLoginController {
|
|||
throw new BusinessException(500, "客户端编码为空");
|
||||
}
|
||||
String capText = captchaProducer.createText();
|
||||
log.info("capText::{}",capText);
|
||||
try {
|
||||
Object o = redisUtil.get(clientCode);
|
||||
if (o != null) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
injured.warn = 20
|
||||
death.warn = 10
|
||||
injured.warn = 60
|
||||
death.warn = 56
|
||||
ammunition.warn = 3
|
||||
food.warn = 3
|
||||
water.warn = 3
|
||||
|
|
@ -7,8 +7,8 @@ fuel.warn = 2
|
|||
medical.warn = 1
|
||||
death.spreed = 3;
|
||||
injured.spreed = 3;
|
||||
ammunition_spreed = 2.6;
|
||||
food_spreed = 2.3;
|
||||
water_spreed = 3.6;
|
||||
fuel_spreed = 3.6;
|
||||
medical_spreed = 1.6;
|
||||
ammunition.spreed = 2.6;
|
||||
food.spreed = 2.3;
|
||||
water.spreed = 3.6;
|
||||
fuel.spreed = 3.6;
|
||||
medical.spreed = 1.6;
|
||||
5
src/main/resources/mapper/tbl/BattleConsumeMapper.xml
Normal file
5
src/main/resources/mapper/tbl/BattleConsumeMapper.xml
Normal 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.BattleConsumeMapper">
|
||||
|
||||
</mapper>
|
||||
|
|
@ -1,5 +1,11 @@
|
|||
<?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">
|
||||
<!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">
|
||||
|
||||
<select id="selectSupplierResource" resultType="com.hivekion.scenario.entity.ScenarioResource">
|
||||
select id ,lng,lat,scenario_Id as scenarioId, resource_name as resourceName
|
||||
from tbl_scenario_resource
|
||||
where resource_id in
|
||||
(select supplier_resource_id from tbl_battle_supplier where battle_resoure_id = #{battleResourceId})
|
||||
</select>
|
||||
</mapper>
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user