Darker
2025-02-27 2633facbfec13267389edde5c29d6e66645c2356
1. 报警管理类添加两个表,并且修改了字段,完善修改后的函数
已修改5个文件
771 ■■■■ 文件已修改
SourceCode/Bond/Servo/AlarmDlg.cpp 156 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/AlarmDlg.h 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/AlarmManager.cpp 503 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/AlarmManager.h 95 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/Servo.cpp 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/AlarmDlg.cpp
@@ -5,8 +5,8 @@
#include "Servo.h"
#include "afxdialogex.h"
#include "AlarmDlg.h"
#include "AlarmManager.h"
#include "Common.h"
#include <iomanip>
#define PAGE_SIZE                        10
#define PAGE_BACKGROUND_COLOR            RGB(252, 252, 255)
@@ -22,7 +22,9 @@
    m_hbrBkgnd = nullptr;
    m_pObserver = nullptr;
    m_strEqName = "";
    m_nSeverityLevel = 0;
    m_strDeviceName = "";
    m_strUnitName = "";
    m_strKeyword = "";
    m_nCurPage = 0;
    m_nTotalPages = 0;
@@ -60,20 +62,25 @@
                        AlarmManager& alarmManager = AlarmManager::getInstance();
                        // 从 pStep 获取需要的参数,假设这些值是从 pStep 中获取的
                        std::string id = std::to_string(pStep->getAlarmId());
                        std::string deviceName = std::to_string(pStep->getUnitId());
                        std::string description = pStep->getText();
                        std::string startTime = "2025-02-25 10:00";
                        std::string endTime = "2025-02-25 12:00";
                        AlarmData alarmData;
                        alarmData.nId = pStep->getAlarmId();
                        alarmData.nSeverityLevel = pStep->getAlarmLevel();
                        alarmData.nDeviceId = pStep->getAlarmDev();
                        alarmData.nUnitId = pStep->getUnitId();
                        alarmData.strDeviceName = alarmManager.getDeviceNameById(alarmData.nDeviceId);
                        alarmData.strUnitName = alarmManager.getUnitNameById(alarmData.nDeviceId, alarmData.nUnitId);
                        alarmData.strDescription = pStep->getText();
                        alarmData.strStartTime = getCurrentTimeString();
                        alarmData.strEndTime = "2000-01-01 00:00";
                        // 插入列表控件
                        CListCtrl* pListCtrl = (CListCtrl*)GetDlgItem(IDC_LIST_ALARM);
                        if (pListCtrl != nullptr) {
                            InsertAlarmData(pListCtrl, id.c_str(), deviceName.c_str(), description.c_str(), startTime.c_str(), endTime.c_str());
                            InsertAlarmData(pListCtrl, alarmData);
                        }
                        // 调用 addAlarm 添加新的 Alarm
                        bool result = alarmManager.addAlarm(id, deviceName, description, startTime, endTime);
                        // 添加新的 Alarm 数据
                        bool result = alarmManager.addAlarm(alarmData);
                        if (result) {
                            LOGI("<CAlarmDlg> Alarm added successfully!");
                        }
