From d870f12daf3e0e7ebb1367d26b7409c71b41e394 Mon Sep 17 00:00:00 2001 From: TsMask <340112800@qq.com> Date: Wed, 22 Nov 2023 15:27:13 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20mml=E5=91=BD=E4=BB=A4=E6=93=8D=E4=BD=9C?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E8=BE=93=E5=85=A5=E5=A4=9A=E8=A1=8C=E5=8F=91?= =?UTF-8?q?=E9=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/i18n/locales/en-US.ts | 10 +- src/i18n/locales/zh-CN.ts | 4 +- src/views/mmlManage/neOperate/index.vue | 350 ++++++++++++++++------- src/views/mmlManage/omcOperate/index.vue | 346 +++++++++++++++------- src/views/mmlManage/udmOperate/index.vue | 346 +++++++++++++++------- 5 files changed, 747 insertions(+), 309 deletions(-) diff --git a/src/i18n/locales/en-US.ts b/src/i18n/locales/en-US.ts index f0074793..36ba85b8 100644 --- a/src/i18n/locales/en-US.ts +++ b/src/i18n/locales/en-US.ts @@ -216,7 +216,7 @@ export default { tabPane1: 'Account password login', tabPane2: 'Login with phone number', registerBtn: 'Register an account', - loginBtn: 'Login', + loginBtn: 'Sign In', loginSuccess: 'Login successful', loginMethod: 'Other login methods:', loginMethodWX: 'WeChat Scan Login', @@ -1252,7 +1252,6 @@ export default { }, }, mmlManage: { - operationtitle: "Interface Settings", cmdTitle: "Command Navigator", cmdConsole: "consoles", cmdOpTip: "Select the item to be operated in the left command navigation!", @@ -1265,8 +1264,10 @@ export default { requireIpv6: "{display} Not a legitimate IPV6 address.", requireEnum: "{display} is not a reasonable enumeration value.", requireBool: "{display} is not a reasonable boolean value.", - clearForm: "Clear Forms", - clearLog: "Clearing logs", + cmdQuickEntry: "Command Quick Entry", + cmdParamPanel: "Parameter Panel", + clearForm: "Reset", + clearLog: "Clear Logs", exec: "Execute", cmdAwait: "Waiting for a command to be sent", omcOperate:{ @@ -1276,6 +1277,7 @@ export default { noUDM: "No UDM network elements", }, mmlSet: { + operationtitle: "Interface Settings", saveText: "Save Settings", ipadd: "Listening to IP addresses", ipaddPlease: "Please enter the listening IP address", diff --git a/src/i18n/locales/zh-CN.ts b/src/i18n/locales/zh-CN.ts index ea370570..53a8eb58 100644 --- a/src/i18n/locales/zh-CN.ts +++ b/src/i18n/locales/zh-CN.ts @@ -1264,7 +1264,9 @@ export default { requireIpv6: "{display} 不是合法的IPV6地址", requireEnum: "{display} 不是合理的枚举值", requireBool: "{display} 不是合理的布尔类型的值", - clearForm: "清除表单", + cmdQuickEntry: "命令快速输入", + cmdParamPanel: "参数面板", + clearForm: "重置", clearLog: "清除日志", exec: "执行", cmdAwait: "等待发送命令", diff --git a/src/views/mmlManage/neOperate/index.vue b/src/views/mmlManage/neOperate/index.vue index b4ab0ed3..edafac6e 100644 --- a/src/views/mmlManage/neOperate/index.vue +++ b/src/views/mmlManage/neOperate/index.vue @@ -11,7 +11,7 @@ import { getMMLByNE, sendMMlByNE } from '@/api/mmlManage/neOperate'; const { t } = useI18n(); /**网元参数 */ -let neCascaderOtions = ref[]>([]); +let neCascaderOptions = ref[]>([]); /**对象信息状态类型 */ type StateType = { @@ -25,6 +25,12 @@ type StateType = { mmlSelect: Record; /**表单数据 */ from: Record; + /**自动完成 input */ + autoCompleteValue: string; + /**自动完成 options */ + autoCompleteData: any[]; + /**自动完成 options */ + autoCompleteSearch: any[]; /**命令发送日志 */ mmlCmdLog: string; }; @@ -34,10 +40,19 @@ let state: StateType = reactive({ neType: [], mmlNeType: '', mmlTreeData: [], - mmlSelect: {}, + mmlSelect: { + title: '', + key: '', + operation: '', + object: '', + param: [], + }, from: { sendLoading: false, }, + autoCompleteValue: '', + autoCompleteData: [], + autoCompleteSearch: [], mmlCmdLog: '', }); @@ -45,6 +60,8 @@ let state: StateType = reactive({ function fnTreeSelect(_: any, info: any) { state.mmlSelect = info.node.dataRef; state.from = {}; + state.autoCompleteValue = + `${state.mmlSelect.operation} ${state.mmlSelect.object}`.trim(); // state.mmlCmdLog = ''; } @@ -55,6 +72,13 @@ function fnCleanCmdLog() { /**清空表单 */ function fnCleanFrom() { + state.mmlSelect = { + title: '', + key: '', + operation: '', + object: '', + param: [], + }; state.from = {}; } @@ -63,51 +87,64 @@ function fnSendMML() { if (state.from.sendLoading) { return; } + + let cmdStr = ''; const operation = state.mmlSelect.operation; const object = state.mmlSelect.object; - let cmdStr = ''; // 根据参数取值 let argsArr: string[] = []; const param = toRaw(state.mmlSelect.param) || []; - const from = toRaw(state.from); - for (const item of param) { - const value = from[item.name]; + if (operation && Array.isArray(param)) { + const from = toRaw(state.from); + for (const item of param) { + const value = from[item.name]; - // 是否必填项且有效值 - const notV = value === null || value === undefined || value === ''; - if (item.optional === 'false' && notV) { - message.warning(t('views.mmlManage.require', { num: item.display }), 2); - return; + // 是否必填项且有效值 + const notV = value === null || value === undefined || value === ''; + if (item.optional === 'false' && notV) { + message.warning(t('views.mmlManage.require', { num: item.display }), 2); + return; + } + + // 检查是否存在值 + if (!Reflect.has(from, item.name) || notV) { + continue; + } + + // 检查规则 + const [ok, msg] = ruleVerification(item, from[item.name]); + if (!ok) { + message.warning({ + content: `${msg}`, + duration: 3, + }); + return; + } + + argsArr.push(`${item.name}=${from[item.name]}`); } - // 检查是否存在值 - if (!Reflect.has(from, item.name) || notV) { - continue; + // 拼装命令 + const argsStr = argsArr.join(','); + if (object && argsStr) { + cmdStr = `${operation} ${object} ${argsStr}`; + } else if (object) { + cmdStr = `${operation} ${object}`; + } else { + cmdStr = `${operation} ${argsStr}`; } - - // 检查规则 - const [ok, msg] = ruleVerification(item, from[item.name]); - if (!ok) { - message.warning({ - content: `${msg}`, - duration: 3, - }); - return; - } - - argsArr.push(`${item.name}=${from[item.name]}`); + cmdStr = cmdStr.trim(); } - // 拼装命令 - const argsStr = argsArr.join(','); - if (object && argsStr) { - cmdStr = `${operation} ${object} ${argsStr}`; - } else if (object) { - cmdStr = `${operation} ${object}`; + if (cmdStr) { + state.autoCompleteValue = cmdStr; } else { - cmdStr = `${operation} ${argsStr}`; + let value = state.autoCompleteValue; + if (value.indexOf('\n') !== -1) { + value = value.replace(/(\r\n|\n)/g, ';'); + } + cmdStr = value; } - cmdStr = cmdStr.trim(); // 发送 state.mmlCmdLog += `${cmdStr}\n`; @@ -215,7 +252,7 @@ function ruleVerification( break; default: - return [false, t('views.mmlManage.requireUn', { display })]; + console.warn(t('views.mmlManage.requireUn', { display }), type); } return result; } @@ -224,8 +261,16 @@ function ruleVerification( function fnNeChange(keys: any, _: any) { // 不是同类型时需要重新加载 if (state.mmlNeType !== keys[0]) { + state.autoCompleteSearch = []; + state.autoCompleteData = []; state.mmlTreeData = []; - state.mmlSelect = {}; + state.mmlSelect = { + title: '', + key: '', + operation: '', + object: '', + param: {}, + }; fnGetList(); } } @@ -236,6 +281,8 @@ function fnGetList() { state.mmlNeType = neType; getMMLByNE(neType).then(res => { if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.data)) { + // 构建自动完成筛选结构 + const autoCompleteArr: Record[] = []; // 构建树结构 const treeArr: Record[] = []; for (const item of res.data) { @@ -252,8 +299,8 @@ function fnGetList() { } // 遍历检查大类 - const treeItem = treeArr.find(i => i.key == item['category']); - if (!treeItem) { + const treeItemIndex = treeArr.findIndex(i => i.key == item['category']); + if (treeItemIndex < 0) { treeArr.push({ title: item['catDisplay'], key: item['category'], @@ -262,17 +309,31 @@ function fnGetList() { { key: id, title: mmlDisplay, object, operation, param }, ], }); + autoCompleteArr.push({ + value: item['catDisplay'], + key: item['category'], + selectable: false, + options: [{ key: id, value: mmlDisplay, object, operation, param }], + }); } else { - treeItem.children.push({ + treeArr[treeItemIndex].children.push({ key: id, title: mmlDisplay, object, operation, param, }); + autoCompleteArr[treeItemIndex].options.push({ + key: id, + value: mmlDisplay, + object, + operation, + param, + }); } } state.mmlTreeData = treeArr; + state.autoCompleteData = autoCompleteArr; } else { message.warning({ content: t('views.mmlManage.cmdNoTip', { num: neType }), @@ -282,6 +343,82 @@ function fnGetList() { }); } +/**自动完成搜索匹配前缀 */ +function fnAutoCompleteSearch(value: string) { + state.autoCompleteSearch = []; + for (const item of state.autoCompleteData) { + const filterOptions = item.options.filter((s: any) => { + return `${s.operation} ${s.object}`.indexOf(value.toLowerCase()) >= 0; + }); + if (filterOptions.length > 0) { + state.autoCompleteSearch.push({ + value: item.value, + key: item.value, + selectable: false, + options: filterOptions, + }); + } + } +} + +/**自动完成搜索选择 */ +function fnAutoCompleteSelect(_: any, option: any) { + state.mmlSelect = { + title: option.value, + key: option.key, + operation: option.operation, + object: option.object, + param: option.param, + }; + state.from = {}; + state.autoCompleteValue = `${option.operation} ${option.object}`.trim(); +} + +/**自动完成搜索选择 */ +function fnAutoCompleteChange(value: any, _: any) { + if (value.indexOf(';') !== -1 || value.indexOf('\n') !== -1) { + fnCleanFrom(); + return; + } + for (const item of state.autoCompleteData) { + const findItem = item.options.find((s: any) => { + const prefix = `${s.operation} ${s.object}`; + return value.startsWith(prefix); + }); + if (findItem) { + state.mmlSelect = { + title: findItem.value, + key: findItem.key, + operation: findItem.operation, + object: findItem.object, + param: findItem.param, + }; + state.from = {}; + // 截取拆分赋值 + const prefix = `${findItem.operation} ${findItem.object} `; + const argsStr = value.replace(prefix, ''); + if (argsStr.length > 3) { + const argsArr = argsStr.split(','); + for (const arg of argsArr) { + const kvArr = arg.split('='); + if (kvArr.length >= 2) { + state.from[kvArr[0]] = kvArr[1]; + } + } + } + break; + } else { + state.mmlSelect = { + title: '', + key: '', + operation: '', + object: '', + param: [], + }; + } + } +} + onMounted(() => { // 获取网元网元列表 useNeInfoStore() @@ -290,18 +427,18 @@ onMounted(() => { if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.data)) { if (res.data.length > 0) { // 过滤不可用的网元 - neCascaderOtions.value = useNeInfoStore().getNeCascaderOtions.filter( + neCascaderOptions.value = useNeInfoStore().getNeCascaderOtions.filter( (item: any) => { return !['OMC'].includes(item.value); } ); // 默认选择AMF - const item = neCascaderOtions.value.find(s => s.value === 'AMF'); + const item = neCascaderOptions.value.find(s => s.value === 'AMF'); if (item && item.children) { const info = item.children[0]; state.neType = [info.neType, info.neId]; } else { - const info = neCascaderOtions.value[0].children[0]; + const info = neCascaderOptions.value[0].children[0]; state.neType = [info.neType, info.neId]; } fnGetList(); @@ -330,16 +467,18 @@ onMounted(() => { - + @@ -347,11 +486,7 @@ onMounted(() => { - +