from flask import request from app.api.data_interface import bp from app.models.result import success, failed from app.core.graph.graph_operations import connect_graph, MyEncoder, create_or_get_node from app.core.data_interface import interface from app.core.meta_data import translate_and_parse, get_formatted_time from app.core.llm import code_generate_standard import json # 数据标准新增 data_standard @bp.route('/data/standard/add', methods=['POST']) def data_standard_add(): try: # 传入请求参数 receiver = request.get_json() name_zh = receiver['name_zh'] # 中文名称 name_en = translate_and_parse(name_zh) # 英文名 receiver['name_en'] = name_en[0] receiver['create_time'] = get_formatted_time() receiver['tag'] = json.dumps(receiver['tag'], ensure_ascii=False) create_or_get_node('data_standard', **receiver) res = success('', "success") return json.dumps(res, ensure_ascii=False, cls=MyEncoder) except Exception as e: res = failed({}, {"error": f"{e}"}) return json.dumps(res, ensure_ascii=False, cls=MyEncoder) # 数据标准详情 data_standard @bp.route('/data/standard/detail', methods=['POST']) def data_standard_detail(): try: # 传入请求参数 receiver = request.get_json() nodeid = receiver['id'] # id cql = """MATCH (n:data_standard) where id(n) = $nodeId RETURN properties(n) as property""" # Create a session from the driver returned by connect_graph with connect_graph().session() as session: property = session.run(cql, nodeId=nodeid).evaluate() if "tag" not in property: property["tag"] = None else: property["tag"] = json.loads(property["tag"]) if "describe" not in property: property["describe"] = None res = success(property, "success") return json.dumps(res, ensure_ascii=False, cls=MyEncoder) except Exception as e: res = failed({}, {"error": f"{e}"}) return json.dumps(res, ensure_ascii=False, cls=MyEncoder) # 数据标准代码 data_standard @bp.route('/data/standard/code', methods=['POST']) def data_standard_code(): try: # 传入请求参数 receiver = request.get_json() input = receiver['input'] describe = receiver['describe'] output = receiver['output'] relation = { "输入参数": input, "输出参数": output } result = code_generate_standard(describe, relation) res = success(result, "success") return json.dumps(res, ensure_ascii=False, cls=MyEncoder) except Exception as e: res = failed({}, {"error": f"{e}"}) return json.dumps(res, ensure_ascii=False, cls=MyEncoder) # 数据标准更新 data_standard 未加到接口文档 @bp.route('/data/standard/update', methods=['POST']) def data_standard_update(): try: # 传入请求参数 receiver = request.get_json() name_zh = receiver['name_zh'] # 中文名称 name_en = translate_and_parse(name_zh) # 英文名 receiver['name_en'] = name_en[0] receiver['create_time'] = get_formatted_time() create_or_get_node('data_standard', **receiver) res = success('', "success") return json.dumps(res, ensure_ascii=False, cls=MyEncoder) except Exception as e: res = failed({}, {"error": f"{e}"}) return json.dumps(res, ensure_ascii=False, cls=MyEncoder) # 数据标准列表展示 @bp.route('/data/standard/list', methods=['POST']) def data_standard_list(): try: # 传入请求参数 receiver = request.get_json() page = int(receiver.get('current', 1)) page_size = int(receiver.get('size', 10)) name_en_filter = receiver.get('name_en', None) name_zh_filter = receiver.get('name_zh', None) category = receiver.get('category', None) time = receiver.get('time', None) # 计算跳过的记录的数量 skip_count = (page - 1) * page_size data, total = interface.standard_list(skip_count, page_size, name_en_filter, name_zh_filter, category, time) response_data = {'records': data, 'total': total, 'size': page_size, 'current': page} res = success(response_data, "success") return json.dumps(res, ensure_ascii=False, cls=MyEncoder) except Exception as e: res = failed({}, {"error": f"{e}"}) return json.dumps(res, ensure_ascii=False, cls=MyEncoder) # 数据标准的图谱(血缘关系Kinship+影响关系Impact+所有关系all) @bp.route('/data/standard/graph/all', methods=['POST']) def data_standard_graph_all(): try: # 传入请求参数 receiver = request.get_json() nodeid = receiver['id'] type = receiver['type'] # kinship/impact/all if type == 'kinship': result = interface.standard_kinship_graph(nodeid) elif type == 'impact': result = interface.standard_impact_graph(nodeid) else: result = interface.standard_all_graph(nodeid) return json.dumps(success(result, "success"), ensure_ascii=False, cls=MyEncoder) except Exception as e: res = failed({}, {"error": f"{e}"}) return json.dumps(res, ensure_ascii=False, cls=MyEncoder) # 数据标签新增 DataLabel @bp.route('/data/label/add', methods=['POST']) def data_label_add(): try: # 传入请求参数 receiver = request.get_json() name_zh = receiver['name_zh'] # 中文名称 name_en = translate_and_parse(name_zh) # 英文名 receiver['name_en'] = name_en[0] receiver['create_time'] = get_formatted_time() create_or_get_node('DataLabel', **receiver) res = success('', "success") return json.dumps(res, ensure_ascii=False, cls=MyEncoder) except Exception as e: res = failed({}, {"error": f"{e}"}) return json.dumps(res, ensure_ascii=False, cls=MyEncoder) # 数据标签详情 DataLabel @bp.route('/data/label/detail', methods=['POST']) def data_label_detail(): try: # 传入请求参数 receiver = request.get_json() nodeid = receiver['id'] # id cql = """MATCH (n:DataLabel) where id(n) = $nodeId RETURN properties(n) as property""" with connect_graph().session() as session: property = session.run(cql, nodeId=nodeid).evaluate() if "describe" not in property: property["describe"] = None res = success(property, "success") return json.dumps(res, ensure_ascii=False, cls=MyEncoder) except Exception as e: res = failed({}, {"error": f"{e}"}) return json.dumps(res, ensure_ascii=False, cls=MyEncoder) # 数据标签列表展示(分类,名称,时间检索) @bp.route('/data/label/list', methods=['POST']) def data_label_list(): try: # 传入请求参数 receiver = request.get_json() page = int(receiver.get('current', 1)) page_size = int(receiver.get('size', 10)) name_en_filter = receiver.get('name_en', None) name_zh_filter = receiver.get('name_zh', None) category = receiver.get('category', None) group = receiver.get('group', None) # 计算跳过的记录的数量 skip_count = (page - 1) * page_size data, total = interface.label_list(skip_count, page_size, name_en_filter, name_zh_filter, category, group) response_data = {'records': data, 'total': total, 'size': page_size, 'current': page} res = success(response_data, "success") return json.dumps(res, ensure_ascii=False, cls=MyEncoder) except Exception as e: res = failed({}, {"error": f"{e}"}) return json.dumps(res, ensure_ascii=False, cls=MyEncoder) # 24.11.19 数据标签动态识别分组 @bp.route('/data/label/dynamic/identify', methods=['POST']) def data_label_dynamic_identify(): try: # 传入请求参数 receiver = request.get_json() name_filter = receiver.get('content', None) data = interface.dynamic_label_list(name_filter) res = success(data, "success") return json.dumps(res, ensure_ascii=False, cls=MyEncoder) except Exception as e: res = failed({}, {"error": f"{e}"}) return json.dumps(res, ensure_ascii=False, cls=MyEncoder) # 数据标签的图谱(血缘关系Kinship+影响关系Impact+所有关系all) @bp.route('/data/label/graph/all', methods=['POST']) def data_label_graph(): try: # 传入请求参数 receiver = request.get_json() nodeid = receiver['id'] type = receiver['type'] # kinship/impact/all if type == 'kinship': result = interface.label_kinship_graph(nodeid) elif type == 'impact': result = interface.label_impact_graph(nodeid) else: result = interface.label_kinship_graph(nodeid) # 对于标签,将all和kinship都视为相同处理 return json.dumps(success(result, "success"), ensure_ascii=False, cls=MyEncoder) except Exception as e: res = failed({}, {"error": f"{e}"}) return json.dumps(res, ensure_ascii=False, cls=MyEncoder) # 删除标签、标准、指标间的关系 @bp.route('/metric/label/standard/delete', methods=['POST']) def metric_label_standard_delete(): try: # 传入请求参数 receiver = request.get_json() sourceid = receiver['sourceid'] targetid = receiver['targetid'] # 查询语句,查询两个节点之间的关系 cql = """ MATCH (source)-[r]-(target) WHERE id(source) = $sourceid AND id(target) = $targetid DELETE r """ with connect_graph().session() as session: result = session.run(cql, sourceid=sourceid, targetid=targetid) res = success("", "success") return json.dumps(res, ensure_ascii=False, cls=MyEncoder) except Exception as e: res = failed({}, {"error": f"{e}"}) return json.dumps(res, ensure_ascii=False, cls=MyEncoder) @bp.route('/data/label/delete', methods=['POST']) def data_label_delete(): """ 删除数据标签节点 请求参数: - id: 节点ID 返回: - 删除结果状态信息 """ try: # 获取请求参数 receiver = request.get_json() node_id = receiver.get('id') # 验证参数 if not node_id: res = failed({}, {"error": "节点ID不能为空"}) return json.dumps(res, ensure_ascii=False, cls=MyEncoder) # 转换为整数 try: node_id = int(node_id) except (ValueError, TypeError): res = failed({}, {"error": "节点ID必须为整数"}) return json.dumps(res, ensure_ascii=False, cls=MyEncoder) # 调用核心业务逻辑执行删除 delete_result = interface.node_delete(node_id) # 根据删除结果返回响应 if delete_result["success"]: res = success({ "id": node_id, "message": delete_result["message"] }, "删除成功") return json.dumps(res, ensure_ascii=False, cls=MyEncoder) else: res = failed({ "id": node_id, "message": delete_result["message"] }, delete_result["message"]) return json.dumps(res, ensure_ascii=False, cls=MyEncoder) except Exception as e: res = failed({}, {"error": f"删除失败: {str(e)}"}) return json.dumps(res, ensure_ascii=False, cls=MyEncoder)