diff --git a/docs/api/API接口文档.md b/docs/api/API接口文档.md deleted file mode 100644 index 4e8aa1a..0000000 --- a/docs/api/API接口文档.md +++ /dev/null @@ -1,1390 +0,0 @@ -# 健身房管理系统 API 接口文档 - -> 文档编号: GYM-API-001 -> 版本: v1.0 -> 日期: 2026-02-28 -> 作者: 张翔 -> 状态: 初稿 - ---- - -## 文档修订历史 - -| 版本 | 日期 | 作者 | 修订内容 | -|------|------|------|---------| -| v1.0 | 2026-02-28 | 张翔 | 初稿 | - ---- - -## 参考文档 - -- 《健身房管理系统概要设计文档》 GYM-HLD-001 -- RESTful API 设计规范 -- JSON API 规范 - ---- - -## 一、接口规范 - -### 1.1 基础信息 - -| 项目 | 说明 | -|------|------| -| 协议 | HTTPS | -| 请求方式 | GET / POST / PUT / DELETE | -| 数据格式 | JSON | -| 字符编码 | UTF-8 | -| 时间格式 | yyyy-MM-dd HH:mm:ss | -| 时区 | Asia/Shanghai | - -### 1.2 请求头 - -``` -Content-Type: application/json -Authorization: Bearer {token} -X-Tenant-Id: {tenantId} -X-Store-Id: {storeId} -X-Request-Id: {uuid} -``` - -### 1.3 响应格式 - -```json -{ - "code": 0, - "message": "success", - "data": {}, - "timestamp": 1709123456789 -} -``` - -### 1.4 错误码定义 - -| 错误码 | 说明 | -|-------|------| -| 0 | 成功 | -| 400 | 请求参数错误 | -| 401 | 未授权 | -| 403 | 无权限 | -| 404 | 资源不存在 | -| 409 | 资源冲突 | -| 429 | 请求过于频繁 | -| 500 | 服务器内部错误 | - ---- - -## 二、会员模块 API - -### 2.1 会员信息 - -#### 2.1.1 获取会员信息 - -``` -GET /api/v1/members/{memberId} -``` - -**请求参数** - -| 参数名 | 类型 | 必填 | 说明 | -|-------|------|------|------| -| memberId | Long | 是 | 会员ID | - -**响应示例** - -```json -{ - "code": 0, - "message": "success", - "data": { - "memberId": 1001, - "memberNo": "M20260001", - "name": "张三", - "phone": "138****8888", - "avatar": "https://xxx.com/avatar.jpg", - "gender": 1, - "birthday": "1990-01-15", - "level": 2, - "levelName": "VIP会员", - "exp": 1500, - "status": 1, - "createdAt": "2026-01-01 10:00:00" - } -} -``` - -#### 2.1.2 获取会员卡列表 - -``` -GET /api/v1/members/{memberId}/cards -``` - -**响应示例** - -```json -{ - "code": 0, - "message": "success", - "data": [ - { - "cardId": 1, - "cardName": "年卡", - "cardType": 1, - "status": 1, - "validFrom": "2026-01-01", - "validTo": "2026-12-31", - "remainDays": 306, - "benefits": [ - { - "benefitId": 1, - "benefitType": 1, - "benefitName": "时长权益", - "remainValue": "306天" - } - ] - } - ] -} -``` - -#### 2.1.3 获取会员权益 - -``` -GET /api/v1/members/{memberId}/benefits -``` - -**响应示例** - -```json -{ - "code": 0, - "message": "success", - "data": { - "timeBenefits": [ - { - "benefitId": 1, - "name": "年卡", - "validFrom": "2026-01-01", - "validTo": "2026-12-31", - "remainDays": 306 - } - ], - "countBenefits": [ - { - "benefitId": 2, - "name": "私教课时包", - "totalCount": 20, - "usedCount": 5, - "remainCount": 15 - } - ], - "balanceBenefits": [ - { - "benefitId": 3, - "name": "储值账户", - "balance": 1000.00 - } - ] - } -} -``` - -### 2.2 会员二维码 - -#### 2.2.1 获取签到二维码 - -``` -GET /api/v1/members/{memberId}/qrcode -``` - -**响应示例** - -```json -{ - "code": 0, - "message": "success", - "data": { - "qrcode": "MEMBER_1001_1709123456", - "expireAt": "2026-02-28 10:35:00", - "refreshInterval": 60 - } -} -``` - ---- - -## 三、预约模块 API - -### 3.1 课程查询 - -#### 3.1.1 获取课程列表 - -``` -GET /api/v1/courses -``` - -**请求参数** - -| 参数名 | 类型 | 必填 | 说明 | -|-------|------|------|------| -| tenantId | Long | 是 | 租户ID | -| storeId | Long | 否 | 门店ID | -| type | Integer | 否 | 课程类型:1-团课 2-私教 3-线上 | -| category | String | 否 | 课程分类 | -| status | Integer | 否 | 状态:1-上架 | -| page | Integer | 否 | 页码,默认1 | -| size | Integer | 否 | 每页数量,默认20 | - -**响应示例** - -```json -{ - "code": 0, - "message": "success", - "data": { - "total": 50, - "list": [ - { - "courseId": 1, - "name": "瑜伽基础课", - "type": 1, - "category": "瑜伽", - "duration": 60, - "capacity": 20, - "difficulty": 1, - "calories": 200, - "coverImage": "https://xxx.com/course.jpg", - "price": 1, - "priceValue": 1, - "status": 1 - } - ] - } -} -``` - -#### 3.1.2 获取课程详情 - -``` -GET /api/v1/courses/{courseId} -``` - -**响应示例** - -```json -{ - "code": 0, - "message": "success", - "data": { - "courseId": 1, - "name": "瑜伽基础课", - "type": 1, - "category": "瑜伽", - "description": "适合初学者的瑜伽课程", - "duration": 60, - "capacity": 20, - "minCapacity": 5, - "difficulty": 1, - "calories": 200, - "equipment": "瑜伽垫", - "coverImage": "https://xxx.com/course.jpg", - "price": 1, - "priceType": 1, - "priceValue": 1, - "advanceDays": 7, - "cancelHours": 2, - "status": 1 - } -} -``` - -### 3.2 预约时段 - -#### 3.2.1 获取可预约时段 - -``` -GET /api/v1/slots -``` - -**请求参数** - -| 参数名 | 类型 | 必填 | 说明 | -|-------|------|------|------| -| tenantId | Long | 是 | 租户ID | -| storeId | Long | 是 | 门店ID | -| resourceType | Integer | 是 | 资源类型:1-团课 2-私教 3-场地 | -| resourceId | Long | 否 | 资源ID | -| date | Date | 是 | 日期 | -| page | Integer | 否 | 页码 | -| size | Integer | 否 | 每页数量 | - -**响应示例** - -```json -{ - "code": 0, - "message": "success", - "data": { - "total": 10, - "list": [ - { - "slotId": 1, - "resourceType": 1, - "resourceId": 1, - "resourceName": "瑜伽基础课", - "coachId": 100, - "coachName": "王教练", - "venueId": 1, - "venueName": "瑜伽室A", - "startTime": "2026-02-28 10:00:00", - "endTime": "2026-02-28 11:00:00", - "capacity": 20, - "bookedCount": 15, - "remainCount": 5, - "status": 1, - "price": 1, - "priceType": 1, - "priceValue": 1, - "bookingStart": "2026-02-21 10:00:00", - "bookingEnd": "2026-02-28 08:00:00", - "cancelDeadline": "2026-02-28 08:00:00" - } - ] - } -} -``` - -#### 3.2.2 获取时段详情 - -``` -GET /api/v1/slots/{slotId} -``` - -**响应示例** - -```json -{ - "code": 0, - "message": "success", - "data": { - "slotId": 1, - "resourceType": 1, - "resourceId": 1, - "resourceName": "瑜伽基础课", - "resourceImage": "https://xxx.com/course.jpg", - "coachId": 100, - "coachName": "王教练", - "coachAvatar": "https://xxx.com/coach.jpg", - "venueId": 1, - "venueName": "瑜伽室A", - "startTime": "2026-02-28 10:00:00", - "endTime": "2026-02-28 11:00:00", - "capacity": 20, - "bookedCount": 15, - "remainCount": 5, - "waitlistCount": 3, - "minCapacity": 5, - "status": 1, - "price": 1, - "priceType": 1, - "priceValue": 1, - "canBook": true, - "canCancel": true, - "bookingStart": "2026-02-21 10:00:00", - "bookingEnd": "2026-02-28 08:00:00", - "cancelDeadline": "2026-02-28 08:00:00" - } -} -``` - -### 3.3 预约操作 - -#### 3.3.1 创建预约 - -``` -POST /api/v1/bookings -``` - -**请求参数** - -```json -{ - "tenantId": 1, - "storeId": 1, - "memberId": 1001, - "slotId": 1, - "source": "app" -} -``` - -**响应示例** - -```json -{ - "code": 0, - "message": "预约成功", - "data": { - "bookingId": 2001, - "bookingNo": "B20260228001", - "slotId": 1, - "resourceName": "瑜伽基础课", - "coachName": "王教练", - "venueName": "瑜伽室A", - "startTime": "2026-02-28 10:00:00", - "endTime": "2026-02-28 11:00:00", - "status": 1, - "priceType": 1, - "priceValue": 1, - "benefitDeducted": { - "benefitId": 1, - "benefitType": 1, - "benefitName": "年卡", - "deductedValue": "1次" - }, - "cancelDeadline": "2026-02-28 08:00:00" - } -} -``` - -#### 3.3.2 取消预约 - -``` -POST /api/v1/bookings/{bookingId}/cancel -``` - -**请求参数** - -```json -{ - "reason": "临时有事" -} -``` - -**响应示例** - -```json -{ - "code": 0, - "message": "取消成功", - "data": { - "bookingId": 2001, - "status": 2, - "refundAmount": 0, - "refundBenefit": { - "benefitId": 1, - "refundValue": "1次" - } - } -} -``` - -#### 3.3.3 获取预约列表 - -``` -GET /api/v1/bookings -``` - -**请求参数** - -| 参数名 | 类型 | 必填 | 说明 | -|-------|------|------|------| -| memberId | Long | 是 | 会员ID | -| status | Integer | 否 | 状态:1-已预约 2-已取消 3-已完成 | -| startDate | Date | 否 | 开始日期 | -| endDate | Date | 否 | 结束日期 | -| page | Integer | 否 | 页码 | -| size | Integer | 否 | 每页数量 | - -**响应示例** - -```json -{ - "code": 0, - "message": "success", - "data": { - "total": 25, - "list": [ - { - "bookingId": 2001, - "bookingNo": "B20260228001", - "resourceType": 1, - "resourceName": "瑜伽基础课", - "coachName": "王教练", - "venueName": "瑜伽室A", - "startTime": "2026-02-28 10:00:00", - "endTime": "2026-02-28 11:00:00", - "status": 1, - "checkinStatus": 0, - "canCancel": true, - "cancelDeadline": "2026-02-28 08:00:00" - } - ] - } -} -``` - -#### 3.3.4 获取预约详情 - -``` -GET /api/v1/bookings/{bookingId} -``` - -**响应示例** - -```json -{ - "code": 0, - "message": "success", - "data": { - "bookingId": 2001, - "bookingNo": "B20260228001", - "memberId": 1001, - "memberName": "张三", - "memberPhone": "138****8888", - "slotId": 1, - "resourceType": 1, - "resourceId": 1, - "resourceName": "瑜伽基础课", - "resourceImage": "https://xxx.com/course.jpg", - "coachId": 100, - "coachName": "王教练", - "coachAvatar": "https://xxx.com/coach.jpg", - "venueId": 1, - "venueName": "瑜伽室A", - "startTime": "2026-02-28 10:00:00", - "endTime": "2026-02-28 11:00:00", - "status": 1, - "checkinStatus": 0, - "checkinAt": null, - "priceType": 1, - "priceValue": 1, - "benefitId": 1, - "source": "app", - "createdAt": "2026-02-25 10:00:00", - "cancelDeadline": "2026-02-28 08:00:00", - "canCancel": true, - "canCheckin": true - } -} -``` - -### 3.4 候补队列 - -#### 3.4.1 加入候补 - -``` -POST /api/v1/waitlist -``` - -**请求参数** - -```json -{ - "tenantId": 1, - "memberId": 1001, - "slotId": 1 -} -``` - -**响应示例** - -```json -{ - "code": 0, - "message": "加入候补成功", - "data": { - "waitlistId": 1, - "slotId": 1, - "queueNo": 4, - "estimatedWaitTime": "约30分钟" - } -} -``` - -#### 3.4.2 取消候补 - -``` -DELETE /api/v1/waitlist/{waitlistId} -``` - -**响应示例** - -```json -{ - "code": 0, - "message": "取消候补成功" -} -``` - ---- - -## 四、签到模块 API - -### 4.1 签到操作 - -#### 4.1.1 二维码签到 - -``` -POST /api/v1/checkin/qrcode -``` - -**请求参数** - -```json -{ - "tenantId": 1, - "storeId": 1, - "qrcode": "MEMBER_1001_1709123456", - "deviceId": 1, - "type": 1, - "bookingId": null -} -``` - -**响应示例** - -```json -{ - "code": 0, - "message": "签到成功", - "data": { - "checkinId": 1001, - "memberId": 1001, - "memberName": "张三", - "memberPhone": "138****8888", - "memberLevel": "VIP会员", - "checkinType": "入场签到", - "checkinTime": "2026-02-28 10:30:00", - "benefitDeducted": { - "type": "时长权益", - "value": "年卡有效期至2026-12-31" - }, - "warnings": [] - } -} -``` - -#### 4.1.2 人脸识别签到 - -``` -POST /api/v1/checkin/face -``` - -**请求参数** - -```json -{ - "tenantId": 1, - "storeId": 1, - "faceFeature": "base64_encoded_feature", - "deviceId": 1, - "type": 1, - "bookingId": null -} -``` - -**响应示例** - -```json -{ - "code": 0, - "message": "签到成功", - "data": { - "checkinId": 1002, - "memberId": 1001, - "memberName": "张三", - "memberPhone": "138****8888", - "memberLevel": "VIP会员", - "checkinType": "入场签到", - "checkinTime": "2026-02-28 10:31:00", - "benefitDeducted": { - "type": "时长权益", - "value": "年卡有效期至2026-12-31" - }, - "warnings": [] - } -} -``` - -#### 4.1.3 NFC签到 - -``` -POST /api/v1/checkin/nfc -``` - -**请求参数** - -```json -{ - "tenantId": 1, - "storeId": 1, - "nfcId": "NFC_CARD_1001", - "deviceId": 1, - "type": 1, - "bookingId": null -} -``` - -**响应示例** - -```json -{ - "code": 0, - "message": "签到成功", - "data": { - "checkinId": 1003, - "memberId": 1001, - "memberName": "张三", - "memberPhone": "138****8888", - "memberLevel": "VIP会员", - "checkinType": "入场签到", - "checkinTime": "2026-02-28 10:32:00", - "benefitDeducted": { - "type": "时长权益", - "value": "年卡有效期至2026-12-31" - }, - "warnings": [] - } -} -``` - -#### 4.1.4 教练代签 - -``` -POST /api/v1/checkin/manual -``` - -**请求参数** - -```json -{ - "tenantId": 1, - "storeId": 1, - "memberId": 1001, - "bookingId": 2001, - "operatorId": 100, - "operatorName": "李教练", - "remark": "会员已到场" -} -``` - -**响应示例** - -```json -{ - "code": 0, - "message": "代签成功", - "data": { - "checkinId": 1004, - "memberId": 1001, - "memberName": "张三", - "checkinType": "私教签到", - "checkinTime": "2026-02-28 10:33:00", - "operatorName": "李教练" - } -} -``` - -### 4.2 人脸管理 - -#### 4.2.1 注册人脸 - -``` -POST /api/v1/face/register -Content-Type: multipart/form-data -``` - -**请求参数** - -| 参数名 | 类型 | 必填 | 说明 | -|-------|------|------|------| -| memberId | Long | 是 | 会员ID | -| faceImage | File | 是 | 人脸照片 | - -**响应示例** - -```json -{ - "code": 0, - "message": "人脸注册成功", - "data": { - "faceId": 1, - "qualityScore": 95.5, - "status": "正常" - } -} -``` - -#### 4.2.2 更新人脸 - -``` -PUT /api/v1/face/{memberId} -Content-Type: multipart/form-data -``` - -**请求参数** - -| 参数名 | 类型 | 必填 | 说明 | -|-------|------|------|------| -| faceImage | File | 是 | 人脸照片 | - -**响应示例** - -```json -{ - "code": 0, - "message": "人脸更新成功", - "data": { - "faceId": 1, - "qualityScore": 96.2, - "status": "正常" - } -} -``` - -#### 4.2.3 删除人脸 - -``` -DELETE /api/v1/face/{memberId} -``` - -**响应示例** - -```json -{ - "code": 0, - "message": "人脸删除成功" -} -``` - -### 4.3 签到记录 - -#### 4.3.1 查询签到记录 - -``` -GET /api/v1/checkin/records -``` - -**请求参数** - -| 参数名 | 类型 | 必填 | 说明 | -|-------|------|------|------| -| memberId | Long | 是 | 会员ID | -| startDate | Date | 否 | 开始日期 | -| endDate | Date | 否 | 结束日期 | -| type | Integer | 否 | 签到类型 | -| page | Integer | 否 | 页码 | -| size | Integer | 否 | 每页数量 | - -**响应示例** - -```json -{ - "code": 0, - "message": "success", - "data": { - "total": 25, - "list": [ - { - "checkinId": 1001, - "type": "入场签到", - "method": "二维码", - "checkinTime": "2026-02-28 10:30:00", - "storeName": "中关村店", - "status": "成功" - }, - { - "checkinId": 1002, - "type": "课程签到", - "method": "人脸识别", - "checkinTime": "2026-02-27 19:00:00", - "courseName": "瑜伽课", - "coachName": "王教练", - "status": "成功" - } - ] - } -} -``` - -#### 4.3.2 查询签到统计 - -``` -GET /api/v1/checkin/statistics -``` - -**请求参数** - -| 参数名 | 类型 | 必填 | 说明 | -|-------|------|------|------| -| tenantId | Long | 是 | 租户ID | -| storeId | Long | 否 | 门店ID | -| startDate | Date | 是 | 开始日期 | -| endDate | Date | 是 | 结束日期 | - -**响应示例** - -```json -{ - "code": 0, - "message": "success", - "data": { - "totalCount": 1500, - "entryCount": 800, - "courseCount": 500, - "privateCount": 150, - "activityCount": 50, - "activeMemberCount": 350, - "newMemberCount": 25, - "peakHour": 19, - "peakCount": 120, - "avgDuration": 90, - "dailyTrend": [ - {"date": "2026-02-01", "count": 50}, - {"date": "2026-02-02", "count": 55} - ] - } -} -``` - -### 4.4 设备管理 - -#### 4.4.1 设备心跳 - -``` -POST /api/v1/device/heartbeat -``` - -**请求参数** - -```json -{ - "deviceId": 1, - "deviceCode": "DEVICE_001", - "status": 1, - "timestamp": "2026-02-28T10:30:00" -} -``` - -**响应示例** - -```json -{ - "code": 0, - "message": "success" -} -``` - -#### 4.4.2 设备列表 - -``` -GET /api/v1/device/list -``` - -**请求参数** - -| 参数名 | 类型 | 必填 | 说明 | -|-------|------|------|------| -| tenantId | Long | 是 | 租户ID | -| storeId | Long | 否 | 门店ID | - -**响应示例** - -```json -{ - "code": 0, - "message": "success", - "data": [ - { - "deviceId": 1, - "name": "前台人脸机", - "code": "DEVICE_001", - "type": "人脸识别机", - "location": "前台入口", - "status": "在线", - "lastHeartbeat": "2026-02-28 10:30:00" - } - ] -} -``` - ---- - -## 五、场地模块 API - -### 5.1 场地查询 - -#### 5.1.1 获取场地列表 - -``` -GET /api/v1/venues -``` - -**请求参数** - -| 参数名 | 类型 | 必填 | 说明 | -|-------|------|------|------| -| tenantId | Long | 是 | 租户ID | -| storeId | Long | 是 | 门店ID | -| type | Integer | 否 | 场地类型 | -| status | Integer | 否 | 状态 | - -**响应示例** - -```json -{ - "code": 0, - "message": "success", - "data": { - "total": 10, - "list": [ - { - "venueId": 1, - "name": "瑜伽室A", - "type": 1, - "typeName": "瑜伽室", - "area": 100.5, - "capacity": 25, - "openTime": "07:00", - "closeTime": "22:00", - "pricePerHour": 100.00, - "status": 1, - "images": [ - "https://xxx.com/venue1.jpg", - "https://xxx.com/venue2.jpg" - ] - } - ] - } -} -``` - -#### 5.1.2 获取场地可用时段 - -``` -GET /api/v1/venues/{venueId}/slots -``` - -**请求参数** - -| 参数名 | 类型 | 必填 | 说明 | -|-------|------|------|------| -| date | Date | 是 | 日期 | - -**响应示例** - -```json -{ - "code": 0, - "message": "success", - "data": [ - { - "slotId": 1, - "startTime": "2026-02-28 10:00:00", - "endTime": "2026-02-28 11:00:00", - "status": 1, - "price": 100.00 - } - ] -} -``` - ---- - -## 六、教练模块 API - -### 6.1 教练查询 - -#### 6.1.1 获取教练列表 - -``` -GET /api/v1/coaches -``` - -**请求参数** - -| 参数名 | 类型 | 必填 | 说明 | -|-------|------|------|------| -| tenantId | Long | 是 | 租户ID | -| storeId | Long | 否 | 门店ID | -| specialty | String | 否 | 专长 | -| status | Integer | 否 | 状态 | - -**响应示例** - -```json -{ - "code": 0, - "message": "success", - "data": { - "total": 20, - "list": [ - { - "coachId": 100, - "name": "王教练", - "avatar": "https://xxx.com/coach.jpg", - "gender": 1, - "specialty": "瑜伽,普拉提", - "experience": 5, - "rating": 4.8, - "courseCount": 120, - "status": 1 - } - ] - } -} -``` - -#### 6.1.2 获取教练可预约时段 - -``` -GET /api/v1/coaches/{coachId}/slots -``` - -**请求参数** - -| 参数名 | 类型 | 必填 | 说明 | -|-------|------|------|------| -| date | Date | 是 | 日期 | - -**响应示例** - -```json -{ - "code": 0, - "message": "success", - "data": [ - { - "slotId": 1, - "startTime": "2026-02-28 10:00:00", - "endTime": "2026-02-28 11:00:00", - "status": 1, - "price": 300.00 - } - ] -} -``` - ---- - -## 七、数据统计 API - -### 7.1 运营数据 - -#### 7.1.1 获取运营概览 - -``` -GET /api/v1/statistics/overview -``` - -**请求参数** - -| 参数名 | 类型 | 必填 | 说明 | -|-------|------|------|------| -| tenantId | Long | 是 | 租户ID | -| storeId | Long | 否 | 门店ID | -| date | Date | 是 | 日期 | - -**响应示例** - -```json -{ - "code": 0, - "message": "success", - "data": { - "date": "2026-02-28", - "memberStats": { - "totalMembers": 1500, - "newMembers": 25, - "activeMembers": 350, - "activeRate": 23.3 - }, - "checkinStats": { - "totalCount": 500, - "entryCount": 300, - "courseCount": 150, - "privateCount": 50 - }, - "bookingStats": { - "totalCount": 200, - "successCount": 180, - "cancelCount": 20, - "successRate": 90.0 - }, - "revenueStats": { - "totalRevenue": 50000.00, - "courseRevenue": 30000.00, - "privateRevenue": 15000.00, - "otherRevenue": 5000.00 - } - } -} -``` - -#### 7.1.2 获取趋势数据 - -``` -GET /api/v1/statistics/trend -``` - -**请求参数** - -| 参数名 | 类型 | 必填 | 说明 | -|-------|------|------|------| -| tenantId | Long | 是 | 租户ID | -| storeId | Long | 否 | 门店ID | -| startDate | Date | 是 | 开始日期 | -| endDate | Date | 是 | 结束日期 | -| metric | String | 是 | 指标:checkin/booking/revenue | - -**响应示例** - -```json -{ - "code": 0, - "message": "success", - "data": { - "metric": "checkin", - "trend": [ - {"date": "2026-02-01", "value": 450}, - {"date": "2026-02-02", "value": 480}, - {"date": "2026-02-03", "value": 520} - ], - "total": 1450, - "average": 483.3, - "max": 520, - "min": 450 - } -} -``` - ---- - -## 八、消息通知 API - -### 8.1 通知管理 - -#### 8.1.1 获取通知列表 - -``` -GET /api/v1/notifications -``` - -**请求参数** - -| 参数名 | 类型 | 必填 | 说明 | -|-------|------|------|------| -| memberId | Long | 是 | 会员ID | -| type | Integer | 否 | 通知类型 | -| isRead | Boolean | 否 | 是否已读 | -| page | Integer | 否 | 页码 | -| size | Integer | 否 | 每页数量 | - -**响应示例** - -```json -{ - "code": 0, - "message": "success", - "data": { - "total": 50, - "unreadCount": 10, - "list": [ - { - "notificationId": 1, - "type": 1, - "typeName": "预约提醒", - "title": "课程预约成功", - "content": "您已成功预约瑜伽基础课,时间为2026-02-28 10:00-11:00", - "isRead": false, - "createdAt": "2026-02-25 10:00:00" - } - ] - } -} -``` - -#### 8.1.2 标记通知已读 - -``` -PUT /api/v1/notifications/{notificationId}/read -``` - -**响应示例** - -```json -{ - "code": 0, - "message": "success" -} -``` - -#### 8.1.3 全部标记已读 - -``` -PUT /api/v1/notifications/read-all -``` - -**请求参数** - -```json -{ - "memberId": 1001 -} -``` - -**响应示例** - -```json -{ - "code": 0, - "message": "success" -} -``` - ---- - -## 九、错误响应示例 - -### 9.1 参数错误 - -```json -{ - "code": 400, - "message": "参数错误: memberId不能为空", - "data": null, - "timestamp": 1709123456789 -} -``` - -### 9.2 未授权 - -```json -{ - "code": 401, - "message": "未授权,请先登录", - "data": null, - "timestamp": 1709123456789 -} -``` - -### 9.3 业务异常 - -```json -{ - "code": 400, - "message": "预约失败:课程已满", - "data": { - "errorCode": "SLOT_FULL", - "errorDetail": "当前时段已预约满,请选择其他时段" - }, - "timestamp": 1709123456789 -} -``` - ---- - -## 十、版本历史 - -| 版本 | 日期 | 作者 | 变更内容 | -|------|------|------|---------| -| v1.0 | 2026-02-28 | 张翔 | 初稿 | diff --git a/docs/design/HLD-系统概要设计.md b/docs/design/HLD-系统概要设计.md index 1ac8fc3..1042258 100644 --- a/docs/design/HLD-系统概要设计.md +++ b/docs/design/HLD-系统概要设计.md @@ -1,8 +1,8 @@ -# 健身房管理系统概要设计文档(HLD) +# 健身房管理系统业务概要设计文档(HLD) > 文档编号: GYM-HLD-001 > 版本: v1.0 -> 日期: 2026-02-28 +> 日期: 2026-03-04 > 作者: 张翔 > 状态: 初稿 @@ -10,9 +10,9 @@ ## 文档修订历史 -| 版本 | 日期 | 作者 | 修订内容 | -| ---- | ---------- | ---- | -------- | -| v1.0 | 2026-02-28 | 张翔 | 初稿 | +| 版本 | 日期 | 作者 | 修订内容 | +| ---- | ---------- | ---- | ------------------ | +| v1.0 | 2026-03-04 | 张翔 | 重构为业务概要设计 | --- @@ -20,11 +20,11 @@ ### 1.1 编写目的 -本文档为健身房管理系统的概要设计文档(High-Level Design),旨在: +本文档为健身房管理系统的业务概要设计文档(High-Level Design),旨在: -1. 从总体上描述系统的技术架构、模块划分、接口设计 -2. 为详细设计提供指导和约束 -3. 作为开发人员、测试人员、运维人员的技术参考 +1. 从业务层面描述系统的业务范围、业务流程、业务规则 +2. 为详细设计提供业务指导和约束 +3. 作为产品经理、业务分析师、开发人员的业务参考 ### 1.2 项目背景 @@ -48,22 +48,19 @@ ### 1.4 参考文档 - 《健身房管理系统产品设计文档》 GYM-PRD-001 -- Spring Boot 3 官方文档 -- R2DBC 规范文档 -- PostgreSQL 官方文档 --- -## 二、系统概述 +## 二、业务概述 -### 2.1 系统目标 +### 2.1 业务目标 -| 目标 | 描述 | 度量标准 | -| ------ | -------------------------- | ---------------- | -| 高可用 | 系统稳定运行,故障快速恢复 | SLA ≥ 99.9% | -| 高并发 | 支撑热门课程抢课场景 | QPS ≥ 1000 | -| 可扩展 | 支持功能模块渐进式扩展 | 模块化设计 | -| 易维护 | 代码规范,文档完善 | 代码覆盖率 ≥ 80% | +| 目标维度 | 目标描述 | 成功指标 | +| -------- | ---------------------- | -------------------------------- | +| 用户体验 | 提升会员预约和签到体验 | 预约成功率 ≥ 95%,签到耗时 ≤ 3秒 | +| 运营效率 | 降低人工操作成本 | 人工处理时间减少 50% | +| 数据价值 | 提供数据驱动决策支持 | 数据报表使用率 ≥ 80% | +| 业务扩展 | 支持多业态灵活适配 | 支持至少3种业态场景 | ### 2.2 用户角色 @@ -143,850 +140,542 @@ --- -## 三、系统架构设计 +## 三、核心业务流程 -### 3.1 总体架构 - -采用分层架构 + 微服务思想的模块化设计: +### 3.1 会员注册与入会流程 ``` ┌─────────────────────────────────────────────────────────────────────────┐ -│ 总体架构 │ +│ 会员注册与入会流程 │ ├─────────────────────────────────────────────────────────────────────────┤ │ │ -│ ┌─────────────────────────────────────────────────────────────────┐ │ -│ │ 客户端层 │ │ -│ ├─────────────────────────────────────────────────────────────────┤ │ -│ │ • 会员小程序 (uniapp+Vue3) │ │ -│ │ • 教练端App (uniapp+Vue3) │ │ -│ │ • 管理后台PC (Vue3+Vite) │ │ -│ │ • 硬件设备 (人脸/NFC) │ │ -│ └─────────────────────────────────────────────────────────────────┘ │ -│ │ │ -│ ▼ │ -│ ┌─────────────────────────────────────────────────────────────────┐ │ -│ │ API Gateway 统一网关 │ │ -│ ├─────────────────────────────────────────────────────────────────┤ │ -│ │ • 路由转发 • 认证鉴权 • 限流熔断 • 日志追踪 │ │ -│ └─────────────────────────────────────────────────────────────────┘ │ -│ │ │ -│ ▼ │ -│ ┌─────────────────────────────────────────────────────────────────┐ │ -│ │ 业务层 │ │ -│ ├─────────────────────────────────────────────────────────────────┤ │ -│ │ • 会员服务 (Member Service) │ │ -│ │ • 预约服务 (Booking Service) │ │ -│ │ • 数据服务 (Data Service) │ │ -│ └─────────────────────────────────────────────────────────────────┘ │ -│ │ │ -│ ▼ │ -│ ┌─────────────────────────────────────────────────────────────────┐ │ -│ │ 公共服务层 │ │ -│ ├─────────────────────────────────────────────────────────────────┤ │ -│ │ • 认证服务 • 消息服务 • 文件服务 • 缓存服务 │ │ -│ └─────────────────────────────────────────────────────────────────┘ │ -│ │ │ -│ ▼ │ -│ ┌─────────────────────────────────────────────────────────────────┐ │ -│ │ 基础设施层 │ │ -│ ├─────────────────────────────────────────────────────────────────┤ │ -│ │ • PostgreSQL • R2DBC • Caffeine • Redis(可选) │ │ -│ └─────────────────────────────────────────────────────────────────┘ │ -│ │ │ -│ ▼ │ -│ ┌─────────────────────────────────────────────────────────────────┐ │ -│ │ 外部服务层 │ │ -│ ├─────────────────────────────────────────────────────────────────┤ │ -│ │ • 微信开放平台 • 短信服务 • 支付服务 • OSS存储 │ │ -│ └─────────────────────────────────────────────────────────────────┘ │ +│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ +│ │ 新用户 │────▶│ 手机号 │────▶│ 验证码 │────▶│ 注册 │ │ +│ │ 访问 │ │ 输入 │ │ 验证 │ │ 成功 │ │ +│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ +│ │ │ +│ ▼ │ +│ ┌──────────┐ │ +│ │ 信息 │ │ +│ │ 完善 │ │ +│ └──────────┘ │ +│ │ │ +│ ▼ │ +│ ┌──────────┐ │ +│ │ 购买 │ │ +│ │ 会员卡 │ │ +│ └──────────┘ │ +│ │ │ +│ ▼ │ +│ ┌──────────┐ │ +│ │ 入会 │ │ +│ │ 完成 │ │ +│ └──────────┘ │ +│ │ +│ 业务规则: │ +│ • 手机号必须唯一,一个手机号只能注册一个会员 │ +│ • 验证码有效期60秒,同一手机号60秒内只能发送一次 │ +│ • 会员信息完善后才能购买会员卡 │ +│ • 会员卡购买成功后立即生效,权益即时可用 │ │ │ └─────────────────────────────────────────────────────────────────────────┘ ``` -### 3.2 技术架构 +### 3.2 课程预约流程 ``` ┌─────────────────────────────────────────────────────────────────────────┐ -│ 技术架构 │ +│ 课程预约流程 │ ├─────────────────────────────────────────────────────────────────────────┤ │ │ -│ ┌─────────────────────────────────────────────────────────────────┐ │ -│ │ 表现层 Presentation │ │ -│ ├─────────────────────────────────────────────────────────────────┤ │ -│ │ • 会员端 uniapp (Vue3 + TS + Pinia + uni-ui) │ │ -│ │ • 教练端 uniapp (Vue3 + TS + Pinia + uni-ui) │ │ -│ │ • 管理后台 Vue3 (Vue3 + TS + Pinia + Element Plus) │ │ -│ └─────────────────────────────────────────────────────────────────┘ │ -│ │ │ -│ ▼ │ -│ ┌─────────────────────────────────────────────────────────────────┐ │ -│ │ 网关层 Gateway │ │ -│ ├─────────────────────────────────────────────────────────────────┤ │ -│ │ Spring Cloud Gateway (路由转发/认证鉴权/限流熔断/日志追踪/灰度发布) │ │ -│ └─────────────────────────────────────────────────────────────────┘ │ -│ │ │ -│ ▼ │ -│ ┌─────────────────────────────────────────────────────────────────┐ │ -│ │ 业务层 Business │ │ -│ ├─────────────────────────────────────────────────────────────────┤ │ -│ │ Spring Boot 3 + WebFlux + JDK 21 │ │ -│ │ • Controller (API) • Service (业务逻辑) │ │ -│ │ • Repository (数据访问) • Model (领域模型) │ │ -│ └─────────────────────────────────────────────────────────────────┘ │ -│ │ │ -│ ▼ │ -│ ┌─────────────────────────────────────────────────────────────────┐ │ -│ │ 数据层 Data │ │ -│ ├─────────────────────────────────────────────────────────────────┤ │ -│ │ • PostgreSQL (R2DBC + Flyway) │ │ -│ │ • Caffeine (本地缓存 + 热点数据) │ │ -│ │ • Redis可选 (分布式缓存 + 分布式锁) │ │ -│ └─────────────────────────────────────────────────────────────────┘ │ +│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ +│ │ 会员 │────▶│ 浏览 │────▶│ 选择 │────▶│ 确认 │ │ +│ │ 登录 │ │ 课程 │ │ 时段 │ │ 预约 │ │ +│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ +│ │ │ +│ ▼ │ +│ ┌──────────┐ │ +│ │ 权益 │ │ +│ │ 检查 │ │ +│ └──────────┘ │ +│ │ │ +│ ┌────────────┴────────┐ │ +│ ▼ ▼ │ +│ ┌──────────┐ ┌──────────┐ │ +│ │ 预约 │ │ 提示 │ │ +│ │ 成功 │ │ 失败 │ │ +│ └──────────┘ └──────────┘ │ +│ │ +│ 业务规则: │ +│ • 会员必须拥有足够的权益才能预约(次数、时长、储值等) │ +│ • 同一时段只能预约一个课程,预约冲突时提示用户 │ +│ • 预约成功后发送通知(微信、短信) │ +│ • 预约取消时间限制:开课前2小时内不能取消 │ +│ • 热门课程支持候补机制,满员后自动进入候补队列 │ │ │ └─────────────────────────────────────────────────────────────────────────┘ ``` -### 3.3 部署架构 +### 3.3 签到流程 ``` ┌─────────────────────────────────────────────────────────────────────────┐ -│ 部署架构 │ +│ 签到流程 │ ├─────────────────────────────────────────────────────────────────────────┤ │ │ -│ ┌─────────────────────────────────────────────────────────────────┐ │ -│ │ 负载均衡器 (Nginx/ALB) │ │ -│ └─────────────────────────────────────────────────────────────────┘ │ -│ │ │ -│ ▼ │ -│ ┌─────────────────────────────────────────────────────────────────┐ │ -│ │ API Gateway 集群 │ │ -│ ├─────────────────────────────────────────────────────────────────┤ │ -│ │ • API Gateway 实例1 • API Gateway 实例2 • API Gateway 实例N │ │ -│ └─────────────────────────────────────────────────────────────────┘ │ -│ │ │ -│ ▼ │ -│ ┌─────────────────────────────────────────────────────────────────┐ │ -│ │ 应用服务集群 │ │ -│ ├─────────────────────────────────────────────────────────────────┤ │ -│ │ • 应用服务 实例1 • 应用服务 实例2 • 应用服务 实例N │ │ -│ └─────────────────────────────────────────────────────────────────┘ │ -│ │ │ -│ ┌───────────────┴───────────────┐ │ -│ ▼ ▼ │ -│ ┌─────────────────────────┐ ┌─────────────────────────┐ │ -│ │ PostgreSQL 数据库层 │ │ Redis 缓存层 │ │ -│ ├─────────────────────────┤ ├─────────────────────────┤ │ -│ │ • 主库 │ │ • 主节点 │ │ -│ │ • 从库1 (主从复制) │ │ • 从节点1 (主从复制) │ │ -│ │ • 从库N (主从复制) │ │ • 从节点N (主从复制) │ │ -│ └─────────────────────────┘ └─────────────────────────┘ │ +│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ +│ │ 会员 │────▶│ 到达 │────▶│ 选择 │────▶│ 验证 │ │ +│ │ 到达 │ │ 门店 │ │ 签到方式│ │ 身份 │ │ +│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ +│ │ │ +│ ┌────────────┴────────┐ │ +│ ▼ ▼ │ +│ ┌──────────┐ ┌──────────┐ │ +│ │ 扫码 │ │ 刷脸 │ │ +│ │ 签到 │ │ 签到 │ │ +│ └──────────┘ └──────────┘ │ +│ │ │ │ +│ └──────────┬──────────┘ │ +│ ▼ │ +│ ┌──────────┐ │ +│ │ 预约 │ │ +│ │ 检查 │ │ +│ └──────────┘ │ +│ │ │ +│ ┌────────────┴────────┐ │ +│ ▼ ▼ │ +│ ┌──────────┐ ┌──────────┐ │ +│ │ 签到 │ │ 手动 │ │ +│ │ 成功 │ │ 处理 │ │ +│ └──────────┘ └──────────┘ │ +│ │ +│ 业务规则: │ +│ • 签到时验证会员身份和预约信息 │ +│ • 有预约的会员优先签到,自动扣减权益 │ +│ • 无预约的会员可以临时签到,需前台确认 │ +│ • 签到成功后记录签到时间、设备信息 │ +│ • 支持教练代签,教练可以确认学员签到 │ +│ • 签到失败时提供明确的错误提示(如:预约不存在、权益不足) │ +│ │ +└─────────────────────────────────────────────────────────────────────────┘ +``` + +### 3.4 会员卡购买与激活流程 + +``` +┌─────────────────────────────────────────────────────────────────────────┐ +│ 会员卡购买与激活流程 │ +├─────────────────────────────────────────────────────────────────────────┤ +│ │ +│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ +│ │ 会员 │────▶│ 浏览 │────▶│ 选择 │────▶│ 支付 │ │ +│ │ 登录 │ │ 会员卡 │ │ 卡类型 │ │ 订单 │ │ +│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ +│ │ │ +│ ▼ │ +│ ┌──────────┐ │ +│ │ 支付 │ │ +│ │ 成功 │ │ +│ └──────────┘ │ +│ │ │ +│ ▼ │ +│ ┌──────────┐ │ +│ │ 会员卡 │ │ +│ │ 激活 │ │ +│ └──────────┘ │ +│ │ │ +│ ▼ │ +│ ┌──────────┐ │ +│ │ 权益 │ │ +│ │ 到账 │ │ +│ └──────────┘ │ +│ │ +│ 业务规则: │ +│ • 会员卡类型包括:时长卡、次卡、储值卡、等级卡 │ +│ • 支付成功后会员卡立即激活,权益即时到账 │ +│ • 会员卡有效期从激活日开始计算 │ +│ • 支持会员卡转让功能(可选,需店长审批) │ +│ • 会员卡到期前7天发送提醒通知 │ +│ • 支持会员卡续费,续费后权益累加 │ │ │ └─────────────────────────────────────────────────────────────────────────┘ ``` --- -## 四、模块设计 +## 四、业务规则 -### 4.1 模块划分 +### 4.1 会员管理规则 -``` -┌─────────────────────────────────────────────────────────────────────────┐ -│ gym-manage-server 父工程 │ -├─────────────────────────────────────────────────────────────────────────┤ -│ │ -│ ┌─────────────────────────────────────────────────────────────────┐ │ -│ │ gym-common 公共模块 │ │ -│ ├─────────────────────────────────────────────────────────────────┤ │ -│ │ • gym-common-core (核心工具类、常量、枚举) │ │ -│ │ • gym-common-redis (Redis配置可选) │ │ -│ │ • gym-common-security (安全认证公共组件) │ │ -│ │ • gym-common-log (日志公共组件) │ │ -│ └─────────────────────────────────────────────────────────────────┘ │ -│ │ -│ ┌─────────────────────────────────────────────────────────────────┐ │ -│ │ gym-api API网关模块 │ │ -│ ├─────────────────────────────────────────────────────────────────┤ │ -│ │ • controller (HTTP接口) • dto (数据传输对象) │ │ -│ │ • vo (视图对象) • config (API配置) │ │ -│ └─────────────────────────────────────────────────────────────────┘ │ -│ │ -│ ┌─────────────────────────────────────────────────────────────────┐ │ -│ │ gym-service 业务服务模块 │ │ -│ ├─────────────────────────────────────────────────────────────────┤ │ -│ │ • gym-service-member (会员服务) │ │ -│ │ • gym-service-booking (预约服务) │ │ -│ │ • gym-service-checkin (签到服务) │ │ -│ │ • gym-service-course (课程服务) │ │ -│ │ • gym-service-coach (教练服务) │ │ -│ │ • gym-service-finance (财务服务) │ │ -│ │ • gym-service-data (数据服务) │ │ -│ └─────────────────────────────────────────────────────────────────┘ │ -│ │ -│ ┌─────────────────────────────────────────────────────────────────┐ │ -│ │ gym-domain 领域模型模块 │ │ -│ ├─────────────────────────────────────────────────────────────────┤ │ -│ │ • model (领域模型) • event (领域事件) • service (领域服务) │ │ -│ └─────────────────────────────────────────────────────────────────┘ │ -│ │ -│ ┌─────────────────────────────────────────────────────────────────┐ │ -│ │ gym-infrastructure 基础设施模块 │ │ -│ ├─────────────────────────────────────────────────────────────────┤ │ -│ │ • repository (数据仓储) • cache (缓存配置) │ │ -│ │ • external (外部服务集成) • config (基础配置) │ │ -│ └─────────────────────────────────────────────────────────────────┘ │ -│ │ -│ ┌─────────────────────────────────────────────────────────────────┐ │ -│ │ gym-starter 启动模块 │ │ -│ ├─────────────────────────────────────────────────────────────────┤ │ -│ │ • gym-admin (管理后台启动器) │ │ -│ └─────────────────────────────────────────────────────────────────┘ │ -│ │ -└─────────────────────────────────────────────────────────────────────────┘ -``` +#### 4.1.1 会员注册规则 -### 4.2 模块职责 +- 手机号必须唯一,一个手机号只能注册一个会员 +- 验证码有效期60秒,同一手机号60秒内只能发送一次 +- 会员信息完善后才能购买会员卡 +- 支持微信一键登录,自动关联手机号 -| 模块 | 职责 | 依赖 | -| ------------------- | ---------------------------------- | ------------------------------ | -| gym-common-core | 提供通用工具类、常量定义、异常处理 | 无 | -| gym-common-security | 提供JWT认证、权限校验 | gym-common-core | -| gym-common-log | 提供统一日志处理 | gym-common-core | -| gym-domain | 定义领域模型、领域事件、领域服务 | gym-common-core | -| gym-infrastructure | 提供数据访问、缓存、外部服务集成 | gym-domain | -| gym-service-member | 会员、会员卡、权益管理 | gym-domain, gym-infrastructure | -| gym-service-booking | 课程预约、库存管理 | gym-domain, gym-infrastructure | -| gym-service-checkin | 签到处理、权益扣减 | gym-domain, gym-infrastructure | -| gym-api | HTTP接口定义、参数校验 | gym-service-\* | -| gym-starter | 应用启动、配置加载 | gym-api | +#### 4.1.2 会员卡规则 -### 4.3 模块交互 +- 会员卡类型:时长卡、次卡、储值卡、等级卡 +- 会员卡支付成功后立即激活,权益即时到账 +- 会员卡有效期从激活日开始计算 +- 支持会员卡续费,续费后权益累加 +- 会员卡到期前7天发送提醒通知 +- 支持会员卡转让功能(可选,需店长审批) -``` -┌─────────────────────────────────────────────────────────────────────────┐ -│ 模块交互流程 │ -├─────────────────────────────────────────────────────────────────────────┤ -│ │ -│ 客户端 (Client) │ -│ │ │ -│ │ 1. HTTP Request │ -│ ▼ │ -│ API Layer │ -│ │ │ -│ │ 2. 调用业务逻辑 │ -│ ▼ │ -│ Service Layer │ -│ │ │ -│ │ 3. 处理领域逻辑 │ -│ ▼ │ -│ Domain Layer │ -│ │ │ -│ │ 4. 访问数据 │ -│ ▼ │ -│ Repo Layer │ -│ │ │ -│ │ 5. 访问基础设施 │ -│ ▼ │ -│ Infrastructure │ -│ │ │ -│ │ 6. 返回结果 │ -│ ▼ │ -│ Repo Layer ──────────────────────────────────────────────────────────┐ │ -│ │ │ │ -│ │ 7. 返回数据 │ │ -│ ▼ │ │ -│ Domain Layer ────────────────────────────────────────────────────────┤ │ -│ │ │ │ -│ │ 8. 返回领域对象 │ │ -│ ▼ │ │ -│ Service Layer ──────────────────────────────────────────────────────┤ │ -│ │ │ │ -│ │ 9. 返回业务结果 │ │ -│ ▼ │ │ -│ API Layer ──────────────────────────────────────────────────────────┤ │ -│ │ │ │ -│ │ 10. HTTP Response │ │ -│ ▼ │ │ -│ 客户端 (Client) ◀────────────────────────────────────────────────────┘ │ -│ │ -└─────────────────────────────────────────────────────────────────────────┘ -``` +#### 4.1.3 权益管理规则 + +- 权益类型:时长、次数、储值、等级 +- 权益使用时优先级:储值 > 次数 > 时长 > 等级 +- 权益扣减时先检查余额,余额不足时提示用户 +- 权益使用记录永久保存,支持查询 +- 权益到期后自动失效,不可使用 + +### 4.2 预约管理规则 + +#### 4.2.1 预约规则 + +- 会员必须拥有足够的权益才能预约(次数、时长、储值等) +- 同一时段只能预约一个课程,预约冲突时提示用户 +- 预约成功后发送通知(微信、短信) +- 预约取消时间限制:开课前2小时内不能取消 +- 热门课程支持候补机制,满员后自动进入候补队列 +- 候补队列按预约时间排序,有人取消时自动补位 + +#### 4.2.2 课程排期规则 + +- 课程排期需提前至少24小时发布 +- 课程排期修改需通知已预约会员 +- 课程取消需提前2小时通知已预约会员 +- 课程满员后自动开启候补 +- 教练请假需提前24小时通知,系统自动调整排期 + +### 4.3 签到管理规则 + +#### 4.3.1 签到规则 + +- 签到时验证会员身份和预约信息 +- 有预约的会员优先签到,自动扣减权益 +- 无预约的会员可以临时签到,需前台确认 +- 签到成功后记录签到时间、设备信息 +- 支持教练代签,教练可以确认学员签到 +- 签到失败时提供明确的错误提示(如:预约不存在、权益不足) + +#### 4.3.2 签到时间规则 + +- 团课签到时间:开课前30分钟至开课后10分钟 +- 私教签到时间:预约时间前后15分钟内 +- 临时签到时间:门店营业时间内 +- 迟到超过10分钟视为缺勤,不扣减权益 + +### 4.4 财务管理规则 + +#### 4.4.1 支付规则 + +- 支持多种支付方式:微信支付、支付宝、银行卡 +- 支付成功后立即到账,实时更新财务数据 +- 支持退款,退款需店长审批 +- 退款原路返回,到账时间取决于支付渠道 +- 支持对账功能,每日自动对账 + +#### 4.4.2 账单规则 + +- 账单实时生成,支持查询和导出 +- 账单包含:订单号、金额、支付方式、时间、状态 +- 账单状态:待支付、已支付、已退款、已取消 +- 支持按时间、门店、会员、类型筛选账单 +- 账单数据永久保存,支持审计 + +### 4.5 数据分析规则 + +#### 4.5.1 数据统计规则 + +- 数据实时统计,支持实时查询 +- 数据按天、周、月、季度、年度汇总 +- 支持多维度数据分析:会员、课程、财务、运营 +- 数据报表支持导出:Excel、PDF +- 数据可视化:图表、趋势图、排行榜 + +#### 4.5.2 数据权限规则 + +- 超级管理员:查看全平台数据 +- 运营管理员:查看负责区域数据 +- 店长:查看本店数据 +- 财务专员:查看财务数据 +- 其他角色:按权限查看对应数据 --- -## 五、接口设计 +## 五、业务场景 -### 5.1 接口规范 +### 5.1 典型业务场景 -#### 5.1.1 RESTful API 规范 +#### 5.1.1 会员预约团课场景 -``` +**场景描述**: +会员小李想预约明天晚上7点的瑜伽课程,他打开会员小程序,浏览课程列表,找到瑜伽课程,查看课程详情,确认教练、场地、时间,检查自己的会员权益(次卡剩余5次),确认可以预约,点击预约按钮,系统验证权益余额,预约成功,收到微信通知。 -基础URL: https://api.gym-manage.com/v1 +**业务流程**: -资源命名规范: +1. 会员登录小程序 +2. 浏览课程列表 +3. 选择瑜伽课程 +4. 查看课程详情 +5. 检查会员权益 +6. 确认预约 +7. 系统验证权益 +8. 预约成功 +9. 发送通知 -- 使用名词复数形式: /members, /bookings, /courses -- 使用小写字母和连字符: /member-cards, /booking-slots -- 避免动词: /members (正确) vs /getMembers (错误) +**涉及的业务规则**: -HTTP方法语义: +- 会员必须拥有足够的权益才能预约 +- 同一时段只能预约一个课程 +- 预约成功后发送通知 -- GET: 查询资源 -- POST: 创建资源 -- PUT: 全量更新资源 -- PATCH: 部分更新资源 -- DELETE: 删除资源 +#### 5.1.2 会员签到场景 -``` +**场景描述**: +会员小李到达健身房,打开会员小程序,点击签到按钮,选择刷脸签到,系统识别人脸,验证身份,检查预约信息,确认有预约,签到成功,自动扣减权益(次卡剩余4次),记录签到时间和设备信息。 -#### 5.1.2 请求响应格式 +**业务流程**: -```json -// 统一响应格式 -{ - "code": 0, // 业务状态码,0表示成功 - "message": "success", // 响应消息 - "data": {}, // 响应数据 - "timestamp": 1709123456789 // 时间戳 -} +1. 会员到达健身房 +2. 打开会员小程序 +3. 点击签到按钮 +4. 选择刷脸签到 +5. 系统识别人脸 +6. 验证身份 +7. 检查预约信息 +8. 签到成功 +9. 扣减权益 +10. 记录签到信息 -// 分页响应格式 -{ - "code": 0, - "message": "success", - "data": { - "list": [], // 数据列表 - "total": 100, // 总记录数 - "page": 1, // 当前页码 - "pageSize": 20 // 每页大小 - }, - "timestamp": 1709123456789 -} +**涉及的业务规则**: -// 错误响应格式 -{ - "code": 40001, // 错误码 - "message": "参数校验失败", // 错误消息 - "data": { - "errors": [ // 详细错误信息 - {"field": "phone", "message": "手机号格式不正确"} - ] - }, - "timestamp": 1709123456789 -} -``` +- 签到时验证会员身份和预约信息 +- 有预约的会员优先签到,自动扣减权益 +- 签到成功后记录签到时间、设备信息 -#### 5.1.3 状态码定义 +#### 5.1.3 教练排课场景 -| 状态码 | 含义 | 说明 | -| ------ | ---------- | --------------------- | -| 0 | 成功 | 请求处理成功 | -| 40001 | 参数错误 | 请求参数校验失败 | -| 40002 | 资源不存在 | 请求的资源不存在 | -| 40003 | 资源已存在 | 创建的资源已存在 | -| 40101 | 未登录 | 用户未登录或Token过期 | -| 40102 | 无权限 | 用户无访问权限 | -| 40301 | 业务异常 | 业务逻辑校验失败 | -| 50001 | 系统异常 | 系统内部错误 | +**场景描述**: +教练王老师想安排下周的私教课程,他打开教练端App,查看自己的排班表,选择下周三下午2点到3点的时间段,选择私教课程,填写课程名称、课程描述,选择场地,设置价格,发布课程,系统自动生成预约时段,会员可以开始预约。 -### 5.2 接口分组 +**业务流程**: -### 5.2 接口分组 +1. 教练登录教练端App +2. 查看排班表 +3. 选择时间段 +4. 选择课程类型 +5. 填写课程信息 +6. 选择场地 +7. 设置价格 +8. 发布课程 +9. 系统生成预约时段 +10. 会员可以预约 -``` -┌─────────────────────────────────────────────────────────────────────────┐ -│ 接口分组 │ -├─────────────────────────────────────────────────────────────────────────┤ -│ │ -│ ┌─────────────────────────────────────────────────────────────────┐ │ -│ │ 认证接口 /v1/auth │ │ -│ ├─────────────────────────────────────────────────────────────────┤ │ -│ │ • POST /login (登录) • POST /logout (登出) │ │ -│ │ • POST /refresh (刷新Token) • POST /wechat-login (微信登录) │ │ -│ └─────────────────────────────────────────────────────────────────┘ │ -│ │ -│ ┌─────────────────────────────────────────────────────────────────┐ │ -│ │ 会员接口 /v1/members │ │ -│ ├─────────────────────────────────────────────────────────────────┤ │ -│ │ • GET / (会员列表) • GET /{id} (会员详情) │ │ -│ │ • POST / (创建会员) • PUT /{id} (更新会员) │ │ -│ │ • GET /{id}/cards (会员卡列表) • GET /{id}/benefits (权益列表)│ │ -│ │ • GET /{id}/bookings (预约记录) │ │ -│ └─────────────────────────────────────────────────────────────────┘ │ -│ │ -│ ┌─────────────────────────────────────────────────────────────────┐ │ -│ │ 课程接口 /v1/courses │ │ -│ ├─────────────────────────────────────────────────────────────────┤ │ -│ │ • GET / (课程列表) • GET /{id} (课程详情) │ │ -│ │ • POST / (创建课程) • PUT /{id} (更新课程) │ │ -│ │ • GET /{id}/slots (可预约时段) │ │ -│ └─────────────────────────────────────────────────────────────────┘ │ -│ │ -│ ┌─────────────────────────────────────────────────────────────────┐ │ -│ │ 预约接口 /v1/bookings │ │ -│ ├─────────────────────────────────────────────────────────────────┤ │ -│ │ • GET / (预约列表) • GET /{id} (预约详情) │ │ -│ │ • POST / (创建预约) • POST /{id}/cancel (取消预约) │ │ -│ │ • GET /my (我的预约) │ │ -│ └─────────────────────────────────────────────────────────────────┘ │ -│ │ -│ ┌─────────────────────────────────────────────────────────────────┐ │ -│ │ 签到接口 /v1/checkins │ │ -│ ├─────────────────────────────────────────────────────────────────┤ │ -│ │ • GET / (签到列表) • POST /scan (扫码签到) │ │ -│ │ • POST /manual (手动签到) • GET /my (我的签到) │ │ -│ └─────────────────────────────────────────────────────────────────┘ │ -│ │ -│ ┌─────────────────────────────────────────────────────────────────┐ │ -│ │ 教练接口 /v1/coaches │ │ -│ ├─────────────────────────────────────────────────────────────────┤ │ -│ │ • GET / (教练列表) • GET /{id} (教练详情) │ │ -│ │ • GET /{id}/schedule (教练排班) • GET /{id}/slots (可预约时段)│ │ -│ └─────────────────────────────────────────────────────────────────┘ │ -│ │ -│ ┌─────────────────────────────────────────────────────────────────┐ │ -│ │ 数据看板 /v1/dashboard │ │ -│ ├─────────────────────────────────────────────────────────────────┤ │ -│ │ • GET /overview (今日概览) • GET /trends (趋势数据) │ │ -│ │ • GET /rankings (排行数据) │ │ -│ └─────────────────────────────────────────────────────────────────┘ │ -│ │ -└─────────────────────────────────────────────────────────────────────────┘ -``` +**涉及的业务规则**: -### 5.3 接口版本管理 +- 课程排期需提前至少24小时发布 +- 课程排期修改需通知已预约会员 +- 课程满员后自动开启候补 -``` -版本策略: -1. URL路径版本: /v1/members, /v2/members -2. 向后兼容原则: 新版本接口保留旧版本功能 -3. 废弃通知: 旧版本接口返回 Warning 头,提前3个月通知 +#### 5.1.4 店长查看数据场景 -版本生命周期: -- 开发中: 内部测试,不对外发布 -- 当前版本: 正式发布,完全支持 -- 已废弃: 仍可使用,但建议迁移 -- 已下线: 不再可用 -``` +**场景描述**: +店长张经理想查看今天的运营数据,他打开管理后台,点击数据看板,查看今日概览(会员数、预约数、签到数、营收),查看趋势数据(近7天预约趋势、近30天营收趋势),查看排行数据(热门课程排行、活跃会员排行),导出数据报表。 + +**业务流程**: + +1. 店长登录管理后台 +2. 点击数据看板 +3. 查看今日概览 +4. 查看趋势数据 +5. 查看排行数据 +6. 导出数据报表 + +**涉及的业务规则**: + +- 数据实时统计,支持实时查询 +- 数据按天、周、月、季度、年度汇总 +- 支持多维度数据分析 +- 数据报表支持导出 + +### 5.2 特殊业务场景 + +#### 5.2.1 热门课程抢课场景 + +**场景描述**: +热门课程(如普拉提)只有10个名额,但有多名会员同时预约,系统采用先到先得的原则,前10名预约成功的会员获得名额,其他会员自动进入候补队列,有会员取消预约时,候补队列中的会员自动补位。 + +**业务流程**: + +1. 多名会员同时预约热门课程 +2. 系统处理预约请求 +3. 前10名预约成功 +4. 其他会员进入候补队列 +5. 有会员取消预约 +6. 候补队列中的会员自动补位 +7. 发送补位通知 + +**涉及的业务规则**: + +- 同一时段只能预约一个课程 +- 热门课程支持候补机制 +- 候补队列按预约时间排序 +- 有人取消时自动补位 + +#### 5.2.2 会员卡过期续费场景 + +**场景描述**: +会员小李的会员卡即将过期,系统提前7天发送提醒通知,小李收到通知后,打开会员小程序,查看会员卡信息,点击续费按钮,选择续费时长,支付成功,会员卡续费成功,权益累加,有效期延长。 + +**业务流程**: + +1. 系统检测会员卡即将过期 +2. 提前7天发送提醒通知 +3. 会员收到通知 +4. 打开会员小程序 +5. 查看会员卡信息 +6. 点击续费按钮 +7. 选择续费时长 +8. 支付成功 +9. 会员卡续费成功 +10. 权益累加,有效期延长 + +**涉及的业务规则**: + +- 会员卡到期前7天发送提醒通知 +- 支持会员卡续费,续费后权益累加 +- 会员卡有效期从续费成功日开始计算 + +#### 5.2.3 签到异常处理场景 + +**场景描述**: +会员小李到达健身房,尝试刷脸签到,但系统无法识别人脸,小李选择扫码签到,扫描二维码,系统验证身份,但发现没有预约,前台工作人员手动处理,确认会员身份,临时签到成功。 + +**业务流程**: + +1. 会员到达健身房 +2. 尝试刷脸签到 +3. 系统无法识别人脸 +4. 选择扫码签到 +5. 扫描二维码 +6. 系统验证身份 +7. 发现没有预约 +8. 前台手动处理 +9. 确认会员身份 +10. 临时签到成功 + +**涉及的业务规则**: + +- 签到时验证会员身份和预约信息 +- 无预约的会员可以临时签到,需前台确认 +- 签到失败时提供明确的错误提示 --- -## 六、安全设计 +## 六、业务约束 -### 6.1 认证机制 +### 6.1 数据约束 -``` -┌─────────────────────────────────────────────────────────────────────────┐ -│ 认证机制 │ -├─────────────────────────────────────────────────────────────────────────┤ -│ │ -│ ┌─────────────────────────────────────────────────────────────────┐ │ -│ │ JWT Token 认证流程 │ │ -│ │ │ │ -│ │ 1. 用户登录 │ │ -│ │ POST /v1/auth/login │ │ -│ │ { phone, code } │ │ -│ │ │ │ │ -│ │ ▼ │ │ -│ │ 2. 服务端验证 │ │ -│ │ - 验证手机号和验证码 │ │ -│ │ - 查询用户信息 │ │ -│ │ - 生成 JWT Token │ │ -│ │ │ │ │ -│ │ ▼ │ │ -│ │ 3. 返回 Token │ │ -│ │ { accessToken, refreshToken, expiresIn } │ │ -│ │ │ │ │ -│ │ ▼ │ │ -│ │ 4. 后续请求携带 Token │ │ -│ │ Authorization: Bearer {accessToken} │ │ -│ │ │ │ │ -│ │ ▼ │ │ -│ │ 5. 服务端验证 Token │ │ -│ │ - 解析 Token │ │ -│ │ - 验证签名和有效期 │ │ -│ │ - 提取用户信息 │ │ -│ │ │ │ -│ └─────────────────────────────────────────────────────────────────┘ │ -│ │ -│ Token 结构: │ -│ { │ -│ "sub": "member:12345", // 用户标识 │ -│ "tenant": "tenant:001", // 租户标识 │ -│ "store": "store:001", // 门店标识 │ -│ "roles": ["MEMBER"], // 角色列表 │ -│ "exp": 1709123456, // 过期时间 │ -│ "iat": 1709120000 // 签发时间 │ -│ } │ -│ │ -└─────────────────────────────────────────────────────────────────────────┘ -``` +- 会员手机号必须唯一 +- 会员ID全局唯一 +- 预约ID全局唯一 +- 签到记录ID全局唯一 +- 会员卡ID全局唯一 +- 订单ID全局唯一 -### 6.2 权限控制 +### 6.2 时间约束 -``` -┌─────────────────────────────────────────────────────────────────────────┐ -│ RBAC 权限模型 │ -├─────────────────────────────────────────────────────────────────────────┤ -│ │ -│ ┌─────────┐ M:N ┌─────────┐ M:N ┌─────────┐ │ -│ │ 用户 │─────────────▶│ 角色 │─────────────▶│ 权限 │ │ -│ │ User │ │ Role │ │Permission│ │ -│ └─────────┘ └─────────┘ └─────────┘ │ -│ │ -│ 角色定义: │ -│ ┌────────────────┬────────────────────────────────────────────────┐ │ -│ │ 角色 │ 权限范围 │ │ -│ ├────────────────┼────────────────────────────────────────────────┤ │ -│ │ ROLE_MEMBER │ 会员端功能:预约、签到、个人信息 │ │ -│ │ ROLE_COACH │ 教练端功能:排课、签到、学员管理 │ │ -│ │ ROLE_RECEPTION │ 前台功能:接待、签到、会员查询 │ │ -│ │ ROLE_STORE_MGR │ 店长功能:单店全功能管理 │ │ -│ │ ROLE_OPERATOR │ 运营功能:营销活动、数据分析 │ │ -│ │ ROLE_FINANCE │ 财务功能:账单、报表 │ │ -│ │ ROLE_ADMIN │ 超管功能:全平台管理 │ │ -│ └────────────────┴────────────────────────────────────────────────┘ │ -│ │ -│ 权限标识: │ -│ 格式: {模块}:{资源}:{操作} │ -│ 示例: │ -│ - member:user:read # 查看会员信息 │ -│ - member:user:write # 编辑会员信息 │ -│ - booking:course:create # 创建课程预约 │ -│ - booking:course:cancel # 取消课程预约 │ -│ - checkin:scan:execute # 执行扫码签到 │ -│ │ -└─────────────────────────────────────────────────────────────────────────┘ -``` +- 验证码有效期60秒 +- 预约取消时间限制:开课前2小时内不能取消 +- 课程排期需提前至少24小时发布 +- 课程取消需提前2小时通知已预约会员 +- 教练请假需提前24小时通知 +- 团课签到时间:开课前30分钟至开课后10分钟 +- 私教签到时间:预约时间前后15分钟内 +- 会员卡到期前7天发送提醒通知 -### 6.3 数据安全 +### 6.3 权益约束 -``` -┌─────────────────────────────────────────────────────────────────────────┐ -│ 数据安全措施 │ -├─────────────────────────────────────────────────────────────────────────┤ -│ │ -│ 1. 敏感数据加密 │ -│ ├── 手机号: 存储时AES加密,展示时脱敏(138****1234) │ -│ ├── 身份证: 存储时AES加密,不对外展示 │ -│ ├── 密码: 使用BCrypt加密存储 │ -│ └── 支付信息: 不存储,仅保留支付渠道token │ -│ │ -│ 2. 传输安全 │ -│ ├── 全站HTTPS │ -│ ├── 敏感接口签名验证 │ -│ └── 防重放攻击(timestamp + nonce) │ -│ │ -│ 3. SQL注入防护 │ -│ ├── 使用R2DBC参数化查询 │ -│ ├── 禁止拼接SQL │ -│ └── 输入参数校验 │ -│ │ -│ 4. XSS防护 │ -│ ├── 输入过滤 │ -│ ├── 输出编码 │ -│ └── Content-Security-Policy头 │ -│ │ -│ 5. CSRF防护 │ -│ ├── CSRF Token验证 │ -│ └── SameSite Cookie │ -│ │ -│ 6. 多租户数据隔离 │ -│ ├── tenant_id 强制过滤 │ -│ ├── 数据库行级安全策略(RLS) │ -│ └── API层租户上下文自动注入 │ -│ │ -└─────────────────────────────────────────────────────────────────────────┘ -``` +- 会员必须拥有足够的权益才能预约 +- 权益使用时优先级:储值 > 次数 > 时长 > 等级 +- 权益扣减时先检查余额,余额不足时提示用户 +- 权益到期后自动失效,不可使用 +- 权益使用记录永久保存,支持查询 -### 6.4 接口安全 +### 6.4 并发约束 -``` -┌─────────────────────────────────────────────────────────────────────────┐ -│ 接口安全措施 │ -├─────────────────────────────────────────────────────────────────────────┤ -│ │ -│ 1. 限流策略 │ -│ ├── 全局限流: 10000 QPS │ -│ ├── 单IP限流: 100 QPS │ -│ ├── 单用户限流: 50 QPS │ -│ └── 敏感接口限流: 登录10次/分钟,短信1次/分钟 │ -│ │ -│ 2. 熔断降级 │ -│ ├── 错误率阈值: 50% │ -│ ├── 熔断时间窗口: 30秒 │ -│ └── 降级策略: 返回默认值或友好提示 │ -│ │ -│ 3. 黑白名单 │ -│ ├── IP白名单: 管理后台接口 │ -│ ├── IP黑名单: 恶意攻击IP │ -│ └── 用户黑名单: 违规用户 │ -│ │ -│ 4. 日志审计 │ -│ ├── 操作日志: 记录所有写操作 │ -│ ├── 访问日志: 记录所有API请求 │ -│ └── 异常日志: 记录系统异常 │ -│ │ -└─────────────────────────────────────────────────────────────────────────┘ -``` +- 同一时段只能预约一个课程 +- 热门课程支持候补机制 +- 候补队列按预约时间排序 +- 有人取消时自动补位 +- 支持高并发场景(QPS ≥ 1000) --- -## 七、性能设计 +## 七、业务指标 -### 7.1 性能目标 +### 7.1 用户体验指标 -| 指标 | 目标值 | 说明 | -| -------- | ----------- | -------------------------- | -| 响应时间 | P99 < 200ms | 99%的请求响应时间小于200ms | -| 吞吐量 | QPS ≥ 1000 | 系统每秒处理请求数 | -| 并发用户 | ≥ 5000 | 同时在线用户数 | -| 可用性 | SLA ≥ 99.9% | 年度可用性 | +| 指标名称 | 目标值 | 测量方法 | +| ---------- | ------ | --------------------------- | +| 预约成功率 | ≥ 95% | 预约成功次数 / 预约总次数 | +| 签到耗时 | ≤ 3秒 | 签到完成时间 - 签到开始时间 | +| 注册成功率 | ≥ 98% | 注册成功次数 / 注册总次数 | +| 支付成功率 | ≥ 99% | 支付成功次数 / 支付总次数 | -### 7.2 性能优化策略 +### 7.2 运营效率指标 -``` -┌─────────────────────────────────────────────────────────────────────────┐ -│ 性能优化策略 │ -├─────────────────────────────────────────────────────────────────────────┤ -│ │ -│ 1. 数据库优化 │ -│ ├── 索引优化: 合理创建索引,避免全表扫描 │ -│ ├── 连接池: R2DBC连接池,max-size=20 │ -│ ├── 读写分离: 主库写入,从库读取(后期扩展) │ -│ └── 分库分表: 按租户分库(后期扩展) │ -│ │ -│ 2. 缓存优化 │ -│ ├── L1缓存: Caffeine本地缓存,热点数据 │ -│ ├── L2缓存: Redis分布式缓存(可选扩展) │ -│ ├── 缓存策略: 写穿透 + 延迟双删 │ -│ └── 缓存预热: 系统启动时预加载热点数据 │ -│ │ -│ 3. 代码优化 │ -│ ├── 响应式编程: WebFlux非阻塞IO │ -│ ├── 异步处理: 非核心流程异步化 │ -│ ├── 批量操作: 减少数据库往返 │ -│ └── 虚拟线程: JDK 21虚拟线程优化阻塞操作 │ -│ │ -│ 4. 网络优化 │ -│ ├── CDN加速: 静态资源CDN分发 │ -│ ├── GZIP压缩: 响应数据压缩 │ -│ ├── HTTP/2: 多路复用 │ -│ └── Keep-Alive: 连接复用 │ -│ │ -└─────────────────────────────────────────────────────────────────────────┘ -``` +| 指标名称 | 目标值 | 测量方法 | +| ---------------- | ------ | -------------------------------------------------------------- | +| 人工处理时间减少 | ≥ 50% | (优化前人工处理时间 - 优化后人工处理时间) / 优化前人工处理时间 | +| 预约取消率 | ≤ 10% | 预约取消次数 / 预约总次数 | +| 签到成功率 | ≥ 98% | 签到成功次数 / 签到总次数 | +| 会员活跃度 | ≥ 60% | 活跃会员数 / 总会员数 | -### 7.3 高并发场景处理 +### 7.3 数据价值指标 -``` -┌─────────────────────────────────────────────────────────────────────────┐ -│ 高并发预约场景处理 │ -├─────────────────────────────────────────────────────────────────────────┤ -│ │ -│ 场景: 热门课程开抢,大量用户同时预约 │ -│ │ -│ 解决方案: │ -│ │ -│ 1. 库存预热 │ -│ └── 开抢前将课程库存加载到Caffeine缓存 │ -│ │ -│ 2. 原子操作 │ -│ └── 使用PostgreSQL原子更新: │ -│ UPDATE booking_slot │ -│ SET booked_count = booked_count + 1 │ -│ WHERE id = ? AND booked_count < capacity │ -│ │ -│ 3. 乐观锁 │ -│ └── 版本号控制,冲突时重试 │ -│ │ -│ 4. 排队机制 │ -│ └── 请求进入队列,异步处理结果 │ -│ │ -│ 5. 限流保护 │ -│ └── 令牌桶限流,防止系统过载 │ -│ │ -│ 6. 候补机制 │ -│ └── 满员后自动进入候补队列,有人取消时自动补位 │ -│ │ -└─────────────────────────────────────────────────────────────────────────┘ -``` +| 指标名称 | 目标值 | 测量方法 | +| -------------- | ------ | ------------------------------- | +| 数据报表使用率 | ≥ 80% | 使用数据报表的用户数 / 总用户数 | +| 数据准确性 | ≥ 99% | 数据准确记录数 / 数据总记录数 | +| 数据实时性 | ≤ 1秒 | 数据更新时间 - 数据产生时间 | + +### 7.4 系统性能指标 + +| 指标名称 | 目标值 | 测量方法 | +| ------------ | ---------- | ---------------------------- | +| 系统可用性 | ≥ 99.9% | (总时间 - 故障时间) / 总时间 | +| 响应时间 | ≤ 2秒 | 请求响应时间 | +| 并发处理能力 | ≥ 1000 QPS | 每秒处理请求数 | --- -## 八、可扩展性设计 +## 八、附录 -### 8.1 水平扩展 +### 8.1 业务术语表 -``` -┌─────────────────────────────────────────────────────────────────────────┐ -│ 水平扩展方案 │ -├─────────────────────────────────────────────────────────────────────────┤ -│ │ -│ 1. 无状态设计 │ -│ ├── Session外置到Redis │ -│ ├── 本地不存储用户状态 │ -│ └── 任意实例可处理任意请求 │ -│ │ -│ 2. 负载均衡 │ -│ ├── 轮询: 默认策略 │ -│ ├── 加权轮询: 根据服务器性能分配权重 │ -│ └── 最少连接: 请求分配给连接数最少的服务器 │ -│ │ -│ 3. 服务拆分(后期) │ -│ ├── 会员服务独立部署 │ -│ ├── 预约服务独立部署 │ -│ └── 数据服务独立部署 │ -│ │ -│ 4. 数据库扩展(后期) │ -│ ├── 读写分离 │ -│ ├── 分库分表 │ -│ └── 多活架构 │ -│ │ -└─────────────────────────────────────────────────────────────────────────┘ -``` +| 术语 | 定义 | +| ----------------------------- | ------------------------------------------------ | +| 租户(Tenant) | 系统的多租户架构中的独立业务实体,如一个连锁品牌 | +| 门店(Store) | 租户下的具体经营场所 | +| 会员(Member) | 在门店注册的用户 | +| 权益(Benefit) | 会员卡包含的时长、次数、储值、等级等权益 | +| 可预约资源(Bookable Resource) | 团课、私教、场地、线上课程等可被预约的对象 | +| 时段(Slot) | 资源的可预约时间窗口 | +| 预约(Booking) | 会员预订课程或场地的行为 | +| 签到(Check-in) | 会员到达健身房并记录到达时间的行为 | +| 会员卡(Member Card) | 会员购买的权益载体,包含时长、次数、储值等 | +| 候补(Waitlist) | 课程满员后,会员进入等待队列,有空位时自动补位 | -### 8.2 功能扩展 +### 8.2 参考文档 -``` -┌─────────────────────────────────────────────────────────────────────────┐ -│ 功能扩展点 │ -├─────────────────────────────────────────────────────────────────────────┤ -│ │ -│ 1. 支付扩展 │ -│ ├── 预留支付接口抽象 │ -│ ├── 支持微信支付、支付宝、银联等 │ -│ └── 可扩展其他支付渠道 │ -│ │ -│ 2. 硬件扩展 │ -│ ├── 签到网关抽象设计 │ -│ ├── 支持多种签到设备 │ -│ └── 可扩展智能硬件 │ -│ │ -│ 3. 消息扩展 │ -│ ├── 消息模板可配置 │ -│ ├── 支持多渠道推送 │ -│ └── 可扩展新的消息渠道 │ -│ │ -│ 4. 报表扩展 │ -│ ├── 报表模板可配置 │ -│ ├── 支持自定义报表 │ -│ └── 可扩展BI工具对接 │ -│ │ -└─────────────────────────────────────────────────────────────────────────┘ -``` +- 《健身房管理系统产品设计文档》 GYM-PRD-001 +- 《健身房管理系统详细设计文档》 GYM-LLD-001 --- -## 九、监控与运维 - -### 9.1 监控体系 - -``` -┌─────────────────────────────────────────────────────────────────────────┐ -│ 监控体系 │ -├─────────────────────────────────────────────────────────────────────────┤ -│ │ -│ 1. 基础监控 │ -│ ├── CPU使用率 │ -│ ├── 内存使用率 │ -│ ├── 磁盘使用率 │ -│ ├── 网络IO │ -│ └── 进程状态 │ -│ │ -│ 2. 应用监控 │ -│ ├── JVM监控(GC、堆内存、线程) │ -│ ├── 请求QPS/响应时间 │ -│ ├── 错误率/异常数 │ -│ └── 数据库连接池状态 │ -│ │ -│ 3. 业务监控 │ -│ ├── 登录数/在线用户数 │ -│ ├── 预约成功率 │ -│ ├── 签到成功率 │ -│ └── 支付成功率 │ -│ │ -│ 4. 告警策略 │ -│ ├── CPU > 80% 告警 │ -│ ├── 内存 > 85% 告警 │ -│ ├── 错误率 > 1% 告警 │ -│ └── 响应时间 P99 > 500ms 告警 │ -│ │ -└─────────────────────────────────────────────────────────────────────────┘ -``` - -### 9.2 日志规范 - -``` -┌─────────────────────────────────────────────────────────────────────────┐ -│ 日志规范 │ -├─────────────────────────────────────────────────────────────────────────┤ -│ │ -│ 1. 日志级别 │ -│ ├── ERROR: 错误日志,需要立即处理 │ -│ ├── WARN: 警告日志,需要关注 │ -│ ├── INFO: 重要业务日志 │ -│ └── DEBUG: 调试日志(生产环境关闭) │ -│ │ -│ 2. 日志格式 │ -│ { │ -│ "timestamp": "2024-02-28T10:00:00.000+08:00", │ -│ "level": "INFO", │ -│ "traceId": "abc123", │ -│ "spanId": "def456", │ -│ "tenantId": "tenant:001", │ -│ "userId": "member:12345", │ -│ "class": "MemberService", │ -│ "method": "createMember", │ -│ "message": "创建会员成功", │ -│ "args": {"phone": "138****1234"}, │ -│ "result": {"memberId": 12345}, │ -│ "duration": 50 │ -│ } │ -│ │ -│ 3. 日志存储 │ -│ ├── 本地文件: 保留7天 │ -│ ├── ELK: 集中存储和分析 │ -│ └── 归档: 超过30天归档到OSS │ -│ │ -└─────────────────────────────────────────────────────────────────────────┘ -``` - ---- - -## 十、附录 - -### 10.1 技术选型清单 - -| 分类 | 技术 | 版本 | 说明 | -| ---------- | -------------- | ---- | ---------------- | -| 后端框架 | Spring Boot | 3.x | 主框架 | -| 响应式 | Spring WebFlux | 3.x | 响应式Web框架 | -| JDK | OpenJDK | 21+ | 虚拟线程支持 | -| 数据库 | PostgreSQL | 15+ | 主数据库 | -| 数据访问 | R2DBC | 1.x | 响应式数据库访问 | -| 数据库迁移 | Flyway | 9.x | 数据库版本管理 | -| 缓存 | Caffeine | 3.x | 本地缓存 | -| 缓存(可选) | Redis | 7.x | 分布式缓存 | -| 前端框架 | Vue | 3.x | 前端框架 | -| 跨端框架 | uniapp | 3.x | 跨端开发框架 | -| 状态管理 | Pinia | 2.x | 状态管理 | -| UI组件 | Element Plus | 2.x | 管理后台UI | -| 构建工具 | Vite | 5.x | 前端构建工具 | -| 容器 | Docker | 24.x | 容器化部署 | - -### 10.2 术语表 - -| 术语 | 英文 | 定义 | -| ---------- | -------------------- | -------------------------------- | -| 高可用 | High Availability | 系统持续提供服务的能力 | -| 响应式编程 | Reactive Programming | 基于数据流和变化传播的编程范式 | -| 多租户 | Multi-tenancy | 单个实例服务多个租户的架构 | -| 软删除 | Soft Delete | 通过标记删除时间而非物理删除数据 | -| 乐观锁 | Optimistic Lock | 假设冲突较少,通过版本号控制并发 | -| 悲观锁 | Pessimistic Lock | 假设冲突较多,通过锁机制控制并发 | - ---- - -_文档结束_ +**文档结束** diff --git a/docs/design/LLD-会员模块详细设计.md b/docs/design/LLD-会员模块详细设计.md index da17699..e16c3d3 100644 --- a/docs/design/LLD-会员模块详细设计.md +++ b/docs/design/LLD-会员模块详细设计.md @@ -19,7 +19,8 @@ ## 参考文档 - 《健身房管理系统产品设计文档》 GYM-PRD-001 -- 《健身房管理系统概要设计文档》 GYM-HLD-001 +- 《健身房管理系统业务概要设计文档》 GYM-HLD-001 +- 《健身房管理系统详细设计文档》 GYM-LLD-000 - Spring Boot 3 官方文档 - R2DBC 规范文档 - PostgreSQL 官方文档 diff --git a/docs/design/LLD-签到模块详细设计.md b/docs/design/LLD-签到模块详细设计.md index e083f27..9b4d481 100644 --- a/docs/design/LLD-签到模块详细设计.md +++ b/docs/design/LLD-签到模块详细设计.md @@ -19,7 +19,8 @@ ## 参考文档 - 《健身房管理系统产品设计文档》 GYM-PRD-001 -- 《健身房管理系统概要设计文档》 GYM-HLD-001 +- 《健身房管理系统业务概要设计文档》 GYM-HLD-001 +- 《健身房管理系统详细设计文档》 GYM-LLD-000 - Spring Boot 3 官方文档 - R2DBC 规范文档 - PostgreSQL 官方文档 diff --git a/docs/design/LLD-系统详细设计.md b/docs/design/LLD-系统详细设计.md new file mode 100644 index 0000000..932cdd6 --- /dev/null +++ b/docs/design/LLD-系统详细设计.md @@ -0,0 +1,796 @@ +# 健身房管理系统详细设计文档(LLD) + +> 文档编号: GYM-LLD-000 +> 版本: v1.0 +> 日期: 2026-03-04 +> 作者: 张翔 +> 状态: 初稿 + +--- + +## 文档修订历史 + +| 版本 | 日期 | 作者 | 修订内容 | +| ---- | ---------- | ---- | -------- | +| v1.0 | 2026-03-04 | 张翔 | 创建系统详细设计文档 | + +--- + +## 参考文档 + +- 《健身房管理系统产品设计文档》 GYM-PRD-001 +- 《健身房管理系统业务概要设计文档》 GYM-HLD-001 +- Spring Boot 3 官方文档 +- R2DBC 规范文档 +- PostgreSQL 官方文档 + +--- + +## 一、系统架构设计 + +### 1.1 总体架构 + +采用分层架构 + 微服务思想的模块化设计: + +``` +┌─────────────────────────────────────────────────────────────────────────┐ +│ 总体架构 │ +├─────────────────────────────────────────────────────────────────────────┤ +│ │ +│ ┌─────────────────────────────────────────────────────────────────┐ │ +│ │ 客户端层 │ │ +│ ├─────────────────────────────────────────────────────────────────┤ │ +│ │ • 会员小程序 (uniapp+Vue3) │ │ +│ │ • 教练端App (uniapp+Vue3) │ │ +│ │ • 管理后台PC (Vue3+Vite) │ │ +│ │ • 硬件设备 (人脸/NFC) │ │ +│ └─────────────────────────────────────────────────────────────────┘ │ +│ │ │ +│ ▼ │ +│ ┌─────────────────────────────────────────────────────────────────┐ │ +│ │ API Gateway 统一网关 │ │ +│ ├─────────────────────────────────────────────────────────────────┤ │ +│ │ • 路由转发 • 认证鉴权 • 限流熔断 • 日志追踪 │ │ +│ └─────────────────────────────────────────────────────────────────┘ │ +│ │ │ +│ ▼ │ +│ ┌─────────────────────────────────────────────────────────────────┐ │ +│ │ 业务层 │ │ +│ ├─────────────────────────────────────────────────────────────────┤ │ +│ │ • 会员服务 (Member Service) │ │ +│ │ • 预约服务 (Booking Service) │ │ +│ │ • 数据服务 (Data Service) │ │ +│ └─────────────────────────────────────────────────────────────────┘ │ +│ │ │ +│ ▼ │ +│ ┌─────────────────────────────────────────────────────────────────┐ │ +│ │ 公共服务层 │ │ +│ ├─────────────────────────────────────────────────────────────────┤ │ +│ │ • 认证服务 • 消息服务 • 文件服务 • 缓存服务 │ │ +│ └─────────────────────────────────────────────────────────────────┘ │ +│ │ │ +│ ▼ │ +│ ┌─────────────────────────────────────────────────────────────────┐ │ +│ │ 基础设施层 │ │ +│ ├─────────────────────────────────────────────────────────────────┤ │ +│ │ • PostgreSQL • R2DBC • Caffeine • Redis(可选) │ │ +│ └─────────────────────────────────────────────────────────────────┘ │ +│ │ │ +│ ▼ │ +│ ┌─────────────────────────────────────────────────────────────────┐ │ +│ │ 外部服务层 │ │ +│ ├─────────────────────────────────────────────────────────────────┤ │ +│ │ • 微信开放平台 • 短信服务 • 支付服务 • OSS存储 │ │ +│ └─────────────────────────────────────────────────────────────────┘ │ +│ │ +└─────────────────────────────────────────────────────────────────────────┘ +``` + +### 1.2 技术架构 + +``` +┌─────────────────────────────────────────────────────────────────────────┐ +│ 技术架构 │ +├─────────────────────────────────────────────────────────────────────────┤ +│ │ +│ ┌─────────────────────────────────────────────────────────────────┐ │ +│ │ 前端技术栈 │ │ +│ ├─────────────────────────────────────────────────────────────────┤ │ +│ │ • uniapp (跨平台小程序) • Vue3 (前端框架) │ │ +│ │ • Vite (构建工具) • TypeScript (类型安全) │ │ +│ └─────────────────────────────────────────────────────────────────┘ │ +│ │ +│ ┌─────────────────────────────────────────────────────────────────┐ │ +│ │ 后端技术栈 │ │ +│ ├─────────────────────────────────────────────────────────────────┤ │ +│ │ • Spring Boot 3 (应用框架) • WebFlux (响应式编程) │ │ +│ │ • JDK 21+ (运行环境) • R2DBC (响应式数据库访问) │ │ +│ │ • Spring Security (安全框架) • Caffeine (本地缓存) │ │ +│ └─────────────────────────────────────────────────────────────────┘ │ +│ │ +│ ┌─────────────────────────────────────────────────────────────────┐ │ +│ │ 数据库技术栈 │ │ +│ ├─────────────────────────────────────────────────────────────────┤ │ +│ │ • PostgreSQL 15+ (主数据库) • Redis (可选缓存) │ │ +│ │ • Flyway (数据库版本管理) • R2DBC PostgreSQL Driver │ │ +│ └─────────────────────────────────────────────────────────────────┘ │ +│ │ +│ ┌─────────────────────────────────────────────────────────────────┐ │ +│ │ 开发工具栈 │ │ +│ ├─────────────────────────────────────────────────────────────────┤ │ +│ │ • Maven (依赖管理) • Git (版本控制) • Docker (容器化) │ │ +│ │ • IDEA (开发IDE) • Postman (接口测试) │ │ +│ └─────────────────────────────────────────────────────────────────┘ │ +│ │ +└─────────────────────────────────────────────────────────────────────────┘ +``` + +### 1.3 部署架构 + +``` +┌─────────────────────────────────────────────────────────────────────────┐ +│ 部署架构 │ +├─────────────────────────────────────────────────────────────────────────┤ +│ │ +│ ┌─────────────────────────────────────────────────────────────────┐ │ +│ │ 客户端层 │ │ +│ ├─────────────────────────────────────────────────────────────────┤ │ +│ │ • 微信小程序 • 教练端App • 管理后台PC • 硬件设备 │ │ +│ └─────────────────────────────────────────────────────────────────┘ │ +│ │ │ +│ ▼ │ +│ ┌─────────────────────────────────────────────────────────────────┐ │ +│ │ CDN层 │ │ +│ ├─────────────────────────────────────────────────────────────────┤ │ +│ │ • 静态资源加速 • 图片优化 • 视频加速 │ │ +│ └─────────────────────────────────────────────────────────────────┘ │ +│ │ │ +│ ▼ │ +│ ┌─────────────────────────────────────────────────────────────────┐ │ +│ │ 负载均衡层 │ │ +│ ├─────────────────────────────────────────────────────────────────┤ │ +│ │ • Nginx (反向代理) • 负载均衡策略 • SSL/TLS │ │ +│ └─────────────────────────────────────────────────────────────────┘ │ +│ │ │ +│ ▼ │ +│ ┌─────────────────────────────────────────────────────────────────┐ │ +│ │ 应用服务器层 │ │ +│ ├─────────────────────────────────────────────────────────────────┤ │ +│ │ • Spring Boot应用 (多实例部署) • Docker容器化 │ │ +│ │ • 健康检查 • 自动扩缩容 • 滚动更新 │ │ +│ └─────────────────────────────────────────────────────────────────┘ │ +│ │ │ +│ ▼ │ +│ ┌─────────────────────────────────────────────────────────────────┐ │ +│ │ 数据库层 │ │ +│ ├─────────────────────────────────────────────────────────────────┤ │ +│ │ • PostgreSQL主从复制 • Redis集群 (可选) • 备份策略 │ │ +│ └─────────────────────────────────────────────────────────────────┘ │ +│ │ │ +│ ▼ │ +│ ┌─────────────────────────────────────────────────────────────────┐ │ +│ │ 监控运维层 │ │ +│ ├─────────────────────────────────────────────────────────────────┤ │ +│ │ • 日志收集 • 性能监控 • 告警通知 • 自动化运维 │ │ +│ └─────────────────────────────────────────────────────────────────┘ │ +│ │ +└─────────────────────────────────────────────────────────────────────────┘ +``` + +--- + +## 二、模块设计 + +### 2.1 模块划分 + +``` +┌─────────────────────────────────────────────────────────────────────────┐ +│ gym-manage-server 父工程 │ +├─────────────────────────────────────────────────────────────────────────┤ +│ │ +│ ┌─────────────────────────────────────────────────────────────────┐ │ +│ │ gym-common 公共模块 │ │ +│ ├─────────────────────────────────────────────────────────────────┤ │ +│ │ • gym-common-core (核心工具类、常量、枚举) │ │ +│ │ • gym-common-redis (Redis配置可选) │ │ +│ │ • gym-common-security (安全认证公共组件) │ │ +│ │ • gym-common-log (日志公共组件) │ │ +│ └─────────────────────────────────────────────────────────────────┘ │ +│ │ +│ ┌─────────────────────────────────────────────────────────────────┐ │ +│ │ gym-api API网关模块 │ │ +│ ├─────────────────────────────────────────────────────────────────┤ │ +│ │ • controller (HTTP接口) • dto (数据传输对象) │ │ +│ │ • vo (视图对象) • config (API配置) │ │ +│ └─────────────────────────────────────────────────────────────────┘ │ +│ │ +│ ┌─────────────────────────────────────────────────────────────────┐ │ +│ │ gym-service 业务服务模块 │ │ +│ ├─────────────────────────────────────────────────────────────────┤ │ +│ │ • gym-service-member (会员服务) │ │ +│ │ • gym-service-booking (预约服务) │ │ +│ │ • gym-service-checkin (签到服务) │ │ +│ │ • gym-service-course (课程服务) │ │ +│ │ • gym-service-coach (教练服务) │ │ +│ │ • gym-service-finance (财务服务) │ │ +│ │ • gym-service-data (数据服务) │ │ +│ └─────────────────────────────────────────────────────────────────┘ │ +│ │ +│ ┌─────────────────────────────────────────────────────────────────┐ │ +│ │ gym-domain 领域模型模块 │ │ +│ ├─────────────────────────────────────────────────────────────────┤ │ +│ │ • model (领域模型) • event (领域事件) • service (领域服务) │ │ +│ └─────────────────────────────────────────────────────────────────┘ │ +│ │ +│ ┌─────────────────────────────────────────────────────────────────┐ │ +│ │ gym-infrastructure 基础设施模块 │ │ +│ ├─────────────────────────────────────────────────────────────────┤ │ +│ │ • repository (数据仓储) • cache (缓存配置) │ │ +│ │ • external (外部服务集成) • config (基础配置) │ │ +│ └─────────────────────────────────────────────────────────────────┘ │ +│ │ +│ ┌─────────────────────────────────────────────────────────────────┐ │ +│ │ gym-starter 启动模块 │ │ +│ ├─────────────────────────────────────────────────────────────────┤ │ +│ │ • gym-admin (管理后台启动器) │ │ +│ └─────────────────────────────────────────────────────────────────┘ │ +│ │ +└─────────────────────────────────────────────────────────────────────────┘ +``` + +### 2.2 模块职责 + +| 模块 | 职责 | 依赖 | +| ------------------- | ---------------------------------- | ------------------------------ | +| gym-common-core | 提供通用工具类、常量定义、异常处理 | 无 | +| gym-common-security | 提供JWT认证、权限校验 | gym-common-core | +| gym-common-redis | 提供Redis缓存支持(可选) | gym-common-core | +| gym-common-log | 提供统一日志记录 | gym-common-core | +| gym-api | 提供HTTP接口、路由转发 | gym-service-* | +| gym-service-member | 会员管理业务逻辑 | gym-domain, gym-infrastructure | +| gym-service-booking | 预约管理业务逻辑 | gym-domain, gym-infrastructure | +| gym-service-checkin | 签到管理业务逻辑 | gym-domain, gym-infrastructure | +| gym-service-course | 课程管理业务逻辑 | gym-domain, gym-infrastructure | +| gym-service-coach | 教练管理业务逻辑 | gym-domain, gym-infrastructure | +| gym-service-finance | 财务管理业务逻辑 | gym-domain, gym-infrastructure | +| gym-service-data | 数据分析业务逻辑 | gym-domain, gym-infrastructure | +| gym-domain | 领域模型、领域事件、领域服务 | 无 | +| gym-infrastructure | 数据仓储、缓存、外部服务集成 | gym-domain | +| gym-starter | 应用启动器 | 所有业务模块 | + +### 2.3 模块交互 + +``` +┌─────────────────────────────────────────────────────────────────────────┐ +│ 模块交互 │ +├─────────────────────────────────────────────────────────────────────────┤ +│ │ +│ ┌──────────┐ │ +│ │ 客户端 │ │ +│ └─────┬────┘ │ +│ │ HTTP/HTTPS │ +│ ▼ │ +│ ┌─────────────────────────────────────────────────────────────────┐ │ +│ │ gym-api (API网关) │ │ +│ └─────────────┬───────────────────────────────────────────────┘ │ +│ │ │ +│ ┌─────────┼─────────┐ │ +│ ▼ ▼ ▼ │ +│ ┌────────┐ ┌────────┐ ┌────────┐ │ +│ │member │ │booking │ │checkin │ │ +│ │service │ │service │ │service │ │ +│ └───┬────┘ └───┬────┘ └───┬────┘ │ +│ │ │ │ │ +│ └───────────┼───────────┘ │ +│ ▼ │ +│ ┌───────────────┐ │ +│ │ gym-domain │ │ +│ └───────┬───────┘ │ +│ │ │ +│ ▼ │ +│ ┌───────────────┐ │ +│ │ gym-infra │ │ +│ └───────┬───────┘ │ +│ │ │ +│ ┌───────────┼───────────┐ │ +│ ▼ ▼ ▼ │ +│ ┌────────┐ ┌────────┐ ┌────────┐ │ +│ │ PG │ │Redis │ │External│ │ +│ └────────┘ └────────┘ └────────┘ │ +│ │ +└─────────────────────────────────────────────────────────────────────────┘ +``` + +--- + +## 三、接口设计 + +### 3.1 接口规范 + +#### 3.1.1 RESTful API设计原则 + +- 使用HTTP标准方法:GET(查询)、POST(创建)、PUT(更新)、DELETE(删除) +- 使用HTTP状态码表示请求结果:200(成功)、400(请求错误)、401(未认证)、403(无权限)、404(资源不存在)、500(服务器错误) +- 使用JSON格式进行数据交换 +- 使用统一的响应结构 + +#### 3.1.2 统一响应结构 + +```json +{ + "code": 200, + "message": "success", + "data": {}, + "timestamp": 1234567890 +} +``` + +#### 3.1.3 错误响应结构 + +```json +{ + "code": 400, + "message": "参数错误", + "data": null, + "timestamp": 1234567890 +} +``` + +#### 3.1.4 分页响应结构 + +```json +{ + "code": 200, + "message": "success", + "data": { + "list": [], + "total": 100, + "page": 1, + "pageSize": 10 + }, + "timestamp": 1234567890 +} +``` + +### 3.2 接口分组 + +``` +┌─────────────────────────────────────────────────────────────────────────┐ +│ 接口分组 │ +├─────────────────────────────────────────────────────────────────────────┤ +│ │ +│ ┌─────────────────────────────────────────────────────────────────┐ │ +│ │ 认证接口 /v1/auth │ │ +│ ├─────────────────────────────────────────────────────────────────┤ │ +│ │ • POST /login (登录) • POST /logout (登出) │ │ +│ │ • POST /refresh (刷新Token) • POST /wechat-login (微信登录) │ │ +│ └─────────────────────────────────────────────────────────────────┘ │ +│ │ +│ ┌─────────────────────────────────────────────────────────────────┐ │ +│ │ 会员接口 /v1/members │ │ +│ ├─────────────────────────────────────────────────────────────────┤ │ +│ │ • GET / (会员列表) • GET /{id} (会员详情) │ │ +│ │ • POST / (创建会员) • PUT /{id} (更新会员) │ │ +│ │ • GET /{id}/cards (会员卡列表) • GET /{id}/benefits (权益列表)│ │ +│ │ • GET /{id}/bookings (预约记录) │ │ +│ └─────────────────────────────────────────────────────────────────┘ │ +│ │ +│ ┌─────────────────────────────────────────────────────────────────┐ │ +│ │ 课程接口 /v1/courses │ │ +│ ├─────────────────────────────────────────────────────────────────┤ │ +│ │ • GET / (课程列表) • GET /{id} (课程详情) │ │ +│ │ • POST / (创建课程) • PUT /{id} (更新课程) │ │ +│ │ • GET /{id}/slots (可预约时段) │ │ +│ └─────────────────────────────────────────────────────────────────┘ │ +│ │ +│ ┌─────────────────────────────────────────────────────────────────┐ │ +│ │ 预约接口 /v1/bookings │ │ +│ ├─────────────────────────────────────────────────────────────────┤ │ +│ │ • GET / (预约列表) • GET /{id} (预约详情) │ │ +│ │ • POST / (创建预约) • POST /{id}/cancel (取消预约) │ │ +│ │ • GET /my (我的预约) │ │ +│ └─────────────────────────────────────────────────────────────────┘ │ +│ │ +│ ┌─────────────────────────────────────────────────────────────────┐ │ +│ │ 签到接口 /v1/checkins │ │ +│ ├─────────────────────────────────────────────────────────────────┤ │ +│ │ • GET / (签到列表) • POST /scan (扫码签到) │ │ +│ │ • POST /manual (手动签到) • GET /my (我的签到) │ │ +│ └─────────────────────────────────────────────────────────────────┘ │ +│ │ +│ ┌─────────────────────────────────────────────────────────────────┐ │ +│ │ 教练接口 /v1/coaches │ │ +│ ├─────────────────────────────────────────────────────────────────┤ │ +│ │ • GET / (教练列表) • GET /{id} (教练详情) │ │ +│ │ • GET /{id}/schedule (教练排班) • GET /{id}/slots (可预约时段)│ │ +│ └─────────────────────────────────────────────────────────────────┘ │ +│ │ +│ ┌─────────────────────────────────────────────────────────────────┐ │ +│ │ 数据看板 /v1/dashboard │ │ +│ ├─────────────────────────────────────────────────────────────────┤ │ +│ │ • GET /overview (今日概览) • GET /trends (趋势数据) │ │ +│ │ • GET /rankings (排行数据) │ │ +│ └─────────────────────────────────────────────────────────────────┘ │ +│ │ +└─────────────────────────────────────────────────────────────────────────┘ +``` + +### 3.3 接口版本管理 + +#### 3.3.1 版本策略 + +- 采用URL路径版本控制:/v1/、/v2/ +- 主版本号变更表示不兼容的API变更 +- 次版本号变更表示向后兼容的功能新增 +- 修订版本号变更表示向后兼容的问题修复 + +#### 3.3.2 版本兼容性 + +- 新版本API发布后,旧版本API至少维护6个月 +- 废弃API在响应头中添加Warning字段 +- 提供API版本迁移指南 + +--- + +## 四、安全设计 + +### 4.1 认证机制 + +#### 4.1.1 JWT认证 + +``` +┌─────────────────────────────────────────────────────────────────────────┐ +│ JWT认证流程 │ +├─────────────────────────────────────────────────────────────────────────┤ +│ │ +│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ +│ │ 用户 │────▶│ 登录 │────▶│ 验证 │────▶│ 生成 │ │ +│ │ 登录 │ │ 请求 │ │ 凭证 │ │ Token │ │ +│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ +│ │ │ +│ ▼ │ +│ ┌──────────┐ │ +│ │ 返回 │ │ +│ │ Token │ │ +│ └──────────┘ │ +│ │ │ +│ ▼ │ +│ ┌──────────┐ │ +│ │ 后续 │ │ +│ │ 请求 │ │ +│ └──────────┘ │ +│ │ │ +│ ▼ │ +│ ┌──────────┐ │ +│ │ 携带 │ │ +│ │ Token │ │ +│ └──────────┘ │ +│ │ +│ Token结构: │ +│ • Header: 算法、类型 │ +│ • Payload: 用户ID、角色、过期时间 │ +│ • Signature: 签名 │ +│ │ +└─────────────────────────────────────────────────────────────────────────┘ +``` + +#### 4.1.2 Token刷新机制 + +- Access Token有效期:2小时 +- Refresh Token有效期:7天 +- Access Token过期时使用Refresh Token刷新 +- Refresh Token过期时需要重新登录 + +### 4.2 权限控制 + +#### 4.2.1 RBAC权限模型 + +``` +┌─────────────────────────────────────────────────────────────────────────┐ +│ RBAC权限模型 │ +├─────────────────────────────────────────────────────────────────────────┤ +│ │ +│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ +│ │ 用户 │──▶│ 角色 │──▶│ 权限 │──▶│ 资源 │ │ +│ │ User │ │ Role │ │Permission│ │ Resource │ │ +│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ +│ │ +│ 权限示例: │ +│ • member:view (查看会员) │ +│ • member:edit (编辑会员) │ +│ • member:delete (删除会员) │ +│ • booking:create (创建预约) │ +│ • booking:cancel (取消预约) │ +│ │ +└─────────────────────────────────────────────────────────────────────────┘ +``` + +#### 4.2.2 权限校验流程 + +1. 用户登录后获取角色和权限 +2. 每次请求时校验权限 +3. 无权限时返回403错误 +4. 支持权限继承和组合 + +### 4.3 数据安全 + +#### 4.3.1 数据加密 + +- 敏感数据(手机号、身份证)使用AES-256加密存储 +- 密码使用BCrypt加密 +- 传输数据使用HTTPS加密 +- 数据库连接使用SSL/TLS + +#### 4.3.2 数据脱敏 + +- 手机号脱敏:138****5678 +- 身份证脱敏:110101********1234 +- 银行卡脱敏:6222************1234 + +#### 4.3.3 数据备份 + +- 每日全量备份 +- 每小时增量备份 +- 备份数据加密存储 +- 备份数据异地容灾 + +### 4.4 接口安全 + +#### 4.4.1 防重放攻击 + +- 每个请求携带时间戳 +- 时间戳有效期:5分钟 +- 请求签名验证 + +#### 4.4.2 防SQL注入 + +- 使用参数化查询 +- 使用R2DBC响应式数据库访问 +- 输入参数校验和过滤 + +#### 4.4.3 防XSS攻击 + +- 输入内容过滤和转义 +- 响应头设置Content-Security-Policy +- 使用白名单过滤 + +--- + +## 五、性能设计 + +### 5.1 性能目标 + +| 指标 | 目标值 | 测量方法 | +| -------------- | ---------- | ---------------------- | +| 响应时间 | ≤ 2秒 | 请求响应时间 | +| 并发处理能力 | ≥ 1000 QPS | 每秒处理请求数 | +| 数据库查询时间 | ≤ 100ms | SQL执行时间 | +| 缓存命中率 | ≥ 80% | 缓存命中次数/总请求次数 | +| 系统可用性 | ≥ 99.9% | (总时间-故障时间)/总时间 | + +### 5.2 性能优化策略 + +``` +┌─────────────────────────────────────────────────────────────────────────┐ +│ 性能优化策略 │ +├─────────────────────────────────────────────────────────────────────────┤ +│ │ +│ 1. 缓存策略 │ +│ ├── Caffeine本地缓存 (热点数据) │ +│ ├── Redis分布式缓存 (可选) │ +│ ├── 数据库查询结果缓存 │ +│ └── 缓存预热和失效策略 │ +│ │ +│ 2. 数据库优化 │ +│ ├── 索引优化 │ +│ ├── 查询优化 │ +│ ├── 分页查询 │ +│ └── 读写分离 (后期) │ +│ │ +│ 3. 响应式编程 │ +│ ├── WebFlux非阻塞IO │ +│ ├── R2DBC响应式数据库访问 │ +│ └── 异步处理 │ +│ │ +│ 4. 前端优化 │ +│ ├── 资源压缩 │ +│ ├── CDN加速 │ +│ ├── 懒加载 │ +│ └── 防抖节流 │ +│ │ +└─────────────────────────────────────────────────────────────────────────┘ +``` + +### 5.3 高并发场景处理 + +``` +┌─────────────────────────────────────────────────────────────────────────┐ +│ 高并发场景处理 │ +├─────────────────────────────────────────────────────────────────────────┤ +│ │ +│ 1. 限流保护 │ +│ └── 令牌桶限流,防止系统过载 │ +│ │ +│ 2. 熔断降级 │ +│ └── 服务异常时快速失败,防止雪崩 │ +│ │ +│ 3. 分布式锁 │ +│ └── Redis分布式锁,保证数据一致性 │ +│ │ +│ 4. 乐观锁 │ +│ └── 版本号控制,冲突时重试 │ +│ │ +│ 5. 排队机制 │ +│ └── 请求进入队列,异步处理结果 │ +│ │ +│ 6. 候补机制 │ +│ └── 满员后自动进入候补队列,有人取消时自动补位 │ +│ │ +└─────────────────────────────────────────────────────────────────────────┘ +``` + +--- + +## 六、可扩展性设计 + +### 6.1 水平扩展 + +``` +┌─────────────────────────────────────────────────────────────────────────┐ +│ 水平扩展方案 │ +├─────────────────────────────────────────────────────────────────────────┤ +│ │ +│ 1. 无状态设计 │ +│ ├── Session外置到Redis │ +│ ├── 本地不存储用户状态 │ +│ └── 任意实例可处理任意请求 │ +│ │ +│ 2. 负载均衡 │ +│ ├── 轮询: 默认策略 │ +│ ├── 加权轮询: 根据服务器性能分配权重 │ +│ └── 最少连接: 请求分配给连接数最少的服务器 │ +│ │ +│ 3. 服务拆分(后期) │ +│ ├── 会员服务独立部署 │ +│ ├── 预约服务独立部署 │ +│ └── 数据服务独立部署 │ +│ │ +│ 4. 数据库扩展(后期) │ +│ ├── 读写分离 │ +│ ├── 分库分表 │ +│ └── 多活架构 │ +│ │ +└─────────────────────────────────────────────────────────────────────────┘ +``` + +### 6.2 功能扩展 + +``` +┌─────────────────────────────────────────────────────────────────────────┐ +│ 功能扩展点 │ +├─────────────────────────────────────────────────────────────────────────┤ +│ │ +│ 1. 支付扩展 │ +│ ├── 预留支付接口抽象 │ +│ ├── 支持微信支付、支付宝、银联等 │ +│ └── 可扩展其他支付渠道 │ +│ │ +│ 2. 硬件扩展 │ +│ ├── 签到网关抽象设计 │ +│ ├── 支持多种签到设备 │ +│ └── 可扩展智能硬件 │ +│ │ +│ 3. 消息扩展 │ +│ ├── 消息模板可配置 │ +│ ├── 支持多渠道推送 │ +│ └── 可扩展新的消息渠道 │ +│ │ +│ 4. 报表扩展 │ +│ ├── 报表模板可配置 │ +│ ├── 支持自定义报表 │ +│ └── 可扩展BI工具对接 │ +│ │ +└─────────────────────────────────────────────────────────────────────────┘ +``` + +--- + +## 七、监控与运维 + +### 7.1 监控体系 + +``` +┌─────────────────────────────────────────────────────────────────────────┐ +│ 监控体系 │ +├─────────────────────────────────────────────────────────────────────────┤ +│ │ +│ 1. 基础监控 │ +│ ├── CPU使用率 │ +│ ├── 内存使用率 │ +│ ├── 磁盘使用率 │ +│ ├── 网络IO │ +│ └── 进程状态 │ +│ │ +│ 2. 应用监控 │ +│ ├── JVM监控(GC、堆内存、线程) │ +│ ├── HTTP请求监控(QPS、响应时间、错误率) │ +│ ├── 数据库连接池监控 │ +│ └── 缓存命中率监控 │ +│ │ +│ 3. 业务监控 │ +│ ├── 会员注册数 │ +│ ├── 预约成功率 │ +│ ├── 签到成功率 │ +│ └── 支付成功率 │ +│ │ +│ 4. 告警机制 │ +│ ├── 告警规则配置 │ +│ ├── 告警通知方式(邮件、短信、钉钉) │ +│ └── 告警升级策略 │ +│ │ +└─────────────────────────────────────────────────────────────────────────┘ +``` + +### 7.2 日志规范 + +#### 7.2.1 日志级别 + +- ERROR:错误日志,系统异常 +- WARN:警告日志,潜在问题 +- INFO:信息日志,关键业务操作 +- DEBUG:调试日志,开发调试使用 + +#### 7.2.2 日志格式 + +``` +[时间] [级别] [线程] [类名] - 日志内容 +[2026-03-04 10:00:00] [INFO] [http-nio-8080-exec-1] [com.gym.controller.MemberController] - 会员登录成功, memberId=12345 +``` + +#### 7.2.3 日志存储 + +- 日志文件按日期滚动 +- 日志文件保留30天 +- 错误日志单独存储 +- 支持日志查询和导出 + +--- + +## 八、附录 + +### 8.1 技术选型清单 + +| 技术类别 | 技术选型 | 版本 | 用途 | +| -------------- | --------------------------- | -------- | ------------------ | +| 前端框架 | Vue3 | 3.x | 前端开发 | +| 前端构建 | Vite | 5.x | 前端构建 | +| 跨平台框架 | uniapp | 3.x | 小程序开发 | +| 后端框架 | Spring Boot | 3.x | 应用框架 | +| 响应式编程 | Spring WebFlux | 3.x | 响应式Web开发 | +| 数据库 | PostgreSQL | 15+ | 主数据库 | +| 数据库访问 | R2DBC | 1.x | 响应式数据库访问 | +| 缓存 | Caffeine | 3.x | 本地缓存 | +| 缓存(可选) | Redis | 7.x | 分布式缓存 | +| 安全框架 | Spring Security | 6.x | 安全认证授权 | +| 数据库版本管理 | Flyway | 9.x | 数据库版本管理 | +| 容器化 | Docker | 24+ | 容器化部署 | +| 负载均衡 | Nginx | 1.24+ | 反向代理负载均衡 | + +### 8.2 术语表 + +| 术语 | 定义 | +| ----------------------------- | ------------------------------------------------ | +| 租户(Tenant) | 系统的多租户架构中的独立业务实体,如一个连锁品牌 | +| 门店(Store) | 租户下的具体经营场所 | +| 会员(Member) | 在门店注册的用户 | +| 权益(Benefit) | 会员卡包含的时长、次数、储值、等级等权益 | +| 可预约资源(Bookable Resource) | 团课、私教、场地、线上课程等可被预约的对象 | +| 时段(Slot) | 资源的可预约时间窗口 | +| JWT | JSON Web Token,用于身份认证 | +| RBAC | Role-Based Access Control,基于角色的访问控制 | +| QPS | Queries Per Second,每秒查询数 | +| SLA | Service Level Agreement,服务等级协议 | + +--- + +**文档结束** diff --git a/docs/design/LLD-预约模块详细设计.md b/docs/design/LLD-预约模块详细设计.md index d76db30..006ec36 100644 --- a/docs/design/LLD-预约模块详细设计.md +++ b/docs/design/LLD-预约模块详细设计.md @@ -19,7 +19,8 @@ ## 参考文档 - 《健身房管理系统产品设计文档》 GYM-PRD-001 -- 《健身房管理系统概要设计文档》 GYM-HLD-001 +- 《健身房管理系统业务概要设计文档》 GYM-HLD-001 +- 《健身房管理系统详细设计文档》 GYM-LLD-000 - Spring Boot 3 官方文档 - R2DBC 规范文档 - PostgreSQL 官方文档