From 883e54860e2da6f2fa181ab3f04f8f217c7b0140 Mon Sep 17 00:00:00 2001 From: hanyuqing <1106611654@qq.com> Date: Tue, 23 Dec 2025 16:42:46 +0800 Subject: [PATCH] all --- controller/GraphController.py | 36 ++++++++++++++++++++++++++++++++++-- util/neo4j_utils.py | 41 +++++++++++++++++++++++++++-------------- vue/src/api/builder.js | 15 +++++++++++++++ vue/src/system/GraphBuilder.vue | 8 ++++++-- 4 files changed, 82 insertions(+), 18 deletions(-) create mode 100644 vue/src/api/builder.js diff --git a/controller/GraphController.py b/controller/GraphController.py index c17579c..f70c951 100644 --- a/controller/GraphController.py +++ b/controller/GraphController.py @@ -1,6 +1,9 @@ import json import sys from datetime import datetime + +import httpx + from app import app from robyn import Robyn, jsonify, Response @@ -74,7 +77,6 @@ def get_data(): direction="both", rel_type=None ) - return Response( status_code=200, description=jsonify(graph_data), @@ -204,4 +206,34 @@ def get_check_tree(): def health(): print(redis_get(DRUG_TREE_KEY)) print(redis_get(CHECK_TREE_KEY)) - return {"status": "ok", "drug_cached": redis_get(DRUG_TREE_KEY) is not None} \ No newline at end of file + return {"status": "ok", "drug_cached": redis_get(DRUG_TREE_KEY) is not None} + + +@app.post("/api/analyze") +async def analyze(request): + try: + # 假设前端传入 JSON: {"text": "病例文本..."} + body = request.json() + input_text = body.get("text", "").strip() + + if not input_text: + return jsonify({"error": "缺少 text 字段"}), 400 + client = httpx.AsyncClient(base_url="http://192.168.50.113:8088") + # 调用实体关系抽取服务 + response = await client.post( + "/extract_entities_and_relations", + json={"text": input_text} + ) + print(response) + if response.status_code == 200: + result = response.json() + return jsonify(result) + else: + return jsonify({ + "error": "实体抽取服务返回错误", + "status": response.status_code, + "detail": response.text + }), response.status_code + + except Exception as e: + return jsonify({"error": str(e)}), 500 \ No newline at end of file diff --git a/util/neo4j_utils.py b/util/neo4j_utils.py index 96b81df..00ede2c 100644 --- a/util/neo4j_utils.py +++ b/util/neo4j_utils.py @@ -1,4 +1,5 @@ # neo4j_util.py +import traceback from datetime import datetime import logging from typing import Dict, List, Optional, Any @@ -263,7 +264,7 @@ class Neo4jUtil: node_properties: Dict[str, Any], direction: str = "both", rel_type: Optional[str] = None, - limit: int = 500, # 👈 新增参数,默认 1000 + limit: int = 2000, # 👈 新增参数,默认 1000 ) -> List[Dict[str, Any]]: """ 查询指定节点的邻居(最多返回 limit 条) @@ -288,17 +289,19 @@ class Neo4jUtil: else: raise ValueError("direction 必须是 'out', 'in' 或 'both'") - # ✅ 添加 LIMIT cypher = f""" MATCH {pattern} WHERE {where_clause} + WITH r, startNode(r) AS s, endNode(r) AS t RETURN - elementId(n) AS sourceId, - head(labels(n)) AS sourceLabel, - n{{.*}} AS sourceProps, - elementId(m) AS targetId, - head(labels(m)) AS targetLabel, - m{{.*}} AS targetProps, + elementId(s) AS sourceId, + head(labels(s)) AS sourceLabel, + s{{.*}} AS sourceProps, + + elementId(t) AS targetId, + head(labels(t)) AS targetLabel, + t{{.*}} AS targetProps, + elementId(r) AS relId, type(r) AS relType, r{{.*}} AS relProps @@ -306,28 +309,38 @@ class Neo4jUtil: """ params["limit"] = limit # 注入 limit 参数(安全) - raw_results = self.execute_read(cypher, params) - + # ✅ 安全执行查询 + try: + raw_results = self.execute_read(cypher, params) + except Exception as e: + # 可选:记录原始错误(如果你有 logger) + # self.logger.error(f"Neo4j 查询失败: {str(e)}\nCypher: {cypher}\nParams: {params}") + traceback.print_exc() # 这会打印完整的 traceback 到 stderr + # 抛出更友好的运行时错误 + raise RuntimeError( + f"查询邻居节点时发生数据库错误: {str(e)}" + ) from e # 使用 'from e' 保留原始异常链 + print(raw_results) neighbors = [] + print("Ssssssssss") + print(len(raw_results)) for row in raw_results: source = dict(row["sourceProps"]) source.update({"id": row["sourceId"], "label": row["sourceLabel"]}) - target = dict(row["targetProps"]) target.update({"id": row["targetId"], "label": row["targetLabel"]}) - relationship = { "id": row["relId"], "type": row["relType"], "properties": dict(row["relProps"]) if row["relProps"] else {} } - neighbors.append({ "source": source, "target": target, "relationship": relationship }) - + print(relationship) + print(neighbors) return neighbors # def find_neighbors_with_relationships( # self, diff --git a/vue/src/api/builder.js b/vue/src/api/builder.js new file mode 100644 index 0000000..627d2d6 --- /dev/null +++ b/vue/src/api/builder.js @@ -0,0 +1,15 @@ + +// src/api/graph.js +import request from '@/utils/request'; + +/** + * 获取测试图谱数据(固定返回 Disease 及其所有关系) + * 后端接口:GET /test (无参数) + */ +export function analyze(data) { + return request({ + url: '/api/analyze', + method: 'post', + data + }); +} diff --git a/vue/src/system/GraphBuilder.vue b/vue/src/system/GraphBuilder.vue index bfed56c..4d6ea53 100644 --- a/vue/src/system/GraphBuilder.vue +++ b/vue/src/system/GraphBuilder.vue @@ -59,6 +59,8 @@