From 9adf6b3b95c617b3a7eee61f5cb02039db65df69 Mon Sep 17 00:00:00 2001 From: Baobhan Sith <80159437+Heavrnl@users.noreply.github.com> Date: Sun, 11 May 2025 21:53:43 +0800 Subject: [PATCH] =?UTF-8?q?refactor=EF=BC=9A=E4=BC=98=E5=8C=96settings?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/settings/AboutSection.vue | 62 ++ .../components/settings/AppearanceSection.vue | 37 + .../settings/CaptchaSettingsForm.vue | 95 ++ .../settings/ChangePasswordForm.vue | 51 + .../settings/DataManagementSection.vue | 51 + .../settings/IpBlacklistSettings.vue | 124 +++ .../settings/IpWhitelistSettings.vue | 40 + .../components/settings/PasskeyManagement.vue | 90 ++ .../settings/SystemSettingsSection.vue | 142 +++ .../settings/TwoFactorAuthSettings.vue | 79 ++ .../settings/WorkspaceSettingsSection.vue | 251 +++++ packages/frontend/src/views/SettingsView.vue | 892 +----------------- 12 files changed, 1044 insertions(+), 870 deletions(-) create mode 100644 packages/frontend/src/components/settings/AboutSection.vue create mode 100644 packages/frontend/src/components/settings/AppearanceSection.vue create mode 100644 packages/frontend/src/components/settings/CaptchaSettingsForm.vue create mode 100644 packages/frontend/src/components/settings/ChangePasswordForm.vue create mode 100644 packages/frontend/src/components/settings/DataManagementSection.vue create mode 100644 packages/frontend/src/components/settings/IpBlacklistSettings.vue create mode 100644 packages/frontend/src/components/settings/IpWhitelistSettings.vue create mode 100644 packages/frontend/src/components/settings/PasskeyManagement.vue create mode 100644 packages/frontend/src/components/settings/SystemSettingsSection.vue create mode 100644 packages/frontend/src/components/settings/TwoFactorAuthSettings.vue create mode 100644 packages/frontend/src/components/settings/WorkspaceSettingsSection.vue diff --git a/packages/frontend/src/components/settings/AboutSection.vue b/packages/frontend/src/components/settings/AboutSection.vue new file mode 100644 index 0000000..b74f45d --- /dev/null +++ b/packages/frontend/src/components/settings/AboutSection.vue @@ -0,0 +1,62 @@ + + + + + \ No newline at end of file diff --git a/packages/frontend/src/components/settings/AppearanceSection.vue b/packages/frontend/src/components/settings/AppearanceSection.vue new file mode 100644 index 0000000..7c0dcd8 --- /dev/null +++ b/packages/frontend/src/components/settings/AppearanceSection.vue @@ -0,0 +1,37 @@ + + + + + \ No newline at end of file diff --git a/packages/frontend/src/components/settings/CaptchaSettingsForm.vue b/packages/frontend/src/components/settings/CaptchaSettingsForm.vue new file mode 100644 index 0000000..b6ef27f --- /dev/null +++ b/packages/frontend/src/components/settings/CaptchaSettingsForm.vue @@ -0,0 +1,95 @@ + + + + + \ No newline at end of file diff --git a/packages/frontend/src/components/settings/ChangePasswordForm.vue b/packages/frontend/src/components/settings/ChangePasswordForm.vue new file mode 100644 index 0000000..7da55e7 --- /dev/null +++ b/packages/frontend/src/components/settings/ChangePasswordForm.vue @@ -0,0 +1,51 @@ + + + + + \ No newline at end of file diff --git a/packages/frontend/src/components/settings/DataManagementSection.vue b/packages/frontend/src/components/settings/DataManagementSection.vue new file mode 100644 index 0000000..abf9b1d --- /dev/null +++ b/packages/frontend/src/components/settings/DataManagementSection.vue @@ -0,0 +1,51 @@ + + + + + \ No newline at end of file diff --git a/packages/frontend/src/components/settings/IpBlacklistSettings.vue b/packages/frontend/src/components/settings/IpBlacklistSettings.vue new file mode 100644 index 0000000..565c30e --- /dev/null +++ b/packages/frontend/src/components/settings/IpBlacklistSettings.vue @@ -0,0 +1,124 @@ + + + + + \ No newline at end of file diff --git a/packages/frontend/src/components/settings/IpWhitelistSettings.vue b/packages/frontend/src/components/settings/IpWhitelistSettings.vue new file mode 100644 index 0000000..abcde1a --- /dev/null +++ b/packages/frontend/src/components/settings/IpWhitelistSettings.vue @@ -0,0 +1,40 @@ + + + + + \ No newline at end of file diff --git a/packages/frontend/src/components/settings/PasskeyManagement.vue b/packages/frontend/src/components/settings/PasskeyManagement.vue new file mode 100644 index 0000000..053c778 --- /dev/null +++ b/packages/frontend/src/components/settings/PasskeyManagement.vue @@ -0,0 +1,90 @@ + + + + + \ No newline at end of file diff --git a/packages/frontend/src/components/settings/SystemSettingsSection.vue b/packages/frontend/src/components/settings/SystemSettingsSection.vue new file mode 100644 index 0000000..2dcff47 --- /dev/null +++ b/packages/frontend/src/components/settings/SystemSettingsSection.vue @@ -0,0 +1,142 @@ + + + + + \ No newline at end of file diff --git a/packages/frontend/src/components/settings/TwoFactorAuthSettings.vue b/packages/frontend/src/components/settings/TwoFactorAuthSettings.vue new file mode 100644 index 0000000..181fa97 --- /dev/null +++ b/packages/frontend/src/components/settings/TwoFactorAuthSettings.vue @@ -0,0 +1,79 @@ + + + + + \ No newline at end of file diff --git a/packages/frontend/src/components/settings/WorkspaceSettingsSection.vue b/packages/frontend/src/components/settings/WorkspaceSettingsSection.vue new file mode 100644 index 0000000..3bb5327 --- /dev/null +++ b/packages/frontend/src/components/settings/WorkspaceSettingsSection.vue @@ -0,0 +1,251 @@ + + + + + \ No newline at end of file diff --git a/packages/frontend/src/views/SettingsView.vue b/packages/frontend/src/views/SettingsView.vue index a4bba59..0b51348 100644 --- a/packages/frontend/src/views/SettingsView.vue +++ b/packages/frontend/src/views/SettingsView.vue @@ -22,214 +22,16 @@

