# 订单详情「记录 Tab」时间线接口 13 字段重构 — 修改接口 — 管理后台

> 变更类型：⚠️ 破坏性变更（字段删除 / 改名 / 新增）
> 端类型：管理后台
> 日期：2026-06-08
> 服务：hl-order-service-v3

---

## 1. 接口背景

订单详情页「记录」Tab 懒加载接口，返回订单状态流转与操作时间线节点列表。

本次对返回值 `LogTimelineVO` 进行全面重构：旧版 6 字段语义模糊、状态值为英文裸枚举、操作人字段名拼写不一；新版扩展为 13 字段，状态标签全部中文化，引入 `changeType` 区分两类节点样式，新增 `id` 字段满足 list key 需要。

**前端必须同步迁移**。旧字段（`action`、`operator`、`fromStatus`、`toStatus`）已从响应体移除或改名，直接使用旧字段的代码将取不到值。

---

## 2. 变更清单

| # | 变更类型 | 旧字段 | 新字段 | 说明 |
|---|---|---|---|---|
| 1 | ⚠️ 删除 | `action` | — | 已拆分为 `title`（事件名）+ `content`（内容描述），原字段不再返回 |
| 2 | ⚠️ 改名 | `operator` | `operatorName` | 操作人姓名，仅字段名变更，值语义不变 |
| 3 | ⚠️ 改名+中文化 | `fromStatus` | `fromStatusLabel` | 状态来源，英文枚举（"PENDING_PAY"）→ 中文标签（"待支付"） |
| 4 | ⚠️ 改名+中文化 | `toStatus` | `toStatusLabel` | 状态目标，英文枚举（"PROCESSING"）→ 中文标签（"定制中"） |
| 5 | 保留 | `occurredAt` | `occurredAt` | 事件发生时间，无变化 |
| 6 | 保留 | `amount` | `amount` | 金额，无变化 |
| 7 | ✨ 新增 | — | `id` | 节点唯一 ID（String 雪花），list key 用此字段 |
| 8 | ✨ 新增 | — | `title` | 中文事件名（原 action 前半段，如支付订金） |
| 9 | ✨ 新增 | — | `content` | 事件内容文本（"¥500" / "拉萨 瑞吉酒店" / "2 位出行人"），可空 |
| 10 | ✨ 新增 | — | `amountKind` | 金额类型枚举（DEPOSIT/FULL/REFUND/RETURN/SETTLEMENT），可空 |
| 11 | ✨ 新增 | — | `relatedType` | 关联单类型（PAYMENT/REFUND/SETTLEMENT/CONTRACT），可空 |
| 12 | ✨ 新增 | — | `relatedId` | 关联单 ID（String），与 relatedType 配对，可空 |
| 13 | ✨ 新增 | — | `eventType` | 英文事件码（机器字段，前端做图标判断，**不直接展示给用户**） |
| 14 | ✨ 新增 | — | `changeType` | 节点类型（STATUS / DATA），前端据此区分节点渲染样式 |

---

## 3. 接口详情

| 项目 | 值 |
|---|---|
| 请求方法 | GET |
| 路径 | /v3/admin/order/{id}/status-log |
| 接口名 | 订单详情 Tab 时间线 |
| 认证 | 需要 Bearer Token（管理后台 JWT） |
| 幂等性 | 查询接口，天然幂等 |
| 限流 | 无特殊限流，跟随全局网关默认限流 |
| 加载时机 | 懒加载（切换到记录 Tab 时触发） |

---

## 4. 接口入参

### 4.1 路径参数

| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| id | Long | 是 | 订单 ID |

### 4.2 请求体

无请求体（GET 请求）。

---

## 5. 出参字段

**返回类型**：Result<List<LogTimelineVO>>

