feat: upload files
This commit is contained in:
@@ -51,14 +51,19 @@ export const AvatarUpload = () => {
|
||||
console.log('file', file);
|
||||
return '';
|
||||
};
|
||||
const customAction = (file) => {
|
||||
console.log('file', file);
|
||||
}
|
||||
return (
|
||||
<Flex gap='middle' wrap>
|
||||
<Upload
|
||||
name='avatar'
|
||||
listType='picture-circle'
|
||||
className='avatar-uploader'
|
||||
multiple={false}
|
||||
showUploadList={false}
|
||||
action={onAciton}
|
||||
customRequest={customAction}
|
||||
beforeUpload={beforeUpload}
|
||||
onChange={handleChange}>
|
||||
{imageUrl ? <img src={imageUrl} alt='avatar' style={{ width: '100%' }} /> : uploadButton}
|
||||
|
||||
80
src/pages/user/module/FileUpload.tsx
Normal file
80
src/pages/user/module/FileUpload.tsx
Normal file
@@ -0,0 +1,80 @@
|
||||
import { message } from 'antd';
|
||||
import { useImperativeHandle, useRef, forwardRef } from 'react';
|
||||
import type { GetProp, UploadProps } from 'antd';
|
||||
type FileTypeOrg = Parameters<GetProp<UploadProps, 'beforeUpload'>>[0];
|
||||
|
||||
export type FileType = {
|
||||
name: string;
|
||||
size: number;
|
||||
lastModified: number;
|
||||
webkitRelativePath: string; // 包含name
|
||||
};
|
||||
|
||||
const beforeUpload = (file: FileTypeOrg) => {
|
||||
const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
|
||||
if (!isJpgOrPng) {
|
||||
message.error('You can only upload JPG/PNG file!');
|
||||
}
|
||||
const isLt2M = file.size / 1024 / 1024 < 2;
|
||||
if (!isLt2M) {
|
||||
message.error('Image must smaller than 2MB!');
|
||||
}
|
||||
return isJpgOrPng && isLt2M;
|
||||
};
|
||||
type Props = {
|
||||
onChange: (path: string) => void;
|
||||
};
|
||||
export const FileUpload = forwardRef<any, Props>((props, ref) => {
|
||||
const inputRef = useRef<HTMLInputElement | null>(null);
|
||||
const onChange = async (e) => {
|
||||
if (!beforeUpload(e.target.files[0])) {
|
||||
return;
|
||||
}
|
||||
console.log(e.target.files);
|
||||
const file = e.target.files[0];
|
||||
const endType = file.name.split('.').pop();
|
||||
const formData = new FormData();
|
||||
formData.append('file', file, `avatar.${endType}`); // 保留文件夹路径
|
||||
const res = await fetch('/api/upload', {
|
||||
method: 'POST',
|
||||
body: formData, //
|
||||
headers: {
|
||||
Authorization: 'Bearer ' + localStorage.getItem('token'),
|
||||
},
|
||||
}).then((res) => res.json());
|
||||
if (res?.code === 200) {
|
||||
console.log('res', res);
|
||||
//
|
||||
const [file] = res.data;
|
||||
const { path } = file || {};
|
||||
props?.onChange?.(path);
|
||||
//
|
||||
} else {
|
||||
message.error(res.message || 'Request failed');
|
||||
}
|
||||
// 清理之前上传的文件
|
||||
e.target.value = '';
|
||||
};
|
||||
// 把ref 传递到上层
|
||||
useImperativeHandle(ref, () => {
|
||||
return {
|
||||
open: () => {
|
||||
inputRef.current?.click();
|
||||
},
|
||||
};
|
||||
});
|
||||
return (
|
||||
<div>
|
||||
<input
|
||||
style={{
|
||||
display: 'none',
|
||||
}}
|
||||
ref={inputRef}
|
||||
accept='image/*'
|
||||
type='file'
|
||||
multiple={false}
|
||||
onChange={onChange}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
Reference in New Issue
Block a user