107 lines
3.9 KiB
Python
107 lines
3.9 KiB
Python
from typing import Optional
|
||
|
||
from pydantic import BaseModel, Field
|
||
|
||
|
||
class RegisterRequest(BaseModel):
|
||
phone: str = Field(..., min_length=11, max_length=11, description="手机号(11位)")
|
||
password: str = Field(..., min_length=6, description="密码(至少6位)")
|
||
nickname: str = Field(..., min_length=1, max_length=50, description="昵称")
|
||
email: Optional[str] = Field(None, description="邮箱(可选)")
|
||
agreed_to_terms: bool = Field(..., description="是否同意用户协议和隐私政策")
|
||
|
||
|
||
class LoginRequest(BaseModel):
|
||
phone: str = Field(..., min_length=11, max_length=11, description="手机号(11位)")
|
||
password: str = Field(..., min_length=1, description="密码")
|
||
agreed_to_terms: bool = Field(..., description="是否同意用户协议和隐私政策")
|
||
|
||
|
||
class TokenResponse(BaseModel):
|
||
access_token: str
|
||
refresh_token: str
|
||
token_type: str = "bearer"
|
||
|
||
|
||
class RefreshTokenRequest(BaseModel):
|
||
refresh_token: str = Field(..., description="刷新令牌")
|
||
|
||
|
||
class UserResponse(BaseModel):
|
||
id: str
|
||
phone: str
|
||
email: Optional[str] = None
|
||
nickname: str
|
||
avatar_url: Optional[str] = None
|
||
subscription_type: str
|
||
created_at: str
|
||
|
||
|
||
class SendSmsRequest(BaseModel):
|
||
phone: str = Field(..., min_length=11, max_length=11, description="手机号(11位)")
|
||
purpose: str = Field(
|
||
..., description="用途:register/login/reset_password/change_phone"
|
||
)
|
||
|
||
|
||
class SendSmsResponse(BaseModel):
|
||
success: bool
|
||
message: str
|
||
expires_in: Optional[int] = None
|
||
|
||
|
||
class SmsLoginRequest(BaseModel):
|
||
phone: str = Field(..., min_length=11, max_length=11, description="手机号(11位)")
|
||
code: str = Field(..., min_length=6, max_length=6, description="验证码(6位)")
|
||
agreed_to_terms: bool = Field(..., description="是否同意用户协议和隐私政策")
|
||
nickname: Optional[str] = Field(
|
||
None, max_length=50, description="昵称(注册时必填,登录时可选)"
|
||
)
|
||
|
||
|
||
class MockSmsLoginRequest(BaseModel):
|
||
"""开发/评测专用:与 MOCK_SMS_LOGIN_ENABLED 联用,跳过短信校验。"""
|
||
|
||
phone: str = Field(..., min_length=11, max_length=11, description="手机号(11位)")
|
||
agreed_to_terms: bool = Field(..., description="是否同意用户协议和隐私政策")
|
||
nickname: Optional[str] = Field(
|
||
None, max_length=50, description="新用户昵称(可选)"
|
||
)
|
||
|
||
|
||
class SmsRegisterRequest(BaseModel):
|
||
phone: str = Field(..., min_length=11, max_length=11, description="手机号(11位)")
|
||
code: str = Field(..., min_length=6, max_length=6, description="验证码(6位)")
|
||
password: str = Field(..., min_length=6, description="密码(至少6位)")
|
||
nickname: str = Field(..., min_length=1, max_length=50, description="昵称")
|
||
email: Optional[str] = Field(None, description="邮箱(可选)")
|
||
agreed_to_terms: bool = Field(..., description="是否同意用户协议和隐私政策")
|
||
|
||
|
||
class ResetPasswordRequest(BaseModel):
|
||
phone: str = Field(..., min_length=11, max_length=11, description="手机号(11位)")
|
||
code: str = Field(..., min_length=6, max_length=6, description="验证码(6位)")
|
||
new_password: str = Field(..., min_length=6, description="新密码(至少6位)")
|
||
|
||
|
||
class ChangePasswordRequest(BaseModel):
|
||
old_password: str = Field(..., min_length=1, description="旧密码")
|
||
new_password: str = Field(..., min_length=6, description="新密码(至少6位)")
|
||
|
||
|
||
class ChangePhoneRequest(BaseModel):
|
||
new_phone: str = Field(
|
||
..., min_length=11, max_length=11, description="新手机号(11位)"
|
||
)
|
||
code: str = Field(..., min_length=6, max_length=6, description="验证码(6位)")
|
||
|
||
|
||
class UpdateNicknameRequest(BaseModel):
|
||
nickname: str = Field(
|
||
..., min_length=1, max_length=50, description="昵称(1-50个字符)"
|
||
)
|
||
|
||
|
||
class AvatarUploadResponse(BaseModel):
|
||
avatar_url: str
|