From 44360bc2cdeee16be72f9cc4bfb42e0ac26b5b44 Mon Sep 17 00:00:00 2001
From: chenluhua1980 <Chenluhua@qq.com>
Date: 星期一, 19 一月 2026 14:47:19 +0800
Subject: [PATCH] 1.修改优化

---
 SourceCode/Bond/Servo/AlarmManager.cpp |  845 ++++++++++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 733 insertions(+), 112 deletions(-)

diff --git a/SourceCode/Bond/Servo/AlarmManager.cpp b/SourceCode/Bond/Servo/AlarmManager.cpp
index 7864235..56d6cbb 100644
--- a/SourceCode/Bond/Servo/AlarmManager.cpp
+++ b/SourceCode/Bond/Servo/AlarmManager.cpp
@@ -1,9 +1,13 @@
 #include "stdafx.h"
+#include "Common.h"
 #include "AlarmManager.h"
 #include <sstream>
+#include <fstream>
 #include <iostream>
 #include <stdexcept>
 #include <ctime>
+#include <iomanip>
+#include <random>
 
 // 常量
 const std::string DATABASE_FILE = R"(AlarmManager.db)";
@@ -30,12 +34,6 @@
     }
 }
 
-// 设置数据库连接
-void AlarmManager::setDatabase(BL::Database* db) {
-    std::lock_guard<std::mutex> lock(m_mutex);
-    m_pDB = db;
-}
-
 // 初始化报警表
 bool AlarmManager::initAlarmTable() {
     char path[MAX_PATH];
@@ -51,17 +49,93 @@
         throw std::runtime_error("Failed to connect to database.");
     }
 
-    const std::string createTableQuery = R"(
-        CREATE TABLE IF NOT EXISTS alarms (
-            id TEXT NOT NULL,
-            device_name TEXT NOT NULL,
-            description TEXT NOT NULL,
-            start_time DATETIME NOT NULL,
-            end_time DATETIME NOT NULL
+    // 创建设备表
+    const std::string createDevicesTableQuery = R"(
+        CREATE TABLE IF NOT EXISTS devices (
+            device_id TEXT PRIMARY KEY NOT NULL,
+            device_name TEXT NOT NULL
         )
     )";
+    if (!m_pDB->executeQuery(createDevicesTableQuery)) {
+        return false;
+    }
 
-    return m_pDB->executeQuery(createTableQuery);
+    // 创建单元表,设备ID和单元ID组合作为主键
+    const std::string createUnitsTableQuery = R"(
+        CREATE TABLE IF NOT EXISTS units (
+            device_id TEXT NOT NULL,
+            unit_id TEXT NOT NULL,
+            unit_name TEXT NOT NULL,
+            PRIMARY KEY (device_id, unit_id),
+            FOREIGN KEY (device_id) REFERENCES devices(device_id)
+        )
+    )";
+    if (!m_pDB->executeQuery(createUnitsTableQuery)) {
+        return false;
+    }
+
+    // 创建报警表,报警记录的alarm_event_id是主键
+    const std::string createAlarmsTableQuery = R"(
+        CREATE TABLE IF NOT EXISTS alarms (
+            alarm_event_id INTEGER PRIMARY KEY AUTOINCREMENT,
+            id TEXT NOT NULL,
+            severity_level INTEGER NOT NULL DEFAULT 0,    
+            device_id TEXT NOT NULL ,
+            unit_id TEXT NOT NULL,
+            description TEXT NOT NULL,
+            start_time DATETIME NOT NULL,
+            end_time DATETIME,
+            FOREIGN KEY (device_id) REFERENCES devices(device_id),
+            FOREIGN KEY (unit_id) REFERENCES units(unit_id)
+        )
+    )";
+    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;
 }
 
 // 销毁报警表
@@ -80,177 +154,474 @@
 	return m_pDB->executeQuery(dropTableQuery);
 }
 
