@zat-design/sisyphus-react 4.2.0-beta.3 → 4.2.0-beta.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/README.md +16 -5
  2. package/dist/index.esm.css +1 -1
  3. package/dist/less.esm.css +1 -1
  4. package/es/ProAction/index.less +0 -1
  5. package/es/ProDownload/style/index.less +0 -1
  6. package/es/ProDrawerForm/style/index.less +2 -1
  7. package/es/ProEditLabel/style/index.less +0 -1
  8. package/es/ProEditTable/components/Summary/index.d.ts +1 -1
  9. package/es/ProEditTable/style/index.less +150 -114
  10. package/es/ProEditTable/utils/config.d.ts +2 -2
  11. package/es/ProEditTable/utils/tools.d.ts +1 -1
  12. package/es/ProEditTable/utils/useEditTableError.d.ts +1 -1
  13. package/es/ProEnum/hooks/useEnum.js +22 -71
  14. package/es/ProEnum/hooks/useEnumRequest.js +9 -10
  15. package/es/ProEnum/hooks/useFrequentEnumRequest.js +2 -1
  16. package/es/ProEnum/index.d.ts +2 -0
  17. package/es/ProEnum/index.js +4 -2
  18. package/es/ProEnum/style/index.less +0 -1
  19. package/es/ProEnum/utils/frequentEnum.d.ts +1 -2
  20. package/es/ProEnum/utils/frequentEnum.js +2 -2
  21. package/es/ProEnum/utils/getEnum.d.ts +47 -0
  22. package/es/ProEnum/utils/getEnum.js +151 -0
  23. package/es/ProEnum/utils/index.d.ts +13 -3
  24. package/es/ProEnum/utils/index.js +44 -10
  25. package/es/ProForm/components/base/SwitchCheckbox/style/index.less +4 -5
  26. package/es/ProForm/components/base/TimePicker/style/index.less +0 -1
  27. package/es/ProForm/components/combination/Container/style/index.less +18 -19
  28. package/es/ProForm/components/combination/FormList/style/index.less +4 -4
  29. package/es/ProForm/components/combination/Group/style/index.less +43 -50
  30. package/es/ProForm/components/combination/Group/utils/index.d.ts +27 -27
  31. package/es/ProForm/components/combination/ProModalSelect/style/index.less +20 -16
  32. package/es/ProForm/components/combination/ProNumberRange/style/index.less +3 -3
  33. package/es/ProForm/components/combination/ProTimeLimit/style/index.less +1 -1
  34. package/es/ProForm/style/index.less +39 -44
  35. package/es/ProLayout/components/Layout/Header/style/index.less +224 -222
  36. package/es/ProLayout/components/Layout/Icon/style/index.less +1 -1
  37. package/es/ProLayout/components/Layout/Menu/FoldMenu/style/index.less +4 -1
  38. package/es/ProLayout/components/Layout/Menu/OpenMenu/style/index.less +9 -7
  39. package/es/ProLayout/components/Layout/Menu/SideMenu/style/index.less +3 -5
  40. package/es/ProLayout/components/Layout/Menu/style/index.less +9 -5
  41. package/es/ProLayout/components/Layout/index.less +4 -4
  42. package/es/ProLayout/components/ProCollapse/PropTypes.d.ts +45 -45
  43. package/es/ProLayout/components/ProCollapse/style/index.less +30 -32
  44. package/es/ProLayout/components/ProFooter/style/index.less +0 -1
  45. package/es/ProLayout/components/ProHeader/PropTypes.d.ts +31 -31
  46. package/es/ProLayout/components/ProHeader/components/ProBackBtn/style/index.less +7 -7
  47. package/es/ProLayout/components/ProHeader/style/index.less +8 -9
  48. package/es/ProLayout/components/TabsManager/style/index.less +9 -11
  49. package/es/ProLayout/style/index.less +197 -201
  50. package/es/ProLayout/utils/index.d.ts +1 -1
  51. package/es/ProSelect/style/index.less +0 -1
  52. package/es/ProSelect/utils/index.d.ts +1 -1
  53. package/es/ProStep/components/Item/index.js +1 -1
  54. package/es/ProStep/components/LazyLoad/index.d.ts +19 -0
  55. package/es/ProStep/components/LazyLoad/index.js +55 -0
  56. package/es/ProStep/components/Listener/index.js +1 -1
  57. package/es/ProStep/propsType.d.ts +1 -1
  58. package/es/ProStep/style/index.less +7 -9
  59. package/es/ProTable/components/RcTable/components/DraggableTable/components/DndWrapper/index.d.ts +1 -1
  60. package/es/ProTable/propsType.d.ts +1 -1
  61. package/es/ProTable/style/index.less +24 -22
  62. package/es/ProTooltip/style/index.less +0 -1
  63. package/es/ProTree/components/ProTreeSelect/style/index.less +102 -99
  64. package/es/ProTree/style/index.less +108 -109
  65. package/es/ProTreeModal/style/index.less +10 -9
  66. package/es/ProUpload/style/index.less +20 -22
  67. package/es/global.less +1 -1
  68. package/es/index.d.ts +2 -2
  69. package/es/style/core/normalize.less +11 -2
  70. package/es/style/index.less +2 -2
  71. package/es/style/less.less +2 -2
  72. package/es/style/theme/antd.less +19 -23
  73. package/es/style/theme/base.less +81 -81
  74. package/es/style/theme/tokens.less +13 -14
  75. package/es/style/variables.less +1 -1
  76. package/package.json +23 -20
