routes.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. from flask import request
  2. from app.api.data_interface import bp
  3. from app.models.result import success, failed
  4. from app.core.graph.graph_operations import connect_graph, MyEncoder, create_or_get_node
  5. from app.core.data_interface import interface
  6. from app.core.meta_data import translate_and_parse, get_formatted_time
  7. from app.core.llm import code_generate_standard
  8. import json
  9. # 数据标准新增 data_standard
  10. @bp.route('/data/standard/add', methods=['POST'])
  11. def data_standard_add():
  12. try:
  13. # 传入请求参数
  14. receiver = request.get_json()
  15. name_zh = receiver['name_zh'] # 中文名称
  16. name_en = translate_and_parse(name_zh) # 英文名
  17. receiver['name_en'] = name_en[0]
  18. receiver['create_time'] = get_formatted_time()
  19. receiver['tag'] = json.dumps(receiver['tag'], ensure_ascii=False)
  20. create_or_get_node('data_standard', **receiver)
  21. res = success('', "success")
  22. return json.dumps(res, ensure_ascii=False, cls=MyEncoder)
  23. except Exception as e:
  24. res = failed({}, {"error": f"{e}"})
  25. return json.dumps(res, ensure_ascii=False, cls=MyEncoder)
  26. # 数据标准详情 data_standard
  27. @bp.route('/data/standard/detail', methods=['POST'])
  28. def data_standard_detail():
  29. try:
  30. # 传入请求参数
  31. receiver = request.get_json()
  32. nodeid = receiver['id'] # id
  33. cql = """MATCH (n:data_standard) where id(n) = $nodeId
  34. RETURN properties(n) as property"""
  35. # Create a session from the driver returned by connect_graph
  36. with connect_graph().session() as session:
  37. result = session.run(cql, nodeId=nodeid).single()
  38. property = result["property"] if result else {}
  39. if "tag" not in property:
  40. property["tag"] = None
  41. else:
  42. property["tag"] = json.loads(property["tag"])
  43. if "describe" not in property:
  44. property["describe"] = None
  45. res = success(property, "success")
  46. return json.dumps(res, ensure_ascii=False, cls=MyEncoder)
  47. except Exception as e:
  48. res = failed({}, {"error": f"{e}"})
  49. return json.dumps(res, ensure_ascii=False, cls=MyEncoder)
  50. # 数据标准代码 data_standard
  51. @bp.route('/data/standard/code', methods=['POST'])
  52. def data_standard_code():
  53. try:
  54. # 传入请求参数
  55. receiver = request.get_json()
  56. input = receiver['input']
  57. describe = receiver['describe']
  58. output = receiver['output']
  59. relation = {
  60. "输入参数": input,
  61. "输出参数": output
  62. }
  63. result = code_generate_standard(describe, relation)
  64. res = success(result, "success")
  65. return json.dumps(res, ensure_ascii=False, cls=MyEncoder)
  66. except Exception as e:
  67. res = failed({}, {"error": f"{e}"})
  68. return json.dumps(res, ensure_ascii=False, cls=MyEncoder)
  69. # 数据标准更新 data_standard 未加到接口文档
  70. @bp.route('/data/standard/update', methods=['POST'])
  71. def data_standard_update():
  72. try:
  73. # 传入请求参数
  74. receiver = request.get_json()
  75. name_zh = receiver['name_zh'] # 中文名称
  76. name_en = translate_and_parse(name_zh) # 英文名
  77. receiver['name_en'] = name_en[0]
  78. receiver['create_time'] = get_formatted_time()
  79. create_or_get_node('data_standard', **receiver)
  80. res = success('', "success")
  81. return json.dumps(res, ensure_ascii=False, cls=MyEncoder)
  82. except Exception as e:
  83. res = failed({}, {"error": f"{e}"})
  84. return json.dumps(res, ensure_ascii=False, cls=MyEncoder)
  85. # 数据标准列表展示
  86. @bp.route('/data/standard/list', methods=['POST'])
  87. def data_standard_list():
  88. try:
  89. # 传入请求参数
  90. receiver = request.get_json()
  91. page = int(receiver.get('current', 1))
  92. page_size = int(receiver.get('size', 10))
  93. name_en_filter = receiver.get('name_en', None)
  94. name_zh_filter = receiver.get('name_zh', None)
  95. category = receiver.get('category', None)
  96. time = receiver.get('time', None)
  97. # 计算跳过的记录的数量
  98. skip_count = (page - 1) * page_size
  99. data, total = interface.standard_list(skip_count, page_size, name_en_filter,
  100. name_zh_filter, category, time)
  101. response_data = {'records': data, 'total': total, 'size': page_size, 'current': page}
  102. res = success(response_data, "success")
  103. return json.dumps(res, ensure_ascii=False, cls=MyEncoder)
  104. except Exception as e:
  105. res = failed({}, {"error": f"{e}"})
  106. return json.dumps(res, ensure_ascii=False, cls=MyEncoder)
  107. # 数据标准的图谱(血缘关系Kinship+影响关系Impact+所有关系all)
  108. @bp.route('/data/standard/graph/all', methods=['POST'])
  109. def data_standard_graph_all():
  110. try:
  111. # 传入请求参数
  112. receiver = request.get_json()
  113. nodeid = receiver['id']
  114. type = receiver['type'] # kinship/impact/all
  115. if type == 'kinship':
  116. result = interface.standard_kinship_graph(nodeid)
  117. elif type == 'impact':
  118. result = interface.standard_impact_graph(nodeid)
  119. else:
  120. result = interface.standard_all_graph(nodeid)
  121. return json.dumps(success(result, "success"), ensure_ascii=False, cls=MyEncoder)
  122. except Exception as e:
  123. res = failed({}, {"error": f"{e}"})
  124. return json.dumps(res, ensure_ascii=False, cls=MyEncoder)
  125. # 数据标签新增 DataLabel
  126. @bp.route('/data/label/add', methods=['POST'])
  127. def data_label_add():
  128. try:
  129. # 传入请求参数
  130. receiver = request.get_json()
  131. name_zh = receiver['name_zh'] # 中文名称
  132. name_en = translate_and_parse(name_zh) # 英文名
  133. receiver['name_en'] = name_en[0]
  134. receiver['create_time'] = get_formatted_time()
  135. create_or_get_node('DataLabel', **receiver)
  136. res = success('', "success")
  137. return json.dumps(res, ensure_ascii=False, cls=MyEncoder)
  138. except Exception as e:
  139. res = failed({}, {"error": f"{e}"})
  140. return json.dumps(res, ensure_ascii=False, cls=MyEncoder)
  141. # 数据标签详情 DataLabel
  142. @bp.route('/data/label/detail', methods=['POST'])
  143. def data_label_detail():
  144. try:
  145. # 传入请求参数
  146. receiver = request.get_json()
  147. nodeid = receiver['id'] # id
  148. cql = """MATCH (n:DataLabel) where id(n) = $nodeId
  149. RETURN properties(n) as property"""
  150. with connect_graph().session() as session:
  151. result = session.run(cql, nodeId=nodeid).single()
  152. property = result["property"] if result else {}
  153. if "describe" not in property:
  154. property["describe"] = None
  155. res = success(property, "success")
  156. return json.dumps(res, ensure_ascii=False, cls=MyEncoder)
  157. except Exception as e:
  158. res = failed({}, {"error": f"{e}"})
  159. return json.dumps(res, ensure_ascii=False, cls=MyEncoder)
  160. # 数据标签列表展示(分类,名称,时间检索)
  161. @bp.route('/data/label/list', methods=['POST'])
  162. def data_label_list():
  163. try:
  164. # 传入请求参数
  165. receiver = request.get_json()
  166. page = int(receiver.get('current', 1))
  167. page_size = int(receiver.get('size', 10))
  168. name_en_filter = receiver.get('name_en', None)
  169. name_zh_filter = receiver.get('name_zh', None)
  170. category = receiver.get('category', None)
  171. group = receiver.get('group', None)
  172. # 计算跳过的记录的数量
  173. skip_count = (page - 1) * page_size
  174. data, total = interface.label_list(skip_count, page_size, name_en_filter,
  175. name_zh_filter, category, group)
  176. response_data = {'records': data, 'total': total, 'size': page_size, 'current': page}
  177. res = success(response_data, "success")
  178. return json.dumps(res, ensure_ascii=False, cls=MyEncoder)
  179. except Exception as e:
  180. res = failed({}, {"error": f"{e}"})
  181. return json.dumps(res, ensure_ascii=False, cls=MyEncoder)
  182. # 24.11.19 数据标签动态识别分组
  183. @bp.route('/data/label/dynamic/identify', methods=['POST'])
  184. def data_label_dynamic_identify():
  185. try:
  186. # 传入请求参数
  187. receiver = request.get_json()
  188. name_filter = receiver.get('content', None)
  189. data = interface.dynamic_label_list(name_filter)
  190. res = success(data, "success")
  191. return json.dumps(res, ensure_ascii=False, cls=MyEncoder)
  192. except Exception as e:
  193. res = failed({}, {"error": f"{e}"})
  194. return json.dumps(res, ensure_ascii=False, cls=MyEncoder)
  195. # 数据标签的图谱(血缘关系Kinship+影响关系Impact+所有关系all)
  196. @bp.route('/data/label/graph/all', methods=['POST'])
  197. def data_label_graph():
  198. try:
  199. # 传入请求参数
  200. receiver = request.get_json()
  201. nodeid = receiver['id']
  202. type = receiver['type'] # kinship/impact/all
  203. if type == 'kinship':
  204. result = interface.label_kinship_graph(nodeid)
  205. elif type == 'impact':
  206. result = interface.label_impact_graph(nodeid)
  207. else:
  208. result = interface.label_kinship_graph(nodeid) # 对于标签,将all和kinship都视为相同处理
  209. return json.dumps(success(result, "success"), ensure_ascii=False, cls=MyEncoder)
  210. except Exception as e:
  211. res = failed({}, {"error": f"{e}"})
  212. return json.dumps(res, ensure_ascii=False, cls=MyEncoder)
  213. # 删除标签、标准、指标间的关系
  214. @bp.route('/metric/label/standard/delete', methods=['POST'])
  215. def metric_label_standard_delete():
  216. try:
  217. # 传入请求参数
  218. receiver = request.get_json()
  219. sourceid = receiver['sourceid']
  220. targetid = receiver['targetid']
  221. # 查询语句,查询两个节点之间的关系
  222. cql = """
  223. MATCH (source)-[r]-(target)
  224. WHERE id(source) = $sourceid AND id(target) = $targetid
  225. DELETE r
  226. """
  227. with connect_graph().session() as session:
  228. result = session.run(cql, sourceid=sourceid, targetid=targetid)
  229. res = success("", "success")
  230. return json.dumps(res, ensure_ascii=False, cls=MyEncoder)
  231. except Exception as e:
  232. res = failed({}, {"error": f"{e}"})
  233. return json.dumps(res, ensure_ascii=False, cls=MyEncoder)
  234. @bp.route('/data/label/delete', methods=['POST'])
  235. def data_label_delete():
  236. """
  237. 删除数据标签节点
  238. 请求参数:
  239. - id: 节点ID
  240. 返回:
  241. - 删除结果状态信息
  242. """
  243. try:
  244. # 获取请求参数
  245. receiver = request.get_json()
  246. node_id = receiver.get('id')
  247. # 验证参数
  248. if not node_id:
  249. res = failed({}, {"error": "节点ID不能为空"})
  250. return json.dumps(res, ensure_ascii=False, cls=MyEncoder)
  251. # 转换为整数
  252. try:
  253. node_id = int(node_id)
  254. except (ValueError, TypeError):
  255. res = failed({}, {"error": "节点ID必须为整数"})
  256. return json.dumps(res, ensure_ascii=False, cls=MyEncoder)
  257. # 调用核心业务逻辑执行删除
  258. delete_result = interface.node_delete(node_id)
  259. # 根据删除结果返回响应
  260. if delete_result["success"]:
  261. res = success({
  262. "id": node_id,
  263. "message": delete_result["message"]
  264. }, "删除成功")
  265. return json.dumps(res, ensure_ascii=False, cls=MyEncoder)
  266. else:
  267. res = failed({
  268. "id": node_id,
  269. "message": delete_result["message"]
  270. }, delete_result["message"])
  271. return json.dumps(res, ensure_ascii=False, cls=MyEncoder)
  272. except Exception as e:
  273. res = failed({}, {"error": f"删除失败: {str(e)}"})
  274. return json.dumps(res, ensure_ascii=False, cls=MyEncoder)