kts-component-invoice-operate 3.2.53 → 3.2.55

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 (199) hide show
  1. package/.dumi/theme/builtins/API.tsx +66 -66
  2. package/.editorconfig +16 -16
  3. package/.fatherrc.ts +4 -4
  4. package/.prettierignore +7 -7
  5. package/.prettierrc +11 -11
  6. package/.umirc.ts +8 -8
  7. package/README.md +5 -5
  8. package/dist/index.esm.js +7905 -5681
  9. package/dist/index.js +7905 -5681
  10. package/docs/index.md +5 -5
  11. package/docs-dist/static/arrowDown.a1cbf0d8.svg +2 -2
  12. package/docs-dist/static/arrowUp.4c482054.svg +2 -2
  13. package/docs-dist/static/fork.5431267d.svg +11 -11
  14. package/docs-dist/static/plus.44013ce3.svg +11 -11
  15. package/docs-dist/static/plus.4fd1af30.svg +11 -11
  16. package/index.html +12 -12
  17. package/package.json +60 -60
  18. package/src/Invoice/Invoice-digtal/_test/disabled/index.tsx +38 -38
  19. package/src/Invoice/Invoice-digtal/_test/easiest/index.tsx +16 -16
  20. package/src/Invoice/Invoice-digtal/_test/header/index.tsx +84 -84
  21. package/src/Invoice/Invoice-digtal/_test/importGoods/index.tsx +470 -470
  22. package/src/Invoice/Invoice-digtal/_test/importStakeholder/index.tsx +17 -17
  23. package/src/Invoice/Invoice-digtal/_test/lineCredit/index.tsx +20 -20
  24. package/src/Invoice/Invoice-digtal/_test/prefab/index.tsx +150 -150
  25. package/src/Invoice/Invoice-digtal/_test/readOnly/index.tsx +41 -41
  26. package/src/Invoice/Invoice-digtal/_test/stakeholder/index.tsx +12 -12
  27. package/src/Invoice/Invoice-digtal/_test/typeSelection/index.tsx +29 -29
  28. package/src/Invoice/Invoice-digtal/index.md +30 -30
  29. package/src/Invoice/InvoiceController/InvoiceControllerForm/index.ts +94 -94
  30. package/src/Invoice/InvoiceController/InvoiceControllerState/AutoComplete/index.ts +17 -17
  31. package/src/Invoice/InvoiceController/InvoiceControllerState/BuyerState/index.tsx +88 -88
  32. package/src/Invoice/InvoiceController/InvoiceControllerState/GoodsListState/Drag/index.ts +12 -12
  33. package/src/Invoice/InvoiceController/InvoiceControllerState/GoodsListState/EndowCode/index.tsx +93 -93
  34. package/src/Invoice/InvoiceController/InvoiceControllerState/GoodsListState/IColumnsReplenish/index.ts +10 -10
  35. package/src/Invoice/InvoiceController/InvoiceControllerState/GoodsListState/IGood/index.ts +75 -75
  36. package/src/Invoice/InvoiceController/InvoiceControllerState/GoodsListState/ImportGoods/index.ts +80 -80
  37. package/src/Invoice/InvoiceController/InvoiceControllerState/GoodsListState/LineAttributeType/index.ts +5 -5
  38. package/src/Invoice/InvoiceController/InvoiceControllerState/GoodsListState/ProductComparison/index.ts +9 -9
  39. package/src/Invoice/InvoiceController/InvoiceControllerState/GoodsListState/index.ts +107 -107
  40. package/src/Invoice/InvoiceController/InvoiceControllerState/Stakeholder/index.ts +10 -10
  41. package/src/Invoice/InvoiceController/InvoiceControllerState/index.ts +60 -60
  42. package/src/Invoice/InvoiceController/fns/addGood.ts +11 -11
  43. package/src/Invoice/InvoiceController/fns/addGoodDiscount.ts +125 -125
  44. package/src/Invoice/InvoiceController/fns/addGoodDiscountV2.ts +84 -84
  45. package/src/Invoice/InvoiceController/fns/delGood.ts +41 -41
  46. package/src/Invoice/InvoiceController/fns/getGoodsSearch.ts +26 -26
  47. package/src/Invoice/InvoiceController/fns/importGoodsDrawer.ts +79 -68
  48. package/src/Invoice/InvoiceController/fns/mergeDetails.ts +163 -163
  49. package/src/Invoice/InvoiceController/fns/mergeDiscount.ts +28 -28
  50. package/src/Invoice/InvoiceController/fns/saveEditGood.ts +24 -24
  51. package/src/Invoice/InvoiceController/fns/setEditGood.ts +16 -16
  52. package/src/Invoice/InvoiceController/fns/setGoods.ts +10 -10
  53. package/src/Invoice/InvoiceController/fns/updateInvoiceNo.ts +8 -8
  54. package/src/Invoice/InvoiceController/index.ts +77 -77
  55. package/src/Invoice/_test/buyerNameSearch/index.tsx +41 -41
  56. package/src/Invoice/_test/deduction/index.tsx +935 -935
  57. package/src/Invoice/_test/draft/index.tsx +40 -40
  58. package/src/Invoice/_test/easiest/index.tsx +5 -5
  59. package/src/Invoice/_test/endowCode/index.tsx +1099 -1099
  60. package/src/Invoice/_test/goodsMenuExpand/index.tsx +32 -32
  61. package/src/Invoice/_test/importBuyer/index.tsx +74 -74
  62. package/src/Invoice/_test/importGoods/index.tsx +515 -515
  63. package/src/Invoice/_test/invoiceType/index.tsx +59 -59
  64. package/src/Invoice/_test/isInvoiceNo/index.tsx +12 -12
  65. package/src/Invoice/_test/replaceHead/index.tsx +22 -22
  66. package/src/Invoice/_test/retrieveData/index.tsx +22 -22
  67. package/src/Invoice/_test/seller/index.tsx +28 -28
  68. package/src/Invoice/_test/setDataSource/index.tsx +73 -73
  69. package/src/Invoice/_test/unit/index.tsx +19 -19
  70. package/src/Invoice/index.less +29 -29
  71. package/src/Invoice/index.md +53 -53
  72. package/src/Invoice/index.tsx +165 -165
  73. package/src/Invoice/tools/calculate/index.ts +112 -112
  74. package/src/Invoice/tools/coolingFn/index.ts +17 -17
  75. package/src/Invoice/tools/evaluate/index.ts +7 -7
  76. package/src/Invoice/tools/idGenerator/index.ts +2 -2
  77. package/src/Invoice/tools/itemName/index.ts +55 -55
  78. package/src/Invoice/tools/lazyFn/index.ts +19 -19
  79. package/src/Invoice/tools/mounting/index.ts +13 -13
  80. package/src/Invoice/tools/strringFn/index.ts +40 -40
  81. package/src/Invoice/tools/useToGenerateId/index.ts +8 -8
  82. package/src/Invoice/ui/default/AddComparisonDrawer/index.tsx +149 -149
  83. package/src/Invoice/ui/default/Buyer/index.less +219 -219
  84. package/src/Invoice/ui/default/Buyer/index.tsx +114 -114
  85. package/src/Invoice/ui/default/Buyer/ui/BuyerNameInput/index.tsx +166 -166
  86. package/src/Invoice/ui/default/Buyer/ui/ImportBuyerButton/index.tsx +21 -21
  87. package/src/Invoice/ui/default/EndowCodeDrawer/index.less +8 -8
  88. package/src/Invoice/ui/default/EndowCodeDrawer/index.tsx +431 -431
  89. package/src/Invoice/ui/default/GoodsList/hook/useColumns/autoFillFn/index.ts +533 -533
  90. package/src/Invoice/ui/default/GoodsList/hook/useColumns/index.tsx +664 -664
  91. package/src/Invoice/ui/default/GoodsList/hook/useColumns/ui/Drag/index.less +20 -20
  92. package/src/Invoice/ui/default/GoodsList/hook/useColumns/ui/Drag/index.tsx +202 -202
  93. package/src/Invoice/ui/default/GoodsList/hook/useColumns/ui/ItemCodeInput/index.less +18 -18
  94. package/src/Invoice/ui/default/GoodsList/hook/useColumns/ui/ItemCodeInput/index.tsx +48 -48
  95. package/src/Invoice/ui/default/GoodsList/hook/useColumns/ui/ItemNameInput/index.less +17 -17
  96. package/src/Invoice/ui/default/GoodsList/hook/useColumns/ui/ItemNameInput/index.tsx +130 -130
  97. package/src/Invoice/ui/default/GoodsList/hook/useColumns/ui/RowEditButton/index.tsx +30 -30
  98. package/src/Invoice/ui/default/GoodsList/hook/useColumns/ui/RowMenu/hook/_useAddComparison/index.tsx +43 -43
  99. package/src/Invoice/ui/default/GoodsList/hook/useColumns/ui/RowMenu/hook/useAddDiscount/index.tsx +76 -76
  100. package/src/Invoice/ui/default/GoodsList/hook/useColumns/ui/RowMenu/hook/useDelItem/index.tsx +41 -41
  101. package/src/Invoice/ui/default/GoodsList/hook/useColumns/ui/RowMenu/hook/useEndowCode/index.tsx +34 -34
  102. package/src/Invoice/ui/default/GoodsList/hook/useColumns/ui/RowMenu/index.less +13 -13
  103. package/src/Invoice/ui/default/GoodsList/hook/useColumns/ui/RowMenu/index.tsx +98 -98
  104. package/src/Invoice/ui/default/GoodsList/hook/useColumns/ui/RowSaveButton/index.tsx +14 -14
  105. package/src/Invoice/ui/default/GoodsList/hook/useColumns/ui/TitleText/index.tsx +20 -20
  106. package/src/Invoice/ui/default/GoodsList/hook/useDeduction/index.tsx +24 -24
  107. package/src/Invoice/ui/default/GoodsList/hook/useOnRow/index.tsx +39 -39
  108. package/src/Invoice/ui/default/GoodsList/hook/useRowSelection/index.tsx +111 -111
  109. package/src/Invoice/ui/default/GoodsList/hook/useWindowClick/index.tsx +23 -23
  110. package/src/Invoice/ui/default/GoodsList/index.less +177 -177
  111. package/src/Invoice/ui/default/GoodsList/index.tsx +191 -191
  112. package/src/Invoice/ui/default/GoodsList/ui/AddRowButton/index.tsx +65 -65
  113. package/src/Invoice/ui/default/GoodsList/ui/BulkMenu/hooks/useAddDiscountRowButton/index.less +21 -21
  114. package/src/Invoice/ui/default/GoodsList/ui/BulkMenu/hooks/useAddDiscountRowButton/index.tsx +244 -244
  115. package/src/Invoice/ui/default/GoodsList/ui/BulkMenu/hooks/useCommodityComparisonButton/index.tsx +75 -75
  116. package/src/Invoice/ui/default/GoodsList/ui/BulkMenu/hooks/useDelRowButton/index.tsx +69 -69
  117. package/src/Invoice/ui/default/GoodsList/ui/BulkMenu/hooks/useEndowCodeButton/index.tsx +58 -58
  118. package/src/Invoice/ui/default/GoodsList/ui/BulkMenu/hooks/useMergeDetails/index.tsx +37 -37
  119. package/src/Invoice/ui/default/GoodsList/ui/BulkMenu/hooks/useMergeDiscount/index.tsx +36 -36
  120. package/src/Invoice/ui/default/GoodsList/ui/BulkMenu/index.tsx +37 -37
  121. package/src/Invoice/ui/default/GoodsList/ui/DescribeSwitch/index.tsx +36 -36
  122. package/src/Invoice/ui/default/GoodsList/ui/Search/index.less +10 -10
  123. package/src/Invoice/ui/default/GoodsList/ui/Search/index.tsx +52 -52
  124. package/src/Invoice/ui/default/GoodsList/ui/Statistics/index.less +18 -18
  125. package/src/Invoice/ui/default/GoodsList/ui/Statistics/index.tsx +109 -109
  126. package/src/Invoice/ui/default/GoodsList/ui/TableRow/index.less +13 -13
  127. package/src/Invoice/ui/default/GoodsList/ui/TableRow/index.tsx +46 -46
  128. package/src/Invoice/ui/default/GoodsList/ui/TableVirtual/index.less +38 -38
  129. package/src/Invoice/ui/default/GoodsList/ui/TableVirtual/index.tsx +108 -108
  130. package/src/Invoice/ui/default/GoodsList/ui/TableVirtual.o/index.less +44 -44
  131. package/src/Invoice/ui/default/GoodsList/ui/TableVirtual.o/index.tsx +96 -96
  132. package/src/Invoice/ui/default/GoodsList/ui/TaxIncludedSwitch/index.tsx +30 -30
  133. package/src/Invoice/ui/default/ImportBuyerDrawer/index.tsx +75 -75
  134. package/src/Invoice/ui/default/ImportGoodsDrawer/index.tsx +193 -193
  135. package/src/Invoice/ui/default/InvoiceHeader/index.less +68 -68
  136. package/src/Invoice/ui/default/InvoiceHeader/index.tsx +246 -246
  137. package/src/Invoice/ui/default/Seller/index.less +113 -113
  138. package/src/Invoice/ui/default/Seller/index.tsx +98 -98
  139. package/src/Invoice/ui/default/Sign/index.less +14 -14
  140. package/src/Invoice/ui/default/Sign/index.tsx +71 -71
  141. package/src/Invoice/ui/digtal/GoodsList/hook/useColumns/autoFillFn/index.ts +519 -519
  142. package/src/Invoice/ui/digtal/GoodsList/hook/useColumns/index.tsx +648 -648
  143. package/src/Invoice/ui/digtal/GoodsList/hook/useColumns/svg/plus.svg +11 -11
  144. package/src/Invoice/ui/digtal/GoodsList/hook/useColumns/ui/Drag/index.less +20 -20
  145. package/src/Invoice/ui/digtal/GoodsList/hook/useColumns/ui/Drag/index.tsx +186 -186
  146. package/src/Invoice/ui/digtal/GoodsList/hook/useColumns/ui/ItemNameInput/index.less +9 -9
  147. package/src/Invoice/ui/digtal/GoodsList/hook/useColumns/ui/ItemNameInput/index.tsx +50 -50
  148. package/src/Invoice/ui/digtal/GoodsList/hook/useColumns/ui/RowEditButton/index.tsx +30 -30
  149. package/src/Invoice/ui/digtal/GoodsList/hook/useColumns/ui/RowMenu/hook/_useAddComparison/index.tsx +43 -43
  150. package/src/Invoice/ui/digtal/GoodsList/hook/useColumns/ui/RowMenu/hook/useAddDiscount/index.tsx +76 -76
  151. package/src/Invoice/ui/digtal/GoodsList/hook/useColumns/ui/RowMenu/hook/useDelItem/index.tsx +41 -41
  152. package/src/Invoice/ui/digtal/GoodsList/hook/useColumns/ui/RowMenu/hook/useEndowCode/index.tsx +34 -34
  153. package/src/Invoice/ui/digtal/GoodsList/hook/useColumns/ui/RowMenu/index.less +13 -13
  154. package/src/Invoice/ui/digtal/GoodsList/hook/useColumns/ui/RowMenu/index.tsx +98 -98
  155. package/src/Invoice/ui/digtal/GoodsList/hook/useColumns/ui/RowSaveButton/index.tsx +14 -14
  156. package/src/Invoice/ui/digtal/GoodsList/hook/useColumns/ui/TitleText/index.tsx +20 -20
  157. package/src/Invoice/ui/digtal/GoodsList/hook/useOnRow/index.tsx +39 -39
  158. package/src/Invoice/ui/digtal/GoodsList/hook/useRowSelection/index.tsx +121 -121
  159. package/src/Invoice/ui/digtal/GoodsList/hook/useWindowClick/index.tsx +23 -23
  160. package/src/Invoice/ui/digtal/GoodsList/index.less +56 -56
  161. package/src/Invoice/ui/digtal/GoodsList/index.tsx +180 -180
  162. package/src/Invoice/ui/digtal/GoodsList/ui/AddRowButton/index.tsx +65 -65
  163. package/src/Invoice/ui/digtal/GoodsList/ui/BulkMenu/hooks/useAddDiscountRowButton/index.tsx +341 -341
  164. package/src/Invoice/ui/digtal/GoodsList/ui/BulkMenu/hooks/useAddDiscountRowButton/svg/add.svg +11 -11
  165. package/src/Invoice/ui/digtal/GoodsList/ui/BulkMenu/hooks/useCommodityComparisonButton/index.tsx +75 -75
  166. package/src/Invoice/ui/digtal/GoodsList/ui/BulkMenu/hooks/useDelRowButton/index.tsx +50 -50
  167. package/src/Invoice/ui/digtal/GoodsList/ui/BulkMenu/hooks/useEmptyRefill/index.tsx +35 -35
  168. package/src/Invoice/ui/digtal/GoodsList/ui/BulkMenu/hooks/useEndowCodeButton/index.tsx +82 -82
  169. package/src/Invoice/ui/digtal/GoodsList/ui/BulkMenu/hooks/useReselectInvoiceType/index.tsx +57 -57
  170. package/src/Invoice/ui/digtal/GoodsList/ui/DescribeSwitch/index.tsx +36 -36
  171. package/src/Invoice/ui/digtal/GoodsList/ui/Search/index.less +11 -11
  172. package/src/Invoice/ui/digtal/GoodsList/ui/Search/index.tsx +50 -50
  173. package/src/Invoice/ui/digtal/GoodsList/ui/Statistics/index.less +53 -53
  174. package/src/Invoice/ui/digtal/GoodsList/ui/Statistics/index.tsx +99 -99
  175. package/src/Invoice/ui/digtal/GoodsList/ui/Statistics/svg/fork.svg +11 -11
  176. package/src/Invoice/ui/digtal/GoodsList/ui/TableRow/index.less +13 -13
  177. package/src/Invoice/ui/digtal/GoodsList/ui/TableRow/index.tsx +40 -40
  178. package/src/Invoice/ui/digtal/GoodsList/ui/TableVirtual/index.less +38 -38
  179. package/src/Invoice/ui/digtal/GoodsList/ui/TableVirtual/index.tsx +108 -108
  180. package/src/Invoice/ui/digtal/GoodsList/ui/TableVirtual.o/index.less +44 -44
  181. package/src/Invoice/ui/digtal/GoodsList/ui/TableVirtual.o/index.tsx +96 -96
  182. package/src/Invoice/ui/digtal/GoodsList/ui/TaxIncludedSwitch/index.tsx +30 -30
  183. package/src/Invoice/ui/digtal/InvoiceHeader/index.less +57 -57
  184. package/src/Invoice/ui/digtal/InvoiceHeader/index.tsx +77 -77
  185. package/src/Invoice/ui/digtal/Sign/index.less +48 -48
  186. package/src/Invoice/ui/digtal/Sign/index.tsx +89 -89
  187. package/src/Invoice/ui/digtal/Stakeholder/index.less +75 -75
  188. package/src/Invoice/ui/digtal/Stakeholder/index.tsx +388 -388
  189. package/src/Invoice/ui/digtal/Stakeholder/svg/arrowDown.svg +2 -2
  190. package/src/Invoice/ui/digtal/Stakeholder/svg/arrowUp.svg +2 -2
  191. package/src/Invoice/ui/digtal/Stakeholder/svg/plus.svg +11 -11
  192. package/src/InvoiceTypeModal/_test/easiest/index.tsx +31 -31
  193. package/src/InvoiceTypeModal/index.less +7 -7
  194. package/src/InvoiceTypeModal/index.md +5 -5
  195. package/src/InvoiceTypeModal/index.tsx +153 -153
  196. package/src/index.ts +9 -9
  197. package/tsconfig.json +31 -31
  198. package/typings.d.ts +3 -3
  199. package/yarn.e.lock +14331 -14331
