SkillProficiencyRadar.php 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. <?php
  2. namespace App\Livewire;
  3. use App\Services\LearningAnalyticsService;
  4. use Livewire\Component;
  5. class SkillProficiencyRadar extends Component
  6. {
  7. public string $studentId = '';
  8. public array $radarData = [];
  9. public bool $isLoading = false;
  10. public string $errorMessage = '';
  11. public function mount(string $studentId): void
  12. {
  13. $this->studentId = $studentId;
  14. $this->loadRadarData();
  15. }
  16. public function loadRadarData(): void
  17. {
  18. $this->isLoading = true;
  19. $this->errorMessage = '';
  20. try {
  21. $service = new LearningAnalyticsService();
  22. $skillProficiency = $service->getStudentSkillProficiency($this->studentId);
  23. if ($skillProficiency && isset($skillProficiency['data'])) {
  24. $this->radarData = $this->processRadarData($skillProficiency['data']);
  25. } else {
  26. $this->radarData = [];
  27. }
  28. } catch (\Exception $e) {
  29. $this->errorMessage = '加载雷达图数据失败:' . $e->getMessage();
  30. $this->radarData = [];
  31. } finally {
  32. $this->isLoading = false;
  33. }
  34. }
  35. /**
  36. * 处理雷达图数据
  37. */
  38. private function processRadarData(array $skillData): array
  39. {
  40. $processedData = [];
  41. $maxValue = 1.0; // 技能熟练度最大值为1
  42. foreach ($skillData as $skill) {
  43. $processedData[] = [
  44. 'skill_name' => $skill['skill_name'],
  45. 'proficiency_level' => $skill['proficiency_level'],
  46. 'skill_level' => $skill['skill_level'],
  47. 'total_questions_attempted' => $skill['total_questions_attempted'],
  48. 'simple_accuracy' => $skill['simple_accuracy'] ?? 0,
  49. 'intermediate_accuracy' => $skill['intermediate_accuracy'] ?? 0,
  50. 'advanced_accuracy' => $skill['advanced_accuracy'] ?? 0,
  51. 'practice_streak' => $skill['practice_streak'] ?? 0,
  52. 'max_value' => $maxValue,
  53. ];
  54. }
  55. return [
  56. 'data' => $processedData,
  57. 'max_value' => $maxValue,
  58. ];
  59. }
  60. /**
  61. * 获取技能等级颜色
  62. */
  63. public function getSkillLevelColor(string $skillLevel): string
  64. {
  65. return match ($skillLevel) {
  66. 'beginner' => '#ef4444', // 红色 - 初学者
  67. 'elementary' => '#f97316', // 橙色 - 入门
  68. 'intermediate' => '#eab308', // 黄色 - 进阶
  69. 'advanced' => '#22c55e', // 绿色 - 熟练
  70. 'proficient' => '#3b82f6', // 蓝色 - 精通
  71. default => '#9ca3af', // 灰色 - 未知
  72. };
  73. }
  74. /**
  75. * 获取技能等级中文名称
  76. */
  77. public function getSkillLevelName(string $skillLevel): string
  78. {
  79. return match ($skillLevel) {
  80. 'beginner' => '初学者',
  81. 'elementary' => '入门',
  82. 'intermediate' => '进阶',
  83. 'advanced' => '熟练',
  84. 'proficient' => '精通',
  85. default => '未知',
  86. };
  87. }
  88. /**
  89. * 获取难度标签
  90. */
  91. public function getDifficultyLabel(string $difficulty): string
  92. {
  93. return match ($difficulty) {
  94. 'simple' => '简单',
  95. 'intermediate' => '中等',
  96. 'advanced' => '困难',
  97. default => $difficulty,
  98. };
  99. }
  100. public function render()
  101. {
  102. return view('livewire.skill-proficiency-radar');
  103. }
  104. }