OL-LearnPlatform/ENROLLMENT_STATUS_UPDATE.md
2025-08-04 02:13:12 +08:00

6.7 KiB
Raw Blame History

课程详情页报名状态功能更新说明

🎯 更新目标

实现课程详情页面的完整报名状态管理,包括:

  1. 判断登录和报名状态
  2. 未报名状态显示灰色不可点击样式
  3. 点击立即报名弹出确认提示框
  4. 确认后跳转到已报名的课程详情页面
  5. 更新右侧课程章节头部样式

📋 功能实现

1. 报名状态管理

// 报名状态管理
const isEnrolled = ref(false) // 用户是否已报名该课程
const enrollmentLoading = ref(false) // 报名加载状态

// 计算用户是否已报名
const isUserEnrolled = computed(() => {
  // 必须同时满足:用户已登录 AND 已报名该课程
  return userStore.isLoggedIn && isEnrolled.value
})

// 报名确认弹窗
const enrollConfirmVisible = ref(false)
const enrollSuccessVisible = ref(false)

2. 报名流程处理

// 处理课程报名
const handleEnrollCourse = () => {
  if (!userStore.isLoggedIn) {
    // 未登录,显示登录弹窗
    showLoginModal()
    return
  }
  
  if (isEnrolled.value) {
    // 已报名,直接跳转到学习页面
    router.push(`/course/${courseId.value}/study`)
    return
  }
  
  // 未报名,显示报名确认弹窗
  enrollConfirmVisible.value = true
}

// 确认报名
const confirmEnrollment = async () => {
  try {
    enrollmentLoading.value = true
    
    // 模拟API调用
    await new Promise(resolve => setTimeout(resolve, 1000))
    
    // 报名成功
    isEnrolled.value = true
    enrollConfirmVisible.value = false
    enrollSuccessVisible.value = true
    
    // 2秒后自动跳转
    setTimeout(() => {
      enrollSuccessVisible.value = false
      router.push(`/course/${courseId.value}/study`)
    }, 2000)
    
  } catch (error) {
    console.error('报名失败:', error)
  } finally {
    enrollmentLoading.value = false
  }
}

3. 课程章节状态控制

<div class="lesson-content" 
     :class="{ 'unregistered': !isUserEnrolled }" 
     @click="isUserEnrolled ? handleSectionClick(section) : handleUnregisteredClick(section)">
  
  <div class="lesson-type-badge" 
       :class="[getLessonTypeBadgeClass(section), { 'disabled': !isUserEnrolled }]">
    {{ getLessonTypeText(section) }}
  </div>
  
  <div class="lesson-info">
    <span class="lesson-title" :class="{ 'disabled': !isUserEnrolled }">
      {{ section.name }}
    </span>
  </div>
  
  <div class="lesson-actions">
    <button class="lesson-action-btn" 
            :class="{ 'disabled': !isUserEnrolled }"
            :disabled="!isUserEnrolled"
            @click.stop="isUserEnrolled ? handleSectionClick(section) : handleUnregisteredClick(section)">
      <!-- 图标 -->
    </button>
  </div>
</div>

4. 报名确认弹窗

<!-- 报名确认弹窗 -->
<div v-if="enrollConfirmVisible" class="modal-overlay" @click="cancelEnrollment">
  <div class="modal-content" @click.stop>
    <div class="modal-header">
      <h3>确认报名</h3>
      <button class="modal-close" @click="cancelEnrollment">×</button>
    </div>
    <div class="modal-body">
      <p>确定要报名《{{ course?.title }}》课程吗?</p>
      <p class="modal-tip">报名后您将获得完整的学习权限</p>
    </div>
    <div class="modal-footer">
      <button class="btn-cancel" @click="cancelEnrollment">取消</button>
      <button class="btn-confirm" @click="confirmEnrollment" :disabled="enrollmentLoading">
        {{ enrollmentLoading ? '报名中...' : '确认报名' }}
      </button>
    </div>
  </div>
</div>

<!-- 报名成功弹窗 -->
<div v-if="enrollSuccessVisible" class="modal-overlay">
  <div class="modal-content success-modal">
    <div class="success-icon"></div>
    <h3>报名成功!</h3>
    <p>正在跳转到学习页面...</p>
  </div>
</div>

🎨 样式更新

1. 课程章节头部样式

根据图片标准更新:

<div class="sections-header">
  <div class="header-left">
    <h3 class="sections-title">课程章节</h3>
  </div>
  <div class="header-right">
    <button class="sort-btn">
      <svg class="sort-icon">...</svg>
      <span class="sort-text">正序</span>
    </button>
  </div>
</div>
.sections-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 20px;
  background: white;
  border-bottom: 1px solid #f0f0f0;
}

.sections-title {
  font-size: 18px;
  font-weight: 600;
  color: #333;
  margin: 0;
}

.sort-btn {
  background: none;
  border: none;
  color: #999;
  padding: 6px 12px;
  border-radius: 4px;
  cursor: pointer;
  font-size: 14px;
  display: flex;
  align-items: center;
  gap: 6px;
}

2. 未报名状态灰色样式

/* 未报名状态的灰色样式 */
.lesson-content.unregistered {
  cursor: not-allowed;
}

.lesson-title.disabled {
  color: #999;
}

.lesson-duration.disabled {
  color: #999;
}

.lesson-type-badge.disabled {
  background: #d9d9d9 !important;
  color: #999 !important;
}

.lesson-action-btn.disabled {
  cursor: not-allowed;
  opacity: 0.5;
}

.lesson-action-btn.disabled svg {
  color: #d9d9d9 !important;
}

.completion-icon.disabled {
  opacity: 0.5;
}

3. 弹窗样式

.modal-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
}

.modal-content {
  background: white;
  border-radius: 8px;
  max-width: 400px;
  width: 90%;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
}

.success-modal {
  text-align: center;
  padding: 40px 24px;
}

.success-icon {
  width: 60px;
  height: 60px;
  background: #52c41a;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0 auto 20px;
  font-size: 30px;
  color: white;
  font-weight: bold;
}

功能流程

未登录用户

  1. 点击"立即报名" → 显示登录弹窗
  2. 登录成功后 → 显示报名确认弹窗
  3. 确认报名 → 显示报名成功提示 → 跳转学习页面

已登录未报名用户

  1. 点击"立即报名" → 显示报名确认弹窗
  2. 确认报名 → 显示报名成功提示 → 跳转学习页面
  3. 点击课程章节 → 显示报名确认弹窗

已报名用户

  1. 点击"立即报名" → 直接跳转学习页面
  2. 点击课程章节 → 正常进入学习

🎯 视觉效果

未报名状态

  • 课程章节显示为灰色
  • 所有按钮不可点击
  • 鼠标悬停显示禁用状态

已报名状态

  • 课程章节显示为彩色
  • 所有功能正常可用
  • 正常的交互反馈

章节头部

  • 简洁的"课程章节"标题
  • 右侧排序按钮带图标
  • 符合图片设计标准

现在课程详情页面具备完整的报名状态管理功能!🎉