新增航线AI绑定、自动开启

This commit is contained in:
sdy 2026-06-18 15:57:00 +08:00
parent f633b2179f
commit 5ac4eb1043
16 changed files with 324 additions and 9 deletions

View File

@ -12,6 +12,7 @@ public interface BusinessConstant {
String WEB_EVENT_TOPIC = "thing/product/%s/web_event"; String WEB_EVENT_TOPIC = "thing/product/%s/web_event";
String NOFLY_ZONE_METHOD = "nofly_zone"; String NOFLY_ZONE_METHOD = "nofly_zone";
String ZHIMOU_AI_CALLBACK = "zhimou_ai_callback"; String ZHIMOU_AI_CALLBACK = "zhimou_ai_callback";
String ZHIMOU_AI_METHOD = "zhimou_ai";
//********************************* minio *********************************// //********************************* minio *********************************//
String ROUTE_IMG_BUCKET = "route-images";//航线图片桶 String ROUTE_IMG_BUCKET = "route-images";//航线图片桶
@ -95,6 +96,8 @@ public interface BusinessConstant {
String DOCK_NOFLY_ZONE_TRIGGER_SIGN = "dock_nofly_zone_trigger_sign_"; String DOCK_NOFLY_ZONE_TRIGGER_SIGN = "dock_nofly_zone_trigger_sign_";
String ZHIMOU_TOKEN = "zhiMou_token"; String ZHIMOU_TOKEN = "zhiMou_token";
String DOCK_ZHIMOU_CONFIG = "dock_zhiMou_config_"; String DOCK_ZHIMOU_CONFIG = "dock_zhiMou_config_";
String ZHIMOU_AI_START = "zhimou_ai_start_";
String ZHIMOU_AI_STOP = "zhimou_ai_stop_";
//********************************* other *********************************// //********************************* other *********************************//
String HTTP_PROTOCOL = "http://"; String HTTP_PROTOCOL = "http://";

View File

@ -9,6 +9,7 @@ import com.multictrl.common.validator.AssertUtils;
import com.multictrl.common.validator.ValidatorUtils; import com.multictrl.common.validator.ValidatorUtils;
import com.multictrl.common.validator.group.AddGroup; import com.multictrl.common.validator.group.AddGroup;
import com.multictrl.common.validator.group.UpdateGroup; import com.multictrl.common.validator.group.UpdateGroup;
import com.multictrl.modules.business.dto.RouteAiDTO;
import com.multictrl.modules.business.dto.RouteDTO; import com.multictrl.modules.business.dto.RouteDTO;
import com.multictrl.modules.business.service.RouteService; import com.multictrl.modules.business.service.RouteService;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
@ -95,4 +96,24 @@ public class RouteController {
return new Result<>(); return new Result<>();
} }
@PostMapping("/setRouteAi")
@Operation(summary = "设置航线AI任务")
@LogOperation("设置航线AI任务")
@RequiresPermissions("bus:route:setAi")
public Result<Object> setRouteAi(@RequestBody RouteAiDTO dto) {
routeService.setRouteAi(dto);
return new Result<>();
}
@DeleteMapping("/deleteRouteAi")
@Operation(summary = "删除航线AI任务")
@LogOperation("删除航线AI任务")
@RequiresPermissions("bus:route:deleteAi")
public Result<Object> deleteRouteAi(@RequestParam Long routeId) {
routeService.deleteRouteAi(routeId);
return new Result<>();
}
} }

View File

@ -109,4 +109,13 @@ public class ZhiMouController {
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + encodedFileName) .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + encodedFileName)
.body(reportBytes); .body(reportBytes);
} }
@Operation(summary = "是否有AI服务")
@GetMapping("/hasAiServer")
@RequiresPermissions("bus:zhiMou:hasAiServer")
public Result<Object> hasAiServer() {
boolean result = zhiMouService.hasAiService();
return new Result<>().ok(result);
}
} }

View File

