| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- import { useState, useCallback } from 'react';
- import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
- import { toast } from 'sonner';
- import { fileClient } from '../api/fileClient';
- import type { FileType } from '../types/file';
- // 文件管理钩子
- export interface UseFileManagementOptions {
- defaultPageSize?: number;
- }
- export const useFileManagement = (options: UseFileManagementOptions = {}) => {
- const { defaultPageSize = 10 } = options;
- const [pagination, setPagination] = useState({
- current: 1,
- pageSize: defaultPageSize,
- total: 0,
- });
- const [searchText, setSearchText] = useState('');
- const queryClient = useQueryClient();
- // 获取文件列表
- const {
- data: filesData,
- isLoading,
- error,
- refetch
- } = useQuery({
- queryKey: ['files', pagination.current, pagination.pageSize, searchText],
- queryFn: async () => {
- const response = await fileClient.$get({
- query: {
- page: pagination.current,
- pageSize: pagination.pageSize,
- keyword: searchText || undefined,
- },
- });
- if (!response.ok) {
- throw new Error('获取文件列表失败');
- }
- return await response.json();
- },
- });
- // 更新文件信息
- const updateFileMutation = useMutation({
- mutationFn: async ({ id, data }: { id: number; data: { name: string; description?: string } }) => {
- const response = await fileClient[':id'].$put({
- param: { id: Number(id) },
- json: data,
- });
- if (!response.ok) {
- throw new Error('更新文件失败');
- }
- return await response.json();
- },
- onSuccess: () => {
- toast.success('文件信息更新成功');
- queryClient.invalidateQueries({ queryKey: ['files'] });
- },
- onError: (error: Error) => {
- toast.error(`更新失败: ${error.message}`);
- },
- });
- // 删除文件
- const deleteFileMutation = useMutation({
- mutationFn: async (id: number) => {
- const response = await fileClient[':id'].$delete({
- param: { id: Number(id) },
- });
- if (!response.ok) {
- throw new Error('删除文件失败');
- }
- },
- onSuccess: () => {
- toast.success('文件删除成功');
- queryClient.invalidateQueries({ queryKey: ['files'] });
- },
- onError: (error: Error) => {
- toast.error(`删除失败: ${error.message}`);
- },
- });
- // 搜索文件
- const handleSearch = useCallback((text: string) => {
- setSearchText(text);
- setPagination(prev => ({ ...prev, current: 1 }));
- }, []);
- // 分页处理
- const handlePageChange = useCallback((page: number, pageSize: number) => {
- setPagination(prev => ({ ...prev, current: page, pageSize }));
- }, []);
- // 文件预览
- const handlePreview = useCallback((file: FileType) => {
- if (isPreviewable(file.type)) {
- window.open(file.fullUrl, '_blank');
- } else {
- toast.warning('该文件类型不支持预览');
- }
- }, []);
- // 文件下载
- const handleDownload = useCallback((file: FileType) => {
- const a = document.createElement('a');
- a.href = file.fullUrl;
- a.download = file.name;
- document.body.appendChild(a);
- a.click();
- document.body.removeChild(a);
- }, []);
- // 检查是否为可预览的文件类型
- const isPreviewable = (fileType: string | null) => {
- if (!fileType) return false;
- return fileType.startsWith('image/') || fileType.startsWith('video/');
- };
- return {
- // 数据
- files: filesData?.data || [],
- pagination: filesData?.pagination || pagination,
- // 状态
- isLoading,
- error,
- searchText,
- // 操作
- handleSearch,
- handlePageChange,
- handlePreview,
- handleDownload,
- updateFile: updateFileMutation.mutateAsync,
- deleteFile: deleteFileMutation.mutateAsync,
- refetch,
- // 工具函数
- isPreviewable,
- };
- };
|