From d7c88780e1df54f34563d60bd7fa01011d2eef03 Mon Sep 17 00:00:00 2001
From: chenluhua1980 <Chenluhua@qq.com>
Date: 星期一, 26 一月 2026 23:17:17 +0800
Subject: [PATCH] 1.CSVData.cpp 里 unserialize 用了 8*2、125*2,但 serialize 只写 8 + 125 字节。 m_svRawData.insert 的 end 指针是 pszBuffer + 125*2,没有用 index 计算,可能把无效区域一起拷进去。 一旦 size 实际是 133(不是 266),就会直接越界,堆会被破坏,m_svDatas.clear() 在销毁元素时崩。

---
 SourceCode/Bond/Servo/AlarmManager.cpp |  448 +++++++++++++++++++++++++++++++++++--------------------
 1 files changed, 282 insertions(+), 166 deletions(-)

diff --git a/SourceCode/Bond/Servo/AlarmManager.cpp b/SourceCode/Bond/Servo/AlarmManager.cpp
index 2143f34..8cd9acb 100644
--- a/SourceCode/Bond/Servo/AlarmManager.cpp
+++ b/SourceCode/Bond/Servo/AlarmManager.cpp
@@ -1,6 +1,7 @@
-#include "stdafx.h"
+锘�#include "stdafx.h"
 #include "Common.h"
 #include "AlarmManager.h"
+#include "Log.h"
 #include <sstream>
 #include <fstream>
 #include <iostream>
@@ -8,25 +9,26 @@
 #include <ctime>
 #include <iomanip>
 #include <random>
+#include <chrono>
 
-// 常量
+// 甯搁噺
 const std::string DATABASE_FILE = R"(AlarmManager.db)";
 
-// 静态成员初始化
+// 闈欐�佹垚鍛樺垵濮嬪寲
 std::mutex AlarmManager::m_mutex;
 
-// 获取单例实例
+// 鑾峰彇鍗曚緥瀹炰緥
 AlarmManager& AlarmManager::getInstance() {
     static AlarmManager instance;
     return instance;
 }
 
-// 构造函数
+// 鏋勯�犲嚱鏁�
 AlarmManager::AlarmManager() {
 	m_pDB = new BL::SQLiteDatabase();
 }
 
-// 析构函数
+// 鏋愭瀯鍑芥暟
 AlarmManager::~AlarmManager() {
     if (m_pDB != nullptr) {
         delete m_pDB;
@@ -34,7 +36,7 @@
     }
 }
 
-// 初始化报警表
+// 鍒濆鍖栨姤璀﹁〃
 bool AlarmManager::initAlarmTable() {
     char path[MAX_PATH];
     GetModuleFileName(NULL, path, MAX_PATH);
@@ -49,7 +51,7 @@
         throw std::runtime_error("Failed to connect to database.");
     }
 
-    // 创建设备表
+    // 鍒涘缓璁惧琛�
     const std::string createDevicesTableQuery = R"(
         CREATE TABLE IF NOT EXISTS devices (
             device_id TEXT PRIMARY KEY NOT NULL,
@@ -60,7 +62,7 @@
         return false;
     }
 
-    // 创建单元表,设备ID和单元ID组合作为主键
+    // 鍒涘缓鍗曞厓琛紝璁惧ID鍜屽崟鍏僆D缁勫悎浣滀负涓婚敭
     const std::string createUnitsTableQuery = R"(
         CREATE TABLE IF NOT EXISTS units (
             device_id TEXT NOT NULL,
@@ -74,7 +76,7 @@
         return false;
     }
 
-    // 创建报警表,报警记录的alarm_event_id是主键
+    // 鍒涘缓鎶ヨ琛紝鎶ヨ璁板綍鐨刟larm_event_id鏄富閿�
     const std::string createAlarmsTableQuery = R"(
         CREATE TABLE IF NOT EXISTS alarms (
             alarm_event_id INTEGER PRIMARY KEY AUTOINCREMENT,
@@ -93,8 +95,9 @@
         return false;
     }
 
