#include "answerWidget.h" #include "ui_answerWidget.h" #include "CAppInfo.h" #include "awMsgBox.h" #include "awQuestionNavigate.h" #include "CCommonTools.h" #include "logproc.h" #include "inprogressFace.h" #include "popMsgBox.h" answerWidget::answerWidget(QWidget *parent) : QWidget(parent), ui(new Ui::answerWidget) { ui->setupUi(this); setStyleSheet(g_appInfoPtr->m_sQssStr); m_sRemoteList << "teamviewer" << "lookmypc" //<< "xt" << "winaw32" << "pcaquickconnect" << "sessioncontroller" << "sunlogin"; // << "sunloginremote"; /* << "qq" <<"wechat" <<"wemeetapp";*/ m_sRemoteTipList << "TeamViewer" << "LookMyPC" //<< QString::fromLocal8Bit("协通") << "Symantec PCAnywhere" << "Symantec PCAnywhere" << "Symantec PCAnywhere" << QString::fromLocal8Bit("向日葵"); // << QString::fromLocal8Bit("向日葵"); /* << "QQ" << QString::fromLocal8Bit("微信") << QString::fromLocal8Bit("腾讯会议");*/ qRegisterMetaType("CGetExamById"); connect(g_httpBllPtr.get(), &CHttpBll::sgnGetExamById, this, &answerWidget::onGetExamById); qRegisterMetaType("CGetExamRecordPaperStruct"); connect(g_httpBllPtr.get(), &CHttpBll::sgnGetExamRecordPaperStruct, this, &answerWidget::onGetExamRecordPaperStruct); qRegisterMetaType("CGetExamProperty"); connect(g_httpBllPtr.get(), &CHttpBll::sgnGetExamProperty, this, &answerWidget::onGetExamProperty); qRegisterMetaType("CWeiXinAnswerEnabled"); connect(g_httpBllPtr.get(), &CHttpBll::sgnWeiXinAnswerEnabled, this, &answerWidget::onWeiXinAnswerEnabled); qRegisterMetaType("CGetQuestionContent"); connect(g_httpBllPtr.get(), &CHttpBll::sgnGetQuestionContent, this, &answerWidget::onGetQuestionContent); qRegisterMetaType("CFindExamQuestionList"); connect(g_httpBllPtr.get(), &CHttpBll::sgnFindExamQuestionList, this, &answerWidget::onFindExamQuestionList); qRegisterMetaType("CStartAnswer"); connect(g_httpBllPtr.get(), &CHttpBll::sgnStartAnswer, this, &answerWidget::onStartAnswer); qRegisterMetaType("CExamHeartbeat"); connect(g_httpBllPtr.get(), &CHttpBll::sgnExamHeartbeat, this, &answerWidget::onExamHeartbeat); qRegisterMetaType("CSubmitQuestionAnswer"); connect(g_httpBllPtr.get(), &CHttpBll::sgnSubmitQuestionAnswer, this, &answerWidget::onSubmitQuestionAnswer); qRegisterMetaType("CEndExam"); connect(g_httpBllPtr.get(), &CHttpBll::sgnEndExam, this, &answerWidget::onEndExam); // qRegisterMetaType("CGetOrgPropertiesByGroupWithoutCache"); // connect(g_httpBllPtr.get(), &CHttpBll::sgnGetOrgPropertiesByGroupWithoutCache, this, &answerWidget::onGetOrgPropertiesByGroupWithoutCache); qRegisterMetaType("CStartFaceLiveVerify"); connect(g_httpBllPtr.get(), &CHttpBll::sgnStartFaceLiveVerify, this, &answerWidget::onStartFaceLiveVerify); #ifdef _DEBUG //g_appInfoPtr->m_oExamInfo.bLivenessCheck = false; // g_appInfoPtr->m_oExamInfo.bFaceCheck = false; #endif // _DEBUG //m_MonitorEnumeratorPtr = std::make_shared(); m_nLeftSeconds = 0; m_nHeartBreatFailedCount = 0; bShowLeftHint = false; GetExamProperty(); // CHttpRequestPackage hrp; // hrp.sUri = QString("/api/ecs_exam_work/exam/getExamPropertyFromCacheByStudentSession/%1/%2") // .arg(g_appInfoPtr->m_oExamInfo.nExamId).arg("SNAPSHOT_INTERVAL,PRACTICE_TYPE,FREEZE_TIME,PRACTICE_TYPE"); // hrp.nRequestType = RequestType::rtGetExamProperty; // hrp.sCommonStr = "SNAPSHOT_INTERVAL,PRACTICE_TYPE,FREEZE_TIME"; // g_httpBllPtr->get(hrp); // { // CHttpRequestPackage hrp; // hrp.sUri = QString("/api/ecs_exam_work/exam/%1").arg(g_appInfoPtr->m_oExamInfo.nExamId); // hrp.nRequestType = RequestType::rtGetExamById; // g_httpBllPtr->get(hrp); // } // CHttpRequestPackage hrp1; // hrp1.sUri = "/api/ecs_oe_student/client/exam/process/getExamRecordPaperStruct"; // hrp1.sParamList.push_back(QString("examRecordDataId,%1").arg(g_appInfoPtr->m_oExamInfo.nExamRecordDataId)); // hrp1.nRequestType = RequestType::rtGetExamRecordPaperStruct; // hrp1.eParamType = HttpParamType::hptUrl; // g_httpBllPtr->post(hrp1); // { // CHttpRequestPackage hrp; // hrp.sUri = "/api/ecs_oe_student/client/exam/process/findExamQuestionList"; // hrp.nRequestType = RequestType::rtFindExamQuestionList; // g_httpBllPtr->post(hrp); // } // { // CHttpRequestPackage hrp; // hrp.sUri = QString("/api/ecs_exam_work/exam/weixinAnswerEnabled/%1") // .arg(g_appInfoPtr->m_oExamInfo.nExamId); // hrp.sParamList.push_back(QString::fromLocal8Bit("courseCode,%1").arg(g_appInfoPtr->m_oExamInfo.sCourseCode)); // hrp.nRequestType = RequestType::rtWeiXinAnswerEnabled; // g_httpBllPtr->get(hrp); // } m_pCountDownTimer = std::make_shared(); m_pCountDownTimer->setInterval(1000); connect(m_pCountDownTimer.get(), &QTimer::timeout, this, [&](){ --m_nLeftSeconds; ui->label_lastTime->setText(QString("%1:%2:%3").arg(m_nLeftSeconds/60/60, 2, 10, QChar('0')) .arg(m_nLeftSeconds/60%60, 2, 10, QChar('0')) .arg(m_nLeftSeconds%60, 2, 10, QChar('0'))); if(m_nLeftSeconds <= 0) { // m_pCountDownTimer->stop(); handinPaper(); } if(m_nLeftSeconds <= 5*60 && m_nLeftSeconds >= 5 * 60 - 5 && !bShowLeftHint) { bShowLeftHint = true; if(m_ptimeLeftTips == nullptr) { m_ptimeLeftTips = std::make_shared(MASK_POP_WIDGET_TYPE::wt_timeLeft, (QWidget*)(this->parent())); connect(m_ptimeLeftTips.get(), &awTimeLeftTips::timeLeftConfirm, this, [&](){ m_ptimeLeftTips.reset(); }); } m_ptimeLeftTips->show(); } if(g_appInfoPtr->m_oExamInfo.bLivenessCheck && g_appInfoPtr->m_oExamInfo.nFaceLiveVerifyId > 0) { if(bShowLivenessTip && (m_nUsedExamSeconds + m_nEnterExamTime - m_nLeftSeconds + g_appInfoPtr->m_oExamInfo.nActionAlert) > g_appInfoPtr->m_oExamInfo.nFaceVerifyDoMinute*60) { bShowLivenessTip = false; m_nEnterLivenessFaceSeconds = m_nLeftSeconds - 20; ShowMsg(QString::fromLocal8Bit("%1秒后开始指定动作检测,请准备!").arg(g_appInfoPtr->m_oExamInfo.nActionAlert), g_appInfoPtr->m_pAnsBgWidget); } if((m_nUsedExamSeconds + m_nEnterExamTime - m_nLeftSeconds) > g_appInfoPtr->m_oExamInfo.nFaceVerifyDoMinute * 60 && m_nEnterLivenessFaceSeconds > m_nLeftSeconds) { //活体检测 if(m_pFaceLiveness == nullptr) { stopCapture(); m_pFaceLiveness = std::make_shared(FACE_LIVENESS_TYPE::flt_inprogress, g_appInfoPtr->m_pAnsBgWidget); connect(m_pFaceLiveness.get(), &faceLiveness::faceLivenessFaild, this, [&](){ g_appInfoPtr->m_oExamInfo.nFaceLiveVerifyId = 0; m_pFaceLiveness.reset(); if(g_appInfoPtr->m_oExamInfo.nFaceVerifyTimes < 2) { emit gobackLogin(); } else { //交卷 handinPaper(true); } }); connect(m_pFaceLiveness.get(), &faceLiveness::faceLivenessSucceed, this, [&](){ g_appInfoPtr->m_oExamInfo.nFaceLiveVerifyId = 0; m_pFaceLiveness.reset(); if (g_appInfoPtr->m_oExamInfo.bFaceCheck) { startCapture(); } }); m_pFaceLiveness->show(); } } } }); if (g_appInfoPtr->m_bDisableRemoteAssistance) { qRegisterMetaType("CGetSoftwareConfig"); connect(g_httpBllPtr.get(), &CHttpBll::sgnGetSoftwareConfig, this, &answerWidget::onGetSoftwareConfig); CHttpRequestPackage hrp; hrp.sUri = QString("https://%1/oe_client/software.json").arg(g_appInfoPtr->m_sEscDomain); hrp.nRequestType = RequestType::rtGetSoftwareConfig; g_httpBllPtr->getUrl(hrp); } m_pHeartbeatTimer = std::make_shared(); m_pHeartbeatTimer->setInterval(60*1000); connect(m_pHeartbeatTimer.get(), &QTimer::timeout, this, [&](){ heartBreat(); if(g_appInfoPtr->m_bDisableRemoteAssistance) { checkRemoteBreach(); } }); } answerWidget::~answerWidget() { awMsgBox::clear(this); if (g_inProcessFace) { stopCapture(); g_inProcessFace.reset(); } delete ui; } void answerWidget::GetExamProperty() { CHttpRequestPackage hrp; hrp.sUri = QString("/api/ecs_exam_work/exam/getExamPropertyFromCacheByStudentSession/%1/%2") .arg(g_appInfoPtr->m_oExamInfo.nExamId).arg("SNAPSHOT_INTERVAL,PRACTICE_TYPE,FREEZE_TIME,PRACTICE_TYPE"); hrp.nRequestType = RequestType::rtGetExamProperty; hrp.sCommonStr = "SNAPSHOT_INTERVAL,PRACTICE_TYPE,FREEZE_TIME"; g_httpBllPtr->get(hrp); } void answerWidget::GetExamById() { CHttpRequestPackage hrp; hrp.sUri = QString("/api/ecs_exam_work/exam/%1").arg(g_appInfoPtr->m_oExamInfo.nExamId); hrp.nRequestType = RequestType::rtGetExamById; g_httpBllPtr->get(hrp); } void answerWidget::GetExamRecordPaperStruct() { CHttpRequestPackage hrp1; hrp1.sUri = "/api/ecs_oe_student/client/exam/process/getExamRecordPaperStruct"; hrp1.sParamList.push_back(QString("examRecordDataId,%1").arg(g_appInfoPtr->m_oExamInfo.nExamRecordDataId)); hrp1.nRequestType = RequestType::rtGetExamRecordPaperStruct; hrp1.eParamType = HttpParamType::hptUrl; g_httpBllPtr->post(hrp1); } void answerWidget::FindExamQuestionList() { CHttpRequestPackage hrp; hrp.sUri = "/api/ecs_oe_student/client/exam/process/findExamQuestionList"; hrp.nRequestType = RequestType::rtFindExamQuestionList; g_httpBllPtr->post(hrp); } void answerWidget::WeiXinAnswerEnabled() { CHttpRequestPackage hrp; hrp.sUri = QString("/api/ecs_exam_work/exam/weixinAnswerEnabled/%1") .arg(g_appInfoPtr->m_oExamInfo.nExamId); hrp.sParamList.push_back(QString::fromLocal8Bit("courseCode,%1").arg(g_appInfoPtr->m_oExamInfo.sCourseCode)); hrp.nRequestType = RequestType::rtWeiXinAnswerEnabled; g_httpBllPtr->get(hrp); } void answerWidget::onGetSoftwareConfig(CGetSoftwareConfig getSoftwareConfig) { if (getSoftwareConfig.nCode == 200) { QString sSoftwareConfig = QByteArray::fromBase64(getSoftwareConfig.sSoftwareConfig.toLocal8Bit()); if(!sSoftwareConfig.isEmpty()) { Json::Reader reader; Json::Value jsonRoot = Json::Value::null; if (reader.parse(sSoftwareConfig.toStdString(), jsonRoot)) { QString sCamera = jsonRoot["vCamList"].asString().c_str(); QStringList cameraList = sCamera.split("\n", QString::SkipEmptyParts); QString sRemoteApp = jsonRoot["remoteApp"].asString().c_str(); QStringList remoteAppList = sRemoteApp.split("\n", QString::SkipEmptyParts); m_sRemoteList += remoteAppList; m_sRemoteTipList += remoteAppList; } } } } void answerWidget::checkRemoteBreach() { static int nIndex = 0; ++nIndex; if(nIndex % 3 == 0) { std::shared_ptr m_MonitorEnumeratorPtr = std::make_shared(); bool bExit = false; QString sCheckStr = ""; if (CCommonTools::isUseRDP()) { sCheckStr = QString::fromLocal8Bit("检测是否开启远程桌面"); qDebug() << QString::fromLocal8Bit("开启远程桌面"); bExit = true; } if (m_MonitorEnumeratorPtr->getMontorNumber() > 1) { sCheckStr = QString::fromLocal8Bit("请检测是否开启分屏"); qDebug() << QString::fromLocal8Bit("开启双屏"); bExit = true; } QStringList appList; CCommonTools::getAllAppNameList(appList, m_sRemoteList, m_sRemoteTipList); if (appList.count() > 0) { bExit = true; for (int i = 0; i < appList.count(); i++) { if (sCheckStr.isEmpty()) { sCheckStr = QString::fromLocal8Bit("请检测是否开启%1").arg(appList[i]); } else { sCheckStr += QString::fromLocal8Bit("、%1").arg(appList[i]); } } } QApplication::processEvents(); if (bExit) { //退出 awTimeLeftTips *wExitExam = new awTimeLeftTips(MASK_POP_WIDGET_TYPE::wt_exitExam, (QWidget*)(this->parent())); wExitExam->setText(sCheckStr, QString::fromLocal8Bit("退出考试")); connect(wExitExam, &awTimeLeftTips::timeLeftConfirm, this, [this, wExitExam]() { if (m_pNetWorkErrorTimerPtr) { m_pNetWorkErrorTimerPtr->stop(); } delete wExitExam; emit gobackLogin(); }); wExitExam->show(); if (m_pNetWorkErrorTimerPtr == nullptr) { m_pNetWorkErrorTimerPtr = std::make_shared(); m_pNetWorkErrorTimerPtr->setInterval(30 * 1000); connect(m_pNetWorkErrorTimerPtr.get(), &QTimer::timeout, [this, wExitExam]() { m_pNetWorkErrorTimerPtr->stop(); delete wExitExam; emit gobackLogin(); }); } m_pNetWorkErrorTimerPtr->start(); } } } void answerWidget::setUI(const int nLeft, const int nTop, const int nWidth, const int nHeight) { setGeometry(nLeft, nTop, nWidth, nHeight); ui->widget_aw_answerBG->setGeometry(0, 0, width()*970/(970+270), height()); ui->widget_navigate->setGeometry(ui->widget_aw_answerBG->x() + ui->widget_aw_answerBG->width() + g_appInfoPtr->m_fRate*20, 0, width() - ui->widget_aw_answerBG->width() - g_appInfoPtr->m_fRate*20, height()); ui->widget_aw_face->setGeometry(0, ui->widget_navigate->height() - g_appInfoPtr->m_fRate*140, ui->widget_navigate->width(), g_appInfoPtr->m_fRate*140); ui->widget_aw_top->setGeometry(0, 0, ui->widget_aw_answerBG->width(), g_appInfoPtr->m_fRate*56); ui->widget_ng_top->setGeometry(0, 0, ui->widget_navigate->width(), g_appInfoPtr->m_fRate*56); ui->label_answerProgress->adjustSize(); ui->label_answerProgress->setGeometry(g_appInfoPtr->m_fRate*20, (ui->widget_aw_top->height() - ui->label_answerProgress->height())/2, ui->label_answerProgress->width(), ui->label_answerProgress->height()); ui->pgb_answerProgress->setGeometry(ui->label_answerProgress->x() + ui->label_answerProgress->width() + g_appInfoPtr->m_fRate*8, (ui->widget_aw_top->height() - g_appInfoPtr->m_fRate*20)/2, g_appInfoPtr->m_fRate*200, g_appInfoPtr->m_fRate*20); ui->btn_handInPaper->setGeometry(ui->widget_aw_top->width() - g_appInfoPtr->m_fRate*(10 + 100), g_appInfoPtr->m_fRate*10, g_appInfoPtr->m_fRate*100, g_appInfoPtr->m_fRate*36); ui->label_lastTimeIcon->setGeometry(g_appInfoPtr->m_fRate*48, g_appInfoPtr->m_fRate*12, g_appInfoPtr->m_fRate*32, g_appInfoPtr->m_fRate*32); ui->label_lastTime->adjustSize(); ui->label_lastTime->setGeometry(ui->label_lastTimeIcon->x() + ui->label_lastTimeIcon->width() + g_appInfoPtr->m_fRate*10, ui->label_lastTimeIcon->y() + (ui->label_lastTimeIcon->height() - ui->label_lastTime->height())/2, ui->label_lastTime->width(), ui->label_lastTime->height()); ui->btn_all->setGeometry(g_appInfoPtr->m_fRate*30, ui->widget_ng_top->height() + g_appInfoPtr->m_fRate*20, g_appInfoPtr->m_fRate*90, g_appInfoPtr->m_fRate*28); ui->btn_allNum->setGeometry(ui->btn_all->x() + ui->btn_all->width() - g_appInfoPtr->m_fRate*(4 + 30), ui->btn_all->y() + (ui->btn_all->height() - g_appInfoPtr->m_fRate*20)/2, g_appInfoPtr->m_fRate*30, g_appInfoPtr->m_fRate*20); ui->btn_answered->setGeometry(ui->btn_all->x() + ui->btn_all->width() + g_appInfoPtr->m_fRate*10, ui->btn_all->y(), ui->btn_all->width(), ui->btn_all->height()); ui->btn_answeredNum->setGeometry(ui->btn_answered->x() + ui->btn_answered->width() - g_appInfoPtr->m_fRate*(4 + 30), ui->btn_allNum->y(), ui->btn_allNum->width(), ui->btn_allNum->height()); ui->btn_unanswered->setGeometry(ui->btn_all->x(), ui->btn_all->y() + ui->btn_all->height() + g_appInfoPtr->m_fRate*10, ui->btn_all->width(), ui->btn_all->height()); ui->btn_unansweredNum->setGeometry(ui->btn_allNum->x(), ui->btn_unanswered->y() + (ui->btn_unanswered->height() - g_appInfoPtr->m_fRate*20)/2, ui->btn_allNum->width(), ui->btn_allNum->height()); ui->btn_marked->setGeometry(ui->btn_answered->x(), ui->btn_unanswered->y(), ui->btn_all->width(), ui->btn_all->height()); ui->btn_markedNum->setGeometry(ui->btn_answeredNum->x(), ui->btn_unansweredNum->y(), ui->btn_allNum->width(), ui->btn_allNum->height()); ui->label_HLine->setGeometry(ui->btn_all->x(), ui->btn_unanswered->y() + ui->btn_unanswered->height() + g_appInfoPtr->m_fRate*20, ui->widget_navigate->width() - ui->btn_all->x()*2, g_appInfoPtr->m_fRate*1 < 1 ? 1 : g_appInfoPtr->m_fRate*1); ui->lw_aw_questionList->setGeometry(0, ui->label_HLine->y(), ui->widget_navigate->width(), ui->widget_aw_face->y() - ui->label_HLine->y() - ui->label_HLine->height()); } void answerWidget::onGetExamById(CGetExamById getExamById) { if (getExamById.nCode == 200) { m_nRetryCount = 0; g_appInfoPtr->m_oExamInfo.nExamId = getExamById.nId; g_appInfoPtr->m_oExamInfo.sExamType = getExamById.sExamType; g_appInfoPtr->m_oExamInfo.nDuration = getExamById.nDuration; GetExamRecordPaperStruct(); } else { // if(getExamById.sMessage.isEmpty()) // { // ShowMsg(QString::fromLocal8Bit("获取考试信息出错"), g_appInfoPtr->m_pAnsBgWidget, MSG_ICON_TYPE::mit_error); // } // else // { // ShowMsg(getExamById.sMessage, g_appInfoPtr->m_pAnsBgWidget, MSG_ICON_TYPE::mit_error); // } if(++m_nRetryCount > 3) { //退出 exitExamTip(); } else { GetExamById(); } } } void answerWidget::onGetExamRecordPaperStruct(CGetExamRecordPaperStruct getExamRecordPaperStruct) { if (getExamRecordPaperStruct.nCode == 200) { m_nRetryCount = 0; m_vPaperGroupStruct.swap(getExamRecordPaperStruct.vPaperGroupStruct); int nSize = m_vPaperGroupStruct.size(); QString sQuestionId = ""; for (int i = 0; i < nSize; ++i) { CPaperGroupStruct &pgs = m_vPaperGroupStruct[i]; awQuestionNavigate *questionItem = new awQuestionNavigate(pgs); connect(questionItem, &awQuestionNavigate::showSubQuestion, this, [&](QString sQuestionId, int nOrder, bool bHasContent) { showQuestionByOrder(nOrder); /*if (bHasContent) { for (CQuestionStruct &qs : pgs.vQuestionStruct) { if (qs.sQuestionId == sQuestionId) { QString sGroupTitleText = QString::fromLocal8Bit("%1、%2 (共%3题)").arg(CCommonTools::Arab2Sinogram(pgs.nNumber)).arg(pgs.sGroupName).arg(pgs.nTotalSubquestion); QString sGroupProgressText = QString::fromLocal8Bit("完成进度(%1/%2)").arg(pgs.nAnsweredCount).arg(pgs.nTotalSubquestion); showSubQuestion(qs, nOrder, sGroupTitleText, sGroupProgressText); } } } else { getQuestionContent(sQuestionId, nOrder); } */ }); QListWidgetItem *pItem = new QListWidgetItem; ui->lw_aw_questionList->addItem(pItem); ui->lw_aw_questionList->setItemWidget(pItem, questionItem); int nHeight = questionItem->setUI(ui->lw_aw_questionList->width() - g_appInfoPtr->m_fRate*60); QSize size = pItem->sizeHint(); size.setHeight(nHeight); pItem->setSizeHint(size); } WeiXinAnswerEnabled(); } else { // if(getExamRecordPaperStruct.sMessage.isEmpty()) // { // ShowMsg(QString::fromLocal8Bit("获取考试结构出错"), g_appInfoPtr->m_pAnsBgWidget, MSG_ICON_TYPE::mit_error); // } // else // { // ShowMsg(getExamRecordPaperStruct.sMessage, g_appInfoPtr->m_pAnsBgWidget, MSG_ICON_TYPE::mit_error); // } if(++m_nRetryCount > 3) { //退出 exitExamTip(); } else { GetExamRecordPaperStruct(); } } } CAnsweredQuestion answerWidget::findQuestionByOrder(CFindExamQuestionList &feql, int nOrder) { for (int i = 0; i < feql.vAnsweredQuestion.size(); ++i) { if (feql.vAnsweredQuestion[i].nOrder == nOrder) { return feql.vAnsweredQuestion[i]; } } } void answerWidget::onFindExamQuestionList(CFindExamQuestionList findExamQuestionList) { if (findExamQuestionList.nCode == 200) { m_nRetryCount = 0; int nTotal = 0; int nAnswered = 0; int nMarked = 0; int nSize = m_vPaperGroupStruct.size(); for (int i = 0; i < nSize; ++i) { int nQuestionSize = m_vPaperGroupStruct[i].vQuestionStruct.size(); for (int j = 0; j < nQuestionSize; ++j) { int nSubQuestionSize = m_vPaperGroupStruct[i].vQuestionStruct[j].vSubQuestionStruct.size(); for (int k = 0; k < nSubQuestionSize; ++k) { nTotal++; int nOrder = m_vPaperGroupStruct[i].vQuestionStruct[j].vSubQuestionStruct[k].nOrder; CAnsweredQuestion aq= findQuestionByOrder(findExamQuestionList, nOrder); m_vPaperGroupStruct[i].vQuestionStruct[j].vSubQuestionStruct[k].bAnswered = aq.bIsAnswer; m_vPaperGroupStruct[i].vQuestionStruct[j].vSubQuestionStruct[k].bMarked = aq.bIsSign; m_vPaperGroupStruct[i].vQuestionStruct[j].vSubQuestionStruct[k].sStudentAnswer = aq.sStudentAnswer; if(!aq.sStudentAnswer.isEmpty() && (aq.sQuestionType == QUESTION_TYPE::SingleChoice || aq.sQuestionType == QUESTION_TYPE::MultipleChoice || aq.sQuestionType == QUESTION_TYPE::TrueOrFalse)) { Json::Reader reader; Json::Value jAnswer = Json::Value::null; if (!reader.parse(aq.sStudentAnswer.toStdString(), jAnswer)) { // ShowMsg(QString::fromLocal8Bit("解析题干出错!"), g_appInfoPtr->m_answerWidget); myDebug() << QString::fromLocal8Bit("解析答案出错!"); } QString sAnswer = ""; int nSize = jAnswer["sections"].size(); for(int i = 0; i < nSize; ++i) { int bSize = jAnswer["sections"][i]["blocks"].size(); for(int j = 0; j < bSize; ++j) { if(jAnswer["sections"][i]["blocks"][j]["type"] == "text") { sAnswer += jAnswer["sections"][i]["blocks"][j]["value"].asString().c_str(); } } } m_vPaperGroupStruct[i].vQuestionStruct[j].vSubQuestionStruct[k].sStudentAnswer = sAnswer; } if (aq.bIsAnswer) { nAnswered++; } if (aq.bIsSign) { nMarked++; } if (!aq.sAudioPlayTimes.isEmpty()) { Json::Reader reader; Json::Value jAudioPlayTimes = Json::Value::null; if (reader.parse(aq.sAudioPlayTimes.toStdString(), jAudioPlayTimes)) { for (int ja = 0; ja < jAudioPlayTimes.size(); ++ja) { Json::Value jAudioPlayItem = jAudioPlayTimes[ja]; g_appInfoPtr->m_jAudioPlayedCount[jAudioPlayItem["name"].asString()] = jAudioPlayItem["times"].asInt(); } } } } } } showQuestionByOrder(1); on_btn_all_clicked(); ui->btn_allNum->setText(QString::number(nTotal)); ui->btn_answeredNum->setText(QString::number(nAnswered)); ui->btn_markedNum->setText(QString::number(nMarked)); ui->btn_unansweredNum->setText(QString::number(nTotal - nAnswered)); ui->pgb_answerProgress->setMaximum(nTotal); ui->pgb_answerProgress->setValue(nAnswered); refreshStatus(); //开始答题 startAnwer(); } else { // if(findExamQuestionList.sMessage.isEmpty()) // { // ShowMsg(QString::fromLocal8Bit("获取题目信息出错"), g_appInfoPtr->m_pAnsBgWidget, MSG_ICON_TYPE::mit_error); // } // else // { // ShowMsg(findExamQuestionList.sMessage, g_appInfoPtr->m_pAnsBgWidget, MSG_ICON_TYPE::mit_error); // } if(++m_nRetryCount > 3) { //退出 exitExamTip(); } else { FindExamQuestionList(); } } } void answerWidget::startAnwer() { CHttpRequestPackage hrp1; hrp1.sUri = "/api/ecs_oe_student/client/exam/process/startAnswer"; hrp1.sParamList.push_back(QString("examRecordDataId,%1").arg(g_appInfoPtr->m_oExamInfo.nExamRecordDataId)); hrp1.nRequestType = RequestType::rtStartAnswer; hrp1.eParamType = HttpParamType::hptUrl; g_httpBllPtr->post(hrp1); } void answerWidget::onGetExamProperty(CGetExamProperty getExamProperty) { if (getExamProperty.nCode == 200) { m_nRetryCount = 0; if (getExamProperty.sType == "SNAPSHOT_INTERVAL,PRACTICE_TYPE,FREEZE_TIME") { m_nSnapshotInterval = getExamProperty.nSnapshotInterval; g_appInfoPtr->m_oExamInfo.sPracticeType = getExamProperty.sPracticeType; m_nFreezeTime = getExamProperty.nFreezeTime; } GetExamById(); } else { // if(getExamProperty.sMessage.isEmpty()) // { // ShowMsg(QString::fromLocal8Bit("获取考试信息出错"), g_appInfoPtr->m_pAnsBgWidget, MSG_ICON_TYPE::mit_error); // } // else // { // ShowMsg(getExamProperty.sMessage, g_appInfoPtr->m_pAnsBgWidget, MSG_ICON_TYPE::mit_error); // } if(++m_nRetryCount > 3) { //退出 exitExamTip(); } else { GetExamProperty(); } } } void answerWidget::onWeiXinAnswerEnabled(CWeiXinAnswerEnabled weiXinAnswerEnabled) { if (weiXinAnswerEnabled.nCode == 200) { m_nRetryCount = 0; g_appInfoPtr->m_bWeiXinAnswerEnabled = weiXinAnswerEnabled.bEnabled; FindExamQuestionList(); } else { // if(weiXinAnswerEnabled.sMessage.isEmpty()) // { // ShowMsg(QString::fromLocal8Bit("获取考试信息失败"), g_appInfoPtr->m_pAnsBgWidget, MSG_ICON_TYPE::mit_error); // } // else // { // ShowMsg(weiXinAnswerEnabled.sMessage, g_appInfoPtr->m_pAnsBgWidget, MSG_ICON_TYPE::mit_error); // } if(++m_nRetryCount > 3) { //退出 exitExamTip(); } else { WeiXinAnswerEnabled(); } } } void answerWidget::showSubQuestion(CQuestionStruct &qs, int nOrder, QString sTitle, QString sProgress) { if (qs.sBody.isEmpty()) { if (m_pQuestion != nullptr) { m_pQuestion.reset(); } if (m_pQuestionSet != nullptr) { m_pQuestionSet.reset(); } m_pQuestion = std::make_shared(qs, nOrder, ui->btn_allNum->text().toInt(), ui->widget_aw_answerBG); connect(m_pQuestion.get(), &question::uploadAnswer, this, [&](int nIndex, __int64 timeStamp, QString sAnswer){ uploadAnswer(nIndex, sAnswer); }); connect(m_pQuestion.get(), &question::questionAnswered, this, [&](bool bAnswered, int nIndex){ refreshStatus(); int nSize = m_vPaperGroupStruct.size(); for (int i = 0; i < nSize; ++i) { int nQuestionSize = m_vPaperGroupStruct[i].vQuestionStruct.size(); for (int j = 0; j < nQuestionSize; ++j) { int nSubQuestionSize = m_vPaperGroupStruct[i].vQuestionStruct[j].vSubQuestionStruct.size(); for (int k = 0; k < nSubQuestionSize; ++k) { CSubQuestionStruct sqs = m_vPaperGroupStruct[i].vQuestionStruct[j].vSubQuestionStruct[k]; if(sqs.nOrder == nIndex) { QString sGroupProgressText = QString::fromLocal8Bit("完成进度(%1/%2)").arg(m_vPaperGroupStruct[i].nAnsweredCount).arg(m_vPaperGroupStruct[i].nTotalSubquestion); m_pQuestion->setGroupInfo("", sGroupProgressText); break; } } } } }); connect(m_pQuestion.get(), &question::markedItem, this, [&](bool bMarked, int nIndex){ refreshStatus(); }); connect(m_pQuestion.get(), &question::previousQuestion, this, [&](int nOrder){ if(nOrder > 1) { showQuestionByOrder(nOrder - 1); } }); connect(m_pQuestion.get(), &question::nextQuestion, this, [&](int nOrder){ showQuestionByOrder(nOrder + 1); }); m_pQuestion->setGroupInfo(sTitle, sProgress); m_pQuestion->setUI(0, g_appInfoPtr->m_fRate * 86, ui->widget_aw_answerBG->width(), ui->widget_aw_answerBG->height() - g_appInfoPtr->m_fRate * (86 + 20)); m_pQuestion->show(); } else { if (m_pQuestion != nullptr) { m_pQuestion.reset(); } if (m_pQuestionSet != nullptr) { m_pQuestionSet.reset(); } m_pQuestionSet = std::make_shared(qs, nOrder, ui->btn_allNum->text().toInt(), ui->widget_aw_answerBG); connect(m_pQuestionSet.get(), &questionSet::uploadAnswer, this, [&](int nIndex, __int64 timeStamp, QString sAnswer){ uploadAnswer(nIndex, sAnswer); }); connect(m_pQuestionSet.get(), &questionSet::questionAnswered, this, [&](bool bAnswered, int nIndex){ refreshStatus(); int nSize = m_vPaperGroupStruct.size(); for (int i = 0; i < nSize; ++i) { int nQuestionSize = m_vPaperGroupStruct[i].vQuestionStruct.size(); for (int j = 0; j < nQuestionSize; ++j) { int nSubQuestionSize = m_vPaperGroupStruct[i].vQuestionStruct[j].vSubQuestionStruct.size(); for (int k = 0; k < nSubQuestionSize; ++k) { CSubQuestionStruct sqs = m_vPaperGroupStruct[i].vQuestionStruct[j].vSubQuestionStruct[k]; if(sqs.nOrder == nIndex) { QString sGroupProgressText = QString::fromLocal8Bit("完成进度(%1/%2)").arg(m_vPaperGroupStruct[i].nAnsweredCount).arg(m_vPaperGroupStruct[i].nTotalSubquestion); m_pQuestionSet->setGroupInfo("", sGroupProgressText); break; } } } } }); connect(m_pQuestionSet.get(), &questionSet::markedItem, this, [&](bool bMarked, int nIndex){ refreshStatus(); }); connect(m_pQuestionSet.get(), &questionSet::previousQuestion, this, [&](int nOrder){ if(nOrder > 1) { showQuestionByOrder(nOrder - 1); } }); connect(m_pQuestionSet.get(), &questionSet::nextQuestion, this, [&](int nOrder){ showQuestionByOrder(nOrder + 1); }); m_pQuestionSet->setGroupInfo(sTitle, sProgress); m_pQuestionSet->setUI(0, g_appInfoPtr->m_fRate * 86, ui->widget_aw_answerBG->width(), ui->widget_aw_answerBG->height() - g_appInfoPtr->m_fRate * (86 + 20)); m_pQuestionSet->show(); } } void answerWidget::refreshStatus() { int nCount = ui->lw_aw_questionList->count(); for(int i = 0; i < nCount; ++i) { awQuestionNavigate *questionItem = dynamic_cast(ui->lw_aw_questionList->itemWidget(ui->lw_aw_questionList->item(i))); if(questionItem) { questionItem->refreshStatus(); } } int nTotal = 0; int nAnswered = 0; int nMarked = 0; int nSize = m_vPaperGroupStruct.size(); for (int i = 0; i < nSize; ++i) { int nQuestionSize = m_vPaperGroupStruct[i].vQuestionStruct.size(); int nAnswerCount = 0; for (int j = 0; j < nQuestionSize; ++j) { int nSubQuestionSize = m_vPaperGroupStruct[i].vQuestionStruct[j].vSubQuestionStruct.size(); for (int k = 0; k < nSubQuestionSize; ++k) { CSubQuestionStruct sqs = m_vPaperGroupStruct[i].vQuestionStruct[j].vSubQuestionStruct[k]; nTotal++; if (sqs.bAnswered) { nAnswerCount++; nAnswered++; } if (sqs.bMarked) { nMarked++; } } } m_vPaperGroupStruct[i].nAnsweredCount = nAnswerCount; } ui->btn_allNum->setText(QString::number(nTotal)); ui->btn_answeredNum->setText(QString::number(nAnswered)); ui->btn_markedNum->setText(QString::number(nMarked)); ui->btn_unansweredNum->setText(QString::number(nTotal - nAnswered)); ui->pgb_answerProgress->setMaximum(nTotal); ui->pgb_answerProgress->setValue(nAnswered); } void answerWidget::showQuestionByOrder(int nOrder) { int nSize = m_vPaperGroupStruct.size(); for (int i = 0; i < nSize; ++i) { int nQuestionSize = m_vPaperGroupStruct[i].vQuestionStruct.size(); for (int j = 0; j < nQuestionSize; ++j) { int nSubQuestionSize = m_vPaperGroupStruct[i].vQuestionStruct[j].vSubQuestionStruct.size(); bool bHasContent = m_vPaperGroupStruct[i].vQuestionStruct[j].bHasContent; for (int k = 0; k < nSubQuestionSize; ++k) { CSubQuestionStruct &sqs = m_vPaperGroupStruct[i].vQuestionStruct[j].vSubQuestionStruct[k]; sqs.bCurrent = false; if(sqs.nOrder == nOrder) { sqs.bCurrent = true; if (bHasContent) { QString sGroupTitleText = QString::fromLocal8Bit("%1、%2 (共%3题)").arg(CCommonTools::Arab2Sinogram(m_vPaperGroupStruct[i].nNumber)).arg(m_vPaperGroupStruct[i].sGroupName).arg(m_vPaperGroupStruct[i].nTotalSubquestion); QString sGroupProgressText = QString::fromLocal8Bit("完成进度(%1/%2)").arg(m_vPaperGroupStruct[i].nAnsweredCount).arg(m_vPaperGroupStruct[i].nTotalSubquestion); showSubQuestion(m_vPaperGroupStruct[i].vQuestionStruct[j], nOrder, sGroupTitleText, sGroupProgressText); } else { getQuestionContent(m_vPaperGroupStruct[i].vQuestionStruct[j].sQuestionId, nOrder); } } } } } refreshStatus(); } void answerWidget::uploadAnswer(int nIndex, QString sAnswer) { int nSize = m_vPaperGroupStruct.size(); for (int i = 0; i < nSize; ++i) { int nQuestionSize = m_vPaperGroupStruct[i].vQuestionStruct.size(); for (int j = 0; j < nQuestionSize; ++j) { int nSubQuestionSize = m_vPaperGroupStruct[i].vQuestionStruct[j].vSubQuestionStruct.size(); for (int k = 0; k < nSubQuestionSize; ++k) { CSubQuestionStruct sqs = m_vPaperGroupStruct[i].vQuestionStruct[j].vSubQuestionStruct[k]; if(!sqs.bUpload) { CHttpRequestPackage hrp; hrp.sUri = QString("/api/ecs_oe_student/client/exam/process/submitQuestionAnswer"); hrp.nRequestType = RequestType::rtSubmitQuestionAnswer; hrp.eParamType = HttpParamType::hptCustomBody; hrp.sParamList.push_back(QString("CustomBody,%1").arg(sAnswer)); hrp.sCommonStr = QString("%1,%2").arg(sqs.nOrder).arg(sqs.nVersion); g_httpBllPtr->post(hrp); } } } } } void answerWidget::onSubmitQuestionAnswer(CSubmitQuestionAnswer submitQuestionAnswer) { if(submitQuestionAnswer.nCode == 200) { int nSize = m_vPaperGroupStruct.size(); for (int i = 0; i < nSize; ++i) { int nQuestionSize = m_vPaperGroupStruct[i].vQuestionStruct.size(); for (int j = 0; j < nQuestionSize; ++j) { int nSubQuestionSize = m_vPaperGroupStruct[i].vQuestionStruct[j].vSubQuestionStruct.size(); for (int k = 0; k < nSubQuestionSize; ++k) { CSubQuestionStruct &sqs = m_vPaperGroupStruct[i].vQuestionStruct[j].vSubQuestionStruct[k]; if(sqs.nOrder == submitQuestionAnswer.nOrder && submitQuestionAnswer.nVersion >= sqs.nVersion) { sqs.bUpload = true; break; } } } } } else { if(submitQuestionAnswer.sMessage.isEmpty()) { ShowMsg(QString::fromLocal8Bit("提交答案失败"), g_appInfoPtr->m_pAnsBgWidget, MSG_ICON_TYPE::mit_error); } else { ShowMsg(submitQuestionAnswer.sMessage, g_appInfoPtr->m_pAnsBgWidget, MSG_ICON_TYPE::mit_error); } } } void answerWidget::getQuestionContent(QString sQuestionId, int nOrder) { CHttpRequestPackage hrp; hrp.sUri = QString("/api/ecs_oe_student/client/exam/process/getQuestionContent") .arg(g_appInfoPtr->m_oExamInfo.nExamId); hrp.nRequestType = RequestType::rtGetQuestionContent; hrp.eParamType = HttpParamType::hptUrl; hrp.sCommonStr = sQuestionId + "," + QString::number(nOrder); hrp.sParamList.push_back(QString("questionId,%1").arg(sQuestionId)); g_httpBllPtr->post(hrp); } void answerWidget::onGetQuestionContent(CGetQuestionContent getQuestionContent) { if (getQuestionContent.nCode == 200) { for (CPaperGroupStruct &pgs : m_vPaperGroupStruct) { for (CQuestionStruct &qs : pgs.vQuestionStruct) { if (qs.sQuestionId == getQuestionContent.sQuestionId) { qs.sBody = getQuestionContent.sBody; qs.sVersion = getQuestionContent.sVersion; qs.bhasAudios = getQuestionContent.bhasAudios; for (int i = 0; i < getQuestionContent.vSubQuestion.size(); ++i) { CSubQuestion sq = getQuestionContent.vSubQuestion[i]; qs.vSubQuestionStruct[i].sBody = sq.sBody; qs.vSubQuestionStruct[i].vRightAnswer.swap(sq.vRightAnswer); qs.vSubQuestionStruct[i].vOptions.swap(sq.vOptions); } QString sGroupTitleText = QString::fromLocal8Bit("%1、%2 (共%3题)").arg(CCommonTools::Arab2Sinogram(pgs.nNumber)).arg(pgs.sGroupName).arg(pgs.nTotalSubquestion); QString sGroupProgressText = QString::fromLocal8Bit("完成进度(%1/%2)").arg(pgs.nAnsweredCount).arg(pgs.nTotalSubquestion); showSubQuestion(qs, getQuestionContent.sOrder.toInt(), sGroupTitleText, sGroupProgressText); break; } } } } else { if(getQuestionContent.sMessage.isEmpty()) { ShowMsg(QString::fromLocal8Bit("获取题目内容失败"), g_appInfoPtr->m_pAnsBgWidget, MSG_ICON_TYPE::mit_error); } else { ShowMsg(getQuestionContent.sMessage, g_appInfoPtr->m_pAnsBgWidget, MSG_ICON_TYPE::mit_error); } } } void answerWidget::onStartAnswer(CStartAnswer startAnswer) { if(startAnswer.nCode == 200) { m_nRetryCount = 0; m_nUsedExamSeconds = startAnswer.nUsedExamSeconds; m_pHeartbeatTimer->start(); heartBreat(); //获取活体参数 if (g_appInfoPtr->m_oExamInfo.bLivenessCheck) { StartFaceLiveVerify(); // GetOrgPropertiesByGroupWithoutCache(); // CHttpRequestPackage hrp; // hrp.sUri = QString("/api/ecs_core/org/getOrgPropertiesByGroupWithoutCache/%1/config4Edit1") // .arg(g_appInfoPtr->m_sRootOrgId); // hrp.nRequestType = RequestType::rtGetOrgPropertiesByGroupWithoutCache; // g_httpBllPtr->get(hrp); { // CHttpRequestPackage hrp; // hrp.sUri = QString("/api/ecs_oe_student/client/exam/process/startFaceLiveVerify") // .arg(g_appInfoPtr->m_sRootOrgId); // hrp.nRequestType = RequestType::rtStartFaceLiveVerify; // hrp.sParamList.push_back(QString("examRecordDataId,%1").arg(g_appInfoPtr->m_oExamInfo.nExamRecordDataId)); // hrp.eParamType = HttpParamType::hptUrl; // g_httpBllPtr->post(hrp); } } } else { // if(startAnswer.sMessage.isEmpty()) // { // ShowMsg(QString::fromLocal8Bit("开始作答失败"), g_appInfoPtr->m_pAnsBgWidget, MSG_ICON_TYPE::mit_error); // } // else // { // ShowMsg(startAnswer.sMessage, g_appInfoPtr->m_pAnsBgWidget, MSG_ICON_TYPE::mit_error); // } if(++m_nRetryCount > 3) { //退出 exitExamTip(); } else { startAnwer(); } } } void answerWidget::GetOrgPropertiesByGroupWithoutCache() { CHttpRequestPackage hrp; hrp.sUri = QString("/api/ecs_core/org/getOrgPropertiesByGroupWithoutCache/%1/config4Edit1") .arg(g_appInfoPtr->m_sRootOrgId); hrp.nRequestType = RequestType::rtGetOrgPropertiesByGroupWithoutCache; g_httpBllPtr->get(hrp); } void answerWidget::onGetOrgPropertiesByGroupWithoutCache(CGetOrgPropertiesByGroupWithoutCache orgProperties) { if(orgProperties.nCode == 200) { m_nRetryCount = 0; g_appInfoPtr->m_oExamInfo.nActionNum = orgProperties.nActionNum; g_appInfoPtr->m_oExamInfo.sActionOptions = orgProperties.sActionOptions; g_appInfoPtr->m_oExamInfo.sActionOrder = orgProperties.sActionOrder; g_appInfoPtr->m_oExamInfo.nActionDuration = orgProperties.nActionDuration; g_appInfoPtr->m_oExamInfo.nActionAlert = orgProperties.nActionAlert; StartFaceLiveVerify(); } else { // if(orgProperties.sMessage.isEmpty()) // { // ShowMsg(QString::fromLocal8Bit("获取考试信息失败"), g_appInfoPtr->m_pAnsBgWidget, MSG_ICON_TYPE::mit_error); // } // else // { // ShowMsg(orgProperties.sMessage, g_appInfoPtr->m_pAnsBgWidget, MSG_ICON_TYPE::mit_error); // } if(++m_nRetryCount > 3) { //退出 exitExamTip(); } else { GetOrgPropertiesByGroupWithoutCache(); } } } void answerWidget::StartFaceLiveVerify() { CHttpRequestPackage hrp; hrp.sUri = QString("/api/ecs_oe_student/client/exam/process/startFaceLiveVerify") .arg(g_appInfoPtr->m_sRootOrgId); hrp.nRequestType = RequestType::rtStartFaceLiveVerify; hrp.sParamList.push_back(QString("examRecordDataId,%1").arg(g_appInfoPtr->m_oExamInfo.nExamRecordDataId)); hrp.eParamType = HttpParamType::hptUrl; g_httpBllPtr->post(hrp); } void answerWidget::onStartFaceLiveVerify(CStartFaceLiveVerify startFaceLiveVerify) { if(startFaceLiveVerify.nCode == 200) { m_nRetryCount = 0; g_appInfoPtr->m_oExamInfo.nFaceLiveVerifyId = startFaceLiveVerify.nFaceLiveVerifyId; g_appInfoPtr->m_oExamInfo.nFaceVerifyTimes = startFaceLiveVerify.nTimes; g_appInfoPtr->m_oExamInfo.nFaceVerifyDoMinute = startFaceLiveVerify.nStartMinute; bShowLivenessTip = true; } else { // if(startFaceLiveVerify.sMessage.isEmpty()) // { // ShowMsg(QString::fromLocal8Bit("开启活体验证失败"), g_appInfoPtr->m_pAnsBgWidget, MSG_ICON_TYPE::mit_error); // } // else // { // ShowMsg(startFaceLiveVerify.sMessage, g_appInfoPtr->m_pAnsBgWidget, MSG_ICON_TYPE::mit_error); // } if(++m_nRetryCount > 3) { //退出 exitExamTip(); } else { StartFaceLiveVerify(); } } } void answerWidget::heartBreat() { CHttpRequestPackage hrp; hrp.sUri = QString("/api/ecs_oe_student/client/exam/process/examHeartbeat"); hrp.nRequestType = RequestType::rtExamHeartbeat; g_httpBllPtr->post(hrp); } void answerWidget::onExamHeartbeat(CExamHeartbeat examHeartbeat) { if (examHeartbeat.nCode == 200) { if(m_nHeartBreatFailedCount > 0) { //m_pHeartbeatTimer->stop(); m_pHeartbeatTimer->setInterval(60 * 1000); //m_pHeartbeatTimer->start(); m_nHeartBreatFailedCount = 0; } m_nLeftSeconds = examHeartbeat.nLeftTime/1000; if(m_nEnterExamTime == 0) { m_nEnterExamTime = m_nLeftSeconds; } m_pCountDownTimer->start(); //过程中人脸识别 if(g_appInfoPtr->m_oExamInfo.bFaceCheck) { if(g_inProcessFace == nullptr) { g_inProcessFace = std::make_shared(); connect(g_inProcessFace.get(), &CInprogressFace::compareFailed, this, [&](QString sErrorMsg){ ShowMsg(sErrorMsg, g_appInfoPtr->m_pAnsBgWidget); }); startCapture(); } m_nNextFaceCountSecond = m_nLeftSeconds - CCommonTools::genRandomNumber(1, 10); } } else { if(m_nHeartBreatFailedCount == 0) { // m_pHeartbeatTimer->stop(); m_pHeartbeatTimer->setInterval(10 * 1000); //m_pHeartbeatTimer->start(); } ++m_nHeartBreatFailedCount; if (m_nHeartBreatFailedCount >= m_nHeartBreatFailedExitCount) { exitExamTip(); //退出 // awTimeLeftTips *wExitExam = new awTimeLeftTips(MASK_POP_WIDGET_TYPE::wt_exitExam, (QWidget*)(this->parent())); // connect(wExitExam, &awTimeLeftTips::timeLeftConfirm, this, [this, wExitExam]() { // if (m_pNetWorkErrorTimerPtr) // { // m_pNetWorkErrorTimerPtr->stop(); // } // delete wExitExam; // emit gobackLogin(); // }); // wExitExam->show(); // if (m_pNetWorkErrorTimerPtr == nullptr) // { // m_pNetWorkErrorTimerPtr = std::make_shared(); // m_pNetWorkErrorTimerPtr->setInterval(30 * 1000); // connect(m_pNetWorkErrorTimerPtr.get(), &QTimer::timeout, [this, wExitExam]() { // m_pNetWorkErrorTimerPtr->stop(); // delete wExitExam; // emit gobackLogin(); // }); // } // m_pNetWorkErrorTimerPtr->start(); } if(examHeartbeat.sMessage.isEmpty()) { ShowMsg(QString::fromLocal8Bit("网络连接异常,请检查网络设置"), g_appInfoPtr->m_pAnsBgWidget, MSG_ICON_TYPE::mit_error); } else { ShowMsg(examHeartbeat.sMessage, g_appInfoPtr->m_pAnsBgWidget, MSG_ICON_TYPE::mit_error); } } } void answerWidget::exitExamTip() { //退出 awTimeLeftTips *wExitExam = new awTimeLeftTips(MASK_POP_WIDGET_TYPE::wt_exitExam, (QWidget*)(this->parent())); connect(wExitExam, &awTimeLeftTips::timeLeftConfirm, this, [this, wExitExam]() { if (m_pNetWorkErrorTimerPtr) { m_pNetWorkErrorTimerPtr->stop(); } delete wExitExam; emit gobackLogin(); }); wExitExam->show(); if (m_pNetWorkErrorTimerPtr == nullptr) { m_pNetWorkErrorTimerPtr = std::make_shared(); m_pNetWorkErrorTimerPtr->setInterval(30 * 1000); connect(m_pNetWorkErrorTimerPtr.get(), &QTimer::timeout, [this, wExitExam]() { m_pNetWorkErrorTimerPtr->stop(); delete wExitExam; emit gobackLogin(); }); } m_pNetWorkErrorTimerPtr->start(); } void answerWidget::on_btn_handInPaper_clicked() { if(m_nFreezeTime*60 > m_nUsedExamSeconds + m_nEnterExamTime - m_nLeftSeconds) { ShowMsg(QString::fromLocal8Bit("冻结时间内不允许交卷"), this, MSG_ICON_TYPE::mit_error); return; } if(m_pHandinPaper == nullptr) { m_pHandinPaper = std::make_shared(ui->btn_answeredNum->text().toInt(), ui->btn_unansweredNum->text().toInt(), ui->btn_markedNum->text().toInt(), (QWidget*)(this->parent())); connect(m_pHandinPaper.get(), &awHandinPaper::handinPaper, this, [&](){ m_pHandinPaper.reset(); //交卷 handinPaper(); }); connect(m_pHandinPaper.get(), &awHandinPaper::cancelHandinPaper, this, [&](){ m_pHandinPaper.reset(); }); } m_pHandinPaper->show(); } bool answerWidget::checkAnswer() { bool bRet = true; int nSize = m_vPaperGroupStruct.size(); for (int i = 0; i < nSize; ++i) { int nQuestionSize = m_vPaperGroupStruct[i].vQuestionStruct.size(); for (int j = 0; j < nQuestionSize; ++j) { int nSubQuestionSize = m_vPaperGroupStruct[i].vQuestionStruct[j].vSubQuestionStruct.size(); for (int k = 0; k < nSubQuestionSize; ++k) { CSubQuestionStruct sqs = m_vPaperGroupStruct[i].vQuestionStruct[j].vSubQuestionStruct[k]; if (!sqs.bUpload) { bRet = false; CHttpRequestPackage hrp; hrp.sUri = QString("/api/ecs_oe_student/client/exam/process/submitQuestionAnswer"); hrp.nRequestType = RequestType::rtSubmitQuestionAnswer; hrp.eParamType = HttpParamType::hptCustomBody; hrp.sParamList.push_back(QString("CustomBody,%1").arg(sqs.sUploadAnswer)); hrp.sCommonStr = QString("%1,%2").arg(sqs.nOrder).arg(sqs.nVersion); g_httpBllPtr->post(hrp); } } } } return bRet; } void answerWidget::handinPaper(bool bForce) { m_pCountDownTimer->stop(); if(g_appInfoPtr->m_oExamInfo.bFaceCheck) { stopCapture(); } if(g_inProcessFace != nullptr) { stopCapture(); g_inProcessFace.reset(); } if(m_pResumeExam == nullptr) { m_pResumeExam = std::make_shared((QWidget*)(this->parent()), QString::fromLocal8Bit("交卷中请稍候…")); } m_pResumeExam->show(); if (checkAnswer()) { // CHttpRequestPackage hrp; // hrp.sUri = QString("/api/ecs_oe_student/client/exam/process/endExam"); // hrp.sCommonStr = __FILE__; // hrp.nRequestType = RequestType::rtEndExam; // g_httpBllPtr->post(hrp); doEndExam(bForce); } else { if (m_pHandinPaperTimer == nullptr) { m_pHandinPaperTimer = std::make_shared(); m_pHandinPaperTimer->setInterval(10 * 1000); connect(m_pHandinPaperTimer.get(), &QTimer::timeout, this, [&]() { if (checkAnswer()) { m_pHandinPaperTimer->stop(); doEndExam(bForce); // CHttpRequestPackage hrp; // hrp.sUri = QString("/api/ecs_oe_student/client/exam/process/endExam"); // hrp.sCommonStr = __FILE__; // hrp.nRequestType = RequestType::rtEndExam; // g_httpBllPtr->post(hrp); } }); } } } void answerWidget::doEndExam(bool bForce) { CHttpRequestPackage hrp; hrp.sUri = QString("/api/ecs_oe_student/client/exam/process/endExam"); if(bForce) { hrp.sParamList.push_back(QString("force,%1").arg(bForce)); hrp.eParamType = HttpParamType::hptUrl; } hrp.sCommonStr = __FILE__; hrp.sAdditionStr = bForce ? "1" : "0"; hrp.nRequestType = RequestType::rtEndExam; g_httpBllPtr->post(hrp); } void answerWidget::onEndExam(CEndExam endExam) { if(endExam.sModuleName == __FILE__) { if (endExam.nCode == 200) { m_pHeartbeatTimer->stop(); m_pResumeExam.reset(); if (g_appInfoPtr->m_oExamInfo.sExamType == EXAM_TYPES::PRACTICE) { if(g_appInfoPtr->m_oExamInfo.sPracticeType != "NO_ANSWER") { emit showPracticeInfo(); } else { emit gobackCourseList(); } } else { emit showExamScore(); } } else { QTimer::singleShot(5*1000, this, [&](){ // CHttpRequestPackage hrp; // hrp.sUri = QString("/api/ecs_oe_student/client/exam/process/endExam"); // hrp.sCommonStr = __FILE__; // hrp.nRequestType = RequestType::rtEndExam; // g_httpBllPtr->post(hrp); doEndExam(endExam.bForce); }); } } } void answerWidget::on_btn_all_clicked() { int nCount = ui->lw_aw_questionList->count(); for(int i = 0; i < nCount; ++i) { awQuestionNavigate *questionItem = dynamic_cast(ui->lw_aw_questionList->itemWidget(ui->lw_aw_questionList->item(i))); if(questionItem) { int nHeight = questionItem->setShowType(ITEM_SHOW_TYPE::ist_showAll); QListWidgetItem *listItem = ui->lw_aw_questionList->item(i); if(listItem) { QSize size = listItem->sizeHint(); size.setHeight(nHeight); listItem->setSizeHint(size); } } } setChecked(ui->btn_all, true); setChecked(ui->btn_marked, false); setChecked(ui->btn_answered, false); setChecked(ui->btn_unanswered, false); } void answerWidget::setChecked(QPushButton *btn, bool bChecked) { QString sNormal = QString(R"(QPushButton { outline:none; background:rgba(242,243,247,1); border-radius:%1px; border:1px solid rgba(240,244,249,1); font-size:%2px; font-family:"Microsoft YaHei"; font-weight:500; color:rgba(153,153,153,1); padding-left:%3px; text-align:left; })").arg((int)(g_appInfoPtr->m_fRate*14)) .arg((int)(g_appInfoPtr->m_fRate*12)) .arg((int)(g_appInfoPtr->m_fRate*15)); QString sChecked = QString(R"(QPushButton { outline:none; background:rgba(242,243,247,1); border-radius:%1px; border:1px solid rgba(189,200,217,1); font-size:%2px; font-family:"Microsoft YaHei"; font-weight:500; color:rgba(153,153,153,1); padding-left:%3px; text-align:left; })").arg((int)(g_appInfoPtr->m_fRate*14)) .arg((int)(g_appInfoPtr->m_fRate*12)) .arg((int)(g_appInfoPtr->m_fRate*15)); btn->setStyleSheet(bChecked ? sChecked : sNormal); } void answerWidget::on_btn_answered_clicked() { int nCount = ui->lw_aw_questionList->count(); for(int i = 0; i < nCount; ++i) { awQuestionNavigate *questionItem = dynamic_cast(ui->lw_aw_questionList->itemWidget(ui->lw_aw_questionList->item(i))); if(questionItem) { int nHeight = questionItem->setShowType(ITEM_SHOW_TYPE::ist_showAnswered); QListWidgetItem *listItem = ui->lw_aw_questionList->item(i); if(listItem) { QSize size = listItem->sizeHint(); size.setHeight(nHeight); listItem->setSizeHint(size); } } } setChecked(ui->btn_all, false); setChecked(ui->btn_marked, false); setChecked(ui->btn_answered, true); setChecked(ui->btn_unanswered, false); } void answerWidget::on_btn_unanswered_clicked() { int nCount = ui->lw_aw_questionList->count(); for(int i = 0; i < nCount; ++i) { awQuestionNavigate *questionItem = dynamic_cast(ui->lw_aw_questionList->itemWidget(ui->lw_aw_questionList->item(i))); if(questionItem) { int nHeight = questionItem->setShowType(ITEM_SHOW_TYPE::ist_showUnanswered); QListWidgetItem *listItem = ui->lw_aw_questionList->item(i); if(listItem) { QSize size = listItem->sizeHint(); size.setHeight(nHeight); listItem->setSizeHint(size); } } } setChecked(ui->btn_all, false); setChecked(ui->btn_marked, false); setChecked(ui->btn_answered, false); setChecked(ui->btn_unanswered, true); } void answerWidget::on_btn_marked_clicked() { int nCount = ui->lw_aw_questionList->count(); for(int i = 0; i < nCount; ++i) { awQuestionNavigate *questionItem = dynamic_cast(ui->lw_aw_questionList->itemWidget(ui->lw_aw_questionList->item(i))); if(questionItem) { int nHeight = questionItem->setShowType(ITEM_SHOW_TYPE::ist_showMarked); QListWidgetItem *listItem = ui->lw_aw_questionList->item(i); if(listItem) { QSize size = listItem->sizeHint(); size.setHeight(nHeight); listItem->setSizeHint(size); } } } setChecked(ui->btn_all, false); setChecked(ui->btn_marked, true); setChecked(ui->btn_answered, false); setChecked(ui->btn_unanswered, false); } void answerWidget::on_btn_allNum_clicked() { on_btn_all_clicked(); } void answerWidget::on_btn_answeredNum_clicked() { on_btn_answered_clicked(); } void answerWidget::on_btn_unansweredNum_clicked() { on_btn_unanswered_clicked(); } void answerWidget::on_btn_markedNum_clicked() { on_btn_marked_clicked(); } void answerWidget::onRenderVideoFrame(const char* userId, TRTCVideoStreamType streamType, TRTCVideoFrame* frame) { if(g_clientVideoProcPtr->isCameraTest()) { __int64 nServerTime = g_appInfoPtr->serverMTime(); if(nServerTime - m_lastFaceTime >= 100) { m_lastFaceTime = nServerTime; cv::Mat matImg; cv::cvtColor(cv::Mat(frame->height, frame->width, CV_8UC4, frame->data), matImg, CV_RGBA2RGB); if(matImg.empty()) { qDebug()<<"widgetCameraTest frame is empty"; return; } std::scoped_lock lock(m_imageMutex); m_nCurImage = matImg; } } } void answerWidget::startCapture() { // if(m_pinitTimer == nullptr) // { // m_pinitTimer = std::make_shared(); // m_pinitTimer->setInterval(1000); // connect(m_pinitTimer.get(), &QTimer::timeout, this, [&](){ // m_pinitTimer->stop(); // if(!m_cam.open(0)) // { // ShowMsg(QString::fromLocal8Bit("打开摄像头失败"), this, MSG_ICON_TYPE::mit_error); // return; // } // int inWidth = ui->widget_aw_face->width(); // m_cam.set(CV_CAP_PROP_FRAME_WIDTH, inWidth*3); // int inHeight = ui->widget_aw_face->height(); // m_cam.set(CV_CAP_PROP_FRAME_HEIGHT, inHeight*3); // m_cam.set(CV_CAP_PROP_FPS, 5); // m_pVideoTimer->start(); // }); // } g_clientVideoProcPtr->startTest(this); g_inProcessFace->startFaceVerify(true); if(m_pVideoTimer == nullptr) { m_pVideoTimer = std::make_shared(); m_pVideoTimer->setInterval(200); m_nLastCaptureSecond = m_nLeftSeconds; connect(m_pVideoTimer.get(), &QTimer::timeout, this, [&](){ cv::Mat frame; { std::scoped_lock lock(m_imageMutex); frame = m_nCurImage; } if(frame.empty()) { qDebug()<<"widgetCameraTest frame is empty"; return; } if (g_inProcessFace != nullptr && m_nLastCaptureSecond - m_nLeftSeconds > g_appInfoPtr->m_oExamInfo.nSnapshotInterval*60) { m_nLastCaptureSecond = m_nLeftSeconds; g_inProcessFace->addImage(frame); } if(g_inProcessFace != nullptr && m_nNextFaceCountSecond > m_nLeftSeconds) { m_nNextFaceCountSecond = m_nLeftSeconds - CCommonTools::genRandomNumber(1, 10); g_inProcessFace->addFaceCountImage(frame); } QImage img = CCommonTools::Mat2QImage(frame); ui->widget_aw_face->setAutoFillBackground(true); QPalette palette; palette.setBrush(QPalette::Window, QBrush(img.scaled(ui->widget_aw_face->width(), ui->widget_aw_face->height()))); ui->widget_aw_face->setPalette(palette); }); } m_pVideoTimer->start(); } void answerWidget::stopCapture() { m_pVideoTimer->stop(); g_inProcessFace->startFaceVerify(false); g_clientVideoProcPtr->stopTest(); // m_pVideoTimer->stop(); // if(m_cam.isOpened()) // { // m_cam.release(); // } }