import { Upload as AntdUpload, UploadProps, ConfigProvider } from 'antd'; import React, { useContext, useMemo, useState } from 'react'; import './index.less'; import classNames from 'classnames'; import { Icon } from '../Icon'; import { RcFile, ShowUploadListInterface, UploadFileStatus, UploadListType, } from 'antd/lib/upload/interface'; import { DraggerProps } from 'antd/lib/upload'; import { Modal } from 'antd'; const { Dragger: AntDragger } = AntdUpload; interface UploadExtraProps { pictureCardTips?: string; } export interface UploadFile { uid: string; size?: number; name: string; fileName?: string; lastModified?: number; lastModifiedDate?: Date; url?: string; status?: UploadFileStatus; percent?: number; thumbUrl?: string; crossOrigin?: React.ImgHTMLAttributes['crossOrigin']; originFileObj?: RcFile; response?: T; error?: any; linkProps?: any; type?: string; xhr?: T; preview?: string; } interface RrenderItemProps { originNode: React.ReactElement< any, string | React.JSXElementConstructor >; file: UploadFile; fileList: UploadFile[]; actions: { download: () => void; preview: () => void; remove: () => void; }; listType: UploadListType; } const statusIcon = { success: { color: 'var(--green-6)', icon: 'CheckOnCircleOne', }, error: { color: 'var(--red-6)', icon: 'AttentionCircleOne', }, uploading: { color: 'var(--primary-6)', icon: 'Loading', loading: true, }, done: { color: 'var(--green-6)', icon: 'CheckOnCircleOne', }, }; const pngIcons = { excel: ( ), xlsx: ( ), xls: ( ), png: ( ), jpeg: ( ), pdf: ( ), ppt: ( ), pptx: ( ), doc: ( ), docx: ( ), other: ( ), }; const renderIcons = { text: { error: pngIcons, done: pngIcons, uploading: pngIcons, }, 'picture-card': { error: , }, }; const Upload = (props: UploadProps & UploadExtraProps) => { // 为了与 antd 的生态保持兼容性,我们要求必须要使用 `.@{ant-prefix}` 变量来生成类名 const { getPrefixCls } = useContext(ConfigProvider.ConfigContext); const prefixCls = getPrefixCls('btri-upload'); const { listType = 'text', pictureCardTips } = props; const renderItem = ({ originNode, file, fileList, actions, listType, }: RrenderItemProps) => { const loadingCom = (
上传中 {file.percent?.toFixed(0)}%
); const Items: any = { text: { showOriginNodeInLoading: true, statusIcon, }, picture: { showOriginNodeInLoading: true, }, 'picture-card': { showOriginNodeInLoading: false, loadingCom, }, }; return (
{Items[listType].showOriginNodeInLoading ? originNode : file.status !== 'uploading' && originNode} {listType === 'text' && statusIcon[file.status] && ( )} {file.status === 'uploading' && Items[listType]?.loadingCom}
); }; const [visible, setVisible] = useState(false); const [previewImage, setPreviewImage] = useState(''); const _showUploadList = useMemo(() => { let resList: boolean | ShowUploadListInterface = false; const defaultList = { removeIcon: () => { return ( ); }, previewIcon: (file) => { return ( ); }, downloadIcon: ( ), }; switch (props.showUploadList) { case false: resList = false; break; case true: resList = defaultList; default: resList = { ...defaultList, ...(props.showUploadList as ShowUploadListInterface), }; break; } return resList; }, [props.showUploadList, listType]); return ( <> { setPreviewImage(file.thumbUrl || file.url); (file.thumbUrl || file.url) && setVisible(true); }} iconRender={(file, listType) => { return ( renderIcons[listType]?.[file.status]?.[file.name.split('.')[1]] || renderIcons[listType]?.[file.status]?.['other'] || renderIcons[listType]?.[file.status] ); }} itemRender={(originNode, file, fileList, actions) => renderItem({ originNode, file, fileList, actions, listType }) } {...props} className={classNames(`${prefixCls}-box`, props.className)} showUploadList={_showUploadList} > {props.children} {listType === 'picture-card' && (
{pictureCardTips}
)}
{ setVisible(false); }} width="60%" className="btri_upload_preview_modal" > ); }; Upload.Dragger = (props: DraggerProps) => { const { getPrefixCls } = useContext(ConfigProvider.ConfigContext); const prefixCls = getPrefixCls('btri-upload-dragger'); const _showUploadList = useMemo(() => { let resList: boolean | ShowUploadListInterface = false; const defaultList = { removeIcon: () => { return ( ); }, previewIcon: (file) => { return ( {}} iconName="PreviewOpen" style={{ fontSize: '20px', color: 'var(--gray-7)', }} > ); }, downloadIcon: ( ), }; switch (props.showUploadList) { case false: resList = false; break; case true: resList = defaultList; default: resList = { ...defaultList, ...(props.showUploadList as ShowUploadListInterface), }; break; } return resList; }, [props.showUploadList]); return ( { return (
{originNode}
); }} iconRender={(file, listType) => { return ( renderIcons[listType]?.[file.status]?.[file.name.split('.')[1]] || renderIcons[listType]?.[file.status]?.['other'] || renderIcons[listType]?.[file.status] ); }} {...props} showUploadList={_showUploadList} className={classNames(`${prefixCls}-box`, props.className)} > {props.children || (
点击上传   /  拖拽到此区域内
)}
); }; Upload.LIST_IGNORE = AntdUpload.LIST_IGNORE; export { Upload };