feat: 快速修改PLMN
This commit is contained in:
560
src/views/ne/neConfig/components/Base.vue
Normal file
560
src/views/ne/neConfig/components/Base.vue
Normal file
@@ -0,0 +1,560 @@
|
||||
<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 useNeInfoStore from '@/store/modules/neinfo';
|
||||
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
||||
import { addNeHost, updateNeHost } from '@/api/ne/neHost';
|
||||
import {
|
||||
getNeConfigData,
|
||||
addNeConfigData,
|
||||
delNeConfigData,
|
||||
editNeConfigData,
|
||||
} from '@/api/ne/neConfig';
|
||||
const { t } = useI18n();
|
||||
const neInfoStore = useNeInfoStore();
|
||||
const emit = defineEmits(['ok', 'cancel', 'update:open']);
|
||||
const props = defineProps({
|
||||
open: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
});
|
||||
|
||||
/**网元类型_多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,
|
||||
uploadFiles: [],
|
||||
});
|
||||
|
||||
/**对话框内表单属性和校验规则 */
|
||||
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;
|
||||
hide();
|
||||
|
||||
// const neHost = form.hostId ? updateNeHost(form) : addNeHost(form);
|
||||
// neHost
|
||||
// .then(res => {
|
||||
// if (res.code === RESULT_CODE_SUCCESS) {
|
||||
// message.success({
|
||||
// content: t('common.operateOk'),
|
||||
// duration: 2,
|
||||
// });
|
||||
// // 返回无引用信息
|
||||
// emit('ok', JSON.parse(JSON.stringify(form)));
|
||||
// fnModalCancel();
|
||||
// } else {
|
||||
// message.error({
|
||||
// content: `${res.msg}`,
|
||||
// duration: 2,
|
||||
// });
|
||||
// }
|
||||
// })
|
||||
// .finally(() => {
|
||||
|
||||
// });
|
||||
})
|
||||
.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);
|
||||
}
|
||||
|
||||
/**监听是否显示,初始数据 */
|
||||
watch(
|
||||
() => props.open,
|
||||
val => {
|
||||
if (val) {
|
||||
// 获取网元网元列表
|
||||
neCascaderOptions.value = neInfoStore.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 = {
|
||||
AMF: [
|
||||
{
|
||||
type: 'array',
|
||||
name: 'guami',
|
||||
display: 'GUAMI List',
|
||||
key: ['plmnId'],
|
||||
item: (index, param) => {
|
||||
const plmn = `${param.plmnId.mcc}${param.plmnId.mnc}`;
|
||||
return {
|
||||
index: index,
|
||||
plmnId: plmn,
|
||||
pointer: 1,
|
||||
regionId: 1,
|
||||
setId: 1,
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'array',
|
||||
name: 'tai',
|
||||
display: 'TAI List',
|
||||
key: ['plmnId'],
|
||||
item: (index, data) => {
|
||||
return {
|
||||
index: index,
|
||||
plmnId: '00101',
|
||||
tac: '4388',
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'array',
|
||||
name: 'slice',
|
||||
display: 'Slice List',
|
||||
key: ['plmnId'],
|
||||
item: (index, data) => {
|
||||
return {
|
||||
index: index,
|
||||
plmnId: '00101',
|
||||
sd: '000001',
|
||||
sst: 1,
|
||||
};
|
||||
},
|
||||
},
|
||||
],
|
||||
IMS: [
|
||||
{
|
||||
type: 'array',
|
||||
name: 'plmn',
|
||||
display: 'PLMN List',
|
||||
key: ['mcc', 'mnc'],
|
||||
item: (index, param) => {
|
||||
const plmn = `${param.plmnId.mcc}${param.plmnId.mnc}`;
|
||||
const domain = `ims.mnc${param.plmnId.mnc}.mcc${param.plmnId.mcc}.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, param) => {
|
||||
const plmn = `${param.plmnId.mcc}${param.plmnId.mnc}`;
|
||||
return {
|
||||
index: index,
|
||||
code: 1,
|
||||
groupId: 1,
|
||||
plmnId: plmn,
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'array',
|
||||
name: 'tai',
|
||||
display: 'TAI List',
|
||||
key: ['plmnId'],
|
||||
item: (index, param) => {
|
||||
const plmn = `${param.plmnId.mcc}${param.plmnId.mnc}`;
|
||||
return {
|
||||
index: index,
|
||||
plmnId: plmn,
|
||||
tac: param.tac,
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'array',
|
||||
name: 'hss',
|
||||
display: 'HSS List',
|
||||
key: ['imsiPre'],
|
||||
item: (index, param) => {
|
||||
const plmn = `${param.plmnId.mcc}${param.plmnId.mnc}`;
|
||||
const Hostname = `hss.ims.mnc${param.plmnId.mnc}.mcc${param.plmnId.mcc}.3gppnetwork.org`;
|
||||
return {
|
||||
index: index,
|
||||
hssHostname: Hostname,
|
||||
hssPort: 3868,
|
||||
imsiPre: plmn,
|
||||
protocol: 'SCTP',
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'array',
|
||||
name: 'sgw',
|
||||
display: 'SGW List',
|
||||
key: ['plmnId'],
|
||||
item: (index, param) => {
|
||||
const plmn = `${param.plmnId.mcc}${param.plmnId.mnc}`;
|
||||
return {
|
||||
index: index,
|
||||
plmnId: plmn,
|
||||
sgwIp: '172.16.5.150',
|
||||
tac: 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} 获取数据失败`);
|
||||
continue;
|
||||
}
|
||||
if (res.data.length === 0) {
|
||||
console.log('数据为空', rule);
|
||||
errMsgArr.push(`${ntType}_${neId} ${rule.display} 数据为空`);
|
||||
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} 已存在${plmn}`);
|
||||
continue;
|
||||
}
|
||||
if (vArr.includes('')) {
|
||||
const index = vArr.findIndex(s => s == '');
|
||||
console.log('空白新增', rule.name, rule.key[index], plmn);
|
||||
errMsgArr.push(`${ntType}_${neId} ${rule.display} 空白项新增${plmn}`);
|
||||
} else {
|
||||
console.log(
|
||||
'不存在替换最后的',
|
||||
rule.name,
|
||||
rule.key[rule.key.length - 1],
|
||||
plmn
|
||||
);
|
||||
errMsgArr.push(`${ntType}_${neId} ${rule.display} 替换最后的`);
|
||||
}
|
||||
}
|
||||
|
||||
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 => s[rule.key] == plmn);
|
||||
if (!item) {
|
||||
console.log('没有找到', rule.name, index);
|
||||
errMsgArr.push(`${ntType}_${neId} ${rule.display} 没有找到`);
|
||||
continue;
|
||||
}
|
||||
const index = item.index;
|
||||
const updateItem = rule.item(index, param);
|
||||
console.log('存在修改', rule.name, index, updateItem);
|
||||
errMsgArr.push(`${ntType}_${neId} ${rule.display} 修改成功`);
|
||||
} else {
|
||||
const item = res.data.sort((a, b) => b.index - a.index);
|
||||
if (!item) {
|
||||
console.log('没有找到', rule.name, index);
|
||||
errMsgArr.push(`${ntType}_${neId} ${rule.display} 没有找到`);
|
||||
continue;
|
||||
}
|
||||
const lastIndex = item[0].index + 1;
|
||||
const addItem = rule.item(lastIndex, param);
|
||||
console.log('不存在新增', rule.name, lastIndex, addItem);
|
||||
errMsgArr.push(`${ntType}_${neId} ${rule.display} 新增成功`);
|
||||
}
|
||||
}
|
||||
}
|
||||
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">
|
||||
<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">
|
||||
<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">
|
||||
<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>
|
||||
@@ -5,6 +5,7 @@ import { ProModal } from 'antdv-pro-modal';
|
||||
import { message } from 'ant-design-vue/es';
|
||||
import { DataNode } from 'ant-design-vue/es/tree';
|
||||
import useI18n from '@/hooks/useI18n';
|
||||
import Base from './components/Base.vue';
|
||||
import TableColumnsDnd from '@/components/TableColumnsDnd/index.vue';
|
||||
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
||||
import useNeInfoStore from '@/store/modules/neinfo';
|
||||
@@ -362,8 +363,13 @@ const {
|
||||
arrayEditClose,
|
||||
});
|
||||
|
||||
const baseOpen = ref(false);
|
||||
function fnBaseOpen() {
|
||||
baseOpen.value = !baseOpen.value;
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
neInfoStore.fnNelist().then(res => {
|
||||
neInfoStore.fnNelist().then(res => {
|
||||
if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.data)) {
|
||||
if (res.data.length > 0) {
|
||||
// 过滤不可用的网元
|
||||
@@ -402,6 +408,11 @@ onMounted(() => {
|
||||
|
||||
<template>
|
||||
<PageContainer>
|
||||
<template #content> </template>
|
||||
<template #contentExtra>
|
||||
<a-button type="primary" @click="fnBaseOpen"> Quickly Modify PLMN </a-button>
|
||||
</template>
|
||||
|
||||
<a-row :gutter="16">
|
||||
<a-col
|
||||
:lg="6"
|
||||
@@ -915,6 +926,9 @@ onMounted(() => {
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</ProModal>
|
||||
|
||||
<!-- 快速修改 -->
|
||||
<Base v-model:open="baseOpen"></Base>
|
||||
</PageContainer>
|
||||
</template>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user