202 lines
4.5 KiB
Vue
202 lines
4.5 KiB
Vue
<template>
|
|
<view class="chapter-detail-page">
|
|
<!-- 自定义导航栏 -->
|
|
<nav-bar :title="$t('courseDetails.chapter')" />
|
|
|
|
<!-- 页面内容 -->
|
|
<view class="page-content">
|
|
<!-- 课程视频 -->
|
|
<AliPlayer
|
|
:video-list="videoList"
|
|
:current-index="currentVideoIndex !== null ? currentVideoIndex : 0"
|
|
:course="{courseTitle:courseTitle, chapterTitle: chapterTitle}"
|
|
:cover="curriculumImgUrl || ''"
|
|
/>
|
|
|
|
<!-- 选项卡 -->
|
|
<wd-tabs v-model="currentTab" class="tabs-section" lineWidth="30">
|
|
<!-- 章节介绍 -->
|
|
<wd-tab name="chapterIntro" :title="$t('courseDetails.chapterIntro')">
|
|
<!-- 章节封面 -->
|
|
<image
|
|
v-if="chapterDetail?.imgUrl"
|
|
:src="chapterDetail.imgUrl"
|
|
mode="widthFix"
|
|
class="chapter-image"
|
|
@click="previewImage(chapterDetail.imgUrl)"
|
|
/>
|
|
|
|
<!-- 章节内容 -->
|
|
<view v-if="chapterDetail?.content" v-html="chapterDetail.content"></view>
|
|
|
|
<view class="copyright">
|
|
<text>{{ $t('courseDetails.copyright') }}</text>
|
|
</view>
|
|
</wd-tab>
|
|
<!-- 思考题 -->
|
|
<wd-tab v-if="chapterDetail?.questions" name="thinkingQuestion" :title="$t('courseDetails.thinkingQuestion')">
|
|
<view v-html="chapterDetail.questions"></view>
|
|
<!-- <view v-else class="no-question">
|
|
<wd-divider>{{ $t('courseDetails.noQuestion') }}</wd-divider>
|
|
</view> -->
|
|
</wd-tab>
|
|
</wd-tabs>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { ref } from 'vue'
|
|
import { onLoad } from '@dcloudio/uni-app'
|
|
import { courseApi } from '@/api/modules/course'
|
|
import AliPlayer from '@/components/ali-video/index.vue'
|
|
import type { IChapterDetail } from '@/types/course'
|
|
import type { IVideoInfo } from '@/types/video'
|
|
|
|
// 页面参数
|
|
const chapterId = ref<number>(0)
|
|
const courseTitle = ref('')
|
|
const chapterTitle = ref('')
|
|
const curriculumImgUrl = ref('')
|
|
|
|
// 页面数据
|
|
const chapterDetail = ref<IChapterDetail | null>(null)
|
|
const videoList = ref<IVideoInfo[]>([])
|
|
const currentVideoIndex = ref(0)
|
|
const activeVideoIndex = ref(0)
|
|
const currentTab = ref('chapterIntro')
|
|
|
|
// 视频播放器引用
|
|
const videoPlayerRef = ref<any>(null)
|
|
|
|
/**
|
|
* 页面加载
|
|
*/
|
|
onLoad((options: any) => {
|
|
chapterId.value = parseInt(options.id)
|
|
courseTitle.value = options.courseTitle || ''
|
|
chapterTitle.value = options.title || ''
|
|
curriculumImgUrl.value = options.curriculumImgUrl || ''
|
|
|
|
loadChapterDetail()
|
|
})
|
|
|
|
/**
|
|
* 加载章节详情
|
|
*/
|
|
const loadChapterDetail = async () => {
|
|
const res = await courseApi.getChapterDetail(chapterId.value)
|
|
if (res.code === 0 && res.data) {
|
|
chapterDetail.value = res.data.detail
|
|
videoList.value = res.data.videos || []
|
|
|
|
// 如果有历史播放记录,定位到对应视频
|
|
if (res.data.current) {
|
|
const index = videoList.value.findIndex((v:any) => v.id === res.data.current)
|
|
if (index !== -1) {
|
|
currentVideoIndex.value = index
|
|
activeVideoIndex.value = index
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 预览图片
|
|
*/
|
|
const previewImage = (url: string) => {
|
|
uni.previewImage({
|
|
urls: [url],
|
|
current: url
|
|
})
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.chapter-detail-page {
|
|
min-height: 100vh;
|
|
background-color: #f5f5f5;
|
|
}
|
|
|
|
.video-section {
|
|
background-color: #000;
|
|
height: 400rpx;
|
|
}
|
|
|
|
.info-section {
|
|
padding: 20rpx;
|
|
background-color: #fff;
|
|
|
|
.info-item {
|
|
margin-bottom: 15rpx;
|
|
font-size: 26rpx;
|
|
color: #666;
|
|
|
|
&:last-child {
|
|
margin-bottom: 0;
|
|
}
|
|
|
|
.label {
|
|
color: #999;
|
|
}
|
|
|
|
.value {
|
|
color: #333;
|
|
}
|
|
}
|
|
}
|
|
|
|
.video-list-section {
|
|
padding: 20rpx;
|
|
background-color: #fff;
|
|
margin-top: 20rpx;
|
|
|
|
.section-title {
|
|
font-size: 32rpx;
|
|
font-weight: 500;
|
|
color: #2979ff;
|
|
margin-bottom: 20rpx;
|
|
}
|
|
}
|
|
|
|
.tabs-section {
|
|
background-color: #fff;
|
|
margin-top: 20rpx;
|
|
|
|
:deep(.wd-tabs__nav) {
|
|
border-bottom: 1px solid #2979ff;
|
|
}
|
|
:deep(.wd-tab__body) {
|
|
padding: 30rpx;
|
|
font-size: 28rpx;
|
|
line-height: 1.8;
|
|
color: #666;
|
|
word-break: break-all;
|
|
}
|
|
:deep(.wd-tabs__line) {
|
|
bottom: 0;
|
|
}
|
|
}
|
|
|
|
.chapter-image {
|
|
width: 100%;
|
|
display: block;
|
|
margin-bottom: 20rpx;
|
|
border-radius: 8rpx;
|
|
}
|
|
|
|
.copyright {
|
|
margin-top: 20rpx;
|
|
padding-top: 20rpx;
|
|
border-top: 1px solid #f0f0f0;
|
|
text-align: center;
|
|
font-size: 24rpx;
|
|
color: #ff4444;
|
|
}
|
|
|
|
.no-question {
|
|
padding: 80rpx 0;
|
|
text-align: center;
|
|
}
|
|
</style>
|