kts-component-invoice-operate 3.2.29 → 3.2.31
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.
- package/dist/Invoice/InvoiceController/InvoiceControllerState/AutoComplete/index.d.ts +1 -1
- package/dist/Invoice/ui/default/GoodsList/hook/useColumns/ui/ItemCodeInput/index.d.ts +1 -1
- package/dist/Invoice/ui/default/GoodsList/ui/TableRow/index.d.ts +1 -0
- package/dist/Invoice/ui/digtal/GoodsList/hook/useColumns/ui/Drag/index.d.ts +7 -0
- package/dist/Invoice/ui/digtal/GoodsList/ui/TableRow/index.d.ts +1 -0
- package/dist/index.esm.js +4604 -3793
- package/dist/index.js +4604 -3793
- package/package.json +1 -1
- package/src/Invoice/InvoiceController/InvoiceControllerState/AutoComplete/index.ts +1 -1
- package/src/Invoice/_test/endowCode/index.tsx +1 -1
- package/src/Invoice/ui/default/GoodsList/hook/useColumns/index.tsx +12 -11
- package/src/Invoice/ui/default/GoodsList/hook/useColumns/ui/Drag/index.less +18 -0
- package/src/Invoice/ui/default/GoodsList/hook/useColumns/ui/Drag/index.tsx +143 -4
- package/src/Invoice/ui/default/GoodsList/hook/useColumns/ui/ItemCodeInput/index.tsx +15 -5
- package/src/Invoice/ui/default/GoodsList/hook/useColumns/ui/ItemNameInput/index.tsx +1 -1
- package/src/Invoice/ui/default/GoodsList/ui/TableRow/index.less +14 -0
- package/src/Invoice/ui/default/GoodsList/ui/TableRow/index.tsx +22 -3
- package/src/Invoice/ui/digtal/GoodsList/hook/useColumns/index.tsx +8 -0
- package/src/Invoice/ui/digtal/GoodsList/hook/useColumns/ui/Drag/index.less +21 -0
- package/src/Invoice/ui/digtal/GoodsList/hook/useColumns/ui/Drag/index.tsx +187 -0
- package/src/Invoice/ui/digtal/GoodsList/hook/useColumns/ui/Drag/svg/I001.svg +1 -0
- package/src/Invoice/ui/digtal/GoodsList/ui/TableRow/index.less +14 -0
- package/src/Invoice/ui/digtal/GoodsList/ui/TableRow/index.tsx +18 -5
package/package.json
CHANGED
|
@@ -53,7 +53,7 @@ export default () => {
|
|
|
53
53
|
<Switch checkedChildren="预制" unCheckedChildren="默认" onChange={e => { e ? setController(controller2) : setController(controller1) }} ></Switch>
|
|
54
54
|
<Button onClick={controller.pipeline(async s => { s.goodsListState.endowCode.getReadOnlyTaxRate = s.goodsListState.endowCode.readOnlyTaxRateMap.DRAFT })} >税率(草稿)</Button>
|
|
55
55
|
<Button onClick={controller.pipeline(async s => { s.goodsListState.endowCode.getReadOnlyTaxRate = () => true })} >税率(预制)</Button>
|
|
56
|
-
<Invoice controller={controller} />
|
|
56
|
+
<Invoice invoiceType='digtal' controller={controller} />
|
|
57
57
|
</div>
|
|
58
58
|
);
|
|
59
59
|
};
|
|
@@ -80,13 +80,13 @@ export default (form: WrappedFormUtils) => {
|
|
|
80
80
|
/** 表头 */
|
|
81
81
|
const columns = React.useMemo(() => {
|
|
82
82
|
return [
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
83
|
+
{
|
|
84
|
+
title: ' ',
|
|
85
|
+
key: 'drag',
|
|
86
|
+
width: 40,
|
|
87
|
+
align: 'center',
|
|
88
|
+
render: (_: any, record: IGood) => <Drag record={record} />
|
|
89
|
+
},
|
|
90
90
|
{
|
|
91
91
|
title: '序号',
|
|
92
92
|
key: 'serialNo',
|
|
@@ -106,9 +106,10 @@ export default (form: WrappedFormUtils) => {
|
|
|
106
106
|
initialValue: editGood.itemCode,
|
|
107
107
|
})(
|
|
108
108
|
<ItemCodeInput
|
|
109
|
-
|
|
110
|
-
onChange={() => {
|
|
111
|
-
onChangeItemCode(controller, form, record);
|
|
109
|
+
record={record}
|
|
110
|
+
onChange={async () => {
|
|
111
|
+
await onChangeItemCode(controller, form, record);
|
|
112
|
+
await onChangeLineAmountIncludeTax(controller, form, record);
|
|
112
113
|
}}
|
|
113
114
|
/>
|
|
114
115
|
)}
|
|
@@ -128,7 +129,7 @@ export default (form: WrappedFormUtils) => {
|
|
|
128
129
|
<Form.Item>
|
|
129
130
|
<div style={{ display: 'flex' }} >
|
|
130
131
|
{getFieldDecorator('itemName', {
|
|
131
|
-
initialValue:
|
|
132
|
+
initialValue: record.itemName,
|
|
132
133
|
rules: [
|
|
133
134
|
...getReplenishRules('itemName'),
|
|
134
135
|
{
|
|
@@ -1,3 +1,21 @@
|
|
|
1
1
|
.kts-invoice-operate-goods-list-itemName-drag {
|
|
2
2
|
cursor: all-scroll;
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.kts-invoice-operate-goods-list-itemName-drag-div {
|
|
8
|
+
z-index : 999;
|
|
9
|
+
border : 1px solid #E6E6E6;
|
|
10
|
+
width : 400px;
|
|
11
|
+
height : 32px;
|
|
12
|
+
display : flex;
|
|
13
|
+
gap : 10px;
|
|
14
|
+
align-items : center;
|
|
15
|
+
position : fixed;
|
|
16
|
+
padding : 0 20px;
|
|
17
|
+
top : 100px;
|
|
18
|
+
background : #fff;
|
|
19
|
+
pointer-events: none;
|
|
20
|
+
opacity : 0.4;
|
|
3
21
|
}
|
|
@@ -4,9 +4,10 @@ import Icon from '@ant-design/icons';
|
|
|
4
4
|
import { ReactComponent as I001Svg } from './svg/I001.svg';
|
|
5
5
|
import { Button } from "kts-components-antd-x3";
|
|
6
6
|
import { IGood, Invoice } from '../../../../../../../..';
|
|
7
|
+
import mounting from "../../../../../../../tools/mounting";
|
|
8
|
+
import { LineAttributeType } from "../../../../../../../InvoiceController";
|
|
7
9
|
import './index.less';
|
|
8
10
|
|
|
9
|
-
|
|
10
11
|
export interface IDragProps {
|
|
11
12
|
record: IGood
|
|
12
13
|
}
|
|
@@ -19,18 +20,121 @@ export default function Drag(props: IDragProps) {
|
|
|
19
20
|
|
|
20
21
|
const editGood = controller.useMemo(s => s.goodsListState.editGood, []);
|
|
21
22
|
|
|
22
|
-
const current = controller.useMemo(s => s.goodsListState.drag.current, []);
|
|
23
|
-
|
|
24
23
|
const disabled = React.useMemo(() => !!editGood, [editGood]);
|
|
25
24
|
|
|
26
25
|
const onMouseDown = React.useCallback(() => {
|
|
27
26
|
if (!controller || !record) return;
|
|
28
27
|
controller.run(async s => s.goodsListState.drag.current = record.$index);
|
|
29
|
-
window.addEventListener('mouseup', onMouseup);
|
|
30
28
|
|
|
29
|
+
const rowList = window.document.querySelectorAll<HTMLDivElement>('.kts-invoice-operate-goods-list');
|
|
30
|
+
|
|
31
|
+
const currentGood = controller.state.goodsListState.goodsList.filter(e => e.$index === record.$index)[0];
|
|
32
|
+
mounting(<DragDiv {...currentGood} />)
|
|
33
|
+
|
|
34
|
+
// 监听移动
|
|
35
|
+
rowList.forEach(e => { e.addEventListener('mouseover', onMouseover) });
|
|
36
|
+
function onMouseover(e: MouseEvent) {
|
|
37
|
+
controller.run(async s => {
|
|
38
|
+
const container = s.goodsListState.drag.container = getRow(e.target)?.dataset?.rowKey;
|
|
39
|
+
if (!container) return;
|
|
40
|
+
|
|
41
|
+
// 不可以插入自己
|
|
42
|
+
if (container === s.goodsListState.drag.current) {
|
|
43
|
+
s.goodsListState.drag.container = undefined;
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const currentGood = s.goodsListState.drag.current && s.goodsListState.goodsMap.get(s.goodsListState.drag.current);
|
|
48
|
+
if (!currentGood) return;
|
|
49
|
+
|
|
50
|
+
const row = s.goodsListState.goodsMap.get(container);
|
|
51
|
+
if (!row) return;
|
|
52
|
+
|
|
53
|
+
// 折扣行 不可以插入 自己的被折扣行
|
|
54
|
+
if (currentGood.lineAttribute === LineAttributeType.折扣行) {
|
|
55
|
+
const currentIndex = s.goodsListState.goodsList.map(e => e.$index).indexOf(currentGood.$index)
|
|
56
|
+
const containerIndex = s.goodsListState.goodsList.map(e => e.$index).indexOf(row.$index)
|
|
57
|
+
if (currentIndex - 1 === containerIndex) {
|
|
58
|
+
s.goodsListState.drag.container = undefined;
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// 被折扣行 不可以插入 自己的折扣行
|
|
64
|
+
if (currentGood.lineAttribute === LineAttributeType.被折扣行) {
|
|
65
|
+
const currentIndex = s.goodsListState.goodsList.map(e => e.$index).indexOf(currentGood.$index)
|
|
66
|
+
const containerIndex = s.goodsListState.goodsList.map(e => e.$index).indexOf(row.$index)
|
|
67
|
+
if (currentIndex + 1 === containerIndex) {
|
|
68
|
+
s.goodsListState.drag.container = undefined;
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// 折扣行 拖动的 相当于 自己的 被折扣行
|
|
74
|
+
if (row.lineAttribute === LineAttributeType.折扣行) {
|
|
75
|
+
const t = s.goodsListState.goodsList.map(e => e.$index).indexOf(container) - 1;
|
|
76
|
+
s.goodsListState.drag.container = s.goodsListState.goodsList[t].$index;
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
const getRow = (t: any): any => {
|
|
82
|
+
try {
|
|
83
|
+
if (t.localName === 'tr') {
|
|
84
|
+
return t;
|
|
85
|
+
} else {
|
|
86
|
+
return getRow(t.parentNode);
|
|
87
|
+
}
|
|
88
|
+
} catch (error) {
|
|
89
|
+
return undefined;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// 放开鼠标
|
|
95
|
+
window.addEventListener('mouseup', onMouseup);
|
|
31
96
|
function onMouseup() {
|
|
97
|
+
insert();
|
|
32
98
|
controller.run(async s => s.goodsListState.drag.current = undefined);
|
|
33
99
|
window.removeEventListener('mouseup', onMouseup);
|
|
100
|
+
rowList.forEach(e => { e.removeEventListener('mouseover', onMouseover) });
|
|
101
|
+
// window.document.body.removeChild(rowDiv);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// 开始插入
|
|
105
|
+
function insert() {
|
|
106
|
+
mounting(<></>);
|
|
107
|
+
controller.run(async s => {
|
|
108
|
+
const { container, current } = s.goodsListState.drag;
|
|
109
|
+
if (!container || !current) return;
|
|
110
|
+
if (container !== current) {
|
|
111
|
+
const goodsList = s.goodsListState.goodsList;
|
|
112
|
+
const goodsMap = s.goodsListState.goodsMap;
|
|
113
|
+
const currentGood = goodsList.filter(e => e.$index === current)[0];
|
|
114
|
+
const currentIndex = goodsList.map(e => e.$index).indexOf(current);
|
|
115
|
+
|
|
116
|
+
/** 需要移动的货品列表 */
|
|
117
|
+
let moveGoods: string[] = [current];
|
|
118
|
+
if (currentGood.lineAttribute === LineAttributeType.被折扣行) {
|
|
119
|
+
moveGoods = [current, goodsList[currentIndex + 1].$index];
|
|
120
|
+
} else if (currentGood.lineAttribute === LineAttributeType.折扣行) {
|
|
121
|
+
moveGoods = [goodsList[currentIndex - 1].$index, current];
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
(() => {
|
|
125
|
+
const g = s.goodsListState.goodsList.filter(e => moveGoods.indexOf(e.$index) < 0);
|
|
126
|
+
const t = g.map(e => e.$index).indexOf(container);
|
|
127
|
+
const m = moveGoods.map(e => goodsMap.get(e)).filter(e => !!e) as IGood[];
|
|
128
|
+
s.goodsListState.goodsList = (g.splice.apply(g, [t, 0, ...m]), g);
|
|
129
|
+
})()
|
|
130
|
+
|
|
131
|
+
s.goodsListState.goodsMap = new Map();
|
|
132
|
+
s.goodsListState.goodsList.forEach(e => { s.goodsListState.goodsMap.set(e.$index, e) });
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
s.goodsListState.drag.container = undefined;
|
|
136
|
+
s.goodsListState.drag.current = undefined;
|
|
137
|
+
})
|
|
34
138
|
}
|
|
35
139
|
}, [controller, record])
|
|
36
140
|
|
|
@@ -46,4 +150,39 @@ export default function Drag(props: IDragProps) {
|
|
|
46
150
|
<Icon component={I001Svg} />
|
|
47
151
|
</Button>
|
|
48
152
|
)
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function DragDiv(props: IGood) {
|
|
156
|
+
|
|
157
|
+
const [x, setX] = React.useState(0);
|
|
158
|
+
const [y, setY] = React.useState(-110);
|
|
159
|
+
|
|
160
|
+
const div = React.useMemo(() => window.document.querySelector(`[data-row-key="${props.$index}"]`), [props.$index])
|
|
161
|
+
|
|
162
|
+
// 初始化位置
|
|
163
|
+
React.useEffect(() => {
|
|
164
|
+
if (!div) return;
|
|
165
|
+
const rect = div.getBoundingClientRect();
|
|
166
|
+
setX(rect.left + 135);
|
|
167
|
+
setY(rect.top);
|
|
168
|
+
}, [div])
|
|
169
|
+
|
|
170
|
+
// 移动事件
|
|
171
|
+
React.useEffect(() => {
|
|
172
|
+
|
|
173
|
+
function onMousemove(e: MouseEvent) { setY(e.clientY - 15) };
|
|
174
|
+
|
|
175
|
+
window.addEventListener('mousemove', onMousemove);
|
|
176
|
+
return () => {
|
|
177
|
+
window.removeEventListener('mousemove', onMousemove);
|
|
178
|
+
}
|
|
179
|
+
})
|
|
180
|
+
|
|
181
|
+
return (
|
|
182
|
+
<div className="kts-invoice-operate-goods-list-itemName-drag-div" style={{ top: y, left: x }} >
|
|
183
|
+
<span>{props.itemName}</span>
|
|
184
|
+
<span>{props.itemModelName}</span>
|
|
185
|
+
<span>{props.unit}</span>
|
|
186
|
+
</div>
|
|
187
|
+
)
|
|
49
188
|
}
|
|
@@ -5,7 +5,7 @@ import { AutoComplete } from 'kts-xui';
|
|
|
5
5
|
import { IGood, Invoice } from '../../../../../../../..';
|
|
6
6
|
import './index.less';
|
|
7
7
|
|
|
8
|
-
export default function ItemCodeInput(props: { onChange?: (e: ChangeEvent<HTMLInputElement>) => void, value?: string,
|
|
8
|
+
export default function ItemCodeInput(props: { onChange?: (e: ChangeEvent<HTMLInputElement>) => void, value?: string, record: any }) {
|
|
9
9
|
|
|
10
10
|
const controller = Invoice.useInvoiceController();
|
|
11
11
|
|
|
@@ -21,7 +21,7 @@ export default function ItemCodeInput(props: { onChange?: (e: ChangeEvent<HTMLIn
|
|
|
21
21
|
const onSearch = React.useCallback(async (searchText: string) => {
|
|
22
22
|
try {
|
|
23
23
|
if (autoComplete.onItemCodeSearch) {
|
|
24
|
-
setOptions(await autoComplete.onItemCodeSearch(searchText))
|
|
24
|
+
setOptions(await autoComplete.onItemCodeSearch(searchText, props.record?.itemName))
|
|
25
25
|
}
|
|
26
26
|
} catch (error) {
|
|
27
27
|
setOptions([])
|
|
@@ -32,13 +32,23 @@ export default function ItemCodeInput(props: { onChange?: (e: ChangeEvent<HTMLIn
|
|
|
32
32
|
const onChangeAutoComplete = React.useCallback(async itemName => {
|
|
33
33
|
const record = options.filter(e => e.itemCode === itemName)[0] as any;
|
|
34
34
|
if (!record) return;
|
|
35
|
-
|
|
35
|
+
|
|
36
|
+
const option = {
|
|
37
|
+
itemCode: record.itemCode,
|
|
38
|
+
itemName: record.itemName,
|
|
39
|
+
taxCategoryCode: record.taxCategoryCode,
|
|
40
|
+
shorthand: record.shorthand,
|
|
41
|
+
specification: record.specification,
|
|
42
|
+
unit: record.unit,
|
|
43
|
+
lineAmountIncludeTax: record.lineAmountIncludeTax,
|
|
44
|
+
taxRate: record.taxRate,
|
|
45
|
+
}
|
|
46
|
+
await controller.setEditGood(option);
|
|
36
47
|
}, [options, controller])
|
|
37
48
|
|
|
38
49
|
return (
|
|
39
50
|
<div className='kts-invoice-operate-goods-list-itemCode-input'>
|
|
40
|
-
{props.
|
|
41
|
-
<AutoComplete onSearch={onSearch} options={options.map(e => ({ value: e.itemCode }))} onChange={onChangeAutoComplete} >
|
|
51
|
+
<AutoComplete onSearch={onSearch} defaultValue={props.value} options={options.map(e => ({ value: e.itemCode }))} onChange={onChangeAutoComplete} >
|
|
42
52
|
<Input style={{ height: '100%', border: 'none' }} value={props.value} onChange={onChange} />
|
|
43
53
|
</AutoComplete>
|
|
44
54
|
</div>
|
|
@@ -99,7 +99,7 @@ export default function ItemNameInput(props: { onChange?: (e: ChangeEvent<HTMLIn
|
|
|
99
99
|
return (
|
|
100
100
|
<div className='kts-invoice-operate-goods-list-itemName-input'>
|
|
101
101
|
{props.shorthand && <span style={{ alignSelf: 'center', fontSize: 12 }} >*{props.shorthand}*</span>}
|
|
102
|
-
<AutoComplete onSearch={onSearch} options={options.map(e => ({ value: e.itemName }))} onChange={onChangeAutoComplete} >
|
|
102
|
+
<AutoComplete onSearch={onSearch} defaultValue={props.value} options={options.map(e => ({ value: e.itemName }))} onChange={onChangeAutoComplete} >
|
|
103
103
|
<Input style={{ height: '100%', border: 'none' }} value={props.value} onChange={onChange} />
|
|
104
104
|
</AutoComplete>
|
|
105
105
|
</div>
|
|
@@ -2,15 +2,24 @@ import React from "react";
|
|
|
2
2
|
import Invoice from '../../../../..';
|
|
3
3
|
import { LineAttributeType } from '../../../../../InvoiceController'
|
|
4
4
|
import classnames from 'classnames'
|
|
5
|
+
import './index.less';
|
|
5
6
|
|
|
6
7
|
export default function TableRow(props: any) {
|
|
7
8
|
|
|
9
|
+
const rowKey = props['data-row-key']
|
|
10
|
+
|
|
8
11
|
const controller = Invoice.useInvoiceController();
|
|
9
12
|
|
|
10
13
|
const goodsMap = controller.useMemo(s => s.goodsListState.goodsMap, [])
|
|
11
14
|
|
|
15
|
+
const current = controller.useMemo(s => s.goodsListState.drag.current, [])
|
|
16
|
+
|
|
17
|
+
const container = controller.useMemo(s => s.goodsListState.drag.container, [])
|
|
18
|
+
|
|
19
|
+
const good = React.useMemo(() => goodsMap?.get(rowKey), [rowKey, goodsMap])
|
|
20
|
+
|
|
12
21
|
const discount = React.useMemo(() => {
|
|
13
|
-
const i =
|
|
22
|
+
const i = good;
|
|
14
23
|
if (!i) return undefined;
|
|
15
24
|
|
|
16
25
|
if (i.lineAttribute === LineAttributeType.折扣行) {
|
|
@@ -20,9 +29,19 @@ export default function TableRow(props: any) {
|
|
|
20
29
|
} else {
|
|
21
30
|
return undefined;
|
|
22
31
|
}
|
|
23
|
-
}, [
|
|
32
|
+
}, [good, goodsMap])
|
|
24
33
|
|
|
25
34
|
return (
|
|
26
|
-
|
|
35
|
+
rowKey === current && current
|
|
36
|
+
? (
|
|
37
|
+
<tr style={{ height: 32.67, borderBottom: '1px solid #E6E6E6', position: 'relative' }} >
|
|
38
|
+
<div style={{ height: 1, width: '100%', background: '#E6E6E6', position: 'absolute', bottom: 0 }} />
|
|
39
|
+
</tr>
|
|
40
|
+
) : (
|
|
41
|
+
<tr
|
|
42
|
+
{...props}
|
|
43
|
+
className={classnames(props.className, discount, (rowKey === container && current) ? 'kts-invoice-operate-goods-list-itemName-drag-container' : undefined)}
|
|
44
|
+
/>
|
|
45
|
+
)
|
|
27
46
|
)
|
|
28
47
|
}
|
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
onChangeTaxRate,
|
|
20
20
|
onChangeItemName,
|
|
21
21
|
} from './autoFillFn';
|
|
22
|
+
import Drag from './ui/Drag';
|
|
22
23
|
|
|
23
24
|
export default (form: WrappedFormUtils) => {
|
|
24
25
|
const { getFieldDecorator, getFieldValue } = form;
|
|
@@ -76,6 +77,13 @@ export default (form: WrappedFormUtils) => {
|
|
|
76
77
|
/** 表头 */
|
|
77
78
|
const columns = React.useMemo(() => {
|
|
78
79
|
return [
|
|
80
|
+
{
|
|
81
|
+
title: ' ',
|
|
82
|
+
key: 'drag',
|
|
83
|
+
width: 40,
|
|
84
|
+
align: 'center',
|
|
85
|
+
render: (_: any, record: IGood) => <Drag record={record} />
|
|
86
|
+
},
|
|
79
87
|
{
|
|
80
88
|
title: '序号',
|
|
81
89
|
key: 'serialNo',
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
.kts-invoice-operate-goods-list-itemName-drag {
|
|
2
|
+
cursor: all-scroll;
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.kts-invoice-operate-goods-list-itemName-drag-div {
|
|
8
|
+
z-index : 999;
|
|
9
|
+
border : 1px solid #E6E6E6;
|
|
10
|
+
width : 400px;
|
|
11
|
+
height : 50px;
|
|
12
|
+
display : flex;
|
|
13
|
+
gap : 10px;
|
|
14
|
+
align-items : center;
|
|
15
|
+
position : fixed;
|
|
16
|
+
padding : 0 20px;
|
|
17
|
+
top : 100px;
|
|
18
|
+
background : #fff;
|
|
19
|
+
pointer-events: none;
|
|
20
|
+
opacity : 0.4;
|
|
21
|
+
}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
|
|
2
|
+
import React from "react";
|
|
3
|
+
import Icon from '@ant-design/icons';
|
|
4
|
+
import { ReactComponent as I001Svg } from './svg/I001.svg';
|
|
5
|
+
import { Button } from "kts-components-antd-x3";
|
|
6
|
+
import { IGood, Invoice } from '../../../../../../../..';
|
|
7
|
+
import mounting from "../../../../../../../tools/mounting";
|
|
8
|
+
import { LineAttributeType } from "../../../../../../../InvoiceController";
|
|
9
|
+
import './index.less';
|
|
10
|
+
|
|
11
|
+
export interface IDragProps {
|
|
12
|
+
record: IGood
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export default function Drag(props: IDragProps) {
|
|
16
|
+
|
|
17
|
+
const { record } = props;
|
|
18
|
+
|
|
19
|
+
const controller = Invoice.useInvoiceController();
|
|
20
|
+
|
|
21
|
+
const editGood = controller.useMemo(s => s.goodsListState.editGood, []);
|
|
22
|
+
|
|
23
|
+
const disabled = React.useMemo(() => !!editGood, [editGood]);
|
|
24
|
+
|
|
25
|
+
const onMouseDown = React.useCallback(() => {
|
|
26
|
+
if (!controller || !record) return;
|
|
27
|
+
controller.run(async s => s.goodsListState.drag.current = record.$index);
|
|
28
|
+
|
|
29
|
+
const rowList = window.document.querySelectorAll<HTMLDivElement>('.kts-invoice-operate-goods-list-digtal');
|
|
30
|
+
|
|
31
|
+
const currentGood = controller.state.goodsListState.goodsList.filter(e => e.$index === record.$index)[0];
|
|
32
|
+
mounting(<DragDiv {...currentGood} />)
|
|
33
|
+
|
|
34
|
+
// 监听移动
|
|
35
|
+
rowList.forEach(e => { e.addEventListener('mouseover', onMouseover) });
|
|
36
|
+
function onMouseover(e: MouseEvent) {
|
|
37
|
+
controller.run(async s => {
|
|
38
|
+
const container = s.goodsListState.drag.container = getRow(e.target)?.dataset?.rowKey;
|
|
39
|
+
if (!container) return;
|
|
40
|
+
|
|
41
|
+
// 不可以插入自己
|
|
42
|
+
if (container === s.goodsListState.drag.current) {
|
|
43
|
+
s.goodsListState.drag.container = undefined;
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const currentGood = s.goodsListState.drag.current && s.goodsListState.goodsMap.get(s.goodsListState.drag.current);
|
|
48
|
+
if (!currentGood) return;
|
|
49
|
+
|
|
50
|
+
const row = s.goodsListState.goodsMap.get(container);
|
|
51
|
+
if (!row) return;
|
|
52
|
+
|
|
53
|
+
// 折扣行 不可以插入 自己的被折扣行
|
|
54
|
+
if (currentGood.lineAttribute === LineAttributeType.折扣行) {
|
|
55
|
+
const currentIndex = s.goodsListState.goodsList.map(e => e.$index).indexOf(currentGood.$index)
|
|
56
|
+
const containerIndex = s.goodsListState.goodsList.map(e => e.$index).indexOf(row.$index)
|
|
57
|
+
if (currentIndex - 1 === containerIndex) {
|
|
58
|
+
s.goodsListState.drag.container = undefined;
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// 被折扣行 不可以插入 自己的折扣行
|
|
64
|
+
if (currentGood.lineAttribute === LineAttributeType.被折扣行) {
|
|
65
|
+
const currentIndex = s.goodsListState.goodsList.map(e => e.$index).indexOf(currentGood.$index)
|
|
66
|
+
const containerIndex = s.goodsListState.goodsList.map(e => e.$index).indexOf(row.$index)
|
|
67
|
+
if (currentIndex + 1 === containerIndex) {
|
|
68
|
+
s.goodsListState.drag.container = undefined;
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// 折扣行 拖动的 相当于 自己的 被折扣行
|
|
74
|
+
if (row.lineAttribute === LineAttributeType.折扣行) {
|
|
75
|
+
const t = s.goodsListState.goodsList.map(e => e.$index).indexOf(container) - 1;
|
|
76
|
+
s.goodsListState.drag.container = s.goodsListState.goodsList[t].$index;
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
const getRow = (t: any): any => {
|
|
81
|
+
try {
|
|
82
|
+
if (t.localName === 'tr') {
|
|
83
|
+
return t;
|
|
84
|
+
} else {
|
|
85
|
+
return getRow(t.parentNode);
|
|
86
|
+
}
|
|
87
|
+
} catch (error) {
|
|
88
|
+
return undefined
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// 放开鼠标
|
|
94
|
+
window.addEventListener('mouseup', onMouseup);
|
|
95
|
+
function onMouseup() {
|
|
96
|
+
insert();
|
|
97
|
+
controller.run(async s => s.goodsListState.drag.current = undefined);
|
|
98
|
+
window.removeEventListener('mouseup', onMouseup);
|
|
99
|
+
rowList.forEach(e => { e.removeEventListener('mouseover', onMouseover) });
|
|
100
|
+
// window.document.body.removeChild(rowDiv);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// 开始插入
|
|
104
|
+
function insert() {
|
|
105
|
+
mounting(<></>);
|
|
106
|
+
controller.run(async s => {
|
|
107
|
+
const { container, current } = s.goodsListState.drag;
|
|
108
|
+
if (!container || !current) return;
|
|
109
|
+
if (container !== current) {
|
|
110
|
+
const goodsList = s.goodsListState.goodsList;
|
|
111
|
+
const goodsMap = s.goodsListState.goodsMap;
|
|
112
|
+
const currentGood = goodsList.filter(e => e.$index === current)[0];
|
|
113
|
+
const currentIndex = goodsList.map(e => e.$index).indexOf(current);
|
|
114
|
+
|
|
115
|
+
/** 需要移动的货品列表 */
|
|
116
|
+
let moveGoods: string[] = [current];
|
|
117
|
+
if (currentGood.lineAttribute === LineAttributeType.被折扣行) {
|
|
118
|
+
moveGoods = [current, goodsList[currentIndex + 1].$index];
|
|
119
|
+
} else if (currentGood.lineAttribute === LineAttributeType.折扣行) {
|
|
120
|
+
moveGoods = [goodsList[currentIndex - 1].$index, current];
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
(() => {
|
|
124
|
+
const g = s.goodsListState.goodsList.filter(e => moveGoods.indexOf(e.$index) < 0);
|
|
125
|
+
const t = g.map(e => e.$index).indexOf(container);
|
|
126
|
+
const m = moveGoods.map(e => goodsMap.get(e)).filter(e => !!e) as IGood[];
|
|
127
|
+
s.goodsListState.goodsList = (g.splice.apply(g, [t, 0, ...m]), g);
|
|
128
|
+
})()
|
|
129
|
+
|
|
130
|
+
s.goodsListState.goodsMap = new Map();
|
|
131
|
+
s.goodsListState.goodsList.forEach(e => { s.goodsListState.goodsMap.set(e.$index, e) });
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
s.goodsListState.drag.container = undefined;
|
|
135
|
+
s.goodsListState.drag.current = undefined;
|
|
136
|
+
})
|
|
137
|
+
}
|
|
138
|
+
}, [controller, record])
|
|
139
|
+
|
|
140
|
+
return (
|
|
141
|
+
<Button
|
|
142
|
+
type='link'
|
|
143
|
+
style={{ padding: 0 }}
|
|
144
|
+
disabled={disabled}
|
|
145
|
+
onMouseDown={onMouseDown}
|
|
146
|
+
onClick={e => { e.stopPropagation() }}
|
|
147
|
+
className={"kts-invoice-operate-goods-list-itemName-drag"}
|
|
148
|
+
>
|
|
149
|
+
<Icon component={I001Svg} />
|
|
150
|
+
</Button>
|
|
151
|
+
)
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function DragDiv(props: IGood) {
|
|
155
|
+
|
|
156
|
+
const [x, setX] = React.useState(0);
|
|
157
|
+
const [y, setY] = React.useState(-110);
|
|
158
|
+
|
|
159
|
+
const div = React.useMemo(() => window.document.querySelector(`[data-row-key="${props.$index}"]`), [props.$index])
|
|
160
|
+
|
|
161
|
+
// 初始化位置
|
|
162
|
+
React.useEffect(() => {
|
|
163
|
+
if (!div) return;
|
|
164
|
+
const rect = div.getBoundingClientRect();
|
|
165
|
+
setX(rect.left + 135);
|
|
166
|
+
setY(rect.top);
|
|
167
|
+
}, [div])
|
|
168
|
+
|
|
169
|
+
// 移动事件
|
|
170
|
+
React.useEffect(() => {
|
|
171
|
+
|
|
172
|
+
function onMousemove(e: MouseEvent) { setY(e.clientY - 25) };
|
|
173
|
+
|
|
174
|
+
window.addEventListener('mousemove', onMousemove);
|
|
175
|
+
return () => {
|
|
176
|
+
window.removeEventListener('mousemove', onMousemove);
|
|
177
|
+
}
|
|
178
|
+
})
|
|
179
|
+
|
|
180
|
+
return (
|
|
181
|
+
<div className="kts-invoice-operate-goods-list-itemName-drag-div" style={{ top: y, left: x }} >
|
|
182
|
+
<span>{props.itemName}</span>
|
|
183
|
+
<span>{props.itemModelName}</span>
|
|
184
|
+
<span>{props.unit}</span>
|
|
185
|
+
</div>
|
|
186
|
+
)
|
|
187
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg t="1694426134787" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4024" width="200" height="200"><path d="M304.87387614-5.81530905h123.75785957v123.75785958H304.87387614V-5.81530905z m281.27727647 0h123.75785836v123.75785958h-123.75785836V-5.81530905zM304.87387614 286.75034075h123.75785957v123.75785835H304.87387614V286.75034075z m281.27727647 0h123.75785836v123.75785835h-123.75785836V286.75034075zM304.87387614 579.21242666h123.75785957v123.75785957H304.87387614v-123.75785957z m281.27727647 0h123.75785836v123.75785957h-123.75785836v-123.75785957zM304.87387614 871.82985838h123.75785957v123.75785837H304.87387614v-123.75785837z m281.27727647 0h123.75785836v123.75785837h-123.75785836v-123.75785837z" p-id="4025"></path></svg>
|