财务统计接入后端

main
wuyize 2023-01-05 22:39:11 +08:00
parent 0579658b6f
commit 0c91c3d29d
4 changed files with 363 additions and 177 deletions

View File

@ -0,0 +1,64 @@
export interface StaffList {
records: Staff[];
/**
*
*/
total: number;
}
/**
*
*
* Department
*/
export interface Department {
/**
* ID
*/
departmentId: number;
/**
*
*/
departmentManager?: Staff;
/**
*
*/
departmentName?: string;
/**
*
*/
staff?: Staff[];
}
/**
* Staff
*
*
*/
export interface Staff {
banned?: boolean;
/**
*
*/
managingDepartment?: Department;
/**
*
*/
staffBase?: string;
/**
*
*/
staffDepartments?: Department[];
/**
*
*/
staffId: string;
/**
*
*/
staffName: string;
/**
*
*/
staffPassword?: string;
}

View File

@ -1,54 +1,53 @@
import {Tabs} from "antd"; import {Tabs, theme} from "antd";
import React from "react"; import React, {useState} from "react";
import UserConfig from "./subpage/UserConfig"; import UserConfig from "./subpage/UserConfig";
import CityConfig from "./subpage/CityConfig"; import CityConfig from "./subpage/CityConfig";
import DepartmentConfig from "./subpage/DepartmentConfig"; import DepartmentConfig from "./subpage/DepartmentConfig";
import OtherConfig from "./subpage/OtherConfig"; import OtherConfig from "./subpage/OtherConfig";
class Configuration extends React.Component<any,any> { function Configuration() {
const {
constructor(props: any) { token: {colorBgContainer},
super(props); } = theme.useToken();
this.state = { const [activatedTab, setActivatedTab] = useState(0)
activatedTab: 0
}
}
tabItems = () => {
return [{
label: "用户配置",
key: "0",
children: <UserConfig activate={this.state.activatedTab === 0}/>
},
{
label: "城市配置",
key: "1",
children: <CityConfig activate={this.state.activatedTab === 1}/>
},
{
label: "部门配置",
key: "2",
children: <DepartmentConfig activate={this.state.activatedTab === 2}/>
},
{
label: "其他配置",
key: "3",
children:<OtherConfig activate={this.state.activatedTab === 3}/>
}]
}
tabChange = (key: string) => {
this.setState({activatedTab: Number(key)})
}
render() {
return ( return (
<Tabs <Tabs
style={{backgroundColor: "white",paddingLeft:10}}
activeKey={this.state.activatedTab.toString()}
onChange={this.tabChange}
type="line" type="line"
items={this.tabItems()} activeKey={activatedTab.toString()}
onChange={(key: string) => {
setActivatedTab(Number(key))
}}
renderTabBar={(props, DefaultTabBar) => (
<div style={{
paddingLeft: 30,
height: 72,
background: colorBgContainer,
display: "flex",
alignItems: 'flex-end'
}}>
<DefaultTabBar {...props} style={{marginBottom: 0, height: 64}}/>
</div>
)}
items={[{
label: "用户配置",
key: "0",
children: <UserConfig activate={activatedTab === 0}/>
}, {
label: "城市配置",
key: "1",
children: <CityConfig activate={activatedTab === 1}/>
}, {
label: "部门配置",
key: "2",
children: <DepartmentConfig activate={activatedTab === 2}/>
}, {
label: "其他配置",
key: "3",
children: <OtherConfig activate={activatedTab === 3}/>
}]}
/> />
) )
} }
}
export default Configuration; export default Configuration;

View File

