From 2ece96546ec80bf26013d005967cbfdc06156ee7 Mon Sep 17 00:00:00 2001
From: mrDarker <mr.darker@163.com>
Date: 星期二, 17 六月 2025 16:32:41 +0800
Subject: [PATCH] 1. 添加配方管理类(数据库) 2. 修改用户管理和系统日志管理类的路径和名称 3. 修复合并代码导致系统日志管理窗口的资源异常的问题

---
 SourceCode/Bond/Servo/Servo.vcxproj         |    2 
 SourceCode/Bond/Servo/RecipeManager.cpp     |  446 ++++++++++++++++++++++++++++++++++++++++++++
 SourceCode/Bond/Servo/Servo.vcxproj.filters |    2 
 SourceCode/Bond/Servo/resource.h            |    0 
 SourceCode/Bond/Servo/SystemLogManager.cpp  |    2 
 SourceCode/Bond/Servo/RecipeManager.h       |  103 ++++++++++
 SourceCode/Bond/Servo/Servo.cpp             |   15 +
 SourceCode/Bond/Servo/Servo.rc              |    0 
 SourceCode/Bond/Servo/UserManager.cpp       |    4 
 9 files changed, 570 insertions(+), 4 deletions(-)

diff --git a/SourceCode/Bond/Servo/RecipeManager.cpp b/SourceCode/Bond/Servo/RecipeManager.cpp
new file mode 100644
index 0000000..247cd40
--- /dev/null
+++ b/SourceCode/Bond/Servo/RecipeManager.cpp
@@ -0,0 +1,446 @@
+#include "stdafx.h"
+#include "RecipeManager.h"
+#include <sstream>
+#include <iomanip>
+#include <fstream>
+#include <iostream>
+
+std::recursive_mutex RecipeManager::m_mutex;
+
+RecipeManager& RecipeManager::getInstance() {
+    static RecipeManager instance;
+    return instance;
+}
+
+RecipeManager::RecipeManager() {
+    m_pDB = new BL::SQLiteDatabase();
+}
+
+RecipeManager::~RecipeManager() {
+    if (m_pDB) {
+        delete m_pDB;
+        m_pDB = nullptr;
+    }
+}
+
+bool RecipeManager::initRecipeTable() {
+    char szPath[MAX_PATH];
+    GetModuleFileNameA(NULL, szPath, MAX_PATH);
+    std::string exePath(szPath);
+    std::string dbDir = exePath.substr(0, exePath.find_last_of("\\/")) + "\\DB";
+    CreateDirectoryA(dbDir.c_str(), NULL);
+
+    std::string dbPath = dbDir + "\\RecipeManager.db";
+    if (!m_pDB->connect(dbPath, true)) {
+        return false;
+    }
+
+    // 启用 SQLite 的外键约束支持
+    if (!m_pDB->executeQuery("PRAGMA foreign_keys = ON;")) {
+        std::cerr << "Failed to enable foreign keys." << std::endl;
+        return false;
+    }
+
+    const std::string createRecipeTable = R"(
+        CREATE TABLE IF NOT EXISTS recipes (
+            ppid TEXT PRIMARY KEY NOT NULL,
+            description TEXT,
+            create_time TEXT DEFAULT (datetime('now', 'localtime'))
+        );
+    )";
+
+    const std::string createDeviceTable = R"(
+        CREATE TABLE IF NOT EXISTS recipe_devices (
+            id INTEGER PRIMARY KEY AUTOINCREMENT,
+            ppid TEXT NOT NULL,
+            device_id INTEGER NOT NULL,
+            device_name TEXT NOT NULL,
+            recipe_id INTEGER NOT NULL,
+            FOREIGN KEY(ppid) REFERENCES recipes(ppid) ON DELETE CASCADE,
+            UNIQUE (ppid, device_id),
+            UNIQUE (ppid, device_name)
+        );
+    )";
+
+    return m_pDB->executeQuery(createRecipeTable)
+        && m_pDB->executeQuery(createDeviceTable);
+}
+
+void RecipeManager::termRecipeTable() {
+    if (!m_pDB) {
+        return;
+    }
+
+    m_pDB->disconnect();
+}
+
+bool RecipeManager::destroyRecipeTable() {
+    if (!m_pDB) {
+		return false;
+    }
+
+    return m_pDB->executeQuery("DROP TABLE IF EXISTS recipe_devices;") && m_pDB->executeQuery("DROP TABLE IF EXISTS recipes;");
+}
+
+bool RecipeManager::ppidExists(const std::string& ppid) {
+    std::ostringstream oss;
+    oss << "SELECT COUNT(*) FROM recipes WHERE ppid = '" << ppid << "';";
+    auto result = m_pDB->fetchResults(oss.str());
+    return (!result.empty() && !result[0].empty() && result[0][0] != "0");
+}
+
+bool RecipeManager::deviceExists(const std::string& ppid, int nDeviceID) {
+    std::ostringstream oss;
+    oss << "SELECT COUNT(*) FROM recipe_devices WHERE ppid = '" << ppid
+        << "' AND device_id = " << nDeviceID << ";";
+    auto result = m_pDB->fetchResults(oss.str());
+    return (!result.empty() && !result[0].empty() && result[0][0] != "0");
+}
+
+bool RecipeManager::addRecipe(const RecipeInfo& recipe) {
+    if (!m_pDB || recipe.strPPID.empty() || recipe.vecDeviceList.empty()) {
+        std::cerr << "[AddRecipe] Invalid input." << std::endl;
+        return false;
+    }
+
+    std::string strTime = recipe.strCreateTime;
+    if (strTime.empty()) {
+        std::time_t now = std::time(nullptr);
+        std::tm tm_now = {};
+        localtime_s(&tm_now, &now);
+        std::stringstream ss;
+        ss << std::put_time(&tm_now, "%Y-%m-%d %H:%M:%S");
+        strTime = ss.str();
+    }
+
+    std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+    // 开始事务
+    m_pDB->executeQuery("BEGIN TRANSACTION;");
+
+    std::ostringstream oss;
+    oss << "INSERT OR REPLACE INTO recipes (ppid, description, create_time) VALUES ('"
+        << recipe.strPPID << "', '"
+        << recipe.strDescription << "', '"
+        << strTime << "');";
+
+    if (!m_pDB->executeQuery(oss.str())) {
+        std::cerr << "[AddRecipe] Failed to insert recipe: " << recipe.strPPID << std::endl;
+        m_pDB->executeQuery("ROLLBACK;");
+        return false;
+    }
+
+    for (const auto& device : recipe.vecDeviceList) {
+        std::ostringstream devSql;
+        devSql << "INSERT OR REPLACE INTO recipe_devices (ppid, device_id, device_name, recipe_id) VALUES ('"
+            << recipe.strPPID << "', "
+            << device.nDeviceID << ", '"
+            << device.strDeviceName << "', "
+            << device.nRecipeID << ");";
+
+        if (!m_pDB->executeQuery(devSql.str())) {
+            std::cerr << "[AddRecipe] Failed to insert device mapping: " << device.nDeviceID << std::endl;
+            m_pDB->executeQuery("ROLLBACK;");
+            return false;
+        }
+    }
+
+    // 提交事务
+    m_pDB->executeQuery("COMMIT;");
+    return true;
+}
+
+bool RecipeManager::addRecipeDevice(const std::string& ppid, const DeviceRecipe& device) {
+    if (!m_pDB || ppid.empty() || device.nDeviceID <= 0 || device.nRecipeID <= 0) {
+        std::cerr << "[addRecipeDevice] Invalid input." << std::endl;
+        return false;
+    }
+
+    // 检查 ppid 是否存在
+	if (!ppidExists(ppid)) {
+		std::cerr << "[addRecipeDevice] PPID does not exist: " << ppid << std::endl;
+		return false;
+	}
+
+    // 插入设备记录
+    std::ostringstream oss;
+    oss << "INSERT OR REPLACE INTO recipe_devices (ppid, device_id, device_name, recipe_id) VALUES ('"
+        << ppid << "', "
+        << device.nDeviceID << ", '"
+        << device.strDeviceName << "', "
+        << device.nRecipeID << ");";
+
+    std::lock_guard<std::recursive_mutex> lock(m_mutex);
+    return m_pDB->executeQuery(oss.str());
+}
+
+bool RecipeManager::deleteRecipeDeviceByID(const std::string& ppid, int nDeviceID) {
+    if (!m_pDB || ppid.empty() || nDeviceID <= 0) {
+        std::cerr << "[deleteRecipeDeviceByID] Invalid input." << std::endl;
+        return false;
+    }
+
+    std::ostringstream oss;
+    oss << "DELETE FROM recipe_devices WHERE ppid = '" << ppid << "' AND device_id = " << nDeviceID << ";";
+
+    std::lock_guard<std::recursive_mutex> lock(m_mutex);
+    return m_pDB->executeQuery(oss.str());
+}
+
+bool RecipeManager::deleteRecipeDeviceByName(const std::string& ppid, const std::string& strDeviceName) {
+    if (!m_pDB || ppid.empty() || strDeviceName.empty()) {
+        std::cerr << "[deleteRecipeDeviceByName] Invalid input." << std::endl;
+        return false;
+    }
+
+    std::ostringstream oss;
+    oss << "DELETE FROM recipe_devices WHERE ppid = '" << ppid << "' AND device_name = '" << strDeviceName << "';";
+
+    std::lock_guard<std::recursive_mutex> lock(m_mutex);
+    return m_pDB->executeQuery(oss.str());
+}
+
+std::vector<RecipeInfo> RecipeManager::getAllRecipes() {
+    if (!m_pDB) {
+        return {};
+    }
+
+    std::vector<RecipeInfo> recipes;
+    auto rows = m_pDB->fetchResults("SELECT ppid, description, create_time FROM recipes;");
+
+    for (const auto& row : rows) {
+        RecipeInfo info;
+        info.strPPID = row[0];
+        info.strDescription = row[1];
+        info.strCreateTime = row[2];
+
+        std::ostringstream devQuery;
+        devQuery << "SELECT device_id, device_name, recipe_id FROM recipe_devices WHERE ppid = '" << info.strPPID << "';";
+        auto devs = m_pDB->fetchResults(devQuery.str());
+
+        for (const auto& dev : devs) {
+            DeviceRecipe dr;
+            dr.strPPID = info.strPPID;
+            try {
+                dr.nDeviceID = std::stoi(dev[0]);
+                dr.strDeviceName = dev[1];
+                dr.nRecipeID = std::stoi(dev[2]);
+            }
+            catch (...) {
+                std::cerr << "Invalid data in recipe_devices for PPID: " << info.strPPID << std::endl;
+                continue;
+            }
+            info.vecDeviceList.push_back(dr);
+        }
+        recipes.push_back(info);
+    }
+
+    return recipes;
+}
+
+RecipeInfo RecipeManager::getRecipeByPPID(const std::string& ppid) {
+    RecipeInfo info;
+    auto rows = m_pDB->fetchResults("SELECT ppid, description, create_time FROM recipes WHERE ppid = '" + ppid + "';");
+    if (rows.empty()) {
+        return info;
+    }
+
+    info.strPPID = rows[0][0];
+    info.strDescription = rows[0][1];
+    info.strCreateTime = rows[0][2];
+
+    auto devs = m_pDB->fetchResults("SELECT device_id, device_name, recipe_id FROM recipe_devices WHERE ppid = '" + ppid + "';");
+    for (const auto& dev : devs) {
+        DeviceRecipe dr;
+        dr.strPPID = ppid;
+        try {
+            dr.nDeviceID = std::stoi(dev[0]);
+            dr.strDeviceName = dev[1];
+            dr.nRecipeID = std::stoi(dev[2]);
+        }
+        catch (...) {
+            std::cerr << "Invalid data in recipe_devices for PPID: " << ppid << std::endl;
+            continue;
+        }
+        info.vecDeviceList.push_back(dr);
+    }
+    return info;
+}
+
+int RecipeManager::getDeviceRecipeIDByID(const std::string& ppid, int nDeviceID) {
+    if (!m_pDB || ppid.empty() || nDeviceID <= 0) {
+        return -1;
+    }
+
+    std::ostringstream query;
+    query << "SELECT recipe_id FROM recipe_devices WHERE ppid = '" << ppid << "' AND device_id = " << nDeviceID << ";";
+
+    auto result = m_pDB->fetchResults(query.str());
+    if (!result.empty() && !result[0].empty()) {
+        try {
+            return std::stoi(result[0][0]);
+        }
+        catch (...) {
+            return -1;
+        }
+    }
+    return -1;
+}
+
+int RecipeManager::getDeviceRecipeIDByName(const std::string& ppid, const std::string& strDeviceName) {
+    if (!m_pDB || ppid.empty() || strDeviceName.empty()) {
+        return -1;
+    }
+
+    std::ostringstream query;
+    query << "SELECT recipe_id FROM recipe_devices WHERE ppid = '" << ppid << "' AND device_name = '" << strDeviceName << "';";
+
+    auto result = m_pDB->fetchResults(query.str());
+    if (!result.empty() && !result[0].empty()) {
+        try {
+            return std::stoi(result[0][0]);
+        }
+        catch (...) {
+            return -1;
+        }
+    }
+    return -1;
+}
+
+bool RecipeManager::deleteRecipeByPPID(const std::string& ppid) {
+    if (!m_pDB) {
+        return false;
+    }
+
+    std::lock_guard<std::recursive_mutex> lock(m_mutex);
+    return m_pDB->executeQuery("DELETE FROM recipes WHERE ppid = '" + ppid + "';");
+}
+
+bool RecipeManager::updateRecipe(const RecipeInfo& recipe) {
+    if (!m_pDB) {
+        return false;
+    }
+
+	if (recipe.strPPID.empty()) {
+		std::cerr << "Recipe PPID cannot be empty." << std::endl;
+		return false;
+	}
+
+    std::lock_guard<std::recursive_mutex> lock(m_mutex);
+    deleteRecipeByPPID(recipe.strPPID);
+    return addRecipe(recipe);
+}
+
+bool RecipeManager::updateDeviceRecipeIDByID(const std::string& ppid, int nDeviceID, int nNewRecipeID) {
+	if (!m_pDB || ppid.empty() || nDeviceID <= 0 || nNewRecipeID <= 0) {
+		return false;
+	}
+
+	std::ostringstream query;
+    std::lock_guard<std::recursive_mutex> lock(m_mutex);
+	query << "UPDATE recipe_devices SET recipe_id = " << nNewRecipeID
+		<< " WHERE ppid = '" << ppid << "' AND device_id = " << nDeviceID << ";";
+	return m_pDB->executeQuery(query.str());
+}
+
+bool RecipeManager::updateDeviceRecipeIDByName(const std::string& ppid, const std::string& strDeviceName, int nNewRecipeID) {
+	if (!m_pDB || ppid.empty() || strDeviceName.empty() || nNewRecipeID <= 0) {
+		return false;
+	}
+	std::ostringstream query;
+    std::lock_guard<std::recursive_mutex> lock(m_mutex);
+	query << "UPDATE recipe_devices SET recipe_id = " << nNewRecipeID
+		<< " WHERE ppid = '" << ppid << "' AND device_name = '" << strDeviceName << "';";
+	return m_pDB->executeQuery(query.str());
+}
+
+void RecipeManager::insertMockData() {
+    if (!m_pDB) {
+        return;
+    }
+
+    RecipeInfo recipe;
+    recipe.strPPID = "P1001";
+    recipe.strDescription = "Main Board Burn-in";
+
+    recipe.vecDeviceList = {
+        {1, 101, "P1001","Burner A"},
+        {2, 102, "P1001", "Burner B"}
+    };
+
+    addRecipe(recipe);
+}
+
+bool RecipeManager::readRecipeFile(const std::string& filename) {
+    if (!m_pDB) {
+        return false;
+    }
+
+    std::ifstream file(filename);
+    if (!file.is_open()) {
+        return false;
+    }
+
+    std::unordered_map<std::string, RecipeInfo> recipeMap;
+    std::string line;
+    std::getline(file, line); // skip header
+
+    while (std::getline(file, line)) {
+        std::stringstream ss(line);
+        std::string cell;
+        std::string ppid, description, createTime;
+        DeviceRecipe dev;
+
+        std::getline(ss, ppid, ',');
+        std::getline(ss, cell, ',');
+        try { dev.nDeviceID = std::stoi(cell); }
+        catch (...) { continue; }
+        std::getline(ss, dev.strDeviceName, ',');
+        std::getline(ss, cell, ',');
+        try { dev.nRecipeID = std::stoi(cell); }
+        catch (...) { continue; }
+        std::getline(ss, description, ',');
+        std::getline(ss, createTime, ',');
+
+        dev.strPPID = ppid;
+        auto& recipe = recipeMap[ppid];
+        recipe.strPPID = ppid;
+        recipe.strDescription = description;
+        recipe.strCreateTime = createTime;
+        recipe.vecDeviceList.push_back(dev);
+    }
+
+    for (const auto& pair : recipeMap) {
+        if (!updateRecipe(pair.second)) {
+            std::cerr << "Failed to update recipe from file: " << pair.first << std::endl;
+        }
+    }
+
+    return true;
+}
+
+bool RecipeManager::saveRecipeFile(const std::string& filename) {
+    if (!m_pDB) {
+        return false;
+    }
+
+    std::ofstream file(filename);
+    if (!file.is_open()) {
+        return false;
+    }
+
+    file << "PPID,DeviceID,DeviceName,RecipeID,Description,CreateTime\n";
+    auto recipes = getAllRecipes();
+    for (const auto& recipe : recipes) {
+        for (const auto& dev : recipe.vecDeviceList) {
+            file << recipe.strPPID << ","
+                << dev.nDeviceID << ","
+                << dev.strDeviceName << ","
+                << dev.nRecipeID << ","
+                << recipe.strDescription << ","
+                << recipe.strCreateTime << "\n";
+        }
+    }
+
+    return true;
+}
\ No newline at end of file
diff --git a/SourceCode/Bond/Servo/RecipeManager.h b/SourceCode/Bond/Servo/RecipeManager.h
new file mode 100644
index 0000000..b5aceaa
--- /dev/null
+++ b/SourceCode/Bond/Servo/RecipeManager.h
@@ -0,0 +1,103 @@
+#ifndef RECIPE_MANAGER_H
+#define RECIPE_MANAGER_H
+
+#include <string>
+#include <vector>
+#include <mutex>
+#include <unordered_map>
+#include "Database.h"
+
+// 单个设备配方映射信息
+struct DeviceRecipe {
+    int nDeviceID;               // 设备ID
+    int nRecipeID;               // 该设备对应的子配方ID
+    std::string strPPID;         // 配方ID(主键)
+    std::string strDeviceName;   // 设备名称 
+};
+
+// 配方信息
+struct RecipeInfo {
+    std::string strPPID;         // 配方ID
+    std::string strDescription;  // 配方描述
+    std::string strCreateTime;   // 创建时间
+    std::vector<DeviceRecipe> vecDeviceList;  // 关联的设备信息列表
+};
+
+using RecipeMap = std::unordered_map<std::string, RecipeInfo>; // 按 PPID 映射的配方表
+
+class RecipeManager {
+public:
+    // 获取单例
+    static RecipeManager& getInstance();
+
+    // 初始化配方数据库
+    bool initRecipeTable();
+
+    // 销毁表或关闭连接
+    void termRecipeTable();
+    bool destroyRecipeTable();
+
+	// 检查 PPID 是否存在
+    bool ppidExists(const std::string& ppid);
+
+	// 检查设备是否存在于指定 PPID 的配方中
+	bool deviceExists(const std::string& ppid, int nDeviceID);
+
+    // 添加一个配方及其设备映射
+    bool addRecipe(const RecipeInfo& recipe);
+
+	// 添加设备到指定配方
+    bool addRecipeDevice(const std::string& ppid, const DeviceRecipe& device);
+
+	// 删除指定 PPID 的设备配方
+    bool deleteRecipeDeviceByID(const std::string& ppid, int nDeviceID);
+
+	// 删除指定 PPID 的设备配方(通过设备名称)
+    bool deleteRecipeDeviceByName(const std::string& ppid, const std::string& strDeviceName);
+
+    // 查询所有配方
+    std::vector<RecipeInfo> getAllRecipes();
+
+    // 按 PPID 查询配方
+    RecipeInfo getRecipeByPPID(const std::string& ppid);
+
+    // 根据 PPID 和设备ID 获取设备配方ID
+    int getDeviceRecipeIDByID(const std::string& ppid, int nDeviceID);
+
+    // 根据 PPID 和设备名称 获取设备配方ID
+    int getDeviceRecipeIDByName(const std::string& ppid, const std::string& strDeviceName);
+
+    // 删除指定 PPID 的配方
+    bool deleteRecipeByPPID(const std::string& ppid);
+
+    // 更新指定 PPID 的配方
+    bool updateRecipe(const RecipeInfo& recipe);
+
+	// 更新设备配方ID(通过 PPID 和设备ID)
+    bool updateDeviceRecipeIDByID(const std::string& ppid, int nDeviceID, int nNewRecipeID);
+
+	// 更新设备配方ID(通过 PPID 和设备名称)
+    bool updateDeviceRecipeIDByName(const std::string& ppid, const std::string& strDeviceName, int nNewRecipeID);
+
+    // 模拟插入数据(测试用)
+    void insertMockData();
+
+    // 读取配方文件(CSV 或 JSON)
+    bool readRecipeFile(const std::string& filename);
+
+    // 保存配方到文件
+    bool saveRecipeFile(const std::string& filename);
+
+private:
+    RecipeManager();
+    ~RecipeManager();
+
+    RecipeManager(const RecipeManager&) = delete;
+    RecipeManager& operator=(const RecipeManager&) = delete;
+
+private:
+    BL::Database* m_pDB;
+    static std::recursive_mutex m_mutex;
+};
+
+#endif // RECIPE_MANAGER_H
\ No newline at end of file
diff --git a/SourceCode/Bond/Servo/Servo.cpp b/SourceCode/Bond/Servo/Servo.cpp
index 74298c4..71f2ed2 100644
--- a/SourceCode/Bond/Servo/Servo.cpp
+++ b/SourceCode/Bond/Servo/Servo.cpp
@@ -11,6 +11,7 @@
 #include "TransferManager.h"
 #include "SystemLogManager.h"
 #include "UserManager.h"
