Skip to content

Commit

Permalink
feat: support customize request method
Browse files Browse the repository at this point in the history
  • Loading branch information
xiaoming99999 committed Dec 20, 2021
1 parent 673d0e7 commit 5bc70be
Show file tree
Hide file tree
Showing 3 changed files with 137 additions and 8 deletions.
67 changes: 67 additions & 0 deletions src/upload/_example/request-method.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import React, { useCallback, useState } from 'react';
import { Radio, Upload } from 'tdesign-react';

const RequestMethod = () => {
const [files, setFiles] = useState([]);
const [uploadMethod, setUploadMethod] = useState('requestSuccessMethod');

// customize upload `file`, if success, return url
const requestSuccessMethod = useCallback(
(file) =>
new Promise((resolve) => {
// set file.percent for mock upload progress
// eslint-disable-next-line no-param-reassign
file.percent = 0;
let timer = setTimeout(() => {
// resolve 参数为关键代码
resolve({
status: 'success',
response: { url: 'https://tdesign.gtimg.com/site/avatar.jpg' },
});
// eslint-disable-next-line no-param-reassign
file.percent = 100;
clearTimeout(timer);
timer = null;
}, 520);
}),
[],
);

// customize upload `file`, if fail, return error message
const requestFailMethod = useCallback(
() =>
new Promise((resolve) => {
// resolve 参数为关键代码
resolve({
status: 'fail',
error: 'for some reason, upload fail',
});
}),
[],
);

const onChangeUploadMethod = useCallback((value) => {
setUploadMethod(value);
setFiles([]);
}, []);

return (
<div className="tdesign-demo-block-column-large">
<div>
<Radio.Group variant="default-filled" value={uploadMethod} onChange={onChangeUploadMethod}>
<Radio.Button value="requestSuccessMethod">上传成功示例</Radio.Button>
<Radio.Button value="requestFailMethod">上传失败示例</Radio.Button>
</Radio.Group>
</div>

<Upload
files={files}
onChange={setFiles}
requestMethod={uploadMethod === 'requestSuccessMethod' ? requestSuccessMethod : requestFailMethod}
tips="自定义上传方法需要返回成功或失败信息"
/>
</div>
);
};

export default RequestMethod;
4 changes: 2 additions & 2 deletions src/upload/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -258,8 +258,8 @@ export interface UploadRemoveContext {
}

export interface SuccessContext {
e: ProgressEvent;
e?: ProgressEvent;
file: UploadFile;
fileList: UploadFile[];
fileList?: UploadFile[];
response: any;
}
74 changes: 68 additions & 6 deletions src/upload/upload.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,14 @@ import FlowList from './themes/flow-list/index';
import BooleanRender from './boolean-render';
import { finishUpload, isSingleFile, updateFileList } from './util';
import { FlowRemoveContext, TdUploadFile, UploadProps } from './types';
import { ProgressContext, SuccessContext, TdUploadProps, UploadFile, UploadRemoveContext } from './type';
import {
ProgressContext,
RequestMethodResponse,
SuccessContext,
TdUploadProps,
UploadFile,
UploadRemoveContext,
} from './type';
import useDefaultValue from './hooks/useDefaultValue';

const urlCreator = window.webkitURL || window.URL;
Expand Down Expand Up @@ -45,6 +52,7 @@ const Upload: React.ForwardRefRenderFunction<unknown, UploadProps> = (props, ref
onRemove,
onDragenter,
onDragleave,
requestMethod,
files: fileList = [],
} = useDefaultValue<Array<TdUploadFile>, UploadProps>(props, []);

Expand Down Expand Up @@ -92,7 +100,7 @@ const Upload: React.ForwardRefRenderFunction<unknown, UploadProps> = (props, ref
};

const onError = useCallback(
(options: { event: ProgressEvent; file: TdUploadFile; response?: any }) => {
(options: { event?: ProgressEvent; file: TdUploadFile; response?: any }) => {
const { event, file, response } = options;
file.status = 'fail';
let res = response;
Expand Down Expand Up @@ -156,19 +164,41 @@ const Upload: React.ForwardRefRenderFunction<unknown, UploadProps> = (props, ref
[fileList, onChange, onProgress],
);

const handleRequestMethod = useCallback(
(file: UploadFile) => {
if (typeof requestMethod !== 'function') {
console.warn('TDesign Upload Warn: `requestMethod` must be a function.');
return;
}
requestMethod(file).then((res: RequestMethodResponse) => {
if (!handleRequestMethodResponse(res)) return;
if (res.status === 'success') {
return handleSuccess({ file, response: res.response });
}
if (res.status === 'fail') {
const r = res.response || {};
onError({ file, response: { ...r, error: res.error } });
}
});
},
[handleSuccess, onError, requestMethod],
);
const upload = useCallback(
(uploadFile: TdUploadFile): Promise<void> => {
async (uploadFile: TdUploadFile): Promise<void> => {
const file = { ...uploadFile };
if (file.status !== 'waiting') {
return;
}
if (!action) {
console.error('TDesign Upload Error: action is required.');
if (!action && !requestMethod) {
console.error('TDesign Upload Error: action or requestMethod is required.');
return;
}
setErrorMsg('');
// eslint-disable-next-line no-param-reassign
file.status = 'progress';
if (requestMethod) {
return handleRequestMethod(file);
}
request({
action,
data,
Expand All @@ -181,9 +211,41 @@ const Upload: React.ForwardRefRenderFunction<unknown, UploadProps> = (props, ref
onSuccess: handleSuccess,
});
},
[action, data, handleProgress, handleSuccess, headers, name, onError, withCredentials],
[
action,
data,
handleProgress,
handleRequestMethod,
handleSuccess,
headers,
name,
onError,
requestMethod,
withCredentials,
],
);

function handleRequestMethodResponse(res: RequestMethodResponse) {
if (!res) {
console.error('TDesign Upload Error: `requestMethodResponse` is required.');
return false;
}
if (!res.status) {
console.error(
'TDesign Upload Error: `requestMethodResponse.status` is missing, which value is `success` or `fail`',
);
return false;
}
if (!['success', 'fail'].includes(res.status)) {
console.error('TDesign Upload Error: `requestMethodResponse.status` must be `success` or `fail`');
return false;
}
if (res.status === 'success' && (!res.response || !res.response.url)) {
console.warn('TDesign Upload Warn: `requestMethodResponse.response.url` is required, when `status` is `success`');
}
return true;
}

const formatFiles = (files: File[] = []): TdUploadFile[] =>
files.map((fileRaw) => {
const file = typeof format === 'function' ? format(fileRaw) : fileRaw;
Expand Down

0 comments on commit 5bc70be

Please sign in to comment.