package com.dji.sample.media.service.impl; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 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.dao.INailMapper; 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.DistrictCodeUtils; 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; import com.drew.imaging.ImageProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import io.minio.MinioClient; import io.minio.PutObjectArgs; import org.slf4j.Logger; import org.slf4j.LoggerFactory; 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 INailMapper nailMapper; @Autowired private GetPatchesMapper patchesMapper; @Autowired private IDeviceDictionaryService deviceDictionaryService; @Autowired private OssServiceContext ossService; @Autowired private TerritoryConfigPojo territoryConfigPojo; @Autowired private IWaylineJobService waylineJobService; @Autowired private IWaylineFileService waylineFileService; @Autowired private MinioPojo pojo; private ObjectMapper objectMapper = new ObjectMapper(); 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 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) { String name = TimerUtil.getDkbh(file.getName()); List lotInfos = patchesMapper.selectList(new LambdaQueryWrapper().eq(LotInfo::getDkbh, name)); if (!lotInfos.isEmpty()) { LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>(); updateWrapper.eq(LotInfo::getDkbh, name) .eq(LotInfo::getInvestigate, 0) .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(); } } @Override public Object mediaInfo(String filename) { String name = filename; if (!filename.contains("mark")) { name = "mark" + filename; } List entity = markMapper.selectList(new LambdaQueryWrapper() .eq(MediaFileMarkEntity::getFileName, name)); if (entity != null) { return entity.get(0).getDronedata(); } else { return "该图片信息正在加载"; } } @Override public List getAllFilesByWorkspaceId(String workspaceId) { return mapper.selectList(new LambdaQueryWrapper() .eq(MediaFileEntity::getWorkspaceId, workspaceId)) .stream() .map(this::entityConvertToDto) .collect(Collectors.toList()); } @Override public PaginationData MediaQuery(Integer page, Integer pageSize, Long updateStart, Long updateEnd, Long photoStart, Long photoEnd, String jobName, String workspaceId, String type) { // 创建查询条件对象 LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); // 添加查询条件 queryWrapper.eq(MediaFileEntity::getWorkspaceId, workspaceId); if (updateStart != null && updateEnd != null) { queryWrapper.between(MediaFileEntity::getCreateTime, updateStart, updateEnd); } if (photoStart != null && photoEnd != null) { queryWrapper.apply("JSON_UNQUOTE(JSON_EXTRACT(metadata, '$.createdTime')) BETWEEN {0} AND {1}", photoStart, photoEnd); } if (jobName != null && !jobName.isEmpty()) { List jobIds = waylineJobService.getJobIds(jobName); if (jobIds.isEmpty()) { return new PaginationData<>(Collections.emptyList(), new Pagination(new Page<>(page, pageSize))); } queryWrapper.in(MediaFileEntity::getJobId, jobIds); } if (type != null && !type.isEmpty()) { if ("图片".equals(type)) { queryWrapper.likeLeft(MediaFileEntity::getFileName, ".jpeg"); } else if ("视频".equals(type)) { queryWrapper.likeLeft(MediaFileEntity::getFileName, ".mp4"); } } queryWrapper.last("ORDER BY JSON_EXTRACT(metadata, '$.createdTime') DESC"); // 执行查询获取所有结果 List allResults = mapper.selectList(queryWrapper); // 处理结果去重并设置任务名称 Map uniqueFileMap = new LinkedHashMap<>(); List uniqueResults = allResults.stream() .peek(mediaFile -> { String taskNameResult = waylineJobService.getName(mediaFile.getJobId()); mediaFile.setJobName(taskNameResult); }) .filter(mediaFile -> uniqueFileMap.putIfAbsent(mediaFile.getFileName(), mediaFile) == null) .collect(Collectors.toList()); // 计算分页信息 int total = uniqueResults.size(); int start = (page - 1) * pageSize; int end = Math.min(start + pageSize, total); // 获取当前页的结果 List pageResults = uniqueResults.subList(start, end); // 创建临时的 Page 对象 Page resultPage = new Page<>(page, pageSize); resultPage.setRecords(pageResults); resultPage.setTotal(total); // 返回分页数据 return new PaginationData<>(pageResults, new Pagination(resultPage)); } @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::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(); } public String getDkbhName(String name) { int startIndex = name.indexOf("点") + 1; int endIndex = name.indexOf("."); return name.substring(startIndex, endIndex); } @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() .peek(mediaFile -> { // 获取任务名称并设置到fileId String taskNameResult = waylineJobService.getName(mediaFile.getJobId()); mediaFile.setJobName(taskNameResult); }) .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()) .examine(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(); } private MediaFileMarkEntity fileUploadConvertToMarkEntity(FileUploadDTO file) { MediaFileMarkEntity.MediaFileMarkEntityBuilder builder = MediaFileMarkEntity.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()) .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 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 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, String type) { 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) .contentType(type) .build() ); fileInputStream.close(); } catch (Exception e) { throw new RuntimeException("上传文件至服务器失败" + e); } } public static long convertToTimestamp(Date date) { // 获取时间戳(毫秒级别) return date.getTime(); } public List getSameJobId(String jobId) { return mapper.selectList(new LambdaQueryWrapper() .eq(MediaFileEntity::getJobId, jobId)); } public void updateMediaFileNames(String jobId) { // 查询符合条件的数据 List mediaFiles = mapper.selectList(new LambdaQueryWrapper() .eq(MediaFileEntity::getJobId, jobId)); boolean allContainTilde = mediaFiles.stream().allMatch(file -> file.getFileName().contains("~")); boolean noneContainTilde = mediaFiles.stream().noneMatch(file -> file.getFileName().contains("~")); // 如果所有 fileName 都包含 '~' 或者都不包含 '~',将 is_add 字段改为 1 if (allContainTilde || noneContainTilde) { return; } // 筛选出name字段不包含'~'的数据 List filteredFiles = mediaFiles.stream() .filter(file -> !file.getFileName().contains("~")) .collect(Collectors.toList()); for (MediaFileEntity currentFile : filteredFiles) { String currentName = currentFile.getFileName(); Map currentMetadata = JSON.parseObject(JSON.toJSONString(currentFile.getMetadata()), Map.class); Long currentCreatedTime = (Long) currentMetadata.get("createdTime"); // 找到metadata中的createdTime小于当前数据的createdTime且最接近的那条数据 Optional closestFileOpt = mediaFiles.stream() .filter(file -> { Map metadata = JSON.parseObject(JSON.toJSONString(file.getMetadata()), Map.class); Long createdTime = (Long) metadata.get("createdTime"); String filename = file.getFileName(); return createdTime < currentCreatedTime && filename.contains("~"); }) .min((file1, file2) -> { Map metadata1 = JSON.parseObject(JSON.toJSONString(file1.getMetadata()), Map.class); Map metadata2 = JSON.parseObject(JSON.toJSONString(file2.getMetadata()), Map.class); Long time1 = (Long) metadata1.get("createdTime"); Long time2 = (Long) metadata2.get("createdTime"); return Long.compare(currentCreatedTime - time1, currentCreatedTime - time2); }); if (closestFileOpt.isEmpty()) { // 找不到小于的文件,尝试找大于且最接近的文件 closestFileOpt = mediaFiles.stream() .filter(file -> { Map metadata = JSON.parseObject(JSON.toJSONString(file.getMetadata()), Map.class); Long createdTime = (Long) metadata.get("createdTime"); String filename = file.getFileName(); return createdTime > currentCreatedTime && filename.contains("~"); }) .min((file1, file2) -> { Map metadata1 = JSON.parseObject(JSON.toJSONString(file1.getMetadata()), Map.class); Map metadata2 = JSON.parseObject(JSON.toJSONString(file2.getMetadata()), Map.class); Long time1 = (Long) metadata1.get("createdTime"); Long time2 = (Long) metadata2.get("createdTime"); return Long.compare(time1 - currentCreatedTime, time2 - currentCreatedTime); }); } // 提取并替换name字段 closestFileOpt.ifPresent(closestFile -> { String closestName = closestFile.getFileName(); int startIndex = closestName.indexOf("V"); if (startIndex == -1) startIndex = closestName.indexOf("W"); if (startIndex == -1) startIndex = closestName.indexOf("Z"); if (startIndex == -1) startIndex = closestName.indexOf("T"); if (startIndex == -1) { return; } int endIndex = closestName.indexOf(".", startIndex); if (endIndex == -1) { return; } String replacement = closestName.substring(startIndex, endIndex); int currentStartIndex = currentName.indexOf("V"); if (currentStartIndex == -1) currentStartIndex = currentName.indexOf("W"); if (currentStartIndex == -1) currentStartIndex = currentName.indexOf("Z"); if (currentStartIndex == -1) currentStartIndex = currentName.indexOf("T"); if (currentStartIndex == -1) { return; } int currentEndIndex = currentName.indexOf(".", currentStartIndex); if (currentEndIndex == -1) { return; } String newName = currentName.substring(0, currentStartIndex) + replacement + currentName.substring(currentEndIndex); currentFile.setFileName(newName); updateMediaById(currentFile.getId(), currentFile); }); } } @Override public void updateMarkMediaFileNames(String jobId) { try { // 查询符合条件的数据 List mediaFiles = markMapper.selectList(new LambdaQueryWrapper() .eq(MediaFileMarkEntity::getJobId, jobId)); // 判断所有 fileName 是否都包含 '~' 或者都不包含 '~' boolean allContainTilde = mediaFiles.stream().allMatch(file -> file.getFileName().contains("~")); boolean noneContainTilde = mediaFiles.stream().noneMatch(file -> file.getFileName().contains("~")); // 如果所有 fileName 都包含 '~' 或者都不包含 '~',将 is_add 字段改为 1 if (allContainTilde || noneContainTilde) { mediaFiles.forEach(file -> { file.setIsadd(1); updateById(file.getId(), file); }); return; } // 筛选出name字段不包含'~'的数据 List filteredFiles = mediaFiles.stream() .filter(file -> !file.getFileName().contains("~")) .collect(Collectors.toList()); for (MediaFileMarkEntity currentFile : filteredFiles) { String currentName = currentFile.getFileName(); Map currentMetadata = JSON.parseObject(JSON.toJSONString(currentFile.getMetadata()), Map.class); Long currentCreatedTime = (Long) currentMetadata.get("createdTime"); // 找到metadata中的createdTime小于当前数据的createdTime且最接近的那条数据 Optional closestFileOpt = mediaFiles.stream() .filter(file -> { Map metadata = JSON.parseObject(JSON.toJSONString(file.getMetadata()), Map.class); Long createdTime = (Long) metadata.get("createdTime"); String filename = file.getFileName(); return createdTime < currentCreatedTime && filename.contains("~"); }) .min((file1, file2) -> { Map metadata1 = JSON.parseObject(JSON.toJSONString(file1.getMetadata()), Map.class); Map metadata2 = JSON.parseObject(JSON.toJSONString(file2.getMetadata()), Map.class); Long time1 = (Long) metadata1.get("createdTime"); Long time2 = (Long) metadata2.get("createdTime"); return Long.compare(currentCreatedTime - time1, currentCreatedTime - time2); }); if (closestFileOpt.isEmpty()) { // 找不到小于的文件,尝试找大于且最接近的文件 closestFileOpt = mediaFiles.stream() .filter(file -> { Map metadata = JSON.parseObject(JSON.toJSONString(file.getMetadata()), Map.class); Long createdTime = (Long) metadata.get("createdTime"); String filename = file.getFileName(); return createdTime > currentCreatedTime && filename.contains("~"); }) .min((file1, file2) -> { Map metadata1 = JSON.parseObject(JSON.toJSONString(file1.getMetadata()), Map.class); Map metadata2 = JSON.parseObject(JSON.toJSONString(file2.getMetadata()), Map.class); Long time1 = (Long) metadata1.get("createdTime"); Long time2 = (Long) metadata2.get("createdTime"); return Long.compare(time1 - currentCreatedTime, time2 - currentCreatedTime); }); } // 提取并替换name字段 closestFileOpt.ifPresent(closestFile -> { String closestName = closestFile.getFileName(); int startIndex = closestName.indexOf("V"); if (startIndex == -1) startIndex = closestName.indexOf("W"); if (startIndex == -1) startIndex = closestName.indexOf("Z"); if (startIndex == -1) startIndex = closestName.indexOf("T"); if (startIndex == -1) { return; } int endIndex = closestName.indexOf(".", startIndex); if (endIndex == -1) { return; } String replacement = closestName.substring(startIndex, endIndex); int currentStartIndex = currentName.indexOf("V"); if (currentStartIndex == -1) currentStartIndex = currentName.indexOf("W"); if (currentStartIndex == -1) currentStartIndex = currentName.indexOf("Z"); if (currentStartIndex == -1) currentStartIndex = currentName.indexOf("T"); if (currentStartIndex == -1) { return; } int currentEndIndex = currentName.indexOf(".", currentStartIndex); if (currentEndIndex == -1) { return; } String newName = currentName.substring(0, currentStartIndex) + replacement + currentName.substring(currentEndIndex); currentFile.setFileName(newName); updateById(currentFile.getId(), currentFile); }); } } catch (Exception e) { e.printStackTrace(); } } public void updateById(Integer id, MediaFileMarkEntity entity) { entity.setIsadd(1); UpdateWrapper updateWrapper = new UpdateWrapper<>(); updateWrapper.eq("id", id); markMapper.update(entity, updateWrapper); } public void updateMediaById(Integer id, MediaFileEntity entity) { UpdateWrapper updateWrapper = new UpdateWrapper<>(); updateWrapper.eq("id", id); mapper.update(entity, updateWrapper); } public void getNoaddFile() { List markEntities = markMapper.selectList(new LambdaQueryWrapper().eq(MediaFileMarkEntity::getIsadd, 0)); for (MediaFileMarkEntity mark : markEntities) { updateMarkMediaFileNames(mark.getJobId()); updateMediaFileNames(mark.getJobId()); } } }