RecommendationList.php 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. <?php
  2. namespace App\Filament\Pages;
  3. use App\Services\QuestionBankService;
  4. use App\Services\KnowledgeGraphService;
  5. use BackedEnum;
  6. use Filament\Pages\Page;
  7. use Filament\Notifications\Notification;
  8. use UnitEnum;
  9. class RecommendationList extends Page
  10. {
  11. protected static string|BackedEnum|null $navigationIcon = 'heroicon-o-sparkles';
  12. protected static ?string $title = '智能推荐';
  13. protected static ?string $navigationLabel = '智能推荐';
  14. protected static ?string $slug = 'recommendation-list';
  15. protected static ?int $navigationSort = 20;
  16. protected string $view = 'filament.pages.recommendation-list';
  17. public ?string $kpCode = null;
  18. public array $knowledgePoint = [];
  19. public array $recommendedQuestions = [];
  20. public bool $loading = true;
  21. public function mount(?string $kp = null)
  22. {
  23. $this->kpCode = $kp;
  24. if (!$kp) {
  25. Notification::make()
  26. ->title('参数错误')
  27. ->body('缺少知识点参数')
  28. ->warning()
  29. ->send();
  30. $this->redirectRoute('filament.admin.pages.exam-analysis');
  31. return;
  32. }
  33. $this->loadRecommendations();
  34. }
  35. protected function loadRecommendations()
  36. {
  37. try {
  38. $this->loading = true;
  39. // 1. 获取知识点信息
  40. $knowledgeService = app(KnowledgeGraphService::class);
  41. $kpList = $knowledgeService->listKnowledgePoints(1, 1000);
  42. if (isset($kpList['data'])) {
  43. foreach ($kpList['data'] as $kp) {
  44. if ($kp['kp_code'] === $this->kpCode) {
  45. $this->knowledgePoint = $kp;
  46. break;
  47. }
  48. }
  49. }
  50. // 2. 获取推荐题目
  51. $questionService = app(QuestionBankService::class);
  52. $response = $questionService->filterQuestions([
  53. 'kp_codes' => $this->kpCode,
  54. 'per_page' => 20,
  55. 'sort' => 'difficulty' // 按难度排序
  56. ]);
  57. if (isset($response['data'])) {
  58. $this->recommendedQuestions = $response['data'];
  59. }
  60. // 3. 如果题目不足,生成更多推荐
  61. if (count($this->recommendedQuestions) < 10) {
  62. $this->recommendedQuestions = array_merge(
  63. $this->recommendedQuestions,
  64. $this->generateAdditionalQuestions()
  65. );
  66. }
  67. $this->loading = false;
  68. } catch (\Exception $e) {
  69. \Log::error('加载推荐题目失败', [
  70. 'kp_code' => $this->kpCode,
  71. 'error' => $e->getMessage()
  72. ]);
  73. Notification::make()
  74. ->title('加载失败')
  75. ->body('无法加载推荐题目,请稍后重试')
  76. ->danger()
  77. ->send();
  78. $this->loading = false;
  79. }
  80. }
  81. protected function generateAdditionalQuestions(): array
  82. {
  83. $kpName = $this->knowledgePoint['cn_name'] ?? $this->kpCode;
  84. $additional = [];
  85. // 基础题
  86. for ($i = 1; $i <= 5; $i++) {
  87. $additional[] = [
  88. 'id' => "gen_basic_{$i}",
  89. 'stem' => "{$kpName}基础练习题 {$i}",
  90. 'question_type' => '基础题',
  91. 'difficulty' => 'easy',
  92. 'score' => 3,
  93. 'kp_code' => $this->kpCode,
  94. 'content' => "这是一道关于{$kpName}的基础练习题,帮助你巩固核心概念。"
  95. ];
  96. }
  97. // 提高题
  98. for ($i = 1; $i <= 5; $i++) {
  99. $additional[] = [
  100. 'id' => "gen_advanced_{$i}",
  101. 'stem' => "{$kpName}提高练习题 {$i}",
  102. 'question_type' => '提高题',
  103. 'difficulty' => 'hard',
  104. 'score' => 8,
  105. 'kp_code' => $this->kpCode,
  106. 'content' => "这是一道关于{$kpName}的提高练习题,挑战你的解题能力。"
  107. ];
  108. }
  109. return $additional;
  110. }
  111. public function getDifficultyLabel(string $difficulty): string
  112. {
  113. return match($difficulty) {
  114. 'easy' => '简单',
  115. 'medium' => '中等',
  116. 'hard' => '困难',
  117. default => '中等',
  118. };
  119. }
  120. public function getDifficultyColor(string $difficulty): string
  121. {
  122. return match($difficulty) {
  123. 'easy' => 'green',
  124. 'medium' => 'blue',
  125. 'hard' => 'red',
  126. default => 'blue',
  127. };
  128. }
  129. public function getTitle(): string
  130. {
  131. if (!empty($this->knowledgePoint)) {
  132. return "{$this->knowledgePoint['cn_name']} - 智能推荐";
  133. }
  134. return '智能推荐';
  135. }
  136. }