ソースを参照

fix: make analysis backfill non destructive by default

yemeishu 1 ヶ月 前
コミット
c2d47d1d7f
1 ファイル変更23 行追加6 行削除
  1. 23 6
      app/Console/Commands/BackfillExamAnalysisResultsCommand.php

+ 23 - 6
app/Console/Commands/BackfillExamAnalysisResultsCommand.php

@@ -17,12 +17,14 @@ class BackfillExamAnalysisResultsCommand extends Command
     private const ACTION_ANALYSIS = 'analysis';
     private const ACTION_PDF_ONLY = 'pdf_only';
     private const ACTION_SYNC_PDF_URL = 'sync_pdf_url';
+    private const ACTION_NEEDS_REVIEW = 'needs_review';
 
     protected $signature = 'exam:backfill-analysis-results
                             {--since= : papers.completed_at >= 该时间(默认今天 00:00:00)}
                             {--paper= : 仅处理指定 paper_id}
                             {--student= : 仅处理指定 student_id}
                             {--limit=100 : 最多处理多少条候选试卷}
+                            {--force-analysis : 允许重算已有但无效的分析数据(默认不覆盖)}
                             {--dry-run : 只打印待回填列表,不执行回填}';
 
     protected $description = '回填 exam_analysis_results 缺失分析数据或缺失 PDF URL 的试卷';
@@ -41,6 +43,7 @@ class BackfillExamAnalysisResultsCommand extends Command
         $limit = max(1, (int) $this->option('limit'));
         $paperFilter = $this->option('paper');
         $studentFilter = $this->option('student');
+        $forceAnalysis = (bool) $this->option('force-analysis');
         $isDryRun = (bool) $this->option('dry-run');
 
         $paperRows = DB::connection('mysql')
@@ -61,6 +64,7 @@ class BackfillExamAnalysisResultsCommand extends Command
             self::ACTION_ANALYSIS => 0,
             self::ACTION_PDF_ONLY => 0,
             self::ACTION_SYNC_PDF_URL => 0,
+            self::ACTION_NEEDS_REVIEW => 0,
         ];
 
         foreach ($paperRows as $paper) {
@@ -85,11 +89,21 @@ class BackfillExamAnalysisResultsCommand extends Command
                 $latest->analysis_data ?? null,
                 $latest->id ?? null,
                 $latest->analysis_pdf_url ?? null,
-                $studentReportPdfUrl
+                $studentReportPdfUrl,
+                $forceAnalysis
             );
 
             $counts[$action]++;
-            if ($action === self::ACTION_SKIP) {
+            if ($action === self::ACTION_SKIP || $action === self::ACTION_NEEDS_REVIEW) {
+                if ($action === self::ACTION_NEEDS_REVIEW) {
+                    $this->warn(sprintf(
+                        '跳过需人工确认的已有分析记录:paper_id=%s student_id=%s analysis_id=%s(如确认要重算,单张使用 --force-analysis --paper=%s)',
+                        $paper->paper_id,
+                        $paper->student_id,
+                        $latest->id ?? 'null',
+                        $paper->paper_id
+                    ));
+                }
                 continue;
             }
 
@@ -104,11 +118,12 @@ class BackfillExamAnalysisResultsCommand extends Command
         }
 
         $this->info(sprintf(
-            '扫描完成:已完成试卷 %d 条,需补分析 %d 条,仅补PDF %d 条,同步PDF URL %d 条,已跳过 %d 条(since=%s, limit=%d)',
+            '扫描完成:已完成试卷 %d 条,需补分析 %d 条,仅补PDF %d 条,同步PDF URL %d 条,需人工确认 %d 条,已跳过 %d 条(since=%s, limit=%d)',
             $paperRows->count(),
             $counts[self::ACTION_ANALYSIS],
             $counts[self::ACTION_PDF_ONLY],
             $counts[self::ACTION_SYNC_PDF_URL],
+            $counts[self::ACTION_NEEDS_REVIEW],
             $counts[self::ACTION_SKIP],
             $since->toDateTimeString(),
             $limit
@@ -145,7 +160,7 @@ class BackfillExamAnalysisResultsCommand extends Command
                         'paper_id' => $item->paper_id,
                         'student_id' => $item->student_id,
                         'questions' => $questions,
-                        'force_recalculate' => true,
+                        'force_recalculate' => $forceAnalysis,
                     ];
 
                     $taskId = $taskManager->createTask(TaskManager::TASK_TYPE_ANALYSIS, [
@@ -204,15 +219,17 @@ class BackfillExamAnalysisResultsCommand extends Command
         mixed $analysisDataRaw,
         mixed $analysisId,
         mixed $analysisPdfUrl,
-        mixed $studentReportPdfUrl
+        mixed $studentReportPdfUrl,
+        bool $forceAnalysis
     ): string
     {
+        $hasAnalysisRow = $analysisId !== null;
         $hasValidAnalysis = $this->hasValidAnalysisData($analysisDataRaw, $analysisId);
         $hasAnalysisPdf = $this->hasNonEmptyString($analysisPdfUrl);
         $hasStudentReportPdf = $this->hasNonEmptyString($studentReportPdfUrl);
 
         if (! $hasValidAnalysis) {
-            return self::ACTION_ANALYSIS;
+            return (! $hasAnalysisRow || $forceAnalysis) ? self::ACTION_ANALYSIS : self::ACTION_NEEDS_REVIEW;
         }
 
         if ($hasAnalysisPdf) {