Skip to content

数据库表创建-消息回执 ​

版本归属 ​

用于 v7 扩展架构版。

表清单 ​

  • message_receipts

message_receipts ​

消息回执表。用于记录某条消息对某个用户的未读和已读状态。

执行 SQL ​

sql
CREATE TABLE IF NOT EXISTS message_receipts (
  id BIGINT PRIMARY KEY AUTO_INCREMENT,
  message_id BIGINT NOT NULL,
  user_id BIGINT NOT NULL,
  status ENUM('unread', 'read') NOT NULL DEFAULT 'unread',
  updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  UNIQUE KEY uk_message_receipts_message_user (message_id, user_id)
);

字段说明:

  • id:回执记录 ID
  • message_id:消息 ID
  • user_id:接收方用户 ID
  • status:回执状态,unread 表示未读,read 表示已读
  • updated_at:状态更新时间

索引说明:

  • uk_message_receipts_message_user:保证一条消息对一个用户只有一条回执记录

业务约束:

  • v3 阶段使用 conversation_members.last_read_message_id 做会话级已读
  • v7 才启用 message_receipts 做逐条消息已读/未读详情
  • 没有回执记录时也可视为未读;显式 unread 用于把某条消息标回未读
  • 查询某条消息已读成员时按 message_id 查询 status = 'read'

建表后检查 ​

sql
DESC message_receipts;
SHOW INDEX FROM message_receipts;

最小验证 ​

以下 SQL 假设 messages 表中已经存在 id = 1 的消息,users 表中已经存在 id = 2 的接收用户。

写入未读回执:

sql
INSERT INTO message_receipts (message_id, user_id, status)
VALUES (1, 2, 'unread');

用户已读时更新状态:

sql
INSERT INTO message_receipts (message_id, user_id, status)
VALUES (1, 2, 'read')
ON DUPLICATE KEY UPDATE
  status = 'read',
  updated_at = CURRENT_TIMESTAMP;

查询消息已读用户:

sql
SELECT user_id, status, updated_at
FROM message_receipts
WHERE message_id = 1 AND status = 'read';

用户标回未读:

sql
INSERT INTO message_receipts (message_id, user_id, status)
VALUES (1, 2, 'unread')
ON DUPLICATE KEY UPDATE
  status = 'unread',
  updated_at = CURRENT_TIMESTAMP;

代码落地点 ​

  • models/message_receipt_model.go 定义 MessageReceipt
  • WebSocket 投递只负责实时消息下发,不自动写入回执
  • 客户端读到消息后写入或更新为 read
  • 客户端需要标回未读时写入或更新为 unread
  • 查询回执前必须校验当前用户是消息所属会话成员

基于 MIT 许可发布