ソースを参照

dev: demo version

Yao 1 週間 前
コミット
3dcdbd102f

+ 0 - 0
blastRecord/.clang-format.yaml → .clang-format


+ 2 - 0
CMakeLists.txt

@@ -146,6 +146,8 @@ add_executable(${PROJECT_NAME}
     loadingWidget.h
     loadingWidget.cpp
     README.md
+    backendapimanager.h backendapimanager.cpp
+
 
 
 )

+ 39 - 0
README.md

@@ -0,0 +1,39 @@
+## 智慧矿山系统 起爆系统PC客户端
+
+## Setup
+### Steps to build system
+ Qt version: 3.8 ~ 3.9
+ Arch: windows X86-64
+ Required Plugins: webengine, mqtt, sql (MySQL drivier)
+ Database: MySQL v7.5
+
+### How to run
+ * 配置数据库 MySQL服务器, 并初始化数据库表(database: pc-system)。
+ * 设置本地数据库(databasemanager.cpp)
+ * 设置Backend 地址(global.h)。
+ * 设置mqtt server
+ * [开发阶段]修改人脸识别数据 通过配置windows环境变量;certName(用户姓名,中文) 和 certNo (身份证号);
+
+### PC Test Account
+ * user1
+  User: Admin
+  Password: 123456
+  
+### FAQ:
+1. 更换人脸识别数据?
+   
+2. MQTT 无法连接
+   * 确认Mqtt服务器地址是否正确
+   * 确认device UUID 没有和其他客户端冲突。
+   * MQTT 只可以在Release编译通过才可以使用。
+3. 如果发布:
+   * 新建目录 Release, 并且复制build好的pc_system.exe到目录下。
+   * 使用SDK(如:C:\Qt\6.9.0\msvc2022_64\bin)下的`windeploy.exe pc-system.exe`。
+   * 确保需要的本地库也在打包的目录下。(如 MySQL.dll及有的可能需要Mysql bin下的ssl cropty 等lib)。
+   
+4. 有些请求为什么会失败?
+   目前一些请求需要cookie, 所以需要从登录页面进入才可以。
+5. 如何添加用户?
+   访问后端APP。菜单: 基础信息 -> 人员管理。添加爆破员,操作员。
+   
+### TODOs:

+ 193 - 0
backendapimanager.cpp

@@ -0,0 +1,193 @@
+#include "backendapimanager.h"
+#include <QEventLoop>
+
+backendAPIManager *backendAPIManager::s_instance = nullptr;
+
+void backendAPIManager::initialize(const QString &backendUrl)
+{
+    if (!s_instance)
+    {
+        s_instance = new backendAPIManager(backendUrl);
+    }
+}
+
+void backendAPIManager::cleanup()
+{
+    if (s_instance)
+    {
+        delete s_instance;
+        s_instance = nullptr;
+    }
+}
+
+void backendAPIManager::setAuthToken(const QString &token)
+{
+    qDebug() << "Setting auth token:" << token << s_instance;
+    if (s_instance)
+    {
+        s_instance->authToken = token;
+    }
+}
+
+backendAPIManager::backendAPIManager(const QString &backendUrl, QObject *parent)
+    : QObject(parent), backendUrl(backendUrl), requestSuccess(false)
+{
+    networkManager = new QNetworkAccessManager(this);
+}
+
+backendAPIManager::~backendAPIManager()
+{
+    if (networkManager)
+    {
+        delete networkManager;
+        networkManager = nullptr;
+    }
+}
+
+void backendAPIManager::setupRequest(QNetworkRequest &request, const QString &endpoint)
+{
+    request.setUrl(QUrl(backendUrl + endpoint));
+    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
+
+    if (!s_instance->authToken.isEmpty())
+    {
+        request.setRawHeader("Authorization", s_instance->authToken.toUtf8());
+    }
+}
+
+QNetworkReply *backendAPIManager::sendRequest(const QString &endpoint,
+                                              const QJsonObject &data,
+                                              const QString &method)
+{
+    QNetworkRequest request;
+    setupRequest(request, endpoint);
+
+    QJsonDocument doc(data);
+    QByteArray jsonData = doc.toJson();
+
+    QNetworkReply *reply = nullptr;
+    if (method == "GET")
+    {
+        reply = networkManager->get(request);
+    }
+    else if (method == "POST")
+    {
+        reply = networkManager->post(request, jsonData);
+    }
+    else if (method == "PUT")
+    {
+        reply = networkManager->put(request, jsonData);
+    }
+    else if (method == "DELETE")
+    {
+        reply = networkManager->deleteResource(request);
+    }
+
+    return reply;
+}
+
+bool backendAPIManager::uploadBlastProject(const QJsonObject &projectData)
+{
+    if (!s_instance)
+        return false;
+
+    s_instance->requestSuccess = false;
+    QNetworkReply *reply = s_instance->sendRequest("blastrecord/pc", projectData, "POST");
+
+    // 使用事件循环等待响应
+    QEventLoop loop;
+    QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
+    loop.exec();
+
+    if (reply->error() == QNetworkReply::NoError)
+    {
+        QJsonDocument response = QJsonDocument::fromJson(reply->readAll());
+        qDebug() << "Upload response:" << response;
+        s_instance->handleUploadFinished(response, reply->url());
+    }
+    else
+    {
+        qDebug() << "Upload error:" << reply->errorString();
+        s_instance->handleUploadError(reply->errorString());
+    }
+
+    reply->deleteLater();
+    qDebug() << "Uploading blast project data:" << projectData << "result" << s_instance->requestSuccess;
+    return s_instance->requestSuccess;
+}
+
+bool backendAPIManager::uploadBlastDet(const QJsonObject &detsData)
+{
+    if (!s_instance)
+        return false;
+
+    s_instance->requestSuccess = false;
+    QNetworkReply *reply = s_instance->sendRequest("/blastrecorddet", detsData, "POST");
+
+    // 使用事件循环等待响应
+    QEventLoop loop;
+    QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
+    loop.exec();
+
+    if (reply->error() == QNetworkReply::NoError)
+    {
+        QJsonDocument response = QJsonDocument::fromJson(reply->readAll());
+        s_instance->handleUploadFinished(response, reply->url());
+    }
+    else
+    {
+        s_instance->handleUploadError(reply->errorString());
+    }
+
+    reply->deleteLater();
+    return s_instance->requestSuccess;
+}
+
+bool backendAPIManager::uploadBlastEquipments(const QJsonObject &regDetsData)
+{
+    if (!s_instance)
+        return false;
+
+    s_instance->requestSuccess = false;
+    QNetworkReply *reply = s_instance->sendRequest("/blastrecorddet", regDetsData, "POST");
+
+    // 使用事件循环等待响应
+    QEventLoop loop;
+    QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
+    loop.exec();
+
+    if (reply->error() == QNetworkReply::NoError)
+    {
+        QJsonDocument response = QJsonDocument::fromJson(reply->readAll());
+        s_instance->handleUploadFinished(response, reply->url());
+    }
+    else
+    {
+        s_instance->handleUploadError(reply->errorString());
+    }
+
+    reply->deleteLater();
+    return s_instance->requestSuccess;
+}
+
+void backendAPIManager::handleUploadFinished(const QJsonDocument &response, const QUrl &url)
+{
+    // Check response status
+    if (response.object().contains("code"))
+    {
+        int code = response.object()["code"].toInt();
+        requestSuccess = (code == 200);
+    }
+    else
+    {
+        requestSuccess = false;
+    }
+
+    emit uploadFinished(response);
+}
+
+void backendAPIManager::handleUploadError(const QString &error)
+{
+    requestSuccess = false;
+    emit uploadError(error);
+}

+ 50 - 0
backendapimanager.h

@@ -0,0 +1,50 @@
+#ifndef BACKENDAPIMANAGER_H
+#define BACKENDAPIMANAGER_H
+
+#include <QObject>
+#include <QJsonObject>
+#include <QJsonDocument>
+#include <QNetworkAccessManager>
+#include <QNetworkReply>
+#include <QNetworkRequest>
+
+class backendAPIManager : public QObject
+{
+    Q_OBJECT
+
+public:
+    static void initialize(const QString &backendUrl);
+    static void cleanup();
+    static void setAuthToken(const QString &token);
+
+    static bool uploadBlastProject(const QJsonObject &projectData);
+    static bool uploadBlastDet(const QJsonObject &detsData);
+    static bool uploadBlastEquipments(const QJsonObject &regDetsData);
+
+signals:
+    void uploadFinished(const QJsonDocument &response);
+    void uploadError(const QString &errorString);
+
+private:
+    explicit backendAPIManager(const QString &backendUrl, QObject *parent = nullptr);
+    ~backendAPIManager();
+
+    // HTTP methods
+    QNetworkReply *sendRequest(const QString &endpoint,
+                               const QJsonObject &data,
+                               const QString &method = "POST");
+    void setupRequest(QNetworkRequest &request, const QString &endpoint);
+    void handleNetworkReply(QNetworkReply *reply);
+
+    static backendAPIManager *s_instance;
+    QString backendUrl;
+    QNetworkAccessManager *networkManager;
+    bool requestSuccess;
+    QString authToken;
+
+private slots:
+    void handleUploadFinished(const QJsonDocument &response, const QUrl &url);
+    void handleUploadError(const QString &error);
+};
+
+#endif // BACKENDAPIMANAGER_H

+ 1 - 1
blastProject/blastprojectpage.cpp

@@ -273,7 +273,7 @@ void BlastProjectPage::insertPlan(const QMap<QString, QString> &data)
         QJsonDocument jsonDoc(jsonArray);
         QByteArray jsonData = jsonDoc.toJson(QJsonDocument::Indented);
 
-        mqttClient->sendMessage("hxgc/companycode/pro/B", jsonData);
+        mqttClient->sendMessage("hxgc/companycode/pro/B", jsonData, 2, true);
         qDebug() <<"mqtt单例:"<< mqttClient;
     }
 

+ 1 - 2
blastRecord/HBlastRecord.h

@@ -1,7 +1,6 @@
 #ifndef HBLASTRECORD_H
 #define HBLASTRECORD_H
 
-
 #include <QString>
 #include <QDateTime>
 #include <QJsonObject>
@@ -104,7 +103,7 @@ public:
     qint64 getUpdateBy() const;
     void setUpdateBy(qint64 newUpdateBy);
 
-    QByteArray BlastRecordToJson(const HBlastRecord& record);
+    QJsonObject BlastRecordToJson();
 
 private:
     qint64 id;

+ 27 - 28
blastRecord/hblastrecord.cpp

@@ -139,7 +139,7 @@ int HBlastRecord::getEquipmentCount() const
     return equipmentCount;
 }
 
-void HBlastRecord::setEquipmentCount(int newEquipmentCount)
+void HBlastRecord::setEquipmentCount(const int newEquipmentCount)
 {
     equipmentCount = newEquipmentCount;
 }
@@ -159,7 +159,7 @@ int HBlastRecord::getErrorDetCount() const
     return errorDetCount;
 }
 
