修复所有设计文档中ASCII图表右侧边框对齐问题
- 修复HLD-系统概要设计.md中所有ASCII图表的右侧边框对齐 - 修复LLD-签到模块详细设计.md中ASCII图表的右侧边框对齐 - 修复LLD-会员模块详细设计.md中ASCII图表的右侧边框对齐 - 修复LLD-预约模块详细设计.md中ASCII图表的右侧边框对齐 - 确保所有ASCII图表的右侧边框纵向靠右对齐
This commit is contained in:
+215
-215
@@ -84,59 +84,59 @@
|
||||
│ 业务范围 │
|
||||
├─────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 会员管理 │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • 会员注册 • 会员卡管理 • 权益管理 • 等级管理 │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 会员管理 │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • 会员注册 • 会员卡管理 • 权益管理 • 等级管理 │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 预约管理 │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • 团课预约 • 私教预约 • 场地预约 • 线上课程 │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 预约管理 │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • 团课预约 • 私教预约 • 场地预约 • 线上课程 │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 签到管理 │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • 扫码签到 • 刷脸签到 • NFC签到 • 教练代签 │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 签到管理 │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • 扫码签到 • 刷脸签到 • NFC签到 • 教练代签 │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 课程管理 │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • 课程类型 • 课程排期 • 场地管理 • 价格配置 │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 课程管理 │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • 课程类型 • 课程排期 • 场地管理 • 价格配置 │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 教练管理 │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • 教练信息 • 排班管理 • 课时统计 • 评价管理 │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 教练管理 │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • 教练信息 • 排班管理 • 课时统计 • 评价管理 │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 财务管理 │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • 营收统计 • 账单管理 • 退款管理 • 对账管理 │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 财务管理 │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • 营收统计 • 账单管理 • 退款管理 • 对账管理 │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 计划中心 │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • 训练计划 • 课程排期 • 会员目标 • 教练排班 │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 计划中心 │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • 训练计划 • 课程排期 • 会员目标 • 教练排班 │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 数据分析 │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • 会员分析 • 课程分析 • 财务分析 • 运营分析 │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 数据分析 │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • 会员分析 • 课程分析 • 财务分析 • 运营分析 │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 系统管理 │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • 租户管理 • 门店管理 • 权限管理 • 系统配置 │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 系统管理 │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • 租户管理 • 门店管理 • 权限管理 • 系统配置 │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
@@ -154,51 +154,51 @@
|
||||
│ 总体架构 │
|
||||
├─────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 客户端层 │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • 会员小程序 (uniapp+Vue3) │ │
|
||||
│ │ • 教练端App (uniapp+Vue3) │ │
|
||||
│ │ • 管理后台PC (Vue3+Vite) │ │
|
||||
│ │ • 硬件设备 (人脸/NFC) │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 客户端层 │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • 会员小程序 (uniapp+Vue3) │ │
|
||||
│ │ • 教练端App (uniapp+Vue3) │ │
|
||||
│ │ • 管理后台PC (Vue3+Vite) │ │
|
||||
│ │ • 硬件设备 (人脸/NFC) │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ API Gateway 统一网关 │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • 路由转发 • 认证鉴权 • 限流熔断 • 日志追踪 │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ API Gateway 统一网关 │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • 路由转发 • 认证鉴权 • 限流熔断 • 日志追踪 │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 业务层 │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • 会员服务 (Member Service) │ │
|
||||
│ │ • 预约服务 (Booking Service) │ │
|
||||
│ │ • 数据服务 (Data Service) │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 业务层 │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • 会员服务 (Member Service) │ │
|
||||
│ │ • 预约服务 (Booking Service) │ │
|
||||
│ │ • 数据服务 (Data Service) │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 公共服务层 │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • 认证服务 • 消息服务 • 文件服务 • 缓存服务 │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 公共服务层 │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • 认证服务 • 消息服务 • 文件服务 • 缓存服务 │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 基础设施层 │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • PostgreSQL • R2DBC • Caffeine • Redis(可选) │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 基础设施层 │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • PostgreSQL • R2DBC • Caffeine • Redis(可选) │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 外部服务层 │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • 微信开放平台 • 短信服务 • 支付服务 • OSS存储 │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 外部服务层 │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • 微信开放平台 • 短信服务 • 支付服务 • OSS存储 │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
@@ -210,38 +210,38 @@
|
||||
│ 技术架构 │
|
||||
├─────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 表现层 Presentation │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • 会员端 uniapp (Vue3 + TS + Pinia + uni-ui) │ │
|
||||
│ │ • 教练端 uniapp (Vue3 + TS + Pinia + uni-ui) │ │
|
||||
│ │ • 管理后台 Vue3 (Vue3 + TS + Pinia + Element Plus) │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 表现层 Presentation │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • 会员端 uniapp (Vue3 + TS + Pinia + uni-ui) │ │
|
||||
│ │ • 教练端 uniapp (Vue3 + TS + Pinia + uni-ui) │ │
|
||||
│ │ • 管理后台 Vue3 (Vue3 + TS + Pinia + Element Plus) │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 网关层 Gateway │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ Spring Cloud Gateway (路由转发/认证鉴权/限流熔断/日志追踪/灰度发布) │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 网关层 Gateway │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ Spring Cloud Gateway (路由转发/认证鉴权/限流熔断/日志追踪/灰度发布) │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 业务层 Business │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ Spring Boot 3 + WebFlux + JDK 21 │ │
|
||||
│ │ • Controller (API) • Service (业务逻辑) │ │
|
||||
│ │ • Repository (数据访问) • Model (领域模型) │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 业务层 Business │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ Spring Boot 3 + WebFlux + JDK 21 │ │
|
||||
│ │ • Controller (API) • Service (业务逻辑) │ │
|
||||
│ │ • Repository (数据访问) • Model (领域模型) │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 数据层 Data │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • PostgreSQL (R2DBC + Flyway) │ │
|
||||
│ │ • Caffeine (本地缓存 + 热点数据) │ │
|
||||
│ │ • Redis可选 (分布式缓存 + 分布式锁) │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 数据层 Data │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • PostgreSQL (R2DBC + Flyway) │ │
|
||||
│ │ • Caffeine (本地缓存 + 热点数据) │ │
|
||||
│ │ • Redis可选 (分布式缓存 + 分布式锁) │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
@@ -253,33 +253,33 @@
|
||||
│ 部署架构 │
|
||||
├─────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 负载均衡器 (Nginx/ALB) │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 负载均衡器 (Nginx/ALB) │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ API Gateway 集群 │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • API Gateway 实例1 • API Gateway 实例2 • API Gateway 实例N │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ API Gateway 集群 │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • API Gateway 实例1 • API Gateway 实例2 • API Gateway 实例N │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 应用服务集群 │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • 应用服务 实例1 • 应用服务 实例2 • 应用服务 实例N │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 应用服务集群 │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • 应用服务 实例1 • 应用服务 实例2 • 应用服务 实例N │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ │ │
|
||||
│ ┌───────────────┴───────────────┐ │
|
||||
│ ▼ ▼ │
|
||||
│ ┌─────────────────────────┐ ┌─────────────────────────┐ │
|
||||
│ │ PostgreSQL 数据库层 │ │ Redis 缓存层 │ │
|
||||
│ ├─────────────────────────┤ ├─────────────────────────┤ │
|
||||
│ │ • 主库 │ │ • 主节点 │ │
|
||||
│ │ • 从库1 (主从复制) │ │ • 从节点1 (主从复制) │ │
|
||||
│ │ • 从库N (主从复制) │ │ • 从节点N (主从复制) │ │
|
||||
│ └─────────────────────────┘ └─────────────────────────┘ │
|
||||
│ ┌───────────────┴───────────────┐ │
|
||||
│ ▼ ▼ │
|
||||
│ ┌─────────────────────────┐ ┌─────────────────────────┐ │
|
||||
│ │ PostgreSQL 数据库层 │ │ Redis 缓存层 │ │
|
||||
│ ├─────────────────────────┤ ├─────────────────────────┤ │
|
||||
│ │ • 主库 │ │ • 主节点 │ │
|
||||
│ │ • 从库1 (主从复制) │ │ • 从节点1 (主从复制) │ │
|
||||
│ │ • 从库N (主从复制) │ │ • 从节点N (主从复制) │ │
|
||||
│ └─────────────────────────┘ └─────────────────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
@@ -295,52 +295,52 @@
|
||||
│ gym-manage-server 父工程 │
|
||||
├─────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ gym-common 公共模块 │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • gym-common-core (核心工具类、常量、枚举) │ │
|
||||
│ │ • gym-common-redis (Redis配置可选) │ │
|
||||
│ │ • gym-common-security (安全认证公共组件) │ │
|
||||
│ │ • gym-common-log (日志公共组件) │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 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-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-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-domain 领域模型模块 │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • model (领域模型) • event (领域事件) • service (领域服务) │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ gym-infrastructure 基础设施模块 │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • repository (数据仓储) • cache (缓存配置) │ │
|
||||
│ │ • external (外部服务集成) • config (基础配置) │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ gym-infrastructure 基础设施模块 │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • repository (数据仓储) • cache (缓存配置) │ │
|
||||
│ │ • external (外部服务集成) • config (基础配置) │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ gym-starter 启动模块 │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • gym-admin (管理后台启动器) │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ gym-starter 启动模块 │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • gym-admin (管理后台启动器) │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
@@ -499,58 +499,58 @@ HTTP方法语义:
|
||||
│ 接口分组 │
|
||||
├─────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 认证接口 /v1/auth │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • POST /login (登录) • POST /logout (登出) │ │
|
||||
│ │ • POST /refresh (刷新Token) • POST /wechat-login (微信登录) │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 认证接口 /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/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/courses │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • GET / (课程列表) • GET /{id} (课程详情) │ │
|
||||
│ │ • POST / (创建课程) • PUT /{id} (更新课程) │ │
|
||||
│ │ • GET /{id}/slots (可预约时段) │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 预约接口 /v1/bookings │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • GET / (预约列表) • GET /{id} (预约详情) │ │
|
||||
│ │ • POST / (创建预约) • POST /{id}/cancel (取消预约) │ │
|
||||
│ │ • GET /my (我的预约) │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 预约接口 /v1/bookings │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • GET / (预约列表) • GET /{id} (预约详情) │ │
|
||||
│ │ • POST / (创建预约) • POST /{id}/cancel (取消预约) │ │
|
||||
│ │ • GET /my (我的预约) │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 签到接口 /v1/checkins │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • GET / (签到列表) • POST /scan (扫码签到) │ │
|
||||
│ │ • POST /manual (手动签到) • GET /my (我的签到) │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 签到接口 /v1/checkins │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • GET / (签到列表) • POST /scan (扫码签到) │ │
|
||||
│ │ • POST /manual (手动签到) • GET /my (我的签到) │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 教练接口 /v1/coaches │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • GET / (教练列表) • GET /{id} (教练详情) │ │
|
||||
│ │ • GET /{id}/schedule (教练排班) • GET /{id}/slots (可预约时段)│ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 教练接口 /v1/coaches │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • GET / (教练列表) • GET /{id} (教练详情) │ │
|
||||
│ │ • GET /{id}/schedule (教练排班) • GET /{id}/slots (可预约时段)│ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 数据看板 /v1/dashboard │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • GET /overview (今日概览) • GET /trends (趋势数据) │ │
|
||||
│ │ • GET /rankings (排行数据) │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 数据看板 /v1/dashboard │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • GET /overview (今日概览) • GET /trends (趋势数据) │ │
|
||||
│ │ • GET /rankings (排行数据) │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
+278
-278
@@ -10,9 +10,9 @@
|
||||
|
||||
## 文档修订历史
|
||||
|
||||
| 版本 | 日期 | 作者 | 修订内容 |
|
||||
|------|------|------|---------|
|
||||
| v1.0 | 2026-02-28 | 张翔 | 初稿 |
|
||||
| 版本 | 日期 | 作者 | 修订内容 |
|
||||
| ---- | ---------- | ---- | -------- |
|
||||
| v1.0 | 2026-02-28 | 张翔 | 初稿 |
|
||||
|
||||
---
|
||||
|
||||
@@ -44,29 +44,29 @@
|
||||
│ 会员模块边界 │
|
||||
├─────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 会员模块内部 │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • 会员管理 • 会员卡管理 • 权益管理 • 等级管理 │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 会员模块内部 │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • 会员管理 • 会员卡管理 • 权益管理 • 等级管理 │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 外部依赖 │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • 租户模块 (获取租户信息) │ │
|
||||
│ │ • 门店模块 (获取门店信息) │ │
|
||||
│ │ • 认证模块 (用户登录认证) │ │
|
||||
│ │ • 消息模块 (发送短信验证码) │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 外部依赖 │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • 租户模块 (获取租户信息) │ │
|
||||
│ │ • 门店模块 (获取门店信息) │ │
|
||||
│ │ • 认证模块 (用户登录认证) │ │
|
||||
│ │ • 消息模块 (发送短信验证码) │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 被依赖 │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • 预约模块 (查询会员权益、扣减权益) │ │
|
||||
│ │ • 签到模块 (查询会员信息、扣减权益) │ │
|
||||
│ │ • 财务模块 (查询会员消费记录) │ │
|
||||
│ │ • 数据模块 (会员数据分析) │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 被依赖 │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • 预约模块 (查询会员权益、扣减权益) │ │
|
||||
│ │ • 签到模块 (查询会员信息、扣减权益) │ │
|
||||
│ │ • 财务模块 (查询会员消费记录) │ │
|
||||
│ │ • 数据模块 (会员数据分析) │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
@@ -82,43 +82,43 @@
|
||||
│ 实体关系图 │
|
||||
├─────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌──────────────┐ │
|
||||
│ │ tenant │ │
|
||||
│ │ (租户表) │ │
|
||||
│ └──────┬───────┘ │
|
||||
│ │ 1:N │
|
||||
│ ┌────┴────┐ │
|
||||
│ ▼ ▼ │
|
||||
│ ┌──────┐ ┌──────┐ │
|
||||
│ │store │ │member│ │
|
||||
│ │(门店)│ │(会员)│ │
|
||||
│ └──┬───┘ └──┬───┘ │
|
||||
│ │ 1:N │ 1:N │
|
||||
│ │ │ │
|
||||
│ │ └─────────────┐ │
|
||||
│ │ │ │
|
||||
│ │ ▼ │
|
||||
│ │ ┌──────────────────┐ │
|
||||
│ │ │ member_card │ │
|
||||
│ │ │ (会员卡) │ │
|
||||
│ │ └────────┬─────────┘ │
|
||||
│ │ │ N:1 │
|
||||
│ │ ▼ │
|
||||
│ │ ┌──────────────────┐ │
|
||||
│ │ │ card_type │ │
|
||||
│ │ │ (卡类型) │ │
|
||||
│ │ └────────┬─────────┘ │
|
||||
│ │ │ 1:N │
|
||||
│ │ ▼ │
|
||||
│ │ ┌──────────────────┐ │
|
||||
│ │ │ level_rule │ │
|
||||
│ │ │ (等级规则) │ │
|
||||
│ │ └──────────────────┘ │
|
||||
│ │ │
|
||||
│ │ ┌──────────────────┐ │
|
||||
│ └───────────────────────┤ member_benefit │ │
|
||||
│ │ (会员权益) │ │
|
||||
│ └──────────────────┘ │
|
||||
│ ┌──────────────┐ │
|
||||
│ │ tenant │ │
|
||||
│ │ (租户表) │ │
|
||||
│ └──────┬───────┘ │
|
||||
│ │ 1:N │
|
||||
│ ┌────┴────┐ │
|
||||
│ ▼ ▼ │
|
||||
│ ┌──────┐ ┌──────┐ │
|
||||
│ │store │ │member│ │
|
||||
│ │(门店)│ │(会员)│ │
|
||||
│ └──┬───┘ └──┬───┘ │
|
||||
│ │ 1:N │ 1:N │
|
||||
│ │ │ │
|
||||
│ │ └─────────────┐ │
|
||||
│ │ │ │
|
||||
│ │ ▼ │
|
||||
│ │ ┌──────────────────┐ │
|
||||
│ │ │ member_card │ │
|
||||
│ │ │ (会员卡) │ │
|
||||
│ │ └────────┬─────────┘ │
|
||||
│ │ │ N:1 │
|
||||
│ │ ▼ │
|
||||
│ │ ┌──────────────────┐ │
|
||||
│ │ │ card_type │ │
|
||||
│ │ │ (卡类型) │ │
|
||||
│ │ └────────┬─────────┘ │
|
||||
│ │ │ 1:N │
|
||||
│ │ ▼ │
|
||||
│ │ ┌──────────────────┐ │
|
||||
│ │ │ level_rule │ │
|
||||
│ │ │ (等级规则) │ │
|
||||
│ │ └──────────────────┘ │
|
||||
│ │ │
|
||||
│ │ ┌──────────────────┐ │
|
||||
│ └───────────────────────┤ member_benefit │ │
|
||||
│ │ (会员权益) │ │
|
||||
│ └──────────────────┘ │
|
||||
│ │
|
||||
│ 关系说明: │
|
||||
│ • tenant (1) ─── (N) store : 一个租户有多个门店 │
|
||||
@@ -370,76 +370,76 @@ CREATE INDEX idx_exp_log_created ON exp_log(created_at);
|
||||
│ 会员领域模型 │
|
||||
├─────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌───────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ <<Entity>> │ │
|
||||
│ │ Member │ │
|
||||
│ ├───────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ - id: Long │ │
|
||||
│ │ - tenantId: Long │ │
|
||||
│ │ - storeId: Long │ │
|
||||
│ │ - memberNo: String │ │
|
||||
│ │ - name: String │ │
|
||||
│ │ - phone: String │ │
|
||||
│ │ - avatar: String │ │
|
||||
│ │ - gender: Gender │ │
|
||||
│ │ - birthday: LocalDate │ │
|
||||
│ │ - level: Integer │ │
|
||||
│ │ - exp: Integer │ │
|
||||
│ │ - status: MemberStatus │ │
|
||||
│ │ - cards: List<MemberCard> │ │
|
||||
│ │ - benefits: List<MemberBenefit> │ │
|
||||
│ ├───────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ + activate(): void │ │
|
||||
│ │ + freeze(reason: String): void │ │
|
||||
│ │ + unfreeze(): void │ │
|
||||
│ │ + addExp(exp: Integer): void │ │
|
||||
│ │ + canLevelUp(): Boolean │ │
|
||||
│ │ + levelUp(): void │ │
|
||||
│ │ + getValidBenefits(): List<MemberBenefit> │ │
|
||||
│ │ + getUsableBenefit(type: BenefitType): MemberBenefit │ │
|
||||
│ └───────────────────────────────────────────────────────────────────┘ │
|
||||
│ │ │
|
||||
│ │ 1:N │
|
||||
│ ▼ │
|
||||
│ ┌────────────────────────────┐ ┌────────────────────────────┐ │
|
||||
│ │ <<Entity>> │ │ <<Entity>> │ │
|
||||
│ │ MemberCard │ │ MemberBenefit │ │
|
||||
│ ├────────────────────────────┤ ├────────────────────────────┤ │
|
||||
│ │ - id: Long │ │ - id: Long │ │
|
||||
│ │ - memberId: Long │ │ - memberId: Long │ │
|
||||
│ │ - cardTypeId: Long │ │ - cardId: Long │ │
|
||||
│ │ - cardNo: String │ │ - type: BenefitType │ │
|
||||
│ │ - status: CardStatus │ │ - category: BenefitCategory│ │
|
||||
│ │ - startDate: LocalDate │ │ - value: BigDecimal │ │
|
||||
│ │ - endDate: LocalDate │ │ - usedValue: BigDecimal │ │
|
||||
│ │ - price: BigDecimal │ │ - remainValue: BigDecimal │ │
|
||||
│ ├────────────────────────────┤ │ - expireDate: LocalDate │ │
|
||||
│ │ + activate(): void │ │ - status: BenefitStatus │ │
|
||||
│ │ + freeze(): void │ ├────────────────────────────┤ │
|
||||
│ │ + unfreeze(): void │ │ + deduct(value): void │ │
|
||||
│ │ + isExpired(): Boolean │ │ + add(value): void │ │
|
||||
│ │ + isUsable(): Boolean │ │ + isExpired(): Boolean │ │
|
||||
│ │ + getRemainDays(): Integer │ │ + isUsable(): Boolean │ │
|
||||
│ └────────────────────────────┘ └────────────────────────────┘ │
|
||||
│ ┌───────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ <<Entity>> │ │
|
||||
│ │ Member │ │
|
||||
│ ├───────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ - id: Long │ │
|
||||
│ │ - tenantId: Long │ │
|
||||
│ │ - storeId: Long │ │
|
||||
│ │ - memberNo: String │ │
|
||||
│ │ - name: String │ │
|
||||
│ │ - phone: String │ │
|
||||
│ │ - avatar: String │ │
|
||||
│ │ - gender: Gender │ │
|
||||
│ │ - birthday: LocalDate │ │
|
||||
│ │ - level: Integer │ │
|
||||
│ │ - exp: Integer │ │
|
||||
│ │ - status: MemberStatus │ │
|
||||
│ │ - cards: List<MemberCard> │ │
|
||||
│ │ - benefits: List<MemberBenefit> │ │
|
||||
│ ├───────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ + activate(): void │ │
|
||||
│ │ + freeze(reason: String): void │ │
|
||||
│ │ + unfreeze(): void │ │
|
||||
│ │ + addExp(exp: Integer): void │ │
|
||||
│ │ + canLevelUp(): Boolean │ │
|
||||
│ │ + levelUp(): void │ │
|
||||
│ │ + getValidBenefits(): List<MemberBenefit> │ │
|
||||
│ │ + getUsableBenefit(type: BenefitType): MemberBenefit │ │
|
||||
│ └───────────────────────────────────────────────────────────────────┘ │
|
||||
│ │ │
|
||||
│ │ 1:N │
|
||||
│ ▼ │
|
||||
│ ┌────────────────────────────┐ ┌────────────────────────────┐ │
|
||||
│ │ <<Entity>> │ │ <<Entity>> │ │
|
||||
│ │ MemberCard │ │ MemberBenefit │ │
|
||||
│ ├────────────────────────────┤ ├────────────────────────────┤ │
|
||||
│ │ - id: Long │ │ - id: Long │ │
|
||||
│ │ - memberId: Long │ │ - memberId: Long │ │
|
||||
│ │ - cardTypeId: Long │ │ - cardId: Long │ │
|
||||
│ │ - cardNo: String │ │ - type: BenefitType │ │
|
||||
│ │ - status: CardStatus │ │ - category: BenefitCategory│ │
|
||||
│ │ - startDate: LocalDate │ │ - value: BigDecimal │ │
|
||||
│ │ - endDate: LocalDate │ │ - usedValue: BigDecimal │ │
|
||||
│ │ - price: BigDecimal │ │ - remainValue: BigDecimal │ │
|
||||
│ ├────────────────────────────┤ │ - expireDate: LocalDate │ │
|
||||
│ │ + activate(): void │ │ - status: BenefitStatus │ │
|
||||
│ │ + freeze(): void │ ├────────────────────────────┤ │
|
||||
│ │ + unfreeze(): void │ │ + deduct(value): void │ │
|
||||
│ │ + isExpired(): Boolean │ │ + add(value): void │ │
|
||||
│ │ + isUsable(): Boolean │ │ + isExpired(): Boolean │ │
|
||||
│ │ + getRemainDays(): Integer │ │ + isUsable(): Boolean │ │
|
||||
│ └────────────────────────────┘ └────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌────────────────────────────┐ ┌────────────────────────────┐ │
|
||||
│ │ <<ValueObject>> │ │ <<ValueObject>> │ │
|
||||
│ │ MemberStatus │ │ BenefitType │ │
|
||||
│ ├────────────────────────────┤ ├────────────────────────────┤ │
|
||||
│ │ NORMAL(1, "正常") │ │ DURATION(1, "时长") │ │
|
||||
│ │ FROZEN(2, "冻结") │ │ TIMES(2, "次数") │ │
|
||||
│ │ CANCELLED(3, "注销") │ │ STORED_VALUE(3, "储值") │ │
|
||||
│ └────────────────────────────┘ │ LEVEL(4, "等级") │ │
|
||||
│ └────────────────────────────┘ │
|
||||
│ ┌────────────────────────────┐ ┌────────────────────────────┐ │
|
||||
│ │ <<ValueObject>> │ │ <<ValueObject>> │ │
|
||||
│ │ MemberStatus │ │ BenefitType │ │
|
||||
│ ├────────────────────────────┤ ├────────────────────────────┤ │
|
||||
│ │ NORMAL(1, "正常") │ │ DURATION(1, "时长") │ │
|
||||
│ │ FROZEN(2, "冻结") │ │ TIMES(2, "次数") │ │
|
||||
│ │ CANCELLED(3, "注销") │ │ STORED_VALUE(3, "储值") │ │
|
||||
│ └────────────────────────────┘ │ LEVEL(4, "等级") │ │
|
||||
│ └────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌────────────────────────────┐ ┌────────────────────────────┐ │
|
||||
│ │ <<ValueObject>> │ │ <<ValueObject>> │ │
|
||||
│ │ CardStatus │ │ BenefitCategory │ │
|
||||
│ ├────────────────────────────┤ ├────────────────────────────┤ │
|
||||
│ │ INACTIVE(1, "未激活") │ │ GROUP_CLASS(1, "团课") │ │
|
||||
│ │ ACTIVE(2, "有效") │ │ PRIVATE(2, "私教") │ │
|
||||
│ │ EXPIRED(3, "已过期") │ │ GENERAL(3, "通用") │ │
|
||||
│ │ USED_UP(4, "已用完") │ └────────────────────────────┘ │
|
||||
│ ┌────────────────────────────┐ ┌────────────────────────────┐ │
|
||||
│ │ <<ValueObject>> │ │ <<ValueObject>> │ │
|
||||
│ │ CardStatus │ │ BenefitCategory │ │
|
||||
│ ├────────────────────────────┤ ├────────────────────────────┤ │
|
||||
│ │ INACTIVE(1, "未激活") │ │ GROUP_CLASS(1, "团课") │ │
|
||||
│ │ ACTIVE(2, "有效") │ │ PRIVATE(2, "私教") │ │
|
||||
│ │ EXPIRED(3, "已过期") │ │ GENERAL(3, "通用") │ │
|
||||
│ │ USED_UP(4, "已用完") │ └────────────────────────────┘ │
|
||||
│ │ FROZEN(5, "已冻结") │ │
|
||||
│ └────────────────────────────┘ │
|
||||
│ │
|
||||
@@ -453,37 +453,37 @@ CREATE INDEX idx_exp_log_created ON exp_log(created_at);
|
||||
│ 领域服务设计 │
|
||||
├─────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌───────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ <<DomainService>> │ │
|
||||
│ │ MemberDomainService │ │
|
||||
│ ├───────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ + registerMember(command: RegisterMemberCommand): Member │ │
|
||||
│ │ + updateMemberInfo(memberId: Long, command: UpdateMemberCommand) │ │
|
||||
│ │ + freezeMember(memberId: Long, reason: String): void │ │
|
||||
│ │ + unfreezeMember(memberId: Long): void │ │
|
||||
│ │ + calculateLevel(memberId: Long): Integer │ │
|
||||
│ └───────────────────────────────────────────────────────────────────┘ │
|
||||
│ ┌───────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ <<DomainService>> │ │
|
||||
│ │ MemberDomainService │ │
|
||||
│ ├───────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ + registerMember(command: RegisterMemberCommand): Member │ │
|
||||
│ │ + updateMemberInfo(memberId: Long, command: UpdateMemberCommand) │ │
|
||||
│ │ + freezeMember(memberId: Long, reason: String): void │ │
|
||||
│ │ + unfreezeMember(memberId: Long): void │ │
|
||||
│ │ + calculateLevel(memberId: Long): Integer │ │
|
||||
│ └───────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌───────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ <<DomainService>> │ │
|
||||
│ │ BenefitDomainService │ │
|
||||
│ ├───────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ + purchaseCard(command: PurchaseCardCommand): MemberCard │ │
|
||||
│ │ + activateCard(cardId: Long): void │ │
|
||||
│ │ + deductBenefit(memberId: Long, request: DeductRequest): void │ │
|
||||
│ │ + refundBenefit(memberId: Long, request: RefundRequest): void │ │
|
||||
│ │ + expireBenefits(): void │ │
|
||||
│ │ + getUsableBenefits(memberId: Long, type: BenefitType): List │ │
|
||||
│ └───────────────────────────────────────────────────────────────────┘ │
|
||||
│ ┌───────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ <<DomainService>> │ │
|
||||
│ │ BenefitDomainService │ │
|
||||
│ ├───────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ + purchaseCard(command: PurchaseCardCommand): MemberCard │ │
|
||||
│ │ + activateCard(cardId: Long): void │ │
|
||||
│ │ + deductBenefit(memberId: Long, request: DeductRequest): void │ │
|
||||
│ │ + refundBenefit(memberId: Long, request: RefundRequest): void │ │
|
||||
│ │ + expireBenefits(): void │ │
|
||||
│ │ + getUsableBenefits(memberId: Long, type: BenefitType): List │ │
|
||||
│ └───────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌───────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ <<DomainService>> │ │
|
||||
│ │ LevelDomainService │ │
|
||||
│ ├───────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ + addExp(memberId: Long, exp: Integer, source: String): void │ │
|
||||
│ │ + calculateLevel(tenantId: Long, exp: Integer): Integer │ │
|
||||
│ │ + getLevelBenefits(tenantId: Long, level: Integer): LevelBenefit │ │
|
||||
│ └───────────────────────────────────────────────────────────────────┘ │
|
||||
│ ┌───────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ <<DomainService>> │ │
|
||||
│ │ LevelDomainService │ │
|
||||
│ ├───────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ + addExp(memberId: Long, exp: Integer, source: String): void │ │
|
||||
│ │ + calculateLevel(tenantId: Long, exp: Integer): Integer │ │
|
||||
│ │ + getLevelBenefits(tenantId: Long, level: Integer): LevelBenefit │ │
|
||||
│ └───────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
@@ -499,35 +499,35 @@ CREATE INDEX idx_exp_log_created ON exp_log(created_at);
|
||||
│ 会员注册流程 │
|
||||
├─────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ 会员端 API层 Service层 数据层 │
|
||||
│ │ │ │ │ │
|
||||
│ │ 1.输入手机号 │ │ │ │
|
||||
│ │─────────────────▶│ │ │ │
|
||||
│ │ │ 2.发送验证码 │ │ │
|
||||
│ │ │───────────────────▶│ │ │
|
||||
│ │ │ │ 3.调用短信服务 │ │
|
||||
│ │ │ │─────────────────▶│ │
|
||||
│ │ │ │◀─────────────────│ │
|
||||
│ │ │◀───────────────────│ │ │
|
||||
│ │◀─────────────────│ 返回验证码ID │ │ │
|
||||
│ │ │ │ │ │
|
||||
│ │ 4.提交注册信息 │ │ │ │
|
||||
│ │─────────────────▶│ │ │ │
|
||||
│ │ │ 5.验证验证码 │ │ │
|
||||
│ │ │───────────────────▶│ │ │
|
||||
│ │ │ │ 6.查询手机号 │ │
|
||||
│ │ │ │─────────────────▶│ │
|
||||
│ │ │ │◀─────────────────│ │
|
||||
│ │ │ │ 7.检查是否已注册 │ │
|
||||
│ │ │ │ │ │
|
||||
│ │ │ │ 8.生成会员编号 │ │
|
||||
│ │ │ │ 9.创建会员 │ │
|
||||
│ │ │ │─────────────────▶│ │
|
||||
│ │ │ │◀─────────────────│ │
|
||||
│ │ │ │ 10.生成JWT Token │ │
|
||||
│ │ │◀───────────────────│ │ │
|
||||
│ │◀─────────────────│ 返回Token和会员信息 │ │ │
|
||||
│ │ │ │ │ │
|
||||
│ 会员端 API层 Service层 数据层 │
|
||||
│ │ │ │ │ │
|
||||
│ │ 1.输入手机号 │ │ │ │
|
||||
│ │─────────────────▶│ │ │ │
|
||||
│ │ │ 2.发送验证码 │ │ │
|
||||
│ │ │───────────────────▶│ │ │
|
||||
│ │ │ │ 3.调用短信服务 │ │
|
||||
│ │ │ │─────────────────▶│ │
|
||||
│ │ │ │◀─────────────────│ │
|
||||
│ │ │◀───────────────────│ │ │
|
||||
│ │◀─────────────────│ 返回验证码ID │ │ │
|
||||
│ │ │ │ │ │
|
||||
│ │ 4.提交注册信息 │ │ │ │
|
||||
│ │─────────────────▶│ │ │ │
|
||||
│ │ │ 5.验证验证码 │ │ │
|
||||
│ │ │───────────────────▶│ │ │
|
||||
│ │ │ │ 6.查询手机号 │ │
|
||||
│ │ │ │─────────────────▶│ │
|
||||
│ │ │ │◀─────────────────│ │
|
||||
│ │ │ │ 7.检查是否已注册 │ │
|
||||
│ │ │ │ │ │
|
||||
│ │ │ │ 8.生成会员编号 │ │
|
||||
│ │ │ │ 9.创建会员 │ │
|
||||
│ │ │ │─────────────────▶│ │
|
||||
│ │ │ │◀─────────────────│ │
|
||||
│ │ │ │ 10.生成JWT Token │ │
|
||||
│ │ │◀───────────────────│ │ │
|
||||
│ │◀─────────────────│ 返回Token和会员信息 │ │ │
|
||||
│ │ │ │ │ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
@@ -539,35 +539,35 @@ CREATE INDEX idx_exp_log_created ON exp_log(created_at);
|
||||
│ 会员卡购买流程 │
|
||||
├─────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ 会员端 API层 OrderService MemberService PaymentService │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ 1.选择卡种│ │ │ │ │
|
||||
│ │─────────▶│ │ │ │ │
|
||||
│ │ │ 2.创建订单 │ │ │ │
|
||||
│ │ │───────────▶│ │ │ │
|
||||
│ │ │ │ 3.校验卡种 │ │ │
|
||||
│ │ │ │─────────────▶│ │ │
|
||||
│ │ │ │◀─────────────│ │ │
|
||||
│ │ │ │ 4.创建支付单 │ │ │
|
||||
│ │ │ │─────────────────────────────▶│ │
|
||||
│ │ │ │◀─────────────────────────────│ │
|
||||
│ │◀────────│ 返回支付参数│ │ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ 5.完成支付│ │ │ │ │
|
||||
│ │──────────────────────────────────────────────────▶│ │
|
||||
│ │ │ │ │ 6.支付回调 │ │
|
||||
│ │ │ │◀─────────────────────────────│ │
|
||||
│ │ │ │ 7.更新订单状态│ │ │
|
||||
│ │ │ │─────────────▶│ │ │
|
||||
│ │ │ │ │ 8.创建会员卡 │ │
|
||||
│ │ │ │ │─────────────▶ │ │
|
||||
│ │ │ │ │ 9.创建权益 │ │
|
||||
│ │ │ │ │─────────────▶ │ │
|
||||
│ │ │ │ │ 10.增加经验值 │ │
|
||||
│ │ │ │ │─────────────▶ │ │
|
||||
│ │ │ │◀─────────────│ │ │
|
||||
│ │◀────────│ 购买成功通知│ │ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ 会员端 API层 OrderService MemberService PaymentService │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ 1.选择卡种│ │ │ │ │
|
||||
│ │─────────▶│ │ │ │ │
|
||||
│ │ │ 2.创建订单 │ │ │ │
|
||||
│ │ │───────────▶│ │ │ │
|
||||
│ │ │ │ 3.校验卡种 │ │ │
|
||||
│ │ │ │─────────────▶│ │ │
|
||||
│ │ │ │◀─────────────│ │ │
|
||||
│ │ │ │ 4.创建支付单 │ │ │
|
||||
│ │ │ │─────────────────────────────▶│ │
|
||||
│ │ │ │◀─────────────────────────────│ │
|
||||
│ │◀────────│ 返回支付参数│ │ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ 5.完成支付│ │ │ │ │
|
||||
│ │──────────────────────────────────────────────────▶│ │
|
||||
│ │ │ │ │ 6.支付回调 │ │
|
||||
│ │ │ │◀─────────────────────────────│ │
|
||||
│ │ │ │ 7.更新订单状态│ │ │
|
||||
│ │ │ │─────────────▶│ │ │
|
||||
│ │ │ │ │ 8.创建会员卡 │ │
|
||||
│ │ │ │ │─────────────▶ │ │
|
||||
│ │ │ │ │ 9.创建权益 │ │
|
||||
│ │ │ │ │─────────────▶ │ │
|
||||
│ │ │ │ │ 10.增加经验值 │ │
|
||||
│ │ │ │ │─────────────▶ │ │
|
||||
│ │ │ │◀─────────────│ │ │
|
||||
│ │◀────────│ 购买成功通知│ │ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
@@ -579,35 +579,35 @@ CREATE INDEX idx_exp_log_created ON exp_log(created_at);
|
||||
│ 权益扣减流程 │
|
||||
├─────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ 调用方 BenefitService Repository │
|
||||
│ │ │ │ │
|
||||
│ │ 1.请求扣减权益 │ │ │
|
||||
│ │─────────────────▶│ │ │
|
||||
│ │ │ 2.查询可用权益 │ │
|
||||
│ │ │────────────────────▶│ │
|
||||
│ │ │◀────────────────────│ │
|
||||
│ │ │ │ │
|
||||
│ │ │ 3.按优先级排序 │ │
|
||||
│ │ │ (即将过期优先) │ │
|
||||
│ │ │ │ │
|
||||
│ │ │ 4.校验余额充足 │ │
|
||||
│ │ │ │ │
|
||||
│ │ │ 5.执行扣减(事务) │ │
|
||||
│ │ │────────────────────▶│ │
|
||||
│ │ │ UPDATE member_benefit │
|
||||
│ │ │ SET remain_value = remain_value - ? │
|
||||
│ │ │ used_value = used_value + ? │
|
||||
│ │ │ WHERE id = ? AND remain_value >= ? │
|
||||
│ │ │ │ │
|
||||
│ │ │ 6.记录变更日志 │ │
|
||||
│ │ │────────────────────▶│ │
|
||||
│ │ │ │ │
|
||||
│ │ │ 7.检查是否用完 │ │
|
||||
│ │ │ 更新状态 │ │
|
||||
│ │ │────────────────────▶│ │
|
||||
│ │ │ │ │
|
||||
│ │◀─────────────────│ 返回扣减结果 │ │
|
||||
│ │ │ │ │
|
||||
│ 调用方 BenefitService Repository │
|
||||
│ │ │ │ │
|
||||
│ │ 1.请求扣减权益 │ │ │
|
||||
│ │─────────────────▶│ │ │
|
||||
│ │ │ 2.查询可用权益 │ │
|
||||
│ │ │────────────────────▶│ │
|
||||
│ │ │◀────────────────────│ │
|
||||
│ │ │ │ │
|
||||
│ │ │ 3.按优先级排序 │ │
|
||||
│ │ │ (即将过期优先) │ │
|
||||
│ │ │ │ │
|
||||
│ │ │ 4.校验余额充足 │ │
|
||||
│ │ │ │ │
|
||||
│ │ │ 5.执行扣减(事务) │ │
|
||||
│ │ │────────────────────▶│ │
|
||||
│ │ │ UPDATE member_benefit │
|
||||
│ │ │ SET remain_value = remain_value - ? │
|
||||
│ │ │ used_value = used_value + ? │
|
||||
│ │ │ WHERE id = ? AND remain_value >= ? │
|
||||
│ │ │ │ │
|
||||
│ │ │ 6.记录变更日志 │ │
|
||||
│ │ │────────────────────▶│ │
|
||||
│ │ │ │ │
|
||||
│ │ │ 7.检查是否用完 │ │
|
||||
│ │ │ 更新状态 │ │
|
||||
│ │ │────────────────────▶│ │
|
||||
│ │ │ │ │
|
||||
│ │◀─────────────────│ 返回扣减结果 │ │
|
||||
│ │ │ │ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
@@ -619,35 +619,35 @@ CREATE INDEX idx_exp_log_created ON exp_log(created_at);
|
||||
│ 等级升级流程 │
|
||||
├─────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ 触发源 LevelService Member LevelRule │
|
||||
│ │ │ │ │ │
|
||||
│ │ 1.增加经验值 │ │ │ │
|
||||
│ │────────────────▶│ │ │ │
|
||||
│ │ │ 2.查询当前会员 │ │ │
|
||||
│ │ │───────────────────▶│ │ │
|
||||
│ │ │◀───────────────────│ │ │
|
||||
│ │ │ │ │ │
|
||||
│ │ │ 3.计算新等级 │ │ │
|
||||
│ │ │─────────────────────────────────────▶│ │
|
||||
│ │ │◀─────────────────────────────────────│ │
|
||||
│ │ │ │ │ │
|
||||
│ │ │ 4.比较是否升级 │ │ │
|
||||
│ │ │ │ │ │
|
||||
│ │ │ [如果升级] │ │ │
|
||||
│ │ │ 5.更新会员等级 │ │ │
|
||||
│ │ │───────────────────▶│ │ │
|
||||
│ │ │ │ │ │
|
||||
│ │ │ 6.发放升级奖励 │ │ │
|
||||
│ │ │ (经验值/优惠券) │ │ │
|
||||
│ │ │───────────────────▶│ │ │
|
||||
│ │ │ │ │ │
|
||||
│ │ │ 7.记录升级日志 │ │ │
|
||||
│ │ │───────────────────▶│ │ │
|
||||
│ │ │ │ │ │
|
||||
│ │ │ 8.发送升级通知 │ │ │
|
||||
│ │ │ │ │ │
|
||||
│ │◀────────────────│ 返回升级结果 │ │ │
|
||||
│ │ │ │ │ │
|
||||
│ 触发源 LevelService Member LevelRule │
|
||||
│ │ │ │ │ │
|
||||
│ │ 1.增加经验值 │ │ │ │
|
||||
│ │────────────────▶│ │ │ │
|
||||
│ │ │ 2.查询当前会员 │ │ │
|
||||
│ │ │───────────────────▶│ │ │
|
||||
│ │ │◀───────────────────│ │ │
|
||||
│ │ │ │ │ │
|
||||
│ │ │ 3.计算新等级 │ │ │
|
||||
│ │ │─────────────────────────────────────▶│ │
|
||||
│ │ │◀─────────────────────────────────────│ │
|
||||
│ │ │ │ │ │
|
||||
│ │ │ 4.比较是否升级 │ │ │
|
||||
│ │ │ │ │ │
|
||||
│ │ │ [如果升级] │ │ │
|
||||
│ │ │ 5.更新会员等级 │ │ │
|
||||
│ │ │───────────────────▶│ │ │
|
||||
│ │ │ │ │ │
|
||||
│ │ │ 6.发放升级奖励 │ │ │
|
||||
│ │ │ (经验值/优惠券) │ │ │
|
||||
│ │ │───────────────────▶│ │ │
|
||||
│ │ │ │ │ │
|
||||
│ │ │ 7.记录升级日志 │ │ │
|
||||
│ │ │───────────────────▶│ │ │
|
||||
│ │ │ │ │ │
|
||||
│ │ │ 8.发送升级通知 │ │ │
|
||||
│ │ │ │ │ │
|
||||
│ │◀────────────────│ 返回升级结果 │ │ │
|
||||
│ │ │ │ │ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
@@ -1802,10 +1802,10 @@ member:
|
||||
|
||||
## 十一、版本历史
|
||||
|
||||
| 版本 | 日期 | 作者 | 变更内容 |
|
||||
|------|------|------|---------|
|
||||
| v1.0 | 2026-02-28 | 张翔 | 初稿 |
|
||||
| 版本 | 日期 | 作者 | 变更内容 |
|
||||
| ---- | ---------- | ---- | -------- |
|
||||
| v1.0 | 2026-02-28 | 张翔 | 初稿 |
|
||||
|
||||
---
|
||||
|
||||
*文档结束*
|
||||
_文档结束_
|
||||
|
||||
+282
-282
@@ -10,9 +10,9 @@
|
||||
|
||||
## 文档修订历史
|
||||
|
||||
| 版本 | 日期 | 作者 | 修订内容 |
|
||||
|------|------|------|---------|
|
||||
| v1.0 | 2026-02-28 | 张翔 | 初稿 |
|
||||
| 版本 | 日期 | 作者 | 修订内容 |
|
||||
| ---- | ---------- | ---- | -------- |
|
||||
| v1.0 | 2026-02-28 | 张翔 | 初稿 |
|
||||
|
||||
---
|
||||
|
||||
@@ -44,41 +44,41 @@
|
||||
│ 签到模块边界 │
|
||||
├─────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 签到模块内部 │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • 签到网关 • 签到验证 • 签到记录 • 签到统计 │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 签到模块内部 │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • 签到网关 • 签到验证 • 签到记录 • 签到统计 │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 外部依赖 │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • 会员模块 (查询会员信息、验证会员状态) │ │
|
||||
│ │ • 权益模块 (验证权益有效性、扣减权益) │ │
|
||||
│ │ • 预约模块 (查询预约信息、验证签到资格) │ │
|
||||
│ │ • 设备模块 (人脸识别设备、NFC读卡器) │ │
|
||||
│ │ • 消息模块 (发送签到通知) │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 外部依赖 │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • 会员模块 (查询会员信息、验证会员状态) │ │
|
||||
│ │ • 权益模块 (验证权益有效性、扣减权益) │ │
|
||||
│ │ • 预约模块 (查询预约信息、验证签到资格) │ │
|
||||
│ │ • 设备模块 (人脸识别设备、NFC读卡器) │ │
|
||||
│ │ • 消息模块 (发送签到通知) │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 被依赖 │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • 财务模块 (签到消费记录) │ │
|
||||
│ │ • 数据模块 (签到数据分析、会员活跃度统计) │ │
|
||||
│ │ • 考勤模块 (教练考勤统计) │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 被依赖 │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • 财务模块 (签到消费记录) │ │
|
||||
│ │ • 数据模块 (签到数据分析、会员活跃度统计) │ │
|
||||
│ │ • 考勤模块 (教练考勤统计) │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 1.3 签到类型
|
||||
|
||||
| 签到类型 | 说明 | 触发条件 | 验证规则 |
|
||||
|---------|------|---------|---------|
|
||||
| **入场签到** | 会员进入健身房 | 扫码/人脸/NFC | 验证会员卡有效性 |
|
||||
| 签到类型 | 说明 | 触发条件 | 验证规则 |
|
||||
| ------------ | ---------------- | ------------- | ---------------------- |
|
||||
| **入场签到** | 会员进入健身房 | 扫码/人脸/NFC | 验证会员卡有效性 |
|
||||
| **课程签到** | 会员参加预约课程 | 扫码/教练代签 | 验证预约记录、时间窗口 |
|
||||
| **私教签到** | 会员上私教课 | 教练代签 | 验证私教预约、教练身份 |
|
||||
| **活动签到** | 会员参加活动 | 扫码 | 验证活动报名 |
|
||||
| **私教签到** | 会员上私教课 | 教练代签 | 验证私教预约、教练身份 |
|
||||
| **活动签到** | 会员参加活动 | 扫码 | 验证活动报名 |
|
||||
|
||||
---
|
||||
|
||||
@@ -91,19 +91,19 @@
|
||||
│ 实体关系图 │
|
||||
├─────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌──────────────┐ ┌──────────────────┐ ┌──────────────┐ │
|
||||
│ │ member │ │ booking_record │ │ device │ │
|
||||
│ │ (会员) │ │ (预约记录) │ │ (设备) │ │
|
||||
│ └──────┬───────┘ └────────┬─────────┘ └──────┬───────┘ │
|
||||
│ │ 1:N │ 1:N │ 1:N │
|
||||
│ │ │ │ │
|
||||
│ └───────────────────┴─────────────────────┘ │
|
||||
│ │ 1:N │
|
||||
│ ▼ │
|
||||
│ ┌──────────────────┐ │
|
||||
│ │ checkin_record │ │
|
||||
│ │ (签到记录) │ │
|
||||
│ └──────────────────┘ │
|
||||
│ ┌──────────────┐ ┌──────────────────┐ ┌──────────────┐ │
|
||||
│ │ member │ │ booking_record │ │ device │ │
|
||||
│ │ (会员) │ │ (预约记录) │ │ (设备) │ │
|
||||
│ └──────┬───────┘ └────────┬─────────┘ └──────┬───────┘ │
|
||||
│ │ 1:N │ 1:N │ 1:N │
|
||||
│ │ │ │ │
|
||||
│ └───────────────────┴─────────────────────┘ │
|
||||
│ │ 1:N │
|
||||
│ ▼ │
|
||||
│ ┌──────────────────┐ │
|
||||
│ │ checkin_record │ │
|
||||
│ │ (签到记录) │ │
|
||||
│ └──────────────────┘ │
|
||||
│ │
|
||||
│ ┌──────────────┐ │
|
||||
│ │ member │ │
|
||||
@@ -303,48 +303,48 @@ CREATE INDEX idx_rule_type ON checkin_rule(rule_type) WHERE deleted_at IS NULL;
|
||||
│ 签到聚合设计 │
|
||||
├─────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌───────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ CheckinRecord (聚合根) │ │
|
||||
│ ├───────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ - id: Long │ │
|
||||
│ │ - tenantId: Long │ │
|
||||
│ │ - storeId: Long │ │
|
||||
│ │ - memberId: Long │ │
|
||||
│ │ - bookingId: Long? │ │
|
||||
│ │ - type: CheckinType │ │
|
||||
│ │ - method: CheckinMethod │ │
|
||||
│ │ - device: DeviceInfo? │ │
|
||||
│ │ - operator: OperatorInfo? │ │
|
||||
│ │ - status: CheckinStatus │ │
|
||||
│ │ - checkinAt: LocalDateTime │ │
|
||||
│ │ - benefit: BenefitDeduction? │ │
|
||||
│ │ │ │
|
||||
│ │ 行为: │ │
|
||||
│ │ + checkin(): void │ │
|
||||
│ │ + cancel(reason: String): void │ │
|
||||
│ │ + isLate(): Boolean │ │
|
||||
│ │ + getDuration(): Duration │ │
|
||||
│ └───────────────────────────────────────────────────────────────────┘ │
|
||||
│ ┌───────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ CheckinRecord (聚合根) │ │
|
||||
│ ├───────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ - id: Long │ │
|
||||
│ │ - tenantId: Long │ │
|
||||
│ │ - storeId: Long │ │
|
||||
│ │ - memberId: Long │ │
|
||||
│ │ - bookingId: Long? │ │
|
||||
│ │ - type: CheckinType │ │
|
||||
│ │ - method: CheckinMethod │ │
|
||||
│ │ - device: DeviceInfo? │ │
|
||||
│ │ - operator: OperatorInfo? │ │
|
||||
│ │ - status: CheckinStatus │ │
|
||||
│ │ - checkinAt: LocalDateTime │ │
|
||||
│ │ - benefit: BenefitDeduction? │ │
|
||||
│ │ │ │
|
||||
│ │ 行为: │ │
|
||||
│ │ + checkin(): void │ │
|
||||
│ │ + cancel(reason: String): void │ │
|
||||
│ │ + isLate(): Boolean │ │
|
||||
│ │ + getDuration(): Duration │ │
|
||||
│ └───────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌───────────────────────┐ ┌───────────────────────┐ │
|
||||
│ │ CheckinGateway │ │ CheckinValidator │ │
|
||||
│ │ (签到网关) │ │ (签到验证器) │ │
|
||||
│ ├───────────────────────┤ ├───────────────────────┤ │
|
||||
│ │ + processQRCode() │ │ + validateMember() │ │
|
||||
│ │ + processFace() │ │ + validateBooking() │ │
|
||||
│ │ + processNFC() │ │ + validateBenefit() │ │
|
||||
│ │ + processManual() │ │ + validateRule() │ │
|
||||
│ └───────────────────────┘ └───────────────────────┘ │
|
||||
│ ┌───────────────────────┐ ┌───────────────────────┐ │
|
||||
│ │ CheckinGateway │ │ CheckinValidator │ │
|
||||
│ │ (签到网关) │ │ (签到验证器) │ │
|
||||
│ ├───────────────────────┤ ├───────────────────────┤ │
|
||||
│ │ + processQRCode() │ │ + validateMember() │ │
|
||||
│ │ + processFace() │ │ + validateBooking() │ │
|
||||
│ │ + processNFC() │ │ + validateBenefit() │ │
|
||||
│ │ + processManual() │ │ + validateRule() │ │
|
||||
│ └───────────────────────┘ └───────────────────────┘ │
|
||||
│ │
|
||||
│ ┌───────────────────────┐ ┌───────────────────────┐ │
|
||||
│ │ CheckinStatistics │ │ FaceRecognition │ │
|
||||
│ │ (签到统计) │ │ (人脸识别) │ │
|
||||
│ ├───────────────────────┤ ├───────────────────────┤ │
|
||||
│ │ + dailyStats() │ │ + register() │ │
|
||||
│ │ + weeklyStats() │ │ + match() │ │
|
||||
│ │ + monthlyStats() │ │ + update() │ │
|
||||
│ │ + memberStats() │ │ + delete() │ │
|
||||
│ └───────────────────────┘ └───────────────────────┘ │
|
||||
│ ┌───────────────────────┐ ┌───────────────────────┐ │
|
||||
│ │ CheckinStatistics │ │ FaceRecognition │ │
|
||||
│ │ (签到统计) │ │ (人脸识别) │ │
|
||||
│ ├───────────────────────┤ ├───────────────────────┤ │
|
||||
│ │ + dailyStats() │ │ + register() │ │
|
||||
│ │ + weeklyStats() │ │ + match() │ │
|
||||
│ │ + monthlyStats() │ │ + update() │ │
|
||||
│ │ + memberStats() │ │ + delete() │ │
|
||||
│ └───────────────────────┘ └───────────────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
@@ -455,47 +455,47 @@ public interface CheckinStatisticsService {
|
||||
│ 入场签到流程 │
|
||||
├─────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌───────┐ ┌───────┐ ┌───────┐ ┌───────┐ ┌───────┐ │
|
||||
│ │ 会员 │ │ 签到 │ │ 签到 │ │ 权益 │ │ 签到 │ │
|
||||
│ │ │ │ 网关 │ │ 验证 │ │ 服务 │ │ 记录 │ │
|
||||
│ └───┬───┘ └───┬───┘ └───┬───┘ └───┬───┘ └───┬───┘ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ 出示二维码 │ │ │ │ │
|
||||
│ │────────────▶│ │ │ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ 解析二维码 │ │ │ │
|
||||
│ │ │────────────▶│ │ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ │ 查询会员 │ │ │
|
||||
│ │ │ │────────────▶│ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ │ 会员信息 │ │ │
|
||||
│ │ │ │◀────────────│ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ │ 验证会员卡 │ │ │
|
||||
│ │ │ │────────────▶│ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ │ 权益状态 │ │ │
|
||||
│ │ │ │◀────────────│ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ │ 检查签到规则│ │ │
|
||||
│ │ │ │─────────────┼────────────▶│ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ │ 规则验证结果│ │ │
|
||||
│ │ │ │◀────────────┼─────────────│ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ 验证结果 │ │ │ │
|
||||
│ │ │◀────────────│ │ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ 创建签到记录│ │ │ │
|
||||
│ │ │─────────────┼─────────────┼────────────▶│ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ 签到成功 │ │ │ │
|
||||
│ │ │◀────────────┼─────────────┼─────────────│ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ 签到成功 │ │ │ │ │
|
||||
│ │◀────────────│ │ │ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ ┌───────┐ ┌───────┐ ┌───────┐ ┌───────┐ ┌───────┐ │
|
||||
│ │ 会员 │ │ 签到 │ │ 签到 │ │ 权益 │ │ 签到 │ │
|
||||
│ │ │ │ 网关 │ │ 验证 │ │ 服务 │ │ 记录 │ │
|
||||
│ └───┬───┘ └───┬───┘ └───┬───┘ └───┬───┘ └───┬───┘ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ 出示二维码 │ │ │ │ │
|
||||
│ │────────────▶│ │ │ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ 解析二维码 │ │ │ │
|
||||
│ │ │────────────▶│ │ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ │ 查询会员 │ │ │
|
||||
│ │ │ │────────────▶│ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ │ 会员信息 │ │ │
|
||||
│ │ │ │◀────────────│ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ │ 验证会员卡 │ │ │
|
||||
│ │ │ │────────────▶│ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ │ 权益状态 │ │ │
|
||||
│ │ │ │◀────────────│ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ │ 检查签到规则│ │ │
|
||||
│ │ │ │─────────────┼────────────▶│ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ │ 规则验证结果│ │ │
|
||||
│ │ │ │◀────────────┼─────────────│ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ 验证结果 │ │ │ │
|
||||
│ │ │◀────────────│ │ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ 创建签到记录│ │ │ │
|
||||
│ │ │─────────────┼─────────────┼────────────▶│ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ 签到成功 │ │ │ │
|
||||
│ │ │◀────────────┼─────────────┼─────────────│ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ 签到成功 │ │ │ │ │
|
||||
│ │◀────────────│ │ │ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
@@ -507,47 +507,47 @@ public interface CheckinStatisticsService {
|
||||
│ 课程签到流程 │
|
||||
├─────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌───────┐ ┌───────┐ ┌───────┐ ┌───────┐ ┌───────┐ │
|
||||
│ │ 会员 │ │ 签到 │ │ 预约 │ │ 权益 │ │ 签到 │ │
|
||||
│ │ │ │ 网关 │ │ 服务 │ │ 服务 │ │ 记录 │ │
|
||||
│ └───┬───┘ └───┬───┘ └───┬───┘ └───┬───┘ └───┬───┘ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ 扫码签到 │ │ │ │ │
|
||||
│ │────────────▶│ │ │ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ 查询预约 │ │ │ │
|
||||
│ │ │────────────▶│ │ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ 预约信息 │ │ │ │
|
||||
│ │ │◀────────────│ │ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ 验证签到时间窗口 │ │ │
|
||||
│ │ │─────────────┼────────────▶│ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ 时间窗口验证结果 │ │ │
|
||||
│ │ │◀────────────┼─────────────│ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ 验证权益 │ │ │ │
|
||||
│ │ │─────────────┼────────────▶│ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ 权益状态 │ │ │ │
|
||||
│ │ │◀────────────┼─────────────│ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ 扣减权益 │ │ │ │
|
||||
│ │ │─────────────┼────────────▶│ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ 扣减结果 │ │ │ │
|
||||
│ │ │◀────────────┼─────────────│ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ 创建签到记录│ │ │ │
|
||||
│ │ │─────────────┼─────────────┼────────────▶│ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ 更新预约签到状态 │ │ │
|
||||
│ │ │────────────▶│ │ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ 签到成功 │ │ │ │ │
|
||||
│ │◀────────────│ │ │ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ ┌───────┐ ┌───────┐ ┌───────┐ ┌───────┐ ┌───────┐ │
|
||||
│ │ 会员 │ │ 签到 │ │ 预约 │ │ 权益 │ │ 签到 │ │
|
||||
│ │ │ │ 网关 │ │ 服务 │ │ 服务 │ │ 记录 │ │
|
||||
│ └───┬───┘ └───┬───┘ └───┬───┘ └───┬───┘ └───┬───┘ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ 扫码签到 │ │ │ │ │
|
||||
│ │────────────▶│ │ │ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ 查询预约 │ │ │ │
|
||||
│ │ │────────────▶│ │ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ 预约信息 │ │ │ │
|
||||
│ │ │◀────────────│ │ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ 验证签到时间窗口 │ │ │
|
||||
│ │ │─────────────┼────────────▶│ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ 时间窗口验证结果 │ │ │
|
||||
│ │ │◀────────────┼─────────────│ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ 验证权益 │ │ │ │
|
||||
│ │ │─────────────┼────────────▶│ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ 权益状态 │ │ │ │
|
||||
│ │ │◀────────────┼─────────────│ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ 扣减权益 │ │ │ │
|
||||
│ │ │─────────────┼────────────▶│ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ 扣减结果 │ │ │ │
|
||||
│ │ │◀────────────┼─────────────│ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ 创建签到记录│ │ │ │
|
||||
│ │ │─────────────┼─────────────┼────────────▶│ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ 更新预约签到状态 │ │ │
|
||||
│ │ │────────────▶│ │ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ 签到成功 │ │ │ │ │
|
||||
│ │◀────────────│ │ │ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
@@ -559,35 +559,35 @@ public interface CheckinStatisticsService {
|
||||
│ 人脸识别签到流程 │
|
||||
├─────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌───────┐ ┌───────┐ ┌───────┐ ┌───────┐ ┌───────┐ │
|
||||
│ │ 会员 │ │ 人脸 │ │ 人脸 │ │ 签到 │ │ 签到 │ │
|
||||
│ │ │ │ 设备 │ │ 服务 │ │ 验证 │ │ 记录 │ │
|
||||
│ └───┬───┘ └───┬───┘ └───┬───┘ └───┬───┘ └───┬───┘ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ 人脸识别 │ │ │ │ │
|
||||
│ │────────────▶│ │ │ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ 提取特征值 │ │ │ │
|
||||
│ │ │────────────▶│ │ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ │ 匹配会员 │ │ │
|
||||
│ │ │ │─────────────┼────────────▶│ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ │ 匹配结果 │ │ │
|
||||
│ │ │ │◀────────────┼─────────────│ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ 会员ID │ │ │ │
|
||||
│ │ │◀────────────│ │ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ 执行签到流程│ │ │ │
|
||||
│ │ │─────────────┼────────────▶│ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ 签到结果 │ │ │ │
|
||||
│ │ │◀────────────┼─────────────┼─────────────│ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ 签到成功 │ │ │ │ │
|
||||
│ │◀────────────│ │ │ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ ┌───────┐ ┌───────┐ ┌───────┐ ┌───────┐ ┌───────┐ │
|
||||
│ │ 会员 │ │ 人脸 │ │ 人脸 │ │ 签到 │ │ 签到 │ │
|
||||
│ │ │ │ 设备 │ │ 服务 │ │ 验证 │ │ 记录 │ │
|
||||
│ └───┬───┘ └───┬───┘ └───┬───┘ └───┬───┘ └───┬───┘ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ 人脸识别 │ │ │ │ │
|
||||
│ │────────────▶│ │ │ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ 提取特征值 │ │ │ │
|
||||
│ │ │────────────▶│ │ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ │ 匹配会员 │ │ │
|
||||
│ │ │ │─────────────┼────────────▶│ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ │ 匹配结果 │ │ │
|
||||
│ │ │ │◀────────────┼─────────────│ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ 会员ID │ │ │ │
|
||||
│ │ │◀────────────│ │ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ 执行签到流程│ │ │ │
|
||||
│ │ │─────────────┼────────────▶│ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ 签到结果 │ │ │ │
|
||||
│ │ │◀────────────┼─────────────┼─────────────│ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ 签到成功 │ │ │ │ │
|
||||
│ │◀────────────│ │ │ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
@@ -599,41 +599,41 @@ public interface CheckinStatisticsService {
|
||||
│ 教练代签流程 │
|
||||
├─────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌───────┐ ┌───────┐ ┌───────┐ ┌───────┐ ┌───────┐ │
|
||||
│ │ 教练 │ │ 签到 │ │ 预约 │ │ 权益 │ │ 签到 │ │
|
||||
│ │ │ │ 网关 │ │ 服务 │ │ 服务 │ │ 记录 │ │
|
||||
│ └───┬───┘ └───┬───┘ └───┬───┘ └───┬───┘ └───┬───┘ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ 选择会员 │ │ │ │ │
|
||||
│ │────────────▶│ │ │ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ 验证教练身份│ │ │ │
|
||||
│ │ │─────────────┼─────────────┼────────────▶│ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ 身份验证结果│ │ │ │
|
||||
│ │ │◀────────────┼─────────────┼─────────────│ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ 查询会员预约│ │ │ │
|
||||
│ │ │────────────▶│ │ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ 预约列表 │ │ │ │
|
||||
│ │ │◀────────────│ │ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ 选择预约 │ │ │ │ │
|
||||
│ │────────────▶│ │ │ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ 验证签到资格│ │ │ │
|
||||
│ │ │─────────────┼────────────▶│ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ 扣减权益 │ │ │ │
|
||||
│ │ │─────────────┼────────────▶│ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ 创建签到记录│ │ │ │
|
||||
│ │ │─────────────┼─────────────┼────────────▶│ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ 代签成功 │ │ │ │ │
|
||||
│ │◀────────────│ │ │ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ ┌───────┐ ┌───────┐ ┌───────┐ ┌───────┐ ┌───────┐ │
|
||||
│ │ 教练 │ │ 签到 │ │ 预约 │ │ 权益 │ │ 签到 │ │
|
||||
│ │ │ │ 网关 │ │ 服务 │ │ 服务 │ │ 记录 │ │
|
||||
│ └───┬───┘ └───┬───┘ └───┬───┘ └───┬───┘ └───┬───┘ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ 选择会员 │ │ │ │ │
|
||||
│ │────────────▶│ │ │ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ 验证教练身份│ │ │ │
|
||||
│ │ │─────────────┼─────────────┼────────────▶│ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ 身份验证结果│ │ │ │
|
||||
│ │ │◀────────────┼─────────────┼─────────────│ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ 查询会员预约│ │ │ │
|
||||
│ │ │────────────▶│ │ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ 预约列表 │ │ │ │
|
||||
│ │ │◀────────────│ │ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ 选择预约 │ │ │ │ │
|
||||
│ │────────────▶│ │ │ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ 验证签到资格│ │ │ │
|
||||
│ │ │─────────────┼────────────▶│ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ 扣减权益 │ │ │ │
|
||||
│ │ │─────────────┼────────────▶│ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ 创建签到记录│ │ │ │
|
||||
│ │ │─────────────┼─────────────┼────────────▶│ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ 代签成功 │ │ │ │ │
|
||||
│ │◀────────────│ │ │ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
@@ -1547,12 +1547,12 @@ public class CheckinStatisticsServiceImpl implements CheckinStatisticsService {
|
||||
|
||||
### 7.1 签到并发场景分析
|
||||
|
||||
| 场景 | 并发特点 | 处理策略 |
|
||||
|------|---------|---------|
|
||||
| 早高峰入场 | 短时间内大量签到请求 | 本地缓存+异步处理 |
|
||||
| 课程签到窗口 | 集中签到时段 | 预加载+限流 |
|
||||
| 人脸识别匹配 | 计算密集型 | 特征缓存+批量匹配 |
|
||||
| 统计计算 | 数据量大 | 异步任务+增量计算 |
|
||||
| 场景 | 并发特点 | 处理策略 |
|
||||
| ------------ | -------------------- | ----------------- |
|
||||
| 早高峰入场 | 短时间内大量签到请求 | 本地缓存+异步处理 |
|
||||
| 课程签到窗口 | 集中签到时段 | 预加载+限流 |
|
||||
| 人脸识别匹配 | 计算密集型 | 特征缓存+批量匹配 |
|
||||
| 统计计算 | 数据量大 | 异步任务+增量计算 |
|
||||
|
||||
### 7.2 签到限流设计
|
||||
|
||||
@@ -1702,16 +1702,16 @@ public class AsyncCheckinProcessor {
|
||||
### 8.1 缓存策略
|
||||
|
||||
| 数据类型 | 缓存位置 | 过期时间 | 更新策略 |
|
||||
|---------|---------|---------|---------|
|
||||
| 会员信息 | 本地缓存 | 30分钟 | 写时更新 |
|
||||
| 人脸特征 | 本地缓存 | 24小时 | 定时刷新 |
|
||||
| 签到规则 | 本地缓存 | 1小时 | 写时更新 |
|
||||
| 签到统计 | 本地缓存 | 5分钟 | 定时计算 |
|
||||
| 设备状态 | 本地缓存 | 1分钟 | 心跳更新 |
|
||||
| -------- | -------- | -------- | -------- |
|
||||
| 会员信息 | 本地缓存 | 30分钟 | 写时更新 |
|
||||
| 人脸特征 | 本地缓存 | 24小时 | 定时刷新 |
|
||||
| 签到规则 | 本地缓存 | 1小时 | 写时更新 |
|
||||
| 签到统计 | 本地缓存 | 5分钟 | 定时计算 |
|
||||
| 设备状态 | 本地缓存 | 1分钟 | 心跳更新 |
|
||||
|
||||
### 8.2 缓存配置
|
||||
|
||||
```java
|
||||
````java
|
||||
@Configuration
|
||||
public class CheckinCacheConfig {
|
||||
|
||||
@@ -1776,7 +1776,7 @@ public class CheckinStatisticsScheduler {
|
||||
);
|
||||
}
|
||||
}
|
||||
```
|
||||
````
|
||||
|
||||
### 9.2 设备心跳检测
|
||||
|
||||
@@ -1919,51 +1919,51 @@ public class CheckinExceptionHandler {
|
||||
|
||||
### 11.1 枚举定义
|
||||
|
||||
| 枚举类型 | 值 | 说明 |
|
||||
|---------|---|------|
|
||||
| CheckinType | 1 | 入场签到 |
|
||||
| CheckinType | 2 | 课程签到 |
|
||||
| CheckinType | 3 | 私教签到 |
|
||||
| CheckinType | 4 | 活动签到 |
|
||||
| CheckinMethod | 1 | 二维码 |
|
||||
| CheckinMethod | 2 | 人脸识别 |
|
||||
| CheckinMethod | 3 | NFC |
|
||||
| CheckinMethod | 4 | 教练代签 |
|
||||
| CheckinStatus | 1 | 成功 |
|
||||
| CheckinStatus | 2 | 失败 |
|
||||
| CheckinStatus | 3 | 已取消 |
|
||||
| DeviceType | 1 | 人脸识别机 |
|
||||
| DeviceType | 2 | NFC读卡器 |
|
||||
| DeviceType | 3 | 扫码枪 |
|
||||
| DeviceType | 4 | 一体机 |
|
||||
| DeviceStatus | 1 | 在线 |
|
||||
| DeviceStatus | 2 | 离线 |
|
||||
| DeviceStatus | 3 | 维护中 |
|
||||
| FaceStatus | 1 | 正常 |
|
||||
| FaceStatus | 2 | 待更新 |
|
||||
| FaceStatus | 3 | 已禁用 |
|
||||
| 枚举类型 | 值 | 说明 |
|
||||
| ------------- | --- | ---------- |
|
||||
| CheckinType | 1 | 入场签到 |
|
||||
| CheckinType | 2 | 课程签到 |
|
||||
| CheckinType | 3 | 私教签到 |
|
||||
| CheckinType | 4 | 活动签到 |
|
||||
| CheckinMethod | 1 | 二维码 |
|
||||
| CheckinMethod | 2 | 人脸识别 |
|
||||
| CheckinMethod | 3 | NFC |
|
||||
| CheckinMethod | 4 | 教练代签 |
|
||||
| CheckinStatus | 1 | 成功 |
|
||||
| CheckinStatus | 2 | 失败 |
|
||||
| CheckinStatus | 3 | 已取消 |
|
||||
| DeviceType | 1 | 人脸识别机 |
|
||||
| DeviceType | 2 | NFC读卡器 |
|
||||
| DeviceType | 3 | 扫码枪 |
|
||||
| DeviceType | 4 | 一体机 |
|
||||
| DeviceStatus | 1 | 在线 |
|
||||
| DeviceStatus | 2 | 离线 |
|
||||
| DeviceStatus | 3 | 维护中 |
|
||||
| FaceStatus | 1 | 正常 |
|
||||
| FaceStatus | 2 | 待更新 |
|
||||
| FaceStatus | 3 | 已禁用 |
|
||||
|
||||
### 11.2 错误码定义
|
||||
|
||||
| 错误码 | 说明 | 处理建议 |
|
||||
|-------|------|---------|
|
||||
| MEMBER_NOT_FOUND | 会员不存在 | 检查会员ID |
|
||||
| MEMBER_INACTIVE | 会员状态异常 | 联系工作人员 |
|
||||
| BOOKING_NOT_FOUND | 预约不存在 | 检查预约ID |
|
||||
| BOOKING_NOT_MATCH | 预约不匹配 | 确认预约信息 |
|
||||
| BOOKING_NOT_CONFIRMED | 预约未确认 | 等待确认 |
|
||||
| ALREADY_CHECKED | 已签到 | 无需重复签到 |
|
||||
| COURSE_ENDED | 课程已结束 | 无法签到 |
|
||||
| DAILY_LIMIT_EXCEEDED | 签到次数超限 | 明日再来 |
|
||||
| INTERVAL_NOT_MET | 签到间隔不足 | 稍后重试 |
|
||||
| RATE_LIMIT_EXCEEDED | 请求过于频繁 | 稍后重试 |
|
||||
| QUALITY_TOO_LOW | 人脸质量低 | 重新拍照 |
|
||||
| FACE_NOT_MATCHED | 人脸匹配失败 | 重新注册或使用其他方式 |
|
||||
| 错误码 | 说明 | 处理建议 |
|
||||
| --------------------- | ------------ | ---------------------- |
|
||||
| MEMBER_NOT_FOUND | 会员不存在 | 检查会员ID |
|
||||
| MEMBER_INACTIVE | 会员状态异常 | 联系工作人员 |
|
||||
| BOOKING_NOT_FOUND | 预约不存在 | 检查预约ID |
|
||||
| BOOKING_NOT_MATCH | 预约不匹配 | 确认预约信息 |
|
||||
| BOOKING_NOT_CONFIRMED | 预约未确认 | 等待确认 |
|
||||
| ALREADY_CHECKED | 已签到 | 无需重复签到 |
|
||||
| COURSE_ENDED | 课程已结束 | 无法签到 |
|
||||
| DAILY_LIMIT_EXCEEDED | 签到次数超限 | 明日再来 |
|
||||
| INTERVAL_NOT_MET | 签到间隔不足 | 稍后重试 |
|
||||
| RATE_LIMIT_EXCEEDED | 请求过于频繁 | 稍后重试 |
|
||||
| QUALITY_TOO_LOW | 人脸质量低 | 重新拍照 |
|
||||
| FACE_NOT_MATCHED | 人脸匹配失败 | 重新注册或使用其他方式 |
|
||||
|
||||
---
|
||||
|
||||
## 十二、版本历史
|
||||
|
||||
| 版本 | 日期 | 作者 | 变更内容 |
|
||||
|------|------|------|---------|
|
||||
| v1.0 | 2026-02-28 | 张翔 | 初稿 |
|
||||
| 版本 | 日期 | 作者 | 变更内容 |
|
||||
| ---- | ---------- | ---- | -------- |
|
||||
| v1.0 | 2026-02-28 | 张翔 | 初稿 |
|
||||
|
||||
+213
-213
@@ -44,28 +44,28 @@
|
||||
│ 预约模块边界 │
|
||||
├─────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 预约模块内部 │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • 课程管理 • 时段管理 • 预约管理 • 库存管理 │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 预约模块内部 │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • 课程管理 • 时段管理 • 预约管理 • 库存管理 │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 外部依赖 │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • 会员模块 (查询会员权益、扣减权益) │ │
|
||||
│ │ • 教练模块 (查询教练信息、排班) │ │
|
||||
│ │ • 场地模块 (查询场地信息、可用性) │ │
|
||||
│ │ • 消息模块 (发送预约通知) │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 外部依赖 │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • 会员模块 (查询会员权益、扣减权益) │ │
|
||||
│ │ • 教练模块 (查询教练信息、排班) │ │
|
||||
│ │ • 场地模块 (查询场地信息、可用性) │ │
|
||||
│ │ • 消息模块 (发送预约通知) │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 被依赖 │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • 签到模块 (查询预约信息、验证签到资格) │ │
|
||||
│ │ • 财务模块 (查询预约消费记录) │ │
|
||||
│ │ • 数据模块 (预约数据分析) │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 被依赖 │ │
|
||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ • 签到模块 (查询预约信息、验证签到资格) │ │
|
||||
│ │ • 财务模块 (查询预约消费记录) │ │
|
||||
│ │ • 数据模块 (预约数据分析) │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
@@ -81,25 +81,25 @@
|
||||
│ 实体关系图 │
|
||||
├─────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
|
||||
│ │ coach │ │ course │ │ venue │ │
|
||||
│ │ (教练) │ │ (课程) │ │ (场地) │ │
|
||||
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ │
|
||||
│ │ 1:N │ 1:N │ 1:N │
|
||||
│ │ │ │ │
|
||||
│ └──────────────┴──────────────┘ │
|
||||
│ │ 1:N │
|
||||
│ ▼ │
|
||||
│ ┌──────────────────┐ │
|
||||
│ │ booking_slot │ │
|
||||
│ │ (预约时段) │ │
|
||||
│ └────────┬─────────┘ │
|
||||
│ │ 1:N │
|
||||
│ ▼ │
|
||||
│ ┌──────────────────┐ │
|
||||
│ │ booking_record │ │
|
||||
│ │ (预约记录) │ │
|
||||
│ └──────────────────┘ │
|
||||
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
|
||||
│ │ coach │ │ course │ │ venue │ │
|
||||
│ │ (教练) │ │ (课程) │ │ (场地) │ │
|
||||
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ │
|
||||
│ │ 1:N │ 1:N │ 1:N │
|
||||
│ │ │ │ │
|
||||
│ └──────────────┴──────────────┘ │
|
||||
│ │ 1:N │
|
||||
│ ▼ │
|
||||
│ ┌──────────────────┐ │
|
||||
│ │ booking_slot │ │
|
||||
│ │ (预约时段) │ │
|
||||
│ └────────┬─────────┘ │
|
||||
│ │ 1:N │
|
||||
│ ▼ │
|
||||
│ ┌──────────────────┐ │
|
||||
│ │ booking_record │ │
|
||||
│ │ (预约记录) │ │
|
||||
│ └──────────────────┘ │
|
||||
│ │
|
||||
│ 关系说明: │
|
||||
│ • coach (1) ─── (N) booking_slot : 一个教练有多个时段 │
|
||||
@@ -334,75 +334,75 @@ CREATE INDEX idx_schedule_date ON coach_schedule(schedule_date) WHERE deleted_at
|
||||
│ 预约领域模型 │
|
||||
├─────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌───────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ <<Entity>> │ │
|
||||
│ │ BookingSlot │ │
|
||||
│ ├───────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ - id: Long │ │
|
||||
│ │ - tenantId: Long │ │
|
||||
│ │ - storeId: Long │ │
|
||||
│ │ - resourceType: ResourceType │ │
|
||||
│ │ - resourceId: Long │ │
|
||||
│ │ - coachId: Long │ │
|
||||
│ │ - venueId: Long │ │
|
||||
│ │ - startTime: LocalDateTime │ │
|
||||
│ │ - endTime: LocalDateTime │ │
|
||||
│ │ - capacity: Integer │ │
|
||||
│ │ - bookedCount: Integer │ │
|
||||
│ │ - waitlistCount: Integer │ │
|
||||
│ │ - status: SlotStatus │ │
|
||||
│ │ - version: Integer │ │
|
||||
│ ├───────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ + hasCapacity(): Boolean │ │
|
||||
│ │ + getRemainCapacity(): Integer │ │
|
||||
│ │ + canBook(): Boolean │ │
|
||||
│ │ + book(): void │ │
|
||||
│ │ + cancel(): void │ │
|
||||
│ │ + isExpired(): Boolean │ │
|
||||
│ │ + isFull(): Boolean │ │
|
||||
│ │ + addToWaitlist(): void │ │
|
||||
│ │ + removeFromWaitlist(): void │ │
|
||||
│ └───────────────────────────────────────────────────────────────────┘ │
|
||||
│ │ │
|
||||
│ │ 1:N │
|
||||
│ ▼ │
|
||||
│ ┌────────────────────────────┐ ┌────────────────────────────┐ │
|
||||
│ │ <<Entity>> │ │ <<Entity>> │ │
|
||||
│ │ BookingRecord │ │ BookingWaitlist │ │
|
||||
│ ├────────────────────────────┤ ├────────────────────────────┤ │
|
||||
│ │ - id: Long │ │ - id: Long │ │
|
||||
│ │ - memberId: Long │ │ - memberId: Long │ │
|
||||
│ │ - slotId: Long │ │ - slotId: Long │ │
|
||||
│ │ - bookingNo: String │ │ - queueNo: Integer │ │
|
||||
│ │ - status: BookingStatus │ │ - status: WaitlistStatus │ │
|
||||
│ │ - priceType: PriceType │ │ - expireAt: LocalDateTime │ │
|
||||
│ │ - priceValue: BigDecimal │ ├────────────────────────────┤ │
|
||||
│ │ - checkinStatus: CheckinSt │ │ + isExpired(): Boolean │ │
|
||||
│ ├────────────────────────────┤ │ + convert(): void │ │
|
||||
│ │ + canCancel(): Boolean │ └────────────────────────────┘ │
|
||||
│ ┌───────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ <<Entity>> │ │
|
||||
│ │ BookingSlot │ │
|
||||
│ ├───────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ - id: Long │ │
|
||||
│ │ - tenantId: Long │ │
|
||||
│ │ - storeId: Long │ │
|
||||
│ │ - resourceType: ResourceType │ │
|
||||
│ │ - resourceId: Long │ │
|
||||
│ │ - coachId: Long │ │
|
||||
│ │ - venueId: Long │ │
|
||||
│ │ - startTime: LocalDateTime │ │
|
||||
│ │ - endTime: LocalDateTime │ │
|
||||
│ │ - capacity: Integer │ │
|
||||
│ │ - bookedCount: Integer │ │
|
||||
│ │ - waitlistCount: Integer │ │
|
||||
│ │ - status: SlotStatus │ │
|
||||
│ │ - version: Integer │ │
|
||||
│ ├───────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ + hasCapacity(): Boolean │ │
|
||||
│ │ + getRemainCapacity(): Integer │ │
|
||||
│ │ + canBook(): Boolean │ │
|
||||
│ │ + book(): void │ │
|
||||
│ │ + cancel(): void │ │
|
||||
│ │ + isExpired(): Boolean │ │
|
||||
│ │ + isFull(): Boolean │ │
|
||||
│ │ + addToWaitlist(): void │ │
|
||||
│ │ + removeFromWaitlist(): void │ │
|
||||
│ └───────────────────────────────────────────────────────────────────┘ │
|
||||
│ │ │
|
||||
│ │ 1:N │
|
||||
│ ▼ │
|
||||
│ ┌────────────────────────────┐ ┌────────────────────────────┐ │
|
||||
│ │ <<Entity>> │ │ <<Entity>> │ │
|
||||
│ │ BookingRecord │ │ BookingWaitlist │ │
|
||||
│ ├────────────────────────────┤ ├────────────────────────────┤ │
|
||||
│ │ - id: Long │ │ - id: Long │ │
|
||||
│ │ - memberId: Long │ │ - memberId: Long │ │
|
||||
│ │ - slotId: Long │ │ - slotId: Long │ │
|
||||
│ │ - bookingNo: String │ │ - queueNo: Integer │ │
|
||||
│ │ - status: BookingStatus │ │ - status: WaitlistStatus │ │
|
||||
│ │ - priceType: PriceType │ │ - expireAt: LocalDateTime │ │
|
||||
│ │ - priceValue: BigDecimal │ ├────────────────────────────┤ │
|
||||
│ │ - checkinStatus: CheckinSt │ │ + isExpired(): Boolean │ │
|
||||
│ ├────────────────────────────┤ │ + convert(): void │ │
|
||||
│ │ + canCancel(): Boolean │ └────────────────────────────┘ │
|
||||
│ │ + cancel(): void │ │
|
||||
│ │ + checkin(): void │ │
|
||||
│ │ + isCheckinable(): Boolean │ │
|
||||
│ └────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌────────────────────────────┐ ┌────────────────────────────┐ │
|
||||
│ │ <<ValueObject>> │ │ <<ValueObject>> │ │
|
||||
│ │ ResourceType │ │ SlotStatus │ │
|
||||
│ ├────────────────────────────┤ ├────────────────────────────┤ │
|
||||
│ │ GROUP_CLASS(1, "团课") │ │ AVAILABLE(1, "可预约") │ │
|
||||
│ │ PRIVATE(2, "私教") │ │ FULL(2, "已满") │ │
|
||||
│ │ VENUE(3, "场地") │ │ CANCELLED(3, "已取消") │ │
|
||||
│ │ ONLINE(4, "线上") │ │ ENDED(4, "已结束") │ │
|
||||
│ └────────────────────────────┘ └────────────────────────────┘ │
|
||||
│ ┌────────────────────────────┐ ┌────────────────────────────┐ │
|
||||
│ │ <<ValueObject>> │ │ <<ValueObject>> │ │
|
||||
│ │ ResourceType │ │ SlotStatus │ │
|
||||
│ ├────────────────────────────┤ ├────────────────────────────┤ │
|
||||
│ │ GROUP_CLASS(1, "团课") │ │ AVAILABLE(1, "可预约") │ │
|
||||
│ │ PRIVATE(2, "私教") │ │ FULL(2, "已满") │ │
|
||||
│ │ VENUE(3, "场地") │ │ CANCELLED(3, "已取消") │ │
|
||||
│ │ ONLINE(4, "线上") │ │ ENDED(4, "已结束") │ │
|
||||
│ └────────────────────────────┘ └────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌────────────────────────────┐ ┌────────────────────────────┐ │
|
||||
│ │ <<ValueObject>> │ │ <<ValueObject>> │ │
|
||||
│ │ BookingStatus │ │ PriceType │ │
|
||||
│ ├────────────────────────────┤ ├────────────────────────────┤ │
|
||||
│ │ BOOKED(1, "已预约") │ │ TIMES(1, "扣次") │ │
|
||||
│ │ CANCELLED(2, "已取消") │ │ DURATION(2, "扣时长") │ │
|
||||
│ │ COMPLETED(3, "已完成") │ │ AMOUNT(3, "扣金额") │ │
|
||||
│ │ EXPIRED(4, "已过期") │ └────────────────────────────┘ │
|
||||
│ ┌────────────────────────────┐ ┌────────────────────────────┐ │
|
||||
│ │ <<ValueObject>> │ │ <<ValueObject>> │ │
|
||||
│ │ BookingStatus │ │ PriceType │ │
|
||||
│ ├────────────────────────────┤ ├────────────────────────────┤ │
|
||||
│ │ BOOKED(1, "已预约") │ │ TIMES(1, "扣次") │ │
|
||||
│ │ CANCELLED(2, "已取消") │ │ DURATION(2, "扣时长") │ │
|
||||
│ │ COMPLETED(3, "已完成") │ │ AMOUNT(3, "扣金额") │ │
|
||||
│ │ EXPIRED(4, "已过期") │ └────────────────────────────┘ │
|
||||
│ └────────────────────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
@@ -415,40 +415,40 @@ CREATE INDEX idx_schedule_date ON coach_schedule(schedule_date) WHERE deleted_at
|
||||
│ 领域服务设计 │
|
||||
├─────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌───────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ <<DomainService>> │ │
|
||||
│ │ BookingDomainService │ │
|
||||
│ ├───────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ + createBooking(command: CreateBookingCommand): BookingRecord │ │
|
||||
│ │ + cancelBooking(bookingId: Long, reason: String): void │ │
|
||||
│ │ + checkin(bookingId: Long): void │ │
|
||||
│ │ + addToWaitlist(memberId: Long, slotId: Long): void │ │
|
||||
│ │ + processWaitlist(slotId: Long): void │ │
|
||||
│ │ + validateBooking(memberId: Long, slotId: Long): void │ │
|
||||
│ └───────────────────────────────────────────────────────────────────┘ │
|
||||
│ ┌───────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ <<DomainService>> │ │
|
||||
│ │ BookingDomainService │ │
|
||||
│ ├───────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ + createBooking(command: CreateBookingCommand): BookingRecord │ │
|
||||
│ │ + cancelBooking(bookingId: Long, reason: String): void │ │
|
||||
│ │ + checkin(bookingId: Long): void │ │
|
||||
│ │ + addToWaitlist(memberId: Long, slotId: Long): void │ │
|
||||
│ │ + processWaitlist(slotId: Long): void │ │
|
||||
│ │ + validateBooking(memberId: Long, slotId: Long): void │ │
|
||||
│ └───────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌───────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ <<DomainService>> │ │
|
||||
│ │ SlotDomainService │ │
|
||||
│ ├───────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ + createSlot(command: CreateSlotCommand): BookingSlot │ │
|
||||
│ │ + batchCreateSlots(command: BatchSlotCommand): List<Slot> │ │
|
||||
│ │ + updateSlot(slotId: Long, command: UpdateSlotCommand): void │ │
|
||||
│ │ + cancelSlot(slotId: Long, reason: String): void │ │
|
||||
│ │ + getAvailableSlots(query: SlotQuery): List<BookingSlot> │ │
|
||||
│ │ + incrementBookedCount(slotId: Long): Boolean │ │
|
||||
│ │ + decrementBookedCount(slotId: Long): void │ │
|
||||
│ └───────────────────────────────────────────────────────────────────┘ │
|
||||
│ ┌───────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ <<DomainService>> │ │
|
||||
│ │ SlotDomainService │ │
|
||||
│ ├───────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ + createSlot(command: CreateSlotCommand): BookingSlot │ │
|
||||
│ │ + batchCreateSlots(command: BatchSlotCommand): List<Slot> │ │
|
||||
│ │ + updateSlot(slotId: Long, command: UpdateSlotCommand): void │ │
|
||||
│ │ + cancelSlot(slotId: Long, reason: String): void │ │
|
||||
│ │ + getAvailableSlots(query: SlotQuery): List<BookingSlot> │ │
|
||||
│ │ + incrementBookedCount(slotId: Long): Boolean │ │
|
||||
│ │ + decrementBookedCount(slotId: Long): void │ │
|
||||
│ └───────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌───────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ <<DomainService>> │ │
|
||||
│ │ InventoryDomainService │ │
|
||||
│ ├───────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ + checkInventory(slotId: Long): Boolean │ │
|
||||
│ │ + reserveInventory(slotId: Long, count: Integer): Boolean │ │
|
||||
│ │ + releaseInventory(slotId: Long, count: Integer): void │ │
|
||||
│ │ + preloadInventory(slotIds: List<Long>): void │ │
|
||||
│ └───────────────────────────────────────────────────────────────────┘ │
|
||||
│ ┌───────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ <<DomainService>> │ │
|
||||
│ │ InventoryDomainService │ │
|
||||
│ ├───────────────────────────────────────────────────────────────────┤ │
|
||||
│ │ + checkInventory(slotId: Long): Boolean │ │
|
||||
│ │ + reserveInventory(slotId: Long, count: Integer): Boolean │ │
|
||||
│ │ + releaseInventory(slotId: Long, count: Integer): void │ │
|
||||
│ │ + preloadInventory(slotIds: List<Long>): void │ │
|
||||
│ └───────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
@@ -464,50 +464,50 @@ CREATE INDEX idx_schedule_date ON coach_schedule(schedule_date) WHERE deleted_at
|
||||
│ 团课预约流程 │
|
||||
├─────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ 会员端 API层 BookingService BenefitService 数据层 │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ 1.选择课程 │ │ │ │ │
|
||||
│ │─────────▶│ │ │ │ │
|
||||
│ │ │ 2.查询时段 │ │ │ │
|
||||
│ │ │─────────────▶│ │ │ │
|
||||
│ │ │ │ 3.查询可预约时段 │ │ │
|
||||
│ │ │ │───────────────────────────────▶│ │
|
||||
│ │ │ │◀───────────────────────────────│ │
|
||||
│ │◀─────────│ 返回时段列表 │ │ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ 4.提交预约 │ │ │ │ │
|
||||
│ │─────────▶│ │ │ │ │
|
||||
│ │ │ 5.创建预约 │ │ │ │
|
||||
│ │ │─────────────▶│ │ │ │
|
||||
│ │ │ │ 6.校验时段 │ │ │
|
||||
│ │ │ │───────────────────────────────▶│ │
|
||||
│ │ │ │◀───────────────────────────────│ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ │ 7.校验会员状态 │ │ │
|
||||
│ │ │ │───────────────────────────────▶│ │
|
||||
│ │ │ │◀───────────────────────────────│ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ │ 8.检查库存(原子)│ │ │
|
||||
│ │ │ │───────────────────────────────▶│ │
|
||||
│ │ │ │◀───────────────────────────────│ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ │ 9.扣减权益 │ │ │
|
||||
│ │ │ │────────────────▶│ │ │
|
||||
│ │ │ │ │─────────────▶│ │
|
||||
│ │ │ │ │◀─────────────│ │
|
||||
│ │ │ │◀────────────────│ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ │ 10.创建预约记录 │ │ │
|
||||
│ │ │ │───────────────────────────────▶│ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ │ 11.增加预约人数 │ │ │
|
||||
│ │ │ │───────────────────────────────▶│ │
|
||||
│ │ │ │◀───────────────────────────────│ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ │ 12.发送预约通知 │ │ │
|
||||
│ │◀─────────│◀─────────────│ │ │ │
|
||||
│ │ 返回预约成功│ │ │ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ 会员端 API层 BookingService BenefitService 数据层 │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ 1.选择课程 │ │ │ │ │
|
||||
│ │─────────▶│ │ │ │ │
|
||||
│ │ │ 2.查询时段 │ │ │ │
|
||||
│ │ │─────────────▶│ │ │ │
|
||||
│ │ │ │ 3.查询可预约时段 │ │ │
|
||||
│ │ │ │───────────────────────────────▶│ │
|
||||
│ │ │ │◀───────────────────────────────│ │
|
||||
│ │◀─────────│ 返回时段列表 │ │ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ 4.提交预约 │ │ │ │ │
|
||||
│ │─────────▶│ │ │ │ │
|
||||
│ │ │ 5.创建预约 │ │ │ │
|
||||
│ │ │─────────────▶│ │ │ │
|
||||
│ │ │ │ 6.校验时段 │ │ │
|
||||
│ │ │ │───────────────────────────────▶│ │
|
||||
│ │ │ │◀───────────────────────────────│ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ │ 7.校验会员状态 │ │ │
|
||||
│ │ │ │───────────────────────────────▶│ │
|
||||
│ │ │ │◀───────────────────────────────│ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ │ 8.检查库存(原子)│ │ │
|
||||
│ │ │ │───────────────────────────────▶│ │
|
||||
│ │ │ │◀───────────────────────────────│ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ │ 9.扣减权益 │ │ │
|
||||
│ │ │ │────────────────▶│ │ │
|
||||
│ │ │ │ │─────────────▶│ │
|
||||
│ │ │ │ │◀─────────────│ │
|
||||
│ │ │ │◀────────────────│ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ │ 10.创建预约记录 │ │ │
|
||||
│ │ │ │───────────────────────────────▶│ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ │ 11.增加预约人数 │ │ │
|
||||
│ │ │ │───────────────────────────────▶│ │
|
||||
│ │ │ │◀───────────────────────────────│ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ │ 12.发送预约通知 │ │ │
|
||||
│ │◀─────────│◀─────────────│ │ │ │
|
||||
│ │ 返回预约成功│ │ │ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
@@ -519,41 +519,41 @@ CREATE INDEX idx_schedule_date ON coach_schedule(schedule_date) WHERE deleted_at
|
||||
│ 取消预约流程 │
|
||||
├─────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ 会员端 API层 BookingService BenefitService 数据层 │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ 1.请求取消 │ │ │ │ │
|
||||
│ │─────────▶│ │ │ │ │
|
||||
│ │ │ 2.查询预约 │ │ │ │
|
||||
│ │ │─────────────▶│ │ │ │
|
||||
│ │ │ │───────────────────────────────▶│ │
|
||||
│ │ │ │◀───────────────────────────────│ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ │ 3.校验可取消 │ │ │
|
||||
│ │ │ │ - 状态检查 │ │ │
|
||||
│ │ │ │ - 时间检查 │ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ │ 4.计算退款金额 │ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ │ 5.退还权益 │ │ │
|
||||
│ │ │ │────────────────▶│ │ │
|
||||
│ │ │ │ │─────────────▶│ │
|
||||
│ │ │ │ │◀─────────────│ │
|
||||
│ │ │ │◀────────────────│ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ │ 6.更新预约状态 │ │ │
|
||||
│ │ │ │───────────────────────────────▶│ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ │ 7.减少预约人数 │ │ │
|
||||
│ │ │ │───────────────────────────────▶│ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ │ 8.处理候补队列 │ │ │
|
||||
│ │ │ │───────────────────────────────▶│ │
|
||||
│ │ │ │◀───────────────────────────────│ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ │ 9.发送取消通知 │ │ │
|
||||
│ │◀─────────│◀─────────────│ │ │ │
|
||||
│ │ 返回取消成功│ │ │ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ 会员端 API层 BookingService BenefitService 数据层 │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ 1.请求取消 │ │ │ │ │
|
||||
│ │─────────▶│ │ │ │ │
|
||||
│ │ │ 2.查询预约 │ │ │ │
|
||||
│ │ │─────────────▶│ │ │ │
|
||||
│ │ │ │───────────────────────────────▶│ │
|
||||
│ │ │ │◀───────────────────────────────│ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ │ 3.校验可取消 │ │ │
|
||||
│ │ │ │ - 状态检查 │ │ │
|
||||
│ │ │ │ - 时间检查 │ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ │ 4.计算退款金额 │ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ │ 5.退还权益 │ │ │
|
||||
│ │ │ │────────────────▶│ │ │
|
||||
│ │ │ │ │─────────────▶│ │
|
||||
│ │ │ │ │◀─────────────│ │
|
||||
│ │ │ │◀────────────────│ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ │ 6.更新预约状态 │ │ │
|
||||
│ │ │ │───────────────────────────────▶│ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ │ 7.减少预约人数 │ │ │
|
||||
│ │ │ │───────────────────────────────▶│ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ │ 8.处理候补队列 │ │ │
|
||||
│ │ │ │───────────────────────────────▶│ │
|
||||
│ │ │ │◀───────────────────────────────│ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ │ 9.发送取消通知 │ │ │
|
||||
│ │◀─────────│◀─────────────│ │ │ │
|
||||
│ │ 返回取消成功│ │ │ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user