From 22f306496b583d3c25f2d3354441b0e29d6840cf Mon Sep 17 00:00:00 2001
From: liusuyi <1951119284@qq.com>
Date: Fri, 26 Dec 2025 09:47:20 +0800
Subject: [PATCH] 飞行历史同步视频从新接口获取

---
 ard-work/src/main/java/com/ard/work/service/impl/ArdFlightTaskServiceImpl.java |  294 +++++++++++++++++++++++++---------------------------------
 1 files changed, 129 insertions(+), 165 deletions(-)

diff --git a/ard-work/src/main/java/com/ard/work/service/impl/ArdFlightTaskServiceImpl.java b/ard-work/src/main/java/com/ard/work/service/impl/ArdFlightTaskServiceImpl.java
index 4ab7d19..5d97e6a 100644
--- a/ard-work/src/main/java/com/ard/work/service/impl/ArdFlightTaskServiceImpl.java
+++ b/ard-work/src/main/java/com/ard/work/service/impl/ArdFlightTaskServiceImpl.java
@@ -10,10 +10,12 @@
 import com.ard.work.component.forest.TyClient;
 import com.ard.work.domain.dto.BoxHistoryDTO;
 import com.ard.work.domain.dto.BoxPhotosDTO;
+import com.ard.work.domain.dto.BoxVideosDTO;
 import com.ard.work.domain.entity.ArdFlightTask;
 import com.ard.work.domain.entity.ArdMedia;
 import com.ard.work.domain.receiver.BoxHistoryReceiver;
 import com.ard.work.domain.receiver.BoxPhotosReceiver;
+import com.ard.work.domain.receiver.BoxVideosReceiver;
 import com.ard.work.domain.receiver.TyHttpCommonReceiver;
 import com.ard.work.mapper.ArdFlightTaskMapper;
 import com.ard.work.mapper.ArdMediaMapper;
@@ -80,7 +82,7 @@
     /**
      * 同步所有服务的飞行历史
      */