@ -0,0 +1,16 @@
package com.multictrl.modules.business.dao;
import com.multictrl.common.dao.BaseDao;
import com.multictrl.modules.business.entity.RouteAiEntity;
import org.apache.ibatis.annotations.Mapper;
/**
* 航线AI任务
*
* @author Sdy
* @since 1.0.0 2026-06-18
*/
@Mapper
public interface RouteAiDao extends BaseDao<RouteAiEntity> {
}

View File

@ -0,0 +1,37 @@
package com.multictrl.modules.business.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
/**
* 航线AI任务
*
* @author Sdy
* @since 1.0.0 2026-06-18
*/
@Data
@Schema(name = "航线AI任务")
public class RouteAiDTO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@NotNull(message = "航线标识不能为空")
@Schema(description = "航线标识")
private Long routeId;
@NotBlank(message = "应用编号不能为空")
@Schema(description = "知眸应用编号")
private String zhimouAppId;
@NotBlank(message = "应用子类不能为空")
@Schema(description = "智眸应用子类编号")
private String zhimouChildId;
}

View File

@ -134,4 +134,10 @@ public class RouteDTO implements Serializable {
@JsonProperty(required = true) @JsonProperty(required = true)
@Schema(description = "航点信息") @Schema(description = "航点信息")
private List<RouteWaypointDTO> routeWaypointList; private List<RouteWaypointDTO> routeWaypointList;
@Schema(description = "知眸应用编号")
private String zhimouAppId;
@Schema(description = "智眸应用子类编号")
private String zhimouChildId;
} }

View File

@ -0,0 +1,32 @@
package com.multictrl.modules.business.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import com.multictrl.common.entity.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.Date;
/**
* 航线AI任务
*
* @author Sdy
* @since 1.0.0 2026-06-18
*/
@EqualsAndHashCode(callSuper = true)
@Data
@TableName("bus_route_ai")
public class RouteAiEntity extends BaseEntity {
/**
* 航线编号
*/
private Long routeId;
/**
* 知眸应用编号
*/
private String zhimouAppId;
/**
* 智眸应用子类编号
*/
private String zhimouChildId;
}

View File