| 字段名 | 类型 | 可空 | 说明 |
|---|---|---|---|
| id | String | 否 | 节点唯一 ID（雪花 String，防 JS 精度丢失），list key 用此字段 |
| occurredAt | String (ISO 8601) | 否 | 事件发生时间，如 2026-06-01T14:30:00 |
| title | String | 否 | 中文事件名，如支付订金、配房完成、出行前取消 |
| content | String | 是 | 事件内容描述，如 Y500、拉萨瑞吉酒店/林芝工布庄园希尔顿、2位出行人；DATA 节点通常有值，STATUS 节点可空 |
| operatorName | String | 否 | 操作人姓名，如李雯；系统自动触发时为系统 |
| fromStatusLabel | String | 是 | 状态流转来源（中文），如待支付；仅 changeType=STATUS 节点有值，DATA 节点为 null |
| toStatusLabel | String | 是 | 状态流转目标（中文），如定制中；仅 changeType=STATUS 节点有值，DATA 节点为 null |
| amount | BigDecimal | 是 | 金额，如 500.00；无金额时为 null |
| amountKind | String | 是 | 金额类型枚举值，见枚举节；无金额时为 null |
| relatedType | String | 是 | 关联单类型（PAYMENT/REFUND/SETTLEMENT/CONTRACT），可空 |
| relatedId | String | 是 | 关联单 ID（String），与 relatedType 配对；可空 |
| eventType | String | 否 | 英文事件码，前端做图标/样式判断用，不直接展示给用户 |
| changeType | String | 否 | 节点类型（STATUS / DATA），前端据此区分节点渲染样式 |

---

## 6. 枚举 / 数据字典

### changeType — 节点类型

| 枚举值 | 含义 | 前端渲染说明 |
|---|---|---|
| STATUS | 状态流转节点 | 展示 fromStatusLabel → toStatusLabel 箭头；amount / amountKind 可能有值 |
| DATA | 状态内数据变更节点 | 无状态箭头；fromStatusLabel / toStatusLabel 为 null；展示 title + content |

### amountKind — 金额类型

| 枚举值 | 含义 |
|---|---|
| DEPOSIT | 订金 |
| FULL | 全款 |
| REFUND | 退款金额 |
| RETURN | 退还金额 |
| SETTLEMENT | 结算金额 |

### relatedType — 关联单类型

| 枚举值 | 含义 |
|---|---|
| PAYMENT | 关联支付单 |
| REFUND | 关联退款单 |
| SETTLEMENT | 关联结算单 |
| CONTRACT | 关联合同单 |

### title 取值示例（中文，后端生成，不限于此列表）

创建订单 / 支付订金 / 支付全款 / 确认订单 / 开始出行 / 返团完成 / 出行前取消 / 出行中终止 / 超时自动取消 / 流程推进 / 补全出行信息 / 新增出行人 / 删除出行人 / 批量导入出行人 / 订单信息调整 / 支付尾款 / 配房完成 / 配导游完成 / 配摄影完成 / 配车完成 / 退款到账 / 核单提交 / 结算确认

---

## 7. 错误码

| 错误码 | HTTP 状态 | 说明 | 前端处理建议 |
|---|---|---|---|
| 200 | 200 | 成功，data 为节点列表（无记录时为空数组 []） | 正常渲染，空数组时展示空状态占位 |
| ORDER_NOT_FOUND（4040xxx） | 200 | 订单不存在 | 提示订单不存在 |
| 401 | 401 | Token 无效或过期 | 跳转登录 |

---

## 8. 示例

### 8.1 典型成功 — 状态流转节点（支付订金）

**请求**

```
GET /v3/admin/order/1798000000000000001/status-log
Authorization: Bearer <token>
```

**响应**

```json
{
  "code": 200,
  "msg": "success",
  "data": [
    {
      "id": "1798000000000000099",
      "occurredAt": "2026-06-01T14:30:00",
      "title": "支付订金",
      "content": "¥500",
      "operatorName": "李雯",
      "fromStatusLabel": "待支付",
      "toStatusLabel": "定制中",
      "amount": 500.00,
      "amountKind": "DEPOSIT",
      "relatedType": "PAYMENT",
      "relatedId": "1798000000000000098",
      "eventType": "DEPOSIT_PAID",
      "changeType": "STATUS"
    }
  ]
}
```

