From be5908615aa5f61c478cf3fa3823dc07c9b1d70f Mon Sep 17 00:00:00 2001
From: LAPTOP-T815PCOQ\25526 <mr.liuyang@126.com>
Date: 星期四, 12 十二月 2024 18:08:34 +0800
Subject: [PATCH] 1. 添加报警表 2. 读取数据库中的报警表显示在界面上,或添加报警数据
---
SourceCode/Bond/BondEq/DBManager/AlarmManager.cpp | 232 +++++++++++++++++++++++++++++
SourceCode/Bond/BondEq/DBManager/AlarmManager.h | 142 +++++++++++++++++
SourceCode/Bond/BondEq/stdafx.h | 1
SourceCode/Bond/BondEq/BondEqDlg.cpp | 16 ++
SourceCode/Bond/BondEq/BondEq.vcxproj | 2
SourceCode/Bond/BondEq/CPageAlarm.cpp | 32 +++
6 files changed, 424 insertions(+), 1 deletions(-)
diff --git a/SourceCode/Bond/BondEq/BondEq.vcxproj b/SourceCode/Bond/BondEq/BondEq.vcxproj
index c76af03..a43d4f8 100644
--- a/SourceCode/Bond/BondEq/BondEq.vcxproj
+++ b/SourceCode/Bond/BondEq/BondEq.vcxproj
@@ -220,6 +220,7 @@
<ClInclude Include="Common.h" />
<ClInclude Include="Configuration.h" />
<ClInclude Include="CPanelProject.h" />
+ <ClInclude Include="DBManager\AlarmManager.h" />
<ClInclude Include="DBManager\AxisManager.h" />
<ClInclude Include="DBManager\SystemLogManager.h" />
<ClInclude Include="DBManager\UserManager.h" />
@@ -294,6 +295,7 @@
<ClCompile Include="CProjectPageRemoteEqs.cpp" />
<ClCompile Include="Configuration.cpp" />
<ClCompile Include="CPanelProject.cpp" />
+ <ClCompile Include="DBManager\AlarmManager.cpp" />
<ClCompile Include="DBManager\AxisManager.cpp" />
<ClCompile Include="DBManager\SystemLogManager.cpp" />
<ClCompile Include="DBManager\UserManager.cpp" />
diff --git a/SourceCode/Bond/BondEq/BondEqDlg.cpp b/SourceCode/Bond/BondEq/BondEqDlg.cpp
index 9aa2398..f381744 100644
--- a/SourceCode/Bond/BondEq/BondEqDlg.cpp
+++ b/SourceCode/Bond/BondEq/BondEqDlg.cpp
@@ -229,6 +229,22 @@
return FALSE;
}
+ // 初始化报警模块
+ AlarmManager& alarmManager = AlarmManager::getInstance();
+ alarmManager.setDatabase(db.get());
+ try {
+ if (!alarmManager.initializeAlarmTable()) {
+ AfxMessageBox("初始化报警模块失败!");
+ return FALSE;
+ }
+ }
+ catch (const std::exception& ex) {
+ CString errorMsg;
+ errorMsg.Format(_T("初始化报警模块失败:%s"), CString(ex.what()));
+ AfxMessageBox(errorMsg, MB_ICONERROR);
+ return FALSE;
+ }
+
// 设置配方文件夹路径
RecipeManager& recipeManager = RecipeManager::getInstance();
std::string strRecipePath = CToolUnits::getCurrentExePath() + _T("\\Recipe");
diff --git a/SourceCode/Bond/BondEq/CPageAlarm.cpp b/SourceCode/Bond/BondEq/CPageAlarm.cpp
index 0d76752..d84faef 100644
--- a/SourceCode/Bond/BondEq/CPageAlarm.cpp
+++ b/SourceCode/Bond/BondEq/CPageAlarm.cpp
@@ -158,6 +158,8 @@
CAlarmMonitor* pMonitor = (CAlarmMonitor*)theApp.m_model.getBonder().GetComponent("警告信息");
pMonitor->Lock();
+
+#if 0
std::map<int, CAlarm*>& alarmings = pMonitor->getAlarmingMap();
std::list< CAlarm*>& alarms = pMonitor->getAlarmRecords();
@@ -167,6 +169,20 @@
for (auto item : alarms) {
AddAlarm(pMonitor, item);
}
+#else
+ // 获取报警数据
+ auto vecData = AlarmManager::getInstance().getAllAlarms();
+
+ // 填充数据
+ CListCtrl* pListCtrl = (CListCtrl*)GetDlgItem(IDC_LIST_ALARM);
+ for (auto item : vecData) {
+ pListCtrl->InsertItem(0, _T(""));
+ pListCtrl->SetItemText(0, 1, item[0].c_str());
+ pListCtrl->SetItemText(0, 2, item[1].c_str());
+ pListCtrl->SetItemText(0, 3, item[2].c_str());
+ pListCtrl->SetItemText(0, 4, item[3].c_str());
+ }
+#endif // 0
pMonitor->Unlock();
}
@@ -186,6 +202,12 @@
if (pAlarm->getOffTime() > 0) {
pListCtrl->SetItemText(0, 4, CToolUnits::timeToString2(pAlarm->getOffTime()).c_str());
}
+
+ AlarmManager::getInstance().addAlarm(
+ std::to_string(pAlarm->getId()).c_str(),
+ pMonitor->getAlarmText(pAlarm->getId()),
+ CToolUnits::timeToString2(pAlarm->getOnTime()).c_str(),
+ CToolUnits::timeToString2(pAlarm->getOffTime()).c_str());
}
void CPageAlarm::UpdateAlarm(CAlarmMonitor* pMonitor, CAlarm* pAlarm)
@@ -198,6 +220,12 @@
if (pListCtrl->GetItemData(i) == (DWORD_PTR)pAlarm) {
if (pAlarm->getOffTime() > 0) {
pListCtrl->SetItemText(i, 4, CToolUnits::timeToString2(pAlarm->getOffTime()).c_str());
+
+ AlarmManager::getInstance().updateAlarmEndTime(
+ std::to_string(pAlarm->getId()).c_str(),
+ pMonitor->getAlarmText(pAlarm->getId()),
+ CToolUnits::timeToString2(pAlarm->getOnTime()).c_str(),
+ CToolUnits::timeToString2(pAlarm->getOffTime()).c_str());
}
}
}
@@ -208,7 +236,9 @@
CListCtrl* pListCtrl = (CListCtrl*)GetDlgItem(IDC_LIST_ALARM);
for (int i = 0; i < pListCtrl->GetItemCount(); i++) {
CAlarm* pAlarm = (CAlarm*)pListCtrl->GetItemData(i);
- pAlarm->release();
+ if (pAlarm != nullptr) {
+ pAlarm->release();
+ }
}
return CDialogEx::DestroyWindow();
diff --git a/SourceCode/Bond/BondEq/DBManager/AlarmManager.cpp b/SourceCode/Bond/BondEq/DBManager/AlarmManager.cpp
new file mode 100644
index 0000000..042dce9
--- /dev/null
+++ b/SourceCode/Bond/BondEq/DBManager/AlarmManager.cpp
@@ -0,0 +1,232 @@
+#include "stdafx.h"
+#include <sstream>
+#include <iostream>
+#include <stdexcept>
+#include <ctime>
+
+// 静态成员初始化
+std::mutex AlarmManager::m_mutex;
+
+// 获取单例实例
+AlarmManager& AlarmManager::getInstance() {
+ static AlarmManager instance;
+ return instance;
+}
+
+// 构造函数
+AlarmManager::AlarmManager() : m_pDB(nullptr) {}
+
+// 析构函数
+AlarmManager::~AlarmManager() {
+ m_pDB = nullptr;
+}
+
+// 设置数据库连接
+void AlarmManager::setDatabase(BL::Database* db) {
+ std::lock_guard<std::mutex> lock(m_mutex);
+ m_pDB = db;
+}
+
+// 初始化报警表
+bool AlarmManager::initializeAlarmTable() {
+ if (!m_pDB) {
+ throw std::runtime_error("Database connection is not set.");
+ }
+
+ const std::string createTableQuery = R"(
+ CREATE TABLE IF NOT EXISTS alarms (
+ id TEXT NOT NULL,
+ description TEXT NOT NULL,
+ start_time DATETIME NOT NULL,
+ end_time DATETIME NOT NULL
+ )
+ )";
+
+ return m_pDB->executeQuery(createTableQuery);
+}
+
+// 添加报警
+bool AlarmManager::addAlarm(const std::string& id, const std::string& description, const std::string& startTime, const std::string& endTime) {
+ if (!m_pDB) {
+ throw std::runtime_error("Database connection is not set.");
+ }
+
+ std::ostringstream query;
+ query << "INSERT INTO alarms (id, description, start_time, end_time) VALUES ("
+ << "'" << id << "', "
+ << "'" << description << "', "
+ << "'" << startTime << "', "
+ << "'" << endTime << "')";
+
+ std::lock_guard<std::mutex> lock(m_mutex);
+ return m_pDB->executeQuery(query.str());
+}
+
+// 查询所有报警数据
+std::vector<std::vector<std::string>> AlarmManager::getAllAlarms() {
+ if (!m_pDB) {
+ throw std::runtime_error("Database connection is not set.");
+ }
+
+ const std::string query = "SELECT id, description, start_time, end_time FROM alarms";
+ return m_pDB->fetchResults(query);
+}
+
+// 根据报警ID查询报警
+std::vector<std::vector<std::string>> AlarmManager::getAlarmsById(const std::string& id) {
+ if (!m_pDB) {
+ throw std::runtime_error("Database connection is not set.");
+ }
+
+ std::ostringstream query;
+ query << "SELECT id, description, start_time, end_time FROM alarms WHERE id = '" << id << "'";
+ return m_pDB->fetchResults(query.str());
+}
+
+// 根据描述查询报警
+std::vector<std::vector<std::string>> AlarmManager::getAlarmsByDescription(const std::string& description) {
+ if (!m_pDB) {
+ throw std::runtime_error("Database connection is not set.");
+ }
+
+ std::ostringstream query;
+ query << "SELECT id, description, start_time, end_time FROM alarms WHERE description LIKE '%" << description << "%'";
+ return m_pDB->fetchResults(query.str());
+}
+
+// 根据时间范围查询报警
+std::vector<std::vector<std::string>> AlarmManager::getAlarmsByTimeRange(
+ const std::string& startTime, const std::string& endTime) {
+
+ if (!m_pDB) {
+ throw std::runtime_error("Database connection is not set.");
+ }
+
+ std::ostringstream query;
+ query << "SELECT id, description, start_time, end_time FROM alarms WHERE 1=1";
+
+ if (!startTime.empty()) {
+ query << " AND start_time >= '" << startTime << "'";
+ }
+ if (!endTime.empty()) {
+ query << " AND end_time <= '" << endTime << "'";
+ }
+
+ return m_pDB->fetchResults(query.str());
+}
+
+// 根据ID、开始时间和结束时间查询报警
+std::vector<std::vector<std::string>> 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.");
+ }
+
+ std::ostringstream query;
+ query << "SELECT id, description, start_time, end_time FROM alarms WHERE id = '" << id << "'";
+
+ if (!startTime.empty()) {
+ query << " AND start_time >= '" << startTime << "'";
+ }
+ if (!endTime.empty()) {
+ query << " AND end_time <= '" << endTime << "'";
+ }
+
+ return m_pDB->fetchResults(query.str());
+}
+
+// 分页查询报警数据
+std::vector<std::vector<std::string>> AlarmManager::getAlarms(int startPosition, int count) {
+ if (!m_pDB) {
+ throw std::runtime_error("Database connection is not set.");
+ }
+
+ std::ostringstream query;
+ query << "SELECT id, description, start_time, end_time FROM alarms LIMIT " << count << " OFFSET " << startPosition;
+ return m_pDB->fetchResults(query.str());
+}
+
+// 筛选报警数据
+std::vector<std::vector<std::string>> AlarmManager::getFilteredAlarms(
+ const std::string& description,
+ const std::string& startTime,
+ const std::string& endTime,
+ int pageNumber,
+ int pageSize) {
+
+ if (!m_pDB) {
+ throw std::runtime_error("Database connection is not set.");
+ }
+
+ std::ostringstream query;
+ query << "SELECT id, description, start_time, end_time FROM alarms WHERE 1=1";
+
+ if (!description.empty()) {
+ query << " AND description LIKE '%" << description << "%'";
+ }
+ if (!startTime.empty()) {
+ query << " AND start_time >= '" << startTime << "'";
+ }
+ if (!endTime.empty()) {
+ query << " AND end_time <= '" << endTime << "'";
+ }
+
+ int offset = (pageNumber - 1) * pageSize;
+ query << " ORDER BY start_time DESC LIMIT " << pageSize << " OFFSET " << offset;
+
+ return m_pDB->fetchResults(query.str());
+}
+
+// 获取符合条件的报警总数
+int AlarmManager::getTotalAlarmCount(
+ const std::string& description,
+ const std::string& startTime,
+ const std::string& endTime) {
+
+ if (!m_pDB) {
+ throw std::runtime_error("Database connection is not set.");
+ }
+
+ std::ostringstream query;
+ query << "SELECT COUNT(*) FROM alarms WHERE 1=1";
+
+ if (!description.empty()) {
+ query << " AND description LIKE '%" << description << "%'";
+ }
+ if (!startTime.empty()) {
+ query << " AND start_time >= '" << startTime << "'";
+ }
+ if (!endTime.empty()) {
+ query << " AND end_time <= '" << endTime << "'";
+ }
+
+ auto results = m_pDB->fetchResults(query.str());
+ return (!results.empty() && !results[0].empty()) ? std::stoi(results[0][0]) : 0;
+}
+
+// 更新报警的结束时间
+bool AlarmManager::updateAlarmEndTime(const std::string& id, const std::string& description, const std::string& startTime, const std::string& newEndTime) {
+ if (!m_pDB) {
+ throw std::runtime_error("Database connection is not set.");
+ }
+
+ std::ostringstream query;
+ query << "UPDATE alarms SET end_time = '" << newEndTime << "'"
+ << " WHERE id = '" << id << "'"
+ << " AND description = '" << description << "'"
+ << " AND start_time = '" << startTime << "'";
+
+ return m_pDB->executeQuery(query.str());
+}
+
+// 清理旧报警数据
+void AlarmManager::cleanOldAlarms(int daysToKeep) {
+ if (!m_pDB) {
+ throw std::runtime_error("Database connection is not set.");
+ }
+
+ std::ostringstream query;
+ query << "DELETE FROM alarms WHERE end_time < datetime('now', '-" << daysToKeep << " days')";
+ m_pDB->executeQuery(query.str());
+}
diff --git a/SourceCode/Bond/BondEq/DBManager/AlarmManager.h b/SourceCode/Bond/BondEq/DBManager/AlarmManager.h
new file mode 100644
index 0000000..bbe3e3a
--- /dev/null
+++ b/SourceCode/Bond/BondEq/DBManager/AlarmManager.h
@@ -0,0 +1,142 @@
+#ifndef ALARM_MANAGER_H
+#define ALARM_MANAGER_H
+
+#include <string>
+#include <vector>
+#include <mutex>
+#include "Database.h"
+
+class AlarmManager {
+public:
+ /**
+ * 获取单例实例
+ * @return AlarmManager实例的引用
+ */
+ static AlarmManager& getInstance();
+
+ /**
+ * 设置数据库连接
+ * @param db 数据库连接的指针
+ */
+ void setDatabase(BL::Database* db);
+
+ /**
+ * 初始化报警表
+ * @return 成功返回true,失败返回false
+ */
+ bool initializeAlarmTable();
+
+ /**
+ * 添加报警
+ * @param id 报警ID
+ * @param description 报警描述
+ * @param startTime 报警开始时间
+ * @param endTime 报警结束时间
+ * @return 成功返回true,失败返回false
+ */
+ bool addAlarm(const std::string& id, const std::string& description, const std::string& startTime, const std::string& endTime);
+
+ /**
+ * 查询所有报警数据
+ * @return 包含所有报警数据的二维字符串向量
+ */
+ std::vector<std::vector<std::string>> getAllAlarms();
+
+ /**
+ * 根据报警ID查询报警
+ * @param id 报警ID
+ * @return 包含筛选后报警数据的二维字符串向量
+ */
+ std::vector<std::vector<std::string>> getAlarmsById(const std::string& id);
+
+ /**
+ * 根据描述查询报警
+ * @param description 报警描述的筛选条件
+ * @return 包含筛选后报警数据的二维字符串向量
+ */
+ std::vector<std::vector<std::string>> getAlarmsByDescription(const std::string& description);
+
+ /**
+ * 根据时间范围查询报警
+ * @param startTime 起始时间
+ * @param endTime 结束时间
+ * @return 包含查询结果的二维字符串向量
+ */
+ std::vector<std::vector<std::string>> getAlarmsByTimeRange(
+ const std::string& startTime, const std::string& endTime);
+
+ /**
+ * 根据ID和时间范围查询报警
+ * @param id 报警ID
+ * @param startTime 起始时间
+ * @param endTime 结束时间
+ * @return 包含查询结果的二维字符串向量
+ */
+ std::vector<std::vector<std::string>> getAlarmsByIdAndTimeRange(
+ const std::string& id, const std::string& startTime, const std::string& endTime);
+
+ /**
+ * 获取报警数据
+ * @param startPosition 起始位置
+ * @param count 获取的记录数量
+ * @return 包含报警数据的二维字符串向量
+ */
+ std::vector<std::vector<std::string>> getAlarms(int startPosition, int count);
+
+ /**
+ * 获取筛选后的报警数据
+ * @param description 报警描述的筛选条件
+ * @param startTime 起始时间筛选条件
+ * @param endTime 结束时间筛选条件
+ * @param pageNumber 页码
+ * @param pageSize 每页的记录数
+ * @return 包含筛选后报警数据的二维字符串向量
+ */
+ std::vector<std::vector<std::string>> getFilteredAlarms(
+ const std::string& description,
+ const std::string& startTime,
+ const std::string& endTime,
+ int pageNumber,
+ int pageSize);
+
+ /**
+ * 获取符合条件的报警总数
+ * @param description 报警描述的筛选条件
+ * @param startTime 起始时间筛选条件
+ * @param endTime 结束时间筛选条件
+ * @return 符合条件的报警总数
+ */
+ int getTotalAlarmCount(
+ const std::string& description,
+ const std::string& startTime,
+ const std::string& endTime);
+
+ /**
+ * 更新报警结束时间
+ * @param id 报警ID
+ * @param description 报警描述
+ * @param startTime 报警开始时间
+ * @param newEndTime 新的报警结束时间
+ * @return 成功返回true,失败返回false
+ */
+ bool updateAlarmEndTime(const std::string& id, const std::string& description, const std::string& startTime, const std::string& newEndTime);
+
+ /**
+ * 清理旧报警
+ * @param daysToKeep 保留的天数
+ */
+ void cleanOldAlarms(int daysToKeep = 30);
+
+private:
+ AlarmManager();
+ ~AlarmManager();
+
+ // 禁止拷贝和赋值
+ AlarmManager(const AlarmManager&) = delete;
+ AlarmManager& operator=(const AlarmManager&) = delete;
+
+ BL::Database* m_pDB;
+ static std::mutex m_mutex;
+};
+
+#endif // ALARM_MANAGER_H
\ No newline at end of file
diff --git a/SourceCode/Bond/BondEq/stdafx.h b/SourceCode/Bond/BondEq/stdafx.h
index ed3a40f..95c78f8 100644
--- a/SourceCode/Bond/BondEq/stdafx.h
+++ b/SourceCode/Bond/BondEq/stdafx.h
@@ -51,6 +51,7 @@
#include "UserManager.h"
#include "RecipeManager.h"
#include "SystemLogManager.h"
+#include "AlarmManager.h"
// 控件样式
static UINT g_nGridFixCellColor = RGB(144, 200, 246);
--
Gitblit v1.9.3