package com.dji.sample.media.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper; 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.common.model.ResponseResult; import com.dji.sample.component.oss.model.OssConfiguration; import com.dji.sample.component.oss.service.impl.OssServiceContext; import com.dji.sample.manage.model.dto.DeviceDictionaryDTO; import com.dji.sample.manage.model.enums.DeviceDomainEnum; 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.model.*; import com.dji.sample.media.service.IFileService; import com.dji.sample.media.util.ImgUtil; import com.dji.sample.patches.dao.GetPatchesMapper; import com.dji.sample.patches.model.entity.LotInfo; import com.dji.sample.patches.utils.TimerUtil; import com.dji.sample.territory.service.impl.TbFjServiceImpl; import com.dji.sample.territory.utils.WaterMarkUtil; import com.drew.imaging.ImageProcessingException; import io.minio.MinioClient; import io.minio.PutObjectArgs; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.awt.*; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.net.URL; import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneId; import java.util.*; import java.util.List; import java.util.stream.Collectors; /** * @author sean * @version 0.2 * @date 2021/12/9 */ @Service @Transactional public class FileServiceImpl implements IFileService { @Autowired private IFileMapper mapper; @Autowired private IMarkMapper markMapper; @Autowired private GetPatchesMapper patchesMapper; @Autowired private IDeviceDictionaryService deviceDictionaryService; @Autowired private OssServiceContext ossService; private Optional getMediaByFingerprint(String workspaceId, String fingerprint) { MediaFileEntity fileEntity = mapper.selectOne(new LambdaQueryWrapper() .eq(MediaFileEntity::getWorkspaceId, workspaceId) .eq(MediaFileEntity::getFingerprint, fingerprint)); return Optional.ofNullable(fileEntity); } private Optional getMediaByFileId(String workspaceId, String fileId) { MediaFileEntity fileEntity = mapper.selectOne(new LambdaQueryWrapper() .eq(MediaFileEntity::getWorkspaceId, workspaceId) .eq(MediaFileEntity::getFileId, fileId)); return Optional.ofNullable(fileEntity); } @Override public Boolean checkExist(String workspaceId, String fingerprint) { return this.getMediaByFingerprint(workspaceId, fingerprint).isPresent(); } @Override public Integer saveFile(String workspaceId, FileUploadDTO file) { MediaFileEntity fileEntity = this.fileUploadConvertToEntity(file); fileEntity.setWorkspaceId(workspaceId); fileEntity.setFileId(UUID.randomUUID().toString()); return mapper.insert(fileEntity); } public Integer saveMarkFile(String workspaceId, FileUploadDTO file) throws IOException, FontFormatException, ImageProcessingException { File file2 = null; MediaFileMarkEntity mediaFileMarkEntity = this.fileUploadConvertToMarkEntity(file); String url = "http://dev.jxpskj.com:9000/cloud-bucket" + file.getObjectKey(); File file1 = TbFjServiceImpl.downloadFile(url); long timestamp = convertToTimestamp(file.getMetadata().getCreatedTime()); boolean endsWith = file.getObjectKey().endsWith(".mp4"); if (!endsWith) { 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.setFileId(UUID.randomUUID().toString()); mediaFileMarkEntity.setObjectKey("/mark" + file.getPath() + "/" + file.getName()); mediaFileMarkEntity.setFileName("mark" + file.getName()); mediaFileMarkEntity.setFilePath("mark" + file.getPath()); String endpoint = "http://dev.jxpskj.com:9000"; String accessKey = "pskj"; String secretKey = "pskj@2021"; String bucketName = "cloud-bucket"; String objectName = mediaFileMarkEntity.getObjectKey(); // 例如 "folder/file.txt" uploadFile(endpoint, accessKey, secretKey, bucketName, objectName, file2); return markMapper.insert(mediaFileMarkEntity); } @Override public Object mediaInfo(String fileId) { MediaFileMarkEntity entity = markMapper.selectOne(new LambdaQueryWrapper() .eq(MediaFileMarkEntity::getFileId, fileId)); return entity.getDronedata(); } @Override public List getAllFilesByWorkspaceId(String workspaceId) { return mapper.selectList(new LambdaQueryWrapper() .eq(MediaFileEntity::getWorkspaceId, workspaceId)) .stream() .map(this::entityConvertToDto) .collect(Collectors.toList()); } @Override public List listMediaFileEntity(String workspaceId, String jobId) { return mapper.selectList(new LambdaQueryWrapper() .eq(MediaFileEntity::getWorkspaceId, workspaceId).eq(MediaFileEntity::getJobId, jobId)); } public List listByIsadd(String dkbh, String workspaceId) { return mapper.selectList(new LambdaQueryWrapper().eq(MediaFileEntity::getIsadd, 0) .eq(MediaFileEntity::getWorkspaceId, workspaceId) .like(MediaFileEntity::getFileName, dkbh + "~")); } public ResponseResult updateExamByFileId(String fileId) { int examineStatus = getExamByFileId(fileId); if (examineStatus == 1) { LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>(); updateWrapper.eq(MediaFileEntity::getFileId, fileId) .set(MediaFileEntity::getExamine, 0); mapper.update(null, updateWrapper); return ResponseResult.success("审核未通过"); } else if (examineStatus == 0) { LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>(); updateWrapper.eq(MediaFileEntity::getFileId, fileId) .set(MediaFileEntity::getExamine, 1); mapper.update(null, updateWrapper); return ResponseResult.success("审核通过"); } return ResponseResult.error("媒体文件不存在"); } public int getExamByFileId(String fileId) { MediaFileEntity entity = mapper.selectOne(new LambdaQueryWrapper() .eq(MediaFileEntity::getFileId, fileId)); return entity.getExamine(); } @Override public PaginationData getMediaFilesPaginationByWorkspaceId(String workspaceId, long page, long pageSize, MediaFileQueryParam mediaFileQueryParam) { // Page pageData = mapper.selectPage( // new Page(page, pageSize), // new LambdaQueryWrapper() // .eq(MediaFileEntity::getWorkspaceId, workspaceId) // .orderByDesc(MediaFileEntity::getId)); Page pageData = mapper.selectPage(new Page(page, pageSize), new LambdaQueryWrapper() .eq(MediaFileEntity::getWorkspaceId, workspaceId) .orderByDesc(MediaFileEntity::getCreateTime)); List records = pageData.getRecords() .stream() .collect(Collectors.toList()); return new PaginationData(records, new Pagination(pageData)); } public int deleteMedia(String workspaceId, String fileId) { int count = mapper.delete(new LambdaUpdateWrapper().eq(MediaFileEntity::getFileId, fileId) .eq(MediaFileEntity::getWorkspaceId, workspaceId)); return count; } @Override public URL getObjectUrl(String workspaceId, String fileId) { Optional mediaFileOpt = getMediaByFileId(workspaceId, fileId); if (mediaFileOpt.isEmpty()) { throw new IllegalArgumentException("{} 不存在"); } return ossService.getObjectUrl(OssConfiguration.bucket, mediaFileOpt.get().getObjectKey()); } @Override public List getFilesByWorkspaceAndJobId(String workspaceId, String jobId) { return mapper.selectList(new LambdaQueryWrapper() .eq(MediaFileEntity::getWorkspaceId, workspaceId) .eq(MediaFileEntity::getJobId, jobId)) .stream() .map(this::entityConvertToDto).collect(Collectors.toList()); } @Override public Boolean updateMediaFile(String workspaceId, MediaFileEntity mediaFileEntity) { /*MediaFileEntity params = new MediaFileEntity(); params.setFileId(mediaFileEntity.getFileId()); params.setWorkspaceId(mediaFileEntity.getWorkspaceId());*/ boolean update1 = new LambdaUpdateChainWrapper<>(mapper).eq(MediaFileEntity::getFileId, mediaFileEntity.getFileId()) .set(MediaFileEntity::getFileName, mediaFileEntity.getFileName()) .set(MediaFileEntity::getCollectStatus, mediaFileEntity.getCollectStatus()) .set(MediaFileEntity::getUserId, mediaFileEntity.getUserId()) .update(); // int update = mapper.update(mediaFileEntity, Wrappers.update(params)); return update1; } /** * Convert the received file object into a database entity object. * * @param file * @return */ private MediaFileEntity fileUploadConvertToEntity(FileUploadDTO file) { MediaFileEntity.MediaFileEntityBuilder builder = MediaFileEntity.builder(); if (file != null) { builder.fileName(file.getName()) .filePath(file.getPath()) .isadd(0) .examine(1) .fingerprint(file.getFingerprint()) .objectKey(file.getObjectKey()) .subFileType(file.getSubFileType()) .isOriginal(file.getExt().getIsOriginal()) .jobId(file.getExt().getFlightId()) .drone(file.getExt().getSn()).metadata(file.getMetadata()) .tinnyFingerprint(file.getExt().getTinnyFingerprint()); // domain-type-subType int[] payloadModel = Arrays.stream(file.getExt().getPayloadModelKey().split("-")) .map(Integer::valueOf) .mapToInt(Integer::intValue) .toArray(); Optional payloadDict = deviceDictionaryService .getOneDictionaryInfoByTypeSubType(DeviceDomainEnum.PAYLOAD.getVal(), payloadModel[1], payloadModel[2]); payloadDict.ifPresent(payload -> builder.payload(payload.getDeviceName())); } return builder.build(); } private MediaFileMarkEntity fileUploadConvertToMarkEntity(FileUploadDTO file) { MediaFileMarkEntity.MediaFileMarkEntityBuilder builder = MediaFileMarkEntity.builder(); if (file != null) { builder.fileName(file.getName()) .filePath(file.getPath()) .isadd(0) .fingerprint(file.getFingerprint()) .objectKey(file.getObjectKey()) .subFileType(file.getSubFileType()) .isOriginal(file.getExt().getIsOriginal()) .jobId(file.getExt().getFlightId()) .drone(file.getExt().getSn()).metadata(file.getMetadata()) .tinnyFingerprint(file.getExt().getTinnyFingerprint()); // domain-type-subType int[] payloadModel = Arrays.stream(file.getExt().getPayloadModelKey().split("-")) .map(Integer::valueOf) .mapToInt(Integer::intValue) .toArray(); Optional 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. * * @param entity * @return */ private MediaFileDTO entityConvertToDto(MediaFileEntity entity) { MediaFileDTO.MediaFileDTOBuilder builder = MediaFileDTO.builder(); if (entity != null) { builder.fileName(entity.getFileName()) .fileId(entity.getFileId()) .filePath(entity.getFilePath()) .isOriginal(entity.getIsOriginal()) .fingerprint(entity.getFingerprint()) .objectKey(entity.getObjectKey()) .tinnyFingerprint(entity.getTinnyFingerprint()) .payload(entity.getPayload()) .metadata(entity.getMetadata()) .createTime(LocalDateTime.ofInstant( Instant.ofEpochMilli(entity.getCreateTime()), ZoneId.systemDefault())) .drone(entity.getDrone()) .jobId(entity.getJobId()); } return builder.build(); } public static void uploadFile(String endpoint, String accessKey, String secretKey, String bucketName, String objectName, File file) { try { // 创建MinIO客户端实例 MinioClient minioClient = MinioClient.builder() .endpoint(endpoint) .credentials(accessKey, secretKey) .build(); // 上传文件 FileInputStream fileInputStream = new FileInputStream(file); minioClient.putObject( PutObjectArgs.builder() .bucket(bucketName) .object(objectName) .stream(fileInputStream, file.length(), -1) .build() ); fileInputStream.close(); } catch (Exception e) { throw new RuntimeException("上传文件至服务器失败" + e); } } public static long convertToTimestamp(Date date) { // 获取时间戳(毫秒级别) return date.getTime(); } }