### 8.2 边界情况 — 数据变更节点（配房完成，fromStatusLabel / toStatusLabel 为 null）

```json
{
  "code": 200,
  "msg": "success",
  "data": [
    {
      "id": "1798000000000000103",
      "occurredAt": "2026-06-02T09:15:00",
      "title": "配房完成",
      "content": "拉萨 瑞吉度假酒店 / 林芝 工布庄园希尔顿",
      "operatorName": "系统",
      "fromStatusLabel": null,
      "toStatusLabel": null,
      "amount": null,
      "amountKind": null,
      "relatedType": null,
      "relatedId": null,
      "eventType": "ROOM_ASSIGNED",
      "changeType": "DATA"
    }
  ]
}
```

> changeType=DATA 节点：fromStatusLabel / toStatusLabel 恒为 null，前端不渲染状态箭头。

### 8.3 业务失败 — 订单不存在

**请求**

```
GET /v3/admin/order/9999999999999999999/status-log
Authorization: Bearer <token>
```

**响应**

```json
{
  "code": 4040001,
  "msg": "订单不存在",
  "data": null
}
```

---

## 9. 业务边界

**适用场景**

- 订单详情页「记录」Tab 懒加载，展示完整时间线。
- 支持所有订单状态（待支付 / 定制中 / 已确认 / 出行中 / 已完成 / 已取消）查看记录。

**不适用场景**

