diff --git a/src/api/modules/course.ts b/src/api/modules/course.ts index c226973..ab7aca6 100644 --- a/src/api/modules/course.ts +++ b/src/api/modules/course.ts @@ -544,11 +544,71 @@ export class CourseApi { } // 报名课程 - static enrollCourse(courseId: number): Promise> { - return ApiRequest.post(`/courses/${courseId}/enroll`) + try { + console.log('🔍 报名课程,课程ID:', courseId) + console.log('🔍 API请求URL: /biz/course/' + courseId + '/enroll') + + const response = await ApiRequest.post(`/biz/course/${courseId}/enroll`) + console.log('🔍 报名API响应:', response) + + // 处理后端响应格式 + if (response.data && typeof response.data === 'object') { + // 如果响应包含success字段,使用标准格式 + if ('success' in response.data) { + return { + code: response.data.code || 0, + message: response.data.message || '报名成功', + data: { + success: response.data.success || false, + message: response.data.message || '', + result: response.data + } + } + } + } + + // 默认返回成功状态 + return { + code: 0, + message: '报名成功', + data: { + success: true, + message: '报名成功', + result: null + } + } + } catch (error: any) { + console.error('❌ 课程报名失败:', error) + + // 如果是401错误,说明未登录 + if (error.response?.status === 401) { + return { + code: 401, + message: '请先登录', + data: { + success: false, + message: '请先登录', + result: null + } + } + } + + // 其他错误 + return { + code: error.response?.status || 500, + message: error.message || '报名失败', + data: { + success: false, + message: error.message || '报名失败', + result: null + } + } + } } // 取消报名 @@ -556,6 +616,81 @@ export class CourseApi { return ApiRequest.delete(`/courses/${courseId}/enroll`) } + // 检查课程报名状态 + static async checkEnrollmentStatus(courseId: string): Promise> { + try { + console.log('🔍 检查课程报名状态,课程ID:', courseId) + console.log('🔍 API请求URL: /biz/course/' + courseId + '/is_enrolled') + + const response = await ApiRequest.get(`/biz/course/${courseId}/is_enrolled`) + console.log('🔍 报名状态API响应:', response) + + // 处理后端响应格式 + if (response.data && typeof response.data === 'object') { + // 如果响应包含success字段,使用标准格式 + if ('success' in response.data) { + return { + code: response.data.code || 0, + message: response.data.message || '', + data: { + result: response.data.result || false, + message: response.data.message + } + } + } + + // 如果直接返回result字段 + if ('result' in response.data) { + return { + code: 0, + message: '查询成功', + data: { + result: response.data.result || false, + message: response.data.message + } + } + } + } + + // 默认返回未报名状态 + return { + code: 0, + message: '查询成功', + data: { + result: false, + message: '未报名' + } + } + } catch (error: any) { + console.error('❌ 检查课程报名状态失败:', error) + + // 如果是401错误,说明未登录 + if (error.response?.status === 401) { + return { + code: 401, + message: '请先登录', + data: { + result: false, + message: '请先登录' + } + } + } + + // 其他错误,默认返回未报名状态 + return { + code: error.response?.status || 500, + message: error.message || '查询失败', + data: { + result: false, + message: error.message || '查询失败' + } + } + } + } + // 获取课程章节列表 static async getCourseSections(courseId: string): Promise> { try { diff --git a/src/views/CourseDetail.vue b/src/views/CourseDetail.vue index 2de69f4..4862871 100644 --- a/src/views/CourseDetail.vue +++ b/src/views/CourseDetail.vue @@ -1300,26 +1300,48 @@ const confirmEnrollment = async () => { try { enrollmentLoading.value = true - // 模拟API调用 - await new Promise(resolve => setTimeout(resolve, 1000)) + console.log('开始报名课程,课程ID:', courseId.value) - // 报名成功 - isEnrolled.value = true - enrollConfirmVisible.value = false - enrollSuccessVisible.value = true + // 调用报名API + const response = await CourseApi.enrollCourse(String(courseId.value)) - // 2秒后跳转到已报名状态的课程详情页面并刷新 - setTimeout(() => { - enrollSuccessVisible.value = false - // 跳转到已报名状态页面 - router.push(`/course/${courseId.value}/enrolled`).then(() => { - // 手动刷新页面 - window.location.reload(); - }) - }, 2000) + if (response.code === 0 && response.data && response.data.success) { + // 检查是否是已经报名的情况 + if (response.data.result && typeof response.data.result === 'object' && response.data.result.code === 'already_enrolled') { + // 用户已经报名,直接跳转到已报名页面 + console.log('用户已经报名该课程,直接跳转到已报名页面') + isEnrolled.value = true + enrollConfirmVisible.value = false + router.push(`/course/${courseId.value}/enrolled`) + return + } - } catch (error) { + // 新报名成功 + console.log('报名成功:', response.data.message) + isEnrolled.value = true + enrollConfirmVisible.value = false + enrollSuccessVisible.value = true + + // 2秒后跳转到已报名状态的课程详情页面并刷新 + setTimeout(() => { + enrollSuccessVisible.value = false + // 跳转到已报名状态页面 + router.push(`/course/${courseId.value}/enrolled`).then(() => { + // 手动刷新页面 + window.location.reload(); + }) + }, 2000) + } else { + // 报名失败 + const errorMessage = response.data?.message || response.message || '报名失败' + console.error('报名失败:', errorMessage) + alert('报名失败:' + errorMessage) + } + + } catch (error: any) { console.error('报名失败:', error) + const errorMessage = error.response?.data?.message || error.message || '网络错误,请稍后重试' + alert('报名失败:' + errorMessage) } finally { enrollmentLoading.value = false } @@ -1330,6 +1352,30 @@ const cancelEnrollment = () => { enrollConfirmVisible.value = false } +// 检查用户报名状态 +const checkUserEnrollmentStatus = async () => { + if (!userStore.isLoggedIn) { + isEnrolled.value = false + return + } + + try { + console.log('检查用户报名状态,课程ID:', courseId.value) + const response = await CourseApi.checkEnrollmentStatus(String(courseId.value)) + + if (response.code === 0 && response.data) { + isEnrolled.value = response.data.result + console.log('用户报名状态:', isEnrolled.value ? '已报名' : '未报名') + } else { + console.warn('检查报名状态失败:', response.message) + isEnrolled.value = false + } + } catch (error) { + console.error('检查报名状态时发生错误:', error) + isEnrolled.value = false + } +} + // 处理未报名用户点击 const handleUnregisteredClick = (section: CourseSection) => { console.log('未报名用户点击课程:', section.name) @@ -1374,13 +1420,14 @@ const initializeMockState = () => { userStore.token = 'mock-token' } - // 模拟用户未报名状态,可以测试完整的报名流程 - isEnrolled.value = false // false=未报名状态,true=已报名状态 + // 不再强制设置报名状态,而是通过API检查真实状态 + // isEnrolled.value = false // 注释掉强制设置 } -onMounted(() => { +onMounted(async () => { console.log('课程详情页加载完成,课程ID:', courseId.value) initializeMockState() // 初始化模拟状态 + await checkUserEnrollmentStatus() // 检查用户报名状态 loadCourseDetail() loadCourseSections() // 启用章节接口调用 loadCourseInstructors() // 启用讲师接口调用 diff --git a/src/views/Courses.vue b/src/views/Courses.vue index 6217654..15c4fee 100644 --- a/src/views/Courses.vue +++ b/src/views/Courses.vue @@ -162,8 +162,10 @@ import { ref, computed, onMounted } from 'vue' import { useRouter } from 'vue-router' import type { Course, CourseCategory, CourseSubject, CourseDifficulty } from '@/api/types' import { CourseApi } from '@/api' +import { useUserStore } from '@/stores/user' const router = useRouter() +const userStore = useUserStore() // 课程数据和加载状态 const courses = ref([]) @@ -419,11 +421,51 @@ const getCourseInstructors = (course: Course) => { } // 跳转到课程详情页 -const goToCourseDetail = (course: Course) => { - router.push({ - name: 'CourseDetail', - params: { id: course.id } - }) +const goToCourseDetail = async (course: Course) => { + try { + // 检查用户是否已登录 + if (!userStore.isLoggedIn) { + console.log('用户未登录,跳转到课程详情页') + router.push({ + name: 'CourseDetail', + params: { id: course.id } + }) + return + } + + console.log('检查课程报名状态,课程ID:', course.id) + + // 调用报名状态检查接口 + const response = await CourseApi.checkEnrollmentStatus(String(course.id)) + + if ((response.code === 0 || response.code === 200) && response.data) { + const isEnrolled = response.data.result + + if (isEnrolled) { + // 已报名,跳转到已报名页面 + console.log('用户已报名,跳转到已报名页面') + router.push(`/course/${course.id}/enrolled`) + } else { + // 未报名,跳转到课程详情页 + console.log('用户未报名,跳转到课程详情页') + router.push(`/course/${course.id}`) + } + } else { + // 查询失败,默认跳转到课程详情页 + console.warn('查询报名状态失败,跳转到课程详情页') + router.push({ + name: 'CourseDetail', + params: { id: course.id } + }) + } + } catch (error) { + console.error('检查报名状态时发生错误:', error) + // 发生错误时,默认跳转到课程详情页 + router.push({ + name: 'CourseDetail', + params: { id: course.id } + }) + } } // 选择排序方式 diff --git a/src/views/Home.vue b/src/views/Home.vue index 34cf0ad..a2a1aea 100644 --- a/src/views/Home.vue +++ b/src/views/Home.vue @@ -521,12 +521,12 @@