RecommendationList.php 4.9 KB

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