Kaynağa Gözat

perf: batch sync paper question grading

yemeishu 1 ay önce
ebeveyn
işleme
a1b6cd5baa
1 değiştirilmiş dosya ile 33 ekleme ve 7 silme
  1. 33 7
      app/Services/ExamAnswerAnalysisService.php

+ 33 - 7
app/Services/ExamAnswerAnalysisService.php

@@ -1711,6 +1711,7 @@ class ExamAnswerAnalysisService
         $now = now();
         $updated = 0;
         $processedQuestionIds = [];
+        $payloadsByQuestionId = [];
         foreach ($examData['questions'] as $question) {
             $questionId = $question['question_id'] ?? $question['question_bank_id'] ?? null;
             if (empty($questionId)) {
@@ -1752,16 +1753,40 @@ class ExamAnswerAnalysisService
                 $payload['teacher_comment'] = $question['teacher_comment'];
             }
 
-            // 关键:不再依赖 paper_questions.id(部分库该字段为空),改为业务键匹配更新
-            $affected = DB::connection('mysql')->table('paper_questions')
+            $payloadsByQuestionId[$questionId] = $payload;
+        }
+
+        if (! empty($payloadsByQuestionId)) {
+            $questionIds = array_keys($payloadsByQuestionId);
+            $paperQuestionRows = DB::connection('mysql')->table('paper_questions')
                 ->where('paper_id', $paperId)
-                ->where(function ($q) use ($questionId) {
-                    $q->where('question_bank_id', $questionId)
-                        ->orWhere('question_id', $questionId);
+                ->where(function ($q) use ($questionIds) {
+                    $q->whereIn('question_bank_id', $questionIds)
+                        ->orWhereIn('question_id', $questionIds);
                 })
-                ->update($payload);
+                ->get(['id', 'question_bank_id', 'question_id']);
 
-            $updated += $affected;
+            $idsByQuestionId = [];
+            foreach ($paperQuestionRows as $row) {
+                foreach ([$row->question_bank_id ?? null, $row->question_id ?? null] as $candidateId) {
+                    $candidateId = (string) $candidateId;
+                    if ($candidateId === '' || ! isset($payloadsByQuestionId[$candidateId])) {
+                        continue;
+                    }
+                    $idsByQuestionId[$candidateId][] = $row->id;
+                }
+            }
+
+            foreach ($payloadsByQuestionId as $questionId => $payload) {
+                $rowIds = array_values(array_unique(array_filter($idsByQuestionId[$questionId] ?? [])));
+                if ($rowIds === []) {
+                    continue;
+                }
+
+                $updated += DB::connection('mysql')->table('paper_questions')
+                    ->whereIn('id', $rowIds)
+                    ->update($payload);
+            }
         }
 
         if ($updated > 0) {
@@ -1779,6 +1804,7 @@ class ExamAnswerAnalysisService
             'input_question_count' => count($examData['questions']),
             'processed_question_count' => count($processedQuestionIds),
             'updated_rows' => $updated,
+            'matched_rows' => isset($paperQuestionRows) ? $paperQuestionRows->count() : 0,
         ]);
     }