tree_utils.py 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. import json
  2. from typing import List, Dict
  3. from dataclasses import dataclass
  4. @dataclass
  5. class TreeNodeDTO:
  6. id: int
  7. name: str
  8. pId: int
  9. icon: str = ""
  10. iconOpen: str = ""
  11. iconClose: str = ""
  12. @dataclass
  13. class TreeDTO:
  14. nodes: List[TreeNodeDTO]
  15. def get_tree_dto(tree_json: str) -> TreeDTO:
  16. """
  17. 将JSON树结构转换为TreeDTO
  18. :param tree_json: JSON格式的树结构字符串
  19. :return: TreeDTO对象
  20. """
  21. tree_dto = TreeDTO(nodes=[])
  22. try:
  23. tree_obj = json.loads(tree_json)
  24. if tree_obj:
  25. # 使用计数器生成唯一ID
  26. id_counter = 0
  27. # 存储父节点路径到ID的映射
  28. path_id_map = {}
  29. # 根节点特殊处理
  30. root_id = id_counter
  31. id_counter += 1
  32. path_id_map["根节点"] = root_id
  33. # 从根节点开始构建树
  34. add_tree(tree_dto.nodes, tree_obj, path_id_map, "根节点", id_counter, "根节点")
  35. except json.JSONDecodeError:
  36. pass
  37. return tree_dto
  38. def add_tree(nodes: List[TreeNodeDTO], tree_obj: Dict, path_id_map: Dict[str, int],
  39. parent_name: str, id_counter: int, parent_path: str):
  40. """
  41. 递归添加树节点
  42. :param nodes: 节点列表
  43. :param tree_obj: 树对象
  44. :param path_id_map: 路径到ID的映射
  45. :param parent_path: 父节点路径
  46. :param id_counter: ID计数器
  47. :param current_path: 当前节点路径
  48. """
  49. # 构建当前节点的完整路径
  50. current_path = f"{parent_path}/{tree_obj['name']}"
  51. # 生成当前节点ID
  52. current_id = id_counter
  53. id_counter += 1
  54. path_id_map[current_path] = current_id
  55. # 获取父节点ID
  56. parent_id = path_id_map[parent_path]
  57. # 判断是否为叶子节点
  58. is_leaf = not tree_obj.get('sNode', [])
  59. # 设置图标
  60. icon = "/images/node.png" if is_leaf else "/images/icon.png"
  61. icon_open = "" if is_leaf else "/images/iconOpen.png"
  62. icon_close = "" if is_leaf else "/images/iconClose.png"
  63. # 创建树节点
  64. node = TreeNodeDTO(
  65. id=current_id,
  66. name=tree_obj['name'],
  67. pId=parent_id,
  68. icon=icon,
  69. iconOpen=icon_open,
  70. iconClose=icon_close
  71. )
  72. nodes.append(node)
  73. # 递归处理子节点
  74. if not is_leaf:
  75. for child in tree_obj['sNode']:
  76. id_counter = add_tree(nodes, child, path_id_map,
  77. tree_obj['name'], id_counter, current_path)
  78. return id_counter