浏览代码

dev: tweaks

Yao 3 周之前
父节点
当前提交
c807e5fa1a
共有 9 个文件被更改,包括 417 次插入23 次删除
  1. 4 0
      CMakeLists.txt
  2. 29 16
      blastopepage.cpp
  3. 3 0
      databasemanager.cpp
  4. 99 0
      loadingWidget.cpp
  5. 37 0
      loadingWidget.h
  6. 157 0
      logger.cpp
  7. 61 0
      logger.h
  8. 19 5
      main.cpp
  9. 8 2
      mainwindow.cpp

+ 4 - 0
CMakeLists.txt

@@ -141,6 +141,10 @@ add_executable(${PROJECT_NAME}
     worker/timeupdatethread.h worker/timeupdatethread.cpp
     logo.rc
     loadingdialog.h loadingdialog.cpp
+    logger.h
+    logger.cpp
+    loadingWidget.h
+    loadingWidget.cpp
 
 
 )

+ 29 - 16
blastopepage.cpp

@@ -2,6 +2,9 @@
 #include "ui_blastopepage.h"
 #include "countdownwidget.h"
 #include <QFont>
+#include "logger.h"
+#include <QProcessEnvironment>
+#include "loadingwidget.h"
 
 
 BlastOpePage::BlastOpePage(QWidget *parent) :