-// 添加报警
-bool AlarmManager::addAlarm(const std::string& id, const std::string& deviceName, const std::string& description, const std::string& startTime, const std::string& endTime) {
-    if (!m_pDB) {
-        throw std::runtime_error("Database connection is not set.");
+// 插入模拟数据
+void AlarmManager::insertMockData() {
+    // 插入设备数据
+    for (int i = 1; i <= 3; ++i) {
+        std::string deviceName = "Device" + std::to_string(i);
+        std::stringstream query;
+        query << "INSERT INTO devices (device_id, device_name) VALUES (" << i << ", '" << deviceName << "');";
+        if (!m_pDB->executeQuery(query.str())) {
+            std::cerr << "Failed to insert device: " << i << std::endl;
+        }
     }
 
-    std::ostringstream query;
-    query << "INSERT INTO alarms (id, device_name, description, start_time, end_time) VALUES ("
-        << "'" << id << "', "
-		<< "'" << deviceName << "', "
-        << "'" << description << "', "
-        << "'" << startTime << "', "
-        << "'" << endTime << "')";
+    // 插入单元数据
+    for (int i = 1; i <= 3; ++i) {
+        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);
 
-    std::lock_guard<std::mutex> lock(m_mutex);
-    return m_pDB->executeQuery(query.str());
+            std::stringstream query;
+            query << "INSERT INTO units (device_id, unit_id, unit_name) VALUES ('"
+                << deviceId << "', '"   // 插入设备ID,确保是字符串
+                << unitId << "', '"     // 插入单元ID,确保是字符串
+                << unitName << "');";
+
+            if (!m_pDB->executeQuery(query.str())) {
+                std::cerr << "Failed to insert unit: " << unitId << std::endl;
+            }
+        }
+    }
+
+    /*
+    // 初始化随机数生成器
+    std::random_device rd;
+    std::mt19937 gen(rd());
+    std::uniform_int_distribution<> deviceDis(1, 3);
+    std::uniform_int_distribution<> unitDis(1, 3);
+    std::uniform_int_distribution<> errorCodeDis(1, 100);
+    std::uniform_int_distribution<> severityDis(0, 3);
+    std::vector<std::string> descriptions = { "Overheat", "Sensor failure", "Power outage" };
+
+    // 时间相关
+    auto now = std::chrono::system_clock::now();
+    auto start_time = std::chrono::system_clock::to_time_t(now);
+    auto end_time = std::chrono::system_clock::to_time_t(now + std::chrono::minutes(10));
+
+    std::tm start_tm = {};
+    std::tm end_tm = {};
+    localtime_s(&start_tm, &start_time);
+    localtime_s(&end_tm, &end_time);
+
+    // 插入模拟数据
+    for (int i = 0; i < 10; ++i) {
+        int deviceId = deviceDis(gen);          // 随机设备ID
+        int unitId = unitDis(gen);              // 随机单元ID
+        int errorCode = errorCodeDis(gen);      // 随机错误码
+        int severityLevel = severityDis(gen);   // 随机生成报警等级
+        std::string description = descriptions[errorCodeDis(gen) % descriptions.size()];  // 随机报警描述
+
+        std::stringstream query;
+        query << "INSERT INTO alarms (id, severity_level, device_id, unit_id, description, start_time, end_time) "
+            << "VALUES (" << errorCode << ", " << severityLevel << ", " << deviceId << ", " << unitId << ", '" << description << "', "
+            << "'" << std::put_time(&start_tm, "%Y-%m-%d %H:%M:%S") << "', "
+            << "'" << std::put_time(&end_tm, "%Y-%m-%d %H:%M:%S") << "');";
+
+        if (!m_pDB->executeQuery(query.str())) {
+            std::cerr << "Failed to insert alarm data." << std::endl;
+        }
+    }
+    */
+}
+
+// 添加报警信息
+bool AlarmManager::addAlarm(const AlarmData& alarmData, int& alarmEventId) {
+    if (!m_pDB) {
+        return false;
+    }
+
+    #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) {
+
+                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
 }
 
 // 查询所有报警数据
