Files
fe.ems.vue3/src/views/index.vue
2023-10-25 17:23:24 +08:00

491 lines
13 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script setup lang="ts">
import { PageContainer } from '@ant-design-vue/pro-layout';
import { ColumnsType } from 'ant-design-vue/lib/table';
import { message } from 'ant-design-vue/lib';
import { reactive, toRaw, ref, onMounted,onBeforeUnmount} from 'vue';
import { listMain } from '@/api/index';
import useI18n from '@/hooks/useI18n';
import { TooltipComponent } from 'echarts/components';
import { GaugeChart } from 'echarts/charts';
import { CanvasRenderer } from 'echarts/renderers';
import * as echarts from 'echarts/core';
import { TitleComponent, LegendComponent } from 'echarts/components';
import { PieChart } from 'echarts/charts';
import { LabelLayout } from 'echarts/features';
const { t } = useI18n();
echarts.use([
TooltipComponent,
GaugeChart,
TitleComponent,
LegendComponent,
PieChart,
CanvasRenderer,
LabelLayout,
]);
/**表格字段列 */
//customRender(){} ----单元格处理
let tableColumns: ColumnsType = [
{
title: '对象',
dataIndex: 'name',
align: 'center',
key: 'status',
},
{
title: '网元状态',
dataIndex: 'status',
align: 'center',
},
{
title: '刷新时间',
dataIndex: 'refresh',
align: 'center',
},
{
title: '版本',
dataIndex: 'version',
align: 'center',
},
{
title: 'IP地址',
dataIndex: 'ipAddress',
key: 'groupName',
align: 'center',
},
];
/**表格状态类型 */
type TabeStateType = {
/**加载等待 */
loading: boolean;
/**紧凑型 */
size: string;
/**斑马纹 */
striped: boolean;
/**搜索栏 */
seached: boolean;
/**记录数据 */
data: object[];
/**勾选记录 */
selectedRowKeys: (string | number)[];
};
/**表格状态 */
let tableState: TabeStateType = reactive({
loading: false,
size: 'middle',
striped: false,
seached: false,
data: [],
selectedRowKeys: [],
});
/**表格状态 */
let nfInfo: any = reactive({
obj: 'OMC',
version: '1.6.2',
status: '正常',
number: '',
outTimeDate: '',
});
/**表格状态类型 */
type nfStateType = {
/**主机名 */
hostName: string;
/**操作系统信息 */
osInfo: string;
/**数据库信息 */
dbInfo: string;
/**IP地址 */
ipAddress: string;
/**端口 */
port: number;
/**版本 */
version: string;
/**CPU利用率 */
cpuUse: string;
/**内存使用 */
memoryUse: string;
/**用户容量 */
capability: number;
/**序列号 */
serialNum: string;
/**许可证到期日期 */
/* selectedRowKeys: (string | number)[];*/
expiryDate: string;
};
/**网元详细信息 */
let pronInfo: nfStateType = reactive({
hostName: '5gc',
osInfo:
'Linux 5gc 4.15.0-112-generic #113-Ubuntu SMP Thu Jul 9 23:41:39 UTC 2020 x86_64 GNU/Linux',
dbInfo: 'adb v1.0.1',
ipAddress: '-',
port: 3030,
version: '-',
cpuUse: '-',
memoryUse: '-',
capability: 0,
serialNum: '-',
expiryDate: '-',
});
/**查询网元状态列表 */
function fnGetList() {
if (tableState.loading) return;
tableState.loading = true;
listMain().then(res => {
tableState.data = res;
tableState.loading = false;
var rightNum = 0;
var errorNum = 0;
for (let i = 0; i < res.length; i++) {
if (res[i].status == '正常') {
rightNum++;
} else {
errorNum++;
}
}
echarts.init(document.getElementById('echarts-records')).clear();
var chartDom = document.getElementById('echarts-records');
var myChart = echarts.init(chartDom);
var option = {
title: {
text: '',
subtext: '',
left: 'center',
},
tooltip: {
trigger: 'item',
},
legend: {
orient: 'vertical',
left: 'left',
},
series: [
{
name: '网元状态',
type: 'pie',
radius: '70%',
center: ['50%', '50%'],
data: [
{ value: rightNum, name: '正常' },
{ value: errorNum, name: '异常' },
],
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)',
},
},
label: {},
},
],
};
option && myChart.setOption(option);
window.onresize = function () {
// echarts 窗口缩放自适应 随着div--echarts-records的大小来适应
myChart.resize();
};
});
}
/**點擊網元名 */
function init(e: any) {
let realData = toRaw(e);
var chartDom = document.getElementById('echarts-records');
var myChart = echarts.init(chartDom);
myChart.clear(); //怕遗留以前得元素
let cpuUsage = realData.cpuUsage;
let memUsage = realData.memUsage;
var nfMenUsage =
Math.round((memUsage?.nfUsedMem / memUsage?.totalMem) * 10000) / 100.0;
let partitionInfo = realData.diskSpace?.partitionInfo[1];
var nfMaxDiskSpace =
Math.round((partitionInfo?.used / partitionInfo?.total) * 10000) / 100.0;
let option = {
tooltip: {
formatter: '{a} <br/>{b} : {c}%',
},
series: [
{
name: 'Nf Memory usage',
center: ['17%', '50%'],
radius: '80%',
type: 'gauge',
progress: {
show: true,
},
pointer: {
//仪表盘的指针
//这个show属性好像有问题因为在这次开发中需要去掉指正我设置false的时候还是显示指针估计是BUG吧我用的echarts-3.2.3希望改进。最终我把width属性设置为0成功搞定
show: true,
//指针长度
length: '60%',
},
title: {
offsetCenter: [0, '90%'],
},
detail: {
valueAnimation: true,
formatter: '{value}',
textStyle: {
fontSize: 18,
},
offsetCenter: [0, '60%'],
},
data: [
{
value: nfMenUsage,
name: 'MEM',
},
],
},
{
center: ['50%', '50%'],
name: 'Nf CPU usage',
radius: '80%',
type: 'gauge',
progress: {
show: true,
},
title: {
offsetCenter: [0, '90%'],
},
detail: {
valueAnimation: true,
formatter: '{value}',
textStyle: {
fontSize: 18,
},
offsetCenter: [0, '60%'],
},
data: [
{
value: cpuUsage?.nfCpuUsage / 100,
name: 'CPU',
},
],
},
{
center: ['83%', '50%'],
name: 'NF maximum disk usage',
radius: '80%',
type: 'gauge',
progress: {
show: true,
},
title: {
offsetCenter: [0, '90%'],
},
detail: {
valueAnimation: true,
formatter: '{value}',
textStyle: {
fontSize: 18,
},
offsetCenter: [0, '60%'],
},
data: [
{
value: nfMaxDiskSpace,
name: 'DiskSpace',
},
],
},
],
};
option && myChart.setOption(option);
window.onresize = function () {
// echarts 窗口缩放自适应 随着div--echarts-records的大小来适应
myChart.resize();
};
nfInfo.obj = realData.name;
nfInfo.number = realData.serialNum;
nfInfo.outTimeDate = realData.expiryDate;
}
/**抽屉 网元详细信息 */
const visible = ref(false);
const closeDrawer = () => {
visible.value = false;
};
/**抽屉 网元详细信息 */
/**监听表格行事件*/
function rowClick(record: any, index: any) {
return {
onClick: (event: any) => {
if (toRaw(record).status == '异常') {
message.error(`网元状态异常`, 2);
return false;
} else {
let pronData = toRaw(record);
//渲染详细信息
pronInfo = {
hostName: pronData.hostName,
osInfo: pronData.osInfo,
dbInfo: pronData.dbInfo,
ipAddress: pronData.ipAddress,
port: pronData.port,
version: pronData.version,
cpuUse:
pronData.name +
':' +
pronData.cpuUsage?.nfCpuUsage / 100 +
'%; ' +
'SYS:' +
pronData.cpuUsage?.sysCpuUsage / 100 +
'%',
memoryUse:
'Total:' +
pronData.memUsage?.totalMem +
'KB; ' +
pronData.name +
':' +
pronData.memUsage?.nfUsedMem +
'KB; SYS:' +
pronData.memUsage?.sysMemUsage +
'KB',
capability: pronData.capability,
serialNum: pronData.serialNum,
expiryDate: pronData.expiryDate,
};
}
visible.value = true;
},
};
}
let timer: any;
onMounted(() => {
fnGetList();
timer = setInterval(fnGetList, 10000); // 每隔10秒执行一次
});
// 在组件卸载之前清除定时器
onBeforeUnmount(() => {
clearInterval(timer);
});
</script>
<template>
<PageContainer :breadcrumb="false">
<div>
<a-drawer :visible="visible" @close="closeDrawer" :width="700">
<a-descriptions bordered :column="1" :label-style="{ width: '160px' }">
<a-descriptions-item :label="t('views.index.hostName')">{{
pronInfo.hostName
}}</a-descriptions-item>
<a-descriptions-item :label="t('views.index.osInfo')">{{
pronInfo.osInfo
}}</a-descriptions-item>
<a-descriptions-item :label="t('views.index.dbInfo')">{{
pronInfo.dbInfo
}}</a-descriptions-item>
<a-descriptions-item :label="t('views.index.ipAddress')">{{
pronInfo.ipAddress
}}</a-descriptions-item>
<a-descriptions-item :label="t('views.index.port')">{{
pronInfo.port
}}</a-descriptions-item>
<a-descriptions-item :label="t('views.index.version')">{{
pronInfo.version
}}</a-descriptions-item>
<a-descriptions-item :label="t('views.index.cpuUse')">{{
pronInfo.cpuUse
}}</a-descriptions-item>
<a-descriptions-item :label="t('views.index.memoryUse')">{{
pronInfo.memoryUse
}}</a-descriptions-item>
<a-descriptions-item :label="t('views.index.capability')">{{
pronInfo.capability
}}</a-descriptions-item>
<a-descriptions-item :label="t('views.index.serialNum')">{{
pronInfo.serialNum
}}</a-descriptions-item>
<a-descriptions-item :label="t('views.index.expiryDate')">{{
pronInfo.expiryDate
}}</a-descriptions-item>
</a-descriptions>
</a-drawer>
</div>
<a-row :gutter="16">
<a-col :lg="14" :md="16" :xs="24">
<!-- 表格列表 -->
<a-table
class="table"
row-key="id"
:columns="tableColumns"
:loading="tableState.loading"
:data-source="tableState.data"
:pagination="false"
:scroll="{ x: true }"
:customRow="rowClick"
>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'status'">
<div v-if="record.status == '正常'">
<a-tag color="blue" @click="init(record)">{{
record.name
}}</a-tag>
</div>
<div v-else>
<a-tag color="pink">{{ record.name }}</a-tag>
</div>
</template>
</template>
</a-table>
</a-col>
<a-col :lg="10" :md="8" :xs="24">
<a-card title="运行状态" style="margin-bottom: 16px">
<div
id="echarts-records"
style="width: 100%; min-height: 200px"
></div>
</a-card>
<a-card title="简略信息" style="margin-top: 16px">
<a-descriptions
bordered
:column="1"
:label-style="{ width: '160px' }"
>
<a-descriptions-item label="对象">{{
nfInfo.obj
}}</a-descriptions-item>
<template v-if="nfInfo.obj === 'OMC'">
<a-descriptions-item label="版本号">{{
nfInfo.version
}}</a-descriptions-item>
<a-descriptions-item label="系统状态">{{
nfInfo.status
}}</a-descriptions-item>
</template>
<template v-else>
<a-descriptions-item label="序列号">{{
nfInfo.number
}}</a-descriptions-item>
<a-descriptions-item label="许可证到期日期">{{
nfInfo.outTimeDate
}}</a-descriptions-item>
</template>
</a-descriptions>
</a-card>
</a-col>
</a-row>
</PageContainer>
</template>
<style lang="less" scoped></style>