Browse Source

地下矿山无线起爆系统

leslie 2 months ago
parent
commit
223f87b7d5
100 changed files with 10586 additions and 0 deletions
  1. 155 0
      CMakeLists.txt
  2. 39 0
      HttpClient.h
  3. 235 0
      PageWidget.cpp
  4. 66 0
      PageWidget.h
  5. 157 0
      PageWidget.ui
  6. 110 0
      QframeTest01.pro
  7. 11 0
      addressfactory.cpp
  8. 14 0
      addressfactory.h
  9. 83 0
      addresspage.cpp
  10. 37 0
      addresspage.h
  11. 99 0
      addresspage.ui
  12. BIN
      background/baseWidget.png
  13. BIN
      background/baseWidget2.png
  14. BIN
      background/blastOpera.png
  15. BIN
      blast.ico
  16. 37 0
      blastProject/HProjectDao.h
  17. 11 0
      blastProject/blastprojectfactory.cpp
  18. 14 0
      blastProject/blastprojectfactory.h
  19. 338 0
      blastProject/blastprojectpage.cpp
  20. 66 0
      blastProject/blastprojectpage.h
  21. 175 0
      blastProject/blastprojectpage.ui
  22. 266 0
      blastProject/hproject.cpp
  23. 144 0
      blastProject/hproject.h
  24. 217 0
      blastProject/hprojectdao.cpp
  25. 349 0
      blastProject/projectdialog.cpp
  26. 72 0
      blastProject/projectdialog.h
  27. 168 0
      blastProject/projectdialog.ui
  28. 134 0
      blastRecord/HBlastRecord.h
  29. 146 0
      blastRecord/blastrecord.cpp
  30. 48 0
      blastRecord/blastrecord.h
  31. 106 0
      blastRecord/blastrecord.ui
  32. 10 0
      blastRecord/blastrecordfactory.cpp
  33. 13 0
      blastRecord/blastrecordfactory.h
  34. 255 0
      blastRecord/hblastrecord.cpp
  35. 202 0
      blastRecord/hblastrecorddao.cpp
  36. 32 0
      blastRecord/hblastrecorddao.h
  37. 190 0
      blastRecord/hblastrecorddet.cpp
  38. 102 0
      blastRecord/hblastrecorddet.h
  39. 103 0
      blastRecordDet/HBlastRecordDet.h
  40. 191 0
      blastRecordDet/hblastrecorddet.cpp
  41. 110 0
      blastRecordDet/hblastrecorddetdao.cpp
  42. 25 0
      blastRecordDet/hblastrecorddetdao.h
  43. 223 0
      blastRegRecord/hblastregrecord.cpp
  44. 118 0
      blastRegRecord/hblastregrecord.h
  45. 110 0
      blastRegRecord/hblastregrecorddao.cpp
  46. 24 0
      blastRegRecord/hblastregrecorddao.h
  47. 659 0
      blastopepage.cpp
  48. 93 0
      blastopepage.h
  49. 185 0
      blastopepage.ui
  50. 11 0
      blastoperationfactory.cpp
  51. 13 0
      blastoperationfactory.h
  52. 11 0
      blastprojectfactory.cpp
  53. 299 0
      blastprojectpage.cpp
  54. 61 0
      blastprojectpage.h
  55. 56 0
      btnserialthread.cpp
  56. 28 0
      btnserialthread.h
  57. 91 0
      btnserialtool.cpp
  58. 31 0
      btnserialtool.h
  59. 60 0
      buttondelegate.cpp
  60. 39 0
      buttondelegate.h
  61. 62 0
      clickabletableview.cpp
  62. 16 0
      clickabletableview.h
  63. 48 0
      countdownwidget.cpp
  64. 29 0
      countdownwidget.h
  65. 30 0
      databasemanager.cpp
  66. 19 0
      databasemanager.h
  67. 90 0
      des3encryption.cpp
  68. 30 0
      des3encryption.h
  69. 93 0
      detInfo/detdialog.cpp
  70. 31 0
      detInfo/detdialog.h
  71. 108 0
      detInfo/detdialog.ui
  72. 11 0
      detInfo/detinfofactory.cpp
  73. 16 0
      detInfo/detinfofactory.h
  74. 166 0
      detInfo/detinfopage.cpp
  75. 66 0
      detInfo/detinfopage.h
  76. 144 0
      detInfo/detinfopage.ui
  77. 11 0
      equipment/equipmentfactory.cpp
  78. 13 0
      equipment/equipmentfactory.h
  79. 120 0
      equipment/equipmentpage.cpp
  80. 49 0
      equipment/equipmentpage.h
  81. 264 0
      equipment/equipmentpage.ui
  82. 11 0
      equipmentfactory.cpp
  83. 13 0
      equipmentfactory.h
  84. 119 0
      equipmentpage.cpp
  85. 22 0
      equipmentpage.h
  86. 135 0
      equipmentpage.ui
  87. 135 0
      equipmnentpage.ui
  88. 636 0
      fireWidget/firingwidget.cpp
  89. 84 0
      fireWidget/firingwidget.h
  90. 272 0
      fireWidget/firingwidget.ui
  91. 286 0
      fireWidget/navprogress.cpp
  92. 78 0
      fireWidget/navprogress.h
  93. 6 0
      global.cpp
  94. 12 0
      global.h
  95. 11 0
      hblastrecorddao.h
  96. 233 0
      hproject.cpp
  97. 129 0
      hproject.h
  98. 182 0
      hprojectdao.cpp
  99. 50 0
      hprojectdao.h
  100. 114 0
      httpclient.cpp

+ 155 - 0
CMakeLists.txt

@@ -0,0 +1,155 @@
+cmake_minimum_required(VERSION 3.16)
+
+project(pc_system LANGUAGES CXX)
+
+# 启用 Qt 的自动 UI、MOC 和资源处理
+set(CMAKE_AUTOUIC ON)
+set(CMAKE_AUTOMOC ON)
+set(CMAKE_AUTORCC ON)
+# 设置 C++ 标准
+set(CMAKE_CXX_STANDARD 17)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
+# # 设置 OpenSSL 安装路径
+set(OPENSSL_ROOT_DIR "D:/qt/Tools/OpenSSLv3/Win_x64")
+
+# 查找 OpenSSL 库
+find_package(OpenSSL REQUIRED)
+if(OpenSSL_FOUND)
+    message(STATUS "OpenSSL found: ${OpenSSL_VERSION}")
+else()
+    message(FATAL_ERROR "OpenSSL not found. Please install OpenSSL development libraries.")
+endif()
+
+
+find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core Gui Widgets Mqtt Sql Network WebEngineWidgets SerialPort)
+find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Gui Widgets  Mqtt Sql Network WebEngineWidgets SerialPort)  # 添加 Widgets
+
+
+# 定义源文件列表
+set(SOURCES
+    PageWidget.cpp
+    blastoperationfactory.cpp
+    blastopepage.cpp
+    addressfactory.cpp
+    addresspage.cpp
+    blastProject/blastprojectfactory.cpp
+    blastProject/blastprojectpage.cpp
+    blastProject/projectdialog.cpp
+    blastProject/hproject.cpp
+    blastProject/hprojectdao.cpp
+    buttondelegate.cpp
+    databasemanager.cpp
+    detInfo/detinfofactory.cpp
+    detInfo/detinfopage.cpp
+    detInfo/detdialog.cpp
+    equipment/equipmentfactory.cpp
+    equipment/equipmentpage.cpp
+    global.cpp
+    httpclient.cpp
+    jobs.cpp
+    login/loginwindow.cpp
+    main.cpp
+    mainwindow.cpp
+    registryManager/registrymanager.cpp
+    mqtt/mqttclient.cpp
+    blastRecord/blastrecordfactory.cpp
+    blastRecord/blastrecord.cpp
+    blastRecord/hblastrecord.cpp
+    blastRecord/hblastrecorddao.cpp
+    blastRecordDet/hblastrecorddet.cpp
+    blastRecordDet/hblastrecorddetdao.cpp
+    blastRegRecord/hblastregrecord.cpp
+    blastRegRecord/hblastregrecorddao.cpp
+    fireWidget/firingwidget.cpp
+    fireWidget/navprogress.cpp
+)
+
+# 定义头文件列表
+set(HEADERS
+    PageWidget.h
+    blastoperationfactory.h
+    blastopepage.h
+    addressfactory.h
+    addresspage.h
+    blastProject/blastprojectfactory.h
+    blastProject/blastprojectpage.h
+    blastProject/hproject.h
+    blastProject/hprojectdao.h
+    blastProject/projectdialog.h
+    buttondelegate.h
+    databasemanager.h
+    detInfo/detinfofactory.h
+    detInfo/detinfopage.h
+    detInfo/detdialog.h
+    equipment/equipmentfactory.h
+    equipment/equipmentpage.h
+    global.h
+    httpclient.h
+    jobs.h
+    login/loginwindow.h
+    mainwindow.h
+    registryManager/registrymanager.h
+    mqtt/mqttclient.h
+    regex.h
+    blastRecord/blastrecordfactory.h
+    blastRecord/blastrecord.h
+    blastRecord/hblastrecord.h
+    blastRecord/hblastrecorddao.h
+    blastRecordDet/hblastrecorddet.h
+    blastRecordDet/hblastrecorddetdao.h
+    blastRegRecord/hblastregrecord.h
+    blastRegRecord/hblastregrecorddao.h
+    fireWidget/firingwidget.h
+    fireWidget/navprogress.h
+)
+
+# 定义 UI 文件列表
+set(FORMS
+    PageWidget.ui
+    addresspage.ui
+    blastProject/blastprojectpage.ui
+    detInfo/detinfopage.ui
+    detInfo/detdialog.ui
+    equipment/equipmentpage.ui
+    login/loginwindow.ui
+    mainwindow.ui
+    blastProject/projectdialog.ui
+    blastopepage.ui
+    blastRecord/blastrecord.ui
+    fireWidget/firingwidget.ui
+)
+
+# 定义资源文件列表
+set(RESOURCES
+    media.qrc
+)
+
+# 添加可执行文件
+add_executable(${PROJECT_NAME}
+    ${SOURCES}
+    ${HEADERS}
+    ${FORMS}
+    ${RESOURCES}
+    des3encryption.h des3encryption.cpp
+    countdownwidget.h countdownwidget.cpp
+    mqttthread.cpp mqttthread.h
+    serial/serialtool.h serial/serialtool.cpp
+    serial/serialgps.h serial/serialgps.cpp
+    paregnrmc.cpp paregnrmc.h
+    serialgpsthread.h serialgpsthread.cpp
+    worker/timeupdatethread.h worker/timeupdatethread.cpp
+    logo.rc
+    loadingdialog.h loadingdialog.cpp
+
+
+)
+target_link_libraries(pc_system Qt${QT_VERSION_MAJOR}::Core Qt${QT_VERSION_MAJOR}::Gui
+    Qt${QT_VERSION_MAJOR}::Widgets Qt${QT_VERSION_MAJOR}::Sql  Qt${QT_VERSION_MAJOR}::Network
+    Qt${QT_VERSION_MAJOR}::Mqtt Qt${QT_VERSION_MAJOR}::WebEngineWidgets OpenSSL::Crypto OpenSSL::SSL Qt${QT_VERSION_MAJOR}::SerialPort)
+
+include(GNUInstallDirs)
+install(TARGETS pc_system
+    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+)

+ 39 - 0
HttpClient.h

@@ -0,0 +1,39 @@
+#ifndef HTTPCLIENT_H
+#define HTTPCLIENT_H
+
+#include <QObject>
+#include <QNetworkAccessManager>
+#include <QNetworkReply>
+#include <QUrl>
+
+class HttpClient : public QObject {
+    Q_OBJECT
+
+public:
+    explicit HttpClient(QObject *parent = nullptr);
+
+    // 发送 GET 请求的接口
+    void sendHttpGetRequest(const QUrl &url);
+
+    void sendHttpGetAddress(const QUrl &url);
+
+
+signals:
+    // 请求成功后发出的信号
+    void httpGetFinished(const QJsonDocument &responseData,const QUrl &url);
+    // 请求失败后发出的信号
+    void httpErrorOccurred(const QString &errorString);
+
+private slots:
+    void onGetFinished();
+    void onNetworkError(QNetworkReply::NetworkError error);
+    void onSslErrors(const QList<QSslError> &errors);
+    void onGetAddress();
+
+private:
+    QNetworkAccessManager *m_networkManager;
+    QUrl m_currenturl;
+    QUrl m_currenturl2;
+};
+
+#endif // HTTPCLIENT_H

+ 235 - 0
PageWidget.cpp

@@ -0,0 +1,235 @@
+#include "PageWidget.h"
+#include "ui_PageWidget.h"
+
+#include <QtGlobal>
+#include <QHBoxLayout>
+#include <QMouseEvent>
+#include <QKeyEvent>
+#include <QDebug>
+#include <QIntValidator>
+
+PageWidget::PageWidget(int blockSize, QWidget *parent) : QWidget(parent),
+    ui(new Ui::PageWidget) {
+    ui->setupUi(this);
+
+    QString qss = QString(".QLabel[page=\"true\"] { padding: 1px; }")
+            + QString(".QLabel[currentPage=\"true\"] { color: rgb(190, 0, 0);}")
+            + QString(".QLabel[page=\"true\"]:hover { color: white; border-radius: 4px; background-color: qlineargradient(spread:reflect, x1:0, y1:0, x2:0, y2:1, stop:0 rgba(53, 121, 238, 255), stop:1 rgba(0, 202, 237, 255));}");
+    this->setStyleSheet(qss);
+    setBlockSize(blockSize);
+    initialize();
+    maxPage = 0;
+    ui->pageLineEdit->setText(QString::number(1));
+
+
+}
+
+PageWidget::~PageWidget() {
+    delete ui;
+    delete pageLabels;
+}
+
+bool PageWidget::eventFilter(QObject *watched, QEvent *e) {
+    if (e->type() == QEvent::MouseButtonRelease) {
+        int page = -1;
+        if (watched == ui->previousPageLabel) { page = getCurrentPage() - 1; }
+        if (watched == ui->nextPageLabel) { page = getCurrentPage() + 1; }
+        for (int i = 0; i < pageLabels->count(); ++i) {
+            if (watched == pageLabels->at(i)) {
+                page = pageLabels->at(i)->text().toInt();
+                break;
+            }
+        }
+
+        if (-1 != page) {
+            setCurrentPage(page, true);
+            return true;
+        }
+    }
+    if (watched == ui->pageLineEdit && e->type() == QEvent::KeyRelease) {
+        QKeyEvent *ke = static_cast<QKeyEvent *>(e);
+        if (ke->key() == Qt::Key_Enter || ke->key() == Qt::Key_Return)
+        {
+            int page = ui->pageLineEdit->text().toInt();
+            if(page > maxPage)
+            {
+                page = maxPage;
+                ui->pageLineEdit->setText(QString::number(page));
+            }
+            setCurrentPage(page, true);
+            return true;
+        }
+    }
+    return QWidget::eventFilter(watched, e);
+}
+
+int PageWidget::getBlockSize() const {
+    return blockSize;
+}
+
+int PageWidget::getMaxPage() const {
+    return maxPage;
+}
+
+int PageWidget::getCurrentPage() const {
+    return currentPage;
+}
+
+void PageWidget::setMaxPage(int page) {
+    page = qMax(page, 1);
+
+    if (maxPage != page) {
+        maxPage = page;
+        currentPage = 1;
+        updatePageLabels();
+    }
+}
+
+void PageWidget::setCurrentPage(int page, bool signalEmitted) {
+    page = qMax(page, 1);
+    page = qMin(page, maxPage);
+
+    if (page != currentPage) {
+        currentPage = page;
+        updatePageLabels();
+        ui->pageLineEdit->setText(QString::number(page));
+
+        if (signalEmitted) {
+            emit currentPageChanged(page);
+        }
+    }
+}
+
+QComboBox *PageWidget::getComboBox() const
+{
+
+    return ui->comboBox;
+
+}
+
+void PageWidget::setBlockSize(int blockSize) {
+    blockSize = qMax(blockSize, 3);
+    if (blockSize % 2 == 0) {
+        ++blockSize;
+    }
+    this->blockSize = blockSize;
+}
+
+
+// 分成三个部分, 左...中...右
+void PageWidget::initialize() {
+
+    ui->pageLineEdit->installEventFilter(this);
+    ui->pageLineEdit->setValidator(new QIntValidator(1, 10000000, this));
+    ui->nextPageLabel->setProperty("page", "true");
+    ui->previousPageLabel->setProperty("page", "true");
+    ui->nextPageLabel->installEventFilter(this);
+    ui->previousPageLabel->installEventFilter(this);
+    pageLabels = new QList<QLabel *>();
+
+    // 设置布局
+    QHBoxLayout *leftLayout = new QHBoxLayout();
+    QHBoxLayout *centerLayout = new QHBoxLayout();
+    QHBoxLayout *rightLayout = new QHBoxLayout();
+
+    leftLayout->setContentsMargins(0, 0, 0, 0);
+    leftLayout->setSpacing(0);
+    centerLayout->setContentsMargins(0, 0, 0, 0);
+    centerLayout->setSpacing(0);
+    rightLayout->setContentsMargins(0, 0, 0, 0);
+    rightLayout->setSpacing(0);
+
+    for (int i = 0; i < blockSize * 3-2; ++i) {
+        QLabel *label = new QLabel(QString::number(i + 1));
+        label->setProperty("page", "true");
+        label->installEventFilter(this);
+        pageLabels->append(label);
+        if (i < 1) {
+            leftLayout->addWidget(label);
+        } else if (i < blockSize * 2) {
+            centerLayout->addWidget(label);
+        } else {
+            rightLayout->addWidget(label);
+        }
+    }
+
+    ui->leftPagesWidget->setLayout(leftLayout);
+    ui->centerPagesWidget->setLayout(centerLayout);
+    ui->rightPagesWidget->setLayout(rightLayout);
+    initCombo();
+}
+
+void PageWidget::initCombo(){
+    ui->comboBox->addItem("10条/页", QVariant(10));  // 显示文本为 "Apple",值为 1
+    ui->comboBox->addItem("50条/页", QVariant(50));
+    ui->comboBox->addItem("100条/页", QVariant(100));
+    ui->comboBox->addItem("200条/页", QVariant(200));
+}
+
+void PageWidget::updatePageLabels() {
+    ui->leftSeparateLabel->hide();
+    ui->rightSeparateLabel->hide();
+
+    if (maxPage <= blockSize * 3) {
+        for (int i = 0; i < pageLabels->count(); i += 1) {
+            QLabel *label = pageLabels->at(i);
+            if (i < maxPage) {
+                label->setText(QString::number(i + 1));
+                label->show();
+            } else {
+                label->hide();
+            }
+
+            if (currentPage - 1 == i) {
+                label->setProperty("currentPage", "true");
+            } else {
+                label->setProperty("currentPage", "false");
+            }
+
+            label->setStyleSheet("/**/");
+        }
+        return;
+    }
+
+    int c = currentPage;
+    int n = blockSize;
+    int m = maxPage;
+    int centerStartPage = 0;
+
+    if (c >= 1 && c < n + n / 2 + 1) {
+        // 显示前 n * 2 个, 后 n 个: 只显示右边的分隔符
+        centerStartPage = 1;
+        ui->rightSeparateLabel->show();
+    } else if (c > m - n - n / 2 && c <= m) {
+        // 显示前 n 个, 后 n * 2 个: 只显示左边的分隔符
+        centerStartPage = m - n - n ;
+        ui->leftSeparateLabel->show();
+    } else {
+        // 显示[1, n], [c - n/2, c + n/2], [m - n + 1, m]: 两个分隔符都显示
+        centerStartPage = c - n;
+        ui->rightSeparateLabel->show();
+        ui->leftSeparateLabel->show();
+    }
+
+    pageLabels->at(0)->setText(QString::number(1));// 前面 n 个
+    for (int i = 1; i < 6; ++i) {
+        pageLabels->at(i)->setText(QString::number(centerStartPage + i)); // 中间 n 个
+    }
+    pageLabels->at(6)->setText(QString::number(m));// 后面 n 个
+
+    for (int i = 0; i < pageLabels->count(); ++i) {
+        QLabel *label = pageLabels->at(i);
+        int page = label->text().toInt();
+        if (page == currentPage) {
+            label->setProperty("currentPage", "true");
+        } else {
+            label->setProperty("currentPage", "false");
+        }
+
+        label->setStyleSheet("/**/");
+        label->show();
+    }
+}
+
+
+

+ 66 - 0
PageWidget.h

@@ -0,0 +1,66 @@
+#ifndef PAGEWIDGET_H
+#define PAGEWIDGET_H
+
+#include <QWidget>
+#include <QList>
+#include <QComboBox>
+#include "databasemanager.h"
+
+
+class QLabel;
+class QEvent;
+
+
+struct HeaderInfo {
+    QString label;
+    QString prop;
+};
+
+namespace Ui {
+    class PageWidget;
+}
+
+class PageWidget : public QWidget {
+    Q_OBJECT
+
+public:
+    explicit PageWidget(int blockSize = 3, QWidget *parent = 0);
+    ~PageWidget();
+
+    /*const 关键字在成员函数声明和定义中的使用,确保了该函数不会修改对象的状态,提高了代码的安全性和可读性。这对于那些只需要读取对象状态而不需要修改对象状态的函数非常有用*/
+    int getBlockSize() const;
+    int getMaxPage() const;
+    int getCurrentPage() const;
+
+    // 其他组件只需要调用这两个函数即可
+    void setMaxPage(int maxPage);   // 当总页数改变时调用
+    void setCurrentPage(int currentPage, bool signalEmitted = false); // 修改当前页时调用
+    void showLeft();
+    QComboBox* getComboBox() const;
+
+protected:
+    virtual bool eventFilter(QObject *watched, QEvent *e);
+
+signals:
+    void currentPageChanged(int page);
+
+
+
+
+
+private:
+    Ui::PageWidget *ui;
+    int blockSize;
+    int maxPage;        //总页数
+    int currentPage;    //当前页面
+    QList<QLabel *> *pageLabels;
+    int PageRecordCount; //每页显示的记录数量
+
+    void setBlockSize(int blockSize);
+    void updatePageLabels();
+    void initialize();
+    void setRecordCount();
+    void initCombo();
+};
+
+#endif // PAGEWIDGET_H

+ 157 - 0
PageWidget.ui

@@ -0,0 +1,157 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>PageWidget</class>
+ <widget class="QWidget" name="PageWidget">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>940</width>
+    <height>50</height>
+   </rect>
+  </property>
+  <property name="minimumSize">
+   <size>
+    <width>0</width>
+    <height>0</height>
+   </size>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <property name="styleSheet">
+   <string notr="true"/>
+  </property>
+  <layout class="QHBoxLayout" name="horizontalLayout">
+   <property name="spacing">
+    <number>1</number>
+   </property>
+   <property name="leftMargin">
+    <number>0</number>
+   </property>
+   <property name="topMargin">
+    <number>0</number>
+   </property>
+   <property name="rightMargin">
+    <number>0</number>
+   </property>
+   <property name="bottomMargin">
+    <number>0</number>
+   </property>
+   <item>
+    <spacer name="horizontalSpacer_right">
+     <property name="orientation">
+      <enum>Qt::Orientation::Horizontal</enum>
+     </property>
+     <property name="sizeHint" stdset="0">
+      <size>
+       <width>45</width>
+       <height>20</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
+   <item>
+    <widget class="QLabel" name="previousPageLabel">
+     <property name="toolTip">
+      <string>上一页</string>
+     </property>
+     <property name="text">
+      <string>&lt;</string>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QWidget" name="leftPagesWidget" native="true"/>
+   </item>
+   <item>
+    <widget class="QLabel" name="leftSeparateLabel">
+     <property name="toolTip">
+      <string>下一页</string>
+     </property>
+     <property name="text">
+      <string>..</string>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QWidget" name="centerPagesWidget" native="true"/>
+   </item>
+   <item>
+    <widget class="QLabel" name="rightSeparateLabel">
+     <property name="toolTip">
+      <string>下一页</string>
+     </property>
+     <property name="text">
+      <string>..</string>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QWidget" name="rightPagesWidget" native="true"/>
+   </item>
+   <item>
+    <widget class="QLabel" name="nextPageLabel">
+     <property name="toolTip">
+      <string>下一页</string>
+     </property>
+     <property name="text">
+      <string>&gt;</string>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QLabel" name="label">
+     <property name="text">
+      <string>第</string>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QLineEdit" name="pageLineEdit">
+     <property name="minimumSize">
+      <size>
+       <width>50</width>
+       <height>0</height>
+      </size>
+     </property>
+     <property name="maximumSize">
+      <size>
+       <width>50</width>
+       <height>16777215</height>
+      </size>
+     </property>
+     <property name="focusPolicy">
+      <enum>Qt::FocusPolicy::ClickFocus</enum>
+     </property>
+     <property name="alignment">
+      <set>Qt::AlignmentFlag::AlignCenter</set>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QLabel" name="label_2">
+     <property name="text">
+      <string>页</string>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QLabel" name="label_display_set2">
+     <property name="text">
+      <string> 条记录</string>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QComboBox" name="comboBox">
+     <property name="editable">
+      <bool>false</bool>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>

+ 110 - 0
QframeTest01.pro

@@ -0,0 +1,110 @@
+QT       += core gui sql network
+
+greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
+
+CONFIG += c++17
+
+# You can make your code fail to compile if it uses deprecated APIs.
+# In order to do so, uncomment the following line.
+#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
+
+SOURCES += \
+    PageWidget.cpp \
+    addressfactory.cpp \
+    addresspage.cpp \
+    blastplanpage.cpp \
+    blastplanpfactory.cpp \
+    blastprojectfactory.cpp \
+    blastprojectpage.cpp \
+    book.cpp \
+    buttondelegate.cpp \
+    databasemanager.cpp \
+    detInfo/detinfofactory.cpp \
+    detInfo/detinfopage.cpp \
+    detdialog.cpp \
+    dialog.cpp \
+    equipment/equipmentfactory.cpp \
+    equipment/equipmentpage.cpp \
+    global.cpp \
+    hplan.cpp \
+    hplandao.cpp \
+    hproject.cpp \
+    hprojectdao.cpp \
+    httpclient.cpp \
+    jobs.cpp \
+    loginwindow.cpp \
+    main.cpp \
+    mainwindow.cpp \
+    mqtt/mqttclient.cpp \
+    newpagefactory.cpp \
+    page.cpp \
+    pagetest.cpp \
+    pagetestfactory.cpp \
+    plandialog.cpp \
+    projectdialog.cpp \
+    sysapi.cpp \
+    sysapidao.cpp \
+    testdialog.cpp
+
+HEADERS += \
+    PageWidget.h \
+    addressfactory.h \
+    addresspage.h \
+    blastplanpage.h \
+    blastplanpfactory.h \
+    blastprojectfactory.h \
+    blastprojectpage.h \
+    book.h \
+    buttondelegate.h \
+    databasemanager.h \
+    detInfo/detinfofactory.h \
+    detInfo/detinfopage.h \
+    detdialog.h \
+    dialog.h \
+    equipment/equipmentfactory.h \
+    equipment/equipmentpage.h \
+    global.h \
+    hplan.h \
+    hplandao.h \
+    hproject.h \
+    hprojectdao.h \
+    httpclient.h \
+    jobs.h \
+    loginwindow.h \
+    mainwindow.h \
+    PageFactory.h\
+    mqtt/mqttclient.h \
+    newpagefactory.h \
+    page.h \
+    pagetest.h \
+    pagetestfactory.h \
+    plandialog.h \
+    projectdialog.h \
+    regex.h \
+    sysapi.h \
+    sysapidao.h \
+    testdialog.h
+
+FORMS += \
+    PageWidget.ui \
+    addresspage.ui \
+    blastplanpage.ui \
+    blastprojectpage.ui \
+    detInfo/detinfopage.ui \
+    detdialog.ui \
+    dialog.ui \
+    equipment/equipmentpage.ui \
+    loginwindow.ui \
+    mainwindow.ui \
+    page.ui \
+    pagetest.ui \
+    plandialog.ui \
+    projectdialog.ui \
+    testdialog.ui
+# Default rules for deployment.
+qnx: target.path = /tmp/$${TARGET}/bin
+else: unix:!android: target.path = /opt/$${TARGET}/bin
+!isEmpty(target.path): INSTALLS += target
+QMAKE_PROJECT_DEPTH = 0
+RESOURCES += \
+    media.qrc

+ 11 - 0
addressfactory.cpp

@@ -0,0 +1,11 @@
+#include "addressfactory.h"
+
+AddressFactory::AddressFactory()
+{
+
+}
+
+QWidget *AddressFactory::createPage(QWidget *parent) const
+{
+    return new AddressPage(parent);
+}

+ 14 - 0
addressfactory.h

@@ -0,0 +1,14 @@
+#ifndef ADDRESSFACTORY_H
+#define ADDRESSFACTORY_H
+#include "PageFactory.h"
+#include "addresspage.h"
+
+
+class AddressFactory: public PageFactory
+{
+public:
+    AddressFactory();
+    QWidget* createPage(QWidget* parent) const override;
+};
+
+#endif // ADDRESSFACTORY_H

+ 83 - 0
addresspage.cpp

@@ -0,0 +1,83 @@
+#include "addresspage.h"
+#include "ui_addresspage.h"
+#include <QDebug>
+#include <QJsonObject>
+#include <QJsonArray>
+#include <QJsonDocument>
+#include "httpclient.h"
+#include "global.h"
+#include <QUrl>
+AddressPage::AddressPage(QWidget *parent) :
+    QWidget(parent),
+    ui(new Ui::AddressPage)
+{
+    ui->setupUi(this);
+    m_httpClient = new HttpClient(this);
+    QUrl localUrl("h-address/pc");
+    QUrl fullUrl = g_url.resolved(localUrl);
+    m_httpClient->sendHttpGetRequest(fullUrl);
+
+    connect(m_httpClient, &HttpClient::httpGetFinished, [this](const QJsonDocument &data) {
+        this->dataTable(data);
+
+    });
+}
+
+void AddressPage::dataTable(const QJsonDocument &jsonDoc)
+{
+    parseJsonString(jsonDoc);
+    model = new QStandardItemModel(this);
+    model->setHorizontalHeaderLabels({"名称", "设备编号", "LORA地址","描述","创建时间"});
+
+    if (jsonDoc["data"].isArray()) {
+        QJsonArray jsonArray = jsonDoc["data"].toArray();
+
+        for (const QJsonValue& jsonValue : jsonArray) {
+            QJsonObject jsonObj = jsonValue.toObject();
+            QList<QStandardItem*> items = jsonToItem(jsonObj);
+            model->appendRow(items);
+        }
+    }
+
+    ui->treeView->setModel(model);
+    ui->treeView->header()->setSectionResizeMode(QHeaderView::Stretch);
+    ui->treeView->header()->setDefaultAlignment(Qt::AlignCenter);
+    ui->treeView->setAlternatingRowColors(true);
+
+}
+
+void AddressPage::parseJsonString(const QJsonDocument &jsonDoc)
+{
+    QJsonObject jsonObj = jsonDoc.object();
+    QJsonObject dataObj = jsonObj["data"].toObject();
+    dataArray = dataObj["list"].toArray();
+}
+
+QList<QStandardItem *> AddressPage::jsonToItem(const QJsonObject &jsonObj)
+{
+
+      QStandardItem* nameItem = new QStandardItem(jsonObj["name"].toString());
+      nameItem->setTextAlignment(Qt::AlignCenter);
+      QStandardItem* equipmentSn = new QStandardItem(jsonObj["equipmentSn"].toString());
+      QStandardItem* loraSn = new QStandardItem(jsonObj["loraSn"].toString());
+      QStandardItem* describe = new QStandardItem(jsonObj["describe"].toString());
+      QString isoDateTimeStr = jsonObj["createdAt"].toString();
+      QDateTime dateTime = QDateTime::fromString(isoDateTimeStr, Qt::ISODateWithMs);
+      QString formattedDateTime = dateTime.toString("yyyy-MM-dd hh:mm:ss");
+      QStandardItem* createdAt = new QStandardItem(formattedDateTime);
+      if (jsonObj.contains("children") && jsonObj["children"].isArray()) {
+          QJsonArray childrenArray = jsonObj["children"].toArray();
+          for (const QJsonValue& child : childrenArray) {
+              QList<QStandardItem*> childItems = jsonToItem(child.toObject());
+              nameItem->appendRow(childItems);
+          }
+      }
+
+      return QList<QStandardItem*>() << nameItem << equipmentSn << loraSn<<describe<<createdAt;
+}
+
+
+AddressPage::~AddressPage()
+{
+    delete ui;
+}

+ 37 - 0
addresspage.h

@@ -0,0 +1,37 @@
+#ifndef ADDRESSPAGE_H
+#define ADDRESSPAGE_H
+
+#include <QWidget>
+#include <QStandardItemModel>
+#include <QJsonArray>
+#include "buttondelegate.h"
+#include "HttpClient.h"
+#include "PageWidget.h"
+
+class QJsonArray;
+class QTableView;
+
+
+namespace Ui {
+class AddressPage;
+}
+
+class AddressPage : public QWidget
+{
+    Q_OBJECT
+
+public:
+    explicit AddressPage(QWidget *parent = nullptr);
+    ~AddressPage();
+
+private:
+    void parseJsonString(const QJsonDocument& jsonDoc);
+    void dataTable( const QJsonDocument& jsonDoc);
+    QList<QStandardItem*> jsonToItem(const QJsonObject& jsonObj);
+    HttpClient *m_httpClient;
+    Ui::AddressPage *ui;
+    QStandardItemModel *model;
+    QJsonArray dataArray;
+};
+
+#endif // ADDRESSPAGE_H

+ 99 - 0
addresspage.ui

@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>AddressPage</class>
+ <widget class="QWidget" name="AddressPage">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>965</width>
+    <height>602</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <property name="styleSheet">
+   <string notr="true">/* 设置 QTreeView 的行高 */
+QTreeView::item {
+    height: 40px;  /* 行高为 40 像素 */
+    text-align: center; 
+}
+</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout_2">
+   <item>
+    <widget class="QFrame" name="searchBox">
+     <property name="frameShape">
+      <enum>QFrame::Shape::StyledPanel</enum>
+     </property>
+     <property name="frameShadow">
+      <enum>QFrame::Shadow::Raised</enum>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QFrame" name="btnBox">
+     <property name="minimumSize">
+      <size>
+       <width>0</width>
+       <height>50</height>
+      </size>
+     </property>
+     <property name="maximumSize">
+      <size>
+       <width>16777215</width>
+       <height>50</height>
+      </size>
+     </property>
+     <property name="frameShape">
+      <enum>QFrame::Shape::StyledPanel</enum>
+     </property>
+     <property name="frameShadow">
+      <enum>QFrame::Shadow::Raised</enum>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QFrame" name="dataWidget">
+     <property name="frameShape">
+      <enum>QFrame::Shape::StyledPanel</enum>
+     </property>
+     <property name="frameShadow">
+      <enum>QFrame::Shadow::Raised</enum>
+     </property>
+     <layout class="QVBoxLayout" name="verticalLayout">
+      <item>
+       <widget class="QTreeView" name="treeView"/>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <widget class="QFrame" name="pagination">
+     <property name="minimumSize">
+      <size>
+       <width>0</width>
+       <height>30</height>
+      </size>
+     </property>
+     <property name="maximumSize">
+      <size>
+       <width>16777215</width>
+       <height>30</height>
+      </size>
+     </property>
+     <property name="frameShape">
+      <enum>QFrame::Shape::StyledPanel</enum>
+     </property>
+     <property name="frameShadow">
+      <enum>QFrame::Shadow::Raised</enum>
+     </property>
+     <layout class="QVBoxLayout" name="verticalLayout_3"/>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>

BIN
background/baseWidget.png


BIN
background/baseWidget2.png


BIN
background/blastOpera.png


BIN
blast.ico


+ 37 - 0
blastProject/HProjectDao.h

@@ -0,0 +1,37 @@
+#ifndef HPROJECTDAO_H
+#define HPROJECTDAO_H
+
+#include <QObject>
+#include <QSqlDatabase>
+#include <QSqlQuery>
+#include <QSqlError>
+#include <QList>
+#include <QSqlRecord>
+#include "HProject.h"
+
+struct PaginatedHProjectResult {
+    QList<QSharedPointer<HProject>> projects;
+    int totalCount;
+};
+
+class HProjectDao
+{
+
+public:
+    HProjectDao(QSqlDatabase db);
+    bool addHProject(const HProject &project);
+    bool updateHProject(const HProject &project);
+    bool deleteHProject(const HProject &project);
+    bool updateBlastStatusByUuid(const QString &uuid, const QString &blastStatus);
+    HProject getHProjectById(qint64 id);
+    PaginatedHProjectResult getAllHProjects(int page, int pageSize);
+    PaginatedHProjectResult getAllHProjectsByOpera(int page, int pageSize);
+
+private:
+    QSqlDatabase database;
+    // 将QSqlRecord转换为HProject对象
+    QSharedPointer<HProject> recordToProject(const QSqlRecord &record);
+
+};
+
+#endif // HPROJECTDAO_H

+ 11 - 0
blastProject/blastprojectfactory.cpp

@@ -0,0 +1,11 @@
+#include "blastprojectfactory.h"
+
+BlastProjectFactory::BlastProjectFactory()
+{
+
+}
+
+QWidget *BlastProjectFactory::createPage(QWidget *parent) const
+{
+    return new BlastProjectPage(parent);
+}

+ 14 - 0
blastProject/blastprojectfactory.h

@@ -0,0 +1,14 @@
+#ifndef BLASTPROJECTFACTORY_H
+#define BLASTPROJECTFACTORY_H
+#include "../PageFactory.h"
+#include "blastprojectpage.h"
+
+
+class BlastProjectFactory:public PageFactory
+{
+public:
+    BlastProjectFactory();
+    QWidget* createPage(QWidget* parent) const override;
+};
+
+#endif // BLASTPROJECTFACTORY_H

+ 338 - 0
blastProject/blastprojectpage.cpp

@@ -0,0 +1,338 @@
+#include "blastprojectpage.h"
+#include "ui_blastprojectpage.h"
+#include <iostream>
+#include "../global.h"
+#include <QUrl>
+#include "../databasemanager.h"
+
+BlastProjectPage::BlastProjectPage(QWidget *parent) :
+    QWidget(parent),
+    ui(new Ui::BlastProjectPage),
+    dao(DatabaseManager::getInstance().getDatabase())
+{
+    ui->setupUi(this);
+    pageWidget= new PageWidget;
+    connect(pageWidget, &PageWidget::currentPageChanged, this, &BlastProjectPage::PageChanged);
+    connect(pageWidget->getComboBox(), QOverload<int>::of(&QComboBox::currentIndexChanged), this, &BlastProjectPage::onComboBoxIndexChanged);
+    ui->verticalLayout_4->addWidget(pageWidget);;
+    pageSize = 10;
+    currentPage = 1;
+
+    RefreshData();
+    m_httpClient = new HttpClient(this);
+    QUrl localUrl("person/type");
+    QUrl fullUrl = g_url.resolved(localUrl);
+    m_httpClient->sendHttpGetRequest(fullUrl);
+
+    QUrl addressLocalUrl("h-address/pc");
+    QUrl addressFullUrl = g_url.resolved(addressLocalUrl);
+    m_httpClient->sendHttpGetAddress(addressFullUrl);
+    connect(m_httpClient, &HttpClient::httpGetFinished, [this](const QJsonDocument &data,const QUrl url) {
+        QString relativePath = url.toString().remove(0, g_url.toString().length());
+        if (relativePath == "person/type") {
+            this->personOptionsByType(data);
+        } else if (relativePath == "h-address/pc") {
+            this->addressOptions(data);
+        }
+
+    });
+
+
+    dialog = new ProjectDialog(this);
+    connect(dialog, &ProjectDialog::validateDetNum, this, &BlastProjectPage::insertPlan);
+    connect(dialog, &ProjectDialog::validateDetNumUpdate, this, &BlastProjectPage::updateProject);
+
+    client = MqttClient::getInstance();
+
+
+}
+
+
+void BlastProjectPage::RefreshData()
+{
+
+    loadDataFromSource(currentPage,pageSize);
+
+}
+
+void BlastProjectPage::loadDataFromSource(int currentPage, int pageSize)
+{
+    PaginatedHProjectResult result =dao.getAllHProjects(currentPage,pageSize);
+
+    QList<QSharedPointer<HProject>> projectList = result.projects;
+
+    totalCount = result.totalCount;
+    pageWidget->setMaxPage(ceil(static_cast<double>(totalCount)/pageSize));
+    QStandardItemModel *model;
+    model = new QStandardItemModel(this);
+
+    // 定义表头信息
+    QList<HeaderInfo> headers = {
+        {"工程名称", "name"},
+        {"操作员", "operatorName"},
+        {"爆破员", "blasterName"},
+        {"井下地址", "addressUuid"},
+        {"雷管数量", "detSum"},
+        {"起爆器数量", "blastCount"},
+        {"起爆状态", "blastStatus"},
+        {"操作",""},
+    };
+
+    int headerCount = headers.size();
+    QStringList headerLabels;
+    QMap<int, QString> propMap;
+    for (int i = 0; i < headers.size(); ++i) {
+        headerLabels << headers[i].label;
+        propMap[i] = headers[i].prop;
+    }
+    model->setHorizontalHeaderLabels(headerLabels);
+
+    for (int row = 0; row < projectList.size(); ++row) {
+        HProject& HProject = *projectList.at(row).data();
+        for (int col = 0; col < headers.size(); ++col) {
+            QString prop = propMap[col];
+            QStandardItem* item = nullptr;
+
+            if (!prop.isEmpty()) {
+                QMetaProperty metaProp = HProject.metaObject()->property(HProject.metaObject()->indexOfProperty(prop.toUtf8()));
+                QVariant value = metaProp.read(&HProject);
+                if (prop == "blastStatus") {
+                    QString statusText;
+                    if (value.toString() == "1") {
+                        statusText = "未注册";
+                        item = new QStandardItem(statusText);
+                        item->setForeground(QColor("#e7c66b"));
+                    } else if (value.toString() == "2") {
+                        statusText = "待起爆";
+                        item = new QStandardItem(statusText);
+                        item->setForeground(QColor("#f3a361"));
+                    } else if (value.toString() == "3") {
+                        statusText = "起爆完成";
+                        item = new QStandardItem(statusText);
+                        item->setForeground(QColor("#90d543"));
+                    } else {
+                        item = new QStandardItem(value.toString());
+                    }
+                } else {
+                    item = new QStandardItem(value.toString());
+                }
+
+            } else {
+                item = new QStandardItem("操作");
+            }
+            if (item) {
+                item->setTextAlignment(Qt::AlignCenter);
+                model->setItem(row, col, item);
+            }
+        }
+    }
+    ui->tableView->setModel(model);
+    ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
+    ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
+    ui->tableView->setAlternatingRowColors(true);
+    // 创建并设置自定义委托
+    ButtonDelegate *delegate = new ButtonDelegate(headerCount-1,this);
+    QObject::connect(delegate, &ButtonDelegate::buttonClicked, [=](int row, int column) {
+        // 获取 HPlan 引用
+        HProject& HPlanDeleteOrUpdate = *projectList.at(row).data();
+        updateId = HPlanDeleteOrUpdate.getId();
+        if(column == 1){
+            deleteButtonClicked(HPlanDeleteOrUpdate);
+        }
+        if(column == 2){
+            updateButtonClicked(HPlanDeleteOrUpdate);
+        }
+    });
+    ui->tableView->setItemDelegateForColumn(headerCount-1, delegate);
+}
+
+
+void BlastProjectPage::PageChanged(int page)
+{
+    currentPage = page;
+    loadDataFromSource(currentPage,pageSize);
+}
+
+void BlastProjectPage::onComboBoxIndexChanged(int index) {
+    QVariant variant = pageWidget->getComboBox()->itemData(index);
+    int value = variant.toInt();
+    pageSize = value;
+    currentPage = 1;
+    loadDataFromSource(currentPage,pageSize);
+
+}
+
+
+void BlastProjectPage::personOptionsByType(const QJsonDocument &jsonDoc)
+{
+    parseJsonString(jsonDoc);
+    QJsonArray bapoYuanArray;
+    QJsonArray anQuanYuanArray;
+    for (const QJsonValue &value : dataArray) {
+        if (value.isObject()) {
+            QJsonObject obj = value.toObject();
+            if (obj.contains("personTypeName")) {
+                QString personTypeName = obj["personTypeName"].toString();
+                if (personTypeName == "爆破员") {
+                    bapoYuanArray.append(obj);
+                } else if (personTypeName == "安全员") {
+                    anQuanYuanArray.append(obj);
+                }
+            }
+        }
+    }
+
+    dialog->SetComboBoxBlast(bapoYuanArray);
+    dialog->SetComboBoxOperator(anQuanYuanArray);
+}
+
+
+void BlastProjectPage::addressOptions(const QJsonDocument &jsonDoc)
+{
+    parseJsonStringAddress(jsonDoc);
+    QJsonArray parentOptions;
+    for (const QJsonValue &item : dataArrayAddress) {
+        parentOptions.append(item.toObject()["name"].toString());
+    }
+    dialog->SetComboBoxAddress(parentOptions);
+    dialog->setChildOptions(dataArrayAddress);
+
+}
+
+// 递归函数,用于提取所有的 name 信息
+void BlastProjectPage::extractNames(const QJsonArray& array, QStringList& names) {
+    for (const auto& item : array) {
+        if (item.isObject()) {
+            QJsonObject obj = item.toObject();
+            if (obj.contains("name")) {
+                names.append(obj["name"].toString());
+            }
+            if (obj.contains("children") && obj["children"].isArray()) {
+                extractNames(obj["children"].toArray(), names);
+            }
+        }
+    }
+}
+
+
+void BlastProjectPage::parseJsonString(const QJsonDocument &jsonDoc)
+{
+    QJsonObject jsonObj = jsonDoc.object();
+    QJsonObject dataObj = jsonObj["data"].toObject();
+    dataArray = dataObj["list"].toArray();
+}
+
+void BlastProjectPage::parseJsonStringAddress(const QJsonDocument &jsonDoc)
+{
+    QJsonObject jsonObj = jsonDoc.object();
+    dataArrayAddress = jsonObj["data"].toArray();
+
+}
+void BlastProjectPage::on_pushButton_clicked()
+{
+
+    dialog->setModal(false);
+    dialog->setOperationStatus(0);
+    int ref = dialog->exec();
+    if (ref==QDialog::Accepted){
+
+    };
+
+}
+
+void BlastProjectPage::insertPlan(const QMap<QString, QString> &data)
+{
+    HProject project;
+    project.setName(data.value("name"));
+    project.setDetSum(data.value("detNum"));
+    project.setBlasterName(data.value("blasterName"));
+    project.setOperatorName(data.value("operatorName"));
+    project.setAddressUuid(data.value("addressUuid"));
+    project.setBlasterIdentity(data.value("blasterIdentity"));
+    project.setOperatorIdentity(data.value("operatorIdentity"));
+    project.setLoraAddress(data.value("loraAddress"));
+    project.setLoraSn(data.value("loraSn"));
+    project.setBlastCount(data.value("blastCount"));
+    project.setBlastStatus("1");
+    // 生成 32 位的 UUID
+    QString uuidString = QUuid::createUuid().toString(QUuid::WithoutBraces).remove(QRegularExpression("-"));
+    project.setUuid(uuidString);
+    project.setCreatedAt(QDateTime::currentDateTime());
+    if(dao.addHProject(project)){
+        RefreshData();
+        QByteArray jsonData  = project.ProjectToJson(project);
+        client->sendMessage("hxgc/companycode", jsonData);
+    }
+
+}
+
+void BlastProjectPage::updateButtonClicked(const HProject &project){
+    dialog->setModal(false);
+    dialog->setOperationStatus(1);
+    dialog->setFormData(project);
+    int ref = dialog->exec();
+    if (ref==QDialog::Accepted){
+
+    };
+
+}
+
+void BlastProjectPage::updateProject(const QMap<QString, QString> &data){
+    HProject project;
+    project.setId(updateId);
+    project.setName(data.value("name"));
+    project.setDetSum(data.value("detNum"));
+    project.setBlasterName(data.value("blasterName"));
+    project.setOperatorName(data.value("operatorName"));
+    project.setAddressUuid(data.value("addressUuid"));
+    project.setBlasterIdentity(data.value("blasterIdentity"));
+    project.setOperatorIdentity(data.value("operatorIdentity"));
+    project.setUpdatedAt(QDateTime::currentDateTime());
+    if(dao.updateHProject(project)){
+        RefreshData();
+    }
+
+
+
+}
+void BlastProjectPage::deleteButtonClicked(const HProject &project){
+
+    if(dao.deleteHProject(project)){
+        RefreshData();
+    }
+
+}
+
+
+void BlastProjectPage::messageAndTopicReceived(const QByteArray &message, const QMqttTopicName &topic){
+    QJsonDocument jsonDoc = QJsonDocument::fromJson(message);
+    if (!jsonDoc.isNull() && jsonDoc.isObject()) {
+        QJsonObject jsonObj = jsonDoc.object();
+        if (jsonObj.contains("uuid")&& jsonObj.contains("status")) {
+            QJsonValue uuidValue = jsonObj["uuid"];
+            QJsonValue statusValue = jsonObj["status"];
+            if (statusValue.isString() && statusValue.toString() == "1") {
+                if (uuidValue.isNull()) {
+                    qDebug() << "uuid 的值为 null";
+                } else {
+                    QString uuid = uuidValue.toString();
+                    updateProjectUUId(uuid);
+                }
+            }
+        }
+    }
+
+}
+
+
+void BlastProjectPage::updateProjectUUId(QString uuid){
+    dao.updateBlastStatusByUuid(uuid,"2");
+
+}
+
+BlastProjectPage::~BlastProjectPage()
+{
+    delete ui;
+}
+
+

+ 66 - 0
blastProject/blastprojectpage.h

@@ -0,0 +1,66 @@
+#ifndef BLASTPROJECTPAGE_H
+#define BLASTPROJECTPAGE_H
+
+#include <QWidget>
+#include <QStandardItemModel>
+#include <QPushButton>
+#include <QJsonArray>
+#include "hprojectdao.h"
+#include "../PageWidget.h"
+#include "../buttondelegate.h"
+#include "projectdialog.h"
+#include "../HttpClient.h"
+#include "../mqtt/mqttclient.h"
+
+namespace Ui {
+class BlastProjectPage;
+}
+
+class BlastProjectPage : public QWidget
+{
+    Q_OBJECT
+
+public:
+    explicit BlastProjectPage(QWidget *parent = nullptr);
+    ~BlastProjectPage();
+
+
+private slots:
+    void PageChanged(int page);
+    void onComboBoxIndexChanged(int index);
+    void on_pushButton_clicked();
+    void messageAndTopicReceived(const QByteArray &message, const QMqttTopicName &topic);
+    void updateProjectUUId(QString uuid);
+private:
+    void RefreshData();
+    void loadDataFromSource(int currentPage,int pageSize);
+    void personOptionsByType(const QJsonDocument &jsonDoc);
+    void parseJsonStringAddress(const QJsonDocument &jsonDoc);
+    void addressOptions(const QJsonDocument &jsonDoc);
+    void parseJsonString(const QJsonDocument &jsonDoc);
+    void fillComboBox(QComboBox *comboBox, const QJsonArray &jsonArray);
+    void insertPlan(const QMap<QString, QString> &data);
+    void updateButtonClicked(const HProject &project);
+    void updateProject(const QMap<QString, QString> &data);
+    void deleteButtonClicked(const HProject &project);
+    void extractNames(const QJsonArray &array, QStringList &names);
+
+private:
+    Ui::BlastProjectPage *ui;
+    PageWidget *pageWidget;
+    ProjectDialog *dialog;
+    HttpClient *m_httpClient;
+    MqttClient* pcBC;
+    HProjectDao dao;
+    QJsonArray dataArray;
+    QJsonArray dataArrayAddress;
+    MqttClient *client;
+    int pageSize;  //每页显示的记录数量
+    int currentPage;      //当前页面
+    int totalCount;
+    int updateId;
+
+
+};
+
+#endif // BLASTPROJECTPAGE_H

+ 175 - 0
blastProject/blastprojectpage.ui

@@ -0,0 +1,175 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>BlastProjectPage</class>
+ <widget class="QWidget" name="BlastProjectPage">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>908</width>
+    <height>507</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <property name="styleSheet">
+   <string notr="true">#pushButton  {
+    /*background-color:#3583FF;*/
+    background-color: qlineargradient(spread:pad, x1:-0.2, y1:0.5, x2:1, y2:0.5, stop:0 rgba(62, 91, 255, 255), stop:0.6 rgba(20, 125, 232, 245));
+    color: white;
+    border: none; /* 去除描边 */
+    /*border: 2px solid #4CAF50;*/
+    border-radius: 20px;
+
+}
+
+QPushButton {
+    background-color:#3583FF;
+    color: white;
+    border: 2px solid #4CAF50;
+    border-radius: 5px;
+
+}</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <widget class="QFrame" name="searchBox">
+     <property name="maximumSize">
+      <size>
+       <width>16777215</width>
+       <height>50</height>
+      </size>
+     </property>
+     <property name="frameShape">
+      <enum>QFrame::Shape::StyledPanel</enum>
+     </property>
+     <property name="frameShadow">
+      <enum>QFrame::Shadow::Raised</enum>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QFrame" name="btnBox">
+     <property name="minimumSize">
+      <size>
+       <width>0</width>
+       <height>50</height>
+      </size>
+     </property>
+     <property name="maximumSize">
+      <size>
+       <width>16777215</width>
+       <height>50</height>
+      </size>
+     </property>
+     <property name="frameShape">
+      <enum>QFrame::Shape::StyledPanel</enum>
+     </property>
+     <property name="frameShadow">
+      <enum>QFrame::Shadow::Raised</enum>
+     </property>
+     <layout class="QHBoxLayout" name="horizontalLayout">
+      <property name="spacing">
+       <number>0</number>
+      </property>
+      <property name="leftMargin">
+       <number>0</number>
+      </property>
+      <property name="topMargin">
+       <number>0</number>
+      </property>
+      <property name="rightMargin">
+       <number>0</number>
+      </property>
+      <property name="bottomMargin">
+       <number>0</number>
+      </property>
+      <item>
+       <spacer name="horizontalSpacer">
+        <property name="orientation">
+         <enum>Qt::Orientation::Horizontal</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>920</width>
+          <height>20</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+      <item>
+       <widget class="QPushButton" name="pushButton">
+        <property name="minimumSize">
+         <size>
+          <width>130</width>
+          <height>40</height>
+         </size>
+        </property>
+        <property name="text">
+         <string>创建</string>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <widget class="QFrame" name="dataWidget">
+     <property name="frameShape">
+      <enum>QFrame::Shape::StyledPanel</enum>
+     </property>
+     <property name="frameShadow">
+      <enum>QFrame::Shadow::Raised</enum>
+     </property>
+     <layout class="QVBoxLayout" name="verticalLayout_3">
+      <item>
+       <widget class="QTableView" name="tableView"/>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <widget class="QFrame" name="pagination">
+     <property name="minimumSize">
+      <size>
+       <width>0</width>
+       <height>30</height>
+      </size>
+     </property>
+     <property name="maximumSize">
+      <size>
+       <width>16777215</width>
+       <height>30</height>
+      </size>
+     </property>
+     <property name="frameShape">
+      <enum>QFrame::Shape::StyledPanel</enum>
+     </property>
+     <property name="frameShadow">
+      <enum>QFrame::Shadow::Raised</enum>
+     </property>
+     <layout class="QVBoxLayout" name="verticalLayout_4">
+      <property name="spacing">
+       <number>0</number>
+      </property>
+      <property name="leftMargin">
+       <number>0</number>
+      </property>
+      <property name="topMargin">
+       <number>0</number>
+      </property>
+      <property name="rightMargin">
+       <number>0</number>
+      </property>
+      <property name="bottomMargin">
+       <number>0</number>
+      </property>
+     </layout>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>

+ 266 - 0
blastProject/hproject.cpp

@@ -0,0 +1,266 @@
+#include "hproject.h"
+
+HProject::HProject(QObject *parent) : QObject(parent)
+{
+}
+
+// Getter and Setter implementations
+qint64 HProject::getId() const
+{
+    return id;
+}
+
+void HProject::setId(qint64 newId)
+{
+    id = newId;
+}
+
+QString HProject::getUuid() const
+{
+    return uuid;
+}
+
+void HProject::setUuid(const QString &newUuid)
+{
+    uuid = newUuid;
+}
+
+QString HProject::getName() const
+{
+    return name;
+}
+
+void HProject::setName(const QString &newName)
+{
+    name = newName;
+}
+
+QString HProject::getCompanyCode() const
+{
+    return companyCode;
+}
+
+void HProject::setCompanyCode(const QString &newCompanyCode)
+{
+    companyCode = newCompanyCode;
+}
+
+QString HProject::getHtid() const
+{
+    return htid;
+}
+
+void HProject::setHtid(const QString &newHtid)
+{
+    htid = newHtid;
+}
+
+QString HProject::getXmbh() const
+{
+    return xmbh;
+}
+
+void HProject::setXmbh(const QString &newXmbh)
+{
+    xmbh = newXmbh;
+}
+
+QString HProject::getOperatorName() const
+{
+    return operatorName;
+}
+
+void HProject::setOperatorName(const QString &newOperatorName)
+{
+    operatorName = newOperatorName;
+}
+
+QString HProject::getOperatorIdentity() const
+{
+    return operatorIdentity;
+}
+
+void HProject::setOperatorIdentity(const QString &newOperatorIdentity)
+{
+    operatorIdentity = newOperatorIdentity;
+}
+
+QString HProject::getBlasterName() const
+{
+    return blasterName;
+}
+
+void HProject::setBlasterName(const QString &newBlasterName)
+{
+    blasterName = newBlasterName;
+}
+
+QString HProject::getBlasterIdentity() const
+{
+    return blasterIdentity;
+}
+
+void HProject::setBlasterIdentity(const QString &newBlasterIdentity)
+{
+    blasterIdentity = newBlasterIdentity;
+}
+
+QString HProject::getAddressUuid() const
+{
+    return addressUuid;
+}
+
+void HProject::setAddressUuid(const QString &newAddressUuid)
+{
+    addressUuid = newAddressUuid;
+}
+
+QString HProject::getPcSn() const
+{
+    return pcSn;
+}
+
+void HProject::setPcSn(const QString &newPcSn)
+{
+    pcSn = newPcSn;
+}
+
+QString HProject::getDetSum() const
+{
+    return detSum;
+}
+
+void HProject::setDetSum(const QString &newDetSum)
+{
+    detSum = newDetSum;
+}
+
+QString HProject::getFileName() const
+{
+    return fileName;
+}
+
+void HProject::setFileName(const QString &newFileName)
+{
+    fileName = newFileName;
+}
+
+QString HProject::getFileUrl() const
+{
+    return fileUrl;
+}
+
+void HProject::setFileUrl(const QString &newFileUrl)
+{
+    fileUrl = newFileUrl;
+}
+
+QString HProject::getBlastStatus() const
+{
+    return blastStatus;
+}
+
+void HProject::setBlastStatus(const QString &newBlastStatus)
+{
+    blastStatus = newBlastStatus;
+}
+
+QDateTime HProject::getCreatedAt() const
+{
+    return createdAt;
+}
+
+void HProject::setCreatedAt(const QDateTime &newCreatedAt)
+{
+    createdAt = newCreatedAt;
+}
+
+QDateTime HProject::getUpdatedAt() const
+{
+    return updatedAt;
+}
+
+void HProject::setUpdatedAt(const QDateTime &newUpdatedAt)
+{
+    updatedAt = newUpdatedAt;
+}
+
+QDateTime HProject::getDeletedAt() const
+{
+    return deletedAt;
+}
+
+void HProject::setDeletedAt(const QDateTime &newDeletedAt)
+{
+    deletedAt = newDeletedAt;
+}
+
+qint64 HProject::getCreateBy() const
+{
+    return createBy;
+}
+
+void HProject::setCreateBy(qint64 newCreateBy)
+{
+    createBy = newCreateBy;
+}
+
+qint64 HProject::getUpdateBy() const
+{
+    return updateBy;
+}
+
+void HProject::setUpdateBy(qint64 newUpdateBy)
+{
+    updateBy = newUpdateBy;
+}
+
+QString HProject::getLoraAddress() const
+{
+    return loraAddress;
+}
+
+void HProject::setLoraAddress(const QString &newLoraAddress)
+{
+    loraAddress = newLoraAddress;
+}
+
+QString HProject::getBlastCount() const
+{
+    return blastCount;
+}
+
+void HProject::setBlastCount(const QString &newBlastCount)
+{
+    blastCount = newBlastCount;
+}
+
+QString HProject::getLoraSn() const
+{
+    return loraSn;
+}
+
+void HProject::setLoraSn(const QString &newLoraSn)
+{
+    loraSn = newLoraSn;
+}
+
+
+
+QByteArray HProject::ProjectToJson(const HProject& project) {
+    QJsonObject jsonObject;
+    jsonObject["name"] = project.getName();
+    jsonObject["uuid"] = project.getUuid();
+    jsonObject["detSum"] = project.getDetSum();
+    jsonObject["blasterName"] = project.getBlasterName();
+    jsonObject["operatorName"] = project.getOperatorName();
+    jsonObject["address"] = project.getAddressUuid();
+    jsonObject["blasterIdentity"] = project.getBlasterIdentity();
+    jsonObject["operatorIdentity"] = project.getOperatorIdentity();
+    jsonObject["loraAddress"] = project.getLoraAddress();
+    jsonObject["loraSn"] = project.getLoraSn();
+    jsonObject["blastCount"] = project.getBlastCount();
+    QJsonDocument jsonDoc(jsonObject);
+    return jsonDoc.toJson(QJsonDocument::Compact);
+}
+

+ 144 - 0
blastProject/hproject.h

@@ -0,0 +1,144 @@
+#ifndef HPROJECT_H
+#define HPROJECT_H
+
+#include <QString>
+#include <QDateTime>
+#include <QJsonObject>
+#include <QJsonDocument>
+#include <QUuid>
+
+class HProject : public QObject
+{
+    Q_OBJECT
+    // 定义属性
+    Q_PROPERTY(qint64 id READ getId WRITE setId)
+    Q_PROPERTY(QString uuid READ getUuid WRITE setUuid)
+    Q_PROPERTY(QString name READ getName WRITE setName)
+    Q_PROPERTY(QString companyCode READ getCompanyCode WRITE setCompanyCode)
+    Q_PROPERTY(QString htid READ getHtid WRITE setHtid)
+    Q_PROPERTY(QString xmbh READ getXmbh WRITE setXmbh)
+    Q_PROPERTY(QString operatorName READ getOperatorName WRITE setOperatorName)
+    Q_PROPERTY(QString operatorIdentity READ getOperatorIdentity WRITE setOperatorIdentity)
+    Q_PROPERTY(QString blasterName READ getBlasterName WRITE setBlasterName)
+    Q_PROPERTY(QString blasterIdentity READ getBlasterIdentity WRITE setBlasterIdentity)
+    Q_PROPERTY(QString addressUuid READ getAddressUuid WRITE setAddressUuid)
+    Q_PROPERTY(QString loraAddress READ getLoraAddress WRITE setLoraAddress)
+    Q_PROPERTY(QString loraSn READ getLoraSn WRITE setLoraSn)
+    Q_PROPERTY(QString pcSn READ getPcSn WRITE setPcSn)
+    Q_PROPERTY(QString detSum READ getDetSum WRITE setDetSum)
+    Q_PROPERTY(QString blastCount READ getBlastCount WRITE setBlastCount)
+    Q_PROPERTY(QString fileName READ getFileName WRITE setFileName)
+    Q_PROPERTY(QString fileUrl READ getFileUrl WRITE setFileUrl)
+    Q_PROPERTY(QString blastStatus READ getBlastStatus WRITE setBlastStatus)
+    Q_PROPERTY(QDateTime createdAt READ getCreatedAt WRITE setCreatedAt)
+    Q_PROPERTY(QDateTime updatedAt READ getUpdatedAt WRITE setUpdatedAt)
+    Q_PROPERTY(QDateTime deletedAt READ getDeletedAt WRITE setDeletedAt)
+    Q_PROPERTY(qint64 createBy READ getCreateBy WRITE setCreateBy)
+    Q_PROPERTY(qint64 updateBy READ getUpdateBy WRITE setUpdateBy)
+
+public:
+    explicit HProject(QObject *parent = nullptr);
+
+    // Getter and Setter methods
+    qint64 getId() const;
+    void setId(qint64 newId);
+
+    QString getUuid() const;
+    void setUuid(const QString &newUuid);
+
+    QString getName() const;
+    void setName(const QString &newName);
+
+    QString getCompanyCode() const;
+    void setCompanyCode(const QString &newCompanyCode);
+
+    QString getHtid() const;
+    void setHtid(const QString &newHtid);
+
+    QString getXmbh() const;
+    void setXmbh(const QString &newXmbh);
+
+    QString getOperatorName() const;
+    void setOperatorName(const QString &newOperatorName);
+
+    QString getOperatorIdentity() const;
+    void setOperatorIdentity(const QString &newOperatorIdentity);
+
+    QString getBlasterName() const;
+    void setBlasterName(const QString &newBlasterName);
+
+    QString getBlasterIdentity() const;
+    void setBlasterIdentity(const QString &newBlasterIdentity);
+
+    QString getAddressUuid() const;
+    void setAddressUuid(const QString &newAddressUuid);
+
+    QString getPcSn() const;
+    void setPcSn(const QString &newPcSn);
+
+    QString getDetSum() const;
+    void setDetSum(const QString &newDetSum);
+
+    QString getFileName() const;
+    void setFileName(const QString &newFileName);
+
+    QString getFileUrl() const;
+    void setFileUrl(const QString &newFileUrl);
+
+    QString getBlastStatus() const;
+    void setBlastStatus(const QString &newBlastStatus);
+
+    QDateTime getCreatedAt() const;
+    void setCreatedAt(const QDateTime &newCreatedAt);
+
+    QDateTime getUpdatedAt() const;
+    void setUpdatedAt(const QDateTime &newUpdatedAt);
+
+    QDateTime getDeletedAt() const;
+    void setDeletedAt(const QDateTime &newDeletedAt);
+
+    qint64 getCreateBy() const;
+    void setCreateBy(qint64 newCreateBy);
+
+    qint64 getUpdateBy() const;
+    void setUpdateBy(qint64 newUpdateBy);
+
+    QByteArray ProjectToJson(const HProject& project);
+
+    QString getLoraAddress() const;
+    void setLoraAddress(const QString &newLoraAddress);
+
+    QString getBlastCount() const;
+    void setBlastCount(const QString &newBlastCount);
+
+    QString getLoraSn() const;
+    void setLoraSn(const QString &newLoraSn);
+
+private:
+    qint64 id;
+    QString uuid;
+    QString name;
+    QString companyCode;
+    QString htid;
+    QString xmbh;
+    QString operatorName;
+    QString operatorIdentity;
+    QString blasterName;
+    QString blasterIdentity;
+    QString addressUuid;
+    QString loraAddress;
+    QString loraSn;
+    QString pcSn;
+    QString detSum;
+    QString blastCount;
+    QString fileName;
+    QString fileUrl;
+    QString blastStatus;
+    QDateTime createdAt;
+    QDateTime updatedAt;
+    QDateTime deletedAt;
+    qint64 createBy;
+    qint64 updateBy;
+};
+
+#endif // HPROJECT_H

+ 217 - 0
blastProject/hprojectdao.cpp

@@ -0,0 +1,217 @@
+#include "HProjectDao.h"
+
+
+HProjectDao::HProjectDao(QSqlDatabase db):database(db)
+{
+}
+
+bool HProjectDao::addHProject(const HProject &project)
+{
+
+    QSqlQuery query;
+    query.prepare("INSERT INTO h_project (uuid, name, company_code, htid, xmbh, operator_name, operator_identity, blaster_name, blaster_identity, address_uuid, lora_address,pc_sn, det_sum, file_name, file_url, blast_status,blast_count,created_at, updated_at, deleted_at, create_by, update_by) "
+                  "VALUES (:uuid, :name, :companyCode, :htid, :xmbh, :operatorName, :operatorIdentity, :blasterName, :blasterIdentity, :addressUuid,:loraAddress, :pcSn, :detSum, :fileName, :fileUrl, :blastStatus, :blastCount,:createdAt, :updatedAt, :deletedAt, :createBy, :updateBy)");
+
+    query.bindValue(":uuid", project.getUuid());
+    query.bindValue(":name", project.getName());
+    query.bindValue(":companyCode", project.getCompanyCode());
+    query.bindValue(":htid", project.getHtid());
+    query.bindValue(":xmbh", project.getXmbh());
+    query.bindValue(":operatorName", project.getOperatorName());
+    query.bindValue(":operatorIdentity", project.getOperatorIdentity());
+    query.bindValue(":blasterName", project.getBlasterName());
+    query.bindValue(":blasterIdentity", project.getBlasterIdentity());
+    query.bindValue(":addressUuid", project.getAddressUuid());
+    query.bindValue(":loraAddress", project.getLoraAddress());
+    query.bindValue(":blastCount", project.getBlastCount());
+    query.bindValue(":pcSn", project.getPcSn());
+    query.bindValue(":detSum", project.getDetSum());
+    query.bindValue(":fileName", project.getFileName());
+    query.bindValue(":fileUrl", project.getFileUrl());
+    query.bindValue(":blastStatus", project.getBlastStatus());
+    query.bindValue(":createdAt", project.getCreatedAt().toString(Qt::ISODateWithMs));
+    query.bindValue(":updatedAt", project.getUpdatedAt().toString(Qt::ISODateWithMs));
+    query.bindValue(":deletedAt", project.getDeletedAt().toString(Qt::ISODateWithMs));
+    query.bindValue(":createBy", project.getCreateBy());
+    query.bindValue(":updateBy", project.getUpdateBy());
+    qDebug() << "Executing SQL query:" << query.lastQuery();
+    if (!query.exec()) {
+        return false;
+    }
+
+    return true;
+}
+
+bool HProjectDao::updateHProject(const HProject &project)
+{
+    QSqlQuery query;
+    query.prepare("UPDATE h_project SET "
+                  "uuid = :uuid, "
+                  "name = :name, "
+                  "company_code = :companyCode, "
+                  "htid = :htid, "
+                  "xmbh = :xmbh, "
+                  "operator_name = :operatorName, "
+                  "operator_identity = :operatorIdentity, "
+                  "blaster_name = :blasterName, "
+                  "blaster_identity = :blasterIdentity, "
+                  "address_uuid = :addressUuid, "
+                  "pc_sn = :pcSn, "
+                  "det_sum = :detSum, "
+                  "file_name = :fileName, "
+                  "file_url = :fileUrl, "
+                  "blast_status = :blastStatus, "
+                  "created_at = :createdAt, "
+                  "updated_at = :updatedAt, "
+                  "deleted_at = :deletedAt, "
+                  "create_by = :createBy, "
+                  "update_by = :updateBy "
+                  "WHERE id = :id");
+
+    query.bindValue(":id", project.getId());
+    query.bindValue(":uuid", project.getUuid());
+    query.bindValue(":name", project.getName());
+    query.bindValue(":companyCode", project.getCompanyCode());
+    query.bindValue(":htid", project.getHtid());
+    query.bindValue(":xmbh", project.getXmbh());
+    query.bindValue(":operatorName", project.getOperatorName());
+    query.bindValue(":operatorIdentity", project.getOperatorIdentity());
+    query.bindValue(":blasterName", project.getBlasterName());
+    query.bindValue(":blasterIdentity", project.getBlasterIdentity());
+    query.bindValue(":addressUuid", project.getAddressUuid());
+    query.bindValue(":pcSn", project.getPcSn());
+    query.bindValue(":detSum", project.getDetSum());
+    query.bindValue(":fileName", project.getFileName());
+    query.bindValue(":fileUrl", project.getFileUrl());
+    query.bindValue(":blastStatus", project.getBlastStatus());
+    query.bindValue(":createdAt", project.getCreatedAt().toString(Qt::ISODateWithMs));
+    query.bindValue(":updatedAt", project.getUpdatedAt().toString(Qt::ISODateWithMs));
+    query.bindValue(":deletedAt", project.getDeletedAt().toString(Qt::ISODateWithMs));
+    query.bindValue(":createBy", project.getCreateBy());
+    query.bindValue(":updateBy", project.getUpdateBy());
+
+    if (!query.exec()) {
+        return false;
+    }
+
+    return true;
+}
+
+bool HProjectDao::deleteHProject(const HProject &project)
+{
+    QSqlQuery query;
+    query.prepare("DELETE FROM h_project WHERE id = :id");
+    query.bindValue(":id", project.getId());
+    if (!query.exec()) {
+        return false;
+    }
+    return true;
+}
+
+// HProject HProjectDao::getHProjectById(qint64 id)
+// {
+//     QSqlQuery query;
+//     // query.prepare("SELECT * FROM hproject WHERE id = :id");
+//     // query.bindValue(":id", id);
+//     // if (query.exec() && query.next()) {
+//     //     return recordToProject(query.record());
+//     // }
+//     return HProject();
+// }
+
+PaginatedHProjectResult HProjectDao::getAllHProjects(int page, int pageSize)
+{
+    QList<QSharedPointer<HProject>> projects;
+    QSqlQuery query(database);
+    int offset = (page - 1) * pageSize;
+    query.prepare("SELECT * FROM h_project ORDER BY created_at LIMIT :pageSize OFFSET :offset");
+    query.bindValue(":pageSize", pageSize);
+    query.bindValue(":offset", offset);
+
+    if (query.exec()) {
+
+        while (query.next()) {
+            projects.append(recordToProject(query.record()));
+        }
+    } else {
+        qWarning() << "Query execution failed: " << query.lastError().text();
+    }
+
+    query.prepare("SELECT COUNT(*) FROM h_project");
+    int totalCount = 0;
+    if (query.exec() && query.next()) {
+        totalCount = query.value(0).toInt();
+    }
+    return { projects, totalCount };
+}
+
+PaginatedHProjectResult HProjectDao::getAllHProjectsByOpera(int page, int pageSize)
+{
+    QList<QSharedPointer<HProject>> projects;
+    QSqlQuery query(database);
+    int offset = (page - 1) * pageSize;
+    query.prepare("SELECT * FROM h_project WHERE blast_status >1 ORDER BY created_at LIMIT :pageSize OFFSET :offset");
+    query.bindValue(":pageSize", pageSize);
+    query.bindValue(":offset", offset);
+    if (query.exec()) {
+        while (query.next()) {
+            projects.append(recordToProject(query.record()));
+        }
+    } else {
+        qWarning() << "Query execution failed: " << query.lastError().text();
+    }
+
+    query.prepare("SELECT COUNT(*) FROM h_project WHERE blast_status > 1");
+    int totalCount = 0;
+    if (query.exec() && query.next()) {
+        totalCount = query.value(0).toInt();
+    }
+    return { projects, totalCount };
+}
+
+
+//更改状态
+bool HProjectDao::updateBlastStatusByUuid(const QString &uuid, const QString &blastStatus)
+{
+    QSqlQuery query;
+    query.prepare("UPDATE h_project SET "
+                  "blast_status = :blastStatus "
+                  "WHERE uuid = :uuid");
+    query.bindValue(":uuid", uuid);
+    query.bindValue(":blastStatus", blastStatus);
+
+    if (!query.exec()) {
+        qCritical() << "Failed to update blast_status for HProject:" << query.lastError().text();
+        return false;
+    }
+
+    return true;
+}
+
+QSharedPointer<HProject> HProjectDao::recordToProject(const QSqlRecord &record)
+{
+    QSharedPointer<HProject> project = QSharedPointer<HProject>::create();
+    project->setId(record.value("id").toInt());
+    project->setUuid(record.value("uuid").toString());
+    project->setName(record.value("name").toString());
+    project->setCompanyCode(record.value("company_code").toString());
+    project->setHtid(record.value("htid").toString());
+    project->setXmbh(record.value("xmbh").toString());
+    project->setOperatorName(record.value("operator_name").toString());
+    project->setOperatorIdentity(record.value("operator_identity").toString());
+    project->setBlasterName(record.value("blaster_name").toString());
+    project->setBlasterIdentity(record.value("blaster_identity").toString());
+    project->setAddressUuid(record.value("address_uuid").toString());
+    project->setPcSn(record.value("pc_sn").toString());
+    project->setDetSum(record.value("det_sum").toString());
+    project->setBlastCount(record.value("blast_count").toString());
+    project->setFileName(record.value("file_name").toString());
+    project->setFileUrl(record.value("file_url").toString());
+    project->setBlastStatus(record.value("blast_status").toString());
+    project->setCreatedAt(QDateTime::fromString(record.value("created_at").toString(), Qt::ISODateWithMs));
+    project->setUpdatedAt(QDateTime::fromString(record.value("updated_at").toString(), Qt::ISODateWithMs));
+    project->setDeletedAt(QDateTime::fromString(record.value("deleted_at").toString(), Qt::ISODateWithMs));
+    project->setCreateBy(record.value("create_by").toInt());
+    project->setUpdateBy(record.value("update_by").toInt());
+    return project;
+}

+ 349 - 0
blastProject/projectdialog.cpp

@@ -0,0 +1,349 @@
+#include "projectdialog.h"
+#include "ui_projectdialog.h"
+
+
+ProjectDialog::ProjectDialog(QWidget *parent) :
+    QDialog(parent),
+    ui(new Ui::ProjectDialog)
+{
+    ui->setupUi(this);
+    connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &ProjectDialog::validateInput);
+    connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &ProjectDialog::clearFormData);
+}
+
+
+void ProjectDialog::SetComboBoxBlast(const QJsonArray& bapoYuanArray)
+{
+    blasterArray =bapoYuanArray;
+    ui->comboBoxBlast->clear();
+    fillComboBox(ui->comboBoxBlast, bapoYuanArray);
+    ui->comboBoxBlast->setCurrentIndex(-1);
+}
+
+
+void ProjectDialog::SetComboBoxOperator(const QJsonArray& anQuanYuanArray)
+{
+    operatorArray =anQuanYuanArray;
+    ui->comboBoxOperator->clear();
+    fillComboBox(ui->comboBoxOperator, anQuanYuanArray);
+    ui->comboBoxOperator->setCurrentIndex(-1);
+}
+
+void ProjectDialog::on_comboBoxOperator_currentIndexChanged(int index)
+{
+    if (index >= 0 && index < operatorArray.size()) {
+        operatorId = operatorArray[index].toObject()["identity"].toString();
+    }
+}
+
+void ProjectDialog::on_comboBoxBlast_currentIndexChanged(int index)
+{
+    if (index >= 0 && index < blasterArray.size()) {
+        blasterId = blasterArray[index].toObject()["identity"].toString();
+    }
+
+}
+
+void ProjectDialog::fillComboBox(QComboBox* comboBox, const QJsonArray& jsonArray) {
+    for (const QJsonValue &value : jsonArray) {
+        if (value.isObject()) {
+            QJsonObject obj = value.toObject();
+            if (obj.contains("name")) {
+                QString name = obj["name"].toString();
+                comboBox->addItem(name);
+            }
+        }
+    }
+}
+
+
+void ProjectDialog::SetComboBoxAddress(const QJsonArray& Options)
+{       parentOptions = Options;
+        ui->comboBoxAddr->clear();
+            for (const QJsonValue &option : Options) {
+                ui->comboBoxAddr->addItem(option.toString());
+            }
+                ui->comboBoxAddr->setCurrentIndex(-1);
+}
+
+void ProjectDialog::SetComboBoxAddress2(const QString &parentName)
+{
+    ui->comboBoxAddr_2->clear();
+    for (const QJsonValue &item : dataOptions) {
+        const QJsonObject &obj = item.toObject();
+        if (obj["name"].toString() == parentName) {
+            const QJsonArray &children = obj["children"].toArray();
+            childOptions = children;
+            for (const QJsonValue &child : children) {
+                ui->comboBoxAddr_2->addItem(child.toObject()["name"].toString());
+            }
+            break;
+        }
+    };
+    ui->comboBoxAddr_2->setCurrentIndex(-1);
+}
+
+void ProjectDialog::SetComboBoxAddress3(const QString &childName)
+{
+    ui->comboBoxAddr_3->clear();
+    for (const QJsonValue &item : dataOptions) {
+        const QJsonArray &childrenArray = item["children"].toArray();
+        for (const QJsonValue &child : childrenArray) {
+            const QJsonObject &childObj = child.toObject();
+            if (childObj["name"].toString() == childName) {
+                const QJsonArray &grandChildrenArray = childObj["children"].toArray();
+                grandChildOptions = grandChildrenArray;
+                qDebug() << "grandChildOptions " << grandChildOptions;
+                for (const QJsonValue &grandChild : grandChildrenArray) {
+                    const QJsonObject &grandChildObj = grandChild.toObject();
+                    ui->comboBoxAddr_3->addItem(grandChildObj["name"].toString());
+                }
+                break;
+            }
+        };
+    }
+
+    ui->comboBoxAddr_3->setCurrentIndex(-1);
+}
+
+
+void ProjectDialog::setChildOptions( const QJsonArray& newDataOptions)
+{
+    dataOptions = newDataOptions;
+
+}
+
+void ProjectDialog::SetComboBoxLora(const QString &grandChildName)
+{
+
+    ui->comboBoxLora->clear();
+    for (const QJsonValue &item : dataOptions) {
+           const QJsonArray &childrenArray = item["children"].toArray();
+           for (const QJsonValue &child : childrenArray) {
+               const QJsonObject &childObj = child.toObject();
+               const QJsonArray &grandChildrenArray = childObj["children"].toArray();
+               for (const QJsonValue &grandChild : grandChildrenArray) {
+                   const QJsonObject &grandChildObj = grandChild.toObject();
+                   if (grandChildObj["name"].toString() == grandChildName) {
+                       const QJsonArray &greatGrandChildrenArray = grandChildObj["children"].toArray();
+                       for (const QJsonValue &greatGrandChild : greatGrandChildrenArray) {
+                           const QJsonObject &greatGrandChildObj = greatGrandChild.toObject();
+                           qDebug() << "greatGrandChildObj " << greatGrandChildObj;
+                           QString name = greatGrandChildObj["name"].toString();
+                           QString loraSn = greatGrandChildObj["loraSn"].toString();
+                           ui->comboBoxLora->addItem(name);
+                           nameLoraSnMap.insert(name, loraSn);
+                           QHash<QString, QString>::const_iterator i;
+                           for (i = nameLoraSnMap.constBegin(); i != nameLoraSnMap.constEnd(); ++i) {
+                               qDebug() << "Key:" << i.key() << ", Value:" << i.value();
+                           }
+                       }
+                       break;
+                   }
+               }
+           }
+       }
+    ui->comboBoxLora->setCurrentIndex(-1);
+}
+
+
+
+
+void ProjectDialog::extractNames(const QJsonArray& array, QStringList& names) {
+    for (const auto& item : array) {
+        if (item.isObject()) {
+            QJsonObject obj = item.toObject();
+            if (obj.contains("name")) {
+                names.append(obj["name"].toString());
+            }
+            if (obj.contains("children") && obj["children"].isArray()) {
+                extractNames(obj["children"].toArray(), names);
+            }
+        }
+    }
+}
+
+void ProjectDialog::clearFormData()
+{
+    QList<QLineEdit*> lineEdits = findChildren<QLineEdit*>();
+    for (QLineEdit* lineEdit : lineEdits) {
+        lineEdit->clear();
+    }
+
+    QList<QComboBox*> comboBoxes = findChildren<QComboBox*>();
+    for (QComboBox* comboBox : comboBoxes) {
+        comboBox->setCurrentIndex(-1);
+    }
+
+}
+
+void ProjectDialog::on_comboBoxAddr_currentIndexChanged(int index)
+{
+    if (index >= 0 && index < parentOptions.size()) {
+        QString parentName = parentOptions[index].toString();
+        SetComboBoxAddress2(parentName);
+    }
+}
+
+
+void ProjectDialog::on_comboBoxAddr_2_currentIndexChanged(int index)
+{
+
+    if (index >= -1 && index < childOptions.size()) {
+        QString childName = childOptions[index].toObject()["name"].toString();
+        SetComboBoxAddress3(childName);
+    }
+}
+
+void ProjectDialog::on_comboBoxAddr_3_currentIndexChanged(int index)
+{
+
+    if (index >= -1 && index < grandChildOptions.size()) {
+        QString grandChildName = grandChildOptions[index].toObject()["name"].toString();
+        SetComboBoxLora(grandChildName);
+     }
+}
+
+
+
+
+void ProjectDialog::validateInput()
+{
+    QString detNum = ui->editDetNum->text().trimmed();
+    QString blastCount = ui->editRegCount->text().trimmed();
+    QString projectName = ui->editName->text().trimmed();
+    QString blastName= ui->comboBoxBlast->currentText().trimmed();
+    QString operatorName= ui->comboBoxOperator->currentText().trimmed();
+    QString parentAddress= ui->comboBoxAddr->currentText().trimmed();
+    QString childAddress= ui->comboBoxAddr_2->currentText().trimmed();
+    QString grandChildAddress= ui->comboBoxAddr_3->currentText().trimmed();
+    QString loraAddress= ui->comboBoxLora->currentText().trimmed();
+
+
+    if (detNum.isEmpty() || !ui->editDetNum->hasAcceptableInput()) {
+        QMessageBox::warning(this, "输入错误", "请输入0-10000的数字!");
+        return;
+    }
+    // 创建一个 QMap 集合,存储数据
+    QMap<QString, QString> data;
+    data["detNum"] = detNum;
+    data["name"] = projectName;
+    data["operatorName"] = operatorName;
+    data["blasterName"] = blastName;
+    // 拼接 addressUuid
+    QString addressUuid = parentAddress;
+    if (!childAddress.isEmpty()) {
+        qDebug()<<"childAddress"<<childAddress;
+        addressUuid += "/" + childAddress;
+        if (!grandChildAddress.isEmpty()) {
+            addressUuid += "/" + grandChildAddress;
+        }
+    }
+    data["addressUuid"] = addressUuid;
+    data["blasterIdentity"] = blasterId;
+    data["operatorIdentity"] = operatorId;
+    data["loraAddress"] = loraAddress;
+    data["loraSn"] = nameLoraSnMap.value(loraAddress);
+    data["blastCount"] = blastCount;
+    if(operationStatus==0){
+        emit validateDetNum(data);
+    } else if (operationStatus==1) {
+        emit validateDetNumUpdate(data);
+    }
+    clearFormData(); // 清除表单数据
+    // this->accept();
+}
+
+int ProjectDialog::getOperationStatus() const
+{
+    return operationStatus;
+}
+
+void ProjectDialog::setOperationStatus(int newOperationStatus)
+{
+    operationStatus = newOperationStatus;
+}
+
+
+void ProjectDialog::setFormData(const HProject &Project)
+{
+    try {
+        ui->editName->setText(Project.getName());
+        ui->editDetNum->setText(Project.getDetSum());
+        ui->editHTID->setText(Project.getHtid());
+        ui->editXMBH->setText(Project.getXmbh());
+        int indexBlast = ui->comboBoxBlast->findText(Project.getBlasterName());
+        if (indexBlast!= -1) {
+            ui->comboBoxBlast->setCurrentIndex(indexBlast);
+        } else {
+            qDebug() << "未找到选项 " <<  "。";
+        }
+        int indexOper = ui->comboBoxOperator->findText(Project.getOperatorName());
+        if (indexOper!= -1) {
+            ui->comboBoxOperator->setCurrentIndex(indexOper);
+        } else {
+            qDebug() << "未找到选项 " <<  "。";
+        }
+        QStringList addressParts = Project.getAddressUuid().split("/");
+        int numAddresses = addressParts.size();
+        qDebug() << "numAddresses " << numAddresses;
+        QVector<QString> addressVariables;
+        for (int i = 0; i < numAddresses; ++i) {
+            QString part = addressParts[i];
+            addressVariables.append(part);
+
+        }
+        // 查找目标文本对应的索引
+        int indexAddr = ui->comboBoxAddr->findText(addressVariables[0]);
+
+        if (indexAddr != -1) {
+            // 如果找到了对应的索引,设置为当前索引
+            ui->comboBoxAddr->setCurrentIndex(indexAddr);
+            qDebug() << "已将选项 " << addressVariables[0] << " 设置为当前显示的选项。";
+        } else {
+            // 如果没找到,输出提示信息
+            qDebug() << "未找到选项 " << addressVariables[0];
+        }
+        if(addressVariables.size()>=2){
+            int indexAddr_2 = ui->comboBoxAddr_2->findText(addressVariables[1]);
+
+            if (indexAddr_2 != -1) {
+                // 如果找到了对应的索引,设置为当前索引
+                ui->comboBoxAddr_2->setCurrentIndex(indexAddr_2);
+                qDebug() << "已将选项 " << addressVariables[1] << " 设置为当前显示的选项。";
+            } else {
+                // 如果没找到,输出提示信息
+                qDebug() << "未找到选项 " << addressVariables[1];
+            }
+        }
+
+        if(addressVariables.size()>=3){
+            int indexAddr_3 = ui->comboBoxAddr_3->findText(addressVariables[2]);
+
+            if (indexAddr_3 != -1) {
+                // 如果找到了对应的索引,设置为当前索引
+                ui->comboBoxAddr_3->setCurrentIndex(indexAddr_3);
+                qDebug() << "已将选项 " << addressVariables[2] << " 设置为当前显示的选项。";
+            } else {
+                // 如果没找到,输出提示信息
+                qDebug() << "未找到选项 " << addressVariables[2];
+            }
+        }
+    } catch (const std::exception& e) {
+        qDebug() << "发生异常: " << e.what();
+    } catch (...) {
+        qDebug() << "发生未知异常";
+    }
+
+
+}
+
+ProjectDialog::~ProjectDialog()
+{
+    delete ui;
+}
+
+
+
+
+

+ 72 - 0
blastProject/projectdialog.h

@@ -0,0 +1,72 @@
+#ifndef PROJECTDIALOG_H
+#define PROJECTDIALOG_H
+
+#include <QDialog>
+#include <QComboBox>
+#include <QJsonArray>
+#include <QJsonObject>
+#include <QHash>
+#include "hproject.h"
+#include "../regex.h"
+
+namespace Ui {
+class ProjectDialog;
+}
+
+class ProjectDialog : public QDialog
+{
+    Q_OBJECT
+
+public:
+    explicit ProjectDialog(QWidget *parent = nullptr);
+    ~ProjectDialog();
+    void SetComboBoxBlast(const QJsonArray &bapoYuan);
+    void SetComboBoxOperator(const QJsonArray &anQuanYuanArray);
+    void SetComboBoxAddress(const QJsonArray &parentOptions);
+    void setChildOptions(const QJsonArray &newChildOptions);
+    void clearFormData();
+    void setFormData(const HProject &Project);
+    int getOperationStatus() const;
+    void setOperationStatus(int newOperationStatus);
+
+private slots:
+    void on_comboBoxAddr_currentIndexChanged(int index);
+
+    void on_comboBoxAddr_2_currentIndexChanged(int index);
+
+    void on_comboBoxOperator_currentIndexChanged(int index);
+
+    void on_comboBoxBlast_currentIndexChanged(int index);
+
+    void on_comboBoxAddr_3_currentIndexChanged(int index);
+
+signals:
+    void validateDetNum(const QMap<QString, QString> &data);
+    void validateDetNumUpdate(const QMap<QString, QString> &data);
+
+
+private:
+    void fillComboBox(QComboBox *comboBox, const QJsonArray &jsonArray);
+    void SetComboBoxAddress2(const QString &parentName);
+    void SetComboBoxAddress3(const QString &childName);
+    void validateInput();
+    void SetComboBoxLora(const QString &grandChildName);
+    void extractNames(const QJsonArray &array, QStringList &names);
+
+private:
+    Ui::ProjectDialog *ui;
+    QString blasterId;
+    QString operatorId;
+    QJsonArray blasterArray;
+    QJsonArray operatorArray;
+    QJsonArray dataOptions;
+    QJsonArray parentOptions;
+    QStringList loraOptions;
+    QJsonArray childOptions;
+    QJsonArray grandChildOptions;
+    QHash<QString, QString> nameLoraSnMap;
+    int operationStatus;
+
+};
+
+#endif // PROJECTDIALOG_H

+ 168 - 0
blastProject/projectdialog.ui

@@ -0,0 +1,168 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ProjectDialog</class>
+ <widget class="QDialog" name="ProjectDialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>505</width>
+    <height>426</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Dialog</string>
+  </property>
+  <layout class="QGridLayout" name="gridLayout">
+   <item row="0" column="0">
+    <layout class="QFormLayout" name="formLayout">
+     <item row="0" column="0">
+      <widget class="QLabel" name="labName">
+       <property name="text">
+        <string>工程名称:</string>
+       </property>
+      </widget>
+     </item>
+     <item row="0" column="1">
+      <widget class="QLineEdit" name="editName"/>
+     </item>
+     <item row="1" column="0">
+      <widget class="QLabel" name="labHTID">
+       <property name="text">
+        <string>合同编号:</string>
+       </property>
+      </widget>
+     </item>
+     <item row="1" column="1">
+      <widget class="QLineEdit" name="editHTID"/>
+     </item>
+     <item row="2" column="0">
+      <widget class="QLabel" name="labXMBH">
+       <property name="text">
+        <string>项目编号:</string>
+       </property>
+      </widget>
+     </item>
+     <item row="2" column="1">
+      <widget class="QLineEdit" name="editXMBH"/>
+     </item>
+     <item row="3" column="0">
+      <widget class="QLabel" name="labOperaName">
+       <property name="text">
+        <string>操作员:</string>
+       </property>
+      </widget>
+     </item>
+     <item row="3" column="1">
+      <widget class="QComboBox" name="comboBoxOperator"/>
+     </item>
+     <item row="4" column="0">
+      <widget class="QLabel" name="labBlastName">
+       <property name="text">
+        <string>爆破员:</string>
+       </property>
+      </widget>
+     </item>
+     <item row="4" column="1">
+      <widget class="QComboBox" name="comboBoxBlast"/>
+     </item>
+     <item row="5" column="0">
+      <widget class="QLabel" name="labAddress">
+       <property name="text">
+        <string>井下地址</string>
+       </property>
+      </widget>
+     </item>
+     <item row="5" column="1">
+      <layout class="QHBoxLayout" name="horizontalLayout">
+       <item>
+        <widget class="QComboBox" name="comboBoxAddr"/>
+       </item>
+       <item>
+        <widget class="QComboBox" name="comboBoxAddr_2"/>
+       </item>
+       <item>
+        <widget class="QComboBox" name="comboBoxAddr_3"/>
+       </item>
+      </layout>
+     </item>
+     <item row="8" column="0">
+      <widget class="QLabel" name="labDetNum">
+       <property name="text">
+        <string>雷管数量:</string>
+       </property>
+      </widget>
+     </item>
+     <item row="8" column="1">
+      <widget class="QLineEdit" name="editDetNum"/>
+     </item>
+     <item row="6" column="0">
+      <widget class="QLabel" name="label">
+       <property name="text">
+        <string>定位器地址:</string>
+       </property>
+      </widget>
+     </item>
+     <item row="6" column="1">
+      <widget class="QComboBox" name="comboBoxLora"/>
+     </item>
+     <item row="7" column="0">
+      <widget class="QLabel" name="labRegCount">
+       <property name="text">
+        <string>起爆器数量:</string>
+       </property>
+      </widget>
+     </item>
+     <item row="7" column="1">
+      <widget class="QLineEdit" name="editRegCount"/>
+     </item>
+    </layout>
+   </item>
+   <item row="1" column="0">
+    <widget class="QDialogButtonBox" name="buttonBox">
+     <property name="orientation">
+      <enum>Qt::Orientation::Horizontal</enum>
+     </property>
+     <property name="standardButtons">
+      <set>QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>ProjectDialog</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>248</x>
+     <y>254</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>ProjectDialog</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>316</x>
+     <y>260</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>

+ 134 - 0
blastRecord/HBlastRecord.h

@@ -0,0 +1,134 @@
+#ifndef HBLASTRECORD_H
+#define HBLASTRECORD_H
+
+
+#include <QString>
+#include <QDateTime>
+#include <QJsonObject>
+#include <QJsonDocument>
+#include <QUuid>
+
+class HBlastRecord : public QObject
+{
+
+    Q_OBJECT
+    // 定义属性
+    Q_PROPERTY(qint64 id READ getId WRITE setId)
+    Q_PROPERTY(QString uuid READ getUuid WRITE setUuid)
+    Q_PROPERTY(QString projectName READ getProjectName WRITE setProjectName)
+    Q_PROPERTY(QString projectHtid READ getProjectHtid WRITE setProjectHtid)
+    Q_PROPERTY(QString projectXmbh READ getProjectXmbh WRITE setProjectXmbh)
+    Q_PROPERTY(QString operatorName READ getOperatorName WRITE setOperatorName)
+    Q_PROPERTY(QString phone READ getPhone WRITE setPhone)
+    Q_PROPERTY(QString operatorIdentity READ getOperatorIdentity WRITE setOperatorIdentity)
+    Q_PROPERTY(QString equipmentSn READ getEquipmentSn WRITE setEquipmentSn)
+    Q_PROPERTY(QString companyCode READ getCompanyCode WRITE setCompanyCode)
+    Q_PROPERTY(QString appVersion READ getAppVersion WRITE setAppVersion)
+    Q_PROPERTY(QString longitude READ getLongitude WRITE setLongitude)
+    Q_PROPERTY(QString latitude READ getLatitude WRITE setLatitude)
+    Q_PROPERTY(int equipmentCount READ getEquipmentCount WRITE setEquipmentCount)
+    Q_PROPERTY(int regDetCount READ getRegDetCount WRITE setRegDetCount)
+    Q_PROPERTY(int errorDetCount READ getErrorDetCount WRITE setErrorDetCount)
+    Q_PROPERTY(QDateTime blastAt READ getBlastAt WRITE setBlastAt)
+    Q_PROPERTY(QDateTime createdAt READ getCreatedAt WRITE setCreatedAt)
+    Q_PROPERTY(QDateTime updatedAt READ getUpdatedAt WRITE setUpdatedAt)
+    Q_PROPERTY(QDateTime deletedAt READ getDeletedAt WRITE setDeletedAt)
+    Q_PROPERTY(qint64 createBy READ getCreateBy WRITE setCreateBy)
+    Q_PROPERTY(qint64 updateBy READ getUpdateBy WRITE setUpdateBy)
+public:
+    explicit HBlastRecord(QObject *parent = nullptr);
+    // Getter and Setter methods
+    qint64 getId() const;
+    void setId(qint64 newId);
+
+    QString getUuid() const;
+    void setUuid(const QString &newUuid);
+
+    QString getProjectName() const;
+    void setProjectName(const QString &newProjectName);
+
+    QString getProjectHtid() const;
+    void setProjectHtid(const QString &newProjectHtid);
+
+    QString getProjectXmbh() const;
+    void setProjectXmbh(const QString &newProjectXmbh);
+
+    QString getOperatorName() const;
+    void setOperatorName(const QString &newOperatorName);
+
+    QString getPhone() const;
+    void setPhone(const QString &newPhone);
+
+    QString getOperatorIdentity() const;
+    void setOperatorIdentity(const QString &newOperatorIdentity);
+
+    QString getEquipmentSn() const;
+    void setEquipmentSn(const QString &newEquipmentSn);
+
+    QString getCompanyCode() const;
+    void setCompanyCode(const QString &newCompanyCode);
+
+    QString getAppVersion() const;
+    void setAppVersion(const QString &newAppVersion);
+
+    QString getLongitude() const;
+    void setLongitude(const QString &newLongitude);
+
+    QString getLatitude() const;
+    void setLatitude(const QString &newLatitude);
+
+    int getEquipmentCount() const;
+    void setEquipmentCount(int newEquipmentCount);
+
+    int getRegDetCount() const;
+    void setRegDetCount(int newRegDetCount);
+
+    int getErrorDetCount() const;
+    void setErrorDetCount(int newErrorDetCount);
+
+    QDateTime getBlastAt() const;
+    void setBlastAt(const QDateTime &newBlastAt);
+
+    QDateTime getCreatedAt() const;
+    void setCreatedAt(const QDateTime &newCreatedAt);
+
+    QDateTime getUpdatedAt() const;
+    void setUpdatedAt(const QDateTime &newUpdatedAt);
+
+    QDateTime getDeletedAt() const;
+    void setDeletedAt(const QDateTime &newDeletedAt);
+
+    qint64 getCreateBy() const;
+    void setCreateBy(qint64 newCreateBy);
+
+    qint64 getUpdateBy() const;
+    void setUpdateBy(qint64 newUpdateBy);
+
+    QByteArray BlastRecordToJson(const HBlastRecord& record);
+
+private:
+    qint64 id;
+    QString uuid;
+    QString projectName;
+    QString projectHtid;
+    QString projectXmbh;
+    QString operatorName;
+    QString phone;
+    QString operatorIdentity;
+    QString equipmentSn;
+    QString companyCode;
+    QString appVersion;
+    QString longitude;
+    QString latitude;
+    int equipmentCount;
+    int regDetCount;
+    int errorDetCount;
+    QDateTime blastAt;
+    QDateTime createdAt;
+    QDateTime updatedAt;
+    QDateTime deletedAt;
+    qint64 createBy;
+    qint64 updateBy;
+};
+
+#endif // HBLASTRECORD_H

+ 146 - 0
blastRecord/blastrecord.cpp

@@ -0,0 +1,146 @@
+#include "blastrecord.h"
+#include "ui_blastrecord.h"
+
+BlastRecord::BlastRecord(QWidget *parent) :
+    QWidget(parent),
+    ui(new Ui::BlastRecord),
+    dao(DatabaseManager::getInstance().getDatabase())
+{
+    ui->setupUi(this);
+    m_pPageWidget = new PageWidget;
+    connect(m_pPageWidget, &PageWidget::currentPageChanged, this, &BlastRecord::PageChanged);
+    connect(m_pPageWidget->getComboBox(), QOverload<int>::of(&QComboBox::currentIndexChanged), this, &BlastRecord::onComboBoxIndexChanged);
+    m_httpClient = new HttpClient(this);
+    pageSize = 10;
+    currentPage = 1;
+    ui->verticalLayout_4->addWidget(m_pPageWidget);
+    loadAndRefreshData();
+
+}
+
+void BlastRecord::loadAndRefreshData() {
+    loadDataFromSource(currentPage,pageSize);
+}
+
+void BlastRecord::loadDataFromSource(int currentPage,int pageSize)
+{
+    PaginatedHBlastRecordResult result =dao.getAllHRecords(currentPage,pageSize);
+
+    QList<QSharedPointer<HBlastRecord>> blastRecordsList = result.BlastRecords;
+    totalCount = result.totalCount;
+
+    m_pPageWidget->setMaxPage(ceil(static_cast<double>(totalCount)/pageSize));
+    QStandardItemModel *model;
+    model = new QStandardItemModel(this);
+    // 定义表头信息
+
+    QList<HeaderInfo> headers = {
+        {"工程名称", "projectName"},
+        {"app版本", "appVersion"},
+        {"起爆器编号", "equipmentSn"},
+        {"注册雷管", "regDetCount"},
+        {"起爆时间", "blastAt"},
+        {"上报时间", "updatedAt"},
+    };
+
+    QStringList headerLabels;
+    QMap<int, QString> propMap;
+    for (int i = 0; i < headers.size(); ++i) {
+        headerLabels << headers[i].label;
+        propMap[i] = headers[i].prop;
+    }
+    model->setHorizontalHeaderLabels(headerLabels);
+
+    for (int row = 0; row < blastRecordsList.size(); ++row) {
+        HBlastRecord& HBlastRecord = *blastRecordsList.at(row).data();
+        for (int col = 0; col < headers.size(); ++col) {
+            QString prop = propMap[col];
+            QStandardItem* item = nullptr;
+            if (!prop.isEmpty()) {
+                QMetaProperty metaProp = HBlastRecord.metaObject()->property(HBlastRecord.metaObject()->indexOfProperty(prop.toUtf8()));
+                QVariant value = metaProp.read(&HBlastRecord);
+                if (value.type() == QVariant::DateTime) {
+                    QDateTime dateTime = value.toDateTime();
+                    item = new QStandardItem(dateTime.toString("yyyy-MM-dd HH:mm:ss"));
+                } else {
+                    item = new QStandardItem(value.toString());
+                    }
+            } else {
+                item = new QStandardItem("操作");
+            }
+            if (item) {
+                item->setTextAlignment(Qt::AlignCenter);
+                model->setItem(row, col, item);
+            }
+        }
+    }
+    ui->tableView->setModel(model);
+    ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
+    ui->tableView->setAlternatingRowColors(true);  // 启用交替行颜色
+    ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
+
+}
+void BlastRecord::PageChanged(int page)
+{
+    currentPage = page;
+    loadDataFromSource(currentPage,pageSize);
+}
+
+
+void BlastRecord::onComboBoxIndexChanged(int index) {
+     QVariant variant = m_pPageWidget->getComboBox()->itemData(index);
+     int value = variant.toInt();
+     pageSize = value;
+    loadDataFromSource(currentPage,pageSize);
+
+}
+
+
+void BlastRecord::dataTable(const QJsonDocument &jsonDoc)
+{
+    parseJsonString(jsonDoc);
+    model = new QStandardItemModel(this);
+    model->setHorizontalHeaderLabels({"工程名称", "app版本", "起爆器编号","注册雷管","起爆时间","上报时间"});
+
+    for (const QJsonValue& jsonValue : dataArray) {
+        QJsonObject jsonObj = jsonValue.toObject();
+        QList<QStandardItem*> items = jsonToItem(jsonObj);
+        model->appendRow(items);
+    }
+
+
+    ui->tableView->setModel(model);
+    ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
+    ui->tableView->setAlternatingRowColors(true);
+
+}
+
+
+QList<QStandardItem *> BlastRecord::jsonToItem(const QJsonObject &jsonObj)
+{
+      QStandardItem* nameItem = new QStandardItem(jsonObj["name"].toString());
+      nameItem->setTextAlignment(Qt::AlignCenter);
+      QStandardItem* equipItem = new QStandardItem(jsonObj["equipmentSn"].toString());
+      QStandardItem* typeItem = new QStandardItem(jsonObj["equipmentTypeName"].toString());
+      QStandardItem* statusItem = new QStandardItem(jsonObj["statusName"].toString());
+      QStandardItem* onlineItem = new QStandardItem(jsonObj["onlineName"].toString());
+      QString createdAtStr = jsonObj["createdAt"].toString();
+      QDateTime createdAt = QDateTime::fromString(createdAtStr, Qt::ISODateWithMs);
+      QString formattedCreatedAt = createdAt.toString("yyyy-MM-dd HH:mm:ss");
+      QStandardItem* createdItem = new QStandardItem(formattedCreatedAt);
+
+      return QList<QStandardItem*>() << nameItem << equipItem << typeItem<<statusItem<<onlineItem<<createdItem;
+
+}
+void BlastRecord::parseJsonString(const QJsonDocument &jsonDoc)
+{
+    QJsonObject jsonObj = jsonDoc.object();
+    QJsonObject dataObj = jsonObj["data"].toObject();
+    dataArray = dataObj["list"].toArray();
+    totalCount = dataObj["count"].toInt();
+    m_pPageWidget->setMaxPage(ceil(static_cast<double>(totalCount)/pageSize));
+}
+BlastRecord::~BlastRecord()
+{
+    delete ui;
+}

+ 48 - 0
blastRecord/blastrecord.h

@@ -0,0 +1,48 @@
+#ifndef BLASTRECORD_H
+#define BLASTRECORD_H
+
+#include <QWidget>
+#include <QJsonObject>
+#include <QJsonArray>
+#include <QJsonDocument>
+#include <QStandardItemModel>
+#include <QUrl>
+#include "../httpclient.h"
+#include "../global.h"
+#include "../PageWidget.h"
+#include "../global.h"
+#include "hblastrecorddao.h"
+namespace Ui {
+class BlastRecord;
+}
+
+class BlastRecord : public QWidget
+{
+    Q_OBJECT
+
+public:
+    explicit BlastRecord(QWidget *parent = nullptr);
+    ~BlastRecord();
+
+private:
+    void parseJsonString(const QJsonDocument& jsonDoc);
+    void dataTable( const QJsonDocument& jsonDoc);
+    void loadDataFromSource(int currentPage, int pageSize);
+    void loadAndRefreshData();
+    void PageChanged(int page);
+    void onComboBoxIndexChanged(int index);
+    QList<QStandardItem*> jsonToItem(const QJsonObject& jsonObj);
+
+private:
+    Ui::BlastRecord *ui;
+    PageWidget *m_pPageWidget;
+    int pageSize;  //每页显示的记录数量
+    int currentPage;      //当前页面
+    int totalCount;
+    HBlastRecordDao dao;
+    HttpClient *m_httpClient;
+    QStandardItemModel *model;
+    QJsonArray dataArray;
+};
+
+#endif // BLASTRECORD_H

+ 106 - 0
blastRecord/blastrecord.ui

@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>BlastRecord</class>
+ <widget class="QWidget" name="BlastRecord">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>868</width>
+    <height>524</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <widget class="QFrame" name="searchBox">
+     <property name="maximumSize">
+      <size>
+       <width>16777215</width>
+       <height>50</height>
+      </size>
+     </property>
+     <property name="frameShape">
+      <enum>QFrame::Shape::StyledPanel</enum>
+     </property>
+     <property name="frameShadow">
+      <enum>QFrame::Shadow::Raised</enum>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QFrame" name="dataWidget">
+     <property name="frameShape">
+      <enum>QFrame::Shape::StyledPanel</enum>
+     </property>
+     <property name="frameShadow">
+      <enum>QFrame::Shadow::Raised</enum>
+     </property>
+     <layout class="QVBoxLayout" name="verticalLayout_3">
+      <property name="spacing">
+       <number>0</number>
+      </property>
+      <property name="leftMargin">
+       <number>0</number>
+      </property>
+      <property name="topMargin">
+       <number>0</number>
+      </property>
+      <property name="rightMargin">
+       <number>0</number>
+      </property>
+      <property name="bottomMargin">
+       <number>0</number>
+      </property>
+      <item>
+       <widget class="QTableView" name="tableView"/>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <widget class="QFrame" name="pagination">
+     <property name="minimumSize">
+      <size>
+       <width>0</width>
+       <height>30</height>
+      </size>
+     </property>
+     <property name="maximumSize">
+      <size>
+       <width>16777215</width>
+       <height>30</height>
+      </size>
+     </property>
+     <property name="frameShape">
+      <enum>QFrame::Shape::StyledPanel</enum>
+     </property>
+     <property name="frameShadow">
+      <enum>QFrame::Shadow::Raised</enum>
+     </property>
+     <layout class="QVBoxLayout" name="verticalLayout_4">
+      <property name="spacing">
+       <number>0</number>
+      </property>
+      <property name="leftMargin">
+       <number>0</number>
+      </property>
+      <property name="topMargin">
+       <number>0</number>
+      </property>
+      <property name="rightMargin">
+       <number>0</number>
+      </property>
+      <property name="bottomMargin">
+       <number>0</number>
+      </property>
+     </layout>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>

+ 10 - 0
blastRecord/blastrecordfactory.cpp

@@ -0,0 +1,10 @@
+#include "blastrecordfactory.h"
+
+BlastRecordFactory::BlastRecordFactory()
+{
+
+}
+QWidget *BlastRecordFactory::createPage(QWidget *parent) const
+{
+    return new BlastRecord(parent);
+}

+ 13 - 0
blastRecord/blastrecordfactory.h

@@ -0,0 +1,13 @@
+#ifndef BLASTRECORDFACTORY_H
+#define BLASTRECORDFACTORY_H
+#include "../PageFactory.h"
+#include "blastrecord.h"
+
+class BlastRecordFactory:public PageFactory
+{
+public:
+    BlastRecordFactory();
+    QWidget* createPage(QWidget* parent) const override;
+};
+
+#endif // BLASTRECORDFACTORY_H

+ 255 - 0
blastRecord/hblastrecord.cpp

@@ -0,0 +1,255 @@
+#include "hblastrecord.h"
+
+HBlastRecord::HBlastRecord(QObject *parent) : QObject(parent)
+{
+}
+
+qint64 HBlastRecord::getId() const
+{
+    return id;
+}
+
+void HBlastRecord::setId(qint64 newId)
+{
+    id = newId;
+}
+
+QString HBlastRecord::getUuid() const
+{
+    return uuid;
+}
+
+void HBlastRecord::setUuid(const QString &newUuid)
+{
+    uuid = newUuid;
+}
+
+QString HBlastRecord::getProjectName() const
+{
+    return projectName;
+}
+
+void HBlastRecord::setProjectName(const QString &newProjectName)
+{
+    projectName = newProjectName;
+}
+
+QString HBlastRecord::getProjectHtid() const
+{
+    return projectHtid;
+}
+
+void HBlastRecord::setProjectHtid(const QString &newProjectHtid)
+{
+    projectHtid = newProjectHtid;
+}
+
+QString HBlastRecord::getProjectXmbh() const
+{
+    return projectXmbh;
+}
+
+void HBlastRecord::setProjectXmbh(const QString &newProjectXmbh)
+{
+    projectXmbh = newProjectXmbh;
+}
+
+QString HBlastRecord::getOperatorName() const
+{
+    return operatorName;
+}
+
+void HBlastRecord::setOperatorName(const QString &newOperatorName)
+{
+    operatorName = newOperatorName;
+}
+
+QString HBlastRecord::getPhone() const
+{
+    return phone;
+}
+
+void HBlastRecord::setPhone(const QString &newPhone)
+{
+    phone = newPhone;
+}
+
+QString HBlastRecord::getOperatorIdentity() const
+{
+    return operatorIdentity;
+}
+
+void HBlastRecord::setOperatorIdentity(const QString &newOperatorIdentity)
+{
+    operatorIdentity = newOperatorIdentity;
+}
+
+QString HBlastRecord::getEquipmentSn() const
+{
+    return equipmentSn;
+}
+
+void HBlastRecord::setEquipmentSn(const QString &newEquipmentSn)
+{
+    equipmentSn = newEquipmentSn;
+}
+
+QString HBlastRecord::getCompanyCode() const
+{
+    return companyCode;
+}
+
+void HBlastRecord::setCompanyCode(const QString &newCompanyCode)
+{
+    companyCode = newCompanyCode;
+}
+
+QString HBlastRecord::getAppVersion() const
+{
+    return appVersion;
+}
+
+void HBlastRecord::setAppVersion(const QString &newAppVersion)
+{
+    appVersion = newAppVersion;
+}
+
+QString HBlastRecord::getLongitude() const
+{
+    return longitude;
+}
+
+void HBlastRecord::setLongitude(const QString &newLongitude)
+{
+    longitude = newLongitude;
+}
+
+QString HBlastRecord::getLatitude() const
+{
+    return latitude;
+}
+
+void HBlastRecord::setLatitude(const QString &newLatitude)
+{
+    latitude = newLatitude;
+}
+
+int HBlastRecord::getEquipmentCount() const
+{
+    return equipmentCount;
+}
+
+void HBlastRecord::setEquipmentCount(int newEquipmentCount)
+{
+    equipmentCount = newEquipmentCount;
+}
+
+int HBlastRecord::getRegDetCount() const
+{
+    return regDetCount;
+}
+
+void HBlastRecord::setRegDetCount(int newRegDetCount)
+{
+    regDetCount = newRegDetCount;
+}
+
+int HBlastRecord::getErrorDetCount() const
+{
+    return errorDetCount;
+}
+
+void HBlastRecord::setErrorDetCount(int newErrorDetCount)
+{
+    errorDetCount = newErrorDetCount;
+}
+
+QDateTime HBlastRecord::getBlastAt() const
+{
+    return blastAt;
+}
+
+void HBlastRecord::setBlastAt(const QDateTime &newBlastAt)
+{
+    blastAt = newBlastAt;
+}
+
+QDateTime HBlastRecord::getCreatedAt() const
+{
+    return createdAt;
+}
+
+void HBlastRecord::setCreatedAt(const QDateTime &newCreatedAt)
+{
+    createdAt = newCreatedAt;
+}
+
+QDateTime HBlastRecord::getUpdatedAt() const
+{
+    return updatedAt;
+}
+
+void HBlastRecord::setUpdatedAt(const QDateTime &newUpdatedAt)
+{
+    updatedAt = newUpdatedAt;
+}
+
+QDateTime HBlastRecord::getDeletedAt() const
+{
+    return deletedAt;
+}
+
+void HBlastRecord::setDeletedAt(const QDateTime &newDeletedAt)
+{
+    deletedAt = newDeletedAt;
+}
+
+qint64 HBlastRecord::getCreateBy() const
+{
+    return createBy;
+}
+
+void HBlastRecord::setCreateBy(qint64 newCreateBy)
+{
+    createBy = newCreateBy;
+}
+
+qint64 HBlastRecord::getUpdateBy() const
+{
+    return updateBy;
+}
+
+void HBlastRecord::setUpdateBy(qint64 newUpdateBy)
+{
+    updateBy = newUpdateBy;
+}
+
+QByteArray HBlastRecord::BlastRecordToJson(const HBlastRecord& record)
+{
+    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["longitude"] = record.getLongitude();
+    json["latitude"] = record.getLatitude();
+    json["equipment_count"] = record.getEquipmentCount();
+    json["reg_det_count"] = record.getRegDetCount();
+    json["error_det_count"] = record.getErrorDetCount();
+    json["blast_at"] = 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();
+}

+ 202 - 0
blastRecord/hblastrecorddao.cpp

@@ -0,0 +1,202 @@
+#include "hblastrecorddao.h"
+
+HBlastRecordDao::HBlastRecordDao(QSqlDatabase db):database(db)
+{
+
+}
+
+PaginatedHBlastRecordResult HBlastRecordDao::getAllHRecords(int page, int pageSize)
+{
+    QList<QSharedPointer<HBlastRecord>> BlastRecords;
+    QSqlQuery query(database);
+    int offset = (page - 1) * pageSize;
+    query.prepare("SELECT * FROM h_blast_record ORDER BY created_at LIMIT :pageSize OFFSET :offset");
+    query.bindValue(":pageSize", pageSize);
+    query.bindValue(":offset", offset);
+    if (query.exec()) {
+        while (query.next()) {
+            BlastRecords.append(recordToBlastRecord(query.record()));
+        }
+    } else {
+        qWarning() << "Query execution failed: " << query.lastError().text();
+    }
+
+    query.prepare("SELECT COUNT(*) FROM h_blast_record");
+    int totalCount = 0;
+    if (query.exec() && query.next()) {
+        totalCount = query.value(0).toInt();
+    }
+    return { BlastRecords, totalCount };
+}
+bool HBlastRecordDao::addHBlastRecord(const HBlastRecord& record)
+{
+
+    QSqlQuery query;
+    query.prepare("INSERT INTO h_blast_record (uuid, project_name, project_htid, project_xmbh, operator_name, phone, operator_identity, equipment_sn, company_code, app_version, longitude, latitude, equipment_count, reg_det_count, error_det_count, blast_at, created_at, updated_at, deleted_at, create_by, update_by) "
+                  "VALUES (:uuid, :project_name, :project_htid, :project_xmbh, :operator_name, :phone, :operator_identity, :equipment_sn, :company_code, :app_version, :longitude, :latitude, :equipment_count, :reg_det_count, :error_det_count, :blast_at, :created_at, :updated_at, :deleted_at, :create_by, :update_by)");
+    query.bindValue(":uuid", record.getUuid());
+    query.bindValue(":project_name", record.getProjectName());
+    query.bindValue(":project_htid", record.getProjectHtid());
+    query.bindValue(":project_xmbh", record.getProjectXmbh());
+    query.bindValue(":operator_name", record.getOperatorName());
+    query.bindValue(":phone", record.getPhone());
+    query.bindValue(":operator_identity", record.getOperatorIdentity());
+    query.bindValue(":equipment_sn", record.getEquipmentSn());
+    query.bindValue(":company_code", record.getCompanyCode());
+    query.bindValue(":app_version", record.getAppVersion());
+    query.bindValue(":longitude", record.getLongitude());
+    query.bindValue(":latitude", record.getLatitude());
+    query.bindValue(":equipment_count", record.getEquipmentCount());
+    query.bindValue(":reg_det_count", record.getRegDetCount());
+    query.bindValue(":error_det_count", record.getErrorDetCount());
+    query.bindValue(":blast_at", record.getBlastAt());
+    query.bindValue(":created_at", record.getCreatedAt().toString(Qt::ISODateWithMs));
+    query.bindValue(":create_by", record.getCreateBy());
+    qDebug() << "created_at:" << record.getCreatedAt();
+    if (query.exec()) {
+        return true;
+
+    } else {
+
+        return false;
+    }
+}
+
+// HBlastRecord HBlastRecordDao::getById(qint64 id)
+// {
+//     HBlastRecord record;
+//     if (!db.isOpen()) {
+//         return record;
+//     }
+
+//     QSqlQuery query(db);
+//     query.prepare("SELECT * FROM h_blast_record WHERE id = :id");
+//     query.bindValue(":id", id);
+
+//     if (query.exec() && query.next()) {
+//         record.setId(query.value("id").toLongLong());
+//         record.setUuid(query.value("uuid").toString());
+//         record.setProjectName(query.value("project_name").toString());
+//         record.setProjectHtid(query.value("project_htid").toString());
+//         record.setProjectXmbh(query.value("project_xmbh").toString());
+//         record.setOperatorName(query.value("operator_name").toString());
+//         record.setPhone(query.value("phone").toString());
+//         record.setOperatorIdentity(query.value("operator_identity").toString());
+//         record.setEquipmentSn(query.value("equipment_sn").toString());
+//         record.setCompanyCode(query.value("company_code").toString());
+//         record.setAppVersion(query.value("app_version").toString());
+//         record.setLongitude(query.value("longitude").toDouble());
+//         record.setLatitude(query.value("latitude").toDouble());
+//         record.setEquipmentCount(query.value("equipment_count").toInt());
+//         record.setRegDetCount(query.value("reg_det_count").toInt());
+//         record.setErrorDetCount(query.value("error_det_count").toInt());
+//         record.setBlastAt(query.value("blast_at").toDateTime());
+//         record.setCreatedAt(query.value("created_at").toDateTime());
+//         record.setUpdatedAt(query.value("updated_at").toDateTime());
+//         record.setDeletedAt(query.value("deleted_at").toDateTime());
+//         record.setCreateBy(query.value("create_by").toLongLong());
+//         record.setUpdateBy(query.value("update_by").toLongLong());
+//     }
+
+//     return record;
+// }
+
+bool HBlastRecordDao::updateHBlastRecord(const HBlastRecord& record)
+{
+
+    QSqlQuery query;
+    query.prepare("UPDATE h_blast_record SET uuid = :uuid,"
+                  " project_name = :project_name, "
+                  "project_htid = :project_htid,"
+                  "project_xmbh = :project_xmbh,"
+                  "operator_name = :operator_name,"
+                  "phone = :phone,"
+                  "operator_identity = :operator_identity,"
+                  "equipment_sn = :equipment_sn,"
+                  "company_code = :company_code,"
+                  " app_version = :app_version,"
+                  "longitude = :longitude,"
+                  "latitude = :latitude,"
+                  "equipment_count = :equipment_count,"
+                  "reg_det_count = :reg_det_count,"
+                  "error_det_count = :error_det_count,"
+                  "blast_at = :blast_at,"
+                  "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());
+    query.bindValue(":project_name", record.getProjectName());
+    query.bindValue(":project_htid", record.getProjectHtid());
+    query.bindValue(":project_xmbh", record.getProjectXmbh());
+    query.bindValue(":operator_name", record.getOperatorName());
+    query.bindValue(":phone", record.getPhone());
+    query.bindValue(":operator_identity", record.getOperatorIdentity());
+    query.bindValue(":equipment_sn", record.getEquipmentSn());
+    query.bindValue(":company_code", record.getCompanyCode());
+    query.bindValue(":app_version", record.getAppVersion());
+    query.bindValue(":longitude", record.getLongitude());
+    query.bindValue(":latitude", record.getLatitude());
+    query.bindValue(":equipment_count", record.getEquipmentCount());
+    query.bindValue(":reg_det_count", record.getRegDetCount());
+    query.bindValue(":error_det_count", record.getErrorDetCount());
+    query.bindValue(":blast_at", record.getBlastAt());
+    query.bindValue(":created_at", record.getCreatedAt());
+    query.bindValue(":updated_at", record.getUpdatedAt());
+    query.bindValue(":deleted_at", record.getDeletedAt());
+    query.bindValue(":create_by", record.getCreateBy());
+    query.bindValue(":update_by", record.getUpdateBy());
+
+    if (query.exec()) {
+        return true;
+    } else {
+        qDebug() << "Failed to update record:" << query.lastError().text();
+        return false;
+    }
+}
+
+bool HBlastRecordDao::deleteHBlastRecord(const HBlastRecord& record)
+{
+    QSqlQuery query;
+    query.prepare("DELETE FROM h_blast_record WHERE id = :id");
+    query.bindValue(":id", record.getId());
+
+    if (query.exec()) {
+        return true;
+    } else {
+        qDebug() << "Failed to delete record:" << query.lastError().text();
+        return false;
+    }
+}
+
+QSharedPointer<HBlastRecord> HBlastRecordDao::recordToBlastRecord(const QSqlRecord &record)
+{
+    QSharedPointer<HBlastRecord> blastRecord = QSharedPointer<HBlastRecord>::create();
+    blastRecord->setId(record.value("id").toLongLong());
+    blastRecord->setUuid(record.value("uuid").toString());
+    blastRecord->setProjectName(record.value("project_name").toString());
+    blastRecord->setProjectHtid(record.value("project_htid").toString());
+    blastRecord->setProjectXmbh(record.value("project_xmbh").toString());
+    blastRecord->setOperatorName(record.value("operator_name").toString());
+    blastRecord->setPhone(record.value("phone").toString());
+    blastRecord->setOperatorIdentity(record.value("operator_identity").toString());
+    blastRecord->setEquipmentSn(record.value("equipment_sn").toString());
+    blastRecord->setCompanyCode(record.value("company_code").toString());
+    blastRecord->setAppVersion(record.value("app_version").toString());
+    blastRecord->setLongitude(record.value("longitude").toString());
+    blastRecord->setLatitude(record.value("latitude").toString());
+    blastRecord->setEquipmentCount(record.value("equipment_count").toInt());
+    blastRecord->setRegDetCount(record.value("reg_det_count").toInt());
+    blastRecord->setErrorDetCount(record.value("error_det_count").toInt());
+    blastRecord->setBlastAt(QDateTime::fromString(record.value("blast_at").toString(), Qt::ISODateWithMs));
+    blastRecord->setCreatedAt(QDateTime::fromString(record.value("created_at").toString(), Qt::ISODateWithMs));
+    blastRecord->setUpdatedAt(QDateTime::fromString(record.value("updated_at").toString(), Qt::ISODateWithMs));
+    blastRecord->setDeletedAt(QDateTime::fromString(record.value("deleted_at").toString(), Qt::ISODateWithMs));
+    blastRecord->setCreateBy(record.value("create_by").toLongLong());
+    blastRecord->setUpdateBy(record.value("update_by").toLongLong());
+    return blastRecord;
+
+}

+ 32 - 0
blastRecord/hblastrecorddao.h

@@ -0,0 +1,32 @@
+#ifndef HBLASTRECORDDAO_H
+#define HBLASTRECORDDAO_H
+#include "HBlastRecord.h"
+#include <QSqlDatabase>
+#include <QSqlQuery>
+#include <QSqlError>
+#include <QSqlRecord>
+#include <QList>
+#include <QDebug>
+
+
+struct PaginatedHBlastRecordResult {
+    QList<QSharedPointer<HBlastRecord>> BlastRecords;
+    int totalCount;
+};
+
+class HBlastRecordDao
+{
+public:
+    HBlastRecordDao(QSqlDatabase db);
+    // HBlastRecord getById(qint64 id);
+    bool deleteHBlastRecord(const HBlastRecord &record);
+    bool updateHBlastRecord(const HBlastRecord &record);
+    bool addHBlastRecord(const HBlastRecord &record);
+    PaginatedHBlastRecordResult getAllHRecords(int page, int pageSize);
+private:
+    QSqlDatabase database;
+    // 将QSqlRecord转换为HBlastRecord对象
+    QSharedPointer<HBlastRecord> recordToBlastRecord(const QSqlRecord &record);
+};
+
+#endif // HBLASTRECORDDAO_H

+ 190 - 0
blastRecord/hblastrecorddet.cpp

@@ -0,0 +1,190 @@
+#include "hblastrecorddet.h"
+
+HBlastRecordDet::HBlastRecordDet(QObject *parent) : QObject(parent)
+{
+    // 可以在这里进行一些初始化操作
+}
+
+qint64 HBlastRecordDet::getId() const
+{
+    return id;
+}
+
+void HBlastRecordDet::setId(qint64 newId)
+{
+    id = newId;
+}
+
+QString HBlastRecordDet::getUuid() const
+{
+    return uuid;
+}
+
+void HBlastRecordDet::setUuid(const QString &newUuid)
+{
+    uuid = newUuid;
+}
+
+QString HBlastRecordDet::getOutCode() const
+{
+    return outCode;
+}
+
+void HBlastRecordDet::setOutCode(const QString &newOutCode)
+{
+    outCode = newOutCode;
+}
+
+QString HBlastRecordDet::getInnerCode() const
+{
+    return innerCode;
+}
+
+void HBlastRecordDet::setInnerCode(const QString &newInnerCode)
+{
+    innerCode = newInnerCode;
+}
+
+QString HBlastRecordDet::getUid() const
+{
+    return uid;
+}
+
+void HBlastRecordDet::setUid(const QString &newUid)
+{
+    uid = newUid;
+}
+
+QString HBlastRecordDet::getStatus() const
+{
+    return status;
+}
+
+void HBlastRecordDet::setStatus(const QString &newStatus)
+{
+    status = newStatus;
+}
+
+QString HBlastRecordDet::getFreq() const
+{
+    return freq;
+}
+
+void HBlastRecordDet::setFreq(const QString &newFreq)
+{
+    freq = newFreq;
+}
+
+QString HBlastRecordDet::getDelayTime() const
+{
+    return delayTime;
+}
+
+void HBlastRecordDet::setDelayTime(const QString &newDelayTime)
+{
+    delayTime = newDelayTime;
+}
+
+QString HBlastRecordDet::getTag() const
+{
+    return tag;
+}
+
+void HBlastRecordDet::setTag(const QString &newTag)
+{
+    tag = newTag;
+}
+
+int HBlastRecordDet::getBlastRecordId() const
+{
+    return blastRecordId;
+}
+
+void HBlastRecordDet::setBlastRecordId(int newBlastRecordId)
+{
+    blastRecordId = newBlastRecordId;
+}
+
+int HBlastRecordDet::getRegId() const
+{
+    return regId;
+}
+
+void HBlastRecordDet::setRegId(int newRegId)
+{
+    regId = newRegId;
+}
+
+QDateTime HBlastRecordDet::getCreatedAt() const
+{
+    return createdAt;
+}
+
+void HBlastRecordDet::setCreatedAt(const QDateTime &newCreatedAt)
+{
+    createdAt = newCreatedAt;
+}
+
+QDateTime HBlastRecordDet::getUpdatedAt() const
+{
+    return updatedAt;
+}
+
+void HBlastRecordDet::setUpdatedAt(const QDateTime &newUpdatedAt)
+{
+    updatedAt = newUpdatedAt;
+}
+
+QDateTime HBlastRecordDet::getDeletedAt() const
+{
+    return deletedAt;
+}
+
+void HBlastRecordDet::setDeletedAt(const QDateTime &newDeletedAt)
+{
+    deletedAt = newDeletedAt;
+}
+
+qint64 HBlastRecordDet::getCreateBy() const
+{
+    return createBy;
+}
+
+void HBlastRecordDet::setCreateBy(qint64 newCreateBy)
+{
+    createBy = newCreateBy;
+}
+
+qint64 HBlastRecordDet::getUpdateBy() const
+{
+    return updateBy;
+}
+
+void HBlastRecordDet::setUpdateBy(qint64 newUpdateBy)
+{
+    updateBy = newUpdateBy;
+}
+
+QByteArray HBlastRecordDet::BlastRecordDetToJson(const HBlastRecordDet& recordDet)
+{
+    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();
+}

+ 102 - 0
blastRecord/hblastrecorddet.h

@@ -0,0 +1,102 @@
+#ifndef HBLASTRECORDDET_H
+#define HBLASTRECORDDET_H
+#include <QString>
+#include <QDateTime>
+#include <QJsonObject>
+#include <QJsonDocument>
+#include <QUuid>
+
+class HBlastRecordDet : public QObject
+{
+    Q_OBJECT
+    // 定义属性
+    Q_PROPERTY(qint64 id READ getId WRITE setId)
+    Q_PROPERTY(QString uuid READ getUuid WRITE setUuid)
+    Q_PROPERTY(QString outCode READ getOutCode WRITE setOutCode)
+    Q_PROPERTY(QString innerCode READ getInnerCode WRITE setInnerCode)
+    Q_PROPERTY(QString uid READ getUid WRITE setUid)
+    Q_PROPERTY(QString status READ getStatus WRITE setStatus)
+    Q_PROPERTY(QString freq READ getFreq WRITE setFreq)
+    Q_PROPERTY(QString delayTime READ getDelayTime WRITE setDelayTime)
+    Q_PROPERTY(QString tag READ getTag WRITE setTag)
+    Q_PROPERTY(int blastRecordId READ getBlastRecordId WRITE setBlastRecordId)
+    Q_PROPERTY(int regId READ getRegId WRITE setRegId)
+    Q_PROPERTY(QDateTime createdAt READ getCreatedAt WRITE setCreatedAt)
+    Q_PROPERTY(QDateTime updatedAt READ getUpdatedAt WRITE setUpdatedAt)
+    Q_PROPERTY(QDateTime deletedAt READ getDeletedAt WRITE setDeletedAt)
+    Q_PROPERTY(qint64 createBy READ getCreateBy WRITE setCreateBy)
+    Q_PROPERTY(qint64 updateBy READ getUpdateBy WRITE setUpdateBy)
+public:
+    explicit HBlastRecordDet(QObject *parent = nullptr);
+
+       // Getter and Setter methods
+    qint64 getId() const;
+    void setId(qint64 newId);
+
+    QString getUuid() const;
+    void setUuid(const QString &newUuid);
+
+    QString getOutCode() const;
+    void setOutCode(const QString &newOutCode);
+
+    QString getInnerCode() const;
+    void setInnerCode(const QString &newInnerCode);
+
+    QString getUid() const;
+    void setUid(const QString &newUid);
+
+    QString getStatus() const;
+    void setStatus(const QString &newStatus);
+
+    QString getFreq() const;
+    void setFreq(const QString &newFreq);
+
+    QString getDelayTime() const;
+    void setDelayTime(const QString &newDelayTime);
+
+    QString getTag() const;
+    void setTag(const QString &newTag);
+
+    int getBlastRecordId() const;
+    void setBlastRecordId(int newBlastRecordId);
+
+    int getRegId() const;
+    void setRegId(int newRegId);
+
+    QDateTime getCreatedAt() const;
+    void setCreatedAt(const QDateTime &newCreatedAt);
+
+    QDateTime getUpdatedAt() const;
+    void setUpdatedAt(const QDateTime &newUpdatedAt);
+
+    QDateTime getDeletedAt() const;
+    void setDeletedAt(const QDateTime &newDeletedAt);
+
+    qint64 getCreateBy() const;
+    void setCreateBy(qint64 newCreateBy);
+
+    qint64 getUpdateBy() const;
+    void setUpdateBy(qint64 newUpdateBy);
+
+    QByteArray BlastRecordDetToJson(const HBlastRecordDet& recordDet);
+
+private:
+    qint64 id;
+    QString uuid;
+    QString outCode;
+    QString innerCode;
+    QString uid;
+    QString status;
+    QString freq;
+    QString delayTime;
+    QString tag;
+    int blastRecordId;
+    int regId;
+    QDateTime createdAt;
+    QDateTime updatedAt;
+    QDateTime deletedAt;
+    qint64 createBy;
+    qint64 updateBy;
+};
+
+#endif // HBLASTRECORDDET_H

+ 103 - 0
blastRecordDet/HBlastRecordDet.h

@@ -0,0 +1,103 @@
+#ifndef HBLASTRECORDDET_H
+#define HBLASTRECORDDET_H
+
+#include <QString>
+#include <QDateTime>
+#include <QJsonObject>
+#include <QJsonDocument>
+#include <QUuid>
+class HBlastRecordDet : public QObject
+{
+    Q_OBJECT
+    // 定义属性
+    Q_PROPERTY(qint64 id READ getId WRITE setId)
+    Q_PROPERTY(QString uuid READ getUuid WRITE setUuid)
+    Q_PROPERTY(QString outCode READ getOutCode WRITE setOutCode)
+    Q_PROPERTY(QString innerCode READ getInnerCode WRITE setInnerCode)
+    Q_PROPERTY(QString uid READ getUid WRITE setUid)
+    Q_PROPERTY(QString status READ getStatus WRITE setStatus)
+    Q_PROPERTY(QString freq READ getFreq WRITE setFreq)
+    Q_PROPERTY(QString delayTime READ getDelayTime WRITE setDelayTime)
+    Q_PROPERTY(QString tag READ getTag WRITE setTag)
+    Q_PROPERTY(QString blastRecordId READ getBlastRecordId WRITE setBlastRecordId)
+    Q_PROPERTY(QString regId READ getRegId WRITE setRegId)
+    Q_PROPERTY(QDateTime createdAt READ getCreatedAt WRITE setCreatedAt)
+    Q_PROPERTY(QDateTime updatedAt READ getUpdatedAt WRITE setUpdatedAt)
+    Q_PROPERTY(QDateTime deletedAt READ getDeletedAt WRITE setDeletedAt)
+    Q_PROPERTY(qint64 createBy READ getCreateBy WRITE setCreateBy)
+    Q_PROPERTY(qint64 updateBy READ getUpdateBy WRITE setUpdateBy)
+public:
+    explicit HBlastRecordDet(QObject *parent = nullptr);
+
+       // Getter and Setter methods
+    qint64 getId() const;
+    void setId(qint64 newId);
+
+    QString getUuid() const;
+    void setUuid(const QString &newUuid);
+
+    QString getOutCode() const;
+    void setOutCode(const QString &newOutCode);
+
+    QString getInnerCode() const;
+    void setInnerCode(const QString &newInnerCode);
+
+    QString getUid() const;
+    void setUid(const QString &newUid);
+
+    QString getStatus() const;
+    void setStatus(const QString &newStatus);
+
+    QString getFreq() const;
+    void setFreq(const QString &newFreq);
+
+    QString getDelayTime() const;
+    void setDelayTime(const QString &newDelayTime);
+
+    QString getTag() const;
+    void setTag(const QString &newTag);
+
+    QString getBlastRecordId() const;
+    void setBlastRecordId(QString newBlastRecordId);
+
+    QString getRegId() const;
+    void setRegId(QString newRegId);
+
+    QDateTime getCreatedAt() const;
+    void setCreatedAt(const QDateTime &newCreatedAt);
+
+    QDateTime getUpdatedAt() const;
+    void setUpdatedAt(const QDateTime &newUpdatedAt);
+
+    QDateTime getDeletedAt() const;
+    void setDeletedAt(const QDateTime &newDeletedAt);
+
+    qint64 getCreateBy() const;
+    void setCreateBy(qint64 newCreateBy);
+
+    qint64 getUpdateBy() const;
+    void setUpdateBy(qint64 newUpdateBy);
+
+    QByteArray BlastRecordDetToJson(const HBlastRecordDet& recordDet);
+
+private:
+    qint64 id;
+    QString uuid;
+    QString outCode;
+    QString innerCode;
+    QString uid;
+    QString status;
+    QString freq;
+    QString delayTime;
+    QString tag;
+    QString blastRecordId;
+    QString regId;
+    QDateTime createdAt;
+    QDateTime updatedAt;
+    QDateTime deletedAt;
+    qint64 createBy;
+    qint64 updateBy;
+
+};
+
+#endif // HBLASTRECORDDET_H

+ 191 - 0
blastRecordDet/hblastrecorddet.cpp

@@ -0,0 +1,191 @@
+#include "hblastrecorddet.h"
+
+HBlastRecordDet::HBlastRecordDet(QObject *parent) : QObject(parent)
+{
+    // 可以在这里进行一些初始化操作
+}
+
+qint64 HBlastRecordDet::getId() const
+{
+    return id;
+}
+
+void HBlastRecordDet::setId(qint64 newId)
+{
+    id = newId;
+}
+
+QString HBlastRecordDet::getUuid() const
+{
+    return uuid;
+}
+
+void HBlastRecordDet::setUuid(const QString &newUuid)
+{
+    uuid = newUuid;
+}
+
+QString HBlastRecordDet::getOutCode() const
+{
+    return outCode;
+}
+
+void HBlastRecordDet::setOutCode(const QString &newOutCode)
+{
+    outCode = newOutCode;
+}
+
+QString HBlastRecordDet::getInnerCode() const
+{
+    return innerCode;
+}
+
+void HBlastRecordDet::setInnerCode(const QString &newInnerCode)
+{
+    innerCode = newInnerCode;
+}
+
+QString HBlastRecordDet::getUid() const
+{
+    return uid;
+}
+
+void HBlastRecordDet::setUid(const QString &newUid)
+{
+    uid = newUid;
+}
+
+QString HBlastRecordDet::getStatus() const
+{
+    return status;
+}
+
+void HBlastRecordDet::setStatus(const QString &newStatus)
+{
+    status = newStatus;
+}
+
+QString HBlastRecordDet::getFreq() const
+{
+    return freq;
+}
+
+void HBlastRecordDet::setFreq(const QString &newFreq)
+{
+    freq = newFreq;
+}
+
+QString HBlastRecordDet::getDelayTime() const
+{
+    return delayTime;
+}
+
+void HBlastRecordDet::setDelayTime(const QString &newDelayTime)
+{
+    delayTime = newDelayTime;
+}
+
+QString HBlastRecordDet::getTag() const
+{
+    return tag;
+}
+
+void HBlastRecordDet::setTag(const QString &newTag)
+{
+    tag = newTag;
+}
+
+QString HBlastRecordDet::getBlastRecordId() const
+{
+    return blastRecordId;
+}
+
+void HBlastRecordDet::setBlastRecordId(QString newBlastRecordId)
+{
+    blastRecordId = newBlastRecordId;
+}
+
+QString HBlastRecordDet::getRegId() const
+{
+    return regId;
+}
+
+void HBlastRecordDet::setRegId(QString newRegId)
+{
+    regId = newRegId;
+}
+
+QDateTime HBlastRecordDet::getCreatedAt() const
+{
+    return createdAt;
+}
+
+void HBlastRecordDet::setCreatedAt(const QDateTime &newCreatedAt)
+{
+    createdAt = newCreatedAt;
+}
+
+QDateTime HBlastRecordDet::getUpdatedAt() const
+{
+    return updatedAt;
+}
+
+void HBlastRecordDet::setUpdatedAt(const QDateTime &newUpdatedAt)
+{
+    updatedAt = newUpdatedAt;
+}
+
+QDateTime HBlastRecordDet::getDeletedAt() const
+{
+    return deletedAt;
+}
+
+void HBlastRecordDet::setDeletedAt(const QDateTime &newDeletedAt)
+{
+    deletedAt = newDeletedAt;
+}
+
+qint64 HBlastRecordDet::getCreateBy() const
+{
+    return createBy;
+}
+
+void HBlastRecordDet::setCreateBy(qint64 newCreateBy)
+{
+    createBy = newCreateBy;
+}
+
+qint64 HBlastRecordDet::getUpdateBy() const
+{
+    return updateBy;
+}
+
+void HBlastRecordDet::setUpdateBy(qint64 newUpdateBy)
+{
+    updateBy = newUpdateBy;
+}
+
+QByteArray HBlastRecordDet::BlastRecordDetToJson(const HBlastRecordDet& recordDet)
+{
+    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();
+
+}

+ 110 - 0
blastRecordDet/hblastrecorddetdao.cpp

@@ -0,0 +1,110 @@
+#include "hblastrecorddetdao.h"
+
+HBlastRecordDetDao::HBlastRecordDetDao(QSqlDatabase db):database(db)
+{
+
+}
+
+
+bool HBlastRecordDetDao::addHBlastRecordDet(const HBlastRecordDet& recordDet)
+{
+    QSqlQuery query;
+    query.prepare("INSERT INTO h_blast_record_det (id, uuid, out_code, inner_code, uid, status, freq, delay_time, tag, blast_record_id, reg_id, created_at, updated_at, deleted_at, create_by, update_by) "
+                  "VALUES (:id, :uuid, :outCode, :innerCode, :uid, :status, :freq, :delayTime, :tag, :blastRecordId, :regId, :createdAt, :updatedAt, :deletedAt, :createBy, :updateBy)");
+    query.bindValue(":id", recordDet.getId());
+    query.bindValue(":uuid", recordDet.getUuid());
+    query.bindValue(":outCode", recordDet.getOutCode());
+    query.bindValue(":innerCode", recordDet.getInnerCode());
+    query.bindValue(":uid", recordDet.getUid());
+    query.bindValue(":status", recordDet.getStatus());
+    query.bindValue(":freq", recordDet.getFreq());
+    query.bindValue(":delayTime", recordDet.getDelayTime());
+    query.bindValue(":tag", recordDet.getTag());
+    query.bindValue(":blastRecordId", recordDet.getBlastRecordId());
+    query.bindValue(":regId", recordDet.getRegId());
+    query.bindValue(":createdAt", recordDet.getCreatedAt());
+    query.bindValue(":updatedAt", recordDet.getUpdatedAt());
+    query.bindValue(":deletedAt", recordDet.getDeletedAt());
+    query.bindValue(":createBy", recordDet.getCreateBy());
+    query.bindValue(":updateBy", recordDet.getUpdateBy());
+
+    if (query.exec()) {
+        return true;
+    } else {
+        qDebug() << "Insert failed:" << query.lastError().text();
+        return false;
+    }
+}
+
+// HBlastRecordDet HBlastRecordDetDao::getById(qint64 id)
+// {
+//     HBlastRecordDet recordDet;
+//     QSqlQuery query(db);
+//     query.prepare("SELECT * FROM HBlastRecordDet WHERE id = :id");
+//     query.bindValue(":id", id);
+
+//     if (query.exec() && query.next()) {
+//         recordDet.setId(query.value("id").toLongLong());
+//         recordDet.setUuid(query.value("uuid").toString());
+//         recordDet.setOutCode(query.value("outCode").toString());
+//         recordDet.setInnerCode(query.value("innerCode").toString());
+//         recordDet.setUid(query.value("uid").toString());
+//         recordDet.setStatus(query.value("status").toString());
+//         recordDet.setFreq(query.value("freq").toString());
+//         recordDet.setDelayTime(query.value("delayTime").toString());
+//         recordDet.setTag(query.value("tag").toString());
+//         recordDet.setBlastRecordId(query.value("blastRecordId").toInt());
+//         recordDet.setRegId(query.value("regId").toInt());
+//         recordDet.setCreatedAt(query.value("createdAt").toDateTime());
+//         recordDet.setUpdatedAt(query.value("updatedAt").toDateTime());
+//         recordDet.setDeletedAt(query.value("deletedAt").toDateTime());
+//         recordDet.setCreateBy(query.value("createBy").toLongLong());
+//         recordDet.setUpdateBy(query.value("updateBy").toLongLong());
+//     }
+
+//     return recordDet;
+// }
+
+bool HBlastRecordDetDao::updateHBlastRecordDet(const HBlastRecordDet& recordDet)
+{
+    QSqlQuery query;
+    query.prepare("UPDATE HBlastRecordDet SET uuid = :uuid, outCode = :outCode, innerCode = :innerCode, uid = :uid, status = :status, freq = :freq, delayTime = :delayTime, tag = :tag, blastRecordId = :blastRecordId, regId = :regId, createdAt = :createdAt, updatedAt = :updatedAt, deletedAt = :deletedAt, createBy = :createBy, updateBy = :updateBy "
+                  "WHERE id = :id");
+    query.bindValue(":id", recordDet.getId());
+    query.bindValue(":uuid", recordDet.getUuid());
+    query.bindValue(":outCode", recordDet.getOutCode());
+    query.bindValue(":innerCode", recordDet.getInnerCode());
+    query.bindValue(":uid", recordDet.getUid());
+    query.bindValue(":status", recordDet.getStatus());
+    query.bindValue(":freq", recordDet.getFreq());
+    query.bindValue(":delayTime", recordDet.getDelayTime());
+    query.bindValue(":tag", recordDet.getTag());
+    query.bindValue(":blastRecordId", recordDet.getBlastRecordId());
+    query.bindValue(":regId", recordDet.getRegId());
+    query.bindValue(":createdAt", recordDet.getCreatedAt());
+    query.bindValue(":updatedAt", recordDet.getUpdatedAt());
+    query.bindValue(":deletedAt", recordDet.getDeletedAt());
+    query.bindValue(":createBy", recordDet.getCreateBy());
+    query.bindValue(":updateBy", recordDet.getUpdateBy());
+
+    if (query.exec()) {
+        return true;
+    } else {
+        qDebug() << "Update failed:" << query.lastError().text();
+        return false;
+    }
+}
+
+// bool HBlastRecordDetDao::deleteById(qint64 id)
+// {
+//     QSqlQuery query(db);
+//     query.prepare("DELETE FROM HBlastRecordDet WHERE id = :id");
+//     query.bindValue(":id", id);
+
+//     if (query.exec()) {
+//         return true;
+//     } else {
+//         qDebug() << "Delete failed:" << query.lastError().text();
+//         return false;
+//     }
+// }

+ 25 - 0
blastRecordDet/hblastrecorddetdao.h

@@ -0,0 +1,25 @@
+#ifndef HBLASTRECORDDETDAO_H
+#define HBLASTRECORDDETDAO_H
+
+#include "HBlastRecordDet.h"
+#include <QSqlDatabase>
+#include <QSqlQuery>
+#include <QSqlError>
+#include <QDebug>
+
+class HBlastRecordDetDao
+{
+public:
+    HBlastRecordDetDao(QSqlDatabase db);
+    HBlastRecordDet getById(qint64 id);
+    bool updateHBlastRecordDet(const HBlastRecordDet &recordDet);
+    bool addHBlastRecordDet(const HBlastRecordDet &recordDet);
+
+private:
+    QSqlDatabase database;
+    // 将QSqlRecord转换为HProject对象
+    // QSharedPointer<HProject> recordToProject(const QSqlRecord &record);
+
+};
+
+#endif // HBLASTRECORDDETDAO_H

+ 223 - 0
blastRegRecord/hblastregrecord.cpp

@@ -0,0 +1,223 @@
+#include "hblastregrecord.h"
+
+HBlastRegRecord::HBlastRegRecord(QObject *parent) : QObject(parent)
+{
+}
+
+
+qint64 HBlastRegRecord::getId() const
+{
+    return id;
+}
+
+void HBlastRegRecord::setId(qint64 newId)
+{
+    id = newId;
+}
+
+QString HBlastRegRecord::getUuid() const
+{
+    return uuid;
+}
+
+void HBlastRegRecord::setUuid(const QString &newUuid)
+{
+    uuid = newUuid;
+}
+
+QString HBlastRegRecord::getEquipSn() const
+{
+    return equipSn;
+}
+
+void HBlastRegRecord::setEquipSn(const QString &newEquipSn)
+{
+    equipSn = newEquipSn;
+}
+
+QString HBlastRegRecord::getEquipVersion() const
+{
+    return equipVersion;
+}
+
+void HBlastRegRecord::setEquipVersion(const QString &newEquipVersion)
+{
+    equipVersion = newEquipVersion;
+}
+
+int HBlastRegRecord::getRegDetoCount() const
+{
+    return regDetoCount;
+}
+
+void HBlastRegRecord::setRegDetoCount(int newRegDetoCount)
+{
+    regDetoCount = newRegDetoCount;
+}
+
+int HBlastRegRecord::getErrorDetoCount() const
+{
+    return errorDetoCount;
+}
+
+void HBlastRegRecord::setErrorDetoCount(int newErrorDetoCount)
+{
+    errorDetoCount = newErrorDetoCount;
+}
+
+QString HBlastRegRecord::getAfterTestBusV() const
+{
+    return afterTestBusV;
+}
+
+void HBlastRegRecord::setAfterTestBusV(const QString &newAfterTestBusV)
+{
+    afterTestBusV = newAfterTestBusV;
+}
+
+QString HBlastRegRecord::getAfterTestBusI() const
+{
+    return afterTestBusI;
+}
+
+void HBlastRegRecord::setAfterTestBusI(const QString &newAfterTestBusI)
+{
+    afterTestBusI = newAfterTestBusI;
+}
+
+QString HBlastRegRecord::getBusLeakageCurrentI() const
+{
+    return busLeakageCurrentI;
+}
+
+void HBlastRegRecord::setBusLeakageCurrentI(const QString &newBusLeakageCurrentI)
+{
+    busLeakageCurrentI = newBusLeakageCurrentI;
+}
+
+QString HBlastRegRecord::getNetChargedV() const
+{
+    return netChargedV;
+}
+
+void HBlastRegRecord::setNetChargedV(const QString &newNetChargedV)
+{
+    netChargedV = newNetChargedV;
+}
+
+QString HBlastRegRecord::getNetChargedI() const
+{
+    return netChargedI;
+}
+
+void HBlastRegRecord::setNetChargedI(const QString &newNetChargedI)
+{
+    netChargedI = newNetChargedI;
+}
+
+QString HBlastRegRecord::getBeforeBlastingV() const
+{
+    return beforeBlastingV;
+}
+
+void HBlastRegRecord::setBeforeBlastingV(const QString &newBeforeBlastingV)
+{
+    beforeBlastingV = newBeforeBlastingV;
+}
+
+QString HBlastRegRecord::getBeforeBlastingI() const
+{
+    return beforeBlastingI;
+}
+
+void HBlastRegRecord::setBeforeBlastingI(const QString &newBeforeBlastingI)
+{
+    beforeBlastingI = newBeforeBlastingI;
+}
+
+QString HBlastRegRecord::getRecordUuid() const
+{
+    return recordUuid;
+}
+
+void HBlastRegRecord::setRecordUuid(const QString &newRecordUuid)
+{
+    recordUuid = newRecordUuid;
+}
+
+QDateTime HBlastRegRecord::getCreatedAt() const
+{
+    return createdAt;
+}
+
+void HBlastRegRecord::setCreatedAt(const QDateTime &newCreatedAt)
+{
+    createdAt = newCreatedAt;
+}
+
+QDateTime HBlastRegRecord::getUpdatedAt() const
+{
+    return updatedAt;
+}
+
+void HBlastRegRecord::setUpdatedAt(const QDateTime &newUpdatedAt)
+{
+    updatedAt = newUpdatedAt;
+}
+
+QDateTime HBlastRegRecord::getDeletedAt() const
+{
+    return deletedAt;
+}
+
+void HBlastRegRecord::setDeletedAt(const QDateTime &newDeletedAt)
+{
+    deletedAt = newDeletedAt;
+}
+
+qint64 HBlastRegRecord::getCreateBy() const
+{
+    return createBy;
+}
+
+void HBlastRegRecord::setCreateBy(qint64 newCreateBy)
+{
+    createBy = newCreateBy;
+}
+
+qint64 HBlastRegRecord::getUpdateBy() const
+{
+    return updateBy;
+}
+
+void HBlastRegRecord::setUpdateBy(qint64 newUpdateBy)
+{
+    updateBy = newUpdateBy;
+}
+
+QByteArray HBlastRegRecord::RecordToJson(const HBlastRegRecord& record)
+{
+    QJsonObject json;
+    json["id"] = record.getId();
+    json["uuid"] = record.getUuid();
+    json["equip_sn"] = record.getEquipSn();
+    json["equip_version"] = record.getEquipVersion();
+    json["reg_deto_count"] = record.getRegDetoCount();
+    json["error_deto_count"] = record.getErrorDetoCount();
+    json["after_test_bus_v"] = record.getAfterTestBusV();
+    json["after_test_bus_i"] = record.getAfterTestBusI();
+    json["bus_leakage_current_i"] = record.getBusLeakageCurrentI();
+    json["net_charged_v"] = record.getNetChargedV();
+    json["net_charged_i"] = record.getNetChargedI();
+    json["before_blasting_v"] = record.getBeforeBlastingV();
+    json["before_blasting_i"] = record.getBeforeBlastingI();
+    json["record_uuid"] = record.getRecordUuid();
+    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();
+}

+ 118 - 0
blastRegRecord/hblastregrecord.h

@@ -0,0 +1,118 @@
+#ifndef HBLASTREGRECORD_H
+#define HBLASTREGRECORD_H
+
+#include <QString>
+#include <QDateTime>
+#include <QJsonObject>
+#include <QJsonDocument>
+#include <QUuid>
+
+class HBlastRegRecord : public QObject
+{
+    Q_OBJECT
+       // 定义属性
+       Q_PROPERTY(qint64 id READ getId WRITE setId)
+       Q_PROPERTY(QString uuid READ getUuid WRITE setUuid)
+       Q_PROPERTY(QString equipSn READ getEquipSn WRITE setEquipSn)
+       Q_PROPERTY(QString equipVersion READ getEquipVersion WRITE setEquipVersion)
+       Q_PROPERTY(int regDetoCount READ getRegDetoCount WRITE setRegDetoCount)
+       Q_PROPERTY(int errorDetoCount READ getErrorDetoCount WRITE setErrorDetoCount)
+       Q_PROPERTY(QString afterTestBusV READ getAfterTestBusV WRITE setAfterTestBusV)
+       Q_PROPERTY(QString afterTestBusI READ getAfterTestBusI WRITE setAfterTestBusI)
+       Q_PROPERTY(QString busLeakageCurrentI READ getBusLeakageCurrentI WRITE setBusLeakageCurrentI)
+       Q_PROPERTY(QString netChargedV READ getNetChargedV WRITE setNetChargedV)
+       Q_PROPERTY(QString netChargedI READ getNetChargedI WRITE setNetChargedI)
+       Q_PROPERTY(QString beforeBlastingV READ getBeforeBlastingV WRITE setBeforeBlastingV)
+       Q_PROPERTY(QString beforeBlastingI READ getBeforeBlastingI WRITE setBeforeBlastingI)
+       Q_PROPERTY(QString recordUuid READ getRecordUuid WRITE setRecordUuid)
+       Q_PROPERTY(QDateTime createdAt READ getCreatedAt WRITE setCreatedAt)
+       Q_PROPERTY(QDateTime updatedAt READ getUpdatedAt WRITE setUpdatedAt)
+       Q_PROPERTY(QDateTime deletedAt READ getDeletedAt WRITE setDeletedAt)
+       Q_PROPERTY(qint64 createBy READ getCreateBy WRITE setCreateBy)
+       Q_PROPERTY(qint64 updateBy READ getUpdateBy WRITE setUpdateBy)
+public:
+    explicit HBlastRegRecord(QObject *parent = nullptr);
+
+    // Getter and Setter methods
+    qint64 getId() const;
+    void setId(qint64 newId);
+
+    QString getUuid() const;
+    void setUuid(const QString &newUuid);
+
+    QString getEquipSn() const;
+    void setEquipSn(const QString &newEquipSn);
+
+    QString getEquipVersion() const;
+    void setEquipVersion(const QString &newEquipVersion);
+
+    int getRegDetoCount() const;
+    void setRegDetoCount(int newRegDetoCount);
+
+    int getErrorDetoCount() const;
+    void setErrorDetoCount(int newErrorDetoCount);
+
+    QString getAfterTestBusV() const;
+    void setAfterTestBusV(const QString &newAfterTestBusV);
+
+    QString getAfterTestBusI() const;
+    void setAfterTestBusI(const QString &newAfterTestBusI);
+
+    QString getBusLeakageCurrentI() const;
+    void setBusLeakageCurrentI(const QString &newBusLeakageCurrentI);
+
+    QString getNetChargedV() const;
+    void setNetChargedV(const QString &newNetChargedV);
+
+    QString getNetChargedI() const;
+    void setNetChargedI(const QString &newNetChargedI);
+
+    QString getBeforeBlastingV() const;
+    void setBeforeBlastingV(const QString &newBeforeBlastingV);
+
+    QString getBeforeBlastingI() const;
+    void setBeforeBlastingI(const QString &newBeforeBlastingI);
+
+    QString getRecordUuid() const;
+    void setRecordUuid(const QString &newRecordUuid);
+
+    QDateTime getCreatedAt() const;
+    void setCreatedAt(const QDateTime &newCreatedAt);
+
+    QDateTime getUpdatedAt() const;
+    void setUpdatedAt(const QDateTime &newUpdatedAt);
+
+    QDateTime getDeletedAt() const;
+    void setDeletedAt(const QDateTime &newDeletedAt);
+
+    qint64 getCreateBy() const;
+    void setCreateBy(qint64 newCreateBy);
+
+    qint64 getUpdateBy() const;
+    void setUpdateBy(qint64 newUpdateBy);
+
+    QByteArray RecordToJson(const HBlastRegRecord& record);
+
+private:
+    qint64 id;
+    QString uuid;
+    QString equipSn;
+    QString equipVersion;
+    int regDetoCount;
+    int errorDetoCount;
+    QString afterTestBusV;
+    QString afterTestBusI;
+    QString busLeakageCurrentI;
+    QString netChargedV;
+    QString netChargedI;
+    QString beforeBlastingV;
+    QString beforeBlastingI;
+    QString recordUuid;
+    QDateTime createdAt;
+    QDateTime updatedAt;
+    QDateTime deletedAt;
+    qint64 createBy;
+    qint64 updateBy;
+};
+
+#endif // HBLASTREGRECORD_H

+ 110 - 0
blastRegRecord/hblastregrecorddao.cpp

@@ -0,0 +1,110 @@
+#include "hblastregrecorddao.h"
+
+HBlastRegRecordDao::HBlastRegRecordDao(QSqlDatabase db) : database(db) {}
+
+bool HBlastRegRecordDao::addHBlastRegRecord(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) "
+                  "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());
+    query.bindValue(":equip_version", record.getEquipVersion());
+    query.bindValue(":reg_deto_count", record.getRegDetoCount());
+    query.bindValue(":error_deto_count", record.getErrorDetoCount());
+    query.bindValue(":after_test_bus_v", record.getAfterTestBusV());
+    query.bindValue(":after_test_bus_i", record.getAfterTestBusI());
+    query.bindValue(":bus_leakage_current_i", record.getBusLeakageCurrentI());
+    query.bindValue(":net_charged_v", record.getNetChargedV());
+    query.bindValue(":net_charged_i", record.getNetChargedI());
+    query.bindValue(":before_blasting_v", record.getBeforeBlastingV());
+    query.bindValue(":before_blasting_i", record.getBeforeBlastingI());
+    query.bindValue(":record_uuid", record.getRecordUuid());
+    query.bindValue(":created_at", record.getCreatedAt());
+    query.bindValue(":updated_at", record.getUpdatedAt());
+    query.bindValue(":deleted_at", record.getDeletedAt());
+    query.bindValue(":create_by", record.getCreateBy());
+    query.bindValue(":update_by", record.getUpdateBy());
+
+    if (query.exec()) {
+        return true;
+    } else {
+        qDebug() << "Insert failed:" << query.lastError().text();
+        return false;
+    }
+}
+
+bool HBlastRegRecordDao::updateHBlastRegRecord(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 "
+                  "WHERE id = :id");
+    query.bindValue(":id", record.getId());
+    query.bindValue(":uuid", record.getUuid());
+    query.bindValue(":equip_sn", record.getEquipSn());
+    query.bindValue(":equip_version", record.getEquipVersion());
+    query.bindValue(":reg_deto_count", record.getRegDetoCount());
+    query.bindValue(":error_deto_count", record.getErrorDetoCount());
+    query.bindValue(":after_test_bus_v", record.getAfterTestBusV());
+    query.bindValue(":after_test_bus_i", record.getAfterTestBusI());
+    query.bindValue(":bus_leakage_current_i", record.getBusLeakageCurrentI());
+    query.bindValue(":net_charged_v", record.getNetChargedV());
+    query.bindValue(":net_charged_i", record.getNetChargedI());
+    query.bindValue(":before_blasting_v", record.getBeforeBlastingV());
+    query.bindValue(":before_blasting_i", record.getBeforeBlastingI());
+    query.bindValue(":record_uuid", record.getRecordUuid());
+    query.bindValue(":created_at", record.getCreatedAt());
+    query.bindValue(":updated_at", record.getUpdatedAt());
+    query.bindValue(":deleted_at", record.getDeletedAt());
+    query.bindValue(":create_by", record.getCreateBy());
+    query.bindValue(":update_by", record.getUpdateBy());
+
+    if (query.exec()) {
+        return true;
+    } else {
+        qDebug() << "Update failed:" << query.lastError().text();
+        return false;
+    }
+}
+
+bool HBlastRegRecordDao::deleteHBlastRegRecord(qint64 id) {
+    QSqlQuery query;
+    query.prepare("DELETE FROM h_blast_reg_record WHERE id = :id");
+    query.bindValue(":id", id);
+
+    if (query.exec()) {
+        return true;
+    } else {
+        qDebug() << "Delete failed:" << query.lastError().text();
+        return false;
+    }
+}
+
+// HBlastRegRecord HBlastRegRecordDao::getHBlastRegRecordById(qint64 id) {
+//     HBlastRegRecord record;
+//     QSqlQuery query;
+//     query.prepare("SELECT * FROM h_blast_reg_record WHERE id = :id");
+//     query.bindValue(":id", id);
+
+//     if (query.exec() && query.next()) {
+//         record.setId(query.value("id").toLongLong());
+//         record.setUuid(query.value("uuid").toString());
+//         record.setEquipSn(query.value("equip_sn").toString());
+//         record.setEquipVersion(query.value("equip_version").toString());
+//         record.setRegDetoCount(query.value("reg_deto_count").toInt());
+//         record.setErrorDetoCount(query.value("error_deto_count").toInt());
+//         record.setAfterTestBusV(query.value("after_test_bus_v").toString());
+//         record.setAfterTestBusI(query.value("after_test_bus_i").toString());
+//         record.setBusLeakageCurrentI(query.value("bus_leakage_current_i").toString());
+//         record.setNetChargedV(query.value("net_charged_v").toString());
+//         record.setNetChargedI(query.value("net_charged_i").toString());
+//         record.setBeforeBlastingV(query.value("before_blasting_v").toString());
+//         record.setBeforeBlastingI(query.value("before_blasting_i").toString());
+//         record.setRecordUuid(query.value("record_uuid").toString());
+//         record.setCreatedAt(query.value("created_at").toDateTime());
+//         record.setUpdatedAt(query.value("updated_at").toDateTime());
+//         record.setDeletedAt(query.value("deleted_at").toDateTime());
+//         record.setCreateBy(query.value("create_by").toLongLong());
+//         record.setUpdateBy(query.value("update_by").toLongLong());
+//     }
+
+//     return record;
+// }

+ 24 - 0
blastRegRecord/hblastregrecorddao.h

@@ -0,0 +1,24 @@
+#ifndef HBLASTREGRECORDDAO_H
+#define HBLASTREGRECORDDAO_H
+
+#include "hblastregrecord.h"
+#include <QSqlDatabase>
+#include <QSqlQuery>
+#include <QSqlError>
+#include <QDebug>
+
+class HBlastRegRecordDao
+{
+public:
+    HBlastRegRecordDao(QSqlDatabase db);
+
+     bool addHBlastRegRecord(const HBlastRegRecord& record);
+     bool updateHBlastRegRecord(const HBlastRegRecord& record);
+     bool deleteHBlastRegRecord(qint64 id);
+     // HBlastRegRecord getHBlastRegRecordById(qint64 id);
+
+ private:
+     QSqlDatabase database;
+};
+
+#endif // HBLASTREGRECORDDAO_H

+ 659 - 0
blastopepage.cpp

@@ -0,0 +1,659 @@
+#include "blastopepage.h"
+#include "ui_blastopepage.h"
+#include "countdownwidget.h"
+#include <QFont>
+
+
+BlastOpePage::BlastOpePage(QWidget *parent) :
+    QWidget(parent),
+    ui(new Ui::BlastOpePage),
+    dao(DatabaseManager::getInstance().getDatabase())
+{
+
+    ui->setupUi(this);
+    initPagination();
+
+
+}
+
+void BlastOpePage::showDownWidget(QString uuid,const QString &topic,const QString &message){
+    CountdownWidget *countdownWidget = new CountdownWidget(this);
+    countdownWidget->resize(200, 200);
+    int x = (this->width() - countdownWidget->width()) / 2;
+    int y = (this->height() - countdownWidget->height()) / 2;
+
+    countdownWidget->move(x, y);
+    countdownWidget->show();
+    firingWidget *widget = uuidWidgetMap.value(uuid);
+
+    if (widget) {
+
+        connect(countdownWidget, &CountdownWidget::countdownFinished, widget,  [widget,topic,message,countdownWidget](){
+
+            widget->onCountdownFinished(topic,message);
+        }, Qt::SingleShotConnection);
+    }
+}
+
+void BlastOpePage::InitFace()
+{
+
+    layout = new QVBoxLayout(this);
+    view = new QWebEngineView(this);
+    view->setAttribute(Qt::WA_OpaquePaintEvent);
+
+    QWebEnginePage *page = view->page();
+
+    QJsonObject metaInfo = getMetaInfo();
+
+    QObject::connect(page, &QWebEnginePage::featurePermissionRequested, [this,page](const QUrl &securityOrigin, QWebEnginePage::Feature feature) {
+        handleFeaturePermission(page, securityOrigin, feature);
+    });
+
+    QUrl postUrl("http://192.168.0.255:8000/api/v1/h-face-verify/pc");
+    QJsonObject response = sendPostRequest(postUrl, metaInfo);
+    QString certifyUrl;
+    if (response.contains("data") && response["data"].isObject()) {
+        QJsonObject dataObject = response["data"].toObject();
+        if (dataObject.contains("ResultObject") && dataObject["ResultObject"].isObject()) {
+            QJsonObject resultObject = dataObject["ResultObject"].toObject();
+            if (resultObject.contains("CertifyId") && resultObject["CertifyId"].isString()) {
+                certifyId= resultObject["CertifyId"].toString();
+            }
+            if (resultObject.contains("CertifyUrl") && resultObject["CertifyUrl"].isString()) {
+                certifyUrl = resultObject["CertifyUrl"].toString();
+            }
+        }
+    }
+    if (!certifyUrl.isEmpty()) {
+
+        view->load(QUrl(certifyUrl));
+
+        layout->addWidget(view);
+
+        layout->setStretchFactor(view, 1);
+
+        QObject::connect(page, &QWebEnginePage::urlChanged, this, &BlastOpePage::onUrlChanged);
+    } else {
+
+        qDebug() << "Failed to get certifyUrl.";
+    }
+}
+
+void BlastOpePage::closeWebViewAndRestoreUI()
+{
+    if (view) {
+        layout->removeWidget(view);
+        delete view;
+        view = nullptr;
+    }
+    if (layout) {
+        delete layout;
+        layout = nullptr;
+    }
+}
+
+// 槽函数:处理 URL 改变事件
+void BlastOpePage::onUrlChanged(const QUrl &newUrl) {
+    if (newUrl.scheme() == "https" && newUrl.host() == "www.baidu.com") {
+        closeWebViewAndRestoreUI();
+        QNetworkAccessManager manager;
+        QUrl requestUrl(QString("http://localhost:8000/api/v1/h-face-verify/certifyId/%1").arg(certifyId));
+        QNetworkRequest request(requestUrl);
+        QNetworkReply *reply = manager.get(request);
+        QEventLoop loop;
+        QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
+        loop.exec();
+
+        if (reply->error() == QNetworkReply::NoError) {
+            QByteArray responseData = reply->readAll();
+            QJsonDocument jsonDoc = QJsonDocument::fromJson(responseData);
+            if (!jsonDoc.isNull() && jsonDoc.isObject()) {
+                QJsonObject rootObj = jsonDoc.object();
+                QJsonObject dataObj = rootObj["data"].toObject();
+                QString message = dataObj["Message"].toString();
+                QJsonObject resultObj = dataObj["ResultObject"].toObject();
+                if (resultObj.isEmpty()) {
+                    int ret = QMessageBox::information(nullptr, "提示", message+" ,请重新认证!");
+                    if (ret == QMessageBox::Ok) {
+                        InitFace();
+                    }
+                } else {
+                    QString passed = resultObj["Passed"].toString();
+                    if (passed == "T") {
+                        QMessageBox::information(nullptr, "提示", "操作成功!");
+                        ui->setupUi(this);
+                        initPagination();
+
+                    } else if (passed == "F") {
+                        int ret = QMessageBox::critical(nullptr, "提示", "操作失败,请重新认证!");
+                        if (ret == QMessageBox::Ok) {
+                            InitFace();
+                        }
+                    }
+                }
+            }
+        } else {
+            qDebug() << "Request failed:" << reply->errorString();
+        }
+
+        reply->deleteLater();
+    }
+
+
+}
+
+
+BlastOpePage::~BlastOpePage()
+{
+    delete ui;
+
+    if (view) {
+        delete view;
+    }
+    if (layout) {
+        delete layout;
+    }
+}
+
+
+QJsonObject BlastOpePage::sendPostRequest(const QUrl &url, const QJsonObject &data) {
+    QNetworkAccessManager manager;
+    QNetworkRequest request(url);
+    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
+
+    QJsonDocument doc(data);
+    QByteArray postData = doc.toJson();
+
+    QNetworkReply *reply = manager.post(request, postData);
+
+    QEventLoop loop;
+    QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
+    loop.exec();
+
+    QJsonObject responseJson;
+    if (reply->error() == QNetworkReply::NoError) {
+        QByteArray responseData = reply->readAll();
+        QJsonDocument responseDoc = QJsonDocument::fromJson(responseData);
+        if (!responseDoc.isNull() && responseDoc.isObject()) {
+            responseJson = responseDoc.object();
+        }
+    } else {
+        qDebug() << "Error fetching content: " << reply->errorString();
+    }
+    reply->deleteLater();
+    return responseJson;
+}
+
+void BlastOpePage::handleFeaturePermission(QWebEnginePage *page, const QUrl &securityOrigin, QWebEnginePage::Feature feature)
+{
+    if (feature == QWebEnginePage::MediaAudioCapture ||
+            feature == QWebEnginePage::MediaAudioVideoCapture ||
+            feature == QWebEnginePage::MediaVideoCapture) {
+        page->setFeaturePermission(securityOrigin, feature, QWebEnginePage::PermissionGrantedByUser);
+    } else {
+        page->setFeaturePermission(securityOrigin, feature, QWebEnginePage::PermissionDeniedByUser);
+    }
+}
+
+QJsonObject BlastOpePage::getMetaInfo() {
+    QJsonObject metaInfo;
+    metaInfo["certName"] = "";
+    metaInfo["certNo"] = "";
+    return metaInfo;
+}
+
+void BlastOpePage::initPagination(){
+    pageWidget= new PageWidget;
+    connect(pageWidget, &PageWidget::currentPageChanged, this, &BlastOpePage::PageChanged);
+    connect(pageWidget->getComboBox(), QOverload<int>::of(&QComboBox::currentIndexChanged), this, &BlastOpePage::onComboBoxIndexChanged);
+    ui->verticalLayout_4->addWidget(pageWidget);;
+    pageSize = 10;
+    currentPage = 1;
+    RefreshData();
+}
+
+void BlastOpePage::RefreshData()
+{
+    loadDataFromSource(currentPage,pageSize);
+}
+
+void BlastOpePage::loadDataFromSource(int currentPage, int pageSize)
+{
+    PaginatedHProjectResult result =dao.getAllHProjectsByOpera(currentPage,pageSize);
+    QList<QSharedPointer<HProject>> projectList = result.projects;
+    totalCount = result.totalCount;
+    pageWidget->setMaxPage(ceil(static_cast<double>(totalCount)/pageSize));
+
+    model = new QStandardItemModel(this);
+
+    headers = {
+        {"选择", ""}, // 新增选择列
+        {"工程名称", "name"},
+        {"操作员", "operatorName"},
+        {"爆破员", "blasterName"},
+        {"井下地址", "addressUuid"},
+        {"雷管数量", "detSum"},
+        {"起爆器数量", "blastCount"},
+        {"起爆状态", "blastStatus"},
+        {"进度", ""},
+        {"操作",""},
+    };
+
+    int headerCount = headers.size();
+    QStringList headerLabels;
+    QMap<int, QString> propMap;
+    for (int i = 0; i < headers.size(); ++i) {
+        headerLabels << headers[i].label;
+        propMap[i] = headers[i].prop;
+    }
+    model->setHorizontalHeaderLabels(headerLabels);
+    for (int row = 0; row < projectList.size(); ++row) {
+        HProject& HProject = *projectList.at(row).data();
+        QStandardItem* uuidItem = new QStandardItem();
+        uuidItem->setData(HProject.getUuid(), Qt::UserRole);
+        model->setItem(row, headerCount, uuidItem);
+        for (int col = 0; col < headerCount; ++col) {
+            QString prop = propMap[col];
+            QStandardItem* item = nullptr;
+            if(col ==0){
+                item = new QStandardItem();
+                item->setCheckable(true);
+                item->setCheckState(Qt::Unchecked);
+                item->setText("");
+            }
+            if (!prop.isEmpty()) {
+                QMetaProperty metaProp = HProject.metaObject()->property(HProject.metaObject()->indexOfProperty(prop.toUtf8()));
+                QVariant value = metaProp.read(&HProject);
+                if (prop == "blastStatus") {
+                    QString statusText;
+                    if (value.toString() == "1") {
+                        statusText = "未 注 册";
+                        item = new QStandardItem(statusText);
+                        item->setForeground(QColor("#e7c66b"));
+                    } else if (value.toString() == "2") {
+                        statusText = "待 起 爆";
+                        item = new QStandardItem(statusText);
+                        item->setForeground(QColor("#f3a361"));
+                    } else if (value.toString() == "3") {
+                        statusText = "起 爆 完 成";
+                        item = new QStandardItem(statusText);
+                        item->setForeground(QColor("#90d543"));
+                    } else {
+                        item = new QStandardItem(value.toString());
+                    }
+                } else {
+                    item = new QStandardItem(value.toString());
+                }
+
+            }
+            if (item) {
+                item->setTextAlignment(Qt::AlignCenter);  // 设置文本居中对齐
+                model->setItem(row, col, item);
+            }
+        }
+
+    }
+    ui->tableView->setModel(model);
+
+
+    connectionItem = QObject::connect(model, &QStandardItemModel::itemChanged, this, &BlastOpePage::onItemChanged);
+    ui->tableView->setColumnWidth(0, 20);
+    for (int i = 1; i < headerCount; ++i) {
+        ui->tableView->horizontalHeader()->setSectionResizeMode(i, QHeaderView::Stretch);
+    }
+    ui->tableView->setColumnHidden(headerCount, true);
+
+    ui->tableView->setAlternatingRowColors(true);
+    ui->tableView->verticalHeader()->setDefaultSectionSize(50);
+
+
+
+    for (int row = 0; row < projectList.size(); ++row) {
+        int progressCol = headers.size() - 2; //
+        QProgressBar *progressBar1 = new QProgressBar(ui->tableView);
+        progressBar1->setRange(0, 100); // 设置范围为0到100
+        progressBar1->setValue(0);
+        progressBar1->setAlignment(Qt::AlignCenter);
+        progressBar1->setStyleSheet("QProgressBar { border: 1px solid grey; border-radius: 5px; background-color: #EEEEEE; height: 10px; }"
+                                    "QProgressBar::chunk { background-color: #05B8CC; width: 2px; margin: 0.5px; border - radius: 10px; }");
+        progressBar1->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+
+        QProgressBar *progressBar2 = new QProgressBar(ui->tableView);
+        progressBar2->setRange(0, 100); // 设置范围为0到100
+        progressBar2->setValue(0);
+        progressBar2->setAlignment(Qt::AlignRight);
+        progressBar2->setStyleSheet("QProgressBar { border: 1px solid grey; border-radius: 5px; background-color: #EEEEEE; height: 20px; }"
+                                    "QProgressBar::chunk { background-color: #05B8CC; width: 20px; margin: 0.5px; border - radius: 10px; }");
+        progressBar2->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+
+        QProgressBar *progressBar3 = new QProgressBar(ui->tableView);
+        progressBar3->setRange(0, 100); // 设置范围为0到100
+        progressBar3->setValue(0);
+        progressBar3->setAlignment(Qt::AlignRight);
+        progressBar3->setStyleSheet("QProgressBar { border: 1px solid grey; border-radius: 5px; background-color: #EEEEEE; height: 20px; }"
+                                    "QProgressBar::chunk { background-color: #05B8CC; width: 20px; margin: 0.5px; border - radius: 10px; }");
+        progressBar3->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+
+        progressBars.append(ProgressBarTriple(progressBar1, progressBar2,progressBar3));
+        QHBoxLayout *progressBarLayout = new QHBoxLayout;
+        progressBarLayout->addWidget(progressBar1);
+        progressBarLayout->addWidget(progressBar2);
+        progressBarLayout->addWidget(progressBar3);
+        progressBarLayout->setAlignment(Qt::AlignCenter);
+        progressBarLayout->setContentsMargins(0, 0, 0, 0);
+
+        QWidget *progressBarContainer = new QWidget(ui->tableView);
+        progressBarContainer->setLayout(progressBarLayout);
+        QModelIndex progressIndex = model->index(row, progressCol);
+        if (progressIndex.isValid()) {
+            ui->tableView->setIndexWidget(progressIndex, progressBarContainer);
+        }
+        int col = headers.size() - 1;
+        // 创建一个按钮
+        QWidget* widget = new QWidget(ui->tableView);
+        QPushButton* button = new QPushButton(widget);
+        button->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+
+            QModelIndex statusIndex = model->index(row, propMap.key("blastStatus"));
+             if (statusIndex.isValid()) {
+                 QString blastStatus = model->data(statusIndex).toString();
+                 if (blastStatus == "起 爆 完 成") {
+                     // 为按钮添加图标,这里假设图标文件名为 icon.png,你需要根据实际情况修改
+                     QIcon icon(":/icons/icons/svg/blast.svg");
+                     button->setIcon(icon);
+                     button->setIconSize(QSize(32, 32)); // 设置图标大小
+                     button->setStyleSheet("QPushButton {"
+                                           "    padding: 0px;"
+                                           "    border: none;"
+                                           "    background-color: transparent;"
+                                           "}"
+                                           );
+
+                 }else{
+                    button->setText("开启起爆流程");
+                 }
+        }
+        QHBoxLayout* layout = new QHBoxLayout(widget);
+        layout->addWidget(button);
+        layout->setAlignment(Qt::AlignCenter);
+        layout->setContentsMargins(0, 0, 0, 0);
+        widget->setLayout(layout);
+
+        QModelIndex index = model->index(row, col);
+        if (index.isValid()) {
+            ui->tableView->setIndexWidget(index, widget);
+            connect(button, &QPushButton::clicked, [this, row,button]() {
+                handleButtonClick(row,button);
+            });
+        }
+    }
+
+}
+
+// 切换页数
+void BlastOpePage::PageChanged(int page)
+{
+    currentPage = page;
+    loadDataFromSource(currentPage,pageSize);
+}
+
+void BlastOpePage::onComboBoxIndexChanged(int index) {
+    QVariant variant = pageWidget->getComboBox()->itemData(index);
+    int value = variant.toInt();
+    pageSize = value;
+    currentPage = 1;
+    loadDataFromSource(currentPage,pageSize);
+}
+
+void BlastOpePage::updateProgressBar(int value, int row)
+{
+    if (!progressBars.isEmpty()) {
+        QProgressBar *progressBar1 = progressBars[row].bar1;
+        QProgressBar *progressBar2 = progressBars[row].bar2;
+        QProgressBar *progressBar3 = progressBars[row].bar3;
+        switch (value) {
+            case 1:
+                 //检查状态
+                progressBar1->setRange(0, 0); // 设置范围为0到100
+                progressBar1->setValue(0);
+                break;
+            case 2:
+                // 检查完成
+               progressBar1->setRange(0, 100); // 设置范围为0到100
+               progressBar1->setValue(100);
+               break;
+            case 3:
+                // 充电开始
+                progressBar2->setRange(0, 0); // 设置范围为0到100
+                progressBar2->setValue(0);
+               break;
+            case 4:
+                //充电完成
+                progressBar2->setRange(0, 100); // 设置范围为0到100
+                progressBar2->setValue(100);
+               break;
+            case 5:
+                //起爆中
+                progressBar3->setRange(0, 0); // 设置范围为0到100
+                progressBar3->setValue(0);
+               break;
+            case 6:
+                //充电完成
+                progressBar3->setRange(0, 100); // 设置范围为0到100
+                progressBar3->setValue(100);
+               break;
+            case 0:
+                progressBar1->setRange(0, 100);
+                progressBar1->setValue(0);
+                progressBar2->setRange(0, 100);
+                progressBar2->setValue(0);
+                progressBar3->setRange(0, 100);
+                progressBar3->setValue(0);
+               break;
+            default:
+                break;
+            }
+
+    }
+
+
+}
+
+void BlastOpePage::onUpdateBlastStatus(int status ,int row)
+{
+    QModelIndex index = model->index(row, 6);
+        if (index.isValid()) {
+            QColor customColor;
+            QFont boldFont;
+            boldFont.setBold(true);
+            switch (status) {
+                case 1:
+                    model->setData(index, "组 网 中 ...");
+                    customColor= QColor("#44035b");
+                    model->setData(index, customColor, Qt::ForegroundRole);
+                    model->setData(index, boldFont, Qt::FontRole);
+                    break;
+                case 2:
+                    model->setData(index, "组 网 完 成");
+                    customColor = QColor("#404185");
+                    model->setData(index, customColor, Qt::ForegroundRole);
+                    break;
+
+                case 3:
+                    model->setData(index, "充 电 中 ...");
+                    customColor = QColor("#31688e");
+                    model->setData(index, customColor, Qt::ForegroundRole);
+                    break;
+                case 4:
+                    model->setData(index, "充 电 完 成");
+                    customColor = QColor("#1f918d");
+                    model->setData(index, customColor, Qt::ForegroundRole);
+                    break;
+                case 5:
+                    model->setData(index, "起 爆 中 ...");
+                    customColor = QColor("#38b775");
+                    model->setData(index, customColor, Qt::ForegroundRole);
+                    break;
+                case 6:
+                    model->setData(index, "起 爆 完 成");
+                    customColor = QColor("#90d543");
+                    model->setData(index, customColor, Qt::ForegroundRole);
+                    break;
+                case 0:
+                    model->setData(index, "已 注 册");
+                    customColor = QColor("#8e620");
+                    model->setData(index, customColor, Qt::ForegroundRole);
+                    break;
+                case 10:
+                    model->setData(index, "按 下 双 建 起 爆 ...");
+                    customColor = QColor("#8e620");
+                    model->setData(index, customColor, Qt::ForegroundRole);
+                    break;
+                default:
+                    break;
+                }
+        }
+}
+
+void BlastOpePage::handleButtonClick(int row,QPushButton *button){
+    QStandardItem *uuidItem = model->item(row, 10);
+    QString uuid;
+    if (uuidItem) {
+        QVariant uuidVariant = uuidItem->data(Qt::UserRole);
+        if (uuidVariant.isValid()) {
+            uuid = uuidVariant.toString();
+        }
+    }
+    if (button->text() == "开启起爆流程") {
+            button->setText("取消起爆流程");
+            firingWidget *widget = new firingWidget(row,false,uuid);
+            connect(widget, &firingWidget::progressChanged, this, &BlastOpePage::updateProgressBar);
+            connect(widget, &firingWidget::updateBlastStatus, this, &BlastOpePage::onUpdateBlastStatus);
+            connect(widget,&firingWidget::updateButton,this,&BlastOpePage::changeButByMqtt);
+            connect(widget,&firingWidget::countdown,this,&BlastOpePage::showDownWidget);
+            connect(widget,&firingWidget::updateProjectStatus,this,&BlastOpePage::updateProject);
+            connect(widget,&firingWidget::closeFiring,this,&BlastOpePage::destroyFiringWidget);
+            widget->show();
+            widget->setAttribute(Qt::WA_DeleteOnClose);
+
+            uuidWidgetMap.insert(uuid, widget);
+    } else if (button->text() == "取消起爆流程") {
+
+        firingWidget *widget = uuidWidgetMap.value(uuid);
+        if (widget) {
+            widget->cancelBlasting();
+        }
+    }
+}
+
+
+void BlastOpePage::changeButByMqtt(int status ,int row){
+    qDebug() << "statusButton:"<<status;
+    QModelIndex index = model->index(row, 8);
+    if (index.isValid()) {
+        QWidget *widget = ui->tableView->indexWidget(index);
+        if (widget) {
+            QPushButton *button = widget->findChild<QPushButton*>();
+            if (button) {
+                // 使用样式表设置图标居中
+                          button->setStyleSheet("QPushButton {"
+                                                "    padding: 0px;"
+                                                "    border: none;"
+                                                "    background-color: transparent;"
+                                                "}"
+                                                );
+
+                // 添加图标,假设图标文件名为 blast.svg,并且该文件存在于项目资源中
+                QIcon icon(":/icons/icons/svg/blast.svg");
+                button->setText("");
+                button->setIcon(icon);
+                button->setIconSize(QSize(32, 32));
+
+            }
+        }
+    }
+}
+
+
+void BlastOpePage::updateProject(QString uuid){
+
+    dao.updateBlastStatusByUuid(uuid,"3");
+
+}
+
+
+void BlastOpePage::destroyFiringWidget(const QString& uuid)
+{
+    firingWidget *widget = uuidWidgetMap.value(uuid);
+    if (widget) {
+        widget->close(); // 关闭窗口
+        widget->deleteLater(); // 释放内存
+        uuidWidgetMap.remove(uuid); // 从映射中移除
+    }
+}
+
+// 槽函数,当 item 状态改变时触发
+void BlastOpePage::onItemChanged(QStandardItem *item) {
+    if (item->column() == 0) { // 仅处理第一列的勾选状态改变
+        if (item->checkState() == Qt::Checked) {
+            QStandardItem *uuidItem = model->item(item->row(), 10);
+            if (uuidItem) {
+                QVariant uuidVariant = uuidItem->data(Qt::UserRole);
+                if (uuidVariant.isValid()) {
+                    QString uuid = uuidVariant.toString();
+                    uuidMap[item->row()] = uuid;
+                }
+            }
+
+        } else if (item->checkState() == Qt::Unchecked) {
+            QStandardItem *uuidItem = model->item(item->row(), 10);
+                          if (uuidItem) {
+                              // 从 item 中获取 uuid 数据
+                              QVariant uuidVariant = uuidItem->data(Qt::UserRole);
+                              if (uuidVariant.isValid()) {
+                                  QString uuid = uuidVariant.toString();
+                                  // 从数组中移除该 uuid
+                                uuidMap.remove(item->row());
+                              }
+                          }
+        }
+    }
+
+}
+
+void BlastOpePage::on_btnSelect_clicked()
+{
+    // 禁用表格第一列的选项
+    for (int row = 0; row < model->rowCount(); ++row) {
+        QStandardItem *item = model->item(row, 0);
+        if (item) {
+            Qt::ItemFlags flags = item->flags();
+            flags &= ~Qt::ItemIsEnabled;
+            item->setFlags(flags);
+        }
+    }
+
+    for (auto it = uuidMap.begin(); it != uuidMap.end(); ++it) {
+        int row = it.key();
+        QString uuid = it.value();
+        firingWidget *widget = new firingWidget(row,true,uuid);
+        QModelIndex index = model->index(row, 9);
+        if (index.isValid()) {
+            QWidget *widgetButton = ui->tableView->indexWidget(index);
+            if (widgetButton) {
+                QPushButton *button = widgetButton->findChild<QPushButton*>();
+                button->setText("取消起爆流程");
+                }
+            }
+
+        // 信号连接
+        connect(widget, &firingWidget::progressChanged, this, &BlastOpePage::updateProgressBar);
+        connect(widget, &firingWidget::updateBlastStatus, this, &BlastOpePage::onUpdateBlastStatus);
+        widget->show();
+        widget->setAttribute(Qt::WA_DeleteOnClose);
+    }
+
+}
+
+

+ 93 - 0
blastopepage.h

@@ -0,0 +1,93 @@
+#ifndef BLASTOPEPAGE_H
+#define BLASTOPEPAGE_H
+
+#include <QWidget>
+#include <QPushButton>
+#include <QLayout>
+#include <QWebEnginePage>
+#include <QNetworkAccessManager>
+#include <QNetworkReply>
+#include <QWebEngineView>
+#include <QJsonObject>
+#include <QJsonDocument>
+#include <QJsonArray>
+#include <QMessageBox>
+#include <QProgressBar>
+#include <QLayout>
+#include <QStandardItemModel>
+#include "PageWidget.h"
+#include "hprojectdao.h"
+#include "fireWidget/firingwidget.h"  // 包含 firingWidget 头文件
+#include "countdownwidget.h"
+
+// 自定义结构体
+struct ProgressBarTriple {
+    QProgressBar* bar1;
+    QProgressBar* bar2;
+    QProgressBar* bar3;
+
+
+    // 构造函数
+    ProgressBarTriple(QProgressBar* b1, QProgressBar* b2, QProgressBar* b3)
+        : bar1(b1), bar2(b2), bar3(b3) {}
+};
+namespace Ui {
+class BlastOpePage;
+}
+
+class BlastOpePage : public QWidget
+{
+    Q_OBJECT
+
+public:
+    explicit BlastOpePage(QWidget *parent = nullptr);
+    ~BlastOpePage();
+private slots:
+    void PageChanged(int page);
+    void onComboBoxIndexChanged(int index);
+    void updateProgressBar(int value,int row);
+    void onUpdateBlastStatus(int status,int row);
+    void changeButByMqtt(int status, int row);
+    void showDownWidget(QString uuid,const QString &topic,const QString &message);
+    void updateProject(QString uuid);
+    void destroyFiringWidget(const QString &uuid);
+    void on_btnSelect_clicked();
+
+    void onItemChanged(QStandardItem *item);
+private:
+    void handleFeaturePermission(QWebEnginePage *page, const QUrl &securityOrigin, QWebEnginePage::Feature feature);
+    void RefreshData();
+    void loadDataFromSource(int currentPage,int pageSize);
+    void InitFace();
+    void closeWebViewAndRestoreUI();
+    void parseJsonString(const QJsonDocument &jsonDoc);
+    void onUrlChanged(const QUrl &newUrl);
+    void initPagination();
+    QJsonObject sendPostRequest(const QUrl &url, const QJsonObject &data);
+    QJsonObject getMetaInfo();
+    void handleButtonClick(int row,QPushButton *button);
+
+
+private:
+    Ui::BlastOpePage *ui;
+    QList<HeaderInfo> headers;
+    QStandardItemModel *model;
+    QMap<QString, firingWidget*> uuidWidgetMap;
+    QWebEngineView *view;
+    QList<QWidget*> originalWidgets; // 用于保存原始的 UI 控件
+    QWidget *overlayWidget;
+    QVBoxLayout *layout;
+    QString certifyId;
+    PageWidget *pageWidget;
+    QJsonArray dataArray;
+    HProjectDao dao;
+    QVector<ProgressBarTriple> progressBars; // 用于保存每行的两个进度条指针
+    QMap<int, QString> uuidMap; // 用于存储行号和对应的 uuid
+    QMetaObject::Connection connectionItem;
+    int pageSize;  //每页显示的记录数量
+    int currentPage;      //当前页面
+    int totalCount;
+
+};
+
+#endif // BLASTOPEPAGE_H

+ 185 - 0
blastopepage.ui

@@ -0,0 +1,185 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>BlastOpePage</class>
+ <widget class="QWidget" name="BlastOpePage">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>1023</width>
+    <height>531</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <property name="styleSheet">
+   <string notr="true">QPushButton {
+    background-color: #4CAF50;
+    color: white;
+    border: 2px solid #4CAF50;
+    border-radius: 5px;
+    padding: 5px;
+}
+QPushButton:pressed {
+    background-color: #388E3C; /* 按下时背景颜色变深 */
+    border-color: #388E3C; /* 按下时边框颜色变深 */
+    color: #f0f0f0; /* 按下时文字颜色稍微变化 */
+}
+QPushButton:hover {
+    /* 悬浮状态样式 */
+    background-color: #66BB6A; /* 悬浮时背景颜色变亮 */
+    border-color: #66BB6A; /* 悬浮时边框颜色变亮 */
+    color: white; /* 悬浮时文字颜色保持不变 */
+}
+#btnSelect {
+    /*background-color:#3583FF;*/
+    background-color: qlineargradient(spread:pad, x1:-0.2, y1:0.5, x2:1, y2:0.5, stop:0 rgba(62, 91, 255, 255), stop:0.6 rgba(20, 125, 232, 245));
+    color: white;
+    border: none; /* 去除描边 */
+    /*border: 2px solid #4CAF50;*/
+    border-radius: 20px;
+
+}</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <widget class="QFrame" name="searchBox">
+     <property name="maximumSize">
+      <size>
+       <width>16777215</width>
+       <height>50</height>
+      </size>
+     </property>
+     <property name="frameShape">
+      <enum>QFrame::Shape::StyledPanel</enum>
+     </property>
+     <property name="frameShadow">
+      <enum>QFrame::Shadow::Raised</enum>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QFrame" name="btnBox">
+     <property name="minimumSize">
+      <size>
+       <width>0</width>
+       <height>50</height>
+      </size>
+     </property>
+     <property name="maximumSize">
+      <size>
+       <width>16777215</width>
+       <height>50</height>
+      </size>
+     </property>
+     <property name="frameShape">
+      <enum>QFrame::Shape::StyledPanel</enum>
+     </property>
+     <property name="frameShadow">
+      <enum>QFrame::Shadow::Raised</enum>
+     </property>
+     <layout class="QHBoxLayout" name="horizontalLayout">
+      <property name="spacing">
+       <number>0</number>
+      </property>
+      <property name="leftMargin">
+       <number>0</number>
+      </property>
+      <property name="topMargin">
+       <number>0</number>
+      </property>
+      <property name="rightMargin">
+       <number>0</number>
+      </property>
+      <property name="bottomMargin">
+       <number>0</number>
+      </property>
+      <item>
+       <spacer name="horizontalSpacer">
+        <property name="orientation">
+         <enum>Qt::Orientation::Horizontal</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>920</width>
+          <height>20</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+      <item>
+       <widget class="QPushButton" name="btnSelect">
+        <property name="minimumSize">
+         <size>
+          <width>130</width>
+          <height>40</height>
+         </size>
+        </property>
+        <property name="text">
+         <string>起爆</string>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <widget class="QFrame" name="dataWidget">
+     <property name="frameShape">
+      <enum>QFrame::Shape::StyledPanel</enum>
+     </property>
+     <property name="frameShadow">
+      <enum>QFrame::Shadow::Raised</enum>
+     </property>
+     <layout class="QVBoxLayout" name="verticalLayout_3">
+      <item>
+       <widget class="QTableView" name="tableView"/>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <widget class="QFrame" name="pagination">
+     <property name="minimumSize">
+      <size>
+       <width>0</width>
+       <height>30</height>
+      </size>
+     </property>
+     <property name="maximumSize">
+      <size>
+       <width>16777215</width>
+       <height>30</height>
+      </size>
+     </property>
+     <property name="frameShape">
+      <enum>QFrame::Shape::StyledPanel</enum>
+     </property>
+     <property name="frameShadow">
+      <enum>QFrame::Shadow::Raised</enum>
+     </property>
+     <layout class="QVBoxLayout" name="verticalLayout_4">
+      <property name="spacing">
+       <number>0</number>
+      </property>
+      <property name="leftMargin">
+       <number>0</number>
+      </property>
+      <property name="topMargin">
+       <number>0</number>
+      </property>
+      <property name="rightMargin">
+       <number>0</number>
+      </property>
+      <property name="bottomMargin">
+       <number>0</number>
+      </property>
+     </layout>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>

+ 11 - 0
blastoperationfactory.cpp

@@ -0,0 +1,11 @@
+#include "blastoperationfactory.h"
+
+BlastOperationFactory::BlastOperationFactory()
+{
+
+}
+
+QWidget *BlastOperationFactory::createPage(QWidget *parent) const
+{
+    return new BlastOpePage(parent);
+}

+ 13 - 0
blastoperationfactory.h

@@ -0,0 +1,13 @@
+#ifndef BLASTOPERATIONFACTORY_H
+#define BLASTOPERATIONFACTORY_H
+#include "PageFactory.h"
+#include "blastopepage.h"
+
+class BlastOperationFactory:public PageFactory
+{
+public:
+    BlastOperationFactory();
+    QWidget* createPage(QWidget* parent) const override;
+};
+
+#endif // BLASTOPERATIONFACTORY_H

+ 11 - 0
blastprojectfactory.cpp

@@ -0,0 +1,11 @@
+#include "blastprojectfactory.h"
+
+BlastProjectFactory::BlastProjectFactory()
+{
+
+}
+
+QWidget *BlastProjectFactory::createPage(QWidget *parent) const
+{
+    return new BlastProjectPage(parent);
+}

+ 299 - 0
blastprojectpage.cpp

@@ -0,0 +1,299 @@
+#include "blastprojectpage.h"
+#include "ui_blastprojectpage.h"
+#include <iostream>
+#include "global.h"
+#include <QUrl>
+#include "databasemanager.h"
+
+BlastProjectPage::BlastProjectPage(QWidget *parent) :
+    QWidget(parent),
+    ui(new Ui::BlastProjectPage),
+    dao(DatabaseManager::getInstance().getDatabase())
+{
+    ui->setupUi(this);
+    pageWidget= new PageWidget;
+    connect(pageWidget, &PageWidget::currentPageChanged, this, &BlastProjectPage::PageChanged);
+    connect(pageWidget->getComboBox(), QOverload<int>::of(&QComboBox::currentIndexChanged), this, &BlastProjectPage::onComboBoxIndexChanged);
+    ui->verticalLayout_4->addWidget(pageWidget);;
+    pageSize = 10;
+    currentPage = 1;
+
+    RefreshData();
+    m_httpClient = new HttpClient(this);
+    QUrl localUrl("person/type");
+    QUrl fullUrl = g_url.resolved(localUrl);
+    m_httpClient->sendHttpGetRequest(fullUrl);
+
+    QUrl addressLocalUrl("h-address/pc");
+    QUrl addressFullUrl = g_url.resolved(addressLocalUrl);
+    m_httpClient->sendHttpGetAddress(addressFullUrl);
+    // 获取用户信息
+    connect(m_httpClient, &HttpClient::httpGetFinished, [this](const QJsonDocument &data,const QUrl url) {
+        QString relativePath = url.toString().remove(0, g_url.toString().length());
+        if (relativePath == "person/type") {
+            this->personOptionsByType(data);
+        } else if (relativePath == "h-address/pc") {
+            this->addressOptions(data);
+        }
+        qDebug() << "relativePath:" << relativePath;
+    });
+
+
+    dialog = new ProjectDialog(this);
+    connect(dialog, &ProjectDialog::validateDetNum, this, &BlastProjectPage::insertPlan);
+    connect(dialog, &ProjectDialog::validateDetNumUpdate, this, &BlastProjectPage::updateProject);
+}
+
+
+void BlastProjectPage::RefreshData()
+{
+
+    loadDataFromSource(currentPage,pageSize);
+
+}
+
+void BlastProjectPage::loadDataFromSource(int currentPage, int pageSize)
+{
+    PaginatedHProjectResult result =dao.getAllHProjects(currentPage,pageSize);
+
+    QList<QSharedPointer<HProject>> projectList = result.projects;
+
+    totalCount = result.totalCount;
+    pageWidget->setMaxPage(ceil(static_cast<double>(totalCount)/pageSize));
+    QStandardItemModel *model;
+    model = new QStandardItemModel(this);
+
+    // 定义表头信息
+    QList<HeaderInfo> headers = {
+        {"工程名称", "name"},
+        {"操作员", "operatorName"},
+        {"爆破员", "blasterName"},
+        {"井下地址", "addressUuid"},
+        {"雷管数量", "detSum"},
+        {"起爆状态", "blastStatus"},
+        {"操作",""},
+    };
+    // 获取表头的长度
+    int headerCount = headers.size();
+    // 设置表头
+    QStringList headerLabels;
+    QMap<int, QString> propMap; // 用于存储表头的 prop 属性
+    for (int i = 0; i < headers.size(); ++i) {
+        headerLabels << headers[i].label;
+        propMap[i] = headers[i].prop;
+    }
+    model->setHorizontalHeaderLabels(headerLabels);
+    // // 填充数据
+    for (int row = 0; row < projectList.size(); ++row) {
+        HProject& HProject = *projectList.at(row).data();
+        for (int col = 0; col < headers.size(); ++col) {
+            QString prop = propMap[col];
+            QStandardItem* item = nullptr;
+
+            // 根据 prop 获取 SysApi 对象的属性值
+            if (!prop.isEmpty()) {
+                QMetaProperty metaProp = HProject.metaObject()->property(HProject.metaObject()->indexOfProperty(prop.toUtf8()));
+                QVariant value = metaProp.read(&HProject);
+                item = new QStandardItem(value.toString());
+            } else {
+                item = new QStandardItem("操作");
+            }
+            if (item) {
+                item->setTextAlignment(Qt::AlignCenter);  // 设置文本居中对齐
+                model->setItem(row, col, item);
+            }
+        }
+    }
+    // 设置 QTableView 的 model
+    ui->tableView->setModel(model);
+    ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
+
+    // 创建并设置自定义委托
+    ButtonDelegate *delegate = new ButtonDelegate(headerCount-1,this);
+    QObject::connect(delegate, &ButtonDelegate::buttonClicked, [=](int row, int column) {
+        qDebug() << "Button clicked at row:" << row << "column:" << column;
+        // 获取 HPlan 引用
+        HProject& HPlanDeleteOrUpdate = *projectList.at(row).data();
+        updateId = HPlanDeleteOrUpdate.getId();
+        if(column == 1){
+            deleteButtonClicked(HPlanDeleteOrUpdate);
+        }
+        if(column == 2){
+            updateButtonClicked(HPlanDeleteOrUpdate);
+        }
+        QStringList rowData;
+        for (int col = 0; col < model->columnCount(); ++col) {
+            QModelIndex index = model->index(row, col);
+            rowData << index.data() .toString();
+            QVariant data = model->data(index);
+            rowData += QString("Column %1: %2 | ").arg(col).arg(data.toString());
+        }
+        // qDebug() << "Row data:" << rowData;
+    });
+    ui->tableView->setItemDelegateForColumn(headerCount-1, delegate);
+}
+
+// 切换页数
+void BlastProjectPage::PageChanged(int page)
+{
+    currentPage = page;
+    loadDataFromSource(currentPage,pageSize);
+}
+
+void BlastProjectPage::onComboBoxIndexChanged(int index) {
+    // 获取当前选中的文本
+    QVariant variant = pageWidget->getComboBox()->itemData(index);
+    int value = variant.toInt();
+    pageSize = value;
+    currentPage = 1;
+    loadDataFromSource(currentPage,pageSize);
+
+}
+
+
+void BlastProjectPage::personOptionsByType(const QJsonDocument &jsonDoc)
+{
+    parseJsonString(jsonDoc);
+    // 定义两个新的 QJsonArray 用于存储分组后的数据
+    QJsonArray bapoYuanArray;
+    QJsonArray anQuanYuanArray;
+
+    for (const QJsonValue &value : dataArray) {
+        if (value.isObject()) {
+            QJsonObject obj = value.toObject();
+            if (obj.contains("personTypeName")) {
+                QString personTypeName = obj["personTypeName"].toString();
+
+                // 按 personType 分组
+                if (personTypeName == "爆破员") {
+                    bapoYuanArray.append(obj);
+                } else if (personTypeName == "安全员") {
+                    anQuanYuanArray.append(obj);
+                }
+            }
+        }
+    }
+    // 将分组后的数据填充到对应的 QComboBox 中
+    dialog->SetComboBoxBlast(bapoYuanArray);
+    dialog->SetComboBoxOperator(anQuanYuanArray);
+}
+
+
+void BlastProjectPage::addressOptions(const QJsonDocument &jsonDoc)
+{
+    parseJsonStringAddress(jsonDoc);
+    QJsonArray parentOptions;
+    for (const QJsonValue &item : dataArrayAddress) {
+        parentOptions.append(item.toObject()["name"].toString());
+    }
+    dialog->SetComboBoxAddress(parentOptions);
+    dialog->setChildOptions(dataArrayAddress);
+    // qDebug()<<"parentOptions data"<<parentOptions;
+}
+
+void BlastProjectPage::parseJsonString(const QJsonDocument &jsonDoc)
+{
+    QJsonObject jsonObj = jsonDoc.object();
+    QJsonObject dataObj = jsonObj["data"].toObject();
+    dataArray = dataObj["list"].toArray();
+    // qDebug()<<"Row data"<<dataArray;
+}
+
+void BlastProjectPage::parseJsonStringAddress(const QJsonDocument &jsonDoc)
+{
+    QJsonObject jsonObj = jsonDoc.object();
+    dataArrayAddress = jsonObj["data"].toArray();
+    // qDebug()<<"Row data"<<dataArrayAddress;
+
+}
+void BlastProjectPage::on_pushButton_clicked()
+{
+
+    dialog->setModal(false);
+    dialog->setOperationStatus(0);
+    int ref = dialog->exec();
+    if (ref==QDialog::Accepted){
+        qDebug()<<"新增对话框关闭";
+    };
+
+}
+
+void BlastProjectPage::insertPlan(const QMap<QString, QString> &data)
+{
+    qDebug() << "Inserting project *****************:";
+
+    HProject project;
+    project.setName(data.value("name"));
+    project.setDetSum(data.value("detNum"));
+    project.setBlasterName(data.value("blasterName"));
+    project.setOperatorName(data.value("operatorName"));
+    project.setAddressUuid(data.value("addressUuid"));
+    project.setBlasterIdentity(data.value("blasterIdentity"));
+    project.setOperatorIdentity(data.value("operatorIdentity"));
+    // 生成 32 位的 UUID
+    QString uuidString = QUuid::createUuid().toString(QUuid::WithoutBraces).remove(QRegularExpression("-"));
+    project.setUuid(uuidString); // 假设 HProject 类有 setUuid 方法
+    if(dao.addHProject(project)){
+        RefreshData();
+        qDebug() << "Inserting MqttClient";
+        MqttClient* client = MqttClient::getInstance();
+
+        // 将 project 对象转换为 JSON
+        QByteArray jsonData  = project.ProjectToJson(project);
+
+        qDebug() << "JSON from HProject: " << jsonData;
+
+        // 发送消息到 testtopic
+        client->sendMessage("testtopic", jsonData);
+
+    }
+
+}
+
+void BlastProjectPage::updateButtonClicked(const HProject &project){
+    dialog->setModal(false);
+    dialog->setOperationStatus(1);
+    dialog->setFormData(project);
+    int ref = dialog->exec();
+    if (ref==QDialog::Accepted){
+        qDebug()<<"aaa";
+    };
+
+}
+
+void BlastProjectPage::updateProject(const QMap<QString, QString> &data){
+    QString detNum = data.value("detNum");
+    QString name = data.value("name");
+    QString operaName = data.value("operatorName");
+    qDebug() << "updateProject  with detNum:" << detNum << "name:" << name << "operaName:" << operaName;
+    HProject project;
+    project.setId(updateId);
+    project.setName(data.value("name"));
+    project.setDetSum(data.value("detNum"));
+    project.setBlasterName(data.value("blasterName"));
+    project.setOperatorName(data.value("operatorName"));
+    project.setAddressUuid(data.value("addressUuid"));
+    project.setBlasterIdentity(data.value("blasterIdentity"));
+    project.setOperatorIdentity(data.value("operatorIdentity"));
+    if(dao.updateHProject(project)){
+        qDebug() << "updateHProject";
+        RefreshData();
+    }
+
+
+
+}
+void BlastProjectPage::deleteButtonClicked(const HProject &project){
+
+    if(dao.deleteHProject(project)){
+        RefreshData();
+    }
+
+}
+
+BlastProjectPage::~BlastProjectPage()
+{
+    delete ui;
+}
+
+

+ 61 - 0
blastprojectpage.h

@@ -0,0 +1,61 @@
+#ifndef BLASTPROJECTPAGE_H
+#define BLASTPROJECTPAGE_H
+
+#include <QWidget>
+#include <QStandardItemModel>
+#include <QPushButton>
+#include <QJsonArray>
+#include "hprojectdao.h"
+#include "PageWidget.h"
+#include "buttondelegate.h"
+#include "projectdialog.h"
+#include "HttpClient.h"
+#include "mqtt/mqttclient.h"
+
+namespace Ui {
+class BlastProjectPage;
+}
+
+class BlastProjectPage : public QWidget
+{
+    Q_OBJECT
+
+public:
+    explicit BlastProjectPage(QWidget *parent = nullptr);
+    ~BlastProjectPage();
+
+
+private slots:
+    void PageChanged(int page);
+    void onComboBoxIndexChanged(int index);
+    void on_pushButton_clicked();
+
+private:
+    void RefreshData();
+    void loadDataFromSource(int currentPage,int pageSize);
+    void personOptionsByType(const QJsonDocument &jsonDoc);
+    void parseJsonStringAddress(const QJsonDocument &jsonDoc);
+    void addressOptions(const QJsonDocument &jsonDoc);
+    void parseJsonString(const QJsonDocument &jsonDoc);
+    void fillComboBox(QComboBox *comboBox, const QJsonArray &jsonArray);
+    void insertPlan(const QMap<QString, QString> &data);
+    void updateButtonClicked(const HProject &project);
+    void updateProject(const QMap<QString, QString> &data);
+    void deleteButtonClicked(const HProject &project);
+
+private:
+    Ui::BlastProjectPage *ui;
+    PageWidget *pageWidget;
+    ProjectDialog *dialog;
+    HttpClient *m_httpClient;
+    HProjectDao dao;
+    QJsonArray dataArray;
+    QJsonArray dataArrayAddress;
+    int pageSize;  //每页显示的记录数量
+    int currentPage;      //当前页面
+    int totalCount;
+    int updateId;
+
+};
+
+#endif // BLASTPROJECTPAGE_H

+ 56 - 0
btnserialthread.cpp

@@ -0,0 +1,56 @@
+#include "btnserialthread.h"
+
+BtnSerialThread::BtnSerialThread(QObject *parent) : QThread(parent)
+{
+    btnSerialTool = nullptr;
+    connect(this, &BtnSerialThread::destroySerialTool, this, &BtnSerialThread::onDestroySerialTool, Qt::QueuedConnection);
+}
+
+BtnSerialThread::~BtnSerialThread()
+{    qDebug() << "SerialToolThread:" ;
+    // emit destroySerialTool();
+    // // if (isRunning()) {
+    // //     qDebug() << "SerialToolT:" ;
+    // //     quit();
+    // //     wait();
+    // // }
+    qDebug() << "Current thread in run():" << QThread::currentThread();
+    qDebug() << "SerialToolThread object is in thread:" << this->thread();
+    qDebug() << "SerialTool object is in thread:" << btnSerialTool->thread();
+}
+
+void BtnSerialThread::run()
+{
+    btnSerialTool = new BtnSerialTool();
+    emit serialToolCreated();
+
+    qDebug() << "SerialToolThread object is in thread:" << this->thread();
+    qDebug() << "SerialTool object is in thread:" << btnSerialTool->thread();
+    qDebug() << "Current thread in run():" << QThread::currentThread();
+    // 连接信号
+
+    connect(this, &BtnSerialThread::sendDataRequest, btnSerialTool, &BtnSerialTool::handleSendDataReques, Qt::QueuedConnection);
+    connect(btnSerialTool, &BtnSerialTool::dataReceived, this, &BtnSerialThread::handleReceivedData, Qt::QueuedConnection);
+    // 启动事件循环
+    exec();
+}
+
+// 处理接收到的数据
+void BtnSerialThread::handleReceivedData(const QByteArray &data)
+{
+    // 这里可以添加具体的处理逻辑,例如打印接收到的数据
+    qDebug() << "Received data:" << data;
+
+    // 可以将接收到的数据通过信号发送出去
+    emit dataReceived(data);
+}
+
+void BtnSerialThread::onDestroySerialTool()
+ {
+    qDebug() << "触发信号" ;
+     if (btnSerialTool) {
+         qDebug() << "delete serialTool";
+         delete btnSerialTool;
+         btnSerialTool = nullptr;
+     }
+ }

+ 28 - 0
btnserialthread.h

@@ -0,0 +1,28 @@
+#ifndef BTNSERIALTHREAD_H
+#define BTNSERIALTHREAD_H
+
+#include <QThread>
+#include <QByteArray>
+#include "btnserialtool.h"
+
+class BtnSerialThread : public QThread
+{
+        Q_OBJECT
+public:
+    BtnSerialThread(QObject *parent = nullptr);
+    ~BtnSerialThread(); // 声明析构函数
+signals:
+    void dataReceived(const QByteArray& data);
+    void sendDataRequest(const QByteArray &data);
+    void serialToolCreated();
+    void destroySerialTool();
+private slots:
+    void handleReceivedData(const QByteArray &data);
+    void onDestroySerialTool();
+protected:
+    void run() override;
+private:
+    BtnSerialTool *btnSerialTool;
+};
+
+#endif // BTNSERIALTHREAD_H

+ 91 - 0
btnserialtool.cpp

@@ -0,0 +1,91 @@
+#include "btnserialtool.h"
+
+BtnSerialTool::BtnSerialTool(QObject *parent) : QObject(parent)
+{
+  setupSerialPort();
+}
+
+
+// 打开串口的函数
+void BtnSerialTool::openSerialPort()
+{
+    const QString portName = "COM8";
+    const qint32 baudRate = 9600;
+
+    if (!serialPort.isOpen()) {
+        serialPort.setPortName(portName);
+        serialPort.setBaudRate(baudRate);
+
+        // 设置数据位,通常为 8 位
+        serialPort.setDataBits(QSerialPort::Data8);
+
+        // 设置停止位,这里设置为 1 位停止位
+        serialPort.setStopBits(QSerialPort::OneStop);
+
+        // 设置校验位,这里设置为无校验
+        serialPort.setParity(QSerialPort::NoParity);
+
+        if (serialPort.open(QIODevice::ReadWrite)) {
+            emit openCloseButtonTextChanged("关闭串口");
+        } else {
+            emit openError();
+        }
+    }
+}
+
+// 关闭串口的函数
+void BtnSerialTool::closeSerialPort()
+{
+    if (serialPort.isOpen()) {
+        serialPort.close();
+        emit openCloseButtonTextChanged("打开串口");
+    }
+}
+
+bool BtnSerialTool::sendData(const QByteArray& data)
+{
+    if (serialPort.isOpen()) {
+        qint64 bytesWritten = serialPort.write(data);
+        return bytesWritten == data.size();
+    }
+    return false;
+}
+
+void BtnSerialTool::handleSendDataReques(const QByteArray &data)
+{
+    sendData(data);
+}
+
+void BtnSerialTool::readData()
+{
+    QByteArray newData = serialPort.readAll();
+    buffer.append(newData);
+
+    // 查找完整的命令
+    int startIndex = buffer.indexOf("\\r\\n");
+    while (startIndex != -1) {
+        int endIndex = buffer.indexOf("\\r\\n", startIndex + 4);
+        if (endIndex != -1) {
+            // 提取完整的命令
+            QByteArray command = buffer.mid(startIndex + 4, endIndex - startIndex - 4);
+            emit dataReceived(newData);
+            qDebug() << "Complete command:" << command;
+
+            // 移除已处理的部分
+            buffer = buffer.mid(endIndex + 4);
+        } else {
+            break;
+        }
+        startIndex = buffer.indexOf("\\r\\n");
+    }
+
+
+    qDebug() << "Received data:" << newData;
+}
+
+
+void BtnSerialTool::setupSerialPort()
+{
+    openSerialPort();
+    connect(&serialPort, &QSerialPort::readyRead, this, &BtnSerialTool::readData);
+}

+ 31 - 0
btnserialtool.h

@@ -0,0 +1,31 @@
+#ifndef BTNSERIALTOOL_H
+#define BTNSERIALTOOL_H
+#include <QObject>
+#include <QSerialPort>
+#include <QPushButton>
+#include <QLineEdit>
+#include <QTextEdit>
+#include <QByteArray>
+
+class BtnSerialTool: public QObject
+{
+    Q_OBJECT
+public:
+    BtnSerialTool(QObject *parent = nullptr);
+    void openSerialPort();
+    void closeSerialPort();
+    void readData();
+    bool sendData(const QByteArray &data);
+signals:
+    void openCloseButtonTextChanged(const QString& text);
+    void openError();
+    void dataReceived(const QByteArray& data);
+public slots:
+    void handleSendDataReques(const QByteArray &data);
+private:
+    void setupSerialPort();
+    QByteArray buffer; // 确保这里声明了 buffer 变量
+    QSerialPort serialPort;
+};
+
+#endif // BTNSERIALTOOL_H

+ 60 - 0
buttondelegate.cpp

@@ -0,0 +1,60 @@
+#include "buttondelegate.h"
+#include <QStyledItemDelegate>
+#include <qDebug>
+
+ButtonDelegate::ButtonDelegate(int buttonColumn,QObject *parent) : QStyledItemDelegate(parent),buttonColumn(buttonColumn){
+    // 构造函数实现(如果需要)
+}
+
+void ButtonDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const {
+    if (index.column() == buttonColumn) {
+        QStyleOptionButton buttonOption1;
+        QStyleOptionButton buttonOption2;
+        QRect rect = option.rect;
+        rect.adjust(0, 0, -1, -1); // 调整大小以适应边框
+
+        // 第一个按钮
+        buttonOption1.rect = rect.adjusted(0, 0, -rect.width() / 2, 0);
+        buttonOption1.text = "删除"; // 按钮文本
+        buttonOption1.state = QStyle::State_Enabled;
+        QApplication::style()->drawControl(QStyle::CE_PushButton, &buttonOption1, painter);
+
+        // 第二个按钮
+        buttonOption2.rect = rect.adjusted(rect.width() / 2, 0, 0, 0);
+        buttonOption2.text = "编辑"; // 按钮文本
+        buttonOption2.state = QStyle::State_Enabled;
+        QApplication::style()->drawControl(QStyle::CE_PushButton, &buttonOption2, painter);
+    } else {
+        QStyledItemDelegate::paint(painter, option, index);
+    }
+}
+
+
+bool ButtonDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)  {
+    if (index.column() == buttonColumn && event->type() == QEvent::MouseButtonPress) {
+        QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
+        QRect rect = option.rect;
+        rect.adjust(0, 0, -1, -1); // 调整大小以适应边框
+
+        // 检测第一个按钮的点击
+        QRect button1Rect = rect.adjusted(0, 0, -rect.width() / 2, 0);
+        if (button1Rect.contains(mouseEvent->pos())) {
+            handleButtonClick (index.row(),1); // 处理第一个按钮点击
+            return true;
+        }
+
+        // 检测第二个按钮的点击
+        QRect button2Rect = rect.adjusted(rect.width() / 2, 0, 0, 0);
+        if (button2Rect.contains(mouseEvent->pos())) {
+            handleButtonClick(index.row(), 2); // 处理第二个按钮点击
+            return true;
+        }
+    }
+    return QStyledItemDelegate::editorEvent(event, model, option, index);
+}
+
+
+void ButtonDelegate::handleButtonClick(int row,int button) {
+    // qDebug() << "行号: " << row << ", 按钮: " << button;
+    emit buttonClicked(row, button); // 发射信号
+    }

+ 39 - 0
buttondelegate.h

@@ -0,0 +1,39 @@
+#ifndef BUTTONDELEGATE_H
+#define BUTTONDELEGATE_H
+
+#include <QStyledItemDelegate>
+#include <QWidget>
+#include <QHBoxLayout>
+#include <QPushButton>
+#include <QModelIndex>
+#include <QAbstractItemModel>
+#include <QPainter>
+#include <QStyleOptionViewItem>
+#include <QStyleOptionButton>
+#include <QApplication>
+#include <QTableView>
+#include <QMouseEvent>
+#include <QDebug>
+
+class ButtonDelegate: public QStyledItemDelegate{
+    Q_OBJECT
+
+public:
+    explicit ButtonDelegate(int buttonColumn,QObject *parent = nullptr);
+
+    void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
+
+    bool editorEvent(QEvent *event, QAbstractItemModel *model,const QStyleOptionViewItem &option, const QModelIndex &index) override;
+
+    void handleButtonClick(int row, int button);
+
+private:
+    int buttonColumn; // 成员变量
+signals:
+    void buttonClicked(int row, int button);
+
+};
+
+
+
+#endif // BUTTONDELEGATE_H

+ 62 - 0
clickabletableview.cpp

@@ -0,0 +1,62 @@
+#include "clickabletableview.h"
+
+ClickableTableView::ClickableTableView(QWidget *parent)
+    : QTableView(parent) {
+    // 构造函数的实现
+    // // 设置背景颜色
+    // QPalette palette = this->palette();
+    // palette.setColor(QPalette::Base, Qt::white);
+    // palette.setColor(QPalette::AlternateBase, Qt::lightGray);
+    // palette.setColor(QPalette::Highlight, QColor(0, 120, 215));
+    // palette.setColor(QPalette::HighlightedText, Qt::white);
+    // this->setPalette(palette);
+
+    // // 设置网格线颜色
+    // this->setGridStyle(Qt::SolidLine);
+    // QColor gridColor(Qt::darkGray);
+    this->setStyleSheet(QString("QTableView { selection-background-color: blue;}"
+                                "QTableView QTableCornerButton::section { background: transparent; } "
+                                "QHeaderView::section { background-color: gray; color: white; padding-left: 4px; padding-right: 4px; } "));
+
+    // // 设置边框
+    // this->setFrameShape(QFrame::Box);
+    // this->setLineWidth(1);
+
+    // // 设置单元格内边距
+    // this->verticalHeader()->setDefaultSectionSize(30);
+    // this->horizontalHeader()->setDefaultSectionSize(100);
+// }
+}
+
+void ClickableTableView::mouseReleaseEvent(QMouseEvent *event) {
+    QModelIndex index = indexAt(event->pos());
+    if (index.isValid() && index.column() == 8) {
+        QRect rect = visualRect(index);
+        QRect firstButtonRect = rect.adjusted(0, 0, -rect.width() / 2, 0);
+        QRect secondButtonRect = rect.adjusted(rect.width() / 2, 0, 0, 0);
+
+        if (firstButtonRect.contains(event->pos())) {
+            // 处理第一个按钮点击事件
+            qDebug() << "Button 1 clicked at row:" << index.row();
+            displayRowData(index.row());
+        } else if (secondButtonRect.contains(event->pos())) {
+            // 处理第二个按钮点击事件
+            qDebug() << "Button 2 clicked at row:" << index.row();
+            displayRowData(index.row());
+        }
+    }
+    QTableView::mouseReleaseEvent(event);
+}
+
+void ClickableTableView::displayRowData(int row) {
+    QAbstractItemModel* model = this->model();
+    if (model) {
+        QString rowData;
+        for (int col = 0; col < model->columnCount(); ++col) {
+            QModelIndex index = model->index(row, col);
+            QVariant data = model->data(index);
+            rowData += QString("Column %1: %2 | ").arg(col).arg(data.toString());
+        }
+        qDebug() << "Row" << row << "Data:" << rowData;
+    }
+}

+ 16 - 0
clickabletableview.h

@@ -0,0 +1,16 @@
+#ifndef CLICKABLETABLEVIEW_H
+#define CLICKABLETABLEVIEW_H
+
+#include <QTableView>
+#include <QMouseEvent>
+#include <QDebug>
+
+class ClickableTableView : public QTableView {
+    Q_OBJECT
+public:
+    explicit ClickableTableView(QWidget *parent = nullptr);
+    void mouseReleaseEvent(QMouseEvent *event) override;
+    void displayRowData(int row);
+};
+
+#endif // CLICKABLETABLEVIEW_H

+ 48 - 0
countdownwidget.cpp

@@ -0,0 +1,48 @@
+#include "countdownwidget.h"
+CountdownWidget::CountdownWidget(QWidget *parent) : QWidget(parent), m_remainingSeconds(5)
+{
+    setWindowFlags(Qt::FramelessWindowHint);
+    setAttribute(Qt::WA_TranslucentBackground);
+    m_timer = new QTimer(this);
+    connect(m_timer, &QTimer::timeout, this, &CountdownWidget::onTimerTimeout);
+    m_timer->start(1000);
+}
+CountdownWidget::~CountdownWidget()
+{
+    if (m_timer->isActive()) {
+        m_timer->stop();
+    }
+}
+void CountdownWidget::paintEvent(QPaintEvent *event)
+{
+    Q_UNUSED(event);
+
+    QPainter painter(this);
+    painter.setRenderHint(QPainter::Antialiasing);
+
+
+    QBrush brush(Qt::red);
+    painter.setBrush(brush);
+    painter.drawEllipse(rect());
+    QFont font;
+    font.setPointSize(58);
+    font.setBold(true);
+    painter.setFont(font);
+    painter.setPen(Qt::white);
+    if (m_remainingSeconds > 0) {
+        painter.drawText(rect(), Qt::AlignCenter, QString::number(m_remainingSeconds));
+    } else {
+        painter.drawText(rect(), Qt::AlignCenter, "0");
+    }
+}
+
+void CountdownWidget::onTimerTimeout()
+{
+    m_remainingSeconds--;
+    if (m_remainingSeconds == 0) {
+        m_timer->stop();
+        close();
+        emit countdownFinished(); // 发出自定义信号
+    }
+    update();
+}

+ 29 - 0
countdownwidget.h

@@ -0,0 +1,29 @@
+#ifndef COUNTDOWNWIDGET_H
+#define COUNTDOWNWIDGET_H
+
+#include <QWidget>
+#include <QTimer>
+#include <QPainter>
+
+class CountdownWidget : public QWidget
+{
+    Q_OBJECT
+public:
+    explicit CountdownWidget(QWidget *parent = nullptr);
+    ~CountdownWidget();
+
+protected:
+    void paintEvent(QPaintEvent *event) override;
+
+signals:
+    void countdownFinished();
+
+private slots:
+    void onTimerTimeout();
+
+private:
+    QTimer *m_timer;
+    int m_remainingSeconds;
+};
+
+#endif // COUNTDOWNWIDGET_H

+ 30 - 0
databasemanager.cpp

@@ -0,0 +1,30 @@
+#include "databasemanager.h"
+#include <QSqlError>
+#include <QDebug>
+
+DatabaseManager& DatabaseManager::getInstance() {
+    static DatabaseManager instance;
+    return instance;
+}
+
+// 创建一个新的数据库连接
+DatabaseManager::DatabaseManager() : db(QSqlDatabase::addDatabase("QMYSQL")) {
+    db.setHostName("192.168.0.255");
+    db.setDatabaseName("pc_system");
+    db.setUserName("hxgc");
+    db.setPassword("hxgc12345678");
+
+    if (!db.open()) {
+        qDebug() << "Failed to open database: " << db.lastError().text();
+    }
+}
+
+DatabaseManager::~DatabaseManager() {
+    if (db.isOpen()) {
+        db.close();
+    }
+}
+
+QSqlDatabase& DatabaseManager::getDatabase() {
+    return db;
+}

+ 19 - 0
databasemanager.h

@@ -0,0 +1,19 @@
+#ifndef DATABASEMANAGER_H
+#define DATABASEMANAGER_H
+#include <QSqlDatabase>
+
+
+class DatabaseManager
+{
+public:
+    static DatabaseManager& getInstance();
+    QSqlDatabase& getDatabase();
+private:
+    DatabaseManager();
+    ~DatabaseManager();
+    DatabaseManager(const DatabaseManager&) = delete;
+    DatabaseManager& operator=(const DatabaseManager&) = delete;
+    QSqlDatabase db;
+};
+
+#endif // DATABASEMANAGER_H

+ 90 - 0
des3encryption.cpp

@@ -0,0 +1,90 @@
+#include "des3encryption.h"
+#include <openssl/des.h>
+Des3Encryption::Des3Encryption()
+{
+
+}
+
+QByteArray Des3Encryption::pkcs7Padding(const QByteArray& data, int blockSize) {
+    int padding = blockSize - (data.size() % blockSize);
+    QByteArray paddedData = data;
+    paddedData.append(QByteArray(padding, static_cast<char>(padding)));
+    return paddedData;
+}
+
+// PKCS#7 去填充函数
+QByteArray Des3Encryption::pkcs7Unpadding(const QByteArray& data) {
+    if (data.isEmpty()) {
+        return data;
+    }
+    int padding = static_cast<unsigned char>(data[data.size() - 1]);
+    if (padding > data.size()) {
+        return data;
+    }
+    return data.left(data.size() - padding);
+}
+
+// DES 加密函数
+QByteArray Des3Encryption::desEncrypt(const QByteArray& data, const QByteArray& key) {
+    DES_cblock desKey;
+    memcpy(desKey, key.constData(), 8);
+    DES_key_schedule schedule;
+    DES_set_key(&desKey, &schedule);
+
+    QByteArray encryptedData;
+    for (int i = 0; i < data.size(); i += 8) {
+        DES_cblock inputBlock;
+        memcpy(inputBlock, data.constData() + i, 8);
+        DES_cblock outputBlock;
+        DES_ecb_encrypt(&inputBlock, &outputBlock, &schedule, DES_ENCRYPT);
+        encryptedData.append(reinterpret_cast<const char*>(outputBlock), 8);
+    }
+    return encryptedData;
+}
+
+// DES 解密函数
+QByteArray Des3Encryption::desDecrypt(const QByteArray& data, const QByteArray& key) {
+    DES_cblock desKey;
+    memcpy(desKey, key.constData(), 8);
+    DES_key_schedule schedule;
+    DES_set_key(&desKey, &schedule);
+
+    QByteArray decryptedData;
+    for (int i = 0; i < data.size(); i += 8) {
+        DES_cblock inputBlock;
+        memcpy(inputBlock, data.constData() + i, 8);
+        DES_cblock outputBlock;
+        DES_ecb_encrypt(&inputBlock, &outputBlock, &schedule, DES_DECRYPT);
+        decryptedData.append(reinterpret_cast<const char*>(outputBlock), 8);
+    }
+    return decryptedData;
+}
+
+// 3DES 加密函数
+QByteArray Des3Encryption::des3Encrypt(const QByteArray& data, const QByteArray& key) {
+    // 将密钥填充到 24 字节
+    QByteArray paddedKey = key.leftJustified(24, '\0');
+    // 对数据进行 PKCS#7 填充
+    QByteArray paddedData = pkcs7Padding(data, 8);
+    QByteArray k1 = paddedKey.mid(0, 8);
+    QByteArray k2 = paddedKey.mid(8, 8);
+    QByteArray k3 = paddedKey.mid(16, 8);
+    QByteArray temp1 = desEncrypt(paddedData, k1);
+    QByteArray temp2 = desDecrypt(temp1, k2);
+    QByteArray encrypted = desEncrypt(temp2, k3);
+
+    return encrypted;
+}
+
+// 3DES 解密函数
+QByteArray Des3Encryption::des3Decrypt(const QByteArray& data, const QByteArray& key) {
+    // 将密钥填充到 24 字节
+    QByteArray paddedKey = key.leftJustified(24, '\0');
+    QByteArray k1 = paddedKey.mid(0, 8);
+    QByteArray k2 = paddedKey.mid(8, 8);
+    QByteArray k3 = paddedKey.mid(16, 8);
+    QByteArray temp1 = desDecrypt(data, k3);
+    QByteArray temp2 = desEncrypt(temp1, k2);
+    QByteArray decrypted = desDecrypt(temp2, k1);
+    return pkcs7Unpadding(decrypted);
+}

+ 30 - 0
des3encryption.h

@@ -0,0 +1,30 @@
+#ifndef DES3ENCRYPTION_H
+#define DES3ENCRYPTION_H
+
+#include <QByteArray>
+class Des3Encryption
+{
+public:
+    Des3Encryption();
+
+public:
+    // PKCS#7 填充函数
+    QByteArray pkcs7Padding(const QByteArray& data, int blockSize);
+
+    // PKCS#7 去填充函数
+    QByteArray pkcs7Unpadding(const QByteArray& data);
+
+    // DES 加密函数
+    QByteArray desEncrypt(const QByteArray& data, const QByteArray& key);
+
+    // DES 解密函数
+    QByteArray desDecrypt(const QByteArray& data, const QByteArray& key);
+
+    // 3DES 加密函数
+    QByteArray des3Encrypt(const QByteArray& data, const QByteArray& key);
+
+    // 3DES 解密函数
+    QByteArray des3Decrypt(const QByteArray& data, const QByteArray& key);
+};
+
+#endif // DES3ENCRYPTION_H

+ 93 - 0
detInfo/detdialog.cpp

@@ -0,0 +1,93 @@
+#include "detdialog.h"
+#include "ui_detdialog.h"
+
+DetDialog::DetDialog(QWidget *parent) :
+    QDialog(parent),
+    ui(new Ui::DetDialog)
+{
+    ui->setupUi(this);
+
+    ui->comboType->addItem("盒条码", "case");
+    ui->comboType->addItem("箱条码", "box");
+    ui->comboType->setCurrentIndex(-1);
+    ui->labFeature->clear();
+    ui->lineFeature->hide();
+
+    // 连接信号和槽
+    connect(ui->comboType, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &DetDialog::onComboTypeIndexChanged);
+    connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &DetDialog::validateInput);
+    connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &DetDialog::clearFormData);
+}
+
+
+void DetDialog::onComboTypeIndexChanged(int index)
+{
+    if (index != -1) {
+        ui->lineFeature->show();
+        QString value = ui->comboType->itemData(index).toString();
+        if (value == "case") {
+            ui->labFeature->setText("装盒标准");
+        } else if (value == "box") {
+            ui->labFeature->setText("特征码");
+        }
+    } else {
+        ui->labFeature->clear();
+        ui->lineFeature->hide();
+    }
+}
+
+
+void DetDialog::validateInput()
+{
+    QString codeType = ui->comboType->currentData().toString();
+    QString beginCode = ui->lineCode->text().trimmed();
+    QString featureorCaseCount = ui->lineFeature->text().trimmed();
+    QString count = ui->lineCount->text().trimmed();
+
+
+    if (codeType.isEmpty() || beginCode.isEmpty() || count.isEmpty()) {
+
+        QMessageBox::warning(this, "输入错误", "请填写所有必填字段。");
+        return;
+    }
+
+    QJsonObject jsonObject;
+    jsonObject["codeType"] = codeType;
+    jsonObject["beginCode"] = beginCode;
+
+    if (codeType == "case") {
+        jsonObject["inCaseCount"] = featureorCaseCount;
+    } else if (codeType == "box") {
+        jsonObject["feature"] = featureorCaseCount;
+    }
+    jsonObject["count"] = count;
+
+
+    QJsonDocument jsonDoc(jsonObject);
+    qDebug() << jsonDoc;
+
+
+    emit validateDetNum(jsonDoc);
+    clearFormData(); // 清除表单数据
+    // this->accept();
+}
+
+void DetDialog::clearFormData()
+{
+
+    QList<QLineEdit*> lineEdits = findChildren<QLineEdit*>();
+    for (QLineEdit* lineEdit : lineEdits) {
+        lineEdit->clear();
+    }
+
+
+    QList<QComboBox*> comboBoxes = findChildren<QComboBox*>();
+    for (QComboBox* comboBox : comboBoxes) {
+        comboBox->setCurrentIndex(-1);
+    }
+
+}
+DetDialog::~DetDialog()
+{
+    delete ui;
+}

+ 31 - 0
detInfo/detdialog.h

@@ -0,0 +1,31 @@
+#ifndef DETDIALOG_H
+#define DETDIALOG_H
+#include <QJsonObject>
+#include <QJsonDocument>
+#include <QDialog>
+#include <QMessageBox>
+
+namespace Ui {
+class DetDialog;
+}
+
+class DetDialog : public QDialog
+{
+    Q_OBJECT
+
+public:
+    explicit DetDialog(QWidget *parent = nullptr);
+    ~DetDialog();
+signals:
+    void validateDetNum(const QJsonDocument &jsonDoc);
+private slots:
+    void onComboTypeIndexChanged(int index);
+    void validateInput();
+private:
+    void clearFormData();
+private:
+    Ui::DetDialog *ui;
+
+};
+
+#endif // DETDIALOG_H

+ 108 - 0
detInfo/detdialog.ui

@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>DetDialog</class>
+ <widget class="QDialog" name="DetDialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>277</width>
+    <height>238</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Dialog</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <layout class="QFormLayout" name="formLayout">
+     <item row="0" column="0">
+      <widget class="QLabel" name="labType">
+       <property name="text">
+        <string>类型</string>
+       </property>
+      </widget>
+     </item>
+     <item row="1" column="0">
+      <widget class="QLabel" name="labCode">
+       <property name="text">
+        <string>条码</string>
+       </property>
+      </widget>
+     </item>
+     <item row="1" column="1">
+      <widget class="QLineEdit" name="lineCode"/>
+     </item>
+     <item row="2" column="0">
+      <widget class="QLabel" name="labCount">
+       <property name="text">
+        <string>数量</string>
+       </property>
+      </widget>
+     </item>
+     <item row="2" column="1">
+      <widget class="QLineEdit" name="lineCount"/>
+     </item>
+     <item row="3" column="0">
+      <widget class="QLabel" name="labFeature">
+       <property name="text">
+        <string>特征码</string>
+       </property>
+      </widget>
+     </item>
+     <item row="3" column="1">
+      <widget class="QLineEdit" name="lineFeature"/>
+     </item>
+     <item row="0" column="1">
+      <widget class="QComboBox" name="comboType"/>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <widget class="QDialogButtonBox" name="buttonBox">
+     <property name="orientation">
+      <enum>Qt::Orientation::Horizontal</enum>
+     </property>
+     <property name="standardButtons">
+      <set>QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>DetDialog</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>316</x>
+     <y>260</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>DetDialog</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>248</x>
+     <y>254</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>

+ 11 - 0
detInfo/detinfofactory.cpp

@@ -0,0 +1,11 @@
+#include "detinfofactory.h"
+
+DetInfoFactory::DetInfoFactory()
+{
+
+}
+
+QWidget *DetInfoFactory::createPage(QWidget *parent) const
+{
+    return new DetInfoPage(parent);
+}

+ 16 - 0
detInfo/detinfofactory.h

@@ -0,0 +1,16 @@
+#ifndef DETINFOFACTORY_H
+#define DETINFOFACTORY_H
+#include "../PageFactory.h"
+#include "detinfopage.h"
+
+
+
+
+class DetInfoFactory:public PageFactory
+{
+public:
+    DetInfoFactory();
+    QWidget* createPage(QWidget* parent) const override;
+};
+
+#endif // DETINFOFACTORY_H

+ 166 - 0
detInfo/detinfopage.cpp

@@ -0,0 +1,166 @@
+#include "detinfopage.h"
+#include "ui_detinfopage.h"
+#include <QTimer>
+
+DetInfoPage::DetInfoPage(QWidget *parent) :
+    QWidget(parent),
+    ui(new Ui::DetInfoPage)
+{
+    ui->setupUi(this);
+    m_pPageWidget = new PageWidget;
+    connect(m_pPageWidget, &PageWidget::currentPageChanged, this, &DetInfoPage::PageChanged);
+    connect(m_pPageWidget->getComboBox(), QOverload<int>::of(&QComboBox::currentIndexChanged), this, &DetInfoPage::onComboBoxIndexChanged);
+    m_httpClient = new HttpClient(this);
+    pageSize = 10;
+    currentPage = 1;
+    ui->verticalLayout_4->addWidget(m_pPageWidget);
+    loadAndRefreshData();
+    loadingDialog = new LoadingDialog(this);
+
+
+}
+void DetInfoPage::loadAndRefreshData() {
+
+    loadDataFromSource(currentPage,pageSize);
+}
+
+void DetInfoPage::loadDataFromSource(int currentPage,int pageSize,const QString& equipmentSn)
+{
+    QUrl localUrl("projectdet/pc");
+    QUrlQuery query;
+
+    query.addQueryItem("pageIndex", QString::number(currentPage));
+    query.addQueryItem("pageSize", QString::number(pageSize));
+    if (!equipmentSn.isEmpty()) {
+        query.addQueryItem("equipmentSn", equipmentSn);
+    }
+    localUrl.setQuery(query);
+    QUrl fullUrl = g_url.resolved(localUrl);
+    m_httpClient->sendHttpGetRequest(fullUrl);
+    connect(m_httpClient, &HttpClient::httpGetFinished, [this](const QJsonDocument &data) {
+        this->dataTable(data);
+    });
+}
+
+void DetInfoPage::PageChanged(int page)
+{
+    currentPage = page;
+    loadDataFromSource(currentPage,pageSize);
+}
+
+
+void DetInfoPage::onComboBoxIndexChanged(int index) {
+     QVariant variant = m_pPageWidget->getComboBox()->itemData(index);
+     int value = variant.toInt();
+     pageSize = value;
+    loadDataFromSource(currentPage,pageSize);
+
+}
+
+
+void DetInfoPage::dataTable(const QJsonDocument &jsonDoc)
+{
+    parseJsonString(jsonDoc);
+    model = new QStandardItemModel(this);
+    model->setHorizontalHeaderLabels({"工程名称", "设备编号", "管码","uid码","工作码","有效期","是否使用","创建时间"});
+    for (const QJsonValue& jsonValue : dataArray) {
+        QJsonObject jsonObj = jsonValue.toObject();
+        QList<QStandardItem*> items = jsonToItem(jsonObj);
+        model->appendRow(items);
+    }
+    ui->tableView->setModel(model);
+    ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
+    ui->tableView->setAlternatingRowColors(true);
+}
+QList<QStandardItem *> DetInfoPage::jsonToItem(const QJsonObject &jsonObj)
+{
+
+      QStandardItem* nameItem = new QStandardItem(jsonObj["name"].toString());
+      nameItem->setTextAlignment(Qt::AlignCenter);
+      QStandardItem* equipItem = new QStandardItem(jsonObj["equipmentSn"].toString());
+      QStandardItem* fbhItem = new QStandardItem(jsonObj["fbh"].toString());
+      QStandardItem* uidItem = new QStandardItem(jsonObj["uid"].toString());
+      QStandardItem* gzmItem = new QStandardItem(jsonObj["gzm"].toString());
+
+      QString yxqStr = jsonObj["yxq"].toString();
+      QDateTime yxq = QDateTime::fromString(yxqStr, Qt::ISODateWithMs);
+      QString formattedYxq = yxq.toString("yyyy-MM-dd HH:mm:ss");
+      QStandardItem* yxqItem = new QStandardItem(formattedYxq);
+      QStandardItem* isUseItem = new QStandardItem(jsonObj["isUse"].toInt());
+      QString createdAtStr = jsonObj["createdAt"].toString();
+      QDateTime createdAt = QDateTime::fromString(createdAtStr, Qt::ISODateWithMs);
+      QString formattedCreatedAt = createdAt.toString("yyyy-MM-dd HH:mm:ss");
+      QStandardItem* createdItem = new QStandardItem(formattedCreatedAt);
+
+      return QList<QStandardItem*>() << nameItem << equipItem <<fbhItem<<uidItem<<gzmItem<<yxqItem<<isUseItem<<createdItem;
+
+}
+
+
+void DetInfoPage::parseJsonString(const QJsonDocument &jsonDoc)
+{
+    QJsonObject jsonObj = jsonDoc.object();
+    QJsonObject dataObj = jsonObj["data"].toObject();
+    dataArray = dataObj["list"].toArray();
+    totalCount = dataObj["count"].toInt();
+    m_pPageWidget->setMaxPage(ceil(static_cast<double>(totalCount)/pageSize));
+}
+
+
+
+DetInfoPage::~DetInfoPage()
+{
+    delete ui;
+}
+
+void DetInfoPage::on_pushButton_clicked()
+{
+    dialog = new DetDialog;
+    dialog->setModal(false);
+    connect(dialog, &DetDialog::validateDetNum, this, &DetInfoPage::insertDet);
+    int ref = dialog->exec();
+    if (ref==QDialog::Accepted){
+
+    };
+}
+
+void DetInfoPage::insertDet(const QJsonDocument &jsonDoc){
+    QNetworkAccessManager manager;
+    QUrl localUrl("det");
+    QUrl fullUrl = g_url.resolved(localUrl);
+    QUrlQuery query;
+    if (!jsonDoc.isNull() && jsonDoc.isObject()) {
+           QJsonObject obj = jsonDoc.object();
+           for (const QString &key : obj.keys()) {
+               QJsonValue value = obj.value(key);
+               if (value.isString()) {
+                   query.addQueryItem(key, value.toString());
+               }
+           }
+       }
+    qDebug()<<""<<fullUrl;
+    fullUrl.setQuery(query);
+    QNetworkRequest request(fullUrl);
+
+    request.setRawHeader("Authorization",globalAuthority.toUtf8());
+    QNetworkReply *reply = manager.get(request);
+    // 使用事件循环等待请求完成
+    QEventLoop loop;
+    QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
+    loop.exec();
+    // 检查请求是否成功
+    if (reply->error() == QNetworkReply::NoError) {
+        // 获取响应数据
+        QByteArray responseData = reply->readAll();
+        QString responseString = QString::fromUtf8(responseData);
+        qDebug() << "Response:" << responseString;
+        loadAndRefreshData();
+    } else {
+        // 处理请求错误
+        qDebug() << "Error:" << reply->errorString();
+    }
+    // 释放资源
+    reply->deleteLater();
+
+}
+

+ 66 - 0
detInfo/detinfopage.h

@@ -0,0 +1,66 @@
+#ifndef DETINFOPAGE_H
+#define DETINFOPAGE_H
+
+#include <QWidget>
+#include <QNetworkAccessManager>
+#include <QNetworkRequest>
+#include <QNetworkReply>
+#include <QUrlQuery>
+#include <QEventLoop>
+#include <QStandardItemModel>
+#include <QJsonArray>
+#include <QJsonObject>
+#include <QJsonDocument>
+#include <QLabel>
+#include <QMoveEvent>
+#include "detdialog.h"
+#include "../global.h"
+#include "../PageWidget.h"
+#include "../HttpClient.h"
+#include "../loadingdialog.h"
+
+namespace Ui {
+class DetInfoPage;
+}
+
+class DetInfoPage : public QWidget
+{
+    Q_OBJECT
+
+public:
+    explicit DetInfoPage(QWidget *parent = nullptr);
+    ~DetInfoPage();
+    void insertDet(const QJsonDocument &jsonDoc);
+
+
+private slots:
+    void on_pushButton_clicked();
+
+
+private:
+    void loadAndRefreshData();
+    void PageChanged(int page);
+    void onComboBoxIndexChanged(int index);
+    void dataTable(const QJsonDocument &jsonDoc);
+    void loadDataFromSource(int currentPage, int pageSize, const QString& equipmentSn="");
+    QList<QStandardItem *> jsonToItem(const QJsonObject &jsonObj);
+    void parseJsonString(const QJsonDocument &jsonDoc);
+
+private:
+    Ui::DetInfoPage *ui;
+    DetDialog *dialog;
+    PageWidget *m_pPageWidget;
+    int pageSize;  //每页显示的记录数量
+    int currentPage;      //当前页面
+    int totalCount;
+    QString *equipmentSn;
+    HttpClient *m_httpClient;
+    QStandardItemModel *model;
+    QJsonArray dataArray;
+    QLabel *loadingLabel;  // 用于显示加载图片的标签
+    LoadingDialog *loadingDialog; // 新增成员变量
+    QPoint lastPos;
+
+};
+
+#endif // DETINFOPAGE_H

+ 144 - 0
detInfo/detinfopage.ui

@@ -0,0 +1,144 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>DetInfoPage</class>
+ <widget class="QWidget" name="DetInfoPage">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>836</width>
+    <height>490</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <property name="styleSheet">
+   <string notr="true">QPushButton {
+    background-color: #4CAF50;
+    color: white;
+    border: 2px solid #4CAF50;
+    border-radius: 5px;
+    padding: 5px;
+}</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <widget class="QFrame" name="searchBox">
+     <property name="maximumSize">
+      <size>
+       <width>16777215</width>
+       <height>50</height>
+      </size>
+     </property>
+     <property name="frameShape">
+      <enum>QFrame::Shape::StyledPanel</enum>
+     </property>
+     <property name="frameShadow">
+      <enum>QFrame::Shadow::Raised</enum>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QFrame" name="btnBox">
+     <property name="minimumSize">
+      <size>
+       <width>0</width>
+       <height>50</height>
+      </size>
+     </property>
+     <property name="maximumSize">
+      <size>
+       <width>16777215</width>
+       <height>50</height>
+      </size>
+     </property>
+     <property name="frameShape">
+      <enum>QFrame::Shape::StyledPanel</enum>
+     </property>
+     <property name="frameShadow">
+      <enum>QFrame::Shadow::Raised</enum>
+     </property>
+     <layout class="QHBoxLayout" name="horizontalLayout">
+      <item>
+       <spacer name="horizontalSpacer">
+        <property name="orientation">
+         <enum>Qt::Orientation::Horizontal</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>920</width>
+          <height>20</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+      <item>
+       <widget class="QPushButton" name="pushButton">
+        <property name="text">
+         <string>创建</string>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <widget class="QFrame" name="dataWidget">
+     <property name="frameShape">
+      <enum>QFrame::Shape::StyledPanel</enum>
+     </property>
+     <property name="frameShadow">
+      <enum>QFrame::Shadow::Raised</enum>
+     </property>
+     <layout class="QVBoxLayout" name="verticalLayout_3">
+      <item>
+       <widget class="QTableView" name="tableView"/>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <widget class="QFrame" name="pagination">
+     <property name="minimumSize">
+      <size>
+       <width>0</width>
+       <height>30</height>
+      </size>
+     </property>
+     <property name="maximumSize">
+      <size>
+       <width>16777215</width>
+       <height>30</height>
+      </size>
+     </property>
+     <property name="frameShape">
+      <enum>QFrame::Shape::StyledPanel</enum>
+     </property>
+     <property name="frameShadow">
+      <enum>QFrame::Shadow::Raised</enum>
+     </property>
+     <layout class="QVBoxLayout" name="verticalLayout_4">
+      <property name="spacing">
+       <number>0</number>
+      </property>
+      <property name="leftMargin">
+       <number>0</number>
+      </property>
+      <property name="topMargin">
+       <number>0</number>
+      </property>
+      <property name="rightMargin">
+       <number>0</number>
+      </property>
+      <property name="bottomMargin">
+       <number>0</number>
+      </property>
+     </layout>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>

+ 11 - 0
equipment/equipmentfactory.cpp

@@ -0,0 +1,11 @@
+#include "equipmentfactory.h"
+
+EquipmentFactory::EquipmentFactory()
+{
+
+}
+
+QWidget *EquipmentFactory::createPage(QWidget *parent) const
+{
+    return new EquipmentPage(parent);
+}

+ 13 - 0
equipment/equipmentfactory.h

@@ -0,0 +1,13 @@
+#ifndef EQUIPMENTFACTORY_H
+#define EQUIPMENTFACTORY_H
+#include "../PageFactory.h"
+#include "equipmentpage.h"
+
+class EquipmentFactory: public PageFactory
+{
+public:
+    EquipmentFactory();
+    QWidget* createPage(QWidget* parent) const override;
+};
+
+#endif // EQUIPMENTFACTORY_H

+ 120 - 0
equipment/equipmentpage.cpp

@@ -0,0 +1,120 @@
+#include "equipmentpage.h"
+#include "ui_equipmentpage.h"
+#include "../global.h"
+
+EquipmentPage::EquipmentPage(QWidget *parent) :
+    QWidget(parent),
+    ui(new Ui::EquipmentPage)
+{
+    ui->setupUi(this);
+    m_pPageWidget = new PageWidget;
+    connect(m_pPageWidget, &PageWidget::currentPageChanged, this, &EquipmentPage::PageChanged);
+    connect(m_pPageWidget->getComboBox(), QOverload<int>::of(&QComboBox::currentIndexChanged), this, &EquipmentPage::onComboBoxIndexChanged);
+    m_httpClient = new HttpClient(this);
+    pageSize = 10;
+    currentPage = 1;
+    ui->verticalLayout_4->addWidget(m_pPageWidget);
+    loadAndRefreshData();
+}
+
+
+
+
+void EquipmentPage::on_btnSearch_clicked()
+{
+    QString equipmentSn = ui->editSn->text();
+    loadDataFromSource(currentPage, pageSize, equipmentSn);
+}
+
+
+void EquipmentPage::loadAndRefreshData() {
+    loadDataFromSource(currentPage,pageSize);
+}
+
+void EquipmentPage::loadDataFromSource(int currentPage,int pageSize,const QString& equipmentSn)
+{
+    QUrl localUrl("equipment/pc");
+
+    QUrlQuery query;
+    query.addQueryItem("pageIndex", QString::number(currentPage));
+    query.addQueryItem("pageSize", QString::number(pageSize));
+    if (!equipmentSn.isEmpty()) {
+        query.addQueryItem("equipmentSn", equipmentSn);
+    }
+    localUrl.setQuery(query);
+    QUrl fullUrl = g_url.resolved(localUrl);
+    m_httpClient->sendHttpGetRequest(fullUrl);
+
+    connect(m_httpClient, &HttpClient::httpGetFinished, [this](const QJsonDocument &data) {
+        this->dataTable(data);
+
+    });
+}
+
+void EquipmentPage::PageChanged(int page)
+{
+    currentPage = page;
+    loadDataFromSource(currentPage,pageSize);
+}
+
+
+void EquipmentPage::onComboBoxIndexChanged(int index) {
+     QVariant variant = m_pPageWidget->getComboBox()->itemData(index);
+     int value = variant.toInt();
+     pageSize = value;
+    loadDataFromSource(currentPage,pageSize);
+
+}
+
+
+void EquipmentPage::dataTable(const QJsonDocument &jsonDoc)
+{
+    parseJsonString(jsonDoc);
+    model = new QStandardItemModel(this);
+    model->setHorizontalHeaderLabels({"名称", "设备编号", "设备类型","设备状态","在线状态","创建时间"});
+
+    for (const QJsonValue& jsonValue : dataArray) {
+        QJsonObject jsonObj = jsonValue.toObject();
+        QList<QStandardItem*> items = jsonToItem(jsonObj);
+        model->appendRow(items);
+    }
+
+    ui->tableView->setModel(model);
+    ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
+    ui->tableView->setAlternatingRowColors(true);
+
+}
+
+QList<QStandardItem *> EquipmentPage::jsonToItem(const QJsonObject &jsonObj)
+{
+
+      QStandardItem* nameItem = new QStandardItem(jsonObj["name"].toString());
+      nameItem->setTextAlignment(Qt::AlignCenter);
+      QStandardItem* equipItem = new QStandardItem(jsonObj["equipmentSn"].toString());
+      QStandardItem* typeItem = new QStandardItem(jsonObj["equipmentTypeName"].toString());
+      QStandardItem* statusItem = new QStandardItem(jsonObj["statusName"].toString());
+      QStandardItem* onlineItem = new QStandardItem(jsonObj["onlineName"].toString());
+      QString createdAtStr = jsonObj["createdAt"].toString();
+      QDateTime createdAt = QDateTime::fromString(createdAtStr, Qt::ISODateWithMs);
+      QString formattedCreatedAt = createdAt.toString("yyyy-MM-dd HH:mm:ss");
+      QStandardItem* createdItem = new QStandardItem(formattedCreatedAt);
+
+      return QList<QStandardItem*>() << nameItem << equipItem << typeItem<<statusItem<<onlineItem<<createdItem;
+
+}
+
+
+void EquipmentPage::parseJsonString(const QJsonDocument &jsonDoc)
+{
+    QJsonObject jsonObj = jsonDoc.object();
+    QJsonObject dataObj = jsonObj["data"].toObject();
+    dataArray = dataObj["list"].toArray();
+    totalCount = dataObj["count"].toInt();
+    m_pPageWidget->setMaxPage(ceil(static_cast<double>(totalCount)/pageSize));
+}
+
+
+EquipmentPage::~EquipmentPage()
+{
+    delete ui;
+}

+ 49 - 0
equipment/equipmentpage.h

@@ -0,0 +1,49 @@
+#ifndef EQUIPMENTPAGE_H
+#define EQUIPMENTPAGE_H
+
+#include <QWidget>
+#include <QStandardItemModel>
+#include <QJsonArray>
+#include <QJsonObject>
+#include <QJsonDocument>
+#include "../buttondelegate.h"
+#include "../HttpClient.h"
+#include "../PageWidget.h"
+
+namespace Ui {
+class EquipmentPage;
+}
+
+class EquipmentPage : public QWidget
+{
+    Q_OBJECT
+
+public:
+    explicit EquipmentPage(QWidget *parent = nullptr);
+    ~EquipmentPage();
+private slots:
+    void on_btnSearch_clicked();
+
+private:
+    void parseJsonString(const QJsonDocument& jsonDoc);
+    void dataTable( const QJsonDocument& jsonDoc);
+    void loadAndRefreshData();
+    void loadDataFromSource(int currentPage, int pageSize,const QString& equipmentSn="");
+    void PageChanged(int page);
+    void onComboBoxIndexChanged(int index);
+    QList<QStandardItem*> jsonToItem(const QJsonObject& jsonObj);
+
+private:
+    Ui::EquipmentPage *ui;
+    PageWidget *m_pPageWidget;
+    int pageSize;  //每页显示的记录数量
+    int currentPage;      //当前页面
+    int totalCount;
+    QString *equipmentSn;
+    HttpClient *m_httpClient;
+    QStandardItemModel *model;
+    QJsonArray dataArray;
+
+};
+
+#endif // EQUIPMENTPAGE_H

+ 264 - 0
equipment/equipmentpage.ui

@@ -0,0 +1,264 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>EquipmentPage</class>
+ <widget class="QWidget" name="EquipmentPage">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>914</width>
+    <height>614</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <property name="styleSheet">
+   <string notr="true">QPushButton {
+    background-color: #4CAF50;
+    color: white;
+    border: 2px solid #4CAF50;
+    border-radius: 5px;
+    padding: 5px;
+}
+
+#frame 
+{ border: none; }
+
+#frame_2
+{ border: none; }
+
+
+       QLineEdit {
+            border: none;  // 去掉边框(下划线)
+            background-color: #f0f0f0; // 设置灰色背景色,#f0f0f0 可根据网站设计调整
+            padding: 5px; // 内边距,让文本不紧贴边框
+        }
+        // 获取焦点时的样式
+        QLineEdit:focus {
+            border: 2px solid #0078d4;  // 点击输入时显示 2px 宽的蓝色边框,#0078d4 可根据设计调整
+        }</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <widget class="QFrame" name="searchBox">
+     <property name="minimumSize">
+      <size>
+       <width>0</width>
+       <height>50</height>
+      </size>
+     </property>
+     <property name="maximumSize">
+      <size>
+       <width>16777215</width>
+       <height>50</height>
+      </size>
+     </property>
+     <property name="frameShape">
+      <enum>QFrame::Shape::StyledPanel</enum>
+     </property>
+     <property name="frameShadow">
+      <enum>QFrame::Shadow::Raised</enum>
+     </property>
+     <layout class="QHBoxLayout" name="horizontalLayout">
+      <property name="spacing">
+       <number>0</number>
+      </property>
+      <property name="leftMargin">
+       <number>0</number>
+      </property>
+      <property name="topMargin">
+       <number>0</number>
+      </property>
+      <property name="rightMargin">
+       <number>0</number>
+      </property>
+      <property name="bottomMargin">
+       <number>0</number>
+      </property>
+      <item>
+       <widget class="QFrame" name="frame_2">
+        <property name="minimumSize">
+         <size>
+          <width>0</width>
+          <height>50</height>
+         </size>
+        </property>
+        <property name="frameShape">
+         <enum>QFrame::Shape::StyledPanel</enum>
+        </property>
+        <property name="frameShadow">
+         <enum>QFrame::Shadow::Raised</enum>
+        </property>
+        <layout class="QHBoxLayout" name="horizontalLayout_3">
+         <item>
+          <widget class="QLabel" name="labSn">
+           <property name="minimumSize">
+            <size>
+             <width>60</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>60</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="text">
+            <string>设备编号:</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QLineEdit" name="editSn">
+           <property name="minimumSize">
+            <size>
+             <width>100</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>100</width>
+             <height>16777215</height>
+            </size>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <spacer name="horizontalSpacer">
+           <property name="orientation">
+            <enum>Qt::Orientation::Horizontal</enum>
+           </property>
+           <property name="sizeHint" stdset="0">
+            <size>
+             <width>601</width>
+             <height>20</height>
+            </size>
+           </property>
+          </spacer>
+         </item>
+        </layout>
+       </widget>
+      </item>
+      <item alignment="">
+       <widget class="QFrame" name="frame">
+        <property name="minimumSize">
+         <size>
+          <width>100</width>
+          <height>50</height>
+         </size>
+        </property>
+        <property name="maximumSize">
+         <size>
+          <width>100</width>
+          <height>50</height>
+         </size>
+        </property>
+        <property name="frameShape">
+         <enum>QFrame::Shape::StyledPanel</enum>
+        </property>
+        <property name="frameShadow">
+         <enum>QFrame::Shadow::Raised</enum>
+        </property>
+        <layout class="QHBoxLayout" name="horizontalLayout_2" stretch="0">
+         <property name="spacing">
+          <number>0</number>
+         </property>
+         <property name="leftMargin">
+          <number>0</number>
+         </property>
+         <property name="topMargin">
+          <number>0</number>
+         </property>
+         <property name="rightMargin">
+          <number>9</number>
+         </property>
+         <property name="bottomMargin">
+          <number>0</number>
+         </property>
+         <item>
+          <widget class="QPushButton" name="btnSearch">
+           <property name="text">
+            <string>查询</string>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <widget class="QFrame" name="dataWidget">
+     <property name="frameShape">
+      <enum>QFrame::Shape::StyledPanel</enum>
+     </property>
+     <property name="frameShadow">
+      <enum>QFrame::Shadow::Raised</enum>
+     </property>
+     <layout class="QVBoxLayout" name="verticalLayout_3">
+      <property name="leftMargin">
+       <number>0</number>
+      </property>
+      <property name="topMargin">
+       <number>0</number>
+      </property>
+      <property name="rightMargin">
+       <number>0</number>
+      </property>
+      <property name="bottomMargin">
+       <number>0</number>
+      </property>
+      <item>
+       <widget class="QTableView" name="tableView"/>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <widget class="QFrame" name="pagination">
+     <property name="minimumSize">
+      <size>
+       <width>0</width>
+       <height>30</height>
+      </size>
+     </property>
+     <property name="maximumSize">
+      <size>
+       <width>16777215</width>
+       <height>30</height>
+      </size>
+     </property>
+     <property name="frameShape">
+      <enum>QFrame::Shape::StyledPanel</enum>
+     </property>
+     <property name="frameShadow">
+      <enum>QFrame::Shadow::Raised</enum>
+     </property>
+     <layout class="QVBoxLayout" name="verticalLayout_4">
+      <property name="spacing">
+       <number>0</number>
+      </property>
+      <property name="leftMargin">
+       <number>0</number>
+      </property>
+      <property name="topMargin">
+       <number>0</number>
+      </property>
+      <property name="rightMargin">
+       <number>0</number>
+      </property>
+      <property name="bottomMargin">
+       <number>0</number>
+      </property>
+     </layout>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>

+ 11 - 0
equipmentfactory.cpp

@@ -0,0 +1,11 @@
+#include "equipmentfactory.h"
+
+EquipmentFactory::EquipmentFactory()
+{
+
+}
+
+QWidget *EquipmentFactory::createPage(QWidget *parent) const
+{
+    return new EquipmentPage(parent);
+}

+ 13 - 0
equipmentfactory.h

@@ -0,0 +1,13 @@
+#ifndef EQUIPMENTFACTORY_H
+#define EQUIPMENTFACTORY_H
+#include "PageFactory.h"
+#include "equipmentpage.h"
+
+class EquipmentFactory: public PageFactory
+{
+public:
+    EquipmentFactory();
+    QWidget* createPage(QWidget* parent) const override;
+};
+
+#endif // EQUIPMENTFACTORY_H

+ 119 - 0
equipmentpage.cpp

@@ -0,0 +1,119 @@
+#include "equipmentpage.h"
+#include "ui_equipmentpage.h"
+#include "../global.h"
+
+EquipmentPage::EquipmentPage(QWidget *parent) :
+    QWidget(parent),
+    ui(new Ui::EquipmentPage)
+{
+    ui->setupUi(this);
+    m_pPageWidget = new PageWidget;
+    connect(m_pPageWidget, &PageWidget::currentPageChanged, this, &EquipmentPage::PageChanged);
+    connect(m_pPageWidget->getComboBox(), QOverload<int>::of(&QComboBox::currentIndexChanged), this, &EquipmentPage::onComboBoxIndexChanged);
+    m_httpClient = new HttpClient(this);
+    pageSize = 10;
+    currentPage = 1;
+    ui->verticalLayout_4->addWidget(m_pPageWidget);
+    loadAndRefreshData();
+}
+
+
+void EquipmentPage::loadAndRefreshData() {
+    loadDataFromSource(currentPage,pageSize);
+}
+
+void EquipmentPage::loadDataFromSource(int currentPage,int pageSize)
+{
+    QUrl localUrl("equipment/pc");
+
+    QUrlQuery query;
+    // 添加新的参数到 QUrlQuery
+    query.addQueryItem("pageIndex", QString::number(currentPage));
+    query.addQueryItem("pageSize", QString::number(pageSize));
+
+    // 再次将查询参数设置到 QUrl 对象中
+    localUrl.setQuery(query);
+
+    qDebug() << localUrl.toString();
+    QUrl fullUrl = g_url.resolved(localUrl);
+    m_httpClient->sendHttpGetRequest(fullUrl);
+    // // 连接信号到槽,以便处理请求结果或错误
+    connect(m_httpClient, &HttpClient::httpGetFinished, [this](const QJsonDocument &data) {
+        this->dataTable(data);
+
+    });
+}
+
+void EquipmentPage::PageChanged(int page)
+{
+    currentPage = page;
+    loadDataFromSource(currentPage,pageSize);
+}
+
+
+void EquipmentPage::onComboBoxIndexChanged(int index) {
+    // 获取当前选中的文本
+     QVariant variant = m_pPageWidget->getComboBox()->itemData(index);
+     int value = variant.toInt();
+     pageSize = value;
+    loadDataFromSource(currentPage,pageSize);
+
+}
+
+
+void EquipmentPage::dataTable(const QJsonDocument &jsonDoc)
+{
+    parseJsonString(jsonDoc);
+    model = new QStandardItemModel(this);
+    model->setHorizontalHeaderLabels({"名称", "设备编号", "设备类型","设备状态","在线状态","创建时间"});
+
+    // 遍历 JSON 数组,将其转换为 QStandardItemModel
+    for (const QJsonValue& jsonValue : dataArray) {
+        QJsonObject jsonObj = jsonValue.toObject();
+        QList<QStandardItem*> items = jsonToItem(jsonObj);
+        model->appendRow(items);
+    }
+
+    // // 设置 QTableView 的 model
+    ui->tableView->setModel(model);
+    ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
+    ui->tableView->setAlternatingRowColors(true);  // 启用交替行颜色
+
+}
+
+QList<QStandardItem *> EquipmentPage::jsonToItem(const QJsonObject &jsonObj)
+{
+
+    // 创建一个 QStandardItem
+      QStandardItem* nameItem = new QStandardItem(jsonObj["name"].toString());
+      nameItem->setTextAlignment(Qt::AlignCenter);
+      QStandardItem* equipItem = new QStandardItem(jsonObj["equipmentSn"].toString());
+      QStandardItem* typeItem = new QStandardItem(jsonObj["equipmentTypeName"].toString());
+      QStandardItem* statusItem = new QStandardItem(jsonObj["statusName"].toString());
+      QStandardItem* onlineItem = new QStandardItem(jsonObj["onlineName"].toString());
+      // 处理 createdAt 字段
+      QString createdAtStr = jsonObj["createdAt"].toString();
+      QDateTime createdAt = QDateTime::fromString(createdAtStr, Qt::ISODateWithMs);
+      QString formattedCreatedAt = createdAt.toString("yyyy-MM-dd HH:mm:ss");
+      QStandardItem* createdItem = new QStandardItem(formattedCreatedAt);
+
+      return QList<QStandardItem*>() << nameItem << equipItem << typeItem<<statusItem<<onlineItem<<createdItem;
+
+}
+
+
+void EquipmentPage::parseJsonString(const QJsonDocument &jsonDoc)
+{
+    QJsonObject jsonObj = jsonDoc.object();
+    QJsonObject dataObj = jsonObj["data"].toObject();
+    dataArray = dataObj["list"].toArray();
+    totalCount = dataObj["count"].toInt();
+    m_pPageWidget->setMaxPage(ceil(static_cast<double>(totalCount)/pageSize));
+    // qDebug()<<"Row data"<<dataObj["count"].toInt();
+}
+
+
+EquipmentPage::~EquipmentPage()
+{
+    delete ui;
+}

+ 22 - 0
equipmentpage.h

@@ -0,0 +1,22 @@
+#ifndef EQUIPMENTPAGE_H
+#define EQUIPMENTPAGE_H
+
+#include <QWidget>
+
+namespace Ui {
+class EquipmentPage;
+}
+
+class EquipmentPage : public QWidget
+{
+    Q_OBJECT
+
+public:
+    explicit EquipmentPage(QWidget *parent = nullptr);
+    ~EquipmentPage();
+
+private:
+    Ui::EquipmentPage *ui;
+};
+
+#endif // EQUIPMENTPAGE_H

+ 135 - 0
equipmentpage.ui

@@ -0,0 +1,135 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>EquipmentPage</class>
+ <widget class="QWidget" name="EquipmentPage">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>700</width>
+    <height>477</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <widget class="QFrame" name="searchBox">
+     <property name="maximumSize">
+      <size>
+       <width>16777215</width>
+       <height>50</height>
+      </size>
+     </property>
+     <property name="frameShape">
+      <enum>QFrame::Shape::StyledPanel</enum>
+     </property>
+     <property name="frameShadow">
+      <enum>QFrame::Shadow::Raised</enum>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QFrame" name="btnBox">
+     <property name="minimumSize">
+      <size>
+       <width>0</width>
+       <height>50</height>
+      </size>
+     </property>
+     <property name="maximumSize">
+      <size>
+       <width>16777215</width>
+       <height>50</height>
+      </size>
+     </property>
+     <property name="frameShape">
+      <enum>QFrame::Shape::StyledPanel</enum>
+     </property>
+     <property name="frameShadow">
+      <enum>QFrame::Shadow::Raised</enum>
+     </property>
+     <layout class="QHBoxLayout" name="horizontalLayout">
+      <item>
+       <spacer name="horizontalSpacer">
+        <property name="orientation">
+         <enum>Qt::Orientation::Horizontal</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>920</width>
+          <height>20</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+      <item>
+       <widget class="QPushButton" name="pushButton">
+        <property name="text">
+         <string>创建</string>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <widget class="QFrame" name="dataWidget">
+     <property name="frameShape">
+      <enum>QFrame::Shape::StyledPanel</enum>
+     </property>
+     <property name="frameShadow">
+      <enum>QFrame::Shadow::Raised</enum>
+     </property>
+     <layout class="QVBoxLayout" name="verticalLayout_3">
+      <item>
+       <widget class="QTableView" name="tableView"/>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <widget class="QFrame" name="pagination">
+     <property name="minimumSize">
+      <size>
+       <width>0</width>
+       <height>30</height>
+      </size>
+     </property>
+     <property name="maximumSize">
+      <size>
+       <width>16777215</width>
+       <height>30</height>
+      </size>
+     </property>
+     <property name="frameShape">
+      <enum>QFrame::Shape::StyledPanel</enum>
+     </property>
+     <property name="frameShadow">
+      <enum>QFrame::Shadow::Raised</enum>
+     </property>
+     <layout class="QVBoxLayout" name="verticalLayout_4">
+      <property name="spacing">
+       <number>0</number>
+      </property>
+      <property name="leftMargin">
+       <number>0</number>
+      </property>
+      <property name="topMargin">
+       <number>0</number>
+      </property>
+      <property name="rightMargin">
+       <number>0</number>
+      </property>
+      <property name="bottomMargin">
+       <number>0</number>
+      </property>
+     </layout>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>

+ 135 - 0
equipmnentpage.ui

@@ -0,0 +1,135 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>EquipmnentPage</class>
+ <widget class="QWidget" name="EquipmnentPage">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>735</width>
+    <height>473</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <widget class="QFrame" name="searchBox">
+     <property name="maximumSize">
+      <size>
+       <width>16777215</width>
+       <height>50</height>
+      </size>
+     </property>
+     <property name="frameShape">
+      <enum>QFrame::Shape::StyledPanel</enum>
+     </property>
+     <property name="frameShadow">
+      <enum>QFrame::Shadow::Raised</enum>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QFrame" name="btnBox">
+     <property name="minimumSize">
+      <size>
+       <width>0</width>
+       <height>50</height>
+      </size>
+     </property>
+     <property name="maximumSize">
+      <size>
+       <width>16777215</width>
+       <height>50</height>
+      </size>
+     </property>
+     <property name="frameShape">
+      <enum>QFrame::Shape::StyledPanel</enum>
+     </property>
+     <property name="frameShadow">
+      <enum>QFrame::Shadow::Raised</enum>
+     </property>
+     <layout class="QHBoxLayout" name="horizontalLayout">
+      <item>
+       <spacer name="horizontalSpacer">
+        <property name="orientation">
+         <enum>Qt::Orientation::Horizontal</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>920</width>
+          <height>20</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+      <item>
+       <widget class="QPushButton" name="pushButton">
+        <property name="text">
+         <string>创建</string>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <widget class="QFrame" name="dataWidget">
+     <property name="frameShape">
+      <enum>QFrame::Shape::StyledPanel</enum>
+     </property>
+     <property name="frameShadow">
+      <enum>QFrame::Shadow::Raised</enum>
+     </property>
+     <layout class="QVBoxLayout" name="verticalLayout_3">
+      <item>
+       <widget class="QTableView" name="tableView"/>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <widget class="QFrame" name="pagination">
+     <property name="minimumSize">
+      <size>
+       <width>0</width>
+       <height>30</height>
+      </size>
+     </property>
+     <property name="maximumSize">
+      <size>
+       <width>16777215</width>
+       <height>30</height>
+      </size>
+     </property>
+     <property name="frameShape">
+      <enum>QFrame::Shape::StyledPanel</enum>
+     </property>
+     <property name="frameShadow">
+      <enum>QFrame::Shadow::Raised</enum>
+     </property>
+     <layout class="QVBoxLayout" name="verticalLayout_4">
+      <property name="spacing">
+       <number>0</number>
+      </property>
+      <property name="leftMargin">
+       <number>0</number>
+      </property>
+      <property name="topMargin">
+       <number>0</number>
+      </property>
+      <property name="rightMargin">
+       <number>0</number>
+      </property>
+      <property name="bottomMargin">
+       <number>0</number>
+      </property>
+     </layout>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>

+ 636 - 0
fireWidget/firingwidget.cpp

@@ -0,0 +1,636 @@
+#include "firingwidget.h"
+#include "ui_firingwidget.h"
+#include "../countdownwidget.h"
+#include <QNetworkAccessManager>
+#include <QNetworkRequest>
+#include <QNetworkReply>
+#include <QUrl>
+#include <QUrlQuery>
+#include <QJsonDocument>
+#include <QJsonObject>
+#include <QJsonArray>
+#include <QDebug>
+#include <QSqlQuery>
+#include "../global.h"
+#define ANSI_COLOR_GREEN "\x1B[32m"
+#define ANSI_COLOR_RESET "\x1B[0m"
+
+firingWidget::firingWidget(const int& row,const bool& select,const QString& uuid,QWidget *parent) :
+    QWidget(parent),
+    ui(new Ui::firingWidget),
+    m_uuid(uuid),
+    m_row(row),
+    m_select(select),
+    dao(DatabaseManager::getInstance().getDatabase()),
+    daoDet(DatabaseManager::getInstance().getDatabase()),
+    daoReg(DatabaseManager::getInstance().getDatabase())
+{
+    ui->setupUi(this);
+
+    ui->pushButton_2->setText("立即测试");
+    ui->textEdit->setStyleSheet("border: none;background: transparent;");
+    ui->frame_2->setStyleSheet("border: none;background: transparent;");
+    QFrame *frame = ui->frame_2;  // 使用你为 QFrame 设置的对象名称
+    navProgress = new NavProgress(frame);
+    ui->verticalLayout->setContentsMargins(0, 30, 0, 0);
+    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"};
+    mqttThread->setConnectionInfo("114.55.233.194", 1883, "hxgc", "hxgc123456", "P"+uuid, topics);
+    connect(mqttThread, &MqttThread::mqttConnected, this, &firingWidget::onMqttConnected);
+    mqttThread->start();
+    connect(mqttThread, &MqttThread::messageAndTopicReceived, this, &firingWidget::handleMessageAndTopic);
+
+    connect(this, &firingWidget::lastStageChanged, this, &firingWidget::onLastStageChanged);
+
+    startBlasting();
+}
+
+
+
+firingWidget::~firingWidget()
+{
+    delete ui;
+}
+
+
+
+void firingWidget::sendMqttMessage(const QString& topic, const QByteArray& message)
+{
+
+    if (mqttThread  && m_isMqttConnected) {
+        emit mqttThread->sendMessageRequested(topic, message);
+    } else {
+        qDebug() << "MQTT 未连接,无法发送消息";
+    }
+}
+
+void firingWidget::startBlasting()
+{
+
+     QTimer::singleShot(1000, this, [this]() {
+         lastStage=0;
+         emit lastStageChanged(0);
+     });
+
+}
+
+
+
+void firingWidget::on_pushButton_2_clicked(){
+    emit countdown(m_uuid,topic,"message");
+}
+
+
+
+bool firingWidget::danUpload(const QJsonObject& jsonObj){
+
+   QString htid = jsonObj["project_htid"].toString();
+   QString htm = ""; //
+   QString xmbh = jsonObj["project_xmbh"].toString();
+   QString sbbh = jsonObj["equipment_sn"].toString();
+   QString bprysfz = jsonObj["operator_identity"].toString();
+   QString dwdm = jsonObj["company_code"].toString();
+   QString xtm = ""; //
+   QString jd = jsonObj["blast_longitude"].toString();
+   QString bpsj = jsonObj["blast_time"].toString();
+   QString wd = jsonObj["blast_latitude"].toString();
+   QStringList uidList;
+   QJsonArray regs = jsonObj["regs"].toArray();
+   for (const auto& reg : regs) {
+       QJsonObject regObj = reg.toObject();
+       QJsonArray dets = regObj["dets"].toArray();
+       for (const auto& det : dets) {
+           QJsonObject detObj = det.toObject();
+           uidList.append(detObj["uid"].toString());
+       }
+   }
+   QString uid = uidList.join(",");
+
+   QString plainText = QString("{\"htid\":\"%1\",\"htm\":\"%2\",\"xmbh\":\"%3\",\"sbbh\":\"%4\","
+                             "\"bprysfz\":\"%5\",\"dwdm\":\"%6\",\"xtm\":\"%7\",\"jd\":\"%8\","
+                             "\"bpsj\":\"%9\",\"wd\":\"%10\",\"uid\":\"%11\"}")
+                     .arg(htid)
+                     .arg(htm)
+                     .arg(xmbh)
+                     .arg(sbbh)
+                     .arg(bprysfz)
+                     .arg(dwdm)
+                     .arg(xtm)
+                     .arg(jd)
+                     .arg(bpsj)
+                     .arg(wd)
+                     .arg(uid);
+    Des3Encryption des3;
+    QByteArray key = "jadl12345678912345678912";
+    QByteArray encryptedData = des3.des3Encrypt(plainText.toUtf8(), key);
+    QByteArray base64Encoded = encryptedData.toBase64();
+    QString encodedJson = QUrl::toPercentEncoding(base64Encoded);
+    QString baseUrl = "http://test.mbdzlg.com/mbdzlgtxzx/servlet/DzlgSysbJsonServlert";
+    QUrl url(baseUrl);
+    QUrlQuery query;
+    query.addQueryItem("param", encodedJson);
+    url.setQuery(query);
+
+    QNetworkAccessManager manager;
+    QNetworkRequest request(url);
+    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
+    QByteArray postData;
+    QNetworkReply *reply = manager.post(request,postData);
+    QEventLoop loop;
+    QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
+    loop.exec();
+    if (reply->error() == QNetworkReply::NoError) {
+        QByteArray responseData = reply->readAll();
+        qDebug() << "Response:" << QString(responseData);
+    } else {
+        qDebug() << "Error:" << reply->errorString();
+    }
+    reply->deleteLater();
+    return true;
+}
+
+bool firingWidget::addRegData(const QJsonObject& jsonObj) {
+    QJsonArray regsArray = jsonObj["regs"].toArray();
+    for (const auto& regValue : regsArray) {
+        QJsonObject regObj = regValue.toObject();
+        HBlastRegRecord recordReg;
+        reg_uuid = QUuid::createUuid().toString(QUuid::WithoutBraces).remove(QRegularExpression("-"));
+        recordReg.setUuid(reg_uuid);
+        recordReg.setEquipSn(regObj["equipment_sn"].toString());
+        recordReg.setEquipVersion(regObj["equipment_version"].toString());
+        recordReg.setRegDetoCount(regObj["reg_deto_count"].toInt());
+        recordReg.setErrorDetoCount(regObj["error_deto_count"].toInt());
+        recordReg.setAfterTestBusV(regObj["after_test_bus_v"].toString());
+        recordReg.setAfterTestBusI(regObj["after_test_bus_i"].toString());
+        recordReg.setBusLeakageCurrentI(regObj["bus_leakage_current_i"].toString());
+        recordReg.setNetChargedV(regObj["net_charged_v"].toString());
+        recordReg.setNetChargedI(regObj["net_charged_i"].toString());
+        recordReg.setBeforeBlastingV(regObj["before_blasting_v"].toString());
+        recordReg.setBeforeBlastingI(regObj["before_blasting_i"].toString());
+        recordReg.setRecordUuid(blast_uuid);
+        recordReg.setCreatedAt(QDateTime::currentDateTime());
+        // 插入数据到数据库
+        if (!daoReg.addHBlastRegRecord(recordReg)) {
+            return false;
+        } else {
+        }
+    }
+    return true;
+}
+
+bool firingWidget::addDetData(const QJsonObject& jsonObj) {
+    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)) {
+                return false;
+            }
+        }
+    }
+    return true;
+}
+
+void firingWidget::handleMessageAndTopic(const QByteArray &message, const QMqttTopicName &topic)
+{
+
+    QString msgText = QString("Topic: %1, Message: %2").arg(topic.name(), QString(message));
+    QTextEdit *textEdit = ui->scrollAreaWidgetContents->findChild<QTextEdit*>("textEdit");
+    if (textEdit) {
+        textEdit->append(msgText);
+    }
+    int stage = 0;
+    QJsonDocument jsonDoc = QJsonDocument::fromJson(message);
+    if (!jsonDoc.isNull() && jsonDoc.isObject()) {
+        QJsonObject jsonObj = jsonDoc.object();
+        if (jsonObj.contains("type") && jsonObj["type"].toInt() == 1) {
+            if (jsonObj.contains("data") && jsonObj["data"].isObject()) {
+                QJsonObject dataObject = jsonObj["data"].toObject();
+                stage = dataObject["stage"].toInt();
+                if (stage != lastStage) {
+                    lastStage = stage;
+                    emit lastStageChanged(lastStage);
+                    switch (stage) {
+                        case 0:
+                            navProgress->setState(0);
+                            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);
+                            ui->pushButton_2->setText("立即测试");
+                            ui->pushButton_2->setEnabled(false);
+                            break;
+                        case 2:
+                            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);
+                            break;
+                        case 3:
+                            ui->pushButton_2->setEnabled(false);
+                            emit progressChanged(3,m_row);
+                            emit updateBlastStatus(3,m_row);
+                            ui->pushButton_2->setText("充电");
+                            navProgress->setState(3);
+                            break;
+                        case 4:
+                            ui->pushButton_2->setEnabled(true);
+                            emit progressChanged(4,m_row);
+                            emit updateBlastStatus(4,m_row);
+                            if(serialTool){
+                                emit updateBlastStatus(10,m_row);
+                                };
+                            ui->pushButton_2->setText("起爆");
+                            navProgress->setState(4);
+                            break;
+                        case 5:
+                            ui->pushButton_2->setEnabled(false);
+                            emit progressChanged(5,m_row);
+                            emit updateBlastStatus(5,m_row);
+                            emit updateButton(5,m_row);
+                            ui->pushButton_2->setText("起爆");
+                            navProgress->setState(5);
+                            break;
+                        case 6:
+                            ui->pushButton_2->setEnabled(false);
+                            emit progressChanged(6,m_row);
+                            emit updateBlastStatus(6,m_row);
+                            emit updateProjectStatus(m_uuid);
+                            ui->pushButton_2->setText("已完成起爆");
+                            navProgress->setState(6);
+                            break;
+                        case 7:
+                            qDebug() << "status:" << stage;
+                            ui->pushButton_2->setEnabled(false);
+                            emit progressChanged(0,m_row); // 发送进度值
+                            emit updateBlastStatus(0,m_row);//正在测试
+                            ui->pushButton_2->setText("已完成起爆");
+                            navProgress->setState(6);
+                            break;
+                        default:
+                            break;
+                    }
+                }
+            }
+        }
+        if (jsonObj.contains("type") && jsonObj["type"].toInt() == 2){
+            if (jsonObj.contains("data") && jsonObj["data"].isObject()) {
+                QJsonObject dataObject = jsonObj["data"].toObject();
+                emit updateData(dataObject);
+                emit closeFiring(m_uuid);
+
+            }
+        }
+
+    }
+}
+
+void firingWidget::onCountdownFinished(const QString &topic,const QString &message){
+    sendMqttMessage(topic, message.toUtf8());
+
+}
+
+void firingWidget::onMqttConnected()
+{
+    m_isMqttConnected = true;
+}
+
+void firingWidget::onButtonPressedReceived(const QString &topic,const QString &message)
+{
+    QByteArray data = "\r\nDISABLE_BUTTON\r\n";
+    // 调用发送数据的方法
+    bool success = serialTool->sendData(data);
+    if (success) {
+        qDebug() << "Data sent successfully";
+    } else {
+        qDebug() << "Failed to send data";
+    }
+    emit countdown(m_uuid,topic,message);
+
+
+}
+
+// 状态改变
+void firingWidget::onLastStageChanged(int newStage)
+{
+     QString topic = "hxgc/"+m_uuid+"/P";
+      QString message;
+      QString buttonText;
+      switch (lastStage) {
+        case 0:
+            message = "起爆测试";
+            buttonText = "立即测试";
+            sendMqttMessage(topic, message.toUtf8());
+            break;
+        case 2:
+            message = "开始充电";
+            buttonText = "充电";
+            sendMqttMessage(topic, message.toUtf8());
+            break;
+        case 4:
+            message = "起爆";
+            buttonText = "起爆";
+            break;
+        case 5:
+            if (connection) {
+                           disconnect(connection);
+                       }
+            if (connectionPress) {
+                           disconnect(connectionPress);
+                       }
+            serialTool->releaseInstance();
+            qDebug() << ANSI_COLOR_GREEN << "释放按键" << ANSI_COLOR_RESET;
+
+          break;
+        default:
+
+            return;
+     }
+
+     if (!message.isEmpty()) {
+         if(lastStage == 4 && !m_select){
+            bool success2;
+            serialTool = SerialTool::getInstance(nullptr, &success2);
+            if(serialTool){
+                QByteArray data = "\r\nENABLE_BUTTON\r\n";
+                bool success = serialTool->sendData(data);
+                if (success) {
+                    qDebug() << "Data sent successfully";
+                } else {
+                    qDebug() << "Failed to send data";
+                }
+                connection =connect(serialTool, &SerialTool::enableButtonReceived, [this]() {
+                    emit updateBlastStatus(10,m_row);
+                });
+                connectionPress = connect(serialTool, &SerialTool::buttonPressedReceived,[this, topic, message]() {
+                    this->onButtonPressedReceived(topic, message);
+                });
+
+            }else if(lastStage == 4&&!m_select){
+                    qDebug() << "多台起爆:待起爆状态";
+            }else {
+                qDebug() << "serialTool Not fond.";
+                //在准备起爆状态下 但是没有获取串口
+                lastStage = 10;
+                qDebug() << lastStage;
+            }
+        }else{//????
+                qDebug() << "Stage 值变为: " << newStage<<"发送消息"<<message.toUtf8();
+         }
+      }
+
+}
+
+void firingWidget::cancelBlasting()
+{
+    QString message = "取消流程";
+    if (!message.isEmpty()) {
+        sendMqttMessage(topic, message.toUtf8());
+    }
+}
+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 (!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();
+    }
+    // danUpload(jsonObj);
+    // if (db.commit()) {
+    //       qDebug() << "Transaction committed successfully.";
+    //   } else {
+    //       qDebug() << "Failed to commit transaction:" << db.lastError().text();
+    //   }
+}
+
+void firingWidget::updateWebData(const QJsonObject& jsonObj){
+    blast_uuid =QUuid::createUuid().toString(QUuid::WithoutBraces).remove(QRegularExpression("-"));
+    lat = labLat;
+    lon = labLon;
+    QSqlDatabase db = DatabaseManager::getInstance().getDatabase();
+    if (!db.transaction()) {
+        qDebug() << "Failed to start transaction:" << db.lastError().text();
+    }
+   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(blast_uuid);
+
+   if (dao.addHBlastRecord(record)) {
+       qDebug() << "Record inserted successfully.";
+   }else{
+       qDebug() << "Failed to insert record.";
+   }
+
+   if (!addRegData(jsonObj)) {
+       if (db.rollback()) {
+           qDebug() << "Transaction rolled back successfully.";
+       } else {
+           qDebug() << "Failed to roll back transaction:" << db.lastError().text();
+       }
+   }
+   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();
+       }
+   }
+
+   db.commit();
+
+
+   if(lat=="定位失败"&&lat=="未知"&&lon=="定位失败"&&lon=="未知"){
+       // 数据出本地 不传丹灵
+
+   }
+   // danUpload(jsonObj);
+   // if (db.commit()) {
+   //       qDebug() << "Transaction committed successfully.";
+   //   } else {
+   //       qDebug() << "Failed to commit transaction:" << db.lastError().text();
+   //   }
+}

+ 84 - 0
fireWidget/firingwidget.h

@@ -0,0 +1,84 @@
+#ifndef FIRINGWIDGET_H
+#define FIRINGWIDGET_H
+#include "navprogress.h"
+#include "../mqtt/mqttclient.h"
+#include "../blastRecord/hblastrecord.h"
+#include "../blastRecord/hblastrecorddao.h"
+#include "../blastRecordDet/hblastrecorddetdao.h"
+#include "../blastRegRecord/hblastregrecorddao.h"
+#include "../databasemanager.h"
+#include <QWidget>
+#include <QJsonDocument>
+#include <QJsonObject>
+#include "../des3encryption.h"
+#include "../mqttthread.h"
+#include "../serial/serialtool.h"
+
+namespace Ui {
+class firingWidget;
+}
+
+class firingWidget : public QWidget
+{
+    Q_OBJECT
+
+public:
+    explicit firingWidget(const int& row ,const bool& select ,const QString& uuid = "",QWidget *parent = nullptr);
+    ~firingWidget();
+    void cancelBlasting();
+
+public slots:
+    void onCountdownFinished(const QString &topic, const QString &message);
+private slots:
+    void on_pushButton_2_clicked();
+    void on_sendTest_4_clicked();
+    void handleMessageAndTopic(const QByteArray &message, const QMqttTopicName &topic);
+
+signals:
+    void progressChanged(int value,int row);
+    void lastStageChanged(int newStage);
+    void updateBlastStatus(int status,int row);
+    void updateButton(int status,int row);
+    void updateProjectStatus(QString uuid);
+    void updateData(const QJsonObject &jsonObj);
+    void countdown(QString uuid,const QString &topic,const QString &message);
+    void closeFiring(QString uuid);
+private slots:
+    // 处理 MQTT 连接成功的槽函数
+    void onMqttConnected();
+    //双键按下
+    void onButtonPressedReceived(const QString &topic,const QString &message);
+    void onLastStageChanged(int newStage);
+    void updateWebData(const QJsonObject &data);
+private:
+    bool addRegData(const QJsonObject &jsonObj);
+    bool addDetData(const QJsonObject &jsonObj);
+    bool danUpload(const QJsonObject &jsonObj);
+    void sendMqttMessage(const QString &topic, const QByteArray &message);
+    void startBlasting();
+
+private:
+    Ui::firingWidget *ui;
+    MqttClient *pcPorjectBC;
+    HBlastRecordDao dao;
+    HBlastRecordDetDao daoDet;
+    HBlastRegRecordDao daoReg;
+    NavProgress *navProgress;
+    MqttThread* mqttThread;
+    SerialTool* serialTool;
+    QString m_uuid; // 用于存储 uuid
+    QString reg_uuid; // 用于存储 uuid
+    QString blast_uuid; // 用于存储 uuid
+    QString topic;
+    int m_row;
+    int lastStage = -1;  // 用于记录上一次的 stage 状态
+    bool m_isMqttConnected = false;
+    bool m_select;
+    QMetaObject::Connection connection; // 声明 connection 变量
+    QMetaObject::Connection connectionPress;
+    QString lat;
+    QString lon;
+
+};
+
+#endif // FIRINGWIDGET_H

+ 272 - 0
fireWidget/firingwidget.ui

@@ -0,0 +1,272 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>firingWidget</class>
+ <widget class="QWidget" name="firingWidget">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>966</width>
+    <height>666</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <property name="styleSheet">
+   <string notr="true">QLabel { letter-spacing: 4px; color: white; }
+
+QTextEdit { color: green; font:20px}
+#textEdit { background-color: transparent; }
+
+QFrame#frame{border-image:url(:/background/background/blastOpera.png)}
+
+
+ QPushButton {
+                       background-color: #00d159; /* 按钮背景颜色 */
+                       color: white; /* 按钮文字颜色 */
+                       border: 3px solid #00ff6d;
+                       border-radius: 5px; /* 按钮圆角 */
+                       padding: 8px 16px; /* 按钮内边距 */
+ 					   font-size: 14px; /* 按钮文字大小 */
+                       text-align: center; /* 按钮文字居中 */
+                         }
+QPushButton:hover {background-color: #00a043; /* 鼠标悬停时的背景颜色 */ }
+QPushButton:pressed { 
+background-color: #008035; /* 按钮按下时的背景颜色 */
+ /* 内发光效果 */
+border: 2px solid #00ff6a; /* 按下时边框颜色变亮 */
+ }
+QPushButton:disabled {
+    background-color: #f0f0f0;
+    color: #808080;
+    border: 1px solid #d0d0d0;
+}</string>
+  </property>
+  <layout class="QGridLayout" name="gridLayout">
+   <property name="leftMargin">
+    <number>0</number>
+   </property>
+   <property name="topMargin">
+    <number>0</number>
+   </property>
+   <property name="rightMargin">
+    <number>0</number>
+   </property>
+   <property name="bottomMargin">
+    <number>0</number>
+   </property>
+   <property name="spacing">
+    <number>0</number>
+   </property>
+   <item row="0" column="0">
+    <widget class="QFrame" name="frame">
+     <property name="minimumSize">
+      <size>
+       <width>0</width>
+       <height>0</height>
+      </size>
+     </property>
+     <property name="maximumSize">
+      <size>
+       <width>16777215</width>
+       <height>16777215</height>
+      </size>
+     </property>
+     <property name="frameShape">
+      <enum>QFrame::Shape::StyledPanel</enum>
+     </property>
+     <property name="frameShadow">
+      <enum>QFrame::Shadow::Raised</enum>
+     </property>
+     <layout class="QVBoxLayout" name="verticalLayout_2">
+      <item>
+       <widget class="QFrame" name="frame_2">
+        <property name="minimumSize">
+         <size>
+          <width>0</width>
+          <height>130</height>
+         </size>
+        </property>
+        <property name="maximumSize">
+         <size>
+          <width>16777215</width>
+          <height>130</height>
+         </size>
+        </property>
+        <property name="frameShape">
+         <enum>QFrame::Shape::StyledPanel</enum>
+        </property>
+        <property name="frameShadow">
+         <enum>QFrame::Shadow::Raised</enum>
+        </property>
+        <layout class="QVBoxLayout" name="verticalLayout"/>
+       </widget>
+      </item>
+      <item>
+       <layout class="QHBoxLayout" name="horizontalLayout_2" stretch="1,7,1">
+        <property name="sizeConstraint">
+         <enum>QLayout::SizeConstraint::SetNoConstraint</enum>
+        </property>
+        <property name="bottomMargin">
+         <number>9</number>
+        </property>
+        <item>
+         <spacer name="horizontalSpacer">
+          <property name="orientation">
+           <enum>Qt::Orientation::Horizontal</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>40</width>
+            <height>20</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+        <item>
+         <widget class="QScrollArea" name="scrollArea">
+          <property name="widgetResizable">
+           <bool>true</bool>
+          </property>
+          <widget class="QWidget" name="scrollAreaWidgetContents">
+           <property name="geometry">
+            <rect>
+             <x>0</x>
+             <y>0</y>
+             <width>724</width>
+             <height>398</height>
+            </rect>
+           </property>
+           <layout class="QVBoxLayout" name="verticalLayout_3">
+            <item>
+             <widget class="QTextEdit" name="textEdit"/>
+            </item>
+           </layout>
+          </widget>
+         </widget>
+        </item>
+        <item>
+         <spacer name="horizontalSpacer_4">
+          <property name="orientation">
+           <enum>Qt::Orientation::Horizontal</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>40</width>
+            <height>20</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+       </layout>
+      </item>
+      <item>
+       <layout class="QHBoxLayout" name="horizontalLayout">
+        <item>
+         <spacer name="horizontalSpacer_2">
+          <property name="orientation">
+           <enum>Qt::Orientation::Horizontal</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>40</width>
+            <height>20</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+        <item>
+         <widget class="QPushButton" name="pushButton_2">
+          <property name="minimumSize">
+           <size>
+            <width>200</width>
+            <height>50</height>
+           </size>
+          </property>
+          <property name="maximumSize">
+           <size>
+            <width>16777215</width>
+            <height>50</height>
+           </size>
+          </property>
+          <property name="text">
+           <string>立即组网</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QPushButton" name="sendTest_4">
+          <property name="minimumSize">
+           <size>
+            <width>200</width>
+            <height>50</height>
+           </size>
+          </property>
+          <property name="maximumSize">
+           <size>
+            <width>16777215</width>
+            <height>50</height>
+           </size>
+          </property>
+          <property name="text">
+           <string>停止起爆</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <spacer name="horizontalSpacer_3">
+          <property name="orientation">
+           <enum>Qt::Orientation::Horizontal</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>40</width>
+            <height>20</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+       </layout>
+      </item>
+      <item>
+       <spacer name="verticalSpacer">
+        <property name="orientation">
+         <enum>Qt::Orientation::Vertical</enum>
+        </property>
+        <property name="sizeType">
+         <enum>QSizePolicy::Policy::Minimum</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>20</width>
+          <height>20</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+      <item>
+       <widget class="QLabel" name="label">
+        <property name="font">
+         <font>
+          <family>宋体</family>
+          <pointsize>9</pointsize>
+          <fontweight>ExtraLight</fontweight>
+         </font>
+        </property>
+        <property name="text">
+         <string>桦芯国创科技有限公司出品</string>
+        </property>
+        <property name="alignment">
+         <set>Qt::AlignmentFlag::AlignCenter</set>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>

+ 286 - 0
fireWidget/navprogress.cpp

@@ -0,0 +1,286 @@
+#include "navprogress.h"
+
+NavProgress::NavProgress(QWidget *parent) : QWidget(parent), navStyle(NavStyle_JD), maxStep(3), state(0)  {
+
+    background = Qt::gray;
+    foreground = Qt::white;
+    firstCircleGreen = false;
+    firstCircleBlinking =false;
+    secondCircleGreen = false;
+    secondCircleBlinking = false;
+    thridCircleGreen = false;
+    thridCircleBlinking = false;
+    topInfo = {"组网", "充电", "起爆"};
+    blinkTimer = new QTimer(this);
+    connect(blinkTimer, &QTimer::timeout, this, &NavProgress::toggleBlinkColors);
+    blinkColor = Qt::red;
+    secondBlinkColor = Qt::red;
+    qDebug()<<"width"<<this->width();
+}
+void NavProgress::setNavStyle(NavStyle style) {
+    navStyle = style;
+    update();
+}
+
+void NavProgress::setMaxStep(int step) {
+    maxStep = step;
+    update();
+}
+
+
+void NavProgress::setTopInfo(const QVector<QString>& info) {
+    topInfo = info;
+    update();
+}
+
+
+void NavProgress::setFirstCircleGreen(bool green) {
+    firstCircleGreen = green;
+    update();
+}
+
+void NavProgress::setFirstCircleBlinking(bool blinking) {
+    firstCircleBlinking = blinking;
+    if (blinking) {
+        blinkTimer->start(500);
+    } else {
+        blinkTimer->stop();
+        update();
+    }
+}
+
+
+
+QVector<QColor> NavProgress::getCircleColors() {
+    QVector<QColor> colors;
+    for (int i = 0; i < maxStep; i++) {
+        if (i == 0 && firstCircleGreen) {
+            colors.append(Qt::green);
+        } else {
+            colors.append(background);
+        }
+    }
+    return colors;
+}
+
+void NavProgress::toggleBlinkColors() {
+
+    blinkColor = (blinkColor == Qt::red)? Qt::gray : Qt::red;
+    if (secondCircleBlinking) {
+
+        secondBlinkColor = (secondBlinkColor == Qt::red)? Qt::gray : Qt::red;
+    }
+    if (thridCircleBlinking) {
+
+        secondBlinkColor = (secondBlinkColor == Qt::red)? Qt::gray : Qt::red;
+    }
+    update();
+}
+
+
+void NavProgress::setState(int newState) {
+    state = newState;
+    switch (state) {
+        case 0:
+            firstCircleGreen = false;
+            firstCircleBlinking = false;
+            secondCircleBlinking = false;
+            secondCircleGreen = false;
+            thridCircleBlinking = false;
+            thridCircleGreen = false;
+            blinkTimer->stop();
+            break;
+        case 1:
+            firstCircleGreen = false;
+            firstCircleBlinking = true;
+            secondCircleBlinking = false;
+            secondCircleGreen = false;
+            thridCircleBlinking = false;
+            thridCircleGreen = false;
+            blinkTimer->start(500);
+            break;
+        case 2:
+            firstCircleGreen = true;
+            firstCircleBlinking = false;
+            secondCircleBlinking = false;
+            secondCircleGreen = false;
+            thridCircleBlinking = false;
+            thridCircleGreen = false;
+            break;
+        case 3:
+            firstCircleGreen = true;
+            firstCircleBlinking = false;
+            secondCircleBlinking = true;
+            secondCircleGreen = false;
+            thridCircleBlinking = false;
+            thridCircleGreen = false;
+            blinkTimer->start(500);
+            break;
+        case 4:
+            firstCircleGreen = true;
+            firstCircleBlinking = false;
+            secondCircleBlinking = false;
+            secondCircleGreen = true;
+            thridCircleBlinking = false;
+            thridCircleGreen = false;
+            break;
+        case 5:
+            firstCircleGreen = true;
+            firstCircleBlinking = false;
+            secondCircleBlinking = false;
+            secondCircleGreen = true;
+            thridCircleBlinking = true;
+            thridCircleGreen = false;
+            blinkTimer->start(500);
+            break;
+        case 6:
+            firstCircleGreen = true;
+            firstCircleBlinking = false;
+            secondCircleBlinking = false;
+            secondCircleGreen = true;
+            thridCircleBlinking = false;
+            thridCircleGreen = true;
+            break;
+        default:
+            break;
+    }
+    update();
+}
+
+void NavProgress::paintEvent(QPaintEvent *) {
+
+    QPainter painter(this);
+    painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
+
+
+    if (navStyle == NavStyle_JD) {
+
+        drawBg_JD(&painter);
+
+        drawText_JD(&painter);
+
+    }
+}
+
+void NavProgress::drawBg_JD(QPainter *painter) {
+    painter->save();
+
+
+    int width = this->width() / maxStep;
+    int height = this->height() / 2;
+    int radius = height / 4;
+    int initX = 0 + radius;
+    int initY = height / 2 + radius / 5;
+
+    initX = width / 2;
+    QPen pen;
+    pen.setWidthF((double)radius / 4);
+    pen.setCapStyle(Qt::RoundCap);
+
+    for (int i = 0; i < maxStep - 1; i++) {
+        if (i == 0 && firstCircleGreen) {
+            pen.setColor(Qt::green);
+        }else if(i == 1 && secondCircleGreen){
+            pen.setColor(Qt::green);
+        }else {
+            pen.setColor(background);
+        }
+        painter->setPen(pen);
+        painter->setBrush(Qt::NoBrush);
+        painter->drawLine(QPoint(initX+ radius + radius , initY), QPoint(initX + width - (radius + radius), initY));
+        initX += width;
+    }
+
+
+    initX = width / 2;
+    painter->setPen(Qt::NoPen);
+
+    for (int i = 0; i < maxStep; i++) {
+
+        if (i == 0 && firstCircleGreen) {
+            painter->setBrush(Qt::green);
+        } else if (i == 0 && firstCircleBlinking) {
+            painter->setBrush(blinkColor);
+        } else if (i == 1 && secondCircleBlinking) {
+            painter->setBrush(secondBlinkColor);
+        }  else if (i == 1 && secondCircleGreen) {
+            painter->setBrush(Qt::green);
+        }else if (i == 2 && thridCircleBlinking) {
+            painter->setBrush(secondBlinkColor);
+        }else if (i == 2 && thridCircleGreen) {
+            painter->setBrush(Qt::green);
+        }
+        else {
+            painter->setBrush(background);
+        }
+        painter->drawEllipse(QPoint(initX, initY), radius, radius);
+        initX += width;
+    }
+
+    initX = width / 2;
+    QPen outerPen;
+    outerPen.setWidth(5);
+    for (int i = 0; i < maxStep; i++) {
+        if (i == 0 && firstCircleBlinking) {
+            outerPen.setColor(blinkColor);
+        } else if (i == 0 && firstCircleGreen) {
+            outerPen.setColor(Qt::green); // 第一个空心圆常亮绿色
+        } else if (i == 1 && secondCircleBlinking) {
+            outerPen.setColor(secondBlinkColor);
+        } else if (i == 1 && secondCircleGreen) {
+            outerPen.setColor(Qt::green);
+        }
+        else if (i == 2 && thridCircleBlinking) {
+            outerPen.setColor(secondBlinkColor);
+        }else if (i == 2 && thridCircleGreen) {
+            outerPen.setColor(Qt::green);
+        }
+        else {
+            outerPen.setColor(background);
+        }
+        painter->setPen(outerPen);
+        painter->setBrush(Qt::NoBrush);
+        int outerRadius = radius + 5; // 外层圆半径比内层圆大 5,可按需调整
+        painter->drawEllipse(QPoint(initX, initY), outerRadius, outerRadius);
+        initX += width;
+    }
+
+    initX = width / 2;
+    QFont font;
+    font.setPixelSize(radius);
+    painter->setFont(font);
+    painter->setPen(foreground);
+    painter->setBrush(Qt::NoBrush);
+
+    for (int i = 0; i < maxStep; i++) {
+        QRect textRect(initX - radius, initY - radius, radius * 2, radius * 2);
+        painter->drawText(textRect, Qt::AlignCenter, QString::number(i + 1));
+        initX += width;
+    }
+
+    painter->restore();
+}
+
+void NavProgress::drawText_JD(QPainter *painter) {
+    int width = this->width() / maxStep;
+    int height = this->height() / 2;
+    int initX = 0;
+    int initY = height * 1 /2 +10;
+    painter->save();
+    QFont font;
+    font.setPixelSize(height / 4);
+    painter->setFont(font);
+    for (int i = 0; i < maxStep; i++) {
+        if (i == 0 && firstCircleGreen) {
+            painter->setPen(Qt::green); // 第一个文字为绿色
+        } else {
+            painter->setPen(background);
+        }
+        painter->setBrush(Qt::NoBrush);
+        QRect textRect(initX, initY, width, height);
+        painter->drawText(textRect, Qt::AlignCenter, topInfo.at(i));
+        initX += width;
+    }
+    painter->restore();
+}
+

+ 78 - 0
fireWidget/navprogress.h

@@ -0,0 +1,78 @@
+#ifndef NAVPROGRESS_H
+#define NAVPROGRESS_H
+
+
+#include <QWidget>
+#include <QPainter>
+#include <QPen>
+#include <QFont>
+#include <QRect>
+#include <QString>
+#include <QVector>
+#include <QVBoxLayout>
+#include <QPushButton>
+#include <QApplication>
+#include <QDebug>
+#include <QTimer>
+
+
+// 定义导航样式枚举
+enum NavStyle {
+    NavStyle_JD,
+};
+
+class NavProgress : public QWidget {
+    Q_OBJECT
+public:
+    NavProgress(QWidget *parent = nullptr);
+
+    // 设置导航样式
+    void setNavStyle(NavStyle style);
+
+    // 设置最大步骤数
+    void setMaxStep(int step);
+
+    // 设置顶部信息
+    void setTopInfo(const QVector<QString>& info);
+
+    // 设置第一个圆为绿色
+    void setFirstCircleGreen(bool green);
+    // 开始或停止第一个空心圆闪烁
+    void setFirstCircleBlinking(bool blinking);
+
+    // 获取每个圆的颜色
+    QVector<QColor> getCircleColors();
+
+    // 设置状态
+    void setState(int newState);
+
+protected:
+    void paintEvent(QPaintEvent *) override;
+    void drawBg_JD(QPainter *painter);
+    void drawText_JD(QPainter *painter);
+    // 其他样式的绘制函数,这里简单占位
+    // void drawCurrentBg_JD(QPainter *painter);
+    // void drawCurrentText_JD(QPainter *painter);
+
+private slots:
+    void toggleBlinkColors();
+
+private:
+    NavStyle navStyle;
+    int maxStep;
+    int state;
+    QColor background;
+    QColor foreground;
+    QVector<QString> topInfo;
+    bool firstCircleGreen;
+    bool firstCircleBlinking;
+    bool secondCircleBlinking;
+    bool secondCircleGreen;
+    bool thridCircleBlinking;
+    bool thridCircleGreen;
+    QColor blinkColor;
+    QColor secondBlinkColor;
+    QTimer *blinkTimer;
+};
+
+#endif // NAVPROGRESS_H

+ 6 - 0
global.cpp

@@ -0,0 +1,6 @@
+#include "global.h"
+
+QUrl g_url("http://192.168.0.255:8000/api/v1/");  // 定义并初始化全局变量
+QString labLat("未知");
+QString labLon("未知");
+QString globalAuthority;

+ 12 - 0
global.h

@@ -0,0 +1,12 @@
+#ifndef GLOBAL_H
+#define GLOBAL_H
+
+#include <QUrl>
+#include <QUrlQuery>
+#include <QString>
+
+extern QUrl g_url;  // 声明全局变量
+extern QString labLat;  // 新增的全局变量声明
+extern QString labLon;  // 新增的全局变量声明
+extern QString globalAuthority;
+#endif // GLOBAL_H

+ 11 - 0
hblastrecorddao.h

@@ -0,0 +1,11 @@
+#ifndef HBLASTRECORDDAO_H
+#define HBLASTRECORDDAO_H
+
+
+class HBlastRecordDao
+{
+public:
+    HBlastRecordDao();
+};
+
+#endif // HBLASTRECORDDAO_H

+ 233 - 0
hproject.cpp

@@ -0,0 +1,233 @@
+#include "hproject.h"
+
+HProject::HProject(QObject *parent) : QObject(parent),
+    id(0),
+    createBy(0),
+    updateBy(0)
+{
+}
+
+// Getter and Setter implementations
+qint64 HProject::getId() const
+{
+    return id;
+}
+
+void HProject::setId(qint64 newId)
+{
+    id = newId;
+}
+
+QString HProject::getUuid() const
+{
+    return uuid;
+}
+
+void HProject::setUuid(const QString &newUuid)
+{
+    uuid = newUuid;
+}
+
+QString HProject::getName() const
+{
+    return name;
+}
+
+void HProject::setName(const QString &newName)
+{
+    name = newName;
+}
+
+QString HProject::getCompanyCode() const
+{
+    return companyCode;
+}
+
+void HProject::setCompanyCode(const QString &newCompanyCode)
+{
+    companyCode = newCompanyCode;
+}
+
+QString HProject::getHtid() const
+{
+    return htid;
+}
+
+void HProject::setHtid(const QString &newHtid)
+{
+    htid = newHtid;
+}
+
+QString HProject::getXmbh() const
+{
+    return xmbh;
+}
+
+void HProject::setXmbh(const QString &newXmbh)
+{
+    xmbh = newXmbh;
+}
+
+QString HProject::getOperatorName() const
+{
+    return operatorName;
+}
+
+void HProject::setOperatorName(const QString &newOperatorName)
+{
+    operatorName = newOperatorName;
+}
+
+QString HProject::getOperatorIdentity() const
+{
+    return operatorIdentity;
+}
+
+void HProject::setOperatorIdentity(const QString &newOperatorIdentity)
+{
+    operatorIdentity = newOperatorIdentity;
+}
+
+QString HProject::getBlasterName() const
+{
+    return blasterName;
+}
+
+void HProject::setBlasterName(const QString &newBlasterName)
+{
+    blasterName = newBlasterName;
+}
+
+QString HProject::getBlasterIdentity() const
+{
+    return blasterIdentity;
+}
+
+void HProject::setBlasterIdentity(const QString &newBlasterIdentity)
+{
+    blasterIdentity = newBlasterIdentity;
+}
+
+QString HProject::getAddressUuid() const
+{
+    return addressUuid;
+}
+
+void HProject::setAddressUuid(const QString &newAddressUuid)
+{
+    addressUuid = newAddressUuid;
+}
+
+QString HProject::getPcSn() const
+{
+    return pcSn;
+}
+
+void HProject::setPcSn(const QString &newPcSn)
+{
+    pcSn = newPcSn;
+}
+
+QString HProject::getDetSum() const
+{
+    return detSum;
+}
+
+void HProject::setDetSum(const QString &newDetSum)
+{
+    detSum = newDetSum;
+}
+
+QString HProject::getFileName() const
+{
+    return fileName;
+}
+
+void HProject::setFileName(const QString &newFileName)
+{
+    fileName = newFileName;
+}
+
+QString HProject::getFileUrl() const
+{
+    return fileUrl;
+}
+
+void HProject::setFileUrl(const QString &newFileUrl)
+{
+    fileUrl = newFileUrl;
+}
+
+QString HProject::getBlastStatus() const
+{
+    return blastStatus;
+}
+
+void HProject::setBlastStatus(const QString &newBlastStatus)
+{
+    blastStatus = newBlastStatus;
+}
+
+QDateTime HProject::getCreatedAt() const
+{
+    return createdAt;
+}
+
+void HProject::setCreatedAt(const QDateTime &newCreatedAt)
+{
+    createdAt = newCreatedAt;
+}
+
+QDateTime HProject::getUpdatedAt() const
+{
+    return updatedAt;
+}
+
+void HProject::setUpdatedAt(const QDateTime &newUpdatedAt)
+{
+    updatedAt = newUpdatedAt;
+}
+
+QDateTime HProject::getDeletedAt() const
+{
+    return deletedAt;
+}
+
+void HProject::setDeletedAt(const QDateTime &newDeletedAt)
+{
+    deletedAt = newDeletedAt;
+}
+
+qint64 HProject::getCreateBy() const
+{
+    return createBy;
+}
+
+void HProject::setCreateBy(qint64 newCreateBy)
+{
+    createBy = newCreateBy;
+}
+
+qint64 HProject::getUpdateBy() const
+{
+    return updateBy;
+}
+
+void HProject::setUpdateBy(qint64 newUpdateBy)
+{
+    updateBy = newUpdateBy;
+}
+
+QByteArray HProject::ProjectToJson(const HProject& project) {
+    QJsonObject jsonObject;
+    jsonObject["name"] = project.getName();
+    jsonObject["detSum"] = project.getDetSum();
+    jsonObject["blasterName"] = project.getBlasterName();
+    jsonObject["operatorName"] = project.getOperatorName();
+    jsonObject["address"] = project.getAddressUuid();
+    jsonObject["blasterIdentity"] = project.getBlasterIdentity();
+    jsonObject["operatorIdentity"] = project.getOperatorIdentity();
+
+    QJsonDocument jsonDoc(jsonObject);
+    return jsonDoc.toJson(QJsonDocument::Compact);
+}

+ 129 - 0
hproject.h

@@ -0,0 +1,129 @@
+#ifndef HPROJECT_H
+#define HPROJECT_H
+
+#include <QString>
+#include <QDateTime>
+#include <QJsonObject>
+#include <QJsonDocument>
+#include <QUuid>
+
+class HProject : public QObject
+{
+    Q_OBJECT
+    // 定义属性
+    Q_PROPERTY(qint64 id READ getId WRITE setId)
+    Q_PROPERTY(QString uuid READ getUuid WRITE setUuid)
+    Q_PROPERTY(QString name READ getName WRITE setName)
+    Q_PROPERTY(QString companyCode READ getCompanyCode WRITE setCompanyCode)
+    Q_PROPERTY(QString htid READ getHtid WRITE setHtid)
+    Q_PROPERTY(QString xmbh READ getXmbh WRITE setXmbh)
+    Q_PROPERTY(QString operatorName READ getOperatorName WRITE setOperatorName)
+    Q_PROPERTY(QString operatorIdentity READ getOperatorIdentity WRITE setOperatorIdentity)
+    Q_PROPERTY(QString blasterName READ getBlasterName WRITE setBlasterName)
+    Q_PROPERTY(QString blasterIdentity READ getBlasterIdentity WRITE setBlasterIdentity)
+    Q_PROPERTY(QString addressUuid READ getAddressUuid WRITE setAddressUuid)
+    Q_PROPERTY(QString pcSn READ getPcSn WRITE setPcSn)
+    Q_PROPERTY(QString detSum READ getDetSum WRITE setDetSum)
+    Q_PROPERTY(QString fileName READ getFileName WRITE setFileName)
+    Q_PROPERTY(QString fileUrl READ getFileUrl WRITE setFileUrl)
+    Q_PROPERTY(QString blastStatus READ getBlastStatus WRITE setBlastStatus)
+    Q_PROPERTY(QDateTime createdAt READ getCreatedAt WRITE setCreatedAt)
+    Q_PROPERTY(QDateTime updatedAt READ getUpdatedAt WRITE setUpdatedAt)
+    Q_PROPERTY(QDateTime deletedAt READ getDeletedAt WRITE setDeletedAt)
+    Q_PROPERTY(qint64 createBy READ getCreateBy WRITE setCreateBy)
+    Q_PROPERTY(qint64 updateBy READ getUpdateBy WRITE setUpdateBy)
+
+public:
+    explicit HProject(QObject *parent = nullptr);
+
+    // Getter and Setter methods
+    qint64 getId() const;
+    void setId(qint64 newId);
+
+    QString getUuid() const;
+    void setUuid(const QString &newUuid);
+
+    QString getName() const;
+    void setName(const QString &newName);
+
+    QString getCompanyCode() const;
+    void setCompanyCode(const QString &newCompanyCode);
+
+    QString getHtid() const;
+    void setHtid(const QString &newHtid);
+
+    QString getXmbh() const;
+    void setXmbh(const QString &newXmbh);
+
+    QString getOperatorName() const;
+    void setOperatorName(const QString &newOperatorName);
+
+    QString getOperatorIdentity() const;
+    void setOperatorIdentity(const QString &newOperatorIdentity);
+
+    QString getBlasterName() const;
+    void setBlasterName(const QString &newBlasterName);
+
+    QString getBlasterIdentity() const;
+    void setBlasterIdentity(const QString &newBlasterIdentity);
+
+    QString getAddressUuid() const;
+    void setAddressUuid(const QString &newAddressUuid);
+
+    QString getPcSn() const;
+    void setPcSn(const QString &newPcSn);
+
+    QString getDetSum() const;
+    void setDetSum(const QString &newDetSum);
+
+    QString getFileName() const;
+    void setFileName(const QString &newFileName);
+
+    QString getFileUrl() const;
+    void setFileUrl(const QString &newFileUrl);
+
+    QString getBlastStatus() const;
+    void setBlastStatus(const QString &newBlastStatus);
+
+    QDateTime getCreatedAt() const;
+    void setCreatedAt(const QDateTime &newCreatedAt);
+
+    QDateTime getUpdatedAt() const;
+    void setUpdatedAt(const QDateTime &newUpdatedAt);
+
+    QDateTime getDeletedAt() const;
+    void setDeletedAt(const QDateTime &newDeletedAt);
+
+    qint64 getCreateBy() const;
+    void setCreateBy(qint64 newCreateBy);
+
+    qint64 getUpdateBy() const;
+    void setUpdateBy(qint64 newUpdateBy);
+
+    QByteArray ProjectToJson(const HProject& project);
+
+private:
+    qint64 id;
+    QString uuid;
+    QString name;
+    QString companyCode;
+    QString htid;
+    QString xmbh;
+    QString operatorName;
+    QString operatorIdentity;
+    QString blasterName;
+    QString blasterIdentity;
+    QString addressUuid;
+    QString pcSn;
+    QString detSum;
+    QString fileName;
+    QString fileUrl;
+    QString blastStatus;
+    QDateTime createdAt;
+    QDateTime updatedAt;
+    QDateTime deletedAt;
+    qint64 createBy;
+    qint64 updateBy;
+};
+
+#endif // HPROJECT_H

+ 182 - 0
hprojectdao.cpp

@@ -0,0 +1,182 @@
+#include "HProjectDao.h"
+
+
+HProjectDao::HProjectDao(QSqlDatabase db):database(db)
+{
+}
+
+bool HProjectDao::addHProject(const HProject &project)
+{
+
+    QSqlQuery query;
+    query.prepare("INSERT INTO h_project (uuid, name, company_code, htid, xmbh, operator_name, operator_identity, blaster_name, blaster_identity, address_uuid, pc_sn, det_sum, file_name, file_url, blast_status, created_at, updated_at, deleted_at, create_by, update_by) "
+                  "VALUES (:uuid, :name, :companyCode, :htid, :xmbh, :operatorName, :operatorIdentity, :blasterName, :blasterIdentity, :addressUuid, :pcSn, :detSum, :fileName, :fileUrl, :blastStatus, :createdAt, :updatedAt, :deletedAt, :createBy, :updateBy)");
+
+    query.bindValue(":uuid", project.getUuid());
+    query.bindValue(":name", project.getName());
+    query.bindValue(":companyCode", project.getCompanyCode());
+    query.bindValue(":htid", project.getHtid());
+    query.bindValue(":xmbh", project.getXmbh());
+    query.bindValue(":operatorName", project.getOperatorName());
+    query.bindValue(":operatorIdentity", project.getOperatorIdentity());
+    query.bindValue(":blasterName", project.getBlasterName());
+    query.bindValue(":blasterIdentity", project.getBlasterIdentity());
+    query.bindValue(":addressUuid", project.getAddressUuid());
+    query.bindValue(":pcSn", project.getPcSn());
+    query.bindValue(":detSum", project.getDetSum());
+    query.bindValue(":fileName", project.getFileName());
+    query.bindValue(":fileUrl", project.getFileUrl());
+    query.bindValue(":blastStatus", project.getBlastStatus());
+    query.bindValue(":createdAt", project.getCreatedAt().toString(Qt::ISODateWithMs));
+    query.bindValue(":updatedAt", project.getUpdatedAt().toString(Qt::ISODateWithMs));
+    query.bindValue(":deletedAt", project.getDeletedAt().toString(Qt::ISODateWithMs));
+    query.bindValue(":createBy", project.getCreateBy());
+    query.bindValue(":updateBy", project.getUpdateBy());
+
+
+    qDebug() << "Executing SQL query:" << query.lastQuery();
+    if (!query.exec()) {
+        qCritical() << "Failed to save HProject:" << query.lastError().text();
+        return false;
+    }
+
+    return true;
+}
+
+bool HProjectDao::updateHProject(const HProject &project)
+{
+    QSqlQuery query;
+    query.prepare("UPDATE h_project SET "
+                  "uuid = :uuid, "
+                  "name = :name, "
+                  "company_code = :companyCode, "
+                  "htid = :htid, "
+                  "xmbh = :xmbh, "
+                  "operator_name = :operatorName, "
+                  "operator_identity = :operatorIdentity, "
+                  "blaster_name = :blasterName, "
+                  "blaster_identity = :blasterIdentity, "
+                  "address_uuid = :addressUuid, "
+                  "pc_sn = :pcSn, "
+                  "det_sum = :detSum, "
+                  "file_name = :fileName, "
+                  "file_url = :fileUrl, "
+                  "blast_status = :blastStatus, "
+                  "created_at = :createdAt, "
+                  "updated_at = :updatedAt, "
+                  "deleted_at = :deletedAt, "
+                  "create_by = :createBy, "
+                  "update_by = :updateBy "
+                  "WHERE id = :id");
+
+    query.bindValue(":id", project.getId());
+    query.bindValue(":uuid", project.getUuid());
+    query.bindValue(":name", project.getName());
+    query.bindValue(":companyCode", project.getCompanyCode());
+    query.bindValue(":htid", project.getHtid());
+    query.bindValue(":xmbh", project.getXmbh());
+    query.bindValue(":operatorName", project.getOperatorName());
+    query.bindValue(":operatorIdentity", project.getOperatorIdentity());
+    query.bindValue(":blasterName", project.getBlasterName());
+    query.bindValue(":blasterIdentity", project.getBlasterIdentity());
+    query.bindValue(":addressUuid", project.getAddressUuid());
+    query.bindValue(":pcSn", project.getPcSn());
+    query.bindValue(":detSum", project.getDetSum());
+    query.bindValue(":fileName", project.getFileName());
+    query.bindValue(":fileUrl", project.getFileUrl());
+    query.bindValue(":blastStatus", project.getBlastStatus());
+    query.bindValue(":createdAt", project.getCreatedAt().toString(Qt::ISODateWithMs));
+    query.bindValue(":updatedAt", project.getUpdatedAt().toString(Qt::ISODateWithMs));
+    query.bindValue(":deletedAt", project.getDeletedAt().toString(Qt::ISODateWithMs));
+    query.bindValue(":createBy", project.getCreateBy());
+    query.bindValue(":updateBy", project.getUpdateBy());
+
+    qDebug() << "Executing UpdateSQL query:" << query.lastQuery();
+    if (!query.exec()) {
+        qCritical() << "Failed to save HProject:" << query.lastError().text();
+        return false;
+    }
+
+    return true;
+}
+
+bool HProjectDao::deleteHProject(const HProject &project)
+{
+    QSqlQuery query;
+    qDebug()<<"Id"<<project.getId();
+    query.prepare("DELETE FROM h_project WHERE id = :id");
+    query.bindValue(":id", project.getId());
+    if (!query.exec()) {
+        qCritical() << "Failed to delete h_project:" << query.lastError().text();
+        return false;
+    }
+    return true;
+}
+
+// HProject HProjectDao::getHProjectById(qint64 id)
+// {
+//     QSqlQuery query;
+//     // query.prepare("SELECT * FROM hproject WHERE id = :id");
+//     // query.bindValue(":id", id);
+//     // if (query.exec() && query.next()) {
+//     //     return recordToProject(query.record());
+//     // }
+//     return HProject();
+// }
+
+PaginatedHProjectResult HProjectDao::getAllHProjects(int page, int pageSize)
+{
+    QList<QSharedPointer<HProject>> projects;
+    QSqlQuery query(database);
+    int offset = (page - 1) * pageSize;
+    query.prepare("SELECT * FROM h_project ORDER BY created_at LIMIT :pageSize OFFSET :offset");
+    query.bindValue(":pageSize", pageSize);
+    query.bindValue(":offset", offset);
+    // while (query.next()) {
+    //     projects.append(recordToProject(query.record()));
+    // }
+
+    // 执行查询并打印SQL
+    if (query.exec()) {
+        qDebug() << "Executed SQL: " << query.executedQuery();
+        while (query.next()) {
+            projects.append(recordToProject(query.record()));
+        }
+    } else {
+        qWarning() << "Query execution failed: " << query.lastError().text();
+    }
+
+    query.prepare("SELECT COUNT(*) FROM h_project");
+    int totalCount = 0;
+    if (query.exec() && query.next()) {
+        totalCount = query.value(0).toInt();
+    }
+    return { projects, totalCount };
+}
+
+QSharedPointer<HProject> HProjectDao::recordToProject(const QSqlRecord &record)
+{
+    QSharedPointer<HProject> project = QSharedPointer<HProject>::create();
+    project->setId(record.value("id").toInt());
+    project->setUuid(record.value("uuid").toString());
+    project->setName(record.value("name").toString());
+    project->setCompanyCode(record.value("company_code").toString());
+    project->setHtid(record.value("htid").toString());
+    project->setXmbh(record.value("xmbh").toString());
+    project->setOperatorName(record.value("operator_name").toString());
+    project->setOperatorIdentity(record.value("operator_identity").toString());
+    project->setBlasterName(record.value("blaster_name").toString());
+    project->setBlasterIdentity(record.value("blaster_identity").toString());
+    project->setAddressUuid(record.value("address_uuid").toString());
+    project->setPcSn(record.value("pc_sn").toString());
+    project->setDetSum(record.value("det_sum").toString());
+    project->setFileName(record.value("file_name").toString());
+    project->setFileUrl(record.value("file_url").toString());
+    project->setBlastStatus(record.value("blast_status").toString());
+    project->setCreatedAt(QDateTime::fromString(record.value("created_at").toString(), Qt::ISODateWithMs));
+    project->setUpdatedAt(QDateTime::fromString(record.value("updated_at").toString(), Qt::ISODateWithMs));
+    project->setDeletedAt(QDateTime::fromString(record.value("deleted_at").toString(), Qt::ISODateWithMs));
+    project->setCreateBy(record.value("create_by").toInt());
+    project->setUpdateBy(record.value("update_by").toInt());
+    return project;
+}

+ 50 - 0
hprojectdao.h

@@ -0,0 +1,50 @@
+#ifndef HPROJECTDAO_H
+#define HPROJECTDAO_H
+
+#include <QObject>
+#include <QSqlDatabase>
+#include <QSqlQuery>
+#include <QSqlError>
+#include <QList>
+#include <QSqlRecord>
+#include <QRegularExpression>
+#include "HProject.h"
+
+struct PaginatedHProjectResult {
+    QList<QSharedPointer<HProject>> projects;
+    int totalCount;
+};
+
+class HProjectDao
+{
+
+public:
+    HProjectDao(QSqlDatabase db);
+
+
+    // 添加一个新的HProject记录
+    bool addHProject(const HProject &project);
+
+    // 更新现有的HProject记录
+    bool updateHProject(const HProject &project);
+
+    // 删除一个HProject记录
+    bool deleteHProject(const HProject &project);
+
+    // 根据ID获取HProject记录
+    HProject getHProjectById(qint64 id);
+
+    bool updateBlastStatusByUuid(const QString &uuid, const QString &blastStatus);
+
+    PaginatedHProjectResult getAllHProjects(int page, int pageSize);
+
+    PaginatedHProjectResult getAllHProjectsByOpera(int page, int pageSize);
+
+
+private:
+    QSqlDatabase database;
+    // 将QSqlRecord转换为HProject对象
+    QSharedPointer<HProject> recordToProject(const QSqlRecord &record);
+};
+
+#endif // HPROJECTDAO_H

+ 114 - 0
httpclient.cpp

@@ -0,0 +1,114 @@
+#include "HttpClient.h"
+#include <QNetworkReply>
+#include <QJsonDocument>
+#include <QJsonObject>
+#include <QJsonArray>
+#include <QDebug>
+
+// HttpClient 类的实现
+
+HttpClient::HttpClient(QObject *parent)
+    : QObject(parent), m_networkManager(new QNetworkAccessManager(this)) {
+    // 构造函数中可以初始化一些变量或设置默认值
+}
+
+void HttpClient::sendHttpGetRequest(const QUrl &url) {
+    QNetworkRequest request(url);
+    m_currenturl = url;
+    QNetworkReply *reply = m_networkManager->get(request);
+    if (!reply) {
+        emit httpErrorOccurred("Failed to create network reply");
+    } else {
+        // qDebug() << "Network reply created successfully.";
+    }
+
+    connect(reply, &QNetworkReply::finished, this, &HttpClient::onGetFinished);
+    // connect(reply, &QNetworkReply::errorOccurred, this, &HttpClient::onNetworkError);
+    // connect(reply, &QNetworkReply::sslErrors, this, &HttpClient::onSslErrors);
+}
+
+void HttpClient::onGetFinished() {
+    QNetworkReply *reply = qobject_cast<QNetworkReply *>(sender());
+    if (reply) {
+        if (reply->error() == QNetworkReply::NoError) {
+            QByteArray responseData = reply->readAll();
+            QJsonDocument jsonDoc = QJsonDocument::fromJson(responseData);
+            if (jsonDoc.isNull()) {
+                qDebug() << "Failed to parse JSON!";
+                return;
+            }
+            else {
+                emit httpGetFinished(jsonDoc,m_currenturl); // 发出信号通知外部处理
+            }
+
+        } else {
+            emit httpErrorOccurred(reply->errorString()); // 发出信号通知外部错误
+        }
+        // 确保释放 reply 对象
+        reply->deleteLater();
+    }
+}
+
+void HttpClient::sendHttpGetAddress(const QUrl &url) {
+    QNetworkRequest request(url);
+    m_currenturl2 = url;
+    QNetworkReply *reply = m_networkManager->get(request);
+    if (!reply) {
+        emit httpErrorOccurred("Failed to create network reply");
+    } else {
+        // qDebug() << "Network reply created successfully.";
+    }
+
+    connect(reply, &QNetworkReply::finished, this, &HttpClient::onGetAddress);
+
+    // connect(reply, &QNetworkReply::errorOccurred, this, &HttpClient::onNetworkError);
+    // connect(reply, &QNetworkReply::sslErrors, this, &HttpClient::onSslErrors);
+}
+
+void HttpClient::onGetAddress() {
+    QNetworkReply *reply = qobject_cast<QNetworkReply *>(sender());
+    if (reply) {
+        if (reply->error() == QNetworkReply::NoError) {
+
+            QByteArray responseData = reply->readAll();
+            QJsonDocument jsonDoc = QJsonDocument::fromJson(responseData);
+            if (jsonDoc.isNull()) {
+                return;
+            }
+            else {
+                // 可以进一步处理响应数据,比如解析 JSON 或 XML
+                emit httpGetFinished(jsonDoc,m_currenturl2); // 发出信号通知外部处理
+            }
+
+        } else {
+            // 处理请求错误
+            // qDebug() << "GET Error:" << reply->errorString();
+            emit httpErrorOccurred(reply->errorString()); // 发出信号通知外部错误
+        }
+
+        reply->deleteLater();
+    }
+}
+
+void HttpClient::onNetworkError(QNetworkReply::NetworkError error) {
+    QNetworkReply *reply = qobject_cast<QNetworkReply *>(sender());
+    if (reply) {
+        emit httpErrorOccurred(reply->errorString());
+    }
+}
+
+void HttpClient::onSslErrors(const QList<QSslError> &errors) {
+    QNetworkReply *reply = qobject_cast<QNetworkReply *>(sender());
+    if (reply) {
+        QString errorString;
+        for (const QSslError &error : errors) {
+            if (!errorString.isEmpty()) {
+                errorString += ", ";
+            }
+            errorString += error.errorString();
+        }
+        emit httpErrorOccurred(errorString);
+
+        // reply->ignoreSslErrors();
+    }
+}

Some files were not shown because too many files changed in this diff