From d33183ca5ec832f315476aa71b942578e5fb37ca Mon Sep 17 00:00:00 2001 From: TsMask <340112800@qq.com> Date: Thu, 26 Dec 2024 20:11:34 +0800 Subject: [PATCH 1/6] =?UTF-8?q?style:=20SMF-CDR=E6=B5=81=E9=87=8F=E6=8A=A5?= =?UTF-8?q?=E8=A1=A8=E9=A1=B5=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/dashboard/smfCDRByIMSI/index.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/views/dashboard/smfCDRByIMSI/index.vue b/src/views/dashboard/smfCDRByIMSI/index.vue index 976940e3..841bd578 100644 --- a/src/views/dashboard/smfCDRByIMSI/index.vue +++ b/src/views/dashboard/smfCDRByIMSI/index.vue @@ -47,7 +47,7 @@ let cdrChart: echarts.ECharts | null = null; /**图表配置 */ const option = { title: { - text: 'Data Volume Uplink / Downlink', + text: 'Data Usage Report', left: 'left', }, tooltip: { @@ -434,7 +434,7 @@ function fnRanderChartDataUpdate() { // 绘制图数据 cdrChart.setOption({ title: { - text: `Data Volume By IMSI ${queryParams.subscriberID}`, + text: `Data Usage Report of IMSI ${queryParams.subscriberID}`, }, xAxis: [ { From c40ee9c8cc994a45982107d4f60f2e849811da26 Mon Sep 17 00:00:00 2001 From: TsMask <340112800@qq.com> Date: Fri, 27 Dec 2024 19:06:12 +0800 Subject: [PATCH 2/6] =?UTF-8?q?fix:=20=E7=9C=8B=E6=9D=BF=E9=87=8D=E5=A4=8D?= =?UTF-8?q?=E8=8E=B7=E5=8F=96UE=E4=BF=AE=E5=A4=8D=E5=92=8CAMF-UE=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E7=BB=93=E6=9E=84=E5=8F=98=E6=9B=B4=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/UserActivity/index.vue | 22 +++++++------------ src/views/dashboard/overview/hooks/useWS.ts | 12 +++++----- src/views/dashboard/overview/index.vue | 2 +- 3 files changed, 15 insertions(+), 21 deletions(-) diff --git a/src/views/dashboard/overview/components/UserActivity/index.vue b/src/views/dashboard/overview/components/UserActivity/index.vue index 1cb9d6c9..a5aaa9c9 100644 --- a/src/views/dashboard/overview/components/UserActivity/index.vue +++ b/src/views/dashboard/overview/components/UserActivity/index.vue @@ -137,18 +137,12 @@ onMounted(() => {
{{ t('views.dashboard.overview.userActivity.time') }}: - - {{ item.data.authTime }} - - - {{ item.data.detachTime }} - - - {{ item.data.changeTime }} - + +
@@ -167,7 +161,7 @@ onMounted(() => {
{{ t('views.dashboard.overview.userActivity.result') }}:  - +
@@ -177,7 +171,7 @@ onMounted(() => {
{{ t('views.dashboard.overview.userActivity.result') }}:  - +
diff --git a/src/views/dashboard/overview/hooks/useWS.ts b/src/views/dashboard/overview/hooks/useWS.ts index bd3e5f4f..62268578 100644 --- a/src/views/dashboard/overview/hooks/useWS.ts +++ b/src/views/dashboard/overview/hooks/useWS.ts @@ -49,7 +49,7 @@ export default function useWS() { // 普通信息 switch (requestId) { // AMF_UE会话事件 - case 'amf_1010': + case 'amf_1010_001': if (Array.isArray(data.rows)) { eventListParse('amf_ue', data); } @@ -95,13 +95,13 @@ export default function useWS() { } break; // MME_UE会话事件 - case '1011_001': + case '1011': if (data.data) { queue.add(() => eventItemParseAndPush('mme_ue', data.data)); } break; // IMS_CDR会话事件 - case '1005_001': + case '1005': if (data.data) { queue.add(() => eventItemParseAndPush('ims_cdr', data.data)); } @@ -132,7 +132,7 @@ export default function useWS() { function userActivitySend() { // AMF_UE会话事件 ws.send({ - requestId: 'amf_1010', + requestId: 'amf_1010_001', type: 'amf_ue', data: { neType: 'AMF', @@ -189,11 +189,11 @@ export default function useWS() { /**订阅通道组 * * 指标UPF (GroupID:12_neId) - * AMF_UE会话事件(GroupID:1010) + * AMF_UE会话事件(GroupID:1010_neId) * MME_UE会话事件(GroupID:1011_neId) * IMS_CDR会话事件(GroupID:1005_neId) */ - subGroupID: '12_' + rmUid + ',1010,1011_001,1005_001', + subGroupID: '12_' + rmUid + ',1010,1011,1005', }, onmessage: wsMessage, onerror: (ev: any) => { diff --git a/src/views/dashboard/overview/index.vue b/src/views/dashboard/overview/index.vue index 46b5ce37..81545c12 100644 --- a/src/views/dashboard/overview/index.vue +++ b/src/views/dashboard/overview/index.vue @@ -252,7 +252,7 @@ function fnSelectNe(value: any, option: any) { for (var key in upfTotalFlow.value) { upfTotalFlow.value[key].requestFlag = false; } - loadData(); + // loadData(); } // 定义一个方法返回 views 容器 From 2138896d433feac348967e692774ae5a31a9ca67 Mon Sep 17 00:00:00 2001 From: TsMask <340112800@qq.com> Date: Fri, 27 Dec 2024 19:07:02 +0800 Subject: [PATCH 3/6] =?UTF-8?q?fix:=20=E7=BD=91=E5=85=83=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?=E9=80=89=E6=8B=A9=E6=A1=86=E8=AD=A6=E5=91=8A=E7=8A=B6=E6=80=81?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/ne/neConfig/index.vue | 1 + 1 file changed, 1 insertion(+) diff --git a/src/views/ne/neConfig/index.vue b/src/views/ne/neConfig/index.vue index 30cb39fc..5ab607b0 100644 --- a/src/views/ne/neConfig/index.vue +++ b/src/views/ne/neConfig/index.vue @@ -114,6 +114,7 @@ function fnSelectNeId(_: any, info: any) { neIdSelect.value = okArr.map((item: any) => item.value); } else { neTypeSelect.value[1] = info.value; + neIdSelect.value = [info.value]; } fnActiveConfigNode(treeState.data[0].key); } From 1cbce9ad0376660bcaf85ef939e8f9c016a06926 Mon Sep 17 00:00:00 2001 From: TsMask <340112800@qq.com> Date: Fri, 27 Dec 2024 19:08:58 +0800 Subject: [PATCH 4/6] =?UTF-8?q?feat:=20UE=E6=95=B0=E6=8D=AE=E5=88=97?= =?UTF-8?q?=E8=A1=A8=E7=BB=9F=E4=B8=80=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/dashboard/amfUE/index.vue | 234 ++++++++++++++++++---------- src/views/dashboard/mmeUE/index.vue | 110 +++++++++---- 2 files changed, 224 insertions(+), 120 deletions(-) diff --git a/src/views/dashboard/amfUE/index.vue b/src/views/dashboard/amfUE/index.vue index 83e061e6..aff168bf 100644 --- a/src/views/dashboard/amfUE/index.vue +++ b/src/views/dashboard/amfUE/index.vue @@ -11,14 +11,21 @@ import { RESULT_CODE_SUCCESS, } from '@/constants/result-constants'; import useDictStore from '@/store/modules/dict'; +import useNeInfoStore from '@/store/modules/neinfo'; import { listAMFDataUE, delAMFDataUE, exportAMFDataUE } from '@/api/neData/amf'; +import { parseDateToStr } from '@/utils/date-utils'; import { OptionsType, WS } from '@/plugins/ws-websocket'; +import dayjs, { Dayjs } from 'dayjs'; import saveAs from 'file-saver'; import PQueue from 'p-queue'; +import { useClipboard } from '@vueuse/core'; +const { copy } = useClipboard({ legacy: true }); const { t } = useI18n(); const { getDict } = useDictStore(); const ws = new WS(); const queue = new PQueue({ concurrency: 1, autoStart: true }); +/**网元可选 */ +let neOtions = ref[]>([]); /**字典数据 */ let dict: { @@ -35,7 +42,10 @@ let dict: { }); /**开始结束时间 */ -let queryRangePicker = ref<[string, string]>(['', '']); +let queryRangePicker = ref<[Dayjs, Dayjs] | undefined>([ + dayjs().startOf('hour'), + dayjs().endOf('hour'), +]); /**查询参数 */ let queryParams = reactive({ @@ -47,9 +57,9 @@ let queryParams = reactive({ sortField: 'timestamp', sortOrder: 'desc', /**开始时间 */ - startTime: '', + startTime: undefined as undefined | number, /**结束时间 */ - endTime: '', + endTime: undefined as undefined | number, /**当前页数 */ pageNum: 1, /**每页条数 */ @@ -67,7 +77,7 @@ function fnQueryReset() { pageNum: 1, pageSize: 20, }); - queryRangePicker.value = ['', '']; + queryRangePicker.value = [dayjs().startOf('hour'), dayjs().endOf('hour')]; tablePagination.current = 1; tablePagination.pageSize = 20; fnGetList(); @@ -141,9 +151,15 @@ let tableColumns: ColumnsType = [ { title: t('views.dashboard.ue.time'), dataIndex: 'eventJSON', - key: 'time', align: 'left', width: 150, + customRender(opt) { + const record = opt.value; + if (record?.time) { + return record.time; + } + return parseDateToStr(+record.timestamp * 1000); + }, }, { title: t('common.operate'), @@ -252,11 +268,19 @@ function fnGetList(pageNum?: number) { if (pageNum) { queryParams.pageNum = pageNum; } - if (!queryRangePicker.value) { - queryRangePicker.value = ['', '']; + + // 时间范围 + if ( + Array.isArray(queryRangePicker.value) && + queryRangePicker.value.length > 0 + ) { + queryParams.startTime = queryRangePicker.value[0].valueOf(); + queryParams.endTime = queryRangePicker.value[1].valueOf(); + } else { + queryParams.startTime = undefined; + queryParams.endTime = undefined; } - queryParams.startTime = queryRangePicker.value[0]; - queryParams.endTime = queryRangePicker.value[1]; + listAMFDataUE(toRaw(queryParams)).then(res => { if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.rows)) { // 取消勾选 @@ -324,6 +348,18 @@ function fnExportList() { }); } +/** + * 复制CDR + * @param jsonStr JSON字符串 + */ +function fnRecordCopy(jsonStr: string) { + if (!jsonStr) return; + const text = JSON.stringify(jsonStr, null, 2); + copy(text).then(() => { + message.success(t('common.copyOk'), 3); + }); +} + /**实时数据开关 */ const realTimeData = ref(false); @@ -333,31 +369,30 @@ const realTimeData = ref(false); function fnRealTime() { realTimeData.value = !realTimeData.value; if (realTimeData.value) { + tableState.seached = false; // 建立链接 const options: OptionsType = { url: '/ws', params: { /**订阅通道组 * - * AMF_UE会话事件(GroupID:1010) + * AMF_UE会话事件(GroupID:1010_neId) */ - subGroupID: '1010', + subGroupID: `1010_${queryParams.neId}`, }, onmessage: wsMessage, - onerror: wsError, + onerror: (ev: any) => { + console.error(ev); + }, }; ws.connect(options); } else { ws.close(); + tableState.seached = true; + fnGetList(1); } } -/**接收数据后回调 */ -function wsError(ev: any) { - // 接收数据后回调 - console.error(ev); -} - /**接收数据后回调 */ function wsMessage(res: Record) { const { code, requestId, data } = res; @@ -371,7 +406,7 @@ function wsMessage(res: Record) { return; } // ueEvent AMF_UE会话事件 - if (data.groupId === '1010') { + if (data.groupId === `1010_${queryParams.neId}`) { const ueEvent = data.data; queue.add(async () => { modalState.maxId += 1; @@ -399,16 +434,40 @@ onMounted(() => { getDict('ue_auth_code'), getDict('ue_event_type'), getDict('ue_event_cm_state'), - ]) - .then(resArr => { - if (resArr[0].status === 'fulfilled') { - dict.ueAauthCode = resArr[0].value; - } - if (resArr[1].status === 'fulfilled') { - dict.ueEventType = resArr[1].value; - } - if (resArr[2].status === 'fulfilled') { - dict.ueEventCmState = resArr[2].value; + ]).then(resArr => { + if (resArr[0].status === 'fulfilled') { + dict.ueAauthCode = resArr[0].value; + } + if (resArr[1].status === 'fulfilled') { + dict.ueEventType = resArr[1].value; + } + if (resArr[2].status === 'fulfilled') { + dict.ueEventCmState = resArr[2].value; + } + }); + + // 获取网元网元列表 + useNeInfoStore() + .fnNelist() + .then(res => { + if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.data)) { + if (res.data.length > 0) { + let arr: Record[] = []; + res.data.forEach(i => { + if (i.neType === 'AMF') { + arr.push({ value: i.neId, label: i.neName }); + } + }); + neOtions.value = arr; + if (arr.length > 0) { + queryParams.neId = arr[0].value; + } + } + } else { + message.warning({ + content: t('common.noData'), + duration: 2, + }); } }) .finally(() => { @@ -434,6 +493,16 @@ onBeforeUnmount(() => { + + + + + { > - + { > + + + + + + {{ t('common.search') }} + + + + {{ t('common.reset') }} + + + + { > - - - - - - {{ t('common.search') }} - - - - {{ t('common.reset') }} - - - - @@ -545,6 +614,7 @@ onBeforeUnmount(() => { :checked-children="t('common.switch.show')" :un-checked-children="t('common.switch.hide')" size="small" + :disabled="realTimeData" /> @@ -605,7 +675,7 @@ onBeforeUnmount(() => { @@ -614,32 +684,23 @@ onBeforeUnmount(() => { -