扫描结构更改提交
This commit is contained in:
parent
8e111b70d3
commit
f4937e4e45
@ -680,62 +680,7 @@ public class NodesServiceImpl extends ServiceImpl<NodesMapper, Nodes> implements
|
|||||||
StorageSourceConfig storageSourceConfig = storageSourceConfigMapper.selectOne(queryWrapper);
|
StorageSourceConfig storageSourceConfig = storageSourceConfigMapper.selectOne(queryWrapper);
|
||||||
|
|
||||||
//获取文件列表
|
//获取文件列表
|
||||||
String absolutePath = project.getProjectName() + "/";
|
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("该项目目录不存在或没有项目文档,请先建立项目目录和文档。");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//获取当前登录用户 上传人是当前登录人
|
//获取当前登录用户 上传人是当前登录人
|
||||||
UsernamePasswordAuthenticationToken authentication =
|
UsernamePasswordAuthenticationToken authentication =
|
||||||
(UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
|
(UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
|
||||||
@ -743,23 +688,40 @@ public class NodesServiceImpl extends ServiceImpl<NodesMapper, Nodes> implements
|
|||||||
if (authentication != null) {
|
if (authentication != null) {
|
||||||
loginuser = (LoginUser) authentication.getPrincipal();
|
loginuser = (LoginUser) authentication.getPrincipal();
|
||||||
}
|
}
|
||||||
|
//登录人
|
||||||
|
String uploader = null;
|
||||||
|
if (loginuser != null) {
|
||||||
|
uploader = loginuser.getUsername();
|
||||||
|
}
|
||||||
// 设置当前时间
|
// 设置当前时间
|
||||||
LocalDateTime now = LocalDateTime.now();
|
LocalDateTime now = LocalDateTime.now();
|
||||||
// 转换为 Timestamp
|
// 转换为 Timestamp
|
||||||
Timestamp currentTime = Timestamp.valueOf(now);
|
Timestamp currentTime = Timestamp.valueOf(now);
|
||||||
|
// 存储所有目录和文件的列表
|
||||||
|
List<Nodes> nodesToCreate = new ArrayList<>();
|
||||||
|
List<Files> filesToCreate = new ArrayList<>();
|
||||||
|
|
||||||
|
String path = storageSourceConfig.getValue() + "/" + absolutePath;
|
||||||
//处理文件夹新增到表结构
|
File projectDir = new File(path);
|
||||||
List<Nodes> nodesList = new ArrayList<>();
|
// 获取所有子目录
|
||||||
|
List<File> allSubDirs = new ArrayList<>();
|
||||||
|
getAllSubDirectories(projectDir, allSubDirs);
|
||||||
|
String storageSourceConfigPath = storageSourceConfig.getValue().replace("\\", "/");
|
||||||
|
// 批量处理子目录
|
||||||
long startBuildNodes = System.currentTimeMillis();
|
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 nodes = new Nodes();
|
||||||
nodes.setId(IdUtil.fastSimpleUUID());
|
nodes.setId(IdUtil.fastSimpleUUID());
|
||||||
nodes.setProjectId(id);
|
nodes.setProjectId(id);
|
||||||
nodes.setParentId("00");
|
nodes.setParentId("00");
|
||||||
nodes.setNodeOrder(1);
|
nodes.setNodeOrder(1);
|
||||||
// 1. 处理空路径,确保默认值
|
// 1. 处理空路径,确保默认值
|
||||||
String filePath = FolderItem.getPath() != null ? FolderItem.getPath() : "/";
|
String filePath = ensurePathFormat(finalPath);
|
||||||
// 2. 路径标准化处理:统一替换所有分隔符为 "/",并合并连续分隔符
|
// 2. 路径标准化处理:统一替换所有分隔符为 "/",并合并连续分隔符
|
||||||
String normalizedPath = filePath
|
String normalizedPath = filePath
|
||||||
.replaceAll("[/\\\\]+", "/") // 将 "\" 或混合分隔符统一为 "/"
|
.replaceAll("[/\\\\]+", "/") // 将 "\" 或混合分隔符统一为 "/"
|
||||||
@ -773,20 +735,25 @@ public class NodesServiceImpl extends ServiceImpl<NodesMapper, Nodes> implements
|
|||||||
// 5. 生成 nodeType(两位数字)
|
// 5. 生成 nodeType(两位数字)
|
||||||
String nodeType = String.format("%02d", depth);
|
String nodeType = String.format("%02d", depth);
|
||||||
nodes.setNodeType(nodeType);
|
nodes.setNodeType(nodeType);
|
||||||
nodes.setNodeName(FolderItem.getName());
|
nodes.setNodeName(subDir.getName());
|
||||||
nodes.setCustom3(ensurePathFormat(FolderItem.getPath()));
|
nodes.setCustom3(ensurePathFormat(finalPath));
|
||||||
nodes.setCreateTime(currentTime);
|
nodes.setCreateTime(currentTime);
|
||||||
nodesList.add(nodes);
|
nodesToCreate.add(nodes);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
LOGGER.info("[构建节点列表] 耗时 {} ms | 待处理数量: {} 条",
|
LOGGER.info("[构建节点列表] 耗时 {} ms | 待处理数量: {} 条",
|
||||||
System.currentTimeMillis() - startBuildNodes,
|
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();
|
long startBatchInsert = System.currentTimeMillis();
|
||||||
int affectedRows = nodesMapper.batchInsertIgnore(nodesList);
|
int affectedRows = nodesMapper.batchInsertIgnore(nodesToCreate);
|
||||||
LOGGER.info("[批量插入节点表] 耗时 {} ms | 实际新增数量: {} 条",
|
LOGGER.info("[批量插入节点表] 耗时 {} ms | 实际新增数量: {} 条",
|
||||||
System.currentTimeMillis() - startBatchInsert,
|
System.currentTimeMillis() - startBatchInsert,
|
||||||
affectedRows);
|
affectedRows);
|
||||||
@ -797,51 +764,42 @@ public class NodesServiceImpl extends ServiceImpl<NodesMapper, Nodes> implements
|
|||||||
int affectedLevelRows = nodesMapper.updateParentIdByPathHierarchy();
|
int affectedLevelRows = nodesMapper.updateParentIdByPathHierarchy();
|
||||||
LOGGER.info("层级关系更新完成,影响 {} 行,总耗时 {} 毫秒", affectedLevelRows, costTime);
|
LOGGER.info("层级关系更新完成,影响 {} 行,总耗时 {} 毫秒", affectedLevelRows, costTime);
|
||||||
|
|
||||||
|
|
||||||
//接下来就是新增文件表 新增成功以后 通过路径获取节点表中的 custom3+路径 就是node ID
|
//接下来就是新增文件表 新增成功以后 通过路径获取节点表中的 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();
|
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 files = new Files();
|
||||||
files.setId(IdUtil.fastSimpleUUID());
|
files.setId(IdUtil.fastSimpleUUID());
|
||||||
files.setProjectId(id);
|
files.setProjectId(id);
|
||||||
files.setNodeId("00");
|
files.setNodeId("00");
|
||||||
files.setFileName(fileItem.getName());
|
files.setFileName(file.getName());
|
||||||
files.setFilePath(ensurePathFormat(fileItem.getPath()));
|
files.setFilePath(ensurePathFormat(finalPath));
|
||||||
// 获取文件大小(字节)
|
files.setFileSize(String.valueOf(file.length()));
|
||||||
long fileSizeInBytes = fileItem.getSize();
|
|
||||||
// 转换为 MB 并保留两位小数
|
|
||||||
double fileSizeInMB = fileSizeInBytes / (1024.0 * 1024.0);
|
|
||||||
String fileSizeFormatted = String.format("%.2f", fileSizeInMB); // 保留两位小数
|
|
||||||
files.setFileSize(fileSizeFormatted);
|
|
||||||
files.setUploadTime(currentTime);
|
files.setUploadTime(currentTime);
|
||||||
if (loginuser == null) {
|
files.setUploader(uploader);
|
||||||
files.setUploader(null);
|
filesToCreate.add(files);
|
||||||
} else {
|
|
||||||
files.setUploader(loginuser.getUsername());
|
|
||||||
}
|
|
||||||
|
|
||||||
filesList.add(files);
|
|
||||||
}
|
}
|
||||||
LOGGER.info("[构建文件列表] 耗时 {} ms | 待处理数量: {} 条",
|
LOGGER.info("[构建文件列表] 耗时 {} ms | 待处理数量: {} 条",
|
||||||
System.currentTimeMillis() - startBuildFiles,
|
System.currentTimeMillis() - startBuildFiles,
|
||||||
filesList.size());
|
filesToCreate.size());
|
||||||
|
|
||||||
|
|
||||||
// 批量插入文件表(忽略重复)
|
// 批量插入文件表(忽略重复)
|
||||||
if (!filesList.isEmpty()) {
|
if (!filesToCreate.isEmpty()) {
|
||||||
long startBatchInsertFiles = System.currentTimeMillis();
|
long startBatchInsertFiles = System.currentTimeMillis();
|
||||||
int affectedRowsFiles = filesMapper.batchInsertFiles(filesList);
|
int affectedRowsFiles = filesMapper.batchInsertFiles(filesToCreate);
|
||||||
LOGGER.info("[批量插入文件表] 耗时 {} ms | 实际新增数量: {} 条",
|
LOGGER.info("[批量插入文件表] 耗时 {} ms | 实际新增数量: {} 条",
|
||||||
System.currentTimeMillis() - startBatchInsertFiles,
|
System.currentTimeMillis() - startBatchInsertFiles,
|
||||||
affectedRowsFiles);
|
affectedRowsFiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//修改文件表中的nodeId
|
//修改文件表中的nodeId
|
||||||
long costTimeFiles = System.currentTimeMillis();
|
long costTimeFiles = System.currentTimeMillis();
|
||||||
int affectedLevelFilesRows = filesMapper.updateNodeIdByPathHierarchy(id);
|
int affectedLevelFilesRows = filesMapper.updateNodeIdByPathHierarchy(id);
|
||||||
@ -849,6 +807,32 @@ public class NodesServiceImpl extends ServiceImpl<NodesMapper, Nodes> implements
|
|||||||
|
|
||||||
return "扫描完成";
|
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/")
|
* 确保路径格式为以 "/" 开头和结尾(例如 "/data/test/")
|
||||||
|
@ -16,8 +16,7 @@
|
|||||||
|
|
||||||
<update id="updateNodeIdByPathHierarchy">
|
<update id="updateNodeIdByPathHierarchy">
|
||||||
UPDATE sd_files a
|
UPDATE sd_files a
|
||||||
LEFT JOIN sd_nodes b
|
LEFT JOIN sd_nodes b ON b.project_id = a.project_id
|
||||||
ON b.project_id = a.project_id
|
|
||||||
AND a.file_path = CONCAT( b.custom3, b.node_name, '/' )
|
AND a.file_path = CONCAT( b.custom3, b.node_name, '/' )
|
||||||
SET a.node_id = b.id
|
SET a.node_id = b.id
|
||||||
WHERE
|
WHERE
|
||||||
|
Loading…
Reference in New Issue
Block a user