You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
<template> <div> <!--上传组件--> <el-upload class="upload-demo" :action="uploadUrl" :auto-upload="false" :on-change="handleChange" :before-upload="handleBeforeUpload" :on-progress="handleProgress" > <el-button slot="trigger">选取文件</el-button> <!--上传文件按钮--> <el-button style="margin-left: 10px" type="primary" :loading="uploading" :disabled="files.length === 0" @click="handleUpload"> 上传文件 </el-button> <el-progress :percentage="percent" /> </el-upload> </div> </template>
<script> import { mapGetters } from 'vuex' import axios from 'axios'
export default { data() { return { files: [], // 选中的文件列表
uploading: false, // 是否正在上传
percent: 0, // 上传进度
uploadUrl: this.baseApi + '/api/collect/uploadFiles' // 上传地址
} }, computed: { ...mapGetters([ 'baseApi' ]) }, methods: { // 切片上传
async upload(file) { const chunkSize = 1024 * 1024 // 每个块的大小为 1MB
const fileSize = file.size // 文件大小
const chunks = Math.ceil(fileSize / chunkSize) // 总块数
const tasks = [] // 上传任务数组
let uploaded = 0 // 已上传块数
// 文件切割
for (let i = 0; i < chunks; i++) { const start = i * chunkSize const end = Math.min(start + chunkSize, fileSize)
tasks.push( new Promise((resolve, reject) => { const formData = new FormData() formData.append('chunk_index', i) // 块编号
formData.append('chunk_count', chunks) // 总块数
formData.append('file_id', file.id) // 文件ID
formData.append('chunk_data', file.slice(start, end)) // 块数据
axios .post(this.uploadUrl, formData) // 上传块数据
.then(res => { uploaded++ this.percent = Math.floor((uploaded / chunks) * 100) console.log(this.percent) resolve() }) .catch(err => { reject(err) }) }) ) }
// 待所有块上传完成后,发送合并请求
await Promise.all(tasks) const res = await axios.post(this.uploadUrl, { file_id: file.id, chunks })
// 上传成功,返回文件URL
if (res.status === 200) { return `${this.uploadUrl}/${file.id}` } else { throw new Error(res.data.message) } }, handleChange(files) { this.files = files }, async handleUpload() { console.log('handleUpload') try { console.log('handleUpload2') this.uploading = true console.log(this.files) const url = await this.upload(this.files) // 文件上传成功,将url展示给用户
this.$message.success(`文件${this.files.name}上传成功!URL:${url}`) // for (let i = 0; i < this.files.length; i++) {
// const file = this.files[i]
// console.log('file', file)
// }
} catch (err) { console.log('handleUpload3') this.$message.error(`文件上传失败!${err.message}`) } finally { console.log('handleUpload4') this.uploading = false } }, handleBeforeUpload() { // TODO: 检查文件大小、类型等
}, handleProgress(event, file) { // 显示上传进度
this.percent = Math.floor((event.loaded / event.total) * 100) } } } </script>
<style lang="scss" scoped> .upload-demo{ position: relative; display: flex; justify-content: center; width: 120px; margin: 20px 0 30px 0; .el-progress{ position: absolute; left: 0; bottom: -20px; } } </style>
|