+#include "RecipeManager.h"
 #include "VerticalLine.h"
 #include "HorizontalLine.h"
 #include "EqsGraphWnd.h"
@@ -134,7 +135,6 @@
 		AfxMessageBox(errorMsg, MB_ICONERROR);
 		return FALSE;
 	}
-	AlarmManager::getInstance().insertMockData();
 
 	// 初始化SECS运行设置管理库
 	try {
@@ -194,6 +194,19 @@
 		return FALSE;
 	}
 
+	// 初始化配方管理库
+	try {
+		if (!RecipeManager::getInstance().initRecipeTable()) {
+			AfxMessageBox("初始化配方管理库失败!");
+			return FALSE;
+		}
+	}
+	catch (const std::exception& ex) {
+		CString errorMsg;
+		errorMsg.Format(_T("初始化配方管理库失败:%s"), CString(ex.what()));
+		AfxMessageBox(errorMsg, MB_ICONERROR);
+		return FALSE;
+	}
 
 
 	CServoDlg dlg;
diff --git a/SourceCode/Bond/Servo/Servo.rc b/SourceCode/Bond/Servo/Servo.rc
index b72754b..22445c9 100644
--- a/SourceCode/Bond/Servo/Servo.rc
+++ b/SourceCode/Bond/Servo/Servo.rc
Binary files differ
diff --git a/SourceCode/Bond/Servo/Servo.vcxproj b/SourceCode/Bond/Servo/Servo.vcxproj
index ec5ba3d..30dacba 100644
--- a/SourceCode/Bond/Servo/Servo.vcxproj
+++ b/SourceCode/Bond/Servo/Servo.vcxproj
@@ -317,6 +317,7 @@
     <ClInclude Include="PageTransferLog.h" />
     <ClInclude Include="PortConfigurationDlg.h" />
     <ClInclude Include="ProductionLogManager.h" />
