wangyaojie 1 year ago
parent
commit
2308a31091

+ 67 - 3
client/answerWidget.cpp

@@ -251,9 +251,9 @@ 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");
+        .arg(g_appInfoPtr->m_oExamInfo.nExamId).arg("SNAPSHOT_INTERVAL,PRACTICE_TYPE,FREEZE_TIME,SHOW_MULTIPLE_CHOICE_WARNING");
     hrp.nRequestType = RequestType::rtGetExamProperty;
-    hrp.sCommonStr = "SNAPSHOT_INTERVAL,PRACTICE_TYPE,FREEZE_TIME";
+    hrp.sCommonStr = "SNAPSHOT_INTERVAL,PRACTICE_TYPE,FREEZE_TIME,SHOW_MULTIPLE_CHOICE_WARNING";
     g_httpBllPtr->get(hrp);
 }
 
@@ -688,11 +688,12 @@ void answerWidget::onGetExamProperty(CGetExamProperty getExamProperty)
 	if (getExamProperty.nCode == 200)
 	{
         m_nRetryCount = 0;
-		if (getExamProperty.sType == "SNAPSHOT_INTERVAL,PRACTICE_TYPE,FREEZE_TIME")
+        if (getExamProperty.sType == "SNAPSHOT_INTERVAL,PRACTICE_TYPE,FREEZE_TIME,SHOW_MULTIPLE_CHOICE_WARNING")
 		{
 			m_nSnapshotInterval = getExamProperty.nSnapshotInterval;
 			g_appInfoPtr->m_oExamInfo.sPracticeType = getExamProperty.sPracticeType;
 			m_nFreezeTime = getExamProperty.nFreezeTime;
+            g_appInfoPtr->m_bMutipleAnserCountTips = getExamProperty.bMutipleAnserCountTips;
 		}
 
         GetExamById();
@@ -928,6 +929,38 @@ void answerWidget::refreshStatus()
 void answerWidget::showQuestionByOrder(int nOrder)
 {
     int nSize = m_vPaperGroupStruct.size();
+    if(g_appInfoPtr->m_bMutipleAnserCountTips)
+    {
+        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];
+                    int n = sqs.sStudentAnswer.length();
+                    if (sqs.bCurrent && sqs.sQuestionType == QUESTION_TYPE::MultipleChoice && sqs.sStudentAnswer.length() < 2 && sqs.sStudentAnswer.length() > 0)
+                    {
+                        if(popMsg(QString::fromLocal8Bit("当前多选题所选答案不足2个,是否确认跳过?"), QString::fromLocal8Bit("系统提示"), this,
+                                  QString::fromLocal8Bit("跳过此题"), QString::fromLocal8Bit("继续作答")) != QDialog::Accepted)
+                        {
+
+                            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], sqs.nOrder, sGroupTitleText, sGroupProgressText);
+
+                            refreshStatus();
+                            return;
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+
     for (int i = 0; i < nSize; ++i)
     {
         int nQuestionSize = m_vPaperGroupStruct[i].vQuestionStruct.size();
@@ -1343,6 +1376,29 @@ void answerWidget::exitExamTip()
     m_pNetWorkErrorTimerPtr->start();
 }
 
+bool answerWidget::allMutipleQuestionHas2Answers()
+{
+    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.sQuestionType == QUESTION_TYPE::MultipleChoice && sqs.sStudentAnswer.length() < 2)
+                {
+                    return false;
+                }
+            }
+        }
+    }
+    return true;
+}
+
+
 void answerWidget::onExamControlCheckTime(CBaseResponsePackage res)
 {
     if(res.nCode == 200)
@@ -1363,6 +1419,14 @@ void answerWidget::onExamControlCheckTime(CBaseResponsePackage res)
                 m_pHandinPaper.reset();
             });
         }
+
+        if(g_appInfoPtr->m_bMutipleAnserCountTips)
+        {
+            if(!allMutipleQuestionHas2Answers())
+            {
+                m_pHandinPaper->showMutipleChoiceTip();
+            }
+        }
         m_pHandinPaper->show();
     }
     else

+ 1 - 0
client/answerWidget.h

@@ -92,6 +92,7 @@ private:
     void onRenderVideoFrame(const char* userId, TRTCVideoStreamType streamType, TRTCVideoFrame* frame);
 	void checkRemoteBreach();
     void setChecked(QPushButton *btn, bool bChecked);
+    bool allMutipleQuestionHas2Answers();
 
     Ui::answerWidget *ui;
 	

+ 44 - 4
client/awBackground.cpp

