# 接口变更记录 — 2026-04-14 11:39

> **提交** `acf4d1e0` · **作者** wx · **时间** 2026-04-14 11:00:15 +0800
>
> feat(product-v2): 实现10个internal接口(VO返回) + order-v2 Feign改指v2

## 变更总览

- **hl-product-service-v2**
  - AdminProduct (改1)
  - 🆕 InternalProduct (+11 接口)

---

## hl-product-service-v2

### AdminProduct

### ✏️ `GET` /admin/product/item/{id}/suggest-price — 建议售价

- 返回类型: `Result<Map<String, Object>>` → `Result<ResourceSuggestPriceRespVO>`
- 🆕 新增响应类型 `ResourceSuggestPriceRespVO`

**响应变更** `ResourceSuggestPriceRespVO`:

  - 🆕 `adultPrice` (`BigDecimal`) — 成人建议售价(含酒店)
  - 🆕 `childPrice` (`BigDecimal`) — 儿童建议售价(不含酒店)
  - 🆕 `resourceCost` (`BigDecimal`) — 资源成本(景区+活动+服务)
  - 🆕 `hotelCost` (`BigDecimal`) — 酒店成本
  - 🆕 `suppliesCost` (`BigDecimal`) — 备品成本
  - 🆕 `extraCost` (`BigDecimal`) — 额外成本
  - 🆕 `tripDays` (`Integer`) — 行程天数
  - 🆕 `costDetails` (`List<Map<String, Object>>`) — 成本明细列表

### 🆕 新增: InternalProduct

### 📌 `GET` /internal/product/internal/product

### 📌 `GET` /internal/product/{productId}/detail — 获取产品详情（内部）

> 不过滤状态，供order-service创建订单时获取快照。

**参数**

  - `{productId}` (`Long`) — 路径参数：产品ID

**响应** `Result<InternalProductDetailVO>`

| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `productId` | `Long` | 产品ID |
| `name` | `String` | 产品名称 |
| `subtitle` | `String` | 副标题 |
| `productType` | `String` | 产品类型(CORE/GROUP/CUSTOM) |
| `category` | `String` | 产品分类(family/honeymoon/photography/experience/driving) |
| `status` | `String` | 产品状态(DRAFT/PUBLISHED等) |
| `tripDays` | `Integer` | 行程天数 |
| `tripNights` | `Integer` | 行程晚数 |
| `coverImageUrl` | `String` | 封面图URL |
| `lineId` | `Long` | 产品线ID |
| `tiers` | `Object` | 档位列表JSON |
| `seasons` | `Object` | 适用季节 |
| `tags` | `Object` | 产品标签 |
| `carouselImages` | `Object` | 轮播图JSON |
| `itinerary` | `List<Object>` | 行程天列表 |

### 📌 `GET` /internal/product/{productId}/simple-quote — 简单报价（内部）

> 从价格日历取售价乘以人数，返回各人群小计和总价。

**参数**

  - `{productId}` (`Long`) — 路径参数：产品ID
  - `childNeedBed` (`boolean`) — 查询参数：儿童加床

**响应** `Result<InternalSimpleQuoteVO>`

| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `adultPrice` | `BigDecimal` | 成人单价 |
| `childPrice` | `BigDecimal` | 儿童单价 |
| `toddlerPrice` | `BigDecimal` | 小童单价 |
| `infantPrice` | `BigDecimal` | 幼童单价 |
| `adultCount` | `Integer` | 成人数量 |
| `childCount` | `Integer` | 儿童数量 |
| `youngChildCount` | `Integer` | 小童数量 |
| `babyCount` | `Integer` | 幼童数量 |
| `adultTotal` | `BigDecimal` | 成人小计 |
| `childTotal` | `BigDecimal` | 儿童小计 |
| `toddlerTotal` | `BigDecimal` | 小童小计 |
| `infantTotal` | `BigDecimal` | 幼童小计 |
| `totalPrice` | `BigDecimal` | 总价 |
| `paymentType` | `String` | 支付方式(FULL/DEPOSIT) |
| `depositRatio` | `Integer` | 订金比例(%) |
| `depositAmount` | `BigDecimal` | 订金金额 |
| `stock` | `Integer` | 剩余库存 |

### 📌 `GET` /internal/product/{productId}/automation-config — 获取自动化配置（内部）

> 供order-service创建订单时获取保险方案、合同配置和支付方式。

**参数**

  - `{productId}` (`Long`) — 路径参数：产品ID

**响应** `Result<InternalAutomationConfigVO>`

| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `insuranceSchemeId` | `Long` | 保险方案ID |
| `contractSchemeId` | `Long` | 合同方案ID |
| `bookingTermsId` | `Long` | 预订条款ID |
| `warmTipsId` | `Long` | 温馨提示ID |
| `paymentType` | `String` | 支付方式(FULL/DEPOSIT) |
| `depositRatio` | `Integer` | 订金比例(%) |
| `depositAmount` | `BigDecimal` | 订金固定额 |

### 📌 `GET` /internal/product/batch/{batchId}/info — 获取班期信息（内部）

> 供order-service创建订单时获取班期快照。

**参数**

  - `{batchId}` (`Long`) — 路径参数：班期ID

