import React from 'react'; import { Spin, Typography, Upload, UploadProps } from 'antd'; import { RcFile, UploadChangeParam, UploadFile } from 'antd/es/upload'; import { FiPlusCircle } from 'react-icons/fi'; import { useRequest } from 'ahooks'; import { cn } from '../../utils/cn'; import { uploadFileByBase64 } from '@/utils/image'; import locale from '@/locale'; const { Text } = Typography; export type UploadFileAttrs = { url: string; width: number; height: number; }; export type UploadChangeInfo = UploadChangeParam>; export type UploadRequestOption = Parameters< NonNullable['customRequest']> >['0']; export type UploadBoxProps = Omit< Partial>, 'children' > & { err?: React.ReactNode; visible?: boolean; hidden?: boolean; icon?: React.ReactNode; iconClassName?: string; wordings?: React.ReactNode; wordingsClassName?: string; className?: string; children?: (x: { loading: boolean; error: Error | null }) => React.ReactNode; }; export function UploadBox({ children, err, icon, iconClassName, wordings, wordingsClassName, className, beforeUpload, customRequest = uploadFileByBase64, ...rest }: UploadBoxProps) { const { runAsync: check, error: e1 } = useRequest( async (file: RcFile) => { return beforeUpload?.(file, [file]) ?? true; }, { manual: true, }, ); const { runAsync: upload, error: e2, loading, } = useRequest( async (params: UploadRequestOption) => { if (loading) { return; } await customRequest?.(params); }, { manual: true, }, ); const e = e1 || e2; const UploadWrapper = children ? Upload : Upload.Dragger; const node = children?.({ loading, error: e || null }); return ( {node || ( <> {loading ? ( ) : (

{icon ?? }

{wordings ?? locale.t('uploadTip')}

)} {err || e ? ( {err || e?.message} ) : null} )}
); }