Files
envi-code/SourceCode/Code2026/CoreCommand/AICloudSettingDlg.cpp
T
2026-09-28 15:28:50 +08:00

501 lines
13 KiB
C++

#include "stdafx.h"
#include "AICloudSettingDlg.h"
#include "earthwormdef.h"
#include "askaipaletteset.h"
#include "aisettingdlg.h"
using namespace SHAI;
using namespace AIJSON;
#define SHAI_CONFIG_FILE _T("\\shai.json")
namespace
{
bool readAiCloudConfig(AICloud &cloud)
{
CString sJsonPath(FilePath::GetSysDir() + SHAI_CONFIG_FILE);
if (_taccess(sJsonPath, 0x0) != 0x0) return false;
Document8 doc;
if (!file2Json(sJsonPath, doc)) return false;
CMIt8 itAiCloud = doc.FindMember("ai_cloud");
if (itAiCloud == doc.MemberEnd()) return false;
if (!itAiCloud->value.IsArray()) return false;
std::string name, api_key, api_url, model;
bool bSelect(false);
const CArr8 &ar = itAiCloud->value.GetArray();
CVIt8 itAr = ar.Begin();
for (; itAr != ar.End(); ++itAr)
{
if (!itAr->IsObject()) continue;
if (!parseValue<std::string>(*itAr, "name", name)) continue;
if (name == cloud.cloudName())
{
if (parseValue<std::string>(*itAr, "api_key", api_key)
&& parseValue<std::string>(*itAr, "api_url", api_url)
&& parseValue<std::string>(*itAr, "model", model)
&& parseValue<bool>(*itAr, "select", bSelect)
)
{
cloud.setApiKey(api_key.c_str());
cloud.setEndpoint(api_url.c_str());
cloud.setCurrentModel(model.c_str());
cloud.setCurrentSelect(bSelect);
return true;
}
}
}
return false;
}
bool readAllCloudConfig(std::vector<SHAI::AICloud*> &clouds)
{
CString sJsonPath(FilePath::GetSysDir() + SHAI_CONFIG_FILE);
if (_taccess(sJsonPath, 0x0) != 0x0) return false;
Document8 doc;
if (!file2Json(sJsonPath, doc)) return false;
CMIt8 itAiCloud = doc.FindMember("ai_cloud");
if (itAiCloud == doc.MemberEnd()) return false;
if (!itAiCloud->value.IsArray()) return false;
std::string name, api_key, api_url, model;
bool bSelect(false);
const CArr8 &ar = itAiCloud->value.GetArray();
CVIt8 itAr = ar.Begin();
for (; itAr != ar.End(); ++itAr)
{
if (!itAr->IsObject()) continue;
if (!parseValue<std::string>(*itAr, "name", name)) continue;
if (!parseValue<std::string>(*itAr, "api_key", api_key)) continue;
if (!parseValue<std::string>(*itAr, "api_url", api_url)) continue;
if (!parseValue<std::string>(*itAr, "model", model)) continue;
if (!parseValue<bool>(*itAr, "select", bSelect)) continue;
AICloud *pCloud = AICloud::createCloud(name.c_str());
if (pCloud)
{
pCloud->setCloudName(name.c_str());
pCloud->setApiKey(api_key.c_str());
pCloud->setEndpoint(api_url.c_str());
pCloud->setCurrentModel(model.c_str());
pCloud->setCurrentSelect(bSelect);
if (AICloud::IsCustomCloud(pCloud))
{
pCloud->insertModel(model.c_str());
}
clouds.push_back(pCloud);
}
}
return !clouds.empty();
}
bool writeAiCloudConfig(const AICloud &cloud)
{
CString sJsonPath(FilePath::GetSysDir() + SHAI_CONFIG_FILE);
if (_taccess(sJsonPath, 0x0) != 0x0)
{
CFile file(sJsonPath, CFile::modeCreate | CFile::modeWrite | CFile::typeBinary);
if (file.m_hFile)
{
std::string s("{}");
file.Write(s.c_str(), (UINT)(sizeof(char) * s.size()));
file.Close();
}
else
return false;
}
Document8 doc;
if (!file2Json(sJsonPath, doc)) return false;
MIt8 itCloud = doc.FindMember("ai_cloud");
if (itCloud == doc.MemberEnd())
{
Value8 vAiCloud, vItem;
vAiCloud.SetArray();
addMember(vItem, "name", cloud.cloudName().c_str());
addMember(vItem, "api_key", cloud.apiKey().c_str());
addMember(vItem, "api_url", cloud.endpoint().c_str());
addMember(vItem, "model", cloud.currentModel().c_str());
addMember(vItem, "select", cloud.currentSelect());
pushBack(vAiCloud, vItem);
addMember(doc, "ai_cloud", vAiCloud);
}
else
{
if (!itCloud->value.IsArray()) return false;
std::string name, api_key, api_url, model;
const Arr8 &ar = itCloud->value.GetArray();
VIt8 itAr = ar.Begin();
for (; itAr != ar.End(); ++itAr)
{
if (!itAr->IsObject()) continue;
if (!parseValue<std::string>(*itAr, "name", name)) continue;
if (name == cloud.cloudName())
{
if (itAr->HasMember("api_key"))
(*itAr)["api_key"].SetString(cloud.apiKey().c_str(), getJsonAllocator());
else
addMember(*itAr, "api_key", cloud.apiKey().c_str());
if (itAr->HasMember("api_url"))
(*itAr)["api_url"].SetString(cloud.endpoint().c_str(), getJsonAllocator());
else
addMember(*itAr, "api_url", cloud.endpoint().c_str());
if (itAr->HasMember("model"))
(*itAr)["model"].SetString(cloud.currentModel().c_str(), getJsonAllocator());
else
addMember(*itAr, "model", cloud.currentModel().c_str());
if (itAr->HasMember("select"))
(*itAr)["select"].SetBool(cloud.currentSelect());
else
addMember(*itAr, "select", cloud.currentSelect());
return json2File(sJsonPath, doc, true);;
}
}
// 走到这里,说明没有找到,需要添加
Value8 vItem;
addMember(vItem, "name", cloud.cloudName().c_str());
addMember(vItem, "api_key", cloud.apiKey().c_str());
addMember(vItem, "api_url", cloud.endpoint().c_str());
addMember(vItem, "model", cloud.currentModel().c_str());
addMember(vItem, "select", cloud.currentSelect());
pushBack(itCloud->value, vItem);
}
return json2File(sJsonPath, doc, true);
}
bool deleteAICloudConfig(LPCSTR cloudName)
{
CString sJsonPath(FilePath::GetSysDir() + SHAI_CONFIG_FILE);
if (_taccess(sJsonPath, 0x0) != 0x0) return false;
Document8 doc;
if (!file2Json(sJsonPath, doc)) return false;
MIt8 itCloud = doc.FindMember("ai_cloud");
if (itCloud == doc.MemberEnd()) return false;
if (!itCloud->value.IsArray()) return false;
bool bFind(false);
std::string name, api_key, api_url, model;
const Arr8 &ar = itCloud->value.GetArray();
VIt8 itAr = ar.Begin();
for (; itAr != ar.End(); ++itAr)
{
if (!itAr->IsObject()) continue;
if (!parseValue<std::string>(*itAr, "name", name)) continue;
if (name == cloudName)
{
ar.Erase(itAr);
bFind = true;
break;
}
}
if (bFind)
return json2File(sJsonPath, doc, true);
return false;
}
}
#pragma region CAICloudSettingDlg
IMPLEMENT_DYNAMIC(CAICloudSettingDlg, CDialog)
CAICloudSettingDlg::CAICloudSettingDlg(CWnd* pParent )
: CDialog(IDD_AI_CLOUD_SETTING, pParent)
, m_sApiKey(_T(""))
, m_sApiEndPoint(_T(""))
, m_bCurrent(FALSE)
, m_pCurrentCloud(NULL)
{
if (!readAllCloudConfig(m_clouds))
AfxMessageBox(_T("未找到配置文件。"));
}
CAICloudSettingDlg::~CAICloudSettingDlg()
{
for (size_t i = 0; i < m_clouds.size(); ++i)
{
if (m_clouds[i])
delete m_clouds[i];
}
m_clouds.clear();
}
void CAICloudSettingDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Text(pDX, IDC_EDIT_API_KEY, m_sApiKey);
DDX_Text(pDX, IDC_EDIT_API_URL, m_sApiEndPoint);
DDX_CBIndex(pDX, IDC_COMBO_MODEL, m_iSelectModelIdx);
DDX_Control(pDX, IDC_LIST_CLOUD, m_wndListCloud);
DDX_Check(pDX, IDC_CHECK_CURRENT, m_bCurrent);
DDX_Control(pDX, IDC_COMBO_MODEL, m_wndComboxModels);
}
BOOL CAICloudSettingDlg::OnInitDialog()
{
CDialog::OnInitDialog();
int idx(-1), iCurrent(0);
for (size_t i = 0; i < m_clouds.size(); ++i)
{
idx = m_wndListCloud.InsertString((int)i, utf2w(m_clouds[i]->cloudName()).c_str());
m_wndListCloud.SetItemData(idx, (DWORD_PTR)m_clouds[i]);
if (m_clouds[i]->currentSelect())
iCurrent = (int)i;
}
m_pCurrentCloud = m_clouds[iCurrent];
m_wndListCloud.SetCurSel(iCurrent);
m_sApiKey = utf2w(m_pCurrentCloud->apiKey()).c_str();
m_sApiEndPoint = utf2w(m_pCurrentCloud->endpoint()).c_str();
m_bCurrent = m_pCurrentCloud->currentSelect();
initModelsCombox();
UpdateData(FALSE);
return TRUE;
}
BEGIN_MESSAGE_MAP(CAICloudSettingDlg, CDialog)
ON_BN_CLICKED(IDOK, &CAICloudSettingDlg::OnBnClickedOk)
ON_BN_CLICKED(IDC_BTN_ADD, &CAICloudSettingDlg::OnBnClickedAdd)
ON_BN_CLICKED(IDC_BTN_DEL, &CAICloudSettingDlg::OnBnClickedDel)
ON_LBN_SELCHANGE(IDC_LIST_CLOUD, &CAICloudSettingDlg::OnLbnSelchangeListCloud)
ON_CBN_SELCHANGE(IDC_COMBO_MODEL, &CAICloudSettingDlg::OnCbnSelchangeComboModel)
END_MESSAGE_MAP()
void CAICloudSettingDlg::OnBnClickedOk()
{
if (!UpdateData(TRUE)) return;
saveCurrentCloud();
bool bHasCurrent(false);
for (size_t i(0); i < m_clouds.size(); ++i)
{
bHasCurrent = m_clouds[i]->currentSelect();
if (bHasCurrent)
break;
}
if (!bHasCurrent)
{
AfxMessageBox(_T("没有设置当前模型。"));
return;
}
for (size_t i(0); i < m_clouds.size(); ++i)
{
writeAiCloudConfig(*m_clouds[i]);
}
g_aiPaletteSet::instance().refreshAiCloud();
CDialog::OnOK();
}
void CAICloudSettingDlg::OnBnClickedAdd()
{
CAiSettingDlg dlg;
if (dlg.DoModal() != IDOK) return;
CustomCloud *pNew = new CustomCloud(AIJSON::w2utf(dlg.m_sName).c_str()
, AIJSON::w2utf(dlg.m_sApiKey).c_str()
, AIJSON::w2utf(dlg.m_sApiUrl).c_str());
if (std::find_if(m_clouds.begin(), m_clouds.end(), AICloud::IS_EQUAL(pNew)) != m_clouds.end())
{
AfxMessageBox(_T("配置已经存在。"));
return;
}
pNew->insertModel(AIJSON::w2utf(dlg.m_sModel).c_str());
pNew->setCurrentModel(AIJSON::w2utf(dlg.m_sModel).c_str());
m_clouds.push_back(pNew);
int idx = m_wndListCloud.InsertString(m_wndListCloud.GetCount(), utf2w(pNew->cloudName()).c_str());
if (idx != -1)
m_wndListCloud.SetItemData(idx, (DWORD_PTR)pNew);
writeAiCloudConfig(*pNew);
m_wndListCloud.SetCurSel(idx);
OnLbnSelchangeListCloud();
}
void CAICloudSettingDlg::OnBnClickedDel()
{
if (AfxMessageBox(_T("确定删除?"), MB_YESNO) != IDYES)
return;
int idx = m_wndListCloud.GetCurSel();
if (idx == -1) return;
AICloud *pCloud = (SHAI::AICloud*)m_wndListCloud.GetItemData(idx);
if (!pCloud) return;
if (!AICloud::IsCustomCloud(pCloud))
{
AfxMessageBox(_T("只可以删除自定义配置。"));
return;
}
std::vector<AICloud*>::iterator it = std::find_if(m_clouds.begin(), m_clouds.end(), AICloud::IS_EQUAL(pCloud));
if (it == m_clouds.end())
return;
m_clouds.erase(it);
deleteAICloudConfig(pCloud->cloudName().c_str());
m_wndListCloud.DeleteString(idx);
DELETE_PTR(pCloud);
int count = m_wndListCloud.GetCount();
if (count > 0)
{
m_pCurrentCloud = NULL;
m_wndListCloud.SetCurSel(0);
OnLbnSelchangeListCloud();
}
}
void CAICloudSettingDlg::OnLbnSelchangeListCloud()
{
// 保存上一个
if (m_pCurrentCloud)
{
saveCurrentCloud();
writeAiCloudConfig(*m_pCurrentCloud);
}
int idx = m_wndListCloud.GetCurSel();
m_pCurrentCloud = (SHAI::AICloud*)m_wndListCloud.GetItemData(idx);
m_sApiKey = utf2w(m_pCurrentCloud->apiKey()).c_str();
m_sApiEndPoint = utf2w(m_pCurrentCloud->endpoint()).c_str();
m_bCurrent = m_pCurrentCloud->currentSelect();
initModelsCombox();
UpdateData(FALSE);
}
void CAICloudSettingDlg::OnCbnSelchangeComboModel()
{
int idx(m_wndComboxModels.GetCurSel());
if (idx == -1) return;
CString str;
m_wndComboxModels.GetLBText(idx, str);
m_pCurrentCloud->setCurrentModel(w2utf(str).c_str());
}
void CAICloudSettingDlg::initModelsCombox()
{
m_pCurrentCloud->getModels();
m_wndComboxModels.ResetContent();
for (size_t i(0); i < m_pCurrentCloud->models().size(); i++)
{
m_wndComboxModels.AddString(utf2w(m_pCurrentCloud->models()[i]).c_str());
}
if (!m_pCurrentCloud->currentModel().empty())
{
if (m_wndComboxModels.GetCount() > 0)
{
m_iSelectModelIdx = m_wndComboxModels.FindString(0
, utf2w(m_pCurrentCloud->currentModel()).c_str());
if (m_iSelectModelIdx == -1)
m_iSelectModelIdx = 0;
}
}
else
{
if (m_wndComboxModels.GetCount() > 0)
m_iSelectModelIdx = 0;
}
}
void CAICloudSettingDlg::saveCurrentCloud()
{
if (!m_pCurrentCloud) return;
UpdateData(TRUE);
m_pCurrentCloud->setApiKey(w2utf(m_sApiKey).c_str());
m_pCurrentCloud->setEndpoint(w2utf(m_sApiEndPoint).c_str());
CString str;
m_wndComboxModels.GetWindowText(str);
m_pCurrentCloud->setCurrentModel(w2utf(str).c_str());
m_pCurrentCloud->setCurrentSelect(m_bCurrent == FALSE ? false : true);
if (m_bCurrent)
{
for (size_t i(0); i < m_clouds.size(); ++i)
{
if (m_pCurrentCloud == m_clouds[i])
continue;
m_clouds[i]->setCurrentSelect(false);
}
}
}
#pragma endregion
bool CAICloudSettingDlg::getActiveAIClouds(AICloud *&pCloud)
{
std::vector<AICloud*> clouds;
readAllCloudConfig(clouds);
if (clouds.empty()) return false;
bool bRel(false);
for (size_t i(0); i < clouds.size(); ++i)
{
AICloud *p(clouds[i]);
if (p->currentSelect())
{
pCloud = AICloud::createCloud(p->cloudName().c_str());
if (pCloud)
{
pCloud->setCloudName(p->cloudName().c_str());
pCloud->setApiKey(p->apiKey().c_str());
pCloud->setEndpoint(p->endpoint().c_str());
pCloud->setCurrentModel(p->currentModel().c_str());
pCloud->setCurrentSelect(p->currentSelect());
pCloud->setModels(p->models());
bRel = true;
}
}
DELETE_PTR(p);
}
return bRel;
}