# 小蒙马报价增强 + 产品操作日志 - 前端对接指南 > **日期**: 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: '' }) ```