docs(chat): 真已读readByPeer+im-chat-read SSE + 房务侧detail.messages已上线实测(22_4223§11/22_4237§8, #4288/#4289 PR#4294)
这个提交包含在:
父节点
b30dee3d22
当前提交
1e9f9ad881
@ -145,3 +145,28 @@ HOUSE 订单会话**只走 open-house**。通用 `/chat/open`(bizModule+peerAd
|
|||||||
**两件待 wx 拍的「可选增强」(前端不必等,先按上表修假已读)**:
|
**两件待 wx 拍的「可选增强」(前端不必等,先按上表修假已读)**:
|
||||||
1. **真·已读回执**(抢单后对方真读了才显「已读」)——需后端把 per-message 已读态(基于会话成员 `lastReadMessageId` 水位)暴露进线程 VO,是独立后端工单。当前最小修 = 前端按上表把假已读改成「留言/已送达」即可。
|
1. **真·已读回执**(抢单后对方真读了才显「已读」)——需后端把 per-message 已读态(基于会话成员 `lastReadMessageId` 水位)暴露进线程 VO,是独立后端工单。当前最小修 = 前端按上表把假已读改成「留言/已送达」即可。
|
||||||
2. **抢单池给房务「该单有 N 条定制师留言」预览做诱饵**——需后端在抢单池 VO 补 pending 留言计数,独立后端工单。当前抢单后才送达可见。
|
2. **抢单池给房务「该单有 N 条定制师留言」预览做诱饵**——需后端在抢单池 VO 补 pending 留言计数,独立后端工单。当前抢单后才送达可见。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 11. ✅ 真已读回执 + 房务侧留言可见 已上线测试服(2026-06-23 · #4288/#4289 · PR #4294 · 已 API 实测)
|
||||||
|
|
||||||
|
§10 标的两项 wx 已拍并实现上线,**取代 §10 的「待定/显已送达」口径**:
|
||||||
|
|
||||||
|
### 11.1 真实「已读/未读」回执(#4289)
|
||||||
|
- 线程消息出参(`GET /admin/message/chat/{conversationKey}/messages` 的 `list[]`)**新增 `readByPeer`(Boolean)**:仅我方消息(`isMine=true`)有意义 = 对端已读到本条(对端成员已读水位 >= 本消息 id)。抢单前无对端恒 false;对端发来的消息(isMine=false)此字段无意义。
|
||||||
|
- **气泡显示口径(升级版,取代 §10)**:
|
||||||
|
|
||||||
|
| 我方消息状态 | 气泡下显示 |
|
||||||
|
|---|---|
|
||||||
|
| 抢单前 | 「留言」 |
|
||||||
|
| 抢单后 · `readByPeer=false` | 「已送达」 |
|
||||||
|
| 抢单后 · `readByPeer=true` | 「已读」 |
|
||||||
|
| 对端发来的(`isMine=false`) | 不标 |
|
||||||
|
|
||||||
|
- **实时刷已读**:对端调 `POST /admin/message/chat/{conversationKey}/read` 后,后端经 SSE 推 **`im-chat-read`** 事件给我方(payload `{conversationKey, readerAdminId, lastReadMessageId}`)→ 前端把本会话 `id <= lastReadMessageId` 的我方气泡刷「已读」。**订阅 `im-chat-read`**(与 `im-chat` 同一条 SSE 流 `/ws/admin-msg/stream`;NOTIFY/CHAT 事件不变向后兼容)。
|
||||||
|
- 实测:线程出参已含 `readByPeer`(字段顺序 `…, isMine, readByPeer, sentAt`)。
|
||||||
|
|
||||||
|
### 11.2 房务侧「内部留言框」显示抢单前留言(#4288)
|
||||||
|
- 详见 `22_4237`:房务订单详情 `GET /admin/house/orders/{orderId}` **新增 `messages` 列表** + `tabCounts.messageCount = 1(定制师需求) + N(留言)`。**抢单池/未抢单也返**(房务在池里浏览即见定制师留言)。
|
||||||
|
- 实测(订单 2068234602970828802,抢单池态):`tabCounts.messageCount=3`、`messages`=[「你好 测试消息」2026-06-23 14:05、「确认单发我一下」14:32]。
|
||||||
|
- `messages[].senderRole` 抢单前留言可能为 `null`(抢单前留言恒来自定制师,前端按「定制师」渲染即可);`senderName` 已是真实姓名。
|
||||||
|
|||||||
@ -46,7 +46,22 @@ DAY2 俄式标准房 ×1 ¥280:candidates = [恩和瓦西里民宿, 呼伦贝
|
|||||||
- 实测(抢单池单 `GET /admin/house/orders/{id}`):`houseStatus=PENDING_CLAIM, houseStatusLabel=待配房, currentStep=1, steps[0].completed=false`。
|
- 实测(抢单池单 `GET /admin/house/orders/{id}`):`houseStatus=PENDING_CLAIM, houseStatusLabel=待配房, currentStep=1, steps[0].completed=false`。
|
||||||
- **内部留言计数**:`tabCounts.messageCount` 由恒 0 改为计入定制师需求(=1)。实测 `messageCount=1`。
|
- **内部留言计数**:`tabCounts.messageCount` 由恒 0 改为计入定制师需求(=1)。实测 `messageCount=1`。
|
||||||
- **H 留言空态对齐(前端)**:既然口径是「定制师需求算 1 条留言」(messageCount=1),内部留言区**别再显「该订单暂无内部留言」**(与 count=1 自相矛盾,且该文案是前端写死,后端不返)。正确:把「定制师需求」当作**第 1 条留言**展示;真正空态只针对**抢单后**房务↔定制师聊天那部分——抢单前聊天关闭,可显「抢单后可与定制师沟通」之类引导而非笼统「暂无内部留言」。
|
- **H 留言空态对齐(前端)**:既然口径是「定制师需求算 1 条留言」(messageCount=1),内部留言区**别再显「该订单暂无内部留言」**(与 count=1 自相矛盾,且该文案是前端写死,后端不返)。正确:把「定制师需求」当作**第 1 条留言**展示;真正空态只针对**抢单后**房务↔定制师聊天那部分——抢单前聊天关闭,可显「抢单后可与定制师沟通」之类引导而非笼统「暂无内部留言」。
|
||||||
- **H2 抢单池「抢单后可与定制师沟通」门控保持不变(与定制师留言不冲突)**:定制师在抢单前可**单向留言**,这些留言由后端压在 pending、**房务抢单那刻自动整批送达抢到的人**(带未读角标 + SSE)。房务在抢单池里未接单、无身份,先不聊是对的;**抢单后**这些留言会出现在房务↔定制师聊天里。聊天气泡的「已读/留言/已送达」显示口径见 **`22_4223` §10**(后端无「已读」字段,抢单前我方消息标「留言」、抢单后标「已送达」,**别写死「已读」**)。
|
- **H2 抢单池「抢单后可与定制师沟通」门控保持不变(与定制师留言不冲突)**:定制师在抢单前可**单向留言**,这些留言由后端压在 pending、**房务抢单那刻自动整批送达抢到的人**(带未读角标 + SSE)。房务在抢单池里未接单、无身份,先不聊是对的;**抢单后**这些留言会出现在房务↔定制师聊天里。聊天气泡的「已读/留言/已送达」显示口径见 **`22_4223` §10/§11**(后端原无「已读」字段,抢单前标「留言」;#4289 已补真已读 `readByPeer`,抢单后 true=「已读」/false=「已送达」,**别写死「已读」**)。
|
||||||
|
|
||||||
|
## 8.「内部留言」框显示定制师留言(✅ #4288 已上线测试服 + API 实测,可接)
|
||||||
|
|
||||||
|
**现状(你 Image #28 反馈「有留言没显示」)**:房务侧订单详情「内部留言」tab 只显「定制师需求」+「抢单后可与定制师沟通」占位,**定制师抢单前发的留言不显示**(你 Image #29 定制师侧已显 2 条留言,房务侧却看不到)。
|
||||||
|
|
||||||
|
**后端已补(实测 `GET /admin/house/orders/{orderId}`)**:详情 **新增顶层 `messages` 列表**(抢单前定制师留言),`tabCounts.messageCount` 由恒 1 改为 **`1(定制师需求) + N(留言)`**。**抢单池/未抢单也返**——房务在池里浏览即见定制师留了什么话。
|
||||||
|
|
||||||
|
**字段契约**:
|
||||||
|
```
|
||||||
|
data.messages: [ { messageId(String雪花), senderName, senderRole, content, sentAt("yyyy-MM-dd HH:mm:ss"), msgType } ]
|
||||||
|
data.tabCounts.messageCount = 1 + messages.length
|
||||||
|
```
|
||||||
|
**实测**(订单 2068234602970828802,抢单池态):`messageCount=3`,`messages`=[「你好 测试消息」14:05、「确认单发我一下」14:32],与定制师侧 Image #29 一致。
|
||||||
|
|
||||||
|
**前端**:「内部留言」框 = 第 1 条「定制师需求」(沿用现有 requirement 渲染)+ 下面按 `messages` 逐条渲染留言(`senderName` + `content` + `sentAt`)。`senderRole` 抢单前留言可能为 null(恒定制师,按「定制师」渲染即可)。抢单后这些留言并入房务↔定制师聊天,气泡已读口径见 `22_4223 §11`。
|
||||||
|
|
||||||
## 6. 操作日志「操作人」别打整串 JSON,渲染 `operator.name`(前端 bug,可立即接)
|
## 6. 操作日志「操作人」别打整串 JSON,渲染 `operator.name`(前端 bug,可立即接)
|
||||||
|
|
||||||
|
|||||||
正在加载...
x
在新工单中引用
屏蔽一个用户