Merge remote-tracking branch 'origin/main' into multi-tenant

This commit is contained in:
TsMask
2025-01-24 20:51:23 +08:00
6 changed files with 170 additions and 48 deletions

View File

@@ -11,7 +11,7 @@ VITE_APP_NAME = "Core Network OMC"
VITE_APP_CODE = "OMC"
# 应用版本
VITE_APP_VERSION = "2.250117"
VITE_APP_VERSION = "2.250124"
# 接口基础URL地址-不带/后缀
VITE_API_BASE_URL = "/omc-api"

View File

@@ -11,7 +11,7 @@ VITE_APP_NAME = "Core Network OMC"
VITE_APP_CODE = "OMC"
# 应用版本
VITE_APP_VERSION = "2.250117"
VITE_APP_VERSION = "2.250124"
# 接口基础URL地址-不带/后缀
VITE_API_BASE_URL = "/omc-api"

View File

@@ -41,3 +41,90 @@ export function exportMMEDataUE(data: Record<string, any>) {
timeout: 60_000,
});
}
/**
* MME-接入基站信息列表
* @param query 查询参数 neId=001&id=1
* @returns object
*/
export function listMMENblist(query: Record<string, any>) {
return request({
url: '/neData/mme/nb/list',
method: 'get',
params: query,
timeout: 60_000,
});
}
/**
* MME-接入基站状态信息列表
* @param query 查询参数 neId=001&state=1
* @returns object
*/
export function listMMENbStatelist(query: Record<string, any>) {
return request({
url: '/neData/mme/nb/list-cfg',
method: 'get',
params: query,
timeout: 60_000,
});
}
/**
* MME-接入基站状态信息新增
* @param neId 网元ID
* @param data 数据 { "index": 1, "name": "Enb", "address": "192.168.8.1", "position": "Area-B" }
* @returns object
*/
export function addMMENbState(neId: string, data: Record<string, any>) {
return request({
url: `/ne/config/data`,
method: 'post',
data: {
neType: 'MME',
neId: neId,
paramName: 'enbList',
paramData: data,
loc: `${data.index}`,
},
});
}
/**
* MME-接入基站状态信息修改
* @param neId 网元ID
* @param data 数据 { "index": 1, "name": "Enb", "address": "192.168.8.1", "position": "Area-B" }
* @returns object
*/
export function editMMENbState(neId: string, data: Record<string, any>) {
return request({
url: `/ne/config/data`,
method: 'put',
data: {
neType: 'MME',
neId: neId,
paramName: 'enbList',
paramData: data,
loc: `${data.index}`,
},
});
}
/**
* MME-接入基站状态信息删除
* @param neId 网元ID
* @param index 数据index
* @returns object
*/
export function delMMENbState(neId: string, index: string | number) {
return request({
url: `/ne/config/data`,
method: 'delete',
params: {
neType: 'MME',
neId: neId,
paramName: 'enbList',
loc: `${index}`,
},
});
}

View File