@@ -49,10 +49,50 @@ awBackground::~awBackground()
 void awBackground::initUI()
 {
     ui->label_cl_company->setVisible(false);
-	//ui->label_awbg_exam->setText(QString::fromLocal8Bit("%1(%2)").arg().arg());
-	ui->label_awbg_student->setText(QString::fromLocal8Bit("%1 | %2 | %3 | %4")
-		.arg(g_appInfoPtr->m_sStudentName).arg(g_appInfoPtr->m_sStudentCode)
-        .arg(g_appInfoPtr->m_sStudentIdentityNumber).arg(g_appInfoPtr->m_sOrgName));
+    QString sStudentInfo = "";
+    if(g_appInfoPtr->m_bShowStudentName)
+    {
+        sStudentInfo = g_appInfoPtr->m_sStudentName;
+    }
+
+    if(g_appInfoPtr->m_bShowStudentCode)
+    {
+        if(sStudentInfo.isEmpty())
+        {
+            sStudentInfo = g_appInfoPtr->m_sStudentCode;
+        }
+        else
+        {
+            sStudentInfo = QString::fromLocal8Bit("%1 | %2").arg(sStudentInfo).arg(g_appInfoPtr->m_sStudentCode);
+        }
+    }
+
+    if(g_appInfoPtr->m_bShowStudentIdentity)
+    {
+        if(sStudentInfo.isEmpty())
+        {
+            sStudentInfo = g_appInfoPtr->m_sStudentIdentityNumber;
+        }
+        else
+        {
+            sStudentInfo = QString::fromLocal8Bit("%1 | %2").arg(sStudentInfo).arg(g_appInfoPtr->m_sStudentIdentityNumber);
+        }
+    }
+
+    if(sStudentInfo.isEmpty())
+    {
+        sStudentInfo = g_appInfoPtr->m_sOrgName;
+    }
+    else
+    {
+        sStudentInfo = QString::fromLocal8Bit("%1 | %2").arg(sStudentInfo).arg(g_appInfoPtr->m_sOrgName);
+    }
+
+    ui->label_awbg_student->setText(sStudentInfo);
+
+//	ui->label_awbg_student->setText(QString::fromLocal8Bit("%1 | %2 | %3 | %4")
+//		.arg(g_appInfoPtr->m_sStudentName).arg(g_appInfoPtr->m_sStudentCode)
+//        .arg(g_appInfoPtr->m_sStudentIdentityNumber).arg(g_appInfoPtr->m_sOrgName));
     QDesktopWidget *dekwiget = QApplication::desktop();
     setGeometry(0, 0, dekwiget->width(), dekwiget->height());
     ui->widget_awbg_BG->setGeometry(0, 0, width(), height());

+ 10 - 2
client/awHandinPaper.cpp

@@ -30,8 +30,8 @@ void awHandinPaper::initUI()
     QDesktopWidget *dekwiget = QApplication::desktop();
     setGeometry(0, 0, dekwiget->width(), dekwiget->height());
     ui->widget_mask->setGeometry(0, 0, dekwiget->width(), dekwiget->height());
-    ui->widget_awhp_BG->setGeometry((width() - g_appInfoPtr->m_fRate*420)/2, (height() - g_appInfoPtr->m_fRate*227)/2,
-                                   g_appInfoPtr->m_fRate*420, g_appInfoPtr->m_fRate*227);
+    ui->widget_awhp_BG->setGeometry((width() - g_appInfoPtr->m_fRate*480)/2, (height() - g_appInfoPtr->m_fRate*227)/2,
+                                   g_appInfoPtr->m_fRate*480, g_appInfoPtr->m_fRate*227);
     ui->label_awhp_icon->setGeometry(g_appInfoPtr->m_fRate*30, g_appInfoPtr->m_fRate*30,
                                     g_appInfoPtr->m_fRate*40, g_appInfoPtr->m_fRate*40);
     ui->label_awhp_title->adjustSize();
@@ -46,12 +46,20 @@ void awHandinPaper::initUI()
     ui->label_awhp_marked->adjustSize();
     ui->label_awhp_marked->setGeometry(ui->label_awhp_unanswered->x(), ui->label_awhp_unanswered->y() + ui->label_awhp_unanswered->height() + g_appInfoPtr->m_fRate*5,
                                        ui->label_awhp_marked->width(), ui->label_awhp_marked->height());
+    ui->label_multipleChoiceTips->adjustSize();
+    ui->label_multipleChoiceTips->setGeometry(ui->label_awhp_unanswered->x(), ui->label_awhp_marked->y() + ui->label_awhp_marked->height() + g_appInfoPtr->m_fRate*15,
+                                       ui->label_multipleChoiceTips->width(), ui->label_multipleChoiceTips->height());
+    ui->label_multipleChoiceTips->setVisible(false);
     ui->btn_awhp_comfirm->setGeometry(ui->widget_awhp_BG->width() - g_appInfoPtr->m_fRate*(20 + 80),
                                       ui->widget_awhp_BG->height() - g_appInfoPtr->m_fRate*(20 + 30),
                                       g_appInfoPtr->m_fRate*80, g_appInfoPtr->m_fRate*30);
     ui->btn_awhp_cancel->setGeometry(ui->btn_awhp_comfirm->x() - g_appInfoPtr->m_fRate*10 - ui->btn_awhp_comfirm->width(), ui->btn_awhp_comfirm->y(),
                                      ui->btn_awhp_comfirm->width(), ui->btn_awhp_comfirm->height());
+}
 
+void awHandinPaper::showMutipleChoiceTip()
+{
+    ui->label_multipleChoiceTips->setVisible(true);
 }
 
 void awHandinPaper::on_btn_awhp_cancel_clicked()

+ 1 - 0
client/awHandinPaper.h

@@ -17,6 +17,7 @@ public:
     explicit awHandinPaper(int nAnswered, int nUnanswered, int nMarked, QWidget *parent = nullptr);
     ~awHandinPaper();
 
+    void showMutipleChoiceTip();
 
 private slots:
     void on_btn_awhp_cancel_clicked();

+ 18 - 5
client/awHandinPaper.ui

@@ -26,9 +26,9 @@
     <property name="geometry">
      <rect>
       <x>40</x>
-      <y>30</y>
+      <y>40</y>
       <width>321</width>
-      <height>221</height>
+      <height>271</height>
      </rect>
     </property>
     <widget class="QLabel" name="label_awhp_icon">
@@ -86,8 +86,8 @@
     <widget class="QPushButton" name="btn_awhp_comfirm">
      <property name="geometry">
       <rect>
