138 lines
3.6 KiB
TypeScript
138 lines
3.6 KiB
TypeScript
import { MyProFormFieldProps } from '@/common';
|
|
import { Apis } from '@/gen/Apis';
|
|
import { PlusOutlined, UploadOutlined } from '@ant-design/icons';
|
|
import { Button, Modal, Upload, UploadFile, UploadProps } from 'antd';
|
|
import { RcFile } from 'antd/es/upload';
|
|
import axios from 'axios';
|
|
import { useSetState } from 'react-use';
|
|
|
|
type MyType = {
|
|
uploadType?: 'image' | 'video' | 'audio' | 'file';
|
|
max?: number;
|
|
} & UploadProps<any> &
|
|
MyProFormFieldProps<UploadFile[]>;
|
|
|
|
const getBase64 = (file: RcFile): Promise<string> =>
|
|
new Promise((resolve, reject) => {
|
|
const reader = new FileReader();
|
|
reader.readAsDataURL(file);
|
|
reader.onload = () => resolve(reader.result as string);
|
|
reader.onerror = (error) => reject(error);
|
|
});
|
|
|
|
export function MyUploadImages({
|
|
value,
|
|
onChange,
|
|
uploadType = 'image',
|
|
max = 1,
|
|
...rest
|
|
}: MyType) {
|
|
const [preview, setPreview] = useSetState<{
|
|
open: boolean;
|
|
image: string;
|
|
title: string;
|
|
}>({
|
|
open: false,
|
|
image: '',
|
|
title: '',
|
|
});
|
|
|
|
console.log('MyUploadImages');
|
|
|
|
const handleCancel = () => setPreview({ open: false });
|
|
|
|
const handlePreview = async (file: UploadFile) => {
|
|
if (!file.url && !file.preview) {
|
|
file.preview = await getBase64(file.originFileObj as RcFile);
|
|
}
|
|
|
|
setPreview({
|
|
open: true,
|
|
image: file.url || file.preview,
|
|
title: file.name || file.url!.substring(file.url!.lastIndexOf('/') + 1),
|
|
});
|
|
};
|
|
|
|
const handleChange: UploadProps['onChange'] = ({ fileList: newFileList }) => {
|
|
console.log('newFileList', newFileList);
|
|
const _newFileList: UploadFile<any>[] = newFileList.map((file) => {
|
|
if (!file.percent) return file;
|
|
return {
|
|
name: file.name,
|
|
status: file.status,
|
|
uid: file.uid,
|
|
url: file.response,
|
|
size: file.size ?? 0,
|
|
type: file.type ?? '',
|
|
};
|
|
});
|
|
onChange?.(_newFileList);
|
|
};
|
|
|
|
const uploadButton =
|
|
uploadType === 'image' ? (
|
|
<div>
|
|
<PlusOutlined />
|
|
</div>
|
|
) : (
|
|
<Button icon={<UploadOutlined />}>点击上传</Button>
|
|
);
|
|
|
|
const customRequest = ({ file, onError, onProgress, onSuccess }: any) => {
|
|
Apis.Common.Auth.PreUpload({
|
|
filename: file.name,
|
|
alc: 'public-read',
|
|
}).then(async (res) => {
|
|
axios
|
|
.put(res.data.url, file, {
|
|
headers: res.data.headers,
|
|
onUploadProgress: ({ total, loaded }) => {
|
|
if (total)
|
|
onProgress(
|
|
{ percent: Math.round((loaded / total) * 100).toFixed(2) },
|
|
file,
|
|
);
|
|
},
|
|
})
|
|
.then(({ data: response }) => {
|
|
console.log('response', response);
|
|
if (response.errorMessage) {
|
|
onError(response, file);
|
|
} else {
|
|
onSuccess(res.data.url.split('?')[0], file);
|
|
}
|
|
});
|
|
});
|
|
|
|
return {
|
|
abort() {
|
|
console.log('upload progress is aborted.');
|
|
},
|
|
};
|
|
};
|
|
|
|
return (
|
|
<>
|
|
<Upload
|
|
accept={uploadType === 'image' ? 'image/*' : '*'}
|
|
fileList={value}
|
|
listType={uploadType === 'image' ? 'picture-card' : 'text'}
|
|
onPreview={handlePreview}
|
|
onChange={handleChange}
|
|
customRequest={customRequest}
|
|
{...rest}
|
|
>
|
|
{!value?.length || (value && value.length < max) ? uploadButton : null}
|
|
</Upload>
|
|
<Modal
|
|
open={preview.open}
|
|
title={preview.title}
|
|
footer={null}
|
|
onCancel={handleCancel}
|
|
>
|
|
<img alt="preview" style={{ width: '100%' }} src={preview.image} />
|
|
</Modal>
|
|
</>
|
|
);
|
|
}
|