/** * 文件管理 Hooks * * contract §2.4:adminFiles / adminFileStats / deleteFiles */ import { useCallback, useState } from "react"; import { useGraphMutation, useGraphQuery } from "./use-graphql"; import { ADMIN_FILES_QUERY, ADMIN_FILE_STATS_QUERY, DELETE_FILES_MUTATION, } from "@/lib/graphql-client"; import type { FileViewModel, FileStats, PaginatedResult, } from "@/types/view-models"; /** 文件列表筛选参数 */ export interface FileFilter { page?: number; pageSize?: number; search?: string; mimeType?: string; entityType?: string; } interface AdminFilesResponse { adminFiles: PaginatedResult; } interface AdminFileStatsResponse { adminFileStats: FileStats; } interface DeleteFilesResponse { deleteFiles: boolean; } export function useFiles(filter: FileFilter) { const result = useGraphQuery(ADMIN_FILES_QUERY, { filter, }); return { ...result, data: result.data?.adminFiles ?? null, }; } export function useFileStats() { const result = useGraphQuery(ADMIN_FILE_STATS_QUERY); return { ...result, data: result.data?.adminFileStats ?? null, }; } export function useDeleteFiles() { const [run, state] = useGraphMutation( DELETE_FILES_MUTATION, ); const deleteFiles = useCallback( async (ids: string[]) => { const res = await run({ ids }); return res.data?.deleteFiles ?? false; }, [run], ); return [deleteFiles, state] as const; } /** 文件筛选状态管理 */ export function useFileFilter(initial?: FileFilter) { const [filter, setFilter] = useState({ page: 1, pageSize: 20, ...initial, }); const setPage = useCallback( (page: number) => setFilter((f) => ({ ...f, page })), [], ); const setSearch = useCallback( (search: string) => setFilter((f) => ({ ...f, search, page: 1 })), [], ); const setMimeType = useCallback( (mimeType: string) => setFilter((f) => ({ ...f, mimeType: mimeType || undefined, page: 1 })), [], ); const setEntityType = useCallback( (entityType: string) => setFilter((f) => ({ ...f, entityType: entityType || undefined, page: 1, })), [], ); return { filter, setFilter, setPage, setSearch, setMimeType, setEntityType }; }