删除系统设置里面环境配置相关代码
This commit is contained in:
parent
f59809023a
commit
d3b7cdb229
@ -4,238 +4,73 @@
|
|||||||
<h1 class="page-title">{{ t('Settings') }}</h1>
|
<h1 class="page-title">{{ t('Settings') }}</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<n-grid :cols="2" :x-gap="24" :y-gap="24">
|
<n-card :title="t('System Settings')">
|
||||||
<!-- 左栏:系统设置 -->
|
<n-form :model="systemSettings" label-placement="left" label-width="120px">
|
||||||
<n-grid-item>
|
<n-form-item :label="t('App Name')">
|
||||||
<n-card :title="t('System Settings')">
|
<n-input v-model:value="systemSettings.appName" :placeholder="t('Enter app name')" />
|
||||||
<n-form :model="systemSettings" label-placement="left" label-width="120px">
|
</n-form-item>
|
||||||
<n-form-item :label="t('App Name')">
|
<n-form-item :label="t('Interface Language')">
|
||||||
<n-input v-model:value="systemSettings.appName" :placeholder="t('Enter app name')" />
|
<n-select
|
||||||
</n-form-item>
|
v-model:value="systemSettings.language"
|
||||||
<n-form-item :label="t('Interface Language')">
|
:options="languageOptions"
|
||||||
<n-select
|
style="width: 200px"
|
||||||
v-model:value="systemSettings.language"
|
@update:value="changeLanguage"
|
||||||
:options="languageOptions"
|
/>
|
||||||
style="width: 200px"
|
</n-form-item>
|
||||||
@update:value="changeLanguage"
|
<n-form-item :label="t('Items Per Page')">
|
||||||
/>
|
<n-select
|
||||||
</n-form-item>
|
v-model:value="systemSettings.itemsPerPage"
|
||||||
<n-form-item :label="t('Items Per Page')">
|
:options="pageSizeOptions"
|
||||||
<n-select
|
style="width: 120px"
|
||||||
v-model:value="systemSettings.itemsPerPage"
|
/>
|
||||||
:options="pageSizeOptions"
|
</n-form-item>
|
||||||
style="width: 120px"
|
<n-form-item :label="t('Timezone')">
|
||||||
/>
|
<n-alert v-if="timezoneError" type="error" style="margin-bottom: 8px">
|
||||||
</n-form-item>
|
{{ timezoneError }}
|
||||||
<n-form-item :label="t('Timezone')">
|
|
||||||
<n-alert v-if="timezoneError" type="error" style="margin-bottom: 8px">
|
|
||||||
{{ timezoneError }}
|
|
||||||
</n-alert>
|
|
||||||
<n-select
|
|
||||||
v-model:value="systemSettings.timezone"
|
|
||||||
:options="timezoneOptions"
|
|
||||||
style="width: 250px"
|
|
||||||
filterable
|
|
||||||
:placeholder="t('Select timezone')"
|
|
||||||
:disabled="timezoneOptions.length === 0"
|
|
||||||
/>
|
|
||||||
</n-form-item>
|
|
||||||
</n-form>
|
|
||||||
<template #footer>
|
|
||||||
<n-space justify="start">
|
|
||||||
<n-button type="primary" class="save-btn-brand" @click="saveSystemSettings">
|
|
||||||
<template #icon>
|
|
||||||
<n-icon><Icon icon="tabler:check" /></n-icon>
|
|
||||||
</template>
|
|
||||||
{{ t('Save') }}
|
|
||||||
</n-button>
|
|
||||||
</n-space>
|
|
||||||
</template>
|
|
||||||
</n-card>
|
|
||||||
</n-grid-item>
|
|
||||||
|
|
||||||
<!-- 右栏:环境配置(仅系统管理员可见) -->
|
|
||||||
<n-grid-item v-if="isAdmin">
|
|
||||||
<n-card :title="t('Environment Configuration')">
|
|
||||||
<n-alert type="warning" style="margin-bottom: 16px">
|
|
||||||
{{ t('Only system administrators can view and edit environment configuration') }}
|
|
||||||
</n-alert>
|
</n-alert>
|
||||||
<n-form
|
<n-select
|
||||||
:model="envConfig"
|
v-model:value="systemSettings.timezone"
|
||||||
label-placement="left"
|
:options="timezoneOptions"
|
||||||
label-width="180px"
|
style="width: 250px"
|
||||||
:loading="envConfigLoading"
|
filterable
|
||||||
>
|
:placeholder="t('Select timezone')"
|
||||||
<n-collapse>
|
:disabled="timezoneOptions.length === 0"
|
||||||
<n-collapse-item name="jingrow" :title="t('Jingrow API Configuration')">
|
/>
|
||||||
<n-form-item :label="t('Jingrow Server URL')">
|
</n-form-item>
|
||||||
<n-input v-model:value="envConfig.jingrow_server_url" placeholder="https://example.jingrow.com" />
|
</n-form>
|
||||||
</n-form-item>
|
<template #footer>
|
||||||
<n-form-item :label="t('Jingrow API Key')">
|
<n-space justify="start">
|
||||||
<n-input v-model:value="envConfig.jingrow_api_key" type="password" show-password-on="click" />
|
<n-button type="primary" class="save-btn-brand" @click="saveSystemSettings">
|
||||||
</n-form-item>
|
<template #icon>
|
||||||
<n-form-item :label="t('Jingrow API Secret')">
|
<n-icon><Icon icon="tabler:check" /></n-icon>
|
||||||
<n-input v-model:value="envConfig.jingrow_api_secret" type="password" show-password-on="click" />
|
</template>
|
||||||
</n-form-item>
|
{{ t('Save') }}
|
||||||
</n-collapse-item>
|
</n-button>
|
||||||
|
</n-space>
|
||||||
<n-collapse-item name="cloud" :title="t('Jingrow Cloud Configuration')">
|
</template>
|
||||||
<n-form-item :label="t('Cloud URL')">
|
</n-card>
|
||||||
<n-input v-model:value="envConfig.jingrow_cloud_url" />
|
|
||||||
</n-form-item>
|
|
||||||
<n-form-item :label="t('Cloud API URL')">
|
|
||||||
<n-input v-model:value="envConfig.jingrow_cloud_api_url" />
|
|
||||||
</n-form-item>
|
|
||||||
<n-form-item :label="t('Cloud API Key')">
|
|
||||||
<n-input v-model:value="envConfig.jingrow_cloud_api_key" type="password" show-password-on="click" />
|
|
||||||
</n-form-item>
|
|
||||||
<n-form-item :label="t('Cloud API Secret')">
|
|
||||||
<n-input v-model:value="envConfig.jingrow_cloud_api_secret" type="password" show-password-on="click" />
|
|
||||||
</n-form-item>
|
|
||||||
</n-collapse-item>
|
|
||||||
|
|
||||||
<n-collapse-item v-if="isLocalMode" name="database" :title="t('Database Configuration')">
|
|
||||||
<n-form-item :label="t('DB Host')">
|
|
||||||
<n-input v-model:value="envConfig.jingrow_db_host" />
|
|
||||||
</n-form-item>
|
|
||||||
<n-form-item :label="t('DB Port')">
|
|
||||||
<n-input v-model:value="envConfig.jingrow_db_port" />
|
|
||||||
</n-form-item>
|
|
||||||
<n-form-item :label="t('DB Name')">
|
|
||||||
<n-input v-model:value="envConfig.jingrow_db_name" />
|
|
||||||
</n-form-item>
|
|
||||||
<n-form-item :label="t('DB User')">
|
|
||||||
<n-input v-model:value="envConfig.jingrow_db_user" />
|
|
||||||
</n-form-item>
|
|
||||||
<n-form-item :label="t('DB Password')">
|
|
||||||
<n-input v-model:value="envConfig.jingrow_db_password" type="password" show-password-on="click" />
|
|
||||||
</n-form-item>
|
|
||||||
<n-form-item :label="t('DB Type')">
|
|
||||||
<n-select v-model:value="envConfig.jingrow_db_type" :options="dbTypeOptions" style="width: 200px" />
|
|
||||||
</n-form-item>
|
|
||||||
</n-collapse-item>
|
|
||||||
|
|
||||||
<n-collapse-item name="backend" :title="t('Backend Configuration')">
|
|
||||||
<n-form-item :label="t('Backend Host')">
|
|
||||||
<n-input v-model:value="envConfig.backend_host" />
|
|
||||||
</n-form-item>
|
|
||||||
<n-form-item :label="t('Backend Port')">
|
|
||||||
<n-input-number v-model:value="envConfig.backend_port" :min="1" :max="65535" />
|
|
||||||
</n-form-item>
|
|
||||||
<n-form-item :label="t('Backend Reload')">
|
|
||||||
<n-switch v-model:value="envConfig.backend_reload" />
|
|
||||||
</n-form-item>
|
|
||||||
</n-collapse-item>
|
|
||||||
|
|
||||||
<n-collapse-item name="dramatiq" :title="t('Dramatiq')">
|
|
||||||
<n-form-item :label="t('Worker Processes')">
|
|
||||||
<n-input-number v-model:value="envConfig.worker_processes" :min="1" :max="32" />
|
|
||||||
</n-form-item>
|
|
||||||
<n-form-item :label="t('Worker Threads')">
|
|
||||||
<n-input-number v-model:value="envConfig.worker_threads" :min="1" :max="32" />
|
|
||||||
</n-form-item>
|
|
||||||
<n-form-item :label="t('Watch')">
|
|
||||||
<n-switch v-model:value="envConfig.watch" />
|
|
||||||
</n-form-item>
|
|
||||||
</n-collapse-item>
|
|
||||||
|
|
||||||
<n-collapse-item name="qdrant" :title="t('Qdrant Configuration')">
|
|
||||||
<n-form-item :label="t('Qdrant Host')">
|
|
||||||
<n-input v-model:value="envConfig.qdrant_host" />
|
|
||||||
</n-form-item>
|
|
||||||
<n-form-item :label="t('Qdrant Port')">
|
|
||||||
<n-input-number v-model:value="envConfig.qdrant_port" :min="1" :max="65535" />
|
|
||||||
</n-form-item>
|
|
||||||
</n-collapse-item>
|
|
||||||
|
|
||||||
<n-collapse-item name="runtime" :title="t('Other')">
|
|
||||||
<n-form-item :label="t('Run Mode')">
|
|
||||||
<n-select v-model:value="envConfig.run_mode" :options="runModeOptions" style="width: 200px" />
|
|
||||||
</n-form-item>
|
|
||||||
<n-form-item :label="t('Environment')">
|
|
||||||
<n-select v-model:value="envConfig.environment" :options="environmentOptions" style="width: 200px" />
|
|
||||||
</n-form-item>
|
|
||||||
<n-form-item :label="t('Log Level')">
|
|
||||||
<n-select v-model:value="envConfig.log_level" :options="logLevelOptions" style="width: 200px" />
|
|
||||||
</n-form-item>
|
|
||||||
</n-collapse-item>
|
|
||||||
</n-collapse>
|
|
||||||
</n-form>
|
|
||||||
<template #footer>
|
|
||||||
<n-space justify="start">
|
|
||||||
<n-button type="default" @click="() => loadEnvironmentConfig()" :loading="envConfigLoading">
|
|
||||||
<template #icon>
|
|
||||||
<n-icon><Icon icon="tabler:refresh" /></n-icon>
|
|
||||||
</template>
|
|
||||||
{{ t('Refresh') }}
|
|
||||||
</n-button>
|
|
||||||
<n-button type="warning" :loading="envConfigRestarting" @click="handleRestartEnvironment">
|
|
||||||
<template #icon>
|
|
||||||
<n-icon><Icon icon="ix:restart" /></n-icon>
|
|
||||||
</template>
|
|
||||||
{{ t('Restart Environment') }}
|
|
||||||
</n-button>
|
|
||||||
<n-button type="primary" class="save-btn-brand" :loading="envConfigSaving" @click="saveEnvironmentConfig">
|
|
||||||
<template #icon>
|
|
||||||
<n-icon><Icon icon="tabler:check" /></n-icon>
|
|
||||||
</template>
|
|
||||||
{{ t('Save') }}
|
|
||||||
</n-button>
|
|
||||||
</n-space>
|
|
||||||
</template>
|
|
||||||
</n-card>
|
|
||||||
</n-grid-item>
|
|
||||||
</n-grid>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { reactive, onMounted, computed, ref } from 'vue'
|
import { reactive, onMounted, ref } from 'vue'
|
||||||
import {
|
import {
|
||||||
NGrid,
|
|
||||||
NGridItem,
|
|
||||||
NCard,
|
NCard,
|
||||||
NForm,
|
NForm,
|
||||||
NFormItem,
|
NFormItem,
|
||||||
NInput,
|
NInput,
|
||||||
NButton,
|
NButton,
|
||||||
NInputNumber,
|
|
||||||
NSelect,
|
NSelect,
|
||||||
NSwitch,
|
|
||||||
NAlert,
|
NAlert,
|
||||||
NCollapse,
|
|
||||||
NCollapseItem,
|
|
||||||
NSpace,
|
NSpace,
|
||||||
NIcon,
|
NIcon,
|
||||||
useMessage,
|
useMessage
|
||||||
useDialog
|
|
||||||
} from 'naive-ui'
|
} from 'naive-ui'
|
||||||
import { Icon } from '@iconify/vue'
|
import { Icon } from '@iconify/vue'
|
||||||
import { getCurrentLocale, setLocale, locales, initLocale, t } from '../../shared/i18n'
|
import { getCurrentLocale, setLocale, locales, initLocale, t } from '../../shared/i18n'
|
||||||
import { useAuthStore } from '../../shared/stores/auth'
|
|
||||||
import { getEnvironmentConfig, updateEnvironmentConfig, restartEnvironment, type EnvironmentConfig } from '../../shared/api/system'
|
|
||||||
import { getCurrentTimezone, getGroupedTimezoneOptions } from '../../shared/utils/timezone'
|
import { getCurrentTimezone, getGroupedTimezoneOptions } from '../../shared/utils/timezone'
|
||||||
|
|
||||||
const message = useMessage()
|
const message = useMessage()
|
||||||
const dialog = useDialog()
|
|
||||||
const authStore = useAuthStore()
|
|
||||||
|
|
||||||
// 检查是否为系统管理员
|
|
||||||
const isAdmin = computed(() => {
|
|
||||||
const user = authStore.user
|
|
||||||
return user?.username === 'Administrator' || user?.id === 'Administrator'
|
|
||||||
})
|
|
||||||
|
|
||||||
// 检查是否为 local 运行模式
|
|
||||||
const isLocalMode = computed(() => {
|
|
||||||
return envConfig.run_mode === 'local'
|
|
||||||
})
|
|
||||||
|
|
||||||
// 环境配置
|
|
||||||
const envConfig = reactive<Partial<EnvironmentConfig>>({})
|
|
||||||
const envConfigLoading = ref(false)
|
|
||||||
const envConfigSaving = ref(false)
|
|
||||||
const envConfigRestarting = ref(false)
|
|
||||||
|
|
||||||
const systemSettings = reactive({
|
const systemSettings = reactive({
|
||||||
appName: localStorage.getItem('appName') || 'Jingrow',
|
appName: localStorage.getItem('appName') || 'Jingrow',
|
||||||
@ -262,33 +97,6 @@ const pageSizeOptions = [
|
|||||||
const timezoneOptions = ref<Array<{ type: string; label: string; key: string; children: Array<{ label: string; value: string }> }>>([])
|
const timezoneOptions = ref<Array<{ type: string; label: string; key: string; children: Array<{ label: string; value: string }> }>>([])
|
||||||
const timezoneError = ref<string | null>(null)
|
const timezoneError = ref<string | null>(null)
|
||||||
|
|
||||||
// 数据库类型选项
|
|
||||||
const dbTypeOptions = [
|
|
||||||
{ label: 'MariaDB', value: 'mariadb' },
|
|
||||||
{ label: 'MySQL', value: 'mysql' },
|
|
||||||
{ label: 'PostgreSQL', value: 'postgresql' }
|
|
||||||
]
|
|
||||||
|
|
||||||
// 运行模式选项
|
|
||||||
const runModeOptions = [
|
|
||||||
{ label: 'API', value: 'api' },
|
|
||||||
{ label: 'Local', value: 'local' }
|
|
||||||
]
|
|
||||||
|
|
||||||
// 环境选项
|
|
||||||
const environmentOptions = [
|
|
||||||
{ label: 'Development', value: 'development' },
|
|
||||||
{ label: 'Production', value: 'production' }
|
|
||||||
]
|
|
||||||
|
|
||||||
// 日志级别选项
|
|
||||||
const logLevelOptions = [
|
|
||||||
{ label: 'DEBUG', value: 'DEBUG' },
|
|
||||||
{ label: 'INFO', value: 'INFO' },
|
|
||||||
{ label: 'WARNING', value: 'WARNING' },
|
|
||||||
{ label: 'ERROR', value: 'ERROR' },
|
|
||||||
{ label: 'CRITICAL', value: 'CRITICAL' }
|
|
||||||
]
|
|
||||||
|
|
||||||
const changeLanguage = (locale: string) => {
|
const changeLanguage = (locale: string) => {
|
||||||
setLocale(locale)
|
setLocale(locale)
|
||||||
@ -310,88 +118,6 @@ const saveSystemSettings = () => {
|
|||||||
}, 1000)
|
}, 1000)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 加载环境配置
|
|
||||||
const loadEnvironmentConfig = async (showMessage = true) => {
|
|
||||||
if (!isAdmin.value) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
envConfigLoading.value = true
|
|
||||||
try {
|
|
||||||
const result = await getEnvironmentConfig()
|
|
||||||
if (result.success && result.data) {
|
|
||||||
Object.assign(envConfig, result.data)
|
|
||||||
if (showMessage) {
|
|
||||||
message.success(t('Environment configuration loaded'))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (showMessage) {
|
|
||||||
message.error(result.message || t('Failed to load environment configuration'))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (error: any) {
|
|
||||||
if (showMessage) {
|
|
||||||
message.error(error.message || t('Failed to load environment configuration'))
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
envConfigLoading.value = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 保存环境配置
|
|
||||||
const saveEnvironmentConfig = async () => {
|
|
||||||
if (!isAdmin.value) {
|
|
||||||
message.error(t('Only system administrators can edit environment configuration'))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
envConfigSaving.value = true
|
|
||||||
try {
|
|
||||||
const result = await updateEnvironmentConfig(envConfig)
|
|
||||||
if (result.success) {
|
|
||||||
message.success(result.message || t('Environment configuration saved'))
|
|
||||||
// 重新加载配置以获取最新值(静默加载,不显示消息)
|
|
||||||
await loadEnvironmentConfig(false)
|
|
||||||
} else {
|
|
||||||
message.error(result.message || t('Failed to save environment configuration'))
|
|
||||||
}
|
|
||||||
} catch (error: any) {
|
|
||||||
message.error(error.message || t('Failed to save environment configuration'))
|
|
||||||
} finally {
|
|
||||||
envConfigSaving.value = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 重启环境
|
|
||||||
const handleRestartEnvironment = () => {
|
|
||||||
if (!isAdmin.value) {
|
|
||||||
message.error(t('Only system administrators can restart environment'))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// 确认对话框
|
|
||||||
dialog.warning({
|
|
||||||
title: t('Restart Environment'),
|
|
||||||
content: t('Are you sure you want to restart the environment? This operation may cause service interruption.'),
|
|
||||||
positiveText: t('Restart'),
|
|
||||||
negativeText: t('Cancel'),
|
|
||||||
onPositiveClick: async () => {
|
|
||||||
envConfigRestarting.value = true
|
|
||||||
try {
|
|
||||||
const result = await restartEnvironment()
|
|
||||||
if (result.success) {
|
|
||||||
message.success(result.message || t('Environment restart request submitted. The system will restart shortly.'))
|
|
||||||
} else {
|
|
||||||
message.error(result.message || t('Failed to restart environment'))
|
|
||||||
}
|
|
||||||
} catch (error: any) {
|
|
||||||
message.error(error.message || t('Failed to restart environment'))
|
|
||||||
} finally {
|
|
||||||
envConfigRestarting.value = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
initLocale()
|
initLocale()
|
||||||
@ -406,10 +132,6 @@ onMounted(async () => {
|
|||||||
console.error('Failed to load timezone options:', error)
|
console.error('Failed to load timezone options:', error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果是系统管理员,加载环境配置(静默加载,不显示消息)
|
|
||||||
if (isAdmin.value) {
|
|
||||||
await loadEnvironmentConfig(false)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user