@bit-sun/business-component 2.0.12 → 2.0.13

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 (68) hide show
  1. package/.editorconfig +16 -16
  2. package/.fatherrc.ts +4 -4
  3. package/.gitlab-ci.yml +174 -135
  4. package/.prettierignore +7 -7
  5. package/.prettierrc +11 -11
  6. package/.umirc.ts +74 -90
  7. package/README.md +27 -27
  8. package/dist/components/Business/SearchSelect/index.d.ts +1 -1
  9. package/dist/components/Functional/SearchSelect/index.d.ts +1 -2
  10. package/dist/index.d.ts +0 -1
  11. package/dist/index.esm.js +6794 -7350
  12. package/dist/index.js +6793 -7348
  13. package/docs/index.md +21 -21
  14. package/package.json +51 -60
  15. package/src/components/Business/AddSelectBusiness/index.md +41 -41
  16. package/src/components/Business/AddSelectBusiness/index.tsx +288 -300
  17. package/src/components/Business/CommodityEntry/index.md +69 -69
  18. package/src/components/Business/CommodityEntry/index.tsx +78 -78
  19. package/src/components/Business/SearchSelect/BusinessUtils.ts +1445 -1445
  20. package/src/components/Business/SearchSelect/common.ts +53 -53
  21. package/src/components/Business/SearchSelect/index.md +1137 -1136
  22. package/src/components/Business/SearchSelect/index.tsx +44 -49
  23. package/src/components/Business/SearchSelect/utils.ts +99 -99
  24. package/src/components/Business/TreeSearchSelect/index.md +126 -126
  25. package/src/components/Business/TreeSearchSelect/index.tsx +34 -34
  26. package/src/components/Business/TreeSearchSelect/utils.ts +60 -60
  27. package/src/components/Functional/AddSelect/index.less +367 -352
  28. package/src/components/Functional/AddSelect/index.md +120 -120
  29. package/src/components/Functional/AddSelect/index.tsx +952 -896
  30. package/src/components/Functional/BillEntry/index.less +371 -371
  31. package/src/components/Functional/BillEntry/index.md +37 -37
  32. package/src/components/Functional/BillEntry/index.tsx +547 -561
  33. package/src/components/Functional/DataImport/index.less +63 -63
  34. package/src/components/Functional/DataImport/index.md +44 -44
  35. package/src/components/Functional/DataImport/index.tsx +689 -689
  36. package/src/components/Functional/DataValidation/index.less +63 -63
  37. package/src/components/Functional/DataValidation/index.md +38 -38
  38. package/src/components/Functional/DataValidation/index.tsx +680 -680
  39. package/src/components/Functional/QueryMutipleInput/index.less +37 -37
  40. package/src/components/Functional/QueryMutipleInput/index.md +33 -33
  41. package/src/components/Functional/QueryMutipleInput/index.tsx +128 -128
  42. package/src/components/Functional/SearchSelect/index.less +115 -115
  43. package/src/components/Functional/SearchSelect/index.md +141 -141
  44. package/src/components/Functional/SearchSelect/index.tsx +732 -791
  45. package/src/components/Functional/TreeSearchSelect/index.md +47 -47
  46. package/src/components/Functional/TreeSearchSelect/index.tsx +149 -149
  47. package/src/index.ts +22 -22
  48. package/src/utils/CheckOneUser/index.md +39 -39
  49. package/src/utils/CheckOneUser/index.ts +51 -51
  50. package/src/utils/requestUtils.ts +32 -32
  51. package/tsconfig.json +29 -29
  52. package/typings.d.ts +2 -2
  53. package/Dockerfile +0 -11
  54. package/dist/app.d.ts +0 -0
  55. package/dist/components/sulaQueryTable/BsSulaQueryTable.d.ts +0 -2
  56. package/dist/components/sulaQueryTable/draggableTable.d.ts +0 -22
  57. package/dist/components/sulaQueryTable/statusComponent.d.ts +0 -2
  58. package/dist/components/sulaQueryTable/utils.d.ts +0 -41
  59. package/nginx.conf +0 -43
  60. package/src/app.tsx +0 -3
  61. package/src/components/sulaQueryTable/BsSulaQueryTable.tsx +0 -368
  62. package/src/components/sulaQueryTable/draggableTable.tsx +0 -111
  63. package/src/components/sulaQueryTable/index.md +0 -271
  64. package/src/components/sulaQueryTable/status-component.less +0 -8
  65. package/src/components/sulaQueryTable/statusComponent.tsx +0 -42
  66. package/src/components/sulaQueryTable/utils.less +0 -48
  67. package/src/components/sulaQueryTable/utils.tsx +0 -336
  68. package/src/global.less +0 -97
