From 6bdda41435c30affe62af2bea8861da916c0c56d Mon Sep 17 00:00:00 2001
From: liusuyi <1951119284@qq.com>
Date: Fri, 26 Dec 2025 14:41:31 +0800
Subject: [PATCH] 优化架次和媒体

---
 /dev/null                                                                        |  202 -------
 ard-work/src/main/java/com/ard/work/domain/entity/ArdMediaPic.java               |   26 +
 ard-work/src/main/java/com/ard/work/mapper/ArdMediaPicMapper.java                |   41 +
 ard-work/src/main/java/com/ard/work/service/impl/ArdFlightTaskServiceImpl.java   |  397 --------------
 ard-work/src/main/java/com/ard/work/mapper/ArdMediaVideoMapper.java              |   36 +
 ard-work/src/main/resources/mapper/ArdMediaVideoMapper.xml                       |  118 ++++
 ard-work/src/main/java/com/ard/work/domain/entity/ArdMediaVideo.java             |   28 +
 ard-work/src/main/resources/mapper/ArdMediaPicMapper.xml                         |   84 +++
 ard-admin/src/main/java/com/ard/web/controller/work/ArdFlightTaskController.java |   78 +++
 ard-work/src/main/java/com/ard/work/service/IArdMediaService.java                |   20 
 ard-admin/src/main/java/com/ard/web/controller/work/UavBaseController.java       |   30 -
 ard-work/src/main/java/com/ard/work/service/impl/ArdMediaServiceImpl.java        |  480 ++++++++++++++++++
 12 files changed, 912 insertions(+), 628 deletions(-)

diff --git a/ard-admin/src/main/java/com/ard/web/controller/work/ArdFlightTaskController.java b/ard-admin/src/main/java/com/ard/web/controller/work/ArdFlightTaskController.java
new file mode 100644
index 0000000..008e125
--- /dev/null
+++ b/ard-admin/src/main/java/com/ard/web/controller/work/ArdFlightTaskController.java
@@ -0,0 +1,78 @@
+package com.ard.web.controller.work;
+
+import com.ard.common.core.controller.BaseController;
+import com.ard.common.core.page.TableDataInfo;
+import com.ard.work.domain.dto.*;
+import com.ard.work.domain.entity.ArdFlightTask;
+import com.ard.work.domain.entity.ArdFlightTaskPart;
+import com.ard.work.domain.entity.ArdMediaPic;
+import com.ard.work.domain.entity.ArdMediaVideo;
+import com.ard.work.service.IArdFlightTaskPartService;
+import com.ard.work.service.IArdFlightTaskService;
+import com.ard.work.service.IArdMediaService;
+import com.ard.work.service.ITyService;
+import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+import com.github.xiaoymin.knife4j.annotations.ApiSort;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * 飞行架次管理接口
+ * ArdFlightController
+ *
+ * @author liusuyi
+ * @date 2024年10月21日13:52
+ **/
+@Api(tags = "飞行架次管理接口")
+@ApiSort(value = 2)
+@RequestMapping("/uav/base")
+@RestController
+public class ArdFlightTaskController extends BaseController {
+
+    @Resource
+    private IArdFlightTaskService ardFlightTaskService;
+    @Resource
+    private IArdFlightTaskPartService ardFlightTaskPartService;
+    @Resource
+    private IArdMediaService ardMediaService;
+
+
+    @ApiOperation("获取飞行架次")
+    @ApiOperationSupport(order = 1)
+    @GetMapping("/getFlightTask")
+    public TableDataInfo getFlightTask(ArdFlightTask ardFlightTask) {
+        startPage();
+        List<ArdFlightTask> list = ardFlightTaskService.selectArdFlightTask(ardFlightTask);
+        return getDataTable(list);
+    }
+
+    @ApiOperation("获取架次飞行轨迹")
+    @ApiOperationSupport(order = 2)
+    @GetMapping("/getCompleteFlightData")
+    public TableDataInfo getCompleteFlightData(ArdFlightTaskPart ardFlightTaskPart) {
+        List<UavFlightStateDTO> completeFlightData = ardFlightTaskPartService.getCompleteFlightData(ardFlightTaskPart);
+        return getDataTable(completeFlightData);
+    }
+
+    @ApiOperation("获取架次图片数据")
+    @ApiOperationSupport(order = 3)
+    @GetMapping("/getMediaPicList")
+    public TableDataInfo getMediaPicList(ArdMediaPic ardMedia) {
+        startPage();
+        List<ArdMediaPic> list = ardMediaService.selectArdMediaPicList(ardMedia);
+        return getDataTable(list);
+    }
+
+    @ApiOperation("获取架次录像数据")
+    @ApiOperationSupport(order = 4)
+    @GetMapping("/getMediaVideoList")
+    public TableDataInfo getMediaVideoList(ArdMediaVideo ardMedia) {
+        startPage();
+        List<ArdMediaVideo> list = ardMediaService.selectArdMediaVideoList(ardMedia);
+        return getDataTable(list);
+    }
+}
\ No newline at end of file
diff --git a/ard-admin/src/main/java/com/ard/web/controller/work/UavBaseController.java b/ard-admin/src/main/java/com/ard/web/controller/work/UavBaseController.java
index bc41a9c..0904ee9 100644
--- a/ard-admin/src/main/java/com/ard/web/controller/work/UavBaseController.java
+++ b/ard-admin/src/main/java/com/ard/web/controller/work/UavBaseController.java
@@ -5,9 +5,7 @@
 import com.ard.common.core.page.TableDataInfo;
 import com.ard.work.domain.dto.*;
 import com.ard.work.domain.dto.telemetry.TelemetryData;
-import com.ard.work.domain.entity.ArdFlightTask;
-import com.ard.work.domain.entity.ArdFlightTaskPart;
-import com.ard.work.domain.entity.ArdMedia;
+import com.ard.work.domain.entity.*;
 import com.ard.work.domain.receiver.*;
 import com.ard.work.service.IArdFlightTaskPartService;
 import com.ard.work.service.IArdFlightTaskService;
