# 房务抢单后，定制师「抢单前发的联系房务消息」红点有、站内信「全部」tab 看不到（前端已收到却没渲染）

> 模块：管理后台 · 站内信/我的消息「全部」tab + 房务抢单
> 类型：**前端处理**（后端已逐项核实正确，无需改后端）
> 日期：2026-06-30
> 反馈来源：wx 手动测试（含浏览器 Network 抓包）
> 说明：**本文修正同目录早前版本的根因**——早前写「前端收 CHAT SSE 没刷列表、红点更新了列表没更新」。经浏览器 Network 抓包实证：**列表接口已把该消息正确返回给浏览器（就在 `records[0]`），前端拿到却没渲染**，根因不是「没刷新」而是「全部 tab 渲染时把这条最新订单消息过滤/去重掉了」。请以本文为准。

## 现象
定制师在**房务还没抢单时**发「联系房务」消息；房务（admin=1001）抢单后：
- 顶部铃铛红点 **+1（未读=1）**✅；
- 但「我的消息 → 全部」列表里**看不到那条新消息**，列表「共 10 条」，缺了最新这条；
- **手动整页刷新后仍然看不到**（排除「列表没刷新」的时序问题）。

## 关键实证（浏览器 Network 抓包）
「全部」tab 拉的 `GET /admin/message/list?pageSize=20&pageNo=1` 响应里，**`records[0]` 就是这条缺失的消息**，字段齐全可渲染：

```json
{
  "messageId": "2071792080350236674",
  "categoryCode": null,
  "title": "HL20260630103610215 · 吕思远",   // 已 enrich 成「团号 · 联系人」
  "content": "77721",
  "link": null,
  "bizId": "2071784830965620737",
  "bizType": "HOUSE",
  "isRead": 0,
  "createTime": 1782788699000,               // 2026-06-30 11:04，本页最新一条
  "messageType": "ORDER",
  "messageTypeLabel": "订单消息",
  "kind": "CHAT",
  "senderName": "王骁",
  "conversationKey": "HOUSE:2071784830965620737"
}
```

即：**后端把这条订单消息作为本页第一条（最新）正确返回了**，但页面「共 10 条」、左侧列表里没有它（列表渲染的最旧 CHAT 行是 06-28 的，更早的 06-19 都在，唯独这条 06-30 最新的被丢）。

## 后端现状（已逐项核实正确，勿改后端）
1. **消息归属迁移**：抢单/转单后 order-v3 经 Feign 调 user-service `bindHouseClaimer`，把抢单前 pending（receiver=0）消息改判给真实抢单房务（`admin_message.admin_id` → claimer）。实测该行已落到 admin=1001 名下（kind=CHAT / messageType=ORDER / is_read=0）。
2. **会话成员迁移**：同一事务里同步「补/对齐房务成员行」（`admin_conversation_member`），claimer 成为该会话有效成员——所以这条会话在**收件箱 `list`** 和**会话列表 `conversations`** 两个端点对 claimer 都可见，不是「孤儿消息」。
3. **分页 total 正确**：`list` 走 MyBatis-Plus 分页，`total` 来自同 wrapper 的 COUNT；列表装配只对 CHAT 行批量 enrich 标题（团号·联系人），**不增删行**。故响应 `total` 与 `records` 一致（本页含这条共 N 条），后端没有少返。
4. **SSE 已发**：迁移真有新消息送达时发 `type=CHAT` 信令（Redis `admin-notify`），携 `unreadCount / conversationKey / senderName / preview`，前端红点已据此 +1（与现象一致）。

→ **后端数据完整一致**：消息行 + 会话成员行都迁移到位、total 正确、SSE 已发、`list` 已把该消息作为 `records[0]` 返回给浏览器。

## 根因（前端：收到了却没渲染）
前端「全部」tab 在渲染 `list` 响应时，把这条**刚迁移来的最新 CHAT（订单消息）行过滤/去重掉了**。可能方向（请前端自查）：
- 「全部」列表对 `kind=CHAT` 行**按 `conversationKey` 去重**（一会话一行），而此会话 `HOUSE:2071784830965620737` 与已渲染的某历史行（同一会话/同一对端「王骁」）判为重复，保留了旧行、丢了这条最新行；
- 或把 `list` 里的 CHAT 行与 `conversations`（会话列表）做合并/抵扣，导致这条新会话消息在「全部」里被会话列表项「吸收」而不在消息流里单独显示；
- 或对 `categoryCode=null` / `link=null` 的 CHAT 行有渲染守卫，把它跳过（注意：正常订单消息本就 `categoryCode=null`、`link=null`，不应据此跳过）。

## 【前端处理】
请检查「我的消息 → 全部」tab 对 `GET /admin/message/list` 响应的渲染逻辑，**确保 `kind=CHAT`（订单消息）行——尤其房务抢单后刚迁移来的最新会话消息（如 `records[0]`）——不被去重/过滤掉**：
- 列表应忠实渲染 `records` 全量（含 `messageType=ORDER` 的 CHAT 行），若要按会话去重也应**保留每个会话的最新一条**（而非保留旧行丢新行）；
- 不要因 `categoryCode=null` / `link=null` 跳过 CHAT 行（订单消息正常就是这俩为 null）；
- 排查重点：复现「房务抢单 → 全部 tab 整页刷新」，对照 Network 响应里 `records[0]` 是否被渲染。后端已确认该条在响应中，前端只需把它渲染出来即可。

> 补充：定制师抢单前发的消息属「订单消息」（kind=CHAT / messageType=ORDER / bizType=HOUSE），抢单后归属迁移给抢单房务即应出现在其「我的消息 → 全部 / 订单消息」中——这是后端既有且已验证的行为，前端把这条已在响应中的记录正确渲染出来即可。