@ -3,11 +3,17 @@ package com.multictrl.modules.business.handler;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONArray; import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject; import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
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.utils.CacheUtils; import com.multictrl.common.utils.CacheUtils;
import com.multictrl.common.utils.JsonUtils; import com.multictrl.common.utils.JsonUtils;
import com.multictrl.modules.business.dao.RouteAiDao;
import com.multictrl.modules.business.dto.NoflyZoneDTO; import com.multictrl.modules.business.dto.NoflyZoneDTO;
import com.multictrl.modules.business.dto.zhimou.ZhiMouAiStart;
import com.multictrl.modules.business.entity.FlightTaskEntity;
import com.multictrl.modules.business.entity.RouteAiEntity;
import com.multictrl.modules.business.influxdb.FlightLog; import com.multictrl.modules.business.influxdb.FlightLog;
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.*;
@ -15,10 +21,7 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.Collections; import java.util.*;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.*; import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
@ -39,6 +42,8 @@ public class OsdHandler implements MessageHandler {
private final DJIBaseService djiBaseService; private final DJIBaseService djiBaseService;
private final MqttPushService mqttPushService; private final MqttPushService mqttPushService;
private final NoflyZoneService noflyZoneService; private final NoflyZoneService noflyZoneService;
private final ZhiMouService zhiMouService;
private final RouteAiDao routeAiDao;
@Override @Override
public void handleMessage(String topic, String payload, String gateway) { public void handleMessage(String topic, String payload, String gateway) {
@ -156,6 +161,9 @@ public class OsdHandler implements MessageHandler {
Double height = data.getDouble("height"); Double height = data.getDouble("height");
NoflyZoneDTO.point point = new NoflyZoneDTO.point(uavReport.getLongitude(), uavReport.getLatitude(), height); NoflyZoneDTO.point point = new NoflyZoneDTO.point(uavReport.getLongitude(), uavReport.getLatitude(), height);
judgingNoFlyZone(dockSn, point, mode); judgingNoFlyZone(dockSn, point, mode);
//智眸AI
routeAiTask(dockSn, mode);
} }
} }
} else { } else {
@ -264,4 +272,58 @@ public class OsdHandler implements MessageHandler {
JSONObject payload = djiBaseService.getPayload(BusinessConstant.NOFLY_ZONE_METHOD, data); JSONObject payload = djiBaseService.getPayload(BusinessConstant.NOFLY_ZONE_METHOD, data);
mqttPushService.pushMessageByClient1(BusinessConstant.WEB_EVENT_TOPIC.formatted(dockSn), payload.toString()); mqttPushService.pushMessageByClient1(BusinessConstant.WEB_EVENT_TOPIC.formatted(dockSn), payload.toString());
} }
/**
* 航线AI任务智眸判断开启
* {"0":"待机","1":"起飞准备","2":"起飞准备完毕","3":"手动飞行","4":"自动起飞","5":"航线飞行","6":"全景拍照","7":"智能跟随","8":"ADS-B 躲避","9":"自动返航",
* "10":"自动降落","11":"强制降落","12":"三桨叶降落","13":"升级中","14":"未连接","15":"APAS","16":"虚拟摇杆状态","17":"指令飞行","18":"空中 RTK 收敛模式",
* "19":"机场选址中","20":"POI环绕","21":"进离场航线飞行过程中"}
*/
private void routeAiTask(String dockSn, Integer modeCode) {
//起飞
if (modeCode == 4) {
CacheUtils.delete(BusinessConstant.ZHIMOU_AI_STOP + dockSn);
if (CacheUtils.get(BusinessConstant.ZHIMOU_AI_START + dockSn) == null) {
CacheUtils.set(BusinessConstant.ZHIMOU_AI_START + dockSn, true);
log.info("航线自动检测AI任务:{}", dockSn);
String taskId = (String) CacheUtils.get(BusinessConstant.WORKING_TASK_ID + dockSn);
FlightTaskEntity entity = flightTaskService.selectById(taskId);
if (!Objects.equals(FlightTaskType.MANUAL.getCode(), entity.getTaskType())) {
RouteAiEntity routeAiEntity = routeAiDao.selectOne(new QueryWrapper<RouteAiEntity>().eq("route_id", entity.getRouteId()));
if (routeAiEntity != null) {
log.info("航线检测到AI任务dockSn:{}, routeId:{}", dockSn, entity.getRouteId());
ZhiMouAiStart zhiMouAiStart = new ZhiMouAiStart();
zhiMouAiStart.setDockSn(dockSn);
zhiMouAiStart.setAppId(routeAiEntity.getZhimouAppId());
zhiMouAiStart.setRules(Arrays.asList(routeAiEntity.getZhimouChildId().split(",")));
com.alibaba.fastjson2.JSONObject result = zhiMouService.startByWeb(zhiMouAiStart);
log.info("航线开启AI任务dockSn:{}, result:{}", dockSn, result);
}
}
}
}
//返航
if (modeCode == 9) {
if (CacheUtils.get(BusinessConstant.ZHIMOU_AI_STOP + dockSn) == null) {
CacheUtils.set(BusinessConstant.ZHIMOU_AI_STOP + dockSn, true);
if (CacheUtils.get(BusinessConstant.ZHIMOU_AI_START + dockSn) != null) {
CacheUtils.delete(BusinessConstant.ZHIMOU_AI_START + dockSn);
com.alibaba.fastjson2.JSONObject result = zhiMouService.stopByWeb(dockSn);
log.info("航线自动停止AI任务dockSn:{}, result:{}", dockSn, result);
if (result != null && result.getIntValue("code") == 0) {
JSONObject data = new JSONObject();
data.set("device", dockSn);
data.set("event", "stop");
data.set("timestamp", System.currentTimeMillis());
JSONObject payload = djiBaseService.getPayload(BusinessConstant.ZHIMOU_AI_METHOD, data);
mqttPushService.pushMessageByClient1(BusinessConstant.WEB_EVENT_TOPIC.formatted(dockSn), payload.toString());
//修改AI媒体
String taskId = (String) CacheUtils.get(BusinessConstant.WORKING_TASK_ID + dockSn);
flightTaskService.updateTaskAiMediaNum(taskId);
}
}
}
}
}
} }

