From a58b4e431b60ff83fa9e66cb4d014417e5c423d9 Mon Sep 17 00:00:00 2001 From: zpc Date: Sun, 7 Dec 2025 21:17:34 +0800 Subject: [PATCH] 321 --- API接口文档_预约房间页面.md | 390 ------- common/env.js | 4 +- common/server/interface/common.js | 12 - common/server/interface/message.js | 53 + common/server/interface/sq.js | 86 +- pages/appointment/appointment-page.vue | 957 ++++++++++++---- pages/appointment/book-room-page.vue | 787 ++++++++++--- pages/me/my-message-page.vue | 120 +- .../前端对接文档_预约系统.md | 1007 +++++++++++++++++ .../我的消息页面接口参数说明.md | 197 ++++ .../消息功能前端接入说明.md | 252 +++++ 历史需求/站内信功能开发总结.md | 293 +++++ 我的收益页面接口参数说明.md | 608 ++++++++++ 收益 需求文档.md | 41 + 14 files changed, 3974 insertions(+), 833 deletions(-) delete mode 100644 API接口文档_预约房间页面.md create mode 100644 common/server/interface/message.js create mode 100644 历史需求/前端对接文档_预约系统.md create mode 100644 历史需求/我的消息页面接口参数说明.md create mode 100644 历史需求/消息功能前端接入说明.md create mode 100644 历史需求/站内信功能开发总结.md create mode 100644 我的收益页面接口参数说明.md create mode 100644 收益 需求文档.md diff --git a/API接口文档_预约房间页面.md b/API接口文档_预约房间页面.md deleted file mode 100644 index 626449e..0000000 --- a/API接口文档_预约房间页面.md +++ /dev/null @@ -1,390 +0,0 @@ -# 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/env.js b/common/env.js index 2f79dc6..b0d7375 100644 --- a/common/env.js +++ b/common/env.js @@ -9,8 +9,8 @@ const development = { // baseUrl: 'https://sqqp.zpc-xy.com', // baseUrl: 'http://1.15.21.245:2401', // host: ['https://sqqp.zpc-xy.com'], - baseUrl: 'http://192.168.1.21:2016', - host: ['http://192.168.1.21:2016'], + baseUrl: 'http://192.168.1.24:2016', + host: ['http://192.168.1.24:2016'], imageUrl: 'https://guyu-1308826010.cos.ap-shanghai.myqcloud.com', }; diff --git a/common/server/interface/common.js b/common/server/interface/common.js index 55d3bcd..fd10550 100644 --- a/common/server/interface/common.js +++ b/common/server/interface/common.js @@ -59,16 +59,4 @@ 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/message.js b/common/server/interface/message.js new file mode 100644 index 0000000..a57689e --- /dev/null +++ b/common/server/interface/message.js @@ -0,0 +1,53 @@ +import request from '@/common/system/request'; + +/** + * 获取消息列表 + * @param {number} pageIndex 页码,从1开始 + * @param {number} pageSize 每页数量 + * @param {number} messageType 消息类型:0=全部,1=私信 + * @returns {Promise} + */ +export const getMessageList = async (pageIndex = 1, pageSize = 20, messageType = 0) => { + const res = await request.getOrCache( + "sq/GetMessageList", + { pageIndex, pageSize, messageType }, + 1 // 缓存1秒 + ); + if (res.code == 0) { + return res.data || []; + } + return []; +} + +/** + * 获取未读消息数量 + * @returns {Promise} + */ +export const getUnreadCount = async () => { + const res = await request.get("sq/GetUnreadCount"); + if (res.code == 0) { + return res.data?.count || 0; + } + return 0; +} + +/** + * 标记所有消息为已读 + * @returns {Promise} + */ +export const markAllAsRead = async () => { + const res = await request.post("sq/MarkAllAsRead"); + if (res.code == 0) { + return true; + } + return false; +} + +// 导出消息接口对象 +export const messageInterface = { + getMessageList, + getUnreadCount, + markAllAsRead +} + +export default messageInterface; diff --git a/common/server/interface/sq.js b/common/server/interface/sq.js index 6e53eef..f4d6a7c 100644 --- a/common/server/interface/sq.js +++ b/common/server/interface/sq.js @@ -141,6 +141,52 @@ export const getPaymentRecords = async (pageIndex = 1, pageSize = 20) => { return null; } +/** + * 获取可选日期列表(今天+未来7天) + * @returns {Promise} [{date:时间戳(秒), dateText:"今天/明天/后天/日期", dateDisplay:"12月06日 周五"}] + */ +export const getAvailableDates = async () => { + const res = await request.get("sq/GetAvailableDates"); + if (res.code == 0) { + return res.data; + } + return null; +} + +/** + * 获取房间列表及时段状态(按时段预约版本) + * @param {number} date 预约日期 时间戳(秒) + * @param {boolean} showOnlyAvailable 是否只显示当前时段可用房间 + * @param {number} currentTimeSlot 当前时段类型(0-3),配合showOnlyAvailable使用 + * @returns {Promise} 房间列表,包含4个时段状态 + */ +export const getRoomListWithSlotsNew = async (date, showOnlyAvailable = false, currentTimeSlot = null) => { + const params = { date: date }; + if (showOnlyAvailable && currentTimeSlot !== null) { + params.showOnlyAvailable = showOnlyAvailable; + params.currentTimeSlot = currentTimeSlot; + } + const res = await request.get("sq/GetRoomListWithSlotsNew", params); + if (res.code == 0) { + return res.data; + } + return null; +} + +/** + * 获取房间详情 + * @param {number} roomId 房间ID + * @param {number} date 预约日期 时间戳(秒) + * @returns {Promise} 房间详情数据 + */ +export const getRoomDetail = async (roomId, date) => { + const res = await request.get("sq/GetRoomDetail", { roomId: roomId, date: date }); + if (res.code == 0) { + return res.data; + } + return null; +} + /** * 获取可预约的房间列表 * @param {number} startTime 开始时间 时间戳(秒) @@ -254,41 +300,6 @@ 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, @@ -299,9 +310,10 @@ export const sqInterface = { addEvaluateServices, getReputationByUser, getPaymentRecords, + getAvailableDates, + getRoomListWithSlotsNew, + getRoomDetail, getReservationRoomList, - getRoomListWithTimeSlots, - getReservationRoomListNew, addSQReservation, joinReservation, cancelReservation, diff --git a/pages/appointment/appointment-page.vue b/pages/appointment/appointment-page.vue index 20c8464..e2a6ed3 100644 --- a/pages/appointment/appointment-page.vue +++ b/pages/appointment/appointment-page.vue @@ -1,25 +1,35 @@