ref: v3变更,,网元关联核心网
This commit is contained in:
@@ -114,3 +114,16 @@ export function updateNeLicense(data: Record<string, any>) {
|
|||||||
timeout: 180_000,
|
timeout: 180_000,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 网元核心关联
|
||||||
|
* @param data 网元对象 {"neUid": "", "coreUid": ""}
|
||||||
|
* @returns object
|
||||||
|
*/
|
||||||
|
export function changeNeCore(data: Record<string, any>) {
|
||||||
|
return request({
|
||||||
|
url: `/ne/info/core`,
|
||||||
|
method: 'PUT',
|
||||||
|
data: data,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import { request } from '@/plugins/http-fetch';
|
|||||||
*/
|
*/
|
||||||
export function listCoreInfo(query: Record<string, any>) {
|
export function listCoreInfo(query: Record<string, any>) {
|
||||||
return request({
|
return request({
|
||||||
url: '/core/info/list',
|
url: '/ne/core/info/list',
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
params: query,
|
params: query,
|
||||||
timeout: 60_000,
|
timeout: 60_000,
|
||||||
@@ -23,7 +23,7 @@ export function listCoreInfo(query: Record<string, any>) {
|
|||||||
*/
|
*/
|
||||||
export function listAllCoreInfo(query: Record<string, any>) {
|
export function listAllCoreInfo(query: Record<string, any>) {
|
||||||
return request({
|
return request({
|
||||||
url: '/core/info/list/all',
|
url: '/ne/core/info/list/all',
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
params: query,
|
params: query,
|
||||||
timeout: 60_000,
|
timeout: 60_000,
|
||||||
@@ -37,7 +37,7 @@ export function listAllCoreInfo(query: Record<string, any>) {
|
|||||||
*/
|
*/
|
||||||
export function getCoreInfo(id: string | number) {
|
export function getCoreInfo(id: string | number) {
|
||||||
return request({
|
return request({
|
||||||
url: `/core/info/${id}`,
|
url: `/ne/core/info/${id}`,
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -49,7 +49,7 @@ export function getCoreInfo(id: string | number) {
|
|||||||
*/
|
*/
|
||||||
export function addCoreInfo(data: Record<string, any>) {
|
export function addCoreInfo(data: Record<string, any>) {
|
||||||
return request({
|
return request({
|
||||||
url: `/core/info`,
|
url: `/ne/core/info`,
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
data: data,
|
data: data,
|
||||||
crypto: sessionGet(CACHE_SESSION_CRYPTO_API) !== 'false',
|
crypto: sessionGet(CACHE_SESSION_CRYPTO_API) !== 'false',
|
||||||
@@ -64,7 +64,7 @@ export function addCoreInfo(data: Record<string, any>) {
|
|||||||
*/
|
*/
|
||||||
export function updateCoreInfo(data: Record<string, any>) {
|
export function updateCoreInfo(data: Record<string, any>) {
|
||||||
return request({
|
return request({
|
||||||
url: `/core/info`,
|
url: `/ne/core/info`,
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
data: data,
|
data: data,
|
||||||
crypto: sessionGet(CACHE_SESSION_CRYPTO_API) !== 'false',
|
crypto: sessionGet(CACHE_SESSION_CRYPTO_API) !== 'false',
|
||||||
@@ -79,7 +79,7 @@ export function updateCoreInfo(data: Record<string, any>) {
|
|||||||
*/
|
*/
|
||||||
export function delCoreInfo(id: string | number) {
|
export function delCoreInfo(id: string | number) {
|
||||||
return request({
|
return request({
|
||||||
url: `/core/info/${id}`,
|
url: `/ne/core/info/${id}`,
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
timeout: 60_000,
|
timeout: 60_000,
|
||||||
});
|
});
|
||||||
@@ -522,6 +522,8 @@ export default {
|
|||||||
},
|
},
|
||||||
ne: {
|
ne: {
|
||||||
common: {
|
common: {
|
||||||
|
coreUid: 'Core UID',
|
||||||
|
coreName: 'Core Name',
|
||||||
neType: 'NE Type',
|
neType: 'NE Type',
|
||||||
neTypePlease: "Please select network element type",
|
neTypePlease: "Please select network element type",
|
||||||
neTypeTip: 'Fill in the type of network element to be created, e.g. SMF.',
|
neTypeTip: 'Fill in the type of network element to be created, e.g. SMF.',
|
||||||
|
|||||||
@@ -522,6 +522,8 @@ export default {
|
|||||||
},
|
},
|
||||||
ne: {
|
ne: {
|
||||||
common: {
|
common: {
|
||||||
|
coreUid: '核心网标识',
|
||||||
|
coreName: '核心网名称',
|
||||||
neType: '网元类型',
|
neType: '网元类型',
|
||||||
neTypePlease: "请选择网元类型",
|
neTypePlease: "请选择网元类型",
|
||||||
neTypeTip: '填写创建的网元类型,如:SMF',
|
neTypeTip: '填写创建的网元类型,如:SMF',
|
||||||
|
|||||||
@@ -9,8 +9,6 @@ const neStore = useNeStore();
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
/**当前选中 */
|
|
||||||
const coreValue = ref(coreStore.currentCoreUid);
|
|
||||||
/**选择列表数据 */
|
/**选择列表数据 */
|
||||||
const coreOtions = ref(coreStore.getSelectOtions);
|
const coreOtions = ref(coreStore.getSelectOtions);
|
||||||
/**选择过滤名称 */
|
/**选择过滤名称 */
|
||||||
@@ -18,7 +16,6 @@ const coreName = ref('');
|
|||||||
|
|
||||||
/**选择 */
|
/**选择 */
|
||||||
async function handleSelect(v: any, item: any) {
|
async function handleSelect(v: any, item: any) {
|
||||||
coreValue.value = v;
|
|
||||||
if (v === coreStore.globalDefaultCoreUid) {
|
if (v === coreStore.globalDefaultCoreUid) {
|
||||||
coreStore.setCurrent(coreStore.globalDefaultSelect);
|
coreStore.setCurrent(coreStore.globalDefaultSelect);
|
||||||
} else {
|
} else {
|
||||||
@@ -42,7 +39,7 @@ function handleSearchFilter(e: any) {
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<a-select
|
<a-select
|
||||||
v-model:value="coreValue"
|
v-model:value="coreStore.currentCoreUid"
|
||||||
:options="coreOtions"
|
:options="coreOtions"
|
||||||
style="width: 200px"
|
style="width: 200px"
|
||||||
@change="handleSelect"
|
@change="handleSelect"
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import {
|
|||||||
RESULT_MSG_SUCCESS,
|
RESULT_MSG_SUCCESS,
|
||||||
} from '@/constants/result-constants';
|
} from '@/constants/result-constants';
|
||||||
import { defineStore } from 'pinia';
|
import { defineStore } from 'pinia';
|
||||||
import { listAllCoreInfo } from '@/api/core/coreInfo';
|
import { listAllCoreInfo } from '@/api/ne_core/coreInfo';
|
||||||
import {
|
import {
|
||||||
changeCoreUid,
|
changeCoreUid,
|
||||||
changeCurrent,
|
changeCurrent,
|
||||||
@@ -24,7 +24,7 @@ type Core = {
|
|||||||
/**选择器单级父类型 */
|
/**选择器单级父类型 */
|
||||||
coreSelectOtions: Record<string, any>[];
|
coreSelectOtions: Record<string, any>[];
|
||||||
/**全局选择 */
|
/**全局选择 */
|
||||||
globalDefaultSelect: Record<string, any>;
|
globalDefaultSelect: { label: string; value: string };
|
||||||
/**默认核心网标识 */
|
/**默认核心网标识 */
|
||||||
globalDefaultCoreUid: string;
|
globalDefaultCoreUid: string;
|
||||||
};
|
};
|
||||||
@@ -47,14 +47,15 @@ const useCoreStore = defineStore('core', {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
setCurrent(v: Record<string, any> = {}) {
|
/**设置当前选择 */
|
||||||
|
setCurrent(v: { label: string; value: string }) {
|
||||||
this.currentSelect = v;
|
this.currentSelect = v;
|
||||||
this.currentCoreUid = v.value;
|
this.currentCoreUid = v.value;
|
||||||
// 存储
|
// 存储
|
||||||
changeCurrent(v);
|
changeCurrent(v);
|
||||||
changeCoreUid(v.value);
|
changeCoreUid(v.value);
|
||||||
},
|
},
|
||||||
// 刷新核心网列表
|
/**刷新核心网列表 */
|
||||||
async fnCorelistRefresh() {
|
async fnCorelistRefresh() {
|
||||||
this.coreList = [];
|
this.coreList = [];
|
||||||
return await this.fnCorelist();
|
return await this.fnCorelist();
|
||||||
@@ -77,7 +78,7 @@ const useCoreStore = defineStore('core', {
|
|||||||
// 转选择器单级父类型
|
// 转选择器单级父类型
|
||||||
this.coreSelectOtions = res.data.map((item: any) => {
|
this.coreSelectOtions = res.data.map((item: any) => {
|
||||||
return {
|
return {
|
||||||
label: item.name,
|
label: item.coreName,
|
||||||
value: item.coreUid,
|
value: item.coreUid,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|||||||
550
src/views/core/info/index.vue
Normal file
550
src/views/core/info/index.vue
Normal file
@@ -0,0 +1,550 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { reactive, ref, onMounted, toRaw } from 'vue';
|
||||||
|
import { PageContainer } from 'antdv-pro-layout';
|
||||||
|
import { ProModal } from 'antdv-pro-modal';
|
||||||
|
import { message, Form, Modal } from 'ant-design-vue/es';
|
||||||
|
import { SizeType } from 'ant-design-vue/es/config-provider';
|
||||||
|
import { MenuInfo } from 'ant-design-vue/es/menu/src/interface';
|
||||||
|
import { ColumnsType } from 'ant-design-vue/es/table';
|
||||||
|
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
||||||
|
import { useRouter } from 'vue-router';
|
||||||
|
import useCoreStore from '@/store/modules/core';
|
||||||
|
import useNeStore from '@/store/modules/ne';
|
||||||
|
import useI18n from '@/hooks/useI18n';
|
||||||
|
|
||||||
|
import {
|
||||||
|
addCoreInfo,
|
||||||
|
delCoreInfo,
|
||||||
|
listCoreInfo,
|
||||||
|
updateCoreInfo,
|
||||||
|
} from '@/api/ne_core/coreInfo';
|
||||||
|
const coreStore = useCoreStore();
|
||||||
|
const neStore = useNeStore();
|
||||||
|
const router = useRouter();
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
/**查询参数 */
|
||||||
|
let queryParams = reactive({
|
||||||
|
/**参数键名 */
|
||||||
|
name: '',
|
||||||
|
/**当前页数 */
|
||||||
|
pageNum: 1,
|
||||||
|
/**每页条数 */
|
||||||
|
pageSize: 20,
|
||||||
|
});
|
||||||
|
|
||||||
|
/**查询参数重置 */
|
||||||
|
function fnQueryReset() {
|
||||||
|
queryParams = Object.assign(queryParams, {
|
||||||
|
name: '',
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 20,
|
||||||
|
});
|
||||||
|
tablePagination.current = 1;
|
||||||
|
tablePagination.pageSize = 20;
|
||||||
|
fnGetList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**表格状态类型 */
|
||||||
|
type TabeStateType = {
|
||||||
|
/**加载等待 */
|
||||||
|
loading: boolean;
|
||||||
|
/**紧凑型 */
|
||||||
|
size: SizeType;
|
||||||
|
/**搜索栏 */
|
||||||
|
seached: boolean;
|
||||||
|
/**记录数据 */
|
||||||
|
data: object[];
|
||||||
|
/**勾选记录 */
|
||||||
|
selectedRowKeys: (string | number)[];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**表格状态 */
|
||||||
|
let tableState: TabeStateType = reactive({
|
||||||
|
loading: false,
|
||||||
|
size: 'middle',
|
||||||
|
seached: true,
|
||||||
|
data: [],
|
||||||
|
selectedRowKeys: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
/**表格字段列 */
|
||||||
|
let tableColumns = ref<ColumnsType>([
|
||||||
|
{
|
||||||
|
title: t('common.rowId'),
|
||||||
|
dataIndex: 'id',
|
||||||
|
align: 'left',
|
||||||
|
width: 100,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Core UID',
|
||||||
|
dataIndex: 'coreUid',
|
||||||
|
align: 'left',
|
||||||
|
width: 100,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Core Name',
|
||||||
|
dataIndex: 'name',
|
||||||
|
align: 'left',
|
||||||
|
width: 100,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'SN',
|
||||||
|
dataIndex: 'sn',
|
||||||
|
align: 'left',
|
||||||
|
width: 200,
|
||||||
|
ellipsis: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('common.operate'),
|
||||||
|
key: 'id',
|
||||||
|
align: 'left',
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
/**表格分页器参数 */
|
||||||
|
let tablePagination = reactive({
|
||||||
|
/**当前页数 */
|
||||||
|
current: 1,
|
||||||
|
/**每页条数 */
|
||||||
|
pageSize: 20,
|
||||||
|
/**默认的每页条数 */
|
||||||
|
defaultPageSize: 20,
|
||||||
|
/**指定每页可以显示多少条 */
|
||||||
|
pageSizeOptions: ['10', '20', '50', '100'],
|
||||||
|
/**只有一页时是否隐藏分页器 */
|
||||||
|
hideOnSinglePage: false,
|
||||||
|
/**是否可以快速跳转至某页 */
|
||||||
|
showQuickJumper: true,
|
||||||
|
/**是否可以改变 pageSize */
|
||||||
|
showSizeChanger: true,
|
||||||
|
/**数据总数 */
|
||||||
|
total: 0,
|
||||||
|
showTotal: (total: number) =>
|
||||||
|
t('common.tablePaginationTotal', { total: total }),
|
||||||
|
onChange: (page: number, pageSize: number) => {
|
||||||
|
tablePagination.current = page;
|
||||||
|
tablePagination.pageSize = pageSize;
|
||||||
|
queryParams.pageNum = page;
|
||||||
|
queryParams.pageSize = pageSize;
|
||||||
|
fnGetList();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
/**表格紧凑型变更操作 */
|
||||||
|
function fnTableSize({ key }: MenuInfo) {
|
||||||
|
tableState.size = key as SizeType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**表格多选 */
|
||||||
|
function fnTableSelectedRowKeys(keys: (string | number)[]) {
|
||||||
|
tableState.selectedRowKeys = keys;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**对话框对象信息状态类型 */
|
||||||
|
type ModalStateType = {
|
||||||
|
/**新增框或修改框是否显示 */
|
||||||
|
openByEdit: boolean;
|
||||||
|
/**标题 */
|
||||||
|
title: string;
|
||||||
|
/**表单数据 */
|
||||||
|
from: Record<string, any>;
|
||||||
|
/**确定按钮 loading */
|
||||||
|
confirmLoading: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**对话框对象信息状态 */
|
||||||
|
let modalState: ModalStateType = reactive({
|
||||||
|
openByEdit: false,
|
||||||
|
title: 'Core Info',
|
||||||
|
from: {
|
||||||
|
id: undefined,
|
||||||
|
coreUid: '',
|
||||||
|
name: '',
|
||||||
|
sn: '',
|
||||||
|
omcId: '',
|
||||||
|
timeZone: '',
|
||||||
|
longitude: 0,
|
||||||
|
latitude: 0,
|
||||||
|
address: '',
|
||||||
|
},
|
||||||
|
confirmLoading: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
/**对话框内表单属性和校验规则 */
|
||||||
|
const modalStateFrom = Form.useForm(
|
||||||
|
modalState.from,
|
||||||
|
reactive({
|
||||||
|
name: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: t('common.inputPlease'),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
sn: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: t('common.selectPlease'),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对话框弹出显示为 新增或者修改
|
||||||
|
* @param configId 参数编号id, 不传为新增
|
||||||
|
*/
|
||||||
|
function fnModalVisibleByEdit(row?: Record<string, any>) {
|
||||||
|
if (!row) {
|
||||||
|
modalStateFrom.resetFields();
|
||||||
|
modalState.title = 'Add Core Info';
|
||||||
|
modalState.openByEdit = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 编辑
|
||||||
|
if (modalState.confirmLoading) return;
|
||||||
|
Object.assign(modalState.from, row);
|
||||||
|
modalState.title = 'Update Info';
|
||||||
|
modalState.openByEdit = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对话框弹出确认执行函数
|
||||||
|
* 进行表达规则校验
|
||||||
|
*/
|
||||||
|
function fnModalOk() {
|
||||||
|
modalStateFrom
|
||||||
|
.validate()
|
||||||
|
.then(() => {
|
||||||
|
modalState.confirmLoading = true;
|
||||||
|
const hide = message.loading(t('common.loading'), 0);
|
||||||
|
const from = toRaw(modalState.from);
|
||||||
|
const req = from.id ? updateCoreInfo(from) : addCoreInfo(from);
|
||||||
|
req
|
||||||
|
.then(res => {
|
||||||
|
if (res.code === RESULT_CODE_SUCCESS) {
|
||||||
|
message.success({
|
||||||
|
content: t('common.msgSuccess', { msg: modalState.title }),
|
||||||
|
duration: 2,
|
||||||
|
});
|
||||||
|
modalState.openByEdit = false;
|
||||||
|
modalStateFrom.resetFields();
|
||||||
|
fnGetList(1);
|
||||||
|
coreStore.fnCorelistRefresh();
|
||||||
|
} else {
|
||||||
|
message.error({
|
||||||
|
content: `${res.msg}`,
|
||||||
|
duration: 2,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
hide();
|
||||||
|
modalState.confirmLoading = false;
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(e => {
|
||||||
|
message.error(t('common.errorFields', { num: e.errorFields.length }), 3);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对话框弹出关闭执行函数
|
||||||
|
* 进行表达规则校验
|
||||||
|
*/
|
||||||
|
function fnModalCancel() {
|
||||||
|
modalState.openByEdit = false;
|
||||||
|
modalStateFrom.resetFields();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 配置删除
|
||||||
|
* @param id 编号ID
|
||||||
|
*/
|
||||||
|
function fnRecordDelete(id: string = '0') {
|
||||||
|
if (id === '0') {
|
||||||
|
id = tableState.selectedRowKeys.join(',');
|
||||||
|
}
|
||||||
|
Modal.confirm({
|
||||||
|
title: t('common.tipTitle'),
|
||||||
|
content: t('views.system.config.delTip', { num: id }),
|
||||||
|
onOk() {
|
||||||
|
const hide = message.loading(t('common.loading'), 0);
|
||||||
|
delCoreInfo(id)
|
||||||
|
.then(res => {
|
||||||
|
if (res.code === RESULT_CODE_SUCCESS) {
|
||||||
|
message.success({
|
||||||
|
content: t('views.system.config.delOk'),
|
||||||
|
duration: 2,
|
||||||
|
});
|
||||||
|
fnGetList();
|
||||||
|
} else {
|
||||||
|
message.error({
|
||||||
|
content: `${res.msg}`,
|
||||||
|
duration: 2,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
hide();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**查询参数配置列表, pageNum初始页数 */
|
||||||
|
function fnGetList(pageNum?: number) {
|
||||||
|
if (tableState.loading) return;
|
||||||
|
tableState.loading = true;
|
||||||
|
if (pageNum) {
|
||||||
|
queryParams.pageNum = pageNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
listCoreInfo(toRaw(queryParams)).then(res => {
|
||||||
|
if (res.code === RESULT_CODE_SUCCESS) {
|
||||||
|
// 取消勾选
|
||||||
|
if (tableState.selectedRowKeys.length > 0) {
|
||||||
|
tableState.selectedRowKeys = [];
|
||||||
|
}
|
||||||
|
tablePagination.total = res.data.total;
|
||||||
|
tableState.data = res.data.rows;
|
||||||
|
if (
|
||||||
|
tablePagination.total <=
|
||||||
|
(queryParams.pageNum - 1) * tablePagination.pageSize &&
|
||||||
|
queryParams.pageNum !== 1
|
||||||
|
) {
|
||||||
|
tableState.loading = false;
|
||||||
|
fnGetList(queryParams.pageNum - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tableState.loading = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**进入核心网管理 */
|
||||||
|
async function fnJumpCore(row: Record<string, any>) {
|
||||||
|
coreStore.setCurrent({
|
||||||
|
label: row.name,
|
||||||
|
value: row.coreUid,
|
||||||
|
});
|
||||||
|
await neStore.fnNelistRefresh();
|
||||||
|
// 切换核心网后,刷新路由
|
||||||
|
await router.replace({ name: 'Index' }).finally(() => {
|
||||||
|
// location.replace(location.origin);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
// 获取列表数据
|
||||||
|
fnGetList();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<PageContainer>
|
||||||
|
<a-card
|
||||||
|
v-show="tableState.seached"
|
||||||
|
:bordered="false"
|
||||||
|
:body-style="{ marginBottom: '24px', paddingBottom: 0 }"
|
||||||
|
>
|
||||||
|
<!-- 表格搜索栏 -->
|
||||||
|
<a-form :model="queryParams" name="queryParams" layout="horizontal">
|
||||||
|
<a-row :gutter="16">
|
||||||
|
<a-col :lg="6" :md="12" :xs="24">
|
||||||
|
<a-form-item label="Name" name="name">
|
||||||
|
<a-input
|
||||||
|
v-model:value="queryParams.name"
|
||||||
|
allow-clear
|
||||||
|
:placeholder="t('common.inputPlease')"
|
||||||
|
></a-input>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
|
||||||
|
<a-col :lg="6" :md="12" :xs="24">
|
||||||
|
<a-form-item>
|
||||||
|
<a-space :size="8">
|
||||||
|
<a-button type="primary" @click.prevent="fnGetList(1)">
|
||||||
|
<template #icon><SearchOutlined /></template>
|
||||||
|
{{ t('common.search') }}
|
||||||
|
</a-button>
|
||||||
|
<a-button type="default" @click.prevent="fnQueryReset">
|
||||||
|
<template #icon><ClearOutlined /></template>
|
||||||
|
{{ t('common.reset') }}
|
||||||
|
</a-button>
|
||||||
|
</a-space>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</a-form>
|
||||||
|
</a-card>
|
||||||
|
|
||||||
|
<a-card :bordered="false" :body-style="{ padding: '0px' }">
|
||||||
|
<!-- 插槽-卡片左侧侧 -->
|
||||||
|
<template #title>
|
||||||
|
<a-space :size="8" align="center">
|
||||||
|
<a-button type="primary" @click.prevent="fnModalVisibleByEdit()">
|
||||||
|
<template #icon><PlusOutlined /></template>
|
||||||
|
{{ t('common.addText') }}
|
||||||
|
</a-button>
|
||||||
|
<a-button
|
||||||
|
type="default"
|
||||||
|
danger
|
||||||
|
:disabled="tableState.selectedRowKeys.length <= 0"
|
||||||
|
@click.prevent="fnRecordDelete()"
|
||||||
|
>
|
||||||
|
<template #icon><DeleteOutlined /></template>
|
||||||
|
{{ t('common.deleteText') }}
|
||||||
|
</a-button>
|
||||||
|
</a-space>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 插槽-卡片右侧 -->
|
||||||
|
<template #extra>
|
||||||
|
<a-space :size="8" align="center">
|
||||||
|
<a-tooltip>
|
||||||
|
<template #title>{{ t('common.searchBarText') }}</template>
|
||||||
|
<a-switch
|
||||||
|
v-model:checked="tableState.seached"
|
||||||
|
:checked-children="t('common.switch.show')"
|
||||||
|
:un-checked-children="t('common.switch.hide')"
|
||||||
|
size="small"
|
||||||
|
/>
|
||||||
|
</a-tooltip>
|
||||||
|
<a-tooltip>
|
||||||
|
<template #title>{{ t('common.reloadText') }}</template>
|
||||||
|
<a-button type="text" @click.prevent="fnGetList()">
|
||||||
|
<template #icon><ReloadOutlined /></template>
|
||||||
|
</a-button>
|
||||||
|
</a-tooltip>
|
||||||
|
<a-tooltip placement="topRight">
|
||||||
|
<template #title>{{ t('common.sizeText') }}</template>
|
||||||
|
<a-dropdown placement="bottomRight" trigger="click">
|
||||||
|
<a-button type="text">
|
||||||
|
<template #icon><ColumnHeightOutlined /></template>
|
||||||
|
</a-button>
|
||||||
|
<template #overlay>
|
||||||
|
<a-menu
|
||||||
|
:selected-keys="[tableState.size as string]"
|
||||||
|
@click="fnTableSize"
|
||||||
|
>
|
||||||
|
<a-menu-item key="default">
|
||||||
|
{{ t('common.size.default') }}
|
||||||
|
</a-menu-item>
|
||||||
|
<a-menu-item key="middle">
|
||||||
|
{{ t('common.size.middle') }}
|
||||||
|
</a-menu-item>
|
||||||
|
<a-menu-item key="small">
|
||||||
|
{{ t('common.size.small') }}
|
||||||
|
</a-menu-item>
|
||||||
|
</a-menu>
|
||||||
|
</template>
|
||||||
|
</a-dropdown>
|
||||||
|
</a-tooltip>
|
||||||
|
</a-space>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 表格列表 -->
|
||||||
|
<a-table
|
||||||
|
class="table"
|
||||||
|
row-key="id"
|
||||||
|
:columns="tableColumns"
|
||||||
|
:loading="tableState.loading"
|
||||||
|
:data-source="tableState.data"
|
||||||
|
:size="tableState.size"
|
||||||
|
:pagination="tablePagination"
|
||||||
|
:scroll="{ x: tableColumns.length * 120 }"
|
||||||
|
:row-selection="{
|
||||||
|
type: 'checkbox',
|
||||||
|
selectedRowKeys: tableState.selectedRowKeys,
|
||||||
|
onChange: fnTableSelectedRowKeys,
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<template #bodyCell="{ column, record }">
|
||||||
|
<template v-if="column.key === 'id'">
|
||||||
|
<a-space :size="8" align="center">
|
||||||
|
<a-tooltip>
|
||||||
|
<template #title>{{ t('common.editText') }}</template>
|
||||||
|
<a-button
|
||||||
|
type="link"
|
||||||
|
@click.prevent="fnModalVisibleByEdit(record)"
|
||||||
|
>
|
||||||
|
<template #icon><FormOutlined /></template>
|
||||||
|
</a-button>
|
||||||
|
</a-tooltip>
|
||||||
|
<a-tooltip>
|
||||||
|
<template #title>{{ t('common.deleteText') }}</template>
|
||||||
|
<a-button
|
||||||
|
type="link"
|
||||||
|
@click.prevent="fnRecordDelete(record.id)"
|
||||||
|
>
|
||||||
|
<template #icon><DeleteOutlined /></template>
|
||||||
|
</a-button>
|
||||||
|
</a-tooltip>
|
||||||
|
<a-button type="link" @click.prevent="fnJumpCore(record)">
|
||||||
|
<template #icon><SettingOutlined /></template>
|
||||||
|
核心网管理
|
||||||
|
</a-button>
|
||||||
|
</a-space>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
</a-table>
|
||||||
|
</a-card>
|
||||||
|
|
||||||
|
<!-- 新增框或修改框 -->
|
||||||
|
<ProModal
|
||||||
|
:drag="true"
|
||||||
|
:width="800"
|
||||||
|
:destroyOnClose="true"
|
||||||
|
:keyboard="false"
|
||||||
|
:mask-closable="false"
|
||||||
|
:open="modalState.openByEdit"
|
||||||
|
:title="modalState.title"
|
||||||
|
:confirm-loading="modalState.confirmLoading"
|
||||||
|
@ok="fnModalOk"
|
||||||
|
@cancel="fnModalCancel"
|
||||||
|
>
|
||||||
|
<a-form
|
||||||
|
name="modalStateFrom"
|
||||||
|
layout="horizontal"
|
||||||
|
:label-col="{ span: 6 }"
|
||||||
|
:label-wrap="true"
|
||||||
|
>
|
||||||
|
<a-row>
|
||||||
|
<a-col :lg="12" :md="12" :xs="24">
|
||||||
|
<a-form-item
|
||||||
|
label="Name"
|
||||||
|
name="name"
|
||||||
|
v-bind="modalStateFrom.validateInfos.name"
|
||||||
|
>
|
||||||
|
<a-input
|
||||||
|
v-model:value="modalState.from.name"
|
||||||
|
allow-clear
|
||||||
|
:placeholder="t('common.inputPlease')"
|
||||||
|
></a-input>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :lg="12" :md="12" :xs="24">
|
||||||
|
<a-form-item
|
||||||
|
label="SN"
|
||||||
|
name="sn"
|
||||||
|
v-bind="modalStateFrom.validateInfos.sn"
|
||||||
|
>
|
||||||
|
<a-input
|
||||||
|
v-model:value="modalState.from.sn"
|
||||||
|
allow-clear
|
||||||
|
:maxlength="8"
|
||||||
|
:placeholder="t('common.inputPlease')"
|
||||||
|
></a-input>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</a-form>
|
||||||
|
</ProModal>
|
||||||
|
</PageContainer>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.table :deep(.ant-pagination) {
|
||||||
|
padding: 0 24px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
18
src/views/core/overview/index.vue
Normal file
18
src/views/core/overview/index.vue
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { onMounted } from 'vue';
|
||||||
|
import { PageContainer } from 'antdv-pro-layout';
|
||||||
|
|
||||||
|
onMounted(() => {});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<PageContainer>
|
||||||
|
<a-card :bordered="false" :body-style="{ padding: '0px' }">
|
||||||
|
<h1>概览</h1>
|
||||||
|
|
||||||
|
告警数 网元数 拓扑图
|
||||||
|
</a-card>
|
||||||
|
</PageContainer>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="less" scoped></style>
|
||||||
@@ -15,7 +15,7 @@ import {
|
|||||||
delCoreInfo,
|
delCoreInfo,
|
||||||
listCoreInfo,
|
listCoreInfo,
|
||||||
updateCoreInfo,
|
updateCoreInfo,
|
||||||
} from '@/api/core/coreInfo';
|
} from '@/api/ne_core/coreInfo';
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const { getDict } = useDictStore();
|
const { getDict } = useDictStore();
|
||||||
const neStore = useNeStore();
|
const neStore = useNeStore();
|
||||||
|
|||||||
367
src/views/ne/info/components/BackConfModal.vue
Normal file
367
src/views/ne/info/components/BackConfModal.vue
Normal file
@@ -0,0 +1,367 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { reactive, toRaw, watch } from 'vue';
|
||||||
|
import { ProModal } from 'antdv-pro-modal';
|
||||||
|
import { Form, Modal, Upload, message, notification } from 'ant-design-vue/es';
|
||||||
|
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
||||||
|
import { UploadRequestOption } from 'ant-design-vue/es/vc-upload/interface';
|
||||||
|
import { FileType, UploadFile } from 'ant-design-vue/es/upload/interface';
|
||||||
|
import {
|
||||||
|
exportNeConfigBackup,
|
||||||
|
importNeConfigBackup,
|
||||||
|
listNeConfigBackup,
|
||||||
|
} from '@/api/ne/neConfigBackup';
|
||||||
|
import saveAs from 'file-saver';
|
||||||
|
import { uploadFile } from '@/api/tool/file';
|
||||||
|
import useI18n from '@/hooks/useI18n';
|
||||||
|
const { t } = useI18n();
|
||||||
|
const emit = defineEmits(['ok', 'cancel', 'update:open']);
|
||||||
|
const props = defineProps({
|
||||||
|
open: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
neUid: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
neType: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
/**导入状态数据 */
|
||||||
|
const importState = reactive({
|
||||||
|
typeOption: [
|
||||||
|
{ label: t('views.ne.neInfo.backConf.server'), value: 'backup' },
|
||||||
|
{ label: t('views.ne.neInfo.backConf.local'), value: 'upload' },
|
||||||
|
],
|
||||||
|
backupData: <any[]>[],
|
||||||
|
});
|
||||||
|
|
||||||
|
/**查询网元远程服务器备份文件 */
|
||||||
|
function backupSearch(name?: string) {
|
||||||
|
const { neType, neUid } = props;
|
||||||
|
listNeConfigBackup({
|
||||||
|
neType,
|
||||||
|
neUid,
|
||||||
|
name,
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 20,
|
||||||
|
}).then(res => {
|
||||||
|
if (res.code === RESULT_CODE_SUCCESS) {
|
||||||
|
importState.backupData = [];
|
||||||
|
res.data.rows.forEach((item: any) => {
|
||||||
|
importState.backupData.push({
|
||||||
|
label: item.name,
|
||||||
|
value: item.path,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**服务器备份文件选择切换 */
|
||||||
|
function backupChange(value: any) {
|
||||||
|
if (!value) {
|
||||||
|
backupSearch();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**类型切换 */
|
||||||
|
function typeChange(value: any) {
|
||||||
|
modalState.from.path = undefined;
|
||||||
|
if (value === 'backup') {
|
||||||
|
backupSearch();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**对话框对象信息状态类型 */
|
||||||
|
type ModalStateType = {
|
||||||
|
/**新增框或修改框是否显示 */
|
||||||
|
openByEdit: boolean;
|
||||||
|
/**标题 */
|
||||||
|
title: string;
|
||||||
|
/**表单数据 */
|
||||||
|
from: {
|
||||||
|
neType: string;
|
||||||
|
neUid: string;
|
||||||
|
type: 'upload' | 'backup';
|
||||||
|
path: string | undefined;
|
||||||
|
};
|
||||||
|
/**确定按钮 loading */
|
||||||
|
confirmLoading: boolean;
|
||||||
|
/**上传文件 */
|
||||||
|
uploadFiles: any[];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**对话框对象信息状态 */
|
||||||
|
let modalState: ModalStateType = reactive({
|
||||||
|
openByEdit: false,
|
||||||
|
title: '配置文件导入',
|
||||||
|
from: {
|
||||||
|
neType: '',
|
||||||
|
neUid: '',
|
||||||
|
type: 'upload',
|
||||||
|
path: undefined,
|
||||||
|
},
|
||||||
|
confirmLoading: false,
|
||||||
|
uploadFiles: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
/**对话框内表单属性和校验规则 */
|
||||||
|
const modalStateFrom = Form.useForm(
|
||||||
|
modalState.from,
|
||||||
|
reactive({
|
||||||
|
path: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: t('views.ne.neInfo.backConf.pathPlease'),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对话框弹出确认执行函数
|
||||||
|
* 进行表达规则校验
|
||||||
|
*/
|
||||||
|
function fnModalOk() {
|
||||||
|
if (modalState.confirmLoading) return;
|
||||||
|
const from = toRaw(modalState.from);
|
||||||
|
modalStateFrom
|
||||||
|
.validate()
|
||||||
|
.then(e => {
|
||||||
|
modalState.confirmLoading = true;
|
||||||
|
const hide = message.loading(t('common.loading'), 0);
|
||||||
|
importNeConfigBackup(from)
|
||||||
|
.then(res => {
|
||||||
|
if (res.code === RESULT_CODE_SUCCESS) {
|
||||||
|
message.success(t('common.operateOk'), 3);
|
||||||
|
// 返回无引用信息
|
||||||
|
emit('ok', JSON.parse(JSON.stringify(from)));
|
||||||
|
fnModalCancel();
|
||||||
|
} else {
|
||||||
|
message.error({
|
||||||
|
content: `${res.msg}`,
|
||||||
|
duration: 3,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
hide();
|
||||||
|
modalState.confirmLoading = false;
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(e => {
|
||||||
|
message.error(t('common.errorFields', { num: e.errorFields.length }), 3);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对话框弹出关闭执行函数
|
||||||
|
* 进行表达规则校验
|
||||||
|
*/
|
||||||
|
function fnModalCancel() {
|
||||||
|
modalState.openByEdit = false;
|
||||||
|
modalState.confirmLoading = false;
|
||||||
|
modalStateFrom.resetFields();
|
||||||
|
modalState.uploadFiles = [];
|
||||||
|
emit('cancel');
|
||||||
|
emit('update:open', false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**表单上传前删除 */
|
||||||
|
function fnBeforeRemoveFile(file: UploadFile) {
|
||||||
|
modalState.from.path = undefined;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**表单上传前检查或转换压缩 */
|
||||||
|
function fnBeforeUploadFile(file: FileType) {
|
||||||
|
if (modalState.confirmLoading) return false;
|
||||||
|
if (!file.name.endsWith('.zip')) {
|
||||||
|
const msg = `${t('components.UploadModal.onlyAllow')} .zip`;
|
||||||
|
message.error(msg, 3);
|
||||||
|
return Upload.LIST_IGNORE;
|
||||||
|
}
|
||||||
|
const isLt3M = file.size / 1024 / 1024 < 100;
|
||||||
|
if (!isLt3M) {
|
||||||
|
const msg = `${t('components.UploadModal.allowFilter')} 100MB`;
|
||||||
|
message.error(msg, 3);
|
||||||
|
return Upload.LIST_IGNORE;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**表单上传文件 */
|
||||||
|
function fnUploadFile(up: UploadRequestOption) {
|
||||||
|
// 发送请求
|
||||||
|
const hide = message.loading(t('common.loading'), 0);
|
||||||
|
modalState.confirmLoading = true;
|
||||||
|
let formData = new FormData();
|
||||||
|
formData.append('file', up.file);
|
||||||
|
formData.append('subPath', 'import');
|
||||||
|
uploadFile(formData)
|
||||||
|
.then(res => {
|
||||||
|
if (res.code === RESULT_CODE_SUCCESS) {
|
||||||
|
// 改为完成状态
|
||||||
|
const file = modalState.uploadFiles[0];
|
||||||
|
file.percent = 100;
|
||||||
|
file.status = 'done';
|
||||||
|
// 预置到表单
|
||||||
|
modalState.from.path = res.data.filePath;
|
||||||
|
} else {
|
||||||
|
message.error(res.msg, 3);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
hide();
|
||||||
|
modalState.confirmLoading = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**监听是否显示,初始数据 */
|
||||||
|
watch(
|
||||||
|
() => props.open,
|
||||||
|
val => {
|
||||||
|
if (val) {
|
||||||
|
if (props.neType && props.neUid) {
|
||||||
|
modalState.from.neType = props.neType;
|
||||||
|
modalState.from.neUid = props.neUid;
|
||||||
|
modalState.title = t('views.ne.neInfo.backConf.title');
|
||||||
|
modalState.openByEdit = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 网元导出配置
|
||||||
|
* @param row 网元编号ID
|
||||||
|
*/
|
||||||
|
function fnExportConf(neUid: string, neType: string) {
|
||||||
|
Modal.confirm({
|
||||||
|
title: t('common.tipTitle'),
|
||||||
|
content: t('views.ne.neInfo.backConf.exportTip'),
|
||||||
|
onOk() {
|
||||||
|
const hide = message.loading(t('common.loading'), 0);
|
||||||
|
exportNeConfigBackup({ neType, neUid })
|
||||||
|
.then(res => {
|
||||||
|
if (res.code === RESULT_CODE_SUCCESS) {
|
||||||
|
notification.success({
|
||||||
|
message: t('common.tipTitle'),
|
||||||
|
description: t('views.ne.neInfo.backConf.exportMsg'),
|
||||||
|
});
|
||||||
|
saveAs(
|
||||||
|
res.data,
|
||||||
|
`${neType}_${neUid}_config_backup_${Date.now()}.zip`
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
message.error(`${res.msg}`, 3);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
hide();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 给组件设置属性 ref="xxxBackConf"
|
||||||
|
// setup内使用 const xxxBackConf = ref();
|
||||||
|
defineExpose({
|
||||||
|
/**导出文件 */
|
||||||
|
exportConf: fnExportConf,
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<ProModal
|
||||||
|
:drag="true"
|
||||||
|
:width="500"
|
||||||
|
:keyboard="false"
|
||||||
|
:mask-closable="false"
|
||||||
|
:open="modalState.openByEdit"
|
||||||
|
:title="modalState.title"
|
||||||
|
:confirm-loading="modalState.confirmLoading"
|
||||||
|
@ok="fnModalOk"
|
||||||
|
@cancel="fnModalCancel"
|
||||||
|
>
|
||||||
|
<a-form name="modalStateFrom" layout="horizontal" :label-col="{ span: 6 }">
|
||||||
|
<a-form-item :label="t('views.ne.common.neType')" name="neType">
|
||||||
|
{{ modalState.from.neType }}
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item :label="t('views.ne.common.neUid')" name="neId">
|
||||||
|
{{ modalState.from.neUid }}
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.ne.neInfo.backConf.importType')"
|
||||||
|
name="type"
|
||||||
|
>
|
||||||
|
<a-select
|
||||||
|
v-model:value="modalState.from.type"
|
||||||
|
default-value="server"
|
||||||
|
:options="importState.typeOption"
|
||||||
|
@change="typeChange"
|
||||||
|
>
|
||||||
|
</a-select>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.ne.neInfo.backConf.server')"
|
||||||
|
name="fileName"
|
||||||
|
v-bind="modalStateFrom.validateInfos.path"
|
||||||
|
v-if="modalState.from.type === 'backup'"
|
||||||
|
>
|
||||||
|
<a-select
|
||||||
|
v-model:value="modalState.from.path"
|
||||||
|
:options="importState.backupData"
|
||||||
|
:placeholder="t('common.selectPlease')"
|
||||||
|
:show-search="true"
|
||||||
|
:default-active-first-option="false"
|
||||||
|
:show-arrow="false"
|
||||||
|
:allow-clear="true"
|
||||||
|
:filter-option="false"
|
||||||
|
:not-found-content="null"
|
||||||
|
@search="backupSearch"
|
||||||
|
@change="backupChange"
|
||||||
|
>
|
||||||
|
</a-select>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.ne.neInfo.backConf.local')"
|
||||||
|
name="file"
|
||||||
|
v-bind="modalStateFrom.validateInfos.path"
|
||||||
|
v-if="modalState.from.type === 'upload'"
|
||||||
|
>
|
||||||
|
<a-upload
|
||||||
|
name="file"
|
||||||
|
v-model:file-list="modalState.uploadFiles"
|
||||||
|
accept=".zip"
|
||||||
|
list-type="text"
|
||||||
|
:max-count="1"
|
||||||
|
:show-upload-list="{
|
||||||
|
showPreviewIcon: false,
|
||||||
|
showRemoveIcon: true,
|
||||||
|
showDownloadIcon: false,
|
||||||
|
}"
|
||||||
|
@remove="fnBeforeRemoveFile"
|
||||||
|
:before-upload="fnBeforeUploadFile"
|
||||||
|
:custom-request="fnUploadFile"
|
||||||
|
:disabled="modalState.confirmLoading"
|
||||||
|
>
|
||||||
|
<a-button type="primary">
|
||||||
|
<template #icon>
|
||||||
|
<UploadOutlined />
|
||||||
|
</template>
|
||||||
|
{{ t('views.ne.neInfo.backConf.localUpload') }}
|
||||||
|
</a-button>
|
||||||
|
</a-upload>
|
||||||
|
</a-form-item>
|
||||||
|
</a-form>
|
||||||
|
</ProModal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="less" scoped></style>
|
||||||
184
src/views/ne/info/components/CoreModal.vue
Normal file
184
src/views/ne/info/components/CoreModal.vue
Normal file
@@ -0,0 +1,184 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { reactive, toRaw, watch } from 'vue';
|
||||||
|
import { ProModal } from 'antdv-pro-modal';
|
||||||
|
import { message, Form } from 'ant-design-vue/es';
|
||||||
|
import useI18n from '@/hooks/useI18n';
|
||||||
|
import useCoreStore from '@/store/modules/core';
|
||||||
|
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
||||||
|
import { changeNeCore } from '@/api/ne/neInfo';
|
||||||
|
const { t } = useI18n();
|
||||||
|
const coreStore = useCoreStore();
|
||||||
|
const emit = defineEmits(['ok', 'cancel', 'update:open']);
|
||||||
|
const props = defineProps({
|
||||||
|
open: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
neUid: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
coreUid: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
/**对话框对象信息状态类型 */
|
||||||
|
type ModalStateType = {
|
||||||
|
/**新增框或修改框是否显示 */
|
||||||
|
openByEdit: boolean;
|
||||||
|
/**标题 */
|
||||||
|
title: string;
|
||||||
|
/**表单数据 */
|
||||||
|
from: Record<string, any>;
|
||||||
|
/**确定按钮 loading */
|
||||||
|
confirmLoading: boolean;
|
||||||
|
/**关联或移除 */
|
||||||
|
select: 'Associated' | 'Removed';
|
||||||
|
};
|
||||||
|
|
||||||
|
/**对话框对象信息状态 */
|
||||||
|
let modalState: ModalStateType = reactive({
|
||||||
|
openByEdit: false,
|
||||||
|
title: 'Associated Core',
|
||||||
|
from: {
|
||||||
|
neUid: '',
|
||||||
|
coreUid: '',
|
||||||
|
},
|
||||||
|
confirmLoading: false,
|
||||||
|
select: 'Associated',
|
||||||
|
});
|
||||||
|
|
||||||
|
/**对话框内表单属性和校验规则 */
|
||||||
|
const modalStateFrom = Form.useForm(
|
||||||
|
modalState.from,
|
||||||
|
reactive({
|
||||||
|
coreUid: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: t('views.ne.neInfo.oam.kpiTimerPlease'),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对话框弹出显示为 新增或者修改
|
||||||
|
*/
|
||||||
|
function fnModalVisible() {
|
||||||
|
const hide = message.loading(t('common.loading'), 0);
|
||||||
|
modalState.from.neUid = props.neUid;
|
||||||
|
modalState.from.coreUid = props.coreUid;
|
||||||
|
modalState.openByEdit = true;
|
||||||
|
modalState.confirmLoading = false;
|
||||||
|
hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对话框弹出确认执行函数
|
||||||
|
* 进行表达规则校验
|
||||||
|
*/
|
||||||
|
function fnModalOk() {
|
||||||
|
modalStateFrom
|
||||||
|
.validate()
|
||||||
|
.then(e => {
|
||||||
|
modalState.confirmLoading = true;
|
||||||
|
const hide = message.loading(t('common.loading'), 0);
|
||||||
|
const from = toRaw(modalState.from);
|
||||||
|
if (modalState.select === 'Removed') {
|
||||||
|
from.coreUid = '#';
|
||||||
|
}
|
||||||
|
changeNeCore(from)
|
||||||
|
.then(res => {
|
||||||
|
if (res.code === RESULT_CODE_SUCCESS) {
|
||||||
|
message.success(t('common.operateOk'), 3);
|
||||||
|
emit('ok');
|
||||||
|
fnModalCancel();
|
||||||
|
} else {
|
||||||
|
message.error({
|
||||||
|
content: `${res.msg}`,
|
||||||
|
duration: 3,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
hide();
|
||||||
|
modalState.confirmLoading = false;
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(e => {
|
||||||
|
message.error(t('common.errorFields', { num: e.errorFields.length }), 3);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对话框弹出关闭执行函数
|
||||||
|
* 进行表达规则校验
|
||||||
|
*/
|
||||||
|
function fnModalCancel() {
|
||||||
|
modalState.openByEdit = false;
|
||||||
|
modalState.confirmLoading = false;
|
||||||
|
modalStateFrom.resetFields();
|
||||||
|
emit('cancel');
|
||||||
|
emit('update:open', false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**监听是否显示,初始数据 */
|
||||||
|
watch(
|
||||||
|
() => props.open,
|
||||||
|
val => {
|
||||||
|
console.log('CoreModal open', val, props.neUid, props.coreUid);
|
||||||
|
if (val && props.neUid) {
|
||||||
|
fnModalVisible();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<ProModal
|
||||||
|
:drag="true"
|
||||||
|
:destroyOnClose="true"
|
||||||
|
:body-style="{ maxHeight: '600px', 'overflow-y': 'auto' }"
|
||||||
|
:keyboard="false"
|
||||||
|
:mask-closable="false"
|
||||||
|
:open="modalState.openByEdit"
|
||||||
|
:title="modalState.title"
|
||||||
|
:confirm-loading="modalState.confirmLoading"
|
||||||
|
@ok="fnModalOk"
|
||||||
|
@cancel="fnModalCancel"
|
||||||
|
>
|
||||||
|
<a-form
|
||||||
|
name="modalStateFrom"
|
||||||
|
layout="horizontal"
|
||||||
|
:label-col="{ span: 12 }"
|
||||||
|
:labelWrap="true"
|
||||||
|
>
|
||||||
|
<a-segmented
|
||||||
|
v-model:value="modalState.select"
|
||||||
|
:options="['Associated', 'Removed']"
|
||||||
|
/>
|
||||||
|
<a-form-item
|
||||||
|
v-if="modalState.select === 'Associated'"
|
||||||
|
label="Select Core"
|
||||||
|
name="coreUid"
|
||||||
|
:label-col="{ span: 6 }"
|
||||||
|
:labelWrap="true"
|
||||||
|
v-bind="modalStateFrom.validateInfos.coreUid"
|
||||||
|
>
|
||||||
|
<a-select
|
||||||
|
v-model:value="modalState.from.coreUid"
|
||||||
|
:options="coreStore.coreSelectOtions"
|
||||||
|
:placeholder="t('common.selectPlease')"
|
||||||
|
>
|
||||||
|
</a-select>
|
||||||
|
</a-form-item>
|
||||||
|
</a-form>
|
||||||
|
</ProModal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="less" scoped></style>
|
||||||
761
src/views/ne/info/components/EditModal.vue
Normal file
761
src/views/ne/info/components/EditModal.vue
Normal file
@@ -0,0 +1,761 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { reactive, onMounted, toRaw, watch } from 'vue';
|
||||||
|
import { ProModal } from 'antdv-pro-modal';
|
||||||
|
import { message, Form, Modal } from 'ant-design-vue/es';
|
||||||
|
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
||||||
|
import { NE_TYPE_LIST } from '@/constants/ne-constants';
|
||||||
|
import { regExpIPv4, regExpIPv6 } from '@/utils/regular-utils';
|
||||||
|
import { addNeInfo, updateNeInfo, getNeInfo } from '@/api/ne/neInfo';
|
||||||
|
import { neHostAuthorizedRSA, testNeHost } from '@/api/ne/neHost';
|
||||||
|
import useDictStore from '@/store/modules/dict';
|
||||||
|
import useI18n from '@/hooks/useI18n';
|
||||||
|
const { getDict } = useDictStore();
|
||||||
|
const { t } = useI18n();
|
||||||
|
const emit = defineEmits(['ok', 'cancel', 'update:open']);
|
||||||
|
const props = defineProps({
|
||||||
|
open: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
id: {
|
||||||
|
type: Number,
|
||||||
|
default: 0,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
/**字典数据 */
|
||||||
|
let dict: {
|
||||||
|
/**主机类型 */
|
||||||
|
neHostType: DictType[];
|
||||||
|
/**分组 */
|
||||||
|
neHostGroupId: DictType[];
|
||||||
|
/**认证模式 */
|
||||||
|
neHostAuthMode: DictType[];
|
||||||
|
} = reactive({
|
||||||
|
neHostType: [],
|
||||||
|
neHostGroupId: [],
|
||||||
|
neHostAuthMode: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 测试主机连接
|
||||||
|
*/
|
||||||
|
function fnHostTest(row: Record<string, any>) {
|
||||||
|
if (modalState.confirmLoading || !row.addr || !row.port) return;
|
||||||
|
modalState.confirmLoading = true;
|
||||||
|
const hide = message.loading(t('common.loading'), 0);
|
||||||
|
testNeHost(row)
|
||||||
|
.then(res => {
|
||||||
|
if (res.code === RESULT_CODE_SUCCESS) {
|
||||||
|
message.success({
|
||||||
|
content: `${row.addr}:${row.port} ${t('views.ne.neHost.testOk')}`,
|
||||||
|
duration: 2,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
message.error({
|
||||||
|
content: `${row.addr}:${row.port} ${res.msg}`,
|
||||||
|
duration: 2,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
hide();
|
||||||
|
modalState.confirmLoading = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**测试主机连接-免密直连 */
|
||||||
|
function fnHostAuthorized(row: Record<string, any>) {
|
||||||
|
if (modalState.confirmLoading) return;
|
||||||
|
|
||||||
|
Modal.confirm({
|
||||||
|
title: t('common.tipTitle'),
|
||||||
|
content: t('views.ne.neHost.authRSATip'),
|
||||||
|
onOk: () => {
|
||||||
|
modalState.confirmLoading = true;
|
||||||
|
neHostAuthorizedRSA(row).then(res => {
|
||||||
|
modalState.confirmLoading = false;
|
||||||
|
if (res.code === RESULT_CODE_SUCCESS) {
|
||||||
|
message.success(t('common.operateOk'), 3);
|
||||||
|
} else {
|
||||||
|
message.error(t('common.operateErr'), 3);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**对话框对象信息状态类型 */
|
||||||
|
type ModalStateType = {
|
||||||
|
/**新增框或修改框是否显示 */
|
||||||
|
openByEdit: boolean;
|
||||||
|
/**标题 */
|
||||||
|
title: string;
|
||||||
|
/**表单数据 */
|
||||||
|
from: Record<string, any>;
|
||||||
|
/**确定按钮 loading */
|
||||||
|
confirmLoading: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**对话框对象信息状态 */
|
||||||
|
let modalState: ModalStateType = reactive({
|
||||||
|
openByEdit: false,
|
||||||
|
title: '网元',
|
||||||
|
from: {
|
||||||
|
id: undefined,
|
||||||
|
neType: 'AMF',
|
||||||
|
neName: '',
|
||||||
|
ipAddr: '',
|
||||||
|
port: 33030,
|
||||||
|
pvFlag: 'PNF',
|
||||||
|
neUid: '',
|
||||||
|
macAddr: '',
|
||||||
|
dn: '',
|
||||||
|
vendorName: '',
|
||||||
|
province: 'Area',
|
||||||
|
remark: '',
|
||||||
|
// 主机
|
||||||
|
hosts: [
|
||||||
|
{
|
||||||
|
id: undefined,
|
||||||
|
hostType: 'ssh',
|
||||||
|
groupId: '1',
|
||||||
|
title: 'SSH_NE_22',
|
||||||
|
addr: '',
|
||||||
|
port: 22,
|
||||||
|
user: 'omcuser',
|
||||||
|
authMode: '2',
|
||||||
|
password: '',
|
||||||
|
privateKey: '',
|
||||||
|
passPhrase: '',
|
||||||
|
remark: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: undefined,
|
||||||
|
hostType: 'telnet',
|
||||||
|
groupId: '1',
|
||||||
|
title: 'Telnet_NE_4100',
|
||||||
|
addr: '',
|
||||||
|
port: 4100,
|
||||||
|
user: 'admin',
|
||||||
|
authMode: '0',
|
||||||
|
password: 'admin',
|
||||||
|
remark: '',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
confirmLoading: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
/**对话框内表单属性和校验规则 */
|
||||||
|
const modalStateFrom = Form.useForm(
|
||||||
|
modalState.from,
|
||||||
|
reactive({
|
||||||
|
neType: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: t('views.ne.common.neTypePlease'),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
neName: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: t('views.ne.common.neNamePlease'),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
ipAddr: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
validator: modalStateFromEqualIPV4AndIPV6,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
/**表单验证IP地址是否有效 */
|
||||||
|
function modalStateFromEqualIPV4AndIPV6(
|
||||||
|
rule: Record<string, any>,
|
||||||
|
value: string,
|
||||||
|
callback: (error?: string) => void
|
||||||
|
) {
|
||||||
|
if (!value) {
|
||||||
|
return Promise.reject(t('views.ne.common.ipAddrPlease'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value.indexOf('.') === -1 && value.indexOf(':') === -1) {
|
||||||
|
return Promise.reject(t('valid.ipPlease'));
|
||||||
|
}
|
||||||
|
if (value.indexOf('.') !== -1 && !regExpIPv4.test(value)) {
|
||||||
|
return Promise.reject(t('valid.ipv4Reg'));
|
||||||
|
}
|
||||||
|
if (value.indexOf(':') !== -1 && !regExpIPv6.test(value)) {
|
||||||
|
return Promise.reject(t('valid.ipv6Reg'));
|
||||||
|
}
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对话框弹出显示为 新增或者修改
|
||||||
|
* @param id 网元ID
|
||||||
|
*/
|
||||||
|
function fnModalVisibleByEdit(id: number) {
|
||||||
|
if (!id) {
|
||||||
|
modalStateFrom.resetFields();
|
||||||
|
modalState.title = t('views.ne.neInfo.addTitle');
|
||||||
|
modalState.openByEdit = true;
|
||||||
|
} else {
|
||||||
|
if (modalState.confirmLoading) return;
|
||||||
|
const hide = message.loading(t('common.loading'), 0);
|
||||||
|
modalState.confirmLoading = true;
|
||||||
|
getNeInfo(id).then(res => {
|
||||||
|
modalState.confirmLoading = false;
|
||||||
|
hide();
|
||||||
|
if (res.code === RESULT_CODE_SUCCESS) {
|
||||||
|
Object.assign(modalState.from, res.data);
|
||||||
|
modalState.title = t('views.ne.neInfo.editTitle');
|
||||||
|
modalState.openByEdit = true;
|
||||||
|
} else {
|
||||||
|
message.error(t('common.getInfoFail'), 2);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对话框弹出确认执行函数
|
||||||
|
* 进行表达规则校验
|
||||||
|
*/
|
||||||
|
function fnModalOk() {
|
||||||
|
modalStateFrom
|
||||||
|
.validate()
|
||||||
|
.then(e => {
|
||||||
|
modalState.confirmLoading = true;
|
||||||
|
const from = toRaw(modalState.from);
|
||||||
|
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(t('common.operateOk'), 3);
|
||||||
|
// 返回无引用信息
|
||||||
|
emit('ok', JSON.parse(JSON.stringify(from)));
|
||||||
|
fnModalCancel();
|
||||||
|
} else {
|
||||||
|
message.error({
|
||||||
|
content: `${res.msg}`,
|
||||||
|
duration: 3,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
hide();
|
||||||
|
modalState.confirmLoading = false;
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(e => {
|
||||||
|
message.error(t('common.errorFields', { num: e.errorFields.length }), 3);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对话框弹出关闭执行函数
|
||||||
|
* 进行表达规则校验
|
||||||
|
*/
|
||||||
|
function fnModalCancel() {
|
||||||
|
modalState.openByEdit = false;
|
||||||
|
modalState.confirmLoading = false;
|
||||||
|
modalStateFrom.resetFields();
|
||||||
|
emit('cancel');
|
||||||
|
emit('update:open', false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**表单修改网元类型 */
|
||||||
|
function fnNeTypeChange(v: any) {
|
||||||
|
// 网元默认只含22和4100
|
||||||
|
if (modalState.from.hosts.length === 3) {
|
||||||
|
modalState.from.hosts.pop();
|
||||||
|
}
|
||||||
|
const hostsLen = modalState.from.hosts.length;
|
||||||
|
// UPF标准版本可支持5002
|
||||||
|
if (hostsLen === 2 && v === 'UPF') {
|
||||||
|
modalState.from.hosts.push({
|
||||||
|
id: undefined,
|
||||||
|
hostType: 'telnet',
|
||||||
|
groupId: '1',
|
||||||
|
title: 'Telnet_NE_5002',
|
||||||
|
addr: modalState.from.ip,
|
||||||
|
port: 5002,
|
||||||
|
user: 'admin',
|
||||||
|
authMode: '0',
|
||||||
|
password: 'admin',
|
||||||
|
remark: '',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// UDM可支持6379
|
||||||
|
if (hostsLen === 2 && v === 'UDM') {
|
||||||
|
modalState.from.hosts.push({
|
||||||
|
id: undefined,
|
||||||
|
hostType: 'redis',
|
||||||
|
groupId: '1',
|
||||||
|
title: 'REDIS_NE_6379',
|
||||||
|
addr: modalState.from.ip,
|
||||||
|
port: 6379,
|
||||||
|
user: 'udmdb',
|
||||||
|
authMode: '0',
|
||||||
|
password: 'helloearth',
|
||||||
|
dbName: '0',
|
||||||
|
remark: '',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**表单修改网元IP */
|
||||||
|
function fnNeIPChange(e: any) {
|
||||||
|
const v = e.target.value;
|
||||||
|
if (v.length < 7) return;
|
||||||
|
for (const host of modalState.from.hosts) {
|
||||||
|
host.addr = v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**监听是否显示,初始数据 */
|
||||||
|
watch(
|
||||||
|
() => props.open,
|
||||||
|
val => {
|
||||||
|
if (val) fnModalVisibleByEdit(props.id);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
// 初始字典数据
|
||||||
|
Promise.allSettled([
|
||||||
|
getDict('ne_host_type'),
|
||||||
|
getDict('ne_host_groupId'),
|
||||||
|
getDict('ne_host_authMode'),
|
||||||
|
]).then(resArr => {
|
||||||
|
if (resArr[0].status === 'fulfilled') {
|
||||||
|
dict.neHostType = resArr[0].value;
|
||||||
|
}
|
||||||
|
if (resArr[1].status === 'fulfilled') {
|
||||||
|
dict.neHostGroupId = resArr[1].value;
|
||||||
|
}
|
||||||
|
if (resArr[2].status === 'fulfilled') {
|
||||||
|
dict.neHostAuthMode = resArr[2].value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<ProModal
|
||||||
|
:drag="true"
|
||||||
|
:width="800"
|
||||||
|
:destroyOnClose="true"
|
||||||
|
:body-style="{ maxHeight: '600px', 'overflow-y': 'auto' }"
|
||||||
|
:keyboard="false"
|
||||||
|
:mask-closable="false"
|
||||||
|
:open="modalState.openByEdit"
|
||||||
|
:title="modalState.title"
|
||||||
|
:confirm-loading="modalState.confirmLoading"
|
||||||
|
@ok="fnModalOk"
|
||||||
|
@cancel="fnModalCancel"
|
||||||
|
>
|
||||||
|
<a-form
|
||||||
|
name="modalStateFrom"
|
||||||
|
layout="horizontal"
|
||||||
|
:label-col="{ span: 6 }"
|
||||||
|
:labelWrap="true"
|
||||||
|
>
|
||||||
|
<a-row>
|
||||||
|
<a-col :lg="12" :md="12" :xs="24">
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.ne.common.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 }))"
|
||||||
|
@change="fnNeTypeChange"
|
||||||
|
:disabled="!!modalState.from.id"
|
||||||
|
>
|
||||||
|
<a-input
|
||||||
|
allow-clear
|
||||||
|
:placeholder="t('common.inputPlease')"
|
||||||
|
:maxlength="32"
|
||||||
|
>
|
||||||
|
<template #prefix>
|
||||||
|
<a-tooltip placement="topLeft">
|
||||||
|
<template #title>
|
||||||
|
{{ t('views.ne.common.neTypeTip') }}
|
||||||
|
</template>
|
||||||
|
<InfoCircleOutlined style="opacity: 0.45; color: inherit" />
|
||||||
|
</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.ne.neInfo.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.ne.neInfo.pnf')">
|
||||||
|
<a-select-option value="PNF">PNF</a-select-option>
|
||||||
|
</a-select-opt-group>
|
||||||
|
<a-select-opt-group :label="t('views.ne.neInfo.vnf')">
|
||||||
|
<a-select-option value="VNF">VNF</a-select-option>
|
||||||
|
</a-select-opt-group>
|
||||||
|
</a-select>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.ne.common.neName')"
|
||||||
|
name="neName"
|
||||||
|
:label-col="{ span: 3 }"
|
||||||
|
:label-wrap="true"
|
||||||
|
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-row>
|
||||||
|
<a-col :lg="12" :md="12" :xs="24">
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.ne.common.ipAddr')"
|
||||||
|
name="ipAddr"
|
||||||
|
v-bind="modalStateFrom.validateInfos.ipAddr"
|
||||||
|
>
|
||||||
|
<a-input
|
||||||
|
v-model:value="modalState.from.ipAddr"
|
||||||
|
allow-clear
|
||||||
|
:placeholder="t('common.inputPlease')"
|
||||||
|
:maxlength="128"
|
||||||
|
@change="fnNeIPChange"
|
||||||
|
>
|
||||||
|
<template #prefix>
|
||||||
|
<a-tooltip placement="topLeft">
|
||||||
|
<template #title>
|
||||||
|
<div>
|
||||||
|
{{ t('views.ne.common.ipAddrTip') }}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<InfoCircleOutlined style="opacity: 0.45; color: inherit" />
|
||||||
|
</a-tooltip>
|
||||||
|
</template>
|
||||||
|
</a-input>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :lg="12" :md="12" :xs="24">
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.ne.common.port')"
|
||||||
|
name="port"
|
||||||
|
v-bind="modalStateFrom.validateInfos.port"
|
||||||
|
>
|
||||||
|
<a-input-number
|
||||||
|
v-model:value="modalState.from.port"
|
||||||
|
style="width: 100%"
|
||||||
|
:min="1"
|
||||||
|
:max="65535"
|
||||||
|
:maxlength="5"
|
||||||
|
placeholder="<=65535"
|
||||||
|
>
|
||||||
|
<template #prefix>
|
||||||
|
<a-tooltip placement="topLeft">
|
||||||
|
<template #title>
|
||||||
|
<div>{{ t('views.ne.common.portTip') }}</div>
|
||||||
|
</template>
|
||||||
|
<InfoCircleOutlined style="opacity: 0.45; color: inherit" />
|
||||||
|
</a-tooltip>
|
||||||
|
</template>
|
||||||
|
</a-input-number>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
|
||||||
|
<a-row>
|
||||||
|
<a-col :lg="12" :md="12" :xs="24">
|
||||||
|
<a-form-item :label="t('views.ne.neInfo.macAddr')" name="macAddr">
|
||||||
|
<a-input
|
||||||
|
v-model:value="modalState.from.macAddr"
|
||||||
|
allow-clear
|
||||||
|
:placeholder="t('common.inputPlease')"
|
||||||
|
:maxlength="64"
|
||||||
|
>
|
||||||
|
<template #prefix>
|
||||||
|
<a-tooltip placement="topLeft">
|
||||||
|
<template #title>
|
||||||
|
<div>{{ t('views.ne.neInfo.macAddrTip') }}</div>
|
||||||
|
</template>
|
||||||
|
<InfoCircleOutlined style="opacity: 0.45; color: inherit" />
|
||||||
|
</a-tooltip>
|
||||||
|
</template>
|
||||||
|
</a-input>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :lg="12" :md="12" :xs="24">
|
||||||
|
<a-form-item :label="t('views.ne.neInfo.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>
|
||||||
|
<a-col :lg="12" :md="12" :xs="24">
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.ne.neInfo.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.ne.neInfo.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
|
||||||
|
:label="t('common.remark')"
|
||||||
|
:label-col="{ span: 3 }"
|
||||||
|
:label-wrap="true"
|
||||||
|
>
|
||||||
|
<a-textarea
|
||||||
|
v-model:value="modalState.from.remark"
|
||||||
|
:auto-size="{ minRows: 1, maxRows: 6 }"
|
||||||
|
:maxlength="450"
|
||||||
|
:show-count="true"
|
||||||
|
:placeholder="t('common.inputPlease')"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<!-- 主机连接配置 -->
|
||||||
|
<a-divider orientation="left">
|
||||||
|
{{ t('views.ne.neInfo.hostConfig') }}
|
||||||
|
</a-divider>
|
||||||
|
<a-collapse class="collapse" ghost>
|
||||||
|
<a-collapse-panel
|
||||||
|
v-for="host in modalState.from.hosts.filter(
|
||||||
|
(s:any) => !(s.hostType === 'telnet' && modalState.from.neType === 'OMC')
|
||||||
|
)"
|
||||||
|
:key="host.title"
|
||||||
|
>
|
||||||
|
<template #header>
|
||||||
|
<span v-if="host.hostType === 'redis'"> DB {{ host.port }} </span>
|
||||||
|
<span v-else>
|
||||||
|
{{ `${host.hostType.toUpperCase()} ${host.port}` }}
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
<a-row>
|
||||||
|
<a-col :lg="12" :md="12" :xs="24">
|
||||||
|
<a-form-item :label="t('views.ne.neHost.addr')">
|
||||||
|
<a-input
|
||||||
|
v-model:value="host.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="neHost.port"
|
||||||
|
>
|
||||||
|
<a-input-number
|
||||||
|
v-model:value="host.port"
|
||||||
|
:min="10"
|
||||||
|
:max="65535"
|
||||||
|
:step="1"
|
||||||
|
:maxlength="5"
|
||||||
|
style="width: 100%"
|
||||||
|
></a-input-number>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
|
||||||
|
<a-form-item
|
||||||
|
v-if="host.hostType === 'telnet'"
|
||||||
|
:label="t('views.ne.neHost.user')"
|
||||||
|
:label-col="{ span: 3 }"
|
||||||
|
:label-wrap="true"
|
||||||
|
>
|
||||||
|
<a-input
|
||||||
|
v-model:value="host.user"
|
||||||
|
allow-clear
|
||||||
|
:maxlength="32"
|
||||||
|
:placeholder="t('common.inputPlease')"
|
||||||
|
>
|
||||||
|
</a-input>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-row v-if="host.hostType === 'ssh'">
|
||||||
|
<a-col :lg="12" :md="12" :xs="24">
|
||||||
|
<a-form-item :label="t('views.ne.neHost.user')">
|
||||||
|
<a-input
|
||||||
|
v-model:value="host.user"
|
||||||
|
allow-clear
|
||||||
|
:maxlength="32"
|
||||||
|
: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="host.authMode"
|
||||||
|
default-value="0"
|
||||||
|
:options="dict.neHostAuthMode"
|
||||||
|
>
|
||||||
|
</a-select>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
|
||||||
|
<a-form-item
|
||||||
|
v-if="host.authMode === '0'"
|
||||||
|
:label="t('views.ne.neHost.password')"
|
||||||
|
:label-col="{ span: 3 }"
|
||||||
|
:label-wrap="true"
|
||||||
|
>
|
||||||
|
<a-input-password
|
||||||
|
v-model:value="host.password"
|
||||||
|
:maxlength="128"
|
||||||
|
:placeholder="t('common.inputPlease')"
|
||||||
|
>
|
||||||
|
</a-input-password>
|
||||||
|
</a-form-item>
|
||||||
|
<template v-if="host.authMode === '1'">
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.ne.neHost.privateKey')"
|
||||||
|
:label-col="{ span: 3 }"
|
||||||
|
:label-wrap="true"
|
||||||
|
>
|
||||||
|
<a-textarea
|
||||||
|
v-model:value="host.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="host.passPhrase"
|
||||||
|
:maxlength="128"
|
||||||
|
:placeholder="t('common.inputPlease')"
|
||||||
|
>
|
||||||
|
</a-input-password>
|
||||||
|
</a-form-item>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<a-form-item
|
||||||
|
v-if="host.hostType === 'mysql'"
|
||||||
|
:label="t('views.ne.neHost.database')"
|
||||||
|
:label-col="{ span: 3 }"
|
||||||
|
:label-wrap="true"
|
||||||
|
>
|
||||||
|
<a-input
|
||||||
|
v-model:value="host.dbName"
|
||||||
|
allow-clear
|
||||||
|
:maxlength="32"
|
||||||
|
:placeholder="t('common.inputPlease')"
|
||||||
|
>
|
||||||
|
</a-input>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item
|
||||||
|
:label="t('common.remark')"
|
||||||
|
:label-col="{ span: 3 }"
|
||||||
|
:label-wrap="true"
|
||||||
|
>
|
||||||
|
<a-textarea
|
||||||
|
v-model:value="host.remark"
|
||||||
|
:auto-size="{ minRows: 1, maxRows: 6 }"
|
||||||
|
:maxlength="450"
|
||||||
|
:show-count="true"
|
||||||
|
:placeholder="t('common.inputPlease')"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<!-- 测试 -->
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.ne.neHost.test')"
|
||||||
|
name="test"
|
||||||
|
:label-col="{ span: 3 }"
|
||||||
|
:label-wrap="true"
|
||||||
|
>
|
||||||
|
<a-button
|
||||||
|
type="primary"
|
||||||
|
shape="round"
|
||||||
|
@click="fnHostTest(host)"
|
||||||
|
:loading="modalState.confirmLoading"
|
||||||
|
>
|
||||||
|
<template #icon><LinkOutlined /></template>
|
||||||
|
</a-button>
|
||||||
|
|
||||||
|
<a-button
|
||||||
|
type="link"
|
||||||
|
@click="fnHostAuthorized(host)"
|
||||||
|
:loading="modalState.confirmLoading"
|
||||||
|
v-if="host.hostType === 'ssh' && host.authMode !== '2'"
|
||||||
|
>
|
||||||
|
{{ t('views.ne.neHost.authRSA') }}
|
||||||
|
</a-button>
|
||||||
|
</a-form-item>
|
||||||
|
</a-collapse-panel>
|
||||||
|
</a-collapse>
|
||||||
|
</a-form>
|
||||||
|
</ProModal>
|
||||||
|
</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>
|
||||||
357
src/views/ne/info/components/LicenseEditModal.vue
Normal file
357
src/views/ne/info/components/LicenseEditModal.vue
Normal file
@@ -0,0 +1,357 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { reactive, onMounted, toRaw, watch } from 'vue';
|
||||||
|
import { ProModal } from 'antdv-pro-modal';
|
||||||
|
import { Form, Modal, Upload, message } from 'ant-design-vue/es';
|
||||||
|
import useI18n from '@/hooks/useI18n';
|
||||||
|
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
||||||
|
import { UploadRequestOption } from 'ant-design-vue/es/vc-upload/interface';
|
||||||
|
import { FileType } from 'ant-design-vue/es/upload/interface';
|
||||||
|
import { uploadFile } from '@/api/tool/file';
|
||||||
|
import { useClipboard } from '@vueuse/core';
|
||||||
|
import saveAs from 'file-saver';
|
||||||
|
import { getNeInfo, codeNeLicense, updateNeLicense } from '@/api/ne/neInfo';
|
||||||
|
const { copy } = useClipboard({ legacy: true });
|
||||||
|
const { t } = useI18n();
|
||||||
|
const emit = defineEmits(['ok', 'cancel', 'update:open']);
|
||||||
|
const props = defineProps({
|
||||||
|
open: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
/**网元ID */
|
||||||
|
id: {
|
||||||
|
type: Number,
|
||||||
|
default: 0,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
neUid: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
/**是否重启服务 */
|
||||||
|
reload: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
/**对话框对象信息状态类型 */
|
||||||
|
type ModalStateType = {
|
||||||
|
/**新增框或修改框是否显示 */
|
||||||
|
openByEdit: boolean;
|
||||||
|
/**标题 */
|
||||||
|
title: string;
|
||||||
|
/**表单数据 */
|
||||||
|
from: {
|
||||||
|
id: number | undefined;
|
||||||
|
neType: string;
|
||||||
|
neName: string;
|
||||||
|
neId: string;
|
||||||
|
activationRequestCode: string;
|
||||||
|
licensePath: string;
|
||||||
|
reload: boolean;
|
||||||
|
};
|
||||||
|
/**确定按钮 loading */
|
||||||
|
confirmLoading: boolean;
|
||||||
|
/**上传文件 */
|
||||||
|
uploadFiles: any[];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**对话框对象信息状态 */
|
||||||
|
let modalState: ModalStateType = reactive({
|
||||||
|
openByEdit: false,
|
||||||
|
title: '授权文件',
|
||||||
|
from: {
|
||||||
|
id: undefined,
|
||||||
|
neType: '',
|
||||||
|
neId: '',
|
||||||
|
neName: '',
|
||||||
|
activationRequestCode: '',
|
||||||
|
licensePath: '',
|
||||||
|
reload: false,
|
||||||
|
},
|
||||||
|
confirmLoading: false,
|
||||||
|
uploadFiles: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
/**对话框内表单属性和校验规则 */
|
||||||
|
const modalStateFrom = Form.useForm(
|
||||||
|
modalState.from,
|
||||||
|
reactive({
|
||||||
|
licensePath: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: t('views.ne.neLicense.licensePathTip'),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对话框弹出确认执行函数
|
||||||
|
* 进行表达规则校验
|
||||||
|
*/
|
||||||
|
function fnModalOk() {
|
||||||
|
if (modalState.confirmLoading || !modalState.from.id) return;
|
||||||
|
|
||||||
|
modalStateFrom
|
||||||
|
.validate()
|
||||||
|
.then(e => {
|
||||||
|
modalState.confirmLoading = true;
|
||||||
|
const hide = message.loading(t('common.loading'), 0);
|
||||||
|
const from = toRaw(modalState.from);
|
||||||
|
updateNeLicense(from).then(res => {
|
||||||
|
if (res.code === RESULT_CODE_SUCCESS) {
|
||||||
|
message.success({
|
||||||
|
content: t('common.operateOk'),
|
||||||
|
duration: 3,
|
||||||
|
});
|
||||||
|
// 返回无引用信息
|
||||||
|
emit('ok', JSON.parse(JSON.stringify(from)));
|
||||||
|
fnModalCancel();
|
||||||
|
} else {
|
||||||
|
message.error({
|
||||||
|
content: `${res.msg}`,
|
||||||
|
duration: 3,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
hide();
|
||||||
|
modalState.confirmLoading = false;
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(e => {
|
||||||
|
message.error(t('common.errorFields', { num: e.errorFields.length }), 3);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对话框弹出关闭执行函数
|
||||||
|
* 进行表达规则校验
|
||||||
|
*/
|
||||||
|
function fnModalCancel() {
|
||||||
|
modalState.openByEdit = false;
|
||||||
|
modalState.confirmLoading = false;
|
||||||
|
modalStateFrom.resetFields();
|
||||||
|
modalState.uploadFiles = [];
|
||||||
|
emit('cancel');
|
||||||
|
emit('update:open', false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**表单上传前检查或转换压缩 */
|
||||||
|
function fnBeforeUploadFile(file: FileType) {
|
||||||
|
if (modalState.confirmLoading) return false;
|
||||||
|
if (!file.name.endsWith('.ini')) {
|
||||||
|
const msg = `${t('components.UploadModal.onlyAllow')} .ini`;
|
||||||
|
message.error(msg, 3);
|
||||||
|
return Upload.LIST_IGNORE;
|
||||||
|
}
|
||||||
|
const isLt3M = file.size / 1024 / 1024 < 3;
|
||||||
|
if (!isLt3M) {
|
||||||
|
const msg = `${t('components.UploadModal.allowFilter')} 3MB`;
|
||||||
|
message.error(msg, 3);
|
||||||
|
return Upload.LIST_IGNORE;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**表单上传文件 */
|
||||||
|
function fnUploadFile(up: UploadRequestOption) {
|
||||||
|
// 发送请求
|
||||||
|
const hide = message.loading(t('common.loading'), 0);
|
||||||
|
modalState.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) {
|
||||||
|
// 改为完成状态
|
||||||
|
const file = modalState.uploadFiles[0];
|
||||||
|
file.percent = 100;
|
||||||
|
file.status = 'done';
|
||||||
|
// 预置到表单
|
||||||
|
modalState.from.licensePath = res.data.filePath;
|
||||||
|
} else {
|
||||||
|
message.error(res.msg, 3);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
hide();
|
||||||
|
modalState.confirmLoading = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**复制授权申请码 */
|
||||||
|
function fnCopyCode() {
|
||||||
|
const code = modalState.from.activationRequestCode;
|
||||||
|
if (!code) return;
|
||||||
|
copy(code).then(() => {
|
||||||
|
message.success(t('common.copyOk'), 3);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**下载授权申请码文件 */
|
||||||
|
function fnDownCode() {
|
||||||
|
const { activationRequestCode, neType, neName } = modalState.from;
|
||||||
|
if (!activationRequestCode) return;
|
||||||
|
Modal.confirm({
|
||||||
|
title: t('common.tipTitle'),
|
||||||
|
content: t('views.ne.neLicense.downCodeTop'),
|
||||||
|
onOk() {
|
||||||
|
const blob = new Blob([activationRequestCode], {
|
||||||
|
type: 'text/plain',
|
||||||
|
});
|
||||||
|
saveAs(blob, `${neType}_${neName}_code.txt`);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对话框弹出显示为 ID编辑
|
||||||
|
* @param id id
|
||||||
|
*/
|
||||||
|
function fnModalVisibleById(id: number) {
|
||||||
|
const hide = message.loading(t('common.loading'), 0);
|
||||||
|
codeNeLicense(props.neUid)
|
||||||
|
.then(res => {
|
||||||
|
if (res.code === RESULT_CODE_SUCCESS) {
|
||||||
|
return getNeInfo(id);
|
||||||
|
} else {
|
||||||
|
message.error(res.msg, 3);
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(res => {
|
||||||
|
if (!res) return;
|
||||||
|
if (res.code === RESULT_CODE_SUCCESS) {
|
||||||
|
Object.assign(modalState.from, res.data);
|
||||||
|
modalState.from.licensePath = '';
|
||||||
|
modalState.from.reload = props.reload;
|
||||||
|
modalState.title = t('views.ne.neLicense.updateTtile');
|
||||||
|
modalState.openByEdit = true;
|
||||||
|
} else {
|
||||||
|
message.error(res.msg, 3);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
modalState.confirmLoading = false;
|
||||||
|
hide();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**监听是否显示,初始数据 */
|
||||||
|
watch(
|
||||||
|
() => props.open,
|
||||||
|
val => {
|
||||||
|
if (val && props.id && props.neUid) {
|
||||||
|
fnModalVisibleById(props.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
onMounted(() => {});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<ProModal
|
||||||
|
:drag="true"
|
||||||
|
:width="800"
|
||||||
|
:destroyOnClose="true"
|
||||||
|
:keyboard="false"
|
||||||
|
:mask-closable="false"
|
||||||
|
:open="modalState.openByEdit"
|
||||||
|
:title="modalState.title"
|
||||||
|
:confirm-loading="modalState.confirmLoading"
|
||||||
|
@ok="fnModalOk"
|
||||||
|
@cancel="fnModalCancel"
|
||||||
|
>
|
||||||
|
<a-form
|
||||||
|
name="modalStateFrom"
|
||||||
|
layout="horizontal"
|
||||||
|
:wrapper-col="{ span: 18 }"
|
||||||
|
:label-col="{ span: 6 }"
|
||||||
|
:labelWrap="true"
|
||||||
|
>
|
||||||
|
<a-row>
|
||||||
|
<a-col :lg="12" :md="12" :xs="24">
|
||||||
|
<a-form-item
|
||||||
|
:label-col="{ span: 12 }"
|
||||||
|
:label="t('views.ne.common.neType')"
|
||||||
|
name="neType"
|
||||||
|
>
|
||||||
|
{{ modalState.from.neType }}
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :lg="12" :md="12" :xs="24">
|
||||||
|
<a-form-item
|
||||||
|
:label-col="{ span: 12 }"
|
||||||
|
:label="t('views.ne.common.neName')"
|
||||||
|
name="neName"
|
||||||
|
>
|
||||||
|
{{ modalState.from.neName }}
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.ne.neLicense.activationRequestCode')"
|
||||||
|
name="activationRequestCode"
|
||||||
|
v-bind="modalStateFrom.validateInfos.activationRequestCode"
|
||||||
|
>
|
||||||
|
<a-input-group compact>
|
||||||
|
<a-input
|
||||||
|
v-model:value="modalState.from.activationRequestCode"
|
||||||
|
:disabled="true"
|
||||||
|
style="width: calc(100% - 64px)"
|
||||||
|
/>
|
||||||
|
<a-tooltip :title="t('common.copyText')" placement="topRight">
|
||||||
|
<a-button type="default" @click="fnCopyCode()">
|
||||||
|
<template #icon><CopyOutlined /></template>
|
||||||
|
</a-button>
|
||||||
|
</a-tooltip>
|
||||||
|
<a-tooltip :title="t('common.downloadText')" placement="topRight">
|
||||||
|
<a-button type="primary" @click="fnDownCode()">
|
||||||
|
<template #icon><DownloadOutlined /></template>
|
||||||
|
</a-button>
|
||||||
|
</a-tooltip>
|
||||||
|
</a-input-group>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.ne.neLicense.licensePath')"
|
||||||
|
name="file"
|
||||||
|
v-bind="modalStateFrom.validateInfos.licensePath"
|
||||||
|
>
|
||||||
|
<a-upload
|
||||||
|
name="file"
|
||||||
|
v-model:file-list="modalState.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="modalState.confirmLoading"
|
||||||
|
>
|
||||||
|
<a-button type="primary">
|
||||||
|
<template #icon>
|
||||||
|
<UploadOutlined />
|
||||||
|
</template>
|
||||||
|
{{ t('views.ne.neLicense.upload') }}
|
||||||
|
</a-button>
|
||||||
|
</a-upload>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<!-- 网元授权不允许操作重启,上传后根据情况去网元信息操作重启 -->
|
||||||
|
<a-form-item label="NE Reload" name="reload" v-if="false">
|
||||||
|
<a-switch v-model:checked="modalState.from.reload"> </a-switch>
|
||||||
|
</a-form-item>
|
||||||
|
</a-form>
|
||||||
|
</ProModal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="less" scoped></style>
|
||||||
248
src/views/ne/info/components/LicenseUpdateMore.vue
Normal file
248
src/views/ne/info/components/LicenseUpdateMore.vue
Normal file
@@ -0,0 +1,248 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { reactive, onMounted, watch, PropType, h } from 'vue';
|
||||||
|
import { message, notification, Upload } from 'ant-design-vue/es';
|
||||||
|
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
||||||
|
import { UploadRequestOption } from 'ant-design-vue/es/vc-upload/interface';
|
||||||
|
import { FileType } from 'ant-design-vue/es/upload/interface';
|
||||||
|
import { ProModal } from 'antdv-pro-modal';
|
||||||
|
import { uploadFile } from '@/api/tool/file';
|
||||||
|
import { updateNeLicense } from '@/api/ne/neInfo';
|
||||||
|
import useI18n from '@/hooks/useI18n';
|
||||||
|
const { t } = useI18n();
|
||||||
|
const emit = defineEmits(['ok', 'cancel', 'update:open']);
|
||||||
|
const props = defineProps({
|
||||||
|
open: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
/**指定网元类型 */
|
||||||
|
licenseList: {
|
||||||
|
type: Array as PropType<Record<string, any>[]>,
|
||||||
|
default: [],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
/**对话框对象信息状态类型 */
|
||||||
|
type ModalStateType = {
|
||||||
|
/**新增框或修改框是否显示 */
|
||||||
|
openByUploadFile: boolean;
|
||||||
|
/**标题 */
|
||||||
|
title: string;
|
||||||
|
/**授权文件路径 */
|
||||||
|
licensePath: string;
|
||||||
|
/**上传文件 */
|
||||||
|
uploadFiles: any[];
|
||||||
|
/**确定按钮 loading */
|
||||||
|
confirmLoading: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**对话框对象信息状态 */
|
||||||
|
let modalState: ModalStateType = reactive({
|
||||||
|
openByUploadFile: false,
|
||||||
|
licensePath: '',
|
||||||
|
uploadFiles: [],
|
||||||
|
title: '授权文件',
|
||||||
|
confirmLoading: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对话框弹出确认执行函数
|
||||||
|
* 进行表达规则校验
|
||||||
|
*/
|
||||||
|
async function fnModalOk() {
|
||||||
|
if (!modalState.licensePath) {
|
||||||
|
message.warning(t('views.ne.neLicense.licensePathTip'), 3);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (modalState.confirmLoading) return;
|
||||||
|
modalState.confirmLoading = true;
|
||||||
|
|
||||||
|
const notificationKey = 'NE_LICENSE_MORE';
|
||||||
|
notification.info({
|
||||||
|
key: notificationKey,
|
||||||
|
message: modalState.title,
|
||||||
|
description: t('common.loading'),
|
||||||
|
duration: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (props.licenseList.length === 0) {
|
||||||
|
notification.close(notificationKey);
|
||||||
|
modalState.confirmLoading = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const hasFailNeType: string[] = [];
|
||||||
|
for (const item of props.licenseList) {
|
||||||
|
try {
|
||||||
|
const res = await updateNeLicense({
|
||||||
|
neUid: item.neUid,
|
||||||
|
licensePath: modalState.licensePath,
|
||||||
|
reload: true, // 重启网元
|
||||||
|
});
|
||||||
|
if (res.code !== RESULT_CODE_SUCCESS) {
|
||||||
|
hasFailNeType.push(item.neType);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 存在错误网元提示
|
||||||
|
if (hasFailNeType.length > 0) {
|
||||||
|
notification.warning({
|
||||||
|
message: modalState.title,
|
||||||
|
description: h('div', {}, [
|
||||||
|
h('p', t('views.ne.neLicense.uploadChangeFail')),
|
||||||
|
h('div', { style: { color: '#f5222d' } }, hasFailNeType.join('、')),
|
||||||
|
]),
|
||||||
|
duration: 4.5,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
notification.success({
|
||||||
|
message: modalState.title,
|
||||||
|
description: t('views.ne.neLicense.uploadChangeOk'),
|
||||||
|
duration: 4.5,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 结束
|
||||||
|
emit('ok', hasFailNeType);
|
||||||
|
fnModalCancel();
|
||||||
|
notification.close(notificationKey);
|
||||||
|
modalState.confirmLoading = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对话框弹出关闭执行函数
|
||||||
|
* 进行表达规则校验
|
||||||
|
*/
|
||||||
|
function fnModalCancel() {
|
||||||
|
modalState.openByUploadFile = false;
|
||||||
|
modalState.confirmLoading = false;
|
||||||
|
modalState.licensePath = '';
|
||||||
|
modalState.uploadFiles = [];
|
||||||
|
emit('cancel');
|
||||||
|
emit('update:open', false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**表单上传前检查或转换压缩 */
|
||||||
|
function fnBeforeUploadFile(file: FileType) {
|
||||||
|
if (modalState.confirmLoading) return false;
|
||||||
|
if (!file.name.endsWith('.ini')) {
|
||||||
|
const msg = `${t('components.UploadModal.onlyAllow')} .ini`;
|
||||||
|
message.error(msg, 3);
|
||||||
|
return Upload.LIST_IGNORE;
|
||||||
|
}
|
||||||
|
const isLt3M = file.size / 1024 / 1024 < 3;
|
||||||
|
if (!isLt3M) {
|
||||||
|
const msg = `${t('components.UploadModal.allowFilter')} 3MB`;
|
||||||
|
message.error(msg, 3);
|
||||||
|
return Upload.LIST_IGNORE;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**表单上传文件 */
|
||||||
|
function fnUploadFile(up: UploadRequestOption) {
|
||||||
|
// 发送请求
|
||||||
|
const hide = message.loading(t('common.loading'), 0);
|
||||||
|
modalState.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) {
|
||||||
|
// 改为完成状态
|
||||||
|
const file = modalState.uploadFiles[0];
|
||||||
|
file.percent = 100;
|
||||||
|
file.status = 'done';
|
||||||
|
// 预置到表单
|
||||||
|
modalState.licensePath = res.data.filePath;
|
||||||
|
} else {
|
||||||
|
message.error(res.msg, 3);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
hide();
|
||||||
|
modalState.confirmLoading = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**监听是否显示,初始数据 */
|
||||||
|
watch(
|
||||||
|
() => props.open,
|
||||||
|
val => {
|
||||||
|
if (val) {
|
||||||
|
modalState.title = t('views.ne.neLicense.updateTtile');
|
||||||
|
modalState.openByUploadFile = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
onMounted(() => {});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<ProModal
|
||||||
|
:drag="true"
|
||||||
|
:destroyOnClose="true"
|
||||||
|
:keyboard="false"
|
||||||
|
:mask-closable="false"
|
||||||
|
:open="modalState.openByUploadFile"
|
||||||
|
:title="modalState.title"
|
||||||
|
:confirm-loading="modalState.confirmLoading"
|
||||||
|
:cancel-button-props="{ disabled: modalState.confirmLoading }"
|
||||||
|
:closable="false"
|
||||||
|
@ok="fnModalOk"
|
||||||
|
@cancel="fnModalCancel"
|
||||||
|
>
|
||||||
|
<a-form
|
||||||
|
name="modalStateFrom"
|
||||||
|
layout="horizontal"
|
||||||
|
:wrapper-col="{ span: 18 }"
|
||||||
|
:label-col="{ span: 6 }"
|
||||||
|
:labelWrap="true"
|
||||||
|
>
|
||||||
|
<a-form-item :label="t('views.ne.common.neType')">
|
||||||
|
<a-tag color="processing" v-for="s in props.licenseList">
|
||||||
|
{{ s.neType }}
|
||||||
|
</a-tag>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.ne.neLicense.licensePath')"
|
||||||
|
name="file"
|
||||||
|
:required="true"
|
||||||
|
:validate-on-rule-change="false"
|
||||||
|
:validateTrigger="[]"
|
||||||
|
>
|
||||||
|
<a-upload
|
||||||
|
name="file"
|
||||||
|
v-model:file-list="modalState.uploadFiles"
|
||||||
|
accept=".ini"
|
||||||
|
list-type="text"
|
||||||
|
:multiple="true"
|
||||||
|
:max-count="1"
|
||||||
|
:show-upload-list="{
|
||||||
|
showPreviewIcon: false,
|
||||||
|
showRemoveIcon: false,
|
||||||
|
showDownloadIcon: false,
|
||||||
|
}"
|
||||||
|
:before-upload="fnBeforeUploadFile"
|
||||||
|
:custom-request="fnUploadFile"
|
||||||
|
:disabled="modalState.confirmLoading"
|
||||||
|
>
|
||||||
|
<a-button type="primary">
|
||||||
|
<template #icon>
|
||||||
|
<UploadOutlined />
|
||||||
|
</template>
|
||||||
|
{{ t('views.ne.neLicense.upload') }}
|
||||||
|
</a-button>
|
||||||
|
</a-upload>
|
||||||
|
</a-form-item>
|
||||||
|
</a-form>
|
||||||
|
</ProModal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="less" scoped></style>
|
||||||
333
src/views/ne/info/components/OAMModal.vue
Normal file
333
src/views/ne/info/components/OAMModal.vue
Normal file
@@ -0,0 +1,333 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { reactive, toRaw, watch } from 'vue';
|
||||||
|
import { ProModal } from 'antdv-pro-modal';
|
||||||
|
import { message, Form } from 'ant-design-vue/es';
|
||||||
|
import useI18n from '@/hooks/useI18n';
|
||||||
|
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
||||||
|
import { getOAMFile, saveOAMFile, serviceNeAction } from '@/api/ne/neAction';
|
||||||
|
const { t } = useI18n();
|
||||||
|
const emit = defineEmits(['ok', 'cancel', 'update:open']);
|
||||||
|
const props = defineProps({
|
||||||
|
open: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
neUid: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
neType: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
/**对话框对象信息状态类型 */
|
||||||
|
type ModalStateType = {
|
||||||
|
/**新增框或修改框是否显示 */
|
||||||
|
openByEdit: boolean;
|
||||||
|
/**标题 */
|
||||||
|
title: string;
|
||||||
|
/**是否重启 */
|
||||||
|
restart: boolean;
|
||||||
|
/**表单数据 */
|
||||||
|
from: Record<string, any>;
|
||||||
|
/**确定按钮 loading */
|
||||||
|
confirmLoading: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**对话框对象信息状态 */
|
||||||
|
let modalState: ModalStateType = reactive({
|
||||||
|
openByEdit: false,
|
||||||
|
title: 'OAM Configuration',
|
||||||
|
restart: false,
|
||||||
|
from: {
|
||||||
|
omcIP: '',
|
||||||
|
oamEnable: true,
|
||||||
|
oamPort: 33030,
|
||||||
|
snmpEnable: true,
|
||||||
|
snmpPort: 4957,
|
||||||
|
kpiEnable: true,
|
||||||
|
kpiTimer: 60,
|
||||||
|
},
|
||||||
|
confirmLoading: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
/**对话框内表单属性和校验规则 */
|
||||||
|
const modalStateFrom = Form.useForm(
|
||||||
|
modalState.from,
|
||||||
|
reactive({
|
||||||
|
kpiTimer: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: t('views.ne.neInfo.oam.kpiTimerPlease'),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对话框弹出显示为 新增或者修改
|
||||||
|
* @param neType 网元类型
|
||||||
|
* @param neId 网元ID
|
||||||
|
*/
|
||||||
|
function fnModalVisibleByTypeAndId(neUid: string) {
|
||||||
|
const hide = message.loading(t('common.loading'), 0);
|
||||||
|
getOAMFile(neUid)
|
||||||
|
.then(res => {
|
||||||
|
if (res.code === RESULT_CODE_SUCCESS) {
|
||||||
|
const data = res.data;
|
||||||
|
const ipType = data?.oamConfig?.ipType || 'ipv4';
|
||||||
|
let omcIP = '127.0.0.1';
|
||||||
|
if (data.oamConfig && Reflect.has(data.oamConfig, ipType)) {
|
||||||
|
omcIP = data?.oamConfig[ipType];
|
||||||
|
}
|
||||||
|
Object.assign(modalState.from, {
|
||||||
|
omcIP: omcIP,
|
||||||
|
oamEnable: data?.oamConfig?.enable || false,
|
||||||
|
oamPort: data?.oamConfig?.port || 33030,
|
||||||
|
snmpEnable: data?.snmpConfig?.enable || false,
|
||||||
|
snmpPort: data?.snmpConfig?.port || 4957,
|
||||||
|
kpiEnable: data?.kpiConfig?.enable || false,
|
||||||
|
kpiTimer: data?.kpiConfig?.timer || 60,
|
||||||
|
});
|
||||||
|
modalState.title = t('views.ne.neInfo.oam.title');
|
||||||
|
modalState.openByEdit = true;
|
||||||
|
} else {
|
||||||
|
message.error(res.msg, 3);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
modalState.confirmLoading = false;
|
||||||
|
hide();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对话框弹出确认执行函数
|
||||||
|
* 进行表达规则校验
|
||||||
|
*/
|
||||||
|
function fnModalOk() {
|
||||||
|
modalStateFrom
|
||||||
|
.validate()
|
||||||
|
.then(e => {
|
||||||
|
modalState.confirmLoading = true;
|
||||||
|
const hide = message.loading(t('common.loading'), 0);
|
||||||
|
const from = toRaw(modalState.from);
|
||||||
|
saveOAMFile({
|
||||||
|
neUid: props.neUid,
|
||||||
|
content: from,
|
||||||
|
sync: true,
|
||||||
|
})
|
||||||
|
.then(res => {
|
||||||
|
if (res.code === RESULT_CODE_SUCCESS) {
|
||||||
|
message.success(t('common.operateOk'), 3);
|
||||||
|
emit('ok');
|
||||||
|
if (modalState.restart) {
|
||||||
|
serviceNeAction({
|
||||||
|
neType: props.neType,
|
||||||
|
neUid: props.neUid,
|
||||||
|
action: 'restart',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
fnModalCancel();
|
||||||
|
} else {
|
||||||
|
message.error({
|
||||||
|
content: `${res.msg}`,
|
||||||
|
duration: 3,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
hide();
|
||||||
|
modalState.confirmLoading = false;
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(e => {
|
||||||
|
message.error(t('common.errorFields', { num: e.errorFields.length }), 3);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对话框弹出关闭执行函数
|
||||||
|
* 进行表达规则校验
|
||||||
|
*/
|
||||||
|
function fnModalCancel() {
|
||||||
|
modalState.openByEdit = false;
|
||||||
|
modalState.confirmLoading = false;
|
||||||
|
modalState.restart = false;
|
||||||
|
modalStateFrom.resetFields();
|
||||||
|
emit('cancel');
|
||||||
|
emit('update:open', false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**监听是否显示,初始数据 */
|
||||||
|
watch(
|
||||||
|
() => props.open,
|
||||||
|
val => {
|
||||||
|
if (val) {
|
||||||
|
if (props.neUid) {
|
||||||
|
fnModalVisibleByTypeAndId(props.neUid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<ProModal
|
||||||
|
:drag="true"
|
||||||
|
:destroyOnClose="true"
|
||||||
|
:body-style="{ maxHeight: '600px', 'overflow-y': 'auto' }"
|
||||||
|
:keyboard="false"
|
||||||
|
:mask-closable="false"
|
||||||
|
:open="modalState.openByEdit"
|
||||||
|
:title="modalState.title"
|
||||||
|
:confirm-loading="modalState.confirmLoading"
|
||||||
|
@ok="fnModalOk"
|
||||||
|
@cancel="fnModalCancel"
|
||||||
|
>
|
||||||
|
<a-form
|
||||||
|
name="modalStateFrom"
|
||||||
|
layout="horizontal"
|
||||||
|
:label-col="{ span: 12 }"
|
||||||
|
:labelWrap="true"
|
||||||
|
>
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.ne.neInfo.oam.restart')"
|
||||||
|
name="restart"
|
||||||
|
:label-col="{ span: 6 }"
|
||||||
|
:labelWrap="true"
|
||||||
|
>
|
||||||
|
<a-switch
|
||||||
|
:checked-children="t('common.switch.open')"
|
||||||
|
:un-checked-children="t('common.switch.shut')"
|
||||||
|
v-model:checked="modalState.restart"
|
||||||
|
></a-switch>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-collapse class="collapse" ghost>
|
||||||
|
<a-collapse-panel header="OAM">
|
||||||
|
<a-row>
|
||||||
|
<a-col :lg="12" :md="12" :xs="24">
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.ne.neInfo.oam.oamEnable')"
|
||||||
|
name="oamEnable"
|
||||||
|
>
|
||||||
|
<a-switch
|
||||||
|
:checked-children="t('common.switch.open')"
|
||||||
|
:un-checked-children="t('common.switch.shut')"
|
||||||
|
v-model:checked="modalState.from.oamEnable"
|
||||||
|
></a-switch>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :lg="12" :md="12" :xs="24">
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.ne.neInfo.oam.oamPort')"
|
||||||
|
name="oamPort"
|
||||||
|
v-bind="modalStateFrom.validateInfos.oamPort"
|
||||||
|
>
|
||||||
|
<a-input-number
|
||||||
|
:min="3000"
|
||||||
|
:max="65535"
|
||||||
|
:step="1"
|
||||||
|
:maxlength="5"
|
||||||
|
v-model:value="modalState.from.oamPort"
|
||||||
|
style="width: 100%"
|
||||||
|
></a-input-number>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.ne.neInfo.oam.omcIP')"
|
||||||
|
name="omcIP"
|
||||||
|
:label-col="{ span: 6 }"
|
||||||
|
:labelWrap="true"
|
||||||
|
>
|
||||||
|
<a-input
|
||||||
|
v-model:value="modalState.from.omcIP"
|
||||||
|
:maxlength="128"
|
||||||
|
></a-input>
|
||||||
|
</a-form-item>
|
||||||
|
</a-collapse-panel>
|
||||||
|
<a-collapse-panel header="SNMP">
|
||||||
|
<a-row>
|
||||||
|
<a-col :lg="12" :md="12" :xs="24">
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.ne.neInfo.oam.snmpEnable')"
|
||||||
|
name="snmpEnable"
|
||||||
|
>
|
||||||
|
<a-switch
|
||||||
|
:checked-children="t('common.switch.open')"
|
||||||
|
:un-checked-children="t('common.switch.shut')"
|
||||||
|
v-model:checked="modalState.from.snmpEnable"
|
||||||
|
></a-switch>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :lg="12" :md="12" :xs="24">
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.ne.neInfo.oam.snmpPort')"
|
||||||
|
name="snmpPort"
|
||||||
|
v-bind="modalStateFrom.validateInfos.snmpPort"
|
||||||
|
>
|
||||||
|
<a-input-number
|
||||||
|
:min="3000"
|
||||||
|
:max="65535"
|
||||||
|
:step="1"
|
||||||
|
:maxlength="5"
|
||||||
|
v-model:value="modalState.from.snmpPort"
|
||||||
|
style="width: 100%"
|
||||||
|
></a-input-number>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</a-collapse-panel>
|
||||||
|
<a-collapse-panel header="KPI">
|
||||||
|
<a-row>
|
||||||
|
<a-col :lg="12" :md="12" :xs="24">
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.ne.neInfo.oam.kpiEnable')"
|
||||||
|
name="kpiEnable"
|
||||||
|
>
|
||||||
|
<a-switch
|
||||||
|
:checked-children="t('common.switch.open')"
|
||||||
|
:un-checked-children="t('common.switch.shut')"
|
||||||
|
v-model:checked="modalState.from.kpiEnable"
|
||||||
|
></a-switch>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :lg="12" :md="12" :xs="24">
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.ne.neInfo.oam.kpiTimer')"
|
||||||
|
name="kpiTimer"
|
||||||
|
v-bind="modalStateFrom.validateInfos.kpiTimer"
|
||||||
|
>
|
||||||
|
<a-input-number
|
||||||
|
:min="5"
|
||||||
|
:max="3600"
|
||||||
|
:step="1"
|
||||||
|
:maxlength="4"
|
||||||
|
v-model:value="modalState.from.kpiTimer"
|
||||||
|
style="width: 100%"
|
||||||
|
></a-input-number>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</a-collapse-panel>
|
||||||
|
</a-collapse>
|
||||||
|
</a-form>
|
||||||
|
</ProModal>
|
||||||
|
</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>
|
||||||
231
src/views/ne/info/hooks/useNeOptions.ts
Normal file
231
src/views/ne/info/hooks/useNeOptions.ts
Normal file
@@ -0,0 +1,231 @@
|
|||||||
|
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
||||||
|
import { Modal, message } from 'ant-design-vue/es';
|
||||||
|
import useI18n from '@/hooks/useI18n';
|
||||||
|
import { useRouter } from 'vue-router';
|
||||||
|
import { updateNeConfigReload } from '@/api/tool/mml';
|
||||||
|
import { serviceNeAction } from '@/api/ne/neAction';
|
||||||
|
import useMaskStore from '@/store/modules/mask';
|
||||||
|
|
||||||
|
export default function useNeOptions() {
|
||||||
|
const router = useRouter();
|
||||||
|
const { t } = useI18n();
|
||||||
|
const maskStore = useMaskStore();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 网元启动
|
||||||
|
* @param row {neName,neType,neId}
|
||||||
|
* @param callback 回调函数,用于刷新表格数据
|
||||||
|
*/
|
||||||
|
function fnNeStart(row: Record<string, any>, callback?: () => void) {
|
||||||
|
Modal.confirm({
|
||||||
|
title: t('common.tipTitle'),
|
||||||
|
content: t('views.ne.common.startTip', { ne: row.neName }),
|
||||||
|
onOk() {
|
||||||
|
const hide = message.loading(t('common.loading'), 0);
|
||||||
|
serviceNeAction({
|
||||||
|
neType: row.neType,
|
||||||
|
neUid: row.neUid,
|
||||||
|
action: 'start',
|
||||||
|
})
|
||||||
|
.then(res => {
|
||||||
|
if (res.code === RESULT_CODE_SUCCESS) {
|
||||||
|
message.success(
|
||||||
|
`${t('views.ne.common.start')} ${row.neName} ${t(
|
||||||
|
'common.operateOk'
|
||||||
|
)}`,
|
||||||
|
3
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
message.error(`${res.msg}`, 3);
|
||||||
|
}
|
||||||
|
callback && callback();
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
hide();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 网元重启
|
||||||
|
* @param row {neName,neType,neId}
|
||||||
|
* @param callback 回调函数,用于刷新表格数据
|
||||||
|
*/
|
||||||
|
function fnNeRestart(row: Record<string, any>, callback?: () => void) {
|
||||||
|
Modal.confirm({
|
||||||
|
title: t('common.tipTitle'),
|
||||||
|
content: t('views.ne.common.restartTip', { ne: row.neName }),
|
||||||
|
onOk() {
|
||||||
|
const hide = message.loading(t('common.loading'), 0);
|
||||||
|
serviceNeAction({
|
||||||
|
neType: row.neType,
|
||||||
|
neUid: row.neUid,
|
||||||
|
action: 'restart',
|
||||||
|
})
|
||||||
|
.then(res => {
|
||||||
|
if (res.code === RESULT_CODE_SUCCESS) {
|
||||||
|
// OMC自升级
|
||||||
|
if (row.neType.toUpperCase() === 'OMC') {
|
||||||
|
if (res.code === RESULT_CODE_SUCCESS) {
|
||||||
|
maskStore.handleMaskType('reload');
|
||||||
|
} else {
|
||||||
|
message.error({
|
||||||
|
content: `${res.msg}`,
|
||||||
|
duration: 3,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
message.success(
|
||||||
|
`${t('views.ne.common.restart')} ${row.neName} ${t(
|
||||||
|
'common.operateOk'
|
||||||
|
)}`,
|
||||||
|
3
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
message.error(`${res.msg}`, 3);
|
||||||
|
}
|
||||||
|
callback && callback();
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
hide();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 网元停止
|
||||||
|
* @param row {neName,neType,neId}
|
||||||
|
* @param callback 回调函数,用于刷新表格数据
|
||||||
|
*/
|
||||||
|
function fnNeStop(row: Record<string, any>, callback?: () => void) {
|
||||||
|
Modal.confirm({
|
||||||
|
title: t('common.tipTitle'),
|
||||||
|
content: t('views.ne.common.stopTip', { ne: row.neName }),
|
||||||
|
onOk() {
|
||||||
|
const hide = message.loading(t('common.loading'), 0);
|
||||||
|
serviceNeAction({
|
||||||
|
neType: row.neType,
|
||||||
|
neUid: row.neUid,
|
||||||
|
action: 'stop',
|
||||||
|
})
|
||||||
|
.then(res => {
|
||||||
|
if (res.code === RESULT_CODE_SUCCESS) {
|
||||||
|
message.success(
|
||||||
|
`${t('views.ne.common.stop')} ${row.neName} ${t(
|
||||||
|
'common.operateOk'
|
||||||
|
)}`,
|
||||||
|
3
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
message.error(`${res.msg}`, 3);
|
||||||
|
}
|
||||||
|
callback && callback();
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
hide();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 网元重新加载
|
||||||
|
* @param row {neName,neType,neId}
|
||||||
|
*/
|
||||||
|
function fnNeReload(row: Record<string, any>) {
|
||||||
|
Modal.confirm({
|
||||||
|
title: t('common.tipTitle'),
|
||||||
|
content: t('views.ne.common.reloadTip'),
|
||||||
|
onOk() {
|
||||||
|
const hide = message.loading(t('common.loading'), 0);
|
||||||
|
updateNeConfigReload(row.neUid)
|
||||||
|
.then(res => {
|
||||||
|
if (res.code === RESULT_CODE_SUCCESS) {
|
||||||
|
message.success(t('common.operateOk'), 3);
|
||||||
|
} else {
|
||||||
|
message.error(`${res.msg}`, 3);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
hide();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 跳转网元日志文件页面
|
||||||
|
* @param row {neType,neId}
|
||||||
|
*/
|
||||||
|
function fnNeLogFile(row: Record<string, any>) {
|
||||||
|
router.push({
|
||||||
|
name: 'NeFile_2123',
|
||||||
|
query: {
|
||||||
|
neType: row.neType,
|
||||||
|
neUid: row.neUid,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析网元状态携带的资源利用率
|
||||||
|
* @param neState {cpu,mem,disk}
|
||||||
|
*/
|
||||||
|
function parseResouresUsage(neState: Record<string, any>) {
|
||||||
|
let sysCpuUsage = 0;
|
||||||
|
let nfCpuUsage = 0;
|
||||||
|
if (neState.cpu) {
|
||||||
|
nfCpuUsage = neState.cpu.nfCpuUsage;
|
||||||
|
const nfCpu = +(nfCpuUsage / 100);
|
||||||
|
nfCpuUsage = +nfCpu.toFixed(2);
|
||||||
|
if (nfCpuUsage > 100) {
|
||||||
|
nfCpuUsage = 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
sysCpuUsage = neState.cpu.sysCpuUsage;
|
||||||
|
const sysCpu = +(sysCpuUsage / 100);
|
||||||
|
sysCpuUsage = +sysCpu.toFixed(2);
|
||||||
|
if (sysCpuUsage > 100) {
|
||||||
|
sysCpuUsage = 100;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let sysMemUsage = 0;
|
||||||
|
if (neState.mem) {
|
||||||
|
const men = neState.mem.sysMemUsage;
|
||||||
|
sysMemUsage = +(men / 100).toFixed(2);
|
||||||
|
if (sysMemUsage > 100) {
|
||||||
|
sysMemUsage = 100;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let sysDiskUsage = 0;
|
||||||
|
if (neState.disk && Array.isArray(neState.disk.partitionInfo)) {
|
||||||
|
let disks: any[] = neState.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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
sysDiskUsage,
|
||||||
|
sysMemUsage,
|
||||||
|
sysCpuUsage,
|
||||||
|
nfCpuUsage,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
fnNeStart,
|
||||||
|
fnNeRestart,
|
||||||
|
fnNeStop,
|
||||||
|
fnNeReload,
|
||||||
|
fnNeLogFile,
|
||||||
|
parseResouresUsage,
|
||||||
|
};
|
||||||
|
}
|
||||||
888
src/views/ne/info/index.vue
Normal file
888
src/views/ne/info/index.vue
Normal file
@@ -0,0 +1,888 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { reactive, onMounted, toRaw, defineAsyncComponent, ref } from 'vue';
|
||||||
|
import { PageContainer } from 'antdv-pro-layout';
|
||||||
|
import { message, Modal } from 'ant-design-vue/es';
|
||||||
|
import { SizeType } from 'ant-design-vue/es/config-provider';
|
||||||
|
import { MenuInfo } from 'ant-design-vue/es/menu/src/interface';
|
||||||
|
import { ColumnsType } from 'ant-design-vue/es/table';
|
||||||
|
import useI18n from '@/hooks/useI18n';
|
||||||
|
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
||||||
|
import useNeStore from '@/store/modules/ne';
|
||||||
|
import { listNeInfo, delNeInfo } from '@/api/ne/neInfo';
|
||||||
|
import { stateNeInfo } from '@/api/ne/neAction';
|
||||||
|
import useDictStore from '@/store/modules/dict';
|
||||||
|
import useNeOptions from './hooks/useNeOptions';
|
||||||
|
const { getDict } = useDictStore();
|
||||||
|
const neStore = useNeStore();
|
||||||
|
const { t } = useI18n();
|
||||||
|
const {
|
||||||
|
fnNeStart,
|
||||||
|
fnNeRestart,
|
||||||
|
fnNeStop,
|
||||||
|
fnNeReload,
|
||||||
|
fnNeLogFile,
|
||||||
|
parseResouresUsage,
|
||||||
|
} = useNeOptions();
|
||||||
|
// 异步加载组件
|
||||||
|
const EditModal = defineAsyncComponent(
|
||||||
|
() => import('./components/EditModal.vue')
|
||||||
|
);
|
||||||
|
const OAMModal = defineAsyncComponent(
|
||||||
|
() => import('./components/OAMModal.vue')
|
||||||
|
);
|
||||||
|
// 软件授权上传
|
||||||
|
const LicenseEditModal = defineAsyncComponent(
|
||||||
|
() => import('./components/LicenseEditModal.vue')
|
||||||
|
);
|
||||||
|
// 核心网关联
|
||||||
|
const CoreModal = defineAsyncComponent(
|
||||||
|
() => import('./components/CoreModal.vue')
|
||||||
|
);
|
||||||
|
// 配置备份文件导入
|
||||||
|
const BackConfModal = defineAsyncComponent(
|
||||||
|
() => import('./components/BackConfModal.vue')
|
||||||
|
);
|
||||||
|
const backConf = ref(); // 引用句柄,取导出函数
|
||||||
|
|
||||||
|
/**字典数据 */
|
||||||
|
let dict: {
|
||||||
|
/**网元信息状态 */
|
||||||
|
neInfoStatus: DictType[];
|
||||||
|
} = reactive({
|
||||||
|
neInfoStatus: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
/**查询参数 */
|
||||||
|
let queryParams = reactive({
|
||||||
|
/**网元类型 */
|
||||||
|
neType: '',
|
||||||
|
/**带状态信息 */
|
||||||
|
bandStatus: false,
|
||||||
|
/**当前页数 */
|
||||||
|
pageNum: 1,
|
||||||
|
/**每页条数 */
|
||||||
|
pageSize: 20,
|
||||||
|
});
|
||||||
|
|
||||||
|
/**查询参数重置 */
|
||||||
|
function fnQueryReset() {
|
||||||
|
queryParams = Object.assign(queryParams, {
|
||||||
|
neType: '',
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 20,
|
||||||
|
});
|
||||||
|
tablePagination.current = 1;
|
||||||
|
tablePagination.pageSize = 20;
|
||||||
|
fnGetList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**表格状态类型 */
|
||||||
|
type TabeStateType = {
|
||||||
|
/**加载等待 */
|
||||||
|
loading: boolean;
|
||||||
|
/**紧凑型 */
|
||||||
|
size: SizeType;
|
||||||
|
/**搜索栏 */
|
||||||
|
seached: boolean;
|
||||||
|
/**记录数据 */
|
||||||
|
data: Record<string, any>[];
|
||||||
|
/**勾选记录 */
|
||||||
|
selectedRowKeys: (string | number)[];
|
||||||
|
/**勾选记录 */
|
||||||
|
selectedRows: Record<string, any>[];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**表格状态 */
|
||||||
|
let tableState: TabeStateType = reactive({
|
||||||
|
loading: false,
|
||||||
|
size: 'middle',
|
||||||
|
seached: true,
|
||||||
|
data: [],
|
||||||
|
selectedRowKeys: [],
|
||||||
|
selectedRows: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
/**表格字段列 */
|
||||||
|
let tableColumns: ColumnsType = [
|
||||||
|
{
|
||||||
|
title: t('views.ne.common.coreUid'),
|
||||||
|
dataIndex: 'coreUid',
|
||||||
|
align: 'left',
|
||||||
|
width: 100,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('views.ne.common.coreName'),
|
||||||
|
dataIndex: 'coreName',
|
||||||
|
align: 'left',
|
||||||
|
width: 150,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('views.ne.common.neUid'),
|
||||||
|
dataIndex: 'neUid',
|
||||||
|
align: 'left',
|
||||||
|
width: 100,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('views.ne.common.neType'),
|
||||||
|
dataIndex: 'neType',
|
||||||
|
align: 'left',
|
||||||
|
width: 100,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('views.ne.common.neName'),
|
||||||
|
dataIndex: 'neName',
|
||||||
|
align: 'left',
|
||||||
|
width: 150,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('views.ne.common.ipAddr'),
|
||||||
|
dataIndex: 'ipAddr',
|
||||||
|
align: 'left',
|
||||||
|
width: 150,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('views.ne.common.port'),
|
||||||
|
dataIndex: 'port',
|
||||||
|
align: 'left',
|
||||||
|
width: 100,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('views.ne.common.serialNum'),
|
||||||
|
dataIndex: 'serialNum',
|
||||||
|
align: 'left',
|
||||||
|
width: 120,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('views.ne.common.expiryDate'),
|
||||||
|
dataIndex: 'expiryDate',
|
||||||
|
align: 'left',
|
||||||
|
width: 150,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('views.ne.common.ueNumber'),
|
||||||
|
dataIndex: 'ueNumber',
|
||||||
|
align: 'left',
|
||||||
|
customRender(opt) {
|
||||||
|
if (['UDM', 'AMF', 'MME'].includes(opt.record.neType)) {
|
||||||
|
return opt.value;
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
},
|
||||||
|
width: 120,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('views.ne.common.nbNumber'),
|
||||||
|
dataIndex: 'nbNumber',
|
||||||
|
align: 'left',
|
||||||
|
customRender(opt) {
|
||||||
|
if (['AMF', 'MME'].includes(opt.record.neType)) {
|
||||||
|
return opt.value;
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
},
|
||||||
|
width: 120,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('views.ne.neInfo.state'),
|
||||||
|
dataIndex: 'status',
|
||||||
|
key: 'status',
|
||||||
|
align: 'left',
|
||||||
|
width: 100,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('common.operate'),
|
||||||
|
key: 'id',
|
||||||
|
align: 'left',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
/**表格分页器参数 */
|
||||||
|
let tablePagination = reactive({
|
||||||
|
/**当前页数 */
|
||||||
|
current: 1,
|
||||||
|
/**每页条数 */
|
||||||
|
pageSize: 20,
|
||||||
|
/**默认的每页条数 */
|
||||||
|
defaultPageSize: 20,
|
||||||
|
/**指定每页可以显示多少条 */
|
||||||
|
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;
|
||||||
|
queryParams.pageNum = page;
|
||||||
|
queryParams.pageSize = pageSize;
|
||||||
|
fnGetList();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
/**表格紧凑型变更操作 */
|
||||||
|
function fnTableSize({ key }: MenuInfo) {
|
||||||
|
tableState.size = key as SizeType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**表格多选 */
|
||||||
|
function fnTableSelectedRowKeys(keys: (string | number)[], rows: any[]) {
|
||||||
|
tableState.selectedRowKeys = keys;
|
||||||
|
tableState.selectedRows = rows.map(item => {
|
||||||
|
return {
|
||||||
|
id: item.id,
|
||||||
|
neUid: item.neUid,
|
||||||
|
neType: item.neType,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**对话框对象信息状态类型 */
|
||||||
|
type ModalStateType = {
|
||||||
|
/**软件授权上传框是否显示 */
|
||||||
|
openByLicense: boolean;
|
||||||
|
/**配置备份框是否显示 */
|
||||||
|
openByBackConf: boolean;
|
||||||
|
/**OAM文件配置框是否显示 */
|
||||||
|
openByOAM: boolean;
|
||||||
|
/**核心网关联框是否显示 */
|
||||||
|
openByCore: boolean;
|
||||||
|
/**新增框或修改框是否显示 */
|
||||||
|
openByEdit: boolean;
|
||||||
|
/**新增框或修改框ID */
|
||||||
|
id: number;
|
||||||
|
neUid: string;
|
||||||
|
neType: string;
|
||||||
|
coreUid: string;
|
||||||
|
/**确定按钮 loading */
|
||||||
|
confirmLoading: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**对话框对象信息状态 */
|
||||||
|
let modalState: ModalStateType = reactive({
|
||||||
|
openByLicense: false,
|
||||||
|
openByBackConf: false,
|
||||||
|
openByOAM: false,
|
||||||
|
openByCore: false,
|
||||||
|
openByEdit: false,
|
||||||
|
id: 0,
|
||||||
|
neUid: '',
|
||||||
|
neType: '',
|
||||||
|
coreUid: '',
|
||||||
|
confirmLoading: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对话框弹出显示为 新增或者修改
|
||||||
|
* @param noticeId 网元id, 不传为新增
|
||||||
|
*/
|
||||||
|
function fnModalVisibleByEdit(row?: Record<string, any>) {
|
||||||
|
if (!row) {
|
||||||
|
modalState.id = 0;
|
||||||
|
modalState.neUid = '';
|
||||||
|
modalState.neType = '';
|
||||||
|
} else {
|
||||||
|
modalState.id = row.id;
|
||||||
|
modalState.neUid = row.neUid;
|
||||||
|
modalState.neType = row.neType;
|
||||||
|
}
|
||||||
|
modalState.openByEdit = !modalState.openByEdit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对话框弹出确认执行函数
|
||||||
|
* 进行表达规则校验
|
||||||
|
*/
|
||||||
|
function fnModalEditOk(from: Record<string, any>) {
|
||||||
|
// 新增时刷新列表
|
||||||
|
if (!from.neUid) {
|
||||||
|
fnGetList();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 编辑时局部更新信息
|
||||||
|
reloadRowInfo(from);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**局部更新信息 */
|
||||||
|
function reloadRowInfo(row: Record<string, any>) {
|
||||||
|
stateNeInfo(row.neUid)
|
||||||
|
.then(res => {
|
||||||
|
// 找到编辑更新的网元
|
||||||
|
const item = tableState.data.find(s => s.id === row.id);
|
||||||
|
if (item && res.code === RESULT_CODE_SUCCESS) {
|
||||||
|
item.neType = row.neType;
|
||||||
|
item.neUid = row.neUid;
|
||||||
|
item.neName = row.neName;
|
||||||
|
item.ipAddr = row.ipAddr;
|
||||||
|
item.port = row.port;
|
||||||
|
if (res.data.online) {
|
||||||
|
item.status = '1';
|
||||||
|
if (res.data.standby) {
|
||||||
|
item.status = '3';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
item.status = '0';
|
||||||
|
}
|
||||||
|
Object.assign(item.serverState, res.data);
|
||||||
|
const resouresUsage = parseResouresUsage(item.serverState);
|
||||||
|
Reflect.set(item, 'resoures', resouresUsage);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
neStore.fnNelistRefresh();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对话框弹出关闭执行函数
|
||||||
|
* 进行表达规则校验
|
||||||
|
*/
|
||||||
|
function fnModalEditCancel() {
|
||||||
|
modalState.neUid = '';
|
||||||
|
modalState.neType = '';
|
||||||
|
modalState.openByEdit = false;
|
||||||
|
modalState.openByOAM = false;
|
||||||
|
modalState.openByCore = false;
|
||||||
|
modalState.openByLicense = false;
|
||||||
|
modalState.openByBackConf = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 记录删除
|
||||||
|
* @param id 编号
|
||||||
|
*/
|
||||||
|
function fnRecordDelete(id: string) {
|
||||||
|
if (modalState.confirmLoading) return;
|
||||||
|
let msg = t('views.ne.neInfo.delTip');
|
||||||
|
if (id === '0') {
|
||||||
|
msg = `${msg} ...${tableState.selectedRowKeys.length}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
Modal.confirm({
|
||||||
|
title: t('common.tipTitle'),
|
||||||
|
content: msg,
|
||||||
|
onOk() {
|
||||||
|
modalState.confirmLoading = true;
|
||||||
|
const hide = message.loading(t('common.loading'), 0);
|
||||||
|
let reqArr: any = [];
|
||||||
|
if (id === '0') {
|
||||||
|
const ids = tableState.selectedRowKeys.join(',');
|
||||||
|
delNeInfo({ id: ids });
|
||||||
|
} else {
|
||||||
|
tableState.data.forEach(item => {
|
||||||
|
if (item.id === id) {
|
||||||
|
reqArr.push(
|
||||||
|
delNeInfo({
|
||||||
|
id: item.id,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Promise.all(reqArr)
|
||||||
|
.then(resArr => {
|
||||||
|
if (resArr.every((item: any) => item.code === RESULT_CODE_SUCCESS)) {
|
||||||
|
message.success(t('common.operateOk'), 3);
|
||||||
|
// 过滤掉删除的id
|
||||||
|
tableState.data = tableState.data.filter(item => {
|
||||||
|
if (tableState.selectedRowKeys.length > 0) {
|
||||||
|
return !tableState.selectedRowKeys.includes(item.id);
|
||||||
|
} else {
|
||||||
|
return item.id !== id;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// 刷新缓存
|
||||||
|
neStore.fnNelistRefresh();
|
||||||
|
} else {
|
||||||
|
message.error({
|
||||||
|
content: t('common.operateErr'),
|
||||||
|
duration: 3,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
hide();
|
||||||
|
modalState.confirmLoading = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 记录多项选择
|
||||||
|
*/
|
||||||
|
function fnRecordMore(type: string | number, row: Record<string, any>) {
|
||||||
|
switch (type) {
|
||||||
|
case 'delete':
|
||||||
|
fnRecordDelete(row.id);
|
||||||
|
break;
|
||||||
|
case 'start':
|
||||||
|
fnNeStart(row, () => reloadRowInfo(row));
|
||||||
|
break;
|
||||||
|
case 'restart':
|
||||||
|
fnNeRestart(row, () => reloadRowInfo(row));
|
||||||
|
break;
|
||||||
|
case 'stop':
|
||||||
|
fnNeStop(row, () => reloadRowInfo(row));
|
||||||
|
break;
|
||||||
|
case 'reload':
|
||||||
|
fnNeReload(row);
|
||||||
|
break;
|
||||||
|
case 'log':
|
||||||
|
fnNeLogFile(row);
|
||||||
|
break;
|
||||||
|
case 'core':
|
||||||
|
modalState.neUid = row.neUid;
|
||||||
|
modalState.coreUid = row.coreUid;
|
||||||
|
modalState.openByCore = !modalState.openByCore;
|
||||||
|
break;
|
||||||
|
case 'oam':
|
||||||
|
modalState.neUid = row.neUid;
|
||||||
|
modalState.neType = row.neType;
|
||||||
|
modalState.openByOAM = !modalState.openByOAM;
|
||||||
|
break;
|
||||||
|
case 'license':
|
||||||
|
modalState.id = row.id;
|
||||||
|
modalState.neUid = row.neUid;
|
||||||
|
modalState.neType = row.neType;
|
||||||
|
modalState.openByLicense = !modalState.openByLicense;
|
||||||
|
break;
|
||||||
|
case 'backConfExport':
|
||||||
|
backConf.value.exportConf(row.neUid, row.neType);
|
||||||
|
break;
|
||||||
|
case 'backConfImport':
|
||||||
|
modalState.neUid = row.neUid;
|
||||||
|
modalState.neType = row.neType;
|
||||||
|
modalState.openByBackConf = !modalState.openByBackConf;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
console.warn(type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**查询列表, pageNum初始页数 */
|
||||||
|
function fnGetList(pageNum?: number) {
|
||||||
|
if (tableState.loading) return;
|
||||||
|
tableState.loading = true;
|
||||||
|
if (pageNum) {
|
||||||
|
queryParams.pageNum = pageNum;
|
||||||
|
}
|
||||||
|
listNeInfo(toRaw(queryParams))
|
||||||
|
.then(res => {
|
||||||
|
if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.data.rows)) {
|
||||||
|
// 取消勾选
|
||||||
|
if (tableState.selectedRowKeys.length > 0) {
|
||||||
|
tableState.selectedRowKeys = [];
|
||||||
|
}
|
||||||
|
const { total, rows } = res.data;
|
||||||
|
tablePagination.total = total;
|
||||||
|
// 遍历处理资源情况数值
|
||||||
|
tableState.data = rows.map((item: any) => {
|
||||||
|
let resouresUsage = {
|
||||||
|
sysDiskUsage: 0,
|
||||||
|
sysMemUsage: 0,
|
||||||
|
sysCpuUsage: 0,
|
||||||
|
nfCpuUsage: 0,
|
||||||
|
};
|
||||||
|
const neState = item.serverState;
|
||||||
|
if (neState) {
|
||||||
|
resouresUsage = parseResouresUsage(neState);
|
||||||
|
} else {
|
||||||
|
item.serverState = { online: false };
|
||||||
|
}
|
||||||
|
Reflect.set(item, 'resoures', resouresUsage);
|
||||||
|
return item;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
tableState.loading = false;
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
// 刷新缓存的网元信息
|
||||||
|
neStore.fnNelistRefresh();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
// 初始字典数据
|
||||||
|
Promise.allSettled([getDict('ne_info_status')]).then(resArr => {
|
||||||
|
if (resArr[0].status === 'fulfilled') {
|
||||||
|
dict.neInfoStatus = resArr[0].value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 获取列表数据
|
||||||
|
fnGetList();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<PageContainer>
|
||||||
|
<a-card
|
||||||
|
v-show="tableState.seached"
|
||||||
|
:bordered="false"
|
||||||
|
:body-style="{ marginBottom: '24px', paddingBottom: 0 }"
|
||||||
|
>
|
||||||
|
<!-- 表格搜索栏 -->
|
||||||
|
<a-form :model="queryParams" name="queryParams" layout="horizontal">
|
||||||
|
<a-row :gutter="16">
|
||||||
|
<a-col :lg="6" :md="12" :xs="24">
|
||||||
|
<a-form-item :label="t('views.ne.common.neType')" name="neType ">
|
||||||
|
<a-auto-complete
|
||||||
|
v-model:value="queryParams.neType"
|
||||||
|
:options="neStore.getNeSelectOtions"
|
||||||
|
allow-clear
|
||||||
|
:placeholder="t('common.inputPlease')"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :lg="6" :md="12" :xs="24">
|
||||||
|
<a-form-item>
|
||||||
|
<a-space :size="8">
|
||||||
|
<a-button type="primary" @click.prevent="fnGetList(1)">
|
||||||
|
<template #icon><SearchOutlined /></template>
|
||||||
|
{{ t('common.search') }}
|
||||||
|
</a-button>
|
||||||
|
<a-button type="default" @click.prevent="fnQueryReset">
|
||||||
|
<template #icon><ClearOutlined /></template>
|
||||||
|
{{ t('common.reset') }}
|
||||||
|
</a-button>
|
||||||
|
</a-space>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</a-form>
|
||||||
|
</a-card>
|
||||||
|
|
||||||
|
<a-card :bordered="false" :body-style="{ padding: '0px' }">
|
||||||
|
<!-- 插槽-卡片左侧侧 -->
|
||||||
|
<template #title>
|
||||||
|
<a-space :size="8" align="center">
|
||||||
|
<a-button type="primary" @click.prevent="fnModalVisibleByEdit()">
|
||||||
|
<template #icon><PlusOutlined /></template>
|
||||||
|
{{ t('common.addText') }}
|
||||||
|
</a-button>
|
||||||
|
<a-button
|
||||||
|
type="default"
|
||||||
|
danger
|
||||||
|
:disabled="tableState.selectedRowKeys.length <= 0"
|
||||||
|
:loading="modalState.confirmLoading"
|
||||||
|
@click.prevent="fnRecordDelete('0')"
|
||||||
|
>
|
||||||
|
<template #icon><DeleteOutlined /></template>
|
||||||
|
{{ t('common.deleteText') }}
|
||||||
|
</a-button>
|
||||||
|
</a-space>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 插槽-卡片右侧 -->
|
||||||
|
<template #extra>
|
||||||
|
<a-space :size="8" align="center">
|
||||||
|
<a-tooltip>
|
||||||
|
<template #title>{{ t('common.searchBarText') }}</template>
|
||||||
|
<a-switch
|
||||||
|
v-model:checked="tableState.seached"
|
||||||
|
:checked-children="t('common.switch.show')"
|
||||||
|
:un-checked-children="t('common.switch.hide')"
|
||||||
|
size="small"
|
||||||
|
/>
|
||||||
|
</a-tooltip>
|
||||||
|
<a-tooltip>
|
||||||
|
<template #title>{{ t('common.reloadText') }}</template>
|
||||||
|
<a-button type="text" @click.prevent="fnGetList()">
|
||||||
|
<template #icon><ReloadOutlined /></template>
|
||||||
|
</a-button>
|
||||||
|
</a-tooltip>
|
||||||
|
<a-tooltip>
|
||||||
|
<template #title>{{ t('common.sizeText') }}</template>
|
||||||
|
<a-dropdown trigger="click" placement="bottomRight">
|
||||||
|
<a-button type="text">
|
||||||
|
<template #icon><ColumnHeightOutlined /></template>
|
||||||
|
</a-button>
|
||||||
|
<template #overlay>
|
||||||
|
<a-menu
|
||||||
|
:selected-keys="[tableState.size as string]"
|
||||||
|
@click="fnTableSize"
|
||||||
|
>
|
||||||
|
<a-menu-item key="default">
|
||||||
|
{{ t('common.size.default') }}
|
||||||
|
</a-menu-item>
|
||||||
|
<a-menu-item key="middle">
|
||||||
|
{{ t('common.size.middle') }}
|
||||||
|
</a-menu-item>
|
||||||
|
<a-menu-item key="small">
|
||||||
|
{{ t('common.size.small') }}
|
||||||
|
</a-menu-item>
|
||||||
|
</a-menu>
|
||||||
|
</template>
|
||||||
|
</a-dropdown>
|
||||||
|
</a-tooltip>
|
||||||
|
</a-space>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 表格列表 -->
|
||||||
|
<a-table
|
||||||
|
class="table"
|
||||||
|
row-key="id"
|
||||||
|
:columns="tableColumns"
|
||||||
|
:loading="tableState.loading"
|
||||||
|
:data-source="tableState.data"
|
||||||
|
:size="tableState.size"
|
||||||
|
:pagination="tablePagination"
|
||||||
|
:scroll="{ x: tableColumns.length * 120 }"
|
||||||
|
:row-selection="{
|
||||||
|
type: 'checkbox',
|
||||||
|
columnWidth: '48px',
|
||||||
|
selectedRowKeys: tableState.selectedRowKeys,
|
||||||
|
onChange: fnTableSelectedRowKeys,
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<template #bodyCell="{ column, record }">
|
||||||
|
<template v-if="column.key === 'status'">
|
||||||
|
<DictTag :options="dict.neInfoStatus" :value="record.status" />
|
||||||
|
</template>
|
||||||
|
<template v-if="column.key === 'id'">
|
||||||
|
<a-space :size="8" align="center">
|
||||||
|
<a-button
|
||||||
|
type="link"
|
||||||
|
@click.prevent="fnRecordMore('core', record)"
|
||||||
|
>
|
||||||
|
<template #icon><FormOutlined /></template>
|
||||||
|
关联核心网
|
||||||
|
</a-button>
|
||||||
|
<a-tooltip>
|
||||||
|
<template #title>{{ t('common.editText') }}</template>
|
||||||
|
<a-button
|
||||||
|
type="link"
|
||||||
|
@click.prevent="fnModalVisibleByEdit(record)"
|
||||||
|
>
|
||||||
|
<template #icon><FormOutlined /></template>
|
||||||
|
</a-button>
|
||||||
|
</a-tooltip>
|
||||||
|
<a-tooltip>
|
||||||
|
<template #title>
|
||||||
|
{{ t('views.ne.common.restart') }}
|
||||||
|
</template>
|
||||||
|
<a-button
|
||||||
|
type="link"
|
||||||
|
@click.prevent="fnRecordMore('restart', record)"
|
||||||
|
>
|
||||||
|
<template #icon><UndoOutlined /></template>
|
||||||
|
</a-button>
|
||||||
|
</a-tooltip>
|
||||||
|
<a-tooltip placement="left">
|
||||||
|
<template #title>{{ t('common.moreText') }}</template>
|
||||||
|
<a-dropdown placement="bottomRight" trigger="click">
|
||||||
|
<a-button type="link">
|
||||||
|
<template #icon><EllipsisOutlined /> </template>
|
||||||
|
</a-button>
|
||||||
|
<template #overlay>
|
||||||
|
<a-menu @click="({ key }:any) => fnRecordMore(key, record)">
|
||||||
|
<a-menu-item key="log">
|
||||||
|
<FileTextOutlined />
|
||||||
|
{{ t('views.ne.common.log') }}
|
||||||
|
</a-menu-item>
|
||||||
|
<a-menu-item key="start">
|
||||||
|
<ThunderboltOutlined />
|
||||||
|
{{ t('views.ne.common.start') }}
|
||||||
|
</a-menu-item>
|
||||||
|
<a-menu-item key="stop">
|
||||||
|
<CloseSquareOutlined />
|
||||||
|
{{ t('views.ne.common.stop') }}
|
||||||
|
</a-menu-item>
|
||||||
|
<a-menu-item key="reload" v-if="false">
|
||||||
|
<SyncOutlined />
|
||||||
|
{{ t('views.ne.common.reload') }}
|
||||||
|
</a-menu-item>
|
||||||
|
<a-menu-item key="delete">
|
||||||
|
<DeleteOutlined />
|
||||||
|
{{ t('common.deleteText') }}
|
||||||
|
</a-menu-item>
|
||||||
|
<a-menu-item
|
||||||
|
key="oam"
|
||||||
|
v-if="!['OMC'].includes(record.neType)"
|
||||||
|
>
|
||||||
|
<FileTextOutlined />
|
||||||
|
{{ t('views.ne.common.oam') }}
|
||||||
|
</a-menu-item>
|
||||||
|
<a-menu-item
|
||||||
|
key="license"
|
||||||
|
v-if="!['OMC'].includes(record.neType)"
|
||||||
|
>
|
||||||
|
<FileTextOutlined />
|
||||||
|
{{ t('views.ne.common.license') }}
|
||||||
|
</a-menu-item>
|
||||||
|
<!-- 配置备份 -->
|
||||||
|
<a-menu-item key="backConfExport">
|
||||||
|
<ExportOutlined />
|
||||||
|
{{ t('views.ne.neInfo.backConf.export') }}
|
||||||
|
</a-menu-item>
|
||||||
|
<a-menu-item key="backConfImport">
|
||||||
|
<ImportOutlined />
|
||||||
|
{{ t('views.ne.neInfo.backConf.import') }}
|
||||||
|
</a-menu-item>
|
||||||
|
</a-menu>
|
||||||
|
</template>
|
||||||
|
</a-dropdown>
|
||||||
|
</a-tooltip>
|
||||||
|
</a-space>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
<template #expandedRowRender="{ record }">
|
||||||
|
<a-row>
|
||||||
|
<a-col :offset="2" :lg="8" :md="8" :xs="8">
|
||||||
|
<a-divider orientation="left">
|
||||||
|
{{ t('views.ne.neInfo.info') }}
|
||||||
|
</a-divider>
|
||||||
|
<div>
|
||||||
|
<span>{{ t('views.ne.neInfo.serviceState') }}:</span>
|
||||||
|
<DictTag :options="dict.neInfoStatus" :value="record.status" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<span>{{ t('views.ne.neVersion.version') }}:</span>
|
||||||
|
<span>{{ record.serverState.version }}</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<span>{{ t('views.ne.common.serialNum') }}:</span>
|
||||||
|
<span>{{ record.serverState.sn }}</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<span>{{ t('views.ne.common.expiryDate') }}:</span>
|
||||||
|
<span>{{ record.serverState.expire }}</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<span>{{ t('views.ne.common.ueNumber') }}:</span>
|
||||||
|
<span
|
||||||
|
v-if="
|
||||||
|
['UDM', 'AMF', 'MME'].includes(record.serverState.neType)
|
||||||
|
"
|
||||||
|
>
|
||||||
|
{{ record.serverState.ueNumber }}
|
||||||
|
</span>
|
||||||
|
<span v-else> - </span>
|
||||||
|
</div>
|
||||||
|
<div v-if="['AMF', 'MME'].includes(record.serverState.neType)">
|
||||||
|
<span>{{ t('views.ne.common.nbNumber') }}:</span>
|
||||||
|
<span> {{ record.serverState.nbNumber }} </span>
|
||||||
|
</div>
|
||||||
|
</a-col>
|
||||||
|
<a-col :offset="2" :lg="8" :md="8" :xs="8">
|
||||||
|
<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="
|
||||||
|
record.resoures.nfCpuUsage < 30
|
||||||
|
? '#52c41a'
|
||||||
|
: record.resoures.nfCpuUsage > 70
|
||||||
|
? '#ff4d4f'
|
||||||
|
: '#1890ff'
|
||||||
|
"
|
||||||
|
:percent="record.resoures.nfCpuUsage"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<span>{{ t('views.ne.neInfo.sysCpu') }}:</span>
|
||||||
|
<a-progress
|
||||||
|
status="normal"
|
||||||
|
:stroke-color="
|
||||||
|
record.resoures.sysCpuUsage < 30
|
||||||
|
? '#52c41a'
|
||||||
|
: record.resoures.sysCpuUsage > 70
|
||||||
|
? '#ff4d4f'
|
||||||
|
: '#1890ff'
|
||||||
|
"
|
||||||
|
:percent="record.resoures.sysCpuUsage"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<span>{{ t('views.ne.neInfo.sysMem') }}:</span>
|
||||||
|
<a-progress
|
||||||
|
status="normal"
|
||||||
|
:stroke-color="
|
||||||
|
record.resoures.sysMemUsage < 30
|
||||||
|
? '#52c41a'
|
||||||
|
: record.resoures.sysMemUsage > 70
|
||||||
|
? '#ff4d4f'
|
||||||
|
: '#1890ff'
|
||||||
|
"
|
||||||
|
:percent="record.resoures.sysMemUsage"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<span>{{ t('views.ne.neInfo.sysDisk') }}:</span>
|
||||||
|
<a-progress
|
||||||
|
status="normal"
|
||||||
|
:stroke-color="
|
||||||
|
record.resoures.sysDiskUsage < 30
|
||||||
|
? '#52c41a'
|
||||||
|
: record.resoures.sysDiskUsage > 70
|
||||||
|
? '#ff4d4f'
|
||||||
|
: '#1890ff'
|
||||||
|
"
|
||||||
|
:percent="record.resoures.sysDiskUsage"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</template>
|
||||||
|
</a-table>
|
||||||
|
</a-card>
|
||||||
|
|
||||||
|
<!-- 新增框或修改框 -->
|
||||||
|
<EditModal
|
||||||
|
v-model:open="modalState.openByEdit"
|
||||||
|
:id="modalState.id"
|
||||||
|
@ok="fnModalEditOk"
|
||||||
|
@cancel="fnModalEditCancel"
|
||||||
|
></EditModal>
|
||||||
|
|
||||||
|
<!-- 核心网关联框 -->
|
||||||
|
<CoreModal
|
||||||
|
v-model:open="modalState.openByCore"
|
||||||
|
:ne-uid="modalState.neUid"
|
||||||
|
:core-uid="modalState.coreUid"
|
||||||
|
@cancel="fnModalEditCancel"
|
||||||
|
></CoreModal>
|
||||||
|
|
||||||
|
<!-- OAM编辑框 -->
|
||||||
|
<OAMModal
|
||||||
|
v-model:open="modalState.openByOAM"
|
||||||
|
:ne-uid="modalState.neUid"
|
||||||
|
:ne-type="modalState.neType"
|
||||||
|
@cancel="fnModalEditCancel"
|
||||||
|
></OAMModal>
|
||||||
|
|
||||||
|
<!-- 配置文件备份框 -->
|
||||||
|
<BackConfModal
|
||||||
|
ref="backConf"
|
||||||
|
v-model:open="modalState.openByBackConf"
|
||||||
|
:ne-uid="modalState.neUid"
|
||||||
|
:ne-type="modalState.neType"
|
||||||
|
@cancel="fnModalEditCancel"
|
||||||
|
></BackConfModal>
|
||||||
|
|
||||||
|
<!-- 文件上传框 -->
|
||||||
|
<LicenseEditModal
|
||||||
|
v-model:open="modalState.openByLicense"
|
||||||
|
:id="modalState.id"
|
||||||
|
:ne-uid="modalState.neUid"
|
||||||
|
:ne-type="modalState.neType"
|
||||||
|
@ok="fnModalEditOk"
|
||||||
|
@cancel="fnModalEditCancel"
|
||||||
|
></LicenseEditModal>
|
||||||
|
</PageContainer>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.table :deep(.ant-pagination) {
|
||||||
|
padding: 0 24px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
18
src/views/ne/overview/index.vue
Normal file
18
src/views/ne/overview/index.vue
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { onMounted } from 'vue';
|
||||||
|
import { PageContainer } from 'antdv-pro-layout';
|
||||||
|
|
||||||
|
onMounted(() => {});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<PageContainer>
|
||||||
|
<a-card :bordered="false" :body-style="{ padding: '0px' }">
|
||||||
|
<h1>概览</h1>
|
||||||
|
|
||||||
|
网元cpu/men/disk
|
||||||
|
</a-card>
|
||||||
|
</PageContainer>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="less" scoped></style>
|
||||||
Reference in New Issue
Block a user