""" 菜单管理 API """ from typing import Annotated, Optional from fastapi import APIRouter, Depends, HTTPException, Query from sqlalchemy.ext.asyncio import AsyncSession from app.core.database import get_db from app.core.security import get_current_active_user, get_current_manager_user from app.schemas.schemas import MenuCreate, MenuUpdate, MenuResponse, ResponseBase from app.services.menu_service import MenuService from app.models.models import User, Menu router = APIRouter(prefix="/menus", tags=["菜单管理"]) @router.get("/tree", summary="获取菜单树") async def get_menu_tree( visible_only: bool = Query(True, description="是否只返回可见菜单"), db: AsyncSession = Depends(get_db), current_user: User = Depends(get_current_active_user) ): """获取菜单树形结构""" tree = await MenuService.get_tree(db, visible_only) return { "code": 200, "message": "success", "data": tree } @router.get("", summary="获取菜单列表") async def get_menus( menu_type: Optional[str] = Query(None, description="菜单类型"), is_visible: Optional[bool] = Query(None, description="是否可见"), db: AsyncSession = Depends(get_db), current_user: User = Depends(get_current_active_user) ): """获取菜单列表""" menus = await MenuService.get_list(db, menu_type, is_visible) menu_list = [] for menu in menus: menu_dict = { "id": menu.id, "parent_id": menu.parent_id, "menu_type": menu.menu_type, "menu_name": menu.menu_name, "menu_icon": menu.menu_icon, "path": menu.path, "component": menu.component, "permission": menu.permission, "sort_order": menu.sort_order, "is_visible": menu.is_visible, "is_active": menu.is_active, "created_at": menu.created_at, "updated_at": menu.updated_at } menu_list.append(menu_dict) return { "code": 200, "message": "success", "data": menu_list } @router.get("/{menu_id}", summary="获取菜单详情") async def get_menu( menu_id: int, db: AsyncSession = Depends(get_db), current_user: User = Depends(get_current_active_user) ): """获取菜单详情""" menu = await MenuService.get_by_id(db, menu_id) if not menu: raise HTTPException(status_code=404, detail="菜单不存在") return { "code": 200, "message": "success", "data": { "id": menu.id, "parent_id": menu.parent_id, "menu_type": menu.menu_type, "menu_name": menu.menu_name, "menu_icon": menu.menu_icon, "path": menu.path, "component": menu.component, "permission": menu.permission, "sort_order": menu.sort_order, "is_visible": menu.is_visible, "is_active": menu.is_active } } @router.post("", summary="创建菜单") async def create_menu( menu_data: MenuCreate, db: AsyncSession = Depends(get_db), current_user: Annotated[User, Depends(get_current_manager_user)] = None ): """创建菜单(需要管理员或经理权限)""" # 如果指定了父菜单,检查父菜单是否存在 if menu_data.parent_id: parent = await MenuService.get_by_id(db, menu_data.parent_id) if not parent: raise HTTPException(status_code=400, detail="父菜单不存在") menu = await MenuService.create(db, menu_data.model_dump()) return { "code": 200, "message": "创建成功", "data": {"id": menu.id} } @router.put("/{menu_id}", summary="更新菜单") async def update_menu( menu_id: int, menu_data: MenuUpdate, db: AsyncSession = Depends(get_db), current_user: Annotated[User, Depends(get_current_manager_user)] = None ): """更新菜单(需要管理员或经理权限)""" menu = await MenuService.update(db, menu_id, menu_data.model_dump(exclude_unset=True)) if not menu: raise HTTPException(status_code=404, detail="菜单不存在") return { "code": 200, "message": "更新成功", "data": {"id": menu.id} } @router.delete("/{menu_id}", summary="删除菜单") async def delete_menu( menu_id: int, db: AsyncSession = Depends(get_db), current_user: Annotated[User, Depends(get_current_manager_user)] = None ): """删除菜单(需要管理员或经理权限)""" success = await MenuService.delete(db, menu_id) if not success: raise HTTPException(status_code=400, detail="无法删除,菜单不存在或存在子菜单") return { "code": 200, "message": "删除成功" } @router.post("/init", summary="初始化默认菜单") async def init_default_menus( db: AsyncSession = Depends(get_db), current_user: Annotated[User, Depends(get_current_manager_user)] = None ): """初始化默认菜单(需要管理员权限)""" await MenuService.init_default_menus(db) return { "code": 200, "message": "初始化成功" }