完成上传发票对话框

main
wuyize 2022-12-31 17:07:27 +08:00
parent bfccd7dfc1
commit bb62d65e8e
3 changed files with 234 additions and 207 deletions

View File

@ -18,20 +18,48 @@ export interface Department {
} }
export interface Invoice { export interface Invoice {
invoiceFileUri: string; invoiceAmount: number;
invoiceThumbnailUri: string;
invoiceNo: string;
invoiceCode: string; invoiceCode: string;
invoiceDate: string; invoiceDate: string;
invoiceUploader: string; invoiceDeparture?: string;
invoiceUploadTime: string; invoiceDestination?: string;
invoiceState: number; invoiceFileUri: string;
invoiceApprovalOpinion: string; invoiceId: number;
invoiceKind: number;
invoiceName?: string;
invoiceNo: string;
invoiceNote: string; invoiceNote: string;
invoiceKind: string; /**
invoiceAmountWithoutTax: number; * -1: 0: 1: 2:
reimbursementId: number; */
invoiceState: number;
invoiceThumbnailUri: string;
invoiceUploader: Staff;
invoiceUploadTime: string;
modified: boolean; modified: boolean;
reimbursement: Reimbursement;
}
export interface InvoiceIdentifyResponse {
invoiceAmount: number;
invoiceCheckCode?: string;
invoiceCode: string;
invoiceDate: string;
invoiceDeparture?: string;
invoiceDestination?: string;
invoiceExtraInfo: InvoiceExtraInfo[];
invoiceFileName: string;
invoiceKind: number;
invoiceName?: string;
invoiceNo: string;
invoiceNote?: string;
invoiceRegionCode?: string;
invoiceSellerTaxCode?: string;
}
export interface InvoiceExtraInfo {
name: string;
value: string;
} }
type Nullable<T> = T | undefined | null; type Nullable<T> = T | undefined | null;

View File