{{ $t('settings.category.security') }}

-
-

{{ $t('settings.changePassword.title') }}

-
-
- - -
-
- - -
-
- - -
-
- -

{{ changePasswordMessage }}

-
-
-
+
-
-

{{ $t('settings.passkey.title') }}

-

{{ $t('settings.passkey.description') }}

- -

{{ passkeyMessage }}

- - -
-

{{ $t('settings.passkey.registeredKeysTitle') }}

-
- {{ $t('common.loading') }} -
-
-
    -
  • -
    -
    - - {{ key.name || $t('settings.passkey.unnamedKey') }} - (ID: ...{{ typeof key.credentialID === 'string' && key.credentialID ? key.credentialID.slice(-8) : 'N/A' }}) - -
    - - - -
    - -
    -
    - {{ $t('settings.passkey.createdDate') }}: {{ formatDate(key.creationDate) }} - {{ $t('settings.passkey.lastUsedDate') }}: {{ formatDate(key.lastUsedDate) }} - ({{ key.transports.join(', ') }}) -
    -
    - -
  • -
-
-

{{ $t('settings.passkey.noKeysRegistered') }}

-

{{ passkeyDeleteError }}

-
-
+
-
-

{{ $t('settings.twoFactor.title') }}

-
-

{{ $t('settings.twoFactor.status.enabled') }}

-
-
- - -
-
- -
-
-
-
-