-    @Scheduled(fixedDelay = 10000)
+    @Scheduled(fixedDelay = 5000)
     public void syncAllFlightHistory() {
         List<String> serverIds = ardServerInfoService.getServerIdsList();
         for (String serverId : serverIds) {
@@ -122,6 +124,10 @@
         if (ardFlightTask == null) {
             // 如果不存在,则插入新记录
             log.debug("insert task {}", boxHistoryReceiver.getTaskId());
+            Date endTime = null;
+            if (boxHistoryReceiver.getEndTime() != null) {
+                endTime = DateUtils.dateTime(DateUtils.YYYY_MM_DD_HH_MM_SS, boxHistoryReceiver.getEndTime());
+            }
             // 创建FlightTask实体对象并填充数据
             ArdFlightTask flightTask = ArdFlightTask.builder()
                     .taskId(boxHistoryReceiver.getTaskId())
@@ -134,7 +140,7 @@
                     .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()))
+                    .endTime(endTime)
                     .flightMileage(boxHistoryReceiver.getFlightMileage())
                     .flightDuration(boxHistoryReceiver.getFlightDuration())
                     .aveSpeed(boxHistoryReceiver.getAveSpeed())
@@ -154,10 +160,8 @@
             if (rows > 0) {
                 // 删除旧的媒体记录,防止重复插入
                 ardMediaMapper.deleteArdMediaByTaskId(flightTask.getTaskId());
-
                 // 插入视频
-                insertVideoToDatabase(flightTask, boxHistoryReceiver.getVideoPathList());
-
+                insertVideoToDatabase(flightTask, serverId, boxHistoryReceiver.getBoxSn());
                 // 插入图片
                 insertPhotoToDatabase(flightTask, serverId, boxHistoryReceiver.getBoxSn());
             }
@@ -165,8 +169,8 @@
             // 如果存在,则更新记录
             log.debug("Updating task {}", boxHistoryReceiver.getTaskId());
             updateFlightTask(ardFlightTask, boxHistoryReceiver);
-            // 增量更新
-            updateVideoToDatabase(ardFlightTask, boxHistoryReceiver.getVideoPathList());
+            // 增量更新视频
+            updateVideoToDatabase(ardFlightTask, serverId, boxHistoryReceiver.getBoxSn());
             // 增量更新图片
             updatePhotoToDatabase(ardFlightTask, serverId, boxHistoryReceiver.getBoxSn());
 
@@ -177,10 +181,12 @@
         boolean needUpdate = false;
 
         // endTime 更新(重要!!!)
-        Date newEnd = DateUtils.dateTime(DateUtils.YYYY_MM_DD_HH_MM_SS, remote.getEndTime());
-        if (newEnd != null && (local.getEndTime() == null || !local.getEndTime().equals(newEnd))) {
-            local.setEndTime(newEnd);
-            needUpdate = true;
+        if (remote.getEndTime() != null) {
+            Date newEnd = DateUtils.dateTime(DateUtils.YYYY_MM_DD_HH_MM_SS, remote.getEndTime());
+            if (local.getEndTime() == null || !local.getEndTime().equals(newEnd)) {
+                local.setEndTime(newEnd);
+                needUpdate = true;
+            }
         }
 
         // photoCount 更新
@@ -208,171 +214,40 @@
         TyHttpCommonReceiver<List<BoxHistoryReceiver>> boxHistory = tyClient.getBoxHistory(serverId, boxHistoryDTO);
         return boxHistory.getContent();
     }
-
-    //调用接口获取架次图片
+    // 调用接口获取架次图片
     private List<BoxPhotosReceiver> getBoxPhotos(String serverId, BoxPhotosDTO boxPhotosDTO) {
         TyHttpCommonReceiver<List<BoxPhotosReceiver>> boxPhotos = tyClient.getBoxPhotos(serverId, boxPhotosDTO);
         return boxPhotos.getContent();
     }
-
-
-    // 插入视频记录
-    private void insertVideoToDatabase(ArdFlightTask flightTask, List<String> videoPathList) {
-        if (videoPathList == null || videoPathList.isEmpty()) {
-            return;
-        }
-        String boxSn = flightTask.getBoxSn();
-        for (String videoPath : videoPathList) {
-            //videoPath = "https://192.168.1.3:9001/record/DBM250974065008/8212fd8e89814d66b6c32f48d05f5101.mp4";
-            ArdMedia media = ArdMedia.builder()
-                    .id(IdUtils.simpleUUID())
-                    .taskId(flightTask.getTaskId())
-                    .mediaType(1)
-                    .sourceUrl(videoPath)
-                    .fileSize(getFileSizeByUrl(videoPath))
-                    .build();
-
-            // ---- 1. 视频上传(失败不抛异常,返回 null) ----
-
-            CompletableFuture<String> videoFuture = CompletableFuture.supplyAsync(() -> {
-                try (InputStream inputStream = openUrlInputStream(videoPath, 5000, 10000)) {
-                    if (inputStream != null) {
-                        return ossServiceContext.upload(
-                                "record",
-                                boxSn + "/" + media.getId() + ".mp4",
-                                inputStream,
-                                MimeTypeUtils.VIDEO_MP4
-                        );
-                    }
-                } catch (Exception e) {
-                    e.printStackTrace();
-                }
-                return null;
-            }, threadPoolTaskExecutor);
-            // ---- 2. 缩略图上传(失败不抛异常,返回 null) ----
-
-            CompletableFuture<String> thumbFuture = CompletableFuture.supplyAsync(() -> {
-                try {
-                    try (ByteArrayInputStream thumbStream = generateThumbnail(videoPath, 1, 200)) {
-                        if (thumbStream != null) {
-                            return ossServiceContext.upload(
-                                    "record",
-                                    boxSn + "/" + media.getId() + ".jpg",
-                                    thumbStream,
-                                    MimeTypeUtils.IMAGE_JPEG
-                            );
-                        }
-                    }
-                } catch (Exception e) {
-                    e.printStackTrace();
-                }
-                return null;
-            }, threadPoolTaskExecutor);
-
-            // 两个完成后写数据库(任意失败不阻断流程)
-            videoFuture.thenCombine(thumbFuture, (vUrl, tUrl) -> {
-                media.setMediaUrl(vUrl);
-                media.setThumbnailUrl(tUrl);
-                media.setCreateTime(new Date());
-                return media;
-            }).thenAcceptAsync(ardMediaMapper::insertArdMedia, threadPoolTaskExecutor);
-        }
+    // 调用接口获取架次视频
+    private List<BoxVideosReceiver> getBoxVideos(String serverId, BoxVideosDTO boxVideosDTO) {
+        TyHttpCommonReceiver<List<BoxVideosReceiver>> boxVideos = tyClient.getBoxVideos(serverId, boxVideosDTO);
+        return boxVideos.getContent();
     }
 
-    private void updateVideoToDatabase(ArdFlightTask flightTask, List<String> videoPathList) {
-        if (videoPathList == null) {
-            return;
-        }
-        // 需要插入新的视频
-        List<ArdMedia> existingVideos = ardMediaMapper.selectArdMediaByTaskIdAndType(flightTask.getTaskId(), 1);
-        Integer count = existingVideos.size();//获取本地库视频数量
-        int size = videoPathList.size();//获取接口返回的视频数量
-        if (count != null && size > count) {
-            log.info("任务【{}】录像数量不一致,需要更新数据库", flightTask.getTaskId());
-
-            // 提取现有的视频路径
-            List<String> existingVideoPaths = existingVideos.stream()
-                    .map(ArdMedia::getSourceUrl) // 获取每个视频的 URL
-                    .collect(Collectors.toList());
-
-            // 从接口返回的视频路径中找出新的视频
-            List<String> newVideos = videoPathList.stream()
-                    .filter(videoPath -> !existingVideoPaths.contains(videoPath)) // 过滤出新的视频
-                    .collect(Collectors.toList());
-            if (!newVideos.isEmpty()) {
-                String boxSn = flightTask.getBoxSn();
-                // 插入新的视频记录
-                for (String videoPath : newVideos) {
-                    ArdMedia ardMedia = ArdMedia.builder()
-                            .id(IdUtils.simpleUUID())
-                            .taskId(flightTask.getTaskId())
-                            .mediaType(1) // 1表示视频
-                            .fileSize(getFileSizeByUrl(videoPath))
-                            .sourceUrl(videoPath)
-                            .build();
-                    // ---- 1. 视频上传(失败不抛异常,返回 null) ----
-                    CompletableFuture<String> videoFuture = CompletableFuture.supplyAsync(() -> {
-                        try (InputStream inputStream = openUrlInputStream(videoPath, 5000, 10000)) {
-                            if (inputStream != null) {
-                                return ossServiceContext.upload(
-                                        "record",
-                                        boxSn + "/" + ardMedia.getId() + ".mp4",
-                                        inputStream,
-                                        MimeTypeUtils.VIDEO_MP4
-                                );
-                            }
-                        } catch (Exception e) {
-                            e.printStackTrace();
-                        }
-                        return null;
-                    }, threadPoolTaskExecutor);
-                    // ---- 2. 缩略图上传(失败不抛异常,返回 null) ----
-                    CompletableFuture<String> thumbFuture = CompletableFuture.supplyAsync(() -> {
-                        try {
-                            try (ByteArrayInputStream thumbStream = generateThumbnail(videoPath, 1, 200)) {
-                                if (thumbStream != null) {
-                                    return ossServiceContext.upload(
-                                            "record",
-                                            boxSn + "/" + ardMedia.getId() + ".jpg",
-                                            thumbStream,
-                                            MimeTypeUtils.IMAGE_JPEG
-                                    );
-                                }
-                            }
-                        } catch (Exception e) {
-                            e.printStackTrace();
-                        }
-                        return null;
-                    }, threadPoolTaskExecutor);
-                    // 两个完成后写数据库(任意失败不阻断流程)
-                    videoFuture.thenCombine(thumbFuture, (vUrl, tUrl) -> {
-                        ardMedia.setMediaUrl(vUrl);
-                        ardMedia.setThumbnailUrl(tUrl);
-                        ardMedia.setCreateTime(new Date());
-                        return ardMedia;
-                    }).thenAcceptAsync(ardMediaMapper::insertArdMedia, threadPoolTaskExecutor);
-                }
-                // 更新任务的视频数量
-                flightTask.setVideoCount(flightTask.getVideoCount() + newVideos.size());
-                ardFlightTaskMapper.updateArdFlightTask(flightTask);
-            }
-        }
-    }
-
-    // 插入图片记录
     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(500);
+        boxPhotosDTO.setPageSize(100);
         List<BoxPhotosReceiver> photoList = getBoxPhotos(serverId, boxPhotosDTO);
         if (photoList != null && !photoList.isEmpty()) {
             addPhotos(flightTask, photoList);
         }
     }
-
+    private void insertVideoToDatabase(ArdFlightTask flightTask, String serverId, String boxSn) {
+        BoxVideosDTO boxVideosDTO = new BoxVideosDTO();
+        boxVideosDTO.setTaskId(flightTask.getTaskId());
+        boxVideosDTO.setBoxSn(boxSn);
+        boxVideosDTO.setPageIndex(1);
+        boxVideosDTO.setPageSize(100);
+        List<BoxVideosReceiver> videoList = getBoxVideos(serverId, boxVideosDTO);
+        if (videoList != null && !videoList.isEmpty()) {
+            addVideos(flightTask, videoList);
+        }
+    }
     private void updatePhotoToDatabase(ArdFlightTask flightTask, String serverId, String boxSn) {
 
         // 获取本地数据库中已存在的图片记录(类型为 0 表示图片)
@@ -411,7 +286,44 @@
             }
         }
     }
