<template> <div class="wrap pb"> <breadcrumb ref="breadcrumb" :data="'课程学习/' + courseName" :query="breadcrumbQuery"></breadcrumb> <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> <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 { breadcrumbQuery: { source: this.$route.query.source }, startTime: Date.now(), // 页面进来的时间 id: this.$route.query.id, video: 'http://liuwanr.oss-cn-shenzhen.aliyuncs.com/mp4/20200519/1589871025648.mp4', chapterList: [], courseName: '', description: '', coverUrl: '', playAuth: '', player: null, previewImg: '', iframeSrc: '', 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.local.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() this.$refs.breadcrumb.update('课程学习/' + (this.$route.query.source == 1 ? '本校课程' : '共享课程') + '/' + 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.local.get(Setting.tokenKey) && !util.local.get('oc_server_token') && showConfirm) { this.$confirm('请先登录,是否直接前往登录?', "提示", { type: 'success' }).then(() => { this.SET_COURSE(this.id) this.$router.push('/login') }).catch(() => {}) return false } this.curLink = `${chapterName}${row.name}`; this.player = null this.playauth = '' this.coverUrl = '' this.pdfSrc = '' this.iframeSrc = '' this.isPPT = false this.isWord = false this.isExcel = false if(this.transferType(row.fileType) == '视频'){ this.$get(`${this.api.getPlayAuth}/${row.fileId}`).then(res => { this.playAuth = res.data.playAuth 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 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: .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 .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>