Merge remote-tracking branch 'origin/main'
commit
2b3b45835a
|
@ -26,30 +26,30 @@ import React, {
|
||||||
useEffect,
|
useEffect,
|
||||||
ReactNode
|
ReactNode
|
||||||
} from "react";
|
} from "react";
|
||||||
import {InvoiceDetail, InvoiceSearchOption} from "../../../models/Invoice"
|
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";
|
||||||
import axiosInstance, {baseUrl} from "../../../utils/axiosInstance";
|
import axiosInstance, {baseUrl} from "../../utils/axiosInstance";
|
||||||
import {Simulate} from "react-dom/test-utils";
|
import {Simulate} from "react-dom/test-utils";
|
||||||
import change = Simulate.change;
|
import change = Simulate.change;
|
||||||
import {useNavigate, useSearchParams} from "react-router-dom";
|
import {useNavigate, useSearchParams} from "react-router-dom";
|
||||||
import {useAppDispatch} from "../../../models/hooks";
|
|
||||||
import InvoiceUploadView from "./InvoiceUploadView";
|
|
||||||
import {
|
import {
|
||||||
Invoice,
|
Invoice,
|
||||||
invoiceItemsMap,
|
invoiceItemsMap,
|
||||||
invoiceTypeExtraItemsMap,
|
invoiceTypeExtraItemsMap,
|
||||||
invoiceTypeItemsMap,
|
invoiceTypeItemsMap,
|
||||||
invoiceTypeNameMap
|
invoiceTypeNameMap
|
||||||
} from "../../../models/Invoice";
|
} from "../../models/Invoice";
|
||||||
import {RadioButtonProps} from "antd/es/radio/radioButton";
|
import {RadioButtonProps} from "antd/es/radio/radioButton";
|
||||||
import qs from "qs";
|
import qs from "qs";
|
||||||
import InvoiceDetailModal from "../InvoiceDetailModal";
|
import InvoiceDetailModal from "./InvoiceDetailModal";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import {store} from "../../../models/store";
|
import {store} from "../../models/store";
|
||||||
|
import InvoiceUploadView from "./mine/InvoiceUploadView";
|
||||||
|
|
||||||
|
|
||||||
|
const {Text, Paragraph} = Typography;
|
||||||
const {Meta} = Card;
|
const {Meta} = Card;
|
||||||
const {Search} = Input;
|
const {Search} = Input;
|
||||||
const {Option} = Select
|
const {Option} = Select
|
||||||
|
@ -63,7 +63,7 @@ const rangeConfig = {
|
||||||
rules: [{type: 'array' as const, required: false, message: 'Please select time!'}],
|
rules: [{type: 'array' as const, required: false, message: 'Please select time!'}],
|
||||||
};
|
};
|
||||||
|
|
||||||
function InvoiceSearch(props: { handleSearchData: any; }) {
|
function InvoiceSearch(props: { isManagement: boolean, handleSearchData: any }) {
|
||||||
const {
|
const {
|
||||||
token: {colorBgContainer, colorPrimary},
|
token: {colorBgContainer, colorPrimary},
|
||||||
} = theme.useToken();
|
} = theme.useToken();
|
||||||
|
@ -75,7 +75,7 @@ function InvoiceSearch(props: { handleSearchData: any; }) {
|
||||||
const items: MenuProps['items'] = [
|
const items: MenuProps['items'] = [
|
||||||
{
|
{
|
||||||
key: '1',
|
key: '1',
|
||||||
label: (<a className="simpleSearchOption" onClick={() => {
|
label: (<a onClick={() => {
|
||||||
invoiceSearchOption.clear();
|
invoiceSearchOption.clear();
|
||||||
setActivatedOption("发票代码")
|
setActivatedOption("发票代码")
|
||||||
}}>
|
}}>
|
||||||
|
@ -84,13 +84,33 @@ function InvoiceSearch(props: { handleSearchData: any; }) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: '2',
|
key: '2',
|
||||||
label: (<a className="simpleSearchOption" onClick={() => {
|
label: (<a onClick={() => {
|
||||||
invoiceSearchOption.clear();
|
invoiceSearchOption.clear();
|
||||||
setActivatedOption("发票编号")
|
setActivatedOption("发票编号")
|
||||||
|
|
||||||
}}>
|
}}>
|
||||||
发票编号
|
发票编号
|
||||||
</a>)
|
</a>)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: '3',
|
||||||
|
label: (<a onClick={() => {
|
||||||
|
invoiceSearchOption.clear();
|
||||||
|
setActivatedOption("上传者姓名")
|
||||||
|
|
||||||
|
}}>
|
||||||
|
上传者姓名
|
||||||
|
</a>)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: '4',
|
||||||
|
label: (<a onClick={() => {
|
||||||
|
invoiceSearchOption.clear();
|
||||||
|
setActivatedOption("上传者工号")
|
||||||
|
|
||||||
|
}}>
|
||||||
|
上传者工号
|
||||||
|
</a>)
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
const onValuesChange = (changedValues: any, allValues: any) => {
|
const onValuesChange = (changedValues: any, allValues: any) => {
|
||||||
|
@ -121,12 +141,23 @@ function InvoiceSearch(props: { handleSearchData: any; }) {
|
||||||
if (!complexEnabled)
|
if (!complexEnabled)
|
||||||
invoiceSearchOption.clear()
|
invoiceSearchOption.clear()
|
||||||
console.log(invoiceSearchOption)
|
console.log(invoiceSearchOption)
|
||||||
if (activatedOption === "发票代码") {
|
invoiceSearchOption.invoiceCode = null
|
||||||
invoiceSearchOption.invoiceCode = value;
|
invoiceSearchOption.invoiceNo = null
|
||||||
invoiceSearchOption.invoiceNo = null;
|
invoiceSearchOption.invoiceUploaderNameFuzzy = null
|
||||||
} else {
|
invoiceSearchOption.invoiceUploaderIdFuzzy = null
|
||||||
invoiceSearchOption.invoiceNo = value;
|
switch (activatedOption) {
|
||||||
invoiceSearchOption.invoiceCode = null;
|
case "发票代码":
|
||||||
|
invoiceSearchOption.invoiceCode = value
|
||||||
|
break;
|
||||||
|
case "发票编号":
|
||||||
|
invoiceSearchOption.invoiceNo = value
|
||||||
|
break;
|
||||||
|
case "上传者姓名":
|
||||||
|
invoiceSearchOption.invoiceUploaderNameFuzzy = value
|
||||||
|
break;
|
||||||
|
case "上传者工号":
|
||||||
|
invoiceSearchOption.invoiceUploaderIdFuzzy = value
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
props.handleSearchData(invoiceSearchOption)
|
props.handleSearchData(invoiceSearchOption)
|
||||||
|
@ -154,7 +185,7 @@ function InvoiceSearch(props: { handleSearchData: any; }) {
|
||||||
<Search className="simpleSearch"
|
<Search className="simpleSearch"
|
||||||
addonBefore={<Dropdown
|
addonBefore={<Dropdown
|
||||||
menu={{
|
menu={{
|
||||||
items,
|
items: props.isManagement ? items : items.slice(0, 2),
|
||||||
selectable: true,
|
selectable: true,
|
||||||
defaultSelectedKeys: ['1'],
|
defaultSelectedKeys: ['1'],
|
||||||
}}
|
}}
|
||||||
|
@ -175,7 +206,9 @@ function InvoiceSearch(props: { handleSearchData: any; }) {
|
||||||
<Checkbox onChange={(e) => {
|
<Checkbox onChange={(e) => {
|
||||||
setComplexEnabled(e.target.checked)
|
setComplexEnabled(e.target.checked)
|
||||||
}}>高级搜索</Checkbox>
|
}}>高级搜索</Checkbox>
|
||||||
<InvoiceUploadView needRefresh={()=>{props.handleSearchData(invoiceSearchOption)}} />
|
{!props.isManagement && <InvoiceUploadView needRefresh={() => {
|
||||||
|
props.handleSearchData(invoiceSearchOption)
|
||||||
|
}}/>}
|
||||||
</div>
|
</div>
|
||||||
{complexEnabled &&
|
{complexEnabled &&
|
||||||
<div className="complexSearchBar" style={{
|
<div className="complexSearchBar" style={{
|
||||||
|
@ -225,7 +258,7 @@ function InvoiceSearch(props: { handleSearchData: any; }) {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function InvoiceItem(props: { invoice: Invoice, onClick(invoice: Invoice): void }) {
|
function InvoiceItem(props: { invoice: Invoice, onClick(invoice: Invoice): void, showUploader?: boolean }) {
|
||||||
const {
|
const {
|
||||||
token: {colorBgContainer, colorPrimary, colorSuccess, colorWarning},
|
token: {colorBgContainer, colorPrimary, colorSuccess, colorWarning},
|
||||||
} = theme.useToken();
|
} = theme.useToken();
|
||||||
|
@ -237,7 +270,8 @@ function InvoiceItem(props: { invoice: Invoice, onClick(invoice: Invoice): void
|
||||||
<div style={{
|
<div style={{
|
||||||
margin: 30
|
margin: 30
|
||||||
}}>
|
}}>
|
||||||
<Badge.Ribbon color={['#00000000', colorPrimary, colorSuccess][props.invoice.invoiceState]} text={['', '报销中', '已报销'][props.invoice.invoiceState]}>
|
<Badge.Ribbon color={['#00000000', colorPrimary, colorSuccess][props.invoice.invoiceState]}
|
||||||
|
text={['', '报销中', '已报销'][props.invoice.invoiceState]}>
|
||||||
<Card
|
<Card
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
hoverable
|
hoverable
|
||||||
|
@ -253,11 +287,32 @@ function InvoiceItem(props: { invoice: Invoice, onClick(invoice: Invoice): void
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<div style={{marginTop: -20}}>
|
<div style={{marginTop: -20}}>
|
||||||
<li style={{
|
<div style={{
|
||||||
|
height: 32,
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
alignItems: 'center'
|
||||||
|
}}>
|
||||||
|
<Text style={{
|
||||||
fontWeight: "bold",
|
fontWeight: "bold",
|
||||||
fontSize: 20
|
fontSize: 20
|
||||||
}}>¥{(props.invoice.invoiceAmount / 100.0).toFixed(2)}</li>
|
}}>¥{(props.invoice.invoiceAmount / 100.0).toFixed(2)}</Text>
|
||||||
<li>{invoiceTypeNameMap.get(props.invoice.invoiceKind)}</li>
|
<Text style={{
|
||||||
|
fontWeight: "bold",
|
||||||
|
fontSize: 16
|
||||||
|
}}>{props.showUploader ? 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.showUploader ? props.invoice.invoiceUploader.staffId : ''}</Text>
|
||||||
|
</div>
|
||||||
<li>{props.invoice.invoiceNo}</li>
|
<li>{props.invoice.invoiceNo}</li>
|
||||||
<li>{props.invoice.invoiceDate}</li>
|
<li>{props.invoice.invoiceDate}</li>
|
||||||
</div>
|
</div>
|
||||||
|
@ -271,7 +326,7 @@ function InvoiceItem(props: { invoice: Invoice, onClick(invoice: Invoice): void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function InvoiceListView(props: {}) {
|
function InvoiceListView(props: { isManagement: boolean }) {
|
||||||
const [totalNum, setTotalNum] = useState(0)
|
const [totalNum, setTotalNum] = useState(0)
|
||||||
const [invoices, setInvoices] = useState([] as any[])
|
const [invoices, setInvoices] = useState([] as any[])
|
||||||
const [search, setSearch] = useSearchParams()
|
const [search, setSearch] = useSearchParams()
|
||||||
|
@ -300,9 +355,8 @@ function InvoiceListView(props: {}) {
|
||||||
params.pageSize = Number(search.get('pageSize'))
|
params.pageSize = Number(search.get('pageSize'))
|
||||||
else
|
else
|
||||||
params.pageSize = 10
|
params.pageSize = 10
|
||||||
|
if (!props.isManagement)
|
||||||
params.invoiceUploaderId = store.getState().token.staffId
|
params.invoiceUploaderId = store.getState().token.staffId
|
||||||
|
|
||||||
axiosInstance({
|
axiosInstance({
|
||||||
url: 'common/invoice?' + qs.stringify(params, {skipNulls: true, arrayFormat: 'indices'}),
|
url: 'common/invoice?' + qs.stringify(params, {skipNulls: true, arrayFormat: 'indices'}),
|
||||||
method: 'get',
|
method: 'get',
|
||||||
|
@ -316,7 +370,7 @@ function InvoiceListView(props: {}) {
|
||||||
}
|
}
|
||||||
const onChange = (pageCurrentNum: Number, pageCurrentSize: Number) => {
|
const onChange = (pageCurrentNum: Number, pageCurrentSize: Number) => {
|
||||||
console.log(pageCurrentNum, pageCurrentSize)
|
console.log(pageCurrentNum, pageCurrentSize)
|
||||||
navigate('/invoice/mine?currentPage=' + pageCurrentNum + '&pageSize=' + pageCurrentSize)
|
navigate('?currentPage=' + pageCurrentNum + '&pageSize=' + pageCurrentSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
const onItemClick = (invoice: Invoice) => {
|
const onItemClick = (invoice: Invoice) => {
|
||||||
|
@ -333,7 +387,6 @@ function InvoiceListView(props: {}) {
|
||||||
}).catch(function (error) {
|
}).catch(function (error) {
|
||||||
console.log(error)
|
console.log(error)
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -345,11 +398,12 @@ function InvoiceListView(props: {}) {
|
||||||
console.log(invoices)
|
console.log(invoices)
|
||||||
return (
|
return (
|
||||||
<div style={{}}>
|
<div style={{}}>
|
||||||
<InvoiceSearch handleSearchData={handleInvoiceSearchInfo}/>
|
<InvoiceSearch isManagement={props.isManagement} handleSearchData={handleInvoiceSearchInfo}/>
|
||||||
<div style={{padding: 26, display: "flex", flexDirection: "column", alignItems: "flex-end"}}>
|
<div style={{padding: '10px 30px 30px 30px', 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 onClick={onItemClick} invoice={item} key={index}/>
|
<InvoiceItem showUploader={props.isManagement} onClick={onItemClick} invoice={item}
|
||||||
|
key={index}/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<Pagination showSizeChanger
|
<Pagination showSizeChanger
|
||||||
|
@ -359,9 +413,11 @@ function InvoiceListView(props: {}) {
|
||||||
pageSize={Number(search.get('pageSize') ? search.get('pageSize') : 10)}
|
pageSize={Number(search.get('pageSize') ? search.get('pageSize') : 10)}
|
||||||
total={totalNum} onChange={onChange}/>
|
total={totalNum} onChange={onChange}/>
|
||||||
</div>
|
</div>
|
||||||
<InvoiceDetailModal needRefresh={()=>{searchInvoiceContent(invoiceSearchOption)}} invoiceDetail={invoiceDetail} open={detailModalOpen} onClose={() => {
|
<InvoiceDetailModal needRefresh={() => {
|
||||||
|
searchInvoiceContent(invoiceSearchOption)
|
||||||
|
}} invoiceDetail={invoiceDetail} open={detailModalOpen} onClose={() => {
|
||||||
setDetailModalOpen(false)
|
setDetailModalOpen(false)
|
||||||
}}/>
|
}} showFooter={true}/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
)
|
)
|
|
@ -1,404 +1,7 @@
|
||||||
import {
|
import InvoiceListView from "../InvoiceListView";
|
||||||
Card,
|
|
||||||
Dropdown,
|
|
||||||
List,
|
|
||||||
Row,
|
|
||||||
Input,
|
|
||||||
Button,
|
|
||||||
Radio,
|
|
||||||
Col,
|
|
||||||
Divider,
|
|
||||||
DatePicker,
|
|
||||||
Form,
|
|
||||||
TimePicker,
|
|
||||||
Select,
|
|
||||||
Checkbox,
|
|
||||||
Pagination, theme, Tag, Badge
|
|
||||||
} from "antd";
|
|
||||||
import type {MenuProps, PaginationProps} from 'antd';
|
|
||||||
import {DownOutlined, UploadOutlined} from '@ant-design/icons';
|
|
||||||
import React, {
|
|
||||||
ReactElement,
|
|
||||||
JSXElementConstructor,
|
|
||||||
ReactFragment,
|
|
||||||
ReactPortal,
|
|
||||||
useState,
|
|
||||||
useEffect,
|
|
||||||
ReactNode
|
|
||||||
} from "react";
|
|
||||||
import {InvoiceDetail, InvoiceSearchOption} from "../../../models/Invoice"
|
|
||||||
import {Space, Typography} from 'antd';
|
|
||||||
import {SizeType} from "antd/es/config-provider/SizeContext";
|
|
||||||
import axios from "axios";
|
|
||||||
import axiosInstance, {baseUrl} from "../../../utils/axiosInstance";
|
|
||||||
import {Simulate} from "react-dom/test-utils";
|
|
||||||
import change = Simulate.change;
|
|
||||||
import {useNavigate, useSearchParams} from "react-router-dom";
|
|
||||||
import {useAppDispatch} from "../../../models/hooks";
|
|
||||||
import {
|
|
||||||
Invoice,
|
|
||||||
invoiceItemsMap,
|
|
||||||
invoiceTypeExtraItemsMap,
|
|
||||||
invoiceTypeItemsMap,
|
|
||||||
invoiceTypeNameMap
|
|
||||||
} from "../../../models/Invoice";
|
|
||||||
import {RadioButtonProps} from "antd/es/radio/radioButton";
|
|
||||||
import qs from "qs";
|
|
||||||
import InvoiceDetailModal from "../InvoiceDetailModal";
|
|
||||||
import dayjs from "dayjs";
|
|
||||||
|
|
||||||
|
|
||||||
const {Text, Paragraph} = Typography;
|
|
||||||
const {Meta} = Card;
|
|
||||||
const {Search} = Input;
|
|
||||||
const {Option} = Select
|
|
||||||
let invoices: Array<Invoice>
|
|
||||||
const {RangePicker} = DatePicker;
|
|
||||||
|
|
||||||
const config = {
|
|
||||||
rules: [{type: 'object' as const, required: false, message: 'Please select time!'}],
|
|
||||||
};
|
|
||||||
const rangeConfig = {
|
|
||||||
rules: [{type: 'array' as const, required: false, message: 'Please select time!'}],
|
|
||||||
};
|
|
||||||
|
|
||||||
function InvoiceSearch(props: { handleSearchData: any; }) {
|
|
||||||
const {
|
|
||||||
token: {colorBgContainer, colorPrimary},
|
|
||||||
} = theme.useToken();
|
|
||||||
|
|
||||||
const [activatedOption, setActivatedOption] = useState('发票代码')
|
|
||||||
const [complexEnabled, setComplexEnabled] = useState(false)
|
|
||||||
const [invoiceSearchOption, setInvoiceSearchOption] = useState(new InvoiceSearchOption())
|
|
||||||
|
|
||||||
const items: MenuProps['items'] = [
|
|
||||||
{
|
|
||||||
key: '1',
|
|
||||||
label: (<a onClick={() => {
|
|
||||||
invoiceSearchOption.clear();
|
|
||||||
setActivatedOption("发票代码")
|
|
||||||
}}>
|
|
||||||
发票代码
|
|
||||||
</a>)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: '2',
|
|
||||||
label: (<a onClick={() => {
|
|
||||||
invoiceSearchOption.clear();
|
|
||||||
setActivatedOption("发票编号")
|
|
||||||
|
|
||||||
}}>
|
|
||||||
发票编号
|
|
||||||
</a>)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: '3',
|
|
||||||
label: (<a onClick={() => {
|
|
||||||
invoiceSearchOption.clear();
|
|
||||||
setActivatedOption("上传者姓名")
|
|
||||||
|
|
||||||
}}>
|
|
||||||
上传者姓名
|
|
||||||
</a>)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: '4',
|
|
||||||
label: (<a 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)
|
|
||||||
invoiceSearchOption.invoiceCode = null
|
|
||||||
invoiceSearchOption.invoiceNo = null
|
|
||||||
invoiceSearchOption.invoiceUploaderNameFuzzy = null
|
|
||||||
invoiceSearchOption.invoiceUploaderIdFuzzy = null
|
|
||||||
switch (activatedOption) {
|
|
||||||
case "发票代码":
|
|
||||||
invoiceSearchOption.invoiceCode = value
|
|
||||||
break;
|
|
||||||
case "发票编号":
|
|
||||||
invoiceSearchOption.invoiceNo = value
|
|
||||||
break;
|
|
||||||
case "上传者姓名":
|
|
||||||
invoiceSearchOption.invoiceUploaderNameFuzzy = value
|
|
||||||
break;
|
|
||||||
case "上传者工号":
|
|
||||||
invoiceSearchOption.invoiceUploaderIdFuzzy = value
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
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: {}) {
|
function InvoiceManagement(props: {}) {
|
||||||
const [totalNum, setTotalNum] = useState(0)
|
return <InvoiceListView isManagement={true}/>
|
||||||
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
|
|
@ -0,0 +1,6 @@
|
||||||
|
import InvoiceListView from "../InvoiceListView";
|
||||||
|
|
||||||
|
function MyInvoice() {
|
||||||
|
return <InvoiceListView isManagement={false}/>
|
||||||
|
}
|
||||||
|
export default MyInvoice
|
|
@ -1,5 +1,5 @@
|
||||||
import React from "react";
|
import React, {useRef, useState} from "react";
|
||||||
import {Button, Popover, Tabs} from "antd";
|
import {Button, Popover, Tabs, TabsProps, theme} from "antd";
|
||||||
import {ActionType, ProColumns, ProTable} from "@ant-design/pro-components";
|
import {ActionType, ProColumns, ProTable} from "@ant-design/pro-components";
|
||||||
import Search from "antd/es/input/Search";
|
import Search from "antd/es/input/Search";
|
||||||
import {statusEnum} from "../mine/MyReimbursement";
|
import {statusEnum} from "../mine/MyReimbursement";
|
||||||
|
@ -278,7 +278,7 @@ class ReimbursementTab extends React.Component<any, any> {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return <>
|
return <div style={{padding: 30}}>
|
||||||
<ReimbursementDetail reimbursement={this.state.detailedReimbursement}
|
<ReimbursementDetail reimbursement={this.state.detailedReimbursement}
|
||||||
closeDetail={this.closeDetail}
|
closeDetail={this.closeDetail}
|
||||||
accessLevel={this.props.accessLevel}
|
accessLevel={this.props.accessLevel}
|
||||||
|
@ -308,55 +308,62 @@ class ReimbursementTab extends React.Component<any, any> {
|
||||||
// </Button>,
|
// </Button>,
|
||||||
// ]}
|
// ]}
|
||||||
/>
|
/>
|
||||||
</>;
|
</div>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ReimbursementApproval extends React.Component<any, any> {
|
function ReimbursementApproval() {
|
||||||
ref = [React.createRef<ReimbursementTab>(), React.createRef<ReimbursementTab>(), React.createRef<ReimbursementTab>()]
|
const [activatedTab, setActivatedTab] = useState(0)
|
||||||
|
const {
|
||||||
constructor(props: any) {
|
token: {colorBgContainer},
|
||||||
super(props);
|
} = theme.useToken();
|
||||||
this.state = {
|
const tabItems = () => {
|
||||||
activatedTab: 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tabItems = () => {
|
|
||||||
return [{
|
return [{
|
||||||
label: "等待审批",
|
label: "等待审批",
|
||||||
key: "0",
|
key: "0",
|
||||||
children: <ReimbursementTab ref={this.ref[0]} mode={0} activate={this.state.activatedTab === 0}
|
children: <ReimbursementTab key={0} mode={0} activate={activatedTab === 0}
|
||||||
accessLevel={1}/>
|
accessLevel={1}/>
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "审批历史",
|
label: "审批历史",
|
||||||
key: "1",
|
key: "1",
|
||||||
children: <ReimbursementTab ref={this.ref[1]} mode={1} activate={this.state.activatedTab === 1}
|
children: <ReimbursementTab key={1} mode={1} activate={activatedTab === 1}
|
||||||
accessLevel={-1}/>
|
accessLevel={-1}/>
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "全部记录",
|
label: "全部记录",
|
||||||
key: "2",
|
key: "2",
|
||||||
children: <ReimbursementTab ref={this.ref[2]} mode={2} activate={this.state.activatedTab === 2}
|
children: <ReimbursementTab key={2} mode={2} activate={activatedTab === 2}
|
||||||
accessLevel={-1}/>
|
accessLevel={-1}/>
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
tabChange = (key: string) => {
|
const tabChange = (key: string) => {
|
||||||
this.setState({activatedTab: Number(key)})
|
setActivatedTab(Number(key))
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
const renderTabBar: TabsProps['renderTabBar'] = (props, DefaultTabBar) => (
|
||||||
|
<div style={{
|
||||||
|
paddingLeft: 30,
|
||||||
|
height: 72,
|
||||||
|
background: colorBgContainer,
|
||||||
|
display: "flex",
|
||||||
|
alignItems: 'flex-end'
|
||||||
|
}}>
|
||||||
|
<DefaultTabBar {...props} style={{marginBottom: 0, height: 64}}/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tabs
|
<Tabs
|
||||||
style={{backgroundColor: "white",paddingLeft:10}}
|
activeKey={activatedTab.toString()}
|
||||||
activeKey={this.state.activatedTab.toString()}
|
onChange={tabChange}
|
||||||
onChange={this.tabChange}
|
renderTabBar={renderTabBar}
|
||||||
type="line"
|
type="line"
|
||||||
items={this.tabItems()}
|
items={tabItems()}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default ReimbursementApproval
|
export default ReimbursementApproval
|
|
@ -373,13 +373,19 @@ class Subpage extends React.Component<any, any> {
|
||||||
// },
|
// },
|
||||||
// },
|
// },
|
||||||
// }}
|
// }}
|
||||||
|
tableRender={(_, dom) => (
|
||||||
|
<div style={{margin: 30}}>
|
||||||
|
{dom}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
search={{
|
search={{
|
||||||
defaultCollapsed: false,
|
defaultCollapsed: false,
|
||||||
labelWidth: 'auto',
|
labelWidth: 'auto',
|
||||||
optionRender: ({searchText}, {form}, dom) => {
|
optionRender: ({searchText}, {form}, dom) => {
|
||||||
// console.log(searchConfig, formProps, dom)
|
// console.log(searchConfig, formProps, dom)
|
||||||
return [
|
return [
|
||||||
<div style={{flexWrap: "nowrap", display: "flex", justifyContent: "flex-end"}}>
|
<div style={{flexWrap: "nowrap", display: "flex", justifyContent: "flex-end", marginRight:6}}>
|
||||||
|
<Space>
|
||||||
<Search className="searchBar"
|
<Search className="searchBar"
|
||||||
addonBefore={"报销单号:"}
|
addonBefore={"报销单号:"}
|
||||||
placeholder={""}
|
placeholder={""}
|
||||||
|
@ -394,6 +400,7 @@ class Subpage extends React.Component<any, any> {
|
||||||
style={{width: 100}}>
|
style={{width: 100}}>
|
||||||
新建报销单
|
新建报销单
|
||||||
</Button>
|
</Button>
|
||||||
|
</Space>
|
||||||
</div>
|
</div>
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,7 +84,6 @@ function HorizontalBarChart(props: { title: string, values: number[], labels: st
|
||||||
},
|
},
|
||||||
series: [
|
series: [
|
||||||
{
|
{
|
||||||
name: 'Direct',
|
|
||||||
type: 'bar',
|
type: 'bar',
|
||||||
colorBy: 'data',
|
colorBy: 'data',
|
||||||
emphasis: {
|
emphasis: {
|
||||||
|
@ -96,46 +95,9 @@ function HorizontalBarChart(props: { title: string, values: number[], labels: st
|
||||||
}} notMerge={true} lazyUpdate={true}/>
|
}} notMerge={true} lazyUpdate={true}/>
|
||||||
}
|
}
|
||||||
|
|
||||||
var mMapData =
|
|
||||||
[
|
|
||||||
{from: '青海省', to: '青海省', value: 90},
|
|
||||||
{from: '青海省', to: '安徽省', value: 80},
|
|
||||||
{from: '青海省', to: '甘肃省', value: 70},
|
|
||||||
{from: '青海省', to: '宁夏省', value: 60},
|
|
||||||
{from: '青海省', to: '山西省', value: 50},
|
|
||||||
{from: '青海省', to: '陕西省', value: 40},
|
|
||||||
{from: '青海省', to: '广东省', value: 30},
|
|
||||||
{from: '青海省', to: '重庆省', value: 20},
|
|
||||||
{from: '青海省', to: '西藏省', value: 10}
|
|
||||||
];
|
|
||||||
|
|
||||||
var convertLineData = function (data: { from: string, to: string, value: number }[]) {
|
|
||||||
var res = [];
|
|
||||||
|
|
||||||
for (var i = 0; i < data.length; i++) {
|
|
||||||
var dataItem = data[i];
|
|
||||||
// @ts-ignore
|
|
||||||
var fromCoord = GeoCoordMap[dataItem.from];
|
|
||||||
// @ts-ignore
|
|
||||||
var toCoord = GeoCoordMap[dataItem.to];
|
|
||||||
|
|
||||||
if (fromCoord && toCoord) {
|
|
||||||
res.push(
|
|
||||||
{
|
|
||||||
fromName: dataItem.from,
|
|
||||||
toName: dataItem.to,
|
|
||||||
coords: [fromCoord, toCoord],
|
|
||||||
value: dataItem.value,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
};
|
|
||||||
|
|
||||||
function StatView() {
|
function StatView() {
|
||||||
const {
|
const {
|
||||||
token: {colorBgContainer, colorPrimary, colorSuccess},
|
token: {colorBgContainer, colorPrimary, colorSuccess, colorBorder},
|
||||||
} = theme.useToken();
|
} = theme.useToken();
|
||||||
|
|
||||||
const [type, setType] = useState<StatType>('month');
|
const [type, setType] = useState<StatType>('month');
|
||||||
|
@ -400,7 +362,11 @@ function StatView() {
|
||||||
return geoCoordMap.find(([name,]) => name.includes(placeName))
|
return geoCoordMap.find(([name,]) => name.includes(placeName))
|
||||||
}
|
}
|
||||||
|
|
||||||
let mapDataTemp: { fromName: string, toName: string, coords: any[], value: number }[] = []
|
let maxValue = 0
|
||||||
|
for (const item of statResponse.reimbursementPlaceStats) {
|
||||||
|
maxValue = Math.max(maxValue, item.reimbursementLaunchCount)
|
||||||
|
}
|
||||||
|
let mapDataTemp: any[] = []
|
||||||
let departures = new Map<string, number>()
|
let departures = new Map<string, number>()
|
||||||
let destinations = new Map<string, number>()
|
let destinations = new Map<string, number>()
|
||||||
for (const item of statResponse.reimbursementPlaceStats) {
|
for (const item of statResponse.reimbursementPlaceStats) {
|
||||||
|
@ -421,10 +387,13 @@ function StatView() {
|
||||||
|
|
||||||
if (fromCoords && toCoords) {
|
if (fromCoords && toCoords) {
|
||||||
mapDataTemp.push({
|
mapDataTemp.push({
|
||||||
"fromName": fromCoords[0],
|
fromName: fromCoords[0],
|
||||||
"toName": toCoords[0],
|
toName: toCoords[0],
|
||||||
"coords": [fromCoords[1], toCoords[1]],
|
coords: [fromCoords[1], toCoords[1]],
|
||||||
"value": item.reimbursementLaunchCount,
|
value: item.reimbursementLaunchCount,
|
||||||
|
lineStyle: {
|
||||||
|
width: item.reimbursementLaunchCount / maxValue * 10
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -676,6 +645,19 @@ function StatView() {
|
||||||
text: '差旅去向',
|
text: '差旅去向',
|
||||||
left: 'center',
|
left: 'center',
|
||||||
},
|
},
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'item',
|
||||||
|
formatter: function (params: any) {
|
||||||
|
let returnStr = '';
|
||||||
|
if (params.componentSubType == 'lines') {
|
||||||
|
returnStr += params.marker;
|
||||||
|
returnStr += params.data.fromName + ' → ' + params.data.toName;
|
||||||
|
returnStr += ':' + params.data.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnStr;
|
||||||
|
}
|
||||||
|
},
|
||||||
geo: {
|
geo: {
|
||||||
map: 'china',
|
map: 'china',
|
||||||
emphasis: {
|
emphasis: {
|
||||||
|
@ -685,8 +667,8 @@ function StatView() {
|
||||||
disabled: true
|
disabled: true
|
||||||
},
|
},
|
||||||
itemStyle: {
|
itemStyle: {
|
||||||
areaColor: '#d4e2fd',
|
areaColor: colorBorder,
|
||||||
borderColor: '#8c8c8c'
|
borderColor: colorBgContainer
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
series: [
|
series: [
|
||||||
|
@ -695,10 +677,21 @@ function StatView() {
|
||||||
zlevel: 2,
|
zlevel: 2,
|
||||||
lineStyle: {
|
lineStyle: {
|
||||||
normal: {
|
normal: {
|
||||||
color: '#',
|
color: {
|
||||||
width: 3,
|
type: 'linear',
|
||||||
opacity: 0.2,
|
x: 0,
|
||||||
curveness: .3
|
y: 0,
|
||||||
|
x2: 1,
|
||||||
|
y2: 1,
|
||||||
|
colorStops: [{
|
||||||
|
offset: 0, color: '#6395f9'
|
||||||
|
}, {
|
||||||
|
offset: 1, color: '#62daab'
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
opacity: 0.5,
|
||||||
|
curveness: .3,
|
||||||
|
cap: 'round'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data: mapData
|
data: mapData
|
||||||
|
|
|
@ -2,13 +2,14 @@ import {Routes, Route} from "react-router-dom";
|
||||||
import {createBrowserHistory} from "history";
|
import {createBrowserHistory} from "history";
|
||||||
import LoginView from "../pages/login/LoginView";
|
import LoginView from "../pages/login/LoginView";
|
||||||
import HomeView from "../pages/HomeView";
|
import HomeView from "../pages/HomeView";
|
||||||
import InvoiceListView from "../pages/Invoice/mine/InvoiceListView";
|
import InvoiceListView from "../pages/Invoice/InvoiceListView";
|
||||||
import MyReimbursement from "../pages/reimbursement/mine/MyReimbursement";
|
import MyReimbursement from "../pages/reimbursement/mine/MyReimbursement";
|
||||||
import {BrowserRouter} from "./BrowserRouter"
|
import {BrowserRouter} from "./BrowserRouter"
|
||||||
import InvoiceManagement from "../pages/Invoice/management/InvoiceManagement";
|
import InvoiceManagement from "../pages/Invoice/management/InvoiceManagement";
|
||||||
import ReimbursementApproval from "../pages/reimbursement/approval/ReimbursementApproval";
|
import ReimbursementApproval from "../pages/reimbursement/approval/ReimbursementApproval";
|
||||||
import StatView from "../pages/stat/StatView";
|
import StatView from "../pages/stat/StatView";
|
||||||
import Configuration from "../pages/configuration/Configuration";
|
import Configuration from "../pages/configuration/Configuration";
|
||||||
|
import MyInvoice from "../pages/Invoice/mine/MyInvoice";
|
||||||
|
|
||||||
export const history = createBrowserHistory()
|
export const history = createBrowserHistory()
|
||||||
|
|
||||||
|
@ -17,7 +18,7 @@ function CustomRouter() {
|
||||||
<BrowserRouter history={history}>
|
<BrowserRouter history={history}>
|
||||||
<Routes>
|
<Routes>
|
||||||
<Route path="/" element={<HomeView/>}>
|
<Route path="/" element={<HomeView/>}>
|
||||||
<Route path="invoice/mine" element={<InvoiceListView/>}></Route>
|
<Route path="invoice/mine" element={<MyInvoice/>}></Route>
|
||||||
<Route path="reimbursement/mine" element={<MyReimbursement/>}></Route>
|
<Route path="reimbursement/mine" element={<MyReimbursement/>}></Route>
|
||||||
<Route path="invoice/management" element={<InvoiceManagement/>}></Route>
|
<Route path="invoice/management" element={<InvoiceManagement/>}></Route>
|
||||||
<Route path="reimbursement/approval" element={<ReimbursementApproval/>}></Route>
|
<Route path="reimbursement/approval" element={<ReimbursementApproval/>}></Route>
|
||||||
|
|
Loading…
Reference in New Issue