拆分了组件
parent
d14b265066
commit
6ce784fdcc
|
@ -2,18 +2,12 @@ import React, {Key, ReactNode} from "react";
|
||||||
import {ReimbursementApplication} from "../../../models/Reimbursement";
|
import {ReimbursementApplication} from "../../../models/Reimbursement";
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
Card,
|
|
||||||
Col,
|
Col,
|
||||||
Form,
|
Form,
|
||||||
Input,
|
Input,
|
||||||
InputNumber,
|
InputNumber,
|
||||||
Modal,
|
Modal, notification,
|
||||||
Pagination,
|
Row
|
||||||
PaginationProps,
|
|
||||||
Popover,
|
|
||||||
Radio,
|
|
||||||
Row,
|
|
||||||
Select, Tag
|
|
||||||
} from "antd";
|
} from "antd";
|
||||||
import {FormInstance} from "antd/es/form";
|
import {FormInstance} from "antd/es/form";
|
||||||
import {Invoice} from "../../../models/Reimbursement";
|
import {Invoice} from "../../../models/Reimbursement";
|
||||||
|
@ -25,338 +19,26 @@ import {Dropdown, message, Space, Tooltip} from 'antd';
|
||||||
import {store} from "../../../models/store";
|
import {store} from "../../../models/store";
|
||||||
import {FieldData} from "rc-field-form/lib/interface";
|
import {FieldData} from "rc-field-form/lib/interface";
|
||||||
import {invoiceTypeNameMap} from "../../../models/Invoice";
|
import {invoiceTypeNameMap} from "../../../models/Invoice";
|
||||||
|
import SingleInvoiceSelector from "./component/SingleInvoiceSelector";
|
||||||
|
import MultiInvoiceSelector from "./component/MultiInvoiceSelector";
|
||||||
|
import {StatisticCard} from "@ant-design/pro-components";
|
||||||
|
|
||||||
function InvoiceCard(props: { invoice: Invoice }) {
|
const {Operation} = StatisticCard;
|
||||||
const invoice = props.invoice;
|
|
||||||
console.log(invoice);
|
|
||||||
return (
|
|
||||||
<Card
|
|
||||||
// hoverable
|
|
||||||
// style={{
|
|
||||||
// width: 250,
|
|
||||||
// height: 300,
|
|
||||||
// margin: 30
|
|
||||||
// }}
|
|
||||||
style={{background: "#f0f0f0"}}
|
|
||||||
cover={<img alt="thumbnail"
|
|
||||||
src={baseUrl + invoice.invoiceThumbnailUri}
|
|
||||||
width="220" height="180"/>}
|
|
||||||
>
|
|
||||||
<div style={{marginTop: -20}}>
|
|
||||||
<li style={{fontWeight: "bold", fontSize: 20}}>¥{(invoice.invoiceAmount / 100.0).toFixed(2)}</li>
|
|
||||||
<li>{invoiceTypeNameMap.get(invoice.invoiceKind)}</li>
|
|
||||||
{(invoice.invoiceDeparture !== null && invoice.invoiceDestination !== null &&
|
|
||||||
<li>{invoice.invoiceDeparture}{" → "}
|
|
||||||
{invoice.invoiceDestination}</li>)}
|
|
||||||
<li>{invoice.invoiceDate}</li>
|
|
||||||
</div>
|
|
||||||
</Card>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
class InvoiceRadioCard extends React.Component<any, any> {
|
|
||||||
|
|
||||||
constructor(props: {
|
|
||||||
invoice: any;
|
|
||||||
hidden: boolean;
|
|
||||||
selected: number;
|
|
||||||
index: number;
|
|
||||||
click: any;
|
|
||||||
}) {
|
|
||||||
super(props);
|
|
||||||
this.state = {
|
|
||||||
invoice: props.invoice,
|
|
||||||
hidden: props.hidden,
|
|
||||||
selected: props.selected,
|
|
||||||
index: props.index,
|
|
||||||
click: props.click,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static getDerivedStateFromProps(props: {
|
|
||||||
invoice: any;
|
|
||||||
hidden: boolean;
|
|
||||||
selected: number;
|
|
||||||
index: number;
|
|
||||||
}) {
|
|
||||||
return {
|
|
||||||
invoice: props.invoice,
|
|
||||||
hidden: props.hidden,
|
|
||||||
selected: props.selected,
|
|
||||||
index: props.index,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
select(e: any) {
|
|
||||||
if (this.state.selected !== 0)
|
|
||||||
return
|
|
||||||
this.setState({selected: 1})
|
|
||||||
this.props.click(this.props.invoice, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
getTag = () => {
|
|
||||||
if (this.state.selected === 1)
|
|
||||||
return <Popover content={"已选作报销凭证"}><Tag color="blue">已选择</Tag></Popover>
|
|
||||||
else if (this.state.selected === 0)
|
|
||||||
return <Popover content={"可用于报销"}><Tag color="green">待选择</Tag></Popover>
|
|
||||||
else if (this.state.selected === -1)
|
|
||||||
return <Popover content={"早于出发日期"}><Tag color="red">不可选</Tag></Popover>
|
|
||||||
else if (this.state.selected === -2)
|
|
||||||
return <Popover content={"晚于返程日期"}><Tag color="red">不可选</Tag></Popover>
|
|
||||||
else if (this.state.selected === -3)
|
|
||||||
return <Popover content={"已作其他用途"}><Tag color="red">不可选</Tag></Popover>
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<Card hidden={this.state.hidden}
|
|
||||||
hoverable={true}
|
|
||||||
style={{marginBottom: 30, background: (this.state.selected === 1 ? "lightskyblue" : "#f0f0f0"),
|
|
||||||
opacity: (this.state.selected >=0 ? 1 : 0.7)}}
|
|
||||||
onClick={(e) => {
|
|
||||||
this.select(e)
|
|
||||||
}}
|
|
||||||
cover={<img alt="thumbnail"
|
|
||||||
src={baseUrl + this.state.invoice.invoiceThumbnailUri}
|
|
||||||
width="300" height="120"/>}
|
|
||||||
// actions={[<Radio checked={this.state.selected} onClick={(e) => {
|
|
||||||
// this.select(e)
|
|
||||||
// }} defaultChecked={this.state.selected}/>]}
|
|
||||||
>
|
|
||||||
<div style={{marginTop: -20, height: 80}}>
|
|
||||||
|
|
||||||
<li style={{
|
|
||||||
fontWeight: "bold",
|
|
||||||
fontSize: 18
|
|
||||||
}}>¥{(this.state.invoice.invoiceAmount / 100.0).toFixed(2)}
|
|
||||||
{this.getTag()}
|
|
||||||
</li>
|
|
||||||
<li>{invoiceTypeNameMap.get(this.state.invoice.invoiceKind)}</li>
|
|
||||||
{(this.state.invoice.invoiceDeparture !== null && this.state.invoice.invoiceDestination !== null &&
|
|
||||||
<li>{this.state.invoice.invoiceDeparture}{" → "}
|
|
||||||
{this.state.invoice.invoiceDestination}</li>)}
|
|
||||||
<li>{this.state.invoice.invoiceDate}</li>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</Card>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class SingleInvoiceSelector extends React.Component<any, any> {
|
|
||||||
value: any
|
|
||||||
onChange: any
|
|
||||||
availableInvoiceKinds = [0, 2, 5, 9, 10, 13]
|
|
||||||
|
|
||||||
constructor(props: {
|
|
||||||
disabled: boolean;
|
|
||||||
pickerOpen: boolean;
|
|
||||||
pickerTitle: string;
|
|
||||||
value: any;
|
|
||||||
onChange: any;
|
|
||||||
after: number;
|
|
||||||
before: number;
|
|
||||||
occupiedInvoices: Invoice[];
|
|
||||||
}) {
|
|
||||||
super(props);
|
|
||||||
this.value = props.value
|
|
||||||
this.onChange = props.onChange
|
|
||||||
this.state = {
|
|
||||||
disabled: props.disabled,
|
|
||||||
occupiedInvoices: props.occupiedInvoices,
|
|
||||||
selectedInvoice: {},
|
|
||||||
singleLimit: true,
|
|
||||||
invoices: [],
|
|
||||||
pickerOpen: props.pickerOpen,
|
|
||||||
pickerTitle: props.pickerTitle,
|
|
||||||
currentPage: 1,
|
|
||||||
pageSize: 4,
|
|
||||||
total: 0,
|
|
||||||
after: props.after,
|
|
||||||
before: props.before,
|
|
||||||
searchOptions: {
|
|
||||||
invoiceNote: "",
|
|
||||||
invoiceDateStart: 0,
|
|
||||||
invoiceDateEnd: 0,
|
|
||||||
invoiceKind: -1,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.requestInvoices(1, this.state.searchOptions)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
requestInvoices(page: number, searchOptions: any) {
|
|
||||||
let params: any = {
|
|
||||||
pageNum: page - 1,
|
|
||||||
pageSize: this.state.pageSize,
|
|
||||||
invoiceUploaderId: store.getState().token.staffId,
|
|
||||||
invoiceStatus: 0,
|
|
||||||
sortBy: "invoiceDate",
|
|
||||||
asc: true,
|
|
||||||
}
|
|
||||||
if (searchOptions.invoiceNote !== "") {
|
|
||||||
params.invoiceNote = searchOptions.invoiceNote
|
|
||||||
}
|
|
||||||
if (searchOptions.invoiceDateStart !== 0) {
|
|
||||||
params.invoiceDateStart = searchOptions.invoiceDateStart
|
|
||||||
}
|
|
||||||
if (searchOptions.invoiceDateEnd !== 0) {
|
|
||||||
params.invoiceDateEnd = searchOptions.invoiceDateEnd
|
|
||||||
}
|
|
||||||
if (searchOptions.invoiceKind !== -1) {
|
|
||||||
params.invoiceKinds = searchOptions.invoiceKind
|
|
||||||
} else {
|
|
||||||
params.invoiceKinds = "0,2,5,9,10,13"
|
|
||||||
}
|
|
||||||
console.log(params)
|
|
||||||
axiosInstance.get('common/invoice', {params: params}).then(response => {
|
|
||||||
this.setState({
|
|
||||||
total: response.data.total, invoices: response.data.records,
|
|
||||||
currentPage: page, searchOptions: searchOptions
|
|
||||||
})
|
|
||||||
}).catch(error => {
|
|
||||||
console.log(error)
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
setSearchOptions = (options: any) => {
|
|
||||||
this.setState({searchOptions: options})
|
|
||||||
}
|
|
||||||
invoiceCard = () => {
|
|
||||||
if (this.state.selectedInvoice.invoiceId === null || this.state.selectedInvoice.invoiceId === undefined) {
|
|
||||||
return (<>请选择一张{this.state.pickerTitle}</>)
|
|
||||||
}
|
|
||||||
return (<InvoiceCard invoice={this.state.selectedInvoice}/>)
|
|
||||||
}
|
|
||||||
pickerOpen = (value: boolean) => {
|
|
||||||
if (this.state.disabled) {
|
|
||||||
alert("请先选择出发票据")
|
|
||||||
} else {
|
|
||||||
this.setState({pickerOpen: value})
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
confirm = () => {
|
|
||||||
this.setState({pickerOpen: false})
|
|
||||||
}
|
|
||||||
cancelSelect = () => {
|
|
||||||
this.onChange(undefined)
|
|
||||||
this.setState({selectedInvoice: {}})
|
|
||||||
}
|
|
||||||
|
|
||||||
click = (invoice: any, status: boolean) => {
|
|
||||||
if (status) {
|
|
||||||
this.setState({selectedInvoice: invoice})
|
|
||||||
this.onChange(invoice)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static getDerivedStateFromProps(nextProps: any, prevState: any) {
|
|
||||||
return {
|
|
||||||
after: nextProps.after,
|
|
||||||
before: nextProps.before,
|
|
||||||
occupiedInvoices: nextProps.occupiedInvoices,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
changePage: PaginationProps['onChange'] = (page) => {
|
|
||||||
console.log(this.state.ocuppiedInvoices)
|
|
||||||
this.requestInvoices(page, this.state.searchOptions)
|
|
||||||
};
|
|
||||||
checkSelected = (invoice: Invoice) => {
|
|
||||||
for (let i = 0; i < this.state.occupiedInvoices.length; i++) {
|
|
||||||
if (this.state.occupiedInvoices[i].invoiceId === invoice.invoiceId) {
|
|
||||||
return -3
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (this.state.after !== 0 && this.state.after > Number(Date.parse(invoice.invoiceDate)))
|
|
||||||
return -1
|
|
||||||
if (this.state.before !== 0 && this.state.before < Number(Date.parse(invoice.invoiceDate)))
|
|
||||||
return -2
|
|
||||||
if (this.state.selectedInvoice.invoiceId === invoice.invoiceId)
|
|
||||||
return 1
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
cardList = () => {
|
|
||||||
let cards = []
|
|
||||||
const maxSize = Math.min(4, this.state.invoices.length)
|
|
||||||
for (let i = 0; i < maxSize; i += 2) {
|
|
||||||
if (i + 1 >= this.state.invoices.length) {
|
|
||||||
cards.push(
|
|
||||||
<Row gutter={18} key={i}>
|
|
||||||
<Col span={12}>
|
|
||||||
<InvoiceRadioCard invoice={this.state.invoices[i]}
|
|
||||||
selected={this.checkSelected(this.state.invoices[i])}
|
|
||||||
hidden={false} index={i}
|
|
||||||
click={this.click}/>
|
|
||||||
</Col>
|
|
||||||
</Row>)
|
|
||||||
} else {
|
|
||||||
cards.push(
|
|
||||||
<Row gutter={18} key={i}>
|
|
||||||
<Col span={12}>
|
|
||||||
<InvoiceRadioCard invoice={this.state.invoices[i]}
|
|
||||||
selected={this.checkSelected(this.state.invoices[i])}
|
|
||||||
hidden={false} index={i}
|
|
||||||
click={this.click}/>
|
|
||||||
</Col>
|
|
||||||
<Col span={12}>
|
|
||||||
<InvoiceRadioCard invoice={this.state.invoices[i + 1]}
|
|
||||||
selected={this.checkSelected(this.state.invoices[i + 1])}
|
|
||||||
hidden={false} index={i + 1} click={this.click}/>
|
|
||||||
</Col>
|
|
||||||
</Row>)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return (
|
|
||||||
<>{cards}</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
|
|
||||||
<Button name={"select"} onClick={() => this.pickerOpen(true)}>
|
|
||||||
|
|
||||||
{this.state.selectedInvoice.invoiceId === null || this.state.selectedInvoice.invoiceId === undefined ?
|
|
||||||
"选择" : "修改"}
|
|
||||||
</Button>
|
|
||||||
|
|
||||||
<Popover
|
|
||||||
content={this.invoiceCard}>
|
|
||||||
<ExclamationCircleOutlined style={{marginLeft: 5}}/>
|
|
||||||
</Popover>
|
|
||||||
<Modal
|
|
||||||
open={this.state.pickerOpen}
|
|
||||||
title={this.state.pickerTitle + "选择"}
|
|
||||||
onOk={this.confirm}
|
|
||||||
onCancel={() => this.pickerOpen(false)}
|
|
||||||
destroyOnClose={true}
|
|
||||||
footer={[
|
|
||||||
<Button key="clear" type="primary" onClick={this.cancelSelect}>
|
|
||||||
清除
|
|
||||||
</Button>,
|
|
||||||
<Button key="confirm" type="primary" onClick={this.confirm}>
|
|
||||||
确定
|
|
||||||
</Button>
|
|
||||||
]}
|
|
||||||
>
|
|
||||||
|
|
||||||
{this.cardList()}
|
|
||||||
<Pagination pageSize={this.state.pageSize} current={this.state.currentPage}
|
|
||||||
onChange={this.changePage} total={this.state.total}/>
|
|
||||||
</Modal>
|
|
||||||
</>)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
const openNotification = (hint: string) => {
|
||||||
|
notification.open({
|
||||||
|
message: hint,
|
||||||
|
duration: 1,
|
||||||
|
onClick: () => {
|
||||||
|
console.log('Notification Clicked!');
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
class ReimbursementCreate extends React.Component<any, any> {
|
class ReimbursementCreate extends React.Component<any, any> {
|
||||||
formRef = React.createRef<FormInstance>();
|
formRef = React.createRef<FormInstance>();
|
||||||
invoiceSelector1 = React.createRef<SingleInvoiceSelector>();
|
invoiceSelector1 = React.createRef<SingleInvoiceSelector>();
|
||||||
invoiceSelector2 = React.createRef<SingleInvoiceSelector>();
|
invoiceSelector2 = React.createRef<SingleInvoiceSelector>();
|
||||||
//invoiceSelector3 = React.createRef<InvoiceSelector>();
|
invoiceSelector3 = React.createRef<MultiInvoiceSelector>();
|
||||||
departments: { departmentId: number, departmentName: string }[] = [];
|
departments: { departmentId: number, departmentName: string }[] = [];
|
||||||
|
|
||||||
constructor(props: {}) {
|
constructor(props: {}) {
|
||||||
|
@ -367,6 +49,7 @@ class ReimbursementCreate extends React.Component<any, any> {
|
||||||
departmentName: store.getState().staff.managingDepartment.departmentName,
|
departmentName: store.getState().staff.managingDepartment.departmentName,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
console.log(store.getState().staff.staffDepartments)
|
||||||
store.getState().staff.staffDepartments.forEach((item) => {
|
store.getState().staff.staffDepartments.forEach((item) => {
|
||||||
this.departments.push({
|
this.departments.push({
|
||||||
departmentId: item.departmentId,
|
departmentId: item.departmentId,
|
||||||
|
@ -381,6 +64,7 @@ class ReimbursementCreate extends React.Component<any, any> {
|
||||||
icon: <UserOutlined/>,
|
icon: <UserOutlined/>,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
console.log(store.getState().staff.staffDepartments)
|
||||||
this.state = {
|
this.state = {
|
||||||
loading: false,
|
loading: false,
|
||||||
open: this.props.open,
|
open: this.props.open,
|
||||||
|
@ -413,9 +97,44 @@ class ReimbursementCreate extends React.Component<any, any> {
|
||||||
//console.log('click', e.key,this.departments.find((item)=>item.departmentId.toString()===e.key));
|
//console.log('click', e.key,this.departments.find((item)=>item.departmentId.toString()===e.key));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
submitCheck = () => {
|
||||||
|
|
||||||
|
return {ok:true,msg:""}
|
||||||
|
}
|
||||||
submit = () => {
|
submit = () => {
|
||||||
console.log(this.formRef.current?.getFieldsValue())
|
let checkResult = this.submitCheck()
|
||||||
|
if(!checkResult.ok){
|
||||||
|
openNotification(checkResult.msg)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let otherInvoices = null
|
||||||
|
if(this.state.otherInvoices?.length>0){
|
||||||
|
otherInvoices = ""
|
||||||
|
for(let i=0;i<this.state.otherInvoices.length;i++){
|
||||||
|
if(i!==0){
|
||||||
|
otherInvoices += ","
|
||||||
|
}
|
||||||
|
otherInvoices += this.state.otherInvoices[i].invoiceId.toString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let params={
|
||||||
|
submitDepartmentId:this.state.selectedDepartment.id,
|
||||||
|
reimbursementNote:this.state.note?this.state.note:"",
|
||||||
|
reimbursementDepartureInvoiceId: this.state.departureInvoice.invoiceId,
|
||||||
|
reimbursementDestinationInvoiceId: this.state.destinationInvoice?.invoiceId,
|
||||||
|
reimbursementOtherInvoiceIds: otherInvoices,
|
||||||
|
reimbursementDepartureName: this.state.departureName,
|
||||||
|
reimbursementDestinationName: this.state.destinationName,
|
||||||
|
reimbursementDuration: this.state.duration,
|
||||||
|
}
|
||||||
|
axiosInstance.post("common/reimbursement", params).then(response => {
|
||||||
|
|
||||||
|
openNotification("提交成功")
|
||||||
|
this.setState({open: false})
|
||||||
|
}).catch(error => {
|
||||||
|
console.log(error)
|
||||||
|
openNotification("提交失败")
|
||||||
|
})
|
||||||
}
|
}
|
||||||
cancel = () => {
|
cancel = () => {
|
||||||
this.setState({open: false})
|
this.setState({open: false})
|
||||||
|
@ -448,31 +167,34 @@ class ReimbursementCreate extends React.Component<any, any> {
|
||||||
|
|
||||||
this.setState(state)
|
this.setState(state)
|
||||||
}
|
}
|
||||||
getOccupiedInvoices = (type:number) => {
|
getOccupiedInvoices = (type: number) => {
|
||||||
let res=[]
|
let res = []
|
||||||
if(type===1){
|
if (type === 1) {
|
||||||
this.state.otherInvoices?.forEach((item:Invoice)=>{
|
this.state.otherInvoices?.forEach((item: Invoice) => {
|
||||||
res.push(item)
|
res.push(item)
|
||||||
})
|
})
|
||||||
if(this.state.destinationInvoice!==null&&this.state.destinationInvoice!==undefined)
|
if (this.state.destinationInvoice !== null && this.state.destinationInvoice !== undefined)
|
||||||
res.push(this.state.destinationInvoice)
|
res.push(this.state.destinationInvoice)
|
||||||
}else if(type===2) {
|
} else if (type === 2) {
|
||||||
this.state.otherInvoices?.forEach((item: Invoice) => {
|
this.state.otherInvoices?.forEach((item: Invoice) => {
|
||||||
res.push(item)
|
res.push(item)
|
||||||
})
|
})
|
||||||
if (this.state.departureInvoice !== null && this.state.departureInvoice !== undefined)
|
if (this.state.departureInvoice !== null && this.state.departureInvoice !== undefined)
|
||||||
res.push(this.state.departureInvoice)
|
res.push(this.state.departureInvoice)
|
||||||
}else if(type===3){
|
} else if (type === 3) {
|
||||||
if(this.state.departureInvoice!==null&&this.state.departureInvoice!==undefined)
|
if (this.state.departureInvoice !== null && this.state.departureInvoice !== undefined)
|
||||||
res.push(this.state.departureInvoice)
|
res.push(this.state.departureInvoice)
|
||||||
if(this.state.destinationInvoice!==null&&this.state.destinationInvoice!==undefined)
|
if (this.state.destinationInvoice !== null && this.state.destinationInvoice !== undefined)
|
||||||
res.push(this.state.destinationInvoice)
|
res.push(this.state.destinationInvoice)
|
||||||
}
|
}
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
|
|
||||||
|
width={800}
|
||||||
open={this.state.open}
|
open={this.state.open}
|
||||||
title="出差报销单"
|
title="出差报销单"
|
||||||
onOk={this.submit}
|
onOk={this.submit}
|
||||||
|
@ -517,6 +239,7 @@ class ReimbursementCreate extends React.Component<any, any> {
|
||||||
<Col span={12}>
|
<Col span={12}>
|
||||||
<Form.Item label="返程票据" name="destinationInvoice" rules={[{required: false}]}>
|
<Form.Item label="返程票据" name="destinationInvoice" rules={[{required: false}]}>
|
||||||
<SingleInvoiceSelector pickerOpen={false}
|
<SingleInvoiceSelector pickerOpen={false}
|
||||||
|
//disabled={this.state.departureInvoice === null || this.state.departureInvoice === undefined}
|
||||||
after={this.state.departureInvoice !== null && this.state.departureInvoice !== undefined ? Number(Date.parse(this.state.departureInvoice.invoiceDate)) : 0}
|
after={this.state.departureInvoice !== null && this.state.departureInvoice !== undefined ? Number(Date.parse(this.state.departureInvoice.invoiceDate)) : 0}
|
||||||
before={0} occupiedInvoices={this.getOccupiedInvoices(2)}
|
before={0} occupiedInvoices={this.getOccupiedInvoices(2)}
|
||||||
pickerTitle={"返程票据"} ref={this.invoiceSelector2}
|
pickerTitle={"返程票据"} ref={this.invoiceSelector2}
|
||||||
|
@ -545,11 +268,51 @@ class ReimbursementCreate extends React.Component<any, any> {
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
|
<Form.Item label="附加票据" name="otherInvoices" rules={[{required: false}]}>
|
||||||
|
<MultiInvoiceSelector pickerOpen={false}
|
||||||
|
after={0}
|
||||||
|
//after={this.state.departureInvoice !== null && this.state.departureInvoice !== undefined ? Number(Date.parse(this.state.departureInvoice.invoiceDate)) : 0}
|
||||||
|
before={0} occupiedInvoices={this.getOccupiedInvoices(3)}
|
||||||
|
pickerTitle={"附加票据"} ref={this.invoiceSelector3}
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
<Form.Item label="备注信息" name="note" rules={[{required: false}]}>
|
<Form.Item label="备注信息" name="note" rules={[{required: false}]}>
|
||||||
<Input.TextArea/>
|
<Input.TextArea/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
<StatisticCard.Group>
|
||||||
|
<StatisticCard
|
||||||
|
statistic={{
|
||||||
|
title: '出发票据金额',
|
||||||
|
value: this.state.departureInvoice !== null && this.state.departureInvoice !== undefined ? (this.state.departureInvoice.invoiceAmount/100.0).toFixed(2): 0,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Operation>+</Operation>
|
||||||
|
<StatisticCard
|
||||||
|
statistic={{
|
||||||
|
title: '返程票据金额',
|
||||||
|
value: this.state.destinationInvoice !== null && this.state.destinationInvoice !== undefined ? (this.state.destinationInvoice.invoiceAmount/100.0).toFixed(2) : 0,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Operation>+</Operation>
|
||||||
|
<StatisticCard
|
||||||
|
statistic={{
|
||||||
|
title: '附加票据金额',
|
||||||
|
value: this.state.otherInvoices!==null&&this.state.otherInvoices!==undefined&&this.state.otherInvoices.length > 0 ?
|
||||||
|
(this.state.otherInvoices.map((item:Invoice) => item.invoiceAmount).reduce((a:number, b:number) => a + b)/100.0).toFixed(2) : 0,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Operation>=</Operation>
|
||||||
|
<StatisticCard
|
||||||
|
statistic={{
|
||||||
|
title: '票据总金额',
|
||||||
|
value: (((this.state.departureInvoice !== null && this.state.departureInvoice !== undefined ? this.state.departureInvoice.invoiceAmount: 0)
|
||||||
|
+(this.state.destinationInvoice !== null && this.state.destinationInvoice !== undefined ? this.state.destinationInvoice.invoiceAmount : 0)
|
||||||
|
+(this.state.otherInvoices!==null&&this.state.otherInvoices!==undefined&&this.state.otherInvoices.length > 0 ?
|
||||||
|
this.state.otherInvoices.map((item:Invoice) => item.invoiceAmount).reduce((a:number, b:number) => a + b) : 0))/100.0).toFixed(2) ,
|
||||||
|
suffix: '元',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</StatisticCard.Group>
|
||||||
</Form>
|
</Form>
|
||||||
</Modal>)
|
</Modal>)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,371 @@
|
||||||
|
import {Invoice} from "../../../../models/Reimbursement";
|
||||||
|
import {Button, Card, Col, Modal, Pagination, PaginationProps, Popover, Row, Tag} from "antd";
|
||||||
|
import axiosInstance, {baseUrl} from "../../../../utils/axiosInstance";
|
||||||
|
import {invoiceTypeNameMap} from "../../../../models/Invoice";
|
||||||
|
import React from "react";
|
||||||
|
import {store} from "../../../../models/store";
|
||||||
|
import {ExclamationCircleOutlined} from "@ant-design/icons";
|
||||||
|
|
||||||
|
|
||||||
|
class InvoiceCheckboxCard extends React.Component<any, any> {
|
||||||
|
|
||||||
|
constructor(props: {
|
||||||
|
invoice: any;
|
||||||
|
hidden: boolean;
|
||||||
|
selected: number;
|
||||||
|
index: number;
|
||||||
|
click: any;
|
||||||
|
}) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
invoice: props.invoice,
|
||||||
|
hidden: props.hidden,
|
||||||
|
selected: props.selected,
|
||||||
|
index: props.index,
|
||||||
|
click: props.click,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static getDerivedStateFromProps(props: {
|
||||||
|
invoice: any;
|
||||||
|
hidden: boolean;
|
||||||
|
selected: number;
|
||||||
|
index: number;
|
||||||
|
}) {
|
||||||
|
return {
|
||||||
|
invoice: props.invoice,
|
||||||
|
hidden: props.hidden,
|
||||||
|
selected: props.selected,
|
||||||
|
index: props.index,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
select(e: any) {
|
||||||
|
if (this.state.selected === 0) {
|
||||||
|
this.setState({selected: 1})
|
||||||
|
this.props.click(this.state.invoice, true)
|
||||||
|
} else if (this.state.selected === 1) {
|
||||||
|
this.setState({selected: 0})
|
||||||
|
this.props.click(this.state.invoice, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getTag = () => {
|
||||||
|
if (this.state.selected === 1)
|
||||||
|
return <Popover content={"已选作报销凭证"}><Tag color="blue">已选择</Tag></Popover>
|
||||||
|
else if (this.state.selected === 0)
|
||||||
|
return <Popover content={"可用于报销"}><Tag color="green">待选择</Tag></Popover>
|
||||||
|
else if (this.state.selected === -1)
|
||||||
|
return <Popover content={"早于出发日期"}><Tag color="red">不可选</Tag></Popover>
|
||||||
|
else if (this.state.selected === -2)
|
||||||
|
return <Popover content={"晚于返程日期"}><Tag color="red">不可选</Tag></Popover>
|
||||||
|
else if (this.state.selected === -3)
|
||||||
|
return <Popover content={"已作其他用途"}><Tag color="red">不可选</Tag></Popover>
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<Card hidden={this.state.hidden}
|
||||||
|
hoverable={true}
|
||||||
|
style={{
|
||||||
|
marginBottom: 30, background: (this.state.selected === 1 ? "lightskyblue" : "#f0f0f0"),
|
||||||
|
opacity: (this.state.selected >= 0 ? 1 : 0.7)
|
||||||
|
}}
|
||||||
|
onClick={(e) => {
|
||||||
|
this.select(e)
|
||||||
|
}}
|
||||||
|
cover={<img alt="thumbnail"
|
||||||
|
src={baseUrl + this.state.invoice.invoiceThumbnailUri}
|
||||||
|
width="300" height="120"/>}
|
||||||
|
// actions={[<Radio checked={this.state.selected} onClick={(e) => {
|
||||||
|
// this.select(e)
|
||||||
|
// }} defaultChecked={this.state.selected}/>]}
|
||||||
|
>
|
||||||
|
<div style={{marginTop: -20, height: 80}}>
|
||||||
|
|
||||||
|
<li style={{
|
||||||
|
fontWeight: "bold",
|
||||||
|
fontSize: 18
|
||||||
|
}}>¥{(this.state.invoice.invoiceAmount / 100.0).toFixed(2)}
|
||||||
|
{this.getTag()}
|
||||||
|
</li>
|
||||||
|
<li>{invoiceTypeNameMap.get(this.state.invoice.invoiceKind)}</li>
|
||||||
|
<li>{this.state.invoice.invoiceName}</li>
|
||||||
|
<li>{this.state.invoice.invoiceNote}</li>
|
||||||
|
<li>{this.state.invoice.invoiceDate}</li>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MultiInvoiceSelector extends React.Component<any, any> {
|
||||||
|
value: any
|
||||||
|
onChange: any
|
||||||
|
availableInvoiceKinds = [0, 2, 5, 9, 10, 13]
|
||||||
|
|
||||||
|
constructor(props: {
|
||||||
|
disabled: boolean;
|
||||||
|
pickerOpen: boolean;
|
||||||
|
pickerTitle: string;
|
||||||
|
value: any;
|
||||||
|
onChange: any;
|
||||||
|
after: number;
|
||||||
|
before: number;
|
||||||
|
occupiedInvoices: Invoice[];
|
||||||
|
}) {
|
||||||
|
super(props);
|
||||||
|
this.value = props.value
|
||||||
|
this.onChange = props.onChange
|
||||||
|
this.state = {
|
||||||
|
disabled: props.disabled,
|
||||||
|
occupiedInvoices: props.occupiedInvoices,
|
||||||
|
selectedInvoice: [],
|
||||||
|
singleLimit: false,
|
||||||
|
invoices: [],
|
||||||
|
pickerOpen: props.pickerOpen,
|
||||||
|
pickerTitle: props.pickerTitle,
|
||||||
|
currentPage: 1,
|
||||||
|
pageSize: 6,
|
||||||
|
total: 0,
|
||||||
|
after: props.after,
|
||||||
|
before: props.before,
|
||||||
|
searchOptions: {
|
||||||
|
invoiceNote: "",
|
||||||
|
invoiceDateStart: 0,
|
||||||
|
invoiceDateEnd: 0,
|
||||||
|
invoiceKind: -1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.requestInvoices(1, this.state.searchOptions)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
requestInvoices(page: number, searchOptions: any) {
|
||||||
|
let params: any = {
|
||||||
|
pageNum: page - 1,
|
||||||
|
pageSize: this.state.pageSize,
|
||||||
|
invoiceUploaderId: store.getState().token.staffId,
|
||||||
|
invoiceStatus: 0,
|
||||||
|
sortBy: "invoiceDate",
|
||||||
|
asc: true,
|
||||||
|
}
|
||||||
|
if (searchOptions.invoiceNote !== "") {
|
||||||
|
params.invoiceNote = searchOptions.invoiceNote
|
||||||
|
}
|
||||||
|
if (searchOptions.invoiceDateStart !== 0) {
|
||||||
|
params.invoiceDateStart = searchOptions.invoiceDateStart
|
||||||
|
}
|
||||||
|
if (searchOptions.invoiceDateEnd !== 0) {
|
||||||
|
params.invoiceDateEnd = searchOptions.invoiceDateEnd
|
||||||
|
}
|
||||||
|
if (searchOptions.invoiceKind !== -1) {
|
||||||
|
params.invoiceKinds = searchOptions.invoiceKind
|
||||||
|
} else {
|
||||||
|
// params.invoiceKinds = "0,2,5,9,10,13"
|
||||||
|
}
|
||||||
|
console.log(params)
|
||||||
|
axiosInstance.get('common/invoice', {params: params}).then(response => {
|
||||||
|
this.setState({
|
||||||
|
total: response.data.total, invoices: response.data.records,
|
||||||
|
currentPage: page, searchOptions: searchOptions
|
||||||
|
})
|
||||||
|
}).catch(error => {
|
||||||
|
console.log(error)
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static getDerivedStateFromProps(props: {
|
||||||
|
after: number;
|
||||||
|
before: number;
|
||||||
|
occupiedInvoices: Invoice[];
|
||||||
|
onChange: any;
|
||||||
|
}, state: any) {
|
||||||
|
let prev = state.selectedInvoice
|
||||||
|
let changed = false
|
||||||
|
if (props.after !== 0) {
|
||||||
|
for (let i = 0; i < prev.length; i++) {
|
||||||
|
if (Number(Date.parse(prev[i].invoiceDate) < props.after)) {
|
||||||
|
prev.splice(i, 1)
|
||||||
|
changed = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!changed)
|
||||||
|
return {
|
||||||
|
after: props.after,
|
||||||
|
before: props.before,
|
||||||
|
occupiedInvoices: props.occupiedInvoices,
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
selectedInvoice: prev,
|
||||||
|
after: props.after,
|
||||||
|
before: props.before,
|
||||||
|
occupiedInvoices: props.occupiedInvoices,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setSearchOptions = (options: any) => {
|
||||||
|
this.setState({searchOptions: options})
|
||||||
|
}
|
||||||
|
pickerOpen = (value: boolean) => {
|
||||||
|
if (this.state.disabled) {
|
||||||
|
alert("请先选择出发票据")
|
||||||
|
} else {
|
||||||
|
this.setState({pickerOpen: value})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
confirm = () => {
|
||||||
|
this.setState({pickerOpen: false})
|
||||||
|
}
|
||||||
|
cancelSelect = () => {
|
||||||
|
this.onChange(undefined)
|
||||||
|
this.setState({selectedInvoice: []})
|
||||||
|
}
|
||||||
|
|
||||||
|
click = (invoice: any, status: boolean) => {
|
||||||
|
|
||||||
|
console.log(invoice)
|
||||||
|
if (status) {
|
||||||
|
let prev = this.state.selectedInvoice
|
||||||
|
for (let i = 0; i < prev.length; i++) {
|
||||||
|
if (prev[i].invoiceId === invoice.invoiceId) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prev.push(invoice)
|
||||||
|
this.setState({selectedInvoice: prev})
|
||||||
|
this.onChange(prev)
|
||||||
|
} else {
|
||||||
|
let prev = this.state.selectedInvoice
|
||||||
|
console.log(prev)
|
||||||
|
for (let i = 0; i < prev.length; i++) {
|
||||||
|
if (prev[i].invoiceId === invoice.invoiceId) {
|
||||||
|
prev.splice(i, 1)
|
||||||
|
this.setState({selectedInvoice: prev})
|
||||||
|
this.onChange(prev)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
changePage: PaginationProps['onChange'] = (page) => {
|
||||||
|
console.log(this.state.ocuppiedInvoices)
|
||||||
|
this.requestInvoices(page, this.state.searchOptions)
|
||||||
|
};
|
||||||
|
checkSelected = (invoice: Invoice) => {
|
||||||
|
for (let i = 0; i < this.state.occupiedInvoices.length; i++) {
|
||||||
|
if (this.state.occupiedInvoices[i].invoiceId === invoice.invoiceId) {
|
||||||
|
return -3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.state.after !== 0 && this.state.after > Number(Date.parse(invoice.invoiceDate)))
|
||||||
|
return -1
|
||||||
|
// if (this.state.before !== 0 && this.state.before < Number(Date.parse(invoice.invoiceDate)))
|
||||||
|
// return -2
|
||||||
|
for (let i = 0; i < this.state.selectedInvoice.length; i++) {
|
||||||
|
if (this.state.selectedInvoice[i] === invoice) {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
cardList = () => {
|
||||||
|
let cards = []
|
||||||
|
const maxSize = Math.min(this.state.pageSize, this.state.invoices.length)
|
||||||
|
for (let i = 0; i < maxSize; i += 3) {
|
||||||
|
if (i + 1 >= this.state.invoices.length) {
|
||||||
|
cards.push(
|
||||||
|
<Row gutter={18} key={i}>
|
||||||
|
<Col span={8}>
|
||||||
|
<InvoiceCheckboxCard invoice={this.state.invoices[i]}
|
||||||
|
selected={this.checkSelected(this.state.invoices[i])}
|
||||||
|
hidden={false} index={i}
|
||||||
|
click={this.click}/>
|
||||||
|
</Col>
|
||||||
|
</Row>)
|
||||||
|
} else if (i + 2 >= this.state.invoices.length) {
|
||||||
|
cards.push(
|
||||||
|
<Row gutter={18} key={i}>
|
||||||
|
<Col span={8}>
|
||||||
|
<InvoiceCheckboxCard invoice={this.state.invoices[i]}
|
||||||
|
selected={this.checkSelected(this.state.invoices[i])}
|
||||||
|
hidden={false} index={i}
|
||||||
|
click={this.click}/>
|
||||||
|
</Col>
|
||||||
|
<Col span={8}>
|
||||||
|
<InvoiceCheckboxCard invoice={this.state.invoices[i + 1]}
|
||||||
|
selected={this.checkSelected(this.state.invoices[i + 1])}
|
||||||
|
hidden={false} index={i + 1} click={this.click}/>
|
||||||
|
</Col>
|
||||||
|
</Row>)
|
||||||
|
} else {
|
||||||
|
cards.push(
|
||||||
|
<Row gutter={18} key={i}>
|
||||||
|
<Col span={8}>
|
||||||
|
<InvoiceCheckboxCard invoice={this.state.invoices[i]}
|
||||||
|
selected={this.checkSelected(this.state.invoices[i])}
|
||||||
|
hidden={false} index={i}
|
||||||
|
click={this.click}/>
|
||||||
|
</Col>
|
||||||
|
<Col span={8}>
|
||||||
|
<InvoiceCheckboxCard invoice={this.state.invoices[i + 1]}
|
||||||
|
selected={this.checkSelected(this.state.invoices[i + 1])}
|
||||||
|
hidden={false} index={i + 1} click={this.click}/>
|
||||||
|
</Col>
|
||||||
|
<Col span={8}>
|
||||||
|
<InvoiceCheckboxCard invoice={this.state.invoices[i + 2]}
|
||||||
|
selected={this.checkSelected(this.state.invoices[i + 2])}
|
||||||
|
hidden={false} index={i + 2} click={this.click}/>
|
||||||
|
</Col>
|
||||||
|
</Row>)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<>{cards}</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
|
||||||
|
<Button name={"select"} onClick={() => this.pickerOpen(true)}>
|
||||||
|
|
||||||
|
{this.state.selectedInvoice === null || this.state.selectedInvoice === undefined ||
|
||||||
|
this.state.selectedInvoice.length === 0 ?
|
||||||
|
"选择" : "修改"}
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<Modal
|
||||||
|
width={1000}
|
||||||
|
open={this.state.pickerOpen}
|
||||||
|
title={this.state.pickerTitle + "选择"}
|
||||||
|
onOk={this.confirm}
|
||||||
|
onCancel={() => this.pickerOpen(false)}
|
||||||
|
destroyOnClose={true}
|
||||||
|
footer={[
|
||||||
|
<Button key="clear" type="primary" onClick={this.cancelSelect}>
|
||||||
|
清除
|
||||||
|
</Button>,
|
||||||
|
<Button key="confirm" type="primary" onClick={this.confirm}>
|
||||||
|
确定
|
||||||
|
</Button>
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
|
||||||
|
{this.cardList()}
|
||||||
|
<Pagination pageSize={this.state.pageSize} current={this.state.currentPage}
|
||||||
|
onChange={this.changePage} total={this.state.total}/>
|
||||||
|
</Modal>
|
||||||
|
</>)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default MultiInvoiceSelector;
|
|
@ -0,0 +1,369 @@
|
||||||
|
import {Invoice} from "../../../../models/Reimbursement";
|
||||||
|
import {Button, Card, Col, Modal, Pagination, PaginationProps, Popover, Row, Tag, notification} from "antd";
|
||||||
|
import axiosInstance, {baseUrl} from "../../../../utils/axiosInstance";
|
||||||
|
import {invoiceTypeNameMap} from "../../../../models/Invoice";
|
||||||
|
import React from "react";
|
||||||
|
import {store} from "../../../../models/store";
|
||||||
|
import {ExclamationCircleOutlined} from "@ant-design/icons";
|
||||||
|
|
||||||
|
const openNotification = (hint: string) => {
|
||||||
|
notification.open({
|
||||||
|
message: hint,
|
||||||
|
duration: 1,
|
||||||
|
onClick: () => {
|
||||||
|
console.log('Notification Clicked!');
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
function InvoiceCard(props: { invoice: Invoice }) {
|
||||||
|
const invoice = props.invoice;
|
||||||
|
console.log(invoice);
|
||||||
|
return (
|
||||||
|
<Card
|
||||||
|
// hoverable
|
||||||
|
// style={{
|
||||||
|
// width: 250,
|
||||||
|
// height: 300,
|
||||||
|
// margin: 30
|
||||||
|
// }}
|
||||||
|
style={{background: "#f0f0f0"}}
|
||||||
|
cover={<img alt="thumbnail"
|
||||||
|
src={baseUrl + invoice.invoiceThumbnailUri}
|
||||||
|
width="220" height="180"/>}
|
||||||
|
>
|
||||||
|
<div style={{marginTop: -20}}>
|
||||||
|
<li style={{fontWeight: "bold", fontSize: 20}}>¥{(invoice.invoiceAmount / 100.0).toFixed(2)}</li>
|
||||||
|
<li>{invoiceTypeNameMap.get(invoice.invoiceKind)}</li>
|
||||||
|
{(invoice.invoiceDeparture !== null && invoice.invoiceDestination !== null &&
|
||||||
|
<li>{invoice.invoiceDeparture}{" → "}
|
||||||
|
{invoice.invoiceDestination}</li>)}
|
||||||
|
<li>{invoice.invoiceDate}</li>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
class InvoiceRadioCard extends React.Component<any, any> {
|
||||||
|
|
||||||
|
constructor(props: {
|
||||||
|
invoice: any;
|
||||||
|
hidden: boolean;
|
||||||
|
selected: number;
|
||||||
|
index: number;
|
||||||
|
click: any;
|
||||||
|
}) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
invoice: props.invoice,
|
||||||
|
hidden: props.hidden,
|
||||||
|
selected: props.selected,
|
||||||
|
index: props.index,
|
||||||
|
click: props.click,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static getDerivedStateFromProps(props: {
|
||||||
|
invoice: any;
|
||||||
|
hidden: boolean;
|
||||||
|
selected: number;
|
||||||
|
index: number;
|
||||||
|
}) {
|
||||||
|
return {
|
||||||
|
invoice: props.invoice,
|
||||||
|
hidden: props.hidden,
|
||||||
|
selected: props.selected,
|
||||||
|
index: props.index,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
select(e: any) {
|
||||||
|
if (this.state.selected !== 0)
|
||||||
|
return
|
||||||
|
this.setState({selected: 1})
|
||||||
|
this.props.click(this.props.invoice, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
getTag = () => {
|
||||||
|
if (this.state.selected === 1)
|
||||||
|
return <Popover content={"已选作报销凭证"}><Tag color="blue">已选择</Tag></Popover>
|
||||||
|
else if (this.state.selected === 0)
|
||||||
|
return <Popover content={"可用于报销"}><Tag color="green">待选择</Tag></Popover>
|
||||||
|
else if (this.state.selected === -1)
|
||||||
|
return <Popover content={"早于出发日期"}><Tag color="red">不可选</Tag></Popover>
|
||||||
|
else if (this.state.selected === -2)
|
||||||
|
return <Popover content={"晚于返程日期"}><Tag color="red">不可选</Tag></Popover>
|
||||||
|
else if (this.state.selected === -3)
|
||||||
|
return <Popover content={"已作其他用途"}><Tag color="red">不可选</Tag></Popover>
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<Card hidden={this.state.hidden}
|
||||||
|
hoverable={true}
|
||||||
|
style={{
|
||||||
|
marginBottom: 30, background: (this.state.selected === 1 ? "lightskyblue" : "#f0f0f0"),
|
||||||
|
opacity: (this.state.selected >= 0 ? 1 : 0.7)
|
||||||
|
}}
|
||||||
|
onClick={(e) => {
|
||||||
|
this.select(e)
|
||||||
|
}}
|
||||||
|
cover={<img alt="thumbnail"
|
||||||
|
src={baseUrl + this.state.invoice.invoiceThumbnailUri}
|
||||||
|
width="300" height="120"/>}
|
||||||
|
// actions={[<Radio checked={this.state.selected} onClick={(e) => {
|
||||||
|
// this.select(e)
|
||||||
|
// }} defaultChecked={this.state.selected}/>]}
|
||||||
|
>
|
||||||
|
<div style={{marginTop: -20, height: 80}}>
|
||||||
|
|
||||||
|
<li style={{
|
||||||
|
fontWeight: "bold",
|
||||||
|
fontSize: 18
|
||||||
|
}}>¥{(this.state.invoice.invoiceAmount / 100.0).toFixed(2)}
|
||||||
|
{this.getTag()}
|
||||||
|
</li>
|
||||||
|
<li>{invoiceTypeNameMap.get(this.state.invoice.invoiceKind)}</li>
|
||||||
|
{(this.state.invoice.invoiceDeparture !== null && this.state.invoice.invoiceDestination !== null &&
|
||||||
|
<li>{this.state.invoice.invoiceDeparture}{" → "}
|
||||||
|
{this.state.invoice.invoiceDestination}</li>)}
|
||||||
|
<li>{this.state.invoice.invoiceDate}</li>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SingleInvoiceSelector extends React.Component<any, any> {
|
||||||
|
value: any
|
||||||
|
onChange: any
|
||||||
|
availableInvoiceKinds = [0, 2, 5, 9, 10, 13]
|
||||||
|
|
||||||
|
constructor(props: {
|
||||||
|
disabled: boolean;
|
||||||
|
pickerOpen: boolean;
|
||||||
|
pickerTitle: string;
|
||||||
|
value: any;
|
||||||
|
onChange: any;
|
||||||
|
after: number;
|
||||||
|
before: number;
|
||||||
|
occupiedInvoices: Invoice[];
|
||||||
|
}) {
|
||||||
|
super(props);
|
||||||
|
this.value = props.value
|
||||||
|
this.onChange = props.onChange
|
||||||
|
this.state = {
|
||||||
|
disabled: props.disabled,
|
||||||
|
occupiedInvoices: props.occupiedInvoices,
|
||||||
|
selectedInvoice: {},
|
||||||
|
singleLimit: true,
|
||||||
|
invoices: [],
|
||||||
|
pickerOpen: props.pickerOpen,
|
||||||
|
pickerTitle: props.pickerTitle,
|
||||||
|
currentPage: 1,
|
||||||
|
pageSize: 6,
|
||||||
|
total: 0,
|
||||||
|
after: props.after,
|
||||||
|
before: props.before,
|
||||||
|
searchOptions: {
|
||||||
|
invoiceNote: "",
|
||||||
|
invoiceDateStart: 0,
|
||||||
|
invoiceDateEnd: 0,
|
||||||
|
invoiceKind: -1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.requestInvoices(1, this.state.searchOptions)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
requestInvoices(page: number, searchOptions: any) {
|
||||||
|
let params: any = {
|
||||||
|
pageNum: page - 1,
|
||||||
|
pageSize: this.state.pageSize,
|
||||||
|
invoiceUploaderId: store.getState().token.staffId,
|
||||||
|
invoiceStatus: 0,
|
||||||
|
sortBy: "invoiceDate",
|
||||||
|
asc: true,
|
||||||
|
}
|
||||||
|
if (searchOptions.invoiceNote !== "") {
|
||||||
|
params.invoiceNote = searchOptions.invoiceNote
|
||||||
|
}
|
||||||
|
if (searchOptions.invoiceDateStart !== 0) {
|
||||||
|
params.invoiceDateStart = searchOptions.invoiceDateStart
|
||||||
|
}
|
||||||
|
if (searchOptions.invoiceDateEnd !== 0) {
|
||||||
|
params.invoiceDateEnd = searchOptions.invoiceDateEnd
|
||||||
|
}
|
||||||
|
if (searchOptions.invoiceKind !== -1) {
|
||||||
|
params.invoiceKinds = searchOptions.invoiceKind
|
||||||
|
} else {
|
||||||
|
params.invoiceKinds = "0,2,5,9,10,13"
|
||||||
|
}
|
||||||
|
console.log(params)
|
||||||
|
axiosInstance.get('common/invoice', {params: params}).then(response => {
|
||||||
|
this.setState({
|
||||||
|
total: response.data.total, invoices: response.data.records,
|
||||||
|
currentPage: page, searchOptions: searchOptions
|
||||||
|
})
|
||||||
|
}).catch(error => {
|
||||||
|
console.log(error)
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
setSearchOptions = (options: any) => {
|
||||||
|
this.setState({searchOptions: options})
|
||||||
|
}
|
||||||
|
invoiceCard = () => {
|
||||||
|
if (this.state.selectedInvoice.invoiceId === null || this.state.selectedInvoice.invoiceId === undefined) {
|
||||||
|
return (<>请选择一张{this.state.pickerTitle}</>)
|
||||||
|
}
|
||||||
|
return (<InvoiceCard invoice={this.state.selectedInvoice}/>)
|
||||||
|
}
|
||||||
|
pickerOpen = (value: boolean) => {
|
||||||
|
if (this.state.disabled) {
|
||||||
|
openNotification("请先选择出发票据")
|
||||||
|
} else {
|
||||||
|
this.setState({pickerOpen: value})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
confirm = () => {
|
||||||
|
this.setState({pickerOpen: false})
|
||||||
|
}
|
||||||
|
cancelSelect = () => {
|
||||||
|
this.onChange(undefined)
|
||||||
|
this.setState({selectedInvoice: {}})
|
||||||
|
}
|
||||||
|
|
||||||
|
click = (invoice: any, status: boolean) => {
|
||||||
|
if (status) {
|
||||||
|
this.setState({selectedInvoice: invoice})
|
||||||
|
this.onChange(invoice)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static getDerivedStateFromProps(nextProps: any, prevState: any) {
|
||||||
|
return {
|
||||||
|
after: nextProps.after,
|
||||||
|
before: nextProps.before,
|
||||||
|
occupiedInvoices: nextProps.occupiedInvoices,
|
||||||
|
disabled: nextProps.disabled,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
changePage: PaginationProps['onChange'] = (page) => {
|
||||||
|
console.log(this.state.ocuppiedInvoices)
|
||||||
|
this.requestInvoices(page, this.state.searchOptions)
|
||||||
|
};
|
||||||
|
checkSelected = (invoice: Invoice) => {
|
||||||
|
for (let i = 0; i < this.state.occupiedInvoices.length; i++) {
|
||||||
|
if (this.state.occupiedInvoices[i].invoiceId === invoice.invoiceId) {
|
||||||
|
return -3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.state.after !== 0 && this.state.after > Number(Date.parse(invoice.invoiceDate)))
|
||||||
|
return -1
|
||||||
|
if (this.state.before !== 0 && this.state.before < Number(Date.parse(invoice.invoiceDate)))
|
||||||
|
return -2
|
||||||
|
if (this.state.selectedInvoice.invoiceId === invoice.invoiceId)
|
||||||
|
return 1
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
cardList = () => {
|
||||||
|
let cards = []
|
||||||
|
const maxSize = Math.min(this.state.pageSize, this.state.invoices.length)
|
||||||
|
for (let i = 0; i < maxSize; i += 3) {
|
||||||
|
if (i + 1 >= this.state.invoices.length) {
|
||||||
|
cards.push(
|
||||||
|
<Row gutter={18} key={i}>
|
||||||
|
<Col span={8}>
|
||||||
|
<InvoiceRadioCard invoice={this.state.invoices[i]}
|
||||||
|
selected={this.checkSelected(this.state.invoices[i])}
|
||||||
|
hidden={false} index={i}
|
||||||
|
click={this.click}/>
|
||||||
|
</Col>
|
||||||
|
</Row>)
|
||||||
|
} else if (i + 2 >= this.state.invoices.length) {
|
||||||
|
cards.push(
|
||||||
|
<Row gutter={18} key={i}>
|
||||||
|
<Col span={8}>
|
||||||
|
<InvoiceRadioCard invoice={this.state.invoices[i]}
|
||||||
|
selected={this.checkSelected(this.state.invoices[i])}
|
||||||
|
hidden={false} index={i}
|
||||||
|
click={this.click}/>
|
||||||
|
</Col>
|
||||||
|
<Col span={8}>
|
||||||
|
<InvoiceRadioCard invoice={this.state.invoices[i + 1]}
|
||||||
|
selected={this.checkSelected(this.state.invoices[i + 1])}
|
||||||
|
hidden={false} index={i + 1} click={this.click}/>
|
||||||
|
</Col>
|
||||||
|
</Row>)
|
||||||
|
} else {
|
||||||
|
cards.push(
|
||||||
|
<Row gutter={18} key={i}>
|
||||||
|
<Col span={8}>
|
||||||
|
<InvoiceRadioCard invoice={this.state.invoices[i]}
|
||||||
|
selected={this.checkSelected(this.state.invoices[i])}
|
||||||
|
hidden={false} index={i}
|
||||||
|
click={this.click}/>
|
||||||
|
</Col>
|
||||||
|
<Col span={8}>
|
||||||
|
<InvoiceRadioCard invoice={this.state.invoices[i + 1]}
|
||||||
|
selected={this.checkSelected(this.state.invoices[i + 1])}
|
||||||
|
hidden={false} index={i + 1} click={this.click}/>
|
||||||
|
</Col>
|
||||||
|
<Col span={8}>
|
||||||
|
<InvoiceRadioCard invoice={this.state.invoices[i + 2]}
|
||||||
|
selected={this.checkSelected(this.state.invoices[i + 2])}
|
||||||
|
hidden={false} index={i + 2} click={this.click}/>
|
||||||
|
</Col>
|
||||||
|
</Row>)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<>{cards}</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
|
||||||
|
<Button name={"select"} onClick={() => this.pickerOpen(true)}>
|
||||||
|
|
||||||
|
{this.state.selectedInvoice.invoiceId === null || this.state.selectedInvoice.invoiceId === undefined ?
|
||||||
|
"选择" : "修改"}
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<Popover
|
||||||
|
content={this.invoiceCard}>
|
||||||
|
<ExclamationCircleOutlined style={{marginLeft: 5}}/>
|
||||||
|
</Popover>
|
||||||
|
<Modal
|
||||||
|
width={1000}
|
||||||
|
open={this.state.pickerOpen}
|
||||||
|
title={this.state.pickerTitle + "选择"}
|
||||||
|
onOk={this.confirm}
|
||||||
|
onCancel={() => this.pickerOpen(false)}
|
||||||
|
destroyOnClose={true}
|
||||||
|
footer={[
|
||||||
|
<Button key="clear" type="primary" onClick={this.cancelSelect}>
|
||||||
|
清除
|
||||||
|
</Button>,
|
||||||
|
<Button key="confirm" type="primary" onClick={this.confirm}>
|
||||||
|
确定
|
||||||
|
</Button>
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
|
||||||
|
{this.cardList()}
|
||||||
|
<Pagination pageSize={this.state.pageSize} current={this.state.currentPage}
|
||||||
|
onChange={this.changePage} total={this.state.total}/>
|
||||||
|
</Modal>
|
||||||
|
</>)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SingleInvoiceSelector
|
Loading…
Reference in New Issue