wangyaojie 7 mēneši atpakaļ
vecāks
revīzija
f48e7198bc

+ 1 - 1
client/CLiveViodeProc.cpp

@@ -92,7 +92,7 @@ void CLiveViodeProc::startTest(HWND hwnd)
 
 
 int CLiveViodeProc::getCameraCount()
 int CLiveViodeProc::getCameraCount()
 {
 {
-    if(m_nCameraCount == 0)
+//    if(m_nCameraCount == 0)
     {
     {
         m_nCameraCount = m_pTRTCSDK->getDeviceManager()->getDevicesList(TXMediaDeviceTypeCamera)->getCount();
         m_nCameraCount = m_pTRTCSDK->getDeviceManager()->getDevicesList(TXMediaDeviceTypeCamera)->getCount();
     }
     }

+ 104 - 5
client/answerWidget.cpp

@@ -352,14 +352,14 @@ void answerWidget::checkRemoteBreach()
 		QString sCheckStr = "";
 		QString sCheckStr = "";
 		if (CCommonTools::isUseRDP())
 		if (CCommonTools::isUseRDP())
 		{
 		{
-			sCheckStr = QString::fromLocal8Bit("检测是否开启远程桌面");
+            sCheckStr = QString::fromLocal8Bit("请关闭远程桌面");
 			qDebug() << QString::fromLocal8Bit("开启远程桌面");
 			qDebug() << QString::fromLocal8Bit("开启远程桌面");
 			bExit = true;
 			bExit = true;
 		}
 		}
 		
 		
 		if (m_MonitorEnumeratorPtr->getMontorNumber() > 1)
 		if (m_MonitorEnumeratorPtr->getMontorNumber() > 1)
 		{
 		{
-			sCheckStr = QString::fromLocal8Bit("请检测是否开启分屏");
+            sCheckStr = QString::fromLocal8Bit("请关闭分屏");
 			qDebug() << QString::fromLocal8Bit("开启双屏");
 			qDebug() << QString::fromLocal8Bit("开启双屏");
 			bExit = true;
 			bExit = true;
 		}
 		}
@@ -376,7 +376,7 @@ void answerWidget::checkRemoteBreach()
                 {
                 {
                     if (sCheckStr.isEmpty())
                     if (sCheckStr.isEmpty())
                     {
                     {
-                        sCheckStr = QString::fromLocal8Bit("请检测是否开启%1").arg(appList[i]);
+                        sCheckStr = QString::fromLocal8Bit("请关闭%1").arg(appList[i]);
                     }
                     }
                     else
                     else
                     {
                     {
@@ -1313,6 +1313,12 @@ void answerWidget::onExamHeartbeat(CExamHeartbeat examHeartbeat)
                 connect(g_inProcessFace.get(), &CInprogressFace::compareFailed, this, [&](QString sErrorMsg){
                 connect(g_inProcessFace.get(), &CInprogressFace::compareFailed, this, [&](QString sErrorMsg){
                     ShowMsg(sErrorMsg, g_appInfoPtr->m_pAnsBgWidget);
                     ShowMsg(sErrorMsg, g_appInfoPtr->m_pAnsBgWidget);
                 });	
                 });	
+
+
+                connect(g_inProcessFace.get(), &CInprogressFace::reAddImage, this, [&](){
+                    m_bReAddFaceImage = true;
+                });
+
 				startCapture();
 				startCapture();
             }  
             }  
             m_nNextFaceCountSecond = m_nLeftSeconds - CCommonTools::genRandomNumber(1, 10);
             m_nNextFaceCountSecond = m_nLeftSeconds - CCommonTools::genRandomNumber(1, 10);
@@ -1793,6 +1799,38 @@ void answerWidget::onRenderVideoFrame(const char* userId, TRTCVideoStreamType st
     }
     }
 }
 }
 
 
+void answerWidget::cameraCheckFiled()
+{
+    if(!m_bIsExitLogin)
+    {
+        m_bIsExitLogin = true;
+        awTimeLeftTips *wExitExam = new awTimeLeftTips(MASK_POP_WIDGET_TYPE::wt_exitExam, (QWidget*)(this->parent()));
+        wExitExam->setText(QString::fromLocal8Bit("未检测到有效摄像头信息,请调整后重试"), 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<QTimer>();
+            m_pNetWorkErrorTimerPtr->setInterval(30 * 1000);
+            connect(m_pNetWorkErrorTimerPtr.get(), &QTimer::timeout, [this, wExitExam]() {
+                m_pNetWorkErrorTimerPtr->stop();
+                delete wExitExam;
+                emit gobackLogin();
+            });
+        }
+        m_pNetWorkErrorTimerPtr->start();
+    }
+    return;
+}
+
 void answerWidget::startCapture()
 void answerWidget::startCapture()
 {
 {
 //    if(m_pinitTimer == nullptr)
 //    if(m_pinitTimer == nullptr)
@@ -1826,6 +1864,9 @@ void answerWidget::startCapture()
         m_nLastCaptureSecond = m_nLeftSeconds;
         m_nLastCaptureSecond = m_nLeftSeconds;
 
 
         connect(m_pVideoTimer.get(), &QTimer::timeout, this, [&](){
         connect(m_pVideoTimer.get(), &QTimer::timeout, this, [&](){
+            int nCameraCount = g_clientVideoProcPtr->getCameraCount();
+            QString sCameraInfo = g_clientVideoProcPtr->getCurrentCamera();
+
 
 
             cv::Mat frame;
             cv::Mat frame;
             {
             {
@@ -1835,14 +1876,56 @@ void answerWidget::startCapture()
 
 
             if(frame.empty())
             if(frame.empty())
             {
             {
-                qDebug()<<"widgetCameraTest frame is empty";
-                return;
+                myServerLog()<<"widgetCameraTest frame is empty";
+                myServerLog()<<"nCameraCount:"<<nCameraCount<<",sCameraInfo:"<<sCameraInfo;
+//                return;
+            }
+
+            bool bCameraCheckField = false;
+            if(nCameraCount == 0 || frame.empty())
+            {
+                if(m_nCheckCameraTime == 0)
+                {
+                    m_nCheckCameraTime = QDateTime::currentDateTime().toSecsSinceEpoch();
+                }
+                bCameraCheckField = true;
+            }
+            else
+            {
+                m_nCheckCameraTime = 0;
+            }
+//            myServerLog()<<"m_nCheckCameraTime:"<<m_nCheckCameraTime;
+
+            if(m_bReAddFaceImage)
+            {
+                if(bCameraCheckField)
+                {
+                    if(m_nCheckCameraTime != 0 && QDateTime::currentDateTime().toSecsSinceEpoch() - m_nCheckCameraTime > 20)
+                    {
+                        cameraCheckFiled();
+                    }
+                    return ;
+                }
+
+                m_bReAddFaceImage = false;
+                if (g_inProcessFace != nullptr)
+                {
+                    g_inProcessFace->addImage(frame);
+                }
             }
             }
 
 
             if (g_inProcessFace != nullptr &&
             if (g_inProcessFace != nullptr &&
                     g_appInfoPtr->m_oExamInfo.bIsExamInProgress &&
                     g_appInfoPtr->m_oExamInfo.bIsExamInProgress &&
                     !m_bExamInpressFaceCaptured)
                     !m_bExamInpressFaceCaptured)
             {
             {
+                if(bCameraCheckField)
+                {
+                    if(m_nCheckCameraTime != 0 && QDateTime::currentDateTime().toSecsSinceEpoch() - m_nCheckCameraTime > 20)
+                    {
+                        cameraCheckFiled();
+                    }
+                    return ;
+                }
                 m_bExamInpressFaceCaptured = true;
                 m_bExamInpressFaceCaptured = true;
                 g_inProcessFace->addImage(frame);
                 g_inProcessFace->addImage(frame);
             }
             }
@@ -1850,6 +1933,14 @@ void answerWidget::startCapture()
             if (g_inProcessFace != nullptr &&
             if (g_inProcessFace != nullptr &&
                 m_nLastCaptureSecond - m_nLeftSeconds > g_appInfoPtr->m_oExamInfo.nSnapshotInterval*60)
                 m_nLastCaptureSecond - m_nLeftSeconds > g_appInfoPtr->m_oExamInfo.nSnapshotInterval*60)
             {
             {
+                if(bCameraCheckField)
+                {
+                    if(m_nCheckCameraTime != 0 && QDateTime::currentDateTime().toSecsSinceEpoch() - m_nCheckCameraTime > 20)
+                    {
+                        cameraCheckFiled();
+                    }
+                    return ;
+                }
                 m_nLastCaptureSecond = m_nLeftSeconds;
                 m_nLastCaptureSecond = m_nLeftSeconds;
                 g_inProcessFace->addImage(frame);
                 g_inProcessFace->addImage(frame);
             }
             }
@@ -1857,6 +1948,14 @@ void answerWidget::startCapture()
             if(g_inProcessFace != nullptr &&
             if(g_inProcessFace != nullptr &&
                     m_nNextFaceCountSecond > m_nLeftSeconds)
                     m_nNextFaceCountSecond > m_nLeftSeconds)
             {
             {
+                if(bCameraCheckField)
+                {
+                    if(m_nCheckCameraTime != 0 && QDateTime::currentDateTime().toSecsSinceEpoch() - m_nCheckCameraTime > 20)
+                    {
+                        cameraCheckFiled();
+                    }
+                    return ;
+                }
 				m_nNextFaceCountSecond = m_nLeftSeconds - CCommonTools::genRandomNumber(1, 10);
 				m_nNextFaceCountSecond = m_nLeftSeconds - CCommonTools::genRandomNumber(1, 10);
                 g_inProcessFace->addFaceCountImage(frame);
                 g_inProcessFace->addFaceCountImage(frame);
             }
             }

+ 5 - 0
client/answerWidget.h

@@ -93,6 +93,9 @@ private:
 	void checkRemoteBreach();
 	void checkRemoteBreach();
     void setChecked(QPushButton *btn, bool bChecked);
     void setChecked(QPushButton *btn, bool bChecked);
     bool allMutipleQuestionHas2Answers();
     bool allMutipleQuestionHas2Answers();
+    void cameraCheckFiled();
+
+    int m_nCheckCameraTime = 0;
 
 
     Ui::answerWidget *ui;
     Ui::answerWidget *ui;
 	
 	
@@ -134,8 +137,10 @@ private:
 	QStringList m_sRemoteTipList;
 	QStringList m_sRemoteTipList;
 
 
 
 
+    bool m_bReAddFaceImage = false;
     bool m_bExamInpressFaceCaptured = false;
     bool m_bExamInpressFaceCaptured = false;
     int m_nRetryCount = 0;
     int m_nRetryCount = 0;
+    bool m_bIsExitLogin = false;
 };
 };
 
 
 #endif // ANSWERWIDGET_H
 #endif // ANSWERWIDGET_H

+ 1 - 1
client/awTimeLeftTips.cpp

@@ -71,7 +71,7 @@ void awTimeLeftTips::initUI()
     setGeometry(0, 0, dekwiget->width(), dekwiget->height());
     setGeometry(0, 0, dekwiget->width(), dekwiget->height());
 	ui->widget_mask->setGeometry(0, 0, width(), height());
 	ui->widget_mask->setGeometry(0, 0, width(), height());
 	ui->widget_awtlt_bg->setGeometry((width() - g_appInfoPtr->m_fRate*420)/2,
 	ui->widget_awtlt_bg->setGeometry((width() - g_appInfoPtr->m_fRate*420)/2,
-		g_appInfoPtr->m_fRate * 190, g_appInfoPtr->m_fRate*420, g_appInfoPtr->m_fRate*190);
+        g_appInfoPtr->m_fRate * 190, g_appInfoPtr->m_fRate*420, g_appInfoPtr->m_fRate*190);
 	ui->label_awtlt_title->adjustSize();
 	ui->label_awtlt_title->adjustSize();
 	ui->label_awtlt_title->setGeometry(g_appInfoPtr->m_fRate *20, g_appInfoPtr->m_fRate *20,
 	ui->label_awtlt_title->setGeometry(g_appInfoPtr->m_fRate *20, g_appInfoPtr->m_fRate *20,
 		ui->label_awtlt_title->width(), ui->label_awtlt_title->height());	
 		ui->label_awtlt_title->width(), ui->label_awtlt_title->height());	

+ 2 - 2
common/CCommonTools.cpp

@@ -849,13 +849,13 @@ namespace CCommonTools
             }
             }
             else
             else
             {
             {
-                myDebug()<<"Mat to Image error";
+                myServerLog()<<"Mat to Image error";
                 return QImage();
                 return QImage();
             }
             }
         }
         }
         catch(std::exception &e)
         catch(std::exception &e)
         {
         {
-            myDebug()<<"Mat2QImage"<<e.what();
+            myServerLog()<<"Mat2QImage"<<e.what();
             return QImage();
             return QImage();
         }
         }
     }
     }

+ 40 - 0
common/CHttpBll.cpp

@@ -1167,6 +1167,22 @@ void CHttpBll::requestProc(CHttpRequestPackage requestPkg)
         }
         }
         break;
         break;
 
 
