lex пре 1 година
родитељ
комит
f317e2a88a

+ 30 - 0
package-lock.json

@@ -20,6 +20,7 @@
         "browserslist": "^4.20.2",
         "classnames": "^2.3.1",
         "clean-deep": "^3.4.0",
+        "cos-js-sdk-v5": "^1.4.21",
         "cropperjs": "^1.5.12",
         "dayjs": "^1.10.7",
         "element-plus": "^2.2.5",
@@ -3708,6 +3709,14 @@
         }
       }
     },
+    "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.7.1",
       "resolved": "https://registry.npmmirror.com/acorn/-/acorn-8.7.1.tgz",
@@ -5145,6 +5154,14 @@
         "semver": "bin/semver.js"
       }
     },
+    "node_modules/cos-js-sdk-v5": {
+      "version": "1.4.21",
+      "resolved": "https://registry.npmmirror.com/cos-js-sdk-v5/-/cos-js-sdk-v5-1.4.21.tgz",
+      "integrity": "sha512-6cR53IZF2o17uaPr8XJSMa+Q73P9pgDFD5IYGcIfJn06JJaK6hGX43nv5DJ17uQYmwQBIqNeZOF97I7ClrsNdA==",
+      "dependencies": {
+        "@xmldom/xmldom": "^0.8.6"
+      }
+    },
     "node_modules/cropperjs": {
       "version": "1.5.12",
       "resolved": "https://registry.npmjs.org/cropperjs/-/cropperjs-1.5.12.tgz",
@@ -13237,6 +13254,11 @@
         "vue-demi": "*"
       }
     },
+    "@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.7.1",
       "resolved": "https://registry.npmmirror.com/acorn/-/acorn-8.7.1.tgz",
@@ -14502,6 +14524,14 @@
         }
       }
     },
