@bit-sun/business-component 2.0.26 → 2.0.28

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,595 @@
1
+ // @ts-nocheck
2
+ import React from 'react';
3
+ import { Table, message, Checkbox, Modal, Input, Button, Tooltip } from 'antd';
4
+ import {
5
+ SortableContainer,
6
+ SortableElement,
7
+ SortableHandle,
8
+ } from 'react-sortable-hoc';
9
+ import { MenuOutlined, SearchOutlined } from '@ant-design/icons';
10
+ import { arrayMoveImmutable } from 'array-move';
11
+ import shezhi from '../../../assets/icon-shezhi.svg';
12
+ import close from '../../../assets/close.svg';
13
+ import drag from '../../../assets/drag.svg';
14
+ import axios from 'axios';
15
+ // import { request } from 'umi';
16
+ import './index.less';
17
+
18
+ interface SortTableProps {
19
+ [propName: string]: any;
20
+ }
21
+ const { Search } = Input;
22
+
23
+ const DragHandle = SortableHandle(() => <img src={drag} />);
24
+
25
+ const data = [
26
+ {
27
+ key: '1',
28
+ title: 'John Brown',
29
+ age: 32,
30
+ address: 'New York No. 1 Lake Park',
31
+ index: 0,
32
+ },
33
+ {
34
+ key: '2',
35
+ title: 'Jim Green',
36
+ age: 42,
37
+ address: 'London No. 1 Lake Park',
38
+ index: 1,
39
+ },
40
+ {
41
+ key: '3',
42
+ title: 'Joe Black',
43
+ age: 32,
44
+ address: 'Sidney No. 1 Lake Park',
45
+ index: 2,
46
+ },
47
+ ];
48
+
49
+ const SortableItem = SortableElement((props: any) => <tr {...props} />);
50
+ const SortableBody = SortableContainer((props: any) => <tbody {...props} />);
51
+
52
+ class SortableTable extends React.Component<SortTableProps> {
53
+ state = {
54
+ dataSource: [],
55
+ columns: [],
56
+ selectedRowKeys: [],
57
+ sortDataSource: [],
58
+ setVisible: false,
59
+ searchDataSource: false,
60
+ onSearchSort: false,
61
+ };
62
+
63
+ patchUserColumnConfig = (config: any) => {
64
+ const { tableCode }: any = this.props;
65
+ if (!tableCode) return;
66
+ let configvalue = config.map((item:any) => ({
67
+ key: item.key,
68
+ dataIndex: item.dataIndex,
69
+ width: item.width,
70
+ hidden: item.hidden,
71
+ fixed: item.fixed
72
+ }))
73
+
74
+ axios({
75
+ url: '/user/appConfig/saveUserOrder',
76
+ method:'POST',
77
+ data: {
78
+ "code": tableCode,
79
+ "detail": JSON.stringify(configvalue)
80
+ },
81
+ }).then((res:any) => {
82
+ if (res?.data?.status === '0') {
83
+ this.patchConfigToLocalstorage(configvalue, tableCode)
84
+ } else {
85
+ message.error('保存表头列自定义失败,请稍后尝试');
86
+ }
87
+ })
88
+ }
89
+
90
+ patchConfigToLocalstorage = (configvalue:any, tableCode:string) => {
91
+ let config = localStorage.getItem('columnCondition') || '[]'
92
+ let configArray = JSON.parse(config)
93
+ let currentSetting = configArray.filter((item:any) => item.code === tableCode)
94
+ if (currentSetting.length) {
95
+ currentSetting[0].detail = JSON.stringify(configvalue)
96
+ } else {
97
+ configArray.push({
98
+ "code": tableCode,
99
+ "detail": JSON.stringify(configvalue)
100
+ })
101
+ }
102
+
103
+ localStorage.setItem('columnCondition', JSON.stringify(configArray))
104
+ }
105
+
106
+ setInitValue = (datasource: any[]) => {
107
+ const { showColumns=[] } = this.props;
108
+ // 获取当前列表定义数据
109
+ let columnConfig = this.getConfigFromlocalstorage();
110
+ let initialDataSourceData = columnConfig.length ? datasource.map(item => {
111
+ let inner = columnConfig.filter((innerItem: any) => (
112
+ innerItem.dataIndex && innerItem.dataIndex === item.dataIndex
113
+ ) || (innerItem.key && innerItem.key === item.key));
114
+ let showColumnItem = showColumns.filter((inneritem:any) => ((inneritem.dataIndex && inneritem.dataIndex === item.dataIndex) || (inneritem.key && inneritem.key === item.key)))
115
+ return {
116
+ ...item,
117
+ key: item.key || item.dataIndex,
118
+ width: showColumnItem[0]?.width || inner[0]?.width || item.width,
119
+ hidden: columnConfig.length && !inner.length,
120
+ }
121
+ })
122
+ : [...datasource]
123
+ this.setState({
124
+ dataSource: initialDataSourceData.map((item: any) => ({
125
+ ...item,
126
+ key: item.key || item.dataIndex,
127
+ })),
128
+ sortDataSource: initialDataSourceData.filter((item: any) => !item.hidden)
129
+ .map((item: any) => ({
130
+ ...item,
131
+ key: item.key || item.dataIndex,
132
+ })),
133
+ });
134
+ };
135
+
136
+ componentWillReceiveProps(nextProps: any) {
137
+ if (
138
+ this.props?.datasource &&
139
+ JSON.stringify(this.props?.datasource) !=
140
+ JSON.stringify(nextProps?.datasource)
141
+ ) {
142
+ this.setInitValue(nextProps?.datasource || []);
143
+ }
144
+ }
145
+
146
+ componentDidMount() {
147
+ const { datasource = [] }: any = this.props;
148
+ this.setInitValue(datasource);
149
+ }
150
+
151
+ columns = [
152
+ {
153
+ title: '列名称',
154
+ dataIndex: 'title',
155
+ className: 'drag-visible',
156
+ width: 100,
157
+ },
158
+ {
159
+ title: '删除',
160
+ dataIndex: 'title1',
161
+ render: (text: any, record: any) => {
162
+ return (
163
+ <span
164
+ onClick={() => {
165
+ this.setState({
166
+ sortDataSource: this.state.sortDataSource.filter((item:any) => {
167
+ return item.title !== record.title;
168
+ }),
169
+ dataSource: [
170
+ ...this.state.dataSource.map((item:any) => {
171
+ if (item.title === record.title) {
172
+ return {
173
+ ...item,
174
+ hidden: true,
175
+ };
176
+ }
177
+
178
+ return item;
179
+ }),
180
+ ],
181
+ });
182
+ }}
183
+ >
184
+ <img src={close} />
185
+ </span>
186
+ );
187
+ },
188
+ },
189
+ {
190
+ title: 'Sort',
191
+ dataIndex: 'sort',
192
+ className: 'drag-visible',
193
+ render: () => <DragHandle />,
194
+ },
195
+ ];
196
+
197
+ showModal = () => {
198
+ const { datasource = [] }: any = this.props;
199
+ this.setState({
200
+ visible: true,
201
+ });
202
+ this.setInitValue(datasource);
203
+ };
204
+
205
+ handleOk = (e?: React.MouseEvent<HTMLElement>) => {
206
+ const { sortDataSource }: any = this.state;
207
+ const { setShowColumns }: any = this.props;
208
+ if (!sortDataSource.length) {
209
+ message.warning('至少选择一列!')
210
+ return;
211
+ }
212
+ this.setState({
213
+ visible: false,
214
+ });
215
+ setShowColumns([...sortDataSource]);
216
+ this.patchUserColumnConfig(sortDataSource)
217
+ };
218
+
219
+ handleCancel = (e: React.MouseEvent<HTMLElement>) => {
220
+ this.setState({
221
+ visible: false,
222
+ });
223
+ };
224
+
225
+ handleTableHeadHidden = (title: string) => {
226
+ const { sortDataSource, dataSource } = this.state;
227
+ this.setState(
228
+ {
229
+ sortDataSource: sortDataSource.filter((item: any) => {
230
+ return item.title !== title;
231
+ }),
232
+ dataSource: [
233
+ ...dataSource.map((item:any) => {
234
+ if (item.title === title) {
235
+ return {
236
+ ...item,
237
+ hidden: true,
238
+ };
239
+ }
240
+
241
+ return item;
242
+ }),
243
+ ],
244
+ },
245
+ () => {
246
+ this.handleOk();
247
+ },
248
+ );
249
+ };
250
+
251
+ onSortEnd = ({ oldIndex, newIndex }: any) => {
252
+ const { sortDataSource } = this.state;
253
+ const { value, setValue }: any = this.props;
254
+ if (sortDataSource[oldIndex]['fixed']) {
255
+ message.warning('固定列不可移动');
256
+ return;
257
+ }
258
+ if (oldIndex !== newIndex) {
259
+ const newData = arrayMoveImmutable(
260
+ [].concat(sortDataSource),
261
+ oldIndex,
262
+ newIndex,
263
+ ).filter((el) => !!el);
264
+ this.setState({ sortDataSource: newData });
265
+ }
266
+ };
267
+
268
+ DraggableContainer = (props: any) => (
269
+ <SortableBody
270
+ useDragHandle
271
+ disableAutoscroll
272
+ helperClass="row-dragging"
273
+ onSortEnd={this.onSortEnd}
274
+ {...props}
275
+ />
276
+ );
277
+
278
+ DraggableBodyRow = ({ className, style, ...restProps }: any) => {
279
+ const { sortDataSource } = this.state;
280
+ // function findIndex base on Table rowKey props and should always be a right array index
281
+ const index = sortDataSource.findIndex(
282
+ (x:any) => x.key === restProps['data-row-key'],
283
+ );
284
+ return <SortableItem index={index} {...restProps} />;
285
+ };
286
+
287
+ onChange = (e: any, title: any) => {
288
+ const { sortDataSource, dataSource } = this.state;
289
+ if (!e.target.checked) {
290
+ this.setState({
291
+ sortDataSource: sortDataSource.filter((item: any) => {
292
+ return item.title !== title;
293
+ }),
294
+ dataSource: [
295
+ ...dataSource.map((item: any) => {
296
+ if (item.title === title) {
297
+ return {
298
+ ...item,
299
+ hidden: true,
300
+ };
301
+ }
302
+
303
+ return item;
304
+ }),
305
+ ],
306
+ });
307
+ } else {
308
+ let fixedLeft: any[] = [];
309
+ let fixedRight: any[] = [];
310
+ let noFixedSortSource: any = [];
311
+ sortDataSource.forEach((item: any) => {
312
+ if (item?.fixed === 'left') {
313
+ fixedLeft.push(item);
314
+ } else if (item?.fixed === 'right') {
315
+ fixedRight.push(item);
316
+ } else {
317
+ noFixedSortSource.push(item);
318
+ }
319
+ });
320
+ this.setState({
321
+ sortDataSource: [
322
+ ...fixedLeft,
323
+ ...noFixedSortSource,
324
+ ...dataSource
325
+ .filter((item: any) => item.title === title)
326
+ .map((source: any) => {
327
+ return {
328
+ ...source,
329
+ hidden: false,
330
+ };
331
+ }),
332
+ ...fixedRight,
333
+ ],
334
+ dataSource: [
335
+ ...dataSource.map((item: any) => {
336
+ if (item.title === title) {
337
+ return {
338
+ ...item,
339
+ hidden: false,
340
+ };
341
+ }
342
+
343
+ return item;
344
+ }),
345
+ ],
346
+ });
347
+ }
348
+ };
349
+
350
+ handleReset = () => {
351
+ const { datasource = [] }: any = this.props;
352
+ this.setInitValue(datasource);
353
+ };
354
+
355
+ onSearch = (e: any) => {
356
+ this.setState({
357
+ searchDataSource: e.target.value,
358
+ });
359
+ };
360
+
361
+ onSearchSort = (e: any) => {
362
+ this.setState({
363
+ onSearchSort: e.target.value,
364
+ });
365
+ };
366
+
367
+ getConfigFromlocalstorage = () => {
368
+ const { tableCode } = this.props;
369
+ if (!tableCode) return [];
370
+ let config = localStorage.getItem('columnCondition') || '[]';
371
+ let configArray = JSON.parse(config);
372
+ let configSetting = configArray.filter(
373
+ (item:any) => item.code === tableCode,
374
+ );
375
+
376
+ if (configSetting.length) {
377
+ return JSON.parse(configSetting[0].detail || '[]');
378
+ }
379
+ return [];
380
+ };
381
+
382
+ render() {
383
+ const {
384
+ dataSource,
385
+ searchDataSource,
386
+ sortDataSource,
387
+ visible,
388
+ onSearchSort,
389
+ }: any = this.state;
390
+
391
+ let seatchDataSource = dataSource.filter(
392
+ (item: any) => item?.title?.indexOf(searchDataSource || '') > -1,
393
+ );
394
+
395
+ return (
396
+ <div className={'sort_table_wrapper'}>
397
+ <Modal
398
+ title="设置表头内容"
399
+ wrapClassName={'sort_table_wrapper'}
400
+ width={820}
401
+ visible={visible}
402
+ onOk={this.handleOk}
403
+ onCancel={this.handleCancel}
404
+ footer={[
405
+ <Button key="back" onClick={this.handleReset}>
406
+ 恢复默认
407
+ </Button>,
408
+ <Button key="submit" onClick={this.handleOk}>
409
+ 取消
410
+ </Button>,
411
+ <Button key="submit" type="primary" onClick={this.handleOk}>
412
+ 确认
413
+ </Button>,
414
+ ]}
415
+ >
416
+ <div className={'sort_table'}>
417
+ <div className={'sort_table_column_wrapper'}>
418
+ <span className={'sort_table_column_count'}>
419
+ 可选字段 <span>(共{dataSource.length}个)</span>
420
+ </span>
421
+ <div className={'sort_table_column'}>
422
+ <Input
423
+ prefix={<SearchOutlined className="site-form-item-icon" />}
424
+ placeholder="搜索"
425
+ allowClear
426
+ onChange={this.onSearch}
427
+ style={{ width: 540 }}
428
+ />
429
+ <div>
430
+ {!searchDataSource && (
431
+ <Checkbox
432
+ checked={
433
+ !dataSource.some((item: any) => {
434
+ if (item.hidden) return true;
435
+
436
+ return false;
437
+ })
438
+ }
439
+ onClick={(e:any) => {
440
+ this.setState({
441
+ dataSource: [
442
+ ...dataSource.map((item: any) => {
443
+ return {
444
+ ...item,
445
+ hidden: !e.target.checked,
446
+ };
447
+ }),
448
+ ],
449
+ sortDataSource: e.target.checked
450
+ ? [
451
+ ...dataSource.map((item: any) => {
452
+ return {
453
+ ...item,
454
+ hidden: false,
455
+ };
456
+ }),
457
+ ]
458
+ : [],
459
+ });
460
+ }}
461
+ >
462
+ 全选
463
+ </Checkbox>
464
+ )}
465
+ </div>
466
+ <div className={'sort_table_column_all'}>
467
+ {searchDataSource
468
+ ? seatchDataSource.map((item: any) => {
469
+ return (
470
+ <Checkbox
471
+ checked={!item.hidden}
472
+ onChange={(e) => {
473
+ this.onChange(e, item.title);
474
+ }}
475
+ >
476
+ {item.title}
477
+ </Checkbox>
478
+ );
479
+ })
480
+ : dataSource
481
+ .filter(
482
+ (item: any) =>
483
+ item?.title?.indexOf('人') === -1 &&
484
+ item?.title?.indexOf('日期') === -1,
485
+ )
486
+ .map((item: any) => {
487
+ return (
488
+ <Checkbox
489
+ checked={!item.hidden}
490
+ onChange={(e) => {
491
+ this.onChange(e, item.title);
492
+ }}
493
+ >
494
+ {item.title}
495
+ </Checkbox>
496
+ );
497
+ })}
498
+ {!!seatchDataSource.length && (
499
+ <span style={{ width: '144px' }}></span>
500
+ )}
501
+
502
+ {!seatchDataSource.length && (
503
+ <div className={'sort_table_column_all_empty'}>
504
+ 未查询到结果
505
+ </div>
506
+ )}
507
+ </div>
508
+ {!searchDataSource && (
509
+ <div>
510
+ <div className={'sort_table_column_special'}>
511
+ <span>人员时间字段</span>
512
+ </div>
513
+ <div className={'sort_table_column_all'}>
514
+ {[...dataSource]
515
+ .filter(
516
+ (item) =>
517
+ item?.title?.indexOf('人') > -1 ||
518
+ item?.title?.indexOf('日期') > -1,
519
+ )
520
+ .map((item) => {
521
+ return (
522
+ <Checkbox
523
+ checked={!item.hidden}
524
+ onChange={(e) => {
525
+ this.onChange(e, item.title);
526
+ }}
527
+ >
528
+ {item.title}
529
+ </Checkbox>
530
+ );
531
+ })}
532
+ <span style={{ width: '144px' }}></span>
533
+ </div>
534
+ </div>
535
+ )}
536
+
537
+ {/* <Checkbox.Group
538
+ options={dataSource.map(item => {
539
+ return {
540
+ label: item.title,
541
+ value: item.title,
542
+ }
543
+ })}
544
+ defaultValue={selectedRowKeys}
545
+ onChange={() => {}}
546
+ /> */}
547
+ </div>
548
+ </div>
549
+ <div className={'sort_table_content_wrapper'}>
550
+ <span className={'sort_table_content_count'}>
551
+ 已选字段 <span>(共{sortDataSource.length}个)</span>
552
+ </span>
553
+ <div className={'sort_table_content'}>
554
+ <span style={{ paddingLeft: '10px' }}>
555
+ <Input
556
+ prefix={<SearchOutlined className="site-form-item-icon" />}
557
+ placeholder="搜索"
558
+ allowClear
559
+ onChange={this.onSearchSort}
560
+ style={{ width: 190 }}
561
+ />
562
+ </span>
563
+ <Table
564
+ pagination={false}
565
+ showHeader={false}
566
+ dataSource={
567
+ onSearchSort
568
+ ? sortDataSource.filter(
569
+ (item:any) => item?.title?.indexOf(onSearchSort) > -1,
570
+ )
571
+ : sortDataSource
572
+ }
573
+ columns={this.columns}
574
+ rowKey="key"
575
+ // rowSelection={rowSelection}
576
+ components={{
577
+ body: {
578
+ wrapper: this.DraggableContainer,
579
+ row: this.DraggableBodyRow,
580
+ },
581
+ }}
582
+ />
583
+ </div>
584
+ </div>
585
+ </div>
586
+ </Modal>
587
+ <Tooltip title="列设置">
588
+ <img width={32} onClick={this.showModal} src={shezhi} />
589
+ </Tooltip>
590
+ </div>
591
+ );
592
+ }
593
+ }
594
+
595
+ export default SortableTable;