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 >= #{startTime}</if>
+ <if test="endTime != null">AND end_time <= #{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