feat: 添加网元配置文件备份的FTP配置管理功能

This commit is contained in:
TsMask
2025-04-10 21:07:29 +08:00
parent 4dda60c8c4
commit fc233c38ea
2 changed files with 279 additions and 16 deletions

View File

@@ -1,4 +1,6 @@
import { CACHE_SESSION_CRYPTO_API } from '@/constants/cache-keys-constants';
import { request } from '@/plugins/http-fetch';
import { sessionGet } from '@/utils/cache-session-utils';
/**
* 网元配置文件备份记录列表
@@ -80,4 +82,44 @@ export function importNeConfigBackup(data: Record<string, any>) {
method: 'POST',
data: data,
});
}
}
/**
* 更新FTP信息
* @param data 数据
* @returns object
*/
export function updateFTPInfo(data: Record<string, any>) {
return request({
url: `/ne/config/backup/ftp`,
method: 'POST',
data: data,
crypto: sessionGet(CACHE_SESSION_CRYPTO_API) !== 'false',
});
}
/**
* 获取FTP信息
* @param data 数据
* @returns object
*/
export function getFTPInfo() {
return request({
url: `/ne/config/backup/ftp`,
method: 'GET',
crypto: sessionGet(CACHE_SESSION_CRYPTO_API) !== 'false',
});
}
/**
* 发送FTP文件
* @param data 数据
* @returns object
*/
export function putFTPInfo(path: string) {
return request({
url: `/ne/config/backup/ftp`,
method: 'PUT',
data: { path },
});
}

View File

