Commit 3498a23d251b2de57c5e4eb41e4a11a402ba087e
Merge branch 'invoice'
# Conflicts: # src/pages/Order/index.tsx # src/services/definition.ts # src/services/request.ts
Showing
20 changed files
with
2464 additions
and
176 deletions
.idea/.name
0 → 100644
1 | +front_project |
.idea/UniappTool.xml
0 → 100644
1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
2 | +<project version="4"> | ||
3 | + <component name="cn.fjdmy.uniapp.UniappProjectDataService"> | ||
4 | + <option name="generalBasePath" value="$PROJECT_DIR$" /> | ||
5 | + <option name="manifestPath" value="$PROJECT_DIR$/manifest.json" /> | ||
6 | + <option name="pagesPath" value="$PROJECT_DIR$/pages.json" /> | ||
7 | + <option name="scanNum" value="1" /> | ||
8 | + <option name="type" value="store" /> | ||
9 | + </component> | ||
10 | +</project> |
.idea/codeStyles/codeStyleConfig.xml
0 → 100644
.idea/rcb-settings.xml
0 → 100644
1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
2 | +<project version="4"> | ||
3 | + <component name="ReactBuddyPluginProjectSettings"> | ||
4 | + <option name="devServerConfigs"> | ||
5 | + <DevServerState> | ||
6 | + <option name="packageJsonPath" value="$PROJECT_DIR$/package.json" /> | ||
7 | + <option name="scriptName" value="build" /> | ||
8 | + </DevServerState> | ||
9 | + </option> | ||
10 | + </component> | ||
11 | +</project> |
src/pages/Invoice/components/Invoice.tsx
0 → 100644
1 | +import styled from 'styled-components'; | ||
2 | +const InvoiceTmpDiv = styled.div` | ||
3 | + font-size: 12px; | ||
4 | + width: 1120px; | ||
5 | + .title { | ||
6 | + font-size: 26px; | ||
7 | + color: #b16363; | ||
8 | + text-align: center; | ||
9 | + line-height: 56px; | ||
10 | + padding-top: 0; | ||
11 | + } | ||
12 | + .extra { | ||
13 | + color: #b15b16; | ||
14 | + .content { | ||
15 | + color: #181818; | ||
16 | + } | ||
17 | + } | ||
18 | + .height84 { | ||
19 | + height: 110px; | ||
20 | + } | ||
21 | + .row { | ||
22 | + border: 2px solid #b16363; | ||
23 | + border-bottom: none; | ||
24 | + color: #b15b16; | ||
25 | + .content { | ||
26 | + color: #181818; | ||
27 | + } | ||
28 | + } | ||
29 | + .last-row { | ||
30 | + .content { | ||
31 | + color: #181818; | ||
32 | + } | ||
33 | + color: #b15b16; | ||
34 | + border-top: 2px solid #b16363; | ||
35 | + } | ||
36 | + .label { | ||
37 | + width: 78px; | ||
38 | + display: inline-block; | ||
39 | + text-align-last: justify; | ||
40 | + text-align: justify; | ||
41 | + } | ||
42 | + .longLabel { | ||
43 | + width: 178px; | ||
44 | + display: inline-block; | ||
45 | + text-align-last: justify; | ||
46 | + text-align: justify; | ||
47 | + } | ||
48 | + .title-label { | ||
49 | + width: 52px; | ||
50 | + } | ||
51 | +`; | ||
52 | +const Row = styled.div` | ||
53 | + .col_1 { | ||
54 | + width: 2.65%; | ||
55 | + borderleft: none; | ||
56 | + } | ||
57 | + .col_4 { | ||
58 | + width: 3.75%; | ||
59 | + } | ||
60 | + .col_9 { | ||
61 | + width: 7.4%; | ||
62 | + } | ||
63 | + .col_2 { | ||
64 | + width: 8.33%; | ||
65 | + } | ||
66 | + .col_3 { | ||
67 | + width: 12.5%; | ||
68 | + } | ||
69 | + .col_5 { | ||
70 | + width: 20.83%; | ||
71 | + } | ||
72 | + .col_6 { | ||
73 | + width: 42.5%; | ||
74 | + } | ||
75 | + .col_7 { | ||
76 | + width: 29.16%; | ||
77 | + } | ||
78 | + .col_8 { | ||
79 | + width: 33.33%; | ||
80 | + } | ||
81 | + .col_14 { | ||
82 | + width: 58.33%; | ||
83 | + } | ||
84 | + .col_15 { | ||
85 | + width: 42.5%; | ||
86 | + } | ||
87 | + .col_17 { | ||
88 | + width: 70.83%; | ||
89 | + } | ||
90 | + .col_18 { | ||
91 | + width: 100%; | ||
92 | + } | ||
93 | + .col_24 { | ||
94 | + width: 100%; | ||
95 | + } | ||
96 | +`; | ||
97 | +const Col = styled.span` | ||
98 | + display: inline-block; | ||
99 | + padding: 8px; | ||
100 | + box-sizing: border-box; | ||
101 | + vertical-align: middle; | ||
102 | + border-left: 2px solid #b16363; | ||
103 | + height: 100%; | ||
104 | + &.no-border { | ||
105 | + border-left: none; | ||
106 | + } | ||
107 | + .text-center { | ||
108 | + text-align: center; | ||
109 | + border-left: none; | ||
110 | + border-right: none; | ||
111 | + } | ||
112 | + &.transparent-border { | ||
113 | + border-left: 2px solid rgba(0, 0, 0, 0); | ||
114 | + } | ||
115 | + &.invoice-number { | ||
116 | + border-left: none; | ||
117 | + color: #b16363; | ||
118 | + padding: 0 0 0 800px; | ||
119 | + font-size: 14px; | ||
120 | + } | ||
121 | +`; | ||
122 | +const UnderLine = styled.div` | ||
123 | + border: 2px solid #b16363; | ||
124 | + width: 325px; | ||
125 | + height: 8px; | ||
126 | + margin: -1% 0 2% 35%; | ||
127 | + border-left: none; | ||
128 | + border-right: none; | ||
129 | +`; | ||
130 | +const InvoiceInfo = styled.span` | ||
131 | + color: black; | ||
132 | +`; | ||
133 | +const TitleDescription = styled.div` | ||
134 | + margin-top: 4.2%; | ||
135 | +`; | ||
136 | +const ProjectContainer = styled.div` | ||
137 | + width: 100%; | ||
138 | + height: 160px; | ||
139 | + border-top: 2px solid #b16363; | ||
140 | + border-right: 2px solid #b16363; | ||
141 | + border-left: 2px solid #b16363; | ||
142 | + overflow: auto; | ||
143 | + .single-project { | ||
144 | + width: 100%; | ||
145 | + height: 30px; | ||
146 | + } | ||
147 | +`; | ||
148 | +export default ({ data }) => { | ||
149 | + return ( | ||
150 | + <div> | ||
151 | + <InvoiceTmpDiv> | ||
152 | + <Row> | ||
153 | + <Col className="col_18 invoice-number"> | ||
154 | + 发票号码:<InvoiceInfo>{data.invoiceNumber}</InvoiceInfo> | ||
155 | + </Col> | ||
156 | + <Col className="title col_18 no-border"> | ||
157 | + 电子发票(增值税专用发票) | ||
158 | + </Col> | ||
159 | + <UnderLine className="UnderLine"> | ||
160 | + <div></div> | ||
161 | + </UnderLine> | ||
162 | + </Row> | ||
163 | + <Row className="row height84"> | ||
164 | + <Col className="col_1 no-border">购买方信息</Col> | ||
165 | + <Col className="col_15"> | ||
166 | + <TitleDescription> | ||
167 | + <span className="label">名称</span>: | ||
168 | + <span className="content">{data.partyAName}</span> | ||
169 | + </TitleDescription> | ||
170 | + <TitleDescription> | ||
171 | + <span className="longLabel">统一社会信用代码/纳税人识别号</span>: | ||
172 | + <span className="content">{data.partyATaxid}</span> | ||
173 | + </TitleDescription> | ||
174 | + </Col> | ||
175 | + <Col className="col_1">销售方信息</Col> | ||
176 | + <Col className="col_6"> | ||
177 | + <TitleDescription> | ||
178 | + <span className="label">名称</span>: | ||
179 | + <span className="content">{data.partyBName}</span> | ||
180 | + </TitleDescription> | ||
181 | + <TitleDescription> | ||
182 | + <span className="longLabel">统一社会信用代码/纳税人识别号</span>: | ||
183 | + <span className="content">{data.partyBTaxid}</span> | ||
184 | + </TitleDescription> | ||
185 | + </Col> | ||
186 | + </Row> | ||
187 | + <Row className="row"> | ||
188 | + <Col className="col_7 no-border"> | ||
189 | + <div className="text-center">项目名称</div> | ||
190 | + </Col> | ||
191 | + <Col className="col_5"> | ||
192 | + <div className="text-center">规格型号</div> | ||
193 | + </Col> | ||
194 | + <Col className=""> | ||
195 | + <div className="text-center">单位</div> | ||
196 | + </Col> | ||
197 | + <Col className=""> | ||
198 | + <div className="text-center">数量</div> | ||
199 | + </Col> | ||
200 | + <Col className="col_2"> | ||
201 | + <div className="text-center">单价</div> | ||
202 | + </Col> | ||
203 | + <Col className="col_3"> | ||
204 | + <div className="text-center">金额</div> | ||
205 | + </Col> | ||
206 | + <Col className=""> | ||
207 | + <div className="text-center">税率/征收率</div> | ||
208 | + </Col> | ||
209 | + <Col className="col_2"> | ||
210 | + <div className="text-center">税额</div> | ||
211 | + </Col> | ||
212 | + </Row> | ||
213 | + <Row> | ||
214 | + <ProjectContainer> | ||
215 | + {data && | ||
216 | + data.invoiceDetails?.map((item) => { | ||
217 | + const { | ||
218 | + taxPrice, | ||
219 | + totalPrice, | ||
220 | + specification, | ||
221 | + projectName, | ||
222 | + quantity, | ||
223 | + price, | ||
224 | + taxRate, | ||
225 | + unit, | ||
226 | + } = item; | ||
227 | + return ( | ||
228 | + <div className="single-project" key={item.id}> | ||
229 | + <Col | ||
230 | + className="col_7 transparent-border" | ||
231 | + key={'projectName'} | ||
232 | + > | ||
233 | + <div className="text-center">{projectName}</div> | ||
234 | + </Col> | ||
235 | + <Col | ||
236 | + className="col_5 transparent-border" | ||
237 | + key={'specification'} | ||
238 | + > | ||
239 | + <div className="text-center">{specification}</div> | ||
240 | + </Col> | ||
241 | + <Col className="col_4 transparent-border" key={'unit'}> | ||
242 | + <div className="text-center">{unit}</div> | ||
243 | + </Col> | ||
244 | + <Col className="col_4 transparent-border" key={'quantity'}> | ||
245 | + <div className="text-center">{quantity}</div> | ||
246 | + </Col> | ||
247 | + <Col className="col_2 transparent-border" key={'price'}> | ||
248 | + <div className="text-center">{price}</div> | ||
249 | + </Col> | ||
250 | + <Col | ||
251 | + className="col_3 transparent-border" | ||
252 | + key={'totalPrice'} | ||
253 | + > | ||
254 | + <div className="text-center">{totalPrice}</div> | ||
255 | + </Col> | ||
256 | + <Col className="col_9 transparent-border" key={'taxRate'}> | ||
257 | + <div className="text-center">{taxRate}</div> | ||
258 | + </Col> | ||
259 | + <Col className="col_2 transparent-border" key={'taxPrice'}> | ||
260 | + <div className="text-center">{taxPrice}</div> | ||
261 | + </Col> | ||
262 | + </div> | ||
263 | + ); | ||
264 | + })} | ||
265 | + </ProjectContainer> | ||
266 | + </Row> | ||
267 | + <Row className="row"> | ||
268 | + <Col className="col_15 no-border"> | ||
269 | + 价税合计(大写) | ||
270 | + <InvoiceInfo>{data.totalPriceText}</InvoiceInfo> | ||
271 | + </Col> | ||
272 | + <Col className="no-border"> | ||
273 | + (小写)<InvoiceInfo>¥{data.totalPrice}</InvoiceInfo> | ||
274 | + </Col> | ||
275 | + </Row> | ||
276 | + <Row className="row height84"> | ||
277 | + <Col className="col_1 no-border">备注</Col> | ||
278 | + <Col className="col_7"> | ||
279 | + <InvoiceInfo>{data.comment}</InvoiceInfo> | ||
280 | + </Col> | ||
281 | + </Row> | ||
282 | + <Row className="last-row"> | ||
283 | + <Col className="col_6 no-border"> | ||
284 | + 开票人:<InvoiceInfo>{data.invoicingPerson}</InvoiceInfo> | ||
285 | + </Col> | ||
286 | + </Row> | ||
287 | + </InvoiceTmpDiv> | ||
288 | + </div> | ||
289 | + ); | ||
290 | +}; |
src/pages/Invoice/components/InvoiceDetailImportModal.tsx
0 → 100644
1 | +import { RESPONSE_CODE } from '@/constants/enum'; | ||
2 | +import { postServiceInvoiceImportInvoiceDetails } from '@/services'; | ||
3 | +import { ModalForm, ProFormUploadDragger } from '@ant-design/pro-components'; | ||
4 | +import { Button, Form, message } from 'antd'; | ||
5 | + | ||
6 | +export default ({ recordId }) => { | ||
7 | + const [form] = Form.useForm(); | ||
8 | + return ( | ||
9 | + <ModalForm | ||
10 | + title="新建表单" | ||
11 | + trigger={<Button type="primary">导入明细</Button>} | ||
12 | + form={form} | ||
13 | + autoFocusFirstInput | ||
14 | + modalProps={{ | ||
15 | + destroyOnClose: true, | ||
16 | + onCancel: () => console.log('run'), | ||
17 | + }} | ||
18 | + submitTimeout={2000} | ||
19 | + onFinish={async (values) => { | ||
20 | + const formData = new FormData(); | ||
21 | + // console.log(fileList[0] as RcFile) | ||
22 | + // formData.append('file', fileList[0] as RcFile); | ||
23 | + formData.append('invoiceRecordId', recordId); | ||
24 | + formData.append('detailsExcel', values.detailsExcel[0].originFileObj); | ||
25 | + // You can use any AJAX library you like | ||
26 | + const res = await postServiceInvoiceImportInvoiceDetails({ | ||
27 | + data: formData, | ||
28 | + headers: { | ||
29 | + 'Content-Type': | ||
30 | + 'multipart/form-data; boundary=----WebKitFormBoundarynl6gT1BKdPWIejNq', | ||
31 | + }, | ||
32 | + }); | ||
33 | + if (res.result === RESPONSE_CODE.SUCCESS) { | ||
34 | + message.success('导入成功'); | ||
35 | + return true; | ||
36 | + } | ||
37 | + }} | ||
38 | + > | ||
39 | + <ProFormUploadDragger name="detailsExcel" label="导入明细表" /> | ||
40 | + </ModalForm> | ||
41 | + ); | ||
42 | +}; |
src/pages/Invoice/components/InvoiceDetailTable.tsx
0 → 100644
1 | +import InvoiceDetailImportModal from '@/pages/Invoice/components/InvoiceDetailImportModal'; | ||
2 | +import { InvoiceProjectSelect } from '@/pages/Invoice/components/InvoiceProjectSelect'; | ||
3 | +import { | ||
4 | + ActionType, | ||
5 | + EditableProTable, | ||
6 | + ProColumns, | ||
7 | +} from '@ant-design/pro-components'; | ||
8 | +import { useEffect, useRef, useState } from 'react'; | ||
9 | + | ||
10 | +export default ({ recordId, details, updateDetails, readOnly }) => { | ||
11 | + const [editableKeys, setEditableRowKeys] = useState([]); | ||
12 | + const [invoiceProject, setInvoiceProject] = useState({}); | ||
13 | + const ref = useRef<ActionType>(); | ||
14 | + useEffect(() => { | ||
15 | + updateDetails(details); | ||
16 | + }, []); | ||
17 | + | ||
18 | + useEffect(() => { | ||
19 | + setEditableRowKeys(details?.map((item) => item.tid)); | ||
20 | + }, [details]); | ||
21 | + const columns: ProColumns[] = [ | ||
22 | + { | ||
23 | + title: '项目名称', | ||
24 | + dataIndex: 'projectName', | ||
25 | + width: 200, | ||
26 | + ellipsis: true, | ||
27 | + readonly: readOnly, | ||
28 | + renderFormItem: () => { | ||
29 | + return ( | ||
30 | + <InvoiceProjectSelect | ||
31 | + setInvoiceProject={setInvoiceProject} | ||
32 | + readOnly={readOnly} | ||
33 | + /> | ||
34 | + ); | ||
35 | + }, | ||
36 | + }, | ||
37 | + { | ||
38 | + title: '规格型号', | ||
39 | + readonly: readOnly, | ||
40 | + dataIndex: 'specification', | ||
41 | + valueType: 'text', | ||
42 | + ellipsis: true, | ||
43 | + }, | ||
44 | + { | ||
45 | + title: '单位', | ||
46 | + readonly: readOnly, | ||
47 | + dataIndex: 'unit', | ||
48 | + valueType: 'text', | ||
49 | + ellipsis: true, | ||
50 | + }, | ||
51 | + { | ||
52 | + title: '数量', | ||
53 | + readonly: readOnly, | ||
54 | + dataIndex: 'quantity', | ||
55 | + valueType: 'digit', | ||
56 | + ellipsis: true, | ||
57 | + }, | ||
58 | + { | ||
59 | + title: '单价', | ||
60 | + readonly: readOnly, | ||
61 | + dataIndex: 'price', | ||
62 | + valueType: 'digit', | ||
63 | + ellipsis: true, | ||
64 | + }, | ||
65 | + { | ||
66 | + title: '金额', | ||
67 | + readonly: readOnly, | ||
68 | + dataIndex: 'totalPrice', | ||
69 | + valueType: 'digit', | ||
70 | + ellipsis: true, | ||
71 | + }, | ||
72 | + { | ||
73 | + title: '税率/征收率', | ||
74 | + readonly: true, | ||
75 | + dataIndex: 'taxRate', | ||
76 | + valueType: () => ({ | ||
77 | + type: 'percent', | ||
78 | + }), | ||
79 | + ellipsis: true, | ||
80 | + }, | ||
81 | + { | ||
82 | + title: '税额', | ||
83 | + readonly: true, | ||
84 | + dataIndex: 'taxPrice', | ||
85 | + valueType: 'digit', | ||
86 | + ellipsis: true, | ||
87 | + }, | ||
88 | + { | ||
89 | + title: '操作', | ||
90 | + valueType: 'option', | ||
91 | + width: 100, | ||
92 | + render: () => { | ||
93 | + return null; | ||
94 | + }, | ||
95 | + }, | ||
96 | + ]; | ||
97 | + | ||
98 | + return ( | ||
99 | + <> | ||
100 | + <EditableProTable | ||
101 | + columns={columns} | ||
102 | + actionRef={ref} | ||
103 | + rowKey="tid" | ||
104 | + scroll={{ | ||
105 | + x: 960, | ||
106 | + }} | ||
107 | + value={details} | ||
108 | + controlled={true} | ||
109 | + recordCreatorProps={ | ||
110 | + readOnly | ||
111 | + ? false | ||
112 | + : { | ||
113 | + newRecordType: 'dataSource', | ||
114 | + record: () => ({ | ||
115 | + tid: Date.now(), | ||
116 | + }), | ||
117 | + } | ||
118 | + } | ||
119 | + toolBarRender={() => { | ||
120 | + return [ | ||
121 | + <InvoiceDetailImportModal key={'import'} recordId={recordId} />, | ||
122 | + ]; | ||
123 | + }} | ||
124 | + editable={{ | ||
125 | + type: 'multiple', | ||
126 | + editableKeys, | ||
127 | + actionRender: (row, config, defaultDoms) => { | ||
128 | + return [defaultDoms.delete]; | ||
129 | + }, | ||
130 | + | ||
131 | + onValuesChange: (record, recordList) => { | ||
132 | + //修改recordList中tid为record.tid的元素,将它的specification属性设置为invoiceProject的specification属性 | ||
133 | + const records = recordList.map((item) => { | ||
134 | + if ( | ||
135 | + record && | ||
136 | + item.tid === record.tid && | ||
137 | + item.projectName !== | ||
138 | + '*' + | ||
139 | + invoiceProject.productAndServiceCatagoryAbbreviation + | ||
140 | + '*' + | ||
141 | + invoiceProject?.name && | ||
142 | + item.specification !== invoiceProject?.specification | ||
143 | + ) { | ||
144 | + console.log(item.projectName); | ||
145 | + console.log(invoiceProject?.name); | ||
146 | + item.projectName = | ||
147 | + '*' + | ||
148 | + invoiceProject.productAndServiceCatagoryAbbreviation + | ||
149 | + '*' + | ||
150 | + invoiceProject?.name; | ||
151 | + item.specification = invoiceProject?.specification; | ||
152 | + item.unit = invoiceProject?.unit; | ||
153 | + item.taxRate = invoiceProject?.taxRate * 100; | ||
154 | + } | ||
155 | + return item; | ||
156 | + }); | ||
157 | + updateDetails(records); | ||
158 | + }, | ||
159 | + }} | ||
160 | + /> | ||
161 | + {/*{<ProCard title="表格数据" headerBordered collapsible defaultCollapsed> | ||
162 | + <ProFormField | ||
163 | + ignoreFormItem | ||
164 | + fieldProps={{ | ||
165 | + style: { | ||
166 | + width: '100%', | ||
167 | + }, | ||
168 | + }} | ||
169 | + mode="read" | ||
170 | + valueType="jsonCode" | ||
171 | + text={JSON.stringify(details)} | ||
172 | + /> | ||
173 | + </ProCard>}*/} | ||
174 | + </> | ||
175 | + ); | ||
176 | +}; |
src/pages/Invoice/components/InvoiceModal.tsx
0 → 100644
1 | +import Invoice from '@/pages/Invoice/components/Invoice'; | ||
2 | +import { postServiceInvoiceGetInvoiceRecord } from '@/services'; | ||
3 | +import { ModalForm } from '@ant-design/pro-components'; | ||
4 | +import { Form } from 'antd'; | ||
5 | +import { useEffect, useState } from 'react'; | ||
6 | + | ||
7 | +export default ({ recordId, getRecord, button }) => { | ||
8 | + const [data, setData] = useState<any>({}); | ||
9 | + useEffect(() => { | ||
10 | + const getData = async () => { | ||
11 | + let ret = await postServiceInvoiceGetInvoiceRecord({ | ||
12 | + query: { | ||
13 | + id: recordId, | ||
14 | + }, | ||
15 | + }); | ||
16 | + setData(ret.data); | ||
17 | + }; | ||
18 | + if (recordId) { | ||
19 | + getData(); | ||
20 | + } | ||
21 | + }, []); | ||
22 | + const [form] = Form.useForm(); | ||
23 | + return ( | ||
24 | + <ModalForm | ||
25 | + title="预览发票" | ||
26 | + trigger={button ? button : <a type="primary">预览</a>} | ||
27 | + onOpenChange={(open) => { | ||
28 | + if (open && getRecord) { | ||
29 | + setData(getRecord()); | ||
30 | + } | ||
31 | + }} | ||
32 | + width={1200} | ||
33 | + form={form} | ||
34 | + autoFocusFirstInput | ||
35 | + modalProps={{ | ||
36 | + destroyOnClose: true, | ||
37 | + }} | ||
38 | + > | ||
39 | + <hr /> | ||
40 | + <Invoice data={data} /> | ||
41 | + </ModalForm> | ||
42 | + ); | ||
43 | +}; |
src/pages/Invoice/components/InvoiceProjectSelect.tsx
0 → 100644
1 | +import { postServiceConstListInvoiceDetailNames } from '@/services'; | ||
2 | +import { Select, Tooltip } from 'antd'; | ||
3 | +import { useState } from 'react'; | ||
4 | + | ||
5 | +export const InvoiceProjectSelect = ({ | ||
6 | + readOnly, | ||
7 | + value, | ||
8 | + onChange, | ||
9 | + setInvoiceProject, | ||
10 | +}) => { | ||
11 | + const [options, setOptions] = useState<any[]>([]); | ||
12 | + // 定义防抖函数 | ||
13 | + let timeoutId = null; | ||
14 | + const fetchOptions = async (keywords) => { | ||
15 | + clearTimeout(timeoutId); | ||
16 | + timeoutId = setTimeout(async () => { | ||
17 | + const res = await postServiceConstListInvoiceDetailNames({ | ||
18 | + data: { | ||
19 | + nameLike: keywords, | ||
20 | + }, | ||
21 | + }); | ||
22 | + const data = res.data; | ||
23 | + console.log('invoiceProject' + JSON.stringify(data)); | ||
24 | + setOptions( | ||
25 | + data.map((item) => { | ||
26 | + return { | ||
27 | + label: | ||
28 | + '*' + | ||
29 | + item.productAndServiceCatagoryAbbreviation + | ||
30 | + '*' + | ||
31 | + item?.name, | ||
32 | + value: item.id, | ||
33 | + ...item, | ||
34 | + }; | ||
35 | + }), | ||
36 | + ); | ||
37 | + // 这里可以放置实际的搜索逻辑,比如发起网络请求等 | ||
38 | + }, 500); // 设置延迟时间,单位毫秒 | ||
39 | + }; | ||
40 | + | ||
41 | + return readOnly ? ( | ||
42 | + <Tooltip title={value}>{value}</Tooltip> | ||
43 | + ) : ( | ||
44 | + <Select | ||
45 | + key="project" | ||
46 | + /*readonly={readonly}*/ | ||
47 | + showSearch | ||
48 | + placeholder="请选择开票项目" | ||
49 | + filterOption={(input, option) => (option?.label ?? '').includes(input)} | ||
50 | + onChange={(e) => { | ||
51 | + setInvoiceProject(options.find((item) => item.value === e)); | ||
52 | + onChange(e); | ||
53 | + }} | ||
54 | + defaultValue={value} | ||
55 | + options={options} | ||
56 | + onSearch={(e) => { | ||
57 | + fetchOptions(e); | ||
58 | + }} | ||
59 | + /> | ||
60 | + ); | ||
61 | +}; |
src/pages/Invoice/components/InvoiceRecordDetailModal.tsx
0 → 100644
1 | +import { RESPONSE_CODE } from '@/constants/enum'; | ||
2 | +import InvoiceDetailTable from '@/pages/Invoice/components/InvoiceDetailTable'; | ||
3 | +import { | ||
4 | + postServiceConstGetPayeeEnum, | ||
5 | + postServiceConstInvoiceType, | ||
6 | + postServiceConstInvoicingType, | ||
7 | + postServiceInvoiceGetInvoiceRecord, | ||
8 | + postServiceInvoiceModifyRecord, | ||
9 | +} from '@/services'; | ||
10 | +import { enumToSelect } from '@/utils'; | ||
11 | +import { | ||
12 | + ModalForm, | ||
13 | + ProCard, | ||
14 | + ProForm, | ||
15 | + ProFormFieldSet, | ||
16 | + ProFormInstance, | ||
17 | + ProFormList, | ||
18 | + ProFormSelect, | ||
19 | + ProFormText, | ||
20 | + ProFormTextArea, | ||
21 | +} from '@ant-design/pro-components'; | ||
22 | +import { Button, Divider, Form, Space, message } from 'antd'; | ||
23 | +import { useEffect, useRef, useState } from 'react'; | ||
24 | + | ||
25 | +export default ({ id, setVisible }) => { | ||
26 | + const [readOnly, setReadOnly] = useState(true); | ||
27 | + const [detailTableData, setDetailTableData] = useState([]); | ||
28 | + const [payees, setPayees] = useState([]); | ||
29 | + const [payeeNameOptions, setPayeeNameOptions] = useState([]); | ||
30 | + const formRef = useRef<ProFormInstance>(); | ||
31 | + const [form] = Form.useForm(); | ||
32 | + | ||
33 | + useEffect(() => { | ||
34 | + console.log('id' + id); | ||
35 | + const getPayees = async () => { | ||
36 | + let res = await postServiceConstGetPayeeEnum(); | ||
37 | + setPayees(res.data); | ||
38 | + let payeeNameOptions = res.data.map((item) => { | ||
39 | + return { | ||
40 | + label: item.payeeName, | ||
41 | + value: item.payeeName, | ||
42 | + }; | ||
43 | + }); | ||
44 | + setPayeeNameOptions(payeeNameOptions); | ||
45 | + }; | ||
46 | + getPayees(); | ||
47 | + }, []); | ||
48 | + const getRecord = async (id) => { | ||
49 | + let ret = await postServiceInvoiceGetInvoiceRecord({ | ||
50 | + query: { | ||
51 | + id: id, | ||
52 | + }, | ||
53 | + }); | ||
54 | + const updatedInvoiceDetails = ret.data.invoiceDetails?.map( | ||
55 | + (item, index) => ({ | ||
56 | + ...item, // 保留原有属性 | ||
57 | + tid: index + 1, // 添加tid属性,这里以T开头,后面跟索引+1,仅作示例,实际可根据需求生成tid | ||
58 | + }), | ||
59 | + ); | ||
60 | + setDetailTableData(updatedInvoiceDetails); | ||
61 | + }; | ||
62 | + useEffect(() => { | ||
63 | + getRecord(id); | ||
64 | + }, []); | ||
65 | + | ||
66 | + const updateDetails = (values) => { | ||
67 | + setDetailTableData(values); | ||
68 | + }; | ||
69 | + return ( | ||
70 | + <> | ||
71 | + <Space> | ||
72 | + <ModalForm | ||
73 | + open | ||
74 | + title="发票详情" | ||
75 | + formRef={formRef} | ||
76 | + request={async () => { | ||
77 | + let ret = await postServiceInvoiceGetInvoiceRecord({ | ||
78 | + query: { | ||
79 | + id: id, | ||
80 | + }, | ||
81 | + }); | ||
82 | + return ret.data; | ||
83 | + }} | ||
84 | + submitter={{ | ||
85 | + render: () => { | ||
86 | + return [ | ||
87 | + <Button | ||
88 | + type={readOnly ? 'primary' : 'default'} | ||
89 | + key="ok" | ||
90 | + onClick={() => { | ||
91 | + setReadOnly(!readOnly); | ||
92 | + }} | ||
93 | + > | ||
94 | + {readOnly ? '编辑' : '取消编辑'} | ||
95 | + </Button>, | ||
96 | + <> | ||
97 | + {!readOnly && ( | ||
98 | + <Button | ||
99 | + type="primary" | ||
100 | + key="submit" | ||
101 | + onClick={async () => { | ||
102 | + const result = await postServiceInvoiceModifyRecord({ | ||
103 | + data: { | ||
104 | + ...form.getFieldsValue(), | ||
105 | + invoiceDetails: [...detailTableData], | ||
106 | + }, | ||
107 | + }); | ||
108 | + if (result.result === RESPONSE_CODE.SUCCESS) { | ||
109 | + message.success('提交成功'); | ||
110 | + } | ||
111 | + setVisible(false); | ||
112 | + return true; | ||
113 | + }} | ||
114 | + > | ||
115 | + 提交 | ||
116 | + </Button> | ||
117 | + )} | ||
118 | + </>, | ||
119 | + /*<Button | ||
120 | + type={'default'} | ||
121 | + key="ok" | ||
122 | + onClick={() => { | ||
123 | + setVisible(false) | ||
124 | + }} | ||
125 | + > | ||
126 | + 取消 | ||
127 | + </Button>,*/ | ||
128 | + ]; | ||
129 | + }, | ||
130 | + }} | ||
131 | + width={1200} | ||
132 | + form={form} | ||
133 | + autoFocusFirstInput | ||
134 | + modalProps={{ | ||
135 | + destroyOnClose: true, | ||
136 | + onCancel: () => { | ||
137 | + setVisible(false); | ||
138 | + }, | ||
139 | + }} | ||
140 | + grid={true} | ||
141 | + layout="horizontal" | ||
142 | + rowProps={{ | ||
143 | + gutter: [0, 0], | ||
144 | + }} | ||
145 | + submitTimeout={2000} | ||
146 | + onFinish={async (values) => { | ||
147 | + const result = await postServiceInvoiceModifyRecord({ | ||
148 | + data: { | ||
149 | + ...values, | ||
150 | + invoiceDetails: { | ||
151 | + ...detailTableData, | ||
152 | + }, | ||
153 | + }, | ||
154 | + }); | ||
155 | + if (result.result === RESPONSE_CODE.SUCCESS) { | ||
156 | + message.success('提交成功'); | ||
157 | + } | ||
158 | + return true; | ||
159 | + }} | ||
160 | + > | ||
161 | + <ProCard | ||
162 | + title="基础信息" | ||
163 | + bordered | ||
164 | + // | ||
165 | + headStyle={{}} | ||
166 | + headerBordered | ||
167 | + size={'small'} | ||
168 | + > | ||
169 | + <ProForm.Group> | ||
170 | + <ProFormText | ||
171 | + readonly | ||
172 | + name="id" | ||
173 | + label="订单批号" | ||
174 | + colProps={{ | ||
175 | + span: 5, | ||
176 | + }} | ||
177 | + tooltip="最长为 24 位" | ||
178 | + placeholder="请输入名称" | ||
179 | + /> | ||
180 | + | ||
181 | + <ProFormText | ||
182 | + readonly | ||
183 | + width="md" | ||
184 | + colProps={{ | ||
185 | + span: 5, | ||
186 | + }} | ||
187 | + name="createByName" | ||
188 | + label="销售代表" | ||
189 | + placeholder="请输入名称" | ||
190 | + /> | ||
191 | + <ProFormText | ||
192 | + readonly | ||
193 | + width="md" | ||
194 | + colProps={{ | ||
195 | + span: 5, | ||
196 | + }} | ||
197 | + name="createTime" | ||
198 | + label="申请时间" | ||
199 | + placeholder="请输入名称" | ||
200 | + /> | ||
201 | + <ProFormSelect | ||
202 | + name="type" | ||
203 | + label="发票类型" | ||
204 | + colProps={{ | ||
205 | + span: 5, | ||
206 | + }} | ||
207 | + readonly={readOnly} | ||
208 | + request={async () => { | ||
209 | + let invoiceTypeRet = await postServiceConstInvoiceType(); | ||
210 | + return enumToSelect(invoiceTypeRet.data); | ||
211 | + }} | ||
212 | + placeholder="Please select a country" | ||
213 | + rules={[ | ||
214 | + { required: true, message: 'Please select your country!' }, | ||
215 | + ]} | ||
216 | + /> | ||
217 | + <ProFormSelect | ||
218 | + name="invoicingType" | ||
219 | + readonly={readOnly} | ||
220 | + label="开具类型" | ||
221 | + colProps={{ | ||
222 | + span: 4, | ||
223 | + }} | ||
224 | + request={async () => { | ||
225 | + let invoicingTypeRet = await postServiceConstInvoicingType(); | ||
226 | + let options = enumToSelect(invoicingTypeRet.data); | ||
227 | + return options; | ||
228 | + }} | ||
229 | + placeholder="Please select a country" | ||
230 | + rules={[ | ||
231 | + { required: true, message: 'Please select your country!' }, | ||
232 | + ]} | ||
233 | + /> | ||
234 | + <ProFormFieldSet | ||
235 | + name="list" | ||
236 | + label="子订单号" | ||
237 | + transform={(value: any) => ({ | ||
238 | + list: value, | ||
239 | + startTime: value[0], | ||
240 | + endTime: value[1], | ||
241 | + })} | ||
242 | + > | ||
243 | + <ProFormList | ||
244 | + name="subOrderIds" | ||
245 | + creatorButtonProps={false} | ||
246 | + itemRender={({}, { record }) => { | ||
247 | + return ( | ||
248 | + <> | ||
249 | + <Button | ||
250 | + className="pl-1 pr-0" | ||
251 | + type="link" | ||
252 | + target="_blank" | ||
253 | + href={'/order?subOrderId=' + record} | ||
254 | + > | ||
255 | + {record} | ||
256 | + </Button> | ||
257 | + <Divider type="vertical" /> | ||
258 | + </> | ||
259 | + ); | ||
260 | + }} | ||
261 | + > | ||
262 | + <ProFormText allowClear={false} width="xs" name={['name']} /> | ||
263 | + </ProFormList> | ||
264 | + </ProFormFieldSet> | ||
265 | + </ProForm.Group> | ||
266 | + </ProCard> | ||
267 | + <hr /> | ||
268 | + <ProCard title="购方信息" bordered headerBordered size={'small'}> | ||
269 | + <ProForm.Group> | ||
270 | + <ProFormText | ||
271 | + readonly={readOnly} | ||
272 | + width="md" | ||
273 | + colProps={{ | ||
274 | + span: 8, | ||
275 | + }} | ||
276 | + name="partyAName" | ||
277 | + label="购方名称" | ||
278 | + placeholder="请输入名称" | ||
279 | + /> | ||
280 | + <ProFormText | ||
281 | + readonly={readOnly} | ||
282 | + width="md" | ||
283 | + colProps={{ | ||
284 | + span: 8, | ||
285 | + }} | ||
286 | + name="partyATaxid" | ||
287 | + label="购方税号" | ||
288 | + placeholder="请输入名称" | ||
289 | + /> | ||
290 | + <ProFormText | ||
291 | + readonly={readOnly} | ||
292 | + width="md" | ||
293 | + colProps={{ | ||
294 | + span: 8, | ||
295 | + }} | ||
296 | + label="开户银行" | ||
297 | + name={'partyAOpenBank'} | ||
298 | + placeholder="请输入名称" | ||
299 | + /> | ||
300 | + <ProFormText | ||
301 | + readonly={readOnly} | ||
302 | + width="md" | ||
303 | + colProps={{ | ||
304 | + span: 8, | ||
305 | + }} | ||
306 | + name="partyABankAccount" | ||
307 | + label="银行账号" | ||
308 | + placeholder="请输入名称" | ||
309 | + /> | ||
310 | + <ProFormText | ||
311 | + readonly={readOnly} | ||
312 | + width="md" | ||
313 | + colProps={{ | ||
314 | + span: 8, | ||
315 | + }} | ||
316 | + name="partyAAddress" | ||
317 | + label="购方地址" | ||
318 | + placeholder="请输入名称" | ||
319 | + /> | ||
320 | + <ProFormText | ||
321 | + readonly={readOnly} | ||
322 | + width="md" | ||
323 | + colProps={{ | ||
324 | + span: 8, | ||
325 | + }} | ||
326 | + name="partyAPhoneNumber" | ||
327 | + label="电话" | ||
328 | + placeholder="请输入名称" | ||
329 | + /> | ||
330 | + </ProForm.Group> | ||
331 | + </ProCard> | ||
332 | + <hr /> | ||
333 | + <ProCard title="销方信息" bordered headerBordered size={'small'}> | ||
334 | + <ProForm.Group> | ||
335 | + <ProFormSelect | ||
336 | + readonly={readOnly} | ||
337 | + width="md" | ||
338 | + name="partyBName" | ||
339 | + options={payeeNameOptions} | ||
340 | + onChange={(value: any) => { | ||
341 | + let payee = payees.find((item: any) => { | ||
342 | + return item.payeeName === value; | ||
343 | + }); | ||
344 | + console.log(JSON.stringify(payee)); | ||
345 | + form.setFieldsValue({ | ||
346 | + partyBTaxid: payee.taxId, | ||
347 | + partyBBankAccount: payee.bankAccount, | ||
348 | + partyBOpenBank: payee.openBank, | ||
349 | + partyBAddress: payee.address, | ||
350 | + partyBPhoneNumber: payee.phoneNumber, | ||
351 | + }); | ||
352 | + }} | ||
353 | + label="销方名称" | ||
354 | + colProps={{ | ||
355 | + span: 8, | ||
356 | + }} | ||
357 | + placeholder="请输入名称" | ||
358 | + /> | ||
359 | + | ||
360 | + <ProFormText | ||
361 | + readonly | ||
362 | + width="md" | ||
363 | + name="partyBTaxid" | ||
364 | + label="销方税号" | ||
365 | + colProps={{ | ||
366 | + span: 8, | ||
367 | + }} | ||
368 | + placeholder="请输入名称" | ||
369 | + /> | ||
370 | + <ProFormText | ||
371 | + readonly | ||
372 | + width="md" | ||
373 | + name="partyBOpenBank" | ||
374 | + label="开户银行" | ||
375 | + colProps={{ | ||
376 | + span: 8, | ||
377 | + }} | ||
378 | + placeholder="请输入名称" | ||
379 | + /> | ||
380 | + <ProFormText | ||
381 | + readonly | ||
382 | + width="md" | ||
383 | + name="partyBBankAccount" | ||
384 | + label="银行账号" | ||
385 | + colProps={{ | ||
386 | + span: 8, | ||
387 | + }} | ||
388 | + placeholder="请输入名称" | ||
389 | + /> | ||
390 | + <ProFormText | ||
391 | + readonly | ||
392 | + width="md" | ||
393 | + colProps={{ | ||
394 | + span: 8, | ||
395 | + }} | ||
396 | + name="partyBAddress" | ||
397 | + label="销方地址" | ||
398 | + placeholder="请输入名称" | ||
399 | + /> | ||
400 | + <ProFormText | ||
401 | + readonly | ||
402 | + width="md" | ||
403 | + colProps={{ | ||
404 | + span: 8, | ||
405 | + }} | ||
406 | + name="partyBPhoneNumber" | ||
407 | + label="电话" | ||
408 | + placeholder="请输入名称" | ||
409 | + /> | ||
410 | + </ProForm.Group> | ||
411 | + </ProCard> | ||
412 | + <hr /> | ||
413 | + <ProCard title="发票明细" bordered headerBordered size={'small'}> | ||
414 | + <InvoiceDetailTable | ||
415 | + recordId={id} | ||
416 | + details={detailTableData} | ||
417 | + updateDetails={updateDetails} | ||
418 | + readOnly={readOnly} | ||
419 | + /> | ||
420 | + </ProCard> | ||
421 | + <hr /> | ||
422 | + <ProCard title="备注" bordered headerBordered size={'small'}> | ||
423 | + <ProFormTextArea | ||
424 | + readonly={readOnly} | ||
425 | + name="comment" | ||
426 | + placeholder="请输入备注" | ||
427 | + /> | ||
428 | + </ProCard> | ||
429 | + </ModalForm> | ||
430 | + </Space> | ||
431 | + </> | ||
432 | + ); | ||
433 | +}; |
src/pages/Invoice/components/InvoicingModal.tsx
0 → 100644
1 | +import { RESPONSE_CODE } from '@/constants/enum'; | ||
2 | +import { postServiceInvoiceInvoicing } from '@/services'; | ||
3 | +import { ModalForm } from '@ant-design/pro-components'; | ||
4 | +import { Button, Form, message } from 'antd'; | ||
5 | + | ||
6 | +export default ({ selectedRowKeys, reloadRecordTable }) => { | ||
7 | + const [form] = Form.useForm<{ name: string; company: string }>(); | ||
8 | + return ( | ||
9 | + <ModalForm<{ | ||
10 | + name: string; | ||
11 | + company: string; | ||
12 | + }> | ||
13 | + title="开票" | ||
14 | + trigger={ | ||
15 | + <Button type="primary" disabled={selectedRowKeys?.length === 0}> | ||
16 | + 开票 | ||
17 | + </Button> | ||
18 | + } | ||
19 | + form={form} | ||
20 | + autoFocusFirstInput | ||
21 | + modalProps={{ | ||
22 | + destroyOnClose: true, | ||
23 | + onCancel: () => console.log('run'), | ||
24 | + }} | ||
25 | + submitTimeout={2000} | ||
26 | + onFinish={async () => { | ||
27 | + let res = await postServiceInvoiceInvoicing({ | ||
28 | + data: { | ||
29 | + invoiceRecordIds: selectedRowKeys, | ||
30 | + }, | ||
31 | + }); | ||
32 | + if (res.result === RESPONSE_CODE.SUCCESS) { | ||
33 | + message.success(res.message); | ||
34 | + } | ||
35 | + reloadRecordTable(); | ||
36 | + message.success('提交成功'); | ||
37 | + return true; | ||
38 | + }} | ||
39 | + ></ModalForm> | ||
40 | + ); | ||
41 | +}; |
src/pages/Invoice/index.tsx
@@ -2,6 +2,9 @@ import ButtonConfirm from '@/components/ButtomConfirm'; | @@ -2,6 +2,9 @@ import ButtonConfirm from '@/components/ButtomConfirm'; | ||
2 | import EllipsisDiv from '@/components/Div/EllipsisDiv'; | 2 | import EllipsisDiv from '@/components/Div/EllipsisDiv'; |
3 | import { RESPONSE_CODE } from '@/constants/enum'; | 3 | import { RESPONSE_CODE } from '@/constants/enum'; |
4 | import AddInvoiceDrawerForm from '@/pages/Invoice/components/AddInvoiceDrawerForm'; | 4 | import AddInvoiceDrawerForm from '@/pages/Invoice/components/AddInvoiceDrawerForm'; |
5 | +import InvoiceModal from '@/pages/Invoice/components/InvoiceModal'; | ||
6 | +import InvoiceRecordDetailModal from '@/pages/Invoice/components/InvoiceRecordDetailModal'; | ||
7 | +import InvoicingModal from '@/pages/Invoice/components/InvoicingModal'; | ||
5 | import { | 8 | import { |
6 | BANK_STATEMENT_COLUMNS, | 9 | BANK_STATEMENT_COLUMNS, |
7 | INVOICE_COLUMNS, | 10 | INVOICE_COLUMNS, |
@@ -11,15 +14,28 @@ import { | @@ -11,15 +14,28 @@ import { | ||
11 | postServiceBankStatementDeleteBankStatement, | 14 | postServiceBankStatementDeleteBankStatement, |
12 | postServiceBankStatementEditBankStatement, | 15 | postServiceBankStatementEditBankStatement, |
13 | postServiceBankStatementQueryBankStatement, | 16 | postServiceBankStatementQueryBankStatement, |
17 | + postServiceConstAfterInvoicingInvoiceRecordStatus, | ||
18 | + postServiceConstBeforeInvoicingInvoiceRecordStatus, | ||
19 | + postServiceConstInvoiceType, | ||
20 | + postServiceConstInvoicingType, | ||
14 | postServiceInvoiceDeleteInvoice, | 21 | postServiceInvoiceDeleteInvoice, |
22 | + postServiceInvoiceInvoicing, | ||
15 | postServiceInvoiceQueryInvoice, | 23 | postServiceInvoiceQueryInvoice, |
24 | + postServiceInvoiceQueryInvoiceRecordList, | ||
25 | + postServiceOrderQuerySalesCode, | ||
16 | } from '@/services'; | 26 | } from '@/services'; |
17 | -import { enumValueToLabel, formatDateTime } from '@/utils'; | 27 | +import { excelExport } from '@/services/exportRequest'; |
28 | +import { | ||
29 | + enumToProTableEnumValue, | ||
30 | + enumToSelect, | ||
31 | + enumValueToLabel, | ||
32 | + formatDateTime, | ||
33 | +} from '@/utils'; | ||
18 | import { formatDate } from '@/utils/time'; | 34 | import { formatDate } from '@/utils/time'; |
19 | import { PlusOutlined } from '@ant-design/icons'; | 35 | import { PlusOutlined } from '@ant-design/icons'; |
20 | -import { ActionType, ProTable } from '@ant-design/pro-components'; | ||
21 | -import { Button, Tabs, message } from 'antd'; | ||
22 | -import { useRef, useState } from 'react'; | 36 | +import { ActionType, ModalForm, ProTable } from '@ant-design/pro-components'; |
37 | +import { Button, Space, Table, Tabs, message } from 'antd'; | ||
38 | +import { useEffect, useRef, useState } from 'react'; | ||
23 | import { INVOCING_STATUS, PAYEE_OPTIONS } from '../Order/constant'; | 39 | import { INVOCING_STATUS, PAYEE_OPTIONS } from '../Order/constant'; |
24 | import BankImportModal from './components/BankImportModal'; | 40 | import BankImportModal from './components/BankImportModal'; |
25 | import InvoiceVerificationModal from './components/InvoiceVerificationModal'; | 41 | import InvoiceVerificationModal from './components/InvoiceVerificationModal'; |
@@ -28,10 +44,51 @@ import './index.less'; | @@ -28,10 +44,51 @@ import './index.less'; | ||
28 | const InvoicePage = () => { | 44 | const InvoicePage = () => { |
29 | const invoiceActionRef = useRef<ActionType>(); | 45 | const invoiceActionRef = useRef<ActionType>(); |
30 | const bankActionRef = useRef<ActionType>(); | 46 | const bankActionRef = useRef<ActionType>(); |
47 | + const waitDealrecordActionRef = useRef<ActionType>(); | ||
48 | + const processedRecordRef = useRef<ActionType>(); | ||
49 | + const [invoiceTypeValueEnum, setInvoiceTypeValueEnum] = useState({}); | ||
50 | + const [invoicingTypeValueEnum, setInvoicingTypeValueEnum] = useState({}); | ||
51 | + const [salesCodeValueEnum, setSalesCodeValueEnum] = useState({}); | ||
31 | const [bankImportModalVisible, setBankImportModalVisible] = useState(false); | 52 | const [bankImportModalVisible, setBankImportModalVisible] = useState(false); |
32 | const [invoiceVerificationVisible, setInvoiceVerificationVisible] = | 53 | const [invoiceVerificationVisible, setInvoiceVerificationVisible] = |
33 | useState(false); | 54 | useState(false); |
34 | const [invoiceId, setInvoiceId] = useState(undefined); | 55 | const [invoiceId, setInvoiceId] = useState(undefined); |
56 | + const [invoiceRecordDetailVisible, setInvoiceRecordDetailVisible] = | ||
57 | + useState(false); | ||
58 | + const [invoiceRecord, setInvoiceRecord] = useState({}); | ||
59 | + const [messageApi, contextHolder] = message.useMessage(); | ||
60 | + | ||
61 | + useEffect(() => { | ||
62 | + async function extracted() { | ||
63 | + let invoiceTypeRet = await postServiceConstInvoiceType(); | ||
64 | + setInvoiceTypeValueEnum(invoiceTypeRet.data); | ||
65 | + } | ||
66 | + extracted().catch(console.error); | ||
67 | + }, []); | ||
68 | + | ||
69 | + useEffect(() => { | ||
70 | + async function extracted() { | ||
71 | + let invoicingTypeRet = await postServiceConstInvoicingType(); | ||
72 | + setInvoicingTypeValueEnum(invoicingTypeRet.data); | ||
73 | + } | ||
74 | + extracted().catch(console.error); | ||
75 | + }, []); | ||
76 | + | ||
77 | + useEffect(() => { | ||
78 | + async function extracted() { | ||
79 | + const res = await postServiceOrderQuerySalesCode(); | ||
80 | + let map = {}; | ||
81 | + res.data?.forEach((item) => { | ||
82 | + map[item.userName] = { | ||
83 | + text: item.userName, | ||
84 | + status: item.userName, | ||
85 | + }; | ||
86 | + }); | ||
87 | + setSalesCodeValueEnum(map); | ||
88 | + } | ||
89 | + | ||
90 | + extracted().catch(console.error); | ||
91 | + }, []); | ||
35 | 92 | ||
36 | const reloadInvoiceTable = () => { | 93 | const reloadInvoiceTable = () => { |
37 | invoiceActionRef.current?.reload(); | 94 | invoiceActionRef.current?.reload(); |
@@ -40,6 +97,10 @@ const InvoicePage = () => { | @@ -40,6 +97,10 @@ const InvoicePage = () => { | ||
40 | const reloadBankStatementTable = () => { | 97 | const reloadBankStatementTable = () => { |
41 | bankActionRef.current?.reload(); | 98 | bankActionRef.current?.reload(); |
42 | }; | 99 | }; |
100 | + const reloadRecordTable = () => { | ||
101 | + waitDealrecordActionRef.current?.reload(); | ||
102 | + processedRecordRef.current?.reload(); | ||
103 | + }; | ||
43 | 104 | ||
44 | const getTableCellText = (target: any) => { | 105 | const getTableCellText = (target: any) => { |
45 | if (!target) { | 106 | if (!target) { |
@@ -53,6 +114,454 @@ const InvoicePage = () => { | @@ -53,6 +114,454 @@ const InvoicePage = () => { | ||
53 | return target; | 114 | return target; |
54 | }; | 115 | }; |
55 | 116 | ||
117 | + const waitDealRecordColumns = [ | ||
118 | + { | ||
119 | + dataIndex: 'index', | ||
120 | + valueType: 'indexBorder', | ||
121 | + hideInSearch: true, | ||
122 | + ellipsis: true, | ||
123 | + width: 48, | ||
124 | + }, | ||
125 | + { | ||
126 | + title: '开票编号', | ||
127 | + valueType: 'text', | ||
128 | + dataIndex: 'id', | ||
129 | + copyable: true, | ||
130 | + hideInSearch: true, | ||
131 | + ellipsis: true, | ||
132 | + width: 100, | ||
133 | + }, | ||
134 | + { | ||
135 | + title: '发票状态', | ||
136 | + valueType: 'Text', | ||
137 | + dataIndex: 'statusText', | ||
138 | + ellipsis: true, | ||
139 | + hideInSearch: true, | ||
140 | + }, | ||
141 | + { | ||
142 | + title: '申请开票时间', | ||
143 | + dataIndex: 'createTime', | ||
144 | + valueType: 'dateTime', | ||
145 | + hideInSearch: true, | ||
146 | + ellipsis: true, | ||
147 | + }, | ||
148 | + { | ||
149 | + title: '销售代表', | ||
150 | + valueType: 'text', | ||
151 | + hideInSearch: true, | ||
152 | + ellipsis: true, | ||
153 | + dataIndex: 'createByName', | ||
154 | + }, | ||
155 | + { | ||
156 | + title: '购方名称', | ||
157 | + valueType: 'text', | ||
158 | + dataIndex: 'partyAName', | ||
159 | + hideInSearch: true, | ||
160 | + ellipsis: true, | ||
161 | + }, | ||
162 | + { | ||
163 | + title: '购方税号', | ||
164 | + valueType: 'text', | ||
165 | + hideInSearch: true, | ||
166 | + dataIndex: 'partyATaxid', | ||
167 | + ellipsis: true, | ||
168 | + }, | ||
169 | + { | ||
170 | + title: '收款单位', | ||
171 | + valueType: 'text', | ||
172 | + hideInSearch: true, | ||
173 | + dataIndex: 'partyBName', | ||
174 | + ellipsis: true, | ||
175 | + }, | ||
176 | + { | ||
177 | + title: '开票金额', | ||
178 | + valueType: 'money', | ||
179 | + dataIndex: 'price', | ||
180 | + hideInSearch: true, | ||
181 | + ellipsis: true, | ||
182 | + }, | ||
183 | + { | ||
184 | + title: '开具类型', | ||
185 | + valueType: 'Text', | ||
186 | + dataIndex: 'invoicingTypeText', | ||
187 | + hideInSearch: true, | ||
188 | + ellipsis: true, | ||
189 | + }, | ||
190 | + { | ||
191 | + title: '发票类型', | ||
192 | + valueType: 'Text', | ||
193 | + dataIndex: 'typeText', | ||
194 | + hideInSearch: true, | ||
195 | + ellipsis: true, | ||
196 | + }, | ||
197 | + { | ||
198 | + title: '是否加急', | ||
199 | + valueType: 'Text', | ||
200 | + dataIndex: 'isUrgentText', | ||
201 | + hideInSearch: true, | ||
202 | + ellipsis: true, | ||
203 | + }, | ||
204 | + { | ||
205 | + title: '申请备注', | ||
206 | + valueType: 'text', | ||
207 | + dataIndex: 'applyInvoicingNotes', | ||
208 | + hideInSearch: true, | ||
209 | + ellipsis: true, | ||
210 | + }, | ||
211 | + { | ||
212 | + title: '购方名称', | ||
213 | + valueType: 'Text', | ||
214 | + dataIndex: 'partyANameLike', | ||
215 | + hideInTable: true, | ||
216 | + }, | ||
217 | + { | ||
218 | + title: '收款单位', | ||
219 | + valueType: 'select', | ||
220 | + dataIndex: 'partyB', | ||
221 | + filters: true, | ||
222 | + onFilter: true, | ||
223 | + hideInTable: true, | ||
224 | + valueEnum: enumToProTableEnumValue(PAYEE_OPTIONS), | ||
225 | + }, | ||
226 | + { | ||
227 | + title: '主订单号', | ||
228 | + valueType: 'Text', | ||
229 | + dataIndex: 'mainOrderId', | ||
230 | + hideInTable: true, | ||
231 | + }, | ||
232 | + { | ||
233 | + title: '子订单号', | ||
234 | + valueType: 'Text', | ||
235 | + dataIndex: 'subOrderId', | ||
236 | + hideInTable: true, | ||
237 | + }, | ||
238 | + { | ||
239 | + title: '销售代表', | ||
240 | + valueType: 'select', | ||
241 | + dataIndex: 'salesCode', | ||
242 | + filters: true, | ||
243 | + onFilter: true, | ||
244 | + hideInTable: true, | ||
245 | + valueEnum: salesCodeValueEnum, | ||
246 | + }, | ||
247 | + { | ||
248 | + title: '发票类型', | ||
249 | + valueType: 'select', | ||
250 | + dataIndex: 'type', | ||
251 | + filters: true, | ||
252 | + onFilter: true, | ||
253 | + hideInTable: true, | ||
254 | + valueEnum: enumToProTableEnumValue(invoiceTypeValueEnum), | ||
255 | + }, | ||
256 | + { | ||
257 | + title: '开具类型', | ||
258 | + valueType: 'select', | ||
259 | + dataIndex: 'invoicingType', | ||
260 | + filters: true, | ||
261 | + onFilter: true, | ||
262 | + hideInTable: true, | ||
263 | + valueEnum: enumToProTableEnumValue(invoicingTypeValueEnum), | ||
264 | + }, | ||
265 | + { | ||
266 | + title: '开票状态', | ||
267 | + valueType: 'select', | ||
268 | + dataIndex: 'status', | ||
269 | + filters: true, | ||
270 | + onFilter: true, | ||
271 | + hideInTable: true, | ||
272 | + request: async () => { | ||
273 | + const res = await postServiceConstBeforeInvoicingInvoiceRecordStatus(); | ||
274 | + return enumToSelect(res.data); | ||
275 | + }, | ||
276 | + }, | ||
277 | + { | ||
278 | + title: '是否加急', | ||
279 | + valueType: 'select', | ||
280 | + dataIndex: 'isUrgent', | ||
281 | + filters: true, | ||
282 | + onFilter: true, | ||
283 | + hideInTable: true, | ||
284 | + valueEnum: { | ||
285 | + true: { | ||
286 | + text: '是', | ||
287 | + status: true, | ||
288 | + }, | ||
289 | + false: { | ||
290 | + text: '否', | ||
291 | + status: false, | ||
292 | + }, | ||
293 | + }, | ||
294 | + }, | ||
295 | + { | ||
296 | + title: '申请开票时间', | ||
297 | + dataIndex: 'createTime', | ||
298 | + valueType: 'dateRange', | ||
299 | + width: 200, | ||
300 | + hideInTable: true, | ||
301 | + search: { | ||
302 | + transform: (value) => { | ||
303 | + if (value) { | ||
304 | + return { | ||
305 | + createTimeGe: value[0], | ||
306 | + createTimeLe: value[1], | ||
307 | + }; | ||
308 | + } | ||
309 | + }, | ||
310 | + }, | ||
311 | + }, | ||
312 | + { | ||
313 | + title: '操作', | ||
314 | + valueType: 'option', | ||
315 | + key: 'option', | ||
316 | + render: (text, record) => { | ||
317 | + return [ | ||
318 | + /*<InvoiceRecordDetailModal | ||
319 | + key="detail" | ||
320 | + id={record.id} | ||
321 | + subOrderIds={record.subOrderIds} | ||
322 | + onClose={()=>{ | ||
323 | + waitDealrecordActionRef.current?.reload(); | ||
324 | + } | ||
325 | + } | ||
326 | + />*/ | ||
327 | + <a | ||
328 | + key="detail" | ||
329 | + onClick={() => { | ||
330 | + setInvoiceRecordDetailVisible(true); | ||
331 | + setInvoiceRecord(record); | ||
332 | + }} | ||
333 | + > | ||
334 | + 详情 | ||
335 | + </a>, | ||
336 | + <InvoiceModal key="invoiceModal" recordId={record.id} />, | ||
337 | + ]; | ||
338 | + }, | ||
339 | + }, | ||
340 | + ]; | ||
341 | + | ||
342 | + const processedRecordColumns = [ | ||
343 | + { | ||
344 | + dataIndex: 'index', | ||
345 | + valueType: 'indexBorder', | ||
346 | + }, | ||
347 | + { | ||
348 | + title: '开票编号', | ||
349 | + valueType: 'text', | ||
350 | + dataIndex: 'id', | ||
351 | + copyable: true, | ||
352 | + ellipsis: true, | ||
353 | + }, | ||
354 | + { | ||
355 | + title: '发票号码', | ||
356 | + valueType: 'text', | ||
357 | + dataIndex: 'invoiceNumber', | ||
358 | + copyable: true, | ||
359 | + ellipsis: true, | ||
360 | + }, | ||
361 | + { | ||
362 | + title: '开票日期', | ||
363 | + dataIndex: 'invoicingTime', | ||
364 | + valueType: 'dateTime', | ||
365 | + hideInSearch: true, | ||
366 | + ellipsis: true, | ||
367 | + }, | ||
368 | + { | ||
369 | + title: '发票类型', | ||
370 | + valueType: 'Text', | ||
371 | + dataIndex: 'typeText', | ||
372 | + hideInSearch: true, | ||
373 | + ellipsis: true, | ||
374 | + }, | ||
375 | + { | ||
376 | + title: '发票状态', | ||
377 | + valueType: 'Text', | ||
378 | + dataIndex: 'statusText', | ||
379 | + hideInSearch: true, | ||
380 | + ellipsis: true, | ||
381 | + }, | ||
382 | + { | ||
383 | + title: '购方名称', | ||
384 | + valueType: 'text', | ||
385 | + dataIndex: 'partyAName', | ||
386 | + hideInSearch: true, | ||
387 | + ellipsis: true, | ||
388 | + }, | ||
389 | + { | ||
390 | + title: '购方税号', | ||
391 | + valueType: 'text', | ||
392 | + dataIndex: 'partyATaxid', | ||
393 | + ellipsis: true, | ||
394 | + }, | ||
395 | + { | ||
396 | + title: '收款单位', | ||
397 | + valueType: 'text', | ||
398 | + dataIndex: 'partyBName', | ||
399 | + hideInSearch: true, | ||
400 | + ellipsis: true, | ||
401 | + }, | ||
402 | + { | ||
403 | + title: '联系人', | ||
404 | + valueType: 'text', | ||
405 | + dataIndex: 'contacts', | ||
406 | + hideInSearch: true, | ||
407 | + ellipsis: true, | ||
408 | + }, | ||
409 | + { | ||
410 | + title: '申请人', | ||
411 | + valueType: 'text', | ||
412 | + dataIndex: 'createByName', | ||
413 | + hideInSearch: true, | ||
414 | + ellipsis: true, | ||
415 | + }, | ||
416 | + { | ||
417 | + title: '开票金额(元)', | ||
418 | + valueType: 'money', | ||
419 | + dataIndex: 'price', | ||
420 | + hideInSearch: true, | ||
421 | + ellipsis: true, | ||
422 | + }, | ||
423 | + { | ||
424 | + title: '备注', | ||
425 | + valueType: 'text', | ||
426 | + dataIndex: 'contacts', | ||
427 | + hideInSearch: true, | ||
428 | + ellipsis: true, | ||
429 | + }, | ||
430 | + { | ||
431 | + title: '失败原因', | ||
432 | + valueType: 'text', | ||
433 | + dataIndex: 'failureReason', | ||
434 | + hideInSearch: true, | ||
435 | + ellipsis: true, | ||
436 | + }, | ||
437 | + | ||
438 | + { | ||
439 | + title: '购方名称', | ||
440 | + valueType: 'text', | ||
441 | + dataIndex: 'partyANameLike', | ||
442 | + hideInTable: true, | ||
443 | + }, | ||
444 | + { | ||
445 | + title: '发票类型', | ||
446 | + valueType: 'select', | ||
447 | + dataIndex: 'type', | ||
448 | + filters: true, | ||
449 | + onFilter: true, | ||
450 | + hideInTable: true, | ||
451 | + valueEnum: enumToProTableEnumValue(invoiceTypeValueEnum), | ||
452 | + }, | ||
453 | + | ||
454 | + { | ||
455 | + title: '开票状态', | ||
456 | + valueType: 'select', | ||
457 | + dataIndex: 'status', | ||
458 | + filters: true, | ||
459 | + onFilter: true, | ||
460 | + hideInTable: true, | ||
461 | + request: async () => { | ||
462 | + const res = await postServiceConstAfterInvoicingInvoiceRecordStatus(); | ||
463 | + return enumToSelect(res.data); | ||
464 | + }, | ||
465 | + }, | ||
466 | + { | ||
467 | + title: '销售代表', | ||
468 | + valueType: 'select', | ||
469 | + dataIndex: 'salesCode', | ||
470 | + filters: true, | ||
471 | + onFilter: true, | ||
472 | + hideInTable: true, | ||
473 | + valueEnum: salesCodeValueEnum, | ||
474 | + }, | ||
475 | + { | ||
476 | + title: '联系人', | ||
477 | + valueType: 'text', | ||
478 | + dataIndex: 'contactsLike', | ||
479 | + hideInTable: true, | ||
480 | + }, | ||
481 | + { | ||
482 | + title: '开票日期', | ||
483 | + dataIndex: 'invoicingTime', | ||
484 | + valueType: 'dateRange', | ||
485 | + hideInTable: true, | ||
486 | + search: { | ||
487 | + transform: (value) => { | ||
488 | + if (value) { | ||
489 | + return { | ||
490 | + invoicingTimeGe: value[0], | ||
491 | + invoicingTimeLe: value[1], | ||
492 | + }; | ||
493 | + } | ||
494 | + }, | ||
495 | + }, | ||
496 | + }, | ||
497 | + { | ||
498 | + title: '收款单位', | ||
499 | + valueType: 'select', | ||
500 | + dataIndex: 'partyB', | ||
501 | + filters: true, | ||
502 | + onFilter: true, | ||
503 | + hideInTable: true, | ||
504 | + valueEnum: enumToProTableEnumValue(PAYEE_OPTIONS), | ||
505 | + }, | ||
506 | + { | ||
507 | + title: '操作', | ||
508 | + valueType: 'option', | ||
509 | + key: 'option', | ||
510 | + render: (text, record) => [ | ||
511 | + <a | ||
512 | + key="detail" | ||
513 | + onClick={() => { | ||
514 | + setInvoiceRecordDetailVisible(true); | ||
515 | + setInvoiceRecord(record); | ||
516 | + }} | ||
517 | + > | ||
518 | + 详情 | ||
519 | + </a>, | ||
520 | + <> | ||
521 | + {record.status === 'SUCCESS' && ( | ||
522 | + <> | ||
523 | + {record.status === 'SUCCESS' && ( | ||
524 | + <a href={record.invoiceAddress} download> | ||
525 | + 下载发票 | ||
526 | + </a> | ||
527 | + )} | ||
528 | + </> | ||
529 | + )} | ||
530 | + </>, | ||
531 | + <> | ||
532 | + {record.status === 'FAIL' && ( | ||
533 | + <ModalForm | ||
534 | + title="提示" | ||
535 | + trigger={ | ||
536 | + <Button type="link" danger> | ||
537 | + 重试 | ||
538 | + </Button> | ||
539 | + } | ||
540 | + autoFocusFirstInput | ||
541 | + modalProps={{ | ||
542 | + destroyOnClose: true, | ||
543 | + }} | ||
544 | + submitTimeout={2000} | ||
545 | + onFinish={async () => { | ||
546 | + const res = await postServiceInvoiceInvoicing({ | ||
547 | + data: { | ||
548 | + invoiceRecordIds: [record.id], | ||
549 | + }, | ||
550 | + }); | ||
551 | + if (res) { | ||
552 | + message.success(res.message); | ||
553 | + processedRecordRef?.current?.reload(); | ||
554 | + } | ||
555 | + return true; | ||
556 | + }} | ||
557 | + > | ||
558 | + 确定重试订单信息吗? | ||
559 | + </ModalForm> | ||
560 | + )} | ||
561 | + </>, | ||
562 | + ], | ||
563 | + }, | ||
564 | + ]; | ||
56 | /** | 565 | /** |
57 | * 加载发票列表表格的各个列格式 | 566 | * 加载发票列表表格的各个列格式 |
58 | */ | 567 | */ |
@@ -296,6 +805,166 @@ const InvoicePage = () => { | @@ -296,6 +805,166 @@ const InvoicePage = () => { | ||
296 | const tabsItems = [ | 805 | const tabsItems = [ |
297 | { | 806 | { |
298 | key: 1, | 807 | key: 1, |
808 | + label: '待处理', | ||
809 | + children: ( | ||
810 | + <ProTable | ||
811 | + columns={waitDealRecordColumns} | ||
812 | + actionRef={waitDealrecordActionRef} | ||
813 | + cardBordered | ||
814 | + pagination={{ | ||
815 | + pageSize: 10, | ||
816 | + }} | ||
817 | + rowSelection={{ | ||
818 | + selections: [Table.SELECTION_ALL, Table.SELECTION_INVERT], | ||
819 | + alwaysShowAlert: true, | ||
820 | + }} | ||
821 | + tableAlertOptionRender={({ selectedRowKeys, selectedRows }) => { | ||
822 | + console.log(selectedRows); | ||
823 | + console.log(selectedRowKeys); | ||
824 | + return ( | ||
825 | + <Space size={16}> | ||
826 | + <InvoicingModal | ||
827 | + reloadRecordTable={reloadRecordTable} | ||
828 | + key="button" | ||
829 | + selectedRowKeys={selectedRowKeys} | ||
830 | + /> | ||
831 | + </Space> | ||
832 | + ); | ||
833 | + }} | ||
834 | + request={async (params) => { | ||
835 | + let res = await postServiceInvoiceQueryInvoiceRecordList({ | ||
836 | + data: { | ||
837 | + ...params, | ||
838 | + statusIn: [ | ||
839 | + 'WAITING_FOR_INVOICING', | ||
840 | + 'AUDITING', | ||
841 | + 'AUDITING_NOT_PASSED', | ||
842 | + 'CANCELED', | ||
843 | + ], | ||
844 | + needBuildDetails: false, | ||
845 | + needBuildSubOrders: true, | ||
846 | + }, | ||
847 | + }); | ||
848 | + return { | ||
849 | + data: res?.data?.data, | ||
850 | + total: res?.data?.total || 0, | ||
851 | + }; | ||
852 | + }} | ||
853 | + columnsState={{ | ||
854 | + persistenceKey: 'pro-table-singe-demos', | ||
855 | + persistenceType: 'localStorage', | ||
856 | + defaultValue: { | ||
857 | + option: { fixed: 'right', disable: true }, | ||
858 | + }, | ||
859 | + onChange(value) { | ||
860 | + console.log('value: ', value); | ||
861 | + }, | ||
862 | + }} | ||
863 | + rowKey="id" | ||
864 | + search={{ | ||
865 | + labelWidth: 'auto', | ||
866 | + }} | ||
867 | + options={{ | ||
868 | + setting: { | ||
869 | + listsHeight: 400, | ||
870 | + }, | ||
871 | + }} | ||
872 | + form={{}} | ||
873 | + dateFormatter="string" | ||
874 | + headerTitle="待开票列表" | ||
875 | + scroll={{ x: 1400, y: 360 }} | ||
876 | + /> | ||
877 | + ), | ||
878 | + }, | ||
879 | + { | ||
880 | + key: 2, | ||
881 | + label: '开票记录', | ||
882 | + children: ( | ||
883 | + <ProTable | ||
884 | + columns={processedRecordColumns} | ||
885 | + actionRef={processedRecordRef} | ||
886 | + cardBordered | ||
887 | + pagination={{ | ||
888 | + pageSize: 10, | ||
889 | + }} | ||
890 | + editable={{ | ||
891 | + type: 'multiple', | ||
892 | + onSave: async (rowKey, data) => { | ||
893 | + await postServiceBankStatementEditBankStatement({ data: data }); | ||
894 | + }, | ||
895 | + actionRender: (row, config, defaultDom) => [ | ||
896 | + defaultDom.save, | ||
897 | + defaultDom.cancel, | ||
898 | + ], | ||
899 | + }} | ||
900 | + search={{ | ||
901 | + labelWidth: 'auto', | ||
902 | + defaultCollapsed: false, | ||
903 | + optionRender: (searchConfig, formProps, dom) => [ | ||
904 | + ...dom, | ||
905 | + <Button | ||
906 | + key="out" | ||
907 | + onClick={() => { | ||
908 | + const values = searchConfig?.form?.getFieldsValue(); | ||
909 | + console.log(values); | ||
910 | + messageApi.open({ | ||
911 | + type: 'loading', | ||
912 | + content: '正在导出文件...', | ||
913 | + }); | ||
914 | + excelExport( | ||
915 | + '/api/service/invoice/exportInvoiceRecords', | ||
916 | + { | ||
917 | + ...values, | ||
918 | + statusIn: ['INVOICING', 'SUCCESS', 'FAIL'], | ||
919 | + }, | ||
920 | + () => { | ||
921 | + messageApi.destroy(); | ||
922 | + }, | ||
923 | + ); | ||
924 | + }} | ||
925 | + > | ||
926 | + 导出 | ||
927 | + </Button>, | ||
928 | + ], | ||
929 | + }} | ||
930 | + request={async (params) => { | ||
931 | + let res = await postServiceInvoiceQueryInvoiceRecordList({ | ||
932 | + data: { | ||
933 | + ...params, | ||
934 | + statusIn: ['INVOICING', 'SUCCESS', 'FAIL'], | ||
935 | + }, | ||
936 | + }); | ||
937 | + return { | ||
938 | + data: res?.data?.data, | ||
939 | + total: res?.data?.total || 0, | ||
940 | + }; | ||
941 | + }} | ||
942 | + columnsState={{ | ||
943 | + persistenceKey: 'pro-table-singe-demos', | ||
944 | + persistenceType: 'localStorage', | ||
945 | + defaultValue: { | ||
946 | + option: { fixed: 'right', disable: true }, | ||
947 | + }, | ||
948 | + onChange(value) { | ||
949 | + console.log('value: ', value); | ||
950 | + }, | ||
951 | + }} | ||
952 | + rowKey="id" | ||
953 | + options={{ | ||
954 | + setting: { | ||
955 | + listsHeight: 400, | ||
956 | + }, | ||
957 | + }} | ||
958 | + form={{}} | ||
959 | + dateFormatter="string" | ||
960 | + headerTitle="待开票列表" | ||
961 | + scroll={{ x: 1400, y: 360 }} | ||
962 | + toolBarRender={() => []} | ||
963 | + /> | ||
964 | + ), | ||
965 | + }, | ||
966 | + { | ||
967 | + key: 3, | ||
299 | label: '发票管理', | 968 | label: '发票管理', |
300 | children: ( | 969 | children: ( |
301 | <ProTable | 970 | <ProTable |
@@ -352,7 +1021,7 @@ const InvoicePage = () => { | @@ -352,7 +1021,7 @@ const InvoicePage = () => { | ||
352 | ), | 1021 | ), |
353 | }, | 1022 | }, |
354 | { | 1023 | { |
355 | - key: 2, | 1024 | + key: 4, |
356 | label: '银行流水', | 1025 | label: '银行流水', |
357 | children: ( | 1026 | children: ( |
358 | <ProTable | 1027 | <ProTable |
@@ -461,6 +1130,16 @@ const InvoicePage = () => { | @@ -461,6 +1130,16 @@ const InvoicePage = () => { | ||
461 | ) : ( | 1130 | ) : ( |
462 | '' | 1131 | '' |
463 | )} | 1132 | )} |
1133 | + {invoiceRecordDetailVisible ? ( | ||
1134 | + <InvoiceRecordDetailModal | ||
1135 | + key="detail" | ||
1136 | + id={invoiceRecord.id} | ||
1137 | + setVisible={setInvoiceRecordDetailVisible} | ||
1138 | + /> | ||
1139 | + ) : ( | ||
1140 | + '' | ||
1141 | + )} | ||
1142 | + {contextHolder} | ||
464 | </div> | 1143 | </div> |
465 | ); | 1144 | ); |
466 | }; | 1145 | }; |
src/pages/Order/components/CheckModal.tsx
@@ -8,7 +8,11 @@ import { | @@ -8,7 +8,11 @@ import { | ||
8 | postServiceOrderLeaderAudit, | 8 | postServiceOrderLeaderAudit, |
9 | postServiceOrderToProcureAudit, | 9 | postServiceOrderToProcureAudit, |
10 | } from '@/services'; | 10 | } from '@/services'; |
11 | -import { ModalForm, ProFormTextArea } from '@ant-design/pro-components'; | 11 | +import { |
12 | + ModalForm, | ||
13 | + ProFormTextArea, | ||
14 | + ProList, | ||
15 | +} from '@ant-design/pro-components'; | ||
12 | import { | 16 | import { |
13 | Button, | 17 | Button, |
14 | Col, | 18 | Col, |
@@ -17,6 +21,8 @@ import { | @@ -17,6 +21,8 @@ import { | ||
17 | Image, | 21 | Image, |
18 | Modal, | 22 | Modal, |
19 | Row, | 23 | Row, |
24 | + Space, | ||
25 | + Tag, | ||
20 | UploadFile, | 26 | UploadFile, |
21 | message, | 27 | message, |
22 | } from 'antd'; | 28 | } from 'antd'; |
@@ -28,6 +34,7 @@ import { | @@ -28,6 +34,7 @@ import { | ||
28 | COMFIR_RECEIPT_IMAGES_NUMBER, | 34 | COMFIR_RECEIPT_IMAGES_NUMBER, |
29 | } from '../constant'; | 35 | } from '../constant'; |
30 | // import { cloneDeep } from 'lodash'; | 36 | // import { cloneDeep } from 'lodash'; |
37 | +import InvoiceSubOrderInfoTable from '@/pages/Order/components/InvoiceSubOrderInfoTable'; | ||
31 | import { enumValueToLabel, transImageFile } from '@/utils'; | 38 | import { enumValueToLabel, transImageFile } from '@/utils'; |
32 | import { PlusOutlined } from '@ant-design/icons'; | 39 | import { PlusOutlined } from '@ant-design/icons'; |
33 | import { cloneDeep } from 'lodash'; | 40 | import { cloneDeep } from 'lodash'; |
@@ -62,7 +69,6 @@ export default ({ | @@ -62,7 +69,6 @@ export default ({ | ||
62 | 69 | ||
63 | const [afterSalesInfo, setAfterSalesInfo] = useState<any>(); | 70 | const [afterSalesInfo, setAfterSalesInfo] = useState<any>(); |
64 | const [prepaidProofImages, setPrepaidProofImages] = useState<any[]>([]); | 71 | const [prepaidProofImages, setPrepaidProofImages] = useState<any[]>([]); |
65 | - | ||
66 | /** | 72 | /** |
67 | * 审核类型 | 73 | * 审核类型 |
68 | */ | 74 | */ |
@@ -674,6 +680,57 @@ export default ({ | @@ -674,6 +680,57 @@ export default ({ | ||
674 | ) : ( | 680 | ) : ( |
675 | '' | 681 | '' |
676 | )} | 682 | )} |
683 | + {checkType(CHECK_TYPE.CONFIRM_REISSUE) && ( | ||
684 | + <> | ||
685 | + <InvoiceSubOrderInfoTable | ||
686 | + subOrderIds={subOrderIds} | ||
687 | + ></InvoiceSubOrderInfoTable> | ||
688 | + </> | ||
689 | + )} | ||
690 | + {checkType(CHECK_TYPE.URGENT_INVOICE_AUDITING) ? ( | ||
691 | + <> | ||
692 | + <ProList | ||
693 | + rowKey="id" | ||
694 | + headerTitle="发票信息" | ||
695 | + metas={{ | ||
696 | + title: { | ||
697 | + dataIndex: 'name', | ||
698 | + }, | ||
699 | + avatar: { | ||
700 | + dataIndex: 'image', | ||
701 | + editable: false, | ||
702 | + }, | ||
703 | + description: { | ||
704 | + dataIndex: 'desc', | ||
705 | + }, | ||
706 | + subTitle: { | ||
707 | + render: () => { | ||
708 | + return ( | ||
709 | + <Space size={0}> | ||
710 | + <Tag color="blue">Ant Design</Tag> | ||
711 | + <Tag color="#5BD8A6">TechUI</Tag> | ||
712 | + </Space> | ||
713 | + ); | ||
714 | + }, | ||
715 | + }, | ||
716 | + actions: { | ||
717 | + render: (text, row, index, action) => [ | ||
718 | + <a | ||
719 | + onClick={() => { | ||
720 | + action?.startEditable(row.id); | ||
721 | + }} | ||
722 | + key="link" | ||
723 | + > | ||
724 | + 编辑 | ||
725 | + </a>, | ||
726 | + ], | ||
727 | + }, | ||
728 | + }} | ||
729 | + ></ProList> | ||
730 | + </> | ||
731 | + ) : ( | ||
732 | + '' | ||
733 | + )} | ||
677 | </ModalForm> | 734 | </ModalForm> |
678 | 735 | ||
679 | <Modal | 736 | <Modal |
src/pages/Order/components/InvoiceSubOrderInfoTable.tsx
0 → 100644
1 | +import { postServiceOrderGetReissueInfo } from '@/services'; | ||
2 | +import type { ProColumns } from '@ant-design/pro-components'; | ||
3 | +import { ProTable } from '@ant-design/pro-components'; | ||
4 | +import { Button, Divider } from 'antd'; | ||
5 | +import { useEffect, useState } from 'react'; | ||
6 | + | ||
7 | +const columns: ProColumns[] = [ | ||
8 | + { | ||
9 | + title: '发票号码', | ||
10 | + width: 80, | ||
11 | + dataIndex: 'invoiceNumber', | ||
12 | + render: (_) => _, | ||
13 | + }, | ||
14 | + { | ||
15 | + title: '关联订单', | ||
16 | + dataIndex: 'subOrderIds', | ||
17 | + render: (_, { subOrderIds }) => { | ||
18 | + console.log(JSON.stringify(_)); | ||
19 | + console.log(JSON.stringify(subOrderIds)); | ||
20 | + return ( | ||
21 | + <> | ||
22 | + {subOrderIds.map((subOrderId, index) => { | ||
23 | + return ( | ||
24 | + <> | ||
25 | + <Button | ||
26 | + key={index} | ||
27 | + className="pl-1 pr-0" | ||
28 | + type="link" | ||
29 | + target="_blank" | ||
30 | + href={'/order?id=' + subOrderId} | ||
31 | + > | ||
32 | + {subOrderId} | ||
33 | + </Button> | ||
34 | + <Divider type="vertical" /> | ||
35 | + </> | ||
36 | + ); | ||
37 | + })} | ||
38 | + </> | ||
39 | + ); | ||
40 | + }, | ||
41 | + }, | ||
42 | +]; | ||
43 | + | ||
44 | +export default ({ subOrderIds }) => { | ||
45 | + const [reissueInfos, setReissueInfos] = useState([]); | ||
46 | + useEffect(() => { | ||
47 | + console.log('info'); | ||
48 | + const getReissueInfo = async () => { | ||
49 | + let res = await postServiceOrderGetReissueInfo({ | ||
50 | + data: subOrderIds, | ||
51 | + }); | ||
52 | + setReissueInfos(res.data); | ||
53 | + }; | ||
54 | + getReissueInfo(); | ||
55 | + }, []); | ||
56 | + return ( | ||
57 | + <ProTable | ||
58 | + dataSource={reissueInfos} | ||
59 | + rowKey="key" | ||
60 | + pagination={false} | ||
61 | + size={'small'} | ||
62 | + //设置左右下边距为0 | ||
63 | + options={false} | ||
64 | + columns={columns} | ||
65 | + search={false} | ||
66 | + dateFormatter="string" | ||
67 | + headerTitle="发票信息" | ||
68 | + /> | ||
69 | + ); | ||
70 | +}; |
src/pages/Order/components/InvoicingDrawerForm.tsx
1 | +// import { PlusOutlined } from '@ant-design/icons'; | ||
2 | +import InvoiceModal from '@/pages/Invoice/components/InvoiceModal'; | ||
3 | +import { | ||
4 | + postServiceConstGetPayeeEnum, | ||
5 | + postServiceConstInvoiceType, | ||
6 | + postServiceConstInvoicingType, | ||
7 | + postServiceConstListInvoiceDetailNames, | ||
8 | + postServiceInvoiceApplyInvoice, | ||
9 | +} from '@/services'; | ||
10 | +import { enumToSelect } from '@/utils'; | ||
1 | import { | 11 | import { |
2 | DrawerForm, | 12 | DrawerForm, |
3 | - ProForm, | ||
4 | - ProFormDateRangePicker, | 13 | + ProCard, |
14 | + ProFormDigit, | ||
15 | + ProFormGroup, | ||
16 | + ProFormList, | ||
17 | + ProFormMoney, | ||
5 | ProFormSelect, | 18 | ProFormSelect, |
6 | ProFormText, | 19 | ProFormText, |
20 | + ProFormTextArea, | ||
7 | } from '@ant-design/pro-components'; | 21 | } from '@ant-design/pro-components'; |
8 | -import { Form, message } from 'antd'; | ||
9 | - | ||
10 | -const waitTime = (time: number = 100) => { | ||
11 | - return new Promise((resolve) => { | ||
12 | - setTimeout(() => { | ||
13 | - resolve(true); | ||
14 | - }, time); | ||
15 | - }); | ||
16 | -}; | ||
17 | - | ||
18 | -export default ({ subOrders, totalPayment, onClose }) => { | ||
19 | - const [form] = Form.useForm<{ name: string; company: string }>(); | 22 | +import { Button, Form } from 'antd'; |
23 | +import { useEffect } from 'react'; | ||
20 | 24 | ||
25 | +export default ({ dataList, mainOrder, setVisible, onClose }) => { | ||
26 | + // let subOrderIds = dataList?.map((item) => { | ||
27 | + // return item.id; | ||
28 | + // }); | ||
29 | + const [form] = Form.useForm(); | ||
30 | + useEffect(() => {}, []); | ||
21 | return ( | 31 | return ( |
22 | - <DrawerForm<{ | ||
23 | - name: string; | ||
24 | - company: string; | ||
25 | - }> | ||
26 | - title="新建表单" | 32 | + <DrawerForm |
33 | + open | ||
34 | + title="合并开票" | ||
27 | resize={{ | 35 | resize={{ |
28 | onResize() { | 36 | onResize() { |
29 | console.log('resize!'); | 37 | console.log('resize!'); |
30 | }, | 38 | }, |
31 | maxWidth: window.innerWidth * 0.8, | 39 | maxWidth: window.innerWidth * 0.8, |
32 | - minWidth: 300, | 40 | + minWidth: 400, |
33 | }} | 41 | }} |
34 | form={form} | 42 | form={form} |
35 | - /*trigger={ | ||
36 | - <Button type="primary"> | ||
37 | - <PlusOutlined /> | ||
38 | - 新建表单 | ||
39 | - </Button> | ||
40 | - }*/ | ||
41 | - open={true} | ||
42 | autoFocusFirstInput | 43 | autoFocusFirstInput |
43 | drawerProps={{ | 44 | drawerProps={{ |
44 | destroyOnClose: true, | 45 | destroyOnClose: true, |
45 | }} | 46 | }} |
47 | + submitter={{ | ||
48 | + render: (props, defaultDoms) => { | ||
49 | + return [ | ||
50 | + <InvoiceModal | ||
51 | + key={'invoicePreview'} | ||
52 | + button={<Button type="primary"> 发票预览 </Button>} | ||
53 | + getRecord={form.getFieldsValue} | ||
54 | + />, | ||
55 | + ...defaultDoms, | ||
56 | + ]; | ||
57 | + }, | ||
58 | + }} | ||
46 | submitTimeout={2000} | 59 | submitTimeout={2000} |
47 | onFinish={async (values) => { | 60 | onFinish={async (values) => { |
48 | - await waitTime(2000); | ||
49 | - console.log(values); | ||
50 | - console.log(subOrders); | ||
51 | - console.log(totalPayment); | ||
52 | - message.success('提交成功'); | 61 | + postServiceInvoiceApplyInvoice({ |
62 | + data: { | ||
63 | + ...values, | ||
64 | + subOrderIds: dataList.map((item) => { | ||
65 | + return item.id; | ||
66 | + }), | ||
67 | + }, | ||
68 | + }); | ||
53 | onClose(); | 69 | onClose(); |
54 | - // 不返回不会关闭弹框 | ||
55 | - return true; | 70 | + }} |
71 | + onOpenChange={(val) => { | ||
72 | + return !val && setVisible(); | ||
56 | }} | 73 | }} |
57 | > | 74 | > |
58 | - <ProForm.Group> | ||
59 | - <ProFormText | ||
60 | - name="name" | ||
61 | - width="md" | ||
62 | - label="签约客户名称" | ||
63 | - tooltip="最长为 24 位" | ||
64 | - placeholder="请输入名称" | ||
65 | - /> | ||
66 | - <ProFormText | ||
67 | - rules={[ | ||
68 | - { | ||
69 | - required: true, | ||
70 | - }, | ||
71 | - ]} | ||
72 | - width="md" | ||
73 | - name="company" | ||
74 | - label="我方公司名称" | ||
75 | - placeholder="请输入名称" | ||
76 | - /> | ||
77 | - </ProForm.Group> | ||
78 | - <ProForm.Group> | ||
79 | - <ProFormText | ||
80 | - width="md" | ||
81 | - name="contract" | ||
82 | - label="合同名称" | ||
83 | - placeholder="请输入名称" | ||
84 | - /> | ||
85 | - <ProFormDateRangePicker name="contractTime" label="合同生效时间" /> | ||
86 | - </ProForm.Group> | ||
87 | - <ProForm.Group> | ||
88 | - <ProFormSelect | ||
89 | - options={[ | ||
90 | - { | ||
91 | - value: 'chapter', | ||
92 | - label: '盖章后生效', | ||
93 | - }, | ||
94 | - ]} | ||
95 | - width="xs" | ||
96 | - name="useMode" | ||
97 | - label="合同约定生效方式" | ||
98 | - /> | ||
99 | - <ProFormSelect | ||
100 | - width="xs" | ||
101 | - options={[ | ||
102 | - { | ||
103 | - value: 'time', | ||
104 | - label: '履行完终止', | ||
105 | - }, | ||
106 | - ]} | ||
107 | - formItemProps={{ | ||
108 | - style: { | ||
109 | - margin: 0, | ||
110 | - }, | ||
111 | - }} | ||
112 | - name="unusedMode" | ||
113 | - label="合同约定失效效方式" | ||
114 | - /> | ||
115 | - </ProForm.Group> | ||
116 | - <ProFormText width="sm" name="id" label="主合同编号" /> | 75 | + <ProFormList |
76 | + name="subOrderIdObjs" | ||
77 | + readonly={true} | ||
78 | + label="开票订单" | ||
79 | + initialValue={dataList.map((item) => { | ||
80 | + return { | ||
81 | + value: item.id, | ||
82 | + }; | ||
83 | + })} | ||
84 | + deleteIconProps={false} | ||
85 | + > | ||
86 | + <ProFormGroup key="group"> | ||
87 | + <ProFormText readonly={true} name="value" label="" /> | ||
88 | + </ProFormGroup> | ||
89 | + </ProFormList> | ||
90 | + <ProFormText | ||
91 | + rules={[ | ||
92 | + { | ||
93 | + required: true, | ||
94 | + }, | ||
95 | + ]} | ||
96 | + width="md" | ||
97 | + name="partyAName" | ||
98 | + label="购方名称" | ||
99 | + initialValue={mainOrder.institution} | ||
100 | + placeholder="请输入名称" | ||
101 | + /> | ||
117 | <ProFormText | 102 | <ProFormText |
118 | - name="project" | ||
119 | - disabled | ||
120 | - label="项目名称" | ||
121 | - initialValue="xxxx项目" | 103 | + rules={[ |
104 | + { | ||
105 | + required: true, | ||
106 | + }, | ||
107 | + ]} | ||
108 | + width="md" | ||
109 | + name="partyATaxid" | ||
110 | + label="购方税号" | ||
111 | + placeholder="请输入名称" | ||
122 | /> | 112 | /> |
123 | <ProFormText | 113 | <ProFormText |
124 | - width="xs" | ||
125 | - name="mangerName" | ||
126 | - disabled | ||
127 | - label="商务经理" | ||
128 | - initialValue="启途" | 114 | + width="md" |
115 | + name="partyAOpenBank" | ||
116 | + label="开户银行" | ||
117 | + placeholder="请输入名称" | ||
118 | + /> | ||
119 | + <ProFormText | ||
120 | + width="md" | ||
121 | + name="partyABankAccount" | ||
122 | + label="开户行账号" | ||
123 | + placeholder="请输入名称" | ||
124 | + /> | ||
125 | + <ProFormMoney | ||
126 | + label="开票金额" | ||
127 | + name="price" | ||
128 | + locale="zh-CN" | ||
129 | + rules={[{ required: true, message: '请填写开票金额!' }]} | ||
130 | + initialValue={dataList.reduce((accumulator, currentValue) => { | ||
131 | + return accumulator + currentValue.subOrderPayment; | ||
132 | + }, 0)} | ||
133 | + /> | ||
134 | + <ProFormSelect | ||
135 | + name="invoicingType" | ||
136 | + label="开具类型" | ||
137 | + request={async () => { | ||
138 | + let invoicingTypeRet = await postServiceConstInvoicingType(); | ||
139 | + let options = enumToSelect(invoicingTypeRet.data); | ||
140 | + return options; | ||
141 | + }} | ||
142 | + placeholder="请选择开具类型" | ||
143 | + rules={[{ required: true, message: '请选择开具类型!' }]} | ||
144 | + /> | ||
145 | + <ProFormSelect | ||
146 | + name="type" | ||
147 | + label="开票类型" | ||
148 | + placeholder="请选择开票类型" | ||
149 | + rules={[{ required: true, message: '请选择开票类型!' }]} | ||
150 | + request={async () => { | ||
151 | + let invoiceTypeRet = await postServiceConstInvoiceType(); | ||
152 | + let options = enumToSelect(invoiceTypeRet.data); | ||
153 | + return options; | ||
154 | + }} | ||
155 | + /> | ||
156 | + <ProFormSelect | ||
157 | + name="partyB" | ||
158 | + label="开票收款单位" | ||
159 | + request={async () => { | ||
160 | + const res = await postServiceConstGetPayeeEnum(); | ||
161 | + let options = res?.data?.map((payee: any) => { | ||
162 | + return { | ||
163 | + ...payee, | ||
164 | + label: payee.payeeName, | ||
165 | + value: payee.name, | ||
166 | + }; | ||
167 | + }); | ||
168 | + return options; | ||
169 | + }} | ||
170 | + onChange={(_, option) => { | ||
171 | + if (option) { | ||
172 | + form.setFieldsValue({ | ||
173 | + partyBName: option.payeeName, | ||
174 | + partyBTaxid: option.taxId, | ||
175 | + }); | ||
176 | + } | ||
177 | + }} | ||
178 | + placeholder="请选择收款单位" | ||
179 | + rules={[{ required: true, message: '请选择收款单位!' }]} | ||
180 | + /> | ||
181 | + <ProFormText | ||
182 | + name="partyBName" | ||
183 | + label="开票收款单位名称" | ||
184 | + hidden | ||
185 | + rules={[{ required: true, message: '请选择收款单位!' }]} | ||
186 | + /> | ||
187 | + <ProFormText | ||
188 | + name="partyBTaxid" | ||
189 | + label="开票收款单位税号" | ||
190 | + hidden | ||
191 | + rules={[{ required: true, message: '请选择收款单位!' }]} | ||
192 | + /> | ||
193 | + <ProFormSelect | ||
194 | + name="isUrgent" | ||
195 | + label="是否加急" | ||
196 | + valueEnum={{ | ||
197 | + true: '是', | ||
198 | + false: '否', | ||
199 | + }} | ||
200 | + placeholder="请选择是否加急" | ||
201 | + rules={[{ required: true, message: '请选择是否加急!' }]} | ||
202 | + /> | ||
203 | + <ProFormList | ||
204 | + name="invoiceDetails" | ||
205 | + label="开票明细" | ||
206 | + initialValue={dataList.map((item) => { | ||
207 | + return { | ||
208 | + subOrderId: item.id, | ||
209 | + projectName: item.productName, | ||
210 | + specification: item.parameters, | ||
211 | + unit: item.unit, | ||
212 | + quantity: item.quantity, | ||
213 | + price: item.productPrice, | ||
214 | + totalPrice: item.totalPayment, | ||
215 | + }; | ||
216 | + })} | ||
217 | + rules={[ | ||
218 | + { | ||
219 | + required: true, | ||
220 | + validator: async (_, value) => { | ||
221 | + console.log(value); | ||
222 | + if (value && value.length > 0) { | ||
223 | + return; | ||
224 | + } | ||
225 | + throw new Error('至少要有一项!'); | ||
226 | + }, | ||
227 | + }, | ||
228 | + ]} | ||
229 | + itemRender={(doms, listMeta) => { | ||
230 | + console.log(listMeta); | ||
231 | + return ( | ||
232 | + <ProCard | ||
233 | + bordered | ||
234 | + extra={doms.action} | ||
235 | + title={'明细' + (listMeta.index + 1)} | ||
236 | + style={{ | ||
237 | + marginBlockEnd: 8, | ||
238 | + }} | ||
239 | + > | ||
240 | + <ProFormText | ||
241 | + key={'subOrderId' + listMeta.index} | ||
242 | + name="subOrderId" | ||
243 | + label="子订单id" | ||
244 | + hidden | ||
245 | + /> | ||
246 | + <ProFormSelect | ||
247 | + key={'projectName' + listMeta.index} | ||
248 | + width="md" | ||
249 | + showSearch | ||
250 | + name="projectName" | ||
251 | + request={async (value) => { | ||
252 | + const keywords = value.keyWords; | ||
253 | + const res = await postServiceConstListInvoiceDetailNames({ | ||
254 | + data: { | ||
255 | + nameLike: keywords, | ||
256 | + }, | ||
257 | + }); | ||
258 | + let options = res?.data?.map((c: any) => { | ||
259 | + return { | ||
260 | + ...c, | ||
261 | + label: | ||
262 | + '*' + | ||
263 | + c.productAndServiceCatagoryAbbreviation + | ||
264 | + '*' + | ||
265 | + c.name, | ||
266 | + value: | ||
267 | + '*' + | ||
268 | + c.productAndServiceCatagoryAbbreviation + | ||
269 | + '*' + | ||
270 | + c?.name, | ||
271 | + key: c.id, | ||
272 | + }; | ||
273 | + }); | ||
274 | + return options; | ||
275 | + }} | ||
276 | + fieldProps={{ | ||
277 | + filterOption() { | ||
278 | + return true; | ||
279 | + }, | ||
280 | + }} | ||
281 | + onChange={(_, option) => { | ||
282 | + let index = listMeta.index; | ||
283 | + let copyList = form.getFieldValue('invoiceDetails'); | ||
284 | + let currentData = copyList[index]; | ||
285 | + currentData.projectName = | ||
286 | + '*' + | ||
287 | + option.productAndServiceCatagoryAbbreviation + | ||
288 | + '*' + | ||
289 | + option.name; | ||
290 | + currentData.specification = option.specification; | ||
291 | + currentData.unit = option.unit; | ||
292 | + form.setFieldValue('invoiceDetails', copyList); | ||
293 | + }} | ||
294 | + debounceTime={1000} | ||
295 | + label="项目名称" | ||
296 | + placeholder="请输入名称" | ||
297 | + /> | ||
298 | + <ProFormText | ||
299 | + key={'specification' + listMeta.index} | ||
300 | + name="specification" | ||
301 | + label="规格型号" | ||
302 | + placeholder="请输入名称" | ||
303 | + /> | ||
304 | + <ProFormText | ||
305 | + key={'unit' + listMeta.index} | ||
306 | + name="unit" | ||
307 | + label="单位" | ||
308 | + placeholder="请输入名称" | ||
309 | + /> | ||
310 | + <ProFormDigit | ||
311 | + key={'quantity' + listMeta.index} | ||
312 | + label="数量" | ||
313 | + name="quantity" | ||
314 | + min={0} | ||
315 | + /> | ||
316 | + <ProFormDigit | ||
317 | + key={'price' + listMeta.index} | ||
318 | + label="单价" | ||
319 | + name="price" | ||
320 | + min={0} | ||
321 | + /> | ||
322 | + <ProFormMoney | ||
323 | + key={'totalPrice' + listMeta.index} | ||
324 | + label="金额" | ||
325 | + name="totalPrice" | ||
326 | + locale="zh-CN" | ||
327 | + /> | ||
328 | + </ProCard> | ||
329 | + ); | ||
330 | + }} | ||
331 | + ></ProFormList> | ||
332 | + <ProFormTextArea | ||
333 | + name="applyInvoicingNotes" | ||
334 | + label="备注" | ||
335 | + placeholder="请输入名称" | ||
129 | /> | 336 | /> |
130 | </DrawerForm> | 337 | </DrawerForm> |
131 | ); | 338 | ); |
src/pages/Order/components/ReissueModal.tsx
@@ -13,7 +13,7 @@ import { | @@ -13,7 +13,7 @@ import { | ||
13 | import { Form } from 'antd'; | 13 | import { Form } from 'antd'; |
14 | import { useEffect, useState } from 'react'; | 14 | import { useEffect, useState } from 'react'; |
15 | 15 | ||
16 | -export default ({ setVisible, mainOrder, onClose }) => { | 16 | +export default ({ setVisible, subOrders, onClose }) => { |
17 | const [invoiceSelectList, setInvoiceSelectList] = useState([]); | 17 | const [invoiceSelectList, setInvoiceSelectList] = useState([]); |
18 | const [mainOrders, setMainOrders] = useState(''); | 18 | const [mainOrders, setMainOrders] = useState(''); |
19 | const [submitting, setSubmitting] = useState(false); | 19 | const [submitting, setSubmitting] = useState(false); |
@@ -21,10 +21,9 @@ export default ({ setVisible, mainOrder, onClose }) => { | @@ -21,10 +21,9 @@ export default ({ setVisible, mainOrder, onClose }) => { | ||
21 | const [form] = Form.useForm<{ invoiceId: string; notes: string }>(); | 21 | const [form] = Form.useForm<{ invoiceId: string; notes: string }>(); |
22 | 22 | ||
23 | let getInvoiceSelectList = async () => { | 23 | let getInvoiceSelectList = async () => { |
24 | - console.log(mainOrder); | ||
25 | const res = await postServiceInvoiceFindInvoice({ | 24 | const res = await postServiceInvoiceFindInvoice({ |
26 | data: { | 25 | data: { |
27 | - mainOrderId: mainOrder.id, | 26 | + subOrderIdIn: subOrders.map((item) => item.id), |
28 | }, | 27 | }, |
29 | }); | 28 | }); |
30 | setInvoiceSelectList([]); | 29 | setInvoiceSelectList([]); |
src/pages/Order/constant.ts
@@ -117,11 +117,10 @@ export const CHECK_TYPE = { | @@ -117,11 +117,10 @@ export const CHECK_TYPE = { | ||
117 | */ | 117 | */ |
118 | export const getNeedInvoicing = (subOrder: any) => { | 118 | export const getNeedInvoicing = (subOrder: any) => { |
119 | if (subOrder.invoicingTime !== null && subOrder.invoicingTime !== undefined) { | 119 | if (subOrder.invoicingTime !== null && subOrder.invoicingTime !== undefined) { |
120 | - if (subOrder.afterInvoicingStatus === 'REISSUE') { | ||
121 | - return '重新开票'; | ||
122 | - } else { | ||
123 | - return '已开票'; | ||
124 | - } | 120 | + return '已开票'; |
121 | + } | ||
122 | + if (subOrder.afterInvoicingStatus === 'REISSUE') { | ||
123 | + return '重新开票'; | ||
125 | } | 124 | } |
126 | if (subOrder.invoicingStatus === 'UN_INVOICE') { | 125 | if (subOrder.invoicingStatus === 'UN_INVOICE') { |
127 | return '不需开票'; | 126 | return '不需开票'; |
@@ -232,6 +231,7 @@ export const AFTER_INVOICING_STATUS = { | @@ -232,6 +231,7 @@ export const AFTER_INVOICING_STATUS = { | ||
232 | URGENT_INVOICE_AUDIT_NOTPASS: '加急审核失败', | 231 | URGENT_INVOICE_AUDIT_NOTPASS: '加急审核失败', |
233 | PARTIAL_INVOICING: '部分开票', | 232 | PARTIAL_INVOICING: '部分开票', |
234 | COMPLETE_INVOICING: '完全开票', | 233 | COMPLETE_INVOICING: '完全开票', |
234 | + INVOICING: '开票中', | ||
235 | REISSUE: '重新开票', | 235 | REISSUE: '重新开票', |
236 | }; | 236 | }; |
237 | 237 | ||
@@ -277,6 +277,7 @@ export const TAGS_COLOR = new Map<string, string>([ | @@ -277,6 +277,7 @@ export const TAGS_COLOR = new Map<string, string>([ | ||
277 | ['AUDIT_PASS', 'success'], | 277 | ['AUDIT_PASS', 'success'], |
278 | ['AUDIT_NOTPASS', 'error'], | 278 | ['AUDIT_NOTPASS', 'error'], |
279 | ['WAIT_CONFIRM_DELIVER_AFTER_INVOICE', 'processing'], | 279 | ['WAIT_CONFIRM_DELIVER_AFTER_INVOICE', 'processing'], |
280 | + ['INVOICING', 'processing'], | ||
280 | ['SALES_CONFIRM', 'warning'], | 281 | ['SALES_CONFIRM', 'warning'], |
281 | ['URGENT_INVOICE_AUDIT_NOTPASS', 'red'], | 282 | ['URGENT_INVOICE_AUDIT_NOTPASS', 'red'], |
282 | ['REISSUE', 'processing'], | 283 | ['REISSUE', 'processing'], |
@@ -426,6 +427,12 @@ export const MAIN_ORDER_COLUMNS = [ | @@ -426,6 +427,12 @@ export const MAIN_ORDER_COLUMNS = [ | ||
426 | hideInTable: true, | 427 | hideInTable: true, |
427 | }, | 428 | }, |
428 | { | 429 | { |
430 | + title: '子订单编号', | ||
431 | + dataIndex: 'subOrderId', | ||
432 | + valueType: 'text', | ||
433 | + hideInTable: true, | ||
434 | + }, | ||
435 | + { | ||
429 | title: '销售代表', | 436 | title: '销售代表', |
430 | dataIndex: 'salesCode', | 437 | dataIndex: 'salesCode', |
431 | valueType: 'text', | 438 | valueType: 'text', |
src/pages/Order/index.tsx
@@ -6,6 +6,8 @@ import ReissueModal from '@/pages/Order/components/ReissueModal'; | @@ -6,6 +6,8 @@ import ReissueModal from '@/pages/Order/components/ReissueModal'; | ||
6 | import { | 6 | import { |
7 | postKingdeeRepSalBillOutbound, | 7 | postKingdeeRepSalBillOutbound, |
8 | postKingdeeRepSalOrderSave, | 8 | postKingdeeRepSalOrderSave, |
9 | + postServiceConstCanApplyAfterInvoicingStatus, | ||
10 | + postServiceInvoiceCancelApply, | ||
9 | postServiceOrderCancelSend, | 11 | postServiceOrderCancelSend, |
10 | postServiceOrderGetCurrentOptNode, | 12 | postServiceOrderGetCurrentOptNode, |
11 | postServiceOrderNoNeedSend, | 13 | postServiceOrderNoNeedSend, |
@@ -127,8 +129,6 @@ const OrderPage = () => { | @@ -127,8 +129,6 @@ const OrderPage = () => { | ||
127 | const [allMainChecked, setAllMainChecked] = useState(false); | 129 | const [allMainChecked, setAllMainChecked] = useState(false); |
128 | const [imagesViewerModalVisible, setImagesViewerModalVisible] = | 130 | const [imagesViewerModalVisible, setImagesViewerModalVisible] = |
129 | useState<boolean>(false); | 131 | useState<boolean>(false); |
130 | - const [InvoicingDrawerFormVisible, setInvoicingDrawerFormVisible] = | ||
131 | - useState<boolean>(false); | ||
132 | const [data, setData] = useState([]); //列表数据 | 132 | const [data, setData] = useState([]); //列表数据 |
133 | const [notesEditVisible, setNotesEditVisible] = useState<boolean>(false); | 133 | const [notesEditVisible, setNotesEditVisible] = useState<boolean>(false); |
134 | const [financialMergeDrawerVisible, setFinancialMergeDrawerVisible] = | 134 | const [financialMergeDrawerVisible, setFinancialMergeDrawerVisible] = |
@@ -159,6 +159,8 @@ const OrderPage = () => { | @@ -159,6 +159,8 @@ const OrderPage = () => { | ||
159 | useState<boolean>(false); | 159 | useState<boolean>(false); |
160 | const [procureConvertModalVisible, setProcureConvertModalVisible] = | 160 | const [procureConvertModalVisible, setProcureConvertModalVisible] = |
161 | useState<boolean>(false); | 161 | useState<boolean>(false); |
162 | + const [invoicingDrawerFormVisible, setInvoicingDrawerFormVisible] = | ||
163 | + useState<boolean>(false); | ||
162 | const [confirmReceiptVisible, setConfirmReceiptVisible] = | 164 | const [confirmReceiptVisible, setConfirmReceiptVisible] = |
163 | useState<boolean>(false); | 165 | useState<boolean>(false); |
164 | const [productionTimeModalVisible, setProductionTimeModalVisible] = | 166 | const [productionTimeModalVisible, setProductionTimeModalVisible] = |
@@ -197,6 +199,8 @@ const OrderPage = () => { | @@ -197,6 +199,8 @@ const OrderPage = () => { | ||
197 | shippingWarehouseChangeModalVisible, | 199 | shippingWarehouseChangeModalVisible, |
198 | setShippingWarehouseChangeModalVisible, | 200 | setShippingWarehouseChangeModalVisible, |
199 | ] = useState(false); | 201 | ] = useState(false); |
202 | + const [canApplyAfterInvoicingStatus, setCanApplyAfterInvoicingStatus] = | ||
203 | + useState([]); | ||
200 | const [ids, setIds] = useState([]); | 204 | const [ids, setIds] = useState([]); |
201 | const [recordOptNode, setRecordOptNode] = useState(null); | 205 | const [recordOptNode, setRecordOptNode] = useState(null); |
202 | const roleCode = userInfo?.roleSmallVO?.code; | 206 | const roleCode = userInfo?.roleSmallVO?.code; |
@@ -223,13 +227,43 @@ const OrderPage = () => { | @@ -223,13 +227,43 @@ const OrderPage = () => { | ||
223 | }; | 227 | }; |
224 | 228 | ||
225 | const refreshTable = () => { | 229 | const refreshTable = () => { |
226 | - console.log('刷新表格'); | ||
227 | mainTableRef.current?.reload(); | 230 | mainTableRef.current?.reload(); |
228 | //刷新表格数据的时候,取消选中行 | 231 | //刷新表格数据的时候,取消选中行 |
229 | setSelectedRows([]); | 232 | setSelectedRows([]); |
230 | setSelectedSubOrderKeys([]); | 233 | setSelectedSubOrderKeys([]); |
231 | }; | 234 | }; |
232 | 235 | ||
236 | + /*useEffect(() => { | ||
237 | + let initAfterInvoicingStatus = async () => { | ||
238 | + const afteInvoicingStatus = await getAfterInvoicingStatus(); | ||
239 | + setAfterInvoicingStatus(afteInvoicingStatus); | ||
240 | + }; | ||
241 | + initAfterInvoicingStatus(); | ||
242 | + }, []);*/ | ||
243 | + | ||
244 | + useEffect(() => { | ||
245 | + // 使用URLSearchParams来解析查询参数 | ||
246 | + const params = new URLSearchParams(location.search); | ||
247 | + const id = params.get('id'); | ||
248 | + const subOrderId = params.get('subOrderId'); | ||
249 | + if (id) { | ||
250 | + mainTableFormRef.current?.setFieldValue('id', id); | ||
251 | + } | ||
252 | + if (subOrderId) { | ||
253 | + mainTableFormRef.current?.setFieldValue('subOrderId', subOrderId); | ||
254 | + } | ||
255 | + }, []); | ||
256 | + | ||
257 | + useEffect(() => { | ||
258 | + const initEnum = async () => { | ||
259 | + let invoiceTypeRet = await postServiceConstCanApplyAfterInvoicingStatus(); | ||
260 | + if (invoiceTypeRet.result === RESPONSE_CODE.SUCCESS) { | ||
261 | + setCanApplyAfterInvoicingStatus(invoiceTypeRet.data); | ||
262 | + } | ||
263 | + }; | ||
264 | + initEnum(); | ||
265 | + }, []); | ||
266 | + | ||
233 | /** | 267 | /** |
234 | * 复制订单到剪贴板 | 268 | * 复制订单到剪贴板 |
235 | * @param record | 269 | * @param record |
@@ -583,9 +617,6 @@ const OrderPage = () => { | @@ -583,9 +617,6 @@ const OrderPage = () => { | ||
583 | mainOrderSelectedMap.clear(); | 617 | mainOrderSelectedMap.clear(); |
584 | subOrderSelectedMap.clear(); | 618 | subOrderSelectedMap.clear(); |
585 | } | 619 | } |
586 | - | ||
587 | - console.log(mainOrderSelectedMap); | ||
588 | - console.log(subOrderSelectedMap); | ||
589 | }; | 620 | }; |
590 | 621 | ||
591 | //表头渲染 | 622 | //表头渲染 |
@@ -1324,8 +1355,8 @@ const OrderPage = () => { | @@ -1324,8 +1355,8 @@ const OrderPage = () => { | ||
1324 | type="link" | 1355 | type="link" |
1325 | onClick={() => { | 1356 | onClick={() => { |
1326 | setCurrentMainId(record.id); | 1357 | setCurrentMainId(record.id); |
1358 | + setCurretnOptSubId(optRecord.id); | ||
1327 | setReissueVisible(true); | 1359 | setReissueVisible(true); |
1328 | - console.log(reissueVisible); | ||
1329 | }} | 1360 | }} |
1330 | > | 1361 | > |
1331 | 重新开票 | 1362 | 重新开票 |
@@ -1356,7 +1387,6 @@ const OrderPage = () => { | @@ -1356,7 +1387,6 @@ const OrderPage = () => { | ||
1356 | className="p-0" | 1387 | className="p-0" |
1357 | type="link" | 1388 | type="link" |
1358 | onClick={() => { | 1389 | onClick={() => { |
1359 | - console.log('here'); | ||
1360 | setCurrentMainId(record.id); | 1390 | setCurrentMainId(record.id); |
1361 | setCurretnOptSubId(optRecord.id); | 1391 | setCurretnOptSubId(optRecord.id); |
1362 | setCheckVisible(true); | 1392 | setCheckVisible(true); |
@@ -1466,7 +1496,7 @@ const OrderPage = () => { | @@ -1466,7 +1496,7 @@ const OrderPage = () => { | ||
1466 | '' | 1496 | '' |
1467 | )} | 1497 | )} |
1468 | 1498 | ||
1469 | - {optRecord.subPath?.includes('saleCancelInvoicing') ? ( | 1499 | + {/*{optRecord.subPath?.includes('saleCancelInvoicing') ? ( |
1470 | <ButtonConfirm | 1500 | <ButtonConfirm |
1471 | className="p-0" | 1501 | className="p-0" |
1472 | title="确认取消申请开票?" | 1502 | title="确认取消申请开票?" |
@@ -1486,6 +1516,27 @@ const OrderPage = () => { | @@ -1486,6 +1516,27 @@ const OrderPage = () => { | ||
1486 | /> | 1516 | /> |
1487 | ) : ( | 1517 | ) : ( |
1488 | '' | 1518 | '' |
1519 | + )}*/} | ||
1520 | + {optRecord.subPath?.includes('saleCancelInvoicing') ? ( | ||
1521 | + <ButtonConfirm | ||
1522 | + className="p-0" | ||
1523 | + title="确认取消申请开票?" | ||
1524 | + text="取消申请" | ||
1525 | + onConfirm={async () => { | ||
1526 | + let res = await postServiceInvoiceCancelApply({ | ||
1527 | + data: { | ||
1528 | + subOrderIds: [optRecord.id], | ||
1529 | + }, | ||
1530 | + }); | ||
1531 | + | ||
1532 | + if (res && res.result === RESPONSE_CODE.SUCCESS) { | ||
1533 | + message.success(res.message); | ||
1534 | + refreshTable(); | ||
1535 | + } | ||
1536 | + }} | ||
1537 | + /> | ||
1538 | + ) : ( | ||
1539 | + '' | ||
1489 | )} | 1540 | )} |
1490 | {optRecord.subPath?.includes('noNeedInvoicingEdit') ? ( | 1541 | {optRecord.subPath?.includes('noNeedInvoicingEdit') ? ( |
1491 | <Button | 1542 | <Button |
@@ -1701,7 +1752,7 @@ const OrderPage = () => { | @@ -1701,7 +1752,7 @@ const OrderPage = () => { | ||
1701 | '' | 1752 | '' |
1702 | )} | 1753 | )} |
1703 | 1754 | ||
1704 | - {optRecord.subPath?.includes('applyInvoicing') ? ( | 1755 | + {/*{optRecord.subPath?.includes('applyInvoicing') ? ( |
1705 | <Button | 1756 | <Button |
1706 | className="p-0" | 1757 | className="p-0" |
1707 | type="link" | 1758 | type="link" |
@@ -1716,6 +1767,23 @@ const OrderPage = () => { | @@ -1716,6 +1767,23 @@ const OrderPage = () => { | ||
1716 | </Button> | 1767 | </Button> |
1717 | ) : ( | 1768 | ) : ( |
1718 | '' | 1769 | '' |
1770 | + )}*/} | ||
1771 | + | ||
1772 | + {optRecord.subPath?.includes('applyInvoicing') ? ( | ||
1773 | + <Button | ||
1774 | + className="p-0" | ||
1775 | + type="link" | ||
1776 | + onClick={() => { | ||
1777 | + setInvoicingDrawerFormVisible(true); | ||
1778 | + createOptObject(optRecord.id, record.id); | ||
1779 | + setIsEdit(false); | ||
1780 | + setIsMainOrder(false); | ||
1781 | + }} | ||
1782 | + > | ||
1783 | + 申请开票 | ||
1784 | + </Button> | ||
1785 | + ) : ( | ||
1786 | + '' | ||
1719 | )} | 1787 | )} |
1720 | 1788 | ||
1721 | {optRecord.subPath?.includes('checkOrder') ? ( | 1789 | {optRecord.subPath?.includes('checkOrder') ? ( |
@@ -2231,9 +2299,6 @@ const OrderPage = () => { | @@ -2231,9 +2299,6 @@ const OrderPage = () => { | ||
2231 | 2299 | ||
2232 | setSelectedSubOrderKeys(newSelectedSubOrderKeys); | 2300 | setSelectedSubOrderKeys(newSelectedSubOrderKeys); |
2233 | setSelectedRows(currentMainOrderSelectedSubOrderList); | 2301 | setSelectedRows(currentMainOrderSelectedSubOrderList); |
2234 | - | ||
2235 | - console.log(mainOrderSelectedMap); | ||
2236 | - console.log(subOrderSelectedMap); | ||
2237 | }, | 2302 | }, |
2238 | selectedRowKeys: selectedSubOrderKeys, | 2303 | selectedRowKeys: selectedSubOrderKeys, |
2239 | // 自定义选择项参考: https://ant.design/components/table-cn/#components-table-demo-row-selection-custom | 2304 | // 自定义选择项参考: https://ant.design/components/table-cn/#components-table-demo-row-selection-custom |
@@ -2711,7 +2776,6 @@ const OrderPage = () => { | @@ -2711,7 +2776,6 @@ const OrderPage = () => { | ||
2711 | onClick={() => { | 2776 | onClick={() => { |
2712 | setCurrentMainId(record.id); | 2777 | setCurrentMainId(record.id); |
2713 | setReissueVisible(true); | 2778 | setReissueVisible(true); |
2714 | - console.log(reissueVisible); | ||
2715 | }} | 2779 | }} |
2716 | > | 2780 | > |
2717 | 重新开票 | 2781 | 重新开票 |
@@ -3150,7 +3214,7 @@ const OrderPage = () => { | @@ -3150,7 +3214,7 @@ const OrderPage = () => { | ||
3150 | '' | 3214 | '' |
3151 | )} | 3215 | )} |
3152 | 3216 | ||
3153 | - {record.mainPath?.includes('applyInvoicing') ? ( | 3217 | + {/*{record.mainPath?.includes('applyInvoicing') ? ( |
3154 | <Button | 3218 | <Button |
3155 | type="link" | 3219 | type="link" |
3156 | className="p-0" | 3220 | className="p-0" |
@@ -3185,6 +3249,43 @@ const OrderPage = () => { | @@ -3185,6 +3249,43 @@ const OrderPage = () => { | ||
3185 | </Button> | 3249 | </Button> |
3186 | ) : ( | 3250 | ) : ( |
3187 | '' | 3251 | '' |
3252 | + )}*/} | ||
3253 | + | ||
3254 | + {record.mainPath?.includes('applyInvoicing') ? ( | ||
3255 | + <Button | ||
3256 | + type="link" | ||
3257 | + className="p-0" | ||
3258 | + onClick={() => { | ||
3259 | + let selectedSubOrders = subOrderSelectedMap.get( | ||
3260 | + record.id, | ||
3261 | + ); | ||
3262 | + if (selectedSubOrders === undefined) { | ||
3263 | + selectedSubOrders = record.subOrderInformationLists; | ||
3264 | + } | ||
3265 | + for (let i = 0; i < selectedSubOrders.length; i++) { | ||
3266 | + if ( | ||
3267 | + selectedSubOrders[i].invoicingStatus === | ||
3268 | + 'UN_INVOICE' || | ||
3269 | + selectedSubOrders[i].afterInvoicingStatus === | ||
3270 | + 'APPLY_FOR_INVOICING' | ||
3271 | + ) { | ||
3272 | + message.error( | ||
3273 | + '请选择需要开票且未申请开票的子订单进行申请', | ||
3274 | + ); | ||
3275 | + return; | ||
3276 | + } | ||
3277 | + } | ||
3278 | + | ||
3279 | + createOptObject(null, record.id); | ||
3280 | + setInvoicingDrawerFormVisible(true); | ||
3281 | + setIsEdit(false); | ||
3282 | + setIsMainOrder(false); | ||
3283 | + }} | ||
3284 | + > | ||
3285 | + 申请开票 | ||
3286 | + </Button> | ||
3287 | + ) : ( | ||
3288 | + '' | ||
3188 | )} | 3289 | )} |
3189 | 3290 | ||
3190 | {record.mainPath?.includes('updateOrder') ? ( | 3291 | {record.mainPath?.includes('updateOrder') ? ( |
@@ -3402,7 +3503,6 @@ const OrderPage = () => { | @@ -3402,7 +3503,6 @@ const OrderPage = () => { | ||
3402 | selectedSubOrders = record.subOrderInformationLists; | 3503 | selectedSubOrders = record.subOrderInformationLists; |
3403 | } | 3504 | } |
3404 | 3505 | ||
3405 | - console.log(selectedSubOrders); | ||
3406 | for (let i = 0; i < selectedSubOrders.length; i++) { | 3506 | for (let i = 0; i < selectedSubOrders.length; i++) { |
3407 | if ( | 3507 | if ( |
3408 | selectedSubOrders[i].afterInvoicingStatus !== | 3508 | selectedSubOrders[i].afterInvoicingStatus !== |
@@ -3990,39 +4090,39 @@ const OrderPage = () => { | @@ -3990,39 +4090,39 @@ const OrderPage = () => { | ||
3990 | //导出按钮配置 | 4090 | //导出按钮配置 |
3991 | const auditItems: MenuProps['items'] = [ | 4091 | const auditItems: MenuProps['items'] = [ |
3992 | { | 4092 | { |
3993 | - label: '领导审核', | ||
3994 | - key: '2', | 4093 | + label: '后置审核', |
4094 | + key: '1', | ||
3995 | onClick: async () => { | 4095 | onClick: async () => { |
3996 | setIsMainOrder(true); | 4096 | setIsMainOrder(true); |
3997 | setCheckVisible(true); | 4097 | setCheckVisible(true); |
3998 | - setOrderCheckType(CHECK_TYPE.LEADER_AUDIT); | 4098 | + setOrderCheckType(CHECK_TYPE.WAITING_FOR_POST_AUDIT); |
3999 | }, | 4099 | }, |
4000 | }, | 4100 | }, |
4001 | { | 4101 | { |
4002 | - label: '后置审核', | ||
4003 | - key: '1', | 4102 | + label: '加急开票审核', |
4103 | + key: '2', | ||
4004 | onClick: async () => { | 4104 | onClick: async () => { |
4005 | setIsMainOrder(true); | 4105 | setIsMainOrder(true); |
4006 | setCheckVisible(true); | 4106 | setCheckVisible(true); |
4007 | - setOrderCheckType(CHECK_TYPE.WAITING_FOR_POST_AUDIT); | 4107 | + setOrderCheckType(CHECK_TYPE.URGENT_INVOICE_AUDITING); |
4008 | }, | 4108 | }, |
4009 | }, | 4109 | }, |
4010 | { | 4110 | { |
4011 | - label: '修改申请审核', | 4111 | + label: '领导审核', |
4012 | key: '3', | 4112 | key: '3', |
4013 | onClick: async () => { | 4113 | onClick: async () => { |
4014 | setIsMainOrder(true); | 4114 | setIsMainOrder(true); |
4015 | setCheckVisible(true); | 4115 | setCheckVisible(true); |
4016 | - setOrderCheckType(CHECK_TYPE.MODIFY_APPLY_WAIT_FOR_AUDIT); | 4116 | + setOrderCheckType(CHECK_TYPE.LEADER_AUDIT); |
4017 | }, | 4117 | }, |
4018 | }, | 4118 | }, |
4019 | { | 4119 | { |
4020 | - label: '加急开票审核', | 4120 | + label: '修改申请审核', |
4021 | key: '4', | 4121 | key: '4', |
4022 | onClick: async () => { | 4122 | onClick: async () => { |
4023 | setIsMainOrder(true); | 4123 | setIsMainOrder(true); |
4024 | setCheckVisible(true); | 4124 | setCheckVisible(true); |
4025 | - setOrderCheckType(CHECK_TYPE.URGENT_INVOICE_AUDITING); | 4125 | + setOrderCheckType(CHECK_TYPE.MODIFY_APPLY_WAIT_FOR_AUDIT); |
4026 | }, | 4126 | }, |
4027 | }, | 4127 | }, |
4028 | ]; | 4128 | ]; |
@@ -4116,19 +4216,6 @@ const OrderPage = () => { | @@ -4116,19 +4216,6 @@ const OrderPage = () => { | ||
4116 | ); | 4216 | ); |
4117 | } | 4217 | } |
4118 | 4218 | ||
4119 | - <Button | ||
4120 | - type="primary" | ||
4121 | - key="out" | ||
4122 | - onClick={() => { | ||
4123 | - setIsEdit(false); | ||
4124 | - setIsMainOrder(true); | ||
4125 | - setInvoicingDrawerFormVisible(true); | ||
4126 | - }} | ||
4127 | - disabled={selectedSubOrderKeys?.length === 0} | ||
4128 | - > | ||
4129 | - 申请开票 | ||
4130 | - </Button>; | ||
4131 | - | ||
4132 | if (rolePath?.includes('mergeInvoicing')) { | 4219 | if (rolePath?.includes('mergeInvoicing')) { |
4133 | toolBtns.push( | 4220 | toolBtns.push( |
4134 | <Button | 4221 | <Button |
@@ -4165,6 +4252,35 @@ const OrderPage = () => { | @@ -4165,6 +4252,35 @@ const OrderPage = () => { | ||
4165 | ); | 4252 | ); |
4166 | } | 4253 | } |
4167 | 4254 | ||
4255 | + toolBtns.push( | ||
4256 | + <Button | ||
4257 | + type="primary" | ||
4258 | + key="inv" | ||
4259 | + onClick={() => { | ||
4260 | + setIsMainOrder(true); | ||
4261 | + let flat = [...subOrderSelectedMap.values()].flat(); | ||
4262 | + //遍历flat,判断afterInvoicingStatusList存在于canApplyAfterInvoicingStatus | ||
4263 | + flat.forEach((item) => { | ||
4264 | + if ( | ||
4265 | + item.invoicingStatus === 'UN_INVOICE' || | ||
4266 | + (item.afterInvoicingStatus !== null && | ||
4267 | + !canApplyAfterInvoicingStatus.includes( | ||
4268 | + item.afterInvoicingStatus, | ||
4269 | + )) | ||
4270 | + ) { | ||
4271 | + message.error('存在不能进行开票的订单'); | ||
4272 | + return; | ||
4273 | + } | ||
4274 | + }); | ||
4275 | + //遍历afterInvoicingStatusList | ||
4276 | + setInvoicingDrawerFormVisible(true); | ||
4277 | + }} | ||
4278 | + disabled={selectedSubOrderKeys?.length === 0} | ||
4279 | + > | ||
4280 | + 申请开票 | ||
4281 | + </Button>, | ||
4282 | + ); | ||
4283 | + | ||
4168 | if (rolePath?.includes('addOrder')) { | 4284 | if (rolePath?.includes('addOrder')) { |
4169 | toolBtns.push( | 4285 | toolBtns.push( |
4170 | <Button | 4286 | <Button |
@@ -4210,15 +4326,6 @@ const OrderPage = () => { | @@ -4210,15 +4326,6 @@ const OrderPage = () => { | ||
4210 | return toolBtns; | 4326 | return toolBtns; |
4211 | } | 4327 | } |
4212 | 4328 | ||
4213 | - useEffect(() => { | ||
4214 | - // 使用URLSearchParams来解析查询参数 | ||
4215 | - const params = new URLSearchParams(location.search); | ||
4216 | - const id = params.get('id'); | ||
4217 | - if (id) { | ||
4218 | - mainTableFormRef.current?.setFieldValue('id', id); | ||
4219 | - } | ||
4220 | - }, []); | ||
4221 | - | ||
4222 | return ( | 4329 | return ( |
4223 | <div className="order-page-container"> | 4330 | <div className="order-page-container"> |
4224 | <div id="resizeDiv"></div> | 4331 | <div id="resizeDiv"></div> |
@@ -4282,7 +4389,10 @@ const OrderPage = () => { | @@ -4282,7 +4389,10 @@ const OrderPage = () => { | ||
4282 | * 第一次进来这个页面,url带有id的话,会自动填充到查询表单中,但是第一次查询params不会带这个id进来 | 4389 | * 第一次进来这个页面,url带有id的话,会自动填充到查询表单中,但是第一次查询params不会带这个id进来 |
4283 | */ | 4390 | */ |
4284 | let orderIds = mainTableFormRef.current?.getFieldValue('id'); | 4391 | let orderIds = mainTableFormRef.current?.getFieldValue('id'); |
4392 | + let subOrderId = | ||
4393 | + mainTableFormRef.current?.getFieldValue('subOrderId'); | ||
4285 | params.id = params.id || orderIds; | 4394 | params.id = params.id || orderIds; |
4395 | + params.subOrderId = params.subOrderId || subOrderId; | ||
4286 | if (params.id !== '') { | 4396 | if (params.id !== '') { |
4287 | params.id = params.id?.replace(/ /g, ''); | 4397 | params.id = params.id?.replace(/ /g, ''); |
4288 | if (params.id?.indexOf(',')) { | 4398 | if (params.id?.indexOf(',')) { |
@@ -4715,13 +4825,15 @@ const OrderPage = () => { | @@ -4715,13 +4825,15 @@ const OrderPage = () => { | ||
4715 | <ReissueModal | 4825 | <ReissueModal |
4716 | setVisible={(val: boolean) => { | 4826 | setVisible={(val: boolean) => { |
4717 | setReissueVisible(val); | 4827 | setReissueVisible(val); |
4718 | - console.log(reissueVisible); | ||
4719 | if (!val) { | 4828 | if (!val) { |
4720 | clearOptObject(); | 4829 | clearOptObject(); |
4721 | } | 4830 | } |
4722 | }} | 4831 | }} |
4723 | - mainOrder={buildMainOrder()} | ||
4724 | - subOrders={buildSubOrders()} | 4832 | + subOrders={ |
4833 | + isMainOrder | ||
4834 | + ? [...subOrderSelectedMap.values()].flat() | ||
4835 | + : buildSubOrders() | ||
4836 | + } | ||
4725 | onClose={() => { | 4837 | onClose={() => { |
4726 | setReissueVisible(false); | 4838 | setReissueVisible(false); |
4727 | clearOptObject(); | 4839 | clearOptObject(); |
@@ -4780,24 +4892,28 @@ const OrderPage = () => { | @@ -4780,24 +4892,28 @@ const OrderPage = () => { | ||
4780 | }} | 4892 | }} |
4781 | /> | 4893 | /> |
4782 | )} | 4894 | )} |
4783 | - | ||
4784 | - {InvoicingDrawerFormVisible && ( | 4895 | + {invoicingDrawerFormVisible && ( |
4785 | <InvoicingDrawerForm | 4896 | <InvoicingDrawerForm |
4786 | - subOrders={ | 4897 | + dataList={ |
4787 | isMainOrder | 4898 | isMainOrder |
4788 | ? [...subOrderSelectedMap.values()].flat() | 4899 | ? [...subOrderSelectedMap.values()].flat() |
4789 | : buildSubOrders() | 4900 | : buildSubOrders() |
4790 | } | 4901 | } |
4791 | - totalPayment={getApplyInvoicingTotalPayment()} | 4902 | + setVisible={(val: boolean) => { |
4903 | + setInvoicingDrawerFormVisible(val); | ||
4904 | + if (!val) { | ||
4905 | + clearOptObject(); | ||
4906 | + } | ||
4907 | + }} | ||
4908 | + mainOrder={isMainOrder ? getFirstMainOrder() : buildMainOrder()} | ||
4792 | onClose={() => { | 4909 | onClose={() => { |
4793 | - setApplyForInvoicingVisible(false); | ||
4794 | - setIsMainOrder(false); | 4910 | + setInvoicingDrawerFormVisible(false); |
4911 | + setIsMainOrder(true); | ||
4795 | clearOptObject(); | 4912 | clearOptObject(); |
4796 | refreshTable(); | 4913 | refreshTable(); |
4797 | }} | 4914 | }} |
4798 | - ></InvoicingDrawerForm> | 4915 | + /> |
4799 | )} | 4916 | )} |
4800 | - | ||
4801 | {contextHolder} | 4917 | {contextHolder} |
4802 | <FloatButton.BackTop visibilityHeight={0} /> | 4918 | <FloatButton.BackTop visibilityHeight={0} /> |
4803 | </div> | 4919 | </div> |
src/services/exportRequest.ts
0 → 100644
1 | +import axios from 'axios'; | ||
2 | + | ||
3 | +export const excelExport = async ( | ||
4 | + url: any = '', | ||
5 | + data: any = {}, | ||
6 | + exportLoadingDestory: any, | ||
7 | +) => { | ||
8 | + axios({ | ||
9 | + url: url, | ||
10 | + method: 'post', | ||
11 | + responseType: 'blob', | ||
12 | + headers: { Authorization: localStorage.getItem('token') }, | ||
13 | + data, | ||
14 | + }) | ||
15 | + .then((response) => { | ||
16 | + // 我这里在拦截器里直接返回的response.data | ||
17 | + const body = response.data; | ||
18 | + let fileUrl = window.URL.createObjectURL( | ||
19 | + new Blob([body], { | ||
20 | + type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', | ||
21 | + }), | ||
22 | + ); | ||
23 | + let a = document.createElement('a'); | ||
24 | + a.style.display = 'none'; | ||
25 | + a.href = fileUrl; | ||
26 | + a.download = '开票记录.xlsx'; | ||
27 | + document.body.appendChild(a); | ||
28 | + a.click(); | ||
29 | + window.URL.revokeObjectURL(a.href); | ||
30 | + document.body.removeChild(a); | ||
31 | + }) | ||
32 | + .catch((error) => { | ||
33 | + // 处理错误 | ||
34 | + console.error('导出错误', error); | ||
35 | + }) | ||
36 | + .finally(() => { | ||
37 | + exportLoadingDestory(); | ||
38 | + }); | ||
39 | +}; |
src/utils/index.ts
@@ -10,6 +10,7 @@ function enumToSelect(data: any) { | @@ -10,6 +10,7 @@ function enumToSelect(data: any) { | ||
10 | 10 | ||
11 | //将枚举的value值转换为label | 11 | //将枚举的value值转换为label |
12 | function enumValueToLabel(value: any, enumObj: any) { | 12 | function enumValueToLabel(value: any, enumObj: any) { |
13 | + console.log(value, enumObj); | ||
13 | if (enumObj !== undefined) { | 14 | if (enumObj !== undefined) { |
14 | return enumObj[value]; | 15 | return enumObj[value]; |
15 | } | 16 | } |