# 预约系统按时段优化 - API接口文档 ## 更新日期:2025-12-06 --- ## 一、概述 本次更新将预约系统从精确时间预约模式改为时段预约模式,新增了房间展示页面、按时段价格配置等功能。 ### 时段定义 | 时段类型 | 时段名称 | 时间范围 | |---------|---------|---------| | 0 | 凌晨 | 00:00 - 05:59 | | 1 | 上午 | 06:00 - 11:59 | | 2 | 下午 | 12:00 - 17:59 | | 3 | 晚上 | 18:00 - 23:59 | --- ## 二、新增用户端接口 ### 2.1 获取未来7天日期列表 **接口地址**:`GET /api/SQ/GetAvailableDates` **请求参数**:无 **响应示例**: ```json { "code": 0, "data": [ { "date": 1733443200, "dateText": "今天", "dateDisplay": "周五" }, { "date": 1733529600, "dateText": "明天", "dateDisplay": "周五" } ], "msg": "ok" } ``` --- ### 2.2 获取房间列表及时段状态 **接口地址**:`GET /api/SQ/GetRoomListWithSlotsNew` **请求参数**: | 参数名 | 类型 | 必填 | 说明 | |-------|------|------|------| | date | long | 是 | 查询日期(Unix时间戳-秒级) | | showOnlyAvailable | bool | 否 | 是否只显示当前时段可用的房间,默认false | | currentTimeSlot | int | 否 | 当前时段类型(0-3),配合showOnlyAvailable使用 | **响应示例**: ```json { "code": 0, "data": [ { "id": 1, "name": "101包间", "room_type_name": "豪华包间", "image_url": "https://...", "capacity": 8, "description": "宽敞舒适...", "standard_price_desc": "80元/时段", "member_price_desc": "60元/时段", "time_slots": [ { "slot_type": 0, "slot_name": "凌晨", "status": "available", "standard_price": 60.00, "member_price": 50.00, "price_desc_standard": "60元/时段", "price_desc_member": "50元/时段" }, { "slot_type": 1, "slot_name": "上午", "status": "reserved", "standard_price": 80.00, "member_price": 60.00, "price_desc_standard": "80元/时段", "price_desc_member": "60元/时段" } ], "status": "available", "is_available": true, "can_reserve": true } ], "msg": "ok" } ``` **时段状态说明**: - `available`:可预约 - `reserved`:已预约 - `unavailable`:不可用(后台设置) - `using`:使用中(当前时间在该时段内且已预约) --- ### 2.4 按时段创建预约 **接口地址**:`POST /api/SQ/AddSQReservationBySlot` **请求头**:需要Authorization **请求体**: ```json { "room_id": 1, "date": 1733443200, "time_slot_type": 1, "latest_arrival_time": 1733468400, "is_solo_mode": false, "player_count": 4, "deposit_fee": 20, "title": "周末开黑", "game_type": "德州扑克", "game_rule": "经典玩法", "extra_info": "欢迎新手", "is_smoking": 0, "gender_limit": 0, "credit_limit": 3.5, "min_age": 18, "max_age": 0, "important_data": "{\"paymentId\":\"ORDER123456\"}" } ``` **字段说明**: | 字段名 | 类型 | 必填 | 说明 | |-------|------|------|------| | room_id | int | 是 | 房间ID | | date | long | 是 | 预约日期(Unix时间戳-秒级) | | time_slot_type | int | 是 | 时段类型:0-3 | | latest_arrival_time | long | 否 | 最晚到店时间(Unix时间戳-秒级) | | is_solo_mode | bool | 否 | 是否为"无需组局"模式,默认false | | player_count | int | 是 | 人数(is_solo_mode=true时固定为1) | | deposit_fee | int | 是 | 鸽子费,0-50整数 | | title | string | 是 | 组局名称 | | game_type | string | 是 | 玩法类型 | | game_rule | string | 否 | 具体规则 | | extra_info | string | 否 | 其他补充 | | is_smoking | int | 否 | 是否禁烟:0=不限制,1=禁烟,2=不禁烟 | | gender_limit | int | 否 | 性别限制:0=不限,1=男,2=女 | | credit_limit | decimal | 否 | 最低信誉分 | | min_age | int | 否 | 最小年龄限制 | | max_age | int | 否 | 最大年龄限制,0=不限 | | important_data | string | 否 | 重要数据(支付相关) | **响应示例**: ```json { "code": 0, "data": { "reservation_id": 123, "start_time": "2025-12-06 06:00:00", "end_time": "2025-12-06 11:59:59", "actual_price": 80.00 }, "msg": "预约成功" } ``` **错误码**: - `500`:参数错误、房间不存在、时间段冲突等 - `402`:用户有其它预约时间冲突 --- ### 2.5 校验是否可以创建预约 **接口地址**:`POST /api/SQ/ValidateReservationBySlot` **请求头**:需要Authorization **请求体**:同"创建预约"接口 **响应示例**: ```json { "code": 0, "data": { "canCreate": true, "reason": "" }, "msg": "" } ``` --- ### 2.6 获取营业时间配置 **接口地址**:`GET /api/SQ/GetBusinessHours` **请求参数**:无 **响应示例**: ```json { "code": 0, "data": { "open_time": "09:00", "close_time": "23:00", "is_24_hours": false, "description": "早9点 至 晚23点" }, "msg": "ok" } ``` --- ### 2.7 获取房间详情(增强版) **接口地址**:`GET /api/SQ/GetRoomDetailEnhanced` **请求参数**: | 参数名 | 类型 | 必填 | 说明 | |-------|------|------|------| | roomId | int | 是 | 房间ID | | date | long | 否 | 查询日期(Unix时间戳-秒级),默认今天 | **响应示例**: ```json { "code": 0, "data": { "id": 1, "name": "101包间", "room_type_name": "豪华包间", "image_url": "https://...", "images": ["https://img1.jpg", "https://img2.jpg"], "price_per_hour": 15.00, "capacity": 8, "description": "宽敞舒适的豪华包间", "amenities": ["空调", "投影仪", "茶水"], "status": "available", "today_reservations": [ { "start_time": "2025-12-06 06:00:00", "end_time": "2025-12-06 11:59:59", "status": 0 } ] }, "msg": "ok" } ``` --- ## 三、修改的现有接口 ### 3.1 加入预约接口(JoinReservation) **修改说明**:新增校验,拒绝加入`is_solo_mode=true`的预约 **新增错误响应**: ```json { "code": 403, "data": null, "msg": "该预约为独享模式,不接受其他人加入" } ``` --- ## 四、数据库变更 ### 4.1 新增表 #### SQRoomPricing(房间时段价格表) ```sql CREATE TABLE [dbo].[SQRoomPricing]( [id] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY, [room_id] [int] NOT NULL, [time_slot_type] [int] NOT NULL, [standard_price] [decimal](10, 2) NOT NULL, [member_price] [decimal](10, 2) NOT NULL, [price_desc_standard] [nvarchar](100) NULL, [price_desc_member] [nvarchar](100) NULL, [effective_date_start] [date] NULL, [effective_date_end] [date] NULL, [is_active] [bit] NOT NULL DEFAULT 1, [created_at] [datetime] NOT NULL DEFAULT GETDATE(), [updated_at] [datetime] NOT NULL DEFAULT GETDATE() ) ``` ### 4.2 修改表 #### SQRooms(房间表) 新增字段: - `room_type_name` (nvarchar(50)):房间类型名称 - `sort_order` (int):排序权重 #### SQRoomUnavailableTimes(房间不可用时段表) 新增字段: - `time_slot_type` (int):时段类型 - `created_by` (int):创建人ID #### SQReservations(预约表) 新增字段: - `time_slot_type` (int):预约的时段类型 - `latest_arrival_time` (datetime):最晚到店时间 - `is_solo_mode` (bit):是否为无需组局模式 - `actual_price` (decimal(10,2)):实际价格 --- ## 五、业务规则说明 ### 5.1 时段预约规则 1. **时段不可重叠**:用户不能预约同一时间有重叠的多个时段 2. **已过时段不可预约**:当前时间已过的时段不允许预约 3. **无需组局模式**: - `is_solo_mode=true`时,`player_count`自动设为1 - 其他用户无法加入该预约 ### 5.2 价格查询规则 1. 优先查询有`effective_date_start/end`且日期匹配的记录(节假日价格) 2. 无匹配则查询`effective_date_start/end`为NULL的默认价格 3. 若某房间某时段无价格配置,该时段不可预约 ### 5.3 房间状态判断 某房间某时段"可预约"需同时满足: 1. 房间状态`status=true`(启用) 2. 该时段无预约记录(`status<3`的预约) 3. 该时段无不可用配置 4. 该时段有价格配置 --- ## 六、错误码定义 | 错误码 | 说明 | |-------|------| | 0 | 成功 | | 400 | 业务错误(如:已加入预约、预约已满) | | 402 | 时间冲突 | | 403 | 权限不足(如:无法加入独享模式预约) | | 404 | 资源不存在 | | 500 | 系统错误或参数错误 | --- ## 七、常见问题 ### Q1: 如何判断当前是哪个时段? A: 根据当前时间的小时数判断: - 0-5点:凌晨(0) - 6-11点:上午(1) - 12-17点:下午(2) - 18-23点:晚上(3) ### Q2: 鸽子费有什么限制? A: 鸽子费必须是0-50之间的整数 ### Q3: 什么是"无需组局"模式? A: 用户独自预约房间,不需要也不允许其他人加入,`player_count`固定为1 ### Q4: 如何设置节假日特殊价格? A: 在`SQRoomPricing`表中添加记录,设置`effective_date_start`和`effective_date_end`为节假日日期范围 --- ## 八、前端对接建议 ### 8.1 日期选择器 调用`GetAvailableDates`获取可选日期列表,展示给用户选择 ### 8.2 房间列表 1. 用户选择日期后,调用`GetRoomListWithSlotsNew`获取房间及4个时段状态 2. 根据`time_slots[].status`显示不同颜色标识: - `available`:绿色 - `reserved`/`using`:红色 - `unavailable`:灰色 3. 根据`can_reserve`字段控制【预约】按钮是否可点击 ### 8.3 创建预约流程 1. 用户点击【预约】按钮 2. 跳转到预约页,携带`roomId`和`date`参数 3. 根据房间时段状态,只显示可预约的时段选项 4. 用户选择时段后,显示对应的价格 5. 填写其他信息后,调用`AddSQReservationBySlot`创建预约 ### 8.4 时间选择器 最晚到店时间的选择范围应根据所选时段动态限制,例如选择"上午"时段时,只能选择06:00-11:59之间的时间 --- ## 九、迁移指南 ### 9.1 数据库迁移 执行提供的SQL迁移脚本:`数据库/SqlServer/更新脚本_预约时段优化.sql` ### 9.2 旧接口兼容 - 原有的`GetReservationRoomList`接口保留,向后兼容 - 原有的`AddSQReservation`接口保留,支持精确时间预约 - 新接口与旧接口可共存,逐步迁移 ### 9.3 前端迁移建议 1. 新功能使用新接口(按时段预约) 2. 旧功能暂时保留,使用旧接口 3. 逐步将用户引导至新的预约流程 --- ## 十、附录 ### 10.1 完整的接口列表 | 接口名称 | 方法 | 路径 | 说明 | |---------|------|------|------| | 获取未来7天日期列表 | GET | /api/SQ/GetAvailableDates | 新增 | | 获取房间列表及时段状态 | GET | /api/SQ/GetRoomListWithSlotsNew | 新增 | | 获取可预约房间列表 | GET | /api/SQ/GetReservationRoomListBySlot | 新增 | | 按时段创建预约 | POST | /api/SQ/AddSQReservationBySlot | 新增 | | 校验是否可创建预约 | POST | /api/SQ/ValidateReservationBySlot | 新增 | | 获取营业时间配置 | GET | /api/SQ/GetBusinessHours | 已存在 | | 获取房间详情 | GET | /api/SQ/GetRoomDetailEnhanced | 新增 | | 加入预约 | POST | /api/SQ/JoinReservation | 修改 | --- **文档版本**:v2.0 **最后更新**:2025-12-06 **联系方式**:jianweie@163.com