-       <x>190</x>
-       <y>190</y>
+       <x>200</x>
+       <y>220</y>
        <width>75</width>
        <height>23</height>
       </rect>
@@ -113,7 +113,7 @@
      <property name="geometry">
       <rect>
        <x>100</x>
-       <y>190</y>
+       <y>220</y>
        <width>75</width>
        <height>23</height>
       </rect>
@@ -122,6 +122,19 @@
       <string>取消</string>
      </property>
     </widget>
+    <widget class="QLabel" name="label_multipleChoiceTips">
+     <property name="geometry">
+      <rect>
+       <x>50</x>
+       <y>180</y>
+       <width>301</width>
+       <height>16</height>
+      </rect>
+     </property>
+     <property name="text">
+      <string>提示:存在多选题答案勾选不足2个的试题</string>
+     </property>
+    </widget>
    </widget>
   </widget>
  </widget>

+ 22 - 0
client/client.qss

@@ -120,6 +120,14 @@ QWidget#widget_pmb_bg,#widget_wcw_BG,#widget_pw_BG,#widget_et_BG,#widget_awhp_BG
     border-radius:RATE_BASE_SIZE16px;
 }
 
+QWidget#widget_pmb_bg
+{
+    background:rgba(255, 255, 255, 1);
+    border-radius:RATE_BASE_SIZE12px;
+    border: 1px solid rgba(0, 0, 0, 0.08*255);
+}
+
+
 QLabel#label_pmb_icon,#label_awmb_icon
 {
     border-image:url(:/images/icon-um.png);
@@ -1012,6 +1020,11 @@ QLabel#label_fc_note
     color:rgba(102, 102, 102,1);
 }
 
+QLabel#label_faceRect
+{
+    border-image:url(:/images/img-face-mask.png);
+}
+
 QPushButton#btn_fc_compare
 {
     outline:none;
@@ -1387,6 +1400,15 @@ QLabel#label_awhp_answered,#label_awhp_unanswered,#label_awhp_marked
     color:rgba(102,102,102,1);
 }
 
+QLabel#label_multipleChoiceTips
+{
+    font-size:RATE_BASE_SIZE14px;
+    font-family:"Microsoft YaHei";
+    font-weight:400;
+    color:rgba(255,0,0,1);
+}
+
+
 QPushButton#btn_awhp_comfirm,#btn_awtlt_confirm
 {
     outline:none;

+ 16 - 12
client/courseList.cpp

@@ -18,6 +18,9 @@ courseList::courseList(QWidget *parent) :
 
 	setStyleSheet(g_appInfoPtr->m_sQssStr);
 
+    ui->btn_minisize->setVisible(!g_appInfoPtr->m_bFullScreenTop);
+
+
 	qRegisterMetaType<CGetStudentInfoBySession>("CGetStudentInfoBySession");
 	connect(g_httpBllPtr.get(), &CHttpBll::sgnGetStudentInfoBySession, this, &courseList::onGetStudentInfoBySession);
 	qRegisterMetaType<CSpecialtyNameList>("CSpecialtyNameList");
@@ -550,6 +553,7 @@ void courseList::onGetExamProperty(CGetExamProperty getExamProperty)
             g_appInfoPtr->m_oExamInfo.nFaceVerifyEndMinute = getExamProperty.nFaceVerifyEndMinute;
             g_appInfoPtr->m_oExamInfo.bIsStrangerEnable = getExamProperty.bIsStrangerEnable;
             g_appInfoPtr->m_oExamInfo.bIsLivenessBefore = getExamProperty.bIsLivenessBefore;
+
             if (getExamProperty.bCheckEnvironment && !g_appInfoPtr->m_oExamInfo.bIsExamInProgress)
 			{
                 if(m_pWhetherEnvTest == nullptr)
@@ -1176,12 +1180,7 @@ void courseList::onCheckExamInProgress(CCheckExamInProgress checkExamInProgress)
                 m_pResumeExam->show();
 
                 //环境监测
-                CHttpRequestPackage hrp;
-                hrp.sUri = QString("/api/ecs_exam_work/exam/getExamPropertyFromCacheByStudentSession/%1/%2")
-                    .arg(g_appInfoPtr->m_oExamInfo.nExamId).arg("CHECK_ENVIRONMENT,IS_FACE_CHECK,SNAPSHOT_INTERVAL,FACE_VERIFY_START_MINUTE,FACE_VERIFY_END_MINUTE,IS_STRANGER_ENABLE,IS_FACE_VERIFY_BEFORE");
-                hrp.nRequestType = RequestType::rtGetExamProperty;
-                hrp.sCommonStr = "CHECK_ENVIRONMENT,IS_FACE_CHECK,SNAPSHOT_INTERVAL,FACE_VERIFY_START_MINUTE,FACE_VERIFY_END_MINUTE,IS_STRANGER_ENABLE,IS_FACE_VERIFY_BEFORE";
-                g_httpBllPtr->get(hrp);
+                getExamProperty();
 
 			}
 		}
