ソースを参照

fix(任务中心): 修复任务状态过早标记为完成的问题

- 主解析完成后状态保持processing,进度80%
- NER和图构建完成后才标记任务为completed
- 新增markCompleted API端点供事件监听器调用
何文松 1 ヶ月 前
コミット
c9296af97a

+ 30 - 0
backend/graph-service/src/main/java/com/lingyue/graph/listener/DocumentParsedEventListener.java

@@ -90,6 +90,9 @@ public class DocumentParsedEventListener {
         
         long totalTime = System.currentTimeMillis() - totalStartTime;
         log.info("文档后处理完成: documentId={}, totalTime={}ms", documentId, totalTime);
+        
+        // Step 3: 更新解析任务的最终状态为已完成
+        updateParseTaskCompleted(documentId);
     }
     
     /**
@@ -386,6 +389,33 @@ public class DocumentParsedEventListener {
     
     // ==================== 任务进度更新 ====================
     
+    /**
+     * 更新解析任务的最终状态为已完成
+     * 当所有后处理阶段(NER、图构建)都完成后调用
+     */
+    private void updateParseTaskCompleted(String documentId) {
+        try {
+            String url = "http://localhost:" + serverPort + "/api/internal/task-progress/complete/" + documentId;
+            
+            HttpHeaders headers = new HttpHeaders();
+            headers.setContentType(MediaType.APPLICATION_JSON);
+            
+            Map<String, Object> data = new HashMap<>();
+            data.put("status", "completed");
+            data.put("progress", 100);
+            data.put("currentStep", "completed");
+            
+            HttpEntity<Map<String, Object>> entity = new HttpEntity<>(data, headers);
+            
+            restTemplate.postForEntity(url, entity, Map.class);
+            log.info("解析任务状态更新为已完成: documentId={}", documentId);
+            
+        } catch (Exception e) {
+            log.warn("更新解析任务完成状态失败(可忽略): documentId={}, error={}", 
+                    documentId, e.getMessage());
+        }
+    }
+    
     /**
      * 更新任务进度(简单版本)
      */

+ 15 - 0
backend/parse-service/src/main/java/com/lingyue/parse/controller/TaskProgressController.java

@@ -102,4 +102,19 @@ public class TaskProgressController {
         
         return AjaxResult.success();
     }
+
+    /**
+     * 标记解析任务已完成
+     * 当所有阶段(包括 NER 和图构建)都完成后调用
+     */
+    @PostMapping("/complete/{documentId}")
+    @Operation(summary = "标记任务完成")
+    public AjaxResult<?> markCompleted(
+            @PathVariable @Parameter(description = "文档ID") String documentId,
+            @RequestBody Map<String, Object> request) {
+        
+        taskProgressService.markCompleted(documentId);
+        
+        return AjaxResult.success();
+    }
 }

+ 9 - 6
backend/parse-service/src/main/java/com/lingyue/parse/service/ParseService.java

@@ -209,12 +209,15 @@ public class ParseService {
                 task.setStructuredStatus("failed");
             }
 
-            // 6. NER 和图构建由事件监听器异步处理,这里标记为等待中
-            // 主解析流程完成,更新任务状态
-            task.setCurrentStep("completed");
-            task.setProgress(100);
-            task.setStatus("completed");
-            task.setCompletedAt(new java.util.Date());
+            // 6. NER 和图构建由事件监听器异步处理
+            // 主解析流程完成,但 NER 和图构建还在等待中
+            // 整体进度设为 80%,等待后续阶段完成
+            task.setCurrentStep("post_processing");
+            task.setProgress(80);
+            task.setNerStatus("pending");
+            task.setGraphStatus("pending");
+            // 状态保持 processing,等所有阶段完成后再标记为 completed
+            task.setStatus("processing");
             saveParseTask(task);
         } catch (Exception e) {
             // 错误分类和处理

+ 33 - 0
backend/parse-service/src/main/java/com/lingyue/parse/service/TaskProgressService.java

@@ -153,6 +153,39 @@ public class TaskProgressService {
         log.debug("更新图构建进度: documentId={}, status={}, progress={}", documentId, status, progress);
     }
 
+    /**
+     * 标记任务完成
+     * 当所有阶段都完成后调用(由事件监听器触发)
+     */
+    @Transactional
+    public void markCompleted(String documentId) {
+        ParseTask task = parseTaskRepository.findByDocumentId(documentId);
+        if (task == null) {
+            log.warn("任务不存在: documentId={}", documentId);
+            return;
+        }
+        
+        // 检查是否所有阶段都已完成
+        if (isAllCompleted(task)) {
+            task.setStatus("completed");
+            task.setProgress(100);
+            task.setCurrentStep("completed");
+            task.setCompletedAt(new Date());
+            parseTaskRepository.updateById(task);
+            log.info("任务标记为完成: documentId={}", documentId);
+        } else if (isAnyFailed(task)) {
+            // 如果有失败的阶段,标记为部分完成
+            task.setStatus("partial");
+            task.setCurrentStep("completed");
+            task.setCompletedAt(new Date());
+            parseTaskRepository.updateById(task);
+            log.info("任务标记为部分完成(有阶段失败): documentId={}", documentId);
+        } else {
+            // 还有未完成的阶段,保持 processing 状态
+            log.debug("任务尚未完全完成: documentId={}", documentId);
+        }
+    }
+    
     /**
      * 标记任务失败
      */