spark-server/internal/module/message/model/message.go
zhr ae9a71034d feat: implement Spark IM V3 modular monolith
Add HTTP /v1 MVC, TCP send path, groups with server-side member-avatar collage, object-storage upload, and friends/favorites around the architecture-v3 layout.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 19:52:11 +08:00

54 lines
1.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 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,
}
}