Add online info to statistics management page

This commit is contained in:
2023-12-19 09:07:41 +08:00
parent 8ac27b6e61
commit 33368f7f89
6 changed files with 176 additions and 16 deletions

View File

@@ -74,6 +74,11 @@
text-align: right; text-align: right;
} }
.big-chart {
width: 0;
height: 400px;
}
> * { > * {
gap: 5px; gap: 5px;
} }

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M739.584 575.561143A365.824 365.824 0 0 0 513.828571 950.857143H73.142857c0-242.358857 196.498286-438.857143 438.857143-438.857143 83.346286 0 161.243429 23.222857 227.584 63.561143zM512 512a219.428571 219.428571 0 1 1 0-438.857143 219.428571 219.428571 0 0 1 0 438.857143z m182.857143 146.285714h256v73.142857h-256v-73.142857z m-73.142857 109.714286h329.142857v73.142857h-329.142857v-73.142857z m-36.571429 109.714286h365.714286v73.142857H585.142857v-73.142857z" /></svg>

After

Width:  |  Height:  |  Size: 545 B

View File

@@ -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_HARDWARE = `${URL_SYS_STATISTIC}/hardware`
export const URL_SYS_STATISTIC_CPU = `${URL_SYS_STATISTIC}/cpu` 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_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 = '/api/v1'
export const URL_API_V1_AVATAR_RANDOM_BASE64 = `${URL_API_V1}/avatar/base64` export const URL_API_V1_AVATAR_RANDOM_BASE64 = `${URL_API_V1}/avatar/base64`

12
src/global.d.ts vendored
View File

