32
This commit is contained in:
parent
db0250db89
commit
fc04321108
390
API接口文档_预约房间页面.md
Normal file
390
API接口文档_预约房间页面.md
Normal file
|
|
@ -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 | 房间状态:<br/>- `available`: 可预约<br/>- `using`: 当前使用中<br/>- `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
|
||||
|
||||
|
|
@ -59,4 +59,16 @@ export const uploadImages = async (formData) => {
|
|||
return res.data;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取营业时间配置
|
||||
* @returns {Promise<any>} 返回营业时间信息 {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;
|
||||
}
|
||||
|
|
@ -254,6 +254,41 @@ export const checkInReservation = async (checkInData) => {
|
|||
|
||||
|
||||
|
||||
/**
|
||||
* 获取房间列表(带时段占用信息)
|
||||
* @param {number} date 查询日期(Unix时间戳-秒级),传入当天0点的时间戳
|
||||
* @param {boolean} showTimeSlots 是否返回时段占用信息(默认false)
|
||||
* @returns {Promise<any>} 返回房间列表
|
||||
*/
|
||||
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<any>} 返回房间列表,包含图片、类型、价格等详细信息
|
||||
*/
|
||||
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,
|
||||
|
|
|
|||
|
|
@ -5,104 +5,248 @@
|
|||
<view style="flex: 1;"></view>
|
||||
<text class="page-title">发起预约</text>
|
||||
<view class="row" style="width: 90%; height: 120rpx; margin: 20rpx auto 0;">
|
||||
<view class="column center" v-for="(item,index) in dateList" :style="setBgColor(index)"
|
||||
<view class="column center" v-for="(item,index) in dateList" :key="index" :style="setBgColor(index)"
|
||||
@click="clickTime(index)" style="width: 96rpx; height: 100%;">
|
||||
<text style="font-size: 26rpx;">{{item.time}}</text>
|
||||
<text style="font-size: 22rpx;">{{item.weekday}}</text>
|
||||
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<text style="margin-top: 20rpx; margin-left: 32rpx; font-size: 24rpx;">营业时间:早XX点 至 晚XX点</text>
|
||||
<text style="margin-top: 20rpx; margin-left: 32rpx; font-size: 24rpx;">
|
||||
营业时间:{{ businessHours ? businessHours.description : '加载中...' }}
|
||||
</text>
|
||||
|
||||
<view class="row"
|
||||
style="width: 686rpx; height: 56rpx; background-color: #2ED9BF; border-radius: 5rpx; margin: 20rpx auto 0; align-items: center;">
|
||||
<text style="font-size: 22rpx; color: #262626; margin-left: 16rpx;">查看当前时段空闲时间</text>
|
||||
<up-switch style="margin-right: 16rpx; margin-left: auto; " v-model="value" @change="change"
|
||||
<up-switch style="margin-right: 16rpx; margin-left: auto;" v-model="showFreeTime" @change="change"
|
||||
size="20"></up-switch>
|
||||
</view>
|
||||
|
||||
<view class="" style="width: 100%; flex: 1; margin-top: 12rpx; overflow-y: auto;">
|
||||
<!-- 加载状态 -->
|
||||
<view v-if="loading" class="center" style="padding: 60rpx 0;">
|
||||
<text style="font-size: 28rpx; color: #999;">加载中...</text>
|
||||
</view>
|
||||
|
||||
<view class="" v-for="(item,index) in roomList"
|
||||
<!-- 无数据提示 -->
|
||||
<view v-else-if="roomList.length === 0" class="center" style="padding: 60rpx 0;">
|
||||
<text style="font-size: 28rpx; color: #999;">暂无房间信息</text>
|
||||
</view>
|
||||
|
||||
<!-- 房间列表 -->
|
||||
<view class="" v-for="(item,index) in roomList" :key="item.id"
|
||||
style="position: relative; width: 706rpx; height: 270rpx; border-radius: 20rpx; background-color: white; margin: 0 auto 20rpx;">
|
||||
|
||||
|
||||
<image src=""
|
||||
<!-- 房间图片 -->
|
||||
<image :src="item.image_url || '/static/default_room.jpg'"
|
||||
style="width: 180rpx; height: 156rpx; background-color: #DEDEDE; border-radius: 14rpx; position: absolute; top: 10rpx; left: 10rpx;"
|
||||
mode=""></image>
|
||||
mode="aspectFill"></image>
|
||||
|
||||
<!-- 房间信息 -->
|
||||
<view class="column" style=" position: absolute; left: 200rpx; top: 20rpx;">
|
||||
<text style="font-size: 28rpx;">房间号或房间名</text>
|
||||
<text style="font-size: 20rpx;">房间类型</text>
|
||||
<text style="font-size: 28rpx;">{{ item.name }}</text>
|
||||
<text style="font-size: 20rpx; color: #666; margin-top: 4rpx;">{{ item.room_type || '标准房' }}</text>
|
||||
|
||||
<text style="font-size: 24rpx; margin-top: 24rpx;">¥30/4小时</text>
|
||||
<text style="font-size: 24rpx; color: #FF0000;">会员价¥30/5小时</text>
|
||||
<text style="font-size: 24rpx; margin-top: 24rpx;">¥{{ item.price_per_hour }}/小时</text>
|
||||
<text style="font-size: 24rpx; color: #FF0000;">会员价¥XX/小时</text>
|
||||
</view>
|
||||
|
||||
<text
|
||||
style="font-size: 20rpx; position: absolute; top: 10rpx; right: 16rpx; color: #FF9901;">当前使用中</text>
|
||||
<!-- 房间状态 -->
|
||||
<text v-if="getRoomStatusText(item.status)"
|
||||
:style="{fontSize: '20rpx', position: 'absolute', top: '10rpx', right: '16rpx', color: getRoomStatusColor(item.status)}">
|
||||
{{ getRoomStatusText(item.status) }}
|
||||
</text>
|
||||
|
||||
<view class="center"
|
||||
style="width: 92rpx; height: 46rpx; background-color: #20BBA4; border-radius: 52rpx; font-size: 26rpx; color: white; position: absolute; bottom: 94rpx; right: 10rpx;">
|
||||
<!-- 预约按钮 -->
|
||||
<view class="center" @click="handleBookRoom(item)"
|
||||
:style="{
|
||||
width: '92rpx',
|
||||
height: '46rpx',
|
||||
backgroundColor: item.status === 'available' ? '#20BBA4' : '#CCCCCC',
|
||||
borderRadius: '52rpx',
|
||||
fontSize: '26rpx',
|
||||
color: 'white',
|
||||
position: 'absolute',
|
||||
bottom: '94rpx',
|
||||
right: '10rpx'
|
||||
}">
|
||||
预约
|
||||
</view>
|
||||
|
||||
<view class="row" style="align-items: center; position: absolute; left: 10rpx; bottom: 60rpx;">
|
||||
<!-- 时段说明 - 仅在showFreeTime为true时显示 -->
|
||||
<view v-if="showFreeTime" class="row" style="align-items: center; position: absolute; left: 10rpx; bottom: 60rpx;">
|
||||
<view style="width: 24rpx; height: 4rpx; background-color: #FF9901;"></view>
|
||||
<text style="font-size: 16rpx; color: #323232; margin-left: 8rpx;">已预定时段</text>
|
||||
<text style="font-size: 16rpx; color: #323232; margin-left: 8rpx;">已预定</text>
|
||||
<view style="width: 24rpx; height: 4rpx; background-color: #E6E6E6; margin-left: 22rpx;"></view>
|
||||
<text style="font-size: 16rpx; color: #323232; margin-left: 8rpx;">已预定时段</text>
|
||||
<text style="font-size: 16rpx; color: #323232; margin-left: 8rpx;">空闲</text>
|
||||
</view>
|
||||
|
||||
<view class="row" style="align-items: center; position: absolute; left: 10rpx; bottom: 14rpx;">
|
||||
|
||||
<!-- 时段占用情况 - 仅在showFreeTime为true时显示 -->
|
||||
<view v-if="showFreeTime" class="row" style="align-items: center; position: absolute; left: 10rpx; bottom: 14rpx;">
|
||||
<view class="column center" style="margin-right: 20rpx;">
|
||||
<view style="width: 70rpx; height: 4rpx; background-color: #FF9901;"></view>
|
||||
<view :style="{width: '70rpx', height: '4rpx', backgroundColor: getSlotColor(item.time_slots, 'dawn')}"></view>
|
||||
<text style="font-size: 12rpx; margin-top: 4rpx;">凌晨</text>
|
||||
</view>
|
||||
<view class="column center" style="margin-right: 20rpx;">
|
||||
<view style="width: 70rpx; height: 4rpx; background-color: #E6E6E6;"></view>
|
||||
<view :style="{width: '70rpx', height: '4rpx', backgroundColor: getSlotColor(item.time_slots, 'morning')}"></view>
|
||||
<text style="font-size: 12rpx; margin-top: 4rpx;">上午</text>
|
||||
</view>
|
||||
<view class="column center" style="margin-right: 20rpx;">
|
||||
<view style="width: 70rpx; height: 4rpx; background-color: #FF9901;"></view>
|
||||
<view :style="{width: '70rpx', height: '4rpx', backgroundColor: getSlotColor(item.time_slots, 'afternoon')}"></view>
|
||||
<text style="font-size: 12rpx; margin-top: 4rpx;">下午</text>
|
||||
</view>
|
||||
<view class="column center" style="margin-right: 20rpx;">
|
||||
<view style="width: 70rpx; height: 4rpx; background-color: #E6E6E6;"></view>
|
||||
<view :style="{width: '70rpx', height: '4rpx', backgroundColor: getSlotColor(item.time_slots, 'evening')}"></view>
|
||||
<text style="font-size: 12rpx; margin-top: 4rpx;">晚上</text>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</view>
|
||||
|
||||
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getRoomListWithTimeSlots } from '@/common/server/interface/sq.js';
|
||||
import { getBusinessHours } from '@/common/server/interface/common.js';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
currentTimeIndex: 0,
|
||||
dateList: [],
|
||||
value: false,
|
||||
roomList: [1, 2, 3, 4, 5, 6],
|
||||
showFreeTime: false, // 是否显示空闲时段
|
||||
roomList: [],
|
||||
businessHours: null, // 营业时间信息
|
||||
loading: false, // 加载状态
|
||||
}
|
||||
},
|
||||
|
||||
onLoad() {
|
||||
this.getDateList();
|
||||
this.loadBusinessHours();
|
||||
this.loadRoomList();
|
||||
},
|
||||
|
||||
methods: {
|
||||
change(e) {
|
||||
console.log('change', e);
|
||||
/**
|
||||
* 加载营业时间
|
||||
*/
|
||||
async loadBusinessHours() {
|
||||
const data = await getBusinessHours();
|
||||
if (data) {
|
||||
this.businessHours = data;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 加载房间列表
|
||||
*/
|
||||
async loadRoomList() {
|
||||
if (this.loading) return;
|
||||
|
||||
this.loading = true;
|
||||
try {
|
||||
const selectedDate = this.dateList[this.currentTimeIndex];
|
||||
const timestamp = this.dateToTimestamp(selectedDate);
|
||||
|
||||
const data = await getRoomListWithTimeSlots(timestamp, this.showFreeTime);
|
||||
if (data) {
|
||||
this.roomList = data;
|
||||
} else {
|
||||
this.roomList = [];
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载房间列表失败', error);
|
||||
uni.showToast({ title: '加载失败', icon: 'none' });
|
||||
this.roomList = [];
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 日期对象转时间戳(秒级)
|
||||
* @param {Object} dateItem 日期对象 {time: "12.6", weekday: "今天"}
|
||||
* @returns {number} 时间戳(秒)
|
||||
*/
|
||||
dateToTimestamp(dateItem) {
|
||||
const [month, day] = dateItem.time.split('.');
|
||||
const year = new Date().getFullYear();
|
||||
const date = new Date(year, month - 1, day, 0, 0, 0);
|
||||
return Math.floor(date.getTime() / 1000);
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取时段颜色
|
||||
* @param {Object} timeSlots 时段占用信息
|
||||
* @param {string} period 时段名称:dawn/morning/afternoon/evening
|
||||
* @returns {string} 颜色值
|
||||
*/
|
||||
getSlotColor(timeSlots, period) {
|
||||
if (!timeSlots || !timeSlots[period]) {
|
||||
return '#E6E6E6'; // 默认空闲颜色
|
||||
}
|
||||
return timeSlots[period].is_occupied ? '#FF9901' : '#E6E6E6';
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取房间状态文本
|
||||
* @param {string} status 状态值:available/using/unavailable
|
||||
* @returns {string} 状态文本
|
||||
*/
|
||||
getRoomStatusText(status) {
|
||||
const statusMap = {
|
||||
'available': '可预约',
|
||||
'using': '当前使用中',
|
||||
'unavailable': '不可用'
|
||||
};
|
||||
return statusMap[status] || '';
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取房间状态文本颜色
|
||||
* @param {string} status 状态值
|
||||
* @returns {string} 颜色值
|
||||
*/
|
||||
getRoomStatusColor(status) {
|
||||
const colorMap = {
|
||||
'available': '#20BBA4',
|
||||
'using': '#FF9901',
|
||||
'unavailable': '#999999'
|
||||
};
|
||||
return colorMap[status] || '#999999';
|
||||
},
|
||||
|
||||
/**
|
||||
* 处理预约按钮点击
|
||||
* @param {Object} room 房间对象
|
||||
*/
|
||||
handleBookRoom(room) {
|
||||
if (room.status !== 'available') {
|
||||
const message = room.status === 'using' ? '当前使用中,无法预约' : '房间不可用';
|
||||
uni.showToast({ title: message, icon: 'none' });
|
||||
return;
|
||||
}
|
||||
|
||||
// 跳转到预约详情页
|
||||
const dateItem = this.dateList[this.currentTimeIndex];
|
||||
uni.navigateTo({
|
||||
url: `/pages/appointment/appointment-page?roomId=${room.id}&roomName=${encodeURIComponent(room.name)}&date=${dateItem.time}`
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 切换时段显示开关
|
||||
*/
|
||||
change(value) {
|
||||
this.showFreeTime = value;
|
||||
this.loadRoomList();
|
||||
},
|
||||
|
||||
/**
|
||||
* 生成日期列表:当天+后续6天,共7天
|
||||
*/
|
||||
|
|
@ -120,7 +264,7 @@
|
|||
const day = current.getDate();
|
||||
const time = `${month}.${day}`;
|
||||
|
||||
// 2. 处理星期显示:当天显示“今天”,其他显示周几
|
||||
// 2. 处理星期显示:当天显示"今天",其他显示周几
|
||||
let weekday;
|
||||
if (i === 0) {
|
||||
weekday = "今天"; // 当天
|
||||
|
|
@ -153,8 +297,12 @@
|
|||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 点击日期切换
|
||||
*/
|
||||
clickTime(index) {
|
||||
this.currentTimeIndex = index;
|
||||
this.loadRoomList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
BIN
static/default_room.jpg
Normal file
BIN
static/default_room.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 54 KiB |
Loading…
Reference in New Issue
Block a user