kts-component-invoice-operate 4.0.1 → 4.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,77 @@
1
+ import React from 'react';
2
+ import Invoice from '../../..';
3
+ import moment from 'moment';
4
+ import 'antd/dist/antd.css';
5
+ import { Button } from 'kts-components-antd-x3';
6
+ import idGenerator from '../../../../Invoice/tools/idGenerator';
7
+ export default () => {
8
+
9
+ const controller = React.useMemo(() => new Invoice.InvoiceController(), []);
10
+ const a = [
11
+ {
12
+ "lineNumber": 1,
13
+ "realEstateAddress": [
14
+ "安徽省合肥市庐江县"
15
+ ],
16
+ "realEstateDetailedAddress": "安徽省合肥市庐江县周瑜大道1号",
17
+ leaseTerm: [moment('20250205'), moment('20250228')],
18
+ "leaseTermStart": "20250205",
19
+ "leaseTermEnd": "20250228",
20
+ "crossCitiesSign": "N",
21
+ "realEstateNumber": "BDCZL100001",
22
+ "unit": "平方米",
23
+ "$index": 0,
24
+ "realEstateUnit": "平方米"
25
+ }
26
+ ]
27
+ const b: any = [
28
+ {
29
+ $index: idGenerator(),
30
+ "serialNumber": "1886972176113950720",
31
+ "lineNumber": 1,
32
+ "taxCode": "3040501030000000000",
33
+ "taxName": "融资租赁",
34
+ "specification": "",
35
+ "itemName": "不动产租赁服务",
36
+ "unit": "幢",
37
+ "quantity": "1",
38
+ "taxRate": 0.09,
39
+ "priceExcludeTax": "9174.31",
40
+ "priceIncludeTax": "10000",
41
+ "amountTax": 825.69,
42
+ "amountExcludeTax": 9174.31,
43
+ "amountIncludeTax": 10000,
44
+ "lineAttribute": 0,
45
+ "favouredPolicyMark": false,
46
+ "ticketLineNumber": "1"
47
+ }
48
+ ]
49
+ React.useEffect(() => {
50
+ // controller.run(async s => {
51
+ // s.goodsListState.goodsList = b;
52
+
53
+ // })
54
+ // controller.run(async s => {
55
+ // window.setTimeout(() => {
56
+ // controller.formList.get('realEstateInfo')?.setFieldsValue({
57
+ // realEstateDataDto: a
58
+ // })
59
+ // }, 1000)
60
+
61
+ // })
62
+ }, [])
63
+ const onSave = async () => {
64
+ const formValues = await controller.validateFields();
65
+ console.log(formValues)
66
+ }
67
+ return (
68
+ <>
69
+ <Button onClick={onSave}>输出表单内容</Button>
70
+ <Invoice
71
+ invoiceType='digtal'
72
+ controller={controller}
73
+ specialInfor={<Invoice.RealEstateSales />}
74
+ />
75
+ </>
76
+ )
77
+ };
@@ -3,8 +3,12 @@
3
3
  <!-- ## 简单用法
4
4
  <code src="./_test/easiest/index.tsx"></code> -->
5
5
 
6
- ## 不动产经营租赁服务
7
- <code src="./_test/realEstateInfo/index.tsx"></code>
6
+ <!-- ## 不动产经营租赁服务
7
+ <code src="./_test/realEstateInfo/index.tsx"></code> -->
8
+
9
+ ## 不动产销售
10
+ <code src="./_test/realEstateSales/index.tsx"></code>
11
+
8
12
 
9
13
  <!-- ## 建筑服务
10
14
  <code src="./_test/architecture/index.tsx"></code> -->
@@ -19,6 +19,7 @@ import StakeFarmerholder from './ui/digtal/StakeFarmerholder';
19
19
  import SignDigtal from './ui/digtal/Sign';
20
20
  import GoodsListDigtal from './ui/digtal/GoodsList';
21
21
  import RealEstateInfo from './ui/digtal/RealEstateInfo';
