feat: 大文件上传分块支持重试 (#5258)

This commit is contained in:
liaoxuezhi 2022-08-30 12:49:48 +08:00 committed by RUNZE LU
parent e42f480a4b
commit 39a7397dfc
4 changed files with 62 additions and 30 deletions

View File

@ -5,7 +5,13 @@ import isPlainObject from 'lodash/isPlainObject';
import ImageControl from './InputImage';
import {Payload, ApiObject, ApiString, ActionObject} from 'amis-core';
import {qsstringify, createObject, guid, isEmpty} from 'amis-core';
import {buildApi, isEffectiveApi, normalizeApi, isApiOutdated, isApiOutdatedWithData} from 'amis-core';
import {
buildApi,
isEffectiveApi,
normalizeApi,
isApiOutdated,
isApiOutdatedWithData
} from 'amis-core';
import {Icon} from 'amis-ui';
import {TooltipWrapper, Button} from 'amis-ui';
import DropZone from 'react-dropzone';
@ -1148,8 +1154,13 @@ export default class FileControl extends React.Component<FileProps, FileState> {
fd.append(config.fieldName || 'file', blob, file.name);
return self
._send(file, api, fd, {}, progress =>
updateProgress(task.partNumber, progress)
._send(
file,
api,
fd,
{},
progress => updateProgress(task.partNumber, progress),
3
)
.then(ret => {
state.loaded++;
@ -1188,20 +1199,23 @@ export default class FileControl extends React.Component<FileProps, FileState> {
});
}
_send(
async _send(
file: FileX,
api: ApiObject | ApiString,
data?: any,
options?: object,
onProgress?: (progress: number) => void
onProgress?: (progress: number) => void,
maxRetryLimit = 0
): Promise<Payload> {
const env = this.props.env;
const __ = this.props.translate;
if (!env || !env.fetcher) {
throw new Error('fetcher is required');
}
return env.fetcher(api, data, {
try {
const result = await env.fetcher(api, data, {
method: 'post',
...options,
withCredentials: true,
@ -1217,6 +1231,25 @@ export default class FileControl extends React.Component<FileProps, FileState> {
onProgress(event.loaded / event.total)
: undefined
});
if (!result.ok) {
throw new Error(result.msg || __('File.errorRetry'));
}
return result;
} catch (error) {
if (maxRetryLimit > 0) {
return this._send(
file,
api,
data,
options,
onProgress,
maxRetryLimit - 1
);
}
throw error;
}
}
removeFileCanelExecutor(file: any, execute = false) {
@ -1542,8 +1575,8 @@ export default class FileControl extends React.Component<FileProps, FileState> {
sizeMutable: false,
renderDescription: false,
shouldComponentUpdate: (props: any, prevProps: any) =>
!!isEffectiveApi(props.receiver, props.data) && (
isApiOutdated(
!!isEffectiveApi(props.receiver, props.data) &&
(isApiOutdated(
props.receiver,
prevProps.receiver,
props.data,
@ -1554,7 +1587,6 @@ export default class FileControl extends React.Component<FileProps, FileState> {
prevProps.receiver,
props.data,
prevProps.data
)
)
))
})
export class FileControlRenderer extends FileControl {}