@tddc/assign-modal 3.0.8 → 3.1.0

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.
@@ -0,0 +1,851 @@
1
+ import { Checkbox, Tree, Input, Ellipsis, Segmented, Empty, Icon } from 'tntd';
2
+ import { useEffect, useState, useCallback, useRef, useMemo } from 'react';
3
+
4
+ import { cloneDeep, debounce } from 'lodash';
5
+ import './index.less';
6
+ import { findSameCodePath, preorder, mergeAndDeduplicate, doSearch } from './utils';
7
+ import { getText } from '../../locale';
8
+
9
+ const { TreeNode } = Tree;
10
+ let path = []; // 上级机构到当前机构的路径
11
+
12
+ const AssignModal = (props) => {
13
+ const {
14
+ orgList = [],
15
+ dataItem = {},
16
+ disabled,
17
+ appList,
18
+ onChange,
19
+ orgTitle,
20
+ appTitle,
21
+ userTitle,
22
+ orgCheckboxTitle,
23
+ appCheckboxTitle,
24
+ userCheckboxTitle,
25
+ userList,
26
+ showUser,
27
+ } = props;
28
+ let { appCodes = [], orgCodes = [], orgCode, appCode, accounts = [], account } = dataItem;
29
+
30
+ const orgMapRef = useRef({});
31
+ const appMapRef = useRef({});
32
+ const userMapRef = useRef({});
33
+
34
+ const rootNode = orgList[0];
35
+
36
+ const [allOrg, allApp, allUser] = useMemo(() => {
37
+ let org = preorder(
38
+ rootNode,
39
+ (key, root) => {
40
+ orgMapRef.current[key] = root;
41
+ },
42
+ true,
43
+ );
44
+ let app = appList.map((item) => {
45
+ appMapRef.current[item.value] = item;
46
+ return item.value;
47
+ });
48
+ let user =
49
+ userList?.map((item) => {
50
+ userMapRef.current[item.account] = item;
51
+ return item.account;
52
+ }) || [];
53
+
54
+ return [org, app, user];
55
+ }, [rootNode, appList, userList]);
56
+
57
+ const titleOptions = [
58
+ `${orgTitle || getText('availableOrgs', props?.lang)}`,
59
+ `${appTitle || getText('availableApps', props?.lang)}`,
60
+ `${userTitle || getText('availableUsers', props?.lang)}`,
61
+ ];
62
+
63
+ if (!showUser) {
64
+ titleOptions.pop();
65
+ }
66
+
67
+ const [treeData, setTreeData] = useState(orgList);
68
+ const [curIndex, setCurIndex] = useState(0);
69
+ const [curValue, setCurValue] = useState(titleOptions[0]);
70
+
71
+ const [checkedKeys, setCheckedKeys] = useState([]);
72
+ const [appKeys, setAppKeys] = useState(appCodes || []);
73
+ const [userKeys, setUserKeys] = useState(accounts || []);
74
+
75
+ const [allOrgChecked, setAllOrgChecked] = useState(false);
76
+ const [allAppChecked, setAllAppChecked] = useState(false);
77
+ const [allUserChecked, setAllUserChecked] = useState(false);
78
+
79
+ const [filterOrg, setFilterOrg] = useState();
80
+ const [filterUser, setFilterUser] = useState();
81
+ const [filterApp, setFilterApp] = useState();
82
+
83
+ useEffect(() => {
84
+ // path 和 allOrgList 赋值
85
+ path = findSameCodePath(rootNode, orgCode);
86
+
87
+ let initOrgs = [];
88
+ let initApps = [];
89
+ let initAccounts = [];
90
+ if (orgCodes.includes('all')) {
91
+ setAllOrgChecked(orgCodes.includes('all'));
92
+ initOrgs = allOrg;
93
+ } else {
94
+ initOrgs = Array.from(new Set([...(orgCodes || []), ...path]));
95
+ }
96
+ if (appCodes.includes('all')) {
97
+ setAllAppChecked(appCodes.includes('all'));
98
+ initApps = allApp;
99
+ } else {
100
+ initApps = Array.from(new Set([...(appCodes || []), appCode]));
101
+ }
102
+
103
+ if (showUser) {
104
+ if (accounts.includes('all')) {
105
+ setAllUserChecked(true);
106
+ initAccounts = allUser;
107
+ } else {
108
+ initAccounts = Array.from(new Set([...(accounts || []), account]));
109
+ }
110
+ }
111
+ setCheckedKeys(initOrgs);
112
+ setAppKeys(initApps || []);
113
+ setUserKeys(initAccounts || []);
114
+ onChange &&
115
+ onChange({
116
+ appKeys: appCodes.includes('all') ? ['all'] : initApps,
117
+ checkedKeys: orgCodes.includes('all') ? ['all'] : initOrgs,
118
+ userKeys: accounts.includes('all') ? ['all'] : initAccounts,
119
+ appCheckAll: appCodes.includes('all'),
120
+ orgCheckAll: orgCodes.includes('all'),
121
+ userCheckAll: accounts.includes('all'),
122
+ checkData: {
123
+ apps: initApps,
124
+ orgs: initOrgs,
125
+ accounts: initAccounts,
126
+ },
127
+ });
128
+ }, [dataItem]);
129
+
130
+ useEffect(() => {
131
+ doSearch(filterOrg, orgMapRef.current, () => {
132
+ let newData = cloneDeep([orgMapRef.current[orgList[0].value]]);
133
+ setTreeData(newData);
134
+ });
135
+ }, [filterOrg]);
136
+
137
+ const loopTreeNodes = (data, level = 0) => {
138
+ const NodeTitle = ({ node }) => {
139
+ return <div className="node-title">{node.title}</div>;
140
+ };
141
+
142
+ return data.map((item) => {
143
+ const { code, show } = item || {};
144
+ if (!show) return null;
145
+
146
+ let orgDisabled = path.includes(code);
147
+
148
+ if (item.children) {
149
+ return (
150
+ <TreeNode
151
+ key={code}
152
+ title={<NodeTitle node={item} />}
153
+ item={item}
154
+ disabled={orgDisabled || disabled || allOrgChecked}
155
+ >
156
+ {loopTreeNodes(item.children, level + 1)}
157
+ </TreeNode>
158
+ );
159
+ }
160
+ return (
161
+ <TreeNode
162
+ style={{
163
+ paddingLeft: `${(level + 1) * 14}px`,
164
+ marginLeft: `-${level * 14}px`,
165
+ }}
166
+ key={code}
167
+ title={<NodeTitle node={item} />}
168
+ item={item}
169
+ disabled={orgDisabled || disabled}
170
+ />
171
+ );
172
+ });
173
+ };
174
+
175
+ const onCheck = (keys, info) => {
176
+ let {
177
+ node: { props },
178
+ } = info;
179
+ let { item } = props;
180
+ let { path } = item;
181
+ let { checked } = keys;
182
+
183
+ if (!info.node.isLeaf() && !info.node.checked) {
184
+ let arr = preorder(info.node.props.item);
185
+ arr.splice(0, 1);
186
+ arr.map((item) => {
187
+ let i = checked.findIndex((i) => i === item);
188
+ if (i !== -1) checked.splice(i, 1);
189
+ });
190
+ }
191
+ if (info.checked) {
192
+ checked.pop();
193
+ checked = mergeAndDeduplicate(checked, path);
194
+ }
195
+
196
+ setCheckedKeys(checked);
197
+
198
+ onChange({
199
+ appKeys: allAppChecked ? ['all'] : appKeys,
200
+ checkedKeys: checked,
201
+ appCheckAll: allAppChecked,
202
+ orgCheckAll: allOrgChecked,
203
+ userKeys: allUserChecked ? ['all'] : userKeys,
204
+ userCheckAll: allUserChecked,
205
+ checkData: {
206
+ apps: appKeys,
207
+ orgs: checked,
208
+ accounts: userKeys,
209
+ },
210
+ });
211
+ };
212
+
213
+ const assignApp = (e) => {
214
+ let value = '';
215
+ let newAppKeys = [];
216
+ if (e.target.checked) {
217
+ value = e.target.value;
218
+ newAppKeys = [...appKeys, value];
219
+ } else {
220
+ value = e.target.value;
221
+ newAppKeys = cloneDeep(appKeys);
222
+ newAppKeys.map((item, index) => {
223
+ if (value === item) {
224
+ newAppKeys.splice(index, 1);
225
+ }
226
+ });
227
+ }
228
+ setAppKeys(newAppKeys);
229
+ onChange({
230
+ appKeys: newAppKeys,
231
+ checkedKeys: allOrgChecked ? ['all'] : checkedKeys,
232
+ appCheckAll: allAppChecked,
233
+ orgCheckAll: allOrgChecked,
234
+ userKeys: allUserChecked ? ['all'] : userKeys,
235
+ userCheckAll: allUserChecked,
236
+ checkData: {
237
+ apps: newAppKeys,
238
+ orgs: checkedKeys,
239
+ accounts: userKeys,
240
+ },
241
+ });
242
+ };
243
+
244
+ const assignUser = (e) => {
245
+ let value = '';
246
+ let newUserKeys = [];
247
+ if (e.target.checked) {
248
+ value = e.target.value;
249
+ newUserKeys = [...userKeys, value];
250
+ } else {
251
+ value = e.target.value;
252
+ newUserKeys = cloneDeep(userKeys);
253
+ newUserKeys.map((item, index) => {
254
+ if (value === item) {
255
+ newUserKeys.splice(index, 1);
256
+ }
257
+ });
258
+ }
259
+ setUserKeys(newUserKeys);
260
+ onChange({
261
+ appKeys,
262
+ checkedKeys: allOrgChecked ? ['all'] : checkedKeys,
263
+ appCheckAll: allAppChecked,
264
+ orgCheckAll: allOrgChecked,
265
+ userKeys: newUserKeys,
266
+ userCheckAll: allUserChecked,
267
+ checkData: {
268
+ apps: appKeys,
269
+ orgs: checkedKeys,
270
+ accounts: newUserKeys,
271
+ },
272
+ });
273
+ };
274
+
275
+ // org全局授权
276
+ const checkAllOrg = (e) => {
277
+ let orgChecks = [];
278
+ if (e.target.checked) {
279
+ setAllOrgChecked(true);
280
+ orgChecks = preorder(rootNode);
281
+ setCheckedKeys(orgChecks);
282
+ onChange({
283
+ appKeys: allAppChecked ? ['all'] : appKeys,
284
+ checkedKeys: ['all'],
285
+ appCheckAll: allAppChecked,
286
+ orgCheckAll: true,
287
+
288
+ userKeys: allUserChecked ? ['all'] : userKeys,
289
+ userCheckAll: allUserChecked,
290
+
291
+ checkData: {
292
+ apps: appKeys,
293
+ orgs: checkedKeys,
294
+ accounts,
295
+ },
296
+ });
297
+ } else {
298
+ setAllOrgChecked(false);
299
+ let arr = orgCodes.includes('all') ? allOrg : orgCodes;
300
+ orgChecks = Array.from(new Set([...(arr || []), ...path]));
301
+
302
+ setCheckedKeys(orgChecks);
303
+ onChange({
304
+ appKeys: allAppChecked ? ['all'] : appKeys,
305
+ checkedKeys: orgChecks,
306
+ appCheckAll: allAppChecked,
307
+ orgCheckAll: false,
308
+ userKeys: allUserChecked ? ['all'] : userKeys,
309
+ userCheckAll: allUserChecked,
310
+ checkData: {
311
+ apps: appKeys,
312
+ orgs: orgChecks,
313
+ accounts,
314
+ },
315
+ });
316
+ }
317
+ };
318
+
319
+ // app全局授权
320
+ const checkedAllApp = (e) => {
321
+ let appChecks = [];
322
+ if (e.target.checked) {
323
+ setAllAppChecked(true);
324
+ appChecks = appList.map((item) => item.value);
325
+ setAppKeys(appChecks);
326
+ onChange({
327
+ appKeys: ['all'],
328
+ checkedKeys: allOrgChecked ? ['all'] : checkedKeys,
329
+ appCheckAll: true,
330
+ orgCheckAll: allOrgChecked,
331
+ userKeys: allUserChecked ? ['all'] : userKeys,
332
+ userCheckAll: allUserChecked,
333
+ checkData: {
334
+ apps: appChecks,
335
+ orgs: checkedKeys,
336
+ accounts,
337
+ },
338
+ });
339
+ } else {
340
+ setAllAppChecked(false);
341
+ let arr = appCodes.includes('all') ? allApp : appCodes;
342
+ appChecks = Array.from(new Set([...(arr || []), appCode]));
343
+
344
+ setAppKeys(appChecks);
345
+ onChange({
346
+ appKeys: appChecks,
347
+ checkedKeys: allOrgChecked ? ['all'] : checkedKeys,
348
+ appCheckAll: false,
349
+ orgCheckAll: allOrgChecked,
350
+ userKeys: allUserChecked ? ['all'] : userKeys,
351
+ userCheckAll: allUserChecked,
352
+ checkData: {
353
+ apps: appChecks,
354
+ orgs: checkedKeys,
355
+ accounts,
356
+ },
357
+ });
358
+ }
359
+ };
360
+
361
+ // account全局授权
362
+ const checkedAllUser = (e) => {
363
+ let userChecks = [];
364
+ if (e.target.checked) {
365
+ setAllUserChecked(true);
366
+ userChecks = userList.map((item) => item.account);
367
+ setUserKeys(userChecks);
368
+
369
+ onChange({
370
+ appKeys: allAppChecked ? ['all'] : appKeys,
371
+ appCheckAll: allAppChecked,
372
+
373
+ checkedKeys: allOrgChecked ? ['all'] : checkedKeys,
374
+ orgCheckAll: allOrgChecked,
375
+
376
+ userKeys: ['all'],
377
+ userCheckAll: true,
378
+ checkData: {
379
+ apps: appKeys,
380
+ orgs: checkedKeys,
381
+ accounts: userChecks,
382
+ },
383
+ });
384
+ } else {
385
+ setAllUserChecked(false);
386
+ const arr = accounts.includes('all') ? allUser : accounts;
387
+ userChecks = Array.from(new Set([...(arr || []), account]));
388
+
389
+ setUserKeys(userChecks);
390
+ onChange({
391
+ appKeys: allAppChecked ? ['all'] : appKeys,
392
+ appCheckAll: allAppChecked,
393
+
394
+ checkedKeys: allOrgChecked ? ['all'] : checkedKeys,
395
+ orgCheckAll: allOrgChecked,
396
+
397
+ userKeys: userChecks,
398
+ userCheckAll: false,
399
+
400
+ checkData: {
401
+ apps: appKeys,
402
+ orgs: checkedKeys,
403
+ accounts: userChecks,
404
+ },
405
+ });
406
+ }
407
+ };
408
+ const debouncedOrgSearch = useCallback(
409
+ debounce((nextValue) => {
410
+ setFilterOrg(nextValue);
411
+ }, 200),
412
+ [],
413
+ );
414
+ const debouncedUserSearch = useCallback(
415
+ debounce((nextValue) => {
416
+ setFilterUser(nextValue);
417
+ }, 200),
418
+ [],
419
+ );
420
+ const debouncedAppSearch = useCallback(
421
+ debounce((nextValue) => {
422
+ setFilterApp(nextValue);
423
+ }, 200),
424
+ [],
425
+ );
426
+ // 拼接机构路径显示名
427
+ const getOrgPathDisplayName = (path = []) => {
428
+ let displayName = '';
429
+ if (path.length > 0) {
430
+ displayName = path.map((item) => orgMapRef.current[item].name).join(' / ');
431
+ }
432
+
433
+ return displayName;
434
+ };
435
+ // 移除单个机构
436
+ const onRemoveSingleOrg = (node) => {
437
+ let del_arr = preorder(node);
438
+ let checked = checkedKeys.filter((item) => !del_arr.includes(item));
439
+ setCheckedKeys(checked);
440
+ setAllOrgChecked(false);
441
+
442
+ onChange({
443
+ appKeys: allAppChecked ? ['all'] : appKeys,
444
+ checkedKeys: checked,
445
+ appCheckAll: allAppChecked,
446
+ orgCheckAll: false,
447
+ userKeys: allUserChecked ? ['all'] : userKeys,
448
+ userCheckAll: allUserChecked,
449
+ checkData: {
450
+ apps: appKeys,
451
+ orgs: checked,
452
+ accounts: userKeys,
453
+ },
454
+ });
455
+ };
456
+ // 移除全部机构
457
+ const onRemoveAllOrg = () => {
458
+ let checked = [rootNode.key];
459
+ setCheckedKeys(checked);
460
+ setAllOrgChecked(false);
461
+ onChange({
462
+ appKeys: allAppChecked ? ['all'] : appKeys,
463
+ checkedKeys: checked,
464
+ appCheckAll: allAppChecked,
465
+ orgCheckAll: false,
466
+ userKeys: allUserChecked ? ['all'] : userKeys,
467
+ userCheckAll: allUserChecked,
468
+ checkData: {
469
+ apps: appKeys,
470
+ orgs: checked,
471
+ accounts: userKeys,
472
+ },
473
+ });
474
+ };
475
+ // 移除单个应用
476
+ const onRemoveSingleApp = (value) => {
477
+ let newAppKeys = cloneDeep(appKeys);
478
+ newAppKeys.map((item, index) => {
479
+ if (value === item) {
480
+ newAppKeys.splice(index, 1);
481
+ }
482
+ });
483
+ setAppKeys(newAppKeys);
484
+ setAllAppChecked(false);
485
+ onChange({
486
+ appKeys: newAppKeys,
487
+ checkedKeys: allOrgChecked ? ['all'] : checkedKeys,
488
+ appCheckAll: false,
489
+ orgCheckAll: allOrgChecked,
490
+ userKeys: allUserChecked ? ['all'] : userKeys,
491
+ userCheckAll: allUserChecked,
492
+ checkData: {
493
+ apps: newAppKeys,
494
+ orgs: checkedKeys,
495
+ accounts: userKeys,
496
+ },
497
+ });
498
+ };
499
+ // 移除全部应用
500
+ const onRemoveAllApp = () => {
501
+ let newAppKeys = [appCode];
502
+ setAppKeys(newAppKeys);
503
+ setAllAppChecked(false);
504
+ onChange({
505
+ appKeys: newAppKeys,
506
+ checkedKeys: allOrgChecked ? ['all'] : checkedKeys,
507
+ appCheckAll: false,
508
+ orgCheckAll: allOrgChecked,
509
+ userKeys: allUserChecked ? ['all'] : userKeys,
510
+ userCheckAll: allUserChecked,
511
+ checkData: {
512
+ apps: newAppKeys,
513
+ orgs: checkedKeys,
514
+ accounts: userKeys,
515
+ },
516
+ });
517
+ };
518
+ // 移除全部用户
519
+ let onRemoveAllUser = () => {
520
+ let newUserKeys = [account];
521
+ setUserKeys(newUserKeys);
522
+ setAllUserChecked(false);
523
+ onChange({
524
+ appKeys: allAppChecked ? ['all'] : appKeys,
525
+ checkedKeys: allOrgChecked ? ['all'] : checkedKeys,
526
+ userKeys: newUserKeys,
527
+ appCheckAll: allAppChecked,
528
+ orgCheckAll: allOrgChecked,
529
+ userCheckAll: false,
530
+ checkData: {
531
+ apps: appKeys,
532
+ orgs: checkedKeys,
533
+ accounts: newUserKeys,
534
+ },
535
+ });
536
+ };
537
+ // 移除单个用户
538
+ let onRemoveSingleUser = (value) => {
539
+ let newUserKeys = cloneDeep(userKeys);
540
+ newUserKeys.map((item, index) => {
541
+ if (value === item) {
542
+ newUserKeys.splice(index, 1);
543
+ }
544
+ });
545
+ setUserKeys(newUserKeys);
546
+ setAllUserChecked(false);
547
+ onChange({
548
+ appKeys: allAppChecked ? ['all'] : appKeys,
549
+ checkedKeys: allOrgChecked ? ['all'] : checkedKeys,
550
+ userKeys: newUserKeys,
551
+ appCheckAll: allAppChecked,
552
+ orgCheckAll: allOrgChecked,
553
+ userCheckAll: false,
554
+ checkData: {
555
+ apps: appKeys,
556
+ orgs: checkedKeys,
557
+ accounts: newUserKeys,
558
+ },
559
+ });
560
+ };
561
+
562
+ // 已选择的机构列表
563
+ let areadySelectOrg = useMemo(() => {
564
+ return checkedKeys.filter((i) => allOrg.includes(i)) || [];
565
+ }, [checkedKeys, allOrg]);
566
+ // 已选择的渠道列表
567
+ let areadySelectApp = useMemo(() => {
568
+ return appKeys.filter((i) => allApp.includes(i)) || [];
569
+ }, [appKeys, allApp]);
570
+ // 已选择的用户列表
571
+ let areadySelectUser = useMemo(() => {
572
+ return userKeys.filter((i) => allUser.includes(i)) || [];
573
+ }, [userKeys, allUser]);
574
+
575
+ // 渲染App列表
576
+ let appListDomRender = useMemo(() => {
577
+ return appList
578
+ .filter((i) => {
579
+ const { label, value } = i;
580
+ if (filterApp) {
581
+ return (
582
+ label?.toLocaleLowerCase().includes(filterApp?.toLocaleLowerCase()) ||
583
+ value?.toLocaleLowerCase().includes(filterApp?.toLocaleLowerCase())
584
+ );
585
+ }
586
+
587
+ return i;
588
+ })
589
+ .map((item, index) => {
590
+ const isCheck = appKeys?.includes(item.value);
591
+ const isOwnAppCode = appCode === item.value;
592
+ return (
593
+ <Checkbox
594
+ checked={isCheck}
595
+ disabled={disabled || isOwnAppCode || allAppChecked}
596
+ onChange={assignApp}
597
+ value={item.value}
598
+ key={index}
599
+ >
600
+ <span style={{ display: 'inline-block' }}>
601
+ <Ellipsis title={item.label} />
602
+ </span>
603
+ </Checkbox>
604
+ );
605
+ });
606
+ }, [appList, appKeys, filterApp]);
607
+
608
+ // 渲染User列表
609
+ let userListDomRender = useMemo(() => {
610
+ return (
611
+ userList
612
+ ?.filter((item) => {
613
+ if (filterUser) {
614
+ return (
615
+ item?.account?.toLocaleLowerCase().includes(filterUser?.toLocaleLowerCase()) ||
616
+ item?.userName?.toLocaleLowerCase().includes(filterUser?.toLocaleLowerCase())
617
+ );
618
+ }
619
+ return item;
620
+ })
621
+ .map((item, index) => {
622
+ const isCheck = userKeys?.includes(item.account);
623
+ const isOwnAccount = account === item.account;
624
+ return (
625
+ <Checkbox
626
+ key={item + index}
627
+ checked={isCheck}
628
+ disabled={disabled || isOwnAccount || allUserChecked}
629
+ onChange={assignUser}
630
+ value={item.account}
631
+ >
632
+ <span style={{ display: 'inline-block' }}>
633
+ <Ellipsis widthLimit={240} title={item.userName} />
634
+ </span>
635
+ </Checkbox>
636
+ );
637
+ }) || <Empty />
638
+ );
639
+ }, [userList, userKeys, filterUser]);
640
+
641
+ return (
642
+ <>
643
+ <Segmented
644
+ className="menu-title"
645
+ value={curValue}
646
+ options={titleOptions}
647
+ onChange={(index) => {
648
+ setCurValue(index);
649
+ setCurIndex(titleOptions.findIndex((i) => i === index));
650
+ }}
651
+ />
652
+ <div className="assign-box-container">
653
+ <div className={`slider panel-${curIndex}`} style={{ width: !!showUser ? '300%' : '200%' }}>
654
+ <div className="org-panel panel">
655
+ <div className="menu-header">
656
+ {/* 授权可用机构列表 */}
657
+ <span className="title">{orgTitle || getText('authorizesOrgList', props?.lang)}</span>
658
+ <div className="menu-all-checked">
659
+ <Checkbox onChange={checkAllOrg} checked={allOrgChecked} disabled={disabled}>
660
+ {/* 全部机构可用 */}
661
+ {orgCheckboxTitle || getText('allOrgAvailable', props?.lang)}
662
+ </Checkbox>
663
+ </div>
664
+ </div>
665
+ <div className="panel-menu-body">
666
+ <div className="panel-left">
667
+ <Input
668
+ size="small"
669
+ allowClear
670
+ placeholder={getText('search', props?.lang)}
671
+ onChange={(e) => {
672
+ debouncedOrgSearch(e.target.value);
673
+ }}
674
+ suffix={<Icon type="zoom" />}
675
+ style={{ marginBottom: 16, width: 'calc(100% - 16px)' }}
676
+ />
677
+ <Tree
678
+ blockNode
679
+ className="tree-list"
680
+ checkable
681
+ checkStrictly={true}
682
+ checkedKeys={checkedKeys}
683
+ defaultExpandAll={true}
684
+ onCheck={onCheck}
685
+ >
686
+ {loopTreeNodes(treeData, 0)}
687
+ </Tree>
688
+ </div>
689
+ <div className="panel-right">
690
+ <div className="select-menu-header">
691
+ {getText('hasBeenSelected', props?.lang)}:{' '}
692
+ {getText('numOfOrg', props?.lang, areadySelectOrg.length || 0)}
693
+ <a onClick={() => onRemoveAllOrg()}>{getText('clear', props?.lang)}</a>
694
+ </div>
695
+ <ul className="select-menu-list">
696
+ {checkedKeys.map((item, index) => {
697
+ let node = orgMapRef.current[item] || {};
698
+ let { path, name } = node;
699
+
700
+ let pathDisplayName = getOrgPathDisplayName(path);
701
+ let disabled = rootNode.key === item;
702
+ return (
703
+ <li key={item.value + index} className="select-menu-list-item">
704
+ <span className="org-name">
705
+ <Ellipsis title={name} />
706
+ </span>
707
+ <span className="path-name">
708
+ <Ellipsis title={pathDisplayName} />
709
+ </span>
710
+ {!disabled && (
711
+ <Icon
712
+ type="close"
713
+ className="close-icon"
714
+ onClick={() => onRemoveSingleOrg(node)}
715
+ />
716
+ )}
717
+ </li>
718
+ );
719
+ }) || <Empty />}
720
+ </ul>
721
+ </div>
722
+ </div>
723
+ </div>
724
+ <div className="app-panel panel">
725
+ <div className="menu-header">
726
+ {/* 授权可用渠道列表 */}
727
+ <span className="title">{appTitle || getText('authorizesAppList', props?.lang)}</span>
728
+ <div className="menu-all-checked">
729
+ <Checkbox onChange={checkedAllApp} checked={allAppChecked} disabled={disabled}>
730
+ {/* 全部渠道可用 */}
731
+ {appCheckboxTitle || getText('allAppAvailable', props?.lang)}
732
+ </Checkbox>
733
+ </div>
734
+ </div>
735
+ <div className="panel-menu-body">
736
+ <div className="panel-left">
737
+ <Input
738
+ onChange={(e) => {
739
+ debouncedAppSearch(e.target.value);
740
+ }}
741
+ size="small"
742
+ allowClear
743
+ placeholder={getText('search', props?.lang)}
744
+ suffix={<Icon type="zoom" />}
745
+ style={{ marginBottom: 16, width: 'calc(100% - 16px)' }}
746
+ />
747
+ {appListDomRender}
748
+ </div>
749
+ <div className="panel-right">
750
+ <div className="select-menu-header">
751
+ <span>
752
+ {getText('hasBeenSelected', props?.lang)}:{' '}
753
+ {getText('numOfApp', props?.lang, areadySelectApp.length || 0)}
754
+ </span>
755
+ <a onClick={() => onRemoveAllApp()}>{getText('clear', props?.lang)}</a>
756
+ </div>
757
+ <ul className="select-menu-list">
758
+ {appKeys.map((item, index) => {
759
+ let node = appMapRef.current[item] || {};
760
+ let { value, label } = node;
761
+
762
+ const isOwnAppCode = appCode === value;
763
+ if (!value && !label) return null; // 不显示多余数据
764
+ return (
765
+ <li key={value + index} className="select-menu-list-item">
766
+ <span className="app-name">
767
+ <Ellipsis title={label} />
768
+ </span>
769
+ {!isOwnAppCode && (
770
+ <Icon
771
+ type="close"
772
+ className="close-icon"
773
+ onClick={() => onRemoveSingleApp(value)}
774
+ />
775
+ )}
776
+ </li>
777
+ );
778
+ }) || <Empty />}
779
+ </ul>
780
+ </div>
781
+ </div>
782
+ </div>
783
+ {!!showUser && (
784
+ <div className="user-panel panel">
785
+ <div className="menu-header">
786
+ {/* 授权可用用户列表 */}
787
+ <span className="title">
788
+ {userTitle || getText('authorizesUserList', props?.lang)}
789
+ </span>
790
+ <div className="menu-all-checked">
791
+ <Checkbox onChange={checkedAllUser} checked={allUserChecked} disabled={disabled}>
792
+ {/* 全部用户可用 */}
793
+ {userCheckboxTitle || getText('allUserAvailable', props?.lang)}
794
+ </Checkbox>
795
+ </div>
796
+ </div>
797
+ <div className="panel-menu-body">
798
+ <div className="panel-left">
799
+ <Input
800
+ size="small"
801
+ allowClear
802
+ placeholder={getText('search', props?.lang)}
803
+ onChange={(e) => {
804
+ debouncedUserSearch(e.target.value);
805
+ }}
806
+ suffix={<Icon type="zoom" />}
807
+ style={{ marginBottom: 16, width: 'calc(100% - 16px)' }}
808
+ />
809
+
810
+ {userListDomRender}
811
+ </div>
812
+ <div className="panel-right">
813
+ <div className="select-menu-header">
814
+ {getText('hasBeenSelected', props?.lang)}:{' '}
815
+ {getText('numOfUser', props?.lang, areadySelectUser.length || 0)}
816
+ <a onClick={() => onRemoveAllUser()}>{getText('clear', props?.lang)}</a>
817
+ </div>
818
+ <ul className="select-menu-list">
819
+ {userKeys.map((item, index) => {
820
+ let node = userMapRef.current[item] || {};
821
+ let { userName } = node;
822
+
823
+ const isOwnAppCode = accounts === node.account;
824
+ if (!userName && !node.account) return null; // 不显示多余数据
825
+ return (
826
+ <li key={userName + index} className="select-menu-list-item">
827
+ <span className="app-name">
828
+ <Ellipsis title={userName} />
829
+ </span>
830
+ {!isOwnAppCode && (
831
+ <Icon
832
+ type="close"
833
+ className="close-icon"
834
+ onClick={() => onRemoveSingleUser(node.account)}
835
+ />
836
+ )}
837
+ </li>
838
+ );
839
+ }) || <Empty />}
840
+ </ul>
841
+ </div>
842
+ </div>
843
+ </div>
844
+ )}
845
+ </div>
846
+ </div>
847
+ </>
848
+ );
849
+ };
850
+
851
+ export default AssignModal;