ソースを参照

Unify calibrated difficulty usage across exam assembly paths

yemeishu 2 日 前
コミット
9d9bff2856

+ 9 - 3
app/Filament/Pages/ExamHistory.php

@@ -3,6 +3,7 @@
 namespace App\Filament\Pages;
 
 use App\Services\QuestionBankService;
+use App\Services\QuestionDifficultyResolver;
 use BackedEnum;
 use Filament\Notifications\Notification;
 use Filament\Pages\Page;
@@ -438,6 +439,11 @@ class ExamHistory extends Page
             // 获取当前试卷的最大题号
             $maxQuestionNumber = \App\Models\PaperQuestion::where('paper_id', $paperId)
                 ->max('question_number') ?? 0;
+            $resolvedQuestion = app(QuestionDifficultyResolver::class)->applyCalibratedDifficulty([[
+                'id' => $question->id,
+                'difficulty' => $question->difficulty ?? 0.5,
+            ]])[0] ?? [];
+            $difficulty = $resolvedQuestion['difficulty'] ?? ($question->difficulty ?? 0.5);
 
             // 创建新的试卷题目记录
             \App\Models\PaperQuestion::create([
@@ -447,9 +453,9 @@ class ExamHistory extends Page
                 'knowledge_point' => $question->kp_code,
                 'question_type' => $this->getQuestionTypeFromQuestion($question),
                 'question_text' => $question->stem,
-                'difficulty' => $question->difficulty ?? 0.5,
-                'score' => $this->calculateScore($question->difficulty ?? 0.5),
-                'estimated_time' => $this->calculateEstimatedTime($question->difficulty ?? 0.5),
+                'difficulty' => $difficulty,
+                'score' => $this->calculateScore($difficulty),
+                'estimated_time' => $this->calculateEstimatedTime($difficulty),
                 'question_number' => $maxQuestionNumber + 1,
             ]);
 

+ 3 - 0
app/Jobs/AssembleExamTaskJob.php

@@ -5,6 +5,7 @@ namespace App\Jobs;
 use App\Models\MistakeRecord;
 use App\Services\DifficultyDistributionService;
 use App\Services\LearningAnalyticsService;
+use App\Services\QuestionDifficultyResolver;
 use App\Services\QuestionBankService;
 use App\Services\QuestionPayloadMapper;
 use App\Services\TaskManager;
@@ -150,6 +151,7 @@ class AssembleExamTaskJob implements ShouldQueue
                     }
 
                     $questions = $this->hydrateQuestions($bankQuestions, $data['kp_codes'] ?? []);
+                    $questions = app(QuestionDifficultyResolver::class)->applyCalibratedDifficulty($questions);
                     $questions = $this->sortQuestionsByRequestedIds($questions, $questionIds);
                     $paperName = $data['paper_name'] ?? ('错题再练_'.$data['student_id'].'_'.now()->format('Ymd_His'));
                 }
@@ -182,6 +184,7 @@ class AssembleExamTaskJob implements ShouldQueue
                 }
 
                 $questions = $this->hydrateQuestions($bankQuestions, $data['kp_codes'] ?? []);
+                $questions = app(QuestionDifficultyResolver::class)->applyCalibratedDifficulty($questions);
                 $questions = $this->sortQuestionsByRequestedIds($questions, $questionIds);
                 $paperName = $data['paper_name'] ?? ('错题复习_'.$data['student_id'].'_'.now()->format('Ymd_His'));
             } else {

+ 1 - 3
app/Services/LearningAnalyticsService.php

@@ -1508,9 +1508,7 @@ class LearningAnalyticsService
             // 3. 根据掌握度对题目进行筛选和排序(含追练:题量与 total_questions / default_total_questions 一致,不再按 50 拉满)
             $targetQuestionCount = min(count($allQuestions), $totalQuestions);
 
-            if (! empty($params['kp_target_counts']) || ! empty($params['max_difficulty_by_kp']) || ! empty($params['type_targets_by_kp'])) {
-                $allQuestions = app(QuestionDifficultyResolver::class)->applyCalibratedDifficulty($allQuestions);
-            }
+            $allQuestions = app(QuestionDifficultyResolver::class)->applyCalibratedDifficulty($allQuestions);
 
             $startTime = microtime(true);
             $selectedQuestions = $this->selectQuestionsByMastery(

+ 20 - 17
app/Services/QuestionDifficultyResolver.php

@@ -32,24 +32,27 @@ class QuestionDifficultyResolver
             return [];
         }
 
-        return DB::table(self::TABLE)
+        $rows = DB::table(self::TABLE)
             ->whereIn('question_bank_id', $questionIds)
-            ->get(['question_bank_id', 'original_difficulty', 'calibrated_difficulty', 'weighted_attempts'])
-            ->mapWithKeys(function ($row) {
-                $qid = (int) ($row->question_bank_id ?? 0);
-                if ($qid <= 0) {
-                    return [];
-                }
-
-                return [
-                    $qid => [
-                        'original_difficulty' => $row->original_difficulty !== null ? (float) $row->original_difficulty : null,
-                        'calibrated_difficulty' => $row->calibrated_difficulty !== null ? (float) $row->calibrated_difficulty : null,
-                        'weighted_attempts' => $row->weighted_attempts !== null ? (float) $row->weighted_attempts : null,
-                    ],
-                ];
-            })
-            ->all();
+            ->orderByDesc('updated_at')
+            ->orderByDesc('id')
+            ->get(['id', 'question_bank_id', 'original_difficulty', 'calibrated_difficulty', 'weighted_attempts']);
+
+        $map = [];
+        foreach ($rows as $row) {
+            $qid = (int) ($row->question_bank_id ?? 0);
+            if ($qid <= 0 || array_key_exists($qid, $map)) {
+                continue;
+            }
+
+            $map[$qid] = [
+                'original_difficulty' => $row->original_difficulty !== null ? (float) $row->original_difficulty : null,
+                'calibrated_difficulty' => $row->calibrated_difficulty !== null ? (float) $row->calibrated_difficulty : null,
+                'weighted_attempts' => $row->weighted_attempts !== null ? (float) $row->weighted_attempts : null,
+            ];
+        }
+
+        return $map;
     }
 
     /**