refactor(preference): use pinia store

This commit is contained in:
Jacky 2025-04-21 07:34:35 +00:00
parent d079e805e5
commit 4aa42da642
No known key found for this signature in database
GPG key ID: 215C21B10DF38B4D
39 changed files with 282 additions and 171 deletions

View file

@ -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"

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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'

View file

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

View file

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

View file

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

View file

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

View file

@ -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: [],
},
})
const systemSettingsStore = useSystemSettingsStore()
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 = {}
})
})
}
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>

View file

@ -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)

View file

@ -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'

View file

@ -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'

View file

@ -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,
}

View file

@ -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

View file

@ -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>

View file

@ -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"

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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,

View file

@ -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) {

View file

@ -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>

View file

@ -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'