优化指标界面
This commit is contained in:
@@ -607,12 +607,12 @@ onMounted(() => {
|
|||||||
<template #icon><FormOutlined /></template>
|
<template #icon><FormOutlined /></template>
|
||||||
</a-button>
|
</a-button>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
<!-- <a-tooltip>
|
<a-tooltip>
|
||||||
<template #title>{{ t('common.deleteText') }}</template>
|
<template #title>{{ t('common.deleteText') }}</template>
|
||||||
<a-button type="link" @click.prevent="fnRecordDelete(record)">
|
<a-button type="link" @click.prevent="fnRecordDelete(record)">
|
||||||
<template #icon><DeleteOutlined /></template>
|
<template #icon><DeleteOutlined /></template>
|
||||||
</a-button>
|
</a-button>
|
||||||
</a-tooltip> -->
|
</a-tooltip>
|
||||||
</a-space>
|
</a-space>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import {
|
|||||||
nextTick,
|
nextTick,
|
||||||
onBeforeUnmount,
|
onBeforeUnmount,
|
||||||
h,
|
h,
|
||||||
|
watch
|
||||||
} from 'vue';
|
} from 'vue';
|
||||||
import { PageContainer } from 'antdv-pro-layout';
|
import { PageContainer } from 'antdv-pro-layout';
|
||||||
import { message, Modal, TableColumnType } from 'ant-design-vue/es';
|
import { message, Modal, TableColumnType } from 'ant-design-vue/es';
|
||||||
@@ -43,6 +44,8 @@ import { generateColorRGBA } from '@/utils/generate-utils';
|
|||||||
import { OptionsType, WS } from '@/plugins/ws-websocket';
|
import { OptionsType, WS } from '@/plugins/ws-websocket';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
import { LineOutlined } from '@ant-design/icons-vue';
|
import { LineOutlined } from '@ant-design/icons-vue';
|
||||||
|
import useLayoutStore from '@/store/modules/layout';
|
||||||
|
const layoutStore = useLayoutStore();
|
||||||
const neInfoStore = useNeInfoStore();
|
const neInfoStore = useNeInfoStore();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const { t, currentLocale } = useI18n();
|
const { t, currentLocale } = useI18n();
|
||||||
@@ -216,6 +219,22 @@ const statsColumns: TableColumnType<any>[] = [
|
|||||||
key: 'title',
|
key: 'title',
|
||||||
width: '65%',
|
width: '65%',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: t('views.perfManage.kpiOverView.totalValue'),
|
||||||
|
dataIndex: 'total',
|
||||||
|
key: 'total',
|
||||||
|
width: '24%',
|
||||||
|
sorter: (a: any, b: any) => a.total - b.total,
|
||||||
|
sortDirections: ['ascend', 'descend'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('views.perfManage.kpiOverView.avgValue'),
|
||||||
|
dataIndex: 'avg',
|
||||||
|
key: 'avg',
|
||||||
|
width: '24%',
|
||||||
|
sorter: (a: any, b: any) => a.avg - b.avg,
|
||||||
|
sortDirections: ['ascend', 'descend'],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: t('views.perfManage.kpiOverView.maxValue'),
|
title: t('views.perfManage.kpiOverView.maxValue'),
|
||||||
dataIndex: 'max',
|
dataIndex: 'max',
|
||||||
@@ -389,11 +408,22 @@ function fnGetList() {
|
|||||||
const values = tableState.data.map((item: any) => {
|
const values = tableState.data.map((item: any) => {
|
||||||
return item[columns.key] ? Number(item[columns.key]) : 0;
|
return item[columns.key] ? Number(item[columns.key]) : 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 计算总值
|
||||||
|
const total = Number(values.reduce((sum, val) => sum + val, 0).toFixed(2));
|
||||||
|
|
||||||
|
// 计算平均值
|
||||||
|
const avg = values.length > 0
|
||||||
|
? Number((total / values.length).toFixed(2))
|
||||||
|
: 0;
|
||||||
|
|
||||||
kpiStats.value.push({
|
kpiStats.value.push({
|
||||||
kpiId: columns.key,
|
kpiId: columns.key,
|
||||||
title: columns.title,
|
title: columns.title,
|
||||||
max: values.length > 0 ? Math.max(...values) : 0,
|
max: values.length > 0 ? Math.max(...values) : 0,
|
||||||
min: values.length > 0 ? Math.min(...values) : 0,
|
min: values.length > 0 ? Math.min(...values) : 0,
|
||||||
|
avg: avg,
|
||||||
|
total: total
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -418,6 +448,7 @@ function fnRanderChart() {
|
|||||||
position: function (pt: any) {
|
position: function (pt: any) {
|
||||||
return [pt[0], '10%'];
|
return [pt[0], '10%'];
|
||||||
},
|
},
|
||||||
|
confine: true, // 限制 tooltip 显示范围
|
||||||
},
|
},
|
||||||
xAxis: {
|
xAxis: {
|
||||||
//x类别轴
|
//x类别轴
|
||||||
@@ -500,6 +531,9 @@ function fnRanderChartData() {
|
|||||||
key: `${columns.key}`,
|
key: `${columns.key}`,
|
||||||
type: 'line',
|
type: 'line',
|
||||||
symbol: 'none',
|
symbol: 'none',
|
||||||
|
symbolSize: 6,
|
||||||
|
smooth: 0.6,
|
||||||
|
showSymbol: true,
|
||||||
sampling: 'lttb',
|
sampling: 'lttb',
|
||||||
itemStyle: {
|
itemStyle: {
|
||||||
color: color,
|
color: color,
|
||||||
@@ -549,8 +583,32 @@ function fnRanderChartData() {
|
|||||||
xAxis: {
|
xAxis: {
|
||||||
type: 'category',
|
type: 'category',
|
||||||
boundaryGap: false,
|
boundaryGap: false,
|
||||||
|
axisLabel: {
|
||||||
|
color: document.documentElement.getAttribute('data-theme') === 'dark'
|
||||||
|
? '#CACADA'
|
||||||
|
: '#333'
|
||||||
|
},
|
||||||
|
splitLine: {
|
||||||
|
show: true,
|
||||||
|
lineStyle: {
|
||||||
|
color: getSplitLineColor()
|
||||||
|
}
|
||||||
|
},
|
||||||
data: chartDataXAxisData,
|
data: chartDataXAxisData,
|
||||||
},
|
},
|
||||||
|
yAxis: {
|
||||||
|
axisLabel: {
|
||||||
|
color: document.documentElement.getAttribute('data-theme') === 'dark'
|
||||||
|
? '#CACADA'
|
||||||
|
: '#333'
|
||||||
|
},
|
||||||
|
splitLine: {
|
||||||
|
show: true,
|
||||||
|
lineStyle: {
|
||||||
|
color: getSplitLineColor()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
series: chartDataYSeriesData,
|
series: chartDataYSeriesData,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -647,29 +705,38 @@ function wsMessage(res: Record<string, any>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 添加一个变量来跟踪当前选中的行
|
// 添加一个变量来跟踪当前选中的行
|
||||||
const selectedRow = ref<string | null>(null);
|
const selectedRow = ref<string[]>([]);
|
||||||
|
|
||||||
// 添加处理行点击的方法
|
// 添加处理行点击的方法
|
||||||
function handleRowClick(record: any) {
|
function handleRowClick(record: any) {
|
||||||
if (selectedRow.value === record.kpiId) {
|
const index = selectedRow.value.indexOf(record.kpiId);
|
||||||
// 如果点击的是当前选中的行,则取消选中
|
|
||||||
selectedRow.value = null;
|
// 如果已经选中,取消选中
|
||||||
// 更新图表,显示所有指标
|
if (index > -1) {
|
||||||
for (let key in chartLegendSelected) {
|
selectedRow.value.splice(index, 1);
|
||||||
chartLegendSelected[key] = true;
|
chartLegendSelected[record.title] = false;
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// 选中新行
|
// 添加新的选中项
|
||||||
selectedRow.value = record.kpiId;
|
selectedRow.value.push(record.kpiId);
|
||||||
// 更新图表,只显示选中的指标
|
|
||||||
for (let key in chartLegendSelected) {
|
// 如果只有一个选中项,重置为 false
|
||||||
if (key === record.title) {
|
if (selectedRow.value.length === 1) {
|
||||||
chartLegendSelected[key] = true;
|
Object.keys(chartLegendSelected).forEach(key => {
|
||||||
} else {
|
|
||||||
chartLegendSelected[key] = false;
|
chartLegendSelected[key] = false;
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
chartLegendSelected[record.title] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 如果没有选中项,设置所有图例为 true
|
||||||
|
if (selectedRow.value.length === 0) {
|
||||||
|
Object.keys(chartLegendSelected).forEach(key => {
|
||||||
|
chartLegendSelected[key] = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新图表设置
|
||||||
kpiChart.value.setOption({
|
kpiChart.value.setOption({
|
||||||
legend: {
|
legend: {
|
||||||
selected: chartLegendSelected,
|
selected: chartLegendSelected,
|
||||||
@@ -677,6 +744,73 @@ function handleRowClick(record: any) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 添加一个函数来获取当前主题下的网格线颜色
|
||||||
|
function getSplitLineColor() {
|
||||||
|
return document.documentElement.getAttribute('data-theme') === 'dark'
|
||||||
|
? '#333333'
|
||||||
|
: '#E8E8E8'; // 亮色模式返回 undefined,使用默认颜色
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监听主题变化
|
||||||
|
watch(
|
||||||
|
() => layoutStore.proConfig.theme, // 监听的值
|
||||||
|
(newValue) => {
|
||||||
|
if (kpiChart.value) {
|
||||||
|
const splitLineColor = getSplitLineColor();
|
||||||
|
// 绘制图数据
|
||||||
|
kpiChart.value.setOption(
|
||||||
|
{
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'axis',
|
||||||
|
position: function (pt: any) {
|
||||||
|
return [pt[0], '10%'];
|
||||||
|
},
|
||||||
|
confine: true, // 限制 tooltip 显示范围
|
||||||
|
backgroundColor: newValue === 'dark'
|
||||||
|
? 'rgba(48, 48, 48, 0.8)'
|
||||||
|
: 'rgba(255, 255, 255, 0.9)',
|
||||||
|
borderColor: newValue === 'dark'
|
||||||
|
? '#555'
|
||||||
|
: '#ddd',
|
||||||
|
textStyle: {
|
||||||
|
color: newValue === 'dark'
|
||||||
|
? '#CACADA'
|
||||||
|
: '#333'
|
||||||
|
},
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
|
axisLabel: {
|
||||||
|
color: newValue === 'dark'
|
||||||
|
? '#CACADA'
|
||||||
|
: '#333'
|
||||||
|
},
|
||||||
|
splitLine: {
|
||||||
|
show: true,
|
||||||
|
lineStyle: {
|
||||||
|
color: splitLineColor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
axisLabel: {
|
||||||
|
color: newValue === 'dark'
|
||||||
|
? '#CACADA'
|
||||||
|
: '#333'
|
||||||
|
},
|
||||||
|
splitLine: {
|
||||||
|
show: true,
|
||||||
|
lineStyle: {
|
||||||
|
color: splitLineColor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// 目前支持的 AMF AUSF MME MOCNGW NSSF SMF UDM UPF PCF
|
// 目前支持的 AMF AUSF MME MOCNGW NSSF SMF UDM UPF PCF
|
||||||
// 获取网元网元列表
|
// 获取网元网元列表
|
||||||
@@ -714,11 +848,16 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 查询当前小时
|
// 查询当前小时
|
||||||
const nowDate: Date = new Date();
|
const now = new Date();
|
||||||
nowDate.setMinutes(0, 0, 0);
|
now.setMinutes(0, 0, 0);
|
||||||
queryRangePicker.value[0] = `${nowDate.getTime()}`;
|
// 设置起始时间为整点前一小时
|
||||||
nowDate.setMinutes(59, 59, 59);
|
const startTime = new Date(now);
|
||||||
queryRangePicker.value[1] = `${nowDate.getTime()}`;
|
startTime.setHours(now.getHours() - 1);
|
||||||
|
queryRangePicker.value[0] = `${startTime.getTime()}`;
|
||||||
|
// 设置结束时间为整点
|
||||||
|
const endTime = new Date(now);
|
||||||
|
endTime.setMinutes(59, 59, 59);
|
||||||
|
queryRangePicker.value[1] = `${endTime.getTime()}`;
|
||||||
fnGetListTitle();
|
fnGetListTitle();
|
||||||
// 绘图
|
// 绘图
|
||||||
fnRanderChart();
|
fnRanderChart();
|
||||||
@@ -739,68 +878,42 @@ onBeforeUnmount(() => {
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<PageContainer>
|
<PageContainer>
|
||||||
<a-card
|
<a-card v-show="tableState.seached" :bordered="false" :body-style="{ marginBottom: '24px', paddingBottom: 0 }">
|
||||||
v-show="tableState.seached"
|
|
||||||
:bordered="false"
|
|
||||||
:body-style="{ marginBottom: '24px', paddingBottom: 0 }"
|
|
||||||
>
|
|
||||||
<!-- 表格搜索栏 -->
|
<!-- 表格搜索栏 -->
|
||||||
<a-form :model="queryParams" name="queryParamsFrom" layout="horizontal">
|
<a-form :model="queryParams" name="queryParamsFrom" layout="horizontal">
|
||||||
<a-row :gutter="16">
|
<a-row :gutter="16">
|
||||||
<a-col :lg="6" :md="12" :xs="24">
|
<a-col :lg="6" :md="12" :xs="24">
|
||||||
<a-form-item name="neType" :label="t('views.ne.common.neType')">
|
<a-form-item name="neType" :label="t('views.ne.common.neType')">
|
||||||
<a-cascader
|
<a-cascader v-model:value="state.neType" :options="neCascaderOptions" :allow-clear="false"
|
||||||
v-model:value="state.neType"
|
:placeholder="t('common.selectPlease')" />
|
||||||
:options="neCascaderOptions"
|
|
||||||
:allow-clear="false"
|
|
||||||
:placeholder="t('common.selectPlease')"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :lg="10" :md="12" :xs="24">
|
<a-col :lg="10" :md="12" :xs="24">
|
||||||
<a-form-item
|
<a-form-item :label="t('views.perfManage.goldTarget.timeFrame')" name="timeFrame">
|
||||||
:label="t('views.perfManage.goldTarget.timeFrame')"
|
<a-range-picker v-model:value="queryRangePicker" bordered :allow-clear="false"
|
||||||
name="timeFrame"
|
:show-time="{ format: 'HH:mm:ss' }" format="YYYY-MM-DD HH:mm:ss" value-format="x"
|
||||||
>
|
style="width: 100%"></a-range-picker>
|
||||||
<a-range-picker
|
|
||||||
v-model:value="queryRangePicker"
|
|
||||||
bordered
|
|
||||||
:allow-clear="false"
|
|
||||||
:show-time="{ format: 'HH:mm:ss' }"
|
|
||||||
format="YYYY-MM-DD HH:mm:ss"
|
|
||||||
value-format="x"
|
|
||||||
style="width: 100%"
|
|
||||||
></a-range-picker>
|
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :lg="4" :md="12" :xs="24">
|
<a-col :lg="4" :md="12" :xs="24">
|
||||||
<a-form-item
|
<a-form-item :label="t('views.perfManage.goldTarget.interval')" name="interval">
|
||||||
:label="t('views.perfManage.goldTarget.interval')"
|
<a-select v-model:value="queryParams.interval" :placeholder="t('common.selectPlease')" :options="[
|
||||||
name="interval"
|
{ label: '5S', value: 5 },
|
||||||
>
|
{ label: '1M', value: 60 },
|
||||||
<a-select
|
{ label: '5M', value: 300 },
|
||||||
v-model:value="queryParams.interval"
|
{ label: '15M', value: 900 },
|
||||||
:placeholder="t('common.selectPlease')"
|
{ label: '30M', value: 1800 },
|
||||||
:options="[
|
{ label: '60M', value: 3600 },
|
||||||
{ label: '5S', value: 5 },
|
]" />
|
||||||
{ label: '1M', value: 60 },
|
|
||||||
{ label: '5M', value: 300 },
|
|
||||||
{ label: '15M', value: 900 },
|
|
||||||
{ label: '30M', value: 1800 },
|
|
||||||
{ label: '60M', value: 3600 },
|
|
||||||
]"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :lg="2" :md="12" :xs="24">
|
<a-col :lg="2" :md="12" :xs="24">
|
||||||
<a-form-item>
|
<a-form-item>
|
||||||
<a-space :size="8">
|
<a-space :size="8">
|
||||||
<a-button
|
<a-button type="primary" :loading="tableState.loading" @click.prevent="fnGetListTitle()">
|
||||||
type="primary"
|
<template #icon>
|
||||||
:loading="tableState.loading"
|
<SearchOutlined />
|
||||||
@click.prevent="fnGetListTitle()"
|
</template>
|
||||||
>
|
|
||||||
<template #icon><SearchOutlined /></template>
|
|
||||||
{{ t('common.search') }}
|
{{ t('common.search') }}
|
||||||
</a-button>
|
</a-button>
|
||||||
</a-space>
|
</a-space>
|
||||||
@@ -814,24 +927,18 @@ onBeforeUnmount(() => {
|
|||||||
<!-- 插槽-卡片左侧侧 -->
|
<!-- 插槽-卡片左侧侧 -->
|
||||||
<template #title>
|
<template #title>
|
||||||
<a-space :size="8" align="center">
|
<a-space :size="8" align="center">
|
||||||
<a-button
|
<a-button type="primary" :loading="tableState.loading" @click.prevent="fnChangShowType()">
|
||||||
type="primary"
|
<template #icon>
|
||||||
:loading="tableState.loading"
|
<AreaChartOutlined />
|
||||||
@click.prevent="fnChangShowType()"
|
</template>
|
||||||
>
|
|
||||||
<template #icon> <AreaChartOutlined /> </template>
|
|
||||||
{{
|
{{
|
||||||
tableState.showTable
|
tableState.showTable
|
||||||
? t('views.perfManage.goldTarget.kpiChartTitle')
|
? t('views.perfManage.goldTarget.kpiChartTitle')
|
||||||
: t('views.perfManage.goldTarget.kpiTableTitle')
|
: t('views.perfManage.goldTarget.kpiTableTitle')
|
||||||
}}
|
}}
|
||||||
</a-button>
|
</a-button>
|
||||||
<a-button
|
<a-button type="dashed" :loading="tableState.loading" @click.prevent="fnRecordExport()"
|
||||||
type="dashed"
|
v-show="tableState.showTable">
|
||||||
:loading="tableState.loading"
|
|
||||||
@click.prevent="fnRecordExport()"
|
|
||||||
v-show="tableState.showTable"
|
|
||||||
>
|
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<ExportOutlined />
|
<ExportOutlined />
|
||||||
</template>
|
</template>
|
||||||
@@ -846,26 +953,23 @@ onBeforeUnmount(() => {
|
|||||||
<a-tooltip>
|
<a-tooltip>
|
||||||
<template #title>{{ t('common.reloadText') }}</template>
|
<template #title>{{ t('common.reloadText') }}</template>
|
||||||
<a-button type="text" @click.prevent="fnGetList()">
|
<a-button type="text" @click.prevent="fnGetList()">
|
||||||
<template #icon><ReloadOutlined /></template>
|
<template #icon>
|
||||||
|
<ReloadOutlined />
|
||||||
|
</template>
|
||||||
</a-button>
|
</a-button>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
<TableColumnsDnd
|
<TableColumnsDnd v-if="tableColumns.length > 0" :cache-id="`kpiTarget_${state.neType[0]}`"
|
||||||
v-if="tableColumns.length > 0"
|
:columns="tableColumns" v-model:columns-dnd="tableColumnsDnd"></TableColumnsDnd>
|
||||||
:cache-id="`kpiTarget_${state.neType[0]}`"
|
|
||||||
:columns="tableColumns"
|
|
||||||
v-model:columns-dnd="tableColumnsDnd"
|
|
||||||
></TableColumnsDnd>
|
|
||||||
<a-tooltip>
|
<a-tooltip>
|
||||||
<template #title>{{ t('common.sizeText') }}</template>
|
<template #title>{{ t('common.sizeText') }}</template>
|
||||||
<a-dropdown trigger="click" placement="bottomRight">
|
<a-dropdown trigger="click" placement="bottomRight">
|
||||||
<a-button type="text">
|
<a-button type="text">
|
||||||
<template #icon><ColumnHeightOutlined /></template>
|
<template #icon>
|
||||||
|
<ColumnHeightOutlined />
|
||||||
|
</template>
|
||||||
</a-button>
|
</a-button>
|
||||||
<template #overlay>
|
<template #overlay>
|
||||||
<a-menu
|
<a-menu :selected-keys="[tableState.size as string]" @click="fnTableSize">
|
||||||
:selected-keys="[tableState.size as string]"
|
|
||||||
@click="fnTableSize"
|
|
||||||
>
|
|
||||||
<a-menu-item key="default">
|
<a-menu-item key="default">
|
||||||
{{ t('common.size.default') }}
|
{{ t('common.size.default') }}
|
||||||
</a-menu-item>
|
</a-menu-item>
|
||||||
@@ -894,37 +998,19 @@ onBeforeUnmount(() => {
|
|||||||
size="small"
|
size="small"
|
||||||
/>
|
/>
|
||||||
</a-form-item> -->
|
</a-form-item> -->
|
||||||
<a-form-item
|
<a-form-item :label="t('views.perfManage.goldTarget.realTimeData')" name="chartRealTime">
|
||||||
:label="t('views.perfManage.goldTarget.realTimeData')"
|
<a-switch :disabled="tableState.loading" v-model:checked="state.chartRealTime"
|
||||||
name="chartRealTime"
|
:checked-children="t('common.switch.open')" :un-checked-children="t('common.switch.shut')"
|
||||||
>
|
@change="fnRealTimeSwitch" size="small" />
|
||||||
<a-switch
|
|
||||||
:disabled="tableState.loading"
|
|
||||||
v-model:checked="state.chartRealTime"
|
|
||||||
:checked-children="t('common.switch.open')"
|
|
||||||
:un-checked-children="t('common.switch.shut')"
|
|
||||||
@change="fnRealTimeSwitch"
|
|
||||||
size="small"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-form>
|
</a-form>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- 表格列表 -->
|
<!-- 表格列表 -->
|
||||||
<a-table
|
<a-table v-show="tableState.showTable" class="table" row-key="id" :columns="tableColumnsDnd"
|
||||||
v-show="tableState.showTable"
|
:loading="tableState.loading" :data-source="tableState.data" :size="tableState.size"
|
||||||
class="table"
|
:pagination="tablePagination" :scroll="{ x: tableColumnsDnd.length * 200, y: 'calc(100vh - 480px)' }"
|
||||||
row-key="id"
|
@resizeColumn="(w: number, col: any) => (col.width = w)" :show-expand-column="false" @change="fnTableChange">
|
||||||
:columns="tableColumnsDnd"
|
|
||||||
:loading="tableState.loading"
|
|
||||||
:data-source="tableState.data"
|
|
||||||
:size="tableState.size"
|
|
||||||
:pagination="tablePagination"
|
|
||||||
:scroll="{ x: tableColumnsDnd.length * 200, y: 'calc(100vh - 480px)' }"
|
|
||||||
@resizeColumn="(w:number, col:any) => (col.width = w)"
|
|
||||||
:show-expand-column="false"
|
|
||||||
@change="fnTableChange"
|
|
||||||
>
|
|
||||||
<template #bodyCell="{ column, record }">
|
<template #bodyCell="{ column, record }">
|
||||||
<template v-if="column.key === 'timeGroup'">
|
<template v-if="column.key === 'timeGroup'">
|
||||||
{{ parseDateToStr(+record.timeGroup) }}
|
{{ parseDateToStr(+record.timeGroup) }}
|
||||||
@@ -934,26 +1020,15 @@ onBeforeUnmount(() => {
|
|||||||
|
|
||||||
<!-- 图表 -->
|
<!-- 图表 -->
|
||||||
<div style="padding: 24px" v-show="!tableState.showTable">
|
<div style="padding: 24px" v-show="!tableState.showTable">
|
||||||
<div
|
<div ref="kpiChartDom" class="chart-container" style="height: 450px; width: 100%"></div>
|
||||||
ref="kpiChartDom"
|
|
||||||
class="chart-container"
|
|
||||||
style="height: 450px; width: 100%"
|
|
||||||
></div>
|
|
||||||
|
|
||||||
<div class="table-container">
|
<div class="table-container">
|
||||||
<a-table
|
<a-table :columns="statsColumns" :data-source="kpiStats" :pagination="false" :scroll="{ y: 250 }" size="small"
|
||||||
:columns="statsColumns"
|
:custom-row="record => ({
|
||||||
:data-source="kpiStats"
|
onClick: () => handleRowClick(record),
|
||||||
:pagination="false"
|
class: selectedRow.includes(record.kpiId) ? 'selected-row' : ''
|
||||||
:scroll="{ y: 250 }"
|
})
|
||||||
size="small"
|
" />
|
||||||
:custom-row="
|
|
||||||
record => ({
|
|
||||||
onClick: () => handleRowClick(record),
|
|
||||||
class: record.kpiId === selectedRow ? 'selected-row' : '',
|
|
||||||
})
|
|
||||||
"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</a-card>
|
</a-card>
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import {
|
|||||||
nextTick,
|
nextTick,
|
||||||
onBeforeUnmount,
|
onBeforeUnmount,
|
||||||
h,
|
h,
|
||||||
|
watch,
|
||||||
} from 'vue';
|
} from 'vue';
|
||||||
import { PageContainer } from 'antdv-pro-layout';
|
import { PageContainer } from 'antdv-pro-layout';
|
||||||
import { message, Modal, TableColumnType } from 'ant-design-vue/es';
|
import { message, Modal, TableColumnType } from 'ant-design-vue/es';
|
||||||
@@ -45,11 +46,15 @@ import { OptionsType, WS } from '@/plugins/ws-websocket';
|
|||||||
import { LineOutlined } from '@ant-design/icons-vue';
|
import { LineOutlined } from '@ant-design/icons-vue';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
import dayjs, { Dayjs } from 'dayjs';
|
import dayjs, { Dayjs } from 'dayjs';
|
||||||
|
import useLayoutStore from '@/store/modules/layout';
|
||||||
|
const layoutStore = useLayoutStore();
|
||||||
const neInfoStore = useNeInfoStore();
|
const neInfoStore = useNeInfoStore();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const { t, currentLocale } = useI18n();
|
const { t, currentLocale } = useI18n();
|
||||||
const ws = new WS();
|
const ws = new WS();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
echarts.use([
|
echarts.use([
|
||||||
TooltipComponent,
|
TooltipComponent,
|
||||||
GridComponent,
|
GridComponent,
|
||||||
@@ -239,6 +244,14 @@ const statsColumns: TableColumnType<any>[] = [
|
|||||||
key: 'title',
|
key: 'title',
|
||||||
width: '65%',
|
width: '65%',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: t('views.perfManage.kpiOverView.avgValue'),
|
||||||
|
dataIndex: 'avg',
|
||||||
|
key: 'avg',
|
||||||
|
width: '24%',
|
||||||
|
sorter: (a: any, b: any) => a.avg - b.avg,
|
||||||
|
sortDirections: ['ascend', 'descend'],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: t('views.perfManage.kpiOverView.maxValue'),
|
title: t('views.perfManage.kpiOverView.maxValue'),
|
||||||
dataIndex: 'max',
|
dataIndex: 'max',
|
||||||
@@ -435,11 +448,21 @@ function fnGetList() {
|
|||||||
const values = tableState.data.map((item: any) => {
|
const values = tableState.data.map((item: any) => {
|
||||||
return item[columns.key] ? Number(item[columns.key]) : 0;
|
return item[columns.key] ? Number(item[columns.key]) : 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// 计算总值
|
||||||
|
const total = Number(values.reduce((sum, val) => sum + val, 0).toFixed(2));
|
||||||
|
|
||||||
|
// 计算平均值
|
||||||
|
const avg = values.length > 0
|
||||||
|
? Number((total / values.length).toFixed(2))
|
||||||
|
: 0;
|
||||||
kpiStats.value.push({
|
kpiStats.value.push({
|
||||||
kpiId: columns.key,
|
kpiId: columns.key,
|
||||||
title: columns.title,
|
title: columns.title,
|
||||||
max: values.length > 0 ? Math.max(...values) : 0,
|
max: values.length > 0 ? Math.max(...values) : 0,
|
||||||
min: values.length > 0 ? Math.min(...values) : 0,
|
min: values.length > 0 ? Math.min(...values) : 0,
|
||||||
|
avg
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -463,6 +486,18 @@ function fnRanderChart() {
|
|||||||
position: function (pt: any) {
|
position: function (pt: any) {
|
||||||
return [pt[0], '10%'];
|
return [pt[0], '10%'];
|
||||||
},
|
},
|
||||||
|
confine: true, // 限制 tooltip 显示范围
|
||||||
|
backgroundColor: document.documentElement.getAttribute('data-theme') === 'dark'
|
||||||
|
? 'rgba(48, 48, 48, 0.8)'
|
||||||
|
: 'rgba(255, 255, 255, 0.9)',
|
||||||
|
borderColor: document.documentElement.getAttribute('data-theme') === 'dark'
|
||||||
|
? '#555'
|
||||||
|
: '#ddd',
|
||||||
|
textStyle: {
|
||||||
|
color: document.documentElement.getAttribute('data-theme') === 'dark'
|
||||||
|
? '#CACADA'
|
||||||
|
: '#333'
|
||||||
|
},
|
||||||
},
|
},
|
||||||
xAxis: {
|
xAxis: {
|
||||||
type: 'category',
|
type: 'category',
|
||||||
@@ -541,6 +576,9 @@ function fnRanderChartData() {
|
|||||||
key: `${columns.key}`,
|
key: `${columns.key}`,
|
||||||
type: 'line',
|
type: 'line',
|
||||||
symbol: 'none',
|
symbol: 'none',
|
||||||
|
symbolSize: 6,
|
||||||
|
smooth: 0.6,
|
||||||
|
showSymbol: true,
|
||||||
sampling: 'lttb',
|
sampling: 'lttb',
|
||||||
itemStyle: {
|
itemStyle: {
|
||||||
color: color,
|
color: color,
|
||||||
@@ -594,8 +632,32 @@ function fnRanderChartData() {
|
|||||||
xAxis: {
|
xAxis: {
|
||||||
type: 'category',
|
type: 'category',
|
||||||
boundaryGap: false,
|
boundaryGap: false,
|
||||||
|
axisLabel: {
|
||||||
|
color: document.documentElement.getAttribute('data-theme') === 'dark'
|
||||||
|
? '#CACADA'
|
||||||
|
: '#333'
|
||||||
|
},
|
||||||
|
splitLine: {
|
||||||
|
show: true,
|
||||||
|
lineStyle: {
|
||||||
|
color: getSplitLineColor()
|
||||||
|
}
|
||||||
|
},
|
||||||
data: chartDataXAxisData,
|
data: chartDataXAxisData,
|
||||||
},
|
},
|
||||||
|
yAxis: {
|
||||||
|
axisLabel: {
|
||||||
|
color: document.documentElement.getAttribute('data-theme') === 'dark'
|
||||||
|
? '#CACADA'
|
||||||
|
: '#333'
|
||||||
|
},
|
||||||
|
splitLine: {
|
||||||
|
show: true,
|
||||||
|
lineStyle: {
|
||||||
|
color: getSplitLineColor()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
series: chartDataYSeriesData,
|
series: chartDataYSeriesData,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -680,29 +742,38 @@ function wsMessage(res: Record<string, any>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 添加一个变量来跟踪当前选中的行
|
// 添加一个变量来跟踪当前选中的行
|
||||||
const selectedRow = ref<string | null>(null);
|
const selectedRow = ref<string[]>([]);
|
||||||
|
|
||||||
// 添加处理行点击的方法
|
// 添加处理行点击的方法
|
||||||
function handleRowClick(record: any) {
|
function handleRowClick(record: any) {
|
||||||
if (selectedRow.value === record.kpiId) {
|
const index = selectedRow.value.indexOf(record.kpiId);
|
||||||
// 如果点击的是当前选中的行,则取消选中
|
|
||||||
selectedRow.value = null;
|
// 如果已经选中,取消选中
|
||||||
// 更新图表,显示所有指标
|
if (index > -1) {
|
||||||
for (let key in chartLegendSelected) {
|
selectedRow.value.splice(index, 1);
|
||||||
chartLegendSelected[key] = true;
|
chartLegendSelected[record.title] = false;
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// 选中新行
|
// 添加新的选中项
|
||||||
selectedRow.value = record.kpiId;
|
selectedRow.value.push(record.kpiId);
|
||||||
// 更新图表,只显示选中的指标
|
|
||||||
for (let key in chartLegendSelected) {
|
// 如果只有一个选中项,重置为 false
|
||||||
if (key === record.title) {
|
if (selectedRow.value.length === 1) {
|
||||||
chartLegendSelected[key] = true;
|
Object.keys(chartLegendSelected).forEach(key => {
|
||||||
} else {
|
|
||||||
chartLegendSelected[key] = false;
|
chartLegendSelected[key] = false;
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
chartLegendSelected[record.title] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 如果没有选中项,设置所有图例为 true
|
||||||
|
if (selectedRow.value.length === 0) {
|
||||||
|
Object.keys(chartLegendSelected).forEach(key => {
|
||||||
|
chartLegendSelected[key] = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新图表设置
|
||||||
kpiChart.value.setOption({
|
kpiChart.value.setOption({
|
||||||
legend: {
|
legend: {
|
||||||
selected: chartLegendSelected,
|
selected: chartLegendSelected,
|
||||||
@@ -710,6 +781,66 @@ function handleRowClick(record: any) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 监听主题变化
|
||||||
|
watch(
|
||||||
|
() => layoutStore.proConfig.theme, // 监听的值
|
||||||
|
(newValue) => {
|
||||||
|
if (kpiChart.value) {
|
||||||
|
const splitLineColor = getSplitLineColor();
|
||||||
|
// 绘制图数据
|
||||||
|
kpiChart.value.setOption(
|
||||||
|
{
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'axis',
|
||||||
|
position: function (pt: any) {
|
||||||
|
return [pt[0], '10%'];
|
||||||
|
},
|
||||||
|
confine: true, // 限制 tooltip 显示范围
|
||||||
|
backgroundColor: newValue === 'dark'
|
||||||
|
? 'rgba(48, 48, 48, 0.8)'
|
||||||
|
: 'rgba(255, 255, 255, 0.9)',
|
||||||
|
borderColor: newValue === 'dark'
|
||||||
|
? '#555'
|
||||||
|
: '#ddd',
|
||||||
|
textStyle: {
|
||||||
|
color: newValue === 'dark'
|
||||||
|
? '#CACADA'
|
||||||
|
: '#333'
|
||||||
|
},
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
|
axisLabel: {
|
||||||
|
color: newValue === 'dark'
|
||||||
|
? '#CACADA'
|
||||||
|
: '#333'
|
||||||
|
},
|
||||||
|
splitLine: {
|
||||||
|
show: true,
|
||||||
|
lineStyle: {
|
||||||
|
color: splitLineColor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
axisLabel: {
|
||||||
|
color: newValue === 'dark'
|
||||||
|
? '#CACADA'
|
||||||
|
: '#333'
|
||||||
|
},
|
||||||
|
splitLine: {
|
||||||
|
show: true,
|
||||||
|
lineStyle: {
|
||||||
|
color: splitLineColor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// 目前支持的 AMF AUSF MME MOCNGW NSSF SMF UDM UPF PCF
|
// 目前支持的 AMF AUSF MME MOCNGW NSSF SMF UDM UPF PCF
|
||||||
// 获取网元网元列表
|
// 获取网元网元列表
|
||||||
@@ -761,7 +892,6 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 查询当前小时
|
// 查询当前小时
|
||||||
|
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
now.setMinutes(0, 0, 0);
|
now.setMinutes(0, 0, 0);
|
||||||
// 设置起始时间为整点前一小时
|
// 设置起始时间为整点前一小时
|
||||||
@@ -794,51 +924,31 @@ onBeforeUnmount(() => {
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<PageContainer>
|
<PageContainer>
|
||||||
<a-card
|
<a-card v-show="tableState.seached" :bordered="false" :body-style="{ marginBottom: '24px', paddingBottom: 0 }">
|
||||||
v-show="tableState.seached"
|
|
||||||
:bordered="false"
|
|
||||||
:body-style="{ marginBottom: '24px', paddingBottom: 0 }"
|
|
||||||
>
|
|
||||||
<!-- 表格搜索栏 -->
|
<!-- 表格搜索栏 -->
|
||||||
<a-form :model="queryParams" name="queryParamsFrom" layout="horizontal">
|
<a-form :model="queryParams" name="queryParamsFrom" layout="horizontal">
|
||||||
<a-row :gutter="16">
|
<a-row :gutter="16">
|
||||||
<a-col :lg="6" :md="12" :xs="24">
|
<a-col :lg="6" :md="12" :xs="24">
|
||||||
<a-form-item name="neType" :label="t('views.ne.common.neType')">
|
<a-form-item name="neType" :label="t('views.ne.common.neType')">
|
||||||
<a-cascader
|
<a-cascader v-model:value="state.neType" :options="neCascaderOptions" :allow-clear="false"
|
||||||
v-model:value="state.neType"
|
:placeholder="t('common.selectPlease')" />
|
||||||
:options="neCascaderOptions"
|
|
||||||
:allow-clear="false"
|
|
||||||
:placeholder="t('common.selectPlease')"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :lg="10" :md="12" :xs="24">
|
<a-col :lg="10" :md="12" :xs="24">
|
||||||
<a-form-item
|
<a-form-item :label="t('views.perfManage.goldTarget.timeFrame')" name="timeFrame">
|
||||||
:label="t('views.perfManage.goldTarget.timeFrame')"
|
<a-range-picker v-model:value="queryRangePicker" bordered :allow-clear="false"
|
||||||
name="timeFrame"
|
:show-time="{ format: 'HH:mm:ss' }" format="YYYY-MM-DD HH:mm:ss" value-format="x" :presets="ranges"
|
||||||
>
|
style="width: 100%"></a-range-picker>
|
||||||
<a-range-picker
|
|
||||||
v-model:value="queryRangePicker"
|
|
||||||
bordered
|
|
||||||
:allow-clear="false"
|
|
||||||
:show-time="{ format: 'HH:mm:ss' }"
|
|
||||||
format="YYYY-MM-DD HH:mm:ss"
|
|
||||||
value-format="x"
|
|
||||||
:presets="ranges"
|
|
||||||
style="width: 100%"
|
|
||||||
></a-range-picker>
|
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
|
|
||||||
<a-col :lg="2" :md="12" :xs="24">
|
<a-col :lg="2" :md="12" :xs="24">
|
||||||
<a-form-item>
|
<a-form-item>
|
||||||
<a-space :size="8">
|
<a-space :size="8">
|
||||||
<a-button
|
<a-button type="primary" :loading="tableState.loading" @click.prevent="fnGetListTitle()">
|
||||||
type="primary"
|
<template #icon>
|
||||||
:loading="tableState.loading"
|
<SearchOutlined />
|
||||||
@click.prevent="fnGetListTitle()"
|
</template>
|
||||||
>
|
|
||||||
<template #icon><SearchOutlined /></template>
|
|
||||||
{{ t('common.search') }}
|
{{ t('common.search') }}
|
||||||
</a-button>
|
</a-button>
|
||||||
</a-space>
|
</a-space>
|
||||||
@@ -852,24 +962,18 @@ onBeforeUnmount(() => {
|
|||||||
<!-- 插槽-卡片左侧侧 -->
|
<!-- 插槽-卡片左侧侧 -->
|
||||||
<template #title>
|
<template #title>
|
||||||
<a-space :size="8" align="center">
|
<a-space :size="8" align="center">
|
||||||
<a-button
|
<a-button type="primary" :loading="tableState.loading" @click.prevent="fnChangShowType()">
|
||||||
type="primary"
|
<template #icon>
|
||||||
:loading="tableState.loading"
|
<AreaChartOutlined />
|
||||||
@click.prevent="fnChangShowType()"
|
</template>
|
||||||
>
|
|
||||||
<template #icon> <AreaChartOutlined /> </template>
|
|
||||||
{{
|
{{
|
||||||
tableState.showTable
|
tableState.showTable
|
||||||
? t('views.perfManage.goldTarget.kpiChartTitle')
|
? t('views.perfManage.goldTarget.kpiChartTitle')
|
||||||
: t('views.perfManage.goldTarget.kpiTableTitle')
|
: t('views.perfManage.goldTarget.kpiTableTitle')
|
||||||
}}
|
}}
|
||||||
</a-button>
|
</a-button>
|
||||||
<a-button
|
<a-button type="dashed" :loading="tableState.loading" @click.prevent="fnRecordExport()"
|
||||||
type="dashed"
|
v-show="tableState.showTable">
|
||||||
:loading="tableState.loading"
|
|
||||||
@click.prevent="fnRecordExport()"
|
|
||||||
v-show="tableState.showTable"
|
|
||||||
>
|
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<ExportOutlined />
|
<ExportOutlined />
|
||||||
</template>
|
</template>
|
||||||
@@ -884,26 +988,23 @@ onBeforeUnmount(() => {
|
|||||||
<a-tooltip>
|
<a-tooltip>
|
||||||
<template #title>{{ t('common.reloadText') }}</template>
|
<template #title>{{ t('common.reloadText') }}</template>
|
||||||
<a-button type="text" @click.prevent="fnGetList()">
|
<a-button type="text" @click.prevent="fnGetList()">
|
||||||
<template #icon><ReloadOutlined /></template>
|
<template #icon>
|
||||||
|
<ReloadOutlined />
|
||||||
|
</template>
|
||||||
</a-button>
|
</a-button>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
<TableColumnsDnd
|
<TableColumnsDnd v-if="tableColumns.length > 0" :cache-id="`kpiTarget_${state.neType[0]}`"
|
||||||
v-if="tableColumns.length > 0"
|
:columns="tableColumns" v-model:columns-dnd="tableColumnsDnd"></TableColumnsDnd>
|
||||||
:cache-id="`kpiTarget_${state.neType[0]}`"
|
|
||||||
:columns="tableColumns"
|
|
||||||
v-model:columns-dnd="tableColumnsDnd"
|
|
||||||
></TableColumnsDnd>
|
|
||||||
<a-tooltip>
|
<a-tooltip>
|
||||||
<template #title>{{ t('common.sizeText') }}</template>
|
<template #title>{{ t('common.sizeText') }}</template>
|
||||||
<a-dropdown trigger="click" placement="bottomRight">
|
<a-dropdown trigger="click" placement="bottomRight">
|
||||||
<a-button type="text">
|
<a-button type="text">
|
||||||
<template #icon><ColumnHeightOutlined /></template>
|
<template #icon>
|
||||||
|
<ColumnHeightOutlined />
|
||||||
|
</template>
|
||||||
</a-button>
|
</a-button>
|
||||||
<template #overlay>
|
<template #overlay>
|
||||||
<a-menu
|
<a-menu :selected-keys="[tableState.size as string]" @click="fnTableSize">
|
||||||
:selected-keys="[tableState.size as string]"
|
|
||||||
@click="fnTableSize"
|
|
||||||
>
|
|
||||||
<a-menu-item key="default">
|
<a-menu-item key="default">
|
||||||
{{ t('common.size.default') }}
|
{{ t('common.size.default') }}
|
||||||
</a-menu-item>
|
</a-menu-item>
|
||||||
@@ -932,61 +1033,32 @@ onBeforeUnmount(() => {
|
|||||||
size="small"
|
size="small"
|
||||||
/>
|
/>
|
||||||
</a-form-item> -->
|
</a-form-item> -->
|
||||||
<a-form-item
|
<a-form-item :label="t('views.perfManage.goldTarget.realTimeData')" name="chartRealTime">
|
||||||
:label="t('views.perfManage.goldTarget.realTimeData')"
|
<a-switch :disabled="tableState.loading" v-model:checked="state.chartRealTime"
|
||||||
name="chartRealTime"
|
:checked-children="t('common.switch.open')" :un-checked-children="t('common.switch.shut')"
|
||||||
>
|
@change="fnRealTimeSwitch" size="small" />
|
||||||
<a-switch
|
|
||||||
:disabled="tableState.loading"
|
|
||||||
v-model:checked="state.chartRealTime"
|
|
||||||
:checked-children="t('common.switch.open')"
|
|
||||||
:un-checked-children="t('common.switch.shut')"
|
|
||||||
@change="fnRealTimeSwitch"
|
|
||||||
size="small"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-form>
|
</a-form>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- 表格列表 -->
|
<!-- 表格列表 -->
|
||||||
<a-table
|
<a-table v-show="tableState.showTable" class="table" row-key="id" :columns="tableColumnsDnd"
|
||||||
v-show="tableState.showTable"
|
:loading="tableState.loading" :data-source="tableState.data" :size="tableState.size"
|
||||||
class="table"
|
:pagination="tablePagination" :scroll="{ x: tableColumnsDnd.length * 200, y: 'calc(100vh - 480px)' }"
|
||||||
row-key="id"
|
@resizeColumn="(w: number, col: any) => (col.width = w)" :show-expand-column="false" @change="fnTableChange">
|
||||||
:columns="tableColumnsDnd"
|
|
||||||
:loading="tableState.loading"
|
|
||||||
:data-source="tableState.data"
|
|
||||||
:size="tableState.size"
|
|
||||||
:pagination="tablePagination"
|
|
||||||
:scroll="{ x: tableColumnsDnd.length * 200, y: 'calc(100vh - 480px)' }"
|
|
||||||
@resizeColumn="(w:number, col:any) => (col.width = w)"
|
|
||||||
:show-expand-column="false"
|
|
||||||
@change="fnTableChange"
|
|
||||||
>
|
|
||||||
</a-table>
|
</a-table>
|
||||||
|
|
||||||
<!-- 图表 -->
|
<!-- 图表 -->
|
||||||
<div style="padding: 24px" v-show="!tableState.showTable">
|
<div style="padding: 24px" v-show="!tableState.showTable">
|
||||||
<div
|
<div ref="kpiChartDom" class="chart-container" style="height: 450px; width: 100%"></div>
|
||||||
ref="kpiChartDom"
|
|
||||||
class="chart-container"
|
|
||||||
style="height: 450px; width: 100%"
|
|
||||||
></div>
|
|
||||||
|
|
||||||
<div class="table-container">
|
<div class="table-container">
|
||||||
<a-table
|
<a-table :columns="statsColumns" :data-source="kpiStats" :pagination="false" :scroll="{ y: 250 }" size="small"
|
||||||
:columns="statsColumns"
|
:custom-row="record => ({
|
||||||
:data-source="kpiStats"
|
onClick: () => handleRowClick(record),
|
||||||
:pagination="false"
|
class: selectedRow.includes(record.kpiId) ? 'selected-row' : ''
|
||||||
:scroll="{ y: 250 }"
|
})
|
||||||
size="small"
|
" />
|
||||||
:custom-row="
|
|
||||||
record => ({
|
|
||||||
onClick: () => handleRowClick(record),
|
|
||||||
class: record.kpiId === selectedRow ? 'selected-row' : '',
|
|
||||||
})
|
|
||||||
"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</a-card>
|
</a-card>
|
||||||
|
|||||||
Reference in New Issue
Block a user