diff --git a/java/src/main/java/com/yfd/platform/modules/specialDocument/service/impl/NodesServiceImpl.java b/java/src/main/java/com/yfd/platform/modules/specialDocument/service/impl/NodesServiceImpl.java index e19311f..d4670d1 100644 --- a/java/src/main/java/com/yfd/platform/modules/specialDocument/service/impl/NodesServiceImpl.java +++ b/java/src/main/java/com/yfd/platform/modules/specialDocument/service/impl/NodesServiceImpl.java @@ -680,62 +680,7 @@ public class NodesServiceImpl extends ServiceImpl implements StorageSourceConfig storageSourceConfig = storageSourceConfigMapper.selectOne(queryWrapper); //获取文件列表 - String absolutePath = project.getProjectName() + "/"; - FileListRequest fileListRequest = buildFileRequest(absolutePath); - String storageKey = fileListRequest.getStorageKey(); - Integer storageId = storageSourceService.findIdByKey(storageKey); - if (storageId == null) { - throw new InvalidStorageSourceException("通过存储源 key 未找到存储源, key: " + storageKey); - } - // 处理请求参数默认值 - fileListRequest.handleDefaultValue(); - AbstractBaseFileService fileService = storageSourceContext.getByStorageId(storageId); - - //获取执行时间 - long startFileListData = System.currentTimeMillis(); - List fileItemListss = fileService.fileListData("", project.getProjectName()); - - LOGGER.info("[fileListData] 耗时 {} ms | 数据量: {} 条", - System.currentTimeMillis() - startFileListData, - fileItemListss.size()); - - - //通过hutool获取路径下面的文件和文件夹// 递归获取所有内容(包含文件和目录,需自定义过滤) - String path = storageSourceConfig.getValue() + "/"+ absolutePath; - long startHutoolFileListData = System.currentTimeMillis(); - List allContents = FileUtil.loopFiles(path, file -> true); - LOGGER.info("[allContents] 耗时 {} ms | 数据量: {} 条", - System.currentTimeMillis() - startHutoolFileListData, - allContents.size()); - - - // 过滤文件夹(添加第二个耗时日志) - long startFilterFolders = System.currentTimeMillis(); - List filteredFolders = fileItemListss.stream() - .filter(item -> item.getType() == FileTypeEnum.FOLDER && item.getPath() != null && !item.getPath().isEmpty()) - .collect(Collectors.toList()); - LOGGER.info("[过滤文件夹] 耗时 {} ms | 过滤后数量: {} 条", - System.currentTimeMillis() - startFilterFolders, - filteredFolders.size()); - - - // 过滤文件(添加第三个耗时日志) - long startFilterFiles = System.currentTimeMillis(); - List filteredFiles = fileItemListss.stream() - .filter(item -> item.getType() == FileTypeEnum.FILE && item.getPath() != null && !item.getPath().isEmpty()) - .collect(Collectors.toList()); - LOGGER.info("[过滤文件] 耗时 {} ms | 过滤后数量: {} 条", - System.currentTimeMillis() - startFilterFiles, - filteredFiles.size()); - - - //todo 首先获取两个集合 对比出数据库中没有的文件夹以及文件,递归增加 - List fileItemList = fileService.fileList(fileListRequest.getPath()); - if (fileItemList.size() == 0) { - throw new Exception("该项目目录不存在或没有项目文档,请先建立项目目录和文档。"); - } - - + String absolutePath = "/" + project.getProjectName() + "/"; //获取当前登录用户 上传人是当前登录人 UsernamePasswordAuthenticationToken authentication = (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication(); @@ -743,23 +688,40 @@ public class NodesServiceImpl extends ServiceImpl implements if (authentication != null) { loginuser = (LoginUser) authentication.getPrincipal(); } + //登录人 + String uploader = null; + if (loginuser != null) { + uploader = loginuser.getUsername(); + } // 设置当前时间 LocalDateTime now = LocalDateTime.now(); // 转换为 Timestamp Timestamp currentTime = Timestamp.valueOf(now); + // 存储所有目录和文件的列表 + List nodesToCreate = new ArrayList<>(); + List filesToCreate = new ArrayList<>(); - - //处理文件夹新增到表结构 - List nodesList = new ArrayList<>(); + String path = storageSourceConfig.getValue() + "/" + absolutePath; + File projectDir = new File(path); + // 获取所有子目录 + List allSubDirs = new ArrayList<>(); + getAllSubDirectories(projectDir, allSubDirs); + String storageSourceConfigPath = storageSourceConfig.getValue().replace("\\", "/"); + // 批量处理子目录 long startBuildNodes = System.currentTimeMillis(); - for (FileItemResult FolderItem : filteredFolders) { + for (File subDir : allSubDirs) { + String normalizedSubDirPath = subDir.getAbsolutePath().replace("\\", "/"); + // 获取上一级目录 + String parentPath = normalizedSubDirPath.substring(0, normalizedSubDirPath.lastIndexOf("/")); + // 去掉 D:/yun 部分 + String finalPath = parentPath.replace(storageSourceConfigPath, ""); Nodes nodes = new Nodes(); nodes.setId(IdUtil.fastSimpleUUID()); nodes.setProjectId(id); nodes.setParentId("00"); nodes.setNodeOrder(1); // 1. 处理空路径,确保默认值 - String filePath = FolderItem.getPath() != null ? FolderItem.getPath() : "/"; + String filePath = ensurePathFormat(finalPath); // 2. 路径标准化处理:统一替换所有分隔符为 "/",并合并连续分隔符 String normalizedPath = filePath .replaceAll("[/\\\\]+", "/") // 将 "\" 或混合分隔符统一为 "/" @@ -773,20 +735,25 @@ public class NodesServiceImpl extends ServiceImpl implements // 5. 生成 nodeType(两位数字) String nodeType = String.format("%02d", depth); nodes.setNodeType(nodeType); - nodes.setNodeName(FolderItem.getName()); - nodes.setCustom3(ensurePathFormat(FolderItem.getPath())); + nodes.setNodeName(subDir.getName()); + nodes.setCustom3(ensurePathFormat(finalPath)); nodes.setCreateTime(currentTime); - nodesList.add(nodes); + nodesToCreate.add(nodes); + + } LOGGER.info("[构建节点列表] 耗时 {} ms | 待处理数量: {} 条", System.currentTimeMillis() - startBuildNodes, - nodesList.size()); - + nodesToCreate.size()); + //todo 首先获取两个集合 对比出数据库中没有的文件夹以及文件,递归增加 + if (!projectDir.exists() || projectDir.list().length == 0) { + throw new Exception("该项目目录不存在或没有项目文档,请先建立项目目录和文档。"); + } // 批量插入节点表(忽略重复) - if (!nodesList.isEmpty()) { + if (!nodesToCreate.isEmpty()) { long startBatchInsert = System.currentTimeMillis(); - int affectedRows = nodesMapper.batchInsertIgnore(nodesList); + int affectedRows = nodesMapper.batchInsertIgnore(nodesToCreate); LOGGER.info("[批量插入节点表] 耗时 {} ms | 实际新增数量: {} 条", System.currentTimeMillis() - startBatchInsert, affectedRows); @@ -797,51 +764,42 @@ public class NodesServiceImpl extends ServiceImpl implements int affectedLevelRows = nodesMapper.updateParentIdByPathHierarchy(); LOGGER.info("层级关系更新完成,影响 {} 行,总耗时 {} 毫秒", affectedLevelRows, costTime); - //接下来就是新增文件表 新增成功以后 通过路径获取节点表中的 custom3+路径 就是node ID + // 获取所有文件 + List allFiles = new ArrayList<>(); + getAllFiles(projectDir, allFiles); + System.out.println("allFiles=" + allFiles.size()); - - //处理文件夹新增到表结构 - List filesList = new ArrayList<>(); long startBuildFiles = System.currentTimeMillis(); - for (FileItemResult fileItem : filteredFiles) { + // 批量处理文件 + for (File file : allFiles) { + String normalizedFilesPath = file.getAbsolutePath().replace("\\", "/"); + // 获取上一级目录 + String parentPath = normalizedFilesPath.substring(0, normalizedFilesPath.lastIndexOf("/")); + // 去掉 D:/yun 部分 + String finalPath = parentPath.replace(storageSourceConfigPath, ""); Files files = new Files(); files.setId(IdUtil.fastSimpleUUID()); files.setProjectId(id); files.setNodeId("00"); - files.setFileName(fileItem.getName()); - files.setFilePath(ensurePathFormat(fileItem.getPath())); - // 获取文件大小(字节) - long fileSizeInBytes = fileItem.getSize(); - // 转换为 MB 并保留两位小数 - double fileSizeInMB = fileSizeInBytes / (1024.0 * 1024.0); - String fileSizeFormatted = String.format("%.2f", fileSizeInMB); // 保留两位小数 - files.setFileSize(fileSizeFormatted); + files.setFileName(file.getName()); + files.setFilePath(ensurePathFormat(finalPath)); + files.setFileSize(String.valueOf(file.length())); files.setUploadTime(currentTime); - if (loginuser == null) { - files.setUploader(null); - } else { - files.setUploader(loginuser.getUsername()); - } - - filesList.add(files); + files.setUploader(uploader); + filesToCreate.add(files); } LOGGER.info("[构建文件列表] 耗时 {} ms | 待处理数量: {} 条", System.currentTimeMillis() - startBuildFiles, - filesList.size()); - - + filesToCreate.size()); // 批量插入文件表(忽略重复) - if (!filesList.isEmpty()) { + if (!filesToCreate.isEmpty()) { long startBatchInsertFiles = System.currentTimeMillis(); - int affectedRowsFiles = filesMapper.batchInsertFiles(filesList); + int affectedRowsFiles = filesMapper.batchInsertFiles(filesToCreate); LOGGER.info("[批量插入文件表] 耗时 {} ms | 实际新增数量: {} 条", System.currentTimeMillis() - startBatchInsertFiles, affectedRowsFiles); } - - - //修改文件表中的nodeId long costTimeFiles = System.currentTimeMillis(); int affectedLevelFilesRows = filesMapper.updateNodeIdByPathHierarchy(id); @@ -849,6 +807,32 @@ public class NodesServiceImpl extends ServiceImpl implements return "扫描完成"; } + private void getAllSubDirectories(File dir, List subDirs) { + File[] files = dir.listFiles(); + if (files != null) { + for (File file : files) { + if (file.isDirectory()) { + subDirs.add(file); + getAllSubDirectories(file, subDirs); + } + } + } + } + + + private void getAllFiles(File dir, List files) { + File[] fileList = dir.listFiles(); + if (fileList != null) { + for (File file : fileList) { + if (file.isFile()) { + files.add(file); + } else if (file.isDirectory()) { + getAllFiles(file, files); + } + } + } + } + /** * 确保路径格式为以 "/" 开头和结尾(例如 "/data/test/") diff --git a/java/src/main/resources/mapper/specialDocument/FilesMapper.xml b/java/src/main/resources/mapper/specialDocument/FilesMapper.xml index eff9cf7..ff8dff8 100644 --- a/java/src/main/resources/mapper/specialDocument/FilesMapper.xml +++ b/java/src/main/resources/mapper/specialDocument/FilesMapper.xml @@ -16,8 +16,7 @@ UPDATE sd_files a - LEFT JOIN sd_nodes b - ON b.project_id = a.project_id + LEFT JOIN sd_nodes b ON b.project_id = a.project_id AND a.file_path = CONCAT( b.custom3, b.node_name, '/' ) SET a.node_id = b.id WHERE