2026-03-18 17:18:23 +08:00
|
|
|
|
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位)")
|
2026-03-19 14:36:14 +08:00
|
|
|
|
purpose: str = Field(
|
|
|
|
|
|
..., description="用途:register/login/reset_password/change_phone"
|
|
|
|
|
|
)
|
2026-03-18 17:18:23 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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="是否同意用户协议和隐私政策")
|
2026-03-19 14:36:14 +08:00
|
|
|
|
nickname: Optional[str] = Field(
|
|
|
|
|
|
None, max_length=50, description="昵称(注册时必填,登录时可选)"
|
|
|
|
|
|
)
|
2026-03-18 17:18:23 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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):
|
2026-03-19 14:36:14 +08:00
|
|
|
|
new_phone: str = Field(
|
|
|
|
|
|
..., min_length=11, max_length=11, description="新手机号(11位)"
|
|
|
|
|
|
)
|
2026-03-18 17:18:23 +08:00
|
|
|
|
code: str = Field(..., min_length=6, max_length=6, description="验证码(6位)")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class UpdateNicknameRequest(BaseModel):
|
2026-03-19 14:36:14 +08:00
|
|
|
|
nickname: str = Field(
|
|
|
|
|
|
..., min_length=1, max_length=50, description="昵称(1-50个字符)"
|
|
|
|
|
|
)
|
2026-03-18 17:18:23 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class AvatarUploadResponse(BaseModel):
|
|
|
|
|
|
avatar_url: str
|