feat: pdf阅读
This commit is contained in:
parent
2b89952c95
commit
8a3bc17497
|
@ -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({
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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">
|
||||||
|
|
Loading…
Reference in New Issue