@zat-design/sisyphus-react 4.5.9 → 4.5.10-beta.1

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 (51) hide show
  1. package/dist/index.esm.css +1 -1
  2. package/dist/less.esm.css +1 -1
  3. package/es/ProAction/components/CheckModalContent/index.js +2 -2
  4. package/es/ProDownload/index.d.ts +2 -1
  5. package/es/ProDownload/index.js +31 -16
  6. package/es/ProDownload/utils.d.ts +10 -5
  7. package/es/ProDownload/utils.js +7 -5
  8. package/es/ProEditTable/utils/index.js +6 -1
  9. package/es/ProEnum/hooks/useEnumRequest.js +98 -77
  10. package/es/ProForm/components/combination/FormList/components/ActionButton.js +2 -2
  11. package/es/ProForm/components/combination/FormList/components/BlockFields.js +1 -0
  12. package/es/ProForm/components/combination/FormList/components/Empty.js +1 -1
  13. package/es/ProForm/components/combination/FormList/components/ToolbarButton.js +3 -3
  14. package/es/ProForm/components/combination/FormList/style/index.less +6 -0
  15. package/es/ProForm/components/combination/Group/component/FlexibleGroup.js +5 -11
  16. package/es/ProForm/components/combination/Group/hooks/index.js +1 -1
  17. package/es/ProForm/components/combination/Group/index.js +1 -1
  18. package/es/ProForm/components/combination/ProModalSelect/hooks/useRequestList.js +22 -8
  19. package/es/ProForm/components/combination/ProModalSelect/index.js +32 -12
  20. package/es/ProForm/components/combination/ProRangeLimit/index.js +1 -1
  21. package/es/ProForm/components/render/Render.js +2 -2
  22. package/es/ProForm/hooks/useWatch.js +7 -8
  23. package/es/ProForm/utils/index.js +2 -2
  24. package/es/ProLayout/components/Layout/Menu/OpenMenu/index.js +8 -8
  25. package/es/ProLayout/components/Layout/Menu/index.js +1 -1
  26. package/es/ProLayout/components/ProFooter/index.js +2 -1
  27. package/es/ProLayout/components/ProHeader/components/Describe/index.js +3 -1
  28. package/es/ProLayout/components/TabsManager/components/TabItem.js +6 -5
  29. package/es/ProLayout/components/TabsManager/hooks/useTabsState.js +104 -16
  30. package/es/ProLayout/components/TabsManager/hooks/useTabsUrlSync.d.ts +19 -0
  31. package/es/ProLayout/components/TabsManager/hooks/useTabsUrlSync.js +295 -0
  32. package/es/ProLayout/components/TabsManager/index.js +54 -14
  33. package/es/ProLayout/components/TabsManager/propTypes.d.ts +4 -0
  34. package/es/ProLayout/components/TabsManager/style/index.less +1 -1
  35. package/es/ProLayout/components/TabsManager/utils/historyObserver.d.ts +7 -0
  36. package/es/ProLayout/components/TabsManager/utils/historyObserver.js +62 -0
  37. package/es/ProLayout/components/TabsManager/utils/index.d.ts +15 -2
  38. package/es/ProLayout/components/TabsManager/utils/index.js +63 -9
  39. package/es/ProLayout/index.js +6 -3
  40. package/es/ProLayout/propTypes.d.ts +28 -1
  41. package/es/ProSelect/index.js +10 -1
  42. package/es/ProSelect/style/index.less +13 -0
  43. package/es/ProStep/style/index.less +1 -1
  44. package/es/ProTable/hooks/useAntdTable.js +11 -10
  45. package/es/ProTabs/index.js +3 -3
  46. package/es/ProTooltip/index.js +2 -5
  47. package/es/ProTree/components/ProTreeSelect/index.js +2 -2
  48. package/es/ProTreeModal/index.js +0 -3
  49. package/es/ProUpload/components/DragRender.js +0 -14
  50. package/package.json +2 -1
  51. package/es/ProConfigProvider/demo/locale.js +0 -58
