93
<template>
<div>
<a-modal v-model:visible="modalVisible" title="上传Graph测试视频" :destroyOnClose="true">
<div class="graph-modal-form-item">
<div class="graph-modal-form-item-label">待测Graph:</div>
{{ record.name }}
</div>
<div style="display:flex;flex-direction: row;">
<div class="graph-modal-form-item-label">
上传测试视频:
</div>
<UploadToOss
selectfilesId="idd"
@returnFileSrc="returnFileSrc($event)"
@deleteAllFile="deleteAllFile(a)"
type="file"
key="id"
fileType="mp4"
:md5="true"
/>
</div>
<template #footer>
<a-button @click="sendUrl" type="primary">确定</a-button>
</template>
</a-modal>
<a-modal v-model:visible="success" title="上传成功"
><div style="display:flex;justify-content:center">
<CheckCircleTwoTone
:style="{ fontSize: '80px' }"
twoToneColor="#52c41a"
/>
</div>
<div style="display:flex;justify-content:center;margin-top:15px">
正在测试模型,测试过程需要一段时间,完成后将邮件告知您
</div>
<template #footer>
<a-button @click="success = false" type="primary">确定</a-button>
</template></a-modal
>
</div>
</template>
<script>
import UploadToOss from '@/components/UploadToOss.vue'
import { CheckCircleTwoTone } from '@ant-design/icons-vue'
import { sendVideoUrl } from '@/requests'
export default {
data () {
return {
success: false,
modalVisible: false,
record: {},
url: ''
}
},
components: {
CheckCircleTwoTone,
UploadToOss
},
methods: {
open (record) {
this.modalVisible = true
this.record = record
// console.log('openrecord', record)
},
returnFileSrc (url) {
this.url = url
},
deleteAllFile () {
this.url = ''
},
sendUrl () {
if (this.url) {
sendVideoUrl()
.then(res => {
console.log(res)
this.modalVisible = false
this.success = true
})
.catch(error => {
this.$message.error(error)
})
} else {
this.$message.error('请上传视频文件')
}
}
}
}
</script>
<style scoped></style>
还是要先把视频文件上传到阿里云oss上返回一个url地址,再把这个地址发给后端。
<template lang="html">
<div style="max-width: 500px;">
<div v-if="currentStatus === 'before upload'">
<a-button @click="doUpload" :disabled="disabled">{{btnText}}</a-button>
<div class="desc">
<span>只允许上传 .{{allowFileType}} 格式文件</span>
<a-tooltip placement="right" v-if="fileDesc">
<template #title>
<span>{{fileDesc}}</span>
</template>
<QuestionCircleOutlined style="margin-left: 6px;"/>
</a-tooltip>
</div>
<!-- {{fileDesc}} -->
</div>
<div id="container">
<div
hidden
:id="selectfilesId"
class="btn"
:disabled="startUpload || files_array.length === 1"
></div>
<a-progress style="width: 80%; min-width: 260px;" v-if="currentStatus === 'uploading'" :percent="upload_progress" size="small" status="active" />
<div v-if="originalFileName" style="display: flex; align-items: center;">
<span class="file-url">
<a-tooltip>
<template #title>{{originalFileName}}</template>
{{ originalFileName }}
</a-tooltip>
</span>
<DeleteOutlined style="cursor: pointer; margin-left: 10px;" @click="clearFiles" /></div>
</div>
</div>
</template>
<script>
import plupload from 'plupload'
import SparkMD5 from 'spark-md5'
import { DeleteOutlined, QuestionCircleOutlined } from '@ant-design/icons-vue'
function calculate (file, callBack) {
const fileReader = new FileReader()
const blobSlice =
File.prototype.mozSlice ||
File.prototype.webkitSlice ||
File.prototype.slice
const chunkSize = 2097152
// read in chunks of 2MB
const chunks = Math.ceil(file.size / chunkSize)
let currentChunk = 0
const spark = new SparkMD5()
function loadNext () {
const start = currentChunk * chunkSize
const end = start + chunkSize >= file.size ? file.size : start + chunkSize
fileReader.readAsBinaryString(blobSlice.call(file, start, end))
}
fileReader.onload = function (e) {
spark.appendBinary(e.target.result) // append binary string
currentChunk++
if (currentChunk < chunks) {
loadNext()
} else {
callBack(spark.end())
}
}
loadNext()
}
export default {
name: 'UploadFile',
components: {
DeleteOutlined,
QuestionCircleOutlined
},
data () {
return {
ossFile: '',
uploadMethod: '',
accessid: '',
accesskey: '',
upload_progress: 0,
host: '',
policyBase64: '',
signature: '',
callbackbody: '',
key: '',
file_name: '',
file_size: 0,
startUpload: false,
expire: 0,
g_object_name: '',
g_object_name_type: '',
now: Date.parse(new Date()) / 1000,
files_array: [],
videoSrc: null,
currentStatus: 'before upload',
fileUrl: '',
originalFileName: ''
}
},
props: {
beforeUpload: Function,
onSuccess: Function,
onError: Function,
onProgress: Function,
disabled: {
default: false
},
project_id: {
default: ''
},
selectfilesId: {
default: ''
},
type: {
default: ''
},
fileType: {
default: ''
},
md5: {
defalut: true
},
defaultFileName: {
default: ''
},
btnText: {
default: '上传文件'
},
fileDesc: {
type: String,
defalut: ''
}
},
mounted () {
this.file_name = ''
this.$nextTick(() => {
this.upload()
})
this.files_array = []
// TODO: 初始化默认文件名称
if (this.defaultFileName) {
this.currentStatus = 'success'
// const regx = /[^\\\/]*[\\\/]+/g
// this.originalFileName = this.defaultFileName.replace(regx, '')
this.originalFileName = this.defaultFileName.split('/').pop()
}
},
computed: {
allowFileType () {
if (this.type === 'video') {
return 'mp4'
} else if (this.type === 'file') {
if (this.fileType) {
return this.fileType
}
console.log(333)
return 'zip,rar,tar,apk,gzip'
} else if (this.type === 'compress') {
return 'zip,rar'
} else {
return 'png,jpg,jpeg'
}
}
},
methods: {
cancelUpload () {
this.uploader.stop()
this.clearFiles()
this.$emit('uploadCurrentStep', {
step: 'before upload'
})
},
doUpload () {
document.getElementById(this.selectfilesId).click()
},
calculateMD5 () {
const file = this.files_array[0]
const filename = file.name
const pos = filename.lastIndexOf('.')
let suffix = ''
let onlyFileName = ''
if (pos !== -1) {
suffix = filename.substring(pos)
onlyFileName = filename.substring(0, pos)
}
calculate(this.files_array[0].getNative(), md5 => {
this.setUploadParam(this.uploader, onlyFileName + '_' + md5 + suffix, false)
this.startUpload = true
})
},
clearFiles () {
this.files_array = []
this.upload_progress = 0
this.g_object_name = ''
this.currentStatus = 'before upload'
this.startUpload = false
this.videoSrc = null
this.ossFile = null
this.fileUrl = ''
this.originalFileName = ''
this.deleteAllFile()
// this.$destroy()
this.$emit('deleteAllFile')
},
deleteAllFile (file) {
if (this.uploader.files[0]) {
this.uploader.removeFile(this.uploader.files[0].id)
}
},
sendRequest () {
const xmlhttp = new XMLHttpRequest()
// 你的服务端接口地址: 参考demo:http://oss-demo.aliyuncs.com/oss-h5-upload-js-php/
// 服务端签名后直传文档: https://help.aliyun.com/document_detail/31926.html
const serverUrl = process.env.VUE_APP_API_BASE_URL + 'api/admin/oss_signature?type=advertise'
xmlhttp.open('GET', serverUrl, false)
xmlhttp.send(null)
return xmlhttp.responseText
},
getSignature () {
this.now = Date.parse(new Date()) / 1000
if (this.expire < this.now + 3) {
const body = this.sendRequest()
let obj = JSON.parse(body)
console.log(obj)
console.log('----------------')
obj = obj.data
this.host = obj.host
this.policyBase64 = obj.policy
this.accessid = obj.accessid
this.signature = obj.signature
this.expire = parseInt(obj.expire, 10).toString()
this.callbackbody = obj.callback
this.key = obj.dir
return true
}
return false
},
getSuffix (filename) {
const pos = filename.lastIndexOf('.')
let suffix = ''
if (pos !== -1) {
suffix = filename.substring(pos)
}
return suffix
},
calculateObjectName (filename) {
this.g_object_name = this.key + filename
},
getUploadedObjectName (filename) {
console.log('====================================')
console.log(`${this.host}/${this.g_object_name}`)
console.log('====================================')
return `${this.host}/${this.g_object_name}`
},
getVideoDuration (file) {
const binaryData = []
binaryData.push(file)
this.videoSrc = window.URL.createObjectURL(
new Blob(binaryData, { type: 'video/mp4' })
)
},
setUploadParam (up, filename, ret) {
console.log(filename)
console.log('------------------dd')
if (ret === false) {
this.getSignature()
}
this.g_object_name = this.key
console.log('====================================')
console.log(filename)
console.log('====================================')
if (filename !== '') {
this.calculateObjectName(filename)
}
const newMultipartParams = {
key: this.g_object_name,
policy: this.policyBase64,
OSSAccessKeyId: this.accessid,
// 让服务端返回200,不然,默认会返回204
success_action_status: '200',
signature: this.signature,
callback: this.callbackbody
}
up.setOption({
url: this.host,
multipart_params: newMultipartParams
})
up.start()
},
upload () {
console.log('====================================')
console.log('==========sssssssssss')
console.log(this.allowFileType)
console.log('====================================')
const that = this
that.uploader = new plupload.Uploader({
runtimes: 'html5,flash,silverlight,html4',
browse_button: that.selectfilesId,
multi_selection: false,
container: document.getElementById('container'),
flash_swf_url: '../../static/pupload/plupload-2.1.2/js/Moxie.swf',
silverlight_xap_url: '../../static/pupload/plupload-2.1.2/js/Moxie.xap',
url: '',
filters: {
mime_types: [
{
title: '文件',
extensions: this.allowFileType
}
],
// 最大只能上传200mb的文件
// max_file_size: '200mb',
// 不允许队列中存在重复文件
prevent_duplicates: false
},
init: {
removeFile: () => {
console.log('=================ss')
},
// PostInit: () => {
// this.ossFile = '';
// document.getElementById('postfiles').onclick = () => {
// console.log('=========aa')
// that.setUploadParam(that.uploader, '', false);
// that.startUpload = true;
//
// // console.log('...');
// return false;
// };
// },
FilesAdded: (up, files) => {
console.log('==================ddd==================')
console.log(files)
console.log(up)
console.log('====================ddd================')
files.unshift()
plupload.each(files, file => {
file.calu_size = plupload.formatSize(file.size)
const fileNative = file.getNative()
that.files_array.push(file)
const extName = file.name.substring(
file.name.lastIndexOf('.') + 1
)
console.log(that.md5)
if (that.md5) {
that.calculateMD5(fileNative)
} else {
console.log(fileNative)
that.setUploadParam(that.uploader, fileNative.name, false)
}
that.originalFileName = fileNative.name
that.currentStatus = 'uploading'
})
},
BeforeUpload: (up, file) => {
// that.checkObjectRadio();
// that.setUploadParam(up, file.md5name, true);
console.group('before')
console.log(up)
console.log(file)
console.groupEnd()
this.$emit('uploading')
},
UploadProgress: (up, file) => {
that.upload_progress = file.percent
},
FileUploaded: (up, file, info) => {
console.group('after')
console.log(up)
console.log(file)
console.log(info)
console.groupEnd()
this.$emit('uploadCurrentStep', {
step: 'upload success'
})
file.finished = true
that.upload_progress = 100
that.currentStatus = 'success'
if (info.status === 200) {
const r = JSON.parse(info.response)
this.fileUrl = this.getUploadedObjectName()
this.$emit('returnFileSrc', this.fileUrl)
} else {
document
.getElementById(file.id)
.getElementsByTagName('b')[0].innerHTML = info.response
}
},
Error: (up, err) => {
if (err.code === -600) {
this.$emit(
'uploadError',
'message.file_exceeding_the_limit'
)
} else if (err.status === 403) {
// console.log('tocken过期,请刷新页面后再上传文件!');
this.$emit('uploadError', 'token过期,请刷新页面后再上传文件!')
} else {
this.$emit('uploadError', '文件类型错误')
}
if (that.onError) {
that.onError(err.message, up, err)
}
}
}
})
that.uploader.init()
}
},
watch: {
defaultFileName (value) {
console.log('value========', value)
if (value) {
this.currentStatus = 'success'
// this.originalFileName = value
// const regx = /[^\\\/]*[\\\/]+/g
// this.originalFileName = value.replace(regx, '')
this.originalFileName = value.split('/').pop()
} else {
this.currentStatus = 'before upload'
this.originalFileName = value
}
}
}
}
</script>
<style scoped>
.progress {
width: 100px;
}
.file-info {
line-height: 22px;
font-size: 13px;
}
.upload-zone {
width: 330px;
height: 126px;
background: #f4f4f4;
border-radius: 4px;
}
.file-url {
overflow: hidden;
display: inline-block;
text-overflow: ellipsis;
white-space: nowrap;
}
.desc {
width: 100%;
font-size: 12px;
color: #666;
line-height: 16px;
}
</style>