diff --git a/CounterAcq/CounterAcq.pro b/CounterAcq/CounterAcq.pro index 72407cd..fae9d10 100644 --- a/CounterAcq/CounterAcq.pro +++ b/CounterAcq/CounterAcq.pro @@ -4,13 +4,6 @@ CONFIG += c++11 -SOURCES += \ - CounterWindow.cpp \ - main.cpp \ - -HEADERS += \ - CounterWindow.h \ - FORMS += \ CounterWindow.ui \ @@ -18,8 +11,11 @@ include(protocol/protocol.pri) HEADERS += CounterDevice.h +HEADERS += CounterWindow.h SOURCES += CounterDevice.cpp +SOURCES += CounterWindow.cpp +SOURCES += main.cpp DISTFILES += conf/config.ini diff --git a/CounterAcq/CounterAcq.pro b/CounterAcq/CounterAcq.pro index 72407cd..fae9d10 100644 --- a/CounterAcq/CounterAcq.pro +++ b/CounterAcq/CounterAcq.pro @@ -4,13 +4,6 @@ CONFIG += c++11 -SOURCES += \ - CounterWindow.cpp \ - main.cpp \ - -HEADERS += \ - CounterWindow.h \ - FORMS += \ CounterWindow.ui \ @@ -18,8 +11,11 @@ include(protocol/protocol.pri) HEADERS += CounterDevice.h +HEADERS += CounterWindow.h SOURCES += CounterDevice.cpp +SOURCES += CounterWindow.cpp +SOURCES += main.cpp DISTFILES += conf/config.ini diff --git a/CounterAcq/CounterWindow.cpp b/CounterAcq/CounterWindow.cpp index 80035a9..a50ebcf 100644 --- a/CounterAcq/CounterWindow.cpp +++ b/CounterAcq/CounterWindow.cpp @@ -42,7 +42,7 @@ { QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); - QApplication::exit(0); + QTimer::singleShot(1000, qApp, SLOT(quit())); } // 2. 获取字典值:设备类型 retCode = this->initDictDeviceTypes(); diff --git a/CounterAcq/CounterAcq.pro b/CounterAcq/CounterAcq.pro index 72407cd..fae9d10 100644 --- a/CounterAcq/CounterAcq.pro +++ b/CounterAcq/CounterAcq.pro @@ -4,13 +4,6 @@ CONFIG += c++11 -SOURCES += \ - CounterWindow.cpp \ - main.cpp \ - -HEADERS += \ - CounterWindow.h \ - FORMS += \ CounterWindow.ui \ @@ -18,8 +11,11 @@ include(protocol/protocol.pri) HEADERS += CounterDevice.h +HEADERS += CounterWindow.h SOURCES += CounterDevice.cpp +SOURCES += CounterWindow.cpp +SOURCES += main.cpp DISTFILES += conf/config.ini diff --git a/CounterAcq/CounterWindow.cpp b/CounterAcq/CounterWindow.cpp index 80035a9..a50ebcf 100644 --- a/CounterAcq/CounterWindow.cpp +++ b/CounterAcq/CounterWindow.cpp @@ -42,7 +42,7 @@ { QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); - QApplication::exit(0); + QTimer::singleShot(1000, qApp, SLOT(quit())); } // 2. 获取字典值:设备类型 retCode = this->initDictDeviceTypes(); diff --git a/CounterAcq/CounterWindow.h b/CounterAcq/CounterWindow.h index 8d5e4a6..09277ba 100644 --- a/CounterAcq/CounterWindow.h +++ b/CounterAcq/CounterWindow.h @@ -7,7 +7,6 @@ #include #include "common/utils/SettingConfig.h" -#include "common/utils/QKafkaUtil.h" #include "common/HttpRequestController.h" #include "CounterDevice.h" @@ -23,8 +22,6 @@ explicit CounterWindow(QWidget *parent = nullptr); ~CounterWindow(); - QString token; - public slots: void drawCounterDataOnPage(CounterDataDto * counterData); @@ -40,7 +37,6 @@ Ui::CounterWindow *ui; - QTimer * timer; HttpRequestController * httpReq; QList deviceList; diff --git a/CounterAcq/CounterAcq.pro b/CounterAcq/CounterAcq.pro index 72407cd..fae9d10 100644 --- a/CounterAcq/CounterAcq.pro +++ b/CounterAcq/CounterAcq.pro @@ -4,13 +4,6 @@ CONFIG += c++11 -SOURCES += \ - CounterWindow.cpp \ - main.cpp \ - -HEADERS += \ - CounterWindow.h \ - FORMS += \ CounterWindow.ui \ @@ -18,8 +11,11 @@ include(protocol/protocol.pri) HEADERS += CounterDevice.h +HEADERS += CounterWindow.h SOURCES += CounterDevice.cpp +SOURCES += CounterWindow.cpp +SOURCES += main.cpp DISTFILES += conf/config.ini diff --git a/CounterAcq/CounterWindow.cpp b/CounterAcq/CounterWindow.cpp index 80035a9..a50ebcf 100644 --- a/CounterAcq/CounterWindow.cpp +++ b/CounterAcq/CounterWindow.cpp @@ -42,7 +42,7 @@ { QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); - QApplication::exit(0); + QTimer::singleShot(1000, qApp, SLOT(quit())); } // 2. 获取字典值:设备类型 retCode = this->initDictDeviceTypes(); diff --git a/CounterAcq/CounterWindow.h b/CounterAcq/CounterWindow.h index 8d5e4a6..09277ba 100644 --- a/CounterAcq/CounterWindow.h +++ b/CounterAcq/CounterWindow.h @@ -7,7 +7,6 @@ #include #include "common/utils/SettingConfig.h" -#include "common/utils/QKafkaUtil.h" #include "common/HttpRequestController.h" #include "CounterDevice.h" @@ -23,8 +22,6 @@ explicit CounterWindow(QWidget *parent = nullptr); ~CounterWindow(); - QString token; - public slots: void drawCounterDataOnPage(CounterDataDto * counterData); @@ -40,7 +37,6 @@ Ui::CounterWindow *ui; - QTimer * timer; HttpRequestController * httpReq; QList deviceList; diff --git a/PhaseCompAcq/PhaseCompAcq.pro b/PhaseCompAcq/PhaseCompAcq.pro index 5eef2d1..c5e895b 100644 --- a/PhaseCompAcq/PhaseCompAcq.pro +++ b/PhaseCompAcq/PhaseCompAcq.pro @@ -1,16 +1,9 @@ -QT += core gui serialport +QT += core gui serialport network greaterThan(QT_MAJOR_VERSION, 4): QT += widgets CONFIG += c++11 -SOURCES += \ - main.cpp \ - PhaseWindow.cpp - -HEADERS += \ - PhaseWindow.h - FORMS += \ PhaseWindow.ui @@ -18,20 +11,19 @@ include(protocol/protocol.pri) HEADERS += PhaseDevice.h -#HEADERS += PhaseSerialServer.h +HEADERS += PhaseWindow.h SOURCES += PhaseDevice.cpp -#SOURCES += PhaseSerialServer.cpp +SOURCES += PhaseWindow.cpp +SOURCES += main.cpp # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target - -INCLUDEPATH += $$PWD/include/librdkafka -DEPENDPATH += $$PWD/include/librdkafka +#unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +#INCLUDEPATH += $$PWD/include/librdkafka +#DEPENDPATH += $$PWD/include/librdkafka DISTFILES += conf/config.ini - -unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ diff --git a/CounterAcq/CounterAcq.pro b/CounterAcq/CounterAcq.pro index 72407cd..fae9d10 100644 --- a/CounterAcq/CounterAcq.pro +++ b/CounterAcq/CounterAcq.pro @@ -4,13 +4,6 @@ CONFIG += c++11 -SOURCES += \ - CounterWindow.cpp \ - main.cpp \ - -HEADERS += \ - CounterWindow.h \ - FORMS += \ CounterWindow.ui \ @@ -18,8 +11,11 @@ include(protocol/protocol.pri) HEADERS += CounterDevice.h +HEADERS += CounterWindow.h SOURCES += CounterDevice.cpp +SOURCES += CounterWindow.cpp +SOURCES += main.cpp DISTFILES += conf/config.ini diff --git a/CounterAcq/CounterWindow.cpp b/CounterAcq/CounterWindow.cpp index 80035a9..a50ebcf 100644 --- a/CounterAcq/CounterWindow.cpp +++ b/CounterAcq/CounterWindow.cpp @@ -42,7 +42,7 @@ { QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); - QApplication::exit(0); + QTimer::singleShot(1000, qApp, SLOT(quit())); } // 2. 获取字典值:设备类型 retCode = this->initDictDeviceTypes(); diff --git a/CounterAcq/CounterWindow.h b/CounterAcq/CounterWindow.h index 8d5e4a6..09277ba 100644 --- a/CounterAcq/CounterWindow.h +++ b/CounterAcq/CounterWindow.h @@ -7,7 +7,6 @@ #include #include "common/utils/SettingConfig.h" -#include "common/utils/QKafkaUtil.h" #include "common/HttpRequestController.h" #include "CounterDevice.h" @@ -23,8 +22,6 @@ explicit CounterWindow(QWidget *parent = nullptr); ~CounterWindow(); - QString token; - public slots: void drawCounterDataOnPage(CounterDataDto * counterData); @@ -40,7 +37,6 @@ Ui::CounterWindow *ui; - QTimer * timer; HttpRequestController * httpReq; QList deviceList; diff --git a/PhaseCompAcq/PhaseCompAcq.pro b/PhaseCompAcq/PhaseCompAcq.pro index 5eef2d1..c5e895b 100644 --- a/PhaseCompAcq/PhaseCompAcq.pro +++ b/PhaseCompAcq/PhaseCompAcq.pro @@ -1,16 +1,9 @@ -QT += core gui serialport +QT += core gui serialport network greaterThan(QT_MAJOR_VERSION, 4): QT += widgets CONFIG += c++11 -SOURCES += \ - main.cpp \ - PhaseWindow.cpp - -HEADERS += \ - PhaseWindow.h - FORMS += \ PhaseWindow.ui @@ -18,20 +11,19 @@ include(protocol/protocol.pri) HEADERS += PhaseDevice.h -#HEADERS += PhaseSerialServer.h +HEADERS += PhaseWindow.h SOURCES += PhaseDevice.cpp -#SOURCES += PhaseSerialServer.cpp +SOURCES += PhaseWindow.cpp +SOURCES += main.cpp # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target - -INCLUDEPATH += $$PWD/include/librdkafka -DEPENDPATH += $$PWD/include/librdkafka +#unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +#INCLUDEPATH += $$PWD/include/librdkafka +#DEPENDPATH += $$PWD/include/librdkafka DISTFILES += conf/config.ini - -unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ diff --git a/PhaseCompAcq/PhaseDevice.cpp b/PhaseCompAcq/PhaseDevice.cpp index 5c84cd5..afc2687 100644 --- a/PhaseCompAcq/PhaseDevice.cpp +++ b/PhaseCompAcq/PhaseDevice.cpp @@ -7,9 +7,9 @@ connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, this, &PhaseDevice::dataReceivedHandler); - kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); - kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); - kafkaUtil.createProducer(); +// kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); +// kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); +// kafkaUtil.createProducer(); } PhaseDevice::~PhaseDevice() @@ -34,6 +34,10 @@ { this->devCode = devCode; } +void PhaseDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} bool PhaseDevice::isSerialOpen() { @@ -74,6 +78,7 @@ if (parse == true) { QDateTime now = QDateTime::currentDateTime(); + phaseData->devCode = this->devCode; phaseData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); phaseData->milisecond = now.toMSecsSinceEpoch(); this->afterFramePhase(phaseData); @@ -92,21 +97,20 @@ this->dataBuff.clear(); // 2. 输出到日志文件中 - QString filePostfix = phaseData->timestamp.mid(0, 13).replace(" ", "_"); - QString filePrefix = QApplication::applicationDirPath() + "/logs/"; + QString date = phaseData->timestamp.mid(0, 10); // 2.1 原始字节数组数据 - QString filename = filePrefix + "raw_" + filePostfix + ".log"; + QString filename = "raw_" + devCode + ".log"; QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); - QLogUtil::writeRawDataLog(filename, content); + QLogUtil::writeRawDataLogByDate(date, filename, content); // 2.2 各个通道的相差数据 for (int i = 1; i <= phaseData->channelActive.size(); i++) { if (phaseData->channelActive.at(i-1).toUInt() == 1) { - QString chFilename("%1CH_%2_%3.log"); - chFilename = chFilename.arg(filePrefix); + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); if (i < 10) { chFilename = chFilename.arg(QString("0%1").arg(i)); @@ -114,10 +118,9 @@ { chFilename = chFilename.arg(i); } - chFilename = chFilename.arg(filePostfix); - QString channelDataStr = QString("%1 %2 %3").arg(phaseData->timestamp).arg(phaseData->channelData.at(i-1)).arg(phaseData->frameId); + QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelData.at(i-1)); - QLogUtil::writeChannelDataLog(chFilename, channelDataStr); + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); // 3. 输出到中间件,执行后续处理过程 if (SettingConfig::getInstance().NEED_KAFKA == 1) @@ -125,7 +128,7 @@ QJsonObject jsonObj = phaseData->toJSON(i - 1); jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); jsonObj.insert("deviceId", devCode); - kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); +// kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); } } } diff --git a/CounterAcq/CounterAcq.pro b/CounterAcq/CounterAcq.pro index 72407cd..fae9d10 100644 --- a/CounterAcq/CounterAcq.pro +++ b/CounterAcq/CounterAcq.pro @@ -4,13 +4,6 @@ CONFIG += c++11 -SOURCES += \ - CounterWindow.cpp \ - main.cpp \ - -HEADERS += \ - CounterWindow.h \ - FORMS += \ CounterWindow.ui \ @@ -18,8 +11,11 @@ include(protocol/protocol.pri) HEADERS += CounterDevice.h +HEADERS += CounterWindow.h SOURCES += CounterDevice.cpp +SOURCES += CounterWindow.cpp +SOURCES += main.cpp DISTFILES += conf/config.ini diff --git a/CounterAcq/CounterWindow.cpp b/CounterAcq/CounterWindow.cpp index 80035a9..a50ebcf 100644 --- a/CounterAcq/CounterWindow.cpp +++ b/CounterAcq/CounterWindow.cpp @@ -42,7 +42,7 @@ { QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); - QApplication::exit(0); + QTimer::singleShot(1000, qApp, SLOT(quit())); } // 2. 获取字典值:设备类型 retCode = this->initDictDeviceTypes(); diff --git a/CounterAcq/CounterWindow.h b/CounterAcq/CounterWindow.h index 8d5e4a6..09277ba 100644 --- a/CounterAcq/CounterWindow.h +++ b/CounterAcq/CounterWindow.h @@ -7,7 +7,6 @@ #include #include "common/utils/SettingConfig.h" -#include "common/utils/QKafkaUtil.h" #include "common/HttpRequestController.h" #include "CounterDevice.h" @@ -23,8 +22,6 @@ explicit CounterWindow(QWidget *parent = nullptr); ~CounterWindow(); - QString token; - public slots: void drawCounterDataOnPage(CounterDataDto * counterData); @@ -40,7 +37,6 @@ Ui::CounterWindow *ui; - QTimer * timer; HttpRequestController * httpReq; QList deviceList; diff --git a/PhaseCompAcq/PhaseCompAcq.pro b/PhaseCompAcq/PhaseCompAcq.pro index 5eef2d1..c5e895b 100644 --- a/PhaseCompAcq/PhaseCompAcq.pro +++ b/PhaseCompAcq/PhaseCompAcq.pro @@ -1,16 +1,9 @@ -QT += core gui serialport +QT += core gui serialport network greaterThan(QT_MAJOR_VERSION, 4): QT += widgets CONFIG += c++11 -SOURCES += \ - main.cpp \ - PhaseWindow.cpp - -HEADERS += \ - PhaseWindow.h - FORMS += \ PhaseWindow.ui @@ -18,20 +11,19 @@ include(protocol/protocol.pri) HEADERS += PhaseDevice.h -#HEADERS += PhaseSerialServer.h +HEADERS += PhaseWindow.h SOURCES += PhaseDevice.cpp -#SOURCES += PhaseSerialServer.cpp +SOURCES += PhaseWindow.cpp +SOURCES += main.cpp # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target - -INCLUDEPATH += $$PWD/include/librdkafka -DEPENDPATH += $$PWD/include/librdkafka +#unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +#INCLUDEPATH += $$PWD/include/librdkafka +#DEPENDPATH += $$PWD/include/librdkafka DISTFILES += conf/config.ini - -unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ diff --git a/PhaseCompAcq/PhaseDevice.cpp b/PhaseCompAcq/PhaseDevice.cpp index 5c84cd5..afc2687 100644 --- a/PhaseCompAcq/PhaseDevice.cpp +++ b/PhaseCompAcq/PhaseDevice.cpp @@ -7,9 +7,9 @@ connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, this, &PhaseDevice::dataReceivedHandler); - kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); - kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); - kafkaUtil.createProducer(); +// kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); +// kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); +// kafkaUtil.createProducer(); } PhaseDevice::~PhaseDevice() @@ -34,6 +34,10 @@ { this->devCode = devCode; } +void PhaseDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} bool PhaseDevice::isSerialOpen() { @@ -74,6 +78,7 @@ if (parse == true) { QDateTime now = QDateTime::currentDateTime(); + phaseData->devCode = this->devCode; phaseData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); phaseData->milisecond = now.toMSecsSinceEpoch(); this->afterFramePhase(phaseData); @@ -92,21 +97,20 @@ this->dataBuff.clear(); // 2. 输出到日志文件中 - QString filePostfix = phaseData->timestamp.mid(0, 13).replace(" ", "_"); - QString filePrefix = QApplication::applicationDirPath() + "/logs/"; + QString date = phaseData->timestamp.mid(0, 10); // 2.1 原始字节数组数据 - QString filename = filePrefix + "raw_" + filePostfix + ".log"; + QString filename = "raw_" + devCode + ".log"; QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); - QLogUtil::writeRawDataLog(filename, content); + QLogUtil::writeRawDataLogByDate(date, filename, content); // 2.2 各个通道的相差数据 for (int i = 1; i <= phaseData->channelActive.size(); i++) { if (phaseData->channelActive.at(i-1).toUInt() == 1) { - QString chFilename("%1CH_%2_%3.log"); - chFilename = chFilename.arg(filePrefix); + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); if (i < 10) { chFilename = chFilename.arg(QString("0%1").arg(i)); @@ -114,10 +118,9 @@ { chFilename = chFilename.arg(i); } - chFilename = chFilename.arg(filePostfix); - QString channelDataStr = QString("%1 %2 %3").arg(phaseData->timestamp).arg(phaseData->channelData.at(i-1)).arg(phaseData->frameId); + QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelData.at(i-1)); - QLogUtil::writeChannelDataLog(chFilename, channelDataStr); + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); // 3. 输出到中间件,执行后续处理过程 if (SettingConfig::getInstance().NEED_KAFKA == 1) @@ -125,7 +128,7 @@ QJsonObject jsonObj = phaseData->toJSON(i - 1); jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); jsonObj.insert("deviceId", devCode); - kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); +// kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); } } } diff --git a/PhaseCompAcq/PhaseDevice.h b/PhaseCompAcq/PhaseDevice.h index 92182d4..aa7d822 100644 --- a/PhaseCompAcq/PhaseDevice.h +++ b/PhaseCompAcq/PhaseDevice.h @@ -5,7 +5,7 @@ #include "common/utils/QSerialPortUtil.h" #include "common/utils/QLogUtil.h" #include "common/utils/SettingConfig.h" -#include "common/utils/QKafkaUtil.h" +//#include "common/utils/QKafkaUtil.h" #include "protocol/PhaseProtocolBM.h" class PhaseDevice : public QObject @@ -25,15 +25,17 @@ void setBaudRate(int baudRate); QString getDevCode(); void setDevCode(QString devCode); + void setDeviceId(QString deviceId); bool isSerialOpen(); private: + QString deviceId; QString devCode; QString comName; int baudRate; QSerialPortUtil serialUtil; - QKafkaUtil kafkaUtil; +// QKafkaUtil kafkaUtil; QByteArray dataBuff; signals: diff --git a/CounterAcq/CounterAcq.pro b/CounterAcq/CounterAcq.pro index 72407cd..fae9d10 100644 --- a/CounterAcq/CounterAcq.pro +++ b/CounterAcq/CounterAcq.pro @@ -4,13 +4,6 @@ CONFIG += c++11 -SOURCES += \ - CounterWindow.cpp \ - main.cpp \ - -HEADERS += \ - CounterWindow.h \ - FORMS += \ CounterWindow.ui \ @@ -18,8 +11,11 @@ include(protocol/protocol.pri) HEADERS += CounterDevice.h +HEADERS += CounterWindow.h SOURCES += CounterDevice.cpp +SOURCES += CounterWindow.cpp +SOURCES += main.cpp DISTFILES += conf/config.ini diff --git a/CounterAcq/CounterWindow.cpp b/CounterAcq/CounterWindow.cpp index 80035a9..a50ebcf 100644 --- a/CounterAcq/CounterWindow.cpp +++ b/CounterAcq/CounterWindow.cpp @@ -42,7 +42,7 @@ { QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); - QApplication::exit(0); + QTimer::singleShot(1000, qApp, SLOT(quit())); } // 2. 获取字典值:设备类型 retCode = this->initDictDeviceTypes(); diff --git a/CounterAcq/CounterWindow.h b/CounterAcq/CounterWindow.h index 8d5e4a6..09277ba 100644 --- a/CounterAcq/CounterWindow.h +++ b/CounterAcq/CounterWindow.h @@ -7,7 +7,6 @@ #include #include "common/utils/SettingConfig.h" -#include "common/utils/QKafkaUtil.h" #include "common/HttpRequestController.h" #include "CounterDevice.h" @@ -23,8 +22,6 @@ explicit CounterWindow(QWidget *parent = nullptr); ~CounterWindow(); - QString token; - public slots: void drawCounterDataOnPage(CounterDataDto * counterData); @@ -40,7 +37,6 @@ Ui::CounterWindow *ui; - QTimer * timer; HttpRequestController * httpReq; QList deviceList; diff --git a/PhaseCompAcq/PhaseCompAcq.pro b/PhaseCompAcq/PhaseCompAcq.pro index 5eef2d1..c5e895b 100644 --- a/PhaseCompAcq/PhaseCompAcq.pro +++ b/PhaseCompAcq/PhaseCompAcq.pro @@ -1,16 +1,9 @@ -QT += core gui serialport +QT += core gui serialport network greaterThan(QT_MAJOR_VERSION, 4): QT += widgets CONFIG += c++11 -SOURCES += \ - main.cpp \ - PhaseWindow.cpp - -HEADERS += \ - PhaseWindow.h - FORMS += \ PhaseWindow.ui @@ -18,20 +11,19 @@ include(protocol/protocol.pri) HEADERS += PhaseDevice.h -#HEADERS += PhaseSerialServer.h +HEADERS += PhaseWindow.h SOURCES += PhaseDevice.cpp -#SOURCES += PhaseSerialServer.cpp +SOURCES += PhaseWindow.cpp +SOURCES += main.cpp # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target - -INCLUDEPATH += $$PWD/include/librdkafka -DEPENDPATH += $$PWD/include/librdkafka +#unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +#INCLUDEPATH += $$PWD/include/librdkafka +#DEPENDPATH += $$PWD/include/librdkafka DISTFILES += conf/config.ini - -unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ diff --git a/PhaseCompAcq/PhaseDevice.cpp b/PhaseCompAcq/PhaseDevice.cpp index 5c84cd5..afc2687 100644 --- a/PhaseCompAcq/PhaseDevice.cpp +++ b/PhaseCompAcq/PhaseDevice.cpp @@ -7,9 +7,9 @@ connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, this, &PhaseDevice::dataReceivedHandler); - kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); - kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); - kafkaUtil.createProducer(); +// kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); +// kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); +// kafkaUtil.createProducer(); } PhaseDevice::~PhaseDevice() @@ -34,6 +34,10 @@ { this->devCode = devCode; } +void PhaseDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} bool PhaseDevice::isSerialOpen() { @@ -74,6 +78,7 @@ if (parse == true) { QDateTime now = QDateTime::currentDateTime(); + phaseData->devCode = this->devCode; phaseData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); phaseData->milisecond = now.toMSecsSinceEpoch(); this->afterFramePhase(phaseData); @@ -92,21 +97,20 @@ this->dataBuff.clear(); // 2. 输出到日志文件中 - QString filePostfix = phaseData->timestamp.mid(0, 13).replace(" ", "_"); - QString filePrefix = QApplication::applicationDirPath() + "/logs/"; + QString date = phaseData->timestamp.mid(0, 10); // 2.1 原始字节数组数据 - QString filename = filePrefix + "raw_" + filePostfix + ".log"; + QString filename = "raw_" + devCode + ".log"; QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); - QLogUtil::writeRawDataLog(filename, content); + QLogUtil::writeRawDataLogByDate(date, filename, content); // 2.2 各个通道的相差数据 for (int i = 1; i <= phaseData->channelActive.size(); i++) { if (phaseData->channelActive.at(i-1).toUInt() == 1) { - QString chFilename("%1CH_%2_%3.log"); - chFilename = chFilename.arg(filePrefix); + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); if (i < 10) { chFilename = chFilename.arg(QString("0%1").arg(i)); @@ -114,10 +118,9 @@ { chFilename = chFilename.arg(i); } - chFilename = chFilename.arg(filePostfix); - QString channelDataStr = QString("%1 %2 %3").arg(phaseData->timestamp).arg(phaseData->channelData.at(i-1)).arg(phaseData->frameId); + QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelData.at(i-1)); - QLogUtil::writeChannelDataLog(chFilename, channelDataStr); + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); // 3. 输出到中间件,执行后续处理过程 if (SettingConfig::getInstance().NEED_KAFKA == 1) @@ -125,7 +128,7 @@ QJsonObject jsonObj = phaseData->toJSON(i - 1); jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); jsonObj.insert("deviceId", devCode); - kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); +// kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); } } } diff --git a/PhaseCompAcq/PhaseDevice.h b/PhaseCompAcq/PhaseDevice.h index 92182d4..aa7d822 100644 --- a/PhaseCompAcq/PhaseDevice.h +++ b/PhaseCompAcq/PhaseDevice.h @@ -5,7 +5,7 @@ #include "common/utils/QSerialPortUtil.h" #include "common/utils/QLogUtil.h" #include "common/utils/SettingConfig.h" -#include "common/utils/QKafkaUtil.h" +//#include "common/utils/QKafkaUtil.h" #include "protocol/PhaseProtocolBM.h" class PhaseDevice : public QObject @@ -25,15 +25,17 @@ void setBaudRate(int baudRate); QString getDevCode(); void setDevCode(QString devCode); + void setDeviceId(QString deviceId); bool isSerialOpen(); private: + QString deviceId; QString devCode; QString comName; int baudRate; QSerialPortUtil serialUtil; - QKafkaUtil kafkaUtil; +// QKafkaUtil kafkaUtil; QByteArray dataBuff; signals: diff --git a/PhaseCompAcq/PhaseWindow.cpp b/PhaseCompAcq/PhaseWindow.cpp index b3cab89..d0e8221 100644 --- a/PhaseCompAcq/PhaseWindow.cpp +++ b/PhaseCompAcq/PhaseWindow.cpp @@ -1,16 +1,16 @@ #include "PhaseWindow.h" #include "ui_PhaseWindow.h" -#include -#include -#include -#include -#include -#include - #include - -#include "common/utils/QKafkaUtil.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include PhaseWindow::PhaseWindow(QWidget *parent) : QWidget(parent), @@ -18,43 +18,74 @@ { ui->setupUi(this); - QString portNames = SettingConfig::getInstance().PORT_NAMES; - int baudRate = SettingConfig::getInstance().BAUD_RATE; - QString devCodes = SettingConfig::getInstance().DEV_CODES; + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); - QStringList comDevList = portNames.split(","); - QStringList devCodeList = devCodes.split(","); + // 窗口大小为占满一屏 + QRect screenRect = QApplication::desktop()->screenGeometry(); + resize(screenRect.width(), screenRect.height()); - for (int i = 0; i < comDevList.size(); i++) + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->line->setGeometry(0, 59, screenRect.width(), 1); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 60, screenRect.width(), screenRect.height() - 60); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + + httpReq = new HttpRequestController(this); + // 1. 获取访问接口需要的token + int retCode = this->initHttpToken(); + if (retCode != 200) { - PhaseDevice * device = new PhaseDevice(this); + QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); - // - connect(device, &PhaseDevice::sendDataToDraw, - this, &PhaseWindow::drawPhaseDataOnPage); + QTimer::singleShot(1000, qApp, SLOT(quit())); + } + // 2. 获取字典值:设备类型 + retCode = this->initDictDeviceTypes(); - device->setComName(comDevList.at(i)); - device->setBaudRate(baudRate); + // 3. 获取比相仪设备列表 + QJsonObject devListRes = this->initDeviceList(); + if (devListRes.find("code")->toInt() == 200) + { + ui->devSelect->clear(); - device->setDevCode(devCodeList.at(i)); + // 4. 将获取到的设备添加到下拉列表框中 + QJsonArray devArray = devListRes.find("data")->toArray(); + for (int i = 0; i < devArray.size(); i++) + { + QJsonObject devItem = devArray.at(i).toObject(); + ui->devSelect->addItem(devItem.find("deviceName")->toString(), devItem.find("deviceNo")->toString()); - this->deviceList.append(device); + PhaseDevice * device = new PhaseDevice(this); + deviceList.append(device); - device->initSerialPort(); - device->startWork(); + device->setComName(devItem.find("linkComName")->toString()); + device->setBaudRate(SettingConfig::getInstance().BAUD_RATE); + device->setDevCode(devItem.find("deviceNo")->toString()); + device->setDeviceId(devItem.find("deviceId")->toString()); + + connect(device, &PhaseDevice::sendDataToDraw, + this, &PhaseWindow::drawPhaseDataOnPage); + + device->initSerialPort(); + + QThread::msleep(100); + } + // 5. 设置下拉框的样式 + QStandardItemModel * model = qobject_cast(ui->devSelect->model()); + for (int i = 0; i < model->rowCount(); ++i) + { + QStandardItem * item = model->item(i); + item->setSizeHint({ 0, 30 }); + } } - for (int i = 0; i < this->deviceList.size(); i++) - { - QWidget * devWidget5 = new QWidget(this->ui->stackedWidget); - - this->ui->stackedWidget->addWidget(devWidget5); - - this->devWidgetList.append(devWidget5); - - // 创建设备的widget - this->generateWidgetForDevice(devCodeList.at(i), i); - } + // 6. 绘制一个设备的多个通道数据面板 + this->generateWidgetForDevice(); } PhaseWindow::~PhaseWindow() @@ -64,99 +95,119 @@ void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) { - // 1. 判断数据属于哪个设备,显示在不同的widget上 + // 当前显示的设备编号 + QString currentDevCode = ui->devSelect->currentData().toString(); - // 2. 循环设置各个tableView - QList devChannels = this->tableModelList.at(0); // 暂时写死 - for (int i = 0; i < phaseData->channelData.size(); i++) + // 如果不是当前设备的帧,直接返回 + if (phaseData->devCode != currentDevCode) { - if (phaseData->channelActive.at(i).toInt() == 1) - { - QList row; - QStandardItem * item = 0; - QStandardItem * item2 = 0; - item = new QStandardItem(QString("%1").arg(phaseData->timestamp.mid(11, 12))); - item2 = new QStandardItem(QString("%1").arg(phaseData->channelData.at(i))); + return; + } - row.append(item); - row.append(item2); + // 更新所有通道BOX的值 + for (int i = 0; i < phaseData->channelActive.size(); i++) + { + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); - QStandardItemModel * model; - model = devChannels.at(i); - if (model->rowCount() >= 60) - { - model->removeRows(0, model->rowCount()); - } - - model->insertRow(0, row); - } + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(phaseData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelData.at(i))); + ((QLineEdit *)channelBox->children().at(6))->setText(phaseData->frameId); + ((QLabel *)channelBox->children().at(7))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); } } -void PhaseWindow::generateWidgetForDevice(QString devCode, int index) +void PhaseWindow::generateWidgetForDevice() { - // 顶部切换widget - QWidget * switchWidget = new QWidget(this->devWidgetList.at(index)); - switchWidget->setGeometry(0, 0, 1024, 50); + // 获取设备数据 + int channelNum = 16; - // 显示数据的区域 - QWidget * gridWidget = new QWidget(this->devWidgetList.at(index)); - gridWidget->setGeometry(0, 50, 1024, 670); + QRect screenRect = QApplication::desktop()->screenGeometry(); - // 顶部水平布局,用于排布按钮 - QHBoxLayout * hLayout = new QHBoxLayout(switchWidget); + ui->scrollContents->setGeometry(0, 60, screenRect.width(), channelNum * 90); - // 文本 - QLabel * label = new QLabel(switchWidget); - label->setText("设备编号:" + devCode); - label->setFont(QFont("微软雅黑", 12)); - hLayout->addWidget(label); + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); - // 按钮 - for (int i = 0; i < this->deviceList.size(); i++) + for (int i = 0; i < channelNum; i++) { - QPushButton * butt5 = new QPushButton(this->deviceList.at(i)->getDevCode()); - hLayout->addWidget(butt5); + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 80 + 10, screenRect.width() - 40, 80); - connect(butt5, &QPushButton::clicked, [=](){ - this->ui->stackedWidget->setCurrentIndex(i); - }); + QHBoxLayout * vbox = new QHBoxLayout(group); + + QLabel * tmLabel = new QLabel(); + tmLabel->setText("时间"); + tmLabel->setFont(labelFont); + tmLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(tmLabel); + QLineEdit * tmValue = new QLineEdit(); + tmValue->setFixedWidth(200); + tmValue->setFont(labelFont); + vbox->addWidget(tmValue); + + QLabel * dataLabel = new QLabel(); + dataLabel->setText("测量数据"); + dataLabel->setFont(labelFont); + dataLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(dataLabel); + QLineEdit * dataValue = new QLineEdit(); + dataValue->setFixedWidth(150); + dataValue->setFont(labelFont); + vbox->addWidget(dataValue); + + QLabel * idLabel = new QLabel(); + idLabel->setText("数据ID"); + idLabel->setFont(labelFont); + idLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(idLabel); + QLineEdit * idValue = new QLineEdit(); + idValue->setFixedWidth(100); + idValue->setFont(labelFont); + vbox->addWidget(idValue); + + QLabel * validLabel = new QLabel(); + validLabel->setText("-"); + validLabel->setFont(labelFont); + validLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(validLabel); + + QSpacerItem * hSpace = new QSpacerItem(20, 20); + hSpace->changeSize(20, 20, QSizePolicy::Expanding); + vbox->addItem(hSpace); + + group->setLayout(vbox); + + layout->addWidget(group); } - - // Grid布局 - QGridLayout * gridLayout = new QGridLayout(gridWidget); - gridLayout->setSpacing(10); - - QList channelModelList; - QStringList labels = QObject::trUtf8("时间,相差").simplified().split(","); - - for (int i = 0; i < 16; i++) - { - QTableView * channelTable = new QTableView(gridWidget); - QStandardItemModel * model = new QStandardItemModel(channelTable); - - model->setHorizontalHeaderLabels(labels); - - channelTable->setModel(model); - - gridLayout->addWidget(channelTable, i / 4, i % 4); - - channelTable->verticalHeader()->hide(); - channelTable->setEditTriggers(QAbstractItemView::NoEditTriggers); - channelTable->scrollToBottom(); - - channelModelList.append(model); - } - - this->tableModelList.append(channelModelList); } -void PhaseWindow::createKafkaMessage() +int PhaseWindow::initHttpToken() { - this->kafkaUtil = new QKafkaUtil(this); - this->kafkaUtil->setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); - this->kafkaUtil->setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int PhaseWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject PhaseWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("比相仪"); + return response; +} - kafkaUtil->createProducer(); - kafkaUtil->produceMessage("hello world kafka kylin"); +void PhaseWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} + +void PhaseWindow::on_exitButt_clicked() +{ + QApplication::exit(0); } diff --git a/CounterAcq/CounterAcq.pro b/CounterAcq/CounterAcq.pro index 72407cd..fae9d10 100644 --- a/CounterAcq/CounterAcq.pro +++ b/CounterAcq/CounterAcq.pro @@ -4,13 +4,6 @@ CONFIG += c++11 -SOURCES += \ - CounterWindow.cpp \ - main.cpp \ - -HEADERS += \ - CounterWindow.h \ - FORMS += \ CounterWindow.ui \ @@ -18,8 +11,11 @@ include(protocol/protocol.pri) HEADERS += CounterDevice.h +HEADERS += CounterWindow.h SOURCES += CounterDevice.cpp +SOURCES += CounterWindow.cpp +SOURCES += main.cpp DISTFILES += conf/config.ini diff --git a/CounterAcq/CounterWindow.cpp b/CounterAcq/CounterWindow.cpp index 80035a9..a50ebcf 100644 --- a/CounterAcq/CounterWindow.cpp +++ b/CounterAcq/CounterWindow.cpp @@ -42,7 +42,7 @@ { QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); - QApplication::exit(0); + QTimer::singleShot(1000, qApp, SLOT(quit())); } // 2. 获取字典值:设备类型 retCode = this->initDictDeviceTypes(); diff --git a/CounterAcq/CounterWindow.h b/CounterAcq/CounterWindow.h index 8d5e4a6..09277ba 100644 --- a/CounterAcq/CounterWindow.h +++ b/CounterAcq/CounterWindow.h @@ -7,7 +7,6 @@ #include #include "common/utils/SettingConfig.h" -#include "common/utils/QKafkaUtil.h" #include "common/HttpRequestController.h" #include "CounterDevice.h" @@ -23,8 +22,6 @@ explicit CounterWindow(QWidget *parent = nullptr); ~CounterWindow(); - QString token; - public slots: void drawCounterDataOnPage(CounterDataDto * counterData); @@ -40,7 +37,6 @@ Ui::CounterWindow *ui; - QTimer * timer; HttpRequestController * httpReq; QList deviceList; diff --git a/PhaseCompAcq/PhaseCompAcq.pro b/PhaseCompAcq/PhaseCompAcq.pro index 5eef2d1..c5e895b 100644 --- a/PhaseCompAcq/PhaseCompAcq.pro +++ b/PhaseCompAcq/PhaseCompAcq.pro @@ -1,16 +1,9 @@ -QT += core gui serialport +QT += core gui serialport network greaterThan(QT_MAJOR_VERSION, 4): QT += widgets CONFIG += c++11 -SOURCES += \ - main.cpp \ - PhaseWindow.cpp - -HEADERS += \ - PhaseWindow.h - FORMS += \ PhaseWindow.ui @@ -18,20 +11,19 @@ include(protocol/protocol.pri) HEADERS += PhaseDevice.h -#HEADERS += PhaseSerialServer.h +HEADERS += PhaseWindow.h SOURCES += PhaseDevice.cpp -#SOURCES += PhaseSerialServer.cpp +SOURCES += PhaseWindow.cpp +SOURCES += main.cpp # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target - -INCLUDEPATH += $$PWD/include/librdkafka -DEPENDPATH += $$PWD/include/librdkafka +#unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +#INCLUDEPATH += $$PWD/include/librdkafka +#DEPENDPATH += $$PWD/include/librdkafka DISTFILES += conf/config.ini - -unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ diff --git a/PhaseCompAcq/PhaseDevice.cpp b/PhaseCompAcq/PhaseDevice.cpp index 5c84cd5..afc2687 100644 --- a/PhaseCompAcq/PhaseDevice.cpp +++ b/PhaseCompAcq/PhaseDevice.cpp @@ -7,9 +7,9 @@ connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, this, &PhaseDevice::dataReceivedHandler); - kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); - kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); - kafkaUtil.createProducer(); +// kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); +// kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); +// kafkaUtil.createProducer(); } PhaseDevice::~PhaseDevice() @@ -34,6 +34,10 @@ { this->devCode = devCode; } +void PhaseDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} bool PhaseDevice::isSerialOpen() { @@ -74,6 +78,7 @@ if (parse == true) { QDateTime now = QDateTime::currentDateTime(); + phaseData->devCode = this->devCode; phaseData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); phaseData->milisecond = now.toMSecsSinceEpoch(); this->afterFramePhase(phaseData); @@ -92,21 +97,20 @@ this->dataBuff.clear(); // 2. 输出到日志文件中 - QString filePostfix = phaseData->timestamp.mid(0, 13).replace(" ", "_"); - QString filePrefix = QApplication::applicationDirPath() + "/logs/"; + QString date = phaseData->timestamp.mid(0, 10); // 2.1 原始字节数组数据 - QString filename = filePrefix + "raw_" + filePostfix + ".log"; + QString filename = "raw_" + devCode + ".log"; QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); - QLogUtil::writeRawDataLog(filename, content); + QLogUtil::writeRawDataLogByDate(date, filename, content); // 2.2 各个通道的相差数据 for (int i = 1; i <= phaseData->channelActive.size(); i++) { if (phaseData->channelActive.at(i-1).toUInt() == 1) { - QString chFilename("%1CH_%2_%3.log"); - chFilename = chFilename.arg(filePrefix); + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); if (i < 10) { chFilename = chFilename.arg(QString("0%1").arg(i)); @@ -114,10 +118,9 @@ { chFilename = chFilename.arg(i); } - chFilename = chFilename.arg(filePostfix); - QString channelDataStr = QString("%1 %2 %3").arg(phaseData->timestamp).arg(phaseData->channelData.at(i-1)).arg(phaseData->frameId); + QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelData.at(i-1)); - QLogUtil::writeChannelDataLog(chFilename, channelDataStr); + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); // 3. 输出到中间件,执行后续处理过程 if (SettingConfig::getInstance().NEED_KAFKA == 1) @@ -125,7 +128,7 @@ QJsonObject jsonObj = phaseData->toJSON(i - 1); jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); jsonObj.insert("deviceId", devCode); - kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); +// kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); } } } diff --git a/PhaseCompAcq/PhaseDevice.h b/PhaseCompAcq/PhaseDevice.h index 92182d4..aa7d822 100644 --- a/PhaseCompAcq/PhaseDevice.h +++ b/PhaseCompAcq/PhaseDevice.h @@ -5,7 +5,7 @@ #include "common/utils/QSerialPortUtil.h" #include "common/utils/QLogUtil.h" #include "common/utils/SettingConfig.h" -#include "common/utils/QKafkaUtil.h" +//#include "common/utils/QKafkaUtil.h" #include "protocol/PhaseProtocolBM.h" class PhaseDevice : public QObject @@ -25,15 +25,17 @@ void setBaudRate(int baudRate); QString getDevCode(); void setDevCode(QString devCode); + void setDeviceId(QString deviceId); bool isSerialOpen(); private: + QString deviceId; QString devCode; QString comName; int baudRate; QSerialPortUtil serialUtil; - QKafkaUtil kafkaUtil; +// QKafkaUtil kafkaUtil; QByteArray dataBuff; signals: diff --git a/PhaseCompAcq/PhaseWindow.cpp b/PhaseCompAcq/PhaseWindow.cpp index b3cab89..d0e8221 100644 --- a/PhaseCompAcq/PhaseWindow.cpp +++ b/PhaseCompAcq/PhaseWindow.cpp @@ -1,16 +1,16 @@ #include "PhaseWindow.h" #include "ui_PhaseWindow.h" -#include -#include -#include -#include -#include -#include - #include - -#include "common/utils/QKafkaUtil.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include PhaseWindow::PhaseWindow(QWidget *parent) : QWidget(parent), @@ -18,43 +18,74 @@ { ui->setupUi(this); - QString portNames = SettingConfig::getInstance().PORT_NAMES; - int baudRate = SettingConfig::getInstance().BAUD_RATE; - QString devCodes = SettingConfig::getInstance().DEV_CODES; + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); - QStringList comDevList = portNames.split(","); - QStringList devCodeList = devCodes.split(","); + // 窗口大小为占满一屏 + QRect screenRect = QApplication::desktop()->screenGeometry(); + resize(screenRect.width(), screenRect.height()); - for (int i = 0; i < comDevList.size(); i++) + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->line->setGeometry(0, 59, screenRect.width(), 1); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 60, screenRect.width(), screenRect.height() - 60); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + + httpReq = new HttpRequestController(this); + // 1. 获取访问接口需要的token + int retCode = this->initHttpToken(); + if (retCode != 200) { - PhaseDevice * device = new PhaseDevice(this); + QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); - // - connect(device, &PhaseDevice::sendDataToDraw, - this, &PhaseWindow::drawPhaseDataOnPage); + QTimer::singleShot(1000, qApp, SLOT(quit())); + } + // 2. 获取字典值:设备类型 + retCode = this->initDictDeviceTypes(); - device->setComName(comDevList.at(i)); - device->setBaudRate(baudRate); + // 3. 获取比相仪设备列表 + QJsonObject devListRes = this->initDeviceList(); + if (devListRes.find("code")->toInt() == 200) + { + ui->devSelect->clear(); - device->setDevCode(devCodeList.at(i)); + // 4. 将获取到的设备添加到下拉列表框中 + QJsonArray devArray = devListRes.find("data")->toArray(); + for (int i = 0; i < devArray.size(); i++) + { + QJsonObject devItem = devArray.at(i).toObject(); + ui->devSelect->addItem(devItem.find("deviceName")->toString(), devItem.find("deviceNo")->toString()); - this->deviceList.append(device); + PhaseDevice * device = new PhaseDevice(this); + deviceList.append(device); - device->initSerialPort(); - device->startWork(); + device->setComName(devItem.find("linkComName")->toString()); + device->setBaudRate(SettingConfig::getInstance().BAUD_RATE); + device->setDevCode(devItem.find("deviceNo")->toString()); + device->setDeviceId(devItem.find("deviceId")->toString()); + + connect(device, &PhaseDevice::sendDataToDraw, + this, &PhaseWindow::drawPhaseDataOnPage); + + device->initSerialPort(); + + QThread::msleep(100); + } + // 5. 设置下拉框的样式 + QStandardItemModel * model = qobject_cast(ui->devSelect->model()); + for (int i = 0; i < model->rowCount(); ++i) + { + QStandardItem * item = model->item(i); + item->setSizeHint({ 0, 30 }); + } } - for (int i = 0; i < this->deviceList.size(); i++) - { - QWidget * devWidget5 = new QWidget(this->ui->stackedWidget); - - this->ui->stackedWidget->addWidget(devWidget5); - - this->devWidgetList.append(devWidget5); - - // 创建设备的widget - this->generateWidgetForDevice(devCodeList.at(i), i); - } + // 6. 绘制一个设备的多个通道数据面板 + this->generateWidgetForDevice(); } PhaseWindow::~PhaseWindow() @@ -64,99 +95,119 @@ void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) { - // 1. 判断数据属于哪个设备,显示在不同的widget上 + // 当前显示的设备编号 + QString currentDevCode = ui->devSelect->currentData().toString(); - // 2. 循环设置各个tableView - QList devChannels = this->tableModelList.at(0); // 暂时写死 - for (int i = 0; i < phaseData->channelData.size(); i++) + // 如果不是当前设备的帧,直接返回 + if (phaseData->devCode != currentDevCode) { - if (phaseData->channelActive.at(i).toInt() == 1) - { - QList row; - QStandardItem * item = 0; - QStandardItem * item2 = 0; - item = new QStandardItem(QString("%1").arg(phaseData->timestamp.mid(11, 12))); - item2 = new QStandardItem(QString("%1").arg(phaseData->channelData.at(i))); + return; + } - row.append(item); - row.append(item2); + // 更新所有通道BOX的值 + for (int i = 0; i < phaseData->channelActive.size(); i++) + { + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); - QStandardItemModel * model; - model = devChannels.at(i); - if (model->rowCount() >= 60) - { - model->removeRows(0, model->rowCount()); - } - - model->insertRow(0, row); - } + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(phaseData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelData.at(i))); + ((QLineEdit *)channelBox->children().at(6))->setText(phaseData->frameId); + ((QLabel *)channelBox->children().at(7))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); } } -void PhaseWindow::generateWidgetForDevice(QString devCode, int index) +void PhaseWindow::generateWidgetForDevice() { - // 顶部切换widget - QWidget * switchWidget = new QWidget(this->devWidgetList.at(index)); - switchWidget->setGeometry(0, 0, 1024, 50); + // 获取设备数据 + int channelNum = 16; - // 显示数据的区域 - QWidget * gridWidget = new QWidget(this->devWidgetList.at(index)); - gridWidget->setGeometry(0, 50, 1024, 670); + QRect screenRect = QApplication::desktop()->screenGeometry(); - // 顶部水平布局,用于排布按钮 - QHBoxLayout * hLayout = new QHBoxLayout(switchWidget); + ui->scrollContents->setGeometry(0, 60, screenRect.width(), channelNum * 90); - // 文本 - QLabel * label = new QLabel(switchWidget); - label->setText("设备编号:" + devCode); - label->setFont(QFont("微软雅黑", 12)); - hLayout->addWidget(label); + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); - // 按钮 - for (int i = 0; i < this->deviceList.size(); i++) + for (int i = 0; i < channelNum; i++) { - QPushButton * butt5 = new QPushButton(this->deviceList.at(i)->getDevCode()); - hLayout->addWidget(butt5); + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 80 + 10, screenRect.width() - 40, 80); - connect(butt5, &QPushButton::clicked, [=](){ - this->ui->stackedWidget->setCurrentIndex(i); - }); + QHBoxLayout * vbox = new QHBoxLayout(group); + + QLabel * tmLabel = new QLabel(); + tmLabel->setText("时间"); + tmLabel->setFont(labelFont); + tmLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(tmLabel); + QLineEdit * tmValue = new QLineEdit(); + tmValue->setFixedWidth(200); + tmValue->setFont(labelFont); + vbox->addWidget(tmValue); + + QLabel * dataLabel = new QLabel(); + dataLabel->setText("测量数据"); + dataLabel->setFont(labelFont); + dataLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(dataLabel); + QLineEdit * dataValue = new QLineEdit(); + dataValue->setFixedWidth(150); + dataValue->setFont(labelFont); + vbox->addWidget(dataValue); + + QLabel * idLabel = new QLabel(); + idLabel->setText("数据ID"); + idLabel->setFont(labelFont); + idLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(idLabel); + QLineEdit * idValue = new QLineEdit(); + idValue->setFixedWidth(100); + idValue->setFont(labelFont); + vbox->addWidget(idValue); + + QLabel * validLabel = new QLabel(); + validLabel->setText("-"); + validLabel->setFont(labelFont); + validLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(validLabel); + + QSpacerItem * hSpace = new QSpacerItem(20, 20); + hSpace->changeSize(20, 20, QSizePolicy::Expanding); + vbox->addItem(hSpace); + + group->setLayout(vbox); + + layout->addWidget(group); } - - // Grid布局 - QGridLayout * gridLayout = new QGridLayout(gridWidget); - gridLayout->setSpacing(10); - - QList channelModelList; - QStringList labels = QObject::trUtf8("时间,相差").simplified().split(","); - - for (int i = 0; i < 16; i++) - { - QTableView * channelTable = new QTableView(gridWidget); - QStandardItemModel * model = new QStandardItemModel(channelTable); - - model->setHorizontalHeaderLabels(labels); - - channelTable->setModel(model); - - gridLayout->addWidget(channelTable, i / 4, i % 4); - - channelTable->verticalHeader()->hide(); - channelTable->setEditTriggers(QAbstractItemView::NoEditTriggers); - channelTable->scrollToBottom(); - - channelModelList.append(model); - } - - this->tableModelList.append(channelModelList); } -void PhaseWindow::createKafkaMessage() +int PhaseWindow::initHttpToken() { - this->kafkaUtil = new QKafkaUtil(this); - this->kafkaUtil->setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); - this->kafkaUtil->setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int PhaseWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject PhaseWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("比相仪"); + return response; +} - kafkaUtil->createProducer(); - kafkaUtil->produceMessage("hello world kafka kylin"); +void PhaseWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} + +void PhaseWindow::on_exitButt_clicked() +{ + QApplication::exit(0); } diff --git a/PhaseCompAcq/PhaseWindow.h b/PhaseCompAcq/PhaseWindow.h index 67b8363..02a7908 100644 --- a/PhaseCompAcq/PhaseWindow.h +++ b/PhaseCompAcq/PhaseWindow.h @@ -2,11 +2,13 @@ #define PHASEWINDOW_H #include +#include #include +#include #include "PhaseDevice.h" #include "common/utils/SettingConfig.h" -#include "common/utils/QKafkaUtil.h" +#include "common/HttpRequestController.h" namespace Ui { class PhaseWindow; @@ -23,18 +25,23 @@ public slots: void drawPhaseDataOnPage(PhaseDataDto * phaseData); +private slots: + void on_minButt_clicked(); + + void on_exitButt_clicked(); + private: + int initHttpToken(); + int initDictDeviceTypes(); + QJsonObject initDeviceList(); + Ui::PhaseWindow *ui; - QList devWidgetList; + HttpRequestController * httpReq; QList deviceList; - QList> tableModelList; - QKafkaUtil * kafkaUtil; - - void generateWidgetForDevice(QString devCode, int index); - void createKafkaMessage(); + void generateWidgetForDevice(); }; #endif // PHASEWINDOW_H diff --git a/CounterAcq/CounterAcq.pro b/CounterAcq/CounterAcq.pro index 72407cd..fae9d10 100644 --- a/CounterAcq/CounterAcq.pro +++ b/CounterAcq/CounterAcq.pro @@ -4,13 +4,6 @@ CONFIG += c++11 -SOURCES += \ - CounterWindow.cpp \ - main.cpp \ - -HEADERS += \ - CounterWindow.h \ - FORMS += \ CounterWindow.ui \ @@ -18,8 +11,11 @@ include(protocol/protocol.pri) HEADERS += CounterDevice.h +HEADERS += CounterWindow.h SOURCES += CounterDevice.cpp +SOURCES += CounterWindow.cpp +SOURCES += main.cpp DISTFILES += conf/config.ini diff --git a/CounterAcq/CounterWindow.cpp b/CounterAcq/CounterWindow.cpp index 80035a9..a50ebcf 100644 --- a/CounterAcq/CounterWindow.cpp +++ b/CounterAcq/CounterWindow.cpp @@ -42,7 +42,7 @@ { QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); - QApplication::exit(0); + QTimer::singleShot(1000, qApp, SLOT(quit())); } // 2. 获取字典值:设备类型 retCode = this->initDictDeviceTypes(); diff --git a/CounterAcq/CounterWindow.h b/CounterAcq/CounterWindow.h index 8d5e4a6..09277ba 100644 --- a/CounterAcq/CounterWindow.h +++ b/CounterAcq/CounterWindow.h @@ -7,7 +7,6 @@ #include #include "common/utils/SettingConfig.h" -#include "common/utils/QKafkaUtil.h" #include "common/HttpRequestController.h" #include "CounterDevice.h" @@ -23,8 +22,6 @@ explicit CounterWindow(QWidget *parent = nullptr); ~CounterWindow(); - QString token; - public slots: void drawCounterDataOnPage(CounterDataDto * counterData); @@ -40,7 +37,6 @@ Ui::CounterWindow *ui; - QTimer * timer; HttpRequestController * httpReq; QList deviceList; diff --git a/PhaseCompAcq/PhaseCompAcq.pro b/PhaseCompAcq/PhaseCompAcq.pro index 5eef2d1..c5e895b 100644 --- a/PhaseCompAcq/PhaseCompAcq.pro +++ b/PhaseCompAcq/PhaseCompAcq.pro @@ -1,16 +1,9 @@ -QT += core gui serialport +QT += core gui serialport network greaterThan(QT_MAJOR_VERSION, 4): QT += widgets CONFIG += c++11 -SOURCES += \ - main.cpp \ - PhaseWindow.cpp - -HEADERS += \ - PhaseWindow.h - FORMS += \ PhaseWindow.ui @@ -18,20 +11,19 @@ include(protocol/protocol.pri) HEADERS += PhaseDevice.h -#HEADERS += PhaseSerialServer.h +HEADERS += PhaseWindow.h SOURCES += PhaseDevice.cpp -#SOURCES += PhaseSerialServer.cpp +SOURCES += PhaseWindow.cpp +SOURCES += main.cpp # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target - -INCLUDEPATH += $$PWD/include/librdkafka -DEPENDPATH += $$PWD/include/librdkafka +#unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +#INCLUDEPATH += $$PWD/include/librdkafka +#DEPENDPATH += $$PWD/include/librdkafka DISTFILES += conf/config.ini - -unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ diff --git a/PhaseCompAcq/PhaseDevice.cpp b/PhaseCompAcq/PhaseDevice.cpp index 5c84cd5..afc2687 100644 --- a/PhaseCompAcq/PhaseDevice.cpp +++ b/PhaseCompAcq/PhaseDevice.cpp @@ -7,9 +7,9 @@ connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, this, &PhaseDevice::dataReceivedHandler); - kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); - kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); - kafkaUtil.createProducer(); +// kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); +// kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); +// kafkaUtil.createProducer(); } PhaseDevice::~PhaseDevice() @@ -34,6 +34,10 @@ { this->devCode = devCode; } +void PhaseDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} bool PhaseDevice::isSerialOpen() { @@ -74,6 +78,7 @@ if (parse == true) { QDateTime now = QDateTime::currentDateTime(); + phaseData->devCode = this->devCode; phaseData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); phaseData->milisecond = now.toMSecsSinceEpoch(); this->afterFramePhase(phaseData); @@ -92,21 +97,20 @@ this->dataBuff.clear(); // 2. 输出到日志文件中 - QString filePostfix = phaseData->timestamp.mid(0, 13).replace(" ", "_"); - QString filePrefix = QApplication::applicationDirPath() + "/logs/"; + QString date = phaseData->timestamp.mid(0, 10); // 2.1 原始字节数组数据 - QString filename = filePrefix + "raw_" + filePostfix + ".log"; + QString filename = "raw_" + devCode + ".log"; QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); - QLogUtil::writeRawDataLog(filename, content); + QLogUtil::writeRawDataLogByDate(date, filename, content); // 2.2 各个通道的相差数据 for (int i = 1; i <= phaseData->channelActive.size(); i++) { if (phaseData->channelActive.at(i-1).toUInt() == 1) { - QString chFilename("%1CH_%2_%3.log"); - chFilename = chFilename.arg(filePrefix); + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); if (i < 10) { chFilename = chFilename.arg(QString("0%1").arg(i)); @@ -114,10 +118,9 @@ { chFilename = chFilename.arg(i); } - chFilename = chFilename.arg(filePostfix); - QString channelDataStr = QString("%1 %2 %3").arg(phaseData->timestamp).arg(phaseData->channelData.at(i-1)).arg(phaseData->frameId); + QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelData.at(i-1)); - QLogUtil::writeChannelDataLog(chFilename, channelDataStr); + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); // 3. 输出到中间件,执行后续处理过程 if (SettingConfig::getInstance().NEED_KAFKA == 1) @@ -125,7 +128,7 @@ QJsonObject jsonObj = phaseData->toJSON(i - 1); jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); jsonObj.insert("deviceId", devCode); - kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); +// kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); } } } diff --git a/PhaseCompAcq/PhaseDevice.h b/PhaseCompAcq/PhaseDevice.h index 92182d4..aa7d822 100644 --- a/PhaseCompAcq/PhaseDevice.h +++ b/PhaseCompAcq/PhaseDevice.h @@ -5,7 +5,7 @@ #include "common/utils/QSerialPortUtil.h" #include "common/utils/QLogUtil.h" #include "common/utils/SettingConfig.h" -#include "common/utils/QKafkaUtil.h" +//#include "common/utils/QKafkaUtil.h" #include "protocol/PhaseProtocolBM.h" class PhaseDevice : public QObject @@ -25,15 +25,17 @@ void setBaudRate(int baudRate); QString getDevCode(); void setDevCode(QString devCode); + void setDeviceId(QString deviceId); bool isSerialOpen(); private: + QString deviceId; QString devCode; QString comName; int baudRate; QSerialPortUtil serialUtil; - QKafkaUtil kafkaUtil; +// QKafkaUtil kafkaUtil; QByteArray dataBuff; signals: diff --git a/PhaseCompAcq/PhaseWindow.cpp b/PhaseCompAcq/PhaseWindow.cpp index b3cab89..d0e8221 100644 --- a/PhaseCompAcq/PhaseWindow.cpp +++ b/PhaseCompAcq/PhaseWindow.cpp @@ -1,16 +1,16 @@ #include "PhaseWindow.h" #include "ui_PhaseWindow.h" -#include -#include -#include -#include -#include -#include - #include - -#include "common/utils/QKafkaUtil.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include PhaseWindow::PhaseWindow(QWidget *parent) : QWidget(parent), @@ -18,43 +18,74 @@ { ui->setupUi(this); - QString portNames = SettingConfig::getInstance().PORT_NAMES; - int baudRate = SettingConfig::getInstance().BAUD_RATE; - QString devCodes = SettingConfig::getInstance().DEV_CODES; + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); - QStringList comDevList = portNames.split(","); - QStringList devCodeList = devCodes.split(","); + // 窗口大小为占满一屏 + QRect screenRect = QApplication::desktop()->screenGeometry(); + resize(screenRect.width(), screenRect.height()); - for (int i = 0; i < comDevList.size(); i++) + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->line->setGeometry(0, 59, screenRect.width(), 1); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 60, screenRect.width(), screenRect.height() - 60); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + + httpReq = new HttpRequestController(this); + // 1. 获取访问接口需要的token + int retCode = this->initHttpToken(); + if (retCode != 200) { - PhaseDevice * device = new PhaseDevice(this); + QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); - // - connect(device, &PhaseDevice::sendDataToDraw, - this, &PhaseWindow::drawPhaseDataOnPage); + QTimer::singleShot(1000, qApp, SLOT(quit())); + } + // 2. 获取字典值:设备类型 + retCode = this->initDictDeviceTypes(); - device->setComName(comDevList.at(i)); - device->setBaudRate(baudRate); + // 3. 获取比相仪设备列表 + QJsonObject devListRes = this->initDeviceList(); + if (devListRes.find("code")->toInt() == 200) + { + ui->devSelect->clear(); - device->setDevCode(devCodeList.at(i)); + // 4. 将获取到的设备添加到下拉列表框中 + QJsonArray devArray = devListRes.find("data")->toArray(); + for (int i = 0; i < devArray.size(); i++) + { + QJsonObject devItem = devArray.at(i).toObject(); + ui->devSelect->addItem(devItem.find("deviceName")->toString(), devItem.find("deviceNo")->toString()); - this->deviceList.append(device); + PhaseDevice * device = new PhaseDevice(this); + deviceList.append(device); - device->initSerialPort(); - device->startWork(); + device->setComName(devItem.find("linkComName")->toString()); + device->setBaudRate(SettingConfig::getInstance().BAUD_RATE); + device->setDevCode(devItem.find("deviceNo")->toString()); + device->setDeviceId(devItem.find("deviceId")->toString()); + + connect(device, &PhaseDevice::sendDataToDraw, + this, &PhaseWindow::drawPhaseDataOnPage); + + device->initSerialPort(); + + QThread::msleep(100); + } + // 5. 设置下拉框的样式 + QStandardItemModel * model = qobject_cast(ui->devSelect->model()); + for (int i = 0; i < model->rowCount(); ++i) + { + QStandardItem * item = model->item(i); + item->setSizeHint({ 0, 30 }); + } } - for (int i = 0; i < this->deviceList.size(); i++) - { - QWidget * devWidget5 = new QWidget(this->ui->stackedWidget); - - this->ui->stackedWidget->addWidget(devWidget5); - - this->devWidgetList.append(devWidget5); - - // 创建设备的widget - this->generateWidgetForDevice(devCodeList.at(i), i); - } + // 6. 绘制一个设备的多个通道数据面板 + this->generateWidgetForDevice(); } PhaseWindow::~PhaseWindow() @@ -64,99 +95,119 @@ void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) { - // 1. 判断数据属于哪个设备,显示在不同的widget上 + // 当前显示的设备编号 + QString currentDevCode = ui->devSelect->currentData().toString(); - // 2. 循环设置各个tableView - QList devChannels = this->tableModelList.at(0); // 暂时写死 - for (int i = 0; i < phaseData->channelData.size(); i++) + // 如果不是当前设备的帧,直接返回 + if (phaseData->devCode != currentDevCode) { - if (phaseData->channelActive.at(i).toInt() == 1) - { - QList row; - QStandardItem * item = 0; - QStandardItem * item2 = 0; - item = new QStandardItem(QString("%1").arg(phaseData->timestamp.mid(11, 12))); - item2 = new QStandardItem(QString("%1").arg(phaseData->channelData.at(i))); + return; + } - row.append(item); - row.append(item2); + // 更新所有通道BOX的值 + for (int i = 0; i < phaseData->channelActive.size(); i++) + { + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); - QStandardItemModel * model; - model = devChannels.at(i); - if (model->rowCount() >= 60) - { - model->removeRows(0, model->rowCount()); - } - - model->insertRow(0, row); - } + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(phaseData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelData.at(i))); + ((QLineEdit *)channelBox->children().at(6))->setText(phaseData->frameId); + ((QLabel *)channelBox->children().at(7))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); } } -void PhaseWindow::generateWidgetForDevice(QString devCode, int index) +void PhaseWindow::generateWidgetForDevice() { - // 顶部切换widget - QWidget * switchWidget = new QWidget(this->devWidgetList.at(index)); - switchWidget->setGeometry(0, 0, 1024, 50); + // 获取设备数据 + int channelNum = 16; - // 显示数据的区域 - QWidget * gridWidget = new QWidget(this->devWidgetList.at(index)); - gridWidget->setGeometry(0, 50, 1024, 670); + QRect screenRect = QApplication::desktop()->screenGeometry(); - // 顶部水平布局,用于排布按钮 - QHBoxLayout * hLayout = new QHBoxLayout(switchWidget); + ui->scrollContents->setGeometry(0, 60, screenRect.width(), channelNum * 90); - // 文本 - QLabel * label = new QLabel(switchWidget); - label->setText("设备编号:" + devCode); - label->setFont(QFont("微软雅黑", 12)); - hLayout->addWidget(label); + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); - // 按钮 - for (int i = 0; i < this->deviceList.size(); i++) + for (int i = 0; i < channelNum; i++) { - QPushButton * butt5 = new QPushButton(this->deviceList.at(i)->getDevCode()); - hLayout->addWidget(butt5); + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 80 + 10, screenRect.width() - 40, 80); - connect(butt5, &QPushButton::clicked, [=](){ - this->ui->stackedWidget->setCurrentIndex(i); - }); + QHBoxLayout * vbox = new QHBoxLayout(group); + + QLabel * tmLabel = new QLabel(); + tmLabel->setText("时间"); + tmLabel->setFont(labelFont); + tmLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(tmLabel); + QLineEdit * tmValue = new QLineEdit(); + tmValue->setFixedWidth(200); + tmValue->setFont(labelFont); + vbox->addWidget(tmValue); + + QLabel * dataLabel = new QLabel(); + dataLabel->setText("测量数据"); + dataLabel->setFont(labelFont); + dataLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(dataLabel); + QLineEdit * dataValue = new QLineEdit(); + dataValue->setFixedWidth(150); + dataValue->setFont(labelFont); + vbox->addWidget(dataValue); + + QLabel * idLabel = new QLabel(); + idLabel->setText("数据ID"); + idLabel->setFont(labelFont); + idLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(idLabel); + QLineEdit * idValue = new QLineEdit(); + idValue->setFixedWidth(100); + idValue->setFont(labelFont); + vbox->addWidget(idValue); + + QLabel * validLabel = new QLabel(); + validLabel->setText("-"); + validLabel->setFont(labelFont); + validLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(validLabel); + + QSpacerItem * hSpace = new QSpacerItem(20, 20); + hSpace->changeSize(20, 20, QSizePolicy::Expanding); + vbox->addItem(hSpace); + + group->setLayout(vbox); + + layout->addWidget(group); } - - // Grid布局 - QGridLayout * gridLayout = new QGridLayout(gridWidget); - gridLayout->setSpacing(10); - - QList channelModelList; - QStringList labels = QObject::trUtf8("时间,相差").simplified().split(","); - - for (int i = 0; i < 16; i++) - { - QTableView * channelTable = new QTableView(gridWidget); - QStandardItemModel * model = new QStandardItemModel(channelTable); - - model->setHorizontalHeaderLabels(labels); - - channelTable->setModel(model); - - gridLayout->addWidget(channelTable, i / 4, i % 4); - - channelTable->verticalHeader()->hide(); - channelTable->setEditTriggers(QAbstractItemView::NoEditTriggers); - channelTable->scrollToBottom(); - - channelModelList.append(model); - } - - this->tableModelList.append(channelModelList); } -void PhaseWindow::createKafkaMessage() +int PhaseWindow::initHttpToken() { - this->kafkaUtil = new QKafkaUtil(this); - this->kafkaUtil->setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); - this->kafkaUtil->setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int PhaseWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject PhaseWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("比相仪"); + return response; +} - kafkaUtil->createProducer(); - kafkaUtil->produceMessage("hello world kafka kylin"); +void PhaseWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} + +void PhaseWindow::on_exitButt_clicked() +{ + QApplication::exit(0); } diff --git a/PhaseCompAcq/PhaseWindow.h b/PhaseCompAcq/PhaseWindow.h index 67b8363..02a7908 100644 --- a/PhaseCompAcq/PhaseWindow.h +++ b/PhaseCompAcq/PhaseWindow.h @@ -2,11 +2,13 @@ #define PHASEWINDOW_H #include +#include #include +#include #include "PhaseDevice.h" #include "common/utils/SettingConfig.h" -#include "common/utils/QKafkaUtil.h" +#include "common/HttpRequestController.h" namespace Ui { class PhaseWindow; @@ -23,18 +25,23 @@ public slots: void drawPhaseDataOnPage(PhaseDataDto * phaseData); +private slots: + void on_minButt_clicked(); + + void on_exitButt_clicked(); + private: + int initHttpToken(); + int initDictDeviceTypes(); + QJsonObject initDeviceList(); + Ui::PhaseWindow *ui; - QList devWidgetList; + HttpRequestController * httpReq; QList deviceList; - QList> tableModelList; - QKafkaUtil * kafkaUtil; - - void generateWidgetForDevice(QString devCode, int index); - void createKafkaMessage(); + void generateWidgetForDevice(); }; #endif // PHASEWINDOW_H diff --git a/PhaseCompAcq/PhaseWindow.ui b/PhaseCompAcq/PhaseWindow.ui index e6da880..01a7759 100644 --- a/PhaseCompAcq/PhaseWindow.ui +++ b/PhaseCompAcq/PhaseWindow.ui @@ -10,26 +10,144 @@ 720 - - - 1024 - 720 - - 多通道比相仪数据采集 - + 0 0 - 1024 - 720 + 100 + 30 - - -1 + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 100 + 30 + + + + + + + + 400 + 10 + 250 + 40 + + + + + + + 250 + 0 + 150 + 60 + + + + + 微软雅黑 + 12 + + + + Qt::LeftToRight + + + 请选择比相仪 + + + Qt::AlignCenter + + + + + + 880 + 10 + 40 + 40 + + + + + + + 退出 + + + + + + 20 + 0 + 200 + 60 + + + + + 微软雅黑 + 14 + + + + 多通道比相仪数据采集 + + + + + + 0 + 59 + 1024 + 1 + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + 830 + 10 + 40 + 40 + + + + + + + 最小化 diff --git a/CounterAcq/CounterAcq.pro b/CounterAcq/CounterAcq.pro index 72407cd..fae9d10 100644 --- a/CounterAcq/CounterAcq.pro +++ b/CounterAcq/CounterAcq.pro @@ -4,13 +4,6 @@ CONFIG += c++11 -SOURCES += \ - CounterWindow.cpp \ - main.cpp \ - -HEADERS += \ - CounterWindow.h \ - FORMS += \ CounterWindow.ui \ @@ -18,8 +11,11 @@ include(protocol/protocol.pri) HEADERS += CounterDevice.h +HEADERS += CounterWindow.h SOURCES += CounterDevice.cpp +SOURCES += CounterWindow.cpp +SOURCES += main.cpp DISTFILES += conf/config.ini diff --git a/CounterAcq/CounterWindow.cpp b/CounterAcq/CounterWindow.cpp index 80035a9..a50ebcf 100644 --- a/CounterAcq/CounterWindow.cpp +++ b/CounterAcq/CounterWindow.cpp @@ -42,7 +42,7 @@ { QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); - QApplication::exit(0); + QTimer::singleShot(1000, qApp, SLOT(quit())); } // 2. 获取字典值:设备类型 retCode = this->initDictDeviceTypes(); diff --git a/CounterAcq/CounterWindow.h b/CounterAcq/CounterWindow.h index 8d5e4a6..09277ba 100644 --- a/CounterAcq/CounterWindow.h +++ b/CounterAcq/CounterWindow.h @@ -7,7 +7,6 @@ #include #include "common/utils/SettingConfig.h" -#include "common/utils/QKafkaUtil.h" #include "common/HttpRequestController.h" #include "CounterDevice.h" @@ -23,8 +22,6 @@ explicit CounterWindow(QWidget *parent = nullptr); ~CounterWindow(); - QString token; - public slots: void drawCounterDataOnPage(CounterDataDto * counterData); @@ -40,7 +37,6 @@ Ui::CounterWindow *ui; - QTimer * timer; HttpRequestController * httpReq; QList deviceList; diff --git a/PhaseCompAcq/PhaseCompAcq.pro b/PhaseCompAcq/PhaseCompAcq.pro index 5eef2d1..c5e895b 100644 --- a/PhaseCompAcq/PhaseCompAcq.pro +++ b/PhaseCompAcq/PhaseCompAcq.pro @@ -1,16 +1,9 @@ -QT += core gui serialport +QT += core gui serialport network greaterThan(QT_MAJOR_VERSION, 4): QT += widgets CONFIG += c++11 -SOURCES += \ - main.cpp \ - PhaseWindow.cpp - -HEADERS += \ - PhaseWindow.h - FORMS += \ PhaseWindow.ui @@ -18,20 +11,19 @@ include(protocol/protocol.pri) HEADERS += PhaseDevice.h -#HEADERS += PhaseSerialServer.h +HEADERS += PhaseWindow.h SOURCES += PhaseDevice.cpp -#SOURCES += PhaseSerialServer.cpp +SOURCES += PhaseWindow.cpp +SOURCES += main.cpp # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target - -INCLUDEPATH += $$PWD/include/librdkafka -DEPENDPATH += $$PWD/include/librdkafka +#unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +#INCLUDEPATH += $$PWD/include/librdkafka +#DEPENDPATH += $$PWD/include/librdkafka DISTFILES += conf/config.ini - -unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ diff --git a/PhaseCompAcq/PhaseDevice.cpp b/PhaseCompAcq/PhaseDevice.cpp index 5c84cd5..afc2687 100644 --- a/PhaseCompAcq/PhaseDevice.cpp +++ b/PhaseCompAcq/PhaseDevice.cpp @@ -7,9 +7,9 @@ connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, this, &PhaseDevice::dataReceivedHandler); - kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); - kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); - kafkaUtil.createProducer(); +// kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); +// kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); +// kafkaUtil.createProducer(); } PhaseDevice::~PhaseDevice() @@ -34,6 +34,10 @@ { this->devCode = devCode; } +void PhaseDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} bool PhaseDevice::isSerialOpen() { @@ -74,6 +78,7 @@ if (parse == true) { QDateTime now = QDateTime::currentDateTime(); + phaseData->devCode = this->devCode; phaseData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); phaseData->milisecond = now.toMSecsSinceEpoch(); this->afterFramePhase(phaseData); @@ -92,21 +97,20 @@ this->dataBuff.clear(); // 2. 输出到日志文件中 - QString filePostfix = phaseData->timestamp.mid(0, 13).replace(" ", "_"); - QString filePrefix = QApplication::applicationDirPath() + "/logs/"; + QString date = phaseData->timestamp.mid(0, 10); // 2.1 原始字节数组数据 - QString filename = filePrefix + "raw_" + filePostfix + ".log"; + QString filename = "raw_" + devCode + ".log"; QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); - QLogUtil::writeRawDataLog(filename, content); + QLogUtil::writeRawDataLogByDate(date, filename, content); // 2.2 各个通道的相差数据 for (int i = 1; i <= phaseData->channelActive.size(); i++) { if (phaseData->channelActive.at(i-1).toUInt() == 1) { - QString chFilename("%1CH_%2_%3.log"); - chFilename = chFilename.arg(filePrefix); + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); if (i < 10) { chFilename = chFilename.arg(QString("0%1").arg(i)); @@ -114,10 +118,9 @@ { chFilename = chFilename.arg(i); } - chFilename = chFilename.arg(filePostfix); - QString channelDataStr = QString("%1 %2 %3").arg(phaseData->timestamp).arg(phaseData->channelData.at(i-1)).arg(phaseData->frameId); + QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelData.at(i-1)); - QLogUtil::writeChannelDataLog(chFilename, channelDataStr); + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); // 3. 输出到中间件,执行后续处理过程 if (SettingConfig::getInstance().NEED_KAFKA == 1) @@ -125,7 +128,7 @@ QJsonObject jsonObj = phaseData->toJSON(i - 1); jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); jsonObj.insert("deviceId", devCode); - kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); +// kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); } } } diff --git a/PhaseCompAcq/PhaseDevice.h b/PhaseCompAcq/PhaseDevice.h index 92182d4..aa7d822 100644 --- a/PhaseCompAcq/PhaseDevice.h +++ b/PhaseCompAcq/PhaseDevice.h @@ -5,7 +5,7 @@ #include "common/utils/QSerialPortUtil.h" #include "common/utils/QLogUtil.h" #include "common/utils/SettingConfig.h" -#include "common/utils/QKafkaUtil.h" +//#include "common/utils/QKafkaUtil.h" #include "protocol/PhaseProtocolBM.h" class PhaseDevice : public QObject @@ -25,15 +25,17 @@ void setBaudRate(int baudRate); QString getDevCode(); void setDevCode(QString devCode); + void setDeviceId(QString deviceId); bool isSerialOpen(); private: + QString deviceId; QString devCode; QString comName; int baudRate; QSerialPortUtil serialUtil; - QKafkaUtil kafkaUtil; +// QKafkaUtil kafkaUtil; QByteArray dataBuff; signals: diff --git a/PhaseCompAcq/PhaseWindow.cpp b/PhaseCompAcq/PhaseWindow.cpp index b3cab89..d0e8221 100644 --- a/PhaseCompAcq/PhaseWindow.cpp +++ b/PhaseCompAcq/PhaseWindow.cpp @@ -1,16 +1,16 @@ #include "PhaseWindow.h" #include "ui_PhaseWindow.h" -#include -#include -#include -#include -#include -#include - #include - -#include "common/utils/QKafkaUtil.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include PhaseWindow::PhaseWindow(QWidget *parent) : QWidget(parent), @@ -18,43 +18,74 @@ { ui->setupUi(this); - QString portNames = SettingConfig::getInstance().PORT_NAMES; - int baudRate = SettingConfig::getInstance().BAUD_RATE; - QString devCodes = SettingConfig::getInstance().DEV_CODES; + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); - QStringList comDevList = portNames.split(","); - QStringList devCodeList = devCodes.split(","); + // 窗口大小为占满一屏 + QRect screenRect = QApplication::desktop()->screenGeometry(); + resize(screenRect.width(), screenRect.height()); - for (int i = 0; i < comDevList.size(); i++) + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->line->setGeometry(0, 59, screenRect.width(), 1); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 60, screenRect.width(), screenRect.height() - 60); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + + httpReq = new HttpRequestController(this); + // 1. 获取访问接口需要的token + int retCode = this->initHttpToken(); + if (retCode != 200) { - PhaseDevice * device = new PhaseDevice(this); + QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); - // - connect(device, &PhaseDevice::sendDataToDraw, - this, &PhaseWindow::drawPhaseDataOnPage); + QTimer::singleShot(1000, qApp, SLOT(quit())); + } + // 2. 获取字典值:设备类型 + retCode = this->initDictDeviceTypes(); - device->setComName(comDevList.at(i)); - device->setBaudRate(baudRate); + // 3. 获取比相仪设备列表 + QJsonObject devListRes = this->initDeviceList(); + if (devListRes.find("code")->toInt() == 200) + { + ui->devSelect->clear(); - device->setDevCode(devCodeList.at(i)); + // 4. 将获取到的设备添加到下拉列表框中 + QJsonArray devArray = devListRes.find("data")->toArray(); + for (int i = 0; i < devArray.size(); i++) + { + QJsonObject devItem = devArray.at(i).toObject(); + ui->devSelect->addItem(devItem.find("deviceName")->toString(), devItem.find("deviceNo")->toString()); - this->deviceList.append(device); + PhaseDevice * device = new PhaseDevice(this); + deviceList.append(device); - device->initSerialPort(); - device->startWork(); + device->setComName(devItem.find("linkComName")->toString()); + device->setBaudRate(SettingConfig::getInstance().BAUD_RATE); + device->setDevCode(devItem.find("deviceNo")->toString()); + device->setDeviceId(devItem.find("deviceId")->toString()); + + connect(device, &PhaseDevice::sendDataToDraw, + this, &PhaseWindow::drawPhaseDataOnPage); + + device->initSerialPort(); + + QThread::msleep(100); + } + // 5. 设置下拉框的样式 + QStandardItemModel * model = qobject_cast(ui->devSelect->model()); + for (int i = 0; i < model->rowCount(); ++i) + { + QStandardItem * item = model->item(i); + item->setSizeHint({ 0, 30 }); + } } - for (int i = 0; i < this->deviceList.size(); i++) - { - QWidget * devWidget5 = new QWidget(this->ui->stackedWidget); - - this->ui->stackedWidget->addWidget(devWidget5); - - this->devWidgetList.append(devWidget5); - - // 创建设备的widget - this->generateWidgetForDevice(devCodeList.at(i), i); - } + // 6. 绘制一个设备的多个通道数据面板 + this->generateWidgetForDevice(); } PhaseWindow::~PhaseWindow() @@ -64,99 +95,119 @@ void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) { - // 1. 判断数据属于哪个设备,显示在不同的widget上 + // 当前显示的设备编号 + QString currentDevCode = ui->devSelect->currentData().toString(); - // 2. 循环设置各个tableView - QList devChannels = this->tableModelList.at(0); // 暂时写死 - for (int i = 0; i < phaseData->channelData.size(); i++) + // 如果不是当前设备的帧,直接返回 + if (phaseData->devCode != currentDevCode) { - if (phaseData->channelActive.at(i).toInt() == 1) - { - QList row; - QStandardItem * item = 0; - QStandardItem * item2 = 0; - item = new QStandardItem(QString("%1").arg(phaseData->timestamp.mid(11, 12))); - item2 = new QStandardItem(QString("%1").arg(phaseData->channelData.at(i))); + return; + } - row.append(item); - row.append(item2); + // 更新所有通道BOX的值 + for (int i = 0; i < phaseData->channelActive.size(); i++) + { + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); - QStandardItemModel * model; - model = devChannels.at(i); - if (model->rowCount() >= 60) - { - model->removeRows(0, model->rowCount()); - } - - model->insertRow(0, row); - } + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(phaseData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelData.at(i))); + ((QLineEdit *)channelBox->children().at(6))->setText(phaseData->frameId); + ((QLabel *)channelBox->children().at(7))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); } } -void PhaseWindow::generateWidgetForDevice(QString devCode, int index) +void PhaseWindow::generateWidgetForDevice() { - // 顶部切换widget - QWidget * switchWidget = new QWidget(this->devWidgetList.at(index)); - switchWidget->setGeometry(0, 0, 1024, 50); + // 获取设备数据 + int channelNum = 16; - // 显示数据的区域 - QWidget * gridWidget = new QWidget(this->devWidgetList.at(index)); - gridWidget->setGeometry(0, 50, 1024, 670); + QRect screenRect = QApplication::desktop()->screenGeometry(); - // 顶部水平布局,用于排布按钮 - QHBoxLayout * hLayout = new QHBoxLayout(switchWidget); + ui->scrollContents->setGeometry(0, 60, screenRect.width(), channelNum * 90); - // 文本 - QLabel * label = new QLabel(switchWidget); - label->setText("设备编号:" + devCode); - label->setFont(QFont("微软雅黑", 12)); - hLayout->addWidget(label); + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); - // 按钮 - for (int i = 0; i < this->deviceList.size(); i++) + for (int i = 0; i < channelNum; i++) { - QPushButton * butt5 = new QPushButton(this->deviceList.at(i)->getDevCode()); - hLayout->addWidget(butt5); + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 80 + 10, screenRect.width() - 40, 80); - connect(butt5, &QPushButton::clicked, [=](){ - this->ui->stackedWidget->setCurrentIndex(i); - }); + QHBoxLayout * vbox = new QHBoxLayout(group); + + QLabel * tmLabel = new QLabel(); + tmLabel->setText("时间"); + tmLabel->setFont(labelFont); + tmLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(tmLabel); + QLineEdit * tmValue = new QLineEdit(); + tmValue->setFixedWidth(200); + tmValue->setFont(labelFont); + vbox->addWidget(tmValue); + + QLabel * dataLabel = new QLabel(); + dataLabel->setText("测量数据"); + dataLabel->setFont(labelFont); + dataLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(dataLabel); + QLineEdit * dataValue = new QLineEdit(); + dataValue->setFixedWidth(150); + dataValue->setFont(labelFont); + vbox->addWidget(dataValue); + + QLabel * idLabel = new QLabel(); + idLabel->setText("数据ID"); + idLabel->setFont(labelFont); + idLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(idLabel); + QLineEdit * idValue = new QLineEdit(); + idValue->setFixedWidth(100); + idValue->setFont(labelFont); + vbox->addWidget(idValue); + + QLabel * validLabel = new QLabel(); + validLabel->setText("-"); + validLabel->setFont(labelFont); + validLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(validLabel); + + QSpacerItem * hSpace = new QSpacerItem(20, 20); + hSpace->changeSize(20, 20, QSizePolicy::Expanding); + vbox->addItem(hSpace); + + group->setLayout(vbox); + + layout->addWidget(group); } - - // Grid布局 - QGridLayout * gridLayout = new QGridLayout(gridWidget); - gridLayout->setSpacing(10); - - QList channelModelList; - QStringList labels = QObject::trUtf8("时间,相差").simplified().split(","); - - for (int i = 0; i < 16; i++) - { - QTableView * channelTable = new QTableView(gridWidget); - QStandardItemModel * model = new QStandardItemModel(channelTable); - - model->setHorizontalHeaderLabels(labels); - - channelTable->setModel(model); - - gridLayout->addWidget(channelTable, i / 4, i % 4); - - channelTable->verticalHeader()->hide(); - channelTable->setEditTriggers(QAbstractItemView::NoEditTriggers); - channelTable->scrollToBottom(); - - channelModelList.append(model); - } - - this->tableModelList.append(channelModelList); } -void PhaseWindow::createKafkaMessage() +int PhaseWindow::initHttpToken() { - this->kafkaUtil = new QKafkaUtil(this); - this->kafkaUtil->setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); - this->kafkaUtil->setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int PhaseWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject PhaseWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("比相仪"); + return response; +} - kafkaUtil->createProducer(); - kafkaUtil->produceMessage("hello world kafka kylin"); +void PhaseWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} + +void PhaseWindow::on_exitButt_clicked() +{ + QApplication::exit(0); } diff --git a/PhaseCompAcq/PhaseWindow.h b/PhaseCompAcq/PhaseWindow.h index 67b8363..02a7908 100644 --- a/PhaseCompAcq/PhaseWindow.h +++ b/PhaseCompAcq/PhaseWindow.h @@ -2,11 +2,13 @@ #define PHASEWINDOW_H #include +#include #include +#include #include "PhaseDevice.h" #include "common/utils/SettingConfig.h" -#include "common/utils/QKafkaUtil.h" +#include "common/HttpRequestController.h" namespace Ui { class PhaseWindow; @@ -23,18 +25,23 @@ public slots: void drawPhaseDataOnPage(PhaseDataDto * phaseData); +private slots: + void on_minButt_clicked(); + + void on_exitButt_clicked(); + private: + int initHttpToken(); + int initDictDeviceTypes(); + QJsonObject initDeviceList(); + Ui::PhaseWindow *ui; - QList devWidgetList; + HttpRequestController * httpReq; QList deviceList; - QList> tableModelList; - QKafkaUtil * kafkaUtil; - - void generateWidgetForDevice(QString devCode, int index); - void createKafkaMessage(); + void generateWidgetForDevice(); }; #endif // PHASEWINDOW_H diff --git a/PhaseCompAcq/PhaseWindow.ui b/PhaseCompAcq/PhaseWindow.ui index e6da880..01a7759 100644 --- a/PhaseCompAcq/PhaseWindow.ui +++ b/PhaseCompAcq/PhaseWindow.ui @@ -10,26 +10,144 @@ 720 - - - 1024 - 720 - - 多通道比相仪数据采集 - + 0 0 - 1024 - 720 + 100 + 30 - - -1 + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 100 + 30 + + + + + + + + 400 + 10 + 250 + 40 + + + + + + + 250 + 0 + 150 + 60 + + + + + 微软雅黑 + 12 + + + + Qt::LeftToRight + + + 请选择比相仪 + + + Qt::AlignCenter + + + + + + 880 + 10 + 40 + 40 + + + + + + + 退出 + + + + + + 20 + 0 + 200 + 60 + + + + + 微软雅黑 + 14 + + + + 多通道比相仪数据采集 + + + + + + 0 + 59 + 1024 + 1 + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + 830 + 10 + 40 + 40 + + + + + + + 最小化 diff --git a/PhaseCompAcq/common/ConstCache.h b/PhaseCompAcq/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/PhaseCompAcq/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/CounterAcq/CounterAcq.pro b/CounterAcq/CounterAcq.pro index 72407cd..fae9d10 100644 --- a/CounterAcq/CounterAcq.pro +++ b/CounterAcq/CounterAcq.pro @@ -4,13 +4,6 @@ CONFIG += c++11 -SOURCES += \ - CounterWindow.cpp \ - main.cpp \ - -HEADERS += \ - CounterWindow.h \ - FORMS += \ CounterWindow.ui \ @@ -18,8 +11,11 @@ include(protocol/protocol.pri) HEADERS += CounterDevice.h +HEADERS += CounterWindow.h SOURCES += CounterDevice.cpp +SOURCES += CounterWindow.cpp +SOURCES += main.cpp DISTFILES += conf/config.ini diff --git a/CounterAcq/CounterWindow.cpp b/CounterAcq/CounterWindow.cpp index 80035a9..a50ebcf 100644 --- a/CounterAcq/CounterWindow.cpp +++ b/CounterAcq/CounterWindow.cpp @@ -42,7 +42,7 @@ { QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); - QApplication::exit(0); + QTimer::singleShot(1000, qApp, SLOT(quit())); } // 2. 获取字典值:设备类型 retCode = this->initDictDeviceTypes(); diff --git a/CounterAcq/CounterWindow.h b/CounterAcq/CounterWindow.h index 8d5e4a6..09277ba 100644 --- a/CounterAcq/CounterWindow.h +++ b/CounterAcq/CounterWindow.h @@ -7,7 +7,6 @@ #include #include "common/utils/SettingConfig.h" -#include "common/utils/QKafkaUtil.h" #include "common/HttpRequestController.h" #include "CounterDevice.h" @@ -23,8 +22,6 @@ explicit CounterWindow(QWidget *parent = nullptr); ~CounterWindow(); - QString token; - public slots: void drawCounterDataOnPage(CounterDataDto * counterData); @@ -40,7 +37,6 @@ Ui::CounterWindow *ui; - QTimer * timer; HttpRequestController * httpReq; QList deviceList; diff --git a/PhaseCompAcq/PhaseCompAcq.pro b/PhaseCompAcq/PhaseCompAcq.pro index 5eef2d1..c5e895b 100644 --- a/PhaseCompAcq/PhaseCompAcq.pro +++ b/PhaseCompAcq/PhaseCompAcq.pro @@ -1,16 +1,9 @@ -QT += core gui serialport +QT += core gui serialport network greaterThan(QT_MAJOR_VERSION, 4): QT += widgets CONFIG += c++11 -SOURCES += \ - main.cpp \ - PhaseWindow.cpp - -HEADERS += \ - PhaseWindow.h - FORMS += \ PhaseWindow.ui @@ -18,20 +11,19 @@ include(protocol/protocol.pri) HEADERS += PhaseDevice.h -#HEADERS += PhaseSerialServer.h +HEADERS += PhaseWindow.h SOURCES += PhaseDevice.cpp -#SOURCES += PhaseSerialServer.cpp +SOURCES += PhaseWindow.cpp +SOURCES += main.cpp # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target - -INCLUDEPATH += $$PWD/include/librdkafka -DEPENDPATH += $$PWD/include/librdkafka +#unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +#INCLUDEPATH += $$PWD/include/librdkafka +#DEPENDPATH += $$PWD/include/librdkafka DISTFILES += conf/config.ini - -unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ diff --git a/PhaseCompAcq/PhaseDevice.cpp b/PhaseCompAcq/PhaseDevice.cpp index 5c84cd5..afc2687 100644 --- a/PhaseCompAcq/PhaseDevice.cpp +++ b/PhaseCompAcq/PhaseDevice.cpp @@ -7,9 +7,9 @@ connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, this, &PhaseDevice::dataReceivedHandler); - kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); - kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); - kafkaUtil.createProducer(); +// kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); +// kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); +// kafkaUtil.createProducer(); } PhaseDevice::~PhaseDevice() @@ -34,6 +34,10 @@ { this->devCode = devCode; } +void PhaseDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} bool PhaseDevice::isSerialOpen() { @@ -74,6 +78,7 @@ if (parse == true) { QDateTime now = QDateTime::currentDateTime(); + phaseData->devCode = this->devCode; phaseData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); phaseData->milisecond = now.toMSecsSinceEpoch(); this->afterFramePhase(phaseData); @@ -92,21 +97,20 @@ this->dataBuff.clear(); // 2. 输出到日志文件中 - QString filePostfix = phaseData->timestamp.mid(0, 13).replace(" ", "_"); - QString filePrefix = QApplication::applicationDirPath() + "/logs/"; + QString date = phaseData->timestamp.mid(0, 10); // 2.1 原始字节数组数据 - QString filename = filePrefix + "raw_" + filePostfix + ".log"; + QString filename = "raw_" + devCode + ".log"; QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); - QLogUtil::writeRawDataLog(filename, content); + QLogUtil::writeRawDataLogByDate(date, filename, content); // 2.2 各个通道的相差数据 for (int i = 1; i <= phaseData->channelActive.size(); i++) { if (phaseData->channelActive.at(i-1).toUInt() == 1) { - QString chFilename("%1CH_%2_%3.log"); - chFilename = chFilename.arg(filePrefix); + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); if (i < 10) { chFilename = chFilename.arg(QString("0%1").arg(i)); @@ -114,10 +118,9 @@ { chFilename = chFilename.arg(i); } - chFilename = chFilename.arg(filePostfix); - QString channelDataStr = QString("%1 %2 %3").arg(phaseData->timestamp).arg(phaseData->channelData.at(i-1)).arg(phaseData->frameId); + QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelData.at(i-1)); - QLogUtil::writeChannelDataLog(chFilename, channelDataStr); + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); // 3. 输出到中间件,执行后续处理过程 if (SettingConfig::getInstance().NEED_KAFKA == 1) @@ -125,7 +128,7 @@ QJsonObject jsonObj = phaseData->toJSON(i - 1); jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); jsonObj.insert("deviceId", devCode); - kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); +// kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); } } } diff --git a/PhaseCompAcq/PhaseDevice.h b/PhaseCompAcq/PhaseDevice.h index 92182d4..aa7d822 100644 --- a/PhaseCompAcq/PhaseDevice.h +++ b/PhaseCompAcq/PhaseDevice.h @@ -5,7 +5,7 @@ #include "common/utils/QSerialPortUtil.h" #include "common/utils/QLogUtil.h" #include "common/utils/SettingConfig.h" -#include "common/utils/QKafkaUtil.h" +//#include "common/utils/QKafkaUtil.h" #include "protocol/PhaseProtocolBM.h" class PhaseDevice : public QObject @@ -25,15 +25,17 @@ void setBaudRate(int baudRate); QString getDevCode(); void setDevCode(QString devCode); + void setDeviceId(QString deviceId); bool isSerialOpen(); private: + QString deviceId; QString devCode; QString comName; int baudRate; QSerialPortUtil serialUtil; - QKafkaUtil kafkaUtil; +// QKafkaUtil kafkaUtil; QByteArray dataBuff; signals: diff --git a/PhaseCompAcq/PhaseWindow.cpp b/PhaseCompAcq/PhaseWindow.cpp index b3cab89..d0e8221 100644 --- a/PhaseCompAcq/PhaseWindow.cpp +++ b/PhaseCompAcq/PhaseWindow.cpp @@ -1,16 +1,16 @@ #include "PhaseWindow.h" #include "ui_PhaseWindow.h" -#include -#include -#include -#include -#include -#include - #include - -#include "common/utils/QKafkaUtil.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include PhaseWindow::PhaseWindow(QWidget *parent) : QWidget(parent), @@ -18,43 +18,74 @@ { ui->setupUi(this); - QString portNames = SettingConfig::getInstance().PORT_NAMES; - int baudRate = SettingConfig::getInstance().BAUD_RATE; - QString devCodes = SettingConfig::getInstance().DEV_CODES; + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); - QStringList comDevList = portNames.split(","); - QStringList devCodeList = devCodes.split(","); + // 窗口大小为占满一屏 + QRect screenRect = QApplication::desktop()->screenGeometry(); + resize(screenRect.width(), screenRect.height()); - for (int i = 0; i < comDevList.size(); i++) + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->line->setGeometry(0, 59, screenRect.width(), 1); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 60, screenRect.width(), screenRect.height() - 60); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + + httpReq = new HttpRequestController(this); + // 1. 获取访问接口需要的token + int retCode = this->initHttpToken(); + if (retCode != 200) { - PhaseDevice * device = new PhaseDevice(this); + QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); - // - connect(device, &PhaseDevice::sendDataToDraw, - this, &PhaseWindow::drawPhaseDataOnPage); + QTimer::singleShot(1000, qApp, SLOT(quit())); + } + // 2. 获取字典值:设备类型 + retCode = this->initDictDeviceTypes(); - device->setComName(comDevList.at(i)); - device->setBaudRate(baudRate); + // 3. 获取比相仪设备列表 + QJsonObject devListRes = this->initDeviceList(); + if (devListRes.find("code")->toInt() == 200) + { + ui->devSelect->clear(); - device->setDevCode(devCodeList.at(i)); + // 4. 将获取到的设备添加到下拉列表框中 + QJsonArray devArray = devListRes.find("data")->toArray(); + for (int i = 0; i < devArray.size(); i++) + { + QJsonObject devItem = devArray.at(i).toObject(); + ui->devSelect->addItem(devItem.find("deviceName")->toString(), devItem.find("deviceNo")->toString()); - this->deviceList.append(device); + PhaseDevice * device = new PhaseDevice(this); + deviceList.append(device); - device->initSerialPort(); - device->startWork(); + device->setComName(devItem.find("linkComName")->toString()); + device->setBaudRate(SettingConfig::getInstance().BAUD_RATE); + device->setDevCode(devItem.find("deviceNo")->toString()); + device->setDeviceId(devItem.find("deviceId")->toString()); + + connect(device, &PhaseDevice::sendDataToDraw, + this, &PhaseWindow::drawPhaseDataOnPage); + + device->initSerialPort(); + + QThread::msleep(100); + } + // 5. 设置下拉框的样式 + QStandardItemModel * model = qobject_cast(ui->devSelect->model()); + for (int i = 0; i < model->rowCount(); ++i) + { + QStandardItem * item = model->item(i); + item->setSizeHint({ 0, 30 }); + } } - for (int i = 0; i < this->deviceList.size(); i++) - { - QWidget * devWidget5 = new QWidget(this->ui->stackedWidget); - - this->ui->stackedWidget->addWidget(devWidget5); - - this->devWidgetList.append(devWidget5); - - // 创建设备的widget - this->generateWidgetForDevice(devCodeList.at(i), i); - } + // 6. 绘制一个设备的多个通道数据面板 + this->generateWidgetForDevice(); } PhaseWindow::~PhaseWindow() @@ -64,99 +95,119 @@ void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) { - // 1. 判断数据属于哪个设备,显示在不同的widget上 + // 当前显示的设备编号 + QString currentDevCode = ui->devSelect->currentData().toString(); - // 2. 循环设置各个tableView - QList devChannels = this->tableModelList.at(0); // 暂时写死 - for (int i = 0; i < phaseData->channelData.size(); i++) + // 如果不是当前设备的帧,直接返回 + if (phaseData->devCode != currentDevCode) { - if (phaseData->channelActive.at(i).toInt() == 1) - { - QList row; - QStandardItem * item = 0; - QStandardItem * item2 = 0; - item = new QStandardItem(QString("%1").arg(phaseData->timestamp.mid(11, 12))); - item2 = new QStandardItem(QString("%1").arg(phaseData->channelData.at(i))); + return; + } - row.append(item); - row.append(item2); + // 更新所有通道BOX的值 + for (int i = 0; i < phaseData->channelActive.size(); i++) + { + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); - QStandardItemModel * model; - model = devChannels.at(i); - if (model->rowCount() >= 60) - { - model->removeRows(0, model->rowCount()); - } - - model->insertRow(0, row); - } + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(phaseData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelData.at(i))); + ((QLineEdit *)channelBox->children().at(6))->setText(phaseData->frameId); + ((QLabel *)channelBox->children().at(7))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); } } -void PhaseWindow::generateWidgetForDevice(QString devCode, int index) +void PhaseWindow::generateWidgetForDevice() { - // 顶部切换widget - QWidget * switchWidget = new QWidget(this->devWidgetList.at(index)); - switchWidget->setGeometry(0, 0, 1024, 50); + // 获取设备数据 + int channelNum = 16; - // 显示数据的区域 - QWidget * gridWidget = new QWidget(this->devWidgetList.at(index)); - gridWidget->setGeometry(0, 50, 1024, 670); + QRect screenRect = QApplication::desktop()->screenGeometry(); - // 顶部水平布局,用于排布按钮 - QHBoxLayout * hLayout = new QHBoxLayout(switchWidget); + ui->scrollContents->setGeometry(0, 60, screenRect.width(), channelNum * 90); - // 文本 - QLabel * label = new QLabel(switchWidget); - label->setText("设备编号:" + devCode); - label->setFont(QFont("微软雅黑", 12)); - hLayout->addWidget(label); + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); - // 按钮 - for (int i = 0; i < this->deviceList.size(); i++) + for (int i = 0; i < channelNum; i++) { - QPushButton * butt5 = new QPushButton(this->deviceList.at(i)->getDevCode()); - hLayout->addWidget(butt5); + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 80 + 10, screenRect.width() - 40, 80); - connect(butt5, &QPushButton::clicked, [=](){ - this->ui->stackedWidget->setCurrentIndex(i); - }); + QHBoxLayout * vbox = new QHBoxLayout(group); + + QLabel * tmLabel = new QLabel(); + tmLabel->setText("时间"); + tmLabel->setFont(labelFont); + tmLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(tmLabel); + QLineEdit * tmValue = new QLineEdit(); + tmValue->setFixedWidth(200); + tmValue->setFont(labelFont); + vbox->addWidget(tmValue); + + QLabel * dataLabel = new QLabel(); + dataLabel->setText("测量数据"); + dataLabel->setFont(labelFont); + dataLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(dataLabel); + QLineEdit * dataValue = new QLineEdit(); + dataValue->setFixedWidth(150); + dataValue->setFont(labelFont); + vbox->addWidget(dataValue); + + QLabel * idLabel = new QLabel(); + idLabel->setText("数据ID"); + idLabel->setFont(labelFont); + idLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(idLabel); + QLineEdit * idValue = new QLineEdit(); + idValue->setFixedWidth(100); + idValue->setFont(labelFont); + vbox->addWidget(idValue); + + QLabel * validLabel = new QLabel(); + validLabel->setText("-"); + validLabel->setFont(labelFont); + validLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(validLabel); + + QSpacerItem * hSpace = new QSpacerItem(20, 20); + hSpace->changeSize(20, 20, QSizePolicy::Expanding); + vbox->addItem(hSpace); + + group->setLayout(vbox); + + layout->addWidget(group); } - - // Grid布局 - QGridLayout * gridLayout = new QGridLayout(gridWidget); - gridLayout->setSpacing(10); - - QList channelModelList; - QStringList labels = QObject::trUtf8("时间,相差").simplified().split(","); - - for (int i = 0; i < 16; i++) - { - QTableView * channelTable = new QTableView(gridWidget); - QStandardItemModel * model = new QStandardItemModel(channelTable); - - model->setHorizontalHeaderLabels(labels); - - channelTable->setModel(model); - - gridLayout->addWidget(channelTable, i / 4, i % 4); - - channelTable->verticalHeader()->hide(); - channelTable->setEditTriggers(QAbstractItemView::NoEditTriggers); - channelTable->scrollToBottom(); - - channelModelList.append(model); - } - - this->tableModelList.append(channelModelList); } -void PhaseWindow::createKafkaMessage() +int PhaseWindow::initHttpToken() { - this->kafkaUtil = new QKafkaUtil(this); - this->kafkaUtil->setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); - this->kafkaUtil->setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int PhaseWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject PhaseWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("比相仪"); + return response; +} - kafkaUtil->createProducer(); - kafkaUtil->produceMessage("hello world kafka kylin"); +void PhaseWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} + +void PhaseWindow::on_exitButt_clicked() +{ + QApplication::exit(0); } diff --git a/PhaseCompAcq/PhaseWindow.h b/PhaseCompAcq/PhaseWindow.h index 67b8363..02a7908 100644 --- a/PhaseCompAcq/PhaseWindow.h +++ b/PhaseCompAcq/PhaseWindow.h @@ -2,11 +2,13 @@ #define PHASEWINDOW_H #include +#include #include +#include #include "PhaseDevice.h" #include "common/utils/SettingConfig.h" -#include "common/utils/QKafkaUtil.h" +#include "common/HttpRequestController.h" namespace Ui { class PhaseWindow; @@ -23,18 +25,23 @@ public slots: void drawPhaseDataOnPage(PhaseDataDto * phaseData); +private slots: + void on_minButt_clicked(); + + void on_exitButt_clicked(); + private: + int initHttpToken(); + int initDictDeviceTypes(); + QJsonObject initDeviceList(); + Ui::PhaseWindow *ui; - QList devWidgetList; + HttpRequestController * httpReq; QList deviceList; - QList> tableModelList; - QKafkaUtil * kafkaUtil; - - void generateWidgetForDevice(QString devCode, int index); - void createKafkaMessage(); + void generateWidgetForDevice(); }; #endif // PHASEWINDOW_H diff --git a/PhaseCompAcq/PhaseWindow.ui b/PhaseCompAcq/PhaseWindow.ui index e6da880..01a7759 100644 --- a/PhaseCompAcq/PhaseWindow.ui +++ b/PhaseCompAcq/PhaseWindow.ui @@ -10,26 +10,144 @@ 720 - - - 1024 - 720 - - 多通道比相仪数据采集 - + 0 0 - 1024 - 720 + 100 + 30 - - -1 + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 100 + 30 + + + + + + + + 400 + 10 + 250 + 40 + + + + + + + 250 + 0 + 150 + 60 + + + + + 微软雅黑 + 12 + + + + Qt::LeftToRight + + + 请选择比相仪 + + + Qt::AlignCenter + + + + + + 880 + 10 + 40 + 40 + + + + + + + 退出 + + + + + + 20 + 0 + 200 + 60 + + + + + 微软雅黑 + 14 + + + + 多通道比相仪数据采集 + + + + + + 0 + 59 + 1024 + 1 + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + 830 + 10 + 40 + 40 + + + + + + + 最小化 diff --git a/PhaseCompAcq/common/ConstCache.h b/PhaseCompAcq/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/PhaseCompAcq/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/PhaseCompAcq/common/HttpRequestController.cpp b/PhaseCompAcq/common/HttpRequestController.cpp new file mode 100644 index 0000000..6abb5af --- /dev/null +++ b/PhaseCompAcq/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceTypes.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDeviceList(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", system.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); + } + + qDebug() << resultObj; + + return resultObj; +} diff --git a/CounterAcq/CounterAcq.pro b/CounterAcq/CounterAcq.pro index 72407cd..fae9d10 100644 --- a/CounterAcq/CounterAcq.pro +++ b/CounterAcq/CounterAcq.pro @@ -4,13 +4,6 @@ CONFIG += c++11 -SOURCES += \ - CounterWindow.cpp \ - main.cpp \ - -HEADERS += \ - CounterWindow.h \ - FORMS += \ CounterWindow.ui \ @@ -18,8 +11,11 @@ include(protocol/protocol.pri) HEADERS += CounterDevice.h +HEADERS += CounterWindow.h SOURCES += CounterDevice.cpp +SOURCES += CounterWindow.cpp +SOURCES += main.cpp DISTFILES += conf/config.ini diff --git a/CounterAcq/CounterWindow.cpp b/CounterAcq/CounterWindow.cpp index 80035a9..a50ebcf 100644 --- a/CounterAcq/CounterWindow.cpp +++ b/CounterAcq/CounterWindow.cpp @@ -42,7 +42,7 @@ { QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); - QApplication::exit(0); + QTimer::singleShot(1000, qApp, SLOT(quit())); } // 2. 获取字典值:设备类型 retCode = this->initDictDeviceTypes(); diff --git a/CounterAcq/CounterWindow.h b/CounterAcq/CounterWindow.h index 8d5e4a6..09277ba 100644 --- a/CounterAcq/CounterWindow.h +++ b/CounterAcq/CounterWindow.h @@ -7,7 +7,6 @@ #include #include "common/utils/SettingConfig.h" -#include "common/utils/QKafkaUtil.h" #include "common/HttpRequestController.h" #include "CounterDevice.h" @@ -23,8 +22,6 @@ explicit CounterWindow(QWidget *parent = nullptr); ~CounterWindow(); - QString token; - public slots: void drawCounterDataOnPage(CounterDataDto * counterData); @@ -40,7 +37,6 @@ Ui::CounterWindow *ui; - QTimer * timer; HttpRequestController * httpReq; QList deviceList; diff --git a/PhaseCompAcq/PhaseCompAcq.pro b/PhaseCompAcq/PhaseCompAcq.pro index 5eef2d1..c5e895b 100644 --- a/PhaseCompAcq/PhaseCompAcq.pro +++ b/PhaseCompAcq/PhaseCompAcq.pro @@ -1,16 +1,9 @@ -QT += core gui serialport +QT += core gui serialport network greaterThan(QT_MAJOR_VERSION, 4): QT += widgets CONFIG += c++11 -SOURCES += \ - main.cpp \ - PhaseWindow.cpp - -HEADERS += \ - PhaseWindow.h - FORMS += \ PhaseWindow.ui @@ -18,20 +11,19 @@ include(protocol/protocol.pri) HEADERS += PhaseDevice.h -#HEADERS += PhaseSerialServer.h +HEADERS += PhaseWindow.h SOURCES += PhaseDevice.cpp -#SOURCES += PhaseSerialServer.cpp +SOURCES += PhaseWindow.cpp +SOURCES += main.cpp # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target - -INCLUDEPATH += $$PWD/include/librdkafka -DEPENDPATH += $$PWD/include/librdkafka +#unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +#INCLUDEPATH += $$PWD/include/librdkafka +#DEPENDPATH += $$PWD/include/librdkafka DISTFILES += conf/config.ini - -unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ diff --git a/PhaseCompAcq/PhaseDevice.cpp b/PhaseCompAcq/PhaseDevice.cpp index 5c84cd5..afc2687 100644 --- a/PhaseCompAcq/PhaseDevice.cpp +++ b/PhaseCompAcq/PhaseDevice.cpp @@ -7,9 +7,9 @@ connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, this, &PhaseDevice::dataReceivedHandler); - kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); - kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); - kafkaUtil.createProducer(); +// kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); +// kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); +// kafkaUtil.createProducer(); } PhaseDevice::~PhaseDevice() @@ -34,6 +34,10 @@ { this->devCode = devCode; } +void PhaseDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} bool PhaseDevice::isSerialOpen() { @@ -74,6 +78,7 @@ if (parse == true) { QDateTime now = QDateTime::currentDateTime(); + phaseData->devCode = this->devCode; phaseData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); phaseData->milisecond = now.toMSecsSinceEpoch(); this->afterFramePhase(phaseData); @@ -92,21 +97,20 @@ this->dataBuff.clear(); // 2. 输出到日志文件中 - QString filePostfix = phaseData->timestamp.mid(0, 13).replace(" ", "_"); - QString filePrefix = QApplication::applicationDirPath() + "/logs/"; + QString date = phaseData->timestamp.mid(0, 10); // 2.1 原始字节数组数据 - QString filename = filePrefix + "raw_" + filePostfix + ".log"; + QString filename = "raw_" + devCode + ".log"; QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); - QLogUtil::writeRawDataLog(filename, content); + QLogUtil::writeRawDataLogByDate(date, filename, content); // 2.2 各个通道的相差数据 for (int i = 1; i <= phaseData->channelActive.size(); i++) { if (phaseData->channelActive.at(i-1).toUInt() == 1) { - QString chFilename("%1CH_%2_%3.log"); - chFilename = chFilename.arg(filePrefix); + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); if (i < 10) { chFilename = chFilename.arg(QString("0%1").arg(i)); @@ -114,10 +118,9 @@ { chFilename = chFilename.arg(i); } - chFilename = chFilename.arg(filePostfix); - QString channelDataStr = QString("%1 %2 %3").arg(phaseData->timestamp).arg(phaseData->channelData.at(i-1)).arg(phaseData->frameId); + QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelData.at(i-1)); - QLogUtil::writeChannelDataLog(chFilename, channelDataStr); + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); // 3. 输出到中间件,执行后续处理过程 if (SettingConfig::getInstance().NEED_KAFKA == 1) @@ -125,7 +128,7 @@ QJsonObject jsonObj = phaseData->toJSON(i - 1); jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); jsonObj.insert("deviceId", devCode); - kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); +// kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); } } } diff --git a/PhaseCompAcq/PhaseDevice.h b/PhaseCompAcq/PhaseDevice.h index 92182d4..aa7d822 100644 --- a/PhaseCompAcq/PhaseDevice.h +++ b/PhaseCompAcq/PhaseDevice.h @@ -5,7 +5,7 @@ #include "common/utils/QSerialPortUtil.h" #include "common/utils/QLogUtil.h" #include "common/utils/SettingConfig.h" -#include "common/utils/QKafkaUtil.h" +//#include "common/utils/QKafkaUtil.h" #include "protocol/PhaseProtocolBM.h" class PhaseDevice : public QObject @@ -25,15 +25,17 @@ void setBaudRate(int baudRate); QString getDevCode(); void setDevCode(QString devCode); + void setDeviceId(QString deviceId); bool isSerialOpen(); private: + QString deviceId; QString devCode; QString comName; int baudRate; QSerialPortUtil serialUtil; - QKafkaUtil kafkaUtil; +// QKafkaUtil kafkaUtil; QByteArray dataBuff; signals: diff --git a/PhaseCompAcq/PhaseWindow.cpp b/PhaseCompAcq/PhaseWindow.cpp index b3cab89..d0e8221 100644 --- a/PhaseCompAcq/PhaseWindow.cpp +++ b/PhaseCompAcq/PhaseWindow.cpp @@ -1,16 +1,16 @@ #include "PhaseWindow.h" #include "ui_PhaseWindow.h" -#include -#include -#include -#include -#include -#include - #include - -#include "common/utils/QKafkaUtil.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include PhaseWindow::PhaseWindow(QWidget *parent) : QWidget(parent), @@ -18,43 +18,74 @@ { ui->setupUi(this); - QString portNames = SettingConfig::getInstance().PORT_NAMES; - int baudRate = SettingConfig::getInstance().BAUD_RATE; - QString devCodes = SettingConfig::getInstance().DEV_CODES; + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); - QStringList comDevList = portNames.split(","); - QStringList devCodeList = devCodes.split(","); + // 窗口大小为占满一屏 + QRect screenRect = QApplication::desktop()->screenGeometry(); + resize(screenRect.width(), screenRect.height()); - for (int i = 0; i < comDevList.size(); i++) + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->line->setGeometry(0, 59, screenRect.width(), 1); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 60, screenRect.width(), screenRect.height() - 60); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + + httpReq = new HttpRequestController(this); + // 1. 获取访问接口需要的token + int retCode = this->initHttpToken(); + if (retCode != 200) { - PhaseDevice * device = new PhaseDevice(this); + QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); - // - connect(device, &PhaseDevice::sendDataToDraw, - this, &PhaseWindow::drawPhaseDataOnPage); + QTimer::singleShot(1000, qApp, SLOT(quit())); + } + // 2. 获取字典值:设备类型 + retCode = this->initDictDeviceTypes(); - device->setComName(comDevList.at(i)); - device->setBaudRate(baudRate); + // 3. 获取比相仪设备列表 + QJsonObject devListRes = this->initDeviceList(); + if (devListRes.find("code")->toInt() == 200) + { + ui->devSelect->clear(); - device->setDevCode(devCodeList.at(i)); + // 4. 将获取到的设备添加到下拉列表框中 + QJsonArray devArray = devListRes.find("data")->toArray(); + for (int i = 0; i < devArray.size(); i++) + { + QJsonObject devItem = devArray.at(i).toObject(); + ui->devSelect->addItem(devItem.find("deviceName")->toString(), devItem.find("deviceNo")->toString()); - this->deviceList.append(device); + PhaseDevice * device = new PhaseDevice(this); + deviceList.append(device); - device->initSerialPort(); - device->startWork(); + device->setComName(devItem.find("linkComName")->toString()); + device->setBaudRate(SettingConfig::getInstance().BAUD_RATE); + device->setDevCode(devItem.find("deviceNo")->toString()); + device->setDeviceId(devItem.find("deviceId")->toString()); + + connect(device, &PhaseDevice::sendDataToDraw, + this, &PhaseWindow::drawPhaseDataOnPage); + + device->initSerialPort(); + + QThread::msleep(100); + } + // 5. 设置下拉框的样式 + QStandardItemModel * model = qobject_cast(ui->devSelect->model()); + for (int i = 0; i < model->rowCount(); ++i) + { + QStandardItem * item = model->item(i); + item->setSizeHint({ 0, 30 }); + } } - for (int i = 0; i < this->deviceList.size(); i++) - { - QWidget * devWidget5 = new QWidget(this->ui->stackedWidget); - - this->ui->stackedWidget->addWidget(devWidget5); - - this->devWidgetList.append(devWidget5); - - // 创建设备的widget - this->generateWidgetForDevice(devCodeList.at(i), i); - } + // 6. 绘制一个设备的多个通道数据面板 + this->generateWidgetForDevice(); } PhaseWindow::~PhaseWindow() @@ -64,99 +95,119 @@ void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) { - // 1. 判断数据属于哪个设备,显示在不同的widget上 + // 当前显示的设备编号 + QString currentDevCode = ui->devSelect->currentData().toString(); - // 2. 循环设置各个tableView - QList devChannels = this->tableModelList.at(0); // 暂时写死 - for (int i = 0; i < phaseData->channelData.size(); i++) + // 如果不是当前设备的帧,直接返回 + if (phaseData->devCode != currentDevCode) { - if (phaseData->channelActive.at(i).toInt() == 1) - { - QList row; - QStandardItem * item = 0; - QStandardItem * item2 = 0; - item = new QStandardItem(QString("%1").arg(phaseData->timestamp.mid(11, 12))); - item2 = new QStandardItem(QString("%1").arg(phaseData->channelData.at(i))); + return; + } - row.append(item); - row.append(item2); + // 更新所有通道BOX的值 + for (int i = 0; i < phaseData->channelActive.size(); i++) + { + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); - QStandardItemModel * model; - model = devChannels.at(i); - if (model->rowCount() >= 60) - { - model->removeRows(0, model->rowCount()); - } - - model->insertRow(0, row); - } + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(phaseData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelData.at(i))); + ((QLineEdit *)channelBox->children().at(6))->setText(phaseData->frameId); + ((QLabel *)channelBox->children().at(7))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); } } -void PhaseWindow::generateWidgetForDevice(QString devCode, int index) +void PhaseWindow::generateWidgetForDevice() { - // 顶部切换widget - QWidget * switchWidget = new QWidget(this->devWidgetList.at(index)); - switchWidget->setGeometry(0, 0, 1024, 50); + // 获取设备数据 + int channelNum = 16; - // 显示数据的区域 - QWidget * gridWidget = new QWidget(this->devWidgetList.at(index)); - gridWidget->setGeometry(0, 50, 1024, 670); + QRect screenRect = QApplication::desktop()->screenGeometry(); - // 顶部水平布局,用于排布按钮 - QHBoxLayout * hLayout = new QHBoxLayout(switchWidget); + ui->scrollContents->setGeometry(0, 60, screenRect.width(), channelNum * 90); - // 文本 - QLabel * label = new QLabel(switchWidget); - label->setText("设备编号:" + devCode); - label->setFont(QFont("微软雅黑", 12)); - hLayout->addWidget(label); + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); - // 按钮 - for (int i = 0; i < this->deviceList.size(); i++) + for (int i = 0; i < channelNum; i++) { - QPushButton * butt5 = new QPushButton(this->deviceList.at(i)->getDevCode()); - hLayout->addWidget(butt5); + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 80 + 10, screenRect.width() - 40, 80); - connect(butt5, &QPushButton::clicked, [=](){ - this->ui->stackedWidget->setCurrentIndex(i); - }); + QHBoxLayout * vbox = new QHBoxLayout(group); + + QLabel * tmLabel = new QLabel(); + tmLabel->setText("时间"); + tmLabel->setFont(labelFont); + tmLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(tmLabel); + QLineEdit * tmValue = new QLineEdit(); + tmValue->setFixedWidth(200); + tmValue->setFont(labelFont); + vbox->addWidget(tmValue); + + QLabel * dataLabel = new QLabel(); + dataLabel->setText("测量数据"); + dataLabel->setFont(labelFont); + dataLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(dataLabel); + QLineEdit * dataValue = new QLineEdit(); + dataValue->setFixedWidth(150); + dataValue->setFont(labelFont); + vbox->addWidget(dataValue); + + QLabel * idLabel = new QLabel(); + idLabel->setText("数据ID"); + idLabel->setFont(labelFont); + idLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(idLabel); + QLineEdit * idValue = new QLineEdit(); + idValue->setFixedWidth(100); + idValue->setFont(labelFont); + vbox->addWidget(idValue); + + QLabel * validLabel = new QLabel(); + validLabel->setText("-"); + validLabel->setFont(labelFont); + validLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(validLabel); + + QSpacerItem * hSpace = new QSpacerItem(20, 20); + hSpace->changeSize(20, 20, QSizePolicy::Expanding); + vbox->addItem(hSpace); + + group->setLayout(vbox); + + layout->addWidget(group); } - - // Grid布局 - QGridLayout * gridLayout = new QGridLayout(gridWidget); - gridLayout->setSpacing(10); - - QList channelModelList; - QStringList labels = QObject::trUtf8("时间,相差").simplified().split(","); - - for (int i = 0; i < 16; i++) - { - QTableView * channelTable = new QTableView(gridWidget); - QStandardItemModel * model = new QStandardItemModel(channelTable); - - model->setHorizontalHeaderLabels(labels); - - channelTable->setModel(model); - - gridLayout->addWidget(channelTable, i / 4, i % 4); - - channelTable->verticalHeader()->hide(); - channelTable->setEditTriggers(QAbstractItemView::NoEditTriggers); - channelTable->scrollToBottom(); - - channelModelList.append(model); - } - - this->tableModelList.append(channelModelList); } -void PhaseWindow::createKafkaMessage() +int PhaseWindow::initHttpToken() { - this->kafkaUtil = new QKafkaUtil(this); - this->kafkaUtil->setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); - this->kafkaUtil->setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int PhaseWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject PhaseWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("比相仪"); + return response; +} - kafkaUtil->createProducer(); - kafkaUtil->produceMessage("hello world kafka kylin"); +void PhaseWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} + +void PhaseWindow::on_exitButt_clicked() +{ + QApplication::exit(0); } diff --git a/PhaseCompAcq/PhaseWindow.h b/PhaseCompAcq/PhaseWindow.h index 67b8363..02a7908 100644 --- a/PhaseCompAcq/PhaseWindow.h +++ b/PhaseCompAcq/PhaseWindow.h @@ -2,11 +2,13 @@ #define PHASEWINDOW_H #include +#include #include +#include #include "PhaseDevice.h" #include "common/utils/SettingConfig.h" -#include "common/utils/QKafkaUtil.h" +#include "common/HttpRequestController.h" namespace Ui { class PhaseWindow; @@ -23,18 +25,23 @@ public slots: void drawPhaseDataOnPage(PhaseDataDto * phaseData); +private slots: + void on_minButt_clicked(); + + void on_exitButt_clicked(); + private: + int initHttpToken(); + int initDictDeviceTypes(); + QJsonObject initDeviceList(); + Ui::PhaseWindow *ui; - QList devWidgetList; + HttpRequestController * httpReq; QList deviceList; - QList> tableModelList; - QKafkaUtil * kafkaUtil; - - void generateWidgetForDevice(QString devCode, int index); - void createKafkaMessage(); + void generateWidgetForDevice(); }; #endif // PHASEWINDOW_H diff --git a/PhaseCompAcq/PhaseWindow.ui b/PhaseCompAcq/PhaseWindow.ui index e6da880..01a7759 100644 --- a/PhaseCompAcq/PhaseWindow.ui +++ b/PhaseCompAcq/PhaseWindow.ui @@ -10,26 +10,144 @@ 720 - - - 1024 - 720 - - 多通道比相仪数据采集 - + 0 0 - 1024 - 720 + 100 + 30 - - -1 + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 100 + 30 + + + + + + + + 400 + 10 + 250 + 40 + + + + + + + 250 + 0 + 150 + 60 + + + + + 微软雅黑 + 12 + + + + Qt::LeftToRight + + + 请选择比相仪 + + + Qt::AlignCenter + + + + + + 880 + 10 + 40 + 40 + + + + + + + 退出 + + + + + + 20 + 0 + 200 + 60 + + + + + 微软雅黑 + 14 + + + + 多通道比相仪数据采集 + + + + + + 0 + 59 + 1024 + 1 + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + 830 + 10 + 40 + 40 + + + + + + + 最小化 diff --git a/PhaseCompAcq/common/ConstCache.h b/PhaseCompAcq/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/PhaseCompAcq/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/PhaseCompAcq/common/HttpRequestController.cpp b/PhaseCompAcq/common/HttpRequestController.cpp new file mode 100644 index 0000000..6abb5af --- /dev/null +++ b/PhaseCompAcq/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceTypes.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDeviceList(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", system.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); + } + + qDebug() << resultObj; + + return resultObj; +} diff --git a/PhaseCompAcq/common/HttpRequestController.h b/PhaseCompAcq/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/PhaseCompAcq/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/CounterAcq/CounterAcq.pro b/CounterAcq/CounterAcq.pro index 72407cd..fae9d10 100644 --- a/CounterAcq/CounterAcq.pro +++ b/CounterAcq/CounterAcq.pro @@ -4,13 +4,6 @@ CONFIG += c++11 -SOURCES += \ - CounterWindow.cpp \ - main.cpp \ - -HEADERS += \ - CounterWindow.h \ - FORMS += \ CounterWindow.ui \ @@ -18,8 +11,11 @@ include(protocol/protocol.pri) HEADERS += CounterDevice.h +HEADERS += CounterWindow.h SOURCES += CounterDevice.cpp +SOURCES += CounterWindow.cpp +SOURCES += main.cpp DISTFILES += conf/config.ini diff --git a/CounterAcq/CounterWindow.cpp b/CounterAcq/CounterWindow.cpp index 80035a9..a50ebcf 100644 --- a/CounterAcq/CounterWindow.cpp +++ b/CounterAcq/CounterWindow.cpp @@ -42,7 +42,7 @@ { QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); - QApplication::exit(0); + QTimer::singleShot(1000, qApp, SLOT(quit())); } // 2. 获取字典值:设备类型 retCode = this->initDictDeviceTypes(); diff --git a/CounterAcq/CounterWindow.h b/CounterAcq/CounterWindow.h index 8d5e4a6..09277ba 100644 --- a/CounterAcq/CounterWindow.h +++ b/CounterAcq/CounterWindow.h @@ -7,7 +7,6 @@ #include #include "common/utils/SettingConfig.h" -#include "common/utils/QKafkaUtil.h" #include "common/HttpRequestController.h" #include "CounterDevice.h" @@ -23,8 +22,6 @@ explicit CounterWindow(QWidget *parent = nullptr); ~CounterWindow(); - QString token; - public slots: void drawCounterDataOnPage(CounterDataDto * counterData); @@ -40,7 +37,6 @@ Ui::CounterWindow *ui; - QTimer * timer; HttpRequestController * httpReq; QList deviceList; diff --git a/PhaseCompAcq/PhaseCompAcq.pro b/PhaseCompAcq/PhaseCompAcq.pro index 5eef2d1..c5e895b 100644 --- a/PhaseCompAcq/PhaseCompAcq.pro +++ b/PhaseCompAcq/PhaseCompAcq.pro @@ -1,16 +1,9 @@ -QT += core gui serialport +QT += core gui serialport network greaterThan(QT_MAJOR_VERSION, 4): QT += widgets CONFIG += c++11 -SOURCES += \ - main.cpp \ - PhaseWindow.cpp - -HEADERS += \ - PhaseWindow.h - FORMS += \ PhaseWindow.ui @@ -18,20 +11,19 @@ include(protocol/protocol.pri) HEADERS += PhaseDevice.h -#HEADERS += PhaseSerialServer.h +HEADERS += PhaseWindow.h SOURCES += PhaseDevice.cpp -#SOURCES += PhaseSerialServer.cpp +SOURCES += PhaseWindow.cpp +SOURCES += main.cpp # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target - -INCLUDEPATH += $$PWD/include/librdkafka -DEPENDPATH += $$PWD/include/librdkafka +#unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +#INCLUDEPATH += $$PWD/include/librdkafka +#DEPENDPATH += $$PWD/include/librdkafka DISTFILES += conf/config.ini - -unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ diff --git a/PhaseCompAcq/PhaseDevice.cpp b/PhaseCompAcq/PhaseDevice.cpp index 5c84cd5..afc2687 100644 --- a/PhaseCompAcq/PhaseDevice.cpp +++ b/PhaseCompAcq/PhaseDevice.cpp @@ -7,9 +7,9 @@ connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, this, &PhaseDevice::dataReceivedHandler); - kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); - kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); - kafkaUtil.createProducer(); +// kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); +// kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); +// kafkaUtil.createProducer(); } PhaseDevice::~PhaseDevice() @@ -34,6 +34,10 @@ { this->devCode = devCode; } +void PhaseDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} bool PhaseDevice::isSerialOpen() { @@ -74,6 +78,7 @@ if (parse == true) { QDateTime now = QDateTime::currentDateTime(); + phaseData->devCode = this->devCode; phaseData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); phaseData->milisecond = now.toMSecsSinceEpoch(); this->afterFramePhase(phaseData); @@ -92,21 +97,20 @@ this->dataBuff.clear(); // 2. 输出到日志文件中 - QString filePostfix = phaseData->timestamp.mid(0, 13).replace(" ", "_"); - QString filePrefix = QApplication::applicationDirPath() + "/logs/"; + QString date = phaseData->timestamp.mid(0, 10); // 2.1 原始字节数组数据 - QString filename = filePrefix + "raw_" + filePostfix + ".log"; + QString filename = "raw_" + devCode + ".log"; QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); - QLogUtil::writeRawDataLog(filename, content); + QLogUtil::writeRawDataLogByDate(date, filename, content); // 2.2 各个通道的相差数据 for (int i = 1; i <= phaseData->channelActive.size(); i++) { if (phaseData->channelActive.at(i-1).toUInt() == 1) { - QString chFilename("%1CH_%2_%3.log"); - chFilename = chFilename.arg(filePrefix); + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); if (i < 10) { chFilename = chFilename.arg(QString("0%1").arg(i)); @@ -114,10 +118,9 @@ { chFilename = chFilename.arg(i); } - chFilename = chFilename.arg(filePostfix); - QString channelDataStr = QString("%1 %2 %3").arg(phaseData->timestamp).arg(phaseData->channelData.at(i-1)).arg(phaseData->frameId); + QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelData.at(i-1)); - QLogUtil::writeChannelDataLog(chFilename, channelDataStr); + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); // 3. 输出到中间件,执行后续处理过程 if (SettingConfig::getInstance().NEED_KAFKA == 1) @@ -125,7 +128,7 @@ QJsonObject jsonObj = phaseData->toJSON(i - 1); jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); jsonObj.insert("deviceId", devCode); - kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); +// kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); } } } diff --git a/PhaseCompAcq/PhaseDevice.h b/PhaseCompAcq/PhaseDevice.h index 92182d4..aa7d822 100644 --- a/PhaseCompAcq/PhaseDevice.h +++ b/PhaseCompAcq/PhaseDevice.h @@ -5,7 +5,7 @@ #include "common/utils/QSerialPortUtil.h" #include "common/utils/QLogUtil.h" #include "common/utils/SettingConfig.h" -#include "common/utils/QKafkaUtil.h" +//#include "common/utils/QKafkaUtil.h" #include "protocol/PhaseProtocolBM.h" class PhaseDevice : public QObject @@ -25,15 +25,17 @@ void setBaudRate(int baudRate); QString getDevCode(); void setDevCode(QString devCode); + void setDeviceId(QString deviceId); bool isSerialOpen(); private: + QString deviceId; QString devCode; QString comName; int baudRate; QSerialPortUtil serialUtil; - QKafkaUtil kafkaUtil; +// QKafkaUtil kafkaUtil; QByteArray dataBuff; signals: diff --git a/PhaseCompAcq/PhaseWindow.cpp b/PhaseCompAcq/PhaseWindow.cpp index b3cab89..d0e8221 100644 --- a/PhaseCompAcq/PhaseWindow.cpp +++ b/PhaseCompAcq/PhaseWindow.cpp @@ -1,16 +1,16 @@ #include "PhaseWindow.h" #include "ui_PhaseWindow.h" -#include -#include -#include -#include -#include -#include - #include - -#include "common/utils/QKafkaUtil.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include PhaseWindow::PhaseWindow(QWidget *parent) : QWidget(parent), @@ -18,43 +18,74 @@ { ui->setupUi(this); - QString portNames = SettingConfig::getInstance().PORT_NAMES; - int baudRate = SettingConfig::getInstance().BAUD_RATE; - QString devCodes = SettingConfig::getInstance().DEV_CODES; + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); - QStringList comDevList = portNames.split(","); - QStringList devCodeList = devCodes.split(","); + // 窗口大小为占满一屏 + QRect screenRect = QApplication::desktop()->screenGeometry(); + resize(screenRect.width(), screenRect.height()); - for (int i = 0; i < comDevList.size(); i++) + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->line->setGeometry(0, 59, screenRect.width(), 1); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 60, screenRect.width(), screenRect.height() - 60); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + + httpReq = new HttpRequestController(this); + // 1. 获取访问接口需要的token + int retCode = this->initHttpToken(); + if (retCode != 200) { - PhaseDevice * device = new PhaseDevice(this); + QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); - // - connect(device, &PhaseDevice::sendDataToDraw, - this, &PhaseWindow::drawPhaseDataOnPage); + QTimer::singleShot(1000, qApp, SLOT(quit())); + } + // 2. 获取字典值:设备类型 + retCode = this->initDictDeviceTypes(); - device->setComName(comDevList.at(i)); - device->setBaudRate(baudRate); + // 3. 获取比相仪设备列表 + QJsonObject devListRes = this->initDeviceList(); + if (devListRes.find("code")->toInt() == 200) + { + ui->devSelect->clear(); - device->setDevCode(devCodeList.at(i)); + // 4. 将获取到的设备添加到下拉列表框中 + QJsonArray devArray = devListRes.find("data")->toArray(); + for (int i = 0; i < devArray.size(); i++) + { + QJsonObject devItem = devArray.at(i).toObject(); + ui->devSelect->addItem(devItem.find("deviceName")->toString(), devItem.find("deviceNo")->toString()); - this->deviceList.append(device); + PhaseDevice * device = new PhaseDevice(this); + deviceList.append(device); - device->initSerialPort(); - device->startWork(); + device->setComName(devItem.find("linkComName")->toString()); + device->setBaudRate(SettingConfig::getInstance().BAUD_RATE); + device->setDevCode(devItem.find("deviceNo")->toString()); + device->setDeviceId(devItem.find("deviceId")->toString()); + + connect(device, &PhaseDevice::sendDataToDraw, + this, &PhaseWindow::drawPhaseDataOnPage); + + device->initSerialPort(); + + QThread::msleep(100); + } + // 5. 设置下拉框的样式 + QStandardItemModel * model = qobject_cast(ui->devSelect->model()); + for (int i = 0; i < model->rowCount(); ++i) + { + QStandardItem * item = model->item(i); + item->setSizeHint({ 0, 30 }); + } } - for (int i = 0; i < this->deviceList.size(); i++) - { - QWidget * devWidget5 = new QWidget(this->ui->stackedWidget); - - this->ui->stackedWidget->addWidget(devWidget5); - - this->devWidgetList.append(devWidget5); - - // 创建设备的widget - this->generateWidgetForDevice(devCodeList.at(i), i); - } + // 6. 绘制一个设备的多个通道数据面板 + this->generateWidgetForDevice(); } PhaseWindow::~PhaseWindow() @@ -64,99 +95,119 @@ void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) { - // 1. 判断数据属于哪个设备,显示在不同的widget上 + // 当前显示的设备编号 + QString currentDevCode = ui->devSelect->currentData().toString(); - // 2. 循环设置各个tableView - QList devChannels = this->tableModelList.at(0); // 暂时写死 - for (int i = 0; i < phaseData->channelData.size(); i++) + // 如果不是当前设备的帧,直接返回 + if (phaseData->devCode != currentDevCode) { - if (phaseData->channelActive.at(i).toInt() == 1) - { - QList row; - QStandardItem * item = 0; - QStandardItem * item2 = 0; - item = new QStandardItem(QString("%1").arg(phaseData->timestamp.mid(11, 12))); - item2 = new QStandardItem(QString("%1").arg(phaseData->channelData.at(i))); + return; + } - row.append(item); - row.append(item2); + // 更新所有通道BOX的值 + for (int i = 0; i < phaseData->channelActive.size(); i++) + { + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); - QStandardItemModel * model; - model = devChannels.at(i); - if (model->rowCount() >= 60) - { - model->removeRows(0, model->rowCount()); - } - - model->insertRow(0, row); - } + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(phaseData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelData.at(i))); + ((QLineEdit *)channelBox->children().at(6))->setText(phaseData->frameId); + ((QLabel *)channelBox->children().at(7))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); } } -void PhaseWindow::generateWidgetForDevice(QString devCode, int index) +void PhaseWindow::generateWidgetForDevice() { - // 顶部切换widget - QWidget * switchWidget = new QWidget(this->devWidgetList.at(index)); - switchWidget->setGeometry(0, 0, 1024, 50); + // 获取设备数据 + int channelNum = 16; - // 显示数据的区域 - QWidget * gridWidget = new QWidget(this->devWidgetList.at(index)); - gridWidget->setGeometry(0, 50, 1024, 670); + QRect screenRect = QApplication::desktop()->screenGeometry(); - // 顶部水平布局,用于排布按钮 - QHBoxLayout * hLayout = new QHBoxLayout(switchWidget); + ui->scrollContents->setGeometry(0, 60, screenRect.width(), channelNum * 90); - // 文本 - QLabel * label = new QLabel(switchWidget); - label->setText("设备编号:" + devCode); - label->setFont(QFont("微软雅黑", 12)); - hLayout->addWidget(label); + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); - // 按钮 - for (int i = 0; i < this->deviceList.size(); i++) + for (int i = 0; i < channelNum; i++) { - QPushButton * butt5 = new QPushButton(this->deviceList.at(i)->getDevCode()); - hLayout->addWidget(butt5); + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 80 + 10, screenRect.width() - 40, 80); - connect(butt5, &QPushButton::clicked, [=](){ - this->ui->stackedWidget->setCurrentIndex(i); - }); + QHBoxLayout * vbox = new QHBoxLayout(group); + + QLabel * tmLabel = new QLabel(); + tmLabel->setText("时间"); + tmLabel->setFont(labelFont); + tmLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(tmLabel); + QLineEdit * tmValue = new QLineEdit(); + tmValue->setFixedWidth(200); + tmValue->setFont(labelFont); + vbox->addWidget(tmValue); + + QLabel * dataLabel = new QLabel(); + dataLabel->setText("测量数据"); + dataLabel->setFont(labelFont); + dataLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(dataLabel); + QLineEdit * dataValue = new QLineEdit(); + dataValue->setFixedWidth(150); + dataValue->setFont(labelFont); + vbox->addWidget(dataValue); + + QLabel * idLabel = new QLabel(); + idLabel->setText("数据ID"); + idLabel->setFont(labelFont); + idLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(idLabel); + QLineEdit * idValue = new QLineEdit(); + idValue->setFixedWidth(100); + idValue->setFont(labelFont); + vbox->addWidget(idValue); + + QLabel * validLabel = new QLabel(); + validLabel->setText("-"); + validLabel->setFont(labelFont); + validLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(validLabel); + + QSpacerItem * hSpace = new QSpacerItem(20, 20); + hSpace->changeSize(20, 20, QSizePolicy::Expanding); + vbox->addItem(hSpace); + + group->setLayout(vbox); + + layout->addWidget(group); } - - // Grid布局 - QGridLayout * gridLayout = new QGridLayout(gridWidget); - gridLayout->setSpacing(10); - - QList channelModelList; - QStringList labels = QObject::trUtf8("时间,相差").simplified().split(","); - - for (int i = 0; i < 16; i++) - { - QTableView * channelTable = new QTableView(gridWidget); - QStandardItemModel * model = new QStandardItemModel(channelTable); - - model->setHorizontalHeaderLabels(labels); - - channelTable->setModel(model); - - gridLayout->addWidget(channelTable, i / 4, i % 4); - - channelTable->verticalHeader()->hide(); - channelTable->setEditTriggers(QAbstractItemView::NoEditTriggers); - channelTable->scrollToBottom(); - - channelModelList.append(model); - } - - this->tableModelList.append(channelModelList); } -void PhaseWindow::createKafkaMessage() +int PhaseWindow::initHttpToken() { - this->kafkaUtil = new QKafkaUtil(this); - this->kafkaUtil->setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); - this->kafkaUtil->setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int PhaseWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject PhaseWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("比相仪"); + return response; +} - kafkaUtil->createProducer(); - kafkaUtil->produceMessage("hello world kafka kylin"); +void PhaseWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} + +void PhaseWindow::on_exitButt_clicked() +{ + QApplication::exit(0); } diff --git a/PhaseCompAcq/PhaseWindow.h b/PhaseCompAcq/PhaseWindow.h index 67b8363..02a7908 100644 --- a/PhaseCompAcq/PhaseWindow.h +++ b/PhaseCompAcq/PhaseWindow.h @@ -2,11 +2,13 @@ #define PHASEWINDOW_H #include +#include #include +#include #include "PhaseDevice.h" #include "common/utils/SettingConfig.h" -#include "common/utils/QKafkaUtil.h" +#include "common/HttpRequestController.h" namespace Ui { class PhaseWindow; @@ -23,18 +25,23 @@ public slots: void drawPhaseDataOnPage(PhaseDataDto * phaseData); +private slots: + void on_minButt_clicked(); + + void on_exitButt_clicked(); + private: + int initHttpToken(); + int initDictDeviceTypes(); + QJsonObject initDeviceList(); + Ui::PhaseWindow *ui; - QList devWidgetList; + HttpRequestController * httpReq; QList deviceList; - QList> tableModelList; - QKafkaUtil * kafkaUtil; - - void generateWidgetForDevice(QString devCode, int index); - void createKafkaMessage(); + void generateWidgetForDevice(); }; #endif // PHASEWINDOW_H diff --git a/PhaseCompAcq/PhaseWindow.ui b/PhaseCompAcq/PhaseWindow.ui index e6da880..01a7759 100644 --- a/PhaseCompAcq/PhaseWindow.ui +++ b/PhaseCompAcq/PhaseWindow.ui @@ -10,26 +10,144 @@ 720 - - - 1024 - 720 - - 多通道比相仪数据采集 - + 0 0 - 1024 - 720 + 100 + 30 - - -1 + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 100 + 30 + + + + + + + + 400 + 10 + 250 + 40 + + + + + + + 250 + 0 + 150 + 60 + + + + + 微软雅黑 + 12 + + + + Qt::LeftToRight + + + 请选择比相仪 + + + Qt::AlignCenter + + + + + + 880 + 10 + 40 + 40 + + + + + + + 退出 + + + + + + 20 + 0 + 200 + 60 + + + + + 微软雅黑 + 14 + + + + 多通道比相仪数据采集 + + + + + + 0 + 59 + 1024 + 1 + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + 830 + 10 + 40 + 40 + + + + + + + 最小化 diff --git a/PhaseCompAcq/common/ConstCache.h b/PhaseCompAcq/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/PhaseCompAcq/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/PhaseCompAcq/common/HttpRequestController.cpp b/PhaseCompAcq/common/HttpRequestController.cpp new file mode 100644 index 0000000..6abb5af --- /dev/null +++ b/PhaseCompAcq/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceTypes.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDeviceList(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", system.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); + } + + qDebug() << resultObj; + + return resultObj; +} diff --git a/PhaseCompAcq/common/HttpRequestController.h b/PhaseCompAcq/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/PhaseCompAcq/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/PhaseCompAcq/common/common.pri b/PhaseCompAcq/common/common.pri index 055a2db..84f57ae 100644 --- a/PhaseCompAcq/common/common.pri +++ b/PhaseCompAcq/common/common.pri @@ -3,10 +3,18 @@ SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp -SOURCES += $$PWD/utils/QKafkaUtil.cpp +#SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp HEADERS += $$PWD/utils/SettingConfig.h HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h -HEADERS += $$PWD/utils/QKafkaUtil.h +#HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/CounterAcq/CounterAcq.pro b/CounterAcq/CounterAcq.pro index 72407cd..fae9d10 100644 --- a/CounterAcq/CounterAcq.pro +++ b/CounterAcq/CounterAcq.pro @@ -4,13 +4,6 @@ CONFIG += c++11 -SOURCES += \ - CounterWindow.cpp \ - main.cpp \ - -HEADERS += \ - CounterWindow.h \ - FORMS += \ CounterWindow.ui \ @@ -18,8 +11,11 @@ include(protocol/protocol.pri) HEADERS += CounterDevice.h +HEADERS += CounterWindow.h SOURCES += CounterDevice.cpp +SOURCES += CounterWindow.cpp +SOURCES += main.cpp DISTFILES += conf/config.ini diff --git a/CounterAcq/CounterWindow.cpp b/CounterAcq/CounterWindow.cpp index 80035a9..a50ebcf 100644 --- a/CounterAcq/CounterWindow.cpp +++ b/CounterAcq/CounterWindow.cpp @@ -42,7 +42,7 @@ { QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); - QApplication::exit(0); + QTimer::singleShot(1000, qApp, SLOT(quit())); } // 2. 获取字典值:设备类型 retCode = this->initDictDeviceTypes(); diff --git a/CounterAcq/CounterWindow.h b/CounterAcq/CounterWindow.h index 8d5e4a6..09277ba 100644 --- a/CounterAcq/CounterWindow.h +++ b/CounterAcq/CounterWindow.h @@ -7,7 +7,6 @@ #include #include "common/utils/SettingConfig.h" -#include "common/utils/QKafkaUtil.h" #include "common/HttpRequestController.h" #include "CounterDevice.h" @@ -23,8 +22,6 @@ explicit CounterWindow(QWidget *parent = nullptr); ~CounterWindow(); - QString token; - public slots: void drawCounterDataOnPage(CounterDataDto * counterData); @@ -40,7 +37,6 @@ Ui::CounterWindow *ui; - QTimer * timer; HttpRequestController * httpReq; QList deviceList; diff --git a/PhaseCompAcq/PhaseCompAcq.pro b/PhaseCompAcq/PhaseCompAcq.pro index 5eef2d1..c5e895b 100644 --- a/PhaseCompAcq/PhaseCompAcq.pro +++ b/PhaseCompAcq/PhaseCompAcq.pro @@ -1,16 +1,9 @@ -QT += core gui serialport +QT += core gui serialport network greaterThan(QT_MAJOR_VERSION, 4): QT += widgets CONFIG += c++11 -SOURCES += \ - main.cpp \ - PhaseWindow.cpp - -HEADERS += \ - PhaseWindow.h - FORMS += \ PhaseWindow.ui @@ -18,20 +11,19 @@ include(protocol/protocol.pri) HEADERS += PhaseDevice.h -#HEADERS += PhaseSerialServer.h +HEADERS += PhaseWindow.h SOURCES += PhaseDevice.cpp -#SOURCES += PhaseSerialServer.cpp +SOURCES += PhaseWindow.cpp +SOURCES += main.cpp # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target - -INCLUDEPATH += $$PWD/include/librdkafka -DEPENDPATH += $$PWD/include/librdkafka +#unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +#INCLUDEPATH += $$PWD/include/librdkafka +#DEPENDPATH += $$PWD/include/librdkafka DISTFILES += conf/config.ini - -unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ diff --git a/PhaseCompAcq/PhaseDevice.cpp b/PhaseCompAcq/PhaseDevice.cpp index 5c84cd5..afc2687 100644 --- a/PhaseCompAcq/PhaseDevice.cpp +++ b/PhaseCompAcq/PhaseDevice.cpp @@ -7,9 +7,9 @@ connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, this, &PhaseDevice::dataReceivedHandler); - kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); - kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); - kafkaUtil.createProducer(); +// kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); +// kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); +// kafkaUtil.createProducer(); } PhaseDevice::~PhaseDevice() @@ -34,6 +34,10 @@ { this->devCode = devCode; } +void PhaseDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} bool PhaseDevice::isSerialOpen() { @@ -74,6 +78,7 @@ if (parse == true) { QDateTime now = QDateTime::currentDateTime(); + phaseData->devCode = this->devCode; phaseData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); phaseData->milisecond = now.toMSecsSinceEpoch(); this->afterFramePhase(phaseData); @@ -92,21 +97,20 @@ this->dataBuff.clear(); // 2. 输出到日志文件中 - QString filePostfix = phaseData->timestamp.mid(0, 13).replace(" ", "_"); - QString filePrefix = QApplication::applicationDirPath() + "/logs/"; + QString date = phaseData->timestamp.mid(0, 10); // 2.1 原始字节数组数据 - QString filename = filePrefix + "raw_" + filePostfix + ".log"; + QString filename = "raw_" + devCode + ".log"; QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); - QLogUtil::writeRawDataLog(filename, content); + QLogUtil::writeRawDataLogByDate(date, filename, content); // 2.2 各个通道的相差数据 for (int i = 1; i <= phaseData->channelActive.size(); i++) { if (phaseData->channelActive.at(i-1).toUInt() == 1) { - QString chFilename("%1CH_%2_%3.log"); - chFilename = chFilename.arg(filePrefix); + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); if (i < 10) { chFilename = chFilename.arg(QString("0%1").arg(i)); @@ -114,10 +118,9 @@ { chFilename = chFilename.arg(i); } - chFilename = chFilename.arg(filePostfix); - QString channelDataStr = QString("%1 %2 %3").arg(phaseData->timestamp).arg(phaseData->channelData.at(i-1)).arg(phaseData->frameId); + QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelData.at(i-1)); - QLogUtil::writeChannelDataLog(chFilename, channelDataStr); + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); // 3. 输出到中间件,执行后续处理过程 if (SettingConfig::getInstance().NEED_KAFKA == 1) @@ -125,7 +128,7 @@ QJsonObject jsonObj = phaseData->toJSON(i - 1); jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); jsonObj.insert("deviceId", devCode); - kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); +// kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); } } } diff --git a/PhaseCompAcq/PhaseDevice.h b/PhaseCompAcq/PhaseDevice.h index 92182d4..aa7d822 100644 --- a/PhaseCompAcq/PhaseDevice.h +++ b/PhaseCompAcq/PhaseDevice.h @@ -5,7 +5,7 @@ #include "common/utils/QSerialPortUtil.h" #include "common/utils/QLogUtil.h" #include "common/utils/SettingConfig.h" -#include "common/utils/QKafkaUtil.h" +//#include "common/utils/QKafkaUtil.h" #include "protocol/PhaseProtocolBM.h" class PhaseDevice : public QObject @@ -25,15 +25,17 @@ void setBaudRate(int baudRate); QString getDevCode(); void setDevCode(QString devCode); + void setDeviceId(QString deviceId); bool isSerialOpen(); private: + QString deviceId; QString devCode; QString comName; int baudRate; QSerialPortUtil serialUtil; - QKafkaUtil kafkaUtil; +// QKafkaUtil kafkaUtil; QByteArray dataBuff; signals: diff --git a/PhaseCompAcq/PhaseWindow.cpp b/PhaseCompAcq/PhaseWindow.cpp index b3cab89..d0e8221 100644 --- a/PhaseCompAcq/PhaseWindow.cpp +++ b/PhaseCompAcq/PhaseWindow.cpp @@ -1,16 +1,16 @@ #include "PhaseWindow.h" #include "ui_PhaseWindow.h" -#include -#include -#include -#include -#include -#include - #include - -#include "common/utils/QKafkaUtil.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include PhaseWindow::PhaseWindow(QWidget *parent) : QWidget(parent), @@ -18,43 +18,74 @@ { ui->setupUi(this); - QString portNames = SettingConfig::getInstance().PORT_NAMES; - int baudRate = SettingConfig::getInstance().BAUD_RATE; - QString devCodes = SettingConfig::getInstance().DEV_CODES; + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); - QStringList comDevList = portNames.split(","); - QStringList devCodeList = devCodes.split(","); + // 窗口大小为占满一屏 + QRect screenRect = QApplication::desktop()->screenGeometry(); + resize(screenRect.width(), screenRect.height()); - for (int i = 0; i < comDevList.size(); i++) + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->line->setGeometry(0, 59, screenRect.width(), 1); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 60, screenRect.width(), screenRect.height() - 60); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + + httpReq = new HttpRequestController(this); + // 1. 获取访问接口需要的token + int retCode = this->initHttpToken(); + if (retCode != 200) { - PhaseDevice * device = new PhaseDevice(this); + QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); - // - connect(device, &PhaseDevice::sendDataToDraw, - this, &PhaseWindow::drawPhaseDataOnPage); + QTimer::singleShot(1000, qApp, SLOT(quit())); + } + // 2. 获取字典值:设备类型 + retCode = this->initDictDeviceTypes(); - device->setComName(comDevList.at(i)); - device->setBaudRate(baudRate); + // 3. 获取比相仪设备列表 + QJsonObject devListRes = this->initDeviceList(); + if (devListRes.find("code")->toInt() == 200) + { + ui->devSelect->clear(); - device->setDevCode(devCodeList.at(i)); + // 4. 将获取到的设备添加到下拉列表框中 + QJsonArray devArray = devListRes.find("data")->toArray(); + for (int i = 0; i < devArray.size(); i++) + { + QJsonObject devItem = devArray.at(i).toObject(); + ui->devSelect->addItem(devItem.find("deviceName")->toString(), devItem.find("deviceNo")->toString()); - this->deviceList.append(device); + PhaseDevice * device = new PhaseDevice(this); + deviceList.append(device); - device->initSerialPort(); - device->startWork(); + device->setComName(devItem.find("linkComName")->toString()); + device->setBaudRate(SettingConfig::getInstance().BAUD_RATE); + device->setDevCode(devItem.find("deviceNo")->toString()); + device->setDeviceId(devItem.find("deviceId")->toString()); + + connect(device, &PhaseDevice::sendDataToDraw, + this, &PhaseWindow::drawPhaseDataOnPage); + + device->initSerialPort(); + + QThread::msleep(100); + } + // 5. 设置下拉框的样式 + QStandardItemModel * model = qobject_cast(ui->devSelect->model()); + for (int i = 0; i < model->rowCount(); ++i) + { + QStandardItem * item = model->item(i); + item->setSizeHint({ 0, 30 }); + } } - for (int i = 0; i < this->deviceList.size(); i++) - { - QWidget * devWidget5 = new QWidget(this->ui->stackedWidget); - - this->ui->stackedWidget->addWidget(devWidget5); - - this->devWidgetList.append(devWidget5); - - // 创建设备的widget - this->generateWidgetForDevice(devCodeList.at(i), i); - } + // 6. 绘制一个设备的多个通道数据面板 + this->generateWidgetForDevice(); } PhaseWindow::~PhaseWindow() @@ -64,99 +95,119 @@ void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) { - // 1. 判断数据属于哪个设备,显示在不同的widget上 + // 当前显示的设备编号 + QString currentDevCode = ui->devSelect->currentData().toString(); - // 2. 循环设置各个tableView - QList devChannels = this->tableModelList.at(0); // 暂时写死 - for (int i = 0; i < phaseData->channelData.size(); i++) + // 如果不是当前设备的帧,直接返回 + if (phaseData->devCode != currentDevCode) { - if (phaseData->channelActive.at(i).toInt() == 1) - { - QList row; - QStandardItem * item = 0; - QStandardItem * item2 = 0; - item = new QStandardItem(QString("%1").arg(phaseData->timestamp.mid(11, 12))); - item2 = new QStandardItem(QString("%1").arg(phaseData->channelData.at(i))); + return; + } - row.append(item); - row.append(item2); + // 更新所有通道BOX的值 + for (int i = 0; i < phaseData->channelActive.size(); i++) + { + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); - QStandardItemModel * model; - model = devChannels.at(i); - if (model->rowCount() >= 60) - { - model->removeRows(0, model->rowCount()); - } - - model->insertRow(0, row); - } + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(phaseData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelData.at(i))); + ((QLineEdit *)channelBox->children().at(6))->setText(phaseData->frameId); + ((QLabel *)channelBox->children().at(7))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); } } -void PhaseWindow::generateWidgetForDevice(QString devCode, int index) +void PhaseWindow::generateWidgetForDevice() { - // 顶部切换widget - QWidget * switchWidget = new QWidget(this->devWidgetList.at(index)); - switchWidget->setGeometry(0, 0, 1024, 50); + // 获取设备数据 + int channelNum = 16; - // 显示数据的区域 - QWidget * gridWidget = new QWidget(this->devWidgetList.at(index)); - gridWidget->setGeometry(0, 50, 1024, 670); + QRect screenRect = QApplication::desktop()->screenGeometry(); - // 顶部水平布局,用于排布按钮 - QHBoxLayout * hLayout = new QHBoxLayout(switchWidget); + ui->scrollContents->setGeometry(0, 60, screenRect.width(), channelNum * 90); - // 文本 - QLabel * label = new QLabel(switchWidget); - label->setText("设备编号:" + devCode); - label->setFont(QFont("微软雅黑", 12)); - hLayout->addWidget(label); + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); - // 按钮 - for (int i = 0; i < this->deviceList.size(); i++) + for (int i = 0; i < channelNum; i++) { - QPushButton * butt5 = new QPushButton(this->deviceList.at(i)->getDevCode()); - hLayout->addWidget(butt5); + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 80 + 10, screenRect.width() - 40, 80); - connect(butt5, &QPushButton::clicked, [=](){ - this->ui->stackedWidget->setCurrentIndex(i); - }); + QHBoxLayout * vbox = new QHBoxLayout(group); + + QLabel * tmLabel = new QLabel(); + tmLabel->setText("时间"); + tmLabel->setFont(labelFont); + tmLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(tmLabel); + QLineEdit * tmValue = new QLineEdit(); + tmValue->setFixedWidth(200); + tmValue->setFont(labelFont); + vbox->addWidget(tmValue); + + QLabel * dataLabel = new QLabel(); + dataLabel->setText("测量数据"); + dataLabel->setFont(labelFont); + dataLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(dataLabel); + QLineEdit * dataValue = new QLineEdit(); + dataValue->setFixedWidth(150); + dataValue->setFont(labelFont); + vbox->addWidget(dataValue); + + QLabel * idLabel = new QLabel(); + idLabel->setText("数据ID"); + idLabel->setFont(labelFont); + idLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(idLabel); + QLineEdit * idValue = new QLineEdit(); + idValue->setFixedWidth(100); + idValue->setFont(labelFont); + vbox->addWidget(idValue); + + QLabel * validLabel = new QLabel(); + validLabel->setText("-"); + validLabel->setFont(labelFont); + validLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(validLabel); + + QSpacerItem * hSpace = new QSpacerItem(20, 20); + hSpace->changeSize(20, 20, QSizePolicy::Expanding); + vbox->addItem(hSpace); + + group->setLayout(vbox); + + layout->addWidget(group); } - - // Grid布局 - QGridLayout * gridLayout = new QGridLayout(gridWidget); - gridLayout->setSpacing(10); - - QList channelModelList; - QStringList labels = QObject::trUtf8("时间,相差").simplified().split(","); - - for (int i = 0; i < 16; i++) - { - QTableView * channelTable = new QTableView(gridWidget); - QStandardItemModel * model = new QStandardItemModel(channelTable); - - model->setHorizontalHeaderLabels(labels); - - channelTable->setModel(model); - - gridLayout->addWidget(channelTable, i / 4, i % 4); - - channelTable->verticalHeader()->hide(); - channelTable->setEditTriggers(QAbstractItemView::NoEditTriggers); - channelTable->scrollToBottom(); - - channelModelList.append(model); - } - - this->tableModelList.append(channelModelList); } -void PhaseWindow::createKafkaMessage() +int PhaseWindow::initHttpToken() { - this->kafkaUtil = new QKafkaUtil(this); - this->kafkaUtil->setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); - this->kafkaUtil->setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int PhaseWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject PhaseWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("比相仪"); + return response; +} - kafkaUtil->createProducer(); - kafkaUtil->produceMessage("hello world kafka kylin"); +void PhaseWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} + +void PhaseWindow::on_exitButt_clicked() +{ + QApplication::exit(0); } diff --git a/PhaseCompAcq/PhaseWindow.h b/PhaseCompAcq/PhaseWindow.h index 67b8363..02a7908 100644 --- a/PhaseCompAcq/PhaseWindow.h +++ b/PhaseCompAcq/PhaseWindow.h @@ -2,11 +2,13 @@ #define PHASEWINDOW_H #include +#include #include +#include #include "PhaseDevice.h" #include "common/utils/SettingConfig.h" -#include "common/utils/QKafkaUtil.h" +#include "common/HttpRequestController.h" namespace Ui { class PhaseWindow; @@ -23,18 +25,23 @@ public slots: void drawPhaseDataOnPage(PhaseDataDto * phaseData); +private slots: + void on_minButt_clicked(); + + void on_exitButt_clicked(); + private: + int initHttpToken(); + int initDictDeviceTypes(); + QJsonObject initDeviceList(); + Ui::PhaseWindow *ui; - QList devWidgetList; + HttpRequestController * httpReq; QList deviceList; - QList> tableModelList; - QKafkaUtil * kafkaUtil; - - void generateWidgetForDevice(QString devCode, int index); - void createKafkaMessage(); + void generateWidgetForDevice(); }; #endif // PHASEWINDOW_H diff --git a/PhaseCompAcq/PhaseWindow.ui b/PhaseCompAcq/PhaseWindow.ui index e6da880..01a7759 100644 --- a/PhaseCompAcq/PhaseWindow.ui +++ b/PhaseCompAcq/PhaseWindow.ui @@ -10,26 +10,144 @@ 720 - - - 1024 - 720 - - 多通道比相仪数据采集 - + 0 0 - 1024 - 720 + 100 + 30 - - -1 + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 100 + 30 + + + + + + + + 400 + 10 + 250 + 40 + + + + + + + 250 + 0 + 150 + 60 + + + + + 微软雅黑 + 12 + + + + Qt::LeftToRight + + + 请选择比相仪 + + + Qt::AlignCenter + + + + + + 880 + 10 + 40 + 40 + + + + + + + 退出 + + + + + + 20 + 0 + 200 + 60 + + + + + 微软雅黑 + 14 + + + + 多通道比相仪数据采集 + + + + + + 0 + 59 + 1024 + 1 + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + 830 + 10 + 40 + 40 + + + + + + + 最小化 diff --git a/PhaseCompAcq/common/ConstCache.h b/PhaseCompAcq/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/PhaseCompAcq/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/PhaseCompAcq/common/HttpRequestController.cpp b/PhaseCompAcq/common/HttpRequestController.cpp new file mode 100644 index 0000000..6abb5af --- /dev/null +++ b/PhaseCompAcq/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceTypes.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDeviceList(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", system.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); + } + + qDebug() << resultObj; + + return resultObj; +} diff --git a/PhaseCompAcq/common/HttpRequestController.h b/PhaseCompAcq/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/PhaseCompAcq/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/PhaseCompAcq/common/common.pri b/PhaseCompAcq/common/common.pri index 055a2db..84f57ae 100644 --- a/PhaseCompAcq/common/common.pri +++ b/PhaseCompAcq/common/common.pri @@ -3,10 +3,18 @@ SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp -SOURCES += $$PWD/utils/QKafkaUtil.cpp +#SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp HEADERS += $$PWD/utils/SettingConfig.h HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h -HEADERS += $$PWD/utils/QKafkaUtil.h +#HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/PhaseCompAcq/common/utils/DefHead.h b/PhaseCompAcq/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/PhaseCompAcq/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/CounterAcq/CounterAcq.pro b/CounterAcq/CounterAcq.pro index 72407cd..fae9d10 100644 --- a/CounterAcq/CounterAcq.pro +++ b/CounterAcq/CounterAcq.pro @@ -4,13 +4,6 @@ CONFIG += c++11 -SOURCES += \ - CounterWindow.cpp \ - main.cpp \ - -HEADERS += \ - CounterWindow.h \ - FORMS += \ CounterWindow.ui \ @@ -18,8 +11,11 @@ include(protocol/protocol.pri) HEADERS += CounterDevice.h +HEADERS += CounterWindow.h SOURCES += CounterDevice.cpp +SOURCES += CounterWindow.cpp +SOURCES += main.cpp DISTFILES += conf/config.ini diff --git a/CounterAcq/CounterWindow.cpp b/CounterAcq/CounterWindow.cpp index 80035a9..a50ebcf 100644 --- a/CounterAcq/CounterWindow.cpp +++ b/CounterAcq/CounterWindow.cpp @@ -42,7 +42,7 @@ { QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); - QApplication::exit(0); + QTimer::singleShot(1000, qApp, SLOT(quit())); } // 2. 获取字典值:设备类型 retCode = this->initDictDeviceTypes(); diff --git a/CounterAcq/CounterWindow.h b/CounterAcq/CounterWindow.h index 8d5e4a6..09277ba 100644 --- a/CounterAcq/CounterWindow.h +++ b/CounterAcq/CounterWindow.h @@ -7,7 +7,6 @@ #include #include "common/utils/SettingConfig.h" -#include "common/utils/QKafkaUtil.h" #include "common/HttpRequestController.h" #include "CounterDevice.h" @@ -23,8 +22,6 @@ explicit CounterWindow(QWidget *parent = nullptr); ~CounterWindow(); - QString token; - public slots: void drawCounterDataOnPage(CounterDataDto * counterData); @@ -40,7 +37,6 @@ Ui::CounterWindow *ui; - QTimer * timer; HttpRequestController * httpReq; QList deviceList; diff --git a/PhaseCompAcq/PhaseCompAcq.pro b/PhaseCompAcq/PhaseCompAcq.pro index 5eef2d1..c5e895b 100644 --- a/PhaseCompAcq/PhaseCompAcq.pro +++ b/PhaseCompAcq/PhaseCompAcq.pro @@ -1,16 +1,9 @@ -QT += core gui serialport +QT += core gui serialport network greaterThan(QT_MAJOR_VERSION, 4): QT += widgets CONFIG += c++11 -SOURCES += \ - main.cpp \ - PhaseWindow.cpp - -HEADERS += \ - PhaseWindow.h - FORMS += \ PhaseWindow.ui @@ -18,20 +11,19 @@ include(protocol/protocol.pri) HEADERS += PhaseDevice.h -#HEADERS += PhaseSerialServer.h +HEADERS += PhaseWindow.h SOURCES += PhaseDevice.cpp -#SOURCES += PhaseSerialServer.cpp +SOURCES += PhaseWindow.cpp +SOURCES += main.cpp # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target - -INCLUDEPATH += $$PWD/include/librdkafka -DEPENDPATH += $$PWD/include/librdkafka +#unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +#INCLUDEPATH += $$PWD/include/librdkafka +#DEPENDPATH += $$PWD/include/librdkafka DISTFILES += conf/config.ini - -unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ diff --git a/PhaseCompAcq/PhaseDevice.cpp b/PhaseCompAcq/PhaseDevice.cpp index 5c84cd5..afc2687 100644 --- a/PhaseCompAcq/PhaseDevice.cpp +++ b/PhaseCompAcq/PhaseDevice.cpp @@ -7,9 +7,9 @@ connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, this, &PhaseDevice::dataReceivedHandler); - kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); - kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); - kafkaUtil.createProducer(); +// kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); +// kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); +// kafkaUtil.createProducer(); } PhaseDevice::~PhaseDevice() @@ -34,6 +34,10 @@ { this->devCode = devCode; } +void PhaseDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} bool PhaseDevice::isSerialOpen() { @@ -74,6 +78,7 @@ if (parse == true) { QDateTime now = QDateTime::currentDateTime(); + phaseData->devCode = this->devCode; phaseData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); phaseData->milisecond = now.toMSecsSinceEpoch(); this->afterFramePhase(phaseData); @@ -92,21 +97,20 @@ this->dataBuff.clear(); // 2. 输出到日志文件中 - QString filePostfix = phaseData->timestamp.mid(0, 13).replace(" ", "_"); - QString filePrefix = QApplication::applicationDirPath() + "/logs/"; + QString date = phaseData->timestamp.mid(0, 10); // 2.1 原始字节数组数据 - QString filename = filePrefix + "raw_" + filePostfix + ".log"; + QString filename = "raw_" + devCode + ".log"; QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); - QLogUtil::writeRawDataLog(filename, content); + QLogUtil::writeRawDataLogByDate(date, filename, content); // 2.2 各个通道的相差数据 for (int i = 1; i <= phaseData->channelActive.size(); i++) { if (phaseData->channelActive.at(i-1).toUInt() == 1) { - QString chFilename("%1CH_%2_%3.log"); - chFilename = chFilename.arg(filePrefix); + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); if (i < 10) { chFilename = chFilename.arg(QString("0%1").arg(i)); @@ -114,10 +118,9 @@ { chFilename = chFilename.arg(i); } - chFilename = chFilename.arg(filePostfix); - QString channelDataStr = QString("%1 %2 %3").arg(phaseData->timestamp).arg(phaseData->channelData.at(i-1)).arg(phaseData->frameId); + QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelData.at(i-1)); - QLogUtil::writeChannelDataLog(chFilename, channelDataStr); + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); // 3. 输出到中间件,执行后续处理过程 if (SettingConfig::getInstance().NEED_KAFKA == 1) @@ -125,7 +128,7 @@ QJsonObject jsonObj = phaseData->toJSON(i - 1); jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); jsonObj.insert("deviceId", devCode); - kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); +// kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); } } } diff --git a/PhaseCompAcq/PhaseDevice.h b/PhaseCompAcq/PhaseDevice.h index 92182d4..aa7d822 100644 --- a/PhaseCompAcq/PhaseDevice.h +++ b/PhaseCompAcq/PhaseDevice.h @@ -5,7 +5,7 @@ #include "common/utils/QSerialPortUtil.h" #include "common/utils/QLogUtil.h" #include "common/utils/SettingConfig.h" -#include "common/utils/QKafkaUtil.h" +//#include "common/utils/QKafkaUtil.h" #include "protocol/PhaseProtocolBM.h" class PhaseDevice : public QObject @@ -25,15 +25,17 @@ void setBaudRate(int baudRate); QString getDevCode(); void setDevCode(QString devCode); + void setDeviceId(QString deviceId); bool isSerialOpen(); private: + QString deviceId; QString devCode; QString comName; int baudRate; QSerialPortUtil serialUtil; - QKafkaUtil kafkaUtil; +// QKafkaUtil kafkaUtil; QByteArray dataBuff; signals: diff --git a/PhaseCompAcq/PhaseWindow.cpp b/PhaseCompAcq/PhaseWindow.cpp index b3cab89..d0e8221 100644 --- a/PhaseCompAcq/PhaseWindow.cpp +++ b/PhaseCompAcq/PhaseWindow.cpp @@ -1,16 +1,16 @@ #include "PhaseWindow.h" #include "ui_PhaseWindow.h" -#include -#include -#include -#include -#include -#include - #include - -#include "common/utils/QKafkaUtil.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include PhaseWindow::PhaseWindow(QWidget *parent) : QWidget(parent), @@ -18,43 +18,74 @@ { ui->setupUi(this); - QString portNames = SettingConfig::getInstance().PORT_NAMES; - int baudRate = SettingConfig::getInstance().BAUD_RATE; - QString devCodes = SettingConfig::getInstance().DEV_CODES; + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); - QStringList comDevList = portNames.split(","); - QStringList devCodeList = devCodes.split(","); + // 窗口大小为占满一屏 + QRect screenRect = QApplication::desktop()->screenGeometry(); + resize(screenRect.width(), screenRect.height()); - for (int i = 0; i < comDevList.size(); i++) + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->line->setGeometry(0, 59, screenRect.width(), 1); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 60, screenRect.width(), screenRect.height() - 60); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + + httpReq = new HttpRequestController(this); + // 1. 获取访问接口需要的token + int retCode = this->initHttpToken(); + if (retCode != 200) { - PhaseDevice * device = new PhaseDevice(this); + QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); - // - connect(device, &PhaseDevice::sendDataToDraw, - this, &PhaseWindow::drawPhaseDataOnPage); + QTimer::singleShot(1000, qApp, SLOT(quit())); + } + // 2. 获取字典值:设备类型 + retCode = this->initDictDeviceTypes(); - device->setComName(comDevList.at(i)); - device->setBaudRate(baudRate); + // 3. 获取比相仪设备列表 + QJsonObject devListRes = this->initDeviceList(); + if (devListRes.find("code")->toInt() == 200) + { + ui->devSelect->clear(); - device->setDevCode(devCodeList.at(i)); + // 4. 将获取到的设备添加到下拉列表框中 + QJsonArray devArray = devListRes.find("data")->toArray(); + for (int i = 0; i < devArray.size(); i++) + { + QJsonObject devItem = devArray.at(i).toObject(); + ui->devSelect->addItem(devItem.find("deviceName")->toString(), devItem.find("deviceNo")->toString()); - this->deviceList.append(device); + PhaseDevice * device = new PhaseDevice(this); + deviceList.append(device); - device->initSerialPort(); - device->startWork(); + device->setComName(devItem.find("linkComName")->toString()); + device->setBaudRate(SettingConfig::getInstance().BAUD_RATE); + device->setDevCode(devItem.find("deviceNo")->toString()); + device->setDeviceId(devItem.find("deviceId")->toString()); + + connect(device, &PhaseDevice::sendDataToDraw, + this, &PhaseWindow::drawPhaseDataOnPage); + + device->initSerialPort(); + + QThread::msleep(100); + } + // 5. 设置下拉框的样式 + QStandardItemModel * model = qobject_cast(ui->devSelect->model()); + for (int i = 0; i < model->rowCount(); ++i) + { + QStandardItem * item = model->item(i); + item->setSizeHint({ 0, 30 }); + } } - for (int i = 0; i < this->deviceList.size(); i++) - { - QWidget * devWidget5 = new QWidget(this->ui->stackedWidget); - - this->ui->stackedWidget->addWidget(devWidget5); - - this->devWidgetList.append(devWidget5); - - // 创建设备的widget - this->generateWidgetForDevice(devCodeList.at(i), i); - } + // 6. 绘制一个设备的多个通道数据面板 + this->generateWidgetForDevice(); } PhaseWindow::~PhaseWindow() @@ -64,99 +95,119 @@ void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) { - // 1. 判断数据属于哪个设备,显示在不同的widget上 + // 当前显示的设备编号 + QString currentDevCode = ui->devSelect->currentData().toString(); - // 2. 循环设置各个tableView - QList devChannels = this->tableModelList.at(0); // 暂时写死 - for (int i = 0; i < phaseData->channelData.size(); i++) + // 如果不是当前设备的帧,直接返回 + if (phaseData->devCode != currentDevCode) { - if (phaseData->channelActive.at(i).toInt() == 1) - { - QList row; - QStandardItem * item = 0; - QStandardItem * item2 = 0; - item = new QStandardItem(QString("%1").arg(phaseData->timestamp.mid(11, 12))); - item2 = new QStandardItem(QString("%1").arg(phaseData->channelData.at(i))); + return; + } - row.append(item); - row.append(item2); + // 更新所有通道BOX的值 + for (int i = 0; i < phaseData->channelActive.size(); i++) + { + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); - QStandardItemModel * model; - model = devChannels.at(i); - if (model->rowCount() >= 60) - { - model->removeRows(0, model->rowCount()); - } - - model->insertRow(0, row); - } + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(phaseData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelData.at(i))); + ((QLineEdit *)channelBox->children().at(6))->setText(phaseData->frameId); + ((QLabel *)channelBox->children().at(7))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); } } -void PhaseWindow::generateWidgetForDevice(QString devCode, int index) +void PhaseWindow::generateWidgetForDevice() { - // 顶部切换widget - QWidget * switchWidget = new QWidget(this->devWidgetList.at(index)); - switchWidget->setGeometry(0, 0, 1024, 50); + // 获取设备数据 + int channelNum = 16; - // 显示数据的区域 - QWidget * gridWidget = new QWidget(this->devWidgetList.at(index)); - gridWidget->setGeometry(0, 50, 1024, 670); + QRect screenRect = QApplication::desktop()->screenGeometry(); - // 顶部水平布局,用于排布按钮 - QHBoxLayout * hLayout = new QHBoxLayout(switchWidget); + ui->scrollContents->setGeometry(0, 60, screenRect.width(), channelNum * 90); - // 文本 - QLabel * label = new QLabel(switchWidget); - label->setText("设备编号:" + devCode); - label->setFont(QFont("微软雅黑", 12)); - hLayout->addWidget(label); + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); - // 按钮 - for (int i = 0; i < this->deviceList.size(); i++) + for (int i = 0; i < channelNum; i++) { - QPushButton * butt5 = new QPushButton(this->deviceList.at(i)->getDevCode()); - hLayout->addWidget(butt5); + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 80 + 10, screenRect.width() - 40, 80); - connect(butt5, &QPushButton::clicked, [=](){ - this->ui->stackedWidget->setCurrentIndex(i); - }); + QHBoxLayout * vbox = new QHBoxLayout(group); + + QLabel * tmLabel = new QLabel(); + tmLabel->setText("时间"); + tmLabel->setFont(labelFont); + tmLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(tmLabel); + QLineEdit * tmValue = new QLineEdit(); + tmValue->setFixedWidth(200); + tmValue->setFont(labelFont); + vbox->addWidget(tmValue); + + QLabel * dataLabel = new QLabel(); + dataLabel->setText("测量数据"); + dataLabel->setFont(labelFont); + dataLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(dataLabel); + QLineEdit * dataValue = new QLineEdit(); + dataValue->setFixedWidth(150); + dataValue->setFont(labelFont); + vbox->addWidget(dataValue); + + QLabel * idLabel = new QLabel(); + idLabel->setText("数据ID"); + idLabel->setFont(labelFont); + idLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(idLabel); + QLineEdit * idValue = new QLineEdit(); + idValue->setFixedWidth(100); + idValue->setFont(labelFont); + vbox->addWidget(idValue); + + QLabel * validLabel = new QLabel(); + validLabel->setText("-"); + validLabel->setFont(labelFont); + validLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(validLabel); + + QSpacerItem * hSpace = new QSpacerItem(20, 20); + hSpace->changeSize(20, 20, QSizePolicy::Expanding); + vbox->addItem(hSpace); + + group->setLayout(vbox); + + layout->addWidget(group); } - - // Grid布局 - QGridLayout * gridLayout = new QGridLayout(gridWidget); - gridLayout->setSpacing(10); - - QList channelModelList; - QStringList labels = QObject::trUtf8("时间,相差").simplified().split(","); - - for (int i = 0; i < 16; i++) - { - QTableView * channelTable = new QTableView(gridWidget); - QStandardItemModel * model = new QStandardItemModel(channelTable); - - model->setHorizontalHeaderLabels(labels); - - channelTable->setModel(model); - - gridLayout->addWidget(channelTable, i / 4, i % 4); - - channelTable->verticalHeader()->hide(); - channelTable->setEditTriggers(QAbstractItemView::NoEditTriggers); - channelTable->scrollToBottom(); - - channelModelList.append(model); - } - - this->tableModelList.append(channelModelList); } -void PhaseWindow::createKafkaMessage() +int PhaseWindow::initHttpToken() { - this->kafkaUtil = new QKafkaUtil(this); - this->kafkaUtil->setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); - this->kafkaUtil->setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int PhaseWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject PhaseWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("比相仪"); + return response; +} - kafkaUtil->createProducer(); - kafkaUtil->produceMessage("hello world kafka kylin"); +void PhaseWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} + +void PhaseWindow::on_exitButt_clicked() +{ + QApplication::exit(0); } diff --git a/PhaseCompAcq/PhaseWindow.h b/PhaseCompAcq/PhaseWindow.h index 67b8363..02a7908 100644 --- a/PhaseCompAcq/PhaseWindow.h +++ b/PhaseCompAcq/PhaseWindow.h @@ -2,11 +2,13 @@ #define PHASEWINDOW_H #include +#include #include +#include #include "PhaseDevice.h" #include "common/utils/SettingConfig.h" -#include "common/utils/QKafkaUtil.h" +#include "common/HttpRequestController.h" namespace Ui { class PhaseWindow; @@ -23,18 +25,23 @@ public slots: void drawPhaseDataOnPage(PhaseDataDto * phaseData); +private slots: + void on_minButt_clicked(); + + void on_exitButt_clicked(); + private: + int initHttpToken(); + int initDictDeviceTypes(); + QJsonObject initDeviceList(); + Ui::PhaseWindow *ui; - QList devWidgetList; + HttpRequestController * httpReq; QList deviceList; - QList> tableModelList; - QKafkaUtil * kafkaUtil; - - void generateWidgetForDevice(QString devCode, int index); - void createKafkaMessage(); + void generateWidgetForDevice(); }; #endif // PHASEWINDOW_H diff --git a/PhaseCompAcq/PhaseWindow.ui b/PhaseCompAcq/PhaseWindow.ui index e6da880..01a7759 100644 --- a/PhaseCompAcq/PhaseWindow.ui +++ b/PhaseCompAcq/PhaseWindow.ui @@ -10,26 +10,144 @@ 720 - - - 1024 - 720 - - 多通道比相仪数据采集 - + 0 0 - 1024 - 720 + 100 + 30 - - -1 + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 100 + 30 + + + + + + + + 400 + 10 + 250 + 40 + + + + + + + 250 + 0 + 150 + 60 + + + + + 微软雅黑 + 12 + + + + Qt::LeftToRight + + + 请选择比相仪 + + + Qt::AlignCenter + + + + + + 880 + 10 + 40 + 40 + + + + + + + 退出 + + + + + + 20 + 0 + 200 + 60 + + + + + 微软雅黑 + 14 + + + + 多通道比相仪数据采集 + + + + + + 0 + 59 + 1024 + 1 + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + 830 + 10 + 40 + 40 + + + + + + + 最小化 diff --git a/PhaseCompAcq/common/ConstCache.h b/PhaseCompAcq/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/PhaseCompAcq/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/PhaseCompAcq/common/HttpRequestController.cpp b/PhaseCompAcq/common/HttpRequestController.cpp new file mode 100644 index 0000000..6abb5af --- /dev/null +++ b/PhaseCompAcq/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceTypes.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDeviceList(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", system.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); + } + + qDebug() << resultObj; + + return resultObj; +} diff --git a/PhaseCompAcq/common/HttpRequestController.h b/PhaseCompAcq/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/PhaseCompAcq/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/PhaseCompAcq/common/common.pri b/PhaseCompAcq/common/common.pri index 055a2db..84f57ae 100644 --- a/PhaseCompAcq/common/common.pri +++ b/PhaseCompAcq/common/common.pri @@ -3,10 +3,18 @@ SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp -SOURCES += $$PWD/utils/QKafkaUtil.cpp +#SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp HEADERS += $$PWD/utils/SettingConfig.h HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h -HEADERS += $$PWD/utils/QKafkaUtil.h +#HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/PhaseCompAcq/common/utils/DefHead.h b/PhaseCompAcq/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/PhaseCompAcq/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/PhaseCompAcq/common/utils/HttpRequestUtil.cpp b/PhaseCompAcq/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/PhaseCompAcq/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/CounterAcq/CounterAcq.pro b/CounterAcq/CounterAcq.pro index 72407cd..fae9d10 100644 --- a/CounterAcq/CounterAcq.pro +++ b/CounterAcq/CounterAcq.pro @@ -4,13 +4,6 @@ CONFIG += c++11 -SOURCES += \ - CounterWindow.cpp \ - main.cpp \ - -HEADERS += \ - CounterWindow.h \ - FORMS += \ CounterWindow.ui \ @@ -18,8 +11,11 @@ include(protocol/protocol.pri) HEADERS += CounterDevice.h +HEADERS += CounterWindow.h SOURCES += CounterDevice.cpp +SOURCES += CounterWindow.cpp +SOURCES += main.cpp DISTFILES += conf/config.ini diff --git a/CounterAcq/CounterWindow.cpp b/CounterAcq/CounterWindow.cpp index 80035a9..a50ebcf 100644 --- a/CounterAcq/CounterWindow.cpp +++ b/CounterAcq/CounterWindow.cpp @@ -42,7 +42,7 @@ { QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); - QApplication::exit(0); + QTimer::singleShot(1000, qApp, SLOT(quit())); } // 2. 获取字典值:设备类型 retCode = this->initDictDeviceTypes(); diff --git a/CounterAcq/CounterWindow.h b/CounterAcq/CounterWindow.h index 8d5e4a6..09277ba 100644 --- a/CounterAcq/CounterWindow.h +++ b/CounterAcq/CounterWindow.h @@ -7,7 +7,6 @@ #include #include "common/utils/SettingConfig.h" -#include "common/utils/QKafkaUtil.h" #include "common/HttpRequestController.h" #include "CounterDevice.h" @@ -23,8 +22,6 @@ explicit CounterWindow(QWidget *parent = nullptr); ~CounterWindow(); - QString token; - public slots: void drawCounterDataOnPage(CounterDataDto * counterData); @@ -40,7 +37,6 @@ Ui::CounterWindow *ui; - QTimer * timer; HttpRequestController * httpReq; QList deviceList; diff --git a/PhaseCompAcq/PhaseCompAcq.pro b/PhaseCompAcq/PhaseCompAcq.pro index 5eef2d1..c5e895b 100644 --- a/PhaseCompAcq/PhaseCompAcq.pro +++ b/PhaseCompAcq/PhaseCompAcq.pro @@ -1,16 +1,9 @@ -QT += core gui serialport +QT += core gui serialport network greaterThan(QT_MAJOR_VERSION, 4): QT += widgets CONFIG += c++11 -SOURCES += \ - main.cpp \ - PhaseWindow.cpp - -HEADERS += \ - PhaseWindow.h - FORMS += \ PhaseWindow.ui @@ -18,20 +11,19 @@ include(protocol/protocol.pri) HEADERS += PhaseDevice.h -#HEADERS += PhaseSerialServer.h +HEADERS += PhaseWindow.h SOURCES += PhaseDevice.cpp -#SOURCES += PhaseSerialServer.cpp +SOURCES += PhaseWindow.cpp +SOURCES += main.cpp # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target - -INCLUDEPATH += $$PWD/include/librdkafka -DEPENDPATH += $$PWD/include/librdkafka +#unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +#INCLUDEPATH += $$PWD/include/librdkafka +#DEPENDPATH += $$PWD/include/librdkafka DISTFILES += conf/config.ini - -unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ diff --git a/PhaseCompAcq/PhaseDevice.cpp b/PhaseCompAcq/PhaseDevice.cpp index 5c84cd5..afc2687 100644 --- a/PhaseCompAcq/PhaseDevice.cpp +++ b/PhaseCompAcq/PhaseDevice.cpp @@ -7,9 +7,9 @@ connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, this, &PhaseDevice::dataReceivedHandler); - kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); - kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); - kafkaUtil.createProducer(); +// kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); +// kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); +// kafkaUtil.createProducer(); } PhaseDevice::~PhaseDevice() @@ -34,6 +34,10 @@ { this->devCode = devCode; } +void PhaseDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} bool PhaseDevice::isSerialOpen() { @@ -74,6 +78,7 @@ if (parse == true) { QDateTime now = QDateTime::currentDateTime(); + phaseData->devCode = this->devCode; phaseData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); phaseData->milisecond = now.toMSecsSinceEpoch(); this->afterFramePhase(phaseData); @@ -92,21 +97,20 @@ this->dataBuff.clear(); // 2. 输出到日志文件中 - QString filePostfix = phaseData->timestamp.mid(0, 13).replace(" ", "_"); - QString filePrefix = QApplication::applicationDirPath() + "/logs/"; + QString date = phaseData->timestamp.mid(0, 10); // 2.1 原始字节数组数据 - QString filename = filePrefix + "raw_" + filePostfix + ".log"; + QString filename = "raw_" + devCode + ".log"; QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); - QLogUtil::writeRawDataLog(filename, content); + QLogUtil::writeRawDataLogByDate(date, filename, content); // 2.2 各个通道的相差数据 for (int i = 1; i <= phaseData->channelActive.size(); i++) { if (phaseData->channelActive.at(i-1).toUInt() == 1) { - QString chFilename("%1CH_%2_%3.log"); - chFilename = chFilename.arg(filePrefix); + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); if (i < 10) { chFilename = chFilename.arg(QString("0%1").arg(i)); @@ -114,10 +118,9 @@ { chFilename = chFilename.arg(i); } - chFilename = chFilename.arg(filePostfix); - QString channelDataStr = QString("%1 %2 %3").arg(phaseData->timestamp).arg(phaseData->channelData.at(i-1)).arg(phaseData->frameId); + QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelData.at(i-1)); - QLogUtil::writeChannelDataLog(chFilename, channelDataStr); + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); // 3. 输出到中间件,执行后续处理过程 if (SettingConfig::getInstance().NEED_KAFKA == 1) @@ -125,7 +128,7 @@ QJsonObject jsonObj = phaseData->toJSON(i - 1); jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); jsonObj.insert("deviceId", devCode); - kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); +// kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); } } } diff --git a/PhaseCompAcq/PhaseDevice.h b/PhaseCompAcq/PhaseDevice.h index 92182d4..aa7d822 100644 --- a/PhaseCompAcq/PhaseDevice.h +++ b/PhaseCompAcq/PhaseDevice.h @@ -5,7 +5,7 @@ #include "common/utils/QSerialPortUtil.h" #include "common/utils/QLogUtil.h" #include "common/utils/SettingConfig.h" -#include "common/utils/QKafkaUtil.h" +//#include "common/utils/QKafkaUtil.h" #include "protocol/PhaseProtocolBM.h" class PhaseDevice : public QObject @@ -25,15 +25,17 @@ void setBaudRate(int baudRate); QString getDevCode(); void setDevCode(QString devCode); + void setDeviceId(QString deviceId); bool isSerialOpen(); private: + QString deviceId; QString devCode; QString comName; int baudRate; QSerialPortUtil serialUtil; - QKafkaUtil kafkaUtil; +// QKafkaUtil kafkaUtil; QByteArray dataBuff; signals: diff --git a/PhaseCompAcq/PhaseWindow.cpp b/PhaseCompAcq/PhaseWindow.cpp index b3cab89..d0e8221 100644 --- a/PhaseCompAcq/PhaseWindow.cpp +++ b/PhaseCompAcq/PhaseWindow.cpp @@ -1,16 +1,16 @@ #include "PhaseWindow.h" #include "ui_PhaseWindow.h" -#include -#include -#include -#include -#include -#include - #include - -#include "common/utils/QKafkaUtil.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include PhaseWindow::PhaseWindow(QWidget *parent) : QWidget(parent), @@ -18,43 +18,74 @@ { ui->setupUi(this); - QString portNames = SettingConfig::getInstance().PORT_NAMES; - int baudRate = SettingConfig::getInstance().BAUD_RATE; - QString devCodes = SettingConfig::getInstance().DEV_CODES; + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); - QStringList comDevList = portNames.split(","); - QStringList devCodeList = devCodes.split(","); + // 窗口大小为占满一屏 + QRect screenRect = QApplication::desktop()->screenGeometry(); + resize(screenRect.width(), screenRect.height()); - for (int i = 0; i < comDevList.size(); i++) + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->line->setGeometry(0, 59, screenRect.width(), 1); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 60, screenRect.width(), screenRect.height() - 60); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + + httpReq = new HttpRequestController(this); + // 1. 获取访问接口需要的token + int retCode = this->initHttpToken(); + if (retCode != 200) { - PhaseDevice * device = new PhaseDevice(this); + QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); - // - connect(device, &PhaseDevice::sendDataToDraw, - this, &PhaseWindow::drawPhaseDataOnPage); + QTimer::singleShot(1000, qApp, SLOT(quit())); + } + // 2. 获取字典值:设备类型 + retCode = this->initDictDeviceTypes(); - device->setComName(comDevList.at(i)); - device->setBaudRate(baudRate); + // 3. 获取比相仪设备列表 + QJsonObject devListRes = this->initDeviceList(); + if (devListRes.find("code")->toInt() == 200) + { + ui->devSelect->clear(); - device->setDevCode(devCodeList.at(i)); + // 4. 将获取到的设备添加到下拉列表框中 + QJsonArray devArray = devListRes.find("data")->toArray(); + for (int i = 0; i < devArray.size(); i++) + { + QJsonObject devItem = devArray.at(i).toObject(); + ui->devSelect->addItem(devItem.find("deviceName")->toString(), devItem.find("deviceNo")->toString()); - this->deviceList.append(device); + PhaseDevice * device = new PhaseDevice(this); + deviceList.append(device); - device->initSerialPort(); - device->startWork(); + device->setComName(devItem.find("linkComName")->toString()); + device->setBaudRate(SettingConfig::getInstance().BAUD_RATE); + device->setDevCode(devItem.find("deviceNo")->toString()); + device->setDeviceId(devItem.find("deviceId")->toString()); + + connect(device, &PhaseDevice::sendDataToDraw, + this, &PhaseWindow::drawPhaseDataOnPage); + + device->initSerialPort(); + + QThread::msleep(100); + } + // 5. 设置下拉框的样式 + QStandardItemModel * model = qobject_cast(ui->devSelect->model()); + for (int i = 0; i < model->rowCount(); ++i) + { + QStandardItem * item = model->item(i); + item->setSizeHint({ 0, 30 }); + } } - for (int i = 0; i < this->deviceList.size(); i++) - { - QWidget * devWidget5 = new QWidget(this->ui->stackedWidget); - - this->ui->stackedWidget->addWidget(devWidget5); - - this->devWidgetList.append(devWidget5); - - // 创建设备的widget - this->generateWidgetForDevice(devCodeList.at(i), i); - } + // 6. 绘制一个设备的多个通道数据面板 + this->generateWidgetForDevice(); } PhaseWindow::~PhaseWindow() @@ -64,99 +95,119 @@ void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) { - // 1. 判断数据属于哪个设备,显示在不同的widget上 + // 当前显示的设备编号 + QString currentDevCode = ui->devSelect->currentData().toString(); - // 2. 循环设置各个tableView - QList devChannels = this->tableModelList.at(0); // 暂时写死 - for (int i = 0; i < phaseData->channelData.size(); i++) + // 如果不是当前设备的帧,直接返回 + if (phaseData->devCode != currentDevCode) { - if (phaseData->channelActive.at(i).toInt() == 1) - { - QList row; - QStandardItem * item = 0; - QStandardItem * item2 = 0; - item = new QStandardItem(QString("%1").arg(phaseData->timestamp.mid(11, 12))); - item2 = new QStandardItem(QString("%1").arg(phaseData->channelData.at(i))); + return; + } - row.append(item); - row.append(item2); + // 更新所有通道BOX的值 + for (int i = 0; i < phaseData->channelActive.size(); i++) + { + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); - QStandardItemModel * model; - model = devChannels.at(i); - if (model->rowCount() >= 60) - { - model->removeRows(0, model->rowCount()); - } - - model->insertRow(0, row); - } + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(phaseData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelData.at(i))); + ((QLineEdit *)channelBox->children().at(6))->setText(phaseData->frameId); + ((QLabel *)channelBox->children().at(7))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); } } -void PhaseWindow::generateWidgetForDevice(QString devCode, int index) +void PhaseWindow::generateWidgetForDevice() { - // 顶部切换widget - QWidget * switchWidget = new QWidget(this->devWidgetList.at(index)); - switchWidget->setGeometry(0, 0, 1024, 50); + // 获取设备数据 + int channelNum = 16; - // 显示数据的区域 - QWidget * gridWidget = new QWidget(this->devWidgetList.at(index)); - gridWidget->setGeometry(0, 50, 1024, 670); + QRect screenRect = QApplication::desktop()->screenGeometry(); - // 顶部水平布局,用于排布按钮 - QHBoxLayout * hLayout = new QHBoxLayout(switchWidget); + ui->scrollContents->setGeometry(0, 60, screenRect.width(), channelNum * 90); - // 文本 - QLabel * label = new QLabel(switchWidget); - label->setText("设备编号:" + devCode); - label->setFont(QFont("微软雅黑", 12)); - hLayout->addWidget(label); + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); - // 按钮 - for (int i = 0; i < this->deviceList.size(); i++) + for (int i = 0; i < channelNum; i++) { - QPushButton * butt5 = new QPushButton(this->deviceList.at(i)->getDevCode()); - hLayout->addWidget(butt5); + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 80 + 10, screenRect.width() - 40, 80); - connect(butt5, &QPushButton::clicked, [=](){ - this->ui->stackedWidget->setCurrentIndex(i); - }); + QHBoxLayout * vbox = new QHBoxLayout(group); + + QLabel * tmLabel = new QLabel(); + tmLabel->setText("时间"); + tmLabel->setFont(labelFont); + tmLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(tmLabel); + QLineEdit * tmValue = new QLineEdit(); + tmValue->setFixedWidth(200); + tmValue->setFont(labelFont); + vbox->addWidget(tmValue); + + QLabel * dataLabel = new QLabel(); + dataLabel->setText("测量数据"); + dataLabel->setFont(labelFont); + dataLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(dataLabel); + QLineEdit * dataValue = new QLineEdit(); + dataValue->setFixedWidth(150); + dataValue->setFont(labelFont); + vbox->addWidget(dataValue); + + QLabel * idLabel = new QLabel(); + idLabel->setText("数据ID"); + idLabel->setFont(labelFont); + idLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(idLabel); + QLineEdit * idValue = new QLineEdit(); + idValue->setFixedWidth(100); + idValue->setFont(labelFont); + vbox->addWidget(idValue); + + QLabel * validLabel = new QLabel(); + validLabel->setText("-"); + validLabel->setFont(labelFont); + validLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(validLabel); + + QSpacerItem * hSpace = new QSpacerItem(20, 20); + hSpace->changeSize(20, 20, QSizePolicy::Expanding); + vbox->addItem(hSpace); + + group->setLayout(vbox); + + layout->addWidget(group); } - - // Grid布局 - QGridLayout * gridLayout = new QGridLayout(gridWidget); - gridLayout->setSpacing(10); - - QList channelModelList; - QStringList labels = QObject::trUtf8("时间,相差").simplified().split(","); - - for (int i = 0; i < 16; i++) - { - QTableView * channelTable = new QTableView(gridWidget); - QStandardItemModel * model = new QStandardItemModel(channelTable); - - model->setHorizontalHeaderLabels(labels); - - channelTable->setModel(model); - - gridLayout->addWidget(channelTable, i / 4, i % 4); - - channelTable->verticalHeader()->hide(); - channelTable->setEditTriggers(QAbstractItemView::NoEditTriggers); - channelTable->scrollToBottom(); - - channelModelList.append(model); - } - - this->tableModelList.append(channelModelList); } -void PhaseWindow::createKafkaMessage() +int PhaseWindow::initHttpToken() { - this->kafkaUtil = new QKafkaUtil(this); - this->kafkaUtil->setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); - this->kafkaUtil->setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int PhaseWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject PhaseWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("比相仪"); + return response; +} - kafkaUtil->createProducer(); - kafkaUtil->produceMessage("hello world kafka kylin"); +void PhaseWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} + +void PhaseWindow::on_exitButt_clicked() +{ + QApplication::exit(0); } diff --git a/PhaseCompAcq/PhaseWindow.h b/PhaseCompAcq/PhaseWindow.h index 67b8363..02a7908 100644 --- a/PhaseCompAcq/PhaseWindow.h +++ b/PhaseCompAcq/PhaseWindow.h @@ -2,11 +2,13 @@ #define PHASEWINDOW_H #include +#include #include +#include #include "PhaseDevice.h" #include "common/utils/SettingConfig.h" -#include "common/utils/QKafkaUtil.h" +#include "common/HttpRequestController.h" namespace Ui { class PhaseWindow; @@ -23,18 +25,23 @@ public slots: void drawPhaseDataOnPage(PhaseDataDto * phaseData); +private slots: + void on_minButt_clicked(); + + void on_exitButt_clicked(); + private: + int initHttpToken(); + int initDictDeviceTypes(); + QJsonObject initDeviceList(); + Ui::PhaseWindow *ui; - QList devWidgetList; + HttpRequestController * httpReq; QList deviceList; - QList> tableModelList; - QKafkaUtil * kafkaUtil; - - void generateWidgetForDevice(QString devCode, int index); - void createKafkaMessage(); + void generateWidgetForDevice(); }; #endif // PHASEWINDOW_H diff --git a/PhaseCompAcq/PhaseWindow.ui b/PhaseCompAcq/PhaseWindow.ui index e6da880..01a7759 100644 --- a/PhaseCompAcq/PhaseWindow.ui +++ b/PhaseCompAcq/PhaseWindow.ui @@ -10,26 +10,144 @@ 720 - - - 1024 - 720 - - 多通道比相仪数据采集 - + 0 0 - 1024 - 720 + 100 + 30 - - -1 + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 100 + 30 + + + + + + + + 400 + 10 + 250 + 40 + + + + + + + 250 + 0 + 150 + 60 + + + + + 微软雅黑 + 12 + + + + Qt::LeftToRight + + + 请选择比相仪 + + + Qt::AlignCenter + + + + + + 880 + 10 + 40 + 40 + + + + + + + 退出 + + + + + + 20 + 0 + 200 + 60 + + + + + 微软雅黑 + 14 + + + + 多通道比相仪数据采集 + + + + + + 0 + 59 + 1024 + 1 + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + 830 + 10 + 40 + 40 + + + + + + + 最小化 diff --git a/PhaseCompAcq/common/ConstCache.h b/PhaseCompAcq/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/PhaseCompAcq/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/PhaseCompAcq/common/HttpRequestController.cpp b/PhaseCompAcq/common/HttpRequestController.cpp new file mode 100644 index 0000000..6abb5af --- /dev/null +++ b/PhaseCompAcq/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceTypes.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDeviceList(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", system.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); + } + + qDebug() << resultObj; + + return resultObj; +} diff --git a/PhaseCompAcq/common/HttpRequestController.h b/PhaseCompAcq/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/PhaseCompAcq/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/PhaseCompAcq/common/common.pri b/PhaseCompAcq/common/common.pri index 055a2db..84f57ae 100644 --- a/PhaseCompAcq/common/common.pri +++ b/PhaseCompAcq/common/common.pri @@ -3,10 +3,18 @@ SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp -SOURCES += $$PWD/utils/QKafkaUtil.cpp +#SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp HEADERS += $$PWD/utils/SettingConfig.h HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h -HEADERS += $$PWD/utils/QKafkaUtil.h +#HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/PhaseCompAcq/common/utils/DefHead.h b/PhaseCompAcq/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/PhaseCompAcq/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/PhaseCompAcq/common/utils/HttpRequestUtil.cpp b/PhaseCompAcq/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/PhaseCompAcq/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/PhaseCompAcq/common/utils/HttpRequestUtil.h b/PhaseCompAcq/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/PhaseCompAcq/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/CounterAcq/CounterAcq.pro b/CounterAcq/CounterAcq.pro index 72407cd..fae9d10 100644 --- a/CounterAcq/CounterAcq.pro +++ b/CounterAcq/CounterAcq.pro @@ -4,13 +4,6 @@ CONFIG += c++11 -SOURCES += \ - CounterWindow.cpp \ - main.cpp \ - -HEADERS += \ - CounterWindow.h \ - FORMS += \ CounterWindow.ui \ @@ -18,8 +11,11 @@ include(protocol/protocol.pri) HEADERS += CounterDevice.h +HEADERS += CounterWindow.h SOURCES += CounterDevice.cpp +SOURCES += CounterWindow.cpp +SOURCES += main.cpp DISTFILES += conf/config.ini diff --git a/CounterAcq/CounterWindow.cpp b/CounterAcq/CounterWindow.cpp index 80035a9..a50ebcf 100644 --- a/CounterAcq/CounterWindow.cpp +++ b/CounterAcq/CounterWindow.cpp @@ -42,7 +42,7 @@ { QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); - QApplication::exit(0); + QTimer::singleShot(1000, qApp, SLOT(quit())); } // 2. 获取字典值:设备类型 retCode = this->initDictDeviceTypes(); diff --git a/CounterAcq/CounterWindow.h b/CounterAcq/CounterWindow.h index 8d5e4a6..09277ba 100644 --- a/CounterAcq/CounterWindow.h +++ b/CounterAcq/CounterWindow.h @@ -7,7 +7,6 @@ #include #include "common/utils/SettingConfig.h" -#include "common/utils/QKafkaUtil.h" #include "common/HttpRequestController.h" #include "CounterDevice.h" @@ -23,8 +22,6 @@ explicit CounterWindow(QWidget *parent = nullptr); ~CounterWindow(); - QString token; - public slots: void drawCounterDataOnPage(CounterDataDto * counterData); @@ -40,7 +37,6 @@ Ui::CounterWindow *ui; - QTimer * timer; HttpRequestController * httpReq; QList deviceList; diff --git a/PhaseCompAcq/PhaseCompAcq.pro b/PhaseCompAcq/PhaseCompAcq.pro index 5eef2d1..c5e895b 100644 --- a/PhaseCompAcq/PhaseCompAcq.pro +++ b/PhaseCompAcq/PhaseCompAcq.pro @@ -1,16 +1,9 @@ -QT += core gui serialport +QT += core gui serialport network greaterThan(QT_MAJOR_VERSION, 4): QT += widgets CONFIG += c++11 -SOURCES += \ - main.cpp \ - PhaseWindow.cpp - -HEADERS += \ - PhaseWindow.h - FORMS += \ PhaseWindow.ui @@ -18,20 +11,19 @@ include(protocol/protocol.pri) HEADERS += PhaseDevice.h -#HEADERS += PhaseSerialServer.h +HEADERS += PhaseWindow.h SOURCES += PhaseDevice.cpp -#SOURCES += PhaseSerialServer.cpp +SOURCES += PhaseWindow.cpp +SOURCES += main.cpp # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target - -INCLUDEPATH += $$PWD/include/librdkafka -DEPENDPATH += $$PWD/include/librdkafka +#unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +#INCLUDEPATH += $$PWD/include/librdkafka +#DEPENDPATH += $$PWD/include/librdkafka DISTFILES += conf/config.ini - -unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ diff --git a/PhaseCompAcq/PhaseDevice.cpp b/PhaseCompAcq/PhaseDevice.cpp index 5c84cd5..afc2687 100644 --- a/PhaseCompAcq/PhaseDevice.cpp +++ b/PhaseCompAcq/PhaseDevice.cpp @@ -7,9 +7,9 @@ connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, this, &PhaseDevice::dataReceivedHandler); - kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); - kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); - kafkaUtil.createProducer(); +// kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); +// kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); +// kafkaUtil.createProducer(); } PhaseDevice::~PhaseDevice() @@ -34,6 +34,10 @@ { this->devCode = devCode; } +void PhaseDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} bool PhaseDevice::isSerialOpen() { @@ -74,6 +78,7 @@ if (parse == true) { QDateTime now = QDateTime::currentDateTime(); + phaseData->devCode = this->devCode; phaseData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); phaseData->milisecond = now.toMSecsSinceEpoch(); this->afterFramePhase(phaseData); @@ -92,21 +97,20 @@ this->dataBuff.clear(); // 2. 输出到日志文件中 - QString filePostfix = phaseData->timestamp.mid(0, 13).replace(" ", "_"); - QString filePrefix = QApplication::applicationDirPath() + "/logs/"; + QString date = phaseData->timestamp.mid(0, 10); // 2.1 原始字节数组数据 - QString filename = filePrefix + "raw_" + filePostfix + ".log"; + QString filename = "raw_" + devCode + ".log"; QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); - QLogUtil::writeRawDataLog(filename, content); + QLogUtil::writeRawDataLogByDate(date, filename, content); // 2.2 各个通道的相差数据 for (int i = 1; i <= phaseData->channelActive.size(); i++) { if (phaseData->channelActive.at(i-1).toUInt() == 1) { - QString chFilename("%1CH_%2_%3.log"); - chFilename = chFilename.arg(filePrefix); + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); if (i < 10) { chFilename = chFilename.arg(QString("0%1").arg(i)); @@ -114,10 +118,9 @@ { chFilename = chFilename.arg(i); } - chFilename = chFilename.arg(filePostfix); - QString channelDataStr = QString("%1 %2 %3").arg(phaseData->timestamp).arg(phaseData->channelData.at(i-1)).arg(phaseData->frameId); + QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelData.at(i-1)); - QLogUtil::writeChannelDataLog(chFilename, channelDataStr); + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); // 3. 输出到中间件,执行后续处理过程 if (SettingConfig::getInstance().NEED_KAFKA == 1) @@ -125,7 +128,7 @@ QJsonObject jsonObj = phaseData->toJSON(i - 1); jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); jsonObj.insert("deviceId", devCode); - kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); +// kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); } } } diff --git a/PhaseCompAcq/PhaseDevice.h b/PhaseCompAcq/PhaseDevice.h index 92182d4..aa7d822 100644 --- a/PhaseCompAcq/PhaseDevice.h +++ b/PhaseCompAcq/PhaseDevice.h @@ -5,7 +5,7 @@ #include "common/utils/QSerialPortUtil.h" #include "common/utils/QLogUtil.h" #include "common/utils/SettingConfig.h" -#include "common/utils/QKafkaUtil.h" +//#include "common/utils/QKafkaUtil.h" #include "protocol/PhaseProtocolBM.h" class PhaseDevice : public QObject @@ -25,15 +25,17 @@ void setBaudRate(int baudRate); QString getDevCode(); void setDevCode(QString devCode); + void setDeviceId(QString deviceId); bool isSerialOpen(); private: + QString deviceId; QString devCode; QString comName; int baudRate; QSerialPortUtil serialUtil; - QKafkaUtil kafkaUtil; +// QKafkaUtil kafkaUtil; QByteArray dataBuff; signals: diff --git a/PhaseCompAcq/PhaseWindow.cpp b/PhaseCompAcq/PhaseWindow.cpp index b3cab89..d0e8221 100644 --- a/PhaseCompAcq/PhaseWindow.cpp +++ b/PhaseCompAcq/PhaseWindow.cpp @@ -1,16 +1,16 @@ #include "PhaseWindow.h" #include "ui_PhaseWindow.h" -#include -#include -#include -#include -#include -#include - #include - -#include "common/utils/QKafkaUtil.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include PhaseWindow::PhaseWindow(QWidget *parent) : QWidget(parent), @@ -18,43 +18,74 @@ { ui->setupUi(this); - QString portNames = SettingConfig::getInstance().PORT_NAMES; - int baudRate = SettingConfig::getInstance().BAUD_RATE; - QString devCodes = SettingConfig::getInstance().DEV_CODES; + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); - QStringList comDevList = portNames.split(","); - QStringList devCodeList = devCodes.split(","); + // 窗口大小为占满一屏 + QRect screenRect = QApplication::desktop()->screenGeometry(); + resize(screenRect.width(), screenRect.height()); - for (int i = 0; i < comDevList.size(); i++) + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->line->setGeometry(0, 59, screenRect.width(), 1); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 60, screenRect.width(), screenRect.height() - 60); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + + httpReq = new HttpRequestController(this); + // 1. 获取访问接口需要的token + int retCode = this->initHttpToken(); + if (retCode != 200) { - PhaseDevice * device = new PhaseDevice(this); + QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); - // - connect(device, &PhaseDevice::sendDataToDraw, - this, &PhaseWindow::drawPhaseDataOnPage); + QTimer::singleShot(1000, qApp, SLOT(quit())); + } + // 2. 获取字典值:设备类型 + retCode = this->initDictDeviceTypes(); - device->setComName(comDevList.at(i)); - device->setBaudRate(baudRate); + // 3. 获取比相仪设备列表 + QJsonObject devListRes = this->initDeviceList(); + if (devListRes.find("code")->toInt() == 200) + { + ui->devSelect->clear(); - device->setDevCode(devCodeList.at(i)); + // 4. 将获取到的设备添加到下拉列表框中 + QJsonArray devArray = devListRes.find("data")->toArray(); + for (int i = 0; i < devArray.size(); i++) + { + QJsonObject devItem = devArray.at(i).toObject(); + ui->devSelect->addItem(devItem.find("deviceName")->toString(), devItem.find("deviceNo")->toString()); - this->deviceList.append(device); + PhaseDevice * device = new PhaseDevice(this); + deviceList.append(device); - device->initSerialPort(); - device->startWork(); + device->setComName(devItem.find("linkComName")->toString()); + device->setBaudRate(SettingConfig::getInstance().BAUD_RATE); + device->setDevCode(devItem.find("deviceNo")->toString()); + device->setDeviceId(devItem.find("deviceId")->toString()); + + connect(device, &PhaseDevice::sendDataToDraw, + this, &PhaseWindow::drawPhaseDataOnPage); + + device->initSerialPort(); + + QThread::msleep(100); + } + // 5. 设置下拉框的样式 + QStandardItemModel * model = qobject_cast(ui->devSelect->model()); + for (int i = 0; i < model->rowCount(); ++i) + { + QStandardItem * item = model->item(i); + item->setSizeHint({ 0, 30 }); + } } - for (int i = 0; i < this->deviceList.size(); i++) - { - QWidget * devWidget5 = new QWidget(this->ui->stackedWidget); - - this->ui->stackedWidget->addWidget(devWidget5); - - this->devWidgetList.append(devWidget5); - - // 创建设备的widget - this->generateWidgetForDevice(devCodeList.at(i), i); - } + // 6. 绘制一个设备的多个通道数据面板 + this->generateWidgetForDevice(); } PhaseWindow::~PhaseWindow() @@ -64,99 +95,119 @@ void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) { - // 1. 判断数据属于哪个设备,显示在不同的widget上 + // 当前显示的设备编号 + QString currentDevCode = ui->devSelect->currentData().toString(); - // 2. 循环设置各个tableView - QList devChannels = this->tableModelList.at(0); // 暂时写死 - for (int i = 0; i < phaseData->channelData.size(); i++) + // 如果不是当前设备的帧,直接返回 + if (phaseData->devCode != currentDevCode) { - if (phaseData->channelActive.at(i).toInt() == 1) - { - QList row; - QStandardItem * item = 0; - QStandardItem * item2 = 0; - item = new QStandardItem(QString("%1").arg(phaseData->timestamp.mid(11, 12))); - item2 = new QStandardItem(QString("%1").arg(phaseData->channelData.at(i))); + return; + } - row.append(item); - row.append(item2); + // 更新所有通道BOX的值 + for (int i = 0; i < phaseData->channelActive.size(); i++) + { + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); - QStandardItemModel * model; - model = devChannels.at(i); - if (model->rowCount() >= 60) - { - model->removeRows(0, model->rowCount()); - } - - model->insertRow(0, row); - } + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(phaseData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelData.at(i))); + ((QLineEdit *)channelBox->children().at(6))->setText(phaseData->frameId); + ((QLabel *)channelBox->children().at(7))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); } } -void PhaseWindow::generateWidgetForDevice(QString devCode, int index) +void PhaseWindow::generateWidgetForDevice() { - // 顶部切换widget - QWidget * switchWidget = new QWidget(this->devWidgetList.at(index)); - switchWidget->setGeometry(0, 0, 1024, 50); + // 获取设备数据 + int channelNum = 16; - // 显示数据的区域 - QWidget * gridWidget = new QWidget(this->devWidgetList.at(index)); - gridWidget->setGeometry(0, 50, 1024, 670); + QRect screenRect = QApplication::desktop()->screenGeometry(); - // 顶部水平布局,用于排布按钮 - QHBoxLayout * hLayout = new QHBoxLayout(switchWidget); + ui->scrollContents->setGeometry(0, 60, screenRect.width(), channelNum * 90); - // 文本 - QLabel * label = new QLabel(switchWidget); - label->setText("设备编号:" + devCode); - label->setFont(QFont("微软雅黑", 12)); - hLayout->addWidget(label); + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); - // 按钮 - for (int i = 0; i < this->deviceList.size(); i++) + for (int i = 0; i < channelNum; i++) { - QPushButton * butt5 = new QPushButton(this->deviceList.at(i)->getDevCode()); - hLayout->addWidget(butt5); + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 80 + 10, screenRect.width() - 40, 80); - connect(butt5, &QPushButton::clicked, [=](){ - this->ui->stackedWidget->setCurrentIndex(i); - }); + QHBoxLayout * vbox = new QHBoxLayout(group); + + QLabel * tmLabel = new QLabel(); + tmLabel->setText("时间"); + tmLabel->setFont(labelFont); + tmLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(tmLabel); + QLineEdit * tmValue = new QLineEdit(); + tmValue->setFixedWidth(200); + tmValue->setFont(labelFont); + vbox->addWidget(tmValue); + + QLabel * dataLabel = new QLabel(); + dataLabel->setText("测量数据"); + dataLabel->setFont(labelFont); + dataLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(dataLabel); + QLineEdit * dataValue = new QLineEdit(); + dataValue->setFixedWidth(150); + dataValue->setFont(labelFont); + vbox->addWidget(dataValue); + + QLabel * idLabel = new QLabel(); + idLabel->setText("数据ID"); + idLabel->setFont(labelFont); + idLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(idLabel); + QLineEdit * idValue = new QLineEdit(); + idValue->setFixedWidth(100); + idValue->setFont(labelFont); + vbox->addWidget(idValue); + + QLabel * validLabel = new QLabel(); + validLabel->setText("-"); + validLabel->setFont(labelFont); + validLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(validLabel); + + QSpacerItem * hSpace = new QSpacerItem(20, 20); + hSpace->changeSize(20, 20, QSizePolicy::Expanding); + vbox->addItem(hSpace); + + group->setLayout(vbox); + + layout->addWidget(group); } - - // Grid布局 - QGridLayout * gridLayout = new QGridLayout(gridWidget); - gridLayout->setSpacing(10); - - QList channelModelList; - QStringList labels = QObject::trUtf8("时间,相差").simplified().split(","); - - for (int i = 0; i < 16; i++) - { - QTableView * channelTable = new QTableView(gridWidget); - QStandardItemModel * model = new QStandardItemModel(channelTable); - - model->setHorizontalHeaderLabels(labels); - - channelTable->setModel(model); - - gridLayout->addWidget(channelTable, i / 4, i % 4); - - channelTable->verticalHeader()->hide(); - channelTable->setEditTriggers(QAbstractItemView::NoEditTriggers); - channelTable->scrollToBottom(); - - channelModelList.append(model); - } - - this->tableModelList.append(channelModelList); } -void PhaseWindow::createKafkaMessage() +int PhaseWindow::initHttpToken() { - this->kafkaUtil = new QKafkaUtil(this); - this->kafkaUtil->setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); - this->kafkaUtil->setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int PhaseWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject PhaseWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("比相仪"); + return response; +} - kafkaUtil->createProducer(); - kafkaUtil->produceMessage("hello world kafka kylin"); +void PhaseWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} + +void PhaseWindow::on_exitButt_clicked() +{ + QApplication::exit(0); } diff --git a/PhaseCompAcq/PhaseWindow.h b/PhaseCompAcq/PhaseWindow.h index 67b8363..02a7908 100644 --- a/PhaseCompAcq/PhaseWindow.h +++ b/PhaseCompAcq/PhaseWindow.h @@ -2,11 +2,13 @@ #define PHASEWINDOW_H #include +#include #include +#include #include "PhaseDevice.h" #include "common/utils/SettingConfig.h" -#include "common/utils/QKafkaUtil.h" +#include "common/HttpRequestController.h" namespace Ui { class PhaseWindow; @@ -23,18 +25,23 @@ public slots: void drawPhaseDataOnPage(PhaseDataDto * phaseData); +private slots: + void on_minButt_clicked(); + + void on_exitButt_clicked(); + private: + int initHttpToken(); + int initDictDeviceTypes(); + QJsonObject initDeviceList(); + Ui::PhaseWindow *ui; - QList devWidgetList; + HttpRequestController * httpReq; QList deviceList; - QList> tableModelList; - QKafkaUtil * kafkaUtil; - - void generateWidgetForDevice(QString devCode, int index); - void createKafkaMessage(); + void generateWidgetForDevice(); }; #endif // PHASEWINDOW_H diff --git a/PhaseCompAcq/PhaseWindow.ui b/PhaseCompAcq/PhaseWindow.ui index e6da880..01a7759 100644 --- a/PhaseCompAcq/PhaseWindow.ui +++ b/PhaseCompAcq/PhaseWindow.ui @@ -10,26 +10,144 @@ 720 - - - 1024 - 720 - - 多通道比相仪数据采集 - + 0 0 - 1024 - 720 + 100 + 30 - - -1 + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 100 + 30 + + + + + + + + 400 + 10 + 250 + 40 + + + + + + + 250 + 0 + 150 + 60 + + + + + 微软雅黑 + 12 + + + + Qt::LeftToRight + + + 请选择比相仪 + + + Qt::AlignCenter + + + + + + 880 + 10 + 40 + 40 + + + + + + + 退出 + + + + + + 20 + 0 + 200 + 60 + + + + + 微软雅黑 + 14 + + + + 多通道比相仪数据采集 + + + + + + 0 + 59 + 1024 + 1 + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + 830 + 10 + 40 + 40 + + + + + + + 最小化 diff --git a/PhaseCompAcq/common/ConstCache.h b/PhaseCompAcq/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/PhaseCompAcq/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/PhaseCompAcq/common/HttpRequestController.cpp b/PhaseCompAcq/common/HttpRequestController.cpp new file mode 100644 index 0000000..6abb5af --- /dev/null +++ b/PhaseCompAcq/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceTypes.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDeviceList(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", system.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); + } + + qDebug() << resultObj; + + return resultObj; +} diff --git a/PhaseCompAcq/common/HttpRequestController.h b/PhaseCompAcq/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/PhaseCompAcq/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/PhaseCompAcq/common/common.pri b/PhaseCompAcq/common/common.pri index 055a2db..84f57ae 100644 --- a/PhaseCompAcq/common/common.pri +++ b/PhaseCompAcq/common/common.pri @@ -3,10 +3,18 @@ SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp -SOURCES += $$PWD/utils/QKafkaUtil.cpp +#SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp HEADERS += $$PWD/utils/SettingConfig.h HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h -HEADERS += $$PWD/utils/QKafkaUtil.h +#HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/PhaseCompAcq/common/utils/DefHead.h b/PhaseCompAcq/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/PhaseCompAcq/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/PhaseCompAcq/common/utils/HttpRequestUtil.cpp b/PhaseCompAcq/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/PhaseCompAcq/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/PhaseCompAcq/common/utils/HttpRequestUtil.h b/PhaseCompAcq/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/PhaseCompAcq/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/PhaseCompAcq/common/utils/MD5.cpp b/PhaseCompAcq/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/PhaseCompAcq/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/CounterAcq/CounterAcq.pro b/CounterAcq/CounterAcq.pro index 72407cd..fae9d10 100644 --- a/CounterAcq/CounterAcq.pro +++ b/CounterAcq/CounterAcq.pro @@ -4,13 +4,6 @@ CONFIG += c++11 -SOURCES += \ - CounterWindow.cpp \ - main.cpp \ - -HEADERS += \ - CounterWindow.h \ - FORMS += \ CounterWindow.ui \ @@ -18,8 +11,11 @@ include(protocol/protocol.pri) HEADERS += CounterDevice.h +HEADERS += CounterWindow.h SOURCES += CounterDevice.cpp +SOURCES += CounterWindow.cpp +SOURCES += main.cpp DISTFILES += conf/config.ini diff --git a/CounterAcq/CounterWindow.cpp b/CounterAcq/CounterWindow.cpp index 80035a9..a50ebcf 100644 --- a/CounterAcq/CounterWindow.cpp +++ b/CounterAcq/CounterWindow.cpp @@ -42,7 +42,7 @@ { QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); - QApplication::exit(0); + QTimer::singleShot(1000, qApp, SLOT(quit())); } // 2. 获取字典值:设备类型 retCode = this->initDictDeviceTypes(); diff --git a/CounterAcq/CounterWindow.h b/CounterAcq/CounterWindow.h index 8d5e4a6..09277ba 100644 --- a/CounterAcq/CounterWindow.h +++ b/CounterAcq/CounterWindow.h @@ -7,7 +7,6 @@ #include #include "common/utils/SettingConfig.h" -#include "common/utils/QKafkaUtil.h" #include "common/HttpRequestController.h" #include "CounterDevice.h" @@ -23,8 +22,6 @@ explicit CounterWindow(QWidget *parent = nullptr); ~CounterWindow(); - QString token; - public slots: void drawCounterDataOnPage(CounterDataDto * counterData); @@ -40,7 +37,6 @@ Ui::CounterWindow *ui; - QTimer * timer; HttpRequestController * httpReq; QList deviceList; diff --git a/PhaseCompAcq/PhaseCompAcq.pro b/PhaseCompAcq/PhaseCompAcq.pro index 5eef2d1..c5e895b 100644 --- a/PhaseCompAcq/PhaseCompAcq.pro +++ b/PhaseCompAcq/PhaseCompAcq.pro @@ -1,16 +1,9 @@ -QT += core gui serialport +QT += core gui serialport network greaterThan(QT_MAJOR_VERSION, 4): QT += widgets CONFIG += c++11 -SOURCES += \ - main.cpp \ - PhaseWindow.cpp - -HEADERS += \ - PhaseWindow.h - FORMS += \ PhaseWindow.ui @@ -18,20 +11,19 @@ include(protocol/protocol.pri) HEADERS += PhaseDevice.h -#HEADERS += PhaseSerialServer.h +HEADERS += PhaseWindow.h SOURCES += PhaseDevice.cpp -#SOURCES += PhaseSerialServer.cpp +SOURCES += PhaseWindow.cpp +SOURCES += main.cpp # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target - -INCLUDEPATH += $$PWD/include/librdkafka -DEPENDPATH += $$PWD/include/librdkafka +#unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +#INCLUDEPATH += $$PWD/include/librdkafka +#DEPENDPATH += $$PWD/include/librdkafka DISTFILES += conf/config.ini - -unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ diff --git a/PhaseCompAcq/PhaseDevice.cpp b/PhaseCompAcq/PhaseDevice.cpp index 5c84cd5..afc2687 100644 --- a/PhaseCompAcq/PhaseDevice.cpp +++ b/PhaseCompAcq/PhaseDevice.cpp @@ -7,9 +7,9 @@ connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, this, &PhaseDevice::dataReceivedHandler); - kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); - kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); - kafkaUtil.createProducer(); +// kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); +// kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); +// kafkaUtil.createProducer(); } PhaseDevice::~PhaseDevice() @@ -34,6 +34,10 @@ { this->devCode = devCode; } +void PhaseDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} bool PhaseDevice::isSerialOpen() { @@ -74,6 +78,7 @@ if (parse == true) { QDateTime now = QDateTime::currentDateTime(); + phaseData->devCode = this->devCode; phaseData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); phaseData->milisecond = now.toMSecsSinceEpoch(); this->afterFramePhase(phaseData); @@ -92,21 +97,20 @@ this->dataBuff.clear(); // 2. 输出到日志文件中 - QString filePostfix = phaseData->timestamp.mid(0, 13).replace(" ", "_"); - QString filePrefix = QApplication::applicationDirPath() + "/logs/"; + QString date = phaseData->timestamp.mid(0, 10); // 2.1 原始字节数组数据 - QString filename = filePrefix + "raw_" + filePostfix + ".log"; + QString filename = "raw_" + devCode + ".log"; QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); - QLogUtil::writeRawDataLog(filename, content); + QLogUtil::writeRawDataLogByDate(date, filename, content); // 2.2 各个通道的相差数据 for (int i = 1; i <= phaseData->channelActive.size(); i++) { if (phaseData->channelActive.at(i-1).toUInt() == 1) { - QString chFilename("%1CH_%2_%3.log"); - chFilename = chFilename.arg(filePrefix); + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); if (i < 10) { chFilename = chFilename.arg(QString("0%1").arg(i)); @@ -114,10 +118,9 @@ { chFilename = chFilename.arg(i); } - chFilename = chFilename.arg(filePostfix); - QString channelDataStr = QString("%1 %2 %3").arg(phaseData->timestamp).arg(phaseData->channelData.at(i-1)).arg(phaseData->frameId); + QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelData.at(i-1)); - QLogUtil::writeChannelDataLog(chFilename, channelDataStr); + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); // 3. 输出到中间件,执行后续处理过程 if (SettingConfig::getInstance().NEED_KAFKA == 1) @@ -125,7 +128,7 @@ QJsonObject jsonObj = phaseData->toJSON(i - 1); jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); jsonObj.insert("deviceId", devCode); - kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); +// kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); } } } diff --git a/PhaseCompAcq/PhaseDevice.h b/PhaseCompAcq/PhaseDevice.h index 92182d4..aa7d822 100644 --- a/PhaseCompAcq/PhaseDevice.h +++ b/PhaseCompAcq/PhaseDevice.h @@ -5,7 +5,7 @@ #include "common/utils/QSerialPortUtil.h" #include "common/utils/QLogUtil.h" #include "common/utils/SettingConfig.h" -#include "common/utils/QKafkaUtil.h" +//#include "common/utils/QKafkaUtil.h" #include "protocol/PhaseProtocolBM.h" class PhaseDevice : public QObject @@ -25,15 +25,17 @@ void setBaudRate(int baudRate); QString getDevCode(); void setDevCode(QString devCode); + void setDeviceId(QString deviceId); bool isSerialOpen(); private: + QString deviceId; QString devCode; QString comName; int baudRate; QSerialPortUtil serialUtil; - QKafkaUtil kafkaUtil; +// QKafkaUtil kafkaUtil; QByteArray dataBuff; signals: diff --git a/PhaseCompAcq/PhaseWindow.cpp b/PhaseCompAcq/PhaseWindow.cpp index b3cab89..d0e8221 100644 --- a/PhaseCompAcq/PhaseWindow.cpp +++ b/PhaseCompAcq/PhaseWindow.cpp @@ -1,16 +1,16 @@ #include "PhaseWindow.h" #include "ui_PhaseWindow.h" -#include -#include -#include -#include -#include -#include - #include - -#include "common/utils/QKafkaUtil.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include PhaseWindow::PhaseWindow(QWidget *parent) : QWidget(parent), @@ -18,43 +18,74 @@ { ui->setupUi(this); - QString portNames = SettingConfig::getInstance().PORT_NAMES; - int baudRate = SettingConfig::getInstance().BAUD_RATE; - QString devCodes = SettingConfig::getInstance().DEV_CODES; + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); - QStringList comDevList = portNames.split(","); - QStringList devCodeList = devCodes.split(","); + // 窗口大小为占满一屏 + QRect screenRect = QApplication::desktop()->screenGeometry(); + resize(screenRect.width(), screenRect.height()); - for (int i = 0; i < comDevList.size(); i++) + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->line->setGeometry(0, 59, screenRect.width(), 1); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 60, screenRect.width(), screenRect.height() - 60); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + + httpReq = new HttpRequestController(this); + // 1. 获取访问接口需要的token + int retCode = this->initHttpToken(); + if (retCode != 200) { - PhaseDevice * device = new PhaseDevice(this); + QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); - // - connect(device, &PhaseDevice::sendDataToDraw, - this, &PhaseWindow::drawPhaseDataOnPage); + QTimer::singleShot(1000, qApp, SLOT(quit())); + } + // 2. 获取字典值:设备类型 + retCode = this->initDictDeviceTypes(); - device->setComName(comDevList.at(i)); - device->setBaudRate(baudRate); + // 3. 获取比相仪设备列表 + QJsonObject devListRes = this->initDeviceList(); + if (devListRes.find("code")->toInt() == 200) + { + ui->devSelect->clear(); - device->setDevCode(devCodeList.at(i)); + // 4. 将获取到的设备添加到下拉列表框中 + QJsonArray devArray = devListRes.find("data")->toArray(); + for (int i = 0; i < devArray.size(); i++) + { + QJsonObject devItem = devArray.at(i).toObject(); + ui->devSelect->addItem(devItem.find("deviceName")->toString(), devItem.find("deviceNo")->toString()); - this->deviceList.append(device); + PhaseDevice * device = new PhaseDevice(this); + deviceList.append(device); - device->initSerialPort(); - device->startWork(); + device->setComName(devItem.find("linkComName")->toString()); + device->setBaudRate(SettingConfig::getInstance().BAUD_RATE); + device->setDevCode(devItem.find("deviceNo")->toString()); + device->setDeviceId(devItem.find("deviceId")->toString()); + + connect(device, &PhaseDevice::sendDataToDraw, + this, &PhaseWindow::drawPhaseDataOnPage); + + device->initSerialPort(); + + QThread::msleep(100); + } + // 5. 设置下拉框的样式 + QStandardItemModel * model = qobject_cast(ui->devSelect->model()); + for (int i = 0; i < model->rowCount(); ++i) + { + QStandardItem * item = model->item(i); + item->setSizeHint({ 0, 30 }); + } } - for (int i = 0; i < this->deviceList.size(); i++) - { - QWidget * devWidget5 = new QWidget(this->ui->stackedWidget); - - this->ui->stackedWidget->addWidget(devWidget5); - - this->devWidgetList.append(devWidget5); - - // 创建设备的widget - this->generateWidgetForDevice(devCodeList.at(i), i); - } + // 6. 绘制一个设备的多个通道数据面板 + this->generateWidgetForDevice(); } PhaseWindow::~PhaseWindow() @@ -64,99 +95,119 @@ void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) { - // 1. 判断数据属于哪个设备,显示在不同的widget上 + // 当前显示的设备编号 + QString currentDevCode = ui->devSelect->currentData().toString(); - // 2. 循环设置各个tableView - QList devChannels = this->tableModelList.at(0); // 暂时写死 - for (int i = 0; i < phaseData->channelData.size(); i++) + // 如果不是当前设备的帧,直接返回 + if (phaseData->devCode != currentDevCode) { - if (phaseData->channelActive.at(i).toInt() == 1) - { - QList row; - QStandardItem * item = 0; - QStandardItem * item2 = 0; - item = new QStandardItem(QString("%1").arg(phaseData->timestamp.mid(11, 12))); - item2 = new QStandardItem(QString("%1").arg(phaseData->channelData.at(i))); + return; + } - row.append(item); - row.append(item2); + // 更新所有通道BOX的值 + for (int i = 0; i < phaseData->channelActive.size(); i++) + { + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); - QStandardItemModel * model; - model = devChannels.at(i); - if (model->rowCount() >= 60) - { - model->removeRows(0, model->rowCount()); - } - - model->insertRow(0, row); - } + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(phaseData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelData.at(i))); + ((QLineEdit *)channelBox->children().at(6))->setText(phaseData->frameId); + ((QLabel *)channelBox->children().at(7))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); } } -void PhaseWindow::generateWidgetForDevice(QString devCode, int index) +void PhaseWindow::generateWidgetForDevice() { - // 顶部切换widget - QWidget * switchWidget = new QWidget(this->devWidgetList.at(index)); - switchWidget->setGeometry(0, 0, 1024, 50); + // 获取设备数据 + int channelNum = 16; - // 显示数据的区域 - QWidget * gridWidget = new QWidget(this->devWidgetList.at(index)); - gridWidget->setGeometry(0, 50, 1024, 670); + QRect screenRect = QApplication::desktop()->screenGeometry(); - // 顶部水平布局,用于排布按钮 - QHBoxLayout * hLayout = new QHBoxLayout(switchWidget); + ui->scrollContents->setGeometry(0, 60, screenRect.width(), channelNum * 90); - // 文本 - QLabel * label = new QLabel(switchWidget); - label->setText("设备编号:" + devCode); - label->setFont(QFont("微软雅黑", 12)); - hLayout->addWidget(label); + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); - // 按钮 - for (int i = 0; i < this->deviceList.size(); i++) + for (int i = 0; i < channelNum; i++) { - QPushButton * butt5 = new QPushButton(this->deviceList.at(i)->getDevCode()); - hLayout->addWidget(butt5); + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 80 + 10, screenRect.width() - 40, 80); - connect(butt5, &QPushButton::clicked, [=](){ - this->ui->stackedWidget->setCurrentIndex(i); - }); + QHBoxLayout * vbox = new QHBoxLayout(group); + + QLabel * tmLabel = new QLabel(); + tmLabel->setText("时间"); + tmLabel->setFont(labelFont); + tmLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(tmLabel); + QLineEdit * tmValue = new QLineEdit(); + tmValue->setFixedWidth(200); + tmValue->setFont(labelFont); + vbox->addWidget(tmValue); + + QLabel * dataLabel = new QLabel(); + dataLabel->setText("测量数据"); + dataLabel->setFont(labelFont); + dataLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(dataLabel); + QLineEdit * dataValue = new QLineEdit(); + dataValue->setFixedWidth(150); + dataValue->setFont(labelFont); + vbox->addWidget(dataValue); + + QLabel * idLabel = new QLabel(); + idLabel->setText("数据ID"); + idLabel->setFont(labelFont); + idLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(idLabel); + QLineEdit * idValue = new QLineEdit(); + idValue->setFixedWidth(100); + idValue->setFont(labelFont); + vbox->addWidget(idValue); + + QLabel * validLabel = new QLabel(); + validLabel->setText("-"); + validLabel->setFont(labelFont); + validLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(validLabel); + + QSpacerItem * hSpace = new QSpacerItem(20, 20); + hSpace->changeSize(20, 20, QSizePolicy::Expanding); + vbox->addItem(hSpace); + + group->setLayout(vbox); + + layout->addWidget(group); } - - // Grid布局 - QGridLayout * gridLayout = new QGridLayout(gridWidget); - gridLayout->setSpacing(10); - - QList channelModelList; - QStringList labels = QObject::trUtf8("时间,相差").simplified().split(","); - - for (int i = 0; i < 16; i++) - { - QTableView * channelTable = new QTableView(gridWidget); - QStandardItemModel * model = new QStandardItemModel(channelTable); - - model->setHorizontalHeaderLabels(labels); - - channelTable->setModel(model); - - gridLayout->addWidget(channelTable, i / 4, i % 4); - - channelTable->verticalHeader()->hide(); - channelTable->setEditTriggers(QAbstractItemView::NoEditTriggers); - channelTable->scrollToBottom(); - - channelModelList.append(model); - } - - this->tableModelList.append(channelModelList); } -void PhaseWindow::createKafkaMessage() +int PhaseWindow::initHttpToken() { - this->kafkaUtil = new QKafkaUtil(this); - this->kafkaUtil->setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); - this->kafkaUtil->setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int PhaseWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject PhaseWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("比相仪"); + return response; +} - kafkaUtil->createProducer(); - kafkaUtil->produceMessage("hello world kafka kylin"); +void PhaseWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} + +void PhaseWindow::on_exitButt_clicked() +{ + QApplication::exit(0); } diff --git a/PhaseCompAcq/PhaseWindow.h b/PhaseCompAcq/PhaseWindow.h index 67b8363..02a7908 100644 --- a/PhaseCompAcq/PhaseWindow.h +++ b/PhaseCompAcq/PhaseWindow.h @@ -2,11 +2,13 @@ #define PHASEWINDOW_H #include +#include #include +#include #include "PhaseDevice.h" #include "common/utils/SettingConfig.h" -#include "common/utils/QKafkaUtil.h" +#include "common/HttpRequestController.h" namespace Ui { class PhaseWindow; @@ -23,18 +25,23 @@ public slots: void drawPhaseDataOnPage(PhaseDataDto * phaseData); +private slots: + void on_minButt_clicked(); + + void on_exitButt_clicked(); + private: + int initHttpToken(); + int initDictDeviceTypes(); + QJsonObject initDeviceList(); + Ui::PhaseWindow *ui; - QList devWidgetList; + HttpRequestController * httpReq; QList deviceList; - QList> tableModelList; - QKafkaUtil * kafkaUtil; - - void generateWidgetForDevice(QString devCode, int index); - void createKafkaMessage(); + void generateWidgetForDevice(); }; #endif // PHASEWINDOW_H diff --git a/PhaseCompAcq/PhaseWindow.ui b/PhaseCompAcq/PhaseWindow.ui index e6da880..01a7759 100644 --- a/PhaseCompAcq/PhaseWindow.ui +++ b/PhaseCompAcq/PhaseWindow.ui @@ -10,26 +10,144 @@ 720 - - - 1024 - 720 - - 多通道比相仪数据采集 - + 0 0 - 1024 - 720 + 100 + 30 - - -1 + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 100 + 30 + + + + + + + + 400 + 10 + 250 + 40 + + + + + + + 250 + 0 + 150 + 60 + + + + + 微软雅黑 + 12 + + + + Qt::LeftToRight + + + 请选择比相仪 + + + Qt::AlignCenter + + + + + + 880 + 10 + 40 + 40 + + + + + + + 退出 + + + + + + 20 + 0 + 200 + 60 + + + + + 微软雅黑 + 14 + + + + 多通道比相仪数据采集 + + + + + + 0 + 59 + 1024 + 1 + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + 830 + 10 + 40 + 40 + + + + + + + 最小化 diff --git a/PhaseCompAcq/common/ConstCache.h b/PhaseCompAcq/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/PhaseCompAcq/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/PhaseCompAcq/common/HttpRequestController.cpp b/PhaseCompAcq/common/HttpRequestController.cpp new file mode 100644 index 0000000..6abb5af --- /dev/null +++ b/PhaseCompAcq/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceTypes.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDeviceList(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", system.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); + } + + qDebug() << resultObj; + + return resultObj; +} diff --git a/PhaseCompAcq/common/HttpRequestController.h b/PhaseCompAcq/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/PhaseCompAcq/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/PhaseCompAcq/common/common.pri b/PhaseCompAcq/common/common.pri index 055a2db..84f57ae 100644 --- a/PhaseCompAcq/common/common.pri +++ b/PhaseCompAcq/common/common.pri @@ -3,10 +3,18 @@ SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp -SOURCES += $$PWD/utils/QKafkaUtil.cpp +#SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp HEADERS += $$PWD/utils/SettingConfig.h HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h -HEADERS += $$PWD/utils/QKafkaUtil.h +#HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/PhaseCompAcq/common/utils/DefHead.h b/PhaseCompAcq/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/PhaseCompAcq/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/PhaseCompAcq/common/utils/HttpRequestUtil.cpp b/PhaseCompAcq/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/PhaseCompAcq/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/PhaseCompAcq/common/utils/HttpRequestUtil.h b/PhaseCompAcq/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/PhaseCompAcq/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/PhaseCompAcq/common/utils/MD5.cpp b/PhaseCompAcq/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/PhaseCompAcq/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/PhaseCompAcq/common/utils/MD5.h b/PhaseCompAcq/common/utils/MD5.h new file mode 100644 index 0000000..5d86d32 --- /dev/null +++ b/PhaseCompAcq/common/utils/MD5.h @@ -0,0 +1,33 @@ +#ifndef MD5_H +#define MD5_H + +#include +#include +#include +#include"DefHead.h" + +#define SHORT_MD5_LEN 16 +#define CHAR_MD5_LEN 34 + + +class MD5 +{ +public: + explicit MD5(); + static void MD5Encode + ( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst + ); + + static bool MD5StrValidate + ( + _In_ const char* input1, + _In_ const char* input2 + ); +private: + ; +}; + +#endif // !MD5_H diff --git a/CounterAcq/CounterAcq.pro b/CounterAcq/CounterAcq.pro index 72407cd..fae9d10 100644 --- a/CounterAcq/CounterAcq.pro +++ b/CounterAcq/CounterAcq.pro @@ -4,13 +4,6 @@ CONFIG += c++11 -SOURCES += \ - CounterWindow.cpp \ - main.cpp \ - -HEADERS += \ - CounterWindow.h \ - FORMS += \ CounterWindow.ui \ @@ -18,8 +11,11 @@ include(protocol/protocol.pri) HEADERS += CounterDevice.h +HEADERS += CounterWindow.h SOURCES += CounterDevice.cpp +SOURCES += CounterWindow.cpp +SOURCES += main.cpp DISTFILES += conf/config.ini diff --git a/CounterAcq/CounterWindow.cpp b/CounterAcq/CounterWindow.cpp index 80035a9..a50ebcf 100644 --- a/CounterAcq/CounterWindow.cpp +++ b/CounterAcq/CounterWindow.cpp @@ -42,7 +42,7 @@ { QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); - QApplication::exit(0); + QTimer::singleShot(1000, qApp, SLOT(quit())); } // 2. 获取字典值:设备类型 retCode = this->initDictDeviceTypes(); diff --git a/CounterAcq/CounterWindow.h b/CounterAcq/CounterWindow.h index 8d5e4a6..09277ba 100644 --- a/CounterAcq/CounterWindow.h +++ b/CounterAcq/CounterWindow.h @@ -7,7 +7,6 @@ #include #include "common/utils/SettingConfig.h" -#include "common/utils/QKafkaUtil.h" #include "common/HttpRequestController.h" #include "CounterDevice.h" @@ -23,8 +22,6 @@ explicit CounterWindow(QWidget *parent = nullptr); ~CounterWindow(); - QString token; - public slots: void drawCounterDataOnPage(CounterDataDto * counterData); @@ -40,7 +37,6 @@ Ui::CounterWindow *ui; - QTimer * timer; HttpRequestController * httpReq; QList deviceList; diff --git a/PhaseCompAcq/PhaseCompAcq.pro b/PhaseCompAcq/PhaseCompAcq.pro index 5eef2d1..c5e895b 100644 --- a/PhaseCompAcq/PhaseCompAcq.pro +++ b/PhaseCompAcq/PhaseCompAcq.pro @@ -1,16 +1,9 @@ -QT += core gui serialport +QT += core gui serialport network greaterThan(QT_MAJOR_VERSION, 4): QT += widgets CONFIG += c++11 -SOURCES += \ - main.cpp \ - PhaseWindow.cpp - -HEADERS += \ - PhaseWindow.h - FORMS += \ PhaseWindow.ui @@ -18,20 +11,19 @@ include(protocol/protocol.pri) HEADERS += PhaseDevice.h -#HEADERS += PhaseSerialServer.h +HEADERS += PhaseWindow.h SOURCES += PhaseDevice.cpp -#SOURCES += PhaseSerialServer.cpp +SOURCES += PhaseWindow.cpp +SOURCES += main.cpp # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target - -INCLUDEPATH += $$PWD/include/librdkafka -DEPENDPATH += $$PWD/include/librdkafka +#unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +#INCLUDEPATH += $$PWD/include/librdkafka +#DEPENDPATH += $$PWD/include/librdkafka DISTFILES += conf/config.ini - -unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ diff --git a/PhaseCompAcq/PhaseDevice.cpp b/PhaseCompAcq/PhaseDevice.cpp index 5c84cd5..afc2687 100644 --- a/PhaseCompAcq/PhaseDevice.cpp +++ b/PhaseCompAcq/PhaseDevice.cpp @@ -7,9 +7,9 @@ connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, this, &PhaseDevice::dataReceivedHandler); - kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); - kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); - kafkaUtil.createProducer(); +// kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); +// kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); +// kafkaUtil.createProducer(); } PhaseDevice::~PhaseDevice() @@ -34,6 +34,10 @@ { this->devCode = devCode; } +void PhaseDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} bool PhaseDevice::isSerialOpen() { @@ -74,6 +78,7 @@ if (parse == true) { QDateTime now = QDateTime::currentDateTime(); + phaseData->devCode = this->devCode; phaseData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); phaseData->milisecond = now.toMSecsSinceEpoch(); this->afterFramePhase(phaseData); @@ -92,21 +97,20 @@ this->dataBuff.clear(); // 2. 输出到日志文件中 - QString filePostfix = phaseData->timestamp.mid(0, 13).replace(" ", "_"); - QString filePrefix = QApplication::applicationDirPath() + "/logs/"; + QString date = phaseData->timestamp.mid(0, 10); // 2.1 原始字节数组数据 - QString filename = filePrefix + "raw_" + filePostfix + ".log"; + QString filename = "raw_" + devCode + ".log"; QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); - QLogUtil::writeRawDataLog(filename, content); + QLogUtil::writeRawDataLogByDate(date, filename, content); // 2.2 各个通道的相差数据 for (int i = 1; i <= phaseData->channelActive.size(); i++) { if (phaseData->channelActive.at(i-1).toUInt() == 1) { - QString chFilename("%1CH_%2_%3.log"); - chFilename = chFilename.arg(filePrefix); + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); if (i < 10) { chFilename = chFilename.arg(QString("0%1").arg(i)); @@ -114,10 +118,9 @@ { chFilename = chFilename.arg(i); } - chFilename = chFilename.arg(filePostfix); - QString channelDataStr = QString("%1 %2 %3").arg(phaseData->timestamp).arg(phaseData->channelData.at(i-1)).arg(phaseData->frameId); + QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelData.at(i-1)); - QLogUtil::writeChannelDataLog(chFilename, channelDataStr); + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); // 3. 输出到中间件,执行后续处理过程 if (SettingConfig::getInstance().NEED_KAFKA == 1) @@ -125,7 +128,7 @@ QJsonObject jsonObj = phaseData->toJSON(i - 1); jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); jsonObj.insert("deviceId", devCode); - kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); +// kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); } } } diff --git a/PhaseCompAcq/PhaseDevice.h b/PhaseCompAcq/PhaseDevice.h index 92182d4..aa7d822 100644 --- a/PhaseCompAcq/PhaseDevice.h +++ b/PhaseCompAcq/PhaseDevice.h @@ -5,7 +5,7 @@ #include "common/utils/QSerialPortUtil.h" #include "common/utils/QLogUtil.h" #include "common/utils/SettingConfig.h" -#include "common/utils/QKafkaUtil.h" +//#include "common/utils/QKafkaUtil.h" #include "protocol/PhaseProtocolBM.h" class PhaseDevice : public QObject @@ -25,15 +25,17 @@ void setBaudRate(int baudRate); QString getDevCode(); void setDevCode(QString devCode); + void setDeviceId(QString deviceId); bool isSerialOpen(); private: + QString deviceId; QString devCode; QString comName; int baudRate; QSerialPortUtil serialUtil; - QKafkaUtil kafkaUtil; +// QKafkaUtil kafkaUtil; QByteArray dataBuff; signals: diff --git a/PhaseCompAcq/PhaseWindow.cpp b/PhaseCompAcq/PhaseWindow.cpp index b3cab89..d0e8221 100644 --- a/PhaseCompAcq/PhaseWindow.cpp +++ b/PhaseCompAcq/PhaseWindow.cpp @@ -1,16 +1,16 @@ #include "PhaseWindow.h" #include "ui_PhaseWindow.h" -#include -#include -#include -#include -#include -#include - #include - -#include "common/utils/QKafkaUtil.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include PhaseWindow::PhaseWindow(QWidget *parent) : QWidget(parent), @@ -18,43 +18,74 @@ { ui->setupUi(this); - QString portNames = SettingConfig::getInstance().PORT_NAMES; - int baudRate = SettingConfig::getInstance().BAUD_RATE; - QString devCodes = SettingConfig::getInstance().DEV_CODES; + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); - QStringList comDevList = portNames.split(","); - QStringList devCodeList = devCodes.split(","); + // 窗口大小为占满一屏 + QRect screenRect = QApplication::desktop()->screenGeometry(); + resize(screenRect.width(), screenRect.height()); - for (int i = 0; i < comDevList.size(); i++) + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->line->setGeometry(0, 59, screenRect.width(), 1); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 60, screenRect.width(), screenRect.height() - 60); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + + httpReq = new HttpRequestController(this); + // 1. 获取访问接口需要的token + int retCode = this->initHttpToken(); + if (retCode != 200) { - PhaseDevice * device = new PhaseDevice(this); + QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); - // - connect(device, &PhaseDevice::sendDataToDraw, - this, &PhaseWindow::drawPhaseDataOnPage); + QTimer::singleShot(1000, qApp, SLOT(quit())); + } + // 2. 获取字典值:设备类型 + retCode = this->initDictDeviceTypes(); - device->setComName(comDevList.at(i)); - device->setBaudRate(baudRate); + // 3. 获取比相仪设备列表 + QJsonObject devListRes = this->initDeviceList(); + if (devListRes.find("code")->toInt() == 200) + { + ui->devSelect->clear(); - device->setDevCode(devCodeList.at(i)); + // 4. 将获取到的设备添加到下拉列表框中 + QJsonArray devArray = devListRes.find("data")->toArray(); + for (int i = 0; i < devArray.size(); i++) + { + QJsonObject devItem = devArray.at(i).toObject(); + ui->devSelect->addItem(devItem.find("deviceName")->toString(), devItem.find("deviceNo")->toString()); - this->deviceList.append(device); + PhaseDevice * device = new PhaseDevice(this); + deviceList.append(device); - device->initSerialPort(); - device->startWork(); + device->setComName(devItem.find("linkComName")->toString()); + device->setBaudRate(SettingConfig::getInstance().BAUD_RATE); + device->setDevCode(devItem.find("deviceNo")->toString()); + device->setDeviceId(devItem.find("deviceId")->toString()); + + connect(device, &PhaseDevice::sendDataToDraw, + this, &PhaseWindow::drawPhaseDataOnPage); + + device->initSerialPort(); + + QThread::msleep(100); + } + // 5. 设置下拉框的样式 + QStandardItemModel * model = qobject_cast(ui->devSelect->model()); + for (int i = 0; i < model->rowCount(); ++i) + { + QStandardItem * item = model->item(i); + item->setSizeHint({ 0, 30 }); + } } - for (int i = 0; i < this->deviceList.size(); i++) - { - QWidget * devWidget5 = new QWidget(this->ui->stackedWidget); - - this->ui->stackedWidget->addWidget(devWidget5); - - this->devWidgetList.append(devWidget5); - - // 创建设备的widget - this->generateWidgetForDevice(devCodeList.at(i), i); - } + // 6. 绘制一个设备的多个通道数据面板 + this->generateWidgetForDevice(); } PhaseWindow::~PhaseWindow() @@ -64,99 +95,119 @@ void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) { - // 1. 判断数据属于哪个设备,显示在不同的widget上 + // 当前显示的设备编号 + QString currentDevCode = ui->devSelect->currentData().toString(); - // 2. 循环设置各个tableView - QList devChannels = this->tableModelList.at(0); // 暂时写死 - for (int i = 0; i < phaseData->channelData.size(); i++) + // 如果不是当前设备的帧,直接返回 + if (phaseData->devCode != currentDevCode) { - if (phaseData->channelActive.at(i).toInt() == 1) - { - QList row; - QStandardItem * item = 0; - QStandardItem * item2 = 0; - item = new QStandardItem(QString("%1").arg(phaseData->timestamp.mid(11, 12))); - item2 = new QStandardItem(QString("%1").arg(phaseData->channelData.at(i))); + return; + } - row.append(item); - row.append(item2); + // 更新所有通道BOX的值 + for (int i = 0; i < phaseData->channelActive.size(); i++) + { + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); - QStandardItemModel * model; - model = devChannels.at(i); - if (model->rowCount() >= 60) - { - model->removeRows(0, model->rowCount()); - } - - model->insertRow(0, row); - } + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(phaseData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelData.at(i))); + ((QLineEdit *)channelBox->children().at(6))->setText(phaseData->frameId); + ((QLabel *)channelBox->children().at(7))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); } } -void PhaseWindow::generateWidgetForDevice(QString devCode, int index) +void PhaseWindow::generateWidgetForDevice() { - // 顶部切换widget - QWidget * switchWidget = new QWidget(this->devWidgetList.at(index)); - switchWidget->setGeometry(0, 0, 1024, 50); + // 获取设备数据 + int channelNum = 16; - // 显示数据的区域 - QWidget * gridWidget = new QWidget(this->devWidgetList.at(index)); - gridWidget->setGeometry(0, 50, 1024, 670); + QRect screenRect = QApplication::desktop()->screenGeometry(); - // 顶部水平布局,用于排布按钮 - QHBoxLayout * hLayout = new QHBoxLayout(switchWidget); + ui->scrollContents->setGeometry(0, 60, screenRect.width(), channelNum * 90); - // 文本 - QLabel * label = new QLabel(switchWidget); - label->setText("设备编号:" + devCode); - label->setFont(QFont("微软雅黑", 12)); - hLayout->addWidget(label); + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); - // 按钮 - for (int i = 0; i < this->deviceList.size(); i++) + for (int i = 0; i < channelNum; i++) { - QPushButton * butt5 = new QPushButton(this->deviceList.at(i)->getDevCode()); - hLayout->addWidget(butt5); + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 80 + 10, screenRect.width() - 40, 80); - connect(butt5, &QPushButton::clicked, [=](){ - this->ui->stackedWidget->setCurrentIndex(i); - }); + QHBoxLayout * vbox = new QHBoxLayout(group); + + QLabel * tmLabel = new QLabel(); + tmLabel->setText("时间"); + tmLabel->setFont(labelFont); + tmLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(tmLabel); + QLineEdit * tmValue = new QLineEdit(); + tmValue->setFixedWidth(200); + tmValue->setFont(labelFont); + vbox->addWidget(tmValue); + + QLabel * dataLabel = new QLabel(); + dataLabel->setText("测量数据"); + dataLabel->setFont(labelFont); + dataLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(dataLabel); + QLineEdit * dataValue = new QLineEdit(); + dataValue->setFixedWidth(150); + dataValue->setFont(labelFont); + vbox->addWidget(dataValue); + + QLabel * idLabel = new QLabel(); + idLabel->setText("数据ID"); + idLabel->setFont(labelFont); + idLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(idLabel); + QLineEdit * idValue = new QLineEdit(); + idValue->setFixedWidth(100); + idValue->setFont(labelFont); + vbox->addWidget(idValue); + + QLabel * validLabel = new QLabel(); + validLabel->setText("-"); + validLabel->setFont(labelFont); + validLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(validLabel); + + QSpacerItem * hSpace = new QSpacerItem(20, 20); + hSpace->changeSize(20, 20, QSizePolicy::Expanding); + vbox->addItem(hSpace); + + group->setLayout(vbox); + + layout->addWidget(group); } - - // Grid布局 - QGridLayout * gridLayout = new QGridLayout(gridWidget); - gridLayout->setSpacing(10); - - QList channelModelList; - QStringList labels = QObject::trUtf8("时间,相差").simplified().split(","); - - for (int i = 0; i < 16; i++) - { - QTableView * channelTable = new QTableView(gridWidget); - QStandardItemModel * model = new QStandardItemModel(channelTable); - - model->setHorizontalHeaderLabels(labels); - - channelTable->setModel(model); - - gridLayout->addWidget(channelTable, i / 4, i % 4); - - channelTable->verticalHeader()->hide(); - channelTable->setEditTriggers(QAbstractItemView::NoEditTriggers); - channelTable->scrollToBottom(); - - channelModelList.append(model); - } - - this->tableModelList.append(channelModelList); } -void PhaseWindow::createKafkaMessage() +int PhaseWindow::initHttpToken() { - this->kafkaUtil = new QKafkaUtil(this); - this->kafkaUtil->setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); - this->kafkaUtil->setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int PhaseWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject PhaseWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("比相仪"); + return response; +} - kafkaUtil->createProducer(); - kafkaUtil->produceMessage("hello world kafka kylin"); +void PhaseWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} + +void PhaseWindow::on_exitButt_clicked() +{ + QApplication::exit(0); } diff --git a/PhaseCompAcq/PhaseWindow.h b/PhaseCompAcq/PhaseWindow.h index 67b8363..02a7908 100644 --- a/PhaseCompAcq/PhaseWindow.h +++ b/PhaseCompAcq/PhaseWindow.h @@ -2,11 +2,13 @@ #define PHASEWINDOW_H #include +#include #include +#include #include "PhaseDevice.h" #include "common/utils/SettingConfig.h" -#include "common/utils/QKafkaUtil.h" +#include "common/HttpRequestController.h" namespace Ui { class PhaseWindow; @@ -23,18 +25,23 @@ public slots: void drawPhaseDataOnPage(PhaseDataDto * phaseData); +private slots: + void on_minButt_clicked(); + + void on_exitButt_clicked(); + private: + int initHttpToken(); + int initDictDeviceTypes(); + QJsonObject initDeviceList(); + Ui::PhaseWindow *ui; - QList devWidgetList; + HttpRequestController * httpReq; QList deviceList; - QList> tableModelList; - QKafkaUtil * kafkaUtil; - - void generateWidgetForDevice(QString devCode, int index); - void createKafkaMessage(); + void generateWidgetForDevice(); }; #endif // PHASEWINDOW_H diff --git a/PhaseCompAcq/PhaseWindow.ui b/PhaseCompAcq/PhaseWindow.ui index e6da880..01a7759 100644 --- a/PhaseCompAcq/PhaseWindow.ui +++ b/PhaseCompAcq/PhaseWindow.ui @@ -10,26 +10,144 @@ 720 - - - 1024 - 720 - - 多通道比相仪数据采集 - + 0 0 - 1024 - 720 + 100 + 30 - - -1 + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 100 + 30 + + + + + + + + 400 + 10 + 250 + 40 + + + + + + + 250 + 0 + 150 + 60 + + + + + 微软雅黑 + 12 + + + + Qt::LeftToRight + + + 请选择比相仪 + + + Qt::AlignCenter + + + + + + 880 + 10 + 40 + 40 + + + + + + + 退出 + + + + + + 20 + 0 + 200 + 60 + + + + + 微软雅黑 + 14 + + + + 多通道比相仪数据采集 + + + + + + 0 + 59 + 1024 + 1 + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + 830 + 10 + 40 + 40 + + + + + + + 最小化 diff --git a/PhaseCompAcq/common/ConstCache.h b/PhaseCompAcq/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/PhaseCompAcq/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/PhaseCompAcq/common/HttpRequestController.cpp b/PhaseCompAcq/common/HttpRequestController.cpp new file mode 100644 index 0000000..6abb5af --- /dev/null +++ b/PhaseCompAcq/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceTypes.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDeviceList(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", system.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); + } + + qDebug() << resultObj; + + return resultObj; +} diff --git a/PhaseCompAcq/common/HttpRequestController.h b/PhaseCompAcq/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/PhaseCompAcq/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/PhaseCompAcq/common/common.pri b/PhaseCompAcq/common/common.pri index 055a2db..84f57ae 100644 --- a/PhaseCompAcq/common/common.pri +++ b/PhaseCompAcq/common/common.pri @@ -3,10 +3,18 @@ SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp -SOURCES += $$PWD/utils/QKafkaUtil.cpp +#SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp HEADERS += $$PWD/utils/SettingConfig.h HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h -HEADERS += $$PWD/utils/QKafkaUtil.h +#HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/PhaseCompAcq/common/utils/DefHead.h b/PhaseCompAcq/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/PhaseCompAcq/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/PhaseCompAcq/common/utils/HttpRequestUtil.cpp b/PhaseCompAcq/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/PhaseCompAcq/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/PhaseCompAcq/common/utils/HttpRequestUtil.h b/PhaseCompAcq/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/PhaseCompAcq/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/PhaseCompAcq/common/utils/MD5.cpp b/PhaseCompAcq/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/PhaseCompAcq/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/PhaseCompAcq/common/utils/MD5.h b/PhaseCompAcq/common/utils/MD5.h new file mode 100644 index 0000000..5d86d32 --- /dev/null +++ b/PhaseCompAcq/common/utils/MD5.h @@ -0,0 +1,33 @@ +#ifndef MD5_H +#define MD5_H + +#include +#include +#include +#include"DefHead.h" + +#define SHORT_MD5_LEN 16 +#define CHAR_MD5_LEN 34 + + +class MD5 +{ +public: + explicit MD5(); + static void MD5Encode + ( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst + ); + + static bool MD5StrValidate + ( + _In_ const char* input1, + _In_ const char* input2 + ); +private: + ; +}; + +#endif // !MD5_H diff --git a/PhaseCompAcq/common/utils/QLogUtil.cpp b/PhaseCompAcq/common/utils/QLogUtil.cpp index 458ac15..43d8655 100644 --- a/PhaseCompAcq/common/utils/QLogUtil.cpp +++ b/PhaseCompAcq/common/utils/QLogUtil.cpp @@ -34,3 +34,59 @@ } +void QLogUtil::writeRawDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile rawLogFile(datePath + filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile chLogFile(datePath + filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::checkLogPath(QStringList path) +{ + QDir dir; + bool exist = false; + + for (int i = 0; i < path.size(); i++) + { + // 判断是否存在日志根目录 + exist = dir.exists(path.at(i)); + if (exist == false) + { + // 不存在则创建目录 + dir.mkdir(path.at(i)); + } + } +} diff --git a/CounterAcq/CounterAcq.pro b/CounterAcq/CounterAcq.pro index 72407cd..fae9d10 100644 --- a/CounterAcq/CounterAcq.pro +++ b/CounterAcq/CounterAcq.pro @@ -4,13 +4,6 @@ CONFIG += c++11 -SOURCES += \ - CounterWindow.cpp \ - main.cpp \ - -HEADERS += \ - CounterWindow.h \ - FORMS += \ CounterWindow.ui \ @@ -18,8 +11,11 @@ include(protocol/protocol.pri) HEADERS += CounterDevice.h +HEADERS += CounterWindow.h SOURCES += CounterDevice.cpp +SOURCES += CounterWindow.cpp +SOURCES += main.cpp DISTFILES += conf/config.ini diff --git a/CounterAcq/CounterWindow.cpp b/CounterAcq/CounterWindow.cpp index 80035a9..a50ebcf 100644 --- a/CounterAcq/CounterWindow.cpp +++ b/CounterAcq/CounterWindow.cpp @@ -42,7 +42,7 @@ { QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); - QApplication::exit(0); + QTimer::singleShot(1000, qApp, SLOT(quit())); } // 2. 获取字典值:设备类型 retCode = this->initDictDeviceTypes(); diff --git a/CounterAcq/CounterWindow.h b/CounterAcq/CounterWindow.h index 8d5e4a6..09277ba 100644 --- a/CounterAcq/CounterWindow.h +++ b/CounterAcq/CounterWindow.h @@ -7,7 +7,6 @@ #include #include "common/utils/SettingConfig.h" -#include "common/utils/QKafkaUtil.h" #include "common/HttpRequestController.h" #include "CounterDevice.h" @@ -23,8 +22,6 @@ explicit CounterWindow(QWidget *parent = nullptr); ~CounterWindow(); - QString token; - public slots: void drawCounterDataOnPage(CounterDataDto * counterData); @@ -40,7 +37,6 @@ Ui::CounterWindow *ui; - QTimer * timer; HttpRequestController * httpReq; QList deviceList; diff --git a/PhaseCompAcq/PhaseCompAcq.pro b/PhaseCompAcq/PhaseCompAcq.pro index 5eef2d1..c5e895b 100644 --- a/PhaseCompAcq/PhaseCompAcq.pro +++ b/PhaseCompAcq/PhaseCompAcq.pro @@ -1,16 +1,9 @@ -QT += core gui serialport +QT += core gui serialport network greaterThan(QT_MAJOR_VERSION, 4): QT += widgets CONFIG += c++11 -SOURCES += \ - main.cpp \ - PhaseWindow.cpp - -HEADERS += \ - PhaseWindow.h - FORMS += \ PhaseWindow.ui @@ -18,20 +11,19 @@ include(protocol/protocol.pri) HEADERS += PhaseDevice.h -#HEADERS += PhaseSerialServer.h +HEADERS += PhaseWindow.h SOURCES += PhaseDevice.cpp -#SOURCES += PhaseSerialServer.cpp +SOURCES += PhaseWindow.cpp +SOURCES += main.cpp # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target - -INCLUDEPATH += $$PWD/include/librdkafka -DEPENDPATH += $$PWD/include/librdkafka +#unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +#INCLUDEPATH += $$PWD/include/librdkafka +#DEPENDPATH += $$PWD/include/librdkafka DISTFILES += conf/config.ini - -unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ diff --git a/PhaseCompAcq/PhaseDevice.cpp b/PhaseCompAcq/PhaseDevice.cpp index 5c84cd5..afc2687 100644 --- a/PhaseCompAcq/PhaseDevice.cpp +++ b/PhaseCompAcq/PhaseDevice.cpp @@ -7,9 +7,9 @@ connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, this, &PhaseDevice::dataReceivedHandler); - kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); - kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); - kafkaUtil.createProducer(); +// kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); +// kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); +// kafkaUtil.createProducer(); } PhaseDevice::~PhaseDevice() @@ -34,6 +34,10 @@ { this->devCode = devCode; } +void PhaseDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} bool PhaseDevice::isSerialOpen() { @@ -74,6 +78,7 @@ if (parse == true) { QDateTime now = QDateTime::currentDateTime(); + phaseData->devCode = this->devCode; phaseData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); phaseData->milisecond = now.toMSecsSinceEpoch(); this->afterFramePhase(phaseData); @@ -92,21 +97,20 @@ this->dataBuff.clear(); // 2. 输出到日志文件中 - QString filePostfix = phaseData->timestamp.mid(0, 13).replace(" ", "_"); - QString filePrefix = QApplication::applicationDirPath() + "/logs/"; + QString date = phaseData->timestamp.mid(0, 10); // 2.1 原始字节数组数据 - QString filename = filePrefix + "raw_" + filePostfix + ".log"; + QString filename = "raw_" + devCode + ".log"; QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); - QLogUtil::writeRawDataLog(filename, content); + QLogUtil::writeRawDataLogByDate(date, filename, content); // 2.2 各个通道的相差数据 for (int i = 1; i <= phaseData->channelActive.size(); i++) { if (phaseData->channelActive.at(i-1).toUInt() == 1) { - QString chFilename("%1CH_%2_%3.log"); - chFilename = chFilename.arg(filePrefix); + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); if (i < 10) { chFilename = chFilename.arg(QString("0%1").arg(i)); @@ -114,10 +118,9 @@ { chFilename = chFilename.arg(i); } - chFilename = chFilename.arg(filePostfix); - QString channelDataStr = QString("%1 %2 %3").arg(phaseData->timestamp).arg(phaseData->channelData.at(i-1)).arg(phaseData->frameId); + QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelData.at(i-1)); - QLogUtil::writeChannelDataLog(chFilename, channelDataStr); + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); // 3. 输出到中间件,执行后续处理过程 if (SettingConfig::getInstance().NEED_KAFKA == 1) @@ -125,7 +128,7 @@ QJsonObject jsonObj = phaseData->toJSON(i - 1); jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); jsonObj.insert("deviceId", devCode); - kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); +// kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); } } } diff --git a/PhaseCompAcq/PhaseDevice.h b/PhaseCompAcq/PhaseDevice.h index 92182d4..aa7d822 100644 --- a/PhaseCompAcq/PhaseDevice.h +++ b/PhaseCompAcq/PhaseDevice.h @@ -5,7 +5,7 @@ #include "common/utils/QSerialPortUtil.h" #include "common/utils/QLogUtil.h" #include "common/utils/SettingConfig.h" -#include "common/utils/QKafkaUtil.h" +//#include "common/utils/QKafkaUtil.h" #include "protocol/PhaseProtocolBM.h" class PhaseDevice : public QObject @@ -25,15 +25,17 @@ void setBaudRate(int baudRate); QString getDevCode(); void setDevCode(QString devCode); + void setDeviceId(QString deviceId); bool isSerialOpen(); private: + QString deviceId; QString devCode; QString comName; int baudRate; QSerialPortUtil serialUtil; - QKafkaUtil kafkaUtil; +// QKafkaUtil kafkaUtil; QByteArray dataBuff; signals: diff --git a/PhaseCompAcq/PhaseWindow.cpp b/PhaseCompAcq/PhaseWindow.cpp index b3cab89..d0e8221 100644 --- a/PhaseCompAcq/PhaseWindow.cpp +++ b/PhaseCompAcq/PhaseWindow.cpp @@ -1,16 +1,16 @@ #include "PhaseWindow.h" #include "ui_PhaseWindow.h" -#include -#include -#include -#include -#include -#include - #include - -#include "common/utils/QKafkaUtil.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include PhaseWindow::PhaseWindow(QWidget *parent) : QWidget(parent), @@ -18,43 +18,74 @@ { ui->setupUi(this); - QString portNames = SettingConfig::getInstance().PORT_NAMES; - int baudRate = SettingConfig::getInstance().BAUD_RATE; - QString devCodes = SettingConfig::getInstance().DEV_CODES; + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); - QStringList comDevList = portNames.split(","); - QStringList devCodeList = devCodes.split(","); + // 窗口大小为占满一屏 + QRect screenRect = QApplication::desktop()->screenGeometry(); + resize(screenRect.width(), screenRect.height()); - for (int i = 0; i < comDevList.size(); i++) + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->line->setGeometry(0, 59, screenRect.width(), 1); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 60, screenRect.width(), screenRect.height() - 60); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + + httpReq = new HttpRequestController(this); + // 1. 获取访问接口需要的token + int retCode = this->initHttpToken(); + if (retCode != 200) { - PhaseDevice * device = new PhaseDevice(this); + QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); - // - connect(device, &PhaseDevice::sendDataToDraw, - this, &PhaseWindow::drawPhaseDataOnPage); + QTimer::singleShot(1000, qApp, SLOT(quit())); + } + // 2. 获取字典值:设备类型 + retCode = this->initDictDeviceTypes(); - device->setComName(comDevList.at(i)); - device->setBaudRate(baudRate); + // 3. 获取比相仪设备列表 + QJsonObject devListRes = this->initDeviceList(); + if (devListRes.find("code")->toInt() == 200) + { + ui->devSelect->clear(); - device->setDevCode(devCodeList.at(i)); + // 4. 将获取到的设备添加到下拉列表框中 + QJsonArray devArray = devListRes.find("data")->toArray(); + for (int i = 0; i < devArray.size(); i++) + { + QJsonObject devItem = devArray.at(i).toObject(); + ui->devSelect->addItem(devItem.find("deviceName")->toString(), devItem.find("deviceNo")->toString()); - this->deviceList.append(device); + PhaseDevice * device = new PhaseDevice(this); + deviceList.append(device); - device->initSerialPort(); - device->startWork(); + device->setComName(devItem.find("linkComName")->toString()); + device->setBaudRate(SettingConfig::getInstance().BAUD_RATE); + device->setDevCode(devItem.find("deviceNo")->toString()); + device->setDeviceId(devItem.find("deviceId")->toString()); + + connect(device, &PhaseDevice::sendDataToDraw, + this, &PhaseWindow::drawPhaseDataOnPage); + + device->initSerialPort(); + + QThread::msleep(100); + } + // 5. 设置下拉框的样式 + QStandardItemModel * model = qobject_cast(ui->devSelect->model()); + for (int i = 0; i < model->rowCount(); ++i) + { + QStandardItem * item = model->item(i); + item->setSizeHint({ 0, 30 }); + } } - for (int i = 0; i < this->deviceList.size(); i++) - { - QWidget * devWidget5 = new QWidget(this->ui->stackedWidget); - - this->ui->stackedWidget->addWidget(devWidget5); - - this->devWidgetList.append(devWidget5); - - // 创建设备的widget - this->generateWidgetForDevice(devCodeList.at(i), i); - } + // 6. 绘制一个设备的多个通道数据面板 + this->generateWidgetForDevice(); } PhaseWindow::~PhaseWindow() @@ -64,99 +95,119 @@ void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) { - // 1. 判断数据属于哪个设备,显示在不同的widget上 + // 当前显示的设备编号 + QString currentDevCode = ui->devSelect->currentData().toString(); - // 2. 循环设置各个tableView - QList devChannels = this->tableModelList.at(0); // 暂时写死 - for (int i = 0; i < phaseData->channelData.size(); i++) + // 如果不是当前设备的帧,直接返回 + if (phaseData->devCode != currentDevCode) { - if (phaseData->channelActive.at(i).toInt() == 1) - { - QList row; - QStandardItem * item = 0; - QStandardItem * item2 = 0; - item = new QStandardItem(QString("%1").arg(phaseData->timestamp.mid(11, 12))); - item2 = new QStandardItem(QString("%1").arg(phaseData->channelData.at(i))); + return; + } - row.append(item); - row.append(item2); + // 更新所有通道BOX的值 + for (int i = 0; i < phaseData->channelActive.size(); i++) + { + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); - QStandardItemModel * model; - model = devChannels.at(i); - if (model->rowCount() >= 60) - { - model->removeRows(0, model->rowCount()); - } - - model->insertRow(0, row); - } + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(phaseData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelData.at(i))); + ((QLineEdit *)channelBox->children().at(6))->setText(phaseData->frameId); + ((QLabel *)channelBox->children().at(7))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); } } -void PhaseWindow::generateWidgetForDevice(QString devCode, int index) +void PhaseWindow::generateWidgetForDevice() { - // 顶部切换widget - QWidget * switchWidget = new QWidget(this->devWidgetList.at(index)); - switchWidget->setGeometry(0, 0, 1024, 50); + // 获取设备数据 + int channelNum = 16; - // 显示数据的区域 - QWidget * gridWidget = new QWidget(this->devWidgetList.at(index)); - gridWidget->setGeometry(0, 50, 1024, 670); + QRect screenRect = QApplication::desktop()->screenGeometry(); - // 顶部水平布局,用于排布按钮 - QHBoxLayout * hLayout = new QHBoxLayout(switchWidget); + ui->scrollContents->setGeometry(0, 60, screenRect.width(), channelNum * 90); - // 文本 - QLabel * label = new QLabel(switchWidget); - label->setText("设备编号:" + devCode); - label->setFont(QFont("微软雅黑", 12)); - hLayout->addWidget(label); + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); - // 按钮 - for (int i = 0; i < this->deviceList.size(); i++) + for (int i = 0; i < channelNum; i++) { - QPushButton * butt5 = new QPushButton(this->deviceList.at(i)->getDevCode()); - hLayout->addWidget(butt5); + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 80 + 10, screenRect.width() - 40, 80); - connect(butt5, &QPushButton::clicked, [=](){ - this->ui->stackedWidget->setCurrentIndex(i); - }); + QHBoxLayout * vbox = new QHBoxLayout(group); + + QLabel * tmLabel = new QLabel(); + tmLabel->setText("时间"); + tmLabel->setFont(labelFont); + tmLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(tmLabel); + QLineEdit * tmValue = new QLineEdit(); + tmValue->setFixedWidth(200); + tmValue->setFont(labelFont); + vbox->addWidget(tmValue); + + QLabel * dataLabel = new QLabel(); + dataLabel->setText("测量数据"); + dataLabel->setFont(labelFont); + dataLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(dataLabel); + QLineEdit * dataValue = new QLineEdit(); + dataValue->setFixedWidth(150); + dataValue->setFont(labelFont); + vbox->addWidget(dataValue); + + QLabel * idLabel = new QLabel(); + idLabel->setText("数据ID"); + idLabel->setFont(labelFont); + idLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(idLabel); + QLineEdit * idValue = new QLineEdit(); + idValue->setFixedWidth(100); + idValue->setFont(labelFont); + vbox->addWidget(idValue); + + QLabel * validLabel = new QLabel(); + validLabel->setText("-"); + validLabel->setFont(labelFont); + validLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(validLabel); + + QSpacerItem * hSpace = new QSpacerItem(20, 20); + hSpace->changeSize(20, 20, QSizePolicy::Expanding); + vbox->addItem(hSpace); + + group->setLayout(vbox); + + layout->addWidget(group); } - - // Grid布局 - QGridLayout * gridLayout = new QGridLayout(gridWidget); - gridLayout->setSpacing(10); - - QList channelModelList; - QStringList labels = QObject::trUtf8("时间,相差").simplified().split(","); - - for (int i = 0; i < 16; i++) - { - QTableView * channelTable = new QTableView(gridWidget); - QStandardItemModel * model = new QStandardItemModel(channelTable); - - model->setHorizontalHeaderLabels(labels); - - channelTable->setModel(model); - - gridLayout->addWidget(channelTable, i / 4, i % 4); - - channelTable->verticalHeader()->hide(); - channelTable->setEditTriggers(QAbstractItemView::NoEditTriggers); - channelTable->scrollToBottom(); - - channelModelList.append(model); - } - - this->tableModelList.append(channelModelList); } -void PhaseWindow::createKafkaMessage() +int PhaseWindow::initHttpToken() { - this->kafkaUtil = new QKafkaUtil(this); - this->kafkaUtil->setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); - this->kafkaUtil->setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int PhaseWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject PhaseWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("比相仪"); + return response; +} - kafkaUtil->createProducer(); - kafkaUtil->produceMessage("hello world kafka kylin"); +void PhaseWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} + +void PhaseWindow::on_exitButt_clicked() +{ + QApplication::exit(0); } diff --git a/PhaseCompAcq/PhaseWindow.h b/PhaseCompAcq/PhaseWindow.h index 67b8363..02a7908 100644 --- a/PhaseCompAcq/PhaseWindow.h +++ b/PhaseCompAcq/PhaseWindow.h @@ -2,11 +2,13 @@ #define PHASEWINDOW_H #include +#include #include +#include #include "PhaseDevice.h" #include "common/utils/SettingConfig.h" -#include "common/utils/QKafkaUtil.h" +#include "common/HttpRequestController.h" namespace Ui { class PhaseWindow; @@ -23,18 +25,23 @@ public slots: void drawPhaseDataOnPage(PhaseDataDto * phaseData); +private slots: + void on_minButt_clicked(); + + void on_exitButt_clicked(); + private: + int initHttpToken(); + int initDictDeviceTypes(); + QJsonObject initDeviceList(); + Ui::PhaseWindow *ui; - QList devWidgetList; + HttpRequestController * httpReq; QList deviceList; - QList> tableModelList; - QKafkaUtil * kafkaUtil; - - void generateWidgetForDevice(QString devCode, int index); - void createKafkaMessage(); + void generateWidgetForDevice(); }; #endif // PHASEWINDOW_H diff --git a/PhaseCompAcq/PhaseWindow.ui b/PhaseCompAcq/PhaseWindow.ui index e6da880..01a7759 100644 --- a/PhaseCompAcq/PhaseWindow.ui +++ b/PhaseCompAcq/PhaseWindow.ui @@ -10,26 +10,144 @@ 720 - - - 1024 - 720 - - 多通道比相仪数据采集 - + 0 0 - 1024 - 720 + 100 + 30 - - -1 + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 100 + 30 + + + + + + + + 400 + 10 + 250 + 40 + + + + + + + 250 + 0 + 150 + 60 + + + + + 微软雅黑 + 12 + + + + Qt::LeftToRight + + + 请选择比相仪 + + + Qt::AlignCenter + + + + + + 880 + 10 + 40 + 40 + + + + + + + 退出 + + + + + + 20 + 0 + 200 + 60 + + + + + 微软雅黑 + 14 + + + + 多通道比相仪数据采集 + + + + + + 0 + 59 + 1024 + 1 + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + 830 + 10 + 40 + 40 + + + + + + + 最小化 diff --git a/PhaseCompAcq/common/ConstCache.h b/PhaseCompAcq/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/PhaseCompAcq/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/PhaseCompAcq/common/HttpRequestController.cpp b/PhaseCompAcq/common/HttpRequestController.cpp new file mode 100644 index 0000000..6abb5af --- /dev/null +++ b/PhaseCompAcq/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceTypes.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDeviceList(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", system.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); + } + + qDebug() << resultObj; + + return resultObj; +} diff --git a/PhaseCompAcq/common/HttpRequestController.h b/PhaseCompAcq/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/PhaseCompAcq/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/PhaseCompAcq/common/common.pri b/PhaseCompAcq/common/common.pri index 055a2db..84f57ae 100644 --- a/PhaseCompAcq/common/common.pri +++ b/PhaseCompAcq/common/common.pri @@ -3,10 +3,18 @@ SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp -SOURCES += $$PWD/utils/QKafkaUtil.cpp +#SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp HEADERS += $$PWD/utils/SettingConfig.h HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h -HEADERS += $$PWD/utils/QKafkaUtil.h +#HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/PhaseCompAcq/common/utils/DefHead.h b/PhaseCompAcq/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/PhaseCompAcq/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/PhaseCompAcq/common/utils/HttpRequestUtil.cpp b/PhaseCompAcq/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/PhaseCompAcq/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/PhaseCompAcq/common/utils/HttpRequestUtil.h b/PhaseCompAcq/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/PhaseCompAcq/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/PhaseCompAcq/common/utils/MD5.cpp b/PhaseCompAcq/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/PhaseCompAcq/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/PhaseCompAcq/common/utils/MD5.h b/PhaseCompAcq/common/utils/MD5.h new file mode 100644 index 0000000..5d86d32 --- /dev/null +++ b/PhaseCompAcq/common/utils/MD5.h @@ -0,0 +1,33 @@ +#ifndef MD5_H +#define MD5_H + +#include +#include +#include +#include"DefHead.h" + +#define SHORT_MD5_LEN 16 +#define CHAR_MD5_LEN 34 + + +class MD5 +{ +public: + explicit MD5(); + static void MD5Encode + ( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst + ); + + static bool MD5StrValidate + ( + _In_ const char* input1, + _In_ const char* input2 + ); +private: + ; +}; + +#endif // !MD5_H diff --git a/PhaseCompAcq/common/utils/QLogUtil.cpp b/PhaseCompAcq/common/utils/QLogUtil.cpp index 458ac15..43d8655 100644 --- a/PhaseCompAcq/common/utils/QLogUtil.cpp +++ b/PhaseCompAcq/common/utils/QLogUtil.cpp @@ -34,3 +34,59 @@ } +void QLogUtil::writeRawDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile rawLogFile(datePath + filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile chLogFile(datePath + filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::checkLogPath(QStringList path) +{ + QDir dir; + bool exist = false; + + for (int i = 0; i < path.size(); i++) + { + // 判断是否存在日志根目录 + exist = dir.exists(path.at(i)); + if (exist == false) + { + // 不存在则创建目录 + dir.mkdir(path.at(i)); + } + } +} diff --git a/PhaseCompAcq/common/utils/QLogUtil.h b/PhaseCompAcq/common/utils/QLogUtil.h index 8da0fcd..1d1ef0f 100644 --- a/PhaseCompAcq/common/utils/QLogUtil.h +++ b/PhaseCompAcq/common/utils/QLogUtil.h @@ -3,7 +3,9 @@ #include #include +#include #include +#include "SettingConfig.h" class QLogUtil : public QObject { @@ -16,6 +18,11 @@ static void writeInfoLog(QString message); static void writeDebugLog(QString message); + static void writeRawDataLogByDate(QString date, QString filename, QString content); + static void writeChannelDataLogByDate(QString date, QString filename, QString content); + +private: + static void checkLogPath(QStringList path); signals: }; diff --git a/CounterAcq/CounterAcq.pro b/CounterAcq/CounterAcq.pro index 72407cd..fae9d10 100644 --- a/CounterAcq/CounterAcq.pro +++ b/CounterAcq/CounterAcq.pro @@ -4,13 +4,6 @@ CONFIG += c++11 -SOURCES += \ - CounterWindow.cpp \ - main.cpp \ - -HEADERS += \ - CounterWindow.h \ - FORMS += \ CounterWindow.ui \ @@ -18,8 +11,11 @@ include(protocol/protocol.pri) HEADERS += CounterDevice.h +HEADERS += CounterWindow.h SOURCES += CounterDevice.cpp +SOURCES += CounterWindow.cpp +SOURCES += main.cpp DISTFILES += conf/config.ini diff --git a/CounterAcq/CounterWindow.cpp b/CounterAcq/CounterWindow.cpp index 80035a9..a50ebcf 100644 --- a/CounterAcq/CounterWindow.cpp +++ b/CounterAcq/CounterWindow.cpp @@ -42,7 +42,7 @@ { QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); - QApplication::exit(0); + QTimer::singleShot(1000, qApp, SLOT(quit())); } // 2. 获取字典值:设备类型 retCode = this->initDictDeviceTypes(); diff --git a/CounterAcq/CounterWindow.h b/CounterAcq/CounterWindow.h index 8d5e4a6..09277ba 100644 --- a/CounterAcq/CounterWindow.h +++ b/CounterAcq/CounterWindow.h @@ -7,7 +7,6 @@ #include #include "common/utils/SettingConfig.h" -#include "common/utils/QKafkaUtil.h" #include "common/HttpRequestController.h" #include "CounterDevice.h" @@ -23,8 +22,6 @@ explicit CounterWindow(QWidget *parent = nullptr); ~CounterWindow(); - QString token; - public slots: void drawCounterDataOnPage(CounterDataDto * counterData); @@ -40,7 +37,6 @@ Ui::CounterWindow *ui; - QTimer * timer; HttpRequestController * httpReq; QList deviceList; diff --git a/PhaseCompAcq/PhaseCompAcq.pro b/PhaseCompAcq/PhaseCompAcq.pro index 5eef2d1..c5e895b 100644 --- a/PhaseCompAcq/PhaseCompAcq.pro +++ b/PhaseCompAcq/PhaseCompAcq.pro @@ -1,16 +1,9 @@ -QT += core gui serialport +QT += core gui serialport network greaterThan(QT_MAJOR_VERSION, 4): QT += widgets CONFIG += c++11 -SOURCES += \ - main.cpp \ - PhaseWindow.cpp - -HEADERS += \ - PhaseWindow.h - FORMS += \ PhaseWindow.ui @@ -18,20 +11,19 @@ include(protocol/protocol.pri) HEADERS += PhaseDevice.h -#HEADERS += PhaseSerialServer.h +HEADERS += PhaseWindow.h SOURCES += PhaseDevice.cpp -#SOURCES += PhaseSerialServer.cpp +SOURCES += PhaseWindow.cpp +SOURCES += main.cpp # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target - -INCLUDEPATH += $$PWD/include/librdkafka -DEPENDPATH += $$PWD/include/librdkafka +#unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +#INCLUDEPATH += $$PWD/include/librdkafka +#DEPENDPATH += $$PWD/include/librdkafka DISTFILES += conf/config.ini - -unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ diff --git a/PhaseCompAcq/PhaseDevice.cpp b/PhaseCompAcq/PhaseDevice.cpp index 5c84cd5..afc2687 100644 --- a/PhaseCompAcq/PhaseDevice.cpp +++ b/PhaseCompAcq/PhaseDevice.cpp @@ -7,9 +7,9 @@ connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, this, &PhaseDevice::dataReceivedHandler); - kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); - kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); - kafkaUtil.createProducer(); +// kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); +// kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); +// kafkaUtil.createProducer(); } PhaseDevice::~PhaseDevice() @@ -34,6 +34,10 @@ { this->devCode = devCode; } +void PhaseDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} bool PhaseDevice::isSerialOpen() { @@ -74,6 +78,7 @@ if (parse == true) { QDateTime now = QDateTime::currentDateTime(); + phaseData->devCode = this->devCode; phaseData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); phaseData->milisecond = now.toMSecsSinceEpoch(); this->afterFramePhase(phaseData); @@ -92,21 +97,20 @@ this->dataBuff.clear(); // 2. 输出到日志文件中 - QString filePostfix = phaseData->timestamp.mid(0, 13).replace(" ", "_"); - QString filePrefix = QApplication::applicationDirPath() + "/logs/"; + QString date = phaseData->timestamp.mid(0, 10); // 2.1 原始字节数组数据 - QString filename = filePrefix + "raw_" + filePostfix + ".log"; + QString filename = "raw_" + devCode + ".log"; QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); - QLogUtil::writeRawDataLog(filename, content); + QLogUtil::writeRawDataLogByDate(date, filename, content); // 2.2 各个通道的相差数据 for (int i = 1; i <= phaseData->channelActive.size(); i++) { if (phaseData->channelActive.at(i-1).toUInt() == 1) { - QString chFilename("%1CH_%2_%3.log"); - chFilename = chFilename.arg(filePrefix); + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); if (i < 10) { chFilename = chFilename.arg(QString("0%1").arg(i)); @@ -114,10 +118,9 @@ { chFilename = chFilename.arg(i); } - chFilename = chFilename.arg(filePostfix); - QString channelDataStr = QString("%1 %2 %3").arg(phaseData->timestamp).arg(phaseData->channelData.at(i-1)).arg(phaseData->frameId); + QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelData.at(i-1)); - QLogUtil::writeChannelDataLog(chFilename, channelDataStr); + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); // 3. 输出到中间件,执行后续处理过程 if (SettingConfig::getInstance().NEED_KAFKA == 1) @@ -125,7 +128,7 @@ QJsonObject jsonObj = phaseData->toJSON(i - 1); jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); jsonObj.insert("deviceId", devCode); - kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); +// kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); } } } diff --git a/PhaseCompAcq/PhaseDevice.h b/PhaseCompAcq/PhaseDevice.h index 92182d4..aa7d822 100644 --- a/PhaseCompAcq/PhaseDevice.h +++ b/PhaseCompAcq/PhaseDevice.h @@ -5,7 +5,7 @@ #include "common/utils/QSerialPortUtil.h" #include "common/utils/QLogUtil.h" #include "common/utils/SettingConfig.h" -#include "common/utils/QKafkaUtil.h" +//#include "common/utils/QKafkaUtil.h" #include "protocol/PhaseProtocolBM.h" class PhaseDevice : public QObject @@ -25,15 +25,17 @@ void setBaudRate(int baudRate); QString getDevCode(); void setDevCode(QString devCode); + void setDeviceId(QString deviceId); bool isSerialOpen(); private: + QString deviceId; QString devCode; QString comName; int baudRate; QSerialPortUtil serialUtil; - QKafkaUtil kafkaUtil; +// QKafkaUtil kafkaUtil; QByteArray dataBuff; signals: diff --git a/PhaseCompAcq/PhaseWindow.cpp b/PhaseCompAcq/PhaseWindow.cpp index b3cab89..d0e8221 100644 --- a/PhaseCompAcq/PhaseWindow.cpp +++ b/PhaseCompAcq/PhaseWindow.cpp @@ -1,16 +1,16 @@ #include "PhaseWindow.h" #include "ui_PhaseWindow.h" -#include -#include -#include -#include -#include -#include - #include - -#include "common/utils/QKafkaUtil.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include PhaseWindow::PhaseWindow(QWidget *parent) : QWidget(parent), @@ -18,43 +18,74 @@ { ui->setupUi(this); - QString portNames = SettingConfig::getInstance().PORT_NAMES; - int baudRate = SettingConfig::getInstance().BAUD_RATE; - QString devCodes = SettingConfig::getInstance().DEV_CODES; + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); - QStringList comDevList = portNames.split(","); - QStringList devCodeList = devCodes.split(","); + // 窗口大小为占满一屏 + QRect screenRect = QApplication::desktop()->screenGeometry(); + resize(screenRect.width(), screenRect.height()); - for (int i = 0; i < comDevList.size(); i++) + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->line->setGeometry(0, 59, screenRect.width(), 1); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 60, screenRect.width(), screenRect.height() - 60); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + + httpReq = new HttpRequestController(this); + // 1. 获取访问接口需要的token + int retCode = this->initHttpToken(); + if (retCode != 200) { - PhaseDevice * device = new PhaseDevice(this); + QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); - // - connect(device, &PhaseDevice::sendDataToDraw, - this, &PhaseWindow::drawPhaseDataOnPage); + QTimer::singleShot(1000, qApp, SLOT(quit())); + } + // 2. 获取字典值:设备类型 + retCode = this->initDictDeviceTypes(); - device->setComName(comDevList.at(i)); - device->setBaudRate(baudRate); + // 3. 获取比相仪设备列表 + QJsonObject devListRes = this->initDeviceList(); + if (devListRes.find("code")->toInt() == 200) + { + ui->devSelect->clear(); - device->setDevCode(devCodeList.at(i)); + // 4. 将获取到的设备添加到下拉列表框中 + QJsonArray devArray = devListRes.find("data")->toArray(); + for (int i = 0; i < devArray.size(); i++) + { + QJsonObject devItem = devArray.at(i).toObject(); + ui->devSelect->addItem(devItem.find("deviceName")->toString(), devItem.find("deviceNo")->toString()); - this->deviceList.append(device); + PhaseDevice * device = new PhaseDevice(this); + deviceList.append(device); - device->initSerialPort(); - device->startWork(); + device->setComName(devItem.find("linkComName")->toString()); + device->setBaudRate(SettingConfig::getInstance().BAUD_RATE); + device->setDevCode(devItem.find("deviceNo")->toString()); + device->setDeviceId(devItem.find("deviceId")->toString()); + + connect(device, &PhaseDevice::sendDataToDraw, + this, &PhaseWindow::drawPhaseDataOnPage); + + device->initSerialPort(); + + QThread::msleep(100); + } + // 5. 设置下拉框的样式 + QStandardItemModel * model = qobject_cast(ui->devSelect->model()); + for (int i = 0; i < model->rowCount(); ++i) + { + QStandardItem * item = model->item(i); + item->setSizeHint({ 0, 30 }); + } } - for (int i = 0; i < this->deviceList.size(); i++) - { - QWidget * devWidget5 = new QWidget(this->ui->stackedWidget); - - this->ui->stackedWidget->addWidget(devWidget5); - - this->devWidgetList.append(devWidget5); - - // 创建设备的widget - this->generateWidgetForDevice(devCodeList.at(i), i); - } + // 6. 绘制一个设备的多个通道数据面板 + this->generateWidgetForDevice(); } PhaseWindow::~PhaseWindow() @@ -64,99 +95,119 @@ void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) { - // 1. 判断数据属于哪个设备,显示在不同的widget上 + // 当前显示的设备编号 + QString currentDevCode = ui->devSelect->currentData().toString(); - // 2. 循环设置各个tableView - QList devChannels = this->tableModelList.at(0); // 暂时写死 - for (int i = 0; i < phaseData->channelData.size(); i++) + // 如果不是当前设备的帧,直接返回 + if (phaseData->devCode != currentDevCode) { - if (phaseData->channelActive.at(i).toInt() == 1) - { - QList row; - QStandardItem * item = 0; - QStandardItem * item2 = 0; - item = new QStandardItem(QString("%1").arg(phaseData->timestamp.mid(11, 12))); - item2 = new QStandardItem(QString("%1").arg(phaseData->channelData.at(i))); + return; + } - row.append(item); - row.append(item2); + // 更新所有通道BOX的值 + for (int i = 0; i < phaseData->channelActive.size(); i++) + { + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); - QStandardItemModel * model; - model = devChannels.at(i); - if (model->rowCount() >= 60) - { - model->removeRows(0, model->rowCount()); - } - - model->insertRow(0, row); - } + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(phaseData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelData.at(i))); + ((QLineEdit *)channelBox->children().at(6))->setText(phaseData->frameId); + ((QLabel *)channelBox->children().at(7))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); } } -void PhaseWindow::generateWidgetForDevice(QString devCode, int index) +void PhaseWindow::generateWidgetForDevice() { - // 顶部切换widget - QWidget * switchWidget = new QWidget(this->devWidgetList.at(index)); - switchWidget->setGeometry(0, 0, 1024, 50); + // 获取设备数据 + int channelNum = 16; - // 显示数据的区域 - QWidget * gridWidget = new QWidget(this->devWidgetList.at(index)); - gridWidget->setGeometry(0, 50, 1024, 670); + QRect screenRect = QApplication::desktop()->screenGeometry(); - // 顶部水平布局,用于排布按钮 - QHBoxLayout * hLayout = new QHBoxLayout(switchWidget); + ui->scrollContents->setGeometry(0, 60, screenRect.width(), channelNum * 90); - // 文本 - QLabel * label = new QLabel(switchWidget); - label->setText("设备编号:" + devCode); - label->setFont(QFont("微软雅黑", 12)); - hLayout->addWidget(label); + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); - // 按钮 - for (int i = 0; i < this->deviceList.size(); i++) + for (int i = 0; i < channelNum; i++) { - QPushButton * butt5 = new QPushButton(this->deviceList.at(i)->getDevCode()); - hLayout->addWidget(butt5); + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 80 + 10, screenRect.width() - 40, 80); - connect(butt5, &QPushButton::clicked, [=](){ - this->ui->stackedWidget->setCurrentIndex(i); - }); + QHBoxLayout * vbox = new QHBoxLayout(group); + + QLabel * tmLabel = new QLabel(); + tmLabel->setText("时间"); + tmLabel->setFont(labelFont); + tmLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(tmLabel); + QLineEdit * tmValue = new QLineEdit(); + tmValue->setFixedWidth(200); + tmValue->setFont(labelFont); + vbox->addWidget(tmValue); + + QLabel * dataLabel = new QLabel(); + dataLabel->setText("测量数据"); + dataLabel->setFont(labelFont); + dataLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(dataLabel); + QLineEdit * dataValue = new QLineEdit(); + dataValue->setFixedWidth(150); + dataValue->setFont(labelFont); + vbox->addWidget(dataValue); + + QLabel * idLabel = new QLabel(); + idLabel->setText("数据ID"); + idLabel->setFont(labelFont); + idLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(idLabel); + QLineEdit * idValue = new QLineEdit(); + idValue->setFixedWidth(100); + idValue->setFont(labelFont); + vbox->addWidget(idValue); + + QLabel * validLabel = new QLabel(); + validLabel->setText("-"); + validLabel->setFont(labelFont); + validLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(validLabel); + + QSpacerItem * hSpace = new QSpacerItem(20, 20); + hSpace->changeSize(20, 20, QSizePolicy::Expanding); + vbox->addItem(hSpace); + + group->setLayout(vbox); + + layout->addWidget(group); } - - // Grid布局 - QGridLayout * gridLayout = new QGridLayout(gridWidget); - gridLayout->setSpacing(10); - - QList channelModelList; - QStringList labels = QObject::trUtf8("时间,相差").simplified().split(","); - - for (int i = 0; i < 16; i++) - { - QTableView * channelTable = new QTableView(gridWidget); - QStandardItemModel * model = new QStandardItemModel(channelTable); - - model->setHorizontalHeaderLabels(labels); - - channelTable->setModel(model); - - gridLayout->addWidget(channelTable, i / 4, i % 4); - - channelTable->verticalHeader()->hide(); - channelTable->setEditTriggers(QAbstractItemView::NoEditTriggers); - channelTable->scrollToBottom(); - - channelModelList.append(model); - } - - this->tableModelList.append(channelModelList); } -void PhaseWindow::createKafkaMessage() +int PhaseWindow::initHttpToken() { - this->kafkaUtil = new QKafkaUtil(this); - this->kafkaUtil->setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); - this->kafkaUtil->setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int PhaseWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject PhaseWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("比相仪"); + return response; +} - kafkaUtil->createProducer(); - kafkaUtil->produceMessage("hello world kafka kylin"); +void PhaseWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} + +void PhaseWindow::on_exitButt_clicked() +{ + QApplication::exit(0); } diff --git a/PhaseCompAcq/PhaseWindow.h b/PhaseCompAcq/PhaseWindow.h index 67b8363..02a7908 100644 --- a/PhaseCompAcq/PhaseWindow.h +++ b/PhaseCompAcq/PhaseWindow.h @@ -2,11 +2,13 @@ #define PHASEWINDOW_H #include +#include #include +#include #include "PhaseDevice.h" #include "common/utils/SettingConfig.h" -#include "common/utils/QKafkaUtil.h" +#include "common/HttpRequestController.h" namespace Ui { class PhaseWindow; @@ -23,18 +25,23 @@ public slots: void drawPhaseDataOnPage(PhaseDataDto * phaseData); +private slots: + void on_minButt_clicked(); + + void on_exitButt_clicked(); + private: + int initHttpToken(); + int initDictDeviceTypes(); + QJsonObject initDeviceList(); + Ui::PhaseWindow *ui; - QList devWidgetList; + HttpRequestController * httpReq; QList deviceList; - QList> tableModelList; - QKafkaUtil * kafkaUtil; - - void generateWidgetForDevice(QString devCode, int index); - void createKafkaMessage(); + void generateWidgetForDevice(); }; #endif // PHASEWINDOW_H diff --git a/PhaseCompAcq/PhaseWindow.ui b/PhaseCompAcq/PhaseWindow.ui index e6da880..01a7759 100644 --- a/PhaseCompAcq/PhaseWindow.ui +++ b/PhaseCompAcq/PhaseWindow.ui @@ -10,26 +10,144 @@ 720 - - - 1024 - 720 - - 多通道比相仪数据采集 - + 0 0 - 1024 - 720 + 100 + 30 - - -1 + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 100 + 30 + + + + + + + + 400 + 10 + 250 + 40 + + + + + + + 250 + 0 + 150 + 60 + + + + + 微软雅黑 + 12 + + + + Qt::LeftToRight + + + 请选择比相仪 + + + Qt::AlignCenter + + + + + + 880 + 10 + 40 + 40 + + + + + + + 退出 + + + + + + 20 + 0 + 200 + 60 + + + + + 微软雅黑 + 14 + + + + 多通道比相仪数据采集 + + + + + + 0 + 59 + 1024 + 1 + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + 830 + 10 + 40 + 40 + + + + + + + 最小化 diff --git a/PhaseCompAcq/common/ConstCache.h b/PhaseCompAcq/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/PhaseCompAcq/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/PhaseCompAcq/common/HttpRequestController.cpp b/PhaseCompAcq/common/HttpRequestController.cpp new file mode 100644 index 0000000..6abb5af --- /dev/null +++ b/PhaseCompAcq/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceTypes.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDeviceList(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", system.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); + } + + qDebug() << resultObj; + + return resultObj; +} diff --git a/PhaseCompAcq/common/HttpRequestController.h b/PhaseCompAcq/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/PhaseCompAcq/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/PhaseCompAcq/common/common.pri b/PhaseCompAcq/common/common.pri index 055a2db..84f57ae 100644 --- a/PhaseCompAcq/common/common.pri +++ b/PhaseCompAcq/common/common.pri @@ -3,10 +3,18 @@ SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp -SOURCES += $$PWD/utils/QKafkaUtil.cpp +#SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp HEADERS += $$PWD/utils/SettingConfig.h HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h -HEADERS += $$PWD/utils/QKafkaUtil.h +#HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/PhaseCompAcq/common/utils/DefHead.h b/PhaseCompAcq/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/PhaseCompAcq/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/PhaseCompAcq/common/utils/HttpRequestUtil.cpp b/PhaseCompAcq/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/PhaseCompAcq/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/PhaseCompAcq/common/utils/HttpRequestUtil.h b/PhaseCompAcq/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/PhaseCompAcq/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/PhaseCompAcq/common/utils/MD5.cpp b/PhaseCompAcq/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/PhaseCompAcq/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/PhaseCompAcq/common/utils/MD5.h b/PhaseCompAcq/common/utils/MD5.h new file mode 100644 index 0000000..5d86d32 --- /dev/null +++ b/PhaseCompAcq/common/utils/MD5.h @@ -0,0 +1,33 @@ +#ifndef MD5_H +#define MD5_H + +#include +#include +#include +#include"DefHead.h" + +#define SHORT_MD5_LEN 16 +#define CHAR_MD5_LEN 34 + + +class MD5 +{ +public: + explicit MD5(); + static void MD5Encode + ( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst + ); + + static bool MD5StrValidate + ( + _In_ const char* input1, + _In_ const char* input2 + ); +private: + ; +}; + +#endif // !MD5_H diff --git a/PhaseCompAcq/common/utils/QLogUtil.cpp b/PhaseCompAcq/common/utils/QLogUtil.cpp index 458ac15..43d8655 100644 --- a/PhaseCompAcq/common/utils/QLogUtil.cpp +++ b/PhaseCompAcq/common/utils/QLogUtil.cpp @@ -34,3 +34,59 @@ } +void QLogUtil::writeRawDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile rawLogFile(datePath + filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile chLogFile(datePath + filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::checkLogPath(QStringList path) +{ + QDir dir; + bool exist = false; + + for (int i = 0; i < path.size(); i++) + { + // 判断是否存在日志根目录 + exist = dir.exists(path.at(i)); + if (exist == false) + { + // 不存在则创建目录 + dir.mkdir(path.at(i)); + } + } +} diff --git a/PhaseCompAcq/common/utils/QLogUtil.h b/PhaseCompAcq/common/utils/QLogUtil.h index 8da0fcd..1d1ef0f 100644 --- a/PhaseCompAcq/common/utils/QLogUtil.h +++ b/PhaseCompAcq/common/utils/QLogUtil.h @@ -3,7 +3,9 @@ #include #include +#include #include +#include "SettingConfig.h" class QLogUtil : public QObject { @@ -16,6 +18,11 @@ static void writeInfoLog(QString message); static void writeDebugLog(QString message); + static void writeRawDataLogByDate(QString date, QString filename, QString content); + static void writeChannelDataLogByDate(QString date, QString filename, QString content); + +private: + static void checkLogPath(QStringList path); signals: }; diff --git a/PhaseCompAcq/common/utils/SettingConfig.cpp b/PhaseCompAcq/common/utils/SettingConfig.cpp index 67a8dd0..1f2ebb2 100644 --- a/PhaseCompAcq/common/utils/SettingConfig.cpp +++ b/PhaseCompAcq/common/utils/SettingConfig.cpp @@ -5,15 +5,18 @@ filename = QApplication::applicationDirPath() + "/conf/config.ini"; setting = new QSettings(this->filename, QSettings::IniFormat); - PORT_NAMES = getProperty("com", "portNames").toString(); BAUD_RATE = getProperty("com", "baudRate").toUInt(); - DEV_CODES = getProperty("com", "devCodes").toString(); NEED_KAFKA = getProperty("kafka", "needKafka").toUInt(); KAFKA_BROKERS = getProperty("kafka", "brokers").toString(); KAFKA_DATA_TOPIC = getProperty("kafka", "dataTopic").toString(); CLIENT_ID = getProperty("client", "clientId").toString(); + APP_KEY = getProperty("client", "appKey").toString(); + + BASE_URL = getProperty("http", "baseUrl").toString(); + + BASE_LOG_PATH = getProperty("log", "basePath").toString(); } diff --git a/CounterAcq/CounterAcq.pro b/CounterAcq/CounterAcq.pro index 72407cd..fae9d10 100644 --- a/CounterAcq/CounterAcq.pro +++ b/CounterAcq/CounterAcq.pro @@ -4,13 +4,6 @@ CONFIG += c++11 -SOURCES += \ - CounterWindow.cpp \ - main.cpp \ - -HEADERS += \ - CounterWindow.h \ - FORMS += \ CounterWindow.ui \ @@ -18,8 +11,11 @@ include(protocol/protocol.pri) HEADERS += CounterDevice.h +HEADERS += CounterWindow.h SOURCES += CounterDevice.cpp +SOURCES += CounterWindow.cpp +SOURCES += main.cpp DISTFILES += conf/config.ini diff --git a/CounterAcq/CounterWindow.cpp b/CounterAcq/CounterWindow.cpp index 80035a9..a50ebcf 100644 --- a/CounterAcq/CounterWindow.cpp +++ b/CounterAcq/CounterWindow.cpp @@ -42,7 +42,7 @@ { QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); - QApplication::exit(0); + QTimer::singleShot(1000, qApp, SLOT(quit())); } // 2. 获取字典值:设备类型 retCode = this->initDictDeviceTypes(); diff --git a/CounterAcq/CounterWindow.h b/CounterAcq/CounterWindow.h index 8d5e4a6..09277ba 100644 --- a/CounterAcq/CounterWindow.h +++ b/CounterAcq/CounterWindow.h @@ -7,7 +7,6 @@ #include #include "common/utils/SettingConfig.h" -#include "common/utils/QKafkaUtil.h" #include "common/HttpRequestController.h" #include "CounterDevice.h" @@ -23,8 +22,6 @@ explicit CounterWindow(QWidget *parent = nullptr); ~CounterWindow(); - QString token; - public slots: void drawCounterDataOnPage(CounterDataDto * counterData); @@ -40,7 +37,6 @@ Ui::CounterWindow *ui; - QTimer * timer; HttpRequestController * httpReq; QList deviceList; diff --git a/PhaseCompAcq/PhaseCompAcq.pro b/PhaseCompAcq/PhaseCompAcq.pro index 5eef2d1..c5e895b 100644 --- a/PhaseCompAcq/PhaseCompAcq.pro +++ b/PhaseCompAcq/PhaseCompAcq.pro @@ -1,16 +1,9 @@ -QT += core gui serialport +QT += core gui serialport network greaterThan(QT_MAJOR_VERSION, 4): QT += widgets CONFIG += c++11 -SOURCES += \ - main.cpp \ - PhaseWindow.cpp - -HEADERS += \ - PhaseWindow.h - FORMS += \ PhaseWindow.ui @@ -18,20 +11,19 @@ include(protocol/protocol.pri) HEADERS += PhaseDevice.h -#HEADERS += PhaseSerialServer.h +HEADERS += PhaseWindow.h SOURCES += PhaseDevice.cpp -#SOURCES += PhaseSerialServer.cpp +SOURCES += PhaseWindow.cpp +SOURCES += main.cpp # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target - -INCLUDEPATH += $$PWD/include/librdkafka -DEPENDPATH += $$PWD/include/librdkafka +#unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +#INCLUDEPATH += $$PWD/include/librdkafka +#DEPENDPATH += $$PWD/include/librdkafka DISTFILES += conf/config.ini - -unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ diff --git a/PhaseCompAcq/PhaseDevice.cpp b/PhaseCompAcq/PhaseDevice.cpp index 5c84cd5..afc2687 100644 --- a/PhaseCompAcq/PhaseDevice.cpp +++ b/PhaseCompAcq/PhaseDevice.cpp @@ -7,9 +7,9 @@ connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, this, &PhaseDevice::dataReceivedHandler); - kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); - kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); - kafkaUtil.createProducer(); +// kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); +// kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); +// kafkaUtil.createProducer(); } PhaseDevice::~PhaseDevice() @@ -34,6 +34,10 @@ { this->devCode = devCode; } +void PhaseDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} bool PhaseDevice::isSerialOpen() { @@ -74,6 +78,7 @@ if (parse == true) { QDateTime now = QDateTime::currentDateTime(); + phaseData->devCode = this->devCode; phaseData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); phaseData->milisecond = now.toMSecsSinceEpoch(); this->afterFramePhase(phaseData); @@ -92,21 +97,20 @@ this->dataBuff.clear(); // 2. 输出到日志文件中 - QString filePostfix = phaseData->timestamp.mid(0, 13).replace(" ", "_"); - QString filePrefix = QApplication::applicationDirPath() + "/logs/"; + QString date = phaseData->timestamp.mid(0, 10); // 2.1 原始字节数组数据 - QString filename = filePrefix + "raw_" + filePostfix + ".log"; + QString filename = "raw_" + devCode + ".log"; QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); - QLogUtil::writeRawDataLog(filename, content); + QLogUtil::writeRawDataLogByDate(date, filename, content); // 2.2 各个通道的相差数据 for (int i = 1; i <= phaseData->channelActive.size(); i++) { if (phaseData->channelActive.at(i-1).toUInt() == 1) { - QString chFilename("%1CH_%2_%3.log"); - chFilename = chFilename.arg(filePrefix); + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); if (i < 10) { chFilename = chFilename.arg(QString("0%1").arg(i)); @@ -114,10 +118,9 @@ { chFilename = chFilename.arg(i); } - chFilename = chFilename.arg(filePostfix); - QString channelDataStr = QString("%1 %2 %3").arg(phaseData->timestamp).arg(phaseData->channelData.at(i-1)).arg(phaseData->frameId); + QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelData.at(i-1)); - QLogUtil::writeChannelDataLog(chFilename, channelDataStr); + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); // 3. 输出到中间件,执行后续处理过程 if (SettingConfig::getInstance().NEED_KAFKA == 1) @@ -125,7 +128,7 @@ QJsonObject jsonObj = phaseData->toJSON(i - 1); jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); jsonObj.insert("deviceId", devCode); - kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); +// kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); } } } diff --git a/PhaseCompAcq/PhaseDevice.h b/PhaseCompAcq/PhaseDevice.h index 92182d4..aa7d822 100644 --- a/PhaseCompAcq/PhaseDevice.h +++ b/PhaseCompAcq/PhaseDevice.h @@ -5,7 +5,7 @@ #include "common/utils/QSerialPortUtil.h" #include "common/utils/QLogUtil.h" #include "common/utils/SettingConfig.h" -#include "common/utils/QKafkaUtil.h" +//#include "common/utils/QKafkaUtil.h" #include "protocol/PhaseProtocolBM.h" class PhaseDevice : public QObject @@ -25,15 +25,17 @@ void setBaudRate(int baudRate); QString getDevCode(); void setDevCode(QString devCode); + void setDeviceId(QString deviceId); bool isSerialOpen(); private: + QString deviceId; QString devCode; QString comName; int baudRate; QSerialPortUtil serialUtil; - QKafkaUtil kafkaUtil; +// QKafkaUtil kafkaUtil; QByteArray dataBuff; signals: diff --git a/PhaseCompAcq/PhaseWindow.cpp b/PhaseCompAcq/PhaseWindow.cpp index b3cab89..d0e8221 100644 --- a/PhaseCompAcq/PhaseWindow.cpp +++ b/PhaseCompAcq/PhaseWindow.cpp @@ -1,16 +1,16 @@ #include "PhaseWindow.h" #include "ui_PhaseWindow.h" -#include -#include -#include -#include -#include -#include - #include - -#include "common/utils/QKafkaUtil.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include PhaseWindow::PhaseWindow(QWidget *parent) : QWidget(parent), @@ -18,43 +18,74 @@ { ui->setupUi(this); - QString portNames = SettingConfig::getInstance().PORT_NAMES; - int baudRate = SettingConfig::getInstance().BAUD_RATE; - QString devCodes = SettingConfig::getInstance().DEV_CODES; + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); - QStringList comDevList = portNames.split(","); - QStringList devCodeList = devCodes.split(","); + // 窗口大小为占满一屏 + QRect screenRect = QApplication::desktop()->screenGeometry(); + resize(screenRect.width(), screenRect.height()); - for (int i = 0; i < comDevList.size(); i++) + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->line->setGeometry(0, 59, screenRect.width(), 1); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 60, screenRect.width(), screenRect.height() - 60); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + + httpReq = new HttpRequestController(this); + // 1. 获取访问接口需要的token + int retCode = this->initHttpToken(); + if (retCode != 200) { - PhaseDevice * device = new PhaseDevice(this); + QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); - // - connect(device, &PhaseDevice::sendDataToDraw, - this, &PhaseWindow::drawPhaseDataOnPage); + QTimer::singleShot(1000, qApp, SLOT(quit())); + } + // 2. 获取字典值:设备类型 + retCode = this->initDictDeviceTypes(); - device->setComName(comDevList.at(i)); - device->setBaudRate(baudRate); + // 3. 获取比相仪设备列表 + QJsonObject devListRes = this->initDeviceList(); + if (devListRes.find("code")->toInt() == 200) + { + ui->devSelect->clear(); - device->setDevCode(devCodeList.at(i)); + // 4. 将获取到的设备添加到下拉列表框中 + QJsonArray devArray = devListRes.find("data")->toArray(); + for (int i = 0; i < devArray.size(); i++) + { + QJsonObject devItem = devArray.at(i).toObject(); + ui->devSelect->addItem(devItem.find("deviceName")->toString(), devItem.find("deviceNo")->toString()); - this->deviceList.append(device); + PhaseDevice * device = new PhaseDevice(this); + deviceList.append(device); - device->initSerialPort(); - device->startWork(); + device->setComName(devItem.find("linkComName")->toString()); + device->setBaudRate(SettingConfig::getInstance().BAUD_RATE); + device->setDevCode(devItem.find("deviceNo")->toString()); + device->setDeviceId(devItem.find("deviceId")->toString()); + + connect(device, &PhaseDevice::sendDataToDraw, + this, &PhaseWindow::drawPhaseDataOnPage); + + device->initSerialPort(); + + QThread::msleep(100); + } + // 5. 设置下拉框的样式 + QStandardItemModel * model = qobject_cast(ui->devSelect->model()); + for (int i = 0; i < model->rowCount(); ++i) + { + QStandardItem * item = model->item(i); + item->setSizeHint({ 0, 30 }); + } } - for (int i = 0; i < this->deviceList.size(); i++) - { - QWidget * devWidget5 = new QWidget(this->ui->stackedWidget); - - this->ui->stackedWidget->addWidget(devWidget5); - - this->devWidgetList.append(devWidget5); - - // 创建设备的widget - this->generateWidgetForDevice(devCodeList.at(i), i); - } + // 6. 绘制一个设备的多个通道数据面板 + this->generateWidgetForDevice(); } PhaseWindow::~PhaseWindow() @@ -64,99 +95,119 @@ void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) { - // 1. 判断数据属于哪个设备,显示在不同的widget上 + // 当前显示的设备编号 + QString currentDevCode = ui->devSelect->currentData().toString(); - // 2. 循环设置各个tableView - QList devChannels = this->tableModelList.at(0); // 暂时写死 - for (int i = 0; i < phaseData->channelData.size(); i++) + // 如果不是当前设备的帧,直接返回 + if (phaseData->devCode != currentDevCode) { - if (phaseData->channelActive.at(i).toInt() == 1) - { - QList row; - QStandardItem * item = 0; - QStandardItem * item2 = 0; - item = new QStandardItem(QString("%1").arg(phaseData->timestamp.mid(11, 12))); - item2 = new QStandardItem(QString("%1").arg(phaseData->channelData.at(i))); + return; + } - row.append(item); - row.append(item2); + // 更新所有通道BOX的值 + for (int i = 0; i < phaseData->channelActive.size(); i++) + { + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); - QStandardItemModel * model; - model = devChannels.at(i); - if (model->rowCount() >= 60) - { - model->removeRows(0, model->rowCount()); - } - - model->insertRow(0, row); - } + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(phaseData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelData.at(i))); + ((QLineEdit *)channelBox->children().at(6))->setText(phaseData->frameId); + ((QLabel *)channelBox->children().at(7))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); } } -void PhaseWindow::generateWidgetForDevice(QString devCode, int index) +void PhaseWindow::generateWidgetForDevice() { - // 顶部切换widget - QWidget * switchWidget = new QWidget(this->devWidgetList.at(index)); - switchWidget->setGeometry(0, 0, 1024, 50); + // 获取设备数据 + int channelNum = 16; - // 显示数据的区域 - QWidget * gridWidget = new QWidget(this->devWidgetList.at(index)); - gridWidget->setGeometry(0, 50, 1024, 670); + QRect screenRect = QApplication::desktop()->screenGeometry(); - // 顶部水平布局,用于排布按钮 - QHBoxLayout * hLayout = new QHBoxLayout(switchWidget); + ui->scrollContents->setGeometry(0, 60, screenRect.width(), channelNum * 90); - // 文本 - QLabel * label = new QLabel(switchWidget); - label->setText("设备编号:" + devCode); - label->setFont(QFont("微软雅黑", 12)); - hLayout->addWidget(label); + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); - // 按钮 - for (int i = 0; i < this->deviceList.size(); i++) + for (int i = 0; i < channelNum; i++) { - QPushButton * butt5 = new QPushButton(this->deviceList.at(i)->getDevCode()); - hLayout->addWidget(butt5); + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 80 + 10, screenRect.width() - 40, 80); - connect(butt5, &QPushButton::clicked, [=](){ - this->ui->stackedWidget->setCurrentIndex(i); - }); + QHBoxLayout * vbox = new QHBoxLayout(group); + + QLabel * tmLabel = new QLabel(); + tmLabel->setText("时间"); + tmLabel->setFont(labelFont); + tmLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(tmLabel); + QLineEdit * tmValue = new QLineEdit(); + tmValue->setFixedWidth(200); + tmValue->setFont(labelFont); + vbox->addWidget(tmValue); + + QLabel * dataLabel = new QLabel(); + dataLabel->setText("测量数据"); + dataLabel->setFont(labelFont); + dataLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(dataLabel); + QLineEdit * dataValue = new QLineEdit(); + dataValue->setFixedWidth(150); + dataValue->setFont(labelFont); + vbox->addWidget(dataValue); + + QLabel * idLabel = new QLabel(); + idLabel->setText("数据ID"); + idLabel->setFont(labelFont); + idLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(idLabel); + QLineEdit * idValue = new QLineEdit(); + idValue->setFixedWidth(100); + idValue->setFont(labelFont); + vbox->addWidget(idValue); + + QLabel * validLabel = new QLabel(); + validLabel->setText("-"); + validLabel->setFont(labelFont); + validLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(validLabel); + + QSpacerItem * hSpace = new QSpacerItem(20, 20); + hSpace->changeSize(20, 20, QSizePolicy::Expanding); + vbox->addItem(hSpace); + + group->setLayout(vbox); + + layout->addWidget(group); } - - // Grid布局 - QGridLayout * gridLayout = new QGridLayout(gridWidget); - gridLayout->setSpacing(10); - - QList channelModelList; - QStringList labels = QObject::trUtf8("时间,相差").simplified().split(","); - - for (int i = 0; i < 16; i++) - { - QTableView * channelTable = new QTableView(gridWidget); - QStandardItemModel * model = new QStandardItemModel(channelTable); - - model->setHorizontalHeaderLabels(labels); - - channelTable->setModel(model); - - gridLayout->addWidget(channelTable, i / 4, i % 4); - - channelTable->verticalHeader()->hide(); - channelTable->setEditTriggers(QAbstractItemView::NoEditTriggers); - channelTable->scrollToBottom(); - - channelModelList.append(model); - } - - this->tableModelList.append(channelModelList); } -void PhaseWindow::createKafkaMessage() +int PhaseWindow::initHttpToken() { - this->kafkaUtil = new QKafkaUtil(this); - this->kafkaUtil->setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); - this->kafkaUtil->setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int PhaseWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject PhaseWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("比相仪"); + return response; +} - kafkaUtil->createProducer(); - kafkaUtil->produceMessage("hello world kafka kylin"); +void PhaseWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} + +void PhaseWindow::on_exitButt_clicked() +{ + QApplication::exit(0); } diff --git a/PhaseCompAcq/PhaseWindow.h b/PhaseCompAcq/PhaseWindow.h index 67b8363..02a7908 100644 --- a/PhaseCompAcq/PhaseWindow.h +++ b/PhaseCompAcq/PhaseWindow.h @@ -2,11 +2,13 @@ #define PHASEWINDOW_H #include +#include #include +#include #include "PhaseDevice.h" #include "common/utils/SettingConfig.h" -#include "common/utils/QKafkaUtil.h" +#include "common/HttpRequestController.h" namespace Ui { class PhaseWindow; @@ -23,18 +25,23 @@ public slots: void drawPhaseDataOnPage(PhaseDataDto * phaseData); +private slots: + void on_minButt_clicked(); + + void on_exitButt_clicked(); + private: + int initHttpToken(); + int initDictDeviceTypes(); + QJsonObject initDeviceList(); + Ui::PhaseWindow *ui; - QList devWidgetList; + HttpRequestController * httpReq; QList deviceList; - QList> tableModelList; - QKafkaUtil * kafkaUtil; - - void generateWidgetForDevice(QString devCode, int index); - void createKafkaMessage(); + void generateWidgetForDevice(); }; #endif // PHASEWINDOW_H diff --git a/PhaseCompAcq/PhaseWindow.ui b/PhaseCompAcq/PhaseWindow.ui index e6da880..01a7759 100644 --- a/PhaseCompAcq/PhaseWindow.ui +++ b/PhaseCompAcq/PhaseWindow.ui @@ -10,26 +10,144 @@ 720 - - - 1024 - 720 - - 多通道比相仪数据采集 - + 0 0 - 1024 - 720 + 100 + 30 - - -1 + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 100 + 30 + + + + + + + + 400 + 10 + 250 + 40 + + + + + + + 250 + 0 + 150 + 60 + + + + + 微软雅黑 + 12 + + + + Qt::LeftToRight + + + 请选择比相仪 + + + Qt::AlignCenter + + + + + + 880 + 10 + 40 + 40 + + + + + + + 退出 + + + + + + 20 + 0 + 200 + 60 + + + + + 微软雅黑 + 14 + + + + 多通道比相仪数据采集 + + + + + + 0 + 59 + 1024 + 1 + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + 830 + 10 + 40 + 40 + + + + + + + 最小化 diff --git a/PhaseCompAcq/common/ConstCache.h b/PhaseCompAcq/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/PhaseCompAcq/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/PhaseCompAcq/common/HttpRequestController.cpp b/PhaseCompAcq/common/HttpRequestController.cpp new file mode 100644 index 0000000..6abb5af --- /dev/null +++ b/PhaseCompAcq/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceTypes.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDeviceList(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", system.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); + } + + qDebug() << resultObj; + + return resultObj; +} diff --git a/PhaseCompAcq/common/HttpRequestController.h b/PhaseCompAcq/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/PhaseCompAcq/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/PhaseCompAcq/common/common.pri b/PhaseCompAcq/common/common.pri index 055a2db..84f57ae 100644 --- a/PhaseCompAcq/common/common.pri +++ b/PhaseCompAcq/common/common.pri @@ -3,10 +3,18 @@ SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp -SOURCES += $$PWD/utils/QKafkaUtil.cpp +#SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp HEADERS += $$PWD/utils/SettingConfig.h HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h -HEADERS += $$PWD/utils/QKafkaUtil.h +#HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/PhaseCompAcq/common/utils/DefHead.h b/PhaseCompAcq/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/PhaseCompAcq/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/PhaseCompAcq/common/utils/HttpRequestUtil.cpp b/PhaseCompAcq/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/PhaseCompAcq/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/PhaseCompAcq/common/utils/HttpRequestUtil.h b/PhaseCompAcq/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/PhaseCompAcq/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/PhaseCompAcq/common/utils/MD5.cpp b/PhaseCompAcq/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/PhaseCompAcq/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/PhaseCompAcq/common/utils/MD5.h b/PhaseCompAcq/common/utils/MD5.h new file mode 100644 index 0000000..5d86d32 --- /dev/null +++ b/PhaseCompAcq/common/utils/MD5.h @@ -0,0 +1,33 @@ +#ifndef MD5_H +#define MD5_H + +#include +#include +#include +#include"DefHead.h" + +#define SHORT_MD5_LEN 16 +#define CHAR_MD5_LEN 34 + + +class MD5 +{ +public: + explicit MD5(); + static void MD5Encode + ( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst + ); + + static bool MD5StrValidate + ( + _In_ const char* input1, + _In_ const char* input2 + ); +private: + ; +}; + +#endif // !MD5_H diff --git a/PhaseCompAcq/common/utils/QLogUtil.cpp b/PhaseCompAcq/common/utils/QLogUtil.cpp index 458ac15..43d8655 100644 --- a/PhaseCompAcq/common/utils/QLogUtil.cpp +++ b/PhaseCompAcq/common/utils/QLogUtil.cpp @@ -34,3 +34,59 @@ } +void QLogUtil::writeRawDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile rawLogFile(datePath + filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile chLogFile(datePath + filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::checkLogPath(QStringList path) +{ + QDir dir; + bool exist = false; + + for (int i = 0; i < path.size(); i++) + { + // 判断是否存在日志根目录 + exist = dir.exists(path.at(i)); + if (exist == false) + { + // 不存在则创建目录 + dir.mkdir(path.at(i)); + } + } +} diff --git a/PhaseCompAcq/common/utils/QLogUtil.h b/PhaseCompAcq/common/utils/QLogUtil.h index 8da0fcd..1d1ef0f 100644 --- a/PhaseCompAcq/common/utils/QLogUtil.h +++ b/PhaseCompAcq/common/utils/QLogUtil.h @@ -3,7 +3,9 @@ #include #include +#include #include +#include "SettingConfig.h" class QLogUtil : public QObject { @@ -16,6 +18,11 @@ static void writeInfoLog(QString message); static void writeDebugLog(QString message); + static void writeRawDataLogByDate(QString date, QString filename, QString content); + static void writeChannelDataLogByDate(QString date, QString filename, QString content); + +private: + static void checkLogPath(QStringList path); signals: }; diff --git a/PhaseCompAcq/common/utils/SettingConfig.cpp b/PhaseCompAcq/common/utils/SettingConfig.cpp index 67a8dd0..1f2ebb2 100644 --- a/PhaseCompAcq/common/utils/SettingConfig.cpp +++ b/PhaseCompAcq/common/utils/SettingConfig.cpp @@ -5,15 +5,18 @@ filename = QApplication::applicationDirPath() + "/conf/config.ini"; setting = new QSettings(this->filename, QSettings::IniFormat); - PORT_NAMES = getProperty("com", "portNames").toString(); BAUD_RATE = getProperty("com", "baudRate").toUInt(); - DEV_CODES = getProperty("com", "devCodes").toString(); NEED_KAFKA = getProperty("kafka", "needKafka").toUInt(); KAFKA_BROKERS = getProperty("kafka", "brokers").toString(); KAFKA_DATA_TOPIC = getProperty("kafka", "dataTopic").toString(); CLIENT_ID = getProperty("client", "clientId").toString(); + APP_KEY = getProperty("client", "appKey").toString(); + + BASE_URL = getProperty("http", "baseUrl").toString(); + + BASE_LOG_PATH = getProperty("log", "basePath").toString(); } diff --git a/PhaseCompAcq/common/utils/SettingConfig.h b/PhaseCompAcq/common/utils/SettingConfig.h index 2d10a4d..ce1e933 100644 --- a/PhaseCompAcq/common/utils/SettingConfig.h +++ b/PhaseCompAcq/common/utils/SettingConfig.h @@ -27,15 +27,18 @@ QVariant getProperty(QString nodeName, QString keyName); /******** 以下为需要的各类参数 ********/ - QString PORT_NAMES; int BAUD_RATE; - QString DEV_CODES; int NEED_KAFKA; QString KAFKA_BROKERS; QString KAFKA_DATA_TOPIC; QString CLIENT_ID; + QString APP_KEY; + + QString BASE_URL; + + QString BASE_LOG_PATH; private: SettingConfig(); diff --git a/CounterAcq/CounterAcq.pro b/CounterAcq/CounterAcq.pro index 72407cd..fae9d10 100644 --- a/CounterAcq/CounterAcq.pro +++ b/CounterAcq/CounterAcq.pro @@ -4,13 +4,6 @@ CONFIG += c++11 -SOURCES += \ - CounterWindow.cpp \ - main.cpp \ - -HEADERS += \ - CounterWindow.h \ - FORMS += \ CounterWindow.ui \ @@ -18,8 +11,11 @@ include(protocol/protocol.pri) HEADERS += CounterDevice.h +HEADERS += CounterWindow.h SOURCES += CounterDevice.cpp +SOURCES += CounterWindow.cpp +SOURCES += main.cpp DISTFILES += conf/config.ini diff --git a/CounterAcq/CounterWindow.cpp b/CounterAcq/CounterWindow.cpp index 80035a9..a50ebcf 100644 --- a/CounterAcq/CounterWindow.cpp +++ b/CounterAcq/CounterWindow.cpp @@ -42,7 +42,7 @@ { QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); - QApplication::exit(0); + QTimer::singleShot(1000, qApp, SLOT(quit())); } // 2. 获取字典值:设备类型 retCode = this->initDictDeviceTypes(); diff --git a/CounterAcq/CounterWindow.h b/CounterAcq/CounterWindow.h index 8d5e4a6..09277ba 100644 --- a/CounterAcq/CounterWindow.h +++ b/CounterAcq/CounterWindow.h @@ -7,7 +7,6 @@ #include #include "common/utils/SettingConfig.h" -#include "common/utils/QKafkaUtil.h" #include "common/HttpRequestController.h" #include "CounterDevice.h" @@ -23,8 +22,6 @@ explicit CounterWindow(QWidget *parent = nullptr); ~CounterWindow(); - QString token; - public slots: void drawCounterDataOnPage(CounterDataDto * counterData); @@ -40,7 +37,6 @@ Ui::CounterWindow *ui; - QTimer * timer; HttpRequestController * httpReq; QList deviceList; diff --git a/PhaseCompAcq/PhaseCompAcq.pro b/PhaseCompAcq/PhaseCompAcq.pro index 5eef2d1..c5e895b 100644 --- a/PhaseCompAcq/PhaseCompAcq.pro +++ b/PhaseCompAcq/PhaseCompAcq.pro @@ -1,16 +1,9 @@ -QT += core gui serialport +QT += core gui serialport network greaterThan(QT_MAJOR_VERSION, 4): QT += widgets CONFIG += c++11 -SOURCES += \ - main.cpp \ - PhaseWindow.cpp - -HEADERS += \ - PhaseWindow.h - FORMS += \ PhaseWindow.ui @@ -18,20 +11,19 @@ include(protocol/protocol.pri) HEADERS += PhaseDevice.h -#HEADERS += PhaseSerialServer.h +HEADERS += PhaseWindow.h SOURCES += PhaseDevice.cpp -#SOURCES += PhaseSerialServer.cpp +SOURCES += PhaseWindow.cpp +SOURCES += main.cpp # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target - -INCLUDEPATH += $$PWD/include/librdkafka -DEPENDPATH += $$PWD/include/librdkafka +#unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +#INCLUDEPATH += $$PWD/include/librdkafka +#DEPENDPATH += $$PWD/include/librdkafka DISTFILES += conf/config.ini - -unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ diff --git a/PhaseCompAcq/PhaseDevice.cpp b/PhaseCompAcq/PhaseDevice.cpp index 5c84cd5..afc2687 100644 --- a/PhaseCompAcq/PhaseDevice.cpp +++ b/PhaseCompAcq/PhaseDevice.cpp @@ -7,9 +7,9 @@ connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, this, &PhaseDevice::dataReceivedHandler); - kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); - kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); - kafkaUtil.createProducer(); +// kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); +// kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); +// kafkaUtil.createProducer(); } PhaseDevice::~PhaseDevice() @@ -34,6 +34,10 @@ { this->devCode = devCode; } +void PhaseDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} bool PhaseDevice::isSerialOpen() { @@ -74,6 +78,7 @@ if (parse == true) { QDateTime now = QDateTime::currentDateTime(); + phaseData->devCode = this->devCode; phaseData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); phaseData->milisecond = now.toMSecsSinceEpoch(); this->afterFramePhase(phaseData); @@ -92,21 +97,20 @@ this->dataBuff.clear(); // 2. 输出到日志文件中 - QString filePostfix = phaseData->timestamp.mid(0, 13).replace(" ", "_"); - QString filePrefix = QApplication::applicationDirPath() + "/logs/"; + QString date = phaseData->timestamp.mid(0, 10); // 2.1 原始字节数组数据 - QString filename = filePrefix + "raw_" + filePostfix + ".log"; + QString filename = "raw_" + devCode + ".log"; QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); - QLogUtil::writeRawDataLog(filename, content); + QLogUtil::writeRawDataLogByDate(date, filename, content); // 2.2 各个通道的相差数据 for (int i = 1; i <= phaseData->channelActive.size(); i++) { if (phaseData->channelActive.at(i-1).toUInt() == 1) { - QString chFilename("%1CH_%2_%3.log"); - chFilename = chFilename.arg(filePrefix); + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); if (i < 10) { chFilename = chFilename.arg(QString("0%1").arg(i)); @@ -114,10 +118,9 @@ { chFilename = chFilename.arg(i); } - chFilename = chFilename.arg(filePostfix); - QString channelDataStr = QString("%1 %2 %3").arg(phaseData->timestamp).arg(phaseData->channelData.at(i-1)).arg(phaseData->frameId); + QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelData.at(i-1)); - QLogUtil::writeChannelDataLog(chFilename, channelDataStr); + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); // 3. 输出到中间件,执行后续处理过程 if (SettingConfig::getInstance().NEED_KAFKA == 1) @@ -125,7 +128,7 @@ QJsonObject jsonObj = phaseData->toJSON(i - 1); jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); jsonObj.insert("deviceId", devCode); - kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); +// kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); } } } diff --git a/PhaseCompAcq/PhaseDevice.h b/PhaseCompAcq/PhaseDevice.h index 92182d4..aa7d822 100644 --- a/PhaseCompAcq/PhaseDevice.h +++ b/PhaseCompAcq/PhaseDevice.h @@ -5,7 +5,7 @@ #include "common/utils/QSerialPortUtil.h" #include "common/utils/QLogUtil.h" #include "common/utils/SettingConfig.h" -#include "common/utils/QKafkaUtil.h" +//#include "common/utils/QKafkaUtil.h" #include "protocol/PhaseProtocolBM.h" class PhaseDevice : public QObject @@ -25,15 +25,17 @@ void setBaudRate(int baudRate); QString getDevCode(); void setDevCode(QString devCode); + void setDeviceId(QString deviceId); bool isSerialOpen(); private: + QString deviceId; QString devCode; QString comName; int baudRate; QSerialPortUtil serialUtil; - QKafkaUtil kafkaUtil; +// QKafkaUtil kafkaUtil; QByteArray dataBuff; signals: diff --git a/PhaseCompAcq/PhaseWindow.cpp b/PhaseCompAcq/PhaseWindow.cpp index b3cab89..d0e8221 100644 --- a/PhaseCompAcq/PhaseWindow.cpp +++ b/PhaseCompAcq/PhaseWindow.cpp @@ -1,16 +1,16 @@ #include "PhaseWindow.h" #include "ui_PhaseWindow.h" -#include -#include -#include -#include -#include -#include - #include - -#include "common/utils/QKafkaUtil.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include PhaseWindow::PhaseWindow(QWidget *parent) : QWidget(parent), @@ -18,43 +18,74 @@ { ui->setupUi(this); - QString portNames = SettingConfig::getInstance().PORT_NAMES; - int baudRate = SettingConfig::getInstance().BAUD_RATE; - QString devCodes = SettingConfig::getInstance().DEV_CODES; + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); - QStringList comDevList = portNames.split(","); - QStringList devCodeList = devCodes.split(","); + // 窗口大小为占满一屏 + QRect screenRect = QApplication::desktop()->screenGeometry(); + resize(screenRect.width(), screenRect.height()); - for (int i = 0; i < comDevList.size(); i++) + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->line->setGeometry(0, 59, screenRect.width(), 1); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 60, screenRect.width(), screenRect.height() - 60); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + + httpReq = new HttpRequestController(this); + // 1. 获取访问接口需要的token + int retCode = this->initHttpToken(); + if (retCode != 200) { - PhaseDevice * device = new PhaseDevice(this); + QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); - // - connect(device, &PhaseDevice::sendDataToDraw, - this, &PhaseWindow::drawPhaseDataOnPage); + QTimer::singleShot(1000, qApp, SLOT(quit())); + } + // 2. 获取字典值:设备类型 + retCode = this->initDictDeviceTypes(); - device->setComName(comDevList.at(i)); - device->setBaudRate(baudRate); + // 3. 获取比相仪设备列表 + QJsonObject devListRes = this->initDeviceList(); + if (devListRes.find("code")->toInt() == 200) + { + ui->devSelect->clear(); - device->setDevCode(devCodeList.at(i)); + // 4. 将获取到的设备添加到下拉列表框中 + QJsonArray devArray = devListRes.find("data")->toArray(); + for (int i = 0; i < devArray.size(); i++) + { + QJsonObject devItem = devArray.at(i).toObject(); + ui->devSelect->addItem(devItem.find("deviceName")->toString(), devItem.find("deviceNo")->toString()); - this->deviceList.append(device); + PhaseDevice * device = new PhaseDevice(this); + deviceList.append(device); - device->initSerialPort(); - device->startWork(); + device->setComName(devItem.find("linkComName")->toString()); + device->setBaudRate(SettingConfig::getInstance().BAUD_RATE); + device->setDevCode(devItem.find("deviceNo")->toString()); + device->setDeviceId(devItem.find("deviceId")->toString()); + + connect(device, &PhaseDevice::sendDataToDraw, + this, &PhaseWindow::drawPhaseDataOnPage); + + device->initSerialPort(); + + QThread::msleep(100); + } + // 5. 设置下拉框的样式 + QStandardItemModel * model = qobject_cast(ui->devSelect->model()); + for (int i = 0; i < model->rowCount(); ++i) + { + QStandardItem * item = model->item(i); + item->setSizeHint({ 0, 30 }); + } } - for (int i = 0; i < this->deviceList.size(); i++) - { - QWidget * devWidget5 = new QWidget(this->ui->stackedWidget); - - this->ui->stackedWidget->addWidget(devWidget5); - - this->devWidgetList.append(devWidget5); - - // 创建设备的widget - this->generateWidgetForDevice(devCodeList.at(i), i); - } + // 6. 绘制一个设备的多个通道数据面板 + this->generateWidgetForDevice(); } PhaseWindow::~PhaseWindow() @@ -64,99 +95,119 @@ void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) { - // 1. 判断数据属于哪个设备,显示在不同的widget上 + // 当前显示的设备编号 + QString currentDevCode = ui->devSelect->currentData().toString(); - // 2. 循环设置各个tableView - QList devChannels = this->tableModelList.at(0); // 暂时写死 - for (int i = 0; i < phaseData->channelData.size(); i++) + // 如果不是当前设备的帧,直接返回 + if (phaseData->devCode != currentDevCode) { - if (phaseData->channelActive.at(i).toInt() == 1) - { - QList row; - QStandardItem * item = 0; - QStandardItem * item2 = 0; - item = new QStandardItem(QString("%1").arg(phaseData->timestamp.mid(11, 12))); - item2 = new QStandardItem(QString("%1").arg(phaseData->channelData.at(i))); + return; + } - row.append(item); - row.append(item2); + // 更新所有通道BOX的值 + for (int i = 0; i < phaseData->channelActive.size(); i++) + { + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); - QStandardItemModel * model; - model = devChannels.at(i); - if (model->rowCount() >= 60) - { - model->removeRows(0, model->rowCount()); - } - - model->insertRow(0, row); - } + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(phaseData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelData.at(i))); + ((QLineEdit *)channelBox->children().at(6))->setText(phaseData->frameId); + ((QLabel *)channelBox->children().at(7))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); } } -void PhaseWindow::generateWidgetForDevice(QString devCode, int index) +void PhaseWindow::generateWidgetForDevice() { - // 顶部切换widget - QWidget * switchWidget = new QWidget(this->devWidgetList.at(index)); - switchWidget->setGeometry(0, 0, 1024, 50); + // 获取设备数据 + int channelNum = 16; - // 显示数据的区域 - QWidget * gridWidget = new QWidget(this->devWidgetList.at(index)); - gridWidget->setGeometry(0, 50, 1024, 670); + QRect screenRect = QApplication::desktop()->screenGeometry(); - // 顶部水平布局,用于排布按钮 - QHBoxLayout * hLayout = new QHBoxLayout(switchWidget); + ui->scrollContents->setGeometry(0, 60, screenRect.width(), channelNum * 90); - // 文本 - QLabel * label = new QLabel(switchWidget); - label->setText("设备编号:" + devCode); - label->setFont(QFont("微软雅黑", 12)); - hLayout->addWidget(label); + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); - // 按钮 - for (int i = 0; i < this->deviceList.size(); i++) + for (int i = 0; i < channelNum; i++) { - QPushButton * butt5 = new QPushButton(this->deviceList.at(i)->getDevCode()); - hLayout->addWidget(butt5); + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 80 + 10, screenRect.width() - 40, 80); - connect(butt5, &QPushButton::clicked, [=](){ - this->ui->stackedWidget->setCurrentIndex(i); - }); + QHBoxLayout * vbox = new QHBoxLayout(group); + + QLabel * tmLabel = new QLabel(); + tmLabel->setText("时间"); + tmLabel->setFont(labelFont); + tmLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(tmLabel); + QLineEdit * tmValue = new QLineEdit(); + tmValue->setFixedWidth(200); + tmValue->setFont(labelFont); + vbox->addWidget(tmValue); + + QLabel * dataLabel = new QLabel(); + dataLabel->setText("测量数据"); + dataLabel->setFont(labelFont); + dataLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(dataLabel); + QLineEdit * dataValue = new QLineEdit(); + dataValue->setFixedWidth(150); + dataValue->setFont(labelFont); + vbox->addWidget(dataValue); + + QLabel * idLabel = new QLabel(); + idLabel->setText("数据ID"); + idLabel->setFont(labelFont); + idLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(idLabel); + QLineEdit * idValue = new QLineEdit(); + idValue->setFixedWidth(100); + idValue->setFont(labelFont); + vbox->addWidget(idValue); + + QLabel * validLabel = new QLabel(); + validLabel->setText("-"); + validLabel->setFont(labelFont); + validLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(validLabel); + + QSpacerItem * hSpace = new QSpacerItem(20, 20); + hSpace->changeSize(20, 20, QSizePolicy::Expanding); + vbox->addItem(hSpace); + + group->setLayout(vbox); + + layout->addWidget(group); } - - // Grid布局 - QGridLayout * gridLayout = new QGridLayout(gridWidget); - gridLayout->setSpacing(10); - - QList channelModelList; - QStringList labels = QObject::trUtf8("时间,相差").simplified().split(","); - - for (int i = 0; i < 16; i++) - { - QTableView * channelTable = new QTableView(gridWidget); - QStandardItemModel * model = new QStandardItemModel(channelTable); - - model->setHorizontalHeaderLabels(labels); - - channelTable->setModel(model); - - gridLayout->addWidget(channelTable, i / 4, i % 4); - - channelTable->verticalHeader()->hide(); - channelTable->setEditTriggers(QAbstractItemView::NoEditTriggers); - channelTable->scrollToBottom(); - - channelModelList.append(model); - } - - this->tableModelList.append(channelModelList); } -void PhaseWindow::createKafkaMessage() +int PhaseWindow::initHttpToken() { - this->kafkaUtil = new QKafkaUtil(this); - this->kafkaUtil->setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); - this->kafkaUtil->setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int PhaseWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject PhaseWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("比相仪"); + return response; +} - kafkaUtil->createProducer(); - kafkaUtil->produceMessage("hello world kafka kylin"); +void PhaseWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} + +void PhaseWindow::on_exitButt_clicked() +{ + QApplication::exit(0); } diff --git a/PhaseCompAcq/PhaseWindow.h b/PhaseCompAcq/PhaseWindow.h index 67b8363..02a7908 100644 --- a/PhaseCompAcq/PhaseWindow.h +++ b/PhaseCompAcq/PhaseWindow.h @@ -2,11 +2,13 @@ #define PHASEWINDOW_H #include +#include #include +#include #include "PhaseDevice.h" #include "common/utils/SettingConfig.h" -#include "common/utils/QKafkaUtil.h" +#include "common/HttpRequestController.h" namespace Ui { class PhaseWindow; @@ -23,18 +25,23 @@ public slots: void drawPhaseDataOnPage(PhaseDataDto * phaseData); +private slots: + void on_minButt_clicked(); + + void on_exitButt_clicked(); + private: + int initHttpToken(); + int initDictDeviceTypes(); + QJsonObject initDeviceList(); + Ui::PhaseWindow *ui; - QList devWidgetList; + HttpRequestController * httpReq; QList deviceList; - QList> tableModelList; - QKafkaUtil * kafkaUtil; - - void generateWidgetForDevice(QString devCode, int index); - void createKafkaMessage(); + void generateWidgetForDevice(); }; #endif // PHASEWINDOW_H diff --git a/PhaseCompAcq/PhaseWindow.ui b/PhaseCompAcq/PhaseWindow.ui index e6da880..01a7759 100644 --- a/PhaseCompAcq/PhaseWindow.ui +++ b/PhaseCompAcq/PhaseWindow.ui @@ -10,26 +10,144 @@ 720 - - - 1024 - 720 - - 多通道比相仪数据采集 - + 0 0 - 1024 - 720 + 100 + 30 - - -1 + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 100 + 30 + + + + + + + + 400 + 10 + 250 + 40 + + + + + + + 250 + 0 + 150 + 60 + + + + + 微软雅黑 + 12 + + + + Qt::LeftToRight + + + 请选择比相仪 + + + Qt::AlignCenter + + + + + + 880 + 10 + 40 + 40 + + + + + + + 退出 + + + + + + 20 + 0 + 200 + 60 + + + + + 微软雅黑 + 14 + + + + 多通道比相仪数据采集 + + + + + + 0 + 59 + 1024 + 1 + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + 830 + 10 + 40 + 40 + + + + + + + 最小化 diff --git a/PhaseCompAcq/common/ConstCache.h b/PhaseCompAcq/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/PhaseCompAcq/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/PhaseCompAcq/common/HttpRequestController.cpp b/PhaseCompAcq/common/HttpRequestController.cpp new file mode 100644 index 0000000..6abb5af --- /dev/null +++ b/PhaseCompAcq/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceTypes.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDeviceList(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", system.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); + } + + qDebug() << resultObj; + + return resultObj; +} diff --git a/PhaseCompAcq/common/HttpRequestController.h b/PhaseCompAcq/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/PhaseCompAcq/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/PhaseCompAcq/common/common.pri b/PhaseCompAcq/common/common.pri index 055a2db..84f57ae 100644 --- a/PhaseCompAcq/common/common.pri +++ b/PhaseCompAcq/common/common.pri @@ -3,10 +3,18 @@ SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp -SOURCES += $$PWD/utils/QKafkaUtil.cpp +#SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp HEADERS += $$PWD/utils/SettingConfig.h HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h -HEADERS += $$PWD/utils/QKafkaUtil.h +#HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/PhaseCompAcq/common/utils/DefHead.h b/PhaseCompAcq/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/PhaseCompAcq/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/PhaseCompAcq/common/utils/HttpRequestUtil.cpp b/PhaseCompAcq/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/PhaseCompAcq/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/PhaseCompAcq/common/utils/HttpRequestUtil.h b/PhaseCompAcq/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/PhaseCompAcq/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/PhaseCompAcq/common/utils/MD5.cpp b/PhaseCompAcq/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/PhaseCompAcq/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/PhaseCompAcq/common/utils/MD5.h b/PhaseCompAcq/common/utils/MD5.h new file mode 100644 index 0000000..5d86d32 --- /dev/null +++ b/PhaseCompAcq/common/utils/MD5.h @@ -0,0 +1,33 @@ +#ifndef MD5_H +#define MD5_H + +#include +#include +#include +#include"DefHead.h" + +#define SHORT_MD5_LEN 16 +#define CHAR_MD5_LEN 34 + + +class MD5 +{ +public: + explicit MD5(); + static void MD5Encode + ( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst + ); + + static bool MD5StrValidate + ( + _In_ const char* input1, + _In_ const char* input2 + ); +private: + ; +}; + +#endif // !MD5_H diff --git a/PhaseCompAcq/common/utils/QLogUtil.cpp b/PhaseCompAcq/common/utils/QLogUtil.cpp index 458ac15..43d8655 100644 --- a/PhaseCompAcq/common/utils/QLogUtil.cpp +++ b/PhaseCompAcq/common/utils/QLogUtil.cpp @@ -34,3 +34,59 @@ } +void QLogUtil::writeRawDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile rawLogFile(datePath + filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile chLogFile(datePath + filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::checkLogPath(QStringList path) +{ + QDir dir; + bool exist = false; + + for (int i = 0; i < path.size(); i++) + { + // 判断是否存在日志根目录 + exist = dir.exists(path.at(i)); + if (exist == false) + { + // 不存在则创建目录 + dir.mkdir(path.at(i)); + } + } +} diff --git a/PhaseCompAcq/common/utils/QLogUtil.h b/PhaseCompAcq/common/utils/QLogUtil.h index 8da0fcd..1d1ef0f 100644 --- a/PhaseCompAcq/common/utils/QLogUtil.h +++ b/PhaseCompAcq/common/utils/QLogUtil.h @@ -3,7 +3,9 @@ #include #include +#include #include +#include "SettingConfig.h" class QLogUtil : public QObject { @@ -16,6 +18,11 @@ static void writeInfoLog(QString message); static void writeDebugLog(QString message); + static void writeRawDataLogByDate(QString date, QString filename, QString content); + static void writeChannelDataLogByDate(QString date, QString filename, QString content); + +private: + static void checkLogPath(QStringList path); signals: }; diff --git a/PhaseCompAcq/common/utils/SettingConfig.cpp b/PhaseCompAcq/common/utils/SettingConfig.cpp index 67a8dd0..1f2ebb2 100644 --- a/PhaseCompAcq/common/utils/SettingConfig.cpp +++ b/PhaseCompAcq/common/utils/SettingConfig.cpp @@ -5,15 +5,18 @@ filename = QApplication::applicationDirPath() + "/conf/config.ini"; setting = new QSettings(this->filename, QSettings::IniFormat); - PORT_NAMES = getProperty("com", "portNames").toString(); BAUD_RATE = getProperty("com", "baudRate").toUInt(); - DEV_CODES = getProperty("com", "devCodes").toString(); NEED_KAFKA = getProperty("kafka", "needKafka").toUInt(); KAFKA_BROKERS = getProperty("kafka", "brokers").toString(); KAFKA_DATA_TOPIC = getProperty("kafka", "dataTopic").toString(); CLIENT_ID = getProperty("client", "clientId").toString(); + APP_KEY = getProperty("client", "appKey").toString(); + + BASE_URL = getProperty("http", "baseUrl").toString(); + + BASE_LOG_PATH = getProperty("log", "basePath").toString(); } diff --git a/PhaseCompAcq/common/utils/SettingConfig.h b/PhaseCompAcq/common/utils/SettingConfig.h index 2d10a4d..ce1e933 100644 --- a/PhaseCompAcq/common/utils/SettingConfig.h +++ b/PhaseCompAcq/common/utils/SettingConfig.h @@ -27,15 +27,18 @@ QVariant getProperty(QString nodeName, QString keyName); /******** 以下为需要的各类参数 ********/ - QString PORT_NAMES; int BAUD_RATE; - QString DEV_CODES; int NEED_KAFKA; QString KAFKA_BROKERS; QString KAFKA_DATA_TOPIC; QString CLIENT_ID; + QString APP_KEY; + + QString BASE_URL; + + QString BASE_LOG_PATH; private: SettingConfig(); diff --git a/PhaseCompAcq/conf/config.ini b/PhaseCompAcq/conf/config.ini index ed326b2..7d0fdb1 100644 --- a/PhaseCompAcq/conf/config.ini +++ b/PhaseCompAcq/conf/config.ini @@ -1,12 +1,17 @@ -[com] -portNames="COM3" -devCodes="9103" +[com] baudRate=115200 [kafka] -needKafka=1 +needKafka=0 brokers="111.198.10.15:12502" dataTopic="cppTest" [client] -clientId="112233445566" +clientId="phase" +appKey="bd593bdd20943d2db8af217c3712a460" + +[http] +baseUrl="http://111.198.10.15:11410" + +[log] +basePath="D:/Workspace Qt/ZXSSCJ-Release/Phase/logs/" diff --git a/CounterAcq/CounterAcq.pro b/CounterAcq/CounterAcq.pro index 72407cd..fae9d10 100644 --- a/CounterAcq/CounterAcq.pro +++ b/CounterAcq/CounterAcq.pro @@ -4,13 +4,6 @@ CONFIG += c++11 -SOURCES += \ - CounterWindow.cpp \ - main.cpp \ - -HEADERS += \ - CounterWindow.h \ - FORMS += \ CounterWindow.ui \ @@ -18,8 +11,11 @@ include(protocol/protocol.pri) HEADERS += CounterDevice.h +HEADERS += CounterWindow.h SOURCES += CounterDevice.cpp +SOURCES += CounterWindow.cpp +SOURCES += main.cpp DISTFILES += conf/config.ini diff --git a/CounterAcq/CounterWindow.cpp b/CounterAcq/CounterWindow.cpp index 80035a9..a50ebcf 100644 --- a/CounterAcq/CounterWindow.cpp +++ b/CounterAcq/CounterWindow.cpp @@ -42,7 +42,7 @@ { QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); - QApplication::exit(0); + QTimer::singleShot(1000, qApp, SLOT(quit())); } // 2. 获取字典值:设备类型 retCode = this->initDictDeviceTypes(); diff --git a/CounterAcq/CounterWindow.h b/CounterAcq/CounterWindow.h index 8d5e4a6..09277ba 100644 --- a/CounterAcq/CounterWindow.h +++ b/CounterAcq/CounterWindow.h @@ -7,7 +7,6 @@ #include #include "common/utils/SettingConfig.h" -#include "common/utils/QKafkaUtil.h" #include "common/HttpRequestController.h" #include "CounterDevice.h" @@ -23,8 +22,6 @@ explicit CounterWindow(QWidget *parent = nullptr); ~CounterWindow(); - QString token; - public slots: void drawCounterDataOnPage(CounterDataDto * counterData); @@ -40,7 +37,6 @@ Ui::CounterWindow *ui; - QTimer * timer; HttpRequestController * httpReq; QList deviceList; diff --git a/PhaseCompAcq/PhaseCompAcq.pro b/PhaseCompAcq/PhaseCompAcq.pro index 5eef2d1..c5e895b 100644 --- a/PhaseCompAcq/PhaseCompAcq.pro +++ b/PhaseCompAcq/PhaseCompAcq.pro @@ -1,16 +1,9 @@ -QT += core gui serialport +QT += core gui serialport network greaterThan(QT_MAJOR_VERSION, 4): QT += widgets CONFIG += c++11 -SOURCES += \ - main.cpp \ - PhaseWindow.cpp - -HEADERS += \ - PhaseWindow.h - FORMS += \ PhaseWindow.ui @@ -18,20 +11,19 @@ include(protocol/protocol.pri) HEADERS += PhaseDevice.h -#HEADERS += PhaseSerialServer.h +HEADERS += PhaseWindow.h SOURCES += PhaseDevice.cpp -#SOURCES += PhaseSerialServer.cpp +SOURCES += PhaseWindow.cpp +SOURCES += main.cpp # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target - -INCLUDEPATH += $$PWD/include/librdkafka -DEPENDPATH += $$PWD/include/librdkafka +#unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +#INCLUDEPATH += $$PWD/include/librdkafka +#DEPENDPATH += $$PWD/include/librdkafka DISTFILES += conf/config.ini - -unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ diff --git a/PhaseCompAcq/PhaseDevice.cpp b/PhaseCompAcq/PhaseDevice.cpp index 5c84cd5..afc2687 100644 --- a/PhaseCompAcq/PhaseDevice.cpp +++ b/PhaseCompAcq/PhaseDevice.cpp @@ -7,9 +7,9 @@ connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, this, &PhaseDevice::dataReceivedHandler); - kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); - kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); - kafkaUtil.createProducer(); +// kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); +// kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); +// kafkaUtil.createProducer(); } PhaseDevice::~PhaseDevice() @@ -34,6 +34,10 @@ { this->devCode = devCode; } +void PhaseDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} bool PhaseDevice::isSerialOpen() { @@ -74,6 +78,7 @@ if (parse == true) { QDateTime now = QDateTime::currentDateTime(); + phaseData->devCode = this->devCode; phaseData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); phaseData->milisecond = now.toMSecsSinceEpoch(); this->afterFramePhase(phaseData); @@ -92,21 +97,20 @@ this->dataBuff.clear(); // 2. 输出到日志文件中 - QString filePostfix = phaseData->timestamp.mid(0, 13).replace(" ", "_"); - QString filePrefix = QApplication::applicationDirPath() + "/logs/"; + QString date = phaseData->timestamp.mid(0, 10); // 2.1 原始字节数组数据 - QString filename = filePrefix + "raw_" + filePostfix + ".log"; + QString filename = "raw_" + devCode + ".log"; QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); - QLogUtil::writeRawDataLog(filename, content); + QLogUtil::writeRawDataLogByDate(date, filename, content); // 2.2 各个通道的相差数据 for (int i = 1; i <= phaseData->channelActive.size(); i++) { if (phaseData->channelActive.at(i-1).toUInt() == 1) { - QString chFilename("%1CH_%2_%3.log"); - chFilename = chFilename.arg(filePrefix); + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); if (i < 10) { chFilename = chFilename.arg(QString("0%1").arg(i)); @@ -114,10 +118,9 @@ { chFilename = chFilename.arg(i); } - chFilename = chFilename.arg(filePostfix); - QString channelDataStr = QString("%1 %2 %3").arg(phaseData->timestamp).arg(phaseData->channelData.at(i-1)).arg(phaseData->frameId); + QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelData.at(i-1)); - QLogUtil::writeChannelDataLog(chFilename, channelDataStr); + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); // 3. 输出到中间件,执行后续处理过程 if (SettingConfig::getInstance().NEED_KAFKA == 1) @@ -125,7 +128,7 @@ QJsonObject jsonObj = phaseData->toJSON(i - 1); jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); jsonObj.insert("deviceId", devCode); - kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); +// kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); } } } diff --git a/PhaseCompAcq/PhaseDevice.h b/PhaseCompAcq/PhaseDevice.h index 92182d4..aa7d822 100644 --- a/PhaseCompAcq/PhaseDevice.h +++ b/PhaseCompAcq/PhaseDevice.h @@ -5,7 +5,7 @@ #include "common/utils/QSerialPortUtil.h" #include "common/utils/QLogUtil.h" #include "common/utils/SettingConfig.h" -#include "common/utils/QKafkaUtil.h" +//#include "common/utils/QKafkaUtil.h" #include "protocol/PhaseProtocolBM.h" class PhaseDevice : public QObject @@ -25,15 +25,17 @@ void setBaudRate(int baudRate); QString getDevCode(); void setDevCode(QString devCode); + void setDeviceId(QString deviceId); bool isSerialOpen(); private: + QString deviceId; QString devCode; QString comName; int baudRate; QSerialPortUtil serialUtil; - QKafkaUtil kafkaUtil; +// QKafkaUtil kafkaUtil; QByteArray dataBuff; signals: diff --git a/PhaseCompAcq/PhaseWindow.cpp b/PhaseCompAcq/PhaseWindow.cpp index b3cab89..d0e8221 100644 --- a/PhaseCompAcq/PhaseWindow.cpp +++ b/PhaseCompAcq/PhaseWindow.cpp @@ -1,16 +1,16 @@ #include "PhaseWindow.h" #include "ui_PhaseWindow.h" -#include -#include -#include -#include -#include -#include - #include - -#include "common/utils/QKafkaUtil.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include PhaseWindow::PhaseWindow(QWidget *parent) : QWidget(parent), @@ -18,43 +18,74 @@ { ui->setupUi(this); - QString portNames = SettingConfig::getInstance().PORT_NAMES; - int baudRate = SettingConfig::getInstance().BAUD_RATE; - QString devCodes = SettingConfig::getInstance().DEV_CODES; + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); - QStringList comDevList = portNames.split(","); - QStringList devCodeList = devCodes.split(","); + // 窗口大小为占满一屏 + QRect screenRect = QApplication::desktop()->screenGeometry(); + resize(screenRect.width(), screenRect.height()); - for (int i = 0; i < comDevList.size(); i++) + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->line->setGeometry(0, 59, screenRect.width(), 1); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 60, screenRect.width(), screenRect.height() - 60); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + + httpReq = new HttpRequestController(this); + // 1. 获取访问接口需要的token + int retCode = this->initHttpToken(); + if (retCode != 200) { - PhaseDevice * device = new PhaseDevice(this); + QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); - // - connect(device, &PhaseDevice::sendDataToDraw, - this, &PhaseWindow::drawPhaseDataOnPage); + QTimer::singleShot(1000, qApp, SLOT(quit())); + } + // 2. 获取字典值:设备类型 + retCode = this->initDictDeviceTypes(); - device->setComName(comDevList.at(i)); - device->setBaudRate(baudRate); + // 3. 获取比相仪设备列表 + QJsonObject devListRes = this->initDeviceList(); + if (devListRes.find("code")->toInt() == 200) + { + ui->devSelect->clear(); - device->setDevCode(devCodeList.at(i)); + // 4. 将获取到的设备添加到下拉列表框中 + QJsonArray devArray = devListRes.find("data")->toArray(); + for (int i = 0; i < devArray.size(); i++) + { + QJsonObject devItem = devArray.at(i).toObject(); + ui->devSelect->addItem(devItem.find("deviceName")->toString(), devItem.find("deviceNo")->toString()); - this->deviceList.append(device); + PhaseDevice * device = new PhaseDevice(this); + deviceList.append(device); - device->initSerialPort(); - device->startWork(); + device->setComName(devItem.find("linkComName")->toString()); + device->setBaudRate(SettingConfig::getInstance().BAUD_RATE); + device->setDevCode(devItem.find("deviceNo")->toString()); + device->setDeviceId(devItem.find("deviceId")->toString()); + + connect(device, &PhaseDevice::sendDataToDraw, + this, &PhaseWindow::drawPhaseDataOnPage); + + device->initSerialPort(); + + QThread::msleep(100); + } + // 5. 设置下拉框的样式 + QStandardItemModel * model = qobject_cast(ui->devSelect->model()); + for (int i = 0; i < model->rowCount(); ++i) + { + QStandardItem * item = model->item(i); + item->setSizeHint({ 0, 30 }); + } } - for (int i = 0; i < this->deviceList.size(); i++) - { - QWidget * devWidget5 = new QWidget(this->ui->stackedWidget); - - this->ui->stackedWidget->addWidget(devWidget5); - - this->devWidgetList.append(devWidget5); - - // 创建设备的widget - this->generateWidgetForDevice(devCodeList.at(i), i); - } + // 6. 绘制一个设备的多个通道数据面板 + this->generateWidgetForDevice(); } PhaseWindow::~PhaseWindow() @@ -64,99 +95,119 @@ void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) { - // 1. 判断数据属于哪个设备,显示在不同的widget上 + // 当前显示的设备编号 + QString currentDevCode = ui->devSelect->currentData().toString(); - // 2. 循环设置各个tableView - QList devChannels = this->tableModelList.at(0); // 暂时写死 - for (int i = 0; i < phaseData->channelData.size(); i++) + // 如果不是当前设备的帧,直接返回 + if (phaseData->devCode != currentDevCode) { - if (phaseData->channelActive.at(i).toInt() == 1) - { - QList row; - QStandardItem * item = 0; - QStandardItem * item2 = 0; - item = new QStandardItem(QString("%1").arg(phaseData->timestamp.mid(11, 12))); - item2 = new QStandardItem(QString("%1").arg(phaseData->channelData.at(i))); + return; + } - row.append(item); - row.append(item2); + // 更新所有通道BOX的值 + for (int i = 0; i < phaseData->channelActive.size(); i++) + { + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); - QStandardItemModel * model; - model = devChannels.at(i); - if (model->rowCount() >= 60) - { - model->removeRows(0, model->rowCount()); - } - - model->insertRow(0, row); - } + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(phaseData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelData.at(i))); + ((QLineEdit *)channelBox->children().at(6))->setText(phaseData->frameId); + ((QLabel *)channelBox->children().at(7))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); } } -void PhaseWindow::generateWidgetForDevice(QString devCode, int index) +void PhaseWindow::generateWidgetForDevice() { - // 顶部切换widget - QWidget * switchWidget = new QWidget(this->devWidgetList.at(index)); - switchWidget->setGeometry(0, 0, 1024, 50); + // 获取设备数据 + int channelNum = 16; - // 显示数据的区域 - QWidget * gridWidget = new QWidget(this->devWidgetList.at(index)); - gridWidget->setGeometry(0, 50, 1024, 670); + QRect screenRect = QApplication::desktop()->screenGeometry(); - // 顶部水平布局,用于排布按钮 - QHBoxLayout * hLayout = new QHBoxLayout(switchWidget); + ui->scrollContents->setGeometry(0, 60, screenRect.width(), channelNum * 90); - // 文本 - QLabel * label = new QLabel(switchWidget); - label->setText("设备编号:" + devCode); - label->setFont(QFont("微软雅黑", 12)); - hLayout->addWidget(label); + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); - // 按钮 - for (int i = 0; i < this->deviceList.size(); i++) + for (int i = 0; i < channelNum; i++) { - QPushButton * butt5 = new QPushButton(this->deviceList.at(i)->getDevCode()); - hLayout->addWidget(butt5); + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 80 + 10, screenRect.width() - 40, 80); - connect(butt5, &QPushButton::clicked, [=](){ - this->ui->stackedWidget->setCurrentIndex(i); - }); + QHBoxLayout * vbox = new QHBoxLayout(group); + + QLabel * tmLabel = new QLabel(); + tmLabel->setText("时间"); + tmLabel->setFont(labelFont); + tmLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(tmLabel); + QLineEdit * tmValue = new QLineEdit(); + tmValue->setFixedWidth(200); + tmValue->setFont(labelFont); + vbox->addWidget(tmValue); + + QLabel * dataLabel = new QLabel(); + dataLabel->setText("测量数据"); + dataLabel->setFont(labelFont); + dataLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(dataLabel); + QLineEdit * dataValue = new QLineEdit(); + dataValue->setFixedWidth(150); + dataValue->setFont(labelFont); + vbox->addWidget(dataValue); + + QLabel * idLabel = new QLabel(); + idLabel->setText("数据ID"); + idLabel->setFont(labelFont); + idLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(idLabel); + QLineEdit * idValue = new QLineEdit(); + idValue->setFixedWidth(100); + idValue->setFont(labelFont); + vbox->addWidget(idValue); + + QLabel * validLabel = new QLabel(); + validLabel->setText("-"); + validLabel->setFont(labelFont); + validLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(validLabel); + + QSpacerItem * hSpace = new QSpacerItem(20, 20); + hSpace->changeSize(20, 20, QSizePolicy::Expanding); + vbox->addItem(hSpace); + + group->setLayout(vbox); + + layout->addWidget(group); } - - // Grid布局 - QGridLayout * gridLayout = new QGridLayout(gridWidget); - gridLayout->setSpacing(10); - - QList channelModelList; - QStringList labels = QObject::trUtf8("时间,相差").simplified().split(","); - - for (int i = 0; i < 16; i++) - { - QTableView * channelTable = new QTableView(gridWidget); - QStandardItemModel * model = new QStandardItemModel(channelTable); - - model->setHorizontalHeaderLabels(labels); - - channelTable->setModel(model); - - gridLayout->addWidget(channelTable, i / 4, i % 4); - - channelTable->verticalHeader()->hide(); - channelTable->setEditTriggers(QAbstractItemView::NoEditTriggers); - channelTable->scrollToBottom(); - - channelModelList.append(model); - } - - this->tableModelList.append(channelModelList); } -void PhaseWindow::createKafkaMessage() +int PhaseWindow::initHttpToken() { - this->kafkaUtil = new QKafkaUtil(this); - this->kafkaUtil->setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); - this->kafkaUtil->setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int PhaseWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject PhaseWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("比相仪"); + return response; +} - kafkaUtil->createProducer(); - kafkaUtil->produceMessage("hello world kafka kylin"); +void PhaseWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} + +void PhaseWindow::on_exitButt_clicked() +{ + QApplication::exit(0); } diff --git a/PhaseCompAcq/PhaseWindow.h b/PhaseCompAcq/PhaseWindow.h index 67b8363..02a7908 100644 --- a/PhaseCompAcq/PhaseWindow.h +++ b/PhaseCompAcq/PhaseWindow.h @@ -2,11 +2,13 @@ #define PHASEWINDOW_H #include +#include #include +#include #include "PhaseDevice.h" #include "common/utils/SettingConfig.h" -#include "common/utils/QKafkaUtil.h" +#include "common/HttpRequestController.h" namespace Ui { class PhaseWindow; @@ -23,18 +25,23 @@ public slots: void drawPhaseDataOnPage(PhaseDataDto * phaseData); +private slots: + void on_minButt_clicked(); + + void on_exitButt_clicked(); + private: + int initHttpToken(); + int initDictDeviceTypes(); + QJsonObject initDeviceList(); + Ui::PhaseWindow *ui; - QList devWidgetList; + HttpRequestController * httpReq; QList deviceList; - QList> tableModelList; - QKafkaUtil * kafkaUtil; - - void generateWidgetForDevice(QString devCode, int index); - void createKafkaMessage(); + void generateWidgetForDevice(); }; #endif // PHASEWINDOW_H diff --git a/PhaseCompAcq/PhaseWindow.ui b/PhaseCompAcq/PhaseWindow.ui index e6da880..01a7759 100644 --- a/PhaseCompAcq/PhaseWindow.ui +++ b/PhaseCompAcq/PhaseWindow.ui @@ -10,26 +10,144 @@ 720 - - - 1024 - 720 - - 多通道比相仪数据采集 - + 0 0 - 1024 - 720 + 100 + 30 - - -1 + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 100 + 30 + + + + + + + + 400 + 10 + 250 + 40 + + + + + + + 250 + 0 + 150 + 60 + + + + + 微软雅黑 + 12 + + + + Qt::LeftToRight + + + 请选择比相仪 + + + Qt::AlignCenter + + + + + + 880 + 10 + 40 + 40 + + + + + + + 退出 + + + + + + 20 + 0 + 200 + 60 + + + + + 微软雅黑 + 14 + + + + 多通道比相仪数据采集 + + + + + + 0 + 59 + 1024 + 1 + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + 830 + 10 + 40 + 40 + + + + + + + 最小化 diff --git a/PhaseCompAcq/common/ConstCache.h b/PhaseCompAcq/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/PhaseCompAcq/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/PhaseCompAcq/common/HttpRequestController.cpp b/PhaseCompAcq/common/HttpRequestController.cpp new file mode 100644 index 0000000..6abb5af --- /dev/null +++ b/PhaseCompAcq/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceTypes.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDeviceList(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", system.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); + } + + qDebug() << resultObj; + + return resultObj; +} diff --git a/PhaseCompAcq/common/HttpRequestController.h b/PhaseCompAcq/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/PhaseCompAcq/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/PhaseCompAcq/common/common.pri b/PhaseCompAcq/common/common.pri index 055a2db..84f57ae 100644 --- a/PhaseCompAcq/common/common.pri +++ b/PhaseCompAcq/common/common.pri @@ -3,10 +3,18 @@ SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp -SOURCES += $$PWD/utils/QKafkaUtil.cpp +#SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp HEADERS += $$PWD/utils/SettingConfig.h HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h -HEADERS += $$PWD/utils/QKafkaUtil.h +#HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/PhaseCompAcq/common/utils/DefHead.h b/PhaseCompAcq/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/PhaseCompAcq/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/PhaseCompAcq/common/utils/HttpRequestUtil.cpp b/PhaseCompAcq/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/PhaseCompAcq/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/PhaseCompAcq/common/utils/HttpRequestUtil.h b/PhaseCompAcq/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/PhaseCompAcq/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/PhaseCompAcq/common/utils/MD5.cpp b/PhaseCompAcq/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/PhaseCompAcq/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/PhaseCompAcq/common/utils/MD5.h b/PhaseCompAcq/common/utils/MD5.h new file mode 100644 index 0000000..5d86d32 --- /dev/null +++ b/PhaseCompAcq/common/utils/MD5.h @@ -0,0 +1,33 @@ +#ifndef MD5_H +#define MD5_H + +#include +#include +#include +#include"DefHead.h" + +#define SHORT_MD5_LEN 16 +#define CHAR_MD5_LEN 34 + + +class MD5 +{ +public: + explicit MD5(); + static void MD5Encode + ( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst + ); + + static bool MD5StrValidate + ( + _In_ const char* input1, + _In_ const char* input2 + ); +private: + ; +}; + +#endif // !MD5_H diff --git a/PhaseCompAcq/common/utils/QLogUtil.cpp b/PhaseCompAcq/common/utils/QLogUtil.cpp index 458ac15..43d8655 100644 --- a/PhaseCompAcq/common/utils/QLogUtil.cpp +++ b/PhaseCompAcq/common/utils/QLogUtil.cpp @@ -34,3 +34,59 @@ } +void QLogUtil::writeRawDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile rawLogFile(datePath + filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile chLogFile(datePath + filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::checkLogPath(QStringList path) +{ + QDir dir; + bool exist = false; + + for (int i = 0; i < path.size(); i++) + { + // 判断是否存在日志根目录 + exist = dir.exists(path.at(i)); + if (exist == false) + { + // 不存在则创建目录 + dir.mkdir(path.at(i)); + } + } +} diff --git a/PhaseCompAcq/common/utils/QLogUtil.h b/PhaseCompAcq/common/utils/QLogUtil.h index 8da0fcd..1d1ef0f 100644 --- a/PhaseCompAcq/common/utils/QLogUtil.h +++ b/PhaseCompAcq/common/utils/QLogUtil.h @@ -3,7 +3,9 @@ #include #include +#include #include +#include "SettingConfig.h" class QLogUtil : public QObject { @@ -16,6 +18,11 @@ static void writeInfoLog(QString message); static void writeDebugLog(QString message); + static void writeRawDataLogByDate(QString date, QString filename, QString content); + static void writeChannelDataLogByDate(QString date, QString filename, QString content); + +private: + static void checkLogPath(QStringList path); signals: }; diff --git a/PhaseCompAcq/common/utils/SettingConfig.cpp b/PhaseCompAcq/common/utils/SettingConfig.cpp index 67a8dd0..1f2ebb2 100644 --- a/PhaseCompAcq/common/utils/SettingConfig.cpp +++ b/PhaseCompAcq/common/utils/SettingConfig.cpp @@ -5,15 +5,18 @@ filename = QApplication::applicationDirPath() + "/conf/config.ini"; setting = new QSettings(this->filename, QSettings::IniFormat); - PORT_NAMES = getProperty("com", "portNames").toString(); BAUD_RATE = getProperty("com", "baudRate").toUInt(); - DEV_CODES = getProperty("com", "devCodes").toString(); NEED_KAFKA = getProperty("kafka", "needKafka").toUInt(); KAFKA_BROKERS = getProperty("kafka", "brokers").toString(); KAFKA_DATA_TOPIC = getProperty("kafka", "dataTopic").toString(); CLIENT_ID = getProperty("client", "clientId").toString(); + APP_KEY = getProperty("client", "appKey").toString(); + + BASE_URL = getProperty("http", "baseUrl").toString(); + + BASE_LOG_PATH = getProperty("log", "basePath").toString(); } diff --git a/PhaseCompAcq/common/utils/SettingConfig.h b/PhaseCompAcq/common/utils/SettingConfig.h index 2d10a4d..ce1e933 100644 --- a/PhaseCompAcq/common/utils/SettingConfig.h +++ b/PhaseCompAcq/common/utils/SettingConfig.h @@ -27,15 +27,18 @@ QVariant getProperty(QString nodeName, QString keyName); /******** 以下为需要的各类参数 ********/ - QString PORT_NAMES; int BAUD_RATE; - QString DEV_CODES; int NEED_KAFKA; QString KAFKA_BROKERS; QString KAFKA_DATA_TOPIC; QString CLIENT_ID; + QString APP_KEY; + + QString BASE_URL; + + QString BASE_LOG_PATH; private: SettingConfig(); diff --git a/PhaseCompAcq/conf/config.ini b/PhaseCompAcq/conf/config.ini index ed326b2..7d0fdb1 100644 --- a/PhaseCompAcq/conf/config.ini +++ b/PhaseCompAcq/conf/config.ini @@ -1,12 +1,17 @@ -[com] -portNames="COM3" -devCodes="9103" +[com] baudRate=115200 [kafka] -needKafka=1 +needKafka=0 brokers="111.198.10.15:12502" dataTopic="cppTest" [client] -clientId="112233445566" +clientId="phase" +appKey="bd593bdd20943d2db8af217c3712a460" + +[http] +baseUrl="http://111.198.10.15:11410" + +[log] +basePath="D:/Workspace Qt/ZXSSCJ-Release/Phase/logs/" diff --git a/ZXSSCJ.pro b/ZXSSCJ.pro index 196b1a8..65aaacc 100644 --- a/ZXSSCJ.pro +++ b/ZXSSCJ.pro @@ -3,7 +3,7 @@ #定义了ordered表示子项目按照添加的顺序来编译 #CONFIG += ordered -SUBDIRS += CounterAcq #计数器数据采集 -#SUBDIRS += PhaseCompAcq #比相仪数据采集 -SUBDIRS += DevStatusAcq +#SUBDIRS += CounterAcq #计数器数据采集 +SUBDIRS += PhaseCompAcq #比相仪数据采集 +#SUBDIRS += DevStatusAcq #SUBDIRS += HClockAcq #氢钟状态数据采集