/** * A4 系统配置查询与写操作。 * * R-26:阈值 / 上限只存系统配置一处。`useEffectiveConfigsQuery` 供业务页读取前端上限, * 读取失败或未登录时由调用方回退到 shared 常量(仅作展示兜底,后端仍做最终校验)。 */ import { CUSTOMER_BASE_FIELD_LIMIT, CUSTOMER_GEN_FIELD_LIMIT, type SystemConfig, type SystemConfigChange, type SystemConfigHistoryQuery, type SystemConfigValue, type UpdateSystemConfigsInput, } from '@lingxi/shared'; import { useMutation, type UseMutationResult, useQuery, useQueryClient, type UseQueryResult, } from '@tanstack/react-query'; import { fetchEffectiveSystemConfigs, fetchSystemConfigHistory, fetchSystemConfigs, updateSystemConfigs, } from '@/api/configs'; import { queryKeys } from '@/api/query-keys'; export function useSystemConfigsQuery(): UseQueryResult<{ items: SystemConfig[] }> { return useQuery({ queryKey: queryKeys.systemConfigs, queryFn: fetchSystemConfigs, staleTime: 10_000, }); } /** 生效配置:key → value(仅登录可读,失败不阻塞业务页) */ export function useEffectiveConfigsQuery(): UseQueryResult> { return useQuery({ queryKey: queryKeys.systemConfigsEffective, queryFn: fetchEffectiveSystemConfigs, select: (data) => { const values: Record = {}; for (const item of data.items) { values[item.key] = item.value; } return values; }, staleTime: 60_000, retry: 1, }); } /** 读取单个数值型生效配置;缺失 / 非数字时回退 shared 常量 */ export function useEffectiveNumberConfig(key: string, fallback: number): number { const effective = useEffectiveConfigsQuery(); const value = effective.data?.[key]; return typeof value === 'number' ? value : fallback; } export interface CustomerFieldLimits { baseFieldLimit: number; genFieldLimit: number; } /** 客户基础字段 / 进入生成字段上限(A3 客户页与表单校验共用,R-26) */ export function useCustomerFieldLimits(): CustomerFieldLimits { const effective = useEffectiveConfigsQuery(); const base = effective.data?.['limit.customer.base_field']; const gen = effective.data?.['limit.customer.gen_field']; return { baseFieldLimit: typeof base === 'number' ? base : CUSTOMER_BASE_FIELD_LIMIT, genFieldLimit: typeof gen === 'number' ? gen : CUSTOMER_GEN_FIELD_LIMIT, }; } export function useSystemConfigHistoryQuery( query: Partial = {}, options: { enabled?: boolean } = {}, ): UseQueryResult<{ items: SystemConfigChange[]; next_cursor: string | null }> { return useQuery({ queryKey: queryKeys.systemConfigHistory(query), queryFn: () => fetchSystemConfigHistory(query), enabled: options.enabled ?? true, staleTime: 5_000, }); } export function useUpdateSystemConfigsMutation(): UseMutationResult< { items: SystemConfig[] }, Error, UpdateSystemConfigsInput > { const queryClient = useQueryClient(); return useMutation({ mutationFn: updateSystemConfigs, onSuccess: async () => { await Promise.all([ queryClient.invalidateQueries({ queryKey: queryKeys.systemConfigs }), queryClient.invalidateQueries({ queryKey: queryKeys.systemConfigsEffective }), queryClient.invalidateQueries({ queryKey: ['system-configs', 'history'] }), ]); }, }); }