@@ -1209,12 +1208,7 @@ void courseList::onCheckExamInProgress(CCheckExamInProgress checkExamInProgress)
 			{
 
                 //环境监测
-                CHttpRequestPackage hrp;
-                hrp.sUri = QString("/api/ecs_exam_work/exam/getExamPropertyFromCacheByStudentSession/%1/%2")
-                    .arg(g_appInfoPtr->m_oExamInfo.nExamId).arg("CHECK_ENVIRONMENT,IS_FACE_CHECK,SNAPSHOT_INTERVAL,FACE_VERIFY_START_MINUTE,FACE_VERIFY_END_MINUTE,IS_STRANGER_ENABLE,IS_FACE_VERIFY_BEFORE");
-                hrp.nRequestType = RequestType::rtGetExamProperty;
-                hrp.sCommonStr = "CHECK_ENVIRONMENT,IS_FACE_CHECK,SNAPSHOT_INTERVAL,FACE_VERIFY_START_MINUTE,FACE_VERIFY_END_MINUTE,IS_STRANGER_ENABLE,IS_FACE_VERIFY_BEFORE";
-                g_httpBllPtr->get(hrp);
+                getExamProperty();
 			}						
 		}		
 	}
@@ -1231,6 +1225,16 @@ void courseList::onCheckExamInProgress(CCheckExamInProgress checkExamInProgress)
 	}
 }
 
+void courseList::getExamProperty()
+{
+    CHttpRequestPackage hrp;
+    hrp.sUri = QString("/api/ecs_exam_work/exam/getExamPropertyFromCacheByStudentSession/%1/%2")
+        .arg(g_appInfoPtr->m_oExamInfo.nExamId).arg("CHECK_ENVIRONMENT,IS_FACE_CHECK,SNAPSHOT_INTERVAL,FACE_VERIFY_START_MINUTE,FACE_VERIFY_END_MINUTE,IS_STRANGER_ENABLE,IS_FACE_VERIFY_BEFORE");
+    hrp.nRequestType = RequestType::rtGetExamProperty;
+    hrp.sCommonStr = "CHECK_ENVIRONMENT,IS_FACE_CHECK,SNAPSHOT_INTERVAL,FACE_VERIFY_START_MINUTE,FACE_VERIFY_END_MINUTE,IS_STRANGER_ENABLE,IS_FACE_VERIFY_BEFORE";
+    g_httpBllPtr->get(hrp);
+}
+
 void courseList::onEndExam(CEndExam endExam)
 {
     if(endExam.sModuleName == __FILE__)

+ 1 - 0
client/courseList.h

@@ -94,6 +94,7 @@ private:
     void GetOrgPropertiesByGroupWithoutCache();
     void doFaceCompare();
     void doLiveness();
+    void getExamProperty();
 
     Ui::courseList *ui;
 

BIN
client/images/img-face-mask.png


+ 6 - 1
client/login.cpp

@@ -502,6 +502,11 @@ void login::onStudentClientConfig(CStudentClientConfig studentClientConfig)
 		g_appInfoPtr->m_sRootOrgId = studentClientConfig.sRootOrgId;
 		g_appInfoPtr->m_bShowQmthLogo = studentClientConfig.bShowQmthLogo;
 		g_appInfoPtr->m_bShowStudentClientAppQrcode = studentClientConfig.bShowStudentClientAppQrcode;
+
+        g_appInfoPtr->m_bShowStudentName = studentClientConfig.bShowStudentName;
+        g_appInfoPtr->m_bShowStudentCode = studentClientConfig.bShowStudentCode;
+        g_appInfoPtr->m_bShowStudentIdentity = studentClientConfig.bShowStudentIdentity;
+
         if(studentClientConfig.bIsCustomMenuLogo)
         {
             g_appInfoPtr->m_sMenuLogoUrl = studentClientConfig.sCusMenuLogoFileUrl;
@@ -539,7 +544,7 @@ void login::onStudentClientConfig(CStudentClientConfig studentClientConfig)
 		}
 		
 #ifdef _DEBUG
-		g_appInfoPtr->m_bFullScreenTop = false;
+        g_appInfoPtr->m_bFullScreenTop = false;
 #endif // _DEBUG
 
         if(g_appInfoPtr->m_bFullScreenTop)

+ 1 - 0
client/rc.qrc

@@ -69,5 +69,6 @@
         <file>images/icon-aw-close.png</file>
         <file>images/icon-aw-minisize.png</file>
         <file>images/btn-etvt-mute.png</file>
+        <file>images/img-face-mask.png</file>
     </qresource>
 </RCC>

+ 5 - 0
common/CAppInfo.cpp

@@ -26,6 +26,11 @@ CAppInfo::CAppInfo()
 	m_bWeiXinAnswerEnabled = false;
 	m_jAudioPlayedCount = Json::Value::null;
 
+    m_bShowStudentName = true;
+    m_bShowStudentCode = true;
+    m_bShowStudentIdentity = true;
+    m_bMutipleAnserCountTips = false;
+
 	m_nStudentId = 0;
 	m_sStudentName = "";
 	m_nOrgId = 0;

+ 4 - 0
common/CAppInfo.h

@@ -101,6 +101,10 @@ public:
 	bool m_bWeiXinAnswerEnabled;//是否开启微信作答
 	Json::Value m_jAudioPlayedCount;
 
+    bool m_bShowStudentName;
+    bool m_bShowStudentCode;
+    bool m_bShowStudentIdentity;
+    bool m_bMutipleAnserCountTips;
 
 	__int64 m_nStudentId;
 	QString m_sStudentName;

+ 16 - 0
common/CHttpBll.cpp

@@ -1270,6 +1270,15 @@ void CHttpBll::genStudentClientConfig(CStudentClientConfig *pStudentClientConfig
         pStudentClientConfig->bShowQmthLogo = QVariant(jsonRoot["SHOW_QMTH_LOGO"].asString().c_str()).toBool();// " : "false",
         pStudentClientConfig->bShowStudentClientAppQrcode = QVariant(jsonRoot["SHOW_STUDENT_CLIENT_APP_QRCODE"].asString().c_str()).toBool();// " : "true",
         pStudentClientConfig->sStudentCodeLoginAlias = jsonRoot["STUDENT_CODE_LOGIN_ALIAS"].asString().c_str(); // " : "学号登录34s"
+
+
+        if (jsonRoot.isMember("SHOW_INFO"))
+        {
+            QString sShowInfo = jsonRoot["SHOW_INFO"].asString().c_str();
+            pStudentClientConfig->bShowStudentName = sShowInfo.indexOf("STU_NAME") >= 0;
+            pStudentClientConfig->bShowStudentCode = sShowInfo.indexOf("STU_CODE") >= 0;
+            pStudentClientConfig->bShowStudentIdentity = sShowInfo.indexOf("IDENTITY_NUMBER") >= 0;
+        }
     }
     catch (const std::exception &e)
     {
@@ -1659,6 +1668,13 @@ void CHttpBll::genGetExamProperty(CGetExamProperty *pGetExamProperty, const std:
                 pGetExamProperty->vOfflineUploadFileType.push_back(jFileType[i].asString().c_str());
             }
         }
+
+
+
+        if(jsonRoot.isMember("SHOW_MULTIPLE_CHOICE_WARNING"))
+        {
+            pGetExamProperty->bMutipleAnserCountTips = QVariant(jsonRoot["SHOW_MULTIPLE_CHOICE_WARNING"].asString().c_str()).toBool();
+        }
     }
     catch (const std::exception &e)
     {

+ 13 - 0
common/httpDataDef.h

@@ -193,6 +193,11 @@ public:
 	bool bShowQmthLogo;// " : "false",
 	bool bShowStudentClientAppQrcode;// " : "true",				
 	QString sStudentCodeLoginAlias;// " : "学号登录34s"
+
+    bool bShowStudentName;
+    bool bShowStudentCode;
+    bool bShowStudentIdentity;
+
 	CStudentClientConfig()
 	{
 		sCusMenuLogoFileUrl = "";
@@ -212,6 +217,10 @@ public:
 		bShowQmthLogo = false;// " : "false",
 		bShowStudentClientAppQrcode = false;// " : "true",				
 		sStudentCodeLoginAlias = ""; // " : "学号登录34s"
+
+        bShowStudentName = true;
+        bShowStudentCode = true;
+        bShowStudentIdentity = true;
 	}
 };
 
