user.py 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. from typing import Optional
  2. from pydantic import BaseModel, EmailStr, Field, field_validator
  3. from datetime import datetime
  4. from typing import List
  5. # 中国大陆手机号(与 M2M 同步等接口一致)
  6. _CN_MOBILE_PATTERN = r"^1[3-9]\d{9}$"
  7. class UserBase(BaseModel):
  8. mobile: str
  9. name: Optional[str] = None
  10. english_name: Optional[str] = None
  11. status: str = "PENDING"
  12. role: Optional[str] = "ORDINARY_USER"
  13. is_deleted: int = 0
  14. class UserCreate(UserBase):
  15. password: str
  16. admin_password: Optional[str] = None
  17. class UserRegister(BaseModel):
  18. mobile: str
  19. password: str
  20. sms_code: str # Added field
  21. name: str # Chinese Name
  22. class PromoteUserRequest(BaseModel):
  23. password: str
  24. captcha_id: str
  25. captcha_code: str
  26. class DeleteUserRequest(BaseModel):
  27. """删除普通用户(软删除)时校验操作者密码与短信验证码。"""
  28. password: str
  29. sms_code: str
  30. class BatchResetEnglishNameRequest(BaseModel):
  31. user_ids: List[int]
  32. admin_password: str
  33. class UserUpdate(BaseModel):
  34. password: Optional[str] = None
  35. mobile: Optional[str] = None
  36. name: Optional[str] = None
  37. english_name: Optional[str] = None
  38. status: Optional[str] = None
  39. role: Optional[str] = None
  40. is_deleted: Optional[int] = None
  41. admin_password: Optional[str] = None
  42. class UserSyncRequest(BaseModel):
  43. mobile: str = Field(..., pattern=_CN_MOBILE_PATTERN, description="用户手机号(平台唯一标识)")
  44. name: Optional[str] = None
  45. english_name: Optional[str] = None
  46. password: Optional[str] = None
  47. status: Optional[str] = None
  48. mapped_key: str = Field(..., min_length=1, max_length=100, description="外部系统用户 ID(映射账号)")
  49. mapped_email: Optional[str] = None # External User Email
  50. is_active: Optional[bool] = None # True=Active, False=Disabled. None=No Change
  51. sync_action: Optional[str] = "UPSERT"
  52. @field_validator("mobile", "mapped_key", mode="before")
  53. @classmethod
  54. def strip_required_str(cls, v):
  55. if isinstance(v, str):
  56. return v.strip()
  57. return v
  58. class UserInDBBase(UserBase):
  59. id: int
  60. created_at: datetime
  61. updated_at: datetime
  62. class Config:
  63. from_attributes = True
  64. class User(UserInDBBase):
  65. pass
  66. class UserInDB(UserInDBBase):
  67. password_hash: str
  68. class UserList(BaseModel):
  69. total: int
  70. items: List[User]
  71. class UserSyncSimple(BaseModel):
  72. mobile: str
  73. name: Optional[str] = None
  74. english_name: Optional[str] = None
  75. class Config:
  76. from_attributes = True
  77. class UserSyncList(BaseModel):
  78. total: int
  79. items: List[UserSyncSimple]