Selaa lähdekoodia

修正生产线管理的列表的api

wangxq 1 kuukausi sitten
vanhempi
commit
60cb50b9d2

+ 1 - 38
app/api/data_resource/routes.py

@@ -113,44 +113,7 @@ def data_resource_translate():
     except Exception as e:
         return jsonify(failed({}, str(e)))
 
-    # 废弃的翻译方法
-    # """数据资源翻译"""
-    # try:
-    #     # 获取表单数据
-    #     name = request.json.get('name', '')
-    #     en_name = request.json.get('en_name', '')
-    #     data_type = request.json.get('data_type', 'table')
-    #     is_file = request.json.get('is_file', False)
-        
-    #     # 验证输入
-    #     if not name:
-    #         return jsonify(failed("名称不能为空"))
-            
-    #     # 如果已经提供了英文名,则直接使用
-    #     if en_name and is_english(en_name):
-    #         translated = True
-    #         return jsonify(success({"name": name, "en_name": en_name, "translated": translated}))
-        
-    #     # 否则进行翻译
-    #     try:
-    #         if data_type == 'table':
-    #             prompt = f"""将以下数据表名(中文)翻译成英文,不需要额外说明:
-    #             中文:{name}
-    #             英文(snake_case格式):
-    #             """
-    #             result = text_resource_solve(None, name, "")
-    #             translated = True
-    #             return jsonify(success({"name": name, "en_name": result["en_name"], "translated": translated}))
-    #         else:
-    #             result = text_resource_solve(None, name, "")
-    #             translated = True
-    #             return jsonify(success({"name": name, "en_name": result["en_name"], "translated": translated}))
-    #     except Exception as e:
-    #         logger.error(f"翻译失败: {str(e)}")
-    #         return jsonify(failed(f"翻译失败: {str(e)}"))
-    # except Exception as e:
-    #     logger.error(f"处理数据资源翻译请求失败: {str(e)}")
-    #     return jsonify(failed(str(e)))
+  
 
 @bp.route('/save', methods=['POST'])
 def data_resource_save():

+ 62 - 19
app/api/production_line/routes.py

@@ -50,15 +50,24 @@ def production_line_list():
         SKIP {skip_count}
         LIMIT {page_size}
         """
-        data = connect_graph.run(cql).data()
-        records = []
-        for item in data:
-            records.append(item['result'])
+        
+        # 修复:使用正确的session方式执行查询
+        driver = connect_graph()
+        if not driver:
+            return json.dumps(failed("无法连接到数据库"), ensure_ascii=False, cls=MyEncoder)
+            
+        with driver.session() as session:
+            result = session.run(cql)
+            data = result.data()
+            records = []
+            for item in data:
+                records.append(item['result'])
 
-        # 获取总量
-        total_query = f"MATCH (n) WHERE (n:data_model OR n:data_resource OR n:data_metric) AND {where_clause}" \
-                      f" RETURN COUNT(n) AS total"
-        total_result = connect_graph.run(total_query).evaluate()
+            # 获取总量
+            total_query = f"MATCH (n) WHERE (n:data_model OR n:data_resource OR n:data_metric) AND {where_clause}" \
+                        f" RETURN COUNT(n) AS total"
+            total_result = session.run(total_query).single()["total"]
+        
         response_data = {'records': records, 'total': total_result, 'size': page_size, 'current': page}
         res = success(response_data, "success")
         return json.dumps(res, ensure_ascii=False, cls=MyEncoder)
@@ -80,21 +89,55 @@ def production_line_graph():
     Returns:
         JSON: 包含图谱数据的响应
     """
-    # 传入请求参数
-    receiver = request.get_json()
-    id = receiver['id']
     try:
