From 9370dd2497683084f8c0ae958f8be5dec34bd2f1 Mon Sep 17 00:00:00 2001
From: mrDarker <mr.darker@163.com>
Date: 星期一, 01 九月 2025 21:53:51 +0800
Subject: [PATCH] 1. JobDataS多了一次Last Glass Flag
---
SourceCode/Bond/Servo/AlarmManager.cpp | 765 +++++++++++++++++++++++++++++++++++++++++++++++++++------
1 files changed, 675 insertions(+), 90 deletions(-)
diff --git a/SourceCode/Bond/Servo/AlarmManager.cpp b/SourceCode/Bond/Servo/AlarmManager.cpp
index 7864235..0ed76e5 100644
--- a/SourceCode/Bond/Servo/AlarmManager.cpp
+++ b/SourceCode/Bond/Servo/AlarmManager.cpp
@@ -1,9 +1,12 @@
#include "stdafx.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 +33,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 +48,47 @@
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)
+ )
+ )";
+ return m_pDB->executeQuery(createAlarmsTableQuery);
}
// 销毁报警表
@@ -80,113 +107,391 @@
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(
+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,
@@ -194,63 +499,107 @@
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 (!id.empty()) {
+ query << " AND a.id = '" << id << "'";
+ }
+ 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 description LIKE '%" << description << "%'";
+ query << " AND a.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 << "'";
}
+ // 分页设置
int offset = (pageNumber - 1) * pageSize;
- query << " ORDER BY start_time DESC LIMIT " << pageSize << " OFFSET " << offset;
+ query << " ORDER BY a.start_time DESC LIMIT " << pageSize << " OFFSET " << offset;
- 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& severityLevel,
const std::string& deviceName,
+ const std::string& unitName,
const std::string& description,
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 << "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 << "'";
+ query << " AND a.id = '" << id << "'";
+ }
+ if (!severityLevel.empty()) {
+ query << " AND a.severity_level = '" << severityLevel << "'";
}
if (!deviceName.empty()) {
- query << " AND device_name LIKE '%" << deviceName << "%'";
+ query << " AND d.device_name LIKE '%" << deviceName << "%'";
+ }
+ if (!unitName.empty()) {
+ query << " AND u.unit_name LIKE '%" << unitName << "%'";
}
if (!description.empty()) {
- query << " AND description LIKE '%" << description << "%'";
+ query << " AND a.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 +607,268 @@
}
// 更新报警的结束时间
-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::string line;
+ bool first_line = true;
+
+ if (!file.is_open()) {
+ std::cerr << "Error opening file!" << std::endl;
+ return false;
+ }
+
+ while (std::getline(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