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

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 +1834 -967
  7. package/dist/index.js +1833 -966
  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 +33 -71
  29. package/src/components/Business/columnSettingTable/index.tsx +3 -4
  30. package/src/components/Business/columnSettingTable/sulaSettingTable.tsx +3 -5
  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 +385 -259
  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) {
@@ -463,17 +533,43 @@ const SearchSelect = forwardRef((props: any, ref: any) => {
463
533
  // 解决选择最后1页的sku,返回后,不显示名称问题
464
534
  const source = _.uniqBy(items.concat(selectedValue), 'value')
465
535
  ctx?.form?.setFieldSource(resultSourceKey, source)
466
- setItems(source)
536
+ setSelectDataSource(source,source?.length)
467
537
  formaData(selectedValue, source);
468
538
  } else {
469
539
  const formatResult = selectMode ? [] : null
470
540
  onChange(formatResult, selectedValue)
471
541
  }
472
542
  }
473
-
474
543
  const handleOk = () => {
475
- handleSelectOver(popvalue)
476
- handleCancel();
544
+ // 按钮保存可传入
545
+ if(onSaveCallback) {
546
+ setConfirmLoading(true)
547
+ onSaveCallback(popvalue).then(res => {
548
+ if(true) {
549
+ // 成功信息可以在调用处处理 即resolve({messageSuccessBackInfo: { needThrowSuccess: false } })、resolve({messageSuccessBackInfo: { needThrowSuccess: true, successMessage: '已保存' } })
550
+ let initSuccessMessage = '保存成功'
551
+ const rmsbi = res?.messageSuccessBackInfo || {};
552
+ if(rmsbi && Object.keys(rmsbi)?.length){
553
+ rmsbi?.needThrowSuccess ? message.success(rmsbi?.successMessage || initSuccessMessage) : null
554
+ } else {
555
+ message.success(initSuccessMessage)
556
+ }
557
+ handleCancel();
558
+ } else {
559
+ }
560
+ setConfirmLoading(false)
561
+ }).catch(Error => {
562
+ if(typeof Error === 'object') {
563
+ !Error.needThrowError ? null : message.error(Error.message)
564
+ } else {
565
+ message.error(Error);
566
+ }
567
+ setConfirmLoading(false)
568
+ })
569
+ } else {
570
+ handleSelectOver(popvalue)
571
+ handleCancel();
572
+ }
477
573
  };
478
574
 
479
575
  const formaData = (value: any, source: any) => {
@@ -500,47 +596,35 @@ const SearchSelect = forwardRef((props: any, ref: any) => {
500
596
  const handleCancel = () => {
501
597
  clearModalTable();
502
598
  setIsModalVisible(false);
503
- if (selectMode) {
504
- run();
505
- }
506
599
  };
507
600
 
508
601
  const refreshItems = () => {
509
602
  // 查看是否存在关联值 如果有关联值 就查询 没有就不能查询
510
603
  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) {
604
+ if (!!isHaveDValue()) {
517
605
  run();
518
606
  } else {
519
- setItems([]);
520
- setItemsTotal(0);
607
+ clearSelectDataSource();
521
608
  }
522
609
  } else {
523
610
  run();
524
611
  }
525
612
  }
526
613
 
527
- const onSearchChange = (e) => {
528
- setSearchValue(e.target.value);
529
- refreshItems();
530
- }
531
-
532
- const onSearchBlur = () => {
533
- setSearchValue('');
614
+ const onSearchChange = (v) => {
615
+ setSearchValue(v);
616
+ if(!!searchStartLength && v?.length < searchStartLength) return;
534
617
  refreshItems();
535
618
  }
536
619
 
537
620
  const onSearchTable = () => {
538
621
  const params = form.getFieldsValue();
622
+
623
+ // const isHaveParams = params && Object.keys(params).filter(item => params[item]).length > 0;
624
+ setModalSearched(true);
625
+
539
626
  setTableFormParams(params);
540
627
  getData({ ...params, pageSize: tableInitPageSize }, 2)
541
- if (selectMode) {
542
- getData(params)
543
- }
544
628
  }
545
629
 
546
630
  const onResetTable = () => {
@@ -549,49 +633,13 @@ const SearchSelect = forwardRef((props: any, ref: any) => {
549
633
  getData({ pageSize: tableInitPageSize, currentPage: 1 }, 2)
550
634
  }
551
635
 
636
+ const toggleCollapsed = () => {
637
+ setCollapsed(!collapsed);
638
+ };
639
+
552
640
  const handleTableChange = (pagination) => {
553
641
  getData({ ...tableFormParams, pageSize: pagination.pageSize, currentPage: pagination.current }, 2)
554
642
  }
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
643
  const LightHeightOption = (props) => {
596
644
  const {
597
645
  filterTxt, text,
@@ -634,7 +682,7 @@ const SearchSelect = forwardRef((props: any, ref: any) => {
634
682
  };
635
683
 
636
684
  const onChangeSelectedKeys = (selectKeys, selectRows) => {
637
- let sksResult = selectRows.map((i) => i.value);
685
+ let sksResult = selectRows?.map((i) => i.value)||[];
638
686
 
639
687
  // 单选 默认直接选中 不需要确定 配置了modalRadioNeedFooter就需要确定
640
688
  if(!selectMode && !modalTableProps?.modalRadioNeedFooter) {
@@ -669,13 +717,23 @@ const SearchSelect = forwardRef((props: any, ref: any) => {
669
717
  },
670
718
  getCheckboxProps: selectProps?.getCheckboxProps ? selectProps?.getCheckboxProps : () => {
671
719
  return ({
672
- disabled: selectProps?.disabled || props?.disabled || (!items.length && !tableData.length),
720
+ disabled: disabled || (!items.length && !tableData.length),
673
721
  })
674
722
  },
675
723
  };
676
724
 
677
- const onDoubleClickSelect = (e, record) => {
678
- if (!selectMode && !(selectProps?.disabled || props?.disabled || (!items.length && !tableData.length))) {
725
+ const onRowClickSelect = (e, record,type) => {
726
+ if (selectMode && !(disabled || (!items.length && !tableData.length))) {
727
+ const oldSelect = selectedRows;
728
+ const newSelect = [JSON.parse(JSON.stringify(record))];
729
+ const srs = getRealStr(oldSelect,newSelect,record);
730
+ const sks = srs.map((i: any) => i.value)
731
+
732
+ onChangeSelectedKeys(sks, srs)
733
+ }
734
+ }
735
+ const onDoubleClickSelect = (e, record,type) => {
736
+ if (!selectMode && !(disabled || (!items.length && !tableData.length))) {
679
737
  const srs = [JSON.parse(JSON.stringify(record))]
680
738
  const sks = srs.map((i: any) => i.value)
681
739
  onChangeSelectedKeys(sks, srs)
@@ -693,40 +751,49 @@ const SearchSelect = forwardRef((props: any, ref: any) => {
693
751
  return false
694
752
  }
695
753
  };
696
- return list.map((i: any) => {
754
+
755
+ const { emptyArray } = getFormRowInfo(list);
756
+ const addKong = emptyArray?.map((i: any) =>({ type: 'kong'}))||[];
757
+ return list?.concat(addKong)?.map((i: any, index: number) => {
758
+ if(i?.type === 'kong') return <Col span={ColSpan} key={i}></Col>;
759
+
697
760
  if (i?.type === 'select' || i?.field?.type === 'select') {
698
761
  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>
762
+ <Col span={ColSpan} key={i.name}>
763
+ <Form.Item name={i.name} label={i.label} key={i.name}>
764
+ <Select style={{ width: '100%' }} placeholder='请选择' onDeselect ={v => onSearchTable()} {...i?.field?.props} disabled={setDisabled(i.name)}>
765
+ {i?.initialSource?.length && i?.initialSource.map((m: any) => (
766
+ <Option value={m.value} key={m.value}>{m.text}</Option>
767
+ ))}
768
+ </Select>
769
+ </Form.Item>
770
+ </Col>
706
771
  )
707
772
  }
708
773
 
709
774
  if (i?.type === 'treeSelect' || i?.field?.type === 'treeSelect') {
710
775
  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>
776
+ <Col span={ColSpan} key={i.name}>
777
+ <Form.Item name={i.name} label={i.label} key={i.name}>
778
+ <TreeSelect style={{ width: '100%' }} placeholder='请选择' {...i?.field?.props} disabled={setDisabled(i.name)}></TreeSelect>
779
+ </Form.Item>
780
+ </Col>
714
781
  )
715
782
  }
716
783
 
717
784
  if (i?.type === 'businessSearchSelect' || i?.field?.type === 'businessSearchSelect') {
718
785
  return (
719
- <div>
786
+ <Col span={ColSpan} key={i.name}>
720
787
  <Form.Item name={i.name} label={i.label} key={i.name}>
721
788
  <BusinessSearchSelect {...i.field.props} disabled={setDisabled(i.name)} />
722
789
  </Form.Item>
723
- </div>
790
+ </Col>
724
791
  )
725
792
  }
726
793
 
727
794
  if (i?.type === 'multipleQueryInput' || i?.field?.type === 'multipleQueryInput') {
728
795
  return (
729
- <div>
796
+ <Col span={ColSpan} key={i.name}>
730
797
  <Form.Item name={i.name} label={i.label} key={i.name}>
731
798
  <QueryMutipleInput onValueChange={(value) => {
732
799
  form.setFieldsValue({
@@ -734,15 +801,17 @@ const SearchSelect = forwardRef((props: any, ref: any) => {
734
801
  })
735
802
  }} />
736
803
  </Form.Item>
737
- </div>
804
+ </Col>
738
805
  );
739
806
  }
740
807
 
741
808
  // 默认type是input
742
809
  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>
810
+ <Col span={ColSpan} key={i.name}>
811
+ <Form.Item name={i.name} label={i.label} key={i.name}>
812
+ <Input style={{ width: '100%' }} placeholder='请输入' allowClear maxLength={100} {...i?.field?.props} disabled={setDisabled(i.name)} />
813
+ </Form.Item>
814
+ </Col>
746
815
  )
747
816
  })
748
817
  } else {
@@ -750,6 +819,152 @@ const SearchSelect = forwardRef((props: any, ref: any) => {
750
819
  }
751
820
  }
752
821
 
822
+ const renderFormItem = (list) => {
823
+ const viCount = modalTableProps?.visibleFieldsCount || defaultVisibleFieldsCount;
824
+ return collapsed ? formItem(list?.slice(0,viCount)) : formItem(list)
825
+ }
826
+
827
+ // const queryFieldsDom = <SearchItemTable
828
+ // ref={searchTableRef}
829
+ // setShowSearchFields={setShowSearchFields||[]}
830
+ // showSearchFields={showSearchFields||[]}
831
+ // datasource={modalTableProps?.tableSearchForm || []}
832
+ // bsTableCode={bsTableCode}
833
+ // />
834
+
835
+ const renderShowTable = (tableList, type) => {
836
+ const tableBoxHeighth = getTableHeigth(modalTableProps?.tableSearchForm);
837
+ const oSY = `calc(100vh - 391px - 82px)`; // 分页 24+16*2+10 「高 + margin * 2 + paddingBottom 10 」
838
+ return (
839
+ <div style={{ height: `calc(100vh - 391px)` }}>
840
+ <Table
841
+ bordered
842
+ size="middle"
843
+ rowSelection={rowSelection}
844
+ columns={tableShowColumns}
845
+ dataSource={tableList}
846
+ {...type=='noPage'?{
847
+ pagination: initPagination,
848
+ locale: {
849
+ emptyText: '暂无已选结果',
850
+ }
851
+ }:{
852
+ pagination: tablePagination,
853
+ onChange: handleTableChange,
854
+ loading: fetching,
855
+ locale: {
856
+ emptyText: modalSearched? '无匹配结果,请更换其他内容再试' : '请输入搜索条件',
857
+ }
858
+ }}
859
+ rowKey={mappingValueField}
860
+ scroll={{
861
+ x: modalTableProps.overScrollX || 'max-content',
862
+ y: modalTableProps.overScrollY || oSY,
863
+ }}
864
+ onRow={(record) => {
865
+ return {
866
+ onClick: event => onRowClickSelect(event, record), // 点击行
867
+ onDoubleClick: (event) =>
868
+ onDoubleClickSelect(event, record),
869
+ };
870
+ }}
871
+ />
872
+ </div>
873
+ )
874
+ }
875
+
876
+ const tabsItems1 = [
877
+ { label: `全部(${tablePagination?.total || 0})`, key: 'all', children: renderShowTable(tableData) }, // 务必填写 key
878
+ ];
879
+ const tabsItems2 = [
880
+ { label: `已选(${selectedRowKeys?.length || 0})`, key: 'selected', children: renderShowTable(selectedRows?.map((s,index)=> ({...s,keyIndex:index+1}))||[],'noPage') },
881
+ ];
882
+
883
+ const resetSelectDataSource = () => {
884
+ setSearchValue('');
885
+ // 有关联值 不需要清空下拉框数据 也不需要重新去请求了
886
+ if(isHaveDependency) return;
887
+ clearSelectDataSource();
888
+ init && run('init')
889
+ }
890
+
891
+ const onClear = () => {
892
+ formaData([], items);
893
+ resetSelectDataSource();
894
+ }
895
+
896
+ const onDeselect = (...arg) => {
897
+ const oldSelect = value?.map(s => ({ value: s?.value||s }))||[];
898
+ const deRecord = arg[1];
899
+ const srs = oldSelect.filter((s: any) => s.value != deRecord?.value)
900
+ onSelectClick(srs, items,false)
901
+ }
902
+ const onSelectClick = (srs, ds,nr=true) => {
903
+ formaData(srs, ds);
904
+ nr && setSelectOpen(false);
905
+ }
906
+
907
+ const onDropdownVisibleChange = (visible) => {
908
+ setSelectOpen(visible);
909
+ // 关闭下拉框 如果首次本身就不展示数据的 没有选中数据-需要清空查询数据源; 首次展示的默认展示
910
+ if (!visible && !value?.length) {
911
+ resetSelectDataSource()
912
+ }
913
+ }
914
+ const renderTable = (dataSource) => {
915
+ return (
916
+ <div className={`search_select_dropdown_table ${!selectMode?'search_select_dropdown_table1':''}`}>
917
+ <Table
918
+ virtual
919
+ bordered
920
+ {...(selectMode?{
921
+ rowSelection: {
922
+ type: 'checkbox',
923
+ columnWidth: '24px',
924
+ selectedRowKeys: labelInValue ? value?.map(s=> (s?.value||s)) : value,
925
+ preserveSelectedRowKeys: true, // 避免搜索之后 没有了选中前的数据 保证sks的正确性
926
+ onChange: (sks, srs) => {
927
+ const oldSelect = value?.map(s => ({ value: s?.value||s }))||[];
928
+ let tmpSelectedRows = oldSelect.concat(srs).filter(item => item != undefined);
929
+ let realSrs = sks.map(key => tmpSelectedRows.filter(item => item.value == key)[0]).filter(item => item != undefined)
930
+ onSelectClick(realSrs, dataSource,false)
931
+ }
932
+ },
933
+ onRow: (record, rowKey) => ({
934
+ onClick: event => {
935
+ event.stopPropagation();
936
+ event.nativeEvent.stopImmediatePropagation();
937
+
938
+ const oldSelect = value?.map(s => ({ value: s?.value||s }))||[];
939
+ const newSelect = [JSON.parse(JSON.stringify(record))];
940
+ const srs = getRealStr(oldSelect,newSelect,record);
941
+ onSelectClick(srs,dataSource,false)
942
+ }, // 点击行
943
+ })
944
+ }:{
945
+ rowSelection: {
946
+ type: 'radio',
947
+ columnWidth: 0,
948
+ selectedRowKeys: labelInValue ? value?.value&&[value?.value]||[] : value&&[value]||[],
949
+ },
950
+ onRow: (record, rowKey) => ({
951
+ onClick: event => {
952
+ const srs = [JSON.parse(JSON.stringify(record))]
953
+ onSelectClick(srs,dataSource)
954
+ }, // 点击行
955
+ })
956
+ })}
957
+ columns={selectProps?.renderTableColumns||[]}
958
+ dataSource={items}
959
+ size="middle"
960
+ pagination={false}
961
+ rowKey={mappingValueField}
962
+ scroll={{ x: 'max-content', y: 288 }}
963
+ />
964
+ </div>
965
+ );
966
+ }
967
+
753
968
  const maxTagPlaceholder = (selectedValues) => {
754
969
  const onClose = (e: any, item: any) => {
755
970
  e.preventDefault();
@@ -799,6 +1014,9 @@ const SearchSelect = forwardRef((props: any, ref: any) => {
799
1014
  return (getSelectValueText(value) || kongValue) as string;
800
1015
  }
801
1016
  const getShowStr = () => {
1017
+ // 优先使用业务使用传入的展示
1018
+ if(viewShowValueStr) return viewShowValueStr;
1019
+
802
1020
  const kongValue = '无'
803
1021
  // 先判断labelInValue与否,labelInValue可以直接去value中获取字段名称,否则去下拉框数据里面去拿;
804
1022
  // 再判断是单选还是多选,数据类型不同取值方式也不同
@@ -808,7 +1026,7 @@ const SearchSelect = forwardRef((props: any, ref: any) => {
808
1026
  return getShowValueStr(kongValue);
809
1027
  }
810
1028
 
811
- const isShouldShowStr = props.disabled && ctx
1029
+ const isShouldShowStr = (props.disabled && ctx) || ctx?.mode == 'view';
812
1030
  return (
813
1031
  <div className={'search_select'}>
814
1032
  {fieldComponent ? (
@@ -830,44 +1048,33 @@ const SearchSelect = forwardRef((props: any, ref: any) => {
830
1048
  id={`search_select_div_${uniqueValue}`}
831
1049
  >
832
1050
  <Select
833
- virtual
834
1051
  labelInValue={labelInValue}
835
1052
  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
- )}
1053
+ onChange={onchange}
1054
+ onClear={onClear}
1055
+ onDeselect={onDeselect}
1056
+ disabled={sDisabled}
1057
+ dropdownStyle={{ borderRadius: '2px', padding: '10px 2px' }}
1058
+ open={selectOpen}
1059
+ onDropdownVisibleChange={onDropdownVisibleChange}
1060
+ dropdownRender={(menu) => items?.length ? renderTable(items) : menu}
855
1061
  notFoundContent={
856
1062
  fetching ? (
857
1063
  <Spin size="small" className='searchSelectSpin' />
858
1064
  ) : (
859
1065
  <div style={{ textAlign: 'center' }}>
860
- <div style={{ marginBottom: 16 }}>
861
- <CopyOutlined style={{ fontSize: '50px' }} />
862
- </div>
863
- <div>无匹配结果,请更换其他内容再试</div>
1066
+ <div>{(searchValue||init||isHaveDependency)?'无匹配结果,请更换其他内容再试':`请录入${searchStartLength?'4位数以上':''}字符进行模糊查询`}</div>
864
1067
  </div>
865
1068
  )
866
1069
  }
867
1070
  onPopupScroll={SelectScroll}
868
- style={{ width: needModalTable ? 'calc(100% - 30px)' : 'calc(100%)' }}
1071
+ style={{ width: 'calc(100%)' }}
869
1072
  placeholder="请选择"
870
1073
  maxTagPlaceholder={maxTagPlaceholder}
1074
+ onSearch={(v) => onSearchChange(v)}
1075
+ {...(needModalTable ? {
1076
+ suffixIcon: <div className={`search_select_expand_button ${(sDisabled)?'search_select_expand_button_disabled':''}`} onClick={showModal}><SearchOutlined /></div>
1077
+ } : {})}
871
1078
  {...currentSelectProps}
872
1079
  getPopupContainer={(triggerNode) => (getPopupContainer && getPopupContainer(triggerNode)) || triggerNode.parentElement}
873
1080
  >
@@ -880,22 +1087,16 @@ const SearchSelect = forwardRef((props: any, ref: any) => {
880
1087
  </Option>
881
1088
  ))}
882
1089
  </Select>
883
- {needModalTable && (
884
- <Button
885
- style={{ width: '30px', padding: '2px'}}
886
- onClick={showModal}
887
- type="primary"
888
- >
889
- <SearchOutlined />
890
- </Button>
891
- )}
892
1090
  </div>
893
1091
  )}
894
1092
  {needModalTable && isModalVisible && (
895
1093
  <Modal
1094
+ maskClosable={false}
1095
+ destroyOnClose
896
1096
  width="80%"
897
1097
  title={modalTableProps?.modalTableTitle}
898
1098
  visible={isModalVisible}
1099
+ confirmLoading={confirmLoading}
899
1100
  onOk={handleOk}
900
1101
  onCancel={handleCancel}
901
1102
  footer={
@@ -907,129 +1108,54 @@ const SearchSelect = forwardRef((props: any, ref: any) => {
907
1108
  <Button
908
1109
  key="submit"
909
1110
  type="primary"
1111
+ loading={confirmLoading}
910
1112
  onClick={handleOk}
911
- disabled={
912
- !tableData.length ||
913
- selectProps?.disabled ||
914
- props?.disabled
915
- }
1113
+ disabled={sDisabled}
916
1114
  >
917
1115
  确定
918
1116
  </Button>,
919
1117
  ]
920
1118
  : null
921
1119
  }
1120
+ wrapClassName={'search_select_modal_wrapper'}
922
1121
  {...(modalTableProps?.modalProps || {})}
923
1122
  >
924
1123
  <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
- >
1124
+ <div className={'search_select_wrapper_topForm'}>
944
1125
  <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>
1126
+ <Form form={form} layout={'horizontal'} colon={false} key="modalForm">
1127
+ <Row>
1128
+ {renderFormItem(modalTableProps?.tableSearchForm)}
1129
+ <Col span={6}>
1130
+ <Space>
1131
+ <Button key="search" type="primary" onClick={onSearchTable}>
1132
+ 查询 Enter
1133
+ </Button>
1134
+ <Button key="reset" onClick={onResetTable}>
1135
+ 重置 ctrl+U
1136
+ </Button>
1137
+ {/* <div>{queryFieldsDom}</div> */}
1138
+ <div style={{position: 'absolute',top: 0,right: 0}}>
1139
+ {hasMoreQueryFields(modalTableProps) && modalTableProps?.isHorizontally
1140
+ ? <img onClick={() => {toggleCollapsed()}} style={{
1141
+ cursor: 'pointer',
1142
+ fontSize: '10px',
1143
+ transition: '0.3s all',
1144
+ transform: `rotate(${collapsed ? 0 : 0.5}turn)`,
1145
+ }} src={zhankaitiaojian} />
1146
+ : <></>
1147
+ }
1148
+ </div>
1149
+ </Space>
1150
+ </Col>
1151
+ </Row>
1152
+ </Form>
963
1153
  </div>
964
1154
  </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>
1155
+
1156
+ <div className={'search_select_wrapper_bottomTable'}>
1157
+ <div className={selectMode ?'search_select_wrapper_bottomTable_wrapLeft2':'search_select_wrapper_bottomTable_wrapLeft1'}><Tabs items={tabsItems1} /></div>
1158
+ {selectMode ? <div className={'search_select_wrapper_bottomTable_wrapRight'}><Tabs items={tabsItems2} tabBarExtraContent={<span onClick={()=> onChangeSelectedKeys([], [])}>清空已选</span>} /></div> : null}
1033
1159
  </div>
1034
1160
  </div>
1035
1161
  </Modal>