From db9d120efcfe76bb73df089dca8986eca9ee0e6f Mon Sep 17 00:00:00 2001
From: chenluhua1980 <Chenluhua@qq.com>
Date: 星期三, 10 十二月 2025 10:11:37 +0800
Subject: [PATCH] 1.扫码上报,但未在配置中设置变量;

---
 SourceCode/Bond/Servo/AlarmManager.cpp |  371 ++++++++++++++++++++++++++++++++++++++--------------
 1 files changed, 270 insertions(+), 101 deletions(-)

diff --git a/SourceCode/Bond/Servo/AlarmManager.cpp b/SourceCode/Bond/Servo/AlarmManager.cpp
index efc66b8..56d6cbb 100644
--- a/SourceCode/Bond/Servo/AlarmManager.cpp
+++ b/SourceCode/Bond/Servo/AlarmManager.cpp
@@ -1,4 +1,5 @@
 #include "stdafx.h"
+#include "Common.h"
 #include "AlarmManager.h"
 #include <sstream>
 #include <fstream>
@@ -31,12 +32,6 @@
         delete m_pDB;
         m_pDB = nullptr;
     }
-}
-
-// 设置数据库连接
-void AlarmManager::setDatabase(BL::Database* db) {
-    std::lock_guard<std::mutex> lock(m_mutex);
-    m_pDB = db;
 }
 
 // 初始化报警表
@@ -89,12 +84,58 @@
             unit_id TEXT NOT NULL,
             description TEXT NOT NULL,
             start_time DATETIME NOT NULL,
-            end_time DATETIME NOT NULL,
+            end_time DATETIME,
             FOREIGN KEY (device_id) REFERENCES devices(device_id),
             FOREIGN KEY (unit_id) REFERENCES units(unit_id)
         )
     )";
-    return m_pDB->executeQuery(createAlarmsTableQuery);
+    if (!m_pDB->executeQuery(createAlarmsTableQuery)) {
+        return false;
+    }
+
+    // 设备列表 (ID -> 名称)
+    std::vector<std::pair<int, std::string>> devices = {
+        {EQ_ID_LOADPORT1, EQ_NAME_LOADPORT1},
+        {EQ_ID_LOADPORT2, EQ_NAME_LOADPORT2},
+        {EQ_ID_LOADPORT3, EQ_NAME_LOADPORT3},
+        {EQ_ID_LOADPORT4, EQ_NAME_LOADPORT4},
+        {EQ_ID_ARM_TRAY1, EQ_NAME_ARM_TRAY1},
+        {EQ_ID_ARM_TRAY2, EQ_NAME_ARM_TRAY2},
+        {EQ_ID_ALIGNER, EQ_NAME_ALIGNER},
+        {EQ_ID_FLIPER, EQ_NAME_FLIPER},
+        {EQ_ID_VACUUMBAKE, EQ_NAME_VACUUMBAKE},
+        {EQ_ID_Bonder1, EQ_NAME_BONDER1},
+        {EQ_ID_Bonder2, EQ_NAME_BONDER2},
+        {EQ_ID_BAKE_COOLING, EQ_NAME_BAKE_COOLING},
+        {EQ_ID_MEASUREMENT, EQ_NAME_MEASUREMENT},
+        {EQ_ID_EFEM, EQ_NAME_EFEM},
+        {EQ_ID_ARM, EQ_NAME_ARM},
+        {EQ_ID_OPERATOR_REMOVE, EQ_NAME_OPERATOR_REMOVE}
+    };
+
+    // 插入 devices 和对应的默认 unit
+    for (const auto& dev : devices) {
+        int nDeviceId = dev.first;
+        const std::string& strDeviceName = dev.second;
+
+        // 插入设备
+        std::ostringstream ossDev;
+        ossDev << "INSERT OR IGNORE INTO devices (device_id, device_name) VALUES("
+            << nDeviceId << ", '" << strDeviceName << "')";
+        if (!m_pDB->executeQuery(ossDev.str())) {
+            return false;
+        }
+
+        // 插入默认单元 (unit_id = 0, unit_name = device_name)
+        std::ostringstream ossUnit;
+        ossUnit << "INSERT OR IGNORE INTO units (device_id, unit_id, unit_name) VALUES("
+            << nDeviceId << ", 0, '" << strDeviceName << "')";
+        if (!m_pDB->executeQuery(ossUnit.str())) {
+            return false;
+        }
+    }
+
+    return true;
 }
 
 // 销毁报警表