@ -1,12 +1,118 @@
import React from "react"; import React, {useEffect, useState} from "react";
import {Button, Space, Table, Tag, Typography} from 'antd';
import type {ColumnsType} from 'antd/es/table';
import {Staff} from "../../../models/UserConfigModels";
import axiosInstance from "../../../utils/axiosInstance";
import {Department} from "../../../models/Staff";
const {Text, Link} = Typography;
function UserConfig(props: any) {
const [departmentMap, setDepartmentMap] = useState(new Map<number, string>())
const departmentToString = (staff: Staff) => {
if (staff.staffId === 'manager')
return '总经理'
let result = !staff.managingDepartment ? '' : departmentMap.get(staff.managingDepartment.departmentId) + '主管'
if (staff.staffDepartments)
for (const department of staff.staffDepartments) {
result += '\xa0\xa0' + departmentMap.get(department.departmentId)
}
return result
}
const columns: ColumnsType<Staff> = [
{
title: '工号',
dataIndex: 'staffId',
key: 'staffId',
},
{
title: '姓名',
dataIndex: 'staffName',
key: 'staffName',
},
{
title: '部门',
dataIndex: 'managingDepartment',
key: 'department',
render: (value, record, index) => <Text>{departmentToString(record)}</Text>,
},
{
title: '',
key: 'action',
render: (_, record) => (
<Space size="middle">
<a></a>
<a></a>
</Space>
),
},
];
const data: Staff[] = [
{
staffId: 'sb123007',
staffName: 'John Brown',
managingDepartment: {
departmentId: 1
},
staffDepartments: [{
departmentId: 1
}]
},
{
staffId: 'sb123008',
staffName: 'John Brown',
managingDepartment: {
departmentId: 1
},
staffDepartments: [{
departmentId: 1
}]
},
{
staffId: 'sb123009',
staffName: 'John Brown',
managingDepartment: {
departmentId: 1
},
staffDepartments: [{
departmentId: 1
}]
},
]
useEffect(() => {
axiosInstance({
url: 'common/department',
method: 'get'
}).then(response => {
const departments: Department[] = response.data
let map = new Map<number, string>()
for (const department of departments)
map.set(department.departmentId, department.departmentName)
setDepartmentMap(map)
}).catch(function (error) {
console.log(error)
})
}, []);
class UserConfig extends React.Component<any,any> {
render() {
return ( return (
<div> <div style={{margin:30}}>
<h1>User Config</h1> <Table columns={columns} dataSource={data}/>
<div style={{position:"absolute", left: 0, top: 0, width: '100%', height: 55, display: "flex", justifyContent:"flex-end", alignItems:"center", paddingRight: 50}}>
<Space>
<Button ></Button>
<Button ></Button>
</Space>
</div> </div>
); </div>
)
} }
}
export default UserConfig; export default UserConfig

View File

