Browse Source

添加oss上传

lex 1 year ago
parent
commit
7e400958e2

+ 37 - 14
package-lock.json

@@ -13,6 +13,7 @@
         "@vant/use": "^1.5.1",
         "@vueuse/core": "^10.1.2",
         "clean-deep": "^3.4.0",
+        "cos-js-sdk-v5": "^1.4.20",
         "dayjs": "^1.11.7",
         "echarts": "^5.4.2",
         "html2canvas": "^1.4.1",
@@ -2962,6 +2963,14 @@
         "vue-demi": ">=0.14.0"
       }
     },
+    "node_modules/@xmldom/xmldom": {
+      "version": "0.8.10",
+      "resolved": "https://registry.npmmirror.com/@xmldom/xmldom/-/xmldom-0.8.10.tgz",
+      "integrity": "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==",
+      "engines": {
+        "node": ">=10.0.0"
+      }
+    },
     "node_modules/acorn": {
       "version": "8.8.2",
       "resolved": "https://registry.npmmirror.com/acorn/-/acorn-8.8.2.tgz",
@@ -3634,6 +3643,14 @@
         "browserslist": "^4.21.5"
       }
     },
+    "node_modules/cos-js-sdk-v5": {
+      "version": "1.4.20",
+      "resolved": "https://registry.npmmirror.com/cos-js-sdk-v5/-/cos-js-sdk-v5-1.4.20.tgz",
+      "integrity": "sha512-cGpmVoKN3iYBtWo8Lwp059fOrT4yyb/+I6fVS++Zyop/ZFJswDRkjnrASViwYd8N+hi3qWVAa6ruvvBsLutEwg==",
+      "dependencies": {
+        "@xmldom/xmldom": "^0.8.6"
+      }
+    },
     "node_modules/cross-spawn": {
       "version": "7.0.3",
       "resolved": "https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.3.tgz",
@@ -10316,8 +10333,7 @@
     "@vant/use": {
       "version": "1.5.1",
       "resolved": "https://registry.npmmirror.com/@vant/use/-/use-1.5.1.tgz",
-      "integrity": "sha512-Zxd7lDz/LliVYEQi3PR9a8CQa/kGCVzF0u9hqDMaTlgXlbG0wHMFPllrcG0ThR6bfs8xrYVuSFM9pJn6HSoUGQ==",
-      "requires": {}
+      "integrity": "sha512-Zxd7lDz/LliVYEQi3PR9a8CQa/kGCVzF0u9hqDMaTlgXlbG0wHMFPllrcG0ThR6bfs8xrYVuSFM9pJn6HSoUGQ=="
     },
     "@vitejs/plugin-legacy": {
       "version": "4.0.3",
@@ -10349,8 +10365,7 @@
       "version": "4.1.0",
       "resolved": "https://registry.npmmirror.com/@vitejs/plugin-vue/-/plugin-vue-4.1.0.tgz",
       "integrity": "sha512-++9JOAFdcXI3lyer9UKUV4rfoQ3T1RN8yDqoCLar86s0xQct5yblxAE+yWgRnU5/0FOlVCpTZpYSBV/bGWrSrQ==",
-      "dev": true,
-      "requires": {}
+      "dev": true
     },
     "@vitejs/plugin-vue-jsx": {
       "version": "3.0.1",
@@ -10609,6 +10624,11 @@
         "vue-demi": ">=0.14.0"
       }
     },
+    "@xmldom/xmldom": {
+      "version": "0.8.10",
+      "resolved": "https://registry.npmmirror.com/@xmldom/xmldom/-/xmldom-0.8.10.tgz",
+      "integrity": "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw=="
+    },
     "acorn": {
       "version": "8.8.2",
       "resolved": "https://registry.npmmirror.com/acorn/-/acorn-8.8.2.tgz",
@@ -10618,8 +10638,7 @@
       "version": "5.3.2",
       "resolved": "https://registry.npmmirror.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
       "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
-      "dev": true,
-      "requires": {}
+      "dev": true
     },
     "aggregate-error": {
       "version": "3.1.0",
@@ -11157,6 +11176,14 @@
         "browserslist": "^4.21.5"
       }
     },
