From e90d0fe42b652c9230c5e544d177dbedb3e57580 Mon Sep 17 00:00:00 2001
From: zhaowenyu <35589726@qq.com>
Date: Wed, 19 Nov 2025 13:51:26 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/dev' into dev

---
 ard-work/src/main/java/com/ard/work/component/netty/command/register/UavInitReplyCmd.java             |    2 
 ard-work/src/main/java/com/ard/work/component/netty/command/real/SignalInfoCmd.java                   |    2 
 ard-route/src/main/java/com/ard/route/service/IArdRouteInfoService.java                               |   46 +
 ard-work/src/main/java/com/ard/work/component/netty/command/camera/RecordStartCmd.java                |    2 
 ard-work/src/main/java/com/ard/work/component/netty/command/settings/ReturnHeightSettingReplyCmd.java |    2 
 ard-work/src/main/java/com/ard/work/component/netty/command/register/UavInitInfoCmd.java              |    2 
 ard-work/src/main/java/com/ard/work/component/netty/command/camera/ZoomCmd.java                       |    2 
 ard-route/src/main/java/com/ard/route/util/InitializationUtils.java                                   |  161 +++++-
 ard-work/src/main/java/com/ard/work/service/impl/ArdFlightTaskServiceServiceImpl.java                 |  415 +++++++++++++----
 ard-work/src/main/java/com/ard/work/component/netty/command/control/AbsAngleControlCmd.java           |    2 
 ard-work/src/main/java/com/ard/work/component/netty/command/control/AngleControlCmd.java              |    2 
 ard-work/src/main/java/com/ard/work/component/netty/command/manual/TakeOffReplyCmd.java               |    2 
 ard-work/src/main/java/com/ard/work/component/netty/command/settings/VideoStreamSettingReplyCmd.java  |    2 
 ard-work/src/main/java/com/ard/work/component/netty/command/wayline/WayLineResumeReplyCmd.java        |    2 
 ard-work/src/main/java/com/ard/work/component/netty/command/settings/ReturnPointSettingReplyCmd.java  |    2 
 ard-work/src/main/java/com/ard/work/mapper/ArdMediaMapper.java                                        |    8 
 ard-work/src/main/java/com/ard/work/component/netty/command/notice/FlyWayEndReplyCmd.java             |    2 
 ard-work/src/main/java/com/ard/work/component/netty/command/manual/LandReplyCmd.java                  |    2 
 ard-work/src/main/java/com/ard/work/component/netty/command/wayline/WayLineUploadReplyCmd.java        |    2 
 ard-work/src/main/java/com/ard/work/domain/entity/ArdMedia.java                                       |   16 
 ard-work/src/main/java/com/ard/work/component/netty/command/manual/LandForcedReplyCmd.java            |    2 
 ard-work/src/main/java/com/ard/work/component/netty/command/real/UavStateCmd.java                     |    2 
 ard-work/src/main/java/com/ard/work/component/netty/command/camera/CapturePicReplyCmd.java            |    2 
 ard-work/src/main/java/com/ard/work/component/netty/command/wayline/WayLineBeginReplyCmd.java         |    2 
 ard-work/src/main/java/com/ard/work/component/netty/command/camera/CapturePicCmd.java                 |    2 
 ard-work/src/main/java/com/ard/work/component/netty/command/control/SpeedControlCmd.java              |    2 
 ard-work/src/main/java/com/ard/work/domain/dto/wayline/PlanLineData.java                              |   52 +
 ard-work/src/main/java/com/ard/work/component/netty/command/notice/UavReadyReplyCmd.java              |    2 
 ard-work/src/main/java/com/ard/work/mapper/ArdFlightTaskMapper.java                                   |    3 
 ard-work/src/main/java/com/ard/work/component/netty/command/manual/EmergencyBrakeReplyCmd.java        |    2 
 ard-work/src/main/java/com/ard/work/domain/entity/ArdDroneInfo.java                                   |    1 
 ard-work/src/main/java/com/ard/work/component/netty/command/camera/RecordStartReplyCmd.java           |    2 
 ard-work/src/main/java/com/ard/work/domain/dto/wayline/PointAction.java                               |   33 +
 ard-work/src/main/java/com/ard/work/component/netty/command/register/HeartbeatReplyCmd.java           |    2 
 ard-route/src/main/java/com/ard/route/domain/sixhe/ArdRouteChange.java                                |    4 
 ard-work/src/main/java/com/ard/work/component/netty/command/register/RegisterReplyCmd.java            |    2 
 ard-work/src/main/java/com/ard/work/component/netty/command/wayline/WayLinePauseReplyCmd.java         |    2 
 ard-admin/src/main/java/com/ard/web/controller/route/ArdRouteInfoController.java                      |   51 +
 ard-work/src/main/java/com/ard/work/component/netty/command/manual/ReturnHomeCancelReplyCmd.java      |    2 
 ard-work/src/main/java/com/ard/work/component/netty/command/notice/BoxPowerStatusReplyCmd.java        |    2 
 ard-work/src/main/java/com/ard/work/component/netty/command/camera/CameraModeReplyCmd.java            |    2 
 ard-work/src/main/java/com/ard/work/component/netty/command/camera/RecordStopReplyCmd.java            |    2 
 ard-work/src/main/java/com/ard/work/domain/entity/UavWayline.java                                     |    6 
 ard-work/src/main/java/com/ard/work/component/netty/command/wayline/WayLineEndReplyCmd.java           |    2 
 ard-work/src/main/java/com/ard/work/domain/dto/wayline/WayLineUploadDTO.java                          |    8 
 ard-work/src/main/java/com/ard/work/component/netty/command/camera/ZoomToLevelCmd.java                |    2 
 ard-work/src/main/java/com/ard/work/component/netty/command/camera/PicUploadCompletedReplyCmd.java    |    2 
 ard-work/src/main/java/com/ard/work/component/netty/command/camera/RecordStopCmd.java                 |    2 
 ard-work/src/main/java/com/ard/work/component/netty/command/manual/PointControlReachedReplyCmd.java   |    2 
 ard-work/src/main/java/com/ard/work/domain/dto/state/PointData.java                                   |   63 ++
 ard-work/src/main/java/com/ard/work/domain/entity/ArdFlightTask.java                                  |   23 
 ard-route/src/main/java/com/ard/route/service/impl/ArdRouteInfoServiceImpl.java                       |  233 +++++++++
 ard-work/src/main/java/com/ard/work/domain/entity/ArdServerInfo.java                                  |    2 
 ard-work/src/main/java/com/ard/work/service/impl/ArdMediaServiceImpl.java                             |    2 
 ard-work/pom.xml                                                                                      |    9 
 ard-work/src/main/java/com/ard/work/component/netty/command/manual/ReturnHomeReplyCmd.java            |    2 
 ard-work/src/main/resources/mapper/ArdFlightTaskMapper.xml                                            |   21 
 ard-route/pom.xml                                                                                     |    4 
 ard-work/src/main/java/com/ard/work/component/netty/command/camera/PhotoReturnToggleCmd.java          |    2 
 ard-work/src/main/java/com/ard/work/component/netty/command/manual/LandCancelReplyCmd.java            |    2 
 ard-work/src/main/java/com/ard/work/component/netty/command/real/UavTelemetryDataCmd.java             |    2 
 ard-work/src/main/java/com/ard/work/component/netty/command/camera/CameraModeCmd.java                 |    2 
 ard-work/src/main/resources/mapper/ArdMediaMapper.xml                                                 |  152 ++++-
 63 files changed, 1,175 insertions(+), 220 deletions(-)

diff --git a/ard-admin/src/main/java/com/ard/web/controller/route/ArdRouteInfoController.java b/ard-admin/src/main/java/com/ard/web/controller/route/ArdRouteInfoController.java
index 09eb7de..85d0068 100644
--- a/ard-admin/src/main/java/com/ard/web/controller/route/ArdRouteInfoController.java
+++ b/ard-admin/src/main/java/com/ard/web/controller/route/ArdRouteInfoController.java
@@ -132,10 +132,51 @@
     /**
      * 上传航线到边缘服务器
      */
-//    @ApiOperation("上传航线到边缘服务器")
-//    @PostMapping
-//    public AjaxResult uploadRouteInformation(@RequestBody ArdRouteInfo ArdRouteInfor) {
-//        return success(ardRouteInfoService.selectArdRouteInforByName(ArdRouteInfor.getName()));
-//    }
+    @ApiOperation("上传航线到边缘服务器")
+    @PostMapping("/uploadRouteToSixHe/{id}/{boxSn}")
+    public AjaxResult uploadRouteToSixHe(@PathVariable("id") String id,
+                                         @PathVariable("boxSn") String boxSn) {
+        return success(ardRouteInfoService.uploadRouteToSixHe(id,boxSn));
+    }
+
+    /**
+     * 开始航线
+     */
+    @ApiOperation("开始航线")
+    @PostMapping("/routeBegins/{boxSn}")
+    public AjaxResult routeBegins(@PathVariable("boxSn") String boxSn) {
+        ardRouteInfoService.routeBegins(boxSn);
+        return AjaxResult.success();
+    }
+
+    /**
+     * 暂停航线
+     */
+    @ApiOperation("暂停航线")
+    @PostMapping("/routeSuspension/{boxSn}")
+    public AjaxResult routeSuspension(@PathVariable("boxSn") String boxSn) {
+        ardRouteInfoService.routeSuspension(boxSn);
+        return AjaxResult.success();
+    }
+
+    /**
+     * 恢复航线
+     */
+    @ApiOperation("恢复航线")
+    @PostMapping("/routeResumption/{boxSn}")
+    public AjaxResult routeResumption(@PathVariable("boxSn") String boxSn) {
+        ardRouteInfoService.routeResumption(boxSn);
+        return AjaxResult.success();
+    }
+
+    /**
+     * 结束航线
+     */
+    @ApiOperation("结束航线")
+    @PostMapping("/routeEnd/{boxSn}")
+    public AjaxResult routeEnd(@PathVariable("boxSn") String boxSn) {
+        ardRouteInfoService.routeEnd(boxSn);
+        return AjaxResult.success();
+    }
 
 }
diff --git a/ard-route/pom.xml b/ard-route/pom.xml
index 34a8b9a..4bdfa32 100644
--- a/ard-route/pom.xml
+++ b/ard-route/pom.xml
@@ -55,6 +55,10 @@
             <groupId>com.ard</groupId>
             <artifactId>ard-system</artifactId>
         </dependency>
+        <dependency>
+            <groupId>com.ard</groupId>
+            <artifactId>ard-work</artifactId>
+        </dependency>
 
     </dependencies>
 
diff --git a/ard-route/src/main/java/com/ard/route/domain/sixhe/ArdRouteChange.java b/ard-route/src/main/java/com/ard/route/domain/sixhe/ArdRouteChange.java
index d5c0e87..a07414c 100644
--- a/ard-route/src/main/java/com/ard/route/domain/sixhe/ArdRouteChange.java
+++ b/ard-route/src/main/java/com/ard/route/domain/sixhe/ArdRouteChange.java
@@ -26,4 +26,8 @@
 
     private List<ArdRoutePoints> points;
 
+    private Integer securityHeight;
+
+    private Integer templateId;
+
 }
diff --git a/ard-route/src/main/java/com/ard/route/service/IArdRouteInfoService.java b/ard-route/src/main/java/com/ard/route/service/IArdRouteInfoService.java
index d50e794..19e0e1e 100644
--- a/ard-route/src/main/java/com/ard/route/service/IArdRouteInfoService.java
+++ b/ard-route/src/main/java/com/ard/route/service/IArdRouteInfoService.java
@@ -4,6 +4,8 @@
 import com.ard.oss.model.MinioUploadResult;
 import com.ard.route.domain.dto.ArdNoflyDto;
 import com.ard.route.domain.route.ArdRouteInfo;
+import com.ard.route.domain.sixhe.ArdRouteChange;
+import com.ard.work.domain.dto.wayline.WayLineUploadDTO;
 import org.springframework.web.multipart.MultipartFile;
 
 import java.util.List;
@@ -92,9 +94,51 @@
     /**
      * 判断行点是否在禁飞区
      *
-     * ardNoflyDto
+     * @param ardNoflyDto 禁飞区DTO实体类
      * @return 结果
      */
     public Boolean selectRouteInfomationNoFly(ArdNoflyDto ardNoflyDto);
 
+    /**
+     * 上传航线到边缘服务器
+     *
+     * @param id ID
+     * @param boxSn 云盒SN编号
+     * @return 结果
+     */
+    public Boolean uploadRouteToSixHe(String id, String boxSn);
+
+    /**
+     * 开始航线
+     *
+     * @param boxSn 云盒SN编号
+     * @return 结果
+     */
+    public Boolean routeBegins(String boxSn);
+
+    /**
+     * 暂停航线
+     *
+     * @param boxSn 云盒SN编号
+     * @return 结果
+     */
+    public Boolean routeSuspension(String boxSn);
+
+    /**
+     * 恢复航线
+     *
+     * @param boxSn 云盒SN编号
+     * @return 结果
+     */
+    public Boolean routeResumption(String boxSn);
+
+    /**
+     * 结束航线
+     *
+     * @param boxSn 云盒SN编号
+     * @return 结果
+     */
+    public Boolean routeEnd(String boxSn);
+
+
 }
diff --git a/ard-route/src/main/java/com/ard/route/service/impl/ArdRouteInfoServiceImpl.java b/ard-route/src/main/java/com/ard/route/service/impl/ArdRouteInfoServiceImpl.java
index 5e9122f..d2e9f34 100644
--- a/ard-route/src/main/java/com/ard/route/service/impl/ArdRouteInfoServiceImpl.java
+++ b/ard-route/src/main/java/com/ard/route/service/impl/ArdRouteInfoServiceImpl.java
@@ -1,6 +1,7 @@
 package com.ard.route.service.impl;
 
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.List;
 
 import com.ard.common.exception.ControlException;
@@ -13,13 +14,20 @@
 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.djuav.ActionGroupReq;
+import com.ard.route.domain.djuav.PointActionReq;
+import com.ard.route.domain.djuav.RoutePointReq;
 import com.ard.route.domain.djuav.UavRouteReq;
 import com.ard.route.domain.dto.ArdNoflyDto;
 import com.ard.route.domain.route.ArdRouteInfo;
+import com.ard.route.domain.sixhe.ArdRouteChange;
 import com.ard.route.domain.vo.KmzResultVo;
 import com.ard.route.mapper.ArdRouteInfoMapper;
 import com.ard.route.service.IArdRouteInfoService;
 import com.ard.route.service.UavRouteService;
+import com.ard.work.domain.dto.state.PointData;
+import com.ard.work.domain.dto.wayline.*;
+import com.ard.work.service.ITyService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.web.multipart.MultipartFile;
@@ -48,6 +56,9 @@
 
     @Resource
     private IArdNoFlyZoneService ardNoFlyZoneService;
