完善设置页连接测试

This commit is contained in:
2026-05-30 03:48:42 +08:00
parent 14f1af4b05
commit 46c4f6092b
10 changed files with 485 additions and 127 deletions
+38 -101
View File
@@ -1,11 +1,9 @@
#include "PetWindow.h"
#include "../ai/ConversationManager.h"
#include "../ai/GoogleGeminiProvider.h"
#include "../ai/OpenAICompatibleProvider.h"
#include "../ai/AIProviderFactory.h"
#include "../character/CharacterPackageLoader.h"
#include "../config/ConfigManager.h"
#include "../config/SecretStore.h"
#include "../util/Logger.h"
#include "ChatBubble.h"
#include "ChatHistoryPanel.h"
@@ -62,85 +60,6 @@ AppConfig normalizedAppConfig(AppConfig config)
return config;
}
bool populateRuntimeApiKey(AIConfig &config, QString *errorMessage)
{
if (!config.apiKey.trimmed().isEmpty())
{
return true;
}
if (config.apiKeyStorage == QStringLiteral("windows-dpapi"))
{
if (config.apiKeyEncrypted.trimmed().isEmpty())
{
*errorMessage = QStringLiteral("请先在设置里配置 API Key。");
return false;
}
const SecretStore::Result result = SecretStore::unprotectText(config.apiKeyEncrypted);
if (!result.success)
{
*errorMessage = QStringLiteral("API Key 解密失败:") + result.errorMessage;
return false;
}
config.apiKey = result.value;
}
if (config.apiKey.trimmed().isEmpty())
{
*errorMessage = QStringLiteral("请先在设置里配置 API Key。");
return false;
}
return true;
}
bool prepareRuntimeAIConfig(AIConfig &config, QString *errorMessage)
{
const bool supportedProtocol = config.protocol == QStringLiteral("openai-compatible")
|| config.protocol == QStringLiteral("google-generative-language");
if (!supportedProtocol)
{
*errorMessage = QStringLiteral("当前 Provider 协议暂未接入。");
return false;
}
if (!populateRuntimeApiKey(config, errorMessage))
{
return false;
}
if (config.baseUrl.trimmed().isEmpty())
{
*errorMessage = QStringLiteral("请先在设置里配置 Base URL。");
return false;
}
if (config.model.trimmed().isEmpty())
{
*errorMessage = QStringLiteral("请先在设置里配置 Model。");
return false;
}
return true;
}
std::unique_ptr<LLMProvider> createProvider(const AIConfig &config)
{
if (config.protocol == QStringLiteral("google-generative-language"))
{
return std::make_unique<GoogleGeminiProvider>(config);
}
if (config.protocol == QStringLiteral("openai-compatible"))
{
return std::make_unique<OpenAICompatibleProvider>(config);
}
return nullptr;
}
QString userVisibleErrorMessage(const ChatResponse &response)
{
QString message = response.errorMessage.trimmed();
@@ -289,6 +208,34 @@ void PetWindow::showBubbleMessage(const QString &message)
m_chatBubble->showMessage(message, bubbleAnchorPosition());
}
void PetWindow::openSettingsDialog()
{
ConfigManager configManager;
SettingsDialog dialog(configManager.loadAIConfigStore(), currentAppConfig(), [this]() {
return isManualStateSwitchLocked();
}, this);
if (dialog.exec() != QDialog::Accepted)
{
return;
}
if (!configManager.saveAIConfigStore(dialog.aiConfigStore()))
{
Logger::warning(QStringLiteral("Failed to save AI config from settings dialog."));
}
applyAppConfig(dialog.appConfig());
if (!configManager.saveAppConfig(currentAppConfig()))
{
Logger::warning(QStringLiteral("Failed to save app config from settings dialog."));
}
}
void PetWindow::setSettingsFallbackInContextMenuEnabled(bool enabled)
{
m_settingsFallbackInContextMenuEnabled = enabled;
}
void PetWindow::contextMenuEvent(QContextMenuEvent *event)
{
resetBubbleAutoHideTimer();
@@ -307,7 +254,11 @@ void PetWindow::contextMenuEvent(QContextMenuEvent *event)
cancelAIAction->setEnabled(aiRequestRunning);
QAction *clearConversationAction = menu.addAction(QStringLiteral("清空对话"));
clearConversationAction->setEnabled(m_conversationManager && m_conversationManager->hasHistory());
QAction *settingsAction = menu.addAction(QStringLiteral("设置"));
QAction *settingsAction = nullptr;
if (m_settingsFallbackInContextMenuEnabled)
{
settingsAction = menu.addAction(QStringLiteral("设置"));
}
addStateTestActions(&menu);
@@ -335,23 +286,9 @@ void PetWindow::contextMenuEvent(QContextMenuEvent *event)
{
clearConversation();
}
else if (selectedAction == settingsAction)
else if (settingsAction != nullptr && selectedAction == settingsAction)
{
ConfigManager configManager;
SettingsDialog dialog(configManager.loadAIConfigStore(), currentAppConfig(), this);
if (dialog.exec() == QDialog::Accepted)
{
if (!configManager.saveAIConfigStore(dialog.aiConfigStore()))
{
Logger::warning(QStringLiteral("Failed to save AI config from settings dialog."));
}
applyAppConfig(dialog.appConfig());
if (!configManager.saveAppConfig(currentAppConfig()))
{
Logger::warning(QStringLiteral("Failed to save app config from settings dialog."));
}
}
openSettingsDialog();
}
else if (selectedAction == exitAction)
{
@@ -402,14 +339,14 @@ bool PetWindow::submitChatMessage(const QString &message)
ConfigManager configManager;
AIConfig config = configManager.loadAIConfig();
QString errorMessage;
if (!prepareRuntimeAIConfig(config, &errorMessage))
if (!AIProviderFactory::prepareRuntimeConfig(config, &errorMessage))
{
playState(QStringLiteral("error"), false);
showBubbleMessage(errorMessage);
return false;
}
std::unique_ptr<LLMProvider> provider = createProvider(config);
std::unique_ptr<LLMProvider> provider = AIProviderFactory::createProvider(config);
if (!provider)
{
playState(QStringLiteral("error"), false);