View File

@ -1,9 +1,12 @@
package com.multictrl.modules.business.handler; package com.multictrl.modules.business.handler;
import cn.hutool.json.JSONObject; import cn.hutool.json.JSONObject;
import com.multictrl.common.constant.BusinessConstant;
import com.multictrl.common.utils.JsonUtils; import com.multictrl.common.utils.JsonUtils;
import com.multictrl.modules.business.dao.ZhimouCallbackDao; import com.multictrl.modules.business.dao.ZhimouCallbackDao;
import com.multictrl.modules.business.entity.ZhimouCallbackEntity; import com.multictrl.modules.business.entity.ZhimouCallbackEntity;
import com.multictrl.modules.business.service.DJIBaseService;
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.Component; import org.springframework.stereotype.Component;
@ -19,6 +22,8 @@ import org.springframework.stereotype.Component;
@RequiredArgsConstructor @RequiredArgsConstructor
public class ZhiMouCallbackHandler implements MessageHandler { public class ZhiMouCallbackHandler implements MessageHandler {
private final ZhimouCallbackDao zhimouCallbackDao; private final ZhimouCallbackDao zhimouCallbackDao;
private final DJIBaseService djiBaseService;
private final MqttPushService mqttPushService;
@Override @Override
public void handleMessage(String topic, String payload, String gateway) { public void handleMessage(String topic, String payload, String gateway) {
@ -35,6 +40,10 @@ public class ZhiMouCallbackHandler implements MessageHandler {
entity.setTaskId(data.getStr("task_id")); entity.setTaskId(data.getStr("task_id"));
entity.setTimestamp(data.getLong("timestamp")); entity.setTimestamp(data.getLong("timestamp"));
zhimouCallbackDao.insert(entity); zhimouCallbackDao.insert(entity);
//推送给前端
JSONObject message = djiBaseService.getPayload(BusinessConstant.ZHIMOU_AI_METHOD, data);
mqttPushService.pushMessageByClient1(BusinessConstant.WEB_EVENT_TOPIC.formatted(gateway), message.toString());
} }
} }
} }

View File

@ -53,4 +53,7 @@ public interface FlightTaskService extends CrudService<FlightTaskEntity, FlightT
//获取上一条任务 //获取上一条任务
FlightTaskDTO getPreviousTask(String taskId, String dockSn); FlightTaskDTO getPreviousTask(String taskId, String dockSn);
//更新架次AI媒体数量
void updateTaskAiMediaNum(String taskId);
} }

View File

@ -2,6 +2,7 @@ package com.multictrl.modules.business.service;
import com.multictrl.common.page.PageData; import com.multictrl.common.page.PageData;
import com.multictrl.common.service.CrudService; import com.multictrl.common.service.CrudService;
import com.multictrl.modules.business.dto.RouteAiDTO;
import com.multictrl.modules.business.dto.RouteDTO; import com.multictrl.modules.business.dto.RouteDTO;
import com.multictrl.modules.business.entity.RouteEntity; import com.multictrl.modules.business.entity.RouteEntity;
@ -29,4 +30,10 @@ public interface RouteService extends CrudService<RouteEntity, RouteDTO> {
//生成kmz //生成kmz
String generateKml(RouteDTO routeDTO); String generateKml(RouteDTO routeDTO);
//设置航线AI任务
void setRouteAi(RouteAiDTO routeAi);
//删除AI任务
void deleteRouteAi(Long routeId);
} }

View File

@ -52,4 +52,7 @@ public interface ZhiMouService {
//获取媒体数量 //获取媒体数量
Integer getMediaCount(String taskId); Integer getMediaCount(String taskId);
//是否有AI服务
boolean hasAiService();
} }

View File

