import React, { useState, useEffect } from 'react'; import { Space, Upload, UploadFile, Tag, Button, Table, } from 'antd'; import { PlusOutlined } from '@ant-design/icons'; import { file2Obj } from 'antd/es/upload/utils' import { RcFile } from 'antd/es/upload/interface'; import classNames from 'classnames'; import Style from './web.module.less'; import { WebComponentProps } from 'oak-frontend-base'; import { EntityDict } from '../../../general-app-domain'; import useFeatures from '../../../hooks/useFeatures'; interface NewUploadFile extends UploadFile { id?: string; } type Theme = 'file' | 'image' | 'image-flow' | 'custom'; type ListType = 'text' | 'picture' | 'picture-card'; function getListType(theme: Theme): ListType { const themeMap: Record = { file: 'text', image: 'picture-card', 'image-flow': 'picture', custom: 'text', }; return themeMap[theme]; } export default function render( props: WebComponentProps< EntityDict, 'extraFile', true, { accept?: string; maxNumber?: number; multiple?: boolean; draggable?: boolean; theme?: Theme; tips?: string; beforeUpload?: (file: File) => Promise; disabled?: boolean; style?: Record; className?: string; directory?: boolean; onPreview?: (file: UploadFile) => void; onDownload?: (file: UploadFile) => void; showUploadList?: boolean; children?: JSX.Element; files?: EntityDict['extraFile']['OpSchema'][]; disableInsert?: boolean; }, { onPickByWeb: ( files: UploadFile[], callback?: (file: any, status: string) => void ) => void; onDeleteByWeb: (file: UploadFile) => void; } > ) { const { accept = 'image/*', maxNumber = 20, multiple = maxNumber !== 1, draggable = false, theme = 'image', tips, beforeUpload, disabled, style, className, directory = false, onPreview, onDownload, children, showUploadList = true, files, disableInsert, } = props.data; const { onPickByWeb, onDeleteByWeb } = props.methods; const features = useFeatures(); const [newFiles, setNewFiles] = useState< EntityDict['extraFile']['OpSchema'][] >([]); const [newUploadFiles, setNewUploadFiles] = useState([] as NewUploadFile[]); const listType = getListType(theme); useEffect(() => { if (files && files.length > 0) { setNewFiles(files); } else { setNewFiles([]); } }, [files]); const extraFileToUploadFile = ( extraFile: EntityDict['extraFile']['OpSchema'], ): NewUploadFile => { const filename = extraFile.filename + (extraFile.extension ? `.${extraFile.extension}` : ''); return { id: extraFile.id, url: features.extraFile.getUrl(extraFile), thumbUrl: features.extraFile.getUrl(extraFile), name: filename, fileName: filename, size: extraFile.size!, type: extraFile.fileType, uid: extraFile.id, //upload 组件需要uid来维护fileList // status: 'done', }; } const setNewUploadFilesByStatus = ( file: EntityDict['extraFile']['Schema'], status: string ) => { const { filename, size, id } = file; const file2 = newUploadFiles.find( (ele: NewUploadFile) => ele.name?.includes(filename) && ele.size === size ); if (file2) { Object.assign(file2, { status, id, }); } setNewUploadFiles(newUploadFiles); }; const customDelete = (index: number) => { const arr = [...newUploadFiles]; arr.splice(index, 1); setNewUploadFiles(arr); }; const getUploadButton = () => { if (children) { return children; } if (listType === 'picture-card') { return (
请选择图片
); } return ; }; return ( { if (typeof beforeUpload === 'function') { const result = await beforeUpload(file); if (result) { return false; } } return false; }} multiple={multiple} maxCount={maxNumber} accept={accept} listType={listType} fileList={ theme === 'custom' ? [] : newFiles?.map((ele) => extraFileToUploadFile(ele) ) } onChange={({ file, fileList, event }) => { // id不存在就是file对象 if (!(file as NewUploadFile).id) { if (theme !== 'custom') { onPickByWeb([file2Obj(file as RcFile)]); } else { setNewUploadFiles([file2Obj(file as RcFile)]); } } }} onRemove={(file) => { onDeleteByWeb(file); }} onPreview={onPreview} onDownload={onDownload} > {disableInsert ? null : getUploadButton()} {tips && ( {tips} )} {theme === 'custom' && ( <> index + 1, width: 100, }, { dataIndex: 'name', title: '文件名', }, { dataIndex: 'size', title: '文件大小', render: (value, record, index) => { return features.extraFile.formatBytes( value as number ); }, }, { dataIndex: 'status', title: '状态', render: (value, record, index) => { let cpn: any; switch (value) { case 'success': cpn = ( success ); break; case 'uploading': cpn = ( uploading ); break; default: cpn = ( waiting ); break; } return cpn; }, }, { dataIndex: 'op', width: 300, title: '操作', align: 'center', render: (value, record, index) => { // 只处理state的文件 这时候可以直接删除 return ( <> {!record.id && ( )} ); }, fixed: 'right', }, ]} />
)} ); }