# 订单详情「合同/保险」Tab 出参终态（管理后台）

- 端类型：管理后台
- 变更类型：修改接口（出参丰富 + 保险结构重构，**含破坏性**）
- 关联 Issue：#4390 #4403　PR：#4391 #4399 #4406
- 日期：2026-06-25

---

## ① 接口背景

订单详情「合同/保险」懒加载 Tab `GET /v3/admin/order/{id}/contract-insurance` 原返回过于单薄（时间线仅 eventType+occurredAt，缺方案名/签署人/产品名/投保人数等），且保险按"代表保单"折叠，多保单（多段方案）丢失各张信息。本次经 3 个 PR 改造到**终态**，一次性说明最终出参。

> **保险一单多保是设计如此**：一个保险方案含多个分段（segment），自动投保逐段投保，每段建一张保单 → 一单可能 N 张并存。故保险改为 **policies 数组**，每张独立展示。合同仍单对象（一单一合同）。

---

## ② 变更清单

| 方法 | 路径 | 变更 |
|---|---|---|
| GET | `/v3/admin/order/{id}/contract-insurance` | contract 顶层补字段 + 富时间线；**insurance 结构重构为 policies 数组** |

统一响应 `Result<T>`：`{ code, message, data, success }`，`code=200` 成功。`data = { contract, insurance }`。

**破坏性提示**：insurance 节点**删除**旧顶层字段 `insurancePolicyNo` / `insurancePremium` / 顶层 `events`，改为聚合层 + `policies[]`（events 移入每张 policy）。前端涉及保险展示**必须改按 policies 数组渲染**。

---

## ③ 出参结构（终态）

```jsonc
"data": {
  "contract": {
    "contractStatus": "SIGNED",          // 合同状态(走 order_main 镜像)GENERATING/GENERATED/SIGNED/VOIDED/RESIGNING；无合同 null
    "contractSchemeName": "标准跟团方案 v3.2", // 合同方案名
    "signerName": "张三",                 // 签署人(isSigner 出行人，无则联系人)
    "signMethod": "电子签",               // 签署方式
    "contractSignedAt": "2026-04-18 17:10:00", // 签约时间(镜像)
    "contractFileUrl": "https://oss.../x.pdf", // 合同文件(镜像)
    "events": [ /* 富时间线，固定5步，见⑤ */ ]
  },
  "insurance": {
    // —— 聚合层(订单维度) ——
    "insuranceStatus": "INSURED",        // 聚合状态(走镜像)INSURING/INSURED/CANCELLED/FAILED；无保险 null
    "insuranceStatusName": "已出单",      // 聚合状态中文
    "totalPremium": "468.00",            // 所有 INSURED 保单保费之和(镜像)
    "policyCount": 2,                    // 保单张数
    // —— 逐张保单 ——
    "policies": [
      {
        "insuranceOrderId": "92000...",
        "productName": "安联境内旅行险·尊享版",
        "policyNo": "AL-DEMO-00001",
        "premium": "384.00",
        "insuredCount": 4,
        "coverAmount": "意外身故10万;医疗30万",
        "policyHolderName": "张三",
        "status": "INSURED",             // 单张状态
        "statusName": "已出单",
        "events": [ /* 该张自己的富时间线，固定5步，见⑤ */ ]
      }
      // ...多段方案有多张；单段长度=1；无保险 policies=[]
    ]
  }
}
```

---

## ④ 入参

无变化（仅 path `id`）。

---

## ⑤ 时间线节点（events）字段

合同/保险 events 均为**固定步骤模板**（合同 5 步、保险 5 步），节点结构：

| 字段 | 类型 | 说明 |
|---|---|---|
| stepCode | string | 步骤码（合同 GENERATE/TEMPLATE/PUSH_SIGN/SIGN/ARCHIVE；保险 TRIGGER/UNDERWRITE/AUDIT/ISSUE/ARCHIVE）|
| eventType | string | 兼容旧字段，值同 stepCode（前端用 stepCode 即可）|
| eventName | string | 步骤中文名（触发生成合同 / 客户电子签 …）|
| actorType | string | 操作方类型 `SYSTEM` / `THIRD_PARTY` / `CUSTOMER` |
| actorTypeName | string | 操作方中文名 `系统` / `第三方` / `客户` |
| actorLabel | string | 来源标签（订单控制台 / 法大大 e-Sign / 安联保险 / 客户本人(电子签)）|
| statusLabel | string | 步骤状态 `已完成` / `进行中` / `待处理`（按当前合同/保单状态派生）|
| description | string | 描述（插值真实数据，如"模板 标准跟团方案 v3.2"/"保费 ¥384 已扣"）|
| occurredAt | datetime | 发生时间（里程碑日志填充；该步对应里程碑未发生 → null）|

**合同 5 步**：触发生成合同(系统) → 生成合同模板(第三方) → 推送签署链接(第三方) → 客户电子签(**客户**) → 回执入库(系统)。
**保险 5 步**：触发出保(系统) → 调用承保接口(系统) → 核保·扣保费(第三方) → 出具电子保单(第三方) → 保单入库·推送客户(系统)。

---

## ⑥ 枚举 / 数据字典

