This commit is contained in:
Admin 2025-08-20 21:55:23 +08:00
commit c6bcb136ad
5 changed files with 338 additions and 36 deletions

View File

@ -544,11 +544,71 @@ export class CourseApi {
}
// 报名课程
static enrollCourse(courseId: number): Promise<ApiResponse<{
enrollmentId: number
static async enrollCourse(courseId: string): Promise<ApiResponse<{
success: boolean
message: string
result?: any
}>> {
return ApiRequest.post(`/courses/${courseId}/enroll`)
try {
console.log('🔍 报名课程课程ID:', courseId)
console.log('🔍 API请求URL: /biz/course/' + courseId + '/enroll')
const response = await ApiRequest.post<any>(`/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<ApiResponse<{
result: boolean
message?: string
}>> {
try {
console.log('🔍 检查课程报名状态课程ID:', courseId)
console.log('🔍 API请求URL: /biz/course/' + courseId + '/is_enrolled')
const response = await ApiRequest.get<any>(`/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<ApiResponse<CourseSectionListResponse>> {
try {

View File

@ -1300,10 +1300,24 @@ const confirmEnrollment = async () => {
try {
enrollmentLoading.value = true
// API
await new Promise(resolve => setTimeout(resolve, 1000))
console.log('开始报名课程课程ID:', courseId.value)
//
// API
const response = await CourseApi.enrollCourse(String(courseId.value))
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
}
//
console.log('报名成功:', response.data.message)
isEnrolled.value = true
enrollConfirmVisible.value = false
enrollSuccessVisible.value = true
@ -1317,9 +1331,17 @@ const confirmEnrollment = async () => {
window.location.reload();
})
}, 2000)
} else {
//
const errorMessage = response.data?.message || response.message || '报名失败'
console.error('报名失败:', errorMessage)
alert('报名失败:' + errorMessage)
}
} catch (error) {
} 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() //

View File

@ -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<Course[]>([])
@ -419,11 +421,51 @@ const getCourseInstructors = (course: Course) => {
}
//
const goToCourseDetail = (course: Course) => {
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 }
})
}
}
//

View File

@ -521,12 +521,12 @@
<script setup lang="ts">
import { onMounted, computed, ref } from 'vue'
import { useI18n } from 'vue-i18n'
import { useRouter } from 'vue-router'
import { useCourseStore } from '@/stores/course'
import { useUserStore } from '@/stores/user'
import { useAuth } from '@/composables/useAuth'
import { CourseApi } from '@/api'
import LoginModal from '@/components/auth/LoginModal.vue'
import RegisterModal from '@/components/auth/RegisterModal.vue'
// import { getPopularCourses } from '@/data/mockCourses'
@ -534,6 +534,7 @@ import RegisterModal from '@/components/auth/RegisterModal.vue'
const { t, locale } = useI18n()
const router = useRouter()
const courseStore = useCourseStore()
const userStore = useUserStore()
const { loginModalVisible, registerModalVisible, handleAuthSuccess } = useAuth()
// 广
@ -720,8 +721,42 @@ const partners = computed(() => [
// ])
//
const goToCourseDetail = (courseId: string) => {
const goToCourseDetail = async (courseId: string) => {
try {
//
if (!userStore.isLoggedIn) {
console.log('用户未登录,跳转到课程详情页')
router.push(`/course/${courseId}`)
return
}
console.log('检查课程报名状态课程ID:', courseId)
//
const response = await CourseApi.checkEnrollmentStatus(String(courseId))
if ((response.code === 0 || response.code === 200) && response.data) {
const isEnrolled = response.data.result
if (isEnrolled) {
//
console.log('用户已报名,跳转到已报名页面')
router.push(`/course/${courseId}/enrolled`)
} else {
//
console.log('用户未报名,跳转到课程详情页')
router.push(`/course/${courseId}`)
}
} else {
//
console.warn('查询报名状态失败,跳转到课程详情页')
router.push(`/course/${courseId}`)
}
} catch (error) {
console.error('检查报名状态时发生错误:', error)
//
router.push(`/course/${courseId}`)
}
}
// -

View File

@ -128,9 +128,12 @@ const toggleFollow = () => {
}
import { useRouter } from 'vue-router'
import type { Course } from '@/api/types'
import { CourseApi } from '@/api'
import { useUserStore } from '@/stores/user'
// import { mockCourses } from '@/data/mockCourses'
const router = useRouter()
const userStore = useUserStore()
//
const courses = ref<Course[]>([])
@ -556,11 +559,51 @@ const getCourseTitle = (course: Course) => {
}
//
const goToCourseDetail = (course: Course) => {
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 }
})
}
}
//