SimilarQuestions.php 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. <?php
  2. namespace App\View\Components\ExamAnalysis;
  3. use Illuminate\View\Component;
  4. use App\Services\QuestionBankService;
  5. use App\Services\KnowledgeGraphService;
  6. class SimilarQuestions extends Component
  7. {
  8. public array $similarQuestions = [];
  9. public array $knowledgePoint = [];
  10. public function __construct(
  11. public ?string $kpCode = null,
  12. public ?array $currentQuestion = null
  13. ) {
  14. if ($kpCode && $currentQuestion) {
  15. $this->knowledgePoint = $currentQuestion['knowledge_point'] ?? [];
  16. $this->similarQuestions = $this->getSimilarQuestions($kpCode);
  17. }
  18. }
  19. /**
  20. * 获取相似题目
  21. */
  22. protected function getSimilarQuestions(string $kpCode): array
  23. {
  24. $questions = [];
  25. try {
  26. // 1. 根据知识点从题库获取相似题目
  27. $questionBankService = app(QuestionBankService::class);
  28. // 确定难度:如果当前题目答错,推荐简单或同等难度的题目
  29. $difficulty = 'all';
  30. if (isset($this->currentQuestion['is_correct']) && !$this->currentQuestion['is_correct']) {
  31. $difficulty = 'easy'; // 推荐简单题目
  32. }
  33. // 调用题库API获取相似题目
  34. $response = $questionBankService->filterQuestions([
  35. 'kp_codes' => $kpCode,
  36. 'difficulty' => $difficulty,
  37. 'per_page' => 5,
  38. 'exclude_id' => $this->currentQuestion['question_bank_id'] ?? null
  39. ]);
  40. if (isset($response['data']) && !empty($response['data'])) {
  41. foreach ($response['data'] as $index => $q) {
  42. $questions[] = [
  43. 'id' => $q['id'] ?? $q['question_id'] ?? uniqid(),
  44. 'title' => $q['stem'] ?? $q['content'] ?? '题目内容',
  45. 'difficulty' => $this->getDifficultyLabel($q['difficulty'] ?? 'medium'),
  46. 'difficulty_color' => $this->getDifficultyColor($q['difficulty'] ?? 'medium'),
  47. 'estimated_time' => $this->getEstimatedTime($q['difficulty'] ?? 'medium'),
  48. 'question_type' => $q['question_type'] ?? '选择题',
  49. 'score' => $q['score'] ?? 5,
  50. 'knowledge_point' => $this->knowledgePoint['name'] ?? $kpCode,
  51. ];
  52. }
  53. }
  54. // 2. 如果题库没有足够的相似题目,使用推荐算法生成
  55. if (count($questions) < 2) {
  56. $questions = array_merge($questions, $this->generateRecommendedQuestions($kpCode));
  57. }
  58. } catch (\Exception $e) {
  59. \Log::error('获取相似题目失败', [
  60. 'kp_code' => $kpCode,
  61. 'error' => $e->getMessage()
  62. ]);
  63. // 返回默认推荐题目
  64. $questions = $this->getDefaultRecommendations($kpCode);
  65. }
  66. return array_slice($questions, 0, 3); // 最多返回3道题
  67. }
  68. /**
  69. * 生成推荐题目
  70. */
  71. protected function generateRecommendedQuestions(string $kpCode): array
  72. {
  73. // 基于知识点生成推荐题目的描述
  74. $recommendations = [];
  75. $kpName = $this->knowledgePoint['name'] ?? $kpCode;
  76. // 根据掌握程度推荐不同类型的题目
  77. if (isset($this->currentQuestion['is_correct']) && !$this->currentQuestion['is_correct']) {
  78. // 答错的题目,推荐基础练习
  79. $recommendations[] = [
  80. 'id' => 'rec_1',
  81. 'title' => "{$kpName}基础练习题 - 巩固核心概念",
  82. 'difficulty' => '简单',
  83. 'difficulty_color' => 'green',
  84. 'estimated_time' => '3分钟',
  85. 'question_type' => '基础题',
  86. 'score' => 3,
  87. 'knowledge_point' => $kpName,
  88. ];
  89. $recommendations[] = [
  90. 'id' => 'rec_2',
  91. 'title' => "{$kpName}变式练习题 - 提升解题能力",
  92. 'difficulty' => '中等',
  93. 'difficulty_color' => 'blue',
  94. 'estimated_time' => '5分钟',
  95. 'question_type' => '变式题',
  96. 'score' => 5,
  97. 'knowledge_point' => $kpName,
  98. ];
  99. } else {
  100. // 答对的题目,推荐提高练习
  101. $recommendations[] = [
  102. 'id' => 'rec_3',
  103. 'title' => "{$kpName}提高题 - 挑战更高难度",
  104. 'difficulty' => '较难',
  105. 'difficulty_color' => 'red',
  106. 'estimated_time' => '8分钟',
  107. 'question_type' => '提高题',
  108. 'score' => 8,
  109. 'knowledge_point' => $kpName,
  110. ];
  111. }
  112. return $recommendations;
  113. }
  114. /**
  115. * 获取默认推荐
  116. */
  117. protected function getDefaultRecommendations(string $kpCode): array
  118. {
  119. return [
  120. [
  121. 'id' => 'default_1',
  122. 'title' => '相关知识点基础练习',
  123. 'difficulty' => '简单',
  124. 'difficulty_color' => 'green',
  125. 'estimated_time' => '3分钟',
  126. 'question_type' => '基础题',
  127. 'score' => 3,
  128. 'knowledge_point' => $this->knowledgePoint['name'] ?? $kpCode,
  129. ],
  130. [
  131. 'id' => 'default_2',
  132. 'title' => '相关知识点综合练习',
  133. 'difficulty' => '中等',
  134. 'difficulty_color' => 'blue',
  135. 'estimated_time' => '5分钟',
  136. 'question_type' => '综合题',
  137. 'score' => 5,
  138. 'knowledge_point' => $this->knowledgePoint['name'] ?? $kpCode,
  139. ],
  140. ];
  141. }
  142. /**
  143. * 获取难度标签
  144. */
  145. protected function getDifficultyLabel(string $difficulty): string
  146. {
  147. return match($difficulty) {
  148. 'easy' => '简单',
  149. 'medium' => '中等',
  150. 'hard' => '较难',
  151. default => '中等',
  152. };
  153. }
  154. /**
  155. * 获取难度颜色
  156. */
  157. protected function getDifficultyColor(string $difficulty): string
  158. {
  159. return match($difficulty) {
  160. 'easy' => 'green',
  161. 'medium' => 'blue',
  162. 'hard' => 'red',
  163. default => 'blue',
  164. };
  165. }
  166. /**
  167. * 获取预计完成时间
  168. */
  169. protected function getEstimatedTime(string $difficulty): string
  170. {
  171. return match($difficulty) {
  172. 'easy' => '3分钟',
  173. 'medium' => '5分钟',
  174. 'hard' => '8分钟',
  175. default => '5分钟',
  176. };
  177. }
  178. public function render()
  179. {
  180. return view('components.exam-analysis.similar-questions');
  181. }
  182. }