|
@@ -22,6 +22,39 @@ from app.core.llm.llm_service import llm_client as llm_call # 导入core/llm模
|
|
|
|
|
|
logger = logging.getLogger("app")
|
|
logger = logging.getLogger("app")
|
|
|
|
|
|
|
|
+def serialize_neo4j_object(obj):
|
|
|
|
+ """
|
|
|
|
+ 将Neo4j对象转换为可JSON序列化的格式
|
|
|
|
+
|
|
|
|
+ Args:
|
|
|
|
+ obj: Neo4j节点或属性值
|
|
|
|
+
|
|
|
|
+ Returns:
|
|
|
|
+ 序列化后的对象
|
|
|
|
+ """
|
|
|
|
+ if hasattr(obj, 'year'): # DateTime对象
|
|
|
|
+ # 将Neo4j DateTime转换为字符串
|
|
|
|
+ return obj.strftime("%Y-%m-%d %H:%M:%S") if hasattr(obj, 'strftime') else str(obj)
|
|
|
|
+ elif hasattr(obj, '__dict__'): # 复杂对象
|
|
|
|
+ return str(obj)
|
|
|
|
+ else:
|
|
|
|
+ return obj
|
|
|
|
+
|
|
|
|
+def serialize_node_properties(node):
|
|
|
|
+ """
|
|
|
|
+ 将Neo4j节点属性序列化为可JSON化的字典
|
|
|
|
+
|
|
|
|
+ Args:
|
|
|
|
+ node: Neo4j节点对象
|
|
|
|
+
|
|
|
|
+ Returns:
|
|
|
|
+ dict: 序列化后的属性字典
|
|
|
|
+ """
|
|
|
|
+ properties = {}
|
|
|
|
+ for key, value in dict(node).items():
|
|
|
|
+ properties[key] = serialize_neo4j_object(value)
|
|
|
|
+ return properties
|
|
|
|
+
|
|
def get_formatted_time():
|
|
def get_formatted_time():
|
|
"""获取格式化的当前时间"""
|
|
"""获取格式化的当前时间"""
|
|
return time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
|
|
return time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
|
|
@@ -158,7 +191,7 @@ def meta_list(page, page_size, search="", en_name_filter=None,
|
|
# 格式化结果
|
|
# 格式化结果
|
|
result_list = []
|
|
result_list = []
|
|
for record in result:
|
|
for record in result:
|
|
- node = dict(record["n"])
|
|
|
|
|
|
+ node = serialize_node_properties(record["n"])
|
|
node["id"] = record["n"].id
|
|
node["id"] = record["n"].id
|
|
result_list.append(node)
|
|
result_list.append(node)
|
|
|
|
|
|
@@ -170,12 +203,24 @@ def meta_list(page, page_size, search="", en_name_filter=None,
|
|
def handle_id_unstructured(node_id):
|
|
def handle_id_unstructured(node_id):
|
|
"""处理非结构化数据节点"""
|
|
"""处理非结构化数据节点"""
|
|
try:
|
|
try:
|
|
|
|
+ # 参数验证
|
|
|
|
+ if node_id is None:
|
|
|
|
+ logger.error("node_id参数不能为None")
|
|
|
|
+ return None
|
|
|
|
+
|
|
|
|
+ # 确保node_id为整数
|
|
|
|
+ try:
|
|
|
|
+ node_id_int = int(node_id)
|
|
|
|
+ except (ValueError, TypeError):
|
|
|
|
+ logger.error(f"node_id不是有效的整数: {node_id}")
|
|
|
|
+ return None
|
|
|
|
+
|
|
with neo4j_driver.get_session() as session:
|
|
with neo4j_driver.get_session() as session:
|
|
query = "MATCH (n) WHERE id(n) = $node_id RETURN n"
|
|
query = "MATCH (n) WHERE id(n) = $node_id RETURN n"
|
|
- result = session.run(query, node_id=int(node_id))
|
|
|
|
|
|
+ result = session.run(query, node_id=node_id_int)
|
|
node = result.single()
|
|
node = result.single()
|
|
if node:
|
|
if node:
|
|
- return dict(node["n"])
|
|
|
|
|
|
+ return serialize_node_properties(node["n"])
|
|
else:
|
|
else:
|
|
return None
|
|
return None
|
|
except Exception as e:
|
|
except Exception as e:
|
|
@@ -265,6 +310,18 @@ def meta_kinship_graph(node_id):
|
|
dict: 图谱数据
|
|
dict: 图谱数据
|
|
"""
|
|
"""
|
|
try:
|
|
try:
|
|
|
|
+ # 参数验证
|
|
|
|
+ if node_id is None:
|
|
|
|
+ logger.error("node_id参数不能为None")
|
|
|
|
+ return {"nodes": [], "relationships": []}
|
|
|
|
+
|
|
|
|
+ # 确保node_id为整数
|
|
|
|
+ try:
|
|
|
|
+ node_id_int = int(node_id)
|
|
|
|
+ except (ValueError, TypeError):
|
|
|
|
+ logger.error(f"node_id不是有效的整数: {node_id}")
|
|
|
|
+ return {"nodes": [], "relationships": []}
|
|
|
|
+
|
|
with neo4j_driver.get_session() as session:
|
|
with neo4j_driver.get_session() as session:
|
|
# 获取节点和直接关系
|
|
# 获取节点和直接关系
|
|
cypher = """
|
|
cypher = """
|
|
@@ -272,7 +329,7 @@ def meta_kinship_graph(node_id):
|
|
WHERE id(n) = $node_id
|
|
WHERE id(n) = $node_id
|
|
RETURN n, r, m
|
|
RETURN n, r, m
|
|
"""
|
|
"""
|
|
- result = session.run(cypher, node_id=int(node_id))
|
|
|
|
|
|
+ result = session.run(cypher, node_id=node_id_int)
|
|
|
|
|
|
# 格式化结果为图谱数据
|
|
# 格式化结果为图谱数据
|
|
nodes = {}
|
|
nodes = {}
|
|
@@ -280,12 +337,12 @@ def meta_kinship_graph(node_id):
|
|
|
|
|
|
for record in result:
|
|
for record in result:
|
|
# 处理源节点
|
|
# 处理源节点
|
|
- source_node = dict(record["n"])
|
|
|
|
|
|
+ source_node = serialize_node_properties(record["n"])
|
|
source_node["id"] = record["n"].id
|
|
source_node["id"] = record["n"].id
|
|
nodes[source_node["id"]] = source_node
|
|
nodes[source_node["id"]] = source_node
|
|
|
|
|
|
# 处理目标节点
|
|
# 处理目标节点
|
|
- target_node = dict(record["m"])
|
|
|
|
|
|
+ target_node = serialize_node_properties(record["m"])
|
|
target_node["id"] = record["m"].id
|
|
target_node["id"] = record["m"].id
|
|
nodes[target_node["id"]] = target_node
|
|
nodes[target_node["id"]] = target_node
|
|
|
|
|
|
@@ -321,6 +378,18 @@ def meta_impact_graph(node_id):
|
|
dict: 图谱数据
|
|
dict: 图谱数据
|
|
"""
|
|
"""
|
|
try:
|
|
try:
|
|
|
|
+ # 参数验证
|
|
|
|
+ if node_id is None:
|
|
|
|
+ logger.error("node_id参数不能为None")
|
|
|
|
+ return {"nodes": [], "relationships": []}
|
|
|
|
+
|
|
|
|
+ # 确保node_id为整数
|
|
|
|
+ try:
|
|
|
|
+ node_id_int = int(node_id)
|
|
|
|
+ except (ValueError, TypeError):
|
|
|
|
+ logger.error(f"node_id不是有效的整数: {node_id}")
|
|
|
|
+ return {"nodes": [], "relationships": []}
|
|
|
|
+
|
|
with neo4j_driver.get_session() as session:
|
|
with neo4j_driver.get_session() as session:
|
|
# 获取所有可达节点和关系
|
|
# 获取所有可达节点和关系
|
|
cypher = """
|
|
cypher = """
|
|
@@ -328,7 +397,7 @@ def meta_impact_graph(node_id):
|
|
WHERE id(n) = $node_id
|
|
WHERE id(n) = $node_id
|
|
RETURN path
|
|
RETURN path
|
|
"""
|
|
"""
|
|
- result = session.run(cypher, node_id=int(node_id))
|
|
|
|
|
|
+ result = session.run(cypher, node_id=node_id_int)
|
|
|
|
|
|
# 格式化结果
|
|
# 格式化结果
|
|
nodes = {}
|
|
nodes = {}
|
|
@@ -339,7 +408,7 @@ def meta_impact_graph(node_id):
|
|
|
|
|
|
# 处理路径中的所有节点
|
|
# 处理路径中的所有节点
|
|
for node in path.nodes:
|
|
for node in path.nodes:
|
|
- node_dict = dict(node)
|
|
|
|
|
|
+ node_dict = serialize_node_properties(node)
|
|
node_dict["id"] = node.id
|
|
node_dict["id"] = node.id
|
|
nodes[node.id] = node_dict
|
|
nodes[node.id] = node_dict
|
|
|
|
|
|
@@ -400,11 +469,23 @@ def parse_entity_relation(text):
|
|
def handle_txt_graph(node_id, entity, entity_en):
|
|
def handle_txt_graph(node_id, entity, entity_en):
|
|
"""处理文本图谱创建"""
|
|
"""处理文本图谱创建"""
|
|
try:
|
|
try:
|
|
|
|
+ # 参数验证
|
|
|
|
+ if node_id is None:
|
|
|
|
+ logger.error("node_id参数不能为None")
|
|
|
|
+ return False
|
|
|
|
+
|
|
|
|
+ # 确保node_id为整数
|
|
|
|
+ try:
|
|
|
|
+ node_id_int = int(node_id)
|
|
|
|
+ except (ValueError, TypeError):
|
|
|
|
+ logger.error(f"node_id不是有效的整数: {node_id}")
|
|
|
|
+ return False
|
|
|
|
+
|
|
# 创建实体节点
|
|
# 创建实体节点
|
|
with neo4j_driver.get_session() as session:
|
|
with neo4j_driver.get_session() as session:
|
|
# 查找源节点
|
|
# 查找源节点
|
|
query = "MATCH (n) WHERE id(n) = $node_id RETURN n"
|
|
query = "MATCH (n) WHERE id(n) = $node_id RETURN n"
|
|
- result = session.run(query, node_id=int(node_id))
|
|
|
|
|
|
+ result = session.run(query, node_id=node_id_int)
|
|
source_node = result.single()["n"]
|
|
source_node = result.single()["n"]
|
|
|
|
|
|
if not source_node:
|
|
if not source_node:
|