+
+    @Resource
+    private ITyService tyService;
 
     /**
      * 查询航线(kmz)
@@ -227,6 +238,228 @@
     }
 
     /**
+     * 上传航线到边缘服务器
+     *
+     * ardNoflyDto
+     * @return 结果
+     */
+    @Override
+    public Boolean uploadRouteToSixHe(String id,String boxSn) {
+        // 1.获取航线信息
+        // 1.1通过航线数据,转换。
+        ArdRouteInfo route = ardRouteInfoMapper.selectArdRouteInfoById(id);
+        try {
+            route.setUavRouteReq((UavRouteReq) deserialize(route.getRouteData()));
+        } catch (IOException | ClassNotFoundException e) {
+            throw new RuntimeException(e);
+        }
+        // 2.将航线信息转换成对应实体类
+        WayLineUploadDTO wayLineUploadDTO = buildWayLineUploadDTO(route);
+        // 3.调用接口
+        tyService.wayLineUpload(wayLineUploadDTO);
+        return true;
+    }
+
+    /**
+     * 开始航线
+     *
+     * @param boxSn 云盒SN编号
+     * @return 结果
+     */
+    @Override
+    public Boolean routeBegins(String boxSn) {
+        WayLineBeginDTO wayLineBeginDTO = new WayLineBeginDTO(boxSn);
+        tyService.wayLineBegin(wayLineBeginDTO);
+        return true;
+    }
+
+    /**
+     * 暂停航线
+     *
+     * @param boxSn 云盒SN编号
+     * @return 结果
+     */
+    @Override
+    public Boolean routeSuspension(String boxSn) {
+        WayLinePauseDTO wayLinePauseDTO = new WayLinePauseDTO(boxSn);
+        tyService.wayLinePause(wayLinePauseDTO);
+        return true;
+    }
+
+    /**
+     * 恢复航线
+     *
+     * @param boxSn 云盒SN编号
+     * @return 结果
+     */
+    @Override
+    public Boolean routeResumption(String boxSn) {
+        WayLineResumeDTO wayLineResumeDTO = new WayLineResumeDTO(boxSn);
+        tyService.wayLineResume(wayLineResumeDTO);
+        return true;
+    }
+
+    /**
+     * 结束航线
+     *
+     * @param boxSn 云盒SN编号
+     * @return 结果
+     */
+    @Override
+    public Boolean routeEnd(String boxSn) {
+        WayLineEndDTO wayLineEndDTO = new WayLineEndDTO(boxSn);
+        tyService.wayLineEnd(wayLineEndDTO);
+        return true;
+    }
+
+    /**
+     * ArdRouteInfo实体转换,WayLineUploadDTO
+     */
+    private WayLineUploadDTO buildWayLineUploadDTO(ArdRouteInfo ardRouteInfo){
+        WayLineUploadDTO wayLineUploadDTO = new WayLineUploadDTO();
+        String finishAction = ardRouteInfo.getUavRouteReq().getFinishAction(); //1
+        Double autoFlightSpeed = ardRouteInfo.getUavRouteReq().getAutoFlightSpeed(); //15
+        Double globalTransitionalSpeed = ardRouteInfo.getUavRouteReq().getGlobalTransitionalSpeed(); //8
+        String exitOnRcLostAction = ardRouteInfo.getUavRouteReq().getExitOnRcLostAction();  //0
+
+        PlanLineData planLineData = new PlanLineData();
+
+
+
+        if (finishAction != null){
+            planLineData.setLoseAction(0);
+        }
+        if (autoFlightSpeed != null){
+            planLineData.setAutoSpeed(8);
+        }
+        if (globalTransitionalSpeed != null){
+            planLineData.setMaxSpeed(15);
+        }
+        if (exitOnRcLostAction != null){
+            planLineData.setFinishedAction(1);
+        }
+        planLineData.setHomeHeight(50);
+        planLineData.setInterests(new ArrayList<>());
+        planLineData.setIsSaveEnergyMode(0);
+        planLineData.setPoints(buildPointDataList(ardRouteInfo.getUavRouteReq()));
+
+        wayLineUploadDTO.setWayLineData(planLineData);
+        return wayLineUploadDTO;
+    }
+
+    private List<PointData> buildPointDataList(UavRouteReq uavRouteReq){
+        List<PointData> pointDataList = new ArrayList<>();
+        for (RoutePointReq routePointReq : uavRouteReq.getRoutePointList()) {
+            PointData pointData = new PointData();
+
+            Integer routePointIndex = routePointReq.getRoutePointIndex();
+            if (routePointIndex != null){
+                pointData.setGroupIndex(routePointIndex);
+            }
+            Double height = routePointReq.getHeight();
+            if (height != null){
+                pointData.setHeight(height.floatValue());
+            }
+            Double longitude = routePointReq.getLatitude();
+            if (longitude != null){
+                pointData.setLng(longitude.floatValue());
+            }
+            Double latitude = routePointReq.getLongitude();
+            if (latitude != null){
+                pointData.setLat(latitude.floatValue());
+            }
+            Double speed = routePointReq.getSpeed();
+            if (speed != null){
+                pointData.setSpeed(speed.floatValue());
+            }
+            pointData.setDampingDistance(0);
+            pointData.setFlightPathMode(1);
+            pointData.setHeading(0);
+            pointData.setHeadingMode(0);
+            pointData.setInterestIndex(-1);
+            pointData.setSafeGohomeFlag(0);
+            pointData.setActions(buildPointActionList(routePointReq.getActionGroupList()));
+            pointDataList.add(pointData);
+
+        }
+        return pointDataList;
+    }
+
+    private List<PointAction> buildPointActionList(List<ActionGroupReq> actionGroupList){
+        List<PointAction> pointActionList = new ArrayList<>();
+        for (ActionGroupReq actionGroupReq : actionGroupList) {
+            for (PointActionReq action : actionGroupReq.getActions()) {
+                PointAction pointAction = typeProcessing(action);
+                pointActionList.add(pointAction);
+            }
+        }
+        return pointActionList;
+    }
+
+    private PointAction typeProcessing(PointActionReq pointActionReq){
+        PointAction pointAction = new PointAction();
+
+        if (pointActionReq.getZoom() != null){
+            pointAction.setType(1);
+            pointAction.setParam(pointActionReq.getZoom().floatValue());
+            pointAction.setSpeakInfo("");
+            pointAction.setWaitTime(2);
+        }
+
+        if (pointActionReq.getTakePhotoType() != null){
+            pointAction.setType(2);
+            pointAction.setParam(1);
+            pointAction.setSpeakInfo("");
+            pointAction.setWaitTime(2);
+        }
+
+        if (pointActionReq.getStartRecord() != null){
+            pointAction.setType(3);
+            pointAction.setParam(1);
+            pointAction.setSpeakInfo("");
+            pointAction.setWaitTime(2);
+        }
+
+        if (pointActionReq.getStopRecord() != null){
+            pointAction.setType(4);
+            pointAction.setParam(1);
+            pointAction.setSpeakInfo("");
+            pointAction.setWaitTime(2);
+        }
+
+        if (pointActionReq.getAircraftHeading() != null){
+            pointAction.setType(5);
+            pointAction.setParam(pointActionReq.getAircraftHeading().floatValue());
+            pointAction.setSpeakInfo("");
+            pointAction.setWaitTime(2);
+        }
+
+        if (pointActionReq.getGimbalPitchRotateAngle() != null){
+            pointAction.setType(6);
+            pointAction.setParam(pointActionReq.getGimbalPitchRotateAngle().floatValue());
+            pointAction.setSpeakInfo("");
+            pointAction.setWaitTime(2);
+        }
+
+        if (pointActionReq.getGimbalYawRotateAngle() != null){
+            pointAction.setType(7);
+            pointAction.setParam(pointActionReq.getGimbalYawRotateAngle().floatValue());
+            pointAction.setSpeakInfo("");
+            pointAction.setWaitTime(2);
+        }
+
+        if (pointActionReq.getHoverTime() != null){
+            pointAction.setType(9);
+            pointAction.setParam(pointActionReq.getHoverTime().floatValue());
+            pointAction.setSpeakInfo("");
+            pointAction.setWaitTime(2);
+        }
+
+        return pointAction;
+
+    }
+
+    /**
      * 数据新增航线信息
      */
     private void insertRouteInfomation(ArdRouteInfo ardRouteInfo){
diff --git a/ard-route/src/main/java/com/ard/route/util/InitializationUtils.java b/ard-route/src/main/java/com/ard/route/util/InitializationUtils.java
index 54807db..f630224 100644
--- a/ard-route/src/main/java/com/ard/route/util/InitializationUtils.java
+++ b/ard-route/src/main/java/com/ard/route/util/InitializationUtils.java
@@ -80,40 +80,137 @@
         ardRouteChange.setIsSaveEnergyMode(0);
         ardRouteChange.setLoseAction(0);
         ardRouteChange.setMaxSpeed(15);
+        ardRouteChange.setSecurityHeight(50);
+        ardRouteChange.setTemplateId(0);
 
         List<ArdRoutePoints> points = new ArrayList<>();
-        ArdRoutePoints ardRoutePoints0 = new ArdRoutePoints();
-        ardRoutePoints0.setDampingDistance(0);
-        ardRoutePoints0.setFlightPathMode(1);
-        ardRoutePoints0.setGroupIndex(0);
-        ardRoutePoints0.setHeading(0);
-        ardRoutePoints0.setHeadingMode(0);
-        ardRoutePoints0.setHeight(50);
-        ardRoutePoints0.setInterestIndex(0);
-        ardRoutePoints0.setLat(31.11339916);
-        ardRoutePoints0.setLon(103.75851462);
-        ardRoutePoints0.setSafeGohomeFlag(0);
-        ardRoutePoints0.setSpeed(8);
-        List<ArdRouteActions> actions = new ArrayList<>();
-        ArdRouteActions ardRouteActions0 = new ArdRouteActions();
-        ardRouteActions0.setParam(10);
-        ardRouteActions0.setSpeakInfo("");
-        ardRouteActions0.setType(1);
-        ardRouteActions0.setWaitTime(2);
-        ArdRouteActions ardRouteActions1 = new ArdRouteActions();
-        ardRouteActions1.setParam(10);
-        ardRouteActions1.setSpeakInfo("");
-        ardRouteActions1.setType(1);
-        ardRouteActions1.setWaitTime(2);
-        ArdRouteActions ardRouteActions2 = new ArdRouteActions();
-        ardRouteActions2.setParam(10);
-        ardRouteActions2.setSpeakInfo("");
-        ardRouteActions2.setType(1);
-        ardRouteActions2.setWaitTime(2);
-        actions.add(ardRouteActions0);
-        actions.add(ardRouteActions1);
-        actions.add(ardRouteActions2);
-        points.add(ardRoutePoints0);
+        //-----------------------------------------------------
+        ArdRoutePoints ardRoutePoints00 = new ArdRoutePoints();
+        ardRoutePoints00.setDampingDistance(0);
+        ardRoutePoints00.setFlightPathMode(1);
+        ardRoutePoints00.setGroupIndex(0);
+        ardRoutePoints00.setHeading(0);
+        ardRoutePoints00.setHeadingMode(0);
+        ardRoutePoints00.setHeight(50);
+        ardRoutePoints00.setInterestIndex(-1);
+        ardRoutePoints00.setLat(31.11339916);
+        ardRoutePoints00.setLon(103.75851462);
+        ardRoutePoints00.setSafeGohomeFlag(0);
+        ardRoutePoints00.setSpeed(8);
+        List<ArdRouteActions> actions00 = new ArrayList<>();
+        ArdRouteActions ardRouteActions00 = new ArdRouteActions();
+        ardRouteActions00.setParam(10);
+        ardRouteActions00.setSpeakInfo("");
+        ardRouteActions00.setType(1);
+        ardRouteActions00.setWaitTime(2);
+        ArdRouteActions ardRouteActions01 = new ArdRouteActions();
+        ardRouteActions01.setParam(10);
+        ardRouteActions01.setSpeakInfo("");
+        ardRouteActions01.setType(1);
+        ardRouteActions01.setWaitTime(2);
+        ArdRouteActions ardRouteActions02 = new ArdRouteActions();
+        ardRouteActions02.setParam(10);
+        ardRouteActions02.setSpeakInfo("");
+        ardRouteActions02.setType(1);
+        ardRouteActions02.setWaitTime(2);
+        actions00.add(ardRouteActions00);
+        actions00.add(ardRouteActions01);
+        actions00.add(ardRouteActions02);
+        ardRoutePoints00.setActions(actions00);
+
+        //-----------------------------------------------------
+        ArdRoutePoints ardRoutePoints10 = new ArdRoutePoints();
+        ardRoutePoints10.setDampingDistance(0);
+        ardRoutePoints10.setFlightPathMode(1);
+        ardRoutePoints10.setGroupIndex(0);
+        ardRoutePoints10.setHeading(0);
+        ardRoutePoints10.setHeadingMode(0);
+        ardRoutePoints10.setHeight(50);
+        ardRoutePoints10.setInterestIndex(-1);
+        ardRoutePoints10.setLat(31.11339916);
+        ardRoutePoints10.setLon(103.75746538);
+        ardRoutePoints10.setSafeGohomeFlag(0);
+        ardRoutePoints10.setSpeed(8);
+        List<ArdRouteActions> actions10 = new ArrayList<>();
+        ArdRouteActions ardRouteActions10 = new ArdRouteActions();
+        ardRouteActions10.setParam(20);
+        ardRouteActions10.setSpeakInfo("");
+        ardRouteActions10.setType(9);
+        ardRouteActions10.setWaitTime(2);
+        ArdRouteActions ardRouteActions11 = new ArdRouteActions();
+        ardRouteActions11.setParam(40);
+        ardRouteActions11.setSpeakInfo("");
+        ardRouteActions11.setType(6);
+        ardRouteActions11.setWaitTime(2);
+        ArdRouteActions ardRouteActions12 = new ArdRouteActions();
+        ardRouteActions12.setParam(40);
+        ardRouteActions12.setSpeakInfo("");
+        ardRouteActions12.setType(7);
+        ardRouteActions12.setWaitTime(2);
+        ArdRouteActions ardRouteActions13 = new ArdRouteActions();
+        ardRouteActions13.setParam(40);
+        ardRouteActions13.setSpeakInfo("");
+        ardRouteActions13.setType(8);
+        ardRouteActions13.setWaitTime(2);
+        actions10.add(ardRouteActions10);
+        actions10.add(ardRouteActions11);
+        actions10.add(ardRouteActions12);
+        ardRoutePoints10.setActions(actions10);
+
+        //-----------------------------------------------------
+        ArdRoutePoints ardRoutePoints20 = new ArdRoutePoints();
+        ardRoutePoints20.setDampingDistance(0);
+        ardRoutePoints20.setFlightPathMode(1);
+        ardRoutePoints20.setGroupIndex(0);
+        ardRoutePoints20.setHeading(0);
+        ardRoutePoints20.setHeadingMode(0);
+        ardRoutePoints20.setHeight(50);
+        ardRoutePoints20.setInterestIndex(-1);
+        ardRoutePoints20.setLat(31.11250084);
+        ardRoutePoints20.setLon(103.75746538);
+        ardRoutePoints20.setSafeGohomeFlag(0);
+        ardRoutePoints20.setSpeed(8);
+        List<ArdRouteActions> actions20 = new ArrayList<>();
+        ArdRouteActions ardRouteActions20 = new ArdRouteActions();
+        ardRouteActions20.setParam(15);
+        ardRouteActions20.setSpeakInfo("");
+        ardRouteActions20.setType(9);
+        ardRouteActions20.setWaitTime(2);
+        ArdRouteActions ardRouteActions21 = new ArdRouteActions();
+        ardRouteActions21.setParam(3);
+        ardRouteActions21.setSpeakInfo("");
+        ardRouteActions21.setType(10);
+        ardRouteActions21.setWaitTime(2);
+        actions20.add(ardRouteActions20);
+        actions20.add(ardRouteActions21);
+        ardRoutePoints20.setActions(actions20);
+
+        //-----------------------------------------------------
+        ArdRoutePoints ardRoutePoints30 = new ArdRoutePoints();
+        ardRoutePoints30.setDampingDistance(0);
+        ardRoutePoints30.setFlightPathMode(1);
+        ardRoutePoints30.setGroupIndex(0);
+        ardRoutePoints30.setHeading(0);
+        ardRoutePoints30.setHeadingMode(0);
+        ardRoutePoints30.setHeight(60);
+        ardRoutePoints30.setInterestIndex(-1);
+        ardRoutePoints30.setLat(31.11250084);
+        ardRoutePoints30.setLon(103.75851462);
+        ardRoutePoints30.setSafeGohomeFlag(0);
+        ardRoutePoints30.setSpeed(8);
+        List<ArdRouteActions> actions30 = new ArrayList<>();
+        ArdRouteActions ardRouteActions30 = new ArdRouteActions();
+        ardRouteActions30.setParam(1);
+        ardRouteActions30.setSpeakInfo("");
+        ardRouteActions30.setType(2);
+        ardRouteActions30.setWaitTime(2);
+        actions30.add(ardRouteActions30);
+        ardRoutePoints30.setActions(actions30);
+
+        points.add(ardRoutePoints00);
+        points.add(ardRoutePoints10);
+        points.add(ardRoutePoints20);
+        points.add(ardRoutePoints30);
 
         ardRouteChange.setPoints(points);
     }
