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

@ -1,169 +1,178 @@
import request from '@/utils/request'
const mycourseApi = {
changePassword: '/sys/user/changePwd',
mycourseList: 'myCourse/getMyCourseList', // 我的课程列表,课程搜索
addMyCourse: 'myCourse/addMyCourse', // 添加课程
centerList: 'focusTrain/getList', // 集中培训列表
centerDetail: 'focusTrain/getDetail', // 集中培训详情
centerJoin: 'project/terminalTrain/enroll', // 集中培训报名
centerSign: 'project/terminalTrain/sign', // 集中培训签到
recommendList: 'sys/recommend/listPage', // 系统推荐课程列表
recommendDetail: 'sys/recommend/detail', // 系统课程推荐详情
trainPlanList: '/myCourse/getMyTrainPlanList', // 培训计划列表
getCourseDetail: 'myCourse/getCourseDetail', // 我的课程详情
getCourseCatalogue: 'myCourse/getCourseCatalogue', // 获取课程目录
reqCourseExam: 'testInClass/add', // 课中检测
simulateTestList: 'simulateTest/list', // 模拟测试列表
simulateTestDetail: 'simulateTest/getQuestions', // 获取模拟测试详情
operationList: 'classwork/list', // 作业列表
reqOperationDetail: 'classwork/get', // 作业详情
reqOperationSubmit: 'classwork/submit', // 作业提交
getMyCourseList: 'studyStatistics/getMyTrainPlanList' // 课程学习统计
changePassword: '/sys/user/changePwd',
mycourseList: 'myCourse/getMyCourseList', // 我的课程列表,课程搜索
addMyCourse: 'myCourse/addMyCourse', // 添加课程
centerList: 'focusTrain/getList', // 集中培训列表
centerDetail: 'focusTrain/getDetail', // 集中培训详情
centerJoin: 'project/terminalTrain/enroll', // 集中培训报名
centerSign: 'project/terminalTrain/sign', // 集中培训签到
recommendList: 'sys/recommend/listPage', // 系统推荐课程列表
recommendDetail: 'sys/recommend/detail', // 系统课程推荐详情
trainPlanList: '/myCourse/getMyTrainPlanList', // 培训计划列表
getCourseDetail: 'myCourse/getCourseDetail', // 我的课程详情
getCourseCatalogue: 'myCourse/getCourseCatalogue', // 获取课程目录
reqCourseExam: 'testInClass/add', // 课中检测
simulateTestList: 'simulateTest/list', // 模拟测试列表
simulateTestDetail: 'simulateTest/getQuestions', // 获取模拟测试详情
operationList: 'classwork/list', // 作业列表
reqOperationDetail: 'classwork/get', // 作业详情
reqOperationSubmit: 'classwork/submit', // 作业提交
getMyCourseList: 'studyStatistics/getMyTrainPlanList', // 课程学习统计
addRecord: '/testInClass/addRecord' // pdf学习完成
}
export function reqChangePassword (data) {
export function reqAddRecord (data) {
return request({
url: mycourseApi.changePassword,
method: 'get',
url: mycourseApi.addRecord,
method: 'post',
params: data
})
}
export function reqChangePassword (data) {
return request({
url: mycourseApi.changePassword,
method: 'get',
params: data
})
}
export function reqCenterJoin (data) {
return request({
url: mycourseApi.centerJoin,
method: 'POST',
data: data
})
return request({
url: mycourseApi.centerJoin,
method: 'POST',
data: data
})
}
export function reqMycourseCount (params) {
return request({
url: mycourseApi.getMyCourseList,
method: 'get',
params: params
})
return request({
url: mycourseApi.getMyCourseList,
method: 'get',
params: params
})
}
export function reqOperationDetail (params) {
return request({
url: mycourseApi.reqOperationDetail,
method: 'get',
params: params
})
return request({
url: mycourseApi.reqOperationDetail,
method: 'get',
params: params
})
}
export function reqOperationSubmit (params) {
return request({
url: mycourseApi.reqOperationSubmit,
method: 'post',
data: params
})
return request({
url: mycourseApi.reqOperationSubmit,
method: 'post',
data: params
})
}
export function reqOperationList (params) {
return request({
url: mycourseApi.operationList,
method: 'get',
params: params
})
return request({
url: mycourseApi.operationList,
method: 'get',
params: params
})
}
export function reqSimulateTestDetail (params) {
return request({
url: mycourseApi.simulateTestDetail,
method: 'post',
params: params
})
return request({
url: mycourseApi.simulateTestDetail,
method: 'post',
params: params
})
}
export function reqSimulateTestList (data) {
return request({
url: mycourseApi.simulateTestList,
method: 'post',
data: data,
params: data
})
return request({
url: mycourseApi.simulateTestList,
method: 'post',
data: data,
params: data
})
}
export function reqMyCourseList (params) {
return request({
url: mycourseApi.mycourseList,
method: 'get',
params: params
})
return request({
url: mycourseApi.mycourseList,
method: 'get',
params: params
})
}
export function reqMyTrainPlanList (params) {
return request({
url: mycourseApi.trainPlanList,
method: 'get',
params: params
})
return request({
url: mycourseApi.trainPlanList,
method: 'get',
params: params
})
}
export function reqAddMyCourse (params) {
return request({
url: mycourseApi.addMyCourse,
method: 'get',
params: params
})
return request({
url: mycourseApi.addMyCourse,
method: 'get',
params: params
})
}
export function reqCourseCenterList (params) {
return request({
url: mycourseApi.centerList,
method: 'get',
params: params
})
return request({
url: mycourseApi.centerList,
method: 'get',
params: params
})
}
export function reqCourseCenterDetail (params) {
return request({
url: mycourseApi.centerDetail,
method: 'get',
params: params
})
return request({
url: mycourseApi.centerDetail,
method: 'get',
params: params
})
}
export function reqRecommendList (params) {
return request({
url: mycourseApi.recommendList,
method: 'get',
params: params
})
return request({
url: mycourseApi.recommendList,
method: 'get',
params: params
})
}
export function recommendDetail (params) {
return request({
url: mycourseApi.recommendDetail,
method: 'get',
params: params
})
return request({
url: mycourseApi.recommendDetail,
method: 'get',
params: params
})
}
export function reqCourseDetail (params) {
return request({
url: mycourseApi.getCourseDetail,
method: 'get',
params: params
})
return request({
url: mycourseApi.getCourseDetail,
method: 'get',
params: params
})
}
export function reqCourseCatalogue (params) {
return request({
url: mycourseApi.getCourseCatalogue,
method: 'get',
params: params
})
return request({
url: mycourseApi.getCourseCatalogue,
method: 'get',
params: params
})
}
export function reqCourseExam (params, data) {
return request({
url: mycourseApi.reqCourseExam,
method: 'post',
params: params,
data: data
})
return request({
url: mycourseApi.reqCourseExam,
method: 'post',
params: params,
data: data
})
}

View File

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

View File

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

View File

@ -2,8 +2,9 @@
<a-card :bordered="false">
<div class="video-box">
<div class="video-title">{{ courseInfo.name }}</div>
<div class="video-main">
<div class="video-main" v-if="curVideo">
<video-player
v-if="curVideo.courseWay === 1"
class="vjs-custom-skin"
ref="videoPlayer"
:options="playerOptions"
@ -11,10 +12,24 @@
@ended="onPlayerEnded($event)"
@timeupdate="onPlayerTimeupdate"
></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 class="video-info">
<a-tabs :default-active-key="activeTab" @change="tabChange">
<a-tabs :default-active-key="activeTab">
<a-tab-pane key="1" tab="课程目录">
<div class="tab-box">
<CourseCatalogue
@ -44,11 +59,14 @@
<!-- 课中考试 -->
<ExamDialog ref="examDialog" :curVideo="curVideo" @success="answerSuccess"></ExamDialog>
<!-- pdf阅读 -->
<PdfView></PdfView>
<PdfView ref="pdfView"></PdfView>
</a-card>
</template>
<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 'vue-video-player/src/custom-theme.css'
import { videoPlayer } from 'vue-video-player'
@ -58,7 +76,7 @@ import ExamDialog from './ExamDialog.vue'
import PdfView from './PdfView.vue'
import OperationModule from './OperationModule.vue'
import StatisticalLearning from './StatisticalLearning.vue'
import { reqCourseDetail, reqCourseCatalogue } from '@/api/mycourse/index'
import { reqCourseDetail, reqCourseCatalogue, reqAddRecord } from '@/api/mycourse/index'
export default {
components: {
@ -68,7 +86,8 @@ export default {
ExamDialog,
StatisticalLearning,
PdfView,
videoPlayer
videoPlayer,
VuePdfApp
},
data () {
return {
@ -77,6 +96,8 @@ export default {
courseInfo: {},
catalogueList: [], //
curVideo: {}, //
readComplete: false, // pdf
pdfLoading: false, // pdf
playerOptions: {},
isMousedown: false,
oldTime: 0,
@ -111,6 +132,7 @@ export default {
})
}
const selected = videoList[0] || ''
console.log('selected', selected)
if (selected) {
this.curVideo = selected
this.playerOptions = {
@ -144,17 +166,69 @@ export default {
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 }) {
const _this = this
const vid = this.$refs.videoPlayer.player
const change = function () {
_this.curVideo = item
vid.src(item.videoAddress)
vid.play()
// _this.openCourseExam() //
if (document.querySelector('#viewerContainer')) {
document.querySelector('#viewerContainer').scrollTop = 0
}
setTimeout(() => {
_this.curVideo = item
//
if (item.courseWay === 1) {
const vid = _this.$refs.videoPlayer.player
vid.src(item.videoAddress)
vid.play()
} else {
_this.readComplete = false // pdf
}
// _this.openCourseExam() //
}, 300)
}
if (this.oldTime > 0 && _this.curVideo.status !== 1) {
if (this.oldTime > 0 && _this.curVideo.status !== 1 && _this.curVideo.courseWay === 1) {
this.$confirm({
title: '确定要切换学习视频吗?',
content: '一但切换学习视频,您现在正在学习的视频学时将清0,确定要切换吗?',
@ -167,14 +241,14 @@ export default {
change()
}
},
tabChange (key) {
// this.$refs.videoPlayer.player.play() //
// this.$refs.videoPlayer.player.pause() //
// this.$refs.videoPlayer.player.src('src') //
},
//
onPlayerEnded () {
this.openCourseExam()
const { curVideo, courseInfo } = this
//
//
if (curVideo.status === 0 && courseInfo.trainType === 2 && curVideo.courseWay === 1) {
this.openCourseExam()
}
},
//
openCourseExam () {
@ -191,8 +265,7 @@ export default {
_this.$refs.examDialog.getExamQuestion()
},
onCancel () {
return new Promise((resolve, reject) => {
}).catch(() => console.log('Oops errors!'))
return new Promise((resolve, reject) => {}).catch(() => console.log('Oops errors!'))
},
wrapClassName: 'dialogTest'
})
@ -240,7 +313,7 @@ export default {
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;
}
</style>

View File

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