# 站内信「订单消息」改为按会话聚合 + 团号标题 + 跳转按钮（前端对接 spec · 管理后台）

- **类型**：前端改造对接说明（**后端零改动**，复用现成接口）
- **端类型**：管理后台（hl-ui）
- **日期**：2026-06-25
- **后端联系人**：王骁（wx）
- **关联**：站内信收件箱混排聊天（#4382 / #4386）的后续优化；INAPP-CHAT v1.0 §1.2 会话列表

> ⚠️ 本文是给前端（mmg）的对接 spec，不是后端变更。后端接口与字段**全部现成**，无需改后端。

---

## 1 背景 / 为什么改

#4382 把聊天混排进站内信「订单消息」是**逐条消息**模型，实测发现它注定数据不全：
- 站内信收件箱本质是「一条消息只在收件方名下存一行」，所以只显示**你收到的那一半**（你自己发的不进你自己收件箱）；
- 释放/转单会把整段对话归属转移，导致旧参与方收件箱里看不到。

结论：聊天应按**会话**展示，不是按单条消息。故站内信「订单消息」改为 **一会话一行**（像聊天软件的会话列表），点开看整段对话。

---

## 2 用现成接口（后端零改动）

### 2.1 会话列表接口

```
GET /admin/message/chat/conversations?bizModule=HOUSE&pageNo=1&pageSize=20
Authorization: Bearer {adminToken}
```

- `bizModule`：`HOUSE`（配房会话）/ `FLEET`（配车会话，车务接入后）；不传=当前员工全部会话。「订单消息」tab 取订单相关会话，可传 `HOUSE`（车务上线后再并 `FLEET`，或不传取全部业务会话）。
- 分页：`pageNo`/`pageSize`；按 `lastMessageAt` 倒序。
- 数据按收件人隔离（每人只看自己参与的会话），无需额外权限处理。

### 2.2 返回字段（ChatConversationRespVO，均已存在）

| 字段 | 类型 | 用途 |
|------|------|------|
| `orderNo` | String | **团号（订单号）→ 放标题**。仅 HOUSE 会话有；order-v3 不可达/非 HOUSE 时为 null |
| `bizId` | Long | **订单ID → 跳转用**（配房页/需求页都用它定位订单） |
| `bizModule` | String | `HOUSE`/`FLEET`，判跳配房页还是配车页 |
| `peerName` | String | 对方姓名（如「王骁」） |
| `peerRole` | String | 对方角色码 `HOUSE`/`CUSTOMIZER`/`FLEET` |
| `peerRoleLabel` | String | 对方角色中文（如「定制师」） |
| `peerOnline` | Boolean | 对方在线态（绿点） |
| `unreadCount` | Integer | 本会话未读数（红点） |
| `lastMessagePreview` | String | 最后一条消息预览（放副标题/内容列） |
| `lastMessageAt` | String | 最后活跃时间 |
| `customerName` | String | 订单联系人（如「王完善」），可拼进标题 |
| `destination`/`tripDays`/`bizStatusLabel`/`progressDesc` | — | 订单维度信息，按需展示 |

---

## 3 前端要做的事

### 3.1 标题加团号
每行标题 = **团号 `orderNo`**（建议再拼客户名 `customerName`），例：`HL20260624092836856 · 王完善`。
- `orderNo` 为 null（无真实订单/order-v3 不可达）时降级显示对方名或会话键，不要显示空白。

### 3.2 行内信息
- 对方：`peerName` + `peerRoleLabel`（+ `peerOnline` 绿点）
- 预览：`lastMessagePreview`
- 未读红点：`unreadCount`（>0 显示）
- 时间：`lastMessageAt`
- 点击行 → 打开该会话线程（用 `conversationKey` 调线程接口 `GET /admin/message/chat/messages`，已有）

### 3.3 跳转按钮（按**你在该会话里的身份**定目标页 —— wx 2026-06-25 修正）

> ⚠️ 修正：**不能按登录账号的全局角色**（如「超级管理员」同时是房务也是定制师，没法定向）。要按 **你在这条会话里是哪一方** = `peerRole` 反推（对方是谁、你就是另一方）。

