mahjong_group/docs/1.0.0/历史需求/API接口文档_预约时段优化.md
2026-01-01 14:39:23 +08:00

449 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 预约系统按时段优化 - 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