@@ -1,11 +1,7 @@
1
1
  /* eslint-disable no-redeclare */
2
- import { useState, useEffect } from 'react';
2
+ import { useState, useEffect, useRef } from 'react';
3
3
  import { useProConfig } from "../../ProConfigProvider";
4
- import { getEnumData } from "../utils";
5
- let baseEnumStorage = (window.localStorage.getItem('zat-design-pro-component-cacheKey') && JSON.parse(window.localStorage.getItem('zat-design-pro-component-cacheKey'))) ?? null;
6
-
7
- // 模块级缓存,用于存储正在进行的 IndexedDB 读取 Promise,避免重复读取
8
- const indexedDBLoadingCache = new Map();
4
+ import { getEnumData, baseCacheKey, baseStorage } from "../utils";
9
5
 
10
6
  /**
11
7
  * input code output [DataOption[],getEnumLabel]
@@ -44,17 +40,15 @@ const indexedDBLoadingCache = new Map();
44
40
 
45
41
  function useEnum(codes, value, compose) {
46
42
  const {
47
- storage = 'localStorage',
48
- cacheKey = 'zat-design-pro-component-cacheKey',
43
+ storage = baseStorage,
44
+ cacheKey = baseCacheKey,
49
45
  fieldNames = {},
50
46
  clear = true,
51
47
  dics = {}
52
48
  } = useProConfig('ProEnum') || {};
53
49
 
54
- // 存在子应用自管理枚举时,需要根据其指定的cacheKey进行缓存
55
- if (cacheKey !== 'zat-design-pro-component-cacheKey') {
56
- baseEnumStorage = null;
57
- }
50
+ // 用 ref 记录哪些 cacheKey 已触发过加载,防止 enumData 变化导致重复 I/O
51
+ const hasLoadedRef = useRef(new Set());
58
52
 
59
53
  // 使用 state 来存储异步加载的数据
60
54
  const [enumData, setEnumData] = useState(() => {
@@ -70,7 +64,7 @@ function useEnum(codes, value, compose) {
70
64
  data: {}
71
65
  };
72
66
  }
73
- return getEnumData(storage, cacheKey, baseEnumStorage) || {
67
+ return getEnumData(storage, cacheKey) || {
74
68
  data: {}
75
69
  };
76
70
  });
@@ -79,7 +73,6 @@ function useEnum(codes, value, compose) {
79
73
  useEffect(() => {
80
74
  if (storage === 'indexedDB' && dics && Object.keys(dics).length > 0) {
81
75
  setEnumData(prevData => {
82
- // 只有当 dics 有数据且与当前数据不同时才更新
83
76
  if (JSON.stringify(dics) !== JSON.stringify(prevData?.data)) {
84
77
  return {
85
78
  data: dics
@@ -90,67 +83,25 @@ function useEnum(codes, value, compose) {
90
83
  }
91
84
  }, [storage, cacheKey, dics]);
92
85
 
93
- // 异步加载 IndexedDB 数据
86
+ // 异步加载 IndexedDB 数据(每个 cacheKey 只触发一次,由 hasLoadedRef 防重)
94
87
  useEffect(() => {
95
- if (storage === 'indexedDB') {
96
- // 使用模块级缓存避免重复读取
97
- let loadPromise = indexedDBLoadingCache.get(cacheKey);
98
- if (!loadPromise) {
99
- loadPromise = Promise.resolve(getEnumData(storage, cacheKey, baseEnumStorage)).then(data => {
100
- // 读取完成后,从缓存中移除
101
- indexedDBLoadingCache.delete(cacheKey);
102
- return data;
103
- }).catch(error => {
104
- // 读取失败后,从缓存中移除
105
- indexedDBLoadingCache.delete(cacheKey);
106
- // 错误已在 getEnumData 中处理,这里返回空数据
107
- return {
108
- data: {}
109
- };
88
+ if (storage === 'indexedDB' && !hasLoadedRef.current.has(cacheKey)) {
89
+ hasLoadedRef.current.add(cacheKey);
90
+ Promise.resolve(getEnumData(storage, cacheKey)).then(data => {
91
+ setEnumData(prevData => {
92
+ if (data && JSON.stringify(data) !== JSON.stringify(prevData)) {
93
+ return data || {
94
+ data: {}
95
+ };
96
+ }
97
+ return prevData;
110
98
  });
111
- indexedDBLoadingCache.set(cacheKey, loadPromise);
112
- }
113
- loadPromise.then(data => {
114
- // 如果数据为空或无效,且当前 enumData 也是空的,尝试重新读取
115
- if ((!data || !data.data || Object.keys(data.data).length === 0) && (!enumData || !enumData.data || Object.keys(enumData.data).length === 0)) {
116
- // 延迟重试,给 IndexedDB 一些时间
117
- setTimeout(() => {
118
- // 清除缓存,允许重新读取
119
- indexedDBLoadingCache.delete(cacheKey);
120
- Promise.resolve(getEnumData(storage, cacheKey, baseEnumStorage)).then(retryData => {
121
- if (retryData && retryData.data && Object.keys(retryData.data).length > 0) {
122
- setEnumData(prevData => {
123
- if (retryData && JSON.stringify(retryData) !== JSON.stringify(prevData)) {
124
- baseEnumStorage = retryData;
125
- return retryData;
126
- }
127
- return prevData;
128
- });
129
- }
130
- }).catch(() => {
131
- // 重试失败,保持空数据
132
- });
133
- }, 100);
134
- } else {
135
- setEnumData(prevData => {
136
- if (data && JSON.stringify(data) !== JSON.stringify(prevData)) {
137
- baseEnumStorage = data;
138
- return data || {
139
- data: {}
140
- };
141
- }
142
- return prevData;
143
- });
144
- }
99
+ }).catch(() => {
100
+ // 错误已在 getEnumData 中处理
145
101
  });
146
102
  }
147
- }, [storage, cacheKey, enumData]);
148
- const catchData = storage === 'indexedDB' ? enumData : getEnumData(storage, cacheKey, baseEnumStorage);
149
-
150
- // 默认枚举缓存数据(仅同步存储)
151
- if (storage !== 'indexedDB') {
152
- baseEnumStorage = catchData;
153
- }
103
+ }, [storage, cacheKey]);
104
+ const catchData = storage === 'indexedDB' ? enumData : getEnumData(storage, cacheKey);
154
105
  if (!codes) {
155
106
  return catchData;
156
107
  }
@@ -1,9 +1,8 @@
1
1
  import { useEffect } from 'react';
2
2
  import { useDeepCompareEffect, useRequest as useRequestFunc } from 'ahooks';
3
- import { diffCode, getEnumData, setEnumData, removeEnumData, cacheFieldNames, baseCacheKey } from "../utils";
3
+ import { diffCode, getEnumData, setEnumData, removeEnumData, cacheFieldNames, baseCacheKey, baseStorage } from "../utils";
4
4
  import locale from "../../locale";
5
5
  import "../utils/eventCenter";
6
- const baseEnumStorage = (window.localStorage.getItem(baseCacheKey) && JSON.parse(window.localStorage.getItem(baseCacheKey))) ?? null;
7
6
  const useEnumRequest = (props, dispatch) => {
8
7
  const {
9
8
  main = false,
@@ -16,7 +15,7 @@ const useEnumRequest = (props, dispatch) => {
16
15
  },
17
16
  cacheKey = baseCacheKey,
18
17
  requestRefresh = false,
19
- storage = 'localStorage',
18
+ storage = baseStorage,
20
19
  dataSource = {},
21
20
  useRequest,
22
21
  transformResponse,
@@ -74,7 +73,7 @@ const useEnumRequest = (props, dispatch) => {
74
73
  }
75
74
 
76
75
  // 获取缓存数据(支持异步)
77
- const cacheData = await Promise.resolve(getEnumData(storage, cacheKey, baseEnumStorage) || {
76
+ const cacheData = await Promise.resolve(getEnumData(storage, cacheKey) || {
78
77
  data: {}
79
78
  });
80
79
 
@@ -106,7 +105,7 @@ const useEnumRequest = (props, dispatch) => {
106
105
  },
107
106
  getCache: () => {
108
107
  // 支持异步读取
109
- const cachePromise = Promise.resolve(getEnumData(storage, cacheKey, baseEnumStorage) || {
108
+ const cachePromise = Promise.resolve(getEnumData(storage, cacheKey) || {
110
109
  data: {}
111
110
  });
112
111
 
@@ -132,7 +131,7 @@ const useEnumRequest = (props, dispatch) => {
132
131
  }
133
132
 
134
133
  // 同步存储的处理
135
- const res = getEnumData(storage, cacheKey, baseEnumStorage) || {
134
+ const res = getEnumData(storage, cacheKey) || {
136
135
  data: {}
137
136
  };
138
137
  dispatch({
@@ -162,7 +161,7 @@ const useEnumRequest = (props, dispatch) => {
162
161
  }
163
162
  });
164
163
  const mergeData = async () => {
165
- const cacheData = await Promise.resolve(getEnumData(storage, cacheKey, baseEnumStorage) || {
164
+ const cacheData = await Promise.resolve(getEnumData(storage, cacheKey) || {
166
165
  data: {}
167
166
  });
168
167
  if (typeof cacheData === 'object') {
@@ -244,7 +243,7 @@ const useEnumRequest = (props, dispatch) => {
244
243
  // TODO 这段代码目前看起来是没啥用的、没起到作用
245
244
  mergeData();
246
245
  } else if (Object.keys(dataSource)) {
247
- const res = await Promise.resolve(getEnumData(storage, cacheKey, baseEnumStorage) || {
246
+ const res = await Promise.resolve(getEnumData(storage, cacheKey) || {
248
247
  data: {}
249
248
  });
250
249
  dispatch({
@@ -255,7 +254,7 @@ const useEnumRequest = (props, dispatch) => {
255
254
  }
256
255
  });
257
256
  } else {
258
- const res = await Promise.resolve(getEnumData(storage, cacheKey, baseEnumStorage) || {
257
+ const res = await Promise.resolve(getEnumData(storage, cacheKey) || {
259
258
  data: {}
260
259
  });
261
260
  dispatch({
@@ -270,7 +269,7 @@ const useEnumRequest = (props, dispatch) => {
270
269
  }, [useRequest?.options]);
271
270
  const shareProEnumDic = async cacheData => {
272
271
  logDebug(cacheData);
273
- const storageData = await Promise.resolve(getEnumData(storage, cacheKey, baseEnumStorage) || {
272
+ const storageData = await Promise.resolve(getEnumData(storage, cacheKey) || {
274
273
  data: {}
275
274
  });
276
275
  dispatch({
@@ -1,12 +1,13 @@
1
1
  import { useDeepCompareEffect, useRequest as useRequestFunc } from 'ahooks';
2
2
  import { replaceFrequentEnumCache } from "../utils/frequentEnum";
3
+ import { baseCacheKey } from "../utils";
3
4
  const useFrequentEnumRequest = (props, dispatch) => {
4
5
  const {
5
6
  frequentEnums,
6
7
  fieldNames,
7
8
  clear = true,
8
9
  storage = 'localStorage',
9
- cacheKey = 'zat-design-pro-component-cacheKey',
10
+ cacheKey = baseCacheKey,
10
11
  dics,
11
12
  dataSource
12
13
  } = props;
@@ -1,8 +1,10 @@
1
1
  import useEnum from './hooks/useEnum';
2
+ import getEnum from './utils/getEnum';
2
3
  import type { ProEnumType } from './propsType';
3
4
  declare const ProEnum: {
4
5
  (props: ProEnumType): import("react/jsx-runtime").JSX.Element;
5
6
  getEnumLabel: (code: string | string[], value: any, compose?: boolean, fieldNameLabel?: string, fieldNameValue?: string) => import("react/jsx-runtime").JSX.Element;
6
7
  useEnum: typeof useEnum;
8
+ getEnum: typeof getEnum;
7
9
  };
8
10
  export default ProEnum;
@@ -12,9 +12,10 @@ import { useProConfig } from "../ProConfigProvider";
12
12
  import ProEnumTag from "./components/Tag";
13
13
  import ProEnumGroup from "./components/Group";
14
14
  import Container from "../ProForm/components/Container";
15
- import { isObject } from "./utils";
15
+ import { isObject, baseCacheKey } from "./utils";
16
16
  import getEnumLabel from "./utils/getEnumLabel";
17
17
  import useEnum from "./hooks/useEnum";
18
+ import getEnum from "./utils/getEnum";
18
19
  import locale from "../locale";
19
20
  import { useFieldProps } from "../ProForm/utils/useFieldProps";
20
21
  import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
@@ -42,7 +43,7 @@ const ProEnum = props => {
42
43
  const {
43
44
  fieldNames,
44
45
  clear = true,
45
- cacheKey = 'zat-design-pro-component-cacheKey',
46
+ cacheKey = baseCacheKey,
46
47
  showCodeName,
47
48
  ...resProps
48
49
  } = useProConfig('ProEnum') || {};
@@ -282,4 +283,5 @@ const ProEnum = props => {
282
283
  };
283
284
  ProEnum.getEnumLabel = getEnumLabel;
284
285
  ProEnum.useEnum = useEnum;
286
+ ProEnum.getEnum = getEnum;
285
287
  export default ProEnum;
@@ -1,4 +1,3 @@
1
-
2
1
  @zaui-disabled-bg: var(--zaui-disabled-bg);
3
2
 
4
3
  .pro-enum {
@@ -1,5 +1,5 @@
1
+ import type { StorageType } from './index';
1
2
  import type { FrequentEnumConfig } from '../propsType';
2
- type StorageType = 'localStorage' | 'sessionStorage' | 'indexedDB';
3
3
  /**
4
4
  * 替换频繁枚举缓存数据的参数接口
5
5
  */
