index.html
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
<script src="<%= BASE_URL %>static/jquery-3.4.1.min.js"></script>
<script src="<%= BASE_URL %>static/webuploader.min.js"></script>
</html>
uploader.vue
<template>
<div>
<div>
<div id="filePicker">选择文件</div>
<div class="file-panel">
<h2>文件列表</h2>
<div class="file-list">
<ul class="file-item" :class="`file-${file.id}`" v-for="file in fileList">
<li class="file-type" :icon="fileCategory(file.ext)"></li>
<li class="file-name">{{file.name}}</li>
<li class="file-size">{{fileSize(file.size)}}</li>
<li class="file-status">上传中...</li>
<li class="file-operate">
<!-- <a title="开始" @click="upload(file)"><Icon type="ios-play" /></a> -->
<!-- <a title="暂停" @click="stop(file)"><Icon type="ios-pause" /></a> -->
<a title="移除" @click="remove(file)">
<Icon type="ios-trash" size='20' />
</a>
</li>
</ul>
<div class="no-file" v-if="!fileList.length"><i class="iconfont icon-empty-file"></i> 暂无待上传文件</div>
</div>
</div>
</div>
</div>
</template>
<script>
import { getToken } from "@/libs/util";
import config from "@/config";
// import {
// deleteFile
// } from "@/api/project/file.js";
export default {
name: 'vue-upload',
props:{
uploadType: {//在内容管理里文件下载或者视频上传中用到分片上传
type: String,
default: ""
},
},
data() {
return {
timer: null,
filepath: '', //上传文件后获得的导入文件地址
fileList: [],
url: process.env.NODE_ENV === 'development' ? (config.baseUrl.dev + '/api/UpLoadService/FPUploadFile/FPUploadFile') : (config.baseUrl.pro + '/api/UpLoadService/FPUploadFile/FPUploadFile'),
uploader: null,
accept: null,
multiple: false,
fileSingleSizeLimit: 2048000,
fileNumLimit: 1,
importpercent: 0,
connection: Object,
currentStep: 0,
errorkey:''
};
},
created() {},
mounted() {
this.$nextTick(() => {
this.initWebUpload();
});
},
methods: {
initWebUpload() {
let formData={uploadType:this.uploadType,};
console.log(this.url+'=======')
this.uploader = WebUploader.create({
auto: true, // 选完文件后,是否自动上传
swf: './static/Uploader.swf', // swf文件路径
server: this.url, // 文件接收服务端
pick: "#filePicker", //this.uploadButton, // 选择文件的按钮
accept: {
title: 'All',
exteensions: 'doc,docx,xls,xlsx,ppt,pptx,pdf,txt,wps,mp4,mp3,jpg,jpeg,png,rm,avi,mpeg,ogg,dwg',
mimeTypes: '.doc,docx,.xls,.xlsx,.ppt,.pptx,.pdf,.txt,.wps,.mp4,.map3,.jpg,.jpeg,.png,.rm,.avi,.mpeg,.ogg,.dwg'
}, // 允许选择文件格式。
threads: 1,
fileNumLimit: (this.uploadType=="download")?undefined:1, // 限制上传个数
//fileSingleSizeLimit: this.fileSingleSizeLimit, // 限制单个上传图片的大小
formData: formData, // 上传所需参数
chunked: true, //分片上传
chunkSize: 2048000, //分片大小
//duplicate: true, // 重复上传
fileVal: new Date().getTime(),
resize: false,
compress:false//是否压缩图片,默认true
});
this.uploader.refresh()
// 当有文件被添加进队列的时候,添加到页面预览
this.uploader.on('fileQueued', (file) => {
if (!file.size) return;
this.fileList.push(file);
});
this.uploader.on('uploadStart', (file) => {
// 在这里可以准备好formData的数据
//this.uploader.options.formData.key = this.keyGenerator(file);
});
this.uploader.on('uploadBeforeSend', (obj,data,headers) => {
// 当某个文件的分块在发送前触发
$.extend(headers,{"Authorization": "Bearer " + getToken(),"RuntoAccessType": "Endpoint"})
// headers = {RuntoAccessType: "Endpoint"}
});
// 文件上传过程中创建进度条实时显示。
this.uploader.on('uploadProgress', (file, percent) => {
$(`.file-${file.id} .progress`).css('width', percent * 100 + '%');
$(`.file-${file.id} .file-status`).html((percent * 100).toFixed(2) + '%');
});
this.uploader.on('uploadSuccess', (file, response) => {
if(response.Code==200){
let info=response.Data[0];
let idx=this.fileList.findIndex(item=>item.name.split('.')[0]==info.FileName);
this.fileList[idx]=Object.assign({},this.fileList[idx],info)
this.$emit('upload',response.Data);
}else{
//this.$Message.error(response.Message)
this.$Notice.error({
title: '上传失败',
desc: response.Message
});
}
//this.filepath = response.data.remoteUrl
//给后台发送合并请求
});
this.uploader.on('uploadError', (file, reason) => {
this.$emit('uploadError', file, reason);
alert(this.res)
});
this.uploader.on('error', (type) => {
let errorMessage = '';
if (type === 'F_EXCEED_SIZE') {
errorMessage = `文件大小不能超过${this.fileSingleSizeLimit / (1024 * 1000)}M`;
} else if (type === 'Q_EXCEED_NUM_LIMIT') {
errorMessage = '文件上传已达到最大上限数';
} else {
errorMessage = `上传出错!请检查后重新上传!错误代码${type}`;
}
this.$emit('error', errorMessage);
});
this.uploader.on('uploadComplete', (file, response) => {
this.$emit('complete', file, response);
});
},
upload(file) {
this.uploader.upload(file);
},
/* stop(file) {
this.uploader.stop(file);
}, */
// 取消并中断文件上传
cancelFile(file) {
this.uploader.cancelFile(file);
},
// 在队列中移除文件
removeFile(file, bool) {
this.uploader.removeFile(file, bool);
},
remove(file) {
// 在ui上移除
let index = this.fileList.findIndex(ele => ele.id === file.id);
if(this.fileList[index].Id){
let id=this.fileList[index].Id;
// deleteFile({ id }).then(res => {
// if(res.data.Code==200){
// this.$Message.success("删除成功!");
// this.fileList.splice(index, 1);
// this.$emit('delete',id);
// }else{
// this.$Message.error(res.data.Message)
// }
// });
}else{
//取消并中断文件上传
this.uploader.cancelFile(file);
// 在队列中移除文件
this.uploader.removeFile(file, true);
this.fileList.splice(index, 1);
}
},
fileSize(size) {
return WebUploader.Base.formatSize(size);
},
fileCategory(ext) {
let type = '';
const typeMap = {
image: [ 'jpg', 'jpeg', 'png',"dwg"],
video: [ "mp3","rm","avi","mp4","mpeg","ogg",],
text: ['doc', 'txt', 'docx', 'pdf', 'xls', 'xlsx', 'ppt', 'pptx',"wps",]
};
Object.keys(typeMap).forEach((_type) => {
const extensions = typeMap[_type];
if (extensions.indexOf(ext) > -1) {
type = _type
}
});
return type
},
},
beforeDestroy() {
this.uploader.destroy();
},
watch: {
uploadType(val) {
this.uploader.destroy();
this.initWebUpload();
},
}
};
</script>
<style lang='less'>
@h-row: 50px;
.file-panel {
width: 840px;
margin-top: 10px;
box-shadow: 0 2px 12px 1px rgba(0, 0, 0, 0.1);
>h2 {
height: 40px;
line-height: 40px;
padding: 0 10px;
border-radius: 4px 4px 0 0;
border-bottom: 1px solid #ccc;
background-color: #fff;
}
.file-list {
position: relative;
height: 360px;
overflow-y: auto;
background-color: rgb(250, 250, 250);
}
.file-item {
position: relative;
height: @h-row;
line-height: @h-row;
padding: 0 10px;
border-bottom: 1px solid #ccc;
background-color: #fff;
z-index: 1;
>li {
display: inline-block;
}
}
.file-type {
width: 24px;
height: 24px;
vertical-align: -5px;
}
.file-name {
width: 40%;
margin-left: 10px;
}
.file-size {
width: 20%;
}
.file-status {
width: 20%;
}
.file-operate {
width: 10%;
>a {
padding: 10px 5px;
cursor: pointer;
color: #666;
&:hover {
color: #ff4081;
}
}
}
.file-type[icon=text] {
background: url(../../assets/admin/text-icon.png);
}
.file-type[icon=video] {
background: url(../../assets/admin/video-icon.png);
}
.file-type[icon=image] {
background: url(../../assets/admin/image-icon.png);
}
.progress {
position: absolute;
top: 0;
left: 0;
height: @h-row - 1;
width: 0;
background-color: #E2EDFE;
z-index: -1;
}
.no-file {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 16px;
}
}
.webuploader-container {
position: relative;
}
.webuploader-element-invisible {
position: absolute !important;
clip: rect(1px 1px 1px 1px);
/* IE6, IE7 */
clip: rect(1px, 1px, 1px, 1px);
}
.webuploader-pick {
position: relative;
display: inline-block;
cursor: pointer;
background: #00b7ee;
padding: 10px 15px;
color: #fff;
text-align: center;
border-radius: 3px;
overflow: hidden;
}
.webuploader-pick-hover {
background: #00a2d4;
}
.webuploader-pick-disable {
opacity: 0.6;
pointer-events: none;
}
.download {
margin-bottom: 10px;
}
.next {
float: right;
}
</style>
使用:
import FPUploader from "@/components/webUploader/uploader";
<FPUploader
v-if="modal.show"
style="margin-top:10px;"
uploadType="video"
/>