feat: pdf阅读

This commit is contained in:
cgd 2022-03-16 14:39:54 +08:00
parent 2b89952c95
commit 8a3bc17497
5 changed files with 224 additions and 134 deletions

View File

@ -19,16 +19,25 @@ const mycourseApi = {
operationList: 'classwork/list', // 作业列表 operationList: 'classwork/list', // 作业列表
reqOperationDetail: 'classwork/get', // 作业详情 reqOperationDetail: 'classwork/get', // 作业详情
reqOperationSubmit: 'classwork/submit', // 作业提交 reqOperationSubmit: 'classwork/submit', // 作业提交
getMyCourseList: 'studyStatistics/getMyTrainPlanList' // 课程学习统计 getMyCourseList: 'studyStatistics/getMyTrainPlanList', // 课程学习统计
addRecord: '/testInClass/addRecord' // pdf学习完成
} }
export function reqAddRecord (data) {
return request({
url: mycourseApi.addRecord,
method: 'post',
params: data
})
}
export function reqChangePassword (data) { export function reqChangePassword (data) {
return request({ return request({
url: mycourseApi.changePassword, url: mycourseApi.changePassword,
method: 'get', method: 'get',
params: data params: data
}) })
} }
export function reqCenterJoin (data) { export function reqCenterJoin (data) {
return request({ return request({

View File

@ -23,11 +23,13 @@
]" ]"
> >
<VideoOne <VideoOne
v-if="j.courseWay === 1"
theme="filled" theme="filled"
:fill="j.id === curVideo.id ? '#1890ff' : j.status === 1 ? '#26bd71' : '#ccc'" :fill="j.id === curVideo.id ? '#1890ff' : j.status === 1 ? '#26bd71' : '#ccc'"
style="margin-right: 6px;" style="margin-right: 6px;"
size="1.2em" size="1.2em"
></VideoOne> ></VideoOne>
<FilePdf v-else theme="filled" size="1.2em" :fill="j.id === curVideo.id ? '#1890ff' : j.status === 1 ? '#26bd71' : '#ccc'" style="margin-right: 6px;"/>
{{ index + 1 }}.{{ k + 1 }} {{ index + 1 }}.{{ k + 1 }}
{{ j.name }} {{ j.name }}
</div> </div>
@ -57,9 +59,9 @@
</template> </template>
<script> <script>
import { VideoOne, Round, History } from '@icon-park/vue' import { VideoOne, Round, History, FilePdf } from '@icon-park/vue'
export default { export default {
components: { VideoOne, Round, History }, components: { VideoOne, Round, History, FilePdf },
props: { props: {
catalogueList: { catalogueList: {
type: Array, type: Array,

View File

@ -22,7 +22,8 @@ export default {
data () { data () {
return { return {
title: 'PDF阅读', title: 'PDF阅读',
visible: true, visible: false,
data: '', //
config: { config: {
toolbar: false, toolbar: false,
sidebar: false sidebar: false
@ -34,6 +35,11 @@ export default {
}, },
methods: { methods: {
initData () {}, initData () {},
open (data) {
console.log('data', data)
this.data = data
this.visible = true
},
pagesRendered (pdfApp) { pagesRendered (pdfApp) {
console.log('pdfApp', pdfApp) console.log('pdfApp', pdfApp)
setTimeout(() => { setTimeout(() => {
@ -47,7 +53,7 @@ export default {
} }
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
::v-deep .ant-modal-body{ ::v-deep .ant-modal-body {
padding-top: 0; padding-top: 0;
padding-bottom: 0; padding-bottom: 0;
} }

View File

@ -2,8 +2,9 @@
<a-card :bordered="false"> <a-card :bordered="false">
<div class="video-box"> <div class="video-box">
<div class="video-title">{{ courseInfo.name }}</div> <div class="video-title">{{ courseInfo.name }}</div>
<div class="video-main"> <div class="video-main" v-if="curVideo">
<video-player <video-player
v-if="curVideo.courseWay === 1"
class="vjs-custom-skin" class="vjs-custom-skin"
ref="videoPlayer" ref="videoPlayer"
:options="playerOptions" :options="playerOptions"
@ -11,10 +12,24 @@
@ended="onPlayerEnded($event)" @ended="onPlayerEnded($event)"
@timeupdate="onPlayerTimeupdate" @timeupdate="onPlayerTimeupdate"
></video-player> ></video-player>
<a-spin :spinning="pdfLoading">
<div v-if="curVideo.courseWay === 2" style="width: 100%;height: 600px;">
<!-- https://www.gjtool.cn/pdfh5/git.pdf -->
<!-- :pdf="curVideo.videoAddress" -->
<vue-pdf-app
:pdf="curVideo.videoAddress"
:config="{
toolbar: false,
sidebar: false,
}"
@open="pdfOpened"
></vue-pdf-app>
</div>
</a-spin>
</div> </div>
</div> </div>
<div class="video-info"> <div class="video-info">
<a-tabs :default-active-key="activeTab" @change="tabChange"> <a-tabs :default-active-key="activeTab">
<a-tab-pane key="1" tab="课程目录"> <a-tab-pane key="1" tab="课程目录">
<div class="tab-box"> <div class="tab-box">
<CourseCatalogue <CourseCatalogue
@ -44,11 +59,14 @@
<!-- 课中考试 --> <!-- 课中考试 -->
<ExamDialog ref="examDialog" :curVideo="curVideo" @success="answerSuccess"></ExamDialog> <ExamDialog ref="examDialog" :curVideo="curVideo" @success="answerSuccess"></ExamDialog>
<!-- pdf阅读 --> <!-- pdf阅读 -->
<PdfView></PdfView> <PdfView ref="pdfView"></PdfView>
</a-card> </a-card>
</template> </template>
<script> <script>
import _ from 'lodash'
import VuePdfApp from 'vue-pdf-app'
import 'vue-pdf-app/dist/icons/main.css'
import 'video.js/dist/video-js.css' import 'video.js/dist/video-js.css'
import 'vue-video-player/src/custom-theme.css' import 'vue-video-player/src/custom-theme.css'
import { videoPlayer } from 'vue-video-player' import { videoPlayer } from 'vue-video-player'
@ -58,7 +76,7 @@ import ExamDialog from './ExamDialog.vue'
import PdfView from './PdfView.vue' import PdfView from './PdfView.vue'
import OperationModule from './OperationModule.vue' import OperationModule from './OperationModule.vue'
import StatisticalLearning from './StatisticalLearning.vue' import StatisticalLearning from './StatisticalLearning.vue'
import { reqCourseDetail, reqCourseCatalogue } from '@/api/mycourse/index' import { reqCourseDetail, reqCourseCatalogue, reqAddRecord } from '@/api/mycourse/index'
export default { export default {
components: { components: {
@ -68,7 +86,8 @@ export default {
ExamDialog, ExamDialog,
StatisticalLearning, StatisticalLearning,
PdfView, PdfView,
videoPlayer videoPlayer,
VuePdfApp
}, },
data () { data () {
return { return {
@ -77,6 +96,8 @@ export default {
courseInfo: {}, courseInfo: {},
catalogueList: [], // catalogueList: [], //
curVideo: {}, // curVideo: {}, //
readComplete: false, // pdf
pdfLoading: false, // pdf
playerOptions: {}, playerOptions: {},
isMousedown: false, isMousedown: false,
oldTime: 0, oldTime: 0,
@ -111,6 +132,7 @@ export default {
}) })
} }
const selected = videoList[0] || '' const selected = videoList[0] || ''
console.log('selected', selected)
if (selected) { if (selected) {
this.curVideo = selected this.curVideo = selected
this.playerOptions = { this.playerOptions = {
@ -144,17 +166,69 @@ export default {
this.catalogueList = data this.catalogueList = data
}) })
}, },
// pdf
pdfOpened (pdfApp) {
const _this = this
setTimeout(() => {
document.querySelector('#viewerContainer').addEventListener('scroll', function (e) {
var target = e.target
const scrollTop = target.scrollTop
const scrollHeight = target.scrollHeight
const height = target.offsetHeight
const total = height + scrollTop + 500
if (total > scrollHeight) {
_this.reachBottom()
}
})
})
},
// pdf
reachBottom: _.debounce(function () {
console.log('>>>>>>>>>>>>>>>>>>>onPlayerEnded')
console.log('到达了底部')
if (!this.readComplete && this.curVideo.status === 0) {
this.readComplete = true
this.readCompleteAjax()
}
}, 300),
//
readCompleteAjax () {
this.pdfLoading = true
const { person } = this.$store.state.user
reqAddRecord({
personId: person.id,
projectId: this.$route.query.courseId,
courseId: this.curVideo.courseId,
coursewareId: this.curVideo.id
})
.then(res => {
this.$message.success('恭喜你,学习完成!')
})
.finally(() => {
this.pdfLoading = false
})
},
// //
changeVideo ({ item, pItem }) { changeVideo ({ item, pItem }) {
const _this = this const _this = this
const vid = this.$refs.videoPlayer.player
const change = function () { const change = function () {
if (document.querySelector('#viewerContainer')) {
document.querySelector('#viewerContainer').scrollTop = 0
}
setTimeout(() => {
_this.curVideo = item _this.curVideo = item
//
if (item.courseWay === 1) {
const vid = _this.$refs.videoPlayer.player
vid.src(item.videoAddress) vid.src(item.videoAddress)
vid.play() vid.play()
// _this.openCourseExam() // } else {
_this.readComplete = false // pdf
} }
if (this.oldTime > 0 && _this.curVideo.status !== 1) { // _this.openCourseExam() //
}, 300)
}
if (this.oldTime > 0 && _this.curVideo.status !== 1 && _this.curVideo.courseWay === 1) {
this.$confirm({ this.$confirm({
title: '确定要切换学习视频吗?', title: '确定要切换学习视频吗?',
content: '一但切换学习视频,您现在正在学习的视频学时将清0,确定要切换吗?', content: '一但切换学习视频,您现在正在学习的视频学时将清0,确定要切换吗?',
@ -167,14 +241,14 @@ export default {
change() change()
} }
}, },
tabChange (key) {
// this.$refs.videoPlayer.player.play() //
// this.$refs.videoPlayer.player.pause() //
// this.$refs.videoPlayer.player.src('src') //
},
// //
onPlayerEnded () { onPlayerEnded () {
const { curVideo, courseInfo } = this
//
//
if (curVideo.status === 0 && courseInfo.trainType === 2 && curVideo.courseWay === 1) {
this.openCourseExam() this.openCourseExam()
}
}, },
// //
openCourseExam () { openCourseExam () {
@ -191,8 +265,7 @@ export default {
_this.$refs.examDialog.getExamQuestion() _this.$refs.examDialog.getExamQuestion()
}, },
onCancel () { onCancel () {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {}).catch(() => console.log('Oops errors!'))
}).catch(() => console.log('Oops errors!'))
}, },
wrapClassName: 'dialogTest' wrapClassName: 'dialogTest'
}) })
@ -240,7 +313,7 @@ export default {
margin: 0 auto; margin: 0 auto;
} }
.learn-exam-dialog ::v-deep .ant-modal-confirm-btns:first-child{ .learn-exam-dialog ::v-deep .ant-modal-confirm-btns:first-child {
display: none; display: none;
} }
</style> </style>

View File

@ -37,7 +37,7 @@
<a-tag v-if="record.status === 3" color="green">已完成</a-tag> <a-tag v-if="record.status === 3" color="green">已完成</a-tag>
</span> </span>
<template slot="schedule" slot-scope="text, record"> <template slot="schedule" slot-scope="text, record">
<a-progress :percent="record.schedule" /> <a-progress v-if="record.schedule || record.schedule === 0" :percent="record.schedule" />
</template> </template>
<template slot="learnHours" slot-scope="text, record">{{ record.learnHours }}小时</template> <template slot="learnHours" slot-scope="text, record">{{ record.learnHours }}小时</template>
<span slot="action" slot-scope="text, record"> <span slot="action" slot-scope="text, record">