| 对方角色 `peerRole` | 你在会话里的身份 | 跳转目标 | 路由（按截图，前端核对实际路由） |
|---------|---------|---------|------|
| `HOUSE`（对方是房务） | 你是**定制师** | **订单详情/需求页** | `/order-v2/detail/{bizId}`（见 Image #5） |
| `FLEET`（对方是车务） | 你是**定制师** | **订单详情/需求页** | `/order-v2/detail/{bizId}` |
| `CUSTOMIZER`（对方是定制师）+ `bizModule=HOUSE` | 你是**房务** | **配房页** | `/housekeeper/orders`（带 `bizId`+`requirementId` 自动开配房详情，见 Image #4） |
| `CUSTOMIZER`（对方是定制师）+ `bizModule=FLEET` | 你是**车务** | **配车页** | 车务配车页（带 `bizId`，路由前端定，best-effort） |

判定逻辑（伪码）：
```
if peerRole == 'CUSTOMIZER':       // 对方是定制师 → 我是业务方
    bizModule == 'HOUSE' ? 配房页 : 配车页
else:                              // 对方是房务/车务 → 我是定制师
    订单详情 /order-v2/detail/{bizId}
```

> 跳转只需 `bizId`+`peerRole`+`bizModule`（+ 房务侧 `requirementId` 自动开详情），均在会话列表 VO 里。后端不提供跳转 URL（避免耦合前端路由）。`requirementId` 见 §6 后端增强。

---

## 4 tab 归属建议（前端 IA 自定）

- **订单消息** tab → 本会话列表接口（按会话聚合，团号+跳转）。
- **普通消息** tab → 系统通知：`GET /admin/message/list?messageType=NORMAL`（仅系统通知，不含聊天）。
- **全部** tab → 由前端决定：可「会话列表 + 系统通知」两段合并展示，或仅系统通知。
- 顶部铃铛未读总数仍走 `GET /admin/message/unread-count`（含聊天+通知全部未读）。

> 说明：#4382/#4386 给 `/admin/message/list` 做的「逐条混排聊天 + 派生标题」保留可用（如某处仍要平铺消息流），但「订单消息」tab 推荐改用本会话列表，体验更完整。

---

## 5 注意

1. `orderNo`/订单维度字段是软依赖 order-v3，测试环境用无真实订单的 bizId（如 88888）/订单已被删时为 null，属正常；真实存在的订单会有团号（实证：库凡巧 HL20260625134754752 团号/客户名都正常）。
2. 跳转目标页路由以前端实际为准（本文路由摘自截图 Image #4 `/housekeeper/orders`、Image #5 `/order-v2/detail/{id}`）。
3. 有疑问找后端（王骁/wx）对字段。

---

## 6 后端增强（会话列表 VO 新增字段，订单简介条 + 房务跳转，2026-06-25）

> 需求：① 从站内信会话列表打开对话时，对话顶部「订单简介条」（关于 **产品名** · 客户·人数 · 团号）也要有（此前仅从订单页进才有，见 Image #8）；② 房务跳转要能自动打开配房详情（需 `requirementId`）。
> 后端在 `/admin/message/chat/conversations`（及 internal `by-biz`）的会话 VO 上新增 4 个字段，均由现成 order-v3 enrich 补齐（order_main 已有产品名/人数，hotel_requirement 已有 requirementId），软依赖降级为 null。

| 新增字段 | 类型 | 来源 | 用途 |
|---------|------|------|------|
| `productName` | String | order_main | 订单简介条「产品名」（如 游牧的森林-短途版）；仅 HOUSE 会话有 |
| `adultCount` | Integer | order_main | 简介条人数「N 大」 |
| `childCount` | Integer | order_main | 简介条人数「N 小」（前端按需拼「2大1小」） |
| `requirementId` | Long | hotel_requirement | 房务跳转配房页时定位/自动打开该订单配房详情（无房务需求时 null） |

- 订单简介条 = `productName` + `customerName`（已有）+ `adultCount`/`childCount` + `orderNo`（已有，团号）。打开会话时前端用会话行这几个字段渲染顶部简介条，无需再查订单页。
- 房务跳转：`/housekeeper/orders?orderId={bizId}&requirementId={requirementId}` 前端据此自动开配房详情（之前只 orderId 落到列表页）。
- **✅ 已上线测试服（PR #4394，order-v3 + user-service 已部署）**。实测真实订单（库凡巧）会话返回 `productName=游牧的森林-短途版 / adultCount=2 / childCount=0 / requirementId=2070028178415337474 / orderNo=HL20260625134754752`，订单已删的会话这些字段为 null（软依赖降级）。前端可直接取用渲染订单简介条 + 房务跳转。
