Files
kevisual-center/src/pages/apps/modules/FileUpload.tsx
2026-02-22 01:32:26 +08:00

112 lines
3.1 KiB
TypeScript

'use client';
import { Button } from '@/components/ui/button';
import { useCallback, useRef } from 'react';
import { useAppVersionStore } from '../store';
import { useShallow } from 'zustand/react/shallow';
import { toast as message } from 'sonner';
export type FileType = {
name: string;
size: number;
lastModified: number;
webkitRelativePath: string; // 包含name
};
export const FileUpload = () => {
const ref = useRef<HTMLInputElement | null>(null);
const appVersionStore = useAppVersionStore(
useShallow((state) => {
return {
formData: state.formData,
setFormData: state.setFormData,
updateByFromData: state.updateByFromData,
};
}),
);
const onChange = useCallback(
async (e: any) => {
console.log(e.target.files);
// webkitRelativePath
let files = Array.from(e.target.files) as any[];
console.log(files);
if (files.length === 0) {
message.error('请选择文件');
return;
}
// 过滤 文件 .DS_Store
files = files.filter((file) => {
if (file.webkitRelativePath.startsWith('__MACOSX')) {
return false;
}
// 过滤node_modules
if (file.webkitRelativePath.includes('node_modules')) {
return false;
}
// 过滤以.开头的文件
return !file.name.startsWith('.');
});
if (files.length === 0) {
console.log('no files');
return;
}
const root = files[0].webkitRelativePath.split('/')[0];
const formData = new FormData();
files.forEach((file) => {
// relativePath 去除第一级
const webkitRelativePath = file.webkitRelativePath.replace(root + '/', '');
formData.append('file', file, webkitRelativePath); // 保留文件夹路径
});
const key = appVersionStore.formData.key;
const version = appVersionStore.formData.version;
formData.append('appKey', key);
formData.append('version', version);
const res = await fetch('/api/app/upload', {
method: 'POST',
body: formData, //
headers: {
Authorization: 'Bearer ' + (typeof window !== 'undefined' ? localStorage.getItem('token') : ''),
},
}).then((res) => res.json());
if (res?.code === 200) {
appVersionStore.setFormData(res.data);
appVersionStore.updateByFromData();
} else {
message.error(res.message || 'Request failed');
}
// 清理之前上传的文件
e.target.value = '';
},
[appVersionStore.formData],
);
return (
<div>
<input
className='hidden'
ref={ref}
type='file'
// @ts-ignore
webkitdirectory='true'
multiple
onChange={onChange}
/>
<Button
variant='outline'
size='sm'
onClick={() => {
const key = appVersionStore.formData.key;
const version = appVersionStore.formData.version;
if (!key || !version) {
message.error('请先选择应用和版本');
return;
}
ref.current!.click();
}}>
</Button>
</div>
);
};