赞
踩
1.背景: vue-simple-uploader 用于进行文件夹的上传,且项目要支持上传大文件,elementUI并不支持上传文件夹,所以使用vue-simple-uploader。
2.特点:
3.vue-simple-uploader的安装:
- import uploader from 'vue-simple-uploader';
- Vue.use(uploader);
- options: {
- target: 'http://localhost:8080', // SpringBoot后台接收文件夹数据的接口
- simultaneousUploads: 10, // 支持同时上传数量
- autoStart: false, // 自动上传
- panelShow: false,
- allowDuplicateUploads: false, // 上传过得文件不可以再上传
- testChunks: false, // 是否分片-不分片
- chunkSize: '102400000000',//块大小
- //query参数是带有数据的post的额外参数,policy、OSSAccessKeyId和signature是获取到的后端签名返回,success_action_status需设置为 200
- query: (file) => {
-
- return {
- name: file.name,
- key: file.key,
- policy,
- OSSAccessKeyId: accessId,
- signature,
- success_action_status: 200,
- };
- },
- }
4.常用的方法
fileSuccess(rootFile, file, message, chunk):完成一个特定的文件上传,rootFile是根文件夹,file是要上传的文件对象,message是服务器返回的响应信息,第四个参数' chunk '是' Uploader.Chunk '的实例;
complete():所有的文件都上传成功;
fileProgress(rootFile): 获取文件上传的进度,rootFile是所有文件;
fileError(rootFile, file, message, chunk):特定的文件上传失败,可在这个回调函数中给用户提示
5.使用:
1.DOM部分
- <template>
- <!-- 上传器 -->
- <uploader ref='uploader' :options='options' :autoStart=false :file-status-text='fileStatusText'
- @file-added='onFileAdded' @file-success='onFileSuccess' @file-removed="filesRemove" @file-error='onFileError'
- class='uploader-ui'>
- <uploader-unsupport></uploader-unsupport>
- <uploader-drop>
- <div>
- <uploader-btn id='global-uploader-btn' :attrs='attrs' ref='uploadBtn'>
- 选择文件
- <i class='el-icon-upload el-icon--right'></i>
- </uploader-btn>
- </div>
- </uploader-drop>
- <uploader-list></uploader-list>
- </uploader>
- </template>
2.script部分
- <script>
-
- export default {
-
- data() {
- return {
- options: {
- //目标上传 URL,默认POST
- target: process.env.VUE_APP_BASE_URL + '/uploader/chunk',
- //分块大小(单位:字节)
- chunkSize: '2048000',
- //上传文件时文件内容的参数名,对应chunk里的Multipart对象名,默认对象名为file
- fileParameterName: 'upfile',
- //失败后最多自动重试上传次数
- maxChunkRetries: 3,
- changeOrigin: true,
- //是否开启服务器分片校验,对应GET类型同名的target URL
- testChunks: true,
- headers: { 'Authorization': 'Bearer ' + localStorage.getItem('token') },
- /*
- 服务器分片校验函数,判断秒传及断点续传,传入的参数是Uploader.Chunk实例以及请求响应信息
- reponse码是successStatuses码时,才会进入该方法
- reponse码如果返回的是permanentErrors 中的状态码,不会进入该方法,直接进入onFileError函数 ,并显示上传失败
- reponse码是其他状态码,不会进入该方法,正常走标准上传
- checkChunkUploadedByResponse函数直接return true的话,不再调用上传接口
- */
- checkChunkUploadedByResponse: function (chunk, response_msg) {
- let objMessage = JSON.parse(response_msg);
- if (objMessage.skipUpload) {
- return true;
- }
- return (objMessage.uploadedChunks || []).indexOf(chunk.offset + 1) >= 0;
- }
- },
- attrs: {
- accept: ACCEPT_CONFIG.getAll()
- },
- fileStatusText: {
- success: '上传成功',
- error: '上传失败',
- uploading: '上传中',
- paused: '暂停',
- waiting: '等待上传'
- }
- };
- },
- methods: {
- onFileAdded(file) {
- this.computeMD5(file);
- },
- /*
- 第一个参数 rootFile 就是成功上传的文件所属的根 Uploader.File 对象,它应该包含或者等于成功上传文件;
- 第二个参数 file 就是当前成功的 Uploader.File 对象本身;
- 第三个参数就是 message 就是服务端响应内容,永远都是字符串;
- 第四个参数 chunk 就是 Uploader.Chunk 实例,它就是该文件的最后一个块实例,如果你想得到请求响应码的话,chunk.xhr.status就是
- */
- onFileSuccess(rootFile, file, response, chunk) {
- //refProjectId为预留字段,可关联附件所属目标,例如所属档案,所属工程等
- file.refProjectId = '123456789';
- console.log('::::', file);
- let data = file
- data.filename = file.name
- data.identifier = file.uniqueIdentifier
- data.totalSize = file.size
- data.alluxioPath = this.sendContent.alluxioPath
- data.userStorageId = this.sendContent.id
- console.log('file', file, data)
-
- mergeFile(data).then(res => {
- console.log('23342', res)
- console.log('父组件', this.$parent)
- // if (res.code === 415) {
- // console.log('合并操作未成功,结果码:' + res.code);
- // }
- if (res.code == 200) {
- if (this.sendContent.idArray && this.sendContent.idArray.length > 0) {
- this.sendContent.idArray.forEach((item) => {
- // this.$parent.refreshList(item)
- console.log('aaaaaaaaa',item)
- this.$emit('refresh', item)
- this.$emit('getFather')
- })
- this.$message.success(res.message)
- }
- } else {
- this.$message.error(res.message)
- }
- })
- // .catch(function (error) {
- // console.log('合并后捕获的未知异常:' + error);
- // });
- },
-
- filesRemove(file) {
- // this.$refs.uploader.pause();
- file.paused = true
- let data = file
- data.filename = file.name
- data.identifier = file.uniqueIdentifier
- data.totalSize = file.size
- data.alluxioPath = this.sendContent.alluxioPath
- data.userStorageId = this.sendContent.id
- deleteMkFile(data).then((res) => {
- console.log('delete', res)
- if (res.code == 200) {
- this.$message.success(res.msg)
- } else {
- this.$message.error(res.msg)
- }
- })
- // const uploaderInstance = this.$refs.uploader.uploader;
- // let temp = uploaderInstance.fileList.findIndex(e => e.uniqueIdentifier === file.uniqueIdentifier)
- // if (temp > -1) {
- // uploaderInstance.fileList[temp].cancel(); //这句代码是删除所选上传文件的关键
- // }
- },
-
- onFileError(rootFile, file, response, chunk) {
- console.log('上传完成后异常信息:' + response);
- },
-
- /**
- * 计算md5,实现断点续传及秒传
- * @param file
- */
- computeMD5(file) {
- file.pause();
-
- //单个文件的大小限制2G
- let fileSizeLimit = 2 * 1024 * 1024 * 1024;
- console.log('文件大小:' + file.size);
- console.log('限制大小:' + fileSizeLimit);
- console.log('alluxioPath' + this.sendContent.alluxioPath);
- // if (file.size > fileSizeLimit) {
- // this.$message({
- // showClose: true,
- // message: '文件大小不能超过2G'
- // });
- // file.cancel();
- // }
-
- 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太慢,因此采用只计算第1块文件的md5的方式
- let chunkNumberMD5 = 1;
-
- loadNext();
-
- fileReader.onload = (e => {
- spark.append(e.target.result);
-
- if (currentChunk < chunkNumberMD5) {
- loadNext();
- } else {
- let md5 = spark.end();
- file.uniqueIdentifier = md5;
- file.resume();
- console.log(`MD5计算完毕:${file.name} \nMD5:${md5} \n分片:${chunks} 大小:${file.size} 用时:${new Date().getTime() - time} ms`);
- }
- });
-
- 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));
- currentChunk++;
- console.log('计算第' + currentChunk + '块');
- }
- },
- close() {
- this.uploader.cancel();
- },
- error(msg) {
- this.$notify({
- title: '错误',
- message: msg,
- type: 'error',
- duration: 2000
- });
- }
- }
- };
- </script>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。