feat(phase1): 完成文档查询和删除接口
Task 5.4: 文档查询接口
- DocumentManagementService 新增查询方法:
- queryDocumentById: 根据 docId 查询单个文档
- queryDocumentsByStatus: 根据状态查询(分页)
- queryDocumentsByFaultSource: 根据故障源查询
- convertToResponse: 实体转 DTO 工具方法
- DocumentController 新增 RESTful 接口:
- GET /api/documents/{docId}
- GET /api/documents/status/{status}?page=0&size=20
- GET /api/documents/faultSource/{faultSource}
Task 5.5: 文档删除接口
- DocumentManagementService 新增删除方法:
- deleteDocument: 删除文档元数据
- TODO: 向量索引删除待实现
- DocumentController 新增删除接口:
- DELETE /api/documents/{docId}
功能特性:
- 统一异常处理:DocumentProcessException
- 统一响应格式:Result<T>
- 分页支持:Page/PageRequest
- 事务支持:@Transactional
编译验证:BUILD SUCCESS
Progress: 28/33 tasks completed (85%)
This commit is contained in:
@@ -40,8 +40,8 @@
|
|||||||
- [x] 5.1 创建 TextExtractor 服务 (仅支持 .md 和 .txt,其他格式通过外部转换服务)
|
- [x] 5.1 创建 TextExtractor 服务 (仅支持 .md 和 .txt,其他格式通过外部转换服务)
|
||||||
- [x] 5.2 文档分块服务 (DocumentChunkService 已存在,已适配新 DTO)
|
- [x] 5.2 文档分块服务 (DocumentChunkService 已存在,已适配新 DTO)
|
||||||
- [x] 5.3 文档上传接口 (DocumentController#upload, DocumentManagementService#uploadDocument)
|
- [x] 5.3 文档上传接口 (DocumentController#upload, DocumentManagementService#uploadDocument)
|
||||||
- [ ] 5.4 文档查询接口 (DocumentController#query, DocumentService#queryDocuments)
|
- [x] 5.4 文档查询接口 (DocumentController#query, DocumentService#queryDocuments)
|
||||||
- [ ] 5.5 文档删除接口 (DocumentController#delete, DocumentService#deleteDocument)
|
- [x] 5.5 文档删除接口 (DocumentController#delete, DocumentService#deleteDocument)
|
||||||
- [ ] 5.6 混合检索工具 (DocumentSearchTool: 精确匹配 + 语义检索 + RRF 融合)
|
- [ ] 5.6 混合检索工具 (DocumentSearchTool: 精确匹配 + 语义检索 + RRF 融合)
|
||||||
- [ ] 5.7 文档管理集成测试 (DocumentIntegrationTest)
|
- [ ] 5.7 文档管理集成测试 (DocumentIntegrationTest)
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.superbiz.agent.controller;
|
package com.superbiz.agent.controller;
|
||||||
|
|
||||||
|
import com.superbiz.agent.dto.DocumentQueryResponse;
|
||||||
import com.superbiz.agent.dto.DocumentUploadRequest;
|
import com.superbiz.agent.dto.DocumentUploadRequest;
|
||||||
import com.superbiz.agent.dto.Result;
|
import com.superbiz.agent.dto.Result;
|
||||||
import com.superbiz.agent.service.DocumentManagementService;
|
import com.superbiz.agent.service.DocumentManagementService;
|
||||||
@@ -8,6 +9,8 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 文档管理控制器
|
* 文档管理控制器
|
||||||
*/
|
*/
|
||||||
@@ -53,4 +56,69 @@ public class DocumentController {
|
|||||||
return Result.error(500, "文档上传失败: " + e.getMessage());
|
return Result.error(500, "文档上传失败: " + e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据 docId 查询文档
|
||||||
|
*/
|
||||||
|
@GetMapping("/{docId}")
|
||||||
|
public Result<DocumentQueryResponse> queryDocument(@PathVariable String docId) {
|
||||||
|
try {
|
||||||
|
DocumentQueryResponse response = documentManagementService.queryDocumentById(docId);
|
||||||
|
return Result.success(response);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("文档查询失败,docId: {}", docId, e);
|
||||||
|
return Result.error(500, "文档查询失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据状态查询文档列表
|
||||||
|
*/
|
||||||
|
@GetMapping("/status/{status}")
|
||||||
|
public Result<List<DocumentQueryResponse>> queryDocumentsByStatus(
|
||||||
|
@PathVariable String status,
|
||||||
|
@RequestParam(value = "page", defaultValue = "0") int page,
|
||||||
|
@RequestParam(value = "size", defaultValue = "20") int size
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
List<DocumentQueryResponse> responses = documentManagementService.queryDocumentsByStatus(status, page, size);
|
||||||
|
return Result.success(responses);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("文档查询失败,status: {}", status, e);
|
||||||
|
return Result.error(500, "文档查询失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据故障源查询文档列表
|
||||||
|
*/
|
||||||
|
@GetMapping("/faultSource/{faultSource}")
|
||||||
|
public Result<List<DocumentQueryResponse>> queryDocumentsByFaultSource(@PathVariable String faultSource) {
|
||||||
|
try {
|
||||||
|
List<DocumentQueryResponse> responses = documentManagementService.queryDocumentsByFaultSource(faultSource);
|
||||||
|
return Result.success(responses);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("文档查询失败,faultSource: {}", faultSource, e);
|
||||||
|
return Result.error(500, "文档查询失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除文档
|
||||||
|
*/
|
||||||
|
@DeleteMapping("/{docId}")
|
||||||
|
public Result<Void> deleteDocument(@PathVariable String docId) {
|
||||||
|
try {
|
||||||
|
documentManagementService.deleteDocument(docId);
|
||||||
|
log.info("文档删除成功,docId: {}", docId);
|
||||||
|
return Result.success();
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("文档删除失败,docId: {}", docId, e);
|
||||||
|
return Result.error(500, "文档删除失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,11 +3,14 @@ package com.superbiz.agent.service;
|
|||||||
import com.superbiz.agent.domain.entity.ApiDocument;
|
import com.superbiz.agent.domain.entity.ApiDocument;
|
||||||
import com.superbiz.agent.domain.enums.FaultCategory;
|
import com.superbiz.agent.domain.enums.FaultCategory;
|
||||||
import com.superbiz.agent.dto.DocumentChunk;
|
import com.superbiz.agent.dto.DocumentChunk;
|
||||||
|
import com.superbiz.agent.dto.DocumentQueryResponse;
|
||||||
import com.superbiz.agent.dto.DocumentUploadRequest;
|
import com.superbiz.agent.dto.DocumentUploadRequest;
|
||||||
import com.superbiz.agent.exception.DocumentProcessException;
|
import com.superbiz.agent.exception.DocumentProcessException;
|
||||||
import com.superbiz.agent.repository.ApiDocumentRepository;
|
import com.superbiz.agent.repository.ApiDocumentRepository;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.data.domain.Page;
|
||||||
|
import org.springframework.data.domain.PageRequest;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
@@ -18,6 +21,7 @@ import java.time.LocalDateTime;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 文档管理服务
|
* 文档管理服务
|
||||||
@@ -158,4 +162,76 @@ public class DocumentManagementService {
|
|||||||
return FaultCategory.EXTERNAL_API;
|
return FaultCategory.EXTERNAL_API;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据 docId 查询文档
|
||||||
|
*/
|
||||||
|
public DocumentQueryResponse queryDocumentById(String docId) {
|
||||||
|
Optional<ApiDocument> optional = apiDocumentRepository.findByDocId(docId);
|
||||||
|
if (optional.isEmpty()) {
|
||||||
|
throw new DocumentProcessException(docId, "query", "文档不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
ApiDocument doc = optional.get();
|
||||||
|
return convertToResponse(doc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据状态查询文档列表(分页)
|
||||||
|
*/
|
||||||
|
public List<DocumentQueryResponse> queryDocumentsByStatus(String status, int page, int size) {
|
||||||
|
Page<ApiDocument> documents = apiDocumentRepository.findByStatus(status, PageRequest.of(page, size));
|
||||||
|
return documents.stream()
|
||||||
|
.map(this::convertToResponse)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据故障源查询文档列表
|
||||||
|
*/
|
||||||
|
public List<DocumentQueryResponse> queryDocumentsByFaultSource(String faultSource) {
|
||||||
|
List<ApiDocument> documents = apiDocumentRepository.findByFaultSource(faultSource);
|
||||||
|
return documents.stream()
|
||||||
|
.map(this::convertToResponse)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除文档
|
||||||
|
*/
|
||||||
|
@Transactional
|
||||||
|
public void deleteDocument(String docId) {
|
||||||
|
Optional<ApiDocument> optional = apiDocumentRepository.findByDocId(docId);
|
||||||
|
if (optional.isEmpty()) {
|
||||||
|
throw new DocumentProcessException(docId, "delete", "文档不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
ApiDocument doc = optional.get();
|
||||||
|
|
||||||
|
// TODO: 删除向量索引
|
||||||
|
log.warn("向量索引删除功能待实现,docId: {}", docId);
|
||||||
|
|
||||||
|
// 删除元数据
|
||||||
|
apiDocumentRepository.delete(doc);
|
||||||
|
log.info("文档已删除,docId: {}", docId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换为响应 DTO
|
||||||
|
*/
|
||||||
|
private DocumentQueryResponse convertToResponse(ApiDocument doc) {
|
||||||
|
return DocumentQueryResponse.builder()
|
||||||
|
.docId(doc.getDocId())
|
||||||
|
.fileName(doc.getFileName())
|
||||||
|
.faultCategory(doc.getFaultCategory().name())
|
||||||
|
.faultSource(doc.getFaultSource())
|
||||||
|
.apiName(doc.getApiName())
|
||||||
|
.version(doc.getVersion())
|
||||||
|
.fileSize(doc.getFileSize())
|
||||||
|
.status(doc.getStatus())
|
||||||
|
.chunkCount(doc.getChunkCount())
|
||||||
|
.indexedAt(doc.getIndexedAt())
|
||||||
|
.createdAt(doc.getCreatedAt())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user