feat: 新增 SAP HANA 数据库备份支持和 FTP 存储后端

后端变更:
- 新增 SAP HANA 备份 Runner (saphana_runner.go),使用 hdbsql CLI 工具执行数据库导出/恢复
- 新增 FTP 存储 Provider (storage/ftp/provider.go),支持 FTP/FTPS 协议上传下载备份文件
- 在 storage/types.go 中添加 FTP 类型常量和 FTPConfig 配置结构
- 在 app.go 中注册 FTP Storage Factory 和 SAP HANA Backup Runner
- 添加 github.com/jlaffaye/ftp 依赖

前端变更:
- BackupTaskType 联合类型新增 'saphana',默认端口 30015
- StorageTargetType 联合类型新增 'ftp'
- 备份任务表单支持 SAP HANA 类型选择及数据库连接配置
- 存储目标表单新增 FTP 配置字段(主机/端口/用户名/密码/基础目录/TLS)

参考:backint_minio1.0.0/ Java 实现
This commit is contained in:
Awuqing
2026-03-21 16:09:14 +08:00
parent be856fe06b
commit aa24442c45
11 changed files with 499 additions and 9 deletions

View File

@@ -106,11 +106,11 @@ export function BackupTaskFormDrawer({ visible, loading, initialValue, storageTa
type: value,
sourcePath: value === 'file' ? current.sourcePath : '',
excludePatterns: value === 'file' ? current.excludePatterns : [],
dbHost: value === 'mysql' || value === 'postgresql' ? current.dbHost : '',
dbPort: value === 'mysql' || value === 'postgresql' ? current.dbPort || getDefaultPort(value) : 0,
dbUser: value === 'mysql' || value === 'postgresql' ? current.dbUser : '',
dbPassword: value === 'mysql' || value === 'postgresql' ? current.dbPassword : '',
dbName: value === 'mysql' || value === 'postgresql' ? current.dbName : '',
dbHost: value === 'mysql' || value === 'postgresql' || value === 'saphana' ? current.dbHost : '',
dbPort: value === 'mysql' || value === 'postgresql' || value === 'saphana' ? current.dbPort || getDefaultPort(value) : 0,
dbUser: value === 'mysql' || value === 'postgresql' || value === 'saphana' ? current.dbUser : '',
dbPassword: value === 'mysql' || value === 'postgresql' || value === 'saphana' ? current.dbPassword : '',
dbName: value === 'mysql' || value === 'postgresql' || value === 'saphana' ? current.dbName : '',
dbPath: value === 'sqlite' ? current.dbPath : '',
}))
if (value !== 'file') {

View File

@@ -5,6 +5,7 @@ export const backupTaskTypeOptions = [
{ label: 'MySQL', value: 'mysql' },
{ label: 'SQLite', value: 'sqlite' },
{ label: 'PostgreSQL', value: 'postgresql' },
{ label: 'SAP HANA', value: 'saphana' },
] as const
export const backupCompressionOptions = [
@@ -22,6 +23,8 @@ export function getBackupTaskTypeLabel(type: BackupTaskType) {
return 'SQLite'
case 'postgresql':
return 'PostgreSQL'
case 'saphana':
return 'SAP HANA'
default:
return type
}
@@ -64,7 +67,7 @@ export function isSQLiteBackupTask(type: BackupTaskType) {
}
export function isDatabaseBackupTask(type: BackupTaskType) {
return type === 'mysql' || type === 'postgresql'
return type === 'mysql' || type === 'postgresql' || type === 'saphana'
}
export function getDefaultPort(type: BackupTaskType) {
@@ -73,6 +76,8 @@ export function getDefaultPort(type: BackupTaskType) {
return 3306
case 'postgresql':
return 5432
case 'saphana':
return 30015
default:
return 0
}

View File

@@ -216,6 +216,50 @@ const FIELD_CONFIG_MAP: Record<StorageTargetType, StorageTargetFieldConfig[]> =
placeholder: '输入新的 SecretKey',
},
],
ftp: [
{
key: 'host',
label: '主机地址',
type: 'input',
required: true,
placeholder: 'ftp.example.com',
},
{
key: 'port',
label: '端口',
type: 'input',
placeholder: '21',
description: '默认 FTP 端口为 21。',
},
{
key: 'username',
label: '用户名',
type: 'input',
required: true,
placeholder: 'backup_user',
},
{
key: 'password',
label: '密码',
type: 'password',
required: true,
sensitive: true,
placeholder: '输入新的 FTP 密码',
},
{
key: 'basePath',
label: '基础目录',
type: 'input',
placeholder: '/backups',
description: 'FTP 服务器上的目标目录,留空使用根目录。',
},
{
key: 'useTLS',
label: '使用 TLS (FTPS)',
type: 'switch',
description: '启用 Explicit TLS 加密连接。',
},
],
}
export function getStorageTargetFieldConfigs(type: StorageTargetType) {
@@ -238,6 +282,8 @@ export function getStorageTargetTypeLabel(type: StorageTargetType) {
return '腾讯云 COS'
case 'qiniu_kodo':
return '七牛云 Kodo'
case 'ftp':
return 'FTP'
default:
return type
}
@@ -251,4 +297,5 @@ export const storageTargetTypeOptions = [
{ label: 'S3 Compatible', value: 's3' },
{ label: 'Google Drive', value: 'google_drive' },
{ label: 'WebDAV', value: 'webdav' },
{ label: 'FTP', value: 'ftp' },
] as const

View File

@@ -1,4 +1,4 @@
export type BackupTaskType = 'file' | 'mysql' | 'sqlite' | 'postgresql'
export type BackupTaskType = 'file' | 'mysql' | 'sqlite' | 'postgresql' | 'saphana'
export type BackupTaskStatus = 'idle' | 'running' | 'success' | 'failed'
export type BackupCompression = 'gzip' | 'none'

View File

@@ -1,4 +1,4 @@
export type StorageTargetType = 'local_disk' | 'google_drive' | 's3' | 'webdav' | 'aliyun_oss' | 'tencent_cos' | 'qiniu_kodo'
export type StorageTargetType = 'local_disk' | 'google_drive' | 's3' | 'webdav' | 'aliyun_oss' | 'tencent_cos' | 'qiniu_kodo' | 'ftp'
export type StorageTestStatus = 'unknown' | 'success' | 'failed'
export type StorageFieldType = 'input' | 'password' | 'switch'