commit
This commit is contained in:
@@ -1,312 +0,0 @@
|
||||
<!--#
|
||||
layout("/layouts/platform.html"){
|
||||
#-->
|
||||
|
||||
<style>
|
||||
.avatar-uploader .el-upload {
|
||||
border: 1px dashed #d9d9d9;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.avatar-uploader .el-upload:hover {
|
||||
border-color: #409EFF;
|
||||
}
|
||||
|
||||
.avatar-uploader-icon {
|
||||
font-size: 28px;
|
||||
color: #8c939d;
|
||||
width: 178px;
|
||||
height: 178px;
|
||||
line-height: 178px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.avatar {
|
||||
width: 178px;
|
||||
height: 178px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.el-popover {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.descriptionContainer {
|
||||
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<div id="app" v-cloak>
|
||||
<guava ref="guava">
|
||||
<el-card shadow="never">
|
||||
<div class="btn-group tool-button mt5">
|
||||
<el-input placeholder="请输入内容" v-model="pageForm.searchKeyword" clearable
|
||||
@keyup.enter.native="doSearch">
|
||||
<el-select v-model="pageForm.searchName" slot="prepend" placeholder="查询类型"
|
||||
style="width: 120px;">
|
||||
<el-option label="标题" value="tea.title"></el-option>
|
||||
</el-select>
|
||||
</el-input>
|
||||
</div>
|
||||
|
||||
<div class="btn-group tool-button mt5">
|
||||
<el-select v-model="pageForm.typeId" clearable>
|
||||
<el-option v-for="item in videoTypeList" :label="item.typeName"
|
||||
:value="item.id"></el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
|
||||
<div class="btn-group tool-button mt5">
|
||||
<el-button type="primary" icon="el-icon-search" @click="doSearch">搜索</el-button>
|
||||
</div>
|
||||
|
||||
<div class="pull-right offscreen-right mt5">
|
||||
<el-button type="primary" @click="openAdd">
|
||||
<i class="ti-plus"></i>
|
||||
新增专辑
|
||||
</el-button>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<el-card shadow="never" class="mt10">
|
||||
<table-tool label="专辑列表" :app="this"></table-tool>
|
||||
<el-table :data="tableData" :size="tableSize" style="width: 100%">
|
||||
<el-table-column type="index" label="序号" width="80px"></el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
header-align="center"
|
||||
v-for="column in tableColumns"
|
||||
show-overflow-tooltip
|
||||
:label="column.label"
|
||||
:prop="column.prop"
|
||||
:sortable="column.sortable"
|
||||
>
|
||||
<template v-if="column.prop==='cover'" scope="{row}">
|
||||
<el-popover
|
||||
placement="top-start"
|
||||
width="100"
|
||||
trigger="hover">
|
||||
<el-image
|
||||
style="height: 100px;width: 100px"
|
||||
:src="APP_DOMAIN+FILE_STREAM_PREVIEW_ADDRESS+'?id='+row.cover"
|
||||
fit="cover">
|
||||
<div slot="error" class="image-slot">
|
||||
<i class="el-icon-picture-outline"></i>
|
||||
</div>
|
||||
</el-image>
|
||||
<el-image
|
||||
slot="reference"
|
||||
style="height: 30px;width: 30px"
|
||||
:src="APP_DOMAIN+FILE_STREAM_PREVIEW_ADDRESS+'?id='+row.cover"
|
||||
fit="cover">
|
||||
<div slot="error" class="image-slot">
|
||||
<i class="el-icon-picture-outline"></i>
|
||||
</div>
|
||||
</el-image>
|
||||
</el-popover>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" header-align="center" label="操作" width="250">
|
||||
<template scope="{row}">
|
||||
<el-button size="small" @click="openView(row)">查看</el-button>
|
||||
<el-button size="small" type="primary" @click="openEdit(row)">编辑</el-button>
|
||||
<el-button size="small" type="danger" @click="doDelete(row.id)">删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!--#include("/layouts/pagination.html"){}#-->
|
||||
</el-card>
|
||||
|
||||
<template #edit>
|
||||
<el-form :model="formData" :rules="rules" ref="ruleForm" label-width="100px"
|
||||
>
|
||||
<el-form-item label="专辑标题" prop="title">
|
||||
<el-input v-model="formData.title" maxlength="30"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="专辑类型" prop="typeId">
|
||||
<el-select v-model="formData.typeId">
|
||||
<el-option v-for="item in videoTypeList" :label="item.typeName"
|
||||
:value="item.id"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="专辑简介" prop="description">
|
||||
<!-- <el-input type="textarea" :rows="3" v-model="formData.description"></el-input>-->
|
||||
<div id="descriptionEditor"></div>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="封面图片" prop="cover">
|
||||
<el-upload
|
||||
class="avatar-uploader"
|
||||
:action="FILE_UPLOAD_ADDRESS"
|
||||
:show-file-list="false"
|
||||
:on-success="handleAvatarSuccess"
|
||||
:before-upload="beforeAvatarUpload">
|
||||
<img v-if="formData.cover"
|
||||
:src="APP_DOMAIN+FILE_STREAM_PREVIEW_ADDRESS+'?id='+formData.cover"
|
||||
class="avatar">
|
||||
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
<el-form-item class="text-right">
|
||||
<el-button type="primary" @click="doHandle">确定</el-button>
|
||||
<el-button @click="$refs.guava.index()">取消</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<template #view>
|
||||
<el-form label-width="100px" label-suffix=":">
|
||||
<el-form-item label="专辑标题">
|
||||
<span>
|
||||
{{viewData.title}}
|
||||
</span>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="专辑类型">
|
||||
<span>{{viewData.typeName}}</span>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="专辑简介">
|
||||
<div v-html="viewData.description" class="descriptionContainer"></div>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="封面图片" prop="cover">
|
||||
<file-upload :files="viewFiles" view></file-upload>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
</guava>
|
||||
</div>
|
||||
|
||||
|
||||
<script>
|
||||
|
||||
<!--#include("/platform/trainEdu/include/include.js"){}#-->
|
||||
|
||||
let descriptionEditor = null
|
||||
|
||||
var vue = new Vue({
|
||||
el: '#app',
|
||||
mixins: [initTableMixins],
|
||||
data() {
|
||||
return {
|
||||
viewFiles: [],
|
||||
pageForm: {
|
||||
searchName: 'tea.title'
|
||||
},
|
||||
formData: {
|
||||
cover: null,
|
||||
title: null,
|
||||
description: null,
|
||||
typeId: null
|
||||
},
|
||||
tableColumns: [
|
||||
{prop: 'title', label: '标题'},
|
||||
{prop: 'cover', label: '封面'},
|
||||
{prop: 'videoCount', label: '视频数量'},
|
||||
{prop: 'typeName', label: '专辑类型'},
|
||||
],
|
||||
rules: {
|
||||
title: [{required: true, message: '请输入标题', trigger: ['change', 'blur']}],
|
||||
description: [{required: true, message: '请输入简介', trigger: ['change', 'blur']}],
|
||||
cover: [{required: true, message: '请上传封面图片', trigger: ['change', 'blur']}],
|
||||
typeId: [{required: true, message: '请选择专辑类型', trigger: ['change', 'blur']}],
|
||||
},
|
||||
videoTypeList: [],
|
||||
viewData: {}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
openAdd() {
|
||||
this.$refs['guava'].edit()
|
||||
this.$refs['ruleForm'].resetFields()
|
||||
this.formData.id = undefined
|
||||
this.$nextTick(() => {
|
||||
$("#descriptionEditor").html("")
|
||||
descriptionEditor = new wangEditor("#descriptionEditor")
|
||||
descriptionEditor.config.onchange = (html) => {
|
||||
this.formData.description = html
|
||||
}
|
||||
descriptionEditor.config.uploadImgShowBase64 = true
|
||||
descriptionEditor.create()
|
||||
descriptionEditor.txt.html()
|
||||
})
|
||||
},
|
||||
async handleAvatarSuccess(res, file) {
|
||||
this.$set(this.formData, 'cover', res.data.id)
|
||||
await this.$refs['ruleForm'].validate()
|
||||
},
|
||||
beforeAvatarUpload(file) {
|
||||
const allow = ['image/jpeg', 'image/png']
|
||||
if (!allow.includes(file.type)) {
|
||||
this.$message.error('上传头像图片只能是 JPG、PNG 格式!')
|
||||
return false
|
||||
}
|
||||
return true
|
||||
},
|
||||
async doHandle() {
|
||||
const valid = await this.$refs['ruleForm'].validate()
|
||||
if (valid) {
|
||||
const methodName = typeof this.formData.id === 'undefined' ? '/doAdd' : '/doEdit'
|
||||
const resp = await $.post(loc() + methodName, this.formData)
|
||||
if (resp.code === 0) {
|
||||
this.notifySuccess(resp.msg)
|
||||
this.doSearch()
|
||||
this.$refs['guava'].index()
|
||||
} else {
|
||||
this.notifyError(resp.msg)
|
||||
}
|
||||
}
|
||||
},
|
||||
openView(row) {
|
||||
this.viewData = {...row}
|
||||
this.viewFiles = [{id: row.cover, filename: row.cover + '.jpg'}]
|
||||
this.$refs.guava.view()
|
||||
},
|
||||
openEdit(row) {
|
||||
this.$refs['guava'].edit()
|
||||
this.formData = JSON.parse(JSON.stringify(row))
|
||||
this.$nextTick(() => {
|
||||
$("#descriptionEditor").html("")
|
||||
descriptionEditor = new wangEditor("#descriptionEditor")
|
||||
descriptionEditor.config.onchange = (html) => {
|
||||
this.formData.description = html
|
||||
}
|
||||
descriptionEditor.config.uploadImgShowBase64 = true
|
||||
descriptionEditor.create()
|
||||
descriptionEditor.txt.html(row.description)
|
||||
})
|
||||
},
|
||||
async doDelete(id) {
|
||||
const confirm = await this.$confirm('确定删除吗?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
})
|
||||
if (confirm === 'confirm') {
|
||||
const resp = await $.post(loc() + '/doDelete', {id})
|
||||
if (resp.code === 0) {
|
||||
this.$notify.success(resp.msg)
|
||||
this.doSearch()
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
async created() {
|
||||
this.videoTypeList = await getVideoType()
|
||||
this.pageData()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
@@ -1,9 +0,0 @@
|
||||
const getAllAlbum = async () => {
|
||||
const {data} = await $.get('/platform/trainEdu/album/getAllAlbum')
|
||||
return data
|
||||
}
|
||||
|
||||
const getVideoType = async () => {
|
||||
const resp = await $.get('/platform/trainEdu/type/pageData', {pageForm: 1, pageSize: 10000})
|
||||
return resp.data.list
|
||||
}
|
||||
@@ -1,144 +0,0 @@
|
||||
<!--#
|
||||
layout("/layouts/platform.html"){
|
||||
#-->
|
||||
|
||||
<div id="app" v-cloak>
|
||||
|
||||
<guava ref="guava">
|
||||
|
||||
<el-card shadow="never">
|
||||
<div class="search">
|
||||
<div class="search-item" v-if="pageForm.searchType==='按分工会分析'">
|
||||
<div class="search-item-label">分工会:</div>
|
||||
<div class="search-item-option">
|
||||
<el-select placeholder="分工会" v-model="pageForm.unionId" style="width: 100%;"
|
||||
@change="unionChange"
|
||||
clearable
|
||||
filterable>
|
||||
<el-option v-for="item in unions" :label="item.unionname" :value="item.id"></el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="search-item" v-if="pageForm.searchType==='按单位分析'">
|
||||
<div class="search-item-label">单位:</div>
|
||||
<div class="search-item-option">
|
||||
<el-select placeholder="单位" v-model="pageForm.unitId" style="width: 100%;"
|
||||
@change="unitChange"
|
||||
clearable
|
||||
filterable>
|
||||
<el-option v-for="item in units" :label="item.name" :value="item.id"></el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="offscreen-right pull-right">
|
||||
<el-radio-group v-model="pageForm.searchType" @change="searchTypeChange">
|
||||
<el-radio-button label="按分工会分析"></el-radio-button>
|
||||
<el-radio-button label="按单位分析"></el-radio-button>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<el-card shadow="never" class="mt10">
|
||||
<table-tool label="统计" :app="this"></table-tool>
|
||||
<el-table :data="tableData" :size="tableSize" style="width: 100%">
|
||||
<el-table-column type="index" label="序号" width="80px"></el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
header-align="center"
|
||||
v-for="column in tableColumns"
|
||||
show-overflow-tooltip
|
||||
:label="column.label"
|
||||
:prop="column.prop"
|
||||
:sortable="column.sortable"
|
||||
>
|
||||
<template v-if="column.prop==='unionName'" scope="{row}">
|
||||
{{isDisPlayCode?'('+row.unionCode+')':null}}{{row.unionName}}
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-card>
|
||||
</guava>
|
||||
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var vue = new Vue({
|
||||
el: '#app',
|
||||
mixins: [initTableMixins],
|
||||
data() {
|
||||
return {
|
||||
tableColumns: [
|
||||
{prop: 'unionName', label: '分工会名称'},
|
||||
{prop: 'unionCode', label: '分工会编码', sortable: true},
|
||||
{prop: 'unionSum', label: '总人数', sortable: true},
|
||||
{prop: 'studyNum', label: '学习人数', sortable: true},
|
||||
],
|
||||
unions: [],
|
||||
units: [],
|
||||
tableData: [],
|
||||
fullTableData: [],
|
||||
pageForm: {
|
||||
searchType: '按分工会分析'
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
unionChange(val) {
|
||||
if (val == null || val == '') {
|
||||
this.tableData = this.fullTableData
|
||||
} else {
|
||||
this.tableData = this.fullTableData.filter(v => v.id === val)
|
||||
}
|
||||
},
|
||||
unitChange(val) {
|
||||
if (val == null || val == '') {
|
||||
this.tableData = this.fullTableData
|
||||
} else {
|
||||
this.tableData = this.fullTableData.filter(v => v.id === val)
|
||||
}
|
||||
},
|
||||
searchTypeChange() {
|
||||
const searchType = this.pageForm.searchType
|
||||
if (searchType === '按分工会分析') {
|
||||
this.tableColumns = [
|
||||
{prop: 'unionName', label: '分工会名称'},
|
||||
{prop: 'unionCode', label: '分工会编码', sortable: true},
|
||||
{prop: 'unionSum', label: '总人数', sortable: true},
|
||||
{prop: 'studyNum', label: '学习人数', sortable: true},
|
||||
]
|
||||
} else {
|
||||
this.tableColumns = [
|
||||
{prop: 'unitName', label: '单位名称'},
|
||||
{prop: 'unitCode', label: '单位编码', sortable: true},
|
||||
{prop: 'unionSum', label: '总人数', sortable: true},
|
||||
{prop: 'studyNum', label: '学习人数', sortable: true},
|
||||
]
|
||||
}
|
||||
this.pageData()
|
||||
},
|
||||
async pageData() {
|
||||
sublime.showLoadingbar()
|
||||
this.tableLoading = true
|
||||
const resp = await $.post(loc() + '/pageData', this.pageForm)
|
||||
sublime.closeLoadingbar()
|
||||
this.tableLoading = false
|
||||
if (resp.code === 0) {
|
||||
this.tableData = resp.data.list
|
||||
this.fullTableData = resp.data.list
|
||||
}
|
||||
}
|
||||
},
|
||||
async created() {
|
||||
this.pageData()
|
||||
this.unions = await getUnions(null)
|
||||
this.units = await getUnits(null)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
@@ -1,122 +0,0 @@
|
||||
<!--#
|
||||
layout("/layouts/platform.html"){
|
||||
#-->
|
||||
|
||||
<div id="app" v-cloak>
|
||||
<guava ref="guava">
|
||||
|
||||
|
||||
<el-card shadow="never" class="mt10">
|
||||
<table-tool label="统计" :app="this"></table-tool>
|
||||
<el-table :data="tableData" :size="tableSize" style="width: 100%">
|
||||
<el-table-column type="index" label="序号" width="80px"></el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
header-align="center"
|
||||
v-for="column in tableColumns"
|
||||
show-overflow-tooltip
|
||||
:label="column.label"
|
||||
:prop="column.prop"
|
||||
:sortable="column.sortable"
|
||||
>
|
||||
<template v-if="column.prop==='sumDuration'" scope="{row}">
|
||||
{{(row.sumDuration / 60 / 60).toFixed(2) + 'h'}}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" header-align="center" label="操作" width="200">
|
||||
<template scope="{row}">
|
||||
<el-button size="small" type="primary" @click="openView(row)">查看具体学习情况</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-card>
|
||||
|
||||
<template #view>
|
||||
<el-table :data="viewTableData" stripe border style="width: 100%">
|
||||
<el-table-column type="index" label="序号" width="80px">
|
||||
<template scope="scope">
|
||||
<span>{{ scope.$index + (viewPageForm.pageNumber - 1) * viewPageForm.pageSize + 1 }} </span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
header-align="center"
|
||||
v-for="column in viewTableColumns"
|
||||
show-overflow-tooltip
|
||||
:label="column.label"
|
||||
:prop="column.prop"
|
||||
:sortable="column.sortable"
|
||||
>
|
||||
<template v-if="column.prop==='studyDuration'" scope="{row}">
|
||||
{{(row.studyDuration / 60 / 60).toFixed(2) + 'h'}}
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<el-row class="el-pagination-container" style="margin-bottom: 0px">
|
||||
<el-pagination
|
||||
@current-change="(val)=>{viewPageForm.pageNumber=val;viewPageData()}"
|
||||
:current-page="viewPageForm.pageNumber"
|
||||
:page-size="viewPageForm.pageSize"
|
||||
layout="total, sizes, prev, pager, next"
|
||||
:total="viewPageForm.totalCount">
|
||||
</el-pagination>
|
||||
</el-row>
|
||||
|
||||
</template>
|
||||
</guava>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var vue = new Vue({
|
||||
el: '#app',
|
||||
mixins: [initTableMixins],
|
||||
data() {
|
||||
return {
|
||||
tableColumns: [
|
||||
{prop: 'title', label: '专辑名称'},
|
||||
{prop: 'typeName', label: '类型'},
|
||||
{prop: 'studyNum', label: '已看人数', sortable: true},
|
||||
{prop: 'sumDuration', label: '课程总时长', sortable: true},
|
||||
],
|
||||
viewTableColumns: [
|
||||
{prop: 'username', label: '姓名'},
|
||||
{prop: 'loginname', label: '工号'},
|
||||
{prop: 'unitname', label: '单位'},
|
||||
{prop: 'unionname', label: '分工会'},
|
||||
{prop: 'studyDuration', label: '观看总时长'},
|
||||
],
|
||||
viewPageForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
totalCount: 0,
|
||||
albumId: null
|
||||
},
|
||||
viewTableData: []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async openView(row) {
|
||||
this.viewPageForm.albumId = row.id
|
||||
this.$refs['guava'].view()
|
||||
await this.viewPageData()
|
||||
},
|
||||
async viewPageData() {
|
||||
const resp = await $.post(loc() + '/getWatchDuration', this.viewPageForm)
|
||||
if (resp.code === 0) {
|
||||
this.viewTableData = resp.data.list
|
||||
this.viewPageForm.totalCount = resp.data.totalCount
|
||||
}
|
||||
},
|
||||
viewPageNumberChange(val) {
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.pageData()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
@@ -1,442 +0,0 @@
|
||||
<!--#
|
||||
layout("/layouts/platform.html"){
|
||||
#-->
|
||||
|
||||
<script src="https://cdn-go.cn/cdn/vod-js-sdk-v6/latest/vod-js-sdk-v6.js"></script>
|
||||
<link href="https://web.sdk.qcloud.com/player/tcplayer/release/v4.3.0/tcplayer.min.css" rel="stylesheet"/>
|
||||
<!--如果需要在 Chrome 和 Firefox 等现代浏览器中通过 H5 播放 HLS 格式的视频,需要在 tcplayer.vx.x.x.min.js 之前引入 hls.min.x.xx.xm.js。-->
|
||||
<script src="https://web.sdk.qcloud.com/player/tcplayer/release/v4.3.0/libs/hls.min.0.13.2m.js"></script>
|
||||
<!--播放器脚本文件-->
|
||||
<script src="https://web.sdk.qcloud.com/player/tcplayer/release/v4.3.0/tcplayer.v4.3.0.min.js"></script>
|
||||
|
||||
<style>
|
||||
|
||||
.el-tag {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.el-image {
|
||||
display: inherit;
|
||||
border-radius: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.hitv_horizontal-txtbox {
|
||||
height: 52px;
|
||||
padding-top: 4px;
|
||||
cursor: pointer;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.hitv_horizontal-title {
|
||||
line-height: 20px;
|
||||
height: auto;
|
||||
display: -webkit-box;
|
||||
overflow: hidden;
|
||||
-o-text-overflow: ellipsis;
|
||||
text-overflow: ellipsis;
|
||||
-webkit-line-clamp: 1;
|
||||
-webkit-box-orient: vertical;
|
||||
width: 200px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hitv_horizontal-desc {
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
zoom: 1;
|
||||
color: #999;
|
||||
width: 200px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
div img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
transition: all 0.6s;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
div img:hover {
|
||||
transform: scale(1.3);
|
||||
}
|
||||
|
||||
.title {
|
||||
color: #222;
|
||||
}
|
||||
|
||||
.select-video {
|
||||
color: #1867b0 !important;
|
||||
}
|
||||
|
||||
|
||||
.info:hover .title {
|
||||
color: #236eb4;
|
||||
}
|
||||
|
||||
.video {
|
||||
height: calc(100vh - 50px - 20px - 54px - 40px);
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.video_list {
|
||||
height: calc(100vh - 50px - 20px - 54px - 40px);
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.name {
|
||||
font-size: 13px;
|
||||
color: grey;
|
||||
}
|
||||
|
||||
.video_div {
|
||||
height: calc(100vh - 20px - 85px - 20px - 60px - 40px - 32px - 15px);
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<div id="app" v-cloak>
|
||||
|
||||
<guava ref="guava" v-model="guavaIndex">
|
||||
|
||||
<el-card shadow="never">
|
||||
<div class="btn-group tool-button mt5">
|
||||
<el-input @keyup.enter.native="doSearch" clearable placeholder="请输入内容"
|
||||
v-model="pageForm.searchKeyword"></el-input>
|
||||
</div>
|
||||
|
||||
<div class="btn-group tool-button mt5">
|
||||
<el-button type="primary" icon="el-icon-search" @click="doSearch">搜索</el-button>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<el-card shadow="never" class="mt20">
|
||||
<div>
|
||||
<el-tag :effect="pageForm.typeId === item.id ? 'dark':'light'" @click="typeClick(item)"
|
||||
v-for="item in typeList">{{item.typeName}}
|
||||
</el-tag>
|
||||
</div>
|
||||
<div class="demo-image__placeholder mt20 video_div"
|
||||
:infinite-scroll-disabled="scrollDisabled"
|
||||
v-infinite-scroll="load">
|
||||
<div @click="goPlayPage(item.id)" class="info mr25 mb10" style="display: inline-block"
|
||||
v-for="item in albumList">
|
||||
<el-image style="width: 200px; height: 130px"
|
||||
:src="APP_DOMAIN+FILE_STREAM_PREVIEW_ADDRESS+'?id='+item.cover"
|
||||
lazy>
|
||||
</el-image>
|
||||
<div class="hitv_horizontal-txtbox">
|
||||
<p class="hitv_horizontal-title">
|
||||
<a class="title">{{item.title}}</a>
|
||||
</p>
|
||||
<p class="hitv_horizontal-desc" v-html="item.description">
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<template #view>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="18">
|
||||
<div id="el-col-video">
|
||||
<video :id="'player-container-id'+albumId" class="video" height="600" playsinline preload="auto"
|
||||
webkit-playsinline>
|
||||
</video>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
title
|
||||
description
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="6" class="video_list">
|
||||
<div @click="playVideo(item)" style="margin-bottom: 20px; display: flex;"
|
||||
v-for="item in videoList">
|
||||
<div>
|
||||
<el-image style="width: 160px; height: 100px; margin-right: 10px"
|
||||
:src="item.coverUrl"
|
||||
lazy>
|
||||
</el-image>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<a :class="currentPlayVideo.id === item.id ? 'select-video':''"
|
||||
class="title">{{item.title}}</a>
|
||||
<div class="upname">
|
||||
<div>
|
||||
<svg height="16" style="position: relative; top: 3px" viewBox="0 0 18 16" width="18"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<path clip-rule="evenodd"
|
||||
d="M9 2.0625C6.85812 2.0625 4.98983 2.1725 3.67735 2.2798C2.77861 2.35327 2.08174 3.04067 2.00119 3.93221C1.90388 5.00924 1.8125 6.43727 1.8125 8C1.8125 9.56273 1.90388 10.9908 2.00119 12.0678C2.08174 12.9593 2.77861 13.6467 3.67735 13.7202C4.98983 13.8275 6.85812 13.9375 9 13.9375C11.1421 13.9375 13.0105 13.8275 14.323 13.7202C15.2216 13.6467 15.9184 12.9595 15.9989 12.0682C16.0962 10.9916 16.1875 9.56386 16.1875 8C16.1875 6.43614 16.0962 5.00837 15.9989 3.9318C15.9184 3.04049 15.2216 2.3533 14.323 2.27983C13.0105 2.17252 11.1421 2.0625 9 2.0625ZM3.5755 1.03395C4.9136 0.924562 6.81674 0.8125 9 0.8125C11.1835 0.8125 13.0868 0.924583 14.4249 1.03398C15.9228 1.15645 17.108 2.31588 17.2438 3.81931C17.3435 4.92296 17.4375 6.38948 17.4375 8C17.4375 9.61052 17.3435 11.077 17.2438 12.1807C17.108 13.6841 15.9228 14.8436 14.4249 14.966C13.0868 15.0754 11.1835 15.1875 9 15.1875C6.81674 15.1875 4.9136 15.0754 3.5755 14.966C2.07738 14.8436 0.892104 13.6838 0.756256 12.1803C0.656505 11.0762 0.5625 9.60942 0.5625 8C0.5625 6.39058 0.656505 4.92379 0.756257 3.81973C0.892104 2.31616 2.07738 1.15643 3.5755 1.03395ZM4.41663 4.93726C4.72729 4.93726 4.97913 5.1891 4.97913 5.49976V8.62476C4.97913 9.34963 5.56675 9.93726 6.29163 9.93726C7.0165 9.93726 7.60413 9.34963 7.60413 8.62476V5.49976C7.60413 5.1891 7.85597 4.93726 8.16663 4.93726C8.47729 4.93726 8.72913 5.1891 8.72913 5.49976V8.62476C8.72913 9.97095 7.63782 11.0623 6.29163 11.0623C4.94543 11.0623 3.85413 9.97095 3.85413 8.62476V5.49976C3.85413 5.1891 4.10597 4.93726 4.41663 4.93726ZM10.2501 4.93726C9.9394 4.93726 9.68756 5.1891 9.68756 5.49976V10.4998C9.68756 10.8104 9.9394 11.0623 10.2501 11.0623C10.5607 11.0623 10.8126 10.8104 10.8126 10.4998V9.60392H12.2292C13.5179 9.60392 14.5626 8.55925 14.5626 7.27059C14.5626 5.98193 13.5179 4.93726 12.2292 4.93726H10.2501ZM12.2292 8.47892H10.8126V6.06226H12.2292C12.8966 6.06226 13.4376 6.60325 13.4376 7.27059C13.4376 7.93793 12.8966 8.47892 12.2292 8.47892Z"
|
||||
fill-rule="evenodd"></path>
|
||||
</svg>
|
||||
<span :class="currentPlayVideo.id === item.id ? 'select-video':''" class="name">{{item.title}}</span>
|
||||
</div>
|
||||
<div>
|
||||
<svg class="icon" height="16" p-id="2411" style="position: relative; top: 3px"
|
||||
t="1660188268757" version="1.1" viewBox="0 0 1024 1024"
|
||||
width="18" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M511.913993 63.989249c-247.012263 0-447.924744 200.912481-447.924744 447.924744s200.912481 447.924744 447.924744 447.924744 447.924744-200.912481 447.924744-447.924744S758.926256 63.989249 511.913993 63.989249zM511.913993 895.677474c-211.577356 0-383.763481-172.186125-383.763481-383.763481 0-211.577356 172.014111-383.763481 383.763481-383.763481s383.763481 172.014111 383.763481 383.763481S723.491349 895.677474 511.913993 895.677474z"
|
||||
p-id="2412"></path>
|
||||
<path d="M672.05913 511.913993l-159.973123 0L512.086007 288.123635c0-17.717453-14.277171-32.166639-31.994625-32.166639-17.717453 0-31.994625 14.449185-31.994625 32.166639l0 255.956996c0 17.717453 14.277171 31.994625 31.994625 31.994625l191.967747 0c17.717453 0 32.166639-14.277171 32.166639-31.994625C704.053754 526.191164 689.604569 511.913993 672.05913 511.913993z"
|
||||
p-id="2413"></path>
|
||||
</svg>
|
||||
<span :class="currentPlayVideo.id === item.id ? 'select-video':''" class="name">{{formatSeconds(item.fileDuration)}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
</guava>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<script>
|
||||
let player = null
|
||||
|
||||
var vue = new Vue({
|
||||
el: '#app',
|
||||
mixins: [initTableMixins],
|
||||
data() {
|
||||
return {
|
||||
typeList: [],
|
||||
albumList: [],
|
||||
videoList: [],
|
||||
pageForm: {
|
||||
typeId: null,
|
||||
pageSize: 30
|
||||
},
|
||||
currentPlayVideo: {},
|
||||
watchRecordList: [],
|
||||
guavaIndex: null,
|
||||
albumId: null,
|
||||
scrollDisabled: false,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
scrollDisabled() {
|
||||
return this.pageForm.totalCount === this.albumList.length
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
async guavaIndex(val) {
|
||||
if (val === 'index' && player) {
|
||||
console.log('xxx')
|
||||
player.dispose()
|
||||
player = null
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
doSearch() {
|
||||
this.albumList = []
|
||||
this.pageForm.pageNumber = 1
|
||||
this.load()
|
||||
},
|
||||
async typeClick(item) {
|
||||
if (this.pageForm.typeId === item.id) return
|
||||
this.pageForm.typeId = item.id
|
||||
this.pageForm.pageNumber = 1
|
||||
this.albumList = []
|
||||
await this.getAlbum()
|
||||
},
|
||||
//获取专辑
|
||||
async load() {
|
||||
this.scrollDisabled = true
|
||||
await this.getAlbum()
|
||||
},
|
||||
async getAlbum() {
|
||||
const resp = await $.get('/platform/trainEdu/album/getAlbumByTypeId', this.pageForm)
|
||||
if (resp.code === 0) {
|
||||
if (resp.data.list.length > 0) {
|
||||
if (this.scrollDisabled === false) {
|
||||
this.albumList = this.albumList.concat(resp.data.list)
|
||||
} else {
|
||||
this.albumList = resp.data.list
|
||||
}
|
||||
this.pageForm.totalCount = resp.data.totalCount
|
||||
this.pageForm.pageNumber = this.pageForm.pageNumber + 1
|
||||
} else {
|
||||
this.noMore = true
|
||||
}
|
||||
}
|
||||
},
|
||||
async goPlayPage(albumId) {
|
||||
this.$refs.guava.view()
|
||||
this.albumId = albumId
|
||||
this.$nextTick(() => {
|
||||
if (!player) {
|
||||
const videoTag = document.getElementById('player-container-id' + albumId)
|
||||
if (!videoTag) {
|
||||
const videoStr = "<video class='video' id='player-container-id" + albumId + "'" + "height='600' preload='auto' playsinline webkit-playsinline></video>"
|
||||
document.getElementById('el-col-video').insertAdjacentHTML('beforeend', videoStr)
|
||||
}
|
||||
player = TCPlayer('player-container-id' + albumId, {})
|
||||
}
|
||||
})
|
||||
const resp = await $.get('/platform/trainEdu/video/getVideoList', {albumId})
|
||||
if (resp.code === 0) {
|
||||
this.videoList = resp.data
|
||||
const currentVideo = this.videoList[0]
|
||||
|
||||
this.currentPlayVideo = currentVideo
|
||||
if (currentVideo) {
|
||||
player.src(currentVideo.mediaUrl)
|
||||
const v = this.watchRecordList.find(v => v.videoId === currentVideo.id)
|
||||
if (v) {
|
||||
player.currentTime(v.watchDuration)
|
||||
}
|
||||
this.playTimeUpdate()
|
||||
}
|
||||
} else {
|
||||
this.notifyWarning(resp.msg)
|
||||
}
|
||||
},
|
||||
async playVideo(item) {
|
||||
|
||||
this.currentPlayVideo = item
|
||||
player.src(item.mediaUrl)
|
||||
await this.getMyWatchRecord()
|
||||
|
||||
//接着上次继续看
|
||||
const v = this.watchRecordList.find(v => v.videoId === item.id)
|
||||
if (v) {
|
||||
this.lastTime = v.watchDuration
|
||||
setTimeout(() => {
|
||||
player.currentTime(v.watchDuration)
|
||||
})
|
||||
} else {
|
||||
player.currentTime(0)
|
||||
await this.addWatchRecord()
|
||||
await this.getMyWatchRecord()
|
||||
}
|
||||
|
||||
// player.play()
|
||||
this.playPause()
|
||||
this.playEnd()
|
||||
this.playTimeUpdate()
|
||||
this.playSeeked()
|
||||
},
|
||||
|
||||
playPlay() {
|
||||
player.on('play', () => {
|
||||
this.lastTime = player.currentTime()
|
||||
this.addWatchRecord()
|
||||
})
|
||||
},
|
||||
|
||||
//快进 快退
|
||||
playSeeked() {
|
||||
player.on('seeked', () => {
|
||||
this.lastTime = player.currentTime()
|
||||
this.addWatchRecord()
|
||||
})
|
||||
},
|
||||
playTimeUpdate() {
|
||||
this.lastTime = player.currentTime()
|
||||
player.on('timeupdate', () => {
|
||||
const nowTime = player.currentTime()
|
||||
if (nowTime - this.lastTime > 5) {
|
||||
this.lastTime = nowTime
|
||||
this.addWatchRecord()
|
||||
}
|
||||
})
|
||||
},
|
||||
playPause() {
|
||||
player.on('pause', () => {
|
||||
this.addWatchRecord()
|
||||
})
|
||||
},
|
||||
|
||||
playEnd() {
|
||||
player.on('ended', () => {
|
||||
this.addWatchRecord()
|
||||
this.getMyWatchRecord()
|
||||
const currentIndex = this.videoList.findIndex(v => v.id === this.currentVideo.id)
|
||||
const nextVideo = this.videoList[currentIndex + 1]
|
||||
if (nextVideo) {
|
||||
this.playVideo(nextVideo)
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
async getVideoType() {
|
||||
const resp = await $.get('/platform/trainEdu/type/pageData', {pageForm: 1, pageSize: 10000})
|
||||
if (resp.code === 0) {
|
||||
this.typeList = resp.data.list
|
||||
}
|
||||
},
|
||||
formatSeconds(value) {
|
||||
let secondTime = parseInt(value);// 秒
|
||||
let minuteTime = 0;// 分
|
||||
let hourTime = 0;// 小时
|
||||
if (secondTime > 60) {//如果秒数大于60,将秒数转换成整数
|
||||
//获取分钟,除以60取整数,得到整数分钟
|
||||
minuteTime = parseInt(secondTime / 60);
|
||||
//获取秒数,秒数取佘,得到整数秒数
|
||||
secondTime = parseInt(secondTime % 60);
|
||||
//如果分钟大于60,将分钟转换成小时
|
||||
if (minuteTime > 60) {
|
||||
//获取小时,获取分钟除以60,得到整数小时
|
||||
hourTime = parseInt(minuteTime / 60);
|
||||
//获取小时后取佘的分,获取分钟除以60取佘的分
|
||||
minuteTime = parseInt(minuteTime % 60);
|
||||
}
|
||||
}
|
||||
let result = "" + parseInt(secondTime) + "秒";
|
||||
|
||||
if (minuteTime > 0) {
|
||||
result = "" + parseInt(minuteTime) + "分" + result;
|
||||
}
|
||||
if (hourTime > 0) {
|
||||
result = "" + parseInt(hourTime) + "小时" + result;
|
||||
}
|
||||
return result;
|
||||
},
|
||||
|
||||
//监听页面关闭 隐藏
|
||||
watchPage() {
|
||||
document.addEventListener('visibilitychange', () => {
|
||||
if (document.visibilityState === 'hidden') {
|
||||
if (player && this.currentPlayVideo) {
|
||||
this.addWatchRecord()
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
async addWatchRecord() {
|
||||
const params = {
|
||||
videoId: this.currentPlayVideo.id,
|
||||
currentTime: parseInt(player.currentTime()),
|
||||
albumId: this.currentPlayVideo.albumId
|
||||
}
|
||||
await $.post('/mobile/trainEducation/addWatchRecord', params)
|
||||
},
|
||||
async getMyWatchRecord() {
|
||||
const {data} = await $.get('/mobile/trainEducation/getMyWatchRecord')
|
||||
this.watchRecordList = data
|
||||
},
|
||||
|
||||
|
||||
},
|
||||
async created() {
|
||||
await this.getVideoType()
|
||||
await this.getMyWatchRecord()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
@@ -1,188 +0,0 @@
|
||||
<!--#
|
||||
layout("/layouts/platform.html"){
|
||||
#-->
|
||||
|
||||
<style>
|
||||
.avatar-uploader .el-upload {
|
||||
border: 1px dashed #d9d9d9;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.avatar-uploader .el-upload:hover {
|
||||
border-color: #409EFF;
|
||||
}
|
||||
|
||||
.avatar-uploader-icon {
|
||||
font-size: 28px;
|
||||
color: #8c939d;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.avatar {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="app" v-cloak>
|
||||
<guava ref="guava">
|
||||
<el-card shadow="never" class="text-right">
|
||||
<div class="btn-group tool-button mt5">
|
||||
<el-button type="primary" @click="openAdd">
|
||||
<i class="ti-plus"></i>
|
||||
新增类型
|
||||
</el-button>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<el-card shadow="never" class="mt10">
|
||||
<table-tool label="专辑类型" :app="this"></table-tool>
|
||||
<el-table :data="tableData" :size="tableSize" style="width: 100%">
|
||||
<el-table-column type="index" label="序号" width="80px"></el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
header-align="center"
|
||||
v-for="column in tableColumns"
|
||||
show-overflow-tooltip
|
||||
:label="column.label"
|
||||
:prop="column.prop"
|
||||
:sortable="column.sortable"
|
||||
>
|
||||
<template v-if="column.prop==='files'" scope="{row}">
|
||||
<el-image
|
||||
v-if="row.files"
|
||||
style="height: 30px;width: 30px"
|
||||
:src="FILE_DOMAIN+'/fileStreamPreview?id='+JSON.parse(row.files)[0].id"
|
||||
fit="cover">
|
||||
<div slot="error" class="image-slot">
|
||||
<i class="el-icon-picture-outline"></i>
|
||||
</div>
|
||||
</el-image>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" header-align="center" label="操作" width="250">
|
||||
<template scope="{row}">
|
||||
<el-button size="small" type="primary" @click="openEdit(row)">编辑</el-button>
|
||||
<el-button size="small" type="danger" @click="doDelete(row.id)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!--#include("/layouts/pagination.html"){}#-->
|
||||
</el-card>
|
||||
</guava>
|
||||
|
||||
<el-dialog :title="formData.id ? '编辑类型':'新增类型'" :visible.sync="dialogVisible" width="30%"
|
||||
:close-on-click-modal="false">
|
||||
<el-form :model="formData" :rules="rules" ref="ruleForm" label-width="80px">
|
||||
<el-form-item label="名称" prop="typeName">
|
||||
<el-input v-model="formData.typeName"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="图标" prop="files">
|
||||
<file-upload :files.sync="formData.files" :type="['jpg', 'jpeg', 'png', 'JPG', 'JPEG', 'PNG']" :max="1">
|
||||
<template #el-upload__tip>
|
||||
<div class="el-upload__tip" slot="tip">
|
||||
请上传1个类型为jpg/png/jpeg等格式的图片
|
||||
</div>
|
||||
</template>
|
||||
</file-upload>
|
||||
|
||||
<!--<el-upload
|
||||
class="avatar-uploader"
|
||||
:action="FILE_UPLOAD_ADDRESS"
|
||||
:show-file-list="false"
|
||||
:on-success="handleAvatarSuccess"
|
||||
:before-upload="beforeAvatarUpload">
|
||||
<img v-if="formData.icon" :src="FILE_DOMAIN+'/fileStreamPreview?id='+formData.icon" class="avatar">
|
||||
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
|
||||
</el-upload>-->
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-row>
|
||||
<el-button @click="dialogVisible=false">取消</el-button>
|
||||
<el-button type="primary" @click="doHandle">确定</el-button>
|
||||
</el-row>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<script>
|
||||
var vue = new Vue({
|
||||
el: '#app',
|
||||
mixins: [initTableMixins],
|
||||
data() {
|
||||
return {
|
||||
dialogVisible: false,
|
||||
formData: {
|
||||
typeName: null,
|
||||
files: []
|
||||
},
|
||||
tableColumns: [
|
||||
{prop: 'typeName', label: '类型名称'},
|
||||
{prop: 'files', label: '图标'},
|
||||
],
|
||||
rules: {
|
||||
typeName: [{required: true, message: '请输入类型名称', trigger: ['change', 'blur']}],
|
||||
files: [{required: true, message: '请上传图标文件', trigger: ['change', 'blur']}],
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
openAdd() {
|
||||
this.dialogVisible = true
|
||||
this.$refs.ruleForm.resetFields()
|
||||
},
|
||||
async doHandle() {
|
||||
const valid = await this.$refs['ruleForm'].validate()
|
||||
if (valid) {
|
||||
const methodName = typeof this.formData.id === 'undefined' ? '/doAdd' : '/doEdit'
|
||||
|
||||
const resp = await $.post(loc() + methodName, {trainEduType: JSON.stringify(this.formData)})
|
||||
if (resp.code === 0) {
|
||||
this.dialogVisible = false
|
||||
this.notifySuccess(resp.msg)
|
||||
this.doSearch()
|
||||
} else {
|
||||
this.notifyError(resp.msg)
|
||||
}
|
||||
}
|
||||
},
|
||||
openEdit(row) {
|
||||
this.dialogVisible = true
|
||||
this.$nextTick(() => {
|
||||
this.formData = {...row, files: JSON.parse(row.files)}
|
||||
})
|
||||
},
|
||||
async doDelete(id) {
|
||||
const confirm = await this.$confirm('确定删除吗?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
})
|
||||
if (confirm === 'confirm') {
|
||||
const resp = await $.post(loc() + '/doDelete', {id})
|
||||
if (resp.code === 0) {
|
||||
this.$notify.success(resp.msg)
|
||||
this.doSearch()
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.pageData()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
@@ -1,360 +0,0 @@
|
||||
<!--#
|
||||
layout("/layouts/platform.html"){
|
||||
#-->
|
||||
|
||||
<script src="https://cdn-go.cn/cdn/vod-js-sdk-v6/latest/vod-js-sdk-v6.js"></script>
|
||||
<link href="https://web.sdk.qcloud.com/player/tcplayer/release/v4.3.0/tcplayer.min.css" rel="stylesheet"/>
|
||||
<!--如果需要在 Chrome 和 Firefox 等现代浏览器中通过 H5 播放 HLS 格式的视频,需要在 tcplayer.vx.x.x.min.js 之前引入 hls.min.x.xx.xm.js。-->
|
||||
<script src="https://web.sdk.qcloud.com/player/tcplayer/release/v4.3.0/libs/hls.min.0.13.2m.js"></script>
|
||||
<!--播放器脚本文件-->
|
||||
<script src="https://web.sdk.qcloud.com/player/tcplayer/release/v4.3.0/tcplayer.v4.3.0.min.js"></script>
|
||||
|
||||
|
||||
<style>
|
||||
|
||||
.video-js {
|
||||
width: 100% !important;
|
||||
min-height: 500px !important;
|
||||
}
|
||||
|
||||
.upload-form-item .el-form-item__content {
|
||||
line-height: unset !important;
|
||||
}
|
||||
|
||||
.video-title {
|
||||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
color: #212121;
|
||||
line-height: 26px;
|
||||
height: 26px;
|
||||
margin-top: 0;
|
||||
margin-bottom: 8px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="app" v-cloak>
|
||||
<guava ref="guava" :v.sync="pageStatus">
|
||||
<el-card shadow="never">
|
||||
<div class="btn-group tool-button mt5">
|
||||
<el-select v-model="pageForm.albumId" placeholder="请选择专辑" filterable clearable @change="doSearch">
|
||||
<el-option
|
||||
v-for="item in albumList"
|
||||
:key="item.id"
|
||||
:label="item.title"
|
||||
:value="item.id">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
|
||||
<div class="btn-group tool-button mt5">
|
||||
<el-input placeholder="请输入内容" v-model="pageForm.searchKeyword" clearable @keyup.enter.native="doSearch">
|
||||
<el-select v-model="pageForm.searchName" slot="prepend" placeholder="查询类型" style="width: 120px;">
|
||||
<el-option label="标题" value="tev.title"></el-option>
|
||||
</el-select>
|
||||
</el-input>
|
||||
</div>
|
||||
|
||||
<div class="btn-group tool-button mt5">
|
||||
<el-button type="primary" icon="el-icon-search" @click="doSearch">搜索</el-button>
|
||||
</div>
|
||||
|
||||
<div class="pull-right offscreen-right mt5">
|
||||
<el-button type="primary" @click="openAdd">
|
||||
<i class="ti-plus"></i>
|
||||
上传视频
|
||||
</el-button>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<el-card shadow="never" class="mt10">
|
||||
<table-tool label="视频列表" :app="this"></table-tool>
|
||||
<el-table :data="tableData" :size="tableSize" @sort-change="pageOrder" style="width: 100%">
|
||||
<el-table-column type="index" label="序号" width="80px"></el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
header-align="center"
|
||||
v-for="column in tableColumns"
|
||||
show-overflow-tooltip
|
||||
:label="column.label"
|
||||
:prop="column.prop"
|
||||
:sortable="column.sortable"
|
||||
>
|
||||
|
||||
<template v-if="column.prop==='disabled'" scope="{row}">
|
||||
<span v-if="row.disabled"><i class="el-icon-error text-error"></i> 禁用</span>
|
||||
<span v-else><i class="el-icon-success text-success"></i> 启用</span>
|
||||
</template>
|
||||
|
||||
</el-table-column>
|
||||
<el-table-column align="center" header-align="center" label="操作" width="250">
|
||||
<template scope="{row}">
|
||||
<el-button size="small" @click="openView(row)">查看</el-button>
|
||||
<el-button size="small" type="primary" @click="openEdit(row)">编辑</el-button>
|
||||
<el-button size="small" type="danger" @click="doDelete(row.id)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!--#include("/layouts/pagination.html"){}#-->
|
||||
</el-card>
|
||||
|
||||
<template #edit>
|
||||
<el-form :model="formData" :rules="rules" ref="ruleForm" label-width="100px">
|
||||
|
||||
<el-form-item label="所属专辑" prop="albumId">
|
||||
<el-select v-model="formData.albumId" placeholder="请选择专辑" style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in albumList"
|
||||
:key="item.id"
|
||||
:label="item.title"
|
||||
:value="item.id">
|
||||
</el-option>
|
||||
</el-select>
|
||||
<div class="text-primary">{{videoTypeTips}}</div>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="视频标题" prop="title">
|
||||
<el-input v-model="formData.title"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="上传文件" prop="url" class="upload-form-item">
|
||||
<wp-upload ref="uploadForm"
|
||||
:upload-auto="false"
|
||||
:size="1024*100"
|
||||
@on-select="selectFile"
|
||||
:allow-files="['mp4']"
|
||||
:max-file-number="1"
|
||||
show-model="list"
|
||||
:file-list="fileList"
|
||||
type="single"></wp-upload>
|
||||
<div class="el-upload__tip">请上传格式为mp4的视频文件,且不超过200M</div>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="排序编号" prop="sortNo">
|
||||
<el-input-number :min="1" :max="128" v-model="formData.sortNo"></el-input-number>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="是否启用" prop="disabled">
|
||||
<el-switch
|
||||
v-model="formData.disabled"
|
||||
:active-value="false"
|
||||
:inactive-value="true"
|
||||
active-color="#13ce66"
|
||||
inactive-color="#ff4949">
|
||||
</el-switch>
|
||||
</el-form-item>
|
||||
|
||||
</el-form>
|
||||
<el-row class="mt20 text-right">
|
||||
<el-button @click="$refs.guava.index()">取消</el-button>
|
||||
<el-button type="primary" @click="doHandle">确定</el-button>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<template #view>
|
||||
<!-- <el-row type="flex" :gutter="20">-->
|
||||
<!-- <el-col :span="18">-->
|
||||
<!-- <h1 class="video-title">-->
|
||||
<!-- <span>{{viewData.albumTitle + '-' + viewData.title}}</span>-->
|
||||
<!-- </h1>-->
|
||||
<!-- <video id="player-container-id" width="700" height="600" preload="auto" playsinline-->
|
||||
<!-- webkit-playsinline>-->
|
||||
<!-- </video>-->
|
||||
<!-- </el-col>-->
|
||||
<!-- <el-col :span="6">-->
|
||||
<!-- <div class="grid-content bg-purple"></div>-->
|
||||
<!-- </el-col>-->
|
||||
<!-- </el-row>-->
|
||||
|
||||
</template>
|
||||
</guava>
|
||||
|
||||
<el-dialog title="视频" :visible.sync="playDialogVisible" width="60%" close-on-click-modal="false">
|
||||
<h1 class="video-title">
|
||||
<span>{{viewData.albumTitle + '-' + viewData.title}}</span>
|
||||
</h1>
|
||||
<video id="player-container-id" height="600" preload="auto" playsinline
|
||||
webkit-playsinline>
|
||||
</video>
|
||||
</el-dialog>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<script>
|
||||
|
||||
<!--#include("/platform/trainEdu/include/include.js"){}#-->
|
||||
|
||||
let player = null
|
||||
|
||||
var vue = new Vue({
|
||||
el: '#app',
|
||||
mixins: [initTableMixins],
|
||||
computed: {
|
||||
videoTypeTips() {
|
||||
const albumId = this.formData.albumId
|
||||
const o = this.albumList.find(v => v.id === albumId)
|
||||
if (o) {
|
||||
//return '请上传' + o.eduType.typeName + '的视频'
|
||||
}
|
||||
return null
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
pageStatus: null,
|
||||
pageForm: {
|
||||
albumId: null,
|
||||
searchName: 'tev.title'
|
||||
},
|
||||
formData: {
|
||||
albumId: null,
|
||||
cover: null,
|
||||
title: null,
|
||||
sortNo: null,
|
||||
disabled: false,
|
||||
url: null
|
||||
},
|
||||
tableColumns: [
|
||||
{prop: 'title', label: '标题'},
|
||||
{prop: 'albumTitle', label: '所属专辑'},
|
||||
{prop: 'createUserName', label: '上传人'},
|
||||
{prop: 'createTime', label: '上传时间', sortable: true},
|
||||
{prop: 'disabled', label: '视频状态', sortable: true},
|
||||
|
||||
],
|
||||
rules: {
|
||||
albumId: [{required: true, message: '请选择所属专辑', trigger: ['change', 'blur']}],
|
||||
title: [{required: true, message: '请选择视频标题', trigger: ['change', 'blur']}],
|
||||
url: [{required: true, message: '请上传视频文件', trigger: ['change', 'blur']}],
|
||||
sortNo: [{required: true, message: '请输入排序编号', trigger: ['change', 'blur']}]
|
||||
},
|
||||
albumList: [],
|
||||
fileList: [],
|
||||
viewData: {},
|
||||
playDialogVisible: false
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
pageStatus(val) {
|
||||
if (val !== 'view') {
|
||||
if (player) {
|
||||
player.pause()
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
openAdd() {
|
||||
this.$refs['guava'].edit()
|
||||
if (this.$refs.uploadForm) {
|
||||
this.$refs.uploadForm.clean()
|
||||
}
|
||||
this.$refs['ruleForm'].resetFields()
|
||||
this.formData.id = undefined
|
||||
this.formData.albumId = this.pageForm.albumId
|
||||
|
||||
},
|
||||
selectFile(preUploadFiles) {
|
||||
if (preUploadFiles && preUploadFiles.length > 0) {
|
||||
this.formData.url = '#'
|
||||
this.$refs['ruleForm'].validate()
|
||||
}
|
||||
},
|
||||
async doHandle() {
|
||||
const fileList = this.$refs.uploadForm.fileShowArray
|
||||
if (fileList && fileList.length > 0) {
|
||||
this.formData.url = '#'
|
||||
} else {
|
||||
this.formData.url = null
|
||||
}
|
||||
const valid = await this.$refs['ruleForm'].validate()
|
||||
if (valid) {
|
||||
|
||||
const loading = this.$loading({
|
||||
lock: true,
|
||||
text: '上传中,文件过大请耐心等待',
|
||||
spinner: 'el-icon-loading',
|
||||
background: 'rgba(0, 0, 0, 0.7)'
|
||||
});
|
||||
|
||||
const methodName = typeof this.formData.id === 'undefined' ? '/doAdd' : '/doEdit'
|
||||
|
||||
const formData = new FormData()
|
||||
formData.append("data", JSON.stringify(this.formData))
|
||||
formData.append("file", this.$refs.uploadForm.fileShowArray[0].file)
|
||||
|
||||
const resp = await $.ajax({
|
||||
type: 'POST',
|
||||
url: loc() + methodName,
|
||||
data: formData,
|
||||
cache: false,
|
||||
processData: false,
|
||||
contentType: false
|
||||
})
|
||||
loading.close()
|
||||
if (resp.code === 0) {
|
||||
this.notifySuccess(resp.msg)
|
||||
this.doSearch()
|
||||
this.$refs['guava'].index()
|
||||
} else {
|
||||
this.notifyError(resp.msg)
|
||||
}
|
||||
}
|
||||
},
|
||||
openView(row) {
|
||||
this.viewData = row
|
||||
this.playDialogVisible = true
|
||||
this.$nextTick(() => {
|
||||
if (!player) {
|
||||
player = TCPlayer('player-container-id', {})
|
||||
}
|
||||
player.src(row.mediaUrl)
|
||||
})
|
||||
|
||||
// player.play()
|
||||
},
|
||||
openEdit(row) {
|
||||
this.$refs['guava'].edit()
|
||||
this.formData = JSON.parse(JSON.stringify(row))
|
||||
this.fileList = [{
|
||||
url: row.mediaUrl
|
||||
}]
|
||||
if (this.$refs.uploadForm) {
|
||||
setTimeout(() => {
|
||||
this.$refs.uploadForm.initWp()
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
},
|
||||
async doDelete(id) {
|
||||
const confirm = await this.$confirm('确定删除吗?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
})
|
||||
if (confirm === 'confirm') {
|
||||
const resp = await $.post(loc() + '/doDelete', {id})
|
||||
if (resp.code === 0) {
|
||||
this.$notify.success(resp.msg)
|
||||
this.doSearch()
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
async created() {
|
||||
this.albumList = await getAllAlbum()
|
||||
if (this.albumList) {
|
||||
this.pageForm.albumId = this.albumList[0].id
|
||||
this.pageData()
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
Reference in New Issue
Block a user