darker
2025-01-17 700ca509ba853d1615ea3e5c470d2532006f0e1e
1. 添加报警管理器,新增设备名称
已添加2个文件
已修改5个文件
504 ■■■■■ 文件已修改
SourceCode/Bond/Servo/AlarmManager.cpp 289 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/AlarmManager.h 163 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/Servo.cpp 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/Servo.vcxproj 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/Servo.vcxproj.filters 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/ServoDlg.cpp 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/stdafx.h 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/AlarmManager.cpp
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,289 @@
#include "stdafx.h"
#include "AlarmManager.h"
#include <sstream>
#include <iostream>
#include <stdexcept>
#include <ctime>
// å¸¸é‡
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;
        m_pDB = nullptr;
    }
}
// è®¾ç½®æ•°æ®åº“连接
void AlarmManager::setDatabase(BL::Database* db) {
    std::lock_guard<std::mutex> lock(m_mutex);
    m_pDB = db;
}
// åˆå§‹åŒ–报警表
bool AlarmManager::initAlarmTable() {
    char path[MAX_PATH];
    GetModuleFileName(NULL, path, MAX_PATH);
    std::string exePath(path);
    std::string dbFileDir = exePath.substr(0, exePath.find_last_of("\\/")) + "\\DB";
    if (!CreateDirectory(dbFileDir.c_str(), NULL) && ERROR_ALREADY_EXISTS != GetLastError()) {
        throw std::runtime_error("Failed to create database directory.");
    }
    std::string dbFilePath = dbFileDir + "\\" + DATABASE_FILE;
    if (!m_pDB->connect(dbFilePath, true)) {
        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
        )
    )";
    return m_pDB->executeQuery(createTableQuery);
}
// é”€æ¯æŠ¥è­¦è¡¨
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.");
    }
    const std::string dropTableQuery = "DROP TABLE IF EXISTS alarms";
    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.");
    }
    std::ostringstream query;
    query << "INSERT INTO alarms (id, device_name, description, start_time, end_time) VALUES ("
        << "'" << id << "', "
        << "'" << deviceName << "', "
        << "'" << 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, device_name, 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, device_name, 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, device_name, 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, device_name, 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, device_name, 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, device_name, 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& id,
    const std::string& deviceName,
    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, device_name, description, start_time, end_time FROM alarms WHERE 1=1";
    if (!id.empty()) {
        query << " AND id = '" << id << "'";
    }
    if (!deviceName.empty()) {
        query << " AND device_name LIKE '%" << deviceName << "%'";
    }
    if (!description.empty()) {
        query << " AND description LIKE '%" << description << "%'";
    }
    if (!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& 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.");
    }
    std::ostringstream query;
    query << "SELECT COUNT(*) FROM alarms WHERE 1=1";
    if (!id.empty()) {
        query << " AND id = '" << id << "'";
    }
    if (!deviceName.empty()) {
        query << " AND device_name LIKE '%" << deviceName << "%'";
    }
    if (!description.empty()) {
        query << " AND description LIKE '%" << description << "%'";
    }
    if (!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& deviceName, 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 device_name = '" << deviceName << "'"
        << " AND description = '" << description << "'"
        << " AND start_time = '" << startTime << "'";
    return m_pDB->executeQuery(query.str());
}
// æ¸…理旧报警数据
void AlarmManager::cleanOldAlarms(int daysToKeep, const std::string& deviceName) {
    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')";
    if (!deviceName.empty()) {
        query << " AND device_name = '" << deviceName << "'";
    }
    m_pDB->executeQuery(query.str());
}
SourceCode/Bond/Servo/AlarmManager.h
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,163 @@
#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 initAlarmTable();
    /**
     * é”€æ¯æŠ¥è­¦è¡¨
     */
    void termAlarmTable();
    /**
     * é”€æ¯æŠ¥è­¦è¡¨
     * @return æˆåŠŸè¿”å›žtrue,失败返回false
     */
    bool destroyAlarmTable();
    /**
     * æ·»åŠ æŠ¥è­¦
     * @param id æŠ¥è­¦ID
     * @param deviceName è®¾å¤‡åç§°
     * @param description æŠ¥è­¦æè¿°
     * @param startTime æŠ¥è­¦å¼€å§‹æ—¶é—´
     * @param endTime æŠ¥è­¦ç»“束时间
     * @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);
    /**
     * æŸ¥è¯¢æ‰€æœ‰æŠ¥è­¦æ•°æ®
     * @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 id æŠ¥è­¦ID的筛选条件
     * @param deviceName è®¾å¤‡åç§°çš„筛选条件
     * @param description æŠ¥è­¦æè¿°çš„筛选条件
     * @param startTime èµ·å§‹æ—¶é—´ç­›é€‰æ¡ä»¶
     * @param endTime ç»“束时间筛选条件
     * @param pageNumber é¡µç 
     * @param pageSize æ¯é¡µçš„记录数
     * @return åŒ…含筛选后报警数据的二维字符串向量
     */
    std::vector<std::vector<std::string>> getFilteredAlarms(
        const std::string& id,
        const std::string& deviceName,
        const std::string& description,
        const std::string& startTime,
        const std::string& endTime,
        int pageNumber,
        int pageSize);
    /**
     * èŽ·å–ç¬¦åˆæ¡ä»¶çš„æŠ¥è­¦æ€»æ•°
     * @param id æŠ¥è­¦ID的筛选条件
     * @param deviceName è®¾å¤‡åç§°çš„筛选条件
     * @param description æŠ¥è­¦æè¿°çš„筛选条件
     * @param startTime èµ·å§‹æ—¶é—´ç­›é€‰æ¡ä»¶
     * @param endTime ç»“束时间筛选条件
     * @return ç¬¦åˆæ¡ä»¶çš„æŠ¥è­¦æ€»æ•°
     */
    int getTotalAlarmCount(
        const std::string& id,
        const std::string& deviceName,
        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& deviceName, const std::string& description, const std::string& startTime, const std::string& newEndTime);
    /**
     * æ¸…理旧报警
     * @param daysToKeep ä¿ç•™çš„天数
     * @param deviceName è®¾å¤‡åç§°
     */
    void cleanOldAlarms(int daysToKeep = 30, const std::string& deviceName = "");
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
SourceCode/Bond/Servo/Servo.cpp
@@ -6,6 +6,7 @@
#include "Servo.h"
#include "ServoDlg.h"
#include "ServoGraph.h"
#include "AlarmManager.h"
// å£°æ˜Žå…¨å±€å˜é‡ï¼Œç”¨äºŽç®¡ç† GDI+ åˆå§‹åŒ–
ULONG_PTR g_diplusToken;
@@ -101,6 +102,21 @@
    InitGDIPlus();
    // åˆå§‹åŒ–报警管理器
    try {
        if (!AlarmManager::getInstance().initAlarmTable()) {
            AfxMessageBox("初始化报警管理器失败!");
            return FALSE;
        }
    }
    catch (const std::exception& ex) {
        CString errorMsg;
        errorMsg.Format(_T("初始化报警管理器失败:%s"), CString(ex.what()));
        AfxMessageBox(errorMsg, MB_ICONERROR);
        return FALSE;
    }
    CServoDlg dlg;
    m_pMainWnd = &dlg;
    INT_PTR nResponse = dlg.DoModal();
