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