import OSS from 'ali-oss' import { v4 as uuidv4 } from 'uuid' class OssUploadUtils { constructor(app, callback = {}) { this.app = app // vue实例 this.client = null // ossClient this.baseFileUrl = '' // 文件上传根路径 this.callback = callback this.fileList = [] // 上传文件列表 } // 初始化oss client实例 async initOssClient() { try { const res = await this.app.$http.api.fetchOssInit() if (res.code) return const { accessKeyId, securityToken, bucket, accessKeySecret } = res.data const config = { // 以华东1(杭州)为例,Region填写为oss-cn-hangzhou。 region: 'oss-cn-shenzhen', accessKeyId, accessKeySecret, stsToken: securityToken, bucket, } this.client = new OSS(config) this.baseFileUrl = `https://${config.bucket}.${config.region}.aliyuncs.com/` setInterval(() => { this.initOssClient() }, 1000 * 60 * 60) return res } catch (error) { return error } } // 取消上传 abortMultipartUpload(abortCheckpoint) { this.client.abortMultipartUpload( abortCheckpoint.name, abortCheckpoint.uploadId ) } // 上传文件 async multipartUpload(rawFile) { if (!this.client) { await this.initOssClient() } if (rawFile.status > -1) return try { // 指定上传到examplebucket的Object名称,例如exampleobject.txt。 rawFile.bucketName = this.generateFileName(rawFile) // 分片上传 const res = await this.client.multipartUpload( rawFile.bucketName, rawFile.file, { // 获取分片上传进度、断点和返回值。 progress: (p, cpt, res) => { this.onProgress(p, cpt, res, rawFile) }, // 设置并发上传的分片数量。 parallel: 10, // 设置分片大小。默认值为1 MB,最小值为100 KB。 partSize: 1024 * 1024, // 文件类型 mime: rawFile.file.type, headers: { // 指定初始化分片上传时是否覆盖同名Object。此处设置为true,表示禁止覆盖同名Object。 'x-oss-forbid-overwrite': 'true', }, } ) this.onSuccess(res, rawFile) } catch (err) { this.onFaild(err, rawFile) console.log(err) } } // 上传文件 upload(file) { const rawfile = this.generateRawfile(file) this.fileList.push(rawfile) this.multipartUpload(rawfile) } // 上传多个文件 uploadAll(fileList) { fileList.forEach((file) => { const rawFile = this.generateRawfile(file) this.fileList.push(rawFile) this.multipartUpload(rawFile) }) } // 监听上传进度 onProgress(p, cpt, res, rawFile) { rawFile.status = 2 rawFile.percentage = Math.ceil(p * 100) rawFile.checkpoint = cpt rawFile.response = res this.callback.progress && this.callback.progress(rawFile, this.fileList) } // 监听上传成功 onSuccess(response, rawFile) { rawFile.status = 1 rawFile.response = response rawFile.url = this.baseFileUrl + response.name this.callback.success && this.callback.success(rawFile, this.fileList) } // 监听上传失败 onFaild(error, rawFile) { rawFile.response = error rawFile.status = 0 this.callback.faild && this.callback.faild(rawFile, this.fileList) } // 处理上传文件名称 generateFileName(rawfile) { const upload_dir = process.env.UPLOAD_DIR const name = upload_dir + rawfile.name.replace(/([^\\/]+)\.([^\\/]+)/i, (match, $1, $2) => { const lastName = rawfile.uuid + '.' + $2 return lastName }) return name } // 处理文件字段信息 generateRawfile(file) { return { uuid: uuidv4(), name: file.name, file: file, percentage: 0, status: -1, // 0 上次失败 1 上传成功 2 上传中 -1 待上传 url: '', response: null, checkpoint: null, } } } export default OssUploadUtils