@@ -1,562 +1,548 @@
1
- // @ts-nocheck
2
- import { Button, message, Input, InputNumber, Tooltip, Table, Popover, Select } from 'antd';
3
- import React, { useState, useRef, useEffect } from 'react';
4
- import { SearchOutlined, CopyOutlined, CloseCircleOutlined } from '@ant-design/icons';
5
- import { stringify } from 'querystring';
6
- import './index.less';
7
- import axios from 'axios';
8
-
9
- const InputElement = ({
10
- record, text, currentIndex, inputLength, index, setData, data, item, callSelectItem
11
- }: {
12
- record: any, text: string, currentIndex: any, inputLength: any, index: any, setData: any, data: any, item: any, callSelectItem: any
13
- }) => {
14
- const [hoverVisibled, updateHoverVisibled] = useState(false);
15
- const [searchData, updateSearchData] = useState([]);
16
- const tableRef = useRef(null);
17
- const [value, setValue] = useState(text)
18
- const inputRef = useRef(false);
19
-
20
- const onSerchdata = (name: any) => {
21
- axios
22
- .get(`/items/sku/pager/v2?${stringify({ 'skuCodeAndSkuName': name, 'pageSize': 100 })}`)
23
- .then(({ data, status }: any) => {
24
- if (status === 200) {
25
- if (data.status === '0') {
26
- updateSearchData(data.data.items.map((item: any, index: any) => ({
27
- ...item,
28
- index
29
- })))
30
- } else {
31
- updateSearchData([])
32
- }
33
- }
34
- })
35
- }
36
-
37
- const onCallback = (itemData: any) => {
38
- updateHoverVisibled(false)
39
- if (itemData) {
40
- callSelectItem({ ...itemData, needFocus: true })
41
- setValue(itemData[item.dataIndex])
42
- } else {
43
- callSelectItem(null)
44
- }
45
- }
46
-
47
- const SearchDataTable = (hoverVisibled: any) => {
48
- const [selectIndex, setSelectIndex] = useState(0);
49
- const inputRef = useRef(null);
50
-
51
- useEffect(() => {
52
- if (searchData.length && hoverVisibled) {
53
- let dom = tableRef?.current?.getElementsByTagName('tbody')[0].getElementsByTagName('tr')[0]
54
- if (dom) {
55
- dom.style.background = '#005CFF30'
56
- }
57
- }
58
- }, [hoverVisibled, tableRef?.current])
59
-
60
- useEffect(() => {
61
- const inter = setInterval(() => {
62
- if (inputRef.current) {
63
- inputRef.current.focus()
64
- }
65
- }, 500)
66
-
67
- return () => {
68
- clearInterval(inter);
69
- }
70
- })
71
-
72
- if (!hoverVisibled) return <></>
73
-
74
- return <div className={'add_select_wrapper_select'} style={{ width: '800px', height: '400px', overflow: 'auto', position: 'relative' }}>
75
- <Input placeholder='请输入skucode或者sku名称' ref={inputRef} style={{ position: 'absolute', zIndex: '-100', height: '22px' }} onKeyDown={(e) => {
76
- let currentIndex = selectIndex
77
- if (e.keyCode === 27) {
78
- e.stopPropagation();
79
- e.preventDefault();
80
- setSelectIndex(0);
81
- onCallback(null)
82
- }
83
- if (e.keyCode === 13) { // enter
84
- onCallback(searchData[currentIndex])
85
- setSelectIndex(0);
86
- }
87
-
88
- if (e.keyCode === 40) { // 向下
89
- let dom = tableRef.current.getElementsByTagName('tbody')[0].getElementsByTagName('tr')[currentIndex + 1]
90
- if (dom) {
91
- tableRef.current.getElementsByTagName('tbody')[0].getElementsByTagName('tr')[currentIndex].style.background = ''
92
- setSelectIndex(currentIndex + 1)
93
- dom.style.background = '#005CFF30'
94
- dom.scrollIntoViewIfNeeded(false)
95
- }
96
- } else if (e.keyCode === 38) {
97
- let dom = tableRef.current.getElementsByTagName('tbody')[0].getElementsByTagName('tr')[currentIndex - 1]
98
- if (dom) {
99
- tableRef.current.getElementsByTagName('tbody')[0].getElementsByTagName('tr')[currentIndex].style.background = ''
100
- setSelectIndex(currentIndex - 1)
101
- dom.style.background = '#005CFF30'
102
- dom.scrollIntoViewIfNeeded(false)
103
- }
104
- }
105
- }} />
106
- <Table
107
- ref={tableRef}
108
- pagination={false}
109
- // components={
110
- // {
111
- // body: {
112
- // cell: ({index, record, ...props}) => {
113
- // debugger
114
- // return <td {...props} style={selectIndex === record?.index ? {background: '#005CFF30'} : {} } />
115
- // }
116
- // }
117
- // }
118
- // }
119
- onRow={(record, index) => {
120
- return {
121
- onClick: ((record, index, event) => {
122
- let dom = tableRef.current.getElementsByTagName('tbody')[0].getElementsByTagName('tr')[index]
123
- if (dom) {
124
- [...(tableRef.current.getElementsByTagName('tbody')[0].getElementsByTagName('tr'))].map(item => {
125
- item.style.background = ''
126
- })
127
- dom.style.background = '#005CFF30'
128
- dom.scrollIntoViewIfNeeded(false)
129
- }
130
- setSelectIndex(index)
131
- }).bind(this, record, index), // 点击行
132
- }
133
- }}
134
- rowClassName={'row-class'}
135
- columns={[{
136
- title: 'SKU编码',
137
- width: 150,
138
- dataIndex: 'skuCode',
139
- },
140
- {
141
- title: 'SKU名称',
142
- width: 200,
143
- ellipsis: {
144
- showTitle: false,
145
- },
146
- render: (text: any) => (
147
- <Tooltip placement="topLeft" title={text}>
148
- {text}
149
- </Tooltip>
150
- ),
151
- dataIndex: 'name',
152
- },
153
- {
154
- title: '国际条码',
155
- width: 100,
156
- ellipsis: {
157
- showTitle: false,
158
- },
159
- dataIndex: 'barCode',
160
- render: (text: any) => (
161
- <Tooltip placement="topLeft" title={text}>
162
- {text}
163
- </Tooltip>
164
- ),
165
- },
166
- {
167
- title: '所属SPU名称',
168
- width: 100,
169
- ellipsis: {
170
- showTitle: false,
171
- },
172
- dataIndex: 'itemName',
173
- render: (text: any) => (
174
- <Tooltip placement="topLeft" title={text}>
175
- {text}
176
- </Tooltip>
177
- ),
178
- },
179
- {
180
- title: '所属SPU编码',
181
- width: 100,
182
- ellipsis: {
183
- showTitle: false,
184
- },
185
- dataIndex: 'itemCode',
186
- render: (text: any) => (
187
- <Tooltip placement="topLeft" title={text}>
188
- {text}
189
- </Tooltip>
190
- ),
191
- },
192
- {
193
- title: '外部编码',
194
- width: 100,
195
- ellipsis: {
196
- showTitle: false,
197
- },
198
- render: (text: any) => (
199
- <Tooltip placement="topLeft" title={text}>
200
- {text}
201
- </Tooltip>
202
- ),
203
- dataIndex: 'externalCode',
204
- }]} dataSource={searchData} />
205
- </div>
206
- }
207
-
208
-
209
- return (
210
- <Popover placement="bottomLeft" destroyTooltipOnHide={{ keepParent: false }} title="" trigger="" content={SearchDataTable(hoverVisibled)} visible={hoverVisibled} onVisibleChange={(disabled) => { updateHoverVisibled(disabled) }}>
211
- {item.isPrimaryInput ?
212
- <Input
213
- value={value}
214
- ref={inputRef}
215
- placeholder='skucode / sku名称'
216
- keyboard={false}
217
- autoFocus={record.autoFocus}
218
- onChange={(value) => {
219
- record[item.dataIndex] = value.currentTarget.value
220
- setValue(value.currentTarget.value)
221
- // setData(data);
222
- }}
223
- // onFocus={(e)=> {
224
- // let dom1 = e.currentTarget;
225
- // dom1.setSelectionRange(100, 0);
226
- // dom1.select(text);
227
- // }}
228
- onKeyDown={(e) => {
229
- // if (e.keyCode === 13 && e.ctrlKey) {
230
- // handleOk(true)
231
- // document.getElementById("first-query")?.focus()
232
- // }
233
- if (e.keyCode === 8 && e.ctrlKey && index) {
234
- message.success('删除当前行')
235
- e.stopPropagation();
236
- e.preventDefault();
237
- let dom = e.nativeEvent.path[3].children[index]?.getElementsByTagName('input')[currentIndex]
238
- if (dom) {
239
- dom.select();
240
- dom.focus();
241
- dom.scrollIntoViewIfNeeded(false)
242
- }
243
- dom = null
244
- setData(data.filter((item, innerIndex) => innerIndex !== index))
245
- }
246
- if (e.keyCode === 13) { // enter
247
- if (item.isPrimaryInput) {
248
- if (e.currentTarget.value.length < 2) {
249
- message.warning('至少输入两个字符');
250
- } else {
251
- updateHoverVisibled(true)
252
- onSerchdata(e.currentTarget.value)
253
- }
254
- }
255
- }
256
- if (e.keyCode === 37 && e.shiftKey) { // 左滑动
257
- e.stopPropagation();
258
- e.preventDefault();
259
- let dom = e.nativeEvent.path[3].children[index + 1]?.getElementsByTagName('input')[currentIndex - 1]
260
- if (dom) {
261
- dom.select();
262
- dom.focus();
263
- dom.scrollIntoViewIfNeeded(false)
264
- }
265
- dom = null
266
- }
267
- if (e.keyCode === 39 && e.shiftKey) { // 右滑
268
- e.stopPropagation();
269
- e.preventDefault();
270
- let dom = e.nativeEvent.path[3].children[index + 1]?.getElementsByTagName('input')[currentIndex + 1]
271
- if (dom) {
272
- dom.select();
273
- dom.focus();
274
- dom.scrollIntoViewIfNeeded(false)
275
- }
276
- dom = null
277
- }
278
- if (e.keyCode === 40) { // 向下
279
- debugger
280
- e.stopPropagation();
281
- e.preventDefault();
282
- let dom = e.nativeEvent.path[3].children[index + 2]?.getElementsByTagName('input')[currentIndex]
283
- if (dom) {
284
- dom.select();
285
- dom.focus();
286
- dom.scrollIntoViewIfNeeded(false)
287
- }
288
- dom = null
289
- } else if (e.keyCode === 38) {
290
- e.stopPropagation();
291
- e.preventDefault();
292
- let dom1 = e.nativeEvent.path[3].children[index]?.getElementsByTagName('input')[currentIndex]
293
- if (dom1) {
294
- // dom1.value=""
295
- // dom1.setSelectionRange(100, 0);
296
- dom1.select();
297
- dom1.focus();
298
- dom1.scrollIntoViewIfNeeded(false)
299
- // dom1.value=record['count']
300
- }
301
- dom1 = null
302
- } else if (e.keyCode === 9 && currentIndex === inputLength - 1 && index === data.length - 1) {
303
- setData([...data, {}])
304
- }
305
- }}
306
- />
307
- :
308
- <InputNumber
309
- // onBlur={() => {updateHoverVisibled(false)}}
310
- defaultValue={text || 0}
311
- min={0}
312
- keyboard={false}
313
- onChange={(value) => {
314
- record[item.dataIndex] = value
315
- }}
316
- onKeyDown={(e) => {
317
- // if (e.keyCode === 13 && e.ctrlKey) {
318
- // handleOk(true)
319
- // document.getElementById("first-query")?.focus()
320
- // }
321
- if (e.keyCode === 8 && e.ctrlKey && index) {
322
- message.success('删除当前行')
323
- e.stopPropagation();
324
- e.preventDefault();
325
- let dom = e.nativeEvent.path[5].children[index]?.getElementsByTagName('input')[currentIndex]
326
- if (dom) {
327
- dom.select();
328
- dom.focus();
329
- dom.scrollIntoViewIfNeeded(false)
330
- }
331
- dom = null
332
- setData(data.filter((item, innerIndex) => innerIndex !== index))
333
- }
334
- if (e.keyCode === 37 && e.shiftKey) { // 左滑动
335
- e.stopPropagation();
336
- e.preventDefault();
337
- let dom = e.nativeEvent.path[5].children[index + 1]?.getElementsByTagName('input')[currentIndex - 1]
338
- if (dom) {
339
- dom.select();
340
- dom.focus();
341
- dom.scrollIntoViewIfNeeded(false)
342
- }
343
- dom = null
344
- }
345
- if (e.keyCode === 39 && e.shiftKey) { // 右滑
346
- e.stopPropagation();
347
- e.preventDefault();
348
- let dom = e.nativeEvent.path[5].children[index + 1]?.getElementsByTagName('input')[currentIndex + 1]
349
- if (dom) {
350
- dom.select();
351
- dom.focus();
352
- dom.scrollIntoViewIfNeeded(false)
353
- }
354
- dom = null
355
- }
356
- if (e.keyCode === 40) { // 向下
357
- e.stopPropagation();
358
- e.preventDefault();
359
- let dom = e.nativeEvent.path[5].children[index + 2]?.getElementsByTagName('input')[currentIndex]
360
- if (dom) {
361
- dom.select();
362
- dom.focus();
363
- dom.scrollIntoViewIfNeeded(false)
364
- }
365
- dom = null
366
- } else if (e.keyCode === 38) {
367
- e.stopPropagation();
368
- e.preventDefault();
369
- let dom1 = e.nativeEvent.path[5].children[index]?.getElementsByTagName('input')[currentIndex]
370
- if (dom1) {
371
- // dom1.value=""
372
- // dom1.setSelectionRange(100, 0);
373
- dom1.select();
374
- dom1.focus();
375
- dom1.scrollIntoViewIfNeeded(false)
376
- // dom1.value=record['count']
377
- }
378
- dom1 = null
379
- } else if (e.keyCode === 9 && currentIndex === inputLength - 1 && index === data.length - 1) {
380
- e.stopPropagation();
381
- e.preventDefault();
382
- } else if (e.keyCode === 13 && currentIndex === inputLength - 1 && index === data.length - 1 && record['skuCode']) {
383
- setData([...data, { autoFocus: true }])
384
- }
385
- }}
386
- />
387
- }
388
-
389
- </Popover>
390
- )
391
- }
392
-
393
- const BillEntry: React.FC = ({ onSaveCallback }) => {
394
- const columns = [
395
- {
396
- title: 'SKU编码',
397
- width: 150,
398
- dataIndex: 'skuCode',
399
- isInputItem: true,
400
- isPrimaryInput: true
401
- },
402
- {
403
- title: 'SKU名称',
404
- width: 200,
405
- ellipsis: {
406
- showTitle: false,
407
- },
408
- render: (text: any) => (
409
- <Tooltip placement="topLeft" title={text}>
410
- {text}
411
- </Tooltip>
412
- ),
413
- dataIndex: 'name',
414
- },
415
- {
416
- title: '单位',
417
- dataIndex: 'selectUnitCode',
418
- width: 100,
419
- isSelectItem: true,
420
- render: (text: any, record: any) => {
421
- let baseUnitCode = '';
422
- if (record?.packingUnitList) {
423
- let base = record.packingUnitList.filter((item: any) => item.unitCode)
424
- if (base.length) {
425
- baseUnitCode = base[0].unitCode
426
- record.selectUnitCode = base[0].unitCode
427
- record.selectedScale = base[0]?.baseUnitScale || 1
428
- }
429
- }
430
-
431
- if (baseUnitCode) {
432
- return <>
433
- <Select defaultValue={baseUnitCode} onChange={(value) => {
434
- record.selectUnitCode = value;record.selectedScale = record?.packingUnitList?.find((item: any) => item.unitCode === value)?.baseUnitScale || 1}
435
- } style={{width: '60px'}}>
436
- {record.packingUnitList && record.packingUnitList.map((item: any) => {
437
- return <Select.Option value={item.unitCode}>{item.name}</Select.Option>
438
- })}
439
- </Select>
440
- </>
441
- }
442
- return <></>
443
- },
444
- },
445
- {
446
- title: '数量',
447
- width: 100,
448
- isInputItem: true,
449
- dataIndex: 'count',
450
- },
451
- {
452
- title: '所属SPU编码',
453
- width: 100,
454
- ellipsis: {
455
- showTitle: false,
456
- },
457
- dataIndex: 'itemCode',
458
- render: (text: any) => (
459
- <Tooltip placement="topLeft" title={text}>
460
- {text}
461
- </Tooltip>
462
- ),
463
- },
464
- {
465
- title: '规格',
466
- width: 200,
467
- ellipsis: {
468
- showTitle: false,
469
- },
470
- render: (text: any) => (
471
- <Tooltip placement="topLeft" title={text}>
472
- {text}
473
- </Tooltip>
474
- ),
475
- dataIndex: 'propertyNameAndValue',
476
- }
477
- ]
478
- const [isModalVisible, setIsModalVisible] = useState(false);
479
- const [data, setData] = useState([{ hovered: false }]);
480
- const tableRef = useRef(null)
481
-
482
- const callSelectItem = (index, item) => {
483
- if (item) {
484
- let newData = [].concat(data)
485
- newData[index] = { ...data[index], ...item }
486
- setData(newData)
487
- }
488
- let dom = tableRef?.current?.getElementsByTagName('tbody')[0].getElementsByTagName('tr')[index + 1]
489
- if (dom) {
490
- setTimeout(() => {
491
- dom.getElementsByTagName('input')[item ? 1 : 0]?.select()
492
- dom.getElementsByTagName('input')[item ? 1 : 0]?.focus()
493
- }, 200)
494
- }
495
- }
496
-
497
- const deleteRecord = (record) => {
498
- setData(data.filter(item => item.skuCode !== record.skuCode))
499
- }
500
-
501
- let inputIndex = 0;
502
- let selectColumns = [...columns.map(item => {
503
- const inputLength = columns.filter(item => item.isInputItem || item.isSelectItem).length
504
- const currentIndex = inputIndex
505
- if (item.isInputItem) {
506
- inputIndex++;
507
- return {
508
- ...item,
509
- render: (text, record, index) => {
510
- return (
511
- <InputElement setData={setData} callSelectItem={callSelectItem.bind(this, index)} item={item} isPrimaryInput={item.isPrimaryInput} record={record} text={text} data={data} index={index} inputLength={inputLength} currentIndex={currentIndex} />
512
- );
513
- },
514
- }
515
- } else if (item.isSelectItem) {
516
- inputIndex++;
517
- }
518
-
519
- return item
520
- }), {
521
- title: '操作',
522
- width: 50,
523
- render: (text, record, index) => {
524
- if (index !== 0) {
525
- return (
526
- <span style={{ cursor: 'pointer', color: '#005CFF' }} onClick={() => {
527
- deleteRecord(record)
528
- }}>删除</span>
529
- )
530
- }
531
- }
532
- }]
533
-
534
-
535
- return (
536
- <div className='add_select'>
537
- <div className='add_select_quick_header'>
538
- <div className='add_select_quick_header_title'><div>快速录入</div><Button type="primary" onClick={() => {
539
- onSaveCallback(data)
540
- }}>提交</Button></div>
541
- <span><span>*</span> &nbsp;快捷键:【Tab】-跳格切换;【Shift+←、→】-当前行左、右移动;【 ↑、↓】-当前列上、下移动;【ctrl+Delete】-删除当前行;</span>
542
- </div>
543
- <div className={'add_select_wrapper_select add_select_wrapper_select_quick'}>
544
- <Table
545
- size='small'
546
- scroll={{ y: 240 }}
547
- ref={tableRef}
548
- dataSource={data}
549
- columns={selectColumns}
550
- pagination={false}
551
- rowClassName={'row-class'}
552
- rowClassName={(record: object | null | undefined, index: number) =>
553
- index % 2 === 0 ? 'table_base row-class' : 'table_odd row-class'
554
- }
555
- />
556
- </div>
557
-
558
- </div>
559
- );
560
- };
561
-
1
+ // @ts-nocheck
2
+ import { Button, message, Input, InputNumber, Tooltip, Table, Popover, Select } from 'antd';
3
+ import React, { useState, useRef, useEffect } from 'react';
4
+ import { SearchOutlined, CopyOutlined, CloseCircleOutlined } from '@ant-design/icons';
5
+ import { stringify } from 'querystring';
6
+ import './index.less';
7
+ import axios from 'axios';
8
+
9
+ const InputElement = ({
10
+ record, text, currentIndex, inputLength, index, setData, data, item, callSelectItem
11
+ }: {
12
+ record: any, text: string, currentIndex: any, inputLength: any, index: any, setData: any, data: any, item: any, callSelectItem: any
13
+ }) => {
14
+ const [hoverVisibled, updateHoverVisibled] = useState(false);
15
+ const [searchData, updateSearchData] = useState([]);
16
+ const tableRef = useRef(null);
17
+ const [value, setValue] = useState(text)
18
+ const inputRef = useRef(false);
19
+
20
+ const onSerchdata = (name: any) => {
21
+ axios
22
+ .get(`/items/sku/pager/v2?${stringify({ 'skuCodeAndSkuName': name, 'pageSize': 100 })}`)
23
+ .then(({ data, status }: any) => {
24
+ if (status === 200) {
25
+ if (data.status === '0') {
26
+ updateSearchData(data.data.items.map((item: any, index: any) => ({
27
+ ...item,
28
+ index
29
+ })))
30
+ } else {
31
+ updateSearchData([])
32
+ }
33
+ }
34
+ })
35
+ }
36
+
37
+ const onCallback = (itemData: any) => {
38
+ updateHoverVisibled(false)
39
+ if (itemData) {
40
+ callSelectItem({ ...itemData, needFocus: true })
41
+ setValue(itemData[item.dataIndex])
42
+ } else {
43
+ callSelectItem(null)
44
+ }
45
+ }
46
+
47
+ const SearchDataTable = (hoverVisibled: any) => {
48
+ const [selectIndex, setSelectIndex] = useState(0);
49
+ const inputRef = useRef(null);
50
+
51
+ useEffect(() => {
52
+ if (searchData.length && hoverVisibled) {
53
+ let dom = tableRef?.current?.getElementsByTagName('tbody')[0].getElementsByTagName('tr')[0]
54
+ if (dom) {
55
+ dom.style.background = '#005CFF30'
56
+ }
57
+ }
58
+ }, [hoverVisibled, tableRef?.current])
59
+
60
+ useEffect(() => {
61
+ const inter = setInterval(() => {
62
+ if (inputRef.current) {
63
+ inputRef.current.focus()
64
+ }
65
+ }, 500)
66
+
67
+ return () => {
68
+ clearInterval(inter);
69
+ }
70
+ })
71
+
72
+ if (!hoverVisibled) return <></>
73
+
74
+ return <div className={'add_select_wrapper_select'} style={{ width: '800px', height: '400px', overflow: 'auto', position: 'relative' }}>
75
+ <Input placeholder='请输入skucode或者sku名称' ref={inputRef} style={{ position: 'absolute', zIndex: '-100', height: '22px' }} onKeyDown={(e) => {
76
+ let currentIndex = selectIndex
77
+ if (e.keyCode === 27) {
78
+ e.stopPropagation();
79
+ e.preventDefault();
80
+ setSelectIndex(0);
81
+ onCallback(null)
82
+ }
83
+ if (e.keyCode === 13) { // enter
84
+ onCallback(searchData[currentIndex])
85
+ setSelectIndex(0);
86
+ }
87
+
88
+ if (e.keyCode === 40) { // 向下
89
+ let dom = tableRef.current.getElementsByTagName('tbody')[0].getElementsByTagName('tr')[currentIndex + 1]
90
+ if (dom) {
91
+ tableRef.current.getElementsByTagName('tbody')[0].getElementsByTagName('tr')[currentIndex].style.background = ''
92
+ setSelectIndex(currentIndex + 1)
93
+ dom.style.background = '#005CFF30'
94
+ dom.scrollIntoViewIfNeeded(false)
95
+ }
96
+ } else if (e.keyCode === 38) {
97
+ let dom = tableRef.current.getElementsByTagName('tbody')[0].getElementsByTagName('tr')[currentIndex - 1]
98
+ if (dom) {
99
+ tableRef.current.getElementsByTagName('tbody')[0].getElementsByTagName('tr')[currentIndex].style.background = ''
100
+ setSelectIndex(currentIndex - 1)
101
+ dom.style.background = '#005CFF30'
102
+ dom.scrollIntoViewIfNeeded(false)
103
+ }
104
+ }
105
+ }} />
106
+ <Table
107
+ ref={tableRef}
108
+ pagination={false}
109
+ // components={
110
+ // {
111
+ // body: {
112
+ // cell: ({index, record, ...props}) => {
113
+ // debugger
114
+ // return <td {...props} style={selectIndex === record?.index ? {background: '#005CFF30'} : {} } />
115
+ // }
116
+ // }
117
+ // }
118
+ // }
119
+ onRow={(record, index) => {
120
+ return {
121
+ onClick: ((record, index, event) => {
122
+ let dom = tableRef.current.getElementsByTagName('tbody')[0].getElementsByTagName('tr')[index]
123
+ if (dom) {
124
+ [...(tableRef.current.getElementsByTagName('tbody')[0].getElementsByTagName('tr'))].map(item => {
125
+ item.style.background = ''
126
+ })
127
+ dom.style.background = '#005CFF30'
128
+ dom.scrollIntoViewIfNeeded(false)
129
+ }
130
+ setSelectIndex(index)
131
+ }).bind(this, record, index), // 点击行
132
+ }
133
+ }}
134
+ rowClassName={'row-class'}
135
+ columns={[{
136
+ title: 'SKU编码',
137
+ width: 150,
138
+ dataIndex: 'skuCode',
139
+ },
140
+ {
141
+ title: 'SKU名称',
142
+ width: 200,
143
+ ellipsis: {
144
+ showTitle: false,
145
+ },
146
+ render: (text: any) => (
147
+ <Tooltip placement="topLeft" title={text}>
148
+ {text}
149
+ </Tooltip>
150
+ ),
151
+ dataIndex: 'name',
152
+ },
153
+ {
154
+ title: '国际条码',
155
+ width: 100,
156
+ ellipsis: {
157
+ showTitle: false,
158
+ },
159
+ dataIndex: 'barCode',
160
+ render: (text: any) => (
161
+ <Tooltip placement="topLeft" title={text}>
162
+ {text}
163
+ </Tooltip>
164
+ ),
165
+ },
166
+ {
167
+ title: '所属SPU名称',
168
+ width: 100,
169
+ ellipsis: {
170
+ showTitle: false,
171
+ },
172
+ dataIndex: 'itemName',
173
+ render: (text: any) => (
174
+ <Tooltip placement="topLeft" title={text}>
175
+ {text}
176
+ </Tooltip>
177
+ ),
178
+ },
179
+ {
180
+ title: '所属SPU编码',
181
+ width: 100,
182
+ ellipsis: {
183
+ showTitle: false,
184
+ },
185
+ dataIndex: 'itemCode',
186
+ render: (text: any) => (
187
+ <Tooltip placement="topLeft" title={text}>
188
+ {text}
189
+ </Tooltip>
190
+ ),
191
+ },
192
+ {
193
+ title: '外部编码',
194
+ width: 100,
195
+ ellipsis: {
196
+ showTitle: false,
197
+ },
198
+ render: (text: any) => (
199
+ <Tooltip placement="topLeft" title={text}>
200
+ {text}
201
+ </Tooltip>
202
+ ),
203
+ dataIndex: 'externalCode',
204
+ }]} dataSource={searchData} />
205
+ </div>
206
+ }
207
+
208
+
209
+ return (
210
+ <Popover placement="bottomLeft" destroyTooltipOnHide={{ keepParent: false }} title="" trigger="" content={SearchDataTable(hoverVisibled)} visible={hoverVisibled} onVisibleChange={(disabled) => { updateHoverVisibled(disabled) }}>
211
+ {item.isPrimaryInput ?
212
+ <Input
213
+ value={value}
214
+ ref={inputRef}
215
+ placeholder='skucode / sku名称'
216
+ keyboard={false}
217
+ autoFocus={record.autoFocus}
218
+ onChange={(value) => {
219
+ record[item.dataIndex] = value.currentTarget.value
220
+ setValue(value.currentTarget.value)
221
+ // setData(data);
222
+ }}
223
+ // onFocus={(e)=> {
224
+ // let dom1 = e.currentTarget;
225
+ // dom1.setSelectionRange(100, 0);
226
+ // dom1.select(text);
227
+ // }}
228
+ onKeyDown={(e) => {
229
+ // if (e.keyCode === 13 && e.ctrlKey) {
230
+ // handleOk(true)
231
+ // document.getElementById("first-query")?.focus()
232
+ // }
233
+ if (e.keyCode === 8 && e.ctrlKey && index) {
234
+ message.success('删除当前行')
235
+ e.stopPropagation();
236
+ e.preventDefault();
237
+ let dom = e.nativeEvent.path[3].children[index]?.getElementsByTagName('input')[currentIndex]
238
+ if (dom) {
239
+ dom.select();
240
+ dom.focus();
241
+ dom.scrollIntoViewIfNeeded(false)
242
+ }
243
+ dom = null
244
+ setData(data.filter((item, innerIndex) => innerIndex !== index))
245
+ }
246
+ if (e.keyCode === 13) { // enter
247
+ if (item.isPrimaryInput) {
248
+ if (e.currentTarget.value.length < 2) {
249
+ message.warning('至少输入两个字符');
250
+ } else {
251
+ updateHoverVisibled(true)
252
+ onSerchdata(e.currentTarget.value)
253
+ }
254
+ }
255
+ }
256
+ if (e.keyCode === 37 && e.shiftKey) { // 左滑动
257
+ e.stopPropagation();
258
+ e.preventDefault();
259
+ let dom = e.nativeEvent.path[3].children[index + 1]?.getElementsByTagName('input')[currentIndex - 1]
260
+ if (dom) {
261
+ dom.select();
262
+ dom.focus();
263
+ dom.scrollIntoViewIfNeeded(false)
264
+ }
265
+ dom = null
266
+ }
267
+ if (e.keyCode === 39 && e.shiftKey) { // 右滑
268
+ e.stopPropagation();
269
+ e.preventDefault();
270
+ let dom = e.nativeEvent.path[3].children[index + 1]?.getElementsByTagName('input')[currentIndex + 1]
271
+ if (dom) {
272
+ dom.select();
273
+ dom.focus();
274
+ dom.scrollIntoViewIfNeeded(false)
275
+ }
276
+ dom = null
277
+ }
278
+ if (e.keyCode === 40) { // 向下
279
+ debugger
280
+ e.stopPropagation();
281
+ e.preventDefault();
282
+ let dom = e.nativeEvent.path[3].children[index + 2]?.getElementsByTagName('input')[currentIndex]
283
+ if (dom) {
284
+ dom.select();
285
+ dom.focus();
286
+ dom.scrollIntoViewIfNeeded(false)
287
+ }
288
+ dom = null
289
+ } else if (e.keyCode === 38) {
290
+ e.stopPropagation();
291
+ e.preventDefault();
292
+ let dom1 = e.nativeEvent.path[3].children[index]?.getElementsByTagName('input')[currentIndex]
293
+ if (dom1) {
294
+ // dom1.value=""
295
+ // dom1.setSelectionRange(100, 0);
296
+ dom1.select();
297
+ dom1.focus();
298
+ dom1.scrollIntoViewIfNeeded(false)
299
+ // dom1.value=record['count']
300
+ }
301
+ dom1 = null
302
+ } else if (e.keyCode === 9 && currentIndex === inputLength - 1 && index === data.length - 1) {
303
+ setData([...data, {}])
304
+ }
305
+ }}
306
+ />
307
+ :
308
+ <InputNumber
309
+ // onBlur={() => {updateHoverVisibled(false)}}
310
+ defaultValue={text || ''}
311
+ min={0}
312
+ keyboard={false}
313
+ onChange={(value) => {
314
+ record[item.dataIndex] = value
315
+ }}
316
+ onKeyDown={(e) => {
317
+ // if (e.keyCode === 13 && e.ctrlKey) {
318
+ // handleOk(true)
319
+ // document.getElementById("first-query")?.focus()
320
+ // }
321
+ if (e.keyCode === 8 && e.ctrlKey && index) {
322
+ message.success('删除当前行')
323
+ e.stopPropagation();
324
+ e.preventDefault();
325
+ let dom = e.nativeEvent.path[5].children[index]?.getElementsByTagName('input')[currentIndex]
326
+ if (dom) {
327
+ dom.select();
328
+ dom.focus();
329
+ dom.scrollIntoViewIfNeeded(false)
330
+ }
331
+ dom = null
332
+ setData(data.filter((item, innerIndex) => innerIndex !== index))
333
+ }
334
+ if (e.keyCode === 37 && e.shiftKey) { // 左滑动
335
+ e.stopPropagation();
336
+ e.preventDefault();
337
+ let dom = e.nativeEvent.path[5].children[index + 1]?.getElementsByTagName('input')[currentIndex - 1]
338
+ if (dom) {
339
+ dom.select();
340
+ dom.focus();
341
+ dom.scrollIntoViewIfNeeded(false)
342
+ }
343
+ dom = null
344
+ }
345
+ if (e.keyCode === 39 && e.shiftKey) { // 右滑
346
+ e.stopPropagation();
347
+ e.preventDefault();
348
+ let dom = e.nativeEvent.path[5].children[index + 1]?.getElementsByTagName('input')[currentIndex + 1]
349
+ if (dom) {
350
+ dom.select();
351
+ dom.focus();
352
+ dom.scrollIntoViewIfNeeded(false)
353
+ }
354
+ dom = null
355
+ }
356
+ if (e.keyCode === 40) { // 向下
357
+ e.stopPropagation();
358
+ e.preventDefault();
359
+ let dom = e.nativeEvent.path[5].children[index + 2]?.getElementsByTagName('input')[currentIndex]
360
+ if (dom) {
361
+ dom.select();
362
+ dom.focus();
363
+ dom.scrollIntoViewIfNeeded(false)
364
+ }
365
+ dom = null
366
+ } else if (e.keyCode === 38) {
367
+ e.stopPropagation();
368
+ e.preventDefault();
369
+ let dom1 = e.nativeEvent.path[5].children[index]?.getElementsByTagName('input')[currentIndex]
370
+ if (dom1) {
371
+ // dom1.value=""
372
+ // dom1.setSelectionRange(100, 0);
373
+ dom1.select();
374
+ dom1.focus();
375
+ dom1.scrollIntoViewIfNeeded(false)
376
+ // dom1.value=record['count']
377
+ }
378
+ dom1 = null
379
+ } else if (e.keyCode === 9 && currentIndex === inputLength - 1 && index === data.length - 1) {
380
+ e.stopPropagation();
381
+ e.preventDefault();
382
+ } else if (e.keyCode === 13 && currentIndex === inputLength - 1 && index === data.length - 1 && record['skuCode']) {
383
+ setData([...data, { autoFocus: true }])
384
+ }
385
+ }}
386
+ />
387
+ }
388
+
389
+ </Popover>
390
+ )
391
+ }
392
+
393
+ const BillEntry: React.FC = ({ onSaveCallback }) => {
394
+ const columns = [
395
+ {
396
+ title: 'SKU编码',
397
+ width: 150,
398
+ dataIndex: 'skuCode',
399
+ isInputItem: true,
400
+ isPrimaryInput: true
401
+ },
402
+ {
403
+ title: 'SKU名称',
404
+ width: 200,
405
+ ellipsis: {
406
+ showTitle: false,
407
+ },
408
+ render: (text: any) => (
409
+ <Tooltip placement="topLeft" title={text}>
410
+ {text}
411
+ </Tooltip>
412
+ ),
413
+ dataIndex: 'name',
414
+ },
415
+ {
416
+ title: '单位',
417
+ dataIndex: 'selectUnitCode',
418
+ width: 100,
419
+ isSelectItem: true,
420
+ render: (text: any, record: any) => {
421
+ if (record?.packingUnitList?.length) {
422
+ const basePackUnit = record?.packingUnitList[0]
423
+ record.selectUnitCode = basePackUnit.unitCode
424
+ return basePackUnit.name || basePackUnit.unitCode
425
+ }
426
+
427
+
428
+ return <></>
429
+ },
430
+ },
431
+ {
432
+ title: '数量',
433
+ width: 100,
434
+ isInputItem: true,
435
+ dataIndex: 'count',
436
+ },
437
+ {
438
+ title: '所属SPU编码',
439
+ width: 100,
440
+ ellipsis: {
441
+ showTitle: false,
442
+ },
443
+ dataIndex: 'itemCode',
444
+ render: (text: any) => (
445
+ <Tooltip placement="topLeft" title={text}>
446
+ {text}
447
+ </Tooltip>
448
+ ),
449
+ },
450
+ {
451
+ title: '规格',
452
+ width: 200,
453
+ ellipsis: {
454
+ showTitle: false,
455
+ },
456
+ render: (text: any) => (
457
+ <Tooltip placement="topLeft" title={text}>
458
+ {text}
459
+ </Tooltip>
460
+ ),
461
+ dataIndex: 'propertyNameAndValue',
462
+ }
463
+ ]
464
+ const [isModalVisible, setIsModalVisible] = useState(false);
465
+ const [data, setData] = useState([{ hovered: false }]);
466
+ const tableRef = useRef(null)
467
+
468
+ const callSelectItem = (index, item) => {
469
+ if (item) {
470
+ let newData = [].concat(data)
471
+ newData[index] = { ...data[index], ...item }
472
+ setData(newData)
473
+ }
474
+ let dom = tableRef?.current?.getElementsByTagName('tbody')[0].getElementsByTagName('tr')[index + 1]
475
+ if (dom) {
476
+ setTimeout(() => {
477
+ dom.getElementsByTagName('input')[item ? 1 : 0]?.select()
478
+ dom.getElementsByTagName('input')[item ? 1 : 0]?.focus()
479
+ }, 200)
480
+ }
481
+ }
482
+
483
+ const deleteRecord = (record) => {
484
+ setData(data.filter(item => item.skuCode !== record.skuCode))
485
+ }
486
+
487
+ let inputIndex = 0;
488
+ let selectColumns = [...columns.map(item => {
489
+ const inputLength = columns.filter(item => item.isInputItem || item.isSelectItem).length
490
+ const currentIndex = inputIndex
491
+ if (item.isInputItem) {
492
+ inputIndex++;
493
+ return {
494
+ ...item,
495
+ render: (text, record, index) => {
496
+ return (
497
+ <InputElement setData={setData} callSelectItem={callSelectItem.bind(this, index)} item={item} isPrimaryInput={item.isPrimaryInput} record={record} text={text} data={data} index={index} inputLength={inputLength} currentIndex={currentIndex} />
498
+ );
499
+ },
500
+ }
501
+ } else if (item.isSelectItem) {
502
+ inputIndex++;
503
+ }
504
+
505
+ return item
506
+ }), {
507
+ title: '操作',
508
+ width: 50,
509
+ render: (text, record, index) => {
510
+ if (index !== 0) {
511
+ return (
512
+ <span style={{ cursor: 'pointer', color: '#005CFF' }} onClick={() => {
513
+ deleteRecord(record)
514
+ }}>删除</span>
515
+ )
516
+ }
517
+ }
518
+ }]
519
+
520
+
521
+ return (
522
+ <div className='add_select'>
523
+ <div className='add_select_quick_header'>
524
+ <div className='add_select_quick_header_title'><div>快速录入</div><Button type="primary" onClick={() => {
525
+ onSaveCallback(data)
526
+ }}>提交</Button></div>
527
+ <span><span>*</span> &nbsp;快捷键:【Tab】-跳格切换;【Shift+←、→】-当前行左、右移动;【 ↑、↓】-当前列上、下移动;【ctrl+Delete】-删除当前行;</span>
528
+ </div>
529
+ <div className={'add_select_wrapper_select add_select_wrapper_select_quick'}>
530
+ <Table
531
+ size='small'
532
+ scroll={{ y: 240 }}
533
+ ref={tableRef}
534
+ dataSource={data}
535
+ columns={selectColumns}
536
+ pagination={false}
537
+ rowClassName={'row-class'}
538
+ rowClassName={(record: object | null | undefined, index: number) =>
539
+ index % 2 === 0 ? 'table_base row-class' : 'table_odd row-class'
540
+ }
541
+ />
542
+ </div>
543
+
544
+ </div>
545
+ );
546
+ };
547
+
562
548
  export default BillEntry;