user.py 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  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] = Field(
  45. None,
  46. description="姓名;UPSERT 时必填。新建用户时英文名由平台根据姓名自动生成并去重",
  47. )
  48. english_name: Optional[str] = Field(
  49. None,
  50. description="已废弃:M2M 同步不再使用此字段,英文名由平台根据姓名生成",
  51. )
  52. password: Optional[str] = None
  53. status: Optional[str] = None
  54. mapped_key: str = Field(..., min_length=1, max_length=100, description="外部系统用户 ID(映射账号)")
  55. mapped_email: Optional[str] = None # External User Email
  56. is_active: Optional[bool] = None # True=Active, False=Disabled. None=No Change
  57. sync_action: Optional[str] = "UPSERT"
  58. @field_validator("mobile", "mapped_key", mode="before")
  59. @classmethod
  60. def strip_required_str(cls, v):
  61. if isinstance(v, str):
  62. return v.strip()
  63. return v
  64. class UserInDBBase(UserBase):
  65. id: int
  66. created_at: datetime
  67. updated_at: datetime
  68. class Config:
  69. from_attributes = True
  70. class User(UserInDBBase):
  71. pass
  72. class UserInDB(UserInDBBase):
  73. password_hash: str
  74. class UserList(BaseModel):
  75. total: int
  76. items: List[User]
  77. class UserSyncSimple(BaseModel):
  78. mobile: str
  79. name: Optional[str] = None
  80. english_name: Optional[str] = None
  81. class Config:
  82. from_attributes = True
  83. class UserSyncList(BaseModel):
  84. total: int
  85. items: List[UserSyncSimple]