提交代码更新0311
This commit is contained in:
parent
9dccf3c4f9
commit
104572a40a
@ -64,7 +64,10 @@ public class TsFilesController {
|
||||
|
||||
/**********************************
|
||||
* 用途说明: 查询实验数据管理文件夹
|
||||
* 参数说明
|
||||
* 参数说明 id 父级ID
|
||||
* 参数说明 path 路径
|
||||
* 参数说明nodeId 节点ID
|
||||
* 参数说明taskId 任务ID
|
||||
* pageNum 当前页
|
||||
* 返回值说明: com.yfd.platform.config.ResponseResult 返回分页查询结果
|
||||
***********************************/
|
||||
@ -72,9 +75,9 @@ public class TsFilesController {
|
||||
@GetMapping("/listTsFiles")
|
||||
@ApiOperation("查询实验数据管理文件夹")
|
||||
@PreAuthorize("@el.check('select:tsfiles')")
|
||||
public ResponseResult getsListTsFiles(String id, String path) throws Exception {
|
||||
public ResponseResult getsListTsFiles(String id, String path,String nodeId,String taskId) throws Exception {
|
||||
//分页查询
|
||||
List<TsFiles> tsfiles = tsFilesService.getsListTsFiles(id, path);
|
||||
List<TsFiles> tsfiles = tsFilesService.getsListTsFiles(id, path,nodeId,taskId);
|
||||
return ResponseResult.successData(tsfiles);
|
||||
}
|
||||
|
||||
@ -94,12 +97,9 @@ public class TsFilesController {
|
||||
if (ObjUtil.isEmpty(tsFiles)) {
|
||||
return ResponseResult.error("参数为空");
|
||||
}
|
||||
Boolean isOk = tsFilesService.addTsFiles(tsFiles);
|
||||
if (isOk) {
|
||||
return ResponseResult.success();
|
||||
} else {
|
||||
return ResponseResult.error();
|
||||
}
|
||||
|
||||
return tsFilesService.addTsFiles(tsFiles);
|
||||
|
||||
}
|
||||
|
||||
/***********************************
|
||||
@ -303,19 +303,19 @@ public class TsFilesController {
|
||||
/**
|
||||
* 对比两个目录的文件差异
|
||||
*
|
||||
* @param ids 勾选的所有数据ID集合
|
||||
* @param id 勾选的所有数据ID集合
|
||||
* @return 文件差异列表
|
||||
*/
|
||||
@Log(module = "实验数据管理", value = "对比本地和minio的文件差异!")
|
||||
@PostMapping("/compare")
|
||||
@ApiOperation("对比两个目录的文件差异")
|
||||
public ResponseResult compareDirectories( String ids, String nodeId, String taskId) {
|
||||
public ResponseResult compareDirectories( String id, String nodeId, String taskId) {
|
||||
|
||||
|
||||
try {
|
||||
List<String> dataset = new ArrayList<>();
|
||||
if (StrUtil.isNotEmpty(ids)) {
|
||||
String[] splitIds = ids.split(",");
|
||||
if (StrUtil.isNotEmpty(id)) {
|
||||
String[] splitIds = id.split(",");
|
||||
// 数组转集合
|
||||
dataset = Arrays.asList(splitIds);
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ public interface ITsFilesService extends IService<TsFiles> {
|
||||
* TsFiles 文档内容
|
||||
* 返回值说明: com.yfd.platform.config.ResponseResult 返回新增成功或者失败
|
||||
***********************************/
|
||||
Boolean addTsFiles(TsFiles tsFiles);
|
||||
ResponseResult addTsFiles(TsFiles tsFiles);
|
||||
|
||||
/**********************************
|
||||
* 用途说明: 修改试验数据管理-文档内容
|
||||
@ -117,7 +117,7 @@ public interface ITsFilesService extends IService<TsFiles> {
|
||||
* pageNum 当前页
|
||||
* 返回值说明: com.yfd.platform.config.ResponseResult 返回分页查询结果
|
||||
***********************************/
|
||||
List<TsFiles> getsListTsFiles(String id,String path);
|
||||
List<TsFiles> getsListTsFiles(String id,String path,String nodeId,String taskId);
|
||||
|
||||
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -8,6 +8,7 @@ import com.yfd.platform.modules.experimentalData.domain.TsFiles;
|
||||
import com.yfd.platform.modules.experimentalData.domain.TsNodes;
|
||||
import com.yfd.platform.modules.experimentalData.mapper.TsFilesMapper;
|
||||
import com.yfd.platform.modules.experimentalData.mapper.TsNodesMapper;
|
||||
import com.yfd.platform.modules.experimentalData.service.ITsFilesService;
|
||||
import com.yfd.platform.modules.experimentalData.service.ITsNodesService;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.yfd.platform.modules.specialDocument.domain.Nodes;
|
||||
@ -34,6 +35,7 @@ import javax.annotation.Resource;
|
||||
import java.sql.Timestamp;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@ -56,6 +58,11 @@ public class TsNodesServiceImpl extends ServiceImpl<TsNodesMapper, TsNodes> impl
|
||||
@Resource
|
||||
private TsFilesMapper tsFilesMapper;
|
||||
|
||||
//实验任务文档表
|
||||
@Resource
|
||||
private ITsFilesService tsFilesService;
|
||||
|
||||
|
||||
//数据源Mapper
|
||||
@Resource
|
||||
private StorageSourceMapper storageSourceMapper;
|
||||
@ -218,7 +225,6 @@ public class TsNodesServiceImpl extends ServiceImpl<TsNodesMapper, TsNodes> impl
|
||||
result.add(nodeWithChildren); // 将当前节点加入结果列表
|
||||
}
|
||||
}
|
||||
|
||||
// 如果当前节点符合条件且没有被添加到result,则将其添加
|
||||
if (currentNode.get("nodeName") instanceof String && ((String) currentNode.get("nodeName")).contains(nodeName) && result.isEmpty()) {
|
||||
result.add(currentNode); // 将当前节点添加到结果列表
|
||||
@ -226,31 +232,6 @@ public class TsNodesServiceImpl extends ServiceImpl<TsNodesMapper, TsNodes> impl
|
||||
|
||||
// 返回包含所有符合条件的树结构的列表
|
||||
return result;
|
||||
|
||||
// // 如果当前节点是目标节点,返回当前节点
|
||||
// if (currentNode.get("nodeName") instanceof String &&((String) currentNode.get("nodeName")).contains(nodeName)) {
|
||||
// return Collections.singletonList(currentNode);
|
||||
// }
|
||||
//// if (nodeName.equals(currentNode.get("nodeName"))) {
|
||||
//// return Collections.singletonList(currentNode);
|
||||
//// }
|
||||
//
|
||||
// // 查找当前节点的所有子节点
|
||||
// List<Map<String, Object>> children = findChildren(allNodes, currentNode.get("nodeId").toString());
|
||||
//
|
||||
// // 递归查找目标节点
|
||||
// for (Map<String, Object> child : children) {
|
||||
// List<Map<String, Object>> childTree = buildTreeToTargetNode(child, allNodes, nodeName);
|
||||
// if (!childTree.isEmpty()) {
|
||||
// // 如果找到目标节点,将当前节点加入树中
|
||||
// Map<String, Object> nodeWithChildren = new HashMap<>(currentNode);
|
||||
// nodeWithChildren.put("children", childTree);
|
||||
// return Collections.singletonList(nodeWithChildren);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // 如果未找到目标节点,返回空列表
|
||||
// return new ArrayList<>();
|
||||
}
|
||||
|
||||
|
||||
@ -291,56 +272,15 @@ public class TsNodesServiceImpl extends ServiceImpl<TsNodesMapper, TsNodes> impl
|
||||
}
|
||||
//序号
|
||||
tsnodes.setNodeOrder(orderno);
|
||||
//查询数据源
|
||||
List<StorageSource> storageSources = storageSourceMapper.findAllOrderByOrderNum();
|
||||
|
||||
// 获取路径
|
||||
List<String> pathNodes = new ArrayList<>();
|
||||
TsNodes nodesData = tsNodesMapper.selectById(tsnodes.getParentId());
|
||||
// 从当前节点向上遍历,直到根节点
|
||||
while (nodesData != null) {
|
||||
pathNodes.add(nodesData.getNodeName());
|
||||
// 如果父节点是 "00",说明已经到了根节点,停止遍历
|
||||
if ("00".equals(nodesData.getParentId())) {
|
||||
break;
|
||||
}
|
||||
// 获取父节点
|
||||
nodesData = tsNodesMapper.selectById(nodesData.getParentId()); // 修正:从 nodesData 中获取 parentId
|
||||
}
|
||||
// 反转路径,使其从根节点到当前节点
|
||||
Collections.reverse(pathNodes);
|
||||
String path = "/" + String.join("/", pathNodes);
|
||||
|
||||
//判断 local或者minio有没有成功
|
||||
List<Boolean> results = new ArrayList<>();
|
||||
for (StorageSource storageSource : storageSources) {
|
||||
//新增节点的时候 创建文件夹
|
||||
NewFolderRequest newFolderRequest = new NewFolderRequest();
|
||||
newFolderRequest.setName(tsnodes.getNodeName());//新建的文件夹名称,示例值(/a/b/c)
|
||||
newFolderRequest.setPassword("");//文件夹密码, 如果文件夹需要密码才能访问,则支持请求密码,示例值(123456)
|
||||
newFolderRequest.setPath(path);//请求路径,示例值(/)
|
||||
newFolderRequest.setStorageKey(storageSource.getType().toString());//存储源 key,示例值(local minio)
|
||||
AbstractBaseFileService<?> fileService = storageSourceContext.getByStorageKey(newFolderRequest.getStorageKey());
|
||||
boolean flag = fileService.newFolder(newFolderRequest.getPath(), newFolderRequest.getName());
|
||||
results.add(flag);
|
||||
}
|
||||
// 使用Java 8的Stream API检查列表中是否包含true
|
||||
boolean hasTrue = results.stream().anyMatch(Boolean::booleanValue);
|
||||
//如果是true 说明至少有一个生成了文件夹 下一步建立表数据
|
||||
if (hasTrue) {
|
||||
int valueAdded = tsNodesMapper.insert(tsnodes);
|
||||
if (valueAdded == 1) {
|
||||
LOGGER.info("local和minio新增成功,表结构增加成功");
|
||||
LOGGER.info("tsnodes表结构增加成功");
|
||||
return ResponseResult.success();
|
||||
} else {
|
||||
LOGGER.error("local和minio新增成功,表结构增加失败");
|
||||
LOGGER.error("tsnodes表结构增加失败");
|
||||
return ResponseResult.error();
|
||||
}
|
||||
|
||||
} else {
|
||||
LOGGER.error("local和minio新增失败");
|
||||
return ResponseResult.error();
|
||||
}
|
||||
}
|
||||
|
||||
/**********************************
|
||||
@ -376,56 +316,12 @@ public class TsNodesServiceImpl extends ServiceImpl<TsNodesMapper, TsNodes> impl
|
||||
if (count > 0) {
|
||||
return ResponseResult.error("节点名称已存在!");
|
||||
}
|
||||
|
||||
//查询数据源
|
||||
List<StorageSource> storageSources = storageSourceMapper.findAllOrderByOrderNum();
|
||||
|
||||
List<String> pathNodes = new ArrayList<>();
|
||||
TsNodes nodesData = tsNodesMapper.selectById(tsnodes.getParentId());
|
||||
// 从当前节点向上遍历,直到根节点
|
||||
while (nodesData != null) {
|
||||
pathNodes.add(nodesData.getNodeName());
|
||||
// 如果父节点是 "00",说明已经到了根节点,停止遍历
|
||||
if ("00".equals(nodesData.getParentId())) {
|
||||
break;
|
||||
}
|
||||
// 获取父节点
|
||||
nodesData = tsNodesMapper.selectById(nodesData.getParentId()); // 修正:从 nodesData 中获取 parentId
|
||||
}
|
||||
// 反转路径,使其从根节点到当前节点
|
||||
Collections.reverse(pathNodes);
|
||||
String path = String.join("/", pathNodes);
|
||||
|
||||
//判断 local或者minio有没有成功
|
||||
List<Boolean> results = new ArrayList<>();
|
||||
for (StorageSource storageSource : storageSources) {
|
||||
//修改文件夹名称
|
||||
RenameFolderRequest renameFolderRequest = new RenameFolderRequest();
|
||||
renameFolderRequest.setName(nodeNameOld);//重命名的原文件夹名称,示例值(movie)
|
||||
renameFolderRequest.setNewName(nodeName);// 重命名后的文件名称,示例值(music)
|
||||
renameFolderRequest.setPassword("");//文件夹密码, 如果文件夹需要密码才能访问,则支持请求密码,示例值(123456)
|
||||
renameFolderRequest.setPath(path);//请求路径,示例值(/)
|
||||
renameFolderRequest.setStorageKey(storageSource.getType().toString());//存储源 key,示例值(local minio)
|
||||
AbstractBaseFileService<?> fileService = storageSourceContext.getByStorageKey(renameFolderRequest.getStorageKey());
|
||||
boolean flag = fileService.renameFolder(renameFolderRequest.getPath(), renameFolderRequest.getName(), renameFolderRequest.getNewName());
|
||||
results.add(flag);
|
||||
}
|
||||
|
||||
// 使用Java 8的Stream API检查列表中是否包含true
|
||||
boolean hasTrue = results.stream().anyMatch(Boolean::booleanValue);
|
||||
//如果是true 说明至少有一个生成了文件夹 下一步建立表数据
|
||||
if (hasTrue) {
|
||||
int valueAdded = tsNodesMapper.updateById(tsnodes);
|
||||
if (valueAdded == 1) {
|
||||
LOGGER.info("local和minio修改成功,表结构增加成功");
|
||||
LOGGER.info("tsnodes表结构修改成功");
|
||||
return ResponseResult.success();
|
||||
} else {
|
||||
LOGGER.error("local和minio修改成功,表结构增加失败");
|
||||
return ResponseResult.error();
|
||||
}
|
||||
|
||||
} else {
|
||||
LOGGER.error("local和minio修改失败");
|
||||
LOGGER.error("tsnodes表结构修改失败");
|
||||
return ResponseResult.error();
|
||||
}
|
||||
}
|
||||
@ -437,105 +333,37 @@ public class TsNodesServiceImpl extends ServiceImpl<TsNodesMapper, TsNodes> impl
|
||||
***********************************/
|
||||
@Override
|
||||
public boolean deleteTsNodesById(String id) {
|
||||
|
||||
|
||||
// try {
|
||||
|
||||
//根据ID 查询当前数据
|
||||
TsNodes tsNodes = tsNodesMapper.selectById(id);
|
||||
//删除之前 先拼路径 然后删除本地和minio的文件夹 最后删除表结构
|
||||
// 删除当前节点
|
||||
int deleteCount = tsNodesMapper.deleteById(id);
|
||||
//删除当前节点的 文件
|
||||
QueryWrapper<TsFiles> queryWrapper1 = new QueryWrapper<>();
|
||||
queryWrapper1.eq("node_id", tsNodes.getNodeId());
|
||||
queryWrapper1.eq("task_id", tsNodes.getTaskId());
|
||||
tsFilesMapper.delete(queryWrapper1);
|
||||
List<TsFiles> tsFiles = tsFilesMapper.selectList(queryWrapper1);
|
||||
|
||||
|
||||
List<String> pathNodes = new ArrayList<>();
|
||||
TsNodes nodesData = tsNodesMapper.selectById(tsNodes.getParentId());
|
||||
// 从当前节点向上遍历,直到根节点
|
||||
while (nodesData != null) {
|
||||
pathNodes.add(nodesData.getNodeName());
|
||||
// 如果父节点是 "00",说明已经到了根节点,停止遍历
|
||||
if ("00".equals(nodesData.getParentId())) {
|
||||
break;
|
||||
List<String> dataset = new ArrayList<>();
|
||||
if (tsFiles != null && !tsFiles.isEmpty()) {
|
||||
dataset = tsFiles.stream()
|
||||
.map(TsFiles::getId) // 假设 TsFiles 类中有 getId() 方法
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
// 获取父节点
|
||||
nodesData = tsNodesMapper.selectById(nodesData.getParentId()); // 修正:从 nodesData 中获取 parentId
|
||||
}
|
||||
// 反转路径,使其从根节点到当前节点
|
||||
Collections.reverse(pathNodes);
|
||||
String path = String.join("/", pathNodes);
|
||||
|
||||
List<BatchDeleteRequest.DeleteItem> deleteItemList = new ArrayList<>();
|
||||
BatchDeleteRequest.DeleteItem deleteItemData = new BatchDeleteRequest.DeleteItem();
|
||||
deleteItemData.setName(tsNodes.getNodeName());
|
||||
deleteItemData.setPassword("");
|
||||
deleteItemData.setPath(path);
|
||||
deleteItemData.setType(FileTypeEnum.FOLDER);
|
||||
deleteItemList.add(deleteItemData);
|
||||
|
||||
//查询数据源
|
||||
List<StorageSource> storageSources = storageSourceMapper.findAllOrderByOrderNum();
|
||||
//判断 local或者minio有没有成功
|
||||
List<Boolean> results = new ArrayList<>();
|
||||
for (StorageSource storageSource : storageSources) {
|
||||
|
||||
BatchDeleteRequest batchDeleteRequest = new BatchDeleteRequest();
|
||||
batchDeleteRequest.setDeleteItems(deleteItemList);
|
||||
batchDeleteRequest.setStorageKey(storageSource.getKey());
|
||||
AbstractBaseFileService<?> fileService = storageSourceContext.getByStorageKey(batchDeleteRequest.getStorageKey());
|
||||
List<BatchDeleteRequest.DeleteItem> deleteItems = batchDeleteRequest.getDeleteItems();
|
||||
int deleteSuccessCount = 0, deleteFailCount = 0, totalCount = CollUtil.size(deleteItems);
|
||||
for (BatchDeleteRequest.DeleteItem deleteItem : deleteItems) {
|
||||
boolean flag = false;
|
||||
try {
|
||||
if (deleteItem.getType() == FileTypeEnum.FILE) {
|
||||
flag = fileService.deleteFile(deleteItem.getPath(), deleteItem.getName());
|
||||
} else if (deleteItem.getType() == FileTypeEnum.FOLDER) {
|
||||
flag = fileService.deleteFolder(deleteItem.getPath(), deleteItem.getName());
|
||||
//批量删除TsFiles表数据
|
||||
if (dataset.size() > 0) {
|
||||
tsFilesService.deleteTsFilesByIds(dataset, "local");
|
||||
}
|
||||
|
||||
if (flag) {
|
||||
deleteSuccessCount++;
|
||||
} else {
|
||||
deleteFailCount++;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("删除文件/文件夹失败, 文件路径: {}, 文件名称: {}", deleteItem.getPath(), deleteItem.getName(), e);
|
||||
deleteFailCount++;
|
||||
}
|
||||
}
|
||||
if (totalCount > 1) {
|
||||
//return ResponseResult.success("批量删除 " + totalCount + " 个, 删除成功 " + deleteSuccessCount + " 个, 失败 " + deleteFailCount + " 个.");
|
||||
LOGGER.error("批量删除 " + totalCount + " 个, 删除成功 " + deleteSuccessCount + " 个, 失败 " + deleteFailCount + " 个.");
|
||||
} else {
|
||||
//return totalCount == deleteSuccessCount ? ResponseResult.success("删除成功") : ResponseResult.error("删除失败");
|
||||
LOGGER.error("批量删除 " + totalCount + " 个, 删除成功 " + deleteSuccessCount + " 个, 失败 " + deleteFailCount + " 个.");
|
||||
|
||||
}
|
||||
//如果是1 说明成功删除
|
||||
if (deleteSuccessCount >= 1) {
|
||||
results.add(true);
|
||||
} else {
|
||||
results.add(false);
|
||||
}
|
||||
}
|
||||
// 使用Java 8的Stream API检查列表中是否包含true
|
||||
boolean hasTrue = results.stream().anyMatch(Boolean::booleanValue);
|
||||
if (hasTrue) {
|
||||
// 递归删除子节点
|
||||
deleteChildren(tsNodes.getNodeId(), tsNodes.getTaskId());
|
||||
// 删除当前节点
|
||||
int deleteCount = tsNodesMapper.deleteById(id);
|
||||
if (deleteCount == 1) {
|
||||
LOGGER.info("tsnodes表结删除改成功");
|
||||
return true;
|
||||
} else {
|
||||
LOGGER.error("tsnodes表结构删除失败");
|
||||
return false;
|
||||
}
|
||||
return hasTrue;
|
||||
|
||||
// } catch (Exception e) {
|
||||
// // 如果发生异常,返回 false
|
||||
// return false;
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -556,9 +384,22 @@ public class TsNodesServiceImpl extends ServiceImpl<TsNodesMapper, TsNodes> impl
|
||||
tsNodesMapper.deleteById(child.getNodeId()); // 删除当前子节点
|
||||
//批量文件的数据
|
||||
QueryWrapper<TsFiles> queryWrapper1 = new QueryWrapper<>();
|
||||
queryWrapper1.eq("node_id", parentId);
|
||||
queryWrapper1.eq("node_id", child.getNodeId());
|
||||
queryWrapper1.eq("task_id", taskId);
|
||||
tsFilesMapper.delete(queryWrapper1);
|
||||
List<TsFiles> tsFiles = tsFilesMapper.selectList(queryWrapper1);
|
||||
|
||||
List<String> dataset = new ArrayList<>();
|
||||
if (tsFiles != null && !tsFiles.isEmpty()) {
|
||||
dataset = tsFiles.stream()
|
||||
.map(TsFiles::getId) // 假设 TsFiles 类中有 getId() 方法
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
//批量删除TsFiles表数据
|
||||
if (dataset.size() > 0) {
|
||||
tsFilesService.deleteTsFilesByIds(dataset, "local");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -164,17 +164,19 @@ public abstract class AbstractS3BaseFileService<P extends S3BaseParam> extends A
|
||||
public List<FileItemResult> s3FileListData(String path, String name) {
|
||||
List<FileItemResult> fileItemList = new ArrayList<>();
|
||||
String bucketName = param.getBucketName();
|
||||
if(path == null || StringUtils.isEmpty(path)){
|
||||
if (path == null || StringUtils.isEmpty(path)) {
|
||||
return fileItemList;
|
||||
}
|
||||
path = ensurePathWithSlash(path); // 确保路径以斜杠开头
|
||||
String fullPath = StringUtils.trimStartSlashes(StringUtils.concat(param.getBasePath(), path, ZFileConstant.PATH_SEPARATOR));
|
||||
|
||||
// 确保路径格式正确,并拼接目标文件夹名称(name)
|
||||
path = ensurePathWithSlash(path); // 输入 path="/",处理为 "/"
|
||||
String targetPath = path + name + ZFileConstant.PATH_SEPARATOR; // 目标路径:/431/
|
||||
String fullPath = StringUtils.trimStartSlashes(
|
||||
StringUtils.concat(param.getBasePath(), targetPath)
|
||||
);
|
||||
|
||||
|
||||
// 新增 includeAll 参数控制是否包含所有子项
|
||||
listFilesInDirectory(bucketName, fullPath, path, name, fileItemList, false);
|
||||
|
||||
// 调用时传入 name=null,确保递归时不再匹配其他同名文件夹
|
||||
listFilesInDirectory(bucketName, fullPath, targetPath, null, fileItemList, false);
|
||||
return fileItemList;
|
||||
}
|
||||
|
||||
@ -184,11 +186,11 @@ public abstract class AbstractS3BaseFileService<P extends S3BaseParam> extends A
|
||||
String path,
|
||||
String name,
|
||||
List<FileItemResult> fileItemList,
|
||||
boolean includeAll // 新增参数:是否强制包含所有内容
|
||||
boolean includeAll
|
||||
) {
|
||||
ListObjectsRequest listObjectsRequest = new ListObjectsRequest()
|
||||
.withBucketName(bucketName)
|
||||
.withPrefix(fullPath)
|
||||
.withPrefix(fullPath) // 关键修复:直接通过 Prefix 限定目标路径
|
||||
.withMaxKeys(1000)
|
||||
.withDelimiter("/");
|
||||
|
||||
@ -209,15 +211,15 @@ public abstract class AbstractS3BaseFileService<P extends S3BaseParam> extends A
|
||||
fileName = fileName.substring(1);
|
||||
}
|
||||
|
||||
// 包含条件:强制包含 或 名称匹配
|
||||
if (includeAll || StrUtil.isEmpty(name) || fileName.equals(name)) {
|
||||
// 包含条件:强制包含 或 名称匹配(仅在初始调用时检查 name)
|
||||
if (includeAll || name == null || StrUtil.isEmpty(name) || fileName.equals(name)) {
|
||||
FileItemResult item = new FileItemResult();
|
||||
item.setName(fileName);
|
||||
item.setSize(s.getSize());
|
||||
item.setTime(s.getLastModified());
|
||||
item.setType(FileTypeEnum.FILE);
|
||||
item.setPath(path); // 路径保持不变
|
||||
item.setUrl(getDownloadUrl(ensurePathWithSlash(path) + fileName)); // 确保路径以斜杠开头
|
||||
item.setPath(path);
|
||||
item.setUrl(getDownloadUrl(ensurePathWithSlash(path) + fileName));
|
||||
fileItemList.add(item);
|
||||
}
|
||||
}
|
||||
@ -227,27 +229,27 @@ public abstract class AbstractS3BaseFileService<P extends S3BaseParam> extends A
|
||||
String folderName = commonPrefix.substring(fullPath.length(), commonPrefix.length() - 1);
|
||||
if (StrUtil.isEmpty(folderName) || folderName.equals(StringUtils.DELIMITER_STR)) continue;
|
||||
|
||||
// 判断是否匹配名称或需要强制包含
|
||||
boolean matchFolder = includeAll || StrUtil.isEmpty(name) || folderName.equals(name);
|
||||
// 匹配条件:仅在初始调用时检查 name,递归时 name=null 直接包含
|
||||
boolean matchFolder = includeAll || name == null || StrUtil.isEmpty(name) || folderName.equals(name);
|
||||
|
||||
if (matchFolder) {
|
||||
FileItemResult folderItem = new FileItemResult();
|
||||
folderItem.setName(folderName);
|
||||
folderItem.setType(FileTypeEnum.FOLDER);
|
||||
folderItem.setPath(path); // 路径保持不变
|
||||
folderItem.setPath(path);
|
||||
fileItemList.add(folderItem);
|
||||
}
|
||||
|
||||
// 递归处理子文件夹(如果匹配则强制包含子项)
|
||||
String subPath = ensurePathWithSlash(path) + folderName + ZFileConstant.PATH_SEPARATOR; // 确保路径以斜杠开头并正确拼接
|
||||
// 递归处理子文件夹时,name=null,强制包含所有子项
|
||||
String subPath = ensurePathWithSlash(path) + folderName + ZFileConstant.PATH_SEPARATOR;
|
||||
String subFullPath = commonPrefix;
|
||||
listFilesInDirectory(
|
||||
bucketName,
|
||||
subFullPath,
|
||||
subPath,
|
||||
name,
|
||||
null, // 关键修复:递归时不再传递 name,避免深层匹配
|
||||
fileItemList,
|
||||
matchFolder // 关键修改:如果父文件夹匹配,则强制包含所有子项
|
||||
matchFolder // 如果父级匹配,则强制包含子项
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -191,40 +191,60 @@ public class LocalServiceImpl extends AbstractProxyTransferService<LocalParam> {
|
||||
List<FileItemResult> resultList = new ArrayList<>();
|
||||
String basePath = param.getFilePath();
|
||||
|
||||
// 处理根目录特殊情况
|
||||
String fullPath = folderPath.equals("/")
|
||||
? Paths.get(basePath).toString()
|
||||
: Paths.get(basePath, folderPath).toString();
|
||||
// 1. 构建目标路径(确保前后有 /)
|
||||
String targetPath = formatCombinedPath(folderPath, name); // 关键修改点
|
||||
|
||||
// 2. 拼接完整物理路径
|
||||
String fullPath = Paths.get(basePath, targetPath).toString();
|
||||
|
||||
File targetDir = new File(fullPath);
|
||||
|
||||
if (!targetDir.exists()) {
|
||||
throw new FileNotFoundException("路径不存在: " + fullPath);
|
||||
}
|
||||
|
||||
// 不添加目标文件夹本身到结果列表(与示例数据结构一致)
|
||||
// resultList.add(convertToFileItem(targetDir, folderPath));
|
||||
|
||||
// 列出目标目录内容
|
||||
// 3. 列出目录内容
|
||||
if (targetDir.isDirectory()) {
|
||||
String effectiveParentPath = folderPath.endsWith("/")
|
||||
? folderPath
|
||||
: folderPath + "/";
|
||||
listFilesInDirectory(targetDir, effectiveParentPath, resultList);
|
||||
listFilesInDirectory(targetDir, targetPath, resultList);
|
||||
}
|
||||
|
||||
return resultList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归列出文件夹下的所有内容
|
||||
* 构建规范化路径(根路径为 /,其他路径为 /path/)
|
||||
*/
|
||||
private String formatCombinedPath(String folderPath, String name) {
|
||||
StringBuilder pathBuilder = new StringBuilder();
|
||||
|
||||
// 处理 folderPath
|
||||
if (StringUtils.isBlank(folderPath) || folderPath.equals("/")) {
|
||||
pathBuilder.append("/");
|
||||
} else {
|
||||
pathBuilder.append(folderPath.trim());
|
||||
if (!folderPath.endsWith("/")) {
|
||||
pathBuilder.append("/");
|
||||
}
|
||||
}
|
||||
|
||||
// 处理 name
|
||||
if (StringUtils.isNotBlank(name)) {
|
||||
String sanitizedName = name.trim().replaceAll("/+", ""); // 防止注入额外路径
|
||||
pathBuilder.append(sanitizedName).append("/");
|
||||
}
|
||||
|
||||
// 最终格式化(替换多斜杠为单斜杠)
|
||||
return pathBuilder.toString().replaceAll("/+", "/");
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归列出目录内容
|
||||
*/
|
||||
private void listFilesInDirectory(File directory, String parentPath, List<FileItemResult> resultList) {
|
||||
File[] files = directory.listFiles();
|
||||
if (files == null) return;
|
||||
|
||||
for (File file : files) {
|
||||
// 创建文件项:父路径不带文件名
|
||||
// 创建文件项(确保路径格式)
|
||||
FileItemResult item = convertToFileItem(file, parentPath);
|
||||
resultList.add(item);
|
||||
|
||||
@ -237,12 +257,12 @@ public class LocalServiceImpl extends AbstractProxyTransferService<LocalParam> {
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换文件对象为结果对象
|
||||
* 转换文件对象为结果对象(路径前后带 /)
|
||||
*/
|
||||
private FileItemResult convertToFileItem(File file, String parentPath) {
|
||||
FileItemResult item = new FileItemResult();
|
||||
item.setName(file.getName());
|
||||
item.setPath(formatPath(parentPath)); // 父路径不带当前文件名
|
||||
item.setPath(formatSinglePath(parentPath)); // 关键修改点
|
||||
item.setType(file.isDirectory() ? FileTypeEnum.FOLDER : FileTypeEnum.FILE);
|
||||
item.setSize(file.isDirectory() ? 0 : file.length());
|
||||
item.setTime(new Date(file.lastModified()));
|
||||
@ -250,13 +270,29 @@ public class LocalServiceImpl extends AbstractProxyTransferService<LocalParam> {
|
||||
}
|
||||
|
||||
/**
|
||||
* 统一格式化路径
|
||||
* 单一路径格式化规则:
|
||||
* - 根路径返回 /
|
||||
* - 其他路径返回 /path/
|
||||
*/
|
||||
private String formatPath(String path) {
|
||||
// 保证路径以/开头且不以/结尾(示例数据结构风格)
|
||||
private String formatSinglePath(String path) {
|
||||
if (StringUtils.isBlank(path)) return "/";
|
||||
|
||||
// 替换多斜杠为单斜杠
|
||||
path = path.replaceAll("/+", "/");
|
||||
if (!path.startsWith("/")) path = "/" + path;
|
||||
if (path.endsWith("/") && path.length() > 1) path = path.substring(0, path.length()-1);
|
||||
|
||||
// 确保以 / 开头
|
||||
if (!path.startsWith("/")) {
|
||||
path = "/" + path;
|
||||
}
|
||||
|
||||
// 根路径直接返回
|
||||
if (path.equals("/")) return path;
|
||||
|
||||
// 确保以 / 结尾
|
||||
if (!path.endsWith("/")) {
|
||||
path += "/";
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
|
@ -11,19 +11,19 @@ spring:
|
||||
druid:
|
||||
master:
|
||||
driverClassName: com.mysql.cj.jdbc.Driver
|
||||
url: jdbc:mysql://120.27.210.161:3306/testdb?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true
|
||||
username: testdb
|
||||
password: 27CTfsyJmZRESmsa
|
||||
# url: jdbc:mysql://121.37.111.42:33306/filemanagedb?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true
|
||||
# username: filemanagedb
|
||||
# password: GAPchydbCKYFjjAa
|
||||
# url: jdbc:mysql://120.27.210.161:3306/testdb?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true
|
||||
# username: testdb
|
||||
# password: 27CTfsyJmZRESmsa
|
||||
url: jdbc:mysql://121.37.111.42:3306/filemanagedb?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true
|
||||
username: filemanagedb
|
||||
password: GAPchydbCKYFjjAa
|
||||
mvc:
|
||||
pathmatch:
|
||||
matching-strategy: ant_path_matcher
|
||||
servlet:
|
||||
multipart:
|
||||
max-file-size: 30MB
|
||||
max-request-size: 100MB
|
||||
max-file-size: 50GB
|
||||
max-request-size: 50GB
|
||||
logging:
|
||||
file:
|
||||
name: logs/projectname.log
|
||||
@ -34,7 +34,7 @@ logging:
|
||||
|
||||
# 在线文档: swagger-ui(生产环境建议关闭)
|
||||
swagger-ui:
|
||||
enabled: true
|
||||
enabled: flase
|
||||
mybatis-plus:
|
||||
configuration:
|
||||
default-enum-type-handler: com.yfd.platform.config.MybatisEnumTypeHandler
|
||||
|
Loading…
Reference in New Issue
Block a user