# 小蒙马(GROUP)团期房间库存管理 - 前端对接指南 > **日期**: 2026-03-18 > **后端状态**: ✅ 已完成,测试环境已部署 > **涉及模块**: 拼团批次管理、小蒙马下单 --- ## 功能说明 小蒙马(GROUP)团期新增**房间库存管理**功能: **核心变更**: 1. 创建团期时**必须设置总房间数**(maxRooms) 2. 用户/管理员下单时,系统自动**扣减房间库存** 3. 房间不足时,下单直接报错"房间不足,剩余X间,需要Y间" 4. 订单取消/退款/超时/散团,系统自动**恢复房间库存** 5. 团期列表、日历、详情均返回房间相关信息 **并发安全**:使用MySQL乐观锁(`WHERE booked_rooms + count <= max_rooms`),防止超卖。 --- ## 变更接口清单 | # | 接口 | 方法 | 路径 | 变更类型 | 说明 | |---|------|------|------|----------|------| | 1 | 创建主批次 | POST | `/admin/product/item/{productId}/group-batch` | 请求新增字段 | 新增必填参数 `maxRooms` | | 2 | 创建子批次(溢出) | POST | `/admin/product/item/group-batch/{parentBatchId}/sub` | 请求新增字段 | 同上 | | 3 | 更新批次 | PUT | `/admin/product/item/group-batch/{batchId}` | 请求新增字段 | 新增可选参数 `maxRooms` | | 4 | 批次列表(树形) | GET | `/admin/product/item/{productId}/group-batches` | 响应新增字段 | VO新增3个房间字段 | | 5 | 批次详情 | GET | `/admin/product/item/group-batch/{batchId}` | 响应新增字段 | 同上 | | 6 | 团期日历(C端) | GET | `/internal/product/{productId}/batches/calendar` | 响应新增字段 | 日历VO新增3个房间字段 | | 7 | GROUP报价 | GET | `/admin/product/item/{productId}/group-quote` | 无变更 | - | --- ## 接口 1:创建主批次(请求新增字段) **使用场景**:管理员在拼团批次管理页面创建新团期时,需要额外填写"总房间数"。 ``` POST /admin/product/item/{productId}/group-batch ``` ### 请求参数 | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | batchName | String | ✅ | 批次名称,如"7月20日第1批" | | departureDate | String(date) | ✅ | 出发日期,如"2026-07-20" | | enrollmentDeadline | String(date) | ✅ | 报名截止日期,必须早于出发日期 | | maxParticipants | Integer | ✅ | 最大参团人数(≥1) | | **maxRooms** | **Integer** | **✅ 新增必填** | **总房间数(≥1),下单时扣减,取消时恢复** | | adultsPerRoom | Integer | 否 | 每间房入住成人数(默认2,用于计算单房差) | | minParticipants | Integer | 否 | 最低成团人数(默认0=不限制) | | remark | String | 否 | 备注说明 | | sortOrder | Integer | 否 | 排序序号(默认0) | ### 请求示例 ```json { "batchName": "7月20日第1批", "departureDate": "2026-07-20", "enrollmentDeadline": "2026-07-15", "maxParticipants": 30, "maxRooms": 15, "adultsPerRoom": 2, "minParticipants": 10, "remark": "暑期特别批次", "sortOrder": 0 } ``` ### 响应示例 ```json { "code": 200, "message": "成功", "data": { "batchId": "2030139162007318530", "productId": "2030106351179280385", "parentBatchId": null, "batchNo": "B2026072033", "batchLabel": "1", "batchName": "7月20日第1批", "departureDate": "2026-07-20", "endDate": "2026-07-26", "enrollmentDeadline": "2026-07-15", "minParticipants": 10, "maxParticipants": 30, "enrolledCount": 0, "adultsPerRoom": 2, "maxRooms": 15, "bookedRooms": 0, "remainingRooms": 15, "batchStatus": "PENDING", "sortOrder": 0, "remark": "暑期特别批次", "createBy": "2025607151170445314", "createTime": "2026-03-18T17:16:00", "updateTime": "2026-03-18T17:16:00", "remainingSlots": 30, "subBatches": [] } } ``` --- ## 接口 3:更新批次(请求新增字段) **使用场景**:管理员修改团期信息时,可调整总房间数(不能低于已预订数)。 ``` PUT /admin/product/item/group-batch/{batchId} ``` ### 新增请求参数 | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | **maxRooms** | **Integer** | **否(新增)** | **总房间数(≥1),不能低于已预订房间数,否则报错** | ### 校验规则 - `maxRooms` 不能低于 `bookedRooms`,否则返回错误:"总房间数不能低于已预订房间数(X)" --- ## 响应 VO 新增字段(影响接口 4、5、6) 以下3个字段在**批次列表、批次详情、团期日历**响应中均有返回: ### 团批次VO(GroupTourBatchVO)— 接口4、5 | 字段 | 类型 | 说明 | |------|------|------| | **maxRooms** | Integer | 总房间数 | | **bookedRooms** | Integer | 已预订房间数 | | **remainingRooms** | Integer | 剩余房间数(= maxRooms - bookedRooms) | ### 团期日历VO(GroupBatchCalendarVO)— 接口6 | 字段 | 类型 | 说明 | |------|------|------| | **maxRooms** | Integer | 总房间数 | | **bookedRooms** | Integer | 已预订房间数 | | **remainingRooms** | Integer | 剩余房间数 | ### 响应示例(批次列表中的一条) ```json { "batchId": "2030139162007318530", "batchName": "7月20日第1批", "departureDate": "2026-07-20", "maxParticipants": 30, "enrolledCount": 5, "remainingSlots": 25, "maxRooms": 15, "bookedRooms": 3, "remainingRooms": 12, "adultsPerRoom": 2, "batchStatus": "ENROLLING" } ``` --- ## 下单相关变更 ### 下单房间校验 用户/管理员创建GROUP订单时,系统会: 1. **前置检查**:根据批次的 `remainingRooms` 判断房间是否充足 2. **乐观锁扣减**:`booked_rooms + roomCount <= max_rooms` 时才扣减成功 3. **失败提示**:`"房间不足,剩余X间,需要Y间"` ### 取消/退款自动恢复 以下场景自动归还房间: - 用户主动取消订单 - 管理员取消订单 - 支付超时自动取消 - 团期散团批量取消 - 退款完成 归还逻辑:`booked_rooms = booked_rooms - 订单的roomCount` --- ## 前端实现建议 ### 创建/编辑团期表单 在现有表单中新增一行: ``` ┌─────────────────────────────────────────────┐ │ 批次名称: [7月20日第1批 ] │ │ 出发日期: [2026-07-20 📅] │ │ 报名截止: [2026-07-15 📅] │ │ 最大人数: [30 ] │ │ 总房间数: [15 ] ← 新增必填 │ │ 每房成人: [2 ] │ │ 最低成团: [10 ] │ │ 备 注: [暑期特别批次 ] │ └─────────────────────────────────────────────┘ ``` - `maxRooms` 使用 `el-input-number`,min=1 - 编辑时需校验:不能低于 `bookedRooms`(从详情接口获取) ### 批次列表展示 在现有的"已报名/最大人数"旁边,增加房间信息: ``` 第1批 | 2026-07-20出发 | 报名中 人数: 5/30 (剩余25) | 房间: 3/15 (剩余12) ``` ### 小程序端日历 日历接口已返回 `remainingRooms`,可在日历格子中展示"剩余X间"。 --- ## 数据库变更 ```sql ALTER TABLE group_tour_batch ADD COLUMN max_rooms INT NOT NULL DEFAULT 0 COMMENT '总房间数', ADD COLUMN booked_rooms INT NOT NULL DEFAULT 0 COMMENT '已预订房间数'; ``` > 已在本地、测试环境执行完毕。历史团期的 max_rooms=0,需要管理员编辑补充。 --- ## 关联字典 | 字典类型 | 字典值 | 中文标签 | 说明 | |----------|--------|----------|------| | batch_status | PENDING | 待开放 | 初始状态,不接受报名 | | batch_status | ENROLLING | 报名中 | 接受报名,可下单 | | batch_status | CONFIRMED | 已成团 | 达到最低成团人数,仍可报名 | | batch_status | FULL | 已满员 | 人数达到上限,自动关闭 | | batch_status | CLOSED | 已关闭 | 管理员手动关闭报名 | | batch_status | DISBANDED | 已解散 | 散团,触发退款 | | batch_status | IN_PROGRESS | 进行中 | 出发日当天自动更新 | | batch_status | FINISHED | 已结束 | 行程结束 |