AliOssUploadCo.ts 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. import { Base64Utils, RandomUtils, StringUtils } from "@imengyu/imengyu-utils";
  2. import { hmacSha1Base64 } from "./hmac";
  3. import type { UploaderAction } from "@/components/form/Uploader";
  4. import LightVillageApi from "@/api/light/LightVillageApi";
  5. const client = {
  6. region: 'oss-cn-shenzhen',
  7. accessKeyId: 'LTAI5t5e7wAQ1FvUA4LCsNs5',
  8. accessKeySecret: 'lhF0SimpatPMHNjmjtIKsWsYwTmJhx',
  9. bucket: 'minnanwenhua',
  10. };
  11. function generatePolicyAndSignature(key: string, accessKeySecret: string) {
  12. try {
  13. const expiration = new Date(Date.now() + 3600 * 1000).toISOString();
  14. const policyText = {
  15. expiration: expiration,
  16. conditions: [
  17. ["content-length-range", 0, 10485760 * 256], // 256MB限制
  18. ["starts-with", "$key", key.substring(0, key.lastIndexOf('/') + 1)]
  19. ]
  20. };
  21. const policyBase64 = Base64Utils.encode(JSON.stringify(policyText));
  22. const signature = hmacSha1(policyBase64, accessKeySecret);
  23. return {
  24. policy: policyBase64,
  25. signature: signature
  26. };
  27. } catch (error) {
  28. console.error("生成policy和signature失败:", error);
  29. throw error;
  30. }
  31. }
  32. function hmacSha1(message: string, key: string) {
  33. try {
  34. return hmacSha1Base64(message, key);
  35. } catch (error) {
  36. console.error("HMAC-SHA1签名生成失败:", error);
  37. throw error;
  38. }
  39. }
  40. function uploadOSS(uploadPath: string, filePath: string, cancelHandler: { cancel: () => void }, onProgress?: (progress: number) => void) {
  41. return new Promise<string>((resolve, reject) => {
  42. const key = uploadPath;
  43. const { policy, signature } = generatePolicyAndSignature(key, client.accessKeySecret);
  44. const formData = {
  45. key,
  46. policy: policy,
  47. OSSAccessKeyId: client.accessKeyId,
  48. signature: signature,
  49. success_action_status: '200'
  50. };
  51. const task = uni.uploadFile({
  52. url: `https://${client.bucket}.${client.region}.aliyuncs.com`,
  53. filePath,
  54. name: 'file',
  55. formData,
  56. success: res => {
  57. if (res.statusCode === 200 || res.statusCode === 204) {
  58. resolve(`https://${client.bucket}.${client.region}.aliyuncs.com/${uploadPath}`)
  59. } else {
  60. reject(new Error('上传失败' + res.statusCode))
  61. }
  62. },
  63. fail: reject,
  64. complete: () => {}
  65. })
  66. task.onProgressUpdate(({ progress }) => onProgress?.(progress));
  67. cancelHandler.cancel = () => {
  68. task.abort();
  69. };
  70. })
  71. }
  72. export function useAliOssUploadCo(subPath: string, storageManage?: {
  73. getVillageId: () => number,
  74. overflow: () => void,
  75. }) {
  76. return (action: UploaderAction) => {
  77. const cancelHandler: { cancel: () => void } = {
  78. cancel: () => {},
  79. };
  80. if (storageManage && action.item.size) {
  81. const villageId = storageManage.getVillageId();
  82. //更新存储
  83. LightVillageApi.updateStorage({
  84. villageId,
  85. memorySize: action.item.size,
  86. }).then(() => {
  87. doUpload();
  88. }).catch((err) => {
  89. if ((err + '').includes('超')) {
  90. //存储已超限
  91. storageManage.overflow();
  92. }
  93. action.onError?.(err);
  94. });
  95. } else {
  96. doUpload();
  97. }
  98. function doUpload() {
  99. const name = StringUtils.path.getFileName(action.item.filePath);
  100. const uploadPath = `${subPath}/${name.split('.')[0]}-${RandomUtils.genNonDuplicateID(26)}.${StringUtils.path.getFileExt(name)}`;
  101. uploadOSS(uploadPath, action.item.filePath, cancelHandler,(progress) => {
  102. action.onProgress?.(progress)
  103. }).then((res) => {
  104. action.onFinish?.({
  105. uploadedUrl: res,
  106. previewUrl: res,
  107. });
  108. }).catch((err) => {
  109. action.onError?.(err);
  110. });
  111. }
  112. return () => {
  113. //取消上传
  114. cancelHandler.cancel();
  115. };
  116. }
  117. }