@@ -84,7 +91,6 @@
                }
            }
        pAny->release();
        }, [&]() -> void {
            // onComplete
@@ -93,8 +99,8 @@
            pThrowable->printf();
        });
        //theApp.m_model.getObservable()->observeOn(pRxWindows->mainThread())
        //    ->subscribe(m_pObserver);
        theApp.m_model.getObservable()->observeOn(pRxWindows->mainThread())
            ->subscribe(m_pObserver);
    }
}
@@ -110,57 +116,15 @@
void CAlarmDlg::LoadAlarms()
{
    //CAlarmMonitor* pMonitor = (CAlarmMonitor*)theApp.m_model.getBonder().GetComponent(ALARM_MONITOR);
    // 当前正在发生的报警
    //pMonitor->Lock();
    //std::map<int, CAlarm*>& alarmings = pMonitor->getAlarmingMap();
    //for (auto item : alarmings) {
    //    AddAlarm(pMonitor, item.second);
    //}
    //pMonitor->Unlock();
    // 刷新历史报警数据
    m_nCurPage = 1;
    UpdatePageData();
}
//void CAlarmDlg::AddAlarm(CAlarmMonitor* pMonitor, CAlarm* pAlarm)
//{
//    if (pMonitor == nullptr) {
//        pMonitor = (CAlarmMonitor*)theApp.m_model.getBonder().GetComponent(ALARM_MONITOR);
//    }
//    CListCtrl* pListCtrl = (CListCtrl*)GetDlgItem(IDC_LIST_ALARM);
//    pListCtrl->InsertItem(0, _T(""));
//    pListCtrl->SetItemData(0, (DWORD_PTR)pAlarm);
//    pAlarm->addRef();
//    pListCtrl->SetItemText(0, 1, std::to_string(pAlarm->getId()).c_str());
//    pListCtrl->SetItemText(0, 2, pMonitor->getAlarmText(pAlarm->getId()));
//    pListCtrl->SetItemText(0, 3, CToolUnits::timeToString2(pAlarm->getOnTime()).c_str());
//    if (pAlarm->getOffTime() > 0) {
//        pListCtrl->SetItemText(0, 4, CToolUnits::timeToString2(pAlarm->getOffTime()).c_str());
//    }
//}
//void CAlarmDlg::UpdateAlarm(CAlarmMonitor* pMonitor, CAlarm* pAlarm)
//{
//    if (pMonitor == nullptr) {
//        pMonitor = (CAlarmMonitor*)theApp.m_model.getBonder().GetComponent(ALARM_MONITOR);
//    }
//    CListCtrl* pListCtrl = (CListCtrl*)GetDlgItem(IDC_LIST_ALARM);
//    for (int i = 0; i < pListCtrl->GetItemCount(); i++) {
//        if (pListCtrl->GetItemData(i) == (DWORD_PTR)pAlarm) {
//            if (pAlarm->getOffTime() > 0) {
//                pListCtrl->SetItemText(i, 4, CToolUnits::timeToString2(pAlarm->getOffTime()).c_str());
//            }
//        }
//    }
//}
void CAlarmDlg::UpdatePageData()
{
    // 根据过滤条件加载数据,提供描述和时间范围查询
    auto vecData = AlarmManager::getInstance().getFilteredAlarms("", m_strEqName, m_strKeyword, m_szTimeStart, m_szTimeEnd, m_nCurPage, PAGE_SIZE);
    auto vecData = AlarmManager::getInstance().getFilteredAlarms("", "", m_strDeviceName, m_strUnitName, m_strKeyword, m_szTimeStart, m_szTimeEnd, m_nCurPage, PAGE_SIZE);
    // 填充数据到控件
    CListCtrl* pListCtrl = (CListCtrl*)GetDlgItem(IDC_LIST_ALARM);
@@ -182,23 +146,29 @@
    GetDlgItem(IDC_BUTTON_NEXT_PAGE)->EnableWindow(m_nCurPage < m_nTotalPages);
}
void CAlarmDlg::FillDataToListCtrl(CListCtrl* pListCtrl, const std::vector<std::vector<std::string>>& vecData)
void CAlarmDlg::FillDataToListCtrl(CListCtrl* pListCtrl, const std::vector<AlarmData>& vecData)
{
    // 清空当前CListCtrl中的所有项
    pListCtrl->DeleteAllItems();
    // 遍历数据并插入到CListCtrl中
    for (const auto& item : vecData) {
    for (const auto& alarm : vecData) {
        int nItem = pListCtrl->InsertItem(pListCtrl->GetItemCount(), _T(""));    // 插入新行
        pListCtrl->SetItemText(nItem, 1, item[0].c_str());                        // 设置第一列的文本(ID)
        pListCtrl->SetItemText(nItem, 2, item[1].c_str());                        // 设置第二列的文本(设备名称)
        pListCtrl->SetItemText(nItem, 3, item[2].c_str());                        // 设置第三列的文本(描述)
        pListCtrl->SetItemText(nItem, 4, item[3].c_str());                        // 设置第四列的文本(开始时间)
        pListCtrl->SetItemText(nItem, 5, item[4].c_str());                        // 设置第四列的文本(解除时间)
        CString str;
        // 设置列内容
        str.Format(_T("%d"), alarm.nId);
        pListCtrl->SetItemText(nItem, 1, str);                                          // 报警ID
        str.Format(_T("%d"), alarm.nSeverityLevel);
        pListCtrl->SetItemText(nItem, 2, str);                                          // 等级
        pListCtrl->SetItemText(nItem, 3, alarm.strDeviceName.c_str());                // 设备名称
        pListCtrl->SetItemText(nItem, 4, alarm.strUnitName.c_str());                  // 单元名称
        pListCtrl->SetItemText(nItem, 5, alarm.strDescription.c_str());               // 描述
        pListCtrl->SetItemText(nItem, 6, alarm.strStartTime.c_str());                 // 开始时间
        pListCtrl->SetItemText(nItem, 7, alarm.strEndTime.c_str());                   // 结束时间
    }
}
void CAlarmDlg::InsertAlarmData(CListCtrl* pListCtrl, const CString& alarmId, const CString& deviceName, const CString& description, const CString& startTime, const CString& endTime)
void CAlarmDlg::InsertAlarmData(CListCtrl* pListCtrl, const AlarmData& alarmData)
{
    int nRowCount = pListCtrl->GetItemCount();
    if (nRowCount >= PAGE_SIZE) {
@@ -206,19 +176,31 @@
    }
    int nNewItem = pListCtrl->InsertItem(0, _T(""));
    pListCtrl->SetItemText(nNewItem, 1, alarmId);       // 警告ID
    pListCtrl->SetItemText(nNewItem, 2, deviceName);    // 设备名称
    pListCtrl->SetItemText(nNewItem, 3, description);   // 描述
    pListCtrl->SetItemText(nNewItem, 4, startTime);     // 发生时间
    pListCtrl->SetItemText(nNewItem, 5, endTime);       // 解除时间
    // 重新调整列宽
    pListCtrl->SetColumnWidth(0, LVSCW_AUTOSIZE);
    pListCtrl->SetColumnWidth(1, LVSCW_AUTOSIZE);
    pListCtrl->SetColumnWidth(2, LVSCW_AUTOSIZE);
    pListCtrl->SetColumnWidth(3, LVSCW_AUTOSIZE);
    pListCtrl->SetColumnWidth(4, LVSCW_AUTOSIZE);
    pListCtrl->SetColumnWidth(5, LVSCW_AUTOSIZE);
    // 设置每一列的数据
    CString str;
    str.Format(_T("%d"), alarmData.nId);
    pListCtrl->SetItemText(nNewItem, 1, str);                                            // 报警ID
    str.Format(_T("%d"), alarmData.nSeverityLevel);
    pListCtrl->SetItemText(nNewItem, 2, str);                                            // 等级
    pListCtrl->SetItemText(nNewItem, 3, alarmData.strDeviceName.c_str());               // 设备名称
    pListCtrl->SetItemText(nNewItem, 4, alarmData.strUnitName.c_str());                 // 单元名称
    pListCtrl->SetItemText(nNewItem, 5, alarmData.strDescription.c_str());              // 描述
    pListCtrl->SetItemText(nNewItem, 6, alarmData.strStartTime.c_str());                // 开始时间
    pListCtrl->SetItemText(nNewItem, 7, alarmData.strEndTime.c_str());                  // 结束时间
}
std::string CAlarmDlg::getCurrentTimeString()
{
    auto now = std::chrono::system_clock::now();
    auto time_t_now = std::chrono::system_clock::to_time_t(now);
    std::tm tm_now = {};
    localtime_s(&tm_now, &time_t_now);
    std::stringstream ss;
    ss << std::put_time(&tm_now, "%Y-%m-%d %H:%M:%S");
    return ss.str();
}
void CAlarmDlg::DoDataExchange(CDataExchange* pDX)
@@ -272,13 +254,15 @@
    ListView_SetImageList(pListCtrl->GetSafeHwnd(), imageList, LVSIL_SMALL);
    pListCtrl->InsertColumn(0, _T(""), LVCFMT_RIGHT, 0);
    pListCtrl->InsertColumn(1, _T("警告ID"), LVCFMT_LEFT, 50);
    pListCtrl->InsertColumn(2, _T("设备名称"), LVCFMT_LEFT, 120);
    pListCtrl->InsertColumn(3, _T("描述"), LVCFMT_LEFT, 280);
    pListCtrl->InsertColumn(4, _T("发生时间"), LVCFMT_LEFT, 180);
    pListCtrl->InsertColumn(5, _T("解除时间"), LVCFMT_LEFT, 180);
    pListCtrl->InsertColumn(2, _T("报警等级"), LVCFMT_LEFT, 50);
    pListCtrl->InsertColumn(3, _T("设备名称"), LVCFMT_LEFT, 120);
    pListCtrl->InsertColumn(4, _T("单元名称"), LVCFMT_LEFT, 120);
    pListCtrl->InsertColumn(5, _T("描述"), LVCFMT_LEFT, 180);
    pListCtrl->InsertColumn(6, _T("发生时间"), LVCFMT_LEFT, 180);
    pListCtrl->InsertColumn(7, _T("解除时间"), LVCFMT_LEFT, 180);
    // 计算总页数
    int totalRecords = AlarmManager::getInstance().getTotalAlarmCount("", m_strEqName, m_strKeyword, m_szTimeStart, m_szTimeEnd);
    int totalRecords = AlarmManager::getInstance().getTotalAlarmCount("", "", m_strDeviceName, m_strUnitName, m_strKeyword, m_szTimeStart, m_szTimeEnd);
    m_nTotalPages = (totalRecords + PAGE_SIZE - 1) / PAGE_SIZE;
    m_nCurPage = 1;
@@ -291,14 +275,6 @@
BOOL CAlarmDlg::DestroyWindow()
{
    //CListCtrl* pListCtrl = (CListCtrl*)GetDlgItem(IDC_LIST_ALARM);
    //for (int i = 0; i < pListCtrl->GetItemCount(); i++) {
    //    CAlarm* pAlarm = (CAlarm*)pListCtrl->GetItemData(i);
    //    if (pAlarm != nullptr) {
    //        pAlarm->release();
    //    }
    //}
    return CDialogEx::DestroyWindow();
}
@@ -400,7 +376,7 @@
    }
    // 计算总页数
    int totalRecords = AlarmManager::getInstance().getTotalAlarmCount("", m_strEqName, m_strKeyword, m_szTimeStart, m_szTimeEnd);
    int totalRecords = AlarmManager::getInstance().getTotalAlarmCount("", "", m_strDeviceName, m_strUnitName, m_strKeyword, m_szTimeStart, m_szTimeEnd);
    m_nTotalPages = (totalRecords + PAGE_SIZE - 1) / PAGE_SIZE;
    m_nCurPage = 1;
