Files
gongxue-base/apps/admin/src/hooks/useApiQuery.ts
wangziqi 9565a0f23c feat(admin): 深化 TanStack Query 数据层
- 新增 queryKeys.ts 统一 QueryKey 工厂(覆盖全部模块,invalidate/refetch/prefetch 同源)
- 新增 queryClient.ts 全局配置:retry 1、staleTime 30s、gcTime 5min、refetchOnWindowFocus false
- 新增 useApiQuery:zod schema 校验 + 类型收敛 + select 转换,消除页面重复 validateResponse 样板
- useApiMutation 支持 onMutate/onSettled/context(乐观更新)
- 示范迁移:Organizations(useApiQuery + 乐观更新归档/恢复)、Students(useApiQuery + queryKeys + 打开抽屉前 prefetch 档案聚合)
- StudentProfileContent queryKey 统一为 queryKeys.archive.detail,prefetch 可命中缓存
2026-08-08 18:37:55 +08:00

32 lines
1.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { useQuery } from '@tanstack/react-query';
import type { QueryKey } from '@tanstack/react-query';
import type { z } from 'zod';
import { validateResponse } from '../utils/validate';
interface UseApiQueryOptions<T, TSelected = T> {
queryKey: QueryKey;
queryFn: () => Promise<unknown>;
/** zod schema响应校验失败会抛出带字段路径的错误由统一错误处理展示 */
schema: z.ZodType<unknown>;
enabled?: boolean;
staleTime?: number;
/** 可选的数据转换React Query select例如列表原始行 → UI 模型 */
select?: (data: T) => TSelected;
}
/**
* useQuery 的类型安全封装queryFn 返回 unknown
* 由 zod schema 校验并收敛为 T消除各页面重复的
* `validateResponse(schema, await api.get(...))` 样板。
*/
export function useApiQuery<T, TSelected = T>(options: UseApiQueryOptions<T, TSelected>) {
const { queryKey, queryFn, schema, enabled, staleTime, select } = options;
return useQuery<T, Error, TSelected>({
queryKey,
enabled,
staleTime,
queryFn: async () => validateResponse<T>(schema, await queryFn()),
select,
});
}