| | |
| | | <template>
|
| | | <div class="file-uploader">
|
| | | <uploader
|
| | | v-if="single"
|
| | | ref="uploader"
|
| | | :options="options"
|
| | | :file-status-text="statusText"
|
| | | class="uploader-single"
|
| | | :sourceType="sourceType"
|
| | | @file-added="onFileAdded"
|
| | | @complete="onComplete"
|
| | | >
|
| | | <div class="up-bar" v-if="isDrag == true">
|
| | | <div class="name">{{ fileName || uploadPlaceholder }}</div>
|
| | | <uploader-btn slot="suffix" :attrs="attrs">
|
| | | <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>
|
| | | <el-input
|
| | | :placeholder="uploadPlaceholder"
|
| | | v-if="isDrag == false"
|
| | | size="small"
|
| | | :readonly="true"
|
| | | v-model="fileName"
|
| | | >
|
| | | <uploader-btn slot="suffix" :attrs="attrs">
|
| | | <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: "",shouldStop:false,
|
| | | 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.sourceType == 3) {
|
| | | // if (
|
| | | // !file.name.endsWith(".tar") ||
|
| | | // !file.name.endsWith(".gz") ||
|
| | | // !file.name.endsWith(".tar.gz")
|
| | | // ) {
|
| | | // this.shouldStop = true
|
| | | // this.$notify.warning("仅支持.tar/.gz/.tar.gz三种格式文件");
|
| | | // return
|
| | | // }
|
| | | // }
|
| | | 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() {
|
| | | if (this.shouldStop) {
|
| | | return
|
| | | }
|
| | | 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;
|
| | | 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>>
|
| | | <template> |
| | | <div class="file-uploader"> |
| | | <uploader |
| | | v-if="single" |
| | | ref="uploader" |
| | | :options="options" |
| | | :file-status-text="statusText" |
| | | class="uploader-single" |
| | | :sourceType="sourceType" |
| | | @file-added="onFileAdded" |
| | | @complete="onComplete" |
| | | > |
| | | <div class="up-bar" v-if="isDrag == true"> |
| | | <div class="name">{{ fileName || uploadPlaceholder }}</div> |
| | | <uploader-btn slot="suffix" :attrs="attrs"> |
| | | <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> |
| | | <el-input |
| | | :placeholder="uploadPlaceholder" |
| | | v-if="isDrag == false" |
| | | size="small" |
| | | :readonly="true" |
| | | v-model="fileName" |
| | | > |
| | | <uploader-btn slot="suffix" :attrs="attrs"> |
| | | <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: "",shouldStop:false, |
| | | 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.sourceType == 3) { |
| | | // if ( |
| | | // !file.name.endsWith(".tar") || |
| | | // !file.name.endsWith(".gz") || |
| | | // !file.name.endsWith(".tar.gz") |
| | | // ) { |
| | | // this.shouldStop = true |
| | | // this.$notify.warning("仅支持.tar/.gz/.tar.gz三种格式文件"); |
| | | // return |
| | | // } |
| | | // } |
| | | 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() { |
| | | if (this.shouldStop) { |
| | | return |
| | | } |
| | | 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; |
| | | 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>> |