优化设置页面

This commit is contained in:
jingrow 2025-11-02 00:26:24 +08:00
parent c59355dcae
commit 78bf296db5
2 changed files with 191 additions and 59 deletions

View File

@ -876,6 +876,49 @@
"View details feature coming soon": "查看详情功能即将推出",
"Install feature coming soon": "安装功能即将推出",
"Publish app feature coming soon": "发布应用功能即将推出",
"Environment Configuration": "环境配置",
"Only system administrators can view and edit environment configuration": "仅系统管理员可以查看和编辑环境配置",
"Jingrow API Configuration": "Jingrow API 配置",
"Jingrow Server URL": "Jingrow 服务器地址",
"Jingrow API Key": "Jingrow API 密钥",
"Jingrow API Secret": "Jingrow API 密钥",
"Jingrow Session Cookie": "Jingrow 会话 Cookie",
"Jingrow Cloud Configuration": "Jingrow Cloud 配置",
"Cloud URL": "Cloud 地址",
"Cloud API URL": "Cloud API 地址",
"Cloud API Key": "Cloud API 密钥",
"Cloud API Secret": "Cloud API 密钥",
"Database Configuration": "数据库配置",
"DB Host": "数据库主机",
"DB Port": "数据库端口",
"DB Name": "数据库名称",
"DB User": "数据库用户",
"DB Password": "数据库密码",
"DB Type": "数据库类型",
"Qdrant Configuration": "Qdrant 配置",
"Qdrant Host": "Qdrant 主机",
"Qdrant Port": "Qdrant 端口",
"Runtime Configuration": "运行时配置",
"Run Mode": "运行模式",
"Environment": "环境",
"Log Level": "日志级别",
"Backend": "后端配置",
"Other": "其他",
"Backend Host": "后端主机",
"Backend Port": "后端端口",
"Backend Reload": "后端热重载",
"Dramatiq": "Dramatiq 任务队列",
"Worker Processes": "工作进程数",
"Worker Threads": "工作线程数",
"Watch": "监听文件变化",
"Save Environment Configuration": "保存环境配置",
"Environment configuration loaded": "环境配置已加载",
"Environment configuration saved": "环境配置已保存",
"Failed to load environment configuration": "加载环境配置失败",
"Failed to save environment configuration": "保存环境配置失败",
"Refresh": "刷新",
"Save": "保存",
"Publish App": "发布应用",
"Active": "活跃",
"View detailed information about the application": "查看应用的详细信息",

View File

