|
@@ -1,215 +1,214 @@
|
|
|
-import request from '@/helpers/request'
|
|
|
-import { Icon, Toast, Uploader, Image } from 'vant'
|
|
|
-import { defineComponent } from 'vue'
|
|
|
-import styles from './index.module.less'
|
|
|
-import { useCustomFieldValue } from '@vant/use'
|
|
|
-import { browser } from '@/helpers/utils'
|
|
|
-import umiRequest from 'umi-request'
|
|
|
-import iconUploader from '@common/images/icon_uploader_video.png'
|
|
|
-import iconUploadPoster from '@common/images/icon_upload_poster.png'
|
|
|
-import { postMessage } from '@/helpers/native-message'
|
|
|
-import { getOssUploadUrl, state } from '@/state'
|
|
|
-
|
|
|
-export default defineComponent({
|
|
|
- name: 'ColUploadVideo',
|
|
|
- props: {
|
|
|
- modelValue: String,
|
|
|
- posterUrl: String,
|
|
|
- tips: {
|
|
|
- type: String,
|
|
|
- default: '点击上传'
|
|
|
- },
|
|
|
- nativeUpload: {
|
|
|
- // 是否使用原生上传, 且当前环境为app才会生效
|
|
|
- type: Boolean,
|
|
|
- default: true
|
|
|
- },
|
|
|
- size: {
|
|
|
- type: Number,
|
|
|
- default: 30
|
|
|
- },
|
|
|
- deletable: {
|
|
|
- type: Boolean,
|
|
|
- default: true
|
|
|
- },
|
|
|
- bucket: {
|
|
|
- type: String,
|
|
|
- default: 'daya'
|
|
|
- }
|
|
|
- },
|
|
|
- methods: {
|
|
|
- beforeRead(file: any) {
|
|
|
- const isLt2M = file.size / 1024 / 1024 < this.size
|
|
|
- // console.log(this.size)
|
|
|
- if (!isLt2M) {
|
|
|
- Toast(`上传视频大小不能超过 ${this.size}MB`)
|
|
|
- return false
|
|
|
- }
|
|
|
- return true
|
|
|
- },
|
|
|
- beforeDelete(file: any, detail: { index: any }) {
|
|
|
- // this.dataModel.splice(detail.index, 1)
|
|
|
- return true
|
|
|
- },
|
|
|
- async afterRead(file: any, detail: any) {
|
|
|
- try {
|
|
|
- file.status = 'uploading'
|
|
|
- file.message = '上传中...'
|
|
|
- // 获取签名
|
|
|
- const signUrl =
|
|
|
- state.platformType === 'TEACHER'
|
|
|
- ? '/api-teacher/getUploadSign'
|
|
|
- : '/api-student/getUploadSign'
|
|
|
-
|
|
|
- const fileName = file.file.name.replaceAll(' ', '_')
|
|
|
- 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: []
|
|
|
- }
|
|
|
- }
|
|
|
- })
|
|
|
- Toast.loading({
|
|
|
- message: '加载中...',
|
|
|
- forbidClick: true,
|
|
|
- loadingType: 'spinner',
|
|
|
- duration: 0
|
|
|
- })
|
|
|
- const obj = {
|
|
|
- policy: res.data.policy,
|
|
|
- signature: res.data.signature,
|
|
|
- key: key,
|
|
|
- KSSAccessKeyId: res.data.kssAccessKeyId,
|
|
|
- acl: 'public-read',
|
|
|
- name: fileName
|
|
|
- }
|
|
|
- let formData = new FormData()
|
|
|
- for (let key in obj) {
|
|
|
- formData.append(key, obj[key])
|
|
|
- }
|
|
|
- formData.append('file', file.file)
|
|
|
- await umiRequest(getOssUploadUrl(this.bucket), {
|
|
|
- method: 'POST',
|
|
|
- data: formData
|
|
|
- })
|
|
|
- const uploadUrl = getOssUploadUrl(this.bucket) + key
|
|
|
- Toast.clear()
|
|
|
- this.$emit('update:modelValue', uploadUrl)
|
|
|
- // this.onUploadChange(uploadUrl)
|
|
|
- // let formData = new FormData()
|
|
|
- // formData.append('file', file.file)
|
|
|
- // let res = await request.post('/api-teacher/uploadFile', {
|
|
|
- // data: formData
|
|
|
- // })
|
|
|
- // const url = res.data.url
|
|
|
- // this.$emit('update:modelValue', uploadUrl)
|
|
|
- } catch (error) {
|
|
|
- //
|
|
|
- console.log(error)
|
|
|
- }
|
|
|
- },
|
|
|
- onClose(e: any) {
|
|
|
- this.$emit('update:modelValue', null)
|
|
|
- e.stopPropagation()
|
|
|
- },
|
|
|
- onNativeUpload() {
|
|
|
- postMessage(
|
|
|
- { api: 'chooseFile', content: { type: 'video', bucket: this.bucket } },
|
|
|
- (res: any) => {
|
|
|
- // this.posterUrlInner = res.firstFrameImg
|
|
|
- this.$emit('update:modelValue', res.fileUrl)
|
|
|
- // this.$emit('update:posterUrl', res.firstFrameImg)
|
|
|
- }
|
|
|
- )
|
|
|
- },
|
|
|
- getVideoBase64(url: string) {
|
|
|
- return new Promise(function (resolve) {
|
|
|
- let dataURL = ''
|
|
|
- const video = document.createElement('video')
|
|
|
- video.setAttribute('crossOrigin', 'anonymous') // 处理跨域
|
|
|
- video.setAttribute('src', url)
|
|
|
- video.setAttribute('preload', 'auto')
|
|
|
- video.addEventListener('loadeddata', function () {
|
|
|
- console.log(video, 'video loadeddata')
|
|
|
- const canvas = document.createElement('canvas')
|
|
|
- console.log('video.clientWidth', video.videoWidth) // 视频宽
|
|
|
- console.log('video.clientHeight', video.videoHeight) // 视频高
|
|
|
- const width = video.videoWidth || 750 // canvas的尺寸和图片一样
|
|
|
- const height = video.videoHeight || 500 // 设置默认宽高为 750 * 500
|
|
|
- canvas.width = width
|
|
|
- canvas.height = height
|
|
|
- ;(canvas as any)
|
|
|
- .getContext('2d')
|
|
|
- .drawImage(video, 0, 0, width, height) // 绘制canvas
|
|
|
- dataURL = canvas.toDataURL('image/jpeg') // 转换为base64
|
|
|
- resolve(dataURL)
|
|
|
- })
|
|
|
- })
|
|
|
- }
|
|
|
- },
|
|
|
- render() {
|
|
|
- useCustomFieldValue(() => this.modelValue)
|
|
|
- return (
|
|
|
- <div class={styles['uploader-section']}>
|
|
|
- {this.modelValue && this.deletable ? (
|
|
|
- <Icon
|
|
|
- name="cross"
|
|
|
- onClick={this.onClose}
|
|
|
- class={styles['img-close']}
|
|
|
- />
|
|
|
- ) : null}
|
|
|
- {browser().isApp && this.nativeUpload ? (
|
|
|
- <div onClick={this.onNativeUpload} style={{ height: '100%' }}>
|
|
|
- {this.modelValue ? (
|
|
|
- <video
|
|
|
- ref="videoUpload"
|
|
|
- class={styles.uploadImg}
|
|
|
- src={this.modelValue + '#t=1,4'}
|
|
|
- // poster={iconUploadPoster}
|
|
|
- />
|
|
|
- ) : (
|
|
|
- <div class={styles.uploader}>
|
|
|
- <Icon name={iconUploader} size="32" />
|
|
|
- <p class={styles.uploaderText}>{this.tips}</p>
|
|
|
- </div>
|
|
|
- )}
|
|
|
- </div>
|
|
|
- ) : (
|
|
|
- <>
|
|
|
- {/* @ts-ignore */}
|
|
|
- <Uploader
|
|
|
- accept=".mp4"
|
|
|
- afterRead={this.afterRead}
|
|
|
- beforeRead={this.beforeRead}
|
|
|
- beforeDelete={this.beforeDelete}
|
|
|
- v-slots={{
|
|
|
- default: () =>
|
|
|
- this.modelValue ? (
|
|
|
- <video
|
|
|
- ref="videoUpload"
|
|
|
- class={styles.uploadImg}
|
|
|
- src={this.modelValue + '#t=1,4'}
|
|
|
- // poster={this.posterUrl || ''}
|
|
|
- />
|
|
|
- ) : (
|
|
|
- <div class={styles.uploader}>
|
|
|
- <Icon name={iconUploader} size="32" />
|
|
|
- <p class={styles.uploaderText}>{this.tips}</p>
|
|
|
- </div>
|
|
|
- )
|
|
|
- }}
|
|
|
- />
|
|
|
- </>
|
|
|
- )}
|
|
|
- </div>
|
|
|
- )
|
|
|
- }
|
|
|
-})
|
|
|
+import request from '@/helpers/request'
|
|
|
+import { Icon, Toast, Uploader, Image } from 'vant'
|
|
|
+import { defineComponent } from 'vue'
|
|
|
+import styles from './index.module.less'
|
|
|
+import { useCustomFieldValue } from '@vant/use'
|
|
|
+import { browser } from '@/helpers/utils'
|
|
|
+import umiRequest from 'umi-request'
|
|
|
+import iconUploader from '@common/images/icon_uploader_video.png'
|
|
|
+import iconUploadPoster from '@common/images/icon_upload_poster.png'
|
|
|
+import { postMessage } from '@/helpers/native-message'
|
|
|
+import { getOssUploadUrl, state } from '@/state'
|
|
|
+
|
|
|
+export default defineComponent({
|
|
|
+ name: 'ColUploadVideo',
|
|
|
+ props: {
|
|
|
+ modelValue: String,
|
|
|
+ posterUrl: String,
|
|
|
+ tips: {
|
|
|
+ type: String,
|
|
|
+ default: '点击上传'
|
|
|
+ },
|
|
|
+ nativeUpload: {
|
|
|
+ // 是否使用原生上传, 且当前环境为app才会生效
|
|
|
+ type: Boolean,
|
|
|
+ default: true
|
|
|
+ },
|
|
|
+ size: {
|
|
|
+ type: Number,
|
|
|
+ default: 30
|
|
|
+ },
|
|
|
+ deletable: {
|
|
|
+ type: Boolean,
|
|
|
+ default: true
|
|
|
+ },
|
|
|
+ bucket: {
|
|
|
+ type: String,
|
|
|
+ default: 'daya'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ beforeRead(file: any) {
|
|
|
+ const isLt2M = file.size / 1024 / 1024 < this.size
|
|
|
+ // console.log(this.size)
|
|
|
+ if (!isLt2M) {
|
|
|
+ Toast(`上传视频大小不能超过 ${this.size}MB`)
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ return true
|
|
|
+ },
|
|
|
+ beforeDelete(file: any, detail: { index: any }) {
|
|
|
+ // this.dataModel.splice(detail.index, 1)
|
|
|
+ return true
|
|
|
+ },
|
|
|
+ async afterRead(file: any, detail: any) {
|
|
|
+ try {
|
|
|
+ file.status = 'uploading'
|
|
|
+ file.message = '上传中...'
|
|
|
+ // 获取签名
|
|
|
+ const signUrl =
|
|
|
+ state.platformType === 'TEACHER'
|
|
|
+ ? '/api-teacher/getUploadSign'
|
|
|
+ : '/api-student/getUploadSign'
|
|
|
+
|
|
|
+ const fileName = file.file.name.replaceAll(' ', '_')
|
|
|
+ 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
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+ Toast.loading({
|
|
|
+ message: '加载中...',
|
|
|
+ forbidClick: true,
|
|
|
+ loadingType: 'spinner',
|
|
|
+ duration: 0
|
|
|
+ })
|
|
|
+ const obj = {
|
|
|
+ policy: res.data.policy,
|
|
|
+ signature: res.data.signature,
|
|
|
+ key: key,
|
|
|
+ KSSAccessKeyId: res.data.kssAccessKeyId,
|
|
|
+ acl: 'public-read',
|
|
|
+ name: fileName
|
|
|
+ }
|
|
|
+ const formData = new FormData()
|
|
|
+ for (const key in obj) {
|
|
|
+ formData.append(key, obj[key])
|
|
|
+ }
|
|
|
+ formData.append('file', file.file)
|
|
|
+ await umiRequest(getOssUploadUrl(this.bucket), {
|
|
|
+ method: 'POST',
|
|
|
+ data: formData
|
|
|
+ })
|
|
|
+ const uploadUrl = getOssUploadUrl(this.bucket) + key
|
|
|
+ Toast.clear()
|
|
|
+ this.$emit('update:modelValue', uploadUrl)
|
|
|
+ // this.onUploadChange(uploadUrl)
|
|
|
+ // let formData = new FormData()
|
|
|
+ // formData.append('file', file.file)
|
|
|
+ // let res = await request.post('/api-teacher/uploadFile', {
|
|
|
+ // data: formData
|
|
|
+ // })
|
|
|
+ // const url = res.data.url
|
|
|
+ // this.$emit('update:modelValue', uploadUrl)
|
|
|
+ } catch (error) {
|
|
|
+ //
|
|
|
+ console.log(error)
|
|
|
+ }
|
|
|
+ },
|
|
|
+ onClose(e: any) {
|
|
|
+ this.$emit('update:modelValue', null)
|
|
|
+ e.stopPropagation()
|
|
|
+ },
|
|
|
+ onNativeUpload() {
|
|
|
+ postMessage(
|
|
|
+ { api: 'chooseFile', content: { type: 'video', bucket: this.bucket } },
|
|
|
+ (res: any) => {
|
|
|
+ // this.posterUrlInner = res.firstFrameImg
|
|
|
+ this.$emit('update:modelValue', res.fileUrl)
|
|
|
+ // this.$emit('update:posterUrl', res.firstFrameImg)
|
|
|
+ }
|
|
|
+ )
|
|
|
+ },
|
|
|
+ getVideoBase64(url: string) {
|
|
|
+ return new Promise(function (resolve) {
|
|
|
+ let dataURL = ''
|
|
|
+ const video = document.createElement('video')
|
|
|
+ video.setAttribute('crossOrigin', 'anonymous') // 处理跨域
|
|
|
+ video.setAttribute('src', url)
|
|
|
+ video.setAttribute('preload', 'auto')
|
|
|
+ video.addEventListener('loadeddata', function () {
|
|
|
+ console.log(video, 'video loadeddata')
|
|
|
+ const canvas = document.createElement('canvas')
|
|
|
+ console.log('video.clientWidth', video.videoWidth) // 视频宽
|
|
|
+ console.log('video.clientHeight', video.videoHeight) // 视频高
|
|
|
+ const width = video.videoWidth || 750 // canvas的尺寸和图片一样
|
|
|
+ const height = video.videoHeight || 500 // 设置默认宽高为 750 * 500
|
|
|
+ canvas.width = width
|
|
|
+ canvas.height = height
|
|
|
+ ;(canvas as any)
|
|
|
+ .getContext('2d')
|
|
|
+ .drawImage(video, 0, 0, width, height) // 绘制canvas
|
|
|
+ dataURL = canvas.toDataURL('image/jpeg') // 转换为base64
|
|
|
+ resolve(dataURL)
|
|
|
+ })
|
|
|
+ })
|
|
|
+ }
|
|
|
+ },
|
|
|
+ render() {
|
|
|
+ useCustomFieldValue(() => this.modelValue)
|
|
|
+ return (
|
|
|
+ <div class={styles['uploader-section']}>
|
|
|
+ {this.modelValue && this.deletable ? (
|
|
|
+ <Icon
|
|
|
+ name="cross"
|
|
|
+ onClick={this.onClose}
|
|
|
+ class={styles['img-close']}
|
|
|
+ />
|
|
|
+ ) : null}
|
|
|
+ {browser().isApp && this.nativeUpload ? (
|
|
|
+ <div onClick={this.onNativeUpload} style={{ height: '100%' }}>
|
|
|
+ {this.modelValue ? (
|
|
|
+ <video
|
|
|
+ ref="videoUpload"
|
|
|
+ class={styles.uploadImg}
|
|
|
+ src={this.modelValue + '#t=1,4'}
|
|
|
+ // poster={iconUploadPoster}
|
|
|
+ />
|
|
|
+ ) : (
|
|
|
+ <div class={styles.uploader}>
|
|
|
+ <Icon name={iconUploader} size="32" />
|
|
|
+ <p class={styles.uploaderText}>{this.tips}</p>
|
|
|
+ </div>
|
|
|
+ )}
|
|
|
+ </div>
|
|
|
+ ) : (
|
|
|
+ <>
|
|
|
+ {/* @ts-ignore */}
|
|
|
+ <Uploader
|
|
|
+ accept=".mp4"
|
|
|
+ afterRead={this.afterRead}
|
|
|
+ beforeRead={this.beforeRead}
|
|
|
+ beforeDelete={this.beforeDelete}
|
|
|
+ v-slots={{
|
|
|
+ default: () =>
|
|
|
+ this.modelValue ? (
|
|
|
+ <video
|
|
|
+ ref="videoUpload"
|
|
|
+ class={styles.uploadImg}
|
|
|
+ src={this.modelValue + '#t=1,4'}
|
|
|
+ // poster={this.posterUrl || ''}
|
|
|
+ />
|
|
|
+ ) : (
|
|
|
+ <div class={styles.uploader}>
|
|
|
+ <Icon name={iconUploader} size="32" />
|
|
|
+ <p class={styles.uploaderText}>{this.tips}</p>
|
|
|
+ </div>
|
|
|
+ )
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ </>
|
|
|
+ )}
|
|
|
+ </div>
|
|
|
+ )
|
|
|
+ }
|
|
|
+})
|