@bit-sun/business-component 4.0.11 → 4.0.12-alpha.3

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 (44) hide show
  1. package/.umirc.ts +10 -6
  2. package/dist/components/Business/BsSulaQueryTable/SearchItemSetting.d.ts +2 -4
  3. package/dist/components/Business/BsSulaQueryTable/utils.d.ts +1 -0
  4. package/dist/components/Business/SearchSelect/BusinessUtils.d.ts +2 -1
  5. package/dist/components/Functional/SearchSelect/utils.d.ts +11 -0
  6. package/dist/index.esm.js +1910 -980
  7. package/dist/index.js +1909 -979
  8. package/package.json +2 -2
  9. package/src/assets/copyImg.svg +16 -0
  10. package/src/assets/zhankaitiaojian-icon.svg +18 -0
  11. package/src/components/Business/BsLayouts/index.tsx +17 -0
  12. package/src/components/Business/BsSulaQueryTable/SearchItemSetting.tsx +45 -17
  13. package/src/components/Business/BsSulaQueryTable/index.less +21 -38
  14. package/src/components/Business/BsSulaQueryTable/index.tsx +26 -16
  15. package/src/components/Business/BsSulaQueryTable/setting.tsx +5 -5
  16. package/src/components/Business/BsSulaQueryTable/utils.tsx +36 -15
  17. package/src/components/Business/DetailPageWrapper/index.less +11 -3
  18. package/src/components/Business/DetailPageWrapper/index.tsx +27 -2
  19. package/src/components/Business/HomePageWrapper/index.less +9 -0
  20. package/src/components/Business/HomePageWrapper/index.tsx +1 -1
  21. package/src/components/Business/SearchSelect/BusinessUtils.tsx +834 -179
  22. package/src/components/Business/SearchSelect/index.md +181 -0
  23. package/src/components/Business/SearchSelect/index.tsx +2 -1
  24. package/src/components/Business/SearchSelect/utils.ts +4 -1
  25. package/src/components/Business/StateFlow/index.less +140 -124
  26. package/src/components/Business/StateFlow/index.tsx +3 -3
  27. package/src/components/Business/columnSettingTable/columnSetting.tsx +6 -6
  28. package/src/components/Business/columnSettingTable/index.less +31 -69
  29. package/src/components/Business/columnSettingTable/index.tsx +36 -6
  30. package/src/components/Business/columnSettingTable/sulaSettingTable.tsx +36 -7
  31. package/src/components/Common/ParagraphCopier/index.tsx +2 -6
  32. package/src/components/Functional/QueryMutipleInput/index.less +51 -19
  33. package/src/components/Functional/QueryMutipleInput/index.tsx +28 -22
  34. package/src/components/Functional/SearchSelect/index.less +236 -73
  35. package/src/components/Functional/SearchSelect/index.tsx +400 -263
  36. package/src/components/Functional/SearchSelect/utils.ts +35 -0
  37. package/src/components/Functional/TreeSearchSelect/index.tsx +1 -1
  38. package/src/components/Solution/RuleComponent/index.js +4 -3
  39. package/src/components/Solution/RuleSetter/function.ts +2 -1
  40. package/src/plugin/TableColumnSetting/index.less +38 -70
  41. package/src/plugin/TableColumnSetting/index.tsx +5 -5
  42. package/src/styles/bsDefault.less +132 -136
  43. package/src/utils/TableUtils.tsx +1 -1
  44. package/src/utils/utils.ts +5 -2
@@ -1,15 +1,16 @@
1
1
  // @ts-nocheck
2
2
  import React, { useState, useEffect, forwardRef, useImperativeHandle } from 'react';
3
3
  import { useDebounceFn } from 'ahooks';
4
- import { Input, Button, Modal, Select, Divider, message, Spin, Form, Table, Checkbox, TreeSelect, Tooltip, Tag } from 'antd';
4
+ import { Input, Button, Modal, Select, Divider, message, Spin, Form, Table, Checkbox, TreeSelect, Tooltip, Tag, Row, Col, Space, Tabs } from 'antd';
5
5
  import { SearchOutlined, CopyOutlined, CaretLeftOutlined } from '@ant-design/icons';
6
6
  import request from '@/utils/request';
7
7
  import { stringify } from 'querystring';
8
- import _, { escapeRegExp, isNil } from "lodash"
8
+ import _, { escapeRegExp, isNil, values } from "lodash"
9
9
  import './index.less';
10
10
  import { BusinessSearchSelect, QueryMutipleInput } from '@/index';
11
- import { handleSourceName } from './utils';
11
+ import { handleSourceName, getFormRowInfo, hasMoreQueryFields, defaultVisibleFieldsCount, getRealStr, ColSpan, getTableHeigth } from './utils';
12
12
  import { judgeIsRequestError } from '@/utils/requestUtils';
13
+ import zhankaitiaojian from '../../../assets/zhankaitiaojian-icon.svg';
13
14
 
14
15
  const { Option } = Select;
15
16
 
