feat: 网元信息页面代码抽离组件,补充新增修改接口

This commit is contained in:
TsMask
2024-03-01 18:57:24 +08:00
parent 9b5b43c2bf
commit bd13b70a88
3 changed files with 792 additions and 936 deletions

View File

@@ -14,9 +14,60 @@ export function listNeInfo(query: Record<string, any>) {
});
}
/**
* 查询网元信息详细
* @param infoId 信息ID
* @returns object
*/
export function getNeInfo(infoId: string | number) {
return request({
url: `/ne/info/${infoId}`,
method: 'get',
});
}
/**
* 网元信息新增
* @param data 网元对象
* @returns object
*/
export function addNeInfo(data: Record<string, any>) {
return request({
url: `/ne/info`,
method: 'post',
data: data,
});
}
/**
* 网元信息修改
* @param data 网元对象
* @returns object
*/
export function updateNeInfo(data: Record<string, any>) {
return request({
url: `/ne/info`,
method: 'put',
data: data,
});
}
/**
* 网元信息删除
* @param id 信息ID
* @returns object
*/
export function delNeInfo(infoIds: string | number) {
return request({
url: `/ne/info/${infoIds}`,
method: 'delete',
timeout: 60_000,
});
}
/**
* 查询网元列表全部无分页
* @param query 查询参数
* @param query 查询参数 neType neId bandStatus
* @returns object
*/
export function listAllNeInfo(query: Record<string, any>) {

View File

@@ -0,0 +1,687 @@
<script setup lang="ts">
import { reactive, onMounted, toRaw, watch } from 'vue';
import { message, Form } from 'ant-design-vue/lib';
import useI18n from '@/hooks/useI18n';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import useNeInfoStore from '@/store/modules/neinfo';
import { getNeInfo, addNeInfo, updateNeInfo } from '@/api/ne/neInfo';
import { NE_TYPE_LIST } from '@/constants/ne-constants';
import { testNeHost } from '@/api/ne/neHost';
import useDictStore from '@/store/modules/dict';
const { getDict } = useDictStore();
const { t } = useI18n();
const emit = defineEmits(['ok', 'cancel', 'update:visible']);
const props = defineProps({
visible: {
type: Boolean,
default: false,
},
editId: {
type: String,
default: '',
},
});
/**字典数据 */
let dict: {
/**主机类型 */
neHostType: DictType[];
/**分组 */
neHostGroupId: DictType[];
/**认证模式 */
neHostAuthMode: DictType[];
} = reactive({
neHostType: [],
neHostGroupId: [],
neHostAuthMode: [],
});
/**
* 对话框弹出测试连接
*/
function fnModalTest() {
testNeHost({})
.then(res => {
if (res.code === RESULT_CODE_SUCCESS) {
message.success({
content: t('views.ne.neHost.testOk'),
duration: 2,
});
} else {
message.error({
content: `${res.msg}`,
duration: 2,
});
}
})
.finally(() => {
modalState.confirmLoading = false;
});
}
/**对话框对象信息状态类型 */
type ModalStateType = {
/**新增框或修改框是否显示 */
visibleByEdit: boolean;
/**标题 */
title: string;
/**表单数据 */
from: Record<string, any>;
/**确定按钮 loading */
confirmLoading: boolean;
};
/**对话框对象信息状态 */
let modalState: ModalStateType = reactive({
visibleByEdit: false,
title: '网元',
from: {
id: undefined,
neId: '001',
neType: 'OMC',
neName: '',
ip: '',
port: 3030,
pvFlag: 'PNF',
rmUid: '4400HX1OMC001',
neAddress: '',
dn: '',
vendorName: '',
province: '',
// 主机
hosts: [
{
hostId: undefined,
hostType: 'ssh',
groupId: '0',
title: '',
addr: '',
port: 22,
user: 'user',
authMode: '0',
password: 'user',
privateKey: '',
passPhrase: '',
remark: '',
},
{
hostId: undefined,
hostType: 'telnet',
groupId: '0',
title: '',
addr: '',
port: 4100,
user: 'user',
password: 'user',
remark: '',
},
],
},
confirmLoading: false,
});
/**对话框内表单属性和校验规则 */
const modalStateFrom = Form.useForm(
modalState.from,
reactive({
neType: [
{
required: true,
message: '请输入网元类型',
},
],
neId: [
{
required: true,
message: '请输入网元标识',
},
],
rmUid: [
{
required: true,
message: '请输入资源唯一标识',
},
],
ip: [
{
required: true,
message: '请输入网元IP地址',
},
],
neName: [
{
required: true,
message: '请输入网元名称',
},
],
})
);
/**
* 对话框弹出显示为 新增或者修改
* @param editId 网元id, 不传为新增
*/
function fnModalVisibleByEdit(editId: string) {
if (!editId) {
modalStateFrom.resetFields();
modalState.title = t('views.configManage.neManage.addNe');
modalState.visibleByEdit = true;
} else {
if (modalState.confirmLoading) return;
const hide = message.loading(t('common.loading'), 0);
modalState.confirmLoading = true;
getNeInfo(editId).then(res => {
modalState.confirmLoading = false;
hide();
if (res.code === RESULT_CODE_SUCCESS) {
modalState.from = Object.assign(modalState.from, res.data);
modalState.title = '编辑网元信息';
modalState.visibleByEdit = 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({
content: '操作成功',
duration: 3,
});
// 刷新缓存的网元信息
useNeInfoStore().fnRefreshNelist();
emit('ok');
fnModalCancel();
} else {
message.error({
content: `${t('views.configManage.neManage.operFail')}`,
duration: 3,
});
}
})
.finally(() => {
hide();
modalState.confirmLoading = false;
});
})
.catch(e => {
message.error(t('common.errorFields', { num: e.errorFields.length }), 3);
});
}
/**
* 对话框弹出关闭执行函数
* 进行表达规则校验
*/
function fnModalCancel() {
modalState.visibleByEdit = false;
modalStateFrom.resetFields();
emit('cancel');
}
/**监听是否显示,初始数据 */
watch(
() => props.visible,
val => {
if (val) fnModalVisibleByEdit(props.editId);
}
);
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>
<DraggableModal
width="800px"
:keyboard="false"
:mask-closable="false"
:visible="modalState.visibleByEdit"
: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 :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.configManage.neManage.neType')"
name="neType"
v-bind="modalStateFrom.validateInfos.neType"
>
<a-auto-complete
v-model:value="modalState.from.neType"
:options="NE_TYPE_LIST.map(v => ({ value: v }))"
>
<a-input
allow-clear
:placeholder="t('common.inputPlease')"
:maxlength="32"
>
<template #prefix>
<a-tooltip placement="topLeft">
<template #title>
{{ t('views.configManage.neManage.neTypeTip') }}
</template>
<InfoCircleOutlined style="color: rgba(0, 0, 0, 0.45)" />
</a-tooltip>
</template>
</a-input>
</a-auto-complete>
</a-form-item>
</a-col>
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.configManage.neManage.pvflag')"
name="pvFlag"
v-bind="modalStateFrom.validateInfos.pvFlag"
>
<a-select
v-model:value="modalState.from.pvFlag"
default-value="PNF"
>
<a-select-opt-group :label="t('views.configManage.neManage.pnf')">
<a-select-option value="PNF">PNF</a-select-option>
</a-select-opt-group>
<a-select-opt-group :label="t('views.configManage.neManage.vnf')">
<a-select-option value="VNF">VNF</a-select-option>
</a-select-opt-group>
</a-select>
</a-form-item>
</a-col>
</a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.configManage.neManage.neId')"
name="neId"
v-bind="modalStateFrom.validateInfos.neId"
>
<a-input
v-model:value="modalState.from.neId"
allow-clear
:maxlength="32"
></a-input>
</a-form-item>
</a-col>
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.configManage.neManage.neName')"
name="neName"
v-bind="modalStateFrom.validateInfos.neName"
>
<a-input
v-model:value="modalState.from.neName"
allow-clear
:maxlength="64"
>
</a-input>
</a-form-item>
</a-col>
</a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.configManage.neManage.ip')"
name="ip"
v-bind="modalStateFrom.validateInfos.ip"
>
<a-input
v-model:value="modalState.from.ip"
allow-clear
:maxlength="128"
@change=""
></a-input>
</a-form-item>
</a-col>
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.configManage.neManage.port')"
name="port"
v-bind="modalStateFrom.validateInfos.port"
>
<a-input-number
v-model:value="modalState.from.port"
style="width: 100%"
:min="1"
:max="65535"
placeholder="<=65535"
>
<template #prefix>
<a-tooltip placement="topLeft">
<template #title>
<div>{{ t('views.configManage.neManage.portTip') }}</div>
</template>
<InfoCircleOutlined style="color: rgba(0, 0, 0, 0.45)" />
</a-tooltip>
</template>
</a-input-number>
</a-form-item>
</a-col>
</a-row>
<a-form-item
:label="t('views.configManage.neManage.uid')"
name="rmUid"
v-bind="modalStateFrom.validateInfos.rmUid"
:label-col="{ span: 3 }"
:labelWrap="true"
>
<a-input
v-model:value="modalState.from.rmUid"
allow-clear
:maxlength="40"
:placeholder="t('views.configManage.neManage.uidTip')"
>
</a-input>
</a-form-item>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.configManage.neManage.mac')"
name="neAddress"
>
<a-input
v-model:value="modalState.from.neAddress"
allow-clear
:maxlength="64"
><template #prefix>
<a-tooltip placement="topLeft">
<template #title>
<div>{{ t('views.configManage.neManage.macTip') }}</div>
</template>
<InfoCircleOutlined style="color: rgba(0, 0, 0, 0.45)" />
</a-tooltip> </template
></a-input>
</a-form-item>
</a-col>
<a-col :lg="12" :md="12" :xs="24">
<a-form-item :label="t('views.configManage.neManage.dn')" name="dn">
<a-input
v-model:value="modalState.from.dn"
allow-clear
:maxlength="255"
></a-input>
</a-form-item>
</a-col>
</a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.configManage.neManage.vendorName')"
name="vendorName"
>
<a-input
v-model:value="modalState.from.vendorName"
allow-clear
:maxlength="64"
>
</a-input>
</a-form-item>
</a-col>
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.configManage.neManage.province')"
name="province"
>
<a-input
v-model:value="modalState.from.province"
allow-clear
:maxlength="32"
></a-input>
</a-form-item>
</a-col>
</a-row>
<!-- 主机连接配置 -->
<a-collapse class="collapse" ghost>
<a-collapse-panel key="ssh" header="配置SSH">
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.configManage.neManage.province')"
name="province"
>
<a-input
v-model:value="modalState.from.province"
allow-clear
></a-input>
</a-form-item>
</a-col>
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.configManage.neManage.sync')"
name="province"
>
<a-switch
v-model:checked="modalState.from.sync"
:checked-children="t('views.configManage.neManage.open')"
:un-checked-children="t('views.configManage.neManage.close')"
/>
</a-form-item>
</a-col>
</a-row>
</a-collapse-panel>
<a-collapse-panel
:key="`${host.hostType}_${host.title}`"
:header="host.hostType.toUpperCase()"
v-for="host in modalState.from.hosts"
>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.ne.neHost.hostType')"
name="hostType"
>
<a-select
v-model:value="host.hostType"
default-value="ssh"
:options="dict.neHostType"
>
</a-select>
</a-form-item>
</a-col>
<a-col :lg="12" :md="12" :xs="24">
<a-form-item :label="t('views.ne.neHost.groupId')" name="groupId">
<a-select
v-model:value="modalState.from.groupId"
default-value="0"
:options="dict.neHostGroupId"
>
</a-select>
</a-form-item>
</a-col>
</a-row>
<a-form-item
:label="t('views.ne.neHost.title')"
name="title"
v-bind="modalStateFrom.validateInfos.title"
:label-col="{ span: 3 }"
:label-wrap="true"
>
<a-input
v-model:value="modalState.from.title"
allow-clear
:maxlength="50"
>
</a-input>
</a-form-item>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.ne.neHost.addr')"
name="addr"
v-bind="modalStateFrom.validateInfos.addr"
>
<a-input
v-model:value="modalState.from.addr"
allow-clear
:maxlength="50"
>
</a-input>
</a-form-item>
</a-col>
<a-col :lg="12" :md="12" :xs="24">
<a-form-item :label="t('views.ne.neHost.port')" name="port">
<a-input-number
v-model:value="modalState.from.port"
:min="10"
:max="65535"
:step="1"
style="width: 100%"
></a-input-number>
</a-form-item>
</a-col>
</a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.ne.neHost.user')"
name="user"
v-bind="modalStateFrom.validateInfos.user"
>
<a-input v-model:value="modalState.from.user" allow-clear>
</a-input>
</a-form-item>
</a-col>
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.ne.neHost.authMode')"
name="authMode"
>
<a-select
v-model:value="modalState.from.authMode"
default-value="0"
:options="dict.neHostAuthMode"
>
</a-select>
</a-form-item>
</a-col>
</a-row>
<a-form-item
v-if="modalState.from.authMode === '0'"
:label="t('views.ne.neHost.password')"
name="password"
:label-col="{ span: 3 }"
:label-wrap="true"
>
<a-input
v-model:value="modalState.from.password"
allow-clear
:maxlength="256"
>
</a-input>
</a-form-item>
<template v-if="modalState.from.authMode === '1'">
<a-form-item
:label="t('views.ne.neHost.privateKey')"
name="privateKey"
:label-col="{ span: 3 }"
:label-wrap="true"
>
<a-textarea
v-model:value="modalState.from.privateKey"
:auto-size="{ minRows: 4, maxRows: 6 }"
:maxlength="3000"
:show-count="true"
/>
</a-form-item>
<a-form-item
:label="t('views.ne.neHost.passPhrase')"
name="passPhrase"
:label-col="{ span: 3 }"
:label-wrap="true"
>
<a-input v-model:value="modalState.from.passPhrase" allow-clear>
</a-input>
</a-form-item>
</template>
<a-form-item
:label="t('views.ne.neHost.remark')"
name="remark"
:label-col="{ span: 3 }"
:label-wrap="true"
>
<a-textarea
v-model:value="modalState.from.remark"
:auto-size="{ minRows: 4, maxRows: 6 }"
:maxlength="450"
:show-count="true"
/>
</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="fnModalTest"
:loading="modalState.confirmLoading"
>
<template #icon><LinkOutlined /></template>
</a-button>
</a-form-item>
</a-collapse-panel>
</a-collapse>
</a-form>
</DraggableModal>
</template>
<style lang="less" scoped>
.collapse :deep(.ant-collapse-item) > .ant-collapse-header {
padding-left: 0;
padding-right: 0;
}
</style>

File diff suppressed because it is too large Load Diff