-std::vector<std::vector<std::string>> AlarmManager::getAllAlarms() {
+std::vector<AlarmData> AlarmManager::getAllAlarms() {
     if (!m_pDB) {
-        throw std::runtime_error("Database connection is not set.");
+        return {};
     }
 
-    const std::string query = "SELECT id, device_name, description, start_time, end_time FROM alarms";
-    return m_pDB->fetchResults(query);
+    // 查询所有报警数据(包括设备名称和单元名称)
+    const std::string query = R"(
+        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
+    )";
+
+    auto results = m_pDB->fetchResults(query);
+
+    // 遍历查询结果,填充 AlarmData 结构体
+    std::vector<AlarmData> alarms;
+    for (const auto& row : results) {
+        AlarmData alarmData;
+        alarmData.nId = std::stoi(row[0]);              // 错误码
+        alarmData.nSeverityLevel = std::stoi(row[1]);   // 报警等级
+        alarmData.nDeviceId = std::stoi(row[2]);        // 设备ID
+        alarmData.nUnitId = std::stoi(row[3]);          // 单元ID
+        alarmData.strDeviceName = row[4];               // 设备名称
+        alarmData.strUnitName = row[5];                 // 单元名称
+        alarmData.strDescription = row[6];              // 描述
+        alarmData.strStartTime = row[7];                // 开始时间
+        alarmData.strEndTime = row[8];                  // 结束时间
+
+        alarms.push_back(alarmData);
+    }
+
+    return alarms;
 }
 
 // 根据报警ID查询报警
