diff --git a/src/views/perfManage/kpiOverView/index.vue b/src/views/perfManage/kpiOverView/index.vue index a526bdb2..8e251066 100644 --- a/src/views/perfManage/kpiOverView/index.vue +++ b/src/views/perfManage/kpiOverView/index.vue @@ -225,6 +225,9 @@ const fnRealTimeSwitch = (bool: boolean) => { } chartData.value = []; + // 初始化统计数据表格 + fnInitKpiStatsData(); + tableLoading.value = true; const options: OptionsType = { url: '/ws', @@ -609,7 +612,7 @@ const updateChart = () => { kpiStats.value.map(item => [ item.title, selectedRows.value.length === 0 || - selectedRows.value.includes(item.kpiId), + selectedRows.value.includes(item.kpiId), ]) ), show: false, @@ -687,6 +690,9 @@ onMounted(async () => { await fetchSpecificKPI(); await nextTick(); + // 初始化统计数据表格 + fnInitKpiStatsData(); + const container = document.getElementById('chartContainer'); if (container && !chart) { chart = echarts.init(container); @@ -835,6 +841,9 @@ const updateChartData = (newData: ChartDataItem) => { }; chart.setOption(option); }); + + // 更新统计数据 - 重新获取完整的30天数据 + fnGetKpiStatsData(); } catch (error) { console.error('Failed to update chart:', error); } @@ -844,54 +853,154 @@ const updateChartData = (newData: ChartDataItem) => { interface KPIStats { kpiId: string; title: string; - max: number; - min: number; - avg: number; - total: number; + last1Day: number | string; + last7Days: number | string; + last30Days: number | string; } -// 添加计算属性,用于计算每个指标的最大值和最小值 +// 添加计算属性,用于计算每个指标的统计数据 // 将 kpiStats 从计算属性改为响应式引用 const kpiStats = ref([]); -// 添加一个计算函数来更新统计数据 -const updateKpiStats = () => { - if (!chartData.value.length || !kpiColumns.value.length) { - kpiStats.value = []; - return; - } - +/**初始化关键指标统计表格数据 */ +function fnInitKpiStatsData() { + // 先初始化表格,显示指标×网元的列表和默认值 kpiStats.value = []; + for (const neType of ALL_NE_TYPES) { for (const ne of neList.value[neType]) { for (const kpiId of TARGET_KPI_IDS[neType]) { const kpi = kpiColumns.value.find(col => col.kpiId === kpiId); if (!kpi) continue; - const key = `${kpiId}_${ne.neId}`; - const values = chartData.value.map(item => Number(item[key]) || 0); - - if (values.length === 0) continue; - - const total = Number( - values.reduce((sum, val) => sum + val, 0).toFixed(2) - ); - const avg = Number((total / values.length).toFixed(2)); - kpiStats.value.push({ - kpiId: key, + kpiId: `${kpiId}_${ne.neId}`, title: `${kpi.title}(${ne.neId})`, - max: Math.max(...values), - min: Math.min(...values), - avg: avg, - total: total, + last1Day: '-', // 默认值,显示加载中状态 + last7Days: '-', + last30Days: '-', }); } } } +} - // 更新图表显示 - updateChartLegendSelect(); +/**获取关键指标近期统计数据 */ +async function fnGetKpiStatsData() { + if (!kpiColumns.value.length) { + return; + } + + const now = new Date(); + const now_ms = now.getTime(); + const day1_start = now_ms - (1 * 24 * 60 * 60 * 1000); // 1天前 + const day7_start = now_ms - (7 * 24 * 60 * 60 * 1000); // 7天前 + const day30_start = now_ms - (30 * 24 * 60 * 60 * 1000); // 30天前 + + try { + // 为每个网元的每个指标分别获取近30天的数据 + for (const neType of ALL_NE_TYPES) { + for (const ne of neList.value[neType]) { + // 请求近30天的数据 + const params = { + neType, + neId: ne.neId, + startTime: String(day30_start), + endTime: String(now_ms), + sortField: 'timeGroup', + sortOrder: 'asc', + interval: 60 * 15, + kpiIds: TARGET_KPI_IDS[neType].join(','), + }; + + try { + const res = await listKPIData(params); + if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.data)) { + // 为每个指标计算统计值 + for (const kpiId of TARGET_KPI_IDS[neType]) { + const kpi = kpiColumns.value.find(col => col.kpiId === kpiId); + if (!kpi) continue; + + const key = `${kpiId}_${ne.neId}`; + + // 根据时间范围筛选非零数据 + const data1Day = res.data.filter((item: any) => { + const itemTime = Number(item.timeGroup); + const value = item[kpiId] ? Number(item[kpiId]) : 0; + return itemTime >= day1_start && value !== 0; + }); + + const data7Days = res.data.filter((item: any) => { + const itemTime = Number(item.timeGroup); + const value = item[kpiId] ? Number(item[kpiId]) : 0; + return itemTime >= day7_start && value !== 0; + }); + + const data30Days = res.data.filter((item: any) => { + const itemTime = Number(item.timeGroup); + const value = item[kpiId] ? Number(item[kpiId]) : 0; + return itemTime >= day30_start && value !== 0; + }); + + // 计算统计值(只对非零数据进行计算,关键指标多为次数类使用累计值) + const calculateValue = (dataArray: any[]) => { + if (dataArray.length === 0) return 0; + + const values = dataArray.map((item: any) => Number(item[kpiId])); + // 关键指标多为次数类,使用累计值 + return Number(values.reduce((sum, val) => sum + val, 0).toFixed(2)); + }; + + // 更新对应的统计数据 + const statsIndex = kpiStats.value.findIndex((item: any) => item.kpiId === key); + if (statsIndex !== -1) { + kpiStats.value[statsIndex].last1Day = calculateValue(data1Day); + kpiStats.value[statsIndex].last7Days = calculateValue(data7Days); + kpiStats.value[statsIndex].last30Days = calculateValue(data30Days); + } + } + } + } catch (error) { + console.error(`获取网元${ne.neId}统计数据失败:`, error); + // 如果获取失败,保持默认值 + for (const kpiId of TARGET_KPI_IDS[neType]) { + const key = `${kpiId}_${ne.neId}`; + const statsIndex = kpiStats.value.findIndex((item: any) => item.kpiId === key); + if (statsIndex !== -1) { + kpiStats.value[statsIndex].last1Day = '-'; + kpiStats.value[statsIndex].last7Days = '-'; + kpiStats.value[statsIndex].last30Days = '-'; + } + } + } + } + } + + // 更新图表显示 + updateChartLegendSelect(); + } catch (error) { + console.error('获取统计数据失败:', error); + // 如果获取失败,保持默认值 + for (const statsItem of kpiStats.value) { + statsItem.last1Day = '-'; + statsItem.last7Days = '-'; + statsItem.last30Days = '-'; + } + } +} + +// 添加一个计算函数来更新统计数据(保持向后兼容) +const updateKpiStats = () => { + if (!kpiColumns.value.length) { + kpiStats.value = []; + return; + } + + // 初始化统计数据 + fnInitKpiStatsData(); + + // 获取统计数据 + fnGetKpiStatsData(); }; // 添加表列定义 @@ -917,35 +1026,55 @@ const statsColumns: TableColumnType[] = [ title: t('views.perfManage.kpiOverView.kpiName'), dataIndex: 'title', key: 'title', - width: '50%', + width: '40%', }, { - title: t('views.perfManage.kpiOverView.totalValue'), - dataIndex: 'total', - key: 'total', - width: '12%', + title: t('views.perfManage.customTarget.ago1'), + dataIndex: 'last1Day', + key: 'last1Day', + width: '20%', sortDirections: ['ascend', 'descend'], + customRender: ({ record }: { record: KPIStats }) => { + const value = record.last1Day; + // 如果是默认值,直接显示 + if (value === '-') { + return value; + } + // 关键指标多为次数类,使用累计值 + return `${value} ${t('views.perfManage.customTarget.total')}`; + }, }, { - title: t('views.perfManage.kpiOverView.avgValue'), - dataIndex: 'avg', - key: 'avg', - width: '12%', + title: t('views.perfManage.customTarget.ago7'), + dataIndex: 'last7Days', + key: 'last7Days', + width: '20%', sortDirections: ['ascend', 'descend'], + customRender: ({ record }: { record: KPIStats }) => { + const value = record.last7Days; + // 如果是默认值,直接显示 + if (value === '-') { + return value; + } + // 关键指标多为次数类,使用累计值 + return `${value} ${t('views.perfManage.customTarget.total')}`; + }, }, { - title: t('views.perfManage.kpiOverView.maxValue'), - dataIndex: 'max', - key: 'max', - width: '12%', - sortDirections: ['ascend', 'descend'], - }, - { - title: t('views.perfManage.kpiOverView.minValue'), - dataIndex: 'min', - key: 'min', - width: '12%', + title: t('views.perfManage.customTarget.ago30'), + dataIndex: 'last30Days', + key: 'last30Days', + width: '20%', sortDirections: ['ascend', 'descend'], + customRender: ({ record }: { record: KPIStats }) => { + const value = record.last30Days; + // 如果是默认值,直接显示 + if (value === '-') { + return value; + } + // 关键指标多为次数类,使用累计值 + return `${value} ${t('views.perfManage.customTarget.total')}`; + }, }, ]; @@ -974,7 +1103,7 @@ const updateChartLegendSelect = () => { kpiStats.value.map(item => [ item.title, selectedRows.value.length === 0 || - selectedRows.value.includes(item.kpiId), + selectedRows.value.includes(item.kpiId), ]) ); @@ -1028,60 +1157,6 @@ const tableRowConfig = computed(() => { :loading="tableLoading" :custom-row="tableRowConfig" > -