From 33368f7f8969b7755b5be22915322836e1a6e50d Mon Sep 17 00:00:00 2001 From: FatttSnake Date: Tue, 19 Dec 2023 09:07:41 +0800 Subject: [PATCH] Add online info to statistics management page --- src/assets/css/pages/system/index.scss | 5 + src/assets/svg/online.svg | 1 + src/constants/urls.constants.ts | 1 + src/global.d.ts | 12 +- src/pages/system/index.tsx | 168 +++++++++++++++++++++++-- src/services/system.tsx | 5 +- 6 files changed, 176 insertions(+), 16 deletions(-) create mode 100644 src/assets/svg/online.svg diff --git a/src/assets/css/pages/system/index.scss b/src/assets/css/pages/system/index.scss index ecf9e7a..a41552d 100644 --- a/src/assets/css/pages/system/index.scss +++ b/src/assets/css/pages/system/index.scss @@ -74,6 +74,11 @@ text-align: right; } + .big-chart { + width: 0; + height: 400px; + } + > * { gap: 5px; } diff --git a/src/assets/svg/online.svg b/src/assets/svg/online.svg new file mode 100644 index 0000000..a6b0741 --- /dev/null +++ b/src/assets/svg/online.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/constants/urls.constants.ts b/src/constants/urls.constants.ts index c4eadc9..ab5a1e2 100644 --- a/src/constants/urls.constants.ts +++ b/src/constants/urls.constants.ts @@ -16,6 +16,7 @@ export const URL_SYS_STATISTIC_SOFTWARE = `${URL_SYS_STATISTIC}/software` export const URL_SYS_STATISTIC_HARDWARE = `${URL_SYS_STATISTIC}/hardware` export const URL_SYS_STATISTIC_CPU = `${URL_SYS_STATISTIC}/cpu` export const URL_SYS_STATISTIC_STORAGE = `${URL_SYS_STATISTIC}/storage` +export const URL_SYS_STATISTIC_ONLINE = `${URL_SYS_STATISTIC}/online` export const URL_API_V1 = '/api/v1' export const URL_API_V1_AVATAR_RANDOM_BASE64 = `${URL_API_V1}/avatar/base64` diff --git a/src/global.d.ts b/src/global.d.ts index e7fe359..e51602e 100644 --- a/src/global.d.ts +++ b/src/global.d.ts @@ -294,10 +294,6 @@ interface AvatarBase64Vo { base64: string } -interface SystemSettingsVo { - mail: MailSettingsVo -} - interface MailSettingsVo { host?: string port?: number @@ -381,3 +377,11 @@ interface FileStoreInfoVo { total: number free: number } + +interface OnlineInfoVo { + current: number + history: { + time: string + record: string + }[] +} diff --git a/src/pages/system/index.tsx b/src/pages/system/index.tsx index 851cf37..55e65dd 100644 --- a/src/pages/system/index.tsx +++ b/src/pages/system/index.tsx @@ -5,9 +5,14 @@ import { TooltipComponent, TooltipComponentOption, GridComponent, - GridComponentOption + GridComponentOption, + ToolboxComponentOption, + DataZoomComponentOption, + ToolboxComponent, + DataZoomComponent } from 'echarts/components' -import { BarChart, BarSeriesOption } from 'echarts/charts' +import { BarChart, BarSeriesOption, LineChart, LineSeriesOption } from 'echarts/charts' +import { UniversalTransition } from 'echarts/features' import { SVGRenderer } from 'echarts/renderers' import '@/assets/css/pages/system/index.scss' import { useUpdatedEffect } from '@/util/hooks' @@ -16,6 +21,7 @@ import { utcToLocalTime } from '@/util/datetime' import { r_sys_statistic_cpu, r_sys_statistic_hardware, + r_sys_statistic_online, r_sys_statistic_software, r_sys_statistic_storage } from '@/services/system' @@ -25,9 +31,23 @@ import FitFullScreen from '@/components/common/FitFullScreen' import HideScrollbar from '@/components/common/HideScrollbar' import LoadingMask from '@/components/common/LoadingMask' -echarts.use([TooltipComponent, GridComponent, BarChart, SVGRenderer]) +echarts.use([ + TooltipComponent, + ToolboxComponent, + GridComponent, + DataZoomComponent, + BarChart, + LineChart, + SVGRenderer, + UniversalTransition +]) type EChartsOption = echarts.ComposeOption< - TooltipComponentOption | GridComponentOption | BarSeriesOption + | TooltipComponentOption + | ToolboxComponentOption + | GridComponentOption + | BarSeriesOption + | DataZoomComponentOption + | LineSeriesOption > const barDefaultSeriesOption: BarSeriesOption = { @@ -46,7 +66,7 @@ const barDefaultSeriesOption: BarSeriesOption = { } } -const eChartsBaseOption: EChartsOption = { +const barEChartsBaseOption: EChartsOption = { tooltip: {}, xAxis: { show: false @@ -70,9 +90,43 @@ const eChartsBaseOption: EChartsOption = { } } +const lineEChartsBaseOption: EChartsOption = { + tooltip: { + trigger: 'axis' + }, + toolbox: { + feature: { + dataZoom: { + yAxisIndex: 'none' + }, + restore: {}, + saveAsImage: {} + } + }, + xAxis: { + type: 'time' + }, + yAxis: { + type: 'value', + interval: 1 + }, + dataZoom: [ + { + type: 'inside', + start: 0, + end: 100 + }, + { + start: 0, + end: 100 + } + ], + series: [{}] +} + interface CommonCardProps extends React.PropsWithChildren { icon: IconComponent - title: string + title: React.ReactNode loading?: boolean expand?: React.ReactNode } @@ -97,6 +151,97 @@ const CommonCard: React.FC = (props) => { ) } +const OnlineInfo: React.FC = () => { + const onlineInfoDivRef = useRef(null) + const onlineInfoEChartsRef = useRef(null) + const [isLoading, setIsLoading] = useState(false) + const [currentOnlineCount, setCurrentOnlineCount] = useState(-1) + + useUpdatedEffect(() => { + const chartResizeObserver = new ResizeObserver(() => { + onlineInfoEChartsRef.current?.resize() + }) + + onlineInfoDivRef.current && chartResizeObserver.observe(onlineInfoDivRef.current) + + return () => { + onlineInfoDivRef.current && chartResizeObserver.unobserve(onlineInfoDivRef.current) + } + }, [isLoading]) + + useUpdatedEffect(() => { + getOnlineInfo() + }, []) + + const getOnlineInfo = () => { + if (isLoading) { + return + } + + setIsLoading(true) + + void r_sys_statistic_online().then((res) => { + const response = res.data + if (response.success) { + const data = response.data + if (data) { + setIsLoading(false) + + setCurrentOnlineCount(data.current) + + setTimeout(() => { + const dataList = data.history.map((value) => [value.time, value.record]) + + onlineInfoEChartsRef.current = echarts.init( + onlineInfoDivRef.current, + null, + { renderer: 'svg' } + ) + + onlineInfoEChartsRef.current?.setOption({ + ...lineEChartsBaseOption, + series: [ + { + name: '在线人数', + type: 'line', + smooth: true, + symbol: 'none', + areaStyle: {}, + data: dataList + } + ] + }) + }) + } + } + }) + } + + return ( + + + 在线用户 + 当前 {currentOnlineCount} + + + } + loading={isLoading} + expand={ + getOnlineInfo()}> + + + } + > + +
+ + + ) +} + const SoftwareInfo: React.FC = () => { const [softwareInfoData, setSoftwareInfoData] = useState() @@ -271,9 +416,9 @@ const CPUInfo: React.FC = () => { setCpuInfoEChartsOption( dataList.map((value, index) => ({ - ...eChartsBaseOption, + ...barEChartsBaseOption, yAxis: { - ...eChartsBaseOption.yAxis, + ...barEChartsBaseOption.yAxis, data: [index === 0 ? '总占用' : `CPU ${index - 1}`] }, series: value @@ -501,13 +646,13 @@ const StorageInfo: React.FC = () => { } const storageInfoVoToStorageEChartsOption = (label: string, used: number, free: number) => ({ - ...eChartsBaseOption, + ...barEChartsBaseOption, xAxis: { - ...eChartsBaseOption.xAxis, + ...barEChartsBaseOption.xAxis, max: used + free }, yAxis: { - ...eChartsBaseOption.yAxis, + ...barEChartsBaseOption.yAxis, data: [label] }, series: [ @@ -577,6 +722,7 @@ const System: React.FC = () => { + diff --git a/src/services/system.tsx b/src/services/system.tsx index 7c0b6a1..5945a13 100644 --- a/src/services/system.tsx +++ b/src/services/system.tsx @@ -12,7 +12,8 @@ import { URL_SYS_STATISTIC_SOFTWARE, URL_SYS_STATISTIC_HARDWARE, URL_SYS_STATISTIC_CPU, - URL_SYS_STATISTIC_STORAGE + URL_SYS_STATISTIC_STORAGE, + URL_SYS_STATISTIC_ONLINE } from '@/constants/urls.constants' import request from '@/services/index' @@ -86,3 +87,5 @@ export const r_sys_statistic_hardware = () => export const r_sys_statistic_cpu = () => request.get(URL_SYS_STATISTIC_CPU) export const r_sys_statistic_storage = () => request.get(URL_SYS_STATISTIC_STORAGE) + +export const r_sys_statistic_online = () => request.get(URL_SYS_STATISTIC_ONLINE)