561 lines
14 KiB
Vue
561 lines
14 KiB
Vue
<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>
|