import type { Ref } from 'vue';
|
|
import type { AxiosProgressEvent } from '#/api/infra/file';
|
|
import { computed, unref } from 'vue';
|
|
import { useAppConfig } from '@vben/hooks';
|
import { $t } from '@vben/locales';
|
|
import { requestClient } from '#/api/request';
|
|
const { apiURL } = useAppConfig(import.meta.env, import.meta.env.PROD);
|
|
/**
|
* 上传类型
|
*/
|
enum UPLOAD_TYPE {
|
// 客户端直接上传(只支持S3服务)
|
CLIENT = 'client',
|
// 客户端发送到后端上传
|
SERVER = 'server',
|
}
|
|
/**
|
* 上传类型钩子函数
|
* @param acceptRef 接受的文件类型
|
* @param helpTextRef 帮助文本
|
* @param maxNumberRef 最大文件数量
|
* @param maxSizeRef 最大文件大小
|
* @returns 文件类型限制和帮助文本的计算属性
|
*/
|
export function useUploadType({
|
acceptRef,
|
helpTextRef,
|
maxNumberRef,
|
maxSizeRef,
|
}: {
|
acceptRef: Ref<string[]>;
|
helpTextRef: Ref<string>;
|
maxNumberRef: Ref<number>;
|
maxSizeRef: Ref<number>;
|
}) {
|
// 文件类型限制
|
const getAccept = computed(() => {
|
const accept = unref(acceptRef);
|
if (accept && accept.length > 0) {
|
return accept;
|
}
|
return [];
|
});
|
const getStringAccept = computed(() => {
|
return unref(getAccept)
|
.map((item) => {
|
return item.indexOf('/') > 0 || item.startsWith('.')
|
? item
|
: `.${item}`;
|
})
|
.join(',');
|
});
|
|
// 支持jpg、jpeg、png格式,不超过2M,最多可选择10张图片,。
|
const getHelpText = computed(() => {
|
const helpText = unref(helpTextRef);
|
if (helpText) {
|
return helpText;
|
}
|
const helpTexts: string[] = [];
|
|
const accept = unref(acceptRef);
|
if (accept.length > 0) {
|
helpTexts.push($t('ui.upload.accept', [accept.join(',')]));
|
}
|
|
const maxSize = unref(maxSizeRef);
|
if (maxSize) {
|
helpTexts.push($t('ui.upload.maxSize', [maxSize]));
|
}
|
|
const maxNumber = unref(maxNumberRef);
|
if (maxNumber && maxNumber !== Infinity) {
|
helpTexts.push($t('ui.upload.maxNumber', [maxNumber]));
|
}
|
return helpTexts.join(',');
|
});
|
return { getAccept, getStringAccept, getHelpText };
|
}
|
|
/**
|
* 上传钩子函数
|
* @param directory 上传目录
|
* @returns 上传 URL 和自定义上传方法
|
*/
|
export function useUpload(directory?: string) {
|
// 后端上传地址
|
const uploadUrl = getUploadUrl();
|
// 是否使用前端直连上传
|
const isClientUpload =
|
UPLOAD_TYPE.CLIENT === import.meta.env.VITE_UPLOAD_TYPE;
|
// 重写上传方法,统一走 system 模块 Storage API
|
async function httpRequest(
|
file: File,
|
onUploadProgress?: AxiosProgressEvent,
|
) {
|
const formData = new FormData();
|
formData.append('files', file);
|
const blobs = await requestClient.post('/system/storage-blob/upload', formData, {
|
onUploadProgress,
|
});
|
const blob = Array.isArray(blobs) ? blobs[0] : blobs;
|
return blob ? { url: blob.url || blob.previewURL, name: blob.name, id: blob.id } : {};
|
}
|
|
return {
|
uploadUrl,
|
httpRequest,
|
};
|
}
|
|
/**
|
* 获得上传 URL(兼容旧版,实际调用走 httpRequest)
|
*/
|
export function getUploadUrl(): string {
|
return `${apiURL}/system/storage-blob/upload`;
|
}
|