# 小蒙马报价增强 + 产品操作日志 - 前端对接指南

> **日期**: 2026-03-18
> **后端状态**: ✅ 已完成，可直接对接
> **涉及模块**: 产品管理（管理端）、C端产品（小程序端）

---

## 一、功能说明

### 1. 产品操作日志（管理端）

产品服务全部管理接口已补全 `@OperationLog` 注解，管理端产品列表页右侧的"操作日志"面板现在能正常显示操作记录。

**覆盖的模块**（共 73 个写操作接口）：
- 产品管理：保存/创建/更新/删除/复制/移动/分享/路径图/状态变更
- 拼团批次管理：创建主批次/子批次/更新/删除/开启报名/关闭报名/解散/服务人员/复制人员
- 定价公式管理：公式组CRUD/激活 + 步骤CRUD/启停/回滚 + 测试 + 变量CRUD
- 定价与费用管理：定价规则/价格日历/费用项/额外成本/自定义费用
- 行程管理：行程天/节点/住宿/餐饮/物资/人员配置
- 产品线管理/文件夹管理/家庭分组管理/报价计算

**前端无需改动**，操作日志面板已接入 `/admin/monitor/operation-logs` 接口，后端开始写入日志后自动显示。

### 2. 小蒙马(GROUP)产品报价增强

GROUP 产品报价接口新增空床补差计算和房间数参数，算价公式更精确。

### 3. 团期批次新增 `adultsPerRoom` 字段

创建/更新批次时可配置每间房入住成人数（默认2），影响单房差和空床补差计算。

---

## 二、接口清单

| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|---|------|------|------|----------|------|
| 1 | GROUP产品报价 | GET | `/admin/product/item/{productId}/group-quote` | 参数+响应新增 | 新增 childCount、roomCount 参数和多个响应字段 |
| 2 | 创建主批次 | POST | `/admin/product/item/{productId}/batch` | 请求新增 | 新增 adultsPerRoom 字段 |
| 3 | 更新批次 | PUT | `/admin/product/item/{productId}/batch/{batchId}` | 请求新增 | 新增 adultsPerRoom 字段 |
| 4 | 批次列表/详情 | GET | 批次相关接口 | 响应新增 | 返回中新增 adultsPerRoom 字段 |

---

## 三、接口详细定义

### 接口 1：GROUP产品报价（管理端）

**使用场景**：管理端产品详情页 → 报价计算面板，输入人数和房间数查看GROUP产品的完整报价。

```
GET /admin/product/item/{productId}/group-quote?batchId=xxx&adultCount=2&childCount=1&roomCount=1
```

### 请求参数

| 参数 | 类型 | 必填 | 默认值 | 说明 |
|------|------|------|--------|------|
| productId | Long | 是 | - | 产品ID（路径参数） |
| batchId | Long | 是 | - | 团期批次ID |
| adultCount | Integer | 否 | 2 | 成人人数 |
| childCount | Integer | 否 | 0 | 儿童人数（🆕 新增） |
| roomCount | Integer | 否 | 1 | 房间数（🆕 新增） |

### 响应示例

```json
{
  "code": 200,
  "message": "操作成功",
  "data": {
    "code": 0,
    "message": null,
    "singleRoomSupplement": 200.00,
    "perPersonCost": 800.00,
    "adultCostPrice": 1000.00,
    "childCostPrice": 800.00,
    "adultSellPrice": 1500.00,
    "childSellPrice": 1300.00,
    "hotelCostTotal": 600.00,
    "adultsPerRoom": 2,
    "roomCount": 1,
    "adultCount": 2,
    "childCount": 1,
    "emptyBedSupplement": 0.00,
    "totalSellPrice": 4300.00,
    "extraCostTotal": 200.00,
    "extraCostPerPerson": 66.67,
    "extraCostItems": [
      {
        "costItemId": "2026...",
        "costItemName": "保险费",
        "unitPrice": 50.00,
        "quantity": 1,
        "totalPrice": 50.00
      }
    ],
    "dayCosts": [...],
    "profitMode": "PERCENT",
    "warnings": []
  }
}
```

### 响应字段说明

| 字段 | 类型 | 说明 |
|------|------|------|
| code | Integer | 返回码: 0=成功, 1=非GROUP产品, 2=错误 |
| message | String | 错误信息（code!=0时） |
| singleRoomSupplement | BigDecimal | 单房差 = 成人售价 - 儿童售价（🆕 含义变更） |
| perPersonCost | BigDecimal | 每人成本（不含酒店） |
| adultCostPrice | BigDecimal | 成人成本价 = 单房差 + 每人费用 |
| childCostPrice | BigDecimal | 儿童成本价 = 每人费用（不含酒店） |
| adultSellPrice | BigDecimal | 成人售价 |
| childSellPrice | BigDecimal | 儿童售价 |
| hotelCostTotal | BigDecimal | 酒店总成本 |
| adultsPerRoom | Integer | 🆕 每间房入住成人数 |
| roomCount | Integer | 🆕 选择的房间数 |
| adultCount | Integer | 🆕 成人数 |
| childCount | Integer | 🆕 儿童数 |
| emptyBedSupplement | BigDecimal | 🆕 空床补差 = (房间数×每房成人数 - 成人数) × 单房差 |
| totalSellPrice | BigDecimal | 🆕 总售价 = 成人价×成人数 + 儿童价×儿童数 + 空床补差 |
| extraCostTotal | BigDecimal | 额外成本总额（团队） |
| extraCostPerPerson | BigDecimal | 额外成本（人均） |
| extraCostItems | Array | 额外成本明细列表 |
| dayCosts | Array | 每日成本明细 |
| profitMode | String | 利润模式 |
| warnings | Array[String] | 警告信息 |

### 算价公式

