|
|
@@ -1,25 +1,31 @@ |
|
|
|
<template> |
|
|
|
<div class="dropzone-wrapper dataset-files"> |
|
|
|
<div |
|
|
|
id="dataset" |
|
|
|
class="dropzone" |
|
|
|
/> |
|
|
|
<p class="upload-info"> |
|
|
|
{{ file_status_text }} |
|
|
|
<strong class="success text red">{{ status }}</strong> |
|
|
|
</p> |
|
|
|
<el-button style="background-color: #21ba45;" type="success" :disabled="btnFlag" @click="onFileAdded">{{upload}}</el-button> |
|
|
|
<div id="dataset" class="dropzone"> |
|
|
|
<div class="maxfilesize ui red message" style="display: none;margin: 2.5rem;"></div> |
|
|
|
</div> |
|
|
|
<el-button style="background-color: #21ba45;margin-top: 2rem;" type="success" :disabled="btnFlag" @click="startUpload">{{upload}}</el-button> |
|
|
|
<el-button type="info" @click="cancelDataset">{{cancel}}</el-button> |
|
|
|
<!-- <p>说明:<br> |
|
|
|
- 只有zip格式的数据集才能发起云脑任务;<br> |
|
|
|
- 云脑1提供 <span class="text blue">CPU / GPU</span> 资源,云脑2提供 <span class="text blue">Ascend NPU</span> 资源;调试使用的数据集也需要上传到对应的环境。</p> --> |
|
|
|
<div style="margin-top: 2rem;position: relative;"> |
|
|
|
<label class="el-form-item__label" style="width: 140px;position: absolute;left: -140px;">上传状态:</label> |
|
|
|
<div v-for="item in allUploadFiles" style="display:flex;padding: 0.8rem 0;border-bottom: 1px solid #e8e8e8;line-height: 1;" > |
|
|
|
<span style="flex:4 1 0%;display: flex;max-width: 80%;"><i :class="[item.status===0?'ri-checkbox-circle-line success':'ri-close-circle-line failed']" style="margin-right: 0.5rem;"></i><span class="nowrap">{{item.name}}</span></span> |
|
|
|
|
|
|
|
<span style="flex:1" v-if="item.status===0"><span style="color: #21ba45;">上传成功</span></span> |
|
|
|
|
|
|
|
<span style="flex:1" v-else-if="item.status===1"> |
|
|
|
<el-tooltip class="item" effect="dark" placement="top"> |
|
|
|
<div slot="content">{{item.info}}</div> |
|
|
|
<span style="color: red;cursor: pointer;">上传失败<span>(重复上传)</span></span> |
|
|
|
</el-tooltip> |
|
|
|
</span> |
|
|
|
<span style="flex:1" v-else><span style="color: red;">上传失败</span></span> |
|
|
|
|
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</template> |
|
|
|
|
|
|
|
<script> |
|
|
|
/* eslint-disable eqeqeq */ |
|
|
|
// import Dropzone from 'dropzone/dist/dropzone.js'; |
|
|
|
// import 'dropzone/dist/dropzone.css' |
|
|
|
import SparkMD5 from 'spark-md5'; |
|
|
|
import axios from 'axios'; |
|
|
|
import qs from 'qs'; |
|
|
@@ -43,8 +49,8 @@ export default { |
|
|
|
data() { |
|
|
|
return { |
|
|
|
dropzoneUploader: null, |
|
|
|
maxFiles: 1, |
|
|
|
maxFilesize: 1 * 1024 * 1024 * 1024 * 1024, |
|
|
|
maxFiles: 10, |
|
|
|
maxFilesize: 200 , |
|
|
|
acceptedFiles: '*/*', |
|
|
|
progress: 0, |
|
|
|
status: '', |
|
|
@@ -55,6 +61,11 @@ export default { |
|
|
|
btnFlag:false, |
|
|
|
cancel:'', |
|
|
|
upload:'', |
|
|
|
uploadFiles:[], |
|
|
|
uploadFilesAddId:[], |
|
|
|
allUploadFiles:[], |
|
|
|
uploadLength:0, |
|
|
|
allUploadLength:0, |
|
|
|
}; |
|
|
|
}, |
|
|
|
|
|
|
@@ -65,82 +76,98 @@ export default { |
|
|
|
this.repoPath = this.dropzoneParams.data('repopath'); |
|
|
|
this.cancel = this.dropzoneParams.data('cancel'); |
|
|
|
this.upload = this.dropzoneParams.data('upload'); |
|
|
|
// let previewTemplate = ''; |
|
|
|
// previewTemplate += '<div class="dz-preview dz-file-preview">\n '; |
|
|
|
// previewTemplate += ' <div class="dz-details">\n '; |
|
|
|
// previewTemplate += ' <div class="dz-filename">'; |
|
|
|
// previewTemplate += |
|
|
|
// ' <span data-dz-name data-dz-thumbnail></span>'; |
|
|
|
// previewTemplate += ' </div>\n '; |
|
|
|
// previewTemplate += ' <div class="dz-size" data-dz-size style="white-space: nowrap"></div>\n '; |
|
|
|
// previewTemplate += ' </div>\n '; |
|
|
|
// previewTemplate += ' <div class="dz-progress ui active progress">'; |
|
|
|
// previewTemplate += |
|
|
|
// ' <div class="dz-upload bar" data-dz-uploadprogress><div class="progress"></div></div>\n '; |
|
|
|
// previewTemplate += ' </div>\n '; |
|
|
|
// previewTemplate += ' <div class="dz-success-mark">'; |
|
|
|
// previewTemplate += ' <span>上传成功</span>'; |
|
|
|
// previewTemplate += ' </div>\n '; |
|
|
|
// previewTemplate += ' <div class="dz-error-mark">'; |
|
|
|
// previewTemplate += ' <span>上传失败</span>'; |
|
|
|
// previewTemplate += ' </div>\n '; |
|
|
|
// previewTemplate += ' <div class="dz-error-message">'; |
|
|
|
// previewTemplate += ' <span data-dz-errormessage></span>'; |
|
|
|
// previewTemplate += ' </div>\n'; |
|
|
|
// previewTemplate += '</div>'; |
|
|
|
let previewTemplate = '' |
|
|
|
previewTemplate += '<div class="dz-preview dz-file-preview" style="width:100%;background: none;">' |
|
|
|
previewTemplate += '<div class="dz-details" style="opacity: 1;">' |
|
|
|
previewTemplate += '<div class="dz-filename"><span data-dz-name></span></div>' |
|
|
|
previewTemplate += '<div class="dz-size" data-dz-size></div>' |
|
|
|
previewTemplate += '<div class="dz-progress ui active progress" style="top: 75%;width: 80%;left: 15%;"><div class="dz-upload bar" data-dz-uploadprogress><div class="progress"></div></div></div>' |
|
|
|
// previewTemplate += '<img data-dz-thumbnail />' |
|
|
|
previewTemplate += '</div>' |
|
|
|
|
|
|
|
previewTemplate += '<div class="dz-success-mark"><span>✔</span></div>' |
|
|
|
previewTemplate += '<div class="dz-error-mark"><span>✘</span></div>' |
|
|
|
previewTemplate += '<div class="dz-error-message"><span data-dz-errormessage></span></div>' |
|
|
|
previewTemplate += '</div>' |
|
|
|
let previewTemplate = ` |
|
|
|
<div class="dz-preview dz-file-preview"> |
|
|
|
<div class="dz-image"> |
|
|
|
<img data-dz-thumbnail /> |
|
|
|
</div> |
|
|
|
<div class="dz-details"> |
|
|
|
<div class="dz-size"><span data-dz-size></span></div> |
|
|
|
<div class="dz-filename"><span data-dz-name></span></div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<div class="dz-progress"><span class="dz-upload" data-dz-uploadprogress></span></div> |
|
|
|
<div class="dz-error-message" style="line-height: 1.5;"><span data-dz-errormessage></span></div> |
|
|
|
<div class="dz-success-mark"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="54" height="54"><path fill="none" d="M0 0h24v24H0z"/><path d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm0-2a8 8 0 1 0 0-16 8 8 0 0 0 0 16zm-.997-4L6.76 11.757l1.414-1.414 2.829 2.829 5.656-5.657 1.415 1.414L11.003 16z" fill="rgba(47,204,113,1)"/></svg></div> |
|
|
|
<div class="dz-error-mark"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="54" height="54"><path fill="none" d="M0 0h24v24H0z"/><path d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm0-2a8 8 0 1 0 0-16 8 8 0 0 0 0 16zm0-9.414l2.828-2.829 1.415 1.415L13.414 12l2.829 2.828-1.415 1.415L12 13.414l-2.828 2.829-1.415-1.415L10.586 12 7.757 9.172l1.415-1.415L12 10.586z" fill="rgba(231,76,60,1)"/></svg></div> |
|
|
|
</div> ` |
|
|
|
const $dropzone = $('div#dataset'); |
|
|
|
const dropzoneUploader = await createDropzone($dropzone[0], { |
|
|
|
url: '/todouploader', |
|
|
|
maxFiles: this.maxFiles, |
|
|
|
maxFilesize: this.maxFileSize, |
|
|
|
maxFilesize: 1024*200, |
|
|
|
filesizeBase:1024, |
|
|
|
parallelUploads: this.maxFiles, |
|
|
|
timeout: 0, |
|
|
|
autoQueue: false, |
|
|
|
addRemoveLinks:true, |
|
|
|
// autoQueue: false, |
|
|
|
autoProcessQueue: false, //自动上传 |
|
|
|
dictDefaultMessage: this.dropzoneParams.data('default-message'), |
|
|
|
dictInvalidFileType: this.dropzoneParams.data('invalid-input-type'), |
|
|
|
dictFileTooBig: this.dropzoneParams.data('file-too-big'), |
|
|
|
dictRemoveFile: this.dropzoneParams.data('remove-file'), |
|
|
|
previewTemplate |
|
|
|
previewTemplate:previewTemplate |
|
|
|
}); |
|
|
|
dropzoneUploader.on('addedfile', (file) => { |
|
|
|
this.file = file |
|
|
|
}); |
|
|
|
dropzoneUploader.on('maxfilesexceeded', function (file) { |
|
|
|
if (this.files[0].status !== 'success') { |
|
|
|
alert(this.dropzoneParams.data('waitting-uploading')); |
|
|
|
this.removeFile(file); |
|
|
|
return; |
|
|
|
if(file.size/(1024*1024)>dropzoneUploader.options.maxFilesize){ |
|
|
|
dropzoneUploader.removeFile(file) |
|
|
|
$('.maxfilesize.ui.red.message').text("单次最多上传10个文件,单个文件不超过200G") |
|
|
|
$('.maxfilesize.ui.red.message').css('display','block') |
|
|
|
|
|
|
|
}else{ |
|
|
|
this.file = file |
|
|
|
$('.maxfilesize.ui.red.message').css('display','none') |
|
|
|
|
|
|
|
} |
|
|
|
this.removeAllFiles(); |
|
|
|
this.addFile(file); |
|
|
|
}); |
|
|
|
dropzoneUploader.on("removedfile",(file)=>{ |
|
|
|
$('.maxfilesize.ui.red.message').css('display','none') |
|
|
|
}) |
|
|
|
dropzoneUploader.on('maxfilesexceeded', function (file) { |
|
|
|
dropzoneUploader.removeFile(file) |
|
|
|
$('.maxfilesize.ui.red.message').text("单次最多上传10个文件,单个文件不超过200G") |
|
|
|
$('.maxfilesize.ui.red.message').css('display','block') |
|
|
|
|
|
|
|
}); |
|
|
|
this.dropzoneUploader = dropzoneUploader; |
|
|
|
}, |
|
|
|
watch:{ |
|
|
|
allUploadLength(len){ |
|
|
|
if(len===this.uploadFiles.length){ |
|
|
|
setTimeout(() => { |
|
|
|
this.dropzoneUploader.removeAllFiles(true) |
|
|
|
this.btnFlag = false |
|
|
|
this.$emit('setcluster',this.btnFlag) |
|
|
|
}, 2000); |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
methods: { |
|
|
|
startUpload(){ |
|
|
|
this.uploadFiles = this.dropzoneUploader.getQueuedFiles() |
|
|
|
if(this.uploadFiles.length===0){ |
|
|
|
return |
|
|
|
} |
|
|
|
this.resetStatus() |
|
|
|
$('.dz-remove').remove() |
|
|
|
$('.maxfilesize.ui.red.message').css('display','none') |
|
|
|
this.btnFlag = true |
|
|
|
this.$emit('setcluster',this.btnFlag) |
|
|
|
this.uploadFiles.forEach(element => { |
|
|
|
element.datasetId = document.getElementById('datasetId').getAttribute('datasetId') |
|
|
|
this.computeMD5(element) |
|
|
|
}); |
|
|
|
}, |
|
|
|
cancelDataset(){ |
|
|
|
location.href = this.repoPath |
|
|
|
this.dropzoneUploader.removeAllFiles(true) |
|
|
|
}, |
|
|
|
resetStatus() { |
|
|
|
this.progress = 0; |
|
|
|
this.status = ''; |
|
|
|
this.uploadLength = 0 |
|
|
|
this.allUploadLength = 0 |
|
|
|
this.allUploadFiles = [] |
|
|
|
}, |
|
|
|
updateProgress(file, progress) { |
|
|
|
console.log("progress---",progress) |
|
|
|
file.previewTemplate.querySelector( |
|
|
|
'.dz-upload' |
|
|
|
).style.width = `${progress}%` |
|
|
@@ -148,6 +175,26 @@ export default { |
|
|
|
'.dz-upload' |
|
|
|
).style.background = '#409eff'; |
|
|
|
}, |
|
|
|
uploadError(file,info){ |
|
|
|
file.previewTemplate.querySelector( |
|
|
|
'.dz-error-mark' |
|
|
|
).style.opacity = 1 |
|
|
|
file.previewTemplate.querySelector( |
|
|
|
'.dz-progress' |
|
|
|
).style.opacity = 0 |
|
|
|
file.previewTemplate.querySelector( |
|
|
|
'.dz-error-message span' |
|
|
|
).innerHTML = info |
|
|
|
file.previewTemplate.querySelector( |
|
|
|
'.dz-error-message' |
|
|
|
).style.display = 'block' |
|
|
|
file.previewTemplate.querySelector( |
|
|
|
'.dz-details' |
|
|
|
).onmouseover = function(){file.previewTemplate.querySelector('.dz-error-message').style.opacity = 1 } |
|
|
|
file.previewTemplate.querySelector( |
|
|
|
'.dz-details' |
|
|
|
).onmouseout = function(){file.previewTemplate.querySelector('.dz-error-message').style.opacity = 0 } |
|
|
|
}, |
|
|
|
emitDropzoneSuccess(file) { |
|
|
|
file.status = 'success'; |
|
|
|
this.dropzoneUploader.emit('success', file); |
|
|
@@ -159,28 +206,22 @@ export default { |
|
|
|
this.dropzoneUploader.emit('error', file); |
|
|
|
// this.dropzoneUploader.emit('complete', file); |
|
|
|
}, |
|
|
|
onFileAdded() { |
|
|
|
this.btnFlag = true |
|
|
|
this.file.datasetId = document |
|
|
|
.getElementById('datasetId') |
|
|
|
.getAttribute('datasetId'); |
|
|
|
this.resetStatus(); |
|
|
|
if(!this.file?.upload){ |
|
|
|
this.btnFlag = false |
|
|
|
return |
|
|
|
} |
|
|
|
this.computeMD5(this.file); |
|
|
|
}, |
|
|
|
|
|
|
|
finishUpload(file) { |
|
|
|
this.emitDropzoneSuccess(file); |
|
|
|
setTimeout(() => { |
|
|
|
console.log("finish",file) |
|
|
|
file.previewTemplate.querySelector( |
|
|
|
'.dz-success-mark' |
|
|
|
).style.opacity = 1 |
|
|
|
file.previewTemplate.querySelector( |
|
|
|
'.dz-progress' |
|
|
|
).style.opacity = 0 |
|
|
|
if(this.uploadLength === this.uploadFiles.length){ |
|
|
|
setTimeout(() => { |
|
|
|
window.location.href = this.repoPath |
|
|
|
}, 1000); |
|
|
|
}, 1000); |
|
|
|
} |
|
|
|
}, |
|
|
|
|
|
|
|
computeMD5(file) { |
|
|
|
this.resetStatus(); |
|
|
|
const blobSlice = |
|
|
|
File.prototype.slice || |
|
|
|
File.prototype.mozSlice || |
|
|
@@ -189,7 +230,6 @@ export default { |
|
|
|
spark = new SparkMD5.ArrayBuffer(), |
|
|
|
fileReader = new FileReader(); |
|
|
|
let currentChunk = 0; |
|
|
|
|
|
|
|
const time = new Date().getTime(); |
|
|
|
this.status = this.dropzoneParams.data('md5-computing'); |
|
|
|
file.totalChunkCounts = chunks; |
|
|
@@ -225,6 +265,7 @@ export default { |
|
|
|
file.size |
|
|
|
} 用时:${(new Date().getTime() - time) / 1000} s` |
|
|
|
); |
|
|
|
this.updateProgress(file,100) |
|
|
|
spark.destroy(); // 释放缓存 |
|
|
|
file.uniqueIdentifier = md5; // 将文件md5赋值给文件唯一标识 |
|
|
|
file.cmd5 = false; // 取消计算md5状态 |
|
|
@@ -257,6 +298,10 @@ export default { |
|
|
|
this.multipartUpload(file); |
|
|
|
} else { |
|
|
|
// 失败如何处理 |
|
|
|
let info = "上传失败" |
|
|
|
this.allUploadLength++ |
|
|
|
this.uploadError(file,info) |
|
|
|
this.allUploadFiles.push({name:file.name,status:2,info:info}) |
|
|
|
return; |
|
|
|
} |
|
|
|
return; |
|
|
@@ -272,15 +317,16 @@ export default { |
|
|
|
//不同数据集上传同一个文件 |
|
|
|
if (file.datasetID != '') { |
|
|
|
if (file.datasetName != "" && file.realName != "") { |
|
|
|
var info = "该文件已上传,对应数据集(" + file.datasetName + ")-文件(" + file.realName + ")"; |
|
|
|
window.alert(info); |
|
|
|
window.location.reload(); |
|
|
|
let info = `该文件已上传在数据集: ${file.datasetName}` |
|
|
|
this.uploadError(file,info) |
|
|
|
this.allUploadLength++ |
|
|
|
this.allUploadFiles.push({name:file.name,status:1,info:info}) |
|
|
|
} |
|
|
|
} |
|
|
|
console.log('文件已上传完成'); |
|
|
|
this.progress = 100; |
|
|
|
this.status = this.dropzoneParams.data('upload-complete'); |
|
|
|
this.finishUpload(file); |
|
|
|
// this.finishUpload(file); |
|
|
|
} else { |
|
|
|
// 断点续传 |
|
|
|
this.multipartUpload(file); |
|
|
@@ -488,7 +534,12 @@ export default { |
|
|
|
this.status = this.dropzoneParams.data('uploading'); |
|
|
|
loadNext(); |
|
|
|
fileReader.onload = async (e) => { |
|
|
|
await uploadChunk(e); |
|
|
|
try{ |
|
|
|
await uploadChunk(e); |
|
|
|
}catch(err){ |
|
|
|
console.log(err) |
|
|
|
} |
|
|
|
|
|
|
|
fileReader.abort(); |
|
|
|
currentChunk++; |
|
|
|
if (currentChunk < chunks) { |
|
|
@@ -504,12 +555,27 @@ export default { |
|
|
|
).toFixed(2)}%`; |
|
|
|
await loadNext(); |
|
|
|
} else { |
|
|
|
await completeUpload(); |
|
|
|
try{ |
|
|
|
await completeUpload(); |
|
|
|
}catch(err){ |
|
|
|
let info = "上传失败" |
|
|
|
this.allUploadLength++ |
|
|
|
this.uploadError(file,info) |
|
|
|
this.allUploadFiles.push({name:file.name,status:2,info:info}) |
|
|
|
if(err){ |
|
|
|
return |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
console.log( |
|
|
|
`文件上传完成:${file.name} \n分片:${chunks} 大小:${ |
|
|
|
file.size |
|
|
|
} 用时:${(new Date().getTime() - time) / 1000} s` |
|
|
|
); |
|
|
|
this.uploadLength++ |
|
|
|
this.allUploadLength++ |
|
|
|
this.allUploadFiles.push({name:file.name,status:0,info:'上传成功'}) |
|
|
|
this.updateProgress(file, 100); |
|
|
|
this.progress = 100; |
|
|
|
this.status = this.dropzoneParams.data('upload-complete'); |
|
|
@@ -545,4 +611,10 @@ export default { |
|
|
|
margin-top: 1em; |
|
|
|
margin-bottom: 3em; |
|
|
|
} |
|
|
|
.success{ |
|
|
|
color: #21ba45; |
|
|
|
} |
|
|
|
.failed{ |
|
|
|
color: red; |
|
|
|
} |
|
|
|
</style> |