| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256 |
- <?php
- namespace App\Livewire\Integrations;
- use Livewire\Component;
- use App\Services\KnowledgeServiceApi;
- use App\Services\QuestionBankService;
- use Illuminate\Support\Facades\Http;
- class KnowledgeNetworkComponent extends Component
- {
- public $selectedKpCode = null;
- public $networkData = [];
- public $kpRelations = [];
- public $questionRelations = [];
- public $isLoading = false;
- protected $listeners = [
- 'kpSelected' => 'handleKpSelected',
- 'clearSelection' => 'clearSelection',
- 'refreshNetwork' => 'loadNetworkData',
- ];
- public function mount($selectedKpCode = null)
- {
- $this->selectedKpCode = $selectedKpCode;
- $this->loadNetworkData();
- }
- public function loadNetworkData()
- {
- $this->isLoading = true;
- try {
- // 获取知识图谱关联关系
- $this->loadKpRelations();
- // 获取题库关联关系
- $this->loadQuestionRelations();
- // 整合数据
- $this->buildNetworkData();
- } catch (\Exception $e) {
- \Log::error('加载知识网络失败', [
- 'kp_code' => $this->selectedKpCode,
- 'error' => $e->getMessage()
- ]);
- $this->dispatch('error', message: '加载知识网络失败');
- }
- $this->isLoading = false;
- }
- private function loadKpRelations()
- {
- try {
- $service = app(KnowledgeServiceApi::class);
- if ($this->selectedKpCode) {
- // 获取选中知识点的关联关系
- $upstream = $service->getUpstreamNodes($this->selectedKpCode, 3);
- $downstream = $service->getDownstreamNodes($this->selectedKpCode, 3);
- $related = $service->getRelatedNodes($this->selectedKpCode);
- $this->kpRelations = [
- 'upstream' => $upstream['nodes'] ?? [],
- 'downstream' => $downstream['nodes'] ?? [],
- 'related' => $related['nodes'] ?? [],
- ];
- } else {
- // 获取所有关联关系(从完整图谱中提取)
- $graphData = $this->getFullGraphData();
- $this->kpRelations = $graphData;
- }
- } catch (\Exception $e) {
- \Log::error('获取知识关联关系失败', ['error' => $e->getMessage()]);
- }
- }
- private function loadQuestionRelations()
- {
- try {
- $service = app(QuestionBankService::class);
- // 获取所有题库统计数据
- $stats = $service->getKnowledgePointStatistics();
- if ($this->selectedKpCode) {
- // 只返回选中知识点的统计
- $selectedStats = collect($stats)->firstWhere('kp_code', $this->selectedKpCode);
- $this->questionRelations = $selectedStats ? [$selectedStats] : [];
- } else {
- $this->questionRelations = $stats;
- }
- } catch (\Exception $e) {
- \Log::error('获取题库关联关系失败', ['error' => $e->getMessage()]);
- }
- }
- private function getFullGraphData()
- {
- try {
- $knowledgeApiBase = config('services.knowledge_api.base_url', 'http://localhost:5011');
- $response = Http::timeout(10)
- ->get($knowledgeApiBase . '/graph/export');
- if ($response->successful()) {
- return $response->json();
- }
- } catch (\Exception $e) {
- \Log::error('获取完整图谱失败', ['error' => $e->getMessage()]);
- }
- return ['nodes' => [], 'edges' => []];
- }
- private function buildNetworkData()
- {
- $network = [
- 'nodes' => [],
- 'links' => [],
- 'groups' => [
- 'knowledge' => ['name' => '知识点', 'color' => '#3B82F6'],
- 'questions' => ['name' => '题库', 'color' => '#10B981'],
- 'skills' => ['name' => '技能', 'color' => '#F59E0B'],
- ],
- ];
- // 添加知识点节点
- $nodesMap = [];
- if ($this->selectedKpCode) {
- // 选中模式:添加相关知识点
- $relatedNodes = array_merge(
- $this->kpRelations['upstream'] ?? [],
- $this->kpRelations['downstream'] ?? [],
- $this->kpRelations['related'] ?? []
- );
- foreach ($relatedNodes as $node) {
- $kpCode = $node['kp_code'];
- $nodesMap[$kpCode] = [
- 'id' => $kpCode,
- 'name' => $node['cn_name'] ?? $kpCode,
- 'group' => 'knowledge',
- 'type' => 'knowledge_point',
- 'data' => $node,
- ];
- }
- // 添加选中的知识点
- $selectedNode = collect($this->kpRelations['upstream'] ?? [])
- ->merge($this->kpRelations['downstream'] ?? [])
- ->merge($this->kpRelations['related'] ?? [])
- ->firstWhere('kp_code', $this->selectedKpCode);
- if ($selectedNode) {
- $nodesMap[$this->selectedKpCode] = [
- 'id' => $this->selectedKpCode,
- 'name' => $selectedNode['cn_name'] ?? $this->selectedKpCode,
- 'group' => 'knowledge',
- 'type' => 'knowledge_point',
- 'data' => $selectedNode,
- ];
- }
- } else {
- // 完整模式:从题库统计中获取知识点
- foreach ($this->questionRelations as $stat) {
- $kpCode = $stat['kp_code'];
- if (!$kpCode) continue;
- $nodesMap[$kpCode] = [
- 'id' => $kpCode,
- 'name' => $stat['cn_name'] ?? $kpCode,
- 'group' => 'knowledge',
- 'type' => 'knowledge_point',
- 'question_count' => $stat['total_questions'] ?? 0,
- 'data' => $stat,
- ];
- }
- }
- // 添加技能节点
- foreach ($this->questionRelations as $stat) {
- if (isset($stat['skills']) && is_array($stat['skills'])) {
- foreach ($stat['skills'] as $skill) {
- $skillCode = $skill['skill_code'] ?? '';
- if (!$skillCode) continue;
- $nodesMap[$skillCode] = [
- 'id' => $skillCode,
- 'name' => $skillCode,
- 'group' => 'skills',
- 'type' => 'skill',
- 'data' => $skill,
- ];
- }
- }
- }
- // 添加链接
- foreach ($this->questionRelations as $stat) {
- $kpCode = $stat['kp_code'];
- if (!$kpCode) continue;
- // 知识点到题目的链接
- if (isset($nodesMap[$kpCode])) {
- $questionCount = $stat['total_questions'] ?? 0;
- if ($questionCount > 0) {
- $network['links'][] = [
- 'source' => $kpCode,
- 'target' => "questions_{$kpCode}",
- 'value' => $questionCount,
- 'type' => 'has_questions',
- ];
- }
- // 知识点到技能点的链接
- if (isset($stat['skills']) && is_array($stat['skills'])) {
- foreach ($stat['skills'] as $skill) {
- $skillCode = $skill['skill_code'] ?? '';
- if ($skillCode && isset($nodesMap[$skillCode])) {
- $network['links'][] = [
- 'source' => $kpCode,
- 'target' => $skillCode,
- 'value' => $skill['question_count'] ?? 1,
- 'type' => 'has_skill',
- ];
- }
- }
- }
- }
- }
- $network['nodes'] = array_values($nodesMap);
- $this->networkData = $network;
- }
- public function handleKpSelected($kpCode)
- {
- $this->selectedKpCode = $kpCode;
- $this->loadNetworkData();
- }
- public function clearSelection()
- {
- $this->selectedKpCode = null;
- $this->loadNetworkData();
- }
- public function render()
- {
- return view('livewire.integrations.knowledge-network-component', [
- 'networkData' => $this->networkData,
- ]);
- }
- }
|