|
|
@@ -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;
|