diff --git a/java/src/main/java/com/yfd/platform/modules/experimentalData/mapper/TsFilesMapper.java b/java/src/main/java/com/yfd/platform/modules/experimentalData/mapper/TsFilesMapper.java
index 58f858e..614ff68 100644
--- a/java/src/main/java/com/yfd/platform/modules/experimentalData/mapper/TsFilesMapper.java
+++ b/java/src/main/java/com/yfd/platform/modules/experimentalData/mapper/TsFilesMapper.java
@@ -2,6 +2,9 @@ package com.yfd.platform.modules.experimentalData.mapper;
import com.yfd.platform.modules.experimentalData.domain.TsFiles;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
/**
*
@@ -13,4 +16,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
*/
public interface TsFilesMapper extends BaseMapper {
+ int batchInsertTsFiles(List tsFilesToCreate);
+
+ int updateParentIdByPathHierarchy(@Param("taskId") String taskId, @Param("nodeId") String nodeId);
}
diff --git a/java/src/main/java/com/yfd/platform/modules/experimentalData/service/impl/TsNodesServiceImpl.java b/java/src/main/java/com/yfd/platform/modules/experimentalData/service/impl/TsNodesServiceImpl.java
index 2e00f2b..7f308c3 100644
--- a/java/src/main/java/com/yfd/platform/modules/experimentalData/service/impl/TsNodesServiceImpl.java
+++ b/java/src/main/java/com/yfd/platform/modules/experimentalData/service/impl/TsNodesServiceImpl.java
@@ -1,6 +1,7 @@
package com.yfd.platform.modules.experimentalData.service.impl;
import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
@@ -21,6 +22,8 @@ import com.yfd.platform.modules.specialDocument.domain.Files;
import com.yfd.platform.modules.specialDocument.domain.Nodes;
import com.yfd.platform.modules.specialDocument.domain.Project;
import com.yfd.platform.modules.storage.context.StorageSourceContext;
+import com.yfd.platform.modules.storage.mapper.StorageSourceConfigMapper;
+import com.yfd.platform.modules.storage.model.entity.StorageSourceConfig;
import com.yfd.platform.modules.storage.model.enums.FileTypeEnum;
import com.yfd.platform.modules.storage.model.request.BatchDeleteRequest;
import com.yfd.platform.modules.storage.model.request.NewFolderRequest;
@@ -30,6 +33,7 @@ import com.yfd.platform.modules.storage.service.base.AbstractBaseFileService;
import com.yfd.platform.system.domain.LoginUser;
import com.yfd.platform.utils.StringUtils;
import io.netty.channel.ChannelInboundHandlerAdapter;
+import lombok.val;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -86,6 +90,10 @@ public class TsNodesServiceImpl extends ServiceImpl impl
@Resource
private StorageSourceService storageSourceService;
+ @Resource
+ private StorageSourceConfigMapper storageSourceConfigMapper;
+
+
//顶级父节点 Top level parent node
public static final String TOP_LEVEL_PARENT_NODE = "00";
@@ -647,6 +655,21 @@ public class TsNodesServiceImpl extends ServiceImpl impl
TsTask tsTask = tsTaskMapper.selectById(id);
+ //文件的第一层是节点 下面的层级是文件夹
+
+
+
+
+
+
+
+
+
+
+
+
+
+
//获取文件列表
String absolutePath = "/" + tsTask.getTaskName() + "/";
FileListRequest fileListRequest = buildFileRequest(absolutePath);
@@ -664,16 +687,7 @@ public class TsNodesServiceImpl extends ServiceImpl impl
if (fileItemList.size() == 0) {
throw new Exception("该试验任务管理项目目录不存在或没有项目文档,请先建立项目目录和文档。");
}
-
-// //获取数据库父节点为0的数据 任务ID 上级节点时00
-// List tsNodes = tsNodesMapper.selectList(new LambdaQueryWrapper().eq(TsNodes::getParentId, "00").eq(TsNodes::getTaskId, id));
-//
-// // 步骤 1:提取现有的 nodeName
-// Set existingNodeNames = tsNodes.stream().map(TsNodes::getNodeName).collect(Collectors.toSet());
-//
-// // 步骤 2:筛选新增数据 找到需要新增到数据库的文件夹 这个属于第一层架
-// List fileItemNewList = fileItemList.stream().filter(fileItem -> !existingNodeNames.contains(fileItem.getName())).collect(Collectors.toList());
- firstLayerData(fileItemList, id);
+ firstLayerData(fileItemList, id);
return "扫描完成";
}
@@ -705,27 +719,6 @@ public class TsNodesServiceImpl extends ServiceImpl impl
}
}
-// else {
-// //获取节点名称
-// String nodeName = getLastPathSegment(item.getPath());
-// //获取节点信息 主要用到ID
-// QueryWrapper queryWrapper = new QueryWrapper<>();
-// queryWrapper.eq("node_name", nodeName);
-// queryWrapper.eq("parent_id", TOP_LEVEL_PARENT_NODE);
-// Nodes node = nodesMapper.selectOne(queryWrapper);
-//
-// //新增之前先查询
-// LambdaQueryWrapper queryWrapper1 = new LambdaQueryWrapper<>();
-// queryWrapper1.eq(Files::getProjectId, projectId);
-// queryWrapper1.eq(Files::getNodeId, node.getId());
-// queryWrapper1.eq(Files::getFilePath, item.getPath());
-// queryWrapper1.eq(Files::getFileName, item.getName());
-// Files files = filesMapper.selectOne(queryWrapper1);
-// if (files == null) {
-// //保存文件信息
-// saveFiles(projectId, node.getId(), item.getPath(), item.getName(), String.valueOf(item.getSize()));
-// }
-// }
}
}
@@ -739,62 +732,264 @@ public class TsNodesServiceImpl extends ServiceImpl impl
*/
private void otherLevelsData(String taskId, String nodeId, String nodeName, String path, String parentId) throws Exception {
- //通过节点的路径加名称 查询下面的文件及文件夹
- String absolutePath = path + nodeName + "/";
- //获取文件列表
- 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);
- //todo 首先获取两个集合 对比出数据库中没有的文件夹以及文件,递归增加
- List fileItemList = fileService.fileList(fileListRequest.getPath());
- for (FileItemResult item : fileItemList) {
- //思路就是 如果是文件夹 就查询一下 没有就新增, 新的的时候递归往下走
- if (item.getType() == FileTypeEnum.FOLDER) {
- //先查询有没有 如果没有就新增 条件 节点ID 任务ID 上级ID 工作空间路径 文件名称
- LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
- queryWrapper.eq(TsFiles::getTaskId, taskId);
- queryWrapper.eq(TsFiles::getNodeId, nodeId);
- queryWrapper.eq(TsFiles::getParentId, parentId);
- queryWrapper.eq(TsFiles::getFileName, item.getName());
- queryWrapper.eq(TsFiles::getWorkPath, item.getPath());
- TsFiles tsFiles = tsFilesMapper.selectOne(queryWrapper);
- //如果没有 新增 并且递归
- if (tsFiles == null) {
- //保存文件
- TsFiles tsFilesData = savetsFiles(taskId, nodeId, item.getName(), item.getPath(), parentId, "FOLDER", String.valueOf(item.getSize()));
- otherLevelsData(taskId, nodeId, item.getName(), item.getPath(), tsFilesData.getId());
+ // 存储所有目录和文件的列表
+ List tsFilesToCreate = new ArrayList<>();
- } else {
- otherLevelsData(taskId, nodeId, item.getName(), item.getPath(), tsFiles.getId());
- }
+ // 设置当前时间
+ LocalDateTime now = LocalDateTime.now();
+ // 转换为 Timestamp
+ Timestamp currentTime = Timestamp.valueOf(now);
+
+
+ // 查询本地文件路径根目录(如 E:\yun)
+ QueryWrapper queryWrapper = new QueryWrapper<>();
+ queryWrapper.eq("name", "filePath");
+ queryWrapper.eq("type", "local");
+ StorageSourceConfig storageSourceConfig = storageSourceConfigMapper.selectOne(queryWrapper);
+
+ //获取文件列表 这个地方path+name
+ File projectDir = new File(storageSourceConfig.getValue()+path+nodeName);
+
+ // 获取所有子目录
+ List allSubDirs = new ArrayList<>();
+ getAllSubDirectories(projectDir, allSubDirs);
+ String storageSourceConfigPath = storageSourceConfig.getValue().replace("\\", "/");
+ // 批量处理子目录
+ long startBuildNodes = System.currentTimeMillis();
+ for (File subDir : allSubDirs) {
+ String normalizedSubDirPath = subDir.getAbsolutePath().replace("\\", "/");
+ // 获取上一级目录
+ String parentPath = normalizedSubDirPath.substring(0, normalizedSubDirPath.lastIndexOf("/"));
+ // 去掉 D:/yun 部分
+ String finalPath = parentPath.replace(storageSourceConfigPath, "");
+ //保存文件信息
+ TsFiles tsFiles1 = new TsFiles();
+ //任务
+ tsFiles1.setTaskId(taskId);
+ //节点
+ tsFiles1.setNodeId(nodeId);
+ //文件 文件夹 区分
+ tsFiles1.setIsFile("FOLDER");
+ //上级ID
+ tsFiles1.setParentId("00");
+ //文件名称
+ tsFiles1.setFileName(subDir.getName());
+ //工作空间路径
+ tsFiles1.setWorkPath(ensurePathFormat(finalPath));
+ tsFiles1.setUploadTime(currentTime);
+
+
+ if ("null".equals(String.valueOf(subDir.length()))) {
+ tsFiles1.setFileSize("0.001");
} else {
- //todo 如果是文件 直接新增就可以了 不需要其他的操作
- //先查询有没有 如果没有就新增 条件 节点ID 任务ID 上级ID 工作空间路径 文件名称
- LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
- queryWrapper.eq(TsFiles::getTaskId, taskId);
- queryWrapper.eq(TsFiles::getNodeId, nodeId);
- queryWrapper.eq(TsFiles::getParentId, parentId);
- queryWrapper.eq(TsFiles::getFileName, item.getName());
- queryWrapper.eq(TsFiles::getWorkPath, item.getPath());
- TsFiles tsFiles = tsFilesMapper.selectOne(queryWrapper);
- if (tsFiles == null) {
+ //文件大小
+ if ("0.000".equals(String.valueOf(subDir.length()))) {
+ tsFiles1.setFileSize("0.001");
+ } else {
+ tsFiles1.setFileSize(String.valueOf(subDir.length()));
+ }
+ }
+ tsFilesToCreate.add(tsFiles1);
+ }
+ LOGGER.info("[构建文件表中的文件夹列表] 耗时 {} ms | 待处理数量: {} 条",
+ System.currentTimeMillis() - startBuildNodes,
+ tsFilesToCreate.size());
- // 获取文件大小(字节)
- long fileSizeInBytes = item.getSize();
- // 转换为 MB 并保留两位小数
- double fileSizeInMB = fileSizeInBytes / (1024.0 * 1024.0);
- String fileSizeFormatted = String.format("%.2f", fileSizeInMB); // 保留两位小数
- //保存文件信息
- TsFiles tsFilesData = savetsFiles(taskId, nodeId, item.getName(), item.getPath(), parentId, "FILE", fileSizeFormatted);
- LOGGER.info("保存文件信息:{}", item.getPath() + item.getName());
+ // 获取所有文件
+ List allFiles = new ArrayList<>();
+ getAllFiles(projectDir, allFiles);
+ System.out.println("allFiles=" + allFiles.size());
+ long startBuildFiles = System.currentTimeMillis();
+ // 批量处理文件
+ for (File file : allFiles) {
+ String normalizedFilesPath = file.getAbsolutePath().replace("\\", "/");
+ // 获取上一级目录
+ String parentPath = normalizedFilesPath.substring(0, normalizedFilesPath.lastIndexOf("/"));
+ // 去掉 D:/yun 部分
+ String finalPath = parentPath.replace(storageSourceConfigPath, "");
+ //保存文件信息
+ TsFiles tsFiles1 = new TsFiles();
+ tsFiles1.setId(IdUtil.fastSimpleUUID());
+ //任务
+ tsFiles1.setTaskId(taskId);
+ //节点
+ tsFiles1.setNodeId(nodeId);
+ //文件 文件夹 区分
+ tsFiles1.setIsFile("FILE");
+ //上级ID
+ tsFiles1.setParentId("00");
+ //文件名称
+ tsFiles1.setFileName(file.getName());
+ //工作空间路径
+ tsFiles1.setWorkPath(ensurePathFormat(finalPath));
+ tsFiles1.setUploadTime(currentTime);
+
+
+ if ("null".equals(String.valueOf(file.length()))) {
+ tsFiles1.setFileSize("0.001");
+ } else {
+ //文件大小
+ if ("0.000".equals(String.valueOf(file.length()))) {
+ tsFiles1.setFileSize("0.001");
+ } else {
+ tsFiles1.setFileSize(String.valueOf(file.length()));
+ }
+ }
+ tsFilesToCreate.add(tsFiles1);
+ }
+ LOGGER.info("[构建文件表中的文件列表] 耗时 {} ms | 待处理数量: {} 条",
+ System.currentTimeMillis() - startBuildFiles,
+ tsFilesToCreate.size());
+
+ // 批量插入文件表(忽略重复)
+ if (!tsFilesToCreate.isEmpty()) {
+ long startBatchInsertFiles = System.currentTimeMillis();
+ int affectedRowsFiles = tsFilesMapper.batchInsertTsFiles(tsFilesToCreate);
+ LOGGER.info("[批量插入试验任务文件表] 耗时 {} ms | 实际新增数量: {} 条",
+ System.currentTimeMillis() - startBatchInsertFiles,
+ affectedRowsFiles);
+ }
+
+ // 记录开始时间
+ long startTimeFiles = System.currentTimeMillis();
+ // 执行更新操作 taskId, String nodeId
+ int affectedLevelFilesRows = tsFilesMapper.updateParentIdByPathHierarchy(taskId,nodeId);
+ // 记录结束时间
+ long endTimeFiles = System.currentTimeMillis();
+ // 计算耗时
+ long costTimeFiles = endTimeFiles - startTimeFiles;
+ // 打印日志
+ LOGGER.info("文件表中的节点ID更新完成,影响 {} 行,总耗时 {} 毫秒", affectedLevelFilesRows, costTimeFiles);
+
+
+// //获取文件列表
+// String absolutePath =path + "/" + nodeName + "/";
+// //获取当前登录用户 上传人是当前登录人
+// UsernamePasswordAuthenticationToken authentication =
+// (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
+// LoginUser loginuser = null;
+// 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);
+//
+//
+//
+//
+//
+// //获取文件列表
+// 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);
+// //todo 首先获取两个集合 对比出数据库中没有的文件夹以及文件,递归增加
+// List fileItemList = fileService.fileList(fileListRequest.getPath());
+//
+// for (FileItemResult item : fileItemList) {
+// //思路就是 如果是文件夹 就查询一下 没有就新增, 新的的时候递归往下走
+// if (item.getType() == FileTypeEnum.FOLDER) {
+// //先查询有没有 如果没有就新增 条件 节点ID 任务ID 上级ID 工作空间路径 文件名称
+// LambdaQueryWrapper queryWrapper1 = new LambdaQueryWrapper<>();
+// queryWrapper1.eq(TsFiles::getTaskId, taskId);
+// queryWrapper1.eq(TsFiles::getNodeId, nodeId);
+// queryWrapper1.eq(TsFiles::getParentId, parentId);
+// queryWrapper1.eq(TsFiles::getFileName, item.getName());
+// queryWrapper1.eq(TsFiles::getWorkPath, item.getPath());
+// TsFiles tsFiles = tsFilesMapper.selectOne(queryWrapper1);
+// //如果没有 新增 并且递归
+// if (tsFiles == null) {
+// //保存文件
+// TsFiles tsFilesData = savetsFiles(taskId, nodeId, item.getName(), item.getPath(), parentId, "FOLDER", String.valueOf(item.getSize()));
+// otherLevelsData(taskId, nodeId, item.getName(), item.getPath(), tsFilesData.getId());
+//
+// } else {
+// otherLevelsData(taskId, nodeId, item.getName(), item.getPath(), tsFiles.getId());
+// }
+// } else {
+// //todo 如果是文件 直接新增就可以了 不需要其他的操作
+// //先查询有没有 如果没有就新增 条件 节点ID 任务ID 上级ID 工作空间路径 文件名称
+// LambdaQueryWrapper queryWrapper2 = new LambdaQueryWrapper<>();
+// queryWrapper2.eq(TsFiles::getTaskId, taskId);
+// queryWrapper2.eq(TsFiles::getNodeId, nodeId);
+// queryWrapper2.eq(TsFiles::getParentId, parentId);
+// queryWrapper2.eq(TsFiles::getFileName, item.getName());
+// queryWrapper2.eq(TsFiles::getWorkPath, item.getPath());
+// TsFiles tsFiles = tsFilesMapper.selectOne(queryWrapper2);
+// if (tsFiles == null) {
+//
+// // 获取文件大小(字节)
+// long fileSizeInBytes = item.getSize();
+// // 转换为 MB 并保留两位小数
+// double fileSizeInMB = fileSizeInBytes / (1024.0 * 1024.0);
+// String fileSizeFormatted = String.format("%.2f", fileSizeInMB); // 保留两位小数
+//
+// //保存文件信息
+// TsFiles tsFilesData = savetsFiles(taskId, nodeId, item.getName(), item.getPath(), parentId, "FILE", fileSizeFormatted);
+// LOGGER.info("保存文件信息:{}", item.getPath() + item.getName());
+// }
+// }
+// }
+ }
+
+ /**
+ * 确保路径格式为以 "/" 开头和结尾(例如 "/data/test/")
+ * 若路径为空或非法,返回根路径 "/"
+ */
+ private String ensurePathFormat(String path) {
+ if (StringUtils.isBlank(path)) {
+ return "/";
+ }
+ // 统一替换反斜杠为斜杠(兼容 Windows 路径)
+ String normalized = path.replaceAll("\\\\", "/");
+ // 去掉多余的斜杠
+ normalized = normalized.replaceAll("/{2,}", "/");
+ // 确保以 "/" 开头
+ if (!normalized.startsWith("/")) {
+ normalized = "/" + normalized;
+ }
+ // 确保以 "/" 结尾
+ if (!normalized.endsWith("/")) {
+ normalized += "/";
+ }
+ return normalized;
+ }
+
+ 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);
}
}
}
diff --git a/java/src/main/resources/mapper/experimentalData/TsFilesMapper.xml b/java/src/main/resources/mapper/experimentalData/TsFilesMapper.xml
index 95e280c..6442f45 100644
--- a/java/src/main/resources/mapper/experimentalData/TsFilesMapper.xml
+++ b/java/src/main/resources/mapper/experimentalData/TsFilesMapper.xml
@@ -2,4 +2,27 @@
+
+
+ INSERT INTO ts_files
+ (id,node_id, task_id, is_file, parent_id, file_name, file_size, work_path,upload_time)
+ VALUES
+
+ (#{item.id},#{item.nodeId}, #{item.taskId}, #{item.isFile}, #{item.parentId},
+ #{item.fileName}, #{item.fileSize}, #{item.workPath}, #{item.uploadTime})
+
+
+
+
+ UPDATE ts_files a
+ LEFT JOIN ts_files b
+ ON b.task_id = a.task_id
+ AND b.node_id = a.node_id
+ AND a.work_path = CONCAT( b.work_path, b.file_name, '/' )
+ SET a.parent_id = b.id
+ WHERE
+ b.task_id = #{taskId}
+ AND b.node_id = #{nodeId}
+
+