Merge remote-tracking branch 'origin/main'
commit
c95fb9ab79
|
@ -25,6 +25,69 @@ export interface Invoice {
|
||||||
reimbursement: Reimbursement;
|
reimbursement: Reimbursement;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
type Nullable<T> = T | undefined | null;
|
||||||
|
|
||||||
|
export class InvoiceSearchOption {
|
||||||
|
invoiceNo: Nullable<string>
|
||||||
|
invoiceCode: Nullable<string>
|
||||||
|
invoiceUploadTimeStart: Nullable<string>
|
||||||
|
invoiceUploadTimeEnd: Nullable<string>
|
||||||
|
invoiceStates: Nullable<any[]>
|
||||||
|
invoiceKinds: Nullable<any[]>
|
||||||
|
invoiceDateStart: Nullable<string>
|
||||||
|
invoiceDateEnd: Nullable<string>
|
||||||
|
invoiceNote: Nullable<string>
|
||||||
|
invoiceUploaderId: Nullable<string>
|
||||||
|
pageNum: number
|
||||||
|
pageSize: number
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.pageNum = 0
|
||||||
|
this.pageSize = 20
|
||||||
|
this.clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
clear() {
|
||||||
|
this.invoiceNo = null
|
||||||
|
this.invoiceCode = null
|
||||||
|
this.invoiceUploadTimeStart = null
|
||||||
|
this.invoiceUploadTimeEnd = null
|
||||||
|
this.invoiceStates = null
|
||||||
|
this.invoiceKinds = null
|
||||||
|
this.invoiceDateStart = null
|
||||||
|
this.invoiceDateEnd = null
|
||||||
|
this.invoiceNote = null
|
||||||
|
this.invoiceUploaderId = null
|
||||||
|
this.pageNum = 0
|
||||||
|
this.pageSize = 20
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface InvoiceDetail {
|
||||||
|
invoiceAmount: number;
|
||||||
|
invoiceCode: string;
|
||||||
|
invoiceDate: string |Dayjs;
|
||||||
|
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|Dayjs;
|
||||||
|
modified: boolean;
|
||||||
|
reimbursement: Reimbursement;
|
||||||
|
}
|
||||||
|
|
||||||
export interface InvoiceIdentifyResponse {
|
export interface InvoiceIdentifyResponse {
|
||||||
invoiceAmount: number;
|
invoiceAmount: number;
|
||||||
invoiceCheckCode?: string;
|
invoiceCheckCode?: string;
|
||||||
|
@ -79,14 +142,40 @@ export const invoiceItemsMap = new Map([
|
||||||
])
|
])
|
||||||
|
|
||||||
export const invoiceTypeItemsMap = new Map([
|
export const invoiceTypeItemsMap = new Map([
|
||||||
|
[0, ['invoiceName', 'invoiceNo', 'invoiceCode', 'invoiceAmount', 'invoiceDate', 'invoiceDeparture', 'invoiceDestination']],
|
||||||
|
[1, ['invoiceName', 'invoiceNo', 'invoiceCode', 'invoiceAmount', 'invoiceDate', 'invoiceCheckCode']],
|
||||||
|
[2, ['invoiceName', 'invoiceNo', 'invoiceCode', 'invoiceAmount', 'invoiceDate', 'invoiceDeparture', 'invoiceDestination']],
|
||||||
[3, ['invoiceName', 'invoiceNo', 'invoiceCode', 'invoiceAmount', 'invoiceDate', 'invoiceCheckCode']],
|
[3, ['invoiceName', 'invoiceNo', 'invoiceCode', 'invoiceAmount', 'invoiceDate', 'invoiceCheckCode']],
|
||||||
|
[5, ['invoiceName', 'invoiceNo', 'invoiceCode', 'invoiceAmount', 'invoiceDate', 'invoiceDeparture', 'invoiceDestination']],
|
||||||
|
[8, ['invoiceName', 'invoiceNo', 'invoiceCode', 'invoiceAmount', 'invoiceDate', 'invoiceCheckCode']],
|
||||||
|
[9, ['invoiceName', 'invoiceNo', 'invoiceCode', 'invoiceAmount', 'invoiceDate', 'invoiceDeparture', 'invoiceDestination']],
|
||||||
|
[10, ['invoiceName', 'invoiceNo', 'invoiceCode', 'invoiceAmount', 'invoiceDate', 'invoiceDeparture', 'invoiceDestination']],
|
||||||
|
[11, ['invoiceName', 'invoiceNo', 'invoiceCode', 'invoiceAmount', 'invoiceDate', 'invoiceCheckCode']],
|
||||||
|
[12, ['invoiceName', 'invoiceNo', 'invoiceCode', 'invoiceAmount', 'invoiceDate', 'invoiceCheckCode']],
|
||||||
[13, ['invoiceName', 'invoiceNo', 'invoiceCode', 'invoiceAmount', 'invoiceDate', 'invoiceDeparture', 'invoiceDestination']],
|
[13, ['invoiceName', 'invoiceNo', 'invoiceCode', 'invoiceAmount', 'invoiceDate', 'invoiceDeparture', 'invoiceDestination']],
|
||||||
|
[15, ['invoiceName', 'invoiceNo', 'invoiceCode', 'invoiceAmount', 'invoiceDate', 'invoiceCheckCode']],
|
||||||
|
[16, ['invoiceName', 'invoiceNo', 'invoiceCode', 'invoiceAmount', 'invoiceDate', 'invoiceCheckCode']],
|
||||||
])
|
])
|
||||||
export const invoiceTypeExtraItemsMap = new Map([
|
export const invoiceTypeExtraItemsMap = new Map([
|
||||||
[3, ['合计金额','合计税额', '购买方名称', '销售方名称', '收款人']],
|
[3, ['合计金额','合计税额', '购买方名称', '销售方名称', '收款人']],
|
||||||
[13, ['时间']],
|
[13, ['时间']],
|
||||||
])
|
])
|
||||||
|
|
||||||
|
export const invoiceTypeShowItemsMap = new Map([
|
||||||
|
[0, ['invoiceName', 'invoiceNo', 'invoiceCode', 'invoiceAmount', 'invoiceDate', 'invoiceDeparture', 'invoiceDestination']],
|
||||||
|
[1, ['invoiceName', 'invoiceNo', 'invoiceCode', 'invoiceAmount', 'invoiceDate']],
|
||||||
|
[2, ['invoiceName', 'invoiceNo', 'invoiceCode', 'invoiceAmount', 'invoiceDate', 'invoiceDeparture', 'invoiceDestination']],
|
||||||
|
[3, ['invoiceName', 'invoiceNo', 'invoiceCode', 'invoiceAmount', 'invoiceDate']],
|
||||||
|
[5, ['invoiceName', 'invoiceNo', 'invoiceCode', 'invoiceAmount', 'invoiceDate', 'invoiceDeparture', 'invoiceDestination']],
|
||||||
|
[8, ['invoiceName', 'invoiceNo', 'invoiceCode', 'invoiceAmount', 'invoiceDate']],
|
||||||
|
[9, ['invoiceName', 'invoiceNo', 'invoiceCode', 'invoiceAmount', 'invoiceDate', 'invoiceDeparture', 'invoiceDestination']],
|
||||||
|
[10, ['invoiceName', 'invoiceNo', 'invoiceCode', 'invoiceAmount', 'invoiceDate', 'invoiceDeparture', 'invoiceDestination']],
|
||||||
|
[11, ['invoiceName', 'invoiceNo', 'invoiceCode', 'invoiceAmount', 'invoiceDate']],
|
||||||
|
[12, ['invoiceName', 'invoiceNo', 'invoiceCode', 'invoiceAmount', 'invoiceDate']],
|
||||||
|
[13, ['invoiceName', 'invoiceNo', 'invoiceCode', 'invoiceAmount', 'invoiceDate', 'invoiceDeparture', 'invoiceDestination']],
|
||||||
|
[15, ['invoiceName', 'invoiceNo', 'invoiceCode', 'invoiceAmount', 'invoiceDate']],
|
||||||
|
[16, ['invoiceName', 'invoiceNo', 'invoiceCode', 'invoiceAmount', 'invoiceDate']],
|
||||||
|
])
|
||||||
|
|
||||||
/*
|
/*
|
||||||
{
|
{
|
||||||
|
|
|
@ -12,6 +12,7 @@ export interface Staff {
|
||||||
staffDepartments: Department[];
|
staffDepartments: Department[];
|
||||||
staffName: string;
|
staffName: string;
|
||||||
staffBase: string;
|
staffBase: string;
|
||||||
|
staffId: string|null|undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Department {
|
export interface Department {
|
||||||
|
@ -19,133 +20,3 @@ export interface Department {
|
||||||
departmentName: string;
|
departmentName: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
type Nullable<T> = T | undefined | null;
|
|
||||||
|
|
||||||
export class InvoiceSearchOption {
|
|
||||||
invoiceNo: Nullable<string>
|
|
||||||
invoiceCode: Nullable<string>
|
|
||||||
invoiceUploadTimeStart: Nullable<string>
|
|
||||||
invoiceUploadTimeEnd: Nullable<string>
|
|
||||||
invoiceState: Nullable<number>
|
|
||||||
invoiceKind: Nullable<string>
|
|
||||||
invoiceDateStart: Nullable<string>
|
|
||||||
invoiceDateEnd: Nullable<string>
|
|
||||||
invoiceNote: Nullable<string>
|
|
||||||
invoiceUploader: Nullable<string>
|
|
||||||
pageNum: number
|
|
||||||
pageSize: number
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
this.pageNum = 0
|
|
||||||
this.pageSize = 20
|
|
||||||
this.clear()
|
|
||||||
}
|
|
||||||
|
|
||||||
clear() {
|
|
||||||
this.invoiceNo = null
|
|
||||||
this.invoiceCode = null
|
|
||||||
this.invoiceUploadTimeStart = null
|
|
||||||
this.invoiceUploadTimeEnd = null
|
|
||||||
this.invoiceState = null
|
|
||||||
this.invoiceKind = null
|
|
||||||
this.invoiceDateStart = null
|
|
||||||
this.invoiceDateEnd = null
|
|
||||||
this.invoiceNote = null
|
|
||||||
this.invoiceUploader = null
|
|
||||||
this.pageNum = 0
|
|
||||||
this.pageSize = 20
|
|
||||||
}
|
|
||||||
|
|
||||||
// toString(){
|
|
||||||
// let res="pageNum="+this.pageNum+"&pageSize="+this.pageSize
|
|
||||||
// res+=(this.invoiceNo===undefined||this.invoiceNo===null||this.invoiceNo===""?"":("&invoiceNo="+this.invoiceNo));
|
|
||||||
// res+=(this.invoiceCode===undefined||this.invoiceCode===null||this.invoiceCode===""?"":("&invoiceCode="+this.invoiceCode));
|
|
||||||
// res+=(this.invoiceUploadTimeStart===undefined||this.invoiceUploadTimeStart===null?"":("&invoiceUploadTimeStart="+this.invoiceUploadTimeStart));
|
|
||||||
// res+=(this.invoiceUploadTimeEnd===undefined||this.invoiceUploadTimeEnd===null?"":("&invoiceUploadTimeEnd="+this.invoiceUploadTimeEnd));
|
|
||||||
// res+=(this.invoiceState===undefined||this.invoiceState===null?"":("&invoiceState="+this.invoiceState));
|
|
||||||
// res+=(this.invoiceKind===undefined||this.invoiceKind===null?"":("&invoiceKind="+this.invoiceKind));
|
|
||||||
// res+=(this.invoiceDateStart===undefined||this.invoiceDateStart===null?"":("&invoiceDateStart="+this.invoiceDateStart));
|
|
||||||
// res+=(this.invoiceDateEnd===undefined||this.invoiceDateEnd===null?"":("&invoiceDateEnd="+this.invoiceDateEnd));
|
|
||||||
// res+=(this.invoiceNote===undefined||this.invoiceNote===null?"":("&invoiceNote="+this.invoiceNote));
|
|
||||||
// res+=(this.invoiceUploader===undefined||this.invoiceUploader===null?"":("&invoiceUploader="+this.invoiceUploader));
|
|
||||||
// return res;
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
export class InvoiceCommit {
|
|
||||||
invoiceFileName: string
|
|
||||||
invoiceNo: string
|
|
||||||
invoiceCode: string
|
|
||||||
invoiceKind: string
|
|
||||||
invoiceDate: dayjs.Dayjs
|
|
||||||
invoiceAmount: number
|
|
||||||
invoiceAmountWithoutTax: number
|
|
||||||
invoiceCheckCode: string
|
|
||||||
invoiceRegionCode: Nullable<string>
|
|
||||||
invoiceSellerTaxCode: Nullable<string>
|
|
||||||
invoiceExtraInfo: Nullable<string> | [] | Map<any, string>
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
this.invoiceFileName = ""
|
|
||||||
this.invoiceNo = ""
|
|
||||||
this.invoiceCode = ""
|
|
||||||
this.invoiceKind = ""
|
|
||||||
this.invoiceDate = dayjs()
|
|
||||||
this.invoiceAmount = 0
|
|
||||||
this.invoiceAmountWithoutTax = 0
|
|
||||||
this.invoiceCheckCode = "000000"
|
|
||||||
this.invoiceRegionCode = null
|
|
||||||
this.invoiceSellerTaxCode = null
|
|
||||||
this.invoiceExtraInfo = null
|
|
||||||
}
|
|
||||||
|
|
||||||
setValue(props: FormData) {
|
|
||||||
console.log("1111" + props.toString())
|
|
||||||
this.invoiceFileName = props.get("invoiceFileName")!.toString()
|
|
||||||
this.invoiceNo = props.get("invoiceNo")!.toString()
|
|
||||||
this.invoiceCode = props.get("invoiceCode")!.toString()
|
|
||||||
this.invoiceKind = props.get("invoiceKind")!.toString()
|
|
||||||
//this.invoiceDate = new Date(props.get("invoiceDate")!.toString())
|
|
||||||
//this.invoiceAmount = props.get("invoiceAmount")!.toString()
|
|
||||||
//this.invoiceAmountWithoutTax = props.get("invoiceAmountWithoutTax")!.toString()
|
|
||||||
this.invoiceCheckCode = props.get("invoiceCheckCode")!.toString()
|
|
||||||
this.invoiceRegionCode = props.get("invoiceRegionCode")!.toString()
|
|
||||||
this.invoiceSellerTaxCode = props.get("invoiceSellerTaxCode")!.toString()
|
|
||||||
//this.invoiceExtraInfo = props.get("invoiceExtraInfo")!.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Reimbursement {
|
|
||||||
/**
|
|
||||||
* 差旅补助金额
|
|
||||||
*/
|
|
||||||
reimbursementAdditionalAmount: number;
|
|
||||||
reimbursementDepartureInvoiceId: number;
|
|
||||||
reimbursementDepartureName: string;
|
|
||||||
reimbursementDestinationInvoiceId?: number;
|
|
||||||
reimbursementDestinationName: string;
|
|
||||||
reimbursementId: number;
|
|
||||||
/**
|
|
||||||
* 发票金额
|
|
||||||
*/
|
|
||||||
reimbursementInvoiceAmount: number;
|
|
||||||
reimbursementNote?: string;
|
|
||||||
/**
|
|
||||||
* 0: success
|
|
||||||
* 1: 待主管审批
|
|
||||||
* 2: 待财务审批
|
|
||||||
* 3: 待财务主管审批
|
|
||||||
* 4: 待总经理审批
|
|
||||||
* 5: 未通过
|
|
||||||
*/
|
|
||||||
reimbursementStatus: number;
|
|
||||||
reimbursementSubmitDepartmentId: number;
|
|
||||||
reimbursementSubmitStaffId: string;
|
|
||||||
reimbursementSubmitTime: string;
|
|
||||||
/**
|
|
||||||
* 单位为天
|
|
||||||
*/
|
|
||||||
reimbursementTripDuration: number;
|
|
||||||
}
|
|
|
@ -27,6 +27,7 @@ const tokenSlice = createSlice({
|
||||||
const staffSlice = createSlice({
|
const staffSlice = createSlice({
|
||||||
name: 'staff',
|
name: 'staff',
|
||||||
initialState: {
|
initialState: {
|
||||||
|
staffId: "",
|
||||||
staffName: "",
|
staffName: "",
|
||||||
managingDepartment: null as Department|null,
|
managingDepartment: null as Department|null,
|
||||||
staffDepartments: [{ departmentId: 0,
|
staffDepartments: [{ departmentId: 0,
|
||||||
|
|
|
@ -83,7 +83,9 @@ function HeaderBar(props: any) {
|
||||||
background: colorBgContainer,
|
background: colorBgContainer,
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
flexDirection: 'row-reverse',
|
flexDirection: 'row-reverse',
|
||||||
alignItems: 'center'
|
alignItems: 'center',
|
||||||
|
zIndex: 100,
|
||||||
|
boxShadow: '0px 6px 16px 0px rgba(0, 0, 0, 0.08)'
|
||||||
}}>
|
}}>
|
||||||
<Dropdown overlayStyle={{minWidth: '150px'}} menu={{items, onClick}} placement="bottomRight" arrow>
|
<Dropdown overlayStyle={{minWidth: '150px'}} menu={{items, onClick}} placement="bottomRight" arrow>
|
||||||
<Button type="text" style={{
|
<Button type="text" style={{
|
||||||
|
@ -111,7 +113,7 @@ function MainMenu(props: any) {
|
||||||
else
|
else
|
||||||
return (
|
return (
|
||||||
<Menu
|
<Menu
|
||||||
style={{height: '100%'}}
|
style={{borderInlineEnd: 'unset'}}
|
||||||
mode="inline"
|
mode="inline"
|
||||||
defaultSelectedKeys={props.defaultSelectedKeys}
|
defaultSelectedKeys={props.defaultSelectedKeys}
|
||||||
items={props.items}
|
items={props.items}
|
||||||
|
@ -195,7 +197,8 @@ function HomeView() {
|
||||||
<Layout style={{height: '100%'}}>
|
<Layout style={{height: '100%'}}>
|
||||||
<Sider
|
<Sider
|
||||||
width={208}
|
width={208}
|
||||||
style={{background: colorBgContainer, boxShadow: '9px 0px 28px 0px rgba(0, 0, 0, 0.05)'}}
|
style={{background: colorBgContainer,zIndex: 200, boxShadow: '6px 0px 16px 0px rgba(0, 0, 0, 0.08)',
|
||||||
|
borderInlineEnd: '1px solid rgba(5, 5, 5, 0.06)'}}
|
||||||
breakpoint="lg"
|
breakpoint="lg"
|
||||||
collapsedWidth="0"
|
collapsedWidth="0"
|
||||||
onBreakpoint={(broken) => {
|
onBreakpoint={(broken) => {
|
||||||
|
@ -212,7 +215,6 @@ function HomeView() {
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
borderInlineEnd: '1px solid rgba(5, 5, 5, 0.06)'
|
|
||||||
}}>
|
}}>
|
||||||
<Icon component={Logo}/>
|
<Icon component={Logo}/>
|
||||||
<span style={{
|
<span style={{
|
||||||
|
@ -222,7 +224,7 @@ function HomeView() {
|
||||||
marginLeft: '4px'
|
marginLeft: '4px'
|
||||||
}}>智能财务报销系统</span>
|
}}>智能财务报销系统</span>
|
||||||
</div>
|
</div>
|
||||||
<MainMenu style={{height: '100%'}} items={menuItems} defaultSelectedKeys={defaultSelectedKeys}/>
|
<MainMenu items={menuItems} defaultSelectedKeys={defaultSelectedKeys}/>
|
||||||
</Sider>
|
</Sider>
|
||||||
<Layout>
|
<Layout>
|
||||||
<HeaderBar/>
|
<HeaderBar/>
|
||||||
|
|
|
@ -0,0 +1,130 @@
|
||||||
|
import React, {useEffect, useState} from "react";
|
||||||
|
import {Button, DatePicker, Form, Input, InputNumber, Modal, Select, Typography} from "antd";
|
||||||
|
import {
|
||||||
|
InvoiceDetail,
|
||||||
|
InvoiceIdentifyResponse,
|
||||||
|
invoiceItemsMap, invoiceTypeExtraItemsMap,
|
||||||
|
invoiceTypeItemsMap,
|
||||||
|
invoiceTypeNameMap, invoiceTypeShowItemsMap
|
||||||
|
} from "../../models/Invoice";
|
||||||
|
import axiosInstance from "../../utils/axiosInstance";
|
||||||
|
import TextArea from "antd/es/input/TextArea";
|
||||||
|
import dayjs, {Dayjs} from "dayjs";
|
||||||
|
import qs from "qs";
|
||||||
|
|
||||||
|
const {Text, Paragraph} = Typography;
|
||||||
|
|
||||||
|
function InvoiceDetailModal(props: any) {
|
||||||
|
//const [open, setOpen] = useState(false)
|
||||||
|
const [loading, setLoading] = useState(false)
|
||||||
|
const [invoice, setInvoice] = useState(null as any)
|
||||||
|
const [formItems, setFormItems] = useState(undefined)
|
||||||
|
//const [form] = Form.useForm();
|
||||||
|
useEffect(() => {
|
||||||
|
|
||||||
|
console.log(props.invoiceDetail)
|
||||||
|
let i = {...props.invoiceDetail}
|
||||||
|
|
||||||
|
setInvoice(i)
|
||||||
|
refreshFormItems(i.invoiceKind)
|
||||||
|
|
||||||
|
}, [props]);
|
||||||
|
const handleCancel = () => {
|
||||||
|
props.onClose()
|
||||||
|
//setOpen(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const inputComponent = (item: string) => {
|
||||||
|
if (item === 'invoiceDate')
|
||||||
|
return <Text>{dayjs(props.invoiceDetail[item]).format('YYYY年MM月DD日')}</Text>
|
||||||
|
else if (item === 'invoiceAmount')
|
||||||
|
return <Text>{`¥ ${props.invoiceDetail[item]}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')}</Text>
|
||||||
|
else
|
||||||
|
return <Text>{props.invoiceDetail[item]}</Text>
|
||||||
|
}
|
||||||
|
|
||||||
|
const refreshFormItems = (invoiceKind: number) => {
|
||||||
|
let items = invoiceTypeShowItemsMap.get(invoiceKind)?.map((item, index) => {
|
||||||
|
return (
|
||||||
|
<Form.Item
|
||||||
|
key={index}
|
||||||
|
name={item}
|
||||||
|
label={invoiceItemsMap.get(item)}
|
||||||
|
>
|
||||||
|
{inputComponent(item)}
|
||||||
|
</Form.Item>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
let extraItems = invoiceTypeExtraItemsMap.get(invoiceKind)?.map((item, index) => {
|
||||||
|
return (
|
||||||
|
<Form.Item
|
||||||
|
key={index}
|
||||||
|
name={['invoiceExtraInfo', item]}
|
||||||
|
label={item}
|
||||||
|
>
|
||||||
|
{inputComponent(item)}
|
||||||
|
</Form.Item>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
setFormItems(<>
|
||||||
|
{items}
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const onTypeChange = (value: number) => {
|
||||||
|
refreshFormItems(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
const withDraw = () => {
|
||||||
|
setLoading(true)
|
||||||
|
axiosInstance({
|
||||||
|
url: 'common/invoice/' + props.invoiceDetail.invoiceId,
|
||||||
|
method: 'delete',
|
||||||
|
}).then(response => {
|
||||||
|
console.log(response.data)
|
||||||
|
setLoading(false)
|
||||||
|
props.onClose()
|
||||||
|
props.needRefresh()
|
||||||
|
}).catch(function (error) {
|
||||||
|
console.log(error)
|
||||||
|
setLoading(false)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
open={props.open}
|
||||||
|
title="发票详情"
|
||||||
|
onCancel={handleCancel}
|
||||||
|
footer={ <Button key="next" type="primary" danger loading={loading} onClick={withDraw}
|
||||||
|
>
|
||||||
|
撤回
|
||||||
|
</Button> }
|
||||||
|
>
|
||||||
|
{
|
||||||
|
<Form layout="horizontal" labelCol={{span: 4}}
|
||||||
|
>
|
||||||
|
<Form.Item
|
||||||
|
name={`invoiceKind`}
|
||||||
|
label={`发票类型`}
|
||||||
|
>
|
||||||
|
<Text>{invoiceTypeNameMap.get(props.invoiceDetail?.invoiceKind)}</Text>
|
||||||
|
</Form.Item>
|
||||||
|
{formItems}
|
||||||
|
<Form.Item
|
||||||
|
name={`invoiceNote`}
|
||||||
|
label={`备注`}
|
||||||
|
>
|
||||||
|
<Paragraph style={{marginTop: 5}}>{props.invoiceDetail?.invoiceNote}</Paragraph>
|
||||||
|
</Form.Item>
|
||||||
|
</Form>
|
||||||
|
}
|
||||||
|
|
||||||
|
</Modal>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default InvoiceDetailModal
|
|
@ -1,6 +1,374 @@
|
||||||
function InvoiceManagement() {
|
import {
|
||||||
|
Card,
|
||||||
|
Dropdown,
|
||||||
|
List,
|
||||||
|
Row,
|
||||||
|
Input,
|
||||||
|
Button,
|
||||||
|
Radio,
|
||||||
|
Col,
|
||||||
|
Divider,
|
||||||
|
DatePicker,
|
||||||
|
Form,
|
||||||
|
TimePicker,
|
||||||
|
Select,
|
||||||
|
Checkbox,
|
||||||
|
Pagination, theme, Tag, Badge
|
||||||
|
} from "antd";
|
||||||
|
import type {MenuProps, PaginationProps} from 'antd';
|
||||||
|
import {DownOutlined, UploadOutlined} from '@ant-design/icons';
|
||||||
|
import React, {
|
||||||
|
ReactElement,
|
||||||
|
JSXElementConstructor,
|
||||||
|
ReactFragment,
|
||||||
|
ReactPortal,
|
||||||
|
useState,
|
||||||
|
useEffect,
|
||||||
|
ReactNode
|
||||||
|
} from "react";
|
||||||
|
import {InvoiceDetail, InvoiceSearchOption} from "../../../models/Invoice"
|
||||||
|
import {Space, Typography} from 'antd';
|
||||||
|
import {SizeType} from "antd/es/config-provider/SizeContext";
|
||||||
|
import axios from "axios";
|
||||||
|
import axiosInstance, {baseUrl} from "../../../utils/axiosInstance";
|
||||||
|
import {Simulate} from "react-dom/test-utils";
|
||||||
|
import change = Simulate.change;
|
||||||
|
import {useNavigate, useSearchParams} from "react-router-dom";
|
||||||
|
import {useAppDispatch} from "../../../models/hooks";
|
||||||
|
import {
|
||||||
|
Invoice,
|
||||||
|
invoiceItemsMap,
|
||||||
|
invoiceTypeExtraItemsMap,
|
||||||
|
invoiceTypeItemsMap,
|
||||||
|
invoiceTypeNameMap
|
||||||
|
} from "../../../models/Invoice";
|
||||||
|
import {RadioButtonProps} from "antd/es/radio/radioButton";
|
||||||
|
import qs from "qs";
|
||||||
|
import InvoiceDetailModal from "../InvoiceDetailModal";
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
|
||||||
|
|
||||||
|
const {Text, Paragraph} = Typography;
|
||||||
|
const {Meta} = Card;
|
||||||
|
const {Search} = Input;
|
||||||
|
const {Option} = Select
|
||||||
|
let invoices: Array<Invoice>
|
||||||
|
const {RangePicker} = DatePicker;
|
||||||
|
|
||||||
|
const config = {
|
||||||
|
rules: [{type: 'object' as const, required: false, message: 'Please select time!'}],
|
||||||
|
};
|
||||||
|
const rangeConfig = {
|
||||||
|
rules: [{type: 'array' as const, required: false, message: 'Please select time!'}],
|
||||||
|
};
|
||||||
|
|
||||||
|
function InvoiceSearch(props: { handleSearchData: any; }) {
|
||||||
|
const {
|
||||||
|
token: {colorBgContainer, colorPrimary},
|
||||||
|
} = theme.useToken();
|
||||||
|
|
||||||
|
const [activatedOption, setActivatedOption] = useState('发票代码')
|
||||||
|
const [complexEnabled, setComplexEnabled] = useState(false)
|
||||||
|
const [invoiceSearchOption, setInvoiceSearchOption] = useState(new InvoiceSearchOption())
|
||||||
|
|
||||||
|
const items: MenuProps['items'] = [
|
||||||
|
{
|
||||||
|
key: '1',
|
||||||
|
label: (<a className="simpleSearchOption" onClick={() => {
|
||||||
|
invoiceSearchOption.clear();
|
||||||
|
setActivatedOption("发票代码")
|
||||||
|
}}>
|
||||||
|
发票代码
|
||||||
|
</a>)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: '2',
|
||||||
|
label: (<a className="simpleSearchOption" onClick={() => {
|
||||||
|
invoiceSearchOption.clear();
|
||||||
|
setActivatedOption("发票编号")
|
||||||
|
|
||||||
|
}}>
|
||||||
|
发票编号
|
||||||
|
</a>)
|
||||||
|
}
|
||||||
|
];
|
||||||
|
const onValuesChange = (changedValues: any, allValues: any) => {
|
||||||
|
invoiceSearchOption.clear()
|
||||||
|
|
||||||
|
console.log(allValues)
|
||||||
|
if (allValues['upload-time-picker'] !== null && allValues['upload-time-picker'] !== undefined) {
|
||||||
|
invoiceSearchOption.invoiceUploadTimeStart = allValues['upload-time-picker'][0].format('YYYY-MM-DDtHH:mm:ss')
|
||||||
|
invoiceSearchOption.invoiceUploadTimeEnd = allValues['upload-time-picker'][1].format('YYYY-MM-DDtHH:mm:ss')
|
||||||
|
}
|
||||||
|
if (allValues['invoice-time-picker'] !== null && allValues['invoice-time-picker'] !== undefined) {
|
||||||
|
invoiceSearchOption.invoiceDateStart = allValues['invoice-time-picker'][0].format('YYYY-MM-DD')
|
||||||
|
invoiceSearchOption.invoiceDateEnd = allValues['invoice-time-picker'][1].format('YYYY-MM-DD')
|
||||||
|
}
|
||||||
|
if (allValues['invoice-state'] !== "全部") {
|
||||||
|
invoiceSearchOption.invoiceStates = [allValues['invoice-state']]
|
||||||
|
}
|
||||||
|
if (allValues['invoice-kind'] !== "全部") {
|
||||||
|
invoiceSearchOption.invoiceKinds = [allValues['invoice-kind']]
|
||||||
|
}
|
||||||
|
if (allValues['invoice-uploader'] !== null && allValues['invoice-uploader'] !== undefined && allValues['invoice-uploader'].trim() !== "") {
|
||||||
|
invoiceSearchOption.invoiceUploaderId = allValues['invoice-uploader'].trim()
|
||||||
|
}
|
||||||
|
props.handleSearchData(invoiceSearchOption)
|
||||||
|
}
|
||||||
|
|
||||||
|
const onSearch = (value: string) => {
|
||||||
|
if (!complexEnabled)
|
||||||
|
invoiceSearchOption.clear()
|
||||||
|
console.log(invoiceSearchOption)
|
||||||
|
if (activatedOption === "发票代码") {
|
||||||
|
invoiceSearchOption.invoiceCode = value;
|
||||||
|
invoiceSearchOption.invoiceNo = null;
|
||||||
|
} else {
|
||||||
|
invoiceSearchOption.invoiceNo = value;
|
||||||
|
invoiceSearchOption.invoiceCode = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
props.handleSearchData(invoiceSearchOption)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const getInvoiceKindsRadioButtons: any = () => {
|
||||||
|
let options: any[] = []
|
||||||
|
invoiceTypeNameMap.forEach(function (value, key, map) {
|
||||||
|
options.push(<Radio.Button style={{marginBottom: 10}} value={key}>{value}</Radio.Button>)
|
||||||
|
})
|
||||||
|
return options
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>发票管理</div>
|
<div className="headBar">
|
||||||
|
<div className="simpleSearchBar" style={{
|
||||||
|
height: '72px',
|
||||||
|
padding: '30px',
|
||||||
|
display: "flex",
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: "space-between",
|
||||||
|
backgroundColor: colorBgContainer
|
||||||
|
}}>
|
||||||
|
<Search className="simpleSearch"
|
||||||
|
addonBefore={<Dropdown
|
||||||
|
menu={{
|
||||||
|
items,
|
||||||
|
selectable: true,
|
||||||
|
defaultSelectedKeys: ['1'],
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Typography.Link>
|
||||||
|
<Space>
|
||||||
|
{activatedOption}
|
||||||
|
<DownOutlined/>
|
||||||
|
</Space>
|
||||||
|
</Typography.Link>
|
||||||
|
</Dropdown>}
|
||||||
|
placeholder={'请在此输入'}
|
||||||
|
allowClear
|
||||||
|
onSearch={(value) => onSearch(value)}
|
||||||
|
style={{width: 404}}
|
||||||
|
enterButton
|
||||||
|
/>
|
||||||
|
<Checkbox onChange={(e) => {
|
||||||
|
setComplexEnabled(e.target.checked)
|
||||||
|
}}>高级搜索</Checkbox>
|
||||||
|
</div>
|
||||||
|
{complexEnabled &&
|
||||||
|
<div className="complexSearchBar" style={{
|
||||||
|
margin: '20px',
|
||||||
|
padding: '20px 20px 0px 20px',
|
||||||
|
display: "flex",
|
||||||
|
backgroundColor: colorBgContainer,
|
||||||
|
borderRadius: '20px'
|
||||||
|
}}>
|
||||||
|
<Form name="complexOption" onValuesChange={onValuesChange} style={{width: '100%'}}>
|
||||||
|
|
||||||
|
<Form.Item
|
||||||
|
name={`invoice-kind`}
|
||||||
|
label={`发票类型`}
|
||||||
|
>
|
||||||
|
<Radio.Group defaultValue="全部">
|
||||||
|
<Radio.Button value="全部">全部</Radio.Button>
|
||||||
|
{getInvoiceKindsRadioButtons()}
|
||||||
|
</Radio.Group>
|
||||||
|
</Form.Item>
|
||||||
|
|
||||||
|
<div style={{marginTop: -10, display: "flex", flexDirection: "row", flexWrap: "wrap"}}>
|
||||||
|
<Form.Item name="upload-time-picker" label="上传时间" {...rangeConfig}
|
||||||
|
style={{marginRight: 100}}>
|
||||||
|
<RangePicker/>
|
||||||
|
</Form.Item>
|
||||||
|
|
||||||
|
<Form.Item name="invoice-time-picker" label="开票日期" {...rangeConfig}>
|
||||||
|
<RangePicker/>
|
||||||
|
</Form.Item>
|
||||||
|
</div>
|
||||||
|
<Form.Item
|
||||||
|
name={`invoice-state`}
|
||||||
|
label={`发票状态`}
|
||||||
|
>
|
||||||
|
<Radio.Group defaultValue="全部">
|
||||||
|
<Radio.Button value="全部">全部</Radio.Button>
|
||||||
|
<Radio.Button value="0">未使用</Radio.Button>
|
||||||
|
<Radio.Button value="1">报销中</Radio.Button>
|
||||||
|
<Radio.Button value="2">已报销</Radio.Button>
|
||||||
|
</Radio.Group>
|
||||||
|
</Form.Item>
|
||||||
|
|
||||||
|
</Form>
|
||||||
|
</div>}
|
||||||
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function InvoiceItem(props: { invoice: Invoice, onClick(invoice: Invoice): void }) {
|
||||||
|
const {
|
||||||
|
token: {colorBgContainer, colorPrimary, colorSuccess, colorWarning},
|
||||||
|
} = theme.useToken();
|
||||||
|
|
||||||
|
const onClick = () => {
|
||||||
|
props.onClick(props.invoice)
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<div style={{
|
||||||
|
margin: 30
|
||||||
|
}}>
|
||||||
|
<Badge.Ribbon color={['#00000000', colorPrimary, colorSuccess][props.invoice.invoiceState]} text={['', '报销中', '已报销'][props.invoice.invoiceState]}>
|
||||||
|
<Card
|
||||||
|
onClick={onClick}
|
||||||
|
hoverable
|
||||||
|
style={{
|
||||||
|
width: 250,
|
||||||
|
height: 300,
|
||||||
|
}}
|
||||||
|
cover={
|
||||||
|
<img alt="thumbnail"
|
||||||
|
src={baseUrl + props.invoice.invoiceThumbnailUri}
|
||||||
|
width="220" height="180"/>
|
||||||
|
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<div style={{marginTop: -20}}>
|
||||||
|
<div style={{height: 32,display: "flex", flexDirection: "row", justifyContent: "space-between", alignItems: 'center'}}>
|
||||||
|
<Text style={{
|
||||||
|
fontWeight: "bold",
|
||||||
|
fontSize: 20
|
||||||
|
}}>¥{(props.invoice.invoiceAmount / 100.0).toFixed(2)}</Text>
|
||||||
|
<Text style={{
|
||||||
|
fontWeight: "bold",
|
||||||
|
fontSize: 16
|
||||||
|
}}>{props.invoice.invoiceUploader.staffName }</Text>
|
||||||
|
</div>
|
||||||
|
<div style={{height: 22,display: "flex", flexDirection: "row", justifyContent: "space-between", alignItems: 'center'}}>
|
||||||
|
<Text>{invoiceTypeNameMap.get(props.invoice.invoiceKind)}</Text>
|
||||||
|
<Text>{props.invoice.invoiceUploader.staffId }</Text>
|
||||||
|
</div>
|
||||||
|
<li>{props.invoice.invoiceNo}</li>
|
||||||
|
<li>{props.invoice.invoiceDate}</li>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
</Badge.Ribbon>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function InvoiceManagement(props: {}) {
|
||||||
|
const [totalNum, setTotalNum] = useState(0)
|
||||||
|
const [invoices, setInvoices] = useState([] as any[])
|
||||||
|
const [search, setSearch] = useSearchParams()
|
||||||
|
const [invoiceSearchOption, setInvoiceSearchOption] = useState(new InvoiceSearchOption())
|
||||||
|
const [detailModalOpen, setDetailModalOpen] = useState(false)
|
||||||
|
const [invoiceDetail, setInvoiceDetail] = useState(null as InvoiceDetail | null)
|
||||||
|
const navigate = useNavigate()
|
||||||
|
|
||||||
|
const handleInvoiceSearchInfo = (invoiceSearch: InvoiceSearchOption) => {
|
||||||
|
//setInvoiceSearchOption(invoiceSearch)
|
||||||
|
searchInvoiceContent(invoiceSearch)
|
||||||
|
}
|
||||||
|
const searchInvoiceContent = (invoiceSearch: InvoiceSearchOption) => {
|
||||||
|
setInvoices([])
|
||||||
|
let params: any = invoiceSearch
|
||||||
|
Object.keys(params).forEach(key => {
|
||||||
|
if (params[key] != null && params[key] !== undefined && params[key] === "") {
|
||||||
|
params[key] = null
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (search.get('currentPage'))
|
||||||
|
params.pageNum = Number(search.get('currentPage')) - 1
|
||||||
|
else
|
||||||
|
params.pageNum = 0
|
||||||
|
if (search.get('pageSize'))
|
||||||
|
params.pageSize = Number(search.get('pageSize'))
|
||||||
|
else
|
||||||
|
params.pageSize = 10
|
||||||
|
axiosInstance({
|
||||||
|
url: 'common/invoice?' + qs.stringify(params, {skipNulls: true, arrayFormat: 'indices'}),
|
||||||
|
method: 'get',
|
||||||
|
}).then(response => {
|
||||||
|
console.log(response.data)
|
||||||
|
setTotalNum(response.data.total)
|
||||||
|
setInvoices([...response.data.records])
|
||||||
|
}).catch(function (error) {
|
||||||
|
console.log(error)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const onChange = (pageCurrentNum: Number, pageCurrentSize: Number) => {
|
||||||
|
console.log(pageCurrentNum, pageCurrentSize)
|
||||||
|
navigate('/invoice/management?currentPage=' + pageCurrentNum + '&pageSize=' + pageCurrentSize)
|
||||||
|
}
|
||||||
|
|
||||||
|
const onItemClick = (invoice: Invoice) => {
|
||||||
|
console.log(invoice)
|
||||||
|
axiosInstance({
|
||||||
|
url: 'common/invoice/' + invoice.invoiceId,
|
||||||
|
method: 'get',
|
||||||
|
}).then(response => {
|
||||||
|
console.log(response.data)
|
||||||
|
let detail: InvoiceDetail = response.data
|
||||||
|
detail.invoiceAmount /= 100.
|
||||||
|
setInvoiceDetail(detail)
|
||||||
|
setDetailModalOpen(true)
|
||||||
|
}).catch(function (error) {
|
||||||
|
console.log(error)
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
console.log(search.get('currentPage'))
|
||||||
|
console.log(search.get('pageSize'))
|
||||||
|
searchInvoiceContent(invoiceSearchOption)
|
||||||
|
}, [search]);
|
||||||
|
|
||||||
|
console.log(invoices)
|
||||||
|
return (
|
||||||
|
<div style={{}}>
|
||||||
|
<InvoiceSearch handleSearchData={handleInvoiceSearchInfo}/>
|
||||||
|
<div style={{padding: 26, display: "flex", flexDirection: "column", alignItems: "flex-end"}}>
|
||||||
|
<div style={{display: "flex", flexWrap: "wrap", justifyContent: 'center', width: '100%'}}>
|
||||||
|
{invoices.map((item: Invoice, index: number) =>
|
||||||
|
<InvoiceItem onClick={onItemClick} invoice={item} key={index}/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<Pagination showSizeChanger
|
||||||
|
showQuickJumper
|
||||||
|
showTotal={(total) => `共 ${total} 项`}
|
||||||
|
current={Number(search.get('currentPage') ? search.get('currentPage') : 1)}
|
||||||
|
pageSize={Number(search.get('pageSize') ? search.get('pageSize') : 10)}
|
||||||
|
total={totalNum} onChange={onChange}/>
|
||||||
|
</div>
|
||||||
|
<InvoiceDetailModal needRefresh={()=>{ searchInvoiceContent(invoiceSearchOption)}} invoiceDetail={invoiceDetail} open={detailModalOpen} onClose={() => {
|
||||||
|
setDetailModalOpen(false)
|
||||||
|
}} showFooter={true}/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
export default InvoiceManagement
|
export default InvoiceManagement
|
|
@ -13,12 +13,20 @@ import {
|
||||||
TimePicker,
|
TimePicker,
|
||||||
Select,
|
Select,
|
||||||
Checkbox,
|
Checkbox,
|
||||||
Pagination, theme
|
Pagination, theme, Tag, Badge
|
||||||
} from "antd";
|
} from "antd";
|
||||||
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, useEffect} from "react";
|
import React, {
|
||||||
import {InvoiceCommit, InvoiceSearchOption} from "../../../models/Staff"
|
ReactElement,
|
||||||
|
JSXElementConstructor,
|
||||||
|
ReactFragment,
|
||||||
|
ReactPortal,
|
||||||
|
useState,
|
||||||
|
useEffect,
|
||||||
|
ReactNode
|
||||||
|
} from "react";
|
||||||
|
import {InvoiceDetail, InvoiceSearchOption} from "../../../models/Invoice"
|
||||||
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,7 +36,18 @@ import change = Simulate.change;
|
||||||
import {useNavigate, useSearchParams} from "react-router-dom";
|
import {useNavigate, useSearchParams} 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";
|
import {
|
||||||
|
Invoice,
|
||||||
|
invoiceItemsMap,
|
||||||
|
invoiceTypeExtraItemsMap,
|
||||||
|
invoiceTypeItemsMap,
|
||||||
|
invoiceTypeNameMap
|
||||||
|
} from "../../../models/Invoice";
|
||||||
|
import {RadioButtonProps} from "antd/es/radio/radioButton";
|
||||||
|
import qs from "qs";
|
||||||
|
import InvoiceDetailModal from "../InvoiceDetailModal";
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
import {store} from "../../../models/store";
|
||||||
|
|
||||||
|
|
||||||
const {Meta} = Card;
|
const {Meta} = Card;
|
||||||
|
@ -36,16 +55,7 @@ const {Search} = Input;
|
||||||
const {Option} = Select
|
const {Option} = Select
|
||||||
let invoices: Array<Invoice>
|
let invoices: Array<Invoice>
|
||||||
const {RangePicker} = DatePicker;
|
const {RangePicker} = DatePicker;
|
||||||
const formItemLayout = {
|
|
||||||
labelCol: {
|
|
||||||
xs: {span: 10},
|
|
||||||
sm: {span: 10},
|
|
||||||
},
|
|
||||||
wrapperCol: {
|
|
||||||
xs: {span: 14},
|
|
||||||
sm: {span: 14},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
const config = {
|
const config = {
|
||||||
rules: [{type: 'object' as const, required: false, message: 'Please select time!'}],
|
rules: [{type: 'object' as const, required: false, message: 'Please select time!'}],
|
||||||
};
|
};
|
||||||
|
@ -87,7 +97,7 @@ function InvoiceSearch(props: { handleSearchData: any; }) {
|
||||||
invoiceSearchOption.clear()
|
invoiceSearchOption.clear()
|
||||||
|
|
||||||
console.log(allValues)
|
console.log(allValues)
|
||||||
if (allValues['upload-time-picker'] != null && allValues['upload-time-picker'] !== undefined) {
|
if (allValues['upload-time-picker'] !== null && allValues['upload-time-picker'] !== undefined) {
|
||||||
invoiceSearchOption.invoiceUploadTimeStart = allValues['upload-time-picker'][0].format('YYYY-MM-DDtHH:mm:ss')
|
invoiceSearchOption.invoiceUploadTimeStart = allValues['upload-time-picker'][0].format('YYYY-MM-DDtHH:mm:ss')
|
||||||
invoiceSearchOption.invoiceUploadTimeEnd = allValues['upload-time-picker'][1].format('YYYY-MM-DDtHH:mm:ss')
|
invoiceSearchOption.invoiceUploadTimeEnd = allValues['upload-time-picker'][1].format('YYYY-MM-DDtHH:mm:ss')
|
||||||
}
|
}
|
||||||
|
@ -96,14 +106,15 @@ function InvoiceSearch(props: { handleSearchData: any; }) {
|
||||||
invoiceSearchOption.invoiceDateEnd = allValues['invoice-time-picker'][1].format('YYYY-MM-DD')
|
invoiceSearchOption.invoiceDateEnd = allValues['invoice-time-picker'][1].format('YYYY-MM-DD')
|
||||||
}
|
}
|
||||||
if (allValues['invoice-state'] !== "全部") {
|
if (allValues['invoice-state'] !== "全部") {
|
||||||
invoiceSearchOption.invoiceState = allValues['invoice-state']
|
invoiceSearchOption.invoiceStates = [allValues['invoice-state']]
|
||||||
}
|
}
|
||||||
if (allValues['invoice-kind'] !== "全部") {
|
if (allValues['invoice-kind'] !== "全部") {
|
||||||
invoiceSearchOption.invoiceKind = allValues['invoice-kind']
|
invoiceSearchOption.invoiceKinds = [allValues['invoice-kind']]
|
||||||
}
|
}
|
||||||
if (allValues['invoice-uploader'] !== null && allValues['invoice-uploader'] !== undefined && allValues['invoice-uploader'].trim() !== "") {
|
if (allValues['invoice-uploader'] !== null && allValues['invoice-uploader'] !== undefined && allValues['invoice-uploader'].trim() !== "") {
|
||||||
invoiceSearchOption.invoiceUploader = allValues['invoice-uploader'].trim()
|
invoiceSearchOption.invoiceUploaderId = allValues['invoice-uploader'].trim()
|
||||||
}
|
}
|
||||||
|
props.handleSearchData(invoiceSearchOption)
|
||||||
}
|
}
|
||||||
|
|
||||||
const onSearch = (value: string) => {
|
const onSearch = (value: string) => {
|
||||||
|
@ -118,14 +129,28 @@ function InvoiceSearch(props: { handleSearchData: any; }) {
|
||||||
invoiceSearchOption.invoiceCode = null;
|
invoiceSearchOption.invoiceCode = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const {handleSearchData} = props
|
props.handleSearchData(invoiceSearchOption)
|
||||||
handleSearchData(invoiceSearchOption)
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getInvoiceKindsRadioButtons: any = () => {
|
||||||
|
let options: any[] = []
|
||||||
|
invoiceTypeNameMap.forEach(function (value, key, map) {
|
||||||
|
options.push(<Radio.Button style={{marginBottom: 10}} value={key}>{value}</Radio.Button>)
|
||||||
|
})
|
||||||
|
return options
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="headBar">
|
<div className="headBar">
|
||||||
<div className="simpleSearchBar" style={{height: '72px', padding: '30px',display: "flex",alignItems: 'center', justifyContent: "space-between",backgroundColor: colorBgContainer}}>
|
<div className="simpleSearchBar" style={{
|
||||||
|
height: '72px',
|
||||||
|
padding: '30px',
|
||||||
|
display: "flex",
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: "space-between",
|
||||||
|
backgroundColor: colorBgContainer
|
||||||
|
}}>
|
||||||
<Search className="simpleSearch"
|
<Search className="simpleSearch"
|
||||||
addonBefore={<Dropdown
|
addonBefore={<Dropdown
|
||||||
menu={{
|
menu={{
|
||||||
|
@ -144,117 +169,124 @@ function InvoiceSearch(props: { handleSearchData: any; }) {
|
||||||
placeholder={'请在此输入'}
|
placeholder={'请在此输入'}
|
||||||
allowClear
|
allowClear
|
||||||
onSearch={(value) => onSearch(value)}
|
onSearch={(value) => onSearch(value)}
|
||||||
style={{width: 304}}
|
style={{width: 404}}
|
||||||
enterButton
|
enterButton
|
||||||
/>
|
/>
|
||||||
<Checkbox onChange={(e) => {
|
<Checkbox onChange={(e) => {
|
||||||
setComplexEnabled(e.target.checked)
|
setComplexEnabled(e.target.checked)
|
||||||
}}>高级搜索</Checkbox>
|
}}>高级搜索</Checkbox>
|
||||||
<InvoiceUploadView/>
|
<InvoiceUploadView needRefresh={()=>{props.handleSearchData(invoiceSearchOption)}} />
|
||||||
</div>
|
</div>
|
||||||
{complexEnabled &&
|
{complexEnabled &&
|
||||||
<div className="complexSearchBar" style={{display: "flex"}}>
|
<div className="complexSearchBar" style={{
|
||||||
<Form name="complexOption" {...formItemLayout} onValuesChange={onValuesChange}>
|
margin: '20px',
|
||||||
<Row>
|
padding: '20px 20px 0px 20px',
|
||||||
<Form.Item name="upload-time-picker" label="发票上传时间" {...rangeConfig}>
|
display: "flex",
|
||||||
<RangePicker/>
|
backgroundColor: colorBgContainer,
|
||||||
</Form.Item>
|
borderRadius: '20px'
|
||||||
|
}}>
|
||||||
|
<Form name="complexOption" onValuesChange={onValuesChange} style={{width: '100%'}}>
|
||||||
|
|
||||||
<Form.Item name="invoice-time-picker" label="发票开票日期" {...rangeConfig}>
|
|
||||||
<RangePicker/>
|
|
||||||
</Form.Item>
|
|
||||||
</Row>
|
|
||||||
<Row style={{display: "flex", flexWrap: "wrap"}}>
|
|
||||||
<Form.Item
|
|
||||||
name={`invoice-state`}
|
|
||||||
label={`发票状态`}
|
|
||||||
style={{minWidth: 150}}
|
|
||||||
><Select defaultValue="全部">
|
|
||||||
<Option value="全部">全部</Option>
|
|
||||||
<Option value="0">未使用</Option>
|
|
||||||
<Option value="1">报销中</Option>
|
|
||||||
<Option value="2">已报销</Option>
|
|
||||||
</Select>
|
|
||||||
</Form.Item>
|
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name={`invoice-kind`}
|
name={`invoice-kind`}
|
||||||
label={`发票类型`}
|
label={`发票类型`}
|
||||||
style={{minWidth: 300}}
|
|
||||||
><Select defaultValue="全部">
|
|
||||||
<Option value="全部">全部</Option>
|
|
||||||
<Option value="增值税普通发票">增值税普通发票</Option>
|
|
||||||
<Option value="增值税专用发票">增值税专用发票</Option>
|
|
||||||
<Option value="增值税电子普通发票">增值税电子普通发票</Option>
|
|
||||||
<Option value="增值税电子专用发票">增值税电子专用发票</Option>
|
|
||||||
<Option value="定额发票">定额发票</Option>
|
|
||||||
</Select>
|
|
||||||
</Form.Item>
|
|
||||||
<Form.Item
|
|
||||||
name={`invoice-uploader`}
|
|
||||||
label={`上传者`}
|
|
||||||
>
|
>
|
||||||
<Input placeholder="任意上传者"/>
|
<Radio.Group defaultValue="全部">
|
||||||
|
<Radio.Button value="全部">全部</Radio.Button>
|
||||||
|
{getInvoiceKindsRadioButtons()}
|
||||||
|
</Radio.Group>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Row>
|
|
||||||
|
<div style={{marginTop: -10, display: "flex", flexDirection: "row", flexWrap: "wrap"}}>
|
||||||
|
<Form.Item name="upload-time-picker" label="上传时间" {...rangeConfig}
|
||||||
|
style={{marginRight: 100}}>
|
||||||
|
<RangePicker/>
|
||||||
|
</Form.Item>
|
||||||
|
|
||||||
|
<Form.Item name="invoice-time-picker" label="开票日期" {...rangeConfig}>
|
||||||
|
<RangePicker/>
|
||||||
|
</Form.Item>
|
||||||
|
</div>
|
||||||
|
<Form.Item
|
||||||
|
name={`invoice-state`}
|
||||||
|
label={`发票状态`}
|
||||||
|
>
|
||||||
|
<Radio.Group defaultValue="全部">
|
||||||
|
<Radio.Button value="全部">全部</Radio.Button>
|
||||||
|
<Radio.Button value="0">未使用</Radio.Button>
|
||||||
|
<Radio.Button value="1">报销中</Radio.Button>
|
||||||
|
<Radio.Button value="2">已报销</Radio.Button>
|
||||||
|
</Radio.Group>
|
||||||
|
</Form.Item>
|
||||||
|
|
||||||
</Form>
|
</Form>
|
||||||
</div>}
|
</div>}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
class InvoiceItem extends React.Component<any, any> {
|
function InvoiceItem(props: { invoice: Invoice, onClick(invoice: Invoice): void }) {
|
||||||
constructor(props: { invoice: Invoice }) {
|
const {
|
||||||
super(props);
|
token: {colorBgContainer, colorPrimary, colorSuccess, colorWarning},
|
||||||
this.state = {
|
} = theme.useToken();
|
||||||
invoiceThumbnailUri: baseUrl + props.invoice.invoiceThumbnailUri,
|
|
||||||
invoiceKind: props.invoice.invoiceKind,
|
|
||||||
invoiceAmount: props.invoice.invoiceAmount,
|
|
||||||
invoiceDate: props.invoice.invoiceDate,
|
|
||||||
invoiceNo: props.invoice.invoiceNo,
|
|
||||||
}
|
|
||||||
console.log(this.state.invoiceThumbnailUri)
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
const onClick = () => {
|
||||||
|
props.onClick(props.invoice)
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
|
<div style={{
|
||||||
|
margin: 30
|
||||||
|
}}>
|
||||||
|
<Badge.Ribbon color={['#00000000', colorPrimary, colorSuccess][props.invoice.invoiceState]} text={['', '报销中', '已报销'][props.invoice.invoiceState]}>
|
||||||
<Card
|
<Card
|
||||||
|
onClick={onClick}
|
||||||
hoverable
|
hoverable
|
||||||
style={{
|
style={{
|
||||||
width: 250,
|
width: 250,
|
||||||
height: 300,
|
height: 300,
|
||||||
margin: 30
|
|
||||||
}}
|
}}
|
||||||
cover={<img alt="thumbnail"
|
cover={
|
||||||
src={this.state.invoiceThumbnailUri}
|
<img alt="thumbnail"
|
||||||
width="220" height="180"/>}
|
src={baseUrl + props.invoice.invoiceThumbnailUri}
|
||||||
|
width="220" height="180"/>
|
||||||
|
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<div style={{marginTop: -20}}>
|
<div style={{marginTop: -20}}>
|
||||||
<li style={{fontWeight: "bold", fontSize: 20}}>¥{(this.state.invoiceAmount / 100.0).toFixed(2)}</li>
|
<li style={{
|
||||||
<li>{invoiceTypeNameMap.get(this.state.invoiceKind)}</li>
|
fontWeight: "bold",
|
||||||
<li>{this.state.invoiceNo}</li>
|
fontSize: 20
|
||||||
<li>{this.state.invoiceDate}</li>
|
}}>¥{(props.invoice.invoiceAmount / 100.0).toFixed(2)}</li>
|
||||||
|
<li>{invoiceTypeNameMap.get(props.invoice.invoiceKind)}</li>
|
||||||
|
<li>{props.invoice.invoiceNo}</li>
|
||||||
|
<li>{props.invoice.invoiceDate}</li>
|
||||||
</div>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
|
</Badge.Ribbon>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
)
|
)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function InvoiceListView(props: {}) {
|
function InvoiceListView(props: {}) {
|
||||||
const [totalNum, setTotalNum] = useState(0)
|
const [totalNum, setTotalNum] = useState(0)
|
||||||
const [invoices, setInvoices] = useState([])
|
const [invoices, setInvoices] = useState([] as any[])
|
||||||
const [search, setSearch] = useSearchParams()
|
const [search, setSearch] = useSearchParams()
|
||||||
|
|
||||||
const [invoiceSearchOption, setInvoiceSearchOption] = useState(new InvoiceSearchOption())
|
const [invoiceSearchOption, setInvoiceSearchOption] = useState(new InvoiceSearchOption())
|
||||||
|
const [detailModalOpen, setDetailModalOpen] = useState(false)
|
||||||
|
const [invoiceDetail, setInvoiceDetail] = useState(null as InvoiceDetail | null)
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
|
|
||||||
const handleInvoiceSearchInfo = (invoiceSearch: InvoiceSearchOption) => {
|
const handleInvoiceSearchInfo = (invoiceSearch: InvoiceSearchOption) => {
|
||||||
setInvoiceSearchOption(invoiceSearch)
|
setInvoiceSearchOption(invoiceSearch)
|
||||||
searchInvoiceContent()
|
searchInvoiceContent(invoiceSearch)
|
||||||
}
|
}
|
||||||
const searchInvoiceContent = () => {
|
const searchInvoiceContent = (invoiceSearch: InvoiceSearchOption) => {
|
||||||
let params: any = invoiceSearchOption
|
setInvoices([])
|
||||||
|
let params: any = invoiceSearch
|
||||||
Object.keys(params).forEach(key => {
|
Object.keys(params).forEach(key => {
|
||||||
if (params[key] != null && params[key] !== undefined && params[key] === "") {
|
if (params[key] != null && params[key] !== undefined && params[key] === "") {
|
||||||
params[key] = null
|
params[key] = null
|
||||||
|
@ -268,14 +300,16 @@ function InvoiceListView(props: {}) {
|
||||||
params.pageSize = Number(search.get('pageSize'))
|
params.pageSize = Number(search.get('pageSize'))
|
||||||
else
|
else
|
||||||
params.pageSize = 10
|
params.pageSize = 10
|
||||||
|
|
||||||
|
params.invoiceUploaderId = store.getState().token.staffId
|
||||||
|
|
||||||
axiosInstance({
|
axiosInstance({
|
||||||
url: 'common/invoice',
|
url: 'common/invoice?' + qs.stringify(params, {skipNulls: true, arrayFormat: 'indices'}),
|
||||||
method: 'get',
|
method: 'get',
|
||||||
params: params
|
|
||||||
}).then(response => {
|
}).then(response => {
|
||||||
console.log(response.data)
|
console.log(response.data)
|
||||||
setTotalNum(response.data.total)
|
setTotalNum(response.data.total)
|
||||||
setInvoices(response.data.records)
|
setInvoices([...response.data.records])
|
||||||
}).catch(function (error) {
|
}).catch(function (error) {
|
||||||
console.log(error)
|
console.log(error)
|
||||||
})
|
})
|
||||||
|
@ -285,19 +319,37 @@ function InvoiceListView(props: {}) {
|
||||||
navigate('/invoice/mine?currentPage=' + pageCurrentNum + '&pageSize=' + pageCurrentSize)
|
navigate('/invoice/mine?currentPage=' + pageCurrentNum + '&pageSize=' + pageCurrentSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const onItemClick = (invoice: Invoice) => {
|
||||||
|
console.log(invoice)
|
||||||
|
axiosInstance({
|
||||||
|
url: 'common/invoice/' + invoice.invoiceId,
|
||||||
|
method: 'get',
|
||||||
|
}).then(response => {
|
||||||
|
console.log(response.data)
|
||||||
|
let detail: InvoiceDetail = response.data
|
||||||
|
detail.invoiceAmount /= 100.
|
||||||
|
setInvoiceDetail(detail)
|
||||||
|
setDetailModalOpen(true)
|
||||||
|
}).catch(function (error) {
|
||||||
|
console.log(error)
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
console.log(search.get('currentPage'))
|
console.log(search.get('currentPage'))
|
||||||
console.log(search.get('pageSize'))
|
console.log(search.get('pageSize'))
|
||||||
searchInvoiceContent()
|
searchInvoiceContent(invoiceSearchOption)
|
||||||
}, [search]);
|
}, [search]);
|
||||||
|
|
||||||
|
console.log(invoices)
|
||||||
return (
|
return (
|
||||||
<div style={{}}>
|
<div style={{}}>
|
||||||
<InvoiceSearch handleSearchData={handleInvoiceSearchInfo}/>
|
<InvoiceSearch handleSearchData={handleInvoiceSearchInfo}/>
|
||||||
<div style={{padding: 26, display: "flex", flexDirection: "column", alignItems: "flex-end"}}>
|
<div style={{padding: 26, display: "flex", flexDirection: "column", alignItems: "flex-end"}}>
|
||||||
<div style={{display: "flex", flexWrap: "wrap", justifyContent: 'center', width: '100%'}}>
|
<div style={{display: "flex", flexWrap: "wrap", justifyContent: 'center', width: '100%'}}>
|
||||||
{invoices.map((item: Invoice, index: number) =>
|
{invoices.map((item: Invoice, index: number) =>
|
||||||
<InvoiceItem invoice={item} key={index}/>
|
<InvoiceItem onClick={onItemClick} invoice={item} key={index}/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<Pagination showSizeChanger
|
<Pagination showSizeChanger
|
||||||
|
@ -307,9 +359,12 @@ function InvoiceListView(props: {}) {
|
||||||
pageSize={Number(search.get('pageSize') ? search.get('pageSize') : 10)}
|
pageSize={Number(search.get('pageSize') ? search.get('pageSize') : 10)}
|
||||||
total={totalNum} onChange={onChange}/>
|
total={totalNum} onChange={onChange}/>
|
||||||
</div>
|
</div>
|
||||||
|
<InvoiceDetailModal needRefresh={()=>{searchInvoiceContent(invoiceSearchOption)}} invoiceDetail={invoiceDetail} open={detailModalOpen} onClose={() => {
|
||||||
|
setDetailModalOpen(false)
|
||||||
|
}}/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default InvoiceListView
|
export default InvoiceListView
|
|
@ -2,7 +2,6 @@ import React, {useEffect, useRef, useState} from 'react';
|
||||||
import {Button, Modal, UploadProps, message, Upload, UploadFile, Form, Input, DatePicker, Select, InputNumber} 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} from "../../../models/Staff";
|
|
||||||
import dayjs, {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";
|
||||||
|
@ -50,11 +49,7 @@ class FileUploadView extends React.Component<any, any> {
|
||||||
|
|
||||||
|
|
||||||
function UpLoadModal(props: any) {
|
function UpLoadModal(props: any) {
|
||||||
const [open, setOpen] = useState(false)
|
|
||||||
const [loading, setLoading] = useState(false)
|
const [loading, setLoading] = useState(false)
|
||||||
useEffect(() => {
|
|
||||||
setOpen(props.open)
|
|
||||||
}, [props]);
|
|
||||||
const handleOk = () => {
|
const handleOk = () => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
let data = new FormData();
|
let data = new FormData();
|
||||||
|
@ -66,7 +61,7 @@ function UpLoadModal(props: any) {
|
||||||
}).then(response => {
|
}).then(response => {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
console.log(response.data)
|
console.log(response.data)
|
||||||
setOpen(false);
|
props.onClose()
|
||||||
props.nextStep(response.data)
|
props.nextStep(response.data)
|
||||||
}).catch(function (error) {
|
}).catch(function (error) {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
|
@ -75,12 +70,12 @@ function UpLoadModal(props: any) {
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCancel = () => {
|
const handleCancel = () => {
|
||||||
setOpen(false);
|
props.onClose()
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
open={open}
|
open={props.open}
|
||||||
title="上传发票"
|
title="上传发票"
|
||||||
onOk={handleOk}
|
onOk={handleOk}
|
||||||
onCancel={handleCancel}
|
onCancel={handleCancel}
|
||||||
|
@ -110,7 +105,7 @@ function FormModal(props: any) {
|
||||||
let i = {...props.invoiceIdentifyResponse}
|
let i = {...props.invoiceIdentifyResponse}
|
||||||
setInvoice(i)
|
setInvoice(i)
|
||||||
refreshFormItems(props.invoiceIdentifyResponse?.invoiceKind)
|
refreshFormItems(props.invoiceIdentifyResponse?.invoiceKind)
|
||||||
//TODO: 重置表单
|
form.resetFields()
|
||||||
form.setFieldsValue(i)
|
form.setFieldsValue(i)
|
||||||
|
|
||||||
}, [props]);
|
}, [props]);
|
||||||
|
@ -137,6 +132,7 @@ function FormModal(props: any) {
|
||||||
console.log(response.data)
|
console.log(response.data)
|
||||||
setLoading(false)
|
setLoading(false)
|
||||||
props.onClose()
|
props.onClose()
|
||||||
|
props.needRefresh()
|
||||||
//setOpen(false)
|
//setOpen(false)
|
||||||
}).catch(function (error) {
|
}).catch(function (error) {
|
||||||
console.log(error)
|
console.log(error)
|
||||||
|
@ -245,7 +241,7 @@ function FormModal(props: any) {
|
||||||
|
|
||||||
class InvoiceUploadView extends React.Component<any, any> {
|
class InvoiceUploadView extends React.Component<any, any> {
|
||||||
|
|
||||||
constructor(props: {}) {
|
constructor(props: any) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
uploadModalOpen: false,
|
uploadModalOpen: false,
|
||||||
|
@ -266,7 +262,11 @@ class InvoiceUploadView extends React.Component<any, any> {
|
||||||
handleNextStep = (response: InvoiceIdentifyResponse) => {
|
handleNextStep = (response: InvoiceIdentifyResponse) => {
|
||||||
response.invoiceDate = dayjs(response.invoiceDate)
|
response.invoiceDate = dayjs(response.invoiceDate)
|
||||||
response.invoiceAmount /= 100.
|
response.invoiceAmount /= 100.
|
||||||
this.setState({uploadModalOpen: false, formModalOpen: true, invoiceIdentifyResponse: response})
|
this.setState({formModalOpen: true, invoiceIdentifyResponse: response})
|
||||||
|
}
|
||||||
|
|
||||||
|
handleUploadModalClose = () => {
|
||||||
|
this.setState({uploadModalOpen:false})
|
||||||
}
|
}
|
||||||
|
|
||||||
handleClose = () => {
|
handleClose = () => {
|
||||||
|
@ -281,8 +281,8 @@ class InvoiceUploadView extends React.Component<any, any> {
|
||||||
<Button onClick={this.showUploadView} className="uploadButton" type="primary" icon={<UploadOutlined/>}>
|
<Button onClick={this.showUploadView} className="uploadButton" type="primary" icon={<UploadOutlined/>}>
|
||||||
上传
|
上传
|
||||||
</Button>
|
</Button>
|
||||||
<UpLoadModal open={this.state.uploadModalOpen} nextStep={this.handleNextStep}/>
|
<UpLoadModal open={this.state.uploadModalOpen} nextStep={this.handleNextStep} onClose={this.handleUploadModalClose}/>
|
||||||
<FormModal open={this.state.formModalOpen} onClose={this.handleClose}
|
<FormModal needRefresh={()=>{ this.props.needRefresh()}} open={this.state.formModalOpen} onClose={this.handleClose}
|
||||||
invoiceIdentifyResponse={this.state.invoiceIdentifyResponse}/>
|
invoiceIdentifyResponse={this.state.invoiceIdentifyResponse}/>
|
||||||
</>);
|
</>);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue