diff --git a/gym-manage-uniapp/api/envConfig.js b/gym-manage-uniapp/api/envConfig.js
new file mode 100644
index 0000000..5fb6881
--- /dev/null
+++ b/gym-manage-uniapp/api/envConfig.js
@@ -0,0 +1,13 @@
+/**
+ * 环境配置文件
+ * 当前仅使用模拟数据(开发模式)
+ */
+
+import { groupCourseMockApi } from './groupCourse.mock.js'
+
+/**
+ * 团课服务(仅使用模拟数据)
+ */
+export const groupCourseService = groupCourseMockApi
+
+export default groupCourseService
diff --git a/gym-manage-uniapp/api/groupCourse.mock.js b/gym-manage-uniapp/api/groupCourse.mock.js
new file mode 100644
index 0000000..1f0aa29
--- /dev/null
+++ b/gym-manage-uniapp/api/groupCourse.mock.js
@@ -0,0 +1,407 @@
+/**
+ * 团课模拟数据(测试环境使用)
+ * 数据格式与后端返回格式保持一致
+ */
+
+// 模拟团课列表数据(与后端返回格式一致)
+const mockCourseList = [
+ {
+ "id": "1",
+ "createBy": "admin",
+ "updateBy": null,
+ "createdAt": "2026-06-01T11:00:00",
+ "updatedAt": "2026-06-01T11:00:00",
+ "deletedAt": null,
+ "courseName": "极速燃脂单车",
+ "coachId": "104",
+ "courseType": "2",
+ "startTime": "2026-06-02T16:45:00",
+ "endTime": "2026-06-15T20:20:00",
+ "maxMembers": 25,
+ "currentMembers": 0,
+ "status": "0",
+ "location": "单车房",
+ "coverImage": "https://picsum.photos/seed/spinning/640/360",
+ "description": "跟随音乐节奏变换阻力和速度,体验爬坡与冲刺的快感,一节课消耗800大卡。支持次数卡(1次)或储值卡(50元)支付。",
+ "pointCardAmount": 0,
+ "storedValueAmount": 0
+ },
+ {
+ "id": "3",
+ "createBy": "coach_zhang",
+ "updateBy": null,
+ "createdAt": "2026-06-01T14:30:00",
+ "updatedAt": "2026-06-01T14:30:00",
+ "deletedAt": null,
+ "courseName": "燃脂搏击",
+ "coachId": "102",
+ "courseType": "2",
+ "startTime": "2026-06-10T18:30:00",
+ "endTime": "2026-06-10T19:30:00",
+ "maxMembers": 20,
+ "currentMembers": 20,
+ "status": "0",
+ "location": "综合训练区",
+ "coverImage": "https://picsum.photos/seed/kickboxing/640/360",
+ "description": "高强度间歇训练,配合音乐快速燃脂,释放压力。名额已满,无法预约。支持次数卡(1次)或储值卡(60元)支付。",
+ "pointCardAmount": 1,
+ "storedValueAmount": 60
+ },
+ {
+ "id": "4",
+ "createBy": "coach_li",
+ "updateBy": null,
+ "createdAt": "2026-06-01T08:00:00",
+ "updatedAt": "2026-06-01T08:00:00",
+ "deletedAt": null,
+ "courseName": "哈他瑜伽",
+ "coachId": "101",
+ "courseType": "1",
+ "startTime": "2026-06-01T15:20:00",
+ "endTime": "2026-06-01T16:50:00",
+ "maxMembers": 12,
+ "currentMembers": 3,
+ "status": "0",
+ "location": "瑜伽教室B",
+ "coverImage": "https://picsum.photos/seed/yoga/640/360",
+ "description": "基础哈他瑜伽,适合所有级别。距开始不足30分钟,已停止预约。支持次数卡(1次)或储值卡(40元)支付。",
+ "pointCardAmount": 1,
+ "storedValueAmount": 40
+ },
+ {
+ "id": "5",
+ "createBy": "coach_wang",
+ "updateBy": null,
+ "createdAt": "2026-05-28T08:00:00",
+ "updatedAt": "2026-05-28T08:00:00",
+ "deletedAt": null,
+ "courseName": "周末冥想修复",
+ "coachId": "101",
+ "courseType": "1",
+ "startTime": "2026-06-20T15:00:00",
+ "endTime": "2026-06-20T16:00:00",
+ "maxMembers": 12,
+ "currentMembers": 3,
+ "status": "1",
+ "location": "冥想室",
+ "coverImage": "https://picsum.photos/seed/meditation/640/360",
+ "description": "通过呼吸和正念冥想,深度放松身心。该课程已被取消。支持次数卡(1次)或储值卡(30元)支付。",
+ "pointCardAmount": 1,
+ "storedValueAmount": 30
+ },
+ {
+ "id": "6",
+ "createBy": "coach_li",
+ "updateBy": null,
+ "createdAt": "2026-05-20T09:15:00",
+ "updatedAt": "2026-05-20T09:15:00",
+ "deletedAt": null,
+ "courseName": "蜜桃臀塑造",
+ "coachId": "103",
+ "courseType": "3",
+ "startTime": "2026-05-30T19:00:00",
+ "endTime": "2026-05-30T20:00:00",
+ "maxMembers": 10,
+ "currentMembers": 8,
+ "status": "2",
+ "location": "私教专区",
+ "coverImage": "https://picsum.photos/seed/glute/640/360",
+ "description": "针对性训练臀部肌肉群,课程已于5月30日结束,无法预约。支持次数卡(1次)或储值卡(80元)支付。",
+ "pointCardAmount": 1,
+ "storedValueAmount": 80
+ },
+ {
+ "id": "7",
+ "createBy": "admin",
+ "updateBy": null,
+ "createdAt": "2026-05-25T09:00:00",
+ "updatedAt": "2026-05-25T09:00:00",
+ "deletedAt": null,
+ "courseName": "午间冥想放松",
+ "coachId": "101",
+ "courseType": "1",
+ "startTime": "2026-05-31T12:00:00",
+ "endTime": "2026-05-31T13:00:00",
+ "maxMembers": 15,
+ "currentMembers": 6,
+ "status": "2",
+ "location": "冥想室",
+ "coverImage": "https://picsum.photos/seed/noonmeditation/640/360",
+ "description": "午间冥想课程,已于5月31日结束。支持次数卡(1次)或储值卡(25元)支付。",
+ "pointCardAmount": 1,
+ "storedValueAmount": 25
+ },
+ {
+ "id": "8",
+ "createBy": "admin",
+ "updateBy": null,
+ "createdAt": "2026-06-01T10:00:00",
+ "updatedAt": "2026-06-01T10:00:00",
+ "deletedAt": null,
+ "courseName": "燃脂搏击_次数卡课程",
+ "coachId": "102",
+ "courseType": "2",
+ "startTime": "2026-06-10T19:30:00",
+ "endTime": "2026-06-10T20:30:00",
+ "maxMembers": 20,
+ "currentMembers": 0,
+ "status": "0",
+ "location": "综合训练区",
+ "coverImage": null,
+ "description": "高强度间歇训练,配合音乐快速燃脂,消耗1次",
+ "pointCardAmount": 1,
+ "storedValueAmount": 0
+ },
+ {
+ "id": "9",
+ "createBy": "admin",
+ "updateBy": null,
+ "createdAt": "2026-06-01T10:00:00",
+ "updatedAt": "2026-06-01T10:00:00",
+ "deletedAt": null,
+ "courseName": "高端普拉提_储值卡课程",
+ "coachId": "103",
+ "courseType": "1",
+ "startTime": "2026-06-11T19:00:00",
+ "endTime": "2026-06-11T20:00:00",
+ "maxMembers": 15,
+ "currentMembers": 0,
+ "status": "0",
+ "location": "普拉提教室",
+ "coverImage": null,
+ "description": "精准训练核心肌群,消耗储值50元",
+ "pointCardAmount": 0,
+ "storedValueAmount": 20
+ },
+ {
+ "id": "11",
+ "createBy": "admin",
+ "updateBy": null,
+ "createdAt": "2026-06-02T10:00:00",
+ "updatedAt": "2026-06-02T10:00:00",
+ "deletedAt": null,
+ "courseName": "时间冲突测试_A_13点-15点",
+ "coachId": "102",
+ "courseType": "2",
+ "startTime": "2026-06-15T13:00:00",
+ "endTime": "2026-06-15T15:00:00",
+ "maxMembers": 20,
+ "currentMembers": 0,
+ "status": "0",
+ "location": "综合训练区",
+ "coverImage": null,
+ "description": "测试用团课A,用于验证时间冲突检测。支持次数卡(1次)或储值卡(50元)支付。",
+ "pointCardAmount": 1,
+ "storedValueAmount": 50
+ },
+ {
+ "id": "12",
+ "createBy": "admin",
+ "updateBy": null,
+ "createdAt": "2026-06-02T10:00:00",
+ "updatedAt": "2026-06-02T10:00:00",
+ "deletedAt": null,
+ "courseName": "时间冲突测试_B_14点-16点",
+ "coachId": "103",
+ "courseType": "1",
+ "startTime": "2026-06-15T14:00:00",
+ "endTime": "2026-06-15T16:00:00",
+ "maxMembers": 15,
+ "currentMembers": 0,
+ "status": "0",
+ "location": "普拉提教室",
+ "coverImage": null,
+ "description": "测试用团课B,与团课A时间重叠(14:00-15:00)。支持次数卡(1次)或储值卡(50元)支付。",
+ "pointCardAmount": 1,
+ "storedValueAmount": 50
+ },
+ {
+ "id": "13",
+ "createBy": "admin",
+ "updateBy": null,
+ "createdAt": "2026-06-02T10:00:00",
+ "updatedAt": "2026-06-02T10:00:00",
+ "deletedAt": null,
+ "courseName": "时间冲突测试_C_10点-12点",
+ "coachId": "101",
+ "courseType": "1",
+ "startTime": "2026-06-15T10:00:00",
+ "endTime": "2026-06-15T12:00:00",
+ "maxMembers": 15,
+ "currentMembers": 0,
+ "status": "0",
+ "location": "瑜伽教室",
+ "coverImage": null,
+ "description": "测试用团课C,与团课A/B不冲突。支持次数卡(1次)或储值卡(50元)支付。",
+ "pointCardAmount": 1,
+ "storedValueAmount": 50
+ },
+ {
+ "id": "14",
+ "createBy": "system",
+ "updateBy": "system",
+ "createdAt": "2026-06-02T17:32:50.532336",
+ "updatedAt": "2026-06-02T17:32:50.532336",
+ "deletedAt": null,
+ "courseName": "动感单车aaa",
+ "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
+ },
+ {
+ "id": "2",
+ "createBy": "admin",
+ "updateBy": null,
+ "createdAt": "2026-06-01T10:00:00",
+ "updatedAt": "2026-06-02T17:35:35.155616",
+ "deletedAt": null,
+ "courseName": "清晨流瑜伽",
+ "coachId": "101",
+ "courseType": "1",
+ "startTime": "2026-06-12T09:00:00",
+ "endTime": "2026-06-12T10:30:00",
+ "maxMembers": 15,
+ "currentMembers": 6,
+ "status": "0",
+ "location": "A座3楼瑜伽教室",
+ "coverImage": "https://picsum.photos/seed/yogaflow/640/360",
+ "description": "适合有一定基础的学员,通过流畅的体式连接呼吸,唤醒身体能量。支持次数卡(1次)或储值卡(45元)支付。",
+ "pointCardAmount": 1,
+ "storedValueAmount": 45
+ },
+ {
+ "id": "15",
+ "createBy": "system",
+ "updateBy": "system",
+ "createdAt": "2026-06-02T17:57:27.483488",
+ "updatedAt": "2026-06-02T17:57:27.483488",
+ "deletedAt": null,
+ "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
+ }
+]
+
+/**
+ * 模拟团课API(测试环境)
+ * 接口签名与真实API保持一致
+ */
+export const groupCourseMockApi = {
+ /**
+ * 获取团课列表(支持分页)
+ * @param {Object} params - 查询参数
+ * @param {number} params.pageNum - 页码(从1开始)
+ * @param {number} params.pageSize - 每页数量
+ * @returns {Promise} - 分页团课列表数据
+ */
+ getList: (params = {}) => {
+ return new Promise((resolve) => {
+ setTimeout(() => {
+ const pageNum = params.pageNum || 1
+ const pageSize = params.pageSize || 10
+
+ const total = mockCourseList.length
+ const startIndex = (pageNum - 1) * pageSize
+ const endIndex = startIndex + pageSize
+ const list = mockCourseList.slice(startIndex, endIndex)
+
+ console.log('[groupCourse.mock.js] 模拟获取团课列表(分页):', {
+ pageNum,
+ pageSize,
+ total,
+ listCount: list.length
+ })
+
+ resolve({
+ code: 0,
+ message: 'success',
+ data: {
+ list,
+ total,
+ pageNum,
+ pageSize,
+ totalPages: Math.ceil(total / pageSize)
+ }
+ })
+ }, 500)
+ })
+ },
+
+ /**
+ * 获取团课详情
+ * @param {string} id - 课程ID
+ * @returns {Promise} - 团课详情数据
+ */
+ getDetail: (id) => {
+ return new Promise((resolve, reject) => {
+ setTimeout(() => {
+ console.log('[groupCourse.mock.js] 模拟获取团课详情:', id)
+ const course = mockCourseList.find(item => item.id === id)
+ if (course) {
+ resolve(course)
+ } else {
+ reject({ code: -1, message: '课程不存在' })
+ }
+ }, 300)
+ })
+ },
+
+ /**
+ * 预约团课
+ * @param {Object} data - 预约数据
+ * @param {string} data.courseId - 课程ID
+ * @param {string} data.memberId - 会员ID
+ * @returns {Promise} - 预约结果
+ */
+ book: (data) => {
+ return new Promise((resolve) => {
+ setTimeout(() => {
+ console.log('[groupCourse.mock.js] 模拟预约团课:', data)
+ resolve({
+ code: 0,
+ message: '预约成功',
+ data: { bookingId: `BK${Date.now()}` }
+ })
+ }, 400)
+ })
+ },
+
+ /**
+ * 取消预约
+ * @param {string} id - 预约记录ID
+ * @returns {Promise} - 取消结果
+ */
+ cancelBooking: (id) => {
+ return new Promise((resolve) => {
+ setTimeout(() => {
+ console.log('[groupCourse.mock.js] 模拟取消预约:', id)
+ resolve({
+ code: 0,
+ message: '取消成功',
+ data: null
+ })
+ }, 300)
+ })
+ }
+}
+
+export default groupCourseMockApi
diff --git a/gym-manage-uniapp/common/style/font/iconfont_courseCard.ttf b/gym-manage-uniapp/common/style/font/iconfont_courseCard.ttf
new file mode 100644
index 0000000..3e233cb
Binary files /dev/null and b/gym-manage-uniapp/common/style/font/iconfont_courseCard.ttf differ
diff --git a/gym-manage-uniapp/common/style/font/iconfont_time_select.ttf b/gym-manage-uniapp/common/style/font/iconfont_time_select.ttf
new file mode 100644
index 0000000..c1d24b1
Binary files /dev/null and b/gym-manage-uniapp/common/style/font/iconfont_time_select.ttf differ
diff --git a/gym-manage-uniapp/common/style/iconfont_courseCard.css b/gym-manage-uniapp/common/style/iconfont_courseCard.css
new file mode 100644
index 0000000..98fb44c
--- /dev/null
+++ b/gym-manage-uniapp/common/style/iconfont_courseCard.css
@@ -0,0 +1,25 @@
+@font-face {
+ font-family: "iconfont_courseCard"; /* Project id */
+ src: url('./font/iconfont_courseCard.ttf?t=1780537357472') format('truetype');
+}
+
+.iconfont_courseCard {
+ font-family: "iconfont_courseCard" !important;
+ font-size: 16px;
+ font-style: normal;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+.icon-didian:before {
+ content: "\e61a";
+}
+
+.icon-renwu-ren:before {
+ content: "\e749";
+}
+
+.icon-shijian:before {
+ content: "\e61d";
+}
+
diff --git a/gym-manage-uniapp/common/style/iconfont_time_select.css b/gym-manage-uniapp/common/style/iconfont_time_select.css
new file mode 100644
index 0000000..1efde39
--- /dev/null
+++ b/gym-manage-uniapp/common/style/iconfont_time_select.css
@@ -0,0 +1,29 @@
+@font-face {
+ font-family: "iconfont_time_select"; /* Project id */
+ src: url('./font/iconfont_time_select.ttf?t=1780535096813') format('truetype');
+}
+
+.iconfont_time_select {
+ font-family: "iconfont_time_select" !important;
+ font-size: 25px;
+ font-style: normal;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+.icon-zaochen:before {
+ content: "\e784";
+}
+
+.icon-gengduo:before {
+ content: "\e6df";
+}
+
+.icon-xiawucha:before {
+ content: "\100ff";
+}
+
+.icon-yewan:before {
+ content: "\e67e";
+}
+
diff --git a/gym-manage-uniapp/components/groupCourse/CourseCard.vue b/gym-manage-uniapp/components/groupCourse/CourseCard.vue
new file mode 100644
index 0000000..2ff731e
--- /dev/null
+++ b/gym-manage-uniapp/components/groupCourse/CourseCard.vue
@@ -0,0 +1,487 @@
+
+
+
+
+
+
+
+
+
+
+
+ {{ statusText }}
+
+
+
+
+ {{ course.maxMembers - course.currentMembers }}个名额
+
+
+
+
+
+
+
+ {{ course.courseName }}
+
+
+
+
+
+
+
+ {{ formatTime(course.startTime) }}
+
+
+
+
+ {{ course.location }}
+
+
+
+
+
+
+ {{ formatDuration(course.startTime, course.endTime) }}
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/gym-manage-uniapp/components/groupCourse/FilterSection.vue b/gym-manage-uniapp/components/groupCourse/FilterSection.vue
new file mode 100644
index 0000000..d97595d
--- /dev/null
+++ b/gym-manage-uniapp/components/groupCourse/FilterSection.vue
@@ -0,0 +1,202 @@
+
+
+
+
+
+ {{ timeRangeText || '选择时间' }}
+
+
+
+
+
+
+
+ {{ sortOptions[sortIndex].label }}
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/gym-manage-uniapp/components/groupCourse/SearchBar.vue b/gym-manage-uniapp/components/groupCourse/SearchBar.vue
new file mode 100644
index 0000000..cec1e7b
--- /dev/null
+++ b/gym-manage-uniapp/components/groupCourse/SearchBar.vue
@@ -0,0 +1,165 @@
+
+
+
+
+
+
+
+
+
+ 搜索
+
+
+
+
+ 热门搜索:
+
+ {{ kw }}
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/gym-manage-uniapp/components/groupCourse/TimePeriodSelector.vue b/gym-manage-uniapp/components/groupCourse/TimePeriodSelector.vue
new file mode 100644
index 0000000..ef71591
--- /dev/null
+++ b/gym-manage-uniapp/components/groupCourse/TimePeriodSelector.vue
@@ -0,0 +1,191 @@
+
+
+
+
+
+
+
+
+ {{ option.label.split(' ')[0] }}
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/gym-manage-uniapp/components/groupCourse/TimeRangePicker.vue b/gym-manage-uniapp/components/groupCourse/TimeRangePicker.vue
new file mode 100644
index 0000000..bb70cdc
--- /dev/null
+++ b/gym-manage-uniapp/components/groupCourse/TimeRangePicker.vue
@@ -0,0 +1,728 @@
+
+
+
+
+
+
+
+
+
+
+
+ 开始日期
+
+ {{ localStartDate || '请选择' }}
+ ›
+
+
+
+
+ 结束日期
+
+ {{ localEndDate || '请选择' }}
+ ›
+
+
+
+
+ 快捷选择
+
+
+ {{ item.label }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ day }}
+
+
+
+ {{ day.day }}
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/gym-manage-uniapp/docs/api-documentation.md b/gym-manage-uniapp/docs/api-documentation.md
new file mode 100644
index 0000000..2f508e9
--- /dev/null
+++ b/gym-manage-uniapp/docs/api-documentation.md
@@ -0,0 +1,234 @@
+# 团课管理系统 API 文档
+
+## 1. 项目概述
+
+本项目是一个基于 UniApp 的健身房团课管理系统,包含完整的 API 层设计,支持开发/生产环境的快速切换。
+
+### 1.1 项目结构
+
+```
+gym-manage-uniapp/
+├── api/ # API 层目录
+│ ├── requestBase.js # 基础请求封装
+│ ├── groupCourse.js # 团课真实API
+│ ├── groupCourse.mock.js # 团课模拟数据API
+│ └── envConfig.js # 环境配置与服务导出
+├── pages/
+│ └── groupCourse/
+│ └── list.vue # 团课列表页面
+└── components/ # 组件目录
+```
+
+---
+
+## 2. API 层设计
+
+### 2.1 架构设计
+
+| 层级 | 文件 | 职责 |
+|------|------|------|
+| 基础层 | `requestBase.js` | 封装 uni.request,统一处理加载状态、错误提示 |
+| 接口层 | `groupCourse.js` | 定义真实后端API接口 |
+| 模拟层 | `groupCourse.mock.js` | 提供模拟数据,支持开发测试 |
+| 配置层 | `envConfig.js` | 环境配置,统一服务导出入口 |
+
+### 2.2 环境切换机制
+
+通过修改 `envConfig.js` 中的 `ENV_MODE` 变量实现环境切换:
+
+```javascript
+// envConfig.js
+export const ENV_MODE = 'development' // 'production' | 'development'
+```
+
+- **`production`**:生产环境,使用真实网络请求
+- **`development`**:开发环境,使用模拟数据
+
+---
+
+## 3. 文件详细说明
+
+### 3.1 requestBase.js - 基础请求封装
+
+**功能定位**:封装 `uni.request`,提供统一的请求处理逻辑。
+
+**核心特性**:
+- 自动显示/隐藏加载提示
+- 统一的响应状态码处理
+- 统一的错误提示机制
+
+**接口定义**:
+
+| 方法 | 说明 | 参数 | 返回值 |
+|------|------|------|--------|
+| `request(options)` | 发起网络请求 | `options` 对象 | `Promise` |
+
+**options 参数**:
+
+| 参数 | 类型 | 必填 | 说明 |
+|------|------|------|------|
+| `url` | string | 是 | 请求路径 |
+| `method` | string | 否 | 请求方法,默认 `GET` |
+| `data` | object | 否 | 请求数据 |
+| `header` | object | 否 | 请求头 |
+
+**响应数据结构**:
+
+```javascript
+// 成功响应
+{
+ code: 0, // 状态码,0表示成功
+ message: 'success', // 提示信息
+ data: {} // 业务数据
+}
+```
+
+### 3.2 groupCourse.js - 团课真实 API
+
+**功能定位**:定义团课相关的真实后端接口。
+
+**接口列表**:
+
+| 方法 | 说明 | 参数 | HTTP方法 | 路径 |
+|------|------|------|----------|------|
+| `getList()` | 获取团课列表 | 无 | GET | `/api/groupCourse/list` |
+| `getDetail(id)` | 获取团课详情 | `id`: 课程ID | GET | `/api/groupCourse/detail/{id}` |
+| `book(data)` | 预约团课 | `data`: 预约数据 | POST | `/api/groupCourse/book` |
+| `cancelBooking(id)` | 取消预约 | `id`: 预约记录ID | POST | `/api/groupCourse/cancel/{id}` |
+
+**book 方法参数结构**:
+
+```javascript
+{
+ courseId: string, // 课程ID
+ memberId: string // 会员ID
+}
+```
+
+### 3.3 groupCourse.mock.js - 团课模拟数据 API
+
+**功能定位**:提供模拟数据,支持开发测试,无需后端服务。
+
+**特性**:
+- 模拟网络延迟(300-500ms)
+- 接口签名与真实API完全一致
+- 包含6条完整的模拟团课数据
+
+**模拟数据结构**:
+
+| 字段 | 类型 | 说明 |
+|------|------|------|
+| `id` | string | 课程唯一标识 |
+| `courseName` | string | 课程名称 |
+| `coachName` | string | 教练姓名 |
+| `coachAvatar` | string | 教练头像 |
+| `startTime` | string | 开始时间(ISO格式) |
+| `endTime` | string | 结束时间(ISO格式) |
+| `duration` | number | 课程时长(分钟) |
+| `location` | string | 上课地点 |
+| `maxMembers` | number | 最大人数 |
+| `currentMembers` | number | 当前人数 |
+| `storedValueAmount` | number | 储值卡价格(元) |
+| `pointCardAmount` | number | 次卡次数 |
+| `courseType` | string | 课程类型 |
+| `level` | string | 难度级别 |
+| `description` | string | 课程描述 |
+| `tags` | array | 标签列表 |
+| `status` | string | 状态(available/closed) |
+
+### 3.4 envConfig.js - 环境配置
+
+**功能定位**:统一服务导出入口,根据环境模式自动选择 API 实现。
+
+**导出内容**:
+
+| 导出项 | 类型 | 说明 |
+|--------|------|------|
+| `ENV_MODE` | string | 当前环境模式 |
+| `groupCourseService` | object | 团课服务实例 |
+
+---
+
+## 4. 使用示例
+
+### 4.1 在页面中使用
+
+```javascript
+// pages/groupCourse/list.vue
+import { groupCourseService } from '@/api/envConfig.js'
+
+// 获取团课列表
+const fetchCourseList = async () => {
+ try {
+ const data = await groupCourseService.getList()
+ courseList.value = data
+ console.log('团课列表获取成功:', data)
+ } catch (error) {
+ console.error('获取团课列表异常:', error)
+ }
+}
+```
+
+### 4.2 切换环境
+
+```javascript
+// api/envConfig.js
+// 开发环境 - 使用模拟数据
+export const ENV_MODE = 'development'
+
+// 生产环境 - 使用真实网络请求
+export const ENV_MODE = 'production'
+```
+
+---
+
+## 5. 数据流转图
+
+```
+┌─────────────────────────────────────────────────────────────┐
+│ 页面层 (View) │
+│ pages/groupCourse/list.vue │
+└───────────────────────────┬─────────────────────────────────┘
+ │ import & call
+ ▼
+┌─────────────────────────────────────────────────────────────┐
+│ 环境配置层 (Config) │
+│ api/envConfig.js │
+│ 根据 ENV_MODE 选择对应的服务实现 │
+└───────────────────────────┬─────────────────────────────────┘
+ │
+ ┌─────────────────┴─────────────────┐
+ ▼ ▼
+┌─────────────────────────┐ ┌─────────────────────────────┐
+│ groupCourse.js │ │ groupCourse.mock.js │
+│ (production 环境) │ │ (development 环境) │
+└───────────┬─────────────┘ └─────────────┬───────────────┘
+ │ │
+ ▼ ▼
+┌─────────────────────────┐ ┌─────────────────────┐
+│ requestBase.js │ │ 本地模拟数据 │
+│ (真实网络请求) │ │ (无需后端) │
+└───────────┬─────────────┘ └─────────────────────┘
+ │
+ ▼
+┌─────────────────────────┐
+│ 后端服务器 API │
+└─────────────────────────┘
+```
+
+---
+
+## 6. 注意事项
+
+1. **环境变量配置**:部署前务必确认 `ENV_MODE` 设置正确
+2. **数据一致性**:模拟数据结构应与真实API保持一致
+3. **错误处理**:所有API调用都应包含 try-catch 错误处理
+4. **日志记录**:建议在关键节点添加日志,便于调试
+
+---
+
+## 7. 版本历史
+
+| 版本 | 日期 | 更新内容 |
+|------|------|----------|
+| v1.0 | 2026-06-04 | 初始版本,完成基础API层设计 |
diff --git a/gym-manage-uniapp/pages/groupCourse/list.vue b/gym-manage-uniapp/pages/groupCourse/list.vue
new file mode 100644
index 0000000..4870609
--- /dev/null
+++ b/gym-manage-uniapp/pages/groupCourse/list.vue
@@ -0,0 +1,172 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 加载中...
+ 没有更多数据了
+ 点击加载更多
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file