feat: 课程详情页面线性进度展示

This commit is contained in:
2024-09-20 16:15:23 +08:00
parent edb4231140
commit 3492fc6c5c
4 changed files with 81 additions and 24 deletions

View File

@ -2,6 +2,7 @@
import BussApi from '@/api/BussApi';
import pageWrapper from '@/components/page-wrapper.vue';
import type { Lesson } from '@/types/api/lesson';
import { calcLessonProgress } from '@/utils/lesson';
import { useRouter } from 'uni-mini-router';
import { onMounted, ref } from 'vue';
import { useToast } from 'wot-design-uni';
@ -10,7 +11,7 @@ const toast = useToast()
const router = useRouter()
const expandedCourse = ref(['lesson'])
const groupLessons = ref<{ [key: string]: Lesson[] }>({})
const groupedLessons = ref<{ [key: string]: Lesson[] }>({})
const openLessonDetail = (courseId: number) => {
router.push({
@ -21,13 +22,6 @@ const openLessonDetail = (courseId: number) => {
})
}
const calcProgress = (course: Lesson) => {
const total = 4
let finished = 0
if (!!course?.script_file) finished++
return Math.floor((finished / total) * 100)
}
onMounted(() => {
toast.loading({
msg: '加载中...'
@ -41,7 +35,9 @@ onMounted(() => {
acc[cur.m_lesson_name].push(cur)
return acc
}, {})
groupLessons.value = groupData
groupedLessons.value = groupData
}).catch(err => {
toast.error({ msg: err.message })
})
})
</script>
@ -50,19 +46,21 @@ onMounted(() => {
<page-wrapper>
<div>
<wd-collapse v-model="expandedCourse">
<wd-status-tip v-if="Object.keys(groupLessons).length === 0" image="content" tip="没有课" />
<wd-collapse-item v-else v-for="(lessons, lessonName) in groupLessons" :title="`${lessonName || '无标题课程'}`"
:name="`${lessonName}`" :key="lessonName">
<wd-status-tip v-if="Object.keys(groupedLessons).length === 0" image="content" tip="没有课" />
<wd-collapse-item v-else v-for="(courses, courseName) in groupedLessons" :title="`${courseName || '无标题课程'}`"
:name="`${courseName}`" :key="courseName">
<div class="w-full">
<wd-status-tip v-if="lessons.length === 0" image="content" tip="没有微课视频" />
<div v-else v-for="(course, i) in lessons" :key="i" @click="openLessonDetail(course.id)"
<wd-status-tip v-if="courses.length === 0" image="content" tip="没有课程小节" />
<div v-else v-for="(lesson, i) in courses" :key="i" @click="openLessonDetail(lesson.id)"
class="w-full py-2 flex justify-between items-center gap-20 border-b border-b-solid border-neutral-200 last:border-b-0 first:pt-0 last:pb-0">
<div class="flex items-center gap-1">
<wd-icon :name="calcProgress(course) === 100 ? 'check-circle' : 'hourglass'" size="16px"></wd-icon>
<span>{{ course.course_name || '无标题视频' }}</span>
<wd-icon
:name="calcLessonProgress(lesson) === 100 ? 'check-circle' : (calcLessonProgress(lesson) === 0 ? 'circle1' : 'hourglass')"
size="16px"></wd-icon>
<span>{{ lesson.course_name || '无标题视频' }}</span>
</div>
<div class="w-32 flex items-center gap-3">
<wd-progress :percentage="calcProgress(course)" />
<wd-progress :percentage="calcLessonProgress(lesson)" hide-text />
<wd-icon name="arrow-right" size="16px" class="op-85"></wd-icon>
</div>
</div>

View File

@ -1,14 +1,17 @@
<script lang="ts" setup>
import BussApi from '@/api/BussApi';
import type { Lesson } from '@/types/api/lesson';
import { calcLessonProgress, extractLessonStage, getLessonSteps } from '@/utils/lesson';
import { useRoute } from 'uni-mini-router';
import { onMounted, ref } from 'vue';
import { computed, onMounted, ref } from 'vue';
import { useToast } from 'wot-design-uni';
const route = useRoute()
const toast = useToast()
const course = ref<Lesson | null>(null)
const lesson = ref<Lesson | null>(null)
const lessonSteps = computed(() => lesson.value ? getLessonSteps(lesson.value) : [])
const lessonStages = computed(() => lesson.value ? extractLessonStage(lesson.value) : null)
onMounted(() => {
if (!route.params?.courseId) {
@ -22,17 +25,22 @@ onMounted(() => {
})
BussApi.course(route.params.courseId).then(courseData => {
toast.close()
course.value = courseData
lesson.value = courseData
}).catch(err => {
toast.error({ msg: err.message })
})
})
</script>
<template>
<div>
<pre>{{ JSON.stringify(course, null, 2) }}</pre>
<div class="p-4">
<wd-steps :active="lessonStages?.step || 0" vertical>
<wd-step v-for="(step, index) in lessonSteps" :key="index" :title="step.title"
:description="step.description" />
</wd-steps>
</div>
</div>
</template>
<style scoped>
</style>
<style scoped></style>