@@ -140,6 +156,9 @@
    // æ¸…理 GDI+
    TermGDIPlus();
    // é”€æ¯æŠ¥è­¦è¡¨
    AlarmManager::getInstance().termAlarmTable();
    return CWinApp::ExitInstance();
}
SourceCode/Bond/Servo/Servo.vcxproj
@@ -115,6 +115,7 @@
      <Optimization>Disabled</Optimization>
      <PreprocessorDefinitions>_WINDOWS;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <SDLCheck>true</SDLCheck>
      <AdditionalIncludeDirectories>.;..;..\DatabaseSDK\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
    </ClCompile>
    <Link>
      <SubSystem>Windows</SubSystem>
@@ -168,6 +169,7 @@
      <IntrinsicFunctions>true</IntrinsicFunctions>
      <PreprocessorDefinitions>_WINDOWS;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <SDLCheck>true</SDLCheck>
      <AdditionalIncludeDirectories>.;..;..\DatabaseSDK\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
    </ClCompile>
    <Link>
      <SubSystem>Windows</SubSystem>
@@ -190,6 +192,7 @@
    <Text Include="ReadMe.txt" />
  </ItemGroup>
  <ItemGroup>
    <ClInclude Include="AlarmManager.h" />
    <ClInclude Include="BlButton.h" />
    <ClInclude Include="Common.h" />
    <ClInclude Include="Configuration.h" />
@@ -209,6 +212,7 @@
    <ClInclude Include="targetver.h" />
  </ItemGroup>
  <ItemGroup>
    <ClCompile Include="AlarmManager.cpp" />
    <ClCompile Include="BlButton.cpp" />
    <ClCompile Include="Configuration.cpp" />
    <ClCompile Include="Context.cpp" />
SourceCode/Bond/Servo/Servo.vcxproj.filters
@@ -69,6 +69,9 @@
    <ClInclude Include="SecsTestDlg.h">
      <Filter>头文件</Filter>
    </ClInclude>
    <ClInclude Include="AlarmManager.h">
      <Filter>头文件</Filter>
    </ClInclude>
  </ItemGroup>
  <ItemGroup>
    <ClCompile Include="Servo.cpp">
@@ -113,6 +116,9 @@
    <ClCompile Include="SecsTestDlg.cpp">
      <Filter>源文件</Filter>
    </ClCompile>
    <ClCompile Include="AlarmManager.cpp">
      <Filter>源文件</Filter>
    </ClCompile>
  </ItemGroup>
  <ItemGroup>
    <ResourceCompile Include="Servo.rc">
SourceCode/Bond/Servo/ServoDlg.cpp
@@ -9,6 +9,7 @@
#include "Common.h"
#include "Log.h"
#include "SecsTestDlg.h"
#include "AlarmManager.h"
#include <chrono>
#include <thread>
#include <cmath>
SourceCode/Bond/Servo/stdafx.h
@@ -33,10 +33,32 @@
#include <afxcontrolbars.h>     // åŠŸèƒ½åŒºå’ŒæŽ§ä»¶æ¡çš„ MFC æ”¯æŒ
// GDI+
#include <gdiplus.h>
using namespace Gdiplus;
// æ•°æ®åº“模块
#include "..\DatabaseSDK\include\Database.h"
#include "..\DatabaseSDK\include\MySQLDatabase.h"
#include "..\DatabaseSDK\include\SQLiteDatabase.h"
#if defined(_WIN64)
#if defined(_DEBUG)
#pragma comment(lib, "..\\DatabaseSDK\\lib\\x64\\Debug\\DatabaseEx.lib")
#else
#pragma comment(lib, "..\\DatabaseSDK\\lib\\x64\\Release\\DatabaseEx.lib")
#endif
#else
#if defined(_DEBUG)
#pragma comment(lib, "..\\DatabaseSDK\\lib\\Win32\\Debug\\DatabaseEx.lib")
#else
#pragma comment(lib, "..\\DatabaseSDK\\lib\\Win32\\Release\\DatabaseEx.lib")
#endif
#endif
#include "..\RxWindows1.0\include\RxWindowsLib.h"
#include "..\HSMSSDK\Include\HSMSSDK.h"