@zat-design/sisyphus-react 4.5.8-beta.6 → 4.5.8

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.
@@ -7,7 +7,7 @@ import { ReactSVG } from 'react-svg';
7
7
  import classNames from 'classnames';
8
8
  import { ProDrawerForm, useProConfig } from "../index";
9
9
  import { Trigger, ListView, TreeView, Cascader } from "./components";
10
- import { getFlatTreeData, filterCheckedNodes, getChildrenKeys, findTreeNodeByKey, getAllKeys, transformMessage, addLevelAndParentId } from "./utils";
10
+ import { getFlatTreeData, filterCheckedNodes, getChildrenKeys, findTreeNodeByKey, transformMessage, addLevelAndParentId } from "./utils";
11
11
  import { transformTreeToArray, treeNodeFind } from "../ProTable/components/RcTable/components/DraggableTable/components/DndWrapper/utils/index";
12
12
  import searchSVG from "../assets/input-search.svg";
13
13
  import locale, { formatMessage } from "../locale";
@@ -15,13 +15,23 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
15
15
  const LIST = 'LIST';
16
16
  const TREE = 'TREE';
17
17
  export const CASCADER = 'CASCADER';
18
+ const getSelectableValues = (flatTreeData, fieldNameValue) => flatTreeData.filter(item => item.disabled !== true).map(item => item[fieldNameValue]);
19
+ const isAllSelectableChecked = (selectableValues, checkedValues) => selectableValues.length > 0 && selectableValues.every(selectableValue => checkedValues.includes(selectableValue));
20
+ const getSelectionState = (currentState, checkedValues, fieldNames) => {
21
+ const selectableValues = getSelectableValues(currentState.flatTreeData, fieldNames.value);
22
+ return {
23
+ checkedValues,
24
+ treeViewData: filterCheckedNodes(currentState.originalTreeData, checkedValues, '', fieldNames),
25
+ checkAll: isAllSelectableChecked(selectableValues, checkedValues)
26
+ };
27
+ };
18
28
  const ProTreeModal = props => {
19
29
  const {
20
30
  dics = {}
21
31
  } = useProConfig('ProEnum');
22
32
  const listRef = useRef(null);
23
33
  const {
24
- open,
34
+ open: controlledOpen,
25
35
  value,
26
36
  onChange,
27
37
  dataSource,
@@ -83,20 +93,32 @@ const ProTreeModal = props => {
83
93
  console.error('allValue must be input');
84
94
  allValue = 'all';
85
95
  }
86
- const [state, setState] = useSetState({
96
+ const [{
97
+ open,
98
+ checkedValues,
99
+ treeData,
100
+ treeViewData,
101
+ originalTreeData,
102
+ flatTreeData,
103
+ searchStr,
104
+ checkAll,
105
+ transformedTree
106
+ }, setState] = useSetState({
87
107
  open: false,
88
108
  checkedValues: [],
89
- beforeClearAllValues: [],
90
- // 点击清空全部并点击关闭、此时数据回显示不正确
91
109
  treeData: [],
92
110
  treeViewData: [],
93
111
  originalTreeData: [],
94
112
  flatTreeData: [],
95
113
  searchStr: '',
96
114
  checkAll: false,
97
- allKeys: [],
98
115
  transformedTree: []
99
116
  });
117
+ const openSnapshotValuesRef = useRef([]);
118
+ const previousControlledOpenRef = useRef(controlledOpen);
119
+ const fieldNamesRef = useRef(fieldNames);
120
+ fieldNamesRef.current = fieldNames;
121
+ const selectableValues = useMemo(() => getSelectableValues(flatTreeData, fieldNameValue), [flatTreeData, fieldNameValue]);
100
122
  const fetchFunction = useRequestFunc(useRequest?.service, {
101
123
  manual: true,
102
124
  onSuccess: res => {
@@ -115,8 +137,7 @@ const ProTreeModal = props => {
115
137
  setState({
116
138
  treeData: responseData,
117
139
  originalTreeData: responseData,
118
- flatTreeData: getFlatTreeData(responseData, fieldNames, modeType),
119
- allKeys: getAllKeys(responseData, fieldNames)
140
+ flatTreeData: getFlatTreeData(responseData, fieldNames, modeType)
120
141
  });
121
142
  },
122
143
  debounceWait: 300,
@@ -129,8 +150,7 @@ const ProTreeModal = props => {
129
150
  setState({
130
151
  treeData: normalizedDataSource,
131
152
  originalTreeData: _cloneDeep(normalizedDataSource),
132
- flatTreeData,
133
- allKeys: getAllKeys(normalizedDataSource, fieldNames)
153
+ flatTreeData
134
154
  });
135
155
  } else if (enumCode) {
136
156
  let dictEnum = dics[enumCode] || [];
@@ -147,8 +167,7 @@ const ProTreeModal = props => {
147
167
  setState({
148
168
  treeData: normalizedDictEnum,
149
169
  originalTreeData: _cloneDeep(normalizedDictEnum),
150
- flatTreeData: getFlatTreeData(normalizedDictEnum, fieldNames),
151
- allKeys: getAllKeys(normalizedDictEnum, fieldNames)
170
+ flatTreeData: getFlatTreeData(normalizedDictEnum, fieldNames)
152
171
  });
153
172
  }
154
173
  }, [dataSource, enumCode]);
@@ -171,25 +190,33 @@ const ProTreeModal = props => {
171
190
  fetchFunction.run(params);
172
191
  }, [useRequest?.options]);
173
192
  useEffect(() => {
174
- setState({
175
- open
176
- });
177
- }, [open]);
193
+ const wasControlledOpen = previousControlledOpenRef.current === true;
194
+ if (controlledOpen === true && !wasControlledOpen) {
195
+ setState(prevState => {
196
+ openSnapshotValuesRef.current = [...prevState.checkedValues];
197
+ return {
198
+ open: true
199
+ };
200
+ });
201
+ } else if (controlledOpen === false && wasControlledOpen) {
202
+ const checkedValues = [...openSnapshotValuesRef.current];
203
+ setState(prevState => ({
204
+ open: false,
205
+ ...getSelectionState(prevState, checkedValues, fieldNamesRef.current)
206
+ }));
207
+ } else {
208
+ setState({
209
+ open: controlledOpen
210
+ });
211
+ }
212
+ previousControlledOpenRef.current = controlledOpen;
213
+ }, [controlledOpen]);
178
214
  useEffect(() => {
179
215
  if (value) {
180
- let checkedValues = [];
181
- const {
182
- treeData,
183
- allKeys,
184
- originalTreeData
185
- } = state;
186
- let treeViewData = [];
216
+ let nextCheckedValues = [];
217
+ let nextTreeViewData = [];
187
218
  if (allValue && typeof value === 'string' && allValue === value) {
188
- if (modeType === LIST) {
189
- checkedValues = treeData.map(item => item[fieldNameValue]) || [];
190
- } else if (modeType === TREE) {
191
- checkedValues = allKeys;
192
- }
219
+ nextCheckedValues = selectableValues;
193
220
  } else {
194
221
  if (!Array.isArray(value)) {
195
222
  console.error('Please pass in the array');
@@ -200,42 +227,43 @@ const ProTreeModal = props => {
200
227
  const isObjectArray = value.every(element => typeof element === 'object' && element !== null);
201
228
  if (!isObjectArray) {
202
229
  console.error('Please enter an array object');
203
- checkedValues = [];
230
+ nextCheckedValues = [];
204
231
  }
205
- checkedValues = value.map(item => item[fieldNameValue]);
232
+ nextCheckedValues = value.map(item => item[fieldNameValue]);
206
233
  } else {
207
- checkedValues = value;
234
+ nextCheckedValues = value;
208
235
  }
209
236
  }
210
- treeViewData = filterCheckedNodes(originalTreeData, checkedValues, '', fieldNames);
237
+ nextTreeViewData = filterCheckedNodes(originalTreeData, nextCheckedValues, '', fieldNames);
238
+ openSnapshotValuesRef.current = [...nextCheckedValues];
211
239
  setState({
212
- checkedValues,
213
- checkAll: checkedValues.length === allKeys.length,
214
- treeViewData,
215
- beforeClearAllValues: checkedValues
240
+ checkedValues: nextCheckedValues,
241
+ checkAll: isAllSelectableChecked(selectableValues, nextCheckedValues),
242
+ treeViewData: nextTreeViewData
216
243
  });
217
- } else if (modeType === LIST && state.flatTreeData && state.flatTreeData.length > 0) {
244
+ } else if (modeType === LIST && flatTreeData && flatTreeData.length > 0) {
218
245
  // mode: 'list' 下,如果没有 value prop,自动将 fixed 的项加入到 checkedValues
219
- const fixedItems = state.flatTreeData.filter(item => item.fixed === 'right').map(item => item[fieldNameValue]);
220
- if (fixedItems.length > 0 && state.checkedValues.length === 0) {
246
+ const fixedItems = flatTreeData.filter(item => item.fixed === 'right').map(item => item[fieldNameValue]);
247
+ if (fixedItems.length > 0 && checkedValues.length === 0) {
221
248
  // 只有当 checkedValues 为空时才自动添加 fixed 项,避免覆盖已有的选中状态
222
- const treeViewData = filterCheckedNodes(state.originalTreeData, fixedItems, '', fieldNames);
249
+ const nextTreeViewData = filterCheckedNodes(originalTreeData, fixedItems, '', fieldNames);
250
+ openSnapshotValuesRef.current = [...fixedItems];
223
251
  setState({
224
252
  checkedValues: fixedItems,
225
- checkAll: fixedItems.length === state.allKeys.length,
226
- treeViewData,
227
- beforeClearAllValues: fixedItems
253
+ checkAll: isAllSelectableChecked(selectableValues, fixedItems),
254
+ treeViewData: nextTreeViewData
228
255
  });
229
256
  }
230
257
  }
231
- }, [value, state.allKeys, state.open, state.flatTreeData, state.originalTreeData, modeType, fieldNameValue]);
258
+ }, [value, open, flatTreeData, originalTreeData, modeType, fieldNameValue, selectableValues]);
232
259
  useDeepCompareEffect(() => {
233
- const transformedTree = addLevelAndParentId(state.treeData, fieldNames);
260
+ const nextTransformedTree = addLevelAndParentId(treeData, fieldNames);
234
261
  setState({
235
- transformedTree
262
+ transformedTree: nextTransformedTree
236
263
  });
237
- }, [state.treeData]);
264
+ }, [treeData]);
238
265
  const handleClick = () => {
266
+ openSnapshotValuesRef.current = [...checkedValues];
239
267
  setState({
240
268
  open: true
241
269
  });
@@ -246,46 +274,37 @@ const ProTreeModal = props => {
246
274
  * close Drawer and onChange(values)
247
275
  */
248
276
  const handleFinish = () => {
249
- // 全选的时候返回 allValue 标记即可
250
- // 3.3.2 版本全选的时候返回所有值的合集 list
251
- if (allValue !== undefined && state.checkAll && !draggable) {
252
- if (labelInValue) {
253
- onChange?.(state.flatTreeData);
254
- } else {
255
- onChange?.(state.flatTreeData.map(item => item[fieldNameValue]));
256
- }
257
- } else if (draggable && span) {
277
+ if (draggable && span) {
258
278
  // 开启 draggable 使用拖拽后的顺序
259
279
  const checkedList = listRef.current?.onChange();
260
280
  onChange(checkedList);
261
281
  } else {
262
- let values = [];
282
+ let values = checkedValues;
263
283
  if (labelInValue) {
264
- state.checkedValues.forEach(val => {
265
- const option = state.flatTreeData.find(item => item[fieldNameValue] === val);
284
+ values = [];
285
+ checkedValues.forEach(val => {
286
+ const option = flatTreeData.find(item => item[fieldNameValue] === val);
266
287
  option && values.push(option);
267
288
  });
268
- } else {
269
- values = state.checkedValues;
270
289
  }
271
- if (min) {
272
- if (values.length < min) {
273
- message.error(formatMessage(locale?.ProTreeModal?.selectMin, {
274
- min
275
- }));
276
- return;
277
- }
290
+ const skipMinCheck = allValue !== undefined && checkAll && !draggable;
291
+ if (!skipMinCheck && min && values.length < min) {
292
+ message.error(formatMessage(locale?.ProTreeModal?.selectMin, {
293
+ min
294
+ }));
295
+ return;
278
296
  }
279
297
  onChange?.(values);
280
298
  }
299
+ openSnapshotValuesRef.current = [...checkedValues];
281
300
  // fix: 当有 openChange 时候、点击确定应该由关闭 openChange 控制
282
- if (!openChange || open === undefined) {
301
+ if (!openChange || controlledOpen === undefined) {
283
302
  setState({
284
303
  open: false
285
304
  });
286
305
  openChange?.(false);
287
306
  }
288
- if (openChange && open !== undefined) {
307
+ if (openChange && controlledOpen !== undefined) {
289
308
  openChange?.(true);
290
309
  }
291
310
  };
@@ -295,19 +314,18 @@ const ProTreeModal = props => {
295
314
  */
296
315
  const handleClearAll = (immediateSubmit = false) => {
297
316
  // 处理 ProTable 场景下 disabled 的不需要被清理
298
- const _checkedValues = span ? state.flatTreeData.filter(item => item.disabled)?.map(item => item[fieldNameValue]) : [];
317
+ const nextCheckedValues = span ? flatTreeData.filter(item => item.disabled)?.map(item => item[fieldNameValue]) : [];
299
318
  setState({
300
- checkedValues: _checkedValues,
301
- beforeClearAllValues: state.checkedValues,
302
- // 把清空全部之前的数据记录下
319
+ checkedValues: nextCheckedValues,
303
320
  treeViewData: [],
304
321
  checkAll: false
305
322
  });
306
323
  if (immediateSubmit) {
324
+ openSnapshotValuesRef.current = [...nextCheckedValues];
307
325
  if (labelInValue) {
308
326
  onChange?.([]);
309
327
  } else {
310
- onChange?.(_checkedValues);
328
+ onChange?.(nextCheckedValues);
311
329
  }
312
330
  }
313
331
  };
@@ -316,11 +334,11 @@ const ProTreeModal = props => {
316
334
  * Drawer close
317
335
  */
318
336
  const handleClose = () => {
319
- setState({
337
+ const restoredCheckedValues = [...openSnapshotValuesRef.current];
338
+ setState(prevState => ({
320
339
  open: false,
321
- checkedValues: state.beforeClearAllValues,
322
- beforeClearAllValues: []
323
- });
340
+ ...getSelectionState(prevState, restoredCheckedValues, fieldNames)
341
+ }));
324
342
  openChange?.(false);
325
343
  };
326
344
 
@@ -329,25 +347,25 @@ const ProTreeModal = props => {
329
347
  * @param values
330
348
  */
331
349
  const handleListCheckChange = (e, code) => {
332
- let checkedValues = [...state.checkedValues];
350
+ let nextCheckedValues = [...checkedValues];
333
351
  const {
334
352
  checked
335
353
  } = e.target;
336
354
  if (!checked) {
337
- checkedValues = checkedValues.filter(value => value !== code);
355
+ nextCheckedValues = nextCheckedValues.filter(value => value !== code);
338
356
  } else if (draggable && span) {
339
357
  // 固定在右侧的情况
340
- const fixedOption = state.flatTreeData.find(item => item.fixed === 'right') || {};
341
- const fixedIdx = checkedValues.findIndex(value => value === fixedOption[fieldNameValue]);
358
+ const fixedOption = flatTreeData.find(item => item.fixed === 'right') || {};
359
+ const fixedIdx = nextCheckedValues.findIndex(value => value === fixedOption[fieldNameValue]);
342
360
  if (fixedIdx >= 0) {
343
- checkedValues.splice(fixedIdx, 0, code);
361
+ nextCheckedValues.splice(fixedIdx, 0, code);
344
362
  } else {
345
- checkedValues.push(code);
363
+ nextCheckedValues.push(code);
346
364
  }
347
365
  } else {
348
- checkedValues.push(code);
366
+ nextCheckedValues.push(code);
349
367
  }
350
- if (max && checkedValues.length > max) {
368
+ if (max && nextCheckedValues.length > max) {
351
369
  message.error(maxMessage ? transformMessage({
352
370
  max
353
371
  }, maxMessage) : formatMessage(locale?.ProTreeModal?.selectMax, {
@@ -356,8 +374,8 @@ const ProTreeModal = props => {
356
374
  return;
357
375
  }
358
376
  setState({
359
- checkedValues,
360
- checkAll: checkedValues.length === state.flatTreeData.length
377
+ checkedValues: nextCheckedValues,
378
+ checkAll: isAllSelectableChecked(selectableValues, nextCheckedValues)
361
379
  });
362
380
  };
363
381
  const handleDragEndChange = checkedValues => {
@@ -366,89 +384,86 @@ const ProTreeModal = props => {
366
384
  });
367
385
  };
368
386
  const onCheck = (checkedKeys, info) => {
369
- let checkedValues = [...state.checkedValues];
370
- const {
371
- originalTreeData
372
- } = state;
387
+ let nextCheckedValues = [...checkedValues];
373
388
 
374
389
  // 如果有检索则自管理
375
- if (state.searchStr) {
390
+ if (searchStr) {
376
391
  const {
377
392
  node
378
393
  } = info;
379
394
  // 从完整树中找到当前节点
380
- const activeNode = treeNodeFind(state.transformedTree, t => t[fieldNameValue] === node[fieldNameValue], {
395
+ const activeNode = treeNodeFind(transformedTree, t => t[fieldNameValue] === node[fieldNameValue], {
381
396
  childrenKey: fieldNames.children
382
397
  });
383
398
  const allChildren = transformTreeToArray([activeNode], {
384
399
  childrenKey: fieldNames.children
385
400
  })?.map(item => item[fieldNameValue]);
386
401
  // 子项合并勾选
387
- checkedValues = checkedValues.concat(allChildren);
402
+ nextCheckedValues = nextCheckedValues.concat(allChildren);
388
403
  // 从完整树中拿到父节点 只要存在父节点,那么就判断当前children是否全被勾选 若全被勾选就合并当前key到勾选队列
389
- const _recourse = findNode => {
404
+ const appendCheckedParentKeys = findNode => {
390
405
  if (findNode.parentId) {
391
- const parentNode = treeNodeFind(state.transformedTree, t => t[fieldNameValue] === findNode.parentId, {
406
+ const parentNode = treeNodeFind(transformedTree, t => t[fieldNameValue] === findNode.parentId, {
392
407
  childrenKey: fieldNames.children
393
408
  });
394
409
  const parentChildrenKeys = transformTreeToArray([parentNode], {
395
410
  childrenKey: fieldNames.children
396
411
  })?.map(item => item[fieldNameValue]);
397
412
  const parentChildrenAllChecked = parentChildrenKeys.every(key => {
398
- return checkedValues.includes(key);
413
+ return nextCheckedValues.includes(key);
399
414
  });
400
415
  if (parentChildrenAllChecked) {
401
416
  // 把当前父节点追加进来
402
- checkedValues = checkedValues.concat([parentNode[fieldNameValue]]);
417
+ nextCheckedValues = nextCheckedValues.concat([parentNode[fieldNameValue]]);
403
418
  // 继续向上查找
404
419
  if (parentNode.parentId) {
405
- _recourse(parentNode);
420
+ appendCheckedParentKeys(parentNode);
406
421
  }
407
422
  }
408
423
  }
409
424
  };
410
- _recourse(activeNode);
425
+ appendCheckedParentKeys(activeNode);
411
426
  }
412
- const _checkStrictly = state.searchStr ? true : checkStrictly;
427
+ const effectiveCheckStrictly = searchStr ? true : checkStrictly;
413
428
 
414
429
  // 此时应该取消掉自身并包含它所有的子集
415
- if (!info.checked && !_checkStrictly) {
430
+ if (!info.checked && !effectiveCheckStrictly) {
416
431
  // 1. 取消自身
417
432
  // 2. 把所有的子节点也要取消
418
- const childrenkeys = [];
419
- getChildrenKeys(info.node, childrenkeys, fieldNames, 'treeCheck');
420
- checkedValues = checkedValues.filter(key => !childrenkeys.includes(key));
433
+ const childrenKeys = [];
434
+ getChildrenKeys(info.node, childrenKeys, fieldNames, 'treeCheck');
435
+ nextCheckedValues = nextCheckedValues.filter(key => !childrenKeys.includes(key));
421
436
 
422
437
  // 3. 取消父节点
423
438
  const parentNodes = findTreeNodeByKey(originalTreeData, info.node.key, fieldNames);
424
439
  const parentKeys = parentNodes.reduce((prev, curr) => prev.concat(curr[fieldNameValue]), []);
425
- checkedValues = checkedValues.filter(key => !parentKeys.includes(key));
440
+ nextCheckedValues = nextCheckedValues.filter(key => !parentKeys.includes(key));
426
441
  } else {
427
- // _checkStrictly 模式下取 checkedKeys.checked 或者自身的 key
428
- if (_checkStrictly) {
442
+ // checkStrictly 模式下取 checkedKeys.checked 或者自身的 key
443
+ if (effectiveCheckStrictly) {
429
444
  if (!info.checked) {
430
- checkedValues = checkedValues.filter(key => key !== info.node.key);
445
+ nextCheckedValues = nextCheckedValues.filter(key => key !== info.node.key);
431
446
  }
432
447
  checkedKeys = checkedKeys.checked || [];
433
448
  }
434
449
  checkedKeys.forEach(key => {
435
- const exist = checkedValues.includes(key);
450
+ const exist = nextCheckedValues.includes(key);
436
451
  if (info.checked && !exist) {
437
- checkedValues.push(key);
452
+ nextCheckedValues.push(key);
438
453
  }
439
454
  });
440
455
  }
441
456
 
442
457
  // 根据选中的筛选出 viewTreeData
443
- let treeViewData = [];
458
+ let nextTreeViewData = [];
444
459
  if (!checkStrictly) {
445
- treeViewData = filterCheckedNodes(originalTreeData, checkedValues, '', fieldNames);
460
+ nextTreeViewData = filterCheckedNodes(originalTreeData, nextCheckedValues, '', fieldNames);
446
461
  } else {
447
- treeViewData = state.flatTreeData.filter(item => {
448
- return checkedValues.includes(item[fieldNameValue]);
462
+ nextTreeViewData = flatTreeData.filter(item => {
463
+ return nextCheckedValues.includes(item[fieldNameValue]);
449
464
  });
450
465
  }
451
- if (max && checkedValues.length > max) {
466
+ if (max && nextCheckedValues.length > max) {
452
467
  message.error(maxMessage ? transformMessage({
453
468
  max
454
469
  }, maxMessage) : formatMessage(locale?.ProTreeModal?.selectMax, {
@@ -457,9 +472,9 @@ const ProTreeModal = props => {
457
472
  return;
458
473
  }
459
474
  setState({
460
- checkedValues,
461
- treeViewData,
462
- checkAll: state.allKeys.length === checkedValues.length
475
+ checkedValues: nextCheckedValues,
476
+ treeViewData: nextTreeViewData,
477
+ checkAll: isAllSelectableChecked(selectableValues, nextCheckedValues)
463
478
  });
464
479
  };
465
480
 
@@ -469,7 +484,7 @@ const ProTreeModal = props => {
469
484
  */
470
485
  const handleFilterClose = fileNameValue => {
471
486
  setState({
472
- checkedValues: state.checkedValues.filter(value => value !== fileNameValue),
487
+ checkedValues: checkedValues.filter(value => value !== fileNameValue),
473
488
  checkAll: false
474
489
  });
475
490
  };
@@ -480,36 +495,33 @@ const ProTreeModal = props => {
480
495
  * @param node
481
496
  */
482
497
  const treeFilterClose = (fileNamekey, node) => {
483
- let checkedValues = [...state.checkedValues];
484
- let treeViewData = [];
485
- const {
486
- originalTreeData
487
- } = state;
498
+ let nextCheckedValues = [...checkedValues];
499
+ let nextTreeViewData = [];
488
500
  if (checkStrictly) {
489
- checkedValues = checkedValues.filter(key => key !== fileNamekey);
501
+ nextCheckedValues = nextCheckedValues.filter(key => key !== fileNamekey);
490
502
  // handleFilterClose
491
- treeViewData = state.flatTreeData.filter(item => {
492
- return checkedValues.includes(item[fieldNameValue]);
503
+ nextTreeViewData = flatTreeData.filter(item => {
504
+ return nextCheckedValues.includes(item[fieldNameValue]);
493
505
  });
494
506
  } else {
495
507
  // 1. 取消自身
496
- checkedValues = checkedValues.filter(key => key !== fileNamekey);
508
+ nextCheckedValues = nextCheckedValues.filter(key => key !== fileNamekey);
497
509
  // 2. 把所有的子节点也要取消
498
- const childrenkeys = [];
499
- getChildrenKeys(node, childrenkeys, fieldNames, 'treeClose');
500
- checkedValues = checkedValues.filter(key => !childrenkeys.includes(key));
510
+ const childrenKeys = [];
511
+ getChildrenKeys(node, childrenKeys, fieldNames, 'treeClose');
512
+ nextCheckedValues = nextCheckedValues.filter(key => !childrenKeys.includes(key));
501
513
 
502
514
  // 3. 取消父节点
503
515
  const parentNodes = findTreeNodeByKey(originalTreeData, fileNamekey, fieldNames);
504
516
  const parentKeys = parentNodes.reduce((prev, curr) => prev.concat(curr[fieldNames.value]), []);
505
- checkedValues = checkedValues.filter(key => !parentKeys.includes(key));
517
+ nextCheckedValues = nextCheckedValues.filter(key => !parentKeys.includes(key));
506
518
 
507
519
  // 根据选中的筛选出 viewTreeData
508
- treeViewData = filterCheckedNodes(originalTreeData, checkedValues, '', fieldNames);
520
+ nextTreeViewData = filterCheckedNodes(originalTreeData, nextCheckedValues, '', fieldNames);
509
521
  }
510
522
  setState({
511
- checkedValues,
512
- treeViewData,
523
+ checkedValues: nextCheckedValues,
524
+ treeViewData: nextTreeViewData,
513
525
  checkAll: false
514
526
  });
515
527
  };
@@ -518,12 +530,12 @@ const ProTreeModal = props => {
518
530
  } = useDebounceFn(str => {
519
531
  if (modeType === LIST || modeType === CASCADER) {
520
532
  const isCASCADER = modeType === CASCADER;
521
- const data = state.flatTreeData.filter(item => {
533
+ const filteredData = flatTreeData.filter(item => {
522
534
  const title = isCASCADER ? item?.title : item[fieldNameLabel];
523
535
  return title.includes(str);
524
536
  });
525
537
  setState({
526
- treeData: !str ? state.originalTreeData : data
538
+ treeData: !str ? originalTreeData : filteredData
527
539
  });
528
540
  }
529
541
  }, {
@@ -571,9 +583,9 @@ const ProTreeModal = props => {
571
583
  });
572
584
  }
573
585
  return /*#__PURE__*/_jsx(Trigger, {
574
- checkedValues: state.checkedValues,
586
+ checkedValues: checkedValues,
575
587
  value: value,
576
- checkAll: state.checkAll,
588
+ checkAll: checkAll,
577
589
  triggerStyle: style,
578
590
  disabled: disabled,
579
591
  isView: isView,
@@ -585,7 +597,7 @@ const ProTreeModal = props => {
585
597
  appointChange: appointChange,
586
598
  appointProps: appointProps
587
599
  });
588
- }, [state.checkedValues, state.checkAll, style, disabled, isView, value]);
600
+ }, [checkedValues, checkAll, style, disabled, isView, value]);
589
601
 
590
602
  /**
591
603
  * 全选操作
@@ -594,26 +606,26 @@ const ProTreeModal = props => {
594
606
  const {
595
607
  checked
596
608
  } = e.target;
597
- let checkedValues = [];
598
- let treeViewData = [];
599
- if (modeType === LIST || modeType === CASCADER) {
600
- if (checked) {
601
- checkedValues = state.flatTreeData.map(item => item[fieldNameValue]);
602
- } else if (!checked && span) {
609
+ let nextCheckedValues = [];
610
+ let nextTreeViewData = [];
611
+ if (checked) {
612
+ nextCheckedValues = flatTreeData.filter(item => item.disabled !== true || checkedValues.includes(item[fieldNameValue])).map(item => item[fieldNameValue]);
613
+ } else if (modeType === LIST || modeType === CASCADER) {
614
+ if (span) {
603
615
  // ProTable 场景下 disabled 不取消掉
604
- checkedValues = state.flatTreeData.filter(item => item.disabled).map(item => item[fieldNameValue]);
605
- } else if (!checked) {
606
- checkedValues = [];
616
+ nextCheckedValues = flatTreeData.filter(item => item.disabled).map(item => item[fieldNameValue]);
617
+ } else {
618
+ nextCheckedValues = [];
607
619
  }
608
- } else if (modeType === TREE) {
609
- checkedValues = checked ? state.allKeys : [];
620
+ }
621
+ if (modeType === TREE) {
610
622
  if (checkStrictly) {
611
- treeViewData = [...state.flatTreeData];
623
+ nextTreeViewData = flatTreeData.filter(item => nextCheckedValues.includes(item[fieldNameValue]));
612
624
  } else {
613
- treeViewData = filterCheckedNodes(state.originalTreeData, checkedValues, '', fieldNames);
625
+ nextTreeViewData = filterCheckedNodes(originalTreeData, nextCheckedValues, '', fieldNames);
614
626
  }
615
627
  }
616
- if (max && checkedValues.length > max) {
628
+ if (max && nextCheckedValues.length > max) {
617
629
  message.error(maxMessage ? transformMessage({
618
630
  max
619
631
  }, maxMessage) : formatMessage(locale?.ProTreeModal?.selectMax, {
@@ -622,9 +634,9 @@ const ProTreeModal = props => {
622
634
  return;
623
635
  }
624
636
  setState({
625
- checkedValues,
626
- checkAll: checked,
627
- treeViewData
637
+ checkedValues: nextCheckedValues,
638
+ checkAll: isAllSelectableChecked(selectableValues, nextCheckedValues),
639
+ treeViewData: nextTreeViewData
628
640
  });
629
641
  };
630
642
 
@@ -633,7 +645,7 @@ const ProTreeModal = props => {
633
645
  * @returns
634
646
  */
635
647
  const renderContainer = () => {
636
- if (state.treeData.length === 0 && state.searchStr) {
648
+ if (treeData.length === 0 && searchStr) {
637
649
  return /*#__PURE__*/_jsx("div", {
638
650
  className: "pro-tree-modal-no-checks",
639
651
  children: locale?.ProTreeModal?.noFinal
@@ -642,11 +654,11 @@ const ProTreeModal = props => {
642
654
  switch (modeType) {
643
655
  case LIST:
644
656
  return /*#__PURE__*/_jsx(ListView, {
645
- treeData: state.treeData,
657
+ treeData: treeData,
646
658
  optionRender: optionRender,
647
- checkedValues: state.checkedValues,
659
+ checkedValues: checkedValues,
648
660
  handleOnChange: handleListCheckChange,
649
- searchStr: state.searchStr,
661
+ searchStr: searchStr,
650
662
  showCodeName: showCodeName,
651
663
  disabled: disabled || isView,
652
664
  fieldNames: fieldNames,
@@ -654,13 +666,13 @@ const ProTreeModal = props => {
654
666
  });
655
667
  case TREE:
656
668
  return /*#__PURE__*/_jsx(TreeView, {
657
- treeData: state.transformedTree,
658
- originalTreeData: state.originalTreeData,
659
- flatTreeData: state.flatTreeData,
660
- checkedValues: state.checkedValues,
669
+ treeData: transformedTree,
670
+ originalTreeData: originalTreeData,
671
+ flatTreeData: flatTreeData,
672
+ checkedValues: checkedValues,
661
673
  onCheck: onCheck,
662
674
  optionRender: optionRender,
663
- searchStr: state.searchStr,
675
+ searchStr: searchStr,
664
676
  showCodeName: showCodeName,
665
677
  disabled: disabled || isView,
666
678
  checkStrictly: checkStrictly,
@@ -668,24 +680,24 @@ const ProTreeModal = props => {
668
680
  fieldNames: fieldNames
669
681
  });
670
682
  case CASCADER:
671
- if (state.searchStr && state.treeData.length) {
683
+ if (searchStr && treeData.length) {
672
684
  return /*#__PURE__*/_jsx(ListView, {
673
- treeData: state.treeData,
685
+ treeData: treeData,
674
686
  modeType: CASCADER,
675
687
  optionRender: optionRender,
676
- checkedValues: state.checkedValues,
688
+ checkedValues: checkedValues,
677
689
  handleOnChange: handleListCheckChange,
678
- searchStr: state.searchStr,
690
+ searchStr: searchStr,
679
691
  showCodeName: showCodeName,
680
692
  disabled: disabled || isView,
681
693
  fieldNames: fieldNames
682
694
  });
683
695
  }
684
696
  return /*#__PURE__*/_jsx(Cascader, {
685
- dataSource: state.treeData,
697
+ dataSource: treeData,
686
698
  fieldNames: fieldNames,
687
- checkedValues: state.checkedValues,
688
- searchStr: state.searchStr,
699
+ checkedValues: checkedValues,
700
+ searchStr: searchStr,
689
701
  showCodeName: showCodeName,
690
702
  handleOnChange: handleListCheckChange,
691
703
  optionRender: optionRender
@@ -696,21 +708,21 @@ const ProTreeModal = props => {
696
708
  };
697
709
  const listTreeData = useMemo(() => {
698
710
  const checkListOptions = [];
699
- state.checkedValues.forEach(key => {
700
- const option = state.flatTreeData.find(item => item[fieldNameValue] === key);
711
+ checkedValues.forEach(key => {
712
+ const option = flatTreeData.find(item => item[fieldNameValue] === key);
701
713
  if (option) {
702
714
  checkListOptions.push(option);
703
715
  }
704
716
  });
705
717
  return checkListOptions;
706
- }, [state.checkedValues, state.flatTreeData]);
718
+ }, [checkedValues, flatTreeData]);
707
719
 
708
720
  /**
709
721
  * 勾选后的右侧展示
710
722
  * @returns
711
723
  */
712
724
  const renderView = () => {
713
- if (state.checkedValues.length === 0) {
725
+ if (checkedValues.length === 0) {
714
726
  return /*#__PURE__*/_jsx("div", {
715
727
  className: "pro-tree-modal-no-checks",
716
728
  children: locale?.ProTreeModal?.noCheck
@@ -726,7 +738,7 @@ const ProTreeModal = props => {
726
738
  fieldNames: fieldNames,
727
739
  disabled: disabled || isView,
728
740
  draggable: draggable,
729
- flatTreeData: state.flatTreeData,
741
+ flatTreeData: flatTreeData,
730
742
  span: span,
731
743
  ref: listRef,
732
744
  optionRender: optionRender,
@@ -738,7 +750,7 @@ const ProTreeModal = props => {
738
750
  mode: "view",
739
751
  checkStrictly: checkStrictly,
740
752
  showCodeName: showCodeName,
741
- treeData: checkStrictly ? listTreeData : state.treeViewData,
753
+ treeData: checkStrictly ? listTreeData : treeViewData,
742
754
  tags: tags,
743
755
  fieldNames: fieldNames,
744
756
  disabled: disabled || isView,
@@ -757,16 +769,16 @@ const ProTreeModal = props => {
757
769
  return /*#__PURE__*/_jsx(_Fragment, {
758
770
  children: /*#__PURE__*/_jsxs("div", {
759
771
  className: "pro-tree-modal",
760
- children: [open === undefined && TriggerComponent, /*#__PURE__*/_jsx(ProDrawerForm, {
772
+ children: [controlledOpen === undefined && TriggerComponent, /*#__PURE__*/_jsx(ProDrawerForm, {
761
773
  onOk: handleFinish,
762
774
  onCancel: handleClose,
763
775
  okDisabled: disabled,
764
- open: state.open,
776
+ open: open,
765
777
  title: title,
766
778
  mode: "Modal",
767
779
  className: "pro-tree-modal-container",
768
780
  extraLeft: allValue !== undefined && !isView ? /*#__PURE__*/_jsx(Checkbox, {
769
- checked: state.checkAll,
781
+ checked: checkAll,
770
782
  disabled: disabled,
771
783
  onChange: handleAllCheck,
772
784
  children: locale?.ProTreeModal?.checkAll
@@ -778,7 +790,7 @@ const ProTreeModal = props => {
778
790
  children: [/*#__PURE__*/_jsx(Input, {
779
791
  disabled: disabled,
780
792
  allowClear: true,
781
- value: state.searchStr,
793
+ value: searchStr,
782
794
  placeholder: placeholder || locale?.ProTreeModal?.input,
783
795
  className: "pro-tree-modal-search",
784
796
  onChange: e => handleSetSearchStr(e.target.value),
@@ -795,7 +807,7 @@ const ProTreeModal = props => {
795
807
  children: [/*#__PURE__*/_jsxs("div", {
796
808
  className: "pro-tree-modal-box-header",
797
809
  children: [/*#__PURE__*/_jsxs("span", {
798
- children: [locale?.ProTreeModal?.check, " (", state.checkedValues.length, "/", max || state.flatTreeData.length, ")"]
810
+ children: [locale?.ProTreeModal?.check, " (", checkedValues.length, "/", max || flatTreeData.length, ")"]
799
811
  }), !isView ? /*#__PURE__*/_jsx(Button, {
800
812
  disabled: disabled,
801
813
  type: "link",