| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 |
- """
- 用户数据传输对象定义
- 定义用户相关API请求和响应的数据结构
- 需求: 3.4, 9.2, 9.3
- """
- from datetime import datetime, date
- from typing import Optional
- from pydantic import BaseModel, ConfigDict, EmailStr, Field, field_validator
- class UserCreate(BaseModel):
- """用户注册请求"""
- username: str = Field(..., min_length=3, max_length=50, description="用户名", examples=["testuser"])
- password: str = Field(..., min_length=6, max_length=100, description="密码(默认为加密密码,Swagger测试时传明文并设置encrypted=false)", examples=["password123"])
- nickname: str = Field(..., min_length=1, max_length=100, description="昵称", examples=["测试用户"])
- email: Optional[EmailStr] = Field(None, description="邮箱", examples=["test@example.com"])
- phone: Optional[str] = Field(None, max_length=20, description="手机号")
- sms_code: Optional[str] = Field(None, description="手机验证码(普通注册时必填)")
- email_code: Optional[str] = Field(None, description="邮箱验证码(填写邮箱时必填)")
- encrypted: Optional[bool] = Field(True, description="密码是否已加密(默认true,Swagger测试时设为false使用明文)")
- @field_validator("email", mode="before")
- @classmethod
- def normalize_email(cls, value):
- # Treat blank strings from external SSO providers as missing email.
- if value is None:
- return None
- if isinstance(value, str):
- normalized = value.strip()
- return normalized or None
- return value
- class UserLogin(BaseModel):
- """用户登录请求"""
- username: str = Field(..., description="用户名或手机号", examples=["testuser"])
- password: str = Field(..., description="密码(默认为加密密码,Swagger测试时传明文并设置encrypted=false)", examples=["password123"])
- encrypted: Optional[bool] = Field(True, description="密码是否已加密(默认true,Swagger测试时设为false使用明文)")
- class UserUpdate(BaseModel):
- """用户信息更新请求"""
- nickname: Optional[str] = Field(None, min_length=1, max_length=100, description="昵称")
- phone: Optional[str] = Field(None, max_length=20, description="手机号")
- email: Optional[EmailStr] = Field(None, description="邮箱")
- avatar: Optional[str] = Field(None, description="头像URL")
- apikey: Optional[str] = Field(None, max_length=255, description="API密钥")
- @field_validator("email", mode="before")
- @classmethod
- def normalize_email(cls, value):
- if value is None:
- return None
- if isinstance(value, str):
- normalized = value.strip()
- return normalized or None
- return value
- class UserVerifyRequest(BaseModel):
- """用户实名认证请求"""
- real_name: str = Field(..., min_length=2, max_length=100, description="真实姓名")
- id_card: str = Field(..., min_length=15, max_length=18, description="身份证号")
- class UserResponse(BaseModel):
- """用户信息响应(不包含密码)"""
- id: str
- username: Optional[str] = None
- nickname: str
- phone: Optional[str] = None
- email: Optional[str] = None
- avatar: Optional[str] = None
- real_name: Optional[str] = None
- is_verified: str = "unverified"
- verified_at: Optional[datetime] = None
- registration_date: Optional[date] = None
- created_at: datetime
- updated_at: datetime
- model_config = ConfigDict(from_attributes=True)
- class TokenResponse(BaseModel):
- """登录令牌响应"""
- access_token: str
- token_type: str = "bearer"
- user: UserResponse
- class TokenVerifyResponse(BaseModel):
- """Token验证响应"""
- valid: bool
- user: UserResponse
|