73 lines
1.8 KiB
TypeScript
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>
|
|
);
|
|
});
|