# 二期 v3：订单详情「服务标准」Tab 接口返回真实成品数据 + notices 新增 title 字段

> **服务**: hl-order-service-v3（产品侧 hl-product-service-v2 配合改造，前端无感）
> **端**: 管理后台
> **接口**: `GET /v3/admin/order/{id}/service-standard`（订单详情 - 服务标准 Tab）
> **类型**: ✏️ 修改接口（出参 `notices[]` 新增 `title` 字段 + 接口由恒空改为返回真实成品）
> **日期**: 2026-06-02
> **关联**: Issue #3363 / PR #3364（前序 #3340 建接口、#3353 改只读快照）

---

## 一句话结论

1. 该接口此前对**所有订单恒返 `data: null`**（产品侧没生产服务标准成品）。本次产品侧补上生产端，**新下单的订单**会返回完整服务标准成品（标题 / 简介 / 服务承诺 / 行程 / 退费说明）。
2. 出参 `notices[]`（服务承诺条目）**每条新增 `title` 字段**。

> ⚠️ 仅对**部署之后新创建**的订单生效。部署前的老订单仍返 `null`（其快照未冻入成品）。开发阶段老订单可忽略。

---

## 出参结构（完整，自包含）

`data` 类型 `ServiceStandardVO`，`data` 为 `null` 表示该订单无服务标准成品。

| 字段 | 类型 | 说明 | 可空 |
|---|---|---|---|
| `title` | string | 标题，固定为 `"出团服务标准·" + 产品名`；产品名为空时退化为 `"出团服务标准"` | 否 |
| `subtitle` | string | 副标题 | **本期恒 null** |
| `intro` | string | 服务标准简介 | 是（产品未配服务标准模板时为 null） |
| `notices` | NoticeItem[] | 服务承诺条目（扁平，无分组） | 是（无源时为空数组 `[]`） |
| `itinerary` | DayVO[] | 行程逐天列表 | 是（无行程时空数组） |
| `refundNotes` | RefundNoteGroup[] | 退费说明分组（按行程节点聚合） | 是（无退费说明时空数组） |

### NoticeItem（服务承诺条目）

| 字段 | 类型 | 说明 | 可空 |
|---|---|---|---|
| `title` | string | **本次新增**。条目主文案标题（如「专业司机」） | 是 |
| `content` | string | 正文（如「持有 A1 驾照，8 年以上驾龄」） | 是 |
| `remark` | string | 备注 / 灰色二级说明 | 是 |
| `color` | string | 文案颜色 `#RRGGBB` | 是 |
| `contactName` | string | 联系人 | 是 |
| `phone` | string | 手机号 | 是 |

### DayVO（行程天）

| 字段 | 类型 | 说明 | 可空 |
|---|---|---|---|
| `dayNumber` | integer | 天序号（从 1 起） | 否 |
| `dayTitle` | string | 天标题（如「第一天-接机」） | 是 |
| `remark` | string | 当天备注 | **本期恒 null** |
| `itineraryNode` | ItineraryNode[] | 当天点位列表 | 是 |

### ItineraryNode（行程点位）

| 字段 | 类型 | 说明 | 可空 |
|---|---|---|---|
| `nodeName` | string | 点位名称（如「呼和诺尔草原旅游区」「早餐」） | 否 |
| `description` | string | 点位描述 | 是 |
| `contactName` | string | 联系人 | **本期恒 null** |
| `phone` | string | 手机号 | **本期恒 null** |

### RefundNoteGroup（退费说明分组）

| 字段 | 类型 | 说明 | 可空 |
|---|---|---|---|
| `sourceName` | string | 来源点位名称（取行程节点名） | 否 |
| `intro` | string | 退费说明备注（如「苔藓为赠送项目，不退费」） | 是 |
| `items` | RefundItem[] | 退费明细列表 | 是 |

### RefundItem（退费明细条目）

