From 0c91c3d29dabe7cf6b7f96fa68185820152485e3 Mon Sep 17 00:00:00 2001 From: wuyize Date: Thu, 5 Jan 2023 22:39:11 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B4=A2=E5=8A=A1=E7=BB=9F=E8=AE=A1=E6=8E=A5?= =?UTF-8?q?=E5=85=A5=E5=90=8E=E7=AB=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/models/UserConfigModels.ts | 64 +++++ src/pages/configuration/Configuration.tsx | 81 +++--- .../configuration/subpage/UserConfig.tsx | 124 +++++++- src/pages/stat/StatView.tsx | 271 ++++++++++-------- 4 files changed, 363 insertions(+), 177 deletions(-) create mode 100644 src/models/UserConfigModels.ts diff --git a/src/models/UserConfigModels.ts b/src/models/UserConfigModels.ts new file mode 100644 index 0000000..f48cc91 --- /dev/null +++ b/src/models/UserConfigModels.ts @@ -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; +} \ No newline at end of file diff --git a/src/pages/configuration/Configuration.tsx b/src/pages/configuration/Configuration.tsx index 8c20c9c..9aa2331 100644 --- a/src/pages/configuration/Configuration.tsx +++ b/src/pages/configuration/Configuration.tsx @@ -1,54 +1,53 @@ -import {Tabs} from "antd"; -import React from "react"; +import {Tabs, theme} from "antd"; +import React, {useState} from "react"; import UserConfig from "./subpage/UserConfig"; import CityConfig from "./subpage/CityConfig"; import DepartmentConfig from "./subpage/DepartmentConfig"; import OtherConfig from "./subpage/OtherConfig"; -class Configuration extends React.Component { - - constructor(props: any) { - super(props); - this.state = { - activatedTab: 0 - } - } - - tabItems = () => { - return [{ - label: "用户配置", - key: "0", - children: - }, - { +function Configuration() { + const { + token: {colorBgContainer}, + } = theme.useToken(); + const [activatedTab, setActivatedTab] = useState(0) + return ( + { + setActivatedTab(Number(key)) + }} + renderTabBar={(props, DefaultTabBar) => ( +
+ +
+ )} + items={[{ + label: "用户配置", + key: "0", + children: + }, { label: "城市配置", key: "1", - children: - }, - { + children: + }, { label: "部门配置", key: "2", - children: - }, - { + children: + }, { label: "其他配置", key: "3", - children: - }] - } - tabChange = (key: string) => { - this.setState({activatedTab: Number(key)}) - } - render() { - return ( - - ) - } + children: + }]} + /> + ) + } + export default Configuration; \ No newline at end of file diff --git a/src/pages/configuration/subpage/UserConfig.tsx b/src/pages/configuration/subpage/UserConfig.tsx index 58633d1..64d6ddc 100644 --- a/src/pages/configuration/subpage/UserConfig.tsx +++ b/src/pages/configuration/subpage/UserConfig.tsx @@ -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"; -class UserConfig extends React.Component { - render() { - return ( -
-

User Config

-
- ); +const {Text, Link} = Typography; + + +function UserConfig(props: any) { + + const [departmentMap, setDepartmentMap] = useState(new Map()) + + + 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 = [ + { + title: '工号', + dataIndex: 'staffId', + key: 'staffId', + }, + { + title: '姓名', + dataIndex: 'staffName', + key: 'staffName', + }, + { + title: '部门', + dataIndex: 'managingDepartment', + key: 'department', + render: (value, record, index) => {departmentToString(record)}, + }, + { + title: '', + key: 'action', + render: (_, record) => ( + + 重置密码 + 移除 + + ), + }, + ]; + 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() + for (const department of departments) + map.set(department.departmentId, department.departmentName) + setDepartmentMap(map) + }).catch(function (error) { + console.log(error) + }) + + }, []); + + return ( +
+ +
+ + + + + +
+ + ) } -export default UserConfig; \ No newline at end of file + +export default UserConfig \ No newline at end of file diff --git a/src/pages/stat/StatView.tsx b/src/pages/stat/StatView.tsx index 5204bd8..3f94eff 100644 --- a/src/pages/stat/StatView.tsx +++ b/src/pages/stat/StatView.tsx @@ -100,6 +100,7 @@ function StatView() { token: {colorBgContainer, colorPrimary, colorSuccess, colorBorder}, } = theme.useToken(); + const [selectedTime, setSelectedTime] = useState(null); const [type, setType] = useState('month'); const [loading, setLoading] = useState(true) const [reimbursementAmount, setReimbursementAmount] = useState(0) @@ -124,7 +125,7 @@ function StatView() { const getStatData = (time: Dayjs | null) => { console.log(time) setLoading(true) - + setSelectedTime(time) axiosInstance({ url: 'common/department', method: 'get' @@ -146,7 +147,143 @@ function StatView() { dates.push(i + '月') } 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>() + departmentMap.forEach(function (value, key, map) { + departmentAmountMap.set(key, new Map()) + }) + + 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() + let destinations = new Map() + 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 = { "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]) - setInvoiceKinds(statResponse.invoiceKindsStats.map((item) => { - return {value: item.invoiceLaunchCount, name: invoiceTypeNameMap.get(item.invoiceKind)} - })) - - - let departmentAmountMap = new Map>() - departmentMap.forEach(function (value, key, map) { - departmentAmountMap.set(key, new Map()) - }) - - 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() - let destinations = new Map() - 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); + }, 1000);*/ }).catch(function (error) { console.log(error) @@ -444,7 +458,10 @@ function StatView() { alignItems: "center" }}> - { + setType(value) + getStatData(selectedTime) + }}>