@@ -17,10 +17,10 @@ const CheckModalContent = props => {
17
17
  children: list[0]
18
18
  }) : null, Array.isArray(list) && list.length > 1 ? /*#__PURE__*/_jsx("div", {
19
19
  className: "list-wrap",
20
- children: list.map(item => /*#__PURE__*/_jsx("div", {
20
+ children: list.map((item, index) => /*#__PURE__*/_jsx("div", {
21
21
  className: "err-item",
22
22
  children: item
23
- }))
23
+ }, `${item}-${index}`))
24
24
  }) : null]
25
25
  })
26
26
  });
@@ -1,6 +1,7 @@
1
+ import { DownloadRequest } from './utils';
1
2
  import type { ProDownloadType } from './propsType';
2
3
  declare const ProDownload: {
3
4
  (props: ProDownloadType): import("react/jsx-runtime").JSX.Element;
4
- downLoadRequest: import("./utils").DownloadRequestProps;
5
+ downLoadRequest: typeof DownloadRequest;
5
6
  };
6
7
  export default ProDownload;
@@ -6,6 +6,12 @@ import classNames from 'classnames';
6
6
  import { BlobMakeFile, DownloadRequest } from "./utils";
7
7
  import { useProConfig } from "../ProConfigProvider";
8
8
  import { jsx as _jsx } from "react/jsx-runtime";