-        cql = """
-        MATCH (n) where id(n) = $nodeId return labels(n)[0] as type
-        """
-        type = connect_graph.run(cql, nodeId=id).evaluate()
+        # 获取请求参数
+        receiver = request.get_json()
+        if not receiver or 'id' not in receiver:
+            return json.dumps(failed("缺少必要参数: id"), ensure_ascii=False, cls=MyEncoder)
+            
+        id = receiver['id']
+        # 修改: 专门处理ID为0的情况,将ID类型视为整数
+        if id is None:
+            return json.dumps(failed("节点ID不能为空"), ensure_ascii=False, cls=MyEncoder)
+            
+        # 确保ID是整数类型
+        try:
+            id = int(id)
+        except (ValueError, TypeError):
+            return json.dumps(failed("节点ID必须是整数"), ensure_ascii=False, cls=MyEncoder)
+            
+        # 修复:使用正确的session方式执行查询
+        driver = connect_graph()
+        if not driver:
+            return json.dumps(failed("无法连接到数据库"), ensure_ascii=False, cls=MyEncoder)
+            
+        with driver.session() as session:
+            # 检查节点是否存在
+            check_query = """
+            MATCH (n) WHERE id(n) = $nodeId 
+            RETURN labels(n)[0] as type, n.name as name
+            """
+            result = session.run(check_query, nodeId=id)
+            record = result.single()
+            
+            if not record:
+                return json.dumps(failed(f"节点不存在: ID={id}"), ensure_ascii=False, cls=MyEncoder)
+                
+            type = record["type"]
+            
+        # 生成图谱
         data = production_draw_graph(id, type)
-        res = success(data, "success")
-        return json.dumps(res, ensure_ascii=False, cls=MyEncoder)
+        
+        # 检查返回结果是否包含错误
+        if "error" in data:
+            error_msg = data.pop("error")
+            return json.dumps(failed(error_msg, data), ensure_ascii=False, cls=MyEncoder)
+        
+        return json.dumps(success(data, "success"), ensure_ascii=False, cls=MyEncoder)
 
     except Exception as e:
-        res = failed({}, {"error": f"{e}"})
-        return json.dumps(res, ensure_ascii=False, cls=MyEncoder)
+        logger.error(f"生成图谱失败: {str(e)}")
+        return json.dumps(failed(str(e)), ensure_ascii=False, cls=MyEncoder)
 
 
 """

+ 2 - 1
app/config/config.py

@@ -82,7 +82,8 @@ class Config:
     NEO4J_URI = "bolt://192.168.67.138:7687"
     NEO4J_HTTP_URI = "http://192.168.67.138:7474"
     NEO4J_USER = "neo4j"
-    NEO4J_PASSWORD = "Doudou312$"
+    NEO4J_PASSWORD = "password"
+    #NEO4J_PASSWORD = "Doudou312$"
     NEO4J_ENCRYPTED = False  # 内网环境可关闭加密 
 
     # Neo4j配置段

+ 136 - 85
app/core/production_line/production_line.py

@@ -20,91 +20,142 @@ def production_draw_graph(id, type):
     Returns:
         dict: 包含节点、连线和根节点ID的图谱数据
     """
