from __future__ import annotations from fastapi import APIRouter, Depends from sqlalchemy import select from sqlalchemy.orm import Session from iti.auth import require_permission from iti.db import get_db from iti.responses import ok from iti_system.models import SysMenu from iti_system.schemas import MenuCreate, MenuUpdate from iti_system.services import build_tree, dump_menu, get_or_404, new_id router = APIRouter(prefix="/sys/menu", tags=["system.menu"]) @router.get("/list", dependencies=[Depends(require_permission("system:menu:list"))]) def list_menu(db: Session = Depends(get_db)): menus = db.scalars(select(SysMenu).order_by(SysMenu.sort, SysMenu.name)).all() return ok([dump_menu(menu) for menu in menus]) @router.get("/tree", dependencies=[Depends(require_permission("system:menu:list"))]) def tree_menu(db: Session = Depends(get_db)): menus = db.scalars(select(SysMenu).order_by(SysMenu.sort, SysMenu.name)).all() return ok(build_tree(menus, dump_menu)) @router.post("", dependencies=[Depends(require_permission("system:menu:create"))]) def create_menu(payload: MenuCreate, db: Session = Depends(get_db)): menu = SysMenu(id=payload.id or new_id(), **payload.model_dump(exclude={"id"})) db.add(menu) db.commit() db.refresh(menu) return ok(dump_menu(menu)) @router.put("/{id}", dependencies=[Depends(require_permission("system:menu:edit"))]) def update_menu(id: str, payload: MenuUpdate, db: Session = Depends(get_db)): menu = get_or_404(db, SysMenu, id, "菜单不存在") for key, value in payload.model_dump(exclude_unset=True).items(): setattr(menu, key, value) db.commit() db.refresh(menu) return ok(dump_menu(menu)) @router.delete("/{id}", dependencies=[Depends(require_permission("system:menu:delete"))]) def delete_menu(id: str, db: Session = Depends(get_db)): menu = get_or_404(db, SysMenu, id, "菜单不存在") db.delete(menu) db.commit() return ok() @router.get("/exists", dependencies=[Depends(require_permission("system:menu:list"))]) def exists_menu(name: str | None = None, auth_code: str | None = None, db: Session = Depends(get_db)): stmt = select(SysMenu) if name: stmt = stmt.where(SysMenu.name == name) if auth_code: stmt = stmt.where(SysMenu.auth_code == auth_code) return ok({"exists": db.scalar(stmt) is not None})