diff --git a/src/i18n/locales/en-US.ts b/src/i18n/locales/en-US.ts index 8df6dc8e..de715fb2 100644 --- a/src/i18n/locales/en-US.ts +++ b/src/i18n/locales/en-US.ts @@ -1110,6 +1110,7 @@ export default { "kpiName":"NE Metrics Name", "maxValue":"Max Value", "minValue":"Min Value", + "avgValue":"Average Value", "kpiChartTitle":"Overview of NE metrics", "changeLine":"Change to Line Charts", "changeBar":"Change to Bar Charts", diff --git a/src/i18n/locales/zh-CN.ts b/src/i18n/locales/zh-CN.ts index 55f1b37a..d65403f0 100644 --- a/src/i18n/locales/zh-CN.ts +++ b/src/i18n/locales/zh-CN.ts @@ -1110,6 +1110,7 @@ export default { "kpiName":"指标名", "maxValue":"最大值", "minValue":"最小值", + "avgValue":"平均值", "kpiChartTitle":"网元指标概览", "changeLine":"切换为折线图", "changeBar":"切换为柱状图", diff --git a/src/views/dashboard/imsCDR/index.vue b/src/views/dashboard/imsCDR/index.vue index deec8653..23633cb3 100644 --- a/src/views/dashboard/imsCDR/index.vue +++ b/src/views/dashboard/imsCDR/index.vue @@ -571,9 +571,7 @@ onBeforeUnmount(() => { @@ -756,7 +754,13 @@ onBeforeUnmount(() => {
{{ t('views.dashboard.cdr.time') }}: - {{ parseDateToStr(+record.timestamp * 1000) }} + + {{ + typeof record.cdrJSON.releaseTime === 'number' + ? parseDateToStr(+record.cdrJSON.releaseTime * 1000) + : record.cdrJSON.releaseTime + }} +
@@ -800,11 +804,23 @@ onBeforeUnmount(() => {
{{ t('views.dashboard.cdr.seizureTime') }}: - {{ record.cdrJSON.seizureTime }} + + {{ + typeof record.cdrJSON.seizureTime === 'number' + ? parseDateToStr(+record.cdrJSON.seizureTime * 1000) + : record.cdrJSON.seizureTime + }} +
{{ t('views.dashboard.cdr.releaseTime') }}: - {{ record.cdrJSON.releaseTime }} + + {{ + typeof record.cdrJSON.releaseTime === 'number' + ? parseDateToStr(+record.cdrJSON.releaseTime * 1000) + : record.cdrJSON.releaseTime + }} +
diff --git a/src/views/dashboard/overview/index.vue b/src/views/dashboard/overview/index.vue index bcf03188..231d0588 100644 --- a/src/views/dashboard/overview/index.vue +++ b/src/views/dashboard/overview/index.vue @@ -162,6 +162,7 @@ function loadData() { clearInterval(interval10s.value); interval10s.value = setInterval(() => { + if (!interval10s.value) return if (upfTFActive.value === '0') { upfTFSend('7'); upfTFActive.value = '7'; @@ -176,6 +177,7 @@ function loadData() { clearInterval(interval5s.value); interval5s.value = setInterval(() => { + if (!interval5s.value) return fnGetSkim(); // 获取概览信息 fnGetNeState(); // 获取网元状态 }, 5_000); diff --git a/src/views/dashboard/smfCDR/index.vue b/src/views/dashboard/smfCDR/index.vue index 699f3cca..588a47fc 100644 --- a/src/views/dashboard/smfCDR/index.vue +++ b/src/views/dashboard/smfCDR/index.vue @@ -16,7 +16,6 @@ import { exportSMFDataCDR, listSMFDataCDR, } from '@/api/neData/smf'; -import { parseDateToStr } from '@/utils/date-utils'; import { OptionsType, WS } from '@/plugins/ws-websocket'; import PQueue from 'p-queue'; import saveAs from 'file-saver'; @@ -700,7 +699,7 @@ onBeforeUnmount(() => {
{{ t('views.dashboard.cdr.time') }}: - {{ parseDateToStr(+record.timestamp * 1000) }} + {{ record.cdrJSON.invocationTimestamp }}
{{ t('views.dashboard.cdr.rowInfo') }} diff --git a/src/views/dashboard/smscCDR/index.vue b/src/views/dashboard/smscCDR/index.vue index 57140a04..2c33eb78 100644 --- a/src/views/dashboard/smscCDR/index.vue +++ b/src/views/dashboard/smscCDR/index.vue @@ -718,7 +718,13 @@ onBeforeUnmount(() => {
{{ t('views.dashboard.cdr.time') }}: - {{ parseDateToStr(+record.timestamp * 1000) }} + + {{ + typeof record.cdrJSON.updateTime === 'number' + ? parseDateToStr(+record.cdrJSON.updateTime * 1000) + : record.cdrJSON.updateTime + }} +
{{ t('views.dashboard.cdr.rowInfo') }} diff --git a/src/views/monitor/topology/index.vue b/src/views/monitor/topology/index.vue index 3c87d33d..2e30e98c 100644 --- a/src/views/monitor/topology/index.vue +++ b/src/views/monitor/topology/index.vue @@ -30,11 +30,12 @@ function fnRanderData() { } /**网元状态调度器 */ -const interval10s = ref(null); +const interval = ref(true); /**查询网元状态 */ async function fnGetState() { for (const node of graphG6Data.nodes) { + if (!interval.value) return; const ne = node.info; // if (ne.neType === 'OMC') continue; const result = await stateNeInfo(ne.neType, ne.neId); @@ -151,11 +152,21 @@ function fnGetList(refresh: boolean = false) { }) .then(randerGroph => { if (!randerGroph) return; - fnGetState().finally(() => { - interval10s.value = setInterval(() => { - fnGetState(); // 获取网元状态 - }, 10_000); - }); + repeatFn(); + }); +} + +/**递归刷新网元状态 */ +function repeatFn() { + if (!interval.value) { + return; + } + fnGetState() + .finally(() => { + repeatFn(); // 递归调用自己 + }) + .catch(error => { + console.error(error); }); } @@ -165,7 +176,7 @@ onMounted(() => { }); onBeforeUnmount(() => { - clearInterval(interval10s.value); + interval.value = false; }); diff --git a/src/views/monitor/topologyArchitecture/index.vue b/src/views/monitor/topologyArchitecture/index.vue index a5ee3889..289a4ba1 100644 --- a/src/views/monitor/topologyArchitecture/index.vue +++ b/src/views/monitor/topologyArchitecture/index.vue @@ -166,7 +166,7 @@ const graphNodeTooltip = new Tooltip({
${t('views.monitor.topology.expiryDate')}: ${neState.expire ?? '--'} -
+ `; }, @@ -294,7 +294,8 @@ function fnGraphDataLoad(reload: boolean = false) { Reflect.set(node, 'neState', { online: false }); // 图片路径处理 if (node.img) node.img = parseBasePath(node.img); - if (node.icon.show && node.icon?.img) node.icon.img = parseBasePath(node.icon.img); + if (node.icon.show && node.icon?.img) + node.icon.img = parseBasePath(node.icon.img); // 遍历是否有网元数据 const nodeID: string = node.id; const hasNe = res.neList.some(ne => { @@ -352,11 +353,11 @@ function fnGraphDataLoad(reload: boolean = false) { } clearInterval(interval10s.value); interval10s.value = null; - fnGetState().finally(() => { - interval10s.value = setInterval(() => { - fnGetState(); // 获取网元状态 - }, 10_000); - }); + fnGetState(); + interval10s.value = setInterval(async () => { + if (!interval10s.value) return; + fnGetState(); // 获取网元状态 + }, 20_000); }); } @@ -364,7 +365,7 @@ function fnGraphDataLoad(reload: boolean = false) { const interval10s = ref(null); /**查询网元状态 */ -async function fnGetState() { +function fnGetState() { // 获取节点状态 for (const node of graphState.data.nodes) { if (notNeNodes.includes(node.id)) continue; diff --git a/src/views/perfManage/kpiKeyTarget/index.vue b/src/views/perfManage/kpiKeyTarget/index.vue index dc48de65..a4798631 100644 --- a/src/views/perfManage/kpiKeyTarget/index.vue +++ b/src/views/perfManage/kpiKeyTarget/index.vue @@ -208,8 +208,8 @@ const rangePicker = reactive({ ...Object.fromEntries(networkElementTypes.value.map(type => [ type, [ - dayjs().startOf('hour').valueOf().toString(), // 当前小时内 - dayjs().endOf('hour').valueOf().toString() + dayjs().subtract(1, 'hour').startOf('hour').valueOf().toString(), // 上一小时开始 + dayjs().startOf('hour').add(1, 'hour').valueOf().toString(), // 当前小时结束 ] ])) as Record, placeholder: [t('views.monitor.monitor.startTime'), t('views.monitor.monitor.endTime')] as [string, string], @@ -336,7 +336,7 @@ const fetchData = async (type: AllChartType) => { endTime, sortField: 'timeGroup', sortOrder: 'desc', - interval: 5, + interval: 60*15, }); if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.data)) { diff --git a/src/views/perfManage/kpiOverView/index.vue b/src/views/perfManage/kpiOverView/index.vue index aa23d66c..da865a72 100644 --- a/src/views/perfManage/kpiOverView/index.vue +++ b/src/views/perfManage/kpiOverView/index.vue @@ -62,9 +62,9 @@ const ws = ref(null); // }); const ranges = ref([ {label:t('views.perfManage.customTarget.sixHoursAgo'),value:[dayjs().subtract(6, 'hours'), - dayjs(),]}, + dayjs(),]}, {label:t('views.perfManage.customTarget.threeHoursAgo'),value:[dayjs().subtract(3, 'hours'), - dayjs(),]}, + dayjs(),]}, {label:t('views.monitor.monitor.today'),value:[dayjs().startOf('day'), dayjs()]}, ]) //日期范围响应式变量 @@ -188,10 +188,9 @@ const processChartData = (rawData: any[]) => { } Object.assign(groupedData.get(timeKey), item); }); - // 获取当前选择的结束时间 - const endTime = dateRange.value[1]; - const processedData = Array.from(groupedData.values()) + + return Array.from(groupedData.values()) .sort((a, b) => Number(a.timeGroup) - Number(b.timeGroup)) .map(item => {//转换成图表需要的格式 const dataItem: ChartDataItem = { date: item.timeGroup.toString() }; @@ -200,17 +199,6 @@ const processChartData = (rawData: any[]) => { }); 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 () => { @@ -236,7 +224,7 @@ const fetchChartData = async () => { endTime: String(endTime), sortField: 'timeGroup', sortOrder: 'asc', - interval: 5, + interval: 60*15, kpiIds: TARGET_KPI_IDS[neType].join(','), }; @@ -272,8 +260,9 @@ const kpiColors = new Map(); // 更新图表类型 const getSeriesConfig = () => ({ - symbol: 'circle', + symbol: 'none', symbolSize: 6, + smooth:0.6, showSymbol: true, }); @@ -293,19 +282,7 @@ const updateChart = () => { 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; }); @@ -379,6 +356,13 @@ const updateChart = () => { xAxis: { // 指定x轴类型为类目轴,适用于离散的类目数据 type: 'category', + splitLine: { + show: true, + lineStyle: { + // 使用深浅的间隔色 + color: '#aaa', + } + }, //控制坐标轴两边留白 // 当为折线图时(isLine为true)时不留白,柱状图时留白 // 这样可以让折线图从原点开始,柱状图有合适的间距 @@ -389,29 +373,29 @@ const updateChart = () => { 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 - } + // 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: { // y轴配置 @@ -585,6 +569,7 @@ interface KPIStats { title: string; max: number; min: number; + avg:number; } // 添加计算属性,用于计算每个指标的最大值和最小值 @@ -599,11 +584,17 @@ const kpiStats = computed((): KPIStats[] => { // 获取该指标的所有数值 const values = chartData.value.map(item => Number(item[kpiId]) || 0); + // 计算平均值 + const avg = values.length > 0 + ? Number((values.reduce((sum, val) => sum + val, 0) / values.length).toFixed(2)) + : 0; + return { kpiId: kpiId, title: kpi.title, max: Math.max(...values), - min: Math.min(...values) + min: Math.min(...values), + avg:avg }; }).filter((item): item is KPIStats => item !== null); }); @@ -628,13 +619,13 @@ const statsColumns: TableColumnType[] = [ title: t('views.perfManage.kpiOverView.kpiName'), dataIndex: 'title', key: 'title', - width: '65%', + width: '63%', }, { title: t('views.perfManage.kpiOverView.maxValue'), dataIndex: 'max', key: 'max', - width: '17%', + width: '12%', sorter: (a: KPIStats, b: KPIStats) => a.max - b.max, // 添加排序函数 sortDirections: ['ascend', 'descend'], }, @@ -642,9 +633,17 @@ const statsColumns: TableColumnType[] = [ title: t('views.perfManage.kpiOverView.minValue'), dataIndex: 'min', key: 'min', - width: '17%', + width: '12%', sorter: (a: KPIStats, b: KPIStats) => a.min - b.min, // 添加排序函数 sortDirections: ['ascend', 'descend'], + }, + { + title: t('views.perfManage.kpiOverView.avgValue'), // 需要在语言包中添加对应的翻译 + dataIndex: 'avg', + key: 'avg', + width: '12%', + sorter: (a: KPIStats, b: KPIStats) => a.avg - b.avg, + sortDirections: ['ascend', 'descend'], } ];