Commit 7937df0645768844bc86221d091cade0d6106756
1 parent
1b5105f2
feat: 手动开票功能开发
Showing
3 changed files
with
139 additions
and
0 deletions
src/pages/Invoice/components/ManualInvoicingModal.tsx
0 → 100644
1 | +import UploadC from '@/pages/Invoice/components/UploadSingleImg'; | |
2 | +import { postOrderErpOrderStagesUpload } from '@/services'; | |
3 | +import { | |
4 | + ModalForm, | |
5 | + ProFormDatePicker, | |
6 | + ProFormText, | |
7 | +} from '@ant-design/pro-components'; | |
8 | +import { Col, Form, Row, message } from 'antd'; | |
9 | +import { RcFile } from 'antd/es/upload'; | |
10 | + | |
11 | +export default () => { | |
12 | + const [form] = Form.useForm<{ name: string; company: string }>(); | |
13 | + return ( | |
14 | + <ModalForm<{ | |
15 | + name: string; | |
16 | + company: string; | |
17 | + }> | |
18 | + title="手动开票" | |
19 | + trigger={<a type="primary">手动开票</a>} | |
20 | + width={400} | |
21 | + layout={'horizontal'} | |
22 | + form={form} | |
23 | + autoFocusFirstInput | |
24 | + modalProps={{ | |
25 | + destroyOnClose: true, | |
26 | + onCancel: () => console.log('run'), | |
27 | + }} | |
28 | + submitTimeout={2000} | |
29 | + onFinish={async (values) => { | |
30 | + console.log(values); | |
31 | + message.success('提交成功'); | |
32 | + return true; | |
33 | + }} | |
34 | + > | |
35 | + <ProFormText width={'md'} name="invoicingPerson" label="开票人" /> | |
36 | + <ProFormText width={'md'} name="invoiceNumber" label="发票号码" /> | |
37 | + <ProFormDatePicker | |
38 | + fieldProps={{ | |
39 | + format: 'YY-MM-DD', | |
40 | + }} | |
41 | + name="invoicingDate" | |
42 | + label="开票日期" | |
43 | + /> | |
44 | + <ProFormText hidden name="url" label="發票地址" /> | |
45 | + <Row> | |
46 | + <Col span={4}>上传发票</Col> | |
47 | + <Col span={20}> | |
48 | + <UploadC | |
49 | + onFilesChange={async (newFileList) => { | |
50 | + if (newFileList.length > 0) { | |
51 | + const formData = new FormData(); | |
52 | + formData.append('file', newFileList[0].originFileObj as RcFile); | |
53 | + const res = await postOrderErpOrderStagesUpload({ | |
54 | + data: formData, | |
55 | + headers: { | |
56 | + 'Content-Type': | |
57 | + 'multipart/form-data; boundary=----WebKitFormBoundarynl6gT1BKdPWIejNq', | |
58 | + }, | |
59 | + }); | |
60 | + const url = res.data; | |
61 | + form.setFieldValue('url', url); | |
62 | + } else { | |
63 | + form.setFieldValue('url', null); | |
64 | + } | |
65 | + }} | |
66 | + ></UploadC> | |
67 | + </Col> | |
68 | + </Row> | |
69 | + </ModalForm> | |
70 | + ); | |
71 | +}; | ... | ... |
src/pages/Invoice/components/UploadSingleImg.tsx
0 → 100644
1 | +import { PlusOutlined } from '@ant-design/icons'; | |
2 | +import type { GetProp, UploadFile, UploadProps } from 'antd'; | |
3 | +import { Image, Upload } from 'antd'; | |
4 | +import { useState } from 'react'; | |
5 | + | |
6 | +type FileType = Parameters<GetProp<UploadProps, 'beforeUpload'>>[0]; | |
7 | + | |
8 | +const getBase64 = (file: FileType): Promise<string> => | |
9 | + new Promise((resolve, reject) => { | |
10 | + const reader = new FileReader(); | |
11 | + reader.readAsDataURL(file); | |
12 | + reader.onload = () => resolve(reader.result as string); | |
13 | + reader.onerror = (error) => reject(error); | |
14 | + }); | |
15 | + | |
16 | +export default ({ onFilesChange }) => { | |
17 | + const [previewOpen, setPreviewOpen] = useState(false); | |
18 | + const [previewImage, setPreviewImage] = useState(''); | |
19 | + const [fileList, setFileList] = useState<UploadFile[]>([]); | |
20 | + | |
21 | + const handlePreview = async (file: UploadFile) => { | |
22 | + if (!file.url && !file.preview) { | |
23 | + file.preview = await getBase64(file.originFileObj as FileType); | |
24 | + } | |
25 | + | |
26 | + setPreviewImage(file.url || (file.preview as string)); | |
27 | + setPreviewOpen(true); | |
28 | + }; | |
29 | + | |
30 | + const uploadButton = ( | |
31 | + <button style={{ border: 0, background: 'none' }} type="button"> | |
32 | + <PlusOutlined /> | |
33 | + <div style={{ marginTop: 8 }}>Upload</div> | |
34 | + </button> | |
35 | + ); | |
36 | + return ( | |
37 | + <> | |
38 | + <Upload | |
39 | + listType="picture-card" | |
40 | + fileList={fileList} | |
41 | + onPreview={handlePreview} | |
42 | + onChange={({ fileList: newFileList }) => { | |
43 | + setFileList(newFileList); | |
44 | + console.log('file' + JSON.stringify(newFileList)); | |
45 | + onFilesChange(newFileList); | |
46 | + }} | |
47 | + > | |
48 | + {fileList.length >= 1 ? null : uploadButton} | |
49 | + </Upload> | |
50 | + {previewImage && ( | |
51 | + <Image | |
52 | + wrapperStyle={{ display: 'none' }} | |
53 | + preview={{ | |
54 | + visible: previewOpen, | |
55 | + onVisibleChange: (visible) => setPreviewOpen(visible), | |
56 | + afterOpenChange: (visible) => !visible && setPreviewImage(''), | |
57 | + }} | |
58 | + src={previewImage} | |
59 | + /> | |
60 | + )} | |
61 | + </> | |
62 | + ); | |
63 | +}; | ... | ... |
src/pages/Invoice/index.tsx
... | ... | @@ -5,6 +5,7 @@ import AddInvoiceDrawerForm from '@/pages/Invoice/components/AddInvoiceDrawerFor |
5 | 5 | import InvoiceModal from '@/pages/Invoice/components/InvoiceModal'; |
6 | 6 | import InvoiceRecordDetailModal from '@/pages/Invoice/components/InvoiceRecordDetailModal'; |
7 | 7 | import InvoicingModal from '@/pages/Invoice/components/InvoicingModal'; |
8 | +import ManualInvoicingModal from '@/pages/Invoice/components/ManualInvoicingModal'; | |
8 | 9 | import { |
9 | 10 | BANK_STATEMENT_COLUMNS, |
10 | 11 | INVOICE_COLUMNS, |
... | ... | @@ -334,6 +335,10 @@ const InvoicePage = () => { |
334 | 335 | 详情 |
335 | 336 | </a>, |
336 | 337 | <InvoiceModal key="invoiceModal" recordId={record.id} />, |
338 | + <ManualInvoicingModal | |
339 | + key={'ManualInvoicingModal'} | |
340 | + record={record} | |
341 | + ></ManualInvoicingModal>, | |
337 | 342 | ]; |
338 | 343 | }, |
339 | 344 | }, | ... | ... |