From 6a68212a9a69ab3a79e914fc0fcb07f5eb8b0dfa Mon Sep 17 00:00:00 2001 From: duanshengchao <519970194@qq.com> Date: Tue, 9 Dec 2025 20:31:08 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E5=AE=8C=E6=88=90=E4=BA=8B=E4=BB=B6?= =?UTF-8?q?=E7=A1=AE=E8=AE=A4=E7=9A=84=E5=85=A8=E9=83=A8=E6=B5=81=E7=A8=8B?= =?UTF-8?q?=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/alarmEventDataService.h | 7 +-- include/alarmEventDataView.h | 3 +- source/alarmEventDataService.cpp | 77 +++++++++++++++++++------------- source/alarmEventDataView.cpp | 63 ++++++++++++++++++++++---- 4 files changed, 107 insertions(+), 43 deletions(-) diff --git a/include/alarmEventDataService.h b/include/alarmEventDataService.h index dabd216..a69d649 100644 --- a/include/alarmEventDataService.h +++ b/include/alarmEventDataService.h @@ -26,13 +26,13 @@ public: void start(); void stop(); void queryHistoricalEvents(const QDateTime& startTime, const QDateTime& endTime, int confirmStatus = -1); - void confirmEvents(const QStringList& uuids); + void confirmEvents(const QStringList& uuids, QVariant context = QVariant()); signals: void realTimeEventReceived(const EventData& event); void historicalQueryError(const QString& msg); void historicalQueryData(const QList& events); - void confirmEventsResult(bool success, const QString& mesg, const QStringList& successUuids); + void confirmEventsResult(bool success, const QString& mesg, const QStringList& successUuids, QVariant context); private slots: void onRabbitMQConnected(); @@ -58,7 +58,6 @@ private: void cancelReconnect(); //实时信息处理 MessageHandleResult processMessage(const QAmqpMessage& message); - EventData parseEventFromMessage(const QByteArray& data, QString& errorString); bool validateEvent(const EventData& event); //历史数据处理 QUrl bulidHistoricalQueryUrl(const QDateTime& startTime, const QDateTime& endTime, int confirmStatus); @@ -89,6 +88,8 @@ private: QSettings* m_settings; QString m_settingsFile; bool m_isVaildSettingsFile; + + quint64 m_currentRequestId; }; #endif diff --git a/include/alarmEventDataView.h b/include/alarmEventDataView.h index 73135c0..ca69668 100644 --- a/include/alarmEventDataView.h +++ b/include/alarmEventDataView.h @@ -83,7 +83,7 @@ private slots: void onRealTimeEventReceived(const EventData& event); void onHistoricalEventsReceived(const QList& events); void onHistoricalQueryError(const QString&); - void onConfirmEventsResult(bool success, const QString& mesg, const QStringList& successUuids); + void onConfirmEventsResult(bool success, const QString& mesg, const QStringList& successUuids, QVariant context); private: void iniHeaderData(); @@ -104,6 +104,7 @@ private: AlarmDataMode m_dataMode; AlarmEventDataFilter m_currentFilter; int m_maxRealTimeEvents; + quint64 m_lastRequestId; //请求ID,在实例化的不同对象调用某同一个对象(此处是AlarmEventDataService)的某个函数并触发其emit某个signal进而触发自身的某个slot时做判别用 //QMap> m_confirmedEvents; }; diff --git a/source/alarmEventDataService.cpp b/source/alarmEventDataService.cpp index 3d2560b..415079e 100644 --- a/source/alarmEventDataService.cpp +++ b/source/alarmEventDataService.cpp @@ -28,6 +28,7 @@ AlarmEventDataService::AlarmEventDataService() , m_amqpExchange(nullptr) , m_reconnectAttempts(0) , m_maxReconnectAttempts(10) + , m_currentRequestId(1) { m_reconnectTimer = new QTimer(this); m_reconnectTimer->setSingleShot(true); @@ -113,8 +114,10 @@ void AlarmEventDataService::queryHistoricalEvents(const QDateTime& startTime, co }); } -void AlarmEventDataService::confirmEvents(const QStringList& uuids) +void AlarmEventDataService::confirmEvents(const QStringList& uuids, QVariant context) { + m_currentRequestId = context.toULongLong(); + QUrl url = buildConfirmEventsUrl(); if(!url.isValid()) return; @@ -200,42 +203,37 @@ void AlarmEventDataService::cancelReconnect() } MessageHandleResult AlarmEventDataService::processMessage(const QAmqpMessage& message) -{ - QString errorString; - EventData event = parseEventFromMessage(message.payload(), errorString); - - if(!errorString.isEmpty()) - return MessageHandleResult::ParseError; - - if(!validateEvent(event)) - return MessageHandleResult::ValidationError; - - emit realTimeEventReceived(event); - return MessageHandleResult::Success; -} - -EventData AlarmEventDataService::parseEventFromMessage(const QByteArray& data, QString& errorString) { QJsonParseError parseError; - QJsonDocument doc = QJsonDocument::fromJson(data, &parseError); + QJsonDocument doc = QJsonDocument::fromJson(message.payload(), &parseError); if(parseError.error != QJsonParseError::NoError) { - errorString = QString("JSON parse error: %1 at offset %2") - .arg(parseError.errorString()) - .arg(parseError.offset); - return EventData(); + // QString errorString = QString("JSON parse error: %1 at offset %2") + // .arg(parseError.errorString()) + // .arg(parseError.offset); + + return MessageHandleResult::ParseError; } if(!doc.isObject()) { - errorString = "JSON document is not an object"; - return EventData(); + //QString errorString = "JSON document is not an object"; + return MessageHandleResult::ValidationError; } QJsonObject obj = doc.object(); - EventData event = EventData::fromJson(obj); - return event; + //加一层判断,当前实时报警信息和确认同步信息都走该接口,并且没有做消息层面的标识,因此先从消息体结构来判断 + if(obj.contains("event_uuid") && obj.contains("event") && obj.contains("type")) + { + EventData event = EventData::fromJson(obj); + if(!validateEvent(event)) + return MessageHandleResult::ValidationError; + + emit realTimeEventReceived(event); + } + + return MessageHandleResult::Success; } bool AlarmEventDataService::validateEvent(const EventData& event) @@ -414,6 +412,8 @@ void AlarmEventDataService::onConfirmEventsRequestFinished(QNetworkReply* reply) if(parseError.error == QJsonParseError::NoError && doc.isObject()) { QJsonObject docObj = doc.object(); + //int code = docObj.value("code").toInt(); + QString msg = docObj.value("msg").toString(); QJsonValue dataValue = docObj.value("data"); if(dataValue.isObject()) { @@ -428,19 +428,34 @@ void AlarmEventDataService::onConfirmEventsRequestFinished(QNetworkReply* reply) successUuids.append(value.toString()); } - emit confirmEventsResult(true, "", successUuids); - return; + emit confirmEventsResult(true, "", successUuids, m_currentRequestId); + } + else + { + QString errorMsg = QString("ConfirmEvents reply error, msg: %1").arg(msg); + LOG_ERROR("Http", errorMsg); + emit confirmEventsResult(false, QString("确认事件失败(%1)").arg(msg), successUuids, m_currentRequestId); } } + else + { + QString errorMsg = QString("ConfirmEvents reply Json is not object: %1").arg(QString(data)); + LOG_ERROR("Http", errorMsg); + emit confirmEventsResult(false, QString("确认事件失败(Json is not object)"), successUuids, m_currentRequestId); + } + } + else + { + QString errorMsg = QString("ConfirmEvents reply Json parse error: %1").arg(parseError.errorString()); + LOG_ERROR("Http", errorMsg); + emit confirmEventsResult(false, QString("确认事件失败(JsonParseError)"), successUuids, m_currentRequestId); } - - emit confirmEventsResult(false, QString("确认事件失败(Json错误)"), successUuids); } else { - QString errorMsg = QString("ConfirmEvents error: %1").arg(reply->errorString()); + QString errorMsg = QString("ConfirmEvents reply Network error: %1").arg(reply->errorString()); LOG_ERROR("Http", errorMsg); - emit confirmEventsResult(false, QString("确认事件失败(%1)").arg(errorMsg), successUuids); + emit confirmEventsResult(false, QString("确认事件失败(Reply Network error)"), successUuids, m_currentRequestId); } reply->deleteLater(); diff --git a/source/alarmEventDataView.cpp b/source/alarmEventDataView.cpp index 5811542..4eba270 100644 --- a/source/alarmEventDataView.cpp +++ b/source/alarmEventDataView.cpp @@ -13,6 +13,7 @@ AlarmEventDataModel::AlarmEventDataModel(AlarmDataMode mode, QObject* parent) : QAbstractTableModel(parent) , m_dataMode(mode) , m_maxRealTimeEvents(5) + , m_lastRequestId(0) { m_paginationInfo.entriesPerPage = 100; m_paginationInfo.currentPage = 1; @@ -36,13 +37,14 @@ AlarmEventDataModel::AlarmEventDataModel(AlarmDataMode mode, QObject* parent) { connect(AlarmEventDataService::instance(), &AlarmEventDataService::historicalQueryData, this, &AlarmEventDataModel::onHistoricalEventsReceived); connect(AlarmEventDataService::instance(), &AlarmEventDataService::historicalQueryError, this, &AlarmEventDataModel::onHistoricalQueryError); - connect(AlarmEventDataService::instance(), &AlarmEventDataService::confirmEventsResult, this, &AlarmEventDataModel::onConfirmEventsResult); } + connect(AlarmEventDataService::instance(), &AlarmEventDataService::confirmEventsResult, this, &AlarmEventDataModel::onConfirmEventsResult); + //实时数据测试 m_simulatedDataTimer = new QTimer(this); connect(m_simulatedDataTimer, &QTimer::timeout, this, &AlarmEventDataModel::onTimeoutSimulateData); - m_simulatedDataTimer->start(3000); + m_simulatedDataTimer->start(5000); } AlarmEventDataModel::~AlarmEventDataModel() @@ -285,18 +287,47 @@ void AlarmEventDataModel::updateEventData(int index, const EventData& updatedEve void AlarmEventDataModel::confirmEvent(const QModelIndex index) { int row = index.row(); + if(m_displayEvents.at(row).status == 3) + { + qDebug() << "the event has been confirmed"; + return; + } QString uuid = m_displayEvents.at(row).id; QStringList uuids; uuids.append(uuid); - AlarmEventDataService::instance()->confirmEvents(uuids); + + // 为本次请求创建一个唯一标识。 + // 简单做法:使用对象的唯一性(this指针)。但要注意对象可能被销毁。 + // 更稳健做法:使用一个递增的成员变量作为请求ID。 + static quint64 s_localRequestId = 0; + quint64 currentRequestId = ++s_localRequestId; + m_lastRequestId = currentRequestId; + // 发送请求,附加上下文标识 + AlarmEventDataService::instance()->confirmEvents(uuids, currentRequestId); } void AlarmEventDataModel::confirmCurPageEvents() { QStringList uuids; for(const EventData& event : m_displayEvents) - uuids.append(event.id); - AlarmEventDataService::instance()->confirmEvents(uuids); + { + if(event.status != 3) + uuids.append(event.id); + } + + if(uuids.isEmpty()) + { + qDebug() << "all events have been confirmed"; + return; + } + // 为本次请求创建一个唯一标识。 + // 简单做法:使用对象的唯一性(this指针)。但要注意对象可能被销毁。 + // 更稳健做法:使用一个递增的成员变量作为请求ID。 + static quint64 s_localRequestId = 0; + quint64 currentRequestId = ++s_localRequestId; + m_lastRequestId = currentRequestId; + // 发送请求,附加上下文标识 + AlarmEventDataService::instance()->confirmEvents(uuids, currentRequestId); } void AlarmEventDataModel::updateCurPageData() @@ -437,16 +468,25 @@ void AlarmEventDataModel::onHistoricalQueryError(const QString& error) emit loadDataError(error); } -void AlarmEventDataModel::onConfirmEventsResult(bool success, const QString& mesg, const QStringList& successUuids) +void AlarmEventDataModel::onConfirmEventsResult(bool success, const QString& mesg, const QStringList& successUuids, QVariant context) { + // 检查上下文是否匹配此模型的请求 + quint64 resultRequestId = context.toULongLong(); + if (resultRequestId != m_lastRequestId) + { + //qDebug() << "is not my signal, i am " << this; + return; // 不是本模型发起的请求,直接忽略 + } + if(!success) { + qDebug() << "confirm error: " << mesg; return; } if(m_dataMode == RealTime) { - beginResetModel(); + //beginResetModel(); for(const QString& uuid : successUuids) { @@ -460,10 +500,17 @@ void AlarmEventDataModel::onConfirmEventsResult(bool success, const QString& mes } } - endResetModel(); + QModelIndex topLeft = createIndex(0, Status); + QModelIndex bottomRight = createIndex(m_displayEvents.count() - 1, Status); + emit dataChanged(topLeft, bottomRight, {Qt::DisplayRole, Qt::ForegroundRole}); + qDebug() << "realtime view confirm refresh"; + //endResetModel(); } else + { + qDebug() << "historical view confirm refresh"; refresh(); + } } bool AlarmEventDataModel::setCurrentPage(int page)