ard-admin/src/main/java/com/ard/web/controller/sample/media/FileController.java
@@ -4,6 +4,7 @@ import com.ard.sample.common.model.ResponseResult; import com.ard.sample.media.model.MediaFileDTO; import com.ard.sample.media.service.IFileService; import io.swagger.annotations.Api; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; @@ -16,6 +17,7 @@ * @version 0.2 * @date 2021/12/9 */ @Api(tags = "媒体文件管理") @RestController @RequestMapping("/dock/media/files") public class FileController { ard-admin/src/main/java/com/ard/web/controller/sample/media/MediaController.java
@@ -5,6 +5,7 @@ import com.ard.sample.media.model.FileUploadDTO; import com.ard.sample.media.service.IMediaService; import com.fasterxml.jackson.core.JsonProcessingException; import io.swagger.annotations.Api; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; @@ -14,13 +15,14 @@ import java.util.concurrent.ConcurrentHashMap; /** * @author sean * @author sean/workspaces * @version 0.2 * @date 2021/12/7 */ @Api(tags = "媒体库管理") @Slf4j @RestController @RequestMapping("/dock/media/workspaces") @RequestMapping("/dock/media") public class MediaController { @Autowired @@ -53,7 +55,7 @@ } /** * Query the files that already exist in this workspace based on the workspace id and the collection of tiny fingerprints. * 根据工作区 ID 和微小指纹的集合查询此工作区中已存在的文件。 * @param tinyFingerprints There is only one tiny_fingerprint parameter in the body. * But it is not recommended to use Map to receive the parameter. * @return ard-sample/src/main/java/com/ard/sample/config/DockConfiguration.java
@@ -1,6 +1,5 @@ package com.ard.sample.config; import com.ard.common.config.OssConfiguration; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; @@ -9,7 +8,13 @@ public class DockConfiguration { public static String endpoint; public static String bucket; public void setEndpoint(String endpoint) { DockConfiguration.endpoint = endpoint; } public void setBucket(String bucket) { DockConfiguration.bucket = bucket; } } ard-sample/src/main/java/com/ard/sample/media/service/impl/MediaServiceImpl.java
@@ -19,9 +19,12 @@ import com.ard.sample.media.model.MediaFileDTO; import com.ard.sample.media.service.IFileService; import com.ard.sample.media.service.IMediaService; import com.ard.sample.wayline.mapper.IWaylineJobHistoryMapper; import com.ard.sample.wayline.model.dto.WaylineJobDTO; import com.ard.sample.wayline.service.IWaylineJobHistoryService; import com.ard.sample.wayline.service.IWaylineJobService; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.integration.annotation.ServiceActivator; import org.springframework.integration.mqtt.support.MqttHeaders; @@ -38,6 +41,7 @@ * @version 0.2 * @date 2021/12/9 */ @Slf4j @Service public class MediaServiceImpl implements IMediaService { @@ -90,6 +94,24 @@ } /** * 处理文件上传回调事件 * * 该方法接收文件上传回调消息,进行业务处理并返回响应。主要逻辑包括: * 1. 解析回调数据并构建响应对象 * 2. 检查回调结果,非成功状态直接返回 * 3. 验证Redis中存储的媒体文件计数信息,防止重复处理 * 4. 查询设备信息和作业信息,解析媒体文件 * 5. 发布处理结果到指定主题 * 6. 通知上传计数更新 * * @param receiver 包含文件上传回调数据的通用主题接收器对象 * 包含以下关键字段: * - data: 回调数据(JSON格式) * - gateway: 设备网关标识 * - tid: 事务ID * - bid: 业务ID */ @Override @ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_FILE_UPLOAD_CALLBACK, outputChannel = ChannelName.OUTBOUND) public void handleFileUploadCallBack(CommonTopicReceiver receiver) { @@ -123,9 +145,12 @@ Optional<WaylineJobDTO> jobOpt = waylineJobService.getJobByJobId(jobId); if (jobOpt.isPresent()) { boolean isSave = parseMediaFile(callback, jobOpt.get()); log.info("媒体库收到数据:{}",callback); if (!isSave) { data.setData(RequestsReply.error(CommonErrorEnum.ILLEGAL_ARGUMENT)); log.info("媒体库保存失败:{}",callback); } } messageSenderService.publish(topic, data); @@ -134,7 +159,7 @@ } /** * update the uploaded count and notify web side * 更新上传的计数并通知网页端 * @param mediaFileCount * @param receiver * @param jobId @@ -172,18 +197,42 @@ .build()); } /** * 解析媒体文件并设置相关属性 * * <p>该函数主要完成两个操作: * 1. 根据任务中的机库序列号设置拍摄媒体的无人机序列号 * 2. 从文件对象键中提取路径并设置到文件对象中 * 最后尝试保存文件并返回是否保存成功 * * @param callback 文件上传回调对象,包含待处理的文件信息 * @param job 航线任务数据传输对象,包含机库序列号等信息 * @return 返回true表示文件保存成功,false表示保存失败 */ private Boolean parseMediaFile(FileUploadCallback callback, WaylineJobDTO job) { // Set the drone sn that shoots the media // 设置拍摄媒体的无人机 Optional<DeviceDTO> dockDTO = deviceService.getDeviceBySn(job.getDockSn()); dockDTO.ifPresent(dock -> callback.getFile().getExt().setSn(dock.getChildDeviceSn())); // set path // 设定路径 String objectKey = callback.getFile().getObjectKey(); callback.getFile().setPath(objectKey.substring(objectKey.indexOf("/") + 1, objectKey.lastIndexOf("/"))); log.info("保存媒体库数据:{}",callback); return fileService.saveFile(callback.getFile()) > 0; } /** * 处理最高优先级上传飞行任务媒体事件 * * 该方法处理来自MQTT通道的最高优先级上传飞行任务媒体请求,主要功能包括: * 1. 验证请求数据有效性 * 2. 发送成功响应 * 3. 更新Redis中媒体文件计数信息 * 4. 通过WebSocket通知前端 * * @param receiver 包含请求数据的接收器对象,包含方法、bid、tid等信息 * @param headers 消息头信息,包含接收的MQTT主题等元数据 */ @Override @ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_HIGHEST_PRIORITY_UPLOAD_FLIGHT_TASK_MEDIA, outputChannel = ChannelName.OUTBOUND) public void handleHighestPriorityUploadFlightTaskMedia(CommonTopicReceiver receiver, MessageHeaders headers) { ard-sample/src/main/java/com/ard/sample/storage/service/impl/StorageServiceImpl.java
@@ -4,6 +4,7 @@ import com.ard.sample.component.mqtt.model.*; import com.ard.sample.component.mqtt.service.IMessageSenderService; import com.ard.oss.model.StsCredentialsDTO; import com.ard.sample.config.DockConfiguration; import com.ard.sample.storage.service.IStorageService; import com.ard.oss.service.impl.OssServiceContext; import org.springframework.beans.factory.annotation.Autowired; @@ -29,8 +30,11 @@ @Override public StsCredentialsDTO getSTSCredentials() { return StsCredentialsDTO.builder() .endpoint(OssConfiguration.endpoint) .bucket(OssConfiguration.bucket) //机场媒体库minio配置信息用代理地址,桶用机场的桶。 //.endpoint(OssConfiguration.endpoint) .endpoint(DockConfiguration.endpoint) // .bucket(OssConfiguration.bucket) .bucket(DockConfiguration.bucket) .credentials(ossService.getCredentials()) .provider(OssConfiguration.provider) .objectKeyPrefix(OssConfiguration.objectDirPrefix) @@ -41,6 +45,7 @@ @Override @ServiceActivator(inputChannel = ChannelName.INBOUND_REQUESTS_STORAGE_CONFIG_GET, outputChannel = ChannelName.OUTBOUND) public void replyConfigGet(CommonTopicReceiver receiver, MessageHeaders headers) { // 20251219 这里是获取上传临时凭证的接口,稍候分析下是否满足条件,如果可以的话就直接回复临时凭证即可 CommonTopicResponse<RequestsReply> response = CommonTopicResponse.<RequestsReply>builder() .tid(receiver.getTid()) .bid(receiver.getBid())