- 合同状态 contractStatus：GENERATED 生成 / SIGNED 已签 / VOIDED 已作废 / UPLOADED 已上传回执 / RESIGNING 重签中
- 保险状态(聚合 insuranceStatus / 单张 status)：INSURING 出单中 / INSURED 已出单 / CANCELLED 已取消 / FAILED 出单失败
- actorType：SYSTEM 系统 / THIRD_PARTY 第三方 / CUSTOMER 客户
- statusLabel：已完成 / 进行中 / 待处理

---

## ⑦ 错误码

无（查询接口正常返 200）。

---

## ⑧ 示例

### 多保单（一单 2 张）保险节选
```json
{ "insurance": {
  "insuranceStatus":"INSURED","insuranceStatusName":"已出单","totalPremium":"468.00","policyCount":2,
  "policies":[
    { "policyNo":"AL-DEMO-00001","productName":"安联境内旅行险·尊享版","premium":"384.00","insuredCount":4,
      "status":"INSURED","statusName":"已出单",
      "events":[
        {"stepCode":"TRIGGER","eventName":"触发出保","actorType":"SYSTEM","actorTypeName":"系统","actorLabel":"订单控制台","statusLabel":"已完成","description":"按 4 位出行人投保","occurredAt":"2026-04-18 09:30:00"},
        {"stepCode":"AUDIT","eventName":"核保·扣保费","actorType":"THIRD_PARTY","actorTypeName":"第三方","actorLabel":"安联保险","statusLabel":"已完成","description":"保费 ¥384 已扣","occurredAt":"2026-04-18 09:30:00"},
        {"stepCode":"ISSUE","eventName":"出具电子保单","actorType":"THIRD_PARTY","actorTypeName":"第三方","actorLabel":"安联保险","statusLabel":"已完成","description":"保单号 AL-DEMO-00001","occurredAt":"2026-04-18 12:00:00"}
      ] },
    { "policyNo":"AL-DEMO-00002","productName":"附加意外险","premium":"84.00","status":"INSURED","statusName":"已出单","events":[ /* 该张自己5步 */ ] }
  ] } }
```

### 合同时间线节选
```json
{ "stepCode":"SIGN","eventName":"客户电子签","actorType":"CUSTOMER","actorTypeName":"客户","actorLabel":"客户本人(电子签)","statusLabel":"已完成","description":"法大大 e-Sign 回传签署回执","occurredAt":"2026-04-18 17:10:00" }
```

### 无合同/无保险
`contract` 顶层字段 null + `events:[]`；`insurance` 聚合字段 null + `policies:[]`。

---

## ⑨ 业务边界

- events 是后端按固定流程模板合成（非逐条原始日志），时间用真实里程碑填充；中间子步（生成模板/推送链接）时间≈所属里程碑时间。
- 单段方案 policies 长度=1；前端统一按数组渲染。
- 顶层 totalPremium = 所有 INSURED 保单保费之和；各张 premium 为单张保费。
- statusLabel 按当前状态派生：已到达里程碑=已完成，当前=进行中，未到=待处理（occurredAt=null）。

---

## ⑩ 修改前后对比

| | 修改前 | 修改后 |
|---|---|---|
| 合同顶层 | 仅 contractStatus/signedAt/fileUrl | + contractSchemeName/signerName/signMethod |
| 时间线节点 | eventType + occurredAt | + stepCode/eventName/actorType/actorTypeName/actorLabel/statusLabel/description |
| 保险结构 | 单对象（代表保单折叠）：insurancePolicyNo/insurancePremium/productName/coverAmount/insuredCount/events 在顶层 | **聚合层(insuranceStatus/insuranceStatusName/totalPremium/policyCount) + policies 数组**（每张独立 + 各自 events）|
| 保险多保单 | 只显示一张，丢其余 | 每张独立展示 |

---

## ⑪ 影响评估 / 回滚

- **破坏性（保险）**：保险旧顶层 `insurancePolicyNo`/`insurancePremium`/`events` **已删**，改 `policies[]`。前端保险展示**必须**改按数组渲染（取 `insurance.policies[*]`），时间线从 `insurance.events` 改 `insurance.policies[i].events`。
- 合同为**非破坏新增**（顶层补字段 + 时间线节点补字段，旧字段保留）。
- 前端尚未对接本 Tab，按此终态一次对接即可。
- 回滚：后端回滚 PR #4391 #4399 #4406。

---

## ⑫ 注意事项

- 金额（totalPremium/premium）+ Long ID（insuranceOrderId）均**字符串化**返回（防 JS 精度）。
- 时间线节点用 `stepCode` 不用 `eventType`（后者仅兼容）。
- policyHolderName/signerName 为投保人/签署人真实姓名（管理后台财务/客服核对保单用）。

---

## ⑬ 关联 / 联系人

- Issue：https://git.1814.love:8443/wx/HL/issues/4390 ・ https://git.1814.love:8443/wx/HL/issues/4403
- PR：https://git.1814.love:8443/wx/HL/pulls/4391 ・ https://git.1814.love:8443/wx/HL/pulls/4399 ・ https://git.1814.love:8443/wx/HL/pulls/4406
- 后端负责人：腰苏图
- 已部署测试服并网关实调验证通过（合同 5 步富时间线 + 保险多保单 policies 数组各张独立时间线均生效）。