-void HBlastRecord::setErrorDetCount(int newErrorDetCount)
+void HBlastRecord::setErrorDetCount(const int newErrorDetCount)
 {
     errorDetCount = newErrorDetCount;
 }
@@ -224,32 +224,31 @@ void HBlastRecord::setUpdateBy(qint64 newUpdateBy)
     updateBy = newUpdateBy;
 }
 
-QByteArray HBlastRecord::BlastRecordToJson(const HBlastRecord &record)
+QJsonObject HBlastRecord::BlastRecordToJson()
 {
     QJsonObject json;
-    json["id"] = record.getId();
-    json["uuid"] = record.getUuid();
-    json["project_name"] = record.getProjectName();
-    json["project_htid"] = record.getProjectHtid();
-    json["project_xmbh"] = record.getProjectXmbh();
-    json["operator_name"] = record.getOperatorName();
-    json["phone"] = record.getPhone();
-    json["operator_identity"] = record.getOperatorIdentity();
-    json["equipment_sn"] = record.getEquipmentSn();
-    json["company_code"] = record.getCompanyCode();
-    json["app_version"] = record.getAppVersion();
-    json["blast_lontitude"] = record.getLongitude();
-    json["blast_latitude"] = record.getLatitude();
-    json["equipment_count"] = record.getEquipmentCount();
-    json["reg_det_count"] = record.getRegDetCount();
-    json["error_det_count"] = record.getErrorDetCount();
-    json["blast_time"] = record.getBlastAt().toString(Qt::ISODateWithMs);
-    json["created_at"] = record.getCreatedAt().toString(Qt::ISODateWithMs);
-    json["updated_at"] = record.getUpdatedAt().toString(Qt::ISODateWithMs);
-    json["deleted_at"] = record.getDeletedAt().toString(Qt::ISODateWithMs);
-    json["create_by"] = record.getCreateBy();
-    json["update_by"] = record.getUpdateBy();
-
-    QJsonDocument doc(json);
-    return doc.toJson();
+    // json["id"] = this->getId();
+    json["uuid"] = this->getUuid();
+    json["project_name"] = this->getProjectName();
+    json["project_htid"] = this->getProjectHtid();
+    json["project_xmbh"] = this->getProjectXmbh();
+    json["operator_name"] = this->getOperatorName();
+    json["phone"] = this->getPhone();
+    json["operator_identity"] = this->getOperatorIdentity();
+    json["equipment_sn"] = this->getEquipmentSn();
+    json["company_code"] = this->getCompanyCode();
+    json["app_version"] = this->getAppVersion();
+    json["blast_longitude"] = this->getLongitude();
+    json["blast_latitude"] = this->getLatitude();
+    json["equipment_count"] = QString::number(this->getEquipmentCount());
+    json["reg_deto_count"] = QString::number(this->getRegDetCount());
+    json["error_deto_count"] = QString::number(this->getErrorDetCount());
+    json["blast_time"] = this->getBlastAt().toString(Qt::ISODateWithMs);
+    json["created_at"] = this->getCreatedAt().toString(Qt::ISODateWithMs);
+    json["updated_at"] = this->getUpdatedAt().toString(Qt::ISODateWithMs);
+    json["deleted_at"] = this->getDeletedAt().toString(Qt::ISODateWithMs);
+    json["create_by"] = this->getCreateBy();
+    json["update_by"] = this->getUpdateBy();
+
+    return json;
 }

+ 2 - 1
blastRecord/hblastrecorddao.cpp

@@ -55,13 +55,14 @@ bool HBlastRecordDao::addHBlastRecord(const HBlastRecord &record)
     query.bindValue(":blast_at", record.getBlastAt().toString(Qt::ISODateWithMs));
     query.bindValue(":created_at", record.getCreatedAt().toString(Qt::ISODateWithMs));
     query.bindValue(":create_by", record.getCreateBy());
-    qDebug() << "created_at:" << record.getCreatedAt();
+    qDebug() << "created_at:" << record.getCreatedAt() << "blast_at" << record.getBlastAt();
     if (query.exec())
     {
         return true;
     }
     else
     {
+        qDebug() << "Failed to insert blast record:" << query.lastError().text();
         return false;
     }
 }

+ 2 - 3
blastRecordDet/HBlastRecordDet.h

@@ -29,7 +29,7 @@ class HBlastRecordDet : public QObject
 public:
     explicit HBlastRecordDet(QObject *parent = nullptr);
 
-       // Getter and Setter methods
+    // Getter and Setter methods
     qint64 getId() const;
     void setId(qint64 newId);
 
@@ -78,7 +78,7 @@ public:
     qint64 getUpdateBy() const;
     void setUpdateBy(qint64 newUpdateBy);
 
-    QByteArray BlastRecordDetToJson(const HBlastRecordDet& recordDet);
+    QJsonObject BlastRecordDetToJson();
 
 private:
     qint64 id;
@@ -97,7 +97,6 @@ private:
     QDateTime deletedAt;
     qint64 createBy;
     qint64 updateBy;
-
 };
 
 #endif // HBLASTRECORDDET_H

+ 19 - 21
blastRecordDet/hblastrecorddet.cpp

@@ -165,27 +165,25 @@ void HBlastRecordDet::setUpdateBy(qint64 newUpdateBy)
     updateBy = newUpdateBy;
 }
 
-QByteArray HBlastRecordDet::BlastRecordDetToJson(const HBlastRecordDet& recordDet)
+QJsonObject HBlastRecordDet::BlastRecordDetToJson()
 {
     QJsonObject jsonObject;
-    jsonObject["id"] = recordDet.getId();
-    jsonObject["uuid"] = recordDet.getUuid();
-    jsonObject["out_code"] = recordDet.getOutCode();
-    jsonObject["inner_code"] = recordDet.getInnerCode();
-    jsonObject["uid"] = recordDet.getUid();
-    jsonObject["status"] = recordDet.getStatus();
-    jsonObject["freq"] = recordDet.getFreq();
-    jsonObject["delay_time"] = recordDet.getDelayTime();
-    jsonObject["tag"] = recordDet.getTag();
-    jsonObject["blast_record_id"] = recordDet.getBlastRecordId();
-    jsonObject["reg_id"] = recordDet.getRegId();
-    jsonObject["created_at"] = recordDet.getCreatedAt().toString(Qt::ISODateWithMs);
-    jsonObject["updated_at"] = recordDet.getUpdatedAt().toString(Qt::ISODateWithMs);
-    jsonObject["deleted_at"] = recordDet.getDeletedAt().toString(Qt::ISODateWithMs);
-    jsonObject["create_by"] = recordDet.getCreateBy();
-    jsonObject["update_by"] = recordDet.getUpdateBy();
-
-    QJsonDocument jsonDoc(jsonObject);
-    return jsonDoc.toJson();
-
+    jsonObject["id"] = this->getId();
+    jsonObject["uuid"] = this->getUuid();
+    jsonObject["out_code"] = this->getOutCode();
+    jsonObject["inner_code"] = this->getInnerCode();
+    jsonObject["uid"] = this->getUid();
+    jsonObject["status"] = this->getStatus();
+    jsonObject["freq"] = this->getFreq();
+    jsonObject["delay_time"] = this->getDelayTime();
+    jsonObject["tag"] = this->getTag();
+    jsonObject["blast_record_id"] = this->getBlastRecordId();
+    jsonObject["reg_id"] = this->getRegId();
+    jsonObject["created_at"] = this->getCreatedAt().toString(Qt::ISODateWithMs);
+    jsonObject["updated_at"] = this->getUpdatedAt().toString(Qt::ISODateWithMs);
+    jsonObject["deleted_at"] = this->getDeletedAt().toString(Qt::ISODateWithMs);
+    jsonObject["create_by"] = this->getCreateBy();
+    jsonObject["update_by"] = this->getUpdateBy();
+
+    return jsonObject;
 }

+ 25 - 13
blastRegRecord/hblastregrecorddao.cpp

@@ -2,9 +2,10 @@
 
 HBlastRegRecordDao::HBlastRegRecordDao(QSqlDatabase db) : database(db) {}
 
