diff --git a/backend/services/data-management-service/src/main/java/com/datamate/datamanagement/application/KnowledgeItemApplicationService.java b/backend/services/data-management-service/src/main/java/com/datamate/datamanagement/application/KnowledgeItemApplicationService.java index 7dc7362..a254c3d 100644 --- a/backend/services/data-management-service/src/main/java/com/datamate/datamanagement/application/KnowledgeItemApplicationService.java +++ b/backend/services/data-management-service/src/main/java/com/datamate/datamanagement/application/KnowledgeItemApplicationService.java @@ -333,7 +333,7 @@ public class KnowledgeItemApplicationService { String relativePath = knowledgeItem.getContent(); BusinessAssert.isTrue(StringUtils.isNotBlank(relativePath), CommonErrorCode.PARAM_ERROR); - Path filePath = resolveKnowledgeItemStoragePath(relativePath); + Path filePath = resolveKnowledgeItemStoragePathWithFallback(relativePath); BusinessAssert.isTrue(Files.exists(filePath) && Files.isRegularFile(filePath), CommonErrorCode.PARAM_ERROR); String downloadName = StringUtils.isNotBlank(knowledgeItem.getSourceFileId()) @@ -390,7 +390,7 @@ public class KnowledgeItemApplicationService { return; } - Path filePath = resolveKnowledgeItemStoragePath(relativePath); + Path filePath = resolveKnowledgeItemStoragePathWithFallback(relativePath); BusinessAssert.isTrue(Files.exists(filePath) && Files.isRegularFile(filePath), CommonErrorCode.PARAM_ERROR); String contentType = null; @@ -532,6 +532,86 @@ public class KnowledgeItemApplicationService { return target; } + private Path resolveKnowledgeItemStoragePathWithFallback(String relativePath) { + BusinessAssert.isTrue(StringUtils.isNotBlank(relativePath), CommonErrorCode.PARAM_ERROR); + String normalizedInput = relativePath.replace("\\", PATH_SEPARATOR).trim(); + Path root = resolveUploadRootPath(); + java.util.LinkedHashSet candidates = new java.util.LinkedHashSet<>(); + + Path inputPath = Paths.get(normalizedInput.replace(PATH_SEPARATOR, File.separator)); + if (inputPath.isAbsolute()) { + Path normalizedAbsolute = inputPath.toAbsolutePath().normalize(); + if (normalizedAbsolute.startsWith(root)) { + candidates.add(normalizedAbsolute); + } + String segmentRelativePath = extractRelativePathFromSegment(normalizedInput, KNOWLEDGE_ITEM_UPLOAD_DIR); + if (StringUtils.isNotBlank(segmentRelativePath)) { + candidates.add(buildKnowledgeItemStoragePath(root, segmentRelativePath)); + } + BusinessAssert.isTrue(!candidates.isEmpty(), CommonErrorCode.PARAM_ERROR); + } else { + String normalizedRelative = normalizeRelativePathValue(normalizedInput); + if (StringUtils.isNotBlank(normalizedRelative)) { + candidates.add(buildKnowledgeItemStoragePath(root, normalizedRelative)); + } + String segmentRelativePath = extractRelativePathFromSegment(normalizedInput, KNOWLEDGE_ITEM_UPLOAD_DIR); + if (StringUtils.isNotBlank(segmentRelativePath)) { + candidates.add(buildKnowledgeItemStoragePath(root, segmentRelativePath)); + } + if (StringUtils.isNotBlank(normalizedRelative) + && !normalizedRelative.startsWith(KNOWLEDGE_ITEM_UPLOAD_DIR + PATH_SEPARATOR) + && !normalizedRelative.equals(KNOWLEDGE_ITEM_UPLOAD_DIR)) { + candidates.add(buildKnowledgeItemStoragePath(root, KNOWLEDGE_ITEM_UPLOAD_DIR + PATH_SEPARATOR + normalizedRelative)); + } + } + + if (root.getFileName() != null && KNOWLEDGE_ITEM_UPLOAD_DIR.equals(root.getFileName().toString())) { + String normalizedRelative = normalizeRelativePathValue(normalizedInput); + if (StringUtils.isNotBlank(normalizedRelative) + && normalizedRelative.startsWith(KNOWLEDGE_ITEM_UPLOAD_DIR + PATH_SEPARATOR)) { + String withoutPrefix = normalizedRelative.substring(KNOWLEDGE_ITEM_UPLOAD_DIR.length() + PATH_SEPARATOR.length()); + if (StringUtils.isNotBlank(withoutPrefix)) { + candidates.add(buildKnowledgeItemStoragePath(root, withoutPrefix)); + } + } + } + + Path fallback = null; + for (Path candidate : candidates) { + if (fallback == null) { + fallback = candidate; + } + if (Files.exists(candidate) && Files.isRegularFile(candidate)) { + return candidate; + } + } + BusinessAssert.notNull(fallback, CommonErrorCode.PARAM_ERROR); + return fallback; + } + + private Path buildKnowledgeItemStoragePath(Path root, String relativePath) { + String normalizedRelativePath = StringUtils.defaultString(relativePath).replace(PATH_SEPARATOR, File.separator); + Path target = root.resolve(normalizedRelativePath).toAbsolutePath().normalize(); + BusinessAssert.isTrue(target.startsWith(root), CommonErrorCode.PARAM_ERROR); + return target; + } + + private String extractRelativePathFromSegment(String rawPath, String segment) { + if (StringUtils.isBlank(rawPath) || StringUtils.isBlank(segment)) { + return null; + } + String normalized = rawPath.replace("\\", PATH_SEPARATOR).trim(); + while (normalized.startsWith(PATH_SEPARATOR)) { + normalized = normalized.substring(1); + } + String segmentPrefix = segment + PATH_SEPARATOR; + int index = normalized.indexOf(segmentPrefix); + if (index < 0) { + return segment.equals(normalized) ? segment : null; + } + return normalizeRelativePathValue(normalized.substring(index)); + } + private KnowledgeItemSearchResponse normalizeSearchResponse(KnowledgeItemSearchResponse item) { BusinessAssert.notNull(item, CommonErrorCode.PARAM_ERROR); if (item.getSourceType() == KnowledgeSourceType.FILE_UPLOAD) {