Parcourir la source

处理卷子100分严格计算的问题

yemeishu il y a 1 jour
Parent
commit
68478593bc
1 fichiers modifiés avec 59 ajouts et 6 suppressions
  1. 59 6
      app/Filament/Pages/IntelligentExamGeneration.php

+ 59 - 6
app/Filament/Pages/IntelligentExamGeneration.php

@@ -1596,29 +1596,82 @@ Cache::put('generated_exam_' . $paperId, $examData, now()->addHour());
                     : $typeStats['choice']['indices']);
 
             if (!empty($adjustIndices)) {
-                $adjustPerQuestion = intval($diff / count($adjustIndices));
-                $remainder = $diff % count($adjustIndices);
+                // 使用更精确的调整算法,避免intval()损失精度
+                $adjustPerQuestion = $diff / count($adjustIndices);
 
                 foreach ($adjustIndices as $i => $idx) {
-                    $adjustment = $adjustPerQuestion + ($i < abs($remainder) ? ($remainder > 0 ? 1 : -1) : 0);
+                    $adjustment = round($adjustPerQuestion);
                     $questions[$idx]['score'] = max(1, $questions[$idx]['score'] + $adjustment);
                 }
             }
         }
 
-        // 最终验证
+        // 最终验证并强制约束总分严格等于目标值
         $scores = array_column($questions, 'score');
         // 确保所有分数都是数字
         $scores = array_map(function($s) {
             return is_numeric($s) ? (float)$s : 0;
         }, $scores);
         $finalTotal = array_sum($scores);
+
+        // 硬性约束:如果总分不等于目标值,强制修正
+        if (abs($finalTotal - $totalScore) > 0.01) {
+            $totalDiff = $totalScore - $finalTotal;
+
+            // 优先从解答题调整,如果不够再从其他题型调整
+            $allAnswerIndices = $typeStats['answer']['indices'];
+            if (empty($allAnswerIndices)) {
+                $allAnswerIndices = array_merge($typeStats['fill']['indices'], $typeStats['choice']['indices']);
+            }
+
+            if (!empty($allAnswerIndices)) {
+                // 计算每题需要调整的平均值
+                $adjustPerQuestion = $totalDiff / count($allAnswerIndices);
+
+                foreach ($allAnswerIndices as $i => $idx) {
+                    $currentScore = $questions[$idx]['score'];
+                    $newScore = max(1, round($currentScore + $adjustPerQuestion));
+                    $questions[$idx]['score'] = (int)$newScore;
+                }
+
+                // 重新计算最终总分
+                $scores = array_column($questions, 'score');
+                $finalTotal = array_sum($scores);
+
+                \Illuminate\Support\Facades\Log::info("已执行硬性约束修正总分", [
+                    'target_score' => $totalScore,
+                    'before_adjust' => $finalTotal - $totalDiff,
+                    'after_adjust' => $finalTotal,
+                    'adjust_per_question' => round($adjustPerQuestion, 2)
+                ]);
+            }
+        }
+
+        // 双重保险:确保最终总分严格等于目标值
+        $finalScores = array_column($questions, 'score');
+        $finalTotal = array_sum($finalScores);
+        if ($finalTotal !== $totalScore) {
+            // 如果还是不相等,强制调整第一道题的分数
+            $forceDiff = $totalScore - $finalTotal;
+            $questions[0]['score'] += $forceDiff;
+            $questions[0]['score'] = max(1, $questions[0]['score']);
+
+            \Illuminate\Support\Facades\Log::warning("执行强制修正总分", [
+                'target_score' => $totalScore,
+                'before_force_adjust' => $finalTotal,
+                'after_force_adjust' => array_sum(array_column($questions, 'score')),
+                'force_adjust_question' => 0,
+                'force_adjust_amount' => $forceDiff
+            ]);
+        }
+
         \Illuminate\Support\Facades\Log::info("分数分配完成", [
             'target_score' => $totalScore,
-            'final_total' => $finalTotal,
+            'final_total' => array_sum(array_column($questions, 'score')),
             'choice_score_each' => $choiceScore,
             'fill_score_each' => $fillScore,
-            'answer_score_each' => $answerScore
+            'answer_score_each' => $answerScore,
+            'is_strict_100' => array_sum(array_column($questions, 'score')) === $totalScore ? '是' : '否'
         ]);
 
         return $questions;