+    "cos-js-sdk-v5": {
+      "version": "1.4.21",
+      "resolved": "https://registry.npmmirror.com/cos-js-sdk-v5/-/cos-js-sdk-v5-1.4.21.tgz",
+      "integrity": "sha512-6cR53IZF2o17uaPr8XJSMa+Q73P9pgDFD5IYGcIfJn06JJaK6hGX43nv5DJ17uQYmwQBIqNeZOF97I7ClrsNdA==",
+      "requires": {
+        "@xmldom/xmldom": "^0.8.6"
+      }
+    },
     "cropperjs": {
       "version": "1.5.12",
       "resolved": "https://registry.npmjs.org/cropperjs/-/cropperjs-1.5.12.tgz",

+ 1 - 0
package.json

@@ -32,6 +32,7 @@
     "browserslist": "^4.20.2",
     "classnames": "^2.3.1",
     "clean-deep": "^3.4.0",
+    "cos-js-sdk-v5": "^1.4.21",
     "cropperjs": "^1.5.12",
     "dayjs": "^1.10.7",
     "element-plus": "^2.2.5",

+ 30 - 25
src/components/col-cropper/cropper.tsx

@@ -18,6 +18,7 @@ import request from '@/helpers/request'
 
 import Cropper from 'cropperjs'
 import 'cropperjs/dist/cropper.css'
+import { getUploadSign, onOnlyFileUpload } from '@/helpers/oss-file-upload'
 export default defineComponent({
   name: 'cropper',
   props: {
@@ -98,41 +99,45 @@ export default defineComponent({
           const fileName =
             (options.name ? options.name.split('.')[0] : +new Date()) + '.png'
           try {
-            let key = new Date().getTime() + fileName
-            let obj = {
-              filename: fileName,
+            const key = new Date().getTime() + fileName
+            const obj = {
+              filename: key,
               bucketName: this.bucket,
               postData: {
-                filename: fileName,
+                filename: key,
                 acl: 'public-read',
-                key: key,
-                unknowValueField: []
+                key: key
               }
             }
-            const res = await request.post('/api-website/getUploadSign', {
-              data: obj
-            })
+            // const res = await request.post('/api-website/getUploadSign', {
+            //   data: obj
+            // })
+            const res = await getUploadSign(obj)
             this.dataObj = {
               policy: res.data.policy,
               signature: res.data.signature,
               key: key,
               KSSAccessKeyId: res.data.kssAccessKeyId,
               acl: 'public-read',
-              name: fileName
+              name: key
             }
 
-            let formData = new FormData()
-            for (let key in this.dataObj) {
-              formData.append(key, this.dataObj[key])
-            }
-            // this.blobToFile(data, fileName)
-            formData.append('file', data, fileName)
-            await umiRequest(this.ossUploadUrl, {
-              method: 'POST',
-              data: formData
+            const uploadUrl = await onOnlyFileUpload(this.ossUploadUrl, {
+              ...this.dataObj,
+              file: data
             })
-            console.log(this.ossUploadUrl + key)
-            const uploadUrl = this.ossUploadUrl + key
+            // const formData = new FormData()
+            // for (const key in this.dataObj) {
+            //   formData.append(key, this.dataObj[key])
+            // }
+            // // this.blobToFile(data, fileName)
+            // formData.append('file', data, fileName)
+            // await umiRequest(this.ossUploadUrl, {
+            //   method: 'POST',
+            //   data: formData
+            // })
+            // console.log(this.ossUploadUrl + key)
+            // const uploadUrl = this.ossUploadUrl + key
             this.cropperOk(uploadUrl)
           } catch (err: any) {
             ElMessage.error(err)
@@ -150,11 +155,11 @@ export default defineComponent({
       return Blob
     },
     base64ToFile(urlData: any, fileName: any) {
-      let arr = urlData.split(',')
-      let mime = arr[0].match(/:(.*?);/)[1]
-      let bytes = atob(arr[1]) // 解码base64
+      const arr = urlData.split(',')
+      const mime = arr[0].match(/:(.*?);/)[1]
+      const bytes = atob(arr[1]) // 解码base64
       let n = bytes.length
-      let ia = new Uint8Array(n)
+      const ia = new Uint8Array(n)
       while (n--) {
         ia[n] = bytes.charCodeAt(n)
       }

+ 69 - 32
src/components/col-upload-video/index.tsx

@@ -11,6 +11,7 @@ import { Document } from '@element-plus/icons-vue'
 import styles from './index.module.less'
 import iconVideo from './images/icon_video.png'
 import request from '@/helpers/request'
+import { getUploadSign, onOnlyFileUpload } from '@/helpers/oss-file-upload'
 
 export default defineComponent({
   name: 'col-upload-video',
@@ -72,31 +73,66 @@ export default defineComponent({
       },
       fileList: [] as any,
       tempUrls: {} as any,
+      uploadFileLength: 0, // 上传文件数量
       responseList: [] as any, // 请求成功之后的数据
       btnLoading: false,
       loading: null as any
     }
   },
   methods: {
-    handleSuccess(response: any, uploadFile: any, uploadFiles: any) {
-      this.loading?.close()
+    async handleSuccess(info: any, uploadFiles: any) {
+      // console.log(info, uploadFiles, 'uploadFiles')
+      try {
+        const obj = {
+          policy: info.data.policy,
+          signature: info.data.signature,
+          key: info.data.key,
+          KSSAccessKeyId: info.data.kssAccessKeyId,
+          acl: 'public-read',
+          name: info.data.key,
+          file: info.file
+        }
+        const url = await onOnlyFileUpload(this.ossUploadUrl, obj)
 
+        if (this.multiple) {
+          this.responseList.push(url)
+          // if (uploadFile.status === 'success') {
+          //   this.responseList.push(this.tempUrls[uploadFile.uid])
+          // }
+          // // 说明已经上传完成
+          // // console.log(uploadFiles, 'uploadFiles')
+          // // console.log(this.responseList, 'responseList')
+          if (this.uploadFileLength === this.responseList.length) {
+            this.btnLoading = false
+            this.multipleModel(this.responseList)
+            this.responseList = [] as any
+            this.fileList = [] as any
+          }
+          return this.responseList
+        } else {
+          this.$emit('update:modelValue', url)
+          return url
+        }
+      } catch {
+        //
+      }
+      this.loading?.close()
       // 多文件上传,每个文件上传成功后,将文件的url添加到fileList
-      console.log(this.fileList, 'fileList')
-      console.log(response, uploadFile, uploadFiles, 'response')
+      // console.log(this.fileList, 'fileList')
+      // console.log(response, uploadFile, uploadFiles, 'response')
       if (this.multiple) {
-        if (uploadFile.status === 'success') {
-          this.responseList.push(this.tempUrls[uploadFile.uid])
-        }
-        // 说明已经上传完成
-        // console.log(uploadFiles, 'uploadFiles')
-        // console.log(this.responseList, 'responseList')
-        if (uploadFiles.length === this.responseList.length) {
-          this.btnLoading = false
-          this.multipleModel(this.responseList)
-          this.responseList = [] as any
-          this.fileList = [] as any
-        }
+        // if (uploadFile.status === 'success') {
+        //   this.responseList.push(this.tempUrls[uploadFile.uid])
+        // }
+        // // 说明已经上传完成
+        // // console.log(uploadFiles, 'uploadFiles')
+        // // console.log(this.responseList, 'responseList')
+        // if (uploadFiles.length === this.responseList.length) {
+        //   this.btnLoading = false
+        //   this.multipleModel(this.responseList)
+        //   this.responseList = [] as any
+        //   this.fileList = [] as any
+        // }
       } else {
         const url = this.ossUploadUrl + this.dataObj.key
         this.$emit('update:modelValue', url)
@@ -105,13 +141,14 @@ export default defineComponent({
     handleRemove() {
       console.log('remove')
     },
-    handleChange() {
-      console.log('handleChange')
+    handleChange(file, fileList) {
+      // console.log('handleChange', file, fileList)
+      this.uploadFileLength = fileList.length
       // this.responseList = []
       // this.tempUrls = []
     },
     handleProgress(e) {
-      console.log('handleProgress', e)
+      // console.log('handleProgress', e)
     },
     handleError() {
       this.btnLoading = false
@@ -119,7 +156,7 @@ export default defineComponent({
     },
     async beforeUpload(file: any) {
       // beforeUpload
-      console.log(file)
+      // console.log(file)
       // let fileType = true
       // if (props.rules.type && props.rules.type.length > 0) {
       //   const fileExtension = file.name.split('.').pop().toUpperCase()
@@ -157,28 +194,28 @@ export default defineComponent({
         })
       }
       try {
-        let fileName = file.name.replaceAll(' ', '_')
-        let key = new Date().getTime() + fileName
-        let obj = {
-          filename: fileName,
+        const fileName = file.name.replaceAll(' ', '_')
+        const key = new Date().getTime() + fileName
+        const obj = {
+          filename: key,
           bucketName: this.bucket,
           postData: {
-            filename: fileName,
+            filename: key,
             acl: 'public-read',
-            key: key,
-            unknowValueField: []
+            key: key
           }
         }
-        const { data } = await request.post('/api-website/getUploadSign', {
-          data: obj
-        })
+        // const { data } = await request.post('/api-website/getUploadSign', {
+        //   data: obj
+        // })
+        const { data } = await getUploadSign(obj)
         this.dataObj = {
           policy: data.policy,
           signature: data.signature,
           key: key,
           KSSAccessKeyId: data.kssAccessKeyId,
           acl: 'public-read',
-          name: fileName
+          name: key
         }
         this.tempUrls[file.uid] = this.ossUploadUrl + this.dataObj.key
       } catch (e) {
@@ -203,7 +240,7 @@ export default defineComponent({
           disabled={this.disabled || this.btnLoading}
           action={this.ossUploadUrl}
           data={this.dataObj}
-          onSuccess={this.handleSuccess}
+          httpRequest={this.handleSuccess}
           onRemove={this.handleRemove}
           onChange={this.handleChange}
           onProgress={this.handleProgress}

+ 38 - 17
src/components/col-upload/index.tsx

@@ -4,6 +4,7 @@ import { Document } from '@element-plus/icons-vue'
 import styles from './index.module.less'
 import iconUpload from './images/icon_upload.png'
 import request from '@/helpers/request'
+import { getUploadSign, onOnlyFileUpload } from '@/helpers/oss-file-upload'
 
 export default defineComponent({
   name: 'col-upload',
@@ -62,12 +63,32 @@ export default defineComponent({
     }
   },
   methods: {
-    handleSuccess() {
+    async handleSuccess(info: any) {
+      // this.loading?.close()
+      // const url = this.ossUploadUrl + this.dataObj.key
+      // console.log(url)
+      // this.$emit('update:modelValue', url)
+      // this.onChange(url)
+
+      try {
+        const obj = {
+          policy: info.data.policy,
+          signature: info.data.signature,
+          key: info.data.key,
+          KSSAccessKeyId: info.data.kssAccessKeyId,
+          acl: 'public-read',
+          name: info.data.key,
+          file: info.file
+        }
+        const url = await onOnlyFileUpload(this.ossUploadUrl, obj)
+
+        // console.log(url)
+        this.$emit('update:modelValue', url)
+        this.onChange(url)
+      } catch {
+        //
+      }
       this.loading?.close()
-      let url = this.ossUploadUrl + this.dataObj.key
-      console.log(url)
-      this.$emit('update:modelValue', url)
-      this.onChange(url)
     },
     handleRemove() {
       console.log('remove')
@@ -118,28 +139,28 @@ export default defineComponent({
       })
       console.log(this.loading)
       try {
-        let fileName = file.name.replaceAll(' ', '_')
-        let key = new Date().getTime() + fileName
-        let obj = {
-          filename: fileName,
+        const fileName = file.name.replaceAll(' ', '_')
+        const key = new Date().getTime() + fileName
+        const obj = {
+          filename: key,
           bucketName: this.bucket,
           postData: {
-            filename: fileName,
+            filename: key,
             acl: 'public-read',
-            key: key,
-            unknowValueField: []
+            key: key
           }
         }
-        const { data } = await request.post('/api-website/getUploadSign', {
-          data: obj
-        })
+        // const { data } = await request.post('/api-website/getUploadSign', {
+        //   data: obj
+        // })
+        const { data } = await getUploadSign(obj)
         this.dataObj = {
           policy: data.policy,
           signature: data.signature,
           key: key,
           KSSAccessKeyId: data.kssAccessKeyId,
           acl: 'public-read',
-          name: fileName
+          name: key
         }
       } catch (e) {
         this.loading.close()
@@ -157,7 +178,7 @@ export default defineComponent({
           disabled={this.disabled}
           action={this.ossUploadUrl}
           data={this.dataObj}
-          onSuccess={this.handleSuccess}
+          httpRequest={this.handleSuccess}
           onRemove={this.handleRemove}
           onChange={this.handleChange}
           onProgress={this.handleProgress}

+ 11 - 4
src/components/col-video/index.tsx

@@ -11,6 +11,14 @@ export default defineComponent({
       default: () => {}
     },
     controls: Boolean,
+    preview: {
+      type: Boolean,
+      default: false
+    },
+    previewControls: {
+      type: Array,
+      default: () => ['play', 'play-large']
+    },
     height: String,
     src: {
       type: String,
@@ -76,7 +84,7 @@ export default defineComponent({
         'duration',
         'mute',
         'captions',
-        'volume',
+        'volume'
       ]
       // if (this.progress) {
       //   controls.push('progress')
@@ -85,9 +93,8 @@ export default defineComponent({
       //   controls.push('volume')
       // }
       this.player = new Plyr((this as any).$refs.video, {
-        controls: controls,
-        ...this.setting,
-
+        controls: this.preview ? this.previewControls : controls,
+        ...this.setting
       })
       // console.log(this.player.elements.container)
       // this.player.elements.container

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

@@ -0,0 +1,249 @@
+import request from './request'
+// import axios from 'axios'
+import umiRequest from 'umi-request'
+import COS from 'cos-js-sdk-v5'
+// import { state } from '@/state'
+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 = 'klx/' + filename
+
+    tempPostData = {
+      key: 'klx/' + postData.key
+    }
+  } else {
+    tempPostData = postData
+  }
+  return request.post('/api-website/open/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: `klx/${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 })
+      }
+    })
+
+    // http://daya-online-1303457149.cos.ap-nanjing.myqcloud.com/klx
+    // http://daya-online-1303457149.cos.ap-nanjing.myqcloud.com/klx
+    await cos
+      .uploadFile({
+        Bucket: tencentBucket /* 填写自己的 bucket,必须字段 */,
+        Region: 'ap-nanjing' /* 存储桶所在地域,必须字段 */,
+        Key: `klx/${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)
+    }
+  }
+}

+ 10 - 1
src/views/user-info/video-operation/course-content/index.module.less

@@ -1,16 +1,20 @@
 .courseContent {
   --el-component-size-large: 48px;
+
   :global {
+
     .el-input,
     .el-select--large,
     .el-form-item--large .el-form-item__label {
       height: 48px;
       line-height: 48px;
     }
+
     .el-form-item__label {
       font-size: 16px;
       color: rgba(0, 0, 0, 0.85);
     }
+
     .el-dialog {
       border-radius: 10px;
       overflow: hidden;
@@ -19,6 +23,7 @@
     .el-dialog__body {
       padding: 0;
     }
+
     .el-dialog__footer {
       background-color: #f6f8f9;
     }
@@ -28,6 +33,10 @@
       height: 85px;
       min-width: auto;
     }
+
+    .el-loading-mask {
+      height: 85px
+    }
   }
 
   .selectMusicAlbum {
@@ -42,4 +51,4 @@
     z-index: 99;
     right: 0;
   }
-}
+}

+ 1 - 0
src/views/user-info/video-operation/course-content/index.tsx

@@ -259,6 +259,7 @@ export default defineComponent({
                     <ColVideo
                       styleValue={{ with: '150px', height: '85px' }}
                       controls={false}
+                      preview
                       src={item.videoUrl}
                       volume={false}
                     />

+ 12 - 0
yarn.lock

@@ -1555,6 +1555,11 @@
   dependencies:
     "vue-demi" "*"
 
+"@xmldom/xmldom@^0.8.6":
+  "integrity" "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw=="
+  "resolved" "https://registry.npmmirror.com/@xmldom/xmldom/-/xmldom-0.8.10.tgz"
+  "version" "0.8.10"
+
 "acorn-jsx@^5.3.1":
   "integrity" "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng=="
   "version" "5.3.1"
@@ -2624,6 +2629,13 @@
   "resolved" "https://registry.npmmirror.com/core-js/-/core-js-3.23.3.tgz"
   "version" "3.23.3"
 
+"cos-js-sdk-v5@^1.4.21":
+  "integrity" "sha512-6cR53IZF2o17uaPr8XJSMa+Q73P9pgDFD5IYGcIfJn06JJaK6hGX43nv5DJ17uQYmwQBIqNeZOF97I7ClrsNdA=="
+  "resolved" "https://registry.npmmirror.com/cos-js-sdk-v5/-/cos-js-sdk-v5-1.4.21.tgz"
+  "version" "1.4.21"
+  dependencies:
+    "@xmldom/xmldom" "^0.8.6"
+
 "cropperjs@^1.5.12":
   "integrity" "sha512-re7UdjE5UnwdrovyhNzZ6gathI4Rs3KGCBSc8HCIjUo5hO42CtzyblmWLj6QWVw7huHyDMfpKxhiO2II77nhDw=="
   "resolved" "https://registry.npmjs.org/cropperjs/-/cropperjs-1.5.12.tgz"