Merge remote-tracking branch 'origin/main' into main
commit
a8bd7a6faf
|
@ -11,7 +11,19 @@ export interface ApifoxModal {
|
||||||
records: Reimbursement[];
|
records: Reimbursement[];
|
||||||
total: number;
|
total: number;
|
||||||
}
|
}
|
||||||
|
export interface ReimbursementApplication {
|
||||||
|
reimbursementDepartureInvoiceId: number;
|
||||||
|
reimbursementDepartureName: string;
|
||||||
|
reimbursementDestinationInvoiceId?: number;
|
||||||
|
reimbursementDestinationName: string;
|
||||||
|
reimbursementNote: string;
|
||||||
|
reimbursementOtherInvoiceIds: number[];
|
||||||
|
/**
|
||||||
|
* 单程行程单时为必填项
|
||||||
|
*/
|
||||||
|
reimbursementTripDuration?: number;
|
||||||
|
submitDepartmentId: number;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* invoice
|
* invoice
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -10,6 +10,7 @@ import {FormInstance} from "antd/es/form";
|
||||||
import {SortOrder} from "antd/es/table/interface";
|
import {SortOrder} from "antd/es/table/interface";
|
||||||
import {Reimbursement} from "../../../models/Reimbursement";
|
import {Reimbursement} from "../../../models/Reimbursement";
|
||||||
import qs from 'qs';
|
import qs from 'qs';
|
||||||
|
import ReimbursementCreate from "./ReimbursementCreate";
|
||||||
|
|
||||||
const valueEnum = {
|
const valueEnum = {
|
||||||
0: 'success',
|
0: 'success',
|
||||||
|
@ -74,12 +75,13 @@ class Subpage extends React.Component<any, any> {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
searchWord: "",
|
searchWord: "",
|
||||||
|
onCreated: false,
|
||||||
}
|
}
|
||||||
this.pullDepartment()
|
this.pullDepartment()
|
||||||
}
|
}
|
||||||
|
|
||||||
department = new Map<number, string>()
|
department = new Map<number, string>()
|
||||||
|
createRef = React.createRef<ReimbursementCreate>();
|
||||||
columns: ProColumns<TableListItem>[] = [
|
columns: ProColumns<TableListItem>[] = [
|
||||||
{
|
{
|
||||||
title: '报销单号',
|
title: '报销单号',
|
||||||
|
@ -187,8 +189,7 @@ class Subpage extends React.Component<any, any> {
|
||||||
}
|
}
|
||||||
|
|
||||||
create() {
|
create() {
|
||||||
//TODO
|
this.createRef.current?.setState({open: true})
|
||||||
alert("123")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
showDetail(reimbursementId: number) {
|
showDetail(reimbursementId: number) {
|
||||||
|
@ -196,10 +197,6 @@ class Subpage extends React.Component<any, any> {
|
||||||
alert(reimbursementId)
|
alert(reimbursementId)
|
||||||
}
|
}
|
||||||
|
|
||||||
async getInvoiceDate(invoiceId: number | undefined) {
|
|
||||||
//TODO
|
|
||||||
return Date.now()
|
|
||||||
}
|
|
||||||
|
|
||||||
async converter(value: Reimbursement[] | undefined, pageSize: number | undefined) {
|
async converter(value: Reimbursement[] | undefined, pageSize: number | undefined) {
|
||||||
if (value === undefined) {
|
if (value === undefined) {
|
||||||
|
@ -218,7 +215,7 @@ class Subpage extends React.Component<any, any> {
|
||||||
additionalAmount: value[i].reimbursementAdditionalAmount,
|
additionalAmount: value[i].reimbursementAdditionalAmount,
|
||||||
status: value[i].reimbursementStatus % 6,
|
status: value[i].reimbursementStatus % 6,
|
||||||
departmentId: value[i].reimbursementSubmitDepartment.departmentId,
|
departmentId: value[i].reimbursementSubmitDepartment.departmentId,
|
||||||
submitDateTime: (new Date(value[i].reimbursementSubmitTime)).getTime(),
|
submitDateTime: Date.parse(value[i].reimbursementSubmitTime),
|
||||||
detail: "查看详情",
|
detail: "查看详情",
|
||||||
back: value[i].reimbursementDestinationInvoice !== undefined,
|
back: value[i].reimbursementDestinationInvoice !== undefined,
|
||||||
})
|
})
|
||||||
|
@ -294,6 +291,8 @@ class Subpage extends React.Component<any, any> {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
|
<>
|
||||||
|
<ReimbursementCreate ref={this.createRef} open={this.state.onCreated} wrapClassName="Subpage" />
|
||||||
<ProTable<TableListItem>
|
<ProTable<TableListItem>
|
||||||
actionRef={this.tableAction}
|
actionRef={this.tableAction}
|
||||||
columns={this.columns}
|
columns={this.columns}
|
||||||
|
@ -356,7 +355,7 @@ class Subpage extends React.Component<any, any> {
|
||||||
// </Button>,
|
// </Button>,
|
||||||
// ]}
|
// ]}
|
||||||
/>
|
/>
|
||||||
);
|
</>);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,275 @@
|
||||||
|
import React, {ReactNode} from "react";
|
||||||
|
import {ReimbursementApplication} from "../../../models/Reimbursement";
|
||||||
|
import {Button, Col, Form, Input, InputNumber, Modal, Popover, Row, Select} from "antd";
|
||||||
|
import {FormInstance} from "antd/es/form";
|
||||||
|
import {Invoice} from "../../../models/Reimbursement";
|
||||||
|
import axiosInstance from "../../../utils/axiosInstance";
|
||||||
|
import Column from "antd/es/table/Column";
|
||||||
|
import type {MenuProps} from 'antd';
|
||||||
|
import {ExclamationCircleOutlined, UserOutlined} from "@ant-design/icons";
|
||||||
|
import {Dropdown, message, Space, Tooltip} from 'antd';
|
||||||
|
import {store} from "../../../models/store";
|
||||||
|
import {FieldData} from "rc-field-form/lib/interface";
|
||||||
|
|
||||||
|
|
||||||
|
class SingleInvoiceSelector extends React.Component<any, any> {
|
||||||
|
value: any
|
||||||
|
onChange: any
|
||||||
|
|
||||||
|
constructor(props: {
|
||||||
|
invoices: Invoice[];
|
||||||
|
pickerOpen: boolean;
|
||||||
|
pickerTitle: string;
|
||||||
|
value: any;
|
||||||
|
onChange: any;
|
||||||
|
}) {
|
||||||
|
super(props);
|
||||||
|
this.value = props.value
|
||||||
|
this.onChange = props.onChange
|
||||||
|
this.state = {
|
||||||
|
selectedInvoice: {},
|
||||||
|
singleLimit: true,
|
||||||
|
invoices: props.invoices,
|
||||||
|
pickerOpen: props.pickerOpen,
|
||||||
|
pickerTitle: props.pickerTitle
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
invoiceCard = () => {
|
||||||
|
if (this.state.selectedInvoice.invoiceId === null || this.state.selectedInvoice.invoiceId === undefined) {
|
||||||
|
return (<>请选择一张{this.state.pickerTitle}</>)
|
||||||
|
}
|
||||||
|
return (<>
|
||||||
|
|
||||||
|
|
||||||
|
</>)
|
||||||
|
}
|
||||||
|
pickerOpen = (value: boolean) => {
|
||||||
|
this.setState({pickerOpen: value})
|
||||||
|
}
|
||||||
|
confirm = () => {
|
||||||
|
//TODO
|
||||||
|
this.onChange(this.state.selectedInvoice.invoiceId)
|
||||||
|
this.setState({pickerOpen: false})
|
||||||
|
}
|
||||||
|
cancelSelect = () => {
|
||||||
|
this.setState({selectedInvoices: []})
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Button name={"select"} onClick={() => this.pickerOpen(true)}>
|
||||||
|
选择
|
||||||
|
</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="confirm" type="primary" onClick={this.confirm}>
|
||||||
|
确定
|
||||||
|
</Button>
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
</Modal>
|
||||||
|
</>)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ReimbursementCreate extends React.Component<any, any> {
|
||||||
|
formRef = React.createRef<FormInstance>();
|
||||||
|
invoiceSelector1 = React.createRef<SingleInvoiceSelector>();
|
||||||
|
invoiceSelector2 = React.createRef<SingleInvoiceSelector>();
|
||||||
|
//invoiceSelector3 = React.createRef<InvoiceSelector>();
|
||||||
|
departments: { departmentId: number, departmentName: string }[] = [];
|
||||||
|
|
||||||
|
constructor(props: {}) {
|
||||||
|
super(props);
|
||||||
|
if (store.getState().staff.managingDepartment != null && store.getState().staff.managingDepartment !== undefined) {
|
||||||
|
this.departments.push({
|
||||||
|
departmentId: store.getState().staff.managingDepartment.departmentId,
|
||||||
|
departmentName: store.getState().staff.managingDepartment.departmentName,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
store.getState().staff.staffDepartments.forEach((item) => {
|
||||||
|
this.departments.push({
|
||||||
|
departmentId: item.departmentId,
|
||||||
|
departmentName: item.departmentName,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
let departmentsPropItems: any[] = [];
|
||||||
|
this.departments.map((item) => {
|
||||||
|
departmentsPropItems.push({
|
||||||
|
label: item.departmentName,
|
||||||
|
key: item.departmentId,
|
||||||
|
icon: <UserOutlined/>,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
this.state = {
|
||||||
|
loading: false,
|
||||||
|
open: this.props.open,
|
||||||
|
invoices: [],
|
||||||
|
selectedDepartment: {id: this.departments[0].departmentId, name: this.departments[0].departmentName},
|
||||||
|
departmentsProps: {
|
||||||
|
items: departmentsPropItems,
|
||||||
|
onClick: this.handleMenuClick,
|
||||||
|
},
|
||||||
|
back: false,
|
||||||
|
duration: 0,
|
||||||
|
}
|
||||||
|
let params = {
|
||||||
|
pageNum: 0,
|
||||||
|
pageSize: 100,
|
||||||
|
invoiceStatus: 0,
|
||||||
|
invoiceUploaderId: store.getState().token.staffId,
|
||||||
|
}
|
||||||
|
axiosInstance.get("common/invoice", {
|
||||||
|
params: params
|
||||||
|
}).then((res) => {
|
||||||
|
this.setState({
|
||||||
|
invoices: res.data.records
|
||||||
|
})
|
||||||
|
this.formRef.current?.setFieldValue("invoices", this.state.invoices)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
findInvoiceById = (id: number):null|Invoice => {
|
||||||
|
//return this.state.invoices[0]
|
||||||
|
this.state.invoices.map((item:Invoice)=>{
|
||||||
|
if(item.invoiceId === id)
|
||||||
|
return item
|
||||||
|
})
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
handleMenuClick: MenuProps['onClick'] = (e) => {
|
||||||
|
this.setState({
|
||||||
|
selectedDepartment: {
|
||||||
|
id: Number(e.key),
|
||||||
|
name: this.departments.find((item) => item.departmentId === Number(e.key))?.departmentName
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.formRef.current?.setFieldValue("departmentId", Number(e.key))
|
||||||
|
//console.log('click', e.key,this.departments.find((item)=>item.departmentId.toString()===e.key));
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
submit = () => {
|
||||||
|
console.log(this.formRef.current?.getFieldsValue())
|
||||||
|
}
|
||||||
|
cancel = () => {
|
||||||
|
this.setState({open: false})
|
||||||
|
}
|
||||||
|
changeDuration = (value: number | null) => {
|
||||||
|
if (value === null)
|
||||||
|
value = 0
|
||||||
|
this.setState({duration: value})
|
||||||
|
}
|
||||||
|
formFieldsChange = (changedFields: any, allFields: any) => {
|
||||||
|
let block = false
|
||||||
|
let startId = allFields['departureInvoiceId']
|
||||||
|
let endId = allFields['destinationInvoiceId']
|
||||||
|
if (typeof startId == "number" && typeof endId == "number") {
|
||||||
|
let s = this.findInvoiceById(startId)
|
||||||
|
let t = this.findInvoiceById(endId)
|
||||||
|
if (s !== null && t !== null) {
|
||||||
|
let x=Math.floor((Date.parse(t.invoiceDate)-Date.parse(s.invoiceDate))/24/60/60/1000) + 1
|
||||||
|
this.setState({back:true,duration:x})
|
||||||
|
this.formRef.current?.setFieldValue('duration',x)
|
||||||
|
block = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!block){
|
||||||
|
this.setState({back:false,duration:0})
|
||||||
|
this.formRef.current?.setFieldValue('duration',0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
open={this.state.open}
|
||||||
|
title="出差报销单"
|
||||||
|
onOk={this.submit}
|
||||||
|
onCancel={this.cancel}
|
||||||
|
destroyOnClose={true}
|
||||||
|
footer={[
|
||||||
|
<Button key="next" type="primary" loading={this.state.loading} onClick={this.submit}>
|
||||||
|
提交
|
||||||
|
</Button>]}
|
||||||
|
>
|
||||||
|
|
||||||
|
<Form ref={this.formRef} onFieldsChange={this.formFieldsChange}
|
||||||
|
initialValues={{
|
||||||
|
departmentId: this.state.selectedDepartment.id,
|
||||||
|
destinationName: '',
|
||||||
|
departureName: '',
|
||||||
|
duration: 0
|
||||||
|
}}>
|
||||||
|
|
||||||
|
<Row gutter={18}>
|
||||||
|
<Col span={12}>
|
||||||
|
<Form.Item label="出发地" name="departureName" rules={[{required: true}]}>
|
||||||
|
<Input/>
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
<Col span={12}>
|
||||||
|
<Form.Item label="目的地" name="destinationName" rules={[{required: true}]}>
|
||||||
|
<Input/>
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
|
||||||
|
<Row gutter={18}>
|
||||||
|
<Col span={12}>
|
||||||
|
<Form.Item label="出发票据" name="departureInvoiceId" rules={[{required: true}]}>
|
||||||
|
<SingleInvoiceSelector invoices={[]} pickerOpen={false}
|
||||||
|
pickerTitle={"出发票据"} ref={this.invoiceSelector1}/>
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
<Col span={12}>
|
||||||
|
<Form.Item label="返程票据" name="destinationInvoiceId" rules={[{required: false}]}>
|
||||||
|
<SingleInvoiceSelector invoices={[]} pickerOpen={false}
|
||||||
|
pickerTitle={"返程票据"} ref={this.invoiceSelector2}/>
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
|
||||||
|
<Row gutter={18}>
|
||||||
|
<Col span={12}>
|
||||||
|
<Form.Item label="出差时长" name={"duration"} rules={[{required: true}]}>
|
||||||
|
<InputNumber addonAfter={"天"} min={0} max={1000} disabled={this.state.back}
|
||||||
|
onChange={this.changeDuration}/>
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
<Col span={12}>
|
||||||
|
<Form.Item label="所属部门" name="departmentId" rules={[{required: true}]}>
|
||||||
|
<Dropdown.Button menu={this.state.departmentsProps}
|
||||||
|
buttonsRender={([leftButton, rightButton]) => [
|
||||||
|
<Button>
|
||||||
|
{this.state.selectedDepartment.name}
|
||||||
|
</Button>,
|
||||||
|
React.cloneElement(rightButton as React.ReactElement<any, string>, {loading: false}),
|
||||||
|
]}>
|
||||||
|
</Dropdown.Button>
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
|
||||||
|
<Form.Item label="备注信息" name="note" rules={[{required: false}]}>
|
||||||
|
<Input.TextArea/>
|
||||||
|
</Form.Item>
|
||||||
|
|
||||||
|
</Form>
|
||||||
|
</Modal>)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ReimbursementCreate;
|
Loading…
Reference in New Issue