| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697 |
- from pydantic import BaseModel, Field, model_validator
- from typing import Optional, Union, Any
- from datetime import datetime
- from enum import Enum
- class MessageType(str, Enum):
- MESSAGE = "MESSAGE"
- NOTIFICATION = "NOTIFICATION"
- class ContentType(str, Enum):
- TEXT = "TEXT"
- IMAGE = "IMAGE"
- VIDEO = "VIDEO"
- FILE = "FILE"
- # 用户在应用内发起的“申请通知”,用于在私信界面展示通知样式(携带 action_url/action_text)
- USER_NOTIFICATION = "USER_NOTIFICATION"
- class MessageBase(BaseModel):
- title: str = Field(..., max_length=255)
- content: Union[str, dict, Any] = Field(..., description="内容")
- content_type: ContentType = ContentType.TEXT
-
- type: MessageType = MessageType.MESSAGE
- app_id: Optional[str] = None # 改为字符串类型,支持开发者保存的字符串 app_id
-
- action_url: Optional[str] = None
- action_text: Optional[str] = None
-
- # SSO 扩展
- target_url: Optional[str] = None
- auto_sso: bool = False
- class MessageCreate(MessageBase):
- receiver_id: Optional[int] = None
- app_user_id: Optional[str] = None
- sender_app_user_id: Optional[str] = None # 应用发信时可选:帐内发起人,解析后写入 sender_id,用于审计和会话聚合
- is_broadcast: bool = False
-
- @model_validator(mode='after')
- def check_receiver(self):
- if self.is_broadcast:
- return self
- if not self.receiver_id and not (self.app_user_id and self.app_id):
- raise ValueError("非广播消息必须提供 receiver_id,或者同时提供 app_user_id 和 app_id")
- return self
- class MessageUpdate(BaseModel):
- is_read: Optional[bool] = None
- class MessageResponse(BaseModel):
- id: int
- sender_id: Optional[int]
- receiver_id: int
- app_id: Optional[int]
- app_name: Optional[str] = None # 应用名称,用于前端显示
-
- type: MessageType
- content_type: ContentType
-
- title: str
- content: str # DB 中存的是字符串
-
- action_url: Optional[str]
- action_text: Optional[str]
-
- is_read: bool
- created_at: datetime
- read_at: Optional[datetime]
- class Config:
- from_attributes = True
- class ConversationResponse(BaseModel):
- user_id: int
- username: str
- full_name: Optional[str]
- unread_count: int
- last_message: str
- last_message_type: ContentType
- updated_at: datetime
- # 系统会话标记及应用信息(用于拆分不同平台的系统通知会话)
- is_system: bool = False
- app_id: Optional[int] = None
- app_name: Optional[str] = None
- # 列表副文案:有 app 的应用通知为「应用通知」;无 app 的旧系统会话为空;用户会话为对端组织名,无组织为空
- remarks: Optional[str] = None
- class Config:
- from_attributes = True
- # Device Schema
- class DeviceRegister(BaseModel):
- device_token: str
- platform: str
- device_name: Optional[str] = None
|