Преглед на файлове

摸底组卷题目数量补充

yemeishu преди 7 часа
родител
ревизия
cbf46c4768
променени са 3 файла, в които са добавени 378 реда и са изтрити 68 реда
  1. 27 48
      app/Services/ExamTypeStrategy.php
  2. 321 7
      app/Services/LearningAnalyticsService.php
  3. 30 13
      app/Services/QuestionLocalService.php

+ 27 - 48
app/Services/ExamTypeStrategy.php

@@ -325,21 +325,19 @@ class ExamTypeStrategy
 
         Log::info('ExamTypeStrategy: 获取到知识点(摸底测试)', [
             'kp_count' => count($kpCodes),
-            'kp_codes' => array_slice($kpCodes, 0, 5)
+            'kp_codes' => $kpCodes,
+            'textbook_id' => $textbookId,
+            'grade' => $grade,
+            'note' => '知识点数量将直接影响题目多样性'
         ]);
 
         // 摸底测试:平衡所有难度,覆盖多个知识点
+        // 【修复】移除硬编码难度配比,使用difficulty_category参数动态计算
         $enhanced = array_merge($params, [
             'kp_codes' => $kpCodes,
             'textbook_id' => $textbookId,
             'grade' => $grade,
             'catalog_chapter_ids' => $catalogChapterIds,
-            // 难度配比:相对平衡,基础题稍多
-            'difficulty_ratio' => [
-                '基础' => 40,
-                '中等' => 40,
-                '拔高' => 20,
-            ],
             // 题型配比:选择题多一些,便于快速评估
             'question_type_ratio' => [
                 '选择题' => 50,
@@ -350,10 +348,12 @@ class ExamTypeStrategy
             'paper_name' => $params['paper_name'] ?? ('摸底测试_' . now()->format('Ymd_His')),
         ]);
 
-        Log::info('ExamTypeStrategy: 摸底测试参数构建完成', [
+        Log::info('ExamTypeStrategy: 摸底测试参数构建完成(未应用难度分布)', [
             'textbook_id' => $textbookId,
             'kp_count' => count($kpCodes),
-            'total_questions' => $totalQuestions
+            'total_questions' => $totalQuestions,
+            'difficulty_category' => $params['difficulty_category'] ?? 1,
+            'note' => '将在buildParams中应用difficulty_category难度分布'
         ]);
 
         return $enhanced;
@@ -459,29 +459,8 @@ class ExamTypeStrategy
         $intensity = $practiceOptions['intensity'] ?? 'medium';
         $focusWeaknesses = $practiceOptions['focus_weaknesses'] ?? true;
 
-        // 根据强度调整难度配比
-        $difficultyRatio = match($intensity) {
-            'low' => [
-                '基础' => 60,
-                '中等' => 35,
-                '拔高' => 5,
-            ],
-            'medium' => [
-                '基础' => 45,
-                '中等' => 40,
-                '拔高' => 15,
-            ],
-            'high' => [
-                '基础' => 30,
-                '中等' => 45,
-                '拔高' => 25,
-            ],
-            default => [
-                '基础' => 45,
-                '中等' => 40,
-                '拔高' => 15,
-            ]
-        };
+        // 【修复】移除硬编码难度配比,专项练习使用difficulty_category参数
+        // 注意:强度调节逻辑已移除,统一使用difficulty_category控制难度分布
 
         // 获取学生薄弱点
         $weaknessFilter = [];
@@ -504,7 +483,6 @@ class ExamTypeStrategy
         }
 
         $enhanced = array_merge($params, [
-            'difficulty_ratio' => $difficultyRatio,
             'kp_codes' => $kpCodes,
             // 专项练习更注重题型覆盖
             'question_type_ratio' => [
@@ -518,11 +496,12 @@ class ExamTypeStrategy
             'weakness_filter' => $weaknessFilter,
         ]);
 
-        Log::info('ExamTypeStrategy: 专项练习参数构建完成', [
+        Log::info('ExamTypeStrategy: 专项练习参数构建完成(未应用难度分布)', [
             'intensity' => $intensity,
-            'difficulty_ratio' => $enhanced['difficulty_ratio'],
+            'difficulty_category' => $params['difficulty_category'] ?? 1,
             'kp_codes_count' => count($enhanced['kp_codes']),
-            'weakness_count' => count($weaknessFilter)
+            'weakness_count' => count($weaknessFilter),
+            'note' => '将在buildParams中应用difficulty_category难度分布'
         ]);
 
         return $enhanced;
@@ -536,15 +515,10 @@ class ExamTypeStrategy
         Log::info('ExamTypeStrategy: 构建教材同步参数', $params);
 
         // 教材同步:按章节顺序,难度递增
+        // 【修复】移除硬编码难度配比,使用difficulty_category参数
         $textbookOptions = $params['textbook_options'] ?? [];
 
         $enhanced = array_merge($params, [
-            // 教材同步:基础和中等题为主
-            'difficulty_ratio' => [
-                '基础' => 50,
-                '中等' => 40,
-                '拔高' => 10,
-            ],
             'question_type_ratio' => [
                 '选择题' => 40,
                 '填空题' => 30,
@@ -554,6 +528,11 @@ class ExamTypeStrategy
             'textbook_options' => $textbookOptions,
         ]);
 
+        Log::info('ExamTypeStrategy: 教材同步参数构建完成(未应用难度分布)', [
+            'difficulty_category' => $params['difficulty_category'] ?? 1,
+            'note' => '将在buildParams中应用difficulty_category难度分布'
+        ]);
+
         return $enhanced;
     }
 
@@ -565,15 +544,10 @@ class ExamTypeStrategy
         Log::info('ExamTypeStrategy: 构建知识点专练参数', $params);
 
         // 知识点专练:深度挖掘,多角度考查
+        // 【修复】移除硬编码难度配比,使用difficulty_category参数
         $knowledgeOptions = $params['knowledge_options'] ?? [];
 
         $enhanced = array_merge($params, [
-            // 知识点专练:难度分布更均匀
-            'difficulty_ratio' => [
-                '基础' => 35,
-                '中等' => 45,
-                '拔高' => 20,
-            ],
             'question_type_ratio' => [
                 '选择题' => 30,
                 '填空题' => 35,
@@ -583,6 +557,11 @@ class ExamTypeStrategy
             'knowledge_options' => $knowledgeOptions,
         ]);
 
+        Log::info('ExamTypeStrategy: 知识点专练参数构建完成(未应用难度分布)', [
+            'difficulty_category' => $params['difficulty_category'] ?? 1,
+            'note' => '将在buildParams中应用difficulty_category难度分布'
+        ]);
+
         return $enhanced;
     }
 

+ 321 - 7
app/Services/LearningAnalyticsService.php

@@ -1555,7 +1555,9 @@ class LearningAnalyticsService
 
                     Log::info('LearningAnalyticsService: 难度分布应用完成', [
                         'difficulty_category_after' => $difficultyCategory,
-                        'after_count' => count($selectedQuestions)
+                        'before_count' => count($selectedQuestions),
+                        'after_count' => count($selectedQuestions),
+                        'success' => count($selectedQuestions) >= $totalQuestions
                     ]);
                 } catch (\Exception $e) {
                     Log::warning('LearningAnalyticsService: 难度分布应用失败,继续使用原结果', [
@@ -1730,9 +1732,39 @@ class LearningAnalyticsService
             // 让上层调用者根据需要选择题目数量
             $selectedQuestions = $formattedQuestions;
 
+            // 【修复】重新启用智能补充功能
+            if (count($selectedQuestions) < $totalNeeded) {
+                $deficit = $totalNeeded - count($selectedQuestions);
+                Log::warning('getQuestionsFromBank: 指定知识点题目不足,尝试智能补充', [
+                    'deficit' => $deficit,
+                    'available_count' => count($selectedQuestions),
+                    'strategy' => '从同年级其他知识点或相邻难度补充'
+                ]);
+
+                // 补充策略:从同年级其他知识点补充
+                $supplementaryQuestions = $this->getSupplementaryQuestionsForGrade(
+                    $params['grade'] ?? 9,
+                    array_column($selectedQuestions, 'kp_code'),
+                    $deficit,
+                    $params['difficulty_category'] ?? 1
+                );
+
+                if (!empty($supplementaryQuestions)) {
+                    $selectedQuestions = array_merge($selectedQuestions, $supplementaryQuestions);
+                    Log::info('getQuestionsFromBank: 智能补充完成', [
+                        'supplementary_count' => count($supplementaryQuestions),
+                        'total_after_supplement' => count($selectedQuestions)
+                    ]);
+                } else {
+                    Log::warning('getQuestionsFromBank: 智能补充失败,未找到合适的题目');
+                }
+            }
+
             Log::info('getQuestionsFromBank 完成', [
                 'final_count' => count($selectedQuestions),
                 'raw_database_count' => $questions->count(),
+                'total_needed' => $totalNeeded,
+                'success' => count($selectedQuestions) >= $totalNeeded,
                 'time_ms' => round((microtime(true) - $startTime) * 1000, 2)
             ]);
 
@@ -1948,7 +1980,10 @@ class LearningAnalyticsService
         Log::info('selectQuestionsByMastery 开始', [
             'question_count' => count($questions),
             'student_id' => $studentId,
-            'total_questions' => $totalQuestions
+            'total_questions' => $totalQuestions,
+            'unique_kp_count' => count(array_unique(array_column($questions, 'kp_code'))),
+            'assemble_type' => $assembleType,
+            'note' => '追踪输入题目数量和知识点多样性'
         ]);
 
         // 【修复】题目数量处理逻辑:无论题目数量多少,都要进行权重分配和筛选
@@ -2133,18 +2168,47 @@ class LearningAnalyticsService
                 return $weightB <=> $weightA;
             });
 
+            // 【修复】摸底测试题型基础分配:记录每个题型的知识点分布
+            $typeKpDistribution = [];
+            foreach ($questionsByType[$type] as $q) {
+                $kpCode = $q['kp_code'] ?? '';
+                if (!isset($typeKpDistribution[$kpCode])) {
+                    $typeKpDistribution[$kpCode] = 0;
+                }
+                $typeKpDistribution[$kpCode]++;
+            }
+
+            Log::info('摸底测试题型基础分配开始', [
+                'type' => $type,
+                'total_questions_in_type' => count($questionsByType[$type]),
+                'kp_distribution_in_type' => $typeKpDistribution,
+                'available_kp_count' => count($typeKpDistribution)
+            ]);
+
             // 根据策略选择题目
             if ($useKnowledgePointPriority) {
                 // 摸底测试:选择第一个未选过知识点的题目
+                $selectedInThisType = 0;
                 foreach ($questionsByType[$type] as $q) {
                     $kpCode = $q['kp_code'] ?? '';
                     if (!isset($kpSelected[$kpCode])) {
                         $selectedQuestions[] = $q;
                         $kpSelected[$kpCode] = true;
-                        Log::debug('题型基础分配(知识点优先)', ['type' => $type, 'kp' => $kpCode]);
-                        break;
+                        $selectedInThisType++;
+                        Log::debug('题型基础分配(知识点优先)', [
+                            'type' => $type,
+                            'kp' => $kpCode,
+                            'question_id' => $q['id'] ?? 'unknown',
+                            'selected_in_type' => $selectedInThisType
+                        ]);
+                        break; // 只选1题
                     }
                 }
+                Log::info('摸底测试题型基础分配完成', [
+                    'type' => $type,
+                    'selected_count' => $selectedInThisType,
+                    'note' => $selectedInThisType > 0 ? '成功选择' : '无可用知识点'
+                ]);
             } else {
                 // 【修复】知识点组卷:随机选择该题型的一道题,避免固定选择第一个导致知识点分布不均
                 $randomIndex = array_rand($questionsByType[$type]);
@@ -2217,9 +2281,19 @@ class LearningAnalyticsService
             'note' => '观察排序是否均衡分布A07和A08'
         ]);
 
-        // 根据策略继续选择题目
+        // 【修复】摸底测试继续选择题目:记录详细的选题过程
+        Log::info('摸底测试继续选择题目开始', [
+            'selected_count_after_basic' => count($selectedQuestions),
+            'total_questions' => $totalQuestions,
+            'selected_kp_codes' => array_keys($kpSelected),
+            'available_kp_count' => count($preSortKpDistribution),
+            'strategy' => $useKnowledgePointPriority ? '知识点优先' : '无知识点限制'
+        ]);
+
         if ($useKnowledgePointPriority) {
-            // 摸底测试:选择未选过知识点的题目(优先)
+            // 摸底测试:优先选择未选过知识点的题目
+            $initialSelectedCount = count($selectedQuestions);
+            $prioritySelectedCount = 0;
             foreach ($allQuestions as $q) {
                 if (count($selectedQuestions) >= $totalQuestions) break;
 
@@ -2227,8 +2301,58 @@ class LearningAnalyticsService
                 if (!isset($kpSelected[$kpCode])) {
                     $selectedQuestions[] = $q;
                     $kpSelected[$kpCode] = true;
-                    Log::debug('继续选择题目(知识点优先)', ['kp' => $kpCode, 'id' => $q['id'] ?? 'unknown']);
+                    $prioritySelectedCount++;
+                    Log::debug('继续选择题目(知识点优先)', [
+                        'kp' => $kpCode,
+                        'id' => $q['id'] ?? 'unknown',
+                        'priority_selected_count' => $prioritySelectedCount,
+                        'total_selected' => count($selectedQuestions)
+                    ]);
+                }
+            }
+
+            Log::info('摸底测试优先阶段完成', [
+                'priority_selected_count' => $prioritySelectedCount,
+                'total_selected' => count($selectedQuestions),
+                'unique_kp_count' => count($kpSelected),
+                'note' => '优先选择未选过知识点的题目'
+            ]);
+
+            // 【修复】降级策略:如果仍未达到目标数量,允许重复选择知识点
+            if (count($selectedQuestions) < $totalQuestions) {
+                Log::warning('selectQuestionsByMastery: 知识点优先策略无法满足数量要求,启用降级策略', [
+                    'requested_count' => $totalQuestions,
+                    'selected_count' => count($selectedQuestions),
+                    'priority_selected_count' => $prioritySelectedCount,
+                    'unique_kp_count' => count($kpSelected),
+                    'available_kp_count' => count($preSortKpDistribution),
+                    'note' => '将允许重复选择知识点以达到目标数量'
+                ]);
+
+                $fallbackSelectedCount = 0;
+                $selectedIds = array_column($selectedQuestions, 'id');
+                foreach ($allQuestions as $q) {
+                    if (count($selectedQuestions) >= $totalQuestions) break;
+
+                    $qid = $q['id'] ?? null;
+                    if ($qid && !in_array($qid, $selectedIds)) {
+                        $selectedQuestions[] = $q;
+                        $selectedIds[] = $qid;
+                        $fallbackSelectedCount++;
+                        Log::debug('降级选择题目(允许知识点重复)', [
+                            'kp' => $q['kp_code'] ?? 'unknown',
+                            'id' => $qid,
+                            'fallback_selected_count' => $fallbackSelectedCount,
+                            'current_count' => count($selectedQuestions)
+                        ]);
+                    }
                 }
+
+                Log::info('摸底测试降级阶段完成', [
+                    'fallback_selected_count' => $fallbackSelectedCount,
+                    'total_selected' => count($selectedQuestions),
+                    'note' => '允许重复选择知识点补充数量'
+                ]);
             }
         } else {
             // 知识点组卷:选择未选过的题目(不要求知识点不重复)
@@ -2280,6 +2404,17 @@ class LearningAnalyticsService
             'is_array' => is_array($selectedQuestions)
         ]);
 
+        // 【新增】最终知识点分布统计
+        $finalKpDistribution = array_count_values(array_column($selectedQuestions, 'kp_code'));
+        Log::info('摸底测试最终知识点分布', [
+            'final_total_count' => count($selectedQuestions),
+            'target_count' => $totalQuestions,
+            'final_kp_distribution' => $finalKpDistribution,
+            'unique_kp_count' => count($finalKpDistribution),
+            'success' => count($selectedQuestions) === $totalQuestions,
+            'kp_coverage_rate' => count($finalKpDistribution) / max(count($preSortKpDistribution), 1) * 100
+        ]);
+
         // ========== 最终排查:确保无重复题目且题型分布合理 ==========
         $finalQuestions = [];
         $seenQuestionIds = [];
@@ -2739,4 +2874,183 @@ class LearningAnalyticsService
             'message' => 'analysis_api_disabled',
         ];
     }
+
+    /**
+     * 【新增】为指定年级智能补充题目
+     * 当指定知识点题目不足时,从同年级其他知识点补充
+     */
+    private function getSupplementaryQuestionsForGrade(
+        int $grade,
+        array $existingKpCodes,
+        int $needCount,
+        int $difficultyCategory
+    ): array {
+        try {
+            Log::info('getSupplementaryQuestionsForGrade: 开始智能补充', [
+                'grade' => $grade,
+                'existing_kp_count' => count($existingKpCodes),
+                'need_count' => $needCount,
+                'difficulty_category' => $difficultyCategory
+            ]);
+
+            // 查询同年级其他知识点的题目
+            $query = \App\Models\Question::query();
+
+            // 排除已选知识点
+            if (!empty($existingKpCodes)) {
+                $query->whereNotIn('kp_code', $existingKpCodes);
+            }
+
+            // 限制同年级(通过教材关联)
+            $gradeKpCodes = $this->getGradeKnowledgePoints($grade);
+            if (!empty($gradeKpCodes)) {
+                $query->whereIn('kp_code', $gradeKpCodes);
+            }
+
+            // 筛选有解题思路的题目
+            $query->whereNotNull('solution')
+                  ->where('solution', '!=', '')
+                  ->where('solution', '!=', '[]');
+
+            // 【重要】移除题目分类限制,允许补充其他分类的题目
+            // $query->where('question_category', 1); // 移除这行
+
+            // 根据难度类别调整查询
+            $difficultyRanges = $this->getDifficultyRangesForCategory($difficultyCategory);
+            $query->where(function ($q) use ($difficultyRanges) {
+                foreach ($difficultyRanges as $range) {
+                    $q->orWhereBetween('difficulty', [$range['min'], $range['max']]);
+                }
+            });
+
+            // 随机排序,增加多样性
+            $query->inRandomOrder()
+                  ->limit($needCount * 2); // 多取一些,后续筛选
+
+            $supplementaryQuestions = $query->get();
+
+            Log::info('getSupplementaryQuestionsForGrade: 查询完成', [
+                'found_count' => $supplementaryQuestions->count(),
+                'need_count' => $needCount
+            ]);
+
+            // 格式化题目
+            $formatted = [];
+            foreach ($supplementaryQuestions as $question) {
+                // 手动判断题目类型,避免类型问题
+                $stem = $question->stem ?? '';
+                $options = is_array($question->options) ? $question->options : (json_decode($question->options ?? '[]', true) ?: []);
+                $correctAnswer = $question->correct_answer ?? '';
+
+                // 简单判断逻辑
+                if (!empty($options) && is_array($options) && count($options) >= 2) {
+                    $questionType = 'choice';
+                } elseif (!empty($correctAnswer) && (strlen($correctAnswer) <= 10 || strpos($correctAnswer, '|') !== false)) {
+                    $questionType = 'fill';
+                } else {
+                    $questionType = 'answer';
+                }
+
+                $formatted[] = [
+                    'id' => $question->id,
+                    'question_bank_id' => $question->id,
+                    'question_type' => $questionType,
+                    'kp_code' => $question->kp_code,
+                    'difficulty' => (float) $question->difficulty,
+                    'stem' => $stem,
+                    'options' => $options,
+                    'correct_answer' => $correctAnswer,
+                    'solution' => $question->solution,
+                    'score' => $question->score ?? 4,
+                    'estimated_time' => $question->estimated_time ?? 300,
+                    'metadata' => [
+                        'question_type_label' => $questionType === 'choice' ? '选择题' : ($questionType === 'fill' ? '填空题' : '解答题'),
+                        'difficulty_label' => $this->getDifficultyLabelFromObject($question->difficulty),
+                        'is_supplementary' => true
+                    ]
+                ];
+            }
+
+            // 随机选择需要的数量
+            shuffle($formatted);
+            $selected = array_slice($formatted, 0, $needCount);
+
+            Log::info('getSupplementaryQuestionsForGrade: 补充完成', [
+                'supplementary_count' => count($selected),
+                'kp_distribution' => array_count_values(array_column($selected, 'kp_code'))
+            ]);
+
+            return $selected;
+
+        } catch (\Exception $e) {
+            Log::error('getSupplementaryQuestionsForGrade: 补充失败', [
+                'grade' => $grade,
+                'need_count' => $needCount,
+                'error' => $e->getMessage()
+            ]);
+            return [];
+        }
+    }
+
+    /**
+     * 【新增】获取指定年级的所有知识点
+     */
+    private function getGradeKnowledgePoints(int $grade): array
+    {
+        try {
+            $kpCodes = DB::table('textbook_chapter_knowledge_relation as tckr')
+                ->join('textbook_catalog_nodes as tcn', 'tckr.catalog_chapter_id', '=', 'tcn.id')
+                ->join('textbooks as t', 'tcn.textbook_id', '=', 't.id')
+                ->where('t.grade', $grade)
+                ->distinct()
+                ->pluck('tckr.kp_code')
+                ->toArray();
+
+            return array_filter($kpCodes);
+        } catch (\Exception $e) {
+            Log::error('getGradeKnowledgePoints: 查询失败', [
+                'grade' => $grade,
+                'error' => $e->getMessage()
+            ]);
+            return [];
+        }
+    }
+
+    /**
+     * 【新增】根据难度类别获取难度范围
+     */
+    private function getDifficultyRangesForCategory(int $difficultyCategory): array
+    {
+        return match($difficultyCategory) {
+            1 => [
+                ['min' => 0.0, 'max' => 0.5],  // 基础型:偏向低难度
+                ['min' => 0.5, 'max' => 1.0],
+            ],
+            2 => [
+                ['min' => 0.0, 'max' => 0.5],  // 进阶型:均衡分布
+                ['min' => 0.5, 'max' => 1.0],
+            ],
+            3 => [
+                ['min' => 0.25, 'max' => 0.75], // 中等型:偏向中等难度
+                ['min' => 0.0, 'max' => 1.0],
+            ],
+            4 => [
+                ['min' => 0.5, 'max' => 1.0],  // 拔高型:偏向高难度
+                ['min' => 0.0, 'max' => 0.5],
+            ],
+            default => [
+                ['min' => 0.0, 'max' => 1.0],
+            ]
+        };
+    }
+
+    /**
+     * 【新增】获取难度标签(重载版本)
+     */
+    private function getDifficultyLabelFromObject(float $difficulty): string
+    {
+        if ($difficulty < 0.3) return '基础';
+        if ($difficulty < 0.7) return '中等';
+        return '拔高';
+    }
 }