@@ -9,11 +12,9 @@ BlastOpePage::BlastOpePage(QWidget *parent) :
     ui(new Ui::BlastOpePage),
     dao(DatabaseManager::getInstance().getDatabase())
 {
-
-    ui->setupUi(this);
-    initPagination();
-    //InitFace();
-
+    InitFace();
+    //ui->setupUi(this);
+    //initPagination();
 }
 
 void BlastOpePage::showDownWidget(QString uuid,const QString &topic,const QString &message){
@@ -29,7 +30,6 @@ void BlastOpePage::showDownWidget(QString uuid,const QString &topic,const QStrin
     if (widget) {
 
         connect(countdownWidget, &CountdownWidget::countdownFinished, widget,  [widget,topic,message,countdownWidget](){
-
             widget->onCountdownFinished(topic,message);
         }, Qt::SingleShotConnection);
     }
@@ -37,7 +37,8 @@ void BlastOpePage::showDownWidget(QString uuid,const QString &topic,const QStrin
 
 void BlastOpePage::InitFace()
 {
-
+    Logger::getInstance().info("start init face verification");
+    LoadingWidget::showLoading(nullptr, "请求创建人脸识别...");
     layout = new QVBoxLayout(this);
     view = new QWebEngineView(this);
     view->setAttribute(Qt::WA_OpaquePaintEvent);
@@ -50,10 +51,13 @@ void BlastOpePage::InitFace()
         handleFeaturePermission(page, securityOrigin, feature);
     });
 
-    QUrl postUrl("http://192.168.0.255:8000/api/v1/h-face-verify/pc");
+    Logger::getInstance().info("FaceVerification: connect");
+    // QUrl postUrl("http://192.168.1.234:8000/api/v1/h-face-verify/pc");
+    QUrl postUrl(QString("%1/%2").arg().arg("h-face-verify/pc") );
     QJsonObject response = sendPostRequest(postUrl, metaInfo);
     QString certifyUrl;
     if (response.contains("data") && response["data"].isObject()) {
+        LoadingWidget::showLoading(nullptr, "正在打开人脸识别界面...");
         QJsonObject dataObject = response["data"].toObject();
         if (dataObject.contains("ResultObject") && dataObject["ResultObject"].isObject()) {
             QJsonObject resultObject = dataObject["ResultObject"].toObject();
@@ -75,14 +79,16 @@ void BlastOpePage::InitFace()
 
         QObject::connect(page, &QWebEnginePage::urlChanged, this, &BlastOpePage::onUrlChanged);
     } else {
-
-        qDebug() << "Failed to get certifyUrl.";
+        QMessageBox::information(nullptr, "提示", "人脸识别请求失败");
+        qDebug() << "Failed to get certifyUrl." << response;
+        Logger::getInstance().error("FaceVerificationInit: Failed to get certifyUrl");
     }
+    Logger::getInstance().info("FaceVerificationInit: successfully");
+    LoadingWidget::hideLoading();
 }
 
 void BlastOpePage::closeWebViewAndRestoreUI()
 {
-    //TODO: crash
     if (view) {
         layout->removeWidget(view);
         delete view;
@@ -99,7 +105,8 @@ void BlastOpePage::onUrlChanged(const QUrl &newUrl) {
     if (newUrl.scheme() == "https" && newUrl.host() == "www.baidu.com") {
         closeWebViewAndRestoreUI();
         QNetworkAccessManager manager;
-        QUrl requestUrl(QString("http://192.168.0.255:8000/api/v1/h-face-verify/certifyId/%1").arg(certifyId));
+        //QUrl requestUrl(QString("http://192.168.0.255:8000/api/v1/h-face-verify/certifyId/%1").arg(certifyId));
+        QUrl requestUrl(QString("http://192.168.1.234:8000/api/v1/h-face-verify/certifyId/%1").arg(certifyId));
         QNetworkRequest request(requestUrl);
         QNetworkReply *reply = manager.get(request);
         QEventLoop loop;
@@ -136,12 +143,12 @@ void BlastOpePage::onUrlChanged(const QUrl &newUrl) {
             }
         } else {
             qDebug() << "Request failed:" << reply->errorString();
+            Logger::getInstance().error("InitFaseVerification request failed: ");
+            Logger::getInstance().error(reply->errorString());
         }
 
         reply->deleteLater();
     }
-
-
 }
 
 
@@ -199,8 +206,14 @@ void BlastOpePage::handleFeaturePermission(QWebEnginePage *page, const QUrl &sec
 
 QJsonObject BlastOpePage::getMetaInfo() {
     QJsonObject metaInfo;
-    metaInfo["certName"] = "wangyao";
-    metaInfo["certNo"] = "";
+
+    // TODO: 获取登录用户信息
+    QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); //  获取系统环境变量
+    QString certName = env.value("certName", ""); // 第二个参数为默认值
+    QString certNo = env.value("certNo", "");
+    metaInfo["certName"] = certName;
+    metaInfo["certNo"] = certNo;
+    qDebug() << certName << certNo << "<certInfo";
     return metaInfo;
 }
 

+ 3 - 0
databasemanager.cpp

@@ -1,6 +1,7 @@
 #include "databasemanager.h"
 #include <QSqlError>
 #include <QDebug>
+#include "logger.h"
 
 DatabaseManager& DatabaseManager::getInstance() {
     static DatabaseManager instance;
@@ -17,6 +18,8 @@ DatabaseManager::DatabaseManager() : db(QSqlDatabase::addDatabase("QMYSQL")) {
     if (!db.open()) {
         qDebug() << "Failed to open database: " << db.lastError().text();
     }
+    Logger::getInstance().info("Mysql Connected");
+
 }
 
 DatabaseManager::~DatabaseManager() {

+ 99 - 0
loadingWidget.cpp

@@ -0,0 +1,99 @@
+// loadingwidget.cpp
+#include "loadingwidget.h"
+#include <QVBoxLayout>
+#include <QResizeEvent>
+#include <QApplication>
+#include <QScreen>
+#include <QLabel>
+#include <QMovie>
+
+LoadingWidget* LoadingWidget::m_instance = nullptr;
+
+LoadingWidget::LoadingWidget(QWidget *parent)
+    : QWidget(parent)
+{
+    initUI();
+}
+
+LoadingWidget* LoadingWidget::instance()
+{
+    if (!m_instance) {
+        m_instance = new LoadingWidget();
+    }
+    return m_instance;
+}
+
+void LoadingWidget::showLoading(QWidget* parent, const QString& text)
+{
+    LoadingWidget* instance = LoadingWidget::instance();
+
+    // 如果提供了parent,则设置parent
+    if (parent) {
+        instance->setParent(parent);
+    }
+
+    instance->m_textLabel->setText(text);
+    instance->m_movie->start();
+    instance->updatePosition();
+    instance->show();
+    instance->raise();
+}
+
+void LoadingWidget::hideLoading()
+{
+    if (m_instance) {
+        m_instance->m_movie->stop();
+        m_instance->hide();
+    }
+}
+
+void LoadingWidget::initUI()
+{
+    // 设置窗口属性
+    setWindowFlags(Qt::FramelessWindowHint | Qt::SubWindow);
+    setAttribute(Qt::WA_TranslucentBackground);
+    setAttribute(Qt::WA_ShowWithoutActivating);
+
+    // 创建动画
+    m_movie = new QMovie(":/icons/icons/loading.gif");
+    m_loadingLabel = new QLabel(this);
+    m_loadingLabel->setMovie(m_movie);
+    m_loadingLabel->setAlignment(Qt::AlignCenter);
+
+    // 创建文本标签
+    m_textLabel = new QLabel(this);
+    m_textLabel->setAlignment(Qt::AlignCenter);
+
+    // 布局
+    QVBoxLayout* layout = new QVBoxLayout(this);
+    layout->addWidget(m_loadingLabel);
+    layout->addWidget(m_textLabel);
+    layout->setSpacing(10);
+    layout->setContentsMargins(20, 20, 20, 20);
+
+    // 样式
+    setStyleSheet("background-color: rgba(0, 0, 0, 150); border-radius: 10px;");
+    m_textLabel->setStyleSheet("color: white; font-size: 16px;");
+
+    // 初始隐藏
+    hide();
+}
+
+void LoadingWidget::resizeEvent(QResizeEvent *event)
+{
+    QWidget::resizeEvent(event);
+    updatePosition();
+}
+
+void LoadingWidget::updatePosition()
+{
+    if (parentWidget()) {
+        // 居中显示在父窗口
+        QRect parentRect = parentWidget()->rect();
+        move(parentRect.center() - rect().center());
+    } else {
+        // 如果没有父窗口,居中显示在屏幕
+        QRect screenGeometry = QApplication::primaryScreen()->geometry();
+        move(screenGeometry.center() - rect().center());
+    }
+}

+ 37 - 0
loadingWidget.h

@@ -0,0 +1,37 @@
+#ifndef LOADINGWIDGET_H
+#define LOADINGWIDGET_H
+
+#include <QWidget>
+
+class QLabel;
+class QMovie;
+
+class LoadingWidget : public QWidget
+{
+    Q_OBJECT
+public:
+    // 获取全局实例
+    static LoadingWidget* instance();
+
+    // 显示加载 (可选parent,不传则居中于屏幕)
+    static void showLoading(QWidget* parent = nullptr, const QString& text = "Loading...");
+
+    // 隐藏加载
+    static void hideLoading();
+
+protected:
+    void resizeEvent(QResizeEvent *event) override;
+
+private:
+    explicit LoadingWidget(QWidget *parent = nullptr);
+    static LoadingWidget* m_instance;
+
+    void updatePosition();
+    void initUI();
+
+    QLabel* m_loadingLabel;
+    QLabel* m_textLabel;
+    QMovie* m_movie;
+};
+
+#endif // LOADINGWIDGET_H

+ 157 - 0
logger.cpp

@@ -0,0 +1,157 @@
+#include "Logger.h"
+#include <QDebug>
+#include <QDir>
+#include <QFileInfo>
+
+// Initialize static members
+QScopedPointer<Logger> Logger::m_instance; // Correct: Default constructs to a null pointer
+QMutex Logger::m_instanceMutex;
+
+Logger& Logger::getInstance(const QString &filePath)
+{
+    // Use a QMutexLocker to ensure thread-safe initialization of the singleton
+    QMutexLocker locker(&m_instanceMutex);
+    if (m_instance.isNull()) {
+        if (filePath.isEmpty()) {
+            qWarning() << "Logger: No file path provided for initial singleton creation. Logging might be disabled.";
+            // Fallback to a default or disable logging, or throw an error.
+            // For simplicity, we'll proceed but warn.
+            m_instance.reset(new Logger("default.log")); // Provide a default if not given
+        } else {
+            m_instance.reset(new Logger(filePath));
+        }
+    }
+    return *m_instance;
+}
+
+// Private constructor
+Logger::Logger(const QString &filePath)
+    : m_logFile(filePath),
+    m_textStream(&m_logFile),
+    m_maxFileSize(10 * 1024 * 1024), // Default to 10 MB
+    m_maxBackupFiles(5)             // Default to 5 backup files
+{
+    QFileInfo fileInfo(filePath);
+    QDir dir = fileInfo.absoluteDir();
+    if (!dir.exists()) {
+        dir.mkpath("."); // Create directory if it doesn't exist
+    }
+
+    if (!m_logFile.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text)) {
+        qWarning() << "Logger: Could not open log file for writing:" << m_logFile.errorString();
+    } else {
+        info("Logger initialized."); // Log the initialization
+    }
+}
+
+// Private destructor
+Logger::~Logger()
+{
+    if (m_logFile.isOpen()) {
+        info("Logger shutting down."); // Log shutdown
+        m_logFile.close();
+    }
+}
+
+void Logger::debug(const QString &message)
+{
+    writeLog(Debug, message);
+}
+
+void Logger::info(const QString &message)
+{
+    writeLog(Info, message);
+}
+
+void Logger::warn(const QString &message)
+{
+    writeLog(Warning, message);
+}
+
+void Logger::error(const QString &message)
+{
+    writeLog(Error, message);
+}
+
+void Logger::critical(const QString &message)
+{
+    writeLog(Critical, message);
+}
+
+void Logger::writeLog(LogLevel level, const QString &message)
+{
+    QMutexLocker locker(&m_mutex);
+
+    if (!m_logFile.isOpen()) {
+        qWarning() << "Logger: Log file is not open. Message not written:" << message;
+        return;
+    }
+
+    if (m_logFile.size() > m_maxFileSize) {
+        rotateLogFile();
+    }
+
+    QString timestamp = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz");
+    QString logLevelStr = logLevelToString(level);
+
+    m_textStream << QString("[%1] [%2] %3\n").arg(timestamp).arg(logLevelStr).arg(message);
+    m_textStream.flush();
+}
+
+void Logger::setMaxFileSize(qint64 bytes)
+{
+    m_maxFileSize = bytes;
+}
+
+void Logger::setMaxBackupFiles(int count)
+{
+    m_maxBackupFiles = count;
+}
+
+void Logger::rotateLogFile()
+{
+    m_logFile.close();
+
+    QFileInfo fileInfo(m_logFile.fileName());
+    QString baseName = fileInfo.baseName();
+    QString suffix = fileInfo.suffix();
+    QString absolutePath = fileInfo.absolutePath();
+
+    for (int i = m_maxBackupFiles - 1; i >= 0; --i) {
+        QString oldLogFileName = QString("%1/%2.%3.%4").arg(absolutePath).arg(baseName).arg(i).arg(suffix);
+        QFile oldLogFile(oldLogFileName);
+        if (oldLogFile.exists()) {
+            if (i == m_maxBackupFiles - 1) {
+                oldLogFile.remove();
+            } else {
+                QString newLogFileName = QString("%1/%2.%3.%4").arg(absolutePath).arg(baseName).arg(i + 1).arg(suffix);
+                oldLogFile.rename(newLogFileName);
+            }
+        }
+    }
+
+    QString newCurrentLogFileName = QString("%1/%2.%3.%4").arg(absolutePath).arg(baseName).arg(0).arg(suffix);
+    m_logFile.rename(newCurrentLogFileName);
+
+    if (!m_logFile.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text)) {
+        qWarning() << "Logger: Could not reopen log file after rotation:" << m_logFile.errorString();
+    }
+}
+
+QString Logger::logLevelToString(LogLevel level) const
+{
+    switch (level) {
+    case Debug:
+        return "DEBUG";
+    case Info:
+        return "INFO";
+    case Warning:
+        return "WARNING";
+    case Error:
+        return "ERROR";
+    case Critical:
+        return "CRITICAL";
+    default:
+        return "UNKNOWN";
+    }
+}

+ 61 - 0
logger.h

@@ -0,0 +1,61 @@
+#ifndef LOGGER_H
+#define LOGGER_H
+
+#include <QFile>
+#include <QTextStream>
+#include <QDateTime>
+#include <QMutex>
+#include <QString>
+#include <QScopedPointer>
+
+class Logger
+{
+public:
+    enum LogLevel {
+        Debug,
+        Info,
+        Warning,
+        Error,
+        Critical
+    };
+
+    // Public static method to get the single instance of the Logger
+    static Logger& getInstance(const QString &filePath = "");
+
+    // Direct logging methods
+    void debug(const QString &message);
+    void info(const QString &message);
+    void warn(const QString &message);
+    void error(const QString &message);
+    void critical(const QString &message);
+
+    void setMaxFileSize(qint64 bytes);
+    void setMaxBackupFiles(int count);
+
+    // Make the destructor public so QScopedPointer can call it
+    ~Logger(); // <-- CHANGE THIS LINE: MOVED FROM PRIVATE TO PUBLIC
+
+private:
+    // Private constructor to prevent direct instantiation
+    explicit Logger(const QString &filePath);
+
+    // Delete copy constructor and assignment operator to prevent copying
+    Logger(const Logger&) = delete;
+    Logger& operator=(const Logger&) = delete;
+
+    QFile m_logFile;
+    QTextStream m_textStream;
+    QMutex m_mutex;
+    qint64 m_maxFileSize;
+    int m_maxBackupFiles;
+
+    void writeLog(LogLevel level, const QString &message);
+    void rotateLogFile();
+    QString logLevelToString(LogLevel level) const;
+
+    // Static members for the singleton instance
+    static QScopedPointer<Logger> m_instance;
+    static QMutex m_instanceMutex;
+};
+
+#endif // LOGGER_H

+ 19 - 5
main.cpp

@@ -1,13 +1,21 @@
 #include "mainwindow.h"
 #include "loginwindow.h"
+#include "logger.h"
 #include "fireWidget/firingwidget.h"
 #include <QApplication>
 #include <QFile>
 #include <QTextStream>
+#include <QQuickWindow>  // 关键头文件
+
 
 int main(int argc, char *argv[])
 {
     QApplication a(argc, argv);
+
+    //TODO: 确认硬件配置,是否需要使用GPU及设备是否安装驱动
+    //QCoreApplication::setAttribute(Qt::AA_UseOpenGLES); // 强制使用 ANGLE (OpenGL ES over DirectX/Vulkan)
+    QQuickWindow::setSceneGraphBackend("software"); // 兼容性: 禁用GPU
+
     // 加载 QSS 文件
     QFile styleFile(":/qss/qss/tableview.qss");
     if (styleFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
@@ -16,24 +24,30 @@ int main(int argc, char *argv[])
         a.setStyleSheet(styleSheet);
         styleFile.close();
     }
-
     // // 获取屏幕信息
     // QScreen *screen = QGuiApplication::primaryScreen();
     // QRect screenGeometry = screen->geometry();
     // int screenWidth = screenGeometry.width();
     // int screenHeight = screenGeometry.height();
 
+    // logger
+    Logger::getInstance("application.log");
+
+    // Optional: Set logger configurations
+    Logger::getInstance().setMaxFileSize(2 * 1024 * 1024); // 2 MB
+    Logger::getInstance().setMaxBackupFiles(3);           // Keep 3 backup files
+    Logger::getInstance().info("Application started from main.");
+
+
     MainWindow w;
     // Page w;
     // pageTest w;
-    // LoginWindow w;
-    // loginWindow.show();
+    //LoginWindow w;
+     //loginWindow.show();
     // 设置应用程序图标
     a.setWindowIcon(QIcon(":/icons/icons/l634z-aceaj-001.ico"));
     // w.resize(screenWidth * 1, screenHeight * 0.95);
     // firingWidget w;
     w.show();
-
-
     return a.exec();
 }

+ 8 - 2
mainwindow.cpp

@@ -4,6 +4,7 @@
 #include <QDebug>
 #include <QWidget>
 #include <QPushButton>
+#include "logger.h"
 
 // 定义 ANzI 转义序列来设置颜色
 #define ANSI_COLOR_GREEN "\x1B[32m"
@@ -40,7 +41,7 @@ MainWindow::MainWindow(QWidget *parent)
     }
     initDateTime();
     initialBtnSerial();
-    initialGPSSerial();
+    // initialGPSSerial();
     ui->labLat->setText("经度: "+lat);
     ui->labLon->setText("维度: "+lon);
     connect(ui->btnClose, &QPushButton::clicked, this, &MainWindow::close);
@@ -115,10 +116,13 @@ void MainWindow::switchPage(QWidget *button) {
 
 void MainWindow::initialMqttService()
 {
+    Logger::getInstance().info("Start init Mqtt server");
+
     MqttClient *pcMqttInit = MqttClient::getInstance();
     QStringList topics = {"hxgc/topic","hxgc/companycode/pro/P"};
     pcMqttInit->connectToMqttBroker("114.55.233.194", 1883, "hxgc", "hxgc123456", "pcMqttInitY11", topics);
     connect(pcMqttInit, &MqttClient::proMessageReceived, this, &MainWindow::messageAndTopicReceived);
+    Logger::getInstance().info("Mqtt service initialized");
 }
 
 void MainWindow::messageAndTopicReceived(const QByteArray &message, const QMqttTopicName &topic){
@@ -163,6 +167,7 @@ void MainWindow::initialBtnSerial()
     serialTool = SerialTool::getInstance(this,&success);
     connect(serialTool, &SerialTool::serialPortOpened, this, &MainWindow::onSerialToolCreated);
     serialTool->setupSerialPort();
+    Logger::getInstance().info("Fire buttons initialized");
 }
 
 void MainWindow::onSerialToolCreated()
@@ -171,10 +176,11 @@ void MainWindow::onSerialToolCreated()
     serialTool->releaseInstance();
     qDebug() << ANSI_COLOR_GREEN << "Serial tool initialized" << ANSI_COLOR_RESET;
 
-
+    Logger::getInstance().info("SerialTool created");
 }
 
 void MainWindow::initialGPSSerial(){
+    Logger::getInstance().info("Start init GPS");
     SerialGPSThread* threadGPS = new SerialGPSThread(this);
     connect(threadGPS, &SerialGPSThread::storedGNRMCDataUpdated, this,&MainWindow::handleStoredGNRMCData);
     threadGPS->start();