作者 张晓杰

培训课程播放视频,证照管理路由修改

@@ -53,12 +53,14 @@ @@ -53,12 +53,14 @@
53 "quill": "1.3.7", 53 "quill": "1.3.7",
54 "screenfull": "5.0.2", 54 "screenfull": "5.0.2",
55 "sortablejs": "1.10.2", 55 "sortablejs": "1.10.2",
  56 + "video.js": "^8.16.1",
56 "vue": "2.6.12", 57 "vue": "2.6.12",
57 "vue-count-to": "1.0.13", 58 "vue-count-to": "1.0.13",
58 "vue-cropper": "0.5.5", 59 "vue-cropper": "0.5.5",
59 "vue-meta": "2.4.0", 60 "vue-meta": "2.4.0",
60 "vue-pdf": "^4.3.0", 61 "vue-pdf": "^4.3.0",
61 "vue-router": "3.4.9", 62 "vue-router": "3.4.9",
  63 + "vue-video-player": "^5.0.2",
62 "vuedraggable": "2.24.3", 64 "vuedraggable": "2.24.3",
63 "vuex": "3.6.0", 65 "vuex": "3.6.0",
64 "xml-js": "1.6.11" 66 "xml-js": "1.6.11"
@@ -38,6 +38,10 @@ import VueMeta from 'vue-meta' @@ -38,6 +38,10 @@ import VueMeta from 'vue-meta'
38 // 字典数据组件 38 // 字典数据组件
39 import DictData from '@/components/DictData' 39 import DictData from '@/components/DictData'
40 40
  41 +// import VideoPlayer from 'vue-video-player'
  42 +// // import 'vue-video-player/src/custom-theme.css'
  43 +// import 'video.js/dist/video-js.css'
  44 +
41 // 全局方法挂载 45 // 全局方法挂载
42 Vue.prototype.getDicts = getDicts 46 Vue.prototype.getDicts = getDicts
43 Vue.prototype.getConfigKey = getConfigKey 47 Vue.prototype.getConfigKey = getConfigKey
@@ -62,6 +66,7 @@ Vue.component('ImagePreview', ImagePreview) @@ -62,6 +66,7 @@ Vue.component('ImagePreview', ImagePreview)
62 Vue.use(directive) 66 Vue.use(directive)
63 Vue.use(plugins) 67 Vue.use(plugins)
64 Vue.use(VueMeta) 68 Vue.use(VueMeta)
  69 +// Vue.use(VideoPlayer)