-std::vector<std::vector<std::string>> AlarmManager::getAlarmsById(const std::string& id) {
+std::vector<AlarmData> AlarmManager::getAlarmsById(const std::string& id) {
     if (!m_pDB) {
-        throw std::runtime_error("Database connection is not set.");
+        return {};
     }
 
     std::ostringstream query;
-    query << "SELECT id, device_name, description, start_time, end_time FROM alarms WHERE id = '" << id << "'";
-    return m_pDB->fetchResults(query.str());
+    query << R"(
+        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
+        WHERE a.id = ')" << id << "'";
+
+    auto results = m_pDB->fetchResults(query.str());
+
+    // 遍历查询结果,填充 AlarmData 结构体
+    std::vector<AlarmData> alarms;
+    for (const auto& row : results) {
+        AlarmData alarmData;
+        alarmData.nId = std::stoi(row[0]);              // 错误码
+        alarmData.nSeverityLevel = std::stoi(row[1]);   // 报警等级
+        alarmData.nDeviceId = std::stoi(row[2]);        // 设备ID
+        alarmData.nUnitId = std::stoi(row[3]);          // 单元ID
+        alarmData.strDeviceName = row[4];               // 设备名称
+        alarmData.strUnitName = row[5];                 // 单元名称
+        alarmData.strDescription = row[6];              // 描述
+        alarmData.strStartTime = row[7];                // 开始时间
+        alarmData.strEndTime = row[8];                  // 结束时间
+
+        alarms.push_back(alarmData);
+    }
+
+    return alarms;
 }
 
 // 根据描述查询报警
-std::vector<std::vector<std::string>> AlarmManager::getAlarmsByDescription(const std::string& description) {
+std::vector<AlarmData> AlarmManager::getAlarmsByDescription(const std::string& description) {
     if (!m_pDB) {
-        throw std::runtime_error("Database connection is not set.");
+        return {};
     }
 
     std::ostringstream query;
-    query << "SELECT id, device_name, description, start_time, end_time FROM alarms WHERE description LIKE '%" << description << "%'";
-    return m_pDB->fetchResults(query.str());
+    query << R"(
+        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
+        WHERE a.description LIKE '%)" << description << R"(%')";
+
+    auto results = m_pDB->fetchResults(query.str());
+
+    // 遍历查询结果,填充 AlarmData 结构体
+    std::vector<AlarmData> alarms;
+    for (const auto& row : results) {
+        AlarmData alarmData;
+        alarmData.nId = std::stoi(row[0]);              // 错误码
+        alarmData.nSeverityLevel = std::stoi(row[1]);   // 报警等级
+        alarmData.nDeviceId = std::stoi(row[2]);        // 设备ID
+        alarmData.nUnitId = std::stoi(row[3]);          // 单元ID
+        alarmData.strDeviceName = row[4];               // 设备名称
+        alarmData.strUnitName = row[5];                 // 单元名称
+        alarmData.strDescription = row[6];              // 描述
+        alarmData.strStartTime = row[7];                // 开始时间
+        alarmData.strEndTime = row[8];                  // 结束时间
+
+        alarms.push_back(alarmData);
+    }
+
+    return alarms;
 }
 
 // 根据时间范围查询报警
-std::vector<std::vector<std::string>> AlarmManager::getAlarmsByTimeRange(
-    const std::string& startTime, const std::string& endTime) {
-
+std::vector<AlarmData> AlarmManager::getAlarmsByTimeRange(const std::string& startTime, const std::string& endTime) {
     if (!m_pDB) {
-        throw std::runtime_error("Database connection is not set.");
+        return {};
     }
 
     std::ostringstream query;
-    query << "SELECT id, device_name, description, start_time, end_time FROM alarms WHERE 1=1";
+    query << R"(
+        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
+        WHERE 1=1)";
 
     if (!startTime.empty()) {
-        query << " AND start_time >= '" << startTime << "'";
+        query << " AND a.start_time >= '" << startTime << "'";
     }
     if (!endTime.empty()) {
-        query << " AND end_time <= '" << endTime << "'";
+        query << " AND a.end_time <= '" << endTime << "'";
     }
 
-    return m_pDB->fetchResults(query.str());
+    auto results = m_pDB->fetchResults(query.str());
+
+    // 遍历查询结果,填充 AlarmData 结构体
+    std::vector<AlarmData> alarms;
+    for (const auto& row : results) {
+        AlarmData alarmData;
+        alarmData.nId = std::stoi(row[0]);              // 错误码
+        alarmData.nSeverityLevel = std::stoi(row[1]);   // 报警等级
+        alarmData.nDeviceId = std::stoi(row[2]);        // 设备ID
+        alarmData.nUnitId = std::stoi(row[3]);          // 单元ID
+        alarmData.strDeviceName = row[4];               // 设备名称
+        alarmData.strUnitName = row[5];                 // 单元名称
+        alarmData.strDescription = row[6];              // 描述
+        alarmData.strStartTime = row[7];                // 开始时间
+        alarmData.strEndTime = row[8];                  // 结束时间
+
+        alarms.push_back(alarmData);
+    }
+
+    return alarms;
 }
 
 // 根据ID、开始时间和结束时间查询报警
-std::vector<std::vector<std::string>> AlarmManager::getAlarmsByIdAndTimeRange(
-    const std::string& id, const std::string& startTime, const std::string& endTime) {
-
+std::vector<AlarmData> AlarmManager::getAlarmsByIdAndTimeRange(const std::string& id, const std::string& startTime, const std::string& endTime) {
     if (!m_pDB) {
-        throw std::runtime_error("Database connection is not set.");
+        return {};
     }
 
     std::ostringstream query;
-    query << "SELECT id, device_name, description, start_time, end_time FROM alarms WHERE id = '" << id << "'";
+    query << R"(
+        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
+        WHERE a.id = ')" << id << "'";
 
     if (!startTime.empty()) {
-        query << " AND start_time >= '" << startTime << "'";
+        query << " AND a.start_time >= '" << startTime << "'";
     }
     if (!endTime.empty()) {
-        query << " AND end_time <= '" << endTime << "'";
+        query << " AND a.end_time <= '" << endTime << "'";
     }
 
-    return m_pDB->fetchResults(query.str());
+    auto results = m_pDB->fetchResults(query.str());
+
+    // 遍历查询结果,填充 AlarmData 结构体
+    std::vector<AlarmData> alarms;
+    for (const auto& row : results) {
+        AlarmData alarmData;
+        alarmData.nId = std::stoi(row[0]);              // 错误码
+        alarmData.nSeverityLevel = std::stoi(row[1]);   // 报警等级
+        alarmData.nDeviceId = std::stoi(row[2]);        // 设备ID
+        alarmData.nUnitId = std::stoi(row[3]);          // 单元ID
+        alarmData.strDeviceName = row[4];               // 设备名称
+        alarmData.strUnitName = row[5];                 // 单元名称
+        alarmData.strDescription = row[6];              // 描述
+        alarmData.strStartTime = row[7];                // 开始时间
+        alarmData.strEndTime = row[8];                  // 结束时间
+
+        alarms.push_back(alarmData);
+    }
+
+    return alarms;
 }
 
 // 分页查询报警数据
-std::vector<std::vector<std::string>> AlarmManager::getAlarms(int startPosition, int count) {
+std::vector<AlarmData> AlarmManager::getAlarms(int startPosition, int count) {
     if (!m_pDB) {
-        throw std::runtime_error("Database connection is not set.");
+        return {};
     }
 
     std::ostringstream query;
-    query << "SELECT id, device_name, description, start_time, end_time FROM alarms LIMIT " << count << " OFFSET " << startPosition;
-    return m_pDB->fetchResults(query.str());
+    query << R"(
+        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
+        LIMIT )" << count << " OFFSET " << startPosition;
+
+    auto results = m_pDB->fetchResults(query.str());
+
+    // 遍历查询结果,填充 AlarmData 结构体
+    std::vector<AlarmData> alarms;
+    for (const auto& row : results) {
+        AlarmData alarmData;
+        alarmData.nId = std::stoi(row[0]);              // 错误码
+        alarmData.nSeverityLevel = std::stoi(row[1]);   // 报警等级
+        alarmData.nDeviceId = std::stoi(row[2]);        // 设备ID
+        alarmData.nUnitId = std::stoi(row[3]);          // 单元ID
+        alarmData.strDeviceName = row[4];               // 设备名称
+        alarmData.strUnitName = row[5];                 // 单元名称
+        alarmData.strDescription = row[6];              // 描述
+        alarmData.strStartTime = row[7];                // 开始时间
+        alarmData.strEndTime = row[8];                  // 结束时间
+
+        alarms.push_back(alarmData);
+    }
+
+    return alarms;
 }
 
 // 筛选报警数据
-std::vector<std::vector<std::string>> AlarmManager::getFilteredAlarms(
-    const std::string& id,
-    const std::string& deviceName,
-    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) {
-        throw std::runtime_error("Database connection is not set.");
+        return {};
     }
 
     std::ostringstream query;
-    query << "SELECT id, device_name, description, start_time, end_time FROM alarms WHERE 1=1";
+    query << R"(
+        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
+        WHERE 1=1)";
 
-	if (!id.empty()) {
-		query << " AND id = '" << id << "'";
-	}
-	if (!deviceName.empty()) {
-		query << " AND device_name LIKE '%" << deviceName << "%'";
-	}
-    if (!description.empty()) {
-        query << " AND description LIKE '%" << description << "%'";
+    // 统一关键字模糊查询
+    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 (!startTime.empty()) {
-        query << " AND start_time >= '" << startTime << "'";
+        query << " AND a.start_time >= '" << startTime << "'";
     }
     if (!endTime.empty()) {
-        query << " AND end_time <= '" << endTime << "'";
+        query << " AND a.end_time <= '" << endTime << "'";
     }
 
-    int offset = (pageNumber - 1) * pageSize;
-    query << " ORDER BY start_time DESC LIMIT " << pageSize << " OFFSET " << offset;
+    // 分页设置
+    int nOffset = (pageNumber - 1) * pageSize;
+    query << " ORDER BY a.start_time DESC LIMIT " << pageSize << " OFFSET " << nOffset;
 
-    return m_pDB->fetchResults(query.str());
+    // 查询
+    auto results = m_pDB->fetchResults(query.str());
+
+    // 遍历查询结果,填充 AlarmData 结构体
+    std::vector<AlarmData> alarms;
+    for (const auto& row : results) {
+        AlarmData alarmData;
+        alarmData.nId = std::stoi(row[0]);             // 错误码
+        alarmData.nSeverityLevel = std::stoi(row[1]);  // 报警等级 (字符串)
+        alarmData.nDeviceId = std::stoi(row[2]);       // 设备ID
+        alarmData.nUnitId = std::stoi(row[3]);         // 单元ID
+        alarmData.strDeviceName = row[4];              // 设备名称
+        alarmData.strUnitName = row[5];                // 单元名称
+        alarmData.strDescription = row[6];             // 描述
+        alarmData.strStartTime = row[7];               // 开始时间
+        alarmData.strEndTime = row[8];                 // 结束时间
+
+        alarms.push_back(alarmData);
+    }
+
+    return alarms;
 }
 
 // 获取符合条件的报警总数
-int AlarmManager::getTotalAlarmCount(
-    const std::string& id,
-    const std::string& deviceName,
-    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) {
-        throw std::runtime_error("Database connection is not set.");
+        return 0;
     }
 
     std::ostringstream query;
-    query << "SELECT COUNT(*) FROM alarms 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 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 (!deviceName.empty()) {
-		query << " AND device_name LIKE '%" << deviceName << "%'";
-    }
-    if (!description.empty()) {
-        query << " AND description LIKE '%" << description << "%'";
-    }
+
+    // 时间条件
     if (!startTime.empty()) {
-        query << " AND start_time >= '" << startTime << "'";
+        query << " AND a.start_time >= '" << startTime << "'";
     }
     if (!endTime.empty()) {
-        query << " AND end_time <= '" << endTime << "'";
+        query << " AND a.end_time <= '" << endTime << "'";
     }
 
     auto results = m_pDB->fetchResults(query.str());