+        case RequestType::rtGetWXUploadedFile:
+        {
+            CGetWXUploadedFile res;
+            res.nCode = nCode;
+            if (sErrorMsg != "" || nCode != 200)
+            {
+                res.sMessage = sErrorMsg;
+            }
+            else
+            {
+                genGetWXUploadedFile(&res, sResponse);
+            }
+            emit sgnGetWXUploadedFile(res);
+        }
+        break;
+
         default:
         default:
         break;
         break;
     }
     }
@@ -2725,3 +2741,27 @@ void CHttpBll::genSkipFaceCheckParam(CSkipFaceCheckParam *pSkipFaceCheckParam, c
         myServerLog()<<sResponse.c_str()<<",exception error"<<e.what();
         myServerLog()<<sResponse.c_str()<<",exception error"<<e.what();
     }
     }
 }
 }
+
+void CHttpBll::genGetWXUploadedFile(CGetWXUploadedFile *pGetWXUploadedFile, const std::string &sResponse)
+{
+    try
+    {
+        Json::Reader reader;
+        Json::Value jsonRoot = Json::Value::null;
+        if (!reader.parse(sResponse, jsonRoot))
+        {
+            pGetWXUploadedFile->sMessage = QString::fromLocal8Bit("数据请求失败,请检查网络是否正常!");
+            myDebug() << pGetWXUploadedFile->sMessage << sResponse.c_str();
+        }
+
+        pGetWXUploadedFile->nExamRecordDataId = jsonRoot["examRecordDataId"].asInt64();
+        pGetWXUploadedFile->nQuestionOrder = jsonRoot["questionOrder"].asInt();
+        pGetWXUploadedFile->sFilePath = jsonRoot["filePath"].asString().c_str();
+        pGetWXUploadedFile->sStatus = jsonRoot["status"].asString().c_str();
+        pGetWXUploadedFile->sTransferFileType = jsonRoot["transferFileType"].asString().c_str();
+    }
+    catch (const std::exception &e)
+    {
+        myServerLog()<<sResponse.c_str()<<",exception error"<<e.what();
+    }
+}

