2024-01-22 11:32:01 +08:00
< template >
2024-03-27 14:31:47 +08:00
< div class = "app-warp" >
< div class = "detail-structure" >
< el -page -header content = "完善页面" @back ="goBack" / >
< div class = "detail-container" >
< div class = "level-title" >
< h1 > 课件基本信息 < / h1 >
2024-01-22 11:32:01 +08:00
< / div >
2024-03-27 14:31:47 +08:00
< el -form ref = "form" :rules ="rules" :model ="form" label -width = " 110px " class = "edit_form" >
< el -form -item label = "课件名称" prop = "COURSEWARENAME" >
< el -input id = "COURSEWARENAME" ref = "COURSEWARENAME" : disabled = "dialogType == 'info'" v -model = " form.COURSEWARENAME " maxlength = "255" placeholder = "这里输入课件名称..." title = "课件名称" / >
< / e l - f o r m - i t e m >
< el -form -item label = "培训类型" prop = "trainAllName" >
< div @ click = "dialogFormVisible = true" >
< el -input v -model = " form.trainAllName " :readonly ="true" maxlength = "255" placeholder = "这里输入培训类型..." title = "培训类型" / >
< / div >
< / e l - f o r m - i t e m >
<!-- < el -form -item label = "培训类型" >
< div > { { form . TRAINTYPE _NAME } } { { form . POSTTYPE _NAME ? '-' + form . POSTTYPE _NAME : '' } } { { form . INDUSTRY _END _ID _NAME ? '-' + form . INDUSTRY _END _ID _NAME : '' } } < / div >
< el -button type = "text" @ click = "dialogFormVisible = true" > 培训类型 < / e l - b u t t o n >
< / e l - f o r m - i t e m > - - >
< el -form -item label = "讲师名称" prop = "SPEAKER" > <!-- 主讲人 -- >
<!-- < el -input id = "SPEAKER" ref = "SPEAKER" v -model = " form.SPEAKER " maxlength = "255" placeholder = "这里输入主讲人..." title = "主讲人" / > -- >
< el -select : disabled = "dialogType == 'info'" v-model ="form.SPEAKER" filterable placeholder="请选择" >
< el -option v -for = " item in teacherAllList " :key ="item.id" :label ="item.name" :value ="item.id" / >
< / e l - s e l e c t >
< / e l - f o r m - i t e m >
< el -form -item label = "课件文件" >
< div >
< a class = "a_link" @click ="goViewVideo(form)" > [ 视 频 预 览 ] < / a >
< / div >
< / e l - f o r m - i t e m >
< el -form -item v-if ="!form.captureIsType && !form.fileIsType" label="课件截图" >
< div class = "img-size" >
< img :src ="form.VIDEOCAPTURE" width = "100%" alt = "" >
< / div >
< / e l - f o r m - i t e m >
< el -form -item label = "课件描述" prop = "COURSEWAREINTRODUCE" > <!-- 课件介绍 -- >
< el -input id = "COURSEWAREINTRODUCE" ref = "COURSEWAREINTRODUCE" : disabled = "dialogType == 'info'" v -model = " form.COURSEWAREINTRODUCE " rows = "5" type = "textarea" maxlength = "255" placeholder = "这里输入课件介绍..." title = "课件介绍" / >
< / e l - f o r m - i t e m >
< el -form -item label = "相关词条" prop = "trainingSection" > <!-- 相关词条 -- >
< el -cascader
: disabled = "dialogType == 'info'"
: options = "dicListMap.relatedTermList"
: props = "{ multiple: true,value: 'id', children: 'nodes', label: 'name' }"
v - model = "form.relatedTerm"
placeholder = "请输入相关词条"
filterable / >
< / e l - f o r m - i t e m >
< / e l - f o r m >
< div class = "detail_foot" >
< el -button type = "primary" @click ="confirm" > 保 存 < / el -button >
< el -button icon = "el-icon-arrow-left" @click ="goBack" > 返 回 < / el -button >
2024-01-22 11:32:01 +08:00
< / div >
< / div >
2024-03-27 14:31:47 +08:00
< / div >
2024-01-22 11:32:01 +08:00
2024-03-27 14:31:47 +08:00
< div v-if ="isShowProgress" class="popContainer" >
< div class = "progress_title" > 视频上传中 , 请耐心等待 ... < / div >
< el -progress
: percentage = "authProgress"
type = "circle"
class = "progress" / >
2024-01-22 11:32:01 +08:00
< / div >
2024-03-27 14:31:47 +08:00
< el -dialog :visible.sync ="dialogFormVisible" title = "培训类型" top = "80px" width = "840px" >
< el -form :model ="form" class = "appformwith" >
< div class = "type_field_box" >
< div class = "type_field_item" >
< div class = "type_field_top" > 培训类型 < / div >
< div class = "type_field_content type_pa" >
< div v-for ="(item,i) in trainingList" :key="i" :class="TRAINTYPE == item.TRAININGTYPE_ID?'type_li_active':''" class="type_li" @click="checkTrain(item)" >
{ { item . NAME } }
< / div >
< / div >
2024-01-22 11:32:01 +08:00
< / div >
2024-03-27 14:31:47 +08:00
< div class = "type_field_item" style = "width:320px" >
< div class = "type_field_top" > 行业类型 < / div >
< div class = "type_field_content m-scroll-style" >
< div class = "type_field_search" >
< el -input
v - model = "filterText"
placeholder = "请输入关键字进行过滤..."
prefix - icon = "el-icon-search"
size = "mini"
clearable / >
2024-01-22 11:32:01 +08:00
< / div >
2024-03-27 14:31:47 +08:00
< el -tree
v - loading = "treeLoading"
ref = "tree"
: data = "industryTreeData"
: props = "industryProps"
: check - on - click - node = "true"
: filter - node - method = "filterNode"
: node - key = "industryProps.value"
: check - strictly = "true"
highlight - current = "true"
class = "type_tree"
@ check = "treeCheck"
@ node - click = "handleNodeClick" / >
2024-01-22 11:32:01 +08:00
< / div >
< / div >
2024-03-27 14:31:47 +08:00
< div class = "type_field_item" >
< div class = "type_field_top" > 岗位类型 < / div >
< div class = "type_field_content type_pa" >
< div v-for ="(item,i) in postList" :key="i" :class="POSTTYPE == item.POSTTYPE_ID?'type_li_active':''" class="type_li" @click="checkPost(item)" >
{ { item . NAME } }
< / div >
< / div >
2024-01-22 11:32:01 +08:00
< / div >
2024-03-27 14:31:47 +08:00
< / div >
2024-01-22 11:32:01 +08:00
< / e l - f o r m >
< div slot = "footer" class = "dialog-footer" >
2024-03-27 14:31:47 +08:00
< el -button @ click = "dialogFormVisible = false" > 取 消 < / e l - b u t t o n >
< el -button type = "primary" @click ="selectIndustry" > 确 定 < / el -button >
2024-01-22 11:32:01 +08:00
< / div >
< / e l - d i a l o g >
< el -dialog v-show ="dialogViewVideo" :visible.sync="dialogViewVideo" title="视频" width="800px" @close="closePlayer" >
<!-- < div >
< video -player ref = "videoPlayer" :playsinline ="true" :options ="playerOptions" class = "video-player vjs-custom-skin" / >
< / div > -- >
< div id = "aLiVideoPlayer" class = "prism-player" / >
< / e l - d i a l o g >
< / div >
< / template >
2024-03-27 14:31:47 +08:00
2024-01-22 11:32:01 +08:00
< script >
2024-03-27 14:31:47 +08:00
2024-01-22 11:32:01 +08:00
import Pagination from '@/components/Pagination' // 通过 el-pagination二次打包
import { requestFN } from '@/utils/request'
import waves from '@/directive/waves' // waves directive
import { videoPlayer } from 'vue-video-player'
import 'video.js/dist/video-js.css'
import SelectTree from '@/components/SelectTree'
import axios from 'axios'
export default {
components : { Pagination , videoPlayer , SelectTree } ,
directives : { waves } ,
data ( ) {
return {
listLoading : true ,
add : false ,
del : false ,
edit : false ,
listQuery : {
page : 1 ,
limit : 10
} ,
total : 0 ,
config : config ,
KEYWORDS : '' ,
teacherKey : '' ,
trainingSectionKey : '' ,
TRAINTYPE : '' ,
POSTTYPE : '' ,
2024-03-27 14:31:47 +08:00
trainLevelList : [ ] ,
TRAINLEVEL : '' ,
2024-01-22 11:32:01 +08:00
vidSate : '' ,
varList : [ ] ,
pd : [ ] ,
form : {
COURSEWARENAME : '' , // 课件名称
SPEAKER : '' , // 主讲人
COURSEWAREINTRODUCE : '' , // 课件介绍
VIDEOFILES : '' , // 课件文件路径
VIDEOCAPTURE : '' , // 课件截图
VIDEOUSERS : [ ] , // 适用人员
vfile : '' ,
vcfile : '' ,
CLASSHOUR : 0 ,
dialogVisible : false ,
fileIsType : true ,
trainingSection : [ ] ,
relatedTerm : [ ] ,
2024-03-27 14:31:47 +08:00
captureIsType : true ,
INDUSTRY _ALL _TYPE : [ ] ,
INDUSTRY _ALL _NAME : [ ] ,
TRAINTYPE : '' ,
POSTTYPE : '' ,
POSTTYPE _NAME : '' ,
TRAINTYPE _NAME : '' ,
INDUSTRY1 : '' ,
INDUSTRY2 : '' ,
INDUSTRY _END _ID : '' ,
INDUSTRY _END _ID _NAME : ''
2024-01-22 11:32:01 +08:00
} ,
hideUpload : false , // 显示图片
fileList : [ ] ,
defaultProps : {
value : 'id' ,
children : 'nodes' ,
label : 'name' ,
multiple : true ,
checkStrictly : true
} ,
multipleSelectionAll : [ ] , // 所有选中的数据包含跨页数据
multipleSelection : [ ] , // 当前页选中的数据
dialogFormEdit : false ,
dialogType : 'add' ,
LearnerCategoryList : [ ] ,
serverurl : config . fileUrl ,
dialogViewVideo : false ,
playerOptions : {
playbackRates : [ 0.5 , 1.0 , 1.5 , 2.0 ] , // 可选的播放速度
autoplay : false , // 如果为true,浏览器准备好时开始回放。
muted : false , // 默认情况下将会消除任何音频。
loop : false , // 是否视频一结束就重新开始。
preload : 'auto' , // 建议浏览器在<video>加载元素后是否应该开始下载视频数据。auto浏览器选择最佳行为,立即开始加载视频(如果浏览器支持)
language : 'zh-CN' ,
aspectRatio : '16:9' , // 将播放器置于流畅模式,并在计算播放器的动态大小时使用该值。值应该代表一个比例 - 用冒号分隔的两个数字(例如"16:9"或"4:3")
fluid : true , // 当true时, Video.js player将拥有流体大小。换句话说, 它将按比例缩放以适应其容器。
sources : [ {
type : 'video/mp4' , // 类型
src : 'https://whrx.qhdsafety.com/file/uploadFiles/file/13cf0f4ec77e4d98ae8cdd9c3386ae0c/20210625/691910cd81024986a392f6203c4045f8.mp4' // url地址
} ] ,
poster : '' , // 封面地址
notSupportedMessage : '此视频暂无法播放,请稍后再试' , // 允许覆盖Video.js无法播放媒体源时显示的默认信息。
controlBar : {
timeDivider : true , // 当前时间和持续时间的分隔符
durationDisplay : true , // 显示持续时间
remainingTimeDisplay : true , // 是否显示剩余时间功能
fullscreenToggle : true // 是否显示全屏按钮
}
} ,
rules : {
COURSEWARENAME : [ { required : true , message : '课件名称不能为空' , trigger : 'blur' } ] ,
2024-03-27 14:31:47 +08:00
// trainAllName: [{ required: true, message: '请选择培训类型', trigger: 'change' }],
POSTTYPE : [ { required : true , message : '请选择岗位培训类型' , trigger : 'blur' } ] ,
2024-01-22 11:32:01 +08:00
CLASSHOUR : [ { required : true , message : '课件学时不能为空' , trigger : 'blur' } ] ,
SPEAKER : [ { required : true , message : '讲师名称不能为空' , trigger : 'blur' } ] ,
COURSEWAREINTRODUCE : [ { required : true , message : '课件描述不能为空' , trigger : 'blur' } ] ,
2024-03-27 14:31:47 +08:00
ONTLINETYPE : [ { required : true , message : '请选择大纲类型' , trigger : 'blur' } ]
2024-01-22 11:32:01 +08:00
} ,
dicListMap : {
outlineDicList : [ ] ,
trainDicList : [ ] ,
postDicList : [ ] ,
trainingSectionList : [ ] ,
relatedTermList : [ ]
} ,
teacherAllList : [ ] ,
vidStateList : [ { value : '0' , label : '启用' } ,
{ value : '1' , label : '禁用' }
] ,
authProgress : 0 ,
isShowProgress : false ,
player : { } ,
isEditVideo : false ,
2024-03-27 14:31:47 +08:00
file : { } ,
// 行业类型树
treeLoading : false ,
industryTreeData : [ ] ,
industryProps : {
children : 'nodes' ,
value : 'INDUSTRYTYPE_ID' ,
label : 'NAME'
} ,
trainAllName : '' ,
dialogFormVisible : false ,
postList : [ ] ,
trainingList : [ ] ,
defaultExpanded : [ ] ,
defaultChecked : [ ] ,
initFlag : false ,
POSTTYPE _NAME : '' ,
TRAINTYPE _NAME : '' ,
INDUSTRY1 : '' ,
INDUSTRY2 : '' ,
INDUSTRY _END _ID : '' ,
INDUSTRY _END _ID _NAME : '' ,
filterText : ''
}
} ,
watch : {
// 'TRAINTYPE': {
// handler(newVal, oldVal) {
// console.info(oldVal)
// // if (this.dialogType == 'add' || (oldVal != null && oldVal != '')) { // 编辑初始化时,不监听
// this.POSTTYPE = ''
// this.POSTTYPE_NAME = ''
// this.getPostList()
// this.INDUSTRY1 = ''
// this.INDUSTRY2 = ''
// this.INDUSTRY_END_ID = ''
// this.INDUSTRY_END_ID_NAME = ''
// this.industryTreeData = []
// // }
// },
// immediate: false
// },
'POSTTYPE' : {
handler ( ) {
// if (!this.initFlag) {
// this.initFlag = true
// }
// this.INDUSTRY1 = ''
// this.INDUSTRY2 = ''
// this.INDUSTRY_END_ID = ''
// this.INDUSTRY_END_ID_NAME = ''
// this.getTreeList()
}
} ,
'filterText' : {
handler ( val ) {
this . $refs . tree . filter ( val )
}
2024-01-22 11:32:01 +08:00
}
} ,
2024-03-27 14:31:47 +08:00
created ( ) {
this . getTrainingList ( )
this . getTeacher ( )
// this.getPostList()
this . getTreeList ( )
this . getDicListByPID ( '4459d3ff36d1475d8b2266da959fcc44' , 'relatedTermList' ) // 相关词条
if ( this . $parent . COURSEWAREID ) {
this . dialogType = 'edit'
this . getData ( )
}
2024-01-22 11:32:01 +08:00
} ,
methods : {
2024-03-27 14:31:47 +08:00
selectIndustry ( ) {
this . form . TRAINTYPE = this . TRAINTYPE
this . form . POSTTYPE = this . POSTTYPE
this . form . POSTTYPE _NAME = this . POSTTYPE _NAME
this . form . TRAINTYPE _NAME = this . TRAINTYPE _NAME
this . form . INDUSTRY1 = this . INDUSTRY1
this . form . INDUSTRY2 = this . INDUSTRY2
this . form . INDUSTRY _END _ID = this . INDUSTRY _END _ID
this . form . INDUSTRY _END _ID _NAME = this . INDUSTRY _END _ID _NAME
// var pn = this.form.POSTTYPE_NAME ? '-' + this.form.POSTTYPE_NAME : ''
// var iname = this.form.INDUSTRY_END_ID_NAME ? '-' + this.form.INDUSTRY_END_ID_NAME : ''
const tName = [ ]
tName . push ( this . TRAINTYPE _NAME == '' ? '1' : this . TRAINTYPE _NAME )
tName . push ( this . INDUSTRY _END _ID _NAME == '' ? '1' : this . INDUSTRY _END _ID _NAME )
tName . push ( this . POSTTYPE _NAME == '' ? '1' : this . POSTTYPE _NAME )
const tName2 = tName . filter ( item => {
return item !== '1'
} )
// this.form.trainAllName = this.form.TRAINTYPE_NAME + iname + pn
this . form . trainAllName = tName2 . join ( '-' ) . replace ( ',' , '' )
this . dialogFormVisible = false
} ,
treeCheck ( data , list ) {
let thisNode = this . $refs . tree . getNode ( data ) // 获取当前节点
this . form . INDUSTRY _ALL _TYPE = [ ]
this . form . INDUSTRY _ALL _NAME = [ ]
const keys = [ ] // 获取已勾选节点的key值
const names = [ ] // 获取已勾选节点的key值
keys . unshift ( thisNode . data . INDUSTRYTYPE _ID )
names . unshift ( thisNode . data . NAME )
if ( thisNode . checked ) { // 当前节点若被选中
for ( let i = thisNode . level ; i > 1 ; i -- ) {
// 当前子节点选中,取消勾选父节点
this . $refs . tree . setChecked ( thisNode . parent , false )
// 判断是否有父级节点
if ( ! thisNode . parent . checked ) { // 父级节点未被选中, 则将父节点替换成当前节点, 往上继续查询, 并将此节点key存入keys数组
thisNode = thisNode . parent
keys . unshift ( thisNode . data . INDUSTRYTYPE _ID )
names . unshift ( thisNode . data . NAME )
}
}
}
this . form . INDUSTRY _ALL _TYPE = keys
this . form . INDUSTRY _ALL _NAME = names
} ,
handleNodeClick ( node , data , value ) {
this . INDUSTRY _END _ID = node . INDUSTRYTYPE _ID
this . INDUSTRY _END _ID _NAME = node . NAME
// this.form.PARENT_ID = node.id
// this.getList(node.id)
} ,
filterNode ( value , data ) {
if ( ! value ) return true
return data . NAME . indexOf ( value ) !== - 1
} ,
checkPost ( item ) {
this . $set ( this , 'POSTTYPE' , item . POSTTYPE _ID )
this . $set ( this , 'POSTTYPE_NAME' , item . NAME )
// this.form.POSTTYPE = id
} ,
checkTrain ( item ) {
this . getPostList ( item . TRAININGTYPE _ID )
this . $set ( this , 'TRAINTYPE' , item . TRAININGTYPE _ID )
this . $set ( this , 'TRAINTYPE_NAME' , item . NAME )
// this.form.TRAINTYPE = id
} ,
// 培训类型
getTrainingList ( ) {
requestFN (
'/trainingtype/listAll' ,
{ }
) . then ( ( data ) => {
this . trainingList = data . varList
} ) . catch ( ( e ) => {
} )
} ,
// 岗位类型
getPostList ( TRAININGTYPE _ID ) {
requestFN (
'/posttype/listAll' ,
{ TRAININGTYPE _ID : TRAININGTYPE _ID }
) . then ( ( data ) => {
this . postList = data . varList
} ) . catch ( ( e ) => {
} )
} ,
// 行业类型树
getTreeList ( ) {
this . treeLoading = true
requestFN (
'/industrytype/getIndustryTree' ,
{ }
) . then ( ( data ) => {
this . treeLoading = false
this . industryTreeData = data . zTreeNodes
} ) . catch ( ( e ) => {
this . treeLoading = false
} )
} ,
2024-01-22 11:32:01 +08:00
getRowKey ( row ) {
return row . VIDEOCOURSEWARE _ID
} ,
// 搜索
getQuery ( ) {
this . $refs . multipleTable . clearSelection ( )
this . getList ( )
} ,
goKeyReset ( ) {
this . KEYWORDS = ''
this . TRAINTYPE = ''
this . POSTTYPE = ''
this . vidSate = ''
this . teacherKey = ''
this . $refs . keyGwRef . clearHandle ( )
this . $refs . trainingSectionRef . clearHandle ( )
this . $refs . keyTrainTypeRef . clearHandle ( )
this . getQuery ( )
} ,
// 获取列表
getList ( ) {
this . listLoading = true
requestFN (
'/videocourseware/list?showCount=' + this . listQuery . limit + '¤tPage=' + this . listQuery . page ,
{
KEYWORDS : this . KEYWORDS ,
TRAINTYPE : this . TRAINTYPE ,
POSTTYPE : this . POSTTYPE ,
STATE : this . vidSate ,
teacherKey : this . teacherKey ,
trainingSectionKey : this . trainingSectionKey
}
) . then ( ( data ) => {
this . listLoading = false
this . varList = data . varList
this . total = data . page . totalResult
this . hasButton ( )
this . pd = data . pd
} ) . catch ( ( e ) => {
this . listLoading = false
} )
} ,
// 格式化适用人员名称
formatterUsers ( row , column ) {
var VIDEOUSERS _VAL = ''
const VIDEOUSERS = row . VIDEOUSERS . slice ( 1 , row . VIDEOUSERS . length - 1 ) . split ( ',' )
for ( let i = 0 ; i < VIDEOUSERS . length ; i ++ ) {
for ( let j = 0 ; j < this . LearnerCategoryList . length ; j ++ ) {
const option = this . LearnerCategoryList [ j ]
if ( option . BIANMA === VIDEOUSERS [ i ] ) {
VIDEOUSERS _VAL += option . NAME + ','
}
}
}
return VIDEOUSERS _VAL . slice ( 0 , VIDEOUSERS _VAL . length - 1 )
} ,
// 添加
handleAdd ( ) {
2024-03-27 14:31:47 +08:00
this . $parent . COURSEWAREID = ''
this . $parent . activeName = 'Edit'
// this.dialogType = 'add'
// this.resetForm()
// // this.getDict()
// this.dialogFormEdit = true
2024-01-22 11:32:01 +08:00
} ,
2024-03-27 14:31:47 +08:00
getData ( ) {
2024-01-22 11:32:01 +08:00
// this.getDict()
this . resetForm ( )
requestFN (
'/videocourseware/goEdit' ,
{
2024-03-27 14:31:47 +08:00
VIDEOCOURSEWARE _ID : this . $parent . COURSEWAREID
2024-01-22 11:32:01 +08:00
}
) . then ( ( data ) => {
this . form = Object . assign ( { } , data . pd ) // copy obj
2024-03-27 14:31:47 +08:00
this . form . trainAllName = data . pd . TYPENAME
// // console.info(this.form)
// // //培训板块 相关词条 回显
// var relatedTermIDS = [] // 相关词条
// data.coursewareAllList.forEach((item, index) => {
// if (item.RECORD_TYPE_ID == 'relatedTerm') {
// const valID = item.DICTIONARIES_IDS.split(',')
// relatedTermIDS.push(valID)
// }
// })
// this.trainAllName = data.pd.TRAININGTYPE_NAME + '-' + data.pd.POSTTYPE_NAME + '-' + data.pd.INDUSTRY_END_ID_NAME
// this.form.relatedTerm = relatedTermIDS
// // this.form.VIDEOUSERS = this.form.VIDEOUSERS.slice(1, this.form.VIDEOUSERS.length - 1).split(',')
// this.form.COURSEWARENAME_update = this.form.COURSEWARENAME
// this.form.fileIsType = false
// this.form.captureIsType = false
// this.TRAINTYPE = this.form.TRAINTYPE
// this.POSTTYPE = this.form.POSTTYPE
// this.INDUSTRY1 = this.form.INDUSTRY1
// this.INDUSTRY2 = this.form.INDUSTRY2
// this.INDUSTRY_END_ID = this.form.INDUSTRY_END_ID
// this.defaultExpanded = [this.INDUSTRY1, this.INDUSTRY2, this.INDUSTRY_END_ID]
// this.defaultChecked = [this.INDUSTRY1, this.INDUSTRY2, this.INDUSTRY_END_ID]
// this.getPostList()
// this.getTreeList()
2024-01-22 11:32:01 +08:00
this . dialogFormEdit = true
} ) . catch ( ( e ) => {
this . listLoading = false
} )
} ,
2024-03-27 14:31:47 +08:00
2024-01-22 11:32:01 +08:00
// 修改
handleEditState ( ID , state ) {
requestFN (
'/videocourseware/editState' ,
{
VIDEOCOURSEWARE _ID : ID ,
STATE : state
}
) . then ( ( data ) => {
this . getList ( )
} ) . catch ( ( e ) => {
this . listLoading = false
} )
} ,
validStr ( str ) {
if ( str != null && str != '' && typeof ( str ) != 'undefined' && str != 0 ) { return true }
return false
} ,
// 保存
confirm ( ) {
2024-03-27 14:31:47 +08:00
// if (this.form.fileIsType) {
// if (!this.file) {
// this.$message.warning('课件文件不能为空,请上传')
// return false
// }
// }
// if (!this.form.INDUSTRY_END_ID) {
// this.$message.warning('请选择培训类型')
// return false
// }
2024-01-22 11:32:01 +08:00
this . $refs . form . validate ( valid => {
if ( valid ) {
Object . keys ( this . form ) . map ( key => {
2024-03-27 14:31:47 +08:00
if ( key == 'relatedTerm' && this . form [ key ] ) {
2024-01-22 11:32:01 +08:00
var relatedTermIDS = ''
this . form [ key ] . forEach ( ( item , index ) => {
relatedTermIDS += item + ';'
} )
this . form . relatedTerm = relatedTermIDS
// formData.append('relatedTerm', relatedTermIDS)
}
} )
2024-03-27 14:31:47 +08:00
requestFN (
'/videocourseware/complete' ,
this . form
) . then ( ( data ) => {
this . $message ( {
message : data . message ,
type : data . type
} )
this . isShowProgress = false
2024-01-22 11:32:01 +08:00
this . dialogFormEdit = false
2024-03-27 14:31:47 +08:00
this . $parent . activeName = 'List'
// this.getList()
} ) . catch ( ( e ) => {
} )
2024-01-22 11:32:01 +08:00
} else {
return false
}
} )
} ,
closePlayer ( ) {
this . player . dispose ( )
} ,
saveInfo ( ) {
requestFN (
'/videocourseware/' + this . dialogType ,
this . form
) . then ( ( data ) => {
this . $message ( {
2024-03-27 14:31:47 +08:00
message : data . message ,
2024-01-22 11:32:01 +08:00
type : data . type
} )
this . isShowProgress = false
this . dialogFormEdit = false
2024-03-27 14:31:47 +08:00
this . $parent . activeName = 'refreshList'
// this.getList()
2024-01-22 11:32:01 +08:00
} ) . catch ( ( e ) => {
} )
} ,
handleQuestion ( ID ) {
this . $parent . COURSEWAREID = ID
this . $parent . COURSEWARETYPE = '1'
this . $parent . activeName = 'Question'
} ,
beforeVideoFileUpload ( file ) {
const types = [ 'video/mp4' ]
const isImage = types . includes ( file . type )
const isLt500M = file . size / 1024 / 1024 < 500
if ( this . fileList . length > 0 ) {
this . $message . error ( '文件超出个数限制!' )
return false
}
if ( ! isImage ) {
this . $message . error ( '上传视频只能是 MP4 格式!' )
return false
} else if ( ! isLt500M ) {
this . $message . error ( '上传视频大小不能超过 500MB!' )
return false
} else {
// const filistMap = {}
// console.info(file)
// filistMap.name = file.name
// file.status = 'success'
// filistMap.file = file
this . fileList . push ( file )
this . $forceUpdate ( )
return true
}
} ,
beforeFCaptureileUpload ( file ) {
const types = [ 'image/jpeg' , 'image/jpg' , 'image/png' ]
const isImage = types . includes ( file . type )
if ( ! isImage ) {
this . $message . error ( '上传图片只能是 JPG、JPEG、PNG 格式!' )
} else {
this . form . vcfile = file
this . form . VIDEOCAPTURE = file
}
} ,
handlePictureCardPreview ( file , fileList ) {
this . form . vcfile = file
this . form . VIDEOCAPTURE = file
this . form . dialogImageUrl = file . url
this . form . dialogVisible = true
} ,
handleRemove ( file , fileList ) {
this . form . vcfile = file
this . form . VIDEOCAPTURE = file
this . hideUpload = fileList . length >= 1
} ,
handleEditChange ( file , fileList ) {
this . form . vcfile = file
this . form . VIDEOCAPTURE = file
this . hideUpload = fileList . length >= 1
} ,
handleRemoveVideo ( file , fileList ) { // 文件列表移除文件时的钩子
this . fileList = [ ]
} ,
handleUploadVideoExceed ( file , fileList ) { // 上传超出数量限制时的钩子
this . $message . warning ( '最多上传1个课件哦! ' )
} ,
// eslint-disable-next-line handle-callback-err
handleUploadVideoError ( err , file , fileList ) {
this . fileList = fileList
file . status = 'success'
this . fileList . push ( file )
} ,
handleDelete ( id ) {
this . $confirm ( '确定要删除吗?' , {
confirmButtonText : '确定' ,
cancelButtonText : '取消' ,
type : 'warning'
} ) . then ( ( ) => {
this . listLoading = true
requestFN (
'/videocourseware/delete' ,
{
VIDEOCOURSEWARE _ID : id
}
) . then ( ( ) => {
this . $message ( {
message : '删除成功' ,
type : 'success'
} )
this . listLoading = false
this . varList = [ ]
this . listQuery . page = 1
this . getList ( )
} ) . catch ( ( e ) => {
this . listLoading = false
} )
} ) . catch ( ( ) => {
} )
} ,
batchDel ( ) {
const _selectData = this . $refs . multipleTable . selection
if ( _selectData == null || _selectData . length == 0 ) {
this . $message ( {
message : '请选中要删除的项...' ,
type : 'error'
} )
return false
}
const ids = _selectData . map ( ( item , index ) => {
return item . VIDEOCOURSEWARE _ID
} ) . join ( ',' )
this . $confirm ( '确定要删除选中的数据吗?' , {
confirmButtonText : '确定' ,
cancelButtonText : '取消' ,
type : 'warning'
} ) . then ( ( ) => {
this . listLoading = true
requestFN (
'/videocourseware/deleteAll' ,
{
DATA _IDS : ids
}
) . then ( ( ) => {
this . $message ( {
message : '删除成功' ,
type : 'success'
} )
this . listLoading = false
this . varList = [ ]
this . listQuery . page = 1
this . $refs . multipleTable . clearSelection ( )
this . getList ( )
} ) . catch ( ( e ) => {
this . listLoading = false
} )
} ) . catch ( ( ) => {
} )
} ,
// 判断按钮权限,用于是否显示按钮
hasButton : function ( ) {
var keys = 'courseware:add,courseware:del,courseware:edit,toExcel'
requestFN (
'/head/hasButton' ,
{
keys : keys
}
) . then ( ( data ) => {
this . add = data . coursewarefhadminadd // 新增权限
this . del = data . coursewarefhadmindel // 删除权限
this . edit = data . coursewarefhadminedit // 修改权限
} ) . catch ( ( e ) => {
this . listLoading = false
} )
} ,
// 获取数据字典数据
getDict : function ( ) {
requestFN (
'/dictionaries/getLevels' ,
{
DICTIONARIES _ID : '3c0d9b5e74834adfacb76139e5d731e5'
}
) . then ( ( data ) => {
this . dicListMap . outlineDicList = data . list
} ) . catch ( ( e ) => {
} )
} ,
resetForm ( ) {
this . form = {
COURSEWARENAME : '' , // 课件名称
SPEAKER : '' , // 主讲人
COURSEWAREINTRODUCE : '' , // 课件介绍
VIDEOFILES : '' , // 课件文件路径
VIDEOCAPTURE : '' , // 课件截图
VIDEOUSERS : '' , // 适用人员
vfile : '' ,
vcfile : '' ,
CLASSHOUR : 0 ,
TRAINTYPE : '' ,
POSTTYPE : '' ,
ONTLINETYPE : '' ,
fileIsType : true ,
captureIsType : true
}
if ( this . $refs . pxTree ) {
this . $refs . pxTree . clearHandle ( )
}
if ( this . $refs . gwTree ) {
this . $refs . gwTree . clearHandle ( )
}
if ( this . $refs . videoUpload ) {
this . $refs . videoUpload . clearFiles ( )
}
if ( this . $refs . videoCaptureUpload ) {
this . form . vcfile = ''
this . form . VIDEOCAPTURE = ''
this . hideUpload = false
this . $refs . videoCaptureUpload . clearFiles ( )
}
} ,
goViewVideo ( row ) {
2024-03-27 14:31:47 +08:00
requestFN (
'/videocourseware/getVideoPlayInfo' ,
{
VIDEOCOURSEWARE _ID : row . VIDEOCOURSEWARE _ID
}
) . then ( ( data ) => {
if ( data . result == 'success' ) {
this . dialogViewVideo = true
this . $nextTick ( ( ) => {
// eslint-disable-next-line no-undef
this . player = new Aliplayer ( {
id : 'aLiVideoPlayer' ,
source : JSON . stringify ( data . urlList ) ,
width : '100%' ,
height : '500px' ,
autoplay : true ,
isLive : false ,
components : [ {
name : 'QualityComponent' ,
// eslint-disable-next-line no-undef
type : AliPlayerComponent . QualityComponent ,
args : [ function ( definition , desc ) {
console . log ( definition + '-----' + desc )
2024-01-22 11:32:01 +08:00
} ]
2024-03-27 14:31:47 +08:00
} ]
} , function ( player ) {
console . log ( 'The player is created' )
/* Register the sourceloaded of the player, query the resolution of the video, invoke the resolution component, and call the setCurrentQuality method to set the resolution. */
player . on ( 'sourceloaded' , function ( params ) {
var paramData = params . paramData
var desc = paramData . desc
var definition = paramData . definition
player . getComponent ( 'QualityComponent' ) . setCurrentQuality ( desc , definition )
2024-01-22 11:32:01 +08:00
} )
} )
2024-03-27 14:31:47 +08:00
} )
} else {
this . $message . warning ( data . message )
}
} ) . catch ( ( e ) => {
} )
2024-01-22 11:32:01 +08:00
// const type = row.VIDEOFILES.slice(row.VIDEOFILES.lastIndexOf('.') + 1)
// this.playerOptions.sources[0].src = this.serverurl + row.VIDEOFILES
// this.playerOptions.poster = this.serverurl + row.VIDEOCAPTURE
// this.playerOptions.sources[0].type = 'video/' + type
} ,
// closePlay() {
// this.$refs.videoPlayer.player.pause()
// },
getDicListByPID ( pId , listName ) {
requestFN (
'/dictionaries/listAllDictToParId' ,
{
parentId : pId
}
) . then ( ( data ) => {
this . dicListMap [ listName ] = JSON . parse ( data . zTreeNodes )
} ) . catch ( ( e ) => {
} )
} ,
getIdcList ( ) {
this . getDicListByPID ( '052369aa22d242118236cde52d0c67ea' , 'trainDicList' )
this . getDicListByPID ( 'f6a7c4f5602f46e291d06b1390a3f820' , 'postDicList' )
2024-03-27 14:31:47 +08:00
// this.getDicListByPID('d538d11e4eec409ab428f5d2f3c67c24', 'trainingSectionList') // 培训板块
2024-01-22 11:32:01 +08:00
this . getDicListByPID ( '4459d3ff36d1475d8b2266da959fcc44' , 'relatedTermList' ) // 相关词条
this . getTeacher ( ) // 获取教师信息
} ,
delFujian ( ) {
this . fileList = [ ]
this . isEditVideo = true
this . form . COURSEWARENAME _update = ''
this . form . fileIsType = true
this . form = Object . assign ( { } , this . form )
// this.$forceUpdate()
} ,
delFujianTupian ( ) {
this . form . captureIsType = true
this . form . vcfile = ''
this . form . VIDEOCAPTURE = ''
this . hideUpload = false
} ,
getTeacher ( ) { // 获取教师信息
requestFN (
'/teacher/listAllSelect' ,
{ }
) . then ( ( data ) => {
this . teacherAllList = JSON . parse ( data . zTreeNodes )
} ) . catch ( ( e ) => {
} )
} ,
uploadFile ( ) {
this . $refs . fileUpload . dispatchEvent ( new MouseEvent ( 'click' ) )
} ,
2024-03-27 14:31:47 +08:00
goBack ( ) {
this . $parent . activeName = 'List'
} ,
2024-01-22 11:32:01 +08:00
fileChange ( e ) {
if ( ! e . target . files [ 0 ] ) {
this . $message . warning ( '请先选择需要上传的文件!' )
return
} else if ( e . target . files [ 0 ] . type != 'video/mp4' ) {
this . $message . warning ( '请选择MP4文件!' )
return
}
this . file = e . target . files [ 0 ]
// eslint-disable-next-line no-unused-vars
var Title = this . file . name
var userData = '{"Vod":{}}'
if ( this . uploader ) {
this . uploader . stopUpload ( )
this . authProgress = 0
this . statusText = ''
}
this . uploader = this . createUploader ( )
this . uploader . addFile ( this . file , null , null , null , userData )
this . uploadDisabled = false
this . pauseDisabled = true
this . resumeDisabled = true
} ,
authUpload ( ) {
// 然后调用 startUpload 方法, 开始上传
if ( this . uploader !== null ) {
this . uploader . startUpload ( )
this . uploadDisabled = true
this . pauseDisabled = false
}
} ,
// 暂停上传
pauseUpload ( ) {
if ( this . uploader !== null ) {
this . uploader . stopUpload ( )
this . resumeDisabled = false
this . pauseDisabled = true
}
} ,
// 恢复上传
resumeUpload ( ) {
if ( this . uploader !== null ) {
this . uploader . startUpload ( )
this . resumeDisabled = true
this . pauseDisabled = false
}
} ,
createUploader ( type ) {
const self = this
// eslint-disable-next-line no-undef
const uploader = new AliyunUpload . Vod ( {
timeout : self . timeout || 60000 ,
partSize : self . partSize || 1048576 ,
parallel : self . parallel || 5 ,
retryCount : self . retryCount || 3 ,
retryDuration : self . retryDuration || 2 ,
region : self . region ,
userId : self . userId ,
// 添加文件成功
addFileSuccess ( uploadInfo ) {
self . uploadDisabled = false
self . resumeDisabled = false
self . statusText = '添加文件成功, 等待上传...'
// console.log('addFileSuccess: ' + uploadInfo.file.name)
} ,
// 开始上传
onUploadstarted ( uploadInfo ) {
// 如果是 UploadAuth 上传方式, 需要调用 uploader.setUploadAuthAndAddress 方法
// 如果是 UploadAuth 上传方式, 需要根据 uploadInfo.videoId是否有值, 调用点播的不同接口获取uploadauth和uploadAddress
// 如果 uploadInfo.videoId 有值,调用刷新视频上传凭证接口,否则调用创建视频上传凭证接口
// 注意: 这里是测试 demo 所以直接调用了获取 UploadAuth 的测试接口, 用户在使用时需要判断 uploadInfo.videoId 存在与否从而调用 openApi
// 如果 uploadInfo.videoId 存在, 调用 刷新视频上传凭证接口(https://help.aliyun.com/document_detail/55408.html)
// 如果 uploadInfo.videoId 不存在,调用 获取视频上传地址和凭证接口(https://help.aliyun.com/document_detail/55407.html)
if ( ! uploadInfo . videoId ) {
2024-06-25 15:56:39 +08:00
const createUrl = config . httpurl + '/audioOrVideo/createUploadVideo?Title=' + uploadInfo . file . name + '&FileName=' + uploadInfo . file . name
2024-01-22 11:32:01 +08:00
axios . get ( createUrl ) . then ( ( { data } ) => {
const uploadAuth = data . body . uploadAuth
const uploadAddress = data . body . uploadAddress
const videoId = data . body . videoId
uploader . setUploadAuthAndAddress ( uploadInfo , uploadAuth , uploadAddress , videoId )
} )
self . statusText = '文件开始上传...'
console . log ( 'onUploadStarted:' + uploadInfo . file . name + ', endpoint:' + uploadInfo . endpoint + ', bucket:' + uploadInfo . bucket + ', object:' + uploadInfo . object )
} else {
// 如果videoId有值, 根据videoId刷新上传凭证
// https://help.aliyun.com/document_detail/55408.html?spm=a2c4g.11186623.6.630.BoYYcY
2024-06-25 17:04:34 +08:00
const refreshUrl = config . httpurl + '/audioOrVideo/refreshUploadVideo?Title=haha1&FileName=xxx.mp4&VideoId=' + uploadInfo . videoId
2024-01-22 11:32:01 +08:00
axios . get ( refreshUrl ) . then ( ( { data } ) => {
const uploadAuth = data . data . uploadAuth
const uploadAddress = data . data . uploadAddress
const videoId = data . data . videoId
uploader . setUploadAuthAndAddress ( uploadInfo , uploadAuth , uploadAddress , videoId )
} )
}
} ,
// 文件上传成功
onUploadSucceed ( uploadInfo ) {
console . log ( 'onUploadSucceed: ' + uploadInfo . file . name + ', endpoint:' + uploadInfo . endpoint + ', bucket:' + uploadInfo . bucket + ', object:' + uploadInfo . object )
self . statusText = '文件上传成功!'
self . uploadDisabled = true
self . resumeDisabled = true
self . form . videoId = uploadInfo . videoId
self . saveInfo ( )
} ,
// 文件上传失败
onUploadFailed ( uploadInfo , code , message ) {
console . log ( 'onUploadFailed: file:' + uploadInfo . file . name + ',code:' + code + ', message:' + message )
self . statusText = '文件上传失败!'
} ,
// 取消文件上传
onUploadCanceled ( uploadInfo , code , message ) {
console . log ( 'Canceled file: ' + uploadInfo . file . name + ', code: ' + code + ', message:' + message )
self . statusText = '文件已暂停上传'
} ,
// 文件上传进度,单位:字节, 可以在这个函数中拿到上传进度并显示在页面上
onUploadProgress ( uploadInfo , totalSize , progress ) {
console . log ( 'onUploadProgress:file:' + uploadInfo . file . name + ', fileSize:' + totalSize + ', percent:' + Math . ceil ( progress * 100 ) + '%' )
const progressPercent = Math . ceil ( progress * 100 )
self . authProgress = progressPercent
self . statusText = '文件上传中...'
// const loading = self.$loading({
// lock: true,
// text: self.authProgress,
// spinner: 'el-icon-loading',
// background: 'rgba(0, 0, 0, 0.7)'
// })
// if (self.authProgress == 100) {
// loading.close()
// self.$message({
// message: '视频课件保存成功',
// type: 'success'
// })
// self.dialogFormEdit = false
// self.getList()
// }
} ,
// 上传凭证超时
onUploadTokenExpired ( uploadInfo ) {
// 上传大文件超时, 如果是上传方式一即根据 UploadAuth 上传时
// 需要根据 uploadInfo.videoId 调用刷新视频上传凭证接口(https://help.aliyun.com/document_detail/55408.html)重新获取 UploadAuth
// 然后调用 resumeUploadWithAuth 方法, 这里是测试接口, 所以我直接获取了 UploadAuth
const refreshUrl = 'https://demo-vod.cn-shanghai.aliyuncs.com/voddemo/RefreshUploadVideo?BusinessType=vodai&TerminalType=pc&DeviceModel=iPhone9,2&UUID=59ECA-4193-4695-94DD-7E1247288&AppVersion=1.0.0&Title=haha1&FileName=xxx.mp4&VideoId=' + uploadInfo . videoId
axios . get ( refreshUrl ) . then ( ( { data } ) => {
const uploadAuth = data . UploadAuth
uploader . resumeUploadWithAuth ( uploadAuth )
console . log ( 'upload expired and resume upload with uploadauth ' + uploadAuth )
} )
self . statusText = '文件超时...'
} ,
// 全部文件上传结束
onUploadEnd ( uploadInfo ) {
console . log ( 'onUploadEnd: uploaded all the files' )
self . statusText = '文件上传完毕'
}
} )
return uploader
}
}
}
< / script >
< style lang = "scss" >
html {
touch - action : none ;
}
. hide . el - upload -- picture - card {
display : none ;
}
. popContainer {
position : fixed ;
top : 0 ;
left : 0 ;
right : 0 ;
bottom : 0 ;
z - index : 999999 ;
background : rgba ( 0 , 0 , 0 , 0.6 ) ;
. el - progress _ _text {
color : # fff ;
}
. progress _title {
position : relative ;
top : 35 % ;
color : # e8e8e8 ;
left : 44.7 % ;
text - shadow : # 000 1 px 1 px 2 px
}
. progress {
position : relative ;
top : 37 % ;
color : # fff ;
left : 46 % ;
// margin: auto;
}
}
< / style >
2024-03-27 14:31:47 +08:00
< style lang = "sass" scoped >
. el - row
margin - bottom : 16 px
& : last - child
margin - bottom : 0
. form - group
display : flex
align - items : center
margin - right : 20 px
. form - label
padding : 9 px 15 px
font - size : 14 px
width : 240 px
font - weight : 400
line - height : 20 px
text - align : right
margin - bottom : 0
. star
color : red
padding - right : 4 px
. input - block
flex : 1
min - height : 36 px
position : relative
. disContent
padding : 0 20 px
display : flex
align - items : center
flex - wrap : wrap
. img - div
position : relative
margin : auto 10 px 10 px 10 px
width : 120 px
height : 120 px
border - radius : 4 px
& > img
width : 100 %
height : 100 %
. disContent - hide
position : absolute
width : 100 %
height : 100 %
border - radius : 4 px
background - color : rgba ( 48 , 48 , 48 , 0.59 )
display : none
top : 0
left : 0
. Delete
position : absolute
bottom : 14 px
right : 10 px
font - size : 16 px
color : white
cursor : pointer
. editCss
. Delete
font - size : 16 px
right : 90 px
. yuLan
position : absolute
bottom : 23 px
right : 50 px
font - size : 16 px
color : white
cursor : pointer
. yuLanImg
position : absolute
bottom : 0
right : 0
width : 100 %
height : 100 %
opacity : 0
. img - div : hover . disContent - hide
display : block
. pitchCss
border : 1 px solid # 202 e78
transition : all linear 0.1 s
width : 116 px
height : 116 px
< / style >