message.py 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. from pydantic import BaseModel, Field, model_validator
  2. from typing import Optional, Union, Any
  3. from datetime import datetime
  4. from enum import Enum
  5. class MessageType(str, Enum):
  6. MESSAGE = "MESSAGE"
  7. NOTIFICATION = "NOTIFICATION"
  8. class ContentType(str, Enum):
  9. TEXT = "TEXT"
  10. IMAGE = "IMAGE"
  11. VIDEO = "VIDEO"
  12. FILE = "FILE"
  13. class MessageBase(BaseModel):
  14. title: str = Field(..., max_length=255)
  15. content: Union[str, dict, Any] = Field(..., description="内容")
  16. content_type: ContentType = ContentType.TEXT
  17. type: MessageType = MessageType.MESSAGE
  18. app_id: Optional[str] = None # 改为字符串类型,支持开发者保存的字符串 app_id
  19. action_url: Optional[str] = None
  20. action_text: Optional[str] = None
  21. # SSO 扩展
  22. target_url: Optional[str] = None
  23. auto_sso: bool = False
  24. class MessageCreate(MessageBase):
  25. receiver_id: Optional[int] = None
  26. app_user_id: Optional[str] = None
  27. @model_validator(mode='after')
  28. def check_receiver(self):
  29. if not self.receiver_id and not (self.app_user_id and self.app_id):
  30. raise ValueError("必须提供 receiver_id,或者同时提供 app_user_id 和 app_id")
  31. return self
  32. class MessageUpdate(BaseModel):
  33. is_read: Optional[bool] = None
  34. class MessageResponse(BaseModel):
  35. id: int
  36. sender_id: Optional[int]
  37. receiver_id: int
  38. app_id: Optional[int]
  39. app_name: Optional[str] = None # 应用名称,用于前端显示
  40. type: MessageType
  41. content_type: ContentType
  42. title: str
  43. content: str # DB 中存的是字符串
  44. action_url: Optional[str]
  45. action_text: Optional[str]
  46. is_read: bool
  47. created_at: datetime
  48. read_at: Optional[datetime]
  49. class Config:
  50. from_attributes = True
  51. class ConversationResponse(BaseModel):
  52. user_id: int
  53. username: str
  54. full_name: Optional[str]
  55. unread_count: int
  56. last_message: str
  57. last_message_type: ContentType
  58. updated_at: datetime
  59. # 系统会话标记及应用信息(用于拆分不同平台的系统通知会话)
  60. is_system: bool = False
  61. app_id: Optional[int] = None
  62. app_name: Optional[str] = None
  63. class Config:
  64. from_attributes = True
  65. # Device Schema
  66. class DeviceRegister(BaseModel):
  67. device_token: str
  68. platform: str
  69. device_name: Optional[str] = None