|  | @@ -1,395 +1,394 @@
 | 
	
		
			
				|  |  | -import {
 | 
	
		
			
				|  |  | -  NButton,
 | 
	
		
			
				|  |  | -  NModal,
 | 
	
		
			
				|  |  | -  NUpload,
 | 
	
		
			
				|  |  | -  UploadCustomRequestOptions,
 | 
	
		
			
				|  |  | -  UploadFileInfo,
 | 
	
		
			
				|  |  | -  useMessage
 | 
	
		
			
				|  |  | -} from 'naive-ui';
 | 
	
		
			
				|  |  | -import { defineComponent, watch, PropType, reactive, ref } from 'vue';
 | 
	
		
			
				|  |  | -import { policy } from './api';
 | 
	
		
			
				|  |  | -import Copper from './copper';
 | 
	
		
			
				|  |  | -import axios from 'axios';
 | 
	
		
			
				|  |  | -import {
 | 
	
		
			
				|  |  | -  getUploadSign,
 | 
	
		
			
				|  |  | -  onFileUpload,
 | 
	
		
			
				|  |  | -  onOnlyFileUpload
 | 
	
		
			
				|  |  | -} from '/src/helpers/oss-file-upload';
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -export default defineComponent({
 | 
	
		
			
				|  |  | -  name: 'upload-file',
 | 
	
		
			
				|  |  | -  props: {
 | 
	
		
			
				|  |  | -    fileList: {
 | 
	
		
			
				|  |  | -      type: String,
 | 
	
		
			
				|  |  | -      default: ''
 | 
	
		
			
				|  |  | -    },
 | 
	
		
			
				|  |  | -    imageList: {
 | 
	
		
			
				|  |  | -      type: Array,
 | 
	
		
			
				|  |  | -      default: () => []
 | 
	
		
			
				|  |  | -    },
 | 
	
		
			
				|  |  | -    accept: {
 | 
	
		
			
				|  |  | -      // 支持类型
 | 
	
		
			
				|  |  | -      type: String,
 | 
	
		
			
				|  |  | -      default: '.jpg,.png,.jpeg,.gif'
 | 
	
		
			
				|  |  | -    },
 | 
	
		
			
				|  |  | -    listType: {
 | 
	
		
			
				|  |  | -      type: String as PropType<'image' | 'image-card'>,
 | 
	
		
			
				|  |  | -      default: 'image-card'
 | 
	
		
			
				|  |  | -    },
 | 
	
		
			
				|  |  | -    showType: {
 | 
	
		
			
				|  |  | -      type: String as PropType<'default' | 'custom'>,
 | 
	
		
			
				|  |  | -      default: 'default'
 | 
	
		
			
				|  |  | -    },
 | 
	
		
			
				|  |  | -    showFileList: {
 | 
	
		
			
				|  |  | -      type: Boolean,
 | 
	
		
			
				|  |  | -      default: true
 | 
	
		
			
				|  |  | -    },
 | 
	
		
			
				|  |  | -    // width: {
 | 
	
		
			
				|  |  | -    //   type: Number,
 | 
	
		
			
				|  |  | -    //   default: 96
 | 
	
		
			
				|  |  | -    // },
 | 
	
		
			
				|  |  | -    // height: {
 | 
	
		
			
				|  |  | -    //   type: Number,
 | 
	
		
			
				|  |  | -    //   default: 96
 | 
	
		
			
				|  |  | -    // },
 | 
	
		
			
				|  |  | -    text: {
 | 
	
		
			
				|  |  | -      type: String as PropType<string>,
 | 
	
		
			
				|  |  | -      default: '上传文件'
 | 
	
		
			
				|  |  | -    },
 | 
	
		
			
				|  |  | -    size: {
 | 
	
		
			
				|  |  | -      // 文件大小
 | 
	
		
			
				|  |  | -      type: Number as PropType<number>,
 | 
	
		
			
				|  |  | -      default: 5
 | 
	
		
			
				|  |  | -    },
 | 
	
		
			
				|  |  | -    max: {
 | 
	
		
			
				|  |  | -      type: Number as PropType<number>,
 | 
	
		
			
				|  |  | -      default: 1
 | 
	
		
			
				|  |  | -    },
 | 
	
		
			
				|  |  | -    multiple: {
 | 
	
		
			
				|  |  | -      type: Boolean as PropType<boolean>,
 | 
	
		
			
				|  |  | -      default: false
 | 
	
		
			
				|  |  | -    },
 | 
	
		
			
				|  |  | -    disabled: {
 | 
	
		
			
				|  |  | -      type: Boolean as PropType<boolean>,
 | 
	
		
			
				|  |  | -      default: false
 | 
	
		
			
				|  |  | -    },
 | 
	
		
			
				|  |  | -    tips: {
 | 
	
		
			
				|  |  | -      type: String as PropType<string>,
 | 
	
		
			
				|  |  | -      default: ''
 | 
	
		
			
				|  |  | -    },
 | 
	
		
			
				|  |  | -    bucketName: {
 | 
	
		
			
				|  |  | -      type: String,
 | 
	
		
			
				|  |  | -      default: 'gyt'
 | 
	
		
			
				|  |  | -    },
 | 
	
		
			
				|  |  | -    path: {
 | 
	
		
			
				|  |  | -      type: String,
 | 
	
		
			
				|  |  | -      default: ''
 | 
	
		
			
				|  |  | -    },
 | 
	
		
			
				|  |  | -    fileName: {
 | 
	
		
			
				|  |  | -      type: String,
 | 
	
		
			
				|  |  | -      default: ''
 | 
	
		
			
				|  |  | -    },
 | 
	
		
			
				|  |  | -    cropper: {
 | 
	
		
			
				|  |  | -      // 是否裁切, 只有图片才支持
 | 
	
		
			
				|  |  | -      type: Boolean as PropType<boolean>,
 | 
	
		
			
				|  |  | -      default: false
 | 
	
		
			
				|  |  | -    },
 | 
	
		
			
				|  |  | -    options: {
 | 
	
		
			
				|  |  | -      type: Object,
 | 
	
		
			
				|  |  | -      default: () => {
 | 
	
		
			
				|  |  | -        return {
 | 
	
		
			
				|  |  | -          viewMode: 0,
 | 
	
		
			
				|  |  | -          autoCrop: true, //是否默认生成截图框
 | 
	
		
			
				|  |  | -          enlarge: 1, //  图片放大倍数
 | 
	
		
			
				|  |  | -          autoCropWidth: 200, //默认生成截图框宽度
 | 
	
		
			
				|  |  | -          autoCropHeight: 200, //默认生成截图框高度
 | 
	
		
			
				|  |  | -          fixedBox: false, //是否固定截图框大小 不允许改变
 | 
	
		
			
				|  |  | -          previewsCircle: true, //预览图是否是原图形
 | 
	
		
			
				|  |  | -          title: '上传图片'
 | 
	
		
			
				|  |  | -        };
 | 
	
		
			
				|  |  | -      }
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -  },
 | 
	
		
			
				|  |  | -  // readFileInputEventAsArrayBuffer 只会在文件的时间回调
 | 
	
		
			
				|  |  | -  emits: [
 | 
	
		
			
				|  |  | -    'update:fileList',
 | 
	
		
			
				|  |  | -    'close',
 | 
	
		
			
				|  |  | -    'readFileInputEventAsArrayBuffer',
 | 
	
		
			
				|  |  | -    'remove'
 | 
	
		
			
				|  |  | -  ],
 | 
	
		
			
				|  |  | -  setup(props, { emit, expose, slots }) {
 | 
	
		
			
				|  |  | -    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({
 | 
	
		
			
				|  |  | -    //   policy: '',
 | 
	
		
			
				|  |  | -    //   signature: '',
 | 
	
		
			
				|  |  | -    //   key: '',
 | 
	
		
			
				|  |  | -    //   KSSAccessKeyId: '',
 | 
	
		
			
				|  |  | -    //   acl: 'public-read',
 | 
	
		
			
				|  |  | -    //   name: ''
 | 
	
		
			
				|  |  | -    // }) as any;
 | 
	
		
			
				|  |  | -    const state = reactive([]) as any;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    const fileListRef = ref<UploadFileInfo[]>([]);
 | 
	
		
			
				|  |  | -    const initFileList = () => {
 | 
	
		
			
				|  |  | -      if (props.fileList) {
 | 
	
		
			
				|  |  | -        const splitName = props.fileList.split('/');
 | 
	
		
			
				|  |  | -        fileListRef.value = [
 | 
	
		
			
				|  |  | -          {
 | 
	
		
			
				|  |  | -            id: new Date().getTime().toString(),
 | 
	
		
			
				|  |  | -            name: splitName[splitName.length - 1],
 | 
	
		
			
				|  |  | -            status: 'finished',
 | 
	
		
			
				|  |  | -            url: props.fileList
 | 
	
		
			
				|  |  | -          }
 | 
	
		
			
				|  |  | -        ];
 | 
	
		
			
				|  |  | -      } else if (Array.isArray(props.imageList)) {
 | 
	
		
			
				|  |  | -        const list: any = [];
 | 
	
		
			
				|  |  | -        props.imageList.forEach((n: any) => {
 | 
	
		
			
				|  |  | -          const splitName = n.split('/');
 | 
	
		
			
				|  |  | -          list.push({
 | 
	
		
			
				|  |  | -            id: Date.now().toString(),
 | 
	
		
			
				|  |  | -            name: splitName[splitName.length - 1],
 | 
	
		
			
				|  |  | -            status: 'finished',
 | 
	
		
			
				|  |  | -            url: n
 | 
	
		
			
				|  |  | -          });
 | 
	
		
			
				|  |  | -        });
 | 
	
		
			
				|  |  | -        fileListRef.value = list;
 | 
	
		
			
				|  |  | -      } else {
 | 
	
		
			
				|  |  | -        fileListRef.value = [];
 | 
	
		
			
				|  |  | -      }
 | 
	
		
			
				|  |  | -    };
 | 
	
		
			
				|  |  | -    initFileList();
 | 
	
		
			
				|  |  | -    watch(
 | 
	
		
			
				|  |  | -      () => props.imageList,
 | 
	
		
			
				|  |  | -      () => {
 | 
	
		
			
				|  |  | -        initFileList();
 | 
	
		
			
				|  |  | -      }
 | 
	
		
			
				|  |  | -    );
 | 
	
		
			
				|  |  | -    watch(
 | 
	
		
			
				|  |  | -      () => props.fileList,
 | 
	
		
			
				|  |  | -      () => {
 | 
	
		
			
				|  |  | -        console.log('list');
 | 
	
		
			
				|  |  | -        initFileList();
 | 
	
		
			
				|  |  | -      }
 | 
	
		
			
				|  |  | -    );
 | 
	
		
			
				|  |  | -    const handleClearFile = () => {
 | 
	
		
			
				|  |  | -      uploadRef.value?.clear();
 | 
	
		
			
				|  |  | -      console.log('清空', uploadRef.value);
 | 
	
		
			
				|  |  | -    };
 | 
	
		
			
				|  |  | -    expose({
 | 
	
		
			
				|  |  | -      handleClearFile
 | 
	
		
			
				|  |  | -    });
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    const CropperModal = ref();
 | 
	
		
			
				|  |  | -    const onBeforeUpload = async (options: any) => {
 | 
	
		
			
				|  |  | -      const file = options.file;
 | 
	
		
			
				|  |  | -      // 文件大小
 | 
	
		
			
				|  |  | -      let isLt2M = true;
 | 
	
		
			
				|  |  | -      if (props.size) {
 | 
	
		
			
				|  |  | -        isLt2M = file.file.size / 1024 / 1024 < props.size;
 | 
	
		
			
				|  |  | -        if (!isLt2M) {
 | 
	
		
			
				|  |  | -          message.error(`文件大小不能超过${props.size}M`);
 | 
	
		
			
				|  |  | -          return false;
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -      }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -      if (!isLt2M) {
 | 
	
		
			
				|  |  | -        return isLt2M;
 | 
	
		
			
				|  |  | -      }
 | 
	
		
			
				|  |  | -      // 是否裁切
 | 
	
		
			
				|  |  | -      if (props.cropper) {
 | 
	
		
			
				|  |  | -        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);
 | 
	
		
			
				|  |  | -            console.log(CropperModal.value, 'cropper');
 | 
	
		
			
				|  |  | -          }, 100);
 | 
	
		
			
				|  |  | -        });
 | 
	
		
			
				|  |  | -        return false;
 | 
	
		
			
				|  |  | -      }
 | 
	
		
			
				|  |  | -      try {
 | 
	
		
			
				|  |  | -        btnLoading.value = true;
 | 
	
		
			
				|  |  | -        console.log(props.path, file.file);
 | 
	
		
			
				|  |  | -        const name = file.file.name;
 | 
	
		
			
				|  |  | -        const suffix = name.slice(name.lastIndexOf('.'));
 | 
	
		
			
				|  |  | -        // const months = dayjs().format('MM')
 | 
	
		
			
				|  |  | -        const fileName = `${props.path}${
 | 
	
		
			
				|  |  | -          props.fileName || Date.now() + suffix
 | 
	
		
			
				|  |  | -        }`;
 | 
	
		
			
				|  |  | -        const obj = {
 | 
	
		
			
				|  |  | -          filename: fileName,
 | 
	
		
			
				|  |  | -          bucketName: props.bucketName,
 | 
	
		
			
				|  |  | -          postData: {
 | 
	
		
			
				|  |  | -            filename: fileName,
 | 
	
		
			
				|  |  | -            acl: 'public-read',
 | 
	
		
			
				|  |  | -            key: fileName,
 | 
	
		
			
				|  |  | -            unknowValueField: []
 | 
	
		
			
				|  |  | -          }
 | 
	
		
			
				|  |  | -        };
 | 
	
		
			
				|  |  | -        // const { data } = await policy(obj);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        // state.policy = data.policy;
 | 
	
		
			
				|  |  | -        // state.signature = data.signature;
 | 
	
		
			
				|  |  | -        // state.key = fileName;
 | 
	
		
			
				|  |  | -        // state.KSSAccessKeyId = data.kssAccessKeyId;
 | 
	
		
			
				|  |  | -        // state.name = fileName;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        // tempFiileBuffer.value = file.file;
 | 
	
		
			
				|  |  | -        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) => {
 | 
	
		
			
				|  |  | -      const item = state.find((c: any) => c.id == options.file.id);
 | 
	
		
			
				|  |  | -      // const url = ossUploadUrl + state.key;
 | 
	
		
			
				|  |  | -      emit('update:fileList', options.file.url);
 | 
	
		
			
				|  |  | -      emit('readFileInputEventAsArrayBuffer', item.tempFiileBuffer);
 | 
	
		
			
				|  |  | -      // options.file.url = url;
 | 
	
		
			
				|  |  | -      visiable.value = false;
 | 
	
		
			
				|  |  | -      btnLoading.value = false;
 | 
	
		
			
				|  |  | -    };
 | 
	
		
			
				|  |  | -    const onRemove = async (options: any) => {
 | 
	
		
			
				|  |  | -      console.log('🚀 ~ options', options);
 | 
	
		
			
				|  |  | -      emit('update:fileList', '');
 | 
	
		
			
				|  |  | -      emit('remove');
 | 
	
		
			
				|  |  | -      btnLoading.value = false;
 | 
	
		
			
				|  |  | -    };
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    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 cropperNo = () => {}
 | 
	
		
			
				|  |  | -    // 裁切成功
 | 
	
		
			
				|  |  | -    const cropperOk = async (blob: any) => {
 | 
	
		
			
				|  |  | -      try {
 | 
	
		
			
				|  |  | -        // const months = dayjs().format('MM')
 | 
	
		
			
				|  |  | -        const fileName = `${props.path}${
 | 
	
		
			
				|  |  | -          props.fileName || new Date().getTime() + '.png'
 | 
	
		
			
				|  |  | -        }`;
 | 
	
		
			
				|  |  | -        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);
 | 
	
		
			
				|  |  | -        const formData = {
 | 
	
		
			
				|  |  | -          policy: data.policy,
 | 
	
		
			
				|  |  | -          signature: data.signature,
 | 
	
		
			
				|  |  | -          acl: 'public-read',
 | 
	
		
			
				|  |  | -          key: fileName,
 | 
	
		
			
				|  |  | -          KSSAccessKeyId: data.kssAccessKeyId,
 | 
	
		
			
				|  |  | -          name: fileName,
 | 
	
		
			
				|  |  | -          file: blob
 | 
	
		
			
				|  |  | -        };
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        const res = await onOnlyFileUpload(ossUploadUrl, formData);
 | 
	
		
			
				|  |  | -        console.log(res, 'upload');
 | 
	
		
			
				|  |  | -        emit('update:fileList', res);
 | 
	
		
			
				|  |  | -        visiable.value = false;
 | 
	
		
			
				|  |  | -      } catch {
 | 
	
		
			
				|  |  | -        //
 | 
	
		
			
				|  |  | -        // message.error('上传失败');
 | 
	
		
			
				|  |  | -        return false;
 | 
	
		
			
				|  |  | -      }
 | 
	
		
			
				|  |  | -    };
 | 
	
		
			
				|  |  | -    return () => (
 | 
	
		
			
				|  |  | -      <div>
 | 
	
		
			
				|  |  | -        <NUpload
 | 
	
		
			
				|  |  | -          ref={uploadRef}
 | 
	
		
			
				|  |  | -          action={ossUploadUrl}
 | 
	
		
			
				|  |  | -          // data={state}
 | 
	
		
			
				|  |  | -          customRequest={onCustomRequest}
 | 
	
		
			
				|  |  | -          v-model:fileList={fileListRef.value}
 | 
	
		
			
				|  |  | -          listType={props.listType}
 | 
	
		
			
				|  |  | -          accept={props.accept}
 | 
	
		
			
				|  |  | -          multiple={props.multiple}
 | 
	
		
			
				|  |  | -          max={props.max}
 | 
	
		
			
				|  |  | -          disabled={props.disabled}
 | 
	
		
			
				|  |  | -          showFileList={props.showFileList}
 | 
	
		
			
				|  |  | -          showPreviewButton
 | 
	
		
			
				|  |  | -          onBeforeUpload={(options: any) => onBeforeUpload(options)}
 | 
	
		
			
				|  |  | -          onFinish={(options: any) => onFinish(options)}
 | 
	
		
			
				|  |  | -          onRemove={(options: any) => onRemove(options)}>
 | 
	
		
			
				|  |  | -          {props.showType === 'default' && props.listType === 'image' && (
 | 
	
		
			
				|  |  | -            <NButton loading={btnLoading.value} type="primary">
 | 
	
		
			
				|  |  | -              {props.text}
 | 
	
		
			
				|  |  | -            </NButton>
 | 
	
		
			
				|  |  | -          )}
 | 
	
		
			
				|  |  | -          {props.showType === 'custom' && slots.custom && slots.custom()}
 | 
	
		
			
				|  |  | -        </NUpload>
 | 
	
		
			
				|  |  | -        {props.tips && (
 | 
	
		
			
				|  |  | -          <p style="font-size: 13px; color: #666; padding-top: 4px;">
 | 
	
		
			
				|  |  | -            {props.tips}
 | 
	
		
			
				|  |  | -          </p>
 | 
	
		
			
				|  |  | -        )}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        <NModal
 | 
	
		
			
				|  |  | -          v-model:show={visiable.value}
 | 
	
		
			
				|  |  | -          preset="dialog"
 | 
	
		
			
				|  |  | -          showIcon={false}
 | 
	
		
			
				|  |  | -          class={['modalTitle background']}
 | 
	
		
			
				|  |  | -          title="上传图片"
 | 
	
		
			
				|  |  | -          style={{ width: '800px' }}>
 | 
	
		
			
				|  |  | -          {/* @cropper-no="error" @cropper-ok="success" */}
 | 
	
		
			
				|  |  | -          <Copper
 | 
	
		
			
				|  |  | -            // ref="CropperModal"
 | 
	
		
			
				|  |  | -            ref={CropperModal}
 | 
	
		
			
				|  |  | -            onClose={() => (visiable.value = false)}
 | 
	
		
			
				|  |  | -            onCropperOk={cropperOk}
 | 
	
		
			
				|  |  | -          />
 | 
	
		
			
				|  |  | -        </NModal>
 | 
	
		
			
				|  |  | -      </div>
 | 
	
		
			
				|  |  | -    );
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | -});
 | 
	
		
			
				|  |  | +import {
 | 
	
		
			
				|  |  | +  NButton,
 | 
	
		
			
				|  |  | +  NModal,
 | 
	
		
			
				|  |  | +  NUpload,
 | 
	
		
			
				|  |  | +  UploadCustomRequestOptions,
 | 
	
		
			
				|  |  | +  UploadFileInfo,
 | 
	
		
			
				|  |  | +  useMessage
 | 
	
		
			
				|  |  | +} from 'naive-ui';
 | 
	
		
			
				|  |  | +import { defineComponent, watch, PropType, reactive, ref } from 'vue';
 | 
	
		
			
				|  |  | +import { policy } from './api';
 | 
	
		
			
				|  |  | +import Copper from './copper';
 | 
	
		
			
				|  |  | +import axios from 'axios';
 | 
	
		
			
				|  |  | +import {
 | 
	
		
			
				|  |  | +  getUploadSign,
 | 
	
		
			
				|  |  | +  onFileUpload,
 | 
	
		
			
				|  |  | +  onOnlyFileUpload
 | 
	
		
			
				|  |  | +} from '/src/helpers/oss-file-upload';
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +export default defineComponent({
 | 
	
		
			
				|  |  | +  name: 'upload-file',
 | 
	
		
			
				|  |  | +  props: {
 | 
	
		
			
				|  |  | +    fileList: {
 | 
	
		
			
				|  |  | +      type: String,
 | 
	
		
			
				|  |  | +      default: ''
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +    imageList: {
 | 
	
		
			
				|  |  | +      type: Array,
 | 
	
		
			
				|  |  | +      default: () => []
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +    accept: {
 | 
	
		
			
				|  |  | +      // 支持类型
 | 
	
		
			
				|  |  | +      type: String,
 | 
	
		
			
				|  |  | +      default: '.jpg,.png,.jpeg,.gif'
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +    listType: {
 | 
	
		
			
				|  |  | +      type: String as PropType<'image' | 'image-card'>,
 | 
	
		
			
				|  |  | +      default: 'image-card'
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +    showType: {
 | 
	
		
			
				|  |  | +      type: String as PropType<'default' | 'custom'>,
 | 
	
		
			
				|  |  | +      default: 'default'
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +    showFileList: {
 | 
	
		
			
				|  |  | +      type: Boolean,
 | 
	
		
			
				|  |  | +      default: true
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +    // width: {
 | 
	
		
			
				|  |  | +    //   type: Number,
 | 
	
		
			
				|  |  | +    //   default: 96
 | 
	
		
			
				|  |  | +    // },
 | 
	
		
			
				|  |  | +    // height: {
 | 
	
		
			
				|  |  | +    //   type: Number,
 | 
	
		
			
				|  |  | +    //   default: 96
 | 
	
		
			
				|  |  | +    // },
 | 
	
		
			
				|  |  | +    text: {
 | 
	
		
			
				|  |  | +      type: String as PropType<string>,
 | 
	
		
			
				|  |  | +      default: '上传文件'
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +    size: {
 | 
	
		
			
				|  |  | +      // 文件大小
 | 
	
		
			
				|  |  | +      type: Number as PropType<number>,
 | 
	
		
			
				|  |  | +      default: 5
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +    max: {
 | 
	
		
			
				|  |  | +      type: Number as PropType<number>,
 | 
	
		
			
				|  |  | +      default: 1
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +    multiple: {
 | 
	
		
			
				|  |  | +      type: Boolean as PropType<boolean>,
 | 
	
		
			
				|  |  | +      default: false
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +    disabled: {
 | 
	
		
			
				|  |  | +      type: Boolean as PropType<boolean>,
 | 
	
		
			
				|  |  | +      default: false
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +    tips: {
 | 
	
		
			
				|  |  | +      type: String as PropType<string>,
 | 
	
		
			
				|  |  | +      default: ''
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +    bucketName: {
 | 
	
		
			
				|  |  | +      type: String,
 | 
	
		
			
				|  |  | +      default: 'gyt'
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +    path: {
 | 
	
		
			
				|  |  | +      type: String,
 | 
	
		
			
				|  |  | +      default: ''
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +    fileName: {
 | 
	
		
			
				|  |  | +      type: String,
 | 
	
		
			
				|  |  | +      default: ''
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +    cropper: {
 | 
	
		
			
				|  |  | +      // 是否裁切, 只有图片才支持
 | 
	
		
			
				|  |  | +      type: Boolean as PropType<boolean>,
 | 
	
		
			
				|  |  | +      default: false
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +    options: {
 | 
	
		
			
				|  |  | +      type: Object,
 | 
	
		
			
				|  |  | +      default: () => {
 | 
	
		
			
				|  |  | +        return {
 | 
	
		
			
				|  |  | +          viewMode: 0,
 | 
	
		
			
				|  |  | +          autoCrop: true, //是否默认生成截图框
 | 
	
		
			
				|  |  | +          enlarge: 1, //  图片放大倍数
 | 
	
		
			
				|  |  | +          autoCropWidth: 200, //默认生成截图框宽度
 | 
	
		
			
				|  |  | +          autoCropHeight: 200, //默认生成截图框高度
 | 
	
		
			
				|  |  | +          fixedBox: false, //是否固定截图框大小 不允许改变
 | 
	
		
			
				|  |  | +          previewsCircle: true, //预览图是否是原图形
 | 
	
		
			
				|  |  | +          title: '上传图片'
 | 
	
		
			
				|  |  | +        };
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  },
 | 
	
		
			
				|  |  | +  // readFileInputEventAsArrayBuffer 只会在文件的时间回调
 | 
	
		
			
				|  |  | +  emits: [
 | 
	
		
			
				|  |  | +    'update:fileList',
 | 
	
		
			
				|  |  | +    'close',
 | 
	
		
			
				|  |  | +    'readFileInputEventAsArrayBuffer',
 | 
	
		
			
				|  |  | +    'remove'
 | 
	
		
			
				|  |  | +  ],
 | 
	
		
			
				|  |  | +  setup(props, { emit, expose, slots }) {
 | 
	
		
			
				|  |  | +    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({
 | 
	
		
			
				|  |  | +    //   policy: '',
 | 
	
		
			
				|  |  | +    //   signature: '',
 | 
	
		
			
				|  |  | +    //   key: '',
 | 
	
		
			
				|  |  | +    //   KSSAccessKeyId: '',
 | 
	
		
			
				|  |  | +    //   acl: 'public-read',
 | 
	
		
			
				|  |  | +    //   name: ''
 | 
	
		
			
				|  |  | +    // }) as any;
 | 
	
		
			
				|  |  | +    const state = reactive([]) as any;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    const fileListRef = ref<UploadFileInfo[]>([]);
 | 
	
		
			
				|  |  | +    const initFileList = () => {
 | 
	
		
			
				|  |  | +      if (props.fileList) {
 | 
	
		
			
				|  |  | +        const splitName = props.fileList.split('/');
 | 
	
		
			
				|  |  | +        fileListRef.value = [
 | 
	
		
			
				|  |  | +          {
 | 
	
		
			
				|  |  | +            id: new Date().getTime().toString(),
 | 
	
		
			
				|  |  | +            name: splitName[splitName.length - 1],
 | 
	
		
			
				|  |  | +            status: 'finished',
 | 
	
		
			
				|  |  | +            url: props.fileList
 | 
	
		
			
				|  |  | +          }
 | 
	
		
			
				|  |  | +        ];
 | 
	
		
			
				|  |  | +      } else if (Array.isArray(props.imageList)) {
 | 
	
		
			
				|  |  | +        const list: any = [];
 | 
	
		
			
				|  |  | +        props.imageList.forEach((n: any) => {
 | 
	
		
			
				|  |  | +          const splitName = n.split('/');
 | 
	
		
			
				|  |  | +          list.push({
 | 
	
		
			
				|  |  | +            id: Date.now().toString(),
 | 
	
		
			
				|  |  | +            name: splitName[splitName.length - 1],
 | 
	
		
			
				|  |  | +            status: 'finished',
 | 
	
		
			
				|  |  | +            url: n
 | 
	
		
			
				|  |  | +          });
 | 
	
		
			
				|  |  | +        });
 | 
	
		
			
				|  |  | +        fileListRef.value = list;
 | 
	
		
			
				|  |  | +      } else {
 | 
	
		
			
				|  |  | +        fileListRef.value = [];
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +    initFileList();
 | 
	
		
			
				|  |  | +    watch(
 | 
	
		
			
				|  |  | +      () => props.imageList,
 | 
	
		
			
				|  |  | +      () => {
 | 
	
		
			
				|  |  | +        initFileList();
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    );
 | 
	
		
			
				|  |  | +    watch(
 | 
	
		
			
				|  |  | +      () => props.fileList,
 | 
	
		
			
				|  |  | +      () => {
 | 
	
		
			
				|  |  | +        initFileList();
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    );
 | 
	
		
			
				|  |  | +    const handleClearFile = () => {
 | 
	
		
			
				|  |  | +      uploadRef.value?.clear();
 | 
	
		
			
				|  |  | +      console.log('清空', uploadRef.value);
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +    expose({
 | 
	
		
			
				|  |  | +      handleClearFile
 | 
	
		
			
				|  |  | +    });
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    const CropperModal = ref();
 | 
	
		
			
				|  |  | +    const onBeforeUpload = async (options: any) => {
 | 
	
		
			
				|  |  | +      const file = options.file;
 | 
	
		
			
				|  |  | +      // 文件大小
 | 
	
		
			
				|  |  | +      let isLt2M = true;
 | 
	
		
			
				|  |  | +      if (props.size) {
 | 
	
		
			
				|  |  | +        isLt2M = file.file.size / 1024 / 1024 < props.size;
 | 
	
		
			
				|  |  | +        if (!isLt2M) {
 | 
	
		
			
				|  |  | +          message.error(`文件大小不能超过${props.size}M`);
 | 
	
		
			
				|  |  | +          return false;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      if (!isLt2M) {
 | 
	
		
			
				|  |  | +        return isLt2M;
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +      // 是否裁切
 | 
	
		
			
				|  |  | +      if (props.cropper) {
 | 
	
		
			
				|  |  | +        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);
 | 
	
		
			
				|  |  | +            console.log(CropperModal.value, 'cropper');
 | 
	
		
			
				|  |  | +          }, 100);
 | 
	
		
			
				|  |  | +        });
 | 
	
		
			
				|  |  | +        return false;
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +      try {
 | 
	
		
			
				|  |  | +        btnLoading.value = true;
 | 
	
		
			
				|  |  | +        console.log(props.path, file.file);
 | 
	
		
			
				|  |  | +        const name = file.file.name;
 | 
	
		
			
				|  |  | +        const suffix = name.slice(name.lastIndexOf('.'));
 | 
	
		
			
				|  |  | +        // const months = dayjs().format('MM')
 | 
	
		
			
				|  |  | +        const fileName = `${props.path}${
 | 
	
		
			
				|  |  | +          props.fileName || Date.now() + suffix
 | 
	
		
			
				|  |  | +        }`;
 | 
	
		
			
				|  |  | +        const obj = {
 | 
	
		
			
				|  |  | +          filename: fileName,
 | 
	
		
			
				|  |  | +          bucketName: props.bucketName,
 | 
	
		
			
				|  |  | +          postData: {
 | 
	
		
			
				|  |  | +            filename: fileName,
 | 
	
		
			
				|  |  | +            acl: 'public-read',
 | 
	
		
			
				|  |  | +            key: fileName,
 | 
	
		
			
				|  |  | +            unknowValueField: []
 | 
	
		
			
				|  |  | +          }
 | 
	
		
			
				|  |  | +        };
 | 
	
		
			
				|  |  | +        // const { data } = await policy(obj);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // state.policy = data.policy;
 | 
	
		
			
				|  |  | +        // state.signature = data.signature;
 | 
	
		
			
				|  |  | +        // state.key = fileName;
 | 
	
		
			
				|  |  | +        // state.KSSAccessKeyId = data.kssAccessKeyId;
 | 
	
		
			
				|  |  | +        // state.name = fileName;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // tempFiileBuffer.value = file.file;
 | 
	
		
			
				|  |  | +        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) => {
 | 
	
		
			
				|  |  | +      const item = state.find((c: any) => c.id == options.file.id);
 | 
	
		
			
				|  |  | +      // const url = ossUploadUrl + state.key;
 | 
	
		
			
				|  |  | +      emit('update:fileList', options.file.url);
 | 
	
		
			
				|  |  | +      emit('readFileInputEventAsArrayBuffer', item.tempFiileBuffer);
 | 
	
		
			
				|  |  | +      // options.file.url = url;
 | 
	
		
			
				|  |  | +      visiable.value = false;
 | 
	
		
			
				|  |  | +      btnLoading.value = false;
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +    const onRemove = async (options: any) => {
 | 
	
		
			
				|  |  | +      console.log('🚀 ~ options', options);
 | 
	
		
			
				|  |  | +      emit('update:fileList', '');
 | 
	
		
			
				|  |  | +      emit('remove');
 | 
	
		
			
				|  |  | +      btnLoading.value = false;
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    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 cropperNo = () => {}
 | 
	
		
			
				|  |  | +    // 裁切成功
 | 
	
		
			
				|  |  | +    const cropperOk = async (blob: any) => {
 | 
	
		
			
				|  |  | +      try {
 | 
	
		
			
				|  |  | +        // const months = dayjs().format('MM')
 | 
	
		
			
				|  |  | +        const fileName = `${props.path}${
 | 
	
		
			
				|  |  | +          props.fileName || new Date().getTime() + '.png'
 | 
	
		
			
				|  |  | +        }`;
 | 
	
		
			
				|  |  | +        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);
 | 
	
		
			
				|  |  | +        const formData = {
 | 
	
		
			
				|  |  | +          policy: data.policy,
 | 
	
		
			
				|  |  | +          signature: data.signature,
 | 
	
		
			
				|  |  | +          acl: 'public-read',
 | 
	
		
			
				|  |  | +          key: fileName,
 | 
	
		
			
				|  |  | +          KSSAccessKeyId: data.kssAccessKeyId,
 | 
	
		
			
				|  |  | +          name: fileName,
 | 
	
		
			
				|  |  | +          file: blob
 | 
	
		
			
				|  |  | +        };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        const res = await onOnlyFileUpload(ossUploadUrl, formData);
 | 
	
		
			
				|  |  | +        console.log(res, 'upload');
 | 
	
		
			
				|  |  | +        emit('update:fileList', res);
 | 
	
		
			
				|  |  | +        visiable.value = false;
 | 
	
		
			
				|  |  | +      } catch {
 | 
	
		
			
				|  |  | +        //
 | 
	
		
			
				|  |  | +        // message.error('上传失败');
 | 
	
		
			
				|  |  | +        return false;
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +    return () => (
 | 
	
		
			
				|  |  | +      <div>
 | 
	
		
			
				|  |  | +        <NUpload
 | 
	
		
			
				|  |  | +          ref={uploadRef}
 | 
	
		
			
				|  |  | +          action={ossUploadUrl}
 | 
	
		
			
				|  |  | +          // data={state}
 | 
	
		
			
				|  |  | +          customRequest={onCustomRequest}
 | 
	
		
			
				|  |  | +          v-model:fileList={fileListRef.value}
 | 
	
		
			
				|  |  | +          listType={props.listType}
 | 
	
		
			
				|  |  | +          accept={props.accept}
 | 
	
		
			
				|  |  | +          multiple={props.multiple}
 | 
	
		
			
				|  |  | +          max={props.max}
 | 
	
		
			
				|  |  | +          disabled={props.disabled}
 | 
	
		
			
				|  |  | +          showFileList={props.showFileList}
 | 
	
		
			
				|  |  | +          showPreviewButton
 | 
	
		
			
				|  |  | +          onBeforeUpload={(options: any) => onBeforeUpload(options)}
 | 
	
		
			
				|  |  | +          onFinish={(options: any) => onFinish(options)}
 | 
	
		
			
				|  |  | +          onRemove={(options: any) => onRemove(options)}>
 | 
	
		
			
				|  |  | +          {props.showType === 'default' && props.listType === 'image' && (
 | 
	
		
			
				|  |  | +            <NButton loading={btnLoading.value} type="primary">
 | 
	
		
			
				|  |  | +              {props.text}
 | 
	
		
			
				|  |  | +            </NButton>
 | 
	
		
			
				|  |  | +          )}
 | 
	
		
			
				|  |  | +          {props.showType === 'custom' && slots.custom && slots.custom()}
 | 
	
		
			
				|  |  | +        </NUpload>
 | 
	
		
			
				|  |  | +        {props.tips && (
 | 
	
		
			
				|  |  | +          <p style="font-size: 13px; color: #666; padding-top: 4px;">
 | 
	
		
			
				|  |  | +            {props.tips}
 | 
	
		
			
				|  |  | +          </p>
 | 
	
		
			
				|  |  | +        )}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        <NModal
 | 
	
		
			
				|  |  | +          v-model:show={visiable.value}
 | 
	
		
			
				|  |  | +          preset="dialog"
 | 
	
		
			
				|  |  | +          showIcon={false}
 | 
	
		
			
				|  |  | +          class={['modalTitle background']}
 | 
	
		
			
				|  |  | +          title="上传图片"
 | 
	
		
			
				|  |  | +          style={{ width: '800px' }}>
 | 
	
		
			
				|  |  | +          {/* @cropper-no="error" @cropper-ok="success" */}
 | 
	
		
			
				|  |  | +          <Copper
 | 
	
		
			
				|  |  | +            // ref="CropperModal"
 | 
	
		
			
				|  |  | +            ref={CropperModal}
 | 
	
		
			
				|  |  | +            onClose={() => (visiable.value = false)}
 | 
	
		
			
				|  |  | +            onCropperOk={cropperOk}
 | 
	
		
			
				|  |  | +          />
 | 
	
		
			
				|  |  | +        </NModal>
 | 
	
		
			
				|  |  | +      </div>
 | 
	
		
			
				|  |  | +    );
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +});
 |