Files
hospital_performance/backend/app/api/v1/menus.py
2026-02-28 15:06:52 +08:00

164 lines
5.1 KiB
Python

"""
菜单管理 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": "初始化成功"
}