diff --git a/changelogs-v2/2026-06/25_站内信顶部铃铛未读角标接入_前端对接_管理后台.md b/changelogs-v2/2026-06/25_站内信顶部铃铛未读角标接入_前端对接_管理后台.md new file mode 100644 index 0000000..072a803 --- /dev/null +++ b/changelogs-v2/2026-06/25_站内信顶部铃铛未读角标接入_前端对接_管理后台.md @@ -0,0 +1,44 @@ +# 站内信顶部铃铛未读角标接入(前端对接 spec · 管理后台) + +- **类型**:前端对接说明(**后端零改动**,数据/信令均已就绪) +- **端类型**:管理后台(hl-ui,各业务页顶部铃铛) +- **日期**:2026-06-25 +- **后端联系人**:王骁(wx) + +> 现象(wx 反馈):房务给定制师发了消息,定制师(在 order-v2 订单详情页)顶部铃铛 🔔 **没有红点**。 +> 排查结论:**后端完全正确**(收件方未读已落库、实时信令已推、未读数接口返真值),铃铛没红点是**前端没把未读数接到铃铛上**。 + +--- + +## 1 后端已就绪(实测确认) + +某条消息发给收件方后,后端做了三件事: + +1. **落库未读**:`admin_message`(收件方 adminId、`is_read=0`)+ 收件方 `member.unread_count+1`。实测房务发「4」后 `countUnread(定制师)=1`、`member.unread_count=1`。 +2. **推实时信令**(事务提交后 SSE 广播,跨实例): + - 聊天消息 → 事件 `im-chat`(`type=CHAT`),payload 含 **`unreadCount`=收件方合并未读(NOTIFY+CHAT)**、`conversationKey`、`senderName`、`preview`、`priority`。 + - 系统通知 → 事件 `message`(`type=NOTIFY`),payload 含 `unreadCount`。 + - 标记已读后 → 事件 `unread-count`(`type=UNREAD`),payload 含最新 `unreadCount`(角标回落)。 +3. **未读数接口**:`GET /admin/message/unread-count` 返回当前登录员工合并未读总数(含聊天+通知)。 + +--- + +## 2 前端要做的(铃铛角标) + +铃铛红点/数字 = 当前登录员工的合并未读数,前端需两路驱动: + +1. **页面加载时**:调 `GET /admin/message/unread-count` 取初值,>0 显红点/数字。**每个有铃铛的页面都要调**(order-v2 订单详情、房务管家、各工作台…),不能只在某一个页面调。 +2. **实时更新**:订阅 SSE 流(`/ws/admin-msg/stream`,与聊天同一条连接),在以下事件里读 `payload.unreadCount` 刷新铃铛角标: + - `im-chat`(收到聊天)→ 取 `unreadCount` 刷角标(红点点亮/数字+1)。 + - `message`(收到通知)→ 同上。 + - `unread-count`(自己标已读后)→ 取 `unreadCount` 刷角标(回落)。 + +> 关键:`im-chat` 事件**既驱动聊天 UI(live append)也驱动铃铛角标**——前端收到 `im-chat` 别只 append 聊天、要同时用 `payload.unreadCount` 刷铃铛。order-v2 订单详情页当前的铃铛大概率①没订阅这条 SSE 流,②或没在加载时调 unread-count,所以收了消息不亮红点。 + +--- + +## 3 注意 + +1. 铃铛角标是**合并未读**(聊天+通知),口径就是 `GET /admin/message/unread-count`,SSE 各事件 payload 的 `unreadCount` 与之一致,直接用即可,不用前端自己累加计数。 +2. SSE 连接要保证在用户登录后的各页面都建立(铃铛是全局组件),否则切到没订阅的页面就收不到实时点亮(刷新时靠 unread-count 兜底)。 +3. 有疑问找后端(王骁/wx)。