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 @@ + + + + + \ 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 @@ + + + + + \ 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 @@ + + + + + \ 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 @@ + + + + + \ 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 @@ + + + + + \ 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