**响应** `Result<InternalBatchInfoVO>`

| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `batchId` | `Long` | 班期ID |
| `productId` | `Long` | 产品ID |
| `batchNo` | `String` | 班期编号 |
| `batchName` | `String` | 班期名称 |
| `departureDate` | `String` | 出发日期 |
| `endDate` | `String` | 结束日期 |
| `enrollmentDeadline` | `String` | 报名截止日 |
| `batchStatus` | `String` | 班期状态(ENROLLING/CONFIRMED/FULL等) |
| `maxParticipants` | `Integer` | 最大参与人数 |
| `enrolledCount` | `Integer` | 已报名人数 |
| `remainingSlots` | `Integer` | 剩余名额 |
| `maxRooms` | `Integer` | 最大房间数 |
| `bookedRooms` | `Integer` | 已预订房间数 |
| `remainingRooms` | `Integer` | 剩余房间数 |
| `adultPrice` | `BigDecimal` | 成人价 |
| `childPrice` | `BigDecimal` | 儿童价 |

### 📌 `GET` /internal/product/batch/{batchId}/quote — 班期报价（内部）

> 供order-service获取GROUP产品按人数/房间的报价。

**参数**

  - `{batchId}` (`Long`) — 路径参数：班期ID

**响应** `Result<InternalBatchQuoteVO>`

| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `adultPrice` | `BigDecimal` | 成人单价 |
| `childPrice` | `BigDecimal` | 儿童单价 |
| `adultCount` | `Integer` | 成人数量 |
| `childCount` | `Integer` | 儿童数量 |
| `roomCount` | `Integer` | 房间数量 |
| `adultTotal` | `BigDecimal` | 成人小计 |
| `childTotal` | `BigDecimal` | 儿童小计 |
| `grandTotal` | `BigDecimal` | 总价 |

### 📌 `POST` /internal/product/{productId}/deduct-stock — 扣减库存（内部）

> 乐观锁扣减价格日历库存。

**参数**

  - `{productId}` (`Long`) — 路径参数：产品ID
  - `date` (`String`) — 查询参数：日期(yyyy-MM-dd)

**响应** `Result<Void>`

### 📌 `POST` /internal/product/{productId}/restore-stock — 恢复库存（内部）

> 订单取消/过期时恢复库存。

**参数**

  - `{productId}` (`Long`) — 路径参数：产品ID
  - `date` (`String`) — 查询参数：日期(yyyy-MM-dd)

**响应** `Result<Void>`

### 📌 `POST` /internal/product/batch/{batchId}/enroll — 报名入团（内部）

> 乐观锁报名。

**参数**

  - `{batchId}` (`Long`) — 路径参数：班期ID
  - `roomCount` (`int`) — 查询参数：预订房间数

**响应** `Result<Void>`

### 📌 `POST` /internal/product/batch/{batchId}/unenroll — 取消报名（内部）

> 归还名额和房间。

**参数**

  - `{batchId}` (`Long`) — 路径参数：班期ID
  - `roomCount` (`int`) — 查询参数：归还房间数

**响应** `Result<Void>`

### 📌 `POST` /internal/product/{productId}/custom-status — 变更定制产品状态（内部）

> 仅CUSTOM类型。

**参数**

  - `{productId}` (`Long`) — 路径参数：产品ID
  - `status` (`String`) — 查询参数：目标状态

**响应** `Result<Void>`

---

<details>
<summary>📁 全部变更文件 (点击展开)</summary>

```
M	hl-order-service-v2/src/main/java/com/hulalv/shared/feign/ProductFeignClient.java
M	hl-product-service-v2/src/main/java/com/hulalv/controller/admin/AdminProductController.java
A	hl-product-service-v2/src/main/java/com/hulalv/controller/internal/InternalProductController.java
A	hl-product-service-v2/src/main/java/com/hulalv/feign/ResourceDetailFeignClient.java
M	hl-product-service-v2/src/main/java/com/hulalv/mapper/GroupTourBatchMapper.java
M	hl-product-service-v2/src/main/java/com/hulalv/mapper/ProductPriceCalendarMapper.java
M	hl-product-service-v2/src/main/java/com/hulalv/service/admin/AmapDrivingService.java
M	hl-product-service-v2/src/main/java/com/hulalv/service/admin/ProductPricingService.java
A	hl-product-service-v2/src/main/java/com/hulalv/service/internal/InternalProductService.java
A	hl-product-service-v2/src/main/java/com/hulalv/vo/admin/ResourceSuggestPriceRespVO.java
A	hl-product-service-v2/src/main/java/com/hulalv/vo/internal/InternalAutomationConfigVO.java
A	hl-product-service-v2/src/main/java/com/hulalv/vo/internal/InternalBatchInfoVO.java
A	hl-product-service-v2/src/main/java/com/hulalv/vo/internal/InternalBatchQuoteVO.java
A	hl-product-service-v2/src/main/java/com/hulalv/vo/internal/InternalProductDetailVO.java
A	hl-product-service-v2/src/main/java/com/hulalv/vo/internal/InternalSimpleQuoteVO.java
M	hl-product-service-v2/src/test/java/com/hulalv/service/admin/AmapDrivingServiceTest.java
```
</details>