+ 2 - 0
common/CHttpBll.h

@@ -75,6 +75,7 @@ signals:
     void sgnUploadFileToAliyun(CUploadFileToAliyun uploadFileToAliyun);
     void sgnUploadFileToAliyun(CUploadFileToAliyun uploadFileToAliyun);
     void sgnExamControlCheckTime(CBaseResponsePackage res);
     void sgnExamControlCheckTime(CBaseResponsePackage res);
     void sgnSkipFaceCheckParam(CSkipFaceCheckParam skipFaceCheckParam);
     void sgnSkipFaceCheckParam(CSkipFaceCheckParam skipFaceCheckParam);
+    void sgnGetWXUploadedFile(CGetWXUploadedFile getWXUploadedFile);
 public:
 public:
     CHttpBll();
     CHttpBll();
 
 
@@ -140,6 +141,7 @@ private:
 
 
 	void genExamCourseInfo(const Json::Value &jExamItem, CExamCourseInfo &eci);
 	void genExamCourseInfo(const Json::Value &jExamItem, CExamCourseInfo &eci);
     void genSkipFaceCheckParam(CSkipFaceCheckParam *pSkipFaceCheckParam, const std::string &sResponse);
     void genSkipFaceCheckParam(CSkipFaceCheckParam *pSkipFaceCheckParam, const std::string &sResponse);
