feat(web): A4 数据字典与系统配置页
背景:用户选定方案 A 主从分栏,A4 需要落地字典与配置页。\n改动:新增 /system/dicts、/system/dicts/:type、/system/settings;主从类型列表 + 三层合并 + 树/词表切换 + 条目/类型弹层;6 组配置 + 命名预览 + 阈值二次确认 + 变更记录;客户字段上限改读 effective config;路由/样式/OpenAPI 类型同步。\n影响面:管理中心新增两个菜单页;客户页上限显示改为配置读取(fallback 共享常量)。\n回滚:回滚本提交并恢复 AppLayout / routes / main 样式 import。\n验证:web typecheck/lint/build;单测 154;浏览器自检 1440/1024 无溢出。
This commit is contained in:
1 parent
e4330a43e4
commit
3b0a99d91f
36 files changed
+7691
-15
No files matched your search
@@ -0,0 +1,108 @@
|
||||
/**
|
||||
* 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<Record<string, SystemConfigValue>> {
|
||||
return useQuery({
|
||||
queryKey: queryKeys.systemConfigsEffective,
|
||||
queryFn: fetchEffectiveSystemConfigs,
|
||||
select: (data) => {
|
||||
const values: Record<string, SystemConfigValue> = {};
|
||||
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<SystemConfigHistoryQuery> = {},
|
||||
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'] }),
|
||||
]);
|
||||
},
|
||||
});
|
||||
}
|
||||
Reference in new issue
Block a user