integrated_traffic_admin_vue/src/views/studyResource/videocourseware/components/complete.vue

1202 lines
41 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<div class="app-warp">
<div class="detail-structure">
<el-page-header content="完善页面" @back="goBack"/>
<div class="detail-container">
<div class="level-title">
<h1>课件基本信息</h1>
</div>
<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="课件名称"/>
</el-form-item>
<el-form-item label="培训类型" prop="trainAllName">
<div @click="dialogFormVisible = true">
<el-input v-model="form.trainAllName" :readonly="true" maxlength="255" placeholder="这里输入培训类型..." title="培训类型"/>
</div>
</el-form-item>
<!-- <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">培训类型</el-button>
</el-form-item> -->
<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"/>
</el-select>
</el-form-item>
<el-form-item label="课件文件">
<div >
<a class="a_link" @click="goViewVideo(form)">[视频预览]</a>
</div>
</el-form-item>
<el-form-item v-if="!form.captureIsType && !form.fileIsType" label="课件截图">
<div class="img-size">
<img :src="form.VIDEOCAPTURE" width="100%" alt="">
</div>
</el-form-item>
<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="课件介绍"/>
</el-form-item>
<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/>
</el-form-item>
</el-form>
<div class="detail_foot">
<el-button type="primary" @click="confirm">保存</el-button>
<el-button icon="el-icon-arrow-left" @click="goBack">返回</el-button>
</div>
</div>
</div>
<div v-if="isShowProgress" class="popContainer">
<div class="progress_title">视频上传中,请耐心等待...</div>
<el-progress
:percentage="authProgress"
type="circle"
class="progress"/>
</div>
<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>
</div>
<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/>
</div>
<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"/>
</div>
</div>
<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>
</div>
</div>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible = false">取 消</el-button>
<el-button type="primary" @click="selectIndustry">确 定</el-button>
</div>
</el-dialog>
<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"/>
</el-dialog>
</div>
</template>
<script>
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: '',
trainLevelList: [],
TRAINLEVEL: '',
vidSate: '',
varList: [],
pd: [],
form: {
COURSEWARENAME: '', // 课件名称
SPEAKER: '', // 主讲人
COURSEWAREINTRODUCE: '', // 课件介绍
VIDEOFILES: '', // 课件文件路径
VIDEOCAPTURE: '', // 课件截图
VIDEOUSERS: [], // 适用人员
vfile: '',
vcfile: '',
CLASSHOUR: 0,
dialogVisible: false,
fileIsType: true,
trainingSection: [],
relatedTerm: [],
captureIsType: true,
INDUSTRY_ALL_TYPE: [],
INDUSTRY_ALL_NAME: [],
TRAINTYPE: '',
POSTTYPE: '',
POSTTYPE_NAME: '',
TRAINTYPE_NAME: '',
INDUSTRY1: '',
INDUSTRY2: '',
INDUSTRY_END_ID: '',
INDUSTRY_END_ID_NAME: ''
},
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' }],
// trainAllName: [{ required: true, message: '请选择培训类型', trigger: 'change' }],
POSTTYPE: [{ required: true, message: '请选择岗位培训类型', trigger: 'blur' }],
CLASSHOUR: [{ required: true, message: '课件学时不能为空', trigger: 'blur' }],
SPEAKER: [{ required: true, message: '讲师名称不能为空', trigger: 'blur' }],
COURSEWAREINTRODUCE: [{ required: true, message: '课件描述不能为空', trigger: 'blur' }],
ONTLINETYPE: [{ required: true, message: '请选择大纲类型', trigger: 'blur' }]
},
dicListMap: {
outlineDicList: [],
trainDicList: [],
postDicList: [],
trainingSectionList: [],
relatedTermList: []
},
teacherAllList: [],
vidStateList: [{ value: '0', label: '启用' },
{ value: '1', label: '禁用' }
],
authProgress: 0,
isShowProgress: false,
player: {},
isEditVideo: false,
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)
}
}
},
created() {
this.getTrainingList()
this.getTeacher()
// this.getPostList()
this.getTreeList()
this.getDicListByPID('4459d3ff36d1475d8b2266da959fcc44', 'relatedTermList') // 相关词条
if (this.$parent.COURSEWAREID) {
this.dialogType = 'edit'
this.getData()
}
},
methods: {
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
})
},
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 + '&currentPage=' + 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() {
this.$parent.COURSEWAREID = ''
this.$parent.activeName = 'Edit'
// this.dialogType = 'add'
// this.resetForm()
// // this.getDict()
// this.dialogFormEdit = true
},
getData() {
// this.getDict()
this.resetForm()
requestFN(
'/videocourseware/goEdit',
{
VIDEOCOURSEWARE_ID: this.$parent.COURSEWAREID
}
).then((data) => {
this.form = Object.assign({}, data.pd) // copy obj
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()
this.dialogFormEdit = true
}).catch((e) => {
this.listLoading = false
})
},
// 修改
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() {
// if (this.form.fileIsType) {
// if (!this.file) {
// this.$message.warning('课件文件不能为空,请上传')
// return false
// }
// }
// if (!this.form.INDUSTRY_END_ID) {
// this.$message.warning('请选择培训类型')
// return false
// }
this.$refs.form.validate(valid => {
if (valid) {
Object.keys(this.form).map(key => {
if (key == 'relatedTerm' && this.form[key]) {
var relatedTermIDS = ''
this.form[key].forEach((item, index) => {
relatedTermIDS += item + ';'
})
this.form.relatedTerm = relatedTermIDS
// formData.append('relatedTerm', relatedTermIDS)
}
})
requestFN(
'/videocourseware/complete',
this.form
).then((data) => {
this.$message({
message: data.message,
type: data.type
})
this.isShowProgress = false
this.dialogFormEdit = false
this.$parent.activeName = 'List'
// this.getList()
}).catch((e) => {
})
} else {
return false
}
})
},
closePlayer() {
this.player.dispose()
},
saveInfo() {
requestFN(
'/videocourseware/' + this.dialogType,
this.form
).then((data) => {
this.$message({
message: data.message,
type: data.type
})
this.isShowProgress = false
this.dialogFormEdit = false
this.$parent.activeName = 'refreshList'
// this.getList()
}).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) {
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)
}]
}]
}, 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)
})
})
})
} else {
this.$message.warning(data.message)
}
}).catch((e) => {
})
// 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')
// this.getDicListByPID('d538d11e4eec409ab428f5d2f3c67c24', 'trainingSectionList') // 培训板块
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'))
},
goBack() {
this.$parent.activeName = 'List'
},
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) {
const createUrl = config.httpurl + '/audioOrVideo/createUploadVideo?Title=' + uploadInfo.file.name + '&FileName=' + uploadInfo.file.name
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
const refreshUrl = config.httpurl + '/audioOrVideo/refreshUploadVideo?Title=haha1&FileName=xxx.mp4&VideoId=' + uploadInfo.videoId
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 1px 1px 2px
}
.progress {
position: relative;
top: 37%;
color: #fff;
left:46%;
// margin: auto;
}
}
</style>
<style lang="sass" scoped>
.el-row
margin-bottom: 16px
&:last-child
margin-bottom: 0
.form-group
display: flex
align-items: center
margin-right: 20px
.form-label
padding: 9px 15px
font-size: 14px
width: 240px
font-weight: 400
line-height: 20px
text-align: right
margin-bottom: 0
.star
color: red
padding-right: 4px
.input-block
flex: 1
min-height: 36px
position: relative
.disContent
padding: 0 20px
display: flex
align-items: center
flex-wrap: wrap
.img-div
position: relative
margin: auto 10px 10px 10px
width: 120px
height: 120px
border-radius: 4px
&>img
width: 100%
height: 100%
.disContent-hide
position: absolute
width: 100%
height: 100%
border-radius: 4px
background-color: rgba(48, 48, 48, 0.59)
display: none
top: 0
left: 0
.Delete
position: absolute
bottom: 14px
right: 10px
font-size: 16px
color: white
cursor: pointer
.editCss
.Delete
font-size: 16px
right: 90px
.yuLan
position: absolute
bottom: 23px
right: 50px
font-size: 16px
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: 1px solid #202e78
transition: all linear 0.1s
width: 116px
height: 116px
</style>