kts-component-invoice-operate 1.1.8 → 1.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kts-component-invoice-operate",
3
- "version": "1.1.8",
3
+ "version": "1.2.2",
4
4
  "scripts": {
5
5
  "start": "dumi dev",
6
6
  "docs:build": "dumi build",
@@ -16,6 +16,27 @@ export interface IFormItem {
16
16
  options: GetFieldDecoratorOptions;
17
17
  }
18
18
 
19
+ export interface IBuyerInfo {
20
+ /** 购买方名称 */
21
+ buyerName?: string;
22
+
23
+ /** 购买方纳税人识别号 */
24
+ buyerNo?: string;
25
+
26
+ /** 购买方地址及电话 */
27
+ buyerAddress?: string;
28
+
29
+ /** 购买方开户行及账号 */
30
+ buyerBank?: string;
31
+ }
32
+
33
+ /** 自动填充 */
34
+ export interface IAutoContainer {
35
+
36
+ /** 购买方变化 */
37
+ onBuyNameChange: (e?: string) => Promise<{ recent: IBuyerInfo[], list: IBuyerInfo[] }>;
38
+ }
39
+
19
40
  export default class BuyerState {
20
41
 
21
42
  /** 表头 */
@@ -61,4 +82,7 @@ export default class BuyerState {
61
82
 
62
83
  /** 顶部扩展 */
63
84
  topExpand?: React.ReactNode;
85
+
86
+ /** 自动填充 */
87
+ autoContainer?: IAutoContainer;
64
88
  }
@@ -0,0 +1,37 @@
1
+ import { thomsonCrossSectionDependencies } from 'mathjs';
2
+ import React from 'react';
3
+ import { Invoice } from '../../../';
4
+
5
+ export default () => {
6
+
7
+ const controller = React.useMemo(() => new MyController(), [])
8
+
9
+ return (
10
+ <Invoice controller={controller} />
11
+ );
12
+ };
13
+
14
+ class MyController extends Invoice.InvoiceController {
15
+ constructor() {
16
+ super()
17
+ this.state.buyerState.autoContainer = {
18
+ onBuyNameChange: async (e?: string) => {
19
+ await this.wait(2000);
20
+ return {
21
+ recent: [
22
+ { buyerName: '中科讯联科技北京网络有限公司', buyerAddress: '918273829182918291' },
23
+ { buyerName: '中科讯联科技北京网络有限公司', buyerAddress: '918273829182918291' },
24
+ { buyerName: '中科讯联科技北京网络有限公司', buyerAddress: '918273829182918291' },
25
+ ],
26
+ list: [
27
+ { buyerName: '中科讯联科技北京网络有限公司', buyerAddress: '918273829182918291' },
28
+ { buyerName: '中科讯联科技北京网络有限公司', buyerAddress: '918273829182918291' },
29
+ { buyerName: '中科讯联科技北京网络有限公司', buyerAddress: '918273829182918291' },
30
+ { buyerName: '中科讯联科技北京网络有限公司', buyerAddress: '918273829182918291' },
31
+ { buyerName: '中科讯联科技北京网络有限公司', buyerAddress: '918273829182918291' },
32
+ ],
33
+ }
34
+ }
35
+ }
36
+ }
37
+ }
@@ -65,21 +65,6 @@ class MyController1 extends Invoice.InvoiceController {
65
65
  console.log('===> 准备赋码的货物索引列表', s.goodsListState.endowCode.endowcodeGoodIndex);
66
66
 
67
67
  s.goodsListState.endowCode.getTaxCategoryCodeTree = async (value) => {
68
- // console.log('===>搜索条件', value);
69
- // return [
70
- // { label: '3040201990000000000/aaa/bbb', id: '3040201990000000000', pid: '0', taxRate: 3, shorthand: 'aaa' },
71
- // { label: '3040201990000000001/aaa/bbb', id: '3040201990000000001', pid: '3040201990000000000', taxRate: 3, shorthand: 'aaa' },
72
- // { label: '3040201990000000002/aaa/bbb', id: '3040201990000000002', pid: '3040201990000000000', taxRate: 3, shorthand: 'aaa' },
73
- // { label: '3040201990000000003/aaa/bbb', id: '3040201990000000003', pid: '3040201990000000000', taxRate: 3, shorthand: 'aaa' },
74
- // { label: '3040201990000000004/aaa/bbb', id: '3040201990000000004', pid: '3040201990000000000', taxRate: 3, shorthand: 'aaa' },
75
- // { label: '3040201990000000005/aaa/bbb', id: '3040201990000000005', pid: '3040201990000000000', taxRate: 3, shorthand: 'aaa' },
76
- // { label: '3040201990000000006/aaa/bbb', id: '3040201990000000006', pid: '3040201990000000000', taxRate: 3, shorthand: 'aaa' },
77
- // { label: '3040201990000000007/aaa/bbb', id: '3040201990000000007', pid: '3040201990000000000', taxRate: 3, shorthand: 'aaa' },
78
- // { label: '3040201990000000008/aaa/bbb', id: '3040201990000000008', pid: '3040201990000000000', taxRate: 3, shorthand: 'aaa' },
79
- // { label: '3040201990000000009/aaa/bbb', id: '3040201990000000009', pid: '3040201990000000000', taxRate: 3, shorthand: 'aaa' },
80
- // { label: '3040201990000000010/aaa/bbb', id: '3040201990000000010', pid: '3040201990000000000', taxRate: 3, shorthand: 'aaa' },
81
- // { label: '3040201990000000011/aaa/bbb', id: '3040201990000000011', pid: '3040201990000000000', taxRate: 3, shorthand: 'aaa' },
82
- // ]
83
68
  return moke.map(e => {
84
69
  return {
85
70
  label: `${e.taxCategoryCode}-${e.shorthand}`,
@@ -6,6 +6,9 @@
6
6
  ## 设置为草稿,设置默认参数 扩展按钮
7
7
  <code src="./_test/draft/index.tsx" title="类似的操作,请查看API" ></code>
8
8
 
9
+ ## 设置购买方名称搜索
10
+ <code src="./_test/buyerNameSearch/index.tsx"></code>
11
+
9
12
  ## 设置扣除额(差额征税)
10
13
  <code src="./_test/deduction/index.tsx"></code>
11
14
 
@@ -75,7 +75,7 @@ const Main = (props: IInvoiceProps) => {
75
75
 
76
76
  const controller = React.useMemo(() => props.controller || new InvoiceController(), [props.controller]);
77
77
 
78
- const [key, setKey] = React.useState(0)
78
+ const [key, setKey] = React.useState(0);
79
79
 
80
80
  React.useEffect(() => {
81
81
  setKey(key + 1);
@@ -84,11 +84,11 @@ const Main = (props: IInvoiceProps) => {
84
84
  return (
85
85
  <InvoiceContext.Provider key={key} value={controller}>
86
86
  <div className="kts-invoice-operate">
87
- {props.invoiceHeader || <InvoiceHeader /> /** 发票头 */}
88
- {props.buyer || <Buyer /> /** 购买方 */}
89
- {props.goodsList || <GoodsList /> /** 货物列表 */}
90
- {props.seller || <Seller /> /** 销售方 */}
91
- {props.sign || <Sign /> /** 落款 */}
87
+ {props.invoiceHeader || <InvoiceHeader /> /** 发票头 */}
88
+ {props.buyer || <Buyer /> /** 购买方 */}
89
+ {props.goodsList || <GoodsList /> /** 货物列表 */}
90
+ {props.seller || <Seller /> /** 销售方 */}
91
+ {props.sign || <Sign /> /** 落款 */}
92
92
  {props.footExpand}
93
93
  </div>
94
94
 
@@ -2,8 +2,8 @@
2
2
  display: flex;
3
3
 
4
4
  .kts-invoice-operate-buyer-message {
5
- flex: 1;
6
- display: flex;
5
+ flex : 1;
6
+ display : flex;
7
7
  position: relative;
8
8
 
9
9
  .ktsAnt3x-descriptions-item-label {
@@ -18,37 +18,37 @@
18
18
  }
19
19
 
20
20
  .ktsAnt3x-descriptions-item-label {
21
- padding: 0 10px;
22
- font-size: 12px;
21
+ padding : 0 10px;
22
+ font-size : 12px;
23
23
  background-color: #fff;
24
- line-height: 30px;
24
+ line-height : 30px;
25
25
  }
26
26
 
27
27
  .ktsAnt3x-descriptions-item-content {
28
28
  padding: 0;
29
29
 
30
30
  .ktsAnt3x-input {
31
- box-shadow: none;
32
- border-color: #fff;
31
+ box-shadow : none;
32
+ border-color : #fff;
33
33
  border-radius: 0;
34
- padding: 0 10px;
35
- font-size: 12px;
36
- line-height: 30px;
37
- width: 100%;
38
- height: 100%;
34
+ padding : 0 10px;
35
+ font-size : 12px;
36
+ line-height : 30px;
37
+ width : 100%;
38
+ height : 100%;
39
39
  }
40
40
 
41
41
  .ktsAnt3x-input:hover {
42
- border: 1 solid;
43
- border-color: #40a9ff;
42
+ border : 1 solid;
43
+ border-color : #40a9ff;
44
44
  border-right-width: 1px !important;
45
45
  }
46
46
 
47
47
  .has-error .ktsAnt3x-input,
48
48
  .has-error .ktsAnt3x-input:hover {
49
49
  background-color: #fff;
50
- border: 1 solid;
51
- border-color: #f5222d;
50
+ border : 1 solid;
51
+ border-color : #f5222d;
52
52
  }
53
53
  }
54
54
 
@@ -61,7 +61,7 @@
61
61
  }
62
62
 
63
63
  .ktsAnt3x-form-item-children {
64
- height: 30px;
64
+ height : 30px;
65
65
  display: block;
66
66
 
67
67
  .ktsAnt3x-btn {
@@ -71,39 +71,140 @@
71
71
 
72
72
  .ktsAnt3x-form-explain {
73
73
  position: absolute;
74
- left: 5px;
75
- top: 6px;
76
- z-index: 10;
74
+ left : 5px;
75
+ top : 6px;
76
+ z-index : 10;
77
77
  }
78
78
  }
79
79
 
80
80
  .kts-invoice-operate-buyer-message-Import {
81
81
  position: absolute;
82
- right: 0px;
83
- top: 0px;
84
- z-index: 10;
82
+ right : 0px;
83
+ top : 0px;
84
+ z-index : 10;
85
85
  }
86
86
  }
87
87
 
88
88
  .kts-invoice-operate-buyer-password {
89
89
  border-left: 1px solid #dcdcdc;
90
- display: flex;
91
- flex: none;
92
- width: 458px;
90
+ display : flex;
91
+ flex : none;
92
+ width : 458px;
93
93
  }
94
94
 
95
95
  .kts-invoice-operate-buyer-title {
96
- flex: none;
97
- width: 30px;
98
- height: 100%;
99
- text-align: center;
96
+ flex : none;
97
+ width : 30px;
98
+ height : 100%;
99
+ text-align : center;
100
100
  border-right: 1px solid #dcdcdc;
101
- display: table;
102
- padding: 0 5px;
101
+ display : table;
102
+ padding : 0 5px;
103
103
 
104
104
  label {
105
- display: table-cell;
105
+ display : table-cell;
106
106
  vertical-align: middle;
107
107
  }
108
108
  }
109
109
  }
110
+
111
+ .ktsAnt3x-popover.kts-invoice-operate-buyer-name-popover {
112
+ padding-top: 0;
113
+
114
+ .ktsAnt3x-popover-inner-content {
115
+ padding : 6px 0;
116
+ display : flex;
117
+ flex-direction: column;
118
+ max-height : 400px;
119
+ overflow-y : auto;
120
+ overflow-x : hidden;
121
+ }
122
+
123
+ .ktsAnt3x-popover-arrow {
124
+ display: none;
125
+ }
126
+
127
+ .kts-invoice-operate-buyer-name-content {
128
+ width: 567px;
129
+
130
+
131
+ .kts-invoice-operate-buyer-name-content-block {
132
+ padding: 14px 0;
133
+
134
+ label {
135
+ display : block;
136
+ font-size: 12px;
137
+ color : #666666;
138
+ }
139
+ }
140
+
141
+ .kts-invoice-operate-buyer-name-content-recently-issued {
142
+ padding: 0;
143
+ margin : 0;
144
+
145
+ li {
146
+ list-style : none;
147
+ width : 50%;
148
+ float : left;
149
+ margin-bottom: 20px;
150
+ }
151
+
152
+ &::after {
153
+ content : ".";
154
+ display : block;
155
+ height : 0;
156
+ clear : left;
157
+ visibility: hidden;
158
+ }
159
+ }
160
+
161
+ .kts-invoice-operate-buyer-name-content-select-company {
162
+ padding : 0;
163
+ margin : 0;
164
+ font-size : 12px;
165
+ padding : 10px;
166
+ font-weight: bold;
167
+ color : #000000;
168
+ cursor : pointer;
169
+ transition : background .4s;
170
+
171
+ &:hover {
172
+ background: #e6e6e6e6;
173
+ }
174
+
175
+ &:last-child {
176
+ margin-bottom: 0;
177
+ }
178
+
179
+ li {
180
+ list-style: none;
181
+ width : 50%;
182
+ float : left;
183
+ }
184
+
185
+ &::after {
186
+ content : ".";
187
+ display : block;
188
+ height : 0;
189
+ clear : left;
190
+ visibility: hidden;
191
+ }
192
+ }
193
+ }
194
+
195
+ .kts-invoice-operate-buyer-name-content-tag {
196
+ line-height : 1;
197
+ padding : 4px 12px;
198
+ background : #F3F3F3;
199
+ border-radius: 9999px;
200
+ font-size : 12px;
201
+ font-weight : bold;
202
+ color : #000;
203
+ cursor : pointer;
204
+ transition : background .4s;
205
+
206
+ &:hover {
207
+ background: #e6e6e6e6;
208
+ }
209
+ }
210
+ }
@@ -3,6 +3,7 @@ import { Descriptions, Form, Typography, Input } from 'kts-components-antd-x3';
3
3
  import { decorator } from 'grey-react-box';
4
4
  import { FormComponentProps } from 'kts-components-antd-x3/lib/form';
5
5
  import ImportBuyerButton from './ui/ImportBuyerButton';
6
+ import BuyerNameInput from './ui/BuyerNameInput';
6
7
  import Invoice from '../../';
7
8
  import { IFormItem } from '../../InvoiceController/InvoiceControllerState/BuyerState';
8
9
  import './index.less';
@@ -28,20 +29,23 @@ const Main = decorator<IBuyerProps, IBuyerProps & FormComponentProps>(
28
29
  const controller = Invoice.useInvoiceController();
29
30
 
30
31
  /** 组件模式 */
31
- const model = controller.useMemo(s => s.model, [])
32
+ const model = controller.useMemo(s => s.model, []);
33
+
34
+ /** 自动填充 */
35
+ const autoContainer = controller.useMemo(s => s.buyerState.autoContainer, []);
32
36
 
33
37
  const formItem = React.useMemo(() => {
34
38
  if (props.formItem) {
35
39
  return props.formItem;
36
40
  } else {
37
41
  return [
38
- { id: 'buyerName', label: '购买方名称', node: <Input size="small" readOnly={model === 'prefab'} />, options: { rules: [{ required: true, message: '不能为空' }] } },
39
- { id: 'buyerNo', label: '购买方纳税人识别号', node: <Input size="small" readOnly={model === 'prefab'} />, options: { rules: [{ required: true, message: '不能为空' }] } },
40
- { id: 'buyerAddress', label: '购买方地址及电话', node: <Input size="small" readOnly={model === 'prefab'} />, options: { rules: [{ required: true, message: '不能为空' }] } },
41
- { id: 'buyerBank', label: '购买方开户行及账号', node: <Input size="small" readOnly={model === 'prefab'} />, options: { rules: [{ required: true, message: '不能为空' }] } },
42
+ { id: 'buyerName', label: '购买方名称', node: <Input size="small" autoComplete="off" readOnly={model === 'prefab'} />, options: { rules: [{ required: true, message: '不能为空' }] } },
43
+ { id: 'buyerNo', label: '购买方纳税人识别号', node: <Input size="small" autoComplete="off" readOnly={model === 'prefab'} />, options: { rules: [{ required: true, message: '不能为空' }] } },
44
+ { id: 'buyerAddress', label: '购买方地址及电话', node: <Input size="small" autoComplete="off" readOnly={model === 'prefab'} />, options: { rules: [{ required: true, message: '不能为空' }] } },
45
+ { id: 'buyerBank', label: '购买方开户行及账号', node: <Input size="small" autoComplete="off" readOnly={model === 'prefab'} />, options: { rules: [{ required: true, message: '不能为空' }] } },
42
46
  ]
43
47
  }
44
- }, [props.formItem, model])
48
+ }, [props.formItem, model]);
45
49
 
46
50
  /** 注册 form */
47
51
  controller.useForm('buyer', form);
@@ -85,7 +89,11 @@ const Main = decorator<IBuyerProps, IBuyerProps & FormComponentProps>(
85
89
  return (
86
90
  <Descriptions.Item key={i} label={getlabel(item)}>
87
91
  <Form.Item>
88
- {getFieldDecorator(item.id, item.options)(item.node)}
92
+ {getFieldDecorator(item.id, item.options)(
93
+ autoContainer
94
+ ? item.id === 'buyerName' ? <BuyerNameInput /> : item.node
95
+ : item.node
96
+ )}
89
97
  </Form.Item>
90
98
  </Descriptions.Item>
91
99
  )
@@ -103,3 +111,4 @@ const Main = decorator<IBuyerProps, IBuyerProps & FormComponentProps>(
103
111
  </Form>
104
112
  );
105
113
  });
114
+
@@ -0,0 +1,159 @@
1
+
2
+ import React from 'react';
3
+ import { Popover, Input, Divider, Spin } from 'kts-components-antd-x3';
4
+ import Invoice from '../../../../';
5
+ import { IBuyerInfo } from '../../../../InvoiceController/InvoiceControllerState/BuyerState';
6
+
7
+ export interface IBuyerNameInputProps {
8
+ value?: string;
9
+ onChange?: (e: string) => void;
10
+ }
11
+
12
+ export default (props: IBuyerNameInputProps) => {
13
+
14
+ /** 控制器 */
15
+ const controller = Invoice.useInvoiceController();
16
+
17
+ /** 组件模式 */
18
+ const model = controller.useMemo(s => s.model, []);
19
+
20
+ /** 是否显示 */
21
+ const [visible, setVisible] = React.useState(false);
22
+
23
+ /** 自动填充 */
24
+ const autoContainer = controller.useMemo(s => s.buyerState.autoContainer, []);
25
+
26
+ /** 自动填充数据 */
27
+ const { dataSource, onBuyNameChange, loading } = useDataSource();
28
+
29
+ /** 悬浮内容 */
30
+ const content = React.useMemo(() => {
31
+ return (
32
+ <div className='kts-invoice-operate-buyer-name-content'>
33
+ {
34
+ loading
35
+ ? (
36
+ <div style={{ textAlign: 'center' }} >
37
+ <Spin />
38
+ </div>
39
+ )
40
+ : (
41
+ <>
42
+ <div className='kts-invoice-operate-buyer-name-content-block' style={{ padding: '14px 10px' }} >
43
+ <label style={{ marginBottom: 10 }} >最近开具</label>
44
+ <ul className='kts-invoice-operate-buyer-name-content-recently-issued' >
45
+ {dataSource.recent.map((e, i) => <li key={i} onClick={() => { onClickItem(e) }} style={{ marginBottom: interval(i, dataSource.recent.length) }} ><MyTag>{e.buyerName}</MyTag></li>)}
46
+ </ul>
47
+ </div>
48
+ <Divider style={{ margin: "0 6px" }} />
49
+ <div className='kts-invoice-operate-buyer-name-content-block' style={{ padding: '14px 10px 4px' }} >
50
+ <label style={{ padding: '0 10px' }} >选择公司</label>
51
+ {
52
+ dataSource.list.map((e, i) => {
53
+ return (
54
+ <ul key={i} onClick={() => { onClickItem(e) }} className='kts-invoice-operate-buyer-name-content-select-company' >
55
+ <li>{e.buyerName}</li>
56
+ <li>{e.buyerAddress}</li>
57
+ </ul>
58
+ )
59
+ })
60
+ }
61
+ </div>
62
+ </>
63
+ )
64
+ }
65
+ </div>
66
+ )
67
+ }, [dataSource, loading])
68
+
69
+ /** 点击了选择项 */
70
+ const onClickItem = React.useCallback(async (e: IBuyerInfo) => {
71
+ controller.formList.get('buyer')?.setFieldsValue(e);
72
+ setVisible(false);
73
+ }, [controller]);
74
+
75
+ /** 输入框数据改变 */
76
+ const onChangeInput = React.useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
77
+ props.onChange && props.onChange(e.target.value);
78
+ onBuyNameChange(e.target.value);
79
+ }, [dataSource])
80
+
81
+ React.useEffect(()=>{
82
+ visible && onBuyNameChange(props.value)
83
+ }, [visible, props.value])
84
+
85
+ if (model === 'prefab' || !autoContainer) {
86
+ return (
87
+ <Input
88
+ size="small"
89
+ autoComplete="off"
90
+ value={props.value}
91
+ readOnly={model === 'prefab'}
92
+ onChange={e => { props.onChange && props.onChange(e.target.value) }}
93
+ />
94
+ )
95
+ }
96
+
97
+ return (
98
+ <Popover
99
+ onVisibleChange={setVisible}
100
+ overlayClassName='kts-invoice-operate-buyer-name-popover'
101
+ placement="bottomLeft"
102
+ trigger="click"
103
+ visible={visible}
104
+ content={content}
105
+ >
106
+ <Input
107
+ size="small"
108
+ autoComplete="off"
109
+ value={props.value}
110
+ onChange={onChangeInput}
111
+ />
112
+ </Popover>
113
+ );
114
+ };
115
+
116
+
117
+ /** 获取自动填充数据 */
118
+ function useDataSource() {
119
+ /** 控制器 */
120
+ const controller = Invoice.useInvoiceController();
121
+
122
+ const [loading, setLoading] = React.useState(false);
123
+
124
+ const [dataSource, setDataSource] = React.useState<{ recent: IBuyerInfo[], list: IBuyerInfo[] }>({ recent: [], list: [] })
125
+
126
+ const autoContainer = controller.useMemo(s => s.buyerState.autoContainer, []);
127
+
128
+ const onBuyNameChange = React.useCallback(async (e?: string | undefined) => {
129
+ if (!autoContainer) return;
130
+ setLoading(true);
131
+ setDataSource(await autoContainer.onBuyNameChange(e));
132
+ setLoading(false);
133
+ }, [autoContainer])
134
+
135
+ return {
136
+ /** 购买方变化 */
137
+ onBuyNameChange,
138
+
139
+ /** 获取自动填充数据 */
140
+ dataSource,
141
+
142
+ /** 加载中 */
143
+ loading,
144
+ }
145
+ }
146
+
147
+ function MyTag(props: any) {
148
+ return (
149
+ <span className='kts-invoice-operate-buyer-name-content-tag' >{props.children}</span>
150
+ )
151
+ }
152
+
153
+ function interval(i: number, t: number) {
154
+ if (t % 2 === 0) {
155
+ return i > t - 3 ? 0 : 20;
156
+ } else {
157
+ return i > t - 2 ? 0 : 20;
158
+ }
159
+ }
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { Descriptions, Input, Form, AutoComplete, Icon } from 'kts-components-antd-x3';
2
+ import { Descriptions, Input, Form } from 'kts-components-antd-x3';
3
3
  import { FormComponentProps } from 'kts-components-antd-x3/lib/form';
4
4
  import { decorator } from 'grey-react-box';
5
5
  import Invoice from '../../';