9
+ const normalizeError = error => {
10
+ if (error !== null && typeof error === 'object') {
11
+ return error;
12
+ }
13
+ return new Error(error == null ? 'Download request failed' : String(error));
14
+ };
9
15
  const ProDownload = props => {
10
16
  const {
11
17
  source,
@@ -31,33 +37,40 @@ const ProDownload = props => {
31
37
  headers,
32
38
  onError: onErrorConfig
33
39
  } = useProConfig('ProDownload') || {};
40
+ const reportError = onError || onErrorConfig;
34
41
  defaultProps.headers = {
35
42
  ...headers,
36
43
  ...defaultProps.headers
37
44
  };
38
45
  const handDownload = async (_params = params) => {
39
46
  if (source === 'url') {
40
- try {
41
- fetch(url || action).then(response => {
42
- if (response.status > 400) {
43
- return Promise.reject(new Error(`Service exception: ${response.status}`));
44
- }
45
- return response.blob();
46
- }).then(res => {
47
- const blob = new Blob([res]);
48
- BlobMakeFile({
49
- blob,
50
- fileName
51
- });
47
+ fetch(url || action).then(response => {
48
+ if (response.status > 400) {
49
+ return Promise.reject(new Error(`Service exception: ${response.status}`));
50
+ }
51
+ return response.blob();
52
+ }).then(res => {
53
+ const blob = new Blob([res]);
54
+ BlobMakeFile({
55
+ blob,
56
+ fileName
52
57
  });
53
- } catch (error) {
54
- Promise.reject(error);
55
- }
58
+ }).catch(error => {
59
+ reportError?.(normalizeError(error));
60
+ });
56
61
  return;
57
62
  }
58
63
  setState({
59
64
  loading: true
60
65
  });
66
+ let errorReported = false;
67
+ const requestOnError = error => {
68
+ if (errorReported) {
69
+ return;
70
+ }
71
+ errorReported = true;
72
+ reportError?.(normalizeError(error));
73
+ };
61
74
  try {
62
75
  // 发起请求
63
76
  await DownloadRequest({
@@ -68,8 +81,10 @@ const ProDownload = props => {
68
81
  transformResponse,
69
82
  fileName,
70
83
  onFinish,
71
- onError: onError || onErrorConfig
84
+ onError: requestOnError
72
85
  });
86
+ } catch (error) {
87
+ requestOnError(error);
73
88
  } finally {
74
89
  setState({
75
90
  loading: false
@@ -3,7 +3,7 @@ export interface PropsWithMakeFilePropsType {
3
3
  fileName: string;
4
4
  url?: string;
5
5
  }
6
- export interface IDownloadRequestPropsType {
6
+ export interface IDownloadRequestPropsType<TResult = Response> {
7
7
  /**
8
8
  * @description 下载请求的地址
9
9
  * @default (必选)
@@ -21,12 +21,12 @@ export interface IDownloadRequestPropsType {
21
21
  params?: any;
22
22
  headers?: any;
23
23
  /** 格式化数据 */
24
- transformResponse?: (data: any) => any;
24
+ transformResponse?: (data: any) => TResult | Promise<TResult>;
25
25
  /**
26
26
  * @description service 执行完成时触发
27
27
  * @default -
28
28
  */
29
- onFinish?: (response: object, params: object) => void;
29
+ onFinish?: (response: Awaited<TResult>, params: object) => void;
30
30
  /**
31
31
  * @description 下载保存的文件名
32
32
  * @default (必选)
@@ -47,7 +47,6 @@ export interface IDownloadRequestPropsType {
47
47
  * @constructor
48
48
  */
49
49
  export declare function BlobMakeFile({ blob, fileName, url }: PropsWithMakeFilePropsType): void;
50
- export type DownloadRequestProps = (props: IDownloadRequestPropsType) => Promise<Response>;
51
50
  type convertBase64ToBlobType = (base64: string, fileType?: string, slice?: number) => Blob;
52
51
  export declare const convertBase64ToBlob: convertBase64ToBlobType;
53
52
  /**
@@ -56,5 +55,11 @@ export declare const convertBase64ToBlob: convertBase64ToBlobType;
56
55
  * @returns string
57
56
  */
58
57
  export declare function getFilenameFromContentDisposition(contentDisposition: any): string;
59
- export declare const DownloadRequest: DownloadRequestProps;
58
+ export declare function DownloadRequest<TResult>(props: IDownloadRequestPropsType<TResult> & {
59
+ transformResponse: (data: any) => TResult | Promise<TResult>;
60
+ }): Promise<Awaited<TResult>>;
61
+ export declare function DownloadRequest(props: IDownloadRequestPropsType<Response> & {
62
+ transformResponse?: undefined;
63
+ }): Promise<Response>;
64
+ export type DownloadRequestProps = typeof DownloadRequest;
60
65
  export {};
@@ -71,7 +71,8 @@ export function getFilenameFromContentDisposition(contentDisposition) {
71
71
  }
72
72
 
73
73
  // 发起请求获取下载文件
74
- export const DownloadRequest = async ({
74
+
75
+ export async function DownloadRequest({
75
76
  url,
76
77
  method = 'post',
77
78
  params,
@@ -80,7 +81,7 @@ export const DownloadRequest = async ({
80
81
  fileName,
81
82
  onFinish,
82
83
  onError
83
- }) => {
84
+ }) {
84
85
  const config = {
85
86
  method,
86
87
  credentials: 'include',
@@ -159,10 +160,11 @@ export const DownloadRequest = async ({
159
160
  fileBlob = await response.blob();
160
161
  }
161
162
  // 完成回调
162
- onFinish?.(_isFunction(transformResponse) ? res : response, params);
163
+ const result = _isFunction(transformResponse) ? res : response;
164
+ onFinish?.(result, params);
163
165
  BlobMakeFile({
164
166
  blob: fileBlob,
165
167
  fileName: fileName || contentFileName
166
168
  });
167
- return Promise.resolve(_isFunction(transformResponse) ? res : response);
168
- };
169
+ return result;
170
+ }
@@ -112,7 +112,12 @@ const getActionColumn = config => {
112
112
  }
113
113
  }
114
114
  // 编辑状态使用自定义form值,非编辑状态直接使用行数据
115
- const lastRecord = filterInternalFields(form.getFieldValue(rowName) ?? record);
115
+ const fieldRecord = filterInternalFields(form.getFieldValue(rowName));
116
+ const lastRecord = {
117
+ ...record,
118
+ ...(fieldRecord && typeof fieldRecord === 'object' ? fieldRecord : {}),
119
+ rowKey: record.rowKey
120
+ };
116
121
  // 新增事件可以设置初始默认值,当做函数的出参导出
117
122
  const onEvent = onClick || onHandle;
118
123
  let result;
@@ -34,6 +34,7 @@ const useEnumRequest = (props, dispatch) => {
34
34
  // 而非跳过 run()。这样 enumRes.data/loading 正常变更,
35
35
  // ProConfigProvider 的 onSuccess 回调能正常触发(修复白屏问题)。
36
36
  const fromCacheRef = useRef(null);
37
+ const errorReportedRef = useRef(false);
37
38
  const originalService = useRequest?.service;
38
39
  const serviceForRequest = useMemo(() => {
39
40
  if (!originalService || storage !== 'indexedDB') {
@@ -54,19 +55,102 @@ const useEnumRequest = (props, dispatch) => {
54
55
  return originalService(...args);
55
56
  };
56
57
  }, [originalService, storage, requestRefresh, cacheKey]);
58
+ const reportBackgroundError = (error, params = []) => {
59
+ if (errorReportedRef.current) {
60
+ return;
61
+ }
62
+ errorReportedRef.current = true;
63
+ const normalizedError = error instanceof Error ? error : new Error(String(error));
64
+ useRequest?.options?.onError?.(normalizedError, params);
65
+ };
57
66
  const enumRes = useRequestFunc(serviceForRequest, {
58
67
  manual: true,
59
68
  cacheKey,
60
69
  cacheTime: -1,
61
70
  staleTime: 6e4 * 60,
62
71
  ...useRequest?.options,
72
+ onBefore: params => {
73
+ errorReportedRef.current = false;
74
+ useRequest?.options?.onBefore?.(params);
75
+ },
76
+ onError: reportBackgroundError,
63
77
  setCache: async res => {
64
- // 缓存命中时跳过 transformResponse 和重复处理,直接 dispatch
65
- if (fromCacheRef.current) {
66
- const cachedData = fromCacheRef.current;
78
+ try {
79
+ // 缓存命中时跳过 transformResponse 和重复处理,直接 dispatch
80
+ if (fromCacheRef.current) {
81
+ const cachedData = fromCacheRef.current;
82
+ const mergedPayload = {
83
+ ...dics,
84
+ ...cachedData,
85
+ ...dataSource
86
+ };
87
+ dispatch({
88
+ type: 'setProEnumDic',
89
+ payload: mergedPayload
90
+ });
91
+ if (main) {
92
+ setTimeout(() => {
93
+ window?.eventCenter?.publish('pro-enum-event', cachedData);
94
+ logDebug(locale?.ProEnum?.mainInitByCache);
95
+ }, 10000);
96
+ }
97
+ fromCacheRef.current = null;
98
+ return res;
99
+ }
100
+ let response = res.data;
101
+ if (transformResponse && typeof transformResponse === 'function') {
102
+ response = await transformResponse(res.data);
103
+ if (typeof response !== 'object' || response == null) {
104
+ throw new Error(locale?.ProEnum?.errorMessage);
105
+ } else {
106
+ res.data = response;
107
+ }
108
+ }
109
+ if (typeof response !== 'object' || response === null) {
110
+ throw Error('response enum data must be object');
111
+ }
112
+ if (Object.keys(response).length === 0) {
113
+ throw Error('Please return valid enumeration data');
114
+ }
115
+
116
+ // 只返回fieldNames对象的key
117
+ if (clear) {
118
+ // 忽略清洗的 codes
119
+ const ignoreCodes = useRequest?.options?.ignoreCodes || [];
120
+ Object.keys(response).forEach(key => {
121
+ if (!response[key] || !Array.isArray(response[key])) {
122
+ return;
123
+ }
124
+ const options = [...response[key]];
125
+ if (ignoreCodes.includes(key)) {
126
+ response[key] = options;
127
+ } else {
128
+ response[key] = options.map(item => {
129
+ return cacheFieldNames(fieldNames, item);
130
+ });
131
+ }
132
+ });
133
+ res.data = response;
134
+ }
135
+
136
+ // 获取缓存数据(支持异步)
137
+ const cacheData = await Promise.resolve(getEnumData(storage, cacheKey) || {
138
+ data: {}
139
+ });
140
+
141
+ // 合并缓存数据
142
+ res.data = {
143
+ ...cacheData?.data,
144
+ ...res.data
145
+ };
146
+
147
+ // 设置缓存数据(支持异步)
148
+ await Promise.resolve(setEnumData(storage, cacheKey, res));
149
+
150
+ // 同步数据到全局
67
151
  const mergedPayload = {
68
152
  ...dics,
69
- ...cachedData,
153
+ ...res.data,
70
154
  ...dataSource
71
155
  };
72
156
  dispatch({
@@ -75,80 +159,15 @@ const useEnumRequest = (props, dispatch) => {
75
159
  });
76
160
  if (main) {
77
161
  setTimeout(() => {
78
- window?.eventCenter?.publish('pro-enum-event', cachedData);
79
- logDebug(locale?.ProEnum?.mainInitByCache);
162
+ window?.eventCenter?.publish('pro-enum-event', res.data);
163
+ logDebug(locale?.ProEnum?.mainInitByRequest);
80
164
  }, 10000);
81
165
  }
82
- fromCacheRef.current = null;
166
+ return res;
167
+ } catch (error) {
168
+ reportBackgroundError(error);
83
169
  return res;
84
170
  }
85
- let response = res.data;
86
- if (transformResponse && typeof transformResponse === 'function') {
87
- response = await transformResponse(res.data);
88
- if (typeof response !== 'object' || response == null) {
89
- throw new Error(locale?.ProEnum?.errorMessage);
90
- } else {
91
- res.data = response;
92
- }
93
- }
94
- if (typeof response !== 'object' || response === null) {
95
- throw Error('response enum data must be object');
96
- }
97
- if (Object.keys(response).length === 0) {
98
- throw Error('Please return valid enumeration data');
99
- }
100
-
101
- // 只返回fieldNames对象的key
102
- if (clear) {
103
- // 忽略清洗的 codes
104
- const ignoreCodes = useRequest?.options?.ignoreCodes || [];
105
- Object.keys(response).forEach(key => {
106
- if (!response[key] || !Array.isArray(response[key])) {
107
- return;
108
- }
109
- const options = [...response[key]];
110
- if (ignoreCodes.includes(key)) {
111
- response[key] = options;
112
- } else {
113
- response[key] = options.map(item => {
114
- return cacheFieldNames(fieldNames, item);
115
- });
116
- }
117
- });
118
- res.data = response;
119
- }
120
-
121
- // 获取缓存数据(支持异步)
122
- const cacheData = await Promise.resolve(getEnumData(storage, cacheKey) || {
123
- data: {}
124
- });
125
-
126
- // 合并缓存数据
127
- res.data = {
128
- ...cacheData?.data,
129
- ...res.data
130
- };
131
-
132
- // 设置缓存数据(支持异步)
133
- await Promise.resolve(setEnumData(storage, cacheKey, res));
134
-
135
- // 同步数据到全局
136
- const mergedPayload = {
137
- ...dics,
138
- ...res.data,
139
- ...dataSource
140
- };
141
- dispatch({
142
- type: 'setProEnumDic',
143
- payload: mergedPayload
144
- });
145
- if (main) {
146
- setTimeout(() => {
147
- window?.eventCenter?.publish('pro-enum-event', res.data);
148
- logDebug(locale?.ProEnum?.mainInitByRequest);
149
- }, 10000);
150
- }
151
- return res;
152
171
  },
153
172
  getCache: params => {
154
173
  if (storage === 'indexedDB') {
@@ -250,6 +269,7 @@ const useEnumRequest = (props, dispatch) => {
250
269
  }
251
270
  };
252
271
  useDeepCompareEffect(() => {
272
+ errorReportedRef.current = false;
253
273
  const executeAsync = async () => {
254
274
  if (useRequest && useRequest?.service) {
255
275
  const {
@@ -264,7 +284,7 @@ const useEnumRequest = (props, dispatch) => {
264
284
  }
265
285
  }
266
286
  enumRes.run(params);
267
- mergeData();
287
+ void mergeData().catch(reportBackgroundError);
268
288
  } else if (dataSource && Object.keys(dataSource).length > 0) {
269
289
  const res = await Promise.resolve(getEnumData(storage, cacheKey) || {
270
290
  data: {}
@@ -294,19 +314,20 @@ const useEnumRequest = (props, dispatch) => {
294
314
  });
295
315
  }
296
316
  };
297
- executeAsync();
317
+ void executeAsync().catch(reportBackgroundError);
298
318
  }, [useRequest?.options]);
299
319
  const shareProEnumDic = async cacheData => {
300
320
  logDebug(cacheData);
301
321
  const storageData = await Promise.resolve(getEnumData(storage, cacheKey) || {
302
322
  data: {}
303
323
  });
324
+ const storagePayload = typeof storageData?.data === 'object' && storageData.data !== null ? storageData.data : storageData;
304
325
  dispatch({
305
326
  type: 'setProEnumDic',
306
327
  payload: {
307
328
  ...dataSource,
308
329
  ...cacheData,
309
- ...storageData
330
+ ...storagePayload
310
331
  }
311
332
  });
312
333
  };
@@ -250,7 +250,7 @@ const ActionButton = props => {
250
250
  });
251
251
  if (!_onClick || data === true) {
252
252
  // 如果有 addIndex 配置,使用它计算插入位置
253
- if (item.addIndex) {
253
+ if (item.addIndex !== undefined) {
254
254
  const insertIndex = typeof item.addIndex === 'function' ? item.addIndex(value, {
255
255
  index,
256
256
  namePath,
@@ -265,7 +265,7 @@ const ActionButton = props => {
265
265
  }
266
266
  if (item?.type === 'add') {
267
267
  // 如果有 addIndex 配置,使用它计算插入位置
268
- if (item.addIndex) {
268
+ if (item.addIndex !== undefined) {
269
269
  const insertIndex = typeof item.addIndex === 'function' ? item.addIndex(value, {
270
270
  index,
271
271
  namePath,
@@ -58,6 +58,7 @@ const BlockFields = props => {
58
58
  }), /*#__PURE__*/_jsx("div", {
59
59
  className: "pro-form-list-left-content",
60
60
  children: /*#__PURE__*/_jsx(ProCollapse, {
61
+ className: "pro-form-list-left-action-right",
61
62
  title: _title,
62
63
  index: index,
63
64
  form: form,
@@ -36,7 +36,7 @@ const Empty = ({
36
36
  const getBtnText = () => {
37
37
  return emptyBtnText || addConfig?.label || locale.ProForm.formListActions[6];
38
38
  };
39
- let show = true;
39
+ let show = toolbarProps !== false;
40
40
  if (addConfig?.show !== undefined) {
41
41
  show = _isFunction(addConfig.show) ? addConfig.show(form.getFieldValue(namePath), {
42
42
  namePath,
@@ -20,7 +20,7 @@ const actions = {
20
20
  const defaultActionProps = [{
21
21
  type: 'add'
22
22
  }];
23
- const filterKeys = ['actionType', 'addIndex'];
23
+ const filterKeys = ['actionType', 'addIndex', 'show'];
24
24
  const ToolbarButton = props => {
25
25
  const {
26
26
  namePath,
@@ -59,7 +59,7 @@ const ToolbarButton = props => {
59
59
  if (!callback || data === true) {
60
60
  if (item?.type === 'add') {
61
61
  // 如果有 addIndex 配置,使用它计算插入位置
62
- if (item.addIndex) {
62
+ if (item.addIndex !== undefined) {
63
63
  const insertIndex = typeof item.addIndex === 'function' ? item.addIndex(value, {
64
64
  namePath,
65
65
  form,
@@ -82,7 +82,7 @@ const ToolbarButton = props => {
82
82
  }
83
83
  if (item?.type === 'add' && data) {
84
84
  // 如果有 addIndex 配置,使用它计算插入位置
85
- if (item.addIndex) {
85
+ if (item.addIndex !== undefined) {
86
86
  const insertIndex = typeof item.addIndex === 'function' ? item.addIndex(value, {
87
87
  namePath,
88
88
  form,
@@ -158,6 +158,12 @@
158
158
  }
159
159
  }
160
160
 
161
+ .pro-form-list-left-action-right {
162
+ .@{ant-prefix}-collapse-extra {
163
+ margin-inline-start: auto;
164
+ }
165
+ }
166
+
161
167
  // 移动端响应式
162
168
  @media (max-width: 768px) {
163
169
  .pro-form-list-left-title-wrapper {
@@ -1,5 +1,4 @@
1
1
  import _isFunction from "lodash/isFunction";
2
- import _isEmpty from "lodash/isEmpty";
3
2
  import React from 'react';
4
3
  import { Space, Form } from 'antd';
5
4
  import classnames from 'classnames';
@@ -219,7 +218,7 @@ const FlexibleGroupRender = props => {
219
218
  requiredOnView: otherProps?.requiredOnView,
220
219
  viewRender: child.viewRender
221
220
  })
222
- }, child.name || `item-${index}`);
221
+ }, String(child.name ?? `item-${index}`));
223
222
  };
224
223
 
225
224
  // 非compact模式:正常的表单项渲染
@@ -248,13 +247,13 @@ const FlexibleGroupRender = props => {
248
247
  // 添加分隔符(除最后一个元素外)
249
248
  if (index < visibleChildren.length - 1 && space?.separator) {
250
249
  // 检查是否在指定位置添加分隔符
251
- const shouldAddSeparator = space.separatorIndex ? Array.isArray(space.separatorIndex) ? space.separatorIndex.includes(originalIndex) : space.separatorIndex === originalIndex : true; // 默认每个元素后都加分隔符
250
+ const shouldAddSeparator = space.separatorIndex != null ? Array.isArray(space.separatorIndex) ? space.separatorIndex.includes(originalIndex) : space.separatorIndex === originalIndex : true; // 默认每个元素后都加分隔符
252
251
 
253
252
  if (shouldAddSeparator) {
254
253
  elements.push( /*#__PURE__*/_jsx("span", {
255
254
  className: "pro-group-separator-space",
256
255
  children: space.separator
257
- }, child.name ? `separator-${child.name}` : `separator-${originalIndex}`));
256
+ }, `separator-${String(child.name ?? originalIndex)}`));
258
257
  }
259
258
  }
260
259
  });
@@ -288,14 +287,14 @@ const FlexibleGroupRender = props => {
288
287
  // 查看模式下,如果没有配置separator,使用默认的 finalSeparator
289
288
  const separatorToUse = isView ? space?.separator || finalSeparator : space?.separator;
290
289
  if (index < visibleChildren.length - 1 && separatorToUse) {
291
- const shouldAddSeparator = space.separatorIndex ? Array.isArray(space.separatorIndex) ? space.separatorIndex.includes(originalIndex) : space.separatorIndex === originalIndex : true;
290
+ const shouldAddSeparator = space.separatorIndex != null ? Array.isArray(space.separatorIndex) ? space.separatorIndex.includes(originalIndex) : space.separatorIndex === originalIndex : true;
292
291
  if (shouldAddSeparator) {
293
292
  // 查看模式下使用不同的className,避免显示边框
294
293
  const separatorClassName = isView ? 'pro-group-separator-compact pro-group-separator-view' : 'pro-group-separator-compact';
295
294
  elements.push( /*#__PURE__*/_jsx("span", {
296
295
  className: separatorClassName,
297
296
  children: separatorToUse
298
- }, child.name ? `separator-${child.name}` : `separator-${originalIndex}`));
297
+ }, `separator-${String(child.name ?? originalIndex)}`));
299
298
  }
300
299
  }
301
300
  });
@@ -316,11 +315,6 @@ const FlexibleGroupRender = props => {
316
315
  // 检查是否有子项包含 show 函数,如果有则需要响应式更新
317
316
  const hasShowFunction = children.some(child => _isFunction(child.show));
318
317
 
319
- // 查看模式下空值处理
320
- if (isView && _isEmpty(children)) {
321
- return otherProps?.viewEmpty || '-';
322
- }
323
-
324
318
  // 查看模式下,检查所有children的值是否都为空
325
319
  if (isView && form && children.length > 0) {
326
320
  const allValuesEmpty = children.every(child => {
@@ -46,7 +46,7 @@ export const useTransformColumns = params => {
46
46
  // 响应式字段改变后的回调
47
47
  const changedCallback = (lastDependency, current) => {
48
48
  // 清值防抖 多次刷新时以最后一次为准
49
- if (clearNotShow !== false && names) {
49
+ if (clearNotShow !== false && (names || value)) {
50
50
  if (current?.show === false) {
51
51
  clearInterval(timerRef.current[index]);
52
52
  timerRef.current[index] = setTimeout(() => {
@@ -134,7 +134,7 @@ const LegacyGroup = props => {
134
134
  elements.push( /*#__PURE__*/_jsx("span", {
135
135
  className: "pro-group-separator-compact",
136
136
  children: newColumn.separator
137
- }, `separator-${newColumn.name || index}`));
137
+ }, `separator-${String(newColumn.name ?? index)}`));
138
138
  }
139
139
  });
140
140
  return /*#__PURE__*/_jsx("div", {
@@ -1,6 +1,6 @@
1
1
  import _isEqual from "lodash/isEqual";
2
2
  import { useDebounceFn, usePrevious, useRequest } from 'ahooks';
3
- import { useCallback, useEffect, useMemo, useState } from 'react';
3
+ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
4
4
  import locale, { formatMessage } from "../../../../../locale";
5
5
  const defaultPage = {
6
6
  pageNum: 1,
@@ -32,7 +32,7 @@ export function useRequestList(service, options, useRequestOptions) {
32
32
  } = useRequestOptions || {};
33
33
  const _defaultParams = Array.isArray(defaultParams) ? defaultParams?.[0] : defaultParams || {};
34
34
  // 搜索表单里的值
35
- const [searchValues, setSearchValues] = useState();
35
+ const [searchValues, setSearchValues] = useState({});
36
36
 
37
37
  // 当次执行service的请求,包括page参数
38
38
  const params = useMemo(() => {
@@ -60,18 +60,29 @@ export function useRequestList(service, options, useRequestOptions) {
60
60
 
61
61
  // 搜索条件变化时触发
62
62
  const prevParams = usePrevious(params);
63
+ const ready = useRequestOptions?.ready;
64
+ const prevReadyRef = useRef(ready);
63
65
  const {
64
- run: queryList
66
+ run: queryList,
67
+ cancel: cancelQueryList
65
68
  } = useDebounceFn(() => {
66
69
  run(params);
67
70
  }, {
68
71
  wait: 300
69
72
  });
70
73
  useEffect(() => {
74
+ const prevReady = prevReadyRef.current;
75
+ prevReadyRef.current = ready;
76
+ const isAutomaticReadyRun = useRequestOptions?.manual !== true && prevReady === false && ready === true;
77
+ if (ready === false || isAutomaticReadyRun) {
78
+ cancelQueryList();
79
+ return;
80
+ }
71
81
  if (prevParams && !_isEqual(prevParams, params)) {
72
82
  queryList();
73
83
  }
74
- }, [params, prevParams, queryList]);
84
+ }, [cancelQueryList, params, prevParams, queryList, ready, useRequestOptions?.manual]);
85
+ useEffect(() => cancelQueryList, [cancelQueryList]);
75
86
 
76
87
  // 分页变更
77
88
  const onChange = useCallback((current, pageSize) => {
@@ -80,15 +91,18 @@ export function useRequestList(service, options, useRequestOptions) {
80
91
  pageSize
81
92
  });
82
93
  }, [onPageChange]);
83
- const onSearch = useCallback(values => {
94
+ const onSearch = useCallback((values, force = false) => {
95
+ const normalizedValues = values && typeof values === 'object' && Object.values(values).every(value => value === undefined) ? {} : values;
84
96
  if (page.pageNum !== 1) {
85
97
  // 查询或重置都从第一页开始,保留当前每页条数
86
98
  onChange(1, page.pageSize);
87
99
  }
88
- if (!_isEqual(searchValues, values)) {
89
- setSearchValues(values);
100
+ if (!_isEqual(searchValues, normalizedValues)) {
101
+ setSearchValues(normalizedValues);
102
+ } else if (force && page.pageNum === 1) {
103
+ run(params);
90
104
  }
91
- }, [onChange, searchValues, page]);
105
+ }, [onChange, page, params, run, searchValues]);
92
106
 
93
107
  // 重置查询条件
94
108
  const onReset = useCallback(() => {