docs(changelog): 22_4223 §9 切真细节契约 — 答前端Q1(open-house选传/后端不解析对端)/Q2(list+sentAt字符串yyyy-MM-dd/isMine)/Q3(SSE已LIVE别轮询)+在线态SSE工单#4273
这个提交包含在:
父节点
a5c7d90b8d
当前提交
65d5980a7d
@ -89,3 +89,31 @@ HOUSE 订单会话**只走 open-house**。通用 `/chat/open`(bizModule+peerAd
|
|||||||
**④ 在线态怎么拿(答「轮询还是 SSE」)**:读响应里的 `peerOnline`(Boolean)(open-house / conversations 都返)。它是**真实在线态**(后端 `adminPresenceService` Redis presence,对方有活跃后台连接=在线),**near-live、约 45s TTL 延迟**。刷新方式 = **轮询 / 重新拉**(re-open-house 或 re-conversations)。**没有专用在线态 SSE 推送**(本期不做)。消息实时到达走站内信 `im-chat` SSE(与在线态是两回事)。抢单前 peer 占位恒 `false`,配「未知」不显在线点即可。
|
**④ 在线态怎么拿(答「轮询还是 SSE」)**:读响应里的 `peerOnline`(Boolean)(open-house / conversations 都返)。它是**真实在线态**(后端 `adminPresenceService` Redis presence,对方有活跃后台连接=在线),**near-live、约 45s TTL 延迟**。刷新方式 = **轮询 / 重新拉**(re-open-house 或 re-conversations)。**没有专用在线态 SSE 推送**(本期不做)。消息实时到达走站内信 `im-chat` SSE(与在线态是两回事)。抢单前 peer 占位恒 `false`,配「未知」不显在线点即可。
|
||||||
|
|
||||||
**⑤ FLEET 车务聊天:未切真(deferred)。** 代码实证 `ConversationMemberService` 注「fleet 接入 deferred」——FLEET 会话的订单摘要 / 真实对端整合**没做**。通用 `/chat/open` 虽接受 `bizModule=FLEET`,但**无真实车务数据对接**。**前端 FLEET 聊天先别做切真**,等车务接入工单(wx「车务用了再加」)。mock 里没有 SSE/在线态属正常——FLEET 整条都还没切真。
|
**⑤ FLEET 车务聊天:未切真(deferred)。** 代码实证 `ConversationMemberService` 注「fleet 接入 deferred」——FLEET 会话的订单摘要 / 真实对端整合**没做**。通用 `/chat/open` 虽接受 `bizModule=FLEET`,但**无真实车务数据对接**。**前端 FLEET 聊天先别做切真**,等车务接入工单(wx「车务用了再加」)。mock 里没有 SSE/在线态属正常——FLEET 整条都还没切真。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9. 切真细节契约(2026-06-23 实测 origin/dev-v3 + LIVE,答前端 Q1/Q2/Q3)
|
||||||
|
|
||||||
|
### Q1 · peerAdminId 强不强制?后端解析对端吗?
|
||||||
|
- **HOUSE 用 `POST /admin/message/chat/open-house`,`peerAdminId` 选填**(不传 = 抢单前 pending 占位「待接单房务」)。**别用通用 `/chat/open`**(它 `peerAdminId` `@NotNull` 强制,只给 FLEET/DIRECT/显式 peer)。
|
||||||
|
- **后端不反查 order-v3 解析对端**(`ChatManager.openHouse` javadoc 明示「前端传 peer,不反查 order-v3」)。对端 id **前端传**,且前端数据里都有:
|
||||||
|
- 定制师→房务:`peerAdminId = claimerId`(来自 `hotelRequirementBrief.claimerId`;抢单前为 null → 不传 = pending)。
|
||||||
|
- 房务→定制师:`peerAdminId = consultantId`(订单/抢单数据里就有)。
|
||||||
|
- 「两端收敛同一条会话」靠键 `HOUSE:{orderId}`(与 peer 无关);但建双方成员行需开方各自传对端 id(抢单前定制师不传 → 房务抢单后 order-v3 afterCommit 自动补房务成员行 + 送达历史,前端无需管)。
|
||||||
|
- **FLEET**:无 open-fleet,通用 open 强制 `peerAdminId`,且 FLEET deferred → **先别做**。
|
||||||
|
- 可选增强:若要前端只传 orderId、后端按 claim/consultant 自动解析对端 → 需后端加 Feign 反查 order-v3,**独立工单待 wx 定**(当前不做,前端传 id 即可跑通)。
|
||||||
|
|
||||||
|
### Q2 · 响应字段(实测对齐 #4020,别凭注释)
|
||||||
|
- 线程 `GET /admin/message/chat/{conversationKey}/messages` → `{conversationKey, hasMore, nextCursor, list[]}`。**是 `list` 不是 `records`**;`list` 按**时间正序**(旧→新,从上往下渲染);游标 `nextCursor` = 本页最小 messageId,作下次 `beforeId` 上翻历史。
|
||||||
|
- 消息项 `list[]`:`{messageId, senderAdminId, senderName, senderRole, msgType(TEXT/IMAGE/SYSTEM), priority(NORMAL/URGENT), content, isMine, sentAt}`。
|
||||||
|
- **`isMine`** = Boolean,后端按 `senderAdminId == 当前登录人` 算(左右气泡布局用)。
|
||||||
|
- **`sentAt`** = **String,格式 `yyyy-MM-dd HH:mm:ss`**(如 `2026-06-16 11:02:31`)——**不是毫秒、不是 ISO-8601**,本地时间到秒、无时区无毫秒。前端按此格式 parse,别当 epoch/ISO。
|
||||||
|
|
||||||
|
### Q3 · SSE 实时(**已有且 LIVE,别再轮询**)
|
||||||
|
- **SSE 端点 `GET /ws/admin-msg/stream`(`text/event-stream`)实测 LIVE(200 + 正确 Content-Type)**。
|
||||||
|
- 发消息:后端 `send` 事务 afterCommit 经 Redis Pub/Sub 广播 **CHAT 信令**给收件方 → SSE 实时冒泡(带 senderName / 预览 / priority + conversationKey)。
|
||||||
|
- **前端应订阅 `/ws/admin-msg/stream`,收到 CHAT 信令即 live-append / 刷新对应会话**,替换「发送后短轮询 6 次(~8s)」的兜底。「没有 SSE」= 没接,不是没有。
|
||||||
|
|
||||||
|
### 在线/离线态走 SSE(wx 2026-06-23 新要求 → 后端工单 **#4273**)
|
||||||
|
- 现状:`peerOnline` 是**轮询字段**(Redis presence key TTL 45s + SSE 心跳续期),**在线态变更不推送**。
|
||||||
|
- wx 拍:改为 **SSE 实时推在线/离线**。已立后端工单 **#4273**(hl-user-service):SSE 连接建/断 → 标在线/离线 → 向会话对端推 `presence` 事件。**前端届时订阅 presence 事件、停 peerOnline 轮询**(保留字段做首屏兜底)。未落地前先用 peerOnline 轮询。
|
||||||
|
|||||||
正在加载...
x
在新工单中引用
屏蔽一个用户