平台功能(自研)消息中心
消息中心
消息中心由两部分组成:
- 管理端:运营或管理员创建消息、选择接收范围与发送方式,发布后异步投递;
- 用户端:每个登录用户在「我的消息」中查看、标记已读、删除,并维护自己的消息偏好。
站内通知通过 SSE 实时推送,未读数独立计数;邮件已接入平台 SMTP 配置,短信与微信通道目前是占位实现。
菜单与权限
| 菜单 | 路径 | 权限标识 |
|---|---|---|
| 系统消息 | /system/message | system:message:list / query / add / edit / remove / export / publish |
| 消息发送日志 | /monitor/messageLog | monitor:messageLog:list / query / remove / export |
| 我的消息 | 用户端入口 | 登录即可,无额外权限 |
/system/messageCenter/** 下的接口全部基于当前登录用户,不需要权限标识;服务端不会信任前端传入的 userId。
数据模型
sys_message(消息主体)
| 字段 | 说明 |
|---|---|
message_id | 主键 |
message_type | 消息类型,字典 sys_message_type,如 notice / system |
message_title | 标题 |
message_content | 正文 |
message_scope | 接收范围:all 全部用户,specified 指定用户 |
message_user_ids | 指定用户 ID,逗号分隔 |
source_id / source_type | 业务来源,便于跳回订单、工单等对象 |
priority | 优先级 |
read_count | 已读人数,由日志回写 |
send_status | pending / sending / success / failed |
send_method | 发送方式,逗号分隔:system,email,sms,wechat |
send_time | 最近一次发布时间 |
error_msg | 发送失败摘要 |
sys_message_log(每人一条投递记录)
| 字段 | 说明 |
|---|---|
log_id | 主键 |
message_id | 所属消息 |
receiver_id | 接收用户 |
send_method | 本条日志对应的一种发送方式 |
send_status | success / failed |
is_read | Y / N |
read_time | 阅读时间 |
send_time | 投递时间 |
error_msg | 该通道的失败原因 |
「全部用户」消息会为每个用户生成日志,数据量随用户数线性增长,发布前请确认范围。
发布流程
管理端 publish
→ send_status = sending,投递到 RabbitMQ
→ MessageSendConsumer 展开接收范围
all:分页查询全部用户,每 1000 人一批
specified:按 message_user_ids 拆分
→ MessageLogCreateConsumer 为每个用户建日志并逐通道发送
→ 全部完成后回写 send_status = success / failed几个关键行为:
- 只有
sending不能重复发布,success/failed/pending都可以重新发布;重发会重新生成投递日志。 - 发布不是同步发送。接口返回成功只代表已进入队列,最终结果看消息状态与发送日志。
- 消费失败会
nack重投,最多 3 次;超过后把消息标记为failed并记录原因。 - 正在发送中的消息不允许删除,删除消息会级联删除对应的全部发送日志。
- 草稿保存与编辑只允许
pending状态,编辑时服务端会忽略前端传入的send_status。
发送方式现状
| 方式 | 标识 | 当前实现 |
|---|---|---|
| 站内消息 | system | 已实现:写入日志并通过 SSE 推送,附带最新未读数 |
| 邮件 | email | 已实现:读取用户邮箱,渲染 templates/mail/system-message.ftl,走平台 SMTP 配置 |
| 短信 | sms | 占位:只记录日志,暂未调用短信服务商 |
| 微信 | wechat | 占位:用户表尚无 openId 字段,暂未接入模板消息 |
未填写 send_method 时只落库、不推送。多选时任一通道成功,该用户日志即记为 success,失败通道的原因会写入 error_msg。
邮件依赖邮件配置:
mail.enabled关闭或 SMTP 参数缺失时,邮件通道会失败,但不影响站内消息。
管理端接口
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /system/message/list | 分页查询,支持类型、标题、范围、状态等条件 |
| GET | /system/message/{messageId} | 详情 |
| POST | /system/message | 新增草稿,强制 send_status=pending |
| POST | /system/message/saveDraft | 保存草稿,返回消息 ID |
| PUT | /system/message | 修改,仅 pending 可改 |
| PUT | /system/message/publish/{messageId} | 发布单条 |
| PUT | /system/message/batchPublish | 批量发布,请求体为 ID 数组 |
| GET | /system/message/logCount?messageIds= | 查询消息已产生的日志数量 |
| DELETE | /system/message/{messageIds} | 删除消息及日志 |
管理端列表首屏(第 1 页且每页不超过 20 条)有 2 分钟 Redis 缓存,新增、修改、发布、删除都会主动清理。
开放接口
公开公告不需要登录,供 C 端首页或门户读取:
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /open/system/message/list | 已发送、类型为 notice、范围为 all 的公告分页 |
| GET | /open/system/message/latest?limit=3 | 最新公告,默认 3 条、上限 10 条,缓存 3 分钟 |
| GET | /open/system/message/{messageId} | 公告详情 |
/latest 是首页滚动通知的热路径,因此单独做了缓存;/open/** 在安全白名单内,租户由开放接口的租户过滤器设置。
插件内发消息不要直接操作数据表,使用 SDK 的 PlatformMessageApi#send:它把「落库 + 发布」合成一步,失败时返回 null 而不抛异常,避免通知失败回滚业务事务。详见能力开放。
前端接入
站内消息通过 SSE 推送,事件数据形如:
{
"messageId": 1001,
"messageType": "notice",
"messageTitle": "系统维护通知",
"messageContent": "今晚 23:00 起进行维护",
"priority": "high",
"sendTime": "2026-10-21 10:00:00",
"unreadCount": 5
}前端收到后可直接更新铃铛未读数并弹出提示;也可以只调用 GET /system/messageCenter/unreadCount 轮询兜底。用户收件箱的接口与偏好设置见我的消息。
界面截图

消息中心(截图占位)
/images/docs/message-center.png建议 1920 × 1080,截消息列表与消息设置页签。