{{ $t('settings.twoFactor.status.disabled') }}

- -
-

{{ $t('settings.twoFactor.setup.scanQrCode') }}

- QR Code -

{{ $t('settings.twoFactor.setup.orEnterSecret') }} {{ setupData.secret }}

-
-
- - -
-
- - -
-
-
-
-

{{ twoFactorMessage }}

-
+
-
-

{{ $t('settings.captcha.title') }}

-

{{ $t('settings.captcha.description') }}

-
- {{ $t('common.loading') }} -
-
- -
- - -
- - -
- - -
- - -
-

{{ $t('settings.captcha.hcaptchaHint') }} hCaptcha.com

-
- - -
-
- - - {{ $t('settings.captcha.secretKeyHint') }} -
-
- - -
-

{{ $t('settings.captcha.recaptchaHint') }} Google reCAPTCHA

-
- - -
-
- - - {{ $t('settings.captcha.secretKeyHint') }} -
-
- - -
- -

{{ captchaMessage }}

-
-
-
+
@@ -237,497 +39,30 @@

{{ $t('settings.ipWhitelist.title') }}

-

{{ $t('settings.ipWhitelist.description') }}

-
-
- - - {{ $t('settings.ipWhitelist.hint') }} -
-
- -

{{ ipWhitelistMessage }}

-
-
+
-
-
-

{{ $t('settings.ipBlacklist.title') }}

- - -
-
- - - -
-

{{ $t('settings.ipBlacklist.description') }}

- -
-
- - -
-
- - -
-
- -
-

{{ blacklistSettingsMessage }}

-
-
- -

{{ $t('settings.ipBlacklist.currentBannedTitle') }}

- -
{{ ipBlacklist.error }}
- -
{{ $t('settings.ipBlacklist.loadingList') }}
- -

{{ $t('settings.ipBlacklist.noBannedIps') }}

- -
- - - - - - - - - - - - - - - - - - - -
{{ $t('settings.ipBlacklist.table.ipAddress') }}{{ $t('settings.ipBlacklist.table.attempts') }}{{ $t('settings.ipBlacklist.table.lastAttempt') }}{{ $t('settings.ipBlacklist.table.bannedUntil') }}{{ $t('settings.ipBlacklist.table.actions') }}
{{ entry.ip }}{{ entry.attempts }}{{ new Date(entry.last_attempt_at * 1000).toLocaleString() }}{{ entry.blocked_until ? new Date(entry.blocked_until * 1000).toLocaleString() : $t('statusMonitor.notAvailable') }} - -
-
- -

{{ blacklistDeleteError }}

-
- -
- {{ $t('settings.ipBlacklist.disabledMessage', 'IP 黑名单功能当前已禁用。') }} -
-
-
+ -
-

{{ $t('settings.category.about') }}

-
-
- {{ $t('settings.about.version') }}: {{ appVersion }} - - - {{ $t('settings.about.checkingUpdate') }} - - - {{ $t('settings.about.error.checkFailedShort') }} - - - {{ $t('settings.about.latestVersion') }} - - - - {{ $t('settings.about.updateAvailable', { version: latestVersion }) }} - - | - - - Heavrnl/nexus-terminal - - | - - - Ko-fi - -
-
-
+
-
-

{{ $t('settings.workspace.title') }}

-
- -
-

{{ $t('settings.popupEditor.title') }}

-
-
- - -
-
- -

{{ popupEditorMessage }}

-
-
-
-
- -
-

{{ $t('settings.shareEditorTabs.title') }}

-
-
- - -
-

{{ $t('settings.shareEditorTabs.description') }}

-
- -

{{ shareTabsMessage }}

-
-
-
-
- -
-

{{ $t('settings.autoCopyOnSelect.title') }}

-
-
- - -
-
- -

{{ autoCopyMessage }}

-
-
-
-
- -
-

{{ $t('settings.workspace.sidebarPersistentTitle') }}

-
-
- - -
-

{{ $t('settings.workspace.sidebarPersistentDescription') }}

