feat(课程): 添加课程组合列表接口并优化课程列表页面
添加获取课程组合列表的API接口 将课程列表页面从分页加载改为一次性加载 根据接口返回数据动态设置显示模式
Showing
2 changed files
with
35 additions
and
30 deletions
| 1 | /* | 1 | /* |
| 2 | * @Date: 2025-04-15 09:32:07 | 2 | * @Date: 2025-04-15 09:32:07 |
| 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com | 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com |
| 4 | - * @LastEditTime: 2025-06-16 11:34:00 | 4 | + * @LastEditTime: 2025-10-21 16:37:51 |
| 5 | * @FilePath: /mlaj/src/api/course.js | 5 | * @FilePath: /mlaj/src/api/course.js |
| 6 | * @Description: 课程模块相关接口 | 6 | * @Description: 课程模块相关接口 |
| 7 | */ | 7 | */ |
| ... | @@ -11,6 +11,7 @@ const Api = { | ... | @@ -11,6 +11,7 @@ const Api = { |
| 11 | GET_COURSE_LIST: '/srv/?a=schedule&t=list', | 11 | GET_COURSE_LIST: '/srv/?a=schedule&t=list', |
| 12 | GET_COURSE_DETAIL: '/srv/?a=schedule&t=detail', | 12 | GET_COURSE_DETAIL: '/srv/?a=schedule&t=detail', |
| 13 | GET_SCHEDULE_COURSE: '/srv/?a=schedule&t=course', | 13 | GET_SCHEDULE_COURSE: '/srv/?a=schedule&t=course', |
| 14 | + GET_SCHEDULE_COMBINATION_LIST: '/srv/?a=schedule&t=combination_list', | ||
| 14 | GET_GROUP_COMMENT_LIST: '/srv/?a=group_comment_list', | 15 | GET_GROUP_COMMENT_LIST: '/srv/?a=group_comment_list', |
| 15 | GROUP_COMMENT_ADD: '/srv/?a=group_comment_add', | 16 | GROUP_COMMENT_ADD: '/srv/?a=group_comment_add', |
| 16 | GROUP_COMMENT_EDIT: '/srv/?a=group_comment_edit', | 17 | GROUP_COMMENT_EDIT: '/srv/?a=group_comment_edit', |
| ... | @@ -45,6 +46,13 @@ export const getCourseDetailAPI = (params) => fn(fetch.get(Api.GET_COURSE_DETAIL | ... | @@ -45,6 +46,13 @@ export const getCourseDetailAPI = (params) => fn(fetch.get(Api.GET_COURSE_DETAIL |
| 45 | export const getScheduleCourseAPI = (params) => fn(fetch.get(Api.GET_SCHEDULE_COURSE, params)) | 46 | export const getScheduleCourseAPI = (params) => fn(fetch.get(Api.GET_SCHEDULE_COURSE, params)) |
| 46 | 47 | ||
| 47 | /** | 48 | /** |
| 49 | + * @description: 获取课程组合列表 | ||
| 50 | + * @param: id 课程 ID | ||
| 51 | + * @return: data: [{ id, title, price, original_price, feature, highlights, count, cover}] | ||
| 52 | + */ | ||
| 53 | +export const getScheduleCombinationListAPI = (params) => fn(fetch.get(Api.GET_SCHEDULE_COMBINATION_LIST, params)) | ||
| 54 | + | ||
| 55 | +/** | ||
| 48 | * @description: 获取课程评论列表 | 56 | * @description: 获取课程评论列表 |
| 49 | * @param: i 课程 ID | 57 | * @param: i 课程 ID |
| 50 | * @param: schedule_id 章节ID,非必须,在课程章节内查询时需要 | 58 | * @param: schedule_id 章节ID,非必须,在课程章节内查询时需要 | ... | ... |
| 1 | <!-- | 1 | <!-- |
| 2 | * @Date: 2025-03-21 14:31:21 | 2 | * @Date: 2025-03-21 14:31:21 |
| 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com | 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com |
| 4 | - * @LastEditTime: 2025-05-21 16:57:36 | 4 | + * @LastEditTime: 2025-10-21 17:12:13 |
| 5 | * @FilePath: /mlaj/src/views/courses/CourseListQRPage.vue | 5 | * @FilePath: /mlaj/src/views/courses/CourseListQRPage.vue |
| 6 | * @Description: 课程列表页面 - 支持列表和卡片两种显示模式 | 6 | * @Description: 课程列表页面 - 支持列表和卡片两种显示模式 |
| 7 | --> | 7 | --> |
| ... | @@ -10,13 +10,10 @@ | ... | @@ -10,13 +10,10 @@ |
| 10 | <div class="pb-16"> | 10 | <div class="pb-16"> |
| 11 | <!-- Course List --> | 11 | <!-- Course List --> |
| 12 | <div class="px-4"> | 12 | <div class="px-4"> |
| 13 | - <van-list | 13 | + <div v-if="loading" class="flex justify-center py-8"> |
| 14 | - v-model:loading="loading" | 14 | + <van-loading size="24px">加载中...</van-loading> |
| 15 | - :finished="finished" | 15 | + </div> |
| 16 | - finished-text="没有更多课程了" | 16 | + <div v-else class="space-y-4"> |
| 17 | - @load="onLoad" | ||
| 18 | - class="space-y-4" | ||
| 19 | - > | ||
| 20 | <!-- 根据type参数显示不同组件 --> | 17 | <!-- 根据type参数显示不同组件 --> |
| 21 | <template v-if="displayType === 'card'"> | 18 | <template v-if="displayType === 'card'"> |
| 22 | <CourseImageCard v-for="course in courses" :key="course.id" :course="course" /> | 19 | <CourseImageCard v-for="course in courses" :key="course.id" :course="course" /> |
| ... | @@ -24,7 +21,7 @@ | ... | @@ -24,7 +21,7 @@ |
| 24 | <template v-else> | 21 | <template v-else> |
| 25 | <CourseCard v-for="course in courses" :key="course.id" :course="course" /> | 22 | <CourseCard v-for="course in courses" :key="course.id" :course="course" /> |
| 26 | </template> | 23 | </template> |
| 27 | - </van-list> | 24 | + </div> |
| 28 | </div> | 25 | </div> |
| 29 | </div> | 26 | </div> |
| 30 | </AppLayout> | 27 | </AppLayout> |
| ... | @@ -37,45 +34,45 @@ import AppLayout from '@/components/layout/AppLayout.vue'; | ... | @@ -37,45 +34,45 @@ import AppLayout from '@/components/layout/AppLayout.vue'; |
| 37 | import CourseCard from '@/components/ui/CourseCard.vue'; | 34 | import CourseCard from '@/components/ui/CourseCard.vue'; |
| 38 | import CourseImageCard from '@/components/ui/CourseImageCard.vue'; | 35 | import CourseImageCard from '@/components/ui/CourseImageCard.vue'; |
| 39 | // 导入接口 | 36 | // 导入接口 |
| 40 | -import { getCourseListAPI } from "@/api/course"; | 37 | +import { getScheduleCombinationListAPI } from "@/api/course"; |
| 41 | -import { List } from 'vant'; | ||
| 42 | 38 | ||
| 43 | const $route = useRoute(); | 39 | const $route = useRoute(); |
| 44 | const courses = ref([]); | 40 | const courses = ref([]); |
| 45 | const loading = ref(false); | 41 | const loading = ref(false); |
| 46 | -const finished = ref(false); | ||
| 47 | -const limit = ref(5); | ||
| 48 | -const page = ref(0); | ||
| 49 | 42 | ||
| 50 | -// 根据URL参数确定显示类型 | 43 | +// 显示类型,默认列表模式 |
| 51 | -const displayType = computed(() => { | 44 | +const displayType = ref('list'); |
| 52 | - return $route.query.type || 'list'; // 默认为list模式 | ||
| 53 | -}); | ||
| 54 | 45 | ||
| 55 | // 获取URL参数中的ID | 46 | // 获取URL参数中的ID |
| 56 | const courseId = computed(() => { | 47 | const courseId = computed(() => { |
| 57 | return $route.query.id || ''; | 48 | return $route.query.id || ''; |
| 58 | }); | 49 | }); |
| 59 | 50 | ||
| 60 | -// Load more courses | 51 | +// 加载课程数据 |
| 61 | -const onLoad = async () => { | 52 | +const loadCourses = async () => { |
| 62 | - const nextPage = page.value; | 53 | + loading.value = true; |
| 63 | - const params = { | 54 | + const params = {}; |
| 64 | - limit: limit.value, | ||
| 65 | - page: nextPage | ||
| 66 | - }; | ||
| 67 | 55 | ||
| 68 | // 如果有ID参数,添加到请求中 | 56 | // 如果有ID参数,添加到请求中 |
| 69 | if (courseId.value) { | 57 | if (courseId.value) { |
| 70 | params.id = courseId.value; | 58 | params.id = courseId.value; |
| 71 | } | 59 | } |
| 72 | 60 | ||
| 73 | - const res = await getCourseListAPI(params); | 61 | + try { |
| 62 | + const res = await getScheduleCombinationListAPI(params); | ||
| 74 | if (res.code) { | 63 | if (res.code) { |
| 75 | - courses.value = [...courses.value, ...res.data]; | 64 | + courses.value = res.data.group_list; |
| 76 | - finished.value = res.data.length < limit.value; | 65 | + displayType.value = res.data.display_mode; |
| 77 | - page.value = nextPage + 1; | ||
| 78 | } | 66 | } |
| 67 | + } catch (error) { | ||
| 68 | + console.error('加载课程失败:', error); | ||
| 69 | + } finally { | ||
| 79 | loading.value = false; | 70 | loading.value = false; |
| 71 | + } | ||
| 80 | }; | 72 | }; |
| 73 | + | ||
| 74 | +// 页面挂载时加载数据 | ||
| 75 | +onMounted(() => { | ||
| 76 | + loadCourses(); | ||
| 77 | +}); | ||
| 81 | </script> | 78 | </script> | ... | ... |
-
Please register or login to post a comment