<template>
|
<div class="file-uploader">
|
<uploader
|
v-if="single"
|
ref="uploader"
|
:options="options"
|
:file-status-text="statusText"
|
class="uploader-single"
|
@file-added="onFileAdded"
|
@complete="onComplete"
|
>
|
<!-- <uploader-drop v-if="isDrag == true">
|
<div class="drag-txt">拖拽文件到这里</div>
|
<span class="icon iconfont" @click.stop="showUpload = false"
|
></span
|
>
|
<uploader-btn>选择文件</uploader-btn>
|
</uploader-drop> -->
|
|
<div class="up-bar" v-if="isDrag == true">
|
<div class="name">{{ fileName || uploadPlaceholder }}</div>
|
<uploader-btn slot="suffix">
|
<el-tooltip :content="tipWords" placement="top" v-if="tip">
|
<div class="open-file-btn">
|
<span class="icon iconfont"></span>
|
</div>
|
</el-tooltip>
|
</uploader-btn>
|
<!-- <div class="open-file-btn">
|
<span class="icon iconfont"></span>
|
</div> -->
|
</div>
|
<el-input
|
:placeholder="uploadPlaceholder"
|
v-if="isDrag == false"
|
size="small"
|
:readonly="true"
|
v-model="fileName"
|
>
|
<uploader-btn slot="suffix">
|
<el-tooltip :content="tipWords" placement="top" v-if="tip">
|
<i
|
class="el-icon-upload2"
|
style="font-size: 18px; color: #0088ff"
|
></i>
|
</el-tooltip>
|
<i
|
v-else
|
class="el-icon-upload2"
|
style="font-size: 18px; color: #0088ff"
|
></i>
|
</uploader-btn>
|
</el-input>
|
<uploader-list />
|
</uploader>
|
|
<uploader
|
v-else
|
ref="uploader"
|
:options="options"
|
:file-status-text="statusText"
|
class="uploader-example"
|
@file-added="onFileAdded"
|
@file-complete="fileComplete"
|
@complete="onComplete"
|
@close="closeHandle"
|
>
|
<uploader-btn ref="button" :sourceType="sourceType">
|
<i class="el-icon-upload2" style="font-size: 18px; color: #0088ff"></i>
|
上传
|
</uploader-btn>
|
<uploader-list />
|
</uploader>
|
</div>
|
</template>
|
|
<script>
|
import uploader from "./uploader";
|
import SparkMD5 from "spark-md5";
|
import UploaderBtn from "./btn";
|
import UploaderList from "./list";
|
import UploaderDrop from "./drop";
|
|
export default {
|
components: {
|
uploader,
|
UploaderBtn,
|
UploaderList,
|
UploaderDrop,
|
},
|
props: {
|
sourceType: {
|
type: Number,
|
},
|
tip: {
|
type: Boolean,
|
default: false,
|
},
|
tipWords: {
|
type: String,
|
default: "",
|
},
|
single: {
|
type: Boolean,
|
default: false,
|
},
|
uploadPlaceholder: {
|
type: String,
|
default: "",
|
},
|
isDrag: {
|
type: Boolean,
|
default: false,
|
},
|
url: {
|
type: String,
|
default: "/data/api-f/file/upload",
|
},
|
attrs: {
|
type: Object,
|
default() {
|
return {};
|
},
|
},
|
},
|
data() {
|
return {
|
fileName: "",
|
fileMd5: "",
|
statusText: {
|
success: "上传成功",
|
error: "上传失败",
|
uploading: "上传中",
|
paused: "暂停中",
|
waiting: "等待中",
|
},
|
};
|
},
|
computed: {
|
uploader() {
|
return this.$refs.uploader.uploader;
|
},
|
options() {
|
return {
|
target: this.url,
|
testChunks: true,
|
headers: {
|
Authorization:
|
sessionStorage.getItem("loginedInfo") &&
|
JSON.parse(sessionStorage.getItem("loginedInfo")).access_token,
|
},
|
};
|
},
|
},
|
methods: {
|
onFileAdded(file) {
|
if (this.single) {
|
this.uploader.fileList = this.uploader.fileList.slice([-1]);
|
this.$emit("file-added");
|
}
|
this.computeMD5(file);
|
},
|
computeMD5(file) {
|
let fileReader = new FileReader();
|
let time = new Date().getTime();
|
let blobSlice =
|
File.prototype.slice ||
|
File.prototype.mozSlice ||
|
File.prototype.webkitSlice;
|
let currentChunk = 0;
|
const chunkSize = 10 * 1024 * 1000;
|
let chunks = Math.ceil(file.size / chunkSize);
|
let spark = new SparkMD5.ArrayBuffer();
|
// 文件状态设为"计算MD5"
|
this.statusText.paused = "准备上传,正在检查文件";
|
file.pause();
|
loadNext();
|
fileReader.onload = (e) => {
|
spark.append(e.target.result);
|
if (currentChunk < chunks) {
|
currentChunk++;
|
loadNext();
|
} else {
|
let md5 = spark.end();
|
this.computeMD5Success(md5, file);
|
this.fileName = file.name;
|
this.fileMd5 = md5;
|
}
|
};
|
fileReader.onerror = function () {
|
this.error(`文件${file.name}读取出错,请检查该文件`);
|
file.cancel();
|
};
|
function loadNext() {
|
let start = currentChunk * chunkSize;
|
let end =
|
start + chunkSize >= file.size ? file.size : start + chunkSize;
|
fileReader.readAsArrayBuffer(blobSlice.call(file.file, start, end));
|
}
|
},
|
computeMD5Success(md5, file) {
|
//将自定义参数直接加载uploader实例的opts上
|
if (location.href.indexOf("dataStack") >= 0) {
|
Object.assign(this.uploader.opts, {
|
query: {
|
stackId: this.DataStackPool.selectedDir.id,
|
// ...this.params,
|
},
|
});
|
}
|
file.uniqueIdentifier = md5;
|
file.resume();
|
this.statusText.paused = "暂停中";
|
},
|
onComplete() {
|
this.$emit("complete", {
|
filename: this.fileName,
|
identifier: this.fileMd5,
|
});
|
},
|
fileComplete() {},
|
closeHandle() {
|
this.$emit("close");
|
},
|
},
|
mounted() {
|
this.isDrag;
|
this.$nextTick(() => {
|
window.uploader = this.$refs.uploader.uploader;
|
});
|
},
|
};
|
</script>
|
|
<style lang="scss">
|
.file-uploader {
|
.el-input__suffix,
|
.el-input__suffix-inner {
|
outline: none !important;
|
}
|
.el-tooltip.focusing {
|
outline: none;
|
}
|
.uploader-example {
|
width: 99%;
|
// padding: 15px;
|
// margin: 40px auto 0;
|
font-size: 12px;
|
// box-shadow: 0 0 10px rgba(0, 0, 0, 0.4);
|
background-color: #fff;
|
}
|
.uploader-example .uploader-btn {
|
position: relative;
|
display: none;
|
// float: right;
|
// top: -45px;
|
}
|
.uploader-example .uploader-list {
|
max-height: 440px;
|
overflow: auto;
|
overflow-x: hidden;
|
overflow-y: auto;
|
}
|
.uploader-single {
|
position: unset;
|
.close {
|
display: none;
|
}
|
.uploader-btn {
|
border: 0px;
|
}
|
.uploader-file {
|
height: 2px;
|
.uploader-file-progress {
|
background: #3d68e1;
|
}
|
.uploader-file-info {
|
display: none;
|
}
|
}
|
|
.up-bar {
|
height: 30px;
|
margin: 25px;
|
background: #f2f2f7;
|
border-radius: 2px;
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
box-sizing: border-box;
|
padding: 0 20px;
|
.iconfont {
|
font-size: 16px;
|
color: #333;
|
}
|
.name {
|
color: #bdbdbd;
|
font-size: 14px;
|
}
|
}
|
}
|
}
|
</style>>
|