From 23b1e3ac371e71536252415f777188607c291cf2 Mon Sep 17 00:00:00 2001
From: liusuyi <1951119284@qq.com>
Date: Tue, 18 Nov 2025 17:13:53 +0800
Subject: [PATCH] 增量媒体库

---
 ard-work/src/main/java/com/ard/work/service/impl/ArdFlightTaskServiceServiceImpl.java |  161 ++++++++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 138 insertions(+), 23 deletions(-)

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..2e19dc8 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,22 @@
 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.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.net.ssl.*;
 import java.io.InputStream;
 import java.net.URL;
+import java.util.ArrayList;
 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 {
 
@@ -127,24 +124,30 @@
         flightTask.setCreateTime(DateUtils.getNowDate());
 
         // 检查是否已经存在相同任务ID的记录
-        ArdFlightTask ardFlightTaskById = ardFlightTaskMapper.getArdFlightTaskById(flightTask.getTaskId());
-        if (ardFlightTaskById != null) {
-            return;
-        }
+        ArdFlightTask ardFlightTask = ardFlightTaskMapper.getArdFlightTaskById(flightTask.getTaskId());
+        if (ardFlightTask == null) {
+            // 如果不存在,则插入新记录
+            log.info("Syncing task {}", boxHistoryReceiver.getTaskId());
+            // 插入新记录
+            int rows = ardFlightTaskMapper.insertArdFlightTask(flightTask);
+            if (rows > 0) {
+                // 删除旧的媒体记录,防止重复插入
+                ardMediaMapper.deleteArdMediaByTaskId(flightTask.getTaskId());
 
-        System.out.println("Syncing task " + boxHistoryReceiver.getTaskId());
+                // 插入视频
+                syncVideoToDatabase(flightTask, boxHistoryReceiver.getVideoPathList());
 
-        // 插入新记录
-        int rows = ardFlightTaskMapper.insertArdFlightTask(flightTask);
-        if (rows > 0) {
-            // 删除旧的媒体记录,防止重复插入
-            ardMediaMapper.deleteArdMediaByTaskId(flightTask.getTaskId());
+                // 插入图片
+                syncPhotoToDatabase(flightTask, serverId, boxHistoryReceiver.getBoxSn());
+            }
+        } else {
+            // 如果存在,则更新记录
+            log.info("Updating task {}", boxHistoryReceiver.getTaskId());
+            // 增量更新
+            updateVideoToDatabase(ardFlightTask, boxHistoryReceiver.getVideoPathList());
+            // 增量更新图片
+            updatePhotoToDatabase(ardFlightTask, serverId, boxHistoryReceiver.getBoxSn());
 
-            // 插入视频
-            syncVideoToDatabase(flightTask, boxHistoryReceiver.getVideoPathList());
-
-            // 插入图片
-            syncPhotoToDatabase(flightTask, serverId, boxHistoryReceiver.getBoxSn());
         }
     }
 
@@ -170,6 +173,58 @@
         }
     }
 
+    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> newVideos = getNewVideos(existingVideos, videoPathList);
+            if (!newVideos.isEmpty()) {
+                // 插入新的视频记录
+                for (String videoPath : newVideos) {
+                    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
+                                ardMedia.setCreateTime(new Date());
+                                ardMediaMapper.insertArdMedia(ardMedia);  // 插入数据库
+                            });
+                }
+
+                // 更新任务的视频数量
+                flightTask.setVideoCount(flightTask.getVideoCount() + newVideos.size());
+                ardFlightTaskMapper.updateArdFlightTask(flightTask);
+            }
+        }
+    }
+
+    // 获取需要插入的新视频路径
+    private List<String> getNewVideos(List<ArdMedia> existingVideos, List<String> videoPathList) {
+        // 提取现有的视频路径
+        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());
+
+        return newVideos;
+    }
+
     // 插入图片记录
     private void syncPhotoToDatabase(ArdFlightTask flightTask, String serverId, String boxSn) {
         // 查询图片
@@ -177,7 +232,7 @@
         boxPhotosDTO.setTaskId(flightTask.getTaskId());
         boxPhotosDTO.setBoxSn(boxSn);
         boxPhotosDTO.setPageIndex(1);
-        boxPhotosDTO.setPageSize(1000);
+        boxPhotosDTO.setPageSize(500);
 
         TyHttpCommonReceiver<List<BoxPhotosReceiver>> boxPhotos = tyClient.getBoxPhotos(serverId, boxPhotosDTO);
         List<BoxPhotosReceiver> photoList = boxPhotos.getContent();
@@ -203,6 +258,66 @@
         }
     }
 
+    private void updatePhotoToDatabase(ArdFlightTask flightTask, String serverId, String boxSn) {
+        int count = flightTask.getPhotoCount(); //获取本地库图片数量
+        // 查询图片
+        BoxPhotosDTO boxPhotosDTO = new BoxPhotosDTO();
+        boxPhotosDTO.setTaskId(flightTask.getTaskId());
+        boxPhotosDTO.setBoxSn(boxSn);
+        boxPhotosDTO.setPageIndex(1);
+        boxPhotosDTO.setPageSize(500);
+        TyHttpCommonReceiver<List<BoxPhotosReceiver>> boxPhotos = tyClient.getBoxPhotos(serverId, boxPhotosDTO);
+        List<BoxPhotosReceiver> photoList = boxPhotos.getContent();
+        int size = photoList.size();
+
+        if (size > count) {
+            log.info("图片数量不一致,需要更新数据库");
+            // 获取本地数据库中已存在的图片记录(类型为 0 表示图片)
+            List<ArdMedia> existingPhotos = ardMediaMapper.selectArdMediaByTaskIdAndType(flightTask.getTaskId(), 0);
+            // 需要插入新的视频
+            List<BoxPhotosReceiver> newPhotos = getNewPhotos(existingPhotos, photoList);
+            if (!newPhotos.isEmpty()) {
+                // 插入新的视频记录
+                for (BoxPhotosReceiver photo : newPhotos) {
+                    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);  // 插入数据库
+                            });
+                }
+
+                // 更新任务的视频数量
+                flightTask.setPhotoCount(flightTask.getPhotoCount() + newPhotos.size());
+                ardFlightTaskMapper.updateArdFlightTask(flightTask);
+            }
+        }
+    }
+
+    // 获取需要插入的新图片
+    private List<BoxPhotosReceiver> getNewPhotos(List<ArdMedia> existingPhotos, List<BoxPhotosReceiver> photoList) {
+        // 提取现有的图片路径(根据 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());
+
+        return newPhotos; // 返回新增的图片列表
+    }
+
     // 通用的上传方法,支持视频和图片等文件上传
     public String uploadFileToOss(String boxSn, String fileUrl, String bucket, String contentType) {
         InputStream fileInputStream = null;

--
Gitblit v1.9.3