# 产品v2 - 4月13日完整更新汇总

**日期**: 2026-04-13
**服务**: product-service-v2
**类型**: 新增接口 + bug修复 + 模块搬迁
**PR**: #431, #433, #442, #446-#452

---

## 一、新增接口

### 1. 计算行程总里程
`GET /admin/product/item/{productId}/calculate-mileage`

根据行程途经点坐标调用高德驾车路线规划API自动计算总驾驶里程。

**返回**: `BigDecimal` 总里程(km)，1位小数

---

### 2. 计算建议售价
`GET /admin/product/item/{productId}/suggest-price`

根据备品成本+额外成本计算建议售价。有激活的公式组时走FormulaEngine计算。

**返回示例**:
```json
{
  "adultSuggestPrice": 220.0,
  "childSuggestPrice": 70.0,
  "formulaApplied": false,
  "adultCost": {
    "suppliesCost": 70.0,
    "extraCost": 150.0,
    "totalCost": 220.0,
    "suppliesItems": [
      {"name": "防晒霜SPF50+", "unitPrice": 30.0, "quantity": 1, "subtotal": 30.0}
    ],
    "extraItems": [
      {"name": "骑马延时", "unitPrice": 150.0, "quantity": 1, "subtotal": 150.0}
    ]
  },
  "childCost": { ... }
}
```

---

### 3. 报价公式管理（从v1搬迁）
`/admin/product/formula/**`

| 接口 | 方法 | 说明 |
|------|------|------|
| `/formula/group/list` | GET | 公式组列表 |
| `/formula/group/{groupId}` | GET | 公式组详情 |
| `/formula/group` | POST | 创建公式组 |
| `/formula/group/{groupId}` | PUT | 更新公式组 |
| `/formula/group/{groupId}/activate` | PUT | 激活公式组 |
| `/formula/group/{groupId}` | DELETE | 删除公式组 |
| `/formula/group/{groupId}/steps` | GET | 步骤列表 |
| `/formula/step/{formulaId}` | GET | 步骤详情 |
| `/formula/step` | POST | 创建步骤 |
| `/formula/step/{formulaId}` | PUT | 更新步骤 |
| `/formula/step/{formulaId}/toggle` | PUT | 启用/禁用 |
| `/formula/step/{formulaId}` | DELETE | 删除步骤 |
| `/formula/step/{formulaId}/versions` | GET | 版本历史 |
| `/formula/step/{formulaId}/rollback/{versionNum}` | PUT | 回滚版本 |
| `/formula/test` | POST | 测试执行 |
| `/formula/var/list` | GET | 变量列表 |
| `/formula/var` | POST | 创建变量 |
| `/formula/var/{varId}` | PUT | 更新变量 |
| `/formula/var/{varId}` | DELETE | 删除变量 |

---

### 4. 温馨提示管理（从v1搬迁）
`/admin/product/warm-tips/**`

| 接口 | 方法 | 说明 |
|------|------|------|
| `/warm-tips/list` | GET | 全部列表 |
| `/warm-tips/enabled` | GET | 启用列表（下拉用） |
| `/warm-tips/{tipsId}` | GET | 详情 |
| `/warm-tips` | POST | 创建 |
| `/warm-tips/{tipsId}` | PUT | 修改 |
| `/warm-tips/{tipsId}` | DELETE | 删除 |
| `/warm-tips/{tipsId}/toggle?enabled=true/false` | PUT | 启用/禁用 |

---

### 5. 预订条款管理（从v1搬迁）
`/admin/product/booking-terms/**`

接口结构同温馨提示，字段名 `tipsId` → `termsId`，`tipsName` → `termsName`

---

## 二、Bug修复

### 1. 产品详情 routeInfo 返回 null（已修）
Step3保存的总里程/线路描述能存入DB但详情接口返回null。原因：SQL返回扁平字段，VO期望嵌套对象。

### 2. 详情返回JSON字段格式（已修）
- `photoUrls`: 之前返回 `"[\"url\"]"`（字符串），现在返回 `["url"]`（数组）
- `customFields`: 同上，字符串→对象
- `images`（节点）: 同上
- `extraData`（节点）: 同上

### 3. 详情返回审计字段（已修）
行程天/节点/住宿/路线点不再返回 `createTime`/`updateTime`/`createdBy`/`updatedBy`/`deletedAt`

### 4. 行程保存事务失效（已修）
调用行程保存接口报500。原因：自调用@Transactional不生效。

---

## 三、全接口验证结果

| 接口 | 状态 |
|------|------|
| 产品线列表/下拉 | ✅ 200 |
| 产品分页列表 | ✅ 200 (7条) |
| 产品详情(4个产品) | ✅ 200, photoUrls=list, coverImg=Y, 审计字段=clean |
| Step1 基础信息保存 | ✅ 200 |
| Step2 行程保存 | ✅ 200 |
| Step3 路线与备品保存 | ✅ 200 |
| Step4 价格日历批量设置 | ✅ 200 |
| Step4 班期创建/修改/删除 | ✅ 200 |
| Step5 补充信息保存 | ✅ 200 |
| 里程计算 | ✅ 200 |
| 建议售价 | ✅ 200 |
| 报价计算 | ✅ 200 |
| 上架预检(4个) | ✅ 全部PASS |
| 费用推导预览 | ✅ 200 |
| 操作记录 | ✅ 200 |
| 温馨提示CRUD | ✅ 200 |
| 预订条款CRUD | ✅ 200 |
| 报价公式组/步骤/变量 | ✅ 200 |