@ -100,6 +100,7 @@ function StatView() {
token: {colorBgContainer, colorPrimary, colorSuccess, colorBorder}, token: {colorBgContainer, colorPrimary, colorSuccess, colorBorder},
} = theme.useToken(); } = theme.useToken();
const [selectedTime, setSelectedTime] = useState<Dayjs|null>(null);
const [type, setType] = useState<StatType>('month'); const [type, setType] = useState<StatType>('month');
const [loading, setLoading] = useState(true) const [loading, setLoading] = useState(true)
const [reimbursementAmount, setReimbursementAmount] = useState(0) const [reimbursementAmount, setReimbursementAmount] = useState(0)
@ -124,7 +125,7 @@ function StatView() {
const getStatData = (time: Dayjs | null) => { const getStatData = (time: Dayjs | null) => {
console.log(time) console.log(time)
setLoading(true) setLoading(true)
setSelectedTime(time)
axiosInstance({ axiosInstance({
url: 'common/department', url: 'common/department',
method: 'get' method: 'get'
@ -146,7 +147,143 @@ function StatView() {
dates.push(i + '月') dates.push(i + '月')
} }
setDates(dates) setDates(dates)
setTimeout(() => { axiosInstance({
url: 'financial/stats',
method: 'get',
params: {
yearly: type==='year',
target: time.format('YYYY-MM-DD')
}
}).then(response => {
const statResponse: StatResponse = response.data
setReimbursementAmount(statResponse.reimbursementAllTotalAmount/100.)
setReimbursementAmountTrend(
(statResponse.reimbursementAllTotalAmount - statResponse.lastAllTotalAmount) / statResponse.lastAllTotalAmount)
setReimbursementAdditionalAmount(statResponse.reimbursementAdditionalTotalAmount/100.)
setReimbursementAdditionalAmountTrend(
(statResponse.reimbursementAdditionalTotalAmount - statResponse.lastAdditionalTotalAmount) / statResponse.lastAdditionalTotalAmount)
setAmounts([statResponse.invoiceLaunchCount, statResponse.reimbursementLaunchCount])
setInvoiceKinds(statResponse.invoiceKindsStats.map((item) => {
return {value: item.invoiceLaunchCount, name: invoiceTypeNameMap.get(item.invoiceKind)}
}))
let departmentAmountMap = new Map<number, Map<number, number>>()
departmentMap.forEach(function (value, key, map) {
departmentAmountMap.set(key, new Map<number, number>())
})
for (const temporalDepartmentStat of statResponse.temporalDepartmentStats) {
for (const departmentStat of temporalDepartmentStat.departmentStats) {
let valueMap = departmentAmountMap.get(departmentStat.departmentId)
if (valueMap) {
valueMap.set(temporalDepartmentStat.value, departmentStat.reimbursementAmount)
departmentAmountMap.set(departmentStat.departmentId, valueMap)
}
}
}
let data: { value: number, name: string }[] = []
let series: any = []
departmentAmountMap.forEach(function (valueMap, key, map) {
let departmentName = departmentMap.get(key)
if (!departmentName) return
let total = 0
valueMap.forEach(function (value, key) {
total += value
})
data.push({value: total, name: departmentName})
let valueMapArray = Array.from(valueMap);
valueMapArray.sort(function (a, b) {
return a[0] - b[0]
})
series.push({
name: departmentName,
type: 'line',
stack: 'Total',
areaStyle: {},
emphasis: {
focus: 'series'
},
data: valueMapArray.map(function ([key, value]) {
return value
})
})
})
setDepartmentPieData(data)
setDepartmentSeries(series)
const geoCoordMap = Object.entries(GeoCoordMap)
const getCoords = (placeName: string) => {
return geoCoordMap.find(([name,]) => name.includes(placeName))
}
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 destinations = new Map<string, number>()
for (const item of statResponse.reimbursementPlaceStats) {
let departureValue = departures.get(item.departureName)
if (departureValue)
departures.set(item.departureName, departureValue + item.reimbursementLaunchCount)
else
departures.set(item.departureName, item.reimbursementLaunchCount)
let destinationValue = departures.get(item.destinationName)
if (destinationValue)
destinations.set(item.destinationName, destinationValue + item.reimbursementLaunchCount)
else
destinations.set(item.destinationName, item.reimbursementLaunchCount)
const fromCoords = getCoords(item.departureName)
const toCoords = getCoords(item.destinationName)
if (fromCoords && toCoords) {
mapDataTemp.push({
fromName: fromCoords[0],
toName: toCoords[0],
coords: [fromCoords[1], toCoords[1]],
value: item.reimbursementLaunchCount,
lineStyle: {
width: item.reimbursementLaunchCount / maxValue * 10
}
})
}
}
setMapData(mapDataTemp)
{
let placeNames: string[] = []
let reimbursementCounts: number[] = []
departures.forEach(function (val, key, map) {
placeNames.push(key)
reimbursementCounts.push(val)
})
setDepartureNames(placeNames)
setDepartureValues(reimbursementCounts)
}
{
let placeNames: string[] = []
let reimbursementCounts: number[] = []
destinations.forEach(function (val, key, map) {
placeNames.push(key)
reimbursementCounts.push(val)
})
setDestinationNames(placeNames)
setDestinationValues(reimbursementCounts)
}
setLoading(false)
}).catch(function (error) {
console.log(error)
})
/* setTimeout(() => {
let statResponse: StatResponse = { let statResponse: StatResponse = {
"temporalDepartmentStats": [ "temporalDepartmentStats": [
{ {
@ -296,131 +433,8 @@ function StatView() {
} }
] ]
} }
setReimbursementAmount(statResponse.reimbursementAllTotalAmount)
setReimbursementAmountTrend(
(statResponse.reimbursementAllTotalAmount - statResponse.lastAllTotalAmount) / statResponse.lastAllTotalAmount)
setReimbursementAdditionalAmount(statResponse.reimbursementAdditionalTotalAmount)
setReimbursementAdditionalAmountTrend(
(statResponse.reimbursementAdditionalTotalAmount - statResponse.lastAdditionalTotalAmount) / statResponse.lastAdditionalTotalAmount)
setAmounts([statResponse.invoiceLaunchCount, statResponse.reimbursementLaunchCount]) }, 1000);*/
setInvoiceKinds(statResponse.invoiceKindsStats.map((item) => {
return {value: item.invoiceLaunchCount, name: invoiceTypeNameMap.get(item.invoiceKind)}
}))
let departmentAmountMap = new Map<number, Map<number, number>>()
departmentMap.forEach(function (value, key, map) {
departmentAmountMap.set(key, new Map<number, number>())
})
for (const temporalDepartmentStat of statResponse.temporalDepartmentStats) {
for (const departmentStat of temporalDepartmentStat.departmentStats) {
let valueMap = departmentAmountMap.get(departmentStat.departmentId)
if (valueMap) {
valueMap.set(temporalDepartmentStat.value, departmentStat.reimbursementAmount)
departmentAmountMap.set(departmentStat.departmentId, valueMap)
}
}
}
let data: { value: number, name: string }[] = []
let series: any = []
departmentAmountMap.forEach(function (valueMap, key, map) {
let departmentName = departmentMap.get(key)
if (!departmentName) return
let total = 0
valueMap.forEach(function (value, key) {
total += value
})
data.push({value: total, name: departmentName})
let valueMapArray = Array.from(valueMap);
valueMapArray.sort(function (a, b) {
return a[0] - b[0]
})
series.push({
name: departmentName,
type: 'line',
stack: 'Total',
areaStyle: {},
emphasis: {
focus: 'series'
},
data: valueMapArray.map(function ([key, value]) {
return value
})
})
})
setDepartmentPieData(data)
setDepartmentSeries(series)
const geoCoordMap = Object.entries(GeoCoordMap)
const getCoords = (placeName: string) => {
return geoCoordMap.find(([name,]) => name.includes(placeName))
}
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 destinations = new Map<string, number>()
for (const item of statResponse.reimbursementPlaceStats) {
let departureValue = departures.get(item.departureName)
if (departureValue)
departures.set(item.departureName, departureValue + item.reimbursementLaunchCount)
else
departures.set(item.departureName, item.reimbursementLaunchCount)
let destinationValue = departures.get(item.destinationName)
if (destinationValue)
destinations.set(item.destinationName, destinationValue + item.reimbursementLaunchCount)
else
destinations.set(item.destinationName, item.reimbursementLaunchCount)
const fromCoords = getCoords(item.departureName)
const toCoords = getCoords(item.destinationName)
if (fromCoords && toCoords) {
mapDataTemp.push({
fromName: fromCoords[0],
toName: toCoords[0],
coords: [fromCoords[1], toCoords[1]],
value: item.reimbursementLaunchCount,
lineStyle: {
width: item.reimbursementLaunchCount / maxValue * 10
}
})
}
}
setMapData(mapDataTemp)
{
let placeNames: string[] = []
let reimbursementCounts: number[] = []
departures.forEach(function (val, key, map) {
placeNames.push(key)
reimbursementCounts.push(val)
})
setDepartureNames(placeNames)
setDepartureValues(reimbursementCounts)
}
{
let placeNames: string[] = []
let reimbursementCounts: number[] = []
destinations.forEach(function (val, key, map) {
placeNames.push(key)
reimbursementCounts.push(val)
})
setDestinationNames(placeNames)
setDestinationValues(reimbursementCounts)
}
setLoading(false)
}, 1000);
}).catch(function (error) { }).catch(function (error) {
console.log(error) console.log(error)
@ -444,7 +458,10 @@ function StatView() {
alignItems: "center" alignItems: "center"
}}> }}>
<Space> <Space>
<Select value={type} onChange={setType}> <Select value={type} onChange={(value, option) => {
setType(value)
getStatData(selectedTime)
}}>
<Option value="month"></Option> <Option value="month"></Option>
<Option value="year"></Option> <Option value="year"></Option>
</Select> </Select>