From aa16a7356fb54f4a87effbf2deb7f3d7c1354e16 Mon Sep 17 00:00:00 2001 From: zhongzm Date: Wed, 30 Jul 2025 18:34:39 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E5=8F=82=E6=95=B0=E5=80=BC=E6=8E=A8?= =?UTF-8?q?=E9=80=81=E6=98=BE=E7=A4=BA=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/perfManage/overview/index.vue | 614 +++++++++++++++++++----- 1 file changed, 484 insertions(+), 130 deletions(-) diff --git a/src/views/perfManage/overview/index.vue b/src/views/perfManage/overview/index.vue index 27f9dfa3..3bae36fe 100644 --- a/src/views/perfManage/overview/index.vue +++ b/src/views/perfManage/overview/index.vue @@ -16,13 +16,17 @@ class="ims-select" :allow-clear="false" /> - - - - - - - + +
+ WebSocket状态: {{ wsStatus }} | 数据点数量: {{ imsRealtimeRawData.length }} +
+ + 测试数据更新 + @@ -213,14 +217,14 @@ async function fetchHistoryData(neId: string) { try { // 计算30分钟前的时间 const endTime = Date.now() - const startTime = endTime - (30 * 60 * 1000) // 30分钟前 + const beginTime = endTime - (30 * 60 * 1000) // 30分钟前 // 构建查询参数,与黄金指标界面保持一致 const params = { neType: 'IMS', neId: neId, interval: 60, // 1分钟颗粒度 - startTime: startTime.toString(), + beginTime: beginTime.toString(), endTime: endTime.toString(), sortField: 'timeGroup', sortOrder: 'desc', @@ -233,7 +237,7 @@ async function fetchHistoryData(neId: string) { const res = await listKPIData(params) console.log('历史数据响应:', res) - if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.data)) { + if (res.code === 200001 && Array.isArray(res.data)) { // 将历史数据转换为与实时数据相同的格式 const historyData = res.data.map((item: any) => ({ timestamp: item.timeGroup || Date.now(), @@ -246,6 +250,9 @@ async function fetchHistoryData(neId: string) { // 注意:这里直接赋值,因为这是初始加载历史数据 imsRealtimeRawData.value = historyData + console.log('历史数据加载完成,数据点数量:', imsRealtimeRawData.value.length) + console.log('最新历史数据时间戳:', historyData.length > 0 ? historyData[historyData.length - 1].timestamp : '无数据') + // 更新所有图表 updateActiveCallsChart() updateFailedCallsChart() @@ -375,6 +382,11 @@ function updateActiveCallsChart() { // 生成时间轴数据 const xAxisData = Array.from({ length: chartData.length }, (_, i) => i + 1) + // 计算最大值、最小值、最新值 + const maxValue = Math.max(...chartData) + const minValue = Math.min(...chartData) + const latestValue = chartData[chartData.length - 1] + chart.setOption({ grid: { left: 0, right: 0, top: 10, bottom: 10 }, xAxis: { type: 'category', show: false, data: xAxisData }, @@ -384,8 +396,45 @@ function updateActiveCallsChart() { type: 'line', symbol: 'none', lineStyle: { width: 2, color: '#1890ff' }, // 蓝色线条表示有数据 areaStyle: { color: 'rgba(24,144,255,0.1)' } // 淡蓝色填充 - }] + }], + graphic: [ + { + type: 'text', + right: 8, + top: 8, + style: { + text: maxValue.toString(), + fontSize: 12, + fill: '#666', + fontWeight: 'bold' + } + }, + { + type: 'text', + right: 8, + top: '50%', + style: { + text: latestValue.toString(), + fontSize: 12, + fill: '#1890ff', + fontWeight: 'bold' + } + }, + { + type: 'text', + right: 8, + bottom: 8, + style: { + text: minValue.toString(), + fontSize: 12, + fill: '#666', + fontWeight: 'bold' + } + } + ] }) + + console.log('updateActiveCallsChart - 图表更新完成') } // 更新failed calls图表 @@ -439,6 +488,11 @@ function updateFailedCallsChart() { // 生成时间轴数据 const xAxisData = Array.from({ length: chartData.length }, (_, i) => i + 1) + // 计算最大值、最小值、最新值 + const maxValue = Math.max(...chartData) + const minValue = Math.min(...chartData) + const latestValue = chartData[chartData.length - 1] + chart.setOption({ grid: { left: 0, right: 0, top: 10, bottom: 10 }, xAxis: { type: 'category', show: false, data: xAxisData }, @@ -448,7 +502,42 @@ function updateFailedCallsChart() { type: 'line', symbol: 'none', lineStyle: { width: 2, color: '#faad14' }, // 橙色线条表示failed calls areaStyle: { color: 'rgba(250,173,20,0.1)' } // 淡橙色填充 - }] + }], + graphic: [ + { + type: 'text', + right: 8, + top: 8, + style: { + text: maxValue.toString(), + fontSize: 12, + fill: '#666', + fontWeight: 'bold' + } + }, + { + type: 'text', + right: 8, + top: '50%', + style: { + text: latestValue.toString(), + fontSize: 12, + fill: '#faad14', + fontWeight: 'bold' + } + }, + { + type: 'text', + right: 8, + bottom: 8, + style: { + text: minValue.toString(), + fontSize: 12, + fill: '#666', + fontWeight: 'bold' + } + } + ] }) } @@ -501,6 +590,11 @@ function updateActiveRegistrationsChart() { // 生成时间轴数据 const xAxisData = Array.from({ length: chartData.length }, (_, i) => i + 1) + // 计算最大值、最小值、最新值 + const maxValue = Math.max(...chartData) + const minValue = Math.min(...chartData) + const latestValue = chartData[chartData.length - 1] + chart.setOption({ grid: { left: 0, right: 0, top: 10, bottom: 10 }, xAxis: { type: 'category', show: false, data: xAxisData }, @@ -510,7 +604,42 @@ function updateActiveRegistrationsChart() { type: 'line', symbol: 'none', lineStyle: { width: 2, color: '#1890ff' }, // 蓝色线条表示active registrations areaStyle: { color: 'rgba(24,144,255,0.1)' } // 淡蓝色填充 - }] + }], + graphic: [ + { + type: 'text', + right: 8, + top: 8, + style: { + text: maxValue.toString(), + fontSize: 12, + fill: '#666', + fontWeight: 'bold' + } + }, + { + type: 'text', + right: 8, + top: '50%', + style: { + text: latestValue.toString(), + fontSize: 12, + fill: '#1890ff', + fontWeight: 'bold' + } + }, + { + type: 'text', + right: 8, + bottom: 8, + style: { + text: minValue.toString(), + fontSize: 12, + fill: '#666', + fontWeight: 'bold' + } + } + ] }) } @@ -565,6 +694,11 @@ function updateFailedRegistrationsChart() { // 生成时间轴数据 const xAxisData = Array.from({ length: chartData.length }, (_, i) => i + 1) + // 计算最大值、最小值、最新值 + const maxValue = Math.max(...chartData) + const minValue = Math.min(...chartData) + const latestValue = chartData[chartData.length - 1] + chart.setOption({ grid: { left: 0, right: 0, top: 10, bottom: 10 }, xAxis: { type: 'category', show: false, data: xAxisData }, @@ -574,51 +708,86 @@ function updateFailedRegistrationsChart() { type: 'line', symbol: 'none', lineStyle: { width: 2, color: '#f5222d' }, // 红色线条表示failed registrations areaStyle: { color: 'rgba(245,34,45,0.1)' } // 淡红色填充 - }] + }], + graphic: [ + { + type: 'text', + right: 8, + top: 8, + style: { + text: maxValue.toString(), + fontSize: 12, + fill: '#666', + fontWeight: 'bold' + } + }, + { + type: 'text', + right: 8, + top: '50%', + style: { + text: latestValue.toString(), + fontSize: 12, + fill: '#f5222d', + fontWeight: 'bold' + } + }, + { + type: 'text', + right: 8, + bottom: 8, + style: { + text: minValue.toString(), + fontSize: 12, + fill: '#666', + fontWeight: 'bold' + } + } + ] }) } // 处理IMS实时数据(只存储当前选中网元) function handleIMSRealtimeData(res: any) { - // console.log('收到实时数据:', res) // 调试信息 + console.log('收到实时数据:', res) // 调试信息 - // 检查数据结构:后端实际格式是 {code: 1, data: {...}, msg: 'success'} + // 检查数据结构:后端实际格式是 {code: 200001, data: {...}, msg: 'success'} const { code, data, msg } = res - // 检查是否是错误响应 - if (code !== 1 || !data) { - // console.warn('收到错误响应或数据格式不正确:', res) // 调试信息 + // 检查是否是错误响应 - 修改为适配实际的code值 + if (code !== 200001 || !data) { + console.warn('收到错误响应或数据格式不正确:', res) // 调试信息 return } // 检查是否是连接确认消息(只包含clientId) if (data.clientId) { - // console.log('收到WebSocket连接确认消息:', data.clientId) // 调试信息 + console.log('收到WebSocket连接确认消息:', data.clientId) // 调试信息 return } // 检查是否是KPI数据消息(包含data和groupId) if (data.data && data.groupId) { - // console.log('收到KPI数据消息,groupId:', data.groupId) // 调试信息 + console.log('收到KPI数据消息,groupId:', data.groupId) // 调试信息 // 解析订阅组ID,确认是我们订阅的IMS网元 const [_, neType, neId] = data.groupId.split('_') if (neType !== 'IMS' || neId !== selectedImsNeId.value) { - // console.log('收到其他网元数据,忽略:', data.groupId) // 调试信息 + console.log('收到其他网元数据,忽略:', data.groupId) // 调试信息 return } const kpiEvent = data.data if (!kpiEvent) { - // console.warn('KPI事件数据为空') // 调试信息 + console.warn('KPI事件数据为空') // 调试信息 return } - // console.log('处理IMS网元KPI数据:', kpiEvent) // 调试信息 + console.log('处理IMS网元KPI数据:', kpiEvent) // 调试信息 // 确保数据结构正确 const dataToStore = { - timestamp: Date.now(), + timestamp: kpiEvent.timeGroup || Date.now(), data: kpiEvent } @@ -632,6 +801,10 @@ function handleIMSRealtimeData(res: any) { console.log('实时数据已添加,当前数据点数量:', imsRealtimeRawData.value.length) console.log('最新数据:', dataToStore) + console.log('最新数据时间戳:', dataToStore.timestamp) + + // 强制触发Vue响应式更新 + imsRealtimeRawData.value = [...imsRealtimeRawData.value] // 更新active calls图表 updateActiveCallsChart() @@ -642,7 +815,7 @@ function handleIMSRealtimeData(res: any) { // 更新failed registrations图表 updateFailedRegistrationsChart() } else { - // console.log('收到未知格式的数据:', data) // 调试信息 + console.log('收到未知格式的数据:', data) // 调试信息 } } @@ -669,16 +842,56 @@ onMounted(() => { // MOS - 保持原有的模拟数据 if (mosChartRef.value) { const chart = echarts.init(mosChartRef.value) + const mosData = [4.62, 4.50, 4.40, 4.35, 4.30] + const maxValue = Math.max(...mosData) + const minValue = Math.min(...mosData) + const latestValue = mosData[mosData.length - 1] + chart.setOption({ grid: { left: 0, right: 0, top: 10, bottom: 10 }, xAxis: { type: 'category', show: false, data: [1,2,3,4,5] }, yAxis: { type: 'value', show: false }, series: [{ - data: [4.62, 4.50, 4.40, 4.35, 4.30], + data: mosData, type: 'line', symbol: 'none', lineStyle: { width: 2, color: '#52c41a' }, areaStyle: { color: 'rgba(82,196,26,0.1)' } - }] + }], + graphic: [ + { + type: 'text', + right: 8, + top: 8, + style: { + text: maxValue.toFixed(2), + fontSize: 12, + fill: '#666', + fontWeight: 'bold' + } + }, + { + type: 'text', + right: 8, + top: '50%', + style: { + text: latestValue.toFixed(2), + fontSize: 12, + fill: '#52c41a', + fontWeight: 'bold' + } + }, + { + type: 'text', + right: 8, + bottom: 8, + style: { + text: minValue.toFixed(2), + fontSize: 12, + fill: '#666', + fontWeight: 'bold' + } + } + ] }) } @@ -754,13 +967,13 @@ function calculateMOChange() { const previousMO = calculateMOValueFromData(previousKpi) // 检查MO是否有有效值 - if (latestMO === '-' || previousMO === '-') return '±0.00% last 5s' + if (latestMO === '-' || previousMO === '-') return '±0.00% last 1m' // 计算变化幅度 const change = latestMO - previousMO // 检查是否有变化 - if (change === 0) return '±0.00% last 5s' + if (change === 0) return '±0.00% last 1m' const changeText = change > 0 ? `+${change.toFixed(2)}%` : `${change.toFixed(2)}%` @@ -772,13 +985,13 @@ function calculateMOChange() { // 计算MT变化值(完善版本) function calculateMTChange() { - if (imsRealtimeRawData.value.length < 2) return '±0.00% last 5s' + if (imsRealtimeRawData.value.length < 2) return '±0.00% last 1m' // 获取最新和上一个数据点 const latestData = imsRealtimeRawData.value[imsRealtimeRawData.value.length - 1] const previousData = imsRealtimeRawData.value[imsRealtimeRawData.value.length - 2] - if (!latestData?.data || !previousData?.data) return '±0.00% last 5s' + if (!latestData?.data || !previousData?.data) return '±0.00% last 1m' const latestKpi = latestData.data const previousKpi = previousData.data @@ -787,13 +1000,13 @@ function calculateMTChange() { const previousMT = calculateMTValueFromData(previousKpi) // 检查MT是否有有效值 - if (latestMT === '-' || previousMT === '-') return '±0.00% last 5s' + if (latestMT === '-' || previousMT === '-') return '±0.00% last 1m' // 计算变化幅度 const change = latestMT - previousMT // 检查是否有变化 - if (change === 0) return '±0.00% last 5s' + if (change === 0) return '±0.00% last 1m' const changeText = change > 0 ? `+${change.toFixed(2)}%` : `${change.toFixed(2)}%` @@ -809,6 +1022,9 @@ function calculateTimeDifference(latestData: any, previousData: any) { const latestTime = latestData.timestamp || latestData.time || Date.now() const previousTime = previousData.timestamp || previousData.time || Date.now() + console.log('计算时间差 - 最新数据时间戳:', latestTime) + console.log('计算时间差 - 上一个数据时间戳:', previousTime) + // 计算时间差(毫秒) const diffMs = Math.abs(latestTime - previousTime) @@ -818,6 +1034,10 @@ function calculateTimeDifference(latestData: any, previousData: any) { // 转换为分钟 const diffMinutes = Math.floor(diffSeconds / 60) + console.log('计算时间差 - 时间差(毫秒):', diffMs) + console.log('计算时间差 - 时间差(秒):', diffSeconds) + console.log('计算时间差 - 时间差(分钟):', diffMinutes) + // 根据时间差返回合适的格式 if (diffMinutes > 0) { return `${diffMinutes}m` @@ -860,13 +1080,13 @@ function calculateRegSuccessValue() { // 计算registration success变化值 function calculateRegSuccessChange() { - if (imsRealtimeRawData.value.length < 2) return '±0.00% last 5s' + if (imsRealtimeRawData.value.length < 2) return '±0.00% last 1m' // 获取最新和上一个数据点 const latestData = imsRealtimeRawData.value[imsRealtimeRawData.value.length - 1] const previousData = imsRealtimeRawData.value[imsRealtimeRawData.value.length - 2] - if (!latestData?.data || !previousData?.data) return '±0.00% last 5s' + if (!latestData?.data || !previousData?.data) return '±0.00% last 1m' const latestKpi = latestData.data const previousKpi = previousData.data @@ -875,13 +1095,13 @@ function calculateRegSuccessChange() { const previousRegSuccess = calculateRegSuccessValueFromData(previousKpi) // 检查registration success是否有有效值 - if (latestRegSuccess === '-' || previousRegSuccess === '-') return '±0.00% last 5s' + if (latestRegSuccess === '-' || previousRegSuccess === '-') return '±0.00% last 1m' // 计算变化幅度 const change = latestRegSuccess - previousRegSuccess // 检查是否有变化 - if (change === 0) return '±0.00% last 5s' + if (change === 0) return '±0.00% last 1m' const changeText = change > 0 ? `+${change.toFixed(2)}%` : `${change.toFixed(2)}%` @@ -909,39 +1129,20 @@ function calculateActiveCallsValue() { const kpiEvent = latestData.data const scscf07 = Number(kpiEvent['SCSCF.07']) || 0 - if (scscf07 === 0) return '-' - + // 修改:即使值为0也显示"0",因为这是有效的后端数据 const activeCallsValue = scscf07 return activeCallsValue.toFixed(0) } // 计算active calls箭头方向 function calculateActiveCallsArrowDirection() { - const changeText = calculateActiveCallsChange() - - if (changeText.startsWith('+')) return 'up' - if (changeText.startsWith('-')) return 'down' - return 'up' // ±0 或无变化时默认向上 -} - -// 计算active calls箭头 -function calculateActiveCallsArrow() { - const changeText = calculateActiveCallsChange() - - if (changeText.startsWith('+')) return '↗' - if (changeText.startsWith('-')) return '↘' - return '→' // ±0 或无变化时显示水平箭头 -} - -// 计算active calls变化值 -function calculateActiveCallsChange() { - if (imsRealtimeRawData.value.length < 2) return '±0 last 5s' + if (imsRealtimeRawData.value.length < 2) return 'up' // 获取最新和上一个数据点 const latestData = imsRealtimeRawData.value[imsRealtimeRawData.value.length - 1] const previousData = imsRealtimeRawData.value[imsRealtimeRawData.value.length - 2] - if (!latestData?.data || !previousData?.data) return '±0 last 5s' + if (!latestData?.data || !previousData?.data) return 'up' const latestKpi = latestData.data const previousKpi = previousData.data @@ -949,14 +1150,60 @@ function calculateActiveCallsChange() { const latestActiveCalls = Number(latestKpi['SCSCF.07']) || 0 const previousActiveCalls = Number(previousKpi['SCSCF.07']) || 0 - // 检查active calls是否有有效值 - if (latestActiveCalls === 0 || previousActiveCalls === 0) return '±0 last 5s' + // 计算变化幅度 + const change = latestActiveCalls - previousActiveCalls + + if (change > 0) return 'up' + if (change < 0) return 'down' + return 'up' // 无变化时默认向上 +} + +// 计算active calls箭头 +function calculateActiveCallsArrow() { + if (imsRealtimeRawData.value.length < 2) return '→' + + // 获取最新和上一个数据点 + const latestData = imsRealtimeRawData.value[imsRealtimeRawData.value.length - 1] + const previousData = imsRealtimeRawData.value[imsRealtimeRawData.value.length - 2] + + if (!latestData?.data || !previousData?.data) return '→' + + const latestKpi = latestData.data + const previousKpi = previousData.data + + const latestActiveCalls = Number(latestKpi['SCSCF.07']) || 0 + const previousActiveCalls = Number(previousKpi['SCSCF.07']) || 0 // 计算变化幅度 const change = latestActiveCalls - previousActiveCalls + if (change > 0) return '↗' + if (change < 0) return '↘' + return '→' // 无变化时显示水平箭头 +} + +// 计算active calls变化值 +function calculateActiveCallsChange() { + if (imsRealtimeRawData.value.length < 2) return '±0 last 1m' + + // 获取最新和上一个数据点 + const latestData = imsRealtimeRawData.value[imsRealtimeRawData.value.length - 1] + const previousData = imsRealtimeRawData.value[imsRealtimeRawData.value.length - 2] + + if (!latestData?.data || !previousData?.data) return '±0 last 1m' + + const latestKpi = latestData.data + const previousKpi = previousData.data + + const latestActiveCalls = Number(latestKpi['SCSCF.07']) || 0 + const previousActiveCalls = Number(previousKpi['SCSCF.07']) || 0 + + // 修改:即使值为0也参与计算,因为这是有效的后端数据 + // 计算变化幅度 + const change = latestActiveCalls - previousActiveCalls + // 检查是否有变化 - if (change === 0) return '±0 last 5s' + if (change === 0) return '±0 last 1m' const changeText = change > 0 ? `+${change.toFixed(0)}` : `${change.toFixed(0)}` @@ -984,31 +1231,71 @@ function calculateFailedCallsValue() { // 计算failed calls箭头方向 function calculateFailedCallsArrowDirection() { - const changeText = calculateFailedCallsChange() - - if (changeText.startsWith('+')) return 'up' - if (changeText.startsWith('-')) return 'down' - return 'up' // ±0 或无变化时默认向上 -} - -// 计算failed calls箭头 -function calculateFailedCallsArrow() { - const changeText = calculateFailedCallsChange() - - if (changeText.startsWith('+')) return '↗' - if (changeText.startsWith('-')) return '↘' - return '→' // ±0 或无变化时显示水平箭头 -} - -// 计算failed calls变化值 -function calculateFailedCallsChange() { - if (imsRealtimeRawData.value.length < 2) return '±0 last 5s' + if (imsRealtimeRawData.value.length < 2) return 'up' // 获取最新和上一个数据点 const latestData = imsRealtimeRawData.value[imsRealtimeRawData.value.length - 1] const previousData = imsRealtimeRawData.value[imsRealtimeRawData.value.length - 2] - if (!latestData?.data || !previousData?.data) return '±0 last 5s' + if (!latestData?.data || !previousData?.data) return 'up' + + const latestKpi = latestData.data + const previousKpi = previousData.data + + const latestScscf06 = Number(latestKpi['SCSCF.06']) || 0 + const latestScscf07 = Number(latestKpi['SCSCF.07']) || 0 + const previousScscf06 = Number(previousKpi['SCSCF.06']) || 0 + const previousScscf07 = Number(previousKpi['SCSCF.07']) || 0 + + const latestFailedCalls = latestScscf06 - latestScscf07 + const previousFailedCalls = previousScscf06 - previousScscf07 + + // 计算变化幅度 + const change = latestFailedCalls - previousFailedCalls + + if (change > 0) return 'up' + if (change < 0) return 'down' + return 'up' // 无变化时默认向上 +} + +// 计算failed calls箭头 +function calculateFailedCallsArrow() { + if (imsRealtimeRawData.value.length < 2) return '→' + + // 获取最新和上一个数据点 + const latestData = imsRealtimeRawData.value[imsRealtimeRawData.value.length - 1] + const previousData = imsRealtimeRawData.value[imsRealtimeRawData.value.length - 2] + + if (!latestData?.data || !previousData?.data) return '→' + + const latestKpi = latestData.data + const previousKpi = previousData.data + + const latestScscf06 = Number(latestKpi['SCSCF.06']) || 0 + const latestScscf07 = Number(latestKpi['SCSCF.07']) || 0 + const previousScscf06 = Number(previousKpi['SCSCF.06']) || 0 + const previousScscf07 = Number(previousKpi['SCSCF.07']) || 0 + + const latestFailedCalls = latestScscf06 - latestScscf07 + const previousFailedCalls = previousScscf06 - previousScscf07 + + // 计算变化幅度 + const change = latestFailedCalls - previousFailedCalls + + if (change > 0) return '↗' + if (change < 0) return '↘' + return '→' // 无变化时显示水平箭头 +} + +// 计算failed calls变化值 +function calculateFailedCallsChange() { + if (imsRealtimeRawData.value.length < 2) return '±0 last 1m' + + // 获取最新和上一个数据点 + const latestData = imsRealtimeRawData.value[imsRealtimeRawData.value.length - 1] + const previousData = imsRealtimeRawData.value[imsRealtimeRawData.value.length - 2] + + if (!latestData?.data || !previousData?.data) return '±0 last 1m' const latestKpi = latestData.data const previousKpi = previousData.data @@ -1025,7 +1312,7 @@ function calculateFailedCallsChange() { const change = latestFailedCalls - previousFailedCalls // 检查是否有变化 - if (change === 0) return '±0 last 5s' + if (change === 0) return '±0 last 1m' const changeText = change > 0 ? `+${change.toFixed(0)}` : `${change.toFixed(0)}` @@ -1046,39 +1333,20 @@ function calculateActiveRegistrationsValue() { const kpiEvent = latestData.data const scscf03 = Number(kpiEvent['SCSCF.03']) || 0 - if (scscf03 === 0) return '-' - + // 修改:即使值为0也显示"0",因为这是有效的后端数据 const activeRegistrationsValue = scscf03 return activeRegistrationsValue.toFixed(0) } // 计算active registrations箭头方向 function calculateActiveRegistrationsArrowDirection() { - const changeText = calculateActiveRegistrationsChange() - - if (changeText.startsWith('+')) return 'up' - if (changeText.startsWith('-')) return 'down' - return 'up' // ±0 或无变化时默认向上 -} - -// 计算active registrations箭头 -function calculateActiveRegistrationsArrow() { - const changeText = calculateActiveRegistrationsChange() - - if (changeText.startsWith('+')) return '↗' - if (changeText.startsWith('-')) return '↘' - return '→' // ±0 或无变化时显示水平箭头 -} - -// 计算active registrations变化值 -function calculateActiveRegistrationsChange() { - if (imsRealtimeRawData.value.length < 2) return '±0 last 5s' + if (imsRealtimeRawData.value.length < 2) return 'up' // 获取最新和上一个数据点 const latestData = imsRealtimeRawData.value[imsRealtimeRawData.value.length - 1] const previousData = imsRealtimeRawData.value[imsRealtimeRawData.value.length - 2] - if (!latestData?.data || !previousData?.data) return '±0 last 5s' + if (!latestData?.data || !previousData?.data) return 'up' const latestKpi = latestData.data const previousKpi = previousData.data @@ -1086,14 +1354,60 @@ function calculateActiveRegistrationsChange() { const latestActiveRegistrations = Number(latestKpi['SCSCF.03']) || 0 const previousActiveRegistrations = Number(previousKpi['SCSCF.03']) || 0 - // 检查active registrations是否有有效值 - if (latestActiveRegistrations === 0 || previousActiveRegistrations === 0) return '±0 last 5s' + // 计算变化幅度 + const change = latestActiveRegistrations - previousActiveRegistrations + + if (change > 0) return 'up' + if (change < 0) return 'down' + return 'up' // 无变化时默认向上 +} + +// 计算active registrations箭头 +function calculateActiveRegistrationsArrow() { + if (imsRealtimeRawData.value.length < 2) return '→' + + // 获取最新和上一个数据点 + const latestData = imsRealtimeRawData.value[imsRealtimeRawData.value.length - 1] + const previousData = imsRealtimeRawData.value[imsRealtimeRawData.value.length - 2] + + if (!latestData?.data || !previousData?.data) return '→' + + const latestKpi = latestData.data + const previousKpi = previousData.data + + const latestActiveRegistrations = Number(latestKpi['SCSCF.03']) || 0 + const previousActiveRegistrations = Number(previousKpi['SCSCF.03']) || 0 // 计算变化幅度 const change = latestActiveRegistrations - previousActiveRegistrations + if (change > 0) return '↗' + if (change < 0) return '↘' + return '→' // 无变化时显示水平箭头 +} + +// 计算active registrations变化值 +function calculateActiveRegistrationsChange() { + if (imsRealtimeRawData.value.length < 2) return '±0 last 1m' + + // 获取最新和上一个数据点 + const latestData = imsRealtimeRawData.value[imsRealtimeRawData.value.length - 1] + const previousData = imsRealtimeRawData.value[imsRealtimeRawData.value.length - 2] + + if (!latestData?.data || !previousData?.data) return '±0 last 1m' + + const latestKpi = latestData.data + const previousKpi = previousData.data + + const latestActiveRegistrations = Number(latestKpi['SCSCF.03']) || 0 + const previousActiveRegistrations = Number(previousKpi['SCSCF.03']) || 0 + + // 修改:即使值为0也参与计算,因为这是有效的后端数据 + // 计算变化幅度 + const change = latestActiveRegistrations - previousActiveRegistrations + // 检查是否有变化 - if (change === 0) return '±0 last 5s' + if (change === 0) return '±0 last 1m' const changeText = change > 0 ? `+${change.toFixed(0)}` : `${change.toFixed(0)}` @@ -1121,31 +1435,71 @@ function calculateFailedRegistrationsValue() { // 计算failed registrations箭头方向 function calculateFailedRegistrationsArrowDirection() { - const changeText = calculateFailedRegistrationsChange() - - if (changeText.startsWith('+')) return 'up' - if (changeText.startsWith('-')) return 'down' - return 'up' // ±0 或无变化时默认向上 -} - -// 计算failed registrations箭头 -function calculateFailedRegistrationsArrow() { - const changeText = calculateFailedRegistrationsChange() - - if (changeText.startsWith('+')) return '↗' - if (changeText.startsWith('-')) return '↘' - return '→' // ±0 或无变化时显示水平箭头 -} - -// 计算failed registrations变化值 -function calculateFailedRegistrationsChange() { - if (imsRealtimeRawData.value.length < 2) return '±0 last 5s' + if (imsRealtimeRawData.value.length < 2) return 'up' // 获取最新和上一个数据点 const latestData = imsRealtimeRawData.value[imsRealtimeRawData.value.length - 1] const previousData = imsRealtimeRawData.value[imsRealtimeRawData.value.length - 2] - if (!latestData?.data || !previousData?.data) return '±0 last 5s' + if (!latestData?.data || !previousData?.data) return 'up' + + const latestKpi = latestData.data + const previousKpi = previousData.data + + const latestScscf04 = Number(latestKpi['SCSCF.04']) || 0 + const latestScscf03 = Number(latestKpi['SCSCF.03']) || 0 + const previousScscf04 = Number(previousKpi['SCSCF.04']) || 0 + const previousScscf03 = Number(previousKpi['SCSCF.03']) || 0 + + const latestFailedRegistrations = latestScscf04 - latestScscf03 + const previousFailedRegistrations = previousScscf04 - previousScscf03 + + // 计算变化幅度 + const change = latestFailedRegistrations - previousFailedRegistrations + + if (change > 0) return 'up' + if (change < 0) return 'down' + return 'up' // 无变化时默认向上 +} + +// 计算failed registrations箭头 +function calculateFailedRegistrationsArrow() { + if (imsRealtimeRawData.value.length < 2) return '→' + + // 获取最新和上一个数据点 + const latestData = imsRealtimeRawData.value[imsRealtimeRawData.value.length - 1] + const previousData = imsRealtimeRawData.value[imsRealtimeRawData.value.length - 2] + + if (!latestData?.data || !previousData?.data) return '→' + + const latestKpi = latestData.data + const previousKpi = previousData.data + + const latestScscf04 = Number(latestKpi['SCSCF.04']) || 0 + const latestScscf03 = Number(latestKpi['SCSCF.03']) || 0 + const previousScscf04 = Number(previousKpi['SCSCF.04']) || 0 + const previousScscf03 = Number(previousKpi['SCSCF.03']) || 0 + + const latestFailedRegistrations = latestScscf04 - latestScscf03 + const previousFailedRegistrations = previousScscf04 - previousScscf03 + + // 计算变化幅度 + const change = latestFailedRegistrations - previousFailedRegistrations + + if (change > 0) return '↗' + if (change < 0) return '↘' + return '→' // 无变化时显示水平箭头 +} + +// 计算failed registrations变化值 +function calculateFailedRegistrationsChange() { + if (imsRealtimeRawData.value.length < 2) return '±0 last 1m' + + // 获取最新和上一个数据点 + const latestData = imsRealtimeRawData.value[imsRealtimeRawData.value.length - 1] + const previousData = imsRealtimeRawData.value[imsRealtimeRawData.value.length - 2] + + if (!latestData?.data || !previousData?.data) return '±0 last 1m' const latestKpi = latestData.data const previousKpi = previousData.data @@ -1162,7 +1516,7 @@ function calculateFailedRegistrationsChange() { const change = latestFailedRegistrations - previousFailedRegistrations // 检查是否有变化 - if (change === 0) return '±0 last 5s' + if (change === 0) return '±0 last 1m' const changeText = change > 0 ? `+${change.toFixed(0)}` : `${change.toFixed(0)}`