# 小程序每日行程详情接口

- **日期**: 2026-04-16
- **服务**: hl-product-service-v2
- **PR**: #675
- **类型**: feat (新接口)

## 新增接口

```
GET /mp/product/{productId}/day/{dayNumber}
```

返回指定天的完整行程详情，用于小程序每日详情页。

### 参数

| 参数 | 类型 | 说明 |
|------|------|------|
| `productId` | Long | 产品ID（路径参数） |
| `dayNumber` | Integer | 天序号，从1开始（路径参数） |

### 响应字段

| 字段 | 类型 | 说明 | 对应原型 |
|------|------|------|---------|
| `dayNumber` | Integer | 天序号 | DAY 2 |
| `dayTitle` | String | 标题 | |
| `quoteText` | String | 每日金句 | 引用文字 |
| `description` | String | 描述 | |
| `coverImageUrl` | String | 封面图 | 顶部大图 |
| `gatherPlace` | Object | 集合地 {name,adcode,center,level} | |
| `dismissalPlace` | Object | 解散地（目的地） | 今日概况·目的地 |
| `dailyMileage` | BigDecimal | 当日里程(km) | 290km |
| `dailyDuration` | Integer | 当日驾车时长(分钟) | 约3.5小时 |
| `breakfast` | String | 早餐 | 今日概况·餐饮 |
| `lunch` | String | 午餐 | |
| `dinner` | String | 晚餐 | |
| `diningRemark` | String | 餐饮备注 | 含BBQ |
| `photoUrls` | List | 实拍照片 | 实拍照片区块 |
| `routePoints` | List | 途经路线 [{name, sortOrder}] | 海拉尔→呼籁营地→额尔古纳 |
| `nodes` | List | 节点列表 | 行程详情 + 今日体验 |
| `hotels` | List | 住宿列表 | 按档位分组展示 |

### nodes[] 字段

| 字段 | 说明 | 用途 |
|------|------|------|
| `nodeType` | SCENIC/ACTIVITY/RESTAURANT/TRANSPORT等 | 行程详情用全部，今日体验只取ACTIVITY |
| `nodeName` | 节点名称 | 呼籁营地、牧云山顶 |
| `startTime` | 开始时间 | 上午、下午 |
| `durationMinutes` | 时长(分钟) | |
| `description` | 描述 | 节点下方的详细文字 |

### hotels[] 字段

| 字段 | 说明 |
|------|------|
| `hotelName` | 酒店名称 |
| `tierSeq` | 档位序号（前端按此分组：1=舒适 2=高档） |
| `roomTypeName` | 房型名称 |
| `roomCount` | 房间数 |

### 错误码

| 场景 | code | message |
|------|------|---------|
| 产品不存在/未上架 | 404 | 产品不存在或已下架 |
| 天序号不存在 | 404 | 行程天不存在: DayN |

### 前端展示对照

- **途经路线**：`routePoints[].name` 用 " → " 连接
- **里程时长**：`dailyMileage` + `dailyDuration`（分钟→"约X.X小时"）
- **今日概况·餐饮**：拼接 `breakfast/lunch/dinner`（HOTEL=含/SELF=自理/SPECIAL=特色）+ `diningRemark`
- **今日概况·目的地**：`dismissalPlace.name`
- **住宿分组**：按 `tierSeq` 分组展示
- **今日体验**：筛选 `nodes[]` 中 `nodeType=ACTIVITY` 的项
