import { useState, useCallback } from 'react'; import { useQuery } from '@tanstack/react-query'; import { fileClient } from '../api/fileClient'; import type { FileType } from '../types/file'; // 文件选择器钩子 export interface UseFileSelectorOptions { filterType?: 'image' | 'all' | string; pageSize?: number; } export const useFileSelector = (options: UseFileSelectorOptions = {}) => { const { filterType = 'all', pageSize = 50 } = options; const [isOpen, setIsOpen] = useState(false); const [selectedFiles, setSelectedFiles] = useState([]); const [searchText, setSearchText] = useState(''); // 获取文件列表 const { data: filesData, isLoading, error, refetch } = useQuery({ queryKey: ['files-for-selection', filterType, searchText], queryFn: async () => { const response = await fileClient.$get({ query: { page: 1, pageSize, keyword: searchText || undefined, }, }); if (!response.ok) { throw new Error('获取文件列表失败'); } return await response.json(); }, enabled: isOpen, }); // 过滤文件 const files = filesData?.data?.filter((file) => { if (filterType === 'all') return true; if (filterType === 'image') return file?.type?.startsWith('image/'); return file?.type?.includes(filterType); }) || []; // 选择文件 const handleSelectFile = useCallback((file: FileType) => { setSelectedFiles(prev => { const isSelected = prev.some(f => f.id === file.id); if (isSelected) { return prev.filter(f => f.id !== file.id); } else { return [...prev, file]; } }); }, []); // 批量选择文件 const handleSelectFiles = useCallback((files: FileType[]) => { setSelectedFiles(files); }, []); // 清除选择 const handleClearSelection = useCallback(() => { setSelectedFiles([]); }, []); // 打开选择器 const handleOpen = useCallback(() => { setIsOpen(true); }, []); // 关闭选择器 const handleClose = useCallback(() => { setIsOpen(false); setSearchText(''); }, []); // 确认选择 const handleConfirm = useCallback(() => { setIsOpen(false); setSearchText(''); return selectedFiles; }, [selectedFiles]); // 搜索文件 const handleSearch = useCallback((text: string) => { setSearchText(text); }, []); // 检查文件是否被选中 const isFileSelected = useCallback((fileId: number) => { return selectedFiles.some(file => file.id === fileId); }, [selectedFiles]); return { // 数据 files, selectedFiles, // 状态 isOpen, isLoading, error, searchText, // 操作 handleOpen, handleClose, handleConfirm, handleSelectFile, handleSelectFiles, handleClearSelection, handleSearch, refetch, // 工具函数 isFileSelected, }; };