diff --git a/ard-work/pom.xml b/ard-work/pom.xml
index ef3f0a4..6ec0789 100644
--- a/ard-work/pom.xml
+++ b/ard-work/pom.xml
@@ -113,6 +113,15 @@
             <groupId>com.ard</groupId>
             <artifactId>ard-oss</artifactId>
         </dependency>
+        <!-- JavaCV 核心(非常小) -->
+        <dependency>
+            <groupId>org.bytedeco</groupId>
+            <artifactId>javacv</artifactId>
+            <version>1.5.8</version>
+        </dependency>
+
+
+
     </dependencies>
     <repositories>
         <repository>
diff --git a/ard-work/src/main/java/com/ard/work/component/netty/command/camera/CameraModeCmd.java b/ard-work/src/main/java/com/ard/work/component/netty/command/camera/CameraModeCmd.java
index 8f198e0..11f4ccd 100644
--- a/ard-work/src/main/java/com/ard/work/component/netty/command/camera/CameraModeCmd.java
+++ b/ard-work/src/main/java/com/ard/work/component/netty/command/camera/CameraModeCmd.java
@@ -4,6 +4,7 @@
 import com.ard.work.component.netty.command.BaseCmd;
 import io.netty.buffer.ByteBuf;
 import lombok.Data;
+import lombok.EqualsAndHashCode;
 
 /**
  * 设置相机模式指令
@@ -11,6 +12,7 @@
  * @author liusuyi
  * @date 2024年10月25日14:44
  **/
