rain
2024-07-15 e567c76939c6516b4146aa6a554d95c0bcb4f078
修改航线文件重命名报错,增加图片缩略图,完善喊话功能
18 files modified
6 files added
535 ■■■■ changed files
src/main/java/com/dji/sample/component/oss/service/IOssService.java 6 ●●●● patch | view | raw | blame | history
src/main/java/com/dji/sample/component/oss/service/impl/AliyunOssServiceImpl.java 5 ●●●●● patch | view | raw | blame | history
src/main/java/com/dji/sample/component/oss/service/impl/AmazonS3ServiceImpl.java 6 ●●●●● patch | view | raw | blame | history
src/main/java/com/dji/sample/component/oss/service/impl/MinIOServiceImpl.java 6 ●●●●● patch | view | raw | blame | history
src/main/java/com/dji/sample/component/oss/service/impl/OssServiceContext.java 5 ●●●●● patch | view | raw | blame | history
src/main/java/com/dji/sample/media/dao/INailMapper.java 9 ●●●●● patch | view | raw | blame | history
src/main/java/com/dji/sample/media/model/MediaFileNailEntity.java 64 ●●●●● patch | view | raw | blame | history
src/main/java/com/dji/sample/media/service/impl/FileServiceImpl.java 110 ●●●●● patch | view | raw | blame | history
src/main/java/com/dji/sample/media/service/impl/MediaServiceImpl.java 3 ●●●● patch | view | raw | blame | history
src/main/java/com/dji/sample/patches/config/pojo/PatchesConfigPojo.java 1 ●●●● patch | view | raw | blame | history
src/main/java/com/dji/sample/patches/utils/TimerUtil.java 2 ●●● patch | view | raw | blame | history
src/main/java/com/dji/sample/speak/controller/SpeakVoiceController.java 22 ●●●● patch | view | raw | blame | history
src/main/java/com/dji/sample/speak/dao/SpeakVoiceMapper.java 10 ●●●●● patch | view | raw | blame | history
src/main/java/com/dji/sample/speak/model/dto/PsdkModelDto.java 2 ●●● patch | view | raw | blame | history
src/main/java/com/dji/sample/speak/model/dto/SpeakRestartDto.java 12 ●●●●● patch | view | raw | blame | history
src/main/java/com/dji/sample/speak/model/dto/SpeakStopDto.java 12 ●●●●● patch | view | raw | blame | history
src/main/java/com/dji/sample/speak/model/entity/SpeakVoiceEntity.java 28 ●●●●● patch | view | raw | blame | history
src/main/java/com/dji/sample/speak/service/SpeakVoiceService.java 13 ●●●●● patch | view | raw | blame | history
src/main/java/com/dji/sample/speak/service/serviceImpl/SpeakVoiceServiceImpl.java 91 ●●●● patch | view | raw | blame | history
src/main/java/com/dji/sample/territory/utils/ImgZipUtil.java 55 ●●●●● patch | view | raw | blame | history
src/main/java/com/dji/sample/territory/utils/WaterMarkUtil.java 4 ●●● patch | view | raw | blame | history
src/main/java/com/dji/sample/wayline/controller/WaylineFileController.java 55 ●●●●● patch | view | raw | blame | history
src/main/java/com/dji/sample/wayline/service/IWaylineFileService.java 2 ●●● patch | view | raw | blame | history
src/main/java/com/dji/sample/wayline/service/impl/WaylineFileServiceImpl.java 12 ●●●●● patch | view | raw | blame | history
src/main/java/com/dji/sample/component/oss/service/IOssService.java
@@ -16,12 +16,14 @@
    /**
     * Get temporary credentials.
     *
     * @return
     */
    CredentialsDTO getCredentials();
    /**
     * Get the address of the object based on the bucket name and the object name.
     *
     * @param bucket    bucket name
     * @param objectKey object name
     * @return download link
@@ -30,6 +32,7 @@
    /**
     * Deletes the object in the storage bucket.
     *
     * @param bucket
     * @param objectKey
     * @return
@@ -38,13 +41,14 @@
    /**
     * Get the contents of an object.
     *
     * @param bucket
     * @param objectKey
     * @return
     */
    InputStream getObject(String bucket, String objectKey);
    void putObject(String bucket, String objectKey, InputStream input);
    String putObject(String bucket, String objectKey, InputStream input);
    void createClient();
}
src/main/java/com/dji/sample/component/oss/service/impl/AliyunOssServiceImpl.java
@@ -90,12 +90,13 @@
    }
    @Override
    public void putObject(String bucket, String objectKey, InputStream input) {
    public String putObject(String bucket, String objectKey, InputStream input) {
        if (ossClient.doesObjectExist(bucket, objectKey)) {
            throw new RuntimeException("文件已存在");
            return "该文件名已存在,请更改文件名后再上传";
        }
        PutObjectResult objectResult = ossClient.putObject(new PutObjectRequest(bucket, objectKey, input, new ObjectMetadata()));
        log.info("Upload File: {}", objectResult.getETag());
        return null;
    }
    public void createClient() {
src/main/java/com/dji/sample/component/oss/service/impl/AmazonS3ServiceImpl.java
@@ -11,6 +11,7 @@
import com.amazonaws.services.securitytoken.model.AssumeRoleRequest;
import com.amazonaws.services.securitytoken.model.AssumeRoleResult;
import com.amazonaws.services.securitytoken.model.Credentials;
import com.dji.sample.common.model.ResponseResult;
import com.dji.sample.component.AuthInterceptor;
import com.dji.sample.component.oss.model.OssConfiguration;
import com.dji.sample.component.oss.model.enums.OssTypeEnum;
@@ -79,12 +80,13 @@
    }
    @Override
    public void putObject(String bucket, String objectKey, InputStream input) {
    public String putObject(String bucket, String objectKey, InputStream input) {
        if (client.doesObjectExist(bucket, objectKey)) {
            throw new RuntimeException("文件名已存在");
            return "文件名重复";
        }
        PutObjectResult objectResult = client.putObject(new PutObjectRequest(bucket, objectKey, input, new ObjectMetadata()));
        log.info("Upload File: {}", objectResult.toString());
        return null;
    }
    public void createClient() {
src/main/java/com/dji/sample/component/oss/service/impl/MinIOServiceImpl.java
@@ -1,5 +1,6 @@
package com.dji.sample.component.oss.service.impl;
import com.dji.sample.common.model.ResponseResult;
import com.dji.sample.component.oss.model.OssConfiguration;
import com.dji.sample.component.oss.model.enums.OssTypeEnum;
import com.dji.sample.component.oss.service.IOssService;
@@ -91,10 +92,10 @@
    }
    @Override
    public void putObject(String bucket, String objectKey, InputStream input) {
    public String putObject(String bucket, String objectKey, InputStream input) {
        try {
            client.statObject(StatObjectArgs.builder().bucket(bucket).object(objectKey).build());
            throw new RuntimeException("文件名已存在");
            return "航线名重复";
        } catch (MinioException | InvalidKeyException | IOException | NoSuchAlgorithmException e) {
            log.info("文件不存在,开始上传。");
            try {
@@ -106,6 +107,7 @@
                ex.printStackTrace();
            }
        }
        return null;
    }
    public void createClient() {
src/main/java/com/dji/sample/component/oss/service/impl/OssServiceContext.java
@@ -1,5 +1,6 @@
package com.dji.sample.component.oss.service.impl;
import com.dji.sample.common.model.ResponseResult;
import com.dji.sample.component.oss.model.OssConfiguration;
import com.dji.sample.component.oss.model.enums.OssTypeEnum;
import com.dji.sample.component.oss.service.IOssService;
@@ -58,8 +59,8 @@
        return this.ossService.getObject(bucket, objectKey);
    }
    public void putObject(String bucket, String objectKey, InputStream stream) {
        this.ossService.putObject(bucket, objectKey, stream);
    public String putObject(String bucket, String objectKey, InputStream stream) {
        return this.ossService.putObject(bucket, objectKey, stream);
    }
    void createClient() {
src/main/java/com/dji/sample/media/dao/INailMapper.java
New file
@@ -0,0 +1,9 @@
package com.dji.sample.media.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.dji.sample.media.model.MediaFileNailEntity;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface INailMapper extends BaseMapper<MediaFileNailEntity> {
}
src/main/java/com/dji/sample/media/model/MediaFileNailEntity.java
New file
@@ -0,0 +1,64 @@
package com.dji.sample.media.model;
import com.baomidou.mybatisplus.annotation.*;
import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@TableName(value = "media_file_nail", autoResultMap = true)
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class MediaFileNailEntity {
    @TableId(type = IdType.AUTO)
    private Integer id;
    @TableField("file_id")
    private String fileId;
    @TableField("file_name")
    private String fileName;
    @TableField("file_path")
    private String filePath;
    @TableField("workspace_id")
    private String workspaceId;
    @TableField("fingerprint")
    private String fingerprint;
    @TableField("tinny_fingerprint")
    private String tinnyFingerprint;
    @TableField("object_key")
    private String objectKey;
    @TableField("sub_file_type")
    private Integer subFileType;
    @TableField("is_original")
    private Boolean isOriginal;
    @TableField("payload")
    private String payload;
    @TableField("job_id")
    private String jobId;
    @TableField(value = "create_time", fill = FieldFill.INSERT)
    private Long createTime;
    @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
    private Long updateTime;
    @TableField("collect_status")
    private Boolean collectStatus;
    @TableField("user_id")
    private String userId;
}
src/main/java/com/dji/sample/media/service/impl/FileServiceImpl.java
@@ -18,6 +18,7 @@
import com.dji.sample.manage.service.IDeviceDictionaryService;
import com.dji.sample.media.dao.IFileMapper;
import com.dji.sample.media.dao.IMarkMapper;
import com.dji.sample.media.dao.INailMapper;
import com.dji.sample.media.model.*;
import com.dji.sample.media.service.IFileService;
import com.dji.sample.media.util.ImgUtil;
@@ -27,6 +28,7 @@
import com.dji.sample.patches.utils.TimerUtil;
import com.dji.sample.territory.pojo.TerritoryConfigPojo;
import com.dji.sample.territory.service.impl.TbFjServiceImpl;
import com.dji.sample.territory.utils.ImgZipUtil;
import com.dji.sample.territory.utils.WaterMarkUtil;
import com.dji.sample.wayline.service.IWaylineFileService;
import com.dji.sample.wayline.service.IWaylineJobService;
@@ -66,6 +68,8 @@
    private IFileMapper mapper;
    @Autowired
    private IMarkMapper markMapper;
    @Autowired
    private INailMapper nailMapper;
    @Autowired
    private GetPatchesMapper patchesMapper;
    @Autowired
@@ -112,7 +116,23 @@
    }
    public void saveMarkFile(String workspaceId, FileUploadDTO file) throws IOException, FontFormatException, ImageProcessingException {
        String endpoint = pojo.getEndpoint();
        String accessKey = pojo.getAccessKey();
        String secretKey = pojo.getSecretKey();
        String bucketName = pojo.getBucket();
        String url = pojo.getEndpoint() + "/" + pojo.getBucket() + file.getObjectKey();
        File file1 = TbFjServiceImpl.downloadFile(url);
        File nailFile = new File(ImgZipUtil.compressImage(file1, 50).toURI());
        MediaFileNailEntity nailEntity = this.fileUploadConvertToNailEntity(file);
        nailEntity.setIsOriginal(false);
        nailEntity.setWorkspaceId(workspaceId);
        nailEntity.setFileName("nail" + file.getName());
        nailEntity.setObjectKey("/nail" + file.getPath() + "/" + file.getName());
        nailEntity.setFilePath("nail" + file.getPath());
        String nailName = nailEntity.getObjectKey();
        nailEntity.setFileId(UUID.randomUUID().toString());
        uploadFile(endpoint, accessKey, secretKey, bucketName, nailName, nailFile, "image/jpeg");
        nailMapper.insert(nailEntity);
        try {
            boolean contains = file.getName().contains("~");
            if (contains) {
@@ -125,44 +145,42 @@
                            .set(LotInfo::getInvestigate, 1);
                    patchesMapper.update(null, updateWrapper);
                }
                boolean endsWith = file.getObjectKey().endsWith(".mp4");
                if (endsWith) {
                    MediaFileMarkEntity mediaFileMarkEntity = this.fileUploadConvertToMarkEntity(file);
                    mediaFileMarkEntity.setWorkspaceId(workspaceId);
                    mediaFileMarkEntity.setFileId(UUID.randomUUID().toString());
                    markMapper.insert(mediaFileMarkEntity);
                }
                MediaFileMarkEntity mediaFileMarkEntity = this.fileUploadConvertToMarkEntity(file);
                long timestamp = convertToTimestamp(file.getMetadata().getCreatedTime());
                File markFile = new File(WaterMarkUtil.addWatermark(file1, timestamp, file.getMetadata().getShootPosition().getLat(),
                        file.getMetadata().getShootPosition().getLng(), file.getMetadata().getGimbalYawDegree()).toURI());
                Object data = ImgUtil.getInfo(file1);
                mediaFileMarkEntity.setDronedata(data);
                mediaFileMarkEntity.setWorkspaceId(workspaceId);
                mediaFileMarkEntity.setIsadd(0);
                mediaFileMarkEntity.setIsOriginal(false);
                mediaFileMarkEntity.setFileId(UUID.randomUUID().toString());
                mediaFileMarkEntity.setObjectKey("/mark" + file.getPath() + "/" + file.getName());
                mediaFileMarkEntity.setFileName("mark" + file.getName());
                mediaFileMarkEntity.setFilePath("mark" + file.getPath());
                String objectName = mediaFileMarkEntity.getObjectKey(); // 例如 "folder/file.txt"
                uploadFile(endpoint, accessKey, secretKey, bucketName, objectName, markFile, "image/jpeg");
                markMapper.insert(mediaFileMarkEntity);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        boolean endsWith = file.getObjectKey().endsWith(".mp4");
        if (endsWith) {
            MediaFileMarkEntity mediaFileMarkEntity = this.fileUploadConvertToMarkEntity(file);
            mediaFileMarkEntity.setWorkspaceId(workspaceId);
            mediaFileMarkEntity.setFileId(UUID.randomUUID().toString());
            markMapper.insert(mediaFileMarkEntity);
        }
        MediaFileMarkEntity mediaFileMarkEntity = this.fileUploadConvertToMarkEntity(file);
        String url = pojo.getEndpoint()+"/"+pojo.getBucket() + file.getObjectKey();
        File file1 = TbFjServiceImpl.downloadFile(url);
        long timestamp = convertToTimestamp(file.getMetadata().getCreatedTime());
        File file2 = new File(WaterMarkUtil.addWatermark(file1, timestamp, file.getMetadata().getShootPosition().getLat(),
                file.getMetadata().getShootPosition().getLng(), file.getMetadata().getGimbalYawDegree()).toURI());
        Object data = ImgUtil.getInfo(file1);
        mediaFileMarkEntity.setDronedata(data);
        mediaFileMarkEntity.setWorkspaceId(workspaceId);
        mediaFileMarkEntity.setIsadd(0);
        mediaFileMarkEntity.setFileId(UUID.randomUUID().toString());
        mediaFileMarkEntity.setObjectKey("/mark" + file.getPath() + "/" + file.getName());
        mediaFileMarkEntity.setFileName("mark" + file.getName());
        mediaFileMarkEntity.setFilePath("mark" + file.getPath());
        String endpoint = pojo.getEndpoint();
        String accessKey = pojo.getAccessKey();
        String secretKey = pojo.getSecretKey();
        String bucketName = pojo.getBucket();
        String objectName = mediaFileMarkEntity.getObjectKey(); // 例如 "folder/file.txt"
        uploadFile(endpoint, accessKey, secretKey, bucketName, objectName, file2,"image/jpeg");
        markMapper.insert(mediaFileMarkEntity);
    }
            }
    @Override
    public Object mediaInfo(String filename) {
        String name = "mark" + filename;
        String name = filename;
        if (!filename.contains("mark")) {
            name = "mark" + filename;
        }
        List<MediaFileMarkEntity> entity = markMapper.selectList(new LambdaQueryWrapper<MediaFileMarkEntity>()
                .eq(MediaFileMarkEntity::getFileName, name));
        if (entity != null) {
@@ -244,8 +262,6 @@
        // 返回分页数据
        return new PaginationData<>(pageResults, new Pagination(resultPage));
    }
    @Override
@@ -410,6 +426,30 @@
        return builder.build();
    }
    private MediaFileNailEntity fileUploadConvertToNailEntity(FileUploadDTO file) {
        MediaFileNailEntity.MediaFileNailEntityBuilder builder = MediaFileNailEntity.builder();
        if (file != null) {
            builder.fileName(file.getName())
                    .fingerprint(file.getFingerprint())
                    .objectKey(file.getObjectKey())
                    .subFileType(file.getSubFileType())
                    .isOriginal(file.getExt().getIsOriginal())
                    .jobId(file.getExt().getFlightId())
                    .tinnyFingerprint(file.getExt().getTinnyFingerprint());
            // domain-type-subType
            int[] payloadModel = Arrays.stream(file.getExt().getPayloadModelKey().split("-"))
                    .map(Integer::valueOf)
                    .mapToInt(Integer::intValue)
                    .toArray();
            Optional<DeviceDictionaryDTO> payloadDict = deviceDictionaryService
                    .getOneDictionaryInfoByTypeSubType(DeviceDomainEnum.PAYLOAD.getVal(), payloadModel[1], payloadModel[2]);
            payloadDict.ifPresent(payload -> builder.payload(payload.getDeviceName()));
        }
        return builder.build();
    }
    /**
     * Convert database entity objects into file data transfer object.
@@ -440,7 +480,7 @@
        return builder.build();
    }
    public static void uploadFile(String endpoint, String accessKey, String secretKey, String bucketName, String objectName, File file,String type) {
    public static void uploadFile(String endpoint, String accessKey, String secretKey, String bucketName, String objectName, File file, String type) {
        try {
            // 创建MinIO客户端实例
            MinioClient minioClient = MinioClient.builder()
src/main/java/com/dji/sample/media/service/impl/MediaServiceImpl.java
@@ -226,12 +226,13 @@
        // set path
        String objectKey = callback.getFile().getObjectKey();
        callback.getFile().setPath(objectKey.substring(objectKey.indexOf("/") + 1, objectKey.lastIndexOf("/")));
        int count =fileService.saveFile(job.getWorkspaceId(), callback.getFile());
                try {
                    fileService.saveMarkFile(job.getWorkspaceId(), callback.getFile());
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
        return fileService.saveFile(job.getWorkspaceId(), callback.getFile()) > 0;
        return count > 0;
    }
    /**
src/main/java/com/dji/sample/patches/config/pojo/PatchesConfigPojo.java
@@ -23,7 +23,6 @@
    private String destKMZFile;
    @Value("${patches.url.path.kmz.sourceDir}")
    private String sourceDir;
    @Value("${patches.xml.temple.template}")
    private String template;
    @Value("${patches.xml.temple.waylines}")
src/main/java/com/dji/sample/patches/utils/TimerUtil.java
@@ -152,7 +152,7 @@
        List<Long> lists1 = new ArrayList<>();
        lists1.add(time);
        String times = convertTimestampToFormattedString(time);
        sendPostWithParameters("别墅巡查一段", "c1b9c70e-2e58-4147-b43e-aa4f639726bb", times, lists1, listOfLists);
        sendPostWithParameters("别墅巡查一段", "2a44748a-1500-406f-80cf-ad92186fe8d2", times, lists1, listOfLists);
    }
    @Scheduled(cron = "0 50 0 * * ?")
src/main/java/com/dji/sample/speak/controller/SpeakVoiceController.java
@@ -2,6 +2,7 @@
import com.dji.sample.common.model.ResponseResult;
import com.dji.sample.component.mqtt.service.IMessageSenderService;
import com.dji.sample.patches.config.pojo.PatchesConfigPojo;
import com.dji.sample.patches.utils.MultipartFileTOFileUtil;
import com.dji.sample.speak.model.dto.PsdkModelDto;
import com.dji.sample.speak.model.dto.SpeakVoiceStartDto;
@@ -13,21 +14,25 @@
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.sound.sampled.UnsupportedAudioFileException;
import java.io.File;
import java.io.IOException;
@RestController
@RequestMapping("${url.speak.prefix}${url.speak.version}")
public class SpeakVoiceController {
    @Autowired
    private SpeakVoiceService voiceServicel;
    @Autowired
    private PatchesConfigPojo patchesConfigPojo;
    @PostMapping("/startVoice")
    public ResponseResult takeVoice(@RequestParam String sn,
                                    @RequestParam int psdk_index,
                                    @RequestParam String name,
                                    @RequestParam MultipartFile file) {
        File file1=MultipartFileTOFileUtil.multipartFile2File(file,"src/main/resources/tmp/20240614");
        return ResponseResult.success(voiceServicel.takeVoice(sn, psdk_index,name,file1));
                                    @RequestParam Integer volumn,
                                    @RequestParam MultipartFile file) throws UnsupportedAudioFileException, IOException {
        File file1=MultipartFileTOFileUtil.multipartFile2File(file,patchesConfigPojo.getUnzip());
        return ResponseResult.success(voiceServicel.takeVoice(sn, psdk_index,name,file1,volumn));
    }
    @PostMapping("/stopVoice")
@@ -49,4 +54,13 @@
    public ResponseResult restartVoice(@RequestParam int psdkIndex, @RequestParam String sn) {
        return ResponseResult.success(voiceServicel.restartVoice(sn, psdkIndex));
    }
    @PostMapping("/putVoice")
    public ResponseResult putVoice (int id){
        return ResponseResult.success(voiceServicel.awayRiver(id));
    }
    @GetMapping("/selectVoice")
    public ResponseResult getVoices(@RequestParam Integer page,@RequestParam Integer page_size ){
    return ResponseResult.success(voiceServicel.getVoices(page,page_size));
    }
}
src/main/java/com/dji/sample/speak/dao/SpeakVoiceMapper.java
New file
@@ -0,0 +1,10 @@
package com.dji.sample.speak.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.dji.sample.speak.model.entity.SpeakVoiceEntity;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface SpeakVoiceMapper extends BaseMapper<SpeakVoiceEntity> {
}
src/main/java/com/dji/sample/speak/model/dto/PsdkModelDto.java
@@ -10,5 +10,5 @@
@AllArgsConstructor
public class PsdkModelDto {
    private Integer psdk_index;
    private PsdkModelEnum play_mode;
    private Integer play_mode;
}
src/main/java/com/dji/sample/speak/model/dto/SpeakRestartDto.java
New file
@@ -0,0 +1,12 @@
package com.dji.sample.speak.model.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class SpeakRestartDto {
    private Integer psdk_index;
}
src/main/java/com/dji/sample/speak/model/dto/SpeakStopDto.java
New file
@@ -0,0 +1,12 @@
package com.dji.sample.speak.model.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class SpeakStopDto {
    private Integer psdk_index;
}
src/main/java/com/dji/sample/speak/model/entity/SpeakVoiceEntity.java
New file
@@ -0,0 +1,28 @@
package com.dji.sample.speak.model.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@TableName("speak_voice")
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class SpeakVoiceEntity {
    @TableId(type = IdType.AUTO)
    private int id;
    @TableField("name")
    private String name;
    @TableField("url")
    private String url;
    @TableField("md5")
    private String md5;
    @TableField("second")
    private double second;
}
src/main/java/com/dji/sample/speak/service/SpeakVoiceService.java
@@ -1,15 +1,22 @@
package com.dji.sample.speak.service;
import com.dji.sample.common.model.PaginationData;
import com.dji.sample.common.model.ResponseResult;
import com.dji.sample.speak.model.dto.PsdkModelDto;
import com.dji.sample.speak.model.dto.SpeakVoiceStartDto;
import com.dji.sample.speak.model.dto.SpeakVolumeDto;
import com.dji.sample.speak.model.entity.SpeakVoiceEntity;
import com.dji.sample.speak.model.enums.FormatEnum;
import com.dji.sample.speak.model.param.SpeakVoiceStartParam;
import org.springframework.stereotype.Service;
import javax.sound.sampled.UnsupportedAudioFileException;
import java.io.File;
import java.io.IOException;
import java.util.List;
public interface SpeakVoiceService {
    int takeVoice(String sn , Integer psdk_index, String name, File file);
    int takeVoice(String sn , Integer psdk_index, String name, File file,Integer volumn) throws UnsupportedAudioFileException, IOException;
    int restartVoice(String sn ,Integer psdk_index);
@@ -18,4 +25,8 @@
    int setVoiceMode(String sn,PsdkModelDto dto);
    int setVoiceVolume(SpeakVolumeDto dto,String sn);
    int awayRiver (int id);
    PaginationData<SpeakVoiceEntity> getVoices(Integer pages,Integer page_size);
}
src/main/java/com/dji/sample/speak/service/serviceImpl/SpeakVoiceServiceImpl.java
@@ -1,25 +1,32 @@
package com.dji.sample.speak.service.serviceImpl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.dji.sample.common.model.Pagination;
import com.dji.sample.common.model.PaginationData;
import com.dji.sample.component.mqtt.service.IMessageSenderService;
import com.dji.sample.media.model.MinioPojo;
import com.dji.sample.media.service.impl.FileServiceImpl;
import com.dji.sample.speak.model.dto.PsdkModelDto;
import com.dji.sample.speak.model.dto.SpeakVoiceFileDto;
import com.dji.sample.speak.model.dto.SpeakVoiceStartDto;
import com.dji.sample.speak.model.dto.SpeakVolumeDto;
import com.dji.sample.speak.dao.SpeakVoiceMapper;
import com.dji.sample.speak.model.dto.*;
import com.dji.sample.speak.model.entity.SpeakVoiceEntity;
import com.dji.sample.speak.model.enums.FormatEnum;
import com.dji.sample.speak.model.enums.PsdkModelEnum;
import com.dji.sample.speak.model.enums.VoiceEnums;
import com.dji.sample.speak.model.param.SpeakVoiceStartParam;
import com.dji.sample.speak.service.SpeakVoiceService;
import com.dji.sample.speak.util.MD5Util;
import lombok.extern.log4j.Log4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.UnsupportedAudioFileException;
import java.io.File;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.stream.Collectors;
@Service
@@ -28,39 +35,86 @@
    private IMessageSenderService messageSenderService;
    @Autowired
    private MinioPojo pojo;
    @Autowired
    private SpeakVoiceMapper voiceMapper;
    @Override
    public int takeVoice( String sn , Integer psdk_index, String name, File file) {
    public int takeVoice(String sn, Integer psdk_index, String name, File file,Integer volumn) throws UnsupportedAudioFileException, IOException {
        SpeakVoiceEntity voiceEntity = new SpeakVoiceEntity();
        SpeakVoiceStartDto dto = new SpeakVoiceStartDto();
        SpeakVoiceFileDto fileDto = new SpeakVoiceFileDto();
        SpeakVolumeDto volumeDto=new SpeakVolumeDto();
        volumeDto.setPsdk_index(psdk_index);
        volumeDto.setPlay_volume(volumn);
        String url = upMinio(file, name);
        fileDto.setUrl(url);
        fileDto.setMd5(MD5Util.getMD5Checksum(file));
        String md5 = MD5Util.getMD5Checksum(file);
        fileDto.setMd5(md5);
        fileDto.setFormat(FormatEnum.PCM);
        fileDto.setName(name);
        dto.setPsdk_index(psdk_index);
        dto.setFile(fileDto);
        double time = getAudioDuration(file);
        voiceEntity.setMd5(md5);
        voiceEntity.setSecond(time);
        voiceEntity.setUrl(url);
        voiceEntity.setName(name);
        voiceMapper.insert(voiceEntity);
        messageSenderService.publishServicesTopic(sn, VoiceEnums.SPEAKER_PLAY_VOLUME_SET.getMethod(), volumeDto);
        return messageSenderService.publishServicesTopic(sn, VoiceEnums.SPEAKER_AUDIO_PLAY_START.getMethod(), dto).getResult();
    }
    @Override
    public int restartVoice(String sn, Integer psdk_index) {
        return messageSenderService.publishServicesTopic(sn, VoiceEnums.SPEAKER_REPLAY.getMethod(), psdk_index).getResult();
        SpeakRestartDto dto=new SpeakRestartDto();
        dto.setPsdk_index(psdk_index);
        return messageSenderService.publishServicesTopic(sn, VoiceEnums.SPEAKER_REPLAY.getMethod(), dto).getResult();
    }
    @Override
    public int stopVoice(String sn, Integer psdk_index) {
        return messageSenderService.publishServicesTopic(sn,VoiceEnums.SPEAKER_PLAY_STOP.getMethod(), psdk_index).getResult();
        SpeakStopDto dto=new SpeakStopDto();
        dto.setPsdk_index(psdk_index);
        return messageSenderService.publishServicesTopic(sn, VoiceEnums.SPEAKER_PLAY_STOP.getMethod(), dto).getResult();
    }
    @Override
    public int setVoiceMode(String sn,PsdkModelDto dto) {
        return messageSenderService.publishServicesTopic(sn,VoiceEnums.SPEAKER_PLAY_MODE_SET.getMethod(), dto).getResult();
    public int setVoiceMode(String sn, PsdkModelDto dto) {
        return messageSenderService.publishServicesTopic(sn, VoiceEnums.SPEAKER_PLAY_MODE_SET.getMethod(), dto).getResult();
    }
    @Override
    public int setVoiceVolume(SpeakVolumeDto dto, String sn) {
        return     messageSenderService.publishServicesTopic(sn,VoiceEnums.SPEAKER_PLAY_VOLUME_SET.getMethod(), dto).getResult();
        return messageSenderService.publishServicesTopic(sn, VoiceEnums.SPEAKER_PLAY_VOLUME_SET.getMethod(), dto).getResult();
    }
    @Override
    public int awayRiver(int id) {
        SpeakVoiceEntity voiceEntity=voiceMapper.selectById(id);
        SpeakVoiceStartDto dto = new SpeakVoiceStartDto();
        SpeakVoiceFileDto fileDto = new SpeakVoiceFileDto();
        fileDto.setUrl(voiceEntity.getUrl());
        fileDto.setMd5(voiceEntity.getMd5());
        fileDto.setFormat(FormatEnum.PCM);
        fileDto.setName(voiceEntity.getName());
        dto.setPsdk_index(2);
        dto.setFile(fileDto);
        return messageSenderService.publishServicesTopic("4TADKCM0010016", VoiceEnums.SPEAKER_AUDIO_PLAY_START.getMethod(), dto).getResult();
    }
    @Override
    public PaginationData<SpeakVoiceEntity> getVoices(Integer pages,Integer page_size) {
        // Paging Query
        Page<SpeakVoiceEntity> page = voiceMapper.selectPage(
                new Page<>(pages,page_size),
                new LambdaQueryWrapper<SpeakVoiceEntity>()
        );
        // Wrap the results of a paging query into a custom paging object.
        List<SpeakVoiceEntity> records = page.getRecords()
                .stream()
                .collect(Collectors.toList());
        return new PaginationData<>(records, new Pagination(page));
    }
    public String upMinio(File file, String fileName) {
@@ -78,4 +132,13 @@
        // 格式化时间,生成当前时间
        return currentTime.format(DateTimeFormatter.ofPattern("MMddHHmm"));
    }
    public static double getAudioDuration(File file) throws UnsupportedAudioFileException, IOException {
        AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(file);
        AudioFormat format = audioInputStream.getFormat();
        long audioFileLength = file.length();
        int frameSize = format.getFrameSize();
        float frameRate = format.getFrameRate();
        return Math.round(audioFileLength / (frameSize * frameRate));
    }
}
src/main/java/com/dji/sample/territory/utils/ImgZipUtil.java
@@ -5,6 +5,7 @@
import javax.imageio.ImageWriter;
import javax.imageio.stream.ImageOutputStream;
import javax.imageio.stream.MemoryCacheImageOutputStream;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.nio.file.Files;
@@ -14,29 +15,43 @@
    /**
     * 图片压缩
     *
     * @param originalImageFile
     * @param compressionQuality 图片压缩质量 0-1
     * @return
     * @throws IOException
     */
    public static File compressImageAndGetFile(File originalImageFile, float compressionQuality) throws IOException {
        BufferedImage originalImage = ImageIO.read(originalImageFile);
        try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
            ImageWriter writer = ImageIO.getImageWritersByFormatName("jpg").next();
            try (ImageOutputStream ios = new MemoryCacheImageOutputStream(baos)) {
                writer.setOutput(ios);
                ImageWriteParam param = writer.getDefaultWriteParam();
                param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
                param.setCompressionQuality(compressionQuality);
                writer.write(null, new javax.imageio.IIOImage(originalImage, null, null), param);
            } finally {
                writer.dispose();
            }
            InputStream in = new ByteArrayInputStream(baos.toByteArray());
            File tempFile = File.createTempFile("compressed-", ".jpg");
            tempFile.deleteOnExit();
            Files.copy(in, tempFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
            return tempFile;
    public static File compressImage(File inputFile, int targetSizeKB) throws IOException {
        BufferedImage image = ImageIO.read(inputFile);
        // 计算目标图片的尺寸
        long targetSizeBytes = targetSizeKB * 1024;
        long originalSizeBytes = getImageSize(image);
        double compressionRatio = (double) targetSizeBytes / originalSizeBytes;
        int targetWidth = (int) (image.getWidth() * Math.sqrt(compressionRatio));
        int targetHeight = (int) (image.getHeight() * Math.sqrt(compressionRatio));
        // 使用ImageIO进行压缩
        BufferedImage compressedImage = new BufferedImage(targetWidth, targetHeight, BufferedImage.TYPE_INT_RGB);
        Graphics2D graphics = compressedImage.createGraphics();
        graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        graphics.drawImage(image, 0, 0, targetWidth, targetHeight, null);
        graphics.dispose();
        // 将压缩后的图片写入输出文件
        File outputFile = new File(inputFile.getParent(), "compressed_" + inputFile.getName());
        ImageIO.write(compressedImage, "jpeg", outputFile);
        return outputFile;
    }
    public static long getImageSize(BufferedImage image) {
        File tempFile;
        try {
            tempFile = File.createTempFile("temp", ".tmp");
            ImageIO.write(image, "jpg", tempFile);
            long size = tempFile.length();
            tempFile.delete();
            return size;
        } catch (IOException ex) {
            ex.printStackTrace();
            return 0;
        }
    }
}
src/main/java/com/dji/sample/territory/utils/WaterMarkUtil.java
@@ -10,9 +10,6 @@
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import static com.dji.sample.territory.utils.ImgZipUtil.compressImageAndGetFile;
@Component
public class WaterMarkUtil {
@@ -65,6 +62,7 @@
        g2d.setComposite(alphaComposite);
        String extraInfo = String.format("Lon:%.7f Lat:%.7f\n%s %s", lng, lat, angel, sd);
        File fontFile = new File("/usr/share/fonts/MiSans-Normal.ttf"); // 替换为你的字体文件路径
//        File fontFile = new File("src/main/resources/MiSans-Normal.ttf"); // 替换为你的字体文件路径
        Font customFont = Font.createFont(Font.TRUETYPE_FONT, fontFile).deriveFont(36.00F);
        // 注册字体
        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
src/main/java/com/dji/sample/wayline/controller/WaylineFileController.java
@@ -41,8 +41,9 @@
    /**
     * 根据查询条件查询航路线文件的基本数据。
     * pilot中的查询条件字段是固定的。
     * @param orderBy   排序的字段。在sql语句的末尾拼接。
     * @param favorited 路径线文件是否为收藏夹。
     *
     * @param orderBy      排序的字段。在sql语句的末尾拼接。
     * @param favorited    路径线文件是否为收藏夹。
     * @param page
     * @param pageSize
     * @param templateType
@@ -52,10 +53,10 @@
    @GetMapping("/{workspace_id}/waylines")
    @SysLogAnnotation(operModul = "航线库", operType = "查询", operDesc = "根据查询条件查询航路线文件的基本数据")
    public ResponseResult<PaginationData<WaylineFileDTO>> getWaylinesPagination(@RequestParam(name = "order_by") String orderBy,
                                      @RequestParam(required = false) boolean favorited, @RequestParam Integer page,
                                      @RequestParam(name = "page_size", defaultValue = "10") Integer pageSize,
                                      @RequestParam(name = "template_type", required = false) Integer[] templateType,
                                      @PathVariable(name = "workspace_id") String workspaceId) {
                                                                                @RequestParam(required = false) boolean favorited, @RequestParam Integer page,
                                                                                @RequestParam(name = "page_size", defaultValue = "10") Integer pageSize,
                                                                                @RequestParam(name = "template_type", required = false) Integer[] templateType,
                                                                                @PathVariable(name = "workspace_id") String workspaceId) {
        WaylineQueryParam param = WaylineQueryParam.builder()
                .favorited(favorited)
                .page(page)
@@ -70,6 +71,7 @@
    /**
     * 根据wayline文件id查询文件的下载地址;
     * 和重定向到此地址直接下载。
     *
     * @param workspaceId
     * @param waylineId
     * @param response
@@ -77,7 +79,7 @@
    @GetMapping("/{workspace_id}/waylines/{wayline_id}/url")
    @SysLogAnnotation(operModul = "航线库", operType = "查询", operDesc = "根据wayline文件id查询文件的下载地址1")
    public void getFileUrl(@PathVariable(name = "workspace_id") String workspaceId,
                                @PathVariable(name = "wayline_id") String waylineId, HttpServletResponse response) {
                           @PathVariable(name = "wayline_id") String waylineId, HttpServletResponse response) {
        try {
            URL url = waylineFileService.getObjectUrl(workspaceId, waylineId);
@@ -91,7 +93,7 @@
    @GetMapping("/{workspace_id}/waylines/{wayline_id}/urlData")
    @SysLogAnnotation(operModul = "航线库", operType = "查询", operDesc = "根据wayline文件id查询文件的下载地址2")
    public ResponseResult getFileUrlData(@PathVariable(name = "workspace_id") String workspaceId,
                           @PathVariable(name = "wayline_id") String waylineId, HttpServletResponse response) {
                                         @PathVariable(name = "wayline_id") String waylineId, HttpServletResponse response) {
        URL url = null;
        try {
@@ -105,6 +107,7 @@
    /**
     * 当航路线文件被飞行员上传到存储服务器时,
     * 通过该接口报告文件的基本信息。
     *
     * @param request
     * @param workspaceId
     * @param uploadFile
@@ -116,7 +119,7 @@
                                         @PathVariable(name = "workspace_id") String workspaceId,
                                         @RequestBody WaylineFileUploadDTO uploadFile) {
        CustomClaim customClaim = (CustomClaim)request.getAttribute(TOKEN_CLAIM);
        CustomClaim customClaim = (CustomClaim) request.getAttribute(TOKEN_CLAIM);
        WaylineFileDTO metadata = uploadFile.getMetadata();
        metadata.setUsername(customClaim.getUsername());
@@ -130,14 +133,15 @@
    /**
     * 根据路径线文件id收藏路径线文件。
     *
     * @param workspaceId
     * @param ids   wayline file id
     * @param ids         wayline file id
     * @return
     */
    @PostMapping("/{workspace_id}/favorites")
    @SysLogAnnotation(operModul = "航线库", operType = "修改", operDesc = "根据路径线文件id收藏路径线文件")
    public ResponseResult markFavorite(@PathVariable(name = "workspace_id") String workspaceId,
                             @RequestParam(name = "id") List<String> ids) {
                                       @RequestParam(name = "id") List<String> ids) {
        boolean isMark = waylineFileService.markFavorite(workspaceId, ids, true);
        return isMark ? ResponseResult.success() : ResponseResult.error();
@@ -145,14 +149,15 @@
    /**
     * 根据航路线文件id删除此航路线文件的收藏夹。
     *
     * @param workspaceId
     * @param ids wayline file id
     * @param ids         wayline file id
     * @return
     */
    @DeleteMapping("/{workspace_id}/favorites")
    @SysLogAnnotation(operModul = "航线库", operType = "删除", operDesc = "根据航路线文件id删除此航路线文件的收藏夹")
    public ResponseResult unmarkFavorite(@PathVariable(name = "workspace_id") String workspaceId,
                             @RequestParam(name = "id") List<String> ids) {
                                         @RequestParam(name = "id") List<String> ids) {
        boolean isMark = waylineFileService.markFavorite(workspaceId, ids, false);
        return isMark ? ResponseResult.success() : ResponseResult.error();
@@ -161,6 +166,7 @@
    /**
     * 根据航路线名称检查名称是否已经存在,必须保证航路线名称的唯一性。
     * 此接口将在上传航路线时被调用,并且必须可用。
     *
     * @param workspaceId
     * @param names
     * @return
@@ -176,6 +182,7 @@
    /**
     * 根据航路线id删除工作区中的航路线文件。
     *
     * @param workspaceId
     * @param waylineId
     * @return
@@ -190,6 +197,7 @@
    /**
     * 上传kmz航线文件
     *
     * @param file
     * @return
     */
@@ -203,27 +211,30 @@
        if (Objects.isNull(file)) {
            return ResponseResult.error("未上传文件");
        }
        CustomClaim customClaim = (CustomClaim)request.getAttribute(TOKEN_CLAIM);
        CustomClaim customClaim = (CustomClaim) request.getAttribute(TOKEN_CLAIM);
        String creator = customClaim.getUsername();
        waylineFileService.importKmzFile(file, workspaceId, creator,patchesId,spotInFreckle);
        return ResponseResult.success();
        String back = waylineFileService.importKmzFile(file, workspaceId, creator, patchesId, spotInFreckle);
        if (back != null) {
            return ResponseResult.error(back);
        }
        return ResponseResult.success(back);
    }
    @GetMapping("/{workspace_id}/waylines_list")
    @SysLogAnnotation(operModul = "航线库", operType = "查询", operDesc = "查询当前工作区航线库列表")
    public ResponseResult<List<WaylineListDTO>> waylineList(@PathVariable(name = "workspace_id") String workspaceId,String droneName) {
        return ResponseResult.success(waylineFileService.waylineList(workspaceId,droneName)) ;
    public ResponseResult<List<WaylineListDTO>> waylineList(@PathVariable(name = "workspace_id") String workspaceId, String droneName) {
        return ResponseResult.success(waylineFileService.waylineList(workspaceId, droneName));
    }
    @PutMapping("/{workspace_id}/wayline_update")
    public ResponseResult upWayline(@RequestParam String waylineId,@RequestParam String name){
        WaylineFileEntity entity=WaylineFileEntity
    public ResponseResult upWayline(@RequestParam String waylineId, @RequestParam String name) {
        WaylineFileEntity entity = WaylineFileEntity
                .builder()
                .waylineId(waylineId)
                .name(name)
                .build();
        if(waylineFileService.updateWayline(entity)==0){
        if (waylineFileService.updateWayline(entity) == 0) {
            return ResponseResult.error("更新失败");
        }else return ResponseResult.success();
        } else return ResponseResult.success();
    }
}
src/main/java/com/dji/sample/wayline/service/IWaylineFileService.java
@@ -83,7 +83,7 @@
     * @param creator
     * @return
     */
    void importKmzFile(MultipartFile file, String workspaceId, String creator,String patchesId,String spotInFreckle);
    String importKmzFile(MultipartFile file, String workspaceId, String creator,String patchesId,String spotInFreckle);
    /**
     * 创建航线,返回航线对象
src/main/java/com/dji/sample/wayline/service/impl/WaylineFileServiceImpl.java
@@ -192,22 +192,25 @@
    }
    @Override
    public void importKmzFile(MultipartFile file, String workspaceId, String creator, String patchesId,String spotInFreckle) {
    public String importKmzFile(MultipartFile file, String workspaceId, String creator, String patchesId, String spotInFreckle) {
        Optional<WaylineFileDTO> waylineFileOpt = validKmzFile(file);
        if (waylineFileOpt.isEmpty()) {
            throw new RuntimeException("文件格式错误");
        }
        String back = null;
        try {
            WaylineFileDTO waylineFile = waylineFileOpt.get();
            waylineFile.setWaylineId(workspaceId);
            waylineFile.setUsername(creator);
            waylineFile.setSpotInFreckle(spotInFreckle);
            ossService.putObject(OssConfiguration.bucket, waylineFile.getObjectKey(), file.getInputStream());
            this.saveWaylineFiles(workspaceId, waylineFile, patchesId);
            back = ossService.putObject(OssConfiguration.bucket, waylineFile.getObjectKey(), file.getInputStream());
            if (back==null) {
                this.saveWaylineFiles(workspaceId, waylineFile, patchesId);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return back;
    }
    @Override
@@ -222,7 +225,6 @@
            waylineFile = waylineFileOpt.get();
            waylineFile.setWaylineId(workspaceId);
            waylineFile.setUsername(creator);
            ossService.putObject(OssConfiguration.bucket, waylineFile.getObjectKey(), file.getInputStream());
            this.saveWaylineFile(workspaceId, waylineFile);