feat: 添加网元配置快速PLMN修改框
This commit is contained in:
592
src/views/ne/neConfig/components/QuickSetup.vue
Normal file
592
src/views/ne/neConfig/components/QuickSetup.vue
Normal file
@@ -0,0 +1,592 @@
|
||||
<script setup lang="ts">
|
||||
import { reactive, toRaw, watch, ref } from 'vue';
|
||||
import { ProModal } from 'antdv-pro-modal';
|
||||
import { Form, message } from 'ant-design-vue/es';
|
||||
import useI18n from '@/hooks/useI18n';
|
||||
import useNeListStore from '@/store/modules/ne_list';
|
||||
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
||||
import {
|
||||
getNeConfigData,
|
||||
addNeConfigData,
|
||||
editNeConfigData,
|
||||
} from '@/api/ne/neConfig';
|
||||
const { t } = useI18n();
|
||||
const neListStore = useNeListStore();
|
||||
const emit = defineEmits(['ok', 'cancel', 'update:open']);
|
||||
const props = defineProps({
|
||||
open: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
|
||||
/**网元类型_多neId */
|
||||
let neCascaderOptions = ref<Record<string, any>[]>([]);
|
||||
|
||||
/**对话框对象信息状态类型 */
|
||||
type ModalStateType = {
|
||||
/**新增框或修改框是否显示 */
|
||||
openByEdit: boolean;
|
||||
/**标题 */
|
||||
title: string;
|
||||
/**表单数据 */
|
||||
from: Record<string, any>;
|
||||
/**网元类型 */
|
||||
neType: string[];
|
||||
/**需要配置的网元列表 */
|
||||
toNe: {
|
||||
neType: string;
|
||||
neId: string;
|
||||
}[];
|
||||
/**提示信息 */
|
||||
msg: string;
|
||||
/**确定按钮 loading */
|
||||
confirmLoading: boolean;
|
||||
};
|
||||
|
||||
/**对话框对象信息状态 */
|
||||
let modalState: ModalStateType = reactive({
|
||||
openByEdit: false,
|
||||
title: 'PLMN Info',
|
||||
from: {
|
||||
plmnId: {
|
||||
mcc: '001',
|
||||
mnc: '01',
|
||||
},
|
||||
tac: '4388',
|
||||
snssai: {
|
||||
sst: '1',
|
||||
sd: '000001',
|
||||
},
|
||||
dnn_data: 'internet',
|
||||
dnn_ims: 'ims',
|
||||
},
|
||||
neType: [],
|
||||
toNe: [],
|
||||
msg: '',
|
||||
confirmLoading: false,
|
||||
});
|
||||
|
||||
/**对话框内表单属性和校验规则 */
|
||||
const modalStateFrom = Form.useForm(
|
||||
modalState.from.plmnId,
|
||||
reactive({
|
||||
mcc: [
|
||||
{
|
||||
required: true,
|
||||
message: t('common.inputPlease'),
|
||||
},
|
||||
],
|
||||
mnc: [
|
||||
{
|
||||
required: true,
|
||||
message: t('common.inputPlease'),
|
||||
},
|
||||
],
|
||||
})
|
||||
);
|
||||
|
||||
/**网元类型选择对应修改 */
|
||||
function fnNeChange(p: any, c: any) {
|
||||
let neList: { neType: string; neId: string }[] = [];
|
||||
for (let i = 0; i < p.length; i++) {
|
||||
const v = p[i];
|
||||
if (v.length === 1) {
|
||||
c[i][0].children.forEach((item: any) => {
|
||||
neList.push({
|
||||
neType: item.neType,
|
||||
neId: item.neId,
|
||||
});
|
||||
});
|
||||
} else if (v.length === 2) {
|
||||
neList.push({
|
||||
neType: v[0],
|
||||
neId: v[1],
|
||||
});
|
||||
}
|
||||
}
|
||||
if (neList.length > 0) {
|
||||
modalState.toNe = neList;
|
||||
} else {
|
||||
modalState.toNe = [];
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 对话框弹出确认执行函数
|
||||
* 进行表达规则校验
|
||||
*/
|
||||
function fnModalOk() {
|
||||
if (modalState.confirmLoading) return;
|
||||
if (modalState.toNe.length === 0) {
|
||||
message.warning({
|
||||
content: 'Please select NE',
|
||||
duration: 3,
|
||||
});
|
||||
return;
|
||||
}
|
||||
const form = toRaw(modalState.from);
|
||||
// console.log(form);
|
||||
|
||||
modalStateFrom
|
||||
.validate()
|
||||
.then(async () => {
|
||||
modalState.confirmLoading = true;
|
||||
const hide = message.loading(t('common.loading'), 0);
|
||||
let errArr = [];
|
||||
for (const item of modalState.toNe) {
|
||||
const err = await toConfig(item.neType, item.neId, form);
|
||||
if (err.length > 0) {
|
||||
errArr.push(...err);
|
||||
}
|
||||
}
|
||||
modalState.msg = errArr.join('\n');
|
||||
modalState.confirmLoading = false;
|
||||
emit('ok', JSON.parse(JSON.stringify(form)));
|
||||
hide();
|
||||
})
|
||||
.catch(e => {
|
||||
message.error(t('common.errorFields', { num: e.errorFields.length }), 3);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 对话框弹出关闭执行函数
|
||||
* 进行表达规则校验
|
||||
*/
|
||||
function fnModalCancel() {
|
||||
modalState.openByEdit = false;
|
||||
modalState.confirmLoading = false;
|
||||
modalStateFrom.resetFields();
|
||||
emit('cancel');
|
||||
emit('update:open', false);
|
||||
// 还原默认值
|
||||
modalState.from = {
|
||||
plmnId: {
|
||||
mcc: '001',
|
||||
mnc: '01',
|
||||
},
|
||||
tac: '4388',
|
||||
snssai: {
|
||||
sst: '1',
|
||||
sd: '000001',
|
||||
},
|
||||
dnn_data: 'internet',
|
||||
dnn_ims: 'ims',
|
||||
};
|
||||
modalState.neType = [];
|
||||
modalState.toNe = [];
|
||||
modalState.msg = '';
|
||||
}
|
||||
|
||||
/**监听是否显示,初始数据 */
|
||||
watch(
|
||||
() => props.open,
|
||||
val => {
|
||||
if (val) {
|
||||
// 获取网元网元列表
|
||||
neCascaderOptions.value = neListStore.getNeCascaderOptions.filter(
|
||||
(item: any) => {
|
||||
return ['MME', 'AMF', 'UDM', 'IMS'].includes(item.value); // 过滤不可用的网元
|
||||
}
|
||||
);
|
||||
if (neCascaderOptions.value.length === 0) {
|
||||
message.warning({
|
||||
content: t('common.noData'),
|
||||
duration: 3,
|
||||
});
|
||||
return;
|
||||
}
|
||||
modalState.openByEdit = true;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// =============== 处理函数
|
||||
|
||||
const supportMapper: Record<string, any> = {
|
||||
AMF: [
|
||||
{
|
||||
type: 'array',
|
||||
name: 'guami',
|
||||
display: 'GUAMI List',
|
||||
key: ['plmnId'],
|
||||
item: (index: any, param: any, lastItem: any) => {
|
||||
const plmn = `${param.plmnId.mcc}${param.plmnId.mnc}`;
|
||||
return {
|
||||
index: index,
|
||||
plmnId: plmn,
|
||||
pointer: lastItem.pointer,
|
||||
regionId: lastItem.regionId,
|
||||
setId: lastItem.setId,
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'array',
|
||||
name: 'tai',
|
||||
display: 'TAI List',
|
||||
key: ['plmnId'],
|
||||
item: (index: any, param: any, lastItem: any) => {
|
||||
const plmn = `${param.plmnId.mcc}${param.plmnId.mnc}`;
|
||||
return {
|
||||
index: index,
|
||||
plmnId: plmn,
|
||||
tac: param.tac,
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'array',
|
||||
name: 'slice',
|
||||
display: 'Slice List',
|
||||
key: ['plmnId'],
|
||||
item: (index: any, param: any, lastItem: any) => {
|
||||
const plmn = `${param.plmnId.mcc}${param.plmnId.mnc}`;
|
||||
const sdStr = param.snssai.sd.padStart(6, '0');
|
||||
return {
|
||||
index: index,
|
||||
plmnId: plmn,
|
||||
sst: parseInt(param.snssai.sst),
|
||||
sd: sdStr,
|
||||
};
|
||||
},
|
||||
},
|
||||
],
|
||||
IMS: [
|
||||
{
|
||||
type: 'array',
|
||||
name: 'plmn',
|
||||
display: 'PLMN List',
|
||||
key: ['mcc', 'mnc'],
|
||||
item: (index: any, param: any, lastItem: any) => {
|
||||
const plmn = `${param.plmnId.mcc}${param.plmnId.mnc}`;
|
||||
const mccDomain = param.plmnId.mcc.padStart(3, '0');
|
||||
const domain = `ims.mnc${param.plmnId.mnc}.mcc${mccDomain}.3gppnetwork.org`;
|
||||
return {
|
||||
index: index,
|
||||
domain: domain,
|
||||
mcc: param.plmnId.mcc,
|
||||
mnc: param.plmnId.mnc,
|
||||
};
|
||||
},
|
||||
},
|
||||
],
|
||||
UDM: [
|
||||
{
|
||||
type: 'list',
|
||||
name: 'system',
|
||||
display: 'System',
|
||||
key: [
|
||||
'supportedPlmn1',
|
||||
'supportedPlmn2',
|
||||
'supportedPlmn3',
|
||||
'supportedPlmn4',
|
||||
],
|
||||
},
|
||||
],
|
||||
MME: [
|
||||
{
|
||||
type: 'array',
|
||||
name: 'gummei',
|
||||
display: 'Gummei List',
|
||||
key: ['plmnId'],
|
||||
item: (index: any, param: any, lastItem: any) => {
|
||||
const plmn = `${param.plmnId.mcc}${param.plmnId.mnc}`;
|
||||
return Object.assign(lastItem, {
|
||||
index: index,
|
||||
plmnId: plmn,
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'array',
|
||||
name: 'tai',
|
||||
display: 'TAI List',
|
||||
key: ['plmnId'],
|
||||
item: (index: any, param: any, lastItem: any) => {
|
||||
const plmn = `${param.plmnId.mcc}${param.plmnId.mnc}`;
|
||||
return {
|
||||
index: index,
|
||||
plmnId: plmn,
|
||||
tac: parseInt(param.tac),
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'array',
|
||||
name: 'hss',
|
||||
display: 'HSS List',
|
||||
key: ['imsiPre'],
|
||||
item: (index: any, param: any, lastItem: any) => {
|
||||
const plmn = `${param.plmnId.mcc}${param.plmnId.mnc}`;
|
||||
return Object.assign(lastItem, {
|
||||
index: index,
|
||||
imsiPre: plmn,
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'array',
|
||||
name: 'sgw',
|
||||
display: 'SGW List',
|
||||
key: ['plmnId'],
|
||||
item: (index: any, param: any, lastItem: any) => {
|
||||
const plmn = `${param.plmnId.mcc}${param.plmnId.mnc}`;
|
||||
return Object.assign(lastItem, {
|
||||
index: index,
|
||||
plmnId: plmn,
|
||||
tac: parseInt(param.tac),
|
||||
});
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
async function toConfig(
|
||||
ntType: string,
|
||||
neId: string,
|
||||
param: Record<string, any>
|
||||
) {
|
||||
let errMsgArr = [];
|
||||
const plmn = `${param.plmnId.mcc}${param.plmnId.mnc}`;
|
||||
for (const rule of supportMapper[ntType]) {
|
||||
const res = await getNeConfigData({
|
||||
neType: ntType,
|
||||
neId: neId,
|
||||
paramName: rule.name,
|
||||
});
|
||||
if (res.code != RESULT_CODE_SUCCESS) {
|
||||
// console.log('获取数据失败', rule);
|
||||
errMsgArr.push(`${ntType}_${neId} ${rule.display} get data failed`);
|
||||
continue;
|
||||
}
|
||||
if (res.data.length === 0) {
|
||||
// console.log('数据为空', rule);
|
||||
errMsgArr.push(`${ntType}_${neId} ${rule.display} data empty`);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (rule.type === 'list') {
|
||||
// key
|
||||
const data = res.data[0];
|
||||
let vArr = [];
|
||||
for (const k of rule.key) {
|
||||
vArr.push(data[k]);
|
||||
}
|
||||
if (vArr.includes(plmn)) {
|
||||
// console.log('存在跳过', rule.name, vArr, plmn);
|
||||
errMsgArr.push(`${ntType}_${neId} ${rule.display} already exists`);
|
||||
continue;
|
||||
}
|
||||
if (vArr.includes('')) {
|
||||
const index = vArr.findIndex(s => s == '');
|
||||
// console.log('空白新增', rule.name, rule.key[index], plmn);
|
||||
const resList = await editNeConfigData({
|
||||
neType: ntType,
|
||||
neId: neId,
|
||||
paramName: rule.name,
|
||||
paramData: {
|
||||
[rule.key[index]]: plmn,
|
||||
},
|
||||
});
|
||||
const state =
|
||||
resList.code != RESULT_CODE_SUCCESS ? 'failed' : 'success';
|
||||
errMsgArr.push(
|
||||
`${ntType}_${neId} ${rule.display} blank items added ${state}`
|
||||
);
|
||||
} else {
|
||||
// console.log(
|
||||
// '不存在替换最后的',
|
||||
// rule.name,
|
||||
// rule.key[rule.key.length - 1],
|
||||
// plmn
|
||||
// );
|
||||
const resList = await editNeConfigData({
|
||||
neType: ntType,
|
||||
neId: neId,
|
||||
paramName: rule.name,
|
||||
paramData: {
|
||||
[rule.key[rule.key.length - 1]]: plmn,
|
||||
},
|
||||
});
|
||||
const state =
|
||||
resList.code != RESULT_CODE_SUCCESS ? 'failed' : 'success';
|
||||
errMsgArr.push(
|
||||
`${ntType}_${neId} ${rule.display} replace the final ${state}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (rule.type === 'array') {
|
||||
// item
|
||||
let vArr = [];
|
||||
for (const item of res.data) {
|
||||
vArr.push(item[rule.key]);
|
||||
}
|
||||
if (vArr.includes(plmn)) {
|
||||
const item = res.data.find((s: any) => s[rule.key] == plmn);
|
||||
if (!item) {
|
||||
// console.log('没有找到', rule.name, index);
|
||||
errMsgArr.push(`${ntType}_${neId} ${rule.display} not found`);
|
||||
continue;
|
||||
}
|
||||
const index = item.index;
|
||||
const updateItem = rule.item(index, param, item);
|
||||
// console.log('存在修改', rule.name, index, updateItem);
|
||||
const resList = await editNeConfigData({
|
||||
neType: ntType,
|
||||
neId: neId,
|
||||
paramName: rule.name,
|
||||
paramData: updateItem,
|
||||
loc: `${index}`,
|
||||
});
|
||||
const state =
|
||||
resList.code != RESULT_CODE_SUCCESS ? 'failed' : 'success';
|
||||
errMsgArr.push(`${ntType}_${neId} ${rule.display} modify ${state}`);
|
||||
} else {
|
||||
let lastIndex = 0;
|
||||
const arr = res.data.sort((a: any, b: any) => b.index - a.index);
|
||||
if (arr.length != 0) {
|
||||
lastIndex = arr[0].index + 1;
|
||||
}
|
||||
const addItem = rule.item(lastIndex, param, arr[0]);
|
||||
// console.log('不存在新增', rule.name, lastIndex, addItem);
|
||||
const resList = await addNeConfigData({
|
||||
neType: ntType,
|
||||
neId: neId,
|
||||
paramName: rule.name,
|
||||
paramData: addItem,
|
||||
loc: `${lastIndex}`,
|
||||
});
|
||||
const state =
|
||||
resList.code != RESULT_CODE_SUCCESS ? 'failed' : 'success';
|
||||
errMsgArr.push(`${ntType}_${neId} ${rule.display} added ${state}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
return errMsgArr;
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ProModal
|
||||
:drag="true"
|
||||
:width="800"
|
||||
:destroyOnClose="true"
|
||||
:keyboard="false"
|
||||
:mask-closable="false"
|
||||
:open="modalState.openByEdit"
|
||||
:title="modalState.title"
|
||||
:confirm-loading="modalState.confirmLoading"
|
||||
@ok="fnModalOk"
|
||||
@cancel="fnModalCancel"
|
||||
>
|
||||
<a-form
|
||||
name="modalStateFromByEdit"
|
||||
layout="horizontal"
|
||||
:label-col="{ span: 6 }"
|
||||
:label-wrap="true"
|
||||
>
|
||||
<a-row>
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item label="DNN_DATA" name="basic.dnn_data" v-if="false">
|
||||
<a-input
|
||||
v-model:value="modalState.from.dnn_data"
|
||||
allow-clear
|
||||
:placeholder="t('common.inputPlease')"
|
||||
:maxlength="50"
|
||||
>
|
||||
<template #prefix>
|
||||
<a-tooltip placement="topLeft">
|
||||
<template #title> DNN </template>
|
||||
<InfoCircleOutlined style="opacity: 0.45; color: inherit" />
|
||||
</a-tooltip>
|
||||
</template>
|
||||
</a-input>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
label="MCC"
|
||||
name="basic.plmnId.mcc"
|
||||
v-bind="modalStateFrom.validateInfos.mcc"
|
||||
>
|
||||
<a-input
|
||||
v-model:value="modalState.from.plmnId.mcc"
|
||||
placeholder="1-65535"
|
||||
></a-input>
|
||||
</a-form-item>
|
||||
<a-form-item label="SST" name="basic.snssai.sst">
|
||||
<a-input-number
|
||||
v-model:value="modalState.from.snssai.sst"
|
||||
:min="1"
|
||||
:max="3"
|
||||
placeholder="1-3"
|
||||
style="width: 100%"
|
||||
>
|
||||
</a-input-number>
|
||||
</a-form-item>
|
||||
<a-form-item label="TAC" name="basic.tac">
|
||||
<a-input
|
||||
v-model:value="modalState.from.tac"
|
||||
placeholder="1-65535"
|
||||
></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item label="DNN_IMS" name="basic.dnn_ims" v-if="false">
|
||||
<a-input
|
||||
v-model:value="modalState.from.dnn_ims"
|
||||
allow-clear
|
||||
:placeholder="t('common.inputPlease')"
|
||||
:maxlength="50"
|
||||
>
|
||||
</a-input>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
label="MNC"
|
||||
name="basic.plmnId.mnc"
|
||||
v-bind="modalStateFrom.validateInfos.mnc"
|
||||
>
|
||||
<a-input
|
||||
v-model:value="modalState.from.plmnId.mnc"
|
||||
placeholder="1-65535"
|
||||
></a-input>
|
||||
</a-form-item>
|
||||
<a-form-item label="SD" name="basic.snssai.sd">
|
||||
<a-input
|
||||
v-model:value="modalState.from.snssai.sd"
|
||||
placeholder="1-65535"
|
||||
></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-divider orientation="left">To NE</a-divider>
|
||||
|
||||
<a-form-item
|
||||
:label="t('views.ne.common.neType')"
|
||||
name="neType"
|
||||
:label-col="{ span: 3 }"
|
||||
:label-wrap="true"
|
||||
>
|
||||
<a-cascader
|
||||
v-model:value="modalState.neType"
|
||||
:options="neCascaderOptions"
|
||||
@change="fnNeChange"
|
||||
multiple
|
||||
:allow-clear="false"
|
||||
:placeholder="t('views.ne.common.neTypePlease')"
|
||||
/>
|
||||
<a-textarea
|
||||
:disabled="true"
|
||||
:hidden="!modalState.msg"
|
||||
:value="modalState.msg"
|
||||
:auto-size="{ minRows: 2, maxRows: 8 }"
|
||||
style="margin-top: 8px"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</ProModal>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped></style>
|
||||
@@ -7,6 +7,7 @@ import { message } from 'ant-design-vue/es';
|
||||
import { DataNode } from 'ant-design-vue/es/tree';
|
||||
import useI18n from '@/hooks/useI18n';
|
||||
import TableColumnsDnd from '@/components/TableColumnsDnd/index.vue';
|
||||
import QuickSetup from './components/QuickSetup.vue';
|
||||
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
||||
import useNeListStore from '@/store/modules/ne_list';
|
||||
import useOptions from './hooks/useOptions';
|
||||
@@ -391,6 +392,12 @@ const { batchState, modalBatchOpen, modalBatchClose, modalBatchOk } =
|
||||
fnActiveConfigNode,
|
||||
});
|
||||
|
||||
/**快速修改编辑框 */
|
||||
const quickOpen = ref(false);
|
||||
function fnQuickOpen() {
|
||||
quickOpen.value = !quickOpen.value;
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
// 获取网元网元列表
|
||||
neCascaderOptions.value = neListStore.getNeCascaderOptions.filter(
|
||||
@@ -430,6 +437,13 @@ onMounted(() => {
|
||||
|
||||
<template>
|
||||
<PageContainer>
|
||||
<template #content> </template>
|
||||
<template #contentExtra>
|
||||
<a-button type="primary" @click="fnQuickOpen">
|
||||
Quickly Modify PLMN
|
||||
</a-button>
|
||||
</template>
|
||||
|
||||
<a-row :gutter="16">
|
||||
<a-col
|
||||
:lg="6"
|
||||
@@ -1053,6 +1067,9 @@ onMounted(() => {
|
||||
</a-row>
|
||||
</a-form>
|
||||
</ProModal>
|
||||
|
||||
<!-- 快速修改 -->
|
||||
<QuickSetup v-model:open="quickOpen"></QuickSetup>
|
||||
</PageContainer>
|
||||
</template>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user