Quellcode durchsuchen

refactor(preference): use pinia store

Jacky vor 1 Woche
Ursprung
Commit
4aa42da642
39 geänderte Dateien mit 282 neuen und 171 gelöschten Zeilen
  1. 1 0
      api/settings/settings.go
  2. 1 0
      app/src/api/settings.ts
  3. 3 0
      app/src/components/Breadcrumb/index.ts
  4. 3 0
      app/src/components/EnvGroupTabs/index.ts
  5. 3 0
      app/src/components/EnvIndicator/index.ts
  6. 3 0
      app/src/components/ICP/index.ts
  7. 3 0
      app/src/components/Logo/index.ts
  8. 3 0
      app/src/components/NginxControl/index.ts
  9. 3 0
      app/src/components/NodeSelector/index.ts
  10. 3 0
      app/src/components/Notification/index.ts
  11. 3 0
      app/src/components/OTPInput/index.ts
  12. 3 0
      app/src/components/PageHeader/index.ts
  13. 3 0
      app/src/components/ReactiveFromNow/index.ts
  14. 3 0
      app/src/components/SensitiveString/index.ts
  15. 3 0
      app/src/components/SetLanguage/index.ts
  16. 1 1
      app/src/components/SwitchAppearance/SwitchAppearance.vue
  17. 3 0
      app/src/components/SwitchAppearance/index.ts
  18. 3 0
      app/src/components/SystemRestore/index.ts
  19. 8 0
      app/src/components/TwoFA/index.ts
  20. 3 0
      app/src/components/VPSwitch/index.ts
  21. 19 133
      app/src/views/preference/Preference.vue
  22. 0 0
      app/src/views/preference/components/AuthSettings/AddPasskey.vue
  23. 2 2
      app/src/views/preference/components/AuthSettings/Passkey.vue
  24. 1 1
      app/src/views/preference/components/AuthSettings/RecoveryCodes.vue
  25. 2 2
      app/src/views/preference/components/AuthSettings/TOTP.vue
  26. 11 0
      app/src/views/preference/components/AuthSettings/index.ts
  27. 127 0
      app/src/views/preference/store/index.ts
  28. 4 3
      app/src/views/preference/tabs/AppSettings.vue
  29. 6 6
      app/src/views/preference/tabs/AuthSettings.vue
  30. 3 3
      app/src/views/preference/tabs/CertSettings.vue
  31. 2 2
      app/src/views/preference/tabs/ExternalNotify.vue
  32. 3 3
      app/src/views/preference/tabs/HTTPSettings.vue
  33. 3 2
      app/src/views/preference/tabs/LogrotateSettings.vue
  34. 16 2
      app/src/views/preference/tabs/NginxSettings.vue
  35. 4 4
      app/src/views/preference/tabs/NodeSettings.vue
  36. 3 3
      app/src/views/preference/tabs/OpenAISettings.vue
  37. 3 2
      app/src/views/preference/tabs/ServerSettings.vue
  38. 3 2
      app/src/views/preference/tabs/TerminalSettings.vue
  39. 11 0
      app/src/views/preference/tabs/index.ts

+ 1 - 0
api/settings/settings.go