+    void genGetWXUploadedFile(CGetWXUploadedFile *pGetWXUploadedFile, const std::string &sResponse);
 
 
 	QString sKey;
 	QString sKey;
     QString sToken;
     QString sToken;

+ 13 - 1
common/httpDataDef.h

@@ -89,7 +89,8 @@ enum class RequestType
     rtClientExamProcessUploadSign,//文件上传签名信息
     rtClientExamProcessUploadSign,//文件上传签名信息
     rtUploadFileToAliyun,
     rtUploadFileToAliyun,
     rtExamControlCheckTime, //交卷冻结时间检查
     rtExamControlCheckTime, //交卷冻结时间检查
-    rtSkipFaceCheckParam//检查当前考生是否跳过人脸识别接口
+    rtSkipFaceCheckParam,//检查当前考生是否跳过人脸识别接口
+    rtGetWXUploadedFile //查询小程序端已上传的文件结果接口
 };
 };
 
 
 class CHttpRequestPackage
 class CHttpRequestPackage
@@ -1462,4 +1463,15 @@ class CSkipFaceCheckParam : public CBaseResponsePackage
 public:
 public:
     bool bSkipFaceCheck = false;
     bool bSkipFaceCheck = false;
 };
 };
+
+class CGetWXUploadedFile : public CBaseResponsePackage
+{
+public:
+    __int64 nExamRecordDataId = 0;
+    int nQuestionOrder = 0;
+    QString sFilePath = "";
+    QString sStatus = "";
+    QString sTransferFileType = "";
+};
+
 #endif // HTTPDATADEF_H
 #endif // HTTPDATADEF_H

+ 52 - 10
face/inprogressFace.cpp

@@ -5,6 +5,7 @@
 #include "CFaceRecProc.h"
 #include "CFaceRecProc.h"
 #include "CAppInfo.h"
 #include "CAppInfo.h"
 #include "json/json.h"
 #include "json/json.h"
+#include <QFileInfo>
 
 
 std::shared_ptr<CInprogressFace> g_inProcessFace = nullptr;
 std::shared_ptr<CInprogressFace> g_inProcessFace = nullptr;
 
 
@@ -163,7 +164,7 @@ void CInprogressFace::threadProc()
 
 
                 if(matImage.empty())
                 if(matImage.empty())
                 {
                 {
-                    myDebug()<<"matImage.empty";
+                    myServerLog()<<"matImage.empty";
                     continue;
                     continue;
                 }
                 }
 
 
@@ -171,12 +172,12 @@ void CInprogressFace::threadProc()
                 float fScore = 0;
                 float fScore = 0;
                 bool bRealness = false;
                 bool bRealness = false;
                 int nTime = 0;
                 int nTime = 0;
-                if(!g_faceRecProcPtr->getMaxFaceScoreWithBase(matImage, nFaceCount, fScore, bRealness, nTime))
+                if(!g_faceRecProcPtr->getMaxFaceScoreWithBase(matImage.clone(), nFaceCount, fScore, bRealness, nTime))
                 {
                 {
                     //比对失败
                     //比对失败
                     QString sErrorMsg = g_faceRecProcPtr->errorMsg();
                     QString sErrorMsg = g_faceRecProcPtr->errorMsg();
                     myDebug()<<QString::fromLocal8Bit("人脸检测失败:")<<sErrorMsg;
                     myDebug()<<QString::fromLocal8Bit("人脸检测失败:")<<sErrorMsg;
-                    uploadFile(matImage, nFaceCount, fScore, bRealness);
+                    uploadFile(matImage.clone(), nFaceCount, fScore, bRealness);
                     emit compareFailed(sErrorMsg);
                     emit compareFailed(sErrorMsg);
                 }
                 }
                 else
                 else
@@ -184,18 +185,18 @@ void CInprogressFace::threadProc()
                     if(nFaceCount == 0)
                     if(nFaceCount == 0)
                     {
                     {
                         //无人脸
                         //无人脸
-                        uploadFile(matImage, nFaceCount, fScore, bRealness);
+                        uploadFile(matImage.clone(), nFaceCount, fScore, bRealness);
                         emit compareFailed(QString::fromLocal8Bit("请让我看到您的正脸"));
                         emit compareFailed(QString::fromLocal8Bit("请让我看到您的正脸"));
                     }
                     }
                     else if(nFaceCount > 1 && g_appInfoPtr->m_oExamInfo.bIsStrangerEnable)
                     else if(nFaceCount > 1 && g_appInfoPtr->m_oExamInfo.bIsStrangerEnable)
                     {
                     {
                         //陌生人
                         //陌生人
-                        uploadFile(matImage, nFaceCount, fScore, bRealness);
+                        uploadFile(matImage.clone(), nFaceCount, fScore, bRealness);
                         emit compareFailed(QString::fromLocal8Bit("检测到陌生人"));
                         emit compareFailed(QString::fromLocal8Bit("检测到陌生人"));
                     }
                     }
 					else
 					else
 					{
 					{
-						uploadFile(matImage, nFaceCount, fScore, bRealness);
+                        uploadFile(matImage.clone(), nFaceCount, fScore, bRealness);
 					}
 					}
                 }
                 }
 
 
