|
@@ -0,0 +1,151 @@
|
|
|
|
+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
|