-    # 数据模型
-    if type == "data_model":
-        cql = """
-        MATCH (n)
-        WHERE id(n) = $nodeId AND labels(n)[0] = "data_model"
-        MATCH (n)-[r:connection]-(m:meta_node)
-        OPTIONAL MATCH (n)-[r2:clean_model]-(d:data_standard)
-        OPTIONAL MATCH (d)-[r3:clean_model]-(m)
-        WITH 
-             collect({from: toString(id(n)), to: toString(id(m)), text: "包含"}) AS line1,
-             collect({from: toString(id(n)), to: toString(id(d)), text: "清洗"}) AS line2,
-             collect({from: toString(id(d)), to: toString(id(m)), text: "清洗"}) AS line3,
-             collect({id: toString(id(n)), text: n.name, type: "model"}) AS node1,
-             collect({id: toString(id(m)), text: m.name}) AS node2,
-             collect({id: toString(id(d)), text: d.name, type: "standard"}) AS node3,n
-        WITH apoc.coll.toSet(line1 + line2 + line3) AS lines,
-             apoc.coll.toSet(node1 + node2 + node3) AS nodes,
-             toString(id(n)) as res
-        RETURN lines,nodes,res
-        """
-        data = connect_graph.run(cql, nodeId=id).data()
-        res = {}
-        for item in data:
-            res = {
-                "nodes": [record for record in item['nodes'] if record['id']],
-                "lines": [record for record in item['lines'] if record['from'] and record['to']],
-                "rootId": item['res'],
-            }
-
-        return res
-    # 数据资源
-    elif type == "data_resource":
-        cql = """
-        MATCH (n)
-        WHERE id(n) = $nodeId AND labels(n)[0] = "data_resource"
-        MATCH (n)-[r:connection]-(m:meta_node)
-        OPTIONAL MATCH (n)-[r2:clean_resource]-(d:data_standard)
-        OPTIONAL MATCH (d)-[r3:clean_resource]-(m)
-        WITH 
-            collect({from: toString(id(n)), to: toString(id(m)), text: "包含"}) AS lines1,
-            collect({from: toString(id(n)), to: toString(id(d)), text: "清洗"}) AS lines2,
-            collect({from: toString(id(d)), to: toString(id(m)), text: "清洗"}) AS lines3,
-            collect({id: toString(id(n)), text: n.name, type: "resource"}) AS nodes1,
-            collect({id: toString(id(m)), text: m.name}) AS nodes2,
-            collect({id: toString(id(d)), text: d.name, type: "standard"}) AS nodes3,n     
-        WITH 
-            apoc.coll.toSet(lines1 + lines2 + lines3) AS lines,
-            apoc.coll.toSet(nodes1 + nodes2 + nodes3) AS nodes,
-            toString(id(n)) AS res       
-        RETURN lines, nodes, res
-        """
-        data = connect_graph.run(cql, nodeId=id).data()
-        res = {}
-        for item in data:
-            res = {
-                "nodes": [record for record in item['nodes'] if record['id']],
-                "lines": [record for record in item['lines'] if record['from'] and record['to'] ],
-                "rootId": item['res'],
-            }
-
-        return res
-    # 数据指标
-    elif type == "data_metric":
-        cql = """
-                MATCH (n)
-                WHERE id(n) = $nodeId AND labels(n)[0] = "data_metric"
-                MATCH (n)-[r:connection]-(m:meta_node)
-                WITH collect({from: toString(id(n)), to: toString(id(m)), text: "处理"}) AS line1,
-                    collect({id: toString(id(n)), text: n.name, type: "etric"}) AS node1,
-                    collect({id: toString(id(m)), text: m.name}) AS node2,n
-                WITH apoc.coll.toSet(line1) AS lines,
-                    apoc.coll.toSet(node1 + node2) AS nodes,
-                    toString(id(n)) as res
-                RETURN lines,nodes,res
-                """
-        data = connect_graph.run(cql, nodeId=id).data()
-        res = {}
-        for item in data:
-            res = {
-                "nodes": [record for record in item['nodes'] if record['id']],
-                "lines": [record for record in item['lines'] if record['from'] and record['to']],
-                "rootId": item['res'],
-            }
-
-        return res 
+    # 获取Neo4j连接
+    driver = connect_graph()
+    if not driver:
+        logger.error("无法连接到数据库")
+        return {"nodes": [], "lines": [], "rootId": "", "error": "无法连接到数据库"}
+    
+    try:
+        # 首先验证节点是否存在
+        with driver.session() as session:
+            check_node_query = """
+            MATCH (n) 
+            WHERE id(n) = $nodeId 
+            RETURN n, labels(n) as labels, n.name as name
+            """
+            check_result = session.run(check_node_query, nodeId=id).single()
+            
+            if not check_result:
+                logger.error(f"节点不存在: ID={id}")
+                return {"nodes": [], "lines": [], "rootId": "", "error": "节点不存在"}
+            
+            actual_type = check_result["labels"][0]  # 获取实际的节点类型
+            node_name = check_result["name"]
+            
+            # 如果提供的类型与实际类型不匹配,使用实际类型
+            if type.lower() != actual_type.lower():
+                logger.warning(f"提供的类型({type})与实际类型({actual_type})不匹配,使用实际类型")
+                type = actual_type
+        
+        # 数据模型
+        if type.lower() == "data_model":
+            cql = """
+            MATCH (n:data_model)
+            WHERE id(n) = $nodeId
+            OPTIONAL MATCH (n)-[r:connection]-(m:meta_node)
+            OPTIONAL MATCH (n)-[r2:clean_model]-(d:data_standard)
+            OPTIONAL MATCH (d)-[r3:clean_model]-(m)
+            WITH 
+                 collect({from: toString(id(n)), to: toString(id(m)), text: "包含"}) AS line1,
+                 collect({from: toString(id(n)), to: toString(id(d)), text: "清洗"}) AS line2,
+                 collect({from: toString(id(d)), to: toString(id(m)), text: "清洗"}) AS line3,
+                 collect({id: toString(id(n)), text: n.name, type: "model"}) AS node1,
+                 collect({id: toString(id(m)), text: m.name}) AS node2,
+                 collect({id: toString(id(d)), text: d.name, type: "standard"}) AS node3,n
+            WITH apoc.coll.toSet(line1 + line2 + line3) AS lines,
+                 apoc.coll.toSet(node1 + node2 + node3) AS nodes,
+                 toString(id(n)) as res
+            RETURN lines,nodes,res
+            """
+        # 数据资源
+        elif type.lower() == "data_resource":
+            cql = """
+            MATCH (n:data_resource)
+            WHERE id(n) = $nodeId
+            OPTIONAL MATCH (n)-[r:connection]-(m:meta_node)
+            OPTIONAL MATCH (n)-[r2:clean_resource]-(d:data_standard)
+            OPTIONAL MATCH (d)-[r3:clean_resource]-(m)
+            WITH 
+                collect({from: toString(id(n)), to: toString(id(m)), text: "包含"}) AS lines1,
+                collect({from: toString(id(n)), to: toString(id(d)), text: "清洗"}) AS lines2,
+                collect({from: toString(id(d)), to: toString(id(m)), text: "清洗"}) AS lines3,
+                collect({id: toString(id(n)), text: n.name, type: "resource"}) AS nodes1,
+                collect({id: toString(id(m)), text: m.name}) AS nodes2,
+                collect({id: toString(id(d)), text: d.name, type: "standard"}) AS nodes3,n     
+            WITH 
+                apoc.coll.toSet(lines1 + lines2 + lines3) AS lines,
+                apoc.coll.toSet(nodes1 + nodes2 + nodes3) AS nodes,
+                toString(id(n)) AS res       
+            RETURN lines, nodes, res
+            """
+        # 数据指标
+        elif type.lower() == "data_metric":
+            cql = """
+            MATCH (n:data_metric)
+            WHERE id(n) = $nodeId
+            OPTIONAL MATCH (n)-[r:connection]-(m:meta_node)
+            WITH collect({from: toString(id(n)), to: toString(id(m)), text: "处理"}) AS line1,
+                collect({id: toString(id(n)), text: n.name, type: "metric"}) AS node1,
+                collect({id: toString(id(m)), text: m.name}) AS node2,n
+            WITH apoc.coll.toSet(line1) AS lines,
+                apoc.coll.toSet(node1 + node2) AS nodes,
+                toString(id(n)) as res
+            RETURN lines,nodes,res
+            """
+        else:
+            # 处理未知节点类型
+            cql = """
+            MATCH (n)
+            WHERE id(n) = $nodeId
+            OPTIONAL MATCH (n)-[r]-(m)
+            WITH collect({from: toString(id(n)), to: toString(id(m)), text: type(r)}) AS lines,
+                 collect({id: toString(id(n)), text: n.name, type: labels(n)[0]}) AS nodes1,
+                 collect({id: toString(id(m)), text: m.name, type: labels(m)[0]}) AS nodes2,
+                 toString(id(n)) as res
+            RETURN apoc.coll.toSet(lines) AS lines, 
+                   apoc.coll.toSet(nodes1 + nodes2) AS nodes, 
+                   res
+            """
+            
+        with driver.session() as session:
+            try:
+                result = session.run(cql, nodeId=id)
+                data = result.data()
+                
+                # 如果没有数据,返回节点自身
+                if not data:
+                    return {
+                        "nodes": [{"id": str(id), "text": node_name, "type": type}],
+                        "lines": [],
+                        "rootId": str(id)
+                    }
+                
+                res = {}
+                for item in data:
+                    res = {
+                        "nodes": [record for record in item['nodes'] if record.get('id')],
+                        "lines": [record for record in item['lines'] if record.get('from') and record.get('to')],
+                        "rootId": item['res'],
+                    }
+                
+                # 确保节点列表不为空
+                if not res.get("nodes"):
+                    res["nodes"] = [{"id": str(id), "text": node_name, "type": type}]
+                
+                return res
+            except Exception as e:
+                logger.error(f"执行图谱查询失败: {str(e)}")
+                return {
+                    "nodes": [{"id": str(id), "text": node_name, "type": type}],
+                    "lines": [],
+                    "rootId": str(id),
+                    "error": f"查询执行失败: {str(e)}"
+                }
+                
+    except Exception as e:
+        logger.error(f"生成图谱失败: {str(e)}")
+        return {"nodes": [], "lines": [], "rootId": "", "error": str(e)}
 
 """
 Manual execution functions for production line