@@ -258,32 +629,282 @@
 }
 
 // 更新报警的结束时间
-bool AlarmManager::updateAlarmEndTime(const std::string& id, const std::string& deviceName, const std::string& description, const std::string& startTime, const std::string& newEndTime) {
+bool AlarmManager::updateAlarmEndTime(
+    const std::string& id,
+    const std::string& severityLevel,
+    const std::string& deviceId,
+    const std::string& unitId,
+    const std::string& description,
+    const std::string& startTime,
+    const std::string& newEndTime) {
+
     if (!m_pDB) {
-        throw std::runtime_error("Database connection is not set.");
+        return false;
     }
 
-    std::ostringstream query;
-    query << "UPDATE alarms SET end_time = '" << newEndTime << "'"
+    // 更新报警结束时间
+    std::ostringstream updateQuery;
+    updateQuery << "UPDATE alarms SET end_time = '" << newEndTime << "'"
         << " WHERE id = '" << id << "'"
-		<< " AND device_name = '" << deviceName << "'"
+        << " AND severity_level = '" << severityLevel << "'"
+        << " AND device_id = '" << deviceId << "'"
+        << " AND unit_id = '" << unitId << "'"
         << " AND description = '" << description << "'"
         << " AND start_time = '" << startTime << "'";
 
-    return m_pDB->executeQuery(query.str());
+    return m_pDB->executeQuery(updateQuery.str());
 }
 
 // 清理旧报警数据
-void AlarmManager::cleanOldAlarms(int daysToKeep, const std::string& deviceName) {
+void AlarmManager::cleanOldAlarms(int daysToKeep, const std::string& deviceId, const std::string& unitId) {
     if (!m_pDB) {
-        throw std::runtime_error("Database connection is not set.");
+        return;
     }
 
     std::ostringstream query;
     query << "DELETE FROM alarms WHERE end_time < datetime('now', '-" << daysToKeep << " days')";
 
-    if (!deviceName.empty()) {
-        query << " AND device_name = '" << deviceName << "'";
+    if (!deviceId.empty()) {
+        query << " AND device_id = '" << deviceId << "'";
     }
+    if (!unitId.empty()) {
+        query << " AND unit_id = '" << unitId << "'";
+    }
+
     m_pDB->executeQuery(query.str());
 }
+
+// 通过设备ID获取设备名称
+std::string AlarmManager::getDeviceNameById(int deviceId) {
+    if (!m_pDB) {
+        return "";
+    }
+
+    std::ostringstream query;
+    query << "SELECT device_name FROM devices WHERE device_id = " << deviceId;
+
+    auto result = m_pDB->fetchResults(query.str());
+    if (result.empty()) {
+        return "";
+    }
+
+    return result[0][0];  // 返回查询到的设备名称
+}
+
+// 通过设备ID和单元ID获取单元名称
+std::string AlarmManager::getUnitNameById(int deviceId, int unitId) {
+    if (!m_pDB) {
+        return "";
+    }
+
+    std::ostringstream query;
+    query << "SELECT unit_name FROM units WHERE device_id = " << deviceId
+        << " AND unit_id = " << unitId;
+
+    auto result = m_pDB->fetchResults(query.str());
+    if (result.empty()) {
+        return "";
+    }
+
+    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::ios::binary);
+    if (!file.is_open()) {
+        std::cerr << "Error opening file!" << std::endl;
+        return false;
+    }
+
+    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;
+        }
+
+        std::stringstream ss(line);
+        std::string cell;
+        AlarmInfo alarm;
+
+        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;
+            }
+            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;
+        }
+    }
+
+    file.close();
+    return true;
+}
+
+// 将报警数据保存到文件
+bool AlarmManager::saveAlarmFile(const std::string& filename) {
+    std::ofstream file(filename);
+
+    if (!file.is_open()) {
+        std::cerr << "打开文件写入失败!" << std::endl;
+        return false;
+    }
+
+    // 写入标题行
+    file << "No,UNIT ID,UNIT NO,Alarm Level,Alarm Code,AlarmID,Alarm Text,Description\n";
+
+    // 写入报警数据
+    int nIndex = 1;
+    for (const auto& pair : m_mapAlarm) {
+        const AlarmInfo& alarm = pair.second;
+        file << nIndex++ << ","
+            << alarm.strUnitID << ","
+            << alarm.strUnitNo << ","
+            << alarm.nAlarmLevel << ","
+            << alarm.nAlarmCode << ","
+            << alarm.nAlarmID << ","
+            << alarm.strAlarmText << ","
+            << alarm.strDescription << "\n";
+    }
+
+    file.close();
+    return true;
+}
+
+// 通过 AlarmID 查询对应的报警信息
+const AlarmInfo* AlarmManager::getAlarmInfoByID(int nAlarmID) const {
+    auto it = m_mapAlarm.find(nAlarmID);
+    if (it != m_mapAlarm.end()) {
+        return &(it->second);
+    }
+    else {
+        std::cerr << "未找到 AlarmID: " << nAlarmID << std::endl;
+        return nullptr;
+    }
+}
+
+// 通过多个 AlarmID 查询对应的报警信息
+std::vector<AlarmInfo> AlarmManager::getAlarmsInfoByIDs(const std::vector<int>& alarmIDs) const {
+    std::vector<AlarmInfo> alarms;
+
+    for (int alarmID : alarmIDs) {
+        auto it = m_mapAlarm.find(alarmID);
+        if (it != m_mapAlarm.end()) {
+            alarms.push_back(it->second);
+        } 
+        else {
+            std::cerr << "未找到 AlarmID: " << alarmID << std::endl;
+        }
+    }
+
+    return alarms;
+}
\ No newline at end of file

--
Gitblit v1.9.3