diff --git a/Release/database/XNSim.db b/Release/database/XNSim.db index e87271c..2816ca1 100644 Binary files a/Release/database/XNSim.db and b/Release/database/XNSim.db differ diff --git a/XNInterfaceGenServer/GenIDL.cpp b/XNInterfaceGenServer/GenIDL.cpp index bd5bc43..eb287d4 100644 --- a/XNInterfaceGenServer/GenIDL.cpp +++ b/XNInterfaceGenServer/GenIDL.cpp @@ -84,7 +84,8 @@ std::string GenIDL::generateIDLContent(const AllInterfaceData &interfaceData) bool GenIDL::generateIDL(const AllInterfaceData &interfaceData) { - if (GenIDL::idlFilePath.empty()) { + if (GenIDL::idlFilePath.empty() || interfaceData.systemName.empty() + || interfaceData.planeName.empty() || interfaceData.ataInterfaceData.empty()) { return false; } diff --git a/XNInterfaceGenServer/GenIDL.h b/XNInterfaceGenServer/GenIDL.h index 778e9f0..d455cde 100644 --- a/XNInterfaceGenServer/GenIDL.h +++ b/XNInterfaceGenServer/GenIDL.h @@ -27,6 +27,11 @@ public: */ static bool createConfigDirectory(const std::string &configName); + /** + * @brief 清除IDL文件路径 + */ + static void clearIDLFilePath() { idlFilePath = ""; } + private: /** * @brief 生成IDL文件内容 diff --git a/XNInterfaceGenServer/GetInterfaceData.cpp b/XNInterfaceGenServer/GetInterfaceData.cpp index cd63790..7184fa6 100644 --- a/XNInterfaceGenServer/GetInterfaceData.cpp +++ b/XNInterfaceGenServer/GetInterfaceData.cpp @@ -18,104 +18,12 @@ static int safe_stoi(const std::string &str, int defaultValue = 0) } } -/** - * @brief 回调函数,用于处理查询结果 - * @param data 用户数据指针 - * @param argc 列数 - * @param argv 列值数组 - * @param azColName 列名数组 - * @return 0表示成功 - */ -static int callback(void *data, int argc, char **argv, char **azColName) -{ - if (!data || !argv || !azColName) { - return 0; - } - auto *allData = static_cast(data); - static bool isFirstRecord = true; - std::string currentSystemName; - std::string currentPlaneName; - std::string currentATAName; - std::string currentModelStructName; - InterfaceData currentInterfaceData; - - //先把数据都读出来 - for (int i = 0; i < argc; i++) { - std::string colName = azColName[i]; - std::string value = argv[i] ? argv[i] : ""; - if (colName == "SystemName") { - currentSystemName = value; - } else if (colName == "PlaneName") { - currentPlaneName = value; - } else if (colName == "ATAName") { - currentATAName = value; - } else if (colName == "ModelStructName") { - currentModelStructName = value; - } else if (colName == "InterfaceName") { - currentInterfaceData.interfaceName = value; - } else if (colName == "InterfaceType") { - currentInterfaceData.interfaceType = value; - } else if (colName == "InterfaceIsArray") { - currentInterfaceData.interfaceIsArray = safe_stoi(value); - } else if (colName == "InterfaceArraySize_1") { - currentInterfaceData.interfaceArraySize_1 = safe_stoi(value); - } else if (colName == "InterfaceArraySize_2") { - currentInterfaceData.interfaceArraySize_2 = safe_stoi(value); - } else if (colName == "InterfaceNotes") { - currentInterfaceData.interfaceNotes = value; - } - } - - // 如果是第一条记录,初始化系统名称和飞机名称 - if (isFirstRecord) { - allData->systemName = currentSystemName; - allData->planeName = currentPlaneName; - isFirstRecord = false; - } - - // 检查系统名称和飞机名称是否匹配 - if (currentSystemName != allData->systemName || currentPlaneName != allData->planeName) { - return 0; - } - - //检查ATA是否已存在 - for (auto &ata : allData->ataInterfaceData) { - if (ata.ataName == currentATAName) { - for (auto &structData : ata.structInterfaceData) { - if (structData.modelStructName == currentModelStructName) { - for (auto &interfaceData : structData.interfaceData) { - if (interfaceData.interfaceName == currentInterfaceData.interfaceName) { - return 0; - } - } - structData.interfaceData.push_back(currentInterfaceData); - return 0; - } - } - StructInterfaceData structData; - structData.modelStructName = currentModelStructName; - structData.interfaceData.push_back(currentInterfaceData); - ata.structInterfaceData.push_back(structData); - return 0; - } - } - ATAInterfaceData ataData; - ataData.ataName = currentATAName; - StructInterfaceData structData; - structData.modelStructName = currentModelStructName; - structData.interfaceData.push_back(currentInterfaceData); - ataData.structInterfaceData.push_back(structData); - allData->ataInterfaceData.push_back(ataData); - return 0; -} - /** * @brief 从指定表中读取接口数据 * @param tableName 数据库表名 * @return 接口数据 */ -AllInterfaceData GetInterfaceData::getInterfaceData(const std::string &tableName, - std::string &errorMsg) +AllInterfaceData GetInterfaceData::getInterfaceData(int configrationID, std::string &errorMsg) { AllInterfaceData allData; std::string dbPath = GetXNCoreEnv() + "/database/XNSim.db"; @@ -126,19 +34,144 @@ AllInterfaceData GetInterfaceData::getInterfaceData(const std::string &tableName return allData; } - char *errMsg = nullptr; + std::string tableName = "DataInterface_" + std::to_string(configrationID); + std::string sql = "SELECT * FROM " + tableName; - std::string sql = "SELECT * FROM " + tableName; - - rc = sqlite3_exec(db, sql.c_str(), callback, &allData, &errMsg); + sqlite3_stmt *stmt = nullptr; + rc = sqlite3_prepare_v2(db, sql.c_str(), -1, &stmt, nullptr); if (rc != SQLITE_OK) { - std::string error = errMsg; - sqlite3_free(errMsg); - errorMsg = "SQL错误: " + error; + errorMsg = "SQL预处理失败: " + std::string(sqlite3_errmsg(db)); + sqlite3_close(db); return allData; } + while (sqlite3_step(stmt) == SQLITE_ROW) { + std::string currentSystemName; + std::string currentPlaneName; + std::string currentATAName; + std::string currentModelStructName; + InterfaceData currentInterfaceData; + int colCount = sqlite3_column_count(stmt); + for (int i = 0; i < colCount; ++i) { + const char *colName = sqlite3_column_name(stmt, i); + if (!colName) + continue; + std::string value = (const char *)sqlite3_column_text(stmt, i); + if (strcmp(colName, "SystemName") == 0) { + currentSystemName = value; + } else if (strcmp(colName, "PlaneName") == 0) { + currentPlaneName = value; + } else if (strcmp(colName, "ATAName") == 0) { + currentATAName = value; + } else if (strcmp(colName, "ModelStructName") == 0) { + currentModelStructName = value; + } else if (strcmp(colName, "InterfaceName") == 0) { + currentInterfaceData.interfaceName = value; + } else if (strcmp(colName, "InterfaceType") == 0) { + currentInterfaceData.interfaceType = value; + } else if (strcmp(colName, "InterfaceIsArray") == 0) { + currentInterfaceData.interfaceIsArray = safe_stoi(value); + } else if (strcmp(colName, "InterfaceArraySize_1") == 0) { + currentInterfaceData.interfaceArraySize_1 = safe_stoi(value); + } else if (strcmp(colName, "InterfaceArraySize_2") == 0) { + currentInterfaceData.interfaceArraySize_2 = safe_stoi(value); + } else if (strcmp(colName, "InterfaceNotes") == 0) { + currentInterfaceData.interfaceNotes = value; + } + } + // 初始化systemName和planeName + if (allData.systemName.empty()) { + allData.systemName = currentSystemName; + allData.planeName = currentPlaneName; + } + // 检查systemName和planeName是否匹配 + if (currentSystemName != allData.systemName || currentPlaneName != allData.planeName) { + continue; + } + // 检查ATA是否已存在 + bool ataFound = false; + for (auto &ata : allData.ataInterfaceData) { + if (ata.ataName == currentATAName) { + bool structFound = false; + for (auto &structData : ata.structInterfaceData) { + if (structData.modelStructName == currentModelStructName) { + bool interfaceFound = false; + for (auto &interfaceData : structData.interfaceData) { + if (interfaceData.interfaceName == currentInterfaceData.interfaceName) { + interfaceFound = true; + break; + } + } + if (!interfaceFound) { + structData.interfaceData.push_back(currentInterfaceData); + } + structFound = true; + break; + } + } + if (!structFound) { + StructInterfaceData structData; + structData.modelStructName = currentModelStructName; + structData.interfaceData.push_back(currentInterfaceData); + ata.structInterfaceData.push_back(structData); + } + ataFound = true; + break; + } + } + if (!ataFound) { + ATAInterfaceData ataData; + ataData.ataName = currentATAName; + StructInterfaceData structData; + structData.modelStructName = currentModelStructName; + structData.interfaceData.push_back(currentInterfaceData); + ataData.structInterfaceData.push_back(structData); + allData.ataInterfaceData.push_back(ataData); + } + } + + sqlite3_finalize(stmt); sqlite3_close(db); return allData; +} + +std::string GetInterfaceData::getConfigName(int configrationID, std::string &errorMsg) +{ + std::string dbPath = GetXNCoreEnv() + "/database/XNSim.db"; + sqlite3 *db = nullptr; + std::string confName; + + int rc = sqlite3_open(dbPath.c_str(), &db); + if (rc != SQLITE_OK) { + errorMsg = "无法打开数据库: " + std::string(sqlite3_errmsg(db)); + return ""; + } + + std::string sql = "SELECT ConfName FROM Configuration WHERE ConfID = ?"; + sqlite3_stmt *stmt = nullptr; + + rc = sqlite3_prepare_v2(db, sql.c_str(), -1, &stmt, nullptr); + if (rc != SQLITE_OK) { + errorMsg = "SQL预处理失败: " + std::string(sqlite3_errmsg(db)); + sqlite3_close(db); + return ""; + } + + sqlite3_bind_int(stmt, 1, configrationID); + + rc = sqlite3_step(stmt); + if (rc == SQLITE_ROW) { + const unsigned char *text = sqlite3_column_text(stmt, 0); + if (text) { + confName = reinterpret_cast(text); + } + } else if (rc != SQLITE_DONE) { + errorMsg = "SQL执行失败: " + std::string(sqlite3_errmsg(db)); + } + + sqlite3_finalize(stmt); + sqlite3_close(db); + + return confName; } \ No newline at end of file diff --git a/XNInterfaceGenServer/GetInterfaceData.h b/XNInterfaceGenServer/GetInterfaceData.h index 57a0ca8..b702927 100644 --- a/XNInterfaceGenServer/GetInterfaceData.h +++ b/XNInterfaceGenServer/GetInterfaceData.h @@ -13,5 +13,12 @@ public: * @param tableName 数据库表名 * @return 接口数据 */ - static AllInterfaceData getInterfaceData(const std::string &tableName, std::string &errorMsg); + static AllInterfaceData getInterfaceData(int configrationID, std::string &errorMsg); + + /** + * @brief 获取配置名称 + * @param configrationID 配置ID + * @return 配置名称 + */ + static std::string getConfigName(int configrationID, std::string &errorMsg); }; diff --git a/XNInterfaceGenServer/PublicDefine.cpp b/XNInterfaceGenServer/PublicDefine.cpp index 516c1f6..2449273 100644 --- a/XNInterfaceGenServer/PublicDefine.cpp +++ b/XNInterfaceGenServer/PublicDefine.cpp @@ -4,6 +4,5 @@ std::string GetXNCoreEnv() { const char *env_value = std::getenv("XNCore"); - std::cout << "XNCore: " << env_value << std::endl; return env_value ? env_value : ""; } \ No newline at end of file diff --git a/XNInterfaceGenServer/XNInterfaceGenServer.cpp b/XNInterfaceGenServer/XNInterfaceGenServer.cpp index 9e136c7..08dd689 100644 --- a/XNInterfaceGenServer/XNInterfaceGenServer.cpp +++ b/XNInterfaceGenServer/XNInterfaceGenServer.cpp @@ -6,95 +6,121 @@ #include "CMakeListsGen.h" // 全局变量定义 -std::string g_tableName; +int g_configrationID; std::string g_configName; -char *g_errorMsg; -int g_errorMsgSize; AllInterfaceData g_interfaceData; -bool XNInterfaceGen_Step1_InitParams(const char *tableName, const int tableNameSize, - const char *configName, const int configNameSize, - const char *errorMsg, const int errorMsgSize) +int XNInterfaceGen_Step1_InitParams(int configrationID, const char *errorMsg, + const int errorMsgSize) { - g_tableName = std::string(tableName, tableNameSize); - g_configName = std::string(configName, configNameSize); - g_errorMsg = const_cast(errorMsg); - g_errorMsgSize = errorMsgSize; - return true; + g_configrationID = 0; + g_configName = ""; + g_interfaceData.systemName = ""; + g_interfaceData.planeName = ""; + g_interfaceData.ataInterfaceData.clear(); + GenIDL::clearIDLFilePath(); + + if (configrationID <= 0) { + memcpy((void *)errorMsg, "Invalid configrationID", errorMsgSize); + return -1; + } + g_configrationID = configrationID; + memcpy((void *)errorMsg, "Init params success", errorMsgSize); + return 0; } -bool XNInterfaceGen_Step2_GetInterfaceData() +int XNInterfaceGen_Step2_GetInterfaceData(const char *errorMsg, const int errorMsgSize) { std::string errorMsgStr; - g_interfaceData = GetInterfaceData::getInterfaceData(g_tableName, errorMsgStr); + g_interfaceData = GetInterfaceData::getInterfaceData(g_configrationID, errorMsgStr); + g_configName = GetInterfaceData::getConfigName(g_configrationID, errorMsgStr); if (!errorMsgStr.empty()) { - memcpy(g_errorMsg, errorMsgStr.c_str(), g_errorMsgSize); - return false; + std::cout << "errorMsgStr: " << errorMsgStr << std::endl; + memcpy((void *)errorMsg, errorMsgStr.c_str(), errorMsgSize); + return -1; } - return true; + return 0; } -bool XNInterfaceGen_Step3_CreateConfigDir() +int XNInterfaceGen_Step3_CreateConfigDir(const char *errorMsg, const int errorMsgSize) { bool ret = GenIDL::createConfigDirectory(g_configName); if (!ret) { - memcpy(g_errorMsg, "Create config directory failed", g_errorMsgSize); - return false; + std::cout << "Create config directory failed" << std::endl; + memcpy((void *)errorMsg, "Create config directory failed", errorMsgSize); + return -1; } - return true; + return 0; } -bool XNInterfaceGen_Step4_GenerateIDL() +int XNInterfaceGen_Step4_GenerateIDL(const char *errorMsg, const int errorMsgSize) { bool ret = GenIDL::generateIDL(g_interfaceData); if (!ret) { - memcpy(g_errorMsg, "Generate IDL failed", g_errorMsgSize); - return false; + std::cout << "Generate IDL failed" << std::endl; + memcpy((void *)errorMsg, "Generate IDL failed", errorMsgSize); + return -1; } - return true; + return 0; } -bool XNInterfaceGen_Step5_GenerateFastDDS() +int XNInterfaceGen_Step5_GenerateFastDDS(const char *errorMsg, const int errorMsgSize) { bool ret = FastDDSGen::generateFastDDSCode(GenIDL::getIDLFilePath()); if (!ret) { - memcpy(g_errorMsg, "Generate FastDDS code failed", g_errorMsgSize); - return false; + std::cout << "Generate FastDDS code failed" << std::endl; + memcpy((void *)errorMsg, "Generate FastDDS code failed", errorMsgSize); + return -1; } - return true; + return 0; } -bool XNInterfaceGen_Step6_GenerateDDSInterface() +int XNInterfaceGen_Step6_GenerateDDSInterface(const char *errorMsg, const int errorMsgSize) { DDSInterfaceGen ddsInterfaceGen(GenIDL::getIDLFilePath()); bool ret = ddsInterfaceGen.generateDDSInterface(g_interfaceData); if (!ret) { - memcpy(g_errorMsg, "Generate DDS interface failed", g_errorMsgSize); - return false; + std::cout << "Generate DDS interface failed" << std::endl; + memcpy((void *)errorMsg, "Generate DDS interface failed", errorMsgSize); + return -1; } - return true; + return 0; } -bool XNInterfaceGen_Step7_GenerateCMakeLists() +int XNInterfaceGen_Step7_GenerateCMakeLists(const char *errorMsg, const int errorMsgSize) { bool ret = CMakeListsGen::generateCMakeLists(g_interfaceData, GenIDL::getIDLFilePath(), g_configName); if (!ret) { - memcpy(g_errorMsg, "Generate CMakeLists.txt failed", g_errorMsgSize); - return false; + std::cout << "Generate CMakeLists.txt failed" << std::endl; + memcpy((void *)errorMsg, "Generate CMakeLists.txt failed", errorMsgSize); + return -1; } - return true; + return 0; } -bool XNInterfaceGen_Step8_BuildAndInstall() +int XNInterfaceGen_Step8_BuildAndInstall(const char *errorMsg, const int errorMsgSize) { std::string idlDirPath = fs::path(GenIDL::getIDLFilePath()).parent_path().string(); std::string buildCmd = "cd " + idlDirPath + " && mkdir -p build && cd build && cmake .. && make && make install"; int buildRet = system(buildCmd.c_str()); if (buildRet != 0) { - memcpy(g_errorMsg, "CMake build or install failed", g_errorMsgSize); - return false; + std::cout << "CMake build or install failed" << std::endl; + memcpy((void *)errorMsg, "CMake build or install failed", errorMsgSize); + return -1; } - return true; + return 0; +} + +int XNInterfaceGen_Step9_SudoLdconfig(const char *errorMsg, const int errorMsgSize) +{ + std::string ldconfigCmd = "sudo ldconfig"; + int ldconfigRet = system(ldconfigCmd.c_str()); + if (ldconfigRet != 0) { + std::cout << "Sudo ldconfig failed" << std::endl; + memcpy((void *)errorMsg, "Sudo ldconfig failed", errorMsgSize); + return -1; + } + return 0; } \ No newline at end of file diff --git a/XNInterfaceGenServer/XNInterfaceGenServer.h b/XNInterfaceGenServer/XNInterfaceGenServer.h index df375b5..3867bcb 100644 --- a/XNInterfaceGenServer/XNInterfaceGenServer.h +++ b/XNInterfaceGenServer/XNInterfaceGenServer.h @@ -5,23 +5,27 @@ #include "PublicDefine.h" // 全局变量声明 -extern std::string g_tableName; +extern int g_configrationID; extern std::string g_configName; -extern char *g_errorMsg; -extern int g_errorMsgSize; extern AllInterfaceData g_interfaceData; // 步骤函数声明 -extern "C" XNIGS_EXPORT bool -XNInterfaceGen_Step1_InitParams(const char *tableName, const int tableNameSize, - const char *configName, const int configNameSize, - const char *errorMsg, const int errorMsgSize); -extern "C" XNIGS_EXPORT bool XNInterfaceGen_Step2_GetInterfaceData(); -extern "C" XNIGS_EXPORT bool XNInterfaceGen_Step3_CreateConfigDir(); -extern "C" XNIGS_EXPORT bool XNInterfaceGen_Step4_GenerateIDL(); -extern "C" XNIGS_EXPORT bool XNInterfaceGen_Step5_GenerateFastDDS(); -extern "C" XNIGS_EXPORT bool XNInterfaceGen_Step6_GenerateDDSInterface(); -extern "C" XNIGS_EXPORT bool XNInterfaceGen_Step7_GenerateCMakeLists(); -extern "C" XNIGS_EXPORT bool XNInterfaceGen_Step8_BuildAndInstall(); - +extern "C" XNIGS_EXPORT int +XNInterfaceGen_Step1_InitParams(int configrationID, const char *errorMsg, const int errorMsgSize); +extern "C" XNIGS_EXPORT int XNInterfaceGen_Step2_GetInterfaceData(const char *errorMsg, + const int errorMsgSize); +extern "C" XNIGS_EXPORT int XNInterfaceGen_Step3_CreateConfigDir(const char *errorMsg, + const int errorMsgSize); +extern "C" XNIGS_EXPORT int XNInterfaceGen_Step4_GenerateIDL(const char *errorMsg, + const int errorMsgSize); +extern "C" XNIGS_EXPORT int XNInterfaceGen_Step5_GenerateFastDDS(const char *errorMsg, + const int errorMsgSize); +extern "C" XNIGS_EXPORT int XNInterfaceGen_Step6_GenerateDDSInterface(const char *errorMsg, + const int errorMsgSize); +extern "C" XNIGS_EXPORT int XNInterfaceGen_Step7_GenerateCMakeLists(const char *errorMsg, + const int errorMsgSize); +extern "C" XNIGS_EXPORT int XNInterfaceGen_Step8_BuildAndInstall(const char *errorMsg, + const int errorMsgSize); +extern "C" XNIGS_EXPORT int XNInterfaceGen_Step9_SudoLdconfig(const char *errorMsg, + const int errorMsgSize); #endif // XN_INTERFACE_GEN_SERVER_H diff --git a/XNSimHtml/components/interface-config/toolbar.js b/XNSimHtml/components/interface-config/toolbar.js index 4c6636e..9788693 100644 --- a/XNSimHtml/components/interface-config/toolbar.js +++ b/XNSimHtml/components/interface-config/toolbar.js @@ -63,6 +63,7 @@ class InterfaceToolbar extends HTMLElement { const addBtn = this.shadowRoot.querySelector('.add-btn'); const deleteBtn = this.shadowRoot.querySelector('.delete-btn'); const importBtn = this.shadowRoot.querySelector('.import-btn'); + const codegenBtn = this.shadowRoot.querySelector('.codegen-btn'); const searchInput = this.shadowRoot.querySelector('.search-input'); const searchBtn = this.shadowRoot.querySelector('.search-btn'); const resetBtn = this.shadowRoot.querySelector('.reset-btn'); @@ -87,6 +88,85 @@ class InterfaceToolbar extends HTMLElement { importModal.style.display = 'block'; }); + codegenBtn.addEventListener('click', async () => { + // 获取当前构型ID和构型名称 + const savedSelection = localStorage.getItem('xnsim-selection'); + if (!savedSelection) { + alert('请先选择构型'); + return; + } + let selection; + try { + selection = JSON.parse(savedSelection); + } catch (e) { + alert('构型信息解析失败'); + return; + } + const configurationId = selection.configurationId; + if (!configurationId) { + alert('请先选择构型'); + return; + } + + this.showCodegenMask('准备生成代码...', 0); + + // 步骤配置 + const steps = [ + { url: '/api/interface-gen/step1', msg: '初始化接口生成参数...', body: { configID: configurationId } }, + { url: '/api/interface-gen/step2', msg: '获取接口数据...' }, + { url: '/api/interface-gen/step3', msg: '创建构型接口目录...' }, + { url: '/api/interface-gen/step4', msg: '生成IDL文件...' }, + { url: '/api/interface-gen/step5', msg: '生成FastDDS接口代码...' }, + { url: '/api/interface-gen/step6', msg: '生成DDS接口代码...' }, + { url: '/api/interface-gen/step7', msg: '生成CMakeLists文件...' }, + { url: '/api/interface-gen/step8', msg: 'CMake构建并安装...' }, + { url: '/api/interface-gen/step9', msg: '执行sudo ldconfig...' } + ]; + let success = true; + for (let i = 0; i < steps.length; i++) { + const step = steps[i]; + const percent = Math.round((i / steps.length) * 100); + this.updateCodegenProgress(step.msg, percent); + try { + let response; + if (step.body) { + response = await fetch(step.url, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(step.body) + }); + } else { + response = await fetch(step.url, { method: 'POST' }); + } + const result = await response.json(); + if (!result.success) { + this.updateCodegenProgress(`❌ ${step.msg} 失败:${result.message}`, percent); + success = false; + break; + } else { + this.updateCodegenProgress(`✅ ${step.msg} 完成`, percent + 1); + } + } catch (err) { + this.updateCodegenProgress(`❌ ${step.msg} 异常:${err.message}`, percent); + success = false; + break; + } + await new Promise(r => setTimeout(r, 400)); + } + if (success) { + this.updateCodegenProgress('🎉 代码生成全部完成!', 100); + await new Promise(r => setTimeout(r, 400)); + } + setTimeout(() => { + this.hideCodegenMask(); + if (success) { + alert('代码生成全部完成!'); + } else { + alert('代码生成失败,请检查进度提示!'); + } + }, 800); + }); + importExcelBtn.addEventListener('click', () => { const input = document.createElement('input'); input.type = 'file'; @@ -260,6 +340,15 @@ class InterfaceToolbar extends HTMLElement { background-color: #1976D2; } + .codegen-btn { + background-color: #2196F3; + color: white; + } + + .codegen-btn:hover { + background-color: #1976D2; + } + .icon-btn { padding: 6px; border: none; @@ -400,6 +489,71 @@ class InterfaceToolbar extends HTMLElement { .cancel-btn:hover { background-color: #e0e0e0; } + + .codegen-mask { + display: none; + position: fixed; + top: 0; + left: 0; + width: 100vw; + height: 100vh; + background: rgba(80,80,80,0.3); + z-index: 9999; + justify-content: center; + align-items: center; + flex-direction: column; + font-size: 22px; + color: #333; + user-select: none; + } + + .codegen-mask.show { + display: flex; + } + + .codegen-progress { + background: #fff; + border-radius: 8px; + padding: 32px 48px; + box-shadow: 0 2px 16px rgba(0,0,0,0.08); + font-size: 20px; + color: #333; + min-width: 300px; + text-align: center; + display: flex; + flex-direction: column; + align-items: center; + } + + .progress-bar-container { + width: 320px; + margin-top: 32px; + display: flex; + flex-direction: column; + align-items: center; + } + + .progress-bar-bg { + width: 100%; + height: 18px; + background: #eee; + border-radius: 9px; + overflow: hidden; + margin-bottom: 8px; + } + + .progress-bar-fill { + height: 100%; + background: linear-gradient(90deg, #2196F3 0%, #4CAF50 100%); + border-radius: 9px 0 0 9px; + transition: width 0.3s; + } + + .progress-bar-text { + font-size: 16px; + color: #2196F3; + font-weight: bold; + }
@@ -417,6 +571,10 @@ class InterfaceToolbar extends HTMLElement { 导入 导入数据 +
@@ -431,6 +589,17 @@ class InterfaceToolbar extends HTMLElement {
+
+
+
代码生成中,请稍候...
+
+
+
+
+
0%
+
+
+