@@ -212,10 +213,49 @@ void CInprogressFace::uploadFile(cv::Mat faceMat, int nFaceCount, float fScore,
 {
 {
     QString sFileName = QString("temp/photo/%1.png").arg(CCommonTools::getUuid());
     QString sFileName = QString("temp/photo/%1.png").arg(CCommonTools::getUuid());
     QImage imgCompare = CCommonTools::Mat2QImage(faceMat);
     QImage imgCompare = CCommonTools::Mat2QImage(faceMat);
-    imgCompare.save(sFileName, "PNG");
+    if(imgCompare.isNull() || !imgCompare.save(sFileName, "PNG"))
+    {
+        myServerLog()<<"imgCompare is null:"<<imgCompare.isNull();
+        try
+        {
+            QFileInfo file(sFileName);
+            cv::imwrite(file.absoluteFilePath().toStdString(), faceMat);
+        }
+        catch (std::exception &e)
+        {
+            emit reAddImage();
+            myServerLog()<<"cv::imwrite failed reAddImage";
+            return;
+        }
+    }
+
+    QFile file(sFileName);
+    if(!file.exists())
+    {
+        emit reAddImage();
+        myServerLog()<<sFileName<<" is not exists reAddImage";
+        return;
+    }
+
+    if(!file.open(QIODevice::ReadOnly))
+    {
+        emit reAddImage();
+        myServerLog()<<"open file failed reAddImage";
+        return;
+    }
+
+    if(file.size() < 1024)
+    {
+        emit reAddImage();
+        myServerLog()<<"reAddImage, filesize < 1kb";
+        return;
+    }
+
+
 
 
     CHttpRequestPackage hrp;
     CHttpRequestPackage hrp;
     hrp.sUri = "/api/ecs_oe_student/client/exam/process/upload/sign";
     hrp.sUri = "/api/ecs_oe_student/client/exam/process/upload/sign";
+    hrp.nRetryCount = 10;
     hrp.nRequestType = RequestType::rtClientExamProcessUploadSign;
     hrp.nRequestType = RequestType::rtClientExamProcessUploadSign;
     hrp.sParamList.push_back(QString("fileSuffix,%1").arg(".png"));
     hrp.sParamList.push_back(QString("fileSuffix,%1").arg(".png"));
     hrp.sParamList.push_back(QString("fileMd5,%1").arg(CCommonTools::fileMd5(sFileName)));
     hrp.sParamList.push_back(QString("fileMd5,%1").arg(CCommonTools::fileMd5(sFileName)));
@@ -241,6 +281,7 @@ void CInprogressFace::onClientExamProcessUploadSign(CClientExamProcessUploadSign
 			if (processUpload.nCode == 200)
 			if (processUpload.nCode == 200)
 			{
 			{
                 CHttpRequestPackage hrp;
                 CHttpRequestPackage hrp;
+                hrp.nRetryCount = 10;
                 hrp.sUri = processUpload.sFormUrl;
                 hrp.sUri = processUpload.sFormUrl;
                 hrp.nRequestType = RequestType::rtUploadFileToAliyun;
                 hrp.nRequestType = RequestType::rtUploadFileToAliyun;
                 hrp.sCommonStr = QString("%1,%2,%3,%4").arg(__FILE__).arg(nFaceCount).arg(fScore).arg(nRealness);;
                 hrp.sCommonStr = QString("%1,%2,%3,%4").arg(__FILE__).arg(nFaceCount).arg(fScore).arg(nRealness);;
@@ -258,7 +299,7 @@ void CInprogressFace::onClientExamProcessUploadSign(CClientExamProcessUploadSign
 			}
 			}
 			else
 			else
 			{
 			{
-
+                emit reAddImage();
 			}
 			}
         }
         }
     }   
     }   
@@ -279,6 +320,7 @@ void CInprogressFace::onUploadFileToAliyun(CUploadFileToAliyun uploadFileToAliyu
             if (uploadFileToAliyun.nCode == 200)
             if (uploadFileToAliyun.nCode == 200)
             {
             {
                 CHttpRequestPackage hrp;
                 CHttpRequestPackage hrp;
+                hrp.nRetryCount = 10;
                 hrp.sUri = "/api/ecs_oe_student/client/exam/process/saveFaceCaptureResult";
                 hrp.sUri = "/api/ecs_oe_student/client/exam/process/saveFaceCaptureResult";
                 hrp.nRequestType = RequestType::rtSaveFaceCaptureResult;
                 hrp.nRequestType = RequestType::rtSaveFaceCaptureResult;
                 Json::Value jBody = Json::Value::null;
                 Json::Value jBody = Json::Value::null;
@@ -297,7 +339,7 @@ void CInprogressFace::onUploadFileToAliyun(CUploadFileToAliyun uploadFileToAliyu
             }
             }
             else
             else
             {
             {
-
+                emit reAddImage();
             }
             }
         }
         }
     }
     }
@@ -312,6 +354,6 @@ void CInprogressFace::onSaveFaceCaptureResult(CBaseResponsePackage res)
     }
     }
     else
     else
     {
     {
-
+        emit reAddImage();
     }
     }
 }
 }

+ 1 - 0
face/inprogressFace.h

