# 团课管理模块 API 文档 > **文档版本**: v1.0 > **创建日期**: 2026-06-02 > **作者**: 张翔 > **状态**: 正式发布 --- ## 📋 目录 1. [概述](#概述) 2. [基础路径](#基础路径) 3. [团课管理接口](#团课管理接口) - [获取所有团课](#获取所有团课) - [分页获取团课](#分页获取团课) - [根据ID获取团课详情](#根据ID获取团课详情) - [创建团课](#创建团课) - [更新团课](#更新团课) - [取消团课](#取消团课) - [团课签到](#团课签到) - [删除团课](#删除团课) 4. [团课预约接口](#团课预约接口) - [预约团课](#预约团课) - [取消预约](#取消预约) - [查询会员预约记录](#查询会员预约记录) - [查询预约详情](#查询预约详情) - [查询课程预约记录](#查询课程预约记录) 5. [数据模型](#数据模型) - [GroupCourse(团课)](#GroupCourse团课) - [GroupCourseBooking(团课预约)](#GroupCourseBooking团课预约) 6. [状态码说明](#状态码说明) 7. [业务规则](#业务规则) --- ## 概述 团课管理模块提供团课的创建、编辑、查询、取消和签到功能,以及团课预约相关操作。采用 Spring WebFlux 响应式编程,支持高并发场景。 ## 基础路径 所有接口的基础路径为: `http://{host}:{port}/api/groupCourse` --- ## 团课管理接口 ### 获取所有团课 | 属性 | 值 | |------|-----| | **HTTP方法** | GET | | **接口路径** | `/api/groupCourse/list` | | **所属文件** | `GroupCourseHandler.java` | **请求参数**: | 参数名 | 类型 | 必填 | 默认值 | 说明 | |--------|------|------|--------|------| | includeDeleted | boolean | 否 | false | 是否包含已删除的团课 | **成功响应** (200 OK): ```json [ { "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` | **请求体**: ```json { "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): ```json { "data": [...], "totalPages": 5, "totalElements": 45, "page": 0, "size": 10 } ``` --- ### 根据ID获取团课详情 | 属性 | 值 | |------|-----| | **HTTP方法** | GET | | **接口路径** | `/api/groupCourse/{id}` | | **所属文件** | `GroupCourseHandler.java` | **路径参数**: | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | id | Long | 是 | 团课ID | **成功响应** (200 OK): ```json { "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): ```json {} ``` --- ### 创建团课 | 属性 | 值 | |------|-----| | **HTTP方法** | POST | | **接口路径** | `/api/groupCourse` | | **所属文件** | `GroupCourseHandler.java` | **请求体**: ```json { "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): ```json { "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): ```json { "success": false, "message": "课程名称不能为空" } ``` --- ### 更新团课 | 属性 | 值 | |------|-----| | **HTTP方法** | PUT | | **接口路径** | `/api/groupCourse/{id}` | | **所属文件** | `GroupCourseHandler.java` | **路径参数**: | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | id | Long | 是 | 团课ID | **请求体**: ```json { "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): ```json { "success": true, "message": "团课更新成功", "data": { "id": 2, "courseName": "动感单车升级版", "coachId": 2, "maxMembers": 30, "description": "升级版高强度有氧运动课程", "pointCardAmount": 2, "storedValueAmount": 80.00 } } ``` **失败响应** (400 Bad Request): ```json { "success": false, "message": "团课不存在" } ``` --- ### 取消团课 | 属性 | 值 | |------|-----| | **HTTP方法** | POST | | **接口路径** | `/api/groupCourse/{id}/cancel` | | **所属文件** | `GroupCourseHandler.java` | **路径参数**: | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | id | Long | 是 | 团课ID | **成功响应** (200 OK): ```json { "success": true, "message": "团课取消成功", "data": { "id": 2, "status": 1 } } ``` **失败响应** (400 Bad Request): ```json { "success": false, "message": "课程取消需提前24小时" } ``` --- ### 团课签到 | 属性 | 值 | |------|-----| | **HTTP方法** | POST | | **接口路径** | `/api/groupCourse/{courseId}/signin` | | **所属文件** | `GroupCourseHandler.java` | **路径参数**: | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | courseId | Long | 是 | 团课ID | **请求体**: ```json { "memberId": 1001 } ``` | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | memberId | Long | **是** | 会员ID | **成功响应** (200 OK): ```json { "success": true, "message": "签到成功", "data": { "id": 2, "currentMembers": 16 } } ``` **失败响应** (400 Bad Request): ```json { "success": false, "message": "课程已满员" } ``` --- ### 删除团课 | 属性 | 值 | |------|-----| | **HTTP方法** | DELETE | | **接口路径** | `/api/groupCourse/{id}` | | **所属文件** | `GroupCourseHandler.java` | **路径参数**: | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | id | Long | 是 | 团课ID | **成功响应** (200 OK): ```json { "success": true, "message": "团课删除成功" } ``` --- ## 团课预约接口 ### 预约团课 | 属性 | 值 | |------|-----| | **HTTP方法** | POST | | **接口路径** | `/api/groupCourse/book` | | **所属文件** | `GroupCourseBookingHandler.java` | **请求体**: ```json { "courseId": 1, "memberId": 1001, "memberCardRecordId": 5001 } ``` | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | courseId | Long | **是** | 团课ID | | memberId | Long | **是** | 会员ID | | memberCardRecordId | Long | **是** | 会员卡记录ID | **成功响应** (200 OK): ```json { "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 | **请求体**: ```json { "memberId": 1001 } ``` | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | memberId | Long | **是** | 会员ID | **成功响应** (200 OK): ```json { "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): ```json [ { "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): ```json { "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): ```json {} ``` --- ### 查询课程预约记录 | 属性 | 值 | |------|-----| | **HTTP方法** | GET | | **接口路径** | `/api/groupCourse/bookings/course/{courseId}` | | **所属文件** | `GroupCourseBookingHandler.java` | **路径参数**: | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | courseId | Long | 是 | 团课ID | **成功响应** (200 OK): ```json [ { "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 | 缺席 | --- ## 业务规则 ### 团课管理 1. **创建团课**:课程名称为必填项 2. **取消团课**:需提前24小时通知,否则拒绝操作 3. **团课签到**:验证课程状态必须为正常,且未达最大人数限制 4. **删除团课**:采用软删除机制,数据保留可恢复 ### 团课预约 1. **预约团课**:需验证会员卡有效性和课程名额 2. **取消预约**:需在课程开始前至少2小时取消 --- ## 附录:错误响应格式 所有接口的错误响应统一格式: ```json { "success": false, "message": "错误描述信息" } ``` --- *文档结束*