Browse Source

feat: tabBar课程为列表;首页最近课程直达详情,按前中后阶段展示操作

liaoxg 1 week ago
parent
commit
6c45a3c

+ 47 - 15
train-backend/src/main/java/com/train/controller/CourseController.java

@@ -72,9 +72,10 @@ public class CourseController {
         return Result.success(courses);
     }
 
-    @Operation(summary = "当前学员所修课程")
+    @Operation(summary = "当前学员所修课程(可传 courseId 指定查询某一门课程)")
     @PostMapping("/current")
-    public Result<Map<String, Object>> current(@RequestAttribute("userId") Long userId) {
+    public Result<Map<String, Object>> current(@RequestBody(required = false) Map<String, Object> body,
+                                               @RequestAttribute("userId") Long userId) {
         Map<String, Object> data = new HashMap<>();
 
         TrainUser user = trainUserMapper.selectById(userId);
@@ -84,20 +85,35 @@ public class CourseController {
 
         TrainCourse course = null;
         TrainClass trainClass = null;
-        if (user.getClassId() != null) {
-            trainClass = trainClassMapper.selectById(user.getClassId());
-            if (trainClass != null && trainClass.getCourseId() != null) {
-                course = trainCourseMapper.selectById(trainClass.getCourseId());
-            }
-        }
+        Long targetCourseId = body != null && body.get("courseId") != null
+                ? Long.valueOf(body.get("courseId").toString()) : null;
 
-        if (course == null) {
-            // 兜底:未进班或课程未关联时,返回首个非下架课程(一般是 L0)
-            course = trainCourseMapper.selectOne(
-                    new LambdaQueryWrapper<TrainCourse>()
-                            .ne(TrainCourse::getStatus, "draft")
-                            .orderByAsc(TrainCourse::getLevel)
-                            .last("LIMIT 1"));
+        if (targetCourseId != null) {
+            // 指定课程:直接查该课程,并解析其中的班次/报名状态
+            course = trainCourseMapper.selectById(targetCourseId);
+            if (user.getClassId() != null) {
+                TrainClass myClass = trainClassMapper.selectById(user.getClassId());
+                // 仅当用户所在班次归属该课程时带上班级信息
+                if (myClass != null && targetCourseId.equals(myClass.getCourseId())) {
+                    trainClass = myClass;
+                }
+            }
+        } else {
+            // 未指定:按 user.class_id -> train_class.course_id 解析
+            if (user.getClassId() != null) {
+                trainClass = trainClassMapper.selectById(user.getClassId());
+                if (trainClass != null && trainClass.getCourseId() != null) {
+                    course = trainCourseMapper.selectById(trainClass.getCourseId());
+                }
+            }
+            if (course == null) {
+                // 兜底:未进班或课程未关联时,返回首个非下架课程(一般是 L0)
+                course = trainCourseMapper.selectOne(
+                        new LambdaQueryWrapper<TrainCourse>()
+                                .ne(TrainCourse::getStatus, "draft")
+                                .orderByAsc(TrainCourse::getLevel)
+                                .last("LIMIT 1"));
+            }
         }
 
         if (course == null) {
@@ -111,6 +127,22 @@ public class CourseController {
             data.put("classCode", trainClass.getCode());
             data.put("classTime", trainClass.getTime());
             data.put("classPlace", trainClass.getPlace());
+        } else {
+            // 未进班/未归属该课程时,给出该课程可申请进班的班次,方便报名后进班
+            List<Map<String, Object>> classes = trainClassMapper.selectList(
+                            new LambdaQueryWrapper<TrainClass>().eq(TrainClass::getCourseId, course.getId()))
+                    .stream().map(cl -> {
+                        Map<String, Object> m = new HashMap<>();
+                        m.put("id", cl.getId());
+                        m.put("name", cl.getName());
+                        m.put("code", cl.getCode());
+                        m.put("time", cl.getTime());
+                        m.put("place", cl.getPlace());
+                        return m;
+                    }).collect(java.util.stream.Collectors.toList());
+            if (!classes.isEmpty()) {
+                data.put("classes", classes);
+            }
         }
         // 学员在该课程下的报名/进班状态
         data.put("enrollment", myEnrollmentStatus(userId, course.getId()));

+ 1 - 1
train-frontend/pages.json

@@ -196,7 +196,7 @@
         "selectedIconPath": "static/tab-task-active.png"
       },
       {
-        "pagePath": "pages/course/detail",
+        "pagePath": "pages/course/index",
         "text": "课程",
         "iconPath": "static/tab-course.png",
         "selectedIconPath": "static/tab-course-active.png"

+ 131 - 95
train-frontend/pages/course/detail.vue

@@ -1,116 +1,96 @@
 <template>
   <view class="course-detail-page">
-    <!-- 课程信息 -->
+    <!-- 课程介绍 -->
     <view class="course-head">
       <text class="course-level">{{ course.level || 'L' }}</text>
       <text class="course-name">{{ course.name }}</text>
       <text class="course-status" :class="'st-' + course.effectiveStatus">{{ statusLabel(course.effectiveStatus) }}</text>
       <text class="course-desc" v-if="course.description">{{ course.description }}</text>
+      <text class="course-time" v-if="course.startTime || course.endTime">
+        开课 {{ fmtDate(course.startTime) }} · 结课 {{ fmtDate(course.endTime) }}
+      </text>
       <text class="course-class" v-if="className">我的班次:{{ className }}</text>
     </view>
 
-    <!-- 报名/参加课程操作区 -->
-    <view class="action-card" v-if="enrollmentStatus !== 'confirmed'">
-      <!-- 未报名 -->
-      <template v-if="enrollmentStatus === 'none'">
-        <text class="action-title">报名参加本课程</text>
-        <text class="action-desc">填写报名信息并支付后即可申请进班学习</text>
-        <button class="action-btn" @click="goTo('/pages/enroll/list')">去报名</button>
-      </template>
-      <!-- 待支付 -->
-      <template v-else-if="enrollmentStatus === 'pending'">
-        <text class="action-title">报名待支付</text>
-        <text class="action-desc">完成支付后即可申请进班</text>
-        <button class="action-btn" @click="goTo('/pages/enroll/list')">去支付</button>
-      </template>
-      <!-- 已支付待进班 -->
-      <template v-else-if="enrollmentStatus === 'paid'">
-        <text class="action-title">已报名,待进班</text>
-        <text class="action-desc">提交进班申请后由班主任审核,审核通过即可开始学习</text>
-        <button class="action-btn" :disabled="enterLoading" @click="applyEnter">申请进班</button>
-      </template>
-      <!-- 审核中 -->
-      <template v-else-if="enrollmentStatus === 'reviewing'">
-        <text class="action-title">进班审核中</text>
-        <text class="action-desc">班主任正在审核你的进班申请,请耐心等待</text>
-        <button class="action-btn disabled" disabled>审核中</button>
-      </template>
-      <!-- 已驳回 -->
-      <template v-else-if="enrollmentStatus === 'rejected'">
-        <text class="action-title">进班申请被驳回</text>
-        <text class="action-desc">可重新提交进班申请,或联系班主任了解原因</text>
-        <button class="action-btn" :disabled="enterLoading" @click="applyEnter">重新申请进班</button>
-      </template>
+    <!-- 未报名:先报名 -->
+    <view class="action-card" v-if="enrollmentStatus === 'none'">
+      <text class="action-title">报名参加本课程</text>
+      <text class="action-desc">填写报名信息并完成支付后,即可申请进班学习</text>
+      <button class="action-btn" @click="goTo('/pages/enroll/list')">去报名</button>
     </view>
 
-    <!-- 学习进度 -->
-    <view class="section-card" v-if="enrollmentStatus === 'confirmed'">
-      <view class="section-head">
-        <text class="section-title">学习进度</text>
-        <text class="progress-count">{{ progress.done }}/{{ progress.total }} 项完成</text>
-      </view>
-      <view class="progress-bar">
-        <view class="progress-fill" :style="{ width: progressPercent }"></view>
-      </view>
-      <view class="progress-list">
-        <view class="progress-item" v-for="(it, idx) in progress.items" :key="idx">
-          <text class="progress-icon" :class="{ done: it.ok }">{{ it.ok ? '✅' : '⬜' }}</text>
-          <text class="progress-label">{{ it.label }}</text>
-        </view>
-      </view>
+    <!-- 已报名未进班 -->
+    <view class="action-card" v-else-if="enrollmentStatus === 'pending'">
+      <text class="action-title">报名待支付</text>
+      <text class="action-desc">完成支付后即可申请进班</text>
+      <button class="action-btn" @click="goTo('/pages/enroll/list')">去支付</button>
+    </view>
+    <view class="action-card" v-else-if="enrollmentStatus === 'paid'">
+      <text class="action-title">已报名,待进班</text>
+      <text class="action-desc">提交进班申请后由班主任审核,审核通过即可开始学习</text>
+      <button class="action-btn" :disabled="enterLoading" @click="applyEnter">申请进班</button>
+    </view>
+    <view class="action-card" v-else-if="enrollmentStatus === 'reviewing'">
+      <text class="action-title">进班审核中</text>
+      <text class="action-desc">班主任正在审核你的进班申请,请耐心等待</text>
+      <button class="action-btn disabled" disabled>审核中</button>
+    </view>
+    <view class="action-card" v-else-if="enrollmentStatus === 'rejected'">
+      <text class="action-title">进班申请被驳回</text>
+      <text class="action-desc">可重新提交进班申请,或联系班主任了解原因</text>
+      <button class="action-btn" :disabled="enterLoading" @click="applyEnter">重新申请进班</button>
     </view>
 
-    <!-- 课程内功能入口 -->
-    <view v-if="enrollmentStatus === 'confirmed'">
-      <view class="section-title">课程内容</view>
-    <view class="nav-grid">
-      <view class="nav-item" @click="goTo('/pages/material/index')">
-        <text class="nav-icon">📄</text>
-        <text class="nav-text">课前资料</text>
-      </view>
-      <view class="nav-item" @click="goTo('/pages/group/index')">
-        <text class="nav-icon">👥</text>
-        <text class="nav-text">我的小组</text>
-      </view>
-      <view class="nav-item" @click="switchToTab('/pages/checkin/index')">
-        <text class="nav-icon">✅</text>
-        <text class="nav-text">装机打卡</text>
-      </view>
-      <view class="nav-item" @click="goTo('/pages/upload/index')">
-        <text class="nav-icon">📤</text>
-        <text class="nav-text">成果上传</text>
-      </view>
-      <view class="nav-item" @click="goTo('/pages/teaching/index')">
-        <text class="nav-icon">📝</text>
-        <text class="nav-text">教学卡</text>
-      </view>
-      <view class="nav-item" @click="goTo('/pages/roadmap/index')">
-        <text class="nav-icon">🎤</text>
-        <text class="nav-text">路演材料</text>
-      </view>
-      <view class="nav-item" @click="goTo('/pages/vote/index')">
-        <text class="nav-icon">🗳️</text>
-        <text class="nav-text">路演投票</text>
+    <!-- 已进班:按课程前/中/后阶段显示要做的事 -->
+    <template v-if="enrollmentStatus === 'confirmed'">
+      <!-- 课程前:课前准备 -->
+      <view class="stage-card" v-if="stage === 'upcoming'">
+        <text class="stage-icon">📅</text>
+        <view class="stage-text">
+          <text class="stage-title">课程即将开课</text>
+          <text class="stage-sub">先完成课前准备,做好学习规划</text>
+        </view>
       </view>
-      <view class="nav-item" @click="goTo('/pages/scoreboard/index')">
-        <text class="nav-icon">🏆</text>
-        <text class="nav-text">积分榜</text>
+      <!-- 课程中:学习进度 -->
+      <view class="section-card" v-if="stage === 'active'">
+        <view class="section-head">
+          <text class="section-title">学习进度</text>
+          <text class="progress-count">{{ progress.done }}/{{ progress.total }} 项完成</text>
+        </view>
+        <view class="progress-bar">
+          <view class="progress-fill" :style="{ width: progressPercent }"></view>
+        </view>
+        <view class="progress-list">
+          <view class="progress-item" v-for="(it, idx) in progress.items" :key="idx">
+            <text class="progress-icon" :class="{ done: it.ok }">{{ it.ok ? '✅' : '⬜' }}</text>
+            <text class="progress-label">{{ it.label }}</text>
+          </view>
+        </view>
       </view>
-      <view class="nav-item" @click="goTo('/pages/plan/index')">
-        <text class="nav-icon">📅</text>
-        <text class="nav-text">行动计划</text>
+      <!-- 课程后:结业事项 -->
+      <view class="stage-card" v-if="stage === 'finished'">
+        <text class="stage-icon">🎉</text>
+        <view class="stage-text">
+          <text class="stage-title">课程已结束</text>
+          <text class="stage-sub">完成结业事项,收获学习成果</text>
+        </view>
       </view>
-      <view class="nav-item" @click="goTo('/pages/assignment/index')">
-        <text class="nav-icon">📋</text>
-        <text class="nav-text">三本账</text>
+
+      <!-- 本阶段要做的事 -->
+      <view class="stage-title-block">本阶段要做的事</view>
+      <view class="nav-grid">
+        <view class="nav-item" v-for="(g, idx) in stageMenus" :key="idx" @click="onMenu(g)">
+          <text class="nav-icon">{{ g.icon }}</text>
+          <text class="nav-text">{{ g.text }}</text>
+        </view>
       </view>
-    </view>
-    </view>
+    </template>
   </view>
 </template>
 
 <script>
 import { getMyCourse, getCourseProgress, enterCourse } from '@/utils/api.js'
+import { formatDateTime } from '@/utils/format.js'
 
 export default {
   data() {
@@ -129,18 +109,56 @@ export default {
       var pct = Math.round((this.progress.done || 0) * 100 / total)
       return pct + '%'
     },
+    // 课程所处阶段:upcoming(前) / active(中) / finished(后) / draft
+    stage() {
+      return this.course.effectiveStatus || 'active'
+    },
     enrollmentStatus() {
       if (!this.enrollment || !this.enrollment.status) return 'none'
       return this.enrollment.status
+    },
+    stageMenus() {
+      if (this.stage === 'upcoming') {
+        // 课程前:课前准备
+        return [
+          { icon: '📄', text: '课前资料', url: '/pages/material/index' },
+          { icon: '📝', text: '兴趣调研', url: '/pages/survey/index' },
+          { icon: '📅', text: '行动计划', url: '/pages/plan/index' },
+          { icon: '👥', text: '我的小组', url: '/pages/group/index' }
+        ]
+      }
+      if (this.stage === 'finished') {
+        // 课程后:结业事项
+        return [
+          { icon: '📋', text: '三本账', url: '/pages/assignment/index' },
+          { icon: '📅', text: '行动计划', url: '/pages/plan/index' },
+          { icon: '🏆', text: '积分榜', url: '/pages/scoreboard/index' },
+          { icon: '🗳️', text: '路演投票', url: '/pages/vote/index' }
+        ]
+      }
+      // 课程中:学习内容
+      return [
+        { icon: '📄', text: '课前资料', url: '/pages/material/index' },
+        { icon: '👥', text: '我的小组', url: '/pages/group/index' },
+        { icon: '✅', text: '装机打卡', url: '/pages/checkin/index', tab: true },
+        { icon: '📤', text: '成果上传', url: '/pages/upload/index' },
+        { icon: '📝', text: '教学卡', url: '/pages/teaching/index' },
+        { icon: '🎤', text: '路演材料', url: '/pages/roadmap/index' },
+        { icon: '🗳️', text: '路演投票', url: '/pages/vote/index' },
+        { icon: '🏆', text: '积分榜', url: '/pages/scoreboard/index' },
+        { icon: '📅', text: '行动计划', url: '/pages/plan/index' },
+        { icon: '📋', text: '三本账', url: '/pages/assignment/index' }
+      ]
     }
   },
-  onLoad() {
+  onLoad(options) {
+    this.courseId = (options && options.courseId) || ''
     this.loadAll()
   },
   methods: {
     loadAll() {
       var self = this
-      getMyCourse().then(function(resp) {
+      getMyCourse(self.courseId).then(function(resp) {
         var d = resp.data || {}
         var c = d.course || {}
         self.course = c
@@ -156,6 +174,14 @@ export default {
         }
       }).catch(function() {})
     },
+    onMenu(g) {
+      if (!g) return
+      if (g.tab) {
+        uni.switchTab({ url: g.url })
+      } else {
+        uni.navigateTo({ url: g.url })
+      }
+    },
     applyEnter() {
       var self = this
       if (!self.course.id) return
@@ -194,11 +220,12 @@ export default {
       var map = { upcoming: '未开始', active: '进行中', finished: '已结束', draft: '未发布' }
       return map[st] || st || '-'
     },
+    fmtDate(v) {
+      if (!v) return '-'
+      return formatDateTime(v)
+    },
     goTo(url) {
       uni.navigateTo({ url: url })
-    },
-    switchToTab(url) {
-      uni.switchTab({ url: url })
     }
   }
 }
@@ -220,8 +247,17 @@ export default {
 .course-status.st-active { color: #22C55E; background: #F0FDF4; }
 .course-status.st-finished { color: #94A3B8; background: #F1F5F9; }
 .course-desc { font-size: 26rpx; color: #64748B; line-height: 1.6; margin-bottom: 8rpx; }
+.course-time { font-size: 24rpx; color: #94A3B8; margin-bottom: 8rpx; }
 .course-class { font-size: 24rpx; color: #1E293B; background: #F1F5F9; border-radius: 8rpx; padding: 8rpx 16rpx; align-self: flex-start; }
 
+.stage-card { display: flex; align-items: center; background: #FFF; border-radius: 16rpx; padding: 28rpx 32rpx; margin-bottom: 24rpx; }
+.stage-icon { font-size: 48rpx; margin-right: 20rpx; }
+.stage-text { display: flex; flex-direction: column; }
+.stage-title { font-size: 30rpx; font-weight: 700; color: #1E293B; margin-bottom: 6rpx; }
+.stage-sub { font-size: 24rpx; color: #64748B; }
+
+.stage-title-block { font-size: 30rpx; font-weight: 600; color: #1E293B; margin-bottom: 16rpx; border-left: 8rpx solid #F97316; padding-left: 16rpx; }
+
 .section-card { background: #FFF; border-radius: 16rpx; padding: 28rpx; margin-bottom: 24rpx; }
 .section-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 16rpx; }
 .section-title { font-size: 30rpx; font-weight: 600; color: #1E293B; border-left: 8rpx solid #F97316; padding-left: 16rpx; }

+ 1 - 1
train-frontend/pages/course/index.vue

@@ -103,7 +103,7 @@ export default {
       if (!c) return
       var s = c.myStatus
       if (s === 'confirmed') {
-        uni.switchTab({ url: '/pages/course/detail' })
+        uni.navigateTo({ url: '/pages/course/detail?courseId=' + c.id })
       } else if (s === 'pending') {
         uni.navigateTo({ url: '/pages/enroll/list' })
       } else if (s === 'paid' || s === 'rejected') {

+ 51 - 15
train-frontend/pages/index/index.vue

@@ -26,7 +26,7 @@
 
     <view class="section-title">日常服务</view>
     <view class="nav-grid">
-      <view class="nav-item" @click="switchToTab('/pages/course/detail')">
+      <view class="nav-item" @click="switchToTab('/pages/course/index')">
         <text class="nav-icon">📚</text>
         <text class="nav-text">课程</text>
       </view>
@@ -44,13 +44,19 @@
       </view>
     </view>
 
-    <view class="course-hint" @click="switchToTab('/pages/course/detail')">
-      <text class="course-hint-icon">📖</text>
-      <view class="course-hint-text">
-        <text class="course-hint-title">{{ courseLabel }} 课程内容</text>
-        <text class="course-hint-sub">课前资料 · 小组 · 打卡 · 成果上传 · 路演 · 积分榜…</text>
+    <view class="section-title">最近课程</view>
+    <view class="course-mini-list">
+      <view class="course-mini-card" v-for="(c, idx) in recentCourses" :key="idx" @click="goToCourse(c)">
+        <view class="course-mini-head">
+          <text class="course-mini-level">{{ c.level || 'L' }}</text>
+          <text class="course-mini-name">{{ c.name }}</text>
+          <text class="course-mini-status" :class="'st-' + c.effectiveStatus">{{ statusLabel(c.effectiveStatus) }}</text>
+        </view>
+        <text class="course-mini-desc" v-if="c.description">{{ c.description }}</text>
+      </view>
+      <view class="course-mini-empty" v-if="!recentCourses.length && isLoggedIn">
+        <text class="course-mini-empty-text">暂无课程</text>
       </view>
-      <text class="course-hint-arrow">›</text>
     </view>
 
     <!-- Login Bottom Sheet -->
@@ -75,7 +81,7 @@
 </template>
 
 <script>
-import { getMyGroup, getClassInfo, wechatLogin, getMyCourse } from '@/utils/api.js'
+import { getMyGroup, getClassInfo, wechatLogin, getMyCourse, getCourseList } from '@/utils/api.js'
 
 export default {
   data() {
@@ -83,6 +89,7 @@ export default {
       groupInfo: null,
       classInfo: null,
       courseName: '',
+      recentCourses: [],
       loginSheetVisible: false,
       loginLoading: false
     }
@@ -149,6 +156,29 @@ export default {
           self.courseName = (c.level ? c.level + ' ' : '') + c.name
         }
       }).catch(function() {})
+      // 最近课程:优先取进行中/未开始,最多 3 门
+      getCourseList().then(function(resp) {
+        var list = resp.data || []
+        var sorted = list.slice().sort(function(a, b) {
+          return rankOf(a) - rankOf(b)
+        })
+        self.recentCourses = sorted.slice(0, 3)
+      }).catch(function() {})
+    },
+    rankOf(c) {
+      var st = c && c.effectiveStatus
+      if (st === 'active') return 0
+      if (st === 'upcoming') return 1
+      if (st === 'finished') return 2
+      return 3
+    },
+    statusLabel(st) {
+      var map = { upcoming: '未开始', active: '进行中', finished: '已结束', draft: '未发布' }
+      return map[st] || st || '-'
+    },
+    goToCourse(c) {
+      if (!c || !c.id) return
+      uni.navigateTo({ url: '/pages/course/detail?courseId=' + c.id })
     },
     showLoginSheet() {
       this.loginSheetVisible = true
@@ -240,13 +270,19 @@ export default {
 .nav-item:active { background: #F8FAFC; }
 .nav-icon { font-size: 44rpx; margin-bottom: 8rpx; }
 .nav-text { font-size: 24rpx; color: #1E293B; text-align: center; }
-.course-hint { display: flex; align-items: center; background: #FFF; border-radius: 16rpx; padding: 28rpx 32rpx; margin-top: 20rpx; }
-.course-hint:active { background: #F8FAFC; }
-.course-hint-icon { font-size: 48rpx; margin-right: 20rpx; }
-.course-hint-text { flex: 1; display: flex; flex-direction: column; }
-.course-hint-title { font-size: 28rpx; font-weight: 600; color: #1E293B; margin-bottom: 6rpx; }
-.course-hint-sub { font-size: 24rpx; color: #64748B; }
-.course-hint-arrow { font-size: 36rpx; color: #CBD5E1; }
+.course-mini-list { display: flex; flex-direction: column; margin-top: 20rpx; }
+.course-mini-card { background: #FFF; border-radius: 16rpx; padding: 24rpx 28rpx; margin-bottom: 16rpx; }
+.course-mini-card:active { background: #F8FAFC; }
+.course-mini-head { display: flex; align-items: center; margin-bottom: 8rpx; }
+.course-mini-level { font-size: 22rpx; font-weight: 600; color: #F97316; background: #FFF7ED; border-radius: 8rpx; padding: 4rpx 14rpx; margin-right: 16rpx; }
+.course-mini-name { font-size: 28rpx; font-weight: 600; color: #1E293B; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
+.course-mini-status { font-size: 22rpx; border-radius: 6rpx; padding: 4rpx 14rpx; }
+.course-mini-status.st-upcoming { color: #F97316; background: #FFF7ED; }
+.course-mini-status.st-active { color: #22C55E; background: #F0FDF4; }
+.course-mini-status.st-finished { color: #94A3B8; background: #F1F5F9; }
+.course-mini-desc { font-size: 24rpx; color: #64748B; line-height: 1.5; overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 1; -webkit-box-orient: vertical; }
+.course-mini-empty { background: #FFF; border-radius: 16rpx; padding: 48rpx 0; text-align: center; }
+.course-mini-empty-text { font-size: 26rpx; color: #94A3B8; }
 
 /* Bottom Sheet Styles */
 .login-sheet-mask {

+ 1 - 1
train-frontend/pages/login/index.vue

@@ -59,7 +59,7 @@ export default {
               if (!data.alumniVerify || data.alumniVerify === 'pending') {
                 uni.redirectTo({ url: '/pages/verify/index' })
               } else if (!data.classId) {
-                uni.switchTab({ url: '/pages/course/detail' })
+                uni.switchTab({ url: '/pages/course/index' })
               } else {
                 uni.switchTab({ url: '/pages/index/index' })
               }

+ 1 - 1
train-frontend/pages/mine/index.vue

@@ -76,7 +76,7 @@
       </view>
     </view>
 
-    <view class="course-entry" @click="switchToTab('/pages/course/detail')">
+    <view class="course-entry" @click="switchToTab('/pages/course/index')">
       <text class="course-entry-icon">📖</text>
       <view class="course-entry-text">
         <text class="course-entry-title">课程内容</text>

+ 1 - 1
train-frontend/pages/verify/index.vue

@@ -108,7 +108,7 @@ export default {
           uni.showToast({ title: '校验通过', icon: 'success' })
           setTimeout(function() {
 if (!self.$store.state.classId) {
-              uni.switchTab({ url: '/pages/course/detail' })
+              uni.switchTab({ url: '/pages/course/index' })
             } else {
               uni.switchTab({ url: '/pages/index/index' })
             }

+ 6 - 2
train-frontend/utils/api.js

@@ -110,8 +110,12 @@ export const getClassInfo = () => {
 export const getCourseList = () => {
   return request('/api/course/list', 'POST')
 }
-export const getMyCourse = () => {
-  return request('/api/course/current', 'POST')
+export const getMyCourse = (courseId) => {
+  var data = {}
+  if (courseId) {
+    data = { courseId }
+  }
+  return request('/api/course/current', 'POST', data)
 }
 export const enterCourse = (courseId) => {
   return request('/api/course/enter', 'POST', { courseId })