# 二期 v3：产品「服务标准」模块 — 模板总则(分组+条目) + 每日特别提醒 + 订单 Tab 富展示

> **服务**: hl-product-service-v2 + hl-order-service-v3
> **PR**: #3157（+ hotfix #3163）
> **Issue**: #3147
> **日期**: 2026-05-28
> **影响**: 🟢 新增能力，全部向后兼容（旧订单 Tab 自动降级，不报错）
> **状态**: ✅ 测试服 9443 全链路实测通过（模板 CRUD → 产品绑定 → 创单冻结 → 订单 Tab）

---

## 背景

「出团服务说明书」需要比原来 `notice.title + 一段富文本` 更丰富的结构：**多分组**（一、出团注意事项…）+ **编号条目**（标题/说明/联系人）+ **每日特别提醒**。本期在产品侧**新建**「服务标准」模块，创单冻结进订单快照，订单/小程序/PDF 读快照展示。

前端需做：① 模板编辑器（分组/条目增删）② 产品 Step5 绑定下拉 ③ 行程 Step2 每日「特别提醒」录入 ④ 订单/小程序服务标准 Tab 富展示 ⑤ 行程单/签单 PDF。

---

## 一、产品侧：服务标准模板管理（新增 admin 接口）

路径前缀 `/admin/product/service-standard-template`（已被现有 `/admin/product/**` 网关路由覆盖）。

### 1. 分页
```
GET /admin/product/service-standard-template/page?pageNo=1&pageSize=10&name=&status=
```
返回 `PageResult`（`data.records[]` + `data.total`），按 sortOrder/id 升序。

### 2. 详情
```
GET /admin/product/service-standard-template/{id}
```

### 3. 保存（id 空=新增 / 非空=修改）
```
POST /admin/product/service-standard-template
```
请求体：
```jsonc
{
  "id": null,                       // 修改时传(字符串透传雪花ID)
  "name": "草原出团服务说明书",       // 必填
  "intro": "出团前请仔细阅读…",       // 顶部提示语(截图绿色提示条)
  "applicableScope": "全部跟团客户",  // 适用对象
  "sections": [                     // 必填:分组+条目
    {
      "title": "一、出行服务",         // 分组标题(必填)
      "items": [
        { "title": "接送站服务", "content": "提供机场/车站免费接送", "contact": "客服 400-xxx" }
      ]
    }
  ],
  "isDefault": false,
  "sortOrder": 0,
  "status": "ENABLED"               // 留空默认 ENABLED；ENABLED=启用/DISABLED=停用
}
```
返回 `data` = 模板ID（**字符串透传，勿 Number()**）。

### 4. 删除（软删，已绑定产品不受影响）
```
DELETE /admin/product/service-standard-template/{id}
```

### 5. 下拉（Step5 绑定用，仅启用项，不分页）
```
GET /admin/product/service-standard-template/enabled
```
返回 `data: [ { "id": "...", "name": "草原出团服务说明书" } ]`（只 id+name）。

---

## 二、产品 Step5 补充信息：绑定模板（纯引用）

`PUT /admin/product/item/{id}/supplement` 请求体**新增**字段：
```jsonc
{ "serviceStandardTemplateId": 2059839696602615809 }  // 字符串透传；解绑传 null
```
保存后产品详情回显该 ID；用上面的 `/enabled` 下拉选。

> **私人定制例外**：私人定制(CUSTOM)产品「完成设计」时会把当时模板内容**冻结快照**进产品，之后改模板不影响该产品；核心/小蒙马为纯引用（改模板后续新订单实时跟随）。前端无需特殊处理，知悉即可。

---

## 三、产品 Step2 行程：每日「特别提醒」

`PUT /admin/product/item/{id}/itinerary` 的每个 `DayItem` **新增**字段：
```jsonc
{
  "dayNumber": 1,
  "serviceTips": [                                  // 本日特别提醒(可空)
    { "title": "本日特别提醒", "content": "今日海拔较高,备好抗高反药" }
  ]
}
```
保存后行程回显该天的 `serviceTips`。

---

## 四、订单详情「服务标准」Tab 响应升级

```
GET /v3/admin/order/{id}/service-standard
```
（小程序端经 hl-mp BFF 聚合，结构一致）

`data` **新增** `serviceStandard` + `dayTips` 两块；保留原 `itinerary`、`refundPolicy`；原 `notice` 字段**废弃**（恒 null，请改用 `serviceStandard`）：
```jsonc
{
  "itinerary": ["Day1 …","Day2 …"],          // 保留:行程天纲
  "notice": null,                            // 废弃,勿再用
  "refundPolicy": { /* 原结构保留 */ },
  "serviceStandard": {                       // 新:服务标准总则
    "intro": "出团前请仔细阅读…",
    "applicableScope": "全部跟团客户",
    "sections": [
      { "title": "一、出行服务",
        "items": [ { "title": "接送站服务", "content": "…", "contact": "客服 400-xxx" } ] }
    ]
  },
  "dayTips": [                               // 新:每日特别提醒(按天)
    { "dayNumber": 1, "dayTitle": "Day1 抵达-接机",
      "tips": [ { "title": "本日特别提醒", "content": "今日海拔较高…" } ] }
  ]
}
```

### 向后兼容（重要）
- **本次升级前已下单的旧订单**：`serviceStandard` 返回 `null`、`dayTips` 返回 `[]`（快照里没有新结构，已实测降级不报错）。前端渲染需判空：`serviceStandard` 为 null 时不画总则区，`dayTips` 为空时不画每日提醒。
- 升级后、且产品已绑模板/配每日提醒的**新订单**才有完整数据（已实测）。

---

## 字段约定
- 所有雪花 ID（模板 id、serviceStandardTemplateId）**按字符串透传，勿 Number()**。
- `sections` / `serviceTips` / `tips` 为空时分别返回 `[]` 或字段缺省，渲染需判空。

---

## 验证
测试服 9443 已用真 admin token 全链路实测：模板 CRUD/下拉 → 产品绑定 → 行程每日提醒 → 创单冻结快照 → 订单 Tab 返回结构化 serviceStandard + dayTips（中文非 null）→ 旧订单降级不报错。