+    private void updateVideoToDatabase(ArdFlightTask flightTask, String serverId, String boxSn) {
 
+        // 获取本地数据库中已存在的图片记录(类型为 0 表示图片)
+        List<ArdMedia> existingVideos = ardMediaMapper.selectArdMediaByTaskIdAndType(flightTask.getTaskId(), 1);
+        int count = existingVideos.size(); //获取本地库视频数量
+        // 查询图片
+        BoxVideosDTO boxVideosDTO = BoxVideosDTO.builder()
+                .taskId(flightTask.getTaskId())
+                .boxSn(boxSn)
+                .pageIndex(1)
+                .pageSize(500)
+                .build();
+        TyHttpCommonReceiver<List<BoxVideosReceiver>> boxVideos = tyClient.getBoxVideos(serverId, boxVideosDTO);
+        List<BoxVideosReceiver> videoList = boxVideos.getContent();
+        int size = videoList.size();
+
+        if (size > count) {
+            log.info("任务【{}】视频数量不一致,需要更新数据库", flightTask.getTaskId());
+            // 需要插入新的视频
+            // 提取现有的图片路径(根据 imgUrl 来判断是否重复)
+            List<String> existingVideoUrls = existingVideos.stream()
+                    .map(ArdMedia::getSourceUrl) // 提取 ArdMedia 中的图片 URL
+                    .collect(Collectors.toList());
+
+            // 筛选出 photoList 中没有出现在 existingPhotos 中的新图片
+            List<BoxVideosReceiver> newVideos = videoList.stream()
+                    .filter(photo -> !existingVideoUrls.contains(photo.getImgUrl())) // 过滤出新视频
+                    .collect(Collectors.toList());
+            if (!newVideos.isEmpty()) {
+                // 插入新的视频记录
+                addVideos(flightTask, newVideos);
+
+                // 更新任务的视频数量
+                flightTask.setVideoCount(flightTask.getPhotoCount() + newVideos.size());
+                ardFlightTaskMapper.updateArdFlightTask(flightTask);
+            }
+        }
+    }
     private void addPhotos(ArdFlightTask flightTask, List<BoxPhotosReceiver> photoList) {
         String boxSn = flightTask.getBoxSn();
         for (BoxPhotosReceiver photo : photoList) {
@@ -451,6 +363,63 @@
                     });
         }
     }
