feat(): 资源使用中的实时数据以及历史数据开发

master
李神峰 2025-02-17 17:57:15 +08:00
parent 35c7b46409
commit 715f86d3a8
15 changed files with 977 additions and 16 deletions

BIN
public/assets/noData.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -15,16 +15,23 @@ const guishiPro = '/shzh/ptjstest'
const shengUrl2Pro = ''
const nmjPro = '/shzh/jcsj'
const jsapi = {
ptjs: {
czrz: shengUrlPro + '/prod-api/baseplat-system/operlog/hb/list',
czdbl: guishiPro + '/monitor/summary',
export:guishiPro + '/monitor/export/',
resource:guishiPro + '/resource/page',
treeList:shengUrlPro + "/prod-api/baseplat-basic/hb/village/getChild/"
treeList: shengUrlPro + "/prod-api/baseplat-basic/hb/village/getChild/",
cpuPage: guishiPro + '/cpu/page',
cpuQuery: guishiPro + '/cpu/list/query',
memoryQuery: guishiPro + '/memory/list/query',
diskQuery: guishiPro + '/disk/list/query',
memoryPage: guishiPro + '/memory/page',
diskPage: guishiPro + '/disk/page',
diskList: guishiPro + '/disk/list',
realCpu: guishiPro + '/cpu/latest',
realMemory: guishiPro + '/memory/latest',
realDisk: guishiPro + '/disk/latest',
},
service: {

View File

@ -274,7 +274,14 @@ const session = {
id:121, redirect: "/ptjs/czrz", parent_id: -1, name: "平台监视", type: 1, order: 1, children: [
{ id: 402, path: "/ptjs/czrz", parent_id: 500, name: "操作日志", type: 0, order: 1},
{ id: 403, path: "/ptjs/czdbl", parent_id: 500, name: "测站到报率", type: 0, order: 1},
{ id: 404, path: "/ptjs/zysy", parent_id: 500, name: "资源使用", type: 0, order: 1},
{
id: 404, path: "/ptjs/zysy", parent_id: 500, name: "资源使用", type: 0, order: 1,
children: [
// { id: 407, path: "/ptjs/zysy/ls", parent_id: 500, name: "历史", type: 0, order: 1 },
{ id: 405, path: "/ptjs/zysy/sssj", parent_id: 500, name: "实时数据", type: 0, order: 1 },
{ id: 406, path: "/ptjs/zysy/lssj", parent_id: 500, name: "历史数据", type: 0, order: 1 },
]
},
]
},

View File

@ -44,8 +44,13 @@ const routes = [
// 测站到报率
{ path: '/ptjs/czdbl', exact: true, component: lazy(() => import('./views/Ptjs/Czdbl')) },
// 资源使用-实时数据
{ path: '/ptjs/zysy/sssj', exact: true, component: lazy(() => import('./views/Ptjs/Sssj')) },
// 资源使用-历史数据
{ path: '/ptjs/zysy/lssj', exact: true, component: lazy(() => import('./views/Ptjs/Lssj')) },
// 资源使用
{ path: '/ptjs/zysy', exact: true, component: lazy(() => import('./views/Ptjs/Zysy')) },
{ path: '/ptjs/zysy/ls', exact: true, component: lazy(() => import('./views/Ptjs/Zysy')) },
//监测站点
{ path: '/jczd/zdbg', exact: true, component: lazy(() => import('./views/Jczd/Bg')) },
{ path: '/jczd/zdsp', exact: true, component: lazy(() => import('./views/Jczd/Sp')) },

View File

@ -68,7 +68,8 @@ export default function dblOption(sellist,selday) {
},
saveAsImage: {
show: true,
title: '保存为图片'
name:'日到报率详情',
title: '保存为图片'
}
}
},

View File

@ -3,7 +3,7 @@ import { Card, message, Table, Space, Button, Spin, Tree } from 'antd';
import ToolBar from './toolbar.js';
import ToolBottom from './toolBottom.js';
import apiurl from '../../../models/apiurl'
import { xyt_httpget2, httpPostFile } from "../../../utils/request";
import { xyt_httpget2, httpPostFile,httpGetFile } from "../../../utils/request";
import { exportFile } from '../../../utils/tools'
import { resJson } from './res.js';
import ReactEcharts from 'echarts-for-react';
@ -410,6 +410,20 @@ export default function Czrz() {
return node;
})
}
// 山洪数据映射
const dataUpdate = (data) => {
return data.map(item => {
if (item.adcd == '420391000000000') {
item.adcd = '420381450000000';
item.adnm = '武当山';
}
if (item.adcd == '421303000000000') {
item.adcd = '421302000000000';
}
return item
})
}
const onLoadData = async ({ key, children }) => {
if (key.substr(4) != '00000000000') {
return
@ -417,8 +431,10 @@ export default function Czrz() {
try {
const res = await xyt_httpget2(apiurl.ptjs.treeList + key)
if (res.code == 200) {
const filterData =res.data.filter(item => item.adcd != '420891000000000')
const results = dataUpdate(filterData)
setTreeList(origin =>
updateTreeData(origin, key, res.data.map(item => ({ ...item, isLeaf: true })))
updateTreeData(origin, key, results.map(item => ({ ...item, isLeaf: true })))
)
}
} catch (error) {
@ -472,11 +488,11 @@ export default function Czrz() {
}
// 下载测站离线表
const download = () => {
// httpPostFile(apiurl.service.yjgx.downLoad, params).then((res) => {
// if (res) {
// exportFile('测站离线表.xlsx', res.data)
// }
// })
httpGetFile(apiurl.ptjs.export + '?' + `tm=${SearchBottom.operTime}`).then((res) => {
if (res) {
exportFile('测站离线表.xlsx', res.data)
}
})
}
useEffect(() => {
if (searchVal) {

View File

@ -88,7 +88,9 @@ export default function qsOption(timeList, listObj, hbobj, list) {
chartTimeList[idx] = str.substring(5, 10);
});
console.log("miny",minY);
console.log("chartTimeList", chartTimeList);
console.log("addSerise",addSerise.data);
return {
@ -150,6 +152,7 @@ console.log("miny",minY);
},
saveAsImage: {
show: true,
name:'到报率变化趋势',
title: '保存为图片'
}
}

View File

@ -0,0 +1,275 @@
import React, { useState, useMemo } from 'react'
import { Card, Tabs,Table } from "antd";
import ReactEcharts from 'echarts-for-react';
import ToolBar from './toolbar';
import zyOptions from './qsOption'
import moment from 'moment';
import NormalSelect from '../../../components/Form/NormalSelect';
import usePageTable from '../../../components/Crud/usePageTable.js'
import { findPage2 } from '../../../components/Crud/_.js'
import apiurl from '../../../models/apiurl'
import { httppost,httpget } from '../../../utils/request.js';
import { useEffect } from 'react';
export default function Lssj() {
const [searchVal, setSearchVal] = useState(false)
const [cbOptions, setCbOptions] = useState([])
const [cbValue, setCbValue] = useState("/")
const [optionsData, setOptionsData] = useState([])
const cpuColumn = [
{
title: '时间',
dataIndex: 'tm',
key: 'tm',
width: 120,
align: "center",
},
{
title: '用户态CPU时间(s)',
dataIndex: 'userTime',
key: 'userTime',
width: 120,
align: "center",
},
{
title: '系统态CPU时间(s)',
dataIndex: 'system',
key: 'system',
width: 120,
align: "center",
},
{
title: '空闲态CPU时间(s)',
dataIndex: 'idle',
key: 'idle',
width: 120,
align: "center",
},{
title: 'I/O等待时间(s)',
dataIndex: 'iowait',
key: 'iowait',
width: 120,
align: "center",
},
{
title: 'CPU使用率(%)',
dataIndex: 'rate',
key: 'rate',
width: 120,
align: "center",
},
]
const ncColumn = [
{
title: '时间',
dataIndex: 'tm',
key: 'tm',
width: 120,
align: "center",
},
{
title: '总内存(MB)',
dataIndex: 'totalSpace',
key: 'totalSpace',
width: 120,
align: "center",
},
{
title: '已用内存(MB)',
dataIndex: 'usedSpace',
key: 'usedSpace',
width: 120,
align: "center",
},
{
title: '可用内存(MB)',
dataIndex: 'freeSpace',
key: 'freeSpace',
width: 120,
align: "center",
},
{
title: '内存使用率(%)',
dataIndex: 'rate',
key: 'rate',
width: 120,
align: "center",
},
]
const ccColumn = [
{
title: '时间',
dataIndex: 'tm',
key: 'tm',
width: 120,
align: "center",
},
{
title: '挂载点',
dataIndex: 'mount',
key: 'mount',
width: 120,
align: "center",
},
{
title: '磁盘名称',
dataIndex: 'name',
key: 'name',
width: 120,
align: "center",
},
{
title: '总磁盘量(GB)',
dataIndex: 'totalSpace',
key: 'totalSpace',
width: 120,
align: "center",
},
{
title: '已用磁盘量(GB)',
dataIndex: 'usedSpace',
key: 'usedSpace',
width: 120,
align: "center",
},
{
title: '可用磁盘量(GB)',
dataIndex: 'freeSpace',
key: 'freeSpace',
width: 120,
align: "center",
},
{
title: '磁盘使用率(%)',
dataIndex: 'rate',
key: 'rate',
width: 120,
align: "center",
},
]
const url = useMemo(() => {
if (searchVal) {
switch (searchVal.type) {
case 0:
return apiurl.ptjs.cpuPage
case 1:
return apiurl.ptjs.memoryPage
case 2:
return apiurl.ptjs.diskPage
}
} else {
return apiurl.ptjs.cpuPage
}
},[searchVal])
const { tableProps, search, refresh } = usePageTable((params) => findPage2(url, params))
const options = useMemo(() => {
if (searchVal && optionsData.length >0) {
return zyOptions(optionsData || [],searchVal.type)
} else {
return zyOptions()
}
}, [searchVal,optionsData])
const newColumns = useMemo(() => {
if (searchVal) {
switch (searchVal.type) {
case 0:
return cpuColumn
case 1:
return ncColumn
case 2:
return ccColumn
}
} else {
return cpuColumn
}
}, [searchVal])
const getDiskList = async () => {
try {
const res = await httpget(apiurl.ptjs.diskList)
if (res.code == 200) {
setCbOptions(res.data.map(item => ({ label: item.mount, value: item.mount })))
}
} catch (error) {
console.log(error);
}
}
// 获取cpu整个时间范围内数据
const getTotalList = async (params,url) => {
try {
const res = await httppost(url,params)
if (res.code == 200) {
const result = res.data.map(item => ({...item,tm:moment(item.tm).format('HH:mm:ss')}))
setOptionsData(result)
}
} catch (error) {
console.log(error);
}
}
useEffect(() => {
if (searchVal) {
const params = {
...searchVal,
mount: searchVal?.type == 2 ? cbValue :undefined
};
search(params)
const url = searchVal.type == 0 ? apiurl.ptjs.cpuQuery :
searchVal.type == 1 ? apiurl.ptjs.memoryQuery :
searchVal.type == 2 ? apiurl.ptjs.diskQuery :
apiurl.ptjs.cpuQuery
getTotalList({...params,type:undefined},url)
}
}, [searchVal,cbValue])
useEffect(() => {
getDiskList();
}, [])
return (
<div className='page'>
<Card style={{ display: 'flex', flexDirection: 'column', width: '100%', marginRight: 10 }}>
<div className='flex' style={{ alignItems: 'center', marginRight: 10, marginBottom: 20 }}>
<img src={require('../../../assets/images/panelTitle.png')} style={{ marginRight: 5 }}></img>
<span style={{ fontSize: 16, fontWeight: 'bold' }}>资源使用</span>
</div>
<ToolBar
setToolVal={setSearchVal}
/>
{optionsData.length > 0 && tableProps.dataSource.length > 0 ?
<>
<div style={{ width: '100%', height: 440, border: '1px solid #dfdfdf', marginTop: 15,position:'relative' }}>
<ReactEcharts option={options} style={{ width: "100%", height: '100%' }} notMerge={true} />
{searchVal.type == 2 && <div style={{ position: 'absolute', top: 10, right: 10 }}>
<NormalSelect
options={cbOptions}
onChange={(value) => {
setCbValue(value)
}}
value={cbValue}
style={{ width: '230px' }} /></div>}
</div>
<Table
columns={newColumns}
{...tableProps}
scroll={{ x: 1000, y: "calc( 100vh - 500px )" }}
rowKey="inx"
/>
</> :
<img
src={`${process.env.PUBLIC_URL}/assets/noData.png`}
alt=''
style={{marginLeft: '36%',marginTop:"10%"}}
/>
}
</Card>
</div>
)
}

View File

@ -0,0 +1,84 @@
import { color } from "echarts";
import moment from "moment"
export default function qsOption(data=[],type=0) {
const minY = Math.ceil(Math.min(...data?.map(item => item.rate)));
const maxY = Math.floor(Math.max(...data?.map(item => item.rate)));
const name = type == 0 ? 'CPU使用率' :
type == 1 ? '内存使用率' :
type == 2 ? '存储使用率' : 'CPU使用率'
const chartType = type != 0 ? 'bar' : 'line';
return {
legend: {
show: true,
top:10
},
grid: {
left: '4%',
right: '4%',
bottom: '8%',
},
tooltip: {
trigger: 'axis',
formatter: function (params) {
if (params.length > 0) {
var result = params[0].name + "<br>";
params.forEach(function (item) {
if (item.value) {
result +=
item.marker +
" " +
item.seriesName +
" : " +
item.value +
"%</br>";
}
});
return result;
}
}
},
xAxis: {
type: 'category',
data: data.map(item => item.tm),
axisLabel: {
interval: 0
}
},
yAxis: {
name: name,
type: 'value',
axisLabel: {
formatter: '{value}%'
},
min: minY,
max: maxY,
axisLine: {
show: true,
},
axisTick: {
show: true,
}
},
series: [
{
name:name,
type: chartType,
itemStyle: {
normal: {
color:'#02a7f0',
label: {
show: false,
formatter: '{c}%'
},
labelLine: {
show: true
}
}
},
data: data.map(item => item.rate)
}
]
}
}

View File

@ -0,0 +1,108 @@
import React, { useEffect, useState } from 'react';
import { Form, Input, Button, DatePicker } from 'antd';
import NormalSelect from '../../../components/Form/NormalSelect';
import dayjs from 'dayjs';
import { FileTextOutlined } from '@ant-design/icons';
const { RangePicker } = DatePicker;
const ToolBar = ({ setToolVal }) => {
const [showIcon, setShowIcon] = useState(false)
const selectList=[
{key:'最近1小时',value:1},
{key:'最近1天',value:2},
{key:'最近7天',value:3},
{key:'最近1个月',value:4},
]
const Stypes = [
{ label: 'CPU', value: 0 },
{ label: '内存', value: 1 },
{ label: '存储', value: 2 },
];
const [form] = Form.useForm();
const onFinish = (values) => {
if (values.tm) {
values.stm = values.tm[0] ? dayjs(values.tm[0]).format('YYYY-MM-DD HH:mm:ss') : "";
values.etm = values.tm[1] ? dayjs(values.tm[1]).format('YYYY-MM-DD HH:mm:ss') : "";
delete values.tm
}
setToolVal(values);
}
const selectTime = (params)=>{
let tmValue=[]
if(params === 1){
tmValue=[dayjs().subtract(1, 'hours'),
dayjs()
]
}else if(params ===2){
tmValue=[dayjs().subtract(1, 'days'),
dayjs()
]
}else if(params ===3){
tmValue=[dayjs().subtract(7, 'days'),
dayjs()
]
}else if(params ===4){
tmValue=[dayjs().subtract(1, 'months'),
dayjs()
]
}
form.setFieldsValue({...params,tm:tmValue})
}
const onValuesChange = (values, allValues) => {
if (allValues.tm) {
allValues.stm = allValues.tm[0] ? dayjs(allValues.tm[0]).format('YYYY-MM-DD HH:mm:ss') : "";
allValues.etm = allValues.tm[1] ? dayjs(allValues.tm[1]).format('YYYY-MM-DD HH:mm:ss') : "";
delete allValues.operTime
}
console.log(values,allValues);
setToolVal(allValues)
}
useEffect(() => {
const tm = [dayjs().subtract(1, 'hours'), dayjs()];
form.setFieldsValue({ tm, type: 0 })
const stm = tm[0].format('YYYY-MM-DD HH:mm:ss');
const etm = tm[1].format('YYYY-MM-DD HH:mm:ss');
setToolVal({type:0,stm,etm})
}, [])
return (
<div className='pageToolBar' style={{position:'relative'}}>
<Form form={form} onFinish={onFinish} size='Default' layout="inline" style={{columnGap:25}} onValuesChange={onValuesChange}>
<Form.Item label="监测时间" name="tm">
<RangePicker
placeholder={['开始日期', '结束日期']}
format='YYYY-MM-DD HH:mm:ss'
style={{ width: 350 }}
showTime
/>
</Form.Item>
<Form.Item label="监测指标" name="type" wrapperCol={{span:1}}>
<NormalSelect options={Stypes} style={{ width: '120px' }} />
</Form.Item>
<Form.Item wrapperCol={{offset:8}}>
<Button type="primary" htmlType="submit" size='Default'>查询</Button>
</Form.Item>
<Form.Item>
<Button size='Default' onClick={() => form.resetFields()}>重置</Button>
</Form.Item>
</Form>
<div style={{display:'flex',justifyContent:'end',position:'absolute',left:"25.5%",
top:"7%"}}
onClick={()=>{
setShowIcon(!showIcon)
}}
>
<FileTextOutlined style={{fontSize:24,color:'skyblue'}}/>
{showIcon &&<div className='selecItem' style={{position:'absolute',zIndex:2,width:200,top:"100%",left:"7.5%",backgroundColor:'#fff',border:'1px solid #f0f0f0',padding:'5px 10px'}}>
{selectList.map((item)=>{
return <div style={{cursor:'pointer'}} onClick={()=>selectTime(item.value)}>{item.key}</div>
})}
</div>}
</div>
</div>
);
}
export default ToolBar;

123
src/views/Ptjs/Sssj/Cpu.js Normal file
View File

@ -0,0 +1,123 @@
import React from 'react'
import { Descriptions } from 'antd'
import './index.less'
export default function Cpu({data}) {
return (
<div>
<Descriptions title='CPU信息' layout='horizontal' bordered column={2}>
<Descriptions.Item label="处理器的名称" span={1}>
{data?.cpuVendor}
</Descriptions.Item>
<Descriptions.Item label="处理器的制造" span={1}>
{data?.cpuName}
</Descriptions.Item>
<Descriptions.Item label="处理器的系列" span={1}>
{data?.cpuFamily}
</Descriptions.Item>
<Descriptions.Item label="处理器的型号" span={1}>
{data?.cpuModel}
</Descriptions.Item>
<Descriptions.Item label="处理器的步进版本" span={1}>
{data?.cpuStepping}
</Descriptions.Item>
<Descriptions.Item label="处理器的唯一标识符" span={1}>
{data?.processorId}
</Descriptions.Item>
<Descriptions.Item label="CPU是否支持64位架构" span={1}>
{data?.cpu64bit ? '是':'否'}
</Descriptions.Item>
<Descriptions.Item label="CPU的标称频率" span={1}>
{data?.cpuVendorFreq}
</Descriptions.Item>
<Descriptions.Item label="逻辑处理器(线程)的数量" span={1}>
{data?.logicalProcessorCount}
</Descriptions.Item>
<Descriptions.Item label="物理处理器的数量" span={1}>
{data?.physicalProcessorCount}
</Descriptions.Item>
<Descriptions.Item label="CPU使用率%" span={1}>
{data?.systemCpuLoad}
</Descriptions.Item>
<Descriptions.Item label="CPU的最大频率" span={1}>
{data?.maxFreq}
</Descriptions.Item>
<Descriptions.Item label="CPU缓存的总大小" span={1}>
{data?.cacheSize}
</Descriptions.Item>
</Descriptions>
{/* <div className='resourceTitle'>
<div style={{ fontSize: 24, fontWeight: 'bold' }}>CPU</div>
<div style={{ fontSize: 18, fontWeight: 'bold' }}>AMD</div>
</div>
<div className='echarts-resource-box'></div>
<div className='cpu-list'>
<div className='left'>
<div className='first-row' style={{ display: 'flex', columnGap: 10 }}>
<div>
<div>利用率</div>
<div style={{ fontSize: 24, fontWeight: 'bold' }}>20%</div>
</div>
<div>
<div>速度</div>
<div style={{ fontSize: 24, fontWeight: 'bold' }}>3.15GHZ</div>
</div>
</div>
<div className='second-row' style={{ display: 'flex', columnGap: 10 }}>
<div>
<div>进程</div>
<div style={{ fontSize: 24, fontWeight: 'bold' }}>20%</div>
</div>
<div>
<div>线程</div>
<div style={{ fontSize: 24, fontWeight: 'bold' }}>20%</div>
</div><div>
<div>句柄</div>
<div style={{ fontSize: 24, fontWeight: 'bold' }}>20%</div>
</div>
</div>
<div className='second-row' style={{ display: 'flex', columnGap: 10 }}>
<div>
<div>正常运行时间</div>
<div style={{ fontSize: 24, fontWeight: 'bold' }}>20%</div>
</div>
</div>
</div>
<div className='right'>
<div className='first' style={{display:'flex',columnGap:0,alignItems:'center'}}>
<div style={{ width: 100,fontSize:16 }}>基准速度</div>
<div style={{width:100,fontSize:16}}>2.00GHZ</div>
</div>
<div className='second' style={{display:'flex',columnGap:10,alignItems:'center'}}>
<div style={{ width: 100,fontSize:16 }}>插槽</div>
<div style={{width:100,fontSize:16}}>1</div>
</div>
<div className='second1' style={{display:'flex',columnGap:10,alignItems:'center'}}>
<div style={{ width: 100,fontSize:16 }}>内核</div>
<div style={{width:100,fontSize:16}}>8</div>
</div>
<div className='second2' style={{display:'flex',columnGap:10,alignItems:'center'}}>
<div style={{ width: 100,fontSize:16 }}>逻辑处理器</div>
<div style={{width:100,fontSize:16}}>8</div>
</div>
<div className='second4' style={{display:'flex',columnGap:10,alignItems:'center'}}>
<div style={{ width: 100,fontSize:16 }}>虚拟化</div>
<div style={{width:100,fontSize:16}}>已启用</div>
</div>
<div className='second3' style={{display:'flex',columnGap:10,alignItems:'center'}}>
<div style={{ width: 100,fontSize:16 }}>L1缓存</div>
<div style={{width:100,fontSize:16}}>512</div>
</div>
<div className='second5' style={{display:'flex',columnGap:10,alignItems:'center'}}>
<div style={{ width: 100,fontSize:16 }}>L2缓存</div>
<div style={{width:100,fontSize:16}}>512</div>
</div>
<div className='second6' style={{display:'flex',columnGap:10,alignItems:'center'}}>
<div style={{ width: 100,fontSize:16 }}>L3缓存</div>
<div style={{width:100,fontSize:16}}>512</div>
</div>
</div>
</div> */}
</div>
)
}

151
src/views/Ptjs/Sssj/Disk.js Normal file
View File

@ -0,0 +1,151 @@
import React from 'react'
import { Table } from 'antd'
import './index.less'
import { render } from '@testing-library/react';
export default function Disk({ data }) {
// 工具函数:格式化字节大小
const formatBytes = (bytes, decimals = 2) => {
if (bytes === 0) return '0 Bytes';
const k = 1024; // 1 KB = 1024 Bytes
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
const i = Math.floor(Math.log(bytes) / Math.log(k)); // 计算单位索引
// 格式化数值并保留指定小数位数
return `${parseFloat((bytes / Math.pow(k, i)).toFixed(decimals))} ${sizes[i]}`;
};
const newColumns = [
{
title: '序号',
dataIndex: 'index',
key: 'index',
width: 60,
render: (_, record, index) => index + 1,
},
{
title: '文件存储名',
dataIndex: 'name',
key: 'name',
width: 120,
},
{
title: '挂载点路径',
dataIndex: 'mount',
key: 'mount',
width: 120,
}, {
title: '文件系统类型',
dataIndex: 'type',
key: 'type',
width: 120,
}, {
title: '总空间大小',
dataIndex: 'totalSpace',
key: 'totalSpace',
width: 120,
render: (v) => <span>{formatBytes(v)}</span>
}, {
title: '可用空间大小',
dataIndex: 'totalSpace',
key: 'totalSpace',
width: 120,
render: (v) => <span>{formatBytes(v)}</span>
},
{
title: '空闲空间大小',
dataIndex: 'freeSpace',
key: 'freeSpace',
width: 120,
render: (v) => <span>{formatBytes(v)}</span>
},
]
return (
<div>
<div style={{fontSize:16,fontWeight:600}}>存储信息</div>
<Table
columns={newColumns}
dataSource={data?.fileStores || []}
pagination={false}
scroll={{ x: 1000, }}
rowKey="inx"
/>
{/* <div className='resourceTitle'>
<div style={{ fontSize: 24, fontWeight: 'bold' }}>CPU</div>
<div style={{ fontSize: 18, fontWeight: 'bold' }}>AMD</div>
</div>
<div className='echarts-resource-box'></div>
<div className='cpu-list'>
<div className='left'>
<div className='first-row' style={{ display: 'flex', columnGap: 10 }}>
<div>
<div>利用率</div>
<div style={{ fontSize: 24, fontWeight: 'bold' }}>20%</div>
</div>
<div>
<div>速度</div>
<div style={{ fontSize: 24, fontWeight: 'bold' }}>3.15GHZ</div>
</div>
</div>
<div className='second-row' style={{ display: 'flex', columnGap: 10 }}>
<div>
<div>进程</div>
<div style={{ fontSize: 24, fontWeight: 'bold' }}>20%</div>
</div>
<div>
<div>线程</div>
<div style={{ fontSize: 24, fontWeight: 'bold' }}>20%</div>
</div><div>
<div>句柄</div>
<div style={{ fontSize: 24, fontWeight: 'bold' }}>20%</div>
</div>
</div>
<div className='second-row' style={{ display: 'flex', columnGap: 10 }}>
<div>
<div>正常运行时间</div>
<div style={{ fontSize: 24, fontWeight: 'bold' }}>20%</div>
</div>
</div>
</div>
<div className='right'>
<div className='first' style={{display:'flex',columnGap:0,alignItems:'center'}}>
<div style={{ width: 100,fontSize:16 }}>基准速度</div>
<div style={{width:100,fontSize:16}}>2.00GHZ</div>
</div>
<div className='second' style={{display:'flex',columnGap:10,alignItems:'center'}}>
<div style={{ width: 100,fontSize:16 }}>插槽</div>
<div style={{width:100,fontSize:16}}>1</div>
</div>
<div className='second1' style={{display:'flex',columnGap:10,alignItems:'center'}}>
<div style={{ width: 100,fontSize:16 }}>内核</div>
<div style={{width:100,fontSize:16}}>8</div>
</div>
<div className='second2' style={{display:'flex',columnGap:10,alignItems:'center'}}>
<div style={{ width: 100,fontSize:16 }}>逻辑处理器</div>
<div style={{width:100,fontSize:16}}>8</div>
</div>
<div className='second4' style={{display:'flex',columnGap:10,alignItems:'center'}}>
<div style={{ width: 100,fontSize:16 }}>虚拟化</div>
<div style={{width:100,fontSize:16}}>已启用</div>
</div>
<div className='second3' style={{display:'flex',columnGap:10,alignItems:'center'}}>
<div style={{ width: 100,fontSize:16 }}>L1缓存</div>
<div style={{width:100,fontSize:16}}>512</div>
</div>
<div className='second5' style={{display:'flex',columnGap:10,alignItems:'center'}}>
<div style={{ width: 100,fontSize:16 }}>L2缓存</div>
<div style={{width:100,fontSize:16}}>512</div>
</div>
<div className='second6' style={{display:'flex',columnGap:10,alignItems:'center'}}>
<div style={{ width: 100,fontSize:16 }}>L3缓存</div>
<div style={{width:100,fontSize:16}}>512</div>
</div>
</div>
</div> */}
</div>
)
}

View File

@ -0,0 +1,104 @@
import React from 'react'
import { Descriptions } from 'antd'
import './index.less'
export default function Memory({ data }) {
return (
<div>
<Descriptions title='内存信息' layout='horizontal' bordered column={2}>
<Descriptions.Item label="总交换空间大小byte" span={1}>
{data?.virtualMemory?.swapTotal}
</Descriptions.Item>
<Descriptions.Item label="已使用的交换空间大小byte" span={1}>
{data?.virtualMemory?.swapUsed}
</Descriptions.Item>
<Descriptions.Item label="从交换空间换入的页数" span={1}>
{data?.virtualMemory?.swapPagesIn}
</Descriptions.Item>
<Descriptions.Item label="换出到交换空间的页数" span={1}>
{data?.virtualMemory?.swapPagesOut}
</Descriptions.Item>
<Descriptions.Item label="虚拟内存的最大容量byte" span={1}>
{data?.virtualMemory?.virtualMax}
</Descriptions.Item>
<Descriptions.Item label="当前使用的虚拟内存大小byte" span={1}>
{data?.virtualMemory?.virtualInUse}
</Descriptions.Item>
</Descriptions>
{/* <div className='resourceTitle'>
<div style={{ fontSize: 24, fontWeight: 'bold' }}>CPU</div>
<div style={{ fontSize: 18, fontWeight: 'bold' }}>AMD</div>
</div>
<div className='echarts-resource-box'></div>
<div className='cpu-list'>
<div className='left'>
<div className='first-row' style={{ display: 'flex', columnGap: 10 }}>
<div>
<div>利用率</div>
<div style={{ fontSize: 24, fontWeight: 'bold' }}>20%</div>
</div>
<div>
<div>速度</div>
<div style={{ fontSize: 24, fontWeight: 'bold' }}>3.15GHZ</div>
</div>
</div>
<div className='second-row' style={{ display: 'flex', columnGap: 10 }}>
<div>
<div>进程</div>
<div style={{ fontSize: 24, fontWeight: 'bold' }}>20%</div>
</div>
<div>
<div>线程</div>
<div style={{ fontSize: 24, fontWeight: 'bold' }}>20%</div>
</div><div>
<div>句柄</div>
<div style={{ fontSize: 24, fontWeight: 'bold' }}>20%</div>
</div>
</div>
<div className='second-row' style={{ display: 'flex', columnGap: 10 }}>
<div>
<div>正常运行时间</div>
<div style={{ fontSize: 24, fontWeight: 'bold' }}>20%</div>
</div>
</div>
</div>
<div className='right'>
<div className='first' style={{display:'flex',columnGap:0,alignItems:'center'}}>
<div style={{ width: 100,fontSize:16 }}>基准速度</div>
<div style={{width:100,fontSize:16}}>2.00GHZ</div>
</div>
<div className='second' style={{display:'flex',columnGap:10,alignItems:'center'}}>
<div style={{ width: 100,fontSize:16 }}>插槽</div>
<div style={{width:100,fontSize:16}}>1</div>
</div>
<div className='second1' style={{display:'flex',columnGap:10,alignItems:'center'}}>
<div style={{ width: 100,fontSize:16 }}>内核</div>
<div style={{width:100,fontSize:16}}>8</div>
</div>
<div className='second2' style={{display:'flex',columnGap:10,alignItems:'center'}}>
<div style={{ width: 100,fontSize:16 }}>逻辑处理器</div>
<div style={{width:100,fontSize:16}}>8</div>
</div>
<div className='second4' style={{display:'flex',columnGap:10,alignItems:'center'}}>
<div style={{ width: 100,fontSize:16 }}>虚拟化</div>
<div style={{width:100,fontSize:16}}>已启用</div>
</div>
<div className='second3' style={{display:'flex',columnGap:10,alignItems:'center'}}>
<div style={{ width: 100,fontSize:16 }}>L1缓存</div>
<div style={{width:100,fontSize:16}}>512</div>
</div>
<div className='second5' style={{display:'flex',columnGap:10,alignItems:'center'}}>
<div style={{ width: 100,fontSize:16 }}>L2缓存</div>
<div style={{width:100,fontSize:16}}>512</div>
</div>
<div className='second6' style={{display:'flex',columnGap:10,alignItems:'center'}}>
<div style={{ width: 100,fontSize:16 }}>L3缓存</div>
<div style={{width:100,fontSize:16}}>512</div>
</div>
</div>
</div> */}
</div>
)
}

View File

@ -0,0 +1,61 @@
import React,{useState,useEffect} from 'react'
import { Card, Tabs } from "antd"
import Cpu from './Cpu';
import Memory from './Memory.js';
import Disk from './Disk.js';
import apiurl from '../../../models/apiurl'
import { httppost,httpget } from '../../../utils/request.js';
export default function Sssj() {
const items = [
{
key: '1',
label: 'CPU',
children: '',
},
{
key: '2',
label: '内存',
children: '',
},
{
key: '3',
label: '存储',
children: '',
},
];
const [objData, setObjData] = useState({})
const [tabs, setTabs] = useState('1');
const getCpuReal = async (tabs) => {
const url = tabs == '1' ? apiurl.ptjs.realCpu :
tabs == '2' ? apiurl.ptjs.realMemory :
tabs == '3' ? apiurl.ptjs.realDisk :
apiurl.ptjs.realCpu;
try {
const res = await httpget(url)
if (res.code == 200) {
setObjData(res.data)
}
} catch (error) {
console.log(error);
}
}
useEffect(() => {
getCpuReal(tabs)
}, [tabs])
return (
<div className='page'>
<Card style={{ display: 'flex', flexDirection: 'column',width:'100%',marginRight:10 }}>
<div className='flex' style={{ alignItems: 'center', marginRight: 10, marginBottom: 20 }}>
<img src={require('../../../assets/images/panelTitle.png')} style={{ marginRight: 5 }}></img>
<span style={{ fontSize: 16, fontWeight: 'bold' }}>资源使用</span>
</div>
<Tabs defaultActiveKey="1" items={items} onChange={(e) => setTabs(e)}/>
{tabs === '1' && <Cpu data={objData} />}
{tabs === '2' && <Memory data={objData} />}
{tabs === '3' && <Disk data={objData} />}
</Card>
</div>
)
}

View File

@ -0,0 +1,16 @@
.resourceTitle{
display: flex;
justify-content: space-between;
padding: 0 10px;
}
.echarts-resource-box{
width: 100%;
height: 440px;
}
.cpu-list{
display: flex;
column-gap: 10px;
.left{
}
}