knowledge-mindmap.blade.php 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. <x-filament::page>
  2. <div
  3. class="space-y-6 bg-white p-4 rounded-xl"
  4. x-data="{
  5. graphInstance: null,
  6. stats: { nodes: 0, extraEdges: 0 },
  7. livewireId: '{{ $this->getId() }}',
  8. async initMindmap() {
  9. try {
  10. // 等待G6和自定义组件加载
  11. await this.waitForComponents();
  12. if (!window.G6 || !window.KnowledgeMindmapGraph) {
  13. console.error('G6组件未加载');
  14. return;
  15. }
  16. this.graphInstance = new window.KnowledgeMindmapGraph({
  17. containerId: 'knowledge-mindmap',
  18. livewireMethod: 'openDrawer',
  19. highlightLowMastery: true,
  20. livewireId: this.livewireId,
  21. });
  22. await this.graphInstance.init();
  23. this.stats = this.graphInstance.stats;
  24. } catch (error) {
  25. console.error('知识图谱初始化失败:', error);
  26. }
  27. },
  28. async waitForComponents() {
  29. let attempts = 0;
  30. const maxAttempts = 50;
  31. while ((!window.G6 || !window.KnowledgeMindmapGraph) && attempts < maxAttempts) {
  32. await new Promise(resolve => setTimeout(resolve, 100));
  33. attempts++;
  34. }
  35. if (attempts >= maxAttempts) {
  36. throw new Error('G6组件加载超时');
  37. }
  38. }
  39. }"
  40. x-init="initMindmap()"
  41. data-knowledge-mindmap-root
  42. >
  43. <div class="rounded-xl border border-slate-200 bg-white shadow-sm p-5">
  44. <div class="flex flex-col gap-4 md:flex-row md:items-center md:justify-between">
  45. <div class="space-y-2 text-slate-900">
  46. <h2 class="text-3xl font-bold">初中数学知识图谱</h2>
  47. <p class="text-lg text-slate-600">掌握度、互动与视觉反馈同步升级,点击任意节点查看学习路径与练习推荐。</p>
  48. <div class="flex flex-wrap items-center gap-4 text-base text-slate-600">
  49. <span>知识点 <span class="font-semibold text-slate-900" x-text="stats.nodes"></span></span>
  50. <span>额外关联 <span class="font-semibold text-slate-900" x-text="stats.extraEdges"></span></span>
  51. <span>已选学生:<span class="font-semibold text-slate-900">{{ $selectedStudentName ?: '未选择' }}</span></span>
  52. </div>
  53. </div>
  54. <div class="grid w-full max-w-xl grid-cols-1 gap-3 rounded-lg border border-slate-200 bg-slate-50 p-4 sm:grid-cols-2 text-slate-900">
  55. <div>
  56. <label class="mb-1 block text-base font-medium text-slate-700">选择老师</label>
  57. <select
  58. wire:model.live="selectedTeacherId"
  59. class="w-full rounded-lg border border-slate-200 bg-white px-3 py-2.5 text-base text-slate-900 placeholder:text-slate-500 focus:border-sky-300 focus:ring-2 focus:ring-sky-200/50"
  60. >
  61. <option value="" class="text-slate-800">请选择老师...</option>
  62. @foreach($teachers as $teacher)
  63. <option value="{{ $teacher['teacher_id'] }}" class="text-slate-900">{{ $teacher['name'] }}</option>
  64. @endforeach
  65. </select>
  66. </div>
  67. <div>
  68. <label class="mb-1 block text-base font-medium text-slate-700">选择学生</label>
  69. <select
  70. wire:model.live="selectedStudentId"
  71. class="w-full rounded-lg border border-slate-200 bg-white px-3 py-2.5 text-base text-slate-900 placeholder:text-slate-500 focus:border-amber-300 focus:ring-2 focus:ring-amber-200/50"
  72. {{ empty($selectedTeacherId) ? 'disabled' : '' }}
  73. >
  74. <option value="" class="text-slate-800">
  75. {{ empty($selectedTeacherId) ? '请先选择老师...' : '请选择学生...' }}
  76. </option>
  77. @foreach($students as $student)
  78. <option value="{{ $student['student_id'] }}" class="text-slate-900">{{ $student['name'] }}</option>
  79. @endforeach
  80. </select>
  81. </div>
  82. </div>
  83. </div>
  84. </div>
  85. <div class="relative overflow-hidden rounded-2xl border border-slate-200 shadow-sm bg-white text-slate-900 knowledge-mindmap-card">
  86. <div
  87. wire:ignore
  88. id="knowledge-mindmap"
  89. class="knowledge-mindmap-canvas relative h-[82vh] min-h-[720px] w-full"
  90. >
  91. <div class="pointer-events-none absolute inset-0 bg-[radial-gradient(circle_at_20%_20%,rgba(255,255,255,0.08),transparent_40%),radial-gradient(circle_at_80%_60%,rgba(255,255,255,0.06),transparent_45%)]"></div>
  92. </div>
  93. </div>
  94. <x-mindmap.detail-drawer
  95. :open="$drawerOpen"
  96. :details="$nodeDetails"
  97. closeAction="closeDrawer"
  98. selectAction="openDrawer"
  99. panelTitle="知识点详情"
  100. />
  101. </div>
  102. @push('styles')
  103. <style>
  104. .knowledge-mindmap-canvas {
  105. background: #ffffff;
  106. color: #0f172a;
  107. }
  108. .g6-grid {
  109. opacity: 0.08;
  110. }
  111. </style>
  112. @endpush
  113. @push('scripts')
  114. <script src="https://gw.alipayobjects.com/os/lib/antv/g6/4.8.24/dist/g6.min.js"></script>
  115. <script src="{{ asset('js/g6-custom-node.js') }}"></script>
  116. <script src="{{ asset('js/knowledge-mindmap-graph.js') }}"></script>
  117. @endpush
  118. </x-filament::page>