فهرست منبع

修改 api 路径的问题

yemeishu 3 هفته پیش
والد
کامیت
02f7ef7b1d
1فایلهای تغییر یافته به همراه213 افزوده شده و 1 حذف شده
  1. 213 1
      app/Services/QuestionBankService.php

+ 213 - 1
app/Services/QuestionBankService.php

@@ -216,7 +216,7 @@ class QuestionBankService
             // 增加超时时间到60秒,确保有足够时间启动异步任务
             // 注意:API是异步的,只需等待任务启动(1-2秒),不需要等待AI生成完成
             $response = Http::timeout(60)
-                ->post($this->baseUrl . '/generate-intelligent-questions', $params);
+                ->post($this->baseUrl . '/ai/generate-intelligent-questions', $params);
 
             if ($response->successful()) {
                 return $response->json();
@@ -1079,4 +1079,216 @@ class QuestionBankService
     {
         return $this->getTaskStatus($taskId) ?? ['status' => 'unknown'];
     }
+
+    /**
+     * 获取知识点题目统计信息
+     * 根据知识点代码,统计该知识点及其子知识点和技能点的题目数量
+     */
+    public function getKnowledgePointStatistics(?string $kpCode = null): array
+    {
+        try {
+            // 获取知识图谱数据和题目统计数据
+            $knowledgeGraph = $this->getKnowledgeGraph();
+            $nodes = $knowledgeGraph['nodes'] ?? [];
+            $edges = $knowledgeGraph['edges'] ?? [];
+            $questionStats = $this->getQuestionsStatisticsFromApi();
+
+            // 构建知识点索引
+            $nodeMap = [];
+            foreach ($nodes as $node) {
+                if (!empty($node['kp_code'])) {
+                    $nodeMap[$node['kp_code']] = $node;
+                }
+            }
+
+            // 构建子知识点关系(从edges中提取)
+            $childrenMap = [];
+            $parentMap = [];
+            foreach ($edges as $edge) {
+                $source = $edge['source'] ?? '';
+                $target = $edge['target'] ?? '';
+                $direction = $edge['relation_direction'] ?? '';
+
+                if (!empty($source) && !empty($target)) {
+                    if ($direction === 'DOWNSTREAM') {
+                        $childrenMap[$source][] = $target;
+                        $parentMap[$target] = $source;
+                    }
+                }
+            }
+
+            // 构建技能点统计
+            $skillStats = [];
+            foreach ($questionStats as $stat) {
+                $code = $stat['kp_code'] ?? '';
+                $skills = $stat['skills_list'] ?? [];
+
+                if (!empty($code)) {
+                    foreach ($skills as $skillCode) {
+                        if (!empty($skillCode)) {
+                            if (!isset($skillStats[$code])) {
+                                $skillStats[$code] = [];
+                            }
+                            if (!isset($skillStats[$code][$skillCode])) {
+                                $skillStats[$code][$skillCode] = 0;
+                            }
+                            $skillStats[$code][$skillCode]++;
+                        }
+                    }
+                }
+            }
+
+            // 如果指定了特定知识点,只返回该知识点的统计
+            if ($kpCode && isset($nodeMap[$kpCode])) {
+                return $this->buildKnowledgePointStats($kpCode, $nodeMap, $childrenMap, $questionStats, $skillStats);
+            }
+
+            // 否则返回所有顶级知识点的统计
+            $result = [];
+            $rootNodes = [];
+
+            // 找出根节点(没有父节点的节点)
+            foreach ($nodes as $node) {
+                $code = $node['kp_code'] ?? '';
+                if (!empty($code) && !isset($parentMap[$code])) {
+                    $rootNodes[] = $code;
+                }
+            }
+
+            foreach ($rootNodes as $rootCode) {
+                $result[] = $this->buildKnowledgePointStats($rootCode, $nodeMap, $childrenMap, $questionStats, $skillStats);
+            }
+
+            // 按题目总数排序
+            usort($result, function($a, $b) {
+                return ($b['total_questions'] ?? 0) <=> ($a['total_questions'] ?? 0);
+            });
+
+            return $result;
+
+        } catch (\Exception $e) {
+            Log::error('获取知识点统计失败', [
+                'kp_code' => $kpCode,
+                'error' => $e->getMessage()
+            ]);
+            return [];
+        }
+    }
+
+    /**
+     * 获取知识图谱数据
+     */
+    private function getKnowledgeGraph(): array
+    {
+        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' => []];
+    }
+
+    /**
+     * 从 API 获取题目统计
+     */
+    private function getQuestionsStatisticsFromApi(): array
+    {
+        try {
+            // 调用题库 API 获取统计数据
+            $response = Http::timeout(30)
+                ->get($this->baseUrl . '/questions/statistics');
+
+            if ($response->successful()) {
+                $data = $response->json();
+                return $data['by_kp'] ?? [];
+            }
+
+            Log::warning('获取题目统计API失败', [
+                'status' => $response->status(),
+                'url' => $this->baseUrl . '/questions/statistics'
+            ]);
+        } catch (\Exception $e) {
+            Log::error('获取题目统计异常', [
+                'error' => $e->getMessage(),
+                'url' => $this->baseUrl . '/questions/statistics'
+            ]);
+        }
+
+        return [];
+    }
+
+    /**
+     * 构建单个知识点的统计信息
+     */
+    private function buildKnowledgePointStats(
+        string $kpCode,
+        array $nodeMap,
+        array $childrenMap,
+        array $questionStats,
+        array $skillStats
+    ): array {
+        $node = $nodeMap[$kpCode] ?? null;
+        if (!$node) {
+            return [];
+        }
+
+        // 获取直接子知识点
+        $children = $childrenMap[$kpCode] ?? [];
+        $directQuestionCount = 0;
+
+        // 查找当前知识点的题目数
+        foreach ($questionStats as $stat) {
+            if ($stat['kp_code'] === $kpCode) {
+                $directQuestionCount = $stat['question_count'] ?? 0;
+                break;
+            }
+        }
+
+        // 计算子知识点统计
+        $childrenStats = [];
+        foreach ($children as $childCode) {
+            $childStats = $this->buildKnowledgePointStats($childCode, $nodeMap, $childrenMap, $questionStats, $skillStats);
+            if (!empty($childStats)) {
+                $childrenStats[] = $childStats;
+            }
+        }
+
+        // 计算子知识点题目总数
+        $childrenQuestionCount = 0;
+        foreach ($childrenStats as $child) {
+            $childrenQuestionCount += $child['total_questions'] ?? 0;
+        }
+
+        // 获取当前知识点的技能点统计
+        $skillsCount = 0;
+        if (isset($skillStats[$kpCode])) {
+            $skillsCount = array_sum($skillStats[$kpCode]);
+        }
+
+        return [
+            'kp_code' => $kpCode,
+            'cn_name' => $node['cn_name'] ?? $kpCode,
+            'en_name' => $node['en_name'] ?? '',
+            'total_questions' => $directQuestionCount + $childrenQuestionCount,
+            'direct_questions' => $directQuestionCount,
+            'children_questions' => $childrenQuestionCount,
+            'children' => $childrenStats,
+            'skills_count' => count($skillStats[$kpCode] ?? []),
+            'skills_total_questions' => $skillsCount,
+            'skills' => array_map(function($skillCode, $count) use ($kpCode) {
+                return [
+                    'kp_code' => $kpCode,
+                    'skill_code' => $skillCode,
+                    'question_count' => $count
+                ];
+            }, array_keys($skillStats[$kpCode] ?? []), array_values($skillStats[$kpCode] ?? []))
+        ];
+    }
 }