# 健身房管理系统基础版技术实现详细设计文档(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 | 张翔 | 创建基础版技术设计文档,整合技术架构和实现细节 |