Răsfoiți Sursa

chore: add analysis backfill stats mode

yemeishu 2 săptămâni în urmă
părinte
comite
451be87daa

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

@@ -25,6 +25,7 @@ class BackfillExamAnalysisResultsCommand extends Command
                             {--student= : 仅处理指定 student_id}
                             {--limit=100 : 最多处理多少条候选试卷}
                             {--force-analysis : 允许重算已有但无效的分析数据(默认不覆盖)}
+                            {--stats-only : 只统计缺失情况,不投递队列、不修改数据、不受 limit 限制}
                             {--dry-run : 只打印待回填列表,不执行回填}';
 
     protected $description = '回填 exam_analysis_results 缺失分析数据或缺失 PDF URL 的试卷';
@@ -40,13 +41,14 @@ class BackfillExamAnalysisResultsCommand extends Command
             return self::FAILURE;
         }
 
+        $statsOnly = (bool) $this->option('stats-only');
         $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')
+        $paperQuery = DB::connection('mysql')
             ->table('papers')
             ->whereNotNull('completed_at')
             ->where('completed_at', '>=', $since->toDateTimeString())
@@ -54,9 +56,13 @@ class BackfillExamAnalysisResultsCommand extends Command
             ->where('student_id', '!=', '')
             ->when($paperFilter, fn ($q) => $q->where('paper_id', $paperFilter))
             ->when($studentFilter, fn ($q) => $q->where('student_id', $studentFilter))
-            ->orderBy('completed_at')
-            ->limit($limit)
-            ->get(['paper_id', 'student_id', 'completed_at']);
+            ->orderBy('completed_at');
+
+        if (! $statsOnly) {
+            $paperQuery->limit($limit);
+        }
+
+        $paperRows = $paperQuery->get(['paper_id', 'student_id', 'completed_at']);
 
         $targets = [];
         $counts = [
@@ -95,7 +101,7 @@ class BackfillExamAnalysisResultsCommand extends Command
 
             $counts[$action]++;
             if ($action === self::ACTION_SKIP || $action === self::ACTION_NEEDS_REVIEW) {
-                if ($action === self::ACTION_NEEDS_REVIEW) {
+                if ($action === self::ACTION_NEEDS_REVIEW && ! $statsOnly) {
                     $this->warn(sprintf(
                         '跳过需人工确认的已有分析记录:paper_id=%s student_id=%s analysis_id=%s(如确认要重算,单张使用 --force-analysis --paper=%s)',
                         $paper->paper_id,
@@ -117,18 +123,28 @@ class BackfillExamAnalysisResultsCommand extends Command
             ];
         }
 
+        $pendingCount = $counts[self::ACTION_ANALYSIS]
+            + $counts[self::ACTION_PDF_ONLY]
+            + $counts[self::ACTION_SYNC_PDF_URL]
+            + $counts[self::ACTION_NEEDS_REVIEW];
+
         $this->info(sprintf(
-            '扫描完成:已完成试卷 %d 条,需补分析 %d 条,仅补PDF %d 条,同步PDF URL %d 条,需人工确认 %d 条,已跳过 %d 条(since=%s, limit=%d)',
+            '扫描完成:试卷 %d 条,待处理 %d 条;需补分析 %d 条,仅补PDF %d 条,同步PDF URL %d 条,需人工确认 %d 条,已完成跳过 %d 条(since=%s%s)',
             $paperRows->count(),
+            $pendingCount,
             $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
+            $statsOnly ? ', stats-only' : ', limit='.$limit
         ));
 
+        if ($statsOnly) {
+            return self::SUCCESS;
+        }
+
         if ($isDryRun) {
             foreach ($targets as $item) {
                 $this->line(sprintf(