AliOssUploadCo.ts 3.2 KB

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