@@ -13,6 +13,7 @@ class CInprogressFace : public QObject
 
 
 signals:
 signals:
     void compareFailed(QString sErrorMsg);
     void compareFailed(QString sErrorMsg);
+    void reAddImage();
 public:
 public:
     CInprogressFace();
     CInprogressFace();
     ~CInprogressFace();
     ~CInprogressFace();

+ 4 - 4
launcher/envCheck.cpp

@@ -223,7 +223,7 @@ void envCheck::checkProc()
 
 
         if(CCommonTools::isUseRDP())
         if(CCommonTools::isUseRDP())
         {
         {
-            sCheckStr = QString::fromLocal8Bit("请检测是否开启远程桌面");
+            sCheckStr = QString::fromLocal8Bit("请关闭远程桌面");
             qDebug()<<QString::fromLocal8Bit("环境检测异常,")<<sCheckStr;
             qDebug()<<QString::fromLocal8Bit("环境检测异常,")<<sCheckStr;
         }
         }
 
 
@@ -233,7 +233,7 @@ void envCheck::checkProc()
         {
         {
             if(sCheckStr.isEmpty())
             if(sCheckStr.isEmpty())
             {
             {
-                sCheckStr = QString::fromLocal8Bit("请检测是否开启分屏");
+                sCheckStr = QString::fromLocal8Bit("请关闭分屏");
             }
             }
             else
             else
             {
             {
@@ -259,7 +259,7 @@ void envCheck::checkProc()
                 {
                 {
                     if(sCheckStr.isEmpty())
                     if(sCheckStr.isEmpty())
                     {
                     {
-                        sCheckStr = QString::fromLocal8Bit("请检测是否存在虚拟摄像头%1").arg(ci.name);
+                        sCheckStr = QString::fromLocal8Bit("请关闭虚拟摄像头%1").arg(ci.name);
                     }
                     }
                     else
                     else
                     {
                     {
@@ -293,7 +293,7 @@ void envCheck::checkProc()
             {
             {
 //                if(sCheckStr.isEmpty())
 //                if(sCheckStr.isEmpty())
 //                {
 //                {
-                    sCheckStr = QString::fromLocal8Bit("请检测是否开启%1").arg(appList[i]);
+                    sCheckStr = QString::fromLocal8Bit("请关闭%1").arg(appList[i]);
                     m_unpasslist.push_back(sCheckStr);
                     m_unpasslist.push_back(sCheckStr);
 //                }
 //                }
 //                else
 //                else

BIN
launcher/images/coe.ico


+ 134 - 0
question/wxAnswer.cpp

@@ -26,6 +26,8 @@ wxAnswer::wxAnswer(QString sAnswerType, int nOrder, QWidget *parent) :
     connect(g_httpBllPtr.get(), &CHttpBll::sgnSaveUploadedFileAcknowledgeStatus, this, &wxAnswer::onSaveUploadedFileAcknowledgeStatus);
     connect(g_httpBllPtr.get(), &CHttpBll::sgnSaveUploadedFileAcknowledgeStatus, this, &wxAnswer::onSaveUploadedFileAcknowledgeStatus);
     qRegisterMetaType<CDownLoadFileInfo>("CDownLoadFileInfo");
     qRegisterMetaType<CDownLoadFileInfo>("CDownLoadFileInfo");
     connect(g_httpBllPtr.get(), &CHttpBll::sgnDownLoadFile, this, &wxAnswer::onDownLoadFile);
     connect(g_httpBllPtr.get(), &CHttpBll::sgnDownLoadFile, this, &wxAnswer::onDownLoadFile);
+    qRegisterMetaType<CGetWXUploadedFile>("CGetWXUploadedFile");
+    connect(g_httpBllPtr.get(), &CHttpBll::sgnGetWXUploadedFile, this, &wxAnswer::onGetWXUploadedFile);
 
 
     if (g_websocketPtr == nullptr)
     if (g_websocketPtr == nullptr)
     {
     {
@@ -129,6 +131,21 @@ wxAnswer::wxAnswer(QString sAnswerType, int nOrder, QWidget *parent) :
         }
         }
 
 
     });
     });
+
+    m_pRefreshTimer = std::make_shared<QTimer>();
+    m_pRefreshTimer->setInterval(1000);
+    connect(m_pRefreshTimer.get(), &QTimer::timeout, this, [&]() {
+        --m_nRefreshSeconds;
+        ui->btn_refresh->setText(QString::fromLocal8Bit("倒计时%1s").arg(m_nRefreshSeconds));
+
+
+        if(m_nRefreshSeconds <= 0)
+        {
+            m_pRefreshTimer->stop();
+            ui->btn_refresh->setEnabled(true);
+            ui->btn_refresh->setText(QString::fromLocal8Bit("刷新"));
+        }
+    });
 	
 	
 }
 }
 
 
@@ -305,6 +322,11 @@ int wxAnswer::setUI(const int nWidth)
         ui->label_wxa_status->setGeometry(ui->label_wxa_statusIcon->x() + ui->label_wxa_statusIcon->width() + g_appInfoPtr->m_fRate*10,
         ui->label_wxa_status->setGeometry(ui->label_wxa_statusIcon->x() + ui->label_wxa_statusIcon->width() + g_appInfoPtr->m_fRate*10,
                                           ui->label_wxa_statusIcon->y() + (ui->label_wxa_statusIcon->height() - ui->label_wxa_status->height())/2,
                                           ui->label_wxa_statusIcon->y() + (ui->label_wxa_statusIcon->height() - ui->label_wxa_status->height())/2,
                                           ui->label_wxa_status->width(), ui->label_wxa_status->height());
                                           ui->label_wxa_status->width(), ui->label_wxa_status->height());
+        ui->btn_refresh->setGeometry(g_appInfoPtr->m_fRate*20, ui->widget_wxa->height() - g_appInfoPtr->m_fRate*(30 + 30),
+                                     g_appInfoPtr->m_fRate*80, g_appInfoPtr->m_fRate*30);
+        ui->label_refreshTip->adjustSize();
+        ui->label_refreshTip->setGeometry(ui->btn_refresh->x() + ui->btn_refresh->width() + g_appInfoPtr->m_fRate*10, ui->btn_refresh->y() + ui->btn_refresh->height()/2 - ui->label_refreshTip->height()/2,
+                                          ui->label_refreshTip->width(), ui->label_refreshTip->height());
         ui->btn_wxa_comfirm->setGeometry((ui->widget_wxa->width() - g_appInfoPtr->m_fRate*120)/2, ui->widget_wxa->height() - g_appInfoPtr->m_fRate*(30 + 40),
         ui->btn_wxa_comfirm->setGeometry((ui->widget_wxa->width() - g_appInfoPtr->m_fRate*120)/2, ui->widget_wxa->height() - g_appInfoPtr->m_fRate*(30 + 40),
                                          g_appInfoPtr->m_fRate*120, g_appInfoPtr->m_fRate*40);
                                          g_appInfoPtr->m_fRate*120, g_appInfoPtr->m_fRate*40);
     }
     }
@@ -624,3 +646,115 @@ void wxAnswer::on_btn_etvt_volume_clicked()
     }
     }
     m_bMute = !m_bMute;
     m_bMute = !m_bMute;
 }
 }
