// Package model is message persistence. One file per table. package model import ( "time" "spark-server/internal/module/message/entity" ) // Message maps table messages. content is a serialized BLOB, not a string. type Message struct { ID int64 `gorm:"column:id;primaryKey;comment:Snowflake MsgId,主键、排序键、同步游标"` ConversationID int64 `gorm:"column:conversation_id;comment:所属会话 id"` SenderID int64 `gorm:"column:sender_id;comment:发送者 user_id"` ClientMsgID string `gorm:"column:client_msg_id;comment:客户端消息 id,与 sender+会话 组成幂等键"` MessageType int16 `gorm:"column:message_type;comment:消息类型:1文本 2图片 3语音 4视频 5表情 6GIF 7文件 8位置 9系统"` Content []byte `gorm:"column:content;type:blob;comment:序列化后的消息体(JSON 字节),禁止存原始 string;媒体只存对象存储 key"` Status int `gorm:"column:status;comment:1=正常 2=已撤回 3=审核隐藏"` CreatedAt time.Time `gorm:"column:created_at;comment:服务端入库时间"` } func (Message) TableName() string { return "messages" } func (r *Message) Entity() *entity.Message { if r == nil { return nil } return &entity.Message{ ID: r.ID, ConversationID: r.ConversationID, SenderID: r.SenderID, ClientMsgID: r.ClientMsgID, Type: entity.Type(r.MessageType), Content: r.Content, Status: r.Status, CreatedAtMS: r.CreatedAt.UnixMilli(), } } func FromEntity(m *entity.Message) *Message { if m == nil { return nil } return &Message{ ID: m.ID, ConversationID: m.ConversationID, SenderID: m.SenderID, ClientMsgID: m.ClientMsgID, MessageType: int16(m.Type), Content: m.Content, Status: m.Status, } }