"""运营端菜单接口""" from typing import Optional from fastapi import APIRouter, Depends from sqlalchemy.orm import Session from sqlalchemy import asc from app.core.database import get_db from app.core.menu_guard import require_admin_or_super_admin from app.core.response import success_response from app.models.models import SysMenu router = APIRouter(prefix="/web/menu", tags=["菜单管理"]) def build_menu_tree(menus: list[SysMenu]) -> list[dict]: """将扁平菜单列表构建为树形结构""" menu_map = {} for menu in menus: menu_dict = { "id": menu.id, "name": menu.code, "code": menu.code, "path": menu.path, "component": menu.component or "/index/index", "icon": menu.icon, "parentId": menu.parent_id, "sortOrder": menu.sort_order, "redirect": menu.redirect, "menuType": menu.menu_type, "isVisible": bool(menu.is_visible), "isCache": bool(menu.is_cache), "isActive": bool(menu.is_active), "meta": { "title": menu.name, "icon": menu.icon, "keepAlive": bool(menu.is_cache), }, "children": [] } menu_map[menu.id] = menu_dict root_menus = [] for menu in menus: if menu.parent_id and menu.parent_id in menu_map: menu_map[menu.parent_id]["children"].append(menu_map[menu.id]) elif not menu.parent_id: root_menus.append(menu_map[menu.id]) # 按 sort_order 排序 def sort_children(item: dict): item["children"] = sorted(item["children"], key=lambda x: x["sortOrder"]) for child in item["children"]: sort_children(child) root_menus = sorted(root_menus, key=lambda x: x["sortOrder"]) for item in root_menus: sort_children(item) return root_menus @router.get("/list") async def get_menu_list( db: Session = Depends(get_db), current_user: dict = Depends(require_admin_or_super_admin) ): """ 获取菜单列表(从 sys_menu 表读取,构建树形结构) """ menus = ( db.query(SysMenu) .filter( SysMenu.is_del == 0, SysMenu.is_active == 1, SysMenu.is_visible == 1, ) .order_by(asc(SysMenu.sort_order)) .all() ) menu_tree = build_menu_tree(menus) return success_response({ "menuList": menu_tree })