From: SnickerSun Date: Fri, 5 Dec 2025 15:15:18 +0000 (+0800) Subject: release雷鸟产测 V1.2 可以勾选测试项 X-Git-Url: http://git.snicker.com.cn/sitemap.xml?a=commitdiff_plain;h=0dc851ba90ba14b998f31d2221c8499d678e5221;p=mirrors%2Ffactory_tool.git release雷鸟产测 V1.2 可以勾选测试项 --- diff --git a/config_manager.cpp b/config_manager.cpp index 36f73a7..026d778 100644 --- a/config_manager.cpp +++ b/config_manager.cpp @@ -56,6 +56,19 @@ void ConfigManager::setDefaultConfig() testConfig["bluetoothRSSI"] = ""; defaultConfig["testConfig"] = testConfig; + // 默认测试项checkbox配置(默认全部选中) + QJsonObject testCheckboxes; + testCheckboxes["lcd"] = true; + testCheckboxes["vib"] = true; + testCheckboxes["btn"] = true; + testCheckboxes["mic"] = true; + testCheckboxes["charge"] = true; + testCheckboxes["ntc"] = true; + testCheckboxes["gsensor"] = true; + testCheckboxes["bt"] = true; + testCheckboxes["4g"] = true; + defaultConfig["testCheckboxes"] = testCheckboxes; + configObject = defaultConfig; configLoaded = true; } @@ -277,3 +290,30 @@ bool ConfigManager::saveConfig(const QString& configPath) return true; } +// 获取测试项checkbox状态 +bool ConfigManager::getTestCheckbox(const QString& key, bool defaultValue) const +{ + if (!configObject.contains("testCheckboxes")) { + return defaultValue; + } + + QJsonObject checkboxes = configObject["testCheckboxes"].toObject(); + if (!checkboxes.contains(key)) { + return defaultValue; + } + + return checkboxes[key].toBool(); +} + +// 设置测试项checkbox状态 +void ConfigManager::setTestCheckbox(const QString& key, bool value) +{ + if (!configObject.contains("testCheckboxes")) { + configObject["testCheckboxes"] = QJsonObject(); + } + + QJsonObject checkboxes = configObject["testCheckboxes"].toObject(); + checkboxes[key] = value; + configObject["testCheckboxes"] = checkboxes; +} + diff --git a/config_manager.h b/config_manager.h index cd4a45c..709f976 100644 --- a/config_manager.h +++ b/config_manager.h @@ -25,6 +25,10 @@ public: void setTestConfig(const QString& key, const QString& value); bool saveConfig(const QString& configPath = QString()); // 保存配置到文件 + // 测试项checkbox配置相关方法 + bool getTestCheckbox(const QString& key, bool defaultValue = true) const; + void setTestCheckbox(const QString& key, bool value); + // 检查配置是否有效 bool isValid() const; diff --git a/mainwindow.cpp b/mainwindow.cpp index 33a9162..88fe677 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -27,7 +27,7 @@ MainWindow::MainWindow(QWidget *parent) , ui(new Ui::MainWindow) { ui->setupUi(this); - setWindowTitle("雷鸟产测工具 V1.1"); + setWindowTitle("雷鸟产测工具 V1.2"); // 确保控制台输出使用UTF-8编码 QTextCodec *utf8Codec = QTextCodec::codecForName("UTF-8"); @@ -443,16 +443,16 @@ void MainWindow::CheckVibratorFunc(const QString& data) qDebug() << "1秒延迟后开始重新测试马达"; ui->statusbar->showMessage("重新开始马达测试", 2000); currentTestStep = TEST_MOTOR; + // performMotorTest()函数内部会检查checkbox,如果未启用会自动跳过 performMotorTest(); }); return; // 直接返回,不继续后续流程 } - // 用户确认完成,马达测试结束,开始按键测试 + // 用户确认完成,马达测试结束,开始下一个测试 if (isProductionTestRunning && currentTestStep == TEST_MOTOR) { - qDebug() << "马达测试确认完成,开始按键测试"; - currentTestStep = TEST_KEY; - performKeyTest(); + qDebug() << "马达测试确认完成,推进到下一个测试"; + skipToNextEnabledTest(); } } } @@ -674,15 +674,23 @@ void MainWindow::ShowPppInfoModemVer(const QString& data) qDebug() << "提取的Modem Version:" << modemVerInfo; qDebug() << "MODEM类型判断: " << (isEGModem() ? "EG系列" : "非EG系列"); - modemVerInfo = modemVerInfo.replace("!", ""); + // 清理版本字符串:移除特殊字符,去除首尾空格 + modemVerInfo = modemVerInfo.replace("!", "").trimmed(); currentModemVersion = modemVerInfo; ui->ModemVerlineEdit->setText(modemVerInfo); // 校验期望MODEM_VER QString expectedModem = ui->expectedModemVerLineEdit ? ui->expectedModemVerLineEdit->text().trimmed() : QString(); + // 对期望值也进行相同的清理处理 + if (!expectedModem.isEmpty()) { + expectedModem = expectedModem.replace("!", "").trimmed(); + } + qDebug() << "提取的Modem Version:" << modemVerInfo; qDebug() << "期望的Modem Version:" << expectedModem; - if (!expectedModem.isEmpty() && modemVerInfo.compare(expectedModem, Qt::CaseSensitive) != 0) { + + // 使用大小写不敏感对比,更宽松 + if (!expectedModem.isEmpty() && modemVerInfo.compare(expectedModem, Qt::CaseInsensitive) != 0) { ui->statusbar->showMessage("MODEM版本不一致: 实际=" + modemVerInfo + " 期望=" + expectedModem, 5000); QMessageBox::critical(this, "版本校验失败", "MODEM_VER不一致,测试失败!\n实际: " + modemVerInfo + "\n期望: " + expectedModem); isProductionTestRunning = false; @@ -713,36 +721,44 @@ void MainWindow::ShowPppInfoPYVer(const QString& data) start++; } - // 查找行结束标志(换行符或字符串结束) - int end = data.indexOf('\n', start); + // 查找结束位置:优先查找@modemVer:(如果PYVer和ModemVer在同一行) + int end = data.indexOf("@modemVer:", start, Qt::CaseInsensitive); if (end == -1) { - end = data.indexOf('\r', start); + // 如果没有@modemVer:,查找行结束标志(换行符或字符串结束) + end = data.indexOf('\n', start); if (end == -1) { - end = data.length(); + end = data.indexOf('\r', start); + if (end == -1) { + end = data.length(); + } } } - // 提取Modem版本信息 + // 提取PYVer版本信息(到@modemVer:之前或行尾) PYVerInfo = data.mid(start, end - start).trimmed(); } - // 方法2:查找"@modemVer:"标识的格式(新格式) + // 方法2:查找"@pyver:"标识的格式(新格式) else { start = data.indexOf("@pyver:", 0, Qt::CaseInsensitive); if (start != -1) { - // 计算版本信息的起始位置(跳过"@modemVer:") + // 计算版本信息的起始位置(跳过"@pyver:") const QString key = "@pyver:"; start += key.length(); - // 查找行结束标志(换行符或字符串结束) - int end = data.indexOf('\n', start); + // 查找结束位置:优先查找@modemVer:(如果PYVer和ModemVer在同一行) + int end = data.indexOf("@modemVer:", start, Qt::CaseInsensitive); if (end == -1) { - end = data.indexOf('\r', start); + // 如果没有@modemVer:,查找行结束标志(换行符或字符串结束) + end = data.indexOf('\n', start); if (end == -1) { - end = data.length(); + end = data.indexOf('\r', start); + if (end == -1) { + end = data.length(); + } } } - // 提取Modem版本信息 + // 提取PYVer版本信息(到@modemVer:之前或行尾) PYVerInfo = data.mid(start, end - start).trimmed(); qDebug() << "使用@pyver:格式提取pyver:" << PYVerInfo; } @@ -760,18 +776,30 @@ void MainWindow::ShowPppInfoPYVer(const QString& data) } } - // 验证Modem Version是否有效(不为空即可) + // 验证PYVER Version是否有效(不为空即可) if (!PYVerInfo.isEmpty()) { + // 清理版本字符串:移除特殊字符,去除首尾空格 + PYVerInfo = PYVerInfo.replace("!", "").trimmed(); + // 保存到成员变量 currentPYVerVersion = PYVerInfo; - // 显示到ModemVer文本框 + // 显示到PYVer文本框 ui->PYVerlineEdit->setText(PYVerInfo); qDebug() << "提取的PYVER Version:" << PYVerInfo; qDebug() << "MODEM类型判断: " << (isEGModem() ? "EG系列" : "非EG系列"); - - // 校验期望MODEM_VER + + // 校验期望PYVER QString expectedPYVER = ui->expectedPYVerLineEdit ? ui->expectedPYVerLineEdit->text().trimmed() : QString(); - if (!expectedPYVER.isEmpty() && PYVerInfo.compare(expectedPYVER, Qt::CaseSensitive) != 0) { + // 对期望值也进行相同的清理处理 + if (!expectedPYVER.isEmpty()) { + expectedPYVER = expectedPYVER.replace("!", "").trimmed(); + } + + qDebug() << "提取的PYVER Version:" << PYVerInfo; + qDebug() << "期望的PYVER Version:" << expectedPYVER; + + // 使用大小写不敏感对比,更宽松 + if (!expectedPYVER.isEmpty() && PYVerInfo.compare(expectedPYVER, Qt::CaseInsensitive) != 0) { ui->statusbar->showMessage("PYVER版本不一致: 实际=" + PYVerInfo + " 期望=" + expectedPYVER, 5000); QMessageBox::critical(this, "版本校验失败", "PYVER不一致,测试失败!\n实际: " + PYVerInfo + "\n期望: " + expectedPYVER); isProductionTestRunning = false; @@ -969,6 +997,10 @@ void MainWindow::readSerialData() // 将新接收的数据追加到缓存 recvBuffer += QString::fromUtf8(recvData); + + // 将所有原始串口数据写入 logtextEdit(完整日志) + ui->logtextEdit->insertPlainText(QString::fromUtf8(recvData)); + ui->logtextEdit->moveCursor(QTextCursor::End); // 自动滚动到底部 // 循环处理缓存中所有完整的行(以\n为结束标志) while (recvBuffer.contains('\n')) { @@ -1297,22 +1329,44 @@ void MainWindow::on_ProductionTestButton_clicked() // 开始产测流程 isProductionTestRunning = true; - currentTestStep = TEST_LCD; - currentLcdColor = 1; // 从红色开始 - initRetry4GCount = 0; - - ui->statusbar->showMessage("开始产测流程...", 2000); - qDebug() << "开始产测流程"; - - // ui->ProductionTestButton->setText("停止产测"); - - // 开始LCD测试 - performLcdTest(); + // 根据checkbox决定从哪个测试开始 + if (isTestItemEnabled("lcd")) { + currentTestStep = TEST_LCD; + currentLcdColor = 1; // 从红色开始 + initRetry4GCount = 0; + + ui->statusbar->showMessage("开始产测流程...", 2000); + qDebug() << "开始产测流程"; + + // ui->ProductionTestButton->setText("停止产测"); + + // 开始LCD测试 + performLcdTest(); + } else { + // LCD未启用,跳过到下一个启用的测试 + currentTestStep = TEST_LCD; // 先设置为LCD,然后skipToNextEnabledTest会跳过 + currentLcdColor = 1; // 初始化LCD颜色 + initRetry4GCount = 0; + + ui->statusbar->showMessage("开始产测流程...", 2000); + qDebug() << "开始产测流程,LCD测试未启用,跳过"; + + // 跳过LCD测试,进入下一个启用的测试 + skipToNextEnabledTest(); + } } // LCD测试函数 void MainWindow::performLcdTest() { + // 检查LCD测试是否启用 + if (!isTestItemEnabled("lcd")) { + qDebug() << "LCD测试未启用,跳过"; + updateTestStatus("lcd", STATUS_UNTESTED); + skipToNextEnabledTest(); + return; + } + if (!isProductionTestRunning || currentTestStep != TEST_LCD) { qDebug() << "LCD测试跳过 - 产测运行:" << isProductionTestRunning << "当前步骤:" << currentTestStep; return; @@ -1320,6 +1374,7 @@ void MainWindow::performLcdTest() // 第一次进入LCD测试时更新状态并发送进入LCD测试模式指令 if (currentLcdColor == 1) { + ui->recvTextEdit->append("========== 开始LCD测试 =========="); updateTestStatus("lcd", STATUS_TESTING); // 发送进入LCD测试模式指令 @@ -1423,12 +1478,11 @@ void MainWindow::onLcdTestTimer() // LCD颜色测试完成,检查用户是否已确认 if (!isWaitingForUserConfirm) { - // 用户已确认,可以继续马达测试 + // 用户已确认,可以继续下一个测试 QTimer::singleShot(1000, this, [this]() { if (isProductionTestRunning) { - qDebug() << "用户已确认LCD结果,开始马达测试"; - currentTestStep = TEST_MOTOR; - performMotorTest(); + qDebug() << "用户已确认LCD结果,推进到下一个测试"; + skipToNextEnabledTest(); } }); } else { @@ -1446,6 +1500,14 @@ void MainWindow::performMotorTest() qDebug() << "产测运行状态:" << isProductionTestRunning; qDebug() << "当前测试步骤:" << currentTestStep << "(TEST_MOTOR=" << TEST_MOTOR << ")"; + // 检查马达测试是否启用 + if (!isTestItemEnabled("motor")) { + qDebug() << "马达测试未启用,跳过"; + updateTestStatus("motor", STATUS_UNTESTED); + skipToNextEnabledTest(); + return; + } + if (!isProductionTestRunning || currentTestStep != TEST_MOTOR) { qDebug() << "马达测试条件不满足,退出函数"; qDebug() << "isProductionTestRunning:" << isProductionTestRunning; @@ -1454,6 +1516,7 @@ void MainWindow::performMotorTest() } qDebug() << "开始马达测试"; + ui->recvTextEdit->append("========== 开始马达测试 =========="); // 重置马达测试状态 motorTestPopupShown = false; @@ -1502,16 +1565,29 @@ void MainWindow::onMotorTestTimer() if (!motorTestPopupShown) { showMotorTestConfirmDialog(); } else { - // 如果弹窗已经显示过,直接开始按键测试 - qDebug() << "马达确认弹窗已显示过,开始按键测试"; - currentTestStep = TEST_KEY; - performKeyTest(); + // 如果弹窗已经显示过,直接开始下一个测试 + qDebug() << "马达确认弹窗已显示过,推进到下一个测试"; + skipToNextEnabledTest(); } } // 4G测试函数 void MainWindow::perform4GTest() { + // 检查4G测试是否启用 + if (!isTestItemEnabled("ppp")) { + qDebug() << "4G测试未启用,跳过"; + updateTestStatus("ppp", STATUS_UNTESTED); + // 4G测试是最后一个测试,如果未启用,直接完成测试 + if (isProductionTestRunning) { + currentTestStep = TEST_COMPLETED; + isProductionTestRunning = false; + QString fileName = saveTestRecord(); + showFinalTestResult(); + } + return; + } + if (!isProductionTestRunning) { qDebug() << "4G测试跳过 - 产测未运行"; return; @@ -1522,6 +1598,7 @@ void MainWindow::perform4GTest() // 第一次4G测试时更新状态并进行CAT1电源控制 if (initRetry4GCount == 1) { + ui->recvTextEdit->append("========== 开始4G测试 =========="); updateTestStatus("ppp", STATUS_TESTING); // 先发送AT^CAT1POWER=0关闭CAT1电源 @@ -1624,6 +1701,7 @@ void MainWindow::checkFactoryModeResult(const QString& data) if (isProductionTestRunning && currentTestStep == TEST_RESET) { ui->statusbar->showMessage("产测模式已开启 - 重启设备中...", 3000); qDebug() << "工厂模式确认后发送设备重启指令"; + ui->recvTextEdit->append(">>> 发送指令: AT^RESET (恢复出厂设置/重启设备)"); serial->write("AT^RESET\r\n"); qDebug() << "发送设备重启指令: AT^RESET"; @@ -1661,6 +1739,7 @@ void MainWindow::checkFactoryModeResult(const QString& data) if (isProductionTestRunning && currentTestStep == TEST_RESET) { ui->statusbar->showMessage("产测模式已开启 - 重启设备中...", 3000); qDebug() << "工厂模式确认后发送设备重启指令"; + ui->recvTextEdit->append(">>> 发送指令: AT^RESET (恢复出厂设置/重启设备)"); serial->write("AT^RESET\r\n"); qDebug() << "发送设备重启指令: AT^RESET"; @@ -1939,21 +2018,19 @@ void MainWindow::showLcdTestConfirmDialog() qDebug() << "停止LCD定时器,防止继续切换颜色和重复调用马达测试"; } - // 直接启动马达测试 + // 推进到下一个启用的测试 if (isProductionTestRunning) { - qDebug() << "LCD测试通过确认,直接启动马达测试"; + qDebug() << "LCD测试通过确认,推进到下一个测试"; qDebug() << "当前产测状态:" << isProductionTestRunning << "当前测试步骤:" << currentTestStep; - currentTestStep = TEST_MOTOR; - qDebug() << "设置测试步骤为TEST_MOTOR,准备调用performMotorTest()"; - // 延迟一点启动马达测试,确保LCD定时器完全停止 + // 延迟一点确保LCD定时器完全停止,然后推进到下一个测试 QTimer::singleShot(100, this, [this]() { - if (isProductionTestRunning && currentTestStep == TEST_MOTOR) { - performMotorTest(); + if (isProductionTestRunning) { + skipToNextEnabledTest(); } }); } else { - qDebug() << "产测未运行,无法启动马达测试"; + qDebug() << "产测未运行,无法继续测试"; } } else if (msgBox.clickedButton() == failButton) { @@ -1972,21 +2049,19 @@ void MainWindow::showLcdTestConfirmDialog() qDebug() << "停止LCD定时器,防止重复调用马达测试"; } - // 即使失败也继续马达测试 + // 即使失败也继续下一个测试 if (isProductionTestRunning) { - qDebug() << "LCD测试失败确认,继续马达测试"; + qDebug() << "LCD测试失败确认,继续下一个测试"; qDebug() << "当前产测状态:" << isProductionTestRunning << "当前测试步骤:" << currentTestStep; - currentTestStep = TEST_MOTOR; - qDebug() << "设置测试步骤为TEST_MOTOR,准备调用performMotorTest()"; - // 延迟一点启动马达测试,确保LCD定时器完全停止 + // 延迟一点确保LCD定时器完全停止,然后推进到下一个测试 QTimer::singleShot(100, this, [this]() { - if (isProductionTestRunning && currentTestStep == TEST_MOTOR) { - performMotorTest(); - } + if (isProductionTestRunning) { + skipToNextEnabledTest(); + } }); } else { - qDebug() << "产测未运行,无法启动马达测试"; + qDebug() << "产测未运行,无法继续测试"; } } else if (msgBox.clickedButton() == retestButton) { @@ -2000,8 +2075,15 @@ void MainWindow::showLcdTestConfirmDialog() currentLcdColor = 1; // 设置为1,从红色开始重新测试 // 重新开始LCD测试 - currentTestStep = TEST_LCD; - performLcdTest(); + // 检查LCD测试是否启用 + if (isTestItemEnabled("lcd")) { + currentTestStep = TEST_LCD; + performLcdTest(); + } else { + qDebug() << "LCD测试未启用,跳过"; + updateTestStatus("lcd", STATUS_UNTESTED); + skipToNextEnabledTest(); + } return; // 直接返回,不继续后续流程 } @@ -2131,22 +2213,30 @@ void MainWindow::showMotorTestConfirmDialog() return; // 直接返回,不继续后续流程 } - // 用户确认完成,马达测试结束,开始按键测试 + // 用户确认完成,马达测试结束,推进到下一个测试 if (isProductionTestRunning && currentTestStep == TEST_MOTOR) { - qDebug() << "马达测试确认完成,开始按键测试"; - currentTestStep = TEST_KEY; - performKeyTest(); + qDebug() << "马达测试确认完成,推进到下一个测试"; + skipToNextEnabledTest(); } } // 执行按键测试 void MainWindow::performKeyTest() { + // 检查按键测试是否启用 + if (!isTestItemEnabled("key")) { + qDebug() << "按键测试未启用,跳过"; + updateTestStatus("key", STATUS_UNTESTED); + skipToNextEnabledTest(); + return; + } + if (!isProductionTestRunning || currentTestStep != TEST_KEY) { return; } qDebug() << "开始按键测试"; + ui->recvTextEdit->append("========== 开始按键测试 =========="); updateTestStatus("key", STATUS_TESTING); ui->statusbar->showMessage("按键测试中,请按下设备上的按键", 10000); @@ -2240,12 +2330,10 @@ void MainWindow::performKeyTest() ui->statusbar->showMessage("按键测试通过", 2000); updateTestStatus("key", STATUS_SUCCESS); - // 继续录音测试 - qDebug() << "=== 按键测试完成,开始录音测试 ==="; + // 继续下一个测试 + qDebug() << "=== 按键测试完成,推进到下一个测试 ==="; keyTestStarted = false; - currentTestStep = TEST_AUDIO; - qDebug() << "设置currentTestStep为TEST_AUDIO:" << TEST_AUDIO; - performAudioTest(); + skipToNextEnabledTest(); } }); @@ -2256,10 +2344,9 @@ void MainWindow::performKeyTest() ui->statusbar->showMessage("按键测试失败", 2000); updateTestStatus("key", STATUS_FAILED); - // 继续录音测试 + // 继续下一个测试 keyTestStarted = false; - currentTestStep = TEST_AUDIO; - performAudioTest(); + skipToNextEnabledTest(); } }); @@ -2338,12 +2425,10 @@ void MainWindow::checkKeyTestResult(const QString& data) qDebug() << "按键测试自动通过"; updateTestStatus("key", STATUS_SUCCESS); - // 继续录音测试 - qDebug() << "=== 按键测试自动完成,开始录音测试 ==="; + // 继续下一个测试 + qDebug() << "=== 按键测试自动完成,推进到下一个测试 ==="; keyTestStarted = false; - currentTestStep = TEST_AUDIO; - qDebug() << "设置currentTestStep为TEST_AUDIO(自动):" << TEST_AUDIO; - performAudioTest(); + skipToNextEnabledTest(); } }); } else { @@ -2422,11 +2507,10 @@ void MainWindow::showKeyTestConfirmDialog(bool allKeysTested) updateTestStatus("key", STATUS_FAILED); } - // 按键测试完成,开始录音测试 + // 按键测试完成,推进到下一个测试 if (isProductionTestRunning) { - keyTestStarted = false; - currentTestStep = TEST_AUDIO; - performAudioTest(); + keyTestStarted = false; + skipToNextEnabledTest(); } } @@ -2452,22 +2536,32 @@ void MainWindow::checkBuildVerResult(const QString& data) serial->write("AT^PMADDVOTE\r\n"); qDebug() << "发送AT^PMADDVOTE指令(第2次): AT^PMADDVOTE"; - // 再延迟1秒后切换到LCD测试阶段 + // 再延迟1秒后切换到LCD测试阶段(如果启用) QTimer::singleShot(1000, this, [this]() { if (isProductionTestRunning) { - qDebug() << "AT^PMADDVOTE指令发送完成,开始LCD测试"; - ui->statusbar->showMessage("初始化完成,开始LCD测试", 2000); - - // 切换到LCD测试阶段 - currentTestStep = TEST_LCD; - - // 延迟1秒后开始LCD测试 - QTimer::singleShot(1000, this, [this]() { - if (isProductionTestRunning && currentTestStep == TEST_LCD) { - qDebug() << "开始LCD测试流程"; - performLcdTest(); - } - }); + // 检查LCD测试是否启用 + if (isTestItemEnabled("lcd")) { + qDebug() << "AT^PMADDVOTE指令发送完成,开始LCD测试"; + ui->statusbar->showMessage("初始化完成,开始LCD测试", 2000); + + // 切换到LCD测试阶段 + currentTestStep = TEST_LCD; + + // 延迟1秒后开始LCD测试 + QTimer::singleShot(1000, this, [this]() { + if (isProductionTestRunning && currentTestStep == TEST_LCD) { + qDebug() << "开始LCD测试流程"; + performLcdTest(); + } + }); + } else { + qDebug() << "AT^PMADDVOTE指令发送完成,LCD测试未启用,跳过"; + ui->statusbar->showMessage("初始化完成,LCD测试未启用,跳过", 2000); + + // LCD未启用,跳过到下一个启用的测试 + currentTestStep = TEST_LCD; + skipToNextEnabledTest(); + } } }); } @@ -2550,6 +2644,10 @@ void MainWindow::updateTestStatus(const QString& testName, TestStatus status) ui->pppStatusIcon->setStyleSheet(iconStyle); ui->pppStatusText->setText(statusText); ui->pppStatusText->setStyleSheet(textStyle); + } else if (testName == "charge" || testName == "ntc") { + // charge和ntc是电池测试的子项,它们的状态用于判定,但不单独显示在UI中 + // 它们的状态会影响battery的整体状态,但这里不更新UI + // 只用于后续的判定逻辑 } // 更新整体状态 @@ -2559,24 +2657,55 @@ void MainWindow::updateTestStatus(const QString& testName, TestStatus status) // 更新整体状态 void MainWindow::updateOverallStatus() { - // 检查各项测试状态(只检查成功状态,简化逻辑) - bool lcdSuccess = ui->lcdStatusText->text() == "通过"; - bool motorSuccess = ui->motorStatusText->text() == "通过"; - bool keySuccess = ui->keyStatusText->text() == "通过"; - bool audioSuccess = ui->audioStatusText->text() == "通过"; - bool batterySuccess = ui->batteryStatusText->text() == "通过"; - bool gsensorSuccess = ui->gsensorStatusText->text() == "通过"; - bool bluetoothSuccess = ui->bluetoothStatusText->text() == "通过"; - bool pppSuccess = ui->pppStatusText->text() == "通过"; + // 检查各项测试状态(只检查成功状态,并根据checkbox决定是否参与判定) + bool allEnabledTestsPassed = true; + + // 检查启用的测试项 + if (isTestItemEnabled("lcd")) { + bool lcdSuccess = ui->lcdStatusText->text() == "通过"; + if (!lcdSuccess) allEnabledTestsPassed = false; + } + if (isTestItemEnabled("motor")) { + bool motorSuccess = ui->motorStatusText->text() == "通过"; + if (!motorSuccess) allEnabledTestsPassed = false; + } + if (isTestItemEnabled("key")) { + bool keySuccess = ui->keyStatusText->text() == "通过"; + if (!keySuccess) allEnabledTestsPassed = false; + } + if (isTestItemEnabled("audio")) { + bool audioSuccess = ui->audioStatusText->text() == "通过"; + if (!audioSuccess) allEnabledTestsPassed = false; + } + // 电池测试:检查充电和NTC(如果启用) + // 注意:charge和ntc的状态通过updateTestStatus("charge", ...)和updateTestStatus("ntc", ...)更新 + // 但由于UI中可能没有独立的charge和ntc状态显示,这里使用battery状态作为综合判定 + // 如果charge或ntc任一启用,都需要检查battery状态 + if (isTestItemEnabled("charge") || isTestItemEnabled("ntc")) { + bool batterySuccess = ui->batteryStatusText->text() == "通过"; + if (!batterySuccess) allEnabledTestsPassed = false; + } + if (isTestItemEnabled("gsensor")) { + bool gsensorSuccess = ui->gsensorStatusText->text() == "通过"; + if (!gsensorSuccess) allEnabledTestsPassed = false; + } + if (isTestItemEnabled("bluetooth")) { + bool bluetoothSuccess = ui->bluetoothStatusText->text() == "通过"; + if (!bluetoothSuccess) allEnabledTestsPassed = false; + } + if (isTestItemEnabled("ppp")) { + bool pppSuccess = ui->pppStatusText->text() == "通过"; + if (!pppSuccess) allEnabledTestsPassed = false; + } QString overallIcon, overallText, overallColor; - if (lcdSuccess && motorSuccess && keySuccess && audioSuccess && batterySuccess && gsensorSuccess && bluetoothSuccess && pppSuccess) { - // 所有测试都通过 + if (allEnabledTestsPassed) { + // 所有启用的测试都通过 overallIcon = "✓"; overallText = "通过"; overallColor = "#4CAF50"; - } else { + } else { // 任何其他情况(失败、测试中、等待开始等)都显示为未通过 overallIcon = "✗"; overallText = "未通过"; @@ -3177,12 +3306,14 @@ void MainWindow::on_openButton_2_clicked() // 发送产测开启指令,等待工厂模式确认 qDebug() << "Step 1: 发送产测开启指令"; ui->statusbar->showMessage("发送产测开启指令,等待设备确认...", 3000); + ui->recvTextEdit->append(">>> 发送指令: AT^FACTORY=1 (开始产测)"); serial->write("AT^FACTORY=1\r\n"); qDebug() << "发送产测开启指令(第1次): AT^FACTORY=1,等待接收 'fac:enter or exit facotry mode' 确认"; // 延迟0.5秒后再发送一次,确保设备接收到指令 QTimer::singleShot(500, this, [this]() { if (isProductionTestRunning && serial->isOpen()) { + ui->recvTextEdit->append(">>> 发送指令: AT^FACTORY=1 (开始产测 - 第2次)"); serial->write("AT^FACTORY=1\r\n"); qDebug() << "发送产测开启指令(第2次): AT^FACTORY=1"; } @@ -3200,12 +3331,21 @@ void MainWindow::performAudioTest() qDebug() << "当前状态检查 - currentTestStep:" << currentTestStep; qDebug() << "当前状态检查 - TEST_AUDIO:" << TEST_AUDIO; + // 检查录音测试是否启用 + if (!isTestItemEnabled("audio")) { + qDebug() << "录音测试未启用,跳过"; + updateTestStatus("audio", STATUS_UNTESTED); + skipToNextEnabledTest(); + return; + } + if (!isProductionTestRunning || currentTestStep != TEST_AUDIO) { qDebug() << "*** performAudioTest 条件不满足,退出 ***"; return; } qDebug() << "开始录音测试(自动模式:AT^AUDIOTEST)"; + ui->recvTextEdit->append("========== 开始录音测试 =========="); updateTestStatus("audio", STATUS_TESTING); ui->statusbar->showMessage("录音测试中:正在发送AUDIOTEST指令...", 3000); @@ -3448,9 +3588,8 @@ void MainWindow::showAudioTestDialog() ui->statusbar->showMessage("录音测试通过", 2000); updateTestStatus("audio", STATUS_SUCCESS); - // 继续电池测试 - currentTestStep = TEST_BATTERY; - performBatteryTest(); + // 继续下一个测试 + skipToNextEnabledTest(); } }); @@ -3461,9 +3600,8 @@ void MainWindow::showAudioTestDialog() ui->statusbar->showMessage("录音测试失败", 2000); updateTestStatus("audio", STATUS_FAILED); - // 继续电池测试 - currentTestStep = TEST_BATTERY; - performBatteryTest(); + // 继续下一个测试 + skipToNextEnabledTest(); } }); @@ -3520,9 +3658,8 @@ void MainWindow::onAudioRecordTimer() serial->write(audioEndCmd.toUtf8()); qDebug() << "发送结束音频测试指令:" << audioEndCmd.trimmed(); - // 继续后续电池测试 - currentTestStep = TEST_BATTERY; - performBatteryTest(); + // 继续后续测试 + skipToNextEnabledTest(); } // 检查录音测试结果 @@ -3568,9 +3705,8 @@ void MainWindow::checkAudioTestResult(const QString& data) serial->write(audioEndCmd.toUtf8()); qDebug() << "发送结束音频测试指令:" << audioEndCmd.trimmed(); - // 继续后续电池测试 - currentTestStep = TEST_BATTERY; - performBatteryTest(); + // 继续后续测试 + skipToNextEnabledTest(); } } } @@ -3578,11 +3714,22 @@ void MainWindow::checkAudioTestResult(const QString& data) // 执行电池测试 void MainWindow::performBatteryTest() { + // 检查电池测试是否启用(充电或NTC任一启用即可) + if (!isTestItemEnabled("charge") && !isTestItemEnabled("ntc")) { + qDebug() << "电池测试未启用(充电和NTC都未启用),跳过"; + updateTestStatus("battery", STATUS_UNTESTED); + updateTestStatus("charge", STATUS_UNTESTED); + updateTestStatus("ntc", STATUS_UNTESTED); + skipToNextEnabledTest(); + return; + } + if (!isProductionTestRunning || currentTestStep != TEST_BATTERY) { return; } qDebug() << "开始电池测试"; + ui->recvTextEdit->append("========== 开始电池测试 =========="); updateTestStatus("battery", STATUS_TESTING); ui->statusbar->showMessage("电池测试中,正在获取电池电压...", 3000); @@ -3671,85 +3818,134 @@ void MainWindow::checkBatteryTestResult(const QString& data) if (charge != -1) resultLog += QString(", 充电状态:%1").arg(charge == 1 ? "充电中" : "未充电"); qDebug() << resultLog; - // 充电状态检查(原有逻辑不变) - if (charge == 0) { - qDebug() << "电池未充电,测试失败"; - ui->statusbar->showMessage("电池测试失败 - 设备未充电", 2000); - showBatteryChargeFailDialog(); - return; - } else if (charge == -1) { - qDebug() << "未检测到充电状态信息"; - ui->statusbar->showMessage("电池测试 - 未检测到充电状态", 2000); - QMessageBox msgBox(this); - msgBox.setWindowTitle("充电状态提醒"); - msgBox.setText("未检测到设备的充电状态信息"); - msgBox.setInformativeText("系统未能检测到设备的充电状态信息,\n但电压检测正常,是否继续测试?"); - msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); - msgBox.setDefaultButton(QMessageBox::Yes); - msgBox.setIcon(QMessageBox::Warning); - - int ret = msgBox.exec(); - if (ret == QMessageBox::No) { - updateTestStatus("battery", STATUS_FAILED); - return; + // 充电状态检查(根据checkbox决定是否判定) + bool chargeCheckEnabled = isTestItemEnabled("charge"); + bool ntcCheckEnabled = isTestItemEnabled("ntc"); + + bool chargePassed = true; // 默认通过(如果未启用检查) + bool ntcPassed = true; // 默认通过(如果未启用检查) + + if (chargeCheckEnabled) { + if (charge == 0) { + qDebug() << "充电检查失败:设备未充电"; + chargePassed = false; + ui->statusbar->showMessage("充电检查失败 - 设备未充电", 2000); + showBatteryChargeFailDialog(); + // 如果充电检查失败,直接返回,不继续测试 + updateTestStatus("charge", STATUS_FAILED); + if (ntcCheckEnabled) { + updateTestStatus("ntc", STATUS_UNTESTED); + } + return; + } else if (charge == -1) { + qDebug() << "未检测到充电状态信息"; + ui->statusbar->showMessage("电池测试 - 未检测到充电状态", 2000); + QMessageBox msgBox(this); + msgBox.setWindowTitle("充电状态提醒"); + msgBox.setText("未检测到设备的充电状态信息"); + msgBox.setInformativeText("系统未能检测到设备的充电状态信息,\n但电压检测正常,是否继续测试?"); + msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); + msgBox.setDefaultButton(QMessageBox::Yes); + msgBox.setIcon(QMessageBox::Warning); + + int ret = msgBox.exec(); + if (ret == QMessageBox::No) { + updateTestStatus("charge", STATUS_FAILED); + if (ntcCheckEnabled) { + updateTestStatus("ntc", STATUS_UNTESTED); + } + return; + } + // 用户选择继续,认为充电检查通过 + chargePassed = true; + } else if (charge == 1) { + chargePassed = true; } } - // 核心修改:同时判断电压和温度是否正常 + // NTC温度检查(根据checkbox决定是否判定) bool isVoltageNormal = (voltage >= 3.3 && voltage <= 4.4); bool isTempNormal = true; // 默认温度正常(未检测到温度时不影响结果) - QString failReason; - - // 若检测到温度,才判断温度是否在正常范围 - if (temp != -1.0) { - isTempNormal = (temp >= MIN_NORMAL_TEMP && temp <= MAX_NORMAL_TEMP); - if (!isTempNormal) { - failReason += QString("温度异常(%1℃,正常范围%2℃-%3℃)").arg(temp).arg(MIN_NORMAL_TEMP).arg(MAX_NORMAL_TEMP); + if (ntcCheckEnabled) { + if (temp != -1.0) { + isTempNormal = (temp >= MIN_NORMAL_TEMP && temp <= MAX_NORMAL_TEMP); + if (!isTempNormal) { + ntcPassed = false; + qDebug() << QString("NTC检查失败:温度异常(%1℃,正常范围%2℃-%3℃)").arg(temp).arg(MIN_NORMAL_TEMP).arg(MAX_NORMAL_TEMP); + updateTestStatus("ntc", STATUS_FAILED); + } else { + ntcPassed = true; + updateTestStatus("ntc", STATUS_SUCCESS); + qDebug() << QString("NTC检查通过:温度正常(%1℃)").arg(temp); + } + } else { + // 未检测到温度,如果启用了NTC检查,需要提示 + qDebug() << "NTC检查:未检测到温度信息"; + QMessageBox msgBox(this); + msgBox.setWindowTitle("NTC温度检查提醒"); + msgBox.setText("未检测到设备的温度信息"); + msgBox.setInformativeText("系统未能检测到设备的温度信息,\n但电压检测正常,是否继续测试?"); + msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); + msgBox.setDefaultButton(QMessageBox::Yes); + msgBox.setIcon(QMessageBox::Warning); + + int ret = msgBox.exec(); + if (ret == QMessageBox::No) { + updateTestStatus("ntc", STATUS_FAILED); + return; + } + // 用户选择继续,认为NTC检查通过 + ntcPassed = true; + updateTestStatus("ntc", STATUS_SUCCESS); } + } else { + // NTC检查未启用,不判定 + ntcPassed = true; } - // 判断电压是否正常,拼接失败原因 - if (!isVoltageNormal) { - if (!failReason.isEmpty()) failReason += ","; - failReason += QString("电压异常(%1V,正常范围3.3V-4.4V)").arg(voltage); - } + // 更新充电状态(用于判定,不显示在UI) + // charge和ntc的状态用于最终判定,但不单独显示 + // 如果充电检查失败,已经在上面return了,这里只记录状态用于判定 - // 最终判断测试结果 - if (isVoltageNormal && isTempNormal) { - // 电压和温度均正常(或未检测到温度但电压正常) - QString successMsg; - if (charge == 1) { - successMsg = QString("电池测试通过 - 电压: %1V, 充电中").arg(voltage); - } else { - successMsg = QString("电池测试通过 - 电压: %1V").arg(voltage); + // 最终判断:只有启用的检查项都通过,才认为电池测试通过 + bool allChecksPassed = chargePassed && ntcPassed && isVoltageNormal; + + if (allChecksPassed) { + QString successMsg = QString("电池测试通过 - 电压: %1V").arg(voltage); + if (charge == 1 && chargeCheckEnabled) { + successMsg += ", 充电中"; + } + if (temp != -1.0 && ntcCheckEnabled) { + successMsg += QString(", 温度: %1℃").arg(temp); } - if (temp != -1.0) successMsg += QString(", 温度: %1℃").arg(temp); if (percent > 0) successMsg += QString(", 电量: %1%").arg(percent); qDebug() << successMsg; ui->statusbar->showMessage(successMsg, 2000); updateTestStatus("battery", STATUS_SUCCESS); - } else { - // 电压或温度异常 - QString failMsg = QString("电池测试失败 - %1").arg(failReason); - if (temp == -1.0 && !isVoltageNormal) { - // 未检测到温度,仅电压异常 - failMsg = QString("电池测试失败 - 电压异常: %1V(正常范围3.3V-4.4V)").arg(voltage); - } else if (voltage >= 3.3 && voltage <= 4.4 && !isTempNormal) { - // 仅温度异常 - failMsg = QString("电池测试失败 - 温度异常: %1℃(正常范围%2℃-%3℃)").arg(temp).arg(MIN_NORMAL_TEMP).arg(MAX_NORMAL_TEMP); + } else { + QString failMsg = "电池测试失败 - "; + QStringList failReasons; + if (!chargePassed && chargeCheckEnabled) { + failReasons << "充电检查失败"; + } + if (!ntcPassed && ntcCheckEnabled) { + failReasons << "NTC温度检查失败"; + } + if (!isVoltageNormal) { + failReasons << QString("电压异常: %1V(正常范围3.3V-4.4V)").arg(voltage); } + failMsg += failReasons.join(","); qDebug() << failMsg; ui->statusbar->showMessage(failMsg, 2000); updateTestStatus("battery", STATUS_FAILED); } - // 电池测试完成,进入G-sensor测试(仅测试通过时继续) - if (isProductionTestRunning && currentTestStep == TEST_BATTERY && isVoltageNormal && isTempNormal) { - qDebug() << "电池测试完成(电压、温度均正常),开始G-sensor测试"; - currentTestStep = TEST_GSENSOR; - performGsensorTest(); + // 电池测试完成,进入下一个测试(仅所有检查通过时继续) + if (isProductionTestRunning && currentTestStep == TEST_BATTERY && allChecksPassed) { + qDebug() << "电池测试完成(所有检查通过),推进到下一个测试"; + skipToNextEnabledTest(); } } } @@ -3757,11 +3953,20 @@ void MainWindow::checkBatteryTestResult(const QString& data) // 执行G-sensor测试 void MainWindow::performGsensorTest() { + // 检查G-sensor测试是否启用 + if (!isTestItemEnabled("gsensor")) { + qDebug() << "G-sensor测试未启用,跳过"; + updateTestStatus("gsensor", STATUS_UNTESTED); + skipToNextEnabledTest(); + return; + } + if (!isProductionTestRunning || currentTestStep != TEST_GSENSOR) { return; } qDebug() << "开始G-sensor测试"; + ui->recvTextEdit->append("========== 开始G-sensor测试 =========="); updateTestStatus("gsensor", STATUS_TESTING); ui->statusbar->showMessage("G-sensor测试中,正在获取sensor ID...", 3000); @@ -3845,13 +4050,10 @@ void MainWindow::checkGsensorTestResult(const QString& data) updateTestStatus("gsensor", STATUS_FAILED); } - // G-sensor测试完成,开始蓝牙测试 + // G-sensor测试完成,推进到下一个测试 if (isProductionTestRunning && currentTestStep == TEST_GSENSOR) { - qDebug() << "G-sensor测试完成,开始蓝牙测试"; - - // 开始蓝牙测试 - currentTestStep = TEST_BLUETOOTH; - performBluetoothTest(); + qDebug() << "G-sensor测试完成,推进到下一个测试"; + skipToNextEnabledTest(); } } else { qDebug() << "G-sensor正则表达式匹配失败,数据:" << data.trimmed(); @@ -3862,13 +4064,10 @@ void MainWindow::checkGsensorTestResult(const QString& data) ui->statusbar->showMessage("G-sensor测试通过 - ID: 0x13 (手动检测)", 2000); updateTestStatus("gsensor", STATUS_SUCCESS); - // G-sensor测试完成,开始蓝牙测试 + // G-sensor测试完成,推进到下一个测试 if (isProductionTestRunning && currentTestStep == TEST_GSENSOR) { - qDebug() << "G-sensor测试完成(手动),开始蓝牙测试"; - - // 开始蓝牙测试 - currentTestStep = TEST_BLUETOOTH; - performBluetoothTest(); + qDebug() << "G-sensor测试完成(手动),推进到下一个测试"; + skipToNextEnabledTest(); } } } @@ -3882,13 +4081,10 @@ void MainWindow::checkGsensorTestResult(const QString& data) ui->statusbar->showMessage("G-sensor测试失败 - 设备无响应", 2000); updateTestStatus("gsensor", STATUS_FAILED); - // G-sensor测试失败,仍然继续蓝牙测试 + // G-sensor测试失败,仍然继续下一个测试 if (isProductionTestRunning && currentTestStep == TEST_GSENSOR) { - qDebug() << "G-sensor测试失败,继续蓝牙测试"; - - // 开始蓝牙测试 - currentTestStep = TEST_BLUETOOTH; - performBluetoothTest(); + qDebug() << "G-sensor测试失败,继续下一个测试"; + skipToNextEnabledTest(); } } } @@ -3896,11 +4092,22 @@ void MainWindow::checkGsensorTestResult(const QString& data) // 执行蓝牙测试 void MainWindow::performBluetoothTest() { + // 检查蓝牙测试是否启用 + if (!isTestItemEnabled("bluetooth")) { + qDebug() << "蓝牙测试未启用,跳过"; + updateTestStatus("bluetooth", STATUS_UNTESTED); + skipToNextEnabledTest(); + return; + } + if (!isProductionTestRunning || currentTestStep != TEST_BLUETOOTH) { + qDebug() << "蓝牙测试条件不满足,退出 - isProductionTestRunning:" << isProductionTestRunning + << ", currentTestStep:" << currentTestStep << ", TEST_BLUETOOTH:" << TEST_BLUETOOTH; return; } qDebug() << "开始蓝牙测试"; + ui->recvTextEdit->append("========== 开始蓝牙测试 =========="); updateTestStatus("bluetooth", STATUS_TESTING); // 重置蓝牙测试相关状态 @@ -3931,13 +4138,26 @@ void MainWindow::performBluetoothTest() qDebug() << "蓝牙测试模式:3设备模式"; } - // 发送开启蓝牙扫描指令 - QString bluetoothCmd = "AT^BTSCANTEST=1\r\n"; - serial->write(bluetoothCmd.toUtf8()); - qDebug() << "发送蓝牙测试开启指令:" << bluetoothCmd.trimmed(); + // 先发送蓝牙使能指令 + ui->recvTextEdit->append(">>> 发送指令: AT^BTENABLE (启用蓝牙)"); + serial->write("AT^BTENABLE\r\n"); + qDebug() << "发送蓝牙使能指令: AT^BTENABLE"; - // 启动10秒超时检测 - bluetoothTestTimer->start(15000); + // 延迟200ms后发送开启蓝牙扫描指令 + QTimer::singleShot(200, this, [this]() { + if (!isProductionTestRunning || currentTestStep != TEST_BLUETOOTH) { + qDebug() << "蓝牙测试已结束,取消发送扫描指令"; + return; + } + + QString bluetoothCmd = "AT^BTSCANTEST=1\r\n"; + ui->recvTextEdit->append(">>> 发送指令: AT^BTSCANTEST=1 (开始蓝牙扫描)"); + serial->write(bluetoothCmd.toUtf8()); + qDebug() << "发送蓝牙测试开启指令:" << bluetoothCmd.trimmed(); + + // 启动15秒超时检测 + bluetoothTestTimer->start(15000); + }); } // 检查蓝牙测试结果 @@ -3980,6 +4200,9 @@ void MainWindow::checkBluetoothTestResult(const QString& data) if (matched && rssiOk) { qDebug() << "解析到蓝牙地址:" << address << ",RSSI:" << rssi; + // 打印到UI:检测到蓝牙设备 + ui->recvTextEdit->append(QString(">>> 检测到蓝牙设备: MAC=%1, RSSI=%2 dBm").arg(address).arg(rssi)); + // 检查是否使用指定地址+RSSI模式 QString targetAddress = ui->bluetoothAddressLineEdit->text().trimmed().toUpper(); QString rssiThresholdStr = ui->bluetoothRSSILineEdit->text().trimmed(); @@ -3996,6 +4219,7 @@ void MainWindow::checkBluetoothTestResult(const QString& data) if (rssi >= rssiThreshold) { // RSSI满足要求,测试通过 qDebug() << "蓝牙测试通过:检测到指定地址" << address << ",RSSI" << rssi << "大于等于阈值" << rssiThreshold; + ui->recvTextEdit->append(QString(">>> 蓝牙测试通过: 目标地址 %1, RSSI=%2 dBm (>= 阈值 %3)").arg(address).arg(rssi).arg(rssiThreshold)); ui->statusbar->showMessage(QString("蓝牙测试通过:地址 %1,RSSI %2").arg(address).arg(rssi), 3000); updateTestStatus("bluetooth", STATUS_SUCCESS); @@ -4008,18 +4232,28 @@ void MainWindow::checkBluetoothTestResult(const QString& data) // 发送结束蓝牙扫描指令 QString bluetoothEndCmd = "AT^BTSCANTEST=2\r\n"; + ui->recvTextEdit->append(">>> 发送指令: AT^BTSCANTEST=2 (结束蓝牙扫描)"); serial->write(bluetoothEndCmd.toUtf8()); qDebug() << "发送蓝牙测试结束指令:" << bluetoothEndCmd.trimmed(); - // 继续后续4G测试 - QTimer::singleShot(500, this, [this]() { + // 延迟200ms后发送蓝牙禁用指令 + QTimer::singleShot(200, this, [this]() { if (isProductionTestRunning && currentTestStep == TEST_BLUETOOTH) { - currentTestStep = TEST_PPP_INIT; - perform4GTest(); + ui->recvTextEdit->append(">>> 发送指令: AT^BTDISABLE (禁用蓝牙)"); + serial->write("AT^BTDISABLE\r\n"); + qDebug() << "发送蓝牙禁用指令: AT^BTDISABLE"; + + // 继续后续测试 + QTimer::singleShot(300, this, [this]() { + if (isProductionTestRunning && currentTestStep == TEST_BLUETOOTH) { + skipToNextEnabledTest(); + } + }); } }); } else { qDebug() << "RSSI不满足要求:" << rssi << "<" << rssiThreshold; + ui->recvTextEdit->append(QString(">>> 蓝牙测试: 目标地址 %1, RSSI=%2 dBm (< 阈值 %3,不满足要求)").arg(address).arg(rssi).arg(rssiThreshold)); ui->statusbar->showMessage(QString("蓝牙测试:检测到地址 %1,但RSSI %2 小于阈值 %3").arg(address).arg(rssi).arg(rssiThreshold), 2000); } } @@ -4028,11 +4262,13 @@ void MainWindow::checkBluetoothTestResult(const QString& data) if (!bluetoothAddresses.contains(address)) { bluetoothAddresses.insert(address); qDebug() << "检测到新的蓝牙地址:" << address << ",当前已检测到" << bluetoothAddresses.size() << "个不同地址"; + ui->recvTextEdit->append(QString(">>> 新蓝牙设备: MAC=%1, RSSI=%2 dBm (已检测到 %3 个不同设备)").arg(address).arg(rssi).arg(bluetoothAddresses.size())); ui->statusbar->showMessage(QString("蓝牙测试:已检测到 %1 个不同地址").arg(bluetoothAddresses.size()), 2000); // 检查是否达到3个及以上不同的蓝牙地址 if (bluetoothAddresses.size() >= 3) { qDebug() << "蓝牙测试通过:已检测到" << bluetoothAddresses.size() << "个不同的蓝牙地址"; + ui->recvTextEdit->append(QString(">>> 蓝牙测试通过: 已检测到 %1 个不同设备 (要求>=3)").arg(bluetoothAddresses.size())); ui->statusbar->showMessage(QString("蓝牙测试通过:检测到 %1 个不同地址").arg(bluetoothAddresses.size()), 3000); updateTestStatus("bluetooth", STATUS_SUCCESS); @@ -4045,19 +4281,30 @@ void MainWindow::checkBluetoothTestResult(const QString& data) // 发送结束蓝牙扫描指令 QString bluetoothEndCmd = "AT^BTSCANTEST=2\r\n"; + ui->recvTextEdit->append(">>> 发送指令: AT^BTSCANTEST=2 (结束蓝牙扫描)"); serial->write(bluetoothEndCmd.toUtf8()); qDebug() << "发送蓝牙测试结束指令:" << bluetoothEndCmd.trimmed(); - // 继续后续4G测试 - QTimer::singleShot(500, this, [this]() { + // 延迟200ms后发送蓝牙禁用指令 + QTimer::singleShot(200, this, [this]() { if (isProductionTestRunning && currentTestStep == TEST_BLUETOOTH) { - currentTestStep = TEST_PPP_INIT; - perform4GTest(); + ui->recvTextEdit->append(">>> 发送指令: AT^BTDISABLE (禁用蓝牙)"); + serial->write("AT^BTDISABLE\r\n"); + qDebug() << "发送蓝牙禁用指令: AT^BTDISABLE"; + + // 继续后续测试 + QTimer::singleShot(300, this, [this]() { + if (isProductionTestRunning && currentTestStep == TEST_BLUETOOTH) { + skipToNextEnabledTest(); + } + }); } }); } } else { qDebug() << "检测到重复的蓝牙地址:" << address << ",已存在,跳过"; + // 即使是重复地址,也打印到UI(但标记为重复) + ui->recvTextEdit->append(QString(">>> 重复蓝牙设备: MAC=%1, RSSI=%2 dBm (已存在)").arg(address).arg(rssi)); } } } @@ -4109,14 +4356,23 @@ void MainWindow::onBluetoothTestTimer() // 发送结束蓝牙扫描指令(无论成功失败都要发送) QString bluetoothEndCmd = "AT^BTSCANTEST=2\r\n"; + ui->recvTextEdit->append(">>> 发送指令: AT^BTSCANTEST=2 (结束蓝牙扫描)"); serial->write(bluetoothEndCmd.toUtf8()); qDebug() << "发送蓝牙测试结束指令:" << bluetoothEndCmd.trimmed(); - // 继续后续4G测试 - QTimer::singleShot(500, this, [this]() { + // 延迟200ms后发送蓝牙禁用指令 + QTimer::singleShot(200, this, [this]() { if (isProductionTestRunning && currentTestStep == TEST_BLUETOOTH) { - currentTestStep = TEST_PPP_INIT; - perform4GTest(); + ui->recvTextEdit->append(">>> 发送指令: AT^BTDISABLE (禁用蓝牙)"); + serial->write("AT^BTDISABLE\r\n"); + qDebug() << "发送蓝牙禁用指令: AT^BTDISABLE"; + + // 继续后续测试 + QTimer::singleShot(300, this, [this]() { + if (isProductionTestRunning && currentTestStep == TEST_BLUETOOTH) { + skipToNextEnabledTest(); + } + }); } }); } @@ -4201,6 +4457,7 @@ void MainWindow::perform4GSignalTest() } qDebug() << "开始4G信号质量测试"; + ui->recvTextEdit->append("========== 开始4G信号质量测试 =========="); ui->statusbar->showMessage("4G信号质量测试中...", 5000); // 根据MODEM类型选择不同的测试方式 @@ -4615,11 +4872,10 @@ void MainWindow::showBatteryChargeFailDialog() qDebug() << "用户确认电池充电失败,标记测试失败"; updateTestStatus("battery", STATUS_FAILED); - // ç»§ç»­G-sensor测试 + // 继续下一个测试 if (isProductionTestRunning && currentTestStep == TEST_BATTERY) { - qDebug() << "电池测试失败确认,继续G-sensor测试"; - currentTestStep = TEST_GSENSOR; - performGsensorTest(); + qDebug() << "电池测试失败确认,继续下一个测试"; + skipToNextEnabledTest(); } } else if (chargeFailDialog.clickedButton() == retryButton) { qDebug() << "用户选择重新获取电池信息"; @@ -4827,6 +5083,7 @@ void MainWindow::showFinalTestResult() // 发送退出产测指令 if (serial->isOpen()) { + ui->recvTextEdit->append(">>> 发送指令: AT^RESTORE (退出产测)"); serial->write("AT^RESTORE\r\n"); qDebug() << "发送退出产测指令: AT^RESTORE"; ui->statusbar->showMessage("已退出产测模式", 3000); @@ -4978,38 +5235,9 @@ void MainWindow::onTestTimeout() updateTestStatus(testName, STATUS_FAILED); // 继续下一个测试 - switch (currentTestStep) { - case TEST_MOTOR: - currentTestStep = TEST_KEY; - performKeyTest(); - break; - case TEST_BATTERY: - currentTestStep = TEST_GSENSOR; - performGsensorTest(); - break; - case TEST_GSENSOR: - { - // G-sensor测试超时,继续蓝牙测试 - qDebug() << "G-sensor测试超时,继续蓝牙测试"; - updateTestStatus("gsensor", STATUS_FAILED); - currentTestStep = TEST_BLUETOOTH; - performBluetoothTest(); - break; - } - case TEST_BLUETOOTH: - { - // 蓝牙测试超时,继续4G测试 - qDebug() << "蓝牙测试超时,继续4G测试"; - updateTestStatus("bluetooth", STATUS_FAILED); - currentTestStep = TEST_PPP_INIT; - perform4GTest(); - break; - } - default: - break; - } + skipToNextEnabledTest(); - } else { + } else { // 用户选择停止测试 qDebug() << "用户选择停止测试"; ui->statusbar->showMessage("测试已停止", 2000); @@ -5422,6 +5650,7 @@ void MainWindow::sendNextVersionCommand() QString cmd = versionCommandQueue[currentVersionCommandIndex]; if (serial->isOpen()) { + ui->recvTextEdit->append(QString(">>> 发送指令: %1 (获取版本信息 [%2/%3])").arg(cmd).arg(currentVersionCommandIndex + 1).arg(versionCommandQueue.size())); serial->write((cmd + "\r\n").toUtf8()); qDebug() << "发送版本信息指令[" << (currentVersionCommandIndex + 1) << "/" << versionCommandQueue.size() << "]:" << cmd; appendToLogFile(QString("发送版本信息指令: %1\n").arg(cmd)); @@ -5489,6 +5718,17 @@ void MainWindow::saveTestConfigToSettings() configManager.setTestConfig("bluetoothAddress", ui->bluetoothAddressLineEdit->text()); configManager.setTestConfig("bluetoothRSSI", ui->bluetoothRSSILineEdit->text()); + // 保存测试项checkbox状态 + configManager.setTestCheckbox("lcd", ui->checkBox_lcd->isChecked()); + configManager.setTestCheckbox("vib", ui->checkBox_vib->isChecked()); + configManager.setTestCheckbox("btn", ui->checkBox_btn->isChecked()); + configManager.setTestCheckbox("mic", ui->checkBox_mic->isChecked()); + configManager.setTestCheckbox("charge", ui->checkBox_charge->isChecked()); + configManager.setTestCheckbox("ntc", ui->checkBox_ntc->isChecked()); + // gsensor checkbox可能不存在,跳过 + configManager.setTestCheckbox("bt", ui->checkBox_bt->isChecked()); + configManager.setTestCheckbox("4g", ui->checkBox_4g->isChecked()); + // 保存到文件 configManager.saveConfig(); @@ -5529,9 +5769,143 @@ void MainWindow::loadTestConfigFromSettings() ui->bluetoothAddressLineEdit->setText(configManager.getTestConfig("bluetoothAddress", "")); ui->bluetoothRSSILineEdit->setText(configManager.getTestConfig("bluetoothRSSI", "")); + // 恢复测试项checkbox状态 + ui->checkBox_lcd->setChecked(configManager.getTestCheckbox("lcd", true)); + ui->checkBox_vib->setChecked(configManager.getTestCheckbox("vib", true)); + ui->checkBox_btn->setChecked(configManager.getTestCheckbox("btn", true)); + ui->checkBox_mic->setChecked(configManager.getTestCheckbox("mic", true)); + ui->checkBox_charge->setChecked(configManager.getTestCheckbox("charge", true)); + ui->checkBox_ntc->setChecked(configManager.getTestCheckbox("ntc", true)); + // gsensor checkbox可能不存在,跳过 + ui->checkBox_bt->setChecked(configManager.getTestCheckbox("bt", true)); + ui->checkBox_4g->setChecked(configManager.getTestCheckbox("4g", true)); + ui->checkBox_bt->setChecked(configManager.getTestCheckbox("bt", true)); + ui->checkBox_4g->setChecked(configManager.getTestCheckbox("4g", true)); + + qDebug() << "测试项checkbox状态已恢复"; + qDebug() << "测试参数已从settings.json加载"; } +// 检查测试项是否启用 +bool MainWindow::isTestItemEnabled(const QString& testName) const +{ + if (testName == "lcd") { + return ui->checkBox_lcd->isChecked(); + } else if (testName == "vib" || testName == "motor") { + return ui->checkBox_vib->isChecked(); + } else if (testName == "btn" || testName == "key") { + return ui->checkBox_btn->isChecked(); + } else if (testName == "mic" || testName == "audio") { + return ui->checkBox_mic->isChecked(); + } else if (testName == "charge") { + return ui->checkBox_charge->isChecked(); + } else if (testName == "ntc") { + return ui->checkBox_ntc->isChecked(); + } else if (testName == "gsensor") { + // gsensor checkbox可能不存在,默认启用 + return true; + } else if (testName == "bt" || testName == "bluetooth") { + return ui->checkBox_bt->isChecked(); + } else if (testName == "4g" || testName == "ppp") { + return ui->checkBox_4g->isChecked(); + } + return true; // 默认启用 +} + +// 跳过当前测试项,推进到下一个启用的测试项 +void MainWindow::skipToNextEnabledTest() +{ + if (!isProductionTestRunning) { + return; + } + + // 根据当前测试步骤,推进到下一个启用的测试项 + if (currentTestStep == TEST_LCD) { + // LCD测试完成,检查马达测试 + if (isTestItemEnabled("motor")) { + currentTestStep = TEST_MOTOR; + performMotorTest(); + } else { + qDebug() << "马达测试未启用,跳过"; + updateTestStatus("motor", STATUS_UNTESTED); + currentTestStep = TEST_MOTOR; // 推进到下一个测试步骤 + skipToNextEnabledTest(); // 递归继续下一个 + } + } else if (currentTestStep == TEST_MOTOR) { + // 马达测试完成,检查按键测试 + if (isTestItemEnabled("key")) { + currentTestStep = TEST_KEY; + performKeyTest(); + } else { + qDebug() << "按键测试未启用,跳过"; + updateTestStatus("key", STATUS_UNTESTED); + currentTestStep = TEST_KEY; // 推进到下一个测试步骤 + skipToNextEnabledTest(); // 递归继续下一个 + } + } else if (currentTestStep == TEST_KEY) { + // 按键测试完成,检查录音测试 + if (isTestItemEnabled("audio")) { + currentTestStep = TEST_AUDIO; + performAudioTest(); + } else { + qDebug() << "录音测试未启用,跳过"; + updateTestStatus("audio", STATUS_UNTESTED); + currentTestStep = TEST_AUDIO; // 推进到下一个测试步骤 + skipToNextEnabledTest(); // 递归继续下一个 + } + } else if (currentTestStep == TEST_AUDIO) { + // 录音测试完成,检查电池测试(如果充电或ntc任一启用,都需要执行电池测试) + if (isTestItemEnabled("charge") || isTestItemEnabled("ntc")) { + currentTestStep = TEST_BATTERY; + performBatteryTest(); + } else { + qDebug() << "电池测试未启用,跳过"; + updateTestStatus("battery", STATUS_UNTESTED); + currentTestStep = TEST_BATTERY; // 推进到下一个测试步骤 + skipToNextEnabledTest(); // 递归继续下一个 + } + } else if (currentTestStep == TEST_BATTERY) { + // 电池测试完成,检查G-sensor测试 + if (isTestItemEnabled("gsensor")) { + currentTestStep = TEST_GSENSOR; + performGsensorTest(); + } else { + qDebug() << "G-sensor测试未启用,跳过"; + updateTestStatus("gsensor", STATUS_UNTESTED); + currentTestStep = TEST_GSENSOR; // 推进到下一个测试步骤 + skipToNextEnabledTest(); // 递归继续下一个 + } + } else if (currentTestStep == TEST_GSENSOR) { + // G-sensor测试完成,检查蓝牙测试 + if (isTestItemEnabled("bluetooth")) { + currentTestStep = TEST_BLUETOOTH; + performBluetoothTest(); + } else { + qDebug() << "蓝牙测试未启用,跳过"; + updateTestStatus("bluetooth", STATUS_UNTESTED); + currentTestStep = TEST_BLUETOOTH; // 推进到下一个测试步骤 + skipToNextEnabledTest(); // 递归继续下一个 + } + } else if (currentTestStep == TEST_BLUETOOTH) { + // 蓝牙测试完成,检查4G测试 + if (isTestItemEnabled("ppp")) { + currentTestStep = TEST_PPP_INIT; + perform4GTest(); + } else { + qDebug() << "4G测试未启用,跳过"; + updateTestStatus("ppp", STATUS_UNTESTED); + // 所有测试完成 + currentTestStep = TEST_COMPLETED; + isProductionTestRunning = false; + QString fileName = saveTestRecord(); + showFinalTestResult(); + } + } else { + qDebug() << "未知的测试步骤,无法推进"; + } +} + // 保存recvTextEdit内容到日志文件 void MainWindow::saveRecvTextEditToLog() { @@ -5587,6 +5961,38 @@ void MainWindow::saveRecvTextEditToLog() } else { qDebug() << "无法保存UI日志文件:" << filePath << "错误:" << logFile.errorString(); } + + // 同时保存logtextEdit的完整日志(文件名加full后缀) + QString fullLogContent = ui->logtextEdit->toPlainText(); + if (!fullLogContent.trimmed().isEmpty()) { + // 生成完整日志文件名(加full后缀) + QString fullFileName = QString("%1_%2_%3_%4_UI日志full.log") + .arg(now.toString("yyyyMMdd")) + .arg(now.toString("hhmmss")) + .arg(imei) + .arg(iccid); + + QString fullFilePath = logsDir + "/" + fullFileName; + + QFile fullLogFile(fullFilePath); + if (fullLogFile.open(QIODevice::WriteOnly | QIODevice::Text)) { + QTextStream fullStream(&fullLogFile); + fullStream.setCodec("UTF-8"); + fullStream << QString("=== 完整日志保存时间: %1 ===\n").arg(now.toString("yyyy-MM-dd hh:mm:ss")); + fullStream << QString("IMEI: %1\n").arg(imei); + fullStream << QString("ICCID: %1\n").arg(iccid); + fullStream << "========================================\n"; + fullStream << fullLogContent; + fullLogFile.close(); + + qDebug() << "完整日志已保存到:" << fullFilePath; + ui->statusbar->showMessage(QString("完整日志已保存: %1").arg(fullFileName), 3000); + } else { + qDebug() << "无法保存完整日志文件:" << fullFilePath << "错误:" << fullLogFile.errorString(); + } + } else { + qDebug() << "logtextEdit内容为空,跳过保存完整日志"; + } } // 创建测试日志文件 @@ -5648,13 +6054,17 @@ void MainWindow::createTestLogFile() qDebug() << "测试日志文件已创建:" << testLogFilePath; } -// 追加内容到日志文件(同时显示到recvTextEdit) +// 追加内容到日志文件(同时显示到recvTextEdit和logtextEdit) void MainWindow::appendToLogFile(const QString& text) { // 显示到recvTextEdit ui->recvTextEdit->insertPlainText(text); ui->recvTextEdit->moveCursor(QTextCursor::End); + // 同时显示到logtextEdit(完整日志) + ui->logtextEdit->insertPlainText(text); + ui->logtextEdit->moveCursor(QTextCursor::End); // 自动滚动到底部 + // 如果日志文件已打开,写入日志文件 if (testLogFile && testLogStream && testLogFile->isOpen()) { *testLogStream << text; diff --git a/mainwindow.h b/mainwindow.h index 1c705ae..552257d 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -247,5 +247,9 @@ private: // 测试参数配置保存和恢复(使用settings.json) void saveTestConfigToSettings(); // 保存测试参数到settings.json void loadTestConfigFromSettings(); // 从settings.json加载测试参数 + + // 测试项checkbox检查辅助函数 + bool isTestItemEnabled(const QString& testName) const; + void skipToNextEnabledTest(); // 跳过当前测试项,推进到下一个启用的测试项 }; #endif // MAINWINDOW_H diff --git a/mainwindow.ui b/mainwindow.ui index 53e5a2d..07c79ee 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -7,7 +7,7 @@ 0 0 1309 - 823 + 829 @@ -476,6 +476,19 @@ background-color: #F57C00; + + + + + 16777215 + 100 + + + + Qt::ScrollBarAlwaysOff + + + @@ -675,7 +688,7 @@ background-color: #F57C00; 0 0 424 - 523 + 529 @@ -1147,6 +1160,80 @@ background-color: #F57C00; + + + + Qt::Horizontal + + + + + + + + + 选择测试项: + + + + + + + LCD + + + + + + + 按键 + + + + + + + 蓝牙测试 + + + + + + + NTC + + + + + + + 录音 + + + + + + + 马达 + + + + + + + 4G测试 + + + + + + + 充电 + + + + +