You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
86 lines
2.8 KiB
Python
86 lines
2.8 KiB
Python
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.enums import MenuTypeEnum, StatusEnum
|
|
from iti_system.models import SysMenu
|
|
from iti_system.schemas import MenuCreate, MenuUpdate
|
|
from iti_system.services import build_tree, current_user, dump_menu, get_or_404, new_id, visible_menu_tree_for_user
|
|
|
|
|
|
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")
|
|
def tree_menu(user=Depends(current_user), db: Session = Depends(get_db)):
|
|
menus = db.scalars(
|
|
select(SysMenu)
|
|
.where(
|
|
SysMenu.status == StatusEnum.ENABLED.value,
|
|
SysMenu.type != MenuTypeEnum.BUTTON.value,
|
|
)
|
|
.order_by(SysMenu.sort, SysMenu.name)
|
|
).all()
|
|
return ok(visible_menu_tree_for_user(user, menus))
|
|
|
|
|
|
@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(
|
|
id: str | None = None,
|
|
name: str | None = None,
|
|
path: str | None = None,
|
|
auth_code: str | None = None,
|
|
authCode: str | None = None,
|
|
db: Session = Depends(get_db),
|
|
):
|
|
stmt = select(SysMenu)
|
|
if id:
|
|
stmt = stmt.where(SysMenu.id != id)
|
|
if name:
|
|
stmt = stmt.where(SysMenu.name == name)
|
|
if path:
|
|
stmt = stmt.where(SysMenu.path == path)
|
|
code = auth_code or authCode
|
|
if code:
|
|
stmt = stmt.where(SysMenu.auth_code == code)
|
|
return ok({"exists": db.scalar(stmt) is not None})
|