@@ -37,4 +37,3 @@ export declare function validateFrequentEnumConfig(config: FrequentEnumConfig):
37
37
  * @returns 合并后的数据
38
38
  */
39
39
  export declare function mergeFrequentEnumData(cacheData: any, dics: any, dataSource: any): any;
40
- export {};
@@ -1,4 +1,4 @@
1
- import { getEnumData, setEnumData, cacheFieldNames } from "./index";
1
+ import { getEnumData, setEnumData, cacheFieldNames, baseCacheKey } from "./index";
2
2
 
3
3
  /**
4
4
  * 替换频繁枚举缓存数据的参数接口
@@ -52,7 +52,7 @@ async function replaceFrequentEnumCacheAsync(params) {
52
52
  export function replaceFrequentEnumCache(params) {
53
53
  const {
54
54
  storage = 'localStorage',
55
- cacheKey = 'zat-design-pro-component-cacheKey',
55
+ cacheKey = baseCacheKey,
56
56
  enums = [],
57
57
  newData = {},
58
58
  fieldNames = {
@@ -0,0 +1,47 @@
1
+ import type { StorageType } from './index';
2
+ export interface GetEnumParams {
3
+ /** 单个枚举 code */
4
+ code?: string;
5
+ /** 多个枚举 code,与 code 互斥 */
6
+ codes?: string[];
7
+ /** 单值查询,返回 [label, option],与 values 互斥 */
8
+ value?: string | number;
9
+ /** 多值查询,返回 [labels[], options[]],与 value 互斥 */
10
+ values?: (string | number)[];
11
+ /** 为 true 时返回 value-label 组合形式 */
12
+ compose?: boolean;
13
+ /** 存储类型,默认 indexedDB */
14
+ storage?: StorageType;
15
+ /** 缓存 key,默认 zat-design-pro-component-cacheKey */
16
+ cacheKey?: string;
17
+ }
18
+ /**
19
+ * 在函数/回调中获取枚举数据,无需在 React 组件内使用。
20
+ *
21
+ * 枚举数据由 ProConfigProvider 初始化时写入 storage。
22
+ *
23
+ * **同步优先策略**:
24
+ * - 内存缓存命中时直接返回值,无需 `await`
25
+ * - localStorage/sessionStorage 首次调用同步读取并预热内存缓存
26
+ * - indexedDB 首次调用(内存未命中)返回 Promise,需 `await` 兜底
27
+ *
28
+ * 典型用法:在 ProConfigProvider 初始化完成后,事件回调/工具函数中直接调用无需 await:
29
+ *
30
+ * @example
31
+ * // 获取全部枚举(内存命中时同步返回)
32
+ * const allEnums = getEnum(config);
33
+ *
34
+ * // 获取单个枚举 options
35
+ * const [cityOptions, getLabel] = getEnum({ code: 'city', ...config });
36
+ *
37
+ * // 获取多个枚举
38
+ * const { city, status } = getEnum({ codes: ['city', 'status'], ...config });
39
+ *
40
+ * // 根据值查询 label
41
+ * const [label, option] = getEnum({ code: 'city', value: 'sh', ...config });
42
+ *
43
+ * // indexedDB 首次加载时兜底(数据未预热时需 await)
44
+ * const allEnums = await getEnum(config);
45
+ */
46
+ declare function getEnum(params?: GetEnumParams): any;
47
+ export default getEnum;
@@ -0,0 +1,151 @@
1
+ import { getEnumData, getEnumDataSync, baseCacheKey, baseStorage } from "./index";
2
+ const FIELD_VALUE = 'value';
3
+ const FIELD_LABEL = 'label';
4
+ const FIELD_CHILDREN = 'children';
5
+
6
+ /** 递归在嵌套结构中查找选项 */
7
+ function findOption(opts, target) {
8
+ const found = opts.find(opt => String(opt[FIELD_VALUE]) === String(target));
9
+ if (found) return found;
10
+ return opts.reduce((acc, opt) => {
11
+ if (acc) return acc;
12
+ const children = opt[FIELD_CHILDREN];
13
+ return Array.isArray(children) ? findOption(children, target) : undefined;
14
+ }, undefined);
15
+ }
16
+
17
+ /** 移除 children 字段 */
18
+ function omitChildren(option) {
19
+ const {
20
+ [FIELD_CHILDREN]: _,
21
+ ...rest
22
+ } = option;
23
+ return rest;
24
+ }
25
+
26
+ /** 格式化单个 label */
27
+ function formatLabel(opt, v, compose) {
28
+ return compose ? `${v}-${opt[FIELD_LABEL]}` : opt[FIELD_LABEL];
29
+ }
30
+
31
+ /** 将 allData 按查询参数转换为最终结果 */
32
+ function resolveEnumResult(allData, params) {
33
+ const {
34
+ code,
35
+ codes,
36
+ value,
37
+ values,
38
+ compose
39
+ } = params;
40
+ if (!code && !codes) {
41
+ return allData;
42
+ }
43
+ if (codes) {
44
+ return codes.reduce((acc, c) => {
45
+ const opts = allData[c];
46
+ if (Array.isArray(opts) && opts.length) acc[c] = opts;
47
+ return acc;
48
+ }, {});
49
+ }
50
+ const options = allData[code] ?? [];
51
+ const getLabelFn = (v, composeFn) => {
52
+ const found = findOption(options, v);
53
+ return found ? formatLabel(found, v, composeFn) : undefined;
54
+ };
55
+ if (values !== undefined) {
56
+ const labels = [];
57
+ const foundOptions = [];
58
+ values.forEach(v => {
59
+ const found = findOption(options, v);
60
+ if (found) {
61
+ foundOptions.push(omitChildren(found));
62
+ labels.push(formatLabel(found, v, compose));
63
+ } else {
64
+ foundOptions.push({
65
+ label: '',
66
+ value: ''
67
+ });
68
+ labels.push('');
69
+ }
70
+ });
71
+ return [labels, foundOptions];
72
+ }
73
+ if (value !== undefined) {
74
+ const found = findOption(options, value);
75
+ if (found) {
76
+ return [formatLabel(found, value, compose), omitChildren(found)];
77
+ }
78
+ return [undefined, undefined];
79
+ }
80
+ return [options, getLabelFn];
81
+ }
82
+
83
+ /**
84
+ * 在函数/回调中获取枚举数据,无需在 React 组件内使用。
85
+ *
86
+ * 枚举数据由 ProConfigProvider 初始化时写入 storage。
87
+ *
88
+ * **同步优先策略**:
89
+ * - 内存缓存命中时直接返回值,无需 `await`
90
+ * - localStorage/sessionStorage 首次调用同步读取并预热内存缓存
91
+ * - indexedDB 首次调用(内存未命中)返回 Promise,需 `await` 兜底
92
+ *
93
+ * 典型用法:在 ProConfigProvider 初始化完成后,事件回调/工具函数中直接调用无需 await:
94
+ *
95
+ * @example
96
+ * // 获取全部枚举(内存命中时同步返回)
97
+ * const allEnums = getEnum(config);
98
+ *
99
+ * // 获取单个枚举 options
100
+ * const [cityOptions, getLabel] = getEnum({ code: 'city', ...config });
101
+ *
102
+ * // 获取多个枚举
103
+ * const { city, status } = getEnum({ codes: ['city', 'status'], ...config });
104
+ *
105
+ * // 根据值查询 label
106
+ * const [label, option] = getEnum({ code: 'city', value: 'sh', ...config });
107
+ *
108
+ * // indexedDB 首次加载时兜底(数据未预热时需 await)
109
+ * const allEnums = await getEnum(config);
110
+ */
111
+ function getEnum(params) {
112
+ const {
113
+ code,
114
+ codes,
115
+ value,
116
+ values,
117
+ compose,
118
+ storage = baseStorage,
119
+ cacheKey = baseCacheKey
120
+ } = params ?? {};
121
+ if (code && codes) {
122
+ console.error('[getEnum] code 和 codes 不能同时传入');
123
+ return undefined;
124
+ }
125
+ if (value !== undefined && values !== undefined) {
126
+ console.error('[getEnum] value 和 values 不能同时传入');
127
+ return undefined;
128
+ }
129
+ const syncResult = getEnumDataSync(storage, cacheKey);
130
+ if (syncResult !== undefined) {
131
+ return resolveEnumResult(syncResult.data ?? {}, {
132
+ code,
133
+ codes,
134
+ value,
135
+ values,
136
+ compose
137
+ });
138
+ }
139
+
140
+ // indexedDB 首次加载兜底,返回 Promise
141
+ return getEnumData(storage, cacheKey).then(res => {
142
+ return resolveEnumResult(res?.data ?? {}, {
143
+ code,
144
+ codes,
145
+ value,
146
+ values,
147
+ compose
148
+ });
149
+ });
150
+ }
151
+ export default getEnum;
@@ -1,6 +1,10 @@
1
1
  import { DataOptionType } from '../propsType';