```
单房差 = 酒店总成本 ÷ 每房成人数
成人成本价 = 单房差 + 人均成本（不含酒店）
儿童成本价 = 人均成本（不含酒店）
成人售价 = 成人成本价 × (1 + 利润率)
儿童售价 = 儿童成本价 × (1 + 利润率)
空床补差 = (房间数 × 每房成人数 - 成人数) × 单房差
总售价 = 成人售价 × 成人数 + 儿童售价 × 儿童数 + 空床补差
```

---

### 接口 2/3：创建/更新团期批次

**变更**：新增 `adultsPerRoom` 字段。

#### 创建批次请求（新增字段）

```
POST /admin/product/item/{productId}/batch
```

```json
{
  "batchLabel": "五一团",
  "batchName": "2026年五一黄金周第一批",
  "departureDate": "2026-05-01",
  "endDate": "2026-05-05",
  "enrollmentDeadline": "2026-04-25",
  "minParticipants": 10,
  "maxParticipants": 30,
  "adultsPerRoom": 2,
  "remark": "备注"
}
```

#### 更新批次请求（新增字段）

```
PUT /admin/product/item/{productId}/batch/{batchId}
```

```json
{
  "batchLabel": "五一团（更新）",
  "adultsPerRoom": 3,
  "maxParticipants": 35
}
```

### 新增字段说明

| 字段 | 类型 | 必填 | 默认值 | 说明 |
|------|------|------|--------|------|
| adultsPerRoom | Integer | 否 | 2 | 每间房入住成人数（影响单房差和空床补差计算） |

### 批次列表/详情响应（新增字段）

批次列表和详情接口返回的 `GroupTourBatchVO` 新增 `adultsPerRoom` 字段：

```json
{
  "batchId": "2026280000000000001",
  "productId": "2026270000000000001",
  "batchLabel": "五一团",
  "departureDate": "2026-05-01",
  "enrolledCount": 15,
  "adultsPerRoom": 2,
  "batchStatus": "ENROLLING",
  "remainingSlots": 15,
  "subBatches": []
}
```

---

## 四、关联字典

### batch_status（批次状态）

| 值 | 中文 | 说明 |
|----|------|------|
| PENDING | 待开放 | 创建后默认状态 |
| ENROLLING | 报名中 | 用户可报名 |
| CONFIRMED | 已成团 | 达到最低人数 |
| FULL | 已满员 | 达到最大人数 |
| CLOSED | 已关闭 | 不再接受报名 |
| IN_PROGRESS | 进行中 | 已出发 |
| FINISHED | 已结束 | 行程结束 |
| DISBANDED | 已解散 | 批次取消 |

### product_type（产品类型）

| 值 | 中文 | 说明 |
|----|------|------|
| CORE | 核心产品 | 标准产品，按人头计价 |
| GROUP | 小蒙马 | 拼团产品，按人头+房间计价 |
| CUSTOM | 定制产品 | 按单计价 |
| ROUTE | 线路产品 | 预设线路，按单计价 |

---

## 五、前端实现建议

### 1. GROUP报价面板

在团期详情或报价页面，增加"房间数"输入框：

```
┌────────────────────────────────────────┐
│ GROUP产品报价                           │
├────────────────────────────────────────┤
│ 团期: [五一团 ▼]                        │
│ 成人: [2]    儿童: [1]    房间: [1]     │
│                                        │
│ ┌──────────────────────────────┐       │
│ │ 成人售价: ¥1,500/人           │       │
│ │ 儿童售价: ¥1,300/人           │       │
│ │ 空床补差: ¥0.00               │       │
│ │ ─────────────────────         │       │
│ │ 总售价:   ¥4,300.00           │       │
│ └──────────────────────────────┘       │
└────────────────────────────────────────┘
```

**参数变更**：调用 `group-quote` 接口时需传 `childCount` 和 `roomCount`。

### 2. 批次创建/编辑表单

新增"每间房入住成人数"字段（默认2，下拉或数字输入框）：

```
┌────────────────────────────────────────┐
│ 创建团期                                │
├────────────────────────────────────────┤
│ 批次标签: [五一团        ]               │
│ 出发日期: [2026-05-01    ]              │
│ 结束日期: [2026-05-05    ]              │
│ 最少成团: [10]  最大人数: [30]           │
│ 每房成人数: [2 ▼]                       │
│ 报名截止: [2026-04-25    ]              │
└────────────────────────────────────────┘
```

### 3. 操作日志面板

无需前端改动。后端已为产品服务所有 POST/PUT/DELETE 接口添加操作日志，查看产品操作日志的面板将自动展示数据。

---

## 六、调用示例（JavaScript）

### GROUP产品报价

```javascript
// 查询GROUP产品报价（含房间数和儿童）
const res = await request.get(`/admin/product/item/${productId}/group-quote`, {
  params: {
    batchId: selectedBatchId,
    adultCount: 2,
    childCount: 1,   // 新增
    roomCount: 1      // 新增
  }
})

if (res.data.code === 0) {
  const quote = res.data
  console.log('成人售价:', quote.adultSellPrice)
  console.log('儿童售价:', quote.childSellPrice)
  console.log('空床补差:', quote.emptyBedSupplement)   // 新增
  console.log('总售价:', quote.totalSellPrice)           // 新增
}
```

### 创建团期批次（含每房成人数）

```javascript
const res = await request.post(`/admin/product/item/${productId}/batch`, {
  batchLabel: '五一团',
  batchName: '2026年五一黄金周第一批',
  departureDate: '2026-05-01',
  endDate: '2026-05-05',
  enrollmentDeadline: '2026-04-25',
  minParticipants: 10,
  maxParticipants: 30,
  adultsPerRoom: 2,   // 新增：每间房入住成人数
  remark: ''
})
```