@@ -127,7 +168,7 @@
 
     // 插入单元数据
     for (int i = 1; i <= 3; ++i) {
-        for (int j = 1; j <= 3; ++j) {
+        for (int j = 0; j <= 3; ++j) {
             int unitId = j;
             std::string deviceId = std::to_string(i);
             std::string unitName = "Unit" + std::to_string(j);
@@ -144,6 +185,7 @@
         }
     }
 
+    /*
     // 初始化随机数生成器
     std::random_device rd;
     std::mt19937 gen(rd());
@@ -181,28 +223,84 @@
             std::cerr << "Failed to insert alarm data." << std::endl;
         }
     }
+    */
 }
 
 // 添加报警信息
-bool AlarmManager::addAlarm(const AlarmData& alarmData) {
+bool AlarmManager::addAlarm(const AlarmData& alarmData, int& alarmEventId) {
     if (!m_pDB) {
         return false;
     }
 
-    // 构建插入查询
-    std::ostringstream query;
-    query << "INSERT INTO alarms (id, severity_level, device_id, unit_id, description, start_time, end_time) VALUES ("
-        << alarmData.nId << ", "              // 错误码
-        << alarmData.nSeverityLevel << ", "   // 报警等级
-        << alarmData.nDeviceId << ", "        // 设备ID
-        << alarmData.nUnitId << ", '"         // 单元ID
-        << alarmData.strDescription << "', '" // 描述
-        << alarmData.strStartTime << "', '"   // 开始时间
-        << alarmData.strEndTime << "')";      // 结束时间
+    #if 0
+        // 开始事务
+        m_pDB->executeQuery("BEGIN TRANSACTION;");
+    
+        // 构建插入查询
+        std::ostringstream query;
+        query << "INSERT INTO alarms (id, severity_level, device_id, unit_id, description, start_time, end_time) VALUES ("
+            << alarmData.nId << ", "              // 错误码
+            << alarmData.nSeverityLevel << ", "   // 报警等级
+            << alarmData.nDeviceId << ", "        // 设备ID
+            << alarmData.nUnitId << ", '"         // 单元ID
+            << alarmData.strDescription << "', '" // 描述
+            << alarmData.strStartTime << "', '"   // 开始时间
+            << alarmData.strEndTime << "')";      // 结束时间
+    
+        // 使用锁保护多线程安全
+        std::lock_guard<std::mutex> lock(m_mutex);
+    
+        // 执行插入查询
+        bool result = m_pDB->executeQuery(query.str());
+        if (result) {
+            alarmEventId = getLastInsertId();
+            m_alarmCache[alarmEventId] = alarmData;
+        }
+    
+        // 提交事务
+        m_pDB->executeQuery("COMMIT;");
+    
+        return result;
+    #else
+        for (AlarmDataMap::const_iterator it = m_mapCache.begin(); it != m_mapCache.end(); ++it) {
+            const AlarmData& alarm = it->second;
+            if (alarm.nId == alarmData.nId &&
+                alarm.nDeviceId == alarmData.nDeviceId &&
+                alarm.nUnitId == alarmData.nUnitId) {
 
-    // 使用锁保护多线程安全
-    std::lock_guard<std::mutex> lock(m_mutex);
-    return m_pDB->executeQuery(query.str());
+                alarmEventId = it->first;
+                return false;
+            }
+        }
+
+        // 构建插入查询并使用 RETURNING 获取插入后的 alarm_event_id
+        std::ostringstream query;
+        query << "INSERT INTO alarms (id, severity_level, device_id, unit_id, description, start_time, end_time) "
+            << "VALUES (" << alarmData.nId << ", " << alarmData.nSeverityLevel << ", " << alarmData.nDeviceId << ", "
+            << alarmData.nUnitId << ", '" << alarmData.strDescription << "', '" << alarmData.strStartTime << "', '"
+            << alarmData.strEndTime << "') RETURNING alarm_event_id;";
+    
+        // 使用锁保护多线程安全
+        std::lock_guard<std::mutex> lock(m_mutex);
+    
+        // 执行查询并获取结果
+        auto results = m_pDB->fetchResults(query.str());
+        if (!results.empty() && !results[0].empty()) {
+            try {
+                // 提取并转换 alarm_event_id
+                alarmEventId = std::stoi(results[0][0]);
+                // 将插入的报警数据添加到缓存
+                m_mapCache[alarmEventId] = alarmData;
+                return true;
+            }
+            catch (const std::exception& e) {
+                std::cerr << "Error parsing alarm_event_id: " << e.what() << std::endl;
+                return false;
+            }
+        }
+    
+        return false;
+    #endif
 }
 
 // 查询所有报警数据
@@ -436,17 +534,7 @@
 }
 
 // 筛选报警数据