-    // 设备列表 (ID -> 名称)
+    // 璁惧鍒楄〃 (ID -> 鍚嶇О)
     std::vector<std::pair<int, std::string>> devices = {
+        {0, "Software"},
         {EQ_ID_LOADPORT1, EQ_NAME_LOADPORT1},
         {EQ_ID_LOADPORT2, EQ_NAME_LOADPORT2},
         {EQ_ID_LOADPORT3, EQ_NAME_LOADPORT3},
@@ -113,12 +116,12 @@
         {EQ_ID_OPERATOR_REMOVE, EQ_NAME_OPERATOR_REMOVE}
     };
 
-    // 插入 devices 和对应的默认 unit
+    // 鎻掑叆 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 << "')";
@@ -126,7 +129,7 @@
             return false;
         }
 
-        // 插入默认单元 (unit_id = 0, unit_name = device_name)
+        // 鎻掑叆榛樿鍗曞厓 (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 << "')";
@@ -138,14 +141,14 @@
     return true;
 }
 
-// 销毁报警表
+// 閿�姣佹姤璀﹁〃
 void AlarmManager::termAlarmTable() {
     if (m_pDB != nullptr) {
 		m_pDB->disconnect();
     }
 }
 
-// 销毁报警表
+// 閿�姣佹姤璀﹁〃
 bool AlarmManager::destroyAlarmTable() {
 	if (!m_pDB) {
 		throw std::runtime_error("Database connection is not set.");
@@ -154,9 +157,9 @@
 	return m_pDB->executeQuery(dropTableQuery);
 }
 
-// 插入模拟数据
+// 鎻掑叆妯℃嫙鏁版嵁
 void AlarmManager::insertMockData() {
-    // 插入设备数据
+    // 鎻掑叆璁惧鏁版嵁
     for (int i = 1; i <= 3; ++i) {
         std::string deviceName = "Device" + std::to_string(i);
         std::stringstream query;
@@ -166,7 +169,7 @@
         }
     }
 
-    // 插入单元数据
+    // 鎻掑叆鍗曞厓鏁版嵁
     for (int i = 1; i <= 3; ++i) {
         for (int j = 0; j <= 3; ++j) {
             int unitId = j;
@@ -175,8 +178,8 @@
 
             std::stringstream query;
             query << "INSERT INTO units (device_id, unit_id, unit_name) VALUES ('"
-                << deviceId << "', '"   // 插入设备ID,确保是字符串
-                << unitId << "', '"     // 插入单元ID,确保是字符串
+                << deviceId << "', '"   // 鎻掑叆璁惧ID锛岀‘淇濇槸瀛楃涓�
+                << unitId << "', '"     // 鎻掑叆鍗曞厓ID锛岀‘淇濇槸瀛楃涓�
                 << unitName << "');";
 
             if (!m_pDB->executeQuery(query.str())) {
@@ -186,7 +189,7 @@
     }
 
     /*
-    // 初始化随机数生成器
+    // 鍒濆鍖栭殢鏈烘暟鐢熸垚鍣�
     std::random_device rd;
     std::mt19937 gen(rd());
     std::uniform_int_distribution<> deviceDis(1, 3);
@@ -195,7 +198,7 @@
     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));
@@ -205,13 +208,13 @@
     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()];  // 随机报警描述
+        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) "
@@ -226,38 +229,38 @@
     */
 }
 
-// 添加报警信息
+// 娣诲姞鎶ヨ淇℃伅
 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 << "')";      // 结束时间
+            << 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;
@@ -273,23 +276,23 @@
             }
         }
 
-        // 构建插入查询并使用 RETURNING 获取插入后的 alarm_event_id
+        // 鏋勫缓鎻掑叆鏌ヨ骞朵娇鐢� 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
+                // 鎻愬彇骞惰浆鎹� alarm_event_id
                 alarmEventId = std::stoi(results[0][0]);
-                // 将插入的报警数据添加到缓存
+                // 灏嗘彃鍏ョ殑鎶ヨ鏁版嵁娣诲姞鍒扮紦瀛�
                 m_mapCache[alarmEventId] = alarmData;
                 return true;
             }
@@ -303,13 +306,13 @@
     #endif
 }
 
