feat: 添加系统备份功能,包括导入导出OMC的API和界面支持

This commit is contained in:
TsMask
2025-09-19 12:04:49 +08:00
parent 98e4d39cdf
commit c01380da6b
5 changed files with 197 additions and 8 deletions

View File

@@ -36,3 +36,33 @@ export function updateBackupFTP(data: Record<string, any>) {
data, data,
}); });
} }
/**
* 备份文件-导出OMC
* @returns object
*/
export function exportBackupOMC() {
return request({
url: '/neData/backup/export-omc',
method: 'POST',
responseType: 'blob',
timeout: 180_000,
});
}
/**
* 备份文件-导入OMC
* @param filePath 备份文件上传返回的/upload 路径
* @returns object
*/
export function importBackupOMC(filePath: string) {
return request({
url: '/neData/backup/import-omc',
method: 'POST',
data: {
neType: 'OMC',
path: filePath,
},
timeout: 180_000,
});
}

View File

@@ -1916,6 +1916,10 @@ export default {
home: 'Home Page', home: 'Home Page',
homeTip:'Do you want to submit the current interface as the system interface?', homeTip:'Do you want to submit the current interface as the system interface?',
homeSet:'Home Page Settings', homeSet:'Home Page Settings',
backup: 'System Backup',
backupInstruction: 'System backup will back up the net element information records and configuration files running on the current system, and can restore the system to the previous state!',
backupExportTip: 'Confirm to export system backup?',
backupImportTip: 'Confirm to import system backup?',
}, },
role:{ role:{
allScopeOptions:'All data permissions', allScopeOptions:'All data permissions',

View File

@@ -1916,6 +1916,10 @@ export default {
home: '系统首页', home: '系统首页',
homeTip:'确认要提交当前界面为系统界面吗?', homeTip:'确认要提交当前界面为系统界面吗?',
homeSet:'系统首页设置', homeSet:'系统首页设置',
backup: '系统备份',
backupInstruction: '系统备份将会对当前系统上运行的网元信息记录及配置文件进行备份,可进行系统的恢复操作!',
backupExportTip: '确认要导出系统备份吗?',
backupImportTip: '确认要导入系统备份吗?',
}, },
role:{ role:{
allScopeOptions:'全部数据权限', allScopeOptions:'全部数据权限',

View File

@@ -0,0 +1,140 @@
<script lang="ts" setup>
import { message, Modal } from 'ant-design-vue/es';
import { reactive } from 'vue';
import useI18n from '@/hooks/useI18n';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { FileType } from 'ant-design-vue/es/upload/interface';
import { UploadRequestOption } from 'ant-design-vue/es/vc-upload/interface';
import { uploadFileChunk } from '@/api/tool/file';
import { exportBackupOMC, importBackupOMC } from '@/api/neData/backup';
import saveAs from 'file-saver';
const { t } = useI18n();
type StateType = {
loading: boolean;
};
let state: StateType = reactive({
loading: false,
});
/**导出 */
function fnExport() {
Modal.confirm({
title: t('common.tipTitle'),
content: t('views.system.setting.backupExportTip'),
onOk() {
const hide = message.loading(t('common.loading'), 0);
exportBackupOMC()
.then(res => {
if (res.code === RESULT_CODE_SUCCESS) {
message.success({
content: t('common.operateOk'),
duration: 3,
});
saveAs(res.data, `BackupOMC-${Date.now()}.zip`);
} else {
message.error({
content: `${res.msg}`,
duration: 3,
});
}
})
.finally(() => {
hide();
});
},
});
}
/**上传前检查或转换压缩 */
function fnBeforeUpload(file: FileType) {
if (state.loading) return false;
console.log(file);
if (file.type !== 'application/x-zip-compressed') {
message.error(
t('views.system.setting.uploadFormat', { format: 'zip' }),
3
);
}
// const isLt10M = file.size / 1024 / 1024 < 10;
// if (!isLt10M) {
// message.error(t('views.system.setting.uploadSize', { size: 10 }), 3);
// }
return true;
}
/**上传变更 */
function fnUpload(up: UploadRequestOption) {
Modal.confirm({
title: t('common.tipTitle'),
content: t('views.system.setting.backupImportTip'),
onOk() {
// 发送请求
const hide = message.loading(t('common.loading'), 0);
state.loading = true;
uploadFileChunk(up.file as File, 5, 'import')
.then(res => {
if (res.code === RESULT_CODE_SUCCESS) {
return importBackupOMC(res.data.filePath);
}
return undefined;
})
.then(res => {
if (!res) {
return;
}
if (res.code === RESULT_CODE_SUCCESS) {
message.success({
content: t('common.operateOk'),
duration: 3,
});
} else {
message.error({
content: `${res.msg}`,
duration: 3,
});
}
})
.finally(() => {
state.loading = false;
hide();
});
},
});
}
</script>
<template>
<a-row>
<a-col :lg="12" :md="12" :xs="24">
<a-button type="default" @click="fnExport()">
{{ t('common.export') }}
</a-button>
<a-upload
name="file"
list-type="picture"
accept=".zip"
:max-count="1"
:show-upload-list="false"
:before-upload="fnBeforeUpload"
:custom-request="fnUpload"
style="margin-left: 10px"
>
<a-button type="link" :disabled="state.loading">
{{ t('common.import') }}
</a-button>
</a-upload>
</a-col>
<a-col :lg="12" :md="12" :xs="24">
<a-typography>
<a-typography-paragraph>
{{ t('views.system.setting.backupInstruction') }}
</a-typography-paragraph>
</a-typography>
</a-col>
</a-row>
</template>
<style lang="less" scoped></style>

View File

@@ -8,6 +8,7 @@ import ChangeHelpDoc from './components/change-help-doc.vue';
import ChangeOfficialUrl from './components/change-official-url.vue'; import ChangeOfficialUrl from './components/change-official-url.vue';
import ChangeI18n from './components/change-i18n.vue'; import ChangeI18n from './components/change-i18n.vue';
import SystemReset from './components/system-reset.vue'; import SystemReset from './components/system-reset.vue';
import SystemBackup from './components/system-backup.vue';
import ChangeHome from './components/change-home-index.vue'; import ChangeHome from './components/change-home-index.vue';
import useI18n from '@/hooks/useI18n'; import useI18n from '@/hooks/useI18n';
const { t } = useI18n(); const { t } = useI18n();
@@ -50,14 +51,24 @@ const { t } = useI18n();
</a-divider> </a-divider>
<ChangeI18n></ChangeI18n> <ChangeI18n></ChangeI18n>
</div> </div>
<a-divider orientation="left"> <div v-perms:has="['system:setting:homeSet']">
{{ t('views.system.setting.homeSet') }} <a-divider orientation="left">
</a-divider> {{ t('views.system.setting.homeSet') }}
<ChangeHome></ChangeHome> </a-divider>
<a-divider orientation="left"> <ChangeHome></ChangeHome>
{{ t('views.system.setting.reset') }} </div>
</a-divider> <div v-perms:has="['system:setting:backup']">
<SystemReset></SystemReset> <a-divider orientation="left">
{{ t('views.system.setting.backup') }}
</a-divider>
<SystemBackup></SystemBackup>
</div>
<div v-perms:has="['system:setting:reset']">
<a-divider orientation="left">
{{ t('views.system.setting.reset') }}
</a-divider>
<SystemReset></SystemReset>
</div>
</a-card> </a-card>
</PageContainer> </PageContainer>
</template> </template>