扫描结构更改提交

This commit is contained in:
lilin 2025-05-26 18:02:02 +08:00
parent 8e111b70d3
commit f4937e4e45
2 changed files with 81 additions and 98 deletions

View File

@ -680,62 +680,7 @@ public class NodesServiceImpl extends ServiceImpl<NodesMapper, Nodes> 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<FileItemResult> 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<File> allContents = FileUtil.loopFiles(path, file -> true);
LOGGER.info("[allContents] 耗时 {} ms | 数据量: {} 条",
System.currentTimeMillis() - startHutoolFileListData,
allContents.size());
// 过滤文件夹添加第二个耗时日志
long startFilterFolders = System.currentTimeMillis();
List<FileItemResult> 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<FileItemResult> 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<FileItemResult> 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<NodesMapper, Nodes> 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<Nodes> nodesToCreate = new ArrayList<>();
List<Files> filesToCreate = new ArrayList<>();
//处理文件夹新增到表结构
List<Nodes> nodesList = new ArrayList<>();
String path = storageSourceConfig.getValue() + "/" + absolutePath;
File projectDir = new File(path);
// 获取所有子目录
List<File> 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<NodesMapper, Nodes> 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<NodesMapper, Nodes> implements
int affectedLevelRows = nodesMapper.updateParentIdByPathHierarchy();
LOGGER.info("层级关系更新完成,影响 {} 行,总耗时 {} 毫秒", affectedLevelRows, costTime);
//接下来就是新增文件表 新增成功以后 通过路径获取节点表中的 custom3+路径 就是node ID
// 获取所有文件
List<File> allFiles = new ArrayList<>();
getAllFiles(projectDir, allFiles);
System.out.println("allFiles=" + allFiles.size());
//处理文件夹新增到表结构
List<Files> 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<NodesMapper, Nodes> implements
return "扫描完成";
}
private void getAllSubDirectories(File dir, List<File> 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<File> 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/"

View File

@ -16,8 +16,7 @@
<update id="updateNodeIdByPathHierarchy">
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