增加天气阻飞
This commit is contained in:
parent
305e40da0f
commit
1591170585
|
|
@ -0,0 +1,15 @@
|
||||||
|
package com.multictrl.common.constant;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Getter
|
||||||
|
public enum FlightTaskType {
|
||||||
|
ROUTE(1, "航线飞行"),
|
||||||
|
MANUAL(2, "手动飞行"),
|
||||||
|
SCHEDULED(3, "定时飞行");
|
||||||
|
|
||||||
|
private final Integer code;
|
||||||
|
private final String desc;
|
||||||
|
}
|
||||||
|
|
@ -13,6 +13,9 @@ public interface SysParamsKey {
|
||||||
String ZHIMOU_AI_APP_KEY = "zhimou_ai_app_key";
|
String ZHIMOU_AI_APP_KEY = "zhimou_ai_app_key";
|
||||||
String ZHIMOU_AI_APP_SECRET = "zhimou_ai_app_secret";
|
String ZHIMOU_AI_APP_SECRET = "zhimou_ai_app_secret";
|
||||||
|
|
||||||
|
//********************************* gaode *********************************//
|
||||||
|
String GAODE_API_KEY = "gaode_api_key";
|
||||||
|
|
||||||
//********************************* sys component *********************************//
|
//********************************* sys component *********************************//
|
||||||
String SRS_RTMP_MAP_URL = "srs_rtmp_map_url";
|
String SRS_RTMP_MAP_URL = "srs_rtmp_map_url";
|
||||||
String EMQX_MAP_URL = "emqx_map_url";
|
String EMQX_MAP_URL = "emqx_map_url";
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,70 @@
|
||||||
|
package com.multictrl.common.utils.weather;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 雾量工具类
|
||||||
|
*
|
||||||
|
* @author Sdy
|
||||||
|
* @since 1.0.0 2025/10/13
|
||||||
|
*/
|
||||||
|
public class FogUtils {
|
||||||
|
// 轻雾类天气现象
|
||||||
|
public static final String[] LIGHT_FOG_TYPES = {
|
||||||
|
"轻雾"
|
||||||
|
};
|
||||||
|
|
||||||
|
// 中雾类天气现象
|
||||||
|
public static final String[] MODERATE_FOG_TYPES = {
|
||||||
|
"雾",
|
||||||
|
"浓雾"
|
||||||
|
};
|
||||||
|
|
||||||
|
// 大雾类天气现象
|
||||||
|
public static final String[] HEAVY_FOG_TYPES = {
|
||||||
|
"强浓雾",
|
||||||
|
"大雾",
|
||||||
|
"特强浓雾"
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否为轻雾类
|
||||||
|
*/
|
||||||
|
public static boolean isMinFog(String fogType) {
|
||||||
|
return contains(LIGHT_FOG_TYPES, fogType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否为中雾类
|
||||||
|
*/
|
||||||
|
public static boolean isModerateFog(String fogType) {
|
||||||
|
return contains(MODERATE_FOG_TYPES, fogType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否为大雾类
|
||||||
|
*/
|
||||||
|
public static boolean isMaxFog(String fogType) {
|
||||||
|
return contains(HEAVY_FOG_TYPES, fogType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取雾类型所属的类别名称
|
||||||
|
*/
|
||||||
|
public static String getCategory(String fogType) {
|
||||||
|
if (isMinFog(fogType)) return "轻雾";
|
||||||
|
if (isModerateFog(fogType)) return "中雾";
|
||||||
|
if (isMaxFog(fogType)) return "大雾";
|
||||||
|
return "未知";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查字符串是否在数组中
|
||||||
|
*/
|
||||||
|
private static boolean contains(String[] array, String value) {
|
||||||
|
for (String item : array) {
|
||||||
|
if (item.equals(value)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,69 @@
|
||||||
|
package com.multictrl.common.utils.weather;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 霾量工具类
|
||||||
|
*
|
||||||
|
* @author Sdy
|
||||||
|
* @since 1.0.0 2025/10/13
|
||||||
|
*/
|
||||||
|
public class HazeUtils {
|
||||||
|
|
||||||
|
// 轻度霾类天气现象
|
||||||
|
public static final String[] LIGHT_HAZE_TYPES = {
|
||||||
|
"霾"
|
||||||
|
};
|
||||||
|
|
||||||
|
// 中度霾类天气现象
|
||||||
|
public static final String[] MODERATE_HAZE_TYPES = {
|
||||||
|
"中度霾"
|
||||||
|
};
|
||||||
|
|
||||||
|
// 重度霾类天气现象
|
||||||
|
public static final String[] HEAVY_HAZE_TYPES = {
|
||||||
|
"重度霾",
|
||||||
|
"严重霾"
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否为轻度霾类
|
||||||
|
*/
|
||||||
|
public static boolean isMinHaze(String hazeType) {
|
||||||
|
return contains(LIGHT_HAZE_TYPES, hazeType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否为中度霾类
|
||||||
|
*/
|
||||||
|
public static boolean isModerateHaze(String hazeType) {
|
||||||
|
return contains(MODERATE_HAZE_TYPES, hazeType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否为重度霾类
|
||||||
|
*/
|
||||||
|
public static boolean isMaxHaze(String hazeType) {
|
||||||
|
return contains(HEAVY_HAZE_TYPES, hazeType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取霾类型所属的类别名称
|
||||||
|
*/
|
||||||
|
public static String getCategory(String hazeType) {
|
||||||
|
if (isMinHaze(hazeType)) return "轻度霾";
|
||||||
|
if (isModerateHaze(hazeType)) return "中度霾";
|
||||||
|
if (isMaxHaze(hazeType)) return "重度霾";
|
||||||
|
return "未知";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查字符串是否在数组中
|
||||||
|
*/
|
||||||
|
private static boolean contains(String[] array, String value) {
|
||||||
|
for (String item : array) {
|
||||||
|
if (item.equals(value)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,87 @@
|
||||||
|
package com.multictrl.common.utils.weather;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 雨量工具类
|
||||||
|
*
|
||||||
|
* @author Sdy
|
||||||
|
* @since 1.0.0 2025/10/13
|
||||||
|
*/
|
||||||
|
public class RainfallUtils {
|
||||||
|
|
||||||
|
// 小雨类天气现象
|
||||||
|
public static final String[] LIGHT_RAIN_TYPES = {
|
||||||
|
"毛毛雨/细雨",
|
||||||
|
"小雨",
|
||||||
|
"阵雨",
|
||||||
|
"雷阵雨",
|
||||||
|
"雨雪天气",
|
||||||
|
"雨夹雪",
|
||||||
|
"阵雨夹雪",
|
||||||
|
"冻雨"
|
||||||
|
};
|
||||||
|
|
||||||
|
// 中雨类天气现象
|
||||||
|
public static final String[] MODERATE_RAIN_TYPES = {
|
||||||
|
"中雨",
|
||||||
|
"小雨-中雨",
|
||||||
|
"雷阵雨并伴有冰雹"
|
||||||
|
};
|
||||||
|
|
||||||
|
// 大雨类天气现象
|
||||||
|
public static final String[] HEAVY_RAIN_TYPES = {
|
||||||
|
"大雨",
|
||||||
|
"中雨-大雨",
|
||||||
|
"强阵雨",
|
||||||
|
"强雷阵雨",
|
||||||
|
"暴雨",
|
||||||
|
"大暴雨",
|
||||||
|
"特大暴雨",
|
||||||
|
"极端降雨",
|
||||||
|
"大雨-暴雨",
|
||||||
|
"暴雨-大暴雨",
|
||||||
|
"大暴雨-特大暴雨"
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否为小雨类
|
||||||
|
*/
|
||||||
|
public static boolean isMinRain(String precipitation) {
|
||||||
|
return contains(LIGHT_RAIN_TYPES, precipitation);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否为中雨类
|
||||||
|
*/
|
||||||
|
public static boolean isModerateRain(String precipitation) {
|
||||||
|
return contains(MODERATE_RAIN_TYPES, precipitation);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否为大雨类
|
||||||
|
*/
|
||||||
|
public static boolean isMaxRain(String precipitation) {
|
||||||
|
return contains(HEAVY_RAIN_TYPES, precipitation);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取降水类型所属的类别名称
|
||||||
|
*/
|
||||||
|
public static String getCategory(String precipitation) {
|
||||||
|
if (isMinRain(precipitation)) return "小雨";
|
||||||
|
if (isModerateRain(precipitation)) return "中雨";
|
||||||
|
if (isMaxRain(precipitation)) return "大雨";
|
||||||
|
return "未知";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查字符串是否在数组中
|
||||||
|
*/
|
||||||
|
private static boolean contains(String[] array, String value) {
|
||||||
|
for (String item : array) {
|
||||||
|
if (item.equals(value)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,76 @@
|
||||||
|
package com.multictrl.common.utils.weather;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 雪量工具类
|
||||||
|
*
|
||||||
|
* @author Sdy
|
||||||
|
* @since 1.0.0 2025/10/13
|
||||||
|
*/
|
||||||
|
public class SnowUtils {
|
||||||
|
// 小雪类天气现象
|
||||||
|
public static final String[] LIGHT_SNOW_TYPES = {
|
||||||
|
"雪",
|
||||||
|
"阵雪",
|
||||||
|
"小雪",
|
||||||
|
"雨雪天气",
|
||||||
|
"雨夹雪",
|
||||||
|
"阵雨夹雪"
|
||||||
|
};
|
||||||
|
|
||||||
|
// 中雪类天气现象
|
||||||
|
public static final String[] MODERATE_SNOW_TYPES = {
|
||||||
|
"中雪",
|
||||||
|
"小雪-中雪"
|
||||||
|
};
|
||||||
|
|
||||||
|
// 大雪类天气现象
|
||||||
|
public static final String[] HEAVY_SNOW_TYPES = {
|
||||||
|
"大雪",
|
||||||
|
"暴雪",
|
||||||
|
"中雪-大雪",
|
||||||
|
"大雪-暴雪"
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否为小雪类
|
||||||
|
*/
|
||||||
|
public static boolean isMinSnow(String snowType) {
|
||||||
|
return contains(LIGHT_SNOW_TYPES, snowType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否为中雪类
|
||||||
|
*/
|
||||||
|
public static boolean isModerateSnow(String snowType) {
|
||||||
|
return contains(MODERATE_SNOW_TYPES, snowType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否为大雪类
|
||||||
|
*/
|
||||||
|
public static boolean isMaxSnow(String snowType) {
|
||||||
|
return contains(HEAVY_SNOW_TYPES, snowType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取雪类型所属的类别名称
|
||||||
|
*/
|
||||||
|
public static String getCategory(String snowType) {
|
||||||
|
if (isMinSnow(snowType)) return "小雪";
|
||||||
|
if (isModerateSnow(snowType)) return "中雪";
|
||||||
|
if (isMaxSnow(snowType)) return "大雪";
|
||||||
|
return "未知";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查字符串是否在数组中
|
||||||
|
*/
|
||||||
|
private static boolean contains(String[] array, String value) {
|
||||||
|
for (String item : array) {
|
||||||
|
if (item.equals(value)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,51 @@
|
||||||
|
package com.multictrl.common.utils.weather;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 飞速级别转换
|
||||||
|
*
|
||||||
|
* @author Sdy
|
||||||
|
* @since 1.0.0 2025/10/12
|
||||||
|
*/
|
||||||
|
public class WindSpeedConverter {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据级别名称获取最大风速
|
||||||
|
*
|
||||||
|
* @param levelName 级别名称 ("≤3", "4", "5", ..., "12")
|
||||||
|
* @return 最大风速 (m/s)
|
||||||
|
*/
|
||||||
|
public static double getMaxWindSpeed(String levelName) {
|
||||||
|
return switch (levelName) {
|
||||||
|
case "≤3" -> 5.4;
|
||||||
|
case "4" -> 7.9;
|
||||||
|
case "5" -> 10.7;
|
||||||
|
case "6" -> 13.8;
|
||||||
|
case "7" -> 17.1;
|
||||||
|
case "8" -> 20.7;
|
||||||
|
case "9" -> 24.4;
|
||||||
|
case "10" -> 28.4;
|
||||||
|
case "11" -> 32.6;
|
||||||
|
case "12" -> 56.0;
|
||||||
|
default -> throw new IllegalArgumentException("无效的级别名称: " + levelName);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取指定级别的最小风速
|
||||||
|
*/
|
||||||
|
public static double getMinWindSpeed(String levelName) {
|
||||||
|
return switch (levelName) {
|
||||||
|
case "≤3" -> 0.0;
|
||||||
|
case "4" -> 5.5;
|
||||||
|
case "5" -> 8.0;
|
||||||
|
case "6" -> 10.8;
|
||||||
|
case "7" -> 13.9;
|
||||||
|
case "8" -> 17.2;
|
||||||
|
case "9" -> 20.8;
|
||||||
|
case "10" -> 24.5;
|
||||||
|
case "11" -> 28.5;
|
||||||
|
case "12" -> 32.7;
|
||||||
|
default -> throw new IllegalArgumentException("无效的级别名称: " + levelName);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -2,6 +2,7 @@ package com.multictrl.modules.business.controller;
|
||||||
|
|
||||||
import com.multictrl.common.annotation.ApiOrder;
|
import com.multictrl.common.annotation.ApiOrder;
|
||||||
import com.multictrl.common.annotation.LogOperation;
|
import com.multictrl.common.annotation.LogOperation;
|
||||||
|
import com.multictrl.common.constant.FlightTaskType;
|
||||||
import com.multictrl.common.exception.ErrorCode;
|
import com.multictrl.common.exception.ErrorCode;
|
||||||
import com.multictrl.common.utils.Result;
|
import com.multictrl.common.utils.Result;
|
||||||
import com.multictrl.modules.business.dto.flight.FlightExecute;
|
import com.multictrl.modules.business.dto.flight.FlightExecute;
|
||||||
|
|
@ -25,10 +26,10 @@ import java.util.List;
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("business/command")
|
@RequestMapping("business/command")
|
||||||
@Tag(name = "航线飞行", description = """
|
@Tag(name = "航线飞行", description = """
|
||||||
航线管理是无人机自主作业的重要功能,
|
航线管理是无人机自主作业的重要功能,
|
||||||
可以实现行业领域的批量化、智能化作业。
|
可以实现行业领域的批量化、智能化作业。
|
||||||
上云 API 提供了相关的接口,实现了航线任务在云端的共享查看、下发执行、取消以及进度上报等功能。
|
上云 API 提供了相关的接口,实现了航线任务在云端的共享查看、下发执行、取消以及进度上报等功能。
|
||||||
用户需要遵照航线文件格式规范(WPML)编写航线文件,定义航线任务。一个航线任务中可以定义多条航线。""")
|
用户需要遵照航线文件格式规范(WPML)编写航线文件,定义航线任务。一个航线任务中可以定义多条航线。""")
|
||||||
@ApiOrder(5)
|
@ApiOrder(5)
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class RouteFlightController {
|
public class RouteFlightController {
|
||||||
|
|
@ -77,7 +78,7 @@ public class RouteFlightController {
|
||||||
@Operation(summary = "取消任务")
|
@Operation(summary = "取消任务")
|
||||||
@RequiresPermissions("bus:route:flight:flightTaskUndo")
|
@RequiresPermissions("bus:route:flight:flightTaskUndo")
|
||||||
public Result<Object> flightTaskUndo(@PathVariable String dockSn,
|
public Result<Object> flightTaskUndo(@PathVariable String dockSn,
|
||||||
@RequestBody List<String> taskIds) {
|
@RequestBody List<String> taskIds) {
|
||||||
if (taskIds.isEmpty()) {
|
if (taskIds.isEmpty()) {
|
||||||
return new Result<>().error(ErrorCode.PARAMS_ERROR);
|
return new Result<>().error(ErrorCode.PARAMS_ERROR);
|
||||||
}
|
}
|
||||||
|
|
@ -90,9 +91,9 @@ public class RouteFlightController {
|
||||||
@Operation(summary = "执行航线")
|
@Operation(summary = "执行航线")
|
||||||
@RequiresPermissions("bus:route:flight:flightExecute")
|
@RequiresPermissions("bus:route:flight:flightExecute")
|
||||||
public Result<Object> flightExecute(@PathVariable String dockSn,
|
public Result<Object> flightExecute(@PathVariable String dockSn,
|
||||||
@RequestBody FlightExecute flightExecute) {
|
@RequestBody FlightExecute flightExecute) {
|
||||||
|
|
||||||
return new Result<>().ok(routeFlightService.flightExecute(dockSn, flightExecute, true));
|
return new Result<>().ok(routeFlightService.flightExecute(dockSn, flightExecute, true, FlightTaskType.ROUTE.getCode()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@LogOperation("空中下发航线")
|
@LogOperation("空中下发航线")
|
||||||
|
|
@ -100,8 +101,8 @@ public class RouteFlightController {
|
||||||
@Operation(summary = "空中下发航线")
|
@Operation(summary = "空中下发航线")
|
||||||
@RequiresPermissions("bus:route:flight:inFlightWaylineDeliver")
|
@RequiresPermissions("bus:route:flight:inFlightWaylineDeliver")
|
||||||
public Result<Object> inFlightWaylineDeliver(@PathVariable String dockSn,
|
public Result<Object> inFlightWaylineDeliver(@PathVariable String dockSn,
|
||||||
@Parameter(name = "routeId", description = "航线标识")
|
@Parameter(name = "routeId", description = "航线标识")
|
||||||
@RequestParam Long routeId) {
|
@RequestParam Long routeId) {
|
||||||
|
|
||||||
return new Result<>().ok(routeFlightService.inFlightWaylineDeliver(dockSn, routeId));
|
return new Result<>().ok(routeFlightService.inFlightWaylineDeliver(dockSn, routeId));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,78 @@
|
||||||
|
package com.multictrl.modules.business.controller;
|
||||||
|
|
||||||
|
import com.multictrl.common.annotation.ApiOrder;
|
||||||
|
import com.multictrl.common.annotation.LogOperation;
|
||||||
|
import com.multictrl.common.utils.Result;
|
||||||
|
import com.multictrl.common.validator.AssertUtils;
|
||||||
|
import com.multictrl.common.validator.ValidatorUtils;
|
||||||
|
import com.multictrl.common.validator.group.AddGroup;
|
||||||
|
import com.multictrl.common.validator.group.DefaultGroup;
|
||||||
|
import com.multictrl.common.validator.group.UpdateGroup;
|
||||||
|
import com.multictrl.modules.business.dto.WeatherNoflyDTO;
|
||||||
|
import com.multictrl.modules.business.service.WeatherNoflyService;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 天气阻飞
|
||||||
|
*
|
||||||
|
* @author Sdy
|
||||||
|
* @since 1.0.0 2026-06-15
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("business/weathernofly")
|
||||||
|
@Tag(name = "天气阻飞")
|
||||||
|
@ApiOrder(24)
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class WeatherNoflyController {
|
||||||
|
private final WeatherNoflyService weatherNoflyService;
|
||||||
|
|
||||||
|
@GetMapping("{dockSn}")
|
||||||
|
@Operation(summary = "信息")
|
||||||
|
@RequiresPermissions("bus:weathernofly:info")
|
||||||
|
public Result<WeatherNoflyDTO> get(@PathVariable String dockSn) {
|
||||||
|
WeatherNoflyDTO data = weatherNoflyService.getInfoByDockSn(dockSn);
|
||||||
|
|
||||||
|
return new Result<WeatherNoflyDTO>().ok(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping
|
||||||
|
@Operation(summary = "保存")
|
||||||
|
@LogOperation("保存")
|
||||||
|
@RequiresPermissions("bus:weathernofly:save")
|
||||||
|
public Result<Object> save(@RequestBody WeatherNoflyDTO dto) {
|
||||||
|
//效验数据
|
||||||
|
ValidatorUtils.validateEntity(dto, AddGroup.class);
|
||||||
|
weatherNoflyService.addWeatherNofly(dto);
|
||||||
|
|
||||||
|
return new Result<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
@PutMapping
|
||||||
|
@Operation(summary = "修改")
|
||||||
|
@LogOperation("修改")
|
||||||
|
@RequiresPermissions("bus:weathernofly:update")
|
||||||
|
public Result<Object> update(@RequestBody WeatherNoflyDTO dto) {
|
||||||
|
//效验数据
|
||||||
|
ValidatorUtils.validateEntity(dto, UpdateGroup.class);
|
||||||
|
weatherNoflyService.update(dto);
|
||||||
|
|
||||||
|
return new Result<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping
|
||||||
|
@Operation(summary = "删除")
|
||||||
|
@LogOperation("删除")
|
||||||
|
@RequiresPermissions("bus:weathernofly:delete")
|
||||||
|
public Result<Object> delete(@RequestBody Long[] ids) {
|
||||||
|
//效验数据
|
||||||
|
AssertUtils.isArrayEmpty(ids, "id");
|
||||||
|
weatherNoflyService.delete(ids);
|
||||||
|
|
||||||
|
return new Result<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
package com.multictrl.modules.business.dao;
|
||||||
|
|
||||||
|
import com.multictrl.common.dao.BaseDao;
|
||||||
|
import com.multictrl.modules.business.entity.WeatherNoflyEntity;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 天气阻飞
|
||||||
|
*
|
||||||
|
* @author Sdy
|
||||||
|
* @since 1.0.0 2026-06-15
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface WeatherNoflyDao extends BaseDao<WeatherNoflyEntity> {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,114 @@
|
||||||
|
package com.multictrl.modules.business.dto;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
import com.multictrl.common.validator.group.AddGroup;
|
||||||
|
import com.multictrl.common.validator.group.UpdateGroup;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.AssertTrue;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import jakarta.validation.constraints.Null;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 天气阻飞
|
||||||
|
*
|
||||||
|
* @author Sdy
|
||||||
|
* @since 1.0.0 2026-06-15
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(name = "天气阻飞")
|
||||||
|
public class WeatherNoflyDTO implements Serializable {
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Null(message = "标识必须为空", groups = AddGroup.class)
|
||||||
|
@NotNull(message = "标识不能为空", groups = UpdateGroup.class)
|
||||||
|
@Schema(description = "标识")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@NotNull(message = "机库SN不能为空", groups = {AddGroup.class, UpdateGroup.class})
|
||||||
|
@Schema(description = "机库sn")
|
||||||
|
private String dockSn;
|
||||||
|
|
||||||
|
@NotNull(message = "是否开启阻飞不能为空", groups = {AddGroup.class, UpdateGroup.class})
|
||||||
|
@Schema(description = "是否开启阻飞(开启后使用机库上报数据)")
|
||||||
|
private Boolean isOpen;
|
||||||
|
|
||||||
|
@Schema(description = "风速m/s")
|
||||||
|
private Double windSpeed;
|
||||||
|
|
||||||
|
@Schema(description = "雨(0关闭 1小雨 2中雨 3大雨)")
|
||||||
|
private Integer rainfall;
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
@Schema(hidden = true)
|
||||||
|
@AssertTrue(message = "参数为空或错误", groups = {AddGroup.class, UpdateGroup.class})
|
||||||
|
public boolean isIsOpenValid() {
|
||||||
|
if (isOpen) {
|
||||||
|
return windSpeed != null && rainfall != null && (rainfall == 0 || rainfall == 1);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull(message = "是否全部阻飞不能为空", groups = {AddGroup.class, UpdateGroup.class})
|
||||||
|
@Schema(description = "是否全部阻飞(开启后全部阻飞不开启只阻飞计划库)")
|
||||||
|
private Boolean isAllPrevent;
|
||||||
|
|
||||||
|
@NotNull(message = "是否开启天气阻飞不能为空", groups = {AddGroup.class, UpdateGroup.class})
|
||||||
|
@Schema(description = "是否开启天气阻飞(开启后在机库数据上增加天气预报数据)")
|
||||||
|
private Boolean isOpenWeather;
|
||||||
|
|
||||||
|
@Schema(description = "风速m/s(天气预报)")
|
||||||
|
private Double windSpeedWeather;
|
||||||
|
|
||||||
|
@Schema(description = "雨(天气预报 0关闭 1小雨 2中雨 3大雨)")
|
||||||
|
private Integer rainfallWeather;
|
||||||
|
|
||||||
|
@Schema(description = "雪(天气预报 0关闭 1小雪 2中雪 3大雪)")
|
||||||
|
private Integer snowWeather;
|
||||||
|
|
||||||
|
@Schema(description = "雾(天气预报 0关闭 1轻雾 2中雾 3大雾)")
|
||||||
|
private Integer fogWeather;
|
||||||
|
|
||||||
|
@Schema(description = "霾(天气预报 0关闭 1轻度霾 2中度霾 3重度霾)")
|
||||||
|
private Integer hazeWeather;
|
||||||
|
|
||||||
|
@Schema(description = "冰雹阻飞")
|
||||||
|
private Boolean isHailWeather;
|
||||||
|
|
||||||
|
@Schema(description = "沙尘暴阻飞")
|
||||||
|
private Boolean isSandstormWeather;
|
||||||
|
|
||||||
|
@Schema(description = "龙卷风阻飞")
|
||||||
|
private Boolean isTornadoWeather;
|
||||||
|
|
||||||
|
@Schema(description = "温度上限(摄氏度)")
|
||||||
|
private Double temperatureMax;
|
||||||
|
|
||||||
|
@Schema(description = "温度下限(摄氏度)")
|
||||||
|
private Double temperatureMin;
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
@Schema(hidden = true)
|
||||||
|
@AssertTrue(message = "天气参数为空或错误", groups = {AddGroup.class, UpdateGroup.class})
|
||||||
|
public boolean isIsOpenWeatherValid() {
|
||||||
|
if (isOpenWeather) {
|
||||||
|
return windSpeedWeather != null
|
||||||
|
&& (rainfallWeather != null && rainfallWeather >= 0 && rainfallWeather <= 3)
|
||||||
|
&& (snowWeather != null && snowWeather >= 0 && snowWeather <= 3)
|
||||||
|
&& (fogWeather != null && fogWeather >= 0 && fogWeather <= 3)
|
||||||
|
&& (hazeWeather != null && hazeWeather >= 0 && hazeWeather <= 3)
|
||||||
|
&& isHailWeather != null
|
||||||
|
&& isSandstormWeather != null
|
||||||
|
&& isTornadoWeather != null
|
||||||
|
&& temperatureMax != null
|
||||||
|
&& temperatureMin != null;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
package com.multictrl.modules.business.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 天气阻飞任务记录参数
|
||||||
|
*
|
||||||
|
* @author Sdy
|
||||||
|
* @since 1.0.0 2026/6/17
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class WeatherNoflyTaskDTO {
|
||||||
|
|
||||||
|
//任务标识
|
||||||
|
private String taskId;
|
||||||
|
|
||||||
|
//机库SN
|
||||||
|
private String dockSn;
|
||||||
|
|
||||||
|
//航线标识
|
||||||
|
private Long routeId;
|
||||||
|
|
||||||
|
//定时任务标识
|
||||||
|
private Long jobId;
|
||||||
|
|
||||||
|
//任务类型 1航线 2手动 3定时
|
||||||
|
private Integer taskType;
|
||||||
|
|
||||||
|
//失败原因
|
||||||
|
private String reason;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,96 @@
|
||||||
|
package com.multictrl.modules.business.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.FieldFill;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.multictrl.common.entity.BaseEntity;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 天气阻飞
|
||||||
|
*
|
||||||
|
* @author Sdy
|
||||||
|
* @since 1.0.0 2026-06-15
|
||||||
|
*/
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Data
|
||||||
|
@TableName("bus_weather_nofly")
|
||||||
|
public class WeatherNoflyEntity extends BaseEntity {
|
||||||
|
/**
|
||||||
|
* 机库sn
|
||||||
|
*/
|
||||||
|
private String dockSn;
|
||||||
|
/**
|
||||||
|
* 是否开启阻飞(开启后使用机库上报数据)
|
||||||
|
*/
|
||||||
|
private Boolean isOpen;
|
||||||
|
/**
|
||||||
|
* 风速m/s
|
||||||
|
*/
|
||||||
|
private Double windSpeed;
|
||||||
|
/**
|
||||||
|
* 雨(0关闭 1小雨 2中雨 3大雨)
|
||||||
|
*/
|
||||||
|
private Integer rainfall;
|
||||||
|
/**
|
||||||
|
* 是否全部阻飞(开启后全部阻飞不开启只阻飞计划库)
|
||||||
|
*/
|
||||||
|
private Boolean isAllPrevent;
|
||||||
|
/**
|
||||||
|
* 是否开启天气阻飞(开启后在机库数据上增加天气预报数据)
|
||||||
|
*/
|
||||||
|
private Boolean isOpenWeather;
|
||||||
|
/**
|
||||||
|
* 风速m/s(天气预报)
|
||||||
|
*/
|
||||||
|
private Double windSpeedWeather;
|
||||||
|
/**
|
||||||
|
* 雨(天气预报 0关闭 1小雨 2中雨 3大雨)
|
||||||
|
*/
|
||||||
|
private Integer rainfallWeather;
|
||||||
|
/**
|
||||||
|
* 雪(天气预报 0关闭 1小雪 2中雪 3大雪)
|
||||||
|
*/
|
||||||
|
private Integer snowWeather;
|
||||||
|
/**
|
||||||
|
* 雾(天气预报 0关闭 1轻雾 2中雾 3大雾)
|
||||||
|
*/
|
||||||
|
private Integer fogWeather;
|
||||||
|
/**
|
||||||
|
* 霾(天气预报 0关闭 1轻度霾 2中度霾 3重度霾)
|
||||||
|
*/
|
||||||
|
private Integer hazeWeather;
|
||||||
|
/**
|
||||||
|
* 冰雹阻飞
|
||||||
|
*/
|
||||||
|
private Boolean isHailWeather;
|
||||||
|
/**
|
||||||
|
* 沙尘暴阻飞
|
||||||
|
*/
|
||||||
|
private Boolean isSandstormWeather;
|
||||||
|
/**
|
||||||
|
* 龙卷风阻飞
|
||||||
|
*/
|
||||||
|
private Boolean isTornadoWeather;
|
||||||
|
/**
|
||||||
|
* 温度上限(摄氏度)
|
||||||
|
*/
|
||||||
|
private Double temperatureMax;
|
||||||
|
/**
|
||||||
|
* 温度下限(摄氏度)
|
||||||
|
*/
|
||||||
|
private Double temperatureMin;
|
||||||
|
/**
|
||||||
|
* 修改人
|
||||||
|
*/
|
||||||
|
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||||
|
private Long updater;
|
||||||
|
/**
|
||||||
|
* 修改时间
|
||||||
|
*/
|
||||||
|
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||||
|
private Date updateDate;
|
||||||
|
}
|
||||||
|
|
@ -47,6 +47,9 @@ public interface DJIBaseService {
|
||||||
//获取机场备降点
|
//获取机场备降点
|
||||||
LatLonDTO getDockAlternateLandPoint(String dockSn);
|
LatLonDTO getDockAlternateLandPoint(String dockSn);
|
||||||
|
|
||||||
|
//获取机库位置
|
||||||
|
LatLonDTO getDockLocation(String dockSn);
|
||||||
|
|
||||||
//机场是否在线
|
//机场是否在线
|
||||||
Boolean isDockOnline(String dockSn);
|
Boolean isDockOnline(String dockSn);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import com.multictrl.common.page.PageData;
|
||||||
import com.multictrl.common.service.CrudService;
|
import com.multictrl.common.service.CrudService;
|
||||||
import com.multictrl.modules.business.dto.FlightTaskDTO;
|
import com.multictrl.modules.business.dto.FlightTaskDTO;
|
||||||
import com.multictrl.modules.business.dto.MediaFileDTO;
|
import com.multictrl.modules.business.dto.MediaFileDTO;
|
||||||
|
import com.multictrl.modules.business.dto.WeatherNoflyTaskDTO;
|
||||||
import com.multictrl.modules.business.entity.FlightTaskEntity;
|
import com.multictrl.modules.business.entity.FlightTaskEntity;
|
||||||
import com.multictrl.modules.business.entity.SrsRecordEntity;
|
import com.multictrl.modules.business.entity.SrsRecordEntity;
|
||||||
import com.multictrl.modules.business.influxdb.UavReport;
|
import com.multictrl.modules.business.influxdb.UavReport;
|
||||||
|
|
@ -30,6 +31,8 @@ public interface FlightTaskService extends CrudService<FlightTaskEntity, FlightT
|
||||||
|
|
||||||
void addJobRouteTask(String taskId, Long jobId);//计划飞行任务
|
void addJobRouteTask(String taskId, Long jobId);//计划飞行任务
|
||||||
|
|
||||||
|
void addWeatherNoflyTask(WeatherNoflyTaskDTO dto);//天气阻飞任务
|
||||||
|
|
||||||
//更新架次完成信息
|
//更新架次完成信息
|
||||||
void updateTaskComplete(String dockSn);
|
void updateTaskComplete(String dockSn);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ package com.multictrl.modules.business.service;
|
||||||
import com.multictrl.modules.business.dto.flight.FlightExecute;
|
import com.multictrl.modules.business.dto.flight.FlightExecute;
|
||||||
|
|
||||||
import com.multictrl.modules.business.dto.multi.PrivateMultiFlightBindDockInfo;
|
import com.multictrl.modules.business.dto.multi.PrivateMultiFlightBindDockInfo;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -17,7 +18,7 @@ public interface RouteFlightService {
|
||||||
String flightTaskUndo(String dockSn, List<String> taskIds);
|
String flightTaskUndo(String dockSn, List<String> taskIds);
|
||||||
|
|
||||||
//执行航线
|
//执行航线
|
||||||
String flightExecute(String dockSn, FlightExecute flightExecute, Boolean isRecord);
|
String flightExecute(String dockSn, FlightExecute flightExecute, Boolean isRecord, Integer taskType);
|
||||||
|
|
||||||
//空中下发航线
|
//空中下发航线
|
||||||
String inFlightWaylineDeliver(String dockSn, Long routeId);
|
String inFlightWaylineDeliver(String dockSn, Long routeId);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
package com.multictrl.modules.business.service;
|
||||||
|
|
||||||
|
import cn.hutool.json.JSONObject;
|
||||||
|
import com.multictrl.common.service.CrudService;
|
||||||
|
import com.multictrl.modules.business.dto.WeatherNoflyDTO;
|
||||||
|
import com.multictrl.modules.business.entity.WeatherNoflyEntity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 天气阻飞
|
||||||
|
*
|
||||||
|
* @author Sdy
|
||||||
|
* @since 1.0.0 2026-06-15
|
||||||
|
*/
|
||||||
|
public interface WeatherNoflyService extends CrudService<WeatherNoflyEntity, WeatherNoflyDTO> {
|
||||||
|
|
||||||
|
//信息
|
||||||
|
WeatherNoflyDTO getInfoByDockSn(String dockSn);
|
||||||
|
|
||||||
|
//新增阻飞
|
||||||
|
void addWeatherNofly(WeatherNoflyDTO dto);
|
||||||
|
|
||||||
|
//判断机库是否阻飞
|
||||||
|
JSONObject allowFlight(String dockSn, boolean isJobTask);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.multictrl.modules.business.service;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 天气服务
|
||||||
|
*
|
||||||
|
* @author Sdy
|
||||||
|
* @since 1.0.0 2026/6/16
|
||||||
|
*/
|
||||||
|
public interface WeatherService {
|
||||||
|
|
||||||
|
//根据经纬度获取实时天气
|
||||||
|
String getWeatherByLonLat(Double longitude, Double latitude);
|
||||||
|
}
|
||||||
|
|
@ -4,25 +4,21 @@ import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.hutool.core.util.IdUtil;
|
import cn.hutool.core.util.IdUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.hutool.json.JSONObject;
|
import cn.hutool.json.JSONObject;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
||||||
import com.multictrl.common.config.MqttConfig;
|
import com.multictrl.common.config.MqttConfig;
|
||||||
import com.multictrl.common.constant.BusinessConstant;
|
import com.multictrl.common.constant.BusinessConstant;
|
||||||
import com.multictrl.common.constant.DockMode;
|
import com.multictrl.common.constant.DockMode;
|
||||||
import com.multictrl.common.constant.FlightTaskProgressStatus;
|
import com.multictrl.common.constant.FlightTaskProgressStatus;
|
||||||
|
import com.multictrl.common.constant.FlightTaskType;
|
||||||
import com.multictrl.common.exception.ErrorCode;
|
import com.multictrl.common.exception.ErrorCode;
|
||||||
import com.multictrl.common.exception.RenException;
|
import com.multictrl.common.exception.RenException;
|
||||||
import com.multictrl.common.utils.CacheUtils;
|
import com.multictrl.common.utils.CacheUtils;
|
||||||
import com.multictrl.common.utils.Utils;
|
import com.multictrl.common.utils.Utils;
|
||||||
import com.multictrl.modules.business.dao.DockDeviceDao;
|
|
||||||
import com.multictrl.modules.business.dto.LatLonDTO;
|
import com.multictrl.modules.business.dto.LatLonDTO;
|
||||||
|
import com.multictrl.modules.business.dto.WeatherNoflyTaskDTO;
|
||||||
import com.multictrl.modules.business.dto.command.DrcStick;
|
import com.multictrl.modules.business.dto.command.DrcStick;
|
||||||
import com.multictrl.modules.business.dto.command.FlyToPoint;
|
import com.multictrl.modules.business.dto.command.FlyToPoint;
|
||||||
import com.multictrl.modules.business.dto.command.TakeoffToPoint;
|
import com.multictrl.modules.business.dto.command.TakeoffToPoint;
|
||||||
import com.multictrl.modules.business.entity.DockDeviceEntity;
|
import com.multictrl.modules.business.service.*;
|
||||||
import com.multictrl.modules.business.service.CommandService;
|
|
||||||
import com.multictrl.modules.business.service.DJIBaseService;
|
|
||||||
import com.multictrl.modules.business.service.FlightTaskService;
|
|
||||||
import com.multictrl.modules.business.service.MqttPushService;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
@ -45,9 +41,9 @@ import java.util.concurrent.locks.ReentrantLock;
|
||||||
public class CommandServiceImpl implements CommandService {
|
public class CommandServiceImpl implements CommandService {
|
||||||
private final DJIBaseService djiBaseService;
|
private final DJIBaseService djiBaseService;
|
||||||
private final MqttConfig mqttConfig;
|
private final MqttConfig mqttConfig;
|
||||||
private final DockDeviceDao dockDeviceDao;
|
|
||||||
private final MqttPushService mqttPushService;
|
private final MqttPushService mqttPushService;
|
||||||
private final FlightTaskService flightTaskService;
|
private final FlightTaskService flightTaskService;
|
||||||
|
private final WeatherNoflyService weatherNoflyService;
|
||||||
private final Map<String, ReentrantLock> cacheLock = new ConcurrentHashMap<>();
|
private final Map<String, ReentrantLock> cacheLock = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -104,6 +100,19 @@ public class CommandServiceImpl implements CommandService {
|
||||||
//设置默认相机模式,需要定频推送前端
|
//设置默认相机模式,需要定频推送前端
|
||||||
CacheUtils.set(BusinessConstant.UAV_VIDEO_TYPE, "wide");
|
CacheUtils.set(BusinessConstant.UAV_VIDEO_TYPE, "wide");
|
||||||
|
|
||||||
|
//判断天气阻飞
|
||||||
|
JSONObject allowFlightResult = weatherNoflyService.allowFlight(dockSn, false);
|
||||||
|
Boolean isAllow = allowFlightResult.getBool("isAllow");
|
||||||
|
if (!isAllow) {
|
||||||
|
String reason = allowFlightResult.getStr("reason");
|
||||||
|
WeatherNoflyTaskDTO dto = new WeatherNoflyTaskDTO();
|
||||||
|
dto.setTaskId(taskId);
|
||||||
|
dto.setDockSn(dockSn);
|
||||||
|
dto.setTaskType(FlightTaskType.MANUAL.getCode());
|
||||||
|
dto.setReason(reason);
|
||||||
|
flightTaskService.addWeatherNoflyTask(dto);
|
||||||
|
return reason;
|
||||||
|
}
|
||||||
//发送执行
|
//发送执行
|
||||||
String result = djiBaseService.executeAndReturnResult(dockSn, "takeoff_to_point", Utils.beanToSnakeJson(takeoffToPoint));
|
String result = djiBaseService.executeAndReturnResult(dockSn, "takeoff_to_point", Utils.beanToSnakeJson(takeoffToPoint));
|
||||||
flightTaskService.addTakeoffTask(taskId, dockSn);
|
flightTaskService.addTakeoffTask(taskId, dockSn);
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,9 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||||
public class DJIBaseServiceImpl implements DJIBaseService {
|
public class DJIBaseServiceImpl implements DJIBaseService {
|
||||||
private final MqttPushService mqttPushService;
|
private final MqttPushService mqttPushService;
|
||||||
|
|
||||||
/** 设备SN → 当前正在等待回复的命令信息(供模拟回复使用) */
|
/**
|
||||||
|
* 设备SN → 当前正在等待回复的命令信息(供模拟回复使用)
|
||||||
|
*/
|
||||||
private final ConcurrentHashMap<String, JSONObject> pendingCmds = new ConcurrentHashMap<>();
|
private final ConcurrentHashMap<String, JSONObject> pendingCmds = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -237,6 +239,20 @@ public class DJIBaseServiceImpl implements DJIBaseService {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LatLonDTO getDockLocation(String dockSn) {
|
||||||
|
Object o = CacheUtils.get(BusinessConstant.DOCK_OSD + dockSn);
|
||||||
|
if (o != null) {
|
||||||
|
JSONObject data = (JSONObject) o;
|
||||||
|
LatLonDTO gps = new LatLonDTO();
|
||||||
|
gps.setLatitude(data.getDouble("latitude"));
|
||||||
|
gps.setLongitude(data.getDouble("longitude"));
|
||||||
|
gps.setHeight(data.getDouble("height"));
|
||||||
|
return gps;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Boolean isDockOnline(String dockSn) {
|
public Boolean isDockOnline(String dockSn) {
|
||||||
Object object = CacheUtils.get(BusinessConstant.DOCK_OSD + dockSn);
|
Object object = CacheUtils.get(BusinessConstant.DOCK_OSD + dockSn);
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
import com.multictrl.common.constant.BusinessConstant;
|
import com.multictrl.common.constant.BusinessConstant;
|
||||||
import com.multictrl.common.constant.FlightTaskStatus;
|
import com.multictrl.common.constant.FlightTaskStatus;
|
||||||
|
import com.multictrl.common.constant.FlightTaskType;
|
||||||
import com.multictrl.common.exception.ErrorCode;
|
import com.multictrl.common.exception.ErrorCode;
|
||||||
import com.multictrl.common.exception.RenException;
|
import com.multictrl.common.exception.RenException;
|
||||||
import com.multictrl.common.page.PageData;
|
import com.multictrl.common.page.PageData;
|
||||||
|
|
@ -19,6 +20,7 @@ import com.multictrl.modules.business.dao.FlightTaskDao;
|
||||||
import com.multictrl.modules.business.dto.FlightTaskDTO;
|
import com.multictrl.modules.business.dto.FlightTaskDTO;
|
||||||
import com.multictrl.modules.business.dto.MediaFileDTO;
|
import com.multictrl.modules.business.dto.MediaFileDTO;
|
||||||
import com.multictrl.modules.business.dto.RouteDTO;
|
import com.multictrl.modules.business.dto.RouteDTO;
|
||||||
|
import com.multictrl.modules.business.dto.WeatherNoflyTaskDTO;
|
||||||
import com.multictrl.modules.business.entity.*;
|
import com.multictrl.modules.business.entity.*;
|
||||||
import com.multictrl.modules.business.influxdb.UavReport;
|
import com.multictrl.modules.business.influxdb.UavReport;
|
||||||
import com.multictrl.modules.business.service.*;
|
import com.multictrl.modules.business.service.*;
|
||||||
|
|
@ -141,6 +143,48 @@ public class FlightTaskServiceImpl extends CrudServiceImpl<FlightTaskDao, Flight
|
||||||
baseDao.insert(entity);
|
baseDao.insert(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addWeatherNoflyTask(WeatherNoflyTaskDTO dto) {
|
||||||
|
FlightTaskEntity entity = new FlightTaskEntity();
|
||||||
|
entity.setTaskId(dto.getTaskId());
|
||||||
|
entity.setTaskType(dto.getTaskType());
|
||||||
|
Long routeId = null;
|
||||||
|
//1航线 2手动 3定时
|
||||||
|
if (Objects.equals(dto.getTaskType(), FlightTaskType.ROUTE.getCode())) {
|
||||||
|
addDockInfo(entity, dto.getDockSn());
|
||||||
|
routeId = dto.getRouteId();
|
||||||
|
entity.setRouteId(routeId);
|
||||||
|
entity.setDeptId(SecurityUser.getDeptId());
|
||||||
|
entity.setCreateName(SecurityUser.getUser().getRealName());
|
||||||
|
} else if (Objects.equals(dto.getTaskType(), FlightTaskType.MANUAL.getCode())) {
|
||||||
|
entity.setTaskId(dto.getTaskId());
|
||||||
|
addDockInfo(entity, dto.getDockSn());
|
||||||
|
entity.setRouteName("一键起飞");
|
||||||
|
entity.setDeptId(SecurityUser.getDeptId());
|
||||||
|
entity.setCreateName(SecurityUser.getUser().getRealName());
|
||||||
|
} else if (Objects.equals(dto.getTaskType(), FlightTaskType.SCHEDULED.getCode())) {
|
||||||
|
ScheduleJobEntity jobEntity = scheduleJobDao.getById(dto.getJobId());
|
||||||
|
addDockInfo(entity, jobEntity.getDockSn());
|
||||||
|
routeId = Long.parseLong(jobEntity.getParams());
|
||||||
|
entity.setRouteId(routeId);
|
||||||
|
entity.setDeptId(jobEntity.getDeptId());
|
||||||
|
SysUserDTO userDTO = userService.get(jobEntity.getUpdater());
|
||||||
|
entity.setCreateName(userDTO.getRealName());
|
||||||
|
}
|
||||||
|
if (routeId != null) {
|
||||||
|
RouteDTO route = routeService.getRoute(routeId);
|
||||||
|
if (route != null) {
|
||||||
|
entity.setRouteName(route.getRouteName());
|
||||||
|
entity.setRouteType(route.getTemplateType());
|
||||||
|
entity.setRouteDistance(route.getTotalDistance());
|
||||||
|
entity.setWaypointNum(route.getRouteWaypointList().size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
entity.setTaskStatus(FlightTaskStatus.PREVENTED.getCode());
|
||||||
|
entity.setFailureReason(dto.getReason());
|
||||||
|
baseDao.insert(entity);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateTaskComplete(String dockSn) {
|
public void updateTaskComplete(String dockSn) {
|
||||||
String taskId = (String) CacheUtils.get(BusinessConstant.WORKING_TASK_ID + dockSn);
|
String taskId = (String) CacheUtils.get(BusinessConstant.WORKING_TASK_ID + dockSn);
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,7 @@ import cn.hutool.core.util.StrUtil;
|
||||||
import cn.hutool.json.JSONObject;
|
import cn.hutool.json.JSONObject;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.multictrl.common.constant.BusinessConstant;
|
import com.multictrl.common.constant.*;
|
||||||
import com.multictrl.common.constant.Constant;
|
|
||||||
import com.multictrl.common.constant.DJIImage;
|
|
||||||
import com.multictrl.common.constant.DockMode;
|
|
||||||
import com.multictrl.common.exception.ErrorCode;
|
import com.multictrl.common.exception.ErrorCode;
|
||||||
import com.multictrl.common.exception.RenException;
|
import com.multictrl.common.exception.RenException;
|
||||||
import com.multictrl.common.page.PageData;
|
import com.multictrl.common.page.PageData;
|
||||||
|
|
@ -246,7 +243,7 @@ public class MultiServiceImpl implements MultiService {
|
||||||
flightExecute.setPrivateMultiFlightBindDockInfos(privateMultiFlightBindDockInfos);
|
flightExecute.setPrivateMultiFlightBindDockInfos(privateMultiFlightBindDockInfos);
|
||||||
|
|
||||||
log.info("privateMultiDockFlightTaskOutbound-> 下发航线给妙算 flightExecute:{}", flightExecute);
|
log.info("privateMultiDockFlightTaskOutbound-> 下发航线给妙算 flightExecute:{}", flightExecute);
|
||||||
return routeFlightService.flightExecute(multiTaskDTO.getMiaoSuan().getDockSn(), flightExecute, true);
|
return routeFlightService.flightExecute(multiTaskDTO.getMiaoSuan().getDockSn(), flightExecute, true, FlightTaskType.ROUTE.getCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -6,20 +6,20 @@ import cn.hutool.json.JSONObject;
|
||||||
import com.multictrl.common.config.MinioConfig;
|
import com.multictrl.common.config.MinioConfig;
|
||||||
import com.multictrl.common.constant.BusinessConstant;
|
import com.multictrl.common.constant.BusinessConstant;
|
||||||
import com.multictrl.common.constant.DockMode;
|
import com.multictrl.common.constant.DockMode;
|
||||||
|
import com.multictrl.common.constant.FlightTaskType;
|
||||||
import com.multictrl.common.exception.ErrorCode;
|
import com.multictrl.common.exception.ErrorCode;
|
||||||
import com.multictrl.common.exception.RenException;
|
import com.multictrl.common.exception.RenException;
|
||||||
import com.multictrl.common.utils.CacheUtils;
|
import com.multictrl.common.utils.CacheUtils;
|
||||||
import com.multictrl.common.utils.JsonUtils;
|
import com.multictrl.common.utils.JsonUtils;
|
||||||
import com.multictrl.common.utils.Utils;
|
import com.multictrl.common.utils.Utils;
|
||||||
import com.multictrl.modules.business.dto.RouteDTO;
|
import com.multictrl.modules.business.dto.RouteDTO;
|
||||||
|
import com.multictrl.modules.business.dto.WeatherNoflyDTO;
|
||||||
|
import com.multictrl.modules.business.dto.WeatherNoflyTaskDTO;
|
||||||
import com.multictrl.modules.business.dto.flight.FlightExecute;
|
import com.multictrl.modules.business.dto.flight.FlightExecute;
|
||||||
import com.multictrl.modules.business.dto.flight.FlightTaskPrepare;
|
import com.multictrl.modules.business.dto.flight.FlightTaskPrepare;
|
||||||
import com.multictrl.modules.business.dto.flight.InFlightWaylineDeliver;
|
import com.multictrl.modules.business.dto.flight.InFlightWaylineDeliver;
|
||||||
import com.multictrl.modules.business.dto.multi.PrivateMultiFlightBindDockInfo;
|
import com.multictrl.modules.business.dto.multi.PrivateMultiFlightBindDockInfo;
|
||||||
import com.multictrl.modules.business.service.DJIBaseService;
|
import com.multictrl.modules.business.service.*;
|
||||||
import com.multictrl.modules.business.service.FlightTaskService;
|
|
||||||
import com.multictrl.modules.business.service.RouteFlightService;
|
|
||||||
import com.multictrl.modules.business.service.RouteService;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
@ -46,6 +46,7 @@ public class RouteFlightServiceImpl implements RouteFlightService {
|
||||||
private final RouteService routeService;
|
private final RouteService routeService;
|
||||||
private final MinioConfig minioConfig;
|
private final MinioConfig minioConfig;
|
||||||
private final FlightTaskService flightTaskService;
|
private final FlightTaskService flightTaskService;
|
||||||
|
private final WeatherNoflyService weatherNoflyService;
|
||||||
private final Map<String, ReentrantLock> cacheLock = new ConcurrentHashMap<>();
|
private final Map<String, ReentrantLock> cacheLock = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -59,7 +60,7 @@ public class RouteFlightServiceImpl implements RouteFlightService {
|
||||||
* multiFlightBindDockInfos aros机场蛙跳模式参数,把N个参与到蛙跳的的机场信息给到妙算,返航时,自动计算离哪个机库位置近,就降落到哪个机库
|
* multiFlightBindDockInfos aros机场蛙跳模式参数,把N个参与到蛙跳的的机场信息给到妙算,返航时,自动计算离哪个机库位置近,就降落到哪个机库
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String flightExecute(String dockSn, FlightExecute flightExecute, Boolean isRecord) {
|
public String flightExecute(String dockSn, FlightExecute flightExecute, Boolean isRecord, Integer taskType) {
|
||||||
ReentrantLock lock = cacheLock.computeIfAbsent(dockSn, k -> new ReentrantLock());
|
ReentrantLock lock = cacheLock.computeIfAbsent(dockSn, k -> new ReentrantLock());
|
||||||
lock.lock();
|
lock.lock();
|
||||||
try {
|
try {
|
||||||
|
|
@ -99,6 +100,20 @@ public class RouteFlightServiceImpl implements RouteFlightService {
|
||||||
if (globalRthHeight <= 50) {
|
if (globalRthHeight <= 50) {
|
||||||
throw new RenException(ErrorCode.GLOBAL_RTH_HEIGHT_NOT_BELOW, "50");
|
throw new RenException(ErrorCode.GLOBAL_RTH_HEIGHT_NOT_BELOW, "50");
|
||||||
}
|
}
|
||||||
|
//判断天气阻飞
|
||||||
|
JSONObject allowFlightResult = weatherNoflyService.allowFlight(dockSn, Objects.equals(taskType, FlightTaskType.SCHEDULED.getCode()));
|
||||||
|
Boolean isAllow = allowFlightResult.getBool("isAllow");
|
||||||
|
if (!isAllow) {
|
||||||
|
String reason = allowFlightResult.getStr("reason");
|
||||||
|
WeatherNoflyTaskDTO dto = new WeatherNoflyTaskDTO();
|
||||||
|
dto.setTaskId(taskId);
|
||||||
|
dto.setDockSn(dockSn);
|
||||||
|
dto.setRouteId(route.getId());
|
||||||
|
dto.setTaskType(taskType);
|
||||||
|
dto.setReason(reason);
|
||||||
|
flightTaskService.addWeatherNoflyTask(dto);
|
||||||
|
return reason;
|
||||||
|
}
|
||||||
//下发任务
|
//下发任务
|
||||||
int exitOnRcLost = "executeLostAction".equals(route.getExitOnRcLost()) ? 1 : 0;
|
int exitOnRcLost = "executeLostAction".equals(route.getExitOnRcLost()) ? 1 : 0;
|
||||||
String kmzUrl = minioConfig.getEndpoint() + "/" + route.getKmzUrl();
|
String kmzUrl = minioConfig.getEndpoint() + "/" + route.getKmzUrl();
|
||||||
|
|
@ -120,7 +135,7 @@ public class RouteFlightServiceImpl implements RouteFlightService {
|
||||||
}
|
}
|
||||||
if (flightExecute.getPrivateMultiFlightBindDockInfos() != null) {
|
if (flightExecute.getPrivateMultiFlightBindDockInfos() != null) {
|
||||||
flightTaskPrepare.setPrivate_multi_flight_bind_dock_info(
|
flightTaskPrepare.setPrivate_multi_flight_bind_dock_info(
|
||||||
flightExecute.getPrivateMultiFlightBindDockInfos());
|
flightExecute.getPrivateMultiFlightBindDockInfos());
|
||||||
}
|
}
|
||||||
JSONObject data = JsonUtils.parseObject(JsonUtils.toJsonString(flightTaskPrepare), JSONObject.class);
|
JSONObject data = JsonUtils.parseObject(JsonUtils.toJsonString(flightTaskPrepare), JSONObject.class);
|
||||||
String result = djiBaseService.executeAndReturnResult(dockSn, "flighttask_prepare", data);
|
String result = djiBaseService.executeAndReturnResult(dockSn, "flighttask_prepare", data);
|
||||||
|
|
@ -128,7 +143,7 @@ public class RouteFlightServiceImpl implements RouteFlightService {
|
||||||
//执行任务
|
//执行任务
|
||||||
Utils.sleep(1000);
|
Utils.sleep(1000);
|
||||||
String resultMsg = djiBaseService.executeAndReturnResult(dockSn, "flighttask_execute",
|
String resultMsg = djiBaseService.executeAndReturnResult(dockSn, "flighttask_execute",
|
||||||
new JSONObject().set("flight_id", taskId));
|
new JSONObject().set("flight_id", taskId));
|
||||||
if (isRecord) {
|
if (isRecord) {
|
||||||
flightTaskService.addRouteTask(taskId, dockSn, route.getId());
|
flightTaskService.addRouteTask(taskId, dockSn, route.getId());
|
||||||
}
|
}
|
||||||
|
|
@ -192,7 +207,7 @@ public class RouteFlightServiceImpl implements RouteFlightService {
|
||||||
throw new RenException(ErrorCode.ROUTE_TASK_NOT_EXIST);
|
throw new RenException(ErrorCode.ROUTE_TASK_NOT_EXIST);
|
||||||
}
|
}
|
||||||
return djiBaseService.executeAndReturnResult(dockSn, "in_flight_wayline_stop",
|
return djiBaseService.executeAndReturnResult(dockSn, "in_flight_wayline_stop",
|
||||||
new JSONObject().set("in_flight_wayline_id", flightId));
|
new JSONObject().set("in_flight_wayline_id", flightId));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -202,6 +217,6 @@ public class RouteFlightServiceImpl implements RouteFlightService {
|
||||||
throw new RenException(ErrorCode.ROUTE_TASK_NOT_EXIST);
|
throw new RenException(ErrorCode.ROUTE_TASK_NOT_EXIST);
|
||||||
}
|
}
|
||||||
return djiBaseService.executeAndReturnResult(dockSn, "in_flight_wayline_recover",
|
return djiBaseService.executeAndReturnResult(dockSn, "in_flight_wayline_recover",
|
||||||
new JSONObject().set("in_flight_wayline_id", flightId));
|
new JSONObject().set("in_flight_wayline_id", flightId));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,275 @@
|
||||||
|
package com.multictrl.modules.business.service.impl;
|
||||||
|
|
||||||
|
import cn.hutool.json.JSONObject;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.multictrl.common.constant.BusinessConstant;
|
||||||
|
import com.multictrl.common.service.impl.CrudServiceImpl;
|
||||||
|
import com.multictrl.common.utils.CacheUtils;
|
||||||
|
import com.multictrl.common.utils.ConvertUtils;
|
||||||
|
import com.multictrl.common.utils.JsonUtils;
|
||||||
|
import com.multictrl.common.utils.weather.*;
|
||||||
|
import com.multictrl.modules.business.dao.WeatherNoflyDao;
|
||||||
|
import com.multictrl.modules.business.dto.LatLonDTO;
|
||||||
|
import com.multictrl.modules.business.dto.WeatherNoflyDTO;
|
||||||
|
import com.multictrl.modules.business.entity.WeatherNoflyEntity;
|
||||||
|
import com.multictrl.modules.business.service.DJIBaseService;
|
||||||
|
import com.multictrl.modules.business.service.WeatherNoflyService;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import com.multictrl.modules.business.service.WeatherService;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 天气阻飞
|
||||||
|
*
|
||||||
|
* @author Sdy
|
||||||
|
* @since 1.0.0 2026-06-15
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class WeatherNoflyServiceImpl extends CrudServiceImpl<WeatherNoflyDao, WeatherNoflyEntity, WeatherNoflyDTO> implements WeatherNoflyService {
|
||||||
|
private final DJIBaseService djiBaseService;
|
||||||
|
private final WeatherService weatherService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public QueryWrapper<WeatherNoflyEntity> getWrapper(Map<String, Object> params) {
|
||||||
|
String id = (String) params.get("id");
|
||||||
|
|
||||||
|
QueryWrapper<WeatherNoflyEntity> wrapper = new QueryWrapper<>();
|
||||||
|
wrapper.eq(StrUtil.isNotBlank(id), "id", id);
|
||||||
|
|
||||||
|
return wrapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WeatherNoflyDTO getInfoByDockSn(String dockSn) {
|
||||||
|
WeatherNoflyEntity entity = baseDao.selectOne(new QueryWrapper<WeatherNoflyEntity>().eq("dock_sn", dockSn));
|
||||||
|
return ConvertUtils.sourceToTarget(entity, WeatherNoflyDTO.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addWeatherNofly(WeatherNoflyDTO dto) {
|
||||||
|
WeatherNoflyEntity entity = baseDao.selectOne(new QueryWrapper<WeatherNoflyEntity>().eq("dock_sn", dto.getDockSn()));
|
||||||
|
if (entity != null) {
|
||||||
|
deleteById(entity.getId());
|
||||||
|
}
|
||||||
|
save(dto);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JSONObject allowFlight(String dockSn, boolean isJobTask) {
|
||||||
|
JSONObject jsonObject = new JSONObject();
|
||||||
|
jsonObject.set("isAllow", true);
|
||||||
|
//查询机库是否有阻飞信息
|
||||||
|
WeatherNoflyEntity entity = baseDao.selectOne(new QueryWrapper<WeatherNoflyEntity>()
|
||||||
|
.eq("dock_sn", dockSn).eq("is_open", true));
|
||||||
|
if (entity != null) {//存在阻飞设置
|
||||||
|
Boolean isAllPrevent = entity.getIsAllPrevent();
|
||||||
|
if (isAllPrevent || isJobTask) {
|
||||||
|
Boolean isOpenWeather = entity.getIsOpenWeather();//判断天气阻飞
|
||||||
|
if (isOpenWeather) {
|
||||||
|
LatLonDTO dockLocation = djiBaseService.getDockLocation(dockSn);
|
||||||
|
String weatherString = weatherService.getWeatherByLonLat(dockLocation.getLongitude(), dockLocation.getLatitude());
|
||||||
|
JSONObject weatherObject = JsonUtils.parseObject(weatherString, JSONObject.class);
|
||||||
|
if (weatherObject != null) {
|
||||||
|
//风速判断
|
||||||
|
String windpower = weatherObject.getStr("windpower");//风力级别
|
||||||
|
double maxWindSpeed = WindSpeedConverter.getMaxWindSpeed(windpower);
|
||||||
|
if (maxWindSpeed >= entity.getWindSpeedWeather()) {
|
||||||
|
log.info("风力过大,级别:{},最大风速:{},阀值:{}", windpower, maxWindSpeed, entity.getWindSpeedWeather());
|
||||||
|
jsonObject.set("isAllow", false);
|
||||||
|
jsonObject.set("reason", "风力过大,阀值:{" + entity.getWindSpeedWeather() + "},起飞时风速:{" + maxWindSpeed + "}");
|
||||||
|
}
|
||||||
|
|
||||||
|
//温度判断
|
||||||
|
double temperature = Double.parseDouble(weatherObject.getStr("temperature"));//温度
|
||||||
|
if (temperature < entity.getTemperatureMin()) {
|
||||||
|
log.info("气温过低,当前温度:{},设置温度下限:{}", temperature, entity.getTemperatureMin());
|
||||||
|
jsonObject.set("isAllow", false);
|
||||||
|
jsonObject.set("reason", "气温过低,阀值:{" + entity.getTemperatureMin() + "},起飞时温度:{" + temperature + "}");
|
||||||
|
}
|
||||||
|
if (temperature > entity.getTemperatureMax()) {
|
||||||
|
log.info("气温过高,当前温度:{},设置温度上限:{}", temperature, entity.getTemperatureMax());
|
||||||
|
jsonObject.set("isAllow", false);
|
||||||
|
jsonObject.set("reason", "气温过高,阀值:{" + entity.getTemperatureMax() + "},起飞时温度:{" + temperature + "}");
|
||||||
|
}
|
||||||
|
|
||||||
|
String weather = weatherObject.getStr("weather");//天气现象
|
||||||
|
//雨量判断
|
||||||
|
Integer rainfallWeather = entity.getRainfallWeather();
|
||||||
|
if (rainfallWeather > 0) {
|
||||||
|
if (rainfallWeather == 1) {
|
||||||
|
if (RainfallUtils.isMinRain(weather) || RainfallUtils.isModerateRain(weather) || RainfallUtils.isMaxRain(weather)) {
|
||||||
|
log.info("已达雨量上限,设置:小雨,实际:{}", weather);
|
||||||
|
jsonObject.set("isAllow", false);
|
||||||
|
jsonObject.set("reason", "触发雨量{小雨}阻飞,起飞时天气:{" + weather + "}");
|
||||||
|
}
|
||||||
|
} else if (rainfallWeather == 2) {
|
||||||
|
if (RainfallUtils.isModerateRain(weather) || RainfallUtils.isMaxRain(weather)) {
|
||||||
|
log.info("已达雨量上限,设置:中雨,实际:{}", weather);
|
||||||
|
jsonObject.set("isAllow", false);
|
||||||
|
jsonObject.set("reason", "触发雨量{中雨}阻飞,起飞时天气:{" + weather + "}");
|
||||||
|
}
|
||||||
|
} else if (rainfallWeather == 3) {
|
||||||
|
if (RainfallUtils.isMaxRain(weather)) {
|
||||||
|
log.info("已达雨量上限,设置:大雨,实际:{}", weather);
|
||||||
|
jsonObject.set("isAllow", false);
|
||||||
|
jsonObject.set("reason", "触发雨量{大雨}阻飞,起飞时天气:{" + weather + "}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//雪量判断
|
||||||
|
Integer snowWeather = entity.getSnowWeather();
|
||||||
|
if (snowWeather > 0) {
|
||||||
|
if (snowWeather == 1) {
|
||||||
|
if (SnowUtils.isMinSnow(weather) || SnowUtils.isModerateSnow(weather) || SnowUtils.isMaxSnow(weather)) {
|
||||||
|
log.info("已达雪量上限,设置:小雪,实际:{}", weather);
|
||||||
|
jsonObject.set("isAllow", false);
|
||||||
|
jsonObject.set("reason", "触发雪量{小雪}阻飞,起飞时天气:{" + weather + "}");
|
||||||
|
}
|
||||||
|
} else if (snowWeather == 2) {
|
||||||
|
if (SnowUtils.isModerateSnow(weather) || SnowUtils.isMaxSnow(weather)) {
|
||||||
|
log.info("已达雪量上限,设置:中雪,实际:{}", weather);
|
||||||
|
jsonObject.set("isAllow", false);
|
||||||
|
jsonObject.set("reason", "触发雪量{中雪}阻飞,起飞时天气:{" + weather + "}");
|
||||||
|
}
|
||||||
|
} else if (snowWeather == 3) {
|
||||||
|
if (SnowUtils.isMaxSnow(weather)) {
|
||||||
|
log.info("已达雪量上限,设置:大雪,实际:{}", weather);
|
||||||
|
jsonObject.set("isAllow", false);
|
||||||
|
jsonObject.set("reason", "触发雪量{大雪}阻飞,起飞时天气:{" + weather + "}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//雾量判断
|
||||||
|
Integer fogWeather = entity.getFogWeather();
|
||||||
|
if (fogWeather > 0) {
|
||||||
|
if (fogWeather == 1) {
|
||||||
|
if (FogUtils.isMinFog(weather) || FogUtils.isModerateFog(weather) || FogUtils.isMaxFog(weather)) {
|
||||||
|
log.info("已达雾量上限,设置:轻雾,实际:{}", weather);
|
||||||
|
jsonObject.set("isAllow", false);
|
||||||
|
jsonObject.set("reason", "触发雾量{轻雾}阻飞,起飞时天气:{" + weather + "}");
|
||||||
|
}
|
||||||
|
} else if (fogWeather == 2) {
|
||||||
|
if (FogUtils.isModerateFog(weather) || FogUtils.isMaxFog(weather)) {
|
||||||
|
log.info("已达雾量上限,设置:中雾,当前:{}", weather);
|
||||||
|
jsonObject.set("isAllow", false);
|
||||||
|
jsonObject.set("reason", "触发雾量{中雾}阻飞,起飞时天气:{" + weather + "}");
|
||||||
|
}
|
||||||
|
} else if (fogWeather == 3) {
|
||||||
|
if (FogUtils.isMaxFog(weather)) {
|
||||||
|
log.info("已达雾量上限,设置:大雾,实际:{}", weather);
|
||||||
|
jsonObject.set("isAllow", false);
|
||||||
|
jsonObject.set("reason", "触发雾量{大雾}阻飞,起飞时天气:{" + weather + "}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//霾量判断
|
||||||
|
Integer hazeWeather = entity.getHazeWeather();
|
||||||
|
if (hazeWeather > 0) {
|
||||||
|
if (hazeWeather == 1) {
|
||||||
|
if (HazeUtils.isMinHaze(weather) || HazeUtils.isModerateHaze(weather) || HazeUtils.isMaxHaze(weather)) {
|
||||||
|
log.info("已达霾量上限,设置:轻度霾,实际:{}", weather);
|
||||||
|
jsonObject.set("isAllow", false);
|
||||||
|
jsonObject.set("reason", "触发霾量{轻度霾}阻飞,起飞时天气:{" + weather + "}");
|
||||||
|
}
|
||||||
|
} else if (hazeWeather == 2) {
|
||||||
|
if (HazeUtils.isModerateHaze(weather) || HazeUtils.isMaxHaze(weather)) {
|
||||||
|
log.info("已达霾量上限,设置:中度霾,实际:{}", weather);
|
||||||
|
jsonObject.set("isAllow", false);
|
||||||
|
jsonObject.set("reason", "触发霾量{中度霾}阻飞,起飞时天气:{" + weather + "}");
|
||||||
|
}
|
||||||
|
} else if (hazeWeather == 3) {
|
||||||
|
if (HazeUtils.isMaxHaze(weather)) {
|
||||||
|
log.info("已达霾量上限,设置:重度霾,实际:{}", weather);
|
||||||
|
jsonObject.set("isAllow", false);
|
||||||
|
jsonObject.set("reason", "触发霾量{重度霾}阻飞,起飞时天气:{" + weather + "}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//冰雹判断
|
||||||
|
Boolean isHailWeather = entity.getIsHailWeather();
|
||||||
|
if (isHailWeather) {
|
||||||
|
if ("雷阵雨并伴有冰雹".equals(weather)) {
|
||||||
|
log.info("已达冰雹阻飞,设置:开启冰雹阻飞,实际:{}", weather);
|
||||||
|
jsonObject.set("isAllow", false);
|
||||||
|
jsonObject.set("reason", "触发冰雹阻飞,起飞时天气:{" + weather + "}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//沙尘暴判断
|
||||||
|
Boolean isSandstormWeather = entity.getIsSandstormWeather();
|
||||||
|
if (isSandstormWeather) {
|
||||||
|
if ("沙尘暴".equals(weather) || "强沙尘暴".equals(weather)) {
|
||||||
|
log.info("已达沙尘暴阻飞,设置:开启沙尘暴阻飞,实际:{}", weather);
|
||||||
|
jsonObject.set("isAllow", false);
|
||||||
|
jsonObject.set("reason", "触发沙尘暴阻飞,起飞时天气:{" + weather + "}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//龙卷风判断
|
||||||
|
Boolean isTornadoWeather = entity.getIsTornadoWeather();
|
||||||
|
if (isTornadoWeather) {
|
||||||
|
if ("龙卷风".equals(weather)) {
|
||||||
|
log.info("已达龙卷风阻飞,设置:开启龙卷风阻飞,实际:{}", weather);
|
||||||
|
jsonObject.set("isAllow", false);
|
||||||
|
jsonObject.set("reason", "触发龙卷风阻飞,起飞时天气:{" + weather + "}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//云端阻飞
|
||||||
|
Integer rainfall = entity.getRainfall();
|
||||||
|
Double windSpeed = entity.getWindSpeed();
|
||||||
|
JSONObject data = (JSONObject) CacheUtils.get(BusinessConstant.DOCK_OSD + dockSn);
|
||||||
|
if (data != null) {
|
||||||
|
if (rainfall == 1 || rainfall == 2 || rainfall == 3) {
|
||||||
|
//0无雨 1小雨 2中雨 3大雨
|
||||||
|
int value = data.getInt("rainfall");
|
||||||
|
if (rainfall == 1) {
|
||||||
|
if (value >= 1) {
|
||||||
|
String message = value == 1 ? "小雨" : value == 2 ? "中雨" : "大雨";
|
||||||
|
log.info("已达下雨阻飞,设置:小雨阻飞,实际:{}", message);
|
||||||
|
jsonObject.set("isAllow", false);
|
||||||
|
jsonObject.set("reason", "触发下雨阻飞,起飞时天气:{" + message + "}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (rainfall == 2) {
|
||||||
|
if (value >= 2) {
|
||||||
|
String message = value == 2 ? "中雨" : "大雨";
|
||||||
|
log.info("已达下雨阻飞,设置:中雨阻飞,实际:{}", message);
|
||||||
|
jsonObject.set("isAllow", false);
|
||||||
|
jsonObject.set("reason", "触发下雨阻飞,起飞时天气:{" + message + "}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (rainfall == 3) {
|
||||||
|
if (value >= 3) {
|
||||||
|
log.info("已达下雨阻飞,设置:大雨阻飞,实际:{大雨}");
|
||||||
|
jsonObject.set("isAllow", false);
|
||||||
|
jsonObject.set("reason", "触发下雨阻飞,起飞时天气:{大雨}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//风速
|
||||||
|
Float value = data.getFloat("wind_speed");
|
||||||
|
if (value >= windSpeed) {
|
||||||
|
log.info("风力过大,设置:风速阻飞:{},实际风速:{}", windSpeed, value);
|
||||||
|
jsonObject.set("isAllow", false);
|
||||||
|
jsonObject.set("reason", "风力过大,阀值:{" + windSpeed + "},起飞时风速:{" + value + "}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return jsonObject;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,132 @@
|
||||||
|
package com.multictrl.modules.business.service.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import cn.hutool.http.HttpUtil;
|
||||||
|
import cn.hutool.json.JSONArray;
|
||||||
|
import cn.hutool.json.JSONObject;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.multictrl.common.constant.SysParamsKey;
|
||||||
|
import com.multictrl.common.exception.ErrorCode;
|
||||||
|
import com.multictrl.common.exception.RenException;
|
||||||
|
import com.multictrl.common.utils.JsonUtils;
|
||||||
|
import com.multictrl.modules.business.service.WeatherService;
|
||||||
|
import com.multictrl.modules.sys.dao.SysParamsDao;
|
||||||
|
import com.multictrl.modules.sys.entity.SysParamsEntity;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 天气服务
|
||||||
|
*
|
||||||
|
* @author Sdy
|
||||||
|
* @since 1.0.0 2026/6/16
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class WeatherServiceImpl implements WeatherService {
|
||||||
|
private final SysParamsDao paramsDao;
|
||||||
|
|
||||||
|
private final static String GAODE_GEOCODE_REGEO = "https://restapi.amap.com/v3/geocode/regeo?key=%s&location=%s&radius=1&extensions=all";
|
||||||
|
public static final String GAODE_WEATHER_API = "https://restapi.amap.com/v3/weather/weatherInfo?key=%s&city=%s&extensions=base";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getWeatherByLonLat(Double longitude, Double latitude) {
|
||||||
|
String location = longitude + "," + latitude;
|
||||||
|
try {
|
||||||
|
String adCode = getAdCode(location);
|
||||||
|
if (StrUtil.isEmpty(adCode)) {
|
||||||
|
log.debug("获取 adcode 失败,经纬度:{}", location);
|
||||||
|
throw new RenException(ErrorCode.GAODE_REQUEST_ERROR);
|
||||||
|
}
|
||||||
|
String weatherByAdCode = getWeatherByAdCode(adCode);
|
||||||
|
if (StrUtil.isEmpty(weatherByAdCode)) {
|
||||||
|
log.debug("获取 weatherByAdCode 失败,经纬度:{}, adCode:{}", location, adCode);
|
||||||
|
throw new RenException(ErrorCode.GAODE_REQUEST_ERROR);
|
||||||
|
}
|
||||||
|
return weatherByAdCode;
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("获取天气信息异常,经纬度:{}", location, e);
|
||||||
|
throw new RenException(ErrorCode.GAODE_REQUEST_ERROR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取高德Key
|
||||||
|
*/
|
||||||
|
private String getGaoDeKey() {
|
||||||
|
SysParamsEntity entity = paramsDao.selectOne(new QueryWrapper<SysParamsEntity>()
|
||||||
|
.eq("param_code", SysParamsKey.GAODE_API_KEY));
|
||||||
|
if (entity == null) {
|
||||||
|
throw new RenException(ErrorCode.GAODE_API_KEY_NO_CONFIG);
|
||||||
|
}
|
||||||
|
|
||||||
|
return entity.getParamValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 调用高德地理编码 API 获取 adcode
|
||||||
|
*/
|
||||||
|
private String getAdCode(String location) {
|
||||||
|
String url = String.format(GAODE_GEOCODE_REGEO, getGaoDeKey(), location);
|
||||||
|
try {
|
||||||
|
String response = HttpUtil.get(url);
|
||||||
|
if (StrUtil.isEmpty(response)) {
|
||||||
|
log.debug("gaode_地理编码接口返回空,url:{}", url);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
JSONObject jsonObject = JsonUtils.parseObject(response, JSONObject.class);
|
||||||
|
if (jsonObject == null || !"OK".equals(jsonObject.getStr("info"))) {
|
||||||
|
log.debug("gaode_地理编码接口返回失败,url:{}, response:{}", url, response);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
JSONObject regeocode = jsonObject.getJSONObject("regeocode");
|
||||||
|
if (regeocode == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
JSONObject addressComponent = regeocode.getJSONObject("addressComponent");
|
||||||
|
if (addressComponent == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return addressComponent.getStr("adcode");
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("gaode_地理编码请求异常,url:{}", url, e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据 adcode 调用高德天气 API 获取实时天气
|
||||||
|
*/
|
||||||
|
private String getWeatherByAdCode(String adCode) {
|
||||||
|
String url = String.format(GAODE_WEATHER_API, getGaoDeKey(), adCode);
|
||||||
|
try {
|
||||||
|
String response = HttpUtil.get(url);
|
||||||
|
if (StrUtil.isEmpty(response)) {
|
||||||
|
log.debug("gaode_天气接口返回空,adCode:{}", adCode);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
JSONObject weatherObject = JsonUtils.parseObject(response, JSONObject.class);
|
||||||
|
if (weatherObject == null) {
|
||||||
|
log.debug("gaode_天气接口返回非 JSON,adCode:{}", adCode);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// 高德天气成功状态为 "1"
|
||||||
|
if (!"1".equals(weatherObject.getStr("status"))) {
|
||||||
|
log.debug("gaode_天气接口返回失败,adCode:{}, response:{}", adCode, response);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
JSONArray lives = weatherObject.getJSONArray("lives");
|
||||||
|
if (lives == null || lives.isEmpty()) {
|
||||||
|
log.debug("gaode_天气接口返回 lives 为空,adCode:{}", adCode);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
JSONObject firstLive = lives.getJSONObject(0);
|
||||||
|
return firstLive.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("gaode_天气请求异常,url:{}", url, e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -2,9 +2,11 @@ package com.multictrl.modules.job.task;
|
||||||
|
|
||||||
import cn.hutool.json.JSONObject;
|
import cn.hutool.json.JSONObject;
|
||||||
import com.multictrl.common.constant.BusinessConstant;
|
import com.multictrl.common.constant.BusinessConstant;
|
||||||
|
import com.multictrl.common.constant.FlightTaskType;
|
||||||
import com.multictrl.common.utils.CacheUtils;
|
import com.multictrl.common.utils.CacheUtils;
|
||||||
import com.multictrl.common.utils.JsonUtils;
|
import com.multictrl.common.utils.JsonUtils;
|
||||||
import com.multictrl.common.utils.Utils;
|
import com.multictrl.common.utils.Utils;
|
||||||
|
import com.multictrl.modules.business.dto.WeatherNoflyTaskDTO;
|
||||||
import com.multictrl.modules.business.dto.flight.FlightExecute;
|
import com.multictrl.modules.business.dto.flight.FlightExecute;
|
||||||
import com.multictrl.modules.business.service.FlightTaskService;
|
import com.multictrl.modules.business.service.FlightTaskService;
|
||||||
import com.multictrl.modules.business.service.RouteFlightService;
|
import com.multictrl.modules.business.service.RouteFlightService;
|
||||||
|
|
@ -50,10 +52,19 @@ public class RouteTask implements ITask {
|
||||||
//执行任务
|
//执行任务
|
||||||
FlightExecute flightExecute = new FlightExecute();
|
FlightExecute flightExecute = new FlightExecute();
|
||||||
flightExecute.setRouteId(Long.parseLong(dto.getParams()));
|
flightExecute.setRouteId(Long.parseLong(dto.getParams()));
|
||||||
routeFlightService.flightExecute(dockSn, flightExecute, false);
|
String result = routeFlightService.flightExecute(dockSn, flightExecute, false, FlightTaskType.SCHEDULED.getCode());
|
||||||
//添加日志
|
//添加日志
|
||||||
Utils.sleep(1000);
|
Utils.sleep(1000);
|
||||||
String taskId = (String) CacheUtils.get(BusinessConstant.WORKING_TASK_ID + dockSn);
|
String taskId = (String) CacheUtils.get(BusinessConstant.WORKING_TASK_ID + dockSn);
|
||||||
flightTaskService.addJobRouteTask(taskId, jobId);
|
if (result.contains("阻飞")) {
|
||||||
|
WeatherNoflyTaskDTO noflyTask = new WeatherNoflyTaskDTO();
|
||||||
|
noflyTask.setTaskId(taskId);
|
||||||
|
noflyTask.setJobId(jobId);
|
||||||
|
noflyTask.setTaskType(FlightTaskType.SCHEDULED.getCode());
|
||||||
|
noflyTask.setReason(result);
|
||||||
|
flightTaskService.addWeatherNoflyTask(noflyTask);
|
||||||
|
} else {
|
||||||
|
flightTaskService.addJobRouteTask(taskId, jobId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,17 @@
|
||||||
package com.multictrl.modules.sys.controller;
|
package com.multictrl.modules.sys.controller;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
import com.multictrl.common.annotation.ApiOrder;
|
import com.multictrl.common.annotation.ApiOrder;
|
||||||
import com.multictrl.common.utils.Result;
|
import com.multictrl.common.utils.Result;
|
||||||
import com.multictrl.modules.business.influxdb.UavReport;
|
import com.multictrl.modules.business.influxdb.UavReport;
|
||||||
import com.multictrl.modules.business.service.InfluxService;
|
import com.multictrl.modules.business.service.InfluxService;
|
||||||
|
import com.multictrl.modules.business.service.WeatherService;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
@ -25,6 +28,7 @@ import java.util.List;
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class IndexController {
|
public class IndexController {
|
||||||
private final InfluxService influxService;
|
private final InfluxService influxService;
|
||||||
|
private final WeatherService weatherService;
|
||||||
|
|
||||||
@GetMapping("/")
|
@GetMapping("/")
|
||||||
public Result<String> index() {
|
public Result<String> index() {
|
||||||
|
|
@ -42,4 +46,11 @@ public class IndexController {
|
||||||
System.out.println(flyList);
|
System.out.println(flyList);
|
||||||
return new Result<>();
|
return new Result<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "经纬度获取天气信息")
|
||||||
|
@GetMapping("/getWeatherByLocation")
|
||||||
|
public Result<JSONObject> getWeatherByLocation(@RequestParam Double lon, @RequestParam Double lat) {
|
||||||
|
String data = weatherService.getWeatherByLonLat(lon, lat);
|
||||||
|
return new Result<JSONObject>().ok(JSONObject.parseObject(data));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -72,4 +72,6 @@ public interface ErrorCode {
|
||||||
int ZHIMOU_NO_CONFIG = 20031;
|
int ZHIMOU_NO_CONFIG = 20031;
|
||||||
int ZHIMOU_REQUEST_ERROR = 20032;
|
int ZHIMOU_REQUEST_ERROR = 20032;
|
||||||
int ZHIMOU_TASK_NOT_EXIST = 20033;
|
int ZHIMOU_TASK_NOT_EXIST = 20033;
|
||||||
|
int GAODE_API_KEY_NO_CONFIG = 20034;
|
||||||
|
int GAODE_REQUEST_ERROR = 20035;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -60,4 +60,6 @@
|
||||||
20030=\u5220\u9664{0}\u5931\u8D25\uFF0C\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458
|
20030=\u5220\u9664{0}\u5931\u8D25\uFF0C\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458
|
||||||
20031=AI\u56FE\u50CF\u68C0\u6D4B\u7B97\u6CD5\u4FE1\u606F\u672A\u914D\u7F6E
|
20031=AI\u56FE\u50CF\u68C0\u6D4B\u7B97\u6CD5\u4FE1\u606F\u672A\u914D\u7F6E
|
||||||
20032=AI\u56FE\u50CF\u68C0\u6D4B\u7B97\u6CD5\u8BF7\u6C42\u51FA\u9519
|
20032=AI\u56FE\u50CF\u68C0\u6D4B\u7B97\u6CD5\u8BF7\u6C42\u51FA\u9519
|
||||||
20033=AI\u4EFB\u52A1\u672A\u5F00\u542F
|
20033=AI\u4EFB\u52A1\u672A\u5F00\u542F
|
||||||
|
20034=\u5929\u6C14\u4FE1\u606F\u8BBF\u95EEkey\u672A\u914D\u7F6E
|
||||||
|
20035=\u5929\u6C14\u63A5\u53E3\u8BF7\u6C42\u51FA\u9519
|
||||||
|
|
@ -2351,4 +2351,80 @@ ALTER TABLE "public"."bus_maintenance_img"
|
||||||
ALTER TABLE public.bus_flight_task
|
ALTER TABLE public.bus_flight_task
|
||||||
ADD ai_media_num int4 NULL;
|
ADD ai_media_num int4 NULL;
|
||||||
COMMENT
|
COMMENT
|
||||||
ON COLUMN public.bus_flight_task.ai_media_num IS 'ai媒体数量';
|
ON COLUMN public.bus_flight_task.ai_media_num IS 'ai媒体数量';
|
||||||
|
|
||||||
|
--2026/6/17
|
||||||
|
DROP TABLE IF EXISTS "public"."bus_weather_nofly";
|
||||||
|
CREATE TABLE "public"."bus_weather_nofly"
|
||||||
|
(
|
||||||
|
"id" int8 NOT NULL,
|
||||||
|
"dock_sn" varchar(255) COLLATE "pg_catalog"."default" NOT NULL,
|
||||||
|
"is_open" bool NOT NULL,
|
||||||
|
"wind_speed" float8,
|
||||||
|
"rainfall" int4,
|
||||||
|
"is_all_prevent" bool NOT NULL,
|
||||||
|
"is_open_weather" bool NOT NULL,
|
||||||
|
"wind_speed_weather" float8,
|
||||||
|
"rainfall_weather" int4,
|
||||||
|
"snow_weather" int4,
|
||||||
|
"fog_weather" int4,
|
||||||
|
"haze_weather" int4,
|
||||||
|
"is_hail_weather" bool,
|
||||||
|
"is_sandstorm_weather" bool,
|
||||||
|
"is_tornado_weather" bool,
|
||||||
|
"temperature_max" float8,
|
||||||
|
"temperature_min" float8,
|
||||||
|
"creator" int8,
|
||||||
|
"create_date" timestamp(6),
|
||||||
|
"updater" int8,
|
||||||
|
"update_date" timestamp(6)
|
||||||
|
)
|
||||||
|
;
|
||||||
|
COMMENT
|
||||||
|
ON COLUMN "public"."bus_weather_nofly"."dock_sn" IS '机库sn';
|
||||||
|
COMMENT
|
||||||
|
ON COLUMN "public"."bus_weather_nofly"."is_open" IS '是否开启阻飞(开启后使用机库上报数据)';
|
||||||
|
COMMENT
|
||||||
|
ON COLUMN "public"."bus_weather_nofly"."wind_speed" IS '风速m/s';
|
||||||
|
COMMENT
|
||||||
|
ON COLUMN "public"."bus_weather_nofly"."rainfall" IS '雨(0关闭 1小雨 2中雨 3大雨)';
|
||||||
|
COMMENT
|
||||||
|
ON COLUMN "public"."bus_weather_nofly"."is_all_prevent" IS '是否全部阻飞(开启后全部阻飞不开启只阻飞计划库)';
|
||||||
|
COMMENT
|
||||||
|
ON COLUMN "public"."bus_weather_nofly"."is_open_weather" IS '是否开启天气阻飞(开启后在机库数据上增加天气预报数据)';
|
||||||
|
COMMENT
|
||||||
|
ON COLUMN "public"."bus_weather_nofly"."wind_speed_weather" IS '风速m/s(天气预报)';
|
||||||
|
COMMENT
|
||||||
|
ON COLUMN "public"."bus_weather_nofly"."rainfall_weather" IS '雨(天气预报 0关闭 1小雨 2中雨 3大雨)';
|
||||||
|
COMMENT
|
||||||
|
ON COLUMN "public"."bus_weather_nofly"."snow_weather" IS '雪(天气预报 0关闭 1小雪 2中雪 3大雪)';
|
||||||
|
COMMENT
|
||||||
|
ON COLUMN "public"."bus_weather_nofly"."fog_weather" IS '雾(天气预报 0关闭 1轻雾 2中雾 3大雾)';
|
||||||
|
COMMENT
|
||||||
|
ON COLUMN "public"."bus_weather_nofly"."haze_weather" IS '霾(天气预报 0关闭 1轻度霾 2中度霾 3重度霾)';
|
||||||
|
COMMENT
|
||||||
|
ON COLUMN "public"."bus_weather_nofly"."is_hail_weather" IS '冰雹阻飞';
|
||||||
|
COMMENT
|
||||||
|
ON COLUMN "public"."bus_weather_nofly"."is_sandstorm_weather" IS '沙尘暴阻飞';
|
||||||
|
COMMENT
|
||||||
|
ON COLUMN "public"."bus_weather_nofly"."is_tornado_weather" IS '龙卷风阻飞';
|
||||||
|
COMMENT
|
||||||
|
ON COLUMN "public"."bus_weather_nofly"."temperature_max" IS '温度上限(摄氏度)';
|
||||||
|
COMMENT
|
||||||
|
ON COLUMN "public"."bus_weather_nofly"."temperature_min" IS '温度下限(摄氏度)';
|
||||||
|
COMMENT
|
||||||
|
ON COLUMN "public"."bus_weather_nofly"."creator" IS '创建人';
|
||||||
|
COMMENT
|
||||||
|
ON COLUMN "public"."bus_weather_nofly"."create_date" IS '创建时间';
|
||||||
|
COMMENT
|
||||||
|
ON COLUMN "public"."bus_weather_nofly"."updater" IS '修改人';
|
||||||
|
COMMENT
|
||||||
|
ON COLUMN "public"."bus_weather_nofly"."update_date" IS '修改时间';
|
||||||
|
COMMENT
|
||||||
|
ON TABLE "public"."bus_weather_nofly" IS '天气阻飞';
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Primary Key structure for table bus_weather_nofly
|
||||||
|
-- ----------------------------
|
||||||
|
ALTER TABLE "public"."bus_weather_nofly"
|
||||||
|
ADD CONSTRAINT "uav_hangar_prevent_pkey" PRIMARY KEY ("id");
|
||||||
Loading…
Reference in New Issue