<template>
<!--dom结构部分-->
<div id="uploader-demo" class="uploader1">
<!--用来存放item-->
<div :id="ids" class="one" style="margin-right: 10px ;width:448px">
<!-- <img :src="imgsrc" alt="" style="width:200px;height: 160px">-->
<!-- <span style="color: red;text-align: center;width: 100%;display: inline-block;"> 格式:.zip</span>-->
<div style="display: flex;align-items: center;justify-content: center;width:448px;height: 100px">
<icon-svg class="icon-file" style="width: 60px;height: 60px; font-size: 160px" icon-class="iconshangchuanwenjian" />
</div>
<div style="text-align: center;color: #1580fd;font-size: 14px;font-weight: bold;line-height: 30px"><span>{{ title }}</span></div>
<div style="text-align:center;color: red ;line-height: 30px">
<span> {{ rules }}</span>
</div>
</div>
<div style="padding: 0 20px;font-weight: bold;font-size: 16px">
已上传
</div>
<div style="flex: 1;height: 160px;overflow-y: auto" class="two">
<div class="upbox">
<div v-if="childData1.length>0" style="display:flex;flex-wrap: wrap;">
<div v-for="(item,index) in childData1" :key="index" class="file-style">
<div class="list-file">
<div style="flex: 1;display: flex;">
<icon-svg style="width: 24px;height: 24px ;margin-top: 5px;margin-left: 30px" icon-class="iconyasuowenjian" />
<TextTooltip
style="line-height:40px ;height: 40px; font-size: 16px ;margin-left: 32px"
:content="item.attachmentName"
class="wid170"
ref-name="supplierName"
/>
<!-- <span style="line-height: 32px;font-size: 16px ;margin-left: 24px"> {{ item.name }}</span>-->
</div>
<icon-svg style="width: 22px;height: 22px;margin-top: 5px;margin-right: 5px" icon-class="iconshanchu" @click.native="deleteclick(item)" />
</div>
<el-progress v-if=" Math.ceil(mumberList[index])!==100 && mumberList[index]" style="padding-left: 22px;" :stroke-width="2" :percentage="Math.ceil(mumberList[index]) " />
</div>
</div>
<!-- <div :id="'fileList'+ids" class="uploader-list" />-->
</div>
</div>
</div>
</template>
<!--引入JS-->
<script>
// <!--引入CSS-->
import '../../../public/static/lib/webuploader.css'
import $ from 'jquery'
import WebUploader from 'webuploader'
import { getRegister, getCheck, getMerge, getUploadend } from '@/api/upload/index'
import { url_config, plchc_pre_url } from '@/config/index'
import TextTooltip from '@/components/textTooltip'
import { Message } from 'element-ui'
// import store from '@/store'
export default {
name: 'VueUpload',
components: {
TextTooltip
},
props: {
accept: {
type: Object,
default: null
},
imgsrc: {
type: String,
default: ''
},
rowjdbm: {
type: String,
default: ''
},
rowcode: {
type: String,
default: ''
},
dossierData: {
type: Array,
default: function() {
return []
}
},
rowlcbm: {
type: String,
default: ''
},
// 上传地址
ids: {
type: String,
default: ''
},
// 上传最大数量 默认为100
fileNumLimit: {
type: Number,
default: 10
},
// 大小限制 默认2M
fileSingleSizeLimit: {
type: Number,
default: 2048000
},
// 上传时传给后端的参数,一般为token,key等
// formData: {
// type: Object,
// default: null
// },
// 生成formData中文件的key,下面只是个例子,具体哪种形式和后端商议
keyGenerator: {
type: Function,
default(file) {
const currentTime = new Date().getTime()
const key = `${currentTime}.${file.name}`
return key
}
},
multiple: {
type: Boolean,
default: false
},
// 上传按钮ID
uploadButton: {
type: String,
default: ''
},
title: {
type: String,
default: ''
},
rules: {
type: String,
default: ''
}
},
data() {
return {
childData1: [],
// actionUrl: `${url_config + plchc_pre_url}/file/upload`,
uploader: null,
webUploadloader: null,
mumberList: []
}
},
mounted() {
setTimeout(() => {
this.initWebUpload()
this.initDossier()
}, 300)
},
destroyed() {
WebUploader.Uploader.unRegister(this.ids)
// this.uploader.destroy()
},
methods: {
initDossier() {
if (this.dossierData) {
if (this.dossierData.length > 0) {
this.childData1 = this.dossierData.map(item => {
return {
attachmentHref: item.attachmentHref,
attachmentId: item.attachmentId,
attachmentName: item.attachmentName,
officeType: item.officeType,
batchNo: item.batchNo,
uuidName: item.uuidName
}
})
}
}
},
deleteclick(item) {
this.childData1.splice(this.childData1.findIndex(arr => arr.uuidName === item.uuidName), 1)
// this.$set(this.childData1, 0)
this.$emit('cdata', this.childData1)
},
initWebUpload() {
var dataIndex = 0
let loading
// 监听分块上传的时间点,断点续传
// let fileMd5; //保存文件MD5名称
// let uploader; //全局对象uploader
const _this = this
// this.webUploadloader = WebUploader
WebUploader.Uploader.register(
{
'before-send-file': 'beforeSendFile', // 文件上传之前执行
'before-send': 'beforeSend', // 文件块上传之前执行
'after-send-file': 'afterSendFile', // 上传完成之后执行
'name': _this.ids
},
{
// 时间点1:所有进行上传之前调用此函数
beforeSendFile: (file) => {
const file_suffix = ['zip', 'rar', 'Zip', 'RAR']
if (!file_suffix.includes(file.name.split('.').slice(-1).join())) {
this.$message.warning({
title: '上传失败',
message: '需上传文件格式为:zip, rar, Zip, RAR',
duration: 3000
})
return
}
loading = this.$loading({
lock: true,
text: '请求中...',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
})
const me = this
const task = WebUploader.Deferred()
console.log('regist', file)
// TODO 将以下属性设置到 this.uploader.options.formData ?
this.fileName = file.name
this.fileSize = file.size
this.mimeType = ('.' + file.type)
this.fileExt = file.ext;
// 计算文件的唯一标识,用于断点续传和妙传
(new WebUploader.Uploader()).md5File(file, 0,
10 * 1024 * 1024).progress(
function(percentage) {
// $("#" + file.id).find("span.state").text("正在获取文件信息...");
}).then(
function(val) {
// $("#" + file.id).find("span.state").text("成功获取文件信息");
console.log('hash', val)
me.fileHash = val
// _this.munberobj.percentageValue = 0
getRegister({
'businessKey': 'test-01',
'extraParamMap': {},
'fileExt': ('.' + file.ext),
'fileHash': val,
'fileName': file.name,
'fileSize': file.size
}).then(res => {
console.log('register', res)
if (res && res.code === 200 && !res.filePath) {
_this.childData1.push(file)
dataIndex = _this.childData1.length - 1
console.log(_this.childData1, '取值了')
task.resolve()
} else if (res && res.code === 200 && res.filePath) {
// this.childData1.splice(this.childData1.findIndex(arr => arr.id === res.id), 1)
loading.close()
Message({
message: '已有上传卷宗',
type: 'error',
duration: 3000
})
// 文件已上传
// this.onSuccess({
// fileName: this.fileName,
// resourceId: res.fileId,
// filePath: res.filePath,
// });
task.reject()
} else {
file.statusText = res && res.msg
task.reject()
}
})
me.uploader.options.formData.fileMd5 = val
})
return task.promise()
},
// 每一个分块发送之前执行该操作,检查当前块是否已经上传
beforeSend: (block) => {
const file_suffix = ['zip', 'rar', 'Zip', 'RAR']
if (!file_suffix.includes(block.file.ext.toLowerCase())) {
return
}
console.log('beforeSend')
const task = WebUploader.Deferred()
const fileHash = this.uploader.options.formData.fileMd5
const fileChunk = {
chunk: block.chunk,
chunkSize: block.end - block.start,
fileHash: fileHash
}
getCheck(fileChunk).then(res => {
console.log('checkChunk', res)
if (res && res.code === 200 && res.chunkId >= 0) {
task.reject() // 分片存在,则跳过上传
} else {
task.resolve()
}
})
this.uploader.options.formData.chunk = fileChunk.chunk
this.uploader.options.formData.chunkSize = fileChunk.chunkSize
this.uploader.options.formData.fileHash = fileHash
return task.promise()
},
afterSendFile: (file) => {
const file_suffix = ['zip', 'rar', 'Zip', 'RAR']
if (!file_suffix.includes(file.ext.toLowerCase())) {
return
}
// 通知合并分块
const task = new WebUploader.Deferred()
const fileMetaData = {
'businessKey': 'test-01',
'extraParamMap': {},
'fileExt': ('.' + file.ext),
'fileHash': this.fileHash,
'fileId': file.id,
'fileName': file.name,
'fileSize': file.size,
'mimeType': file.type
}
getMerge(fileMetaData).then(res => {
console.log(res.filePath)
const uploadfile = {
'authorization': this.$store.state.user.token,
'filePath': res.filePath,
'xtCode': this.rowcode,
'lcbm': this.rowlcbm,
'jdbm': this.rowjdbm
}
getUploadend(uploadfile).then(resdata => {
this.childData1 = this.childData1.filter(item => item.ext !== 'zip')
if (resdata) {
this.childData1 = [...this.childData1, ...[resdata]]
this.$emit('cdata', this.childData1)
this.$forceUpdate()
// this.childData1.push(resdata)
// console.log(this.childData1, '取值了')
// /
// this.$set(this.childData1, 0)
// this.$emit('cdata', this.childData1)
}
})
console.log('mergeChunks', res)
if (res && res.code === 200 && res.filePath) {
console.log('切片合并成功')
task.resolve()
// this.onSuccess({
// fileName: this.fileName,
// resourceId: res.fileId,
// filePath: res.filePath,
// });
} else {
console.log('合并文件失败')
task.reject()
// this.onError({ msg: '合并文件失败' });
}
})
}
}
)
this.uploader = WebUploader.create({
// 选完文件后,是否自动上传。
auto: true,
// swf文件路径
swf: '<%=request.getContextPath()%>/static/lib/webuploader/Uploader.swf',
// 文件接收服务端。
server: url_config + '/' + plchc_pre_url + '/v1/bigfile/upload-chunk',
// server: 'http://192.168.0.12:9201/yunpi-plchc-srv-ga/v1/bigfile/upload-chunk',
// 选择文件的按钮。可选。
// 内部根据当前运行是创建,可能是input元素,也可能是flash.
pick: document.getElementById(this.ids),
accept: this.getAccept(this.accept), // 允许选择文件格式。
threads: 3,
multiple: false,
// fileNumLimit: this.fileNumLimit, // 限制上传个数
// fileSingleSizeLimit: this.fileSingleSizeLimit, // 限制单个上传图片的大小
chunked: true, // 分片上传
chunkSize: 5242880, // 分片大小
duplicate: true, // 重复上传
formData: { // 上传分片的http请求中一同携带的数据
appid: '1',
fileHash: ''
// methodname: 'breakpointRenewal',
}
})
console.log('upload', this.uploader)
// 当有文件添加进来的时候
this.uploader.on('fileQueued', (file) => {
console.log(file, 'fileQueued')
const $li = $(
'<div id="' + file.id + '" class="file-item thumbnail">' +
'<img>' +
'<div class="info">' + file.name + '</div>' +
'</div>'
)
const $img = $li.find('img')
// $list为容器jQuery实例
$('#fileList' + this.ids).append($li)
// 创建缩略图
// 如果为非图片文件,可以不用调用此方法。
// thumbnailWidth x thumbnailHeight 为 100 x 100
this.uploader.makeThumb(file, function(error, src) {
if (error) {
$img.replaceWith('<span>不能预览</span>')
return
}
$img.attr('src', src)
}, 100, 100)
})
this.uploader.on('uploadStart', (file) => {
// 在这里可以准备好formData的数据
})
// 文件上传过程中创建进度条实时显示。
this.uploader.on('uploadProgress', function(file, percentage) {
if (file) {
_this.mumberList[dataIndex] = percentage * 100
_this.$set(_this.mumberList, dataIndex, _this.mumberList[dataIndex])
}
// const $li = $('#' + file.id)
/* let $percent = $li.find('.progress span')
// 避免重复创建
if (!$percent.length) {
$percent = $('<p class="progress"><span></span></p>')
.appendTo($li)
.find('span')
}
$percent.css('width', percentage * 100 + '%')*/
})
// 文件上传成功,给item添加成功class, 用样式标记上传成功。
this.uploader.on('uploadSuccess', function(file) {
loading.close()
})
// 文件上传失败,显示上传出错。
this.uploader.on('uploadError', function(file) {
loading.close()
/* const $li = $('#' + file.id)
let $error = $li.find('div.error')
// 避免重复创建
if (!$error.length) {
$error = $('<div class="error"></div>').appendTo($li)
}
$error.text('上传失败')*/
})
// 完成上传完了,成功或者失败,先删除进度条。
this.uploader.on('uploadComplete', function(file) {
})
this.uploader.on('uploadSuccess', (file, response) => {
})
this.uploader.on('uploadError', (file, reason) => {
})
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}`
}
console.error(errorMessage)
this.$emit('error', errorMessage)
})
this.uploader.on('uploadComplete', (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)
},
getAccept(accept) {
switch (accept) {
case 'text':
return {
title: 'Texts',
exteensions: '.zip,.rar',
mimeTypes: '.zip,.rar'
}
// eslint-disable-next-line no-unreachable
break
// case 'video':
// return {
// title: 'Videos',
// exteensions: 'mp4',
// mimeTypes: '.mp4'
// }
// // eslint-disable-next-line no-unreachable
// break
// case 'image':
// return {
// title: 'Images',
// exteensions: 'gif,jpg,jpeg,bmp,png',
// mimeTypes: '.gif,.jpg,.jpeg,.bmp,.png'
// }
// // eslint-disable-next-line no-unreachable
// break
default: return accept
}
}
}
}
</script>
<style lang="scss" scoped>
.uploader1{
display: flex;
flex-direction: row;
.one,.two{
/*width: 50%;*/
/*height: 190px;*/
/*border:1px solid #ccc;*/
// float: left;
box-sizing: border-box;
}
.upbox{
.uploader-list{
display: flex;
flex-direction: row;
overflow: auto;
.file-item{
// margin-right: 10px;
padding: 4%;
}
}
}
}
.list-file{
display: flex;
/*width: 50%;*/
/*padding: 10px 20px;*/
/*justify-content: space-around;*/
/*background-color: #f8f8f8;*/
/*background-color:#eee;*/
/*width:calc(33.3% - 10px) ;*/
/*margin-top: 10px;*/
/*margin-bottom: 10px;*/
/*margin-right: 10px;*/
justify-content: space-between;
}
.file-style{
width: calc(33.3% - 10px);
margin-right: 10px;
margin-top: 10px;
margin-bottom: 10px;
/*padding: 10px;*/
background-color: rgb(238, 238, 238);
}
// 直接把官方的css粘过来就行了
</style>
网友评论