+
+void wxAnswer::on_btn_refresh_clicked()
+{
+    ui->btn_refresh->setEnabled(false);
+
+    CHttpRequestPackage hrp;
+    hrp.sUri = "/api/ecs_oe_student/examControl/getUploadedFile";
+    hrp.nRequestType = RequestType::rtGetWXUploadedFile;
+    hrp.sParamList.push_back(QString("examRecordDataId,%1").arg(g_appInfoPtr->m_oExamInfo.nExamRecordDataId));
+    hrp.sParamList.push_back(QString("questionOrder,%1").arg(m_nOrder));
+    hrp.eParamType = HttpParamType::hptUrl;
+    g_httpBllPtr->post(hrp);
+
+    m_pRefreshTimer->start();
+    m_nRefreshSeconds = 20;
+    ui->btn_refresh->setText(QString::fromLocal8Bit("倒计时%1s").arg(m_nRefreshSeconds));
+}
+
+void wxAnswer::onGetWXUploadedFile(CGetWXUploadedFile getWXUploadedFile)
+{
+    if(getWXUploadedFile.nCode == 200)
+    {
+        if(getWXUploadedFile.sStatus == "UNCONFIRMED")
+        {
+            CHttpRequestPackage hrp;
+            hrp.sUri = "/api/ecs_oe_student/examControl/saveUploadedFileAcknowledgeStatus";
+            hrp.nRequestType = RequestType::rtSaveUploadedFileAcknowledgeStatus;
+            Json::Value jBody = Json::Value::null;
+            jBody["examRecordDataId"] = g_appInfoPtr->m_oExamInfo.nExamRecordDataId;
+            jBody["order"] = m_nOrder;
+            jBody["filePath"] = getWXUploadedFile.sFilePath.toStdString();
+            jBody["acknowledgeStatus"] = "CONFIRMED";
+            hrp.sParamList.push_back(QString("CustomBody,%1").arg(jBody.toStyledString().c_str()));
+            hrp.sCommonStr = getWXUploadedFile.sFilePath;
+            hrp.eParamType = HttpParamType::hptCustomBody;
+            g_httpBllPtr->post(hrp);
+
+
+            QString sFileUrl = getWXUploadedFile.sFilePath;
+            if(m_sAnswerType == "SINGLE_AUDIO")
+            {
+                m_sFileUrl = sFileUrl;
+                {
+                    QString sFileName = sFileUrl.right(sFileUrl.length() - sFileUrl.lastIndexOf("/") - 1);
+                    sFileName = g_appInfoPtr->m_sCacheFileDir + sFileName;
+                    CHttpRequestPackage hrp;
+                    hrp.sUri = sFileUrl;
+                    hrp.sCommonStr = sFileName;
+                    hrp.sCommonStr1 = __FILE__;
+                    hrp.nRequestType = RequestType::rtDownLoadFile;
+                    hrp.nRetryCount = 3;
+                    g_httpBllPtr->downLoad(hrp);
+                }
+            }
+            else
+            {
+                if(m_picList == nullptr)
+                {
+                    m_picList = std::make_shared<wPictureList>(g_appInfoPtr->m_fRate*108, g_appInfoPtr->m_fRate*10, ui->widget_wxa);
+                }
+
+                QStringList answerList = m_picList->getFileUrls().split(",");
+
+                QStringList fileList;
+                if(!sFileUrl.isEmpty())
+                {
+                    fileList = sFileUrl.split(",");
+                    for (QString sFile : fileList)
+                    {
+                        if(answerList.indexOf(sFile) < 0)
+                        {
+                            m_picList->AddPic(sFile);
+                        }
+                    }
+                }
+
+                if(m_picList->itemCount() > 5)
+                {
+                    ui->label_wxa_qrcode->setVisible(false);
+                }
+
+                int nHeight = m_picList->setUI(g_appInfoPtr->m_fRate*30, ui->label_wxa_qrcode->y() + ui->label_wxa_qrcode->height() + g_appInfoPtr->m_fRate*20,
+                                       ui->widget_wxa->width() - g_appInfoPtr->m_fRate*30*2);
+                ui->btn_refresh->setGeometry(g_appInfoPtr->m_fRate*20, ui->widget_wxa->height() - g_appInfoPtr->m_fRate*(30 + 30),
+                                             g_appInfoPtr->m_fRate*80, g_appInfoPtr->m_fRate*30);
+                ui->label_refreshTip->adjustSize();
+                ui->label_refreshTip->setGeometry(ui->btn_refresh->x() + ui->btn_refresh->width() + g_appInfoPtr->m_fRate*10, ui->btn_refresh->y() + ui->btn_refresh->height()/2 - ui->label_refreshTip->height()/2,
+                                                  ui->label_refreshTip->width(), ui->label_refreshTip->height());
+                ui->btn_wxa_comfirm->setGeometry((ui->widget_wxa->width() - g_appInfoPtr->m_fRate*120)/2, m_picList->y() + m_picList->height() + g_appInfoPtr->m_fRate*30,
+                                                 g_appInfoPtr->m_fRate*120, g_appInfoPtr->m_fRate*40);
+                ui->widget_wxa->setGeometry((width() - g_appInfoPtr->m_fRate*760)/2, (height() - (ui->btn_wxa_comfirm->y() + ui->btn_wxa_comfirm->height() + g_appInfoPtr->m_fRate*30))/2,
+                                            g_appInfoPtr->m_fRate*760, ui->btn_wxa_comfirm->y() + ui->btn_wxa_comfirm->height() + g_appInfoPtr->m_fRate*30);
+
+
+                m_picList->show();
+            }
+            ui->label_wxa_status->setText(QString::fromLocal8Bit("已上传"));
+            ShowMsg(QString::fromLocal8Bit("小程序作答已更新"), g_appInfoPtr->m_pAnsBgWidget, MSG_ICON_TYPE::mit_information);
+        }
+    }
+    else
+    {
+        if(getWXUploadedFile.sMessage.isEmpty())
+        {
+            ShowMsg(QString::fromLocal8Bit("同步拍照作答失败"), g_appInfoPtr->m_pAnsBgWidget, MSG_ICON_TYPE::mit_error);
+        }
+        else
+        {
+            ShowMsg(getWXUploadedFile.sMessage, g_appInfoPtr->m_pAnsBgWidget, MSG_ICON_TYPE::mit_error);
+        }
+    }
+}