SourceCode/Bond/Servo/AlarmDlg.h
@@ -1,7 +1,6 @@
#pragma once
#include "afxdialogex.h"
#include <vector>
#include <string>
#include "AlarmManager.h"
// CAlarmDlg 对话框
@@ -17,20 +16,21 @@
    void InitRxWindow();
    void Resize();
    void LoadAlarms();
    //void AddAlarm(CAlarmMonitor* pMonitor, CAlarm* pAlarm);
    //void UpdateAlarm(CAlarmMonitor* pMonitor, CAlarm* pAlarm);
    void UpdatePageData();
    void UpdatePageControls();
    void FillDataToListCtrl(CListCtrl* pListCtrl, const std::vector<std::vector<std::string>>& vecData);
    void InsertAlarmData(CListCtrl* pListCtrl, const CString& alarmId, const CString& deviceName, const CString& description, const CString& startTime, const CString& endTime);
    void FillDataToListCtrl(CListCtrl* pListCtrl, const std::vector<AlarmData>& vecData);
    void InsertAlarmData(CListCtrl* pListCtrl, const AlarmData& alarmData);
    std::string getCurrentTimeString();
private:
    COLORREF m_crBkgnd;
    HBRUSH m_hbrBkgnd;
    IObserver* m_pObserver;
    // 关键字
    std::string m_strEqName;
    // 搜索关键字
    int m_nSeverityLevel;
    std::string m_strDeviceName;
    std::string m_strUnitName;
    std::string m_strKeyword;
    // 页码
