提交代码
This commit is contained in:
parent
2939613be8
commit
0499b55011
@ -375,6 +375,26 @@ public class TsFilesController {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**********************************
|
||||||
|
* 用途说明: 查询本地和备份空间结构树
|
||||||
|
* 参数说明 taskId 节点ID
|
||||||
|
* 参数说明 nodeId 任务ID
|
||||||
|
* 返回值说明: com.yfd.platform.config.ResponseResult 返回双树数据
|
||||||
|
***********************************/
|
||||||
|
@Log(module = "实验数据管理", value = "查询本地和备份空间结构树!")
|
||||||
|
@PostMapping("/listLocalAndBackup")
|
||||||
|
@ApiOperation("查询本地和备份空间结构树")
|
||||||
|
public ResponseResult listLocalAndBackup(String taskId, String nodeId) {
|
||||||
|
|
||||||
|
|
||||||
|
if (StrUtil.isBlank(taskId) && StrUtil.isBlank(nodeId)) {
|
||||||
|
return ResponseResult.error("参数为空");
|
||||||
|
}
|
||||||
|
//查询本地树和minio树
|
||||||
|
DualTreeResponse response = tsFilesService.listLocalAndBackup(taskId, nodeId);
|
||||||
|
return ResponseResult.successData(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**********************************
|
/**********************************
|
||||||
* 用途说明: 查询本地结构树
|
* 用途说明: 查询本地结构树
|
||||||
|
@ -207,4 +207,12 @@ public interface ITsFilesService extends IService<TsFiles> {
|
|||||||
* 返回值说明: com.yfd.platform.config.ResponseResult 返回双树数据
|
* 返回值说明: com.yfd.platform.config.ResponseResult 返回双树数据
|
||||||
***********************************/
|
***********************************/
|
||||||
DualTreeResponse listBackupTree(String taskId, String nodeId, String id);
|
DualTreeResponse listBackupTree(String taskId, String nodeId, String id);
|
||||||
|
|
||||||
|
/**********************************
|
||||||
|
* 用途说明: 查询本地和备份空间结构树
|
||||||
|
* 参数说明 taskId 节点ID
|
||||||
|
* 参数说明 nodeId 任务ID
|
||||||
|
* 返回值说明: com.yfd.platform.config.ResponseResult 返回双树数据
|
||||||
|
***********************************/
|
||||||
|
DualTreeResponse listLocalAndBackup(String taskId, String nodeId);
|
||||||
}
|
}
|
||||||
|
@ -2234,24 +2234,43 @@ public class TsFilesServiceImpl extends ServiceImpl<TsFilesMapper, TsFiles> impl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 保留Unix权限
|
// 保留Unix权限(仅在非Windows系统生效)
|
||||||
if (!System.getProperty("os.name").toLowerCase().contains("win")) {
|
if (!System.getProperty("os.name").toLowerCase().contains("win")) {
|
||||||
Files.setPosixFilePermissions(targetPath,
|
try {
|
||||||
PosixFilePermissions.fromString(getPosixMode(entry.getMode())));
|
Files.setPosixFilePermissions(
|
||||||
|
targetPath,
|
||||||
|
PosixFilePermissions.fromString(getPosixMode(entry.getMode()))
|
||||||
|
);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
// 捕获非法权限格式异常,避免进程终止
|
||||||
|
System.err.println("警告: 无法设置权限 [" + entry.getMode() + "] 文件: " + targetPath);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return destRoot.toFile();
|
return destRoot.toFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 转换Unix权限位
|
/**
|
||||||
|
* 将TAR文件条目的权限位转换为POSIX格式字符串
|
||||||
|
* (修正1:移除空格,修正2:屏蔽高位)
|
||||||
|
*/
|
||||||
private String getPosixMode(int mode) {
|
private String getPosixMode(int mode) {
|
||||||
return String.format("%s%s%s %s%s%s %s%s%s",
|
// 仅保留低9位权限信息(用户/组/其他)
|
||||||
(mode & 0400) != 0 ? "r" : "-", (mode & 0200) != 0 ? "w" : "-", (mode & 0100) != 0 ? "x" : "-",
|
mode &= 0777;
|
||||||
(mode & 0040) != 0 ? "r" : "-", (mode & 0020) != 0 ? "w" : "-", (mode & 0010) != 0 ? "x" : "-",
|
return String.format("%s%s%s%s%s%s%s%s%s",
|
||||||
(mode & 0004) != 0 ? "r" : "-", (mode & 0002) != 0 ? "w" : "-", (mode & 0001) != 0 ? "x" : "-");
|
(mode & 0400) != 0 ? "r" : "-", // 用户读
|
||||||
|
(mode & 0200) != 0 ? "w" : "-", // 用户写
|
||||||
|
(mode & 0100) != 0 ? "x" : "-", // 用户执行
|
||||||
|
(mode & 0040) != 0 ? "r" : "-", // 组读
|
||||||
|
(mode & 0020) != 0 ? "w" : "-", // 组写
|
||||||
|
(mode & 0010) != 0 ? "x" : "-", // 组执行
|
||||||
|
(mode & 0004) != 0 ? "r" : "-", // 其他读
|
||||||
|
(mode & 0002) != 0 ? "w" : "-", // 其他写
|
||||||
|
(mode & 0001) != 0 ? "x" : "-"); // 其他执行
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 验证目标路径安全性(防止路径穿越攻击)
|
* 验证目标路径安全性(防止路径穿越攻击)
|
||||||
*/
|
*/
|
||||||
@ -4284,6 +4303,59 @@ public class TsFilesServiceImpl extends ServiceImpl<TsFilesMapper, TsFiles> impl
|
|||||||
// return new DualTreeResponse(localTrees, minioTrees);
|
// return new DualTreeResponse(localTrees, minioTrees);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
/**********************************
|
||||||
|
* 用途说明: 查询本地和备份空间结构树
|
||||||
|
* 参数说明 taskId 节点ID
|
||||||
|
* 参数说明 nodeId 任务ID
|
||||||
|
* 返回值说明: com.yfd.platform.config.ResponseResult 返回双树数据
|
||||||
|
***********************************/
|
||||||
|
@Override
|
||||||
|
public DualTreeResponse listLocalAndBackup(String taskId, String nodeId) {
|
||||||
|
// 记录方法入参
|
||||||
|
LOGGER.info("Starting to build dual trees for taskId={}, nodeId={}", taskId, nodeId);
|
||||||
|
// 1. 批量查询所有相关节点
|
||||||
|
QueryWrapper<TsFiles> queryWrapper = new QueryWrapper<>();
|
||||||
|
queryWrapper.eq("task_id", taskId)
|
||||||
|
.eq("node_id", nodeId);
|
||||||
|
List<TsFiles> allNodes = tsFilesMapper.selectList(queryWrapper);
|
||||||
|
|
||||||
|
// 2. 构建内存索引提升查询效率
|
||||||
|
Map<String, List<TsFiles>> parentChildrenMap = allNodes.stream()
|
||||||
|
.collect(Collectors.groupingBy(TsFiles::getParentId));
|
||||||
|
LOGGER.debug("使用{}个条目构建父子映射", parentChildrenMap.size());
|
||||||
|
|
||||||
|
// 3. 双树构建容器
|
||||||
|
List<TreeDTO> localTrees = new ArrayList<>();
|
||||||
|
List<TreeDTO> minioTrees = new ArrayList<>();
|
||||||
|
|
||||||
|
// 4. 从顶级节点(parentId为00)开始构建树
|
||||||
|
List<TsFiles> rootNodes = parentChildrenMap.get("00");
|
||||||
|
if (rootNodes == null || rootNodes.isEmpty()) {
|
||||||
|
LOGGER.warn("找不到的根节点 taskId={}, nodeId={}", taskId, nodeId);
|
||||||
|
return new DualTreeResponse(localTrees, minioTrees);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rootNodes != null) {
|
||||||
|
for (TsFiles rootNode : rootNodes) {
|
||||||
|
// 构建本地树
|
||||||
|
TreeDTO localTree = buildTree(rootNode, parentChildrenMap, true);
|
||||||
|
if (localTree != null) {
|
||||||
|
localTrees.add(localTree);
|
||||||
|
LOGGER.debug("添加了本地树节点: {}", localTree.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构建Minio树
|
||||||
|
TreeDTO minioTree = buildTree(rootNode, parentChildrenMap, false);
|
||||||
|
if (minioTree != null) {
|
||||||
|
minioTrees.add(minioTree);
|
||||||
|
LOGGER.debug("添加了MINIO树节点: {}", minioTree.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LOGGER.info("Tree construction completed. Local nodes: {}, MinIO nodes: {}", localTrees.size(), minioTrees.size());
|
||||||
|
return new DualTreeResponse(localTrees, minioTrees);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 递归构建树形结构(内存操作,不再查询数据库)
|
* 递归构建树形结构(内存操作,不再查询数据库)
|
||||||
*
|
*
|
||||||
|
Loading…
Reference in New Issue
Block a user