+    <ClInclude Include="RecipeManager.h" />
     <ClInclude Include="Resource.h" />
     <ClInclude Include="SECSRuntimeManager.h" />
     <ClInclude Include="SecsTestDlg.h" />
@@ -454,6 +455,7 @@
     <ClCompile Include="PageTransferLog.cpp" />
     <ClCompile Include="PortConfigurationDlg.cpp" />
     <ClCompile Include="ProductionLogManager.cpp" />
+    <ClCompile Include="RecipeManager.cpp" />
     <ClCompile Include="SECSRuntimeManager.cpp" />
     <ClCompile Include="SecsTestDlg.cpp" />
     <ClCompile Include="Servo.cpp" />
diff --git a/SourceCode/Bond/Servo/Servo.vcxproj.filters b/SourceCode/Bond/Servo/Servo.vcxproj.filters
index 0293739..76458e6 100644
--- a/SourceCode/Bond/Servo/Servo.vcxproj.filters
+++ b/SourceCode/Bond/Servo/Servo.vcxproj.filters
@@ -167,6 +167,7 @@
     <ClCompile Include="SystemLogManager.cpp" />
     <ClCompile Include="UserManager.cpp" />
     <ClCompile Include="InputDialog.cpp" />
+    <ClCompile Include="RecipeManager.cpp" />
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="AlarmManager.h" />
@@ -339,6 +340,7 @@
     <ClInclude Include="UserManager.h" />
     <ClInclude Include="SystemLogManager.h" />
     <ClInclude Include="InputDialog.h" />
