ソースを参照

fix: use paper question difficulty for mastery analysis

yemeishu 2 週間 前
コミット
0213418eec
1 ファイル変更25 行追加5 行削除
  1. 25 5
      app/Services/ExamAnswerAnalysisService.php

+ 25 - 5
app/Services/ExamAnswerAnalysisService.php

@@ -114,7 +114,7 @@ class ExamAnswerAnalysisService
 
         // 【公司要求】4. 计算每个知识点的加权掌握度(传入学案基准难度)
         // 核心算法:难度映射 → 权重计算 → 数值更新(newMastery = oldMastery + change)
-        $knowledgeMasteryVector = $this->calculateKnowledgeMasteryVector($questions, $questionMappings, $examBaseDifficulty, $studentId);
+        $knowledgeMasteryVector = $this->calculateKnowledgeMasteryVector($questions, $questionMappings, $examBaseDifficulty, $studentId, $paperId);
 
         // 【公司要求】5. 更新学生掌握度(包含多级父节点掌握度计算)
         $updatedMastery = $this->updateStudentMastery($studentId, $knowledgeMasteryVector);
@@ -662,18 +662,37 @@ class ExamAnswerAnalysisService
      * @param  array  $questionIds  题目ID数组
      * @return array [questionId => difficulty] 映射
      */
-    private function batchGetQuestionDifficulties(array $questionIds): array
+    private function batchGetQuestionDifficulties(array $questionIds, ?string $paperId = null): array
     {
         if (empty($questionIds)) {
             return [];
         }
 
         $difficulties = [];
+        $questionIds = array_values(array_unique(array_filter($questionIds)));
 
         try {
+            if ($paperId !== null && $paperId !== '') {
+                $paperQuestionRows = DB::connection('mysql')
+                    ->table('paper_questions')
+                    ->where('paper_id', $paperId)
+                    ->whereIn('question_bank_id', $questionIds)
+                    ->whereNotNull('difficulty')
+                    ->get(['question_bank_id', 'difficulty']);
+
+                foreach ($paperQuestionRows as $row) {
+                    $difficulties[$row->question_bank_id] = (float) $row->difficulty;
+                }
+            }
+
+            $missingQuestionIds = array_values(array_diff($questionIds, array_keys($difficulties)));
+            if ($missingQuestionIds === []) {
+                return $difficulties;
+            }
+
             $questions = DB::connection('mysql')
                 ->table('questions')
-                ->whereIn('id', $questionIds)
+                ->whereIn('id', $missingQuestionIds)
                 ->select(['id', 'difficulty'])
                 ->get();
 
@@ -685,6 +704,7 @@ class ExamAnswerAnalysisService
         } catch (\Exception $e) {
             Log::warning('批量获取题目难度失败', [
                 'question_ids' => $questionIds,
+                'paper_id' => $paperId,
                 'error' => $e->getMessage(),
             ]);
         }
@@ -714,14 +734,14 @@ class ExamAnswerAnalysisService
      * @param  string|null  $studentId  学生ID
      * @return array 知识点掌握度向量
      */
-    private function calculateKnowledgeMasteryVector(array $questions, array $questionMappings, ?int $examBaseDifficulty = null, ?string $studentId = null): array
+    private function calculateKnowledgeMasteryVector(array $questions, array $questionMappings, ?int $examBaseDifficulty = null, ?string $studentId = null, ?string $paperId = null): array
     {
         // 按知识点聚合答题记录
         $knowledgeAttempts = [];
 
         // 批量获取所有题目的难度(减少数据库查询次数)
         $questionIds = array_filter(array_map(fn ($q) => $q['question_id'] ?? $q['question_bank_id'] ?? null, $questions));
-        $questionDifficulties = $this->batchGetQuestionDifficulties($questionIds);
+        $questionDifficulties = $this->batchGetQuestionDifficulties($questionIds, $paperId);
 
         foreach ($questions as $question) {
             $questionId = $question['question_id'] ?? $question['question_bank_id'] ?? null;