Files
gym-manage/gym-manage-api/docs/datacount-api.md
T

849 lines
19 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 数据统计模块 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}}
```