from fastapi import APIRouter, Depends, HTTPException, status from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm from pydantic import BaseModel from datetime import datetime, timedelta from typing import Optional from passlib.context import CryptContext from db.neo4j import get_neo4j_db # 路由 router = APIRouter() def get_node_value(n): label = str(n.labels) if label == ":Disease": return 7000 if label == ":Department": return 6000 if label == ":Symptom": return 5500 if label == ":Drug": return 5000 return 4000 @router.get("/api/graph/{node_id}") def get_graph_node_by_id(node_id: str): graph = get_neo4j_db() data = { "nodes":[], "edges":[]} graph = get_neo4j_db() result = graph.run(f"match path=(n)-[*1]->(p) where id(n)={node_id} or id(p)={node_id} return nodes(path) as nodes,relationships(path) as relations limit 50") ids = [] for r in result: nodes = r["nodes"] relations = r["relations"] for n in nodes: if n.identity in ids: continue else: ids.append(n.identity) data["nodes"].append({"id": n.identity, "name": n["name"], "value":get_node_value(n)}) for r in relations: start_pos = ids.index(r.start_node.identity) end_pos = ids.index(r.end_node.identity) if start_pos >=0 and end_pos >=0: data["edges"].append({"id": r.identity, "name": type(r).__name__, "start": start_pos, "end":end_pos}) return { "status": 200, "data": data} @router.get("/api/node/{node_id}") def get_node_by_id(node_id: str): graph = get_neo4j_db() data = { "nodes":[]} graph = get_neo4j_db() result = graph.run(f"match (n) where id(n)={node_id} return n") for r in result: node = r["n"] itemData = {"id": node.identity,"type":str(node.labels), "name": node.get("name"), "value":5000, "props": []} for item in node.items(): key, value = item if isinstance(value,list): value = ",".join(value) itemData["props"].append({ "name" : key, "value":value}) data["nodes"].append(itemData) return { "status": 200, "data": data} @router.get("/api/edge/{node_id}") def get_edge_by_id(node_id: str): graph = get_neo4j_db() data = { "edges":[]} graph = get_neo4j_db() result = graph.run(f"match (n)-[r]->(p) where id(r)={node_id} return r") for r in result: edges = r["r"] itemData = {"id": edges.identity,"type":type(edges).__name__, "name": edges.get("name"), "value":5000, "props": []} for item in edges.items(): key, value = item if isinstance(value,list): value = ",".join(value) itemData["props"].append({ "name" : key, "value":value}) data["edges"].append(itemData) return { "status": 200, "data": data} @router.get("/api/graph-search/{name}") def search_node_by_name(name: str): graph = get_neo4j_db() data = { "nodes":[], "edges":[]} graph = get_neo4j_db() result = graph.run(f"match path=(n)-[*1]->(p) where n.name contains \"{name}\" return nodes(path) as nodes,relationships(path) as relations limit 50") ids = [] for r in result: nodes = r["nodes"] relations = r["relations"] for n in nodes: if n.identity in ids: continue else: ids.append(n.identity) data["nodes"].append({"id": n.identity, "name": n["name"], "value":get_node_value(n)}) for r in relations: start_pos = ids.index(r.start_node.identity) end_pos = ids.index(r.end_node.identity) if start_pos >=0 and end_pos >=0: data["edges"].append({"id": r.identity, "name": type(r).__name__, "start": start_pos, "end":end_pos}) return { "status": 200, "data": data} graph_router = router