22
+ import RealEstateSales from './ui/digtal/RealEstateSales';
22
23
  import Architecture from './ui/digtal/Architecture';
23
24
  import FreightList from './ui/digtal/FreightList';
24
25
 
@@ -105,6 +106,9 @@ export default class Invoice extends React.PureComponent<IInvoiceProps> {
105
106
  /** 特殊信息-不动产经营租赁服务(数电) */
106
107
  static readonly RealEstateInfo = RealEstateInfo;
107
108
 
109
+ /** 特殊信息-不动产销售(数电) */
110
+ static readonly RealEstateSales = RealEstateSales;
111
+
108
112
  /** 特殊信息-建筑服务(数电) */
109
113
  static readonly Architecture = Architecture;
110
114
 
@@ -48,18 +48,19 @@ export default decorator<RealEstateInfoProps, FormComponentProps & RealEstateInf
48
48
  indexRef.current = dd;
49
49
  }, [goodsList, indexRef])
50
50
  // 注册 form
51
+
51
52
  controller.useForm('realEstateInfo', form);
52
53
  const getList = () => {
53
54
  const decrease = indexRef.current.length > goodsList.length
54
55
  if (decrease) {
55
56
  //已删行列表
56
57
  const diff = indexRef.current.filter((item: any) => !goodsList.find(i => i.$index === item));
57
-
58
+
58
59
  const formData: any[] = form.getFieldValue('realEstateDataDto');
59
60
  if (Array.isArray(formData) && diff.length > 0) {
60
-
61
+
61
62
  const newForm = formData?.filter(item => !diff.find((i: any) => i === item.$index));
62
-
63
+
63
64
  form.setFieldsValue({
64
65
  realEstateDataDto: newForm
65
66
  });
@@ -68,7 +69,9 @@ export default decorator<RealEstateInfoProps, FormComponentProps & RealEstateInf
68
69
  realEstateDataDto: undefined
69
70
  });
70
71
  }
71
- }
72
+ }
73
+ console.log(form.getFieldsValue())
74
+ console.log('goodsList',goodsList)
72
75
  return goodsList.map((item, index) => {
73
76
  if (item.lineAttribute === 0) {
74
77
  return <Row gutter={[17, 0]} >
@@ -88,14 +91,8 @@ export default decorator<RealEstateInfoProps, FormComponentProps & RealEstateInf
88
91
  ? (<MyArrString />)
89
92
  : (<Cascader
90
93
  style={{ width: '100%' }}
91
- options={[{
92
- "name": "北京市",
93
- }] || props.realEstateAddressOptions}
94
- fieldNames={{
95
- label: 'name',
96
- value: 'name',
97
- children: 'children'
98
- } || props.realEstateAddressFieldNames}
94
+ options={props.realEstateAddressOptions}
95
+ fieldNames={props.realEstateAddressFieldNames}
99
96
  placeholder="请选择省市区县"
100
97
  />)
101
98
  )}
@@ -193,7 +190,7 @@ export default decorator<RealEstateInfoProps, FormComponentProps & RealEstateInf
193
190
  <div className="kts-invoice-operate-real-estate-info-digtal">
194
191
  <div className='real-estate-info-digtal-label' >特殊信息-不动产经营租赁服务</div>
195
192
  {getList()}
196
-
193
+
197
194
  </div>
198
195
  )
199
196
  })
