# 【新增接口·管理后台】产品 Step5 服务标准 tab 只读预览

> PR: #3377  服务: hl-product-service-v2 | 更新时间: 2026-06-03
> 存放目录: changelogs-v2/2026-06/  影响范围: 管理后台「产品编辑 / Step5 补充信息 / 服务标准 tab」

## ⚠️ 关键说明

Step5 补充信息新增「服务标准」tab，**一个接口返三块**，均**只读、实时拉取不冻快照**：

1. 当前绑定模板内容
2. 各行程节点的服务标准（来自资源 `service_standard`）
3. 各行程节点的退费说明（来自资源退费说明）

模板的**绑定（写）**走 Step5 保存的 `serviceStandardTemplateId`（见同期《服务标准模板与产品的关联方式》），本接口只负责 tab 内的**只读预览展示**。

## 1. 接口背景

运营在 Step5 绑定模板后，希望一屏看到：当前模板内容、以及各行程节点从资源实时带出的服务标准与退费说明，而不必跳到资源页或下单后才看到。

## 2. 接口清单

| # | 方法 | 路径 | 变更类型 | 鉴权 |
|---|------|------|----------|------|
| 1 | GET | `/admin/product/item/{id}/service-standard-preview` | 新增 | admin token，产品数据权限（与产品详情同口径） |

## 3. 请求示例

```bash
curl -H "Authorization: Bearer <admin-token>" \
  "https://api.test.1814.love:9443/admin/product/item/2056944461216100353/service-standard-preview"
```

## 4. 响应结构与字段说明

```
{
  "templateId": Long,            // 当前绑定模板 ID，未绑定为 null
  "template": { ... },           // 绑定模板完整内容，结构同模板详情接口，未绑定为 null
  "nodes": [ ... ]               // 行程节点服务标准+退费说明，仅含有内容的节点，皆空节点不返回
}
```

nodes[] 字段：

| 字段 | 类型 | 说明 |
|------|------|------|
| dayNumber | Integer | 第几天 |
| nodeName | String | 节点名称（如「呼和诺尔草原旅游区」） |
| nodeType | String | 节点类型：SCENIC / ACTIVITY / HOTEL / RESTAURANT / SERVICE ... |
| serviceStandard | String | 节点服务标准（来自资源），无则 null |
| refundNote | Object | 退费说明，无则 null |

refundNote 结构：

| 字段 | 类型 | 说明 |
|------|------|------|
| intro | String | 退费说明备注 |
| items[].title | String | 条目标题（如「成人未参加」） |
| items[].amount | BigDecimal | 退费金额 |
| items[].unitLabel | String | 单位文案（如「/人」「/团」） |
| items[].settleScope | String | 结算范围枚举：PER_PERSON / PER_TEAM |
| items[].settleScopeLabel | String | 结算范围中文（按人 / 按团） |
| items[].remark | String | 备注，可空 |
| items[].effectiveFrom / effectiveTo | Date | 生效区间，可空 |

## 5. 真实响应示例（测试服 dev-v3，产品 2056944461216100353）

```json
{
  "code": 200,
  "data": {
    "templateId": null,
    "template": null,
    "nodes": [
      {
        "dayNumber": 1,
        "nodeName": "巴音温泉",
        "nodeType": "SERVICE",
        "serviceStandard": "提供24小时管家服务，含接送站、行程咨询、紧急联络。",
        "refundNote": null
      },
      {
        "dayNumber": 2,
        "nodeName": "呼和诺尔草原旅游区",
        "nodeType": "SCENIC",
        "serviceStandard": "景区内提供免费讲解、母婴室、医疗点；请听从工作人员安排，注意草原防火。",
        "refundNote": {
          "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 }
          ]
        }
      },
      {
        "dayNumber": 2,
        "nodeName": "黄河湿地漂流",
        "nodeType": "ACTIVITY",
        "serviceStandard": "漂流配备专业教练与救生装备，全程安全护航；12岁以下需成人陪同。",
        "refundNote": null
      }
    ]
  }
}
```

> 说明：示例中节点 `serviceStandard` 为测试服联调写入的样例数据。若资源未配置 `service_standard`，该字段返回 `null`（详见《资源服务标准字段》一文，运营在资源上配置后即自动带出）。

## 6. 测试服实测（dev-v3）

12 个产品调用全部 `code=200`。模板块、退费说明块用真数据验证通过；节点服务标准块在景区 / 游玩项目 / 服务各配一条 `service_standard` 后，三类节点均正确返回上方示例值。

## 7. 前端动作

1. 进入 Step5 服务标准 tab 调本接口。
2. 渲染三块：`template` 模板内容、`nodes[].serviceStandard` 节点服务标准、`nodes[].refundNote` 节点退费说明，均只读。
3. `template` / `serviceStandard` / `refundNote` 均可能为 `null`，按需隐藏对应区块。
4. 绑定（写）走 supplement 的 `serviceStandardTemplateId`，预览（读）走本接口，两者配合。
