Merge branch 'main-v2' into lite-ba

This commit is contained in:
TsMask
2025-08-29 19:53:10 +08:00
18 changed files with 114 additions and 77 deletions

View File

@@ -1,5 +1,17 @@
# 版本发布日志
## 2.2508.4-20250829
- 新增 网元授权显示用户数/基站数
- 优化 网元当前版本显示是否有包存在
- 优化 cdr/ue导出操作后锁定按钮事件防重发
- 优化 网元可选静态可选项添加PGWC
- 优化 参数配置添加校验过滤长度~和-定义范围
- 修复 UPF流量统计数据同时获取刷新
- 修复 UPF流量统计字节数据格式化显示不一致问题
- 新增 指标Title管理页面功能
- 新增 增加多个导出操作的超时时间至180秒
## 2.2508.2-20250815
- 优化 给config.js加随机数避免缓存

View File

@@ -22,6 +22,12 @@ export const NE_TYPE_LIST = [
'CHF',
'HLR',
'SGWC',
'PGWC',
'IP-SM-GW',
'MMTel-AS',
'I-CSCF',
'P-CSCF',
'S-CSCF',
];
/**

View File

@@ -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',

View File

@@ -539,6 +539,8 @@ export default {
port: '服务端口',
portTip: "网元服务端口,默认:33030",
capability: '容量',
ueNumber: '用户数',
nbNumber: '基站数',
serialNum: '序列号',
expiryDate: '许可证到期日期',
normalcy: '正常',

View File

@@ -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

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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<string, number>) {
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,
};
}

View File

@@ -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);

View File

@@ -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<string, number>) {
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,
};
}

View File

@@ -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));
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -105,8 +105,8 @@ let tableColumns = ref<TableColumnsType>([
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<TableColumnsType>([
},
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<string, any>) {
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}`,

View File

@@ -108,6 +108,7 @@ let tableColumns = ref<TableColumnsType>([
{
title: t('views.ne.neVersion.version'),
dataIndex: 'version',
key: 'version',
align: 'left',
width: 150,
resizable: true,
@@ -605,6 +606,21 @@ onMounted(() => {
<template v-if="column.key === 'status'">
<DictTag :options="dictStatus" :value="record.status" />
</template>
<template v-if="column.key === 'version'">
{{ record.version }}
<a-tooltip
placement="topRight"
v-if="
record.version &&
(record.path === '' || record.path === '-')
"
>
<template #title>
{{ t('views.ne.neVersion.noPath') }}
</template>
<InfoCircleOutlined />
</a-tooltip>
</template>
<template v-if="column.key === 'preVersion'">
{{ record.preVersion }}
<a-tooltip