-
- -

{{ workspaceSidebarPersistentMessage }}

-
-
-
-
- -
-

{{ $t('settings.commandInputSync.title', '命令输入同步') }}

-
-
- - -

{{ $t('settings.commandInputSync.description', '将命令输入框的内容实时同步到所选面板的搜索框。') }}

-
-
- -

{{ commandInputSyncMessage }}

-
-
-
-
- -
-

{{ $t('settings.workspace.showConnectionTagsTitle', '显示连接标签') }}

-
-
- - -
-

{{ $t('settings.workspace.showConnectionTagsDescription', '关闭后将隐藏连接列表中的标签,并从搜索中排除标签。') }}

-
- -

{{ showConnectionTagsMessage }}

-
-
-
-
- -
-

{{ $t('settings.workspace.showQuickCommandTagsTitle', '显示快捷指令标签') }}

-
-
- - -
-

{{ $t('settings.workspace.showQuickCommandTagsDescription', '关闭后将隐藏快捷指令列表中的标签,并从搜索中排除标签。') }}

-
- -

{{ showQuickCommandTagsMessage }}

-
-
-
-
- -
-

{{ t('settings.terminalScrollback.title', '终端回滚行数') }}

-
-
- - - {{ t('settings.terminalScrollback.limitHint', '设置终端保留的最大输出行数。0 或留空表示无限制 (使用默认值 5000)。此设置将在下次打开终端时生效。') }} -
-
- -

{{ terminalScrollbackLimitMessage }}

-
-
-
-
- -
-

{{ $t('settings.workspace.fileManagerDeleteConfirmTitle', '文件管理器删除确认') }}

-
-
- - -
-
- -

{{ fileManagerShowDeleteConfirmationMessage }}

-
-
-
-
-
+ -
-

{{ $t('settings.category.system') }}

-
- -
-

{{ $t('settings.language.title') }}

-
-
- - -
-
- -

{{ languageMessage }}

-
-
-
-
- -
-

{{ $t('settings.timezone.title') }}

-
-
- - - {{ $t('settings.timezone.description') }} -
-
- -

{{ timezoneMessage }}

-
-
-
-
- -
-

{{ t('settings.statusMonitor.title') }}

-
-
- - - {{ t('settings.statusMonitor.refreshIntervalHint') }} -
-
- -

{{ statusMonitorMessage }}

-
-
-
-
- -
-

{{ t('settings.docker.title') }}

-
-
- - - {{ t('settings.docker.refreshIntervalHint') }} -
-
- - -
-
- -

{{ dockerSettingsMessage }}

-
-
-
-
-
+ -
-

- {{ t('settings.category.dataManagement', '数据管理') }} -

-
- -
-

{{ t('settings.exportConnections.title', '导出连接数据') }}

-

- {{ t('settings.exportConnections.decryptKeyInfo', '解压密码为您的 data/.env 文件中的 ENCRYPTION_KEY。请妥善保管此文件。') }} -

-
-
- -

{{ exportConnectionsMessage }}

-
-
-
-
-
+ -
-

{{ $t('settings.category.appearance') }}

-
- -
-

{{ $t('settings.appearance.title') }}

-

{{ $t('settings.appearance.description') }}

