2025-11-03 16:49:13 +08:00
|
|
|
|
#ifndef ALARMEVENTUTILS_H
|
|
|
|
|
|
#define ALARMEVENTUTILS_H
|
|
|
|
|
|
|
2025-11-06 18:54:50 +08:00
|
|
|
|
#include <QUrl>
|
2025-11-03 16:49:13 +08:00
|
|
|
|
#include "alarmEventGlobal.h"
|
|
|
|
|
|
|
2025-11-06 18:54:50 +08:00
|
|
|
|
///////------structs-----
|
|
|
|
|
|
//RabbitMQ链接配置
|
|
|
|
|
|
struct RabbitMQConfig
|
|
|
|
|
|
{
|
|
|
|
|
|
QString host;
|
|
|
|
|
|
int port;
|
|
|
|
|
|
QString username;
|
|
|
|
|
|
QString password;
|
|
|
|
|
|
QString virtualHost;
|
|
|
|
|
|
QString exchangeName;
|
|
|
|
|
|
QString queueName;
|
|
|
|
|
|
QString routingKey;
|
|
|
|
|
|
int reconnectInterval; //重连间隔(毫秒)
|
|
|
|
|
|
int heartbeat;
|
|
|
|
|
|
bool autoAck;
|
|
|
|
|
|
|
|
|
|
|
|
RabbitMQConfig()
|
|
|
|
|
|
: port(5672)
|
2025-11-07 17:33:04 +08:00
|
|
|
|
, reconnectInterval(3000)
|
2025-11-06 18:54:50 +08:00
|
|
|
|
, heartbeat(60)
|
|
|
|
|
|
, autoAck(true)
|
|
|
|
|
|
{}
|
|
|
|
|
|
|
|
|
|
|
|
bool isValid() const
|
|
|
|
|
|
{
|
|
|
|
|
|
if(host.isEmpty())
|
|
|
|
|
|
{
|
|
|
|
|
|
qWarning() << "RabbitMQ host is empty";
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
if(port <= 0 || port > 65535)
|
|
|
|
|
|
{
|
|
|
|
|
|
qWarning() << "RabbitMQ port is invalid: " << port;
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
if(username.isEmpty())
|
|
|
|
|
|
{
|
|
|
|
|
|
qWarning() << "RabbitMQ username is empty";
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
if(exchangeName.isEmpty())
|
|
|
|
|
|
{
|
|
|
|
|
|
qWarning() << "RabbitMQ exchange name is empty";
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
if(queueName.isEmpty())
|
|
|
|
|
|
{
|
|
|
|
|
|
qWarning() << "RabbitMQ queue name is empty";
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
if(routingKey.isEmpty())
|
|
|
|
|
|
{
|
|
|
|
|
|
qWarning() << "RabbitMQ routingKey is empty";
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (reconnectInterval <= 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
qWarning() << "RabbitMQ reconnect interval is invalid:" << reconnectInterval;
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
//历史数据服务配置
|
|
|
|
|
|
struct HistoricalConfig
|
|
|
|
|
|
{
|
|
|
|
|
|
QUrl baseUrl;
|
|
|
|
|
|
int timeout; //请求超时(毫秒)
|
|
|
|
|
|
QVariantMap requestHeaders;
|
|
|
|
|
|
int maxRetries; //最大重试次数
|
|
|
|
|
|
int retryInterval; //重试间隔
|
|
|
|
|
|
|
|
|
|
|
|
HistoricalConfig()
|
|
|
|
|
|
: timeout(3000)
|
|
|
|
|
|
, maxRetries(3)
|
|
|
|
|
|
, retryInterval(1000)
|
|
|
|
|
|
{}
|
|
|
|
|
|
|
|
|
|
|
|
bool isValid() const
|
|
|
|
|
|
{
|
|
|
|
|
|
if(!baseUrl.isValid())
|
|
|
|
|
|
{
|
|
|
|
|
|
qWarning() << "Historical service base URL is invalid:" << baseUrl.errorString();
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
if(timeout <= 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
qWarning() << "Historical service timeout is invalid:" << timeout;
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
if(maxRetries < 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
qWarning() << "Historical service max retries is invalid:" << maxRetries;
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
if(retryInterval <= 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
qWarning() << "Historical service retry interval is invalid:" << retryInterval;
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
//缓存配置
|
|
|
|
|
|
struct CacheConfig
|
|
|
|
|
|
{
|
|
|
|
|
|
int maxSize; //缓存事件最大数量
|
|
|
|
|
|
int cleanupInterval; //清理间隔(毫秒)
|
|
|
|
|
|
bool enableStatistics; //是否统计
|
|
|
|
|
|
|
|
|
|
|
|
CacheConfig()
|
|
|
|
|
|
: maxSize(10000)
|
|
|
|
|
|
, cleanupInterval(60000) //1分钟
|
|
|
|
|
|
, enableStatistics(false)
|
|
|
|
|
|
{}
|
|
|
|
|
|
|
|
|
|
|
|
bool isValid() const
|
|
|
|
|
|
{
|
|
|
|
|
|
if(maxSize <= 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
qWarning() << "Cache max size is invalid:" << maxSize;
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
if(cleanupInterval < 0 )
|
|
|
|
|
|
{
|
|
|
|
|
|
qWarning() << "Cache cleanup interval is invalid:" << cleanupInterval;
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
//统一服务配置
|
|
|
|
|
|
struct ServiceConfig
|
|
|
|
|
|
{
|
|
|
|
|
|
RabbitMQConfig rabbitMQConfig;
|
|
|
|
|
|
HistoricalConfig historicalConfig;
|
|
|
|
|
|
CacheConfig cacheConfig;
|
|
|
|
|
|
|
|
|
|
|
|
ServiceConfig() {}
|
|
|
|
|
|
|
|
|
|
|
|
bool isValid() const
|
|
|
|
|
|
{
|
|
|
|
|
|
return rabbitMQConfig.isValid() && historicalConfig.isValid() && cacheConfig.isValid();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//从JSON对象加载配置
|
|
|
|
|
|
static ServiceConfig fromJson(const QJsonObject& json);
|
|
|
|
|
|
//转化为JSON对象
|
|
|
|
|
|
QJsonObject toJson() const;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
///////------enums-----
|
|
|
|
|
|
//服务状态
|
|
|
|
|
|
enum class ServiceStatus
|
|
|
|
|
|
{
|
|
|
|
|
|
Uninitialized,//未初始化
|
2025-11-07 17:33:04 +08:00
|
|
|
|
//Initialized, //已初始化
|
2025-11-06 18:54:50 +08:00
|
|
|
|
Disconnected, //未连接
|
|
|
|
|
|
Connecting, //连接中
|
|
|
|
|
|
Connected, //已连接
|
|
|
|
|
|
Error, //错误状态
|
|
|
|
|
|
Reconnecting //重连中
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
//连接状态
|
|
|
|
|
|
enum class ConnectionStatus
|
|
|
|
|
|
{
|
|
|
|
|
|
Disconnected,
|
|
|
|
|
|
Connecting,
|
|
|
|
|
|
Connected
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
//错误严重程度
|
|
|
|
|
|
enum class ErrorSeverity
|
|
|
|
|
|
{
|
|
|
|
|
|
Info, //信息
|
|
|
|
|
|
Warning, //警告
|
|
|
|
|
|
Error, //错误
|
|
|
|
|
|
Critical //严重错误
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
//消息处理结果
|
|
|
|
|
|
enum class MessageHandleResult
|
|
|
|
|
|
{
|
|
|
|
|
|
Success,
|
|
|
|
|
|
ParseError, //解析错误
|
|
|
|
|
|
ValidationError, //验证错误
|
|
|
|
|
|
Duplicate //重复消息
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
//注册为元类型,用于信号槽的chuandi
|
|
|
|
|
|
Q_DECLARE_METATYPE(ServiceStatus)
|
|
|
|
|
|
Q_DECLARE_METATYPE(ConnectionStatus)
|
|
|
|
|
|
Q_DECLARE_METATYPE(ErrorSeverity)
|
|
|
|
|
|
Q_DECLARE_METATYPE(MessageHandleResult)
|
|
|
|
|
|
|
|
|
|
|
|
///////------classes-----
|
2025-11-03 16:49:13 +08:00
|
|
|
|
class AlarmEventDataFilter
|
|
|
|
|
|
{
|
|
|
|
|
|
public:
|
|
|
|
|
|
AlarmEventDataFilter();
|
|
|
|
|
|
|
2025-11-18 14:26:29 +08:00
|
|
|
|
void setTimeRange(const QDateTime& start, const QDateTime& end) {m_beginTime = start; m_endTime = end;}
|
|
|
|
|
|
QDateTime beginTime() {return m_beginTime;}
|
|
|
|
|
|
QDateTime endTime() {return m_endTime;}
|
2025-11-03 16:49:13 +08:00
|
|
|
|
void setStationFilter(const QString& station) {m_station = station;}
|
|
|
|
|
|
void setBayFilter(const QString& bay) {m_bay = bay;}
|
|
|
|
|
|
void setTypeFilter(int type) {m_type = type;}
|
|
|
|
|
|
void setSeverityFilter(const QString& severity) {m_severity = severity;}
|
|
|
|
|
|
void setDescriptionFilter(const QString& description) {m_description = description;}
|
|
|
|
|
|
void setConfirmStatusFilter(int status) {m_status = status;}
|
2025-11-25 11:54:16 +08:00
|
|
|
|
int confirmStatus() {return m_status;}
|
2025-11-03 16:49:13 +08:00
|
|
|
|
|
|
|
|
|
|
bool matches(const EventData& event);
|
|
|
|
|
|
void clear();
|
|
|
|
|
|
QVector<EventData> apply(const QVector<EventData>& events);
|
|
|
|
|
|
|
|
|
|
|
|
private:
|
2025-11-17 10:13:02 +08:00
|
|
|
|
void reset();
|
2025-11-03 16:49:13 +08:00
|
|
|
|
bool isEmpty();
|
|
|
|
|
|
|
2025-11-18 14:26:29 +08:00
|
|
|
|
QDateTime m_beginTime;
|
2025-11-03 16:49:13 +08:00
|
|
|
|
QDateTime m_endTime;
|
|
|
|
|
|
QString m_station;
|
|
|
|
|
|
QString m_bay;
|
|
|
|
|
|
int m_type;
|
|
|
|
|
|
QString m_severity;
|
|
|
|
|
|
QString m_description;
|
|
|
|
|
|
int m_status;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2025-11-06 18:54:50 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 数据缓存
|
|
|
|
|
|
*
|
|
|
|
|
|
* 数据缓存的主要作用:
|
|
|
|
|
|
* 批量存储:当数据需要做本地存储时,可以先存入缓存,达到一定数量后批量进行存储,从而减少数据库的频繁操作
|
|
|
|
|
|
* 快速访问:按条件查询数据时,先从缓存中查找,减少数据库或网络操作
|
|
|
|
|
|
* 数据去重:避免存储重复数据
|
|
|
|
|
|
* 清理策略:例如采用LRU,自动清理最久未使用的数据,从而控制内存内使用
|
|
|
|
|
|
*
|
|
|
|
|
|
* 若有以上场景,可以按需扩展该类,目前暂无场景
|
|
|
|
|
|
*/
|
2025-11-03 16:49:13 +08:00
|
|
|
|
class AlarmEventCache
|
|
|
|
|
|
{
|
|
|
|
|
|
public:
|
|
|
|
|
|
AlarmEventCache();
|
|
|
|
|
|
|
|
|
|
|
|
void setMaxSize(int maxSize);
|
|
|
|
|
|
int getMaxSize() const {return m_maxSize;}
|
|
|
|
|
|
|
|
|
|
|
|
void addEvent(const EventData& event);
|
|
|
|
|
|
void clear();
|
|
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
void trimToSize();
|
|
|
|
|
|
|
|
|
|
|
|
int m_maxSize;
|
|
|
|
|
|
QVector<EventData> m_events;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
#endif
|