Files

240 lines
7.9 KiB
Python
Raw Permalink 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.
# =============================================================================
# 角色 Pydantic Schema
# =============================================================================
# 说明:定义角色相关的请求/响应数据结构
# 包含:角色响应、角色分配、角色映射规则等 Schema
# =============================================================================
from datetime import datetime
from typing import List, Optional
from pydantic import BaseModel, Field, field_validator
# --------------------------------------------------------------------------
# 角色响应 Schema
# --------------------------------------------------------------------------
class RoleResponse(BaseModel):
"""角色响应 Schema。
Attributes:
id: 角色ID
name: 角色标识(user/agent/admin
display_name: 显示名称(用户/坐席/管理员)
description: 角色描述
permissions: 权限列表
is_default: 是否默认角色
user_count: 拥有该角色的用户数(可选)
created_at: 创建时间
updated_at: 更新时间
"""
id: str
name: str
display_name: str
description: Optional[str] = None
permissions: List[str] = []
is_default: bool = False
user_count: Optional[int] = None
created_at: datetime
updated_at: datetime
model_config = {"from_attributes": True}
# --------------------------------------------------------------------------
# 用户角色响应 Schema
# --------------------------------------------------------------------------
class UserRoleResponse(BaseModel):
"""用户角色响应 Schema。
Attributes:
id: 记录ID
employee_id: 企微 UserID
role_id: 角色 ID
role_name: 角色标识
role_display_name: 角色显示名称
source: 角色来源(auto/tag/ehr/manual
assigned_by: 分配者
assigned_at: 分配时间
expires_at: 过期时间
"""
id: str
employee_id: str
role_id: str
role_name: str
role_display_name: str
source: str
assigned_by: Optional[str] = None
assigned_at: datetime
expires_at: Optional[datetime] = None
model_config = {"from_attributes": True}
# --------------------------------------------------------------------------
# 角色分配请求 Schema
# --------------------------------------------------------------------------
class RoleAssignRequest(BaseModel):
"""角色分配请求 Schema。
Attributes:
employee_id: 企微 UserID
role_name: 角色标识(user/agent/admin
reason: 分配原因(可选)
"""
employee_id: str = Field(..., min_length=1, max_length=100, description="企微 UserID")
role_name: str = Field(..., min_length=1, max_length=50, description="角色标识")
reason: Optional[str] = Field(None, max_length=500, description="分配原因")
# --------------------------------------------------------------------------
# 角色撤销请求 Schema
# --------------------------------------------------------------------------
class RoleRevokeRequest(BaseModel):
"""角色撤销请求 Schema。
Attributes:
employee_id: 企微 UserID
role_name: 角色标识(user/agent/admin
reason: 撤销原因(可选)
"""
employee_id: str = Field(..., min_length=1, max_length=100, description="企微 UserID")
role_name: str = Field(..., min_length=1, max_length=50, description="角色标识")
reason: Optional[str] = Field(None, max_length=500, description="撤销原因")
# --------------------------------------------------------------------------
# 角色映射规则响应 Schema
# --------------------------------------------------------------------------
class RoleMappingRuleResponse(BaseModel):
"""角色映射规则响应 Schema。
Attributes:
id: 规则ID
role_id: 目标角色 ID
role_name: 目标角色标识
source_type: 来源类型(wecom_tag/ehr_position
source_value: 来源值(标签名/岗位关键词)
priority: 优先级
is_active: 是否启用
created_at: 创建时间
"""
id: str
role_id: str
role_name: str
source_type: str
source_value: str
priority: int = 0
is_active: bool = True
created_at: datetime
model_config = {"from_attributes": True}
# --------------------------------------------------------------------------
# 角色映射规则创建/更新请求 Schema
# --------------------------------------------------------------------------
class RoleMappingRuleRequest(BaseModel):
"""角色映射规则创建/更新请求 Schema。
Attributes:
role_name: 目标角色标识(user/agent/admin
source_type: 来源类型(wecom_tag/ehr_position
source_value: 来源值(标签名/岗位关键词)
priority: 优先级(数值越大优先级越高)
is_active: 是否启用
"""
role_name: str = Field(..., min_length=1, max_length=50, description="目标角色标识")
source_type: str = Field(..., min_length=1, max_length=50, description="来源类型")
source_value: str = Field(..., min_length=1, max_length=200, description="来源值")
priority: int = Field(0, ge=0, le=100, description="优先级(0-100")
is_active: bool = Field(True, description="是否启用")
@field_validator("source_type")
@classmethod
def validate_source_type(cls, v: str) -> str:
"""校验来源类型是否合法。"""
allowed_types = {"wecom_tag", "ehr_position"}
if v not in allowed_types:
raise ValueError(f"无效的来源类型: {v},合法值为: {allowed_types}")
return v
@field_validator("role_name")
@classmethod
def validate_role_name(cls, v: str) -> str:
"""校验角色标识是否合法。"""
allowed_roles = {"user", "agent", "admin"}
if v not in allowed_roles:
raise ValueError(f"无效的角色标识: {v},合法值为: {allowed_roles}")
return v
@field_validator("source_value")
@classmethod
def validate_source_value(cls, v: str) -> str:
"""校验来源值是否包含恶意内容。"""
# 过滤特殊字符
forbidden_chars = {"<", ">", ";", "'", '"', "\\", "/", "(", ")"}
for char in v:
if char in forbidden_chars:
raise ValueError(f"来源值包含非法字符: {char}")
return v
# --------------------------------------------------------------------------
# Portal 用户信息响应 Schema
# --------------------------------------------------------------------------
class PortalUserInfo(BaseModel):
"""Portal 用户信息响应 Schema。
用于路由选择页展示用户信息和角色列表。
Attributes:
employee_id: 企微 UserID
name: 姓名
department: 部门
avatar: 头像URL
roles: 角色列表
current_role: 当前选择的角色
"""
employee_id: str
name: str
department: Optional[str] = None
avatar: Optional[str] = None
roles: List[RoleResponse] = []
current_role: str = "user"
# --------------------------------------------------------------------------
# 角色切换请求 Schema
# --------------------------------------------------------------------------
class SwitchRoleRequest(BaseModel):
"""角色切换请求 Schema。
Attributes:
new_role: 目标角色标识
"""
new_role: str = Field(..., min_length=1, max_length=50, description="目标角色标识")
# --------------------------------------------------------------------------
# 角色切换响应 Schema
# --------------------------------------------------------------------------
class SwitchRoleResponse(BaseModel):
"""角色切换响应 Schema。
Attributes:
current_role: 切换后的角色标识
redirect_url: 重定向URL
"""
current_role: str
redirect_url: str