#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(*itAr, "name", name)) continue; if (name == cloud.cloudName()) { if (parseValue(*itAr, "api_key", api_key) && parseValue(*itAr, "api_url", api_url) && parseValue(*itAr, "model", model) && parseValue(*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 &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(*itAr, "name", name)) continue; if (!parseValue(*itAr, "api_key", api_key)) continue; if (!parseValue(*itAr, "api_url", api_url)) continue; if (!parseValue(*itAr, "model", model)) continue; if (!parseValue(*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(*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(*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::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 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; }