upload.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. import OSS from 'ali-oss'
  2. import { v4 as uuidv4 } from 'uuid'
  3. class OssUploadUtils {
  4. constructor(app, callback = {}) {
  5. this.app = app // vue实例
  6. this.client = null // ossClient
  7. this.baseFileUrl = '' // 文件上传根路径
  8. this.callback = callback
  9. this.fileList = [] // 上传文件列表
  10. }
  11. // 初始化oss client实例
  12. async initOssClient() {
  13. try {
  14. const res = await this.app.$http.api.fetchOssInit()
  15. if (res.code) return
  16. const { accessKeyId, securityToken, bucket, accessKeySecret } = res.data
  17. const config = {
  18. // 以华东1(杭州)为例,Region填写为oss-cn-hangzhou。
  19. region: 'oss-cn-shenzhen',
  20. accessKeyId,
  21. accessKeySecret,
  22. stsToken: securityToken,
  23. bucket,
  24. }
  25. this.client = new OSS(config)
  26. this.baseFileUrl = `https://${config.bucket}.${config.region}.aliyuncs.com/`
  27. setInterval(() => {
  28. this.initOssClient()
  29. }, 1000 * 60 * 60)
  30. return res
  31. } catch (error) {
  32. return error
  33. }
  34. }
  35. // 取消上传
  36. abortMultipartUpload(abortCheckpoint) {
  37. this.client.abortMultipartUpload(
  38. abortCheckpoint.name,
  39. abortCheckpoint.uploadId
  40. )
  41. }
  42. // 上传文件
  43. async multipartUpload(rawFile) {
  44. if (!this.client) {
  45. await this.initOssClient()
  46. }
  47. if (rawFile.status > -1) return
  48. try {
  49. // 指定上传到examplebucket的Object名称,例如exampleobject.txt。
  50. rawFile.bucketName = this.generateFileName(rawFile)
  51. // 分片上传
  52. const res = await this.client.multipartUpload(
  53. rawFile.bucketName,
  54. rawFile.file,
  55. {
  56. // 获取分片上传进度、断点和返回值。
  57. progress: (p, cpt, res) => {
  58. this.onProgress(p, cpt, res, rawFile)
  59. },
  60. // 设置并发上传的分片数量。
  61. parallel: 10,
  62. // 设置分片大小。默认值为1 MB,最小值为100 KB。
  63. partSize: 1024 * 1024,
  64. // 文件类型
  65. mime: rawFile.file.type,
  66. headers: {
  67. // 指定初始化分片上传时是否覆盖同名Object。此处设置为true,表示禁止覆盖同名Object。
  68. 'x-oss-forbid-overwrite': 'true',
  69. },
  70. }
  71. )
  72. this.onSuccess(res, rawFile)
  73. } catch (err) {
  74. this.onFaild(err, rawFile)
  75. console.log(err)
  76. }
  77. }
  78. // 上传文件
  79. upload(file) {
  80. const rawfile = this.generateRawfile(file)
  81. this.fileList.push(rawfile)
  82. this.multipartUpload(rawfile)
  83. }
  84. // 上传多个文件
  85. uploadAll(fileList) {
  86. fileList.forEach((file) => {
  87. const rawFile = this.generateRawfile(file)
  88. this.fileList.push(rawFile)
  89. this.multipartUpload(rawFile)
  90. })
  91. }
  92. // 监听上传进度
  93. onProgress(p, cpt, res, rawFile) {
  94. rawFile.status = 2
  95. rawFile.percentage = Math.ceil(p * 100)
  96. rawFile.checkpoint = cpt
  97. rawFile.response = res
  98. this.callback.progress && this.callback.progress(rawFile, this.fileList)
  99. }
  100. // 监听上传成功
  101. onSuccess(response, rawFile) {
  102. rawFile.status = 1
  103. rawFile.response = response
  104. rawFile.url = this.baseFileUrl + response.name
  105. this.callback.success && this.callback.success(rawFile, this.fileList)
  106. }
  107. // 监听上传失败
  108. onFaild(error, rawFile) {
  109. rawFile.response = error
  110. rawFile.status = 0
  111. this.callback.faild && this.callback.faild(rawFile, this.fileList)
  112. }
  113. // 处理上传文件名称
  114. generateFileName(rawfile) {
  115. const upload_dir = process.env.UPLOAD_DIR
  116. const name =
  117. upload_dir +
  118. rawfile.name.replace(/([^\\/]+)\.([^\\/]+)/i, (match, $1, $2) => {
  119. const lastName = rawfile.uuid + '.' + $2
  120. return lastName
  121. })
  122. return name
  123. }
  124. // 处理文件字段信息
  125. generateRawfile(file) {
  126. return {
  127. uuid: uuidv4(),
  128. name: file.name,
  129. file: file,
  130. percentage: 0,
  131. status: -1, // 0 上次失败 1 上传成功 2 上传中 -1 待上传
  132. url: '',
  133. response: null,
  134. checkpoint: null,
  135. }
  136. }
  137. }
  138. export default OssUploadUtils