@@ -294,10 +294,6 @@ interface AvatarBase64Vo {
base64: string base64: string
} }
interface SystemSettingsVo {
mail: MailSettingsVo
}
interface MailSettingsVo { interface MailSettingsVo {
host?: string host?: string
port?: number port?: number
@@ -381,3 +377,11 @@ interface FileStoreInfoVo {
total: number total: number
free: number free: number
} }
interface OnlineInfoVo {
current: number
history: {
time: string
record: string
}[]
}

View File

@@ -5,9 +5,14 @@ import {
TooltipComponent, TooltipComponent,
TooltipComponentOption, TooltipComponentOption,
GridComponent, GridComponent,
GridComponentOption GridComponentOption,
ToolboxComponentOption,
DataZoomComponentOption,
ToolboxComponent,
DataZoomComponent
} from 'echarts/components' } 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 { SVGRenderer } from 'echarts/renderers'
import '@/assets/css/pages/system/index.scss' import '@/assets/css/pages/system/index.scss'
import { useUpdatedEffect } from '@/util/hooks' import { useUpdatedEffect } from '@/util/hooks'
@@ -16,6 +21,7 @@ import { utcToLocalTime } from '@/util/datetime'
import { import {
r_sys_statistic_cpu, r_sys_statistic_cpu,
r_sys_statistic_hardware, r_sys_statistic_hardware,
r_sys_statistic_online,
r_sys_statistic_software, r_sys_statistic_software,
r_sys_statistic_storage r_sys_statistic_storage
} from '@/services/system' } from '@/services/system'
@@ -25,9 +31,23 @@ import FitFullScreen from '@/components/common/FitFullScreen'
import HideScrollbar from '@/components/common/HideScrollbar' import HideScrollbar from '@/components/common/HideScrollbar'
import LoadingMask from '@/components/common/LoadingMask' 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< type EChartsOption = echarts.ComposeOption<
TooltipComponentOption | GridComponentOption | BarSeriesOption | TooltipComponentOption
| ToolboxComponentOption
| GridComponentOption
| BarSeriesOption
| DataZoomComponentOption
| LineSeriesOption
> >
const barDefaultSeriesOption: BarSeriesOption = { const barDefaultSeriesOption: BarSeriesOption = {
@@ -46,7 +66,7 @@ const barDefaultSeriesOption: BarSeriesOption = {
} }
} }
const eChartsBaseOption: EChartsOption = { const barEChartsBaseOption: EChartsOption = {
tooltip: {}, tooltip: {},
xAxis: { xAxis: {
show: false 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 { interface CommonCardProps extends React.PropsWithChildren {
icon: IconComponent icon: IconComponent
title: string title: React.ReactNode
loading?: boolean loading?: boolean
expand?: React.ReactNode expand?: React.ReactNode
} }
@@ -97,6 +151,97 @@ const CommonCard: React.FC<CommonCardProps> = (props) => {
) )
} }
const OnlineInfo: React.FC = () => {
const onlineInfoDivRef = useRef<HTMLDivElement>(null)
const onlineInfoEChartsRef = useRef<echarts.EChartsType | null>(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 (
<CommonCard
icon={IconFatwebOnline}
title={
<>
<FlexBox gap={10} direction={'horizontal'}>
<span style={{ whiteSpace: 'nowrap' }}>线</span>
<AntdTag> {currentOnlineCount}</AntdTag>
</FlexBox>
</>
}
loading={isLoading}
expand={
<AntdButton title={'刷新'} onClick={() => getOnlineInfo()}>
<Icon component={IconFatwebRefresh} />
</AntdButton>
}
>
<FlexBox className={'card-content'} direction={'horizontal'}>
<div className={'big-chart'} ref={onlineInfoDivRef} />
</FlexBox>
</CommonCard>
)
}
const SoftwareInfo: React.FC = () => { const SoftwareInfo: React.FC = () => {
const [softwareInfoData, setSoftwareInfoData] = useState<SoftwareInfoVo>() const [softwareInfoData, setSoftwareInfoData] = useState<SoftwareInfoVo>()
@@ -271,9 +416,9 @@ const CPUInfo: React.FC = () => {
setCpuInfoEChartsOption( setCpuInfoEChartsOption(
dataList.map((value, index) => ({ dataList.map((value, index) => ({
...eChartsBaseOption, ...barEChartsBaseOption,
yAxis: { yAxis: {
...eChartsBaseOption.yAxis, ...barEChartsBaseOption.yAxis,
data: [index === 0 ? '总占用' : `CPU ${index - 1}`] data: [index === 0 ? '总占用' : `CPU ${index - 1}`]
}, },
series: value series: value
@@ -501,13 +646,13 @@ const StorageInfo: React.FC = () => {
} }
const storageInfoVoToStorageEChartsOption = (label: string, used: number, free: number) => ({ const storageInfoVoToStorageEChartsOption = (label: string, used: number, free: number) => ({
...eChartsBaseOption, ...barEChartsBaseOption,
xAxis: { xAxis: {
...eChartsBaseOption.xAxis, ...barEChartsBaseOption.xAxis,
max: used + free max: used + free
}, },
yAxis: { yAxis: {
...eChartsBaseOption.yAxis, ...barEChartsBaseOption.yAxis,
data: [label] data: [label]
}, },
series: [ series: [
@@ -577,6 +722,7 @@ const System: React.FC = () => {
<FitFullScreen> <FitFullScreen>
<HideScrollbar isShowVerticalScrollbar autoHideWaitingTime={500}> <HideScrollbar isShowVerticalScrollbar autoHideWaitingTime={500}>
<FlexBox direction={'horizontal'} className={'root-content'}> <FlexBox direction={'horizontal'} className={'root-content'}>
<OnlineInfo />
<SoftwareInfo /> <SoftwareInfo />
<HardwareInfo /> <HardwareInfo />
<CPUInfo /> <CPUInfo />

View File

@@ -12,7 +12,8 @@ import {
URL_SYS_STATISTIC_SOFTWARE, URL_SYS_STATISTIC_SOFTWARE,
URL_SYS_STATISTIC_HARDWARE, URL_SYS_STATISTIC_HARDWARE,
URL_SYS_STATISTIC_CPU, URL_SYS_STATISTIC_CPU,
URL_SYS_STATISTIC_STORAGE URL_SYS_STATISTIC_STORAGE,
URL_SYS_STATISTIC_ONLINE
} from '@/constants/urls.constants' } from '@/constants/urls.constants'
import request from '@/services/index' import request from '@/services/index'
@@ -86,3 +87,5 @@ export const r_sys_statistic_hardware = () =>
export const r_sys_statistic_cpu = () => request.get<CpuInfoVo>(URL_SYS_STATISTIC_CPU) export const r_sys_statistic_cpu = () => request.get<CpuInfoVo>(URL_SYS_STATISTIC_CPU)
export const r_sys_statistic_storage = () => request.get<StorageInfoVo>(URL_SYS_STATISTIC_STORAGE) export const r_sys_statistic_storage = () => request.get<StorageInfoVo>(URL_SYS_STATISTIC_STORAGE)
export const r_sys_statistic_online = () => request.get<OnlineInfoVo>(URL_SYS_STATISTIC_ONLINE)