Ant-design-vue 实现大文件分片上传
<div id="fileUpload"><a-form-item :labelCol="labelCol":wrapperCol="wrapperCol"label="文件"extra="最多5个;附件格式:pdf、word、excel、ppt、png、jpg、jpeg、...
·
<div id="fileUpload">
<a-form-item :labelCol="labelCol"
:wrapperCol="wrapperCol"
label="文件"
extra="最多5个;附件格式:pdf、word、excel、ppt、png、jpg、jpeg、
png、zip、rar文件大小不超过512MB;"
has-feedback>
<a-upload
v-decorator="['attachData',
{
valuePropName: 'fileList',
getValueFromEvent: normFile,
rules: [{ required: true, message: '请选择文件上传!'}]
}
]"
name="file"
list-type="picture"
accept=".pdf,.doc,.docx,image/jpeg,image/jpg,image/png,.xlsx,.xls,.ppt,.zip,.rar"
:beforeUpload="beforeUpload"
:remove="remove"
:data="uploadData"
@change="handleChange"
:customRequest="customRequest"
>
<a-button>
<a-icon type="upload"/>
上传申报文件
</a-button>
</a-upload>
</a-form-item>
</div>
跟上期一样只是这次的上传使用自定义的
customRequest :通过覆盖默认的上传行为,可以自定义自己的上传实现
// 自定义文件上传
customRequest (option) {
partUpload({
file: option.file,
onProgress: (num) => {
option.onProgress({ percent: num })
}
}).then(res => {
this.$message.success(`上传成功`)
}
}).catch(err => {
})
}
下面分片的方法customRequest 的方法就下的js
import _ from 'lodash'
import api from '@/api'
import {originApi} from '../api/base'
import Big from 'big.js'
import FileMd5 from './fileMd5.js'
import {Modal} from 'ant-design-vue'
// 分片上传接口
const actionUrl = 'xxxxx'//上传使用的地址
// 分片上传暂存参数
const partData = {}
// 分片上传默认参数
const defaultOption = {
downloadFlag: 1,
publicFlag: false,
totalSize: 0,
currentSize: 1024 * 1024 * 20, // 20M
appendFlag: true,
position: 0,
times: 1,
fileName: '',
objectKey: '',
chunks: [],
onProgress: (e) => {},
cancelToken: (e) => {}
}
// 获取分片上传的接口参数
const getPartFile = (tid) => {
const data = partData[tid]
const formData = new FormData()
const chunk = data.chunks[data.times - 1]
const blob = new Blob([chunk.currentBuffer], { type: 'application/octet-stream' })
formData.append('file', blob, chunk.chunkMD5)
formData.append('position', chunk.position)
formData.append('times', data.times)
formData.append('downloadFlag', data.downloadFlag)
formData.append('publicFlag', data.publicFlag)
formData.append('totalSize', data.totalSize)
formData.append('fileName', data.fileName)
formData.append('currentSize', data.currentSize)
formData.append('appendFlag', data.appendFlag)
if (data.uploadId) formData.append('uploadId', data.uploadId)
if (data.objectKey) formData.append('objectKey', data.objectKey)
return formData
}
// 上传分片文件
const uploadPart = (tid, resolve, reject) => {
const formData = getPartFile(tid)
const data = partData[tid]
originApi.post(
actionUrl,
formData,
{
onUploadProgress: (progressEvent) => {
const uploadProgress = new Big(progressEvent.loaded).div(progressEvent.total).div(data.chunks.length)
const totalComplete = new Big(data.times - 1).div(data.chunks.length).plus(uploadProgress)
const percent = new Big(totalComplete).times(100)
data.percent = parseFloat(percent)
data.onProgress(data.percent)
},
cancelToken: new api.CancelToken(function executor (c) {
data.cancelToken(c)
})
}
).then(res => {
if (res.data.code === -702) {
resolve(res || {})
Modal.error(
{
okText: '确定',
title: '提示',
mask: false,
content: res.data.message
}
)
} else if (res.data.errors && res.data.errors.length > 0) { // 接口报错时
const { title } = res.data.errors[0]
reject(new Error(title))
} else { // 接口正常时
const resData = res.data.data || {}
if (!data.objectKey) data.objectKey = resData.objectKey
if (!data.uploadId) data.uploadId = resData.uploadId
data.times++
if (data.percent >= 100) {
resolve(resData)
// 上传成功后清除已有数据,释放内存
delete partData[tid]
} else {
uploadPart(tid, resolve, reject)
}
}
}).catch(err => {
reject(err)
})
}
export default (opt) => {
const timeStampId = new Date().getTime().toString()
partData[timeStampId] = _.extend({}, defaultOption, opt)
return new Promise((resolve, reject) => {
const data = partData[timeStampId]
const file = data.file
FileMd5(file, (e, md5, chunks) => {
if (e) {
reject(new Error(e))
} else {
data.fileName = file.name
data.totalSize = file.size
data.times = 1
data.chunks = chunks
uploadPart(timeStampId, resolve, reject)
}
})
})
}
更多推荐
已为社区贡献3条内容
所有评论(0)