+ 30 - 13
app/Services/QuestionLocalService.php

@@ -636,13 +636,25 @@ class QuestionLocalService
                 }
             }
 
-            Log::debug('QuestionLocalService: 难度层级选择', [
-                'level' => $level,
-                'target' => $targetCount,
-                'actual' => $taken,
-                'bucket_size' => count($bucket),
-                'range_key' => $rangeKey
-            ]);
+            // 【修复】如果某个难度范围题目不足,记录日志但不截断
+            if ($taken < $targetCount) {
+                Log::warning('QuestionLocalService: 难度范围题目不足,允许后续补充', [
+                    'level' => $level,
+                    'range_key' => $rangeKey,
+                    'target' => $targetCount,
+                    'actual' => $taken,
+                    'bucket_size' => count($bucket),
+                    'note' => '将在后续步骤中从其他范围补充题目'
+                ]);
+            } else {
+                Log::debug('QuestionLocalService: 难度层级选择', [
+                    'level' => $level,
+                    'target' => $targetCount,
+                    'actual' => $taken,
+                    'bucket_size' => count($bucket),
+                    'range_key' => $rangeKey
+                ]);
+            }
         }
 
         Log::info('QuestionLocalService: 分布选择后统计', [
@@ -653,9 +665,11 @@ class QuestionLocalService
 
         // 如果数量不足,从剩余题目中补充
         if (count($selected) < $totalQuestions) {
-            Log::info('QuestionLocalService: 开始补充题目', [
+            Log::warning('QuestionLocalService: 开始补充题目(难度分布无法满足要求)', [
                 'need_more' => $totalQuestions - count($selected),
-                'selected_count' => count($selected)
+                'selected_count' => count($selected),
+                'difficulty_category' => $difficultyCategory,
+                'note' => '由于难度分布限制,将从所有剩余题目中补充'
             ]);
 
             $remaining = [];
@@ -671,13 +685,16 @@ class QuestionLocalService
                 'need_more' => $totalQuestions - count($selected)
             ]);
 
+            // 【修复】打乱剩余题目顺序,确保随机性
             shuffle($remaining);
             $needMore = $totalQuestions - count($selected);
-            $selected = array_merge($selected, array_slice($remaining, 0, $needMore));
+            $supplementCount = min($needMore, count($remaining));
+            $selected = array_merge($selected, array_slice($remaining, 0, $supplementCount));
 
-            Log::info('QuestionLocalService: 补充完成', [
-                'supplement_added' => $needMore,
-                'final_count_before_truncate' => count($selected)
+            Log::warning('QuestionLocalService: 补充完成', [
+                'supplement_added' => $supplementCount,
+                'final_count_before_truncate' => count($selected),
+                'remaining_unused' => count($remaining) - $supplementCount
             ]);
         }