- 不适用于小程序端（该接口为 /v3/admin/*，仅管理后台消费）。
- 不适用于批量查询（接口只支持单订单）。

**特殊边界**

- 新创建订单若尚无任何操作记录，返回 data: []（空数组），前端 Tab 需有空状态占位。
- eventType 为机器字段，后端随业务迭代可能新增新值；前端图标映射表需留 fallback 分支（未知 eventType 显示默认图标），不能写死枚举列表。
- DATA 类型节点的 content 在极少数情况下可能为 null，前端展示时须做空判断。
- amount 字段仅在有金额关联时有值；DATA 类节点（如配房完成）的 amount 恒为 null。

---

## 10. 修改前后对比

### 字段级对比

| 旧字段名 | 旧类型 | 旧值示例 | 新字段名 | 新类型 | 新值示例 | 变更类型 |
|---|---|---|---|---|---|---|
| action | String | "PAY: 支付成功，¥500" | 已删除（拆分） | — | title=支付订金 content=¥500 | ⚠️ 删除 |
| operator | String | "李雯" | operatorName | String | "李雯" | ⚠️ 改名 |
| fromStatus | String | "PENDING_PAY" | fromStatusLabel | String | "待支付" | ⚠️ 改名+语义变 |
| toStatus | String | "PROCESSING" | toStatusLabel | String | "定制中" | ⚠️ 改名+语义变 |
| occurredAt | LocalDateTime | "2026-06-01T14:30:00" | occurredAt | LocalDateTime | 不变 | 保留 |
| amount | BigDecimal | 500.00 | amount | BigDecimal | 不变 | 保留 |
| — | — | — | id | String | "1798000000000000099" | ✨ 新增 |
| — | — | — | title | String | "支付订金" | ✨ 新增 |
| — | — | — | content | String | "¥500" | ✨ 新增 |
| — | — | — | amountKind | String | "DEPOSIT" | ✨ 新增 |
| — | — | — | relatedType | String | "PAYMENT" | ✨ 新增 |
| — | — | — | relatedId | String | "1798000000000000098" | ✨ 新增 |
| — | — | — | eventType | String | "DEPOSIT_PAID" | ✨ 新增 |
| — | — | — | changeType | String | "STATUS" | ✨ 新增 |

### 行为级对比

| 行为 | 旧版 | 新版 |
|---|---|---|
| 状态标签语言 | 英文枚举如 PENDING_PAY，前端需自行映射为中文 | 中文标签如待支付，前端直接展示，无需映射 |
| 事件描述 | 单个 action 字段拼接如 PAY: 支付成功，¥500，前端需解析 | title（名称）+ content（详情）分离，直接使用 |
| list key | 无唯一标识，只能用数组 index | id 字段（雪花 String），可作稳定 list key |
| 节点类型区分 | 无，前端无法区分状态流转节点与数据变更节点 | changeType（STATUS/DATA），前端可差异化渲染 |
| 金额关联信息 | 仅 amount | amount + amountKind + relatedType + relatedId |

---

## 11. 影响评估 / 迁移

### 破坏兼容

此次变更为**破坏性变更**，以下旧字段已从响应体移除或改名：

| 旧字段 | 状态 | 前端必须修改的地方 |
|---|---|---|
| action | 已删除 | 展示事件名的地方改用 title；展示内容的地方改用 content（可空） |
| operator | 已改名为 operatorName | 所有读取 operator 的地方改为 operatorName |
| fromStatus | 已改名为 fromStatusLabel | 所有读取 fromStatus 的地方改为 fromStatusLabel；值已中文化，无需再做枚举映射 |
| toStatus | 已改名为 toStatusLabel | 所有读取 toStatus 的地方改为 toStatusLabel；值已中文化，无需再做枚举映射 |

### 前端同步迁移清单

1. **list key**：将用 index 作为 list key 的地方改为使用 id 字段。
2. **事件名展示**：action → 改用 title（直接字符串，后端已生成中文）。
3. **事件内容展示**：原从 action 拼串截取的内容 → 改用 content（可空，展示前做空判断）。
4. **操作人**：operator → operatorName（字段名替换，值语义不变）。
5. **状态标签**：fromStatus / toStatus → fromStatusLabel / toStatusLabel；新值已为中文，删除前端原有枚举映射表逻辑。
6. **节点样式分支**：新增 changeType 读取逻辑：
   - changeType === STATUS：渲染状态流转箭头（fromStatusLabel → toStatusLabel）
   - changeType === DATA：仅渲染 title + content，不渲染状态标签
7. **图标映射**：新增对 eventType 的图标选取逻辑；未知 eventType 值使用默认图标（前端不要写死枚举，需留 fallback）。
8. **金额区块**：可利用 amountKind 细化金额标签（订金/全款/退款等），relatedType + relatedId 可用于跳转关联单详情。

### 前端同步上线

接口破坏兼容，后端与前端**需协调同步上线**，避免新后端 + 旧前端代码同时在线导致字段取不到值。

### 回滚方案

若需回滚，后端恢复旧版 LogTimelineVO（6 字段），前端同步回滚字段引用。接口签名变化不向下兼容，必须同步部署。

---

## 12. 注意事项

1. **fromStatusLabel / toStatusLabel 在 DATA 节点为 null**：前端读取这两个字段前必须判断 changeType === STATUS，避免渲染 null。
2. **id 为 String 类型**：雪花 ID 超出 JS Number 精度范围，后端已序列化为字符串。前端直接用字符串处理，不要转 Number，否则精度丢失导致 key 冲突。
3. **eventType 不展示给用户**：该字段为机器码，仅用于图标/样式判断逻辑，不应直接渲染在 UI 上。
4. **content 可空**：部分节点无内容描述，展示时必须做空判断，避免显示 null 或 undefined。
5. **空列表处理**：新订单无操作记录时返回 data: []，记录 Tab 需有空状态占位（如暂无记录）。
6. **eventType 可能扩展**：随业务迭代后端可能新增 eventType 值，前端图标映射表必须留 fallback 分支，不能写死枚举列表。
7. **删除原有枚举映射**：旧版前端可能维护了 fromStatus / toStatus 英文到中文映射表，新版状态标签已由后端生成中文，该映射表可以删除，避免冗余维护。

---

## 13. 关联 / 联系人

| 项目 | 信息 |
|---|---|
| 父 Issue | https://git.1814.love:8443/wx/HL/issues/3561 |
| PR | https://git.1814.love:8443/wx/HL/pulls/3574 |
| Merge Commit | https://git.1814.love:8443/wx/HL/commit/1f93d534fe2073e56f236d6558ba6165706602b5 |
| 后端负责人 | yst |