65 DictData.install() 70 DictData.install()
66 71
67 /** 72 /**
@@ -102,19 +102,31 @@ export const constantRoutes = [ @@ -102,19 +102,31 @@ export const constantRoutes = [
102 ] 102 ]
103 }, 103 },
104 { 104 {
105 - path: '/contract/compliancemanagement/orginfoCertificate', 105 + path: '/system/orginfo/orginfoCertificate',
106 component: Layout, 106 component: Layout,
107 hidden: true, 107 hidden: true,
108 children: [ 108 children: [
109 { 109 {
110 path: 'orginfoCertificate/index', 110 path: 'orginfoCertificate/index',
111 - component: () => import('@/views/compliancemanagement/orginfoCertificate/index'), 111 + component: () => import('@/views/system/orginfo/orginfoCertificate/index'),
112 name: 'orginfoCertificate', 112 name: 'orginfoCertificate',
113 meta: { title: '证照管理', icon: '' } 113 meta: { title: '证照管理', icon: '' }
114 } 114 }
115 ] 115 ]
  116 + },
  117 + {
  118 + path: '/compliance/compliancemanagement/compliancetraining',
  119 + component: Layout,
  120 + hidden: true,
  121 + children: [
  122 + {
  123 + path: 'trainingcourse/play',
  124 + component: () => import('@/views/compliancemanagement/compliancetraining/trainingcourse/play'),
  125 + name: 'orginfoCertificate',
  126 + meta: { title: '培训课程', icon: '' }
  127 + }
  128 + ]
116 } 129 }
117 - // /contract/compliancemanagement/orginfoCertificate  
118 ] 130 ]
119 131
120 // 动态路由,基于用户权限动态去加载 132 // 动态路由,基于用户权限动态去加载
@@ -107,6 +107,11 @@ @@ -107,6 +107,11 @@
107 @click="handleDelete(scope.row)" 107 @click="handleDelete(scope.row)"
108 v-hasPermi="['system:trainingcourse:remove']" 108 v-hasPermi="['system:trainingcourse:remove']"
109 >删除</el-button> 109 >删除</el-button>
  110 + <el-button
  111 + size="mini"
  112 + type="text"
  113 + @click="handlePlayer(scope.row)"
  114 + >播放视频</el-button>
110 </template> 115 </template>
111 </el-table-column> 116 </el-table-column>
112 </el-table> 117 </el-table>
@@ -229,13 +234,17 @@ export default { @@ -229,13 +234,17 @@ export default {
229 id: [ 234 id: [
230 { required: true, message: "不能为空", trigger: "blur" } 235 { required: true, message: "不能为空", trigger: "blur" }
231 ] 236 ]
232 - } 237 + },
233 }; 238 };
234 }, 239 },
235 created() { 240 created() {
236 this.getList(); 241 this.getList();
237 }, 242 },
238 methods: { 243 methods: {
  244 +//视频播放
  245 + handlePlayer(){
  246 + this.$router.push({ path: '/compliance/compliancemanagement/compliancetraining/trainingcourse/play'});
  247 + },
239 /** 查询【请填写功能名称】列表 */ 248 /** 查询【请填写功能名称】列表 */
240 getList() { 249 getList() {
241 this.loading = true; 250 this.loading = true;
  1 +<template>
  2 + <div class="info">
  3 + <div class="container">
  4 + <div class="play">
  5 + <el-row>
  6 + <el-col :span="24">
  7 + <video-player
  8 + id="video"
  9 + class="video-player vjs-custom-skin"
  10 + ref="videoPlayer"
  11 + @ended="videoEnded"
  12 + @timeupdate="videoTimeUp"
  13 + @loadeddata="videoLoaded"
  14 + @seeking="videoSeeking"
  15 + @seeked="videoSeeked"
  16 + :events="['seeking', 'seeked']"
  17 + :playsinline="true"
  18 + :options="playerOptions"
  19 + ></video-player>
  20 + <!-- <h3 id="text-progress">{{ this.progress }}</h3> -->
  21 + </el-col>
  22 + <!-- <el-col :span="6" class="text"> -->
  23 + <!-- </el-col> -->
  24 + </el-row>
  25 + </div>
  26 + </div>
  27 + </div>
  28 + </template>
  29 +
  30 + <script>
  31 + import Vue from 'vue'
  32 + import VideoPlayer from 'vue-video-player'
  33 +import 'video.js/dist/video-js.css'
  34 +import 'vue-video-player/src/custom-theme.css'
  35 +Vue.use(VideoPlayer)
  36 + export default {
  37 + data() {
  38 + return {
  39 + classHour : [],
  40 + data : [],
  41 + userId :'',
  42 + videoInformation : [],
  43 + progress : '0.00%',
  44 + durationTime : '' ,// 视频总时常
  45 + currentTime : '' ,// 当前播放进度时长
  46 + saveDurationTime : '', // 视频总时常
  47 + saveCurrentTime:'', // 当前播放进度时长
  48 + isShowSubs: false,
  49 + recodrTime :null,
  50 + playerOptions:{
  51 + playbackRates: [0.7, 1.0, 1.5, 2.0], //播放速度
  52 + autoplay: false, //如果true,浏览器准备好时开始回放。
  53 + muted: false, // 默认情况下将会消除任何音频。
  54 + loop: false, // 导致视频一结束就重新开始。
  55 + preload: 'auto', // 建议浏览器在<video>加载元素后是否应该开始下载视频数据。auto浏览器选择最佳行为,立即开始加载视频(如果浏览器支持)
  56 + language: 'zh-CN',
  57 + aspectRatio: '16:9', // 将播放器置于流畅模式,并在计算播放器的动态大小时使用该值。值应该代表一个比例 - 用冒号分隔的两个数字(例如"16:9"或"4:3")
  58 + fluid: true, // 当true时,Video.js player将拥有流体大小。换句话说,它将按比例缩放以适应其容器。
  59 + sources: [
  60 + {
  61 + type: 'video/mp4', //这里的种类支持很多种:基本视频格式、直播、流媒体等,具体可以参看git网址项目
  62 + src: 'http://vjs.zencdn.net/v/oceans.mp4' //url地址
  63 + }
  64 + ],
  65 + poster: '', //你的封面地址
  66 + // width: document.documentElement.clientWidth, //播放器宽度
  67 + notSupportedMessage: '此视频暂无法播放,请稍后再试', //允许覆盖Video.js无法播放媒体源时显示的默认信息。
  68 + controlBar: {
  69 + timeDivider: true,
  70 + durationDisplay: true,
  71 + remainingTimeDisplay: false,
  72 + fullscreenToggle: true //全屏按钮
  73 + }
  74 + }
  75 + }
  76 + },
  77 + created() {
  78 + },
  79 + methods: {
  80 + // 视频信息加载完成,获取总时长,若接口返回进度,断点播放
  81 + videoLoaded(item) {
  82 + this.durationTime = item.cache_.duration
  83 + this.videoInformation = item
  84 + // console.log('progress', this.progress)
  85 + if (this.progress > '0.00%') {
  86 + item.currentTime(Number(this.currentTime))
  87 + }
  88 + // console.log('视频信息videoLoaded:', this.videoInformation)
  89 + },
  90 + // 当前播放进度
  91 + videoTimeUp(item) {
  92 + this.currentTime = item.cache_.currentTime
  93 + this.progress = ((this.currentTime.toFixed(2) / item.cache_.duration.toFixed(2)) * 100).toFixed(2) + '%'
  94 + // console.log('当前播放进度', item)
  95 + },
  96 + // 正在拖动
  97 + videoSeeking(item) {
  98 + // console.log('正在拖动',item)
  99 + this.isSeeking = true
  100 + },
  101 + // 拖动结束
  102 + videoSeeked(item) {
  103 + // console.log('拖动结束',item)
  104 + this.isSeeking = false
  105 + },
  106 +
  107 + // 点击播放
  108 + videoPlay() {
  109 + //清除定时器
  110 + if (this.pauseTimer) {
  111 + clearTimeout(this.pauseTimer)
  112 + }
  113 + },
  114 + // 触发暂停
  115 + videoPause(item) {
  116 + //利用定时器延迟
  117 + this.pauseTimer = setTimeout(() => {
  118 + if (this.isVideoEnd) return
  119 + if (this.isSeeking) return
  120 + // 展示蒙层
  121 + this.isShowSubs = true
  122 + }, 100)
  123 + },
  124 + // 播放结束
  125 + videoEnded() {
  126 + this.isVideoEnd = true
  127 + }
  128 + }
  129 + }
  130 + </script>
  131 + <style lang="scss" scoped>
  132 + $width: 1140px;
  133 + .info {
  134 + width: 100%;
  135 + }
  136 + .container {
  137 + width: $width;
  138 + margin: auto;
  139 + .breadcrumb {
  140 + padding-top: 20px;
  141 + padding-bottom: 20px;
  142 + }
  143 + .play {
  144 + box-shadow: 0 4px 8px 0 rgba(28, 31, 33, 0.1);
  145 + background-color: #26262b;
  146 + .text {
  147 + font-size: 15px;
  148 + color: #fff;
  149 + text-align: left;
  150 + .title {
  151 + padding: 12px 15px;
  152 + }
  153 + .teacher {
  154 + padding: 12px 0 12px 10px;
  155 + background: #2d2d2d;
  156 + }
  157 + .list {
  158 + height: 393px;
  159 + width: 283px;
  160 + .name1 {
  161 + cursor: pointer;
  162 + background: #2d2d2d;
  163 + font-size: 15px;
  164 + padding: 10px 0 10px 47px;
  165 + margin-top: 2px;
  166 + }
  167 + .name2 {
  168 + cursor: pointer;
  169 + color: rgb(61, 231, 112);
  170 + background: #2d2d2d;
  171 + font-size: 15px;
  172 + padding: 10px 0 10px 47px;
  173 + margin-top: 2px;
  174 + }
  175 + }
  176 + }
  177 + }
  178 + // .biref {
  179 + // box-shadow: 0 4px 8px 0 rgba(28, 31, 33, 0.1);
  180 + // background-color: #ffffff;
  181 + // font-size: 15px;
  182 + // text-align: left;
  183 + // color: #5e5e5e;
  184 + // padding: 25px 20px;
  185 + // margin: 30px 0;
  186 + // img {
  187 + // vertical-align: middle;
  188 + // margin-right: 5px;
  189 + // }
  190 + // }
  191 + }
  192 + </style>
  193 + <style>
  194 + body {
  195 + background-color: #f7f9fc !important;
  196 + /* background-color: #d7e4f7 !important; */
  197 + }
  198 + .vjs-custom-skin > .video-js .vjs-big-play-button {
  199 + width: 70px;
  200 + border-radius: 50%;
  201 + }
  202 + .el-breadcrumb__inner {
  203 + color: #2c3e50 !important;
  204 + }
  205 + .el-scrollbar__wrap {
  206 + overflow: hidden;
  207 + position: relative;
  208 + }
  209 + </style>
@@ -198,8 +198,7 @@ export default { @@ -198,8 +198,7 @@ export default {
198 }, 198 },
199 methods: { 199 methods: {
200 toOrginfoCertificateList(row){ 200 toOrginfoCertificateList(row){
201 - console.log('row=====',row)  
202 - this.$router.push({ path: '/contract/compliancemanagement/orginfoCertificate/orginfoCertificate/index', query: {orgcode: row.orgcode }}); 201 + this.$router.push({ path: '/system/orginfo/orginfoCertificate/orginfoCertificate/index', query: {orgcode: row.orgcode }});
203 }, 202 },
204 /** 查询【请填写功能名称】列表 */ 203 /** 查询【请填写功能名称】列表 */
205 getList() { 204 getList() {
@@ -304,7 +304,7 @@ export default { @@ -304,7 +304,7 @@ export default {
304 methods: { 304 methods: {
305 //根据单位编号查询列表 305 //根据单位编号查询列表
306 getorgcode(orgcode){ 306 getorgcode(orgcode){
307 - console.log(orgcode) 307 + // console.log(orgcode)
308 selectByOrgnCode(orgcode).then(response =>{ 308 selectByOrgnCode(orgcode).then(response =>{
309 console.log(response.data) 309 console.log(response.data)
310 this.orginfoCertificateList = response.data 310 this.orginfoCertificateList = response.data