From 549decf91ef988814913cddc86f5c4e006b277e7 Mon Sep 17 00:00:00 2001
From: LAPTOP-SNT8I5JK\Boounion <Chenluhua@qq.com>
Date: 星期四, 21 八月 2025 05:27:48 +0800
Subject: [PATCH] Merge branch 'clh' of http://soft.boounion.cn/r/~chenluhua/Bond2 into clh

---
 SourceCode/Bond/Servo/RecipeManager.cpp |   93 +++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 87 insertions(+), 6 deletions(-)

diff --git a/SourceCode/Bond/Servo/RecipeManager.cpp b/SourceCode/Bond/Servo/RecipeManager.cpp
index 247cd40..e0a186b 100644
--- a/SourceCode/Bond/Servo/RecipeManager.cpp
+++ b/SourceCode/Bond/Servo/RecipeManager.cpp
@@ -56,7 +56,7 @@
             device_id INTEGER NOT NULL,
             device_name TEXT NOT NULL,
             recipe_id INTEGER NOT NULL,
-            FOREIGN KEY(ppid) REFERENCES recipes(ppid) ON DELETE CASCADE,
+            FOREIGN KEY(ppid) REFERENCES recipes(ppid) ON DELETE CASCADE ON UPDATE CASCADE,
             UNIQUE (ppid, device_id),
             UNIQUE (ppid, device_name)
         );
@@ -220,7 +220,6 @@
 
         for (const auto& dev : devs) {
             DeviceRecipe dr;
-            dr.strPPID = info.strPPID;
             try {
                 dr.nDeviceID = std::stoi(dev[0]);
                 dr.strDeviceName = dev[1];
@@ -238,6 +237,48 @@
     return recipes;
 }
 
+std::vector<RecipeInfo> RecipeManager::getRecipesByKeyword(const std::string& keyword) {
+    std::vector<RecipeInfo> recipes;
+    if (!m_pDB || keyword.empty()) {
+        return recipes;
+    }
+
+    std::ostringstream query;
+    query << "SELECT ppid, description, create_time FROM recipes "
+        << "WHERE ppid LIKE '%" << keyword << "%' OR description LIKE '%" << keyword << "%';";
+
+    auto rows = m_pDB->fetchResults(query.str());
+    for (const auto& row : rows) {
+        if (row.size() >= 3) {
+            RecipeInfo info;
+            info.strPPID = row[0];
+            info.strDescription = row[1];
+            info.strCreateTime = row[2];
+            recipes.push_back(info);
+        }
+    }
+    return recipes;
+}
+
+std::vector<std::string> RecipeManager::getAllPPID() const {
+    std::vector<std::string> vecPPID;
+
+    if (!m_pDB) {
+        return vecPPID;
+    }
+
+    const std::string query = "SELECT ppid FROM recipes ORDER BY ppid;";
+    auto result = m_pDB->fetchResults(query);
+
+    for (const auto& row : result) {
+        if (!row.empty()) {
+            vecPPID.push_back(row[0]);
+        }
+    }
+
+    return vecPPID;
+}
+
 RecipeInfo RecipeManager::getRecipeByPPID(const std::string& ppid) {
     RecipeInfo info;
     auto rows = m_pDB->fetchResults("SELECT ppid, description, create_time FROM recipes WHERE ppid = '" + ppid + "';");
@@ -252,7 +293,6 @@
     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];
@@ -331,6 +371,48 @@
     return addRecipe(recipe);
 }
 
+bool RecipeManager::updatePPID(const std::string& oldPPID, const std::string& newPPID) {
+    if (!m_pDB || oldPPID.empty() || newPPID.empty()) {
+        std::cerr << "[updatePPID] Invalid input." << std::endl;
+        return false;
+    }
+
+    std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+    // 检查是否已经存在相同的 newPPID
+    auto check = m_pDB->fetchResults("SELECT COUNT(*) FROM recipes WHERE ppid = '" + newPPID + "';");
+    if (!check.empty() && !check[0].empty() && check[0][0] != "0") {
+        std::cerr << "[updatePPID] New PPID already exists: " << newPPID << std::endl;
+        return false;
+    }
+
+    m_pDB->executeQuery("BEGIN TRANSACTION;");
+
+    std::ostringstream sql;
+    sql << "UPDATE recipes SET ppid = '" << newPPID << "' WHERE ppid = '" << oldPPID << "';";
+    if (!m_pDB->executeQuery(sql.str())) {
+        std::cerr << "[updatePPID] Failed to update recipes table." << std::endl;
+        m_pDB->executeQuery("ROLLBACK;");
+        return false;
+    }
+
+    m_pDB->executeQuery("COMMIT;");
+    return true;
+}
+
+bool RecipeManager::updateDescription(const std::string& ppid, const std::string& newDescription) {
+    if (!m_pDB || ppid.empty()) {
+        std::cerr << "[updateRecipeDescription] Invalid input." << std::endl;
+        return false;
+    }
+
+    std::ostringstream oss;
+    oss << "UPDATE recipes SET description = '" << newDescription << "' WHERE ppid = '" << ppid << "';";
+
+    std::lock_guard<std::recursive_mutex> lock(m_mutex);
+    return m_pDB->executeQuery(oss.str());
+}
+
 bool RecipeManager::updateDeviceRecipeIDByID(const std::string& ppid, int nDeviceID, int nNewRecipeID) {
 	if (!m_pDB || ppid.empty() || nDeviceID <= 0 || nNewRecipeID <= 0) {
 		return false;
@@ -364,8 +446,8 @@
     recipe.strDescription = "Main Board Burn-in";
 
     recipe.vecDeviceList = {
-        {1, 101, "P1001","Burner A"},
-        {2, 102, "P1001", "Burner B"}
+        {1, 101, "Burner A"},
+        {2, 102, "Burner B"}
     };
 
     addRecipe(recipe);
@@ -402,7 +484,6 @@
         std::getline(ss, description, ',');
         std::getline(ss, createTime, ',');
 
-        dev.strPPID = ppid;
         auto& recipe = recipeMap[ppid];
         recipe.strPPID = ppid;
         recipe.strDescription = description;

--
Gitblit v1.9.3