展品维保小程序前端代码接口
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.

160 lines
4.2 KiB

2 weeks ago
2 weeks ago
6 days ago
2 weeks ago
6 days ago
2 weeks ago
  1. import config from '@/config'
  2. import Crypto from '@/utils/oss-upload/common/crypto/crypto.js.js'
  3. import '@/utils/oss-upload/common/crypto/hmac.js'
  4. import '@/utils/oss-upload/common/crypto/sha1.js'
  5. import { Base64 } from '@/utils/oss-upload/common/crypto/base64.js'
  6. /**
  7. * 生成随机Key
  8. */
  9. function storeKey() {
  10. let s = [];
  11. let hexDigits = "0123456789abcdef";
  12. for (let i = 0; i < 36; i++) {
  13. s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
  14. }
  15. s[14] = "4";
  16. s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1);
  17. s[8] = s[13] = s[18] = s[23] = "-";
  18. return s.join("");
  19. }
  20. /**
  21. * 生成OSS签名配置
  22. */
  23. function generateOSSConfig() {
  24. // 设置1小时后过期
  25. let date = new Date()
  26. date = date.setHours(date.getHours() + 1)
  27. let extime = "" + new Date(date).toISOString()
  28. let policyText = {
  29. "expiration": extime,
  30. "conditions": [
  31. ["content-length-range", 0, 1024 * 1024 * 100] // 设置上传文件的大小限制100MB
  32. ]
  33. };
  34. const policyBase64 = Base64.encode(JSON.stringify(policyText))
  35. // 生成签名
  36. let bytes = Crypto.HMAC(Crypto.SHA1, policyBase64, config.aliOSS_secretKey, {
  37. asBytes: true
  38. });
  39. let signature = Crypto.util.bytesToBase64(bytes);
  40. return {
  41. accessid: config.aliOSS_accessKey,
  42. // host: `https://${config.aliOSS_bucketName}.${config.endpoint}`,
  43. host: config.staticDomain,
  44. signature: signature,
  45. policyBase64: policyBase64,
  46. }
  47. }
  48. /**
  49. * OSS上传功能使用签名认证
  50. * @param {Object} file - 文件对象uni.chooseImage返回的文件
  51. * @returns {Promise<Object>} 返回上传结果
  52. */
  53. const uploadImage = async (file) => {
  54. try {
  55. // 生成OSS配置和签名
  56. const ossConfig = generateOSSConfig()
  57. // 生成唯一文件名
  58. const timestamp = Date.now()
  59. const randomStr = Math.random().toString(36).substring(2, 8)
  60. const fileExtension = getFileExtension(file.name || file.path || '.jpg')
  61. const fileName = `avatars/${timestamp}_${randomStr}${fileExtension}`
  62. const result = await uni.uploadFile({
  63. url: ossConfig.host,
  64. filePath: file.path || file.tempFilePath,
  65. name: 'file',
  66. formData: {
  67. key: fileName,
  68. policy: ossConfig.policyBase64,
  69. OSSAccessKeyId: ossConfig.accessid,
  70. success_action_status: '200',
  71. signature: ossConfig.signature,
  72. }
  73. })
  74. console.log('OSS上传结果:', result)
  75. // 检查上传是否成功
  76. if (result.errMsg && result.errMsg.includes("uploadFile:ok")) {
  77. const fileUrl = `${config.staticDomain}${fileName}`
  78. return {
  79. success: true,
  80. url: fileUrl,
  81. fileName: fileName
  82. }
  83. } else {
  84. throw new Error(`OSS上传失败,状态码: ${result.statusCode}, 错误信息: ${result.errMsg}`)
  85. }
  86. } catch (error) {
  87. console.error('OSS上传失败:', error)
  88. return {
  89. success: false,
  90. error: error.message || 'OSS上传失败'
  91. }
  92. }
  93. }
  94. /**
  95. * 获取文件扩展名
  96. */
  97. const getFileExtension = (fileName) => {
  98. if (!fileName) return '.jpg'
  99. const lastDot = fileName.lastIndexOf('.')
  100. return lastDot !== -1 ? fileName.substring(lastDot) : '.jpg'
  101. }
  102. /**
  103. * 选择并上传图片到OSS一步到位
  104. */
  105. const chooseAndUpload = async () => {
  106. try {
  107. // 选择图片
  108. const chooseResult = await uni.chooseImage({
  109. count: 1,
  110. sizeType: ['compressed'],
  111. sourceType: ['album', 'camera']
  112. })
  113. if (chooseResult.tempFilePaths && chooseResult.tempFilePaths.length > 0) {
  114. const file = {
  115. path: chooseResult.tempFilePaths[0],
  116. tempFilePath: chooseResult.tempFilePaths[0]
  117. }
  118. // 显示加载提示
  119. uni.showLoading({ title: '上传中...' })
  120. // 上传文件到OSS
  121. const uploadResult = await uploadImage(file)
  122. uni.hideLoading()
  123. if (uploadResult.success) {
  124. uni.showToast({ title: '上传成功!', icon: 'success' })
  125. return uploadResult
  126. } else {
  127. uni.showToast({ title: uploadResult.error, icon: 'error' })
  128. return null
  129. }
  130. }
  131. } catch (error) {
  132. uni.hideLoading()
  133. uni.showToast({ title: 'OSS上传失败', icon: 'error' })
  134. console.error('OSS上传失败:', error)
  135. return null
  136. }
  137. }
  138. export {
  139. uploadImage,
  140. chooseAndUpload,
  141. getFileExtension
  142. }