+    <ClInclude Include="RecipeManager.h" />
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="Servo.rc" />
diff --git a/SourceCode/Bond/Servo/SystemLogManager.cpp b/SourceCode/Bond/Servo/SystemLogManager.cpp
index 87a324c..7289fb6 100644
--- a/SourceCode/Bond/Servo/SystemLogManager.cpp
+++ b/SourceCode/Bond/Servo/SystemLogManager.cpp
@@ -42,7 +42,7 @@
     }
 
     // 构造数据库路径
-    std::string dbPath = dbDir + "\\SystemLog.db";
+    std::string dbPath = dbDir + "\\SystemLogManager.db";
 
     // 连接数据库
     if (!m_pDB->connect(dbPath, true)) {
diff --git a/SourceCode/Bond/Servo/UserManager.cpp b/SourceCode/Bond/Servo/UserManager.cpp
index cceff0c..1e6d5f8 100644
--- a/SourceCode/Bond/Servo/UserManager.cpp
+++ b/SourceCode/Bond/Servo/UserManager.cpp
@@ -7,7 +7,7 @@
 #include <sstream>
 
 const std::string SESSION_FILE = R"(session.dat)";
-const std::string DATABASE_FILE = R"(BondEq.db)";
+const std::string DATABASE_FILE = R"(UserManager.db)";
 
 const std::string INITIAL_ADMIN_USERNAME = "admin";
 const std::string INITIAL_ADMIN_PASSWORD = "admin";
@@ -160,7 +160,7 @@
     char szPath[MAX_PATH];
     GetModuleFileName(NULL, szPath, MAX_PATH);
     std::string exePath(szPath);
-    std::string dbDir = exePath.substr(0, exePath.find_last_of("\\/")) + "\\DB";
+    std::string dbDir = exePath.substr(0, exePath.find_last_of("\\/")) + "\\DB\\";
 
     // 检查并创建config文件夹
     DWORD fileAttr = GetFileAttributes(dbDir.c_str());
diff --git a/SourceCode/Bond/Servo/resource.h b/SourceCode/Bond/Servo/resource.h
index 6ddfdd1..2108414 100644
--- a/SourceCode/Bond/Servo/resource.h
+++ b/SourceCode/Bond/Servo/resource.h
Binary files differ

--
Gitblit v1.9.3