diff --git a/inventory-backend/app/api/v1/warehouse.py b/inventory-backend/app/api/v1/warehouse.py index 6b7a351..53d5fe8 100644 --- a/inventory-backend/app/api/v1/warehouse.py +++ b/inventory-backend/app/api/v1/warehouse.py @@ -10,23 +10,25 @@ warehouse_bp = Blueprint('warehouse', __name__, url_prefix='/api/v1/warehouse') def build_tree(nodes, parent_id=None): """ - 将平铺的数据构建为树形结构 + 将平铺的数据构建为树形结构(O(N) 内存组装,避免递归时每层全量扫描导致 O(N²)) + + 做法:先把全部节点按 parent_id 分组到 Map,再从根出发逐层用 Map 取子节点组装。 + 每个节点只被处理一次,显著快于"每次递归 for 遍历全表"的旧实现。 """ - tree = [] + by_parent = {} for node in nodes: - if node.parent_id == parent_id: - children = build_tree(nodes, node.id) - node_dict = node.to_dict() - if children: - # 子节点按 name 升序排序 - children_sorted = sorted(children, key=lambda x: x.get('name', '')) - node_dict['children'] = children_sorted - else: - node_dict['children'] = [] - tree.append(node_dict) - # 当前层级按 name 升序排序 - tree_sorted = sorted(tree, key=lambda x: x.get('name', '')) - return tree_sorted + by_parent.setdefault(node.parent_id, []).append(node) + + def assemble(pid): + kids = sorted(by_parent.get(pid, []), key=lambda x: (x.name or '')) + out = [] + for k in kids: + d = k.to_dict() + d['children'] = assemble(k.id) + out.append(d) + return out + + return assemble(parent_id) @warehouse_bp.route('/tree', methods=['GET'])