zhaowenyu
2025-11-12 0f5b969ddd52ca43ef003867b5a6749d74b7d71d
Merge remote-tracking branch 'origin/dev' into dev
3 files added
35 files modified
1074 ■■■■■ changed files
ard-admin/src/main/java/com/ard/web/controller/route/ArdRouteFolderController.java 7 ●●●●● patch | view | raw | blame | history
ard-admin/src/main/java/com/ard/web/controller/route/ArdRouteInformationController.java 28 ●●●●● patch | view | raw | blame | history
ard-oss/src/main/java/com/ard/oss/service/IOssService.java 16 ●●●●● patch | view | raw | blame | history
ard-oss/src/main/java/com/ard/oss/service/impl/MinIOServiceImpl.java 26 ●●●●● patch | view | raw | blame | history
ard-route/pom.xml 4 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/domain/route/ArdRouteInformation.java 6 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/domain/vo/KmzResultVo.java 7 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/mapper/ArdRouteInformationMapper.java 18 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/service/IArdRouteInformationService.java 18 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/service/UavRouteService.java 8 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/service/impl/ArdRouteFolderServiceImpl.java 15 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/service/impl/ArdRouteInformationServiceImpl.java 94 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/service/impl/UavRouteServiceImpl.java 66 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/util/InitializationUtils.java 8 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/util/RouteFileUtils.java 3 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/util/ToolUtils.java 18 ●●●●● patch | view | raw | blame | history
ard-route/src/main/resources/mapper/ArdRouteFolderMapper.xml 11 ●●●●● patch | view | raw | blame | history
ard-route/src/main/resources/mapper/ArdRouteInformationMapper.xml 27 ●●●●● patch | view | raw | blame | history
ard-system/src/main/java/com/ard/data/map/domain/ArdMap.java 2 ●●●●● patch | view | raw | blame | history
ard-system/src/main/java/com/ard/data/model/domain/ArdModel.java 2 ●●●●● patch | view | raw | blame | history
ard-system/src/main/java/com/ard/data/noflyzone/service/impl/ArdNoFlyZoneServiceImpl.java 2 ●●●●● patch | view | raw | blame | history
ard-system/src/main/java/com/ard/data/noflyzone/utils/NoFlyZoneUtils.java 105 ●●●●● patch | view | raw | blame | history
ard-system/src/main/java/com/ard/data/tile/domain/ArdTile.java 2 ●●●●● patch | view | raw | blame | history
ard-system/src/main/resources/mapper/data/ArdMapMapper.xml 10 ●●●●● patch | view | raw | blame | history
ard-system/src/main/resources/mapper/data/ArdModelMapper.xml 10 ●●●●● patch | view | raw | blame | history
ard-system/src/main/resources/mapper/data/ArdTileMapper.xml 10 ●●●●● patch | view | raw | blame | history
ard-vtdu/src/main/java/com/ard/vtdu/domain/StreamInfo.java 2 ●●●●● patch | view | raw | blame | history
ard-vtdu/src/main/java/com/ard/vtdu/service/impl/ArdArdMediaServiceImpl.java 54 ●●●●● patch | view | raw | blame | history
ard-work/src/main/java/com/ard/work/aspect/UavControlAspect.java 145 ●●●●● patch | view | raw | blame | history
ard-work/src/main/java/com/ard/work/aspect/annotation/CheckControlRight.java 3 ●●●●● patch | view | raw | blame | history
ard-work/src/main/java/com/ard/work/aspect/annotation/CheckDroneStatus.java 15 ●●●●● patch | view | raw | blame | history
ard-work/src/main/java/com/ard/work/aspect/annotation/CheckNoFlyZone.java 14 ●●●●● patch | view | raw | blame | history
ard-work/src/main/java/com/ard/work/aspect/annotation/CheckTakeoffAltitude.java 3 ●●●●● patch | view | raw | blame | history
ard-work/src/main/java/com/ard/work/domain/entity/ArdDroneInfo.java 2 ●●●●● patch | view | raw | blame | history
ard-work/src/main/java/com/ard/work/domain/entity/ArdServerInfo.java 2 ●●●●● patch | view | raw | blame | history
ard-work/src/main/java/com/ard/work/service/impl/TyServiceImpl.java 281 ●●●●● patch | view | raw | blame | history
ard-work/src/main/resources/mapper/ArdDroneInfoMapper.xml 16 ●●●●● patch | view | raw | blame | history
ard-work/src/main/resources/mapper/ArdServerInfoMapper.xml 14 ●●●●● patch | view | raw | blame | history
ard-admin/src/main/java/com/ard/web/controller/route/ArdRouteFolderController.java
@@ -43,7 +43,6 @@
     * 查询分组列表
     */
    @ApiOperation("查询分组列表")
    //@PreAuthorize("@ss.hasPermi('route:folder:list')")
    @GetMapping("/list")
    public TableDataInfo list(ArdRouteFolder ardRouteFolder) {
        //startPage();
@@ -55,7 +54,6 @@
     * 导出分组列表
     */
    @ApiOperation("导出分组列表")
    //@PreAuthorize("@ss.hasPermi('route:folder:export')")
    @Log(title = "分组", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, ArdRouteFolder ardRouteFolder) {
@@ -68,7 +66,6 @@
     * 获取分组详细信息
     */
    @ApiOperation("获取分组详细信息")
    //@PreAuthorize("@ss.hasPermi('route:folder:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") String id) {
        return success(ardRouteFolderService.selectArdRouteFolderById(id));
@@ -78,7 +75,6 @@
     * 新增分组
     */
    @ApiOperation("新增分组")
    //@PreAuthorize("@ss.hasPermi('route:folder:add')")
    @Log(title = "分组", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody ArdRouteFolder ardRouteFolder) {
@@ -90,7 +86,6 @@
     * 修改分组
     */
    @ApiOperation("修改分组")
    //@PreAuthorize("@ss.hasPermi('route:folder:edit')")
    @Log(title = "分组", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody ArdRouteFolder ardRouteFolder) {
@@ -102,7 +97,6 @@
     * 删除分组
     */
    @ApiOperation("删除分组")
    //@PreAuthorize("@ss.hasPermi('route:folder:remove')")
    @Log(title = "分组", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable String[] ids) {
@@ -117,4 +111,5 @@
            return AjaxResult.error(e.getMessage());
        }
    }
}
ard-admin/src/main/java/com/ard/web/controller/route/ArdRouteInformationController.java
@@ -39,7 +39,6 @@
     * 查询航线(kmz)列表
     */
    @ApiOperation("查询航线(kmz)列表")
    //@PreAuthorize("@ss.hasPermi('route:information:list')")
    @GetMapping("/list")
    public TableDataInfo list(ArdRouteInformation ardRouteInformation) {
        startPage();
@@ -51,7 +50,6 @@
     * 导出航线(kmz)列表
     */
    @ApiOperation("导出航线(kmz)列表")
    //@PreAuthorize("@ss.hasPermi('route:information:export')")
    @Log(title = "航线(kmz)", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, ArdRouteInformation ardRouteInformation) {
@@ -64,7 +62,6 @@
     * 获取航线(kmz)详细信息
     */
    @ApiOperation("获取航线(kmz)详细信息")
    //@PreAuthorize("@ss.hasPermi('route:information:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") String id) {
        return success(ardRouteInformationService.selectArdRouteInformationById(id));
@@ -74,7 +71,6 @@
     * 新增航线(kmz)
     */
    @ApiOperation("新增航线(kmz)")
    //@PreAuthorize("@ss.hasPermi('route:information:add')")
    @Log(title = "航线(kmz)", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody ArdRouteInformation ardRouteInformation) {
@@ -86,7 +82,6 @@
     * 修改航线(kmz)
     */
    @ApiOperation("修改航线(kmz)")
    //@PreAuthorize("@ss.hasPermi('route:information:edit')")
    @Log(title = "航线(kmz)", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody ArdRouteInformation ardRouteInformation) {
@@ -98,7 +93,6 @@
     * 删除航线(kmz)
     */
    @ApiOperation("删除航线(kmz)")
    //@PreAuthorize("@ss.hasPermi('route:information:remove')")
    @Log(title = "航线(kmz)", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable String[] ids) {
@@ -109,11 +103,31 @@
     * 导入航线(kmz)文件
     */
    @ApiOperation("导入航线(kmz)文件")
    //@PreAuthorize("@ss.hasPermi('route:information:upload')")
    @PostMapping("/upload")
    public AjaxResult upload(@RequestPart("file") MultipartFile file) {
        MinioUploadResult minioUploadResult = ardRouteInformationService.uploadArdRouteInformation(file);
        return success(minioUploadResult);
    }
    /**
     * 修改航线分组ID
     */
    @ApiOperation("修改航线分组ID")
    @Log(title = "航线(kmz)", businessType = BusinessType.UPDATE)
    @PutMapping("/updateFolderId/{id}/{folderId}")
    public AjaxResult updateFolderId(@PathVariable("id") String id,
                                     @PathVariable("folderId") String folderId) {
        return toAjax(ardRouteInformationService.updateRouteInformationFolderId(id,folderId));
    }
    /**
     * 判断行点是否在禁飞区
     */
    @ApiOperation("判断行点是否在禁飞区")
    @GetMapping("/noFly/{longitude}/{latitude}")
    public Boolean noFly(@PathVariable("longitude") Double longitude,
                               @PathVariable("latitude") Double latitude) {
        return ardRouteInformationService.selectRouteInformationNoFly(longitude,latitude);
    }
}
ard-oss/src/main/java/com/ard/oss/service/IOssService.java
@@ -12,14 +12,14 @@
 */
public interface IOssService {
    String getOssType();
    public String getOssType();
    /**
     * Get temporary credentials.
     *
     * @return
     */
    CredentialsDTO getCredentials();
    public CredentialsDTO getCredentials();
    /**
     * Get the address of the object based on the bucket name and the object name.
@@ -28,7 +28,7 @@
     * @param objectKey object name
     * @return download link
     */
    URL getObjectUrl(String bucket, String objectKey);
    public URL getObjectUrl(String bucket, String objectKey);
    /**
     * Deletes the object in the storage bucket.
@@ -37,7 +37,7 @@
     * @param objectKey
     * @return
     */
    Boolean deleteObject(String bucket, String objectKey);
    public Boolean deleteObject(String bucket, String objectKey);
    /**
     * Get the contents of an object.
@@ -46,12 +46,12 @@
     * @param objectKey
     * @return
     */
    InputStream getObject(String bucket, String objectKey);
    public InputStream getObject(String bucket, String objectKey);
    void putObject(String bucket, String objectKey, InputStream input);
    public void putObject(String bucket, String objectKey, InputStream input);
    void putObject(String bucket, String objectKey, InputStream input, String contentType);
    public void putObject(String bucket, String objectKey, InputStream input, String contentType);
    void createClient();
    public void createClient();
}
ard-oss/src/main/java/com/ard/oss/service/impl/MinIOServiceImpl.java
@@ -127,7 +127,10 @@
    @Override
    public Boolean deleteObject(String bucket, String objectKey) {
        try {
            client.removeObject(RemoveObjectArgs.builder().bucket(bucket).object(objectKey).build());
            client.removeObject(RemoveObjectArgs.builder()
                    .bucket(bucket)
                    .object(objectKey)
                    .build());
        } catch (MinioException | NoSuchAlgorithmException | IOException | InvalidKeyException e) {
            log.error("Failed to delete file.");
            e.printStackTrace();
@@ -139,7 +142,10 @@
    @Override
    public InputStream getObject(String bucket, String objectKey) {
        try {
            GetObjectResponse object = client.getObject(GetObjectArgs.builder().bucket(bucket).object(objectKey).build());
            GetObjectResponse object = client.getObject(GetObjectArgs.builder()
                    .bucket(bucket)
                    .object(objectKey)
                    .build());
            return new ByteArrayInputStream(object.readAllBytes());
        } catch (ErrorResponseException | InsufficientDataException | InternalException | InvalidKeyException | InvalidResponseException | IOException | NoSuchAlgorithmException | ServerException | XmlParserException e) {
            e.printStackTrace();
@@ -150,7 +156,10 @@
    @Override
    public void putObject(String bucket, String objectKey, InputStream input) {
        try {
            client.statObject(StatObjectArgs.builder().bucket(bucket).object(objectKey).build());
            client.statObject(StatObjectArgs.builder()
                    .bucket(bucket)
                    .object(objectKey)
                    .build());
            throw new RuntimeException("The filename already exists.");
        } catch (MinioException | InvalidKeyException | IOException | NoSuchAlgorithmException e) {
            log.info("The file does not exist, start uploading.");
@@ -158,7 +167,11 @@
                // 设置 partSize 为 10MB
                long partSize = 10 * 1024 * 1024;
                ObjectWriteResponse response = client.putObject(
                        PutObjectArgs.builder().bucket(bucket).object(objectKey).stream(input, -1, partSize).build());
                        PutObjectArgs.builder()
                                .bucket(bucket)
                                .object(objectKey)
                                .stream(input, -1, partSize)
                                .build());
                log.info("Upload File: {}", response.etag());
            } catch (MinioException | IOException | InvalidKeyException | NoSuchAlgorithmException ex) {
                log.error("Failed to upload File {}.", objectKey);
@@ -170,7 +183,10 @@
    public void putObject(String bucket, String objectKey, InputStream input, String contentType) {
        try {
            // 检查文件是否已经存在
            client.statObject(StatObjectArgs.builder().bucket(bucket).object(objectKey).build());
            client.statObject(StatObjectArgs.builder()
                    .bucket(bucket)
                    .object(objectKey)
                    .build());
            throw new RuntimeException("The file already exists: " + objectKey);
        } catch (ErrorResponseException e) {
            // 如果文件不存在,则继续上传
ard-route/pom.xml
@@ -51,6 +51,10 @@
            <groupId>com.ard</groupId>
            <artifactId>ard-oss</artifactId>
        </dependency>
        <dependency>
            <groupId>com.ard</groupId>
            <artifactId>ard-system</artifactId>
        </dependency>
    </dependencies>
ard-route/src/main/java/com/ard/route/domain/route/ArdRouteInformation.java
@@ -42,6 +42,9 @@
    /** 分组ID */
    private String folderId;
    /** 航线类型 */
    private String routeType;
    /** 飞行器 */
    private String aircraft;
@@ -53,4 +56,7 @@
     */
    private UavRouteReq uavRouteReq;
    /** 航线数据 */
    private byte[] routeData;
}
ard-route/src/main/java/com/ard/route/domain/vo/KmzResultVo.java
@@ -5,12 +5,19 @@
@Data
public class KmzResultVo {
    /** 新文件名称 */
    private String fileNameNew;
    /** Minio文件路径 */
    private String minioUpPath;
    /** 文件路径 */
    private String upPath;
    /** 文件大小 */
    private Double upFileSize;
    /** 返回数据 */
    private String data;
}
ard-route/src/main/java/com/ard/route/mapper/ArdRouteInformationMapper.java
@@ -1,6 +1,7 @@
package com.ard.route.mapper;
import com.ard.route.domain.route.ArdRouteInformation;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@@ -76,4 +77,21 @@
     */
    public int deleteRouteInformationByFolderIds(String[] folderIds);
    /**
     * 查询航线(kmz)列表
     *
     * @param folderId 所属文件夹ID
     * @return 航线(kmz)集合
     */
    public List<ArdRouteInformation> selectArdRouteInformationByFolderId(String folderId);
    /**
     * 修改航线分组ID
     *
     * @param id ID
     * @param folderId 分组ID
     * @return 结果
     */
    public int updateRouteInformationFolderId(@Param("id") String id, @Param("folderId")String folderId);
}
ard-route/src/main/java/com/ard/route/service/IArdRouteInformationService.java
@@ -78,4 +78,22 @@
     */
    public ArdRouteInformation selectArdRouteInformationByName(String name);
    /**
     * 修改航线分组ID
     *
     * @param id ID
     * @param folderId 分组ID
     * @return 结果
     */
    public int updateRouteInformationFolderId(String id,String folderId);
    /**
     * 判断行点是否在禁飞区
     *
     * @param longitude 经度
     * @param latitude 纬度
     * @return 结果
     */
    public Boolean selectRouteInformationNoFly(Double longitude, Double latitude);
}
ard-route/src/main/java/com/ard/route/service/UavRouteService.java
@@ -12,7 +12,7 @@
    /**
     * 编辑kmz文件
     */
    public String updateKmz(UavRouteReq uavRouteReq,String fileName);
    public KmzResultVo updateKmz(UavRouteReq uavRouteReq,String fileName);
    /**
     * 生成kmz文件(带航点)
@@ -24,4 +24,10 @@
     */
    public KmzInfoVO parseKmz(String file);
    /**
     * 编辑kmz文件
     * 定制:删除旧的文件名的文件,并添加新文件名的文件
     */
    public KmzResultVo updateKmzNew(UavRouteReq uavRouteReq, String oldFileName, String newFilePath) ;
}
ard-route/src/main/java/com/ard/route/service/impl/ArdRouteFolderServiceImpl.java
@@ -43,9 +43,7 @@
    @Override
    public ArdRouteFolder selectArdRouteFolderById(String id) {
        ArdRouteFolder ardRouteFolder = ardRouteFolderMapper.selectArdRouteFolderById(id);
        ArdRouteInformation ardRouteInformation = new ArdRouteInformation();
        ardRouteInformation.setFolderId(id);
        ardRouteFolder.setArdRouteInformationLs(ardRouteInformationMapper.selectArdRouteInformationList(ardRouteInformation));
        ardRouteFolder.setArdRouteInformationLs(ardRouteInformationMapper.selectArdRouteInformationByFolderId(id));
        return ardRouteFolder;
    }
@@ -60,18 +58,9 @@
    public List<ArdRouteFolder> selectArdRouteFolderList(ArdRouteFolder ardRouteFolder) {
        List<ArdRouteFolder> list = ardRouteFolderMapper.selectArdRouteFolderList(ardRouteFolder);
        for (ArdRouteFolder routeFolder : list) {
            routeFolder.setArdRouteInformationLs(getArdRouteInformation(routeFolder.getId()));
            routeFolder.setArdRouteInformationLs(ardRouteInformationMapper.selectArdRouteInformationByFolderId(routeFolder.getId()));
        }
        return list;
    }
    /**
     * 查询文件列表
     */
    private List<ArdRouteInformation> getArdRouteInformation(String folderId) {
        ArdRouteInformation ardRouteInformation = new ArdRouteInformation();
        ardRouteInformation.setFolderId(folderId);
        return ardRouteInformationMapper.selectArdRouteInformationList(ardRouteInformation);
    }
    /**
ard-route/src/main/java/com/ard/route/service/impl/ArdRouteInformationServiceImpl.java
@@ -1,11 +1,19 @@
package com.ard.route.service.impl;
import java.io.IOException;
import java.util.List;
import com.ard.common.exception.ControlException;
import com.ard.common.utils.DateUtils;
import com.ard.common.utils.file.FileUtils;
import com.ard.common.utils.uuid.IdUtils;
import com.ard.data.noflyzone.domain.ArdNoFlyZone;
import com.ard.data.noflyzone.domain.Vertex;
import com.ard.data.noflyzone.service.IArdNoFlyZoneService;
import com.ard.data.noflyzone.utils.NoFlyZoneUtils;
import com.ard.oss.model.MinioUploadResult;
import com.ard.oss.service.impl.OssServiceContext;
import com.ard.route.domain.UavRouteReq;
import com.ard.route.domain.route.ArdRouteInformation;
import com.ard.route.domain.vo.KmzResultVo;
import com.ard.route.service.UavRouteService;
@@ -17,8 +25,7 @@
import javax.annotation.Resource;
import static com.ard.route.util.ToolUtils.extractFilePath;
import static com.ard.route.util.ToolUtils.getFileNameWithoutExtension;
import static com.ard.route.util.ToolUtils.*;
/**
 * 航线(kmz)Service业务层处理
@@ -38,6 +45,9 @@
    @Autowired
    private UavRouteService routeService;
    @Resource
    private IArdNoFlyZoneService ardNoFlyZoneService;
    /**
     * 查询航线(kmz)
     * 
@@ -46,7 +56,13 @@
     */
    @Override
    public ArdRouteInformation selectArdRouteInformationById(String id) {
        return ardRouteInformationMapper.selectArdRouteInformationById(id);
        ArdRouteInformation ardRouteInformation = ardRouteInformationMapper.selectArdRouteInformationById(id);
        try {
            ardRouteInformation.setUavRouteReq((UavRouteReq) deserialize(ardRouteInformation.getRouteData()));
        } catch (IOException | ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
        return ardRouteInformation;
    }
    /**
@@ -73,13 +89,16 @@
        if (ardRouteInformation.getFolderId() == null){
            ardRouteInformation.setFolderId("0");
        }
        // 航线数据
        byte[] routeData;
        try {
            routeData = serialize(ardRouteInformation.getUavRouteReq());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        ardRouteInformation.setRouteData(routeData);
        KmzResultVo kmzResult = routeService.buildKmz(ardRouteInformation.getUavRouteReq(), ardRouteInformation.getFileName());
        // 将KmzResult中的信息设置到ardRouteInformation中
        ardRouteInformation.setFileNameNew(kmzResult.getFileNameNew());
        ardRouteInformation.setMinioUpPath(kmzResult.getMinioUpPath());
        ardRouteInformation.setUpPath(kmzResult.getUpPath());
        ardRouteInformation.setUpFileSize(kmzResult.getUpFileSize());
        ardRouteInformationMapper.insertArdRouteInformation(ardRouteInformation);
        ardRouteInformationMapper.insertArdRouteInformation(assembly(ardRouteInformation,kmzResult));
        return kmzResult.getUpPath();
    }
@@ -92,7 +111,27 @@
    @Override
    public int updateArdRouteInformation(ArdRouteInformation ardRouteInformation) {
        ardRouteInformation.setUpdateTime(DateUtils.getNowDate());
        return ardRouteInformationMapper.updateArdRouteInformation(ardRouteInformation);
        KmzResultVo kmzResult = new KmzResultVo();
        // 获取源文件名字
        ArdRouteInformation route = ardRouteInformationMapper.selectArdRouteInformationById(ardRouteInformation.getId());
        if (route.getFileName().equals(ardRouteInformation.getFileName())) {
            kmzResult = routeService.updateKmz(ardRouteInformation.getUavRouteReq(), ardRouteInformation.getFileName());
        }else {
            kmzResult = routeService.updateKmzNew(ardRouteInformation.getUavRouteReq(), route.getFileName(),ardRouteInformation.getFileName());
        }
        if ("更新航线kmz文件失败".equals(kmzResult.getData())) {
            return 0;
        }
        return ardRouteInformationMapper.updateArdRouteInformation(assembly(ardRouteInformation,kmzResult));
    }
    //组装数据
    private ArdRouteInformation assembly(ArdRouteInformation information,KmzResultVo kmzResult){
        information.setFileNameNew(kmzResult.getFileNameNew());
        information.setMinioUpPath(kmzResult.getMinioUpPath());
        information.setUpPath(kmzResult.getUpPath());
        information.setUpFileSize(kmzResult.getUpFileSize());
        return information;
    }
    /**
@@ -161,6 +200,41 @@
    }
    /**
     * 修改航线分组ID
     *
     * @param id ID
     * @param folderId 分组ID
     * @return 结果
     */
    @Override
    public int updateRouteInformationFolderId(String id, String folderId) {
        return ardRouteInformationMapper.updateRouteInformationFolderId(id, folderId);
    }
    /**
     * 判断行点是否在禁飞区
     *
     * @param longitude 经度
     * @param latitude 纬度
     * @return 结果
     */
    @Override
    public Boolean selectRouteInformationNoFly(Double longitude, Double latitude) {
        if (longitude == null || latitude == null) {
            throw new ControlException("方法参数中未找到有效经纬度字段,无法判断禁飞区!");
        }
        List<ArdNoFlyZone> ardNoFlyZones = ardNoFlyZoneService.selectArdNoFlyZoneList(new ArdNoFlyZone());
        if (!ardNoFlyZones.isEmpty()) {
            Vertex vertex = new Vertex(longitude, latitude);
            boolean inNoFlyZones = NoFlyZoneUtils.isInNoFlyZones(vertex, ardNoFlyZones);
            if (inNoFlyZones) {
                throw new ControlException("目标点在禁飞区内,无法执行操作!");
            }
        }
        return true;
    }
    /**
     * 数据新增航线信息
     */
    private void insertRouteInformation(ArdRouteInformation ardRouteInformation){
ard-route/src/main/java/com/ard/route/service/impl/UavRouteServiceImpl.java
@@ -61,12 +61,15 @@
     * 编辑kmz文件
     */
    @Override
    public String updateKmz(UavRouteReq uavRouteReq,String fileName){
    public KmzResultVo updateKmz(UavRouteReq uavRouteReq,String fileName){
        KmzResultVo result = new KmzResultVo();
        // 校验修改的文件是否存在
        ArdRouteInformation routeInformation = ardRouteInformationService.selectArdRouteInformationByName(fileName);
        if ( routeInformation == null ){
            return "修改航线文件失败,请检查文件是否存在";
            result.setData("修改航线文件失败,请检查文件是否存在");
            return result;
        }
        // 获取文件
        String minioUrl = routeInformation.getMinioUpPath();
        try (InputStream inputStream = ossService.getObject(kmzPath,minioUrl);
@@ -86,13 +89,13 @@
                    this.handleRouteUpdate(wpmlInfo, uavRouteReq, FileTypeConstants.WPML, kmlParams);
                }
            }
            // 删除minio的文件
            // 插入修改好的minio文件
            return RouteFileUtils.buildKmz("更新航线kmz文件111111", kmlInfo, wpmlInfo, kmzPath);
            // 删除文件
            ossService.deleteObject(kmzPath, minioUrl);
            return buildKmzMethod(routeInformation.getFileName(), kmlInfo, wpmlInfo);
        } catch (Exception e) {
            return "更新航线kmz文件失败";
            e.printStackTrace();
            result.setData("更新航线kmz文件失败");
            return result;
        }
    }
@@ -160,7 +163,7 @@
    public KmzResultVo buildKmz(String fileName, KmlParams kmlParams) {
        KmlInfo kmlInfo = buildKml(kmlParams);
        KmlInfo wpmlInfo = buildWpml(kmlParams);
        return buildKmz(fileName, kmlInfo, wpmlInfo);
        return buildKmzMethod(fileName, kmlInfo, wpmlInfo);
    }
    /**
@@ -171,7 +174,7 @@
     * @param wpmlInfo wpml 文件信息
     * @return 本地文件路径
     */
    public KmzResultVo buildKmz(String fileName, KmlInfo kmlInfo, KmlInfo wpmlInfo) {
    public KmzResultVo buildKmzMethod(String fileName, KmlInfo kmlInfo, KmlInfo wpmlInfo) {
        XStream xStream = new XStream(new DomDriver());
        xStream.processAnnotations(KmlInfo.class);
        xStream.addImplicitCollection(KmlActionGroup.class, "action");
@@ -202,8 +205,10 @@
                 ZipOutputStream zipOutputStream = new ZipOutputStream(baos)) {
                zipOutputStream.setLevel(0);
                // 创建KMZ文件内容
                // 创建 wpmz 目录中的 template.kml 文件条目
                buildZipFile("wpmz/template.kml", zipOutputStream, kml);
                // 创建 wpmz 目录中的 waylines.wpml 文件条目
                buildZipFile("wpmz/waylines.wpml", zipOutputStream, wpml);
                zipOutputStream.finish();
@@ -254,4 +259,43 @@
        }
        return null;
    }
    @Override
    public KmzResultVo updateKmzNew(UavRouteReq uavRouteReq, String oldFile, String newFile) {
        KmzResultVo result = new KmzResultVo();
        // 校验修改的文件是否存在
        ArdRouteInformation routeInformation = ardRouteInformationService.selectArdRouteInformationByName(oldFile);
        if ( routeInformation == null ){
            result.setData("修改航线文件失败,请检查文件是否存在");
            return result;
        }
        // 获取文件
        String minioUrl = routeInformation.getMinioUpPath();
        try (InputStream inputStream = ossService.getObject(kmzPath,minioUrl);
             ArchiveInputStream archiveInputStream = new ZipArchiveInputStream(inputStream)){
            ArchiveEntry entry;
            KmlInfo kmlInfo = new KmlInfo();
            KmlInfo wpmlInfo = new KmlInfo();
            KmlParams kmlParams = new KmlParams();
            while (!Objects.isNull(entry = archiveInputStream.getNextEntry())) {
                String name = entry.getName();
                if (name.toLowerCase().endsWith(".kml")) {
                    kmlInfo = RouteFileUtils.parseKml(archiveInputStream);
                    buildKmlParams(kmlParams, kmlInfo);
                    this.handleRouteUpdate(kmlInfo, uavRouteReq, FileTypeConstants.KML, kmlParams);
                } else if (name.toLowerCase().endsWith(".wpml")) {
                    wpmlInfo = RouteFileUtils.parseKml(archiveInputStream);
                    this.handleRouteUpdate(wpmlInfo, uavRouteReq, FileTypeConstants.WPML, kmlParams);
                }
            }
            // 删除文件
            ossService.deleteObject(kmzPath, minioUrl);
            return buildKmzMethod(newFile, kmlInfo, wpmlInfo);
        } catch (Exception e) {
            result.setData("更新航线kmz文件失败");
            return result;
        }
    }
}
ard-route/src/main/java/com/ard/route/util/InitializationUtils.java
@@ -17,9 +17,11 @@
    public UavRouteReq initialization(UavRouteReq uavRouteReq){
        uavRouteReq.setTemplateType("waypoint");
        // 起始点默认航线第一个点
        uavRouteReq.setTakeOffRefPoint(
                uavRouteReq.getRoutePointList().get(0).getLatitude() + "," +
                        uavRouteReq.getRoutePointList().get(0).getLongitude() + "," + "0");
        if (uavRouteReq.getTakeOffRefPoint().isEmpty()){
            uavRouteReq.setTakeOffRefPoint(
                    uavRouteReq.getRoutePointList().get(0).getLatitude() + "," +
                            uavRouteReq.getRoutePointList().get(0).getLongitude() + "," + "0");
        }
        //uavRouteReq.setDroneType(89);
        uavRouteReq.setSubDroneType(0);
        uavRouteReq.setPayloadType(43);
ard-route/src/main/java/com/ard/route/util/RouteFileUtils.java
@@ -53,10 +53,11 @@
     * @param wpmlInfo wpml 文件信息
     * @return 本地文件路径
     */
    public static String buildKmz(String fileName, KmlInfo kmlInfo, KmlInfo wpmlInfo, String kmzFilePath) {
    public static String buildKmzA(String fileName, KmlInfo kmlInfo, KmlInfo wpmlInfo, String kmzFilePath) {
        XStream xStream = new XStream(new DomDriver());
        xStream.processAnnotations(KmlInfo.class);
        xStream.addImplicitCollection(KmlActionGroup.class, "action");
        xStream.addImplicitCollection(KmlPlacemark.class, "actionGroup");
        String kml = XML_HEADER + xStream.toXML(kmlInfo);
        String wpml = XML_HEADER + xStream.toXML(wpmlInfo);
ard-route/src/main/java/com/ard/route/util/ToolUtils.java
@@ -1,5 +1,6 @@
package com.ard.route.util;
import java.io.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
@@ -85,4 +86,21 @@
        return "";
    }
    // 对象序列化为字节数组
    public static byte[] serialize(Object obj) throws IOException {
        try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
             ObjectOutputStream oos = new ObjectOutputStream(baos)) {
            oos.writeObject(obj);
            return baos.toByteArray();
        }
    }
    // 字节数组反序列化为对象
    public static Object deserialize(byte[] data) throws IOException, ClassNotFoundException {
        try (ByteArrayInputStream bais = new ByteArrayInputStream(data);
             ObjectInputStream ois = new ObjectInputStream(bais)) {
            return ois.readObject();
        }
    }
}
ard-route/src/main/resources/mapper/ArdRouteFolderMapper.xml
@@ -12,18 +12,7 @@
        <result property="createTime"    column="create_time"    />
        <result property="updateBy"    column="update_by"    />
        <result property="updateTime"    column="update_time"    />
        <!-- 关联 ArdRouteFile 对象 -->
        <association property="ardRouteFile"
                     javaType="com.ard.route.domain.route.ArdRouteFile"
                     column="folder_id"
                     autoMapping="true"
                     select="selectArdRouteFile">
        </association>
    </resultMap>
    <select id="selectArdRouteFile" resultType="com.ard.route.domain.route.ArdRouteFile">
        select * from ard_route_file where id = #{folderId}
    </select>
    <sql id="selectArdRouteFolderVo">
        select id,
ard-route/src/main/resources/mapper/ArdRouteInformationMapper.xml
@@ -12,8 +12,10 @@
        <result property="minioUpPath"    column="minio_up_path"    />
        <result property="upFileSize"    column="up_file_size"    />
        <result property="folderId"    column="folder_id"    />
        <result property="routeType"    column="route_type"    />
        <result property="aircraft"    column="aircraft"    />
        <result property="aircraftModel"    column="aircraft_model"    />
        <result property="routeData"    column="route_data"    />
        <result property="createBy"    column="create_by"    />
        <result property="createTime"    column="create_time"    />
        <result property="updateBy"    column="update_by"    />
@@ -28,8 +30,10 @@
               minio_up_path,
               up_file_size,
               folder_id,
               route_type,
               aircraft,
               aircraft_model,
               route_data,
               create_by,
               create_time,
               update_by,
@@ -41,6 +45,9 @@
        <include refid="selectArdRouteInformationVo"/>
        <where>  
            <if test="fileName != null  and fileName != ''"> and file_name like concat('%', #{fileName}, '%')</if>
            <if test="aircraft != null  and aircraft != ''"> and aircraft = #{aircraft}</if>
            <if test="aircraftModel != null  and aircraftModel != ''"> and aircraft_model = #{aircraftModel}</if>
            <if test="routeType != null  and routeType != ''"> and route_type = #{routeType}</if>
            <if test="upPath != null  and upPath != ''"> and up_path = #{upPath}</if>
            <if test="upFileSize != null "> and up_file_size = #{upFileSize}</if>
        </where>
@@ -61,8 +68,10 @@
            <if test="minioUpPath != null">minio_up_path,</if>
            <if test="upFileSize != null">up_file_size,</if>
            <if test="folderId != null">folder_id,</if>
            <if test="routeType != null">route_type,</if>
            <if test="aircraft != null">aircraft,</if>
            <if test="aircraftModel != null">aircraft_model,</if>
            <if test="routeData != null">route_data,</if>
            <if test="createBy != null">create_by,</if>
            <if test="createTime != null">create_time,</if>
            <if test="updateBy != null">update_by,</if>
@@ -76,8 +85,10 @@
            <if test="minioUpPath != null">#{minioUpPath},</if>
            <if test="upFileSize != null">#{upFileSize},</if>
            <if test="folderId != null">#{folderId},</if>
            <if test="routeType != null">#{routeType},</if>
            <if test="aircraft != null">#{aircraft},</if>
            <if test="aircraftModel != null">#{aircraftModel},</if>
            <if test="routeData != null">#{routeData},</if>
            <if test="createBy != null">#{createBy},</if>
            <if test="createTime != null">#{createTime},</if>
            <if test="updateBy != null">#{updateBy},</if>
@@ -94,6 +105,7 @@
            <if test="minioUpPath != null">minio_up_path = #{minioUpPath},</if>
            <if test="upFileSize != null">up_file_size = #{upFileSize},</if>
            <if test="folderId != null">folder_id = #{folderId},</if>
            <if test="routeType != null">route_type = #{routeType},</if>
            <if test="aircraft != null">aircraft = #{aircraft},</if>
            <if test="aircraftModel != null">aircraft_model = #{aircraftModel},</if>
            <if test="createBy != null">create_by = #{createBy},</if>
@@ -127,4 +139,19 @@
        </foreach>
    </delete>
    <select id="selectArdRouteInformationByFolderId" parameterType="String" resultMap="ArdRouteInformationResult">
        <include refid="selectArdRouteInformationVo"/>
        <where>
            <if test="folderId != null "> and folder_id = #{folderId}</if>
        </where>
    </select>
    <update id="updateRouteInformationFolderId">
        update ard_route_information
        <trim prefix="SET" suffixOverrides=",">
            <if test="folderId != null">folder_id = #{folderId},</if>
        </trim>
        where id = #{id}
    </update>
</mapper>
ard-system/src/main/java/com/ard/data/map/domain/ArdMap.java
@@ -5,7 +5,7 @@
import lombok.Data;
/**
 * 地图管理对象 ard_map_management
 * 地图管理对象 ard_map
 * 
 * @author xia
 * @date 2025-10-10
ard-system/src/main/java/com/ard/data/model/domain/ArdModel.java
@@ -5,7 +5,7 @@
import lombok.Data;
/**
 * 模型管理对象 ard_model_management
 * 模型管理对象 ard_model
 * 
 * @author xia
 * @date 2025-10-10
ard-system/src/main/java/com/ard/data/noflyzone/service/impl/ArdNoFlyZoneServiceImpl.java
@@ -100,4 +100,6 @@
    {
        return ardNoFlyZoneMapper.deleteArdNoFlyZoneById(id);
    }
}
ard-system/src/main/java/com/ard/data/noflyzone/utils/NoFlyZoneUtils.java
New file
@@ -0,0 +1,105 @@
package com.ard.data.noflyzone.utils;
import com.ard.data.noflyzone.domain.ArdNoFlyBox;
import com.ard.data.noflyzone.domain.ArdNoFlyZone;
import com.ard.data.noflyzone.domain.Vertex;
import java.util.List;
public class NoFlyZoneUtils {
    /**
     * 判断点是否在禁飞区集合中
     *
     * @param point   目标点
     * @param zones   禁飞区集合
     * @return true: 点在任意禁飞区内
     */
    public static boolean isInNoFlyZones(Vertex point, List<ArdNoFlyZone> zones) {
        if (point == null || zones == null || zones.isEmpty()) {
            return false;
        }
        for (ArdNoFlyZone zone : zones) {
            // 1️⃣ 先快速判断外接矩形
            if (zone.getArdNoFlyBox() != null &&
                !isInBox(point, zone.getArdNoFlyBox())) {
                continue; // 点不在外接矩形内,跳过
            }
            // 2️⃣ 多边形判断
            List<Vertex> vertices = zone.getVertices();
            if (vertices != null && !vertices.isEmpty()) {
                if (isPointInPolygon(point, vertices)) {
                    return true;
                }
            }
        }
        return false;
    }
    /**
     * 判断点是否在矩形框内
     */
    private static boolean isInBox(Vertex point, ArdNoFlyBox box) {
        return point.x >= box.getMinx() && point.x <= box.getMaxx() &&
               point.y >= box.getMiny() && point.y <= box.getMaxy();
    }
    /**
     * 射线法判断点是否在多边形内
     */
    private static boolean isPointInPolygon(Vertex point, List<Vertex> vertices) {
        if (point == null || vertices == null || vertices.size() < 3) {
            return false;
        }
        int count = 0;
        int n = vertices.size();
        double epsilon = 1e-9;
        for (int i = 0; i < n; i++) {
            Vertex v1 = vertices.get(i);
            Vertex v2 = vertices.get((i + 1) % n);
            // 点就是顶点
            if (v1.IsSame(point)) {
                return true;
            }
            double minX = Math.min(v1.x, v2.x);
            double maxX = Math.max(v1.x, v2.x);
            double minY = Math.min(v1.y, v2.y);
            double maxY = Math.max(v1.y, v2.y);
            // 水平线段
            if (Math.abs(minY - maxY) < epsilon) {
                if (Math.abs(point.y - minY) < epsilon && point.x >= minX && point.x <= maxX) {
                    return true;
                } else {
                    continue;
                }
            }
            // 点不在纵向范围
            if (point.y < minY || point.y > maxY) {
                continue;
            }
            double xIntersect = v1.x + (point.y - v1.y) * (v2.x - v1.x) / (v2.y - v1.y);
            if (Math.abs(xIntersect - point.x) < epsilon) {
                return true; // 点在边界
            }
            if (xIntersect > point.x) {
                count++;
            }
            if (Math.abs(point.y - minY) < epsilon) {
                count--;
            }
        }
        return count % 2 != 0;
    }
}
ard-system/src/main/java/com/ard/data/tile/domain/ArdTile.java
@@ -5,7 +5,7 @@
import lombok.Data;
/**
 * tile管理对象 ard_tile_management
 * tile管理对象 ard_tile
 * 
 * @author xia
 * @date 2025-10-10
ard-system/src/main/resources/mapper/data/ArdMapMapper.xml
@@ -22,7 +22,7 @@
               release_status,
               default_loading,
               map_path
        from ard_map_management
        from ard_map
    </sql>
    <select id="selectArdMapList" parameterType="ArdMap" resultMap="ArdMapResult">
@@ -41,7 +41,7 @@
    </select>
    <insert id="insertArdMap" parameterType="ArdMap">
        insert into ard_map_management
        insert into ard_map
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="id != null">id,</if>
            <if test="mapName != null">map_name,</if>
@@ -63,7 +63,7 @@
    </insert>
    <update id="updateArdMap" parameterType="ArdMap">
        update ard_map_management
        update ard_map
        <trim prefix="SET" suffixOverrides=",">
            <if test="mapName != null">map_name = #{mapName},</if>
            <if test="mapType != null">map_type = #{mapType},</if>
@@ -76,11 +76,11 @@
    </update>
    <delete id="deleteArdMapById" parameterType="String">
        delete from ard_map_management where id = #{id}
        delete from ard_map where id = #{id}
    </delete>
    <delete id="deleteArdMapByIds" parameterType="String">
        delete from ard_map_management where id in
        delete from ard_map where id in
        <foreach item="id" collection="array" open="(" separator="," close=")">
            #{id}
        </foreach>
ard-system/src/main/resources/mapper/data/ArdModelMapper.xml
@@ -22,7 +22,7 @@
               height,
               proportion,
               model_url
        from ard_model_management
        from ard_model
    </sql>
    <select id="selectArdModelList" parameterType="ArdModel" resultMap="ArdModelResult">
@@ -43,7 +43,7 @@
    </select>
    <insert id="insertArdModel" parameterType="ArdModel">
        insert into ard_model_management
        insert into ard_model
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="id != null">id,</if>
            <if test="modelName != null">model_name,</if>
@@ -65,7 +65,7 @@
    </insert>
    <update id="updateArdModel" parameterType="ArdModel">
        update ard_model_management
        update ard_model
        <trim prefix="SET" suffixOverrides=",">
            <if test="modelName != null">model_name = #{modelName},</if>
            <if test="longitude != null">longitude = #{longitude},</if>
@@ -78,11 +78,11 @@
    </update>
    <delete id="deleteArdModelById" parameterType="String">
        delete from ard_model_management where id = #{id}
        delete from ard_model where id = #{id}
    </delete>
    <delete id="deleteArdModelByIds" parameterType="String">
        delete from ard_model_management where id in
        delete from ard_model where id in
        <foreach item="id" collection="array" open="(" separator="," close=")">
            #{id}
        </foreach>
ard-system/src/main/resources/mapper/data/ArdTileMapper.xml
@@ -30,7 +30,7 @@
               user_id,
               dept_id,
               default_loading
        from ard_tile_management
        from ard_tile
    </sql>
    <select id="selectArdTileList" parameterType="ArdTile" resultMap="ArdTileResult">
@@ -48,7 +48,7 @@
    </select>
    <insert id="insertArdTile" parameterType="ArdTile">
        insert into ard_tile_management
        insert into ard_tile
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="id != null">id,</if>
            <if test="tilesName != null">tiles_name,</if>
@@ -78,7 +78,7 @@
    </insert>
    <update id="updateArdTile" parameterType="ArdTile">
        update ard_tile_management
        update ard_tile
        <trim prefix="SET" suffixOverrides=",">
            <if test="tilesName != null">tiles_name = #{tilesName},</if>
            <if test="tilesHeight != null">tiles_height = #{tilesHeight},</if>
@@ -95,11 +95,11 @@
    </update>
    <delete id="deleteArdTileById" parameterType="String">
        delete from ard_tile_management where id = #{id}
        delete from ard_tile where id = #{id}
    </delete>
    <delete id="deleteArdTileByIds" parameterType="String">
        delete from ard_tile_management where id in
        delete from ard_tile where id in
        <foreach item="id" collection="array" open="(" separator="," close=")">
            #{id}
        </foreach>
ard-vtdu/src/main/java/com/ard/vtdu/domain/StreamInfo.java
@@ -25,7 +25,7 @@
     */
    String name;
    /**
     * 源rtsp地址
     * 源
     */
    String rtspSource;
    /**
ard-vtdu/src/main/java/com/ard/vtdu/service/impl/ArdArdMediaServiceImpl.java
@@ -196,6 +196,8 @@
            String name = item.getName();
            info.setName(name);
            Conf conf = mediaClient.getPathConfig(name);
            //源
            info.setRtspSource(conf.getSource());
            //RTMP播放地址
            String rtmpUrl = "rtmp://" + mediamtxConfig.getPlayHost() + ":1935/" + name;
            info.setRtmpUrl(rtmpUrl);
@@ -206,51 +208,21 @@
            String protocol = mediamtxConfig.isHttps() ? "https://" : "http://";
            String webrtcUrl = protocol + mediamtxConfig.getPlayHost() + ":8889/" + name;
            info.setWebrtcUrl(webrtcUrl);
            Source source = item.getSource();
            if (source == null || source.getId().equals("")) {
                //会话ID
                info.setId("0");
                //下行流量
                long bytesReceived = item.getBytesReceived();
                String formatReceivedSize = ArdTool.formatFileSize(bytesReceived);
                info.setDownTraffic(formatReceivedSize);
                //上行流量
                long bytesSent = item.getBytesSent();
                String formatSentdSize = ArdTool.formatFileSize(bytesSent);
                info.setUpTraffic(formatSentdSize);
                info.setBeginTime(item.getReadyTime());
            } else {
                RtspSession rtspSession = getRtspSessionById(source.getId());
                //会话ID
                info.setId(rtspSession.getId());
                //开始推流时间
                info.setBeginTime(rtspSession.getCreated());
                //上行流量
                long bytesReceived = rtspSession.getBytesReceived();
                String formatReceivedSize = ArdTool.formatFileSize(bytesReceived);
                info.setUpTraffic(formatReceivedSize);
                //下行流量
                long bytesSent = rtspSession.getBytesSent();
                String formatSentSize = ArdTool.formatFileSize(bytesSent);
                info.setDownTraffic(formatSentSize);
                //推流服务器
                info.setRemoteAddr(rtspSession.getRemoteAddr());
            }
            //RTSP源地址
            String runOn = "";
            if (StringUtils.isNotEmpty(conf.getRunOnDemand())) {
                runOn = conf.getRunOnDemand();
            }
            Matcher matcher = Pattern.compile("rtsp://[^\\s\"]+").matcher(runOn);
            if (matcher.find()) {
                info.setRtspSource(matcher.group());
            } else {
                info.setRtspSource(conf.getSource());
            }
            //上行流量
            long bytesReceived = item.getBytesReceived();
            String formatReceivedSize = ArdTool.formatFileSize(bytesReceived);
            info.setUpTraffic(formatReceivedSize);
            //下行流量
            long bytesSent = item.getBytesSent();
            String formatSentSize = ArdTool.formatFileSize(bytesSent);
            info.setDownTraffic(formatSentSize);
            //传输协议
            info.setProtocol(conf.getSourceProtocol());
            //拉流数量
            List<Readers> readers = item.getReaders();
            //开始时间
            info.setBeginTime(item.getReadyTime());
            info.setNum(readers.size());
            PushStreamInfoList.add(info);
ard-work/src/main/java/com/ard/work/aspect/UavControlAspect.java
@@ -1,11 +1,23 @@
package com.ard.work.aspect;
import com.ard.common.constant.CacheConstants;
import com.ard.common.core.redis.RedisCache;
import com.ard.common.exception.ControlException;
import com.ard.common.utils.SecurityUtils;
import com.ard.common.utils.StringUtils;
import com.ard.common.utils.reflect.ReflectUtils;
import com.ard.data.noflyzone.domain.ArdNoFlyZone;
import com.ard.data.noflyzone.domain.Vertex;
import com.ard.data.noflyzone.service.IArdNoFlyZoneService;
import com.ard.data.noflyzone.utils.NoFlyZoneUtils;
import com.ard.work.aspect.annotation.CheckDroneStatus;
import com.ard.work.aspect.annotation.CheckNoFlyZone;
import com.ard.work.aspect.annotation.CheckTakeoffAltitude;
import com.ard.work.aspect.annotation.CheckControlRight;
import com.ard.work.domain.cache.UavTelemetryDataCache;
import com.ard.work.domain.dto.telemetry.TelemetryData;
import com.ard.work.domain.entity.ArdDroneInfo;
import com.ard.work.service.IArdDroneInfoService;
import com.ard.work.service.control.UavControlService;
import com.ard.work.domain.message.UavControlType;
import org.aspectj.lang.JoinPoint;
@@ -14,11 +26,11 @@
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.util.List;
/**
 * AOP 切面:拦截 @RequireUavControl,检查用户是否拥有 UAV 控制权限
 *
 * 无人机控制切面
 * <p>
 * 注意切面顺序:同类方法注解按字母ABCD顺序,不同类注解按order(1)顺序 越小优先级越高
 */
@Aspect
@@ -27,9 +39,13 @@
    @Resource
    private UavControlService uavControlService;
    @Resource
    private IArdNoFlyZoneService ardNoFlyZoneService;
    @Resource
    private RedisCache redisCache;
    /**
     * 前置通知:控制权检测
     * 控制权检查
     */
    @Before("@annotation(checkControlRight)")
    public void checkUavControl(JoinPoint joinPoint, CheckControlRight checkControlRight) {
@@ -42,22 +58,35 @@
        // 获取方法参数
        Object[] args = joinPoint.getArgs();
        // 遍历参数,使用反射获取每个参数中的 boxSn
        for (Object arg : args) {
            String boxSn = getBoxSn(arg);  // 调用之前实现的 getBoxSn 方法
            if (boxSn != null) {
                // 检查当前用户是否拥有该设备的控制权限
                Long currentController = uavControlService.getCurrentController(boxSn,
                        controlType.name().toLowerCase());
                if (currentController == null || !currentController.equals(userId)) {
                    throw new ControlException("无权执行该操作,需要 " + controlType + " 控制权限");
                }
            if (arg == null) {
                continue;
            }
            // 1️⃣ 获取 boxSn
            String boxSn = ReflectUtils.getFieldValue(arg, "boxSn");
            if (StringUtils.isBlank(boxSn)) {
                continue;
            }
            // 2️⃣ 检查控制权
            Long currentController = uavControlService.getCurrentController(boxSn,
                    controlType.name().toLowerCase());
            if (currentController == null || !currentController.equals(userId)) {
                throw new ControlException("无权执行该操作,需要 " + controlType + " 控制权限");
            }
            // 3️⃣ 检查在线状态
            Boolean online = redisCache.getCacheObject(CacheConstants.UAV_ONLINE_KEY + boxSn);
            if (online == null || !online) {
                throw new ControlException("无人机离线,无法执行操作!boxSn: " + boxSn);
            }
        }
    }
    /**
     * 前置通知:高度检查
     * 高度检查
     */
    @Before("@annotation(checkTakeoffAltitude)")
    public void takeoffAltitudeCheck(JoinPoint joinPoint, CheckTakeoffAltitude checkTakeoffAltitude) {
@@ -68,7 +97,7 @@
        // 遍历参数,使用反射获取每个参数中的 boxSn
        for (Object arg : args) {
            String boxSn = getBoxSn(arg);  // 调用之前实现的 getBoxSn 方法
            String boxSn = ReflectUtils.getFieldValue(arg, "boxSn");  // 调用之前实现的 getBoxSn 方法
            if (boxSn != null) {
                TelemetryData uavTelemetryData = UavTelemetryDataCache.get(boxSn);
                if (uavTelemetryData == null) {
@@ -83,41 +112,67 @@
    }
    /**
     * 通过反射获取对象中的 boxSn 字段
     *
     * @param dto 要反射的对象
     * @return boxSn 字段的值,如果没有找到则返回 null
     * 状态检查
     */
    public static String getBoxSn(Object dto) {
        if (dto == null) {
            return null; // 如果对象为空,直接返回 null
        }
    @Before("@annotation(checkDroneStatus)")
    public void checkDroneStatus(JoinPoint joinPoint, CheckDroneStatus checkDroneStatus) {
        for (Object arg : joinPoint.getArgs()) {
            if (arg == null) {
                continue;
            }
        try {
            // 获取类的所有字段
            Field[] fields = dto.getClass().getDeclaredFields();
            for (Field field : fields) {
                // 设置字段可访问
                field.setAccessible(true);
                // 判断是否是 boxSn 字段
                if ("boxSn".equals(field.getName())) {
                    // 检查字段类型是否是 String 类型
                    if (field.getType().equals(String.class)) {
                        // 获取并返回 boxSn 字段的值
                        return (String) field.get(dto);
                    } else {
                        // 如果字段类型不是 String,返回 null
                        return null;
                    }
            String boxSn = ReflectUtils.getFieldValue(arg, "boxSn");
            if (boxSn == null) {
                continue;
            }
            // 检查在线状态
            if (checkDroneStatus.checkOnline()) {
                Boolean online = redisCache.getCacheObject(CacheConstants.UAV_ONLINE_KEY + boxSn);
                if (online == null || !online) {
                    throw new ControlException("无人机离线,无法执行操作!boxSn: " + boxSn);
                }
            }
        } catch (IllegalAccessException e) {
            // 捕获异常并打印日志
            System.err.println("反射访问失败: " + e.getMessage());
            e.printStackTrace();
        }
    }
    /**
     * 禁飞区检查
     */
    @Before("@annotation(checkNoFlyZone)")
    public void checkNoFlyZone(JoinPoint joinPoint, CheckNoFlyZone checkNoFlyZone) {
        Object[] args = joinPoint.getArgs();
        if (args == null || args.length == 0) {
            return;
        }
        return null; // 如果没有找到 boxSn 字段,返回 null
        Double longitude = null;
        Double latitude = null;
        for (Object arg : args) {
            if (arg == null) {
                continue;
            }
            Double lon = ReflectUtils.getFieldValue(arg, "longitude");
            Double lat = ReflectUtils.getFieldValue(arg, "latitude");
            if (lon != null && lat != null) {
                longitude = lon;
                latitude = lat;
                break;
            }
        }
        if (longitude == null || latitude == null) {
            throw new ControlException("方法参数中未找到有效经纬度字段,无法判断禁飞区!");
        }
        List<ArdNoFlyZone> ardNoFlyZones = ardNoFlyZoneService.selectArdNoFlyZoneList(new ArdNoFlyZone());
        if (!ardNoFlyZones.isEmpty()) {
            Vertex vertex = new Vertex(longitude, latitude);
            boolean inNoFlyZones = NoFlyZoneUtils.isInNoFlyZones(vertex, ardNoFlyZones);
            if (inNoFlyZones) {
                throw new ControlException("目标点在禁飞区内,无法执行操作!");
            }
        }
    }
}
ard-work/src/main/java/com/ard/work/aspect/annotation/CheckControlRight.java
@@ -8,7 +8,8 @@
import java.lang.annotation.Target;
/**
 * 自定义注解:用于方法拦截,检查 UAV 控制权限
 * 控制权限检查
 * 包含无人机在线检查
 */
@Target(ElementType.METHOD)   // 作用于方法
@Retention(RetentionPolicy.RUNTIME) // 运行时生效
ard-work/src/main/java/com/ard/work/aspect/annotation/CheckDroneStatus.java
New file
@@ -0,0 +1,15 @@
package com.ard.work.aspect.annotation;
import java.lang.annotation.*;
/**
 * 检查飞行器状态
 *
 */
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CheckDroneStatus {
    boolean checkOnline() default true;
}
ard-work/src/main/java/com/ard/work/aspect/annotation/CheckNoFlyZone.java
New file
@@ -0,0 +1,14 @@
package com.ard.work.aspect.annotation;
import java.lang.annotation.*;
/**
 * 检查禁飞区
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CheckNoFlyZone {
    // 简化,不需要字段
}
ard-work/src/main/java/com/ard/work/aspect/annotation/CheckTakeoffAltitude.java
@@ -5,6 +5,9 @@
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
 * 检查最低高度
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface CheckTakeoffAltitude {
ard-work/src/main/java/com/ard/work/domain/entity/ArdDroneInfo.java
@@ -10,7 +10,7 @@
import java.util.Objects;
/**
 * 无人机盒子对象 ard_drone_info
 * 无人机盒子对象 ard_drone
 * 
 * @author ard
 * @date 2025-03-04
ard-work/src/main/java/com/ard/work/domain/entity/ArdServerInfo.java
@@ -7,7 +7,7 @@
import lombok.Data;
/**
 * 服务器管理对象 ard_server_info
 * 服务器管理对象 ard_server
 * 
 * @author xia
 * @date 2025-10-10
ard-work/src/main/java/com/ard/work/service/impl/TyServiceImpl.java
@@ -1,10 +1,9 @@
package com.ard.work.service.impl;
import com.ard.common.constant.CacheConstants;
import com.ard.common.core.redis.RedisCache;
import com.ard.common.exception.ServiceException;
import com.ard.common.utils.StringUtils;
import com.ard.common.exception.ControlException;
import com.ard.work.aspect.annotation.CheckControlRight;
import com.ard.work.aspect.annotation.CheckDroneStatus;
import com.ard.work.aspect.annotation.CheckNoFlyZone;
import com.ard.work.aspect.annotation.CheckTakeoffAltitude;
import com.ard.work.component.forest.TyClient;
import com.ard.work.component.netty.TcpClientUtil;
@@ -56,7 +55,6 @@
import com.ard.work.service.IArdServerInfoService;
import com.ard.work.service.ITyService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@@ -79,8 +77,6 @@
    private IArdDroneInfoService ardDroneService;
    @Resource
    private TyClient tyClient;
    @Autowired
    private RedisCache redisCache;
    /**
     * 获取边缘服务器token信息
@@ -125,12 +121,10 @@
    public BoxStreamUrlReceiver getBoxLiveUrl(String boxSn) {
        ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
        if (ardDroneInfo == null) {
            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        // ✅ 判断无人机是否在线
        if (!isDroneOnline(boxSn)) {
            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
        }
        TyHttpCommonReceiver<BoxStreamUrlReceiver> boxLiveUrl = tyClient.getBoxLiveUrl(ardDroneInfo.getServerId(),
                boxSn);
        return boxLiveUrl == null ? null : boxLiveUrl.getContent();
@@ -146,11 +140,7 @@
        String boxSn = boxHistoryDTO.getBoxSn();
        ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
        if (ardDroneInfo == null) {
            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        // ✅ 判断无人机是否在线
        if (!isDroneOnline(boxSn)) {
            throw new ServiceException("无人机离线,无法执行起飞指令, boxSn: " + boxSn);
            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        TyHttpCommonReceiver<List<BoxHistoryReceiver>> boxHistory = tyClient.getBoxHistory(ardDroneInfo.getServerId(),
                boxHistoryDTO);
@@ -167,11 +157,7 @@
        String boxSn = boxPhotosDTO.getBoxSn();
        ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
        if (ardDroneInfo == null) {
            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        // ✅ 判断无人机是否在线
        if (!isDroneOnline(boxSn)) {
            throw new ServiceException("无人机离线,无法执行起飞指令, boxSn: " + boxSn);
            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        TyHttpCommonReceiver<List<BoxPhotosReceiver>> boxPhotos = tyClient.getBoxPhotos(ardDroneInfo.getServerId(),
                boxPhotosDTO);
@@ -186,11 +172,7 @@
        String boxSn = boxSettingsDTO.getBoxSn();
        ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
        if (ardDroneInfo == null) {
            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        // ✅ 判断无人机是否在线
        if (!isDroneOnline(boxSn)) {
            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        TyHttpCommonReceiver<?> result = tyClient.updateBoxSettings(ardDroneInfo.getServerId(), boxSettingsDTO);
        return result.getState() == 1;
@@ -204,11 +186,7 @@
        String boxSn = returnHeightSettingDTO.getBoxSn();
        ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
        if (ardDroneInfo == null) {
            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        // ✅ 判断无人机是否在线
        if (!isDroneOnline(boxSn)) {
            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        ReturnHeightSettingCmd returnHeightSettingCmd = new ReturnHeightSettingCmd(returnHeightSettingDTO);
        this.sendMessage(ardDroneInfo.getServerId(), returnHeightSettingCmd);
@@ -223,11 +201,7 @@
        String boxSn = returnPointSettingDTO.getBoxSn();
        ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
        if (ardDroneInfo == null) {
            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        // ✅ 判断无人机是否在线
        if (!isDroneOnline(boxSn)) {
            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        ReturnPointSettingCmd returnPointSettingCmd = new ReturnPointSettingCmd(returnPointSettingDTO);
        this.sendMessage(ardDroneInfo.getServerId(), returnPointSettingCmd);
@@ -242,11 +216,7 @@
        String boxSn = videoStreamSettingDTO.getBoxSn();
        ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
        if (ardDroneInfo == null) {
            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        // ✅ 判断无人机是否在线
        if (!isDroneOnline(boxSn)) {
            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        VideoStreamSettingCmd videoStreamSettingCmd = new VideoStreamSettingCmd(videoStreamSettingDTO);
        this.sendMessage(ardDroneInfo.getServerId(), videoStreamSettingCmd);
@@ -278,11 +248,7 @@
        String boxSn = angleControlDto.getBoxSn();
        ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
        if (ardDroneInfo == null) {
            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        // ✅ 判断无人机是否在线
        if (!isDroneOnline(boxSn)) {
            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        AngleControlCmd controlAngleCommand = new AngleControlCmd(angleControlDto);
        this.sendMessage(ardDroneInfo.getServerId(), controlAngleCommand);
@@ -298,11 +264,7 @@
        String boxSn = absAngleControlDto.getBoxSn();
        ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
        if (ardDroneInfo == null) {
            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        // ✅ 判断无人机是否在线
        if (!isDroneOnline(boxSn)) {
            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        AbsAngleControlCmd absAngleControlCommand = new AbsAngleControlCmd(absAngleControlDto);
        this.sendMessage(ardDroneInfo.getServerId(), absAngleControlCommand);
@@ -318,11 +280,7 @@
        String boxSn = speedControlDto.getBoxSn();
        ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
        if (ardDroneInfo == null) {
            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        // ✅ 判断无人机是否在线
        if (!isDroneOnline(boxSn)) {
            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        SpeedControlCmd speedControlCommand = new SpeedControlCmd(speedControlDto);
        this.sendMessage(ardDroneInfo.getServerId(), speedControlCommand);
@@ -332,16 +290,13 @@
    /**
     * 设置相机模式
     */
    @CheckControlRight(UavControlType.PAYLOAD)
    @Override
    public Boolean updateCameraMode(CameraModeDTO cameraModeDTO) {
        String boxSn = cameraModeDTO.getBoxSn();
        ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
        if (ardDroneInfo == null) {
            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        // ✅ 判断无人机是否在线
        if (!isDroneOnline(boxSn)) {
            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        CameraModeCmd cameraModeCommand = new CameraModeCmd(cameraModeDTO);
        this.sendMessage(ardDroneInfo.getServerId(), cameraModeCommand);
@@ -351,16 +306,13 @@
    /**
     * 拍照
     */
    @CheckControlRight(UavControlType.PAYLOAD)
    @Override
    public Boolean capturePic(CapturePicDTO capturePicDto) {
        String boxSn = capturePicDto.getBoxSn();
        ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
        if (ardDroneInfo == null) {
            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        // ✅ 判断无人机是否在线
        if (!isDroneOnline(boxSn)) {
            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        //设置相机模式为拍照模式
        updateCameraMode(CameraModeDTO.builder().boxSn(capturePicDto.getBoxSn()).actionParam((byte) 0x01).build());
@@ -375,16 +327,13 @@
    /**
     * 录像
     */
    @CheckControlRight(UavControlType.PAYLOAD)
    @Override
    public Boolean record(RecordDTO recordDto) {
        String boxSn = recordDto.getBoxSn();
        ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
        if (ardDroneInfo == null) {
            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        // ✅ 判断无人机是否在线
        if (!isDroneOnline(boxSn)) {
            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        BaseCmd baseCmd;
        if (recordDto.getIsRecord()) {
@@ -406,11 +355,7 @@
        String boxSn = zoomDTO.getBoxSn();
        ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
        if (ardDroneInfo == null) {
            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        // ✅ 判断无人机是否在线
        if (!isDroneOnline(boxSn)) {
            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        ZoomCmd zoomCommand = new ZoomCmd(zoomDTO);
        this.sendMessage(ardDroneInfo.getServerId(), zoomCommand);
@@ -426,11 +371,7 @@
        String boxSn = zoomToLevelDTO.getBoxSn();
        ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
        if (ardDroneInfo == null) {
            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        // ✅ 判断无人机是否在线
        if (!isDroneOnline(boxSn)) {
            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        ZoomToLevelCmd zoomToLevelCommand = new ZoomToLevelCmd(zoomToLevelDTO);
        this.sendMessage(ardDroneInfo.getServerId(), zoomToLevelCommand);
@@ -440,16 +381,13 @@
    /**
     * 切换摄像头
     */
    @CheckControlRight(UavControlType.PAYLOAD)
    @Override
    public Boolean switchCamera(SwitchCameraDTO switchCameraDTO) {
        String boxSn = switchCameraDTO.getBoxSn();
        ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
        if (ardDroneInfo == null) {
            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        // ✅ 判断无人机是否在线
        if (!isDroneOnline(boxSn)) {
            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        SwitchCameraCmd switchCameraCmd = new SwitchCameraCmd(switchCameraDTO);
        this.sendMessage(ardDroneInfo.getServerId(), switchCameraCmd);
@@ -459,16 +397,13 @@
    /**
     * 切换视频源
     */
    @CheckControlRight(UavControlType.PAYLOAD)
    @Override
    public Boolean switchSource(SwitchSourceDTO switchSourceDTO) {
        String boxSn = switchSourceDTO.getBoxSn();
        ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
        if (ardDroneInfo == null) {
            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        // ✅ 判断无人机是否在线
        if (!isDroneOnline(boxSn)) {
            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        SwitchSourceCmd switchSourceCmd = new SwitchSourceCmd(switchSourceDTO);
        this.sendMessage(ardDroneInfo.getServerId(), switchSourceCmd);
@@ -478,16 +413,13 @@
    /**
     * 打开或关闭照片回传
     */
    @CheckControlRight(UavControlType.PAYLOAD)
    @Override
    public Boolean photoReturnToggle(PhotoReturnToggleDTO photoReturnToggleDTO) {
        String boxSn = photoReturnToggleDTO.getBoxSn();
        ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
        if (ardDroneInfo == null) {
            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        // ✅ 判断无人机是否在线
        if (!isDroneOnline(boxSn)) {
            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        PhotoReturnToggleCmd photoReturnToggleCmd = new PhotoReturnToggleCmd(photoReturnToggleDTO);
        this.sendMessage(ardDroneInfo.getServerId(), photoReturnToggleCmd);
@@ -497,16 +429,13 @@
    /**
     * 切换无人机控制权
     */
    @CheckDroneStatus
    @Override
    public Boolean switchUavControl(SwitchUavControlDTO switchUavControlDTO) {
        String boxSn = switchUavControlDTO.getBoxSn();
        ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
        if (ardDroneInfo == null) {
            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        // ✅ 判断无人机是否在线
        if (!isDroneOnline(boxSn)) {
            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        SwitchUavControlCmd switchUavControlCmd = new SwitchUavControlCmd(switchUavControlDTO);
        this.sendMessage(ardDroneInfo.getServerId(), switchUavControlCmd);
@@ -522,11 +451,7 @@
        String boxSn = takeOffDTO.getBoxSn();
        ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
        if (ardDroneInfo == null) {
            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        // ✅ 判断无人机是否在线
        if (!isDroneOnline(boxSn)) {
            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        TakeOffCmd takeOffCmd = new TakeOffCmd(takeOffDTO);
        this.sendMessage(ardDroneInfo.getServerId(), takeOffCmd);
@@ -542,11 +467,7 @@
        String boxSn = returnHomeDTO.getBoxSn();
        ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
        if (ardDroneInfo == null) {
            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        // ✅ 判断无人机是否在线
        if (!isDroneOnline(boxSn)) {
            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        ReturnHomeCmd returnHomeCmd = new ReturnHomeCmd(returnHomeDTO);
        this.sendMessage(ardDroneInfo.getServerId(), returnHomeCmd);
@@ -562,11 +483,7 @@
        String boxSn = returnHomeCancelDTO.getBoxSn();
        ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
        if (ardDroneInfo == null) {
            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        // ✅ 判断无人机是否在线
        if (!isDroneOnline(boxSn)) {
            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        ReturnHomeCancelCmd returnHomeCancelCmd = new ReturnHomeCancelCmd(returnHomeCancelDTO);
        this.sendMessage(ardDroneInfo.getServerId(), returnHomeCancelCmd);
@@ -582,11 +499,7 @@
        String boxSn = landDTO.getBoxSn();
        ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
        if (ardDroneInfo == null) {
            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        // ✅ 判断无人机是否在线
        if (!isDroneOnline(boxSn)) {
            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        LandCmd landCmd = new LandCmd(landDTO);
        this.sendMessage(ardDroneInfo.getServerId(), landCmd);
@@ -602,11 +515,7 @@
        String boxSn = landCancelDTO.getBoxSn();
        ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
        if (ardDroneInfo == null) {
            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        // ✅ 判断无人机是否在线
        if (!isDroneOnline(boxSn)) {
            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        LandCancelCmd landCancelCmd = new LandCancelCmd(landCancelDTO);
        this.sendMessage(ardDroneInfo.getServerId(), landCancelCmd);
@@ -622,11 +531,7 @@
        String boxSn = landForcedDTO.getBoxSn();
        ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
        if (ardDroneInfo == null) {
            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        // ✅ 判断无人机是否在线
        if (!isDroneOnline(boxSn)) {
            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        LandForcedCmd landForcedCmd = new LandForcedCmd(landForcedDTO);
        this.sendMessage(ardDroneInfo.getServerId(), landForcedCmd);
@@ -643,11 +548,7 @@
        String boxSn = flyControlDTO.getBoxSn();
        ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
        if (ardDroneInfo == null) {
            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        // ✅ 判断无人机是否在线
        if (!isDroneOnline(boxSn)) {
            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        FlyControlCmd flyControlCmd = new FlyControlCmd(flyControlDTO);
        this.sendMessage(ardDroneInfo.getServerId(), flyControlCmd);
@@ -659,16 +560,13 @@
     */
    @CheckControlRight(UavControlType.FLY)
    @CheckTakeoffAltitude(minAltitude = 30.0)
    @CheckNoFlyZone
    @Override
    public Boolean flyPointControl(FlyPointControlDTO flyPointControlDTO) {
        String boxSn = flyPointControlDTO.getBoxSn();
        ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
        if (ardDroneInfo == null) {
            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        // ✅ 判断无人机是否在线
        if (!isDroneOnline(boxSn)) {
            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        FlyPointControlCmd flyPointControlCmd = new FlyPointControlCmd(flyPointControlDTO);
        this.sendMessage(ardDroneInfo.getServerId(), flyPointControlCmd);
@@ -684,12 +582,10 @@
        String boxSn = flyPointControlCancelDTO.getBoxSn();
        ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
        if (ardDroneInfo == null) {
            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        // ✅ 判断无人机是否在线
        if (!isDroneOnline(boxSn)) {
            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
        }
        FlyPointControlCancelCmd flyPointControlCancelCmd = new FlyPointControlCancelCmd(flyPointControlCancelDTO);
        this.sendMessage(ardDroneInfo.getServerId(), flyPointControlCancelCmd);
        return true;
@@ -704,12 +600,10 @@
        String boxSn = emeragencyBrakeDTO.getBoxSn();
        ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
        if (ardDroneInfo == null) {
            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        // ✅ 判断无人机是否在线
        if (!isDroneOnline(boxSn)) {
            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
        }
        EmergencyBrakeCmd emergencyBrakeCmd = new EmergencyBrakeCmd(emeragencyBrakeDTO);
        this.sendMessage(ardDroneInfo.getServerId(), emergencyBrakeCmd);
        return true;
@@ -747,11 +641,7 @@
        String boxSn = speakModeSwitchDTO.getBoxSn();
        ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
        if (ardDroneInfo == null) {
            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        // ✅ 判断无人机是否在线
        if (!isDroneOnline(boxSn)) {
            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        SpeakModeSwitchCmd speakModeSwitchCmd = new SpeakModeSwitchCmd(speakModeSwitchDTO);
        this.sendMessage(ardDroneInfo.getServerId(), speakModeSwitchCmd);
@@ -766,11 +656,7 @@
        String boxSn = textSpeakDTO.getBoxSn();
        ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
        if (ardDroneInfo == null) {
            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        // ✅ 判断无人机是否在线
        if (!isDroneOnline(boxSn)) {
            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        TextSpeakCmd textSpeakCmd = new TextSpeakCmd(textSpeakDTO);
        this.sendMessage(ardDroneInfo.getServerId(), textSpeakCmd);
@@ -785,11 +671,7 @@
        String boxSn = realSpeakDTO.getBoxSn();
        ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
        if (ardDroneInfo == null) {
            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        // ✅ 判断无人机是否在线
        if (!isDroneOnline(boxSn)) {
            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        RealSpeakCmd realSpeakCmd = new RealSpeakCmd(realSpeakDTO);
        this.sendMessage(ardDroneInfo.getServerId(), realSpeakCmd);
@@ -804,11 +686,7 @@
        String boxSn = recordSpeakDTO.getBoxSn();
        ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
        if (ardDroneInfo == null) {
            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        // ✅ 判断无人机是否在线
        if (!isDroneOnline(boxSn)) {
            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        RecordSpeakCmd recordSpeakCmd = new RecordSpeakCmd(recordSpeakDTO);
        this.sendMessage(ardDroneInfo.getServerId(), recordSpeakCmd);
@@ -823,11 +701,7 @@
        String boxSn = volumeSettingDTO.getBoxSn();
        ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
        if (ardDroneInfo == null) {
            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        // ✅ 判断无人机是否在线
        if (!isDroneOnline(boxSn)) {
            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        VolumeSettingCmd volumeSettingCmd = new VolumeSettingCmd(volumeSettingDTO);
        this.sendMessage(ardDroneInfo.getServerId(), volumeSettingCmd);
@@ -842,11 +716,7 @@
        String boxSn = loopSettingDTO.getBoxSn();
        ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
        if (ardDroneInfo == null) {
            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        // ✅ 判断无人机是否在线
        if (!isDroneOnline(boxSn)) {
            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        LoopSettingCmd loopSettingCmd = new LoopSettingCmd(loopSettingDTO);
        this.sendMessage(ardDroneInfo.getServerId(), loopSettingCmd);
@@ -861,11 +731,7 @@
        String boxSn = stopSpeakDTO.getBoxSn();
        ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
        if (ardDroneInfo == null) {
            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        // ✅ 判断无人机是否在线
        if (!isDroneOnline(boxSn)) {
            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        StopSpeakCmd stopSpeakCmd = new StopSpeakCmd(stopSpeakDTO);
        this.sendMessage(ardDroneInfo.getServerId(), stopSpeakCmd);
@@ -875,16 +741,13 @@
    /**
     * 航线上传
     */
    @CheckControlRight(UavControlType.FLY)
    @Override
    public Boolean wayLineUpload(WayLineUploadDTO wayLineUploadDTO) {
        String boxSn = wayLineUploadDTO.getBoxSn();
        ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
        if (ardDroneInfo == null) {
            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        // ✅ 判断无人机是否在线
        if (!isDroneOnline(boxSn)) {
            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        //wayLineUploadDTO.setWayLineData(this.CreatePlanLineData());//设置航线数据
        WayLineUploadCmd wayLineUploadCmd = new WayLineUploadCmd(wayLineUploadDTO);
@@ -935,11 +798,7 @@
        String boxSn = wayLineBeginDTO.getBoxSn();
        ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
        if (ardDroneInfo == null) {
            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        // ✅ 判断无人机是否在线
        if (!isDroneOnline(boxSn)) {
            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        WayLineBeginCmd wayLineBeginCmd = new WayLineBeginCmd(wayLineBeginDTO);
        this.sendMessage(ardDroneInfo.getServerId(), wayLineBeginCmd);
@@ -955,11 +814,7 @@
        String boxSn = wayLinePauseDTO.getBoxSn();
        ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
        if (ardDroneInfo == null) {
            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        // ✅ 判断无人机是否在线
        if (!isDroneOnline(boxSn)) {
            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        WayLinePauseCmd wayLinePauseCmd = new WayLinePauseCmd(wayLinePauseDTO);
        this.sendMessage(ardDroneInfo.getServerId(), wayLinePauseCmd);
@@ -975,11 +830,7 @@
        String boxSn = wayLineResumeDTO.getBoxSn();
        ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
        if (ardDroneInfo == null) {
            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        // ✅ 判断无人机是否在线
        if (!isDroneOnline(boxSn)) {
            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        WayLineResumeCmd wayLineResumeCmd = new WayLineResumeCmd(wayLineResumeDTO);
        this.sendMessage(ardDroneInfo.getServerId(), wayLineResumeCmd);
@@ -995,11 +846,7 @@
        String boxSn = wayLineEndDTO.getBoxSn();
        ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
        if (ardDroneInfo == null) {
            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        // ✅ 判断无人机是否在线
        if (!isDroneOnline(boxSn)) {
            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
        }
        WayLineEndCmd wayLineEndCmd = new WayLineEndCmd(wayLineEndDTO);
        this.sendMessage(ardDroneInfo.getServerId(), wayLineEndCmd);
@@ -1275,14 +1122,4 @@
    private void sendMessage(String key, BaseCmd msg) {
        TcpClientUtil.sendMessage(key, msg);
    }
    // 判断无人机是否在线
    private boolean isDroneOnline(String boxSn) {
        if (StringUtils.isBlank(boxSn)) {
            return false;
        }
        Object obj = redisCache.getCacheObject(CacheConstants.UAV_ONLINE_KEY + boxSn);
        return obj != null;
    }
}
ard-work/src/main/resources/mapper/ArdDroneInfoMapper.xml
@@ -33,7 +33,7 @@
    </resultMap>
    <select id="selectArdServerInfo" resultType="com.ard.work.domain.entity.ArdServerInfo">
        select * from ard_server_info where id = #{serverId}
        select * from ard_server where id = #{serverId}
    </select>
    <sql id="selectArdDroneVo">
@@ -50,7 +50,7 @@
               c.user_id,
               c.dept_id,
               c.box_alias_name
        from ard_drone_info c
        from ard_drone c
                 left join sys_dept d on d.dept_id = c.dept_id
                 left join sys_user u on u.user_id = c.user_id
    </sql>
@@ -82,7 +82,7 @@
        where box_sn = #{boxSn}
    </select>
    <insert id="insertArdDrone" parameterType="ArdDroneInfo">
        insert into ard_drone_info
        insert into ard_drone
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="id != null">id,</if>
            <if test="boxSn != null">box_sn,</if>
@@ -126,7 +126,7 @@
    </insert>
    <update id="updateArdDrone" parameterType="ArdDroneInfo">
        update ard_drone_info
        update ard_drone
        <trim prefix="SET" suffixOverrides=",">
            <if test="boxSn != null">box_sn = #{boxSn},</if>
            <if test="boxName != null">box_name = #{boxName},</if>
@@ -150,18 +150,18 @@
    </update>
    <delete id="deleteArdDroneById" parameterType="String">
        delete from ard_drone_info where id = #{id}
        delete from ard_drone where id = #{id}
    </delete>
    <delete id="deleteArdDroneByIds" parameterType="String">
        delete from ard_drone_info where id in
        delete from ard_drone where id in
        <foreach item="id" collection="array" open="(" separator="," close=")">
            #{id}
        </foreach>
    </delete>
    <insert id="insertArdDroneLs" parameterType="java.util.List">
        insert into ard_drone_info(
        insert into ard_drone(
            id,
            box_sn,
            box_name,
@@ -204,7 +204,7 @@
    </insert>
    <update id="updateDroneStatus">
        update ard_drone_info
        update ard_drone
        <trim prefix="SET" suffixOverrides=",">
            <if test="onLine != null">on_line = #{onLine},</if>
        </trim>
ard-work/src/main/resources/mapper/ArdServerInfoMapper.xml
@@ -34,7 +34,7 @@
               user_id,
               dept_id,
               server_status
        from ard_server_info
        from ard_server
    </sql>
    <sql id="selectArdServerInfoVo">
@@ -51,7 +51,7 @@
               c.user_id,
               c.dept_id,
               c.server_status
        from ard_server_info c
        from ard_server c
                 left join sys_dept d on d.dept_id = c.dept_id
                 left join sys_user u on u.user_id = c.user_id
    </sql>
@@ -78,7 +78,7 @@
    </select>
    <insert id="insertArdServerInfo" parameterType="ArdServerInfo">
        insert into ard_server_info
        insert into ard_server
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="id != null">id,</if>
            <if test="serverName != null">server_name,</if>
@@ -112,7 +112,7 @@
    </insert>
    <update id="updateArdServerInfo" parameterType="ArdServerInfo">
        update ard_server_info
        update ard_server
        <trim prefix="SET" suffixOverrides=",">
            <if test="serverName != null">server_name = #{serverName},</if>
            <if test="host != null">host = #{host},</if>
@@ -131,7 +131,7 @@
    </update>
    <update id="updateServerStatus">
        update ard_server_info
        update ard_server
        <trim prefix="SET" suffixOverrides=",">
            <if test="status != null">server_status = #{status},</if>
        </trim>
@@ -139,11 +139,11 @@
    </update>
    <delete id="deleteArdServerInfoById" parameterType="String">
        delete from ard_server_info where id = #{id}
        delete from ard_server where id = #{id}
    </delete>
    <delete id="deleteArdServerInfoByIds" parameterType="String">
        delete from ard_server_info where id in
        delete from ard_server where id in
        <foreach item="id" collection="array" open="(" separator="," close=")">
            #{id}
        </foreach>