240 lines
7.9 KiB
Python
240 lines
7.9 KiB
Python
|
|
# =============================================================================
|
|||
|
|
# 角色 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
|