Files
kevisual-center-v1/src/pages/user/module/FileUpload.tsx
2025-02-28 15:31:32 +08:00

81 lines
2.1 KiB
TypeScript

import { message } from '@/modules/message';
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>
);
});