@ -27,6 +27,7 @@ import {Simulate} from "react-dom/test-utils";
import change = Simulate.change; import change = Simulate.change;
import {useNavigate} from "react-router-dom"; import {useNavigate} from "react-router-dom";
import {useAppDispatch} from "../../../models/hooks"; import {useAppDispatch} from "../../../models/hooks";
import InvoiceUploadView from "./InvoiceUploadView";
const {Meta} = Card; const {Meta} = Card;
const {Search} = Input; const {Search} = Input;
@ -58,6 +59,7 @@ class InvoiceSearch extends React.Component<any, any> {
searchContent: '请在此输入', searchContent: '请在此输入',
complexEnabled: false, complexEnabled: false,
invoiceSearchOption: new InvoiceSearchOption(), invoiceSearchOption: new InvoiceSearchOption(),
isUploadModalOpen: false
} }
} }
@ -72,22 +74,14 @@ class InvoiceSearch extends React.Component<any, any> {
this.state.invoiceSearchOption.invoiceNo = value; this.state.invoiceSearchOption.invoiceNo = value;
this.state.invoiceSearchOption.invoiceCode = null; this.state.invoiceSearchOption.invoiceCode = null;
} }
//const dispatch = useAppDispatch();
//const navigate = useNavigate();
const {handleSearchData} = this.props const {handleSearchData} = this.props
handleSearchData(this.state.invoiceSearchOption) handleSearchData(this.state.invoiceSearchOption)
// axiosInstance({
// url: 'common/invoice/list',
// method: 'get',
// params: params
// }).then(response => {
// console.log(response.data)
// handleSearchData(response.data.records)
// }).catch(function (error) {
// console.log(error)
// })
}
}
showUploadModal = () => {
this.setState({ isUploadModalOpen: true})
}
render() { render() {
const items: MenuProps['items'] = [ const items: MenuProps['items'] = [
@ -162,9 +156,7 @@ class InvoiceSearch extends React.Component<any, any> {
this.setState({complexEnabled: e.target.checked}) this.setState({complexEnabled: e.target.checked})
}}></Checkbox> }}></Checkbox>
<Button className="uploadButton" type="primary" icon={<UploadOutlined/>} size="large"> <InvoiceUploadView/>
</Button>
</div> </div>
{this.state.complexEnabled&& {this.state.complexEnabled&&
<div className="complexSearchBar" style={{display: "flex"}}> <div className="complexSearchBar" style={{display: "flex"}}>
@ -224,7 +216,7 @@ class InvoiceItem extends React.Component<any, any> {
this.state = { this.state = {
invoiceThumbnailUri: baseUrl+props.invoice.invoiceThumbnailUri, invoiceThumbnailUri: baseUrl+props.invoice.invoiceThumbnailUri,
invoiceKind: props.invoice.invoiceKind, invoiceKind: props.invoice.invoiceKind,
invoiceAmountWithoutTax: props.invoice.invoiceAmountWithoutTax, invoiceAmount: props.invoice.invoiceAmount,
invoiceDate: props.invoice.invoiceDate, invoiceDate: props.invoice.invoiceDate,
invoiceNo: props.invoice.invoiceNo, invoiceNo: props.invoice.invoiceNo,
} }
@ -238,7 +230,6 @@ class InvoiceItem extends React.Component<any, any> {
style={{ style={{
width: 250, width: 250,
height: 300, height: 300,
background: "dimgrey",
margin: 30 margin: 30
}} }}
cover={<img alt="thumbnail" cover={<img alt="thumbnail"
@ -246,9 +237,9 @@ class InvoiceItem extends React.Component<any, any> {
width="220" height="180"/>} width="220" height="180"/>}
> >
<div style={{marginTop: -20}}> <div style={{marginTop: -20}}>
<li style={{fontWeight: "bold", fontSize: 20}}>{this.state.invoiceNo}</li> <li style={{fontWeight: "bold", fontSize: 20}}>¥{(this.state.invoiceAmount / 100.0).toFixed(2)}</li>
<li>{this.state.invoiceKind}</li> <li>{this.state.invoiceKind}</li>
<li>¥{(this.state.invoiceAmountWithoutTax / 100.0).toFixed(2)}</li> <li>{this.state.invoiceNo}</li>
<li>{this.state.invoiceDate}</li> <li>{this.state.invoiceDate}</li>
</div> </div>
</Card> </Card>
@ -297,7 +288,7 @@ class InvoiceListView extends React.Component<any, any> {
params['pageNum'] = this.state.pageNum-1 params['pageNum'] = this.state.pageNum-1
params['pageSize'] = this.state.pageSize params['pageSize'] = this.state.pageSize
axiosInstance({ axiosInstance({
url: 'common/invoice/list', url: 'common/invoice',
method: 'get', method: 'get',
params: params params: params
}).then(response => { }).then(response => {
@ -323,9 +314,9 @@ class InvoiceListView extends React.Component<any, any> {
return ( return (
<div style={{}}> <div style={{}}>
<InvoiceSearch handleSearchData={this.handleInvoiceSearchInfo}/> <InvoiceSearch handleSearchData={this.handleInvoiceSearchInfo}/>
<div style={{display: "flex", flexWrap: "wrap", backgroundColor: "lightgrey"}}> <div style={{display: "flex", flexWrap: "wrap"}}>
{this.state.invoices.map((item: Invoice) => {this.state.invoices.map((item: Invoice, index:number) =>
<InvoiceItem invoice={item}/> <InvoiceItem invoice={item} key={index}/>
)} )}
</div> </div>

View File

@ -1,23 +1,24 @@
import React, {useState} from 'react'; import React, {useEffect, useRef, useState} from 'react';
import {Button, Modal, UploadProps, message, Upload, UploadFile, Form, Input, DatePicker} from 'antd'; import {Button, Modal, UploadProps, message, Upload, UploadFile, Form, Input, DatePicker} from 'antd';
import { InboxOutlined } from '@ant-design/icons'; import {InboxOutlined, UploadOutlined} from '@ant-design/icons';
import axiosInstance from "../../../utils/axiosInstance"; import axiosInstance from "../../../utils/axiosInstance";
import {InvoiceCommit} from "../../../models/Staff"; import {InvoiceCommit, InvoiceIdentifyResponse} from "../../../models/Staff";
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import TextArea from "antd/es/input/TextArea"; import TextArea from "antd/es/input/TextArea";
import {constants} from "http2"; import {constants} from "http2";
import type { FormInstance } from 'antd/es/form'; import type {FormInstance} from 'antd/es/form';
import {useAppDispatch} from "../../../models/hooks"; import {useAppDispatch} from "../../../models/hooks";
const { Dragger } = Upload;
let tempFile :File const {Dragger} = Upload;
let tempFile: File
const props: UploadProps = { const props: UploadProps = {
name: 'file', name: 'file',
multiple: false, multiple: false,
maxCount: 1, maxCount: 1,
accept: "image/png, image/jpeg, image/jpg", accept: "image/png, image/jpeg, image/jpg",
beforeUpload: (file,fileList)=>{ beforeUpload: (file, fileList) => {
tempFile=file tempFile = file
console.log(file) console.log(file)
return false return false
}, },
@ -37,7 +38,7 @@ const props: UploadProps = {
}, },
}; };
class FileUploadView extends React.Component<any, any>{ class FileUploadView extends React.Component<any, any> {
render() { render() {
return (<Dragger {...props}> return (<Dragger {...props}>
<p className="ant-upload-drag-icon"> <p className="ant-upload-drag-icon">
@ -53,95 +54,68 @@ class FileUploadView extends React.Component<any, any>{
} }
class InvoiceUploadView extends React.Component<any, any>{ function UpLoadModal(props: any) {
formRef = React.createRef<FormInstance>(); const [open, setOpen] = useState(false)
constructor(props: {}) { const [loading, setLoading] = useState(false)
super(props); useEffect(() => {
this.state = { setOpen(props.open)
loading: false, }, [props]);
open: false, const handleOk = () => {
uploadOpen: false, setLoading(true);
uploadStep: 0, let data = new FormData();
invoiceCommit: new InvoiceCommit(), data.append('invoiceFile', tempFile)
}
this.state.invoiceCommit.invoiceNo="init"
}
setUploadOpen(value: Boolean) {
this.setState({uploadOpen: value})
}
setOpen(value: Boolean) {
this.setState({open : value})
}
setLoading(value: Boolean) {
this.setState({loading : value})
}
setUploadStep(value: number) {
this.setState({uploadStep : value})
}
showUploadView = () => {
this.setOpen(true);
};
handleOk = () => {
this.setLoading(true);
//this.setLoading(false);
this.setOpen(false);
let data= new FormData();
data.append('invoiceFile',tempFile)
axiosInstance({ axiosInstance({
url: 'common/invoice/identify', url: 'common/invoice/identify',
method: 'POST', method: 'POST',
data: data data: data
}).then(response => { }).then(response => {
setLoading(false);
console.log(response.data) console.log(response.data)
let result = new InvoiceCommit() setOpen(false);
result.invoiceNo = response.data.invoiceNo props.nextStep(response.data)
result.invoiceDate = dayjs(response.data.invoiceDate)
result.invoiceAmountWithoutTax = response.data.invoiceAmountWithoutTax
result.invoiceAmount = response.data.invoiceAmount
result.invoiceCode = response.data.invoiceCode
result.invoiceCheckCode = response.data.invoiceCheckCode
result.invoiceKind = response.data.invoiceKind
result.invoiceFileName = response.data.invoiceFileName
result.invoiceExtraInfo = ""
Object.keys(response.data.invoiceExtraInfo).forEach( key => {
result.invoiceExtraInfo+=(key+": "+response.data.invoiceExtraInfo[key]+"\n")
});
// for(let i=0;i<response.data.invoiceExtraInfo.length;i++){
// result.invoiceExtraInfo+=(response.data.invoiceExtraInfo[i].name+": "+response.data.invoiceExtraInfo[i].value+"\n")
// }
this.setState({invoiceCommit:result})
this.formRef.current!.setFieldsValue(result);
}).catch(function (error) { }).catch(function (error) {
setLoading(false);
console.log(error) console.log(error)
}) })
this.setState({uploadStep:1})
this.setUploadOpen(true)
this.setLoading(false);
// let fakeData=new InvoiceCommit()
// fakeData.invoiceNo="No"
// fakeData.invoiceCode="Code"
// fakeData.invoiceDate=new Date()
// setInvoiceCommit(fakeData)
}; };
const handleCancel = () => {
handleCancel = () => { setOpen(false);
this.setOpen(false);
}; };
handleUploadCanCel = () => { return (
this.setUploadOpen(false); <Modal
} open={open}
submit=()=>{ title="Title"
let result=this.formRef.current!.getFieldsValue() onOk={handleOk}
result.invoiceDate=result.invoiceDate.format("YYYY-MM-DD") onCancel={handleCancel}
result.invoiceExtraInfo=new Map(result.invoiceExtraInfo.split("\n").map((entry: string) => entry.split(": "))) footer={[
<Button key="cancel" onClick={handleCancel}>
</Button>,
<Button key="next" type="primary" loading={loading} onClick={handleOk}>
</Button>
]}
>
<FileUploadView/>
</Modal>
)
}
function FormModal(props: any) {
const [open, setOpen] = useState(false)
const [form] = Form.useForm();
useEffect(() => {
setOpen(props.open)
}, [props]);
const handleCancel = () => {
setOpen(false);
};
const submit = () => {
let result = form!.getFieldsValue()
result.invoiceDate = result.invoiceDate.format("YYYY-MM-DD")
result.invoiceExtraInfo = new Map(result.invoiceExtraInfo.split("\n").map((entry: string) => entry.split(": ")))
console.log(result.invoiceExtraInfo.split("\n").map((entry: string) => entry.split(": "))) console.log(result.invoiceExtraInfo.split("\n").map((entry: string) => entry.split(": ")))
// let extraInfo=[] // let extraInfo=[]
// let line = result.invoiceExtraInfo.split('\n') // let line = result.invoiceExtraInfo.split('\n')
@ -165,102 +139,136 @@ class InvoiceUploadView extends React.Component<any, any>{
}) })
} }
return (
<Modal
open={open}
title="Title"
onOk={submit}
onCancel={handleCancel}
footer={[
<Button key="cancel" onClick={handleCancel}>
</Button>,
<Button key="next" type="primary" loading={false} onClick={submit}
>
</Button>
]}
>
<Form form={form}>
<Form.Item
name={`invoiceNo`}
label={`发票编码`}
>
<Input/>
</Form.Item>
<Form.Item
name={`invoiceCode`}
label={`发票代码`}
>
<Input/>
</Form.Item>
<Form.Item
name={`invoiceKind`}
label={`发票类型`}
>
<Input/>
</Form.Item>
<Form.Item
name={`invoiceAmount`}
label={`计税总额`}
>
<Input/>
</Form.Item>
<Form.Item
name={`invoiceAmountWithoutTax`}
label={`非税金额`}
>
<Input/>
</Form.Item>
<Form.Item
name={`invoiceDate`}
label={`开票日期`}
>
<DatePicker/>
</Form.Item>
<Form.Item
name={`invoiceCheckCode`}
label={`核验码`}
>
<Input/>
</Form.Item>
<Form.Item
name={`invoiceExtraInfo`}
label={`其他信息`}
>
<TextArea/>
</Form.Item>
</Form>
</Modal>
)
}
class InvoiceUploadView extends React.Component<any, any> {
formRef = React.createRef<FormInstance>();
constructor(props: {}) {
super(props);
this.state = {
loading: false,
open: false,
uploadOpen: false,
uploadStep: 0,
invoiceCommit: new InvoiceCommit(),
}
this.state.invoiceCommit.invoiceNo = "init"
}
setUploadOpen(value: Boolean) {
this.setState({uploadOpen: value})
}
setOpen(value: Boolean) {
this.setState({open: value})
}
setLoading(value: Boolean) {
this.setState({loading: value})
}
setUploadStep(value: number) {
this.setState({uploadStep: value})
}
showUploadView = () => {
this.setOpen(true);
};
handleUploadCanCel = () => {
this.setUploadOpen(false);
}
handleNextStep = (response: InvoiceIdentifyResponse) => {
this.setState({open: false, uploadOpen: true})
}
render() { render() {
console.log(this.state.invoiceCommit) console.log(this.state.invoiceCommit)
console.log(this.state.uploadStep) console.log(this.state.uploadStep)
// @ts-ignore
// @ts-ignore // @ts-ignore
return ( return (
<> <>
<Button type="primary" onClick={this.showUploadView}> <Button onClick={this.showUploadView} className="uploadButton" type="primary" icon={<UploadOutlined/>}
Open Modal with customized footer size="large">
</Button> </Button>
<Modal <UpLoadModal open={this.state.open} nextStep={this.handleNextStep}/>
open={this.state.open} <FormModal open={this.state.uploadOpen}/>
title="Title"
onOk={this.handleOk}
onCancel={this.handleCancel}
footer={[
<Button key="cancel" onClick={this.handleCancel}>
</Button>,
<Button key="next" type="primary" loading={this.state.loading} onClick={this.handleOk}>
</Button>
]}
>
<FileUploadView/>
</Modal>
<Modal
open={this.state.uploadOpen}
title="Title"
onOk={this.submit}
onCancel={this.handleCancel}
footer={[
<Button key="cancel" onClick={this.handleCancel}>
</Button>,
<Button key="next" type="primary" loading={false} onClick={this.submit}
>
</Button>
]}
>
<Form ref={this.formRef} initialValues={{invoiceNo:this.state.invoiceCommit.invoiceNo}}>
<Form.Item
name={`invoiceNo`}
label={`发票编码`}
>
<Input />
</Form.Item>
<Form.Item
name={`invoiceCode`}
label={`发票代码`}
>
<Input />
</Form.Item>
<Form.Item
name={`invoiceKind`}
label={`发票类型`}
>
<Input />
</Form.Item>
<Form.Item
name={`invoiceAmount`}
label={`计税总额`}
>
<Input />
</Form.Item>
<Form.Item
name={`invoiceAmountWithoutTax`}
label={`非税金额`}
>
<Input/>
</Form.Item>
<Form.Item
name={`invoiceDate`}
label={`开票日期`}
>
<DatePicker/>
</Form.Item>
<Form.Item
name={`invoiceCheckCode`}
label={`核验码`}
>
<Input/>
</Form.Item>
<Form.Item
name={`invoiceExtraInfo`}
label={`其他信息`}
>
<TextArea/>
</Form.Item>
</Form>
</Modal>
</>); </>);
} }