From 9d647260680880a02c2fb4dae403bc40c9688acf Mon Sep 17 00:00:00 2001 From: Rairn <958414905@qq.com> Date: Tue, 27 Jun 2023 16:57:19 +0800 Subject: [PATCH] fix(FileSelector): fix uploading --- .../schema-component/antd/preview/Preview.tsx | 31 +++++++++++++++---- .../schema-component/antd/upload/Upload.tsx | 2 +- .../schema-component/antd/upload/shared.ts | 3 +- 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/packages/core/client/src/schema-component/antd/preview/Preview.tsx b/packages/core/client/src/schema-component/antd/preview/Preview.tsx index 948eadea3107..93639118fb90 100644 --- a/packages/core/client/src/schema-component/antd/preview/Preview.tsx +++ b/packages/core/client/src/schema-component/antd/preview/Preview.tsx @@ -1,10 +1,9 @@ import { DeleteOutlined, DownloadOutlined, PlusOutlined } from '@ant-design/icons'; import { connect, mapReadPretty } from '@formily/react'; -import { Upload as AntdUpload, Button, Progress, Space } from 'antd'; +import { Upload as AntdUpload, Button, Progress, Space, UploadFile } from 'antd'; import cls from 'classnames'; -import { css } from '@emotion/css'; import { saveAs } from 'file-saver'; -import React, { useEffect, useState } from 'react'; +import React, { useEffect, useRef, useState } from 'react'; import { useTranslation } from 'react-i18next'; import Lightbox from 'react-image-lightbox'; import 'react-image-lightbox/style.css'; // This only needs to be imported once in your app @@ -33,12 +32,15 @@ export const FileSelector = (props: Props) => { const [photoIndex, setPhotoIndex] = useState(0); const [visible, setVisible] = useState(false); const { t } = useTranslation(); + const internalFileList = useRef([]); // 兼容旧版本 const showSelectButton = selectFile === undefined && quickUpload === undefined; useEffect(() => { - setFileList(toFileList(value)); + const fileList = toFileList(value); + setFileList(fileList); + internalFileList.current = fileList; }, [value]); const handleRemove = (file) => { @@ -114,6 +116,7 @@ export const FileSelector = (props: Props) => { icon={} onClick={() => { handleRemove(file); + internalFileList.current = internalFileList.current.filter((item) => item.uid !== file.uid); }} /> )} @@ -166,9 +169,14 @@ export const FileSelector = (props: Props) => { showUploadList={false} onRemove={handleRemove} onChange={(info) => { + // info.fileList 有 BUG,会导致上传状态一直是 uploading + // 所以这里仿照 antd 源码,自己维护一个 fileList + const list = updateFileList(info.file, internalFileList.current); + internalFileList.current = list; + // 如果不在这里 setFileList 的话,会导致 onChange 只会执行一次 - setFileList([...info.fileList]); - uploadProps.onChange?.(info); + setFileList(toFileList(list)); + uploadProps.onChange?.({ fileList: list }); }} >
{ }; export default Preview; + +function updateFileList(file: UploadFile, fileList: (UploadFile | Readonly)[]) { + const nextFileList = [...fileList]; + const fileIndex = nextFileList.findIndex(({ uid }) => uid === file.uid); + if (fileIndex === -1) { + nextFileList.push(file); + } else { + nextFileList[fileIndex] = file; + } + return nextFileList; +} diff --git a/packages/core/client/src/schema-component/antd/upload/Upload.tsx b/packages/core/client/src/schema-component/antd/upload/Upload.tsx index bff06e635a31..a1fef5fce973 100644 --- a/packages/core/client/src/schema-component/antd/upload/Upload.tsx +++ b/packages/core/client/src/schema-component/antd/upload/Upload.tsx @@ -321,7 +321,7 @@ Upload.DraggerV2 = connect( export default Upload; -export function updateFileList(file: UploadFile, fileList: (UploadFile | Readonly)[]) { +function updateFileList(file: UploadFile, fileList: (UploadFile | Readonly)[]) { const nextFileList = [...fileList]; const fileIndex = nextFileList.findIndex(({ uid }) => uid === file.uid); if (fileIndex === -1) { diff --git a/packages/core/client/src/schema-component/antd/upload/shared.ts b/packages/core/client/src/schema-component/antd/upload/shared.ts index 6bf1c0c0031c..a283a5e94086 100644 --- a/packages/core/client/src/schema-component/antd/upload/shared.ts +++ b/packages/core/client/src/schema-component/antd/upload/shared.ts @@ -2,7 +2,6 @@ import { Field } from '@formily/core'; import { useField } from '@formily/react'; import { reaction } from '@formily/reactive'; import { isArr, isValid, toArr as toArray } from '@formily/shared'; -import { UploadChangeParam } from 'antd/es/upload'; import { UploadFile } from 'antd/es/upload/interface'; import { useEffect } from 'react'; import { useAPIClient } from '../../../api-client'; @@ -167,7 +166,7 @@ export const useUploadValidator = (serviceErrorMessage = 'Upload Service Error') export function useUploadProps({ serviceErrorMessage, ...props }: T) { useUploadValidator(serviceErrorMessage); - const onChange = (param: UploadChangeParam) => { + const onChange = (param: { fileList: any[] }) => { props.onChange?.(normalizeFileList([...param.fileList])); };