#!/usr/bin/env python # -*- coding: utf-8 -*- """ Role Schema - 角色数据验证模式 """ from datetime import datetime from typing import Optional, List from pydantic import BaseModel, ConfigDict, Field, field_validator from app.base_schema import CSTDatetime class RoleBase(BaseModel): """角色基础Schema""" name: str = Field(..., min_length=1, max_length=64, description="角色名称") code: str = Field(..., min_length=1, max_length=64, description="角色编码") role_type: int = Field(default=1, description="角色类型(0-系统角色, 1-自定义角色)") status: bool = Field(default=True, description="角色状态") priority: int = Field(default=0, description="角色优先级") description: Optional[str] = Field(None, description="角色描述") remark: Optional[str] = Field(None, description="备注") sort: int = Field(default=0, description="排序") @field_validator("code") @classmethod def validate_code(cls, v): """验证角色编码格式""" if not v: raise ValueError("角色编码不能为空") if not v.replace('_', '').isalnum(): raise ValueError("角色编码只能包含字母、数字和下划线") return v @field_validator("role_type") @classmethod def validate_role_type(cls, v): """验证角色类型""" if v not in [0, 1]: raise ValueError("角色类型必须为 0(系统角色) 或 1(自定义角色)") return v @field_validator("priority") @classmethod def validate_priority(cls, v): """验证优先级""" if v < 0: raise ValueError("优先级不能为负数") return v class RoleCreate(RoleBase): """角色创建Schema""" menu_ids: List[str] = Field(default=[], description="菜单ID列表") permission_ids: List[str] = Field(default=[], description="权限ID列表") dept_ids: List[str] = Field(default=[], description="部门ID列表") class RoleUpdate(BaseModel): """角色更新Schema - 所有字段可选""" name: Optional[str] = Field(None, min_length=1, max_length=64, description="角色名称") code: Optional[str] = Field(None, min_length=1, max_length=64, description="角色编码") role_type: Optional[int] = Field(None, description="角色类型") status: Optional[bool] = Field(None, description="角色状态") priority: Optional[int] = Field(None, description="角色优先级") description: Optional[str] = Field(None, description="角色描述") remark: Optional[str] = Field(None, description="备注") sort: Optional[int] = Field(None, description="排序") menu_ids: Optional[List[str]] = Field(None, description="菜单ID列表") permission_ids: Optional[List[str]] = Field(None, description="权限ID列表") dept_ids: Optional[List[str]] = Field(None, description="部门ID列表") @field_validator("code") @classmethod def validate_code(cls, v): """验证角色编码格式""" if v is not None: if not v: raise ValueError("角色编码不能为空") if not v.replace('_', '').isalnum(): raise ValueError("角色编码只能包含字母、数字和下划线") return v @field_validator("role_type") @classmethod def validate_role_type(cls, v): """验证角色类型""" if v is not None and v not in [0, 1]: raise ValueError("角色类型必须为 0(系统角色) 或 1(自定义角色)") return v @field_validator("priority") @classmethod def validate_priority(cls, v): """验证优先级""" if v is not None and v < 0: raise ValueError("优先级不能为负数") return v class RoleResponse(BaseModel): """角色响应Schema""" id: str name: str code: str role_type: int role_type_display: Optional[str] = None status: bool priority: int description: Optional[str] = None remark: Optional[str] = None user_count: int = 0 menu_count: int = 0 permission_count: int = 0 can_delete: bool = True sort: int = 0 is_deleted: bool = False sys_create_datetime: Optional[CSTDatetime] = None sys_update_datetime: Optional[CSTDatetime] = None model_config = ConfigDict(from_attributes=True) class RoleDetail(RoleResponse): """角色详情响应Schema(包含关联数据)""" menu_ids: List[str] = [] permission_ids: List[str] = [] dept_ids: List[str] = [] class RoleSimple(BaseModel): """角色简单输出(用于选择器)""" id: str name: str code: str status: bool role_type: int model_config = ConfigDict(from_attributes=True) class RoleBatchDeleteIn(BaseModel): """批量删除角色输入""" ids: List[str] = Field(..., description="要删除的角色ID列表") class RoleBatchDeleteOut(BaseModel): """批量删除角色输出""" count: int = Field(..., description="删除的记录数") failed_ids: List[str] = Field(default=[], description="删除失败的ID列表") class RoleBatchUpdateStatusIn(BaseModel): """批量更新角色状态输入""" ids: List[str] = Field(..., description="角色ID列表") status: bool = Field(..., description="角色状态") class RoleBatchUpdateStatusOut(BaseModel): """批量更新角色状态输出""" count: int = Field(..., description="更新的记录数") class RoleUserSchema(BaseModel): """角色关联的用户信息""" id: str name: Optional[str] = None username: str avatar: Optional[str] = None email: Optional[str] = None mobile: Optional[str] = None dept_name: Optional[str] = None model_config = ConfigDict(from_attributes=True) class RoleUserIn(BaseModel): """角色用户操作输入""" role_id: str = Field(..., description="角色ID") user_ids: List[str] = Field(default=[], description="用户ID列表") user_id: Optional[str] = Field(None, description="单个用户ID") class RoleMenuPermissionUpdateIn(BaseModel): """更新角色菜单和权限输入""" menu_ids: List[str] = Field(default=[], description="菜单ID列表") permission_ids: List[str] = Field(default=[], description="权限ID列表") loaded_menu_ids: List[str] = Field(default=[], description="前端已加载过权限的菜单ID列表,用于增量更新权限(只替换这些菜单下的权限,保留未加载菜单的原有权限)") class RoleSearchRequest(BaseModel): """搜索角色请求""" keyword: str = Field(..., description="搜索关键词") class RoleCopyRequest(BaseModel): """复制角色请求""" new_name: str = Field(..., description="新角色名称") new_code: str = Field(..., description="新角色编码")