@@ -15,6 +15,12 @@ import {
} from '@/api/neData/amf';
const { t } = useI18n();
import { useRoute } from 'vue-router';
import {
addMMENbState,
delMMENbState,
editMMENbState,
listMMENbStatelist,
} from '@/api/neData/mme';
const route = useRoute();
const nbState = ref<DictType[]>([
@@ -204,7 +210,7 @@ function fnRecordDelete(index: string) {
}
for (const v of tableState.selectedRowKeys) {
if (neType === 'MME') {
// reqArr.push(delAMFNbState(neId, v));
reqArr.push(delMMENbState(neId, v));
}
if (neType === 'AMF') {
reqArr.push(delAMFNbState(neId, v));
@@ -212,7 +218,7 @@ function fnRecordDelete(index: string) {
}
} else {
if (neType === 'MME') {
// reqArr.push(delAMFNbState(neId, index));
reqArr.push(delMMENbState(neId, index));
}
if (neType === 'AMF') {
reqArr.push(delAMFNbState(neId, index));
@@ -247,9 +253,9 @@ function fnGetList() {
const [neType, neId] = neTypeAndId.value;
queryParams.neId = neId;
let req = null;
// if (neType === 'MME') {
// req = listAMFNbStatelist(toRaw(queryParams));
// }
if (neType === 'MME') {
req = listMMENbStatelist(toRaw(queryParams));
}
if (neType === 'AMF') {
req = listAMFNbStatelist(toRaw(queryParams));
}
@@ -309,11 +315,15 @@ let modalState: ModalStateType = reactive({
openByEdit: false,
title: 'NB Config List',
from: {
index: undefined,
address: '',
index: undefined,
name: '',
nbName: undefined,
offTime: undefined,
onTime: undefined,
position: '',
state: undefined,
ueNum: undefined,
},
confirmLoading: false,
});
@@ -368,17 +378,28 @@ function fnModalVisibleByEdit(edit?: string | number) {
* 进行表达规则校验
*/
function fnModalOk() {
const neID = queryParams.neId;
if (!neID) return;
const [neType, neId] = neTypeAndId.value;
if (!neId) return;
const from = JSON.parse(JSON.stringify(modalState.from));
modalStateFrom
.validate()
.then(e => {
modalState.confirmLoading = true;
const hide = message.loading(t('common.loading'), 0);
let result: any = from.state
? editAMFNbState(neID, from)
: addAMFNbState(neID, from);
let result: any = null;
if (neType === 'MME') {
result = from.state
? editMMENbState(neId, from)
: addMMENbState(neId, from);
}
if (neType === 'AMF') {
result = from.state
? editAMFNbState(neId, from)
: addAMFNbState(neId, from);
}
if (result === null) {
return;
}
result
.then((res: any) => {
if (res.code === RESULT_CODE_SUCCESS) {

View File

@@ -11,6 +11,7 @@ import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { stateNeInfo } from '@/api/ne/neInfo';
import { parseDateToStr } from '@/utils/date-utils';
import { useFullscreen } from '@vueuse/core';
import { listMMENbStatelist } from '@/api/neData/mme';
const { t } = useI18n();
/**图DOM节点实例对象 */
@@ -399,8 +400,7 @@ async function fnGraphDataBase() {
data.nodes?.push(node);
continue;
}
// if (['AMF', 'MME'].includes(item.value)) {
if (['AMF'].includes(item.value)) {
if (['AMF', 'MME'].includes(item.value)) {
if (item.children?.length === 0) continue;
for (const child of item.children) {
const id = `${child.neType}_${child.neId}`;
@@ -452,6 +452,25 @@ async function fnGraphDataNb(data: GraphData) {
}
}
if (item.nType === 'MME') {
const neId = (item.nInfo as any).neId;
const res = await listMMENbStatelist({ neId });
if (res.code !== RESULT_CODE_SUCCESS || !Array.isArray(res.data)) {
continue;
}
for (const nb of res.data) {
const id = `${item.id}_${nb.index}`;
data.nodes?.push({
id: id,
label: fittingString(`${nb.name}`, 80, 14),
img: parseBasePath('/svg/base4G.svg'),
nInfo: nb,
nType: 'ENB',
});
data.edges?.push({
source: item.id,
target: id,
});
}
}
}
return data;
@@ -514,6 +533,23 @@ async function fnGraphState(reload: boolean = false) {
}
}
if (reload && nInfo.neType === 'MME') {
const res = await listMMENbStatelist({ neId: nInfo.neId });
if (res.code == RESULT_CODE_SUCCESS && Array.isArray(res.data)) {
for (const nb of res.data) {
const nbItem = graphData.nodes.find(
(v: any) => v.id === `${id}_${nb.index}`
);
if (nbItem) {
Object.assign(nbItem.nInfo, nb);
const stateColor = nb.state === 'ON' ? '#52c41a' : '#f5222d'; // 状态颜色
graphG6.value.setItemState(
nbItem.id,
'top-right-dot',
stateColor
);
}
}
}
}
});
@@ -537,7 +573,7 @@ const interval = ref<boolean>(false);
/**递归刷新图状态 */
function repeatFn(reload: boolean = false) {
if (!interval.value) {
if (!interval.value || !graphG6Dom.value) {
return;
}
fnGraphState(reload)

View File

@@ -1,44 +1,17 @@
<script setup lang="ts">
import {
onMounted,
type Component,
defineAsyncComponent,
shallowRef,
ref,
} from 'vue';
import { ref } from 'vue';
import { PageContainer } from 'antdv-pro-layout';
import ListComponent from '@/views/ne-data/base-station/components/list.vue';
import TopologyComponent from '@/views/ne-data/base-station/components/topology.vue';
import useI18n from '@/hooks/useI18n';
const { t } = useI18n();
const defineComponent = shallowRef<Component | null>(null);
const value = ref<string>('list');
function fnSwitch(evt: any) {
const name = evt.target?.value;
if (name === 'topology') {
defineComponent.value = defineAsyncComponent(
() => import('@/views/ne-data/base-station/components/topology.vue')
);
}
if (name === 'list') {
defineComponent.value = defineAsyncComponent(
() => import('@/views/ne-data/base-station/components/list.vue')
);
}
}
onMounted(() => {
fnSwitch({ target: { value: 'list' } });
});
</script>
<template>
<PageContainer>
<template #extra>
<a-radio-group
v-model:value="value"
button-style="solid"
@change="fnSwitch"
>
<a-radio-group v-model:value="value" button-style="solid">
<a-radio-button value="list">
{{ t('views.neData.baseStation.list') }}
</a-radio-button>
@@ -48,7 +21,12 @@ onMounted(() => {
</a-radio-group>
</template>
<component :is="defineComponent" />
<div v-show="value === 'list'">
<ListComponent></ListComponent>
</div>
<div v-if="value === 'topology'">
<TopologyComponent></TopologyComponent>
</div>
</PageContainer>
</template>