SourceCode/Bond/Servo/AlarmManager.cpp
@@ -5,6 +5,8 @@
#include <iostream>
#include <stdexcept>
#include <ctime>
#include <iomanip>
#include <random>
// 常量
const std::string DATABASE_FILE = R"(AlarmManager.db)";
@@ -52,17 +54,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 NOT NULL,
            FOREIGN KEY (device_id) REFERENCES devices(device_id),
            FOREIGN KEY (unit_id) REFERENCES units(unit_id)
        )
    )";
    return m_pDB->executeQuery(createAlarmsTableQuery);
}
// 销毁报警表
@@ -81,113 +113,334 @@
    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 = 1; j <= 3; ++j) {
            int unitId = j;
            std::string deviceId = std::to_string(i);
            std::string unitName = "Unit" + std::to_string(j);
            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) {
    if (!m_pDB) {
        return false;
    }
    // 构建插入查询
    std::ostringstream query;
    query << "INSERT INTO alarms (id, severity_level, device_id, unit_id, description, start_time, end_time) VALUES ("
        << alarmData.nId << ", "              // 错误码
        << alarmData.nSeverityLevel << ", "   // 报警等级
        << alarmData.nDeviceId << ", "        // 设备ID
        << alarmData.nUnitId << ", '"         // 单元ID
        << alarmData.strDescription << "', '" // 描述
        << alarmData.strStartTime << "', '"   // 开始时间
        << alarmData.strEndTime << "')";      // 结束时间
    // 使用锁保护多线程安全
    std::lock_guard<std::mutex> lock(m_mutex);
    return m_pDB->executeQuery(query.str());
}
// 查询所有报警数据
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,
@@ -195,63 +448,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 << "'";
        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 << "'";
    }
    // 分页设置
    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());
