pref: 网元快速安装页面重构
This commit is contained in:
@@ -1,15 +1,11 @@
|
||||
<script setup lang="ts">
|
||||
import { Form, Modal, message } from 'ant-design-vue/lib';
|
||||
import { onMounted, reactive, toRaw } from 'vue';
|
||||
import {
|
||||
addNeInfo,
|
||||
getNeInfoByTypeAndID,
|
||||
updateNeInfo,
|
||||
} from '@/api/ne/neInfo';
|
||||
import { addNeInfo, getNeInfoByTypeAndID, updateNeInfo } from '@/api/ne/neInfo';
|
||||
import { neHostAuthorizedRSA, testNeHost } from '@/api/ne/neHost';
|
||||
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
||||
import { NE_TYPE_LIST } from '@/constants/ne-constants';
|
||||
import { fnToStepName, stepState } from '../hooks/useStep';
|
||||
import { fnRestStepState, fnToStepName, stepState } from '../hooks/useStep';
|
||||
import useI18n from '@/hooks/useI18n';
|
||||
import useDictStore from '@/store/modules/dict';
|
||||
import useNeInfoStore from '@/store/modules/neinfo';
|
||||
@@ -308,6 +304,18 @@ function fnNeIPChange(e: any) {
|
||||
}
|
||||
}
|
||||
|
||||
/**返回上一步 */
|
||||
function fnStepPrev() {
|
||||
Modal.confirm({
|
||||
title: t('common.tipTitle'),
|
||||
content: '确认要放弃当前变更返回上一步吗?',
|
||||
onOk() {
|
||||
fnRestStepState();
|
||||
fnToStepName('Start');
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**下一步操作 */
|
||||
function fnStepNext() {
|
||||
if (!modalState.stepNext) return;
|
||||
@@ -671,6 +679,8 @@ onMounted(() => {
|
||||
|
||||
<div class="ne-oper">
|
||||
<a-space direction="horizontal" :size="18">
|
||||
<a-button @click="fnStepPrev()"> 上一步 </a-button>
|
||||
|
||||
<a-button
|
||||
type="primary"
|
||||
@click="fnModalOk()"
|
||||
|
||||
@@ -249,6 +249,9 @@ function fnRecordInstall() {
|
||||
message.error(`安装失败 ${res.msg}`, 3);
|
||||
}
|
||||
|
||||
// 非选择的重置
|
||||
state.optionType = 'option';
|
||||
fnOptionTypeChange();
|
||||
hide();
|
||||
state.confirmLoading = false;
|
||||
},
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<script setup lang="ts">
|
||||
import { Modal, message } from 'ant-design-vue/lib';
|
||||
import { defineAsyncComponent, onMounted, reactive, ref, toRaw } from 'vue';
|
||||
import { fnToStepName, stepState } from '../hooks/useStep';
|
||||
import { Modal } from 'ant-design-vue/lib';
|
||||
import { defineAsyncComponent, onMounted, onUnmounted, reactive } from 'vue';
|
||||
import { fnRestStepState, stepState } from '../hooks/useStep';
|
||||
import useI18n from '@/hooks/useI18n';
|
||||
import { getNeLicenseByTypeAndID } from '@/api/ne/neLicense';
|
||||
import { codeNeLicense, stateNeLicense } from '@/api/ne/neLicense';
|
||||
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
||||
const { t } = useI18n();
|
||||
const EditModal = defineAsyncComponent(
|
||||
@@ -12,42 +12,62 @@ const EditModal = defineAsyncComponent(
|
||||
|
||||
/**对象信息信息状态类型 */
|
||||
type StateType = {
|
||||
/**是否可以下一步 */
|
||||
stepNext: boolean;
|
||||
/**文件上传 */
|
||||
visibleByFile: boolean;
|
||||
/**授权信息数据 */
|
||||
from: {
|
||||
id: undefined | string;
|
||||
neType: string;
|
||||
neId: string;
|
||||
activationRequestCode: string;
|
||||
licensePath: string;
|
||||
reload: boolean;
|
||||
// 下面是状态检查结果
|
||||
expire: string;
|
||||
sn: string;
|
||||
};
|
||||
/**确定按钮 loading */
|
||||
confirmLoading: boolean;
|
||||
/**定时调度 */
|
||||
timeInterval: any;
|
||||
timeCount: number;
|
||||
};
|
||||
|
||||
/**对象信息状态 */
|
||||
let state: StateType = reactive({
|
||||
stepNext: false,
|
||||
optionType: 'option',
|
||||
visibleByFile: false,
|
||||
from: {
|
||||
id: undefined,
|
||||
neType: '',
|
||||
neId: '',
|
||||
activationRequestCode: '',
|
||||
licensePath: '',
|
||||
reload: true,
|
||||
expire: '',
|
||||
sn: '',
|
||||
},
|
||||
confirmLoading: false,
|
||||
timeInterval: null,
|
||||
timeCount: 30,
|
||||
});
|
||||
|
||||
/**对话框弹出确认执行函数*/
|
||||
function fnModalOk(e: any) {
|
||||
Object.assign(state.from, e);
|
||||
state.timeInterval = setInterval(() => {
|
||||
if (state.timeCount <= 0) {
|
||||
state.from.sn = '';
|
||||
state.from.expire = '';
|
||||
clearInterval(state.timeInterval);
|
||||
state.timeInterval = null;
|
||||
state.timeCount = 30;
|
||||
return;
|
||||
}
|
||||
if (state.timeCount % 5 === 0) {
|
||||
stateNeLicense(e.neType, e.neId).then(res => {
|
||||
if (res.code === RESULT_CODE_SUCCESS && res.data) {
|
||||
state.from.sn = res.data.sn;
|
||||
state.from.expire = res.data.expire;
|
||||
|
||||
clearInterval(state.timeInterval);
|
||||
state.timeInterval = null;
|
||||
state.timeCount = 30;
|
||||
}
|
||||
});
|
||||
}
|
||||
state.timeCount--;
|
||||
}, 1_000);
|
||||
}
|
||||
|
||||
/**对话框弹出关闭执行函数*/
|
||||
@@ -55,166 +75,84 @@ function fnModalCancel() {
|
||||
state.visibleByFile = false;
|
||||
}
|
||||
|
||||
/**启动服务验证 */
|
||||
function fnRunCheck() {
|
||||
if (state.confirmLoading) return;
|
||||
const form = toRaw(state.from);
|
||||
// if (form.licensePath === '') {
|
||||
// message.error(t('common.errorFields', { num: 1 }), 3);
|
||||
// return;
|
||||
// }
|
||||
state.confirmLoading = true;
|
||||
const hide = message.loading(t('common.loading'), 0);
|
||||
// changeNeLicense(form)
|
||||
// .then(res => {
|
||||
// if (res.code === RESULT_CODE_SUCCESS) {
|
||||
// message.success('网元开始进行校验', 3);
|
||||
// fnVerifyTask();
|
||||
// } else {
|
||||
// message.error(res.msg, 3);
|
||||
// }
|
||||
// })
|
||||
// .finally(() => {
|
||||
// hide();
|
||||
// state.confirmLoading = false;
|
||||
// });
|
||||
}
|
||||
|
||||
/**
|
||||
* 对话框弹出显示为 新增或者修改
|
||||
* @param id id
|
||||
*/
|
||||
function fnModalVisibleByTypeAndId(neType: string, neId: string) {
|
||||
const hide = message.loading(t('common.loading'), 0);
|
||||
getNeLicenseByTypeAndID(neType, neId)
|
||||
.then(res => {
|
||||
if (res.code === RESULT_CODE_SUCCESS) {
|
||||
Object.assign(state.from, res.data);
|
||||
|
||||
} else {
|
||||
message.error(res.msg, 3);
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
state.confirmLoading = false;
|
||||
hide();
|
||||
});
|
||||
}
|
||||
|
||||
/**返回上一步 */
|
||||
function fnStepPrev() {
|
||||
/**结束操作 */
|
||||
function fnStepEnd() {
|
||||
Modal.confirm({
|
||||
title: t('common.tipTitle'),
|
||||
content: '确认要放弃当前变更返回上一步吗?',
|
||||
content: '确认要结束安装吗?',
|
||||
onOk() {
|
||||
fnToStepName('NeInfoSoftwareInstall');
|
||||
fnRestStepState();
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**下一步操作 */
|
||||
function fnStepNext(stepName: 'Done') {
|
||||
if (stepName === 'Done') {
|
||||
Modal.confirm({
|
||||
title: t('common.tipTitle'),
|
||||
content: '确认要结束网元安装吗?',
|
||||
onOk() {
|
||||
fnToStepName('Done');
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
const { neType, neId } = stepState.neInfo;
|
||||
if (neId) {
|
||||
state.from.neType = neType;
|
||||
state.from.neId = neId;
|
||||
codeNeLicense(neType, neId);
|
||||
}
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
clearInterval(state.timeInterval);
|
||||
state.timeInterval = null;
|
||||
state.timeCount = 30;
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="ne">
|
||||
<a-form
|
||||
name="modalStateFrom"
|
||||
layout="horizontal"
|
||||
autocomplete="off"
|
||||
:validate-on-rule-change="false"
|
||||
:validateTrigger="[]"
|
||||
:label-col="{ span: 3 }"
|
||||
:wrapper-col="{ span: 12 }"
|
||||
:label-wrap="true"
|
||||
<a-result
|
||||
:status="!state.from.sn ? 'info' : 'success'"
|
||||
:title="!state.from.sn ? '是否立即授权激活' : '成功激活'"
|
||||
>
|
||||
<template #extra>
|
||||
<a-button
|
||||
type="primary"
|
||||
:disabled="state.from.sn !== ''"
|
||||
:loading="state.timeCount < 30"
|
||||
@click="() => (state.visibleByFile = !state.visibleByFile)"
|
||||
>
|
||||
授权激活
|
||||
</a-button>
|
||||
<a-button
|
||||
type="default"
|
||||
:disabled="state.timeCount < 30"
|
||||
@click="fnStepEnd()"
|
||||
>
|
||||
结束
|
||||
</a-button>
|
||||
</template>
|
||||
|
||||
<div
|
||||
v-if="
|
||||
state.timeInterval === null && state.timeCount === 30 && !state.from.sn
|
||||
"
|
||||
>
|
||||
<a-form-item label="授权申请码" name="comment" :required="true">
|
||||
<a-input-group compact>
|
||||
<a-input
|
||||
v-model:value="state.from.activationRequestCode"
|
||||
:disabled="true"
|
||||
style="width: calc(100% - 64px)"
|
||||
/>
|
||||
<a-tooltip title="复制">
|
||||
<a-button type="default">
|
||||
<template #icon><CopyOutlined /></template>
|
||||
</a-button>
|
||||
</a-tooltip>
|
||||
<a-tooltip title="下载">
|
||||
<a-button type="primary">
|
||||
<template #icon><DownloadOutlined /></template>
|
||||
</a-button>
|
||||
</a-tooltip>
|
||||
</a-input-group>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item name="check" :wrapper-col="{ span: 14, offset: 3 }">
|
||||
<div style="align-items: center">
|
||||
<a-button
|
||||
type="primary"
|
||||
shape="round"
|
||||
@click="fnRunCheck()"
|
||||
:loading="state.confirmLoading"
|
||||
>
|
||||
<template #icon><LinkOutlined /></template>
|
||||
授权校验
|
||||
</a-button>
|
||||
</div>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
|
||||
<!-- 文件上传框 -->
|
||||
<EditModal
|
||||
v-model:visible="state.visibleByFile"
|
||||
:ne-type="state.from.neType"
|
||||
:ne-id="state.from.neId"
|
||||
@ok="fnModalOk"
|
||||
@cancel="fnModalCancel"
|
||||
></EditModal>
|
||||
|
||||
<div class="ne-oper">
|
||||
<a-space direction="horizontal" :size="18">
|
||||
<a-button type="default" danger :loading="state.confirmLoading">
|
||||
<template #icon><ReloadOutlined /></template>
|
||||
Refresh State
|
||||
</a-button>
|
||||
|
||||
<a-button type="ghost" :loading="state.confirmLoading">
|
||||
<template #icon><DownloadOutlined /></template>
|
||||
Download Activation Code
|
||||
</a-button>
|
||||
|
||||
<a-button type="dashed" @click="fnStepNext('Done')"> 结束 </a-button>
|
||||
<p>授权激活可获取授权激活码,得到授权文件后上传激活</p>
|
||||
<p>结束将返回第一步</p>
|
||||
</div>
|
||||
<div v-if="state.timeInterval !== null">
|
||||
<a-space direction="horizontal" :size="16">
|
||||
<a-spin />
|
||||
等待网元验证 {{ state.timeCount }}s
|
||||
</a-space>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="state.from.sn !== ''">
|
||||
<p style="font-size: 16px">序列号:{{ state.from.sn }}</p>
|
||||
<p style="font-size: 16px">许可证到期时间:{{ state.from.expire }}</p>
|
||||
</div>
|
||||
</a-result>
|
||||
|
||||
<!-- 文件上传框 -->
|
||||
<EditModal
|
||||
v-model:visible="state.visibleByFile"
|
||||
:ne-type="state.from.neType"
|
||||
:ne-id="state.from.neId"
|
||||
@ok="fnModalOk"
|
||||
@cancel="fnModalCancel"
|
||||
></EditModal>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.ne {
|
||||
padding-top: 12px;
|
||||
|
||||
&-oper {
|
||||
padding-top: 24px;
|
||||
text-align: end;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<style lang="less" scoped></style>
|
||||
|
||||
@@ -108,7 +108,6 @@ const checkStateFrom = Form.useForm(
|
||||
function fnCheckInfo() {
|
||||
if (state.confirmLoading) return;
|
||||
const form = toRaw(state.from);
|
||||
console.log(form);
|
||||
const validateArr = ['addr', 'port', 'user'];
|
||||
if (form.authMode === '0') {
|
||||
validateArr.push('password');
|
||||
|
||||
@@ -1,339 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { reactive, onMounted, toRaw, onUnmounted } from 'vue';
|
||||
import { message, Modal, Upload } from 'ant-design-vue/lib';
|
||||
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
||||
import { useClipboard } from '@vueuse/core';
|
||||
import { FileType } from 'ant-design-vue/lib/upload/interface';
|
||||
import { UploadRequestOption } from 'ant-design-vue/lib/vc-upload/interface';
|
||||
import { uploadFile } from '@/api/tool/file';
|
||||
import {
|
||||
codeNeLicense,
|
||||
changeNeLicense,
|
||||
stateNeLicense,
|
||||
} from '@/api/ne/neLicense';
|
||||
import useI18n from '@/hooks/useI18n';
|
||||
import { stepState } from '../hooks/useStep';
|
||||
import saveAs from 'file-saver';
|
||||
const { copy } = useClipboard({ legacy: true });
|
||||
const { t } = useI18n();
|
||||
|
||||
/**授权激活对象信息状态类型 */
|
||||
type LicenseStateType = {
|
||||
/**步骤 */
|
||||
setp: 'license' | 'verify';
|
||||
/**表单数据 */
|
||||
from: {
|
||||
neType: string;
|
||||
neId: string;
|
||||
activationRequestCode: string;
|
||||
licensePath: string;
|
||||
reload: boolean;
|
||||
};
|
||||
/**确定按钮 loading */
|
||||
confirmLoading: boolean;
|
||||
/**上传文件 */
|
||||
uploadFiles: any[];
|
||||
};
|
||||
|
||||
/**授权激活对象信息状态 */
|
||||
const licenseState: LicenseStateType = reactive({
|
||||
setp: 'license',
|
||||
from: {
|
||||
neType: '',
|
||||
neId: '',
|
||||
activationRequestCode: '',
|
||||
licensePath: '',
|
||||
reload: true,
|
||||
},
|
||||
confirmLoading: false,
|
||||
uploadFiles: [],
|
||||
});
|
||||
|
||||
/**表单上传前检查或转换压缩 */
|
||||
function fnBeforeUploadFile(file: FileType) {
|
||||
if (licenseState.confirmLoading) return false;
|
||||
if (!file.name.endsWith('.ini')) {
|
||||
message.error('只支持上传文件格式 .ini', 3);
|
||||
return Upload.LIST_IGNORE;
|
||||
}
|
||||
const isLt2M = file.size / 1024 / 1024 < 2;
|
||||
if (!isLt2M) {
|
||||
message.error('文件必须小于2MB', 3);
|
||||
return Upload.LIST_IGNORE;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**表单上传文件 */
|
||||
function fnUploadFile(up: UploadRequestOption) {
|
||||
// 发送请求
|
||||
const hide = message.loading(t('common.loading'), 0);
|
||||
licenseState.confirmLoading = true;
|
||||
let formData = new FormData();
|
||||
formData.append('file', up.file);
|
||||
formData.append('subPath', 'license');
|
||||
uploadFile(formData)
|
||||
.then(res => {
|
||||
if (res.code === RESULT_CODE_SUCCESS) {
|
||||
message.success('上传成功', 3);
|
||||
// 改为完成状态
|
||||
const file = licenseState.uploadFiles[0];
|
||||
file.percent = 100;
|
||||
file.status = 'done';
|
||||
// 预置到表单
|
||||
const { fileName } = res.data;
|
||||
licenseState.from.licensePath = fileName;
|
||||
} else {
|
||||
message.error(res.msg, 3);
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
hide();
|
||||
licenseState.confirmLoading = false;
|
||||
});
|
||||
}
|
||||
|
||||
/**复制授权申请码 */
|
||||
function fnCopyCode() {
|
||||
const code = licenseState.from.activationRequestCode;
|
||||
if (!code) return;
|
||||
copy(code).then(() => {
|
||||
message.success('已成功复制', 3);
|
||||
});
|
||||
}
|
||||
|
||||
/**下载授权申请码文件 */
|
||||
function fnDownCode() {
|
||||
const { activationRequestCode, neType, neId } = licenseState.from;
|
||||
if (!activationRequestCode) return;
|
||||
Modal.confirm({
|
||||
title: t('common.tipTitle'),
|
||||
content: '确认将授权申请码下载为文件进行保存?',
|
||||
onOk() {
|
||||
const blob = new Blob([activationRequestCode], {
|
||||
type: 'text/plain',
|
||||
});
|
||||
saveAs(blob, `${neType}_${neId}_code.txt`);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**读取授权申请码 */
|
||||
function fnGetCode() {
|
||||
const { neType, neId } = licenseState.from;
|
||||
licenseState.confirmLoading = true;
|
||||
codeNeLicense(neType, neId).then(res => {
|
||||
if (res.code === RESULT_CODE_SUCCESS) {
|
||||
licenseState.from.activationRequestCode = res.data;
|
||||
licenseState.confirmLoading = false;
|
||||
} else {
|
||||
message.error(res.msg, 3);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**启动服务验证 */
|
||||
function fnRunCheck() {
|
||||
if (licenseState.confirmLoading) return;
|
||||
const form = toRaw(licenseState.from);
|
||||
if (form.licensePath === '') {
|
||||
message.error(t('common.errorFields', { num: 1 }), 3);
|
||||
return;
|
||||
}
|
||||
licenseState.confirmLoading = true;
|
||||
const hide = message.loading(t('common.loading'), 0);
|
||||
changeNeLicense(form)
|
||||
.then(res => {
|
||||
if (res.code === RESULT_CODE_SUCCESS) {
|
||||
message.success('网元开始进行校验', 3);
|
||||
fnVerifyTask();
|
||||
} else {
|
||||
message.error(res.msg, 3);
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
hide();
|
||||
licenseState.confirmLoading = false;
|
||||
});
|
||||
}
|
||||
|
||||
/**校验状态 */
|
||||
const verifyState = reactive({
|
||||
timer: null as any,
|
||||
/**执行次数 */
|
||||
count: 0,
|
||||
/**信息日志 */
|
||||
msgArr: [] as string[],
|
||||
/**数据 sn expire */
|
||||
data: null as any,
|
||||
});
|
||||
|
||||
/**巡检校验任务 */
|
||||
function fnVerifyTask() {
|
||||
licenseState.setp = 'verify';
|
||||
verifyState.timer = setInterval(() => {
|
||||
if (verifyState.count > 15) {
|
||||
clearTimeout(verifyState.timer);
|
||||
verifyState.msgArr.unshift(
|
||||
`第 ${verifyState.count} 次:网元验证激活失败,请重新上传有效激活文件。`
|
||||
);
|
||||
return;
|
||||
}
|
||||
const { neType, neId } = licenseState.from;
|
||||
stateNeLicense(neType, neId).then(res => {
|
||||
if (res.code === RESULT_CODE_SUCCESS && res.data && res.data.sn) {
|
||||
message.success(`${neType} ${neId} 网元激活成功`, 3);
|
||||
verifyState.data = res.data;
|
||||
// 记录当前步骤状态信息
|
||||
stepState.states[stepState.current] = { from: res.data };
|
||||
stepState.stepNext = true;
|
||||
}
|
||||
verifyState.count += 1;
|
||||
verifyState.msgArr.unshift(`第 ${verifyState.count} 次:${res.msg}`);
|
||||
});
|
||||
}, 2_000);
|
||||
}
|
||||
|
||||
/**巡检重新校验 */
|
||||
function fnVerifyTaskStop() {
|
||||
clearTimeout(verifyState.timer);
|
||||
verifyState.count = 0;
|
||||
verifyState.msgArr = [];
|
||||
licenseState.setp = 'license';
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
// 读取步骤:网元信息
|
||||
const stepPrevFrom = stepState.states[1].from;
|
||||
const { neType, neId } = stepPrevFrom;
|
||||
licenseState.from.neType = neType;
|
||||
licenseState.from.neId = neId;
|
||||
// 获取code
|
||||
fnGetCode();
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
clearTimeout(verifyState.timer);
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a-form
|
||||
name="modalStateFrom"
|
||||
layout="horizontal"
|
||||
autocomplete="off"
|
||||
:validate-on-rule-change="false"
|
||||
:validateTrigger="[]"
|
||||
:label-col="{ span: 3 }"
|
||||
:wrapper-col="{ span: 12 }"
|
||||
:label-wrap="true"
|
||||
>
|
||||
<div>---- 授权申请</div>
|
||||
|
||||
<template v-if="licenseState.setp === 'license'">
|
||||
<a-form-item label="授权申请码" name="comment" :required="true">
|
||||
<a-input-group compact>
|
||||
<a-input
|
||||
v-model:value="licenseState.from.activationRequestCode"
|
||||
:disabled="true"
|
||||
style="width: calc(100% - 64px)"
|
||||
/>
|
||||
<a-tooltip title="复制">
|
||||
<a-button type="default" @click="fnCopyCode()">
|
||||
<template #icon><CopyOutlined /></template>
|
||||
</a-button>
|
||||
</a-tooltip>
|
||||
<a-tooltip title="下载">
|
||||
<a-button type="primary" @click="fnDownCode()">
|
||||
<template #icon><DownloadOutlined /></template>
|
||||
</a-button>
|
||||
</a-tooltip>
|
||||
</a-input-group>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="授权激活文件" name="file" :required="true">
|
||||
<a-upload
|
||||
name="file"
|
||||
v-model:file-list="licenseState.uploadFiles"
|
||||
accept=".ini"
|
||||
list-type="text"
|
||||
:max-count="1"
|
||||
:show-upload-list="{
|
||||
showPreviewIcon: false,
|
||||
showRemoveIcon: false,
|
||||
showDownloadIcon: false,
|
||||
}"
|
||||
:before-upload="fnBeforeUploadFile"
|
||||
:custom-request="fnUploadFile"
|
||||
:disabled="licenseState.confirmLoading"
|
||||
>
|
||||
<a-button type="default"> 上传文件 </a-button>
|
||||
</a-upload>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item name="check" :wrapper-col="{ span: 14, offset: 3 }">
|
||||
<div style="align-items: center">
|
||||
<a-button
|
||||
type="primary"
|
||||
shape="round"
|
||||
@click="fnRunCheck()"
|
||||
:loading="licenseState.confirmLoading"
|
||||
>
|
||||
<template #icon><LinkOutlined /></template>
|
||||
授权校验
|
||||
</a-button>
|
||||
</div>
|
||||
</a-form-item>
|
||||
</template>
|
||||
|
||||
<div>---- 校验信息</div>
|
||||
|
||||
<template v-if="licenseState.setp === 'verify'">
|
||||
<a-form-item
|
||||
name="info"
|
||||
label="巡检信息"
|
||||
:label-col="{ span: 3 }"
|
||||
:wrapper-col="{ span: 24 }"
|
||||
:label-wrap="true"
|
||||
>
|
||||
<a-result
|
||||
:status="verifyState.data ? 'success' : 'info'"
|
||||
:title="verifyState.data ? '成功激活' : '请等待网元验证结果'"
|
||||
>
|
||||
<template #extra>
|
||||
<a-button
|
||||
@click="fnVerifyTaskStop()"
|
||||
v-if="verifyState.data === null"
|
||||
>
|
||||
返回重新校验
|
||||
</a-button>
|
||||
</template>
|
||||
|
||||
<div class="verify-msg" v-if="verifyState.data === null">
|
||||
<p
|
||||
style="font-size: 16px"
|
||||
v-for="(s, i) in verifyState.msgArr"
|
||||
:key="i"
|
||||
>
|
||||
<close-circle-outlined :style="{ color: 'red' }" />
|
||||
{{ s }}
|
||||
</p>
|
||||
</div>
|
||||
<div v-else>
|
||||
<p style="font-size: 16px">序列号:{{ verifyState.data.sn }}</p>
|
||||
<p style="font-size: 16px">
|
||||
许可证到期时间:{{ verifyState.data.expire }}
|
||||
</p>
|
||||
</div>
|
||||
</a-result>
|
||||
</a-form-item>
|
||||
</template>
|
||||
</a-form>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.verify-msg {
|
||||
height: 200px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
</style>
|
||||
@@ -1,411 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { reactive, onMounted, toRaw } from 'vue';
|
||||
import { message, Form, Modal } from 'ant-design-vue/lib';
|
||||
import useI18n from '@/hooks/useI18n';
|
||||
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
||||
import { neHostAuthorizedRSA, neHostCheckInfo } from '@/api/ne/neHost';
|
||||
import useDictStore from '@/store/modules/dict';
|
||||
import { stepState } from '../hooks/useStep';
|
||||
const { getDict } = useDictStore();
|
||||
const { t } = useI18n();
|
||||
|
||||
/**字典数据 */
|
||||
let dict: {
|
||||
/**认证模式 */
|
||||
neHostAuthMode: DictType[];
|
||||
} = reactive({
|
||||
neHostAuthMode: [],
|
||||
});
|
||||
|
||||
/**检查对象信息状态类型 */
|
||||
type CheckStateType = {
|
||||
/**服务器信息 */
|
||||
info: Record<string, any>;
|
||||
/**表单数据 */
|
||||
from: Record<string, any>;
|
||||
/**确定按钮 loading */
|
||||
confirmLoading: boolean;
|
||||
};
|
||||
|
||||
/**检查对象信息状态 */
|
||||
let checkState: CheckStateType = reactive({
|
||||
info: {
|
||||
addr: '未连接',
|
||||
kernelName: '-',
|
||||
kernelRelease: '-',
|
||||
machine: '-',
|
||||
nodename: '-',
|
||||
prettyName: '-',
|
||||
sshLink: false,
|
||||
sudo: false,
|
||||
},
|
||||
from: {
|
||||
hostId: undefined,
|
||||
hostType: 'ssh',
|
||||
groupId: '1',
|
||||
title: 'SSH_NE_22',
|
||||
addr: '192.168.5.57',
|
||||
port: 22,
|
||||
user: 'agtuser',
|
||||
authMode: '0',
|
||||
password: 'QWERqwer',
|
||||
privateKey: '',
|
||||
passPhrase: '',
|
||||
remark: '',
|
||||
},
|
||||
confirmLoading: false,
|
||||
});
|
||||
|
||||
/**表单属性和校验规则 */
|
||||
const checkStateFrom = Form.useForm(
|
||||
checkState.from,
|
||||
reactive({
|
||||
addr: [
|
||||
{
|
||||
required: true,
|
||||
min: 1,
|
||||
max: 128,
|
||||
message: t('views.ne.neHost.addrPlease'),
|
||||
},
|
||||
],
|
||||
port: [
|
||||
{
|
||||
required: true,
|
||||
message: t('views.ne.neHost.portPlease'),
|
||||
},
|
||||
],
|
||||
user: [
|
||||
{
|
||||
required: true,
|
||||
min: 1,
|
||||
max: 50,
|
||||
message: t('views.ne.neHost.userPlease'),
|
||||
},
|
||||
],
|
||||
password: [
|
||||
{
|
||||
required: true,
|
||||
min: 1,
|
||||
max: 128,
|
||||
message: t('views.ne.neHost.passwordPlease'),
|
||||
},
|
||||
],
|
||||
privateKey: [
|
||||
{
|
||||
required: true,
|
||||
min: 1,
|
||||
max: 128,
|
||||
message: t('views.ne.neHost.privateKeyPlease'),
|
||||
},
|
||||
],
|
||||
})
|
||||
);
|
||||
|
||||
/**测试连接检查信息 */
|
||||
function fnCheckInfo() {
|
||||
if (checkState.confirmLoading) return;
|
||||
const form = toRaw(checkState.from);
|
||||
const validateArr = ['addr', 'port', 'user'];
|
||||
if (form.authMode === '0') {
|
||||
validateArr.push('password');
|
||||
}
|
||||
if (form.authMode === '1') {
|
||||
validateArr.push('privateKey');
|
||||
}
|
||||
|
||||
checkState.confirmLoading = true;
|
||||
const hide = message.loading(t('common.loading'), 0);
|
||||
checkStateFrom
|
||||
.validate(validateArr)
|
||||
.then(() => {
|
||||
Object.assign(checkState.info, {
|
||||
addr: '未连接',
|
||||
kernelName: '-',
|
||||
kernelRelease: '-',
|
||||
machine: '-',
|
||||
nodename: '-',
|
||||
prettyName: '-',
|
||||
sshLink: false,
|
||||
sudo: false,
|
||||
});
|
||||
stepState.stepNext = false;
|
||||
return neHostCheckInfo(form);
|
||||
})
|
||||
.then(res => {
|
||||
if (res.code === RESULT_CODE_SUCCESS) {
|
||||
checkState.info = res.data;
|
||||
if (!res.data.sudo) {
|
||||
message.warning({
|
||||
content: `请配置服务器授予当前用户无密码 sudo 权限,确保有权限进行软件包安装`,
|
||||
duration: 2,
|
||||
});
|
||||
return;
|
||||
}
|
||||
// if (!res.data.sshLink) {
|
||||
// message.warning({
|
||||
// content: `请配置服务器间免密信任关系,确保服务器间文件传输功能`,
|
||||
// duration: 2,
|
||||
// });
|
||||
// return;
|
||||
// }
|
||||
message.success({
|
||||
content: `${form.addr}:${form.port} ${t('views.ne.neHost.testOk')}`,
|
||||
duration: 2,
|
||||
});
|
||||
// 记录当前步骤状态信息
|
||||
stepState.states[stepState.current] = {
|
||||
info: checkState.info,
|
||||
from: checkState.from,
|
||||
};
|
||||
stepState.stepNext = true;
|
||||
} else {
|
||||
message.error({
|
||||
content: `${form.addr}:${form.port} ${res.msg}`,
|
||||
duration: 2,
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch(e => {
|
||||
message.error(t('common.errorFields', { num: e.errorFields.length }), 3);
|
||||
})
|
||||
.finally(() => {
|
||||
hide();
|
||||
checkState.confirmLoading = false;
|
||||
});
|
||||
}
|
||||
|
||||
/**测试连接检查信息表单重置 */
|
||||
function fnCheckInfoReset() {
|
||||
checkStateFrom.resetFields();
|
||||
}
|
||||
|
||||
/**SSH连接-免密直连 */
|
||||
function fnSSHLink() {
|
||||
if (checkState.info.sshLink) return;
|
||||
Modal.confirm({
|
||||
title: '提示',
|
||||
content: '是否要配置免密直连?',
|
||||
onOk: () => {
|
||||
const form = toRaw(checkState.from);
|
||||
neHostAuthorizedRSA(form).then(res => {
|
||||
if (res.code === RESULT_CODE_SUCCESS) {
|
||||
message.success({
|
||||
content: `操作成功`,
|
||||
duration: 2,
|
||||
});
|
||||
checkState.info.sshLink = true;
|
||||
} else {
|
||||
message.error({
|
||||
content: `操作失败`,
|
||||
duration: 2,
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
// 初始字典数据
|
||||
Promise.allSettled([getDict('ne_host_authMode')]).then(resArr => {
|
||||
if (resArr[0].status === 'fulfilled') {
|
||||
dict.neHostAuthMode = resArr[0].value;
|
||||
}
|
||||
});
|
||||
// 读取步骤:环境检查
|
||||
const stepPrevFrom = stepState.states[0];
|
||||
if (stepPrevFrom) {
|
||||
if (stepPrevFrom.info) {
|
||||
const info = toRaw(stepPrevFrom.info);
|
||||
Object.assign(checkState.info, info);
|
||||
}
|
||||
if (stepPrevFrom.from) {
|
||||
const from = toRaw(stepPrevFrom.from);
|
||||
Object.assign(checkState.from, from);
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a-descriptions :column="{ lg: 3, md: 2, sm: 2, xs: 1 }" bordered>
|
||||
<a-descriptions-item label="服务器IP" :span="3">
|
||||
{{ checkState.info.addr }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="系统">
|
||||
{{ checkState.info.kernelName }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="架构">
|
||||
{{ checkState.info.machine }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="内核">
|
||||
{{ checkState.info.kernelRelease }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item>
|
||||
<template #label>
|
||||
平台
|
||||
<a-tooltip placement="topLeft">
|
||||
<template #title> 支持 Ubuntu </template>
|
||||
<InfoCircleOutlined style="color: rgba(0, 0, 0, 0.45)" />
|
||||
</a-tooltip>
|
||||
</template>
|
||||
{{ checkState.info.prettyName }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="主机名">
|
||||
{{ checkState.info.nodename }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="授予权限">
|
||||
<a-tag :color="checkState.info.sudo ? 'success' : 'error'">
|
||||
<template #icon>
|
||||
<CheckCircleOutlined v-if="checkState.info.sudo" />
|
||||
<CloseCircleOutlined v-else />
|
||||
</template>
|
||||
可提权
|
||||
</a-tag>
|
||||
|
||||
<a-tag
|
||||
:color="checkState.info.sshLink ? 'success' : 'error'"
|
||||
style="cursor: pointer"
|
||||
@click="fnSSHLink()"
|
||||
>
|
||||
<template #icon>
|
||||
<CheckCircleOutlined v-if="checkState.info.sshLink" />
|
||||
<CloseCircleOutlined v-else />
|
||||
</template>
|
||||
可免密直连
|
||||
</a-tag>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="连接检查" :span="2">
|
||||
<a-form
|
||||
name="checkStateFrom"
|
||||
layout="horizontal"
|
||||
:label-col="{ span: 6 }"
|
||||
:label-wrap="true"
|
||||
>
|
||||
<a-row :gutter="16">
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item
|
||||
:label="t('views.ne.neHost.addr')"
|
||||
name="addr"
|
||||
v-bind="checkStateFrom.validateInfos.addr"
|
||||
>
|
||||
<a-input
|
||||
v-model:value="checkState.from.addr"
|
||||
allow-clear
|
||||
:maxlength="128"
|
||||
:placeholder="t('common.inputPlease')"
|
||||
>
|
||||
</a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item
|
||||
:label="t('views.ne.neHost.port')"
|
||||
name="port"
|
||||
v-bind="checkStateFrom.validateInfos.port"
|
||||
>
|
||||
<a-input-number
|
||||
v-model:value="checkState.from.port"
|
||||
:min="10"
|
||||
:max="65535"
|
||||
:step="1"
|
||||
style="width: 100%"
|
||||
></a-input-number>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-row :gutter="16">
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item
|
||||
:label="t('views.ne.neHost.user')"
|
||||
name="user"
|
||||
v-bind="checkStateFrom.validateInfos.user"
|
||||
>
|
||||
<a-input
|
||||
v-model:value="checkState.from.user"
|
||||
allow-clear
|
||||
:maxlength="50"
|
||||
:placeholder="t('common.inputPlease')"
|
||||
>
|
||||
</a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item :label="t('views.ne.neHost.authMode')">
|
||||
<a-select
|
||||
v-model:value="checkState.from.authMode"
|
||||
default-value="0"
|
||||
:options="dict.neHostAuthMode"
|
||||
>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-form-item
|
||||
v-if="checkState.from.authMode === '0'"
|
||||
:label="t('views.ne.neHost.password')"
|
||||
:label-col="{ span: 3 }"
|
||||
:label-wrap="true"
|
||||
name="password"
|
||||
v-bind="checkStateFrom.validateInfos.password"
|
||||
>
|
||||
<a-input-password
|
||||
v-model:value="checkState.from.password"
|
||||
:maxlength="128"
|
||||
:placeholder="t('common.inputPlease')"
|
||||
>
|
||||
</a-input-password>
|
||||
</a-form-item>
|
||||
|
||||
<template v-if="checkState.from.authMode === '1'">
|
||||
<a-form-item
|
||||
:label="t('views.ne.neHost.privateKey')"
|
||||
:label-col="{ span: 3 }"
|
||||
:label-wrap="true"
|
||||
name="privateKey"
|
||||
v-bind="checkStateFrom.validateInfos.privateKey"
|
||||
>
|
||||
<a-textarea
|
||||
v-model:value="checkState.from.privateKey"
|
||||
:auto-size="{ minRows: 4, maxRows: 6 }"
|
||||
:maxlength="3000"
|
||||
:show-count="true"
|
||||
:placeholder="t('views.ne.neHost.privateKeyPlease')"
|
||||
/>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item
|
||||
:label="t('views.ne.neHost.passPhrase')"
|
||||
:label-col="{ span: 3 }"
|
||||
:label-wrap="true"
|
||||
>
|
||||
<a-input-password
|
||||
v-model:value="checkState.from.passPhrase"
|
||||
:maxlength="128"
|
||||
:placeholder="t('common.inputPlease')"
|
||||
>
|
||||
</a-input-password>
|
||||
</a-form-item>
|
||||
</template>
|
||||
|
||||
<a-form-item :wrapper-col="{ span: 8, offset: 3 }">
|
||||
<a-button
|
||||
type="primary"
|
||||
html-type="submit"
|
||||
@click="fnCheckInfo()"
|
||||
:loading="checkState.confirmLoading"
|
||||
>
|
||||
进行连接
|
||||
</a-button>
|
||||
<a-button style="margin-left: 12px" @click="fnCheckInfoReset()">
|
||||
重置
|
||||
</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped></style>
|
||||
@@ -1,241 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { reactive, onMounted, onBeforeMount, toRaw } from 'vue';
|
||||
import { message } from 'ant-design-vue/lib';
|
||||
import {
|
||||
RESULT_CODE_ERROR,
|
||||
RESULT_CODE_SUCCESS,
|
||||
} from '@/constants/result-constants';
|
||||
import { stepState } from '../hooks/useStep';
|
||||
import { getConfigFile, saveConfigFile } from '@/api/ne/neInfo';
|
||||
import useI18n from '@/hooks/useI18n';
|
||||
const { t } = useI18n();
|
||||
|
||||
/**配置对象信息状态类型 */
|
||||
type ConfigState = {
|
||||
neType: string;
|
||||
neId: string;
|
||||
/**文件列表 */
|
||||
fileList: string[];
|
||||
/**OAM网管端配置 */
|
||||
oam: Record<string, any>;
|
||||
oamFilePath: string;
|
||||
/**确定按钮 loading */
|
||||
confirmLoading: boolean;
|
||||
};
|
||||
|
||||
/**配置对象信息状态 */
|
||||
let configState: ConfigState = reactive({
|
||||
neType: '',
|
||||
neId: '',
|
||||
fileList: [],
|
||||
oam: {
|
||||
httpManageCfg: {
|
||||
ipv4: '172.16.5.100',
|
||||
port: 33030,
|
||||
},
|
||||
oamConfig: {
|
||||
enable: true,
|
||||
neConfig: {
|
||||
dn: '-',
|
||||
neId: '001',
|
||||
neName: 'xxx_001',
|
||||
pvFlag: 'PNF',
|
||||
province: '-',
|
||||
rmUid: '4400HX1xxx001',
|
||||
vendorName: '',
|
||||
},
|
||||
ipv4: '172.16.5.100',
|
||||
port: 33030,
|
||||
},
|
||||
snmpConfig: {
|
||||
enable: false,
|
||||
},
|
||||
},
|
||||
oamFilePath: '',
|
||||
confirmLoading: false,
|
||||
});
|
||||
|
||||
/**查询配置文件或内容 */
|
||||
function fnGetConfigFile(filePath: string = '') {
|
||||
if (filePath === '' && configState.confirmLoading) return;
|
||||
configState.confirmLoading = true;
|
||||
getConfigFile({
|
||||
neType: configState.neType,
|
||||
neId: configState.neId,
|
||||
filePath: filePath,
|
||||
fileType: 'yaml',
|
||||
})
|
||||
.then(res => {
|
||||
// 目录列表
|
||||
if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.data)) {
|
||||
configState.fileList = res.data;
|
||||
// 网管配置
|
||||
if (res.data.includes('oam_manager.yaml')) {
|
||||
configState.oamFilePath = 'oam_manager.yaml';
|
||||
fnGetConfigFile(configState.oamFilePath);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// 单文件内容 yaml
|
||||
if (res.code === RESULT_CODE_SUCCESS && typeof res.data === 'object') {
|
||||
if (filePath.startsWith('oam_manager')) {
|
||||
configState.oam = res.data;
|
||||
// 读取第二步的网元信息
|
||||
const stepNeInfo = stepState.states[1].from;
|
||||
configState.oam.snmpConfig.enable = false;
|
||||
configState.oam.oamConfig.enable = true;
|
||||
configState.oam.oamConfig.neConfig = {
|
||||
dn: stepNeInfo.db,
|
||||
neId: stepNeInfo.neId,
|
||||
neName: stepNeInfo.neName,
|
||||
pvFlag: stepNeInfo.pvFlag,
|
||||
province: stepNeInfo.province,
|
||||
rmUid: stepNeInfo.rmUid,
|
||||
vendorName: stepNeInfo.vendorName,
|
||||
};
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// 出错
|
||||
if (res.code === RESULT_CODE_ERROR) {
|
||||
message.error({
|
||||
content: res.msg,
|
||||
duration: 3,
|
||||
});
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
configState.confirmLoading = false;
|
||||
});
|
||||
}
|
||||
|
||||
/**保存配置文件 */
|
||||
function fnSaveConfigFile() {
|
||||
if (configState.confirmLoading) return;
|
||||
configState.confirmLoading = true;
|
||||
const hide = message.loading(t('common.loading'), 0);
|
||||
const data = {
|
||||
neType: configState.neType,
|
||||
neId: configState.neId,
|
||||
fileType: 'yaml',
|
||||
filePath: '',
|
||||
content: '',
|
||||
sync: true, // 同步到网元
|
||||
};
|
||||
|
||||
// 配置信息
|
||||
const oamData = toRaw(configState.oam);
|
||||
saveConfigFile(
|
||||
Object.assign(data, {
|
||||
filePath: configState.oamFilePath,
|
||||
content: oamData,
|
||||
})
|
||||
)
|
||||
.then(res => {
|
||||
if (res.code === RESULT_CODE_SUCCESS) {
|
||||
message.success({
|
||||
content: '保存成功',
|
||||
duration: 3,
|
||||
});
|
||||
// 记录当前步骤状态信息
|
||||
stepState.states[stepState.current] = {
|
||||
oam: oamData,
|
||||
};
|
||||
stepState.stepNext = true;
|
||||
} else {
|
||||
message.error({
|
||||
content: '保存失败',
|
||||
duration: 3,
|
||||
});
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
hide();
|
||||
configState.confirmLoading = false;
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
// 读取第二步的网元信息
|
||||
const stepNeInfo = stepState.states[1].from;
|
||||
configState.neType = stepNeInfo.neType;
|
||||
configState.neId = stepNeInfo.neId;
|
||||
// 读取文件列表
|
||||
fnGetConfigFile();
|
||||
});
|
||||
|
||||
onBeforeMount(() => {});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a-form
|
||||
name="modalStateFrom"
|
||||
layout="horizontal"
|
||||
:label-col="{ span: 6 }"
|
||||
:labelWrap="true"
|
||||
>
|
||||
<div>网管端配置</div>
|
||||
{{ configState.oam }}
|
||||
<a-row :gutter="16">
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item label="httpManageCfg.ipv4" name="ipv4">
|
||||
<a-input
|
||||
v-model:value="configState.oam.httpManageCfg.ipv4"
|
||||
allow-clear
|
||||
:placeholder="t('common.inputPlease')"
|
||||
:maxlength="32"
|
||||
></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item label="httpManageCfg.port" name="port">
|
||||
<a-input
|
||||
v-model:value="configState.oam.httpManageCfg.port"
|
||||
allow-clear
|
||||
:placeholder="t('common.inputPlease')"
|
||||
:maxlength="32"
|
||||
></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row :gutter="16">
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item label="oamconfig.ipv4" name="ipv4">
|
||||
<a-input
|
||||
v-model:value="configState.oam.oamConfig.ipv4"
|
||||
allow-clear
|
||||
:placeholder="t('common.inputPlease')"
|
||||
:maxlength="32"
|
||||
></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item label="oamconfig.port" name="port">
|
||||
<a-input
|
||||
v-model:value="configState.oam.oamConfig.port"
|
||||
allow-clear
|
||||
:placeholder="t('common.inputPlease')"
|
||||
:maxlength="32"
|
||||
></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-form-item :wrapper-col="{ span: 14, offset: 3 }">
|
||||
<a-button
|
||||
type="primary"
|
||||
html-type="submit"
|
||||
@click="fnSaveConfigFile()"
|
||||
:loading="configState.confirmLoading"
|
||||
>
|
||||
保存配置
|
||||
</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped></style>
|
||||
@@ -1,242 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { reactive, onMounted, onBeforeMount, toRaw } from 'vue';
|
||||
import { message } from 'ant-design-vue/lib';
|
||||
import {
|
||||
RESULT_CODE_ERROR,
|
||||
RESULT_CODE_SUCCESS,
|
||||
} from '@/constants/result-constants';
|
||||
import { stepState } from '../hooks/useStep';
|
||||
import { getConfigFile, saveConfigFile } from '@/api/ne/neInfo';
|
||||
import useI18n from '@/hooks/useI18n';
|
||||
const { t } = useI18n();
|
||||
|
||||
/**配置对象信息状态类型 */
|
||||
type ConfigState = {
|
||||
neType: string;
|
||||
neId: string;
|
||||
/**文件列表 */
|
||||
fileList: string[];
|
||||
/**OAM网管端配置 */
|
||||
oam: Record<string, any>;
|
||||
oamFilePath: string;
|
||||
/**确定按钮 loading */
|
||||
confirmLoading: boolean;
|
||||
};
|
||||
|
||||
/**配置对象信息状态 */
|
||||
let configState: ConfigState = reactive({
|
||||
neType: '',
|
||||
neId: '',
|
||||
fileList: [],
|
||||
oam: {
|
||||
httpmanagecfg: {
|
||||
ipv4: '172.16.5.110',
|
||||
port: 33030,
|
||||
},
|
||||
oamconfig: {
|
||||
enable: true,
|
||||
neconfig: {
|
||||
dn: '-',
|
||||
neId: '001',
|
||||
neName: 'IMS_001',
|
||||
pVFlag: 'PNF',
|
||||
province: '-',
|
||||
rmUID: '4400HX1IMS001',
|
||||
vendorName: '',
|
||||
},
|
||||
ipv4: '172.16.5.100',
|
||||
port: 33030,
|
||||
},
|
||||
snmpconfig: {
|
||||
enable: false,
|
||||
},
|
||||
},
|
||||
oamFilePath: '',
|
||||
cfg: {},
|
||||
cfgFilePath: '',
|
||||
confirmLoading: false,
|
||||
});
|
||||
|
||||
/**查询配置文件或内容 */
|
||||
function fnGetConfigFile(filePath: string = '') {
|
||||
if (filePath === '' && configState.confirmLoading) return;
|
||||
configState.confirmLoading = true;
|
||||
getConfigFile({
|
||||
neType: configState.neType,
|
||||
neId: configState.neId,
|
||||
filePath: filePath,
|
||||
fileType: 'yaml',
|
||||
})
|
||||
.then(res => {
|
||||
// 目录列表
|
||||
if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.data)) {
|
||||
configState.fileList = res.data;
|
||||
// 网管配置
|
||||
if (res.data.includes('oam_manager.yaml')) {
|
||||
configState.oamFilePath = 'oam_manager.yaml';
|
||||
fnGetConfigFile(configState.oamFilePath);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// 单文件内容 yaml
|
||||
if (res.code === RESULT_CODE_SUCCESS && typeof res.data === 'object') {
|
||||
if (filePath.startsWith('oam_manager')) {
|
||||
configState.oam = res.data;
|
||||
// 读取第二步的网元信息
|
||||
const stepNeInfo = stepState.states[1].from;
|
||||
configState.oam.snmpconfig.enable = false;
|
||||
configState.oam.oamconfig.enable = true;
|
||||
configState.oam.oamconfig.neconfig = {
|
||||
dn: stepNeInfo.db,
|
||||
neId: stepNeInfo.neId,
|
||||
neName: stepNeInfo.neName,
|
||||
pVFlag: stepNeInfo.pvFlag,
|
||||
province: stepNeInfo.province,
|
||||
rmUID: stepNeInfo.rmUid,
|
||||
vendorName: stepNeInfo.vendorName,
|
||||
};
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// 出错
|
||||
if (res.code === RESULT_CODE_ERROR) {
|
||||
message.error({
|
||||
content: res.msg,
|
||||
duration: 3,
|
||||
});
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
configState.confirmLoading = false;
|
||||
});
|
||||
}
|
||||
|
||||
/**保存配置文件 */
|
||||
function fnSaveConfigFile() {
|
||||
if (configState.confirmLoading) return;
|
||||
configState.confirmLoading = true;
|
||||
const hide = message.loading(t('common.loading'), 0);
|
||||
const data = {
|
||||
neType: configState.neType,
|
||||
neId: configState.neId,
|
||||
fileType: 'yaml',
|
||||
filePath: '',
|
||||
content: '',
|
||||
sync: true, // 同步到网元
|
||||
};
|
||||
|
||||
// 配置信息
|
||||
const oamData = toRaw(configState.oam);
|
||||
saveConfigFile(
|
||||
Object.assign(data, {
|
||||
filePath: configState.oamFilePath,
|
||||
content: oamData,
|
||||
})
|
||||
)
|
||||
.then(res => {
|
||||
if (res.code === RESULT_CODE_SUCCESS) {
|
||||
message.success({
|
||||
content: '保存成功',
|
||||
duration: 3,
|
||||
});
|
||||
// 记录当前步骤状态信息
|
||||
stepState.states[stepState.current] = {
|
||||
oam: oamData,
|
||||
};
|
||||
stepState.stepNext = true;
|
||||
} else {
|
||||
message.error({
|
||||
content: '保存失败',
|
||||
duration: 3,
|
||||
});
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
hide();
|
||||
configState.confirmLoading = false;
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
// 读取第二步的网元信息
|
||||
const stepNeInfo = stepState.states[1].from;
|
||||
configState.neType = stepNeInfo.neType;
|
||||
configState.neId = stepNeInfo.neId;
|
||||
// 读取文件列表
|
||||
fnGetConfigFile();
|
||||
});
|
||||
|
||||
onBeforeMount(() => {});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a-form
|
||||
name="modalStateFrom"
|
||||
layout="horizontal"
|
||||
:label-col="{ span: 6 }"
|
||||
:labelWrap="true"
|
||||
>
|
||||
<div>网管端配置</div>
|
||||
<a-row :gutter="16">
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item label="httpmanagecfg.ipv4" name="ipv4">
|
||||
<a-input
|
||||
v-model:value="configState.oam.httpmanagecfg.ipv4"
|
||||
allow-clear
|
||||
:placeholder="t('common.inputPlease')"
|
||||
:maxlength="32"
|
||||
></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item label="httpmanagecfg.port" name="port">
|
||||
<a-input
|
||||
v-model:value="configState.oam.httpmanagecfg.port"
|
||||
allow-clear
|
||||
:placeholder="t('common.inputPlease')"
|
||||
:maxlength="32"
|
||||
></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row :gutter="16">
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item label="oamconfig.ipv4" name="ipv4">
|
||||
<a-input
|
||||
v-model:value="configState.oam.oamconfig.ipv4"
|
||||
allow-clear
|
||||
:placeholder="t('common.inputPlease')"
|
||||
:maxlength="32"
|
||||
></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item label="oamconfig.port" name="port">
|
||||
<a-input
|
||||
v-model:value="configState.oam.oamconfig.port"
|
||||
allow-clear
|
||||
:placeholder="t('common.inputPlease')"
|
||||
:maxlength="32"
|
||||
></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-form-item :wrapper-col="{ span: 14, offset: 3 }">
|
||||
<a-button
|
||||
type="primary"
|
||||
html-type="submit"
|
||||
@click="fnSaveConfigFile()"
|
||||
:loading="configState.confirmLoading"
|
||||
>
|
||||
保存配置
|
||||
</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped></style>
|
||||
@@ -1,310 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { reactive, onMounted, onBeforeMount, toRaw } from 'vue';
|
||||
import { message } from 'ant-design-vue/lib';
|
||||
import {
|
||||
RESULT_CODE_ERROR,
|
||||
RESULT_CODE_SUCCESS,
|
||||
} from '@/constants/result-constants';
|
||||
import { stepState } from '../hooks/useStep';
|
||||
import { getConfigFile, saveConfigFile } from '@/api/ne/neInfo';
|
||||
import useI18n from '@/hooks/useI18n';
|
||||
const { t } = useI18n();
|
||||
|
||||
/**配置对象信息状态类型 */
|
||||
type ConfigState = {
|
||||
neType: string;
|
||||
neId: string;
|
||||
/**文件列表 */
|
||||
fileList: string[];
|
||||
/**OAM网管端配置 */
|
||||
oam: Record<string, any>;
|
||||
oamFilePath: string;
|
||||
/**网元主要配置 */
|
||||
cfg: Record<string, any>;
|
||||
cfgFilePath: string;
|
||||
/**确定按钮 loading */
|
||||
confirmLoading: boolean;
|
||||
};
|
||||
|
||||
/**配置对象信息状态 */
|
||||
let configState: ConfigState = reactive({
|
||||
neType: '',
|
||||
neId: '',
|
||||
fileList: [],
|
||||
oam: {
|
||||
httpmanagecfg: {
|
||||
ipv4: '172.16.5.150',
|
||||
port: 33030,
|
||||
},
|
||||
oamconfig: {
|
||||
enable: true,
|
||||
neconfig: {
|
||||
dn: '-',
|
||||
neId: '001',
|
||||
neName: 'SMF_001',
|
||||
pVFlag: 'PNF',
|
||||
province: '-',
|
||||
rmUID: '4400HX1SMF001',
|
||||
vendorName: '',
|
||||
},
|
||||
ipv4: '172.16.5.100',
|
||||
port: 33030,
|
||||
},
|
||||
snmpconfig: {
|
||||
enable: false,
|
||||
},
|
||||
},
|
||||
oamFilePath: '',
|
||||
cfg: {
|
||||
localconfig: {
|
||||
n4interfacecfg: {
|
||||
ipv4: '172.16.5.150',
|
||||
port: 8805,
|
||||
},
|
||||
telnetip: '172.16.5.150',
|
||||
},
|
||||
},
|
||||
cfgFilePath: '',
|
||||
confirmLoading: false,
|
||||
});
|
||||
|
||||
/**查询配置文件或内容 */
|
||||
function fnGetConfigFile(filePath: string = '') {
|
||||
if (filePath === '' && configState.confirmLoading) return;
|
||||
configState.confirmLoading = true;
|
||||
getConfigFile({
|
||||
neType: configState.neType,
|
||||
neId: configState.neId,
|
||||
filePath: filePath,
|
||||
fileType: 'yaml',
|
||||
})
|
||||
.then(res => {
|
||||
// 目录列表
|
||||
if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.data)) {
|
||||
configState.fileList = res.data;
|
||||
// 网管配置
|
||||
if (res.data.includes('oam_manager.yaml')) {
|
||||
configState.oamFilePath = 'oam_manager.yaml';
|
||||
fnGetConfigFile(configState.oamFilePath);
|
||||
}
|
||||
// 网元配置
|
||||
if (res.data.includes('smf_conf.yaml')) {
|
||||
configState.cfgFilePath = 'smf_conf.yaml';
|
||||
fnGetConfigFile(configState.cfgFilePath);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 单文件内容 yaml
|
||||
if (res.code === RESULT_CODE_SUCCESS && typeof res.data === 'object') {
|
||||
if (filePath.startsWith('oam_manager')) {
|
||||
configState.oam = res.data;
|
||||
// 读取第二步的网元信息
|
||||
const stepNeInfo = stepState.states[1].from;
|
||||
configState.oam.snmpconfig.enable = false;
|
||||
configState.oam.oamconfig.enable = true;
|
||||
configState.oam.oamconfig.neconfig = {
|
||||
dn: stepNeInfo.db,
|
||||
neId: stepNeInfo.neId,
|
||||
neName: stepNeInfo.neName,
|
||||
pVFlag: stepNeInfo.pvFlag,
|
||||
province: stepNeInfo.province,
|
||||
rmUID: stepNeInfo.rmUid,
|
||||
vendorName: stepNeInfo.vendorName,
|
||||
};
|
||||
}
|
||||
|
||||
if (filePath.startsWith('smf_conf')) {
|
||||
configState.cfg = res.data;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 出错
|
||||
if (res.code === RESULT_CODE_ERROR) {
|
||||
message.error({
|
||||
content: res.msg,
|
||||
duration: 3,
|
||||
});
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
configState.confirmLoading = false;
|
||||
});
|
||||
}
|
||||
|
||||
/**保存配置文件 */
|
||||
function fnSaveConfigFile() {
|
||||
if (configState.confirmLoading) return;
|
||||
configState.confirmLoading = true;
|
||||
const hide = message.loading(t('common.loading'), 0);
|
||||
const data = {
|
||||
neType: configState.neType,
|
||||
neId: configState.neId,
|
||||
fileType: 'yaml',
|
||||
filePath: '',
|
||||
content: '',
|
||||
sync: true, // 同步到网元
|
||||
};
|
||||
|
||||
// 配置信息
|
||||
const oamData = toRaw(configState.oam);
|
||||
const cfgData = toRaw(configState.cfg);
|
||||
Promise.all([
|
||||
saveConfigFile(
|
||||
Object.assign(data, {
|
||||
filePath: configState.oamFilePath,
|
||||
content: oamData,
|
||||
})
|
||||
),
|
||||
saveConfigFile(
|
||||
Object.assign(data, {
|
||||
filePath: configState.cfgFilePath,
|
||||
content: cfgData,
|
||||
})
|
||||
),
|
||||
])
|
||||
.then(resArr => {
|
||||
if (
|
||||
resArr[0].code === RESULT_CODE_SUCCESS &&
|
||||
resArr[1].code === RESULT_CODE_SUCCESS
|
||||
) {
|
||||
message.success({
|
||||
content: '保存成功',
|
||||
duration: 3,
|
||||
});
|
||||
// 记录当前步骤状态信息
|
||||
stepState.states[stepState.current] = {
|
||||
oam: oamData,
|
||||
cfg: cfgData,
|
||||
};
|
||||
stepState.stepNext = true;
|
||||
} else {
|
||||
message.error({
|
||||
content: '保存失败',
|
||||
duration: 3,
|
||||
});
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
hide();
|
||||
configState.confirmLoading = false;
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
// 读取第二步的网元信息
|
||||
const stepNeInfo = stepState.states[1].from;
|
||||
configState.neType = stepNeInfo.neType;
|
||||
configState.neId = stepNeInfo.neId;
|
||||
// 读取文件列表
|
||||
fnGetConfigFile();
|
||||
});
|
||||
|
||||
onBeforeMount(() => {});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a-form
|
||||
name="modalStateFrom"
|
||||
layout="horizontal"
|
||||
:label-col="{ span: 6 }"
|
||||
:labelWrap="true"
|
||||
>
|
||||
<div>网管端配置</div>
|
||||
<a-row :gutter="16">
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item label="httpmanagecfg.ipv4" name="ipv4">
|
||||
<a-input
|
||||
v-model:value="configState.oam.httpmanagecfg.ipv4"
|
||||
allow-clear
|
||||
:placeholder="t('common.inputPlease')"
|
||||
:maxlength="32"
|
||||
></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item label="httpmanagecfg.port" name="port">
|
||||
<a-input
|
||||
v-model:value="configState.oam.httpmanagecfg.port"
|
||||
allow-clear
|
||||
:placeholder="t('common.inputPlease')"
|
||||
:maxlength="32"
|
||||
></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row :gutter="16">
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item label="oamconfig.ipv4" name="ipv4">
|
||||
<a-input
|
||||
v-model:value="configState.oam.oamconfig.ipv4"
|
||||
allow-clear
|
||||
:placeholder="t('common.inputPlease')"
|
||||
:maxlength="32"
|
||||
></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item label="oamconfig.port" name="port">
|
||||
<a-input
|
||||
v-model:value="configState.oam.oamconfig.port"
|
||||
allow-clear
|
||||
:placeholder="t('common.inputPlease')"
|
||||
:maxlength="32"
|
||||
></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<div>网元端配置</div>
|
||||
<a-row :gutter="16">
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item label="localconfig.n4interfacecfg.ipv4" name="ipv4">
|
||||
<a-input
|
||||
v-model:value="configState.cfg.localconfig.n4interfacecfg.ipv4"
|
||||
allow-clear
|
||||
:placeholder="t('common.inputPlease')"
|
||||
:maxlength="32"
|
||||
></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item label="localconfig.n4interfacecfg.port" name="port">
|
||||
<a-input
|
||||
v-model:value="configState.cfg.localconfig.n4interfacecfg.port"
|
||||
allow-clear
|
||||
:placeholder="t('common.inputPlease')"
|
||||
:maxlength="32"
|
||||
></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row :gutter="16">
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item label="localconfig.telnetip" name="telnetip">
|
||||
<a-input
|
||||
v-model:value="configState.cfg.localconfig.telnetip"
|
||||
allow-clear
|
||||
:placeholder="t('common.inputPlease')"
|
||||
:maxlength="32"
|
||||
></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="12" :md="12" :xs="24"> </a-col>
|
||||
</a-row>
|
||||
|
||||
<a-form-item :wrapper-col="{ span: 14, offset: 3 }">
|
||||
<a-button
|
||||
type="primary"
|
||||
html-type="submit"
|
||||
@click="fnSaveConfigFile()"
|
||||
:loading="configState.confirmLoading"
|
||||
>
|
||||
保存配置
|
||||
</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped></style>
|
||||
@@ -1,232 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { reactive, onMounted, onBeforeMount } from 'vue';
|
||||
import { message } from 'ant-design-vue/lib';
|
||||
import {
|
||||
RESULT_CODE_ERROR,
|
||||
RESULT_CODE_SUCCESS,
|
||||
} from '@/constants/result-constants';
|
||||
import { stepState } from '../hooks/useStep';
|
||||
import { getConfigFile, saveConfigFile } from '@/api/ne/neInfo';
|
||||
import { parseDateToStr } from '@/utils/date-utils';
|
||||
|
||||
/**配置对象信息状态类型 */
|
||||
type ConfigState = {
|
||||
/**展开指定的树节点 */
|
||||
expandedKeys: string[];
|
||||
/**设置选中的树节点 */
|
||||
selectedKeys: string[];
|
||||
/**表单数据 */
|
||||
treeData: any[];
|
||||
/**等待 loading */
|
||||
treeLoading: boolean;
|
||||
/**选中的树节点 */
|
||||
selected: { title: string; key: string };
|
||||
/**设置选中的数据内容 */
|
||||
keyTextData: string;
|
||||
/**设置选中等待 loading */
|
||||
keyTextLoading: boolean;
|
||||
};
|
||||
|
||||
/**配置对象信息状态 */
|
||||
let configState: ConfigState = reactive({
|
||||
expandedKeys: ['000'],
|
||||
selectedKeys: ['oam_manager.yaml'],
|
||||
treeData: [
|
||||
{
|
||||
title: 'NE',
|
||||
key: '000',
|
||||
children: [
|
||||
{
|
||||
title: 'oam_manager',
|
||||
key: 'oam_manager.yaml',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
treeLoading: false,
|
||||
selected: { title: 'oam_manager', key: 'oam_manager.yaml' },
|
||||
keyTextData: '...',
|
||||
keyTextLoading: false,
|
||||
});
|
||||
|
||||
/**查询可选命令列表 */
|
||||
function fnSelectConfigNode(_: any, info: any) {
|
||||
const { title, key } = info.node;
|
||||
configState.selectedKeys = [key];
|
||||
configState.selected = { title, key };
|
||||
fnGetConfigFile(key);
|
||||
}
|
||||
|
||||
/**查询配置列表 */
|
||||
function fnGetConfigFile(filePath: string = '') {
|
||||
if (filePath) {
|
||||
if (configState.keyTextLoading) return;
|
||||
configState.keyTextLoading = true;
|
||||
} else {
|
||||
if (configState.treeLoading) return;
|
||||
configState.treeLoading = true;
|
||||
}
|
||||
|
||||
// 读取第二步的网元信息
|
||||
const stepNeInfo = stepState.states[1].from;
|
||||
getConfigFile({
|
||||
neType: stepNeInfo.neType,
|
||||
neId: stepNeInfo.neId,
|
||||
filePath: filePath,
|
||||
fileType: 'txt',
|
||||
})
|
||||
.then(res => {
|
||||
// 目录列表
|
||||
if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.data)) {
|
||||
const treeItem = {
|
||||
title: stepNeInfo.neType,
|
||||
key: stepNeInfo.neId,
|
||||
children: [] as any,
|
||||
};
|
||||
treeItem.children = res.data.map((fileName: string) => {
|
||||
return {
|
||||
title: fileName.replace(/\.[^.]+$/, ''),
|
||||
key: fileName,
|
||||
};
|
||||
});
|
||||
configState.treeData = [treeItem];
|
||||
configState.expandedKeys = [stepNeInfo.neId];
|
||||
// 选中加载显示内容
|
||||
if (treeItem.children.length > 0) {
|
||||
const fileItem = treeItem.children[0];
|
||||
configState.selectedKeys = [fileItem.key];
|
||||
configState.selected = fileItem;
|
||||
fnGetConfigFile(fileItem.key);
|
||||
}
|
||||
}
|
||||
|
||||
// 单文件内容
|
||||
if (res.code === RESULT_CODE_SUCCESS && typeof res.data === 'string') {
|
||||
configState.keyTextData = res.data;
|
||||
}
|
||||
|
||||
// 出错
|
||||
if (res.code === RESULT_CODE_ERROR) {
|
||||
message.error({
|
||||
content: res.msg,
|
||||
duration: 3,
|
||||
});
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
if (filePath) {
|
||||
configState.keyTextLoading = false;
|
||||
} else {
|
||||
configState.treeLoading = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**保存配置文件 */
|
||||
function fnSaveConfigFile() {
|
||||
if (configState.keyTextLoading) return;
|
||||
// 读取第二步的网元信息
|
||||
const stepNeInfo = stepState.states[1].from;
|
||||
saveConfigFile({
|
||||
neType: stepNeInfo.neType,
|
||||
neId: stepNeInfo.neId,
|
||||
filePath: configState.selected.key,
|
||||
content: configState.keyTextData,
|
||||
sync: true, // 同步到网元
|
||||
})
|
||||
.then(res => {
|
||||
if (res.code === RESULT_CODE_SUCCESS) {
|
||||
saveState.saveTime = parseDateToStr(new Date(), 'HH:mm:ss');
|
||||
// 记录当前步骤状态信息
|
||||
stepState.states[stepState.current] = {
|
||||
treeData: configState.treeData,
|
||||
};
|
||||
stepState.stepNext = true;
|
||||
} else {
|
||||
message.error({
|
||||
content: res.msg,
|
||||
duration: 3,
|
||||
});
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
saveState.timer = null;
|
||||
});
|
||||
}
|
||||
|
||||
/**保存文件数据状态 */
|
||||
const saveState = reactive({
|
||||
timer: null as any,
|
||||
saveTime: '',
|
||||
});
|
||||
|
||||
/**文件数据变更 */
|
||||
function fnChangekeyTextData(val: string) {
|
||||
console.log(val);
|
||||
// 在用户停止输入3秒后,执行保存请求的操作
|
||||
if (saveState.timer) {
|
||||
clearTimeout(saveState.timer);
|
||||
}
|
||||
stepState.stepNext = false;
|
||||
saveState.timer = setTimeout(fnSaveConfigFile, 3_000);
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
fnGetConfigFile();
|
||||
});
|
||||
|
||||
onBeforeMount(() => {
|
||||
clearTimeout(saveState.timer);
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a-row :gutter="8">
|
||||
<a-col :lg="6" :md="6" :xs="24">
|
||||
<a-spin :spinning="configState.treeLoading">
|
||||
<a-directory-tree
|
||||
v-model:expandedKeys="configState.expandedKeys"
|
||||
v-model:selectedKeys="configState.selectedKeys"
|
||||
@select="fnSelectConfigNode"
|
||||
:tree-data="configState.treeData"
|
||||
></a-directory-tree>
|
||||
</a-spin>
|
||||
</a-col>
|
||||
<a-col :lg="18" :md="18" :xs="24">
|
||||
<a-spin :spinning="configState.treeLoading || configState.keyTextLoading">
|
||||
<CodemirrorEdite
|
||||
v-model:value="configState.keyTextData"
|
||||
:disabled="configState.keyTextLoading"
|
||||
lang="yaml"
|
||||
height="500px"
|
||||
@change="fnChangekeyTextData"
|
||||
></CodemirrorEdite>
|
||||
<div
|
||||
class="edite-tip"
|
||||
:class="{ 'edite-tip__ing': saveState.timer > 0 }"
|
||||
>
|
||||
{{ configState.selected.title }}
|
||||
<template v-if="saveState.saveTime.length > 1">
|
||||
| 最近保存: {{ saveState.saveTime }}
|
||||
</template>
|
||||
</div>
|
||||
</a-spin>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.edite-tip {
|
||||
min-height: 24px;
|
||||
padding: 0 4px;
|
||||
color: #fff;
|
||||
line-height: 24px;
|
||||
background: var(--ant-primary-color);
|
||||
border-radius: 2px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s, border 0s, line-height 0s, box-shadow 0s;
|
||||
&__ing {
|
||||
background: var(--ant-primary-color-disabled);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,182 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { reactive, onMounted } from 'vue';
|
||||
import useI18n from '@/hooks/useI18n';
|
||||
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
||||
import { stateNeInfo } from '@/api/ne/neInfo';
|
||||
import { stepState } from '../hooks/useStep';
|
||||
const { t } = useI18n();
|
||||
|
||||
/**状态数据 */
|
||||
const state = reactive({
|
||||
data: {} as Record<string, any>,
|
||||
resoures: {} as Record<string, any>,
|
||||
});
|
||||
|
||||
function getNeState() {
|
||||
// 读取第二步的网元信息
|
||||
const stepNeInfo = stepState.states[1].from;
|
||||
stateNeInfo(stepNeInfo.neType, stepNeInfo.neId).then(res => {
|
||||
// 单文件内容
|
||||
if (res.code === RESULT_CODE_SUCCESS) {
|
||||
state.data = res.data;
|
||||
|
||||
let sysCpuUsage = 0;
|
||||
let nfCpuUsage = 0;
|
||||
if (res.data.cpu) {
|
||||
nfCpuUsage = res.data.cpu.nfCpuUsage;
|
||||
if (nfCpuUsage > 100) {
|
||||
const nfCpu = +(res.data.cpu.nfCpuUsage / 100);
|
||||
if (nfCpu > 100) {
|
||||
nfCpuUsage = 100;
|
||||
} else {
|
||||
nfCpuUsage = +nfCpu.toFixed(2);
|
||||
}
|
||||
}
|
||||
|
||||
sysCpuUsage = res.data.cpu.sysCpuUsage;
|
||||
if (sysCpuUsage > 100) {
|
||||
const sysCpu = +(res.data.cpu.sysCpuUsage / 100);
|
||||
if (sysCpu > 100) {
|
||||
sysCpuUsage = 100;
|
||||
} else {
|
||||
sysCpuUsage = +sysCpu.toFixed(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let sysMemUsage = 0;
|
||||
if (res.data.mem) {
|
||||
let men = res.data.mem.sysMemUsage;
|
||||
if (men > 100) {
|
||||
men = +(men / 100).toFixed(2);
|
||||
}
|
||||
sysMemUsage = men;
|
||||
}
|
||||
|
||||
let sysDiskUsage = 0;
|
||||
if (res.data.disk && Array.isArray(res.data.disk.partitionInfo)) {
|
||||
let disks: any[] = res.data.disk.partitionInfo;
|
||||
disks = disks.sort((a, b) => +b.used - +a.used);
|
||||
if (disks.length > 0) {
|
||||
const { total, used } = disks[0];
|
||||
sysDiskUsage = +((used / total) * 100).toFixed(2);
|
||||
}
|
||||
}
|
||||
|
||||
Reflect.set(state, 'resoures', {
|
||||
sysDiskUsage,
|
||||
sysMemUsage,
|
||||
sysCpuUsage,
|
||||
nfCpuUsage,
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getNeState();
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div style="width: 46%; padding-left: 32px; padding-bottom: 16px">
|
||||
<a-divider orientation="left">
|
||||
{{ t('views.ne.neInfo.info') }}
|
||||
</a-divider>
|
||||
<div>
|
||||
<span>{{ t('views.ne.neInfo.serviceState') }}:</span>
|
||||
<a-tag :color="state.data.online ? 'processing' : 'error'">
|
||||
{{
|
||||
state.data.online
|
||||
? t('views.ne.neInfo.normalcy')
|
||||
: t('views.ne.neInfo.exceptions')
|
||||
}}
|
||||
</a-tag>
|
||||
</div>
|
||||
<div>
|
||||
<span>{{ t('views.ne.neInfo.version') }}:</span>
|
||||
<span>{{ state.data.version }}</span>
|
||||
</div>
|
||||
<div>
|
||||
<span>{{ t('views.ne.neInfo.serialNum') }}:</span>
|
||||
<span>{{ state.data.sn }}</span>
|
||||
</div>
|
||||
<div>
|
||||
<span>{{ t('views.ne.neInfo.expiryDate') }}:</span>
|
||||
<span>{{ state.data.expire }}</span>
|
||||
</div>
|
||||
|
||||
<a-divider orientation="left">
|
||||
{{ t('views.ne.neInfo.resourceInfo') }}
|
||||
</a-divider>
|
||||
<div>
|
||||
<span>{{ t('views.ne.neInfo.neCpu') }}:</span>
|
||||
<a-progress
|
||||
status="normal"
|
||||
:stroke-color="
|
||||
state.resoures.nfCpuUsage < 30
|
||||
? '#52c41a'
|
||||
: state.resoures.nfCpuUsage > 70
|
||||
? '#ff4d4f'
|
||||
: '#1890ff'
|
||||
"
|
||||
:percent="state.resoures.nfCpuUsage"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<span>{{ t('views.ne.neInfo.sysCpu') }}:</span>
|
||||
<a-progress
|
||||
status="normal"
|
||||
:stroke-color="
|
||||
state.resoures.sysCpuUsage < 30
|
||||
? '#52c41a'
|
||||
: state.resoures.sysCpuUsage > 70
|
||||
? '#ff4d4f'
|
||||
: '#1890ff'
|
||||
"
|
||||
:percent="state.resoures.sysCpuUsage"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<span>{{ t('views.ne.neInfo.sysMem') }}:</span>
|
||||
<a-progress
|
||||
status="normal"
|
||||
:stroke-color="
|
||||
state.resoures.sysMemUsage < 30
|
||||
? '#52c41a'
|
||||
: state.resoures.sysMemUsage > 70
|
||||
? '#ff4d4f'
|
||||
: '#1890ff'
|
||||
"
|
||||
:percent="state.resoures.sysMemUsage"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<span>{{ t('views.ne.neInfo.sysDisk') }}:</span>
|
||||
<a-progress
|
||||
status="normal"
|
||||
:stroke-color="
|
||||
state.resoures.sysDiskUsage < 30
|
||||
? '#52c41a'
|
||||
: state.resoures.sysDiskUsage > 70
|
||||
? '#ff4d4f'
|
||||
: '#1890ff'
|
||||
"
|
||||
:percent="state.resoures.sysDiskUsage"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.collapse :deep(.ant-collapse-item) > .ant-collapse-header {
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
}
|
||||
.collapse-header {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
}
|
||||
</style>
|
||||
@@ -1,628 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { reactive, onMounted, toRaw } from 'vue';
|
||||
import { message, Form, Upload } from 'ant-design-vue/lib';
|
||||
import useI18n from '@/hooks/useI18n';
|
||||
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
||||
import { NE_TYPE_LIST } from '@/constants/ne-constants';
|
||||
import { ColumnsType } from 'ant-design-vue/lib/table';
|
||||
import { installNeSoftware, listNeSoftware } from '@/api/ne/neSoftware';
|
||||
import { parseDateToStr } from '@/utils/date-utils';
|
||||
import { FileType } from 'ant-design-vue/lib/upload/interface';
|
||||
import { UploadRequestOption } from 'ant-design-vue/lib/vc-upload/interface';
|
||||
import { uploadFileChunk } from '@/api/tool/file';
|
||||
import { stepState } from '../hooks/useStep';
|
||||
const { t } = useI18n();
|
||||
|
||||
/**表格字段列 */
|
||||
let tableColumns: ColumnsType = [
|
||||
{
|
||||
title: t('common.rowId'),
|
||||
dataIndex: 'id',
|
||||
align: 'left',
|
||||
width: 50,
|
||||
},
|
||||
{
|
||||
title: 'neType',
|
||||
dataIndex: 'neType',
|
||||
align: 'left',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: 'name',
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
align: 'left',
|
||||
width: 300,
|
||||
},
|
||||
{
|
||||
title: 'version',
|
||||
dataIndex: 'version',
|
||||
align: 'left',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: 'description',
|
||||
dataIndex: 'description',
|
||||
key: 'description',
|
||||
align: 'left',
|
||||
ellipsis: true,
|
||||
},
|
||||
{
|
||||
title: 'createTime',
|
||||
dataIndex: 'createTime',
|
||||
align: 'left',
|
||||
width: 150,
|
||||
customRender(opt) {
|
||||
if (!opt.value) return '';
|
||||
return parseDateToStr(+opt.value);
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
/**表格分页器参数 */
|
||||
let tablePagination = reactive({
|
||||
/**当前页数 */
|
||||
current: 1,
|
||||
/**每页条数 */
|
||||
pageSize: 10,
|
||||
/**默认的每页条数 */
|
||||
defaultPageSize: 10,
|
||||
/**指定每页可以显示多少条 */
|
||||
pageSizeOptions: ['10', '20', '50', '100'],
|
||||
/**只有一页时是否隐藏分页器 */
|
||||
hideOnSinglePage: false,
|
||||
/**是否可以快速跳转至某页 */
|
||||
showQuickJumper: true,
|
||||
/**是否可以改变 pageSize */
|
||||
showSizeChanger: true,
|
||||
/**数据总数 */
|
||||
total: 0,
|
||||
showTotal: (total: number) => t('common.tablePaginationTotal', { total }),
|
||||
onChange: (page: number, pageSize: number) => {
|
||||
tablePagination.current = page;
|
||||
tablePagination.pageSize = pageSize;
|
||||
tableState.queryParams.pageNum = page;
|
||||
tableState.queryParams.pageSize = pageSize;
|
||||
fnGetList();
|
||||
},
|
||||
});
|
||||
|
||||
/**表格状态类型 */
|
||||
type TabeStateType = {
|
||||
/**查询参数 */
|
||||
queryParams: Record<string, any>;
|
||||
/**加载等待 */
|
||||
loading: boolean;
|
||||
/**记录数据 */
|
||||
data: object[];
|
||||
/**勾选记录 */
|
||||
selectedRowKeys: (string | number)[];
|
||||
};
|
||||
|
||||
/**表格状态 */
|
||||
let tableState: TabeStateType = reactive({
|
||||
queryParams: {
|
||||
neType: '',
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
},
|
||||
loading: false,
|
||||
data: [],
|
||||
selectedRowKeys: [],
|
||||
});
|
||||
|
||||
/**表格多选 */
|
||||
function fnTableSelectedRowKeys(
|
||||
keys: (string | number)[],
|
||||
selectedRows: any[]
|
||||
) {
|
||||
tableState.selectedRowKeys = keys;
|
||||
// 选择的表单数据填充
|
||||
const row = selectedRows[0];
|
||||
installState.from.neType = row.neType;
|
||||
installState.from.name = row.name;
|
||||
installState.from.path = row.path;
|
||||
installState.from.version = row.version;
|
||||
installState.from.description = row.description;
|
||||
}
|
||||
|
||||
/**查询列表, pageNum初始页数 */
|
||||
function fnGetList(pageNum?: number) {
|
||||
if (tableState.loading) return;
|
||||
tableState.loading = true;
|
||||
if (pageNum) {
|
||||
tableState.queryParams.pageNum = pageNum;
|
||||
}
|
||||
listNeSoftware(toRaw(tableState.queryParams)).then(res => {
|
||||
if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.rows)) {
|
||||
// 取消勾选
|
||||
if (tableState.selectedRowKeys.length > 0) {
|
||||
tableState.selectedRowKeys = [];
|
||||
}
|
||||
tablePagination.total = res.total;
|
||||
// 遍历处理资源情况数值
|
||||
tableState.data = res.rows;
|
||||
}
|
||||
tableState.loading = false;
|
||||
});
|
||||
}
|
||||
|
||||
/**安装对象信息状态类型 */
|
||||
type InstallStateType = {
|
||||
/**步骤 */
|
||||
setp: 'pkg' | 'preinput' | 'log';
|
||||
/**步骤日志输出 */
|
||||
setpLog: string;
|
||||
/**文件操作类型 上传 or 选择 */
|
||||
optionType: 'upload' | 'option';
|
||||
/**表单数据 */
|
||||
from: {
|
||||
neType: string;
|
||||
neId: string;
|
||||
name: string;
|
||||
path: string;
|
||||
version: string;
|
||||
description: string;
|
||||
};
|
||||
/**确定按钮 loading */
|
||||
confirmLoading: boolean;
|
||||
/**上传文件 */
|
||||
uploadFiles: any[];
|
||||
/**预输入 */
|
||||
preinput: Record<string, any>;
|
||||
};
|
||||
|
||||
/**安装对象信息状态 */
|
||||
let installState: InstallStateType = reactive({
|
||||
setp: 'pkg',
|
||||
setpLog: '',
|
||||
optionType: 'upload',
|
||||
from: {
|
||||
neType: '',
|
||||
neId: '',
|
||||
name: '',
|
||||
path: '',
|
||||
version: '',
|
||||
description: '',
|
||||
},
|
||||
confirmLoading: false,
|
||||
uploadFiles: [],
|
||||
preinput: {
|
||||
// IMS
|
||||
pubIP: '192.168.5.57',
|
||||
mcc: '001',
|
||||
mnc: '01',
|
||||
priIP: '172.16.16.51',
|
||||
pisCSCF: 'true',
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* 表单修改网元类型
|
||||
*/
|
||||
function fnNeTypeChange(v: any) {
|
||||
tableState.queryParams.neType = v;
|
||||
if (installState.optionType === 'option') {
|
||||
fnGetList(1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 表单修改文件操作类型
|
||||
*/
|
||||
function fnOptionTypeChange() {
|
||||
if (installState.optionType === 'upload') {
|
||||
installState.from.name = '';
|
||||
installState.from.path = '';
|
||||
installState.from.version = '';
|
||||
installState.from.description = '';
|
||||
}
|
||||
if (installState.optionType === 'option') {
|
||||
tableState.queryParams.neType = installState.from.neType;
|
||||
fnGetList(1);
|
||||
}
|
||||
}
|
||||
|
||||
/**表单属性和校验规则 */
|
||||
const installStateFrom = Form.useForm(
|
||||
installState.from,
|
||||
reactive({
|
||||
neType: [
|
||||
{
|
||||
required: true,
|
||||
min: 1,
|
||||
max: 32,
|
||||
message: t('views.configManage.softwareManage.neTypePlease'),
|
||||
},
|
||||
],
|
||||
version: [
|
||||
{
|
||||
required: true,
|
||||
min: 1,
|
||||
max: 64,
|
||||
message: t('views.configManage.softwareManage.versionPlease'),
|
||||
},
|
||||
],
|
||||
path: [
|
||||
{
|
||||
required: true,
|
||||
message: t('views.configManage.softwareManage.updateFilePlease'),
|
||||
},
|
||||
],
|
||||
})
|
||||
);
|
||||
|
||||
/**表单上传前检查或转换压缩 */
|
||||
function fnBeforeUploadFile(file: FileType) {
|
||||
if (installState.confirmLoading) return false;
|
||||
const fileName = file.name;
|
||||
const suff = fileName.substring(fileName.lastIndexOf('.'));
|
||||
if (!['.deb', '.rpm'].includes(suff)) {
|
||||
message.error(
|
||||
t('views.configManage.softwareManage.onlyAble', {
|
||||
fileText: '(.deb、.rpm)',
|
||||
}),
|
||||
3
|
||||
);
|
||||
return Upload.LIST_IGNORE;
|
||||
}
|
||||
// 根据给定的软件名取版本号 ims-r2.2312.x-ub22.deb
|
||||
const matches = fileName.match(/([0-9.]+[0-9x]+)/);
|
||||
if (matches) {
|
||||
installState.from.version = matches[0];
|
||||
}
|
||||
const neTypeIndex = fileName.indexOf('-');
|
||||
if (neTypeIndex !== -1) {
|
||||
const neType = fileName.substring(0, neTypeIndex).toUpperCase();
|
||||
if (installState.from.neType !== neType) {
|
||||
message.error('请上传对应网元类型的安装包', 3);
|
||||
return Upload.LIST_IGNORE;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**表单上传文件 */
|
||||
function fnUploadFile(up: UploadRequestOption) {
|
||||
// 发送请求
|
||||
const hide = message.loading(t('common.loading'), 0);
|
||||
installState.confirmLoading = true;
|
||||
uploadFileChunk(up.file as File, 5, 'software')
|
||||
.then(res => {
|
||||
if (res.code === RESULT_CODE_SUCCESS) {
|
||||
message.success('上传成功', 3);
|
||||
// 改为完成状态
|
||||
const file = installState.uploadFiles[0];
|
||||
file.percent = 100;
|
||||
file.status = 'done';
|
||||
// 预置到表单
|
||||
const { fileName, originalFileName } = res.data;
|
||||
installState.from.name = originalFileName;
|
||||
installState.from.path = fileName;
|
||||
} else {
|
||||
message.error(res.msg, 3);
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
hide();
|
||||
installState.confirmLoading = false;
|
||||
});
|
||||
}
|
||||
|
||||
/**软件包检查 */
|
||||
function fnRunCheck() {
|
||||
if (installState.confirmLoading) return;
|
||||
const hide = message.loading(t('common.loading'), 0);
|
||||
installStateFrom
|
||||
.validate()
|
||||
.then(() => {
|
||||
installState.setp = 'preinput';
|
||||
})
|
||||
.catch(e => {
|
||||
message.error(t('common.errorFields', { num: e.errorFields.length }), 3);
|
||||
})
|
||||
.finally(() => {
|
||||
hide();
|
||||
installState.confirmLoading = false;
|
||||
});
|
||||
}
|
||||
|
||||
/**开始安装 */
|
||||
function fnInstall() {
|
||||
if (installState.confirmLoading) return;
|
||||
installState.confirmLoading = true;
|
||||
const hide = message.loading(t('common.loading'), 0);
|
||||
const from = toRaw(installState.from);
|
||||
const preinput = toRaw(installState.preinput);
|
||||
installNeSoftware({
|
||||
software: from,
|
||||
preinput: preinput,
|
||||
})
|
||||
.then(res => {
|
||||
if (res.code === RESULT_CODE_SUCCESS) {
|
||||
installState.setp = 'log';
|
||||
installState.setpLog = res.data;
|
||||
message.success('软件安装成功', 3);
|
||||
// 记录当前步骤状态信息
|
||||
stepState.states[stepState.current] = {
|
||||
from: from,
|
||||
preinput: preinput,
|
||||
};
|
||||
stepState.stepNext = true;
|
||||
} else {
|
||||
message.error(res.msg, 3);
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
hide();
|
||||
installState.confirmLoading = false;
|
||||
});
|
||||
}
|
||||
|
||||
/**重新安装 */
|
||||
function fnInstallReset() {
|
||||
installState.setp = 'pkg';
|
||||
installState.optionType = 'option';
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
// 读取步骤:网元信息
|
||||
const stepPrevFrom = stepState.states[1];
|
||||
if (stepPrevFrom && stepPrevFrom.from) {
|
||||
installState.from.neType = stepPrevFrom.from.neType;
|
||||
installState.from.neId = stepPrevFrom.from.neId;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a-form
|
||||
name="installStateFrom"
|
||||
layout="horizontal"
|
||||
:label-col="{ span: 3 }"
|
||||
:wrapper-col="{ span: 8 }"
|
||||
:label-wrap="true"
|
||||
>
|
||||
<div>---- 安装软件包</div>
|
||||
|
||||
<template v-if="installState.setp === 'pkg'">
|
||||
<a-form-item
|
||||
:label="t('views.configManage.softwareManage.neType')"
|
||||
name="neType"
|
||||
v-bind="installStateFrom.validateInfos.neType"
|
||||
>
|
||||
<a-auto-complete
|
||||
v-model:value="installState.from.neType"
|
||||
:disabled="true"
|
||||
:options="NE_TYPE_LIST.map(v => ({ value: v }))"
|
||||
@change="fnNeTypeChange"
|
||||
>
|
||||
<a-input
|
||||
allow-clear
|
||||
:placeholder="t('common.inputPlease')"
|
||||
:maxlength="32"
|
||||
:disabled="true"
|
||||
>
|
||||
<template #prefix>
|
||||
<a-tooltip placement="topLeft">
|
||||
<template #title>
|
||||
{{ t('views.configManage.neManage.neTypeTip') }}
|
||||
</template>
|
||||
<InfoCircleOutlined style="color: rgba(0, 0, 0, 0.45)" />
|
||||
</a-tooltip>
|
||||
</template>
|
||||
</a-input>
|
||||
</a-auto-complete>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="软件来源" name="optionType">
|
||||
<a-radio-group
|
||||
v-model:value="installState.optionType"
|
||||
button-style="solid"
|
||||
@change="fnOptionTypeChange"
|
||||
:disabled="installState.confirmLoading"
|
||||
>
|
||||
<a-radio-button value="upload">新上传</a-radio-button>
|
||||
<a-radio-button value="option">已上传</a-radio-button>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
|
||||
<!-- 重新上传 -->
|
||||
<template v-if="installState.optionType === 'upload'">
|
||||
<a-form-item
|
||||
:label="t('views.configManage.softwareManage.version')"
|
||||
name="version"
|
||||
v-bind="installStateFrom.validateInfos.version"
|
||||
>
|
||||
<a-input
|
||||
v-model:value="installState.from.version"
|
||||
allow-clear
|
||||
:placeholder="t('views.configManage.softwareManage.versionPlease')"
|
||||
></a-input>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
:label="t('views.configManage.softwareManage.updateComment')"
|
||||
name="description"
|
||||
v-bind="installStateFrom.validateInfos.description"
|
||||
>
|
||||
<a-textarea
|
||||
v-model:value="installState.from.description"
|
||||
:auto-size="{ minRows: 1, maxRows: 4 }"
|
||||
:maxlength="500"
|
||||
:show-count="true"
|
||||
:placeholder="
|
||||
t('views.configManage.softwareManage.updateCommentPlease')
|
||||
"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
:label="t('views.configManage.softwareManage.updateFile')"
|
||||
name="file"
|
||||
v-bind="installStateFrom.validateInfos.path"
|
||||
>
|
||||
<a-upload
|
||||
name="file"
|
||||
v-model:file-list="installState.uploadFiles"
|
||||
accept=".rpm,.deb"
|
||||
list-type="text"
|
||||
:max-count="1"
|
||||
:show-upload-list="{
|
||||
showPreviewIcon: false,
|
||||
showRemoveIcon: false,
|
||||
showDownloadIcon: false,
|
||||
}"
|
||||
:before-upload="fnBeforeUploadFile"
|
||||
:custom-request="fnUploadFile"
|
||||
:disabled="installState.confirmLoading"
|
||||
>
|
||||
<a-button type="default" :disabled="installState.confirmLoading">
|
||||
{{ t('views.configManage.softwareManage.selectFile') }}
|
||||
</a-button>
|
||||
</a-upload>
|
||||
</a-form-item>
|
||||
</template>
|
||||
|
||||
<!-- 选择已上传 -->
|
||||
<template v-if="installState.optionType === 'option'">
|
||||
<a-form-item label="选择记录" name="option" :wrapper-col="{ span: 24 }">
|
||||
<a-table
|
||||
class="table"
|
||||
row-key="id"
|
||||
:columns="tableColumns"
|
||||
:loading="tableState.loading"
|
||||
:data-source="tableState.data"
|
||||
:pagination="tablePagination"
|
||||
size="small"
|
||||
:scroll="{ x: tableColumns.length * 100, y: '400px' }"
|
||||
:row-selection="{
|
||||
type: 'radio',
|
||||
columnWidth: '48px',
|
||||
selectedRowKeys: tableState.selectedRowKeys,
|
||||
onChange: fnTableSelectedRowKeys,
|
||||
}"
|
||||
>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'name'">
|
||||
<a-tooltip placement="topLeft">
|
||||
<template #title>{{ record.path }}</template>
|
||||
<div style="cursor: pointer">{{ record.name }}</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key === 'description'">
|
||||
<a-tooltip placement="topLeft">
|
||||
<template #title>{{ record.description }}</template>
|
||||
<div style="cursor: pointer">{{ record.description }}</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
</a-form-item>
|
||||
</template>
|
||||
|
||||
<a-form-item :wrapper-col="{ span: 14, offset: 3 }">
|
||||
<a-button
|
||||
type="primary"
|
||||
html-type="submit"
|
||||
@click="fnRunCheck()"
|
||||
:loading="installState.confirmLoading"
|
||||
>
|
||||
安装检查
|
||||
</a-button>
|
||||
</a-form-item>
|
||||
</template>
|
||||
|
||||
<div>--- 安装前预输入</div>
|
||||
|
||||
<template v-if="installState.setp === 'preinput'">
|
||||
<a-form-item
|
||||
name="info"
|
||||
label="安装前预输入"
|
||||
:label-col="{ span: 3 }"
|
||||
:label-wrap="true"
|
||||
>
|
||||
<div style="align-items: center">-----</div>
|
||||
</a-form-item>
|
||||
|
||||
<!-- IMS 预输入 -->
|
||||
<template v-if="installState.from.neType === 'IMS'">
|
||||
<a-form-item label="P/I/S-CSCF Config" name="pisCSCF">
|
||||
<a-input
|
||||
v-model:value="installState.preinput.pisCSCF"
|
||||
allow-clear
|
||||
placeholder="P/I/S-CSCF Config"
|
||||
></a-input>
|
||||
</a-form-item>
|
||||
<a-form-item label="modipplmn IP" name="pubIP">
|
||||
<a-input
|
||||
v-model:value="installState.preinput.pubIP"
|
||||
allow-clear
|
||||
placeholder="IMS modipplmn IP"
|
||||
></a-input>
|
||||
</a-form-item>
|
||||
<a-form-item label="modipplmn mcc" name="mcc">
|
||||
<a-input
|
||||
v-model:value="installState.preinput.mcc"
|
||||
allow-clear
|
||||
placeholder="IMS modipplmn mcc"
|
||||
></a-input>
|
||||
</a-form-item>
|
||||
<a-form-item label="modipplmn mnc" name="mnc">
|
||||
<a-input
|
||||
v-model:value="installState.preinput.mnc"
|
||||
allow-clear
|
||||
placeholder="IMS modipplmn mnc"
|
||||
></a-input>
|
||||
</a-form-item>
|
||||
<a-form-item label="modintraip priIP" name="priIP">
|
||||
<a-input
|
||||
v-model:value="installState.preinput.priIP"
|
||||
allow-clear
|
||||
placeholder="IMS modintraip priIP"
|
||||
></a-input>
|
||||
</a-form-item>
|
||||
</template>
|
||||
|
||||
<a-form-item :wrapper-col="{ span: 14, offset: 3 }">
|
||||
<a-button
|
||||
type="primary"
|
||||
html-type="submit"
|
||||
@click="fnInstall()"
|
||||
:loading="installState.confirmLoading"
|
||||
>
|
||||
开始安装
|
||||
</a-button>
|
||||
</a-form-item>
|
||||
</template>
|
||||
|
||||
<div>---- 安装进行信息</div>
|
||||
|
||||
<template v-if="installState.setp === 'log'">
|
||||
<a-form-item
|
||||
name="info"
|
||||
label="安装日志"
|
||||
:label-col="{ span: 3 }"
|
||||
:wrapper-col="{ span: 24 }"
|
||||
:label-wrap="true"
|
||||
>
|
||||
<TerminalText
|
||||
id="installLog"
|
||||
:rows="28"
|
||||
:value="installState.setpLog"
|
||||
></TerminalText>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item :wrapper-col="{ span: 14, offset: 3 }">
|
||||
<a-button
|
||||
type="primary"
|
||||
html-type="submit"
|
||||
@click="fnInstallReset()"
|
||||
:loading="installState.confirmLoading"
|
||||
>
|
||||
返回重新选择安装
|
||||
</a-button>
|
||||
</a-form-item>
|
||||
</template>
|
||||
</a-form>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped></style>
|
||||
@@ -1,472 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { reactive, onMounted, toRaw } from 'vue';
|
||||
import { message, Form, Modal } from 'ant-design-vue/lib';
|
||||
import useI18n from '@/hooks/useI18n';
|
||||
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
||||
import useNeInfoStore from '@/store/modules/neinfo';
|
||||
import {
|
||||
addNeInfo,
|
||||
updateNeInfo,
|
||||
getNeInfoByTypeAndIDNe,
|
||||
} from '@/api/ne/neInfo';
|
||||
import { NE_TYPE_LIST } from '@/constants/ne-constants';
|
||||
import { stepState } from '../hooks/useStep';
|
||||
const { t } = useI18n();
|
||||
|
||||
/**对话框对象信息状态类型 */
|
||||
type ModalStateType = {
|
||||
/**新增框或修改框是否显示 */
|
||||
visibleByEdit: boolean;
|
||||
/**标题 */
|
||||
title: string;
|
||||
/**表单数据 */
|
||||
from: Record<string, any>;
|
||||
/**确定按钮 loading */
|
||||
confirmLoading: boolean;
|
||||
};
|
||||
|
||||
/**对话框对象信息状态 */
|
||||
let modalState: ModalStateType = reactive({
|
||||
visibleByEdit: false,
|
||||
title: '网元',
|
||||
from: {
|
||||
id: undefined,
|
||||
neId: '001',
|
||||
neType: 'AMF',
|
||||
neName: '',
|
||||
ip: '',
|
||||
port: 33030,
|
||||
pvFlag: 'PNF',
|
||||
rmUid: '4400HX1AMF001',
|
||||
neAddress: '',
|
||||
dn: '',
|
||||
vendorName: '',
|
||||
province: '',
|
||||
// 主机
|
||||
hosts: [
|
||||
{
|
||||
hostId: undefined,
|
||||
hostType: 'ssh',
|
||||
groupId: '1',
|
||||
title: 'SSH_NE_22',
|
||||
addr: '',
|
||||
port: 22,
|
||||
user: 'user',
|
||||
authMode: '0',
|
||||
password: 'user',
|
||||
privateKey: '',
|
||||
passPhrase: '',
|
||||
remark: '',
|
||||
},
|
||||
{
|
||||
hostId: undefined,
|
||||
hostType: 'telnet',
|
||||
groupId: '1',
|
||||
title: 'Telnet_NE_4100',
|
||||
addr: '',
|
||||
port: 4100,
|
||||
user: 'user',
|
||||
authMode: '0',
|
||||
password: 'user',
|
||||
remark: '',
|
||||
},
|
||||
],
|
||||
},
|
||||
confirmLoading: false,
|
||||
});
|
||||
|
||||
/**对话框内表单属性和校验规则 */
|
||||
const modalStateFrom = Form.useForm(
|
||||
modalState.from,
|
||||
reactive({
|
||||
neType: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入网元类型',
|
||||
},
|
||||
],
|
||||
neId: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入网元标识',
|
||||
},
|
||||
],
|
||||
rmUid: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入资源唯一标识',
|
||||
},
|
||||
],
|
||||
ip: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入网元IP地址',
|
||||
},
|
||||
],
|
||||
neName: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入网元名称',
|
||||
},
|
||||
],
|
||||
})
|
||||
);
|
||||
|
||||
/**测试连接检查信息 */
|
||||
function fnNeInfo() {
|
||||
const from = toRaw(modalState.from);
|
||||
modalStateFrom
|
||||
.validate()
|
||||
.then(e => {
|
||||
modalState.confirmLoading = true;
|
||||
return getNeInfoByTypeAndIDNe(from.neType, from.neId);
|
||||
})
|
||||
.then(res => {
|
||||
if (res.code === RESULT_CODE_SUCCESS) {
|
||||
message.warning({
|
||||
content: `${from.neType} 已存在网元标识:${from.neId} ,资源唯一标识:${from.rmUid}`,
|
||||
duration: 3,
|
||||
});
|
||||
from.id = res.data.id;
|
||||
from.hostIds = res.data.hostIds;
|
||||
const hostIds = res.data.hostIds.split(',');
|
||||
if (hostIds.length == 2) {
|
||||
from.hosts[0].hostId = hostIds[0];
|
||||
from.hosts[1].hostId = hostIds[1];
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
message.success({
|
||||
content: `${from.neType} 可使用网元标识:${from.neId}`,
|
||||
duration: 3,
|
||||
});
|
||||
from.id = undefined;
|
||||
return false;
|
||||
}
|
||||
})
|
||||
.then(state => {
|
||||
let confirmTitle = '新增提示';
|
||||
let confirmContent = '是否新增为新的网元信息并继续?';
|
||||
if (state) {
|
||||
confirmTitle = '更新提示';
|
||||
confirmContent = '是否更新替换已存在网元信息并继续?';
|
||||
}
|
||||
Modal.confirm({
|
||||
title: confirmTitle,
|
||||
content: confirmContent,
|
||||
okText: '确认',
|
||||
cancelText: '取消',
|
||||
onCancel: () => {
|
||||
from.id = undefined;
|
||||
},
|
||||
onOk: () => {
|
||||
const result = from.id ? updateNeInfo(from) : addNeInfo(from);
|
||||
const hide = message.loading(t('common.loading'), 0);
|
||||
result
|
||||
.then(res => {
|
||||
if (res.code === RESULT_CODE_SUCCESS) {
|
||||
message.success({
|
||||
content: '操作成功',
|
||||
duration: 3,
|
||||
});
|
||||
// 刷新缓存的网元信息
|
||||
useNeInfoStore()
|
||||
.fnRefreshNelist()
|
||||
.then(neRes => {
|
||||
const itemNe = neRes.data.find(
|
||||
(item: any) =>
|
||||
item.neType === from.neType && item.neId === from.neId
|
||||
);
|
||||
if (itemNe) {
|
||||
Object.assign(from, itemNe);
|
||||
// 记录当前步骤状态信息
|
||||
stepState.states[stepState.current] = { from };
|
||||
stepState.stepNext = true;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
message.error({
|
||||
content: `${t('views.configManage.neManage.operFail')}`,
|
||||
duration: 3,
|
||||
});
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
hide();
|
||||
modalState.confirmLoading = false;
|
||||
});
|
||||
},
|
||||
});
|
||||
})
|
||||
.catch(e => {
|
||||
message.error(t('common.errorFields', { num: e.errorFields.length }), 3);
|
||||
})
|
||||
.finally(() => {
|
||||
modalState.confirmLoading = false;
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
// 读取步骤:环境检查
|
||||
const stepPrevFrom = stepState.states[0];
|
||||
if (stepPrevFrom && stepPrevFrom.from) {
|
||||
modalState.from.ip = stepPrevFrom.from.addr;
|
||||
Object.assign(modalState.from.hosts[0], stepPrevFrom.from);
|
||||
Object.assign(modalState.from.hosts[1], {
|
||||
addr: modalState.from.ip,
|
||||
user: 'admin',
|
||||
password: 'admin',
|
||||
});
|
||||
}
|
||||
|
||||
// 读取步骤:网元信息
|
||||
const stepCurrentFrom = stepState.states[1];
|
||||
if (stepCurrentFrom && stepCurrentFrom.from) {
|
||||
Object.assign(modalState.from, stepCurrentFrom.from);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a-form
|
||||
name="modalStateFrom"
|
||||
layout="horizontal"
|
||||
:label-col="{ span: 6 }"
|
||||
:labelWrap="true"
|
||||
>
|
||||
<a-row :gutter="16">
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item
|
||||
:label="t('views.configManage.neManage.neType')"
|
||||
name="neType"
|
||||
v-bind="modalStateFrom.validateInfos.neType"
|
||||
>
|
||||
<a-auto-complete
|
||||
v-model:value="modalState.from.neType"
|
||||
:options="NE_TYPE_LIST.map(v => ({ value: v }))"
|
||||
>
|
||||
<a-input
|
||||
allow-clear
|
||||
:placeholder="t('common.inputPlease')"
|
||||
:maxlength="32"
|
||||
>
|
||||
<template #prefix>
|
||||
<a-tooltip placement="topLeft">
|
||||
<template #title>
|
||||
{{ t('views.configManage.neManage.neTypeTip') }}
|
||||
</template>
|
||||
<InfoCircleOutlined style="color: rgba(0, 0, 0, 0.45)" />
|
||||
</a-tooltip>
|
||||
</template>
|
||||
</a-input>
|
||||
</a-auto-complete>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item
|
||||
:label="t('views.configManage.neManage.pvflag')"
|
||||
name="pvFlag"
|
||||
v-bind="modalStateFrom.validateInfos.pvFlag"
|
||||
>
|
||||
<a-select v-model:value="modalState.from.pvFlag" default-value="PNF">
|
||||
<a-select-opt-group :label="t('views.configManage.neManage.pnf')">
|
||||
<a-select-option value="PNF">PNF</a-select-option>
|
||||
</a-select-opt-group>
|
||||
<a-select-opt-group :label="t('views.configManage.neManage.vnf')">
|
||||
<a-select-option value="VNF">VNF</a-select-option>
|
||||
</a-select-opt-group>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-row :gutter="16">
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item
|
||||
:label="t('views.configManage.neManage.neId')"
|
||||
name="neId"
|
||||
v-bind="modalStateFrom.validateInfos.neId"
|
||||
>
|
||||
<a-input
|
||||
v-model:value="modalState.from.neId"
|
||||
allow-clear
|
||||
:placeholder="t('common.inputPlease')"
|
||||
:maxlength="32"
|
||||
></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item
|
||||
:label="t('views.configManage.neManage.neName')"
|
||||
name="neName"
|
||||
v-bind="modalStateFrom.validateInfos.neName"
|
||||
>
|
||||
<a-input
|
||||
v-model:value="modalState.from.neName"
|
||||
allow-clear
|
||||
:placeholder="t('common.inputPlease')"
|
||||
:maxlength="64"
|
||||
>
|
||||
</a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-row :gutter="16">
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item
|
||||
:label="t('views.configManage.neManage.ip')"
|
||||
name="ip"
|
||||
v-bind="modalStateFrom.validateInfos.ip"
|
||||
>
|
||||
<a-input
|
||||
v-model:value="modalState.from.ip"
|
||||
allow-clear
|
||||
:disabled="true"
|
||||
:placeholder="t('common.inputPlease')"
|
||||
:maxlength="128"
|
||||
>
|
||||
<template #prefix>
|
||||
<a-tooltip placement="topLeft">
|
||||
<template #title>
|
||||
<div>
|
||||
{{ t('views.ne.neInfo.ipAddr') }}
|
||||
</div>
|
||||
</template>
|
||||
<InfoCircleOutlined style="color: rgba(0, 0, 0, 0.45)" />
|
||||
</a-tooltip>
|
||||
</template>
|
||||
</a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item
|
||||
:label="t('views.configManage.neManage.port')"
|
||||
name="port"
|
||||
v-bind="modalStateFrom.validateInfos.port"
|
||||
>
|
||||
<a-input-number
|
||||
v-model:value="modalState.from.port"
|
||||
style="width: 100%"
|
||||
:min="1"
|
||||
:max="65535"
|
||||
placeholder="<=65535"
|
||||
>
|
||||
<template #prefix>
|
||||
<a-tooltip placement="topLeft">
|
||||
<template #title>
|
||||
<div>{{ t('views.configManage.neManage.portTip') }}</div>
|
||||
</template>
|
||||
<InfoCircleOutlined style="color: rgba(0, 0, 0, 0.45)" />
|
||||
</a-tooltip>
|
||||
</template>
|
||||
</a-input-number>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-form-item
|
||||
:label="t('views.configManage.neManage.uid')"
|
||||
name="rmUid"
|
||||
v-bind="modalStateFrom.validateInfos.rmUid"
|
||||
:label-col="{ span: 3 }"
|
||||
:labelWrap="true"
|
||||
>
|
||||
<a-input
|
||||
v-model:value="modalState.from.rmUid"
|
||||
allow-clear
|
||||
:placeholder="t('common.inputPlease')"
|
||||
:maxlength="40"
|
||||
>
|
||||
<template #prefix>
|
||||
<a-tooltip placement="topLeft">
|
||||
<template #title>
|
||||
<div>
|
||||
{{ t('views.ne.neInfo.rmUID') }}
|
||||
</div>
|
||||
</template>
|
||||
<InfoCircleOutlined style="color: rgba(0, 0, 0, 0.45)" />
|
||||
</a-tooltip>
|
||||
</template>
|
||||
</a-input>
|
||||
</a-form-item>
|
||||
|
||||
<a-row :gutter="16">
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item
|
||||
:label="t('views.configManage.neManage.mac')"
|
||||
name="neAddress"
|
||||
>
|
||||
<a-input
|
||||
v-model:value="modalState.from.neAddress"
|
||||
allow-clear
|
||||
:placeholder="t('common.inputPlease')"
|
||||
:maxlength="64"
|
||||
>
|
||||
<template #prefix>
|
||||
<a-tooltip placement="topLeft">
|
||||
<template #title>
|
||||
<div>{{ t('views.configManage.neManage.macTip') }}</div>
|
||||
</template>
|
||||
<InfoCircleOutlined style="color: rgba(0, 0, 0, 0.45)" />
|
||||
</a-tooltip>
|
||||
</template>
|
||||
</a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item :label="t('views.configManage.neManage.dn')" name="dn">
|
||||
<a-input
|
||||
v-model:value="modalState.from.dn"
|
||||
allow-clear
|
||||
:placeholder="t('common.inputPlease')"
|
||||
:maxlength="255"
|
||||
></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-row :gutter="16">
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item
|
||||
:label="t('views.configManage.neManage.vendorName')"
|
||||
name="vendorName"
|
||||
>
|
||||
<a-input
|
||||
v-model:value="modalState.from.vendorName"
|
||||
allow-clear
|
||||
:placeholder="t('common.inputPlease')"
|
||||
:maxlength="64"
|
||||
>
|
||||
</a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item
|
||||
:label="t('views.configManage.neManage.province')"
|
||||
name="province"
|
||||
>
|
||||
<a-input
|
||||
v-model:value="modalState.from.province"
|
||||
allow-clear
|
||||
:placeholder="t('common.inputPlease')"
|
||||
:maxlength="32"
|
||||
></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-form-item :wrapper-col="{ span: 14, offset: 3 }">
|
||||
<a-button
|
||||
type="primary"
|
||||
html-type="submit"
|
||||
@click="fnNeInfo()"
|
||||
:loading="modalState.confirmLoading"
|
||||
>
|
||||
检查信息
|
||||
</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped></style>
|
||||
@@ -59,66 +59,3 @@ export function fnToStepName(stepName: string) {
|
||||
|
||||
stepState.stepName = stepName;
|
||||
}
|
||||
|
||||
// import { reactive } from 'vue';
|
||||
|
||||
// /**步骤信息状态类型 */
|
||||
// type StepStateType = {
|
||||
// /**当前选中 */
|
||||
// current: number;
|
||||
// /**步骤项 */
|
||||
// steps: {
|
||||
// title: string;
|
||||
// description: string;
|
||||
// }[];
|
||||
// /**步骤下一步 */
|
||||
// stepNext: boolean;
|
||||
// /**步骤信息状态 */
|
||||
// states: any[];
|
||||
// };
|
||||
|
||||
// /**步骤信息状态 */
|
||||
// export const stepState: StepStateType = reactive({
|
||||
// current: 0,
|
||||
// steps: [
|
||||
// {
|
||||
// title: '网元信息',
|
||||
// description: '网元基础信息',
|
||||
// },
|
||||
// {
|
||||
// title: '网元安装',
|
||||
// description: '执行安装启动服务等待10秒停止服务',
|
||||
// },
|
||||
// {
|
||||
// title: '网元配置',
|
||||
// description: '修改网元的配置文件',
|
||||
// },
|
||||
// {
|
||||
// title: '网元激活',
|
||||
// description: '获取激活码和上传授权文件',
|
||||
// },
|
||||
// {
|
||||
// title: '完成安装',
|
||||
// description: '获取网元服务状态',
|
||||
// },
|
||||
// ],
|
||||
// stepNext: false,
|
||||
// states: [],
|
||||
// });
|
||||
|
||||
// /**步骤信息状态复位 */
|
||||
// export function fnRestStepState() {
|
||||
// stepState.current = 0;
|
||||
// stepState.stepNext = false;
|
||||
// stepState.states = [];
|
||||
// }
|
||||
|
||||
// export function fnStepNext() {
|
||||
// stepState.current++;
|
||||
// stepState.stepNext = false;
|
||||
// }
|
||||
|
||||
// export function fnStepPrev() {
|
||||
// stepState.current--;
|
||||
// stepState.stepNext = true;
|
||||
// }
|
||||
|
||||
@@ -5,7 +5,7 @@ import { stepState, fnRestStepState } from './hooks/useStep';
|
||||
|
||||
// 异步加载组件
|
||||
const Start = defineAsyncComponent(
|
||||
() => import('./components/NeInfoSoftwareLicense.vue')
|
||||
() => import('./components/Start.vue')
|
||||
);
|
||||
|
||||
// 当前组件
|
||||
@@ -29,8 +29,7 @@ onMounted(() => {
|
||||
<template>
|
||||
<PageContainer>
|
||||
<a-card
|
||||
:bordered="false"
|
||||
:body-style="{ padding: '12px', minHeight: '450px' }"
|
||||
:bordered="false"
|
||||
>
|
||||
<!-- 插槽-卡片左侧 -->
|
||||
<template #title>
|
||||
|
||||
Reference in New Issue
Block a user