diff --git a/docs/design/HLD-系统概要设计.md b/docs/design/HLD-系统概要设计.md index d30b0be..51c4877 100644 --- a/docs/design/HLD-系统概要设计.md +++ b/docs/design/HLD-系统概要设计.md @@ -79,36 +79,54 @@ ### 2.3 业务范围 -``` -┌─────────────────────────────────────────────────────────────────┐ -│ 业务范围 │ -├─────────────────────────────────────────────────────────────────┤ -│ │ -│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ -│ │ 会员管理 │ │ 预约管理 │ │ 签到管理 │ │ -│ │ 会员注册 │ │ 团课预约 │ │ 扫码签到 │ │ -│ │ 会员卡管理 │ │ 私教预约 │ │ 刷脸签到 │ │ -│ │ 权益管理 │ │ 场地预约 │ │ NFC签到 │ │ -│ │ 等级管理 │ │ 线上课程 │ │ 教练代签 │ │ -│ └─────────────┘ └─────────────┘ └─────────────┘ │ -│ │ -│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ -│ │ 课程管理 │ │ 教练管理 │ │ 财务管理 │ │ -│ │ 课程类型 │ │ 教练信息 │ │ 营收统计 │ │ -│ │ 课程排期 │ │ 排班管理 │ │ 账单管理 │ │ -│ │ 场地管理 │ │ 课时统计 │ │ 退款管理 │ │ -│ │ 价格配置 │ │ 评价管理 │ │ 对账管理 │ │ -│ └─────────────┘ └─────────────┘ └─────────────┘ │ -│ │ -│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ -│ │ 计划中心 │ │ 数据分析 │ │ 系统管理 │ │ -│ │ 训练计划 │ │ 会员分析 │ │ 租户管理 │ │ -│ │ 课程排期 │ │ 课程分析 │ │ 门店管理 │ │ -│ │ 会员目标 │ │ 财务分析 │ │ 权限管理 │ │ -│ │ 教练排班 │ │ 运营分析 │ │ 系统配置 │ │ -│ └─────────────┘ └─────────────┘ └─────────────┘ │ -│ │ -└─────────────────────────────────────────────────────────────────┘ +```mermaid +mindmap + root((业务范围)) + 会员管理 + 会员注册 + 会员卡管理 + 权益管理 + 等级管理 + 预约管理 + 团课预约 + 私教预约 + 场地预约 + 线上课程 + 签到管理 + 扫码签到 + 刷脸签到 + NFC签到 + 教练代签 + 课程管理 + 课程类型 + 课程排期 + 场地管理 + 价格配置 + 教练管理 + 教练信息 + 排班管理 + 课时统计 + 评价管理 + 财务管理 + 营收统计 + 账单管理 + 退款管理 + 对账管理 + 计划中心 + 训练计划 + 课程排期 + 会员目标 + 教练排班 + 数据分析 + 会员分析 + 课程分析 + 财务分析 + 运营分析 + 系统管理 + 租户管理 + 门店管理 + 权限管理 + 系统配置 ``` --- @@ -119,147 +137,186 @@ 采用分层架构 + 微服务思想的模块化设计: -``` -┌─────────────────────────────────────────────────────────────────────────┐ -│ 客户端层 │ -├──────────────────┬──────────────────┬──────────────────┬───────────────┤ -│ 会员小程序 │ 教练端App │ 管理后台PC │ 硬件设备 │ -│ (uniapp+Vue3) │ (uniapp+Vue3) │ (Vue3+Vite) │ (人脸/NFC) │ -└────────┬─────────┴────────┬─────────┴────────┬─────────┴───────┬───────┘ - │ │ │ │ - └──────────────────┴────────┬─────────┴─────────────────┘ - │ - ┌────────▼────────┐ - │ API Gateway │ - │ (统一网关) │ - │ - 路由转发 │ - │ - 认证鉴权 │ - │ - 限流熔断 │ - │ - 日志追踪 │ - └────────┬────────┘ - │ - ┌───────────────────────────┼───────────────────────────┐ - │ │ │ - ▼ ▼ ▼ -┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ -│ 会员服务 │ │ 预约服务 │ │ 数据服务 │ -│ Member Service │ │ Booking Service │ │ Data Service │ -├─────────────────┤ ├─────────────────┤ ├─────────────────┤ -│ - 会员管理 │ │ - 课程管理 │ │ - 数据统计 │ -│ - 会员卡管理 │ │ - 预约管理 │ │ - 报表生成 │ -│ - 权益管理 │ │ - 签到管理 │ │ - 数据导出 │ -│ - 等级管理 │ │ - 库存管理 │ │ - 数据分析 │ -└────────┬────────┘ └────────┬────────┘ └────────┬────────┘ - │ │ │ - └──────────────────────────┼──────────────────────────┘ - │ - ┌───────────────────────────┼───────────────────────────┐ - │ │ │ - ▼ ▼ ▼ -┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ -│ 公共服务层 │ │ 基础设施层 │ │ 外部服务 │ -├─────────────────┤ ├─────────────────┤ ├─────────────────┤ -│ - 认证服务 │ │ - PostgreSQL │ │ - 微信开放平台 │ -│ - 消息服务 │ │ - R2DBC │ │ - 短信服务 │ -│ - 文件服务 │ │ - Caffeine │ │ - 支付服务 │ -│ - 缓存服务 │ │ - Redis(可选) │ │ - OSS存储 │ -└─────────────────┘ └─────────────────┘ └─────────────────┘ +```mermaid +graph TB + subgraph ClientLayer[客户端层] + A1[会员小程序
uniapp+Vue3] + A2[教练端App
uniapp+Vue3] + A3[管理后台PC
Vue3+Vite] + A4[硬件设备
人脸/NFC] + end + + subgraph Gateway[API Gateway
统一网关] + B1[路由转发] + B2[认证鉴权] + B3[限流熔断] + B4[日志追踪] + end + + subgraph BusinessLayer[业务层] + C1[会员服务
Member Service] + C2[预约服务
Booking Service] + C3[数据服务
Data Service] + end + + subgraph CommonLayer[公共服务层] + D1[认证服务] + D2[消息服务] + D3[文件服务] + D4[缓存服务] + end + + subgraph InfraLayer[基础设施层] + E1[PostgreSQL] + E2[R2DBC] + E3[Caffeine] + E4[Redis可选] + end + + subgraph ExternalLayer[外部服务] + F1[微信开放平台] + F2[短信服务] + F3[支付服务] + F4[OSS存储] + end + + A1 --> Gateway + A2 --> Gateway + A3 --> Gateway + A4 --> Gateway + + Gateway --> C1 + Gateway --> C2 + Gateway --> C3 + + C1 --> CommonLayer + C2 --> CommonLayer + C3 --> CommonLayer + + CommonLayer --> InfraLayer + CommonLayer --> ExternalLayer ``` ### 3.2 技术架构 -``` -┌─────────────────────────────────────────────────────────────────────────┐ -│ 技术架构分层 │ -├─────────────────────────────────────────────────────────────────────────┤ -│ │ -│ ┌───────────────────────────────────────────────────────────────────┐ │ -│ │ 表现层 (Presentation) │ │ -│ │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ │ -│ │ │ 会员端 uniapp │ │ 教练端 uniapp │ │ 管理后台 Vue3 │ │ │ -│ │ │ - Vue3 + TS │ │ - Vue3 + TS │ │ - Vue3 + TS │ │ │ -│ │ │ - Pinia │ │ - Pinia │ │ - Pinia │ │ │ -│ │ │ - uni-ui │ │ - uni-ui │ │ - Element Plus│ │ │ -│ │ └─────────────────┘ └─────────────────┘ └─────────────────┘ │ │ -│ └───────────────────────────────────────────────────────────────────┘ │ -│ │ │ -│ ▼ │ -│ ┌───────────────────────────────────────────────────────────────────┐ │ -│ │ 网关层 (Gateway) │ │ -│ │ ┌─────────────────────────────────────────────────────────────┐ │ │ -│ │ │ Spring Cloud Gateway │ │ │ -│ │ │ - 路由转发 - 认证鉴权 - 限流熔断 - 日志追踪 - 灰度发布 │ │ │ -│ │ └─────────────────────────────────────────────────────────────┘ │ │ -│ └───────────────────────────────────────────────────────────────────┘ │ -│ │ │ -│ ▼ │ -│ ┌───────────────────────────────────────────────────────────────────┐ │ -│ │ 业务层 (Business) │ │ -│ │ ┌─────────────────────────────────────────────────────────────┐ │ │ -│ │ │ Spring Boot 3 + WebFlux + JDK 21 │ │ │ -│ │ │ ┌───────────┐ ┌───────────┐ ┌───────────┐ ┌───────────┐ │ │ │ -│ │ │ │ Controller│ │ Service │ │ Repository│ │ Model │ │ │ │ -│ │ │ │ (API) │ │ (业务逻辑) │ │ (数据访问) │ │ (领域模型) │ │ │ │ -│ │ │ └───────────┘ └───────────┘ └───────────┘ └───────────┘ │ │ │ -│ │ └─────────────────────────────────────────────────────────────┘ │ │ -│ └───────────────────────────────────────────────────────────────────┘ │ -│ │ │ -│ ▼ │ -│ ┌───────────────────────────────────────────────────────────────────┐ │ -│ │ 数据层 (Data) │ │ -│ │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ │ -│ │ │ PostgreSQL │ │ Caffeine │ │ Redis(可选) │ │ │ -│ │ │ - R2DBC │ │ - 本地缓存 │ │ - 分布式缓存 │ │ │ -│ │ │ - Flyway │ │ - 热点数据 │ │ - 分布式锁 │ │ │ -│ │ └─────────────────┘ └─────────────────┘ └─────────────────┘ │ │ -│ └───────────────────────────────────────────────────────────────────┘ │ -│ │ -└─────────────────────────────────────────────────────────────────────────┘ +```mermaid +graph TB + subgraph Presentation[表现层 Presentation] + A1[会员端 uniapp
Vue3 + TS
Pinia
uni-ui] + A2[教练端 uniapp
Vue3 + TS
Pinia
uni-ui] + A3[管理后台 Vue3
Vue3 + TS
Pinia
Element Plus] + end + + subgraph Gateway[网关层 Gateway] + B[Spring Cloud Gateway
路由转发
认证鉴权
限流熔断
日志追踪
灰度发布] + end + + subgraph Business[业务层 Business] + C[Spring Boot 3 + WebFlux + JDK 21] + C1[Controller
API] + C2[Service
业务逻辑] + C3[Repository
数据访问] + C4[Model
领域模型] + end + + subgraph Data[数据层 Data] + D1[PostgreSQL
R2DBC
Flyway] + D2[Caffeine
本地缓存
热点数据] + D3[Redis可选
分布式缓存
分布式锁] + end + + A1 --> B + A2 --> B + A3 --> B + B --> C + C --> C1 + C1 --> C2 + C2 --> C3 + C3 --> C4 + C4 --> D1 + C4 --> D2 + C4 --> D3 ``` ### 3.3 部署架构 +```mermaid +graph TB + LB[负载均衡器
Nginx/ALB] + + subgraph GatewayInstances[API Gateway集群] + GW1[API Gateway
实例1] + GW2[API Gateway
实例2] + GW3[API Gateway
实例N] + end + + subgraph AppInstances[应用服务集群] + APP1[应用服务
实例1] + APP2[应用服务
实例2] + APP3[应用服务
实例N] + end + + subgraph DBLayer[数据库层] + PG1[PostgreSQL
主库] + PG2[PostgreSQL
从库1] + PG3[PostgreSQL
从库N] + end + + subgraph CacheLayer[缓存层] + REDIS1[Redis
主节点] + REDIS2[Redis
从节点1] + REDIS3[Redis
从节点N] + end + + LB --> GW1 + LB --> GW2 + LB --> GW3 + + GW1 --> APP1 + GW2 --> APP2 + GW3 --> APP3 + + APP1 --> PG1 + APP2 --> PG1 + APP3 --> PG1 + + PG1 -.->|主从复制| PG2 + PG1 -.->|主从复制| PG3 + + APP1 --> REDIS1 + APP2 --> REDIS1 + APP3 --> REDIS1 + + REDIS1 -.->|主从复制| REDIS2 + REDIS1 -.->|主从复制| REDIS3 ``` -┌─────────────────────────────────────────────────────────────────────────┐ -│ 部署架构 │ -├─────────────────────────────────────────────────────────────────────────┤ -│ │ -│ ┌─────────────────┐ │ -│ │ 负载均衡器 │ │ -│ │ (Nginx/ALB) │ │ -│ └────────┬────────┘ │ -│ │ │ -│ ┌───────────────────┼───────────────────┐ │ -│ │ │ │ │ -│ ▼ ▼ ▼ │ -│ ┌────────────────┐ ┌────────────────┐ ┌────────────────┐ │ -│ │ API Gateway │ │ API Gateway │ │ API Gateway │ │ -│ │ (实例1) │ │ (实例2) │ │ (实例N) │ │ -│ └───────┬────────┘ └───────┬────────┘ └───────┬────────┘ │ -│ │ │ │ │ -│ └───────────────────┼───────────────────┘ │ -│ │ │ -│ ┌──────────────────┼──────────────────┐ │ -│ │ │ │ │ -│ ▼ ▼ ▼ │ -│ ┌────────────────┐ ┌────────────────┐ ┌────────────────┐ │ -│ │ Application │ │ Application │ │ Application │ │ -│ │ Server (Pod1) │ │ Server (Pod2) │ │ Server (PodN) │ │ -│ └───────┬────────┘ └───────┬────────┘ └ + +│ └───────────────────┼───────────────────┘ │ +│ │ │ +│ ┌──────────────────┼──────────────────┐ │ +│ │ │ │ │ +│ ▼ ▼ ▼ │ +│ ┌────────────────┐ ┌────────────────┐ ┌────────────────┐ │ +│ │ Application │ │ Application │ │ Application │ │ +│ │ Server (Pod1) │ │ Server (Pod2) │ │ Server (PodN) │ │ +│ └───────┬────────┘ └───────┬────────┘ └ + ``` -───────┬────────┘ │ -│ │ │ │ │ -│ └───────────────────┼───────────────────┘ │ -│ │ │ -│ ┌───────────────────────────┼───────────────────────────┐ │ -│ │ │ │ │ -│ ▼ ▼ ▼ │ -│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ -│ │ PostgreSQL │ │ Redis │ │ OSS │ │ -│ │ (主从复制) │ │ (哨兵模式) │ │ (对象存储) │ │ -│ └──────────────┘ └──────────────┘ └──────────────┘ │ -│ │ + +───────┬────────┘ │ +│ │ │ │ │ +│ └───────────────────┼───────────────────┘ │ +│ │ │ +│ ┌───────────────────────────┼───────────────────────────┐ │ +│ │ │ │ │ +│ ▼ ▼ ▼ │ +│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ +│ │ PostgreSQL │ │ Redis │ │ OSS │ │ +│ │ (主从复制) │ │ (哨兵模式) │ │ (对象存储) │ │ +│ └──────────────┘ └──────────────┘ └──────────────┘ │ +│ │ └─────────────────────────────────────────────────────────────────────────┘ + ``` --- @@ -268,94 +325,96 @@ ### 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 模块划分 + +```mermaid +graph TB + subgraph Parent[gym-manage-server 父工程] + subgraph Common[gym-common 公共模块] + C1[gym-common-core
核心工具类、常量、枚举] + C2[gym-common-redis
Redis配置可选] + C3[gym-common-security
安全认证公共组件] + C4[gym-common-log
日志公共组件] + end + + subgraph API[gym-api API网关模块] + A1[controller
HTTP接口] + A2[dto
数据传输对象] + A3[vo
视图对象] + A4[config
API配置] + end + + subgraph Service[gym-service 业务服务模块] + S1[gym-service-member
会员服务] + S2[gym-service-booking
预约服务] + S3[gym-service-checkin
签到服务] + S4[gym-service-course
课程服务] + S5[gym-service-coach
教练服务] + S6[gym-service-finance
财务服务] + S7[gym-service-data
数据服务] + end + + subgraph Domain[gym-domain 领域模型模块] + D1[model
领域模型] + D2[event
领域事件] + D3[service
领域服务] + end + + subgraph Infra[gym-infrastructure 基础设施模块] + I1[repository
数据仓储] + I2[cache
缓存配置] + I3[external
外部服务集成] + I4[config
基础配置] + end + + subgraph Starter[gym-starter 启动模块] + ST[gym-admin
管理后台启动器] + end + end +```` ### 4.2 模块职责 -| 模块 | 职责 | 依赖 | -|------|------|------| -| 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 | +| 模块 | 职责 | 依赖 | +| ------------------- | ---------------------------------- | ------------------------------ | +| 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.3 模块交互 -``` -┌─────────────────────────────────────────────────────────────────────────┐ -│ 模块交互流程 │ -├─────────────────────────────────────────────────────────────────────────┤ -│ │ -│ HTTP Request │ -│ │ │ -│ ▼ │ -│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ -│ │ API │───▶│ Service │───▶│ Domain │───▶│ Repo │ │ -│ │ Layer │ │ Layer │ │ Layer │ │ Layer │ │ -│ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ -│ │ │ │ │ │ -│ │ │ │ │ │ -│ │ ▼ ▼ ▼ │ -│ │ ┌─────────────────────────────────────┐ │ -│ │ │ Infrastructure │ │ -│ │ │ ┌─────────┐ ┌─────────┐ ┌─────┐ │ │ -│ │ │ │ Cache │ │ MQ │ │ DB │ │ │ -│ │ │ └─────────┘ └─────────┘ └─────┘ │ │ -│ │ └─────────────────────────────────────┘ │ -│ │ │ -│ ▼ │ -│ HTTP Response │ -│ │ -└─────────────────────────────────────────────────────────────────────────┘ +```mermaid +sequenceDiagram + participant Client as 客户端 + participant API as API Layer + participant Service as Service Layer + participant Domain as Domain Layer + participant Repo as Repo Layer + participant Infra as Infrastructure + + Client->>API: HTTP Request + API->>Service: 调用业务逻辑 + Service->>Domain: 处理领域逻辑 + Domain->>Repo: 访问数据 + Repo->>Infra: 访问基础设施 + Infra-->>Repo: 返回结果 + Repo-->>Domain: 返回数据 + Domain-->>Service: 返回领域对象 + Service-->>API: 返回业务结果 + API-->>Client: HTTP Response ``` --- @@ -367,19 +426,23 @@ #### 5.1.1 RESTful API 规范 ``` + 基础URL: https://api.gym-manage.com/v1 资源命名规范: + - 使用名词复数形式: /members, /bookings, /courses - 使用小写字母和连字符: /member-cards, /booking-slots - 避免动词: /members (正确) vs /getMembers (错误) HTTP方法语义: + - GET: 查询资源 - POST: 创建资源 - PUT: 全量更新资源 - PATCH: 部分更新资源 - DELETE: 删除资源 + ``` #### 5.1.2 请求响应格式 @@ -421,71 +484,75 @@ HTTP方法语义: #### 5.1.3 状态码定义 -| 状态码 | 含义 | 说明 | -|--------|------|------| -| 0 | 成功 | 请求处理成功 | -| 40001 | 参数错误 | 请求参数校验失败 | -| 40002 | 资源不存在 | 请求的资源不存在 | -| 40003 | 资源已存在 | 创建的资源已存在 | -| 40101 | 未登录 | 用户未登录或Token过期 | -| 40102 | 无权限 | 用户无访问权限 | -| 40301 | 业务异常 | 业务逻辑校验失败 | -| 50001 | 系统异常 | 系统内部错误 | +| 状态码 | 含义 | 说明 | +| ------ | ---------- | --------------------- | +| 0 | 成功 | 请求处理成功 | +| 40001 | 参数错误 | 请求参数校验失败 | +| 40002 | 资源不存在 | 请求的资源不存在 | +| 40003 | 资源已存在 | 创建的资源已存在 | +| 40101 | 未登录 | 用户未登录或Token过期 | +| 40102 | 无权限 | 用户无访问权限 | +| 40301 | 业务异常 | 业务逻辑校验失败 | +| 50001 | 系统异常 | 系统内部错误 | ### 5.2 接口分组 -``` -┌─────────────────────────────────────────────────────────────────────────┐ -│ API 接口分组 │ -├─────────────────────────────────────────────────────────────────────────┤ -│ │ -│ /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.2 接口分组 + +```mermaid +graph LR + subgraph Auth[认证接口 /v1/auth] + A1[POST /login
登录] + A2[POST /logout
登出] + A3[POST /refresh
刷新Token] + A4[POST /wechat-login
微信登录] + end + + subgraph Members[会员接口 /v1/members] + M1[GET /
会员列表] + M2[GET /{id}
会员详情] + M3[POST /
创建会员] + M4[PUT /{id}
更新会员] + M5[GET /{id}/cards
会员卡列表] + M6[GET /{id}/benefits
权益列表] + M7[GET /{id}/bookings
预约记录] + end + + subgraph Courses[课程接口 /v1/courses] + C1[GET /
课程列表] + C2[GET /{id}
课程详情] + C3[POST /
创建课程] + C4[PUT /{id}
更新课程] + C5[GET /{id}/slots
可预约时段] + end + + subgraph Bookings[预约接口 /v1/bookings] + B1[GET /
预约列表] + B2[GET /{id}
预约详情] + B3[POST /
创建预约] + B4[POST /{id}/cancel
取消预约] + B5[GET /my
我的预约] + end + + subgraph Checkins[签到接口 /v1/checkins] + CH1[GET /
签到列表] + CH2[POST /scan
扫码签到] + CH3[POST /manual
手动签到] + CH4[GET /my
我的签到] + end + + subgraph Coaches[教练接口 /v1/coaches] + CO1[GET /
教练列表] + CO2[GET /{id}
教练详情] + CO3[GET /{id}/schedule
教练排班] + CO4[GET /{id}/slots
可预约时段] + end + + subgraph Dashboard[数据看板 /v1/dashboard] + D1[GET /overview
今日概览] + D2[GET /trends
趋势数据] + D3[GET /rankings
排行数据] + end ``` ### 5.3 接口版本管理 @@ -670,12 +737,12 @@ HTTP方法语义: ### 7.1 性能目标 -| 指标 | 目标值 | 说明 | -|------|--------|------| +| 指标 | 目标值 | 说明 | +| -------- | ----------- | -------------------------- | | 响应时间 | P99 < 200ms | 99%的请求响应时间小于200ms | -| 吞吐量 | QPS ≥ 1000 | 系统每秒处理请求数 | -| 并发用户 | ≥ 5000 | 同时在线用户数 | -| 可用性 | SLA ≥ 99.9% | 年度可用性 | +| 吞吐量 | QPS ≥ 1000 | 系统每秒处理请求数 | +| 并发用户 | ≥ 5000 | 同时在线用户数 | +| 可用性 | SLA ≥ 99.9% | 年度可用性 | ### 7.2 性能优化策略 @@ -892,34 +959,34 @@ HTTP方法语义: ### 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 | 容器化部署 | +| 分类 | 技术 | 版本 | 说明 | +| ---------- | -------------- | ---- | ---------------- | +| 后端框架 | 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 | 假设冲突较多,通过锁机制控制并发 | +| 术语 | 英文 | 定义 | +| ---------- | -------------------- | -------------------------------- | +| 高可用 | 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 33bb08f..aa6add0 100644 --- a/docs/design/LLD-会员模块详细设计.md +++ b/docs/design/LLD-会员模块详细设计.md @@ -29,33 +29,28 @@ ### 1.2 模块边界 -``` -┌─────────────────────────────────────────────────────────────────────────┐ -│ 会员模块边界 │ -├─────────────────────────────────────────────────────────────────────────┤ -│ │ -│ ┌─────────────────────────────────────────────────────────────────┐ │ -│ │ 会员模块内部 │ │ -│ │ │ │ -│ │ ┌───────────┐ ┌───────────┐ ┌───────────┐ ┌──────────┐ │ │ -│ │ │ 会员管理 │ │ 会员卡管理 │ │ 权益管理 │ │ 等级管理 │ │ │ -│ │ └───────────┘ └───────────┘ └───────────┘ └──────────┘ │ │ -│ │ │ │ -│ └─────────────────────────────────────────────────────────────────┘ │ -│ │ -│ 外部依赖: │ -│ ├── 租户模块: 获取租户信息 │ -│ ├── 门店模块: 获取门店信息 │ -│ ├── 认证模块: 用户登录认证 │ -│ └── 消息模块: 发送短信验证码 │ -│ │ -│ 被依赖: │ -│ ├── 预约模块: 查询会员权益、扣减权益 │ -│ ├── 签到模块: 查询会员信息、扣减权益 │ -│ ├── 财务模块: 查询会员消费记录 │ -│ └── 数据模块: 会员数据分析 │ -│ │ -└─────────────────────────────────────────────────────────────────────────┘ +```mermaid +graph TB + subgraph Internal[会员模块内部] + M1[会员管理] + M2[会员卡管理] + M3[权益管理] + M4[等级管理] + end + + subgraph ExternalDeps[外部依赖] + D1[租户模块
获取租户信息] + D2[门店模块
获取门店信息] + D3[认证模块
用户登录认证] + D4[消息模块
发送短信验证码] + end + + subgraph Deps[被依赖] + U1[预约模块
查询会员权益、扣减权益] + U2[签到模块
查询会员信息、扣减权益] + U3[财务模块
查询会员消费记录] + U4[数据模块
会员数据分析] + end ``` --- @@ -64,53 +59,91 @@ ### 2.1 实体关系图 -``` -┌─────────────────────────────────────────────────────────────────────────┐ -│ 会员模块ER图 │ -├─────────────────────────────────────────────────────────────────────────┤ -│ │ -│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ -│ │ tenant │ │ store │ │ member │ │ -│ │─────────────│ │─────────────│ │─────────────│ │ -│ │ id │◀──┐ │ id │◀──┐ │ id │ │ -│ │ name │ │ │ tenant_id │───┘ │ tenant_id │───┐ │ -│ │ code │ │ │ name │ │ store_id │───┼──┐ │ -│ │ status │ │ │ address │ │ member_no │ │ │ │ -│ └─────────────┘ │ │ status │ │ name │ │ │ │ -│ │ └─────────────┘ │ phone │ │ │ │ -│ │ │ gender │ │ │ │ -│ │ │ level │ │ │ │ -│ │ │ exp │ │ │ │ -│ │ │ status │ │ │ │ -│ │ └─────────────┘ │ │ │ -│ │ │ │ │ │ -│ │ │ │ │ │ -│ │ ▼ │ │ │ -│ │ ┌─────────────┐ ┌─────────────┐ │ │ │ -│ │ │ member_card │◀──────│ member_bene │ │ │ │ -│ │ │─────────────│ │ fit │ │ │ │ -│ │ │ id │ │─────────────│ │ │ │ -│ │ │ member_id │──────▶│ id │ │ │ │ -│ │ │ card_type_id│ │ member_id │───┘ │ │ -│ │ │ card_no │ │ card_id │ │ │ -│ │ │ status │ │ type │ │ │ -│ │ │ start_date │ │ value │ │ │ -│ │ │ end_date │ │ used_value │ │ │ -│ │ └─────────────┘ │ expire_date │ │ │ -│ │ └─────────────┘ │ │ -│ │ │ │ -│ │ ┌─────────────┐ ┌─────────────┐ │ │ -│ │ │ card_type │ │ level_rule │ │ │ -│ │ │─────────────│ │─────────────│ │ │ -│ └───│ tenant_id │ │ tenant_id │◀─────┘ │ -│ │ name │ │ level │ │ -│ │ type │ │ name │ │ -│ │ price │ │ min_exp │ │ -│ │ duration │ │ max_exp │ │ -│ └─────────────┘ │ discount │ │ -│ └─────────────┘ │ -│ │ -└─────────────────────────────────────────────────────────────────────────┘ +```mermaid +erDiagram + tenant ||--o{ store : has + tenant ||--o{ member : has + store ||--o{ member : belongs + + member ||--o{ member_card : has + member ||--o{ member_benefit : has + + member_card }o--|| card_type : type + member_benefit }o--|| card_type : card + + card_type }o--|| level_rule : has + + tenant { + bigint id PK + varchar name + varchar code + smallint status + } + + store { + bigint id PK + bigint tenant_id FK + varchar name + varchar address + smallint status + } + + member { + bigint id PK + bigint tenant_id FK + bigint store_id FK + varchar member_no + varchar name + varchar phone + smallint gender + smallint level + int exp + smallint status + } + + member_card { + bigint id PK + bigint member_id FK + bigint card_type_id FK + varchar card_no + smallint status + date start_date + date end_date + } + + member_benefit { + bigint id PK + bigint member_id FK + bigint card_id FK + smallint type + decimal value + decimal used_value + date expire_date + } + + card_type { + bigint id PK + bigint tenant_id FK + varchar name + varchar code + smallint type + decimal price + int duration_days + int total_times + decimal stored_value + smallint level + decimal discount + } + + level_rule { + bigint id PK + bigint tenant_id FK + smallint level + varchar name + int min_exp + int max_exp + decimal discount + } ``` ### 2.2 数据表设计 diff --git a/docs/design/LLD-签到模块详细设计.md b/docs/design/LLD-签到模块详细设计.md index 2c360f1..9854dd6 100644 --- a/docs/design/LLD-签到模块详细设计.md +++ b/docs/design/LLD-签到模块详细设计.md @@ -29,33 +29,28 @@ ### 1.2 模块边界 -``` -┌─────────────────────────────────────────────────────────────────────────┐ -│ 签到模块边界 │ -├─────────────────────────────────────────────────────────────────────────┤ -│ │ -│ ┌─────────────────────────────────────────────────────────────────┐ │ -│ │ 签到模块内部 │ │ -│ │ │ │ -│ │ ┌───────────┐ ┌───────────┐ ┌───────────┐ ┌──────────┐ │ │ -│ │ │ 签到网关 │ │ 签到验证 │ │ 签到记录 │ │ 签到统计 │ │ │ -│ │ └───────────┘ └───────────┘ └───────────┘ └──────────┘ │ │ -│ │ │ │ -│ └─────────────────────────────────────────────────────────────────┘ │ -│ │ -│ 外部依赖: │ -│ ├── 会员模块: 查询会员信息、验证会员状态 │ -│ ├── 权益模块: 验证权益有效性、扣减权益 │ -│ ├── 预约模块: 查询预约信息、验证签到资格 │ -│ ├── 设备模块: 人脸识别设备、NFC读卡器 │ -│ └── 消息模块: 发送签到通知 │ -│ │ -│ 被依赖: │ -│ ├── 财务模块: 签到消费记录 │ -│ ├── 数据模块: 签到数据分析、会员活跃度统计 │ -│ └── 考勤模块: 教练考勤统计 │ -│ │ -└─────────────────────────────────────────────────────────────────────────┘ +```mermaid +graph TB + subgraph Internal[签到模块内部] + C1[签到网关] + C2[签到验证] + C3[签到记录] + C4[签到统计] + end + + subgraph ExternalDeps[外部依赖] + D1[会员模块
查询会员信息、验证会员状态] + D2[权益模块
验证权益有效性、扣减权益] + D3[预约模块
查询预约信息、验证签到资格] + D4[设备模块
人脸识别设备、NFC读卡器] + D5[消息模块
发送签到通知] + end + + subgraph Deps[被依赖] + U1[财务模块
签到消费记录] + U2[数据模块
签到数据分析、会员活跃度统计] + U3[考勤模块
教练考勤统计] + end ``` ### 1.3 签到类型 @@ -73,51 +68,57 @@ ### 2.1 实体关系图 -``` -┌─────────────────────────────────────────────────────────────────────────┐ -│ 签到模块ER图 │ -├─────────────────────────────────────────────────────────────────────────┤ -│ │ -│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ -│ │ member │ │booking_record│ │ device │ │ -│ │─────────────│ │─────────────│ │─────────────│ │ -│ │ id │ │ id │ │ id │ │ -│ │ name │ │ member_id │ │ name │ │ -│ │ phone │ │ slot_id │ │ type │ │ -│ │ status │ │ status │ │ location │ │ -│ └──────┬──────┘ │ checkin_ │ │ status │ │ -│ │ │ status │ └──────┬──────┘ │ -│ │ └──────┬──────┘ │ │ -│ │ │ │ │ -│ │ ┌────────────────┼─────────────────────┘ │ -│ │ │ │ │ -│ │ ▼ ▼ │ -│ │ ┌─────────────────────────────┐ │ -│ │ │ checkin_record │ │ -│ │ │─────────────────────────────│ │ -│ │ │ id │ │ -│ │ │ tenant_id │ │ -│ │ │ member_id ◀────────────┘ │ -│ │ │ booking_id │ │ -│ │ │ device_id │ │ -│ │ │ type │ │ -│ │ │ method │ │ -│ │ │ status │ │ -│ │ │ checkin_at │ │ -│ │ └─────────────────────────────┘ │ -│ │ │ -│ │ ┌─────────────────────────────┐ │ -│ │ │ member_face │ │ -│ │ │─────────────────────────────│ │ -│ │ │ id │ │ -│ │ │ member_id ◀────────────┘ │ -│ │ │ face_feature │ │ -│ │ │ status │ │ -│ │ └─────────────────────────────┘ │ -│ │ │ -│ └────────────────────────────────────────────────────────────┘ -│ │ -└─────────────────────────────────────────────────────────────────────────┘ +```mermaid +erDiagram + member ||--o{ checkin_record : makes + booking_record ||--o{ checkin_record : for + device ||--o{ checkin_record : used + + member ||--o{ member_face : has + + member { + bigint id PK + varchar name + varchar phone + smallint status + } + + booking_record { + bigint id PK + bigint member_id FK + bigint slot_id FK + smallint status + smallint checkin_status + } + + device { + bigint id PK + varchar name + smallint type + varchar location + smallint status + } + + checkin_record { + bigint id PK + bigint tenant_id FK + bigint store_id FK + bigint member_id FK + bigint booking_id FK + bigint device_id FK + smallint type + smallint method + smallint status + timestamp checkin_at + date checkin_date + } + + member_face { + bigint id PK + bigint member_id FK + bytea face_feature + smallint status + } ``` ### 2.2 数据表设计 diff --git a/docs/design/LLD-预约模块详细设计.md b/docs/design/LLD-预约模块详细设计.md index ce89422..d33ae65 100644 --- a/docs/design/LLD-预约模块详细设计.md +++ b/docs/design/LLD-预约模块详细设计.md @@ -29,32 +29,27 @@ ### 1.2 模块边界 -``` -┌─────────────────────────────────────────────────────────────────────────┐ -│ 预约模块边界 │ -├─────────────────────────────────────────────────────────────────────────┤ -│ │ -│ ┌─────────────────────────────────────────────────────────────────┐ │ -│ │ 预约模块内部 │ │ -│ │ │ │ -│ │ ┌───────────┐ ┌───────────┐ ┌───────────┐ ┌──────────┐ │ │ -│ │ │ 课程管理 │ │ 时段管理 │ │ 预约管理 │ │ 库存管理 │ │ │ -│ │ └───────────┘ └───────────┘ └───────────┘ └──────────┘ │ │ -│ │ │ │ -│ └─────────────────────────────────────────────────────────────────┘ │ -│ │ -│ 外部依赖: │ -│ ├── 会员模块: 查询会员权益、扣减权益 │ -│ ├── 教练模块: 查询教练信息、排班 │ -│ ├── 场地模块: 查询场地信息、可用性 │ -│ └── 消息模块: 发送预约通知 │ -│ │ -│ 被依赖: │ -│ ├── 签到模块: 查询预约信息、验证签到资格 │ -│ ├── 财务模块: 查询预约消费记录 │ -│ └── 数据模块: 预约数据分析 │ -│ │ -└─────────────────────────────────────────────────────────────────────────┘ +```mermaid +graph TB + subgraph Internal[预约模块内部] + B1[课程管理] + B2[时段管理] + B3[预约管理] + B4[库存管理] + end + + subgraph ExternalDeps[外部依赖] + D1[会员模块
查询会员权益、扣减权益] + D2[教练模块
查询教练信息、排班] + D3[场地模块
查询场地信息、可用性] + D4[消息模块
发送预约通知] + end + + subgraph Deps[被依赖] + U1[签到模块
查询预约信息、验证签到资格] + U2[财务模块
查询预约消费记录] + U3[数据模块
预约数据分析] + end ``` --- @@ -63,60 +58,69 @@ ### 2.1 实体关系图 -``` -┌─────────────────────────────────────────────────────────────────────────┐ -│ 预约模块ER图 │ -├─────────────────────────────────────────────────────────────────────────┤ -│ │ -│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ -│ │ coach │ │ course │ │ venue │ │ -│ │─────────────│ │─────────────│ │─────────────│ │ -│ │ id │ │ id │ │ id │ │ -│ │ name │ │ tenant_id │ │ tenant_id │ │ -│ │ specialty │ │ name │ │ name │ │ -│ │ status │ │ type │ │ type │ │ -│ └──────┬──────┘ │ category │ │ capacity │ │ -│ │ │ duration │ │ status │ │ -│ │ │ capacity │ └──────┬──────┘ │ -│ │ │ status │ │ │ -│ │ └──────┬──────┘ │ │ -│ │ │ │ │ -│ │ ┌────────────────┼─────────────────────┘ │ -│ │ │ │ │ -│ │ ▼ ▼ │ -│ │ ┌─────────────────────────────┐ │ -│ │ │ booking_slot │ │ -│ │ │─────────────────────────────│ │ -│ │ │ id │ │ -│ │ │ tenant_id │ │ -│ │ │ resource_type (course/venue)│ │ -│ │ │ resource_id │ │ -│ │ │ coach_id │◀──────────┐ │ -│ │ │ venue_id │ │ │ -│ │ │ start_time │ │ │ -│ │ │ end_time │ │ │ -│ │ │ capacity │ │ │ -│ │ │ booked_count │ │ │ -│ │ │ status │ │ │ -│ │ └─────────────┬───────────────┘ │ │ -│ │ │ │ │ -│ │ ▼ │ │ -│ │ ┌─────────────────────────────┐ │ │ -│ │ │ booking_record │ │ │ -│ │ │─────────────────────────────│ │ │ -│ │ │ id │ │ │ -│ │ │ tenant_id │ │ │ -│ │ │ member_id │ │ │ -│ │ │ slot_id │───────────┘ │ -│ │ │ coach_id │ │ -│ │ │ status │ │ -│ │ │ price │ │ -│ │ │ checkin_status │ │ -│ │ └─────────────────────────────┘ │ -│ │ │ -│ └────────────────────────────────────────────────────────────┘ -│ │ -└─────────────────────────────────────────────────────────────────────────┘ +### 2.1 实体关系图 + +```mermaid +erDiagram + coach ||--o{ booking_slot : coaches + course ||--o{ booking_slot : courses + venue ||--o{ booking_slot : venues + + booking_slot ||--o{ booking_record : slots + + coach { + bigint id PK + varchar name + varchar specialty + smallint status + } + + course { + bigint id PK + bigint tenant_id FK + varchar name + smallint type + varchar category + int duration + int capacity + smallint status + } + + venue { + bigint id PK + bigint tenant_id FK + varchar name + smallint type + int capacity + smallint status + } + + booking_slot { + bigint id PK + bigint tenant_id FK + smallint resource_type + bigint resource_id FK + bigint coach_id FK + bigint venue_id FK + timestamp start_time + timestamp end_time + int capacity + int booked_count + smallint status + } + + booking_record { + bigint id PK + bigint tenant_id FK + bigint member_id FK + bigint slot_id FK + bigint coach_id FK + smallint status + decimal price + smallint price_type + decimal price_value + smallint checkin_status + } ``` ### 2.2 数据表设计