diff --git a/.gitignore b/.gitignore index a2f4b0c..30a4a93 100644 --- a/.gitignore +++ b/.gitignore @@ -1,56 +1,71 @@ -bin/ -# ---> Qt -# C++ objects and libs -*.slo -*.lo -*.o -*.a -*.la -*.lai -*.so -*.so.* -*.dll -*.dylib - -# Qt-es -object_script.*.Release -object_script.*.Debug -*_plugin_import.cpp -/.qmake.cache -/.qmake.stash -*.pro.user -*.pro.user.* -*.qbs.user -*.qbs.user.* -*.moc -moc_*.cpp -moc_*.h -qrc_*.cpp -ui_*.h -*.qmlc -*.jsc -Makefile* -*build-* -*.qm -*.prl - -# Qt unit tests -target_wrapper.* - -# QtCreator -*.autosave - -# QtCreator Qml -*.qmlproject.user -*.qmlproject.user.* - -# QtCreator CMake -CMakeLists.txt.user* - -# QtCreator 4.8< compilation database -compile_commands.json - -# QtCreator local machine specific files for imported projects -*creator.user* - -*_qmlcache.qrc +bin/ +.idea/ +# ---> Qt +# C++ objects and libs +*.slo +*.lo +*.o +*.a +*.la +*.lai +*.so +*.so.* +*.dll +*.dylib + +# Qt-es +object_script.*.Release +object_script.*.Debug +*_plugin_import.cpp +/.qmake.cache +/.qmake.stash +*.pro.user +*.pro.user.* +*.qbs.user +*.qbs.user.* +*.moc +moc_*.cpp +moc_*.h +qrc_*.cpp +ui_*.h +*.qmlc +*.jsc +Makefile* +*build-* +*.qm +*.prl + +# Qt unit tests +target_wrapper.* + +# QtCreator +*.autosave + +# QtCreator Qml +*.qmlproject.user +*.qmlproject.user.* + +# QtCreator CMake +CMakeLists.txt.user* + +# QtCreator 4.8< compilation database +compile_commands.json + +# QtCreator local machine specific files for imported projects +*.user + +*_qmlcache.qrc +LaunchRegisterKey.vcxproj +LaunchRegisterKey.vcxproj.filters +.vs/LaunchRegisterKey/FileContentIndex/aaaaca74-5a29-4c9c-a0b2-4aafa2ded7c4.vsidx +.vs/LaunchRegisterKey/v17/.suo +.vs/LaunchRegisterKey/v17/Browse.VC.db +.vs/LaunchRegisterKey/v17/Browse.VC.db-shm +.vs/LaunchRegisterKey/v17/Browse.VC.db-wal +.vs/LaunchRegisterKey/v17/Browse.VC.opendb +.vs/LaunchRegisterKey/v17/ipch/AutoPCH/33033be55980b52b/WIDGET.ipch +.vs/LaunchRegisterKey/v17/ipch/AutoPCH/71f3d9e241800f09/SETTINGWGT.ipch +.vs/LaunchRegisterKey/v17/ipch/AutoPCH/b58d33b68fb99398/COMMON.ipch +.vs/LaunchRegisterKey/v17/ipch/AutoPCH/e407f47aecf49074/UDPDATATHREAD.ipch +debug/ +release/ diff --git a/LaunchRegisterKey.pro b/LaunchRegisterKey.pro index 349f29f..0dcb8d0 100644 --- a/LaunchRegisterKey.pro +++ b/LaunchRegisterKey.pro @@ -1,4 +1,4 @@ -QT += core gui network +QT += core gui network sql greaterThan(QT_MAJOR_VERSION, 4): QT += widgets @@ -31,7 +31,8 @@ HEADERS += \ third_party/nlohmann/json.hpp \ third_party/nlohmann/json_fwd.hpp \ ui/settingwgt.h \ - ui/widget.h + ui/widget.h \ + utils/interface.h FORMS += \ ui/settingwgt.ui \ diff --git a/LaunchRegisterKey.pro.user b/LaunchRegisterKey.pro.user deleted file mode 100644 index 15f89ac..0000000 --- a/LaunchRegisterKey.pro.user +++ /dev/null @@ -1,319 +0,0 @@ - - - - - - EnvironmentId - {f213a5b1-fd80-4b82-9045-7920f30d1a64} - - - ProjectExplorer.Project.ActiveTarget - 0 - - - ProjectExplorer.Project.EditorSettings - - true - false - true - - Cpp - - CppGlobal - - - - QmlJS - - QmlJSGlobal - - - 2 - UTF-8 - false - 4 - false - 80 - true - true - 1 - true - false - 0 - true - true - 0 - 8 - true - 0 - true - true - true - false - - - - ProjectExplorer.Project.PluginSettings - - - -fno-delayed-template-parsing - - true - - - - ProjectExplorer.Project.Target.0 - - Desktop Qt 5.14.1 MSVC2017 32bit - Desktop Qt 5.14.1 MSVC2017 32bit - qt.qt5.5141.win32_msvc2017_kit - 0 - 0 - 0 - - D:/Project/VMAX/VMAXWeb/LaunchRegisterKey/bin - - - true - QtProjectManager.QMakeBuildStep - true - - false - false - false - - - true - Qt4ProjectManager.MakeStep - - false - - - false - - 2 - Build - Build - ProjectExplorer.BuildSteps.Build - - - - true - Qt4ProjectManager.MakeStep - - true - clean - - false - - 1 - Clean - Clean - ProjectExplorer.BuildSteps.Clean - - 2 - false - - Debug - Qt4ProjectManager.Qt4BuildConfiguration - 2 - - - D:/Project/VMAX/VMAXWeb/build-LaunchRegisterKey-Desktop_Qt_5_14_1_MSVC2017_32bit-Release - - - true - QtProjectManager.QMakeBuildStep - false - - false - false - true - - - true - Qt4ProjectManager.MakeStep - - false - - - false - - 2 - Build - Build - ProjectExplorer.BuildSteps.Build - - - - true - Qt4ProjectManager.MakeStep - - true - clean - - false - - 1 - Clean - Clean - ProjectExplorer.BuildSteps.Clean - - 2 - false - - Release - Qt4ProjectManager.Qt4BuildConfiguration - 0 - - - D:/Project/VMAX/VMAXWeb/build-LaunchRegisterKey-Desktop_Qt_5_14_1_MSVC2017_32bit-Profile - - - true - QtProjectManager.QMakeBuildStep - true - - false - true - true - - - true - Qt4ProjectManager.MakeStep - - false - - - false - - 2 - Build - Build - ProjectExplorer.BuildSteps.Build - - - - true - Qt4ProjectManager.MakeStep - - true - clean - - false - - 1 - Clean - Clean - ProjectExplorer.BuildSteps.Clean - - 2 - false - - Profile - Qt4ProjectManager.Qt4BuildConfiguration - 0 - - 3 - - - 0 - Deploy - Deploy - ProjectExplorer.BuildSteps.Deploy - - 1 - ProjectExplorer.DefaultDeployConfiguration - - 1 - - - dwarf - - cpu-cycles - - - 250 - - -e - cpu-cycles - --call-graph - dwarf,4096 - -F - 250 - - -F - true - 4096 - false - false - 1000 - - true - - false - false - false - false - true - 0.01 - 10 - true - kcachegrind - 1 - 25 - - 1 - true - false - true - valgrind - - 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - - 2 - - Qt4ProjectManager.Qt4RunConfiguration:D:/Project/VMAX/VMAXWeb/LaunchRegisterKey/LaunchRegisterKey.pro - D:/Project/VMAX/VMAXWeb/LaunchRegisterKey/LaunchRegisterKey.pro - - false - - false - true - true - false - false - true - - D:/Project/VMAX/VMAXWeb/LaunchRegisterKey/bin - - 1 - - - - ProjectExplorer.Project.TargetCount - 1 - - - ProjectExplorer.Project.Updater.FileVersion - 22 - - - Version - 22 - - diff --git a/common.h b/common.h index c4defea..d1c29de 100644 --- a/common.h +++ b/common.h @@ -5,29 +5,9 @@ #include "utils/Singleton.h" #include #include +#include "utils/interface.h" #include "nlohmann/json.hpp" #include "EasySpdLog.h" -enum Mode -{ - GLOBAL, - LOCAL, -}; - -struct ModeConfig -{ - int index; - QString name; - QString workPath; - QString reworkPath; -}; - -struct ProductConfig -{ - int productId; - Mode workMode; - bool selected; - QString productFormat; -}; class Common : public QObject, public Singleton { diff --git a/network/udpdatathread.cpp b/network/udpdatathread.cpp index 03e13e2..bbb5130 100644 --- a/network/udpdatathread.cpp +++ b/network/udpdatathread.cpp @@ -1,8 +1,9 @@ #include "udpdatathread.h" #include #include "common.h" +#include "EasySpdLog.h" + #include -#define MAXSIZES 1024 UdpDataThread::UdpDataThread(QObject *parent) : QObject(parent) @@ -31,7 +32,9 @@ UdpDataThread::~UdpDataThread() void UdpDataThread::sendSnId(const QString &data) { - m_udpWorker->startSending("send_sn", data.toLocal8Bit(), m_hostAddr, Common::GetInstance()->getDstPort()); + QString snMsg = QString("5901%1%2").arg(data.length()).arg(data); + //m_udpWorker->sendData(snMsg.toLocal8Bit(), m_hostAddr, Common::GetInstance()->getDstPort()); + m_udpWorker->startSending("send_sn", snMsg.toLocal8Bit(), m_hostAddr, Common::GetInstance()->getDstPort()); } void UdpDataThread::sendStop() @@ -57,19 +60,42 @@ void UdpDataThread::recvData(const QByteArray &data) QString dataStr(data); if (dataStr.mid(0, 2).toInt() != CONSTHEAD) return; - int msgType = dataStr.mid(2, 2).toInt(); switch(msgType) { case SIGNAL_BEATSRC: { m_connectStatus = true; - int type = dataStr.mid(4, 2).toInt(); + int type = dataStr.mid(6, 1).toInt(); Common::GetInstance()->setCurrentWorkMode(type); emit connectStatus(true); break; } + case SIGNAL_SN: + { + int status = dataStr.mid(4, 3).toInt(); + if (status == 11) + { + m_udpWorker->stopSending("send_sn"); + } + else + { + qDebug()<<"SIGNAL_SN:"<= 3) { + Common::GetInstance()->setCurrentWorkMode(-1); emit connectStatus(false); qDebug()<<"disconnect"; times = 0; diff --git a/network/udpdatathread.h b/network/udpdatathread.h index 4297ac7..f3137da 100644 --- a/network/udpdatathread.h +++ b/network/udpdatathread.h @@ -21,14 +21,13 @@ class UdpDataThread : public QObject public: UdpDataThread(QObject *parent = nullptr); ~UdpDataThread(); - - void send_circle(const QString& data); void sendSnId(const QString& data); void sendStop(); void sendClose(); void stopClose(); signals: void connectStatus(bool); + void registerRet(bool); private slots: void recvData(const QByteArray &data); void checkConnectSlot(); diff --git a/ui/settingwgt.cpp b/ui/settingwgt.cpp index 05fc485..c70a47c 100644 --- a/ui/settingwgt.cpp +++ b/ui/settingwgt.cpp @@ -22,6 +22,7 @@ SettingWgt::SettingWgt(QWidget *parent) : m_productsCfg = Common::GetInstance()->getProductConfigs(); m_workmodesCfg = Common::GetInstance()->getWorkModeConfigs(); m_productNums = m_productsCfg.size(); + m_workModeNums = m_workmodesCfg.size(); initUI(); //一定放在前面 loadConfig(); } @@ -106,8 +107,10 @@ void SettingWgt::initUI() layout->addWidget(lineEdit, i + 1, 2); // 工作模式下拉框创建 QComboBox *comboBox = new QComboBox(ui->frame_setting); - comboBox->addItem("GLOBAL", 0); - comboBox->addItem("LOCAL", 1); + for (const auto& productCfg : m_workmodesCfg) + { + comboBox->addItem(productCfg.name, productCfg.index); + } m_modeComboBoxes.push_back(comboBox); layout->addWidget(comboBox, i + 1, 3); } @@ -125,7 +128,11 @@ void SettingWgt::loadConfig() int mode = product.workMode; m_snFormatLineEdits[index - 1]->setText(product.productFormat); m_selectCheckBoxes[index - 1]->setCheckState(selected ? Qt::Checked : Qt::Unchecked); - m_modeComboBoxes[index - 1]->setCurrentIndex(mode); + int pos = m_modeComboBoxes[index - 1]->findData(QVariant(mode)); + if (pos != -1) + { + m_modeComboBoxes[index - 1]->setCurrentIndex(pos); + } } } @@ -169,7 +176,12 @@ void SettingWgt::on_pushButton_ok_clicked() { m_productsCfg[i + 1].selected = m_selectCheckBoxes[i]->isChecked(); m_productsCfg[i + 1].productFormat = m_snFormatLineEdits[i]->text().trimmed(); - m_productsCfg[i + 1].workMode = static_cast(m_modeComboBoxes[i]->currentIndex()); + m_productsCfg[i + 1].workMode = static_cast(m_modeComboBoxes[i]->currentData().toInt()); + } + for (auto& workmodeCfg : m_workmodesCfg) + { + workmodeCfg.workPath = m_workPathLineEdits[workmodeCfg.index].first->text().trimmed(); + workmodeCfg.reworkPath = m_workPathLineEdits[workmodeCfg.index].second->text().trimmed(); } Common::GetInstance()->saveConfig(m_productsCfg, m_workmodesCfg); emit SettingFinishSig(); diff --git a/ui/settingwgt.h b/ui/settingwgt.h index fd1cb75..a2f311d 100644 --- a/ui/settingwgt.h +++ b/ui/settingwgt.h @@ -44,6 +44,7 @@ private: QMap m_productsCfg; QMap m_workmodesCfg; uint m_productNums; + uint m_workModeNums; }; #endif // SETTINGDLG_H diff --git a/ui/widget.cpp b/ui/widget.cpp index 7cc80f4..b72e446 100644 --- a/ui/widget.cpp +++ b/ui/widget.cpp @@ -4,7 +4,12 @@ #include #include - +#include +#include +#include +#include +#include +#include #include "common.h" #include @@ -26,6 +31,8 @@ Widget::Widget(QWidget *parent) connect(m_settingDlg, &SettingWgt::SettingFinishSig, [this](){ on_pushButton_setting_clicked(); }); + connect(m_udpDataThread, &UdpDataThread::registerRet, this, &Widget::RegisterRetSlot); + connect(m_udpDataThread, &UdpDataThread::connectStatus, this, &Widget::ConnectStatusSlot); } Widget::~Widget() @@ -58,22 +65,98 @@ int Widget::checkSNId(const QString &snId) if (snId.isEmpty()) { QMessageBox::warning(this, "产品SN错误", "产品SN为空! 请重新扫码!"); - return -1; + LWarn("Product SN id is empty!"); + return SNEmptyError; } QRegExp reg("[a-z]"); if (reg.indexIn(snId) != -1) { QMessageBox::information(this,"提示",QString("产品SN(%1)包含小写! 请重新扫码!").arg(snId)); + LWarn("Product SN contains lowercase!"); ui->lineEdit_snId->setText(""); - return -1; + return SNLowerCaseError; } if (snId.contains(" ")) { QMessageBox::information(this,"提示",QString("产品SN(%1)包含空格! 请重新扫码!").arg(snId)); + LWarn("Product SN contains Spaces!"); ui->lineEdit_snId->setText(""); - return -1; + return SNSpaceError; + } + return NoError; +} + +int Widget::startIECSProgram(const QString& workPath, const QString& snId) +{ + QProcess *process = new QProcess(this); + process->start(workPath); + qDebug()<<"startIECSProgram:"<waitForStarted()) + { + LError("Failed to start the program with arguments:{}", process->errorString()); + return ExecIECSError; + } + m_udpDataThread->sendSnId(snId); + return NoError; +} + +int Widget::checkForRepairProgram(const int mode, const QString& sn, bool& isFind) +{ + auto workModeCfg = Common::GetInstance()->getWorkModeConfigs(); + QDir workDir(workModeCfg[mode].workPath); + workDir.cdUp(); + QString dbPath = workDir.absolutePath() + "/config.db"; + return databaseQuery(dbPath, sn, isFind); +} + +int Widget::databaseQuery(const QString& databasePath, const QString& deviceSn, bool& isFind) +{ + // 创建和打开 SQLite 数据库 + QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE"); + db.setDatabaseName(databasePath); // 使用传入的数据库路径 + if (!db.open()) + { + LError("Failed to open database:{}", db.lastError().text()); + isFind = false; + return DatabaseOpenError; + } + + // 创建查询对象 + QSqlQuery query(db); + // 准备 SQL 查询 + query.prepare("SELECT COUNT(1) FROM history WHERE device_sn = :device_sn;"); + query.bindValue(":device_sn", deviceSn); + // 执行查询 + if (!query.exec()) { + LError("Failed to execute query:{}", query.lastError().text()); + isFind = false; + db.close(); + return DatabaseSelectError; + } + // 处理查询结果 + if (query.next()) + { + int count = query.value(0).toInt(); + isFind = (count > 0); + db.close(); + return NoError; + } + isFind = false; + db.close(); + return DatabaseUnknownError; +} + +void Widget::RegisterRetSlot(bool ret) +{ + ui->lineEdit_snId->setEnabled(true); +} + +void Widget::ConnectStatusSlot(bool ret) +{ + if (!ret) + { + ui->lineEdit_snId->setEnabled(true); } - return 0; } void Widget::on_pushButton_setting_clicked() @@ -107,6 +190,12 @@ void Widget::addLogItem(const QString &text) ui->list_log->addItem(text); // 添加新条目 } +int Widget::switchProgram() +{ + + return 0; +} + void Widget::on_lineEdit_snId_returnPressed() { QString snId = ui->lineEdit_snId->text(); @@ -132,14 +221,42 @@ void Widget::on_lineEdit_snId_returnPressed() QMessageBox::information(this, "警告", "当前SN与启用设值SN不匹配,请检查或重新扫码"); return; } + ui->lineEdit_snId->setEnabled(false); auto currWorkMode = Common::GetInstance()->getCurrentWorkMode(); - if (selectedProducts[productFormat] != currWorkMode) + bool isRepair = false; + // 查找数据库,判断是否需要返修程序 + ret = checkForRepairProgram(selectedProducts[productFormat], snId, isRepair); + if (ret != NoError) { - qDebug()<<"not match!!!"; - m_udpDataThread->sendClose(); + LError("checkForRepairProgram error!{}", ret); return; - //TODO:不相等时,需要结束当前的IECS程序,如果为-1,则代表没有IECS程序执行,直接启动IECS程序即可 + } + auto selectMode = selectedProducts[productFormat]; + auto workModeCfgs = Common::GetInstance()->getWorkModeConfigs(); + if (selectMode != currWorkMode) + { + // 切换工作模式 + if (currWorkMode != -1) + { + m_udpDataThread->sendClose(); + } + //TODO:不相等时,m_udpDataThread发送关闭信号,等待Common单例类中的标志位变成-1后,m_udpDataThread停止发送关闭信号并启动IECS程序 //同时需要去IECS程序路径中查找数据库,判断是否使用返修程序 + auto workModeCfg = workModeCfgs[selectMode]; + QString workPath = isRepair ? workModeCfg.reworkPath : workModeCfg.workPath; + qDebug()<<"workPath:"<getCurrentWorkMode() == -1) + { + m_udpDataThread->stopClose(); + timer->stop(); // 停止定时器 + // 启动 IECS 程序 + startIECSProgram(workPath, snId); + } + }); + timer->start(1000); + return; } m_udpDataThread->sendSnId(snId); } diff --git a/ui/widget.h b/ui/widget.h index 69fbcca..4aee6b9 100644 --- a/ui/widget.h +++ b/ui/widget.h @@ -19,11 +19,17 @@ private: void initUI(); void setSNLineEditFocus(); int checkSNId(const QString& snId); + int startIECSProgram(const QString& workPath, const QString& snId); + int checkForRepairProgram(const int mode, const QString& sn, bool& isFind); + + int databaseQuery(const QString& databasePath, const QString& deviceSn, bool& isFind); private slots: + void RegisterRetSlot(bool ret); + void ConnectStatusSlot(bool ret); void addLogItem(const QString& text); + int switchProgram(); void on_pushButton_setting_clicked(); void on_lineEdit_snId_returnPressed(); - void on_pushButton_sendSnId_clicked(); private: diff --git a/utils/interface.h b/utils/interface.h new file mode 100644 index 0000000..3448302 --- /dev/null +++ b/utils/interface.h @@ -0,0 +1,46 @@ +#ifndef INTERFACE_H +#define INTERFACE_H +#include +enum ErrorCode +{ + NoError = 0, + // SN相关错误 + SNEmptyError = 1, // 产品SN为空 + SNLowerCaseError, // 产品SN小写字母 + SNSpaceError, // 产品SN包含空格 + SNFormatError, // 产品SN格式错误 + // 数据库相关错误 + DatabaseOpenError, // 打开数据库失败 + DatabaseReadError, // 读取数据库失败 + DatabaseWriteError, // 写入数据库失败 + DatabaseSelectError, // 选择数据库失败 + DatabaseUnknownError, // 未知数据库错误 + // 执行程序相关错误 + ExecIECSError, // 执行IECS失败 +}; + +enum Mode +{ + GLOBAL, + LOCAL, + GLOBALM2M, + LOCALM2M, +}; + +struct ModeConfig +{ + int index; + QString name; + QString workPath; + QString reworkPath; +}; + +struct ProductConfig +{ + int productId; + Mode workMode; + bool selected; + QString productFormat; +}; + +#endif // INTERFACE_H