<template>
<div class="app-container">
<div>
<div class="font-family-h font-bold c-fc-333 margin-b title"><i class="square"></i>{{curName}}内容</div>
</div>
<div v-show="isDefault" class="relative c-width100 height120 border-radio4 c-ph20 c-pv10 border c-bg-fa">
<div class="vhcenter pointer" style="height:100%;line-height:118px;">
<!-- <div class="vhcenter pointer"> -->
<synchronize-video ref="uploader" class="drag-upload" v-if="curName == '视频'"
btnType="text"
btnCss="c-fc-60 "
btnText="上传视频"
:maxSize="2"
:isDrag="true"
:multiple="true"
:reupload="true"
:limit="10"
@beforeUpload="beforeUploadVideo"
@onProgress="getProgress"
@getData="submitVideoSuccess"
@submitVideoError="submitVideoError">
</synchronize-video>
<el-upload drag v-else
class="fl drag-upload"
ref="avatarUpload"
name="file"
:action="url"
limit="10"
:on-exceed="onexceed"
list-type="picture"
:onChange="change"
:data="uploadData"
:before-upload="beforeUpload"
multiple="true"
:on-success="handleSuccess"
:show-file-list="false"
:auto-upload="true"
:on-progress="progress"
style="width: 100%;height:100%;" >
<!-- <el-button slot="trigger" size="mini" type="primary">选取文件</el-button> -->
<div slot="trigger" >
<img src="@/assets/icon/upload.png" class="width40 height40"><span>上传{{curName}}</span>
</div>
</el-upload>
</div>
</div>
<div class="Mplupload-box">
<div v-for="(item,index) in data" :key="index" class="relative c-width100 height120 border-radio4 c-ph20 c-pv10 border c-bg-fa margin-b10">
<section class="clearfix">
<span class="fl c-text-ellipsis1 c-line-30 margin-r10" style="max-width:60%;">{{item.name}}</span>
<span class="fl c-line-30 c-fc-sgray">{{item.msize|byteTransform}}</span>
<span class="fr c-line-30 c-fc-fred" v-if="item.uploadStatus">上传失败</span>
<span class="fr c-line-30 c-fc-blue" v-else>{{item.percent|Datastatus}}{{item.analysis|anastatus}}</span>
</section>
<section>
<p class="upload-progress">
<span class="upload-bar c-bg-blue" :style="'right:'+(100 - item.percent)+'%'"></span>
<!-- <span class="upload-bar c-bg-blue" :style="'width:'+item.percent+'%'"></span> -->
</p>
</section>
<section class="c-line-30 clearfix">
<span class="fl">已上传:{{item.curSize|byteTransform}}/{{item.msize|byteTransform}}</span>
<!-- {{item.speed}} -->
<span class="fr c-fs-12 c-fc-666" v-if="item.uploadErrorTip">失败原因:{{item.uploadErrorTip}}</span>
</section>
</div>
</div>
<div class="c-fs-14 c-line-30 c-fc-sgray">
{{ruleContent}}
</div>
<div class="center" v-if="isComplete||allComplete">
<el-button class="btn-item margin-t30 margin-b30" style="" type="primary" v-loading.fullscreen="btnLoading"
@click="back">保存
</el-button>
</div>
<b></b>
</div>
</template>
<script>
import { imageSign, audioCallBack, saveVideo } from '@/api/materials'
import { convertTxVodFile } from '@/api/courseDetail'
import { getUploadToken } from '@/api/common'
import synchronizeVideo from '@/views/templatePage/uploadVideo/synchronizeVideo.vue'
import { randomString } from '@/utils/index'
import { byteTransform } from '@/utils/index'
export default {
name: 'upload',
components: {
synchronizeVideo
},
data() {
return {
nameList: {
'Image': '图片',
'Audio': '音频',
'Video': '视频'
},
curName: '',
// imgSignData: {},
url: '',
isShowMaterial: false, // 选择素材弹窗
isDefault: true, // 进入页面默认显示的模块
isComplete: false, // 上传完成弹窗
data: [],
ruleContent: '', // 规则内容
audioData: {
token: null
},
uploadData: {
},
// 图片直传的参数
uploadParams: {
name: '',
policy: '',
OSSAccessKeyId: '',
success_action_status: '200',
callback: '',
signature: ''
},
fId: -1,
FideDir: '', // 图片服务器路径
uploadCount: 0, // 设置上传的索引
uploadIndex: {}, // 上传的索引
countFinsh: 0 // 上传完成的个数
}
},
watch: {
$route: function(to, from) {
this.curName = ''
// imgSignData: {},
this.url = ''
this.data = []
this.isDefault = true // 进入页面默认显示的模块
this.isComplete = false
this.ruleContent = '' // 规则内容
this.audioData = {
token: null
}
this.uploadData = {
}
// 图片直传的参数
this.uploadParams = {
name: '',
policy: '',
OSSAccessKeyId: '',
success_action_status: '200',
callback: '',
signature: ''
}
this.FideDir = '' // 图片服务器路径
this.uploadCount = 0 // 设置上传的索引
this.uploadIndex = {} // 上传的索引
this.countFinsh = 0 // 上传完成的个数
this.init()
}
},
mounted() {
this.init()
console.log(111)
console.log(this.$route, 9900)
},
computed: {
allComplete() {
// 上传个数等于 完成个数
console.log(this.uploadCount, this.countFinsh)
if (this.uploadCount == this.countFinsh && this.countFinsh != 0) {
return true
}
return false
}
},
filters: {
Datastatus(val) {
if (val < 0) {
return ''
}
if (val == 0) {
return '正在解析中'
}
if (val < 100) {
return (val + '%')
}
if (val >= 100) {
return '已完成'
}
},
anastatus(val) {
if (val < 0) {
return ''
}
if (val == 0) {
return ''
}
if (val < 100) {
return ('进度' + val + '%')
}
},
byteTransform
// (limit) {
// let size = ''
// if (limit < 1 * 1024) { // 小于0.1KB,则转化成B
// size = limit.toFixed(2) + 'B'
// } else if (limit < 1 * 1024 * 1024) { // 小于1MB,则转化成KB
// size = (limit / 1024).toFixed(2) + 'KB'
// } else if (limit < 1 * 1024 * 1024 * 1024) { // 小于1GB,则转化成MB
// size = (limit / (1024 * 1024)).toFixed(2) + 'MB'
// } else { // 其他转化成GB
// size = (limit / (1024 * 1024 * 1024)).toFixed(2) + 'GB'
// }
// var sizeStr = size + '' // 转成字符串
// var index = sizeStr.indexOf('.') // 获取小数点处的索引
// var dou = sizeStr.substr(index + 1, 2) // 获取小数点后两位的值
// if (dou == '00') { // 判断后两位是否为00,如果是则删除00
// return sizeStr.substring(0, index) + sizeStr.substr(index + 3, 2)
// }
// return size
// }
},
methods: {
// /** -----------新版分割线-------- */视频上传
beforeUploadVideo({ file }) {
this.isDefault = false
this.data.push({
name: file.name,
percent: 0,
msize: file.size,
analysis: 0,
curSize: 0
})
this.uploadCount++
},
getProgress(data) {
this.data[data.count].percent = Math.floor(data.percent * 100)
this.data[data.count].uploadStatus = false
this.data[data.count].uploadErrorTip = ''
this.data[data.count].curSize = this.data[data.count].percent > 0 ? this.data[data.count].msize * this.data[data.count].percent * 0.01 : 0
},
submitVideoSuccess(val) {
var vm = this
vm.countFinsh++
const data = val[0]
const params = {
resId: data.doneResult.fileId,
resName: data.file.name,
resUrl: data.doneResult.video.url,
resType: 1,
categoryId: vm.$route.params.fId
}
saveVideo(params).then((res) => {
// 转码
convertTxVodFile(params.resId, { type: 'resLibrary' }).then(res => {
})
})
},
submitVideoError(err, { uploadCount }) {
// this.data.forEach(el => {
// if (el.percent < 100) {
// el.uploadStatus = '上传失败'
// el.uploadErrorTip = err
// }
// })
this.$set(
this.data[uploadCount],
'uploadStatus',
'上传失败'
)
this.$set(
this.data[uploadCount],
'uploadErrorTip',
err
)
this.$set(this.data, this.data, false)
this.$message.error('上传失败的原因:' + err)
},
/** -----------新版分割线-------- */
handleAvatarBeforeUpload() {},
onexceed() {
this.$message({
type: 'info',
message: '最多上传个数为10个'
})
},
handleSuccess(res, file, filelist) {
if (this.$route.params.type == 'Audio') {
const audioUrl = res.hash
audioCallBack({ audioName: file.name, audioUrl, fId: this.fId }).then((res) => {
// if (res.data.statusCode == 200) {
// }
}).catch(() => {
this.$message({
message: '音频入库失败!',
type: 'error'
})
})
}
let countUnUploaded = 0 // 未上传个数
console.log(filelist)
filelist.filter((item, index) => {
if (item.status == 'uploading') {
countUnUploaded += 1
}
})
if (!countUnUploaded) {
this.isComplete = true
}
},
// handleError(err, file, filelist) {
// },
customRequest(data) {
// axios.post(data.action,this.imgSignData)
},
change(file, filelist) {
console.log(filelist, 7878)
},
beforeUpload(file) {
// 上传规则限制
if (!this.rule(file)) {
return false
}
this.isDefault = false
if (this.$route.params.type == 'Image') {
this.imgUpload(file)
this.uploadIndex[file.uid] = this.uploadCount++
console.log(this.uploadIndex[file.uid])
}
if (this.$route.params.type == 'Audio') {
this.url = 'https://upload.qiniup.com/'
this.getQiniuToken()
if (!this.audioData.token) {
this.$message({
type: 'info',
message: '获取七牛信息失败请刷新页面重试'
})
return
}
this.data.push({
msize: file.size,
name: file.name,
percent: 0,
curSize: 0
})
this.uploadIndex[file.uid] = this.uploadCount++
console.log(this.uploadIndex[file.uid])
}
if (this.$route.params.type == 'Video') {
return false
}
},
progress(event, file) {
if (this.$route.params.type == 'Video') {
return false
} else {
const index = this.uploadIndex[file.uid]
this.data[index].percent = (event.loaded / event.total * 100).toFixed(2)
this.data[index].curSize = (file.size * this.data[index].percent * 0.01).toFixed(0)
}
},
imgUpload(file) {
const index = file.name.lastIndexOf('.')
const preFilename = file.name.slice(0, index).replace(/\s/g, '') // 图片名字
const filetype = file.name.slice(index) // 图片类型
this.uploadData.key = this.FideDir + preFilename + '_' + randomString(20) + filetype
this.uploadData.name = file.name
this.data.push({
msize: file.size,
name: file.name,
percent: 0,
curSize: 0
})
},
init() {
this.curName = this.nameList[this.$route.params.type]
this.fId = this.$route.params.fId
if (this.$route.params.type == 'Image') {
this.getImgSign()
this.ruleContent = `
支持批量上传(单次最多10个),只支持JPG、PNG、GIF格式,文件大小建议不超过3M;文件名称不超过100个字;
上传过程中,请勿关闭页面,否则上传失败;
`
}
if (this.$route.params.type == 'Audio') {
this.url = 'https://upload.qiniup.com/'
this.$nextTick(() => {
this.getQiniuToken()
})
this.ruleContent = `
支持批量上传(单次最多10个),只支持MP3格式,文件大小建议不超过300M;
上传过程中,请勿关闭页面,否则上传失败;
`
}
if (this.$route.params.type == 'Video') {
this.url = 'https://upload.qiniup.com/'
// this.getQiniuToken();
this.ruleContent = `
支持批量上传(单次最多10个),只支持MP4格式,建议用chrome或者360极速模式浏览器上传;
单个文件大小建议不超过1G,文件名请勿包含特殊字符(#^;<>);
上传过程中,请勿关闭页面,否则上传失败;
`
}
},
getImgSign() {
imageSign({ fId: this.fId }).then((res) => {
if (res.status == 200) {
const curData = res.data.data
this.url = curData.host
this.uploadData = {
'key': '',
'policy': curData.policy,
'OSSAccessKeyId': curData.accessid,
'success_action_status': '200', // 让服务端返回200,不然,默认会返回204
'callback': curData.callback,
'signature': curData.signature
}
this.FideDir = curData.dir
}
}).catch((_) => {
})
},
getQiniuToken() {
getUploadToken().then(res => {
this.audioData.token = res.data.data
this.uploadData.token = res.data.data
}).catch(err => {
console.log(err)
})
},
emptySize(file, name) {
if (file.size == 0) {
this.$message.error(`上传的${name}内容不存在`)
return true
}
return false
},
rule(file) {
// 上传规则
if (this.$route.params.type == 'Image') {
// 封面选择文件判断
const isFu = /[\/]|[\?]|[\:]|[\*]|[\"]|[<]|[>]|[,]|[']|[\+]|[\#]|[%]/.test(file.name)
if (isFu) {
this.$message({
message: `文件名不得包含 / : * ? " < > , ' + # %等特殊字符`,
type: 'warning'
})
return false
}
const isImg = file.type == 'image/jpeg' || file.type == 'image/png' || file.type == 'image/gif'
if (!isImg) {
this.$message.warning('上传图片只能是 JPG , PNG 或者 GIF 格式')
return false
}
if (this.emptySize(file, '图片')) {
return false
}
const isLt3M = file.size / 1024 / 1024 < 3
if (!isLt3M) {
this.$message.error('上传图片大小不能超过 3MB!')
return false
}
const isLength = file.name.length <= 100
if (!isLength) {
this.$message.error('图片名称不能超过 100 个字!')
return false
}
return isImg && isLt3M && isLength
}
if (this.$route.params.type == 'Audio') {
// 封面选择文件判断
const isImg = file.type == 'audio/mp3' || file.type == 'audio/mpeg'
if (!isImg) {
this.$message.warning('上传音频只能是MP3格式')
return false
}
if (this.emptySize(file, '音频')) {
return false
}
const isLt3M = file.size / 1024 / 1024 < 300
if (!isLt3M) {
this.$message.error('上传音频大小不能超过 300M!')
return false
}
return isImg && isLt3M
}
if (this.$route.params.type == 'Video') {
// 封面选择文件判断
const isImg = file.type == 'video/mp4'
if (!isImg) {
this.$message.warning('上传视频只能是MP4格式')
return false
}
if (this.emptySize(file, '视频')) {
return false
}
const isLt3M = file.size / 1024 / 1024 < 2048
if (!isLt3M) {
this.$message.error('上传视频大小不能超过 2GB!')
return false
}
const isFu = /[\/]|[\?]|[\:]|[\*]|[\"]|[<]|[>]|[,]|[']/.test(file.name)
if (isFu) {
this.$message({
message: `视频文件名不得包含 / : * ? " < > , ' 等字符`,
type: 'warning'
})
return false
}
return isImg && isLt3M && !isFu
}
},
back() {
this.$store.dispatch('delVisitedViews', this.$route).then((views) => {
this.$router.push({ name: 'materialBank' })
})
}
}
}
</script>
<style scoped lang="scss">
.vhcenter {
position: absolute;
top:50%;
left:50%;
width:100%;
transform:translate(-50%,-50%);
text-align: center;
img {
vertical-align: middle;
}
}
.Mplupload-box {
max-height: 600px;
overflow: auto;
}
.upload-progress {
height: 8px;
background-color: #ccc;
margin: 14px 0;
border-radius: 2px;
position: relative;
.upload-bar {
position: absolute;
// transition: all 0.67s;
height: 8px;
border-radius: 2px;
left: 0;
}
}
</style>
<style>
.vhcenter .el-upload {
width: 100% !important;
}
.drag-upload .el-upload-dragger {
width: 100%;
height: 100%;
background: #fafafa;
border: 0;
}
</style>