@ -1,10 +1,12 @@
package com.multictrl.modules.business.service.impl; package com.multictrl.modules.business.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime; import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.FileUtil;
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.core.conditions.update.UpdateWrapper;
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;
@ -17,6 +19,7 @@ import cn.hutool.core.util.StrUtil;
import com.multictrl.common.utils.*; import com.multictrl.common.utils.*;
import com.multictrl.modules.business.dao.DockDeviceDao; import com.multictrl.modules.business.dao.DockDeviceDao;
import com.multictrl.modules.business.dao.FlightTaskDao; import com.multictrl.modules.business.dao.FlightTaskDao;
import com.multictrl.modules.business.dao.ZhimouCallbackDao;
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;
@ -34,6 +37,7 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.*; import java.util.*;
import java.util.stream.Collectors;
/** /**
* 飞行架次 * 飞行架次
@ -54,6 +58,7 @@ public class FlightTaskServiceImpl extends CrudServiceImpl<FlightTaskDao, Flight
private final ScheduleJobDao scheduleJobDao; private final ScheduleJobDao scheduleJobDao;
private final SysUserService userService; private final SysUserService userService;
private final ZhiMouService zhiMouService; private final ZhiMouService zhiMouService;
private final ZhimouCallbackDao zhimouCallbackDao;
@Override @Override
public QueryWrapper<FlightTaskEntity> getWrapper(Map<String, Object> params) { public QueryWrapper<FlightTaskEntity> getWrapper(Map<String, Object> params) {
@ -235,12 +240,10 @@ public class FlightTaskServiceImpl extends CrudServiceImpl<FlightTaskDao, Flight
Long count = mediaFileService.getDao().selectCount(new QueryWrapper<MediaFileEntity>() Long count = mediaFileService.getDao().selectCount(new QueryWrapper<MediaFileEntity>()
.eq("task_id", taskId).eq("dock_sn", dockSn)); .eq("task_id", taskId).eq("dock_sn", dockSn));
entity.setMediaNum(count.intValue()); entity.setMediaNum(count.intValue());
updateById(entity);
//更新ai媒体数量 //更新ai媒体数量
Integer mediaCount = zhiMouService.getMediaCount(taskId); updateTaskAiMediaNum(taskId);
entity.setAiMediaNum(mediaCount);
updateById(entity);
} }
@Override @Override
@ -403,6 +406,22 @@ public class FlightTaskServiceImpl extends CrudServiceImpl<FlightTaskDao, Flight
return ConvertUtils.sourceToTarget(previousTask, FlightTaskDTO.class); return ConvertUtils.sourceToTarget(previousTask, FlightTaskDTO.class);
} }
@Override
public void updateTaskAiMediaNum(String taskId) {
List<ZhimouCallbackEntity> entityList = zhimouCallbackDao.selectList(new QueryWrapper<ZhimouCallbackEntity>()
.eq("business_id", taskId));
if (CollUtil.isEmpty(entityList)) {
return;
}
Set<String> taskIds = entityList.stream().map(ZhimouCallbackEntity::getTaskId).collect(Collectors.toSet());
int count = 0;
for (String ti : taskIds) {
count += zhiMouService.getMediaCount(ti);
}
baseDao.update(new UpdateWrapper<FlightTaskEntity>().set("ai_media_num", count)
.eq("task_id", taskId));
}
//添加dock信息 //添加dock信息
private void addDockInfo(FlightTaskEntity entity, String dockSn) { private void addDockInfo(FlightTaskEntity entity, String dockSn) {
entity.setDockSn(dockSn); entity.setDockSn(dockSn);

View File

@ -1,5 +1,6 @@
package com.multictrl.modules.business.service.impl; package com.multictrl.modules.business.service.impl;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.multictrl.common.constant.BusinessConstant; import com.multictrl.common.constant.BusinessConstant;
@ -9,12 +10,16 @@ import com.multictrl.common.service.impl.CrudServiceImpl;
import com.multictrl.common.utils.ConvertUtils; import com.multictrl.common.utils.ConvertUtils;
import com.multictrl.common.utils.kmz.KmzUtils; import com.multictrl.common.utils.kmz.KmzUtils;
import com.multictrl.common.validator.AssertUtils; import com.multictrl.common.validator.AssertUtils;
import com.multictrl.common.validator.ValidatorUtils;
import com.multictrl.modules.business.dao.RouteAiDao;
import com.multictrl.modules.business.dao.RouteDao; import com.multictrl.modules.business.dao.RouteDao;
import com.multictrl.modules.business.dao.RouteWaypointDao; import com.multictrl.modules.business.dao.RouteWaypointDao;
import com.multictrl.modules.business.dao.WaypointActionDao; import com.multictrl.modules.business.dao.WaypointActionDao;
import com.multictrl.modules.business.dto.RouteAiDTO;
import com.multictrl.modules.business.dto.RouteDTO; import com.multictrl.modules.business.dto.RouteDTO;
import com.multictrl.modules.business.dto.RouteWaypointDTO; import com.multictrl.modules.business.dto.RouteWaypointDTO;
import com.multictrl.modules.business.dto.WaypointActionDTO; import com.multictrl.modules.business.dto.WaypointActionDTO;
import com.multictrl.modules.business.entity.RouteAiEntity;
import com.multictrl.modules.business.entity.RouteEntity; import com.multictrl.modules.business.entity.RouteEntity;
import com.multictrl.modules.business.entity.RouteWaypointEntity; import com.multictrl.modules.business.entity.RouteWaypointEntity;
import com.multictrl.modules.business.entity.WaypointActionEntity; import com.multictrl.modules.business.entity.WaypointActionEntity;
@ -42,6 +47,7 @@ public class RouteServiceImpl extends CrudServiceImpl<RouteDao, RouteEntity, Rou
private final RouteWaypointDao routeWaypointDao; private final RouteWaypointDao routeWaypointDao;
private final WaypointActionDao waypointActionDao; private final WaypointActionDao waypointActionDao;
private final MinioService minioService; private final MinioService minioService;
private final RouteAiDao routeAiDao;
@Override @Override
public QueryWrapper<RouteEntity> getWrapper(Map<String, Object> params) { public QueryWrapper<RouteEntity> getWrapper(Map<String, Object> params) {
@ -92,6 +98,17 @@ public class RouteServiceImpl extends CrudServiceImpl<RouteDao, RouteEntity, Rou
//保存航点信息 //保存航点信息
saveWaypoint(routeEntity.getId(), routeWaypointList); saveWaypoint(routeEntity.getId(), routeWaypointList);
//保存AI任务
String zhimouAppId = routeDTO.getZhimouAppId();
String childId = routeDTO.getZhimouChildId();
if (StrUtil.isNotBlank(zhimouAppId) && StrUtil.isNotBlank(childId)) {
RouteAiDTO routeAiDTO = new RouteAiDTO();
routeAiDTO.setRouteId(routeEntity.getId());
routeAiDTO.setZhimouAppId(zhimouAppId);
routeAiDTO.setZhimouChildId(childId);
setRouteAi(routeAiDTO);
}
} }
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@ -127,6 +144,17 @@ public class RouteServiceImpl extends CrudServiceImpl<RouteDao, RouteEntity, Rou
if (StrUtil.isNotBlank(entity.getKmzUrl())) { if (StrUtil.isNotBlank(entity.getKmzUrl())) {
minioService.removeFile(BusinessConstant.ROUTE_KMZ_BUCKET, entity.getKmzUrl().replaceAll(BusinessConstant.ROUTE_KMZ_BUCKET, "")); minioService.removeFile(BusinessConstant.ROUTE_KMZ_BUCKET, entity.getKmzUrl().replaceAll(BusinessConstant.ROUTE_KMZ_BUCKET, ""));
} }
//保存AI任务
String zhimouAppId = routeDTO.getZhimouAppId();
String childId = routeDTO.getZhimouChildId();
if (StrUtil.isNotBlank(zhimouAppId) && StrUtil.isNotBlank(childId)) {
RouteAiDTO routeAiDTO = new RouteAiDTO();
routeAiDTO.setRouteId(routeId);
routeAiDTO.setZhimouAppId(zhimouAppId);
routeAiDTO.setZhimouChildId(childId);
setRouteAi(routeAiDTO);
}
} }
@Override @Override
@ -158,6 +186,24 @@ public class RouteServiceImpl extends CrudServiceImpl<RouteDao, RouteEntity, Rou
} }
} }
@Override
public void setRouteAi(RouteAiDTO routeAi) {
ValidatorUtils.validateEntity(routeAi);
RouteAiEntity routeAiEntity = ConvertUtils.sourceToTarget(routeAi, RouteAiEntity.class);
List<RouteAiEntity> aiEntityList = routeAiDao.selectList(new QueryWrapper<RouteAiEntity>()
.eq("route_id", routeAi.getRouteId()));
if (CollUtil.isNotEmpty(aiEntityList)) {
List<Long> idList = aiEntityList.stream().map(RouteAiEntity::getId).toList();
routeAiDao.deleteByIds(idList);
}
routeAiDao.insert(routeAiEntity);
}
@Override
public void deleteRouteAi(Long routeId) {
routeAiDao.delete(new QueryWrapper<RouteAiEntity>().eq("route_id", routeId));
}
//判断航线是否存在 //判断航线是否存在
private void checkRouteExist(Long id, String routeName) { private void checkRouteExist(Long id, String routeName) {
RouteEntity uavRouteEntity = baseDao.selectOne(new QueryWrapper<RouteEntity>() RouteEntity uavRouteEntity = baseDao.selectOne(new QueryWrapper<RouteEntity>()

View File

@ -479,6 +479,14 @@ public class ZhiMouServiceImpl implements ZhiMouService {
} }
} }
@Override
public boolean hasAiService() {
List<SysParamsEntity> paramList = paramsDao.selectList(new QueryWrapper<SysParamsEntity>()
.in("param_code", zhiMouRequestPara));
return !CollUtil.isEmpty(paramList) && paramList.size() == zhiMouRequestPara.size();
}
private String replaceRtmpIpPort(String originalUrl, String newIp, String newPort) { private String replaceRtmpIpPort(String originalUrl, String newIp, String newPort) {
// 定义RTMP URL的正则表达式模式 // 定义RTMP URL的正则表达式模式
Pattern pattern = Pattern.compile("^rtmp://([^/:]+):([^/]+)(/.*)$"); Pattern pattern = Pattern.compile("^rtmp://([^/:]+):([^/]+)(/.*)$");

View File

@ -2428,3 +2428,37 @@ ON TABLE "public"."bus_weather_nofly" IS '天气阻飞';
-- ---------------------------- -- ----------------------------
ALTER TABLE "public"."bus_weather_nofly" ALTER TABLE "public"."bus_weather_nofly"
ADD CONSTRAINT "uav_hangar_prevent_pkey" PRIMARY KEY ("id"); ADD CONSTRAINT "uav_hangar_prevent_pkey" PRIMARY KEY ("id");
--2026/6/18
-- public.bus_route_ai definition
-- Drop table
-- DROP TABLE public.bus_route_ai;
CREATE TABLE public.bus_route_ai
(
id int8 NOT NULL, -- 主键
route_id int8 NOT NULL, -- 航线编号
zhimou_app_id varchar(128) NOT NULL, -- 知眸应用编号
zhimou_child_id varchar(500) NULL, -- 智眸应用子类编号
creator int8 NOT NULL, -- 创建人
create_date timestamp(6) NOT NULL -- 创建时间
);
COMMENT
ON TABLE public.bus_route_ai IS '航线AI任务';
-- Column comments
COMMENT
ON COLUMN public.bus_route_ai.id IS '主键';
COMMENT
ON COLUMN public.bus_route_ai.route_id IS '航线编号';
COMMENT
ON COLUMN public.bus_route_ai.zhimou_app_id IS '知眸应用编号';
COMMENT
ON COLUMN public.bus_route_ai.creator IS '创建人';
COMMENT
ON COLUMN public.bus_route_ai.create_date IS '创建时间';
COMMENT
ON COLUMN public.bus_route_ai.zhimou_child_id IS '智眸应用子类编号';