-// 查询所有报警数据
+// 鏌ヨ鎵�鏈夋姤璀︽暟鎹�
 std::vector<AlarmData> AlarmManager::getAllAlarms() {
     if (!m_pDB) {
         return {};
     }
 
-    // 查询所有报警数据(包括设备名称和单元名称)
+    // 鏌ヨ鎵�鏈夋姤璀︽暟鎹紙鍖呮嫭璁惧鍚嶇О鍜屽崟鍏冨悕绉帮級
     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
@@ -319,19 +322,19 @@
 
     auto results = m_pDB->fetchResults(query);
 
-    // 遍历查询结果,填充 AlarmData 结构体
+    // 閬嶅巻鏌ヨ缁撴灉锛屽~鍏� 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];                  // 结束时间
+        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);
     }
@@ -339,7 +342,7 @@
     return alarms;
 }
 
-// 根据报警ID查询报警
+// 鏍规嵁鎶ヨID鏌ヨ鎶ヨ
 std::vector<AlarmData> AlarmManager::getAlarmsById(const std::string& id) {
     if (!m_pDB) {
         return {};
@@ -355,19 +358,19 @@
 
     auto results = m_pDB->fetchResults(query.str());
 
-    // 遍历查询结果,填充 AlarmData 结构体
+    // 閬嶅巻鏌ヨ缁撴灉锛屽~鍏� 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];                  // 结束时间
+        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);
     }
@@ -375,7 +378,7 @@
     return alarms;
 }
 
-// 根据描述查询报警
+// 鏍规嵁鎻忚堪鏌ヨ鎶ヨ
 std::vector<AlarmData> AlarmManager::getAlarmsByDescription(const std::string& description) {
     if (!m_pDB) {
         return {};
@@ -391,19 +394,19 @@
 
     auto results = m_pDB->fetchResults(query.str());
 
-    // 遍历查询结果,填充 AlarmData 结构体
+    // 閬嶅巻鏌ヨ缁撴灉锛屽~鍏� 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];                  // 结束时间
+        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);
     }
@@ -411,7 +414,7 @@
     return alarms;
 }
 
-// 根据时间范围查询报警
+// 鏍规嵁鏃堕棿鑼冨洿鏌ヨ鎶ヨ
 std::vector<AlarmData> AlarmManager::getAlarmsByTimeRange(const std::string& startTime, const std::string& endTime) {
     if (!m_pDB) {
         return {};
@@ -434,19 +437,19 @@
 
     auto results = m_pDB->fetchResults(query.str());
 
-    // 遍历查询结果,填充 AlarmData 结构体
+    // 閬嶅巻鏌ヨ缁撴灉锛屽~鍏� 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];                  // 结束时间
+        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);
     }
@@ -454,7 +457,7 @@
     return alarms;
 }
 
-// 根据ID、开始时间和结束时间查询报警
+// 鏍规嵁ID銆佸紑濮嬫椂闂村拰缁撴潫鏃堕棿鏌ヨ鎶ヨ
 std::vector<AlarmData> AlarmManager::getAlarmsByIdAndTimeRange(const std::string& id, const std::string& startTime, const std::string& endTime) {
     if (!m_pDB) {
         return {};
@@ -477,19 +480,19 @@
 
     auto results = m_pDB->fetchResults(query.str());
 
-    // 遍历查询结果,填充 AlarmData 结构体
+    // 閬嶅巻鏌ヨ缁撴灉锛屽~鍏� 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];                  // 结束时间
+        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);
     }
@@ -497,7 +500,7 @@
     return alarms;
 }
 
-// 分页查询报警数据
+// 鍒嗛〉鏌ヨ鎶ヨ鏁版嵁
 std::vector<AlarmData> AlarmManager::getAlarms(int startPosition, int count) {
     if (!m_pDB) {
         return {};
@@ -513,19 +516,19 @@
 
     auto results = m_pDB->fetchResults(query.str());
 
-    // 遍历查询结果,填充 AlarmData 结构体
+    // 閬嶅巻鏌ヨ缁撴灉锛屽~鍏� 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];                  // 结束时间
+        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);
     }
@@ -533,7 +536,86 @@
     return alarms;
 }
 
