This commit is contained in:
root
2026-10-16 13:51:00 +08:00
parent 6bf949949c
commit 8fc899d0a9
3830 changed files with 11228 additions and 188377 deletions
+107
View File
@@ -0,0 +1,107 @@
"""认证模块请求/响应模型"""
import re
from pydantic import BaseModel, Field, field_validator, model_validator
PASSWORD_RE = re.compile(r"^(?=.*[A-Za-z])(?=.*\d).{8,32}$")
PHONE_RE = re.compile(r"^1\d{10}$")
EMAIL_RE = re.compile(r"^[\w.+-]+@[\w-]+\.[\w.]+$")
def _check_password(v: str) -> str:
if not PASSWORD_RE.match(v):
raise ValueError("密码须 8-32 位且包含字母和数字")
return v
class SmsSendReq(BaseModel):
phone: str
scene: str = Field(pattern="^(register|login|reset)$")
@field_validator("phone")
@classmethod
def _v_phone(cls, v: str) -> str:
if not PHONE_RE.match(v):
raise ValueError("手机号格式不正确")
return v
class EmailSendReq(BaseModel):
email: str
scene: str = Field(pattern="^(register|login|reset)$")
@field_validator("email")
@classmethod
def _v_email(cls, v: str) -> str:
if not EMAIL_RE.match(v):
raise ValueError("邮箱格式不正确")
return v
class RegisterReq(BaseModel):
type: str = Field(pattern="^(phone|email)$")
phone: str | None = None
email: str | None = None
code: str = Field(min_length=4, max_length=8)
password: str
nickname: str | None = Field(default=None, max_length=20)
invite_code: str | None = Field(default=None, max_length=10)
@field_validator("password")
@classmethod
def _v_pwd(cls, v: str) -> str:
return _check_password(v)
@model_validator(mode="after")
def _v_target(self):
if self.type == "phone" and not (self.phone and PHONE_RE.match(self.phone)):
raise ValueError("手机号格式不正确")
if self.type == "email" and not (self.email and EMAIL_RE.match(self.email)):
raise ValueError("邮箱格式不正确")
return self
class LoginReq(BaseModel):
type: str = Field(pattern="^(phone_password|phone_code|email_password)$")
phone: str | None = None
email: str | None = None
password: str | None = None
code: str | None = None
revoke: bool = False # 注销冻结期内:确认撤销注销
@model_validator(mode="after")
def _v_fields(self):
if self.type.startswith("phone") and not self.phone:
raise ValueError("手机号必填")
if self.type.startswith("email") and not self.email:
raise ValueError("邮箱必填")
if self.type.endswith("password") and not self.password:
raise ValueError("密码必填")
if self.type.endswith("code") and not self.code:
raise ValueError("验证码必填")
return self
class RefreshReq(BaseModel):
refresh_token: str = Field(min_length=10)
class PasswordResetReq(BaseModel):
type: str = Field(pattern="^(phone|email)$")
phone: str | None = None
email: str | None = None
code: str = Field(min_length=4, max_length=8)
new_password: str
@field_validator("new_password")
@classmethod
def _v_pwd(cls, v: str) -> str:
return _check_password(v)
@model_validator(mode="after")
def _v_target(self):
if self.type == "phone" and not (self.phone and PHONE_RE.match(self.phone)):
raise ValueError("手机号格式不正确")
if self.type == "email" and not (self.email and EMAIL_RE.match(self.email)):
raise ValueError("邮箱格式不正确")
return self