-bool HBlastRegRecordDao::saveHBlastRegRecord(const HBlastRegRecord& record) {
+bool HBlastRegRecordDao::saveHBlastRegRecord(const HBlastRegRecord &record)
+{
     QSqlQuery query;
-    query.prepare("INSERT INTO h_blast_reg_record (uuid, equip_sn, equip_version, reg_deto_count, error_deto_count, after_test_bus_v, after_test_bus_i, bus_leakage_current_i, net_charged_v, net_charged_i, before_blasting_v, before_blasting_i, record_uuid, created_at, updated_at, deleted_at, create_by, update_by) "
+    query.prepare("INSERT INTO h_blast_equipment_record (uuid, equip_sn, equip_version, reg_deto_count, error_deto_count, after_test_bus_v, after_test_bus_i, bus_leakage_current_i, net_charged_v, net_charged_i, before_blasting_v, before_blasting_i, record_uuid, created_at, updated_at, deleted_at, create_by, update_by) "
                   "VALUES (:uuid, :equip_sn, :equip_version, :reg_deto_count, :error_deto_count, :after_test_bus_v, :after_test_bus_i, :bus_leakage_current_i, :net_charged_v, :net_charged_i, :before_blasting_v, :before_blasting_i, :record_uuid, :created_at, :updated_at, :deleted_at, :create_by, :update_by)");
     query.bindValue(":uuid", record.getUuid());
     query.bindValue(":equip_sn", record.getEquipSn());
@@ -25,17 +26,21 @@ bool HBlastRegRecordDao::saveHBlastRegRecord(const HBlastRegRecord& record) {
     query.bindValue(":create_by", record.getCreateBy());
     query.bindValue(":update_by", record.getUpdateBy());
 
-    if (query.exec()) {
+    if (query.exec())
+    {
         return true;
-    } else {
+    }
+    else
+    {
         qDebug() << "Insert failed:" << query.lastError().text();
         return false;
     }
 }
 
-bool HBlastRegRecordDao::updateHBlastRegRecord(const HBlastRegRecord& record) {
+bool HBlastRegRecordDao::updateHBlastEquipmentRecord(const HBlastRegRecord &record)
+{
     QSqlQuery query;
-    query.prepare("UPDATE h_blast_reg_record SET uuid = :uuid, equip_sn = :equip_sn, equip_version = :equip_version, reg_deto_count = :reg_deto_count, error_deto_count = :error_deto_count, after_test_bus_v = :after_test_bus_v, after_test_bus_i = :after_test_bus_i, bus_leakage_current_i = :bus_leakage_current_i, net_charged_v = :net_charged_v, net_charged_i = :net_charged_i, before_blasting_v = :before_blasting_v, before_blasting_i = :before_blasting_i, record_uuid = :record_uuid, created_at = :created_at, updated_at = :updated_at, deleted_at = :deleted_at, create_by = :create_by, update_by = :update_by "
+    query.prepare("UPDATE h_blast_equipment_record SET uuid = :uuid, equip_sn = :equip_sn, equip_version = :equip_version, reg_deto_count = :reg_deto_count, error_deto_count = :error_deto_count, after_test_bus_v = :after_test_bus_v, after_test_bus_i = :after_test_bus_i, bus_leakage_current_i = :bus_leakage_current_i, net_charged_v = :net_charged_v, net_charged_i = :net_charged_i, before_blasting_v = :before_blasting_v, before_blasting_i = :before_blasting_i, record_uuid = :record_uuid, created_at = :created_at, updated_at = :updated_at, deleted_at = :deleted_at, create_by = :create_by, update_by = :update_by "
                   "WHERE id = :id");
     query.bindValue(":id", record.getId());
     query.bindValue(":uuid", record.getUuid());
@@ -57,22 +62,29 @@ bool HBlastRegRecordDao::updateHBlastRegRecord(const HBlastRegRecord& record) {
     query.bindValue(":create_by", record.getCreateBy());
     query.bindValue(":update_by", record.getUpdateBy());
 
-    if (query.exec()) {
+    if (query.exec())
+    {
         return true;
-    } else {
+    }
+    else
+    {
         qDebug() << "Update failed:" << query.lastError().text();
         return false;
     }
 }
 
-bool HBlastRegRecordDao::deleteHBlastRegRecord(qint64 id) {
+bool HBlastRegRecordDao::deleteHBlastRegRecord(qint64 id)
+{
     QSqlQuery query;
-    query.prepare("DELETE FROM h_blast_reg_record WHERE id = :id");
+    query.prepare("DELETE FROM h_blast_equipment_record WHERE id = :id");
     query.bindValue(":id", id);
 
-    if (query.exec()) {
+    if (query.exec())
+    {
         return true;
-    } else {
+    }
+    else
+    {
         qDebug() << "Delete failed:" << query.lastError().text();
         return false;
     }
@@ -81,7 +93,7 @@ bool HBlastRegRecordDao::deleteHBlastRegRecord(qint64 id) {
 // HBlastRegRecord HBlastRegRecordDao::getHBlastRegRecordById(qint64 id) {
 //     HBlastRegRecord record;
 //     QSqlQuery query;
-//     query.prepare("SELECT * FROM h_blast_reg_record WHERE id = :id");
+//     query.prepare("SELECT * FROM h_blast_equipment_record WHERE id = :id");
 //     query.bindValue(":id", id);
 
 //     if (query.exec() && query.next()) {

+ 6 - 6
blastRegRecord/hblastregrecorddao.h

@@ -12,13 +12,13 @@ class HBlastRegRecordDao
 public:
     HBlastRegRecordDao(QSqlDatabase db);
 
-     bool saveHBlastRegRecord(const HBlastRegRecord& record);
-     bool updateHBlastRegRecord(const HBlastRegRecord& record);
-     bool deleteHBlastRegRecord(qint64 id);
-     // HBlastRegRecord getHBlastRegRecordById(qint64 id);
+    bool saveHBlastRegRecord(const HBlastRegRecord &record);
+    bool updateHBlastEquipmentRecord(const HBlastRegRecord &record);
+    bool deleteHBlastRegRecord(qint64 id);
+    // HBlastRegRecord getHBlastRegRecordById(qint64 id);
 
- private:
-     QSqlDatabase database;
+private:
+    QSqlDatabase database;
 };
 
 #endif // HBLASTREGRECORDDAO_H

ファイルの差分が大きいため隠しています
+ 382 - 305
blastopepage.cpp


+ 1 - 1
databasemanager.cpp

@@ -10,7 +10,7 @@ DatabaseManager& DatabaseManager::getInstance() {
 
 // 创建一个新的数据库连接
 DatabaseManager::DatabaseManager() : db(QSqlDatabase::addDatabase("QMYSQL")) {
-    QString host("192.168.1.160");
+    QString host("127.0.0.1");
     db.setHostName(host);
     db.setDatabaseName("pc_system");
     db.setUserName("root");

+ 109 - 246
fireWidget/firingwidget.cpp

@@ -14,6 +14,8 @@
 #include <QMessageBox>
 #include <QTimeZone>
 #include "../global.h"
+#include "../backendapimanager.h"
+#include "../logger.h"
 
 #define ANSI_COLOR_GREEN "\x1B[32m"
 #define ANSI_COLOR_RESET "\x1B[0m"
@@ -59,10 +61,12 @@ void firingWidget::sendMqttMessage(const QString &topic, const QByteArray &messa
 
     if (mqttThread && m_isMqttConnected)
     {
-        emit mqttThread->sendMessageRequested(topic, message);
+        Logger::getInstance().info(QString("发送MQTT消息到主题: %1, 消息: %2").arg(topic, QString(message)));
+        emit mqttThread->sendMessageRequested(topic, message, quint8(2), false);
     }
     else
     {
+        Logger::getInstance().error("MQTT未连接, 无法发送消息");
         qDebug() << "MQTT 未连接,无法发送消息";
     }
 }
@@ -154,7 +158,7 @@ bool firingWidget::uploadToDanLing(const QJsonObject &jsonObj)
     return true;
 }
 
-bool firingWidget::recordBlastReg(const QJsonObject &jsonObj)
+bool firingWidget::recordBlastEquipments(const QJsonObject &jsonObj)
 {
     QJsonArray regsArray = jsonObj["regs"].toArray();
     for (const auto &regValue : regsArray)
@@ -359,6 +363,7 @@ void firingWidget::onLastStageChanged(int newStage)
         return;
     }
 
+    Logger::getInstance().info(QString("Stage changed to: %1, sending message: %2").arg(newStage).arg(message));
     if (!message.isEmpty())
     {
         if (lastStage == 4 && !m_select)
@@ -371,6 +376,7 @@ void firingWidget::onLastStageChanged(int newStage)
                 bool success = serialTool->sendData(data);
                 if (success)
                 {
+                    Logger::getInstance().info(QString("Data sent successfully to serial tool: %1").arg(data));
                     qDebug() << "Data sent successfully";
                 }
                 else
@@ -384,6 +390,7 @@ void firingWidget::onLastStageChanged(int newStage)
             }
             else
             {
+                Logger::getInstance().error("SerialTool instance not found.");
                 qDebug() << "serialTool Not fond.";
                 // 在准备起爆状态下 但是没有获取串口
                 lastStage = 10;
@@ -411,170 +418,12 @@ void firingWidget::cancelBlasting()
 }
 void firingWidget::on_sendTest_4_clicked()
 {
-    // qDebug() << "navProgress 取消流程";
-    // QString message = "取消流程";
-    // if (!message.isEmpty()) {
-    //     sendMqttMessage(topic, message.toUtf8());
-    // }
-
-    lat = labLat;
-    lon = labLon;
-    QSqlDatabase db = DatabaseManager::getInstance().getDatabase();
-    if (!db.transaction())
-    {
-        qDebug() << "Failed to start transaction:" << db.lastError().text();
-        // return false;
-    }
-    // 假设的 JSON 数据
-    QString jsonData = R"(
-    {
-        "blast_latitude": "30.2039",
-        "project_xmbh": "",
-        "app_version": "1.52",
-        "operator_identity": "330781198509079292",
-        "blast_time": "2017-07-12 15:00:15",
-        "regs": [
-            {
-                "net_charged_v": "13499",
-                "after_test_bus_i": "0",
-                "after_test_bus_v": "7006",
-                "equipment_version": "AK01_V3.2_240726",
-                "bus_leakage_current_i": "0",
-                "reg_deto_count": "2",
-                "before_blasting_i": "1",
-                "error_deto_count": "2",
-                "net_charged_i": "0",
-                "before_blasting_v": "13484",
-                "dets": [
-                    {
-                        "uid": "24211104F18004",
-                        "freq": "80000",
-                        "out_code": "2411104F18000",
-                        "tag": "1-1-1",
-                        "in_code": "045AC8360A4C0061",
-                        "status": "0x03",
-                        "delay_time": "0.0"
-                    },
-                    {
-                        "uid": "24211104F18005",
-                        "freq": "80000",
-                        "out_code": "2411104F18001",
-                        "tag": "1-2-1",
-                        "in_code": "055AC8360A4C0088",
-                        "status": "0x03",
-                        "delay_time": "20.0"
-                    }
-                ],
-                "equipment_sn": "F34A0000001"
-            }
-        ],
-        "reg_deto_count": "2",
-        "project_name": "sidf",
-        "operator_name": "樊工",
-        "phone": "18611112222",
-        "project_htid": "",
-        "company_code": "3701234300003",
-        "blast_longitude": "120.196",
-        "error_deto_count": "2",
-        "equipment_sn": "F34A0000001"
-    }
-    )";
-
-    QJsonDocument doc = QJsonDocument::fromJson(jsonData.toUtf8());
-    QJsonObject jsonObj = doc.object();
-    // 创建 HBlastRecord 对象
-    HBlastRecord record;
-    record.setProjectName(jsonObj["project_name"].toString());
-    record.setProjectHtid(jsonObj["project_htid"].toString());
-    record.setProjectXmbh(jsonObj["project_xmbh"].toString());
-    record.setOperatorName(jsonObj["operator_name"].toString());
-    record.setPhone(jsonObj["phone"].toString());
-    record.setOperatorIdentity(jsonObj["operator_identity"].toString());
-    record.setEquipmentSn(jsonObj["equipment_sn"].toString());
-    record.setCompanyCode(jsonObj["company_code"].toString());
-    record.setAppVersion(jsonObj["app_version"].toString());
-
-    // record.setLongitude(jsonObj["blast_longitude"].toString());
-    // record.setLatitude(jsonObj["blast_latitude"].toString());
-
-    record.setLongitude(lat);
-    record.setLatitude(lon);
-    record.setRegDetCount(jsonObj["reg_deto_count"].toInt());
-    record.setErrorDetCount(jsonObj["error_deto_count"].toInt());
-    record.setBlastAt(QDateTime::fromString(jsonObj["blast_time"].toString(), "yyyy-MM-dd hh:mm:ss"));
-    record.setCreatedAt(QDateTime::currentDateTime());
-    qDebug() << "currentDateTime." << QDateTime::currentDateTime();
-
-    record.setUuid(QUuid::createUuid().toString(QUuid::WithoutBraces).remove(QRegularExpression("-")));
-
-    // if (dao.addHBlastRecord(record)) {
-    //     qDebug() << "Record inserted successfully.";
-    // }else{
-    //     qDebug() << "Failed to insert record.";
-    // }
-    // if (!addDetData(jsonObj)) {
-    //     qDebug() << "Insert failed for UID:"; // 假设 record 有 uid 成员
-    //     if (db.rollback()) {
-    //         qDebug() << "Transaction rolled back successfully.";
-    //     } else {
-    //         qDebug() << "Failed to roll back transaction:" << db.lastError().text();
-    //     }
-    // }
-    // if (!addRegData(jsonObj)) {
-    //     if (db.rollback()) {
-    //         qDebug() << "Transaction rolled back successfully.";
-    //     } else {
-    //         qDebug() << "Failed to roll back transaction:" << db.lastError().text();
-    //     }
-    // }
-
-    // db.commit();
-
-    if (lat == "定位失败" && lat == "未知" && lon == "定位失败" && lon == "未知")
-    {
-        // 数据出本地 不传丹灵
-        if (dao.addHBlastRecord(record))
-        {
-            qDebug() << "Record inserted successfully.";
-        }
-        else
-        {
-            qDebug() << "Failed to insert record.";
-        }
-        if (!recordDetsData(jsonObj))
-        {
-            qDebug() << "Insert failed for UID:"; // 假设 record 有 uid 成员
-            if (db.rollback())
-            {
-                qDebug() << "Transaction rolled back successfully.";
-            }
-            else
-            {
-                qDebug() << "Failed to roll back transaction:" << db.lastError().text();
-            }
-        }
-        if (!recordBlastReg(jsonObj))
-        {
-            if (db.rollback())
-            {
-                qDebug() << "Transaction rolled back successfully.";
-            }
-            else
-            {
-                qDebug() << "Failed to roll back transaction:" << db.lastError().text();
-            }
-        }
-
-        db.commit();
-    }
-    // danUpload(jsonObj);
-    // if (db.commit()) {
-    //       qDebug() << "Transaction committed successfully.";
-    //   } else {
-    //       qDebug() << "Failed to commit transaction:" << db.lastError().text();
-    //   }
 }
 
+void firingWidget::testonBlastSucess(const QJsonObject &jsonObj)
+{
+    onBlastSucess(jsonObj);
+}
 // 处理爆破成功,安全验证装置通过MQTT传回的数据
 void firingWidget::onBlastSucess(const QJsonObject &jsonObj)
 {
@@ -584,41 +433,35 @@ void firingWidget::onBlastSucess(const QJsonObject &jsonObj)
     lon = labLon;
 
     saveDataToLocalDB(jsonObj);
-    uploadToServer(jsonObj);
 
-    if (lat == "定位失败" && lat == "未知" && lon == "定位失败" && lon == "未知"){
+    if (lat == "定位失败" && lat == "未知" && lon == "定位失败" && lon == "未知")
+    {
         QMessageBox::critical(nullptr, "错误", "未获取有效定位数据,数据将暂不上传丹灵");
         // 数据:存本地 不传丹灵
     }
-    // TODO location数据如果错误,不提交丹灵
-    // danUpload(jsonObj);
-    // if (db.commit()) {
-    //       qDebug() << "Transaction committed successfully.";
-    //   } else {
-    //       qDebug() << "Failed to commit transaction:" << db.lastError().text();
-    //   }
+    uploadToDanLing(jsonObj);
 }
 
-/* 
-	Id               int                              `json:"-" comment:"主键编码"` // 主键编码
-	Uuid             string                           `json:"uuid" comment:""`
-	ProjectName      string                           `json:"project_name" comment:"工程名称"`
-	ProjectHtid      string                           `json:"project_htid" comment:"合同编号"`
-	ProjectXmbh      string                           `json:"project_xmbh" comment:"项目编号"`
-	OperatorName     string                           `json:"operator_name" comment:"操作员"`
-	Phone            string                           `json:"phone" comment:"操作员电话"`
-	OperatorIdentity string                           `json:"operator_identity" comment:"操作员身份证"`
-	EquipmentSn      string                           `json:"equipment_sn" comment:"设备序列号"`
-	CompanyCode      string                           `json:"company_code" comment:"公司代码"`
-	AppVersion       string                           `json:"app_version" comment:"app版本"`
-	Longitude        string                           `json:"blast_longitude" comment:"经度"`
-	Latitude         string                           `json:"blast_latitude" comment:"纬度"`
-	EquipmentCount   string                           `json:"equipment_count" comment:"设备数量"`
-	RegDetCount      string                           `json:"reg_deto_count" comment:"注册雷管数量"`
-	ErrorDetCount    string                           `json:"error_deto_count" comment:"异常雷管数量"`
-	BlastAt          string                           `json:"blast_time" comment:"爆破时间"`
-	Regs             []HBlastRecordEquipmentInsertReq `json:"regs"`
-	WBlasterId       string                           `json:"w_blaster_id"`
+/*
+    Id               int                              `json:"-" comment:"主键编码"` // 主键编码
+    Uuid             string                           `json:"uuid" comment:""`
+    ProjectName      string                           `json:"project_name" comment:"工程名称"`
+    ProjectHtid      string                           `json:"project_htid" comment:"合同编号"`
+    ProjectXmbh      string                           `json:"project_xmbh" comment:"项目编号"`
+    OperatorName     string                           `json:"operator_name" comment:"操作员"`
+    Phone            string                           `json:"phone" comment:"操作员电话"`
+    OperatorIdentity string                           `json:"operator_identity" comment:"操作员身份证"`
+    EquipmentSn      string                           `json:"equipment_sn" comment:"设备序列号"`
+    CompanyCode      string                           `json:"company_code" comment:"公司代码"`
+    AppVersion       string                           `json:"app_version" comment:"app版本"`
+    Longitude        string                           `json:"blast_longitude" comment:"经度"`
+    Latitude         string                           `json:"blast_latitude" comment:"纬度"`
+    EquipmentCount   string                           `json:"equipment_count" comment:"设备数量"`
+    RegDetCount      string                           `json:"reg_deto_count" comment:"注册雷管数量"`
+    ErrorDetCount    string                           `json:"error_deto_count" comment:"异常雷管数量"`
+    BlastAt          string                           `json:"blast_time" comment:"爆破时间"`
+    Regs             []HBlastRecordEquipmentInsertReq `json:"regs"`
+    WBlasterId       string                           `json:"w_blaster_id"`
 */
 void firingWidget::uploadToServer(const QJsonObject &jsonObj)
 {
@@ -636,31 +479,33 @@ void firingWidget::saveDataToLocalDB(const QJsonObject &jsonObj)
         return;
     }
 
-    if (!recordBlastData(jsonObj))
+    HBlastRecord *blastRecord = recordBlastProject(jsonObj);
+    if (blastRecord == nullptr)
     {
         if (db.rollback())
         {
-            qDebug() << "Transaction rolled back successfully.";
+            qDebug() << "Transaction rolled back successfully for no blastRecoard created.";
+            Logger::getInstance().error(QString("Failed to create blast record. data: %1").arg(QJsonDocument(jsonObj).toJson(QJsonDocument::Indented)));
         }
         else
         {
             qDebug() << "Failed to roll back transaction:" << db.lastError().text();
         }
     }
-    if (!recordBlastReg(jsonObj))
+    if (!recordBlastEquipments(jsonObj))
     {
         if (db.rollback())
         {
-            qDebug() << "Transaction rolled back successfully.";
+            qDebug() << "Transaction rolled back successfully for equiments.";
         }
         else
         {
             qDebug() << "Failed to roll back transaction:" << db.lastError().text();
         }
     }
-    if (!recordDetsData(jsonObj))
+    QList<HBlastRecordDet *> detsRecords = recordDetsData(jsonObj);
+    if (detsRecords.isEmpty())
     {
-        qDebug() << "Insert failed for UID:"; // 假设 record 有 uid 成员
         if (db.rollback())
         {
             qDebug() << "Transaction rolled back successfully.";
@@ -672,77 +517,95 @@ void firingWidget::saveDataToLocalDB(const QJsonObject &jsonObj)
     }
 
     db.commit();
+
+    if (blastRecord != nullptr)
+    {
+        if (!backendAPIManager::uploadBlastProject(blastRecord->BlastRecordToJson()))
+        {
+            Logger::getInstance().error(QString("Failed to upload blast project. data: %1").arg(QJsonDocument(blastRecord->BlastRecordToJson()).toJson(QJsonDocument::Indented)));
+        }
+    }
 }
 
-HBlastRecord* firingWidget::recordBlastData(const QJsonObject &jsonObj)
+HBlastRecord *firingWidget::recordBlastProject(const QJsonObject &jsonObj)
 {
-    HBlastRecord record;
-    record.setProjectName(jsonObj["project_name"].toString());
-    record.setProjectHtid(jsonObj["project_htid"].toString());
-    record.setProjectXmbh(jsonObj["project_xmbh"].toString());
-    record.setOperatorName(jsonObj["operator_name"].toString());
-    record.setPhone(jsonObj["phone"].toString());
-    record.setOperatorIdentity(jsonObj["operator_identity"].toString());
-    record.setEquipmentSn(jsonObj["equipment_sn"].toString());
-    record.setCompanyCode(jsonObj["company_code"].toString());
-    record.setAppVersion(jsonObj["app_version"].toString());
-
-    record.setLongitude(jsonObj["blast_longitude"].toString());
-    record.setLatitude(jsonObj["blast_latitude"].toString());
-
-    // record.setLongitude(lat);
-    // record.setLatitude(lon);
-    record.setRegDetCount(jsonObj["reg_deto_count"].toString().toInt());
-    record.setErrorDetCount(jsonObj["error_deto_count"].toString().toInt());
-    QDateTime blastTime = QDateTime::fromString(jsonObj["blast_time"].toString(), "yyyy-MM-dd hh:mm:ss +08:00");
-    blastTime.setTimeZone(QTimeZone(QByteArrayLiteral("Asia/Shanghai")));
-    record.setBlastAt(blastTime);
-    record.setCreatedAt(QDateTime::currentDateTime());
-    qDebug() << "currentDateTime." << QDateTime::currentDateTime();
-    record.setUuid(blast_uuid);
-
-    if (dao.addHBlastRecord(record))
+    HBlastRecord *record = new HBlastRecord();
+    record->setProjectName(jsonObj["project_name"].toString());
+    record->setProjectHtid(jsonObj["project_htid"].toString());
+    record->setProjectXmbh(jsonObj["project_xmbh"].toString());
+    record->setOperatorName(jsonObj["operator_name"].toString());
+    record->setPhone(jsonObj["phone"].toString());
+    record->setOperatorIdentity(jsonObj["operator_identity"].toString());
+    record->setEquipmentSn(jsonObj["equipment_sn"].toString());
+    record->setCompanyCode(jsonObj["company_code"].toString());
+    record->setAppVersion(jsonObj["app_version"].toString());
+
+    record->setLongitude(jsonObj["blast_longitude"].toString().left(10));
+    record->setLatitude(jsonObj["blast_latitude"].toString().left(10));
+
+    // record->setLongitude(lat);
+    // record->setLatitude(lon);
+    record->setRegDetCount(jsonObj["reg_deto_count"].toString().toInt());
+    record->setErrorDetCount(jsonObj["error_deto_count"].toString().toInt());
+    QDateTime blastTime = QDateTime::fromString(jsonObj["blast_time"].toString(), "yyyy-MM-dd hh:mm:ss");
+    // blastTime.setTimeZone(QTimeZone(QByteArrayLiteral("Asia/Shanghai")));
+    record->setBlastAt(blastTime);
+    record->setCreatedAt(QDateTime::currentDateTime());
+    record->setUuid(blast_uuid);
+
+    if (dao.addHBlastRecord(*record))
     {
         qDebug() << "Record inserted successfully.";
-        return &record;
+        return record;
     }
     else
     {
         qDebug() << "Failed to insert record.";
+        delete record;
         return nullptr;
     }
 }
 
-bool firingWidget::recordDetsData(const QJsonObject &jsonObj)
+QList<HBlastRecordDet *> firingWidget::recordDetsData(const QJsonObject &jsonObj)
 {
+    QList<HBlastRecordDet *> recordDets;
     QJsonArray regsArray = jsonObj["regs"].toArray();
+
     for (const auto &regValue : regsArray)
     {
         QJsonObject regObj = regValue.toObject();
         QJsonArray detsArray = regObj["dets"].toArray();
+
         for (const auto &detValue : detsArray)
         {
             QJsonObject detObj = detValue.toObject();
-            HBlastRecordDet recordDet;
-
-            recordDet.setId(0);
-            recordDet.setUuid(QUuid::createUuid().toString(QUuid::WithoutBraces).remove(QRegularExpression("-")));
-            recordDet.setOutCode(detObj["out_code"].toString());
-            recordDet.setInnerCode(detObj["in_code"].toString());
-            recordDet.setUid(detObj["uid"].toString());
-            recordDet.setStatus(detObj["status"].toString());
-            recordDet.setFreq(detObj["freq"].toString());
-            recordDet.setDelayTime(detObj["delay_time"].toString());
-            recordDet.setTag(detObj["tag"].toString());
-            recordDet.setCreatedAt(QDateTime::currentDateTime());
-            recordDet.setBlastRecordId(blast_uuid);
-            recordDet.setRegId(reg_uuid);
-            recordDet.setCreatedAt(QDateTime::currentDateTime());
-            if (!daoDet.addHBlastRecordDet(recordDet))
+            HBlastRecordDet *recordDet = new HBlastRecordDet();
+
+            recordDet->setId(0);
+            recordDet->setUuid(QUuid::createUuid().toString(QUuid::WithoutBraces).remove(QRegularExpression("-")));
+            recordDet->setOutCode(detObj["out_code"].toString());
+            recordDet->setInnerCode(detObj["in_code"].toString());
+            recordDet->setUid(detObj["uid"].toString());
+            recordDet->setStatus(detObj["status"].toString());
+            recordDet->setFreq(detObj["freq"].toString());
+            recordDet->setDelayTime(detObj["delay_time"].toString());
+            recordDet->setTag(detObj["tag"].toString());
+            recordDet->setCreatedAt(QDateTime::currentDateTime());
+            recordDet->setBlastRecordId(blast_uuid);
+            recordDet->setRegId(reg_uuid);
+            recordDet->setCreatedAt(QDateTime::currentDateTime());
+
+            if (daoDet.addHBlastRecordDet(*recordDet))
+            {
+                recordDets.append(recordDet);
+            }
+            else
             {
-                return false;
+                Logger::getInstance().error(QString("Failed to insert record det. data %1").arg(QJsonDocument(recordDet->BlastRecordDetToJson()).toJson(QJsonDocument::Compact)));
+                delete recordDet;
+                continue;
             }
         }
     }
-    return true;
+    return recordDets;
 }

+ 4 - 3
fireWidget/firingwidget.h

@@ -27,6 +27,7 @@ public:
     explicit firingWidget(const int &row, const bool &select, const QString &uuid = "", QWidget *parent = nullptr);
     ~firingWidget();
     void cancelBlasting();
+    void testonBlastSucess(const QJsonObject &data);
 
 public slots:
     void onCountdownFinished(const QString &topic, const QString &message);
@@ -54,10 +55,10 @@ private slots:
     void onBlastSucess(const QJsonObject &data);
 
 private:
-    bool recordBlastReg(const QJsonObject &jsonObj);
-    bool recordDetsData(const QJsonObject &jsonObj);
+    bool recordBlastEquipments(const QJsonObject &jsonObj);
+    QList<HBlastRecordDet *> recordDetsData(const QJsonObject &jsonObj);
     bool uploadToDanLing(const QJsonObject &jsonObj);
-    HBlastRecord* recordBlastData(const QJsonObject &jsonObj);
+    HBlastRecord *recordBlastProject(const QJsonObject &jsonObj);
     void saveDataToLocalDB(const QJsonObject &jsonObj);
     void uploadToServer(const QJsonObject &jsonObj);
     void sendMqttMessage(const QString &topic, const QByteArray &message);

+ 37 - 30
login/loginwindow.cpp

@@ -1,30 +1,27 @@
 #include "loginwindow.h"
 #include "ui_loginwindow.h"
+#include "../backendapimanager.h"
 
-
-
-LoginWindow::LoginWindow(QWidget *parent) :
-    QWidget(parent),
-    ui(new Ui::LoginWindow),
-    manager(new QNetworkAccessManager(this))
+LoginWindow::LoginWindow(QWidget *parent) : QWidget(parent),
+                                            ui(new Ui::LoginWindow),
+                                            manager(new QNetworkAccessManager(this))
 {
     ui->setupUi(this);
-    registryManager =  new RegistryManager();
+    registryManager = new RegistryManager();
     ui->username->lineEdit()->setPlaceholderText("请输入用户名");
-    QMovie* movie = new QMovie(this);
+    QMovie *movie = new QMovie(this);
     movie->setFileName(":/icons/icons/hxgc.gif");
     movie->start();
     ui->label->setMovie(movie);
     setWindowFlags(Qt::FramelessWindowHint);
     initUesrCombox();
-
-
 }
 
 void LoginWindow::initUesrCombox()
 {
     QStringList allUsernames = registryManager->getAllUsernames();
-    for (const QString& username : allUsernames) {
+    for (const QString &username : allUsernames)
+    {
         ui->username->addItem(username);
     }
     ui->username->setCurrentIndex(-1);
@@ -39,11 +36,13 @@ void LoginWindow::on_btnLogin_clicked()
 
     QString username = ui->username->currentText();
     QString password = ui->password->text();
-    if (username.isEmpty() || password.isEmpty()) {
+    if (username.isEmpty() || password.isEmpty())
+    {
         QMessageBox::critical(nullptr, "输入错误", "用户名或密码不能为空,请重新输入。");
         return;
     }
-    try{
+    try
+    {
         // 构造请求数据
         QJsonObject jsonData;
         jsonData["username"] = username;
@@ -57,7 +56,8 @@ void LoginWindow::on_btnLogin_clicked()
         // 发送 POST 请求
         QNetworkReply *reply = manager->post(request, data);
         // 处理响应
-        QObject::connect(reply, &QNetworkReply::finished, [reply,this,username,password]() {
+        QObject::connect(reply, &QNetworkReply::finished, [reply, this, username, password]()
+                         {
             try {
                 if (reply->error() == QNetworkReply::NoError) {
                     QByteArray responseData = reply->readAll();
@@ -105,7 +105,20 @@ void LoginWindow::on_btnLogin_clicked()
                                 globalAuthority = "Bearer " + Authority;
                                 this->close();
                                 MainWindow *mainWindow = new MainWindow();
-
+                                backendAPIManager::setAuthToken(globalAuthority);
+
+    /*TODO: delete
+    QString jsonString = "{\"app_version\":\"1.52\",\"blast_latitude\":\"30.21122186731856\",\"blast_longitude\":\"120.22146062951883\",\"blast_time\":\"2025-06-03 12:00:00\",\"company_code\":\"3701234300003\",\"equipment_sn\":\"F34A0000001\",\"error_deto_count\":\"0\",\"operator_identity\":\"330781198509079292\",\"operator_name\":\"栋工\",\"phone\":\"18611112222\",\"project_htid\":\"\",\"project_name\":\"sidf\",\"project_xmbh\":\"\",\"reg_deto_count\":\"2\",\"regs\":[{\"after_test_bus_i\":\"41\",\"after_test_bus_v\":\"8006\",\"before_blasting_i\":\"49\",\"before_blasting_v\":\"13492\",\"bus_leakage_current_i\":\"0\",\"dets\":[{\"delay_time\":\"0.0\",\"freq\":\"0\",\"in_code\":\"005AC8360A4C01A7\",\"out_code\":\"2411104F18000\",\"status\":\"0x00\",\"tag\":\"1-1-1\",\"uid\":\"24211104F18000\"},{\"delay_time\":\"80.0\",\"freq\":\"0\",\"in_code\":\"015AC8360A4C014E\",\"out_code\":\"2411104F18001\",\"status\":\"0x00\",\"tag\":\"1-2-1\",\"uid\":\"24211104F18001\"}],\"equipment_sn\":\"null\",\"equipment_version\":\"null\",\"error_deto_count\":\"0\",\"net_charged_i\":\"49\",\"net_charged_v\":\"13501\",\"reg_deto_count\":\"2\"}]}";
+    // 使用 QJsonDocument::fromJson 直接解析 QByteArray 并获取 QJsonObject
+    // 这是一个非常简洁的单行操作,假设你知道顶层是 JSON 对象且不关心详细的错误信息
+    QJsonObject myJsonObject = QJsonDocument::fromJson(jsonString.toUtf8()).object();
+    qDebug() << "debug" << QDateTime::fromString(myJsonObject["blast_time"].toString(), "yyyy-MM-dd hh:mm:ss").toString(Qt::ISODateWithMs);
+    int row = 1;
+    firingWidget *wt = new firingWidget(row, false, "111");
+    wt->testonBlastSucess(myJsonObject);
+    //<< Delete
+    */
+    
                                 QScreen *screen = QGuiApplication::primaryScreen();
                                 QRect screenGeometry = screen->geometry();
                                 int screenWidth = screenGeometry.width();
@@ -131,19 +144,18 @@ void LoginWindow::on_btnLogin_clicked()
             } catch (const std::exception& e) {
                 qDebug() << "Exception in response handling: " << e.what();
             }
-            reply->deleteLater();
-        });
-
-    } catch (const std::exception& e) {
+            reply->deleteLater(); });
+    }
+    catch (const std::exception &e)
+    {
         qDebug() << "Exception in request sending: " << e.what();
     }
-
 }
 
-
 void LoginWindow::mousePressEvent(QMouseEvent *event)
 {
-    if (event->button() == Qt::LeftButton) {
+    if (event->button() == Qt::LeftButton)
+    {
         m_dragPosition = event->globalPos() - frameGeometry().topLeft();
         event->accept();
     }
@@ -151,31 +163,28 @@ void LoginWindow::mousePressEvent(QMouseEvent *event)
 
 void LoginWindow::mouseMoveEvent(QMouseEvent *event)
 {
-    if (event->buttons() & Qt::LeftButton) {
+    if (event->buttons() & Qt::LeftButton)
+    {
         move(event->globalPos() - m_dragPosition);
         event->accept();
     }
 }
 
-
 void LoginWindow::on_btnClose_clicked()
 {
     this->close();
 }
 
-
 void LoginWindow::on_btnMin_clicked()
 {
     this->showMinimized();
 }
 
-
 void LoginWindow::on_username_activated(int index)
 {
-    qDebug()<<index;
+    qDebug() << index;
 }
 
-
 void LoginWindow::on_username_currentIndexChanged(int index)
 {
     QString name = ui->username->currentText();
@@ -183,6 +192,4 @@ void LoginWindow::on_username_currentIndexChanged(int index)
     QString pass = registryManager->getPasswordByUsername(name);
 
     ui->password->setText(pass);
-
 }
-

+ 10 - 19
main.cpp

@@ -5,8 +5,8 @@
 #include <QApplication>
 #include <QFile>
 #include <QTextStream>
-#include <QQuickWindow>  // 关键头文件
-
+#include <QQuickWindow> // 关键头文件
+#include "backendapimanager.h"
 
 int main(int argc, char *argv[])
 {
@@ -14,20 +14,10 @@ int main(int argc, char *argv[])
 
     QQuickWindow::setSceneGraphBackend("software"); // 兼容性: 禁用GPU
 
-    /*TODO: delete
-     * QString jsonString = "{\"app_version\":\"1.52\",\"blast_latitude\":\"30.21122186731856\",\"blast_longitude\":\"120.22146062951883\",\"blast_time\":\"2025-05-29 16:02:32\",\"company_code\":\"3701234300003\",\"equipment_sn\":\"F34A0000001\",\"error_deto_count\":\"0\",\"operator_identity\":\"330781198509079292\",\"operator_name\":\"栋工\",\"phone\":\"18611112222\",\"project_htid\":\"\",\"project_name\":\"sidf\",\"project_xmbh\":\"\",\"reg_deto_count\":\"2\",\"regs\":[{\"after_test_bus_i\":\"41\",\"after_test_bus_v\":\"8006\",\"before_blasting_i\":\"49\",\"before_blasting_v\":\"13492\",\"bus_leakage_current_i\":\"0\",\"dets\":[{\"delay_time\":\"0.0\",\"freq\":\"0\",\"in_code\":\"005AC8360A4C01A7\",\"out_code\":\"2411104F18000\",\"status\":\"0x00\",\"tag\":\"1-1-1\",\"uid\":\"24211104F18000\"},{\"delay_time\":\"80.0\",\"freq\":\"0\",\"in_code\":\"015AC8360A4C014E\",\"out_code\":\"2411104F18001\",\"status\":\"0x00\",\"tag\":\"1-2-1\",\"uid\":\"24211104F18001\"}],\"equipment_sn\":\"null\",\"equipment_version\":\"null\",\"error_deto_count\":\"0\",\"net_charged_i\":\"49\",\"net_charged_v\":\"13501\",\"reg_deto_count\":\"2\"}]}";
-    // 使用 QJsonDocument::fromJson 直接解析 QByteArray 并获取 QJsonObject
-    // 这是一个非常简洁的单行操作,假设你知道顶层是 JSON 对象且不关心详细的错误信息
-    QJsonObject myJsonObject = QJsonDocument::fromJson(jsonString.toUtf8()).object();
-    qDebug() <<"debug" << QDateTime::fromString(myJsonObject["blast_time"].toString(), "yyyy-MM-dd hh:mm:ss").toString();
-    qDebug() <<"debug" << QDateTime::fromString(myJsonObject["blast_time"].toString(), "yyyy-MM-dd hh:mm:ss").toString(Qt::ISODateWithMs);
-     */
-
-
-
     // 加载 QSS 文件
     QFile styleFile(":/qss/qss/tableview.qss");
-    if (styleFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
+    if (styleFile.open(QIODevice::ReadOnly | QIODevice::Text))
+    {
         QTextStream stream(&styleFile);
         QString styleSheet = stream.readAll();
         app.setStyleSheet(styleSheet);
@@ -43,15 +33,16 @@ int main(int argc, char *argv[])
     Logger::getInstance("application.log");
 
     Logger::getInstance().setMaxFileSize(2 * 1024 * 1024); // 2 MB
-    Logger::getInstance().setMaxBackupFiles(3);           // Keep 3 backup files
+    Logger::getInstance().setMaxBackupFiles(3);            // Keep 3 backup files
     Logger::getInstance().info("Application started from main.");
 
+    backendAPIManager::initialize(g_url.toString());
 
-    //MainWindow w;
-    // Page w;
-    // pageTest w;
+    // MainWindow w;
+    //  Page w;
+    //  pageTest w;
     LoginWindow w;
-     //loginWindow.show();
+    // loginWindow.show();
     // 设置应用程序图标
     app.setWindowIcon(QIcon(":/icons/icons/l634z-aceaj-001.ico"));
     // w.resize(screenWidth * 1, screenHeight * 0.95);

+ 126 - 82
mainwindow.cpp

@@ -10,50 +10,70 @@
 // 定义 ANzI 转义序列来设置颜色
 #define ANSI_COLOR_GREEN "\x1B[32m"
 #define ANSI_COLOR_RESET "\x1B[0m"
+#include <exception>
+#include <QMessageBox>
+
 MainWindow::MainWindow(QWidget *parent)
-    : QMainWindow(parent)
-    , ui(new Ui::MainWindow)
-{
-
-    // 去除窗口边界,设置为无边框窗口
-    this->setWindowFlags(Qt::FramelessWindowHint);
-    this->setWindowState(Qt::WindowMaximized); //Maximizes the window
-    ui->setupUi(this);
-
-    initializeAnimate();
-    initialMqttService();
-
-    pageFactories[ui->btnNew] = new AddressFactory();
-    pageFactories[ui->btnBlastProject] = new BlastProjectFactory();
-    pageFactories[ui->btnEquipment] = new EquipmentFactory();
-    pageFactories[ui->btnDet] = new DetInfoFactory();
-    pageFactories[ui->btnBlastOper] = new BlastOperationFactory();
-    pageFactories[ui->btnRecord] = new BlastRecordFactory();
-
-    connect(ui->btnToggle, &QPushButton::clicked, this, &MainWindow::onToggleButtonClicked);
-    for (auto *widget : left_button_station) {
-          QPushButton *button = qobject_cast<QPushButton*>(widget);
-          if (button) {
-              connect(button, &QPushButton::clicked, this, [this, button]{
-                  onButtonClicked(button);
-              });
-          }
+    : QMainWindow(parent), ui(new Ui::MainWindow)
+{
+    try
+    {
+        // 去除窗口边界,设置为无边框窗口
+        this->setWindowFlags(Qt::FramelessWindowHint);
+        this->setWindowState(Qt::WindowMaximized); // Maximizes the window
+        ui->setupUi(this);
+
+        initializeAnimate();
+        initialMqttService();
+
+        pageFactories[ui->btnNew] = new AddressFactory();
+        pageFactories[ui->btnBlastProject] = new BlastProjectFactory();
+        pageFactories[ui->btnEquipment] = new EquipmentFactory();
+        pageFactories[ui->btnDet] = new DetInfoFactory();
+        pageFactories[ui->btnBlastOper] = new BlastOperationFactory();
+        pageFactories[ui->btnRecord] = new BlastRecordFactory();
+
+        connect(ui->btnToggle, &QPushButton::clicked, this, &MainWindow::onToggleButtonClicked);
+        for (auto *widget : left_button_station)
+        {
+            QPushButton *button = qobject_cast<QPushButton *>(widget);
+            if (button)
+            {
+                connect(button, &QPushButton::clicked, this, [this, button]
+                        { onButtonClicked(button); });
+            }
+        }
+        initDateTime();
+        initialBtnSerial();
+        // initialGPSSerial();
+        ui->labLat->setText("经度: " + lat);
+        ui->labLon->setText("维度: " + lon);
+        connect(ui->btnClose, &QPushButton::clicked, this, &MainWindow::close);
+        connect(this, &MainWindow::projectTitleChanged, this, &MainWindow::updateProjectTitleLabel);
+    }
+    catch (const std::exception &ex)
+    {
+        Logger::getInstance().error(QString("Application crashed: %1").arg(ex.what()));
+        QMessageBox::critical(this, "Error", QString("Application crashed: %1").arg(ex.what()));
+        throw; // rethrow to allow further handling if needed
+    }
+    catch (...)
+    {
+        Logger::getInstance().error("Application crashed: Unknown exception");
+        QMessageBox::critical(this, "Error", "Application crashed: Unknown exception");
+        throw;
     }
-    initDateTime();
-    initialBtnSerial();
-    // initialGPSSerial();
-    ui->labLat->setText("经度: "+lat);
-    ui->labLon->setText("维度: "+lon);
-    connect(ui->btnClose, &QPushButton::clicked, this, &MainWindow::close);
-    connect(this, &MainWindow::projectTitleChanged, this, &MainWindow::updateProjectTitleLabel);
 }
 
-void MainWindow::updateProjectTitleLabel(const QString &newTitle) {
+void MainWindow::updateProjectTitleLabel(const QString &newTitle)
+{
     ui->projectTitleLable->setText(newTitle);
 }
 
-void MainWindow::setProjectTitle(const QString &newTitle) {
-    if (m_currentProjectTitle != newTitle) {
+void MainWindow::setProjectTitle(const QString &newTitle)
+{
+    if (m_currentProjectTitle != newTitle)
+    {
         m_currentProjectTitle = newTitle;
 
         // Emit the signal to notify listeners (like our QLabel slot)
@@ -61,94 +81,110 @@ void MainWindow::setProjectTitle(const QString &newTitle) {
     }
 }
 
-void MainWindow::initializeAnimate() {
+void MainWindow::initializeAnimate()
+{
     move(200, 200);
     animate_leftFrame = new QPropertyAnimation(ui->leftFrame, "minimumWidth");
     animate_leftFrame->setDuration(300);
-    for (QObject *child : ui->left_buttonsBox->children()) {
-        if (qobject_cast<QWidget*>(child)) {
-            left_button_station.append(qobject_cast<QWidget*>(child));
+    for (QObject *child : ui->left_buttonsBox->children())
+    {
+        if (qobject_cast<QWidget *>(child))
+        {
+            left_button_station.append(qobject_cast<QWidget *>(child));
         }
     }
-
 }
 
-void MainWindow::onToggleButtonClicked() {
+void MainWindow::onToggleButtonClicked()
+{
     // 执行动画
     JOBS ::btn_animation(ui->leftFrame, animate_leftFrame);
-    for (QWidget *b : left_button_station) {
+    for (QWidget *b : left_button_station)
+    {
         b->setProperty("spread", !b->property("spread").toBool());
         b->setStyleSheet(b->styleSheet());
     }
 }
 
-    // 选中按钮
-void MainWindow::onButtonClicked(QPushButton  *button)
+// 选中按钮
+void MainWindow::onButtonClicked(QPushButton *button)
 {
     setStyleSheets(static_cast<QPushButton *>(button));
 
     switchPage(static_cast<QPushButton *>(button));
 }
 
+void MainWindow::switchPage(QWidget *button)
+{
+    LoadingWidget::showLoading(nullptr, "请稍等");
+    if (pageFactories.contains(button))
+    {
 
-void MainWindow::switchPage(QWidget *button) {
-    if (pageFactories.contains(button)) {
-
-        PageFactory* factory = pageFactories[button];
+        PageFactory *factory = pageFactories[button];
 
-        if (createdPageByButton.contains(button)) {
-            QWidget* existingPage = createdPageByButton[button];
+        if (createdPageByButton.contains(button))
+        {
+            QWidget *existingPage = createdPageByButton[button];
             existingPage->hide();
             ui->stackedWidget->removeWidget(existingPage);
             createdPageByButton.remove(button);
         }
 
-        QWidget* newPage = factory->createPage(this);
+        QWidget *newPage = factory->createPage(this);
+
         ui->stackedWidget->addWidget(newPage);
         ui->stackedWidget->setCurrentWidget(newPage);
-        setProjectTitle(qobject_cast<QPushButton*>(button)->text());
+        setProjectTitle(qobject_cast<QPushButton *>(button)->text());
 
         createdPageByButton.insert(button, newPage);
         int pageCount = ui->stackedWidget->count();
     }
+    LoadingWidget::hideLoading();
 }
 
-
 void MainWindow::initialMqttService()
 {
     Logger::getInstance().info("Start init Mqtt server.");
     MqttClient *pcMqttInit = MqttClient::getInstance();
-    QStringList topics = {"hxgc/topic","hxgc/companycode/pro/P"};
+    QStringList topics = {"hxgc/topic", "hxgc/companycode/pro/P"};
     pcMqttInit->connectToMqttBroker("114.55.233.194", 1883, "hxgc", "hxgc123456", "pcMqttInitY11", topics);
     connect(pcMqttInit, &MqttClient::proMessageReceived, this, &MainWindow::messageAndTopicReceived);
     Logger::getInstance().info("Connect Mqtt server request sent.");
 }
 
-void MainWindow::messageAndTopicReceived(const QByteArray &message, const QMqttTopicName &topic){
+void MainWindow::messageAndTopicReceived(const QByteArray &message, const QMqttTopicName &topic)
+{
     QJsonDocument jsonDoc = QJsonDocument::fromJson(message);
-    if (!jsonDoc.isNull() && jsonDoc.isObject()) {
+    if (!jsonDoc.isNull() && jsonDoc.isObject())
+    {
         QJsonObject jsonObj = jsonDoc.object();
-        if (jsonObj.contains("uuid")&& jsonObj.contains("status")) {
+        if (jsonObj.contains("uuid") && jsonObj.contains("status"))
+        {
             QJsonValue uuidValue = jsonObj["uuid"];
             QJsonValue statusValue = jsonObj["status"];
-            if (statusValue.isString() && statusValue.toString() == "1") { // "1" 未注册
-                if (uuidValue.isNull()) {
+            if (statusValue.isString() && statusValue.toString() == "1")
+            { // "1" 未注册
+                if (uuidValue.isNull())
+                {
                     qDebug() << "uuid 的值为 null";
-                } else {
+                }
+                else
+                {
                     QString uuid = uuidValue.toString();
                     HProjectDao dao = HProjectDao(DatabaseManager::getInstance().getDatabase());
-                    dao.updateBlastStatusByUuid(uuid,"2");
+                    dao.updateBlastStatusByUuid(uuid, "2");
                 }
             }
         }
     }
 }
 
-void MainWindow::setStyleSheets(QPushButton  *selectedButton)
+void MainWindow::setStyleSheets(QPushButton *selectedButton)
 {
-    for (auto *b : left_button_station) {
+    for (auto *b : left_button_station)
+    {
         b->setProperty("selected", b == selectedButton);
-        b->setStyleSheet(b->styleSheet());  // 刷新显示
+        b->setStyleSheet(b->styleSheet()); // 刷新显示
     }
 }
 
@@ -160,8 +196,9 @@ void MainWindow::onMqttConnected()
 }
 
 void MainWindow::initialBtnSerial()
-{   bool success;
-    serialTool = SerialTool::getInstance(this,&success);
+{
+    bool success;
+    serialTool = SerialTool::getInstance(this, &success);
     connect(serialTool, &SerialTool::serialPortOpened, this, &MainWindow::onSerialToolCreated);
     serialTool->setupSerialPort();
     Logger::getInstance().info("Fire buttons initialized");
@@ -175,30 +212,35 @@ void MainWindow::onSerialToolCreated()
     Logger::getInstance().info("SerialTool initialized");
 }
 
-void MainWindow::initialGPSSerial(){
+void MainWindow::initialGPSSerial()
+{
     Logger::getInstance().info("开始初始化GPS");
-    SerialGPSThread* threadGPS = new SerialGPSThread(this);
-    connect(threadGPS, &SerialGPSThread::storedGNRMCDataUpdated, this,&MainWindow::handleStoredGNRMCData);
+    SerialGPSThread *threadGPS = new SerialGPSThread(this);
+    connect(threadGPS, &SerialGPSThread::storedGNRMCDataUpdated, this, &MainWindow::handleStoredGNRMCData);
     threadGPS->start();
 }
 // 槽函数,用于接收 RMCData 数据
 void MainWindow::handleStoredGNRMCData(const RMCData &data)
 {
 
-    if(data.isValid){
-        lat  = QString::number(data.latitude);
-        lon  = QString::number(data.longitude);
-    }else{
-        lat  = "定位失败";
-        lon  = "定位失败";
+    if (data.isValid)
+    {
+        lat = QString::number(data.latitude);
+        lon = QString::number(data.longitude);
+    }
+    else
+    {
+        lat = "定位失败";
+        lon = "定位失败";
     }
 
-    ui->labLat->setText("经度: "+lat);
-    ui->labLon->setText("纬度: "+lon);
+    ui->labLat->setText("经度: " + lat);
+    ui->labLon->setText("纬度: " + lon);
     labLat = lat;
     labLon = lon;
 }
-void MainWindow::initDateTime(){
+void MainWindow::initDateTime()
+{
     timeThread = new TimeUpdateThread(this);
     connect(timeThread, &TimeUpdateThread::timeUpdated, this, &MainWindow::onTimeUpdated);
     timeThread->start();
@@ -216,7 +258,8 @@ MainWindow::~MainWindow()
 
 void MainWindow::mousePressEvent(QMouseEvent *event)
 {
-    if (event->button() == Qt::LeftButton) {
+    if (event->button() == Qt::LeftButton)
+    {
         m_dragPosition = event->globalPos() - frameGeometry().topLeft();
         event->accept();
     }
@@ -224,7 +267,8 @@ void MainWindow::mousePressEvent(QMouseEvent *event)
 
 void MainWindow::mouseMoveEvent(QMouseEvent *event)
 {
-    if (event->buttons() & Qt::LeftButton) {
+    if (event->buttons() & Qt::LeftButton)
+    {
         move(event->globalPos() - m_dragPosition);
         event->accept();
     }

+ 28 - 35
mqtt/mqttclient.cpp

@@ -4,8 +4,7 @@
 #include "../logger.h"
 #include <QMessageBox>
 
-
-MqttClient* MqttClient::instance = nullptr;
+MqttClient *MqttClient::instance = nullptr;
 
 MqttClient::MqttClient(QObject *parent)
     : QObject(parent), mqClient(new QMqttClient(this))
@@ -17,31 +16,29 @@ MqttClient::MqttClient(QObject *parent)
     connect(mqClient, &QMqttClient::errorChanged, this, &MqttClient::onError);
     connect(mqClient, &QMqttClient::messageReceived, this, &MqttClient::onMessageReceived);
 
-    connect(mqClient, &QMqttClient::errorChanged, this, [this](QMqttClient::ClientError error) {
-        Logger::getInstance().error(QString("MQTT error: %1").arg(error));
-    });
+    connect(mqClient, &QMqttClient::errorChanged, this, [this](QMqttClient::ClientError error)
+            { Logger::getInstance().error(QString("MQTT error: %1").arg(error)); });
 
     connect(mqClient, &QMqttClient::connected, this, &MqttClient::connected);
 }
 
 // 单例模式
-MqttClient* MqttClient::getInstance()
+MqttClient *MqttClient::getInstance()
 {
-    if (instance == nullptr) {
+    if (instance == nullptr)
+    {
         instance = new MqttClient();
     }
     return instance;
 }
 
-
-
-MqttClient* MqttClient::createNewInstance()
+MqttClient *MqttClient::createNewInstance()
 {
     return new MqttClient();
 }
 void MqttClient::connectToMqttBroker()
 {
-    qDebug() << "MQTT 1511: " ;
+    qDebug() << "MQTT 1511: ";
 
     mqClient->setHostname("114.55.233.194");
     mqClient->setPort(1883);
@@ -53,11 +50,9 @@ void MqttClient::connectToMqttBroker()
     // 设置客户端 ID
     mqClient->setClientId("pc");
     mqClient->connectToHost();
-
-
 }
 
-void MqttClient::connectToMqttBroker(const QString& hostname, quint16 port, const QString& username, const QString& password, const QString& clientId,const QStringList& topicsToSubscribe)
+void MqttClient::connectToMqttBroker(const QString &hostname, quint16 port, const QString &username, const QString &password, const QString &clientId, const QStringList &topicsToSubscribe)
 {
     mqClient->setHostname(hostname);
     mqClient->setPort(port);
@@ -71,7 +66,6 @@ void MqttClient::connectToMqttBroker(const QString& hostname, quint16 port, cons
     mqClient->connectToHost();
     // 保存要订阅的主题列表
     m_subscribeTopics = topicsToSubscribe;
-
 }
 void MqttClient::onConnected()
 {
@@ -79,12 +73,10 @@ void MqttClient::onConnected()
     subscribeToTopics(m_subscribeTopics);
 }
 
-
-
-
-void MqttClient::subscribeToTopics(const QStringList& topics)
+void MqttClient::subscribeToTopics(const QStringList &topics)
 {
-    for (const auto& topic : topics) {
+    for (const auto &topic : topics)
+    {
         subscribeToTopic(topic);
     }
 }
@@ -95,36 +87,38 @@ void MqttClient::subscribeToTopic(const QString &topic)
     mqClient->subscribe(topic);
 }
 
-
-
-void MqttClient:: sendMessage(const QString& topic, const QByteArray& message)
+void MqttClient::sendMessage(const QString &topic, const QByteArray &message, quint8 qos, bool isRetainedMsg)
 {
-    if (mqClient->state() == QMqttClient::Connected) {
-        quint8 qos = 1;
-        auto pub = mqClient->publish(QMqttTopicName(topic), message, qos, true);
+    if (mqClient->state() == QMqttClient::Connected)
+    {
+        auto pub = mqClient->publish(QMqttTopicName(topic), message, qos, isRetainedMsg);
         if (pub == -1)
             qDebug() << "Could not publish message";
         else
-            qDebug() << "Message published"<<message;
-    } else {
+            qDebug() << "Message published" << message;
+    }
+    else
+    {
         qDebug() << "Not connected to MQTT server";
-
     }
 }
 
 void MqttClient::onMessageReceived(const QByteArray &message, const QMqttTopicName &topic)
 {
-    if (topic.name() == "hxgc/companycode/pro/P") {
-        emit proMessageReceived(message,topic);
-    }else{
+    if (topic.name() == "hxgc/companycode/pro/P")
+    {
+        emit proMessageReceived(message, topic);
+    }
+    else
+    {
         emit messageAndTopicReceived(message, topic);
     }
-
 }
 
 void MqttClient::onStateChanged(QMqttClient::ClientState state)
 {
-    switch (state) {
+    switch (state)
+    {
     case QMqttClient::ClientState::Disconnected:
         QMessageBox::information(nullptr, "提示", "MQTT连接已断开,请重新登录");
         qDebug() << "MQTT 客户端状态: 断开连接";
@@ -142,7 +136,6 @@ void MqttClient::onStateChanged(QMqttClient::ClientState state)
     }
 }
 
-
 void MqttClient::onError(QMqttClient::ClientError error)
 {
 

+ 4 - 5
mqtt/mqttclient.h

@@ -1,7 +1,6 @@
 #ifndef MQTTCLIENT_H
 #define MQTTCLIENT_H
 
-
 #include <QObject>
 #include <QtMqtt/qmqttclient.h>
 #include <QtMqtt/qmqttmessage.h>
@@ -11,11 +10,11 @@ class MqttClient : public QObject
     Q_OBJECT
 
 public:
-    static MqttClient* getInstance();  // 静态成员函数,用于获取单例实例
-    static MqttClient* createNewInstance();
+    static MqttClient *getInstance(); // 静态成员函数,用于获取单例实例
+    static MqttClient *createNewInstance();
     explicit MqttClient(QObject *parent = nullptr);
     void subscribeToTopic(const QString &topic);
-    void sendMessage(const QString &topic, const QByteArray &message);
+    void sendMessage(const QString &topic, const QByteArray &message, quint8 qos, bool isRetainedMsg);
     void onMessageReceived(const QByteArray &message, const QMqttTopicName &topic);
     void connectToMqttBroker(const QString &hostname, quint16 port, const QString &username,
                              const QString &password, const QString &clientId, const QStringList &topicsToSubscribe);
@@ -34,7 +33,7 @@ private slots:
     // void onMessageReceived(const QByteArray &message, const QMqttTopicName &topic);
 
 private:
-    static MqttClient* instance;  // 静态成员变量,用于保存单例实例
+    static MqttClient *instance; // 静态成员变量,用于保存单例实例
     QMqttClient *mqClient;
     QStringList m_subscribeTopics;
 };

+ 12 - 8
mqttthread.cpp

@@ -1,4 +1,5 @@
 #include "mqttthread.h"
+#include "logger.h"
 #include "./mqtt/mqttclient.h" // 假设 MqttClient 类的头文件是 mqttclient.h
 
 MqttThread::MqttThread(QObject *parent) : QThread(parent)
@@ -10,12 +11,13 @@ MqttThread::~MqttThread()
     m_stopFlag = true;
     quit();
     wait();
-    if (mqttClient) {
+    if (mqttClient)
+    {
         delete mqttClient;
     }
 }
 
-void MqttThread::setConnectionInfo(const QString& hostname, quint16 port, const QString& username, const QString& password, const QString& clientId, const QStringList& topicsToSubscribe)
+void MqttThread::setConnectionInfo(const QString &hostname, quint16 port, const QString &username, const QString &password, const QString &clientId, const QStringList &topicsToSubscribe)
 {
     m_hostname = hostname;
     m_port = port;
@@ -25,7 +27,7 @@ void MqttThread::setConnectionInfo(const QString& hostname, quint16 port, const
     m_topicsToSubscribe = topicsToSubscribe;
 }
 
-MqttClient* MqttThread::getMqttClient() const
+MqttClient *MqttThread::getMqttClient() const
 {
     return mqttClient;
 }
@@ -45,15 +47,17 @@ void MqttThread::run()
     connect(mqttClient, &MqttClient::connected, this, &MqttThread::mqttConnected);
     connect(mqttClient, &MqttClient::messageAndTopicReceived, this, &MqttThread::messageAndTopicReceived);
     connect(this, &MqttThread::sendMessageRequested, mqttClient, &MqttClient::sendMessage);
-    while (!m_stopFlag) {
+    while (!m_stopFlag)
+    {
         exec();
     }
 }
 
-
-void MqttThread::sendMqttMessage(const QString& topic, const QByteArray& message)
+void MqttThread::sendMqttMessage(const QString &topic, const QByteArray &message, quint8 qos, bool isRetainedMsg)
 {
-    if (mqttClient) {
-        mqttClient->sendMessage(topic, message);
+    if (mqttClient)
+    {
+        Logger::getInstance().info(QString("发送MQTT消息到主题: %1, 消息: %2, qos: %3, isRetainMsg: %4").arg(topic, QString(message), qos, isRetainedMsg ? "true" : "false"));
+        mqttClient->sendMessage(topic, message, qos, isRetainedMsg);
     }
 }

+ 5 - 9
mqttthread.h

@@ -16,24 +16,21 @@ public:
     ~MqttThread();
     void stopThread();
 
-    void sendMqttMessage(const QString &topic, const QByteArray& message);
-    void setConnectionInfo(const QString& hostname, quint16 port, const QString& username, const QString& password, const QString& clientId, const QStringList& topicsToSubscribe);
-    MqttClient* getMqttClient() const;
-
+    void sendMqttMessage(const QString &topic, const QByteArray &message, quint8 qos, bool isRetainedMsg);
+    void setConnectionInfo(const QString &hostname, quint16 port, const QString &username, const QString &password, const QString &clientId, const QStringList &topicsToSubscribe);
+    MqttClient *getMqttClient() const;
 
 signals:
     void mqttConnected();
     // 转发 MQTT 消息接收信号
     void messageAndTopicReceived(const QByteArray &message, const QMqttTopicName &topic);
-    void sendMessageRequested(const QString& topic, const QByteArray& message);
-
-
+    void sendMessageRequested(const QString &topic, const QByteArray &message, quint8 qos, bool isRetainedMsg);
 
 protected:
     void run() override;
 
 private:
-    MqttClient* mqttClient = nullptr;
+    MqttClient *mqttClient = nullptr;
     QString m_hostname;
     quint16 m_port;
     QString m_username;
@@ -41,6 +38,5 @@ private:
     QString m_clientId;
     QStringList m_topicsToSubscribe;
     bool m_stopFlag = false;
-
 };
 #endif // MQTTTHREAD_H

+ 48 - 30
serial/serialtool.cpp

@@ -1,37 +1,42 @@
 #include "SerialTool.h"
 #include <QDebug>
+#include "../logger.h"
 
 // 定义静态成员变量并初始化为 nullptr
-SerialTool* SerialTool::instance = nullptr;
+SerialTool *SerialTool::instance = nullptr;
 QMutex SerialTool::globalMutex;
 SerialTool::SerialTool(QObject *parent) : QObject(parent)
 {
-
 }
 SerialTool::~SerialTool()
 {
-    if (serialPort.isOpen()) {
+    if (serialPort.isOpen())
+    {
         serialPort.close();
     }
 }
 
-SerialTool* SerialTool::getInstance(QObject *parent, bool* success)
+SerialTool *SerialTool::getInstance(QObject *parent, bool *success)
 {
 
-    if (instance == nullptr) {
+    if (instance == nullptr)
+    {
         instance = new SerialTool(parent);
     }
-    if (instance->isInUse) {
-        if (success) {
+    if (instance->isInUse)
+    {
+        if (success)
+        {
             *success = false;
         }
         return nullptr;
     }
     instance->isInUse = true;
-    if (success) {
+    if (success)
+    {
         *success = true;
     }
-//    globalMutex.unlock();
+    //    globalMutex.unlock();
     return instance;
 }
 // 打开串口的函数
@@ -40,16 +45,22 @@ void SerialTool::openSerialPort()
     const QString portName = "COM1";
     const qint32 baudRate = 9600;
 
-    if (!serialPort.isOpen()) {
+    if (!serialPort.isOpen())
+    {
         serialPort.setPortName(portName);
         serialPort.setBaudRate(baudRate);
 
         serialPort.setDataBits(QSerialPort::Data8);
         serialPort.setStopBits(QSerialPort::OneStop);
         serialPort.setParity(QSerialPort::NoParity);
-        if (serialPort.open(QIODevice::ReadWrite)) {
+        if (serialPort.open(QIODevice::ReadWrite))
+        {
+            Logger::getInstance().info(QString("串口 %1 打开成功").arg(portName));
             emit serialPortOpened(); // 发射新信号
-        } else {
+        }
+        else
+        {
+            Logger::getInstance().error(QString("串口 %1 打开错误").arg(portName));
             emit openError();
         }
     }
@@ -58,15 +69,17 @@ void SerialTool::openSerialPort()
 // 关闭串口的函数
 void SerialTool::closeSerialPort()
 {
-    if (serialPort.isOpen()) {
+    if (serialPort.isOpen())
+    {
         serialPort.close();
         emit openCloseButtonTextChanged("打开串口");
     }
 }
 
-bool SerialTool::sendData(const QByteArray& data)
+bool SerialTool::sendData(const QByteArray &data)
 {
-    if (serialPort.isOpen()) {
+    if (serialPort.isOpen())
+    {
         qint64 bytesWritten = serialPort.write(data);
         return bytesWritten == data.size();
     }
@@ -84,30 +97,37 @@ void SerialTool::readData()
     buffer.append(newData);
 
     int startIndex = buffer.indexOf("\r\n");
-    while (startIndex != -1) {
+    while (startIndex != -1)
+    {
         int endIndex = buffer.indexOf("\r\n", startIndex + 2);
-        if (endIndex != -1) {
+        if (endIndex != -1)
+        {
             QByteArray command = buffer.mid(startIndex + 2, endIndex - startIndex - 2);
             emit dataReceived(newData);
             // 根据 command 的值发射相应的信号
-                if (command == "BUTTON_DISABLED") {
-                    emit disableButtonReceived();
-                } else if (command == "BUTTON_PRESSED") {
-                        emit buttonPressedReceived();
-                } else if (command == "BUTTON_ENABLE") {
-                        emit enableButtonReceived();
-                }
+            if (command == "BUTTON_DISABLED")
+            {
+                emit disableButtonReceived();
+            }
+            else if (command == "BUTTON_PRESSED")
+            {
+                emit buttonPressedReceived();
+            }
+            else if (command == "BUTTON_ENABLE")
+            {
+                emit enableButtonReceived();
+            }
 
             buffer = buffer.mid(endIndex + 2);
-        } else {
+        }
+        else
+        {
             break;
         }
         startIndex = buffer.indexOf("\r\n");
     }
-
 }
 
-
 void SerialTool::setupSerialPort()
 {
     openSerialPort();
@@ -121,7 +141,5 @@ void SerialTool::releaseInstance()
 
 bool SerialTool::getIsInUse()
 {
-    return isInUse ;
+    return isInUse;
 }
-
-

この差分においてかなりの量のファイルが変更されているため、一部のファイルを表示していません