Files
fastapi-best-architecture/backend/app/utils/build_tree.py
T
Wu Clan 6c5e7a6881 Add department-related interfaces and others (#101)
* Add tool to build tree structure data

* Update to keyword parameter style

* Add department-related interfaces

* Update departmental section interface permissions

* Add TODO and minor fixes

* Fix department relationships

* Fix user foreign key relationship deletion setting

* Add path parameters to the operation log

* Complete todo items

* Update department deletion logic

* Update operation log entry records

* Add AES encryption algorithm

* Add operation log request entry to the secret

* Fix naming prefixes

* Add easy encryption tools

* FIX CASBIN_EXCLUDE typing

* Update user password reset interface

* Add confirm_password to the operation log encryption
2023-06-09 11:00:13 +08:00

83 lines
2.2 KiB
Python

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from typing import Any, Sequence
from asgiref.sync import sync_to_async
from backend.app.common.enums import BuildTreeType
from backend.app.utils.serializers import RowData, select_to_list
@sync_to_async
def get_tree_nodes(row: Sequence[RowData]) -> list[dict[str, Any]]:
"""获取所有树形结构节点"""
tree_nodes = select_to_list(row)
tree_nodes.sort(key=lambda x: x['sort'])
return tree_nodes
@sync_to_async
def traversal_to_tree(nodes: list[dict[str, Any]]) -> list[dict[str, Any]]:
"""
通过遍历算法构造树形结构
:param nodes:
:return:
"""
node_map = {}
root_nodes = []
for node in nodes:
parent_id = node['parent_id']
if parent_id is None:
root_nodes.append(node)
else:
parent_node = node_map.get(parent_id, {})
parent_node.setdefault('children', []).append(node)
node_map[parent_id] = parent_node
node_map[node['id']] = node
return root_nodes
async def recursive_to_tree(nodes: list[dict[str, Any]], *, parent_id: int | None = None) -> list[dict[str, Any]]:
"""
通过递归算法构造树形结构
:param nodes:
:param parent_id:
:return:
"""
tree = []
for node in nodes:
if node['parent_id'] == parent_id:
child_node = {
'id': node['id'],
'parent_id': node['parent_id'],
'children': await recursive_to_tree(nodes, parent_id=node['id']),
}
tree.append(child_node)
return tree
async def get_tree_data(
row: Sequence[RowData], build_type: BuildTreeType = BuildTreeType.traversal, *, parent_id: int | None = None
) -> list[dict[str, Any]]:
"""
获取树形结构数据
:param row:
:param build_type:
:param parent_id:
:return:
"""
nodes = await get_tree_nodes(row)
match build_type:
case BuildTreeType.traversal:
tree = await traversal_to_tree(nodes)
case BuildTreeType.recursive:
tree = await recursive_to_tree(nodes, parent_id=parent_id)
case _:
raise ValueError(f'无效的算法类型:{build_type}')
return tree