From cbf5045d84088891ef0696b189e1f8af6a653bad Mon Sep 17 00:00:00 2001
From: guoshilong <123456>
Date: Mon, 13 Nov 2023 10:09:32 +0800
Subject: [PATCH] 图斑距离计算,定时任务添加逻辑

---
 src/main/java/com/dji/sample/wayline/service/impl/FlightTaskServiceImpl.java |    3 
 src/main/java/com/dji/sample/wayline/controller/WaylineJobController.java    |   42 ++-
 src/main/java/com/dji/sample/wayline/model/param/FlyAreaParam.java           |   19 +
 src/main/java/com/dji/sample/utils/GeoUtils.java                             |   78 +++++++
 src/main/java/com/dji/sample/wayline/service/impl/WaylineJobServiceImpl.java |  389 +++++++++++++++++++++++++++++++++++---
 src/main/java/com/dji/sample/wayline/model/param/PointPOJO.java              |   27 ++
 src/main/java/com/dji/sample/wayline/service/IWaylineJobService.java         |   14 +
 7 files changed, 515 insertions(+), 57 deletions(-)

diff --git a/src/main/java/com/dji/sample/utils/GeoUtils.java b/src/main/java/com/dji/sample/utils/GeoUtils.java
new file mode 100644
index 0000000..c1bfb14
--- /dev/null
+++ b/src/main/java/com/dji/sample/utils/GeoUtils.java
@@ -0,0 +1,78 @@
+package com.dji.sample.utils;
+
+import com.dji.sample.wayline.model.param.PointPOJO;
+
+import java.util.List;
+
+/**
+ * 空间计算工具类
+ */
+public class GeoUtils {
+    /**
+     * 默认地球半径
+     */
+    private static double EARTH_RADIUS = 6371000;//赤道半径(单位m)
+
+    /**
+     * 转化为弧度(rad)
+     */
+    private static double rad(double d) {
+        return d * Math.PI / 180.0;
+    }
+
+
+    /**
+     * 计算中心经纬度与目标经纬度的距离(米)
+     *
+     * @param centerLon 中心精度
+     * @param centerLat 中心纬度
+     * @param targetLon 需要计算的精度
+     * @param targetLat 需要计算的纬度
+     * @return 米
+     */
+    public static double distance(double centerLon, double centerLat, double targetLon, double targetLat) {
+
+        double jl_jd = 102834.74258026089786013677476285;// 每经度单位米;
+        double jl_wd = 111712.69150641055729984301412873;// 每纬度单位米;
+        double b = Math.abs((centerLat - targetLat) * jl_jd);
+        double a = Math.abs((centerLon - targetLon) * jl_wd);
+        return Math.sqrt((a * a + b * b));
+    }
+
+    /**
+     * 根据多个点计算中心点
+     * @param list
+     * @return
+     */
+    public static PointPOJO getCenterPoint(List<PointPOJO> list) {
+
+        int total = list.size();
+        double X = 0, Y = 0, Z = 0;
+
+        for (int i = 0; i < list.size(); i++) {
+            PointPOJO point = list.get(i);
+            double lat, lon, x, y, z;
+            lon = point.getLon() * Math.PI / 180;
+            lat = point.getLat() * Math.PI / 180;
+            x = Math.cos(lat) * Math.cos(lon);
+            y = Math.cos(lat) * Math.sin(lon);
+            z = Math.sin(lat);
+            X += x;
+            Y += y;
+            Z += z;
+        }
+
+
+        X = X / total;
+        Y = Y / total;
+        Z = Z / total;
+        double Lon = Math.atan2(Y, X);
+        double Hyp = Math.sqrt(X * X + Y * Y);
+        double Lat = Math.atan2(Z, Hyp);
+
+        PointPOJO centerPoint = new PointPOJO();
+        centerPoint.setLon( Lon * 180 / Math.PI);
+        centerPoint.setLat(Lat * 180 / Math.PI);
+        return centerPoint;
+    }
+}
diff --git a/src/main/java/com/dji/sample/wayline/controller/WaylineJobController.java b/src/main/java/com/dji/sample/wayline/controller/WaylineJobController.java
index 1da52e6..0a416e0 100644
--- a/src/main/java/com/dji/sample/wayline/controller/WaylineJobController.java
+++ b/src/main/java/com/dji/sample/wayline/controller/WaylineJobController.java
@@ -6,9 +6,7 @@
 import com.dji.sample.log.aspect.SysLogAnnotation;
 import com.dji.sample.wayline.model.dto.WaylineJobDTO;
 import com.dji.sample.wayline.model.entity.WaylineJobEntity;
-import com.dji.sample.wayline.model.param.CreateJobParam;
-import com.dji.sample.wayline.model.param.UpdateJobParam;
-import com.dji.sample.wayline.model.param.WaylineJobQueryParam;
+import com.dji.sample.wayline.model.param.*;
 import com.dji.sample.wayline.service.IWaylineJobService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
