|
@@ -1,474 +1,474 @@
|
|
|
-import { PropType, computed, defineComponent, reactive, ref } from 'vue';
|
|
|
-import styles from './index.module.less';
|
|
|
-import {
|
|
|
- NButton,
|
|
|
- NSpace,
|
|
|
- NUpload,
|
|
|
- NUploadDragger,
|
|
|
- UploadCustomRequestOptions,
|
|
|
- UploadFileInfo,
|
|
|
- useMessage
|
|
|
-} from 'naive-ui';
|
|
|
-// import iconUploadAdd from '../../../images/icon-upload-add.png';
|
|
|
-import { NaturalTypeEnum, PageEnum } from '/src/enums/pageEnum';
|
|
|
-// import { policy } from '/src/components/upload-file/api';
|
|
|
-import { formatUrlType } from '../upload-modal';
|
|
|
-// import axios from 'axios';
|
|
|
-import {
|
|
|
- getUploadSign,
|
|
|
- onFileUpload,
|
|
|
- onOnlyFileUpload
|
|
|
- // ossSwitch
|
|
|
-} from '/src/helpers/oss-file-upload';
|
|
|
-
|
|
|
-export default defineComponent({
|
|
|
- name: 'save-modal',
|
|
|
- props: {
|
|
|
- fileList: {
|
|
|
- type: String,
|
|
|
- default: ''
|
|
|
- },
|
|
|
- imageList: {
|
|
|
- type: Array,
|
|
|
- default: () => []
|
|
|
- },
|
|
|
- accept: {
|
|
|
- // 支持类型
|
|
|
- type: String,
|
|
|
- default: '.jpg,.png,.jpeg,.gif'
|
|
|
- },
|
|
|
- showType: {
|
|
|
- type: String as PropType<'default' | 'custom'>,
|
|
|
- default: 'default'
|
|
|
- },
|
|
|
- showFileList: {
|
|
|
- type: Boolean,
|
|
|
- default: true
|
|
|
- },
|
|
|
- max: {
|
|
|
- type: Number as PropType<number>,
|
|
|
- default: 1
|
|
|
- },
|
|
|
- multiple: {
|
|
|
- type: Boolean as PropType<boolean>,
|
|
|
- default: false
|
|
|
- },
|
|
|
- disabled: {
|
|
|
- type: Boolean as PropType<boolean>,
|
|
|
- default: false
|
|
|
- },
|
|
|
- bucketName: {
|
|
|
- type: String,
|
|
|
- default: 'gyt'
|
|
|
- },
|
|
|
- directoryDnd: {
|
|
|
- type: Boolean as PropType<boolean>,
|
|
|
- default: false
|
|
|
- },
|
|
|
- path: {
|
|
|
- type: String,
|
|
|
- default: ''
|
|
|
- },
|
|
|
- fileName: {
|
|
|
- type: String,
|
|
|
- default: ''
|
|
|
- }
|
|
|
- },
|
|
|
- emits: ['close', 'confrim'],
|
|
|
- setup(props, { emit }) {
|
|
|
- const ossUploadUrl = `https://${props.bucketName}.ks3-cn-beijing.ksyuncs.com/`;
|
|
|
- const message = useMessage();
|
|
|
- const visiable = ref<boolean>(false);
|
|
|
- const btnLoading = ref<boolean>(false);
|
|
|
- const tempFiileBuffer = ref();
|
|
|
- const uploadRef = ref();
|
|
|
- const state = reactive([]) as any;
|
|
|
-
|
|
|
- const fileListRef = ref<UploadFileInfo[]>([]);
|
|
|
- const uploadList = ref([] as any);
|
|
|
-
|
|
|
- // 获取文件后缀名
|
|
|
- function getFileExtension(filename: string) {
|
|
|
- return filename.slice(((filename.lastIndexOf('.') - 1) >>> 0) + 2);
|
|
|
- }
|
|
|
-
|
|
|
- // 判断是否是允许的文件类型
|
|
|
- function isAllowedFileType(filename: string, allowedExtensions: any) {
|
|
|
- const extension = getFileExtension(filename).toLowerCase();
|
|
|
- return allowedExtensions.includes(extension);
|
|
|
- }
|
|
|
-
|
|
|
- const onBeforeUpload = async (options: any) => {
|
|
|
- const file = options.file;
|
|
|
- // 文件大小
|
|
|
- let isLt2M = true;
|
|
|
-
|
|
|
- const allowedExtensions = [
|
|
|
- 'jpg',
|
|
|
- 'jpeg',
|
|
|
- 'png',
|
|
|
- 'mp4',
|
|
|
- // 'ppt',
|
|
|
- // 'pptx',
|
|
|
- 'mp3'
|
|
|
- ];
|
|
|
- if (!isAllowedFileType(file.file.name, allowedExtensions)) {
|
|
|
- message.error('文件格式不支持');
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- const type = file.type.includes('image')
|
|
|
- ? NaturalTypeEnum.IMG
|
|
|
- : file.type.includes('audio')
|
|
|
- ? NaturalTypeEnum.SONG
|
|
|
- : file.type.includes('video')
|
|
|
- ? NaturalTypeEnum.VIDEO
|
|
|
- : file.type.includes(
|
|
|
- 'vnd.openxmlformats-officedocument.presentationml.presentation'
|
|
|
- ) || file.type.includes('vnd.ms-powerpoint')
|
|
|
- ? NaturalTypeEnum.PPT
|
|
|
- : 'other';
|
|
|
-
|
|
|
- if (type === 'other') {
|
|
|
- message.error(`文件格式不支持`);
|
|
|
- return false;
|
|
|
- }
|
|
|
- const size = type === 'IMG' ? 2 : type === 'SONG' ? 20 : 500;
|
|
|
- if (size) {
|
|
|
- isLt2M = file.file.size / 1024 / 1024 < size;
|
|
|
- if (!isLt2M) {
|
|
|
- const typeStr =
|
|
|
- type === 'IMG' ? '图片' : type === 'SONG' ? '音频' : '视频';
|
|
|
- message.error(`${typeStr}大小不能超过${size}M`);
|
|
|
- return false;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (!isLt2M) {
|
|
|
- return isLt2M;
|
|
|
- }
|
|
|
- // 是否裁切
|
|
|
- // if (props.cropper && type === 'IMG') {
|
|
|
- // getBase64(file.file, (imageUrl: any) => {
|
|
|
- // const target = Object.assign({}, props.options, {
|
|
|
- // img: imageUrl,
|
|
|
- // name: file.file.name // 上传文件名
|
|
|
- // });
|
|
|
- // visiable.value = true;
|
|
|
-
|
|
|
- // setTimeout(() => {
|
|
|
- // CropperModal.value?.edit(target);
|
|
|
- // }, 100);
|
|
|
- // });
|
|
|
- // return false;
|
|
|
- // }
|
|
|
-
|
|
|
- try {
|
|
|
- btnLoading.value = true;
|
|
|
- const name = file.file.name;
|
|
|
- const suffix = name.slice(name.lastIndexOf('.'));
|
|
|
- const fileName = `${props.path}${Date.now() + file.id + suffix}`;
|
|
|
- const obj = {
|
|
|
- filename: fileName,
|
|
|
- bucketName: props.bucketName,
|
|
|
- postData: {
|
|
|
- filename: fileName,
|
|
|
- acl: 'public-read',
|
|
|
- key: fileName,
|
|
|
- unknowValueField: []
|
|
|
- }
|
|
|
- };
|
|
|
- // const { data } = await policy(obj);
|
|
|
- const { data } = await getUploadSign(obj);
|
|
|
- state.push({
|
|
|
- id: file.id,
|
|
|
- tempFiileBuffer: file.file,
|
|
|
- policy: data.policy,
|
|
|
- signature: data.signature,
|
|
|
- acl: 'public-read',
|
|
|
- key: fileName,
|
|
|
- KSSAccessKeyId: data.kssAccessKeyId,
|
|
|
- name: fileName
|
|
|
- });
|
|
|
- } catch {
|
|
|
- //
|
|
|
- // message.error('上传失败')
|
|
|
- btnLoading.value = false;
|
|
|
- return false;
|
|
|
- }
|
|
|
- return true;
|
|
|
- };
|
|
|
- // const getBase64 = async (img: any, callback: any) => {
|
|
|
- // const reader = new FileReader();
|
|
|
- // reader.addEventListener('load', () => callback(reader.result));
|
|
|
- // reader.readAsDataURL(img);
|
|
|
- // };
|
|
|
-
|
|
|
- const onFinish = (options: any) => {
|
|
|
- onFinishAfter(options);
|
|
|
- };
|
|
|
- const onFinishAfter = async (options: any) => {
|
|
|
- console.log(options, 'onFinishAfter');
|
|
|
- const item = state.find((c: any) => c.id == options.file.id);
|
|
|
- const type = formatUrlType(options.file.url);
|
|
|
- let coverImg = '';
|
|
|
- if (type === 'IMG') {
|
|
|
- coverImg = options.file.url;
|
|
|
- } else if (type === 'SONG') {
|
|
|
- coverImg = PageEnum.SONG_DEFAULT_COVER;
|
|
|
- } else if (type === 'PPT') {
|
|
|
- coverImg = PageEnum.PPT_DEFAULT_COVER;
|
|
|
- } else if (type === 'VIDEO') {
|
|
|
- // 获取视频封面图
|
|
|
- coverImg = await getVideoCoverImg(item.tempFiileBuffer);
|
|
|
- }
|
|
|
-
|
|
|
- uploadList.value.push({
|
|
|
- coverImg,
|
|
|
- content: options.file.url,
|
|
|
- id: options.file.id,
|
|
|
- name: options.file.name
|
|
|
- ? options.file.name.slice(0, options.file.name.lastIndexOf('.'))
|
|
|
- : ''
|
|
|
- });
|
|
|
-
|
|
|
- visiable.value = false;
|
|
|
- btnLoading.value = false;
|
|
|
- };
|
|
|
- const getVideoMsg = (file: any) => {
|
|
|
- return new Promise((resolve, reject) => {
|
|
|
- // let dataURL = '';
|
|
|
- const videoElement = document.createElement('video');
|
|
|
- videoElement.setAttribute('crossOrigin', 'Anonymous'); // 处理跨域
|
|
|
- videoElement.setAttribute('preload', 'auto'); // auto|metadata|none
|
|
|
- videoElement.muted = true;
|
|
|
- videoElement.autoplay = true;
|
|
|
- videoElement.src = URL.createObjectURL(file);
|
|
|
- // Listen for 'canplay' to ensure the video is ready for frame capture
|
|
|
- videoElement.addEventListener('loadedmetadata', () => {
|
|
|
- // 这里开始播放
|
|
|
- videoElement.play();
|
|
|
- setTimeout(() => {
|
|
|
- // 过500ms 暂停, 解决空白问题
|
|
|
- videoElement.currentTime = 0;
|
|
|
- videoElement.pause();
|
|
|
- // 创建canvas元素
|
|
|
- const canvas: any = document.createElement('canvas');
|
|
|
- canvas.width = videoElement.videoWidth;
|
|
|
- canvas.height = videoElement.videoHeight;
|
|
|
-
|
|
|
- // 将视频帧绘制到canvas上
|
|
|
- // const ctx = canvas.getContext('2d');
|
|
|
-
|
|
|
- // console.log(videoElement);
|
|
|
- // ctx.drawImage(videoElement, 0, 0, canvas.width, canvas.height);
|
|
|
- canvas
|
|
|
- .getContext('2d')
|
|
|
- .drawImage(videoElement, 0, 0, canvas.width, canvas.height);
|
|
|
-
|
|
|
- // 将canvas图像转换为base64格式的数据URI
|
|
|
- // const dataUrl = canvas.toDataURL('image/png');
|
|
|
- // 返回base64格式的数据URI
|
|
|
- // resolve(dataUrl);
|
|
|
- canvas.toBlob((blob: any) => {
|
|
|
- resolve(blob);
|
|
|
- });
|
|
|
- }, 500);
|
|
|
- });
|
|
|
-
|
|
|
- // 如果视频加载出错,则返回错误信息
|
|
|
- videoElement.addEventListener('error', (e: any) => {
|
|
|
- reject(e);
|
|
|
- });
|
|
|
- // return new Promise((resolve, reject) => {
|
|
|
- // videoElement.addEventListener('loadedmetadata', () => {
|
|
|
- // // 这里开始播放
|
|
|
- // videoElement.play()
|
|
|
- // setTimeout(() => {
|
|
|
- // // 过500ms 暂停, 解决空白问题
|
|
|
- // videoElement.pause()
|
|
|
- // // 创建canvas元素
|
|
|
- // const canvas = document.createElement('canvas');
|
|
|
- // canvas.width = videoElement.videoWidth;
|
|
|
- // canvas.height = videoElement.videoHeight;
|
|
|
-
|
|
|
- // // 将视频帧绘制到canvas上
|
|
|
- // const ctx = canvas.getContext('2d');
|
|
|
-
|
|
|
- // console.log(videoElement);
|
|
|
- // ctx.drawImage(videoElement, 0, 0, canvas.width, canvas.height);
|
|
|
-
|
|
|
- // // 将canvas图像转换为base64格式的数据URI
|
|
|
- // const dataUrl = canvas.toDataURL('image/png');
|
|
|
- // console.log(dataUrl);
|
|
|
- // thumbnail.src = dataUrl;
|
|
|
- // thumbnail.style.display = 'inline';
|
|
|
- // // 返回base64格式的数据URI
|
|
|
- // resolve(dataUrl);
|
|
|
- // }, 500);
|
|
|
- // });
|
|
|
-
|
|
|
- // // 如果视频加载出错,则返回错误信息
|
|
|
- // videoElement.addEventListener('error', () => {
|
|
|
- // reject(`Failed to load video: ${videoUrl}`);
|
|
|
- // });
|
|
|
- // });
|
|
|
-
|
|
|
- // videoElement.addEventListener('canplay', function () {
|
|
|
- // console.log('Video can play');
|
|
|
- // const canvas: any = document.createElement('canvas'),
|
|
|
- // width = videoElement.videoWidth,
|
|
|
- // height = videoElement.videoHeight;
|
|
|
-
|
|
|
- // canvas.width = width;
|
|
|
- // canvas.height = height;
|
|
|
- // canvas.getContext('2d').drawImage(videoElement, 0, 0, width, height);
|
|
|
-
|
|
|
- // canvas.toBlob((blob: any) => {
|
|
|
- // resolve(blob);
|
|
|
- // });
|
|
|
- // });
|
|
|
- // videoElement.addEventListener('error', function (e) {
|
|
|
- // console.error('Error loading video:', e);
|
|
|
- // reject(e);
|
|
|
- // });
|
|
|
- });
|
|
|
- };
|
|
|
-
|
|
|
- const getVideoCoverImg = async (file: any) => {
|
|
|
- try {
|
|
|
- btnLoading.value = true;
|
|
|
- const imgBlob: any = await getVideoMsg(file || tempFiileBuffer.value);
|
|
|
- const fileName = `${props.path}${Date.now() + '.png'}`;
|
|
|
- const obj = {
|
|
|
- filename: fileName,
|
|
|
- bucketName: props.bucketName,
|
|
|
- postData: {
|
|
|
- filename: fileName,
|
|
|
- acl: 'public-read',
|
|
|
- key: fileName,
|
|
|
- unknowValueField: []
|
|
|
- }
|
|
|
- };
|
|
|
- const { data } = await getUploadSign(obj);
|
|
|
-
|
|
|
- const fileParams = {
|
|
|
- policy: data.policy,
|
|
|
- signature: data.signature,
|
|
|
- key: fileName,
|
|
|
- acl: 'public-read',
|
|
|
- KSSAccessKeyId: data.kssAccessKeyId,
|
|
|
- name: fileName,
|
|
|
- file: imgBlob
|
|
|
- } as any;
|
|
|
- const res = await onOnlyFileUpload(ossUploadUrl, fileParams);
|
|
|
-
|
|
|
- return res;
|
|
|
- } finally {
|
|
|
- btnLoading.value = false;
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
- const onRemove = async (file: any) => {
|
|
|
- const index = uploadList.value.findIndex(
|
|
|
- (update: any) => update.id === file.file.id
|
|
|
- );
|
|
|
- uploadList.value.splice(index, 1);
|
|
|
- btnLoading.value = false;
|
|
|
- return true;
|
|
|
- };
|
|
|
-
|
|
|
- const uploadStatus = computed(() => {
|
|
|
- let status = false;
|
|
|
- fileListRef.value.forEach((file: any) => {
|
|
|
- if (file.status !== 'finished') {
|
|
|
- status = true;
|
|
|
- }
|
|
|
- });
|
|
|
- return status || fileListRef.value.length <= 0;
|
|
|
- });
|
|
|
-
|
|
|
- const onCustomRequest = ({
|
|
|
- file,
|
|
|
- // data,
|
|
|
- // headers,
|
|
|
- // withCredentials,
|
|
|
- action,
|
|
|
- onFinish,
|
|
|
- onError,
|
|
|
- onProgress
|
|
|
- }: UploadCustomRequestOptions) => {
|
|
|
- const item = state.find((c: any) => {
|
|
|
- return c.id == file.id;
|
|
|
- });
|
|
|
-
|
|
|
- item.file = file;
|
|
|
- onFileUpload({ file, action, data: item, onProgress, onFinish, onError });
|
|
|
- };
|
|
|
-
|
|
|
- const onSubmit = async () => {
|
|
|
- const list: any = [];
|
|
|
- fileListRef.value.forEach((file: any) => {
|
|
|
- const item = uploadList.value.find(
|
|
|
- (child: any) => child.id === file.id
|
|
|
- );
|
|
|
- if (item) {
|
|
|
- list.push(item);
|
|
|
- }
|
|
|
- });
|
|
|
- emit('confrim', list);
|
|
|
- };
|
|
|
-
|
|
|
- return () => (
|
|
|
- <div class={styles.saveModal}>
|
|
|
- <NUpload
|
|
|
- ref={uploadRef}
|
|
|
- action={ossUploadUrl}
|
|
|
- // data={(file: any) => {
|
|
|
-
|
|
|
- // return { ...more };
|
|
|
- // }}
|
|
|
- customRequest={onCustomRequest}
|
|
|
- v-model:fileList={fileListRef.value}
|
|
|
- // accept=".jpg,jpeg,.png,audio/mp3,video/mp4,application/vnd.ms-powerpoint,application/vnd.openxmlformats-officedocument.presentationml.presentation"
|
|
|
- accept=".jpg,jpeg,.png,audio/mp3,video/mp4"
|
|
|
- multiple={true}
|
|
|
- max={10}
|
|
|
- // disabled={props.disabled}
|
|
|
- showFileList={true}
|
|
|
- showPreviewButton
|
|
|
- onBeforeUpload={(options: any) => onBeforeUpload(options)}
|
|
|
- onFinish={(options: any) => {
|
|
|
- onFinish(options);
|
|
|
- }}
|
|
|
- onRemove={(options: any) => onRemove(options)}>
|
|
|
- <NUploadDragger>
|
|
|
- <div class={styles.uploadBtn}>
|
|
|
- <div class={styles.iconUploadAdd} />
|
|
|
- <h3>点击或者拖动文件到该区域来上传</h3>
|
|
|
- <p>
|
|
|
- {/* 仅支持JPG、PNG、MP3、MP4、PPT格式文件,单次最多支持 */}
|
|
|
- 仅支持JPG、PNG、MP3、MP4,单次最多支持
|
|
|
- <br />
|
|
|
- 上传10个文件
|
|
|
- </p>
|
|
|
- </div>
|
|
|
- </NUploadDragger>
|
|
|
- </NUpload>
|
|
|
-
|
|
|
- <NSpace class={styles.btnGroup} justify="center">
|
|
|
- <NButton round onClick={() => emit('close')}>
|
|
|
- 取消
|
|
|
- </NButton>
|
|
|
- <NButton
|
|
|
- round
|
|
|
- type="primary"
|
|
|
- disabled={uploadStatus.value || btnLoading.value}
|
|
|
- onClick={onSubmit}>
|
|
|
- 确定
|
|
|
- </NButton>
|
|
|
- </NSpace>
|
|
|
- </div>
|
|
|
- );
|
|
|
- }
|
|
|
-});
|
|
|
+import { PropType, computed, defineComponent, reactive, ref } from 'vue';
|
|
|
+import styles from './index.module.less';
|
|
|
+import {
|
|
|
+ NButton,
|
|
|
+ NSpace,
|
|
|
+ NUpload,
|
|
|
+ NUploadDragger,
|
|
|
+ UploadCustomRequestOptions,
|
|
|
+ UploadFileInfo,
|
|
|
+ useMessage
|
|
|
+} from 'naive-ui';
|
|
|
+// import iconUploadAdd from '../../../images/icon-upload-add.png';
|
|
|
+import { NaturalTypeEnum, PageEnum } from '/src/enums/pageEnum';
|
|
|
+// import { policy } from '/src/components/upload-file/api';
|
|
|
+import { formatUrlType } from '../upload-modal';
|
|
|
+// import axios from 'axios';
|
|
|
+import {
|
|
|
+ getUploadSign,
|
|
|
+ onFileUpload,
|
|
|
+ onOnlyFileUpload
|
|
|
+ // ossSwitch
|
|
|
+} from '/src/helpers/oss-file-upload';
|
|
|
+
|
|
|
+export default defineComponent({
|
|
|
+ name: 'save-modal',
|
|
|
+ props: {
|
|
|
+ fileList: {
|
|
|
+ type: String,
|
|
|
+ default: ''
|
|
|
+ },
|
|
|
+ imageList: {
|
|
|
+ type: Array,
|
|
|
+ default: () => []
|
|
|
+ },
|
|
|
+ accept: {
|
|
|
+ // 支持类型
|
|
|
+ type: String,
|
|
|
+ default: '.jpg,.png,.jpeg,.gif'
|
|
|
+ },
|
|
|
+ showType: {
|
|
|
+ type: String as PropType<'default' | 'custom'>,
|
|
|
+ default: 'default'
|
|
|
+ },
|
|
|
+ showFileList: {
|
|
|
+ type: Boolean,
|
|
|
+ default: true
|
|
|
+ },
|
|
|
+ max: {
|
|
|
+ type: Number as PropType<number>,
|
|
|
+ default: 1
|
|
|
+ },
|
|
|
+ multiple: {
|
|
|
+ type: Boolean as PropType<boolean>,
|
|
|
+ default: false
|
|
|
+ },
|
|
|
+ disabled: {
|
|
|
+ type: Boolean as PropType<boolean>,
|
|
|
+ default: false
|
|
|
+ },
|
|
|
+ bucketName: {
|
|
|
+ type: String,
|
|
|
+ default: 'gyt'
|
|
|
+ },
|
|
|
+ directoryDnd: {
|
|
|
+ type: Boolean as PropType<boolean>,
|
|
|
+ default: false
|
|
|
+ },
|
|
|
+ path: {
|
|
|
+ type: String,
|
|
|
+ default: ''
|
|
|
+ },
|
|
|
+ fileName: {
|
|
|
+ type: String,
|
|
|
+ default: ''
|
|
|
+ }
|
|
|
+ },
|
|
|
+ emits: ['close', 'confrim'],
|
|
|
+ setup(props, { emit }) {
|
|
|
+ const ossUploadUrl = `https://${props.bucketName}.ks3-cn-beijing.ksyuncs.com/`;
|
|
|
+ const message = useMessage();
|
|
|
+ const visiable = ref<boolean>(false);
|
|
|
+ const btnLoading = ref<boolean>(false);
|
|
|
+ const tempFiileBuffer = ref();
|
|
|
+ const uploadRef = ref();
|
|
|
+ const state = reactive([]) as any;
|
|
|
+
|
|
|
+ const fileListRef = ref<UploadFileInfo[]>([]);
|
|
|
+ const uploadList = ref([] as any);
|
|
|
+
|
|
|
+ // 获取文件后缀名
|
|
|
+ function getFileExtension(filename: string) {
|
|
|
+ return filename.slice(((filename.lastIndexOf('.') - 1) >>> 0) + 2);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 判断是否是允许的文件类型
|
|
|
+ function isAllowedFileType(filename: string, allowedExtensions: any) {
|
|
|
+ const extension = getFileExtension(filename).toLowerCase();
|
|
|
+ return allowedExtensions.includes(extension);
|
|
|
+ }
|
|
|
+
|
|
|
+ const onBeforeUpload = async (options: any) => {
|
|
|
+ const file = options.file;
|
|
|
+ // 文件大小
|
|
|
+ let isLt2M = true;
|
|
|
+
|
|
|
+ const allowedExtensions = [
|
|
|
+ 'jpg',
|
|
|
+ 'jpeg',
|
|
|
+ 'png',
|
|
|
+ 'mp4',
|
|
|
+ // 'ppt',
|
|
|
+ // 'pptx',
|
|
|
+ 'mp3'
|
|
|
+ ];
|
|
|
+ if (!isAllowedFileType(file.file.name, allowedExtensions)) {
|
|
|
+ message.error('文件格式不支持');
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ const type = file.type.includes('image')
|
|
|
+ ? NaturalTypeEnum.IMG
|
|
|
+ : file.type.includes('audio')
|
|
|
+ ? NaturalTypeEnum.SONG
|
|
|
+ : file.type.includes('video')
|
|
|
+ ? NaturalTypeEnum.VIDEO
|
|
|
+ : file.type.includes(
|
|
|
+ 'vnd.openxmlformats-officedocument.presentationml.presentation'
|
|
|
+ ) || file.type.includes('vnd.ms-powerpoint')
|
|
|
+ ? NaturalTypeEnum.PPT
|
|
|
+ : 'other';
|
|
|
+
|
|
|
+ if (type === 'other') {
|
|
|
+ message.error(`文件格式不支持`);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ const size = type === 'IMG' ? 2 : type === 'SONG' ? 20 : 500;
|
|
|
+ if (size) {
|
|
|
+ isLt2M = file.file.size / 1024 / 1024 < size;
|
|
|
+ if (!isLt2M) {
|
|
|
+ const typeStr =
|
|
|
+ type === 'IMG' ? '图片' : type === 'SONG' ? '音频' : '视频';
|
|
|
+ message.error(`${typeStr}大小不能超过${size}M`);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!isLt2M) {
|
|
|
+ return isLt2M;
|
|
|
+ }
|
|
|
+ // 是否裁切
|
|
|
+ // if (props.cropper && type === 'IMG') {
|
|
|
+ // getBase64(file.file, (imageUrl: any) => {
|
|
|
+ // const target = Object.assign({}, props.options, {
|
|
|
+ // img: imageUrl,
|
|
|
+ // name: file.file.name // 上传文件名
|
|
|
+ // });
|
|
|
+ // visiable.value = true;
|
|
|
+
|
|
|
+ // setTimeout(() => {
|
|
|
+ // CropperModal.value?.edit(target);
|
|
|
+ // }, 100);
|
|
|
+ // });
|
|
|
+ // return false;
|
|
|
+ // }
|
|
|
+
|
|
|
+ try {
|
|
|
+ btnLoading.value = true;
|
|
|
+ const name = file.file.name;
|
|
|
+ const suffix = name.slice(name.lastIndexOf('.'));
|
|
|
+ const fileName = `${props.path}${Date.now() + file.id + suffix}`;
|
|
|
+ const obj = {
|
|
|
+ filename: fileName,
|
|
|
+ bucketName: props.bucketName,
|
|
|
+ postData: {
|
|
|
+ filename: fileName,
|
|
|
+ acl: 'public-read',
|
|
|
+ key: fileName,
|
|
|
+ unknowValueField: []
|
|
|
+ }
|
|
|
+ };
|
|
|
+ // const { data } = await policy(obj);
|
|
|
+ const { data } = await getUploadSign(obj);
|
|
|
+ state.push({
|
|
|
+ id: file.id,
|
|
|
+ tempFiileBuffer: file.file,
|
|
|
+ policy: data.policy,
|
|
|
+ signature: data.signature,
|
|
|
+ acl: 'public-read',
|
|
|
+ key: fileName,
|
|
|
+ KSSAccessKeyId: data.kssAccessKeyId,
|
|
|
+ name: fileName
|
|
|
+ });
|
|
|
+ } catch {
|
|
|
+ //
|
|
|
+ // message.error('上传失败')
|
|
|
+ btnLoading.value = false;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ };
|
|
|
+ // const getBase64 = async (img: any, callback: any) => {
|
|
|
+ // const reader = new FileReader();
|
|
|
+ // reader.addEventListener('load', () => callback(reader.result));
|
|
|
+ // reader.readAsDataURL(img);
|
|
|
+ // };
|
|
|
+
|
|
|
+ const onFinish = (options: any) => {
|
|
|
+ onFinishAfter(options);
|
|
|
+ };
|
|
|
+ const onFinishAfter = async (options: any) => {
|
|
|
+ console.log(options, 'onFinishAfter');
|
|
|
+ const item = state.find((c: any) => c.id == options.file.id);
|
|
|
+ const type = formatUrlType(options.file.url);
|
|
|
+ let coverImg = '';
|
|
|
+ if (type === 'IMG') {
|
|
|
+ coverImg = options.file.url;
|
|
|
+ } else if (type === 'SONG') {
|
|
|
+ coverImg = PageEnum.SONG_DEFAULT_COVER;
|
|
|
+ } else if (type === 'PPT') {
|
|
|
+ coverImg = PageEnum.PPT_DEFAULT_COVER;
|
|
|
+ } else if (type === 'VIDEO') {
|
|
|
+ // 获取视频封面图
|
|
|
+ coverImg = await getVideoCoverImg(item.tempFiileBuffer);
|
|
|
+ }
|
|
|
+
|
|
|
+ uploadList.value.push({
|
|
|
+ coverImg,
|
|
|
+ content: options.file.url,
|
|
|
+ id: options.file.id,
|
|
|
+ name: options.file.name
|
|
|
+ ? options.file.name.slice(0, options.file.name.lastIndexOf('.'))
|
|
|
+ : ''
|
|
|
+ });
|
|
|
+
|
|
|
+ visiable.value = false;
|
|
|
+ btnLoading.value = false;
|
|
|
+ };
|
|
|
+ const getVideoMsg = (file: any) => {
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
+ // let dataURL = '';
|
|
|
+ const videoElement = document.createElement('video');
|
|
|
+ videoElement.setAttribute('crossOrigin', 'Anonymous'); // 处理跨域
|
|
|
+ videoElement.setAttribute('preload', 'auto'); // auto|metadata|none
|
|
|
+ videoElement.muted = true;
|
|
|
+ videoElement.autoplay = true;
|
|
|
+ videoElement.src = URL.createObjectURL(file);
|
|
|
+ // Listen for 'canplay' to ensure the video is ready for frame capture
|
|
|
+ videoElement.addEventListener('loadedmetadata', () => {
|
|
|
+ // 这里开始播放
|
|
|
+ videoElement.play();
|
|
|
+ setTimeout(() => {
|
|
|
+ // 过500ms 暂停, 解决空白问题
|
|
|
+ videoElement.currentTime = 0;
|
|
|
+ videoElement.pause();
|
|
|
+ // 创建canvas元素
|
|
|
+ const canvas: any = document.createElement('canvas');
|
|
|
+ canvas.width = videoElement.videoWidth;
|
|
|
+ canvas.height = videoElement.videoHeight;
|
|
|
+
|
|
|
+ // 将视频帧绘制到canvas上
|
|
|
+ // const ctx = canvas.getContext('2d');
|
|
|
+
|
|
|
+ // console.log(videoElement);
|
|
|
+ // ctx.drawImage(videoElement, 0, 0, canvas.width, canvas.height);
|
|
|
+ canvas
|
|
|
+ .getContext('2d')
|
|
|
+ .drawImage(videoElement, 0, 0, canvas.width, canvas.height);
|
|
|
+
|
|
|
+ // 将canvas图像转换为base64格式的数据URI
|
|
|
+ // const dataUrl = canvas.toDataURL('image/png');
|
|
|
+ // 返回base64格式的数据URI
|
|
|
+ // resolve(dataUrl);
|
|
|
+ canvas.toBlob((blob: any) => {
|
|
|
+ resolve(blob);
|
|
|
+ });
|
|
|
+ }, 500);
|
|
|
+ });
|
|
|
+
|
|
|
+ // 如果视频加载出错,则返回错误信息
|
|
|
+ videoElement.addEventListener('error', (e: any) => {
|
|
|
+ reject(e);
|
|
|
+ });
|
|
|
+ // return new Promise((resolve, reject) => {
|
|
|
+ // videoElement.addEventListener('loadedmetadata', () => {
|
|
|
+ // // 这里开始播放
|
|
|
+ // videoElement.play()
|
|
|
+ // setTimeout(() => {
|
|
|
+ // // 过500ms 暂停, 解决空白问题
|
|
|
+ // videoElement.pause()
|
|
|
+ // // 创建canvas元素
|
|
|
+ // const canvas = document.createElement('canvas');
|
|
|
+ // canvas.width = videoElement.videoWidth;
|
|
|
+ // canvas.height = videoElement.videoHeight;
|
|
|
+
|
|
|
+ // // 将视频帧绘制到canvas上
|
|
|
+ // const ctx = canvas.getContext('2d');
|
|
|
+
|
|
|
+ // console.log(videoElement);
|
|
|
+ // ctx.drawImage(videoElement, 0, 0, canvas.width, canvas.height);
|
|
|
+
|
|
|
+ // // 将canvas图像转换为base64格式的数据URI
|
|
|
+ // const dataUrl = canvas.toDataURL('image/png');
|
|
|
+ // console.log(dataUrl);
|
|
|
+ // thumbnail.src = dataUrl;
|
|
|
+ // thumbnail.style.display = 'inline';
|
|
|
+ // // 返回base64格式的数据URI
|
|
|
+ // resolve(dataUrl);
|
|
|
+ // }, 500);
|
|
|
+ // });
|
|
|
+
|
|
|
+ // // 如果视频加载出错,则返回错误信息
|
|
|
+ // videoElement.addEventListener('error', () => {
|
|
|
+ // reject(`Failed to load video: ${videoUrl}`);
|
|
|
+ // });
|
|
|
+ // });
|
|
|
+
|
|
|
+ // videoElement.addEventListener('canplay', function () {
|
|
|
+ // console.log('Video can play');
|
|
|
+ // const canvas: any = document.createElement('canvas'),
|
|
|
+ // width = videoElement.videoWidth,
|
|
|
+ // height = videoElement.videoHeight;
|
|
|
+
|
|
|
+ // canvas.width = width;
|
|
|
+ // canvas.height = height;
|
|
|
+ // canvas.getContext('2d').drawImage(videoElement, 0, 0, width, height);
|
|
|
+
|
|
|
+ // canvas.toBlob((blob: any) => {
|
|
|
+ // resolve(blob);
|
|
|
+ // });
|
|
|
+ // });
|
|
|
+ // videoElement.addEventListener('error', function (e) {
|
|
|
+ // console.error('Error loading video:', e);
|
|
|
+ // reject(e);
|
|
|
+ // });
|
|
|
+ });
|
|
|
+ };
|
|
|
+
|
|
|
+ const getVideoCoverImg = async (file: any) => {
|
|
|
+ try {
|
|
|
+ btnLoading.value = true;
|
|
|
+ const imgBlob: any = await getVideoMsg(file || tempFiileBuffer.value);
|
|
|
+ const fileName = `${props.path}${Date.now() + '.png'}`;
|
|
|
+ const obj = {
|
|
|
+ filename: fileName,
|
|
|
+ bucketName: props.bucketName,
|
|
|
+ postData: {
|
|
|
+ filename: fileName,
|
|
|
+ acl: 'public-read',
|
|
|
+ key: fileName,
|
|
|
+ unknowValueField: []
|
|
|
+ }
|
|
|
+ };
|
|
|
+ const { data } = await getUploadSign(obj);
|
|
|
+
|
|
|
+ const fileParams = {
|
|
|
+ policy: data.policy,
|
|
|
+ signature: data.signature,
|
|
|
+ key: fileName,
|
|
|
+ acl: 'public-read',
|
|
|
+ KSSAccessKeyId: data.kssAccessKeyId,
|
|
|
+ name: fileName,
|
|
|
+ file: imgBlob
|
|
|
+ } as any;
|
|
|
+ const res = await onOnlyFileUpload(ossUploadUrl, fileParams);
|
|
|
+
|
|
|
+ return res;
|
|
|
+ } finally {
|
|
|
+ btnLoading.value = false;
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ const onRemove = async (file: any) => {
|
|
|
+ const index = uploadList.value.findIndex(
|
|
|
+ (update: any) => update.id === file.file.id
|
|
|
+ );
|
|
|
+ uploadList.value.splice(index, 1);
|
|
|
+ btnLoading.value = false;
|
|
|
+ return true;
|
|
|
+ };
|
|
|
+
|
|
|
+ const uploadStatus = computed(() => {
|
|
|
+ let status = false;
|
|
|
+ fileListRef.value.forEach((file: any) => {
|
|
|
+ if (file.status !== 'finished') {
|
|
|
+ status = true;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ return status || fileListRef.value.length <= 0;
|
|
|
+ });
|
|
|
+
|
|
|
+ const onCustomRequest = ({
|
|
|
+ file,
|
|
|
+ // data,
|
|
|
+ // headers,
|
|
|
+ // withCredentials,
|
|
|
+ action,
|
|
|
+ onFinish,
|
|
|
+ onError,
|
|
|
+ onProgress
|
|
|
+ }: UploadCustomRequestOptions) => {
|
|
|
+ const item = state.find((c: any) => {
|
|
|
+ return c.id == file.id;
|
|
|
+ });
|
|
|
+
|
|
|
+ item.file = file;
|
|
|
+ onFileUpload({ file, action, data: item, onProgress, onFinish, onError });
|
|
|
+ };
|
|
|
+
|
|
|
+ const onSubmit = async () => {
|
|
|
+ const list: any = [];
|
|
|
+ fileListRef.value.forEach((file: any) => {
|
|
|
+ const item = uploadList.value.find(
|
|
|
+ (child: any) => child.id === file.id
|
|
|
+ );
|
|
|
+ if (item) {
|
|
|
+ list.push(item);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ emit('confrim', list);
|
|
|
+ };
|
|
|
+
|
|
|
+ return () => (
|
|
|
+ <div class={styles.saveModal}>
|
|
|
+ <NUpload
|
|
|
+ ref={uploadRef}
|
|
|
+ action={ossUploadUrl}
|
|
|
+ // data={(file: any) => {
|
|
|
+
|
|
|
+ // return { ...more };
|
|
|
+ // }}
|
|
|
+ customRequest={onCustomRequest}
|
|
|
+ v-model:fileList={fileListRef.value}
|
|
|
+ // accept=".jpg,jpeg,.png,audio/mp3,video/mp4,application/vnd.ms-powerpoint,application/vnd.openxmlformats-officedocument.presentationml.presentation"
|
|
|
+ accept=".jpg,jpeg,.png,audio/mp3,video/mp4"
|
|
|
+ multiple={true}
|
|
|
+ max={10}
|
|
|
+ // disabled={props.disabled}
|
|
|
+ showFileList={true}
|
|
|
+ showPreviewButton
|
|
|
+ onBeforeUpload={(options: any) => onBeforeUpload(options)}
|
|
|
+ onFinish={(options: any) => {
|
|
|
+ onFinish(options);
|
|
|
+ }}
|
|
|
+ onRemove={(options: any) => onRemove(options)}>
|
|
|
+ <NUploadDragger>
|
|
|
+ <div class={styles.uploadBtn}>
|
|
|
+ <div class={styles.iconUploadAdd} />
|
|
|
+ <h3>点击或者拖动文件到该区域来上传</h3>
|
|
|
+ <p>
|
|
|
+ {/* 仅支持JPG、PNG、MP3、MP4、PPT格式文件,单次最多支持 */}
|
|
|
+ 仅支持JPG、PNG、MP3、MP4,单次最多支持
|
|
|
+ <br />
|
|
|
+ 上传10个文件
|
|
|
+ </p>
|
|
|
+ </div>
|
|
|
+ </NUploadDragger>
|
|
|
+ </NUpload>
|
|
|
+
|
|
|
+ <NSpace class={styles.btnGroup} justify="center">
|
|
|
+ <NButton round onClick={() => emit('close')}>
|
|
|
+ 取消
|
|
|
+ </NButton>
|
|
|
+ <NButton
|
|
|
+ round
|
|
|
+ type="primary"
|
|
|
+ disabled={uploadStatus.value || btnLoading.value}
|
|
|
+ onClick={onSubmit}>
|
|
|
+ 确定
|
|
|
+ </NButton>
|
|
|
+ </NSpace>
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+ }
|
|
|
+});
|