-std::vector<AlarmData> AlarmManager::getFilteredAlarms(
-    const std::string& id,
-    const std::string& severityLevel,
-    const std::string& deviceName,
-    const std::string& unitName,
-    const std::string& description,
-    const std::string& startTime,
-    const std::string& endTime,
-    int pageNumber,
-    int pageSize) {
-
+std::vector<AlarmData> AlarmManager::getFilteredAlarms(const std::string& keyword, const std::string& startTime, const std::string& endTime, int pageNumber, int pageSize) {
     if (!m_pDB) {
         return {};
     }
@@ -456,25 +544,20 @@
         SELECT a.id, a.severity_level, a.device_id, a.unit_id, d.device_name, u.unit_name, a.description, a.start_time, a.end_time
         FROM alarms a
         JOIN devices d ON a.device_id = d.device_id
-        JOIN units u ON a.device_id = u.device_id AND a.unit_id = u.unit_id
+        JOIN units u   ON a.device_id = u.device_id AND a.unit_id = u.unit_id
         WHERE 1=1)";
 
-    // 传入的过滤条件
-    if (!id.empty()) {
-        query << " AND a.id = '" << id << "'";
+    // 统一关键字模糊查询
+    if (!keyword.empty()) {
+        query << " AND ("
+            << "a.id LIKE '%" << keyword << "%' OR "
+            << "a.severity_level LIKE '%" << keyword << "%' OR "
+            << "d.device_name LIKE '%" << keyword << "%' OR "
+            << "u.unit_name LIKE '%" << keyword << "%' OR "
+            << "a.description LIKE '%" << keyword << "%')";
     }
-    if (!severityLevel.empty()) {
-        query << " AND a.severity_level = '" << severityLevel << "'";
-    }
-    if (!deviceName.empty()) {
-        query << " AND d.device_name LIKE '%" << deviceName << "%'";
-    }
-    if (!unitName.empty()) {
-        query << " AND u.unit_name LIKE '%" << unitName << "%'";
-    }
-    if (!description.empty()) {
-        query << " AND a.description LIKE '%" << description << "%'";
-    }
+
+    // 时间条件
     if (!startTime.empty()) {
         query << " AND a.start_time >= '" << startTime << "'";
     }
@@ -483,9 +566,10 @@
     }
 
     // 分页设置
-    int offset = (pageNumber - 1) * pageSize;
-    query << " ORDER BY a.start_time DESC LIMIT " << pageSize << " OFFSET " << offset;
+    int nOffset = (pageNumber - 1) * pageSize;
+    query << " ORDER BY a.start_time DESC LIMIT " << pageSize << " OFFSET " << nOffset;
 
+    // 查询
     auto results = m_pDB->fetchResults(query.str());
 
     // 遍历查询结果,填充 AlarmData 结构体
@@ -509,41 +593,30 @@
 }
 
 // 获取符合条件的报警总数
