Merge remote-tracking branch 'origin/main'

main
白封羽 2023-01-02 23:33:37 +08:00
commit c95fb9ab79
8 changed files with 777 additions and 261 deletions

View File

@ -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']],
])
/* /*
{ {

View File

@ -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;
}

View File

@ -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,

View File

@ -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/>

View File

@ -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

View File

@ -1,6 +1,374 @@
function InvoiceManagement() { import {
return( Card,
<div></div> 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 (
<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

View File

@ -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,31 +319,52 @@ 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
showQuickJumper showQuickJumper
showTotal={(total) => `${total}`} showTotal={(total) => `${total}`}
current={Number(search.get('currentPage')?search.get('currentPage'):1)} current={Number(search.get('currentPage') ? search.get('currentPage') : 1)}
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

View File

@ -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}/>
</>); </>);