@@ -11,11 +11,15 @@ import useDictStore from '@/store/modules/dict';
import { NE_TYPE_LIST } from '@/constants/ne-constants';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { parseDateToStr } from '@/utils/date-utils';
import { regExpIPv4 } from '@/utils/regular-utils';
import {
delNeConfigBackup,
downNeConfigBackup,
listNeConfigBackup,
updateNeConfigBackup,
getFTPInfo,
putFTPInfo,
updateFTPInfo,
} from '@/api/ne/neConfigBackup';
import saveAs from 'file-saver';
const { t } = useI18n();
@@ -58,8 +62,6 @@ type TabeStateType = {
loading: boolean;
/**紧凑型 */
size: SizeType;
/**搜索栏 */
seached: boolean;
/**记录数据 */
data: any[];
/**勾选记录 */
@@ -70,7 +72,6 @@ type TabeStateType = {
let tableState: TabeStateType = reactive({
loading: false,
size: 'middle',
seached: false,
data: [],
selectedRowKeys: [],
});
@@ -98,12 +99,12 @@ let tableColumns = ref<TableColumnsType>([
{
title: t('common.createTime'),
dataIndex: 'createTime',
align: 'center',
align: 'left',
customRender(opt) {
if (!opt.value) return '';
return parseDateToStr(opt.value);
},
width: 150,
width: 200,
},
{
title: t('views.ne.neConfigBackup.name'),
@@ -179,7 +180,7 @@ function fnGetList(pageNum?: number) {
queryParams.pageNum = pageNum;
}
listNeConfigBackup(toRaw(queryParams)).then(res => {
if (res.code === RESULT_CODE_SUCCESS) {
if (res.code === RESULT_CODE_SUCCESS) {
const { total, rows } = res.data;
tablePagination.total = total;
tableState.data = rows;
@@ -387,12 +388,125 @@ onMounted(() => {
fnGetList();
});
});
/**FTP日志对象信息状态 */
let modalStateFTP: ModalStateType = reactive({
openByEdit: false,
title: '设置远程备份配置',
from: {
username: '',
password: '',
toIp: '',
toPort: 22,
enable: false,
dir: '',
},
confirmLoading: false,
});
/**FTP日志对象信息内表单属性和校验规则 */
const modalStateFTPFrom = Form.useForm(
modalStateFTP.from,
reactive({
toIp: [
{
required: true,
pattern: regExpIPv4,
message: 'Please enter the service login IP',
},
],
username: [
{
required: true,
trigger: 'blur',
message: 'Please enter the service login user name',
},
],
dir: [
{
required: true,
trigger: 'blur',
message: 'Please enter the service address target file directory',
},
],
})
);
/**
* 对话框弹出显示为 新增或者修改
* @param configId 参数编号id, 不传为新增
*/
function fnModalFTPVisibleByEdit() {
if (modalStateFTP.confirmLoading) return;
const hide = message.loading(t('common.loading'), 0);
modalStateFTP.confirmLoading = true;
getFTPInfo().then(res => {
modalStateFTP.confirmLoading = false;
hide();
if (res.code === RESULT_CODE_SUCCESS && res.data) {
modalStateFTP.from = Object.assign(modalStateFTP.from, res.data);
modalStateFTP.title = 'Setting Remote Backup';
modalStateFTP.openByEdit = true;
} else {
message.error(res.msg, 3);
modalStateFTP.title = 'Setting Remote Backup';
modalStateFTP.openByEdit = false;
}
});
}
/**FTP对象保存 */
function fnModalFTPOk() {
modalStateFTPFrom.validate().then(() => {
modalStateFTP.confirmLoading = true;
const from = toRaw(modalStateFTP.from);
updateFTPInfo(from)
.then(res => {
if (res.code === RESULT_CODE_SUCCESS) {
message.success(`Configuration saved successfully`, 3);
fnModalFTPCancel();
} else {
message.warning(`Configuration save exception`, 3);
}
})
.finally(() => {
modalStateFTP.confirmLoading = false;
});
});
}
/**
* 对话框弹出关闭执行函数
* 进行表达规则校验
*/
function fnModalFTPCancel() {
modalStateFTP.openByEdit = false;
modalStateFTPFrom.resetFields();
}
/**
* 同步文件到FTP
* @param row
*/
function fnSyncFileToFTP(row: Record<string, any>) {
modalStateFTP.confirmLoading = true;
putFTPInfo(row.path)
.then(res => {
if (res.code === RESULT_CODE_SUCCESS) {
message.success(t('common.operateOk'), 3);
} else {
message.warning(res.msg, 3);
}
})
.finally(() => {
modalStateFTP.confirmLoading = false;
});
}
</script>
<template>
<PageContainer>
<a-card
v-show="tableState.seached"
:bordered="false"
:body-style="{ marginBottom: '24px', paddingBottom: 0 }"
>
@@ -457,14 +571,11 @@ onMounted(() => {
<!-- 插槽-卡片右侧 -->
<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 placement="topRight">
<template #title>Setting Remote Backup</template>
<a-button type="text" @click.prevent="fnModalFTPVisibleByEdit()">
<template #icon><DeliveredProcedureOutlined /></template>
</a-button>
</a-tooltip>
<a-tooltip>
<template #title>{{ t('common.reloadText') }}</template>
@@ -520,6 +631,16 @@ onMounted(() => {
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'id'">
<a-space :size="8" align="center">
<a-tooltip placement="topRight">
<template #title>Send Current File To Remote Backup</template>
<a-button
type="link"
:loading="modalStateFTP.confirmLoading"
@click.prevent="fnSyncFileToFTP(record)"
>
<template #icon><CloudServerOutlined /></template>
</a-button>
</a-tooltip>
<a-tooltip>
<template #title>{{ t('common.downloadText') }}</template>
<a-button type="link" @click.prevent="fnDownloadFile(record)">
@@ -597,6 +718,106 @@ onMounted(() => {
</a-form-item>
</a-form>
</ProModal>
<!-- FTP -->
<ProModal
:drag="true"
:width="800"
:destroyOnClose="true"
:keyboard="false"
:mask-closable="false"
:open="modalStateFTP.openByEdit"
:title="modalStateFTP.title"
:confirm-loading="modalStateFTP.confirmLoading"
@ok="fnModalFTPOk"
@cancel="fnModalFTPCancel"
>
<a-form
name="modalStateFTPFrom"
layout="horizontal"
:label-col="{ span: 6 }"
:label-wrap="true"
>
<a-form-item label="Enable" name="enable" :label-col="{ span: 3 }">
<a-switch
v-model:checked="modalStateFTP.from.enable"
:checked-children="t('common.switch.open')"
:un-checked-children="t('common.switch.shut')"
/>
</a-form-item>
<template v-if="modalStateFTP.from.enable">
<a-row>
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
label="Service IP"
name="toIp"
v-bind="modalStateFTPFrom.validateInfos.toIp"
>
<a-input
v-model:value="modalStateFTP.from.toIp"
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="Service Port"
name="toPort"
v-bind="modalStateFTPFrom.validateInfos.toPort"
>
<a-input-number
v-model:value="modalStateFTP.from.toPort"
allow-clear
:placeholder="t('common.inputPlease')"
></a-input-number>
</a-form-item>
</a-col>
</a-row>
<a-row>
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
label="UserName"
name="username"
v-bind="modalStateFTPFrom.validateInfos.username"
>
<a-input
v-model:value="modalStateFTP.from.username"
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="Password"
name="password"
v-bind="modalStateFTPFrom.validateInfos.password"
>
<a-input-password
v-model:value="modalStateFTP.from.password"
allow-clear
:placeholder="t('common.inputPlease')"
></a-input-password>
</a-form-item>
</a-col>
</a-row>
<a-form-item
label="Save Dir"
name="dir"
v-bind="modalStateFTPFrom.validateInfos.dir"
:label-col="{ span: 3 }"
>
<a-input
v-model:value="modalStateFTP.from.dir"
allow-clear
:placeholder="t('common.inputPlease')"
></a-input>
</a-form-item>
</template>
</a-form>
</ProModal>
</PageContainer>
</template>