15 KiB
15 KiB
团课管理模块 API 文档
文档版本: v1.0
创建日期: 2026-06-02
作者: 张翔
状态: 正式发布
📋 目录
概述
团课管理模块提供团课的创建、编辑、查询、取消和签到功能,以及团课预约相关操作。采用 Spring WebFlux 响应式编程,支持高并发场景。
基础路径
所有接口的基础路径为: http://{host}:{port}/api/groupCourse
团课管理接口
获取所有团课
| 属性 | 值 |
|---|---|
| HTTP方法 | GET |
| 接口路径 | /api/groupCourse/list |
| 所属文件 | GroupCourseHandler.java |
请求参数:
| 参数名 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| includeDeleted | boolean | 否 | false | 是否包含已删除的团课 |
成功响应 (200 OK):
[
{
"id": 1,
"courseName": "瑜伽入门",
"coachId": 1,
"courseType": 1,
"startTime": "2026-06-02T09:00:00",
"endTime": "2026-06-02T10:00:00",
"maxMembers": 20,
"currentMembers": 15,
"status": 0,
"location": "健身房A区",
"coverImage": "https://example.com/yoga.jpg",
"description": "适合初学者的瑜伽课程",
"createdAt": "2026-06-01T10:00:00",
"updatedAt": "2026-06-01T10:00:00"
}
]
分页获取团课
| 属性 | 值 |
|---|---|
| HTTP方法 | POST |
| 接口路径 | /api/groupCourse/page |
| 所属文件 | GroupCourseHandler.java |
请求体:
{
"page": 0,
"size": 10,
"sort": "id",
"order": "asc",
"keyword": "瑜伽"
}
| 参数名 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| page | int | 否 | 0 | 页码,从0开始 |
| size | int | 否 | 10 | 每页数量,最大100 |
| sort | string | 否 | id | 排序字段 |
| order | string | 否 | asc | 排序方式(asc/desc) |
| keyword | string | 否 | - | 搜索关键词 |
请求参数:
| 参数名 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| includeDeleted | boolean | 否 | false | 是否包含已删除的团课 |
成功响应 (200 OK):
{
"data": [...],
"totalPages": 5,
"totalElements": 45,
"page": 0,
"size": 10
}
根据ID获取团课详情
| 属性 | 值 |
|---|---|
| HTTP方法 | GET |
| 接口路径 | /api/groupCourse/{id} |
| 所属文件 | GroupCourseHandler.java |
路径参数:
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| id | Long | 是 | 团课ID |
成功响应 (200 OK):
{
"id": 1,
"courseName": "瑜伽入门",
"coachId": 1,
"courseType": 1,
"startTime": "2026-06-02T09:00:00",
"endTime": "2026-06-02T10:00:00",
"maxMembers": 20,
"currentMembers": 15,
"status": 0,
"location": "健身房A区",
"coverImage": "https://example.com/yoga.jpg",
"description": "适合初学者的瑜伽课程",
"pointCardAmount": 1,
"storedValueAmount": 50.00,
"createdAt": "2026-06-01T10:00:00",
"updatedAt": "2026-06-01T10:00:00"
}
失败响应 (404 Not Found):
{}
创建团课
| 属性 | 值 |
|---|---|
| HTTP方法 | POST |
| 接口路径 | /api/groupCourse |
| 所属文件 | GroupCourseHandler.java |
请求体:
{
"courseName": "动感单车",
"coachId": 2,
"courseType": 2,
"startTime": "2026-06-05T18:00:00",
"endTime": "2026-06-05T19:00:00",
"maxMembers": 25,
"location": "健身房B区",
"coverImage": "https://example.com/spinning.jpg",
"description": "高强度有氧运动课程",
"pointCardAmount": 1,
"storedValueAmount": 50.00
}
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| courseName | String | 是 | 课程名称 |
| coachId | Long | 否 | 教练ID |
| courseType | Long | 否 | 课程类型 |
| startTime | LocalDateTime | 否 | 开始时间 |
| endTime | LocalDateTime | 否 | 结束时间 |
| maxMembers | Integer | 否 | 最大参与人数,默认20 |
| location | String | 否 | 上课地点 |
| coverImage | String | 否 | 封面图URL |
| description | String | 否 | 课程描述 |
| pointCardAmount | Integer | 否 | 点卡额度(消耗次数),默认1 |
| storedValueAmount | BigDecimal | 否 | 储值卡额度(消耗金额),默认0 |
成功响应 (200 OK):
{
"success": true,
"message": "团课创建成功",
"data": {
"id": 2,
"courseName": "动感单车",
"coachId": 2,
"courseType": 2,
"startTime": "2026-06-05T18:00:00",
"endTime": "2026-06-05T19:00:00",
"maxMembers": 25,
"currentMembers": 0,
"status": 0,
"location": "健身房B区",
"coverImage": "https://example.com/spinning.jpg",
"description": "高强度有氧运动课程",
"pointCardAmount": 1,
"storedValueAmount": 50.00
}
}
失败响应 (400 Bad Request):
{
"success": false,
"message": "课程名称不能为空"
}
更新团课
| 属性 | 值 |
|---|---|
| HTTP方法 | PUT |
| 接口路径 | /api/groupCourse/{id} |
| 所属文件 | GroupCourseHandler.java |
路径参数:
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| id | Long | 是 | 团课ID |
请求体:
{
"courseName": "动感单车升级版",
"coachId": 2,
"maxMembers": 30,
"description": "升级版高强度有氧运动课程",
"pointCardAmount": 2,
"storedValueAmount": 80.00
}
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| courseName | String | 否 | 课程名称 |
| coachId | Long | 否 | 教练ID |
| courseType | Long | 否 | 课程类型 |
| startTime | LocalDateTime | 否 | 开始时间 |
| endTime | LocalDateTime | 否 | 结束时间 |
| maxMembers | Integer | 否 | 最大参与人数 |
| location | String | 否 | 上课地点 |
| coverImage | String | 否 | 封面图URL |
| description | String | 否 | 课程描述 |
| pointCardAmount | Integer | 否 | 点卡额度(消耗次数) |
| storedValueAmount | BigDecimal | 否 | 储值卡额度(消耗金额) |
成功响应 (200 OK):
{
"success": true,
"message": "团课更新成功",
"data": {
"id": 2,
"courseName": "动感单车升级版",
"coachId": 2,
"maxMembers": 30,
"description": "升级版高强度有氧运动课程",
"pointCardAmount": 2,
"storedValueAmount": 80.00
}
}
失败响应 (400 Bad Request):
{
"success": false,
"message": "团课不存在"
}
取消团课
| 属性 | 值 |
|---|---|
| HTTP方法 | POST |
| 接口路径 | /api/groupCourse/{id}/cancel |
| 所属文件 | GroupCourseHandler.java |
路径参数:
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| id | Long | 是 | 团课ID |
成功响应 (200 OK):
{
"success": true,
"message": "团课取消成功",
"data": {
"id": 2,
"status": 1
}
}
失败响应 (400 Bad Request):
{
"success": false,
"message": "课程取消需提前24小时"
}
团课签到
| 属性 | 值 |
|---|---|
| HTTP方法 | POST |
| 接口路径 | /api/groupCourse/{courseId}/signin |
| 所属文件 | GroupCourseHandler.java |
路径参数:
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| courseId | Long | 是 | 团课ID |
请求体:
{
"memberId": 1001
}
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| memberId | Long | 是 | 会员ID |
成功响应 (200 OK):
{
"success": true,
"message": "签到成功",
"data": {
"id": 2,
"currentMembers": 16
}
}
失败响应 (400 Bad Request):
{
"success": false,
"message": "课程已满员"
}
删除团课
| 属性 | 值 |
|---|---|
| HTTP方法 | DELETE |
| 接口路径 | /api/groupCourse/{id} |
| 所属文件 | GroupCourseHandler.java |
路径参数:
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| id | Long | 是 | 团课ID |
成功响应 (200 OK):
{
"success": true,
"message": "团课删除成功"
}
团课预约接口
预约团课
| 属性 | 值 |
|---|---|
| HTTP方法 | POST |
| 接口路径 | /api/groupCourse/book |
| 所属文件 | GroupCourseBookingHandler.java |
请求体:
{
"courseId": 1,
"memberId": 1001,
"memberCardRecordId": 5001
}
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| courseId | Long | 是 | 团课ID |
| memberId | Long | 是 | 会员ID |
| memberCardRecordId | Long | 是 | 会员卡记录ID |
成功响应 (200 OK):
{
"success": true,
"message": "预约成功",
"data": {
"id": 100,
"courseId": 1,
"memberId": 1001,
"memberCardRecordId": 5001,
"bookingTime": "2026-06-02T08:00:00",
"status": "0"
}
}
取消预约
| 属性 | 值 |
|---|---|
| HTTP方法 | POST |
| 接口路径 | /api/groupCourse/booking/{bookingId}/cancel |
| 所属文件 | GroupCourseBookingHandler.java |
路径参数:
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| bookingId | Long | 是 | 预约ID |
请求体:
{
"memberId": 1001
}
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| memberId | Long | 是 | 会员ID |
成功响应 (200 OK):
{
"success": true,
"message": "取消成功",
"data": {
"id": 100,
"status": "1",
"cancelTime": "2026-06-02T09:00:00"
}
}
查询会员预约记录
| 属性 | 值 |
|---|---|
| HTTP方法 | GET |
| 接口路径 | /api/groupCourse/bookings/member/{memberId} |
| 所属文件 | GroupCourseBookingHandler.java |
路径参数:
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| memberId | Long | 是 | 会员ID |
成功响应 (200 OK):
[
{
"id": 100,
"courseId": 1,
"courseName": "瑜伽入门",
"memberId": 1001,
"memberCardRecordId": 5001,
"bookingTime": "2026-06-02T08:00:00",
"status": "0",
"courseStartTime": "2026-06-02T09:00:00",
"location": "健身房A区"
}
]
查询预约详情
| 属性 | 值 |
|---|---|
| HTTP方法 | GET |
| 接口路径 | /api/groupCourse/bookings/{bookingId} |
| 所属文件 | GroupCourseBookingHandler.java |
路径参数:
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| bookingId | Long | 是 | 预约ID |
成功响应 (200 OK):
{
"id": 100,
"courseId": 1,
"courseName": "瑜伽入门",
"memberId": 1001,
"memberCardRecordId": 5001,
"bookingTime": "2026-06-02T08:00:00",
"status": "0",
"courseStartTime": "2026-06-02T09:00:00",
"courseEndTime": "2026-06-02T10:00:00",
"location": "健身房A区"
}
失败响应 (404 Not Found):
{}
查询课程预约记录
| 属性 | 值 |
|---|---|
| HTTP方法 | GET |
| 接口路径 | /api/groupCourse/bookings/course/{courseId} |
| 所属文件 | GroupCourseBookingHandler.java |
路径参数:
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| courseId | Long | 是 | 团课ID |
成功响应 (200 OK):
[
{
"id": 100,
"courseId": 1,
"courseName": "瑜伽入门",
"memberId": 1001,
"bookingTime": "2026-06-02T08:00:00",
"status": "0"
}
]
数据模型
GroupCourse(团课)
| 字段名 | 类型 | 说明 |
|---|---|---|
| id | Long | 主键ID |
| courseName | String | 课程名称 |
| coachId | Long | 教练ID |
| courseType | Long | 课程类型 |
| startTime | LocalDateTime | 开始时间 |
| endTime | LocalDateTime | 结束时间 |
| maxMembers | Integer | 最大参与人数 |
| currentMembers | Integer | 当前参与人数 |
| status | Long | 状态(0-正常,1-已取消,2-已结束) |
| location | String | 上课地点 |
| coverImage | String | 封面图URL |
| description | String | 课程描述 |
| pointCardAmount | Integer | 点卡额度(消耗次数),默认1 |
| storedValueAmount | BigDecimal | 储值卡额度(消耗金额),默认0 |
| createdBy | String | 创建人 |
| updatedBy | String | 更新人 |
| createdAt | LocalDateTime | 创建时间 |
| updatedAt | LocalDateTime | 更新时间 |
| deletedAt | LocalDateTime | 删除时间(软删除) |
GroupCourseBooking(团课预约)
| 字段名 | 类型 | 说明 |
|---|---|---|
| id | Long | 主键ID |
| courseId | Long | 团课ID |
| courseName | String | 团课名称 |
| memberId | Long | 会员ID |
| memberCardRecordId | Long | 会员卡记录ID |
| bookingTime | LocalDateTime | 预约时间 |
| status | String | 状态(0-已预约,1-已取消,2-已出席,3-缺席) |
| cancelTime | LocalDateTime | 取消时间 |
| courseStartTime | LocalDateTime | 课程开始时间 |
| courseEndTime | LocalDateTime | 课程结束时间 |
| location | String | 上课地点 |
| createdBy | String | 创建人 |
| updatedBy | String | 更新人 |
| createdAt | LocalDateTime | 创建时间 |
| updatedAt | LocalDateTime | 更新时间 |
| deletedAt | LocalDateTime | 删除时间(软删除) |
状态码说明
团课状态
| 状态码 | 含义 |
|---|---|
| 0 | 正常 |
| 1 | 已取消 |
| 2 | 已结束 |
预约状态
| 状态码 | 含义 |
|---|---|
| 0 | 已预约 |
| 1 | 已取消 |
| 2 | 已出席 |
| 3 | 缺席 |
业务规则
团课管理
- 创建团课:课程名称为必填项
- 取消团课:需提前24小时通知,否则拒绝操作
- 团课签到:验证课程状态必须为正常,且未达最大人数限制
- 删除团课:采用软删除机制,数据保留可恢复
团课预约
- 预约团课:需验证会员卡有效性和课程名额
- 取消预约:需在课程开始前至少2小时取消
附录:错误响应格式
所有接口的错误响应统一格式:
{
"success": false,
"message": "错误描述信息"
}
文档结束