@@ -16,6 +14,7 @@
 import javax.servlet.http.HttpServletRequest;
 import javax.validation.Valid;
 import java.sql.SQLException;
+import java.util.List;
 import java.util.Set;
 
 import static com.dji.sample.component.AuthInterceptor.TOKEN_CLAIM;
@@ -34,6 +33,7 @@
 
     /**
      * 创建航路任务。
+     *
      * @param request
      * @param param
      * @param workspaceId
@@ -44,7 +44,7 @@
     @SysLogAnnotation(operModul = "计划库", operType = "新增", operDesc = "创建计划")
     public ResponseResult createJob(HttpServletRequest request, @Valid @RequestBody CreateJobParam param,
                                     @PathVariable(name = "workspace_id") String workspaceId) throws SQLException {
-        CustomClaim customClaim = (CustomClaim)request.getAttribute(TOKEN_CLAIM);
+        CustomClaim customClaim = (CustomClaim) request.getAttribute(TOKEN_CLAIM);
         customClaim.setWorkspaceId(workspaceId);
 
         return waylineJobService.publishFlightTask(param, customClaim);
@@ -53,6 +53,7 @@
 
     /**
      * 创建航路任务(重复定时和连续执行)
+     *
      * @param request
      * @param param
      * @param workspaceId
@@ -62,8 +63,8 @@
     @PostMapping("/{workspace_id}/flight-tasks-condition")
     @SysLogAnnotation(operModul = "计划库", operType = "新增", operDesc = "创建航路任务(重复定时和连续执行)")
     public ResponseResult createJobCondition(HttpServletRequest request, @Valid @RequestBody CreateJobParam param,
-                                    @PathVariable(name = "workspace_id") String workspaceId) throws SQLException {
-        CustomClaim customClaim = (CustomClaim)request.getAttribute(TOKEN_CLAIM);
+                                             @PathVariable(name = "workspace_id") String workspaceId) throws SQLException {
+        CustomClaim customClaim = (CustomClaim) request.getAttribute(TOKEN_CLAIM);
         customClaim.setWorkspaceId(workspaceId);
 
         return waylineJobService.publishFlightTaskCondition(param, customClaim);
@@ -71,6 +72,7 @@
 
     /**
      * 分页查询
+     *
      * @param page
      * @param pageSize
      * @param workspaceId
@@ -80,28 +82,28 @@
     @SysLogAnnotation(operModul = "计划库", operType = "查询", operDesc = "分页查询")
     public ResponseResult<PaginationData<WaylineJobDTO>> getJobs(@RequestParam(defaultValue = "1") Long page,
                                                                  @RequestParam(name = "page_size", defaultValue = "10") Long pageSize,
-                                                                 @PathVariable(name = "workspace_id") String workspaceId, WaylineJobQueryParam waylineJobQueryParam){
-        PaginationData<WaylineJobDTO> data = waylineJobService.getJobsByWorkspaceId(workspaceId, page, pageSize,waylineJobQueryParam);
+                                                                 @PathVariable(name = "workspace_id") String workspaceId, WaylineJobQueryParam waylineJobQueryParam) {
+        PaginationData<WaylineJobDTO> data = waylineJobService.getJobsByWorkspaceId(workspaceId, page, pageSize, waylineJobQueryParam);
         return ResponseResult.success(data);
     }
 
     /**
      * 查询最新的记录
+     *
      * @return
      */
     @GetMapping("/{workspace_id}/latestJob")
