You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

193 lines
7.5 KiB

import json
import traceback
from app import app
from robyn import jsonify, Response
from service.OperationService import OperationService
from urllib.parse import unquote
# 实例化业务逻辑对象
operation_service = OperationService()
def create_response(status_code, data_dict):
"""
统一响应格式封装,强制使用 UTF-8 防止中文乱码。
"""
return Response(
status_code=status_code,
description=jsonify(data_dict),
headers={"Content-Type": "application/json; charset=utf-8"}
)
def parse_request_body(req):
"""
通用请求体解析器:解决解析 bytes、字符串或多重序列化的情况。
"""
body = req.body
try:
if isinstance(body, (bytes, bytearray)):
body = json.loads(body.decode('utf-8'))
if isinstance(body, str):
body = json.loads(body)
return body if isinstance(body, dict) else {}
except Exception as e:
print(f"Request Body Parse Error: {e}")
return {}
# --- 1. 获取全量动态标签 ---
@app.get("/api/kg/labels")
def get_labels(req):
try:
labels = operation_service.get_all_labels()
return create_response(200, {"code": 200, "data": labels, "msg": "success"})
except Exception as e:
traceback.print_exc()
return create_response(500, {"code": 500, "msg": f"获取标签失败: {str(e)}"})
# --- 2. 输入联想建议 ---
@app.get("/api/kg/node/suggest")
def suggest_node(req):
try:
query_data = getattr(req, "queries", getattr(req, "query_params", {}))
raw_keyword = query_data.get("keyword", "")
keyword = raw_keyword[0] if isinstance(raw_keyword, list) and raw_keyword else str(raw_keyword)
clean_keyword = unquote(keyword).strip()
suggestions = operation_service.suggest_nodes(clean_keyword)
return create_response(200, {"code": 200, "data": suggestions, "msg": "success"})
except Exception as e:
traceback.print_exc()
return create_response(500, {"code": 500, "msg": str(e)})
# --- 3. 获取分页节点列表 ---
@app.get("/api/kg/nodes")
def get_nodes(req):
try:
query_data = getattr(req, "queries", getattr(req, "query_params", {}))
page = int(query_data.get("page", "1"))
page_size = int(query_data.get("pageSize", "20"))
res_data = operation_service.get_nodes_subset(page, page_size)
return create_response(200, {"code": 200, "data": res_data, "msg": "success"})
except Exception as e:
traceback.print_exc()
return create_response(500, {"code": 500, "msg": f"获取节点列表失败: {str(e)}"})
# --- 4. 获取分页关系列表 ---
@app.get("/api/kg/relationships")
def get_relationships(req):
try:
query_data = getattr(req, "queries", getattr(req, "query_params", {}))
page = int(query_data.get("page", "1"))
page_size = int(query_data.get("pageSize", "20"))
res_data = operation_service.get_relationships_subset(page, page_size)
return create_response(200, {"code": 200, "data": res_data, "msg": "success"})
except Exception as e:
traceback.print_exc()
return create_response(500, {"code": 500, "msg": f"获取关系列表失败: {str(e)}"})
# --- 5. 新增节点 ---
@app.post("/api/kg/node/add")
def add_node(req):
try:
body = parse_request_body(req)
# 增加 strip() 防止空格导致的匹配失败
label = str(body.get("label", "Drug")).strip()
name = str(body.get("name", "")).strip()
if not name:
return create_response(200, {"code": 400, "msg": "添加失败:节点名称不能为空"})
result = operation_service.add_node(label, name)
return create_response(200, {"code": 200 if result["success"] else 400, "msg": result["msg"]})
except Exception as e:
traceback.print_exc()
return create_response(200, {"code": 500, "msg": f"服务器内部错误: {str(e)}"})
# --- 6. 修改节点 ---
@app.post("/api/kg/node/update")
def update_node(req):
try:
body = parse_request_body(req)
node_id = body.get("id")
name = str(body.get("name", "")).strip()
label = str(body.get("label", "")).strip()
if not node_id or not name:
return create_response(200, {"code": 400, "msg": "修改失败:参数缺失(ID或Name)"})
result = operation_service.update_node(node_id, name, label)
return create_response(200, {"code": 200 if result["success"] else 400, "msg": result["msg"]})
except Exception as e:
traceback.print_exc()
return create_response(200, {"code": 500, "msg": str(e)})
# --- 7. 新增关系 ---
@app.post("/api/kg/rel/add")
def add_relationship(req):
try:
body = parse_request_body(req)
# 强制格式化所有字符串,彻底杜绝数据类型导致的 MATCH 失败
source = str(body.get("source", "")).strip()
target = str(body.get("target", "")).strip()
rel_type = str(body.get("type", "")).strip()
rel_label = str(body.get("label", "")).strip()
if not all([source, target, rel_type]):
return create_response(200, {"code": 400, "msg": "添加失败:起始点、结束点和类型不能为空"})
result = operation_service.add_relationship(source, target, rel_type, rel_label)
return create_response(200, {"code": 200 if result["success"] else 400, "msg": result["msg"]})
except Exception as e:
traceback.print_exc()
return create_response(200, {"code": 500, "msg": f"新增关系异常: {str(e)}"})
# --- 8. 修改关系 ---
@app.post("/api/kg/rel/update")
def update_rel(req):
try:
body = parse_request_body(req)
rel_id = body.get("id")
source = str(body.get("source", "")).strip()
target = str(body.get("target", "")).strip()
rel_type = str(body.get("type", "")).strip()
rel_label = str(body.get("label", "")).strip()
if not all([rel_id, source, target, rel_type]):
return create_response(200, {"code": 400, "msg": "修改失败:必要参数(ID/Source/Target/Type)缺失"})
result = operation_service.update_relationship(rel_id, source, target, rel_type, rel_label)
return create_response(200, {"code": 200 if result["success"] else 400, "msg": result["msg"]})
except Exception as e:
traceback.print_exc()
return create_response(200, {"code": 500, "msg": str(e)})
# --- 9. 删除节点 ---
@app.post("/api/kg/node/delete")
def delete_node(req):
try:
body = parse_request_body(req)
node_id = body.get("id")
if not node_id:
return create_response(200, {"code": 400, "msg": "删除失败:节点ID不能为空"})
operation_service.delete_node(node_id)
return create_response(200, {"code": 200, "msg": "节点及其关联关系已成功删除"})
except Exception as e:
traceback.print_exc()
return create_response(200, {"code": 500, "msg": str(e)})
# --- 10. 删除关系 ---
@app.post("/api/kg/rel/delete")
def delete_rel(req):
try:
body = parse_request_body(req)
rel_id = body.get("id")
if not rel_id:
return create_response(200, {"code": 400, "msg": "删除失败:关系ID不能为空"})
operation_service.delete_relationship(rel_id)
return create_response(200, {"code": 200, "msg": "关系已成功从数据库移除"})
except Exception as e:
traceback.print_exc()
return create_response(200, {"code": 500, "msg": str(e)})