You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
653 lines
16 KiB
653 lines
16 KiB
<template> |
|
<div class="wrap pb"> |
|
<breadcrumb :routes.sync="routes" /> |
|
<div class="flex"> |
|
<div class="cover" :class="{ 'is-word': showMask1 }"> |
|
<img v-if="coverUrl" :src="coverUrl" alt="" width="100%" height="100%"> |
|
<template v-else-if="iframeSrc"> |
|
<iframe class="inner fileIframe" id="fileIframe" :src="iframeSrc" frameborder="0"></iframe> |
|
<template v-if="showMask"> |
|
<div class="mask" style="width: 500px;height: 30px;top: 53px;right: 320px"></div> |
|
<div class="mask" style="width: 175px;height: 30px;top: 53px;right: 5px"></div> |
|
</template> |
|
<template v-if="showMask1"> |
|
<div class="word-mask" style="height: 40px;"></div> |
|
<div class="word-mask2" style="top: 55px;left: 28%;width: 44%;height: calc(100% - 80px);"></div> |
|
</template> |
|
<template v-if="showMask2"> |
|
<div class="excel-mask1" style="height: 48px;"></div> |
|
</template> |
|
</template> |
|
<div class="pdf inner" v-else-if="pdfSrc"> |
|
<p class="arrow"> |
|
<span @click="changePdfPage(0)" class="turn el-icon-arrow-left" :class="{ grey: currentPage == 1 }"></span> |
|
{{ currentPage }} / {{ pageCount }} |
|
<span @click="changePdfPage(1)" class="turn el-icon-arrow-right" |
|
:class="{ grey: currentPage == pageCount }"></span> |
|
</p> |
|
<pdf class="pdf-wrap" :src="pdfSrc" :page="currentPage" @num-pages="pageCount = $event" |
|
@page-loaded="currentPage = $event" @loaded="loadPdfHandler"> |
|
</pdf> |
|
</div> |
|
<div class="inner" v-else-if="playAuth"> |
|
<div class="video_wid" id="player"></div> |
|
</div> |
|
<div class="inner" v-else-if="videoSrc"> |
|
<video class="video" :key="videoSrc" width="100%" height="100%" autoplay controls> |
|
<source :src="videoSrc" type="video/mp4"> |
|
您的浏览器不支持 video 标签。 |
|
</video> |
|
</div> |
|
</div> |
|
<div class="catalog"> |
|
<div class="list"> |
|
<h4 class="title">{{ courseName }}</h4> |
|
<div class="desc-wrap"> |
|
<div class="desc" :class="{ active: desShrink }" v-html="description"></div> |
|
<i class="arrow" :class="{ active: desShrink }" v-if="description && description.length > 40"> |
|
</i> |
|
</div> |
|
<div class="chapters"> |
|
<template v-if="chapterList && chapterList.length"> |
|
<div class="chapter" v-for="(item, index) in chapterList" :key="index"> |
|
<div class="chapterName">{{ item.name }}</div> |
|
<div class="section" v-if="item.subsectionList.length"> |
|
<div v-for="(section, i) in item.subsectionList" :key="i" @click="preview(section, item.name)"> |
|
<p class="sectionName" :class="{ active: curLink === `${item.name}${section.name}` }"> |
|
<img v-if="section.fileType === 'pptx'" src="@/assets/img/exts/ppt.png" alt=""> |
|
<img v-else-if="section.fileType === 'mp4'" src="@/assets/img/exts/video.png" alt=""> |
|
<img v-else-if="section.fileType === 'doc' || section.fileType === 'docx'" |
|
src="@/assets/img/exts/word.png" alt=""> |
|
<img v-else-if="section.fileType === 'txt'" src="@/assets/img/exts/txt.png" alt=""> |
|
<img v-else-if="section.fileType === 'pdf'" src="@/assets/img/exts/pdf.png" alt=""> |
|
<img v-else src="@/assets/img/exts/pic.png" alt=""> |
|
{{ section.name }} |
|
</p> |
|
</div> |
|
</div> |
|
</div> |
|
</template> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
</template> |
|
|
|
<script> |
|
import { mapState, mapMutations } from 'vuex'; |
|
import pdf from "vue-pdf"; |
|
import 'quill/dist/quill.core.css'; |
|
import 'quill/dist/quill.snow.css'; |
|
import 'quill/dist/quill.bubble.css'; |
|
import breadcrumb from '@/components/breadcrumb' |
|
import Setting from "@/setting" |
|
import util from "@/libs/util" |
|
export default { |
|
data () { |
|
return { |
|
routes: [], |
|
startTime: Date.now(), // 页面进来的时间 |
|
id: this.$route.query.id, |
|
video: '', |
|
chapterList: [], |
|
courseName: '', |
|
description: '', |
|
coverUrl: '', |
|
playAuth: '', |
|
player: null, |
|
previewImg: '', |
|
iframeSrc: '', |
|
videoSrc: '', |
|
isWord: false, |
|
isPPT: false, |
|
isExcel: false, |
|
showMask: false, |
|
showMask1: false, |
|
showMask2: false, |
|
closePosi: { |
|
top: '80px' |
|
}, |
|
pdfVisible: false, |
|
pdfSrc: '', |
|
currentPage: 0, // pdf文件页码 |
|
pageCount: 0, // pdf文件总页数 |
|
fileType: 'pdf', // 文件类型 |
|
desShrink: false, |
|
curLink: "", // 当前选中 |
|
}; |
|
}, |
|
computed: { |
|
...mapState({ |
|
courseId: state => state.courseId, |
|
classId: state => state.classId, |
|
}), |
|
}, |
|
components: { pdf, breadcrumb }, |
|
mounted () { |
|
this.insertScript() |
|
this.getData() |
|
}, |
|
destroyed () { |
|
// 记录播放时长 |
|
util.session.get(Setting.tokenKey) && this.$post(this.api.playRecordSave, { |
|
courseId: this.id, |
|
courseType: 1, |
|
playTime: Math.ceil((Date.now() - this.startTime) / 1000 / 60) |
|
}).then(({ data }) => { }).catch(res => { }) |
|
}, |
|
methods: { |
|
...mapMutations('project', [ |
|
'SET_COURSE' |
|
]), |
|
getData () { |
|
this.$post(`${this.api.findByIdCourse}?id=${this.id}`).then(({ data }) => { |
|
this.courseName = data.courseName |
|
this.description = data.courseIntroduction |
|
this.coverUrl = data.coverUrl || 'https://huoran.oss-cn-shenzhen.aliyuncs.com/20220224/png/1496735335294984192.png' |
|
this.getChapter() |
|
|
|
const path = this.$store.state.course.referrer |
|
this.routes = [ |
|
{ |
|
name: '课程学习', |
|
path |
|
}, |
|
{ |
|
name: this.$route.query.source == 1 ? '本校课程' : '共享课程', |
|
path |
|
}, |
|
{ |
|
name: this.courseName |
|
} |
|
] |
|
}).catch(res => { }) |
|
}, |
|
async getChapter () { |
|
let res = await this.$get(`${this.api.queryChaptersAndSubsections}?courseId=${this.id}`) |
|
this.chapterList = res.chapterList |
|
if (this.chapterList.length && this.chapterList[0].subsectionList && this.chapterList[0].subsectionList.length) { |
|
this.preview(this.chapterList[0].subsectionList[0], this.chapterList[0].name, 0); |
|
} |
|
}, |
|
insertScript () { |
|
const linkTag = document.createElement('link'); |
|
linkTag.rel = 'stylesheet'; |
|
linkTag.href = 'https://g.alicdn.com/de/prismplayer/2.8.2/skins/default/aliplayer-min.css'; |
|
document.body.appendChild(linkTag); |
|
|
|
const scriptTag = document.createElement('script'); |
|
scriptTag.type = 'text/javascript'; |
|
scriptTag.src = 'https://g.alicdn.com/de/prismplayer/2.8.2/aliplayer-min.js'; |
|
document.body.appendChild(scriptTag); |
|
}, |
|
transferType (ext) { |
|
const suf = ext.toLowerCase() |
|
if ('jpg,jpeg,png,gif,svg,psd'.includes(suf)) return '图片' |
|
if ('mp4,3gp,mov,m4v,avi,dat,mkv,flv,vob,rmvb,rm,qlv'.includes(suf)) return '视频' |
|
return suf |
|
}, |
|
preview (row, chapterName, showConfirm = 1) { |
|
// 如果没登录,直接去登录 |
|
if (!util.session.get(Setting.tokenKey) && !util.local.get('oc_server_token') && showConfirm) { |
|
this.$confirm('请先登录,是否直接前往登录?', "提示", { |
|
type: 'success', |
|
closeOnClickModal: false |
|
}).then(() => { |
|
this.SET_COURSE(this.id) |
|
this.$router.push('/login') |
|
}).catch(() => { }) |
|
return false |
|
} |
|
this.curLink = `${chapterName}${row.name}`; |
|
this.playauth = '' |
|
this.coverUrl = '' |
|
this.pdfSrc = '' |
|
this.iframeSrc = '' |
|
this.isPPT = false |
|
this.isWord = false |
|
this.isExcel = false |
|
if (this.transferType(row.fileType) == '视频') { |
|
// 阿里云视频点播 |
|
if (row.fileId) { |
|
this.$get(`${this.api.getPlayAuth}/${row.fileId}`).then(res => { |
|
this.playAuth = res.playAuth |
|
// 如果已经产生了实例,则销毁重新创建,不然播放器会播放上一个视频 |
|
if (this.player) { |
|
this.player.dispose() |
|
this.player = null |
|
} |
|
this.$nextTick(() => { |
|
if (this.player) { |
|
this.player.replayByVidAndPlayAuth(row.fileId, this.playAuth); |
|
} else { |
|
this.player = new Aliplayer({ |
|
id: "player", |
|
width: "100%", |
|
autoplay: false, |
|
vid: row.fileId, |
|
playauth: this.playAuth, |
|
encryptType: 1 //当播放私有加密流时需要设置。 |
|
}); |
|
} |
|
}); |
|
}).catch(res => { }) |
|
} else { |
|
this.videoSrc = row.fileUrl |
|
} |
|
} else if (this.transferType(row.fileType) == '图片') { |
|
this.coverUrl = row.fileUrl |
|
} else if (row.fileType == 'pdf') { |
|
this.pdfSrc = row.fileUrl |
|
this.pdfVisible = true |
|
} else { |
|
this.$get(`${this.api.getSubsection}?subsectionId=${row.id}`).then(res => { |
|
if (row.fileType == 'pptx') { |
|
this.isPPT = true |
|
this.isWord = false |
|
this.isExcel = false |
|
} else if (row.fileType == 'doc' || row.fileType == 'docx') { |
|
this.isPPT = false |
|
this.isWord = true |
|
this.isExcel = false |
|
} else if (row.fileType == 'xls' || row.fileType == 'xlsx') { |
|
this.isExcel = true |
|
this.isPPT = false |
|
this.isWord = false |
|
} else { |
|
this.isPPT = false |
|
this.isWord = false |
|
this.isExcel = false |
|
} |
|
if (this.isPPT) { |
|
this.showMask = true |
|
} else { |
|
this.showMask = false |
|
} |
|
if (this.isWord) { |
|
this.showMask1 = true |
|
} else { |
|
this.showMask1 = false |
|
} |
|
if (this.isExcel) { |
|
this.showMask2 = true |
|
} else { |
|
this.showMask2 = false |
|
} |
|
this.iframeSrc = res.previewUrl |
|
}) |
|
.catch(err => { |
|
}); |
|
} |
|
}, |
|
closePlayer () { |
|
this.playAuth = '' |
|
this.player.pause() |
|
}, |
|
closeIframe () { |
|
this.iframeSrc = '' |
|
this.showMask = false |
|
this.showMask1 = false |
|
}, |
|
closePdf () { |
|
this.pdfSrc = '' |
|
this.currentPage = 1 |
|
}, |
|
changePdfPage (val) { |
|
if (val === 0 && this.currentPage > 1) { |
|
this.currentPage-- |
|
} |
|
if (val === 1 && this.currentPage < this.pageCount) { |
|
this.currentPage++ |
|
} |
|
}, |
|
loadPdfHandler (e) { |
|
this.currentPage = 1 |
|
} |
|
} |
|
}; |
|
</script> |
|
<style> |
|
.desc img { |
|
width: 100%; |
|
} |
|
</style> |
|
<style lang="scss" scoped> |
|
$height: 700px; |
|
|
|
.video_wid, |
|
.cover { |
|
position: relative; |
|
width: 76%; |
|
height: $height !important; |
|
border: 0; |
|
} |
|
|
|
.page { |
|
margin: 12px 0; |
|
|
|
.intro { |
|
font-size: 16px; |
|
color: #333; |
|
line-height: 24px; |
|
} |
|
} |
|
|
|
.cover { |
|
flex: 1; |
|
background-color: #252528; |
|
|
|
img { |
|
border-radius: 8px; |
|
} |
|
|
|
&.is-word { |
|
overflow: hidden; |
|
} |
|
} |
|
|
|
.fileIframe { |
|
height: $height !important; |
|
} |
|
|
|
.video_wid, |
|
.inner { |
|
width: 100%; |
|
height: 100% !important; |
|
border: 0; |
|
overflow: auto; |
|
} |
|
|
|
.cover.is-word { |
|
.inner { |
|
height: calc(100% + 38px) !important; |
|
margin-top: -38px; |
|
} |
|
} |
|
|
|
.video_wid:focus { |
|
outline: none; |
|
} |
|
|
|
.catalog { |
|
width: 296px; |
|
padding: 16px; |
|
margin-left: 12px; |
|
background-color: #252528; |
|
|
|
.entry { |
|
display: block; |
|
width: 100%; |
|
height: 34px; |
|
margin-bottom: 16px; |
|
background: url(../../../assets/img/entry.png) 0 0/100% 100% no-repeat; |
|
cursor: pointer; |
|
|
|
&:hover { |
|
opacity: 0.9; |
|
} |
|
} |
|
} |
|
|
|
.list { |
|
height: calc(700px - 82px); |
|
overflow-y: auto; |
|
|
|
.title { |
|
margin-bottom: 11px; |
|
color: #fff; |
|
font-size: 16px; |
|
} |
|
|
|
.desc-wrap { |
|
position: relative; |
|
|
|
.desc { |
|
font-size: 12px; |
|
color: #fff; |
|
line-height: 22px; |
|
@include mul-ellipsis(4); |
|
|
|
&.active { |
|
display: block; |
|
overflow: visible; |
|
} |
|
} |
|
|
|
.arrow { |
|
position: absolute; |
|
bottom: 2px; |
|
right: 0; |
|
display: flex; |
|
justify-content: space-between; |
|
width: 46px; |
|
background-color: #fff; |
|
|
|
span { |
|
font-size: 14px; |
|
color: rgba(0, 0, 0, 0.65); |
|
} |
|
|
|
img { |
|
width: 16px; |
|
cursor: pointer; |
|
} |
|
|
|
&.active { |
|
span { |
|
opacity: 0; |
|
} |
|
|
|
img { |
|
transform: rotate(180deg); |
|
} |
|
} |
|
} |
|
} |
|
|
|
.chapters { |
|
margin-top: 16px; |
|
max-height: calc(100% - 53px); |
|
overflow: auto; |
|
} |
|
|
|
.chapter { |
|
margin-bottom: 20px; |
|
|
|
.chapterName { |
|
color: #fff; |
|
font-size: 14px; |
|
} |
|
|
|
.section { |
|
padding: 5px 15px; |
|
margin-top: 12px; |
|
background-color: #121214; |
|
|
|
.sectionName { |
|
margin: 12px 0; |
|
font-size: 12px; |
|
color: #999; |
|
cursor: pointer; |
|
@include ellipsis; |
|
|
|
img { |
|
margin-right: 8px; |
|
} |
|
|
|
&.active { |
|
color: #fff; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
.el-image-viewer__wrapper { |
|
transform: translateY(-10px); |
|
transition: transform 0.5s; |
|
|
|
&.active { |
|
transform: translateY(0); |
|
} |
|
} |
|
|
|
.el-image-viewer__close { |
|
z-index: 2000; |
|
top: 15px; |
|
right: 15px; |
|
|
|
&.doc-close { |
|
i { |
|
color: #000 !important; |
|
} |
|
} |
|
} |
|
|
|
.list::-webkit-scrollbar { |
|
width: 4px; |
|
} |
|
|
|
.list::-webkit-scrollbar-thumb { |
|
border-radius: 10px; |
|
background: rgba(0, 0, 0, 0.06); |
|
} |
|
|
|
.mask { |
|
z-index: 9; |
|
position: absolute; |
|
background-color: rgb(57, 58, 61); |
|
} |
|
|
|
.word-mask { |
|
z-index: 9; |
|
position: absolute; |
|
top: 0; |
|
right: 0; |
|
width: 100%; |
|
background-color: rgb(243, 242, 241); |
|
} |
|
|
|
.word-mask1 { |
|
z-index: 9; |
|
position: absolute; |
|
top: 0; |
|
right: 0; |
|
width: 100%; |
|
background-color: #185abd; |
|
} |
|
|
|
.word-mask2 { |
|
z-index: 9; |
|
position: absolute; |
|
background-color: transparent; |
|
} |
|
|
|
.excel-mask1 { |
|
z-index: 9; |
|
position: absolute; |
|
top: 0; |
|
left: 20%; |
|
width: 60%; |
|
background-color: #107c41; |
|
} |
|
|
|
/deep/.pdf-dia { |
|
border-radius: 0 !important; |
|
|
|
.el-dialog__header { |
|
display: none; |
|
} |
|
|
|
.el-dialog__body { |
|
padding: 0; |
|
} |
|
|
|
.el-dialog__headerbtn { |
|
top: 10px; |
|
|
|
.el-dialog__close { |
|
color: #fff; |
|
font-size: 16px; |
|
} |
|
} |
|
} |
|
|
|
.pdf { |
|
.arrow { |
|
padding: 10px 0; |
|
display: flex; |
|
justify-content: center; |
|
align-items: center; |
|
font-size: 16px; |
|
color: #fff; |
|
background-color: #333; |
|
|
|
.turn { |
|
margin: 0 10px; |
|
font-size: 18px; |
|
cursor: pointer; |
|
} |
|
} |
|
|
|
.pdf-wrap { |
|
width: 80%; |
|
margin: 0 auto; |
|
} |
|
} |
|
|
|
/deep/.project-dia { |
|
.el-dialog__body { |
|
padding: 28px 32px; |
|
} |
|
} |
|
|
|
.projects { |
|
display: flex; |
|
flex-wrap: wrap; |
|
max-height: 400px; |
|
overflow: auto; |
|
|
|
li { |
|
display: inline-flex; |
|
align-items: center; |
|
width: 238px; |
|
padding: 16px; |
|
margin: 0 20px 20px 0; |
|
background-color: #f6f8fa; |
|
border-radius: 16px; |
|
cursor: pointer; |
|
|
|
&:hover { |
|
span { |
|
color: #007eff; |
|
} |
|
} |
|
|
|
&:nth-child(3n) { |
|
margin-right: 0; |
|
} |
|
|
|
&.active { |
|
background-color: #f2f7ff; |
|
|
|
span { |
|
color: #3988ff; |
|
} |
|
} |
|
} |
|
|
|
span { |
|
max-width: 140px; |
|
margin-left: 14px; |
|
font-size: 14px; |
|
color: #333; |
|
} |
|
} |
|
|
|
@media (max-width: 1430px) { |
|
.wrap { |
|
padding: 12px 100px 20px; |
|
} |
|
} |
|
</style> |