优化认证检查逻辑,确保加载状态显示在正确位置;更新配置验证逻辑,使用深拷贝确保数据完整性
This commit is contained in:
@@ -94,15 +94,6 @@ export function Layout({ children }: LayoutProps) {
|
|||||||
return unsubscribe
|
return unsubscribe
|
||||||
}, [router, announce, t])
|
}, [router, announce, t])
|
||||||
|
|
||||||
// 认证检查中,显示加载状态
|
|
||||||
if (checking) {
|
|
||||||
return (
|
|
||||||
<div className="flex h-screen items-center justify-center bg-background">
|
|
||||||
<div className="text-muted-foreground">{t('layout.verifyingLogin')}</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取实际应用的主题(处理 system 情况)
|
// 获取实际应用的主题(处理 system 情况)
|
||||||
const getActualTheme = () => {
|
const getActualTheme = () => {
|
||||||
if (theme === 'system') {
|
if (theme === 'system') {
|
||||||
@@ -114,6 +105,15 @@ export function Layout({ children }: LayoutProps) {
|
|||||||
const actualTheme = getActualTheme()
|
const actualTheme = getActualTheme()
|
||||||
const pageBg = useBackground('page')
|
const pageBg = useBackground('page')
|
||||||
|
|
||||||
|
// 认证检查中,显示加载状态
|
||||||
|
if (checking) {
|
||||||
|
return (
|
||||||
|
<div className="flex h-screen items-center justify-center bg-background">
|
||||||
|
<div className="text-muted-foreground">{t('layout.verifyingLogin')}</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TooltipProvider delayDuration={300}>
|
<TooltipProvider delayDuration={300}>
|
||||||
<SkipNav />
|
<SkipNav />
|
||||||
|
|||||||
@@ -189,8 +189,8 @@ function BotConfigPageContent() {
|
|||||||
setBotConfig(config.bot as BotConfig)
|
setBotConfig(config.bot as BotConfig)
|
||||||
setPersonalityConfig(config.personality as PersonalityConfig)
|
setPersonalityConfig(config.personality as PersonalityConfig)
|
||||||
|
|
||||||
// 确保 talk_value_rules 有默认值
|
// 确保 chat 配置和 talk_value_rules 有默认值
|
||||||
const chatConfigData = config.chat as ChatConfig
|
const chatConfigData = (config.chat ?? {}) as ChatConfig
|
||||||
if (!chatConfigData.talk_value_rules) {
|
if (!chatConfigData.talk_value_rules) {
|
||||||
chatConfigData.talk_value_rules = []
|
chatConfigData.talk_value_rules = []
|
||||||
}
|
}
|
||||||
@@ -265,7 +265,7 @@ function BotConfigPageContent() {
|
|||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const raw = result.data
|
const raw = (result.data as unknown as Record<string, unknown>).content as string
|
||||||
// 将 TOML 基本字符串中的转义序列转换为实际字符以便在编辑器中正确显示
|
// 将 TOML 基本字符串中的转义序列转换为实际字符以便在编辑器中正确显示
|
||||||
// 使用正则表达式只处理双引号字符串内的转义序列,不影响单引号字符串
|
// 使用正则表达式只处理双引号字符串内的转义序列,不影响单引号字符串
|
||||||
const unescaped = raw.replace(/"([^"]*)"/g, (_match, content) => {
|
const unescaped = raw.replace(/"([^"]*)"/g, (_match, content) => {
|
||||||
@@ -302,7 +302,7 @@ function BotConfigPageContent() {
|
|||||||
setLoading(false)
|
setLoading(false)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
parseAndSetConfig(result.data)
|
parseAndSetConfig((result.data as Record<string, unknown>).config as Record<string, unknown>)
|
||||||
setHasUnsavedChanges(false)
|
setHasUnsavedChanges(false)
|
||||||
initialLoadRef.current = false
|
initialLoadRef.current = false
|
||||||
|
|
||||||
@@ -455,7 +455,7 @@ function BotConfigPageContent() {
|
|||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
parseAndSetConfig(result.data)
|
parseAndSetConfig((result.data as Record<string, unknown>).config as Record<string, unknown>)
|
||||||
setHasUnsavedChanges(false)
|
setHasUnsavedChanges(false)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('加载配置失败:', error)
|
console.error('加载配置失败:', error)
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
配置管理API路由
|
配置管理API路由
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import copy
|
||||||
import os
|
import os
|
||||||
import tomlkit
|
import tomlkit
|
||||||
from fastapi import APIRouter, HTTPException, Body, Depends, Cookie, Header
|
from fastapi import APIRouter, HTTPException, Body, Depends, Cookie, Header
|
||||||
@@ -11,6 +12,7 @@ from src.common.logger import get_logger
|
|||||||
from src.webui.core import verify_auth_token_from_cookie_or_header
|
from src.webui.core import verify_auth_token_from_cookie_or_header
|
||||||
from src.webui.utils.toml_utils import save_toml_with_format, _update_toml_doc
|
from src.webui.utils.toml_utils import save_toml_with_format, _update_toml_doc
|
||||||
from src.config.config import Config, ModelConfig, CONFIG_DIR, PROJECT_ROOT
|
from src.config.config import Config, ModelConfig, CONFIG_DIR, PROJECT_ROOT
|
||||||
|
from src.config.config_base import AttributeData
|
||||||
from src.config.official_configs import (
|
from src.config.official_configs import (
|
||||||
BotConfig,
|
BotConfig,
|
||||||
PersonalityConfig,
|
PersonalityConfig,
|
||||||
@@ -204,7 +206,7 @@ async def update_bot_config(config_data: ConfigBody, _auth: bool = Depends(requi
|
|||||||
try:
|
try:
|
||||||
# 验证配置数据
|
# 验证配置数据
|
||||||
try:
|
try:
|
||||||
Config.from_dict(config_data)
|
Config.from_dict(AttributeData(), copy.deepcopy(config_data))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise HTTPException(status_code=400, detail=f"配置数据验证失败: {str(e)}") from e
|
raise HTTPException(status_code=400, detail=f"配置数据验证失败: {str(e)}") from e
|
||||||
|
|
||||||
@@ -227,7 +229,7 @@ async def update_model_config(config_data: ConfigBody, _auth: bool = Depends(req
|
|||||||
try:
|
try:
|
||||||
# 验证配置数据
|
# 验证配置数据
|
||||||
try:
|
try:
|
||||||
ModelConfig.from_dict(config_data)
|
ModelConfig.from_dict(AttributeData(), copy.deepcopy(config_data))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise HTTPException(status_code=400, detail=f"配置数据验证失败: {str(e)}") from e
|
raise HTTPException(status_code=400, detail=f"配置数据验证失败: {str(e)}") from e
|
||||||
|
|
||||||
@@ -277,7 +279,7 @@ async def update_bot_config_section(section_name: str, section_data: SectionBody
|
|||||||
|
|
||||||
# 验证完整配置
|
# 验证完整配置
|
||||||
try:
|
try:
|
||||||
Config.from_dict(config_data)
|
Config.from_dict(AttributeData(), copy.deepcopy(dict(config_data)))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise HTTPException(status_code=400, detail=f"配置数据验证失败: {str(e)}") from e
|
raise HTTPException(status_code=400, detail=f"配置数据验证失败: {str(e)}") from e
|
||||||
|
|
||||||
@@ -327,7 +329,7 @@ async def update_bot_config_raw(raw_content: RawContentBody, _auth: bool = Depen
|
|||||||
|
|
||||||
# 验证配置数据结构
|
# 验证配置数据结构
|
||||||
try:
|
try:
|
||||||
Config.from_dict(config_data)
|
Config.from_dict(AttributeData(), copy.deepcopy(dict(config_data)))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise HTTPException(status_code=400, detail=f"配置数据验证失败: {str(e)}") from e
|
raise HTTPException(status_code=400, detail=f"配置数据验证失败: {str(e)}") from e
|
||||||
|
|
||||||
@@ -377,7 +379,7 @@ async def update_model_config_section(
|
|||||||
|
|
||||||
# 验证完整配置
|
# 验证完整配置
|
||||||
try:
|
try:
|
||||||
ModelConfig.from_dict(config_data)
|
ModelConfig.from_dict(AttributeData(), copy.deepcopy(dict(config_data)))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"配置数据验证失败,详细错误: {str(e)}")
|
logger.error(f"配置数据验证失败,详细错误: {str(e)}")
|
||||||
# 特殊处理:如果是更新 api_providers,检查是否有模型引用了已删除的provider
|
# 特殊处理:如果是更新 api_providers,检查是否有模型引用了已删除的provider
|
||||||
|
|||||||
Reference in New Issue
Block a user