Merge branch 'main' of http://192.168.2.166:3180/OMC/ems_frontend_vue3
This commit is contained in:
@@ -350,6 +350,9 @@ onBeforeUnmount(() => {
|
|||||||
<a-descriptions-item :label="t('views.index.version')">{{
|
<a-descriptions-item :label="t('views.index.version')">{{
|
||||||
pronInfo.version
|
pronInfo.version
|
||||||
}}</a-descriptions-item>
|
}}</a-descriptions-item>
|
||||||
|
<a-descriptions-item :label="t('views.index.capability')">{{
|
||||||
|
pronInfo.capability
|
||||||
|
}}</a-descriptions-item>
|
||||||
<a-descriptions-item :label="t('views.index.cpuUse')">{{
|
<a-descriptions-item :label="t('views.index.cpuUse')">{{
|
||||||
pronInfo.cpuUse
|
pronInfo.cpuUse
|
||||||
}}</a-descriptions-item>
|
}}</a-descriptions-item>
|
||||||
|
|||||||
@@ -176,7 +176,7 @@ let tableColumns: ColumnsType = [
|
|||||||
width: 150,
|
width: 150,
|
||||||
customRender(opt) {
|
customRender(opt) {
|
||||||
const cdrJSON = opt.value;
|
const cdrJSON = opt.value;
|
||||||
if (typeof cdrJSON.seizureTime === 'number') {
|
if (typeof cdrJSON.updateTime === 'number') {
|
||||||
return parseDateToStr(+cdrJSON.updateTime * 1000);
|
return parseDateToStr(+cdrJSON.updateTime * 1000);
|
||||||
}
|
}
|
||||||
return cdrJSON.updateTime;
|
return cdrJSON.updateTime;
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ interface ChartDataItem {
|
|||||||
[kpiId: string]: string | number; // 动态指标
|
[kpiId: string]: string | number; // 动态指标
|
||||||
}
|
}
|
||||||
const tableLoading = ref(false);
|
const tableLoading = ref(false);
|
||||||
|
const rangeLoading = ref(false);
|
||||||
//网元类型定义
|
//网元类型定义
|
||||||
const ALL_NE_TYPES = ['AMF','SMF','UPF','MME','IMS','SMSC'] as const;
|
const ALL_NE_TYPES = ['AMF','SMF','UPF','MME','IMS','SMSC'] as const;
|
||||||
type NeType= typeof ALL_NE_TYPES[number];
|
type NeType= typeof ALL_NE_TYPES[number];
|
||||||
@@ -47,6 +48,18 @@ echarts.use([
|
|||||||
// WebSocket连接
|
// WebSocket连接
|
||||||
const ws = ref<WS | null>(null);
|
const ws = ref<WS | null>(null);
|
||||||
|
|
||||||
|
//时间选择
|
||||||
|
let ranges = ref<Record<string, [Dayjs, Dayjs]>>({
|
||||||
|
[t('views.perfManage.customTarget.sixHoursAgo')]: [
|
||||||
|
dayjs().subtract(6, 'hours'),
|
||||||
|
dayjs(),
|
||||||
|
],
|
||||||
|
[t('views.perfManage.customTarget.threeHoursAgo')]: [
|
||||||
|
dayjs().subtract(3, 'hours'),
|
||||||
|
dayjs(),
|
||||||
|
],
|
||||||
|
[t('views.monitor.monitor.today')]: [dayjs().startOf('day'), dayjs()],
|
||||||
|
});
|
||||||
//日期范围响应式变量
|
//日期范围响应式变量
|
||||||
const dateRange = ref<[string, string]>([
|
const dateRange = ref<[string, string]>([
|
||||||
dayjs().startOf('hour').valueOf().toString(),
|
dayjs().startOf('hour').valueOf().toString(),
|
||||||
@@ -168,8 +181,10 @@ const processChartData = (rawData: any[]) => {
|
|||||||
}
|
}
|
||||||
Object.assign(groupedData.get(timeKey), item);
|
Object.assign(groupedData.get(timeKey), item);
|
||||||
});
|
});
|
||||||
|
// 获取当前选择的结束时间
|
||||||
|
const endTime = dateRange.value[1];
|
||||||
|
|
||||||
return Array.from(groupedData.values())
|
const processedData = Array.from(groupedData.values())
|
||||||
.sort((a, b) => Number(a.timeGroup) - Number(b.timeGroup))
|
.sort((a, b) => Number(a.timeGroup) - Number(b.timeGroup))
|
||||||
.map(item => {//转换成图表需要的格式
|
.map(item => {//转换成图表需要的格式
|
||||||
const dataItem: ChartDataItem = { date: item.timeGroup.toString() };
|
const dataItem: ChartDataItem = { date: item.timeGroup.toString() };
|
||||||
@@ -178,6 +193,17 @@ const processChartData = (rawData: any[]) => {
|
|||||||
});
|
});
|
||||||
return dataItem;
|
return dataItem;
|
||||||
});
|
});
|
||||||
|
// 如果有数据,且最后一个数据点的时间小于选择的结束时间
|
||||||
|
if (processedData.length > 0 && Number(processedData[processedData.length - 1].date) < Number(endTime)) {
|
||||||
|
// 添加一个结束时间点,所有指标值设为0
|
||||||
|
const endDataPoint: ChartDataItem = { date: endTime };
|
||||||
|
selectedKPIs.value.forEach(kpiId => {
|
||||||
|
endDataPoint[kpiId] = 0;
|
||||||
|
});
|
||||||
|
processedData.push(endDataPoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
return processedData;
|
||||||
};
|
};
|
||||||
// 获取图表数据方法
|
// 获取图表数据方法
|
||||||
const fetchChartData = async () => {
|
const fetchChartData = async () => {
|
||||||
@@ -185,6 +211,8 @@ const fetchChartData = async () => {
|
|||||||
updateChart();
|
updateChart();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
tableLoading.value=true;
|
||||||
|
rangeLoading.value=true;
|
||||||
try {
|
try {
|
||||||
const[startTime,endTime]=dateRange.value;
|
const[startTime,endTime]=dateRange.value;
|
||||||
if (!startTime || !endTime) {
|
if (!startTime || !endTime) {
|
||||||
@@ -226,6 +254,9 @@ const fetchChartData = async () => {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to fetch chart data:', error);
|
console.error('Failed to fetch chart data:', error);
|
||||||
message.error(t('common.getInfoFail'));
|
message.error(t('common.getInfoFail'));
|
||||||
|
}finally {
|
||||||
|
tableLoading.value=false;
|
||||||
|
rangeLoading.value=false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -250,6 +281,26 @@ const updateChart = () => {
|
|||||||
const color = kpiColors.get(kpiId)||generateColorRGBA();
|
const color = kpiColors.get(kpiId)||generateColorRGBA();
|
||||||
kpiColors.set(kpiId, color);
|
kpiColors.set(kpiId, color);
|
||||||
|
|
||||||
|
// 获取数据数组
|
||||||
|
const data = chartData.value.map((item, index) => {
|
||||||
|
const value = item[kpiId] || 0;
|
||||||
|
// 如果是最后一个数据点,添加特殊样式
|
||||||
|
if (index === chartData.value.length - 1) {
|
||||||
|
return {
|
||||||
|
value,
|
||||||
|
symbolSize: 12, // 更大的节点
|
||||||
|
itemStyle: {
|
||||||
|
color, // 保持与线条相同的颜色
|
||||||
|
borderWidth: 3, // 添加边框
|
||||||
|
borderColor: color, // 边框颜色
|
||||||
|
shadowBlur: 10, // 添加阴影效果
|
||||||
|
shadowColor: color,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
name: kpi.title,
|
name: kpi.title,
|
||||||
type: 'line',
|
type: 'line',
|
||||||
@@ -266,6 +317,27 @@ const updateChart = () => {
|
|||||||
},
|
},
|
||||||
tooltip: {
|
tooltip: {
|
||||||
trigger: 'axis',
|
trigger: 'axis',
|
||||||
|
position: function (point: number[], params: any, dom: HTMLElement, rect: any, size: { viewSize: number[], contentSize: number[] }) {
|
||||||
|
const [x, y] = point;
|
||||||
|
const [viewWidth] = size.viewSize;
|
||||||
|
const [tooltipWidth, tooltipHeight] = size.contentSize;
|
||||||
|
|
||||||
|
// 距离右侧的距离
|
||||||
|
const rightSpace = viewWidth - x;
|
||||||
|
|
||||||
|
// 计算垂直方向的居中位置
|
||||||
|
// 将 tooltip 的中心点对齐到鼠标位置
|
||||||
|
const verticalOffset = -tooltipHeight / 2;
|
||||||
|
|
||||||
|
// 如果右侧空间不足以显示tooltip(假设需要20px的安全距离)
|
||||||
|
if (rightSpace < tooltipWidth + 20) {
|
||||||
|
// 向左显示,垂直居中
|
||||||
|
return [x - tooltipWidth - 10, y + verticalOffset];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 默认向右显示,垂直居中
|
||||||
|
return [x + 10, y + verticalOffset];
|
||||||
|
},
|
||||||
},
|
},
|
||||||
legend: {
|
legend: {
|
||||||
data: selectedKPIs.value.map(kpiId =>
|
data: selectedKPIs.value.map(kpiId =>
|
||||||
@@ -309,6 +381,29 @@ const updateChart = () => {
|
|||||||
dayjs(Number(item.date)).format('YYYY-MM-DD HH:mm:ss')
|
dayjs(Number(item.date)).format('YYYY-MM-DD HH:mm:ss')
|
||||||
),
|
),
|
||||||
//设置坐标轴刻度标签的样式
|
//设置坐标轴刻度标签的样式
|
||||||
|
axisLabel: {
|
||||||
|
interval: function(index: number, value: string) {
|
||||||
|
const currentTime = dayjs(value);
|
||||||
|
const minutes = currentTime.minute();
|
||||||
|
const seconds = currentTime.second();
|
||||||
|
|
||||||
|
// 始终显示小时的起始和结束时间点
|
||||||
|
if ((minutes === 0 && seconds === 0) ||
|
||||||
|
(minutes === 59 && seconds === 59)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 对于中间的时间点,使用 auto 的逻辑
|
||||||
|
if (index % Math.ceil(chartData.value.length / 6) === 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
rotate: 0,
|
||||||
|
align: 'center',
|
||||||
|
hideOverlap: true
|
||||||
|
}
|
||||||
},
|
},
|
||||||
yAxis: {
|
yAxis: {
|
||||||
// y轴配置
|
// y轴配置
|
||||||
@@ -446,7 +541,7 @@ const updateChartData = (newData: ChartDataItem) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
chartData.value.push(newData);
|
chartData.value.push(newData);
|
||||||
if (chartData.value.length > 50) {//100改为50
|
if (chartData.value.length > 100) {//100改为50
|
||||||
chartData.value.shift();//大于100条时删除最早的数据
|
chartData.value.shift();//大于100条时删除最早的数据
|
||||||
}
|
}
|
||||||
//使用try-catch包裹图表更新逻辑
|
//使用try-catch包裹图表更新逻辑
|
||||||
@@ -590,6 +685,8 @@ const updateChartLegendSelect = (selectedKpiId?: string) => {
|
|||||||
format="YYYY-MM-DD HH:mm:ss"
|
format="YYYY-MM-DD HH:mm:ss"
|
||||||
:value-format="'x'"
|
:value-format="'x'"
|
||||||
:disabled="isRealtime"
|
:disabled="isRealtime"
|
||||||
|
:ranges="ranges"
|
||||||
|
:loading="rangeLoading"
|
||||||
@change="handleDateChange"
|
@change="handleDateChange"
|
||||||
/>
|
/>
|
||||||
<a-form-item
|
<a-form-item
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ async function fnIPerf() {
|
|||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (state.dataType === 'options' && state.data.host === '') {
|
if (state.dataType === 'options' && state.data.mode === 'client' && state.data.host === '') {
|
||||||
message.warning({
|
message.warning({
|
||||||
content: 'Please fill in the Host',
|
content: 'Please fill in the Host',
|
||||||
duration: 2,
|
duration: 2,
|
||||||
|
|||||||
Reference in New Issue
Block a user