+    "cos-js-sdk-v5": {
+      "version": "1.4.20",
+      "resolved": "https://registry.npmmirror.com/cos-js-sdk-v5/-/cos-js-sdk-v5-1.4.20.tgz",
+      "integrity": "sha512-cGpmVoKN3iYBtWo8Lwp059fOrT4yyb/+I6fVS++Zyop/ZFJswDRkjnrASViwYd8N+hi3qWVAa6ruvvBsLutEwg==",
+      "requires": {
+        "@xmldom/xmldom": "^0.8.6"
+      }
+    },
     "cross-spawn": {
       "version": "7.0.3",
       "resolved": "https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.3.tgz",
@@ -11551,8 +11578,7 @@
       "version": "8.8.0",
       "resolved": "https://registry.npmmirror.com/eslint-config-prettier/-/eslint-config-prettier-8.8.0.tgz",
       "integrity": "sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA==",
-      "dev": true,
-      "requires": {}
+      "dev": true
     },
     "eslint-plugin-prettier": {
       "version": "4.2.1",
@@ -13601,8 +13627,7 @@
       "version": "6.0.0",
       "resolved": "https://registry.npmmirror.com/postcss-pxtorem/-/postcss-pxtorem-6.0.0.tgz",
       "integrity": "sha512-ZRXrD7MLLjLk2RNGV6UA4f5Y7gy+a/j1EqjAfp9NdcNYVjUMvg5HTYduTjSkKBkRkfqbg/iKrjMO70V4g1LZeg==",
-      "dev": true,
-      "requires": {}
+      "dev": true
     },
     "postcss-selector-parser": {
       "version": "6.0.11",
@@ -14530,14 +14555,12 @@
     "vue-awesome-swiper": {
       "version": "5.0.1",
       "resolved": "https://registry.npmmirror.com/vue-awesome-swiper/-/vue-awesome-swiper-5.0.1.tgz",
-      "integrity": "sha512-mWjFJzUqA4lG+DmsmibvMpoiBnl+IH2SSeiiQ3i5M0t1y9FknTxnGT0DsMb2YdJLgjYMEK3sYOWzqgLnZMH8Lg==",
-      "requires": {}
+      "integrity": "sha512-mWjFJzUqA4lG+DmsmibvMpoiBnl+IH2SSeiiQ3i5M0t1y9FknTxnGT0DsMb2YdJLgjYMEK3sYOWzqgLnZMH8Lg=="
     },
     "vue-demi": {
       "version": "0.14.5",
       "resolved": "https://registry.npmmirror.com/vue-demi/-/vue-demi-0.14.5.tgz",
-      "integrity": "sha512-o9NUVpl/YlsGJ7t+xuqJKx8EBGf1quRhCiT6D/J0pfwmk9zUwYkC7yrF4SZCe6fETvSM3UNL2edcbYrSyc4QHA==",
-      "requires": {}
+      "integrity": "sha512-o9NUVpl/YlsGJ7t+xuqJKx8EBGf1quRhCiT6D/J0pfwmk9zUwYkC7yrF4SZCe6fETvSM3UNL2edcbYrSyc4QHA=="
     },
     "vue-eslint-parser": {
       "version": "9.1.1",

+ 1 - 0
package.json

@@ -26,6 +26,7 @@
     "@vant/use": "^1.5.1",
     "@vueuse/core": "^10.1.2",
     "clean-deep": "^3.4.0",
+    "cos-js-sdk-v5": "^1.4.20",
     "dayjs": "^1.11.7",
     "echarts": "^5.4.2",
     "html2canvas": "^1.4.1",

+ 48 - 35
src/components/m-uploader/index.tsx

@@ -16,6 +16,7 @@ import iconUploader from '@common/images/icon-upload.png';
 import iconVideoDefault from '@common/images/icon-video-c.png';
 import request from '@/helpers/request';
 import { getOssUploadUrl } from '@/state';
+import { getUploadSign, onOnlyFileUpload } from '@/helpers/oss-file-upload';
 
 export default defineComponent({
   name: 'col-upload',
@@ -164,23 +165,34 @@ export default defineComponent({
       // 上传文件
       try {
         // 获取签名
-        const signUrl = '/api-web/getUploadSign';
+        // const signUrl = '/api-web/getUploadSign';
         const tempName = file.name || '';
-        const fileName =
-          this.path + '/' + (tempName && tempName.replace(/ /gi, '_'));
+        const fileName = this.path
+          ? this.path + '/' + (tempName && tempName.replace(/ /gi, '_'))
+          : tempName && tempName.replace(/ /gi, '_');
         const key = new Date().getTime() + fileName;
         console.log(file);
 
-        const res = await request.post(signUrl, {
-          data: {
-            filename: fileName,
-            bucketName: this.bucket,
-            postData: {
-              filename: fileName,
-              acl: 'public-read',
-              key: key,
-              unknowValueField: []
-            }
+        // const res = await request.post(signUrl, {
+        //   data: {
+        //     filename: fileName,
+        //     bucketName: this.bucket,
+        //     postData: {
+        //       filename: fileName,
+        //       acl: 'public-read',
+        //       key: key,
+        //       unknowValueField: []
+        //     }
+        //   }
+        // });
+        const { data } = await getUploadSign({
+          filename: key,
+          bucketName: this.bucket,
+          postData: {
+            filename: key,
+            acl: 'public-read',
+            key: key,
+            unknowValueField: []
           }
         });
         showLoadingToast({
@@ -190,24 +202,29 @@ export default defineComponent({
           duration: 0
         });
         const obj = {
-          policy: res.data.policy,
-          signature: res.data.signature,
+          policy: data.policy,
+          signature: data.signature,
           key: key,
-          KSSAccessKeyId: res.data.kssAccessKeyId,
+          KSSAccessKeyId: data.kssAccessKeyId,
           acl: 'public-read',
-          name: fileName
+          name: key,
+          file
         } as any;
-        const formData = new FormData();
-        for (const key in obj) {
-          formData.append(key, obj[key]);
-        }
-        formData.append('file', file, fileName);
-        await umiRequest(getOssUploadUrl(this.bucket), {
-          method: 'POST',
-          data: formData
-        });
-        console.log(getOssUploadUrl(this.bucket) + key);
-        const uploadUrl = getOssUploadUrl(this.bucket) + key;
+        // const formData = new FormData();
+        // for (const key in obj) {
+        //   formData.append(key, obj[key]);
+        // }
+        // formData.append('file', file, fileName);
+        // await umiRequest(getOssUploadUrl(this.bucket), {
+        //   method: 'POST',
+        //   data: formData
+        // });
+        // console.log(getOssUploadUrl(this.bucket) + key);
+        // const uploadUrl = getOssUploadUrl(this.bucket) + key;
+        const uploadUrl = await onOnlyFileUpload(
+          getOssUploadUrl(this.bucket),
+          obj
+        );
         closeToast();
         // 判断是否是多选
         if (this.maxCount > 1) {
@@ -241,11 +258,7 @@ export default defineComponent({
               )}
               <div class={['van-uploader__upload']}>
                 {this.uploadType === 'IMAGE' ? (
-                  <Image
-                    src={item + '@base@tag=imgScale&w=200'}
-                    class={styles.previewImg}
-                    fit="cover"
-                  />
+                  <Image src={item} class={styles.previewImg} fit="cover" />
                 ) : (
                   <video
                     ref="videoUpload"
@@ -294,7 +307,7 @@ export default defineComponent({
                           fit="cover"
                           position="center"
                           class={styles.uploadImg}
-                          src={item + '@base@tag=imgScale&w=200'}
+                          src={item}
                         />
                       ) : (
                         <video
@@ -358,7 +371,7 @@ export default defineComponent({
                         fit="cover"
                         position="center"
                         class={styles.uploadImg}
-                        src={item + '@base@tag=imgScale&w=200'}
+                        src={item}
                       />
                     ) : (
                       <video

+ 22 - 28
src/components/m-uploader/inside.tsx

@@ -16,6 +16,7 @@ import iconUploader from '@common/images/icon-upload.png';
 import iconVideoDefault from '@common/images/icon-video-c.png';
 import request from '@/helpers/request';
 import { getOssUploadUrl } from '@/state';
+import { getUploadSign, onOnlyFileUpload } from '@/helpers/oss-file-upload';
 
 export default defineComponent({
   name: 'col-upload',
@@ -163,23 +164,22 @@ export default defineComponent({
       // 上传文件
       try {
         // 获取签名
-        const signUrl = '/api-web/getUploadSign';
+        // const signUrl = '/api-web/getUploadSign';
         const tempName = file.name || '';
-        const fileName =
-          this.path + '/' + (tempName && tempName.replace(/ /gi, '_'));
+        const fileName = this.path
+          ? this.path + '/' + (tempName && tempName.replace(/ /gi, '_'))
+          : tempName && tempName.replace(/ /gi, '_');
         const key = new Date().getTime() + fileName;
         console.log(file);
 
-        const res = await request.post(signUrl, {
-          data: {
-            filename: fileName,
-            bucketName: this.bucket,
-            postData: {
-              filename: fileName,
-              acl: 'public-read',
-              key: key,
-              unknowValueField: []
-            }
+        const { data } = await getUploadSign({
+          filename: key,
+          bucketName: this.bucket,
+          postData: {
+            filename: key,
+            acl: 'public-read',
+            key: key,
+            unknowValueField: []
           }
         });
         showLoadingToast({
@@ -189,24 +189,18 @@ export default defineComponent({
           duration: 0
         });
         const obj = {
-          policy: res.data.policy,
-          signature: res.data.signature,
+          policy: data.policy,
+          signature: data.signature,
           key: key,
-          KSSAccessKeyId: res.data.kssAccessKeyId,
+          KSSAccessKeyId: data.kssAccessKeyId,
           acl: 'public-read',
-          name: fileName
+          name: key,
+          file
         } as any;
-        const formData = new FormData();
-        for (const key in obj) {
-          formData.append(key, obj[key]);
-        }
-        formData.append('file', file, fileName);
-        await umiRequest(getOssUploadUrl(this.bucket), {
-          method: 'POST',
-          data: formData
-        });
-        console.log(getOssUploadUrl(this.bucket) + key);
-        const uploadUrl = getOssUploadUrl(this.bucket) + key;
+        const uploadUrl = await onOnlyFileUpload(
+          getOssUploadUrl(this.bucket),
+          obj
+        );
         closeToast();
         // 判断是否是多选
         if (this.maxCount > 1) {

+ 246 - 0
src/helpers/oss-file-upload.ts

@@ -0,0 +1,246 @@
+import request from './request';
+// import axios from 'axios'
+import umiRequest from 'umi-request';
+import COS from 'cos-js-sdk-v5';
+export const ossSwitch = 'tencent' as 'ks3' | 'tencent'; // 上传文件服务商
+const tencentBucket = 'daya-online-1303457149';
+
+/**
+ * 管乐团 gyt/
+ * 酷乐秀 klx/
+ * 课堂乐器 ktqy/
+ * 管乐迷 gym/
+ */
+
+// 定义一个cos 对象
+/**
+ * 获取上传文件签名
+ * @param params 上传对应参数
+ * { filename: fileName,
+     bucketName: props.bucketName,
+     postData: {
+      filename: fileName,
+      acl: 'public-read',
+      key: fileName,
+      unknowValueField: []
+    }}
+ * @param oss 服务商 ks3 tencent
+ * @returns ”{'signatur'':'',''kssAccessKeyI'':'',''policy': '' }“
+ */
+export const getUploadSign = async (params: any) => {
+  const { bucketName, filename, postData } = params;
+  const ossType = ossSwitch;
+  let bucket = bucketName;
+  let file = filename;
+  // const key = postData.key;
+  let tempPostData: any = {};
+  if (ossType === 'tencent') {
+    bucket = tencentBucket;
+    file = 'gym/' + filename;
+
+    tempPostData = {
+      key: 'gym/' + postData.key
+    };
+  } else {
+    tempPostData = postData;
+  }
+  return request.post('/api-web/getUploadSign', {
+    data: {
+      postData: tempPostData,
+      pluginName: ossType,
+      bucketName: bucket,
+      filename: file
+    },
+    params: { pluginName: ossType }
+  });
+};
+
+/**
+ * 使用组件上传时,调用方法
+ * @param param0
+ */
+export const onFileUpload = ({
+  file,
+  action,
+  data,
+  onProgress,
+  onFinish,
+  onError
+}: any) => {
+  if (ossSwitch === 'ks3') {
+    const fileParams = {
+      policy: data.policy,
+      signature: data.signature,
+      key: data.key,
+      acl: 'public-read',
+      KSSAccessKeyId: data.KSSAccessKeyId,
+      name: data.name
+    } as any;
+    const formData = new FormData();
+    for (const key in fileParams) {
+      formData.append(key, fileParams[key]);
+    }
+    formData.append('file', data.file as File);
+    // axios
+    //   .post(action as string, formData, {
+    //     onUploadProgress: ({ progress }) => {
+    //       console.log(progress)
+    //       onProgress({ percent: Math.ceil((progress || 0) * 100) })
+    //     }
+    //   })
+    //   .then(() => {
+    //     file.url = action + data.key
+    //     onFinish()
+    //   })
+    //   .catch((error) => {
+    //     onError(error)
+    //   })
+    umiRequest(action as string, {
+      method: 'POST',
+      data: formData
+    })
+      .then(() => {
+        file.url = action + data.key;
+        onFinish();
+      })
+      .catch(error => {
+        onError(error);
+      });
+  } else {
+    const cos = new COS({
+      Domain: 'https://oss.dayaedu.com',
+      Protocol: 'https',
+      // getAuthorization 必选参数
+      getAuthorization: async (options, callback: any) => {
+        callback({ Authorization: data.signature });
+      }
+    });
+    cos
+      .uploadFile({
+        Bucket: tencentBucket /* 填写自己的 bucket,必须字段 */,
+        Region: 'ap-nanjing' /* 存储桶所在地域,必须字段 */,
+        Key: `gym/${data.name}`,
+        /* 存储在桶里的对象键(例如:1.jpg,a/b/test.txt,图片.jpg)支持中文,必须字段 */
+        Body: data.file.file, // 上传文件对象
+        SliceSize:
+          1024 *
+          1024 *
+          500 /* 触发分块上传的阈值,超过5MB使用分块上传,小于5MB使用简单上传。可自行设置,非必须 */,
+        onProgress: function (progressData) {
+          onProgress({ percent: Math.ceil((progressData.percent || 0) * 100) });
+        }
+      })
+      .then((res: any) => {
+        // file.url = 'https://' + res.Location;
+        if (res.Location?.indexOf('http') >= 0) {
+          file.url = res.Location;
+        } else {
+          file.url = 'https://' + res.Location;
+        }
+        onFinish();
+      })
+      .catch(error => {
+        console.log(error, 'error');
+        onError();
+      });
+  }
+};
+
+export const onOnlyFileUpload = async (action: string, params: any) => {
+  if (ossSwitch === 'ks3') {
+    const fileParams = {
+      policy: params.policy,
+      signature: params.signature,
+      key: params.key,
+      acl: 'public-read',
+      KSSAccessKeyId: params.KSSAccessKeyId,
+      name: params.name
+    } as any;
+    const formData = new FormData();
+    for (const key in fileParams) {
+      formData.append(key, fileParams[key]);
+    }
+    formData.append('file', params.file as File);
+    let file = '';
+    let errorObj: any = null;
+    // await axios
+    //   .post(action as string, formData, {
+    //     // onUploadProgress: ({ progress }) => {
+    //     //   console.log(progress);
+    //     //   onProgress({ percent: Math.ceil((progress || 0) * 100) });
+    //     // }
+    //   })
+    //   .then(() => {
+    //     file = action + params.key
+    //   })
+    //   .catch((error) => {
+    //     // onError(error);
+    //     errorObj = error
+    //     // throw new Error(error);
+    //   })
+    await umiRequest(action as string, {
+      method: 'POST',
+      data: formData
+    })
+      .then(() => {
+        file = action + params.key;
+      })
+      .catch(error => {
+        errorObj = error;
+      });
+    if (file) {
+      return file;
+    } else {
+      throw new Error(errorObj);
+    }
+    return file;
+  } else {
+    let file = '';
+    let errorObj: any = null;
+    console.log(params, 'params');
+    const cos = new COS({
+      Domain: 'https://oss.dayaedu.com',
+      // getAuthorization 必选参数
+      getAuthorization: async (options, callback: any) => {
+        callback({ Authorization: params.signature });
+      }
+    });
+
+    await cos
+      .uploadFile({
+        Bucket: tencentBucket /* 填写自己的 bucket,必须字段 */,
+        Region: 'ap-nanjing' /* 存储桶所在地域,必须字段 */,
+        Key: `gym/${params.name}`,
+        /* 存储在桶里的对象键(例如:1.jpg,a/b/test.txt,图片.jpg)支持中文,必须字段 */
+        Body: params.file, // 上传文件对象
+        SliceSize:
+          1024 *
+          1024 *
+          500 /* 触发分块上传的阈值,超过5MB使用分块上传,小于5MB使用简单上传。可自行设置,非必须 */
+        // onProgress: function (progressData) {
+        //   onProgress({ percent: Math.ceil((progressData.percent || 0) * 100) });
+        // }
+      })
+      .then((res: any) => {
+        // file.url = 'https://' + res.Location;
+        // file = 'https://' + res.Location;
+        if (res.Location?.indexOf('http') >= 0) {
+          file = res.Location;
+        } else {
+          file = 'https://' + res.Location;
+        }
+        // onFinish();
+      })
+      .catch(error => {
+        // console.log(error, 'error');
+        // onError();
+        // throw new Error(error);
+        errorObj = error;
+      });
+    if (file) {
+      return file;
+    } else {
+      throw new Error(errorObj);
+    }
+  }
+};