diff --git a/changelogs-v2/2026-06/24_4330_4332_释放回池冻结旧房务会话+消息转留言池真生效_管理后台.md b/changelogs-v2/2026-06/24_4330_4332_释放回池冻结旧房务会话+消息转留言池真生效_管理后台.md new file mode 100644 index 0000000..09fab75 --- /dev/null +++ b/changelogs-v2/2026-06/24_4330_4332_释放回池冻结旧房务会话+消息转留言池真生效_管理后台.md @@ -0,0 +1,37 @@ +# 房务释放回池:冻结旧房务会话 + 旧房务消息整段转「留言池」(链路修通真生效) + +> 变更类型:🔧 修复(后端,前端按下方「留言态展示」配合) +> 端类型:管理后台(房务管家·订单详情聊天 / 定制师侧「待接单房务」会话) +> 日期:2026-06-24 | 工单:#4329 #4331 | PR:#4330 #4332 | 服务:hl-user-service(双实例已部署 health UP,**测试服 DB+API ground-truth 实测全通过**) + +--- + +## 背景 +房务订单聊天=方案A(一单一会话 `HOUSE:{orderId}`,房务轮换)。此前「释放回抢单池」后两个 bug: +1. 定制师还能跟**旧房务**继续聊(旧房务会话没冻结); +2. 上次聊天内容没转成「留言」(下个房务抢单看不到对话连续性)。 + +根因有两层: +- **#4331(根因)**:释放事件经 Feign 调 user 绑定时传 `houseAdminId=null`,但 user 端入参 VO 该字段有 `@NotNull` → `@Valid` 直接 400 打回 → 释放绑定逻辑**从未真正执行**(软依赖被 fallback 静默吞掉,主流程照常成功,潜伏数周)。去掉该 `@NotNull` 后链路才通。 +- **#4330(逻辑)**:释放绑定逻辑本身补全——归档旧房务成员行 + 旧房务名下消息整段转留言池。 + +## 后端行为变化(前端一般无需改) +释放回抢单池后: +- **旧房务**:会话成员行 `status→ARCHIVED`,脱离该会话——其会话列表不再显示本会话、且**不能再发消息**(发消息返业务码「无权访问该会话」)。 +- **该会话全部聊天消息**(含旧房务已读的)整段改判回「留言池」(无房务接收态)。 +- **定制师**:其「联系房务」回退「待接单房务」态(peer 占位),后续发的消息进留言池。 +- **下个房务抢单**:留言池消息整段转发给新房务(计入未读 + 转为正常聊天)。 +- 同一房务**重新抢回**该单:归档行自动复活(`status→ACTIVE`),聊天恢复。 + +## 前端「留言态」展示配合(重点) +释放回池后,定制师打开会话标题显示「待接单房务」,**该会话历史消息整体呈现为「留言」态**——这是预期效果(无房务接单期间的消息都是留言,等下个房务抢单转为实时聊天): +- 定制师侧:会话仍可打开、可继续发(进留言池),消息标「留言」属正常,**不是 bug**。 +- 房务侧(未抢单):订单详情显示「抢单后可与定制师实时沟通」占位(前端已去掉旧「内部留言」入口,符合「只留聊天」要求)。 +- 旧房务侧:释放后该会话从其会话列表消失(已归档),符合预期。 + +## 验证说明(如实·ground-truth) +✅ 测试服 DB + API 实测全通过: +- 释放后旧房务(admin)成员行 `status=ARCHIVED`、其会话列表无此会话; +- 旧房务释放后发消息被拒(「无权访问该会话」); +- 该单留言池消息齐全(定制师留言 admin_id=0 就绪,下个房务抢单可转发); +- 同房务重抢→成员行复活 `ACTIVE`、聊天恢复。