最近项目需求使用到大附件上传功能,图片最多5M,视频100M,结合查询到的资料决定使用webuploader上传组件,项目展示效果如下:

流程图:

1.上传前判断文件格式,项目只支持.png,.jpeg,.jpg,.mp4的视频和图片
2.图片最多5M,视频100M
3.图片可多选上传,视频每次上传一个
4.上传前获取uuid、文件名称和总文件md5判断是否重名和是否已上传过
5.已上传过时跳过上传直接进度显示99,并执行保存缩略图这一步
6.上传时显示上传进度,默认5M分片,大小超出自动分片,获取每个分片的md5
7.上传完成后执行合并操作,将所有分片md5和uuid提交与后端
8.后端验证分片个数和所有分片md5个数,合并后的文件md5和总文件md5,返回保存的附件地址url
9.获取url对应的缩略图并执行保存缩略图
template
<template>
<el-row class="webUploader">
<el-col :span="24" class="mb20" :style="{ display: 'flex' }">
<div class="upload-area" :id="'drag'" v-show="is_upload">
<div class="upload" ref="selectFile" :id="'up_single'" >
<div class="upload-icon"><i class="el-icon-upload"></i></div>
<div class="upload-desc">将文件拖到此处,或<em>点击上传</em></div>
<div class="upload-tip">支持上传jpg/png/jpeg/mp4格式文件,图片文件不能超过5M,视频文件不能超过100M。</div>
</div>
</div>
<div class="upload-area" v-show="!is_upload">
<div class="upload" >
视频素材上传中请稍后......
</div>
</div>
<el-dialog
title="提示"
:visible.sync="dialogVisible"
width="450px"
:show-close="false"
:before-close="handleClose">
<span class="model-title" slot="title">
<span class="title">上传失败</span>
<span class="close" @click="dialogVisible = false"><i class="el-icon-close"></i></span>
</span>
<div class="model">
<div class="text">素材不符合上传要求!</div>
<div class="text">支持上传jpg/png/jpeg/mp4格式文件,图片文件不能超过5M,视频文件不能超过100M。</div>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false" size="small">取 消</el-button>
<el-button type="primary" @click="dialogVisible = false" size="small">确 定</el-button>
</span>
</el-dialog>
<div class="upload-card" v-if="uploadLoading">
<div class="title">素材上传进度</div>
<div class="card-wrap">
<div class="card-item" v-for="(item,index) in value" :key="index">
<div class="file-name">
<i :icon="item.type" class="uploader-file-icon">
</i>
<div class="name"> {
{
item.fileName}}</div>
</div>
<div class="fileProgress">
<div class="bar-outer">
<div class="bar-inner" :style="{width:item.fileProgress+'%'}"></div>
</div>
{
{
item.fileProgress+'%' }}
</div>
</div>
</div>
</div>
</el-col>
</el-row>
</template>
script
<script>
//引入webuploader
import WebUploader from "webuploader";
import "webuploader/dist/webuploader.css";
import api from "@/http/api.js";
import BMF from 'browser-md5-file';
var chunkObj = {
}; //用来记录文件的状态、上传中断的位置
var md5Obj = {
};//记录文件分片后所有分片的md5
var GUID = WebUploader.Base.guid();//一个GUID
export default {
name: "uploaderList",
components: {
},
props: {
accept: {
type: [String, Object],
default: null
},
// 上传地址
url: {
type: String,
default: "/mtv_back/api/mtv-backend/sysMaterial/fileUpload",///mtv_back/api/mtv-backend/operate/upLoadFile
},
// 上传最大数量 默认为100
fileNumLimit: {
type: Number,
default: 100
},
// 大小限制 默认2M
fileSingleSizeLimit: {
type: Number,
default: 5120000
},
fileType: {
type: String,
default: "knowledge"
},
// 上传时传给后端的参数,一般为token,key等
formData: {
type: Object,
default: () => {
return {
uuid: null, code: 9,md5:null };
}
},
// 生成formData中文件的key,下面只是个例子,具体哪种形式和后端商议
keyGenerator: {
type: Function,
default: () => `${
new Date().getTime()}`
},
multiple: {
type: Boolean,
default: true
},
// 上传按钮ID
uploadButton: {
type: String,
default: ""
},
value: {
type: Array,
default: () => []
},
disabled: {
type: Boolean,
default: () => false
},
groupType:{
type: String,
default: ""
},
},
data() {
return {
uploader: null,
dialogVisible:false,
collapse:false,
panelShow:true,
uploadLoading:false,
Filesize:0,
file_type:'',//保存切换目录之前的type
is_upload:true,//是否能继续上传,视频每次只能1个,图片可以多个
fileObj:{
//上传的文件对象
}
};
},
watch: {
disabled(newVal) {
if (newVal) {
this.uploader.destroy();
return false;
}
this.initWebUpload();
},
groupType(newVal){
this.groupType = newVal;
}
},
mounted() {
if (!this.disabled) {
this.$nextTick(()=>{
console.log('初始化');
this.uploader = this.initWebUpload();
})
}
},
methods: {
handleClose(){
this.dialogVisible=false;
},
initWebUpload() {
console.log('初始化2');
// if (this.uploader) {
// this.uploader.destroy();
// }
let _this = this;
WebUploader.Uploader.register({
"before-send-file":"beforeSendFile",
"before-send": "beforeSend"
}, {
"beforeSendFile": function (file) {
// var deferred = WebUploader.Deferred();
// this.$axios.post({
// url: "/PublicInfoManage/ResourceFile/isCheckFiles",
// data: {
// seq: seq,
// fileMd5: $.md5(file.name + file.size + file.ext),
// fileName:file.name
// },
// dataType: "json",
// success: function (data) {
// console.log(data);
// chunkObj = data;
// chunkObj.type = data.type;
// chunkObj.chunk == data.chunk;
// if (data.type == 0) {
// deferred.reject();
// //$("#" + file.id).find(".state").text("文件已上传");
// } else if (data.type == 1) {
// if (data.chunk) {
// deferred.resolve();
// }
// } else {
// deferred.resolve();
// }
// },
// error: function () {
// deferred.resolve();
// }
// })
// deferred.resolve();
// return deferred.promise();
},
"beforeSend": function (block) {
//分块对象
console.log('分块11',block);
let _this = this;
console.log('分块11',_this);
if(_this.options.chunked){
var deferred = WebUploader.Deferred();
var curChunk = block.chunk;//第几个分片
var totalChunk = block.chunks;//总共几个分片
(new WebUploader.Uploader()).md5File(block.file, block.start, block.end)
.progress(function(percentage) {
console.log("正在读取文件");
})
.then(function(val) {
//block.md5 = val;
console.log("分块的md5",val);
console.log('当前的md5',_this.options.formData.md5);
// _this.options.formData.chunk = block.chunk;
// _this.options.formData.fileSize = block.file.size;//分片大小
// if(block.file.name.indexOf('.jpg')!=-1 || block.file.name.indexOf('.jpeg')!=-1){
// }else{
// }
if(md5Obj[block.file.name]){
md5Obj[block.file.name].md5List[block.chunk] = val;
}else{
md5Obj[block.file.name] = {
md5List:[],
}
md5Obj[block.file.name].md5List[block.chunk] = val;
}
//deferred.resolve();
if(chunkObj[block.file.name] && chunkObj[block.file.name].lackList){
//如果重传只传失败的
if(chunkObj[block.file.name].lackList.indexOf(val)!=-1){
//_this.options.formData.md5 = val;
_this.options.formData.chunk = block.chunk;
_this.options.formData.fileSize = block.file.size;//分片大小
deferred.resolve();
}else{
deferred.reject();//跳过此分块
}
}else{
//
//_this.options.formData.md5 = val;
_this.options.formData.chunk = block.chunk;
_this

文章详细描述了一个Vue.js项目中使用WebUploader组件实现大附件上传的过程,包括文件格式检查、分片上传、MD5校验、文件合并及错误处理。特别强调了在分片上传时如何获取每个分片的MD5值,并在上传前进行验证,确保文件完整性。
最低0.47元/天 解锁文章
1020

被折叠的 条评论
为什么被折叠?



