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, default: '上传文件' }, size: { // 文件大小 type: Number as PropType, default: 5 }, max: { type: Number as PropType, default: 1 }, multiple: { type: Boolean as PropType, default: false }, disabled: { type: Boolean as PropType, default: false }, tips: { type: String as PropType, default: '' }, bucketName: { type: String, default: 'gyt' }, path: { type: String, default: '' }, fileName: { type: String, default: '' }, cropper: { // 是否裁切, 只有图片才支持 type: Boolean as PropType, 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(false); const btnLoading = ref(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([]); 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 () => (
onBeforeUpload(options)} onFinish={(options: any) => onFinish(options)} onRemove={(options: any) => onRemove(options)}> {props.showType === 'default' && props.listType === 'image' && ( {props.text} )} {props.showType === 'custom' && slots.custom && slots.custom()} {props.tips && (

{props.tips}

)} {/* @cropper-no="error" @cropper-ok="success" */} (visiable.value = false)} onCropperOk={cropperOk} />
); } });