import { useQuery, type UseQueryResult, keepPreviousData, } from "@tanstack/react-query"; import { providersApi, settingsApi, usageApi, type AppId } from "@/lib/api"; import type { Provider, Settings, UsageResult } from "@/types"; const sortProviders = ( providers: Record, ): Record => { const sortedEntries = Object.values(providers) .sort((a, b) => { const indexA = a.sortIndex ?? Number.MAX_SAFE_INTEGER; const indexB = b.sortIndex ?? Number.MAX_SAFE_INTEGER; if (indexA !== indexB) { return indexA - indexB; } const timeA = a.createdAt ?? 0; const timeB = b.createdAt ?? 0; if (timeA === timeB) { return a.name.localeCompare(b.name, "zh-CN"); } return timeA - timeB; }) .map((provider) => [provider.id, provider] as const); return Object.fromEntries(sortedEntries); }; export interface ProvidersQueryData { providers: Record; currentProviderId: string; } export interface UseProvidersQueryOptions { isProxyRunning?: boolean; // 代理服务是否运行中 } export const useProvidersQuery = ( appId: AppId, options?: UseProvidersQueryOptions, ): UseQueryResult => { const { isProxyRunning = false } = options || {}; return useQuery({ queryKey: ["providers", appId], placeholderData: keepPreviousData, // 当代理服务运行时,每 10 秒刷新一次供应商列表 // 这样可以自动反映后端熔断器自动禁用代理目标的变更 refetchInterval: isProxyRunning ? 10000 : false, queryFn: async () => { let providers: Record = {}; let currentProviderId = ""; try { providers = await providersApi.getAll(appId); } catch (error) { console.error("获取供应商列表失败:", error); } try { currentProviderId = await providersApi.getCurrent(appId); } catch (error) { console.error("获取当前供应商失败:", error); } if (Object.keys(providers).length === 0) { try { const success = await providersApi.importDefault(appId); if (success) { providers = await providersApi.getAll(appId); currentProviderId = await providersApi.getCurrent(appId); } } catch (error) { console.error("导入默认配置失败:", error); } } return { providers: sortProviders(providers), currentProviderId, }; }, }); }; export const useSettingsQuery = (): UseQueryResult => { return useQuery({ queryKey: ["settings"], queryFn: async () => settingsApi.get(), }); }; export interface UseUsageQueryOptions { enabled?: boolean; autoQueryInterval?: number; // 自动查询间隔(分钟),0 表示禁用 } export const useUsageQuery = ( providerId: string, appId: AppId, options?: UseUsageQueryOptions, ) => { const { enabled = true, autoQueryInterval = 0 } = options || {}; // 计算 staleTime:如果有自动刷新间隔,使用该间隔;否则默认 5 分钟 // 这样可以避免切换 app 页面时重复触发查询 const staleTime = autoQueryInterval > 0 ? autoQueryInterval * 60 * 1000 // 与刷新间隔保持一致 : 5 * 60 * 1000; // 默认 5 分钟 const query = useQuery({ queryKey: ["usage", providerId, appId], queryFn: async () => usageApi.query(providerId, appId), enabled: enabled && !!providerId, refetchInterval: autoQueryInterval > 0 ? Math.max(autoQueryInterval, 1) * 60 * 1000 // 最小1分钟 : false, refetchIntervalInBackground: true, // 后台也继续定时查询 refetchOnWindowFocus: false, retry: false, staleTime, // 使用动态计算的缓存时间 gcTime: 10 * 60 * 1000, // 缓存保留 10 分钟(组件卸载后) }); return { ...query, lastQueriedAt: query.dataUpdatedAt || null, }; };