123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348 |
- #include "mainwindow.h"
- #include <QtCore/qlist.h>
- #include <QtCore/qobject.h>
- #include <QDebug>
- #include <QPushButton>
- #include <QWidget>
- #include "backendapimanager.h"
- #include "global.h"
- #include "jobs.h"
- #include "loadingWidget.h"
- #include "logger.h"
- #include "mqtt/mqttclient.h"
- #include "ui_mainwindow.h"
- // 定义 ANzI 转义序列来设置颜色
- #define ANSI_COLOR_GREEN "\x1B[32m"
- #define ANSI_COLOR_RESET "\x1B[0m"
- #include <QMessageBox>
- #include <exception>
- MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) {
- try {
- this->setWindowFlags(Qt::FramelessWindowHint | Qt::Window);
- this->setWindowState(Qt::WindowMaximized); // Maximizes the window
- // this->setFixedSize(1360, 864);
- ui->setupUi(this);
- LoadingWidget::init(ui->stackedWidget);
- initializeAnimate();
- initialMqttService();
- pageFactories[ui->btnHome] = new HomepageFactory();
- pageFactories[ui->btnNew] = new AddressFactory();
- pageFactories[ui->btnBlastProject] = new BlastProjectFactory();
- pageFactories[ui->btnEquipment] = new EquipmentFactory();
- pageFactories[ui->btnDet] = new DetInfoFactory();
- pageFactories[ui->btnBlastOper] = new BlastOperationFactory();
- pageFactories[ui->btnRecord] = new BlastRecordFactory();
- connect(ui->btnToggle, &QPushButton::clicked, this, &MainWindow::onToggleButtonClicked);
- for (auto *widget : left_button_station) {
- QPushButton *button = qobject_cast<QPushButton *>(widget);
- if (button) {
- connect(button, &QPushButton::clicked, this, [this, button] { onButtonClicked(button); });
- }
- }
- initDateTime();
- initialBtnSerial();
- // initialGPSSerial();
- ui->labLat->setText("经度: " + lat);
- ui->labLon->setText("维度: " + lon);
- connect(ui->btnClose, &QPushButton::clicked, this, &MainWindow::close);
- connect(this, &MainWindow::menubarTitleChanged, this, &MainWindow::updateProjectTitleLabel);
- } catch (const std::exception &ex) {
- Logger::getInstance().error(QString("Application crashed: %1").arg(ex.what()));
- QMessageBox::critical(this, "Error", QString("Application crashed: %1").arg(ex.what()));
- throw; // rethrow to allow further handling if needed
- } catch (...) {
- Logger::getInstance().error("Application crashed: Unknown exception");
- QMessageBox::critical(this, "Error", "Application crashed: Unknown exception");
- throw;
- }
- }
- void MainWindow::updateProjectTitleLabel(const QString &newTitle) { ui->projectTitleLable->setText(newTitle); }
- void MainWindow::handleRefreshPage() {
- // 刷新页面
- ui->stackedWidget->currentWidget()->update();
- }
- void MainWindow::setMenubarTitle(const QString &newTitle) {
- if (m_currentProjectTitle != newTitle) {
- m_currentProjectTitle = newTitle;
- // Emit the signal to notify listeners (like our QLabel slot)
- emit menubarTitleChanged(m_currentProjectTitle);
- }
- }
- void MainWindow::initializeAnimate() {
- move(200, 200);
- animate_leftFrame = new QPropertyAnimation(ui->leftFrame, "minimumWidth");
- animate_leftFrame->setDuration(300);
- for (QObject *child : ui->left_buttonsBox->children()) {
- if (qobject_cast<QWidget *>(child)) {
- left_button_station.append(qobject_cast<QWidget *>(child));
- }
- }
- }
- void MainWindow::onToggleButtonClicked() {
- // 执行动画
- JOBS ::btn_animation(ui->leftFrame, animate_leftFrame);
- for (QWidget *b : left_button_station) {
- b->setProperty("spread", !b->property("spread").toBool());
- b->setStyleSheet(b->styleSheet());
- }
- }
- // 选中按钮
- void MainWindow::onButtonClicked(QPushButton *button) {
- setStyleSheets(static_cast<QPushButton *>(button));
- switchPage(static_cast<QPushButton *>(button));
- }
- void MainWindow::switchPage(QWidget *button) {
- LoadingWidget::showLoading(this, "请稍等");
- if (pageFactories.contains(button)) {
- PageFactory *factory = pageFactories[button];
- if (createdPageByButton.contains(button)) {
- QWidget *existingPage = createdPageByButton[button];
- existingPage->hide();
- ui->stackedWidget->removeWidget(existingPage);
- createdPageByButton.remove(button);
- }
- QWidget *newPage = factory->createPage(this);
- ui->stackedWidget->addWidget(newPage);
- ui->stackedWidget->setCurrentWidget(newPage);
- setMenubarTitle(qobject_cast<QPushButton *>(button)->text());
- createdPageByButton.insert(button, newPage);
- int pageCount = ui->stackedWidget->count();
- }
- LoadingWidget::hideLoading();
- }
- void MainWindow::initialMqttService() {
- Logger::getInstance().info("Start init Mqtt server.");
- if (mainMqttClient != nullptr) {
- QMqttSubscription *projectMsgSubsciber = mainMqttClient->subscribeToTopic(MQTT_TOPIC_COMPANY_PROJECTS_SUB);
- if (projectMsgSubsciber != nullptr) {
- connect(projectMsgSubsciber, &QMqttSubscription::messageReceived, this,
- &MainWindow::handleMqttProjectsMessage);
- } else {
- Logger::getInstance().error("Failed to subscribe to MQTT topic: " + MQTT_TOPIC_COMPANY_PROJECTS_SUB);
- }
- } else {
- Logger::getInstance().error("mainMqttClient is null, cannot initialize MQTT service");
- }
- }
- void MainWindow::publishBlastProjects() {
- QJsonArray jsonArray;
- HProjectDao dao = HProjectDao(DatabaseManager::getInstance().getDatabase());
- QList<QSharedPointer<HProject>> projectsReg = dao.getAllHProjectsReg();
- for (const auto &projectPtr : projectsReg) {
- if (projectPtr) {
- QByteArray projectJson = projectPtr->ProjectToJson(*projectPtr);
- QJsonDocument doc = QJsonDocument::fromJson(projectJson);
- jsonArray.append(doc.object());
- }
- }
- QJsonDocument jsonDoc(jsonArray);
- QByteArray jsonData = jsonDoc.toJson(QJsonDocument::Indented);
- mainMqttClient->sendMessage(MQTT_TOPIC_COMPANY_PROJECTS_PUBLISH, jsonData, 2, true);
- }
- void MainWindow::handleMqttProjectsMessage(const QMqttMessage &message) {
- Logger::getInstance().info("Received Mqtt message on topic: " + message.topic().name() +
- ", message: " + QString::fromUtf8(message.payload()));
- QJsonDocument jsonDoc = QJsonDocument::fromJson(message.payload());
- 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() == BlastStatus::Created) { // "1" 未注册
- if (uuidValue.isNull()) {
- qDebug() << "uuid 的值为 null";
- } else {
- QString uuid = uuidValue.toString();
- HProjectDao dao = HProjectDao(DatabaseManager::getInstance().getDatabase());
- dao.updateBlastStatusByUuid(uuid, BlastStatus::Registered);
- }
- }
- } else if (jsonObj.contains("msgType") && jsonObj["msgType"].toString() == "blastSuccess") {
- // 爆破成功, 更新状态; 尤其是离线爆破的; 服务器收到爆破记录后发布
- HProjectDao dao = HProjectDao(DatabaseManager::getInstance().getDatabase());
- for (const QJsonValue &projectUuid : jsonObj["projectUuids"].toArray()) {
- qDebug() << "Received offline project blasted UUID: " << projectUuid;
- dao.updateBlastStatusByUuid(projectUuid.toString(), BlastStatus::Blasted);
- }
- publishBlastProjects();
- } else if (jsonObj.contains("msgType") && jsonObj["msgType"].toString() == "safeCheck") {
- // 处理安全验证消息
- if (jsonObj["status"] != "ok") {
- QMessageBox::warning(this, "安全验证失败", QString("安全验证未通过,请联系安全员确认"));
- return;
- }
- const QString addressUuid = jsonObj["addressUuid"].toString();
- QJsonArray addressList = backendAPIManager::getHAddresses();
- QList<QString> subAddressUuids = findAllChildUuids(addressList, addressUuid);
- subAddressUuids.append(addressUuid); // 添加当前地址的 UUID
- if (subAddressUuids.isEmpty()) {
- QMessageBox::information(nullptr, "安全验证失败", QString("未找到子地址,请联系安全员确认"));
- return;
- }
- HProjectDao dao = HProjectDao(DatabaseManager::getInstance().getDatabase());
- QList<QSharedPointer<HProject>> pendingCheckProjects = dao.getRegistedProjectByAddressUuid(subAddressUuids);
- for (const auto &project : pendingCheckProjects) {
- dao.updateBlastStatusByUuid(project->getUuid(), BlastStatus::SafeChecked);
- }
- if (!pendingCheckProjects.isEmpty()) {
- QMessageBox::information(nullptr, "安全员确认信息",
- QString("收到工程被安全员确认,请刷新查看爆破作业列表"));
- return;
- }
- }
- }
- }
- void MainWindow::setStyleSheets(QPushButton *selectedButton) {
- for (auto *b : left_button_station) {
- b->setProperty("selected", b == selectedButton);
- b->setStyleSheet(b->styleSheet()); // 刷新显示
- }
- }
- // 处理 MQTT 连接成功的槽函数
- void MainWindow::onMqttConnected() {
- m_isMqttConnected = true;
- Logger::getInstance().info("Mqtt connected.");
- }
- void MainWindow::initialBtnSerial() {
- bool success;
- serialTool = SerialTool::getInstance(this, &success);
- connect(serialTool, &SerialTool::serialPortOpened, this, &MainWindow::onSerialToolCreated);
- serialTool->setupSerialPort();
- Logger::getInstance().info("Fire buttons initialized");
- }
- void MainWindow::onSerialToolCreated() {
- m_btnSerialInitialized = true;
- serialTool->releaseInstance();
- qDebug() << ANSI_COLOR_GREEN << "Serial tool initialized" << ANSI_COLOR_RESET;
- Logger::getInstance().info("SerialTool initialized");
- }
- void MainWindow::initialGPSSerial() {
- Logger::getInstance().info("开始初始化GPS");
- SerialGPSThread *threadGPS = new SerialGPSThread(this);
- connect(threadGPS, &SerialGPSThread::storedGNRMCDataUpdated, this, &MainWindow::handleStoredGNRMCData);
- threadGPS->start();
- }
- // 槽函数,用于接收 RMCData 数据
- void MainWindow::handleStoredGNRMCData(const RMCData &data) {
- if (data.isValid) {
- lat = QString::number(data.latitude);
- lon = QString::number(data.longitude);
- } else {
- lat = "定位失败";
- lon = "定位失败";
- }
- ui->labLat->setText("经度: " + lat);
- ui->labLon->setText("纬度: " + lon);
- labLat = lat;
- labLon = lon;
- }
- void MainWindow::initDateTime() {
- timeThread = new TimeUpdateThread(this);
- connect(timeThread, &TimeUpdateThread::timeUpdated, this, &MainWindow::onTimeUpdated);
- timeThread->start();
- }
- void MainWindow::onTimeUpdated(const QString &timeString) { ui->dateTimeShow->setText(timeString); }
- MainWindow::~MainWindow() {
- timeThread->stop();
- delete ui;
- }
- void MainWindow::mousePressEvent(QMouseEvent *event) {
- // if (event->button() == Qt::LeftButton) {
- // m_dragPosition = event->globalPos() - frameGeometry().topLeft();
- // event->accept();
- // }
- }
- void MainWindow::mouseMoveEvent(QMouseEvent *event) {
- // if (event->buttons() & Qt::LeftButton) {
- // move(event->globalPos() - m_dragPosition);
- // event->accept();
- // }
- }
- QList<QString> MainWindow::findAllChildUuids(const QJsonArray &addressArray, const QString targetUuid) {
- QList<QString> childrenUuids;
- for (const QJsonValue &value : addressArray) {
- if (!value.isObject()) continue;
- QJsonObject addressObj = value.toObject();
- QString currentUuid = addressObj["uuid"].toString();
- if (currentUuid == targetUuid) {
- // Found the target address, now collect all children UUIDs recursively
- if (addressObj.contains("children") && addressObj["children"].isArray()) {
- QJsonArray children = addressObj["children"].toArray();
- for (const QJsonValue &child : children) {
- if (child.isObject()) {
- QString childUuid = child.toObject()["uuid"].toString();
- childrenUuids.append(childUuid);
- // max depth 3
- if (child.toObject().contains("children") && child.toObject()["children"].isArray()) {
- QJsonArray grandchildren = child.toObject()["children"].toArray();
- for (const QJsonValue &grandchild : grandchildren) {
- if (grandchild.isObject()) {
- QString grandchildUuid = grandchild.toObject()["uuid"].toString();
- childrenUuids.append(grandchildUuid);
- }
- }
- }
- }
- }
- return childrenUuids;
- }
- } else if (addressObj.contains("children") && addressObj["children"].isArray()) {
- // Continue searching in children
- QJsonArray children = addressObj["children"].toArray();
- QList<QString> result = findAllChildUuids(children, targetUuid);
- if (!result.isEmpty()) {
- return result;
- }
- }
- }
- return childrenUuids;
- }
|