-    public ResponseResult<WaylineJobEntity> getLatestJobs(@PathVariable(name = "workspace_id") String workspaceId,WaylineJobQueryParam waylineJobQueryParam){
+    public ResponseResult<WaylineJobEntity> getLatestJobs(@PathVariable(name = "workspace_id") String workspaceId, WaylineJobQueryParam waylineJobQueryParam) {
 
-        WaylineJobEntity waylineJobEntity = waylineJobService.getLatestJob(workspaceId,waylineJobQueryParam);
+        WaylineJobEntity waylineJobEntity = waylineJobService.getLatestJob(workspaceId, waylineJobQueryParam);
 
         return ResponseResult.success(waylineJobEntity);
     }
 
 
-
-
     /**
      * 发送命令取消作业。
+     *
      * @param jobIds
      * @param workspaceId
      * @return
@@ -110,13 +112,14 @@
     @DeleteMapping("/{workspace_id}/jobs")
     @SysLogAnnotation(operModul = "计划库", operType = "删除", operDesc = "发送命令取消作业")
     public ResponseResult publishCancelJob(@RequestParam(name = "job_id") Set<String> jobIds,
-                                     @PathVariable(name = "workspace_id") String workspaceId) throws SQLException {
+                                           @PathVariable(name = "workspace_id") String workspaceId) throws SQLException {
         waylineJobService.cancelFlightTask(workspaceId, jobIds);
         return ResponseResult.success();
     }
 
     /**
      * 将此作业的媒体文件设置为立即上传。
+     *
      * @param workspaceId
      * @param jobId
      * @return
@@ -124,7 +127,7 @@
     @PostMapping("/{workspace_id}/jobs/{job_id}/media-highest")
     @SysLogAnnotation(operModul = "计划库", operType = "修改", operDesc = "将此作业的媒体文件设置为立即上传")
     public ResponseResult uploadMediaHighestPriority(@PathVariable(name = "workspace_id") String workspaceId,
-                                             @PathVariable(name = "job_id") String jobId) {
+                                                     @PathVariable(name = "job_id") String jobId) {
         waylineJobService.uploadMediaHighestPriority(workspaceId, jobId);
         return ResponseResult.success();
     }
@@ -137,4 +140,15 @@
         waylineJobService.updateJobStatus(workspaceId, jobId, param);
         return ResponseResult.success();
     }
+
+    /**
+     * 根据区域飞行
+     *
+     * @return
+     */
+    @PostMapping("/{sn}/jobs/flyByArea")
+    @SysLogAnnotation(operModul = "根据区域飞行", operType = "根据区域飞行", operDesc = "根据区域飞行")
+    public ResponseResult flyByArea(@PathVariable(name = "sn") String sn, @RequestBody FlyAreaParam flyAreaParam) {
+        return         waylineJobService.flyByArea(sn,flyAreaParam );
+    }
 }
diff --git a/src/main/java/com/dji/sample/wayline/model/param/FlyAreaParam.java b/src/main/java/com/dji/sample/wayline/model/param/FlyAreaParam.java
new file mode 100644
index 0000000..9cc00b8
--- /dev/null
+++ b/src/main/java/com/dji/sample/wayline/model/param/FlyAreaParam.java
@@ -0,0 +1,19 @@
+package com.dji.sample.wayline.model.param;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class FlyAreaParam {
+    //机场的经纬度
+    @JsonProperty(value = "dockPoint")
+    private PointPOJO dockPoint;
+
+    //区域集合
+    @JsonProperty(value = "areaList")
+    private List<List<PointPOJO>> areaList;
+    //无人机巡逻半径 (m)
+    private  Double radius;
+}
diff --git a/src/main/java/com/dji/sample/wayline/model/param/PointPOJO.java b/src/main/java/com/dji/sample/wayline/model/param/PointPOJO.java
new file mode 100644
index 0000000..a9b6497
--- /dev/null
+++ b/src/main/java/com/dji/sample/wayline/model/param/PointPOJO.java
@@ -0,0 +1,27 @@
+package com.dji.sample.wayline.model.param;
+
+import lombok.Data;
+
+/**
+ * 点
+ */
+@Data
+public class PointPOJO {
+
+    /**
+     * 经度
+     */
+    private Double lon;
+
+    /**
+     * 纬度
+     */
+    private Double lat;
+
+    /**
+     * 高度
+     */
+    private Double height;
+
+    private Double distance;
+}
diff --git a/src/main/java/com/dji/sample/wayline/service/IWaylineJobService.java b/src/main/java/com/dji/sample/wayline/service/IWaylineJobService.java
index e41b145..08c34d2 100644
--- a/src/main/java/com/dji/sample/wayline/service/IWaylineJobService.java
+++ b/src/main/java/com/dji/sample/wayline/service/IWaylineJobService.java
@@ -7,9 +7,7 @@
 import com.dji.sample.wayline.model.dto.WaylineJobDTO;
 import com.dji.sample.wayline.model.entity.WaylineJobEntity;
 import com.dji.sample.wayline.model.enums.WaylineJobStatusEnum;
-import com.dji.sample.wayline.model.param.CreateJobParam;
-import com.dji.sample.wayline.model.param.UpdateJobParam;
-import com.dji.sample.wayline.model.param.WaylineJobQueryParam;
+import com.dji.sample.wayline.model.param.*;
 import org.springframework.messaging.MessageHeaders;
 
 import java.sql.SQLException;
@@ -117,7 +115,7 @@
      * @param dto
      * @return
      */
-    Boolean updateJob(WaylineJobDTO dto);
+    Boolean updateJob(WaylineJobDTO dto) ;
 
     /**
      * Paginate through all jobs in this workspace.
@@ -164,4 +162,12 @@
      * @return
      */
     WaylineJobEntity getLatestJob(String workspaceId, WaylineJobQueryParam waylineJobQueryParam);
