113 lines
3.7 KiB
Python
113 lines
3.7 KiB
Python
"""
|
||
用户模型
|
||
"""
|
||
from datetime import datetime
|
||
from typing import Optional
|
||
from pydantic import BaseModel, EmailStr, Field
|
||
|
||
|
||
class User(BaseModel):
|
||
"""用户模型"""
|
||
id: Optional[int] = None
|
||
username: str = Field(..., max_length=50)
|
||
email: EmailStr
|
||
phone: str = Field(..., max_length=255)
|
||
wechat_openid: Optional[str] = Field(None, max_length=100)
|
||
wechat_unionid: Optional[str] = Field(None, max_length=100)
|
||
wechat_nickname: Optional[str] = Field(None, max_length=100)
|
||
wechat_avatar_url: Optional[str] = None
|
||
display_name: Optional[str] = Field(None, max_length=100)
|
||
avatar_url: Optional[str] = None
|
||
bio: Optional[str] = None
|
||
is_active: bool = True
|
||
email_verified: bool = False
|
||
is_search: bool = Field(False, description="是否启用联网搜索")
|
||
created_at: Optional[datetime] = None
|
||
updated_at: Optional[datetime] = None
|
||
last_login_at: Optional[datetime] = None
|
||
hashed_password: Optional[str] = Field(None, max_length=255)
|
||
# 企业版
|
||
enterprise_id: Optional[int] = None
|
||
department_id: Optional[int] = None
|
||
role: str = Field("employee", description="admin | leader | employee")
|
||
is_first_login: bool = True
|
||
|
||
class Config:
|
||
from_attributes = True
|
||
|
||
|
||
class UserCreate(BaseModel):
|
||
"""创建用户请求模型"""
|
||
username: str = Field(..., max_length=50)
|
||
email: EmailStr
|
||
phone: str = Field(..., max_length=255)
|
||
password: str = Field(..., min_length=6)
|
||
display_name: Optional[str] = Field(None, max_length=100)
|
||
|
||
|
||
class PhoneRegisterRequest(BaseModel):
|
||
"""手机号注册请求模型"""
|
||
phone: str = Field(..., pattern=r'^1[3-9]\d{9}$', description="手机号")
|
||
code: str = Field(..., min_length=4, max_length=6, description="验证码")
|
||
password: str = Field(..., min_length=6, description="密码")
|
||
username: Optional[str] = Field(None, max_length=50, description="用户名,可选")
|
||
|
||
|
||
class PhoneLoginRequest(BaseModel):
|
||
"""手机号登录请求模型"""
|
||
phone: str = Field(..., pattern=r'^1[3-9]\d{9}$', description="手机号")
|
||
code: Optional[str] = Field(None, min_length=4, max_length=6, description="验证码")
|
||
password: Optional[str] = Field(None, min_length=6, description="密码")
|
||
|
||
|
||
class SendSmsCodeRequest(BaseModel):
|
||
"""发送短信验证码请求模型"""
|
||
phone: str = Field(..., pattern=r'^1[3-9]\d{9}$', description="手机号")
|
||
scene: str = Field("login", description="场景:login/register/reset")
|
||
captcha_id: str = Field(..., description="图形验证码 ID")
|
||
captcha_code: str = Field(..., min_length=4, max_length=6, description="图形验证码")
|
||
|
||
|
||
class WechatLoginRequest(BaseModel):
|
||
"""微信小程序登录请求模型"""
|
||
code: str = Field(..., description="微信登录凭证 (wx.login 获取)")
|
||
phone_code: Optional[str] = Field(None, description="手机号授权码 (getPhoneNumber 获取,用于账号合并)")
|
||
|
||
|
||
class UserLogin(BaseModel):
|
||
"""用户登录请求模型"""
|
||
username: str
|
||
password: str
|
||
|
||
|
||
class UserResponse(BaseModel):
|
||
"""用户响应模型(不包含敏感信息)"""
|
||
id: int
|
||
username: str
|
||
email: str
|
||
phone: str
|
||
display_name: Optional[str] = None
|
||
avatar_url: Optional[str] = None
|
||
bio: Optional[str] = None
|
||
is_active: bool
|
||
email_verified: bool
|
||
is_search: bool = False
|
||
created_at: datetime
|
||
updated_at: datetime
|
||
last_login_at: Optional[datetime] = None
|
||
enterprise_id: Optional[int] = None
|
||
department_id: Optional[int] = None
|
||
role: str = "employee"
|
||
is_first_login: bool = True
|
||
|
||
class Config:
|
||
from_attributes = True
|
||
|
||
|
||
class TokenResponse(BaseModel):
|
||
"""Token 响应模型"""
|
||
access_token: str
|
||
token_type: str = "bearer"
|
||
user: UserResponse
|
||
|