73 lines
1.8 KiB
TypeScript

import { message } from '@/modules/message';
import { useImperativeHandle, useRef, forwardRef } from 'react';
import { uploadFileChunked } from '@kevisual/resources/index.ts';
export type FileType = {
name: string;
size: number;
lastModified: number;
webkitRelativePath: string; // 包含name
};
const beforeUpload = (file: any) => {
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 filename = `avatar.${endType}`;
const res = (await uploadFileChunked(file, {
isPublic: true,
filename,
})) as any;
console.log('res', res);
if (res?.code === 200) {
const resource = res.data?.resource;
props?.onChange?.(resource);
} 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>
);
});