+
+    ResponseResult flyByArea(String sn, FlyAreaParam flyAreaParam);
+
+    /**
+     * 判断是否有下一次任务
+     * @param job
+     */
+    ResponseResult checkNextJob(WaylineJobDTO job)  throws SQLException ;
 }
diff --git a/src/main/java/com/dji/sample/wayline/service/impl/FlightTaskServiceImpl.java b/src/main/java/com/dji/sample/wayline/service/impl/FlightTaskServiceImpl.java
index 893b0bc..567a9b0 100644
--- a/src/main/java/com/dji/sample/wayline/service/impl/FlightTaskServiceImpl.java
+++ b/src/main/java/com/dji/sample/wayline/service/impl/FlightTaskServiceImpl.java
@@ -65,6 +65,7 @@
 
     /**
      * Handle the progress messages of the flight tasks reported by the dock.
+     * 处理机场上报的飞行任务进度信息
      * @param receiver
      * @param headers
      */
@@ -110,7 +111,7 @@
                 .mediaCount(mediaCount)
                 .build();
 
-        // record the update of the media count.
+        //记录媒体计数的更新
         if (Objects.nonNull(job.getMediaCount()) && job.getMediaCount() != 0) {
             RedisOpsUtils.hashSet(RedisConst.MEDIA_FILE_PREFIX + receiver.getGateway(), job.getJobId(),
                     MediaFileCountDTO.builder().jobId(receiver.getBid()).mediaCount(job.getMediaCount()).uploadedCount(0).build());
diff --git a/src/main/java/com/dji/sample/wayline/service/impl/WaylineJobServiceImpl.java b/src/main/java/com/dji/sample/wayline/service/impl/WaylineJobServiceImpl.java
index c149023..0c72c27 100644
--- a/src/main/java/com/dji/sample/wayline/service/impl/WaylineJobServiceImpl.java
+++ b/src/main/java/com/dji/sample/wayline/service/impl/WaylineJobServiceImpl.java
@@ -1,7 +1,9 @@
 package com.dji.sample.wayline.service.impl;
 
+import com.alibaba.druid.stat.TableStat;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.dji.sample.common.error.CommonErrorEnum;
 import com.dji.sample.common.model.CustomClaim;
@@ -12,11 +14,17 @@
 import com.dji.sample.component.mqtt.service.IMessageSenderService;
 import com.dji.sample.component.redis.RedisConst;
 import com.dji.sample.component.redis.RedisOpsUtils;
+import com.dji.sample.control.model.dto.PointDTO;
 import com.dji.sample.control.model.param.DrcModeParam;
+import com.dji.sample.control.model.param.FlyToPointParam;
+import com.dji.sample.control.model.param.TakeoffToPointParam;
+import com.dji.sample.control.service.IControlService;
 import com.dji.sample.control.service.IDrcService;
 import com.dji.sample.manage.model.dto.DeviceDTO;
 import com.dji.sample.manage.model.enums.DeviceModeCodeEnum;
 import com.dji.sample.manage.model.enums.DockModeCodeEnum;
+import com.dji.sample.manage.model.enums.DroneRcLostActionEnum;
+import com.dji.sample.manage.model.enums.WaylineRcLostActionEnum;
 import com.dji.sample.manage.model.receiver.OsdDockReceiver;
 import com.dji.sample.manage.model.receiver.OsdSubDeviceReceiver;
 import com.dji.sample.manage.service.IDeviceRedisService;
@@ -24,13 +32,12 @@
 import com.dji.sample.media.model.MediaFileCountDTO;
 import com.dji.sample.media.model.MediaMethodEnum;
 import com.dji.sample.media.service.IFileService;
+import com.dji.sample.utils.GeoUtils;
 import com.dji.sample.wayline.dao.IWaylineJobMapper;
 import com.dji.sample.wayline.model.dto.*;
 import com.dji.sample.wayline.model.entity.WaylineJobEntity;
 import com.dji.sample.wayline.model.enums.*;
-import com.dji.sample.wayline.model.param.CreateJobParam;
-import com.dji.sample.wayline.model.param.UpdateJobParam;
-import com.dji.sample.wayline.model.param.WaylineJobQueryParam;
+import com.dji.sample.wayline.model.param.*;
 import com.dji.sample.wayline.service.IWaylineFileService;
 import com.dji.sample.wayline.service.IWaylineJobService;
 import com.dji.sample.wayline.service.IWaylineRedisService;
@@ -89,6 +96,9 @@
 
     @Autowired
     private IWaylineRedisService waylineRedisService;
+
+    @Autowired
+    private IControlService controlService;
 
     private Optional<WaylineJobDTO> insertWaylineJob(WaylineJobEntity jobEntity) {
         int id = mapper.insert(jobEntity);
@@ -238,42 +248,141 @@
 
         WaylineJobDTO waylineJob = waylineJobOpt.get();
 
-        //循环执行时间
-        for (List<Long> timeArr : param.getExecuteStartTimeArr()) {
-            LocalDate date = LocalDate.ofInstant(Instant.ofEpochSecond(timeArr.get(0)), ZoneId.systemDefault());
-            long beginTime = LocalDateTime.of(date, LocalTime.ofInstant(Instant.ofEpochSecond(timeArr.get(0)), ZoneId.systemDefault()))
-                    .atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
+        //存一条记录,
+        List<Long> timeArr = param.getExecuteStartTimeArr().get(0);
 
-            long endTime = timeArr.size() > 1 && Objects.nonNull(timeArr.get(1)) ?
-                    LocalDateTime.of(date, LocalTime.ofInstant(Instant.ofEpochSecond(timeArr.get(1)), ZoneId.systemDefault()))
-                            .atZone(ZoneId.systemDefault()).toInstant().toEpochMilli() : beginTime;
+        LocalDate date = LocalDate.ofInstant(Instant.ofEpochSecond(timeArr.get(0)), ZoneId.systemDefault());
+        LocalDateTime beginTime = LocalDateTime.of(date, LocalTime.ofInstant(Instant.ofEpochSecond(timeArr.get(0)), ZoneId.systemDefault()));
 
-            if (WaylineTaskTypeEnum.IMMEDIATE != param.getTaskType() && endTime < System.currentTimeMillis()) {
-                //中断当前循环执行下一个
-                continue;
-            }
+        LocalDateTime endTime = timeArr.size() > 1 && Objects.nonNull(timeArr.get(1)) ?
+                LocalDateTime.of(date, LocalTime.ofInstant(Instant.ofEpochSecond(timeArr.get(1)), ZoneId.systemDefault())) : beginTime;
 
-
-            //条件任务
-            if (param.getTaskType() == WaylineTaskTypeEnum.CONDITION) {
-                //如果是条件任务类型,需要在任务参数中添加条件。
-                waylineJob.setConditions(
-                        WaylineTaskConditionDTO.builder()
-                                .executableConditions(Objects.nonNull(param.getMinStorageCapacity()) ? WaylineTaskExecutableConditionDTO.builder().storageCapacity(param.getMinStorageCapacity()).build() : null)
-                                .readyConditions(WaylineTaskReadyConditionDTO.builder()
-                                        .batteryCapacity(param.getMinBatteryCapacity())
-                                        .beginTime(beginTime)
-                                        .endTime(endTime)
-                                        .build())
-                                .build());
-            }
-
-            ResponseResult response = this.publishOneFlightTask(waylineJob);
-            if (ResponseResult.CODE_SUCCESS != response.getCode()) {
-                return response;
-            }
-
+        if (WaylineTaskTypeEnum.IMMEDIATE != param.getTaskType() && endTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli() < System.currentTimeMillis()) {
+            return ResponseResult.error("任务已过期");
         }
+        //条件任务
+        if (param.getTaskType() == WaylineTaskTypeEnum.CONDITION) {
+            //如果是条件任务类型,需要在任务参数中添加条件。
+            waylineJob.setConditions(
+                    WaylineTaskConditionDTO.builder()
+                            .executableConditions(Objects.nonNull(param.getMinStorageCapacity()) ? WaylineTaskExecutableConditionDTO.builder().storageCapacity(param.getMinStorageCapacity()).build() : null)
+                            .readyConditions(WaylineTaskReadyConditionDTO.builder()
+                                    .batteryCapacity(param.getMinBatteryCapacity())
+                                    .beginTime(beginTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli())
+                                    .endTime(endTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli())
+                                    .build())
+                            .build());
+        } else {
+            waylineJob.setBeginTime(beginTime);
+        }
+
+        ResponseResult response = this.publishOneFlightTask(waylineJob);
+        if (ResponseResult.CODE_SUCCESS != response.getCode()) {
+            return response;
+        }
+
+
+        //新增多条数据
+        //开始日期
+//        String parentId = "";
+//        for (int i = 0; i < param.getExecuteStartTimeArr().size(); i++) {
+//            List<Long> timeArr = param.getExecuteStartTimeArr().get(i);
+//
+//            long beginTimeLong = 0L;
+//            long endTimeLong = 0L;
+//            LocalDateTime beginTime = null;
+//            if (i == 0) {
+//                //父,开始-结束为整个区间
+//                //开始日期
+//                LocalDate startDate = LocalDate.ofInstant(Instant.ofEpochSecond(param.getTaskDays().get(0)), ZoneId.systemDefault());
+//                beginTimeLong = LocalDateTime.of(startDate, LocalTime.ofInstant(Instant.ofEpochSecond(param.getExecuteStartTimeArr().get(0).get(0)), ZoneId.systemDefault()))
+//                        .atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
+//
+//                //结束日期
+//                LocalDate endDate = LocalDate.ofInstant(Instant.ofEpochSecond(param.getTaskDays().get(1)), ZoneId.systemDefault());
+//                endTimeLong = LocalDateTime.of(endDate, LocalTime.ofInstant(Instant.ofEpochSecond(param.getExecuteStartTimeArr().get(param.getExecuteStartTimeArr().size() - 1).get(0)), ZoneId.systemDefault()))
+//                        .atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
+//            } else {
+//                //子,开始-结束为当前区间
+//                //开始日期
+//                LocalDate date = LocalDate.ofInstant(Instant.ofEpochSecond(timeArr.get(0)), ZoneId.systemDefault());
+//                //任务执行开始时间
+//                beginTime = LocalDateTime.of(date, LocalTime.ofInstant(Instant.ofEpochSecond(timeArr.get(0)), ZoneId.systemDefault()));
+//                //任务结束时间
+//                LocalDateTime endTime = timeArr.size() > 1 && Objects.nonNull(timeArr.get(1)) ?
+//                        LocalDateTime.of(date, LocalTime.ofInstant(Instant.ofEpochSecond(timeArr.get(1)), ZoneId.systemDefault())) : beginTime;
+//
+//                beginTimeLong = beginTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
+//                endTimeLong = endTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
+//            }
+//
+//
+//            //保存数据
+//            WaylineJobEntity waylineJobEntity = WaylineJobEntity.builder()
+//                    .parentId(parentId.equals("") ? null : parentId)
+//                    .jobId(UUID.randomUUID().toString())
+//                    .name(param.getName())
+//                    .dockSn(param.getDockSn())
+//                    .fileId(param.getFileId())
+//                    .username(customClaim.getUsername())
+//                    .workspaceId(customClaim.getWorkspaceId())
+//
+//                    .beginTime(beginTimeLong)
+//                    .endTime(endTimeLong)
+//                    .status(WaylineJobStatusEnum.PENDING.getVal())
+//                    .taskType(param.getTaskType().getVal())
+//                    .waylineType(param.getWaylineType().getVal())
+//                    .outOfControlAction(param.getOutOfControlAction())
+//                    .batteryCapacity(param.getMinBatteryCapacity())
+//                    .rthAltitude(param.getRthAltitude())
+//                    .mediaCount(0)
+//                    .repFreVal(param.getRepFreVal())
+//                    .repFreType(param.getRepFreType())
+//                    .repRuleType(param.getRepRuleType())
+//                    .repRuleVal(param.getRepRuleVal())
+//                    .executeTimeArr(param.getTaskPeriods())
+//                    .executeStartTimeArr(param.getExecuteStartTimeArr())
+//                    .build();
+//
+//            Optional<WaylineJobDTO> waylineJobOpt = insertWaylineJob(waylineJobEntity);
+//
+//            if (waylineJobOpt.isEmpty()) {
+//                throw new SQLException("任务创建失败");
+//            }
+//
+//
+//            if (i == 0) {
+//                //把第一个当作父
+//                parentId = waylineJobEntity.getId().toString();
+//            }
+//            WaylineJobDTO waylineJob = waylineJobOpt.get();
+//
+//            //条件任务
+//            if (param.getTaskType() == WaylineTaskTypeEnum.CONDITION) {
+//                //如果是条件任务类型,需要在任务参数中添加条件。
+//                waylineJob.setConditions(
+//                        WaylineTaskConditionDTO.builder()
+//                                .executableConditions(Objects.nonNull(param.getMinStorageCapacity()) ? WaylineTaskExecutableConditionDTO.builder().storageCapacity(param.getMinStorageCapacity()).build() : null)
+//                                .readyConditions(WaylineTaskReadyConditionDTO.builder()
+//                                        .batteryCapacity(param.getMinBatteryCapacity())
+//                                        .beginTime(beginTimeLong)
+//                                        .endTime(endTimeLong)
+//                                        .build())
+//                                .build());
+//            } else {
+//                waylineJob.setBeginTime(beginTime);
+//            }
+//
+//            if (waylineJobOpt.isEmpty()) {
+//                throw new SQLException("任务创建失败");
+//            }
+//
+//            ResponseResult response = this.publishOneFlightTask(waylineJob);
+//            if (ResponseResult.CODE_SUCCESS != response.getCode()) {
+//                return response;
+//            }
+//        }
+
         return ResponseResult.success();
     }
 
@@ -481,7 +590,17 @@
     }
 
     @Override
-    public Boolean updateJob(WaylineJobDTO dto) {
+    public Boolean updateJob(WaylineJobDTO dto){
+
+        try {
+            if (dto.getStatus() == 3){
+                this.checkNextJob(dto);
+            }
+        }catch (SQLException e) {
+            throw new RuntimeException(e);
+        }
+
+
         return mapper.update(this.dto2Entity(dto),
                 new LambdaUpdateWrapper<WaylineJobEntity>()
                         .eq(WaylineJobEntity::getJobId, dto.getJobId())) > 0;
@@ -683,12 +802,206 @@
 //                .orderByDesc(WaylineJobEntity::getBeginTime)
 //        );
 
-        WaylineJobEntity waylineJobEntity = mapper.getLatest(workspaceId,waylineJobQueryParam);
+        WaylineJobEntity waylineJobEntity = mapper.getLatest(workspaceId, waylineJobQueryParam);
 
 
-       return waylineJobEntity;
+        return waylineJobEntity;
     }
 
+    @Override
+    public ResponseResult flyByArea(String sn, FlyAreaParam flyAreaParam) {
+
+        List<List<PointPOJO>> areaList = flyAreaParam.getAreaList();
+        PointPOJO dockPoint = flyAreaParam.getDockPoint();
+        Double radius = flyAreaParam.getRadius();
+
+        List<PointPOJO> centerPointList = new ArrayList<>();
+
+        //根据区域获取中心点
+        areaList.forEach(area -> {
+            PointPOJO centerPoint = GeoUtils.getCenterPoint(area);
+            centerPointList.add(centerPoint);
+        });
+
+        //巡逻目标集合
+        List<PointPOJO> targetList = new ArrayList<>();
+        //获取所有中心点之后,
+        centerPointList.forEach(centerPoint -> {
+            //判断各个中心点和机场点的距离
+            double distance = GeoUtils.distance(dockPoint.getLon(), dockPoint.getLat(), centerPoint.getLon(), centerPoint.getLat());
+
+            //当距离小于半径时,添加到目标集合中
+            if (distance <= radius) {
+                centerPoint.setDistance(distance);
+                targetList.add(centerPoint);
+            }
+        });
+
+        //按距离从近到远排序
+        targetList.sort(Comparator.comparing(PointPOJO::getDistance));
+
+        //后续为无人机操作逻辑
+        //先飞到空中
+        TakeoffToPointParam takeoffToPointParam = new TakeoffToPointParam();
+
+        takeoffToPointParam.setTargetLatitude(dockPoint.getLat());
+        takeoffToPointParam.setTargetLongitude(dockPoint.getLon());
+        //设置飞行高度
+        takeoffToPointParam.setTargetHeight(120.0);
+        //设置安全起飞高度
+        takeoffToPointParam.setSecurityTakeoffHeight(100.0);
+        //设置返航高度
+        takeoffToPointParam.setRthAltitude(100.0);
+        //设置失控操作
+        takeoffToPointParam.setRcLostAction(DroneRcLostActionEnum.RETURN_HOME);
+        //设置起飞速度
+        takeoffToPointParam.setMaxSpeed(10.0);
+        takeoffToPointParam.setExitWaylineWhenRcLost(WaylineRcLostActionEnum.EXECUTE_RC_LOST_ACTION);
+
+        //起飞
+        ResponseResult responseResult = controlService.takeoffToPoint(sn, takeoffToPointParam);
+
+        if (responseResult.getCode() != ResponseResult.CODE_SUCCESS) {
+            return responseResult;
+        }
+        //向目标点飞行
+
+        FlyToPointParam flyToPointParam = new FlyToPointParam();
+        flyToPointParam.setMaxSpeed(14);
+        List<PointDTO> pointDTOS = new ArrayList<>();
+        targetList.forEach(pointPOJO -> {
+            PointDTO pointDTO = new PointDTO();
+            pointDTO.setHeight(150.0);
+            pointDTO.setLongitude(pointPOJO.getLon());
+            pointDTO.setLatitude(pointPOJO.getLat());
+
+            pointDTOS.add(pointDTO);
+        });
+        flyToPointParam.setPoints(pointDTOS);
+        ResponseResult responseResult1 = controlService.flyToPoint(sn, flyToPointParam);
+
+        if (responseResult1.getCode() != ResponseResult.CODE_SUCCESS) {
+            return responseResult1;
+        }
+
+        //返航
+        //return_home
+
+
+        return ResponseResult.success();
+    }
+
+    @Override
+    public ResponseResult checkNextJob(WaylineJobDTO job)  throws SQLException  {
+
+        WaylineJobEntity params = new WaylineJobEntity();
+        params.setJobId(job.getJobId());
+
+
+        WaylineJobEntity currentJob = mapper.selectOne(Wrappers.query(params));
+        if (currentJob == null) {
+            return ResponseResult.error("该任务不存在");
+        }
+
+        //该任务没有多次时间
+        if (currentJob.getExecuteStartTimeArr() == null) {
+            return ResponseResult.success();
+        }
+
+        List<List<Long>> executeStartTimeArr = currentJob.getExecuteStartTimeArr();
+        int indexTime = -1;
+
+        long currentTime = System.currentTimeMillis();
+        for (int i = 0; i < executeStartTimeArr.size(); i++) {
+            Long startTime = Long.valueOf(executeStartTimeArr.get(i).get(0));
+            //如果当前时间小于开始时间
+            if (currentTime < startTime) {
+                //当前索引就是下一次要执行的时间
+                indexTime = i;
+                break;
+            }
+        }
+
+        List<Long> timeArr = currentJob.getExecuteStartTimeArr().get(indexTime);
+        LocalDate date = LocalDate.ofInstant(Instant.ofEpochSecond(timeArr.get(0)), ZoneId.systemDefault());
+        LocalDateTime beginDate = LocalDateTime.of(date, LocalTime.ofInstant(Instant.ofEpochSecond(timeArr.get(0)), ZoneId.systemDefault()));
+        LocalDateTime endDate = timeArr.size() > 1 && Objects.nonNull(timeArr.get(1)) ?
+                LocalDateTime.of(date, LocalTime.ofInstant(Instant.ofEpochSecond(timeArr.get(1)), ZoneId.systemDefault()))
+                : beginDate;
+
+        long beginTime = beginDate
+                .atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
+        long endTime = endDate
+                .atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
+
+
+        //添加一条新数据
+        WaylineJobEntity waylineJobEntity = WaylineJobEntity.builder()
+                .jobId(UUID.randomUUID().toString())
+                //大于1则拿前面的parentId,为1则拿第0个的id
+                .parentId(indexTime > 1 ? currentJob.getParentId().toString() : currentJob.getId().toString())
+                .name(currentJob.getName())
+                .dockSn(currentJob.getDockSn())
+                .fileId(currentJob.getFileId())
+                .username(currentJob.getUsername())
+                .workspaceId(currentJob.getWorkspaceId())
+
+                .beginTime(beginTime)
+                .endTime(endTime)
+                .status(WaylineJobStatusEnum.PENDING.getVal())
+                .taskType(currentJob.getTaskType())
+                .waylineType(currentJob.getWaylineType())
+                .outOfControlAction(currentJob.getOutOfControlAction())
+                .batteryCapacity(currentJob.getBatteryCapacity())
+                .rthAltitude(currentJob.getRthAltitude())
+                .mediaCount(0)
+                .repFreVal(currentJob.getRepFreVal())
+                .repFreType(currentJob.getRepFreType())
+                .repRuleType(currentJob.getRepRuleType())
+                .repRuleVal(currentJob.getRepRuleVal())
+                .executeTimeArr(currentJob.getExecuteTimeArr())
+                .executeStartTimeArr(currentJob.getExecuteStartTimeArr())
+                .build();
+
+        Optional<WaylineJobDTO> waylineJobOpt = insertWaylineJob(waylineJobEntity);
+
+        if (waylineJobOpt.isEmpty()) {
+            return ResponseResult.error("任务创建失败");
+        }
+
+        WaylineJobDTO waylineJob = waylineJobOpt.get();
+
+        LocalDateTime beginTimeNext = LocalDateTime.of(date, LocalTime.ofInstant(Instant.ofEpochSecond(timeArr.get(0)), ZoneId.systemDefault()));
+
+        LocalDateTime endTimeNext = timeArr.size() > 1 && Objects.nonNull(timeArr.get(1)) ?
+                LocalDateTime.of(date, LocalTime.ofInstant(Instant.ofEpochSecond(timeArr.get(1)), ZoneId.systemDefault())) : beginTimeNext;
+
+
+        //条件任务
+        if (currentJob.getTaskType() == 2) {
+            //如果是条件任务类型,需要在任务参数中添加条件。
+            waylineJob.setConditions(
+                    WaylineTaskConditionDTO.builder()
+                            .executableConditions(null)
+                            .readyConditions(WaylineTaskReadyConditionDTO.builder()
+                                    .batteryCapacity(currentJob.getBatteryCapacity())
+                                    .beginTime(beginTime)
+                                    .endTime(endTime)
+                                    .build())
+                            .build());
+        } else {
+            waylineJob.setBeginTime(beginDate);
+        }
+
+        ResponseResult response = this.publishOneFlightTask(waylineJob);
+        if (ResponseResult.CODE_SUCCESS != response.getCode()) {
+            return response;
+        }
+
+        return ResponseResult.success();
+    }
+
+
     private void pauseJob(String workspaceId, String dockSn, String jobId, WaylineJobStatusEnum statusEnum) {
         if (WaylineJobStatusEnum.PAUSED == statusEnum && jobId.equals(waylineRedisService.getPausedWaylineJobId(dockSn))) {
             waylineRedisService.setPausedWaylineJob(dockSn, jobId);

--
Gitblit v1.9.3