@@ -27,6 +28,7 @@ const SearchSelect = forwardRef((props: any, ref: any) => {
27
28
  needModalTable = true,
28
29
  getPopupContainer = undefined,
29
30
  fieldComponent,
31
+ onSaveCallback,
30
32
  selectBusinessType,
31
33
  } = props;
32
34
  const {
@@ -40,33 +42,51 @@ const SearchSelect = forwardRef((props: any, ref: any) => {
40
42
  mappingTextShowKeyField,
41
43
  mappingValueField = 'code',
42
44
  mappingTextShowTextField,
43
- init = true,// 是否初始请求
45
+ init = false,// 是否初始请求,默认初始不请求,查询需要限制录入4位数以上支持模糊查询
44
46
  extralHeaders = {},// 额外请求头参数
45
47
  specialBracket = false,// 是否使用特殊括弧显示选项 【value】text
46
48
  noNeedSplit = false,// label显示不需要任何特殊化
49
+ noOperate, // 级联禁用按钮设置字段
50
+ viewShowValueStr, // 详情展示值,不传展示组件处理的默认值
51
+ searchStartLength, // 默认不校验长度去搜索,如果配置了,则按照配置项长度进行处理搜索
47
52
  } = requestConfig || {};
48
53
  const resultSourceKey = handleSourceName(sourceName || requestConfig?.sourceName || ctx?.name || 'supplierCode')
49
54
 
50
55
  const selectMode = selectProps?.mode // 设定当前选择器 为单选或者多选模式 无设定为单选模式(默认)
51
56
  const initVal = value || (selectMode ? [] : null);
52
57
  const pageSize = 100 // 下拉框默认分页 条数
53
- const tableInitPageSize = 10 // 弹框默认分页 条数
58
+ const tableInitPageSize = 20 // 弹框默认分页 条数
54
59
  const currentPage = 1
55
60
  const selectParamsKey = requestConfig?.filter || 'qp-codeAndName-like'
56
61
  const selectParamsInitKey = requestConfig?.filterInit || selectParamsKey
57
62
  const currentSelectProps = {
58
63
  ...selectProps,
59
64
  // 以下属性不可更改----设计配置项
60
- showSearch: false,
65
+ showArrow: true,
66
+ showSearch: true,
61
67
  filterOption: false,
62
68
  allowClear: true,
63
69
  listHeight: 160,
64
70
  optionLabelProp: "label",
65
- autoClearSearchValue: false
71
+ autoClearSearchValue: false,
72
+ placement: 'bottomLeft'
66
73
  }
67
- const tableInitPagination = { showQuickJumper: true, total: 0, current: 1, pageSize: tableInitPageSize }
74
+ const initPagination = { showQuickJumper: true, showSizeChanger: false, showTotal: (total: any) => `共 ${total} 条`, pageSize: tableInitPageSize }
75
+ const tableInitPagination = { ...initPagination, total: 0, current: 1 }
76
+ const disabled = noOperate || selectProps?.disabled || props?.disabled;
77
+ const isHaveDependency = fixedparameter && fieldValToParam && ctx;
78
+ const isHaveDValue = () => {
79
+ let formValueList = [];
80
+ fieldValToParam.forEach((item: any, index: any) => {
81
+ const fixedParamVal = ctx.form.getFieldValue(fieldValToParam[index]);
82
+ formValueList.push(fixedParamVal);
83
+ });
84
+ return formValueList.filter((item: any) => item).length > 0
85
+ }
86
+ const sDisabled = disabled || (isHaveDependency && !!!isHaveDValue());
68
87
 
69
88
  const [items, setItems] = useState([]);
89
+ const [selectOpen, setSelectOpen] = useState(false);
70
90
  const [scrollPage, setScrollPage] = useState(1);
71
91
  const [itemsTotal, setItemsTotal] = useState(0);
72
92
  const [fetching, setFetching] = useState(false);
@@ -101,6 +121,7 @@ const SearchSelect = forwardRef((props: any, ref: any) => {
101
121
  );
102
122
 
103
123
  const [form] = Form.useForm();
124
+ const [collapsed, setCollapsed] = useState(true);
104
125
  const [caretLeftFlag, setCaretLeftFlag] = useState(true);
105
126
  const [tableData, setTableData] = useState([]);
106
127
  const [tablePagination, setTablePagination] = useState(tableInitPagination)
@@ -110,33 +131,45 @@ const SearchSelect = forwardRef((props: any, ref: any) => {
110
131
  const [indeterminate, setIndeterminate] = useState(false)
111
132
  const [tableFormParams, setTableFormParams] = useState({});
112
133
  const [tooltipVisible, setTooltipVisible] = useState(false);
134
+ const [tableShowColumns, setTabletShowColumns] = useState(modalTableProps?.tableColumns?.filter(s => typeof s.defaultSort == 'number')?.sort((a,b)=> a.defaultSort-b.defaultSort)||[]);
135
+ const [confirmLoading, setConfirmLoading] = useState(false);
136
+ const [modalSearched, setModalSearched]=useState(false);
137
+
138
+ const setSelectDataSource = (list,total: number) => {
139
+ setItems(list);
140
+ setItemsTotal(total);
141
+ }
142
+ const clearSelectDataSource = () => {
143
+ setSelectDataSource([],0)
144
+ }
113
145
 
114
146
  useImperativeHandle(ref, () => ({
115
147
  refreshDataSource: (reset: boolean = false) => {
116
148
  if (reset) {
117
149
  if (init) {
150
+ // 有关联,依赖项清空,此form项数据源也应清空, 也不可点击搜索
151
+ if(isHaveDependency){
152
+ clearSelectDataSource();
153
+ return;
154
+ }
118
155
  run('init');
119
156
  } else {
120
- setItems([]);
121
- setItemsTotal(0);
157
+ clearSelectDataSource();
122
158
  }
123
159
  } else {
124
160
  run();
125
161
  }
126
162
  },
127
- clearDataSource: () => {
128
- setItems([]);
129
- setItemsTotal(0);
130
- },
163
+ clearSelectDataSource:clearSelectDataSource,
131
164
  getTableFormRef: () => form,
132
165
  // 解决下拉框数据源的问题
133
166
  getSelectDataSource: () => items,
134
- setSelectDataSource: (list: any, listTotal: number) => {
135
- setItems(list);
136
- setItemsTotal(listTotal);
137
- },
167
+ setSelectDataSource,
138
168
  refreshSelectDataSource: () => {
139
169
  refreshItems()
170
+ },
171
+ handleModalVisible: (flag) => {
172
+ if (flag) { showModal(); } else { handleCancel(); }
140
173
  }
141
174
  }))
142
175
 
@@ -148,7 +181,7 @@ const SearchSelect = forwardRef((props: any, ref: any) => {
148
181
 
149
182
  // 处理dependence参数
150
183
  const fixedParam = {};
151
- if (fixedparameter && fieldValToParam && ctx) {
184
+ if (isHaveDependency) {
152
185
  fixedparameter.forEach((item: any, index: any) => {
153
186
  const fixedParamVal = ctx.form.getFieldValue(fieldValToParam[index]);
154
187
  if(fixedParamVal) {
@@ -314,7 +347,7 @@ const SearchSelect = forwardRef((props: any, ref: any) => {
314
347
  const keys = res.list ? 'list' : 'items';
315
348
  source = res
316
349
  ? res[keys]
317
- ? res[keys].map((item: any) => {
350
+ ? res[keys].map((item: any, index: number) => {
318
351
  let textShowText = item[mappingTextField]
319
352
  if (mappingTextShowTextField) {
320
353
  textShowText = []
@@ -326,6 +359,7 @@ const SearchSelect = forwardRef((props: any, ref: any) => {
326
359
  textShowText = item[mappingTextShowTextField]
327
360
  }
328
361
  }
362
+ if(!item?.children?.length) {delete item?.children};
329
363
  return {
330
364
  ...item,
331
365
  text: specialBracket
@@ -334,10 +368,11 @@ const SearchSelect = forwardRef((props: any, ref: any) => {
334
368
  textShowText,
335
369
  textShowKey: item[mappingTextShowKeyField || mappingValueField],
336
370
  value: item[mappingValueField],
371
+ keyIndex: index + 1,
337
372
  };
338
373
  })
339
374
  : Array.isArray(res) &&
340
- res?.map((item: Record<string, any>) => {
375
+ res?.map((item: Record<string, any>, index: number) => {
341
376
  let textShowText = item[mappingTextField]
342
377
  if (mappingTextShowTextField) {
343
378
  textShowText = []
@@ -349,6 +384,7 @@ const SearchSelect = forwardRef((props: any, ref: any) => {
349
384
  textShowText = item[mappingTextShowTextField]
350
385
  }
351
386
  }
387
+ if(!item?.children?.length) {delete item?.children};
352
388
  return {
353
389
  ...item,
354
390
  text: specialBracket
@@ -357,18 +393,19 @@ const SearchSelect = forwardRef((props: any, ref: any) => {
357
393
  textShowText,
358
394
  textShowKey: item[mappingTextShowKeyField || mappingValueField],
359
395
  value: item[mappingValueField],
396
+ keyIndex: index + 1,
360
397
  };
361
398
  })
362
399
  : [];
363
400
  }
364
- source = Array.isArray(source) ? source : []
401
+ // 数据源 不可以有重复key
402
+ source = Array.isArray(source) ? _.uniqBy(source, 'value') : [];
365
403
  if(callback) {
366
404
  callback(source)
367
405
  } else {
368
406
  if (type === 1) {
369
407
  ctx?.form?.setFieldSource(resultSourceKey, source)
370
- setItems(source)
371
- setItemsTotal(Number(res?.total || res?.totalCount || source.length))
408
+ setSelectDataSource(source,(Number(res?.total || res?.totalCount || source.length)))
372
409
  } else {
373
410
  setTableData(source)
374
411
  setTablePagination({ ...tablePagination, total: Number(res?.total || res?.totalCount || source.length), pageSize: Number(res?.size || res?.pageSize || (params?.pageSize || pageSize)), current: Number(res?.page || res?.currentPage || (params?.currentPage || currentPage)) })
@@ -418,6 +455,10 @@ const SearchSelect = forwardRef((props: any, ref: any) => {
418
455
  if (init) {
419
456
  run('init')
420
457
  }
458
+ // 编辑/详情页面回显
459
+ if(!init && !!value && ['edit','view'].includes(ctx?.mode)) {
460
+ run('init')
461
+ }
421
462
  }, [])
422
463
 
423
464
  useEffect(() => {
@@ -432,14 +473,43 @@ const SearchSelect = forwardRef((props: any, ref: any) => {
432
473
 
433
474
  useEffect(() => {
434
475
  if (init) {
435
- setItems([]);
436
- setItemsTotal(0);
476
+ clearSelectDataSource();
437
477
  run('init')
438
478
  }
439
479
  },[selectBusinessType])
440
480
 
481
+ // 处理键盘事件
482
+ const handleKeyPress = (event) => {
483
+ if ((event.metaKey || event.ctrlKey) && (event.key === 'U' || event.keyCode == 85)) {
484
+ // ctrl + U 键 重置
485
+ onResetTable()
486
+ } else if (event.key === 'Enter' || event.keyCode == 13) {
487
+ // Enter 键 查询
488
+ onSearchTable()
489
+ }
490
+ };
491
+ useEffect(() => {
492
+ const removeListener = () => {
493
+ // 组件卸载时移除事件监听
494
+ document.removeEventListener('keydown', handleKeyPress);
495
+ }
496
+ if(isModalVisible) {
497
+ document.addEventListener('keydown', handleKeyPress);
498
+ } else {
499
+ removeListener()
500
+ }
501
+ return () => {
502
+ removeListener()
503
+ };
504
+ },[isModalVisible])
505
+
441
506
  const showModal = () => {
442
- getData({ pageSize: tableInitPageSize, currentPage: 1 }, 3)
507
+ if(sDisabled) return;
508
+
509
+ setSelectOpen(false)
510
+ setSearchValue('');
511
+ setModalSearched(false);
512
+
443
513
  setIsModalVisible(true);
444
514
  // 回显
445
515
  if (value) {
@@ -461,21 +531,54 @@ const SearchSelect = forwardRef((props: any, ref: any) => {
461
531
  const handleSelectOver = (selectedValue: any) => {
462
532
  if (selectedValue?.length) {
463
533
  // 解决选择最后1页的sku,返回后,不显示名称问题
464
- const source = _.uniqBy(items.concat(selectedValue), 'value')
465
- ctx?.form?.setFieldSource(resultSourceKey, source)
466
- setItems(source)
534
+ updateSelectDataSource(selectedValue)
467
535
  formaData(selectedValue, source);
468
536
  } else {
469
537
  const formatResult = selectMode ? [] : null
470
538
  onChange(formatResult, selectedValue)
471
539
  }
472
540
  }
541
+ const handleOk = (sValue?:any) => {
542
+ const pValue = sValue || popvalue
543
+ // 按钮保存可传入
544
+ if(onSaveCallback) {
545
+ setConfirmLoading(true)
546
+ onSaveCallback(pValue).then(res => {
547
+ if(true) {
548
+ // 成功信息可以在调用处处理 即resolve({messageSuccessBackInfo: { needThrowSuccess: false } })、resolve({messageSuccessBackInfo: { needThrowSuccess: true, successMessage: '已保存' } })
549
+ let initSuccessMessage = '保存成功'
550
+ const rmsbi = res?.messageSuccessBackInfo || {};
551
+ if(rmsbi && Object.keys(rmsbi)?.length){
552
+ rmsbi?.needThrowSuccess ? message.success(rmsbi?.successMessage || initSuccessMessage) : null
553
+ } else {
554
+ message.success(initSuccessMessage)
555
+ }
556
+ handleCancel();
557
+ } else {
558
+ }
559
+ setConfirmLoading(false)
560
+ }).catch(Error => {
561
+ if(typeof Error === 'object') {
562
+ !Error.needThrowError ? null : message.error(Error.message)
563
+ } else {
564
+ message.error(Error);
565
+ }
566
+ setConfirmLoading(false)
567
+ })
568
+ } else {
569
+ handleSelectOver(pValue)
570
+ handleCancel();
571
+ }
572
+ };
473
573
 
474
- const handleOk = () => {
475
- handleSelectOver(popvalue)
476
- handleCancel();
574
+ // 更新选中数据位置
575
+ const updateSelectDataSource = (selectedValues) => {
576
+ const nSource = _.uniqBy(selectedValues.concat(items), 'value')
577
+ ctx?.form?.setFieldSource(resultSourceKey, nSource)
578
+ setSelectDataSource(nSource,nSource?.length)
477
579
  };
478
580
 
581
+ // 下拉框 / 弹窗 选中数据之后 最终都会执行此函数
479
582
  const formaData = (value: any, source: any) => {
480
583
  if (labelInValue) {
481
584
  const formatResult = value.map((i: any) => ({ key: i[mappingValueField] || i.key, label: i[mappingTextField] || i.label, value: i[mappingValueField] || i.value }))
@@ -500,47 +603,35 @@ const SearchSelect = forwardRef((props: any, ref: any) => {
500
603
  const handleCancel = () => {
501
604
  clearModalTable();
502
605
  setIsModalVisible(false);
503
- if (selectMode) {
504
- run();
505
- }
506
606
  };
507
607
 
508
608
  const refreshItems = () => {
509
609
  // 查看是否存在关联值 如果有关联值 就查询 没有就不能查询
510
610
  if (fieldValToParam && ctx && fixedparamsDisabled) {
511
- let formValueList = [];
512
- fieldValToParam.forEach((item: any, index: any) => {
513
- const fixedParamVal = ctx.form.getFieldValue(fieldValToParam[index]);
514
- formValueList.push(fixedParamVal);
515
- });
516
- if (formValueList.filter((item: any) => item).length > 0) {
611
+ if (!!isHaveDValue()) {
517
612
  run();
518
613
  } else {
519
- setItems([]);
520
- setItemsTotal(0);
614
+ clearSelectDataSource();
521
615
  }
522
616
  } else {
523
617
  run();
524
618
  }
525
619
  }
526
620
 
527
- const onSearchChange = (e) => {
528
- setSearchValue(e.target.value);
529
- refreshItems();
530
- }
531
-
532
- const onSearchBlur = () => {
533
- setSearchValue('');
621
+ const onSearchChange = (v) => {
622
+ setSearchValue(v);
623
+ if(!!searchStartLength && v?.length < searchStartLength) return;
534
624
  refreshItems();
535
625
  }
536
626
 
537
627
  const onSearchTable = () => {
538
628
  const params = form.getFieldsValue();
629
+
630
+ // const isHaveParams = params && Object.keys(params).filter(item => params[item]).length > 0;
631
+ setModalSearched(true);
632
+
539
633
  setTableFormParams(params);
540
634
  getData({ ...params, pageSize: tableInitPageSize }, 2)
541
- if (selectMode) {
542
- getData(params)
543
- }
544
635
  }
545
636
 
546
637
  const onResetTable = () => {
@@ -549,49 +640,13 @@ const SearchSelect = forwardRef((props: any, ref: any) => {
549
640
  getData({ pageSize: tableInitPageSize, currentPage: 1 }, 2)
550
641
  }
551
642
 
643
+ const toggleCollapsed = () => {
644
+ setCollapsed(!collapsed);
645
+ };
646
+
552
647
  const handleTableChange = (pagination) => {
553
648
  getData({ ...tableFormParams, pageSize: pagination.pageSize, currentPage: pagination.current }, 2)
554
649
  }
555
-
556
- const onCheckAllData = (pSize) => {
557
- getData({ ...tableFormParams, pageSize: pSize, currentPage: 1 }, 2,(source) => {
558
- const currentItemsData = JSON.parse(JSON.stringify(source))
559
- setSelectedRowKeys(currentItemsData.map(i => i.value))
560
- setPopValue(currentItemsData);
561
- setSelectedRows(currentItemsData)
562
- })
563
- }
564
-
565
- const onChangeCheckAll = (e) => {
566
- // 允许用户自定义 全选操作逻辑
567
- if(modalTableProps?.onCheckAll) {
568
- modalTableProps?.onCheckAll(e,{items,itemsTotal,tablePagination,onCheckAllData,setSelectedRowKeys,setPopValue,setSelectedRows,setIndeterminate,setCheckedAll})
569
- return;
570
- }
571
-
572
- if (e.target.checked) {
573
- // 如果下拉框有所有数据就处理选中所有【items.length === itemsTotal】(最多可选100条)
574
- // 如果超过100条 就默认查出所有数据
575
- if ((items.length < itemsTotal) || (items.length === itemsTotal && itemsTotal == 0)) {
576
- const totalCount = tablePagination?.total || itemsTotal // 兼容有查询条件的情况 首次加载是没有所有数据的,默认给加载后端返回的总条数
577
- const totalPage = Math.ceil(totalCount / tablePagination?.pageSize);
578
- const allPageSize = totalPage * tablePagination?.pageSize;
579
- onCheckAllData(allPageSize)
580
- } else {
581
- const currentItemsData = JSON.parse(JSON.stringify(items))
582
- setSelectedRowKeys(currentItemsData.map(i => i.value))
583
- setPopValue(currentItemsData);
584
- setSelectedRows(currentItemsData)
585
- }
586
- } else {
587
- setSelectedRowKeys([])
588
- setPopValue([]);
589
- setSelectedRows([])
590
- }
591
- setIndeterminate(false);
592
- setCheckedAll(e.target.checked);
593
- }
594
-
595
650
  const LightHeightOption = (props) => {
596
651
  const {
597
652
  filterTxt, text,
@@ -634,12 +689,11 @@ const SearchSelect = forwardRef((props: any, ref: any) => {
634
689
  };
635
690
 
636
691
  const onChangeSelectedKeys = (selectKeys, selectRows) => {
637
- let sksResult = selectRows.map((i) => i.value);
692
+ let sksResult = selectRows?.map((i) => i.value)||[];
638
693
 
639
694
  // 单选 默认直接选中 不需要确定 配置了modalRadioNeedFooter就需要确定
640
695
  if(!selectMode && !modalTableProps?.modalRadioNeedFooter) {
641
- handleSelectOver(selectRows)
642
- handleCancel();
696
+ handleOk(selectRows)
643
697
  }
644
698
 
645
699
  setSelectedRowKeys(sksResult)
@@ -669,13 +723,23 @@ const SearchSelect = forwardRef((props: any, ref: any) => {
669
723
  },
670
724
  getCheckboxProps: selectProps?.getCheckboxProps ? selectProps?.getCheckboxProps : () => {
671
725
  return ({
672
- disabled: selectProps?.disabled || props?.disabled || (!items.length && !tableData.length),
726
+ disabled: disabled || (!items.length && !tableData.length),
673
727
  })
674
728
  },
675
729
  };
676
730
 
677
- const onDoubleClickSelect = (e, record) => {
678
- if (!selectMode && !(selectProps?.disabled || props?.disabled || (!items.length && !tableData.length))) {
731
+ const onRowClickSelect = (e, record,type) => {
732
+ if (selectMode && !(disabled || (!items.length && !tableData.length))) {
733
+ const oldSelect = selectedRows;
734
+ const newSelect = [JSON.parse(JSON.stringify(record))];
735
+ const srs = getRealStr(oldSelect,newSelect,record);
736
+ const sks = srs.map((i: any) => i.value)
737
+
738
+ onChangeSelectedKeys(sks, srs)
739
+ }
740
+ }
741
+ const onDoubleClickSelect = (e, record,type) => {
742
+ if (!selectMode && !(disabled || (!items.length && !tableData.length))) {
679
743
  const srs = [JSON.parse(JSON.stringify(record))]
680
744
  const sks = srs.map((i: any) => i.value)
681
745
  onChangeSelectedKeys(sks, srs)
@@ -693,40 +757,49 @@ const SearchSelect = forwardRef((props: any, ref: any) => {
693
757
  return false
694
758
  }
695
759
  };
696
- return list.map((i: any) => {
760
+
761
+ const { emptyArray } = getFormRowInfo(list);
762
+ const addKong = emptyArray?.map((i: any) =>({ type: 'kong'}))||[];
763
+ return list?.concat(addKong)?.map((i: any, index: number) => {
764
+ if(i?.type === 'kong') return <Col span={ColSpan} key={i}></Col>;
765
+
697
766
  if (i?.type === 'select' || i?.field?.type === 'select') {
698
767
  return (
699
- <Form.Item name={i.name} label={i.label} key={i.name}>
700
- <Select style={{ width: '100%' }} placeholder='请选择' {...i?.field?.props} disabled={setDisabled(i.name)}>
701
- {i?.initialSource?.length && i?.initialSource.map((m: any) => (
702
- <Option value={m.value} key={m.value}>{m.text}</Option>
703
- ))}
704
- </Select>
705
- </Form.Item>
768
+ <Col span={ColSpan} key={i.name}>
769
+ <Form.Item name={i.name} label={i.label} key={i.name}>
770
+ <Select style={{ width: '100%' }} placeholder='请选择' onDeselect ={v => onSearchTable()} {...i?.field?.props} disabled={setDisabled(i.name)}>
771
+ {i?.initialSource?.length && i?.initialSource.map((m: any) => (
772
+ <Option value={m.value} key={m.value}>{m.text}</Option>
773
+ ))}
774
+ </Select>
775
+ </Form.Item>
776
+ </Col>
706
777
  )
707
778
  }
708
779
 
709
780
  if (i?.type === 'treeSelect' || i?.field?.type === 'treeSelect') {
710
781
  return (
711
- <Form.Item name={i.name} label={i.label} key={i.name}>
712
- <TreeSelect style={{ width: '100%' }} placeholder='请选择' {...i?.field?.props} disabled={setDisabled(i.name)}></TreeSelect>
713
- </Form.Item>
782
+ <Col span={ColSpan} key={i.name}>
783
+ <Form.Item name={i.name} label={i.label} key={i.name}>
784
+ <TreeSelect style={{ width: '100%' }} placeholder='请选择' {...i?.field?.props} disabled={setDisabled(i.name)}></TreeSelect>
785
+ </Form.Item>
786
+ </Col>
714
787
  )
715
788
  }
716
789
 
717
790
  if (i?.type === 'businessSearchSelect' || i?.field?.type === 'businessSearchSelect') {
718
791
  return (
719
- <div>
792
+ <Col span={ColSpan} key={i.name}>
720
793
  <Form.Item name={i.name} label={i.label} key={i.name}>
721
794
  <BusinessSearchSelect {...i.field.props} disabled={setDisabled(i.name)} />
722
795
  </Form.Item>
723
- </div>
796
+ </Col>
724
797
  )
725
798
  }
726
799
 
727
800
  if (i?.type === 'multipleQueryInput' || i?.field?.type === 'multipleQueryInput') {
728
801
  return (
729
- <div>
802
+ <Col span={ColSpan} key={i.name}>
730
803
  <Form.Item name={i.name} label={i.label} key={i.name}>
731
804
  <QueryMutipleInput onValueChange={(value) => {
732
805
  form.setFieldsValue({
@@ -734,15 +807,17 @@ const SearchSelect = forwardRef((props: any, ref: any) => {
734
807
  })
735
808
  }} />
736
809
  </Form.Item>
737
- </div>
810
+ </Col>
738
811
  );
739
812
  }
740
813
 
741
814
  // 默认type是input
742
815
  return (
743
- <Form.Item name={i.name} label={i.label} key={i.name}>
744
- <Input style={{ width: '100%' }} placeholder='请输入' allowClear maxLength={100} {...i?.field?.props} disabled={setDisabled(i.name)} />
745
- </Form.Item>
816
+ <Col span={ColSpan} key={i.name}>
817
+ <Form.Item name={i.name} label={i.label} key={i.name}>
818
+ <Input style={{ width: '100%' }} placeholder='请输入' allowClear maxLength={100} {...i?.field?.props} disabled={setDisabled(i.name)} />
819
+ </Form.Item>
820
+ </Col>
746
821
  )
747
822
  })
748
823
  } else {
@@ -750,6 +825,157 @@ const SearchSelect = forwardRef((props: any, ref: any) => {
750
825
  }
751
826
  }
752
827
 
828
+ const renderFormItem = (list) => {
829
+ const viCount = modalTableProps?.visibleFieldsCount || defaultVisibleFieldsCount;
830
+ return collapsed ? formItem(list?.slice(0,viCount)) : formItem(list)
831
+ }
832
+
833
+ // const queryFieldsDom = <SearchItemTable
834
+ // ref={searchTableRef}
835
+ // setShowSearchFields={setShowSearchFields||[]}
836
+ // showSearchFields={showSearchFields||[]}
837
+ // datasource={modalTableProps?.tableSearchForm || []}
838
+ // bsTableCode={bsTableCode}
839
+ // />
840
+
841
+ const renderShowTable = (tableList, type) => {
842
+ const tableBoxHeighth = getTableHeigth(modalTableProps?.tableSearchForm);
843
+ const oSY = `calc(100vh - ${tableBoxHeighth}px - 82px)`; // 分页 24+16*2+10 「高 + margin * 2 + paddingBottom 10 」
844
+ return (
845
+ <div style={{ height: `calc(100vh - ${tableBoxHeighth}px)` }}>
846
+ <Table
847
+ bordered
848
+ size="middle"
849
+ rowSelection={rowSelection}
850
+ columns={tableShowColumns}
851
+ dataSource={tableList}
852
+ {...type=='noPage'?{
853
+ pagination: initPagination,
854
+ locale: {
855
+ emptyText: '暂无已选结果',
856
+ }
857
+ }:{
858
+ pagination: tablePagination,
859
+ onChange: handleTableChange,
860
+ loading: fetching,
861
+ locale: {
862
+ emptyText: modalSearched? '无匹配结果,请更换其他内容再试' : '请输入搜索条件',
863
+ }
864
+ }}
865
+ rowKey={mappingValueField}
866
+ scroll={{
867
+ x: modalTableProps.overScrollX || 'max-content',
868
+ y: modalTableProps.overScrollY || oSY,
869
+ }}
870
+ onRow={(record) => {
871
+ return {
872
+ onClick: event => onRowClickSelect(event, record), // 点击行
873
+ onDoubleClick: (event) =>
874
+ onDoubleClickSelect(event, record),
875
+ };
876
+ }}
877
+ />
878
+ </div>
879
+ )
880
+ }
881
+
882
+ const tabsItems1 = [
883
+ { label: `全部(${tablePagination?.total || 0})`, key: 'all', children: renderShowTable(tableData) }, // 务必填写 key
884
+ ];
885
+ const tabsItems2 = [
886
+ { label: `已选(${selectedRowKeys?.length || 0})`, key: 'selected', children: renderShowTable(selectedRows?.map((s,index)=> ({...s,keyIndex:index+1}))||[],'noPage') },
887
+ ];
888
+
889
+ const resetSelectDataSource = () => {
890
+ setSearchValue('');
891
+ // 有关联值 不需要清空下拉框数据 也不需要重新去请求了
892
+ if(isHaveDependency) return;
893
+ clearSelectDataSource();
894
+ init && run('init')
895
+ }
896
+
897
+ const onClear = () => {
898
+ // 执行父组件 onClear 事件
899
+ props?.onClear?.();
900
+ // 清空下拉框 / 弹窗 选中数据
901
+ formaData([], items);
902
+ onChangeSelectedKeys([], [])
903
+ // 重置下拉框数据源
904
+ resetSelectDataSource();
905
+ }
906
+
907
+ const onDeselect = (...arg) => {
908
+ const oldSelect = value?.map(s => ({ value: s?.value||s }))||[];
909
+ const deRecord = arg[1];
910
+ const srs = oldSelect.filter((s: any) => s.value != deRecord?.value)
911
+ onSelectClick(srs, items,false)
912
+ }
913
+ const onSelectClick = (srs, ds,nr=true) => {
914
+ formaData(srs, ds);
915
+ nr && setSelectOpen(false);
916
+ }
917
+
918
+ const onDropdownVisibleChange = (visible) => {
919
+ setSelectOpen(visible);
920
+ // 关闭下拉框 如果首次本身就不展示数据的 没有选中数据-需要清空查询数据源; 首次展示的默认展示
921
+ if (!visible && !value?.length) {
922
+ resetSelectDataSource()
923
+ }
924
+ }
925
+ const renderTable = (dataSource) => {
926
+ return (
927
+ <div className={`search_select_dropdown_table ${!selectMode?'search_select_dropdown_table1':''}`}>
928
+ <Table
929
+ virtual
930
+ bordered
931
+ {...(selectMode?{
932
+ rowSelection: {
933
+ type: 'checkbox',
934
+ columnWidth: '24px',
935
+ selectedRowKeys: labelInValue ? value?.map(s=> (s?.value||s)) : value,
936
+ preserveSelectedRowKeys: true, // 避免搜索之后 没有了选中前的数据 保证sks的正确性
937
+ onChange: (sks, srs) => {
938
+ const oldSelect = value?.map(s => ({ value: s?.value||s }))||[];
939
+ let tmpSelectedRows = oldSelect.concat(srs).filter(item => item != undefined);
940
+ let realSrs = sks.map(key => tmpSelectedRows.filter(item => item.value == key)[0]).filter(item => item != undefined)
941
+ onSelectClick(realSrs, dataSource,false)
942
+ }
943
+ },
944
+ onRow: (record, rowKey) => ({
945
+ onClick: event => {
946
+ event.stopPropagation();
947
+ event.nativeEvent.stopImmediatePropagation();
948
+
949
+ const oldSelect = value?.map(s => ({ value: s?.value||s }))||[];
950
+ const newSelect = [JSON.parse(JSON.stringify(record))];
951
+ const srs = getRealStr(oldSelect,newSelect,record);
952
+ onSelectClick(srs,dataSource,false)
953
+ }, // 点击行
954
+ })
955
+ }:{
956
+ rowSelection: {
957
+ type: 'radio',
958
+ columnWidth: 0,
959
+ selectedRowKeys: labelInValue ? value?.value&&[value?.value]||[] : value&&[value]||[],
960
+ },
961
+ onRow: (record, rowKey) => ({
962
+ onClick: event => {
963
+ const srs = [JSON.parse(JSON.stringify(record))]
964
+ onSelectClick(srs,dataSource)
965
+ }, // 点击行
966
+ })
967
+ })}
968
+ columns={selectProps?.renderTableColumns||[]}
969
+ dataSource={items}
970
+ size="middle"
971
+ pagination={false}
972
+ rowKey={mappingValueField}
973
+ scroll={{ x: 'max-content', y: 288 }}
974
+ />
975
+ </div>
976
+ );
977
+ }
978
+
753
979
  const maxTagPlaceholder = (selectedValues) => {
754
980
  const onClose = (e: any, item: any) => {
755
981
  e.preventDefault();
@@ -799,6 +1025,9 @@ const SearchSelect = forwardRef((props: any, ref: any) => {
799
1025
  return (getSelectValueText(value) || kongValue) as string;
800
1026
  }
801
1027
  const getShowStr = () => {
1028
+ // 优先使用业务使用传入的展示
1029
+ if(viewShowValueStr) return viewShowValueStr;
1030
+
802
1031
  const kongValue = '无'
803
1032
  // 先判断labelInValue与否,labelInValue可以直接去value中获取字段名称,否则去下拉框数据里面去拿;
804
1033
  // 再判断是单选还是多选,数据类型不同取值方式也不同
@@ -808,7 +1037,7 @@ const SearchSelect = forwardRef((props: any, ref: any) => {
808
1037
  return getShowValueStr(kongValue);
809
1038
  }
810
1039
 
811
- const isShouldShowStr = props.disabled && ctx
1040
+ const isShouldShowStr = (props.disabled && ctx) || ctx?.mode == 'view';
812
1041
  return (
813
1042
  <div className={'search_select'}>
814
1043
  {fieldComponent ? (
@@ -830,44 +1059,33 @@ const SearchSelect = forwardRef((props: any, ref: any) => {
830
1059
  id={`search_select_div_${uniqueValue}`}
831
1060
  >
832
1061
  <Select
833
- virtual
834
1062
  labelInValue={labelInValue}
835
1063
  value={value}
836
- onChange={onChange}
837
- disabled={props.disabled}
838
- dropdownRender={(menu) => (
839
- <>
840
- <Input
841
- value={searchValue}
842
- style={{ width: '98%', marginLeft: '1%' }}
843
- placeholder="请输入"
844
- onChange={(e) => onSearchChange(e)}
845
- onBlur={onSearchBlur}
846
- onKeyDown={(e) => {
847
- // 阻止多选的冒泡
848
- e.stopPropagation();
849
- }}
850
- />
851
- <Divider style={{ margin: '8px 0' }} />
852
- {menu}
853
- </>
854
- )}
1064
+ onChange={onchange}
1065
+ onClear={onClear}
1066
+ onDeselect={onDeselect}
1067
+ disabled={sDisabled}
1068
+ dropdownStyle={{ borderRadius: '2px', padding: '10px 2px' }}
1069
+ open={selectOpen}
1070
+ onDropdownVisibleChange={onDropdownVisibleChange}
1071
+ dropdownRender={(menu) => items?.length ? renderTable(items) : menu}
855
1072
  notFoundContent={
856
1073
  fetching ? (
857
1074
  <Spin size="small" className='searchSelectSpin' />
858
1075
  ) : (
859
1076
  <div style={{ textAlign: 'center' }}>
860
- <div style={{ marginBottom: 16 }}>
861
- <CopyOutlined style={{ fontSize: '50px' }} />
862
- </div>
863
- <div>无匹配结果,请更换其他内容再试</div>
1077
+ <div>{(searchValue||init||isHaveDependency)?'无匹配结果,请更换其他内容再试':`请录入${searchStartLength?'4位数以上':''}字符进行模糊查询`}</div>
864
1078
  </div>
865
1079
  )
866
1080
  }
867
1081
  onPopupScroll={SelectScroll}
868
- style={{ width: needModalTable ? 'calc(100% - 30px)' : 'calc(100%)' }}
1082
+ style={{ width: 'calc(100%)' }}
869
1083
  placeholder="请选择"
870
1084
  maxTagPlaceholder={maxTagPlaceholder}
1085
+ onSearch={(v) => onSearchChange(v)}
1086
+ {...(needModalTable ? {
1087
+ suffixIcon: <div className={`search_select_expand_button ${(sDisabled)?'search_select_expand_button_disabled':''}`} onClick={showModal}><SearchOutlined /></div>
1088
+ } : {})}
871
1089
  {...currentSelectProps}
872
1090
  getPopupContainer={(triggerNode) => (getPopupContainer && getPopupContainer(triggerNode)) || triggerNode.parentElement}
873
1091
  >
@@ -880,22 +1098,16 @@ const SearchSelect = forwardRef((props: any, ref: any) => {
880
1098
  </Option>
881
1099
  ))}
882
1100
  </Select>
883
- {needModalTable && (
884
- <Button
885
- style={{ width: '30px', padding: '2px'}}
886
- onClick={showModal}
887
- type="primary"
888
- >
889
- <SearchOutlined />
890
- </Button>
891
- )}
892
1101
  </div>
893
1102
  )}
894
1103
  {needModalTable && isModalVisible && (
895
1104
  <Modal
1105
+ maskClosable={false}
1106
+ destroyOnClose
896
1107
  width="80%"
897
1108
  title={modalTableProps?.modalTableTitle}
898
1109
  visible={isModalVisible}
1110
+ confirmLoading={confirmLoading}
899
1111
  onOk={handleOk}
900
1112
  onCancel={handleCancel}
901
1113
  footer={
@@ -907,129 +1119,54 @@ const SearchSelect = forwardRef((props: any, ref: any) => {
907
1119
  <Button
908
1120
  key="submit"
909
1121
  type="primary"
1122
+ loading={confirmLoading}
910
1123
  onClick={handleOk}
911
- disabled={
912
- !tableData.length ||
913
- selectProps?.disabled ||
914
- props?.disabled
915
- }
1124
+ disabled={sDisabled}
916
1125
  >
917
1126
  确定
918
1127
  </Button>,
919
1128
  ]
920
1129
  : null
921
1130
  }
1131
+ wrapClassName={'search_select_modal_wrapper'}
922
1132
  {...(modalTableProps?.modalProps || {})}
923
1133
  >
924
1134
  <div className={'search_select_wrapper'}>
925
- <div
926
- className={'search_select_wrapper_click_flag'}
927
- onClick={() => setCaretLeftFlag(!caretLeftFlag)}
928
- >
929
- <CaretLeftOutlined
930
- className={
931
- caretLeftFlag
932
- ? 'search_select_wrapper_click_flag_arrow'
933
- : 'search_select_wrapper_click_flag_arrow_1'
934
- }
935
- />
936
- </div>
937
- <div
938
- className={
939
- caretLeftFlag
940
- ? 'search_select_wrapper_left'
941
- : 'search_select_wrapper_left1'
942
- }
943
- >
1135
+ <div className={'search_select_wrapper_topForm'}>
944
1136
  <div className={'select_list_columns'}>
945
- <div className={'select_list_columns_tips'}>搜索</div>
946
- <div className={'select_list_columns_formItems'}>
947
- <Form form={form} layout="vertical" key="modalForm">
948
- {formItem(modalTableProps?.tableSearchForm)}
949
- </Form>
950
- </div>
951
- </div>
952
- <div className={'select_list_searchButton'}>
953
- <Button
954
- key="reset"
955
- className={'select_list_button_space'}
956
- onClick={onResetTable}
957
- >
958
- 重置
959
- </Button>
960
- <Button key="search" type="primary" onClick={onSearchTable}>
961
- 查询
962
- </Button>
1137
+ <Form form={form} layout={'horizontal'} colon={false} key="modalForm">
1138
+ <Row>
1139
+ {renderFormItem(modalTableProps?.tableSearchForm)}
1140
+ <Col span={6}>
1141
+ <Space>
1142
+ <Button key="search" type="primary" onClick={onSearchTable}>
1143
+ 查询 Enter
1144
+ </Button>
1145
+ <Button key="reset" onClick={onResetTable}>
1146
+ 重置 ctrl+U
1147
+ </Button>
1148
+ {/* <div>{queryFieldsDom}</div> */}
1149
+ <div style={{position: 'absolute',top: 0,right: 0}}>
1150
+ {hasMoreQueryFields(modalTableProps) && modalTableProps?.isHorizontally
1151
+ ? <img onClick={() => {toggleCollapsed()}} style={{
1152
+ cursor: 'pointer',
1153
+ fontSize: '10px',
1154
+ transition: '0.3s all',
1155
+ transform: `rotate(${collapsed ? 0 : 0.5}turn)`,
1156
+ }} src={zhankaitiaojian} />
1157
+ : <></>
1158
+ }
1159
+ </div>
1160
+ </Space>
1161
+ </Col>
1162
+ </Row>
1163
+ </Form>
963
1164
  </div>
964
1165
  </div>
965
- <div
966
- className={
967
- caretLeftFlag
968
- ? 'search_select_wrapper_right'
969
- : 'search_select_wrapper_right1'
970
- }
971
- >
972
- <div>
973
- <div className={'select_list_selectTips'}>
974
- <div style={{ marginLeft: 8 }}>
975
- 搜索结果共
976
- <span style={themeColor}>
977
- {tablePagination?.total || 0}
978
- </span>
979
-
980
- {selectMode ? (
981
- <span>
982
- , 本次已选
983
- <span style={themeColor}>
984
- {selectedRowKeys?.length || 0}
985
- </span>
986
-
987
- </span>
988
- ) : (
989
- ''
990
- )}
991
- </div>
992
- <div
993
- style={{ color: 'rgba(127, 127, 127, 0.6470588235294118)' }}
994
- >
995
- {selectMode
996
- ? '勾选后点击确定按钮完成选择'
997
- : '双击数据行或点击单选图标完成选择'}
998
- </div>
999
- </div>
1000
- <Table
1001
- size="small"
1002
- rowSelection={rowSelection}
1003
- columns={modalTableProps?.tableColumns}
1004
- dataSource={tableData}
1005
- pagination={tablePagination}
1006
- onChange={handleTableChange}
1007
- rowKey={mappingValueField}
1008
- scroll={{
1009
- x: modalTableProps.overScrollX || 'max-content',
1010
- y: modalTableProps.overScrollY || null,
1011
- }}
1012
- onRow={(record) => {
1013
- return {
1014
- onDoubleClick: (event) =>
1015
- onDoubleClickSelect(event, record),
1016
- };
1017
- }}
1018
- />
1019
- {(selectMode && !modalTableProps?.isHiddenCheckAll) ? (
1020
- <div className={'select_list_selectAll'}>
1021
- <Checkbox
1022
- indeterminate={indeterminate}
1023
- checked={checkedAll}
1024
- onChange={onChangeCheckAll}
1025
- disabled={selectProps?.disabled || props?.disabled}
1026
- />{' '}
1027
- 全选所有页面
1028
- </div>
1029
- ) : (
1030
- ''
1031
- )}
1032
- </div>
1166
+
1167
+ <div className={'search_select_wrapper_bottomTable'}>
1168
+ <div className={selectMode ?'search_select_wrapper_bottomTable_wrapLeft2':'search_select_wrapper_bottomTable_wrapLeft1'}><Tabs items={tabsItems1} /></div>
1169
+ {selectMode ? <div className={'search_select_wrapper_bottomTable_wrapRight'}><Tabs items={tabsItems2} tabBarExtraContent={<span onClick={()=> onChangeSelectedKeys([], [])}>清空已选</span>} /></div> : null}
1033
1170
  </div>
1034
1171
  </div>
1035
1172
  </Modal>