- -
-
-
+
@@ -742,205 +77,23 @@ import { useSettingsStore } from '../stores/settings.store'; import { useAppearanceStore } from '../stores/appearance.store'; // 导入外观 store import { useI18n } from 'vue-i18n'; import { storeToRefs } from 'pinia'; -import { useChangePassword } from '../composables/settings/useChangePassword'; -import { usePasskeyManagement } from '../composables/settings/usePasskeyManagement'; -import { useTwoFactorAuth } from '../composables/settings/useTwoFactorAuth'; -import { useCaptchaSettings, type CaptchaProvider, type UpdateCaptchaSettingsDto } from '../composables/settings/useCaptchaSettings'; // Import Captcha composable -import { useIpWhitelist } from '../composables/settings/useIpWhitelist'; // Import IP Whitelist composable -import { useIpBlacklist } from '../composables/settings/useIpBlacklist'; // Import IP Blacklist composable -import { useVersionCheck } from '../composables/settings/useVersionCheck'; // Import Version Check composable -import { useWorkspaceSettings } from '../composables/settings/useWorkspaceSettings'; // Import Workspace Settings composable -import { useAppearanceSettings } from '../composables/settings/useAppearanceSettings'; // Import Appearance Settings composable -import { useSystemSettings } from '../composables/settings/useSystemSettings'; // Import System Settings composable -import { useExportConnections } from '../composables/settings/useExportConnections'; // Import Export Connections composable +import ChangePasswordForm from '../components/settings/ChangePasswordForm.vue'; // 导入新组件 +import PasskeyManagement from '../components/settings/PasskeyManagement.vue'; // 导入新组件 +import TwoFactorAuthSettings from '../components/settings/TwoFactorAuthSettings.vue'; // 导入新组件 +import CaptchaSettingsForm from '../components/settings/CaptchaSettingsForm.vue'; // 导入新组件 +import IpWhitelistSettings from '../components/settings/IpWhitelistSettings.vue'; // 导入新组件 +import IpBlacklistSettings from '../components/settings/IpBlacklistSettings.vue'; // 导入新组件 +import AboutSection from '../components/settings/AboutSection.vue'; // 导入新组件 +import WorkspaceSettingsSection from '../components/settings/WorkspaceSettingsSection.vue'; // 导入新组件 +import SystemSettingsSection from '../components/settings/SystemSettingsSection.vue'; // 导入新组件 +import DataManagementSection from '../components/settings/DataManagementSection.vue'; // 导入新组件 +import AppearanceSection from '../components/settings/AppearanceSection.vue'; // 导入新组件 const authStore = useAuthStore(); const settingsStore = useSettingsStore(); const appearanceStore = useAppearanceStore(); // 实例化外观 store const { t } = useI18n(); -// --- Change Password (Refactored) --- -const { - currentPassword, - newPassword, - confirmPassword, - changePasswordLoading, - changePasswordMessage, - changePasswordSuccess, - handleChangePassword, -} = useChangePassword(); - -// --- Passkey Management (Refactored) --- -const { - passkeys, // from authStore, made reactive via usePasskeyManagement - passkeysLoading: authStorePasskeysLoading, // from authStore, alias to avoid conflict if template uses 'passkeysLoading' for registration - passkeyRegistrationLoading: passkeyLoading, // Aliased for template compatibility - passkeyMessage, - passkeySuccess, - passkeyDeleteLoadingStates, - passkeyDeleteError, - editingPasskeyId, - editingPasskeyName, - passkeyEditLoadingStates, - handleRegisterNewPasskey, - startEditPasskeyName, - cancelEditPasskeyName, - savePasskeyName, - handleDeletePasskey, - formatDate, // formatDate for passkeys section -} = usePasskeyManagement(); - -// --- 2FA (Refactored) --- -const { - twoFactorEnabled, - twoFactorLoading, - twoFactorMessage, - twoFactorSuccess, - setupData, - verificationCode, - disablePassword, - isSettingUp2FA, - // checkTwoFactorStatus, // onMounted will call this - handleSetup2FA, - handleVerifyAndActivate2FA, - handleDisable2FA, - cancelSetup, -} = useTwoFactorAuth(); - -// --- CAPTCHA Settings (Refactored) --- -const { - captchaForm, - captchaLoading, - captchaMessage, - captchaSuccess, - handleUpdateCaptchaSettings, -} = useCaptchaSettings(); - -// --- IP Whitelist (Refactored) --- -const { - ipWhitelistInput, - ipWhitelistLoading, - ipWhitelistMessage, - ipWhitelistSuccess, - handleUpdateIpWhitelist, -} = useIpWhitelist(); - -// --- IP Blacklist (Refactored) --- -const { - ipBlacklistEnabled, - handleUpdateIpBlacklistEnabled, - blacklistSettingsForm, - blacklistSettingsLoading, - blacklistSettingsMessage, - blacklistSettingsSuccess, - handleUpdateBlacklistSettings, - ipBlacklist, - blacklistToDeleteIp, - blacklistDeleteLoading, - blacklistDeleteError, - handleDeleteIp, // Exposed as it's used in the template -} = useIpBlacklist(); - -// --- Version Check (Refactored) --- -const { - appVersion, // Now from useVersionCheck - latestVersion, - isCheckingVersion, - versionCheckError, - isUpdateAvailable, - checkLatestVersion, // Function to check version -} = useVersionCheck(); - -// --- Workspace Settings (Refactored) --- -const { - popupEditorEnabled, - popupEditorLoading, - popupEditorMessage, - popupEditorSuccess, - handleUpdatePopupEditorSetting, - shareTabsEnabled, - shareTabsLoading, - shareTabsMessage, - shareTabsSuccess, - handleUpdateShareTabsSetting, - autoCopyEnabled, - autoCopyLoading, - autoCopyMessage, - autoCopySuccess, - handleUpdateAutoCopySetting, - workspaceSidebarPersistentEnabled, - workspaceSidebarPersistentLoading, - workspaceSidebarPersistentMessage, - workspaceSidebarPersistentSuccess, - handleUpdateWorkspaceSidebarSetting, - commandInputSyncTargetLocal, - commandInputSyncLoading, - commandInputSyncMessage, - commandInputSyncSuccess, - handleUpdateCommandInputSyncTarget, - showConnectionTagsLocal, - showConnectionTagsLoading, - showConnectionTagsMessage, - showConnectionTagsSuccess, - handleUpdateShowConnectionTags, - showQuickCommandTagsLocal, - showQuickCommandTagsLoading, - showQuickCommandTagsMessage, - showQuickCommandTagsSuccess, - handleUpdateShowQuickCommandTags, - terminalScrollbackLimitLocal, - terminalScrollbackLimitLoading, - terminalScrollbackLimitMessage, - terminalScrollbackLimitSuccess, - handleUpdateTerminalScrollbackLimit, - fileManagerShowDeleteConfirmationLocal, - fileManagerShowDeleteConfirmationLoading, - fileManagerShowDeleteConfirmationMessage, - fileManagerShowDeleteConfirmationSuccess, - handleUpdateFileManagerDeleteConfirmation, -} = useWorkspaceSettings(); - -// --- Appearance Settings (Refactored) --- -const { - openStyleCustomizer, -} = useAppearanceSettings(); - -// --- System Settings (Refactored) --- -const { - selectedLanguage, - languageLoading, - languageMessage, - languageSuccess, - languageNames, - availableLocales, - handleUpdateLanguage, - selectedTimezone, - timezoneLoading, - timezoneMessage, - timezoneSuccess, - commonTimezones, - handleUpdateTimezone, - statusMonitorIntervalLocal, - statusMonitorLoading, - statusMonitorMessage, - statusMonitorSuccess, - handleUpdateStatusMonitorInterval, - dockerInterval, - dockerExpandDefault, - dockerSettingsLoading, - dockerSettingsMessage, - dockerSettingsSuccess, - handleUpdateDockerSettings, -} = useSystemSettings(); - -// --- Export Connections (Refactored) --- -const { - exportConnectionsLoading, - exportConnectionsMessage, - exportConnectionsSuccess, - handleExportConnections, -} = useExportConnections(); - // --- Reactive state from store --- // 使用 storeToRefs 获取响应式 getter,包括 language const { @@ -956,7 +109,6 @@ const { onMounted(async () => { // await fetchIpBlacklist(); // REMOVED - Handled by useIpBlacklist.ts onMounted await settingsStore.loadCaptchaSettings(); // <-- Load CAPTCHA settings - await checkLatestVersion(); // <-- Check for latest version on mount });