@@ -454,6 +463,8 @@ public:
 
     bool bIsLivenessBefore;//考前活体检测
 
+    bool bMutipleAnserCountTips;
+
 	CGetExamProperty()
 	{
 		sType = "";
@@ -473,6 +484,8 @@ public:
 		bShowCheatingRemark = false;
 		sCheatingRemark = "";
         bIsLivenessBefore = false;
+
+        bMutipleAnserCountTips = false;
 	}
 };
 

+ 31 - 5
common/popMsgBox.cpp

@@ -4,6 +4,7 @@
 #include "CAppInfo.h"
 
 #include <QDesktopWidget>
+#include <QGraphicsDropShadowEffect>
 
 popMsgBox::popMsgBox(QWidget *parent) :
     QDialog(parent),
@@ -12,9 +13,17 @@ popMsgBox::popMsgBox(QWidget *parent) :
     ui->setupUi(this);
 
     setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint);
-    setAttribute(Qt::WA_TranslucentBackground);       //小部件应该具有半透明的背景
+    setAttribute(Qt::WA_TranslucentBackground);
+
 
     setStyleSheet(g_appInfoPtr->m_sQssStr);
+
+    QGraphicsDropShadowEffect* effect = new QGraphicsDropShadowEffect(this);
+    effect->setColor(QColor(0, 0, 0, 0.08*255));
+    effect->setOffset(g_appInfoPtr->m_fRate*2, g_appInfoPtr->m_fRate*2);
+    effect->setBlurRadius(g_appInfoPtr->m_fRate*12);
+
+    setGraphicsEffect(effect);
 }
 
 popMsgBox::~popMsgBox()
@@ -22,6 +31,12 @@ popMsgBox::~popMsgBox()
     delete ui;
 }
 
