|
@@ -1504,14 +1504,32 @@ class LearningAnalyticsService
|
|
|
|
|
|
|
|
// 4. 如果题目过多,按权重排序后截取
|
|
// 4. 如果题目过多,按权重排序后截取
|
|
|
if (count($selectedQuestions) > $totalQuestions) {
|
|
if (count($selectedQuestions) > $totalQuestions) {
|
|
|
|
|
+ Log::info('开始按权重排序题目', [
|
|
|
|
|
+ 'before_sort_count' => count($selectedQuestions),
|
|
|
|
|
+ 'target_count' => $totalQuestions
|
|
|
|
|
+ ]);
|
|
|
|
|
+
|
|
|
|
|
+ $startTime = microtime(true);
|
|
|
usort($selectedQuestions, function ($a, $b) use ($kpWeights) {
|
|
usort($selectedQuestions, function ($a, $b) use ($kpWeights) {
|
|
|
$weightA = $kpWeights[$a['kp_code']] ?? 1.0;
|
|
$weightA = $kpWeights[$a['kp_code']] ?? 1.0;
|
|
|
$weightB = $kpWeights[$b['kp_code']] ?? 1.0;
|
|
$weightB = $kpWeights[$b['kp_code']] ?? 1.0;
|
|
|
return $weightB <=> $weightA;
|
|
return $weightB <=> $weightA;
|
|
|
});
|
|
});
|
|
|
|
|
+ $sortTime = (microtime(true) - $startTime) * 1000;
|
|
|
|
|
+
|
|
|
|
|
+ Log::info('权重排序完成', [
|
|
|
|
|
+ 'sort_time_ms' => round($sortTime, 2),
|
|
|
|
|
+ 'after_sort_count' => count($selectedQuestions)
|
|
|
|
|
+ ]);
|
|
|
|
|
+
|
|
|
$selectedQuestions = array_slice($selectedQuestions, 0, $totalQuestions);
|
|
$selectedQuestions = array_slice($selectedQuestions, 0, $totalQuestions);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ Log::info('开始题型配比调整', [
|
|
|
|
|
+ 'input_count' => count($selectedQuestions),
|
|
|
|
|
+ 'target_count' => $totalQuestions
|
|
|
|
|
+ ]);
|
|
|
|
|
+
|
|
|
// 5. 按题型和难度进行微调
|
|
// 5. 按题型和难度进行微调
|
|
|
return $this->adjustQuestionsByRatio($selectedQuestions, $questionTypeRatio, $difficultyRatio, $totalQuestions);
|
|
return $this->adjustQuestionsByRatio($selectedQuestions, $questionTypeRatio, $difficultyRatio, $totalQuestions);
|
|
|
}
|
|
}
|
|
@@ -1549,6 +1567,9 @@ class LearningAnalyticsService
|
|
|
'type_ratio' => $typeRatio
|
|
'type_ratio' => $typeRatio
|
|
|
]);
|
|
]);
|
|
|
|
|
|
|
|
|
|
+ // 缓存题目类型,避免重复计算
|
|
|
|
|
+ $questionTypeCache = [];
|
|
|
|
|
+
|
|
|
// 按题型分桶
|
|
// 按题型分桶
|
|
|
$buckets = [
|
|
$buckets = [
|
|
|
'choice' => [],
|
|
'choice' => [],
|
|
@@ -1556,7 +1577,17 @@ class LearningAnalyticsService
|
|
|
'answer' => [],
|
|
'answer' => [],
|
|
|
];
|
|
];
|
|
|
foreach ($questions as $q) {
|
|
foreach ($questions as $q) {
|
|
|
- $type = $this->determineQuestionType($q);
|
|
|
|
|
|
|
+ $qid = $q['id'] ?? $q['question_id'] ?? null;
|
|
|
|
|
+
|
|
|
|
|
+ if ($qid && isset($questionTypeCache[$qid])) {
|
|
|
|
|
+ $type = $questionTypeCache[$qid];
|
|
|
|
|
+ } else {
|
|
|
|
|
+ $type = $this->determineQuestionType($q);
|
|
|
|
|
+ if ($qid) {
|
|
|
|
|
+ $questionTypeCache[$qid] = $type;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
if (!isset($buckets[$type])) {
|
|
if (!isset($buckets[$type])) {
|
|
|
$type = 'answer';
|
|
$type = 'answer';
|
|
|
}
|
|
}
|
|
@@ -1626,14 +1657,24 @@ class LearningAnalyticsService
|
|
|
// 截断至目标数
|
|
// 截断至目标数
|
|
|
$selected = array_slice($selected, 0, $targetCount);
|
|
$selected = array_slice($selected, 0, $targetCount);
|
|
|
|
|
|
|
|
|
|
+ // 使用缓存统计题型分布
|
|
|
|
|
+ $selectedCounts = ['choice' => 0, 'fill' => 0, 'answer' => 0];
|
|
|
|
|
+ foreach ($selected as $q) {
|
|
|
|
|
+ $qid = $q['id'] ?? $q['question_id'] ?? null;
|
|
|
|
|
+ if ($qid && isset($questionTypeCache[$qid])) {
|
|
|
|
|
+ $type = $questionTypeCache[$qid];
|
|
|
|
|
+ } else {
|
|
|
|
|
+ $type = $this->determineQuestionType($q);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (isset($selectedCounts[$type])) {
|
|
|
|
|
+ $selectedCounts[$type]++;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
Log::info('题型配比调整完成', [
|
|
Log::info('题型配比调整完成', [
|
|
|
'target_count' => $targetCount,
|
|
'target_count' => $targetCount,
|
|
|
'targets' => $targets,
|
|
'targets' => $targets,
|
|
|
- 'selected_counts' => [
|
|
|
|
|
- 'choice' => count(array_filter($selected, fn($q) => $this->determineQuestionType($q) === 'choice')),
|
|
|
|
|
- 'fill' => count(array_filter($selected, fn($q) => $this->determineQuestionType($q) === 'fill')),
|
|
|
|
|
- 'answer' => count(array_filter($selected, fn($q) => $this->determineQuestionType($q) === 'answer')),
|
|
|
|
|
- ],
|
|
|
|
|
|
|
+ 'selected_counts' => $selectedCounts,
|
|
|
'final_selected_count' => count($selected)
|
|
'final_selected_count' => count($selected)
|
|
|
]);
|
|
]);
|
|
|
|
|
|