@@ -0,0 +1,22 @@
1
+ .kts-invoice-operate-real-estate-info-digtal {
2
+ padding : 20px;
3
+ border-bottom: 2px solid #9F613E;
4
+ border-left : 2px solid #9F613E;
5
+ border-right : 2px solid #9F613E;
6
+
7
+ .real-estate-info-digtal-label {
8
+ color : #9F613E;
9
+ font-weight: bold;
10
+ }
11
+
12
+ .ktsAnt3x-row.ktsAnt3x-form-item {
13
+ margin-bottom: 0;
14
+ }
15
+ .ktsAntX-row{
16
+ border-bottom: 1px dashed #9F613E;
17
+ &:last-child {
18
+ border-bottom: none;
19
+ }
20
+ }
21
+
22
+ }
@@ -0,0 +1,301 @@
1
+
2
+ import React, { useEffect } from "react";
3
+ import { decorator } from 'grey-react-box';
4
+ import { Form } from 'kts-components-antd-x3';
5
+ import { FormComponentProps } from 'kts-components-antd-x3/lib/form';
6
+ import Invoice from '../../..';
7
+ import './index.less';
8
+ import { Cascader, Col, DatePicker, Input, Row, Select } from "kts-components-antd-x4";
9
+ import moment from "moment";
10
+
11
+ const { RangePicker } = DatePicker;
12
+
13
+ export interface RealEstateInfoProps {
14
+ /**
15
+ * 不动产地址数据
16
+ */
17
+ realEstateAddressOptions?: any[];
18
+
19
+ /**
20
+ * 不动产地址数据字段名
21
+ */
22
+ realEstateAddressFieldNames?: any;
23
+ }
24
+
25
+ /** 特殊信息-不动产销售 */
26
+ export default decorator<RealEstateInfoProps, FormComponentProps & RealEstateInfoProps>(Form.create())(props => {
27
+
28
+ /** 控制器 */
29
+ const controller = Invoice.useInvoiceController();
30
+
31
+ const { form } = props;
32
+
33
+ const { getFieldDecorator } = form;
34
+
35
+ const model = controller.useMemo(s => s.model, []);
36
+
37
+ const readOnly = React.useMemo(() => model === 'readOnly', [model]);
38
+
39
+ const goodsList = controller.useMemo(s => s.goodsListState.goodsList, []);
40
+ const indexRef = React.useRef<any>([]);
41
+ useEffect(() => {
42
+ const dd = goodsList?.reduce((acc: any, cur: any) => {
43
+ if (cur.lineAttribute === 0) {
44
+ acc.push(cur.$index)
45
+ }
46
+ return acc
47
+ }, [])
48
+ indexRef.current = dd;
49
+ }, [goodsList, indexRef])
50
+ // 注册 form
51
+
52
+ controller.useForm('realEstateSales', form);
53
+ const getList = () => {
54
+ const decrease = indexRef.current.length > goodsList.length
55
+ if (decrease) {
56
+ //已删行列表
57
+ const diff = indexRef.current.filter((item: any) => !goodsList.find(i => i.$index === item));
58
+
59
+ const formData: any[] = form.getFieldValue('realEstateDataDto');
60
+ if (Array.isArray(formData) && diff.length > 0) {
61
+
62
+ const newForm = formData?.filter(item => !diff.find((i: any) => i === item.$index));
63
+
64
+ form.setFieldsValue({
65
+ realEstateDataDto: newForm
66
+ });
67
+ } else {
68
+ form.setFieldsValue({
69
+ realEstateDataDto: undefined
70
+ });
71
+ }
72
+ }
73
+ return goodsList.map((item, index) => {
74
+ if (item.lineAttribute === 0) {
75
+ return <Row gutter={[17, 0]} >
76
+ <Col span={6} >
77
+ <Form.Item label='不动产单元代码' >
78
+ {getFieldDecorator(`realEstateDataDto[${index}].unitCode`, {
79
+ rules: readOnly ? [] : []
80
+ })(
81
+ readOnly
82
+ ? <MyNY />
83
+ : <Input autoComplete='off' />
84
+ )}
85
+ </Form.Item>
86
+ </Col>
87
+ <Col span={6} >
88
+ <Form.Item label='网签合同备案编号' >
89
+ {getFieldDecorator(`realEstateDataDto[${index}].contractNumber`, {
90
+ rules: readOnly ? [] : []
91
+ })(
92
+ readOnly
93
+ ? <MyNY />
94
+ : <Input autoComplete='off' />
95
+ )}
96
+ </Form.Item>
97
+ </Col>
98
+ <Col span={6} >
99
+ <Form.Item style={{ display: 'none' }}>
100
+ {getFieldDecorator(`realEstateDataDto[${index}].$index`, {
101
+ initialValue: item.$index,
102
+ })(
103
+ <Input />
104
+ )}
105
+ </Form.Item>
106
+ {/* <Col span={6} >
107
+ <Form.Item label='不动产单元代码/网签合同备案编号' >
108
+ {getFieldDecorator(`realEstateDataDto[${index}].type`, {
109
+ rules: readOnly ? [] : []
110
+ })(
111
+ readOnly
112
+ ? <MyNY />
113
+ : <Select placeholder='请选择' style={{ width: '100%' }} >
114
+ <Select.Option value='unitCode'>不动产单元代码</Select.Option>
115
+ <Select.Option value='contractNumber'>网签合同备案编号</Select.Option>
116
+ </Select>
117
+ )}
118
+ </Form.Item>
119
+ </Col> */}
120
+
121
+ <Form.Item label='不动产地址'>
122
+ {getFieldDecorator(`realEstateDataDto[${index}].realEstateAddress`, {
123
+ rules: readOnly ? [] : [{ required: true, message: '请选择不动产地址' }]
124
+ })(
125
+ readOnly
126
+ ? (<MyArrString />)
127
+ : (<Cascader
128
+ style={{ width: '100%' }}
129
+ options={props.realEstateAddressOptions}
130
+ fieldNames={props.realEstateAddressFieldNames}
131
+ placeholder="请选择省市区县"
132
+ />)
133
+ )}
134
+ </Form.Item>
135
+ </Col>
136
+ <Col span={6} >
137
+ <Form.Item label='详细地址' >
138
+ {getFieldDecorator(`realEstateDataDto[${index}].realEstateDetailedAddress`, {
139
+ rules: readOnly ? [] : [
140
+ { required: true, message: '请输入详细地址' },
141
+ { max: 120, message: '详细地址最多120个字符' },
142
+ {
143
+ validator: async (_, value, callback) => {
144
+ const pattern = /街|路|村|乡|镇|道|巷|号/;
145
+ if (pattern.test(value)) {
146
+ callback()
147
+ } else {
148
+ callback('地址必须包含“街”、“路”、“村”、“乡”、“镇”、“道”、“巷”、“号”等任意一个关键词')
149
+ }
150
+ }
151
+ }
152
+ ]
153
+ })(
154
+ readOnly
155
+ ? <MyDiv />
156
+ : <Input autoComplete='off' placeholder="请输入详细地址" />
157
+ )}
158
+ </Form.Item>
159
+ </Col>
160
+ <Col span={6} >
161
+ <Form.Item label='跨地(市)标志' >
162
+ {getFieldDecorator(`realEstateDataDto[${index}].crossCitiesSign`, {
163
+ rules: readOnly ? [] : [
164
+ { required: true, message: '请选择跨地(市)标志' }
165
+ ]
166
+ })(
167
+ readOnly
168
+ ? <MyNY />
169
+ : <Select placeholder='请选择' style={{ width: '100%' }} >
170
+ <Select.Option value='Y'>是</Select.Option>
171
+ <Select.Option value='N'>否</Select.Option>
172
+ </Select>
173
+ )}
174
+ </Form.Item>
175
+ </Col>
176
+ <Col span={6} >
177
+ <Form.Item label='土地增值税项目编号' >
178
+ {getFieldDecorator(`realEstateDataDto[${index}].landTaxProjNo`, {
179
+ rules: readOnly ? [] : []
180
+ })(
181
+ readOnly
182
+ ? <MyArrMoment />
183
+ : <Input autoComplete='off' />
184
+ )}
185
+ </Form.Item>
186
+ </Col>
187
+ <Col span={6} >
188
+ <Form.Item label='核定计税价格' >
189
+ {getFieldDecorator(`realEstateDataDto[${index}].approvedTaxableAmount`, {
190
+ rules: readOnly ? [] : []
191
+ })(
192
+ readOnly
193
+ ? <MyArrMoment />
194
+ : <Input autoComplete='off' type="number" />
195
+ )}
196
+ </Form.Item>
197
+ </Col>
198
+ <Col span={6} >
199
+ <Form.Item label='实际成交含税金额' >
200
+ {getFieldDecorator(`realEstateDataDto[${index}].tradedIncludeAmount`, {
201
+ rules: readOnly ? [] : []
202
+ })(
203
+ readOnly
204
+ ? <MyArrMoment />
205
+ : <Input autoComplete='off' type="number" />
206
+ )}
207
+ </Form.Item>
208
+ </Col>
209
+
210
+ <Col span={6} >
211
+ <Form.Item label='房屋产权证书/不动产权证号' >
212
+ {getFieldDecorator(`realEstateDataDto[${index}].realEstateNumber`, {
213
+ rules: readOnly ? [] : [
214
+
215
+ { max: 40, message: '证书编号最多40个字符' },
216
+ ]
217
+ })(
218
+ readOnly
219
+ ? <MyDiv />
220
+ : <Input autoComplete='off' />
221
+ )}
222
+ </Form.Item>
223
+ </Col>
224
+ <Col span={6} >
225
+ <Form.Item label='面积单位' >
226
+ {getFieldDecorator(`realEstateDataDto[${index}].realEstateUnit`, {
227
+ rules: readOnly ? [] : [{ required: true, message: '请选择面积单位' }]
228
+ })(
229
+ readOnly
230
+ ? <MyDiv />
231
+ : <Select placeholder='请选择' style={{ width: '100%' }} >
232
+ <Select.Option value="平方千米">平方千米</Select.Option>
233
+ <Select.Option value="平方米">平方米</Select.Option>
234
+ <Select.Option value="公顷">公顷</Select.Option>
235
+ <Select.Option value="亩">亩</Select.Option>
236
+ <Select.Option value="h㎡">h㎡</Select.Option>
237
+ <Select.Option value="k㎡">k㎡</Select.Option>
238
+ <Select.Option value="㎡">㎡</Select.Option>
239
+ </Select>
240
+ )}
241
+ </Form.Item>
242
+ </Col>
243
+ </Row>
244
+ }
245
+ })
246
+ }
247
+ return (
248
+ <div className="kts-invoice-operate-real-estate-info-digtal">
249
+ <div className='real-estate-info-digtal-label' >特殊信息-不动产销售</div>
250
+ {getList()}
251
+
252
+ </div>
253
+ )
254
+ })
255
+
256
+ class MyDiv extends React.Component<{ value?: string, style?: React.CSSProperties }> {
257
+ render(): React.ReactNode {
258
+ return (
259
+ <div style={this.props.style}>{this.props.value}</div>
260
+ )
261
+ }
262
+ }
263
+
264
+ class MyArrString extends React.Component<{ value?: string[], style?: React.CSSProperties }> {
265
+ render(): React.ReactNode {
266
+ return (
267
+ <div style={this.props.style}>
268
+ {
269
+ this.props.value?.filter(e => !!e)
270
+ .join(',')
271
+ }
272
+ </div>
273
+ )
274
+ }
275
+ }
276
+
277
+ class MyArrMoment extends React.Component<{ value?: moment.Moment[], style?: React.CSSProperties }> {
278
+ render(): React.ReactNode {
279
+ const { value = [] } = this.props
280
+ return (
281
+ <div style={this.props.style}>
282
+ <span>{moment.isMoment(value[0]) && value[0].format('YYYY-MM-DD')}</span>
283
+ <span style={{ color: '#9F603D', fontWeight: 600 }} > - </span>
284
+ <span>{moment.isMoment(value[1]) && value[0].format('YYYY-MM-DD')}</span>
285
+ </div>
286
+ )
287
+ }
288
+ }
289
+
290
+ class MyNY extends React.Component<{ value?: 'Y' | 'N', style?: React.CSSProperties }> {
291
+ render(): React.ReactNode {
292
+ return (
293
+ <div style={this.props.style}>
294
+ {
295
+ this.props.value === 'Y' ? '是' : '否'
296
+ }
297
+ </div>
298
+ )
299
+ }
300
+ }
301
+