kts-component-invoice-operate 3.2.98 → 3.2.99

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