# 后端 BUG 修复 — 装备建议组合 绑定层级 product_supplement → product_line

**日期**: 2026-05-07
**类型**: 后端 BUG 修复（admin 后台 + 小程序）
**模块**: 产品管理（产品线 / 主题）+ 装备建议组合
**通知**: @mmg
**关联**: PR #1782 + PR #1786 (hotfix)，Closes #1777
**测试服**: dev 已部署 + round-trip 验收 PASS
**前端是否需改动**: ✅ **必改**（API 契约 break，前后端必须同步上线）

---

## 背景

PR #1768（2026-05-06）实现「装备建议组合模板 + 产品绑定」时，把 `equipment_template_id` 加在 `product_supplement` 表（每个版本独立绑一个模板）。

业务正确做法：装备需求由目的地、季节、产品类型决定 —— 这些都是**产品线（主题）**层级属性。同主题下不同版本（如「短途版」「南线经典」）只在行程时长、价格、班期上差异，装备需求几乎一致。一主题一份装备建议是合理粒度，运营不必每开新版本都重选模板。

PR #1782 把绑定层级**从 `product_supplement`（版本）下沉到 `product_line`（主题）**。

---

## 前端改动清单

### 1. 主题（产品线）创建/编辑表单 — 新增「装备建议组合」字段

| 项 | 值 |
|----|-----|
| 字段名 | `equipmentTemplateId` |
| 类型 | `Long`（前端传字符串数字也接受） |
| 必填 | 否（可选） |
| label | 装备建议组合 |
| 控件 | 下拉框（搜索/清除） |
| 选项数据 | `GET /admin-api/admin/equipment-template/enabled` （已就绪，返 `EquipmentTemplateSimpleRespVO[]`，含 `templateId/name`） |
| 表单回显 | `GET /admin-api/admin/product/line/{lineId}` 返回的 `equipmentTemplateId` 字段 |
| 保存接口 | `POST /admin-api/admin/product/line`（创建/更新统一入口） body 含 `equipmentTemplateId`（取消绑定传 `null`，已通过 hotfix PR #1786 修复 null 落库 BUG） |

特殊提示展示：当 `equipmentTemplateId != null && equipmentTemplateName == null` 时（模板被软删），展示提示「该装备建议组合已删除，请重新选择」。

### 2. 版本编辑 Step5 表单 — 移除「装备建议组合」字段

`ProductSupplementSaveReqVO.equipmentTemplateId` 已删；`/admin-api/admin/product/{productId}/step5` 提交即使带上该字段也会被静默忽略。请前端表单**直接移除该字段**，避免误导用户以为版本级也能配。

### 3. 版本详情 — `supplement.equipmentTemplateId/Name` 已删

`/admin-api/admin/product/{productId}` 详情接口的 `supplement` 节点不再返 `equipmentTemplateId/Name`。如版本详情页面需要展示装备建议，从主题（产品线）详情接口拿（`GET /admin-api/admin/product/line/{lineId}`）。

### 4. 模板 CRUD 入口位置（建议）

当前位置：「产品 → 主题列表」工具栏「装备建议组合」按钮（PR #1768 引入）。

建议新位置：「系统管理 → 模板管理 / 数据字典」之类全局入口（理由：装备建议组合是全局共享资源，不挂在任何产品维度下；与「合同方案」「保险方案」「行程保障模板」「温馨提示」类一致）。

具体放哪由前端拍板，不影响后端。

### 5. 小程序端 — 透明（无需改）

`GET /mp/product/{productId}` 详情接口的 `equipmentList` 字段语义不变；后端实现已切到 `product → line → equipmentTemplateId`，三态规则保留：
- 主题绑模板 → 返模板 items
- 主题未绑 / 模板软删 → fallback `supplement.equipmentList`（版本自定义）

---

## API 字段差异（前后端对账）

### 新增字段（主题相关 VO）

| 接口 | VO | 字段 | 类型 | 说明 |
|------|-----|------|------|------|
| `POST/PUT /admin/product/line` | `ProductLineSaveReqVO` | `equipmentTemplateId` | `Long` 可选 | 装备建议组合模板 ID；null 取消绑定 |
| `GET /admin/product/line/{id}` | `ProductLineRespVO` | `equipmentTemplateId` | `Long` | 同上 |
| `GET /admin/product/line/{id}` | `ProductLineRespVO` | `equipmentTemplateName` | `String` | 模板名称回显（模板软删时为 null） |
| `GET /admin/product/line/list` | `ProductLineRespVO`（列表项同 VO） | 同上两字段 | — | 已批量回填（不 N+1） |

### 删除字段（版本相关 VO）

| 接口 | VO | 字段 | 处理 |
|------|-----|------|------|
| `POST/PUT /admin/product/{id}/step5` | `ProductSupplementSaveReqVO` | `equipmentTemplateId` | **删除**；前端表单需移除 |
| `GET /admin/product/{id}` | `ProductDetailRespVO.SupplementVO` | `equipmentTemplateId` | **删除** |
| `GET /admin/product/{id}` | `ProductDetailRespVO.SupplementVO` | `equipmentTemplateName` | **删除** |

---

## 后端验收实测（测试服 dev round-trip PASS）

| 验收项 | 实测 |
|--------|------|
| 网关 `/admin/equipment-template/**` 路由 | hl-gateway dev 已部署 |
| 取消绑定 (`equipmentTemplateId=null`) 落库 | hotfix PR #1786 后 PASS（FieldStrategy.IGNORED 注解） |
| 列表回填 templateName | PASS（中文非 null） |
| mp 详情三态 fallback | PASS |
| 模板更新反向清缓存 | PASS（前后两次 GET 反映 items 变化） |
| 模板被引用拒绝软删 | PASS（code 440102） |
| 不存在 templateId 校验 | PASS（code 440103） |

---

## 上线时序（前后端协同）

后端 dev 已合 + 测试服已部署 + round-trip 通过。**前端必须同步上线**，否则：
- 主题创建/编辑表单缺「装备建议组合」字段 → 运营无法配置主题级装备建议
- 版本编辑 Step5 表单仍显示「装备建议组合」字段 → 提交时被静默忽略，误导

正式服由运维管理员部署 hl-product-service-v2 + hl-gateway（PR #1782 + PR #1770）+ hl-ui（前端发版后）。

@mmg 请评估前端改动量并约一个上线时间。
