初步完成发票提交
parent
68431ef6e6
commit
81cafa8010
|
@ -9,6 +9,7 @@ import {RouterProvider} from "react-router-dom";
|
||||||
import CustomRouter from "./router/router";
|
import CustomRouter from "./router/router";
|
||||||
import {PersistGate} from 'redux-persist/integration/react'
|
import {PersistGate} from 'redux-persist/integration/react'
|
||||||
import {ConfigProvider} from "antd";
|
import {ConfigProvider} from "antd";
|
||||||
|
import zhCN from 'antd/locale/zh_CN';
|
||||||
|
|
||||||
const root = ReactDOM.createRoot(
|
const root = ReactDOM.createRoot(
|
||||||
document.getElementById('root') as HTMLElement
|
document.getElementById('root') as HTMLElement
|
||||||
|
@ -17,7 +18,7 @@ root.render(
|
||||||
<React.StrictMode>
|
<React.StrictMode>
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
<PersistGate loading={null} persistor={persistor}>
|
<PersistGate loading={null} persistor={persistor}>
|
||||||
<ConfigProvider theme={{
|
<ConfigProvider locale={zhCN} theme={{
|
||||||
token: {
|
token: {
|
||||||
colorPrimary: "#1890ff",
|
colorPrimary: "#1890ff",
|
||||||
colorSuccess: "#52c41a",
|
colorSuccess: "#52c41a",
|
||||||
|
|
|
@ -0,0 +1,106 @@
|
||||||
|
import {Staff} from "./Staff";
|
||||||
|
import {Reimbursement} from "./Reimbursement";
|
||||||
|
import {Dayjs} from "dayjs"
|
||||||
|
export interface Invoice {
|
||||||
|
invoiceAmount: number;
|
||||||
|
invoiceCode: string;
|
||||||
|
invoiceDate: string;
|
||||||
|
invoiceDeparture?: string;
|
||||||
|
invoiceDestination?: string;
|
||||||
|
invoiceFileUri: string;
|
||||||
|
invoiceId: number;
|
||||||
|
invoiceKind: number;
|
||||||
|
invoiceName?: string;
|
||||||
|
invoiceNo: string;
|
||||||
|
invoiceNote: string;
|
||||||
|
/**
|
||||||
|
* -1: 不合格 0: 已上传 1: 报销中 2: 已报销
|
||||||
|
*/
|
||||||
|
invoiceState: number;
|
||||||
|
invoiceThumbnailUri: string;
|
||||||
|
invoiceUploader: Staff;
|
||||||
|
invoiceUploadTime: string;
|
||||||
|
modified: boolean;
|
||||||
|
reimbursement: Reimbursement;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface InvoiceIdentifyResponse {
|
||||||
|
invoiceAmount: number;
|
||||||
|
invoiceCheckCode?: string;
|
||||||
|
invoiceCode: string;
|
||||||
|
invoiceDate: string|Dayjs;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const invoiceTypeNameMap = new Map ([
|
||||||
|
[0, '出租车发票'],
|
||||||
|
[1, '定额发票'],
|
||||||
|
[2, '火车票'],
|
||||||
|
[3, '增值税发票'],
|
||||||
|
[5, '机票行程单'],
|
||||||
|
[8, '通用机打发票'],
|
||||||
|
[9, '汽车票'],
|
||||||
|
[10, '轮船票'],
|
||||||
|
[11, '增值税发票(卷票)'],
|
||||||
|
[12, '购车发票'],
|
||||||
|
[13, '过路过桥费发票'],
|
||||||
|
[15, '非税发票'],
|
||||||
|
[16, '全电发票']
|
||||||
|
])
|
||||||
|
|
||||||
|
export const invoiceItemsMap = new Map([
|
||||||
|
['invoiceNo', '发票编号'],
|
||||||
|
['invoiceCode', '发票代码'],
|
||||||
|
['invoiceAmount', '金额'],
|
||||||
|
['invoiceDate', '开票日期'],
|
||||||
|
['invoiceKind', '发票种类'],
|
||||||
|
['invoiceCheckCode', '校验码'],
|
||||||
|
['invoiceRegionCode', '区域码'],
|
||||||
|
['invoiceSellerTaxCode', '卖方税号'],
|
||||||
|
['invoiceNote', '备注'],
|
||||||
|
['invoiceDeparture', '出发地'],
|
||||||
|
['invoiceDestination', '目的地'],
|
||||||
|
['invoiceName', '发票名称'],
|
||||||
|
])
|
||||||
|
|
||||||
|
export const invoiceTypeItemsMap = new Map ([
|
||||||
|
|
||||||
|
[13, ['invoiceName', 'invoiceNo', 'invoiceCode', 'invoiceAmount', 'invoiceDate', 'invoiceDeparture', 'invoiceDestination']],
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
{
|
||||||
|
"invoiceFileName": "e86d8d76c0507dcfb5364172a4832494.jpg",
|
||||||
|
"invoiceNo": "35971607",
|
||||||
|
"invoiceCode": "121011972201",
|
||||||
|
"invoiceAmount": 1000,
|
||||||
|
"invoiceDate": "2019-07-11",
|
||||||
|
"invoiceKind": 13,
|
||||||
|
"invoiceCheckCode": "",
|
||||||
|
"invoiceRegionCode": "",
|
||||||
|
"invoiceSellerTaxCode": "",
|
||||||
|
"invoiceExtraInfo": {
|
||||||
|
"时间": "13:01",
|
||||||
|
"发票消费类型": "交通",
|
||||||
|
"高速标志": "1"
|
||||||
|
},
|
||||||
|
"invoiceNote": null,
|
||||||
|
"invoiceDeparture": "苏家屯",
|
||||||
|
"invoiceDestination": "灯塔",
|
||||||
|
"invoiceName": "辽宁省高速公路通行费专用发票"
|
||||||
|
}*/
|
|
@ -18,52 +18,10 @@ export interface Department {
|
||||||
departmentName: string;
|
departmentName: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Invoice {
|
|
||||||
invoiceAmount: number;
|
|
||||||
invoiceCode: string;
|
|
||||||
invoiceDate: string;
|
|
||||||
invoiceDeparture?: string;
|
|
||||||
invoiceDestination?: string;
|
|
||||||
invoiceFileUri: string;
|
|
||||||
invoiceId: number;
|
|
||||||
invoiceKind: number;
|
|
||||||
invoiceName?: string;
|
|
||||||
invoiceNo: string;
|
|
||||||
invoiceNote: string;
|
|
||||||
/**
|
|
||||||
* -1: 不合格 0: 已上传 1: 报销中 2: 已报销
|
|
||||||
*/
|
|
||||||
invoiceState: number;
|
|
||||||
invoiceThumbnailUri: string;
|
|
||||||
invoiceUploader: Staff;
|
|
||||||
invoiceUploadTime: string;
|
|
||||||
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;
|
||||||
|
|
||||||
export class InvoiceSearchOption {
|
export class InvoiceSearchOption {
|
||||||
invoiceNo: Nullable<string>
|
invoiceNo: Nullable<string>
|
||||||
invoiceCode: Nullable<string>
|
invoiceCode: Nullable<string>
|
||||||
|
@ -77,11 +35,13 @@ export class InvoiceSearchOption{
|
||||||
invoiceUploader: Nullable<string>
|
invoiceUploader: Nullable<string>
|
||||||
pageNum: number
|
pageNum: number
|
||||||
pageSize: number
|
pageSize: number
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.pageNum = 0
|
this.pageNum = 0
|
||||||
this.pageSize = 20
|
this.pageSize = 20
|
||||||
this.clear()
|
this.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
clear() {
|
clear() {
|
||||||
this.invoiceNo = null
|
this.invoiceNo = null
|
||||||
this.invoiceCode = null
|
this.invoiceCode = null
|
||||||
|
@ -125,6 +85,7 @@ export class InvoiceCommit {
|
||||||
invoiceRegionCode: Nullable<string>
|
invoiceRegionCode: Nullable<string>
|
||||||
invoiceSellerTaxCode: Nullable<string>
|
invoiceSellerTaxCode: Nullable<string>
|
||||||
invoiceExtraInfo: Nullable<string> | [] | Map<any, string>
|
invoiceExtraInfo: Nullable<string> | [] | Map<any, string>
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.invoiceFileName = ""
|
this.invoiceFileName = ""
|
||||||
this.invoiceNo = ""
|
this.invoiceNo = ""
|
||||||
|
@ -138,6 +99,7 @@ export class InvoiceCommit {
|
||||||
this.invoiceSellerTaxCode = null
|
this.invoiceSellerTaxCode = null
|
||||||
this.invoiceExtraInfo = null
|
this.invoiceExtraInfo = null
|
||||||
}
|
}
|
||||||
|
|
||||||
setValue(props: FormData) {
|
setValue(props: FormData) {
|
||||||
console.log("1111" + props.toString())
|
console.log("1111" + props.toString())
|
||||||
this.invoiceFileName = props.get("invoiceFileName")!.toString()
|
this.invoiceFileName = props.get("invoiceFileName")!.toString()
|
||||||
|
@ -153,6 +115,7 @@ export class InvoiceCommit {
|
||||||
//this.invoiceExtraInfo = props.get("invoiceExtraInfo")!.
|
//this.invoiceExtraInfo = props.get("invoiceExtraInfo")!.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Reimbursement {
|
export interface Reimbursement {
|
||||||
/**
|
/**
|
||||||
* 差旅补助金额
|
* 差旅补助金额
|
||||||
|
|
|
@ -38,6 +38,7 @@ const staffSlice = createSlice({
|
||||||
state.staffName = action.payload.staffName
|
state.staffName = action.payload.staffName
|
||||||
state.managingDepartment = action.payload.managingDepartment
|
state.managingDepartment = action.payload.managingDepartment
|
||||||
state.staffDepartments = action.payload.staffDepartments
|
state.staffDepartments = action.payload.staffDepartments
|
||||||
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -71,7 +71,7 @@ function HeaderBar(props: any) {
|
||||||
const departmentToString = (staff: Staff) => {
|
const departmentToString = (staff: Staff) => {
|
||||||
let result = staff.managingDepartment === null ? '' : staff.managingDepartment.departmentName + '主管'
|
let result = staff.managingDepartment === null ? '' : staff.managingDepartment.departmentName + '主管'
|
||||||
for (const department of staff.staffDepartments) {
|
for (const department of staff.staffDepartments) {
|
||||||
result += ' ' + department.departmentName
|
result += '\xa0\xa0' + department.departmentName
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
@ -85,7 +85,7 @@ function HeaderBar(props: any) {
|
||||||
flexDirection: 'row-reverse',
|
flexDirection: 'row-reverse',
|
||||||
alignItems: 'center'
|
alignItems: 'center'
|
||||||
}}>
|
}}>
|
||||||
<Dropdown menu={{items, onClick}} placement="bottomRight" arrow>
|
<Dropdown overlayStyle={{minWidth: '150px'}} menu={{items, onClick}} placement="bottomRight" arrow>
|
||||||
<Button type="text" style={{
|
<Button type="text" style={{
|
||||||
marginRight: '12px', height: '100%',
|
marginRight: '12px', height: '100%',
|
||||||
display: 'flex', justifyContent: 'center', alignItems: 'center'
|
display: 'flex', justifyContent: 'center', alignItems: 'center'
|
||||||
|
@ -96,7 +96,7 @@ function HeaderBar(props: any) {
|
||||||
width: '24px', height: '24px', backgroundColor: colorPrimary, borderRadius: '12px',
|
width: '24px', height: '24px', backgroundColor: colorPrimary, borderRadius: '12px',
|
||||||
display: 'flex', justifyContent: 'center', alignItems: 'center'
|
display: 'flex', justifyContent: 'center', alignItems: 'center'
|
||||||
}}>
|
}}>
|
||||||
<span style={{color: 'white'}}>{staff.staffName[0]}</span>
|
<span style={{color: 'white', fontSize: '10px'}}>{staff.staffName[0]}</span>
|
||||||
</div>
|
</div>
|
||||||
</Button>
|
</Button>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
|
|
|
@ -18,7 +18,7 @@ import {
|
||||||
import type {MenuProps, PaginationProps} from 'antd';
|
import type {MenuProps, PaginationProps} from 'antd';
|
||||||
import {DownOutlined, UploadOutlined} from '@ant-design/icons';
|
import {DownOutlined, UploadOutlined} from '@ant-design/icons';
|
||||||
import React, {ReactElement, JSXElementConstructor, ReactFragment, ReactPortal, useState} from "react";
|
import React, {ReactElement, JSXElementConstructor, ReactFragment, ReactPortal, useState} from "react";
|
||||||
import {Invoice, InvoiceCommit, InvoiceSearchOption} from "../../../models/Staff"
|
import {InvoiceCommit, InvoiceSearchOption} from "../../../models/Staff"
|
||||||
import {Space, Typography} from 'antd';
|
import {Space, Typography} from 'antd';
|
||||||
import {SizeType} from "antd/es/config-provider/SizeContext";
|
import {SizeType} from "antd/es/config-provider/SizeContext";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
@ -28,6 +28,7 @@ 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";
|
import InvoiceUploadView from "./InvoiceUploadView";
|
||||||
|
import {Invoice, invoiceTypeNameMap} from "../../../models/Invoice";
|
||||||
|
|
||||||
const {Meta} = Card;
|
const {Meta} = Card;
|
||||||
const {Search} = Input;
|
const {Search} = Input;
|
||||||
|
@ -238,7 +239,7 @@ class InvoiceItem extends React.Component<any, any> {
|
||||||
>
|
>
|
||||||
<div style={{marginTop: -20}}>
|
<div style={{marginTop: -20}}>
|
||||||
<li style={{fontWeight: "bold", fontSize: 20}}>¥{(this.state.invoiceAmount / 100.0).toFixed(2)}</li>
|
<li style={{fontWeight: "bold", fontSize: 20}}>¥{(this.state.invoiceAmount / 100.0).toFixed(2)}</li>
|
||||||
<li>{this.state.invoiceKind}</li>
|
<li>{invoiceTypeNameMap.get(this.state.invoiceKind)}</li>
|
||||||
<li>{this.state.invoiceNo}</li>
|
<li>{this.state.invoiceNo}</li>
|
||||||
<li>{this.state.invoiceDate}</li>
|
<li>{this.state.invoiceDate}</li>
|
||||||
</div>
|
</div>
|
||||||
|
@ -262,6 +263,9 @@ class InvoiceListView extends React.Component<any, any> {
|
||||||
totalNum: 2,
|
totalNum: 2,
|
||||||
PaginationKey: -2
|
PaginationKey: -2
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount(){
|
||||||
this.searchInvoiceContent()
|
this.searchInvoiceContent()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,19 @@
|
||||||
import React, {useEffect, useRef, 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, Select, InputNumber} from 'antd';
|
||||||
import {InboxOutlined, UploadOutlined} from '@ant-design/icons';
|
import {InboxOutlined, UploadOutlined} from '@ant-design/icons';
|
||||||
import axiosInstance from "../../../utils/axiosInstance";
|
import axiosInstance from "../../../utils/axiosInstance";
|
||||||
import {InvoiceCommit, InvoiceIdentifyResponse} from "../../../models/Staff";
|
import {InvoiceCommit} from "../../../models/Staff";
|
||||||
import dayjs from 'dayjs';
|
import dayjs, {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";
|
||||||
|
import {
|
||||||
|
InvoiceIdentifyResponse,
|
||||||
|
invoiceItemsMap,
|
||||||
|
invoiceTypeItemsMap,
|
||||||
|
invoiceTypeNameMap,
|
||||||
|
} from "../../../models/Invoice";
|
||||||
|
|
||||||
const {Dragger} = Upload;
|
const {Dragger} = Upload;
|
||||||
|
|
||||||
|
@ -22,17 +28,6 @@ const props: UploadProps = {
|
||||||
console.log(file)
|
console.log(file)
|
||||||
return false
|
return false
|
||||||
},
|
},
|
||||||
onChange(info) {
|
|
||||||
// const { status } = info.file;
|
|
||||||
// if (status !== 'uploading') {
|
|
||||||
// console.log('here---------'+info.file, info.fileList);
|
|
||||||
// }
|
|
||||||
// if (status === 'done') {
|
|
||||||
// message.success(`${info.file.name} file uploaded successfully.`);
|
|
||||||
// } else if (status === 'error') {
|
|
||||||
// message.error(`${info.file.name} file upload failed.`);
|
|
||||||
// }
|
|
||||||
},
|
|
||||||
onDrop(e) {
|
onDrop(e) {
|
||||||
console.log('Dropped files', e.dataTransfer.files);
|
console.log('Dropped files', e.dataTransfer.files);
|
||||||
},
|
},
|
||||||
|
@ -86,7 +81,7 @@ function UpLoadModal(props: any) {
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
open={open}
|
open={open}
|
||||||
title="Title"
|
title="上传发票"
|
||||||
onOk={handleOk}
|
onOk={handleOk}
|
||||||
onCancel={handleCancel}
|
onCancel={handleCancel}
|
||||||
footer={[
|
footer={[
|
||||||
|
@ -105,104 +100,109 @@ function UpLoadModal(props: any) {
|
||||||
|
|
||||||
function FormModal(props: any) {
|
function FormModal(props: any) {
|
||||||
const [open, setOpen] = useState(false)
|
const [open, setOpen] = useState(false)
|
||||||
|
const [loading, setLoading] = useState(false)
|
||||||
|
const [invoice, setInvoice] = useState({})
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setOpen(props.open)
|
setOpen(props.open)
|
||||||
|
console.log(props.invoiceIdentifyResponse)
|
||||||
|
let i = {...props.invoiceIdentifyResponse}
|
||||||
|
setInvoice(i)
|
||||||
|
form.setFieldsValue(i)
|
||||||
}, [props]);
|
}, [props]);
|
||||||
const handleCancel = () => {
|
const handleCancel = () => {
|
||||||
setOpen(false);
|
setOpen(false);
|
||||||
};
|
};
|
||||||
const submit = () => {
|
const submit = () => {
|
||||||
let result = form!.getFieldsValue()
|
setLoading(true)
|
||||||
|
console.log(form.getFieldsValue())
|
||||||
|
let result:InvoiceIdentifyResponse = {...invoice , ...form.getFieldsValue()} as InvoiceIdentifyResponse
|
||||||
|
console.log(result)
|
||||||
|
if (typeof result.invoiceDate !== "string") {
|
||||||
result.invoiceDate = result.invoiceDate.format("YYYY-MM-DD")
|
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(": ")))
|
|
||||||
// let extraInfo=[]
|
result.invoiceAmount*=100
|
||||||
// let line = result.invoiceExtraInfo.split('\n')
|
console.log(result)
|
||||||
// for(let i=0;i<line.length;i++){
|
|
||||||
// let tmp = line[i].split(": ")
|
|
||||||
// if(tmp.length===2){
|
|
||||||
// extraInfo.push({name:tmp[0],value:tmp[1]})
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// result.invoiceExtraInfo=extraInfo
|
|
||||||
console.log(result.invoiceExtraInfo)
|
|
||||||
axiosInstance({
|
axiosInstance({
|
||||||
url: 'common/invoice/submit',
|
url: 'common/invoice/submit',
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
data: result
|
data: result
|
||||||
}).then(response => {
|
}).then(response => {
|
||||||
//TODO
|
|
||||||
console.log(response.data)
|
console.log(response.data)
|
||||||
|
setLoading(false)
|
||||||
|
setOpen(false)
|
||||||
}).catch(function (error) {
|
}).catch(function (error) {
|
||||||
console.log(error)
|
console.log(error)
|
||||||
|
setLoading(false)
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const inputComponent = (item: string) => {
|
||||||
|
if (item === 'invoiceDate')
|
||||||
|
return <DatePicker/>
|
||||||
|
else if(item === 'invoiceAmount')
|
||||||
|
return <InputNumber
|
||||||
|
style={{ width: '100%' }}
|
||||||
|
formatter={(value) => `¥ ${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')}
|
||||||
|
/>
|
||||||
|
else
|
||||||
|
return <Input/>
|
||||||
|
}
|
||||||
|
let formItems = invoiceTypeItemsMap.get(props.invoiceIdentifyResponse?.invoiceKind)?.map((item, index) => {
|
||||||
|
return (
|
||||||
|
<Form.Item
|
||||||
|
key={index}
|
||||||
|
name={item}
|
||||||
|
label={invoiceItemsMap.get(item)}
|
||||||
|
>
|
||||||
|
{inputComponent(item)}
|
||||||
|
</Form.Item>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
const getInvoiceKindOptions = () => {
|
||||||
|
let options: { value: number; label: string; }[] = []
|
||||||
|
invoiceTypeNameMap.forEach(function (value, key, map) {
|
||||||
|
options.push({
|
||||||
|
value: key,
|
||||||
|
label: value,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
return options
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
open={open}
|
open={open}
|
||||||
|
title="提交发票"
|
||||||
title="Title"
|
|
||||||
onOk={submit}
|
onOk={submit}
|
||||||
onCancel={handleCancel}
|
onCancel={handleCancel}
|
||||||
footer={[
|
footer={[
|
||||||
<Button key="cancel" onClick={handleCancel}>
|
<Button key="cancel" onClick={handleCancel}>
|
||||||
取消
|
取消
|
||||||
</Button>,
|
</Button>,
|
||||||
<Button key="next" type="primary" loading={false} onClick={submit}
|
<Button key="next" type="primary" loading={loading} onClick={submit}
|
||||||
>
|
>
|
||||||
下一步
|
提交
|
||||||
</Button>
|
</Button>
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<Form form={form}>
|
<Form form={form} layout="horizontal" labelCol={{span: 4}}
|
||||||
|
|
||||||
<Form.Item
|
|
||||||
name={`invoiceNo`}
|
|
||||||
label={`发票编码`}
|
|
||||||
>
|
>
|
||||||
<Input/>
|
|
||||||
</Form.Item>
|
|
||||||
<Form.Item
|
|
||||||
name={`invoiceCode`}
|
|
||||||
label={`发票代码`}
|
|
||||||
>
|
|
||||||
<Input/>
|
|
||||||
</Form.Item>
|
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name={`invoiceKind`}
|
name={`invoiceKind`}
|
||||||
label={`发票类型`}
|
label={`发票类型`}
|
||||||
>
|
>
|
||||||
<Input/>
|
<Select
|
||||||
|
options={getInvoiceKindOptions()}
|
||||||
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
{formItems}
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name={`invoiceAmount`}
|
name={`invoiceNote`}
|
||||||
label={`计税总额`}
|
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/>
|
<TextArea/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
@ -213,44 +213,32 @@ function FormModal(props: any) {
|
||||||
|
|
||||||
|
|
||||||
class InvoiceUploadView extends React.Component<any, any> {
|
class InvoiceUploadView extends React.Component<any, any> {
|
||||||
formRef = React.createRef<FormInstance>();
|
|
||||||
|
|
||||||
constructor(props: {}) {
|
constructor(props: {}) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
loading: false,
|
uploadModalOpen: false,
|
||||||
open: false,
|
formModalOpen: false,
|
||||||
uploadOpen: false,
|
invoiceIdentifyResponse: null
|
||||||
uploadStep: 0,
|
|
||||||
invoiceCommit: new InvoiceCommit(),
|
|
||||||
}
|
|
||||||
this.state.invoiceCommit.invoiceNo = "init"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setUploadOpen(value: Boolean) {
|
|
||||||
this.setState({uploadOpen: value})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setOpen(value: Boolean) {
|
setOpen(value: Boolean) {
|
||||||
this.setState({open: value})
|
this.setState({uploadModalOpen: value})
|
||||||
}
|
}
|
||||||
|
|
||||||
showUploadView = () => {
|
showUploadView = () => {
|
||||||
this.setOpen(true);
|
this.setOpen(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
handleUploadCanCel = () => {
|
|
||||||
this.setUploadOpen(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
handleNextStep = (response: InvoiceIdentifyResponse) => {
|
handleNextStep = (response: InvoiceIdentifyResponse) => {
|
||||||
this.setState({open: false, uploadOpen: true})
|
response.invoiceDate = dayjs(response.invoiceDate)
|
||||||
|
response.invoiceAmount /= 100.
|
||||||
|
this.setState({uploadModalOpen: false, formModalOpen: true, invoiceIdentifyResponse: response})
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
console.log(this.state.invoiceCommit)
|
|
||||||
console.log(this.state.uploadStep)
|
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
return (
|
return (
|
||||||
|
@ -259,8 +247,9 @@ class InvoiceUploadView extends React.Component<any, any> {
|
||||||
size="large">
|
size="large">
|
||||||
上传
|
上传
|
||||||
</Button>
|
</Button>
|
||||||
<UpLoadModal open={this.state.open} nextStep={this.handleNextStep}/>
|
<UpLoadModal open={this.state.uploadModalOpen} nextStep={this.handleNextStep}/>
|
||||||
<FormModal open={this.state.uploadOpen}/>
|
<FormModal open={this.state.formModalOpen}
|
||||||
|
invoiceIdentifyResponse={this.state.invoiceIdentifyResponse}/>
|
||||||
</>);
|
</>);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import React from 'react';
|
import React, {useState} from 'react';
|
||||||
import {Button, Form, Input} from 'antd';
|
import {Button, Form, Input, Alert} from 'antd';
|
||||||
import {LockOutlined, UserOutlined} from '@ant-design/icons';
|
import {LockOutlined, UserOutlined} from '@ant-design/icons';
|
||||||
import './LoginView.css';
|
import './LoginView.css';
|
||||||
import loginImg from '../../assets/login.png'
|
import loginImg from '../../assets/login.png'
|
||||||
|
@ -12,7 +12,8 @@ import {setToken} from "../../models/store";
|
||||||
function LoginView() {
|
function LoginView() {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
|
const [showAlert, setShowAlert] = useState(false)
|
||||||
|
const [alertMessage, setAlertMessage] = useState('')
|
||||||
const onFinish = (values: any) => {
|
const onFinish = (values: any) => {
|
||||||
console.log(values)
|
console.log(values)
|
||||||
const data = new FormData();
|
const data = new FormData();
|
||||||
|
@ -30,7 +31,8 @@ function LoginView() {
|
||||||
navigate('/invoice/mine')
|
navigate('/invoice/mine')
|
||||||
}).catch(function (error) {
|
}).catch(function (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
//showAlert.value = true
|
setAlertMessage(error.response.data.msg)
|
||||||
|
setShowAlert(true)
|
||||||
});
|
});
|
||||||
console.log('Success:', values);
|
console.log('Success:', values);
|
||||||
};
|
};
|
||||||
|
@ -38,6 +40,9 @@ function LoginView() {
|
||||||
console.log('Failed:', errorInfo);
|
console.log('Failed:', errorInfo);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const afterClose = () =>{
|
||||||
|
setShowAlert(false)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="background">
|
<div className="background">
|
||||||
|
@ -93,7 +98,16 @@ function LoginView() {
|
||||||
<Input.Password prefix={<LockOutlined/>}
|
<Input.Password prefix={<LockOutlined/>}
|
||||||
placeholder="密码"/>
|
placeholder="密码"/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
{showAlert&&
|
||||||
|
<Alert
|
||||||
|
style={{marginBottom: 20, height: 32}}
|
||||||
|
message={alertMessage}
|
||||||
|
type="error"
|
||||||
|
closable
|
||||||
|
showIcon
|
||||||
|
afterClose={afterClose}
|
||||||
|
/>
|
||||||
|
}
|
||||||
<Form.Item>
|
<Form.Item>
|
||||||
<Button type="primary" htmlType="submit" style={{width: '100%'}}>
|
<Button type="primary" htmlType="submit" style={{width: '100%'}}>
|
||||||
登录
|
登录
|
||||||
|
|
|
@ -15,7 +15,7 @@ axiosInstance.interceptors.request.use(
|
||||||
function (config: AxiosRequestConfig) {
|
function (config: AxiosRequestConfig) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
config.headers.Authorization = "Bearer " + store.getState().token.accessToken
|
config.headers.Authorization = "Bearer " + store.getState().token.accessToken
|
||||||
console.log(config)
|
//console.log(config)
|
||||||
return config
|
return config
|
||||||
},
|
},
|
||||||
function (error) {
|
function (error) {
|
||||||
|
|
|
@ -18,7 +18,8 @@
|
||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
"isolatedModules": true,
|
"isolatedModules": true,
|
||||||
"noEmit": true,
|
"noEmit": true,
|
||||||
"jsx": "react-jsx"
|
"jsx": "react-jsx",
|
||||||
|
"downlevelIteration": true
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
"src"
|
"src"
|
||||||
|
|
Loading…
Reference in New Issue