多媒体信息发布平台
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

352 lines
11 KiB

<template>
<div class="components_upload">
<!-- <div v-if="isTheme">
<el-button class="cont_upload_btn" round type="primary">选择文件</el-button>
<input id="upFile" ref="inputfile" type="file" name="upFile" @change="changeFile($event)" />
</div> -->
<el-button class="cont_upload_btn" round type="primary">{{ isTheme ? '选择文件' : '上传' }}</el-button>
<input id="upFile" type="file" name="upFile" @change="changeFile($event)" />
<input v-if="isTheme" type="button" name="开始上传" value="开始上传" class="start_upload" @click="uploadFile()" />
<!-- 上传列表layer -->
<div v-if="!isTheme" class="upload_layer">
<el-dialog
title="上传列表"
:close-on-click-modal="false"
:show-close="false"
:visible.sync="uploadListVisible"
height="384px"
>
<el-table :data="fileData" :header-cell-style="{ color: '#333' }">
<el-table-column align="center" prop="fileNames" label="文件名" />
<el-table-column align="center" prop="formatType" label="类型" />
<el-table-column align="center" prop="fileSize" label="大小" />
<el-table-column align="center" prop="filePercentTxt" label="状态">
<template slot-scope="scope">
<div class="loadingModal" :style="{ 'height': '100%' }">
<el-progress
v-if="scope.row.filePercent != 0 && scope.row.filePercent != 100"
:stroke-width="6"
:percentage="scope.row.filePercent"
/>
<span v-else>{{ scope.row.filePercentTxt }}</span>
</div>
</template>
</el-table-column>
<el-table-column align="center" prop="handle" label="操作">
<template slot-scope="scope">
<!-- <el-button
type="primary"
round
class="on_off_btn"
style="width: 50px; display: inline-block;"
@click="controlUpload(scope.$index)"
>{{ uploadStatus ?'暂停':'继续' }}</el-button> -->
<el-button
type="info"
round
style="width: 50px; display: inline-block;"
class="upload_delt"
@click="deltUpload(scope.$index)"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<div class="upload_list_right">
<div class="upload_list_btn">
<el-button>点击上传</el-button>
<input id="upLoadFile" ref="inputfile" type="file" name="upFile" @change="changeFile($event)" />
</div>
<div class="upload_return" @click="uploadListVisible=false">返回</div>
</div>
</el-dialog>
</div>
</div>
</template>
<script>
import * as qiniu from 'qiniu-js'
import { getQiniuToken, FectchUploadTokenAndOps } from '@/api/upload/upload'
let observable
export default {
name: 'Qiniu',
props: {
isTheme: {
type: Boolean,
required: true
}
},
data() {
return {
file: null,
token: '',
baseurl: 'qiniu.aiyxlib.com',
fileData: [],
fileNames: '',
formatType: '',
postfix: '',
fileSize: '',
duration: 0,
uploadListVisible: false,
subscription: '',
uploadFileUrl: null,
filePercent: 0,
uploadStatus: false,
isActiveType: null
}
},
mounted() {
this.getQiniuToken()
localStorage.removeItem('compareName')
},
methods: {
changeFile(e) {
// 获取文件
this.file = e.target.files[0]
this.$emit('getName', this.file.name)
this.formatType = this.file.type.substring(0, this.file.type.indexOf('/'))
if (this.isActiveType == 0) {
if (this.formatType != 'image') {
this.$message.error('请上传图片文件!')
return
}
} else if (this.isActiveType == 1) {
if (this.formatType != 'video') {
this.$message.error('请上传视频文件!')
return
}
} else if (this.isActiveType == 2) {
if (this.formatType != 'audio') {
this.$message.error('请上传音频文件!')
return
}
}
this.fileNames = this.file.name
this.postfix = this.fileNames.substring(
this.fileNames.lastIndexOf('.') + 1,
this.fileNames.length
)
this.fileSize = this.file.size
if (this.formatType === 'image') {
const isJPG = this.file.type === 'image/jpeg' || this.file.type === 'image/png' || this.file.type === 'image/bmp' || this.file.type === 'image/gif'
const isLt2M = this.file.size / 1024 / 1024 < 4
if (!isJPG) {
this.$message.error('图片只支持bmp、jpg、png、gif格式的文件')
}
if (!isLt2M) {
this.$message.error('图片大小不能超过 4MB !')
}
}
const isRepeat = this.fileData.map(item => item.key).indexOf(this.fileNames)
if (isRepeat == -1) {
this.fileData.push({
fileNames: this.fileNames,
formatType: this.formatType,
fileSize: this.fileSize,
filePercent: 0,
filePercentTxt: '上传中',
key: this.fileNames,
uploadStatus: false
})
if (!this.isTheme) {
setTimeout(() => {
this.uploadFile()
}, 1000)
}
} else {
if (!this.isTheme) {
this.$message({
message: '该素材上传列表内已存在~',
type: 'info'
})
}
}
// this.getOpsToken()
this.uploadListVisible = true
},
getQiniuToken() {
getQiniuToken().then(res => {
this.token = res.data
})
},
getOpsToken() {
const name = Date.parse(new Date()) + '.mp4'
const name1 = Date.parse(new Date())
const param = {
tFileName: name1,
tExtName: this.postfix
}
FectchUploadTokenAndOps(param).then(res => {
this.token = res.data
const _this = this
const putExtra = {
fname: name1,
params: {},
mimeType: null
}
const config = {
useCdnDomain: true,
region: qiniu.region.z0,
concurrentRequestLimit: 3,
checkByMD5: true,
retryCount: 3
}
const token = this.token
observable = qiniu.upload(
this.file,
name,
token,
putExtra,
config
)
_this.percentage = 10
})
},
getVideoDuration(fileUrl) {
const _this = this
const audioElement = new Audio(fileUrl)
audioElement.addEventListener('loadedmetadata', function() {
_this.duration = parseInt(audioElement.duration) // 得到时长为秒,小数,182.36
// self.ruleForm.videoDuration = parseInt(result) // 转为int值
})
},
uploadFile() {
// 当前VUE中的this 是指向实例,相当于父级,指向指不到子级中。所需需要一个变量 _this 存储this得指向。
const _this = this
_this.filePercent = 0
_this.uploadStatus = false
let compareChunks = []
var finishedAttr = []
// 获取身份的token
const token = _this.token
// 上传时的配置
var config = {
useCdnDomain: true
}
// 设置文件的配置
var putExtra = {
fname: '',
params: {},
mimeType: null
}
// 实例化七牛云的上传实例
observable = qiniu.upload(_this.file, _this.file.name, token, putExtra, { resumingByFileSize: 4 * 1024 * 1024 }, config)
// 设置实例的监听对象
localStorage.setItem('currentFile', _this.file.name)
// 接收上传进度信息
var next = function(res) {
const currentFile = localStorage.getItem('currentFile')
const index = _this.fileData.map((item) => item.key).indexOf(currentFile)
var chunks = res.chunks || []
var total = res.total
// 这里对每个chunk更新进度,并记录已经更新好的避免重复更新,同时对未开始更新的跳过
for (var i = 0; i < chunks.length; i++) {
if (chunks[i].percent === 0 || finishedAttr[i]) {
continue
}
if (compareChunks[i].percent === chunks[i].percent) {
continue
}
if (chunks[i].percent === 100) {
finishedAttr[i] = true
}
}
compareChunks = chunks
_this.filePercent = parseInt(total.percent)
_this.$nextTick(function() {
_this.fileData[index].filePercent = _this.filePercent
})
}
// 接收上传错误信息
var error = function(err) {
console.log(err)
}
// 接收上传完成后的信息
var complete = function(res) {
const index = _this.fileData.map((item) => item.key).indexOf(res.key)
_this.uploadFileUrl = 'http://' + _this.baseurl + '/' + res.key
// 上传完成后调用保存素材方法
_this.getVideoDuration(_this.uploadFileUrl)
_this.$nextTick(function() {
_this.fileData[index].filePercentTxt = '上传成功'
_this.fileData[index].filePercent = 100
})
setTimeout(() => {
_this.$emit('saveMaterial')
}, 200)
document.getElementById('upFile').value = ''
document.getElementById('upLoadFile').value = ''
localStorage.removeItem('currentFile')
// localStorage.removeItem('currentCompareName')
}
var subObject = {
next: next,
error: error,
complete: complete
}
_this.controlUpload = function() {
_this.uploadStatus = !_this.uploadStatus
if (_this.uploadStatus) {
_this.subscription = observable.subscribe(subObject) // 调用sdk上传接口获得相应的observable,控制上传和暂停
} else {
_this.subscription.unsubscribe()
}
}
_this.controlUpload()
// 上传开始
// subscription = observable.subscribe(observer)
},
deltUpload(index) {
this.subscription.unsubscribe()
this.fileData.splice(index, 1)
}
}
}
</script>
<style lang="scss" scoped>
.components_upload{
position: relative;
}
#upFile,
#upLoadFile{
display: block;
width: 114px;
height: 34px;
padding: 0;
font-size: 14px;
border: none;
opacity: 0;
}
.cont_upload_btn{
position: absolute;
left: 0;
top: 0;
}
.upload_list_btn{
position: relative;
::v-deep .el-button {
position: absolute;
left: 0;
top: 0;
width: auto;
height: auto;
margin: 0;
padding: 0;
font-size: 14px;
font-weight: bold;
color: #3a8aeb;
}
#upLoadFile{
width: 60px;
}
}
::v-deep .el-progress-bar__outer{
background-color: transparent;
}
::v-deep .el-progress-bar__inner {
background-image: linear-gradient(to right, #40cbfe, #3a8aeb)
}
</style>