From d78ab86af696b7b762823db10ba0f126e697ae2d Mon Sep 17 00:00:00 2001
From: mrDarker <mr.darker@163.com>
Date: 星期一, 01 九月 2025 17:30:44 +0800
Subject: [PATCH] 1. 添加手动输入配方名称

---
 SourceCode/Bond/Servo/RecipeManager.cpp       |  117 +++++++++++++++++++++++++++--
 SourceCode/Bond/Servo/RecipeManager.h         |    8 +
 SourceCode/Bond/Servo/PageRecipe.h            |    2 
 SourceCode/Bond/Servo/RecipeDeviceBindDlg.cpp |   12 ++
 SourceCode/Bond/Servo/PageRecipe.cpp          |   71 ++++++++++++++++-
 5 files changed, 190 insertions(+), 20 deletions(-)

diff --git a/SourceCode/Bond/Servo/PageRecipe.cpp b/SourceCode/Bond/Servo/PageRecipe.cpp
index 9d9d83c..ab54bcf 100644
--- a/SourceCode/Bond/Servo/PageRecipe.cpp
+++ b/SourceCode/Bond/Servo/PageRecipe.cpp
@@ -6,6 +6,7 @@
 #include "afxdialogex.h"
 #include "PageRecipe.h"
 #include "MsgDlg.h"
+#include "InputDialog.h"
 #include "RecipeDeviceBindDlg.h"
 
 // CPageRecipe 瀵硅瘽妗�
@@ -146,8 +147,18 @@
 		m_listPPID.SetItemText(i, 2, CA2T(recipe.strPPID.c_str()));
 
 		for (int j = 0; j < recipe.vecDeviceList.size(); j++){
+			int nRecipeID = recipe.vecDeviceList.at(j).nRecipeID;
+			std::string strDeviceName = recipe.vecDeviceList.at(j).strDeviceName;
+			std::string strRecipeName = RecipeManager::getInstance().getDeviceRecipeName(strDeviceName, nRecipeID);
+
 			CString str;
-			str.Format(_T("%d"), recipe.vecDeviceList.at(j).nRecipeID);
+			if (strRecipeName.empty()) {
+				str.Format(_T("%d"), recipe.vecDeviceList.at(j).nRecipeID);
+			}
+			else {
+				str.Format(_T("%s"), CA2T(strRecipeName.c_str()));
+			}
+	
 			m_listPPID.SetItemText(i, j + 3, str);
 		}
 
@@ -167,6 +178,22 @@
 		return;
 	}
 
+	CComboBox* pComboBox = (CComboBox*)GetDlgItem(IDC_COMBO_EQUIPMENT);
+	if (pComboBox == nullptr || !::IsWindow(pComboBox->m_hWnd)) {
+		return;
+	}
+
+	int nEqSel = pComboBox->GetCurSel();
+	if (nEqSel == CB_ERR) {
+		return;
+	}
+
+	auto& mgr = RecipeManager::getInstance();
+	SERVO::CEquipment* pEq = (SERVO::CEquipment*)pComboBox->GetItemDataPtr(nEqSel);
+	if (pEq == nullptr) {
+		return;
+	}
+
 	// 娓呯┖褰撳墠CListCtrl涓殑鎵�鏈夐」
 	pListCtrl->DeleteAllItems();
 	if (pList == nullptr) {
@@ -179,6 +206,13 @@
 		int index = m_listPPID.InsertItem(m_listPPID.GetItemCount(), _T(""));
 		m_listPPID.SetItemText(index, 1, std::to_string(item.first).c_str());
 		m_listPPID.SetItemText(index, 2, std::to_string(item.second).c_str());
+
+		std::string strRecipeName = mgr.getDeviceRecipeName(pEq->getName(), item.second);
+		if (strRecipeName.empty()) {
+			strRecipeName = std::to_string(item.second);
+			mgr.addDeviceRecipe(pEq->getName(), item.second, strRecipeName);
+		}
+		m_listPPID.SetItemText(index, 3, strRecipeName.c_str());
 	}
 
 	// 鑾峰彇鍒楁暟