@@ -259,36 +556,86 @@
}
// 更新报警的结束时间
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];  // 返回查询到的单元名称
}
// 读取报警文件
bool AlarmManager::readAlarmFile(const std::string& filename) {
    std::ifstream file(filename);
SourceCode/Bond/Servo/AlarmManager.h
@@ -17,6 +17,18 @@
    std::string strDescription;
};
struct AlarmData {
    int nId;                       // 错误码
    int nSeverityLevel;            // 报警等级
    int nDeviceId;                 // 设备ID
    int nUnitId;                   // 单元ID
    std::string strDeviceName;     // 设备名称
    std::string strUnitName;       // 单元名称
    std::string strDescription;    // 描述
    std::string strStartTime;      // 开始时间
    std::string strEndTime;        // 结束时间
};
using AlarmMap = std::unordered_map<int, AlarmInfo>;
class AlarmManager {
@@ -51,77 +63,80 @@
    bool destroyAlarmTable();
    /**
    * 插入模拟数据
    */
    void insertMockData();
    /**
     * 添加报警
     * @param id 报警ID
     * @param deviceName 设备名称
     * @param description 报警描述
     * @param startTime 报警开始时间
     * @param endTime 报警结束时间
     * @param alarmData 报警数据的结构体
     * @return 成功返回true,失败返回false
     */
    bool addAlarm(const std::string& id, const std::string& deviceName, const std::string& description, const std::string& startTime, const std::string& endTime);
    bool addAlarm(const AlarmData& alarmData);
    /**
     * 查询所有报警数据
     * @return 包含所有报警数据的二维字符串向量
     * @return 包含所有报警数据的结构体
     */
    std::vector<std::vector<std::string>> getAllAlarms();
    std::vector<AlarmData> getAllAlarms();
    /**
     * 根据报警ID查询报警
     * @param id 报警ID
     * @return 包含筛选后报警数据的二维字符串向量
     * @return 包含筛选后报警数据的结构体
     */
    std::vector<std::vector<std::string>> getAlarmsById(const std::string& id);
    std::vector<AlarmData> getAlarmsById(const std::string& id);
    /**
     * 根据描述查询报警
     * @param description 报警描述的筛选条件
     * @return 包含筛选后报警数据的二维字符串向量
     * @return 包含筛选后报警数据的结构体
     */
    std::vector<std::vector<std::string>> getAlarmsByDescription(const std::string& description);
    std::vector<AlarmData> getAlarmsByDescription(const std::string& description);
    /**
     * 根据时间范围查询报警
     * @param startTime 起始时间
     * @param endTime 结束时间
     * @return 包含查询结果的二维字符串向量
     * @return 包含查询结果的报警数据
     */
    std::vector<std::vector<std::string>> getAlarmsByTimeRange(
        const std::string& startTime, const std::string& endTime);
    std::vector<AlarmData> getAlarmsByTimeRange(const std::string& startTime, const std::string& endTime);
    /**
    * 根据ID和时间范围查询报警
     * @param id 报警ID
     * @param startTime 起始时间
     * @param endTime 结束时间
     * @return 包含查询结果的二维字符串向量
     * @return 包含查询结果的报警数据
     */
    std::vector<std::vector<std::string>> getAlarmsByIdAndTimeRange(
        const std::string& id, const std::string& startTime, const std::string& endTime);
    std::vector<AlarmData> getAlarmsByIdAndTimeRange(const std::string& id, const std::string& startTime, const std::string& endTime);
    /**
     * 获取报警数据
     * @param startPosition 起始位置
     * @param count 获取的记录数量
     * @return 包含报警数据的二维字符串向量
     * @return 包含查询结果的报警数据
     */
    std::vector<std::vector<std::string>> getAlarms(int startPosition, int count);
    std::vector<AlarmData> getAlarms(int startPosition, int count);
    /**
     * 获取筛选后的报警数据
     * @param id 报警ID的筛选条件
     * @param severityLevel 报警等级筛选条件
     * @param deviceName 设备名称的筛选条件
     * @param unitName 单元名称的筛选条件
     * @param description 报警描述的筛选条件
     * @param startTime 起始时间筛选条件
     * @param endTime 结束时间筛选条件
     * @param pageNumber 页码
     * @param pageSize 每页的记录数
     * @return 包含筛选后报警数据的二维字符串向量
     * @return 包含查询结果的报警数据
     */
    std::vector<std::vector<std::string>> getFilteredAlarms(
    std::vector<AlarmData> 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,
@@ -131,7 +146,9 @@
    /**
     * 获取符合条件的报警总数
     * @param id 报警ID的筛选条件
     * @param severityLevel 报警等级筛选条件
     * @param deviceName 设备名称的筛选条件
     * @param unitName 单元名称的筛选条件
     * @param description 报警描述的筛选条件
     * @param startTime 起始时间筛选条件
     * @param endTime 结束时间筛选条件
@@ -139,7 +156,9 @@
     */
    int 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);
@@ -147,19 +166,45 @@
    /**
     * 更新报警结束时间
     * @param id 报警ID
     * @param severityLevel 报警等级筛选条件
     * @param deviceId 设备ID
     * @param unitId 单元ID
     * @param description 报警描述
     * @param startTime 报警开始时间
     * @param newEndTime 新的报警结束时间
     * @return 成功返回true,失败返回false
     */
    bool updateAlarmEndTime(const std::string& id, const std::string& deviceName, const std::string& description, const std::string& startTime, const std::string& newEndTime);
    bool 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);
    /**
     * 清理旧报警
     * @param daysToKeep 保留的天数
     * @param deviceName 设备名称
     * @param deviceId 设备ID
     * @param unitId 单元ID
     */
    void cleanOldAlarms(int daysToKeep = 30, const std::string& deviceName = "");
    void cleanOldAlarms(int daysToKeep = 30, const std::string& deviceId = "", const std::string& unitId = "");
    /**
    * 通过设备ID获取设备名称
    * @param deviceId 设备ID
    * @return 成功返回设备名称,失败返回空
    */
    std::string getDeviceNameById(int deviceId);
    /**
    * 通过设备ID和单元ID获取单元名称
    * @param deviceId 设备ID
    * @param unitId 单元ID
    * @return 成功返回单元名称,失败返回空
    */
    std::string getUnitNameById(int deviceId, int unitId);
    /**
     * 读取报警文件
SourceCode/Bond/Servo/Servo.cpp
@@ -116,6 +116,7 @@
        AfxMessageBox(errorMsg, MB_ICONERROR);
        return FALSE;
    }
    //AlarmManager::getInstance().insertMockData();
    // 初始化SECS运行设置管理库