import React, { ChangeEvent, useCallback, useEffect, useRef } from 'react'; import { Wrapper, HiddenFileInput } from './style'; import useReducer from 'utils/useReducerHelper'; import { genUUID } from 'utils'; import FileListComponent from './sub-components/FileList'; import { uploadFiles } from './sub-components/helpers'; import message from '../message'; import Button from './types/Button'; import Drop from './types/Drop'; import Picture from './types/Picture'; import { IUpload } from './types'; let cancel: any; export const Upload = function({ type = 'button', label = '上传', width = 416, multiple = false, accept = '*', name = 'file', disabled, onChange, defaultFiles = [], actionUrl = 'https://www.mocky.io/v2/5cc8019d300000980a055e76', propertyPath = '', maxUpload = 5, additionalData = {}, ...rest }: IUpload) { const propertyNameList = propertyPath.split('.').filter(Boolean); const [state, dispatch] = useReducer({ files: [], isDragOver: false, }); useEffect(() => { dispatch({ files: defaultFiles.map(f => ({ uid: genUUID(), name: f.name, data: f.url, isLoading: false, isError: false, progress: 0, })), }); }, []); const fileInput: any = useRef(); const onFileInputChange = useCallback( ({ target: { files } }: ChangeEvent) => { let filesState = Array.from(files as FileList).map(f => ({ uid: genUUID(), name: f.name, file: f, data: null, isLoading: true, isError: false, progress: 0, })); if (filesState.length + state.files.length > maxUpload) { message.warning(`上传文件数超过了最大允许上传数:${maxUpload}个`, 4000); filesState = filesState.slice(0, maxUpload - state.files.length); } cancel = uploadFiles( filesState, actionUrl, name, dispatch, state.files, additionalData, propertyNameList.join('.'), (data: any) => { onChange && onChange(data); } ); }, [state.files, onChange] ); const onRemove = useCallback( (index: number, isLoading: boolean) => { if (isLoading) { cancel[index].cancel('取消上传'); return; } (fileInput.current as HTMLInputElement).value = ''; const files = JSON.parse(JSON.stringify(state.files)); files.splice(index, 1); dispatch({ files }); onChange && onChange(files); }, [state.files, fileInput] ); let child; switch (type) { case 'button': child = (