diff --git a/CHANGELOG.md b/CHANGELOG.md index e6069eb2..76335ef8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ # 版本发布日志 +## 2.2508.4-20250829 + +- 新增 网元授权显示用户数/基站数 +- 优化 网元当前版本显示是否有包存在 +- 优化 cdr/ue导出操作后锁定按钮事件防重发 +- 优化 网元可选静态可选项添加PGWC +- 优化 参数配置添加校验过滤长度~和-定义范围 +- 修复 UPF流量统计数据同时获取刷新 +- 修复 UPF流量统计字节数据格式化显示不一致问题 +- 新增 指标Title管理页面功能 +- 新增 增加多个导出操作的超时时间至180秒 + ## 2.2508.2-20250815 - 优化 给config.js加随机数避免缓存 diff --git a/src/constants/ne-constants.ts b/src/constants/ne-constants.ts index cdf6b689..7d9ef989 100644 --- a/src/constants/ne-constants.ts +++ b/src/constants/ne-constants.ts @@ -22,6 +22,12 @@ export const NE_TYPE_LIST = [ 'CHF', 'HLR', 'SGWC', + 'PGWC', + 'IP-SM-GW', + 'MMTel-AS', + 'I-CSCF', + 'P-CSCF', + 'S-CSCF', ]; /** diff --git a/src/i18n/locales/en-US.ts b/src/i18n/locales/en-US.ts index a8e14239..2bfc7aaa 100644 --- a/src/i18n/locales/en-US.ts +++ b/src/i18n/locales/en-US.ts @@ -539,6 +539,8 @@ export default { port: 'Port', portTip: "Network element port default:33030", capability: 'Capability', + ueNumber: 'UE Number', + nbNumber: 'Radio Number', serialNum: 'Serial Number', expiryDate: 'Expiry Date', normalcy: 'Normal', diff --git a/src/i18n/locales/zh-CN.ts b/src/i18n/locales/zh-CN.ts index 367db62a..1b30d7a0 100644 --- a/src/i18n/locales/zh-CN.ts +++ b/src/i18n/locales/zh-CN.ts @@ -539,6 +539,8 @@ export default { port: '服务端口', portTip: "网元服务端口,默认:33030", capability: '容量', + ueNumber: '用户数', + nbNumber: '基站数', serialNum: '序列号', expiryDate: '许可证到期日期', normalcy: '正常', diff --git a/src/utils/parse-utils.ts b/src/utils/parse-utils.ts index ada8afec..3df76e1e 100644 --- a/src/utils/parse-utils.ts +++ b/src/utils/parse-utils.ts @@ -177,25 +177,6 @@ export function parseSizeFromKbs(sizeByte: number, timeInterval: number): any { return [(realBit / 1000 / 1000).toFixed(2), ' Mbits/sec']; } -/** - * 位数据转换单位 - * @param bits 位Bit大小 64009540 = 512.08 MB - * @returns xx B / KB / MB / GB / TB / PB / EB / ZB / YB - */ -export function parseSizeFromBits(bits: number | string): string { - bits = Number(bits) || 0; - if (bits <= 0) return '0 B'; - bits = bits * 8; - const units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; - const unitIndex = Math.floor(Math.log2(bits) / 10); - const value = bits / Math.pow(1000, unitIndex); - const unti = units[unitIndex]; - if (unitIndex > 0) { - return `${value.toFixed(2)} ${unti}`; - } - return `${value} ${unti}`; -} - /** * 字节数转换单位 * @param byte 字节Byte大小 64009540 = 512.08 MB diff --git a/src/views/dashboard/amfUE/index.vue b/src/views/dashboard/amfUE/index.vue index 5d6a5cba..4edc10c3 100644 --- a/src/views/dashboard/amfUE/index.vue +++ b/src/views/dashboard/amfUE/index.vue @@ -339,6 +339,7 @@ function fnExportList() { title: t('common.tipTitle'), content: t('views.dashboard.ue.exportTip'), onOk() { + modalState.confirmLoading = true; const hide = message.loading(t('common.loading'), 0); const querys = toRaw(queryParams); querys.pageSize = 10000; diff --git a/src/views/dashboard/imsCDR/index.vue b/src/views/dashboard/imsCDR/index.vue index 61eb8983..c9a64dd5 100644 --- a/src/views/dashboard/imsCDR/index.vue +++ b/src/views/dashboard/imsCDR/index.vue @@ -408,6 +408,7 @@ function fnExportList() { title: t('common.tipTitle'), content: t('views.dashboard.cdr.exportTip'), onOk() { + modalState.confirmLoading = true; const hide = message.loading(t('common.loading'), 0); const querys = toRaw(queryParams); querys.pageSize = 10000; diff --git a/src/views/dashboard/mmeUE/index.vue b/src/views/dashboard/mmeUE/index.vue index d98431df..3d848803 100644 --- a/src/views/dashboard/mmeUE/index.vue +++ b/src/views/dashboard/mmeUE/index.vue @@ -341,6 +341,7 @@ function fnExportList() { title: t('common.tipTitle'), content: t('views.dashboard.ue.exportTip'), onOk() { + modalState.confirmLoading = true; const hide = message.loading(t('common.loading'), 0); const querys = toRaw(queryParams); querys.pageSize = 10000; diff --git a/src/views/dashboard/overview/hooks/useUPFTotalFlow.ts b/src/views/dashboard/overview/hooks/useUPFTotalFlow.ts index edc1335b..16c3f6d2 100644 --- a/src/views/dashboard/overview/hooks/useUPFTotalFlow.ts +++ b/src/views/dashboard/overview/hooks/useUPFTotalFlow.ts @@ -1,5 +1,5 @@ import { parseDateToStr } from '@/utils/date-utils'; -import { parseSizeFromBits, parseSizeFromKbs } from '@/utils/parse-utils'; +import { parseSizeFromByte, parseSizeFromKbs } from '@/utils/parse-utils'; import { ref } from 'vue'; type FDType = { @@ -81,9 +81,9 @@ export function upfTFParse(day: string, data: Record) { let { up, down } = data; upfTotalFlow.value[day] = { up: up, - upFrom: parseSizeFromBits(up), + upFrom: parseSizeFromByte(up), down: down, - downFrom: parseSizeFromBits(down), + downFrom: parseSizeFromByte(down), requestFlag: false, }; } diff --git a/src/views/dashboard/overview/index.vue b/src/views/dashboard/overview/index.vue index 1df21595..128a740e 100644 --- a/src/views/dashboard/overview/index.vue +++ b/src/views/dashboard/overview/index.vue @@ -229,15 +229,15 @@ function loadData() { interval10s.value = setInterval(() => { if (!interval10s.value || !initFlag) return; if (upfTFActive.value === '0') { - upfTFSend('7'); upfTFActive.value = '7'; } else if (upfTFActive.value === '7') { - upfTFSend('30'); upfTFActive.value = '30'; } else if (upfTFActive.value === '30') { - upfTFSend('0'); upfTFActive.value = '0'; } + upfTFSend('0'); + upfTFSend('7'); + upfTFSend('30'); }, 10_000); clearInterval(interval5s.value); diff --git a/src/views/dashboard/overview2/hooks/useUPFTotalFlow.ts b/src/views/dashboard/overview2/hooks/useUPFTotalFlow.ts index 4366405d..c90af755 100644 --- a/src/views/dashboard/overview2/hooks/useUPFTotalFlow.ts +++ b/src/views/dashboard/overview2/hooks/useUPFTotalFlow.ts @@ -1,5 +1,5 @@ import { parseDateToStr } from '@/utils/date-utils'; -import { parseSizeFromBits, parseSizeFromKbs } from '@/utils/parse-utils'; +import { parseSizeFromByte, parseSizeFromKbs } from '@/utils/parse-utils'; import { ref } from 'vue'; type FDType = { @@ -79,9 +79,9 @@ export function upfTFParse(day: string, data: Record) { let { up, down } = data; upfTotalFlow.value[day] = { up: up, - upFrom: parseSizeFromBits(up), + upFrom: parseSizeFromByte(up), down: down, - downFrom: parseSizeFromBits(down), + downFrom: parseSizeFromByte(down), requestFlag: false, }; } diff --git a/src/views/dashboard/overview2/index.vue b/src/views/dashboard/overview2/index.vue index 9c10bf27..5cbeec79 100644 --- a/src/views/dashboard/overview2/index.vue +++ b/src/views/dashboard/overview2/index.vue @@ -176,15 +176,15 @@ async function fnGetSkim() { { request: (neId: string) => listAMFNblist({ neId }), process: async (res: any, neId: any) => { - console.log(neId) - if (res.code === RESULT_CODE_SUCCESS&& Array.isArray(res.data)) { + console.log(neId); + if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.data)) { skimState.gnbNum += res.data.length; skimState.gnbUeNum += res.data.reduce( (sum: number, item: any) => sum + item.ueNum, 0 ); const amfNbRes = await listAMFNbStatelist({ neId }); - console.log(amfNbRes) + console.log(amfNbRes); if ( amfNbRes.code === RESULT_CODE_SUCCESS && Array.isArray(amfNbRes.data) @@ -224,13 +224,13 @@ async function fnGetSkim() { ); const mmeNbRes = await listMMENbStatelist({ neId }); - console.log(mmeNbRes) + console.log(mmeNbRes); if ( mmeNbRes.code === RESULT_CODE_SUCCESS && Array.isArray(mmeNbRes.data) ) { // skimState.eNbSumNum += mmeNbRes.data.length; - console.log(mmeNbRes) + console.log(mmeNbRes); tempEnbSumNum += mmeNbRes.data.length; } } @@ -238,21 +238,20 @@ async function fnGetSkim() { }, ], ]); - console.log(neCascaderOptions) + console.log(neCascaderOptions); const requests = neCascaderOptions.value.flatMap( (ne: any) => ne.children ?.map((child: any) => { - console.log(child.neId) + console.log(child.neId); const handler = neHandlers.get(child.neType); return handler ? { promise: handler.request(child.neId), process: handler.process, - neId: child.neId, // 这里加上neId - - } + neId: child.neId, // 这里加上neId + } : null; }) .filter(Boolean) || [] @@ -311,15 +310,15 @@ function loadData() { interval10s.value = setInterval(() => { if (!interval10s.value || !initFlag) return; if (upfTFActive.value === '0') { - upfTFSend('7'); upfTFActive.value = '7'; } else if (upfTFActive.value === '7') { - upfTFSend('30'); upfTFActive.value = '30'; } else if (upfTFActive.value === '30') { - upfTFSend('0'); upfTFActive.value = '0'; } + upfTFSend('0'); + upfTFSend('7'); + upfTFSend('30'); }, 10_000); clearInterval(interval5s.value); @@ -375,12 +374,14 @@ async function fnSelectUDM(e: any) { pageNum: 1, pageSize: 1, }); - console.log(res) + console.log(res); // listUDMSub({ neId: udmNeId.value, pageNum: 1, pageSize: 1 }).then(res => { - if (res.code === RESULT_CODE_SUCCESS && typeof res.data.total === 'number') { + if ( + res.code === RESULT_CODE_SUCCESS && + typeof res.data.total === 'number' + ) { skimState.udmSubNum = res.data.total; - console.log(res) - + console.log(res); } else { skimState.udmSubNum = 0; } @@ -393,7 +394,7 @@ async function fnSelectUDM(e: any) { } /**资源控制-选择NE */ function fnSelectNeRe(e: any) { - console.log(e) + console.log(e); graphNodeClickID.value = e.key; } // @@ -408,7 +409,7 @@ const getPopupContainer = () => { onMounted(() => { // 获取网元网元列表 neListStore.neCascaderOptions.forEach(item => { - console.log(item) + console.log(item); if (item.value === 'UPF') { neOtions.value = JSON.parse(JSON.stringify(item.children)); } diff --git a/src/views/dashboard/sgwcCDR/index.vue b/src/views/dashboard/sgwcCDR/index.vue index a1f4cd3f..b00a849e 100644 --- a/src/views/dashboard/sgwcCDR/index.vue +++ b/src/views/dashboard/sgwcCDR/index.vue @@ -378,6 +378,7 @@ function fnExportList() { title: t('common.tipTitle'), content: t('views.dashboard.cdr.exportTip'), onOk() { + modalState.confirmLoading = true; const hide = message.loading(t('common.loading'), 0); const querys = toRaw(queryParams); querys.pageSize = 10000; diff --git a/src/views/dashboard/smfCDR/index.vue b/src/views/dashboard/smfCDR/index.vue index 222e1b47..28975ea6 100644 --- a/src/views/dashboard/smfCDR/index.vue +++ b/src/views/dashboard/smfCDR/index.vue @@ -405,6 +405,7 @@ function fnExportList() { title: t('common.tipTitle'), content: t('views.dashboard.cdr.exportTip'), onOk() { + modalState.confirmLoading = true; const hide = message.loading(t('common.loading'), 0); const querys = toRaw(queryParams); querys.pageSize = 10000; diff --git a/src/views/dashboard/smscCDR/index.vue b/src/views/dashboard/smscCDR/index.vue index 9b3d034e..cac8d744 100644 --- a/src/views/dashboard/smscCDR/index.vue +++ b/src/views/dashboard/smscCDR/index.vue @@ -372,6 +372,7 @@ function fnExportList() { title: t('common.tipTitle'), content: t('views.dashboard.cdr.exportTip'), onOk() { + modalState.confirmLoading = true; const hide = message.loading(t('common.loading'), 0); const querys = toRaw(queryParams); querys.pageSize = 10000; diff --git a/src/views/ne/neConfig/hooks/useOptions.ts b/src/views/ne/neConfig/hooks/useOptions.ts index 8c88fde8..ba531f69 100644 --- a/src/views/ne/neConfig/hooks/useOptions.ts +++ b/src/views/ne/neConfig/hooks/useOptions.ts @@ -29,8 +29,13 @@ export default function useOptions({ t }: any) { case 'int': // filter: "0~128" - if (filter && filter.indexOf('~') !== -1) { - const filterArr = filter.split('~'); + if (filter) { + let filterArr = ['0', '1']; + if (filter.indexOf('-') !== -1) { + filterArr = filter.split('-'); + } else if (filter.indexOf('~') !== -1) { + filterArr = filter.split('~'); + } const minInt = parseInt(filterArr[0]); const maxInt = parseInt(filterArr[1]); const valueInt = parseInt(value); @@ -47,18 +52,12 @@ export default function useOptions({ t }: any) { break; case 'ipv4': if (!regExpIPv4.test(value)) { - return [ - false, - t('views.ne.neConfig.requireIpv4', { display }), - ]; + return [false, t('views.ne.neConfig.requireIpv4', { display })]; } break; case 'ipv6': if (!regExpIPv6.test(value)) { - return [ - false, - t('views.ne.neConfig.requireIpv6', { display }), - ]; + return [false, t('views.ne.neConfig.requireIpv6', { display })]; } break; case 'enum': @@ -71,10 +70,7 @@ export default function useOptions({ t }: any) { } if (!Object.keys(filterJson).includes(`${value}`)) { - return [ - false, - t('views.ne.neConfig.requireEnum', { display }), - ]; + return [false, t('views.ne.neConfig.requireEnum', { display })]; } } break; @@ -90,10 +86,7 @@ export default function useOptions({ t }: any) { } if (!Object.values(filterJson).includes(`${value}`)) { - return [ - false, - t('views.ne.neConfig.requireBool', { display }), - ]; + return [false, t('views.ne.neConfig.requireBool', { display })]; } } break; @@ -101,12 +94,20 @@ export default function useOptions({ t }: any) { // filter: "0~128" // 字符串长度判断 - if (filter && filter.indexOf('~') !== -1) { + if (filter) { try { - const filterArr = filter.split('~'); - let rule = new RegExp( - '^\\S{' + filterArr[0] + ',' + filterArr[1] + '}$' - ); + let rule: RegExp = new RegExp('^.*$'); + if (filter.indexOf('-') !== -1) { + const filterArr = filter.split('-'); + rule = new RegExp( + '^.{' + filterArr[0] + ',' + filterArr[1] + '}$' + ); + } else if (filter.indexOf('~') !== -1) { + const filterArr = filter.split('~'); + rule = new RegExp( + '^\\S{' + filterArr[0] + ',' + filterArr[1] + '}$' + ); + } if (!rule.test(value)) { return [ false, @@ -157,10 +158,7 @@ export default function useOptions({ t }: any) { break; default: - return [ - false, - t('views.ne.neConfig.requireUn', { display }), - ]; + return [false, t('views.ne.neConfig.requireUn', { display })]; } return result; } diff --git a/src/views/ne/neLicense/index.vue b/src/views/ne/neLicense/index.vue index 635bdeea..ce210815 100644 --- a/src/views/ne/neLicense/index.vue +++ b/src/views/ne/neLicense/index.vue @@ -105,8 +105,8 @@ let tableColumns = ref([ width: 120, }, { - title: t('views.ne.common.capability'), - dataIndex: 'capability', + title: t('views.ne.common.ueNumber'), + dataIndex: 'ueNumber', align: 'left', customRender(opt) { if (['UDM', 'AMF', 'MME'].includes(opt.record.neType)) { @@ -116,6 +116,18 @@ let tableColumns = ref([ }, width: 100, }, + { + title: t('views.ne.common.nbNumber'), + dataIndex: 'nbNumber', + align: 'left', + customRender(opt) { + if (['AMF', 'MME'].includes(opt.record.neType)) { + return opt.value; + } + return '-'; + }, + width: 100, + }, { title: t('common.remark'), dataIndex: 'remark', @@ -276,7 +288,8 @@ function fnRecordState(row: Record) { row.status = '1'; row.serialNum = res.data.sn; row.expiryDate = res.data.expire; - row.capability = res.data.capability; + row.ueNumber = res.data.ueNumber; + row.nbNumber = res.data.nbNumber; row.updateTime = new Date().getTime(); message.success( `${row.neType} ${row.neId} ${dictStatus.value[1].label}`, diff --git a/src/views/ne/neVersion/index.vue b/src/views/ne/neVersion/index.vue index 8242cf65..10a2740a 100644 --- a/src/views/ne/neVersion/index.vue +++ b/src/views/ne/neVersion/index.vue @@ -108,6 +108,7 @@ let tableColumns = ref([ { title: t('views.ne.neVersion.version'), dataIndex: 'version', + key: 'version', align: 'left', width: 150, resizable: true, @@ -605,6 +606,21 @@ onMounted(() => { +