import { get, defaults, findIndex } from 'lodash-es';
import { ref } from 'vue';
import { ElMessage } from 'element-plus';
type keyPath = Array<string> | string;
type uOptions = { limit: number };
export function useUpload<T>(
uApi: (params: any, formData: any) => Promise<T>,
dApi?: (id: string) => Promise<T>,
uOptions?: uOptions,
uParams: object | (() => object) = {},
// format: (data: { fileName: string; suffix: string }) => fFIle,
options: {
path?: { data?: keyPath };
} = {}
) {
defaults(options, {
path: {
data: 'data.result',
},
immediate: false,
});
// defaults(format, (data: bFile) => {
// return { ...data, name: `${data.fileName}${data.suffix}`, type: 'image' };
// });
// 统一数据格式
const format = (data: any): any => {
const type = getFileType(data.suffix);
return { ...data, name: `${data.fileName}${data.suffix}`, type };
};
const getFileType = (suffix: string) => {
const suffixType: any = {
'.jpg': 'image',
'.jpeg': 'image',
'.bmp': 'image',
'.png': 'image',
'.webp': 'image',
'.mp4': 'video',
'.webm': 'video',
'.mp3': 'audio',
};
return suffixType[suffix];
};
let uFileList = ref<any>([]);
// 初始化文件列表
const initFileList = (fileList: Array<any> = []) => {
fileList = fileList || [];
uFileList.value = fileList.map((file) => format(file));
};
// 文件上传
const onChange = async (uploadFile: any) => {
const requestData = {};
if (uParams) {
if (typeof uParams === 'function') {
Object.assign(requestData, uParams());
} else {
Object.assign(requestData, uParams);
}
}
const uid = uploadFile.uid;
let formData = new FormData();
formData.append('files', uploadFile.raw);
try {
const res = await uApi(requestData, formData);
const result = get(res, options!.path?.data, []);
if (!result) return; // 没有返回数据就不更新本地文件列表
// 上传成功文件用新数据更新文件列表
const curIndex = findIndex(uFileList.value, function (o: { uid: string }) {
return o.uid == uid;
});
uFileList.value.splice(curIndex, 1, format(result[0]));
} catch (error: any) {
// 上传不成功移除文件
const curIndex = findIndex(uFileList.value, function (o: { uid: string }) {
return o.uid == uid;
});
uFileList.value.splice(curIndex, 1);
}
};
// 文件移除
const onRemove = async (file: { id: string }) => {
if (!dApi) return;
await dApi(file.id);
};
// 文件异常处理
const onExceed = (files: any, uploadFiles: any) => {
const total = files.length + uploadFiles.length;
if (total > uOptions.limit) {
ElMessage.error(`最多只能上传 ${uOptions.limit} 个文件,请删除后再上传!`);
}
};
return { fileList: uFileList, initFileList, onChange, onRemove, onExceed };
}