+@EqualsAndHashCode(callSuper = true)
 @Data
 public class CameraModeCmd extends BaseCmd {
     private final byte encryptFlag = 0x00; // 加密标志
diff --git a/ard-work/src/main/java/com/ard/work/component/netty/command/camera/CameraModeReplyCmd.java b/ard-work/src/main/java/com/ard/work/component/netty/command/camera/CameraModeReplyCmd.java
index dcbb831..f70fa96 100644
--- a/ard-work/src/main/java/com/ard/work/component/netty/command/camera/CameraModeReplyCmd.java
+++ b/ard-work/src/main/java/com/ard/work/component/netty/command/camera/CameraModeReplyCmd.java
@@ -3,6 +3,7 @@
 import com.ard.work.component.netty.command.BaseCmd;
 import io.netty.buffer.ByteBuf;
 import lombok.Data;
+import lombok.EqualsAndHashCode;
 
 /**
  * 设置相机模式回复指令
@@ -10,6 +11,7 @@
  * @author liusuyi
  * @date 2024年10月25日14:44
  **/
+@EqualsAndHashCode(callSuper = true)
 @Data
 public class CameraModeReplyCmd extends BaseCmd {
     private final byte encryptFlag = 0x00; // 加密标志
diff --git a/ard-work/src/main/java/com/ard/work/component/netty/command/camera/CapturePicCmd.java b/ard-work/src/main/java/com/ard/work/component/netty/command/camera/CapturePicCmd.java
index a2e17b3..faa4396 100644
--- a/ard-work/src/main/java/com/ard/work/component/netty/command/camera/CapturePicCmd.java
+++ b/ard-work/src/main/java/com/ard/work/component/netty/command/camera/CapturePicCmd.java
@@ -4,6 +4,7 @@
 import com.ard.work.component.netty.command.BaseCmd;
 import io.netty.buffer.ByteBuf;
 import lombok.Data;
+import lombok.EqualsAndHashCode;
 
 /**
  * 抓拍指令
@@ -11,6 +12,7 @@
  * @author liusuyi
  * @date 2024年10月25日14:44
  **/
+@EqualsAndHashCode(callSuper = true)
 @Data
 public class CapturePicCmd extends BaseCmd {
     private final byte encryptFlag = 0x00; // 加密标志
diff --git a/ard-work/src/main/java/com/ard/work/component/netty/command/camera/CapturePicReplyCmd.java b/ard-work/src/main/java/com/ard/work/component/netty/command/camera/CapturePicReplyCmd.java
index 3c40f4f..09c4768 100644
--- a/ard-work/src/main/java/com/ard/work/component/netty/command/camera/CapturePicReplyCmd.java
+++ b/ard-work/src/main/java/com/ard/work/component/netty/command/camera/CapturePicReplyCmd.java
@@ -3,6 +3,7 @@
 import com.ard.work.component.netty.command.BaseCmd;
 import io.netty.buffer.ByteBuf;
 import lombok.Data;
+import lombok.EqualsAndHashCode;
 
 /**
  * 抓拍回复指令
@@ -10,6 +11,7 @@
  * @author liusuyi
  * @date 2024年10月25日14:44
  **/
+@EqualsAndHashCode(callSuper = true)
 @Data
 public class CapturePicReplyCmd extends BaseCmd {
     private final byte encryptFlag = 0x00; // 加密标志
diff --git a/ard-work/src/main/java/com/ard/work/component/netty/command/camera/PhotoReturnToggleCmd.java b/ard-work/src/main/java/com/ard/work/component/netty/command/camera/PhotoReturnToggleCmd.java
index 0ec1cf5..6b55d41 100644
--- a/ard-work/src/main/java/com/ard/work/component/netty/command/camera/PhotoReturnToggleCmd.java
+++ b/ard-work/src/main/java/com/ard/work/component/netty/command/camera/PhotoReturnToggleCmd.java
@@ -4,6 +4,7 @@
 import com.ard.work.component.netty.command.BaseCmd;
 import io.netty.buffer.ByteBuf;
 import lombok.Data;
+import lombok.EqualsAndHashCode;
 
 /**
  * 打开或关闭照片回传指令
@@ -11,6 +12,7 @@
  * @author liusuyi
  * @date 2024年10月25日14:44
  **/
+@EqualsAndHashCode(callSuper = true)
 @Data
 public class PhotoReturnToggleCmd extends BaseCmd {
     private final byte encryptFlag = 0x00;      // 加密标志
diff --git a/ard-work/src/main/java/com/ard/work/component/netty/command/camera/PicUploadCompletedReplyCmd.java b/ard-work/src/main/java/com/ard/work/component/netty/command/camera/PicUploadCompletedReplyCmd.java
index 11bae54..bd049d6 100644
--- a/ard-work/src/main/java/com/ard/work/component/netty/command/camera/PicUploadCompletedReplyCmd.java
+++ b/ard-work/src/main/java/com/ard/work/component/netty/command/camera/PicUploadCompletedReplyCmd.java
@@ -3,6 +3,7 @@
 import com.ard.work.component.netty.command.BaseCmd;
 import io.netty.buffer.ByteBuf;
 import lombok.Data;
+import lombok.EqualsAndHashCode;
 
 import java.nio.charset.StandardCharsets;
 
@@ -12,6 +13,7 @@
  * @author liusuyi
  * @date 2024年10月26日11:54
  **/
+@EqualsAndHashCode(callSuper = true)
 @Data
 public class PicUploadCompletedReplyCmd extends BaseCmd {
     private final byte encryptFlag = 0x00;  // 加密标志
diff --git a/ard-work/src/main/java/com/ard/work/component/netty/command/camera/RecordStartCmd.java b/ard-work/src/main/java/com/ard/work/component/netty/command/camera/RecordStartCmd.java
index 7d9316a..0619869 100644
--- a/ard-work/src/main/java/com/ard/work/component/netty/command/camera/RecordStartCmd.java
+++ b/ard-work/src/main/java/com/ard/work/component/netty/command/camera/RecordStartCmd.java
@@ -4,6 +4,7 @@
 import com.ard.work.component.netty.command.BaseCmd;
 import io.netty.buffer.ByteBuf;
 import lombok.Data;
+import lombok.EqualsAndHashCode;
 
 /**
  * 开始录像指令
@@ -12,6 +13,7 @@
  * @date 2024年10月25日14:44
  **/
 @Data
+@EqualsAndHashCode(callSuper = false)
 public class RecordStartCmd extends BaseCmd {
     private final byte encryptFlag = 0x00; // 加密标志
     private final byte actionCode=0x24;    // 动作编号
diff --git a/ard-work/src/main/java/com/ard/work/component/netty/command/camera/RecordStartReplyCmd.java b/ard-work/src/main/java/com/ard/work/component/netty/command/camera/RecordStartReplyCmd.java
index eb8a998..26265ce 100644
--- a/ard-work/src/main/java/com/ard/work/component/netty/command/camera/RecordStartReplyCmd.java
+++ b/ard-work/src/main/java/com/ard/work/component/netty/command/camera/RecordStartReplyCmd.java
@@ -3,6 +3,7 @@
 import com.ard.work.component.netty.command.BaseCmd;
 import io.netty.buffer.ByteBuf;
 import lombok.Data;
+import lombok.EqualsAndHashCode;
 
 /**
  * 开始录像回复指令
@@ -10,6 +11,7 @@
  * @author liusuyi
  * @date 2024年10月25日14:44
  **/
+@EqualsAndHashCode(callSuper = true)
 @Data
 public class RecordStartReplyCmd extends BaseCmd {
     private final byte encryptFlag = 0x00; // 加密标志
diff --git a/ard-work/src/main/java/com/ard/work/component/netty/command/camera/RecordStopCmd.java b/ard-work/src/main/java/com/ard/work/component/netty/command/camera/RecordStopCmd.java
index 5f2f5f5..a7279d9 100644
--- a/ard-work/src/main/java/com/ard/work/component/netty/command/camera/RecordStopCmd.java
+++ b/ard-work/src/main/java/com/ard/work/component/netty/command/camera/RecordStopCmd.java
@@ -4,6 +4,7 @@
 import com.ard.work.component.netty.command.BaseCmd;
 import io.netty.buffer.ByteBuf;
 import lombok.Data;
+import lombok.EqualsAndHashCode;
 
 /**
  * 停止录像指令
@@ -11,6 +12,7 @@
  * @author liusuyi
  * @date 2024年10月25日14:44
  **/
+@EqualsAndHashCode(callSuper = true)
 @Data
 public class RecordStopCmd extends BaseCmd {
     private final byte encryptFlag = 0x00; // 加密标志
diff --git a/ard-work/src/main/java/com/ard/work/component/netty/command/camera/RecordStopReplyCmd.java b/ard-work/src/main/java/com/ard/work/component/netty/command/camera/RecordStopReplyCmd.java
index 2af84e0..f71c6b9 100644
--- a/ard-work/src/main/java/com/ard/work/component/netty/command/camera/RecordStopReplyCmd.java
+++ b/ard-work/src/main/java/com/ard/work/component/netty/command/camera/RecordStopReplyCmd.java
@@ -3,6 +3,7 @@
 import com.ard.work.component.netty.command.BaseCmd;
 import io.netty.buffer.ByteBuf;
 import lombok.Data;
+import lombok.EqualsAndHashCode;
 
 /**
  * 停止录像回复指令
@@ -10,6 +11,7 @@
  * @author liusuyi
  * @date 2024年10月25日14:44
  **/
+@EqualsAndHashCode(callSuper = true)
 @Data
 public class RecordStopReplyCmd extends BaseCmd {
     private final byte encryptFlag = 0x00; // 加密标志
diff --git a/ard-work/src/main/java/com/ard/work/component/netty/command/camera/ZoomCmd.java b/ard-work/src/main/java/com/ard/work/component/netty/command/camera/ZoomCmd.java
index b98dc35..d956c79 100644
--- a/ard-work/src/main/java/com/ard/work/component/netty/command/camera/ZoomCmd.java
+++ b/ard-work/src/main/java/com/ard/work/component/netty/command/camera/ZoomCmd.java
@@ -4,6 +4,7 @@
 import com.ard.work.component.netty.command.BaseCmd;
 import io.netty.buffer.ByteBuf;
 import lombok.Data;
+import lombok.EqualsAndHashCode;
 
 /**
  * 变倍指令
@@ -12,6 +13,7 @@
  * @date 2024年10月25日14:44
  **/
 @Data
+@EqualsAndHashCode(callSuper = false)
 public class ZoomCmd extends BaseCmd {
     private final byte encryptFlag = 0x00; // 加密标志
     private final byte actionCode;  // 动作编号
diff --git a/ard-work/src/main/java/com/ard/work/component/netty/command/camera/ZoomToLevelCmd.java b/ard-work/src/main/java/com/ard/work/component/netty/command/camera/ZoomToLevelCmd.java
index 010e2bb..7bf424c 100644
--- a/ard-work/src/main/java/com/ard/work/component/netty/command/camera/ZoomToLevelCmd.java
+++ b/ard-work/src/main/java/com/ard/work/component/netty/command/camera/ZoomToLevelCmd.java
@@ -4,6 +4,7 @@
 import com.ard.work.component.netty.command.BaseCmd;
 import io.netty.buffer.ByteBuf;
 import lombok.Data;
+import lombok.EqualsAndHashCode;
 
 /**
  * 变倍到指定倍数指令
@@ -11,6 +12,7 @@
  * @author liusuyi
  * @date 2024年10月25日14:44
  **/
+@EqualsAndHashCode(callSuper = true)
 @Data
 public class ZoomToLevelCmd extends BaseCmd {
     private final byte encryptFlag = 0x00; // 加密标志
diff --git a/ard-work/src/main/java/com/ard/work/component/netty/command/control/AbsAngleControlCmd.java b/ard-work/src/main/java/com/ard/work/component/netty/command/control/AbsAngleControlCmd.java
index 09d85d7..d3d8706 100644
--- a/ard-work/src/main/java/com/ard/work/component/netty/command/control/AbsAngleControlCmd.java
+++ b/ard-work/src/main/java/com/ard/work/component/netty/command/control/AbsAngleControlCmd.java
@@ -4,6 +4,7 @@
 import com.ard.work.component.netty.command.BaseCmd;
 import io.netty.buffer.ByteBuf;
 import lombok.Data;
+import lombok.EqualsAndHashCode;
 
 /**
  * 云台绝对值控制(基于角度)命令
@@ -13,6 +14,7 @@
  */
 
 @Data
+@EqualsAndHashCode(callSuper = false)
 public class AbsAngleControlCmd extends BaseCmd {
     private final byte encryptFlag = 0x00; // 加密标志
     private final byte actionCode = 0x09;  // 动作编号
diff --git a/ard-work/src/main/java/com/ard/work/component/netty/command/control/AngleControlCmd.java b/ard-work/src/main/java/com/ard/work/component/netty/command/control/AngleControlCmd.java
index d9a86d3..58452c3 100644
--- a/ard-work/src/main/java/com/ard/work/component/netty/command/control/AngleControlCmd.java
+++ b/ard-work/src/main/java/com/ard/work/component/netty/command/control/AngleControlCmd.java
@@ -4,6 +4,7 @@
 import com.ard.work.component.netty.command.BaseCmd;
 import io.netty.buffer.ByteBuf;
 import lombok.Data;
+import lombok.EqualsAndHashCode;
 
 /**
  * 云台转动(基于角度)命令
@@ -13,6 +14,7 @@
  */
 
 @Data
+@EqualsAndHashCode(callSuper = false)
 public class AngleControlCmd extends BaseCmd {
     private final byte encryptFlag = 0x00; // 加密标志
     private final byte actionCode; // 动作编号
diff --git a/ard-work/src/main/java/com/ard/work/component/netty/command/control/SpeedControlCmd.java b/ard-work/src/main/java/com/ard/work/component/netty/command/control/SpeedControlCmd.java
index 466a167..d929bf5 100644
--- a/ard-work/src/main/java/com/ard/work/component/netty/command/control/SpeedControlCmd.java
+++ b/ard-work/src/main/java/com/ard/work/component/netty/command/control/SpeedControlCmd.java
@@ -4,6 +4,7 @@
 import com.ard.work.component.netty.command.BaseCmd;
 import io.netty.buffer.ByteBuf;
 import lombok.Data;
+import lombok.EqualsAndHashCode;
 
 /**
  * 云台绝对值控制(基于角度)命令
@@ -12,6 +13,7 @@
  * @date 2024/10/22 16:36
  */
 
+@EqualsAndHashCode(callSuper = true)
 @Data
 public class SpeedControlCmd extends BaseCmd {
     private final byte encryptFlag = 0x00;          // 加密标志
diff --git a/ard-work/src/main/java/com/ard/work/component/netty/command/manual/EmergencyBrakeReplyCmd.java b/ard-work/src/main/java/com/ard/work/component/netty/command/manual/EmergencyBrakeReplyCmd.java
index dab5069..2565c3a 100644
--- a/ard-work/src/main/java/com/ard/work/component/netty/command/manual/EmergencyBrakeReplyCmd.java
+++ b/ard-work/src/main/java/com/ard/work/component/netty/command/manual/EmergencyBrakeReplyCmd.java
@@ -3,6 +3,7 @@
 import com.ard.work.component.netty.command.BaseCmd;
 import io.netty.buffer.ByteBuf;
 import lombok.Data;
+import lombok.EqualsAndHashCode;
 
 /**
  * 紧急制动回复指令
@@ -10,6 +11,7 @@
  * @author liusuyi
  * @date 2024年10月30日16:20
  **/
+@EqualsAndHashCode(callSuper = true)
 @Data
 public class EmergencyBrakeReplyCmd extends BaseCmd {
 
diff --git a/ard-work/src/main/java/com/ard/work/component/netty/command/manual/LandCancelReplyCmd.java b/ard-work/src/main/java/com/ard/work/component/netty/command/manual/LandCancelReplyCmd.java
index 9a3c0b5..807cb3b 100644
--- a/ard-work/src/main/java/com/ard/work/component/netty/command/manual/LandCancelReplyCmd.java
+++ b/ard-work/src/main/java/com/ard/work/component/netty/command/manual/LandCancelReplyCmd.java
@@ -3,6 +3,7 @@
 import com.ard.work.component.netty.command.BaseCmd;
 import io.netty.buffer.ByteBuf;
 import lombok.Data;
+import lombok.EqualsAndHashCode;
 
 /**
  * 取消降落回复指令
@@ -11,6 +12,7 @@
  * @date 2024年10月26日15:43
  **/
 @Data
+@EqualsAndHashCode(callSuper = false)
 public class LandCancelReplyCmd extends BaseCmd {
 
     private final byte encryptFlag = 0x00; // 加密标志
diff --git a/ard-work/src/main/java/com/ard/work/component/netty/command/manual/LandForcedReplyCmd.java b/ard-work/src/main/java/com/ard/work/component/netty/command/manual/LandForcedReplyCmd.java
index f25eba5..e0c4b34 100644
--- a/ard-work/src/main/java/com/ard/work/component/netty/command/manual/LandForcedReplyCmd.java
+++ b/ard-work/src/main/java/com/ard/work/component/netty/command/manual/LandForcedReplyCmd.java
@@ -3,6 +3,7 @@
 import com.ard.work.component.netty.command.BaseCmd;
 import io.netty.buffer.ByteBuf;
 import lombok.Data;
+import lombok.EqualsAndHashCode;
 
 /**
  * 强制降落回复指令
@@ -10,6 +11,7 @@
  * @author liusuyi
  * @date 2024年10月26日15:43
  **/
+@EqualsAndHashCode(callSuper = true)
 @Data
 public class LandForcedReplyCmd extends BaseCmd {
 
diff --git a/ard-work/src/main/java/com/ard/work/component/netty/command/manual/LandReplyCmd.java b/ard-work/src/main/java/com/ard/work/component/netty/command/manual/LandReplyCmd.java
index f09dd68..a2d0c9f 100644
--- a/ard-work/src/main/java/com/ard/work/component/netty/command/manual/LandReplyCmd.java
+++ b/ard-work/src/main/java/com/ard/work/component/netty/command/manual/LandReplyCmd.java
@@ -3,6 +3,7 @@
 import com.ard.work.component.netty.command.BaseCmd;
 import io.netty.buffer.ByteBuf;
 import lombok.Data;
+import lombok.EqualsAndHashCode;
 
 /**
  * 降落回复指令
@@ -10,6 +11,7 @@
  * @author liusuyi
  * @date 2024年10月26日15:43
  **/
+@EqualsAndHashCode(callSuper = true)
 @Data
 public class LandReplyCmd extends BaseCmd {
 
diff --git a/ard-work/src/main/java/com/ard/work/component/netty/command/manual/PointControlReachedReplyCmd.java b/ard-work/src/main/java/com/ard/work/component/netty/command/manual/PointControlReachedReplyCmd.java
index 407eeea..8986ff9 100644
--- a/ard-work/src/main/java/com/ard/work/component/netty/command/manual/PointControlReachedReplyCmd.java
+++ b/ard-work/src/main/java/com/ard/work/component/netty/command/manual/PointControlReachedReplyCmd.java
@@ -3,6 +3,7 @@
 import com.ard.work.component.netty.command.BaseCmd;
 import io.netty.buffer.ByteBuf;
 import lombok.Data;
+import lombok.EqualsAndHashCode;
 
 /**
  * 到达指点飞行位置回复指令
@@ -10,6 +11,7 @@
  * @author liusuyi
  * @date 2024年10月26日15:43
  **/
+@EqualsAndHashCode(callSuper = true)
 @Data
 public class PointControlReachedReplyCmd extends BaseCmd {
 
diff --git a/ard-work/src/main/java/com/ard/work/component/netty/command/manual/ReturnHomeCancelReplyCmd.java b/ard-work/src/main/java/com/ard/work/component/netty/command/manual/ReturnHomeCancelReplyCmd.java
index 487b476..9fc3e0e 100644
--- a/ard-work/src/main/java/com/ard/work/component/netty/command/manual/ReturnHomeCancelReplyCmd.java
+++ b/ard-work/src/main/java/com/ard/work/component/netty/command/manual/ReturnHomeCancelReplyCmd.java
@@ -3,6 +3,7 @@
 import com.ard.work.component.netty.command.BaseCmd;
 import io.netty.buffer.ByteBuf;
 import lombok.Data;
+import lombok.EqualsAndHashCode;
 
 /**
  * 取消返航回复指令
@@ -11,6 +12,7 @@
  * @date 2024年10月26日15:43
  **/
 @Data
+@EqualsAndHashCode(callSuper = false)
 public class ReturnHomeCancelReplyCmd extends BaseCmd {
 
     private final byte encryptFlag = 0x00; // 加密标志
diff --git a/ard-work/src/main/java/com/ard/work/component/netty/command/manual/ReturnHomeReplyCmd.java b/ard-work/src/main/java/com/ard/work/component/netty/command/manual/ReturnHomeReplyCmd.java
index 1c6d082..8fc2bd7 100644
--- a/ard-work/src/main/java/com/ard/work/component/netty/command/manual/ReturnHomeReplyCmd.java
+++ b/ard-work/src/main/java/com/ard/work/component/netty/command/manual/ReturnHomeReplyCmd.java
@@ -3,6 +3,7 @@
 import com.ard.work.component.netty.command.BaseCmd;
 import io.netty.buffer.ByteBuf;
 import lombok.Data;
+import lombok.EqualsAndHashCode;
 
 /**
  * 返航回复指令
@@ -10,6 +11,7 @@
  * @author liusuyi
  * @date 2024年10月26日15:43
  **/
+@EqualsAndHashCode(callSuper = true)
 @Data
 public class ReturnHomeReplyCmd extends BaseCmd {
 
diff --git a/ard-work/src/main/java/com/ard/work/component/netty/command/manual/TakeOffReplyCmd.java b/ard-work/src/main/java/com/ard/work/component/netty/command/manual/TakeOffReplyCmd.java
index 53387c2..13ee4af 100644
--- a/ard-work/src/main/java/com/ard/work/component/netty/command/manual/TakeOffReplyCmd.java
+++ b/ard-work/src/main/java/com/ard/work/component/netty/command/manual/TakeOffReplyCmd.java
@@ -3,6 +3,7 @@
 import com.ard.work.component.netty.command.BaseCmd;
 import io.netty.buffer.ByteBuf;
 import lombok.Data;
+import lombok.EqualsAndHashCode;
 
 /**
  * 起飞回复指令
@@ -10,6 +11,7 @@
  * @author liusuyi
  * @date 2024年10月26日15:43
  **/
+@EqualsAndHashCode(callSuper = true)
 @Data
 public class TakeOffReplyCmd extends BaseCmd {
     private final byte encryptFlag = 0x00; // 加密标志
diff --git a/ard-work/src/main/java/com/ard/work/component/netty/command/notice/BoxPowerStatusReplyCmd.java b/ard-work/src/main/java/com/ard/work/component/netty/command/notice/BoxPowerStatusReplyCmd.java
index 5b87f8d..df28612 100644
--- a/ard-work/src/main/java/com/ard/work/component/netty/command/notice/BoxPowerStatusReplyCmd.java
+++ b/ard-work/src/main/java/com/ard/work/component/netty/command/notice/BoxPowerStatusReplyCmd.java
@@ -3,6 +3,7 @@
 import com.ard.work.component.netty.command.BaseCmd;
 import io.netty.buffer.ByteBuf;
 import lombok.Data;
+import lombok.EqualsAndHashCode;
 
 /**
  * 云盒开关机通知回复指令
@@ -11,6 +12,7 @@
  * @date 2024年10月26日11:54
  **/
 @Data
+@EqualsAndHashCode(callSuper = false)
 public class BoxPowerStatusReplyCmd extends BaseCmd {
     private final byte status; // 时间戳
 
diff --git a/ard-work/src/main/java/com/ard/work/component/netty/command/notice/FlyWayEndReplyCmd.java b/ard-work/src/main/java/com/ard/work/component/netty/command/notice/FlyWayEndReplyCmd.java
index 7c72b59..1231cfe 100644
--- a/ard-work/src/main/java/com/ard/work/component/netty/command/notice/FlyWayEndReplyCmd.java
+++ b/ard-work/src/main/java/com/ard/work/component/netty/command/notice/FlyWayEndReplyCmd.java
@@ -3,6 +3,7 @@
 import com.ard.work.component.netty.command.BaseCmd;
 import io.netty.buffer.ByteBuf;
 import lombok.Data;
+import lombok.EqualsAndHashCode;
 
 /**
  * 航线结束通知回复指令
@@ -11,6 +12,7 @@
  * @date 2024年10月26日11:54
  **/
 @Data
+@EqualsAndHashCode(callSuper = false)
 public class FlyWayEndReplyCmd extends BaseCmd {
     private final byte encryptFlag = 0x00;  // 加密标志
     private final byte actionCode = 0x2E;   // 动作编号
diff --git a/ard-work/src/main/java/com/ard/work/component/netty/command/notice/UavReadyReplyCmd.java b/ard-work/src/main/java/com/ard/work/component/netty/command/notice/UavReadyReplyCmd.java
index db9b82f..0f59f89 100644
--- a/ard-work/src/main/java/com/ard/work/component/netty/command/notice/UavReadyReplyCmd.java
+++ b/ard-work/src/main/java/com/ard/work/component/netty/command/notice/UavReadyReplyCmd.java
@@ -3,6 +3,7 @@
 import com.ard.work.component.netty.command.BaseCmd;
 import io.netty.buffer.ByteBuf;
 import lombok.Data;
+import lombok.EqualsAndHashCode;
 
 /**
  * 无人机准备完成通知回复指令
@@ -11,6 +12,7 @@
  * @date 2024年10月26日11:54
  **/
 @Data
+@EqualsAndHashCode(callSuper = false)
 public class UavReadyReplyCmd extends BaseCmd {
     private final byte encryptFlag = 0x00;  // 加密标志
     private final byte actionCode = 0x3D;   // 动作编号
diff --git a/ard-work/src/main/java/com/ard/work/component/netty/command/real/SignalInfoCmd.java b/ard-work/src/main/java/com/ard/work/component/netty/command/real/SignalInfoCmd.java
index 8e7ebb7..04dd7f9 100644
--- a/ard-work/src/main/java/com/ard/work/component/netty/command/real/SignalInfoCmd.java
+++ b/ard-work/src/main/java/com/ard/work/component/netty/command/real/SignalInfoCmd.java
@@ -4,7 +4,9 @@
 import com.ard.work.component.netty.command.BaseCmd;
 import io.netty.buffer.ByteBuf;
 import lombok.Data;
+import lombok.EqualsAndHashCode;
 
+@EqualsAndHashCode(callSuper = true)
 @Data
 public class SignalInfoCmd extends BaseCmd {
     private int delayTime;
diff --git a/ard-work/src/main/java/com/ard/work/component/netty/command/real/UavStateCmd.java b/ard-work/src/main/java/com/ard/work/component/netty/command/real/UavStateCmd.java
index ffcea80..c1fc801 100644
--- a/ard-work/src/main/java/com/ard/work/component/netty/command/real/UavStateCmd.java
+++ b/ard-work/src/main/java/com/ard/work/component/netty/command/real/UavStateCmd.java
@@ -4,7 +4,9 @@
 import com.ard.work.component.netty.command.BaseCmd;
 import io.netty.buffer.ByteBuf;
 import lombok.Data;
+import lombok.EqualsAndHashCode;
 
+@EqualsAndHashCode(callSuper = true)
 @Data
 public class UavStateCmd extends BaseCmd {
     private UavState uavState;  // ProtoBuf 数据类
diff --git a/ard-work/src/main/java/com/ard/work/component/netty/command/real/UavTelemetryDataCmd.java b/ard-work/src/main/java/com/ard/work/component/netty/command/real/UavTelemetryDataCmd.java
index 350a60e..0733d8b 100644
--- a/ard-work/src/main/java/com/ard/work/component/netty/command/real/UavTelemetryDataCmd.java
+++ b/ard-work/src/main/java/com/ard/work/component/netty/command/real/UavTelemetryDataCmd.java
@@ -4,6 +4,7 @@
 import com.ard.work.component.netty.command.BaseCmd;
 import io.netty.buffer.ByteBuf;
 import lombok.Data;
+import lombok.EqualsAndHashCode;
 
 /**
  * UavDataCommand
@@ -12,6 +13,7 @@
  * @date 2024年10月23日9:33
  **/
 @Data
+@EqualsAndHashCode(callSuper = false)
 public class UavTelemetryDataCmd extends BaseCmd {
     private TelemetryData telemetryData;
     // 构造函数
diff --git a/ard-work/src/main/java/com/ard/work/component/netty/command/register/HeartbeatReplyCmd.java b/ard-work/src/main/java/com/ard/work/component/netty/command/register/HeartbeatReplyCmd.java
index 3564f7c..b605bd0 100644
--- a/ard-work/src/main/java/com/ard/work/component/netty/command/register/HeartbeatReplyCmd.java
+++ b/ard-work/src/main/java/com/ard/work/component/netty/command/register/HeartbeatReplyCmd.java
@@ -3,6 +3,7 @@
 import com.ard.work.component.netty.command.BaseCmd;
 import io.netty.buffer.ByteBuf;
 import lombok.Data;
+import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
 
 /**
@@ -12,6 +13,7 @@
  * @date 2024/10/22 16:36
  */
 @Data
+@EqualsAndHashCode(callSuper = false)
 @NoArgsConstructor
 public class HeartbeatReplyCmd extends BaseCmd {
 
diff --git a/ard-work/src/main/java/com/ard/work/component/netty/command/register/RegisterReplyCmd.java b/ard-work/src/main/java/com/ard/work/component/netty/command/register/RegisterReplyCmd.java
index 2feb544..653eb28 100644
--- a/ard-work/src/main/java/com/ard/work/component/netty/command/register/RegisterReplyCmd.java
+++ b/ard-work/src/main/java/com/ard/work/component/netty/command/register/RegisterReplyCmd.java
@@ -3,6 +3,7 @@
 import com.ard.work.component.netty.command.BaseCmd;
 import io.netty.buffer.ByteBuf;
 import lombok.Data;
+import lombok.EqualsAndHashCode;
 
 /**
  * 注册命令
@@ -10,6 +11,7 @@
  * @author 刘苏义
  * @date 2024/10/22 16:36
  */
+@EqualsAndHashCode(callSuper = true)
 @Data
 public class RegisterReplyCmd extends BaseCmd {
     private byte success;
diff --git a/ard-work/src/main/java/com/ard/work/component/netty/command/register/UavInitInfoCmd.java b/ard-work/src/main/java/com/ard/work/component/netty/command/register/UavInitInfoCmd.java
index 341edb9..7786343 100644
--- a/ard-work/src/main/java/com/ard/work/component/netty/command/register/UavInitInfoCmd.java
+++ b/ard-work/src/main/java/com/ard/work/component/netty/command/register/UavInitInfoCmd.java
@@ -3,6 +3,7 @@
 import com.ard.work.component.netty.command.BaseCmd;
 import io.netty.buffer.ByteBuf;
 import lombok.Data;
+import lombok.EqualsAndHashCode;
 
 /**
  * 无人机初始化回复命令
@@ -12,6 +13,7 @@
  */
 
 @Data
+@EqualsAndHashCode(callSuper = false)
 public class UavInitInfoCmd extends BaseCmd {
 
     private final byte encryptFlag; // 加密标志
diff --git a/ard-work/src/main/java/com/ard/work/component/netty/command/register/UavInitReplyCmd.java b/ard-work/src/main/java/com/ard/work/component/netty/command/register/UavInitReplyCmd.java
index 5da3831..ca7ab94 100644
--- a/ard-work/src/main/java/com/ard/work/component/netty/command/register/UavInitReplyCmd.java
+++ b/ard-work/src/main/java/com/ard/work/component/netty/command/register/UavInitReplyCmd.java
@@ -4,6 +4,7 @@
 import com.ard.work.component.netty.protobuf.TelemetryDataPB;
 import io.netty.buffer.ByteBuf;
 import lombok.Data;
+import lombok.EqualsAndHashCode;
 
 /**
  *  无人机就绪通知命令
@@ -11,6 +12,7 @@
  * @author 刘苏义
  * @date 2024/10/24 17:18
  */
+@EqualsAndHashCode(callSuper = true)
 @Data
 public class UavInitReplyCmd extends BaseCmd {
 
diff --git a/ard-work/src/main/java/com/ard/work/component/netty/command/settings/ReturnHeightSettingReplyCmd.java b/ard-work/src/main/java/com/ard/work/component/netty/command/settings/ReturnHeightSettingReplyCmd.java
index 58ca3da..1472ff3 100644
--- a/ard-work/src/main/java/com/ard/work/component/netty/command/settings/ReturnHeightSettingReplyCmd.java
+++ b/ard-work/src/main/java/com/ard/work/component/netty/command/settings/ReturnHeightSettingReplyCmd.java
@@ -3,6 +3,7 @@
 import com.ard.work.component.netty.command.BaseCmd;
 import io.netty.buffer.ByteBuf;
 import lombok.Data;
+import lombok.EqualsAndHashCode;
 
 /**
  * 修改返航高度回复指令
@@ -11,6 +12,7 @@
  * @date 2024年10月30日16:20
  **/
 @Data
+@EqualsAndHashCode(callSuper = false)
 public class ReturnHeightSettingReplyCmd extends BaseCmd {
 
     private final byte encryptFlag = 0x00; // 加密标志
diff --git a/ard-work/src/main/java/com/ard/work/component/netty/command/settings/ReturnPointSettingReplyCmd.java b/ard-work/src/main/java/com/ard/work/component/netty/command/settings/ReturnPointSettingReplyCmd.java
index 2f5411f..3ec6a2a 100644
--- a/ard-work/src/main/java/com/ard/work/component/netty/command/settings/ReturnPointSettingReplyCmd.java
+++ b/ard-work/src/main/java/com/ard/work/component/netty/command/settings/ReturnPointSettingReplyCmd.java
@@ -3,6 +3,7 @@
 import com.ard.work.component.netty.command.BaseCmd;
 import io.netty.buffer.ByteBuf;
 import lombok.Data;
+import lombok.EqualsAndHashCode;
 
 /**
  * 修改返航高度回复指令
@@ -10,6 +11,7 @@
  * @author liusuyi
  * @date 2024年10月30日16:20
  **/
+@EqualsAndHashCode(callSuper = true)
 @Data
 public class ReturnPointSettingReplyCmd extends BaseCmd {
 
diff --git a/ard-work/src/main/java/com/ard/work/component/netty/command/settings/VideoStreamSettingReplyCmd.java b/ard-work/src/main/java/com/ard/work/component/netty/command/settings/VideoStreamSettingReplyCmd.java
index baa57b1..a46f0d3 100644
--- a/ard-work/src/main/java/com/ard/work/component/netty/command/settings/VideoStreamSettingReplyCmd.java
+++ b/ard-work/src/main/java/com/ard/work/component/netty/command/settings/VideoStreamSettingReplyCmd.java
@@ -3,6 +3,7 @@
 import com.ard.work.component.netty.command.BaseCmd;
 import io.netty.buffer.ByteBuf;
 import lombok.Data;
+import lombok.EqualsAndHashCode;
 
 /**
  * 设置视频码流回复指令
@@ -10,6 +11,7 @@
  * @author liusuyi
  * @date 2024年10月30日16:20
  **/
+@EqualsAndHashCode(callSuper = true)
 @Data
 public class VideoStreamSettingReplyCmd extends BaseCmd {
 
diff --git a/ard-work/src/main/java/com/ard/work/component/netty/command/wayline/WayLineBeginReplyCmd.java b/ard-work/src/main/java/com/ard/work/component/netty/command/wayline/WayLineBeginReplyCmd.java
index da94067..7b267e1 100644
--- a/ard-work/src/main/java/com/ard/work/component/netty/command/wayline/WayLineBeginReplyCmd.java
+++ b/ard-work/src/main/java/com/ard/work/component/netty/command/wayline/WayLineBeginReplyCmd.java
@@ -3,6 +3,7 @@
 import com.ard.work.component.netty.command.BaseCmd;
 import io.netty.buffer.ByteBuf;
 import lombok.Data;
+import lombok.EqualsAndHashCode;
 
 /**
  * 开始航线回复指令
@@ -10,6 +11,7 @@
  * @author liusuyi
  * @date 2024年10月30日16:20
  **/
+@EqualsAndHashCode(callSuper = true)
 @Data
 public class WayLineBeginReplyCmd extends BaseCmd {
 
diff --git a/ard-work/src/main/java/com/ard/work/component/netty/command/wayline/WayLineEndReplyCmd.java b/ard-work/src/main/java/com/ard/work/component/netty/command/wayline/WayLineEndReplyCmd.java
index 35dfc10..fce768a 100644
--- a/ard-work/src/main/java/com/ard/work/component/netty/command/wayline/WayLineEndReplyCmd.java
+++ b/ard-work/src/main/java/com/ard/work/component/netty/command/wayline/WayLineEndReplyCmd.java
@@ -3,6 +3,7 @@
 import com.ard.work.component.netty.command.BaseCmd;
 import io.netty.buffer.ByteBuf;
 import lombok.Data;
+import lombok.EqualsAndHashCode;
 
 /**
  * 结束航线回复指令
@@ -11,6 +12,7 @@
  * @date 2024年10月30日16:20
  **/
 @Data
+@EqualsAndHashCode(callSuper = false)
 public class WayLineEndReplyCmd extends BaseCmd {
 
     private final byte encryptFlag = 0x00; // 加密标志
diff --git a/ard-work/src/main/java/com/ard/work/component/netty/command/wayline/WayLinePauseReplyCmd.java b/ard-work/src/main/java/com/ard/work/component/netty/command/wayline/WayLinePauseReplyCmd.java
index 7e0ee1f..5a6d963 100644
--- a/ard-work/src/main/java/com/ard/work/component/netty/command/wayline/WayLinePauseReplyCmd.java
+++ b/ard-work/src/main/java/com/ard/work/component/netty/command/wayline/WayLinePauseReplyCmd.java
@@ -3,6 +3,7 @@
 import com.ard.work.component.netty.command.BaseCmd;
 import io.netty.buffer.ByteBuf;
 import lombok.Data;
+import lombok.EqualsAndHashCode;
 
 /**
  * 暂停航线回复指令
@@ -10,6 +11,7 @@
  * @author liusuyi
  * @date 2024年10月30日16:20
  **/
+@EqualsAndHashCode(callSuper = true)
 @Data
 public class WayLinePauseReplyCmd extends BaseCmd {
 
diff --git a/ard-work/src/main/java/com/ard/work/component/netty/command/wayline/WayLineResumeReplyCmd.java b/ard-work/src/main/java/com/ard/work/component/netty/command/wayline/WayLineResumeReplyCmd.java
index f035308..7d7e9d3 100644
--- a/ard-work/src/main/java/com/ard/work/component/netty/command/wayline/WayLineResumeReplyCmd.java
+++ b/ard-work/src/main/java/com/ard/work/component/netty/command/wayline/WayLineResumeReplyCmd.java
@@ -3,6 +3,7 @@
 import com.ard.work.component.netty.command.BaseCmd;
 import io.netty.buffer.ByteBuf;
 import lombok.Data;
+import lombok.EqualsAndHashCode;
 
 /**
  * 恢复航线回复指令
@@ -11,6 +12,7 @@
  * @date 2024年10月30日16:20
  **/
 @Data
+@EqualsAndHashCode(callSuper = false)
 public class WayLineResumeReplyCmd extends BaseCmd {
 
     private final byte encryptFlag = 0x00; // 加密标志
diff --git a/ard-work/src/main/java/com/ard/work/component/netty/command/wayline/WayLineUploadReplyCmd.java b/ard-work/src/main/java/com/ard/work/component/netty/command/wayline/WayLineUploadReplyCmd.java
index bba4e12..4e4344a 100644
--- a/ard-work/src/main/java/com/ard/work/component/netty/command/wayline/WayLineUploadReplyCmd.java
+++ b/ard-work/src/main/java/com/ard/work/component/netty/command/wayline/WayLineUploadReplyCmd.java
@@ -3,6 +3,7 @@
 import com.ard.work.component.netty.command.BaseCmd;
 import io.netty.buffer.ByteBuf;
 import lombok.Data;
+import lombok.EqualsAndHashCode;
 
 /**
  * 上传航线回复指令
@@ -11,6 +12,7 @@
  * @date 2024年10月30日16:20
  **/
 @Data
+@EqualsAndHashCode(callSuper = false)
 public class WayLineUploadReplyCmd extends BaseCmd {
 
     private final byte encryptFlag = 0x00; // 加密标志
diff --git a/ard-work/src/main/java/com/ard/work/domain/dto/state/PointData.java b/ard-work/src/main/java/com/ard/work/domain/dto/state/PointData.java
index bb6bc9d..daab7cc 100644
--- a/ard-work/src/main/java/com/ard/work/domain/dto/state/PointData.java
+++ b/ard-work/src/main/java/com/ard/work/domain/dto/state/PointData.java
@@ -8,17 +8,56 @@
 // 假设 PointData 类定义如下
 @Data
 public class PointData {
-    private double lat; // 纬度
-    private double lng; // 经度
-    private float height; // 高度(单位:米,范围0~遥控器限高)
-    private float speed; // 速度(单位:米/秒,范围0~15),默认8
-    private List<PointAction> actions; // 动作数组
-    private int flightPathMode; // 航线飞行模式:1=直线飞行,2=协调转弯,3=曲线飞行(停),4=曲线飞行(不停)
-    private float dampingDistance; // 转弯半径(仅协调转弯模式下有效),取值范围1~655.35单位:米
-    private int safeGohomeFlag; // 是否为安全返航点 0=不是,1=是
-    private int headingMode; // 偏航模式 0=自动,1=锁定,2=遥控器控制,3=云台依照航点方向旋转,4=朝向兴趣点,5=飞机和云台的偏航同时旋转
-    private float heading; // 航点偏航 -180~180
-    private int interestIndex; // 兴趣点下标,默认-1
-    private int groupIndex; // 组下标
+
+    /** 纬度 */
+    private double lat;
+
+    /** 经度 */
+    private double lng;
+
+    /** 高度(单位:米,范围0~遥控器限高) */
+    private float height;
+
+    /** 速度(单位:米/秒,范围0~15),默认8 */
+    private float speed;
+
+    /** 动作数组 */
+    private List<PointAction> actions;
+
+    /** 航线飞行模式:
+     * 1=直线飞行,
+     * 2=协调转弯,
+     * 3=曲线飞行(停),
+     * 4=曲线飞行(不停)
+     */
+    private int flightPathMode;
+
+    /** 转弯半径(仅协调转弯模式下有效),取值范围1~655.35单位:米 */
+    private float dampingDistance;
+
+    /** 是否为安全返航点
+     * 0=不是,
+     * 1=是
+     */
+    private int safeGohomeFlag;
+
+    /** 偏航模式
+     * 0=自动,
+     * 1=锁定,
+     * 2=遥控器控制,
+     * 3=云台依照航点方向旋转,
+     * 4=朝向兴趣点,
+     * 5=飞机和云台的偏航同时旋转
+     */
+    private int headingMode;
+
+    /** 航点偏航 -180~180 */
+    private float heading;
+
+    /** 兴趣点下标,默认-1 */
+    private int interestIndex;
+
+    /** 组下标 */
+    private int groupIndex;
 
 }
\ No newline at end of file
diff --git a/ard-work/src/main/java/com/ard/work/domain/dto/wayline/PlanLineData.java b/ard-work/src/main/java/com/ard/work/domain/dto/wayline/PlanLineData.java
index fb2f336..b8749d7 100644
--- a/ard-work/src/main/java/com/ard/work/domain/dto/wayline/PlanLineData.java
+++ b/ard-work/src/main/java/com/ard/work/domain/dto/wayline/PlanLineData.java
@@ -18,17 +18,43 @@
 @AllArgsConstructor
 @NoArgsConstructor
 public class PlanLineData {
-    private int finishedAction;     // 结束航线后动作(必填)
-    private float maxSpeed;         // 最大飞行速度(单位:米/秒)
-    private float autoSpeed;        // 自动飞行速度(单位:米/秒)
-    private List<PointData> points; // 坐标点数组(必填)
-    private int loseAction;         // 网络失联后动作(必填)
-    private int homeHeight;         // 返航高度(必填)
-    private int isSaveEnergyMode;   // 是否开启节能模式
-    private HangarPoint takePoint;  // 起飞点机库信息
-    private HangarPoint landPoint;  // 降落点机库信息
-    private List<PointData> interests;      // 兴趣点数组
-    private NormalModel normalModel;        // 普通建模
-    private SurroundModel surroundModel;    // 环绕建模
-    private PointData takeOffPoint;         // 起飞点
+
+    /**  结束航线后动作(必填) */
+    private int finishedAction;
+
+    /**  最大飞行速度(单位:米/秒) */
+    private float maxSpeed;
+
+    /**  自动飞行速度(单位:米/秒) */
+    private float autoSpeed;
+
+    /**  坐标点数组(必填) */
+    private List<PointData> points;
+
+    /**  网络失联后动作(必填) */
+    private int loseAction;
+
+    /**  返航高度(必填) */
+    private int homeHeight;
+
+    /**  是否开启节能模式 */
+    private int isSaveEnergyMode;
+
+    /**  起飞点机库信息 */
+    private HangarPoint takePoint;
+
+    /**  降落点机库信息 */
+    private HangarPoint landPoint;
+
+    /**  兴趣点数组 */
+    private List<PointData> interests;
+
+    /**  普通建模 */
+    private NormalModel normalModel;
+
+    /**  环绕建模 */
+    private SurroundModel surroundModel;
+
+    /**  起飞点 */
+    private PointData takeOffPoint;
 }
diff --git a/ard-work/src/main/java/com/ard/work/domain/dto/wayline/PointAction.java b/ard-work/src/main/java/com/ard/work/domain/dto/wayline/PointAction.java
index 4102dcb..49d6719 100644
--- a/ard-work/src/main/java/com/ard/work/domain/dto/wayline/PointAction.java
+++ b/ard-work/src/main/java/com/ard/work/domain/dto/wayline/PointAction.java
@@ -15,8 +15,33 @@
 @AllArgsConstructor
 @NoArgsConstructor
 public class PointAction {
-    private int type; // 类型:1-变焦 2-拍照 3-录像 4-停录 5-控制飞机机头偏航 6-控制云台俯仰 7-控制云台偏航 8-控制云台横滚 9-悬停 10-等距间隔拍照 11-等时间隔拍照 12-结束间隔拍照 13-单条喊话 14-开始循环喊话 15-结束循环喊话 16-对焦
-    private float param; // 参数,根据类型不同含义不同
-    private int waitTime; // 动作触发后等待时长(单位:秒)
-    private String speakInfo; // 喊话内容[type=13和type=14时生效]
+
+    /** 类型:
+     * 1-变焦
+     * 2-拍照
+     * 3-录像
+     * 4-停录
+     * 5-控制飞机机头偏航
+     * 6-控制云台俯仰
+     * 7-控制云台偏航
+     * 8-控制云台横滚
+     * 9-悬停
+     * 10-等距间隔拍照
+     * 11-等时间隔拍照
+     * 12-结束间隔拍照
+     * 13-单条喊话
+     * 14-开始循环喊话
+     * 15-结束循环喊话
+     * 16-对焦
+     */
+    private int type;
+
+    /** 参数,根据类型不同含义不同 */
+    private float param;
+
+    /** 动作触发后等待时长(单位:秒) */
+    private int waitTime;
+
+    /** 喊话内容[type=13和type=14时生效] */
+    private String speakInfo;
 }
diff --git a/ard-work/src/main/java/com/ard/work/domain/dto/wayline/WayLineUploadDTO.java b/ard-work/src/main/java/com/ard/work/domain/dto/wayline/WayLineUploadDTO.java
index 78e3788..9d9cdf6 100644
--- a/ard-work/src/main/java/com/ard/work/domain/dto/wayline/WayLineUploadDTO.java
+++ b/ard-work/src/main/java/com/ard/work/domain/dto/wayline/WayLineUploadDTO.java
@@ -16,6 +16,14 @@
 @AllArgsConstructor
 @NoArgsConstructor
 public class WayLineUploadDTO {
+
+    /**
+     * 云盒SN编号
+     */
     private String boxSn;
+
+    /**
+     * 航线数据
+     */
     private PlanLineData wayLineData;
 }
diff --git a/ard-work/src/main/java/com/ard/work/domain/entity/ArdDroneInfo.java b/ard-work/src/main/java/com/ard/work/domain/entity/ArdDroneInfo.java
index baa2947..80a43c9 100644
--- a/ard-work/src/main/java/com/ard/work/domain/entity/ArdDroneInfo.java
+++ b/ard-work/src/main/java/com/ard/work/domain/entity/ArdDroneInfo.java
@@ -19,6 +19,7 @@
 @Builder
 @AllArgsConstructor
 @NoArgsConstructor
+@EqualsAndHashCode(callSuper = false)
 public class ArdDroneInfo extends BaseEntity {
 
     private static final long serialVersionUID = 1L;
diff --git a/ard-work/src/main/java/com/ard/work/domain/entity/ArdFlightTask.java b/ard-work/src/main/java/com/ard/work/domain/entity/ArdFlightTask.java
index 8e4602b..62a8d23 100644
--- a/ard-work/src/main/java/com/ard/work/domain/entity/ArdFlightTask.java
+++ b/ard-work/src/main/java/com/ard/work/domain/entity/ArdFlightTask.java
@@ -1,12 +1,16 @@
 package com.ard.work.domain.entity;
 
 import com.ard.common.core.domain.BaseEntity;
-import lombok.Data;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.*;
 
 import java.util.Date;
-import java.util.List;
 
+@EqualsAndHashCode(callSuper = true)
 @Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
 public class ArdFlightTask extends BaseEntity {
 
     private Integer taskId;             // 任务ID
@@ -16,8 +20,21 @@
     private Integer photoCount;         // 图片数量
     private Integer videoCount;         // 录像数量
     private String videoPath;           // 视频路径
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private Date startTime;             // 任务开始时间
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private Date endTime;               // 任务结束时间
+    private Long duration;              // 持续时长(单位:秒)
     private String serverId;            // 服务器ID
-    private List<ArdMedia> mediaList;   // 媒体文件列表
+
+    // 计算持续时长,单位:秒
+    public Long getDuration() {
+        if (startTime != null && endTime != null) {
+            // 计算时间差(毫秒)
+            long durationMillis = endTime.getTime() - startTime.getTime();
+            // 将毫秒转换为秒
+            return durationMillis / 1000;
+        }
+        return null;
+    }
 }
diff --git a/ard-work/src/main/java/com/ard/work/domain/entity/ArdMedia.java b/ard-work/src/main/java/com/ard/work/domain/entity/ArdMedia.java
index a29e680..f5b97d5 100644
--- a/ard-work/src/main/java/com/ard/work/domain/entity/ArdMedia.java
+++ b/ard-work/src/main/java/com/ard/work/domain/entity/ArdMedia.java
@@ -1,9 +1,16 @@
 package com.ard.work.domain.entity;
 
 import com.ard.common.core.domain.BaseEntity;
-import lombok.Data;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.*;
 
+import java.util.Date;
+
+@EqualsAndHashCode(callSuper = true)
 @Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
 public class ArdMedia extends BaseEntity {
 
     private String id;                 // 媒体ID
@@ -13,4 +20,11 @@
     private String fileMd5;            // 文件MD5值
     private String mediaUrl;           // 地址
     private String sourceUrl;          // 源地址
+    private Long   photoId;            // 图片ID
+    private Double longitude;          // 经度
+    private Double latitude;           // 纬度
+    private Double height;             // 高度
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date captureTime;          // 抓拍时间
+    private String thumbnailUrl;       // 视频缩略图URL
 }
diff --git a/ard-work/src/main/java/com/ard/work/domain/entity/ArdServerInfo.java b/ard-work/src/main/java/com/ard/work/domain/entity/ArdServerInfo.java
index 0ce9bef..902445d 100644
--- a/ard-work/src/main/java/com/ard/work/domain/entity/ArdServerInfo.java
+++ b/ard-work/src/main/java/com/ard/work/domain/entity/ArdServerInfo.java
@@ -5,6 +5,7 @@
 import com.ard.common.core.domain.BaseEntity;
 import lombok.Builder;
 import lombok.Data;
+import lombok.EqualsAndHashCode;
 
 /**
  * 服务器管理对象 ard_server
@@ -12,6 +13,7 @@
  * @author xia
  * @date 2025-10-10
  */
+@EqualsAndHashCode(callSuper = true)
 @Data
 public class ArdServerInfo extends BaseEntity {
 
diff --git a/ard-work/src/main/java/com/ard/work/domain/entity/UavWayline.java b/ard-work/src/main/java/com/ard/work/domain/entity/UavWayline.java
index 1688d89..d34208a 100644
--- a/ard-work/src/main/java/com/ard/work/domain/entity/UavWayline.java
+++ b/ard-work/src/main/java/com/ard/work/domain/entity/UavWayline.java
@@ -1,9 +1,6 @@
 package com.ard.work.domain.entity;
 
-import lombok.AllArgsConstructor;
-import lombok.Builder;
-import lombok.Data;
-import lombok.NoArgsConstructor;
+import lombok.*;
 import com.ard.common.annotation.Excel;
 import com.ard.common.core.domain.BaseEntity;
 
@@ -13,6 +10,7 @@
  * @author ard
  * @date 2025-06-27
  */
+@EqualsAndHashCode(callSuper = true)
 @Data
 @Builder
 @AllArgsConstructor
diff --git a/ard-work/src/main/java/com/ard/work/mapper/ArdFlightTaskMapper.java b/ard-work/src/main/java/com/ard/work/mapper/ArdFlightTaskMapper.java
index 9235bc4..d6683b3 100644
--- a/ard-work/src/main/java/com/ard/work/mapper/ArdFlightTaskMapper.java
+++ b/ard-work/src/main/java/com/ard/work/mapper/ArdFlightTaskMapper.java
@@ -10,6 +10,9 @@
     // 插入飞行任务
     int insertArdFlightTask(ArdFlightTask task);
 
+    // 插入飞行任务
+    int updateArdFlightTask(ArdFlightTask task);
+
     // 根据任务ID获取飞行任务
     ArdFlightTask getArdFlightTaskById(@Param("taskId") Integer taskId);
 
diff --git a/ard-work/src/main/java/com/ard/work/mapper/ArdMediaMapper.java b/ard-work/src/main/java/com/ard/work/mapper/ArdMediaMapper.java
index ebd0e76..5a45bf6 100644
--- a/ard-work/src/main/java/com/ard/work/mapper/ArdMediaMapper.java
+++ b/ard-work/src/main/java/com/ard/work/mapper/ArdMediaMapper.java
@@ -2,6 +2,8 @@
 
 import com.ard.work.domain.entity.ArdMedia;
 import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
 import java.util.List;
 
 
@@ -14,7 +16,10 @@
      * @return 媒体数据集合
      */
     List<ArdMedia> selectArdMedia(ArdMedia ardMedia);  // 动态查询
+
     List<ArdMedia> selectArdMediaByTaskId(Integer taskId);  // 根据任务ID查询
+
+    List<ArdMedia> selectArdMediaByTaskIdAndType(@Param("taskId") Integer taskId, @Param("mediaType") Integer mediaType);  //
 
     /**
      * 插入媒体数据记录
@@ -26,7 +31,10 @@
     void insertArdMediaList(List<ArdMedia> ardMediaList);  // 插入批量记录
 
     void updateArdMedia(ArdMedia ardMedia);  // 更新记录
+
     void deleteArdMediaById(Integer id);  // 根据ID删除记录
+
     void deleteArdMediaByIds(List<Integer> mediaIds);  // 批量删除记录
+
     void deleteArdMediaByTaskId(Integer taskId);  // 批量删除记录
 }
diff --git a/ard-work/src/main/java/com/ard/work/service/impl/ArdFlightTaskServiceServiceImpl.java b/ard-work/src/main/java/com/ard/work/service/impl/ArdFlightTaskServiceServiceImpl.java
index 87b1be2..bcc4d7d 100644
--- a/ard-work/src/main/java/com/ard/work/service/impl/ArdFlightTaskServiceServiceImpl.java
+++ b/ard-work/src/main/java/com/ard/work/service/impl/ArdFlightTaskServiceServiceImpl.java
@@ -1,10 +1,8 @@
 package com.ard.work.service.impl;
 
 import com.ard.common.utils.DateUtils;
-import com.ard.common.utils.StringUtils;
 import com.ard.common.utils.file.MimeTypeUtils;
 import com.ard.common.utils.uuid.IdUtils;
-import com.ard.oss.service.IOssService;
 import com.ard.oss.service.impl.OssServiceContext;
 import com.ard.work.component.forest.TyClient;
 import com.ard.work.domain.dto.BoxHistoryDTO;
@@ -18,23 +16,29 @@
 import com.ard.work.mapper.ArdMediaMapper;
 import com.ard.work.service.IArdFlightTaskService;
 import com.ard.work.service.IArdServerInfoService;
-import org.apache.commons.io.FilenameUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.scheduling.annotation.Async;
+import lombok.extern.slf4j.Slf4j;
+import org.bytedeco.javacv.FFmpegFrameGrabber;
+import org.bytedeco.javacv.Frame;
+import org.bytedeco.javacv.Java2DFrameConverter;
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
 import org.springframework.stereotype.Service;
-import org.springframework.web.multipart.MultipartFile;
 
 import javax.annotation.Resource;
+import javax.imageio.ImageIO;
 import javax.net.ssl.*;
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
 import java.io.InputStream;
+import java.net.HttpURLConnection;
 import java.net.URL;
 import java.util.Date;
 import java.util.List;
-import java.util.Objects;
 import java.util.concurrent.CompletableFuture;
+import java.util.stream.Collectors;
 
+@Slf4j
 @Service
 public class ArdFlightTaskServiceServiceImpl implements IArdFlightTaskService {
 
@@ -48,16 +52,23 @@
     private TyClient tyClient;
     @Resource
     private OssServiceContext ossServiceContext;
-
     @Resource
     private ThreadPoolTaskExecutor threadPoolTaskExecutor;  // 使用线程池执行异步任务
 
+    /**
+     * 查询飞行架次列表
+     *
+     * @param ardFlightTask 飞行架次
+     * @return 飞行架次集合
+     */
     @Override
     public List<ArdFlightTask> selectArdFlightTask(ArdFlightTask ardFlightTask) {
         return ardFlightTaskMapper.selectArdFlightTask(ardFlightTask);
     }
 
-    // 同步所有服务的飞行历史
+    /**
+     * 同步所有服务的飞行历史
+     */
     @Scheduled(fixedDelay = 10000)
     public void syncAllFlightHistory() {
         List<String> serverIds = ardServerInfoService.getServerIdsList();
@@ -75,12 +86,12 @@
         return maxStartTime != null ? maxStartTime : new Date(0);  // 如果没有数据,返回 Unix 纪元时间作为起点
     }
 
-    // 调用接口获取飞行历史数据
     // 根据上次同步时间同步飞行历史
-    public void syncFlightHistory(String serverId, Date lastSyncTime) {
+    public void syncFlightHistory(String serverId, Date startTime) {
         // 创建查询条件 BoxHistoryDTO,并设置 startTime 作为过滤条件
-        BoxHistoryDTO boxHistoryDTO = new BoxHistoryDTO();
-        boxHistoryDTO.setStartTime(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, lastSyncTime));  // 传递 lastSyncTime 参数
+        BoxHistoryDTO boxHistoryDTO = BoxHistoryDTO.builder()
+                .startTime(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, startTime))
+                .build();
 
         // 获取飞行历史
         List<BoxHistoryReceiver> historyList = getBoxHistory(serverId, boxHistoryDTO);
@@ -93,118 +104,257 @@
         }
     }
 
+    // 将数据同步到本地数据库
+    private void syncToLocalDatabase(String serverId, BoxHistoryReceiver boxHistoryReceiver) {
+        // 检查是否已经存在相同任务ID的记录
+        ArdFlightTask ardFlightTask = ardFlightTaskMapper.getArdFlightTaskById(boxHistoryReceiver.getTaskId());
+        if (ardFlightTask == null) {
+            // 如果不存在,则插入新记录
+            log.debug("insert task {}", boxHistoryReceiver.getTaskId());
+            // 创建FlightTask实体对象并填充数据
+            ArdFlightTask flightTask = ArdFlightTask.builder()
+                    .taskId(boxHistoryReceiver.getTaskId())
+                    .boxSn(boxHistoryReceiver.getBoxSn())
+                    .boxName(boxHistoryReceiver.getBoxName())
+                    .taskName(boxHistoryReceiver.getTaskName())
+                    .photoCount(Integer.parseInt(boxHistoryReceiver.getPhotoCount()))
+                    .videoCount((boxHistoryReceiver.getVideoPathList() != null) ?
+                            boxHistoryReceiver.getVideoPathList().size() : 0)
+                    .videoPath(boxHistoryReceiver.getVideoPath())
+                    .serverId(serverId)
+                    .startTime(DateUtils.dateTime(DateUtils.YYYY_MM_DD_HH_MM_SS, boxHistoryReceiver.getStartTime()))
+                    .endTime(DateUtils.dateTime(DateUtils.YYYY_MM_DD_HH_MM_SS, boxHistoryReceiver.getEndTime()))
+                    .build();
+            flightTask.setCreateTime(DateUtils.getNowDate());
+            // 插入新记录
+            int rows = ardFlightTaskMapper.insertArdFlightTask(flightTask);
+            if (rows > 0) {
+                // 删除旧的媒体记录,防止重复插入
+                ardMediaMapper.deleteArdMediaByTaskId(flightTask.getTaskId());
+
+                // 插入视频
+                insertVideoToDatabase(flightTask, boxHistoryReceiver.getVideoPathList());
+
+                // 插入图片
+                insertPhotoToDatabase(flightTask, serverId, boxHistoryReceiver.getBoxSn());
+            }
+        } else {
+            // 如果存在,则更新记录
+            log.debug("Updating task {}", boxHistoryReceiver.getTaskId());
+            // 增量更新
+            updateVideoToDatabase(ardFlightTask, boxHistoryReceiver.getVideoPathList());
+            // 增量更新图片
+            updatePhotoToDatabase(ardFlightTask, serverId, boxHistoryReceiver.getBoxSn());
+
+        }
+    }
+
+
     // 调用接口获取飞行历史数据
     private List<BoxHistoryReceiver> getBoxHistory(String serverId, BoxHistoryDTO boxHistoryDTO) {
         TyHttpCommonReceiver<List<BoxHistoryReceiver>> boxHistory = tyClient.getBoxHistory(serverId, boxHistoryDTO);
         return boxHistory.getContent();
     }
 
-    // 将数据同步到本地数据库
-    private void syncToLocalDatabase(String serverId, BoxHistoryReceiver boxHistoryReceiver) {
-        // 创建FlightTask实体对象并填充数据
-        ArdFlightTask flightTask = new ArdFlightTask();
-        flightTask.setTaskId(boxHistoryReceiver.getTaskId());
-        flightTask.setBoxSn(boxHistoryReceiver.getBoxSn());
-        flightTask.setBoxName(boxHistoryReceiver.getBoxName());
-        flightTask.setTaskName(boxHistoryReceiver.getTaskName());
+    //调用接口获取架次图片
+    private List<BoxPhotosReceiver> getBoxPhotos(String serverId, BoxPhotosDTO boxPhotosDTO) {
+        TyHttpCommonReceiver<List<BoxPhotosReceiver>> boxPhotos = tyClient.getBoxPhotos(serverId, boxPhotosDTO);
+        return boxPhotos.getContent();
+    }
 
-        Integer photoCount = Integer.parseInt(boxHistoryReceiver.getPhotoCount());
-        flightTask.setPhotoCount(photoCount);
 
-        Integer videoCount = (boxHistoryReceiver.getVideoPathList() != null) ?
-                boxHistoryReceiver.getVideoPathList().size() : 0;
-        flightTask.setVideoCount(videoCount);
+    // 插入视频记录
+    private void insertVideoToDatabase(ArdFlightTask flightTask, List<String> videoPathList) {
+        if (videoPathList != null && !videoPathList.isEmpty()) {
+            for (String videoPath : videoPathList) {
+                ArdMedia ardMedia = ArdMedia.builder()
+                        .id(IdUtils.simpleUUID())
+                        .taskId(flightTask.getTaskId())
+                        .mediaType(1) // 1表示视频
+                        .sourceUrl(videoPath)
+                        .fileSize(getFileSizeByUrl(videoPath))
+                        .build();
+                CompletableFuture.supplyAsync(() -> {
+                    try {
+                        // 上传视频
+                        String videoUrl = uploadFileToOss(flightTask.getBoxSn(), videoPath, "record",
+                                MimeTypeUtils.VIDEO_MP4);
+                        ardMedia.setMediaUrl(videoUrl);
+                        // 生成缩略图 InputStream
+                        ByteArrayInputStream thumbnailStream = generateThumbnailInputStream(videoPath, 2, 200);
+                        if (thumbnailStream != null) {
+                            String thumbnailUrl = ossServiceContext.upload("record",
+                                    flightTask.getBoxSn() + "/" + IdUtils.fastSimpleUUID() + ".jpg",
+                                    thumbnailStream,
+                                    MimeTypeUtils.IMAGE_JPEG);
+                            ardMedia.setThumbnailUrl(thumbnailUrl);
+                        }
 
-        flightTask.setVideoPath(boxHistoryReceiver.getVideoPath());
-        flightTask.setServerId(serverId);
+                        ardMedia.setCreateTime(new Date());
+                        return ardMedia;
 
-        Date startTime = DateUtils.dateTime(DateUtils.YYYY_MM_DD_HH_MM_SS, boxHistoryReceiver.getStartTime());
-        flightTask.setStartTime(startTime);
+                    } catch (Exception e) {
+                        e.printStackTrace();
+                        return null;
+                    }
+                }, threadPoolTaskExecutor).thenAccept(am -> {
+                    if (am != null) {
+                        ardMediaMapper.insertArdMedia(am);
+                    }
+                });
 
-        Date endTime = DateUtils.dateTime(DateUtils.YYYY_MM_DD_HH_MM_SS, boxHistoryReceiver.getEndTime());
-        flightTask.setEndTime(endTime);
-
-        flightTask.setCreateTime(DateUtils.getNowDate());
-
-        // 检查是否已经存在相同任务ID的记录
-        ArdFlightTask ardFlightTaskById = ardFlightTaskMapper.getArdFlightTaskById(flightTask.getTaskId());
-        if (ardFlightTaskById != null) {
-            return;
-        }
-
-        System.out.println("Syncing task " + boxHistoryReceiver.getTaskId());
-
-        // 插入新记录
-        int rows = ardFlightTaskMapper.insertArdFlightTask(flightTask);
-        if (rows > 0) {
-            // 删除旧的媒体记录,防止重复插入
-            ardMediaMapper.deleteArdMediaByTaskId(flightTask.getTaskId());
-
-            // 插入视频
-            syncVideoToDatabase(flightTask, boxHistoryReceiver.getVideoPathList());
-
-            // 插入图片
-            syncPhotoToDatabase(flightTask, serverId, boxHistoryReceiver.getBoxSn());
+            }
         }
     }
 
-    // 插入视频记录
-    private void syncVideoToDatabase(ArdFlightTask flightTask, List<String> videoPathList) {
-        if (videoPathList != null && !videoPathList.isEmpty()) {
-            for (String videoPath : videoPathList) {
+    private void updateVideoToDatabase(ArdFlightTask flightTask, List<String> videoPathList) {
+        if (videoPathList == null) {
+            return;
+        }
+        Integer count = flightTask.getVideoCount();//获取本地库视频数量
+        int size = videoPathList.size();//获取接口返回的视频数量
+        if (count != null && size > count) {
+            log.info("录像数量不一致,需要更新数据库");
+            // 需要插入新的视频
+            List<ArdMedia> existingVideos = ardMediaMapper.selectArdMediaByTaskIdAndType(flightTask.getTaskId(), 1);
+            // 提取现有的视频路径
+            List<String> existingVideoPaths = existingVideos.stream()
+                    .map(ArdMedia::getSourceUrl) // 获取每个视频的 URL
+                    .collect(Collectors.toList());
 
-                ArdMedia ardMedia = new ArdMedia();
-                ardMedia.setId(IdUtils.simpleUUID());
-                ardMedia.setTaskId(flightTask.getTaskId());
-                ardMedia.setMediaType(1); // 1表示视频
-                ardMedia.setSourceUrl(videoPath);
-                // 异步上传文件到OSS,并在上传完成后插入数据库
-                CompletableFuture.supplyAsync(() -> uploadFileToOss(flightTask.getBoxSn(), videoPath, "record",
-                                MimeTypeUtils.VIDEO_MP4), threadPoolTaskExecutor)
-                        .thenAccept(url -> {
-                            ardMedia.setMediaUrl(url);  // 获取上传后的文件 URL
+            // 从接口返回的视频路径中找出新的视频
+            List<String> newVideos = videoPathList.stream()
+                    .filter(videoPath -> !existingVideoPaths.contains(videoPath)) // 过滤出新的视频
+                    .collect(Collectors.toList());
+            if (!newVideos.isEmpty()) {
+                // 插入新的视频记录
+                for (String videoPath : newVideos) {
+                    ArdMedia ardMedia = ArdMedia.builder()
+                            .id(IdUtils.simpleUUID())
+                            .taskId(flightTask.getTaskId())
+                            .mediaType(1) // 1表示视频
+                            .fileSize(getFileSizeByUrl(videoPath))
+                            .sourceUrl(videoPath)
+                            .build();
+                    CompletableFuture.supplyAsync(() -> {
+                        try {
+                            // 上传视频
+                            String videoUrl = uploadFileToOss(flightTask.getBoxSn(), videoPath, "record",
+                                    MimeTypeUtils.VIDEO_MP4);
+                            ardMedia.setMediaUrl(videoUrl);
+
+
+                            // 生成缩略图 InputStream
+                            ByteArrayInputStream thumbnailStream = generateThumbnailInputStream(videoPath, 2, 200);
+                            if (thumbnailStream != null) {
+                                String thumbnailUrl = ossServiceContext.upload("record",
+                                        flightTask.getBoxSn() + "/" + IdUtils.fastSimpleUUID() + ".jpg",
+                                        thumbnailStream,
+                                        MimeTypeUtils.IMAGE_JPEG);
+                                ardMedia.setThumbnailUrl(thumbnailUrl);
+                            }
+
                             ardMedia.setCreateTime(new Date());
-                            ardMediaMapper.insertArdMedia(ardMedia);  // 插入数据库
-                        });
+                            return ardMedia;
+
+                        } catch (Exception e) {
+                            e.printStackTrace();
+                            return null;
+                        }
+                    }, threadPoolTaskExecutor).thenAccept(am -> {
+                        if (am != null) {
+                            ardMediaMapper.insertArdMedia(am);
+                        }
+                    });
+                }
+                // 更新任务的视频数量
+                flightTask.setVideoCount(flightTask.getVideoCount() + newVideos.size());
+                ardFlightTaskMapper.updateArdFlightTask(flightTask);
             }
         }
     }
 
     // 插入图片记录
-    private void syncPhotoToDatabase(ArdFlightTask flightTask, String serverId, String boxSn) {
+    private void insertPhotoToDatabase(ArdFlightTask flightTask, String serverId, String boxSn) {
         // 查询图片
         BoxPhotosDTO boxPhotosDTO = new BoxPhotosDTO();
         boxPhotosDTO.setTaskId(flightTask.getTaskId());
         boxPhotosDTO.setBoxSn(boxSn);
         boxPhotosDTO.setPageIndex(1);
-        boxPhotosDTO.setPageSize(1000);
+        boxPhotosDTO.setPageSize(500);
+        List<BoxPhotosReceiver> photoList = getBoxPhotos(serverId, boxPhotosDTO);
+        if (photoList != null && !photoList.isEmpty()) {
+            addPhotos(flightTask, photoList);
+        }
+    }
 
+    private void updatePhotoToDatabase(ArdFlightTask flightTask, String serverId, String boxSn) {
+        int count = flightTask.getPhotoCount(); //获取本地库图片数量
+        // 查询图片
+        BoxPhotosDTO boxPhotosDTO = BoxPhotosDTO.builder()
+                .taskId(flightTask.getTaskId())
+                .boxSn(boxSn)
+                .pageIndex(1)
+                .pageSize(500)
+                .build();
         TyHttpCommonReceiver<List<BoxPhotosReceiver>> boxPhotos = tyClient.getBoxPhotos(serverId, boxPhotosDTO);
         List<BoxPhotosReceiver> photoList = boxPhotos.getContent();
+        int size = photoList.size();
 
-        if (photoList != null && !photoList.isEmpty()) {
-            for (BoxPhotosReceiver photo : photoList) {
-                ArdMedia ardMedia = new ArdMedia();
-                ardMedia.setId(IdUtils.simpleUUID());
-                ardMedia.setTaskId(flightTask.getTaskId());
-                ardMedia.setMediaType(0); // 0表示图片
-                ardMedia.setFileSize(photo.getFileSize());
-                ardMedia.setFileMd5(photo.getFileMd5());
-                ardMedia.setSourceUrl(photo.getImgUrl());
-                // 异步上传文件到OSS,并在上传完成后插入数据库
-                CompletableFuture.supplyAsync(() -> uploadFileToOss(flightTask.getBoxSn(), photo.getImgUrl(), "pic",
-                                MimeTypeUtils.IMAGE_JPG), threadPoolTaskExecutor)
-                        .thenAccept(url -> {
-                            ardMedia.setMediaUrl(url);  // 获取上传后的文件 URL
-                            ardMedia.setCreateTime(new Date());
-                            ardMediaMapper.insertArdMedia(ardMedia);  // 插入数据库
-                        });
+        if (size > count) {
+            log.info("图片数量不一致,需要更新数据库");
+            // 获取本地数据库中已存在的图片记录(类型为 0 表示图片)
+            List<ArdMedia> existingPhotos = ardMediaMapper.selectArdMediaByTaskIdAndType(flightTask.getTaskId(), 0);
+            // 需要插入新的视频
+            // 提取现有的图片路径(根据 imgUrl 来判断是否重复)
+            List<String> existingPhotoUrls = existingPhotos.stream()
+                    .map(ArdMedia::getSourceUrl) // 提取 ArdMedia 中的图片 URL
+                    .collect(Collectors.toList());
+
+            // 筛选出 photoList 中没有出现在 existingPhotos 中的新图片
+            List<BoxPhotosReceiver> newPhotos = photoList.stream()
+                    .filter(photo -> !existingPhotoUrls.contains(photo.getImgUrl())) // 过滤出新图片
+                    .collect(Collectors.toList());
+            if (!newPhotos.isEmpty()) {
+                // 插入新的视频记录
+                addPhotos(flightTask, newPhotos);
+
+                // 更新任务的视频数量
+                flightTask.setPhotoCount(flightTask.getPhotoCount() + newPhotos.size());
+                ardFlightTaskMapper.updateArdFlightTask(flightTask);
             }
         }
     }
 
+    private void addPhotos(ArdFlightTask flightTask, List<BoxPhotosReceiver> photoList) {
+        for (BoxPhotosReceiver photo : photoList) {
+            ArdMedia ardMedia = ArdMedia.builder()
+                    .id(IdUtils.simpleUUID())
+                    .taskId(flightTask.getTaskId())
+                    .mediaType(0) // 0表示图片
+                    .fileSize(photo.getFileSize())
+                    .fileMd5(photo.getFileMd5())
+                    .sourceUrl(photo.getImgUrl())
+                    .photoId(photo.getPhotoId())
+                    .longitude(photo.getLng())
+                    .latitude(photo.getLat())
+                    .height(photo.getHeight())
+                    .captureTime(DateUtils.dateTime(DateUtils.YYYY_MM_DD_HH_MM_SS, photo.getTimeStamp()))
+                    .build();
+            // 异步上传文件到OSS,并在上传完成后插入数据库
+            CompletableFuture.supplyAsync(() -> uploadFileToOss(flightTask.getBoxSn(), photo.getImgUrl(), "pic",
+                            MimeTypeUtils.IMAGE_JPG), threadPoolTaskExecutor)
+                    .thenAccept(url -> {
+                        ardMedia.setMediaUrl(url);  // 获取上传后的文件 URL
+                        ardMedia.setCreateTime(new Date());
+                        ardMediaMapper.insertArdMedia(ardMedia);  // 插入数据库
+                    });
+        }
+    }
+
+
     // 通用的上传方法,支持视频和图片等文件上传
-    public String uploadFileToOss(String boxSn, String fileUrl, String bucket, String contentType) {
+    private String uploadFileToOss(String boxSn, String fileUrl, String bucket, String contentType) {
         InputStream fileInputStream = null;
         String fileOssUrl = "";
         try {
@@ -233,12 +383,7 @@
             HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
 
             // 创建所有主机名都信任的HostnameVerifier
-            HostnameVerifier allHostsValid = new HostnameVerifier() {
-                @Override
-                public boolean verify(String hostname, SSLSession session) {
-                    return true;
-                }
-            };
+            HostnameVerifier allHostsValid = (hostname, session) -> true;
             HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
 
             // 现在可以正常访问
@@ -270,4 +415,82 @@
         return fileOssUrl; // 返回上传后的文件OSS URL
     }
 
+    // 获取文件大小
+    private long getFileSizeByUrl(String fileUrl) {
+        try {
+            URL url = new URL(fileUrl);
+            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+            conn.setRequestMethod("HEAD");
+            conn.connect();
+            return conn.getContentLengthLong(); // 返回字节大小
+        } catch (Exception e) {
+            return -1;
+        }
+    }
+
+    // 生成视频缩略图
+    public ByteArrayInputStream generateThumbnailInputStream(String videoFile,
+                                                             int skipFrames,
+                                                             int targetWidth) throws Exception {
+        long start = System.currentTimeMillis();
+        FFmpegFrameGrabber grabber = null;
+
+        try {
+            grabber = new FFmpegFrameGrabber(videoFile);
+            grabber.start();
+
+            int totalFrames = grabber.getLengthInFrames();
+            System.out.println("视频总帧数: " + totalFrames);
+            System.out.println("视频时长: " + grabber.getLengthInTime() / 1000000 + "秒");
+
+            Frame frame = null;
+            int currentFrame = 0;
+
+            // 读取指定帧数后的第一帧有效图像
+            while (currentFrame < totalFrames) {
+                frame = grabber.grabImage();
+                if (frame == null) {
+                    break;
+                }
+
+                if (currentFrame > skipFrames && frame.image != null) {
+                    break;
+                }
+                currentFrame++;
+            }
+
+            if (frame == null || frame.image == null) {
+                throw new Exception("无法获取有效视频帧");
+            }
+
+            // 转换 Frame 为 BufferedImage
+            Java2DFrameConverter converter = new Java2DFrameConverter();
+            BufferedImage image = converter.getBufferedImage(frame);
+
+            // 按目标宽度等比缩放
+            int targetHeight = (int) ((double) targetWidth / image.getWidth() * image.getHeight());
+            BufferedImage scaledImage = new BufferedImage(targetWidth, targetHeight, BufferedImage.TYPE_3BYTE_BGR);
+            scaledImage.getGraphics().drawImage(image, 0, 0, targetWidth, targetHeight, null);
+
+            // 转成 ByteArrayInputStream
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            ImageIO.write(scaledImage, "jpg", baos);
+            long cost = System.currentTimeMillis() - start;
+            System.out.println("处理耗时: " + cost + "ms");
+
+            return new ByteArrayInputStream(baos.toByteArray());
+
+        } finally {
+            if (grabber != null) {
+                try {
+                    grabber.stop();
+                    grabber.close();
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+
+
 }
diff --git a/ard-work/src/main/java/com/ard/work/service/impl/IArdMediaServiceImpl.java b/ard-work/src/main/java/com/ard/work/service/impl/ArdMediaServiceImpl.java
similarity index 91%
rename from ard-work/src/main/java/com/ard/work/service/impl/IArdMediaServiceImpl.java
rename to ard-work/src/main/java/com/ard/work/service/impl/ArdMediaServiceImpl.java
index 26a7e85..2fe5482 100644
--- a/ard-work/src/main/java/com/ard/work/service/impl/IArdMediaServiceImpl.java
+++ b/ard-work/src/main/java/com/ard/work/service/impl/ArdMediaServiceImpl.java
@@ -14,7 +14,7 @@
  * Date: 2025年11月18日13:17
  **/
 @Service
-public class IArdMediaServiceImpl implements IArdMediaService {
+public class ArdMediaServiceImpl implements IArdMediaService {
     @Resource
     private ArdMediaMapper ardMediaMapper;
 
diff --git a/ard-work/src/main/resources/mapper/ArdFlightTaskMapper.xml b/ard-work/src/main/resources/mapper/ArdFlightTaskMapper.xml
index cdd7d25..dae11c0 100644
--- a/ard-work/src/main/resources/mapper/ArdFlightTaskMapper.xml
+++ b/ard-work/src/main/resources/mapper/ArdFlightTaskMapper.xml
@@ -93,9 +93,28 @@
         </trim>
     </insert>
 
+    <update id="updateArdFlightTask" parameterType="com.ard.work.domain.entity.ArdFlightTask">
+        update ard_flight_task
+        <set>
+            <if test="taskId != null">task_id = #{taskId},</if>
+            <if test="boxSn != null">box_sn = #{boxSn},</if>
+            <if test="boxName != null">box_name = #{boxName},</if>
+            <if test="taskName != null">task_name = #{taskName},</if>
+            <if test="videoCount != null">video_count = #{videoCount},</if>
+            <if test="photoCount != null">photo_count = #{photoCount},</if>
+            <if test="videoPath != null">video_path = #{videoPath},</if>
+            <if test="startTime != null">start_time = #{startTime},</if>
+            <if test="endTime != null">end_time = #{endTime},</if>
+            <if test="serverId != null">server_id = #{serverId},</if>
+            <if test="updateBy != null">update_by = #{updateBy},</if>
+            <if test="updateTime != null">update_time = #{updateTime},</if>
+            <if test="remark != null">remark = #{remark},</if>
+        </set>
+        where task_id = #{taskId}
+    </update>
 
     <!-- 根据任务ID获取飞行任务 -->
-    <select id="getArdFlightTaskById" resultType="ArdFlightTask">
+    <select id="getArdFlightTaskById" resultMap="ArdFlightTaskResult">
         SELECT *
         FROM ard_flight_task
         WHERE task_id = #{taskId}
diff --git a/ard-work/src/main/resources/mapper/ArdMediaMapper.xml b/ard-work/src/main/resources/mapper/ArdMediaMapper.xml
index 2c8db02..21f6459 100644
--- a/ard-work/src/main/resources/mapper/ArdMediaMapper.xml
+++ b/ard-work/src/main/resources/mapper/ArdMediaMapper.xml
@@ -11,41 +11,80 @@
         <result property="fileMd5" column="file_md5"/>
         <result property="mediaUrl" column="media_url"/>
         <result property="sourceUrl" column="source_url"/>
+        <result property="photoId" column="photo_id"/>
+        <result property="longitude" column="longitude"/>
+        <result property="latitude" column="latitude"/>
+        <result property="height" column="height"/>
+        <result property="thumbnailUrl" column="thumbnail_url"/>
+        <result property="captureTime" column="capture_time"/>
         <result property="createTime" column="create_time"/>
     </resultMap>
 
+
     <!-- 查询媒体列表:根据条件动态生成SQL -->
     <select id="selectArdMedia" resultMap="ArdMediaResult">
-        SELECT id, task_id, media_type, file_size, file_md5, media_url, source_url,create_time
+        SELECT
+        id, task_id, media_type, file_size, file_md5, media_url, source_url,thumbnail_url,
+        photo_id, longitude, latitude, height, capture_time, create_time
         FROM ard_media
         <where>
-            <!-- 动态查询条件:任务ID -->
             <if test="taskId != null">AND task_id = #{taskId}</if>
-
-            <!-- 动态查询条件:媒体类型 -->
             <if test="mediaType != null">AND media_type = #{mediaType}</if>
-
-            <!-- 动态查询条件:文件大小 -->
             <if test="fileSize != null">AND file_size = #{fileSize}</if>
-
-            <!-- 动态查询条件:文件MD5 -->
             <if test="fileMd5 != null">AND file_md5 = #{fileMd5}</if>
-
-            <!-- 动态查询条件:媒体URL -->
             <if test="mediaUrl != null">AND media_url = #{mediaUrl}</if>
-
-            <!-- 动态查询条件:时间戳 -->
+            <if test="sourceUrl != null">AND source_url = #{sourceUrl}</if>
+            <if test="thumbnailUrl != null">AND thumbnail_url = #{thumbnailUrl}</if>
+            <if test="photoId != null">AND photo_id = #{photoId}</if>
+            <if test="longitude != null">AND longitude = #{longitude}</if>
+            <if test="latitude != null">AND latitude = #{latitude}</if>
+            <if test="height != null">AND height = #{height}</if>
+            <if test="captureTime != null">AND capture_time = #{captureTime}</if>
             <if test="createTime != null">AND create_time = #{createTime}</if>
         </where>
+        ORDER BY create_time DESC
     </select>
+
 
     <!-- 根据任务ID查询媒体 -->
     <select id="selectArdMediaByTaskId" resultMap="ArdMediaResult">
-        SELECT id, task_id, media_type, file_size, file_md5, media_url, create_time
+        SELECT id,
+               task_id,
+               media_type,
+               file_size,
+               file_md5,
+               media_url,
+               source_url,
+               thumbnail_url,
+               photo_id,
+               longitude,
+               latitude,
+               height,
+               capture_time,
+               create_time
         FROM ard_media
         WHERE task_id = #{taskId}
     </select>
-
+    <!-- 根据任务ID和媒体类型查询媒体 -->
+    <select id="selectArdMediaByTaskIdAndType" resultMap="ArdMediaResult">
+        SELECT id,
+               task_id,
+               media_type,
+               file_size,
+               file_md5,
+               media_url,
+               source_url,
+               thumbnail_url,
+               photo_id,
+               longitude,
+               latitude,
+               height,
+               capture_time,
+               create_time
+        FROM ard_media
+        WHERE task_id = #{taskId}
+          and media_type = #{mediaType}
+    </select>
     <!-- 插入媒体记录 -->
     <insert id="insertArdMedia" parameterType="com.ard.work.domain.entity.ArdMedia">
         INSERT INTO ard_media
@@ -57,8 +96,15 @@
             <if test="fileMd5 != null">file_md5,</if>
             <if test="mediaUrl != null">media_url,</if>
             <if test="sourceUrl != null">source_url,</if>
+            <if test="thumbnailUrl != null">thumbnail_url,</if>
+            <if test="photoId != null">photo_id,</if>
+            <if test="longitude != null">longitude,</if>
+            <if test="latitude != null">latitude,</if>
+            <if test="height != null">height,</if>
+            <if test="captureTime != null">capture_time,</if>
             <if test="createTime != null">create_time,</if>
         </trim>
+
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="id != null">#{id},</if>
             <if test="taskId != null">#{taskId},</if>
@@ -67,43 +113,51 @@
             <if test="fileMd5 != null">#{fileMd5},</if>
             <if test="mediaUrl != null">#{mediaUrl},</if>
             <if test="sourceUrl != null">#{sourceUrl},</if>
+            <if test="thumbnailUrl != null">#{thumbnailUrl},</if>
+            <if test="photoId != null">#{photoId},</if>
+            <if test="longitude != null">#{longitude},</if>
+            <if test="latitude != null">#{latitude},</if>
+            <if test="height != null">#{height},</if>
+            <if test="captureTime != null">#{captureTime},</if>
             <if test="createTime != null">#{createTime},</if>
         </trim>
     </insert>
 
-
     <!-- 批量插入媒体记录 -->
     <insert id="insertArdMediaList" parameterType="java.util.List">
-        INSERT INTO ard_media
-        <trim prefix="(" suffix=")" suffixOverrides=",">
-            <if test="list != null and !list.isEmpty()">
-                <foreach item="item" collection="list" separator=",">
-                    <trim prefix="(" suffix=")" suffixOverrides=",">
-                        <if test="item.taskId != null">task_id,</if>
-                        <if test="item.mediaType != null">media_type,</if>
-                        <if test="item.fileSize != null">file_size,</if>
-                        <if test="item.fileMd5 != null">file_md5,</if>
-                        <if test="item.mediaUrl != null">media_url,</if>
-                        <if test="item.sourceUrl != null">source_url,</if>
-                        <if test="item.createTime != null">create_time,</if>
-                    </trim>
-                </foreach>
-            </if>
-        </trim>
-
-        <trim prefix="values " suffix=")" suffixOverrides=",">
-            <foreach item="item" collection="list" separator=",">
-                <trim prefix="(" suffix=")" suffixOverrides=",">
-                    <if test="item.taskId != null">#{item.taskId},</if>
-                    <if test="item.mediaType != null">#{item.mediaType},</if>
-                    <if test="item.fileSize != null">#{item.fileSize},</if>
-                    <if test="item.fileMd5 != null">#{item.fileMd5},</if>
-                    <if test="item.mediaUrl != null">#{item.mediaUrl},</if>
-                    <if test="item.sourceUrl != null">#{item.sourceUrl},</if>
-                    <if test="item.createTime != null">#{item.createTime},</if>
-                </trim>
-            </foreach>
-        </trim>
+        INSERT INTO ard_media(
+        task_id,
+        media_type,
+        file_size,
+        file_md5,
+        media_url,
+        source_url,
+        thumbnail_url,
+        photo_id,
+        longitude,
+        latitude,
+        height,
+        capture_time,
+        create_time
+        )
+        VALUES
+        <foreach collection="list" item="item" separator=",">
+            (
+            #{item.taskId},
+            #{item.mediaType},
+            #{item.fileSize},
+            #{item.fileMd5},
+            #{item.mediaUrl},
+            #{item.sourceUrl},
+            #{item.thumbnailUrl},
+            #{item.photoId},
+            #{item.longitude},
+            #{item.latitude},
+            #{item.height},
+            #{item.captureTime},
+            #{item.createTime}
+            )
+        </foreach>
     </insert>
 
 
@@ -122,7 +176,9 @@
 
     <!-- 删除媒体记录 -->
     <delete id="deleteArdMediaById" parameterType="Integer">
-        DELETE FROM ard_media WHERE id = #{id}
+        DELETE
+        FROM ard_media
+        WHERE id = #{id}
     </delete>
 
     <!-- 批量删除媒体记录 -->
@@ -134,7 +190,9 @@
     </delete>
 
     <delete id="deleteArdMediaByTaskId" parameterType="java.lang.Integer">
-        DELETE FROM ard_media WHERE task_id = #{taskId}
+        DELETE
+        FROM ard_media
+        WHERE task_id = #{taskId}
     </delete>
 
 </mapper>

--
Gitblit v1.9.3