+void popMsgBox::setBtnText(QString sBtnYesText, QString sBtnNoText)
+{
+    ui->btn_yes->setText(sBtnYesText);
+    ui->btn_no->setText(sBtnNoText);
+}
+
 void popMsgBox::setMsg(QString sMsg, QString sTitle)
 {
     ui->label_pmb_content->setText(sMsg);
@@ -30,16 +45,16 @@ void popMsgBox::setMsg(QString sMsg, QString sTitle)
 
 void popMsgBox::initUI(POP_MSG_BTN btn)
 {
-    int nCW = g_appInfoPtr->m_fRate*340;
+    int nCW = g_appInfoPtr->m_fRate*352;
     QDesktopWidget *dekwiget = QApplication::desktop();
-    setGeometry((dekwiget->width() - nCW)/2, (dekwiget->height() - g_appInfoPtr->m_fRate*253)/2, nCW, g_appInfoPtr->m_fRate*253);
-    ui->widget_pmb_bg->setGeometry(0, 0 , nCW, g_appInfoPtr->m_fRate*253);
+    setGeometry((dekwiget->width() - nCW)/2, (dekwiget->height() - g_appInfoPtr->m_fRate*265)/2, nCW, g_appInfoPtr->m_fRate*265);
+    ui->widget_pmb_bg->setGeometry(g_appInfoPtr->m_fRate*6, g_appInfoPtr->m_fRate*6 , nCW - g_appInfoPtr->m_fRate*12, g_appInfoPtr->m_fRate*253);
     ui->label_pmb_icon->setGeometry(g_appInfoPtr->m_fRate*30, g_appInfoPtr->m_fRate*30,
                                    g_appInfoPtr->m_fRate*40, g_appInfoPtr->m_fRate*40);
     ui->label_pmb_title->adjustSize();
     ui->label_pmb_title->setGeometry(ui->label_pmb_icon->x() + ui->label_pmb_icon->width() + g_appInfoPtr->m_fRate*16, g_appInfoPtr->m_fRate*30,
                                      ui->label_pmb_title->width(), ui->label_pmb_title->height());
-    ui->label_pmb_content->setFixedWidth(nCW - ui->label_pmb_icon->x() - ui->label_pmb_icon->width() - g_appInfoPtr->m_fRate*16*2);\
+    ui->label_pmb_content->setFixedWidth(nCW - ui->label_pmb_icon->x() - ui->label_pmb_icon->width() - g_appInfoPtr->m_fRate*16*2 - g_appInfoPtr->m_fRate*12);
     ui->label_pmb_content->adjustSize();
     ui->label_pmb_content->setGeometry(ui->label_pmb_icon->x() + ui->label_pmb_icon->width() + g_appInfoPtr->m_fRate*16,
                                        ui->label_pmb_title->y() + ui->label_pmb_title->height() + g_appInfoPtr->m_fRate*8,
@@ -55,6 +70,17 @@ void popMsgBox::initUI(POP_MSG_BTN btn)
                             ui->btn_yes->y(), ui->btn_yes->width(), ui->btn_yes->height());
 }
 
+int popMsg(QString sMsg, QString sTitle, QWidget *parent, QString sBtnYesText, QString sBtnNoText)
+{
+    popMsgBox msgDlg(parent);
+
+    msgDlg.setMsg(sMsg, sTitle);
+    msgDlg.initUI(POP_MSG_BTN::pmb_yse_no);
+    msgDlg.setBtnText(sBtnYesText, sBtnNoText);
+
+    return msgDlg.exec();
+}
+
 int popMsg(QString sMsg, QString sTitle, QWidget *parent, POP_MSG_BTN btn, int nStayTime)
 {
     popMsgBox msgDlg(parent);

+ 2 - 0
common/popMsgBox.h

@@ -22,6 +22,7 @@ public:
     explicit popMsgBox(QWidget *parent = nullptr);
     ~popMsgBox();
 
+    void setBtnText(QString sBtnYesText, QString sBtnNoText);
     void setMsg(QString sMsg, QString sTitle);
     void initUI(POP_MSG_BTN btn);
 	
@@ -36,6 +37,7 @@ private:
 	std::shared_ptr<QTimer> m_timePtr;
 };
 
+extern int popMsg(QString sMsg, QString sTitle, QWidget *parent, QString sBtnYesText, QString sBtnNoText);
 extern int popMsg(QString sMsg, QString sTitle, QWidget *parent, POP_MSG_BTN btn = POP_MSG_BTN::pmb_yse_no, int nStayTime = 0);
 
 #endif // POPMSGBOX_H

+ 3 - 0
common/popMsgBox.ui

@@ -13,6 +13,9 @@
   <property name="windowTitle">
    <string>Form</string>
   </property>
+  <property name="styleSheet">
+   <string notr="true"/>
+  </property>
   <widget class="QWidget" name="widget_pmb_bg" native="true">
    <property name="geometry">
     <rect>

+ 19 - 16
face/faceCompare.cpp

@@ -165,6 +165,9 @@ void faceCompare::initUI()
                                             ui->label_fc_basePhoto->width() - g_appInfoPtr->m_fRate*10*2, g_appInfoPtr->m_fRate*20);
     ui->widget_fc_camera->setGeometry(ui->label_fc_basePhoto->x() + ui->label_fc_basePhoto->width() + g_appInfoPtr->m_fRate*20,
                                      ui->label_fc_basePhoto->y(), g_appInfoPtr->m_fRate*580, g_appInfoPtr->m_fRate*300);
+    ui->label_faceRect->setGeometry((ui->widget_fc_camera->width() - g_appInfoPtr->m_fRate*140)/2,
+                                    (ui->widget_fc_camera->height() - g_appInfoPtr->m_fRate*140 - g_appInfoPtr->m_fRate*(20 + 40))/2,
+                                    g_appInfoPtr->m_fRate*140, g_appInfoPtr->m_fRate*140);
     ui->btn_fc_compare->setGeometry((ui->widget_fc_camera->width() - g_appInfoPtr->m_fRate*120)/2,
                                     ui->widget_fc_camera->height() - g_appInfoPtr->m_fRate*(20 + 40),
                                     g_appInfoPtr->m_fRate*120, g_appInfoPtr->m_fRate*40);
