from fastapi import APIRouter, Depends, HTTPException, Request from sqlalchemy.orm import Session from typing import List from ..database import get_db from ..models import Role, User from ..schemas import RoleCreate, RoleUpdate, RoleResponse from .auth import get_current_admin router = APIRouter(prefix="/api/admin/roles", tags=["admin"]) @router.get("", response_model=List[RoleResponse]) def list_roles(db: Session = Depends(get_db), admin_user: User = Depends(get_current_admin)): roles = db.query(Role).order_by(Role.name).all() return [RoleResponse.model_validate(r) for r in roles] @router.post("", response_model=RoleResponse) def create_role(data: RoleCreate, request: Request, db: Session = Depends(get_db), admin_user: User = Depends(get_current_admin)): existing = db.query(Role).filter(Role.name == data.name).first() if existing: raise HTTPException(status_code=400, detail="角色已存在") role = Role(name=data.name, description=data.description, is_system=False) db.add(role) db.commit() db.refresh(role) return RoleResponse.model_validate(role) @router.put("/{role_id}", response_model=RoleResponse) def update_role(role_id: int, data: RoleUpdate, request: Request, db: Session = Depends(get_db), admin_user: User = Depends(get_current_admin)): role = db.query(Role).filter(Role.id == role_id).first() if not role: raise HTTPException(status_code=404, detail="角色不存在") if role.is_system: raise HTTPException(status_code=400, detail="系统角色不可编辑") if data.name is not None: role.name = data.name if data.description is not None: role.description = data.description db.commit() db.refresh(role) return RoleResponse.model_validate(role) @router.delete("/{role_id}") def delete_role(role_id: int, request: Request, db: Session = Depends(get_db), admin_user: User = Depends(get_current_admin)): role = db.query(Role).filter(Role.id == role_id).first() if not role: raise HTTPException(status_code=404, detail="角色不存在") if role.is_system: raise HTTPException(status_code=400, detail="系统角色不可删除") db.delete(role) db.commit() return {"message": "删除成功"}