+ 5 - 0
question/wxAnswer.h

@@ -35,6 +35,7 @@ private slots:
     void onFileAnswer(__int64 nExamRecordDataId, int nOrder, QString sFileType, QString sFileUrl);
     void onFileAnswer(__int64 nExamRecordDataId, int nOrder, QString sFileType, QString sFileUrl);
     void onSaveUploadedFileAcknowledgeStatus(CSaveUploadedFileAcknowledgeStatus saveUploadedFileAcknowledgeStatus);
     void onSaveUploadedFileAcknowledgeStatus(CSaveUploadedFileAcknowledgeStatus saveUploadedFileAcknowledgeStatus);
     void onDownLoadFile(CDownLoadFileInfo downLoadFileInfo);
     void onDownLoadFile(CDownLoadFileInfo downLoadFileInfo);
+    void onGetWXUploadedFile(CGetWXUploadedFile getWXUploadedFile);
 
 
 
 
     void on_btn_wxa_close_clicked();
     void on_btn_wxa_close_clicked();
@@ -49,12 +50,16 @@ private slots:
 
 
     void on_btn_etvt_volume_clicked();
     void on_btn_etvt_volume_clicked();
 
 
+    void on_btn_refresh_clicked();
+
 private:
 private:
     Ui::wxAnswer *ui;
     Ui::wxAnswer *ui;
     int m_nOrder;
     int m_nOrder;
     QString m_sAnswerType;
     QString m_sAnswerType;
     QString m_sFileUrl;
     QString m_sFileUrl;
     std::shared_ptr<wPictureList> m_picList;
     std::shared_ptr<wPictureList> m_picList;
+    std::shared_ptr<QTimer> m_pRefreshTimer;
+    int m_nRefreshSeconds = 20;
 
 
     int m_nPlayVol;
     int m_nPlayVol;
 
 

+ 26 - 0
question/wxAnswer.ui

@@ -234,6 +234,32 @@
       </property>
       </property>
      </widget>
      </widget>
     </widget>
     </widget>
+    <widget class="QPushButton" name="btn_refresh">
+     <property name="geometry">
+      <rect>
+       <x>10</x>
+       <y>360</y>
+       <width>93</width>
+       <height>28</height>
+      </rect>
+     </property>
+     <property name="text">
+      <string>刷新</string>
+     </property>
+    </widget>
+    <widget class="QLabel" name="label_refreshTip">
+     <property name="geometry">
+      <rect>
+       <x>100</x>
+       <y>370</y>
+       <width>72</width>
+       <height>15</height>
+      </rect>
+     </property>
+     <property name="text">
+      <string>同步拍照作答</string>
+     </property>
+    </widget>
    </widget>
    </widget>
   </widget>
   </widget>
  </widget>
  </widget>