-int AlarmManager::getTotalAlarmCount(
-    const std::string& id,
-    const std::string& severityLevel,
-    const std::string& deviceName,
-    const std::string& unitName,
-    const std::string& description,
-    const std::string& startTime,
-    const std::string& endTime) {
-
+int AlarmManager::getTotalAlarmCount(const std::string& keyword, const std::string& startTime, const std::string& endTime) {
     if (!m_pDB) {
         return 0;
     }
 
     std::ostringstream query;
-    query << "SELECT COUNT(*) FROM alarms a "
-        << "JOIN devices d ON a.device_id = d.device_id "
-        << "JOIN units u ON a.device_id = u.device_id AND a.unit_id = u.unit_id "
-        << "WHERE 1=1";
+    query << R"(
+        SELECT COUNT(*)
+        FROM alarms a
+        JOIN devices d ON a.device_id = d.device_id
+        JOIN units u   ON a.device_id = u.device_id AND a.unit_id = u.unit_id
+        WHERE 1=1)";
 
-    // 添加过滤条件
-    if (!id.empty()) {
-        query << " AND a.id = '" << id << "'";
+    // 统一关键字模糊查询
+    if (!keyword.empty()) {
+        query << " AND ("
+            << "a.id LIKE '%" << keyword << "%' OR "
+            << "a.severity_level LIKE '%" << keyword << "%' OR "
+            << "d.device_name LIKE '%" << keyword << "%' OR "
+            << "u.unit_name LIKE '%" << keyword << "%' OR "
+            << "a.description LIKE '%" << keyword << "%')";
     }
-    if (!severityLevel.empty()) {
-        query << " AND a.severity_level = '" << severityLevel << "'";
-    }
-    if (!deviceName.empty()) {
-        query << " AND d.device_name LIKE '%" << deviceName << "%'";
-    }
-    if (!unitName.empty()) {
-        query << " AND u.unit_name LIKE '%" << unitName << "%'";
-    }
-    if (!description.empty()) {
-        query << " AND a.description LIKE '%" << description << "%'";
-    }
+
+    // 时间条件
     if (!startTime.empty()) {
         query << " AND a.start_time >= '" << startTime << "'";
     }
@@ -636,18 +709,108 @@
     return result[0][0];  // 返回查询到的单元名称
 }
 
+// 获取最近插入的 alarm_event_id
+int AlarmManager::getLastInsertId() {
+    std::string query = "SELECT last_insert_rowid();";
+    auto results = m_pDB->fetchResults(query);
+
+    if (results.empty() || results[0].empty()) {
+        return -1;
+    }
+
+    // 从查询结果中获取最后插入的 ID
+    int lastInsertId = std::stoi(results[0][0]);
+    return lastInsertId;
+}
+
+// 通过 alarm_event_id 解除报警(更新结束时间)
+bool AlarmManager::clearAlarmByEventId(int alarmEventId, const std::string& endTime) {
+    if (!m_pDB) {
+        return false;
+    }
+
+    bool result = true;
+    auto it = m_mapCache.find(alarmEventId);
+    if (it != m_mapCache.end()) {
+        std::lock_guard<std::mutex> lock(m_mutex);
+
+        std::ostringstream query;
+        query << "UPDATE alarms SET end_time = '" << endTime << "' WHERE alarm_event_id = " << alarmEventId << ";";
+        bool result = m_pDB->executeQuery(query.str());
+        if (result) {
+            m_mapCache.erase(it);
+        }
+    }
+
+    return result;
+}
+
+// 通过多个属性查找并解除报警(更新结束时间)
+bool AlarmManager::clearAlarmByAttributes(int nId, int nDeviceId, int nUnitId, const std::string& endTime) {
+    if (!m_pDB) {
+        return false;
+    }
+
+    std::lock_guard<std::mutex> lock(m_mutex);
+
+    // 先在缓存中查找匹配的 alarm_event_id
+    int alarmEventId = -1;
+    for (AlarmDataMap::const_iterator it = m_mapCache.begin(); it != m_mapCache.end(); ++it) {
+        const AlarmData& alarm = it->second;
+        if (alarm.nId == nId &&
+            alarm.nDeviceId == nDeviceId &&
+            alarm.nUnitId == nUnitId) {
+
+            alarmEventId = it->first;
+            break;
+        }
+    }
+
+    // 如果没找到匹配的记录,则直接返回 false
+    if (alarmEventId == -1) {
+        return false;
+    }
+
+    // 构建 SQL 语句,使用找到的 alarm_event_id 来更新结束时间
+    std::ostringstream query;
+    query << "UPDATE alarms SET end_time = '" << endTime << "' WHERE alarm_event_id = " << alarmEventId << ";";
+    bool result = m_pDB->executeQuery(query.str());
+    if (result) {
+        m_mapCache.erase(alarmEventId);
+    }
+
+    return result;
+}
+
 // 读取报警文件
 bool AlarmManager::readAlarmFile(const std::string& filename) {
-    std::ifstream file(filename);
-    std::string line;
-    bool first_line = true;
-
+    std::ifstream file(filename, std::ios::binary);
     if (!file.is_open()) {
         std::cerr << "Error opening file!" << std::endl;
         return false;
     }
 
-    while (std::getline(file, line)) {
+    auto getline_cross = [](std::ifstream& f, std::string& out) -> bool {
+        out.clear();
+        char ch;
+        while (f.get(ch)) {
+            if (ch == '\r') {
+                // 处理 \r\n 或 单独 \r
+                if (f.peek() == '\n') f.get();
+                break;
+            }
+            else if (ch == '\n') {
+                break;
+            }
+            out.push_back(ch);
+        }
+        return !out.empty() || !f.eof();
+    };
+
+    std::string line;
+    bool first_line = true;
+
+    while (getline_cross(file, line)) {
         if (first_line) {
             first_line = false;
             continue;
@@ -657,23 +820,29 @@
         std::string cell;
         AlarmInfo alarm;
 
-        std::getline(ss, cell, ',');
-        std::getline(ss, alarm.strUnitID, ',');
-        std::getline(ss, alarm.strUnitNo, ',');
-        std::getline(ss, cell, ',');
-        alarm.nAlarmLevel = std::stoi(cell);
-        std::getline(ss, cell, ',');
-        alarm.nAlarmCode = std::stoi(cell);
-        std::getline(ss, cell, ',');
-        alarm.nAlarmID = std::stoi(cell);
-        std::getline(ss, alarm.strAlarmText, ',');
-        std::getline(ss, alarm.strDescription, ',');
+        try {
+            if (!std::getline(ss, cell, ',')) throw std::runtime_error("Missing field: No");
+            if (!std::getline(ss, alarm.strUnitID, ',')) throw std::runtime_error("Missing field: UnitID");
+            if (!std::getline(ss, alarm.strUnitNo, ',')) throw std::runtime_error("Missing field: UnitNo");
+            if (!std::getline(ss, cell, ',')) throw std::runtime_error("Missing field: AlarmLevel");
+            alarm.nAlarmLevel = std::stoi(cell);
+            if (!std::getline(ss, cell, ',')) throw std::runtime_error("Missing field: AlarmCode");
+            alarm.nAlarmCode = std::stoi(cell);
+            if (!std::getline(ss, cell, ',')) throw std::runtime_error("Missing field: AlarmID");
+            alarm.nAlarmID = std::stoi(cell);
+            if (!std::getline(ss, alarm.strAlarmText, ',')) throw std::runtime_error("Missing field: AlarmText");
+            if (!std::getline(ss, alarm.strDescription, ',')) throw std::runtime_error("Missing field: Description");
 
-        if (m_mapAlarm.find(alarm.nAlarmID) == m_mapAlarm.end()) {
-            m_mapAlarm[alarm.nAlarmID] = alarm;
+            if (m_mapAlarm.find(alarm.nAlarmID) == m_mapAlarm.end()) {
+                m_mapAlarm[alarm.nAlarmID] = alarm;
+            }
+            else {
+                std::cerr << "Duplicate AlarmID: " << alarm.nAlarmID << std::endl;
+            }
         }
-        else {
-            std::cerr << "Duplicate AlarmID: " << alarm.nAlarmID << std::endl;
+        catch (const std::exception& e) {
+            std::cerr << "Error parsing line: " << line << " - " << e.what() << std::endl;
+            continue;
         }
     }
 
@@ -731,7 +900,7 @@
         auto it = m_mapAlarm.find(alarmID);
         if (it != m_mapAlarm.end()) {
             alarms.push_back(it->second);
-        }
+        } 
         else {
             std::cerr << "未找到 AlarmID: " << alarmID << std::endl;
         }

--
Gitblit v1.9.3