+    private void addVideos(ArdFlightTask flightTask, List<BoxVideosReceiver> videoList) {
+        String boxSn = flightTask.getBoxSn();
+        for (BoxVideosReceiver video : videoList) {
+            ArdMedia ardMedia = ArdMedia.builder()
+                    .id(IdUtils.simpleUUID())
+                    .taskId(flightTask.getTaskId())
+                    .mediaType(1) // 1表示视频
+                    .fileSize(getFileSizeByUrl(video.getImgUrl()))
+                    .sourceUrl(video.getImgUrl())
+                    .captureTime(DateUtils.parseDate(video.getStartTime()))
+                    .build();
+            // 异步上传文件到OSS,并在上传完成后插入数据库
+            // ---- 1. 视频上传(失败不抛异常,返回 null) ----
+            CompletableFuture<String> videoFuture = CompletableFuture.supplyAsync(() -> {
+                try (InputStream inputStream = openUrlInputStream(ardMedia.getSourceUrl(), 5000, 10000)) {
+                    if (inputStream != null) {
+                        return ossServiceContext.upload(
+                                "record",
+                                boxSn + "/" + ardMedia.getId() + ".mp4",
+                                inputStream,
+                                MimeTypeUtils.VIDEO_MP4
+                        );
+                    }
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+                return null;
+            }, threadPoolTaskExecutor);
+            // ---- 2. 缩略图上传(失败不抛异常,返回 null) ----
+
+            CompletableFuture<String> thumbFuture = CompletableFuture.supplyAsync(() -> {
+                try {
+                    try (ByteArrayInputStream thumbStream = generateThumbnail(ardMedia.getSourceUrl(), 1, 200)) {
+                        if (thumbStream != null) {
+                            return ossServiceContext.upload(
+                                    "record",
+                                    boxSn + "/" + ardMedia.getId() + ".jpg",
+                                    thumbStream,
+                                    MimeTypeUtils.IMAGE_JPEG
+                            );
+                        }
+                    }
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+                return null;
+            }, threadPoolTaskExecutor);
+
+            // 两个完成后写数据库(任意失败不阻断流程)
+            videoFuture.thenCombine(thumbFuture, (vUrl, tUrl) -> {
+                ardMedia.setMediaUrl(vUrl);
+                ardMedia.setThumbnailUrl(tUrl);
+                ardMedia.setCreateTime(new Date());
+                return ardMedia;
+            }).thenAcceptAsync(ardMediaMapper::insertArdMedia, threadPoolTaskExecutor);
+        }
+    }
 
     // 获取文件大小
     private long getFileSizeByUrl(String fileUrl) {
@@ -464,12 +433,8 @@
             return -1;
         }
     }
-
     // 生成视频缩略图
-    public ByteArrayInputStream generateThumbnail(
-            String videoFile,
-            int skipSeconds,
-            int targetWidth) {
+    public ByteArrayInputStream generateThumbnail(String videoFile, int skipSeconds, int targetWidth) {
         String ffmpegPath = "";
         if (osSelect.isWindows()) {
             ffmpegPath = "ffmpeg";
@@ -533,7 +498,6 @@
             throw new RuntimeException("FFmpeg 生成缩略图失败", e);
         }
     }
-
     /**
      * 将 URL 转成 InputStream
      *

--
Gitblit v1.9.3