From fc04321108d8a16e0abc66ca3d9f52274495a476 Mon Sep 17 00:00:00 2001 From: zpc Date: Sat, 6 Dec 2025 13:57:23 +0800 Subject: [PATCH] 32 --- API接口文档_预约房间页面.md | 390 ++++++++++++++++++++++++++ common/server/interface/common.js | 12 + common/server/interface/sq.js | 37 +++ pages/appointment/book-room-page.vue | 212 +++++++++++--- static/default_room.jpg | Bin 0 -> 54955 bytes 5 files changed, 619 insertions(+), 32 deletions(-) create mode 100644 API接口文档_预约房间页面.md create mode 100644 static/default_room.jpg diff --git a/API接口文档_预约房间页面.md b/API接口文档_预约房间页面.md new file mode 100644 index 0000000..626449e --- /dev/null +++ b/API接口文档_预约房间页面.md @@ -0,0 +1,390 @@ +# 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 + diff --git a/common/server/interface/common.js b/common/server/interface/common.js index fd10550..55d3bcd 100644 --- a/common/server/interface/common.js +++ b/common/server/interface/common.js @@ -59,4 +59,16 @@ export const uploadImages = async (formData) => { return res.data; } return null; +} + +/** + * 获取营业时间配置 + * @returns {Promise} 返回营业时间信息 {open_time, close_time, is_24_hours, description} + */ +export const getBusinessHours = async () => { + const res = await request.get("Common/GetBusinessHours"); + if (res.code == 0) { + return res.data; + } + return null; } \ No newline at end of file diff --git a/common/server/interface/sq.js b/common/server/interface/sq.js index c3db6f8..6e53eef 100644 --- a/common/server/interface/sq.js +++ b/common/server/interface/sq.js @@ -254,6 +254,41 @@ export const checkInReservation = async (checkInData) => { +/** + * 获取房间列表(带时段占用信息) + * @param {number} date 查询日期(Unix时间戳-秒级),传入当天0点的时间戳 + * @param {boolean} showTimeSlots 是否返回时段占用信息(默认false) + * @returns {Promise} 返回房间列表 + */ +export const getRoomListWithTimeSlots = async (date, showTimeSlots = false) => { + const res = await request.get("sq/GetRoomListWithTimeSlots", { + date: date, + showTimeSlots: showTimeSlots + }); + if (res.code == 0) { + return res.data; + } + return null; +} + +/** + * 获取可预约房间列表(新版,包含更丰富信息) + * @param {number} startTime 开始时间(Unix时间戳-秒级) + * @param {number} endTime 结束时间(Unix时间戳-秒级) + * @returns {Promise} 返回房间列表,包含图片、类型、价格等详细信息 + */ +export const getReservationRoomListNew = async (startTime, endTime) => { + const res = await request.get("sq/GetReservationRoomListNew", { + startTime: startTime, + endTime: endTime + }); + if (res.code == 0) { + return res.data; + } + return null; +} + + export const sqInterface = { canCreateSQReservation, getReservationList, @@ -265,6 +300,8 @@ export const sqInterface = { getReputationByUser, getPaymentRecords, getReservationRoomList, + getRoomListWithTimeSlots, + getReservationRoomListNew, addSQReservation, joinReservation, cancelReservation, diff --git a/pages/appointment/book-room-page.vue b/pages/appointment/book-room-page.vue index c4cb6ee..2573515 100644 --- a/pages/appointment/book-room-page.vue +++ b/pages/appointment/book-room-page.vue @@ -5,104 +5,248 @@ 发起预约 - {{item.time}} {{item.weekday}} - - 营业时间:早XX点 至 晚XX点 + + 营业时间:{{ businessHours ? businessHours.description : '加载中...' }} + 查看当前时段空闲时间 - + + + 加载中... + - + + 暂无房间信息 + + + + - - + + mode="aspectFill"> + - 房间号或房间名 - 房间类型 + {{ item.name }} + {{ item.room_type || '标准房' }} - ¥30/4小时 - 会员价¥30/5小时 + ¥{{ item.price_per_hour }}/小时 + 会员价¥XX/小时 - 当前使用中 + + + {{ getRoomStatusText(item.status) }} + - + + 预约 - + + - 已预定时段 + 已预定 - 已预定时段 + 空闲 - - + + - + 凌晨 - + 上午 - + 下午 - + 晚上 - -