@@ -180,30 +183,30 @@ void faceCompare::on_btn_fc_compare_clicked()
 {
     if(g_faceRecProcPtr == nullptr)
     {
-        g_faceRecProcPtr = std::make_shared<CFaceRecProc>();
-
-        if (!g_appInfoPtr->m_sStudentPhotoPath.isEmpty())
-        {
-            if(!setBaseImage())
-            {
-                return;
-            }
-        }
-        else
-        {
-            ShowMsg(QString::fromLocal8Bit("本场考试需要进行人脸检测,但是您没有上传底照,请联系老师"), this, MSG_ICON_TYPE::mit_error);
-			QTimer::singleShot(3000, this, [&]() { emit exitFaceCompare(); });
-            return;
-        }
+        g_faceRecProcPtr = std::make_shared<CFaceRecProc>();       
     }
 
-    if(!g_faceRecProcPtr->hasBaseImage())
+    if (!g_appInfoPtr->m_sStudentPhotoPath.isEmpty())
     {
         if(!setBaseImage())
         {
             return;
         }
     }
+    else
+    {
+        ShowMsg(QString::fromLocal8Bit("本场考试需要进行人脸检测,但是您没有上传底照,请联系老师"), this, MSG_ICON_TYPE::mit_error);
+        QTimer::singleShot(3000, this, [&]() { emit exitFaceCompare(); });
+        return;
+    }
+
+//    if(!g_faceRecProcPtr->hasBaseImage())
+//    {
+//        if(!setBaseImage())
+//        {
+//            return;
+//        }
+//    }
 
     m_bStartCompare = true;
 	ui->btn_fc_compare->setEnabled(false);

+ 13 - 0
face/faceCompare.ui

@@ -153,6 +153,19 @@
        <string>开始识别</string>
       </property>
      </widget>
+     <widget class="QLabel" name="label_faceRect">
+      <property name="geometry">
+       <rect>
+        <x>100</x>
+        <y>30</y>
+        <width>121</width>
+        <height>101</height>
+       </rect>
+      </property>
+      <property name="text">
+       <string/>
+      </property>
+     </widget>
     </widget>
    </widget>
   </widget>

+ 53 - 53
face/faceLiveness.cpp

@@ -137,33 +137,33 @@ faceLiveness::faceLiveness(FACE_LIVENESS_TYPE livenessType, QWidget *parent) :
 		m_initTimer->stop();
         if(g_faceRecProcPtr == nullptr)
         {
-            g_faceRecProcPtr = std::make_shared<CFaceRecProc>();
+            g_faceRecProcPtr = std::make_shared<CFaceRecProc>();            
+        }
 
-            if (!g_appInfoPtr->m_sStudentPhotoPath.isEmpty())
+        if (!g_appInfoPtr->m_sStudentPhotoPath.isEmpty())
+        {
+//                if(!g_faceRecProcPtr->hasBaseImage())
             {
-                if(!g_faceRecProcPtr->hasBaseImage())
+                if(!setBaseImage())
                 {
-                    if(!setBaseImage())
-                    {
-                        return;
-                    }
+                    return;
                 }
             }
-            else
-            {
-                ShowMsg(QString::fromLocal8Bit("当前考试未底照"), this, MSG_ICON_TYPE::mit_error);
-                return;
-            }
         }
-
-        if(!g_faceRecProcPtr->hasBaseImage())
+        else
         {
-            if(!setBaseImage())
-            {
-                return;
-            }
+            ShowMsg(QString::fromLocal8Bit("当前考试未底照"), this, MSG_ICON_TYPE::mit_error);
+            return;
         }
 
+//        if(!g_faceRecProcPtr->hasBaseImage())
+//        {
+//            if(!setBaseImage())
+//            {
+//                return;
+//            }
+//        }
+
         m_bStartCompare = true;
         m_fMaxYaw = 0;
         m_fMinYaw = 0;
@@ -480,48 +480,35 @@ void faceLiveness::on_btn_fl_startVerify_clicked()
 {
     if(g_faceRecProcPtr == nullptr)
     {
-        g_faceRecProcPtr = std::make_shared<CFaceRecProc>();
+        g_faceRecProcPtr = std::make_shared<CFaceRecProc>();       
+    }
 
-        if (!g_appInfoPtr->m_sStudentPhotoPath.isEmpty())
+    if (!g_appInfoPtr->m_sStudentPhotoPath.isEmpty())
+    {
+//        if(!g_faceRecProcPtr->hasBaseImage())
         {
-            if(!g_faceRecProcPtr->hasBaseImage())
+            if(!setBaseImage())
             {
-                if(!setBaseImage())
-                {
-                    return;
-                }
+                return;
             }
-
-//            QString sFileName = g_appInfoPtr->m_sStudentPhotoPath.right(g_appInfoPtr->m_sStudentPhotoPath.length() - g_appInfoPtr->m_sStudentPhotoPath.lastIndexOf("/") - 1);
-//            sFileName = g_appInfoPtr->m_sCacheFileDir + sFileName;
-//            if(!QFile::exists(sFileName))
-//            {
-//                ShowMsg(QString::fromLocal8Bit("底照下载失败,请检查网络"), this, MSG_ICON_TYPE::mit_error);
-//                return;
-//            }
-
-//            if(!g_faceRecProcPtr->setBaseImage(sFileName))
-//            {
-//                ShowMsg(g_faceRecProcPtr->errorMsg(), this, MSG_ICON_TYPE::mit_error);
-//                return;
-//            }
         }
-        else
-        {
-            ShowMsg(QString::fromLocal8Bit("当前考试未底照"), this, MSG_ICON_TYPE::mit_error);
-            return;
-        }
-    }
 
-
-    if(!g_faceRecProcPtr->hasBaseImage())
+    }
+    else
     {
-        if(!setBaseImage())
-        {
-            return;
-        }
+        ShowMsg(QString::fromLocal8Bit("当前考试未底照"), this, MSG_ICON_TYPE::mit_error);
+        return;
     }
 
+
+//    if(!g_faceRecProcPtr->hasBaseImage())
+//    {
+//        if(!setBaseImage())
+//        {
+//            return;
+//        }
+//    }
+
     m_bStartCompare = true;
     m_fMaxYaw = 0;
     m_fMinYaw = 0;
@@ -568,7 +555,7 @@ void faceLiveness::initAcionIcon()
     movie->start();
 }
 
