117 lines
4.7 KiB
Python
117 lines
4.7 KiB
Python
import json
|
|
import logging
|
|
|
|
import fastapi
|
|
from fastapi import APIRouter, Request
|
|
|
|
# 配置日志
|
|
logger = logging.getLogger(__name__)
|
|
|
|
# 创建路由对象
|
|
router = APIRouter(prefix="/api", tags=["知识图谱相关接口"])
|
|
|
|
# 获取知识树数据接口
|
|
@router.get("/tree-data")
|
|
async def get_tree_data(request: fastapi.Request):
|
|
try:
|
|
pg_pool = request.app.state.pool
|
|
async with pg_pool.acquire() as conn:
|
|
# 执行查询
|
|
rows = await conn.fetch("""
|
|
SELECT id,
|
|
title,
|
|
parent_id,
|
|
is_leaf,
|
|
prerequisite,
|
|
related
|
|
FROM knowledge_points
|
|
ORDER BY parent_id, id
|
|
""")
|
|
# 构建节点映射
|
|
nodes = {}
|
|
for row in rows:
|
|
prerequisite_data = json.loads(row[4]) if row[4] else []
|
|
# 转换先修知识格式
|
|
if isinstance(prerequisite_data, list) and len(prerequisite_data) > 0 and isinstance(prerequisite_data[0], dict):
|
|
# 已经是新格式
|
|
prerequisites = prerequisite_data
|
|
else:
|
|
# 转换为新格式
|
|
prerequisites = [{{"id": str(id), "title": title}} for id, title in (prerequisite_data or [])] if prerequisite_data else None
|
|
|
|
related_data = json.loads(row[5]) if row[5] else []
|
|
# 转换相关知识格式
|
|
if isinstance(related_data, list) and len(related_data) > 0 and isinstance(related_data[0], dict):
|
|
# 已经是新格式
|
|
related = related_data
|
|
else:
|
|
# 转换为新格式
|
|
related = [{{"id": str(id), "title": title}} for id, title in (related_data or [])] if related_data else None
|
|
|
|
node = {{
|
|
"id": row[0],
|
|
"title": row[1],
|
|
"parent_id": row[2],
|
|
"is_leaf": row[3],
|
|
"prerequisite": prerequisites,
|
|
"related": related,
|
|
"children": []
|
|
}}
|
|
nodes[row[0]] = node
|
|
|
|
# 构建树结构
|
|
tree_data = []
|
|
for node_id, node in nodes.items():
|
|
parent_id = node["parent_id"]
|
|
if parent_id is None or parent_id == 0:
|
|
tree_data.append(node)
|
|
else:
|
|
if parent_id in nodes:
|
|
if "children" not in nodes[parent_id]:
|
|
nodes[parent_id]["children"] = []
|
|
nodes[parent_id]["children"].append(node)
|
|
|
|
return {{"code": 0, "data": tree_data}}
|
|
except Exception as e:
|
|
return {{"code": 1, "msg": str(e)}}
|
|
|
|
# 更新知识节点接口
|
|
@router.post("/update-knowledge")
|
|
async def update_knowledge(request: Request):
|
|
try:
|
|
data = await request.json()
|
|
node_id = data.get('node_id')
|
|
knowledge = data.get('knowledge', [])
|
|
update_type = data.get('update_type', 'prerequisite') # 默认为先修知识
|
|
|
|
if not node_id:
|
|
raise ValueError("Missing node_id")
|
|
|
|
pg_pool = request.app.state.pool
|
|
async with pg_pool.acquire() as conn:
|
|
if update_type == 'prerequisite':
|
|
await conn.execute("""
|
|
UPDATE knowledge_points
|
|
SET prerequisite = $1
|
|
WHERE id = $2
|
|
""",
|
|
json.dumps(
|
|
[{{"id": p["id"], "title": p["title"]}} for p in knowledge],
|
|
ensure_ascii=False
|
|
),
|
|
node_id)
|
|
else: # related knowledge
|
|
await conn.execute("""
|
|
UPDATE knowledge_points
|
|
SET related = $1
|
|
WHERE id = $2
|
|
""",
|
|
json.dumps(
|
|
[{{"id": p["id"], "title": p["title"]}} for p in knowledge],
|
|
ensure_ascii=False
|
|
),
|
|
node_id)
|
|
|
|
return {{"code": 0, "msg": "更新成功"}}
|
|
except Exception as e:
|
|
return {{"code": 1, "msg": str(e)}} |