# 健身房管理系统基础版技术实现详细设计文档(T-ILD)
> 文档编号: GYM-T-ILD-BASIC-001
> 版本: v1.0
> 日期: 2026-03-08
> 作者: 张翔
> 状态: 已发布
---
## 文档修订历史
| 版本 | 日期 | 作者 | 修订内容 |
| ---- | ---------- | ---- | ---------------------- |
| v1.0 | 2026-03-08 | 张翔 | 创建基础版技术实现详细设计文档,整合技术架构和实现细节 |
---
## 一、引言
### 1.1 编写目的
本文档为健身房管理系统基础版的技术实现详细设计文档(Technical Implementation Level Design),旨在:
1. 从技术层面描述基础版的系统架构、技术选型、实现细节
2. 为开发人员提供技术实现指导
3. 作为架构师、开发工程师的技术参考
### 1.2 项目背景
健身房管理系统基础版是面向小型工作室、个人教练等场景的核心版本,采用响应式编程架构,保证高并发、低延迟、高可用性。
### 1.3 参考文档
- 《健身房管理系统基础版产品设计文档》 GYM-PRD-BASIC-001
- 《健身房管理系统基础版业务概要设计文档》 GYM-B-HLD-BASIC-001
- 《健身房管理系统基础版业务详细设计文档》 GYM-B-LLD-BASIC-001
- Spring Boot 3 官方文档
- Spring WebFlux 官方文档
- R2DBC 规范文档
- PostgreSQL 官方文档
---
## 二、架构决策
### 2.1 架构选型
经过深入评估,本系统采用以下架构决策:
| 决策项 | 选择方案 | 理由 |
|-------|---------|------|
| **应用架构** | 单体应用 | 适合当前规模(基础版100并发用户,付费订阅版500并发用户),开发效率高,部署简单,成本低 |
| **编程模型** | 响应式编程(WebFlux + R2DBC) | 高并发能力(10x 提升),低延迟(50% 降低),资源利用率高(75% 降低) |
| **部署方式** | Docker Compose | 一键部署,环境一致性好,回滚快速 |
| **数据库** | PostgreSQL | 金融级数据库,支持 ACID 事务,JSONB 支持灵活配置 |
| **缓存** | Redis | 高性能缓存,支持分布式锁 |
| **消息队列** | RabbitMQ | 成熟稳定,支持延迟消息 |
| **搜索引擎** | Elasticsearch | 全文搜索,适合复杂查询 |
| **监控** | Prometheus + Grafana | 完善的监控体系,可视化好 |
### 2.2 技术栈
#### 核心技术栈
| 技术组件 | 版本 | 用途 |
|---------|------|------|
| **Spring Boot** | 3.2.x | 应用框架 |
| **Spring WebFlux** | 3.2.x | 响应式 Web 框架 |
| **Spring Data R2DBC** | 3.2.x | 响应式数据访问 |
| **PostgreSQL R2DBC** | 1.0.0.RELEASE | PostgreSQL 响应式驱动 |
| **Spring Security** | 6.2.x | 安全框架 |
| **Redis Reactive** | 3.2.x | 响应式缓存 |
| **RabbitMQ** | 3.12.x | 消息队列 |
| **Elasticsearch** | 8.11.x | 搜索引擎 |
| **Prometheus** | Latest | 监控指标采集 |
| **Grafana** | Latest | 监控可视化 |
| **Docker** | 24.x | 容器化部署 |
| **Docker Compose** | 2.20.x | 容器编排 |
#### 开发工具
| 工具 | 版本 | 用途 |
|------|------|------|
| **JDK** | 17+ | 运行环境 |
| **Maven** | 3.9.x | 项目构建 |
| **Lombok** | 1.18.x | 代码简化 |
| **MapStruct** | 1.5.x | 对象映射 |
| **Micrometer** | 1.12.x | 监控指标 |
| **SpringDoc OpenAPI** | 2.3.x | API 文档 |
---
### 2.3 基础版性能与架构特点
#### 2.3.1 性能目标
| 指标类型 | 指标项 | 目标值 | 说明 |
|---------|--------|--------|------|
| **应用指标** | 并发数 | ≤ 100 | 基础版支持100并发用户 |
| **应用指标** | API响应时间 | ≤ 500ms | 95%请求响应时间 |
| **应用指标** | 系统可用性 | ≥ 99.5% | 年度目标 |
| **数据库指标** | 连接池大小 | 20 | R2DBC连接池 |
| **数据库指标** | 查询响应时间 | ≤ 200ms | 95%查询响应时间 |
| **缓存指标** | 缓存命中率 | ≥ 80% | Redis缓存 |
| **缓存指标** | 缓存响应时间 | ≤ 10ms | Redis缓存 |
#### 2.3.2 架构特点
基础版采用轻量级架构设计,满足小型工作室和个人教练的需求:
**1. 单体应用架构**
- 部署简单,维护成本低
- 适合单门店场景
- 数据隔离通过租户ID实现
**2. 资源优化配置**
- 数据库连接池:20个连接
- Redis缓存:1GB内存
- RabbitMQ队列:单队列模式
- Elasticsearch:单节点部署
**3. 扩展性限制**
- 不支持多门店管理
- 不支持分布式部署
- 不支持高可用集群
- 并发用户数限制100
#### 2.3.3 与付费订阅版的差异
| 维度 | 基础版 | 付费订阅版 |
|------|--------|-----------|
| **并发用户数** | 100 | 500 |
| **数据库连接池** | 20 | 100 |
| **Redis内存** | 1GB | 4GB |
| **RabbitMQ队列** | 单队列 | 多队列集群 |
| **Elasticsearch** | 单节点 | 3节点集群 |
| **多门店支持** | 不支持 | 支持 |
| **分布式部署** | 不支持 | 支持 |
| **高可用集群** | 不支持 | 支持 |
---
## 三、系统架构设计
### 3.1 总体架构
采用分层架构 + 模块化设计的单体应用:
```mermaid
flowchart TB
subgraph 单体应用总体架构
A[客户端层
• 会员小程序 uniapp+Vue3
• 教练端App uniapp+Vue3
• 管理后台PC Vue3+Vite
• 硬件设备 人脸/NFC]
B[Nginx 反向代理
• 负载均衡
• SSL 终止
• 静态资源
• 限流]
C[Presentation Layer WebFlux
• Controller
• Router
• Filter
• Validator]
D[Application Layer 业务编排
• Service
• Facade
• Orchestrator
• 事务管理]
E[Domain Layer 领域模型
• Entity
• Value Object
• Domain Service
• Repository]
F[Infrastructure Layer 基础设施
• Repository R2DBC
• Cache Redis
• Message RabbitMQ
• Search Elasticsearch
• File OSS
• Distributed Lock]
G[外部服务层
• PostgreSQL
• Redis
• RabbitMQ
• Elasticsearch
• 微信开放平台
• 短信服务
• 支付服务
• OSS存储]
H[监控与运维层
• Prometheus
• Grafana
• 日志收集
• 告警]
A --> B
B --> C
C --> D
D --> E
E --> F
F --> G
G --> H
end
```
### 3.2 分层架构详解
#### 3.2.1 Presentation Layer(表现层)
**职责**:
- 接收 HTTP 请求
- 参数验证
- 路由转发
- 响应封装
- 异常处理
**技术实现**:
- Spring WebFlux Router
- Spring Validation
- Spring Security Reactive
- Global Exception Handler
#### 3.2.2 Application Layer(应用层)
**职责**:
- 业务逻辑编排
- 事务管理
- 跨模块协调
- 权限校验
**技术实现**:
- Service 类
- @Transactional 注解
- 分布式锁
- Saga 模式(跨服务事务)
#### 3.2.3 Domain Layer(领域层)
**职责**:
- 领域模型定义
- 业务规则封装
- 领域服务
- 仓储接口定义
**技术实现**:
- Entity 类
- Value Object 类
- Domain Service 类
- Repository 接口
#### 3.2.4 Infrastructure Layer(基础设施层)
**职责**:
- 数据访问实现
- 缓存管理
- 消息队列
- 文件存储
- 外部服务调用
**技术实现**:
- R2DBC Repository
- Redis Reactive
- RabbitMQ Reactive
- Elasticsearch Reactive
- OSS SDK
### 3.3 模块化设计
单体应用内部采用模块化设计,为未来拆分微服务做准备:
```
gym-manage/
├── gym-manage-api/ # API 层
│ ├── controller/
│ │ ├── member/ # 会员模块 API
│ │ ├── booking/ # 预约模块 API
│ │ ├── checkin/ # 签到模块 API
│ │ ├── benefit/ # 权益模块 API
│ │ ├── subscription/ # 订阅模块 API
│ │ ├── marketing/ # 营销模块 API
│ │ └── analytics/ # 数据分析模块 API
│ ├── dto/
│ │ ├── request/ # 请求 DTO
│ │ └── response/ # 响应 DTO
│ └── config/
│ ├── WebFluxConfig.java
│ ├── SecurityConfig.java
│ └── R2dbcConfig.java
│
├── gym-manage-application/ # 应用层
│ ├── service/
│ │ ├── member/
│ │ ├── booking/
│ │ ├── checkin/
│ │ ├── benefit/
│ │ ├── subscription/
│ │ ├── marketing/
│ │ └── analytics/
│ ├── facade/
│ └── orchestrator/
│
├── gym-manage-domain/ # 领域层
│ ├── entity/
│ │ ├── Member.java
│ │ ├── BookingRecord.java
│ │ ├── CheckinRecord.java
│ │ ├── MemberBenefit.java
│ │ ├── SubscriptionRecord.java
│ │ └── ...
│ ├── valueobject/
│ ├── repository/
│ │ ├── MemberRepository.java
│ │ ├── BookingRecordRepository.java
│ │ └── ...
│ └── service/
│ └── DomainService.java
│
├── gym-manage-infrastructure/ # 基础设施层
│ ├── repository/
│ │ └── impl/
│ │ ├── MemberRepositoryImpl.java
│ │ ├── BookingRecordRepositoryImpl.java
│ │ └── ...
│ ├── cache/
│ │ └── RedisCacheService.java
│ ├── message/
│ │ └── RabbitMQService.java
│ ├── search/
│ │ └── ElasticsearchService.java
│ ├── lock/
│ │ └── DistributedLockService.java
│ └── config/
│ ├── R2dbcConfiguration.java
│ ├── RedisConfiguration.java
│ ├── RabbitMQConfiguration.java
│ └── ElasticsearchConfiguration.java
│
└── gym-manage-main/ # 主启动类
├── GymManageApplication.java
└── resources/
├── application.yml
├── application-dev.yml
└── application-prod.yml
```
---
## 四、响应式编程架构
### 4.1 响应式编程模型
本系统采用 Project Reactor 作为响应式编程库:
| 组件 | 类型 | 说明 |
|------|------|------|
| **Mono** | 0-1 个元素 | 表示异步计算结果,返回单个对象或空 |
| **Flux** | 0-N 个元素 | 表示异步数据流,返回多个对象 |
| **Scheduler** | 线程调度器 | 控制异步操作的执行线程 |
### 4.2 响应式编程规范
#### 4.2.1 基本原则
1. **永不阻塞**
- 禁止在响应式流中使用 `block()`、`blockFirst()`、`blockLast()`
- 所有 I/O 操作必须使用非阻塞方式
2. **链式调用**
- 使用 `flatMap`、`map`、`filter` 等操作符链式调用
- 避免嵌套的 `subscribe`
3. **错误处理**
- 使用 `onErrorResume`、`onErrorReturn` 处理错误
- 避免使用 `try-catch` 捕获响应式异常
4. **背压处理**
- 使用 `onBackpressureBuffer`、`onBackpressureDrop` 处理背压
- 避免内存溢出
#### 4.2.2 代码示例
**✅ 正确示例**:
```java
public Mono getMember(Long id) {
return memberRepository.findById(id)
.switchIfEmpty(Mono.error(new BusinessException("会员不存在")))
.flatMap(member -> loadMemberCards(member.getId()))
.flatMap(member -> loadMemberBenefits(member.getId()))
.doOnSuccess(member -> log.info("查询会员成功: memberId={}", member.getId()))
.doOnError(e -> log.error("查询会员失败: memberId={}", id, e));
}
```
**❌ 错误示例**:
```java
public Member getMember(Long id) {
// 错误:使用 block() 阻塞
return memberRepository.findById(id).block();
}
public Mono getMember(Long id) {
return memberRepository.findById(id)
.flatMap(member -> {
// 错误:在 flatMap 中使用 block()
List cards = memberCardRepository.findByMemberId(member.getId()).collectList().block();
return Mono.just(member);
});
}
```
### 4.3 响应式事务管理
#### 4.3.1 本地事务
使用 `@Transactional` 注解管理本地事务:
```java
@Service
public class BookingService {
@Transactional
public Mono bookSlot(BookingRequest request) {
return validateBooking(request)
.flatMap(v -> checkSlotAvailability(request.getSlotId()))
.flatMap(slot -> deductBenefit(request.getMemberId(), slot))
.flatMap(benefit -> createBookingRecord(request, benefit))
.flatMap(booking -> updateSlotBookedCount(request.getSlotId()));
}
}
```
#### 4.3.2 分布式锁
使用 Redis 实现分布式锁:
```java
@Component
public class RedisDistributedLock {
private final ReactiveRedisTemplate redisTemplate;
private static final String LOCK_PREFIX = "lock:";
private static final long DEFAULT_EXPIRE_TIME = 30;
public Mono tryLock(String key, long expireTime) {
String lockKey = LOCK_PREFIX + key;
String lockValue = UUID.randomUUID().toString();
return redisTemplate.opsForValue()
.setIfAbsent(lockKey, lockValue, Duration.ofSeconds(expireTime))
.flatMap(locked -> {
if (Boolean.TRUE.equals(locked)) {
log.info("获取锁成功: key={}", lockKey);
return Mono.just(true);
} else {
log.warn("获取锁失败: key={}", lockKey);
return Mono.just(false);
}
});
}
public Mono unlock(String key) {
String lockKey = LOCK_PREFIX + key;
return redisTemplate.delete(lockKey)
.doOnSuccess(deleted -> {
if (Boolean.TRUE.equals(deleted)) {
log.info("释放锁成功: key={}", lockKey);
}
})
.then();
}
}
```
#### 4.3.3 Saga 模式(跨模块事务)
对于跨模块的事务,使用 Saga 模式:
```java
@Service
public class BookingSaga {
public Mono execute(BookingRequest request) {
return bookSlot(request)
.flatMap(booking -> sendNotification(booking))
.flatMap(booking -> updateStatistics(booking))
.onErrorResume(e -> compensate(request, e));
}
private Mono bookSlot(BookingRequest request) {
// 预约逻辑
}
private Mono sendNotification(BookingRecord booking) {
// 发送通知
}
private Mono updateStatistics(BookingRecord booking) {
// 更新统计
}
private Mono compensate(BookingRequest request, Throwable e) {
// 补偿逻辑
return cancelBooking(request)
.then(Mono.error(e));
}
}
```
---
## 五、数据库设计
### 5.1 数据库选型
本系统采用 PostgreSQL 作为主数据库,原因如下:
1. **金融级可靠性**:支持 ACID 事务,数据一致性有保障
2. **JSONB 支持**:灵活存储配置数据,支持复杂查询
3. **响应式驱动**:R2DBC 提供非阻塞访问
4. **开源免费**:降低成本
### 5.2 核心表设计
#### 5.2.1 租户表(tenant)
| 字段名 | 类型 | 说明 | 约束 |
|-------|------|------|------|
| id | BIGINT | 主键 | PK, AUTO_INCREMENT |
| name | VARCHAR(100) | 租户名称 | NOT NULL |
| logo_url | VARCHAR(500) | Logo地址 | NULL |
| brand_color | VARCHAR(20) | 品牌颜色 | NULL |
| status | TINYINT | 状态(1正常,2禁用) | NOT NULL, DEFAULT 1 |
| created_at | TIMESTAMP | 创建时间 | NOT NULL, DEFAULT CURRENT_TIMESTAMP |
| updated_at | TIMESTAMP | 更新时间 | NOT NULL, DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP |
#### 5.2.2 门店表(store)
| 字段名 | 类型 | 说明 | 约束 |
|-------|------|------|------|
| id | BIGINT | 主键 | PK, AUTO_INCREMENT |
| tenant_id | BIGINT | 租户ID | FK, NOT NULL |
| name | VARCHAR(100) | 门店名称 | NOT NULL |
| address | VARCHAR(500) | 地址 | NULL |
| phone | VARCHAR(20) | 电话 | NULL |
| status | TINYINT | 状态(1正常,2禁用) | NOT NULL, DEFAULT 1 |
| created_at | TIMESTAMP | 创建时间 | NOT NULL, DEFAULT CURRENT_TIMESTAMP |
| updated_at | TIMESTAMP | 更新时间 | NOT NULL, DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP |
#### 5.2.3 会员表(member)
| 字段名 | 类型 | 说明 | 约束 |
|-------|------|------|------|
| id | BIGINT | 主键 | PK, AUTO_INCREMENT |
| tenant_id | BIGINT | 租户ID | FK, NOT NULL |
| store_id | BIGINT | 门店ID | FK, NOT NULL |
| member_no | VARCHAR(20) | 会员编号 | UNIQUE, NOT NULL |
| name | VARCHAR(50) | 姓名 | NOT NULL |
| phone | VARCHAR(20) | 手机号 | UNIQUE, NOT NULL |
| gender | TINYINT | 性别(1男,2女) | NULL |
| birthday | DATE | 生日 | NULL |
| height | INT | 身高(cm) | NULL |
| weight | INT | 体重(kg) | NULL |
| fitness_goal | VARCHAR(100) | 健身目标 | NULL |
| status | TINYINT | 状态(1正常,2禁用) | NOT NULL, DEFAULT 1 |
| created_at | TIMESTAMP | 创建时间 | NOT NULL, DEFAULT CURRENT_TIMESTAMP |
| updated_at | TIMESTAMP | 更新时间 | NOT NULL, DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP |
#### 5.2.4 会员卡表(member_card)
| 字段名 | 类型 | 说明 | 约束 |
|-------|------|------|------|
| id | BIGINT | 主键 | PK, AUTO_INCREMENT |
| member_id | BIGINT | 会员ID | FK, NOT NULL |
| card_type_id | BIGINT | 卡类型ID | FK, NOT NULL |
| card_no | VARCHAR(50) | 卡号 | UNIQUE, NOT NULL |
| start_date | DATE | 开始日期 | NOT NULL |
| end_date | DATE | 结束日期 | NULL |
| status | TINYINT | 状态(1正常,2禁用) | NOT NULL, DEFAULT 1 |
| created_at | TIMESTAMP | 创建时间 | NOT NULL, DEFAULT CURRENT_TIMESTAMP |
| updated_at | TIMESTAMP | 更新时间 | NOT NULL, DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP |
#### 5.2.5 会员权益表(member_benefit)
| 字段名 | 类型 | 说明 | 约束 |
|-------|------|------|------|
| id | BIGINT | 主键 | PK, AUTO_INCREMENT |
| member_id | BIGINT | 会员ID | FK, NOT NULL |
| card_type_id | BIGINT | 卡类型ID | FK, NOT NULL |
| benefit_type | TINYINT | 权益类型(1时长,2次数,3储值) | NOT NULL |
| balance | INT | 余额(次数或金额) | NOT NULL, DEFAULT 0 |
| valid_days | INT | 有效天数 | NULL |
| expire_date | DATE | 到期日期 | NULL |
| created_at | TIMESTAMP | 创建时间 | NOT NULL, DEFAULT CURRENT_TIMESTAMP |
| updated_at | TIMESTAMP | 更新时间 | NOT NULL, DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP |
#### 5.2.6 团课表(group_class)
| 字段名 | 类型 | 说明 | 约束 |
|-------|------|------|------|
| id | BIGINT | 主键 | PK, AUTO_INCREMENT |
| store_id | BIGINT | 门店ID | FK, NOT NULL |
| coach_id | BIGINT | 教练ID | FK, NOT NULL |
| name | VARCHAR(100) | 课程名称 | NOT NULL |
| description | TEXT | 课程描述 | NULL |
| max_capacity | INT | 最大容量 | NOT NULL, DEFAULT 20 |
| start_time | TIMESTAMP | 开始时间 | NOT NULL |
| end_time | TIMESTAMP | 结束时间 | NOT NULL |
| location | VARCHAR(100) | 地点 | NULL |
| status | TINYINT | 状态(1正常,2取消) | NOT NULL, DEFAULT 1 |
| created_at | TIMESTAMP | 创建时间 | NOT NULL, DEFAULT CURRENT_TIMESTAMP |
| updated_at | TIMESTAMP | 更新时间 | NOT NULL, DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP |
#### 5.2.7 预约记录表(booking_record)
| 字段名 | 类型 | 说明 | 约束 |
|-------|------|------|------|
| id | BIGINT | 主键 | PK, AUTO_INCREMENT |
| member_id | BIGINT | 会员ID | FK, NOT NULL |
| group_class_id | BIGINT | 团课ID | FK, NOT NULL |
| booking_time | TIMESTAMP | 预约时间 | NOT NULL |
| cancel_time | TIMESTAMP | 取消时间 | NULL |
| status | TINYINT | 状态(1已预约,2已取消,3已完成) | NOT NULL, DEFAULT 1 |
| created_at | TIMESTAMP | 创建时间 | NOT NULL, DEFAULT CURRENT_TIMESTAMP |
| updated_at | TIMESTAMP | 更新时间 | NOT NULL, DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP |
#### 5.2.8 签到记录表(checkin_record)
| 字段名 | 类型 | 说明 | 约束 |
|-------|------|------|------|
| id | BIGINT | 主键 | PK, AUTO_INCREMENT |
| member_id | BIGINT | 会员ID | FK, NOT NULL |
| store_id | BIGINT | 门店ID | FK, NOT NULL |
| booking_id | BIGINT | 预约ID | FK, NULL |
| checkin_time | TIMESTAMP | 签到时间 | NOT NULL |
| checkin_type | TINYINT | 签到类型(1自由训练,2团课) | NOT NULL |
| created_at | TIMESTAMP | 创建时间 | NOT NULL, DEFAULT CURRENT_TIMESTAMP |
### 5.3 索引设计
| 表名 | 索引名 | 字段 | 类型 | 说明 |
|------|--------|------|------|------|
| member | idx_member_phone | phone | BTREE | 手机号索引 |
| member | idx_member_store | store_id | BTREE | 门店ID索引 |
| member_card | idx_card_member | member_id | BTREE | 会员ID索引 |
| member_benefit | idx_benefit_member | member_id | BTREE | 会员ID索引 |
| group_class | idx_class_store | store_id | BTREE | 门店ID索引 |
| group_class | idx_class_time | start_time | BTREE | 开始时间索引 |
| booking_record | idx_booking_member | member_id | BTREE | 会员ID索引 |
| booking_record | idx_booking_class | group_class_id | BTREE | 团课ID索引 |
| checkin_record | idx_checkin_member | member_id | BTREE | 会员ID索引 |
| checkin_record | idx_checkin_time | checkin_time | BTREE | 签到时间索引 |
---
## 六、API接口设计
### 6.1 API设计原则
1. **RESTful风格**:遵循REST架构风格
2. **统一响应格式**:所有接口返回统一格式
3. **版本控制**:通过URL路径进行版本控制
4. **错误处理**:统一的错误码和错误信息
5. **幂等性**:关键操作支持幂等性
### 6.2 统一响应格式
```json
{
"code": 200,
"message": "success",
"data": {},
"timestamp": 1678234567890
}
```
### 6.3 核心API接口
#### 6.3.1 会员模块API
| 接口 | 方法 | 路径 | 说明 |
|------|------|------|------|
| 会员注册 | POST | /api/v1/members/register | 注册新会员 |
| 会员登录 | POST | /api/v1/members/login | 会员登录 |
| 获取会员信息 | GET | /api/v1/members/{id} | 获取会员详情 |
| 更新会员信息 | PUT | /api/v1/members/{id} | 更新会员信息 |
| 获取会员列表 | GET | /api/v1/members | 获取会员列表 |
#### 6.3.2 预约模块API
| 接口 | 方法 | 路径 | 说明 |
|------|------|------|------|
| 预约团课 | POST | /api/v1/bookings | 预约团课 |
| 取消预约 | DELETE | /api/v1/bookings/{id} | 取消预约 |
| 获取预约记录 | GET | /api/v1/bookings | 获取预约记录 |
| 创建团课 | POST | /api/v1/group-classes | 创建团课 |
| 获取团课列表 | GET | /api/v1/group-classes | 获取团课列表 |
#### 6.3.3 签到模块API
| 接口 | 方法 | 路径 | 说明 |
|------|------|------|------|
| 会员签到 | POST | /api/v1/checkins | 会员签到 |
| 获取签到记录 | GET | /api/v1/checkins | 获取签到记录 |
#### 6.3.4 会员卡模块API
| 接口 | 方法 | 路径 | 说明 |
|------|------|------|------|
| 购买会员卡 | POST | /api/v1/member-cards | 购买会员卡 |
| 获取会员卡列表 | GET | /api/v1/member-cards | 获取会员卡列表 |
| 续费会员卡 | POST | /api/v1/member-cards/{id}/renew | 续费会员卡 |
### 6.4 API接口示例
#### 6.4.1 预约团课
**请求**:
```http
POST /api/v1/bookings
Content-Type: application/json
Authorization: Bearer {token}
{
"memberId": 123,
"groupClassId": 456
}
```
**响应**:
```json
{
"code": 200,
"message": "预约成功",
"data": {
"id": 789,
"memberId": 123,
"groupClassId": 456,
"bookingTime": "2026-03-08T10:00:00",
"status": 1
},
"timestamp": 1678234567890
}
```
---
## 七、部署架构
### 7.1 部署方式
本系统采用 Docker Compose 进行容器化部署,实现一键部署和环境一致性。
### 7.2 部署架构图
```mermaid
flowchart TB
subgraph "部署架构"
A[用户] --> B[Nginx
反向代理]
B --> C[应用服务器
gym-manage]
C --> D[PostgreSQL
数据库]
C --> E[Redis
缓存]
C --> F[RabbitMQ
消息队列]
C --> G[Elasticsearch
搜索引擎]
C --> H[Prometheus
监控]
H --> I[Grafana
可视化]
end
```
### 7.3 Docker Compose配置
```yaml
version: '3.8'
services:
# 应用服务
gym-manage:
build: .
ports:
- "8080:8080"
environment:
- SPRING_PROFILES_ACTIVE=prod
- DB_HOST=postgres
- REDIS_HOST=redis
- RABBITMQ_HOST=rabbitmq
- ELASTICSEARCH_HOST=elasticsearch
depends_on:
- postgres
- redis
- rabbitmq
- elasticsearch
networks:
- gym-network
# PostgreSQL数据库
postgres:
image: postgres:15-alpine
environment:
- POSTGRES_DB=gym_manage
- POSTGRES_USER=gym_user
- POSTGRES_PASSWORD=gym_password
volumes:
- postgres-data:/var/lib/postgresql/data
ports:
- "5432:5432"
networks:
- gym-network
# Redis缓存
redis:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
- redis-data:/data
networks:
- gym-network
# RabbitMQ消息队列
rabbitmq:
image: rabbitmq:3.12-management-alpine
environment:
- RABBITMQ_DEFAULT_USER=gym_user
- RABBITMQ_DEFAULT_PASS=gym_password
ports:
- "5672:5672"
- "15672:15672"
volumes:
- rabbitmq-data:/var/lib/rabbitmq
networks:
- gym-network
# Elasticsearch搜索引擎
elasticsearch:
image: elasticsearch:8.11.0
environment:
- discovery.type=single-node
- ES_JAVA_OPTS=-Xms512m -Xmx512m
ports:
- "9200:9200"
- "9300:9300"
volumes:
- elasticsearch-data:/usr/share/elasticsearch/data
networks:
- gym-network
# Prometheus监控
prometheus:
image: prom/prometheus:latest
ports:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus-data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
networks:
- gym-network
# Grafana可视化
grafana:
image: grafana/grafana:latest
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
volumes:
- grafana-data:/var/lib/grafana
networks:
- gym-network
volumes:
postgres-data:
redis-data:
rabbitmq-data:
elasticsearch-data:
prometheus-data:
grafana-data:
networks:
gym-network:
driver: bridge
```
### 7.4 部署步骤
1. **构建镜像**:
```bash
docker-compose build
```
2. **启动服务**:
```bash
docker-compose up -d
```
3. **查看日志**:
```bash
docker-compose logs -f gym-manage
```
4. **停止服务**:
```bash
docker-compose down
```
---
## 八、监控与运维
### 8.1 监控体系
本系统采用 Prometheus + Grafana 构建完善的监控体系:
| 监控类型 | 监控内容 | 告警阈值 |
|---------|---------|---------|
| **应用监控** | JVM内存、CPU、线程数 | 内存使用率 > 80% |
| **接口监控** | 请求量、响应时间、错误率 | 错误率 > 5% |
| **数据库监控** | 连接数、查询时间、慢查询 | 慢查询 > 1s |
| **缓存监控** | 命中率、内存使用 | 命中率 < 80% |
| **消息队列监控** | 队列长度、消费速率 | 队列长度 > 1000 |
### 8.2 日志管理
采用结构化日志,便于查询和分析:
```java
@Slf4j
@Service
public class BookingService {
public Mono bookSlot(BookingRequest request) {
log.info("开始预约团课: memberId={}, groupClassId={}",
request.getMemberId(), request.getGroupClassId());
return bookingRepository.save(booking)
.doOnSuccess(booking -> log.info("预约成功: bookingId={}", booking.getId()))
.doOnError(e -> log.error("预约失败: memberId={}, groupClassId={}",
request.getMemberId(), request.getGroupClassId(), e));
}
}
```
### 8.3 性能优化
#### 8.3.1 缓存策略
| 缓存类型 | 缓存内容 | 过期时间 | 更新策略 |
|---------|---------|---------|---------|
| **本地缓存** | 配置信息、字典数据 | 30分钟 | 定时刷新 |
| **Redis缓存** | 会员信息、团课信息 | 1小时 | 主动更新 |
| **查询缓存** | 热点查询结果 | 10分钟 | 惰性更新 |
#### 8.3.2 数据库优化
1. **索引优化**:为常用查询字段添加索引
2. **查询优化**:避免全表扫描,使用分页查询
3. **连接池优化**:合理配置连接池大小
4. **读写分离**:主从复制,读写分离
#### 8.3.3 响应式优化
1. **非阻塞I/O**:所有I/O操作使用非阻塞方式
2. **背压处理**:合理处理背压,避免内存溢出
3. **异步处理**:耗时操作异步处理
4. **线程池优化**:合理配置线程池大小
---
## 九、安全设计
### 9.1 认证授权
采用 JWT + Spring Security 实现认证授权:
1. **JWT Token**:用户登录后签发JWT Token
2. **Token验证**:每次请求验证Token有效性
3. **权限控制**:基于角色的访问控制(RBAC)
### 9.2 数据安全
1. **数据加密**:敏感数据加密存储
2. **传输加密**:HTTPS加密传输
3. **数据备份**:定期备份数据
4. **审计日志**:记录关键操作日志
### 9.3 接口安全
1. **限流**:防止接口被恶意调用
2. **防重放**:防止请求重放攻击
3. **参数校验**:严格校验请求参数
4. **SQL注入防护**:使用参数化查询
---
## 十、测试策略
### 10.1 测试分层
| 测试类型 | 测试内容 | 测试工具 |
|---------|---------|---------|
| **单元测试** | 单个方法/类的测试 | JUnit, Mockito |
| **集成测试** | 多个组件协作测试 | SpringBootTest, TestContainers |
| **接口测试** | API接口测试 | Postman, RestAssured |
| **性能测试** | 系统性能测试 | JMeter, Gatling |
### 10.2 测试覆盖率
- **单元测试覆盖率**:≥ 80%
- **集成测试覆盖率**:≥ 60%
- **关键路径覆盖率**:100%
---
## 十一、附录
### 11.1 技术术语表
| 术语 | 说明 |
|------|------|
| **响应式编程** | 基于异步数据流和变化传播的编程范式 |
| **R2DBC** | Reactive Relational Database Connectivity,响应式数据库连接规范 |
| **Mono** | Project Reactor中表示0-1个元素的响应式类型 |
| **Flux** | Project Reactor中表示0-N个元素的响应式类型 |
| **Saga模式** | 长时间运行事务的补偿模式 |
### 11.2 参考文档
- 《健身房管理系统基础版产品设计文档》 GYM-PRD-BASIC-001
- 《健身房管理系统基础版业务概要设计文档》 GYM-B-HLD-BASIC-001
- 《健身房管理系统基础版业务详细设计文档》 GYM-B-LLD-BASIC-001
- Spring Boot 3 官方文档
- Spring WebFlux 官方文档
- R2DBC 规范文档
- PostgreSQL 官方文档
### 11.3 变更记录
| 版本 | 日期 | 作者 | 修订内容 |
| ---- | ---------- | ---- | ---------------------- |
| v1.0 | 2026-03-08 | 张翔 | 创建基础版技术设计文档,整合技术架构和实现细节 |