# api/roles.py from typing import List from django.shortcuts import get_object_or_404 from ninja import Router from ninja.errors import HttpError from users.models import Role from users.permission import has_permission, clear_user_permissions_cache from users.schema import RoleOut, RoleCreate, RoleMenuAssign, RoleUpdate router = Router(tags=['roles']) @router.post("/", response=RoleOut, summary="创建角色") def create_role(request, payload: RoleCreate): if not has_permission(request.auth.id, "role:create"): raise HttpError(403, "权限不足") role = Role.objects.create(**payload.dict()) return role @router.get("/", response=List[RoleOut], summary="获取角色列表") def list_roles(request): if not has_permission(request.auth.id, "role:list"): raise HttpError(403, "权限不足") return Role.objects.all() @router.get("/{role_id}/", response=RoleOut, summary="获取角色详情") def get_role(request, role_id: int): if not has_permission(request.auth.id, "role:view"): raise HttpError(403, "权限不足") role = get_object_or_404(Role, id=role_id) return role @router.put("/{role_id}/", response=RoleOut, summary="更新角色") def update_role(request, role_id: int, payload: RoleUpdate): if not has_permission(request.auth.id, "role:update"): raise HttpError(403, "权限不足") role = get_object_or_404(Role, id=role_id) for attr, value in payload.dict().items(): setattr(role, attr, value) role.save() return role @router.delete("/{role_id}/", summary="删除角色") def delete_role(request, role_id: int): if not has_permission(request.auth.id, "role:delete"): raise HttpError(403, "权限不足") role = get_object_or_404(Role, id=role_id) role.delete() return {"success": True} @router.post("/{role_id}/menus/", summary="分配角色菜单权限") def assign_role_menus(request, role_id: int, payload: RoleMenuAssign): if not has_permission(request.auth.id, "role:assign_menus"): raise HttpError(403, "权限不足") role = get_object_or_404(Role, id=role_id) # 直接使用 ManyToManyField 的 set() 方法 role.menus.set(payload.menu_ids) # 清除该角色下所有用户的权限缓存 clear_user_permissions_cache(role_id) return {"success": True}