| 字段 | 类型 | 说明 | 可空 |
|---|---|---|---|
| `title` | string | 展示标题（如「成人未参加」） | 是 |
| `amount` | number | 退费金额（赠送项目为 0） | 是 |
| `unitLabel` | string | 展示文案：`/人` `/团` `/辆` | 是 |
| `settleScope` | string | 结算粒度枚举（见下） | 是 |
| `settleScopeLabel` | string | 结算粒度中文（冻结即定格） | 是 |
| `remark` | string | 备注 | 是 |
| `effectiveFrom` | string(date) | 规则生效起日，`null` = 无限制 | 是 |
| `effectiveTo` | string(date) | 规则生效止日，`null` = 无限制 | 是 |

---

## 枚举 / 数据字典

### settleScope（结算粒度）

| 枚举值 | settleScopeLabel（中文） | 配套 unitLabel |
|---|---|---|
| `PER_PERSON` | 按人 | /人 |
| `PER_TEAM` | 按团 | /团 |
| `PER_VEHICLE` | 按车 | /辆 |

> `settleScopeLabel` 在下单时随快照冻结，定格当时字典中文，资源后改不影响老订单。

---

## 请求示例

```
GET /v3/admin/order/2061762043987247105/service-standard
Authorization: Bearer {adminToken}
```

## 响应示例（真实，测试服 dev-v3 实测）

```json
{
  "code": 200,
  "message": "成功",
  "success": true,
  "data": {
    "title": "出团服务标准·测试核心产品-单档-固定订金",
    "subtitle": null,
    "intro": "全程贴心服务保障",
    "notices": [
      {
        "title": "专业司机",
        "content": "持有A1驾照,8年以上驾龄",
        "remark": "仅限指定时段",
        "color": "#FF6600",
        "contactName": "李师傅",
        "phone": "13800000000"
      }
    ],
    "itinerary": [
      {
        "dayNumber": 1,
        "dayTitle": "第一天-接机",
        "remark": null,
        "itineraryNode": [
          { "nodeName": "海拉尔接机", "description": null, "contactName": null, "phone": null },
          { "nodeName": "早餐", "description": "含(酒店)", "contactName": null, "phone": null }
        ]
      }
    ],
    "refundNotes": [
      {
        "sourceName": "呼和诺尔草原旅游区",
        "intro": "苔藓为赠送项目，不退费",
        "items": [
          {
            "title": "成人未参加", "amount": 44.0, "unitLabel": "/人",
            "settleScope": "PER_PERSON", "settleScopeLabel": "按人",
            "remark": "凭票退", "effectiveFrom": null, "effectiveTo": null
          },
          {
            "title": "整团未到", "amount": 100.0, "unitLabel": "/团",
            "settleScope": "PER_TEAM", "settleScopeLabel": "按团",
            "remark": null, "effectiveFrom": null, "effectiveTo": null
          }
        ]
      }
    ]
  }
}
```

## 响应示例（老订单 / 无成品）

```json
{ "code": 200, "message": "成功", "success": true, "data": null }
```

---

## 业务边界 / 注意事项

- `data: null` 是合法返回，表示该订单无服务标准成品（部署前老订单 / 产品未配服务标准）。
- `intro`、`notices` 来源于产品「服务标准模板」：产品未绑模板时，`intro` 为 `null`、`notices` 为 `[]`，但 `title` / `itinerary` / `refundNotes`（有各自数据源时）仍正常返回。
- `subtitle`、`DayVO.remark`、`ItineraryNode.contactName/phone` 本期固定为 `null`（预留字段）。
- 成品在下单时随产品快照整体冻结，资源 / 产品后续修改不影响已下单订单。

---

## 关联

- Issue: https://git.1814.love:8443/wx/HL/issues/3363
- PR: https://git.1814.love:8443/wx/HL/pulls/3364
- 前序: #3340（建接口）/ #3353（改只读快照）
