# API接口文档 - 预约房间页面 (book-room-page)
## 文档说明
本文档为 `uniapp/mahjong_group/pages/appointment/book-room-page.vue` 页面提供完整的API接口设计方案。
---
## 📊 数据库设计评估
### 现有字段(SQRooms表)
✅ **已有字段:**
- `id`: 房间ID
- `name`: 房间名称
- `price_per_hour`: 价格/小时
- `capacity`: 可容纳人数
- `status`: 可用状态 (bool)
⚠️ **缺失字段(需要扩展):**
- `image_url`: 房间图片URL
- `room_type`: 房间类型(如:小包、中包、大包、豪华包)
- `description`: 房间描述
### 已新增字段
```sql
-- 扩展 SQRooms 表,添加以下字段:
ALTER TABLE SQRooms ADD image_url NVARCHAR(500) NULL;
ALTER TABLE SQRooms ADD room_type NVARCHAR(50) NULL;
ALTER TABLE SQRooms ADD description NVARCHAR(500) NULL;
```
---
## 📡 API接口设计
### 1️⃣ 获取房间列表(带时段占用信息)
**接口名称:** GetRoomListWithTimeSlots
**请求方式:** `GET`
**接口路径:** `/api/SQ/GetRoomListWithTimeSlots`
**功能说明:** 获取指定日期的所有房间列表,包含房间详细信息、价格、当前状态以及时段占用情况
#### 请求参数
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| date | long | 是 | 查询日期(Unix时间戳-秒级),传入当天0点的时间戳 |
| showTimeSlots | bool | 否 | 是否返回时段占用信息(默认false) |
**示例:**
```
GET /api/SQ/GetRoomListWithTimeSlots?date=1733443200&showTimeSlots=true
```
#### 响应数据
```json
{
"code": 0,
"msg": "ok",
"data": [
{
"id": 1,
"name": "304号-大包",
"room_type": "大包",
"image_url": "https://example.com/rooms/304.jpg",
"price_per_hour": 30.00,
"vip_price_per_hour": 25.00,
"capacity": 6,
"description": "豪华大包厢,配有独立卫生间",
"status": "available", // available-可预约, using-使用中, unavailable-不可用
"is_available": true,
"time_slots": { // 仅当 showTimeSlots=true 时返回
"dawn": { // 凌晨 0:00-6:00
"is_occupied": true,
"reservations": [
{ "start_time": "2025-12-06 02:00:00", "end_time": "2025-12-06 06:00:00" }
]
},
"morning": { // 上午 6:00-12:00
"is_occupied": false,
"reservations": []
},
"afternoon": { // 下午 12:00-18:00
"is_occupied": true,
"reservations": [
{ "start_time": "2025-12-06 14:00:00", "end_time": "2025-12-06 18:00:00" }
]
},
"evening": { // 晚上 18:00-24:00
"is_occupied": false,
"reservations": []
}
}
},
{
"id": 2,
"name": "305号-中包",
"room_type": "中包",
"image_url": "https://example.com/rooms/305.jpg",
"price_per_hour": 20.00,
"vip_price_per_hour": null,
"capacity": 4,
"description": "标准中包厢",
"status": "using",
"is_available": false,
"time_slots": null
}
]
}
```
#### 响应字段说明
| 字段 | 类型 | 说明 |
|------|------|------|
| id | int | 房间ID |
| name | string | 房间名称 |
| room_type | string | 房间类型 |
| image_url | string | 房间图片URL(若为空,前端显示默认图) |
| price_per_hour | decimal | 标准价格/小时 |
| vip_price_per_hour | decimal | 会员价/小时(null表示无会员价) |
| capacity | int | 可容纳人数 |
| description | string | 房间描述 |
| status | string | 房间状态:
- `available`: 可预约
- `using`: 当前使用中
- `unavailable`: 不可用(维护中等) |
| is_available | bool | 是否可预约 |
| time_slots | object | 时段占用信息(仅当请求参数 showTimeSlots=true 时返回) |
---
### 2️⃣ 新增获取可预约房间列表
**接口名称:** GetReservationRoomListNew
**请求方式:** `GET`
**接口路径:** `/api/SQ/GetReservationRoomListNew`
**功能说明:** 获取指定时间段内可预约的房间列表(不包含已预约和不可用时段的房间)
#### 请求参数
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| startTime | long | 是 | 开始时间(Unix时间戳-秒级) |
| endTime | long | 是 | 结束时间(Unix时间戳-秒级) |
**示例:**
```
GET /api/SQ/GetReservationRoomListNew?startTime=1733457600&endTime=1733472000
```
#### 响应数据
```json
{
"code": 0,
"msg": "ok",
"data": [
{
"id": 1,
"name": "304号-大包",
"room_type": "大包",
"image_url": "https://example.com/rooms/304.jpg",
"price_per_hour": 30.00,
"vip_price_per_hour": 25.00,
"capacity": 6,
"description": "豪华大包厢",
"display_name": "304号-大包 30.00/小时" // 用于前端直接显示
},
{
"id": 3,
"name": "306号-小包",
"room_type": "小包",
"image_url": null,
"price_per_hour": 15.00,
"vip_price_per_hour": null,
"capacity": 4,
"description": "标准小包厢",
"display_name": "306号-小包 15.00/小时"
}
]
}
```
---
### 3️⃣ 获取营业时间配置
**接口名称:** GetBusinessHours
**请求方式:** `GET`
**接口路径:** `/api/Common/GetBusinessHours`
**功能说明:** 获取店铺营业时间配置
#### 请求参数
无
#### 响应数据
```json
{
"code": 0,
"msg": "ok",
"data": {
"open_time": "09:00",
"close_time": "23:00",
"is_24_hours": false,
"description": "早9点 至 晚23点"
}
}
```
#### 响应字段说明
| 字段 | 类型 | 说明 |
|------|------|------|
| open_time | string | 开始营业时间(HH:mm格式) |
| close_time | string | 结束营业时间(HH:mm格式) |
| is_24_hours | bool | 是否24小时营业 |
| description | string | 营业时间描述文本 |
---
### 4️⃣ 获取房间详情
**接口名称:** GetRoomDetail
**请求方式:** `GET`
**接口路径:** `/api/SQ/GetRoomDetail`
**功能说明:** 获取指定房间的详细信息
#### 请求参数
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| roomId | int | 是 | 房间ID |
| date | long | 否 | 查询日期(默认今天) |
#### 响应数据
```json
{
"code": 0,
"msg": "ok",
"data": {
"id": 1,
"name": "304号-大包",
"room_type": "大包",
"image_url": "https://example.com/rooms/304.jpg",
"images": [ // 多图展示
"https://example.com/rooms/304_1.jpg",
"https://example.com/rooms/304_2.jpg"
],
"price_per_hour": 30.00,
"vip_price_per_hour": 25.00,
"capacity": 6,
"description": "豪华大包厢,配有独立卫生间、智能麻将桌、空调、Wi-Fi等设施",
"amenities": ["独立卫生间", "智能麻将桌", "空调", "Wi-Fi"],
"status": "available",
"today_reservations": [ // 今日预约情况
{
"start_time": "2025-12-06 14:00:00",
"end_time": "2025-12-06 18:00:00",
"status": 0
}
]
}
}
```
---
## 🔄 前端调用流程
### 页面加载流程
```javascript
// 1. 页面初始化
onLoad() {
this.getDateList(); // 生成7天日期列表(前端)
this.loadRoomList(); // 加载房间列表
this.getBusinessHours(); // 获取营业时间
}
// 2. 加载房间列表(基础模式)
async loadRoomList() {
const selectedDate = this.dateList[this.currentTimeIndex];
const timestamp = this.dateToTimestamp(selectedDate.time);
const res = await uni.request({
url: '/api/SQ/GetRoomListWithTimeSlots',
data: {
date: timestamp,
showTimeSlots: this.showFreeTime // 根据开关决定是否获取时段
}
});
this.roomList = res.data.data;
}
// 3. 切换日期时重新加载
clickTime(index) {
this.currentTimeIndex = index;
this.loadRoomList();
}
// 4. 切换时段显示开关
change(value) {
this.showFreeTime = value;
this.loadRoomList(); // 重新加载,包含时段信息
}
// 5. 点击预约按钮
handleBookRoom(room) {
if (room.status !== 'available') {
uni.showToast({ title: '该房间不可预约', icon: 'none' });
return;
}
// 跳转到预约详情页,传递房间信息
uni.navigateTo({
url: '/pages/appointment/appointment-page?' +
'roomId=' + room.id +
'&roomName=' + encodeURIComponent(room.name) +
'&date=' + this.dateList[this.currentTimeIndex].time
});
}
```
## ✅ 总结
### 数据库设计评估结果
**现有设计基本满足需求**,但建议扩展以下字段以提升用户体验:
1. ⚠️ **必要扩展**(影响核心功能):
- 无,现有字段可满足基本功能
2. ✨ **建议扩展**(提升用户体验):
- `image_url`: 房间图片
- `room_type`: 房间类型
- `vip_price_per_hour`: 会员价
- `description`: 房间描述
### API实现优先级
| 优先级 | 接口 | 说明 |
|--------|------|------|
| 🔴 **P0** | GetRoomListWithTimeSlots | 核心接口,提供房间列表和时段信息 |
| 🟡 **P1** | 优化 GetReservationRoomList | 返回更丰富的房间信息 |
| 🟢 **P2** | GetBusinessHours | 营业时间配置 |
| 🔵 **P3** | GetRoomDetail | 房间详情 |
---
## 📝 注意事项
1. **时区处理**:
- 前端传递时间戳时需统一使用UTC+8时区
- 后端 `DateTimeOffset.FromUnixTimeSeconds()` 自动处理时区转换
2. **默认图片**:
- 前端需准备默认房间图片:`/static/default-room.png`
- 当 `image_url` 为空时使用默认图
3. **缓存策略**:
- 房间列表建议缓存5分钟
- 时段信息实时查询,不缓存
4. **性能优化**:
- 首次加载不查询时段信息(showTimeSlots=false)
- 仅当用户打开开关时再查询时段详情
---
**文档版本**: v1.0
**创建日期**: 2025-12-06
**最后更新**: 2025-12-06