@@ -416,15 +450,40 @@
 void CPageRecipe::OnBnClickedButtonModify()
 {
 	// TODO: 鍦ㄦ娣诲姞鎺т欢閫氱煡澶勭悊绋嬪簭浠g爜
+	CComboBox* pComboBox = (CComboBox*)GetDlgItem(IDC_COMBO_EQUIPMENT);
+	if (pComboBox == nullptr || !::IsWindow(pComboBox->m_hWnd)) {
+		return;
+	}
+
 	POSITION pos = m_listPPID.GetFirstSelectedItemPosition();
 	if (!pos) {
 		AfxMessageBox(_T("璇峰厛閫夋嫨涓�鏉¢厤鏂硅褰曡繘琛屼慨鏀癸紒"));
 		return;
 	}
 
-	int nSel = m_listPPID.GetNextSelectedItem(pos);
-	CString strPPID = m_listPPID.GetItemText(nSel, 2);
-	UpdateRecipeByPPID(strPPID);
+	int nLine = m_listPPID.GetNextSelectedItem(pos);
+	CString strID = m_listPPID.GetItemText(nLine, 2);
+
+	int nSel = pComboBox->GetCurSel();
+	SERVO::CEquipment* pEq = (SERVO::CEquipment*)pComboBox->GetItemDataPtr(nSel);
+	if (pEq == nullptr) {
+		UpdateRecipeByPPID(strID);
+	}
+	else {
+		CInputDialog dlg(_T("淇敼閰嶆柟鍚嶇О"), _T("璇疯緭鍏ラ厤鏂瑰悕绉帮細"));
+		if (dlg.DoModal() != IDOK) {
+			return;
+		}
+
+		CString strText = dlg.GetInputText();
+		if (strText.IsEmpty()) {
+			AfxMessageBox(_T("閰嶆柟鍚嶇О涓嶈兘涓虹┖锛�"));
+			return;
+		}
+		if (RecipeManager::getInstance().updateDeviceRecipe(pEq->getName(), _ttoi(strID), std::string(CT2A(strText)))) {
+			m_listPPID.SetItemText(nLine, 3, strText);
+		}
+	}
 }
 
 void CPageRecipe::OnBnClickedButtonDelete()
@@ -526,7 +585,7 @@
 	int selectedCount = ListView_GetSelectedCount(m_listPPID.GetSafeHwnd());
 
 	GetDlgItem(IDC_BUTTON_NEW)->EnableWindow(nEqSel == 0 && selectedCount > 0);
-	GetDlgItem(IDC_BUTTON_MODIFY)->EnableWindow(nEqSel == 0 && selectedCount > 0);
+	GetDlgItem(IDC_BUTTON_MODIFY)->EnableWindow(/*nEqSel == 0 &&*/ selectedCount > 0);
 	GetDlgItem(IDC_BUTTON_DELETE)->EnableWindow(nEqSel == 0 && selectedCount > 0);
 	GetDlgItem(IDC_BUTTON_DELETE_ALL)->EnableWindow(nEqSel == 0 && selectedCount > 0);
 }
@@ -537,7 +596,7 @@
 	int nEqSel = pComboBox->GetCurSel();
 	int selectedCount = ListView_GetSelectedCount(m_listPPID.GetSafeHwnd());
 
-	GetDlgItem(IDC_BUTTON_NEW)->EnableWindow(nEqSel == 0 && selectedCount > 0);
+	GetDlgItem(IDC_BUTTON_NEW)->EnableWindow(nEqSel == 0/* && selectedCount > 0*/);
 	GetDlgItem(IDC_BUTTON_MODIFY)->EnableWindow(nEqSel == 0 && selectedCount > 0);
 	GetDlgItem(IDC_BUTTON_DELETE)->EnableWindow(nEqSel == 0 && selectedCount > 0);
 	GetDlgItem(IDC_BUTTON_DELETE_ALL)->EnableWindow(nEqSel == 0 && selectedCount > 0);
diff --git a/SourceCode/Bond/Servo/PageRecipe.h b/SourceCode/Bond/Servo/PageRecipe.h
index 6833e3b..c723630 100644
--- a/SourceCode/Bond/Servo/PageRecipe.h
+++ b/SourceCode/Bond/Servo/PageRecipe.h
@@ -43,4 +43,4 @@
 
 private:
 	CListCtrlEx m_listPPID;
