import { computed, getCurrentInstance, Ref } from 'vue' import axios from 'axios' import { get } from 'lodash-es' export function useUpload (accept?: Ref, size?: Ref) { const instance = getCurrentInstance() const globalUpload = computed(() => instance?.appContext.config.globalProperties.upload) const props = instance?.props const mergeConfig = computed(() => { return Object.assign({}, globalUpload.value || {}, props?.upload) }) const useAccept = computed(() => accept?.value || props?.accept as string) const useSize = computed(() => size?.value || props?.size as number) const errorCallback = props?.errorCallback async function uploadHandler (files: any, progress?: Function) { return new Promise((resolve, reject) => { const message = accessFile(files) if (message) { return reject(message) } const formData = new FormData() mergeConfig.value.data.map(item => { if (item.value === 'file') { if (Array.isArray(files)) { files.map(f => { formData.append(item.key, f) }) } else { formData.append(item.key, files) } } }) let headers: any = {} if (mergeConfig.value.headers && typeof mergeConfig.value.headers === 'function') { headers = mergeConfig.value.headers() } else { headers = mergeConfig.value.headers } const config: any = { headers: headers } if (progress) { config.onUploadProgress = progress } axios.post(mergeConfig.value.path, formData, config).then(res => { const { data } = res const { status, message } = data if (status === 200) { let item: any = {} if (!mergeConfig.value.listPath) { item = data } else { item = get(data, mergeConfig.value.listPath) } item.name = item[mergeConfig.value.nameKey] item.url = `${ mergeConfig.value.domain || '' }${ item[mergeConfig.value.urlKey] }` resolve(item) } else if (errorCallback && typeof errorCallback === 'function') { errorCallback(message) } else { reject('上传失败') } }).catch(err => { if (errorCallback && typeof errorCallback === 'function') { errorCallback(err) } else { reject(err) } }) }) } function checkType (fileName: string) { if (!useAccept.value) return true const index = fileName.lastIndexOf('.') const extension = fileName.substring(index).toLowerCase() const allowedType = useAccept.value.split(',') return allowedType.indexOf(extension) >= 0 } function accessFile (files: any) { if (!files) { return '请选择文件' } if (props?.multiple) { let accessNumber = 0 for (let i = 0; i < files.length; i++) { const file = files[i] const check = checkType(file.name) if (!check) { return `文件${ files.name }格式不支持!` } if (files.size > useSize.value * 1024 * 1024) { return `文件${ files.name }过大!` } accessNumber++ } if (accessNumber === files.length) { return '' } } else { const check = checkType(files.name) if (!check) { return `文件${ files.name }格式不支持!` } if (files.size > useSize.value * 1024 * 1024) { return `文件${ files.name }过大!` } } return '' } return { uploadHandler, mergeConfig } }