diff --git a/java/src/main/java/com/yfd/platform/modules/experimentalData/service/impl/TsFilesServiceImpl.java b/java/src/main/java/com/yfd/platform/modules/experimentalData/service/impl/TsFilesServiceImpl.java index 47f049a..45e3cbe 100644 --- a/java/src/main/java/com/yfd/platform/modules/experimentalData/service/impl/TsFilesServiceImpl.java +++ b/java/src/main/java/com/yfd/platform/modules/experimentalData/service/impl/TsFilesServiceImpl.java @@ -3052,43 +3052,33 @@ public class TsFilesServiceImpl extends ServiceImpl impl @Override public Page compareMd5(List dataset, String nodeId, String taskId, Page page) { try { - TsTask tsTask = tsTaskMapper.selectById(taskId); TableNameContextHolder.setTaskCode(tsTask.getTaskCode()); StorageSource storageSource = getStorageConfig(tsTask.getBackupStorageId()); + // 获取本地文件路径根目录和存储空间名称 - StorageSourceConfig filePathConfig = getStorageSourceConfig("filePath", "local",tsTask.getLocalStorageId()); - StorageSourceConfig bucketConfig = getStorageSourceConfig("bucketName", "minio",tsTask.getBackupStorageId()); + StorageSourceConfig filePathConfig = getStorageSourceConfig("filePath", "local", tsTask.getLocalStorageId()); + StorageSourceConfig bucketConfig = getStorageSourceConfig("bucketName", "minio", tsTask.getBackupStorageId()); - // ================ 1. 执行原始分页查询 ================ + // ================ 1. 获取所有数据(忽略分页) ================ QueryWrapper queryWrapper = buildQueryWrapper(dataset, nodeId, taskId); - Page tsFilesPage = tsFilesMapper.selectPage(page, queryWrapper); + List allRecords = tsFilesMapper.selectList(queryWrapper); // 获取所有记录 + // ================ 2. 处理文件夹递归 ================ + List allFiles = new ArrayList<>(); if (StringUtils.isEmpty(nodeId) || StringUtils.isEmpty(taskId)) { - if (tsFilesPage == null) { - tsFilesPage = new Page<>(); - tsFilesPage.setRecords(new ArrayList<>()); // 确保 records 被初始化 - } - - List records = tsFilesPage.getRecords(); - // 递归查询每个记录的子节点,并添加到 records 中 - List allFiles = new ArrayList<>(); - for (TsFiles tsFiles : records) { - // 将当前节点加入结果列表 + for (TsFiles tsFiles : allRecords) { allFiles.add(tsFiles); - // 查询该节点的所有子节点并递归添加 if ("FOLDER".equals(tsFiles.getIsFile())) { - List childFiles = getChildFilesRecursiveMd5(tsFiles.getId(), allFiles); + getChildFilesRecursiveMd5(tsFiles.getId(), allFiles); } } - tsFilesPage.setRecords(allFiles); // 同步到 tsFilesPage - System.out.println("Updated records: " + allFiles); + } else { + allFiles = allRecords; } - // ================ 2. 过滤并处理符合条件的记录 ================ - - // ================ 2. 优化后的MD5比较处理 ================ - List filteredRecords = tsFilesPage.getRecords().parallelStream() + // ================ 3. 并行处理所有文件的MD5比较 ================ + List filteredRecords = allFiles.parallelStream() .filter(tsFile -> { if ("FOLDER".equals(tsFile.getIsFile())) { return false; // 跳过文件夹 @@ -3098,7 +3088,7 @@ public class TsFilesServiceImpl extends ServiceImpl impl String minioMD5 = null; boolean hasError = false; - // 计算本地文件MD5(带资源自动管理) + // 计算本地文件MD5 String localFilePath = filePathConfig.getValue() + tsFile.getWorkPath(); File localFile = new File(localFilePath, tsFile.getFileName()); @@ -3132,7 +3122,7 @@ public class TsFilesServiceImpl extends ServiceImpl impl hasError = true; } - // 始终设置MD5字段(成功为实际值,失败为null) + // 设置MD5字段 tsFile.setLocatMd5(localMD5); tsFile.setMinioMd5(minioMD5); @@ -3143,56 +3133,180 @@ public class TsFilesServiceImpl extends ServiceImpl impl }) .collect(Collectors.toList()); -// List filteredRecords = tsFilesPage.getRecords().stream() -// .filter(tsFile -> { -// try { -// if("FOLDER".equals(tsFile.getIsFile())){ -// return false; -// } -// // 计算本地文件MD5 -// File localFile = new File(filePathConfig.getValue() + tsFile.getWorkPath(), tsFile.getFileName()); -// String localMD5 = calculateMD5Data(new FileInputStream(localFile)); -// -// // 计算MinIO文件MD5 -// -// String minioMD5 = getMinioMD5Data(bucketConfig.getValue(), tsFile.getBackupPath(), tsFile.getFileName(),storageSource); -// -// // 路径处理 -// //tsFile.setWorkPath(processingPath(tsFile.getWorkPath(), tsFile.getNodeId())); -// // tsFile.setBackupPath(processingPath(tsFile.getBackupPath(), tsFile.getNodeId())); -// -// // 设置MD5字段(即使不满足条件也保留字段) -// tsFile.setLocatMd5(localMD5); -// tsFile.setMinioMd5(minioMD5); -// -// // 返回是否满足过滤条件 -// return StringUtils.isNoneEmpty(localMD5, minioMD5) && !localMD5.equals(minioMD5); -// } catch (Exception e) { -// LOGGER.error("MD5计算失败: {}", tsFile.getFileName(), e); -// return false; -// } -// }) -// .collect(Collectors.toList()); + // ================ 4. 内存分页处理 ================ + int total = filteredRecords.size(); + long pageSize = page.getSize(); + long currentPage = page.getCurrent(); + long totalPages = pageSize > 0 ? (total + pageSize - 1) / pageSize : 0; + // 计算分页起始索引 + long startIndex = (currentPage - 1) * pageSize; + if (startIndex < 0) startIndex = 0; + if (startIndex >= total) startIndex = total; - // ================ 3. 构建新的分页结果 ================ - Page resultPage = new Page<>(); - resultPage.setRecords(filteredRecords); // 过滤后的数据 - resultPage.setTotal(filteredRecords.size()); // 总记录数为当前页过滤后数量 - resultPage.setCurrent(page.getCurrent()); // 保持当前页码 - resultPage.setSize(page.getSize()); // 保持每页大小 - resultPage.setPages( // 重新计算总页数 - (filteredRecords.size() + page.getSize() - 1) / page.getSize() - ); + // 计算分页结束索引 + long endIndex = Math.min(startIndex + pageSize, total); + + // 获取当前页数据 + List pagedRecords = filteredRecords.subList((int) startIndex,(int) endIndex); + + // ================ 5. 构建分页结果 ================ + Page resultPage = new Page<>(currentPage, pageSize, total); + resultPage.setPages(totalPages); + resultPage.setRecords(pagedRecords); return resultPage; } catch (Exception e) { - LOGGER.error("未知异常:{}", e.getMessage(), e); + LOGGER.error("MD5比较异常: {}", e.getMessage(), e); throw new RuntimeException("系统错误,请联系管理员"); } finally { TableNameContextHolder.clear(); } } +// public Page compareMd5(List dataset, String nodeId, String taskId, Page page) { +// try { +// +// TsTask tsTask = tsTaskMapper.selectById(taskId); +// TableNameContextHolder.setTaskCode(tsTask.getTaskCode()); +// StorageSource storageSource = getStorageConfig(tsTask.getBackupStorageId()); +// // 获取本地文件路径根目录和存储空间名称 +// StorageSourceConfig filePathConfig = getStorageSourceConfig("filePath", "local",tsTask.getLocalStorageId()); +// StorageSourceConfig bucketConfig = getStorageSourceConfig("bucketName", "minio",tsTask.getBackupStorageId()); +// +// // ================ 1. 执行原始分页查询 ================ +// QueryWrapper queryWrapper = buildQueryWrapper(dataset, nodeId, taskId); +// Page tsFilesPage = tsFilesMapper.selectPage(page, queryWrapper); +// +// if (StringUtils.isEmpty(nodeId) || StringUtils.isEmpty(taskId)) { +// if (tsFilesPage == null) { +// tsFilesPage = new Page<>(); +// tsFilesPage.setRecords(new ArrayList<>()); // 确保 records 被初始化 +// } +// +// List records = tsFilesPage.getRecords(); +// // 递归查询每个记录的子节点,并添加到 records 中 +// List allFiles = new ArrayList<>(); +// for (TsFiles tsFiles : records) { +// // 将当前节点加入结果列表 +// allFiles.add(tsFiles); +// // 查询该节点的所有子节点并递归添加 +// if ("FOLDER".equals(tsFiles.getIsFile())) { +// List childFiles = getChildFilesRecursiveMd5(tsFiles.getId(), allFiles); +// } +// } +// tsFilesPage.setRecords(allFiles); // 同步到 tsFilesPage +// } +// +// // ================ 2. 过滤并处理符合条件的记录 ================ +// +// // ================ 2. 优化后的MD5比较处理 ================ +// +// // ================ 2. 优化后的MD5比较处理 ================ +// List filteredRecords = tsFilesPage.getRecords().parallelStream() +// .filter(tsFile -> { +// if ("FOLDER".equals(tsFile.getIsFile())) { +// return false; // 跳过文件夹 +// } +// +// String localMD5 = null; +// String minioMD5 = null; +// boolean hasError = false; +// +// // 计算本地文件MD5(带资源自动管理) +// String localFilePath = filePathConfig.getValue() + tsFile.getWorkPath(); +// File localFile = new File(localFilePath, tsFile.getFileName()); +// +// if (localFile.exists()) { +// try (InputStream is = new FileInputStream(localFile)) { +// localMD5 = calculateMD5Data(is); +// } catch (Exception e) { +// LOGGER.error("本地文件MD5计算失败: {} | 路径: {}", +// tsFile.getFileName(), localFilePath, e); +// hasError = true; +// } +// } else { +// LOGGER.warn("本地文件不存在: {} | 路径: {}", tsFile.getFileName(), localFilePath); +// hasError = true; +// } +// +// // 计算MinIO文件MD5 +// try { +// minioMD5 = getMinioMD5Data( +// bucketConfig.getValue(), +// tsFile.getBackupPath(), +// tsFile.getFileName(), +// storageSource +// ); +// } catch (Exception e) { +// LOGGER.error("MinIO文件MD5获取失败: {} | Bucket: {}/{}", +// tsFile.getFileName(), +// bucketConfig.getValue(), +// tsFile.getBackupPath(), +// e); +// hasError = true; +// } +// +// // 始终设置MD5字段(成功为实际值,失败为null) +// tsFile.setLocatMd5(localMD5); +// tsFile.setMinioMd5(minioMD5); +// +// // 仅当两者都成功计算且不相等时保留 +// return !hasError && +// StringUtils.isNoneEmpty(localMD5, minioMD5) && +// !localMD5.equals(minioMD5); +// }) +// .collect(Collectors.toList()); +// +//// List filteredRecords = tsFilesPage.getRecords().stream() +//// .filter(tsFile -> { +//// try { +//// if("FOLDER".equals(tsFile.getIsFile())){ +//// return false; +//// } +//// // 计算本地文件MD5 +//// File localFile = new File(filePathConfig.getValue() + tsFile.getWorkPath(), tsFile.getFileName()); +//// String localMD5 = calculateMD5Data(new FileInputStream(localFile)); +//// +//// // 计算MinIO文件MD5 +//// +//// String minioMD5 = getMinioMD5Data(bucketConfig.getValue(), tsFile.getBackupPath(), tsFile.getFileName(),storageSource); +//// +//// // 路径处理 +//// //tsFile.setWorkPath(processingPath(tsFile.getWorkPath(), tsFile.getNodeId())); +//// // tsFile.setBackupPath(processingPath(tsFile.getBackupPath(), tsFile.getNodeId())); +//// +//// // 设置MD5字段(即使不满足条件也保留字段) +//// tsFile.setLocatMd5(localMD5); +//// tsFile.setMinioMd5(minioMD5); +//// +//// // 返回是否满足过滤条件 +//// return StringUtils.isNoneEmpty(localMD5, minioMD5) && !localMD5.equals(minioMD5); +//// } catch (Exception e) { +//// LOGGER.error("MD5计算失败: {}", tsFile.getFileName(), e); +//// return false; +//// } +//// }) +//// .collect(Collectors.toList()); +// +// +// // ================ 3. 构建新的分页结果 ================ +// Page resultPage = new Page<>(); +// resultPage.setRecords(filteredRecords); // 过滤后的数据 +// resultPage.setTotal(filteredRecords.size()); // 总记录数为当前页过滤后数量 +// resultPage.setCurrent(page.getCurrent()); // 保持当前页码 +// resultPage.setSize(page.getSize()); // 保持每页大小 +// resultPage.setPages( // 重新计算总页数 +// (filteredRecords.size() + page.getSize() - 1) / page.getSize() +// ); +// +// return resultPage; +// } catch (Exception e) { +// LOGGER.error("未知异常:{}", e.getMessage(), e); +// throw new RuntimeException("系统错误,请联系管理员"); +// } finally { +// TableNameContextHolder.clear(); +// } +// } @Override