-// 筛选报警数据
+// 鑾峰彇褰撳墠鏈粨鏉熺殑鎶ヨ锛坋nd_time 涓虹┖锛夛紝骞跺彲鎸� start_time 鏈�杩� N 灏忔椂杩囨护
+std::vector<AlarmData> AlarmManager::getActiveAlarms(int recentHours /*=12*/) {
+    if (!m_pDB) {
+        return {};
+    }
+
+    // 璁$畻鏃堕棿闃堝�硷細褰撳墠鏃堕棿鍑� recentHours
+    std::string cutoffTime;
+    if (recentHours > 0) {
+        using namespace std::chrono;
+        auto cutoff = system_clock::now() - hours(recentHours);
+        std::time_t t = system_clock::to_time_t(cutoff);
+        std::tm tm {};
+        localtime_s(&tm, &t);
+        char buf[32] = { 0 };
+        std::strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &tm);
+        cutoffTime = buf;
+    }
+
+    std::ostringstream query;
+    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.end_time IS NULL OR a.end_time = ''
+    )";
+    if (!cutoffTime.empty()) {
+        query << " AND a.start_time >= '" << cutoffTime << "'";
+    }
+    query << " ORDER BY a.start_time DESC";
+
+    auto lastErrStr = []() -> std::string {
+        DWORD gle = GetLastError();
+        if (gle == 0) return {};
+        LPSTR buf = nullptr;
+        size_t len = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+            nullptr, gle, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&buf, 0, nullptr);
+        std::string s = (buf && len > 0) ? std::string(buf, len) : "";
+        if (buf) LocalFree(buf);
+        return s;
+    };
+    std::vector<std::vector<std::string>> results;
+    try {
+        results = m_pDB->fetchResults(query.str());
+    }
+    catch (const std::exception& ex) {
+        DWORD gle = GetLastError();
+        auto errStr = lastErrStr();
+        LOGE("<AlarmManager>getActiveAlarms failed: %s, GLE=%lu (%s)", ex.what(), gle, errStr.c_str());
+        return {};
+    }
+    std::vector<AlarmData> alarms;
+    auto toInt = [](const std::string& s) -> int {
+        try {
+            return std::stoi(s);
+        }
+        catch (...) {
+            return 0;
+        }
+    };
+    for (const auto& row : results) {
+        if (row.size() < 9) continue;
+        AlarmData alarmData;
+        alarmData.nId = toInt(row[0]);
+        alarmData.nSeverityLevel = toInt(row[1]);
+        alarmData.nDeviceId = toInt(row[2]);
+        alarmData.nUnitId = toInt(row[3]);
+        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<AlarmData> AlarmManager::getFilteredAlarms(const std::string& keyword, const std::string& startTime, const std::string& endTime, int pageNumber, int pageSize) {
     if (!m_pDB) {
         return {};
@@ -547,7 +629,7 @@
         JOIN units u   ON a.device_id = u.device_id AND a.unit_id = u.unit_id
         WHERE 1=1)";
 
-    // 统一关键字模糊查询
+    // 缁熶竴鍏抽敭瀛楁ā绯婃煡璇�
     if (!keyword.empty()) {
         query << " AND ("
             << "a.id LIKE '%" << keyword << "%' OR "
@@ -557,7 +639,7 @@
             << "a.description LIKE '%" << keyword << "%')";
     }
 
-    // 时间条件
+    // 鏃堕棿鏉′欢
     if (!startTime.empty()) {
         query << " AND a.start_time >= '" << startTime << "'";
     }
@@ -565,26 +647,26 @@
         query << " AND a.end_time <= '" << endTime << "'";
     }
 
-    // 分页设置
+    // 鍒嗛〉璁剧疆
     int nOffset = (pageNumber - 1) * pageSize;
     query << " ORDER BY a.start_time DESC LIMIT " << pageSize << " OFFSET " << nOffset;
 
-    // 查询
+    // 鏌ヨ
     auto results = m_pDB->fetchResults(query.str());
 
-    // 遍历查询结果,填充 AlarmData 结构体
+    // 閬嶅巻鏌ヨ缁撴灉锛屽~鍏� 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];                 // 结束时间
+        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);
     }
@@ -592,7 +674,7 @@
     return alarms;
 }
 