@ -1,12 +1,36 @@
<template>
<div class="settings-page">
<div class="page-header">
<h1 class="page-title">{{ t('Settings') }}</h1>
<p class="page-description">{{ t('System settings') }}</p>
<n-space justify="space-between" align="center">
<div>
<h1 class="page-title">{{ t('Settings') }}</h1>
</div>
<n-space v-if="isAdmin">
<n-button type="default" @click="loadEnvironmentConfig" :loading="envConfigLoading">
<template #icon>
<n-icon><Icon icon="tabler:refresh" /></n-icon>
</template>
</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>
<n-space v-else>
<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>
</n-space>
</div>
<n-grid :cols="1" :x-gap="24" :y-gap="24">
<!-- 系统设置 -->
<n-grid :cols="2" :x-gap="24" :y-gap="24">
<!-- 左栏系统设置 -->
<n-grid-item>
<n-card :title="t('System Settings')">
<n-form :model="systemSettings" label-placement="left" label-width="120px">
@ -49,16 +73,11 @@
:placeholder="t('Select timezone')"
/>
</n-form-item>
<n-form-item>
<n-button type="primary" @click="saveSystemSettings">
{{ t('Save settings') }}
</n-button>
</n-form-item>
</n-form>
</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">
@ -72,106 +91,101 @@
>
<n-collapse>
<n-collapse-item name="jingrow" :title="t('Jingrow API Configuration')">
<n-form-item label="Jingrow Server URL">
<n-form-item :label="t('Jingrow Server URL')">
<n-input v-model:value="envConfig.jingrow_server_url" placeholder="https://example.jingrow.com" />
</n-form-item>
<n-form-item label="Jingrow API Key">
<n-form-item :label="t('Jingrow API Key')">
<n-input v-model:value="envConfig.jingrow_api_key" type="password" show-password-on="click" />
</n-form-item>
<n-form-item label="Jingrow API Secret">
<n-form-item :label="t('Jingrow API Secret')">
<n-input v-model:value="envConfig.jingrow_api_secret" type="password" show-password-on="click" />
</n-form-item>
<n-form-item label="Jingrow Session Cookie">
<n-form-item :label="t('Jingrow Session Cookie')">
<n-input v-model:value="envConfig.jingrow_session_cookie" />
</n-form-item>
</n-collapse-item>
<n-collapse-item name="cloud" :title="t('Jingrow Cloud Configuration')">
<n-form-item label="Cloud URL">
<n-form-item :label="t('Cloud URL')">
<n-input v-model:value="envConfig.jingrow_cloud_url" />
</n-form-item>
<n-form-item label="Cloud API URL">
<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="Cloud API Key">
<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="Cloud API Secret">
<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 name="database" :title="t('Database Configuration')">
<n-form-item label="DB Host">
<n-form-item :label="t('DB Host')">
<n-input v-model:value="envConfig.jingrow_db_host" />
</n-form-item>
<n-form-item label="DB Port">
<n-form-item :label="t('DB Port')">
<n-input v-model:value="envConfig.jingrow_db_port" />
</n-form-item>
<n-form-item label="DB Name">
<n-form-item :label="t('DB Name')">
<n-input v-model:value="envConfig.jingrow_db_name" />
</n-form-item>
<n-form-item label="DB User">
<n-form-item :label="t('DB User')">
<n-input v-model:value="envConfig.jingrow_db_user" />
</n-form-item>
<n-form-item label="DB Password">
<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="DB Type">
<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="qdrant" :title="t('Qdrant Configuration')">
<n-form-item label="Qdrant Host">
<n-form-item :label="t('Qdrant Host')">
<n-input v-model:value="envConfig.qdrant_host" />
</n-form-item>
<n-form-item label="Qdrant Port">
<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('Runtime Configuration')">
<n-form-item label="Run Mode">
<n-select v-model:value="envConfig.run_mode" :options="runModeOptions" style="width: 200px" />
</n-form-item>
<n-form-item label="Environment">
<n-select v-model:value="envConfig.environment" :options="environmentOptions" style="width: 200px" />
</n-form-item>
<n-form-item label="Log Level">
<n-select v-model:value="envConfig.log_level" :options="logLevelOptions" style="width: 200px" />
</n-form-item>
<n-form-item label="Backend Host">
<n-collapse-item name="backend" :title="t('Backend')">
<n-form-item :label="t('Backend Host')">
<n-input v-model:value="envConfig.backend_host" />
</n-form-item>
<n-form-item label="Backend Port">
<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="Backend Reload">
<n-form-item :label="t('Backend Reload')">
<n-switch v-model:value="envConfig.backend_reload" />
</n-form-item>
<n-form-item label="Worker Processes">
</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="Worker Threads">
<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="Watch">
<n-form-item :label="t('Watch')">
<n-switch v-model:value="envConfig.watch" />
</n-form-item>
</n-collapse-item>
</n-collapse>
<n-form-item style="margin-top: 16px">
<n-space>
<n-button type="primary" :loading="envConfigSaving" @click="saveEnvironmentConfig">
{{ t('Save Environment Configuration') }}
</n-button>
<n-button @click="loadEnvironmentConfig">
{{ t('Refresh') }}
</n-button>
</n-space>
</n-form-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>
</n-card>
</n-grid-item>
@ -196,8 +210,10 @@ import {
NCollapse,
NCollapseItem,
NSpace,
NIcon,
useMessage
} from 'naive-ui'
import { Icon } from '@iconify/vue'
import { getCurrentLocale, setLocale, locales, initLocale, t } from '../shared/i18n'
import { useAuthStore } from '../shared/stores/auth'
import { getEnvironmentConfig, updateEnvironmentConfig, type EnvironmentConfig } from '../shared/api/system'
@ -380,16 +396,89 @@ onMounted(async () => {
font-size: 28px;
font-weight: 700;
color: #1f2937;
margin: 0 0 8px 0;
}
.page-description {
font-size: 16px;
color: #6b7280;
margin: 0;
}
/* 保存按钮 - 使用柔和的品牌色系,与 pagetype 详情页保存按钮一致 */
.save-btn-brand {
background: #e6f8f0 !important;
border: 1px solid #1fc76f !important;
color: #0d684b !important;
}
.save-btn-brand :deep(.n-button__border) {
border: none !important;
border-color: transparent !important;
}
.save-btn-brand :deep(.n-button__state-border) {
border: none !important;
border-color: transparent !important;
}
.save-btn-brand:hover {
background: #dcfce7 !important;
border-color: #1fc76f !important;
border: 1px solid #1fc76f !important;
color: #166534 !important;
box-shadow: 0 2px 8px rgba(31, 199, 111, 0.15) !important;
}
.save-btn-brand:hover :deep(.n-button__border),
.save-btn-brand:hover :deep(.n-button__state-border) {
border: none !important;
border-color: transparent !important;
}
.save-btn-brand:focus {
background: #dcfce7 !important;
border-color: #1fc76f !important;
border: 1px solid #1fc76f !important;
color: #166534 !important;
box-shadow: 0 0 0 2px rgba(31, 199, 111, 0.2) !important;
}
.save-btn-brand:focus :deep(.n-button__border),
.save-btn-brand:focus :deep(.n-button__state-border) {
border: none !important;
border-color: transparent !important;
}
.save-btn-brand:active {
background: #1fc76f !important;
border-color: #1fc76f !important;
border: 1px solid #1fc76f !important;
color: white !important;
box-shadow: 0 1px 4px rgba(31, 199, 111, 0.2) !important;
}
.save-btn-brand:active :deep(.n-button__border),
.save-btn-brand:active :deep(.n-button__state-border) {
border-color: transparent !important;
}
.save-btn-brand:disabled {
background: #f1f5f9 !important;
border: 1px solid #e2e8f0 !important;
border-color: #e2e8f0 !important;
color: #94a3b8 !important;
opacity: 0.6 !important;
cursor: not-allowed !important;
}
.save-btn-brand:disabled :deep(.n-button__border),
.save-btn-brand:disabled :deep(.n-button__state-border) {
border: none !important;
border-color: transparent !important;
}
/* 响应式设计 */
@media (max-width: 1200px) {
.settings-page :deep(.n-grid) {
grid-template-columns: 1fr !important;
}
}
@media (max-width: 768px) {
.settings-page {
padding: 0 12px;