From 38139d95eb16cfaf38396e0b865a49b258b1943c Mon Sep 17 00:00:00 2001 From: InfinityPacer <160988576+InfinityPacer@users.noreply.github.com> Date: Wed, 19 Aug 2026 18:34:37 +0800 Subject: [PATCH] feat(settings): configure migration backups (#687) --- src/locales/en-US.ts | 3 +++ src/locales/zh-CN.ts | 2 ++ src/locales/zh-TW.ts | 2 ++ src/views/setting/AccountSettingSystem.vue | 9 +++++++++ src/views/setting/__tests__/AccountSettingSystem.spec.ts | 9 +++++++++ 5 files changed, 25 insertions(+) diff --git a/src/locales/en-US.ts b/src/locales/en-US.ts index f1265c93..079d7d92 100644 --- a/src/locales/en-US.ts +++ b/src/locales/en-US.ts @@ -2234,6 +2234,9 @@ export default { dbBackupMaxCount: 'Maximum Backup Count', dbBackupMaxCountHint: 'Set to 0 for no limit', dbBackupMaxCountInvalid: 'Maximum backup count must be an integer greater than or equal to 0', + dbBackupOnUpgrade: 'Back Up Before Database Migration', + dbBackupOnUpgradeHint: + 'Automatically create a backup when pending migrations are detected for an existing database', dataCleanupEnable: 'Enable Data Cleanup', dataCleanupEnableHint: 'When disabled, scheduled data cleanup tasks will be skipped', dataCleanupDaysRequired: 'Please enter a cleanup retention period', diff --git a/src/locales/zh-CN.ts b/src/locales/zh-CN.ts index 2b006960..9d8d8b70 100644 --- a/src/locales/zh-CN.ts +++ b/src/locales/zh-CN.ts @@ -2203,6 +2203,8 @@ export default { dbBackupMaxCount: '最大保留份数', dbBackupMaxCountHint: '0 表示不限制', dbBackupMaxCountInvalid: '最大保留份数必须是大于等于 0 的整数', + dbBackupOnUpgrade: '数据库迁移前备份', + dbBackupOnUpgradeHint: '检测到现有数据库存在待执行迁移时自动创建备份', dataCleanupEnable: '启用数据清理', dataCleanupEnableHint: '总开关关闭时将跳过定时数据清理任务', dataCleanupDaysRequired: '请输入清理周期', diff --git a/src/locales/zh-TW.ts b/src/locales/zh-TW.ts index 4bbbdc4f..f0a9da33 100644 --- a/src/locales/zh-TW.ts +++ b/src/locales/zh-TW.ts @@ -2202,6 +2202,8 @@ export default { dbBackupMaxCount: '最大保留份數', dbBackupMaxCountHint: '0 表示不限制', dbBackupMaxCountInvalid: '最大保留份數必須是大於等於 0 的整數', + dbBackupOnUpgrade: '資料庫遷移前備份', + dbBackupOnUpgradeHint: '偵測到現有資料庫存在待執行遷移時自動建立備份', dataCleanupEnable: '啟用數據清理', dataCleanupEnableHint: '總開關關閉時將跳過定時數據清理任務', dataCleanupDaysRequired: '請輸入清理週期', diff --git a/src/views/setting/AccountSettingSystem.vue b/src/views/setting/AccountSettingSystem.vue index b9e7050f..feb03c46 100644 --- a/src/views/setting/AccountSettingSystem.vue +++ b/src/views/setting/AccountSettingSystem.vue @@ -106,6 +106,7 @@ const SystemSettings = ref({ DB_BACKUP_PATH: null, DB_BACKUP_RETENTION_DAYS: 30, DB_BACKUP_MAX_COUNT: 30, + DB_BACKUP_ON_UPGRADE: true, // 媒体 RECOGNIZE_PLUGIN_FIRST: false, MEDIA_RECOGNIZE_SHARE: true, @@ -2537,6 +2538,14 @@ watch(currentLlmSnapshotKey, (snapshotKey, previousSnapshotKey) => { prepend-inner-icon="mdi-backup-restore" /> + + + { expect(dialog.getByLabelText('备份目录')).toHaveAttribute('data-storage', 'local') expect(dialog.getByLabelText('备份过期天数')).toHaveValue(30) expect(dialog.getByLabelText('最大保留份数')).toHaveValue(30) + expect(dialog.getByLabelText('数据库迁移前备份')).toBeChecked() }) it('loads, edits, and saves the database backup policy', async () => { @@ -1073,6 +1074,7 @@ describe('AccountSettingSystem', () => { DB_BACKUP_CRON: '15 2 * * 1', DB_BACKUP_ENABLE: true, DB_BACKUP_MAX_COUNT: 12, + DB_BACKUP_ON_UPGRADE: false, DB_BACKUP_PATH: '/data/backup', DB_BACKUP_RETENTION_DAYS: 45, } @@ -1081,10 +1083,12 @@ describe('AccountSettingSystem', () => { expect(dialog.getByLabelText('备份周期')).toHaveValue('15 2 * * 1') expect(dialog.getByLabelText('备份目录')).toHaveValue('/data/backup') + expect(dialog.getByLabelText('数据库迁移前备份')).not.toBeChecked() await fireEvent.update(dialog.getByLabelText('备份周期'), '30 4 * * *') await fireEvent.update(dialog.getByLabelText('备份目录'), ' relative/backup ') await fireEvent.update(dialog.getByLabelText('备份过期天数'), '60') await fireEvent.update(dialog.getByLabelText('最大保留份数'), '20') + await fireEvent.click(dialog.getByLabelText('数据库迁移前备份')) await fireEvent.click(dialog.getByRole('button', { name: '保存' })) await waitFor(() => expect(screen.queryByRole('dialog')).not.toBeInTheDocument()) @@ -1093,6 +1097,7 @@ describe('AccountSettingSystem', () => { DB_BACKUP_CRON: '30 4 * * *', DB_BACKUP_ENABLE: true, DB_BACKUP_MAX_COUNT: 20, + DB_BACKUP_ON_UPGRADE: true, DB_BACKUP_PATH: 'relative/backup', DB_BACKUP_RETENTION_DAYS: 60, }), @@ -1105,6 +1110,7 @@ describe('AccountSettingSystem', () => { DB_BACKUP_CRON: ' 15 2 * * 1 ', DB_BACKUP_ENABLE: true, DB_BACKUP_MAX_COUNT: '12', + DB_BACKUP_ON_UPGRADE: false, DB_BACKUP_PATH: ' /data/backup ', DB_BACKUP_RETENTION_DAYS: '45', } @@ -1113,6 +1119,7 @@ describe('AccountSettingSystem', () => { await fireEvent.click(dialog.getByLabelText('启用数据备份')) expect(dialog.queryByLabelText('备份周期')).not.toBeInTheDocument() + expect(dialog.queryByLabelText('数据库迁移前备份')).not.toBeInTheDocument() await fireEvent.click(dialog.getByRole('button', { name: '保存' })) await waitFor(() => expect(screen.queryByRole('dialog')).not.toBeInTheDocument()) @@ -1121,6 +1128,7 @@ describe('AccountSettingSystem', () => { DB_BACKUP_CRON: '15 2 * * 1', DB_BACKUP_ENABLE: false, DB_BACKUP_MAX_COUNT: 12, + DB_BACKUP_ON_UPGRADE: false, DB_BACKUP_PATH: '/data/backup', DB_BACKUP_RETENTION_DAYS: 45, }), @@ -1161,6 +1169,7 @@ describe('AccountSettingSystem', () => { expect.objectContaining({ DB_BACKUP_CRON: '', DB_BACKUP_MAX_COUNT: 0, + DB_BACKUP_ON_UPGRADE: true, DB_BACKUP_PATH: null, DB_BACKUP_RETENTION_DAYS: 0, }),