@@ -25,6 +25,7 @@ func GetSettings(c *gin.Context) {
 	settings.NginxSettings.ErrorLogPath = nginx.GetErrorLogPath()
 	settings.NginxSettings.ConfigDir = nginx.GetConfPath()
 	settings.NginxSettings.PIDPath = nginx.GetPIDPath()
+	settings.NginxSettings.StubStatusPort = settings.NginxSettings.GetStubStatusPort()
 
 	if settings.NginxSettings.ReloadCmd == "" {
 		settings.NginxSettings.ReloadCmd = "nginx -s reload"

+ 1 - 0
app/src/api/settings.ts

@@ -64,6 +64,7 @@ export interface NginxSettings {
   reload_cmd: string
   restart_cmd: string
   stub_status_port: number
+  container_name: string
 }
 
 export interface NodeSettings {

+ 3 - 0
app/src/components/Breadcrumb/index.ts

@@ -0,0 +1,3 @@
+import Breadcrumb from './Breadcrumb.vue'
+
+export default Breadcrumb

+ 3 - 0
app/src/components/EnvGroupTabs/index.ts

@@ -0,0 +1,3 @@
+import EnvGroupTabs from './EnvGroupTabs.vue'
+
+export default EnvGroupTabs

+ 3 - 0
app/src/components/EnvIndicator/index.ts

@@ -0,0 +1,3 @@
+import EnvIndicator from './EnvIndicator.vue'
+
+export default EnvIndicator

+ 3 - 0
app/src/components/ICP/index.ts

@@ -0,0 +1,3 @@
+import ICP from './ICP.vue'
+
+export default ICP

+ 3 - 0
app/src/components/Logo/index.ts

@@ -0,0 +1,3 @@
+import Logo from './Logo.vue'
+
+export default Logo

+ 3 - 0
app/src/components/NginxControl/index.ts

@@ -0,0 +1,3 @@
+import NginxControl from './NginxControl.vue'
+
+export default NginxControl

+ 3 - 0
app/src/components/NodeSelector/index.ts

@@ -0,0 +1,3 @@
+import NodeSelector from './NodeSelector.vue'
+
+export default NodeSelector

+ 3 - 0
app/src/components/Notification/index.ts

@@ -0,0 +1,3 @@
+import Notification from './Notification.vue'
+
+export default Notification

+ 3 - 0
app/src/components/OTPInput/index.ts

@@ -0,0 +1,3 @@
+import OTPInput from './OTPInput.vue'
+
+export default OTPInput

+ 3 - 0
app/src/components/PageHeader/index.ts

@@ -0,0 +1,3 @@
+import PageHeader from './PageHeader.vue'
+
+export default PageHeader

+ 3 - 0
app/src/components/ReactiveFromNow/index.ts

@@ -0,0 +1,3 @@
+import ReactiveFromNow from './ReactiveFromNow.vue'
+
+export default ReactiveFromNow

+ 3 - 0
app/src/components/SensitiveString/index.ts

@@ -0,0 +1,3 @@
+import SensitiveString from './SensitiveString.vue'
+
+export default SensitiveString

+ 3 - 0
app/src/components/SetLanguage/index.ts

@@ -0,0 +1,3 @@
+import SetLanguage from './SetLanguage.vue'
+
+export default SetLanguage

+ 1 - 1
app/src/components/SwitchAppearance/SwitchAppearance.vue

@@ -1,6 +1,6 @@
 <script lang="ts" setup>
 import type { Ref } from 'vue'
-import VPSwitch from '@/components/VPSwitch/VPSwitch.vue'
+import VPSwitch from '@/components/VPSwitch'
 import { useSettingsStore } from '@/pinia'
 import VPIconMoon from './icons/VPIconMoon.vue'
 import VPIconSun from './icons/VPIconSun.vue'

+ 3 - 0
app/src/components/SwitchAppearance/index.ts

@@ -0,0 +1,3 @@
+import SwitchAppearance from './SwitchAppearance.vue'
+
+export default SwitchAppearance

+ 3 - 0
app/src/components/SystemRestore/index.ts

@@ -0,0 +1,3 @@
+import SystemRestoreContainer from './SystemRestoreContent.vue'
+
+export default SystemRestoreContainer

+ 8 - 0
app/src/components/TwoFA/index.ts

@@ -0,0 +1,8 @@
+import Authorization from './Authorization.vue'
+import use2FAModal from './use2FAModal'
+
+export default Authorization
+
+export {
+  use2FAModal,
+}

+ 3 - 0
app/src/components/VPSwitch/index.ts

@@ -0,0 +1,3 @@
+import VPSwitch from './VPSwitch.vue'
+
+export default VPSwitch

+ 19 - 133
app/src/views/preference/Preference.vue

@@ -1,137 +1,23 @@
 <script setup lang="ts">
-import type { Settings } from '@/api/settings'
-import settings from '@/api/settings'
-import FooterToolBar from '@/components/FooterToolbar/FooterToolBar.vue'
-import use2FAModal from '@/components/TwoFA/use2FAModal'
-import { useSettingsStore } from '@/pinia'
-import AppSettings from '@/views/preference/AppSettings.vue'
-import AuthSettings from '@/views/preference/AuthSettings.vue'
-import CertSettings from '@/views/preference/CertSettings.vue'
-import ExternalNotify from '@/views/preference/ExternalNotify.vue'
-import HTTPSettings from '@/views/preference/HTTPSettings.vue'
-import LogrotateSettings from '@/views/preference/LogrotateSettings.vue'
-import NginxSettings from '@/views/preference/NginxSettings.vue'
-import NodeSettings from '@/views/preference/NodeSettings.vue'
-import OpenAISettings from '@/views/preference/OpenAISettings.vue'
-import ServerSettings from '@/views/preference/ServerSettings.vue'
-import TerminalSettings from '@/views/preference/TerminalSettings.vue'
-import { message } from 'ant-design-vue'
-import { storeToRefs } from 'pinia'
+import FooterToolBar from '@/components/FooterToolbar'
+import {
+  AppSettings,
+  AuthSettings,
+  CertSettings,
+  ExternalNotify,
+  HTTPSettings,
+  LogrotateSettings,
+  NginxSettings,
+  NodeSettings,
+  OpenAISettings,
+  ServerSettings,
+  TerminalSettings,
+} from '@/views/preference/tabs'
+import useSystemSettingsStore from './store'
 
-const data = ref<Settings>({
-  app: {
-    page_size: 10,
-    jwt_secret: '',
-  },
-  server: {
-    host: '0.0.0.0',
-    port: 9000,
-    run_mode: 'debug',
-    enable_https: false,
-    ssl_cert: '',
-    ssl_key: '',
-  },
-  database: {
-    name: '',
-  },
-  auth: {
-    ip_white_list: [],
-    ban_threshold_minutes: 10,
-    max_attempts: 10,
-  },
-  casdoor: {
-    endpoint: '',
-    client_id: '',
-    client_secret: '',
-    certificate_path: '',
-    organization: '',
-    application: '',
-    redirect_uri: '',
-  },
-  cert: {
-    email: '',
-    ca_dir: '',
-    renewal_interval: 7,
-    recursive_nameservers: [],
-    http_challenge_port: '9180',
-  },
-  http: {
-    github_proxy: '',
-    insecure_skip_verify: false,
-  },
-  logrotate: {
-    enabled: false,
-    cmd: '',
-    interval: 1440,
-  },
-  nginx: {
-    access_log_path: '',
-    error_log_path: '',
-    config_dir: '',
-    config_path: '',
-    log_dir_white_list: [],
-    pid_path: '',
-    test_config_cmd: '',
-    reload_cmd: '',
-    restart_cmd: '',
-    stub_status_port: 51820,
-  },
-  node: {
-    name: '',
-    secret: '',
-    skip_installation: false,
-    demo: false,
-    icp_number: '',
-    public_security_number: '',
-  },
-  openai: {
-    model: '',
-    base_url: '',
-    proxy: '',
-    token: '',
-    api_type: 'OPEN_AI',
-    enable_code_completion: false,
-    code_completion_model: '',
-  },
-  terminal: {
-    start_cmd: '',
-  },
-  webauthn: {
-    rp_display_name: '',
-    rpid: '',
-    rp_origins: [],
-  },
-})
-
-settings.get().then(r => {
-  data.value = r
-})
-
-const settingsStore = useSettingsStore()
-const { server_name } = storeToRefs(settingsStore)
-const errors = ref<Record<string, Record<string, string>>>({})
-const refAuthSettings = useTemplateRef('refAuthSettings')
-
-async function save() {
-  // fix type
-  data.value.cert.http_challenge_port = data.value.cert.http_challenge_port.toString()
-
-  const otpModal = use2FAModal()
-
-  otpModal.open().then(() => {
-    settings.save(data.value).then(r => {
-      if (!settingsStore.is_remote)
-        server_name.value = r?.server?.name ?? ''
-      data.value = r
-      refAuthSettings.value?.getBannedIPs?.()
-      message.success($gettext('Save successfully'))
-      errors.value = {}
-    })
-  })
-}
+const systemSettingsStore = useSystemSettingsStore()
 
-provide('data', data)
-provide('errors', errors)
+systemSettingsStore.getSettings()
 
 const router = useRouter()
 const route = useRoute()
@@ -195,7 +81,7 @@ onMounted(() => {
           key="auth"
           :tab="$gettext('Auth')"
         >
-          <AuthSettings ref="refAuthSettings" />
+          <AuthSettings />
         </ATabPane>
         <ATabPane
           key="cert"
@@ -226,7 +112,7 @@ onMounted(() => {
     <FooterToolBar v-if="activeKey !== 'external_notify'">
       <AButton
         type="primary"
-        @click="save"
+        @click="systemSettingsStore.save"
       >
         {{ $gettext('Save') }}
       </AButton>

+ 0 - 0
app/src/views/preference/components/AddPasskey.vue → app/src/views/preference/components/AuthSettings/AddPasskey.vue


+ 2 - 2
app/src/views/preference/components/Passkey.vue → app/src/views/preference/components/AuthSettings/Passkey.vue

@@ -1,14 +1,14 @@
 <script setup lang="ts">
 import type { Passkey } from '@/api/passkey'
 import passkey from '@/api/passkey'
-import ReactiveFromNow from '@/components/ReactiveFromNow/ReactiveFromNow.vue'
+import ReactiveFromNow from '@/components/ReactiveFromNow'
 import { formatDateTime } from '@/lib/helper'
 import { useUserStore } from '@/pinia'
-import AddPasskey from '@/views/preference/components/AddPasskey.vue'
 import { DeleteOutlined, EditOutlined, KeyOutlined } from '@ant-design/icons-vue'
 import { message } from 'ant-design-vue'
 import dayjs from 'dayjs'
 import relativeTime from 'dayjs/plugin/relativeTime'
+import AddPasskey from './AddPasskey.vue'
 
 dayjs.extend(relativeTime)
 

+ 1 - 1
app/src/views/preference/components/RecoveryCodes.vue → app/src/views/preference/components/AuthSettings/RecoveryCodes.vue

@@ -2,7 +2,7 @@
 import type { TwoFAStatus } from '@/api/2fa'
 import type { RecoveryCode } from '@/api/recovery'
 import recovery from '@/api/recovery'
-import use2FAModal from '@/components/TwoFA/use2FAModal'
+import { use2FAModal } from '@/components/TwoFA'
 import { CopyOutlined, WarningOutlined } from '@ant-design/icons-vue'
 import { UseClipboard } from '@vueuse/components'
 import { message } from 'ant-design-vue'

+ 2 - 2
app/src/views/preference/components/TOTP.vue → app/src/views/preference/components/AuthSettings/TOTP.vue

@@ -1,8 +1,8 @@
 <script setup lang="ts">
 import type { RecoveryCode } from '@/api/recovery'
 import otp from '@/api/otp'
-import OTPInput from '@/components/OTPInput/OTPInput.vue'
-import use2FAModal from '@/components/TwoFA/use2FAModal'
+import OTPInput from '@/components/OTPInput'
+import { use2FAModal } from '@/components/TwoFA'
 import { CheckCircleOutlined } from '@ant-design/icons-vue'
 import { UseClipboard } from '@vueuse/components'
 import { message } from 'ant-design-vue'

+ 11 - 0
app/src/views/preference/components/AuthSettings/index.ts

@@ -0,0 +1,11 @@
+import AddPasskey from './AddPasskey.vue'
+import Passkey from './Passkey.vue'
+import RecoveryCodes from './RecoveryCodes.vue'
+import TOTP from './TOTP.vue'
+
+export {
+  AddPasskey,
+  Passkey,
+  RecoveryCodes,
+  TOTP,
+}

+ 127 - 0
app/src/views/preference/store/index.ts

@@ -0,0 +1,127 @@
+import type { Settings } from '@/api/settings'
+import settings from '@/api/settings'
+import { use2FAModal } from '@/components/TwoFA'
+import { useSettingsStore } from '@/pinia'
+import { message } from 'ant-design-vue'
+import { defineStore } from 'pinia'
+
+const useSystemSettingsStore = defineStore('systemSettings', () => {
+  const data = ref<Settings>({
+    app: {
+      page_size: 10,
+      jwt_secret: '',
+    },
+    server: {
+      host: '0.0.0.0',
+      port: 9000,
+      run_mode: 'debug',
+      enable_https: false,
+      ssl_cert: '',
+      ssl_key: '',
+    },
+    database: {
+      name: '',
+    },
+    auth: {
+      ip_white_list: [],
+      ban_threshold_minutes: 10,
+      max_attempts: 10,
+    },
+    casdoor: {
+      endpoint: '',
+      client_id: '',
+      client_secret: '',
+      certificate_path: '',
+      organization: '',
+      application: '',
+      redirect_uri: '',
+    },
+    cert: {
+      email: '',
+      ca_dir: '',
+      renewal_interval: 7,
+      recursive_nameservers: [],
+      http_challenge_port: '9180',
+    },
+    http: {
+      github_proxy: '',
+      insecure_skip_verify: false,
+    },
+    logrotate: {
+      enabled: false,
+      cmd: '',
+      interval: 1440,
+    },
+    nginx: {
+      access_log_path: '',
+      error_log_path: '',
+      config_dir: '',
+      config_path: '',
+      log_dir_white_list: [],
+      pid_path: '',
+      test_config_cmd: '',
+      reload_cmd: '',
+      restart_cmd: '',
+      stub_status_port: 51820,
+      container_name: '',
+    },
+    node: {
+      name: '',
+      secret: '',
+      skip_installation: false,
+      demo: false,
+      icp_number: '',
+      public_security_number: '',
+    },
+    openai: {
+      model: '',
+      base_url: '',
+      proxy: '',
+      token: '',
+      api_type: 'OPEN_AI',
+      enable_code_completion: false,
+      code_completion_model: '',
+    },
+    terminal: {
+      start_cmd: '',
+    },
+    webauthn: {
+      rp_display_name: '',
+      rpid: '',
+      rp_origins: [],
+    },
+  })
+  const errors = ref<Record<string, Record<string, string>>>({})
+
+  function getSettings() {
+    settings.get().then(r => {
+      data.value = r
+    })
+  }
+
+  async function save() {
+    if (!data.value)
+      return
+
+    // fix type
+    data.value.cert.http_challenge_port = data.value.cert.http_challenge_port.toString()
+
+    const otpModal = use2FAModal()
+
+    otpModal.open().then(() => {
+      settings.save(data.value!).then(r => {
+        const settingsStore = useSettingsStore()
+        const { server_name } = storeToRefs(settingsStore)
+        if (!settingsStore.is_remote)
+          server_name.value = r?.server?.name ?? ''
+        data.value = r
+        message.success($gettext('Save successfully'))
+        errors.value = {}
+      })
+    })
+  }
+
+  return { data, errors, getSettings, save }
+})
+
+export default useSystemSettingsStore

+ 4 - 3
app/src/views/preference/AppSettings.vue → app/src/views/preference/tabs/AppSettings.vue

@@ -1,8 +1,9 @@
 <script setup lang="ts">
-import type { Settings } from '@/api/settings'
-import SensitiveString from '@/components/SensitiveString/SensitiveString.vue'
+import SensitiveString from '@/components/SensitiveString'
+import useSystemSettingsStore from '../store'
 
-const data: Ref<Settings> = inject('data') as Ref<Settings>
+const systemSettingsStore = useSystemSettingsStore()
+const { data } = storeToRefs(systemSettingsStore)
 </script>
 
 <template>

+ 6 - 6
app/src/views/preference/AuthSettings.vue → app/src/views/preference/tabs/AuthSettings.vue

@@ -1,18 +1,18 @@
 <script setup lang="tsx">
 import type { TwoFAStatus } from '@/api/2fa'
 import type { RecoveryCode } from '@/api/recovery'
-import type { BannedIP, Settings } from '@/api/settings'
+import type { BannedIP } from '@/api/settings'
 import type { CustomRender } from '@/components/StdDesign/StdDataDisplay/StdTableTransformer'
 import type { Ref } from 'vue'
 import twoFA from '@/api/2fa'
 import setting from '@/api/settings'
-import RecoveryCodes from '@/views/preference/components/RecoveryCodes.vue'
-import TOTP from '@/views/preference/components/TOTP.vue'
 import { message } from 'ant-design-vue'
 import dayjs from 'dayjs'
-import PasskeyRegistration from './components/Passkey.vue'
+import { Passkey, RecoveryCodes, TOTP } from '../components/AuthSettings'
+import useSystemSettingsStore from '../store'
 
-const data: Ref<Settings> = inject('data') as Ref<Settings>
+const systemSettingsStore = useSystemSettingsStore()
+const { data } = storeToRefs(systemSettingsStore)
 
 const bannedIPColumns = [{
   title: $gettext('IP'),
@@ -68,7 +68,7 @@ get2FAStatus()
   <div class="flex justify-center">
     <div>
       <h2>{{ $gettext('2FA Settings') }}</h2>
-      <PasskeyRegistration class="mb-4" />
+      <Passkey class="mb-4" />
 
       <TOTP
         v-model:recovery-codes="recoveryCodes"

+ 3 - 3
app/src/views/preference/CertSettings.vue → app/src/views/preference/tabs/CertSettings.vue

@@ -1,10 +1,10 @@
 <script setup lang="ts">
-import type { Settings } from '@/api/settings'
 import { DeleteOutlined, HolderOutlined } from '@ant-design/icons-vue'
 import Draggable from 'vuedraggable'
+import useSystemSettingsStore from '../store'
 
-const data: Ref<Settings> = inject('data') as Ref<Settings>
-const errors: Record<string, Record<string, string>> = inject('errors') as Record<string, Record<string, string>>
+const systemSettingsStore = useSystemSettingsStore()
+const { data, errors } = storeToRefs(systemSettingsStore)
 </script>
 
 <template>

+ 2 - 2
app/src/views/preference/ExternalNotify.vue → app/src/views/preference/tabs/ExternalNotify.vue

@@ -1,8 +1,8 @@
 <script setup lang="ts">
 import externalNotify from '@/api/external_notify'
 import { StdCurd } from '@/components/StdDesign/StdDataDisplay'
-import columns from './components/ExternalNotify/columns'
-import ExternalNotifyEditor from './components/ExternalNotify/ExternalNotifyEditor.vue'
+import ExternalNotifyEditor from '../components/ExternalNotify'
+import columns from '../components/ExternalNotify/columns'
 </script>
 
 <template>

+ 3 - 3
app/src/views/preference/HTTPSettings.vue → app/src/views/preference/tabs/HTTPSettings.vue

@@ -1,8 +1,8 @@
 <script setup lang="ts">
-import type { Settings } from '@/api/settings'
+import useSystemSettingsStore from '../store'
 
-const data: Ref<Settings> = inject('data') as Ref<Settings>
-const errors: Record<string, Record<string, string>> = inject('errors') as Record<string, Record<string, string>>
+const systemSettingsStore = useSystemSettingsStore()
+const { data, errors } = storeToRefs(systemSettingsStore)
 </script>
 
 <template>

+ 3 - 2
app/src/views/preference/LogrotateSettings.vue → app/src/views/preference/tabs/LogrotateSettings.vue

@@ -1,7 +1,8 @@
 <script setup lang="ts">
-import type { Settings } from '@/api/settings'
+import useSystemSettingsStore from '../store'
 
-const data: Ref<Settings> = inject('data') as Ref<Settings>
+const systemSettingsStore = useSystemSettingsStore()
+const { data } = storeToRefs(systemSettingsStore)
 </script>
 
 <template>

+ 16 - 2
app/src/views/preference/NginxSettings.vue → app/src/views/preference/tabs/NginxSettings.vue

@@ -1,7 +1,8 @@
 <script setup lang="ts">
-import type { Settings } from '@/api/settings'
+import useSystemSettingsStore from '../store'
 
-const data: Ref<Settings> = inject('data') as Ref<Settings>
+const systemSettingsStore = useSystemSettingsStore()
+const { data } = storeToRefs(systemSettingsStore)
 </script>
 
 <template>
@@ -42,6 +43,19 @@ const data: Ref<Settings> = inject('data') as Ref<Settings>
     <AFormItem :label="$gettext('Nginx Restart Command')">
       {{ data.nginx.restart_cmd }}
     </AFormItem>
+    <AFormItem :label="$gettext('Nginx Control Mode')">
+      <div v-if="data.nginx.container_name">
+        <ATag color="blue" tag>
+          {{ $gettext('External Docker Container') }}
+        </ATag>
+        {{ data.nginx.container_name }}
+      </div>
+      <div v-else>
+        <ATag color="green" tag>
+          {{ $gettext('Local') }}
+        </ATag>
+      </div>
+    </AFormItem>
   </AForm>
 </template>
 

+ 4 - 4
app/src/views/preference/NodeSettings.vue → app/src/views/preference/tabs/NodeSettings.vue

@@ -1,9 +1,9 @@
 <script setup lang="ts">
-import type { Settings } from '@/api/settings'
-import SensitiveString from '@/components/SensitiveString/SensitiveString.vue'
+import SensitiveString from '@/components/SensitiveString'
+import useSystemSettingsStore from '../store'
 
-const data: Ref<Settings> = inject('data') as Ref<Settings>
-const errors: Record<string, Record<string, string>> = inject('errors') as Record<string, Record<string, string>>
+const systemSettingsStore = useSystemSettingsStore()
+const { data, errors } = storeToRefs(systemSettingsStore)
 </script>
 
 <template>

+ 3 - 3
app/src/views/preference/OpenAISettings.vue → app/src/views/preference/tabs/OpenAISettings.vue

@@ -1,9 +1,9 @@
 <script setup lang="ts">
-import type { Settings } from '@/api/settings'
 import { LLM_MODELS, LLM_PROVIDERS } from '@/constants/llm'
+import useSystemSettingsStore from '../store'
 
-const data: Ref<Settings> = inject('data') as Ref<Settings>
-const errors: Record<string, Record<string, string>> = inject('errors') as Record<string, Record<string, string>>
+const systemSettingsStore = useSystemSettingsStore()
+const { data, errors } = storeToRefs(systemSettingsStore)
 
 const models = LLM_MODELS.map(model => ({
   value: model,

+ 3 - 2
app/src/views/preference/ServerSettings.vue → app/src/views/preference/tabs/ServerSettings.vue

@@ -1,9 +1,10 @@
 <script setup lang="ts">
 import type { Cert } from '@/api/cert'
-import type { Settings } from '@/api/settings'
 import ChangeCert from '@/views/site/site_edit/components/Cert/ChangeCert.vue'
+import useSystemSettingsStore from '../store'
 
-const data: Ref<Settings> = inject('data') as Ref<Settings>
+const systemSettingsStore = useSystemSettingsStore()
+const { data } = storeToRefs(systemSettingsStore)
 
 function handleCertChange(certs: Cert[]) {
   if (certs.length > 0 && data.value?.server) {

+ 3 - 2
app/src/views/preference/TerminalSettings.vue → app/src/views/preference/tabs/TerminalSettings.vue

@@ -1,7 +1,8 @@
 <script setup lang="ts">
-import type { Settings } from '@/api/settings'
+import useSystemSettingsStore from '../store'
 
-const data: Ref<Settings> = inject('data') as Ref<Settings>
+const systemSettingsStore = useSystemSettingsStore()
+const { data } = storeToRefs(systemSettingsStore)
 </script>
 
 <template>

+ 11 - 0
app/src/views/preference/tabs/index.ts

@@ -0,0 +1,11 @@
+export { default as AppSettings } from './AppSettings.vue'
+export { default as AuthSettings } from './AuthSettings.vue'
+export { default as CertSettings } from './CertSettings.vue'
+export { default as ExternalNotify } from './ExternalNotify.vue'
+export { default as HTTPSettings } from './HTTPSettings.vue'
+export { default as LogrotateSettings } from './LogrotateSettings.vue'
+export { default as NginxSettings } from './NginxSettings.vue'
+export { default as NodeSettings } from './NodeSettings.vue'
+export { default as OpenAISettings } from './OpenAISettings.vue'
+export { default as ServerSettings } from './ServerSettings.vue'
+export { default as TerminalSettings } from './TerminalSettings.vue'