-};
+};
\ No newline at end of file
diff --git a/SourceCode/Bond/Servo/RecipeDeviceBindDlg.cpp b/SourceCode/Bond/Servo/RecipeDeviceBindDlg.cpp
index 549fb19..22d0386 100644
--- a/SourceCode/Bond/Servo/RecipeDeviceBindDlg.cpp
+++ b/SourceCode/Bond/Servo/RecipeDeviceBindDlg.cpp
@@ -95,9 +95,15 @@
     pCombo->ResetContent();
     for (const auto& pair : mapRecipeIds) {
         int nRecipeID = pair.second;
-        CString strRecipeName;
-        strRecipeName.Format(_T("%d"), nRecipeID);
-        int idx = pCombo->AddString(strRecipeName);
+
+        std::string strRecipeName = RecipeManager::getInstance().getDeviceRecipeName(pEq->getName(), nRecipeID);
+        if (strRecipeName.empty()) {
+            strRecipeName = std::to_string(nRecipeID);
+        }
+
+        CString str;
+        str.Format(_T("%s"), strRecipeName.c_str());
+        int idx = pCombo->AddString(str);
         pCombo->SetItemData(idx, nRecipeID);
         if (nSelectedRecipeID == nRecipeID) {
             pCombo->SetCurSel(idx);
diff --git a/SourceCode/Bond/Servo/RecipeManager.cpp b/SourceCode/Bond/Servo/RecipeManager.cpp
index 5928d57..1095038 100644
--- a/SourceCode/Bond/Servo/RecipeManager.cpp
+++ b/SourceCode/Bond/Servo/RecipeManager.cpp
@@ -56,6 +56,7 @@
             device_id INTEGER NOT NULL,
             device_name TEXT NOT NULL,
             recipe_id INTEGER NOT NULL,
+            recipe_name TEXT NOT NULL,
             FOREIGN KEY(ppid) REFERENCES recipes(ppid) ON DELETE CASCADE ON UPDATE CASCADE,
             UNIQUE (ppid, device_id),
             UNIQUE (ppid, device_name)
@@ -131,11 +132,13 @@
 
     for (const auto& device : recipe.vecDeviceList) {
         std::ostringstream devSql;
-        devSql << "INSERT OR REPLACE INTO recipe_devices (ppid, device_id, device_name, recipe_id) VALUES ('"
+        devSql << "INSERT OR REPLACE INTO recipe_devices (ppid, device_id, device_name, recipe_id, recipe_name) VALUES ('"
             << recipe.strPPID << "', "
             << device.nDeviceID << ", '"
             << device.strDeviceName << "', "
-            << device.nRecipeID << ");";
+            << device.nRecipeID << ", '"
+            << device.strRecipeName << "');";
+
 
         if (!m_pDB->executeQuery(devSql.str())) {
             std::cerr << "[AddRecipe] Failed to insert device mapping: " << device.nDeviceID << std::endl;
@@ -163,11 +166,12 @@
 
     // 插入设备记录
     std::ostringstream oss;
-    oss << "INSERT OR REPLACE INTO recipe_devices (ppid, device_id, device_name, recipe_id) VALUES ('"
+    oss << "INSERT OR REPLACE INTO recipe_devices (ppid, device_id, device_name, recipe_id, recipe_name) VALUES ('"
         << ppid << "', "
         << device.nDeviceID << ", '"
         << device.strDeviceName << "', "
-        << device.nRecipeID << ");";
+        << device.nRecipeID << ", '"
+        << device.strRecipeName << "');";
 
     std::lock_guard<std::recursive_mutex> lock(m_mutex);
     return m_pDB->executeQuery(oss.str());
@@ -214,7 +218,7 @@
         info.strCreateTime = row[2];
 
         std::ostringstream devQuery;
-        devQuery << "SELECT device_id, device_name, recipe_id FROM recipe_devices WHERE ppid = '" << info.strPPID << "';";
+        devQuery << "SELECT device_id, device_name, recipe_id, recipe_name FROM recipe_devices WHERE ppid = '" << info.strPPID << "'ORDER BY id ASC;";
         auto devs = m_pDB->fetchResults(devQuery.str());
 
         for (const auto& dev : devs) {
@@ -223,6 +227,7 @@
                 dr.nDeviceID = std::stoi(dev[0]);
                 dr.strDeviceName = dev[1];
                 dr.nRecipeID = std::stoi(dev[2]);
+				dr.strRecipeName = dev[3];
             }
             catch (...) {
                 std::cerr << "Invalid data in recipe_devices for PPID: " << info.strPPID << std::endl;
@@ -289,13 +294,14 @@
     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 + "';");
+    auto devs = m_pDB->fetchResults("SELECT device_id, device_name, recipe_id, recipe_name FROM recipe_devices WHERE ppid = '" + ppid + "';");
     for (const auto& dev : devs) {
         DeviceRecipe dr;
         try {
             dr.nDeviceID = std::stoi(dev[0]);
             dr.strDeviceName = dev[1];
             dr.nRecipeID = std::stoi(dev[2]);
+            dr.strRecipeName = dev[3];
         }
         catch (...) {
             std::cerr << "Invalid data in recipe_devices for PPID: " << ppid << std::endl;
@@ -435,6 +441,88 @@
 	return m_pDB->executeQuery(query.str());
 }
 
+bool RecipeManager::addDeviceRecipe(const std::string& deviceName, int nRecipeID, const std::string& strRecipeName) {
+    if (!m_pDB || deviceName.empty() || nRecipeID <= 0 || strRecipeName.empty()) { 
+        return false;
+    }
+
+    std::ostringstream sql;
+    sql << "CREATE TABLE IF NOT EXISTS " << deviceName << "_Recipes ("
+        << "recipe_id INTEGER PRIMARY KEY, "
+        << "recipe_name TEXT NOT NULL"
+        << ");";
+    m_pDB->executeQuery(sql.str());
+
+    std::ostringstream ins;
+    ins << "INSERT OR REPLACE INTO " << deviceName << "_Recipes (recipe_id, recipe_name) VALUES ("
+        << nRecipeID << ", '" << strRecipeName << "');";
+
+    std::lock_guard<std::recursive_mutex> lk(m_mutex);
+    return m_pDB->executeQuery(ins.str());
+}
+
+bool RecipeManager::updateDeviceRecipe(const std::string& deviceName, int nRecipeID, const std::string& newName) {
+    if (!m_pDB || deviceName.empty() || nRecipeID <= 0 || newName.empty()) { 
+        return false;
+    }
+
+    std::ostringstream sql;
+    sql << "UPDATE " << deviceName << "_Recipes SET recipe_name='" << newName
+        << "' WHERE recipe_id=" << nRecipeID << ";";
+
+    std::lock_guard<std::recursive_mutex> lk(m_mutex);
+    return m_pDB->executeQuery(sql.str());
+}
+
+std::string RecipeManager::getDeviceRecipeName(const std::string& deviceName, int nRecipeID) {
+    if (!m_pDB || deviceName.empty() || nRecipeID <= 0) {
+        return "";
+    }
+
+    std::ostringstream sql;
+    sql << "SELECT recipe_name FROM " << deviceName << "_Recipes "
+        << "WHERE recipe_id=" << nRecipeID << " LIMIT 1;";
+
+    auto rows = m_pDB->fetchResults(sql.str());
+    if (!rows.empty() && !rows[0].empty()) {
+        return rows[0][0];
+    }
+    return "";
+}
+
+bool RecipeManager::deleteDeviceRecipe(const std::string& deviceName, int nRecipeID) {
+    if (!m_pDB || deviceName.empty() || nRecipeID <= 0) { 
+        return false;
+    }
+
+    std::ostringstream sql;
+    sql << "DELETE FROM " << deviceName << "_Recipes WHERE recipe_id=" << nRecipeID << ";";
+
+    std::lock_guard<std::recursive_mutex> lk(m_mutex);
+    return m_pDB->executeQuery(sql.str());
+}
+
+std::vector<std::pair<int, std::string>> RecipeManager::getDeviceRecipes(const std::string& deviceName) {
+    std::vector<std::pair<int, std::string>> out;
+    if (!m_pDB || deviceName.empty()) { 
+        return out;
+    }
+
+    std::ostringstream sql;
+    sql << "SELECT recipe_id, recipe_name FROM " << deviceName << "_Recipes ORDER BY recipe_id;";
+
+    auto rows = m_pDB->fetchResults(sql.str());
+    for (const auto& r : rows) {
+        if (r.size() < 2) continue;
+        try {
+            int id = std::stoi(r[0]);
+            out.emplace_back(id, r[1]);
+        }
+        catch (...) {}
+    }
+    return out;
+}
+
 void RecipeManager::insertMockData() {
     if (!m_pDB) {
         return;
@@ -445,11 +533,20 @@
     recipe.strDescription = "Main Board Burn-in";
 
     recipe.vecDeviceList = {
-        {1, 101, "Burner A"},
-        {2, 102, "Burner B"}
+        {9, 101, "VacuumBake", "VacuumBake"},
+        {10, 102, "Bonder1", "Bonder1"},
+        {11, 103, "Bonder2", "Bonder2"}
     };
 
     addRecipe(recipe);
+
+    addDeviceRecipe("Bonder1", 101, "标准工艺");
+    addDeviceRecipe("Bonder1", 102, "改良工艺");
+    addDeviceRecipe("Bonder1", 103, "高速模式");
+
+    addDeviceRecipe("Bonder2", 101, "标准工艺");
+    addDeviceRecipe("Bonder2", 102, "改良工艺");
+    addDeviceRecipe("Bonder2", 103, "高速模式");
 }
 
 bool RecipeManager::readRecipeFile(const std::string& filename) {
@@ -480,6 +577,7 @@
         std::getline(ss, cell, ',');
         try { dev.nRecipeID = std::stoi(cell); }
         catch (...) { continue; }
+		std::getline(ss, dev.strRecipeName, ',');
         std::getline(ss, description, ',');
         std::getline(ss, createTime, ',');
 
@@ -509,7 +607,7 @@
         return false;
     }
 
-    file << "PPID,DeviceID,DeviceName,RecipeID,Description,CreateTime\n";
+    file << "PPID,DeviceID,DeviceName,RecipeID,RecipeName,Description,CreateTime\n";
     auto recipes = getAllRecipes();
     for (const auto& recipe : recipes) {
         for (const auto& dev : recipe.vecDeviceList) {
@@ -517,6 +615,7 @@
                 << dev.nDeviceID << ","
                 << dev.strDeviceName << ","
                 << dev.nRecipeID << ","
+				<< dev.strRecipeName << ","
                 << recipe.strDescription << ","
                 << recipe.strCreateTime << "\n";
         }
diff --git a/SourceCode/Bond/Servo/RecipeManager.h b/SourceCode/Bond/Servo/RecipeManager.h
index b27b026..3ada9c2 100644
--- a/SourceCode/Bond/Servo/RecipeManager.h
+++ b/SourceCode/Bond/Servo/RecipeManager.h
@@ -11,8 +11,8 @@
 struct DeviceRecipe {
     int nDeviceID;               // 设备ID
     int nRecipeID;               // 子配方ID
-	std::string strRecipeName;   // 子配方名称
     std::string strDeviceName;   // 设备名称 
+	std::string strRecipeName;   // 子配方名称
 };
 
 // 配方信息
@@ -91,6 +91,12 @@
 	// 更新设备配方ID(通过 PPID 和设备名称)
     bool updateDeviceRecipeIDByName(const std::string& ppid, const std::string& strDeviceName, int nNewRecipeID);
 
+    bool addDeviceRecipe(const std::string& deviceName, int nRecipeID, const std::string& strRecipeName);
+    bool updateDeviceRecipe(const std::string& deviceName, int nRecipeID, const std::string& newName);
+    std::string getDeviceRecipeName(const std::string& deviceName, int nRecipeID);
+    bool deleteDeviceRecipe(const std::string& deviceName, int nRecipeID);
+    std::vector<std::pair<int, std::string>> getDeviceRecipes(const std::string& deviceName);
+
     // 模拟插入数据(测试用)
     void insertMockData();
 

--
Gitblit v1.9.3