-void faceLiveness::saveLivenessResult()
+void faceLiveness:: saveLivenessResult()
 {
 	try
 	{
@@ -614,6 +601,7 @@ void faceLiveness::saveLivenessResult()
 					jLiveness["faceCount"] = m_livenessList[i].nFaceCount;
 					jLiveness["realness"] = m_livenessList[i].nRealness;
 					jLiveness["similarity"] = m_livenessList[i].fSimilarity;
+                    jLiveness["fileUrl"] = m_livenessList[i].sUrl.toStdString();
 					if (m_livenessList[i].nFaceCount == 0)
 					{
 						jLiveness["status"] = STATUS_TYPE::ST_NOT_ONESELF.toStdString();
@@ -637,7 +625,7 @@ void faceLiveness::saveLivenessResult()
 				}
 
 			}
-			qDebug() << jLiveness.toStyledString().c_str();
+            myServerLog() << jLiveness.toStyledString().c_str();
 			CHttpRequestPackage hrp;
 			hrp.sUri = QString("/api/ecs_oe_student/client/exam/process/saveFaceLiveVerifyResult");
 			hrp.nRequestType = RequestType::rtSaveFaceLiveVerifyResult;
@@ -817,6 +805,7 @@ void faceLiveness::onClientExamProcessUploadSign(CClientExamProcessUploadSign pr
         {
             if(processUpload.nCode == 200)
             {
+                m_nRetryCount = 0;
                 CHttpRequestPackage hrp;
                 hrp.sUri = processUpload.sFormUrl;
                 hrp.nRequestType = RequestType::rtUploadFileToAliyun;
@@ -843,6 +832,16 @@ void faceLiveness::onClientExamProcessUploadSign(CClientExamProcessUploadSign pr
                 {
                     ShowMsg(processUpload.sMessage, this, MSG_ICON_TYPE::mit_error);
                 }
+
+                if(m_nRetryCount < 4)
+                {
+                    saveLivenessResult();
+                    m_nRetryCount++;
+                }
+                else
+                {
+                    emit faceLivenessFaild();
+                }
             }
         }
     }
@@ -986,6 +985,7 @@ void faceLiveness::onSaveFaceLiveVerifyResult(CBaseResponsePackage res)
 	{
 		if (res.nCode == 200)
 		{
+            m_nRetryCount = 0;
 			if (m_pCloseTimer == nullptr)
 			{
 				m_pCloseTimer = std::make_shared<QTimer>();

+ 23 - 23
face/inprogressFace.cpp

@@ -81,31 +81,31 @@ void CInprogressFace::threadProc()
 {
 	if (g_faceRecProcPtr == nullptr)
 	{
-		g_faceRecProcPtr = std::make_shared<CFaceRecProc>();
-
-		if (!g_appInfoPtr->m_sStudentPhotoPath.isEmpty())
-		{
-			QString sFileName = g_appInfoPtr->m_sStudentPhotoPath.right(g_appInfoPtr->m_sStudentPhotoPath.length() - g_appInfoPtr->m_sStudentPhotoPath.lastIndexOf("/") - 1);
-			sFileName = g_appInfoPtr->m_sCacheFileDir + sFileName;
-			if (!QFile::exists(sFileName))
-			{
-				emit compareFailed(QString::fromLocal8Bit("底照下载失败,请检查网络"));
-				return;
-			}
-			
-            if(!g_faceRecProcPtr->setBaseImage(sFileName))
-            {
-                emit compareFailed(g_faceRecProcPtr->errorMsg());
-                return;
-            }
-		}
-		else
-		{
-			emit compareFailed(QString::fromLocal8Bit("当前考试未底照"));
-			return;
-		}
+		g_faceRecProcPtr = std::make_shared<CFaceRecProc>();		
 	}
 
+    if (!g_appInfoPtr->m_sStudentPhotoPath.isEmpty())
+    {
+        QString sFileName = g_appInfoPtr->m_sStudentPhotoPath.right(g_appInfoPtr->m_sStudentPhotoPath.length() - g_appInfoPtr->m_sStudentPhotoPath.lastIndexOf("/") - 1);
+        sFileName = g_appInfoPtr->m_sCacheFileDir + sFileName;
+        if (!QFile::exists(sFileName))
+        {
+            emit compareFailed(QString::fromLocal8Bit("底照下载失败,请检查网络"));
+            return;
+        }
+
+        if(!g_faceRecProcPtr->setBaseImage(sFileName))
+        {
+            emit compareFailed(g_faceRecProcPtr->errorMsg());
+            return;
+        }
+    }
+    else
+    {
+        emit compareFailed(QString::fromLocal8Bit("当前考试未底照"));
+        return;
+    }
+
     while(m_bIsRun)
     {
         if(m_bStart)

+ 1 - 1
launcher/envCheck.cpp

@@ -276,7 +276,7 @@ void envCheck::checkProc()
     if(!sCheckStr.isEmpty())
     {
         m_unpasslist.push_back(sCheckStr);
-        myDebug()<<QString::fromLocal8Bit("环境检测异常,")<<sCheckStr;
+        myServerLog()<<QString::fromLocal8Bit("环境检测异常,")<<sCheckStr;
     }
 
     sCheckStr = "";