knowledge-point-details.blade.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. <div class="bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 overflow-hidden">
  2. @if(!$nodeDetails)
  3. {{-- 空状态 --}}
  4. <div class="p-8 text-center text-gray-500 dark:text-gray-400">
  5. <svg class="mx-auto h-12 w-12 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
  6. <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"></path>
  7. <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"></path>
  8. </svg>
  9. <p class="mt-2">点击知识图谱中的节点查看详细信息</p>
  10. </div>
  11. @else
  12. {{-- 知识点标题 --}}
  13. <div class="p-6 border-b border-gray-200 dark:border-gray-700">
  14. <div class="flex items-center justify-between">
  15. <div>
  16. <h3 class="text-xl font-bold text-gray-900 dark:text-gray-100">
  17. {{ $nodeDetails['cn_name'] ?? $nodeDetails['kp_code'] ?? $nodeDetails['code'] ?? '未知知识点' }}
  18. </h3>
  19. <div class="mt-1 flex items-center gap-2 text-sm text-gray-500 dark:text-gray-400">
  20. <span>{{ $nodeDetails['kp_code'] ?? $nodeDetails['code'] ?? $selectedNode }}</span>
  21. @if($nodeDetails['phase'])
  22. <span class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200">
  23. {{ $nodeDetails['phase'] }}
  24. </span>
  25. @endif
  26. @if($nodeDetails['category'])
  27. <span class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200">
  28. {{ $nodeDetails['category'] }}
  29. </span>
  30. @endif
  31. </div>
  32. </div>
  33. <div class="text-right">
  34. <div class="text-sm text-gray-500 dark:text-gray-400">重要度</div>
  35. <div class="text-2xl font-bold text-indigo-600 dark:text-indigo-400">
  36. {{ $nodeDetails['importance'] ?? 0 }}
  37. </div>
  38. </div>
  39. </div>
  40. </div>
  41. {{-- 统计概览 --}}
  42. <div class="p-6 border-b border-gray-200 dark:border-gray-700">
  43. <div class="grid grid-cols-2 md:grid-cols-4 gap-4">
  44. <div class="text-center">
  45. <div class="text-2xl font-bold text-blue-600 dark:text-blue-400">{{ $this->totalQuestions }}</div>
  46. <div class="text-sm text-gray-500 dark:text-gray-400 mt-1">总题目数</div>
  47. </div>
  48. <div class="text-center">
  49. <div class="text-2xl font-bold text-green-600 dark:text-green-400">{{ $this->directQuestions }}</div>
  50. <div class="text-sm text-gray-500 dark:text-gray-400 mt-1">直接题目</div>
  51. </div>
  52. <div class="text-center">
  53. <div class="text-2xl font-bold text-yellow-600 dark:text-yellow-400">{{ $this->childrenQuestions }}</div>
  54. <div class="text-sm text-gray-500 dark:text-gray-400 mt-1">子知识点题目</div>
  55. </div>
  56. <div class="text-center">
  57. <div class="text-2xl font-bold text-purple-600 dark:text-purple-400">{{ $this->skillsQuestions }}</div>
  58. <div class="text-sm text-gray-500 dark:text-gray-400 mt-1">技能点题目</div>
  59. </div>
  60. </div>
  61. </div>
  62. {{-- 标签页导航 --}}
  63. <div class="px-6 border-b border-gray-200 dark:border-gray-700">
  64. <nav class="flex space-x-8" aria-label="Tabs">
  65. <button
  66. wire:click="setActiveTab('overview')"
  67. class="{{ $activeTab === 'overview' ? 'border-indigo-500 text-indigo-600 dark:text-indigo-400' : 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300 dark:text-gray-400 dark:hover:text-gray-300' }} py-4 px-1 border-b-2 font-medium text-sm"
  68. >
  69. 知识点介绍
  70. </button>
  71. <button
  72. wire:click="setActiveTab('children')"
  73. class="{{ $activeTab === 'children' ? 'border-indigo-500 text-indigo-600 dark:text-indigo-400' : 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300 dark:text-gray-400 dark:hover:text-gray-300' }} py-4 px-1 border-b-2 font-medium text-sm"
  74. >
  75. 一级子知识点
  76. @if(count($this->childrenNodes) > 0)
  77. <span class="ml-2 inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium bg-indigo-100 text-indigo-800 dark:bg-indigo-900 dark:text-indigo-200">
  78. {{ count($this->childrenNodes) }}
  79. </span>
  80. @endif
  81. </button>
  82. <button
  83. wire:click="setActiveTab('skills')"
  84. class="{{ $activeTab === 'skills' ? 'border-indigo-500 text-indigo-600 dark:text-indigo-400' : 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300 dark:text-gray-400 dark:hover:text-gray-300' }} py-4 px-1 border-b-2 font-medium text-sm"
  85. >
  86. 技能点
  87. @if($this->skillsCount > 0)
  88. <span class="ml-2 inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium bg-indigo-100 text-indigo-800 dark:bg-indigo-900 dark:text-indigo-200">
  89. {{ $this->skillsCount }}
  90. </span>
  91. @endif
  92. </button>
  93. </nav>
  94. </div>
  95. {{-- 标签页内容 --}}
  96. <div class="p-6">
  97. @if($activeTab === 'overview')
  98. {{-- 知识点介绍 --}}
  99. <div class="space-y-4">
  100. @if(!empty($nodeDetails['description']))
  101. <div>
  102. <h4 class="text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">描述</h4>
  103. <p class="text-sm text-gray-600 dark:text-gray-400">{{ $nodeDetails['description'] }}</p>
  104. </div>
  105. @endif
  106. @if(!empty($nodeDetails['skills']))
  107. <div>
  108. <h4 class="text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">相关技能</h4>
  109. <div class="flex flex-wrap gap-2">
  110. @foreach($nodeDetails['skills'] as $skill)
  111. <span class="inline-flex items-center px-3 py-1 rounded-full text-sm font-medium bg-indigo-100 text-indigo-800 dark:bg-indigo-900 dark:text-indigo-200">
  112. {{ $skill['skill_name'] ?? $skill['skill_code'] ?? 'Unknown' }}
  113. </span>
  114. @endforeach
  115. </div>
  116. </div>
  117. @endif
  118. <div class="grid grid-cols-2 gap-4">
  119. <div>
  120. <h4 class="text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">英文名称</h4>
  121. <p class="text-sm text-gray-600 dark:text-gray-400">{{ $nodeDetails['en_name'] ?? '-' }}</p>
  122. </div>
  123. <div>
  124. <h4 class="text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">技能数量</h4>
  125. <p class="text-sm text-gray-600 dark:text-gray-400">{{ count($nodeDetails['skills'] ?? []) }}</p>
  126. </div>
  127. </div>
  128. </div>
  129. @elseif($activeTab === 'children')
  130. {{-- 一级子知识点 --}}
  131. <div class="space-y-4">
  132. @if(empty($this->childrenNodes))
  133. <div class="text-center text-gray-500 dark:text-gray-400 py-8">
  134. <svg class="mx-auto h-8 w-8 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
  135. <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20 13V6a2 2 0 00-2-2H6a2 2 0 00-2 2v7m16 0v5a2 2 0 01-2 2H6a2 2 0 01-2-2v-5m16 0h-2.586a1 1 0 00-.707.293l-2.414 2.414a1 1 0 01-.707.293h-3.172a1 1 0 01-.707-.293l-2.414-2.414A1 1 0 006.586 13H4"></path>
  136. </svg>
  137. <p class="mt-2 text-sm">暂无子知识点</p>
  138. </div>
  139. @else
  140. <div class="space-y-3">
  141. @foreach($this->childrenNodes as $child)
  142. <div class="flex items-center justify-between p-4 bg-gray-50 dark:bg-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-600 transition-colors cursor-pointer">
  143. <div class="flex-1">
  144. <div class="flex items-center gap-3">
  145. <div class="flex-1">
  146. <h5 class="text-sm font-medium text-gray-900 dark:text-gray-100">
  147. {{ $child['cn_name'] ?? $child['kp_code'] }}
  148. </h5>
  149. <p class="text-sm text-gray-500 dark:text-gray-400">{{ $child['kp_code'] }}</p>
  150. </div>
  151. <div class="text-right">
  152. @if(isset($child['question_count']))
  153. <div class="text-sm font-medium text-blue-600 dark:text-blue-400">
  154. {{ $child['question_count'] }} 题
  155. </div>
  156. @endif
  157. @if(!empty($child['phase']))
  158. <span class="text-xs text-gray-500 dark:text-gray-400">{{ $child['phase'] }}</span>
  159. @endif
  160. </div>
  161. </div>
  162. </div>
  163. <div class="ml-4">
  164. <svg class="w-5 h-5 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
  165. <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path>
  166. </svg>
  167. </div>
  168. </div>
  169. @endforeach
  170. </div>
  171. @endif
  172. </div>
  173. @elseif($activeTab === 'skills')
  174. {{-- 技能点 --}}
  175. <div class="space-y-4">
  176. @if(empty($nodeDetails['question_stats']['skills'] ?? []))
  177. <div class="text-center text-gray-500 dark:text-gray-400 py-8">
  178. <svg class="mx-auto h-8 w-8 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
  179. <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"></path>
  180. </svg>
  181. <p class="mt-2 text-sm">暂无技能点数据</p>
  182. </div>
  183. @else
  184. <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
  185. @foreach($nodeDetails['question_stats']['skills'] as $skill)
  186. <div class="p-4 bg-gradient-to-br from-indigo-50 to-blue-50 dark:from-indigo-900/20 dark:to-blue-900/20 rounded-lg border border-indigo-100 dark:border-indigo-800">
  187. <div class="flex items-center justify-between mb-2">
  188. <h5 class="text-sm font-medium text-gray-900 dark:text-gray-100">
  189. {{ $skill['skill_code'] }}
  190. </h5>
  191. <span class="inline-flex items-center px-2 py-1 rounded text-xs font-medium bg-indigo-600 text-white">
  192. {{ $skill['question_count'] ?? 0 }} 题
  193. </span>
  194. </div>
  195. <div class="w-full bg-gray-200 dark:bg-gray-700 rounded-full h-2">
  196. @php
  197. $maxCount = collect($nodeDetails['question_stats']['skills'] ?? [])->max('question_count') ?: 1;
  198. $percentage = ($skill['question_count'] ?? 0) / $maxCount * 100;
  199. @endphp
  200. <div
  201. class="bg-indigo-600 h-2 rounded-full transition-all"
  202. style="width: {{ $percentage }}%"
  203. ></div>
  204. </div>
  205. </div>
  206. @endforeach
  207. </div>
  208. @endif
  209. </div>
  210. @endif
  211. </div>
  212. @endif
  213. </div>