Przeglądaj źródła

firing stage code optmize; add config file

Yao 1 miesiąc temu
rodzic
commit
23df9cf985
11 zmienionych plików z 284 dodań i 198 usunięć
  1. 46 46
      blastopepage.cpp
  2. 4 4
      blastopepage.h
  3. 16 0
      config.ini_tpl
  4. 95 86
      fireWidget/firingwidget.cpp
  5. 16 36
      fireWidget/firingwidget.h
  6. 24 7
      global.cpp
  7. 64 4
      global.h
  8. 1 1
      login/loginwindow.cpp
  9. 2 5
      main.cpp
  10. 12 7
      mainwindow.cpp
  11. 4 2
      mainwindow.h

+ 46 - 46
blastopepage.cpp

@@ -431,37 +431,37 @@ void BlastOpePage::updateProgressBar(int firingStage, int row) {
         QProgressBar *progressBar2 = progressBars[row].bar2;
         QProgressBar *progressBar3 = progressBars[row].bar3;
         switch (firingStage) {
-            case 1:
+            case FiringStages::QuickTesting:
                 // 组网状态
                 progressBar1->setRange(0, 0);  // 设置范围为0到100
                 progressBar1->setValue(0);
                 break;
-            case 2:
+            case FiringStages::QuickTestFinished:
                 // 组网完成
                 progressBar1->setRange(0, 100);  // 设置范围为0到100
                 progressBar1->setValue(100);
                 break;
-            case 3:
+            case FiringStages::NetCharging:
                 // 充电开始
                 progressBar2->setRange(0, 0);  // 设置范围为0到100
                 progressBar2->setValue(0);
                 break;
-            case 4:
+            case FiringStages::NetChargingFinished:
                 // 充电完成
                 progressBar2->setRange(0, 100);  // 设置范围为0到100
                 progressBar2->setValue(100);
                 break;
-            case 5:
+            case FiringStages::Blasting:
                 // 起爆中
                 progressBar3->setRange(0, 0);  // 设置范围为0到100
                 progressBar3->setValue(0);
                 break;
-            case 6:
+            case FiringStages::BlastFinished:
                 // 充电完成
                 progressBar3->setRange(0, 100);  // 设置范围为0到100
                 progressBar3->setValue(100);
                 break;
-            case 0:
+            case FiringStages::NotStarted:
                 progressBar1->setRange(0, 100);
                 progressBar1->setValue(0);
                 progressBar2->setRange(0, 100);
@@ -476,53 +476,54 @@ void BlastOpePage::updateProgressBar(int firingStage, int row) {
 }
 
 void BlastOpePage::onFiringStageUpdated(int stage, int row) {
-    QModelIndex index = model->index(row, 7);
-    if (index.isValid()) {
+    QModelIndex firingStatusItem = model->index(row, 7);
+    if (firingStatusItem.isValid()) {
         QColor customColor;
         QFont boldFont;
         boldFont.setBold(true);
         switch (stage) {
-            case 0:
-                model->setData(index, "待起爆");
+            case FiringStages::NotStarted:
+                model->setData(firingStatusItem, "待起爆");
                 customColor = QColor("#44035b");
-                model->setData(index, customColor, Qt::ForegroundRole);
-                model->setData(index, boldFont, Qt::FontRole);
+                model->setData(firingStatusItem, customColor, Qt::ForegroundRole);
+                model->setData(firingStatusItem, boldFont, Qt::FontRole);
                 break;
-            case 1:
-                model->setData(index, "组 网 中 ...");
+            case FiringStages::QuickTesting:
+                model->setData(firingStatusItem, "组 网 中 ...");
                 customColor = QColor("#44035b");
-                model->setData(index, customColor, Qt::ForegroundRole);
-                model->setData(index, boldFont, Qt::FontRole);
+                model->setData(firingStatusItem, customColor, Qt::ForegroundRole);
+                model->setData(firingStatusItem, boldFont, Qt::FontRole);
                 break;
-            case 2:
-                model->setData(index, "组 网 完 成");
+            case FiringStages::QuickTestFinished:
+                model->setData(firingStatusItem, "组 网 完 成");
                 customColor = QColor("#404185");
-                model->setData(index, customColor, Qt::ForegroundRole);
+                model->setData(firingStatusItem, customColor, Qt::ForegroundRole);
                 break;
-            case 3:
-                model->setData(index, "充 电 中 ...");
+            case FiringStages::NetCharging:
+                model->setData(firingStatusItem, "充 电 中 ...");
                 customColor = QColor("#31688e");
-                model->setData(index, customColor, Qt::ForegroundRole);
+                model->setData(firingStatusItem, customColor, Qt::ForegroundRole);
                 break;
-            case 4:
-                model->setData(index, "充 电 完 成");
+            case FiringStages::NetChargingFinished:
+                model->setData(firingStatusItem, "充 电 完 成");
                 customColor = QColor("#1f918d");
-                model->setData(index, customColor, Qt::ForegroundRole);
+                model->setData(firingStatusItem, customColor, Qt::ForegroundRole);
                 break;
-            case 5:
-                model->setData(index, "起 爆 中 ...");
+            case FiringStages::Blasting:
+                model->setData(firingStatusItem, "起 爆 中 ...");
                 customColor = QColor("#38b775");
-                model->setData(index, customColor, Qt::ForegroundRole);
+                model->setData(firingStatusItem, customColor, Qt::ForegroundRole);
+                updateOpBtn(6, row);  // 更新按钮
                 break;
-            case 6:
-                model->setData(index, "起 爆 完 成");
+            case FiringStages::BlastFinished:
+                model->setData(firingStatusItem, "起 爆 完 成");
                 customColor = QColor("#90d543");
-                model->setData(index, customColor, Qt::ForegroundRole);
+                model->setData(firingStatusItem, customColor, Qt::ForegroundRole);
                 break;
-            case 10:
-                model->setData(index, "按 下 双 建 起 爆 ...");
+            case FiringStages::PendingTrigger:
+                model->setData(firingStatusItem, "按 下 双 建 起 爆 ...");
                 customColor = QColor("#8e620");
-                model->setData(index, customColor, Qt::ForegroundRole);
+                model->setData(firingStatusItem, customColor, Qt::ForegroundRole);
                 break;
             default:
                 break;
@@ -544,7 +545,7 @@ void BlastOpePage::handleSingleBlastButtonClick(int row, QPushButton *button) {
         button->setMinimumWidth(80);
         button->setText(stopBlastButtonTxt);
         firingWidget *widget = new firingWidget(row, false, uuid);
-        connect(widget, &firingWidget::progressChanged, this, &BlastOpePage::updateProgressBar);
+        connect(widget, &firingWidget::updateBlastStatus, this, &BlastOpePage::updateProgressBar);
         connect(widget, &firingWidget::updateBlastStatus, this, &BlastOpePage::onFiringStageUpdated);
         connect(widget, &firingWidget::updateButton, this, &BlastOpePage::updateOpBtn);
         connect(widget, &firingWidget::countdown, this, &BlastOpePage::showCountDownWidget);
@@ -656,12 +657,12 @@ void BlastOpePage::on_btnSelect_clicked() {
         }
 
         // 信号连接
-        connect(widgetSelect, &firingWidget::progressChanged, this, &BlastOpePage::updateProgressBar);
+        connect(widgetSelect, &firingWidget::updateBlastStatus, this, &BlastOpePage::updateProgressBar);
         connect(widgetSelect, &firingWidget::updateBlastStatus, this, &BlastOpePage::onFiringStageUpdated);
-        connect(widgetSelect, &firingWidget::selectSignal, this, &BlastOpePage::handleSelect);
+        connect(widgetSelect, &firingWidget::selectSignal, this, &BlastOpePage::setBatchBlastTrigger);
         connect(widgetSelect, &firingWidget::updateButton, this, &BlastOpePage::updateOpBtn);
         connect(widgetSelect, &firingWidget::updateProjectStatus, this, &BlastOpePage::handlerUpdateProjectStatus);
-        connect(widgetSelect, &firingWidget::closeFiring, this, &BlastOpePage::destroyFiringWidgetSelect);
+        connect(widgetSelect, &firingWidget::closeFiring, this, &BlastOpePage::destroyBatchFiringWidget);
         widgetSelect->show();
         widgetSelect->setAttribute(Qt::WA_DeleteOnClose);
         uuidWidgetSMap.insert(uuid, widgetSelect);
@@ -673,13 +674,13 @@ void BlastOpePage::on_btnSelect_clicked() {
 }
 
 // 完成充电
-void BlastOpePage::handleSelect(QString uuid) {
+void BlastOpePage::setBatchBlastTrigger(QString uuid) {
     selectedUuids.insert(uuid);
     bool isSame = checkUuidsSame();
     if (isSame) {
         bool successSelect;
         serialTool = SerialTool::getInstance(nullptr, &successSelect);
-        connect(serialTool, &SerialTool::buttonPressedReceived, this, &BlastOpePage::showDownWidgetSelect,
+        connect(serialTool, &SerialTool::buttonPressedReceived, this, &BlastOpePage::showCountDownForBatchBlast,
                 Qt::SingleShotConnection);
         if (serialTool) {
             QByteArray data = "\r\nENABLE_BUTTON\r\n";
@@ -713,13 +714,12 @@ void BlastOpePage::handleSelect(QString uuid) {
 bool BlastOpePage::checkUuidsSame() {
     QSet<QString> mapUuids;
     for (const auto &value : uuidMap) {
-        qDebug() << "value" << value;
         mapUuids.insert(value);
     }
     return selectedUuids == mapUuids;
 }
 
-void BlastOpePage::showDownWidgetSelect() {
+void BlastOpePage::showCountDownForBatchBlast() {
     QByteArray data = "\r\nDISABLE_BUTTON\r\n";
     bool success = serialTool->sendData(data);
     if (success) {
@@ -736,11 +736,11 @@ void BlastOpePage::showDownWidgetSelect() {
     countdownWidgetSelect->move(x, y);
     countdownWidgetSelect->show();
 
-    connect(countdownWidgetSelect, &CountdownWidget::countdownFinished, this, &BlastOpePage::triggerBlastSelected,
+    connect(countdownWidgetSelect, &CountdownWidget::countdownFinished, this, &BlastOpePage::triggerBatchFiringBlast,
             Qt::SingleShotConnection);
 }
 
-void BlastOpePage::triggerBlastSelected() {
+void BlastOpePage::triggerBatchFiringBlast() {
     for (auto it = uuidWidgetSMap.begin(); it != uuidWidgetSMap.end(); ++it) {
         QString uuid = it.key();
         firingWidget *widget = it.value();
@@ -750,7 +750,7 @@ void BlastOpePage::triggerBlastSelected() {
     }
 }
 
-void BlastOpePage::destroyFiringWidgetSelect(const QString &uuid) {
+void BlastOpePage::destroyBatchFiringWidget(const QString &uuid) {
     firingWidget *widget = uuidWidgetSMap.value(uuid);
     if (widget) {
         widget->close();

+ 4 - 4
blastopepage.h

@@ -52,10 +52,10 @@ class BlastOpePage : public QWidget {
     void destroyFiringWidget(const QString &uuid);
     void on_btnSelect_clicked();
     void onItemCheckboxChanged(QStandardItem *item);
-    void handleSelect(QString uuid);
-    void showDownWidgetSelect();
-    void triggerBlastSelected();
-    void destroyFiringWidgetSelect(const QString &uuid);
+    void setBatchBlastTrigger(QString uuid);
+    void showCountDownForBatchBlast();
+    void triggerBatchFiringBlast();
+    void destroyBatchFiringWidget(const QString &uuid);
 
    private:
     void handleFeaturePermission(QWebEnginePage *page, const QUrl &securityOrigin, QWebEnginePage::Feature feature);

+ 16 - 0
config.ini_tpl

@@ -0,0 +1,16 @@
+[General]
+api_backend_url=http://192.168.0.241:8000/api/v1/
+
+[Ports]
+firewidget_port=COM1
+gps_port=COM2
+
+[Database]
+host=127.0.0.1
+
+[MQTT]
+client_id="mqttclient_PC"
+topic="hxgc/companycode/pro/P"
+
+[UI]
+show_triggering_widget=false

+ 95 - 86
fireWidget/firingwidget.cpp

@@ -21,16 +21,13 @@
 #define ANSI_COLOR_GREEN "\x1B[32m"
 #define ANSI_COLOR_RESET "\x1B[0m"
 
-// Static constant definitions
-const int ErrorBlastStatusList::DEV_ERROR = 0xA0;
-const int ErrorBlastStatusList::BUS_SHORT = 0xA1;
-const int ErrorBlastStatusList::BUS_VOLTAGE_ERR = 0xA2;
-const int ErrorBlastStatusList::DET_OFFLINE_ERR = 0xA3;
+#define MSG_DATA_TYPE_BLASTING 1
+#define MSG_DATA_TYPE_RECORD 2
 
 firingWidget::firingWidget(const int &row, const bool &select, const QString &uuid, QWidget *parent)
     : QWidget(parent),
       ui(new Ui::firingWidget),
-      m_uuid(uuid),
+      m_curProjUuid(uuid),
       m_row(row),
       m_select(select),
       daoProj(DatabaseManager::getInstance().getDatabase()),
@@ -47,7 +44,8 @@ firingWidget::firingWidget(const int &row, const bool &select, const QString &uu
     ui->scrollArea->setStyleSheet("background: rgba(0, 0, 0, 22); border-radius: 20px;");
     ui->verticalLayout->addWidget(navProgress);
     mqttThread = new MqttThread(this);
-    QStringList topics = {"hxgc/" + uuid + "/B"};
+    m_topic = "hxgc/" + uuid + "/B";
+    QStringList topics = {m_topic};
     mqttThread->setConnectionInfo("114.55.233.194", 1883, "hxgc", "hxgc123456", "P" + uuid, topics);
     connect(mqttThread, &MqttThread::mqttConnected, this, &firingWidget::onMqttConnected);
     mqttThread->start();
@@ -57,7 +55,10 @@ firingWidget::firingWidget(const int &row, const bool &select, const QString &uu
     startBlasting();
 }
 
-firingWidget::~firingWidget() { delete ui; }
+firingWidget::~firingWidget() {
+    BlastingProjManager::removeBlastingProject(m_curProjUuid);
+    delete ui;
+}
 
 void firingWidget::sendMqttMessage(const QString &topic, const QByteArray &message) {
     if (mqttThread && m_isMqttConnected) {
@@ -69,7 +70,7 @@ void firingWidget::sendMqttMessage(const QString &topic, const QByteArray &messa
 
 void firingWidget::startBlasting() {
     QTimer::singleShot(1000, this, [this]() {
-        lastStage = 0;
+        m_lastStage = 0;
         emit lastStageChanged(0);
     });
 
@@ -124,7 +125,7 @@ void firingWidget::startBlasting() {
 //
 //     heartbeatThread->start();
 // }
-void firingWidget::on_pushButton_2_clicked() { emit countdown(m_uuid, topic, "message"); }
+void firingWidget::on_pushButton_2_clicked() { emit countdown(m_curProjUuid, m_topic, "message"); }
 
 // NOTE: aborted, changed to upload in the smartmine server side.
 bool firingWidget::uploadToDanLing(const QJsonObject &jsonObj) {
@@ -207,95 +208,107 @@ void firingWidget::handleProjectFiringMqttMessage(const QByteArray &message, con
     if (!jsonDoc.isNull() && jsonDoc.isObject()) {
         QJsonObject jsonObj = jsonDoc.object();
 
-        if (jsonObj.contains("type") && jsonObj["type"].toInt() == 1) {
+        if (jsonObj.contains("type") && jsonObj["type"].toInt() == MSG_DATA_TYPE_BLASTING) {
             if (jsonObj.contains("data") && jsonObj["data"].isObject()) {
-                QJsonObject dataObject = jsonObj["data"].toObject();
-                int status = dataObject["status"].toInt();
-                if (ErrorBlastStatusList::isErrorStatus(status)) {
+                QJsonObject relayInfo = jsonObj["data"].toObject();
+                int status = relayInfo["status"].toInt();
+                if (ErrorBlastStatus::isErrorStatus(status)) {
                     Logger::getInstance().error(QString("爆破器返回异常. 工程uuid: %1; 错误code: %2")
-                                                    .arg(m_uuid, ErrorBlastStatusList::getErrorMessage(status)));
-                    QMessageBox::critical(
-                        nullptr, "爆破器报错",
-                        QString("错误错误信息: %1").arg(ErrorBlastStatusList::getErrorMessage(status)));
+                                                    .arg(m_curProjUuid, ErrorBlastStatus::getErrorMessage(status)));
+                    QMessageBox::critical(nullptr, "爆破器报错",
+                                          QString("错误错误信息: %1").arg(ErrorBlastStatus::getErrorMessage(status)));
                     cancelBlasting();
                     return;
                 }
 
-                stage = dataObject["stage"].toInt();
-                if (stage != lastStage) {
-                    lastStage = stage;
+                stage = relayInfo["stage"].toInt();
+                if (stage != m_lastStage) {
+                    m_lastStage = stage;
                     switch (stage) {
-                        case 0:
-                            navProgress->setState(0);
+                        case FiringStages::NotStarted:
+                            navProgress->setState(FiringStages::NotStarted);
                             ui->pushButton_2->setText("立即测试");
                             ui->pushButton_2->setEnabled(false);
                             break;
-                        case 1:
-                            navProgress->setState(1);
-                            emit progressChanged(1, m_row);
-                            emit updateBlastStatus(1, m_row);
+                        case FiringStages::QuickTesting:
+                            navProgress->setState(FiringStages::QuickTesting);
+                            emit updateBlastStatus(FiringStages::QuickTesting, m_row);
                             ui->pushButton_2->setText("立即测试");
                             ui->pushButton_2->setEnabled(false);
                             break;
-                        case 2:
+                        case FiringStages::QuickTestFinished:
+                            // 组网测试检查报错雷管数量,如果有错误,提示用户确认是否继续
+                            if (relayInfo["errorCount"].toInt() > 0) {
+                                QMessageBox::StandardButton reply;
+                                reply = QMessageBox::question(nullptr, "组网测试错误",
+                                                              QString("组网测试发现 %1 个报错雷管,是否继续起爆?")
+                                                                  .arg(relayInfo["errorCount"].toInt()),
+                                                              QMessageBox::Yes | QMessageBox::No);
+                                if (reply == QMessageBox::No) {
+                                    cancelBlasting();
+                                    return;
+                                }
+                            }
                             ui->pushButton_2->setEnabled(true);
-                            emit progressChanged(2, m_row);
-                            emit updateBlastStatus(2, m_row);
-                            qDebug() << "stage:" << stage;
                             ui->pushButton_2->setText("充电");
-                            navProgress->setState(2);
+                            navProgress->setState(FiringStages::QuickTestFinished);
+
+                            emit progressChanged(FiringStages::QuickTestFinished, m_row);
+                            emit updateBlastStatus(FiringStages::QuickTestFinished, m_row);
                             break;
-                        case 3:
+                        case FiringStages::NetCharging:
                             ui->pushButton_2->setEnabled(false);
-                            emit progressChanged(3, m_row);
-                            emit updateBlastStatus(3, m_row);
+                            emit progressChanged(FiringStages::NetCharging, m_row);
+                            emit updateBlastStatus(FiringStages::NetCharging, m_row);
                             ui->pushButton_2->setText("充电");
-                            navProgress->setState(3);
+                            navProgress->setState(FiringStages::NetCharging);
                             break;
-                        case 4:
+                        case FiringStages::NetChargingFinished:
                             ui->pushButton_2->setEnabled(true);
-                            emit progressChanged(4, m_row);
-                            emit updateBlastStatus(4, m_row);
+                            emit progressChanged(FiringStages::NetChargingFinished, m_row);
+                            emit updateBlastStatus(FiringStages::NetChargingFinished, m_row);
                             ui->pushButton_2->setText("起爆");
-                            navProgress->setState(4);
+                            navProgress->setState(FiringStages::NetChargingFinished);
                             break;
-                        case 5:
+                        case FiringStages::Blasting:
                             ui->pushButton_2->setEnabled(false);
-                            emit progressChanged(5, m_row);
-                            emit updateBlastStatus(5, m_row);
-                            emit updateButton(5, m_row);
+                            emit progressChanged(FiringStages::Blasting, m_row);
+                            emit updateBlastStatus(FiringStages::Blasting, m_row);
+                            emit updateButton(FiringStages::Blasting, m_row);
                             ui->pushButton_2->setText("起爆");
-                            navProgress->setState(5);
+                            navProgress->setState(FiringStages::Blasting);
                             break;
-                        case 6:
+                        case FiringStages::BlastFinished:
                             ui->pushButton_2->setEnabled(false);
-                            emit progressChanged(6, m_row);
-                            emit updateBlastStatus(6, m_row);
-                            emit updateProjectStatus(m_uuid, BlastStatus::Blasted);
-                            emit updateButton(6, m_row);
+                            emit progressChanged(FiringStages::BlastFinished, m_row);
+                            emit updateBlastStatus(FiringStages::BlastFinished, m_row);
+                            emit updateProjectStatus(m_curProjUuid, BlastStatus::Blasted);
+                            emit updateButton(FiringStages::BlastFinished, m_row);
                             ui->pushButton_2->setText("已完成起爆");
-                            navProgress->setState(6);
+                            navProgress->setState(FiringStages::BlastFinished);
+                            emit closeFiring(m_curProjUuid);
                             break;
-                        case 7:
+                        case 7:  // TODO: ?
                             ui->pushButton_2->setEnabled(false);
-                            emit progressChanged(0, m_row);    // 发送进度值
-                            emit updateBlastStatus(0, m_row);  // 正在测试
                             ui->pushButton_2->setText("已完成起爆");
-                            navProgress->setState(6);
+                            emit progressChanged(0, m_row);
+                            emit updateBlastStatus(0, m_row);
+                            navProgress->setState(FiringStages::BlastFinished);
+                            emit closeFiring(m_curProjUuid);
                             break;
                         default:
                             break;
                     }
 
-                    emit lastStageChanged(lastStage);
+                    emit lastStageChanged(m_lastStage);
                 }
             }
         }
-        if (jsonObj.contains("type") && jsonObj["type"].toInt() == 2) {
+        if (jsonObj.contains("type") && jsonObj["type"].toInt() == MSG_DATA_TYPE_RECORD) {
             if (jsonObj.contains("data") && jsonObj["data"].isObject()) {
                 QJsonObject dataObject = jsonObj["data"].toObject();
                 emit updateData(dataObject);
-                emit closeFiring(m_uuid);
+                emit closeFiring(m_curProjUuid);
             }
         }
     }
@@ -307,7 +320,7 @@ void firingWidget::onCountdownFinished(const QString &topic, const QString &mess
 }
 
 void firingWidget::onMqttConnected() {
-    Logger::getInstance().info(QString("Project(%1) firing MQTT connected successfully.").arg(m_uuid));
+    Logger::getInstance().info(QString("Project(%1) firing MQTT connected successfully.").arg(m_curProjUuid));
     m_isMqttConnected = true;
 }
 
@@ -319,27 +332,27 @@ void firingWidget::onButtonPressedReceived(const QString &topic, const QString &
         Logger::getInstance().error(QString("onButtonPressedReceived: Failed to send data: %1").arg(data));
         return;
     }
-    emit countdown(m_uuid, topic, message);
+    emit countdown(m_curProjUuid, topic, message);
     qDebug() << "Data sent successfully";
 }
 
 void firingWidget::onSafeChecked(const QString projectUuid) {
-    if (projectUuid == m_uuid) {
-        lastStage = 3;  // 设置为待安全确认状态
-        emit projSafeCheckSuccess(m_uuid);
-        emit lastStageChanged(lastStage);
+    if (projectUuid == m_curProjUuid) {
+        m_lastStage = 3;  // 设置为待安全确认状态
+        emit projSafeCheckSuccess(m_curProjUuid);
+        emit lastStageChanged(m_lastStage);
         qDebug() << ANSI_COLOR_GREEN << "安全确认成功,进入待起爆状态" << ANSI_COLOR_RESET;
     } else {
-        qDebug() << "Project UUID mismatch, expected: " << m_uuid << ", got: " << projectUuid;
+        qDebug() << "Project UUID mismatch, expected: " << m_curProjUuid << ", got: " << projectUuid;
     }
 }
 
 // 状态改变
 void firingWidget::handleFiringStageChanged(int newStage) {
-    QString topic = "hxgc/" + m_uuid + "/P";
+    QString topic = "hxgc/" + m_curProjUuid + "/P";
     QString message;
     QString buttonText;
-    switch (lastStage) {
+    switch (newStage) {
         case 0:
             message = "起爆测试";
             buttonText = "立即测试";
@@ -376,7 +389,7 @@ void firingWidget::handleFiringStageChanged(int newStage) {
     }
 
     if (!message.isEmpty()) {
-        if (lastStage == 4 && !m_select) {
+        if (m_lastStage == FiringStages::NetChargingFinished && !m_select) {
             bool success2;
             serialTool = SerialTool::getInstance(nullptr, &success2);
             if (serialTool) {
@@ -395,11 +408,11 @@ void firingWidget::handleFiringStageChanged(int newStage) {
             } else {
                 qDebug() << "serialTool Not fond.";
                 // 在准备起爆状态下 但是没有获取串口
-                lastStage = 10;
+                m_lastStage = 10;
             }
-        } else if (lastStage == 4 && m_select) {
+        } else if (m_lastStage == FiringStages::NetChargingFinished && m_select) {
             qDebug() << "多台起爆:待起爆状态";
-            emit selectSignal(m_uuid);
+            emit selectSignal(m_curProjUuid);
         } else {  //????
             qDebug() << "Stage 值变为: " << newStage << "发送消息" << message.toUtf8();
         }
@@ -407,15 +420,14 @@ void firingWidget::handleFiringStageChanged(int newStage) {
 }
 
 void firingWidget::cancelBlasting() {
-    emit progressChanged(0, m_row);  // 重置进度
+    emit progressChanged(0, m_row);
     emit updateBlastStatus(0, m_row);
-    emit updateProjectStatus(m_uuid, BlastStatus::Created);
-    // TODO: 重置状态为已注册
+    emit updateProjectStatus(m_curProjUuid, BlastStatus::Created);
 
-    // QString message = "取消流程";
-    // if (!message.isEmpty()) {
-    //     sendMqttMessage(topic, message.toUtf8());
-    // }
+    QString message = "取消流程";
+    if (!message.isEmpty()) {
+        sendMqttMessage(m_topic, message.toUtf8());
+    }
 }
 void firingWidget::on_sendTest_4_clicked() {}
 
@@ -423,8 +435,6 @@ void firingWidget::testOnBlastSuccess(const QJsonObject &jsonObj) { onBlastSucce
 // 处理爆破成功,安全验证装置通过MQTT传回的数据
 void firingWidget::onBlastSuccess(const QJsonObject &jsonObj) {
     Logger::getInstance("blastRecord.log").info(QJsonDocument(jsonObj).toJson(QJsonDocument::Indented));
-    blast_uuid = QUuid::createUuid().toString(QUuid::WithoutBraces).remove(QRegularExpression("-"));
-
     saveAndUploadRecord(jsonObj);
 }
 
@@ -462,14 +472,13 @@ void firingWidget::saveAndUploadRecord(const QJsonObject &jsonObj) {
     blastRecord->setEquipmentRecords(blastEquipmentRecords);
 
     if (db.commit()) {
-        Logger::getInstance().info(QString("Transaction committed successfully. blast_uuid: %1").arg(blast_uuid));
+        Logger::getInstance().info(
+            QString("Transaction committed successfully. blast_uuid: %1").arg(blastRecord->getUuid()));
     } else {
         Logger::getInstance().error(QString("Failed to commit transaction: %1. try to rollback: %2")
                                         .arg(db.lastError().text(), db.rollback() ? "success" : "failed"));
         return;
     }
-
-    qDebug() << "Transaction committed successfully for blast record with uuid:" << blastRecord->getUuid();
     uploadBlastRecordToServer(blastRecord);
 }
 
@@ -487,6 +496,8 @@ void firingWidget::uploadBlastRecordToServer(HBlastRecord *blastRecord) {
 
 HBlastRecord *firingWidget::recordBlastProject(const QJsonObject &jsonObj) {
     HBlastRecord *record = new HBlastRecord();
+
+    record->setUuid(QUuid::createUuid().toString(QUuid::WithoutBraces).remove(QRegularExpression("-")));
     record->setIsOfflineBlast(jsonObj["is_offline_blast"].toString() == "true");
     record->setProjectName(jsonObj["project_name"].toString());
     record->setProjectHtid(jsonObj["project_htid"].toString());
@@ -507,7 +518,6 @@ HBlastRecord *firingWidget::recordBlastProject(const QJsonObject &jsonObj) {
     QDateTime blastTime = QDateTime::fromString(jsonObj["blast_time"].toString(), "yyyy-MM-dd hh:mm:ss");
     record->setBlastAt(blastTime);
     record->setCreatedAt(QDateTime::currentDateTime());
-    record->setUuid(blast_uuid);
 
     if (daoProj.addHBlastRecord(*record)) {
         qDebug() << "Record inserted successfully.";
@@ -521,8 +531,7 @@ HBlastRecord *firingWidget::recordBlastProject(const QJsonObject &jsonObj) {
 
 HBlastEquipmentRecord *firingWidget::recordBlastEquipment(const QString blastProjectUuid, const QJsonObject &regObj) {
     HBlastEquipmentRecord *recordReg = new HBlastEquipmentRecord();
-    reg_uuid = QUuid::createUuid().toString(QUuid::WithoutBraces).remove(QRegularExpression("-"));
-    recordReg->setUuid(reg_uuid);
+    recordReg->setUuid(QUuid::createUuid().toString(QUuid::WithoutBraces).remove(QRegularExpression("-")));
     recordReg->setEquipSn(regObj["equipment_sn"].toString());
     recordReg->setEquipVersion(regObj["equipment_version"].toString());
     recordReg->setRegDetoCount(regObj["reg_deto_count"].toString().toInt());

+ 16 - 36
fireWidget/firingwidget.h

@@ -17,40 +17,22 @@
 #include "../serial/serialtool.h"
 #include "navprogress.h"
 
+/* ref: 起爆器端协议
+public class Reply{
+   private int status=0;
+   private String msg = "”;
+   private int regcount = 0;
+   private int errorCount =0;
+   private int busVoltage = 0;
+   private int buscurrent =0;
+   private int stage = 1;//组网中,组网完成,充电中,充电完成, 起爆中,起爆完成
+}
+*/
 namespace Ui {
 class firingWidget;
 }
 
 // Error status codes for device and bus issues
-class ErrorBlastStatusList {
-   public:
-    // Error code constants
-    static const int DEV_ERROR;        // Device exception
-    static const int BUS_SHORT;        // Bus short circuit
-    static const int BUS_VOLTAGE_ERR;  // Bus voltage abnormal
-    static const int DET_OFFLINE_ERR;  // Detonator offline
-
-    // Check if a status code exists in the error list
-    static bool isErrorStatus(int code) { return getErrorMap().find(code) != getErrorMap().end(); }
-
-    // Get error message for a status code
-    static QString getErrorMessage(int code) {
-        const auto &map = getErrorMap();
-        auto it = map.find(code);
-        return (it != map.end()) ? it->second : "Unknown error";
-    }
-
-   private:
-    // Internal function to get the error map (lazy initialization)
-    static const std::map<int, QString> &getErrorMap() {
-        static const std::map<int, QString> errorMap = {{DEV_ERROR, "设备异常"},
-                                                        {BUS_SHORT, "总线短路"},
-                                                        {BUS_VOLTAGE_ERR, "总线电压异常"},
-                                                        {DET_OFFLINE_ERR, "雷管掉线"}};
-        return errorMap;
-    }
-};
-
 class firingWidget : public QWidget {
     Q_OBJECT
 
@@ -108,18 +90,16 @@ class firingWidget : public QWidget {
     NavProgress *navProgress;
     MqttThread *mqttThread;
     SerialTool *serialTool = nullptr;
-    QString m_uuid;      // 用于存储 uuid
-    QString reg_uuid;    // 用于存储 uuid
-    QString blast_uuid;  // 用于存储 uuid
-    QString topic;
+    QString m_curProjUuid;
+    QString m_topic;  // firingwidget对应的 MQTT 主题
     int m_row;
-    int lastStage = -1;  // 用于记录上一次的 stage 状态
+    int m_lastStage = -1;  // 用于记录上一次的 stage 状态
     bool m_isMqttConnected = false;
     bool m_select;
     QMetaObject::Connection connection;  // 声明 connection 变量
     QMetaObject::Connection connectionPress;
-    QString lat;
-    QString lon;
+    QString m_latitude;
+    QString m_longitude;
 };
 
 #endif  // FIRINGWIDGET_H

+ 24 - 7
global.cpp

@@ -1,12 +1,29 @@
 #include "global.h"
 
-QUrl apiBackendUrl("http://192.168.0.241:8000/api/v1/");  // 定义并初始化全局变量
+#include <QSettings>
+
+#include "logger.h"
+
+QUrl apiBackendUrl;  // 定义并初始化全局变量
 QString labLat("未知");
 QString labLon("未知");
 QString globalAuthority;
-QString firewidgetPort("COM1");  // 4 for dev; 1: 爆破装
-QString gpsPort("COM3");
-QString databaseHost("192.168.0.241");
-QString mqttClientId("mqttclient_OnDevPC");
-QString MQTT_TOPIC_COMPANY_PROJECTS("hxgc/companycode/pro/P");
-bool isShowTriggeringWidget = false;
+QString firewidgetPort;  // 4 for dev; 1: 爆破装置
+QString gpsPort;
+QString databaseHost;
+QString mqttClientId;
+QString MQTT_TOPIC_COMPANY_PROJECTS;
+bool isShowTriggeringWidget;
+
+void loadConfig() {
+    QSettings settings("config.ini", QSettings::IniFormat);
+
+    // Remove local variable declarations and assign directly to global variables
+    apiBackendUrl = QUrl(settings.value("api_backend_url", "http://192.168.0.241:8000/api/v1/").toString());
+    firewidgetPort = settings.value("Ports/firewidget_port", "COM1").toString();
+    gpsPort = settings.value("Ports/gps_port", "COM3").toString();
+    databaseHost = settings.value("Database/host", "127.0.0.1").toString();
+    mqttClientId = settings.value("MQTT/client_id", "mqttclient_PC").toString();
+    MQTT_TOPIC_COMPANY_PROJECTS = settings.value("MQTT/topic", "hxgc/companycode/pro/P").toString();
+    isShowTriggeringWidget = settings.value("UI/show_triggering_widget", false).toBool();
+}

+ 64 - 4
global.h

@@ -7,16 +7,36 @@
 
 #include "logger.h"
 
-extern QUrl apiBackendUrl;  // 声明全局变量
-extern QString labLat;      // 新增的全局变量声明
-extern QString labLon;      // 新增的全局变量声明
-extern QString globalAuthority;
+extern QUrl apiBackendUrl;                   // 声明全局变量
 extern QString firewidgetPort;               // 点火装置串口号
 extern QString gpsPort;                      // gps串口号
 extern QString databaseHost;                 // pc数据库地址
 extern QString mqttClientId;                 // mqtt客户端ID
 extern QString MQTT_TOPIC_COMPANY_PROJECTS;  // 每个部署点(公司)唯一地址
 extern bool isShowTriggeringWidget;          // 是否显示点火装置触发中调试组件
+extern void loadConfig();                    // 声明全局函数
+
+extern QString globalAuthority;
+extern QString labLat;  // 新增的全局变量声明
+extern QString labLon;  // 新增的全局变量声明
+
+// BlastingProjManager namespace for managing blasting projects
+namespace BlastingProjManager {
+inline std::vector<QString> blastingProjectUuids;
+
+inline void addBlastingProject(const QString& uuid) { blastingProjectUuids.push_back(uuid); }
+
+inline void removeBlastingProject(const QString& uuid) {
+    auto it = std::find(blastingProjectUuids.begin(), blastingProjectUuids.end(), uuid);
+    if (it != blastingProjectUuids.end()) {
+        blastingProjectUuids.erase(it);
+    }
+}
+
+inline int getBlastingProjectCount() { return blastingProjectUuids.size(); }
+
+inline const std::vector<QString>& getBlastingProjectUuids() { return blastingProjectUuids; }
+}  // namespace BlastingProjManager
 
 /* BlastStatus*/
 namespace BlastStatus {
@@ -35,4 +55,44 @@ const QString ErrorOccurred = "爆破异常";
 const QString SafeChecked = "已安全检查";
 }  // namespace BlastStatusNames
 
+namespace ErrorBlastStatus {
+// Error code constants
+const int DEV_ERROR = 0xA0;
+const int BUS_SHORT = 0xA1;
+const int BUS_VOLTAGE_ERR = 0xA2;
+const int DET_OFFLINE_ERR = 0xA3;
+
+// Internal function to get the error map (lazy initialization)
+inline const std::map<int, QString>& getErrorMap() {
+    static const std::map<int, QString> errorMap = {{DEV_ERROR, "设备异常"},
+                                                    {BUS_SHORT, "总线短路"},
+                                                    {BUS_VOLTAGE_ERR, "总线电压异常"},
+                                                    {DET_OFFLINE_ERR, "雷管掉线"}};
+    return errorMap;
+}
+
+// Check if a status code exists in the error list
+inline bool isErrorStatus(int code) { return getErrorMap().find(code) != getErrorMap().end(); }
+
+// Get error message for a status code
+inline QString getErrorMessage(int code) {
+    const auto& map = getErrorMap();
+    auto it = map.find(code);
+    return (it != map.end()) ? it->second : "Unknown error";
+}
+}  // namespace ErrorBlastStatus
+
+// namespace FiringStages
+namespace FiringStages {
+const static int NotStarted = 0;
+const static int QuickTesting = 1;         // 组网测试中
+const static int QuickTestFinished = 2;    // 组网测试完成
+const static int NetCharging = 3;          // 组网充电中
+const static int NetChargingFinished = 4;  // 组网充电完成
+const static int Blasting = 5;             // 爆破中
+const static int BlastFinished = 6;        // 爆破完成
+const static int PendingTrigger = 10;      // 待触发按钮触发起爆
+}  // namespace FiringStages
+// namespace FiringStages
+
 #endif  // GLOBAL_H

+ 1 - 1
login/loginwindow.cpp

@@ -52,7 +52,7 @@ void LoginWindow::on_btnLogin_clicked() {
         jsonData["password"] = password;
         QJsonDocument doc(jsonData);
         QByteArray data = doc.toJson();
-
+        qDebug() << "Login request data:" << apiBackendUrl;
         QUrl fullUrl = apiBackendUrl.resolved(QUrl("login/pc"));  // 替换为实际的服务器接口地址
         QNetworkRequest request(fullUrl);                         // 替换为实际的服务器接口地址
         request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");

+ 2 - 5
main.cpp

@@ -5,6 +5,7 @@
 
 #include "backendapimanager.h"
 #include "fireWidget/firingwidget.h"
+#include "global.h"
 #include "logger.h"
 #include "loginwindow.h"
 #include "mainwindow.h"
@@ -22,11 +23,6 @@ int main(int argc, char *argv[]) {
         app.setStyleSheet(styleSheet);
         styleFile.close();
     }
-    // // 获取屏幕信息
-    // QScreen *screen = QGuiApplication::primaryScreen();
-    // QRect screenGeometry = screen->geometry();
-    // int screenWidth = screenGeometry.width();
-    // int screenHeight = screenGeometry.height();
 
     // logger
     Logger::getInstance("application.log");
@@ -35,6 +31,7 @@ int main(int argc, char *argv[]) {
     Logger::getInstance().setMaxBackupFiles(3);             // Keep 3 backup files
     Logger::getInstance().info("Application started from main.");
 
+    loadConfig();
     backendAPIManager::initialize(apiBackendUrl.toString());
 
     // MainWindow w;

+ 12 - 7
mainwindow.cpp

@@ -51,7 +51,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi
         ui->labLat->setText("经度: " + lat);
         ui->labLon->setText("维度: " + lon);
         connect(ui->btnClose, &QPushButton::clicked, this, &MainWindow::close);
-        connect(this, &MainWindow::projectTitleChanged, this, &MainWindow::updateProjectTitleLabel);
+        connect(this, &MainWindow::menubarTitleChanged, 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()));
@@ -65,12 +65,17 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi
 
 void MainWindow::updateProjectTitleLabel(const QString &newTitle) { ui->projectTitleLable->setText(newTitle); }
 
-void MainWindow::setProjectTitle(const QString &newTitle) {
+void MainWindow::handleRefreshPage() {
+    // 刷新页面
+    ui->stackedWidget->currentWidget()->update();
+}
+
+void MainWindow::setMenubarTitle(const QString &newTitle) {
     if (m_currentProjectTitle != newTitle) {
         m_currentProjectTitle = newTitle;
 
         // Emit the signal to notify listeners (like our QLabel slot)
-        emit projectTitleChanged(m_currentProjectTitle);
+        emit menubarTitleChanged(m_currentProjectTitle);
     }
 }
 
@@ -117,7 +122,7 @@ void MainWindow::switchPage(QWidget *button) {
 
         ui->stackedWidget->addWidget(newPage);
         ui->stackedWidget->setCurrentWidget(newPage);
-        setProjectTitle(qobject_cast<QPushButton *>(button)->text());
+        setMenubarTitle(qobject_cast<QPushButton *>(button)->text());
 
         createdPageByButton.insert(button, newPage);
         int pageCount = ui->stackedWidget->count();
@@ -156,7 +161,7 @@ void MainWindow::handleMqttProjectsMessage(const QByteArray &message, const QMqt
         } else if (jsonObj.contains("msgType") && jsonObj["msgType"].toString() == "safeCheck") {
             // 处理安全验证消息
             if (jsonObj["status"] != "ok") {
-                QMessageBox::warning(this, "安全验证失败", QString("安全验证未通过,练习安全员确认"));
+                QMessageBox::warning(this, "安全验证失败", QString("安全验证未通过,请联系安全员确认"));
                 return;
             }
 
@@ -167,7 +172,7 @@ void MainWindow::handleMqttProjectsMessage(const QByteArray &message, const QMqt
             subAddressUuids.append(addressUuid);  // 添加当前地址的 UUID
             qDebug() << "子地址 UUIDs: " << subAddressUuids << "-----" << addressUuid;
             if (subAddressUuids.isEmpty()) {
-                QMessageBox::information(nullptr, "安全验证失败", QString("未找到子地址,练习安全员确认"));
+                QMessageBox::information(nullptr, "安全验证失败", QString("未找到子地址,请联系安全员确认"));
                 return;
             }
             HProjectDao dao = HProjectDao(DatabaseManager::getInstance().getDatabase());
@@ -178,9 +183,9 @@ void MainWindow::handleMqttProjectsMessage(const QByteArray &message, const QMqt
             }
             if (!pendingCheckProjects.isEmpty()) {
                 QMessageBox::information(nullptr, "安全员确认信息", QString("收到工程被安全员确认,请查看爆破列表"));
+                emit refreshPage();
                 return;
             }
-            // TODO: refresh the project list page
         }
     }
 }

+ 4 - 2
mainwindow.h

@@ -33,10 +33,11 @@ class MainWindow : public QMainWindow {
     MainWindow(QWidget *parent = nullptr);
     ~MainWindow();
 
-    void setProjectTitle(const QString &newTitle);
+    void setMenubarTitle(const QString &newTitle);
 
    signals:
-    void projectTitleChanged(const QString &newTitle);
+    void menubarTitleChanged(const QString &newTitle);
+    void refreshPage();
 
    private slots:
     void onToggleButtonClicked();
@@ -44,6 +45,7 @@ class MainWindow : public QMainWindow {
     void handleStoredGNRMCData(const RMCData &data);
     void onTimeUpdated(const QString &timeString);
     void updateProjectTitleLabel(const QString &newTitle);
+    void handleRefreshPage();
 
     void handleMqttProjectsMessage(const QByteArray &message, const QMqttTopicName &topic);