2
- type StorageType = 'localStorage' | 'sessionStorage' | 'indexedDB';
2
+ export type StorageType = 'localStorage' | 'sessionStorage' | 'indexedDB';
3
3
  export declare const baseCacheKey = "zat-design-pro-component-cacheKey";
4
+ /** v4 默认存储类型 */
5
+ export declare const baseStorage: StorageType;
6
+ /** 模块级内存缓存,key 为 cacheKey,替代原单例 baseEnumStorage 变量 */
7
+ export declare const enumMemoryCache: Map<string, any>;
4
8
  interface EnumRes {
5
9
  data: Record<string, DataOptionType[]>;
6
10
  [key: string]: any;
@@ -9,10 +13,9 @@ interface EnumRes {
9
13
  * 获取枚举数据
10
14
  * @param storage
11
15
  * @param cacheKey
12
- * @param baseEnumStorage
13
16
  * @returns
14
17
  */
15
- export declare function getEnumData(storage: StorageType, cacheKey: string, baseEnumStorage?: any): EnumRes | Promise<EnumRes>;
18
+ export declare function getEnumData(storage: StorageType, cacheKey: string): EnumRes | Promise<EnumRes>;
16
19
  /**
17
20
  * 设置枚举数据
18
21
  * @param storage
@@ -26,6 +29,13 @@ export declare function setEnumData(storage: StorageType, cacheKey: string, data
26
29
  * @param cacheKey
27
30
  */
28
31
  export declare function removeEnumData(storage: StorageType, cacheKey: string): Promise<void>;
32
+ /**
33
+ * 从内存缓存或同步存储中同步读取枚举数据,不触发任何异步 I/O。
34
+ * - 内存缓存命中时直接返回
35
+ * - localStorage/sessionStorage 同步读取并预热内存缓存
36
+ * - indexedDB 未命中时返回 undefined(需异步兜底)
37
+ */
38
+ export declare function getEnumDataSync(storage: StorageType, cacheKey: string): EnumRes | undefined;
29
39
  /**
30
40
  * 判断枚举列表是否存在
31
41
  * @param storage
@@ -1,6 +1,12 @@
1
1
  import { get, set, del } from 'idb-keyval';
2
2
  export const baseCacheKey = 'zat-design-pro-component-cacheKey';
3
3
 
4
+ /** v4 默认存储类型 */
5
+ export const baseStorage = 'indexedDB';
6
+
7
+ /** 模块级内存缓存,key 为 cacheKey,替代原单例 baseEnumStorage 变量 */
8
+ export const enumMemoryCache = new Map();
9
+
4
10
  // IndexedDB 可用性检测缓存
5
11
  let indexedDBAvailable = null;
6
12
 
@@ -73,22 +79,23 @@ async function setToIndexedDB(key, value) {
73
79
  * 获取枚举数据
74
80
  * @param storage
75
81
  * @param cacheKey
76
- * @param baseEnumStorage
77
82
  * @returns
78
83
  */
79
- export function getEnumData(storage, cacheKey, baseEnumStorage) {
80
- // IndexedDB 返回 Promise
84
+ export function getEnumData(storage, cacheKey) {
85
+ // IndexedDB:先查内存缓存,命中则同步返回,避免实际 I/O
81
86
  if (storage === 'indexedDB') {
82
- return getFromIndexedDB(cacheKey);
87
+ if (enumMemoryCache.has(cacheKey)) {
88
+ return Promise.resolve(enumMemoryCache.get(cacheKey));
89
+ }
90
+ return getFromIndexedDB(cacheKey).then(data => {
91
+ enumMemoryCache.set(cacheKey, data);
92
+ return data;
93
+ });
83
94
  }
84
95
 
85
96
  // localStorage/sessionStorage 保持同步
86
- if (baseEnumStorage && window.localStorage.getItem(cacheKey) && cacheKey === baseCacheKey) {
87
- return baseEnumStorage;
88
- }
89
97
  if (storage === 'localStorage') {
90
98
  const data = JSON.parse(window.localStorage.getItem(cacheKey) || '{}');
91
- // 确保返回的数据格式正确,包含 data 字段
92
99
  if (data && typeof data === 'object' && 'data' in data) {
93
100
  return data;
94
101
  }
@@ -98,7 +105,6 @@ export function getEnumData(storage, cacheKey, baseEnumStorage) {
98
105
  }
99
106
  if (storage === 'sessionStorage') {
100
107
  const data = JSON.parse(window.sessionStorage.getItem(cacheKey) || '{}');
101
- // 确保返回的数据格式正确,包含 data 字段
102
108
  if (data && typeof data === 'object' && 'data' in data) {
103
109
  return data;
104
110
  }
@@ -122,8 +128,9 @@ export function setEnumData(storage, cacheKey, data) {
122
128
  return;
123
129
  }
124
130
 
125
- // IndexedDB 返回 Promise
131
+ // IndexedDB:同步写内存缓存,异步持久化到 IndexedDB
126
132
  if (storage === 'indexedDB') {
133
+ enumMemoryCache.set(cacheKey, data);
127
134
  return setToIndexedDB(cacheKey, data);
128
135
  }
129
136
 
@@ -158,6 +165,33 @@ export async function removeEnumData(storage, cacheKey) {
158
165
  }
159
166
  }
160
167
 
168
+ /**
169
+ * 从内存缓存或同步存储中同步读取枚举数据,不触发任何异步 I/O。
170
+ * - 内存缓存命中时直接返回
171
+ * - localStorage/sessionStorage 同步读取并预热内存缓存
172
+ * - indexedDB 未命中时返回 undefined(需异步兜底)
173
+ */
174
+ export function getEnumDataSync(storage, cacheKey) {
175
+ if (enumMemoryCache.has(cacheKey)) return enumMemoryCache.get(cacheKey);
176
+ if (storage === 'localStorage') {
177
+ const d = JSON.parse(window.localStorage.getItem(cacheKey) || '{}');
178
+ const res = d?.data ? d : {
179
+ data: {}
180
+ };
181
+ enumMemoryCache.set(cacheKey, res);
182
+ return res;
183
+ }
184
+ if (storage === 'sessionStorage') {
185
+ const d = JSON.parse(window.sessionStorage.getItem(cacheKey) || '{}');
186
+ const res = d?.data ? d : {
187
+ data: {}
188
+ };
189
+ enumMemoryCache.set(cacheKey, res);
190
+ return res;
191
+ }
192
+ return undefined;
193
+ }
194
+
161
195
  /**
162
196
  * 判断枚举列表是否存在
163
197
  * @param storage
@@ -1,13 +1,12 @@
1
-
2
1
  .switch-checkbox-view {
3
- display : flex;
2
+ display: flex;
4
3
  align-items: center;
5
4
 
6
5
  .switch-checkbox-view-label {
7
- flex : 0 0 @zaui-form-label-width;
8
- overflow : initial;
6
+ flex: 0 0 @zaui-form-label-width;
7
+ overflow: initial;
9
8
  line-height: 1;
10
9
  white-space: pre-wrap;
11
- color : var(--zaui-aide-text, #939599);
10
+ color: var(--zaui-aide-text, #939599);
12
11
  }
13
12
  }
@@ -1,4 +1,3 @@
1
-
2
1
  /* 适配antd 5.x,不再导入antd样式 */
3
2
 
4
3
  .ant-picker-time {