完成模块4,4.1基础数据统计的部分功能

This commit is contained in:
2026-06-06 15:19:40 +08:00
parent 8af444b7ee
commit 8958ffaa9e
20 changed files with 2723 additions and 200 deletions
+848
View File
@@ -0,0 +1,848 @@
# 数据统计模块 API 文档
> 模块:gym-dataCount
> 版本:1.0.0
> 更新日期:2026-06-06
## 概述
数据统计模块提供会员数据统计、预约数据统计和数据导出功能,支持按日期查询、日期范围查询和汇总统计。
---
## 基础信息
- **Base URL**: `/api/stats`
- **Content-Type**: `application/json`
- **响应格式**: JSON
---
## 1. 会员数据统计
### 1.1 获取指定日期的会员统计
获取某一天的会员数据统计信息。
**请求**
```http
GET /api/stats/member/date/{date}
```
**路径参数**
| 参数 | 类型 | 必填 | 说明 |
|-----|------|-----|------|
| date | string | 是 | 统计日期,格式:yyyy-MM-dd |
**请求示例**
```bash
curl -X GET "http://localhost:8080/api/stats/member/date/2026-06-01"
```
**响应示例**
```json
{
"date": "2026-06-01",
"newMembers": 5,
"activeMembers": 0,
"retainedMembers": 0,
"totalMembers": 19,
"maleMembers": 10,
"femaleMembers": 9,
"cardPurchaseCount": 19,
"averageAge": 29.5
}
```
**响应字段说明**
| 字段 | 类型 | 说明 |
|-----|------|------|
| date | string | 统计日期 |
| newMembers | integer | 当日新增会员数 |
| activeMembers | integer | 当日活跃会员数(有会员卡操作的会员) |
| retainedMembers | integer | 留存会员数 |
| totalMembers | integer | 总会员数(累计) |
| maleMembers | integer | 男性会员总数 |
| femaleMembers | integer | 女性会员总数 |
| cardPurchaseCount | integer | 当日购卡人数 |
| averageAge | number | 会员平均年龄 |
---
### 1.2 获取日期范围内的会员统计列表
获取指定日期范围内每天的会员统计数据。
**请求**
```http
GET /api/stats/member/range?startDate=2026-06-01&endDate=2026-06-05
```
**查询参数**
| 参数 | 类型 | 必填 | 说明 |
|-----|------|-----|------|
| startDate | string | 是 | 开始日期,格式:yyyy-MM-dd |
| endDate | string | 是 | 结束日期,格式:yyyy-MM-dd |
**请求示例**
```bash
curl -X GET "http://localhost:8080/api/stats/member/range?startDate=2026-06-01&endDate=2026-06-03"
```
**响应示例**
```json
[
{
"date": "2026-06-01",
"newMembers": 5,
"activeMembers": 0,
"totalMembers": 19,
"maleMembers": 10,
"femaleMembers": 9,
"cardPurchaseCount": 19,
"averageAge": 29.5
},
{
"date": "2026-06-02",
"newMembers": 4,
"activeMembers": 0,
"totalMembers": 19,
"maleMembers": 10,
"femaleMembers": 9,
"cardPurchaseCount": 19,
"averageAge": 29.5
},
{
"date": "2026-06-03",
"newMembers": 3,
"activeMembers": 0,
"totalMembers": 19,
"maleMembers": 10,
"femaleMembers": 9,
"cardPurchaseCount": 19,
"averageAge": 29.5
}
]
```
---
### 1.3 获取会员统计汇总
获取指定日期范围内的会员数据汇总统计。
**请求**
```http
GET /api/stats/member/summary?startDate=2026-06-01&endDate=2026-06-30
```
**查询参数**
| 参数 | 类型 | 必填 | 说明 |
|-----|------|-----|------|
| startDate | string | 是 | 开始日期,格式:yyyy-MM-dd |
| endDate | string | 是 | 结束日期,格式:yyyy-MM-dd |
**请求示例**
```bash
curl -X GET "http://localhost:8080/api/stats/member/summary?startDate=2026-06-01&endDate=2026-06-06"
```
**响应示例**
```json
{
"startDate": "2026-06-01",
"endDate": "2026-06-06",
"newMembers": 19,
"activeMembers": 0,
"totalMembers": 19,
"maleMembers": 10,
"femaleMembers": 9,
"cardPurchaseCount": 19,
"averageAge": 29.5
}
```
---
## 2. 预约数据统计
### 2.1 获取指定日期的预约统计
获取某一天的团课预约数据统计信息。
**请求**
```http
GET /api/stats/booking/date/{date}
```
**路径参数**
| 参数 | 类型 | 必填 | 说明 |
|-----|------|-----|------|
| date | string | 是 | 统计日期,格式:yyyy-MM-dd |
**请求示例**
```bash
curl -X GET "http://localhost:8080/api/stats/booking/date/2026-06-01"
```
**响应示例**
```json
{
"date": "2026-06-01",
"totalBookings": 32,
"cancelledBookings": 5,
"attendedBookings": 27,
"bookingSuccessRate": 0.0,
"cancellationRate": 15.63,
"attendanceRate": 84.38,
"popularCourseName": "燃脂单车",
"popularCourseCount": 19,
"totalCourses": 3,
"fullCourses": 1
}
```
**响应字段说明**
| 字段 | 类型 | 说明 |
|-----|------|------|
| date | string | 统计日期 |
| totalBookings | integer | 预约总数 |
| cancelledBookings | integer | 取消预约数 |
| attendedBookings | integer | 实际到场数 |
| bookingSuccessRate | number | 预约成功率(保留) |
| cancellationRate | number | 取消率(百分比) |
| attendanceRate | number | 到场率(百分比) |
| popularCourseName | string | 最热门课程名称 |
| popularCourseCount | integer | 热门课程预约数 |
| totalCourses | integer | 当日团课总数 |
| fullCourses | integer | 满员课程数 |
---
### 2.2 获取日期范围内的预约统计列表
获取指定日期范围内每天的预约统计数据。
**请求**
```http
GET /api/stats/booking/range?startDate=2026-06-01&endDate=2026-06-05
```
**查询参数**
| 参数 | 类型 | 必填 | 说明 |
|-----|------|-----|------|
| startDate | string | 是 | 开始日期,格式:yyyy-MM-dd |
| endDate | string | 是 | 结束日期,格式:yyyy-MM-dd |
**请求示例**
```bash
curl -X GET "http://localhost:8080/api/stats/booking/range?startDate=2026-06-01&endDate=2026-06-03"
```
**响应示例**
```json
[
{
"date": "2026-06-01",
"totalBookings": 32,
"cancelledBookings": 5,
"attendedBookings": 27,
"cancellationRate": 15.63,
"attendanceRate": 84.38,
"popularCourseName": "燃脂单车",
"popularCourseCount": 19,
"totalCourses": 3,
"fullCourses": 1
},
{
"date": "2026-06-02",
"totalBookings": 30,
"cancelledBookings": 3,
"attendedBookings": 27,
"cancellationRate": 10.00,
"attendanceRate": 90.00,
"popularCourseName": "流瑜伽",
"popularCourseCount": 10,
"totalCourses": 3,
"fullCourses": 0
},
{
"date": "2026-06-03",
"totalBookings": 35,
"cancelledBookings": 4,
"attendedBookings": 31,
"cancellationRate": 11.43,
"attendanceRate": 88.57,
"popularCourseName": "哈他瑜伽",
"popularCourseCount": 12,
"totalCourses": 3,
"fullCourses": 2
}
]
```
---
### 2.3 获取预约统计汇总
获取指定日期范围内的预约数据汇总统计。
**请求**
```http
GET /api/stats/booking/summary?startDate=2026-06-01&endDate=2026-06-30
```
**查询参数**
| 参数 | 类型 | 必填 | 说明 |
|-----|------|-----|------|
| startDate | string | 是 | 开始日期,格式:yyyy-MM-dd |
| endDate | string | 是 | 结束日期,格式:yyyy-MM-dd |
**请求示例**
```bash
curl -X GET "http://localhost:8080/api/stats/booking/summary?startDate=2026-06-01&endDate=2026-06-06"
```
**响应示例**
```json
{
"startDate": "2026-06-01",
"endDate": "2026-06-06",
"totalBookings": 172,
"cancelledBookings": 16,
"attendedBookings": 156,
"cancellationRate": 9.30,
"attendanceRate": 90.70
}
```
---
## 3. 数据导出
### 3.1 导出会员统计数据
导出指定日期范围内的会员统计数据为CSV文件。
**请求**
```http
GET /api/stats/export/member?startDate=2026-06-01&endDate=2026-06-30
```
**查询参数**
| 参数 | 类型 | 必填 | 说明 |
|-----|------|-----|------|
| startDate | string | 是 | 开始日期,格式:yyyy-MM-dd |
| endDate | string | 是 | 结束日期,格式:yyyy-MM-dd |
**请求示例**
```bash
curl -X GET "http://localhost:8080/api/stats/export/member?startDate=2026-06-01&endDate=2026-06-03" \
-H "Accept: text/csv" \
--output member_stats.csv
```
**响应**
- **Content-Type**: `text/csv; charset=UTF-8`
- **Content-Disposition**: `attachment; filename=member_statistics_2026-06-01_2026-06-03.csv`
**CSV格式示例**
```csv
统计日期,新增会员数,活跃会员数,总会员数,男性会员数,女性会员数,购卡人数,平均年龄
2026-06-01,5,0,19,10,9,19,29.5
2026-06-02,4,0,19,10,9,19,29.5
2026-06-03,3,0,19,10,9,19,29.5
```
---
### 3.2 导出预约统计数据
导出指定日期范围内的预约统计数据为CSV文件。
**请求**
```http
GET /api/stats/export/booking?startDate=2026-06-01&endDate=2026-06-30
```
**查询参数**
| 参数 | 类型 | 必填 | 说明 |
|-----|------|-----|------|
| startDate | string | 是 | 开始日期,格式:yyyy-MM-dd |
| endDate | string | 是 | 结束日期,格式:yyyy-MM-dd |
**请求示例**
```bash
curl -X GET "http://localhost:8080/api/stats/export/booking?startDate=2026-06-01&endDate=2026-06-03" \
-H "Accept: text/csv" \
--output booking_stats.csv
```
**响应**
- **Content-Type**: `text/csv; charset=UTF-8`
- **Content-Disposition**: `attachment; filename=booking_statistics_2026-06-01_2026-06-03.csv`
**CSV格式示例**
```csv
统计日期,预约总数,取消预约数,实际到场数,取消率(%),到场率(%),热门课程,热门课程预约数,团课总数,满员课程数
2026-06-01,32,5,27,15.63,84.38,燃脂单车,19,3,1
2026-06-02,30,3,27,10.00,90.00,流瑜伽,10,3,0
2026-06-03,35,4,31,11.43,88.57,哈他瑜伽,12,3,2
```
---
### 3.3 导出全部统计数据
导出指定日期范围内的会员和预约统计数据为CSV文件。
**请求**
```http
GET /api/stats/export/all?startDate=2026-06-01&endDate=2026-06-30
```
**查询参数**
| 参数 | 类型 | 必填 | 说明 |
|-----|------|-----|------|
| startDate | string | 是 | 开始日期,格式:yyyy-MM-dd |
| endDate | string | 是 | 结束日期,格式:yyyy-MM-dd |
**请求示例**
```bash
curl -X GET "http://localhost:8080/api/stats/export/all?startDate=2026-06-01&endDate=2026-06-03" \
-H "Accept: text/csv" \
--output all_stats.csv
```
**响应**
- **Content-Type**: `text/csv; charset=UTF-8`
- **Content-Disposition**: `attachment; filename=all_statistics_2026-06-01_2026-06-03.csv`
**CSV格式示例**
```csv
=== 会员数据统计 ===
统计日期,新增会员数,活跃会员数,总会员数,男性会员数,女性会员数,购卡人数,平均年龄
2026-06-01,5,0,19,10,9,19,29.5
2026-06-02,4,0,19,10,9,19,29.5
2026-06-03,3,0,19,10,9,19,29.5
=== 预约数据统计 ===
统计日期,预约总数,取消预约数,实际到场数,取消率(%),到场率(%),热门课程,热门课程预约数,团课总数,满员课程数
2026-06-01,32,5,27,15.63,84.38,燃脂单车,19,3,1
2026-06-02,30,3,27,10.00,90.00,流瑜伽,10,3,0
2026-06-03,35,4,31,11.43,88.57,哈他瑜伽,12,3,2
```
---
## 4. 错误响应
所有接口在发生错误时返回统一的错误格式:
```json
{
"success": false,
"message": "错误描述信息"
}
```
**常见错误码**
| HTTP状态码 | 说明 |
|-----------|------|
| 400 Bad Request | 参数格式错误或缺少必填参数 |
| 404 Not Found | 指定日期的数据不存在 |
| 500 Internal Server Error | 服务器内部错误 |
---
## 5. 定时任务
模块内置以下定时任务,自动计算统计数据并缓存到Redis:
| 任务名称 | 执行时间 | 说明 |
|---------|---------|------|
| 每日统计 | 每日凌晨1点 | 计算前一天的会员和预约统计 |
| 每周汇总 | 每周一凌晨2点 | 计算上周的汇总统计 |
| 每月汇总 | 每月1号凌晨3点 | 计算上月的汇总统计 |
**缓存策略**
- 缓存键前缀:`stats:member:``stats:booking:`
- 缓存过期时间:3600秒(1小时)
- 每日定时任务会自动刷新缓存
---
## 6. 数据来源
统计数据来源于以下数据表:
| 统计类型 | 数据表 | 说明 |
|---------|-------|------|
| 会员统计 | `member_user` | 会员基本信息表 |
| 会员卡统计 | `member_card_record` | 会员卡记录表 |
| 预约统计 | `group_course_booking` | 团课预约记录表 |
| 课程统计 | `group_course` | 团课课程表 |
---
## 7. 技术实现
- **框架**: Spring WebFlux(响应式编程)
- **数据库访问**: Spring Data R2DBC
- **缓存**: RedisReactiveRedisTemplate
- **API文档**: OpenAPI 3.0 / Swagger
- **导出格式**: CSV
---
## 附录:接口列表汇总
| 方法 | 路径 | 说明 |
|-----|------|------|
| GET | `/api/stats/member/date/{date}` | 获取指定日期会员统计 |
| GET | `/api/stats/member/range` | 获取日期范围会员统计列表 |
| GET | `/api/stats/member/summary` | 获取会员统计汇总 |
| GET | `/api/stats/booking/date/{date}` | 获取指定日期预约统计 |
| GET | `/api/stats/booking/range` | 获取日期范围预约统计列表 |
| GET | `/api/stats/booking/summary` | 获取预约统计汇总 |
| GET | `/api/stats/export/member` | 导出会员统计CSV |
| GET | `/api/stats/export/booking` | 导出预约统计CSV |
| GET | `/api/stats/export/all` | 导出全部统计CSV |
---
## 8. 测试指南
### 8.1 测试数据说明
数据库已预置测试数据,日期范围为 **2026-06-01 至 2026-06-10**
#### 会员数据分布
| 日期 | 新增会员数 | 男性会员 | 女性会员 |
|------|-----------|---------|---------|
| 2026-06-01 | 5 | 3 | 2 |
| 2026-06-02 | 4 | 2 | 2 |
| 2026-06-03 | 3 | 1 | 2 |
| 2026-06-04 | 2 | 1 | 1 |
| 2026-06-05 | 3 | 2 | 1 |
| 2026-06-06 | 2 | 1 | 1 |
| **合计** | **19** | **10** | **9** |
#### 预约数据分布
| 日期 | 预约总数 | 取消预约 | 实际到场 | 满员课程数 |
|------|---------|---------|---------|-----------|
| 2026-06-01 | 32 | 5 | 27 | 1 |
| 2026-06-02 | 30 | 3 | 27 | 0 |
| 2026-06-03 | 35 | 4 | 31 | 2 |
| 2026-06-04 | 28 | 2 | 26 | 1 |
| 2026-06-05 | 25 | 1 | 24 | 0 |
| 2026-06-06 | 22 | 1 | 21 | 0 |
---
### 8.2 测试用例
#### 8.2.1 会员数据统计
**测试1:获取单日会员统计**
```bash
curl -X GET "http://localhost:8080/api/stats/member/date/2026-06-01"
```
**预期结果**
```json
{
"date": "2026-06-01",
"newMembers": 5,
"activeMembers": 0,
"retainedMembers": 0,
"totalMembers": 19,
"maleMembers": 10,
"femaleMembers": 9,
"cardPurchaseCount": 19,
"averageAge": 29.5
}
```
---
**测试2:获取日期范围会员统计**
```bash
curl -X GET "http://localhost:8080/api/stats/member/range?startDate=2026-06-01&endDate=2026-06-03"
```
**预期结果**:返回3条记录,分别为 2026-06-01、2026-06-02、2026-06-03 的统计数据。
---
**测试3:获取会员统计汇总**
```bash
curl -X GET "http://localhost:8080/api/stats/member/summary?startDate=2026-06-01&endDate=2026-06-06"
```
**预期结果**
```json
{
"startDate": "2026-06-01",
"endDate": "2026-06-06",
"newMembers": 19,
"activeMembers": 0,
"totalMembers": 19,
"maleMembers": 10,
"femaleMembers": 9,
"cardPurchaseCount": 19,
"averageAge": 29.5
}
```
---
#### 8.2.2 预约数据统计
**测试4:获取单日预约统计**
```bash
curl -X GET "http://localhost:8080/api/stats/booking/date/2026-06-01"
```
**预期结果**
```json
{
"date": "2026-06-01",
"totalBookings": 32,
"cancelledBookings": 5,
"attendedBookings": 27,
"bookingSuccessRate": 0.0,
"cancellationRate": 15.63,
"attendanceRate": 84.38,
"popularCourseName": "燃脂单车",
"popularCourseCount": 19,
"totalCourses": 3,
"fullCourses": 1
}
```
---
**测试5:获取日期范围预约统计**
```bash
curl -X GET "http://localhost:8080/api/stats/booking/range?startDate=2026-06-01&endDate=2026-06-03"
```
**预期结果**:返回3条记录,分别为 2026-06-01、2026-06-02、2026-06-03 的统计数据。
---
**测试6:获取预约统计汇总**
```bash
curl -X GET "http://localhost:8080/api/stats/booking/summary?startDate=2026-06-01&endDate=2026-06-06"
```
**预期结果**
```json
{
"startDate": "2026-06-01",
"endDate": "2026-06-06",
"totalBookings": 172,
"cancelledBookings": 16,
"attendedBookings": 156,
"cancellationRate": 9.30,
"attendanceRate": 90.70
}
```
---
#### 8.2.3 数据导出
**测试7:导出会员统计数据**
```bash
curl -X GET "http://localhost:8080/api/stats/export/member?startDate=2026-06-01&endDate=2026-06-03" \
-H "Accept: text/csv" \
--output member_stats.csv
```
**预期结果**:下载 CSV 文件,包含 2026-06-01 至 2026-06-03 的会员统计数据。
---
**测试8:导出预约统计数据**
```bash
curl -X GET "http://localhost:8080/api/stats/export/booking?startDate=2026-06-01&endDate=2026-06-03" \
-H "Accept: text/csv" \
--output booking_stats.csv
```
**预期结果**:下载 CSV 文件,包含 2026-06-01 至 2026-06-03 的预约统计数据。
---
**测试9:导出全部统计数据**
```bash
curl -X GET "http://localhost:8080/api/stats/export/all?startDate=2026-06-01&endDate=2026-06-03" \
-H "Accept: text/csv" \
--output all_stats.csv
```
**预期结果**:下载 CSV 文件,包含会员和预约的完整统计数据。
---
### 8.3 测试参数说明
#### 日期参数格式
所有日期参数必须使用 `yyyy-MM-dd` 格式,例如:
-`2026-06-01`
-`2026/06/01`
-`2026-6-1`
-`06-01-2026`
#### 日期范围参数
| 参数 | 说明 | 示例 |
|-----|------|------|
| startDate | 开始日期(包含) | `2026-06-01` |
| endDate | 结束日期(包含) | `2026-06-06` |
**注意事项**
- `startDate` 必须 ≤ `endDate`
- 日期范围不能超过 365 天
- 日期必须在测试数据范围内(2026-06-01 至 2026-06-10
---
### 8.4 常见测试场景
#### 场景1:测试单日统计
```bash
# 测试6月1日的会员和预约统计
curl "http://localhost:8080/api/stats/member/date/2026-06-01"
curl "http://localhost:8080/api/stats/booking/date/2026-06-01"
```
---
#### 场景2:测试一周统计
```bash
# 测试6月第一周的统计
curl "http://localhost:8080/api/stats/member/summary?startDate=2026-06-01&endDate=2026-06-06"
curl "http://localhost:8080/api/stats/booking/summary?startDate=2026-06-01&endDate=2026-06-06"
```
---
#### 场景3:测试数据导出
```bash
# 导出6月前3天的所有统计数据
curl "http://localhost:8080/api/stats/export/all?startDate=2026-06-01&endDate=2026-06-03" \
--output test_data.csv
```
---
### 8.5 错误测试用例
#### 测试10:日期格式错误
```bash
curl -X GET "http://localhost:8080/api/stats/member/date/2026/06/01"
```
**预期结果**HTTP 400 Bad Request
---
#### 测试11:日期范围无效
```bash
curl -X GET "http://localhost:8080/api/stats/member/range?startDate=2026-06-06&endDate=2026-06-01"
```
**预期结果**HTTP 400 Bad Request
---
#### 测试12:日期超出测试数据范围
```bash
curl -X GET "http://localhost:8080/api/stats/member/date/2025-01-01"
```
**预期结果**HTTP 404 Not Found 或返回空数据
---
### 8.6 使用 Postman 测试
导入以下环境变量到 Postman
| 变量名 | 值 | 说明 |
|-------|---|------|
| `base_url` | `http://localhost:8080` | API 基础地址 |
| `test_start_date` | `2026-06-01` | 测试开始日期 |
| `test_end_date` | `2026-06-06` | 测试结束日期 |
示例请求:
```
GET {{base_url}}/api/stats/member/date/2026-06-01
GET {{base_url}}/api/stats/member/range?startDate={{test_start_date}}&endDate={{test_end_date}}
GET {{base_url}}/api/stats/booking/summary?startDate={{test_start_date}}&endDate={{test_end_date}}
```