@@ -1,664 +1,664 @@
1
- import React from 'react';
2
- import { Form, AutoComplete, Select, Button, Input, Spin, Tooltip } from 'kts-components-antd-x3';
3
- import { InputProps } from 'kts-components-antd-x3/lib/input';
4
- import { WrappedFormUtils } from 'kts-components-antd-x3/lib/form/Form';
5
- import { IGood } from '../../../../../InvoiceController';
6
- import Invoice from '../../../../..';
7
- import RowMenu from './ui/RowMenu';
8
- import TitleText from './ui/TitleText';
9
- import ItemNameInput from './ui/ItemNameInput';
10
- import ItemCodeInput from './ui/ItemCodeInput';
11
- import {
12
- onChangeQuantity,
13
- onChangePriceIncludeTax,
14
- onChangePriceExcludeTax,
15
- onChangeLineAmountIncludeTax,
16
- onChangeLineAmountExcludeTax,
17
- onChangeTaxRate,
18
- onChangeItemName,
19
- onChangeItemCode,
20
- } from './autoFillFn';
21
- import { getItemNameWithShorthand } from '../../../../../tools/itemName';
22
- import Drag from './ui/Drag';
23
-
24
- export default (form: WrappedFormUtils) => {
25
- const { getFieldDecorator, getFieldValue } = form;
26
-
27
- const controller = Invoice.useInvoiceController();
28
-
29
- /** 是否含税 */
30
- const isTaxIncluded = controller.useMemo(e => e.goodsListState.isTaxIncluded, []);
31
-
32
- /** 组件模式 */
33
- const model = controller.useMemo(e => e.model, []);
34
-
35
- /** 是否启用拖拽 */
36
- const isStart = controller.useMemo((e) => e.goodsListState.drag.isStart, []);
37
-
38
- /** 是否显示我方 */
39
- const isMyShow = controller.useMemo(e => e.goodsListState.isMyShow, []);
40
-
41
- /** 正在编辑的货物 */
42
- const editGood = controller.useMemo((e) => e.goodsListState.editGood, []);
43
-
44
- /** 商品表格隐藏列 */
45
- const columnshide = controller.useMemo((e) => e.goodsListState.columnshide, []);
46
-
47
- /** 搜索条件 */
48
- const searchValue = controller.useMemo((e) => e.goodsListState.searchValue, []);
49
-
50
- /** 税率列表 */
51
- const taxRateList = controller.useMemo((e) => e.goodsListState.taxRateList, []);
52
-
53
- /** 单位列表 */
54
- const unitList = controller.useMemo((e) => e.goodsListState.unitList, []);
55
-
56
- /** 商品表格补充配置 */
57
- const columnsReplenish = controller.useMemo((e) => e.goodsListState.columnsReplenish, []);
58
-
59
- /** 扣除额 */
60
- const deduction = controller.useMemo((e) => e.goodsListState.deduction, []);
61
-
62
- /** 计算中启动字段 */
63
- const changeField = controller.useMemo((e) => e.calculatingField, []);
64
-
65
- /** 计算中启动字段 */
66
- const setChangeField = React.useCallback((value: string) => controller.run(async s => { s.calculatingField = value }), []);
67
-
68
- const onNumberValueChange = React.useCallback((e) => {
69
- const value = e?.target?.value;
70
- if (value) {
71
- return value.replace(/[^0-9-\.]/g, '');
72
- }
73
- }, [])
74
-
75
- /** 获取补充校验规则 */
76
- const getReplenishRules = React.useCallback((id: string) => {
77
- return columnsReplenish[id] ? columnsReplenish[id].rules || [] : []
78
- }, [columnsReplenish])
79
-
80
- /** 金额整数位限制,不传默认9位 */
81
- const priceIntegerDigit = controller.useMemo((e) => e.priceIntegerDigit || 9, []);
82
-
83
- /** 表头 */
84
- const columns = React.useMemo(() => {
85
- return [
86
- {
87
- title: ' ',
88
- key: 'drag',
89
- width: 40,
90
- align: 'center',
91
- render: (_: any, record: IGood) => <Drag record={record} />
92
- },
93
- {
94
- title: '序号',
95
- key: 'serialNo',
96
- dataIndex: 'serialNo',
97
- width: 50,
98
- render: (e: number) => <span style={{ padding: '0 10px' }}>{e}</span>,
99
- },
100
- {
101
- title: '商品编码',
102
- key: 'itemCode',
103
- width: 119,
104
- render: (_: string, record: IGood) => {
105
- if (editGood?.$index === record.$index) {
106
- return (
107
- <Form.Item>
108
- {getFieldDecorator('itemCode', {
109
- initialValue: editGood.itemCode,
110
- rules: [
111
- ...getReplenishRules('itemCode'),
112
- { pattern: /^.{1,19}$/, message: '商品编码长度不能超过19位' },
113
- ]
114
- })(
115
- <ItemCodeInput
116
- onChange={async () => {
117
- await onChangeItemCode(controller, form, record);
118
- await onChangeLineAmountIncludeTax(controller, form, record);
119
- }}
120
- />
121
- )}
122
- </Form.Item>
123
- )
124
- } else {
125
- return <span style={{ padding: '0 10px' }}>{record.itemCode}</span>
126
- }
127
- }
128
- },
129
- {
130
- title: <TitleText required >项目名称</TitleText>,
131
- key: 'itemName',
132
- render: (_: string, record: IGood) => {
133
- if (editGood?.$index === record.$index) {
134
- return (
135
- <Form.Item>
136
- <div style={{ display: 'flex' }} >
137
- {getFieldDecorator('itemName', {
138
- initialValue: record.itemName,
139
- rules: [
140
- ...getReplenishRules('itemName'),
141
- {
142
- validator: async (_, __, callback) => {
143
- await controller.wait();
144
- const value = controller.state.goodsListState.editGood;
145
- if (!value?.itemName && !value?.itemNameSelf) {
146
- callback('项目名称不能为空');
147
- } else {
148
- return;
149
- }
150
- }
151
- }
152
- ]
153
- })(
154
- <ItemNameInput
155
- shorthand={editGood.shorthand}
156
- onChange={() => {
157
- onChangeItemName(controller, form, record);
158
- }}
159
- />
160
- )}
161
- <div className="kts-invoice-operate-goods-list-able-list-itemName-import">
162
- {controller.getGoodsList && model !== 'readOnly' && (
163
- <Tooltip title="点击从商品管理中添加商品信息">
164
- <Button
165
- onClick={controller.pipeline(async s => { s.goodsListState.importGoods.isVisibleDrawer = true })}
166
- type="link"
167
- icon="plus-circle"
168
- />
169
- </Tooltip>
170
- )}
171
- </div>
172
- </div>
173
- </Form.Item>
174
- );
175
- } else {
176
- return (
177
- <MyItemNameDiv
178
- valueT={formatSearch(getItemNameWithShorthand({ shorthand: record.shorthand, full: record.itemNameSelf || '' }), searchValue)}
179
- valueF={formatSearch(getItemNameWithShorthand({ shorthand: record.shorthand, full: record.itemName || '' }), searchValue)}
180
- isMyShow={isMyShow}
181
- />
182
- )
183
- }
184
- },
185
- },
186
- {
187
- title: <TitleText rules={columnsReplenish['itemModelName']?.rules} >规格型号</TitleText>,
188
- key: 'itemModelName',
189
- width: 119,
190
- render: (_: string, record: IGood) => {
191
- if (editGood?.$index === record.$index) {
192
- return (
193
- <Form.Item>
194
- {getFieldDecorator('itemModelName', {
195
- initialValue: isMyShow ? editGood.itemModelNameSelf : editGood.itemModelName,
196
- rules: getReplenishRules('itemModelName'),
197
- })(
198
- <MyInput
199
- onChange={async () => {
200
- await controller.wait()
201
- const key = isMyShow ? 'itemModelNameSelf' : 'itemModelName';
202
- const value = {} as any;
203
- value[key] = form.getFieldsValue().itemModelName;
204
- controller.setEditGood(value);
205
- }}
206
- />,
207
- )}
208
- </Form.Item>
209
- );
210
- } else {
211
- return (
212
- <MyItemNameDiv
213
- valueT={formatSearch(record.itemModelNameSelf, searchValue)}
214
- valueF={formatSearch(record.itemModelName, searchValue)}
215
- isMyShow={isMyShow}
216
- />
217
- )
218
- }
219
- },
220
- },
221
- {
222
- title: <TitleText rules={columnsReplenish['unit']?.rules} >单位</TitleText>,
223
- key: 'unit',
224
- width: 70,
225
- render: (_: string, record: IGood) => {
226
- if (editGood?.$index === record.$index) {
227
- return (
228
- <Form.Item>
229
- {getFieldDecorator('unit', {
230
- initialValue: editGood.unit,
231
- rules: getReplenishRules('unit'),
232
- })(
233
- <AutoComplete
234
- style={{ width: '100%' }}
235
- dataSource={unitList}
236
- onChange={async () => {
237
- await controller.wait()
238
- // const key = isMyShow ? 'unit' : 'unitOther';
239
- // const value = {} as any;
240
- // value[key] = form.getFieldsValue().unit;
241
- controller.setEditGood({ unit: form.getFieldsValue().unit });
242
- }}
243
- />,
244
- )}
245
- </Form.Item>
246
- );
247
- } else {
248
- return <span style={{ padding: '0 10px' }}>{record.unit}</span>;
249
- }
250
- },
251
- },
252
- {
253
- title: <TitleText rules={columnsReplenish['quantity']?.rules} >数量</TitleText>,
254
- dataIndex: 'quantity',
255
- key: 'quantity',
256
- align: 'right',
257
- width: 149,
258
- render: (value: string, record: IGood) => {
259
- if (editGood?.$index === record.$index) {
260
- return (
261
- <Form.Item>
262
- {getFieldDecorator('quantity', {
263
- initialValue: editGood.quantity,
264
- getValueFromEvent: onNumberValueChange,
265
- rules: [
266
- ...getReplenishRules('quantity'),
267
- { pattern: /^[+-]?(0|([1-9]\d*))(\.\d+)?$/, message: '数量必须为数字' },
268
- {
269
- validator: async (_, value, callback) => {
270
- await controller.wait();
271
- const isvalue = !!value || value === 0;
272
- const isPrice = !!getFieldValue(isTaxIncluded ? 'priceIncludeTax' : 'priceExcludeTax') || getFieldValue(isTaxIncluded ? 'priceIncludeTax' : 'priceExcludeTax') === 0;
273
- if (isvalue || isPrice === isvalue) return;
274
- callback('请输入数量');
275
- }
276
- }
277
- ],
278
- })(
279
- <MyInput
280
- style={{ textAlign: 'right' }}
281
- maxLength={16}
282
- loading={isCipher(changeField, "quantity")}
283
- onChange={async () => {
284
- setChangeField('quantity');
285
- await onChangeQuantity(controller, form, record);
286
- }}
287
- />,
288
- )}
289
- </Form.Item>
290
- );
291
- } else {
292
- return <span style={{ padding: '0 10px' }}>{value}</span>;
293
- }
294
- },
295
- },
296
- {
297
- title: <TitleText rules={columnsReplenish['priceIncludeTax']?.rules} >单价(含税)</TitleText>,
298
- dataIndex: 'priceIncludeTax',
299
- key: 'priceIncludeTax',
300
- align: 'right',
301
- width: 149,
302
- render: (value: string, record: IGood) => {
303
- if (editGood?.$index === record.$index) {
304
- return (
305
- <Form.Item>
306
- {getFieldDecorator('priceIncludeTax', {
307
- initialValue: editGood.priceIncludeTax,
308
- getValueFromEvent: onNumberValueChange,
309
- rules: [
310
- ...getReplenishRules('priceIncludeTax'),
311
- { pattern: /^[+-]?(0|([1-9]\d*))(\.\d+)?$/, message: '单价必须为数字' },
312
- {
313
- validator: async (_, value, callback) => {
314
- await controller.wait();
315
- const isQuantity = !!getFieldValue('quantity') || getFieldValue('quantity') === 0;
316
- const isvalue = !!value || value === 0;
317
- if (isvalue || isQuantity === isvalue) return;
318
- callback('请输入单价');
319
- }
320
- }
321
- ],
322
- })(
323
- <MyInput
324
- style={{ textAlign: 'right' }}
325
- maxLength={16}
326
- loading={isCipher(changeField, 'priceIncludeTax')}
327
- onChange={() => {
328
- setChangeField('priceIncludeTax');
329
- onChangePriceIncludeTax(controller, form, record);
330
- }}
331
- />,
332
- )}
333
- </Form.Item>
334
- );
335
- } else {
336
- return <span style={{ padding: '0 10px' }}>{value}</span>;
337
- }
338
- },
339
- },
340
- {
341
- title: <TitleText rules={columnsReplenish['priceExcludeTax']?.rules} >单价(不含税)</TitleText>,
342
- dataIndex: 'priceExcludeTax',
343
- key: 'priceExcludeTax',
344
- align: 'right',
345
- width: 149,
346
- render: (value: string, record: IGood) => {
347
- if (editGood?.$index === record.$index) {
348
- return (
349
- <Form.Item>
350
- {getFieldDecorator('priceExcludeTax', {
351
- initialValue: editGood.priceExcludeTax,
352
- getValueFromEvent: onNumberValueChange,
353
- rules: [
354
- ...getReplenishRules('priceExcludeTax'),
355
- { pattern: /^[+-]?(0|([1-9]\d*))(\.\d+)?$/, message: '单价必须为数字' },
356
- {
357
- validator: async (_, value, callback) => {
358
- await controller.wait();
359
- const isQuantity = !!getFieldValue('quantity') || getFieldValue('quantity') === 0;
360
- const isvalue = !!value || value === 0;
361
- if (isvalue || isQuantity === isvalue) return;
362
- callback('请输入单价');
363
- }
364
- }
365
- ],
366
- })(
367
- <MyInput
368
- style={{ textAlign: 'right' }}
369
- maxLength={16}
370
- loading={isCipher(changeField, 'priceExcludeTax')}
371
- onChange={() => {
372
- setChangeField('priceExcludeTax');
373
- onChangePriceExcludeTax(controller, form, record);
374
- }}
375
- />,
376
- )}
377
- </Form.Item>
378
- );
379
- } else {
380
- return <span style={{ padding: '0 10px' }}>{value}</span>;
381
- }
382
- },
383
- },
384
- {
385
- title: <TitleText required >金额(含税)</TitleText>,
386
- dataIndex: 'lineAmountIncludeTax',
387
- key: 'lineAmountIncludeTax',
388
- width: 119,
389
- align: 'right',
390
- render: (value: string, record: IGood) => {
391
- if (editGood?.$index === record.$index) {
392
- return (
393
- <Form.Item>
394
- {getFieldDecorator('lineAmountIncludeTax', {
395
- initialValue: editGood.lineAmountIncludeTax,
396
- getValueFromEvent: onNumberValueChange,
397
- rules: [
398
- ...getReplenishRules('lineAmountIncludeTax'),
399
- { required: true, message: '金额不能为空' },
400
- { pattern: /^[+-]?(0|([1-9]\d*))(\.\d+)?$/, message: '金额必须为数字' },
401
- {
402
- validator: async (_, value, callback) => {
403
- if (`${value}`.split('.')[0].length > priceIntegerDigit) {
404
- callback(`金额整数部分不能大于${priceIntegerDigit}位,小数点后最多2位`);
405
- }
406
- }
407
- },
408
- {
409
- validator: async (_, value, callback) => {
410
- if (deduction && parseFloat(value) <= deduction) {
411
- callback('扣除额不能大于等于价税合计');
412
- }
413
- }
414
- },
415
- ],
416
- })(
417
- <MyInput
418
- style={{ textAlign: 'right' }}
419
- loading={isCipher(changeField, 'lineAmountIncludeTax')}
420
- onChange={() => {
421
- setChangeField('lineAmountIncludeTax');
422
- onChangeLineAmountIncludeTax(controller, form, record);
423
- }}
424
- />,
425
- )}
426
- </Form.Item>
427
- );
428
- } else {
429
- return <span style={{ padding: '0 10px' }}>{formatSearch(parseFloat(value).toFixed(2), searchValue)}</span>;
430
- }
431
- },
432
- },
433
- {
434
- title: <TitleText required >金额(不含税)</TitleText>,
435
- dataIndex: 'lineAmountExcludeTax',
436
- key: 'lineAmountExcludeTax',
437
- align: 'right',
438
- width: 119,
439
- render: (value: string, record: IGood) => {
440
- if (editGood?.$index === record.$index) {
441
- return (
442
- <Form.Item>
443
- {getFieldDecorator('lineAmountExcludeTax', {
444
- initialValue: editGood.lineAmountExcludeTax,
445
- getValueFromEvent: onNumberValueChange,
446
- rules: [
447
- ...getReplenishRules('lineAmountExcludeTax'),
448
- { required: true, message: '金额不能为空' },
449
- { pattern: /^[+-]?(0|([1-9]\d*))(\.\d+)?$/, message: '金额必须为数字' },
450
- {
451
- validator: async (_, value: string, callback) => {
452
- if (`${value}`.split('.')[0].length > priceIntegerDigit) {
453
- callback(`金额整数部分不能大于${priceIntegerDigit}位,小数点后最多2位`);
454
- }
455
- }
456
- },
457
- ],
458
- })(
459
- <MyInput
460
- style={{ textAlign: 'right' }}
461
- loading={isCipher(changeField, 'lineAmountExcludeTax')}
462
- onChange={() => {
463
- setChangeField('lineAmountExcludeTax');
464
- onChangeLineAmountExcludeTax(controller, form, record);
465
- }}
466
- />,
467
- )}
468
- </Form.Item>
469
- );
470
- } else {
471
- return <span style={{ padding: '0 10px' }}>{formatSearch(parseFloat(value).toFixed(2), searchValue)}</span>;
472
- }
473
- },
474
- },
475
- {
476
- title: <TitleText required >税率%</TitleText>,
477
- dataIndex: 'taxRate',
478
- key: 'taxRate',
479
- align: 'right',
480
- width: 70,
481
- render: (value: string, record: IGood) => {
482
- if (editGood?.$index === record.$index) {
483
- return (
484
- <Form.Item>
485
- {getFieldDecorator('taxRate', {
486
- initialValue: editGood.taxRate,
487
- rules: [
488
- ...getReplenishRules('taxRate'),
489
- { required: true, message: ' ' },
490
- { pattern: /^[+-]?(0|([1-9]\d*))(\.\d+)?$/, message: ' ' },
491
- ],
492
- })(
493
- <Select
494
- className="kts-invoice-operate-goods-list-table-tax-rate"
495
- dropdownMenuStyle={{ textAlign: "right" }}
496
- showArrow={false}
497
- style={{ width: '100%' }}
498
- onChange={() => {
499
- setChangeField('taxRate');
500
- onChangeTaxRate(controller, form, record);
501
- }}
502
- >
503
- {taxRateList.map((e, i) => {
504
- return (
505
- <Select.Option key={i} value={e}>
506
- {e}%
507
- </Select.Option>
508
- );
509
- })}
510
- </Select>,
511
- )}
512
- </Form.Item>
513
- );
514
- } else {
515
- return <span style={{ padding: '0 10px' }}>{value}%</span>;
516
- }
517
- },
518
- },
519
- {
520
- title: <TitleText rules={columnsReplenish['taxAmount']?.rules} >税额</TitleText>,
521
- dataIndex: 'taxAmount',
522
- key: 'taxAmount',
523
- align: 'right',
524
- width: 119,
525
- render: (value: string, record: IGood) => {
526
- if (editGood?.$index === record.$index) {
527
- return getFieldDecorator('taxAmount', {
528
- initialValue: editGood.taxAmount,
529
- rules: getReplenishRules('taxAmount'),
530
- })(<MyDiv loading={isCipher(changeField, 'taxAmount')} />);
531
- } else {
532
- return <span style={{ padding: '0 10px' }}>{parseFloat(value).toFixed(2)}</span>;
533
- }
534
- },
535
- },
536
- {
537
- title: '操作',
538
- key: 'operating',
539
- align: 'right',
540
- width: 130,
541
- fixed: 'right',
542
- render: (_value: string, record: IGood) => <RowMenu key={record.lineAttribute} goods={record} />,
543
- },
544
- ]
545
- // 筛选隐藏
546
- .filter(e => {
547
- return e.key ? columnshide.indexOf(e.key) < 0 : false;
548
- })
549
- // 含税不含税
550
- .filter((e) => {
551
- if (isTaxIncluded) {
552
- return !(e.key === 'priceExcludeTax' || e.key === 'lineAmountExcludeTax');
553
- } else {
554
- return !(e.key === 'priceIncludeTax' || e.key === 'lineAmountIncludeTax');
555
- }
556
- })
557
- // 是否启动拖拽
558
- .filter(e => e.key !=='drag' || isStart)
559
- // 只读
560
- .filter(e => {
561
- if (model === 'readOnly') {
562
- return e.key !== 'operating';
563
- } else {
564
- return true;
565
- }
566
- })
567
- .map((e) => {
568
- return {
569
- ...e,
570
- ellipsis: true,
571
- };
572
- }) as any[];
573
- }, [isTaxIncluded, editGood, controller, changeField, deduction, isMyShow, searchValue, model, columnsReplenish, columnshide, isStart]);
574
- return columns;
575
- };
576
-
577
- /** 字段 */
578
- function isCipher(name?: string, field?: string) {
579
- if (!name || !field) return false;
580
- return name !== field;
581
- }
582
-
583
- class MyInput extends React.Component<InputProps & { loading?: boolean }> {
584
- render() {
585
- if (this.props.loading) {
586
- return (
587
- <Spin size="small">
588
- <Input {...this.props} autoComplete="off" />
589
- </Spin>
590
- )
591
- } else {
592
- return <Input {...this.props} autoComplete="off" />
593
- }
594
- }
595
- }
596
-
597
- class MyDiv extends React.Component<{ value?: any, loading?: boolean }> {
598
- render() {
599
- if (this.props.loading) {
600
- return (
601
- <Spin size="small">
602
- <span style={{ padding: '0 10px' }}>{this.props.value}</span>
603
- </Spin>
604
- )
605
- } else {
606
- return <span style={{ padding: '0 10px' }}>{this.props.value}</span>
607
- }
608
- }
609
- }
610
-
611
- class MyItemNameDiv extends React.Component<{ valueT?: React.ReactNode, valueF?: React.ReactNode, isMyShow: boolean }> {
612
- render(): React.ReactNode {
613
-
614
- const { isMyShow, valueT, valueF } = this.props;
615
-
616
- if (isMyShow) {
617
- if (valueT) {
618
- return (
619
- <Tooltip title={valueT}>
620
- <span style={{ padding: '0 10px', color: '#0074ff' }}>{valueT}</span>
621
- </Tooltip>
622
- )
623
- } else {
624
- return (
625
- <Tooltip title={valueF}>
626
- <span style={{ padding: '0 10px' }}>{valueF}</span>
627
- </Tooltip>
628
- )
629
- }
630
- } else {
631
- if (valueF) {
632
- return (
633
- <Tooltip title={valueF}>
634
- <span style={{ padding: '0 10px' }}>{valueF}</span>
635
- </Tooltip>
636
- )
637
- } else {
638
- return (
639
- <Tooltip title={valueT}>
640
- <span style={{ padding: '0 10px', color: '#0074ff' }}>{valueT}</span>
641
- </Tooltip>
642
- )
643
- }
644
- }
645
- }
646
- }
647
-
648
- /** 格式搜索结果 */
649
- function formatSearch(value?: string, search?: string) {
650
- if (!value || !search) return value;
651
-
652
- const __html = ucoding(value).split(new RegExp(ucoding(search), 'g')).map(e => dcoding(e)).join(`<span class="kts-invoice-operate-goods-list-table-search-protrude" >${search}</span>`);
653
- return <span dangerouslySetInnerHTML={{ __html }} />
654
- }
655
-
656
- /** 编码 */
657
- function ucoding(v: string): string {
658
- return v.split('').map(e => `U${e.charCodeAt(0)}E`).join('');
659
- }
660
-
661
- /** 解码 */
662
- function dcoding(v: string): string {
663
- return v.split('U').map(e => e ? String.fromCharCode(parseInt(e.replace('E', ''))) : '').join('');
664
- }
1
+ import React from 'react';
2
+ import { Form, AutoComplete, Select, Button, Input, Spin, Tooltip } from 'kts-components-antd-x3';
3
+ import { InputProps } from 'kts-components-antd-x3/lib/input';
4
+ import { WrappedFormUtils } from 'kts-components-antd-x3/lib/form/Form';
5
+ import { IGood } from '../../../../../InvoiceController';
6
+ import Invoice from '../../../../..';
7
+ import RowMenu from './ui/RowMenu';
8
+ import TitleText from './ui/TitleText';
9
+ import ItemNameInput from './ui/ItemNameInput';
10
+ import ItemCodeInput from './ui/ItemCodeInput';
11
+ import {
12
+ onChangeQuantity,
13
+ onChangePriceIncludeTax,
14
+ onChangePriceExcludeTax,
15
+ onChangeLineAmountIncludeTax,
16
+ onChangeLineAmountExcludeTax,
17
+ onChangeTaxRate,
18
+ onChangeItemName,
19
+ onChangeItemCode,
20
+ } from './autoFillFn';
21
+ import { getItemNameWithShorthand } from '../../../../../tools/itemName';
22
+ import Drag from './ui/Drag';
23
+
24
+ export default (form: WrappedFormUtils) => {
25
+ const { getFieldDecorator, getFieldValue } = form;
26
+
27
+ const controller = Invoice.useInvoiceController();
28
+
29
+ /** 是否含税 */
30
+ const isTaxIncluded = controller.useMemo(e => e.goodsListState.isTaxIncluded, []);
31
+
32
+ /** 组件模式 */
33
+ const model = controller.useMemo(e => e.model, []);
34
+
35
+ /** 是否启用拖拽 */
36
+ const isStart = controller.useMemo((e) => e.goodsListState.drag.isStart, []);
37
+
38
+ /** 是否显示我方 */
39
+ const isMyShow = controller.useMemo(e => e.goodsListState.isMyShow, []);
40
+
41
+ /** 正在编辑的货物 */
42
+ const editGood = controller.useMemo((e) => e.goodsListState.editGood, []);
43
+
44
+ /** 商品表格隐藏列 */
45
+ const columnshide = controller.useMemo((e) => e.goodsListState.columnshide, []);
46
+
47
+ /** 搜索条件 */
48
+ const searchValue = controller.useMemo((e) => e.goodsListState.searchValue, []);
49
+
50
+ /** 税率列表 */
51
+ const taxRateList = controller.useMemo((e) => e.goodsListState.taxRateList, []);
52
+
53
+ /** 单位列表 */
54
+ const unitList = controller.useMemo((e) => e.goodsListState.unitList, []);
55
+
56
+ /** 商品表格补充配置 */
57
+ const columnsReplenish = controller.useMemo((e) => e.goodsListState.columnsReplenish, []);
58
+
59
+ /** 扣除额 */
60
+ const deduction = controller.useMemo((e) => e.goodsListState.deduction, []);
61
+
62
+ /** 计算中启动字段 */
63
+ const changeField = controller.useMemo((e) => e.calculatingField, []);
64
+
65
+ /** 计算中启动字段 */
66
+ const setChangeField = React.useCallback((value: string) => controller.run(async s => { s.calculatingField = value }), []);
67
+
68
+ const onNumberValueChange = React.useCallback((e) => {
69
+ const value = e?.target?.value;
70
+ if (value) {
71
+ return value.replace(/[^0-9-\.]/g, '');
72
+ }
73
+ }, [])
74
+
75
+ /** 获取补充校验规则 */
76
+ const getReplenishRules = React.useCallback((id: string) => {
77
+ return columnsReplenish[id] ? columnsReplenish[id].rules || [] : []
78
+ }, [columnsReplenish])
79
+
80
+ /** 金额整数位限制,不传默认9位 */
81
+ const priceIntegerDigit = controller.useMemo((e) => e.priceIntegerDigit || 9, []);
82
+
83
+ /** 表头 */
84
+ const columns = React.useMemo(() => {
85
+ return [
86
+ {
87
+ title: ' ',
88
+ key: 'drag',
89
+ width: 40,
90
+ align: 'center',
91
+ render: (_: any, record: IGood) => <Drag record={record} />
92
+ },
93
+ {
94
+ title: '序号',
95
+ key: 'serialNo',
96
+ dataIndex: 'serialNo',
97
+ width: 50,
98
+ render: (e: number) => <span style={{ padding: '0 10px' }}>{e}</span>,
99
+ },
100
+ {
101
+ title: '商品编码',
102
+ key: 'itemCode',
103
+ width: 119,
104
+ render: (_: string, record: IGood) => {
105
+ if (editGood?.$index === record.$index) {
106
+ return (
107
+ <Form.Item>
108
+ {getFieldDecorator('itemCode', {
109
+ initialValue: editGood.itemCode,
110
+ rules: [
111
+ ...getReplenishRules('itemCode'),
112
+ { pattern: /^.{1,19}$/, message: '商品编码长度不能超过19位' },
113
+ ]
114
+ })(
115
+ <ItemCodeInput
116
+ onChange={async () => {
117
+ await onChangeItemCode(controller, form, record);
118
+ await onChangeLineAmountIncludeTax(controller, form, record);
119
+ }}
120
+ />
121
+ )}
122
+ </Form.Item>
123
+ )
124
+ } else {
125
+ return <span style={{ padding: '0 10px' }}>{record.itemCode}</span>
126
+ }
127
+ }
128
+ },
129
+ {
130
+ title: <TitleText required >项目名称</TitleText>,
131
+ key: 'itemName',
132
+ render: (_: string, record: IGood) => {
133
+ if (editGood?.$index === record.$index) {
134
+ return (
135
+ <Form.Item>
136
+ <div style={{ display: 'flex' }} >
137
+ {getFieldDecorator('itemName', {
138
+ initialValue: record.itemName,
139
+ rules: [
140
+ ...getReplenishRules('itemName'),
141
+ {
142
+ validator: async (_, __, callback) => {
143
+ await controller.wait();
144
+ const value = controller.state.goodsListState.editGood;
145
+ if (!value?.itemName && !value?.itemNameSelf) {
146
+ callback('项目名称不能为空');
147
+ } else {
148
+ return;
149
+ }
150
+ }
151
+ }
152
+ ]
153
+ })(
154
+ <ItemNameInput
155
+ shorthand={editGood.shorthand}
156
+ onChange={() => {
157
+ onChangeItemName(controller, form, record);
158
+ }}
159
+ />
160
+ )}
161
+ <div className="kts-invoice-operate-goods-list-able-list-itemName-import">
162
+ {controller.getGoodsList && model !== 'readOnly' && (
163
+ <Tooltip title="点击从商品管理中添加商品信息">
164
+ <Button
165
+ onClick={controller.pipeline(async s => { s.goodsListState.importGoods.isVisibleDrawer = true })}
166
+ type="link"
167
+ icon="plus-circle"
168
+ />
169
+ </Tooltip>
170
+ )}
171
+ </div>
172
+ </div>
173
+ </Form.Item>
174
+ );
175
+ } else {
176
+ return (
177
+ <MyItemNameDiv
178
+ valueT={formatSearch(getItemNameWithShorthand({ shorthand: record.shorthand, full: record.itemNameSelf || '' }), searchValue)}
179
+ valueF={formatSearch(getItemNameWithShorthand({ shorthand: record.shorthand, full: record.itemName || '' }), searchValue)}
180
+ isMyShow={isMyShow}
181
+ />
182
+ )
183
+ }
184
+ },
185
+ },
186
+ {
187
+ title: <TitleText rules={columnsReplenish['itemModelName']?.rules} >规格型号</TitleText>,
188
+ key: 'itemModelName',
189
+ width: 119,
190
+ render: (_: string, record: IGood) => {
191
+ if (editGood?.$index === record.$index) {
192
+ return (
193
+ <Form.Item>
194
+ {getFieldDecorator('itemModelName', {
195
+ initialValue: isMyShow ? editGood.itemModelNameSelf : editGood.itemModelName,
196
+ rules: getReplenishRules('itemModelName'),
197
+ })(
198
+ <MyInput
199
+ onChange={async () => {
200
+ await controller.wait()
201
+ const key = isMyShow ? 'itemModelNameSelf' : 'itemModelName';
202
+ const value = {} as any;
203
+ value[key] = form.getFieldsValue().itemModelName;
204
+ controller.setEditGood(value);
205
+ }}
206
+ />,
207
+ )}
208
+ </Form.Item>
209
+ );
210
+ } else {
211
+ return (
212
+ <MyItemNameDiv
213
+ valueT={formatSearch(record.itemModelNameSelf, searchValue)}
214
+ valueF={formatSearch(record.itemModelName, searchValue)}
215
+ isMyShow={isMyShow}
216
+ />
217
+ )
218
+ }
219
+ },
220
+ },
221
+ {
222
+ title: <TitleText rules={columnsReplenish['unit']?.rules} >单位</TitleText>,
223
+ key: 'unit',
224
+ width: 70,
225
+ render: (_: string, record: IGood) => {
226
+ if (editGood?.$index === record.$index) {
227
+ return (
228
+ <Form.Item>
229
+ {getFieldDecorator('unit', {
230
+ initialValue: editGood.unit,
231
+ rules: getReplenishRules('unit'),
232
+ })(
233
+ <AutoComplete
234
+ style={{ width: '100%' }}
235
+ dataSource={unitList}
236
+ onChange={async () => {
237
+ await controller.wait()
238
+ // const key = isMyShow ? 'unit' : 'unitOther';
239
+ // const value = {} as any;
240
+ // value[key] = form.getFieldsValue().unit;
241
+ controller.setEditGood({ unit: form.getFieldsValue().unit });
242
+ }}
243
+ />,
244
+ )}
245
+ </Form.Item>
246
+ );
247
+ } else {
248
+ return <span style={{ padding: '0 10px' }}>{record.unit}</span>;
249
+ }
250
+ },
251
+ },
252
+ {
253
+ title: <TitleText rules={columnsReplenish['quantity']?.rules} >数量</TitleText>,
254
+ dataIndex: 'quantity',
255
+ key: 'quantity',
256
+ align: 'right',
257
+ width: 149,
258
+ render: (value: string, record: IGood) => {
259
+ if (editGood?.$index === record.$index) {
260
+ return (
261
+ <Form.Item>
262
+ {getFieldDecorator('quantity', {
263
+ initialValue: editGood.quantity,
264
+ getValueFromEvent: onNumberValueChange,
265
+ rules: [
266
+ ...getReplenishRules('quantity'),
267
+ { pattern: /^[+-]?(0|([1-9]\d*))(\.\d+)?$/, message: '数量必须为数字' },
268
+ {
269
+ validator: async (_, value, callback) => {
270
+ await controller.wait();
271
+ const isvalue = !!value || value === 0;
272
+ const isPrice = !!getFieldValue(isTaxIncluded ? 'priceIncludeTax' : 'priceExcludeTax') || getFieldValue(isTaxIncluded ? 'priceIncludeTax' : 'priceExcludeTax') === 0;
273
+ if (isvalue || isPrice === isvalue) return;
274
+ callback('请输入数量');
275
+ }
276
+ }
277
+ ],
278
+ })(
279
+ <MyInput
280
+ style={{ textAlign: 'right' }}
281
+ maxLength={16}
282
+ loading={isCipher(changeField, "quantity")}
283
+ onChange={async () => {
284
+ setChangeField('quantity');
285
+ await onChangeQuantity(controller, form, record);
286
+ }}
287
+ />,
288
+ )}
289
+ </Form.Item>
290
+ );
291
+ } else {
292
+ return <span style={{ padding: '0 10px' }}>{value}</span>;
293
+ }
294
+ },
295
+ },
296
+ {
297
+ title: <TitleText rules={columnsReplenish['priceIncludeTax']?.rules} >单价(含税)</TitleText>,
298
+ dataIndex: 'priceIncludeTax',
299
+ key: 'priceIncludeTax',
300
+ align: 'right',
301
+ width: 149,
302
+ render: (value: string, record: IGood) => {
303
+ if (editGood?.$index === record.$index) {
304
+ return (
305
+ <Form.Item>
306
+ {getFieldDecorator('priceIncludeTax', {
307
+ initialValue: editGood.priceIncludeTax,
308
+ getValueFromEvent: onNumberValueChange,
309
+ rules: [
310
+ ...getReplenishRules('priceIncludeTax'),
311
+ { pattern: /^[+-]?(0|([1-9]\d*))(\.\d+)?$/, message: '单价必须为数字' },
312
+ {
313
+ validator: async (_, value, callback) => {
314
+ await controller.wait();
315
+ const isQuantity = !!getFieldValue('quantity') || getFieldValue('quantity') === 0;
316
+ const isvalue = !!value || value === 0;
317
+ if (isvalue || isQuantity === isvalue) return;
318
+ callback('请输入单价');
319
+ }
320
+ }
321
+ ],
322
+ })(
323
+ <MyInput
324
+ style={{ textAlign: 'right' }}
325
+ maxLength={16}
326
+ loading={isCipher(changeField, 'priceIncludeTax')}
327
+ onChange={() => {
328
+ setChangeField('priceIncludeTax');
329
+ onChangePriceIncludeTax(controller, form, record);
330
+ }}
331
+ />,
332
+ )}
333
+ </Form.Item>
334
+ );
335
+ } else {
336
+ return <span style={{ padding: '0 10px' }}>{value}</span>;
337
+ }
338
+ },
339
+ },
340
+ {
341
+ title: <TitleText rules={columnsReplenish['priceExcludeTax']?.rules} >单价(不含税)</TitleText>,
342
+ dataIndex: 'priceExcludeTax',
343
+ key: 'priceExcludeTax',
344
+ align: 'right',
345
+ width: 149,
346
+ render: (value: string, record: IGood) => {
347
+ if (editGood?.$index === record.$index) {
348
+ return (
349
+ <Form.Item>
350
+ {getFieldDecorator('priceExcludeTax', {
351
+ initialValue: editGood.priceExcludeTax,
352
+ getValueFromEvent: onNumberValueChange,
353
+ rules: [
354
+ ...getReplenishRules('priceExcludeTax'),
355
+ { pattern: /^[+-]?(0|([1-9]\d*))(\.\d+)?$/, message: '单价必须为数字' },
356
+ {
357
+ validator: async (_, value, callback) => {
358
+ await controller.wait();
359
+ const isQuantity = !!getFieldValue('quantity') || getFieldValue('quantity') === 0;
360
+ const isvalue = !!value || value === 0;
361
+ if (isvalue || isQuantity === isvalue) return;
362
+ callback('请输入单价');
363
+ }
364
+ }
365
+ ],
366
+ })(
367
+ <MyInput
368
+ style={{ textAlign: 'right' }}
369
+ maxLength={16}
370
+ loading={isCipher(changeField, 'priceExcludeTax')}
371
+ onChange={() => {
372
+ setChangeField('priceExcludeTax');
373
+ onChangePriceExcludeTax(controller, form, record);
374
+ }}
375
+ />,
376
+ )}
377
+ </Form.Item>
378
+ );
379
+ } else {
380
+ return <span style={{ padding: '0 10px' }}>{value}</span>;
381
+ }
382
+ },
383
+ },
384
+ {
385
+ title: <TitleText required >金额(含税)</TitleText>,
386
+ dataIndex: 'lineAmountIncludeTax',
387
+ key: 'lineAmountIncludeTax',
388
+ width: 119,
389
+ align: 'right',
390
+ render: (value: string, record: IGood) => {
391
+ if (editGood?.$index === record.$index) {
392
+ return (
393
+ <Form.Item>
394
+ {getFieldDecorator('lineAmountIncludeTax', {
395
+ initialValue: editGood.lineAmountIncludeTax,
396
+ getValueFromEvent: onNumberValueChange,
397
+ rules: [
398
+ ...getReplenishRules('lineAmountIncludeTax'),
399
+ { required: true, message: '金额不能为空' },
400
+ { pattern: /^[+-]?(0|([1-9]\d*))(\.\d+)?$/, message: '金额必须为数字' },
401
+ {
402
+ validator: async (_, value, callback) => {
403
+ if (`${value}`.split('.')[0].length > priceIntegerDigit) {
404
+ callback(`金额整数部分不能大于${priceIntegerDigit}位,小数点后最多2位`);
405
+ }
406
+ }
407
+ },
408
+ {
409
+ validator: async (_, value, callback) => {
410
+ if (deduction && parseFloat(value) <= deduction) {
411
+ callback('扣除额不能大于等于价税合计');
412
+ }
413
+ }
414
+ },
415
+ ],
416
+ })(
417
+ <MyInput
418
+ style={{ textAlign: 'right' }}
419
+ loading={isCipher(changeField, 'lineAmountIncludeTax')}
420
+ onChange={() => {
421
+ setChangeField('lineAmountIncludeTax');
422
+ onChangeLineAmountIncludeTax(controller, form, record);
423
+ }}
424
+ />,
425
+ )}
426
+ </Form.Item>
427
+ );
428
+ } else {
429
+ return <span style={{ padding: '0 10px' }}>{formatSearch(parseFloat(value).toFixed(2), searchValue)}</span>;
430
+ }
431
+ },
432
+ },
433
+ {
434
+ title: <TitleText required >金额(不含税)</TitleText>,
435
+ dataIndex: 'lineAmountExcludeTax',
436
+ key: 'lineAmountExcludeTax',
437
+ align: 'right',
438
+ width: 119,
439
+ render: (value: string, record: IGood) => {
440
+ if (editGood?.$index === record.$index) {
441
+ return (
442
+ <Form.Item>
443
+ {getFieldDecorator('lineAmountExcludeTax', {
444
+ initialValue: editGood.lineAmountExcludeTax,
445
+ getValueFromEvent: onNumberValueChange,
446
+ rules: [
447
+ ...getReplenishRules('lineAmountExcludeTax'),
448
+ { required: true, message: '金额不能为空' },
449
+ { pattern: /^[+-]?(0|([1-9]\d*))(\.\d+)?$/, message: '金额必须为数字' },
450
+ {
451
+ validator: async (_, value: string, callback) => {
452
+ if (`${value}`.split('.')[0].length > priceIntegerDigit) {
453
+ callback(`金额整数部分不能大于${priceIntegerDigit}位,小数点后最多2位`);
454
+ }
455
+ }
456
+ },
457
+ ],
458
+ })(
459
+ <MyInput
460
+ style={{ textAlign: 'right' }}
461
+ loading={isCipher(changeField, 'lineAmountExcludeTax')}
462
+ onChange={() => {
463
+ setChangeField('lineAmountExcludeTax');
464
+ onChangeLineAmountExcludeTax(controller, form, record);
465
+ }}
466
+ />,
467
+ )}
468
+ </Form.Item>
469
+ );
470
+ } else {
471
+ return <span style={{ padding: '0 10px' }}>{formatSearch(parseFloat(value).toFixed(2), searchValue)}</span>;
472
+ }
473
+ },
474
+ },
475
+ {
476
+ title: <TitleText required >税率%</TitleText>,
477
+ dataIndex: 'taxRate',
478
+ key: 'taxRate',
479
+ align: 'right',
480
+ width: 70,
481
+ render: (value: string, record: IGood) => {
482
+ if (editGood?.$index === record.$index) {
483
+ return (
484
+ <Form.Item>
485
+ {getFieldDecorator('taxRate', {
486
+ initialValue: editGood.taxRate,
487
+ rules: [
488
+ ...getReplenishRules('taxRate'),
489
+ { required: true, message: ' ' },
490
+ { pattern: /^[+-]?(0|([1-9]\d*))(\.\d+)?$/, message: ' ' },
491
+ ],
492
+ })(
493
+ <Select
494
+ className="kts-invoice-operate-goods-list-table-tax-rate"
495
+ dropdownMenuStyle={{ textAlign: "right" }}
496
+ showArrow={false}
497
+ style={{ width: '100%' }}
498
+ onChange={() => {
499
+ setChangeField('taxRate');
500
+ onChangeTaxRate(controller, form, record);
501
+ }}
502
+ >
503
+ {taxRateList.map((e, i) => {
504
+ return (
505
+ <Select.Option key={i} value={e}>
506
+ {e}%
507
+ </Select.Option>
508
+ );
509
+ })}
510
+ </Select>,
511
+ )}
512
+ </Form.Item>
513
+ );
514
+ } else {
515
+ return <span style={{ padding: '0 10px' }}>{value}%</span>;
516
+ }
517
+ },
518
+ },
519
+ {
520
+ title: <TitleText rules={columnsReplenish['taxAmount']?.rules} >税额</TitleText>,
521
+ dataIndex: 'taxAmount',
522
+ key: 'taxAmount',
523
+ align: 'right',
524
+ width: 119,
525
+ render: (value: string, record: IGood) => {
526
+ if (editGood?.$index === record.$index) {
527
+ return getFieldDecorator('taxAmount', {
528
+ initialValue: editGood.taxAmount,
529
+ rules: getReplenishRules('taxAmount'),
530
+ })(<MyDiv loading={isCipher(changeField, 'taxAmount')} />);
531
+ } else {
532
+ return <span style={{ padding: '0 10px' }}>{parseFloat(value).toFixed(2)}</span>;
533
+ }
534
+ },
535
+ },
536
+ {
537
+ title: '操作',
538
+ key: 'operating',
539
+ align: 'right',
540
+ width: 130,
541
+ fixed: 'right',
542
+ render: (_value: string, record: IGood) => <RowMenu key={record.lineAttribute} goods={record} />,
543
+ },
544
+ ]
545
+ // 筛选隐藏
546
+ .filter(e => {
547
+ return e.key ? columnshide.indexOf(e.key) < 0 : false;
548
+ })
549
+ // 含税不含税
550
+ .filter((e) => {
551
+ if (isTaxIncluded) {
552
+ return !(e.key === 'priceExcludeTax' || e.key === 'lineAmountExcludeTax');
553
+ } else {
554
+ return !(e.key === 'priceIncludeTax' || e.key === 'lineAmountIncludeTax');
555
+ }
556
+ })
557
+ // 是否启动拖拽
558
+ .filter(e => e.key !=='drag' || isStart)
559
+ // 只读
560
+ .filter(e => {
561
+ if (model === 'readOnly') {
562
+ return e.key !== 'operating';
563
+ } else {
564
+ return true;
565
+ }
566
+ })
567
+ .map((e) => {
568
+ return {
569
+ ...e,
570
+ ellipsis: true,
571
+ };
572
+ }) as any[];
573
+ }, [isTaxIncluded, editGood, controller, changeField, deduction, isMyShow, searchValue, model, columnsReplenish, columnshide, isStart]);
574
+ return columns;
575
+ };
576
+
577
+ /** 字段 */
578
+ function isCipher(name?: string, field?: string) {
579
+ if (!name || !field) return false;
580
+ return name !== field;
581
+ }
582
+
583
+ class MyInput extends React.Component<InputProps & { loading?: boolean }> {
584
+ render() {
585
+ if (this.props.loading) {
586
+ return (
587
+ <Spin size="small">
588
+ <Input {...this.props} autoComplete="off" />
589
+ </Spin>
590
+ )
591
+ } else {
592
+ return <Input {...this.props} autoComplete="off" />
593
+ }
594
+ }
595
+ }
596
+
597
+ class MyDiv extends React.Component<{ value?: any, loading?: boolean }> {
598
+ render() {
599
+ if (this.props.loading) {
600
+ return (
601
+ <Spin size="small">
602
+ <span style={{ padding: '0 10px' }}>{this.props.value}</span>
603
+ </Spin>
604
+ )
605
+ } else {
606
+ return <span style={{ padding: '0 10px' }}>{this.props.value}</span>
607
+ }
608
+ }
609
+ }
610
+
611
+ class MyItemNameDiv extends React.Component<{ valueT?: React.ReactNode, valueF?: React.ReactNode, isMyShow: boolean }> {
612
+ render(): React.ReactNode {
613
+
614
+ const { isMyShow, valueT, valueF } = this.props;
615
+
616
+ if (isMyShow) {
617
+ if (valueT) {
618
+ return (
619
+ <Tooltip title={valueT}>
620
+ <span style={{ padding: '0 10px', color: '#0074ff' }}>{valueT}</span>
621
+ </Tooltip>
622
+ )
623
+ } else {
624
+ return (
625
+ <Tooltip title={valueF}>
626
+ <span style={{ padding: '0 10px' }}>{valueF}</span>
627
+ </Tooltip>
628
+ )
629
+ }
630
+ } else {
631
+ if (valueF) {
632
+ return (
633
+ <Tooltip title={valueF}>
634
+ <span style={{ padding: '0 10px' }}>{valueF}</span>
635
+ </Tooltip>
636
+ )
637
+ } else {
638
+ return (
639
+ <Tooltip title={valueT}>
640
+ <span style={{ padding: '0 10px', color: '#0074ff' }}>{valueT}</span>
641
+ </Tooltip>
642
+ )
643
+ }
644
+ }
645
+ }
646
+ }
647
+
648
+ /** 格式搜索结果 */
649
+ function formatSearch(value?: string, search?: string) {
650
+ if (!value || !search) return value;
651
+
652
+ const __html = ucoding(value).split(new RegExp(ucoding(search), 'g')).map(e => dcoding(e)).join(`<span class="kts-invoice-operate-goods-list-table-search-protrude" >${search}</span>`);
653
+ return <span dangerouslySetInnerHTML={{ __html }} />
654
+ }
655
+
656
+ /** 编码 */
657
+ function ucoding(v: string): string {
658
+ return v.split('').map(e => `U${e.charCodeAt(0)}E`).join('');
659
+ }
660
+
661
+ /** 解码 */
662
+ function dcoding(v: string): string {
663
+ return v.split('U').map(e => e ? String.fromCharCode(parseInt(e.replace('E', ''))) : '').join('');
664
+ }