Bläddra i källkod

feat(attachment): integrate FileStorageService for actual file persistence

- Fix IdGenerator to use timestamp+random to avoid collision after restart
- Add lingyue-file dependency to lingyue-project
- AttachmentController now calls FileStorageService.uploadFile()
- AttachmentService stores fileKey from FileStorageService as node property
何文松 12 timmar sedan
förälder
incheckning
e4c5016390

+ 4 - 3
backend/lingyue-common/src/main/java/com/lingyue/common/util/IdGenerator.java

@@ -16,9 +16,10 @@ public final class IdGenerator {
     }
 
     public static String generateAttachmentKey() {
-        int year = LocalDate.now().getYear();
-        int seq = COUNTER.incrementAndGet();
-        return String.format("ATT-%d-%03d", year, seq);
+        // Use timestamp + random to avoid collision after restart
+        long ts = System.currentTimeMillis();
+        int rand = (int) (Math.random() * 1000);
+        return String.format("ATT-%d-%d", ts, rand);
     }
 
     public static String generateFileKey() {

+ 4 - 0
backend/lingyue-project/pom.xml

@@ -24,6 +24,10 @@
             <groupId>com.lingyue</groupId>
             <artifactId>lingyue-graph</artifactId>
         </dependency>
+        <dependency>
+            <groupId>com.lingyue</groupId>
+            <artifactId>lingyue-file</artifactId>
+        </dependency>
 
         <!-- Spring Boot Web -->
         <dependency>

+ 10 - 3
backend/lingyue-project/src/main/java/com/lingyue/project/attachment/controller/AttachmentController.java

@@ -1,6 +1,9 @@
 package com.lingyue.project.attachment.controller;
 
 import com.lingyue.common.core.Result;
+import com.lingyue.common.security.UserContext;
+import com.lingyue.file.dto.FileUploadVO;
+import com.lingyue.file.service.FileStorageService;
 import com.lingyue.project.attachment.dto.AttachmentUploadVO;
 import com.lingyue.project.attachment.dto.AttachmentVO;
 import com.lingyue.project.attachment.service.AttachmentService;
@@ -23,20 +26,24 @@ public class AttachmentController {
 
     private final AttachmentService attachmentService;
     private final DocxParseService docxParseService;
+    private final FileStorageService fileStorageService;
 
     @Operation(summary = "上传附件")
     @PostMapping("/api/v1/projects/{projectId}/attachments/upload")
     public Result<AttachmentUploadVO> upload(@PathVariable Long projectId,
                                               @RequestParam("file") MultipartFile file,
                                               @RequestParam(required = false) String displayName) {
-        // TODO: 调用file-service上传文件,获取filePath
+        // 1. 上传文件到文件存储服务
+        Long userId = UserContext.currentUserId();
+        FileUploadVO fileVO = fileStorageService.uploadFile(file, userId);
+
+        // 2. 创建附件记录,使用文件服务返回的 fileKey
         String fileName = file.getOriginalFilename();
         String fileType = fileName != null && fileName.contains(".")
                 ? fileName.substring(fileName.lastIndexOf(".") + 1) : "unknown";
-        String filePath = "/uploads/" + fileName;
 
         AttachmentUploadVO vo = attachmentService.uploadAttachment(
-                projectId, displayName, fileName, filePath, fileType, file.getSize());
+                projectId, displayName, fileName, fileVO.getFileKey(), fileType, file.getSize());
         return Result.ok(vo);
     }
 

+ 5 - 4
backend/lingyue-project/src/main/java/com/lingyue/project/attachment/service/AttachmentService.java

@@ -45,22 +45,23 @@ public class AttachmentService {
 
     @Transactional
     public AttachmentUploadVO uploadAttachment(Long projectId, String displayName,
-                                                String fileName, String filePath,
+                                                String fileName, String fileKey,
                                                 String fileType, long fileSize) {
         Node project = nodeService.getById(projectId);
         if (project == null || !Constants.NODE_PROJECT.equals(project.getNodeType())) {
             throw new BusinessException(404, "项目不存在");
         }
 
-        String fileKey = IdGenerator.generateAttachmentKey();
+        // fileKey is now passed from FileStorageService, use it directly
+        String attachmentKey = IdGenerator.generateAttachmentKey();
         Long userId = UserContext.currentUserId();
 
         Long attachmentId = nodeService.createNode(
-                Constants.NODE_ATTACHMENT, fileKey,
+                Constants.NODE_ATTACHMENT, attachmentKey,
                 displayName != null ? displayName : fileName, userId);
 
         propertyService.setNodeProperty(attachmentId, "file_name", fileName);
-        propertyService.setNodeProperty(attachmentId, "file_path", filePath);
+        propertyService.setNodeProperty(attachmentId, "file_key", fileKey);  // Store the actual file key
         propertyService.setNodeProperty(attachmentId, "file_type", fileType);
         propertyService.setNodeProperty(attachmentId, "file_size", String.valueOf(fileSize));
         propertyService.setNodeProperty(attachmentId, "parse_status", Constants.PARSE_PENDING);