-// 获取符合条件的报警总数
+// 鑾峰彇绗﹀悎鏉′欢鐨勬姤璀︽�绘暟
 int AlarmManager::getTotalAlarmCount(const std::string& keyword, const std::string& startTime, const std::string& endTime) {
     if (!m_pDB) {
         return 0;
@@ -606,7 +688,7 @@
         JOIN units u   ON a.device_id = u.device_id AND a.unit_id = u.unit_id
         WHERE 1=1)";
 
-    // 统一关键字模糊查询
+    // 缁熶竴鍏抽敭瀛楁ā绯婃煡璇�
     if (!keyword.empty()) {
         query << " AND ("
             << "a.id LIKE '%" << keyword << "%' OR "
@@ -616,7 +698,7 @@
             << "a.description LIKE '%" << keyword << "%')";
     }
 
-    // 时间条件
+    // 鏃堕棿鏉′欢
     if (!startTime.empty()) {
         query << " AND a.start_time >= '" << startTime << "'";
     }
@@ -628,7 +710,7 @@
     return (!results.empty() && !results[0].empty()) ? std::stoi(results[0][0]) : 0;
 }
 
-// 更新报警的结束时间
+// 鏇存柊鎶ヨ鐨勭粨鏉熸椂闂�
 bool AlarmManager::updateAlarmEndTime(
     const std::string& id,
     const std::string& severityLevel,
@@ -642,7 +724,7 @@
         return false;
     }
 
-    // 更新报警结束时间
+    // 鏇存柊鎶ヨ缁撴潫鏃堕棿
     std::ostringstream updateQuery;
     updateQuery << "UPDATE alarms SET end_time = '" << newEndTime << "'"
         << " WHERE id = '" << id << "'"
@@ -655,7 +737,7 @@
     return m_pDB->executeQuery(updateQuery.str());
 }
 
-// 清理旧报警数据
+// 娓呯悊鏃ф姤璀︽暟鎹�
 void AlarmManager::cleanOldAlarms(int daysToKeep, const std::string& deviceId, const std::string& unitId) {
     if (!m_pDB) {
         return;
@@ -674,7 +756,7 @@
     m_pDB->executeQuery(query.str());
 }
 
-// 通过设备ID获取设备名称
+// 閫氳繃璁惧ID鑾峰彇璁惧鍚嶇О
 std::string AlarmManager::getDeviceNameById(int deviceId) {
     if (!m_pDB) {
         return "";
@@ -688,10 +770,10 @@
         return "";
     }
 
-    return result[0][0];  // 返回查询到的设备名称
+    return result[0][0];  // 杩斿洖鏌ヨ鍒扮殑璁惧鍚嶇О
 }
 
-// 通过设备ID和单元ID获取单元名称
+// 閫氳繃璁惧ID鍜屽崟鍏僆D鑾峰彇鍗曞厓鍚嶇О
 std::string AlarmManager::getUnitNameById(int deviceId, int unitId) {
     if (!m_pDB) {
         return "";
@@ -706,10 +788,10 @@
         return "";
     }
 
-    return result[0][0];  // 返回查询到的单元名称
+    return result[0][0];  // 杩斿洖鏌ヨ鍒扮殑鍗曞厓鍚嶇О
 }
 
-// 获取最近插入的 alarm_event_id
+// 鑾峰彇鏈�杩戞彃鍏ョ殑 alarm_event_id
 int AlarmManager::getLastInsertId() {
     std::string query = "SELECT last_insert_rowid();";
     auto results = m_pDB->fetchResults(query);
@@ -718,12 +800,12 @@
         return -1;
     }
 
-    // 从查询结果中获取最后插入的 ID
+    // 浠庢煡璇㈢粨鏋滀腑鑾峰彇鏈�鍚庢彃鍏ョ殑 ID
     int lastInsertId = std::stoi(results[0][0]);
     return lastInsertId;
 }
 