@@ -70,32 +68,6 @@
     public AjaxResult getBoxHistory(@RequestBody BoxHistoryDTO boxHistoryDTO) {
         List<BoxHistoryReceiver> boxHistory = tyService.getBoxHistory(boxHistoryDTO);
         return AjaxResult.success(boxHistory);
-    }
-
-    @ApiOperation("获取飞行架次")
-    @ApiOperationSupport(order = 4)
-    @GetMapping("/getFlightTask")
-    public TableDataInfo getFlightTask(ArdFlightTask ardFlightTask) {
-        startPage();
-        List<ArdFlightTask> list = ardFlightTaskService.selectArdFlightTask(ardFlightTask);
-        return getDataTable(list);
-    }
-
-    @ApiOperation("获取架次飞行轨迹")
-    @ApiOperationSupport(order = 4)
-    @GetMapping("/getCompleteFlightData")
-    public TableDataInfo getCompleteFlightData(ArdFlightTaskPart ardFlightTaskPart) {
-        List<UavFlightStateDTO> completeFlightData = ardFlightTaskPartService.getCompleteFlightData(ardFlightTaskPart);
-        return getDataTable(completeFlightData);
-    }
-
-    @ApiOperation("获取媒体数据")
-    @ApiOperationSupport(order = 4)
-    @GetMapping("/getMediaList")
-    public TableDataInfo getMediaList(ArdMedia ardMedia) {
-        startPage();
-        List<ArdMedia> list = ardMediaService.selectArdMediaList(ardMedia);
-        return getDataTable(list);
     }
 
     @ApiOperation("获取任务照片")
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
deleted file mode 100644
index f5b97d5..0000000
--- a/ard-work/src/main/java/com/ard/work/domain/entity/ArdMedia.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package com.ard.work.domain.entity;
-
-import com.ard.common.core.domain.BaseEntity;
-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
-    private Integer taskId;            // 任务ID(外键关联飞行任务)
-    private Integer mediaType;         // 媒体类型(0"photo" 或 1"video")
-    private Long fileSize;             // 文件大小
-    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/ArdMediaPic.java b/ard-work/src/main/java/com/ard/work/domain/entity/ArdMediaPic.java
new file mode 100644
index 0000000..d5f4b34
--- /dev/null
+++ b/ard-work/src/main/java/com/ard/work/domain/entity/ArdMediaPic.java
@@ -0,0 +1,26 @@
+package com.ard.work.domain.entity;
+
+import com.ard.common.core.domain.BaseEntity;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.*;
+
+import java.util.Date;
+
+@EqualsAndHashCode(callSuper = true)
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class ArdMediaPic extends BaseEntity {
+    private Long id;
+    private Integer taskId;
+    private Long fileSize;
+    private String fileMd5;
+    private String mediaUrl;
+    private String sourceUrl;
+    private Double longitude;
+    private Double latitude;
+    private Double height;
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date captureTime;
+}
diff --git a/ard-work/src/main/java/com/ard/work/domain/entity/ArdMediaVideo.java b/ard-work/src/main/java/com/ard/work/domain/entity/ArdMediaVideo.java
new file mode 100644
index 0000000..9611eb5
--- /dev/null
+++ b/ard-work/src/main/java/com/ard/work/domain/entity/ArdMediaVideo.java
@@ -0,0 +1,28 @@
+package com.ard.work.domain.entity;
+
+
+import com.ard.common.core.domain.BaseEntity;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.*;
+
+import java.util.Date;
+
+@EqualsAndHashCode(callSuper = true)
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class ArdMediaVideo extends BaseEntity {
+    private Long id;
+    private String name;
+    private Long fileSize;
+    private String mediaUrl;
+    private String sourceUrl;
+    private String thumbnailUrl;
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date startTime;
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date endTime;
+    private Integer spanSeconds;
+    private 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
deleted file mode 100644
index 5a45bf6..0000000
--- a/ard-work/src/main/java/com/ard/work/mapper/ArdMediaMapper.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package com.ard.work.mapper;
-
-import com.ard.work.domain.entity.ArdMedia;
-import org.apache.ibatis.annotations.Mapper;
-import org.apache.ibatis.annotations.Param;
-
-import java.util.List;
-
-
-public interface ArdMediaMapper {
-
-    /**
-     * 查询媒体数据列表
-     *
-     * @param ardMedia 媒体数据
-     * @return 媒体数据集合
-     */
-    List<ArdMedia> selectArdMedia(ArdMedia ardMedia);  // 动态查询
-
-    List<ArdMedia> selectArdMediaByTaskId(Integer taskId);  // 根据任务ID查询
-
-    List<ArdMedia> selectArdMediaByTaskIdAndType(@Param("taskId") Integer taskId, @Param("mediaType") Integer mediaType);  //
-
-    /**
-     * 插入媒体数据记录
-     *
-     * @param ardMedia 媒体数据
-     */
-    void insertArdMedia(ArdMedia ardMedia);  // 插入单个记录
-
-    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/mapper/ArdMediaPicMapper.java b/ard-work/src/main/java/com/ard/work/mapper/ArdMediaPicMapper.java
new file mode 100644
index 0000000..716234d
--- /dev/null
+++ b/ard-work/src/main/java/com/ard/work/mapper/ArdMediaPicMapper.java
@@ -0,0 +1,41 @@
+package com.ard.work.mapper;
+
+import com.ard.work.domain.entity.ArdMediaPic;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+@Mapper
+public interface ArdMediaPicMapper {
+
+    /**
+     * 查询图片列表(条件查询)
+     */
+    List<ArdMediaPic> selectPicList(ArdMediaPic query);
+
+    /**
+     * 根据任务ID查询图片
+     */
+    List<ArdMediaPic> selectPicByTaskId(@Param("taskId") Integer taskId);
+
+    /**
+     * 新增图片
+     */
+    int insertPic(ArdMediaPic pic);
+
+    /**
+     * 批量新增图片
+     */
+    int insertPicList(@Param("list") List<ArdMediaPic> list);
+
+    /**
+     * 根据ID删除图片
+     */
+    int deletePicById(@Param("id") String id);
+
+    /**
+     * 根据任务ID删除图片
+     */
+    int deletePicByTaskId(@Param("taskId") Integer taskId);
+}
diff --git a/ard-work/src/main/java/com/ard/work/mapper/ArdMediaVideoMapper.java b/ard-work/src/main/java/com/ard/work/mapper/ArdMediaVideoMapper.java
new file mode 100644
index 0000000..10a7472
--- /dev/null
+++ b/ard-work/src/main/java/com/ard/work/mapper/ArdMediaVideoMapper.java
@@ -0,0 +1,36 @@
+package com.ard.work.mapper;
+
+import com.ard.work.domain.entity.ArdMediaVideo;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+@Mapper
+public interface ArdMediaVideoMapper {
+
+    /**
+     * 查询视频列表(条件查询)
+     */
+    List<ArdMediaVideo> selectArdMediaVideoList(ArdMediaVideo query);
+
+    /**
+     * 根据任务ID查询视频
+     */
+    List<ArdMediaVideo> selectArdMediaVideoByTaskId(@Param("taskId") Integer taskId);
+
+    /**
+     * 新增视频
+     */
+    int insertArdMediaVideo(ArdMediaVideo video);
+
+    /**
+     * 根据ID删除视频
+     */
+    int deleteArdMediaVideoById(@Param("id") String id);
+
+    /**
+     * 根据任务ID删除视频
+     */
+    int deleteArdMediaVideoByTaskId(@Param("taskId") Integer taskId);
+}
diff --git a/ard-work/src/main/java/com/ard/work/service/IArdMediaService.java b/ard-work/src/main/java/com/ard/work/service/IArdMediaService.java
index 356ed7a..59d987e 100644
--- a/ard-work/src/main/java/com/ard/work/service/IArdMediaService.java
+++ b/ard-work/src/main/java/com/ard/work/service/IArdMediaService.java
@@ -1,7 +1,8 @@
 package com.ard.work.service;
 
-import com.ard.work.domain.entity.ArdMedia;
-
+import com.ard.work.domain.entity.ArdFlightTask;
+import com.ard.work.domain.entity.ArdMediaPic;
+import com.ard.work.domain.entity.ArdMediaVideo;
 import java.util.List;
 
 /**
@@ -10,11 +11,12 @@
  * Date: 2025年11月18日13:15
  **/
 public interface IArdMediaService {
-    /**
-     * 查询媒体数据列表
-     *
-     * @param ardMedia 媒体数据
-     * @return 媒体数据集合
-     */
-    public List<ArdMedia> selectArdMediaList(ArdMedia ardMedia);
+
+    List<ArdMediaPic> selectArdMediaPicList(ArdMediaPic ardMediaPic);
+    List<ArdMediaVideo> selectArdMediaVideoList(ArdMediaVideo ardMediaVideo);
+    void insertPhotoToDatabase(ArdFlightTask flightTask, String serverId, String boxSn);
+    void insertVideoToDatabase(ArdFlightTask flightTask, String serverId, String boxSn);
+    void updatePhotoToDatabase(ArdFlightTask flightTask, String serverId, String boxSn);
+    void updateVideoToDatabase(ArdFlightTask flightTask, String serverId, String boxSn);
+
 }
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 5d97e6a..97dc505 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
@@ -4,49 +4,23 @@
 import com.ard.common.core.domain.entity.SysUser;
 import com.ard.common.core.redis.RedisCache;
 import com.ard.common.utils.DateUtils;
-import com.ard.common.utils.file.MimeTypeUtils;
-import com.ard.common.utils.uuid.IdUtils;
-import com.ard.oss.service.impl.OssServiceContext;
 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;
 import com.ard.work.service.IArdFlightTaskService;
+import com.ard.work.service.IArdMediaService;
 import com.ard.work.service.IArdServerInfoService;
 import com.ard.work.service.control.UavControlService;
-import com.ard.work.util.osSelect;
 import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.scheduling.annotation.Scheduled;
-import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
-import javax.net.ssl.HttpsURLConnection;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.X509TrustManager;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.net.URLConnection;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
-import java.util.concurrent.CompletableFuture;
-import java.util.stream.Collectors;
 
 @Slf4j
 @Service
@@ -55,19 +29,16 @@
     @Resource
     private ArdFlightTaskMapper ardFlightTaskMapper;
     @Resource
-    private ArdMediaMapper ardMediaMapper;
-    @Resource
     private IArdServerInfoService ardServerInfoService;
     @Resource
-    private TyClient tyClient;
-    @Resource
-    private OssServiceContext ossServiceContext;
-    @Resource
-    private ThreadPoolTaskExecutor threadPoolTaskExecutor;  // 使用线程池执行异步任务
-    @Resource
     private UavControlService uavControlService;
-    @Autowired
+    @Resource
+    private IArdMediaService ardMediaService;
+    @Resource
     private RedisCache redisCache;
+    @Resource
+    private TyClient tyClient;
+
     /**
      * 查询飞行架次列表
      *
@@ -97,6 +68,12 @@
     private Date getLastSyncTimeForServer(String serverId) {
         Date maxStartTime = ardFlightTaskMapper.findMaxStartTimeByServerId(serverId);
         return maxStartTime != null ? maxStartTime : new Date(0);  // 如果没有数据,返回 Unix 纪元时间作为起点
+    }
+
+    // 调用接口获取飞行历史数据
+    private List<BoxHistoryReceiver> getBoxHistory(String serverId, BoxHistoryDTO boxHistoryDTO) {
+        TyHttpCommonReceiver<List<BoxHistoryReceiver>> boxHistory = tyClient.getBoxHistory(serverId, boxHistoryDTO);
+        return boxHistory.getContent();
     }
 
     // 根据上次同步时间同步飞行历史
@@ -158,24 +135,23 @@
             // 插入新记录
             int rows = ardFlightTaskMapper.insertArdFlightTask(flightTask);
             if (rows > 0) {
-                // 删除旧的媒体记录,防止重复插入
-                ardMediaMapper.deleteArdMediaByTaskId(flightTask.getTaskId());
                 // 插入视频
-                insertVideoToDatabase(flightTask, serverId, boxHistoryReceiver.getBoxSn());
+                ardMediaService.insertVideoToDatabase(flightTask, serverId, boxHistoryReceiver.getBoxSn());
                 // 插入图片
-                insertPhotoToDatabase(flightTask, serverId, boxHistoryReceiver.getBoxSn());
+                ardMediaService.insertPhotoToDatabase(flightTask, serverId, boxHistoryReceiver.getBoxSn());
             }
         } else {
             // 如果存在,则更新记录
             log.debug("Updating task {}", boxHistoryReceiver.getTaskId());
             updateFlightTask(ardFlightTask, boxHistoryReceiver);
             // 增量更新视频
-            updateVideoToDatabase(ardFlightTask, serverId, boxHistoryReceiver.getBoxSn());
+            ardMediaService.updateVideoToDatabase(ardFlightTask, serverId, boxHistoryReceiver.getBoxSn());
             // 增量更新图片
-            updatePhotoToDatabase(ardFlightTask, serverId, boxHistoryReceiver.getBoxSn());
+            ardMediaService.updatePhotoToDatabase(ardFlightTask, serverId, boxHistoryReceiver.getBoxSn());
 
         }
     }
+
     private void updateFlightTask(ArdFlightTask local, BoxHistoryReceiver remote) {
 
         boolean needUpdate = false;
@@ -208,342 +184,5 @@
         }
     }
 
-
-    // 调用接口获取飞行历史数据
-    private List<BoxHistoryReceiver> getBoxHistory(String serverId, BoxHistoryDTO boxHistoryDTO) {
-        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 List<BoxVideosReceiver> getBoxVideos(String serverId, BoxVideosDTO boxVideosDTO) {
-        TyHttpCommonReceiver<List<BoxVideosReceiver>> boxVideos = tyClient.getBoxVideos(serverId, boxVideosDTO);
-        return boxVideos.getContent();
-    }
-
-    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(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 表示图片)
-        List<ArdMedia> existingPhotos = ardMediaMapper.selectArdMediaByTaskIdAndType(flightTask.getTaskId(), 0);
-        int count = existingPhotos.size(); //获取本地库图片数量
-        // 查询图片
-        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 (size > count) {
-            log.info("任务【{}】图片数量不一致,需要更新数据库", flightTask.getTaskId());
-            // 需要插入新的视频
-            // 提取现有的图片路径(根据 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 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) {
-            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(() -> {
-                        try (InputStream inputStream = openUrlInputStream(photo.getImgUrl(), 5000, 10000)) {
-                            if (inputStream != null) {
-                                return ossServiceContext.upload(
-                                        "pic",
-                                        boxSn + "/" + ardMedia.getId() + ".jpg",
-                                        inputStream,
-                                        MimeTypeUtils.IMAGE_JPG
-                                );
-                            }
-                        } catch (Exception e) {
-                            e.printStackTrace();
-                        }
-                        return null;
-                    }, threadPoolTaskExecutor)
-                    .thenAccept(url -> {
-                        ardMedia.setMediaUrl(url);
-                        ardMedia.setCreateTime(new Date());
-                        ardMediaMapper.insertArdMedia(ardMedia);
-                    });
-        }
-    }
-    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) {
-        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 generateThumbnail(String videoFile, int skipSeconds, int targetWidth) {
-        String ffmpegPath = "";
-        if (osSelect.isWindows()) {
-            ffmpegPath = "ffmpeg";
-        } else if (osSelect.isLinux()) {
-            ffmpegPath = "/usr/local/ffmpeg/bin/ffmpeg";
-        }
-        try {
-            List<String> command = new ArrayList<>();
-            command.add(ffmpegPath);
-
-            command.add("-timeout");
-            command.add("3000000");
-            command.add("-rw_timeout");
-            command.add("3000000");
-
-            command.add("-ss");
-            command.add(String.format("00:00:%02d", skipSeconds));
-            command.add("-i");
-            command.add(videoFile);
-            command.add("-vframes");
-            command.add("1");
-
-            // 等比缩放
-            command.add("-vf");
-            command.add("scale=" + targetWidth + ":-1");
-
-            // **确保输出 JPEG**
-            command.add("-f");
-            command.add("mjpeg");      // 关键点:输出格式固定为 JPEG
-            command.add("-vcodec");
-            command.add("mjpeg");
-
-            // 输出到管道
-            command.add("pipe:1");
-
-            // ⭐ 打印最终命令(可复制)
-            log.info("ffmpeg command: {}", String.join(" ", command));
-
-            ProcessBuilder pb = new ProcessBuilder(command);
-            pb.redirectErrorStream(false);
-            Process process = pb.start();
-
-            // 读取 FFmpeg 输出(JPEG 数据)到内存
-            ByteArrayOutputStream baos = new ByteArrayOutputStream();
-            try (InputStream is = process.getInputStream()) {
-                byte[] buffer = new byte[8192];
-                int len;
-                while ((len = is.read(buffer)) != -1) {
-                    baos.write(buffer, 0, len);
-                }
-            }
-
-            int exitCode = process.waitFor();
-            if (exitCode != 0) {
-                throw new RuntimeException("FFmpeg 执行失败,退出码: " + exitCode);
-            }
-
-            return new ByteArrayInputStream(baos.toByteArray());
-
-        } catch (IOException | InterruptedException e) {
-            throw new RuntimeException("FFmpeg 生成缩略图失败", e);
-        }
-    }
-    /**
-     * 将 URL 转成 InputStream
-     *
-     * @param fileUrl              文件 URL
-     * @param connectTimeoutMillis 连接超时(毫秒)
-     * @param readTimeoutMillis    读取超时(毫秒)
-     * @return InputStream,如果失败返回 null
-     */
-    public InputStream openUrlInputStream(String fileUrl, int connectTimeoutMillis, int readTimeoutMillis) {
-        try {
-            URL url = new URL(fileUrl);
-
-            // 支持 HTTPS 信任所有证书(如果需要访问自签名证书)
-            if ("https".equalsIgnoreCase(url.getProtocol())) {
-                TrustManager[] trustAllCerts = new TrustManager[]{
-                        new X509TrustManager() {
-                            @Override
-                            public void checkClientTrusted(X509Certificate[] chain, String authType) {
-                            }
-
-                            @Override
-                            public void checkServerTrusted(X509Certificate[] chain, String authType) {
-                            }
-
-                            @Override
-                            public X509Certificate[] getAcceptedIssuers() {
-                                return null;
-                            }
-                        }
-                };
-                SSLContext sc = SSLContext.getInstance("SSL");
-                sc.init(null, trustAllCerts, new java.security.SecureRandom());
-                HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
-                HttpsURLConnection.setDefaultHostnameVerifier((hostname, session) -> true);
-            }
-
-            URLConnection connection = url.openConnection();
-            connection.setConnectTimeout(connectTimeoutMillis);
-            connection.setReadTimeout(readTimeoutMillis);
-
-            return connection.getInputStream();
-
-        } catch (Exception e) {
-            e.printStackTrace();
-            return null;
-        }
-    }
 
 }
diff --git a/ard-work/src/main/java/com/ard/work/service/impl/ArdMediaServiceImpl.java b/ard-work/src/main/java/com/ard/work/service/impl/ArdMediaServiceImpl.java
index 2fe5482..1f95bce 100644
--- a/ard-work/src/main/java/com/ard/work/service/impl/ArdMediaServiceImpl.java
+++ b/ard-work/src/main/java/com/ard/work/service/impl/ArdMediaServiceImpl.java
@@ -1,31 +1,493 @@
 package com.ard.work.service.impl;
 
-import com.ard.work.domain.entity.ArdMedia;
-import com.ard.work.mapper.ArdMediaMapper;
+import com.ard.common.utils.DateUtils;
+import com.ard.common.utils.file.MimeTypeUtils;
+import com.ard.oss.service.impl.OssServiceContext;
+import com.ard.work.component.forest.TyClient;
+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.ArdMediaPic;
+import com.ard.work.domain.entity.ArdMediaVideo;
+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.ArdMediaPicMapper;
+import com.ard.work.mapper.ArdMediaVideoMapper;
 import com.ard.work.service.IArdMediaService;
+import com.ard.work.util.osSelect;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLConnection;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Date;
 import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.stream.Collectors;
 
 /**
  * Description:
  * Author: lsy
  * Date: 2025年11月18日13:17
  **/
+@Slf4j
 @Service
 public class ArdMediaServiceImpl implements IArdMediaService {
+
     @Resource
-    private ArdMediaMapper ardMediaMapper;
+    private TyClient tyClient;
+    @Resource
+    private ArdMediaPicMapper ardMediaPicMapper;
+    @Resource
+    private ArdMediaVideoMapper ardMediaVideoMapper;
+    @Resource
+    private OssServiceContext ossServiceContext;
+    @Resource
+    private ArdFlightTaskMapper ardFlightTaskMapper;
+    @Resource
+    private ThreadPoolTaskExecutor threadPoolTaskExecutor;
+
+    // 调用接口获取架次图片
+    private List<BoxPhotosReceiver> getBoxPhotos(String serverId, BoxPhotosDTO boxPhotosDTO) {
+        TyHttpCommonReceiver<List<BoxPhotosReceiver>> boxPhotos = tyClient.getBoxPhotos(serverId, boxPhotosDTO);
+        return boxPhotos.getContent();
+    }
+
+    // 调用接口获取架次视频
+    private List<BoxVideosReceiver> getBoxVideos(String serverId, BoxVideosDTO boxVideosDTO) {
+        TyHttpCommonReceiver<List<BoxVideosReceiver>> boxVideos = tyClient.getBoxVideos(serverId, boxVideosDTO);
+        return boxVideos.getContent();
+    }
+
+    @Override
+    public List<ArdMediaPic> selectArdMediaPicList(ArdMediaPic ardMediaPic) {
+        return ardMediaPicMapper.selectPicList(ardMediaPic);
+    }
+
+    @Override
+    public List<ArdMediaVideo> selectArdMediaVideoList(ArdMediaVideo ardMediaVideo) {
+        return ardMediaVideoMapper.selectArdMediaVideoList(ardMediaVideo);
+    }
+
+    @Override
+    public void insertPhotoToDatabase(ArdFlightTask flightTask, String serverId, String boxSn) {
+        log.warn("开始获取图片信息");
+        // 查询图片
+        BoxPhotosDTO boxPhotosDTO = new BoxPhotosDTO();
+        boxPhotosDTO.setTaskId(flightTask.getTaskId());
+        boxPhotosDTO.setBoxSn(boxSn);
+        boxPhotosDTO.setPageIndex(1);
+        boxPhotosDTO.setPageSize(100);
+        List<BoxPhotosReceiver> photoList = getBoxPhotos(serverId, boxPhotosDTO);
+        if (photoList != null && !photoList.isEmpty()) {
+            addPhotos(flightTask, photoList);
+        }
+    }
+
+    @Override
+    public void insertVideoToDatabase(ArdFlightTask flightTask, String serverId, String boxSn) {
+        log.warn("开始获取视频信息");
+        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);
+        }
+    }
+
+
+    @Override
+    public void updatePhotoToDatabase(ArdFlightTask flightTask, String serverId, String boxSn) {
+
+        // 获取本地数据库中已存在的图片记录(类型为 0 表示图片)
+        List<ArdMediaPic> existingPhotos = ardMediaPicMapper.selectPicByTaskId(flightTask.getTaskId());
+        int count = existingPhotos.size(); //获取本地库图片数量
+        // 查询图片
+        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 (size > count) {
+            log.info("任务【{}】图片数量不一致,需要更新数据库", flightTask.getTaskId());
+            // 需要插入新的视频
+            // 提取现有的图片路径(根据 imgUrl 来判断是否重复)
+            List<String> existingPhotoUrls = existingPhotos.stream()
+                    .map(ArdMediaPic::getSourceUrl) // 提取 ArdMediaPic 中的图片 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);
+            }
+        }
+    }
+
+
+    @Override
+    public void updateVideoToDatabase(ArdFlightTask flightTask, String serverId, String boxSn) {
+
+        // 获取本地数据库中已存在的视频记录
+        List<ArdMediaVideo> existingVideos = ardMediaVideoMapper.selectArdMediaVideoByTaskId(flightTask.getTaskId());
+        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(ArdMediaVideo::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.getVideoCount() + newVideos.size());
+                ardFlightTaskMapper.updateArdFlightTask(flightTask);
+            }
+        }
+    }
+
+    private void addPhotos1(ArdFlightTask flightTask, List<BoxPhotosReceiver> photoList) {
+        log.warn("开始添加图片");
+        String boxSn = flightTask.getBoxSn();
+        for (BoxPhotosReceiver photo : photoList) {
+            ArdMediaPic ardMedia = ArdMediaPic.builder()
+                    .id(photo.getPhotoId())
+                    .taskId(flightTask.getTaskId())
+                    .fileSize(photo.getFileSize())
+                    .fileMd5(photo.getFileMd5())
+                    .sourceUrl(photo.getImgUrl())
+                    .longitude(photo.getLng())
+                    .latitude(photo.getLat())
+                    .height(photo.getHeight())
+                    .captureTime(DateUtils.parseDate(photo.getTimeStamp()))
+                    .build();
+            String url = "";
+            try {
+                InputStream inputStream = openUrlInputStream(photo.getImgUrl(), 5000, 10000);
+                if (inputStream != null) {
+                    url = ossServiceContext.upload(
+                            "pic",
+                            boxSn + "/" + ardMedia.getId() + ".jpg",
+                            inputStream,
+                            MimeTypeUtils.IMAGE_JPG
+                    );
+                }
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+            ardMedia.setMediaUrl(url);
+            ardMedia.setCreateTime(new Date());
+            ardMediaPicMapper.insertPic(ardMedia);
+        }
+    }
+    private void addPhotos(ArdFlightTask flightTask, List<BoxPhotosReceiver> photoList) {
+        log.warn("开始添加图片");
+        String boxSn = flightTask.getBoxSn();
+        for (BoxPhotosReceiver photo : photoList) {
+            CompletableFuture.runAsync(() -> {
+                ArdMediaPic ardMedia = ArdMediaPic.builder()
+                        .id(photo.getPhotoId())
+                        .taskId(flightTask.getTaskId())
+                        .fileSize(photo.getFileSize())
+                        .fileMd5(photo.getFileMd5())
+                        .sourceUrl(photo.getImgUrl())
+                        .longitude(photo.getLng())
+                        .latitude(photo.getLat())
+                        .height(photo.getHeight())
+                        .captureTime(DateUtils.parseDate(photo.getTimeStamp()))
+                        .build();
+
+                String url = "";
+                try (InputStream inputStream = openUrlInputStream(photo.getImgUrl(), 5000, 10000)) {
+                    if (inputStream != null) {
+                        url = ossServiceContext.upload(
+                                "pic",
+                                boxSn + "/" + ardMedia.getId() + ".jpg",
+                                inputStream,
+                                MimeTypeUtils.IMAGE_JPG
+                        );
+                    }
+                } catch (Exception e) {
+                    log.error("图片上传失败 taskId={}, photoId={}", flightTask.getTaskId(), photo.getPhotoId(), e);
+                }
+
+                ardMedia.setMediaUrl(url);
+                ardMedia.setCreateTime(new Date());
+                ardMediaPicMapper.insertPic(ardMedia);
+
+            }, threadPoolTaskExecutor); // 使用自定义线程池
+        }
+    }
+
+    private void addVideos1(ArdFlightTask flightTask, List<BoxVideosReceiver> videoList) {
+        log.warn("开始添加视频");
+        String boxSn = flightTask.getBoxSn();
+        for (BoxVideosReceiver video : videoList) {
+            ArdMediaVideo ardMedia = ArdMediaVideo.builder()
+                    .id(video.getId())
+                    .name(video.getName())
+                    .taskId(flightTask.getTaskId())
+                    .fileSize(getFileSizeByUrl(video.getImgUrl()))
+                    .sourceUrl(video.getImgUrl())
+                    .startTime(DateUtils.parseDate(video.getStartTime()))
+                    .endTime(DateUtils.parseDate(video.getEndTime()))
+                    .spanSeconds(Integer.parseInt(video.getSpanSeconds()))
+                    .build();
+
+            // 视频上传
+            String videoUrl = null;
+            try (InputStream videoStream = openUrlInputStream(ardMedia.getSourceUrl(), 5000, 10000)) {
+                if (videoStream != null) {
+                    videoUrl = ossServiceContext.upload("record", boxSn + "/" + ardMedia.getId() + ".mp4", videoStream, MimeTypeUtils.VIDEO_MP4);
+                }
+            } catch (Exception e) {
+                log.error("视频上传失败 taskId={}, videoId={}", flightTask.getTaskId(), video.getId(), e);
+            }
+
+            // 缩略图上传(失败不影响视频入库)
+            String thumbUrl = null;
+            try (ByteArrayInputStream thumbStream = generateThumbnail(ardMedia.getSourceUrl(), 1, 200)) {
+                if (thumbStream != null) {
+                    thumbUrl = ossServiceContext.upload("record", boxSn + "/" + ardMedia.getId() + ".jpg", thumbStream, MimeTypeUtils.IMAGE_JPEG);
+                }
+            } catch (Exception e) {
+                log.warn("缩略图生成或上传失败 taskId={}, videoId={}", flightTask.getTaskId(), video.getId(), e);
+            }
+
+            // 入库(即使缩略图为空也入库)
+            ardMedia.setMediaUrl(videoUrl);
+            ardMedia.setThumbnailUrl(thumbUrl);
+            ardMedia.setCreateTime(new Date());
+            ardMediaVideoMapper.insertArdMediaVideo(ardMedia);
+        }
+    }
+    private void addVideos(ArdFlightTask flightTask, List<BoxVideosReceiver> videoList) {
+        String boxSn = flightTask.getBoxSn();
+
+        for (BoxVideosReceiver video : videoList) {
+            CompletableFuture.runAsync(() -> {
+                ArdMediaVideo ardMedia = ArdMediaVideo.builder()
+                        .id(video.getId())
+                        .name(video.getName())
+                        .taskId(flightTask.getTaskId())
+                        .fileSize(getFileSizeByUrl(video.getImgUrl()))
+                        .sourceUrl(video.getImgUrl())
+                        .startTime(DateUtils.parseDate(video.getStartTime()))
+                        .endTime(DateUtils.parseDate(video.getEndTime()))
+                        .spanSeconds(Integer.parseInt(video.getSpanSeconds()))
+                        .build();
+
+                // 视频上传
+                String videoUrl = null;
+                try (InputStream videoStream = openUrlInputStream(ardMedia.getSourceUrl(), 5000, 10000)) {
+                    if (videoStream != null) {
+                        videoUrl = ossServiceContext.upload("record",
+                                boxSn + "/" + ardMedia.getId() + ".mp4",
+                                videoStream,
+                                MimeTypeUtils.VIDEO_MP4);
+                    }
+                } catch (Exception e) {
+                    log.error("视频上传失败 taskId={}, videoId={}", flightTask.getTaskId(), video.getId(), e);
+                }
+
+                // 缩略图上传(失败不影响视频入库)
+                String thumbUrl = null;
+                try (ByteArrayInputStream thumbStream = generateThumbnail(ardMedia.getSourceUrl(), 1, 200)) {
+                    if (thumbStream != null) {
+                        thumbUrl = ossServiceContext.upload("record",
+                                boxSn + "/" + ardMedia.getId() + ".jpg",
+                                thumbStream,
+                                MimeTypeUtils.IMAGE_JPEG);
+                    }
+                } catch (Exception e) {
+                    log.warn("缩略图生成或上传失败 taskId={}, videoId={}", flightTask.getTaskId(), video.getId(), e);
+                }
+
+                // 入库(即使缩略图为空也入库)
+                ardMedia.setMediaUrl(videoUrl);
+                ardMedia.setThumbnailUrl(thumbUrl);
+                ardMedia.setCreateTime(new Date());
+                ardMediaVideoMapper.insertArdMediaVideo(ardMedia);
+
+            }, threadPoolTaskExecutor);
+        }
+    }
+
+
+
+    // 获取文件大小
+    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 generateThumbnail(String videoFile, int skipSeconds, int targetWidth) {
+        String ffmpegPath = "";
+        if (osSelect.isWindows()) {
+            ffmpegPath = "ffmpeg";
+        } else if (osSelect.isLinux()) {
+            ffmpegPath = "/usr/local/ffmpeg/bin/ffmpeg";
+        }
+        try {
+            List<String> command = new ArrayList<>();
+            command.add(ffmpegPath);
+
+            command.add("-timeout");
+            command.add("3000000");
+            command.add("-rw_timeout");
+            command.add("3000000");
+
+            command.add("-ss");
+            command.add(String.format("00:00:%02d", skipSeconds));
+            command.add("-i");
+            command.add(videoFile);
+            command.add("-vframes");
+            command.add("1");
+
+            // 等比缩放
+            command.add("-vf");
+            command.add("scale=" + targetWidth + ":-1");
+
+            // **确保输出 JPEG**
+            command.add("-f");
+            command.add("mjpeg");      // 关键点:输出格式固定为 JPEG
+            command.add("-vcodec");
+            command.add("mjpeg");
+
+            // 输出到管道
+            command.add("pipe:1");
+
+            // ⭐ 打印最终命令(可复制)
+            log.info("ffmpeg command: {}", String.join(" ", command));
+
+            ProcessBuilder pb = new ProcessBuilder(command);
+            pb.redirectErrorStream(false);
+            Process process = pb.start();
+
+            // 读取 FFmpeg 输出(JPEG 数据)到内存
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            try (InputStream is = process.getInputStream()) {
+                byte[] buffer = new byte[8192];
+                int len;
+                while ((len = is.read(buffer)) != -1) {
+                    baos.write(buffer, 0, len);
+                }
+            }
+
+            int exitCode = process.waitFor();
+            if (exitCode != 0) {
+                throw new RuntimeException("FFmpeg 执行失败,退出码: " + exitCode);
+            }
+
+            return new ByteArrayInputStream(baos.toByteArray());
+
+        } catch (IOException | InterruptedException e) {
+            throw new RuntimeException("FFmpeg 生成缩略图失败", e);
+        }
+    }
 
     /**
-     * 查询媒体数据列表
+     * 将 URL 转成 InputStream
      *
-     * @param ardMedia 媒体数据
-     * @return 媒体数据集合
+     * @param fileUrl              文件 URL
+     * @param connectTimeoutMillis 连接超时(毫秒)
+     * @param readTimeoutMillis    读取超时(毫秒)
+     * @return InputStream,如果失败返回 null
      */
-    @Override
-    public List<ArdMedia> selectArdMediaList(ArdMedia ardMedia) {
-        return ardMediaMapper.selectArdMedia(ardMedia);
+    public InputStream openUrlInputStream(String fileUrl, int connectTimeoutMillis, int readTimeoutMillis) {
+        try {
+            URL url = new URL(fileUrl);
+
+            // 支持 HTTPS 信任所有证书(如果需要访问自签名证书)
+            if ("https".equalsIgnoreCase(url.getProtocol())) {
+                TrustManager[] trustAllCerts = new TrustManager[]{
+                        new X509TrustManager() {
+                            @Override
+                            public void checkClientTrusted(X509Certificate[] chain, String authType) {
+                            }
+
+                            @Override
+                            public void checkServerTrusted(X509Certificate[] chain, String authType) {
+                            }
+
+                            @Override
+                            public X509Certificate[] getAcceptedIssuers() {
+                                return null;
+                            }
+                        }
+                };
+                SSLContext sc = SSLContext.getInstance("SSL");
+                sc.init(null, trustAllCerts, new java.security.SecureRandom());
+                HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
+                HttpsURLConnection.setDefaultHostnameVerifier((hostname, session) -> true);
+            }
+
+            URLConnection connection = url.openConnection();
+            connection.setConnectTimeout(connectTimeoutMillis);
+            connection.setReadTimeout(readTimeoutMillis);
+
+            return connection.getInputStream();
+
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
     }
 }
diff --git a/ard-work/src/main/resources/mapper/ArdMediaMapper.xml b/ard-work/src/main/resources/mapper/ArdMediaMapper.xml
deleted file mode 100644
index 2548d11..0000000
--- a/ard-work/src/main/resources/mapper/ArdMediaMapper.xml
+++ /dev/null
@@ -1,202 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="com.ard.work.mapper.ArdMediaMapper">
-
-    <!-- 结果映射 -->
-    <resultMap id="ArdMediaResult" type="ArdMedia">
-        <result property="id" column="id"/>
-        <result property="taskId" column="task_id"/>
-        <result property="mediaType" column="media_type"/>
-        <result property="fileSize" column="file_size"/>
-        <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,thumbnail_url,
-        photo_id, longitude, latitude, height, capture_time, create_time
-        FROM ard_media
-        <where>
-            <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>
-            <if test="fileMd5 != null">AND file_md5 = #{fileMd5}</if>
-            <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
-            CASE
-                WHEN media_type = 0 THEN capture_time
-                ELSE create_time
-            END DESC
-    </select>
-
-
-    <!-- 根据任务ID查询媒体 -->
-    <select id="selectArdMediaByTaskId" 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}
-    </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
-        <trim prefix="(" suffix=")" suffixOverrides=",">
-            <if test="id != null">id,</if>
-            <if test="taskId != null">task_id,</if>
-            <if test="mediaType != null">media_type,</if>
-            <if test="fileSize != null">file_size,</if>
-            <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>
-            <if test="mediaType != null">#{mediaType},</if>
-            <if test="fileSize != null">#{fileSize},</if>
-            <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(
-        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>
-
-
-    <!-- 更新媒体记录 -->
-    <update id="updateArdMedia" parameterType="com.ard.work.domain.entity.ArdMedia">
-        UPDATE ard_media
-        <set>
-            <if test="mediaType != null">media_type = #{mediaType},</if>
-            <if test="fileSize != null">file_size = #{fileSize},</if>
-            <if test="fileMd5 != null">file_md5 = #{fileMd5},</if>
-            <if test="mediaUrl != null">media_url = #{mediaUrl},</if>
-            <if test="createTime != null">create_time = #{createTime},</if>
-        </set>
-        WHERE id = #{id}
-    </update>
-
-    <!-- 删除媒体记录 -->
-    <delete id="deleteArdMediaById" parameterType="Integer">
-        DELETE
-        FROM ard_media
-        WHERE id = #{id}
-    </delete>
-
-    <!-- 批量删除媒体记录 -->
-    <delete id="deleteArdMediaByIds" parameterType="java.util.List">
-        DELETE FROM ard_media WHERE id IN
-        <foreach item="id" collection="list" open="(" separator="," close=")">
-            #{id}
-        </foreach>
-    </delete>
-
-    <delete id="deleteArdMediaByTaskId" parameterType="java.lang.Integer">
-        DELETE
-        FROM ard_media
-        WHERE task_id = #{taskId}
-    </delete>
-
-</mapper>
diff --git a/ard-work/src/main/resources/mapper/ArdMediaPicMapper.xml b/ard-work/src/main/resources/mapper/ArdMediaPicMapper.xml
new file mode 100644
index 0000000..40379b9
--- /dev/null
+++ b/ard-work/src/main/resources/mapper/ArdMediaPicMapper.xml
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+
+<mapper namespace="com.ard.work.mapper.ArdMediaPicMapper">
+
+    <resultMap id="ArdMediaPicResult" type="ArdMediaPic">
+        <result property="id" column="id"/>
+        <result property="fileSize" column="file_size"/>
+        <result property="fileMd5" column="file_md5"/>
+        <result property="mediaUrl" column="media_url"/>
+        <result property="sourceUrl" column="source_url"/>
+        <result property="longitude" column="longitude"/>
+        <result property="latitude" column="latitude"/>
+        <result property="height" column="height"/>
+        <result property="taskId" column="task_id"/>
+        <result property="captureTime" column="capture_time"/>
+        <result property="createTime" column="create_time"/>
+        <result property="updateTime" column="update_time"/>
+    </resultMap>
+
+    <!-- 查询图片列表 -->
+    <select id="selectPicList" resultMap="ArdMediaPicResult">
+        SELECT
+        id, task_id, file_size, file_md5, media_url, source_url,
+        longitude, latitude, height, capture_time, create_time, update_time
+        FROM ard_media_pic
+        <where>
+            <if test="taskId != null">AND task_id = #{taskId}</if>
+            <if test="fileMd5 != null">AND file_md5 = #{fileMd5}</if>
+        </where>
+        ORDER BY capture_time DESC
+    </select>
+
+    <!-- 根据任务ID查询图片 -->
+    <select id="selectPicByTaskId" resultMap="ArdMediaPicResult">
+        SELECT * FROM ard_media_pic WHERE task_id = #{taskId}
+        ORDER BY capture_time DESC
+    </select>
+
+    <!-- 插入图片 -->
+    <insert id="insertPic" parameterType="com.ard.work.domain.entity.ArdMediaPic">
+        INSERT INTO ard_media_pic (
+            id, task_id, file_size, file_md5,
+            media_url, source_url,
+            longitude, latitude, height,
+            capture_time, create_time
+        ) VALUES (
+                     #{id}, #{taskId}, #{fileSize}, #{fileMd5},
+                     #{mediaUrl}, #{sourceUrl},
+                     #{longitude}, #{latitude}, #{height},
+                     #{captureTime}, #{createTime}
+                 )
+    </insert>
+
+    <!-- 批量插入图片 -->
+    <insert id="insertPicList">
+        INSERT INTO ard_media_pic (
+        id, task_id, file_size, file_md5,
+        media_url, source_url,
+        longitude, latitude, height,
+        capture_time, create_time
+        )
+        VALUES
+        <foreach collection="list" item="item" separator=",">
+            (
+            #{item.id}, #{item.taskId}, #{item.fileSize}, #{item.fileMd5},
+            #{item.mediaUrl}, #{item.sourceUrl},
+            #{item.longitude}, #{item.latitude}, #{item.height},
+            #{item.captureTime}, #{item.createTime}
+            )
+        </foreach>
+    </insert>
+
+    <delete id="deletePicById">
+        DELETE FROM ard_media_pic WHERE id = #{id}
+    </delete>
+
+    <delete id="deletePicByTaskId">
+        DELETE FROM ard_media_pic WHERE task_id = #{taskId}
+    </delete>
+
+</mapper>
diff --git a/ard-work/src/main/resources/mapper/ArdMediaVideoMapper.xml b/ard-work/src/main/resources/mapper/ArdMediaVideoMapper.xml
new file mode 100644
index 0000000..86e514e
--- /dev/null
+++ b/ard-work/src/main/resources/mapper/ArdMediaVideoMapper.xml
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+
+<mapper namespace="com.ard.work.mapper.ArdMediaVideoMapper">
+
+    <!-- 结果映射 -->
+    <resultMap id="ArdMediaVideoResult" type="com.ard.work.domain.entity.ArdMediaVideo">
+        <id property="id" column="id"/>
+        <result property="name" column="name"/>
+        <result property="fileSize" column="file_size"/>
+        <result property="mediaUrl" column="media_url"/>
+        <result property="sourceUrl" column="source_url"/>
+        <result property="thumbnailUrl" column="thumbnail_url"/>
+        <result property="startTime" column="start_time"/>
+        <result property="endTime" column="end_time"/>
+        <result property="spanSeconds" column="span_seconds"/>
+        <result property="taskId" column="task_id"/>
+        <result property="createTime" column="create_time"/>
+        <result property="updateTime" column="update_time"/>
+    </resultMap>
+
+    <!-- 查询视频列表 -->
+    <select id="selectArdMediaVideoList" resultMap="ArdMediaVideoResult">
+        SELECT
+        id, name, file_size, media_url, source_url, thumbnail_url,
+        start_time, end_time, span_seconds, task_id,
+        create_time, update_time
+        FROM ard_media_video
+        <where>
+            <if test="taskId != null">AND task_id = #{taskId}</if>
+            <if test="name != null and name != ''">AND name LIKE CONCAT('%', #{name}, '%')</if>
+            <if test="startTime != null">AND start_time &gt;= #{startTime}</if>
+            <if test="endTime != null">AND end_time &lt;= #{endTime}</if>
+        </where>
+        ORDER BY start_time DESC
+    </select>
+
+    <!-- 根据ID查询 -->
+    <select id="selectArdMediaVideoById" resultMap="ArdMediaVideoResult">
+        SELECT
+            id, name, file_size, media_url, source_url, thumbnail_url,
+            start_time, end_time, span_seconds, task_id,
+            create_time, update_time
+        FROM ard_media_video
+        WHERE id = #{id}
+    </select>
+
+    <!-- 根据任务ID查询 -->
+    <select id="selectArdMediaVideoByTaskId" resultMap="ArdMediaVideoResult">
+        SELECT
+            id, name, file_size, media_url, source_url, thumbnail_url,
+            start_time, end_time, span_seconds, task_id,
+            create_time, update_time
+        FROM ard_media_video
+        WHERE task_id = #{taskId}
+        ORDER BY start_time DESC
+    </select>
+
+    <!-- 新增视频 -->
+    <insert id="insertArdMediaVideo" parameterType="com.ard.work.domain.entity.ArdMediaVideo">
+        INSERT INTO ard_media_video (
+            id, name, file_size, media_url, source_url, thumbnail_url,
+            start_time, end_time, span_seconds, task_id,
+            create_time, update_time
+        ) VALUES (
+                     #{id}, #{name}, #{fileSize}, #{mediaUrl}, #{sourceUrl}, #{thumbnailUrl},
+                     #{startTime}, #{endTime}, #{spanSeconds}, #{taskId},
+                     #{createTime}, #{updateTime}
+                 )
+    </insert>
+
+    <!-- 批量新增 -->
+    <insert id="insertArdMediaVideoList">
+        INSERT INTO ard_media_video (
+        id, name, file_size, media_url, source_url, thumbnail_url,
+        start_time, end_time, span_seconds, task_id,
+        create_time, update_time
+        )
+        VALUES
+        <foreach collection="list" item="item" separator=",">
+            (
+            #{item.id}, #{item.name}, #{item.fileSize},
+            #{item.mediaUrl}, #{item.sourceUrl}, #{item.thumbnailUrl},
+            #{item.startTime}, #{item.endTime}, #{item.spanSeconds},
+            #{item.taskId}, #{item.createTime}, #{item.updateTime}
+            )
+        </foreach>
+    </insert>
+
+    <!-- 更新视频 -->
+    <update id="updateArdMediaVideo">
+        UPDATE ard_media_video
+        <set>
+            <if test="name != null">name = #{name},</if>
+            <if test="fileSize != null">file_size = #{fileSize},</if>
+            <if test="mediaUrl != null">media_url = #{mediaUrl},</if>
+            <if test="sourceUrl != null">source_url = #{sourceUrl},</if>
+            <if test="thumbnailUrl != null">thumbnail_url = #{thumbnailUrl},</if>
+            <if test="startTime != null">start_time = #{startTime},</if>
+            <if test="endTime != null">end_time = #{endTime},</if>
+            <if test="spanSeconds != null">span_seconds = #{spanSeconds},</if>
+            <if test="updateTime != null">update_time = #{updateTime},</if>
+        </set>
+        WHERE id = #{id}
+    </update>
+
+    <!-- 删除 -->
+    <delete id="deleteArdMediaVideoById">
+        DELETE FROM ard_media_video WHERE id = #{id}
+    </delete>
+
+    <delete id="deleteArdMediaVideoByTaskId">
+        DELETE FROM ard_media_video WHERE task_id = #{taskId}
+    </delete>
+
+</mapper>

--
Gitblit v1.9.3