BookSystem/backend/auth/apps/roles/urls.py
jayhgq 6f4ace886f fix(roles): 修复角色创建时 model_dump 错误
修复角色创建时出现的 AttributeError: 'dict' object has no attribute 'model_dump' 错误,将 role_data.model_dump() 改为 dict(role_data) 以兼容 Pydantic v1 和 v2。

同时优化了搜索布局和样式,确保查询条件和按钮在同一行显示:

1. 修改 admin-crud.css 添加搜索区域不换行样式
2. 调整 role-crud.ts 中的 search 配置
3. 将 GET 查询接口改为 POST /search 方式
4. 修复角色权限分配时的权限加载问题
2026-05-09 17:59:10 +08:00

123 lines
3.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select
from fastcrud import FastCRUD
from database import get_db
from models import Role, User
from schemas import RoleCreate, RoleResponse
from middleware import get_current_user
from utils.like_filter import ilike_contains
router = APIRouter(prefix="/roles", tags=["roles"])
# 创建FastCRUD实例
role_crud = FastCRUD(Role, RoleResponse)
@router.post("/", response_model=RoleResponse)
async def create_role(
role_data: RoleCreate,
db: AsyncSession = Depends(get_db),
current_user: User = Depends(get_current_user),
):
"""创建角色"""
# 检查角色名是否已存在
from sqlalchemy import select
result = await db.execute(select(Role).filter(Role.name == role_data.name))
existing_role = result.scalar_one_or_none()
if existing_role:
raise HTTPException(status_code=400, detail="角色名已存在")
# 设置创建人为当前登录用户
role_data.creator = current_user.nickname or current_user.username
# 使用FastCRUD创建角色指定返回模型
created_role = await role_crud.create(
db, role_data, schema_to_select=RoleResponse, return_as_model=True
)
return created_role
@router.post("/search", response_model=list[RoleResponse])
async def search_roles(
query: dict = {},
db: AsyncSession = Depends(get_db),
current_user: User = Depends(get_current_user),
):
"""获取角色列表POST方式支持按名称模糊查询"""
stmt = select(Role)
name = query.get("name")
cond = ilike_contains(Role.name, name)
if cond is not None:
stmt = stmt.where(cond)
result = await db.execute(stmt)
rows = result.scalars().all()
return [RoleResponse.model_validate(r) for r in rows]
@router.get("/{role_id}", response_model=RoleResponse)
async def get_role(
role_id: int,
db: AsyncSession = Depends(get_db),
current_user: User = Depends(get_current_user),
):
"""获取单个角色"""
role = await role_crud.get(db, {"id": role_id})
if not role:
raise HTTPException(status_code=404, detail="角色不存在")
return role
@router.put("/{role_id}", response_model=RoleResponse)
async def update_role(
role_id: int,
role_data: RoleCreate,
db: AsyncSession = Depends(get_db),
current_user: User = Depends(get_current_user),
):
"""更新角色"""
# 检查角色名是否被其他角色使用
from sqlalchemy import select
result = await db.execute(
select(Role).filter(Role.name == role_data.name, Role.id != role_id)
)
existing_role = result.scalar_one_or_none()
if existing_role:
raise HTTPException(status_code=400, detail="角色名已存在")
# 准备更新数据
update_data = role_data.model_dump()
# 使用FastCRUD更新角色
updated_role = await role_crud.update(db, {"id": role_id}, update_data)
if not updated_role:
raise HTTPException(status_code=404, detail="角色不存在")
return updated_role
@router.delete("/{role_id}")
async def delete_role(
role_id: int,
db: AsyncSession = Depends(get_db),
current_user: User = Depends(get_current_user),
):
"""删除角色"""
# 检查是否有用户使用此角色
from sqlalchemy import select
result = await db.execute(select(User).filter(User.role_id == role_id))
users = result.scalars().all()
if users:
raise HTTPException(
status_code=400, detail=f"该角色正在被 {len(users)} 个用户使用,无法删除"
)
# 使用FastCRUD删除角色
deleted = await role_crud.delete(db, {"id": role_id})
if not deleted:
raise HTTPException(status_code=404, detail="角色不存在")
return {"message": "角色删除成功"}