146 lines
5.4 KiB
Python
146 lines
5.4 KiB
Python
# =============================================================================
|
||
# 企微IT智能服务台 — 消息 Pydantic Schema
|
||
# =============================================================================
|
||
# 说明:定义消息相关的请求/响应数据结构
|
||
# 支持消息类型:文本(text)/图片(image)/文件(file)/系统(system)
|
||
# =============================================================================
|
||
|
||
from datetime import datetime
|
||
from typing import Any, Dict, List, Optional
|
||
|
||
from pydantic import BaseModel, Field, field_validator
|
||
|
||
|
||
# --------------------------------------------------------------------------
|
||
# 消息类型和发送者类型的合法值
|
||
# --------------------------------------------------------------------------
|
||
VALID_MSG_TYPES = {"text", "image", "file", "system"}
|
||
VALID_SENDER_TYPES = {"employee", "agent", "ai", "system"}
|
||
|
||
|
||
# --------------------------------------------------------------------------
|
||
# 创建消息 Schema(坐席发送消息时使用)
|
||
# --------------------------------------------------------------------------
|
||
class MessageCreate(BaseModel):
|
||
"""创建消息请求 Schema。
|
||
|
||
坐席发送消息时使用。
|
||
支持文本消息和文件/图片消息。
|
||
|
||
Attributes:
|
||
content: 消息内容(文本消息为正文,文件消息为文件URL或描述)
|
||
msg_type: 消息类型(默认 text,支持 image/file)
|
||
media_url: 媒体文件URL(图片/文件消息时使用)
|
||
file_name: 文件名(文件消息时使用)
|
||
file_size: 文件大小(字节,文件消息时使用)
|
||
"""
|
||
|
||
content: str = Field(..., min_length=1, description="消息内容")
|
||
# 支持文本、图片、文件类型
|
||
msg_type: str = Field(default="text", description="消息类型: text/image/file")
|
||
# M1 新增:文件上传相关字段
|
||
media_url: Optional[str] = Field(None, description="媒体文件URL(图片/文件消息时使用)")
|
||
file_name: Optional[str] = Field(None, description="文件名")
|
||
file_size: Optional[int] = Field(None, description="文件大小(字节)")
|
||
# M1 新增:引用回复
|
||
reply_to_id: Optional[str] = Field(None, description="引用回复:被回复的消息ID")
|
||
|
||
@field_validator("msg_type")
|
||
@classmethod
|
||
def validate_msg_type(cls, v: str) -> str:
|
||
"""校验消息类型是否合法。"""
|
||
if v not in VALID_MSG_TYPES:
|
||
raise ValueError(f"无效的消息类型: {v},合法值为: {VALID_MSG_TYPES}")
|
||
return v
|
||
|
||
|
||
# --------------------------------------------------------------------------
|
||
# 企微回调消息 Schema(从企微接收到的消息)
|
||
# --------------------------------------------------------------------------
|
||
class WecomInboundMessage(BaseModel):
|
||
"""企微回调消息 Schema。
|
||
|
||
解析企微回调 XML 后得到的结构化消息。
|
||
|
||
Attributes:
|
||
from_user_id: 发送者企微UserID
|
||
content: 消息内容
|
||
msg_type: 消息类型(text/image等)
|
||
create_time: 消息创建时间戳
|
||
agent_id: 应用AgentID
|
||
"""
|
||
|
||
from_user_id: str = Field(..., description="发送者企微UserID")
|
||
content: str = Field(default="", description="消息内容")
|
||
msg_type: str = Field(default="text", description="消息类型")
|
||
create_time: Optional[int] = Field(None, description="消息创建时间戳")
|
||
agent_id: Optional[str] = Field(None, description="应用AgentID")
|
||
|
||
|
||
# --------------------------------------------------------------------------
|
||
# 消息响应 Schema(返回给前端的数据结构)
|
||
# --------------------------------------------------------------------------
|
||
class MessageResponse(BaseModel):
|
||
"""消息响应 Schema。
|
||
|
||
返回给前端的消息数据结构。
|
||
使用 from_attributes=True 支持从 SQLAlchemy 模型直接转换。
|
||
|
||
Attributes:
|
||
id: 消息ID
|
||
conversation_id: 所属会话ID
|
||
sender_type: 发送者类型
|
||
sender_id: 发送者ID
|
||
sender_name: 发送者姓名
|
||
content: 消息内容
|
||
msg_type: 消息类型
|
||
media_url: 媒体文件URL
|
||
file_name: 文件名
|
||
file_size: 文件大小
|
||
extra_data: 扩展元数据
|
||
ai_suggestion: 是否为AI建议
|
||
is_read: 是否已读
|
||
created_at: 创建时间
|
||
"""
|
||
|
||
id: str
|
||
conversation_id: str
|
||
sender_type: str
|
||
sender_id: str
|
||
sender_name: str
|
||
content: str
|
||
msg_type: str
|
||
# M1 新增:媒体/文件相关字段
|
||
media_url: Optional[str] = None
|
||
file_name: Optional[str] = None
|
||
file_size: Optional[int] = None
|
||
extra_data: Optional[Dict[str, Any]] = None
|
||
# M1 新增:引用回复
|
||
reply_to_id: Optional[str] = None
|
||
ai_suggestion: bool
|
||
is_read: bool
|
||
created_at: datetime
|
||
# M2 新增:消息状态和可撤回时间
|
||
status: str = "sent"
|
||
recallable_until: Optional[datetime] = None
|
||
|
||
model_config = {"from_attributes": True}
|
||
|
||
|
||
# --------------------------------------------------------------------------
|
||
# 消息列表响应 Schema
|
||
# --------------------------------------------------------------------------
|
||
class MessageListResponse(BaseModel):
|
||
"""消息列表响应 Schema。
|
||
|
||
包含消息列表和是否还有更多消息的标志,
|
||
用于向上加载历史消息。
|
||
|
||
Attributes:
|
||
items: 消息列表
|
||
has_more: 是否还有更多历史消息
|
||
"""
|
||
|
||
items: List[MessageResponse]
|
||
has_more: bool
|