-// 通过 alarm_event_id 解除报警(更新结束时间)
+// 閫氳繃 alarm_event_id 瑙i櫎鎶ヨ锛堟洿鏂扮粨鏉熸椂闂达級
 bool AlarmManager::clearAlarmByEventId(int alarmEventId, const std::string& endTime) {
     if (!m_pDB) {
         return false;
@@ -745,7 +827,7 @@
     return result;
 }
 
-// 通过多个属性查找并解除报警(更新结束时间)
+// 閫氳繃澶氫釜灞炴�ф煡鎵惧苟瑙i櫎鎶ヨ锛堟洿鏂扮粨鏉熸椂闂达級
 bool AlarmManager::clearAlarmByAttributes(int nId, int nDeviceId, int nUnitId, const std::string& endTime) {
     if (!m_pDB) {
         return false;
@@ -753,7 +835,7 @@
 
     std::lock_guard<std::mutex> lock(m_mutex);
 
-    // 先在缓存中查找匹配的 alarm_event_id
+    // 鍏堝湪缂撳瓨涓煡鎵惧尮閰嶇殑 alarm_event_id
     int alarmEventId = -1;
     for (AlarmDataMap::const_iterator it = m_mapCache.begin(); it != m_mapCache.end(); ++it) {
         const AlarmData& alarm = it->second;
@@ -766,12 +848,32 @@
         }
     }
 
-    // 如果没找到匹配的记录,则直接返回 false
-    if (alarmEventId == -1) {
-        return false;
-    }
+	// 缂撳瓨鏈懡涓椂锛屼粠鏁版嵁搴撴煡鎵句粛鏈粨鏉熺殑璁板綍锛堝彇鏈�鏂颁竴鏉★級
+	if (alarmEventId == -1) {
+		std::ostringstream querySel;
+		querySel << "SELECT alarm_event_id FROM alarms WHERE "
+			<< "id = " << nId
+			<< " AND device_id = " << nDeviceId
+			<< " AND unit_id = " << nUnitId
+			<< " AND (end_time IS NULL OR end_time = '') "
+			<< "ORDER BY start_time DESC LIMIT 1;";
+		auto results = m_pDB->fetchResults(querySel.str());
+		if (!results.empty() && !results[0].empty()) {
+			try {
+				alarmEventId = std::stoi(results[0][0]);
+			}
+			catch (...) {
+				alarmEventId = -1;
+			}
+		}
+	}
 
-    // 构建 SQL 语句,使用找到的 alarm_event_id 来更新结束时间
+	// 濡傛灉娌℃壘鍒板尮閰嶇殑璁板綍锛屽垯鐩存帴杩斿洖 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());
@@ -782,18 +884,35 @@
     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;
@@ -804,7 +923,6 @@
         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");
@@ -817,7 +935,6 @@
             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;
             }
@@ -826,7 +943,6 @@
             }
         }
         catch (const std::exception& e) {
-            // 捕获并记录解析错误
             std::cerr << "Error parsing line: " << line << " - " << e.what() << std::endl;
             continue;
         }
@@ -836,19 +952,19 @@
     return true;
 }
 
-// 将报警数据保存到文件
+// 灏嗘姤璀︽暟鎹繚瀛樺埌鏂囦欢
 bool AlarmManager::saveAlarmFile(const std::string& filename) {
     std::ofstream file(filename);
 
     if (!file.is_open()) {
-        std::cerr << "打开文件写入失败!" << std::endl;
+        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;
@@ -866,19 +982,19 @@
     return true;
 }
 
-// 通过 AlarmID 查询对应的报警信息
+// 閫氳繃 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;
+        std::cerr << "鏈壘鍒� AlarmID: " << nAlarmID << std::endl;
         return nullptr;
     }
 }
 
-// 通过多个 AlarmID 查询对应的报警信息
+// 閫氳繃澶氫釜 AlarmID 鏌ヨ瀵瑰簲鐨勬姤璀︿俊鎭�
 std::vector<AlarmInfo> AlarmManager::getAlarmsInfoByIDs(const std::vector<int>& alarmIDs) const {
     std::vector<AlarmInfo> alarms;
 
@@ -888,7 +1004,7 @@
             alarms.push_back(it->second);
         } 
         else {
-            std::cerr << "未找到 AlarmID: " << alarmID << std::endl;
+            std::cerr << "鏈壘鍒� AlarmID: " << alarmID << std::endl;
         }
     }
 

--
Gitblit v1.9.3