diff --git a/app/config/config.ini b/app/config/config.ini index dad4d6d..05b9b64 100644 --- a/app/config/config.ini +++ b/app/config/config.ini @@ -8,7 +8,7 @@ up_result=true use_socket_server=false [interface] -http_ip=192.168.2.108 +http_ip=192.168.2.212 http_port=20004 token_path=/api/token_path up_result_path=/api/train-carriage/identification/rfid-save @@ -16,5 +16,5 @@ username=guest_01 password=d55b0f642e817eea24725d2f2a31dd08 [socket_server] -server_ip=172.18.160.1 +server_ip=192.168.2.212 server_port=7000 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3bb309c..78dc96b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -37,6 +37,7 @@ find_package(Qt5 COMPONENTS QT5_WRAP_CPP(MOC_Files qt_source/mainwindow.h interface/TcpClient.h + threads/UpResultThread.h ) include_directories( @@ -102,6 +103,8 @@ file(GLOB_RECURSE COMMON_SRCS_LISTS ConfigUtil/*.cpp # interface interface/*.cpp + # threads + threads/*.cpp # 串口信息处理逻辑 serial/*.cpp ) diff --git a/src/common/common.h b/src/common/common.h index fb50356..c35cf20 100644 --- a/src/common/common.h +++ b/src/common/common.h @@ -17,5 +17,20 @@ #include "Log.h" #include "StringUtil.h" +namespace ai_matrix { + const QString g_config_path = "./config/config.ini"; + + struct TrainInfo { + std::string carriageType; + std::string carriageNum; + std::string strOrder; + std::string trainTime; + std::string collectTime; + std::string strRfidInfo; + }; + +} + + #endif //TRAIN_RFID_COMMON_H diff --git a/src/main.cpp b/src/main.cpp index 5549d35..aa99649 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3,6 +3,25 @@ #include "TcpClient.h" #include "common.h" +void myMessageOutput(QtMsgType type, const QMessageLogContext& context, const QString& msg) { + switch (type) { + case QtDebugMsg: + // 处理debug信息 + break; + case QtWarningMsg: + // 处理警告信息 + break; + case QtCriticalMsg: + // 处理严重错误信息 + LogError<<"严重异常"; + break; + case QtFatalMsg: + // 处理致命错误信息 + LogError<<"致命异常"; + break; + } +} + int main(int argc, char *argv[]) { QApplication a(argc, argv); @@ -40,6 +59,7 @@ int main(int argc, char *argv[]) { { SetConsoleOutputCP(CP_UTF8); QApplication::setWindowIcon(QIcon("./logo.ico")); + qInstallMessageHandler(myMessageOutput); MainWindow w; w.show(); diff --git a/src/qt_source/mainwindow.cpp b/src/qt_source/mainwindow.cpp index b72c416..4a85ef0 100644 --- a/src/qt_source/mainwindow.cpp +++ b/src/qt_source/mainwindow.cpp @@ -152,42 +152,13 @@ MainWindow::MainWindow(QWidget *parent) ui->openComButton->click(); -// QThread *thread = new QThread; -// // 创建并移至线程的lambda表达式 -// moveToThread(thread); -// connect(thread, &QThread::started, [=]() { -//// // 配置文件读取 -//// QString errorMessage = ""; -//// ai_matrix::BaseConfig baseConfig; -//// ai_matrix::InterfaceConfig interfaceConfig; -//// if (!ConfigUtil::readBaseConfig(this->configPath_, errorMessage, baseConfig)) -//// { -//// this->logError(errorMessage); -//// } -//// if (!ConfigUtil::readInterfaceConfig(this->configPath_, errorMessage, interfaceConfig)) -//// { -//// this->logError(errorMessage); -//// } -// -// while (true) -// { -//// if ((this->iDirection == 0 && this->queueTrainInfo_.size() <= 4) || this->iDirection < 0) continue; -// while (!this->queueTrainInfo_.isEmpty()) -// { -// TrainInfo trainInfo_ = this->queueTrainInfo_.pop(); -// if (!this->upWeb(trainInfo_)) -// { -// //this->logError("第" + QString::fromStdString(trainInfo.strOrder) + "节,识别结果上传失败!"); -// } -// -//// QThread::msleep(1000); -// } -// QThread::msleep(2000); -// } -// }); -// -// connect(thread, &QThread::finished, thread, &QObject::deleteLater); -// thread->start(); + this->upResultThread = new UpResultThread(&this->queueTrainInfo_, &this->iDirection, this); + this->upResultThread->start(); + + connect(this->upResultThread, &UpResultThread::DebugSignals, this, &MainWindow::DebugSlots); + connect(this->upResultThread, &UpResultThread::InfoSignals, this, &MainWindow::InfoSlots); + connect(this->upResultThread, &UpResultThread::WarnSignals, this, &MainWindow::WarnSlots); + connect(this->upResultThread, &UpResultThread::ErrorSignals, this, &MainWindow::ErrorSlots); } MainWindow::~MainWindow() @@ -389,175 +360,6 @@ QStandardItem* MainWindow::getStandardItem(const QString &value) return resultTableItem; } - -/******************************同 web 交互****************************************/ - -/** - * @brief:Http发送RFID数据 - * @param:carriageType:车型 - * @param:carriageNumber:车号 - * @param:carriageOrder:车节号 - * @param:time:当前时间 - * @param:rfidSourceInfo:RFID的原始数据(过滤掉了重复磁条信息) - * @return: 成功:true - * 失败:false - */ -bool MainWindow::upWeb(TrainInfo &trainInfo) -{ - try { - Json::Value arrayObj; //构建对象 - - arrayObj["comeTime"] = trainInfo.trainTime; - arrayObj["collectTime"] = trainInfo.collectTime; - arrayObj["carriageNumber"] = trainInfo.carriageNum; - arrayObj["carriageType"] = trainInfo.carriageType; - arrayObj["carriageOrder"] = trainInfo.strOrder; -// arrayObj["steel"] = trainInfo.strRfidInfo; - - Json::Value trainParams; - trainParams["poundNo"] = std::to_string(this->baseConfig_.trackName); - arrayObj["trainParams"] = trainParams; - Json::StreamWriterBuilder writer; - std::string str = Json::writeString(writer, arrayObj); - - this->logInfo("第" + QString::fromStdString(trainInfo.strOrder) + "节,发送web: " + QString::fromStdString(str)); - httplib::Client cli(this->interfaceConfig_.httpIp.toStdString(), this->interfaceConfig_.httpPort); - - cli.set_connection_timeout(3, 0); - cli.set_read_timeout(0, 700 * 1000); - httplib::Headers header; - httplib::Params params; - header.emplace("blade-auth", this->webToken); - //header.emplace("Content-Type", "application/json"); - - auto res = cli.Post(this->interfaceConfig_.upResultPath.toStdString(), header, str, "application/json"); - - if (res) - { - if (res->status == 200) - { - this->logInfo("第" + QString::fromStdString(trainInfo.strOrder) + "节,web返回: " + QString::fromStdString(res->body)); - Json::CharReaderBuilder readerBuilder; - std::istringstream iss(res->body); - Json::Value root; - std::string errs; - bool parsingSuccessful = Json::parseFromStream(readerBuilder, iss, &root, &errs); - if (parsingSuccessful) - { - if (root["success"].asBool()) - { - return true; - } - else - { - - if (root["msg"].asString() == "请求未授权") { - this->logWarn("第" + QString::fromStdString(trainInfo.strOrder) + "节,因请求未授权,而上传识别结果失败!重新请求token。"); - if (!this->getToken()) return false; - return this->upWeb(trainInfo); - } - this->logError("第" + QString::fromStdString(trainInfo.strOrder) + "节,识别结果上传失败,原因:" + QString::fromStdString(root["msg"].asString())); - } - } - else - { - this->logError("第" + QString::fromStdString(trainInfo.strOrder) + "节,识别结果上传失败,返回数据解析异常,返回数据非json:" + QString::fromStdString(res->body)); - } - } - else - { - this->logError("第" + QString::fromStdString(trainInfo.strOrder) + "节,识别结果上传失败,原因:" + QString::number(res->status) + " - " + QString::fromStdString(res->body)); - if (res->status == 401) { - this->logWarn("因请求未授权,而上传识别结果失败!重新请求token。"); - this->getToken(); - return this->upWeb(trainInfo); - } - } - } - else - { - this->logError("第" + QString::fromStdString(trainInfo.strOrder) + "节,上传数据失败,请检查网络,或者上传地址!"); - } - } - catch (std::exception &e) - { - this->logError("第" + QString::fromStdString(trainInfo.strOrder) + "节,上传识别结果失败,原因:"); - this->logError(e.what()); - } - return false; -} - -/** - * @brief:Http获取授权 - * @param: - * @return: - */ -bool MainWindow::getToken() -{ - try - { - httplib::Client cli(this->interfaceConfig_.httpIp.toStdString(), this->interfaceConfig_.httpPort); - cli.set_connection_timeout(0, 300 * 1000); - cli.set_read_timeout(0,300*1000); - httplib::Headers header; - httplib::Params params; - - header.emplace("Authorization", "Basic Y2xpZW50X2VudGVycHJpc2U6Y2xpZW50X2VudGVycHJpc2Vfc2VjcmV0"); - - params.emplace("username", this->interfaceConfig_.username.toStdString()); - params.emplace("password", this->interfaceConfig_.password.toStdString()); - params.emplace("tenantId", "000000"); - params.emplace("grant_type", "password"); - auto res = cli.Post("/api/blade-auth/oauth/token", header, params); - if (res) - { - if (res->status == 200) - { - Json::CharReaderBuilder readerBuilder; - std::istringstream iss(res->body); - Json::Value root; - std::string errs; - bool parsingSuccessful = Json::parseFromStream(readerBuilder, iss, &root, &errs); - - if (parsingSuccessful) - { - if (!root.get("token_type", "").asString().empty()) - { - this->webToken = root["token_type"].asString(); - this->webToken.append(" "); - this->webToken.append(root["access_token"].asString()); - this->logInfo("已获取到web token"); - return true; - } - else - { - this->logError("获取web token失败,原因:" + QString::fromStdString(res->body)); - } - } - else - { - this->logError("获取web token返回数据解析异常,返回数据非json。详细:" + QString::fromStdString(res->body)); - } - } - } - else - { - auto err = res.error(); -// if (err == httplib::Error::Connection) { -// std::cout << " (连接出错)" << std::endl; -// } - this->logError("获取web token失败!请检查网络或请求地址。详细:" + QString::fromStdString(to_string(err))); - } - } - catch (std::exception &e) - { - this->logError("获取授权失败,原因:"); - this->logError(e.what()); - } - return false; -} - - /***************************最小化相关****************************************/ /** * @brief:接收最小化信号 @@ -630,26 +432,6 @@ void MainWindow::on_ShowMainAction() this->activateWindow(); } -/** - * @brief:最小化 - * @param: - * @return:空 - */ -void MainWindow::on_ExitAppAction() -{ - // 弹出对话框要求用户输入密码 - QString password = QInputDialog::getText(this, "密码验证", "请输入密码:", QLineEdit::Password); - - // 验证账号和密码是否正确 - if (password == "matrix") { - this->initParam(); - this->tcp_->close(); - exit(0); - } else { - QMessageBox::warning(this, "验证失败", "密码不正确!"); - } -} - void MainWindow::on_activatedSysTrayIcon(QSystemTrayIcon::ActivationReason reason) { switch(reason){ @@ -895,17 +677,6 @@ void MainWindow::upRfid(QString rfidInfo) trainInfo.strRfidInfo = rfidInfo.toStdString(); this->queueTrainInfo_.push(trainInfo); -// QtConcurrent::run([=](){ - if ((this->iDirection == 0 && this->queueTrainInfo_.size() <= 4) || this->iDirection < 0) return; - while (!this->queueTrainInfo_.isEmpty()) - { - TrainInfo trainInfo_ = this->queueTrainInfo_.pop(); - if (!this->upWeb(trainInfo_)) - { - //this->logError("第" + QString::fromStdString(trainInfo.strOrder) + "节,识别结果上传失败!"); - } - } -// }); } void MainWindow::IdentifyTypeUpdate() { @@ -929,6 +700,22 @@ void MainWindow::IdentifyTypeUpdate() { } } +void MainWindow::DebugSlots(const QString &info) { + this->logDebug(info); +} + +void MainWindow::InfoSlots(const QString &info) { + this->logInfo(info); +} + +void MainWindow::WarnSlots(const QString &info) { + this->logWarn(info); +} + +void MainWindow::ErrorSlots(const QString &info) { + this->logError(info); +} + // ============================= 测试 ==================================== void MainWindow::readTestInfo() diff --git a/src/qt_source/mainwindow.h b/src/qt_source/mainwindow.h index 7981540..c0ab5ed 100644 --- a/src/qt_source/mainwindow.h +++ b/src/qt_source/mainwindow.h @@ -52,11 +52,13 @@ #include "ConfigUtil.h" #include "ComDetect.h" #include "TcpClient.h" +#include "../threads/UpResultThread.h" QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACE +using namespace ai_matrix; class MainWindow : public QWidget { @@ -93,14 +95,8 @@ public: QStandardItem* getStandardItem(const QString &value); private: - struct TrainInfo { - std::string carriageType; - std::string carriageNum; - std::string strOrder; - std::string trainTime; - std::string collectTime; - std::string strRfidInfo; - }; + + UpResultThread *upResultThread; QString trainTime; QString logRfidRecvName; @@ -142,9 +138,6 @@ private: TcpClient* tcpClient; - bool upWeb(TrainInfo &trainInfo); - bool getToken(); - private: QTcpSocket* tcp_ = nullptr; QStatusBar* statusBar; @@ -159,7 +152,6 @@ private: void creat_action(); void changeEvent(QEvent *event); void on_ShowMainAction(); - void on_ExitAppAction(); void closeEvent(QCloseEvent *event); void creat_menu(); @@ -178,6 +170,11 @@ private slots: void readTestInfo(); void IdentifyTypeUpdate(); + void DebugSlots(const QString &info); + void InfoSlots(const QString &info); + void WarnSlots(const QString &info); + void ErrorSlots(const QString &info); + private: Ui::MainWindow *ui; }; diff --git a/src/threads/UpResultThread.cpp b/src/threads/UpResultThread.cpp new file mode 100644 index 0000000..3763d9d --- /dev/null +++ b/src/threads/UpResultThread.cpp @@ -0,0 +1,206 @@ +// +// Created by Mr.V on 2024/4/3. +// + +#include "UpResultThread.h" + + +UpResultThread::UpResultThread(MQueue *queueTrainInfo, int *iDirection, QObject *parent) : + QThread(parent) +{ + this->queueTrainInfo_ = queueTrainInfo; + this->iDirection = iDirection; + + // 配置文件读取 + QString errorMessage = ""; + if (!ConfigUtil::readBaseConfig(g_config_path, errorMessage, this->baseConfig_)) + { + this->ErrorSignals(errorMessage); + } + if (!ConfigUtil::readInterfaceConfig(g_config_path, errorMessage, this->interfaceConfig_)) + { + this->ErrorSignals(errorMessage); + } +} + +void UpResultThread::run() +{ + while (true) + { +// if ((*this->iDirection == 0 && this->queueTrainInfo_->size() <= 4) || *this->iDirection < 0) continue; + + while (!this->queueTrainInfo_->isEmpty()) + { + TrainInfo trainInfo_ = this->queueTrainInfo_->pop(); + if (!this->upWeb(trainInfo_)) + { + //this->logError("第" + QString::fromStdString(trainInfo.strOrder) + "节,识别结果上传失败!"); + } + } + QThread::sleep(1); + } +} + +/** + * @brief:Http发送RFID数据 + * @param:carriageType:车型 + * @param:carriageNumber:车号 + * @param:carriageOrder:车节号 + * @param:time:当前时间 + * @param:rfidSourceInfo:RFID的原始数据(过滤掉了重复磁条信息) + * @return: 成功:true + * 失败:false + */ +bool UpResultThread::upWeb(TrainInfo &trainInfo) +{ + try { + Json::Value arrayObj; //构建对象 + + arrayObj["comeTime"] = trainInfo.trainTime; + arrayObj["collectTime"] = trainInfo.collectTime; + arrayObj["carriageNumber"] = trainInfo.carriageNum; + arrayObj["carriageType"] = trainInfo.carriageType; + arrayObj["carriageOrder"] = trainInfo.strOrder; + arrayObj["steel"] = trainInfo.strRfidInfo; + + Json::Value trainParams; + trainParams["poundNo"] = std::to_string(this->baseConfig_.trackName); + arrayObj["trainParams"] = trainParams; + Json::StreamWriterBuilder writer; + std::string str = Json::writeString(writer, arrayObj); + + this->InfoSignals("第" + QString::fromStdString(trainInfo.strOrder) + "节,发送web: " + QString::fromStdString(str)); + httplib::Client cli(this->interfaceConfig_.httpIp.toStdString(), this->interfaceConfig_.httpPort); + + cli.set_connection_timeout(3, 0); + cli.set_read_timeout(3, 0); + httplib::Headers header; + httplib::Params params; + header.emplace("blade-auth", this->webToken); + //header.emplace("Content-Type", "application/json"); + + auto res = cli.Post(this->interfaceConfig_.upResultPath.toStdString(), header, str, "application/json"); + + if (res) + { + if (res->status == 200) + { + this->InfoSignals("第" + QString::fromStdString(trainInfo.strOrder) + "节,web返回: " + QString::fromStdString(res->body)); + Json::CharReaderBuilder readerBuilder; + std::istringstream iss(res->body); + Json::Value root; + std::string errs; + bool parsingSuccessful = Json::parseFromStream(readerBuilder, iss, &root, &errs); + if (parsingSuccessful) + { + if (root["success"].asBool()) + { + return true; + } + else + { + + if (root["msg"].asString() == "请求未授权") { + this->WarnSignals("第" + QString::fromStdString(trainInfo.strOrder) + "节,因请求未授权,而上传识别结果失败!重新请求token。"); + if (!this->getToken()) return false; + return this->upWeb(trainInfo); + } + this->ErrorSignals("第" + QString::fromStdString(trainInfo.strOrder) + "节,识别结果上传失败,原因:" + QString::fromStdString(root["msg"].asString())); + } + } + else + { + this->ErrorSignals("第" + QString::fromStdString(trainInfo.strOrder) + "节,识别结果上传失败,返回数据解析异常,返回数据非json:" + QString::fromStdString(res->body)); + } + } + else + { + this->ErrorSignals("第" + QString::fromStdString(trainInfo.strOrder) + "节,识别结果上传失败,原因:" + QString::number(res->status) + " - " + QString::fromStdString(res->body)); + if (res->status == 401) { + this->WarnSignals("因请求未授权,而上传识别结果失败!重新请求token。"); + this->getToken(); + return this->upWeb(trainInfo); + } + } + } + else + { + this->ErrorSignals("第" + QString::fromStdString(trainInfo.strOrder) + "节,上传数据失败,请检查网络,或者上传地址!"); + } + } + catch (std::exception &e) + { + this->ErrorSignals("第" + QString::fromStdString(trainInfo.strOrder) + "节,上传识别结果失败,原因:" + QString::fromStdString(e.what())); + } + return false; +} + +/** + * @brief:Http获取授权 + * @param: + * @return: + */ +bool UpResultThread::getToken() +{ + try + { + httplib::Client cli(this->interfaceConfig_.httpIp.toStdString(), this->interfaceConfig_.httpPort); + cli.set_connection_timeout(0, 300 * 1000); + cli.set_read_timeout(0,300*1000); + httplib::Headers header; + httplib::Params params; + + header.emplace("Authorization", "Basic Y2xpZW50X2VudGVycHJpc2U6Y2xpZW50X2VudGVycHJpc2Vfc2VjcmV0"); + + params.emplace("username", this->interfaceConfig_.username.toStdString()); + params.emplace("password", this->interfaceConfig_.password.toStdString()); + params.emplace("tenantId", "000000"); + params.emplace("grant_type", "password"); + auto res = cli.Post("/api/blade-auth/oauth/token", header, params); + if (res) + { + if (res->status == 200) + { + Json::CharReaderBuilder readerBuilder; + std::istringstream iss(res->body); + Json::Value root; + std::string errs; + bool parsingSuccessful = Json::parseFromStream(readerBuilder, iss, &root, &errs); + + if (parsingSuccessful) + { + if (!root.get("token_type", "").asString().empty()) + { + this->webToken = root["token_type"].asString(); + this->webToken.append(" "); + this->webToken.append(root["access_token"].asString()); + this->InfoSignals("已获取到web token"); + return true; + } + else + { + this->ErrorSignals("获取web token失败,原因:" + QString::fromStdString(res->body)); + } + } + else + { + this->ErrorSignals("获取web token返回数据解析异常,返回数据非json。详细:" + QString::fromStdString(res->body)); + } + } + } + else + { + auto err = res.error(); +// if (err == httplib::Error::Connection) { +// std::cout << " (连接出错)" << std::endl; +// } + this->ErrorSignals("获取web token失败!请检查网络或请求地址。详细:" + QString::fromStdString(to_string(err))); + } + } + catch (std::exception &e) + { + this->ErrorSignals("获取授权失败,原因:" + QString::fromStdString(e.what())); + } + return false; +} + diff --git a/src/threads/UpResultThread.h b/src/threads/UpResultThread.h new file mode 100644 index 0000000..c82da54 --- /dev/null +++ b/src/threads/UpResultThread.h @@ -0,0 +1,44 @@ +// +// Created by Mr.V on 2024/4/3. +// + +#ifndef TRAIN_RFID_UPRESULTTHREAD_H +#define TRAIN_RFID_UPRESULTTHREAD_H + +#include +#include "common.h" +#include "MQueue.h" +#include "httplib.h" +#include "json.h" +#include "ConfigUtil.h" + +using namespace ai_matrix; + +class UpResultThread : public QThread{ + Q_OBJECT +public: + ~UpResultThread() {}; + + UpResultThread(MQueue *queueTrainInfo, int *iDirection, QObject *parent = nullptr); + + void run() override; + +private: + MQueue *queueTrainInfo_ = nullptr; + int *iDirection; + ai_matrix::BaseConfig baseConfig_; + ai_matrix::InterfaceConfig interfaceConfig_; + std::string webToken; //授权信息 + + bool upWeb(TrainInfo &trainInfo); + bool getToken(); + +signals: + void DebugSignals(const QString &info); + void InfoSignals(const QString &info); + void WarnSignals(const QString &info); + void ErrorSignals(const QString &info); +}; + + +#endif //TRAIN_RFID_UPRESULTTHREAD_H