courseList.cpp 51 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408
  1. #include "courseList.h"
  2. #include "ui_courseList.h"
  3. #include "awMsgBox.h"
  4. #include <QDesktopWidget>
  5. #include <QMouseEvent>
  6. #include "CAppInfo.h"
  7. #include "CSqlite3DBProc.h"
  8. courseList::courseList(QWidget *parent) :
  9. QWidget(parent),
  10. ui(new Ui::courseList)
  11. {
  12. ui->setupUi(this);
  13. setWindowFlags(Qt::FramelessWindowHint);
  14. setStyleSheet(g_appInfoPtr->m_sQssStr);
  15. ui->btn_minisize->setVisible(!g_appInfoPtr->m_bFullScreenTop);
  16. qRegisterMetaType<CGetStudentInfoBySession>("CGetStudentInfoBySession");
  17. connect(g_httpBllPtr.get(), &CHttpBll::sgnGetStudentInfoBySession, this, &courseList::onGetStudentInfoBySession);
  18. qRegisterMetaType<CSpecialtyNameList>("CSpecialtyNameList");
  19. connect(g_httpBllPtr.get(), &CHttpBll::sgnSpecialtyNameList, this, &courseList::onSpecialtyNameList);
  20. qRegisterMetaType<CCheckExamInProgress>("CCheckExamInProgress");
  21. connect(g_httpBllPtr.get(), &CHttpBll::sgnCheckExamInProgress, this, &courseList::onCheckExamInProgress);
  22. qRegisterMetaType<CGetStudentClientMenu>("CGetStudentClientMenu");
  23. connect(g_httpBllPtr.get(), &CHttpBll::sgnGetStudentClientMenu, this, &courseList::onGetStudentClientMenu);
  24. qRegisterMetaType<CGetUserNoticeList>("CGetUserNoticeList");
  25. connect(g_httpBllPtr.get(), &CHttpBll::sgnGetUserNoticeList, this, &courseList::onGetUserNoticeList);
  26. qRegisterMetaType<CDownLoadFileInfo>("CDownLoadFileInfo");
  27. connect(g_httpBllPtr.get(), &CHttpBll::sgnDownLoadFile, this, &courseList::onDownLoadFile);
  28. qRegisterMetaType<CAppDownLoadUrl>("CAppDownLoadUrl");
  29. connect(g_httpBllPtr.get(), &CHttpBll::sgnAppDownLoadUrl, this, &courseList::onAppDownLoadUrl);
  30. qRegisterMetaType<CStartExamLimit>("CStartExamLimit");
  31. connect(g_httpBllPtr.get(), &CHttpBll::sgnStartExamLimit, this, &courseList::onStartExamLimit);
  32. qRegisterMetaType<CIpLimit>("CIpLimit");
  33. connect(g_httpBllPtr.get(), &CHttpBll::sgnIpLimit, this, &courseList::onIpLimit);
  34. qRegisterMetaType<CGetExamProperty>("CGetExamProperty");
  35. connect(g_httpBllPtr.get(), &CHttpBll::sgnGetExamProperty, this, &courseList::onGetExamProperty);
  36. qRegisterMetaType<CFaceCheckEnabled>("CFaceCheckEnabled");
  37. connect(g_httpBllPtr.get(), &CHttpBll::sgnFaceCheckEnabled, this, &courseList::onFaceCheckEnabled);
  38. qRegisterMetaType<CLivenessEnabled>("CLivenessEnabled");
  39. connect(g_httpBllPtr.get(), &CHttpBll::sgnLivenessEnabled, this, &courseList::onLivenessEnabled);
  40. qRegisterMetaType<CEndExam>("CEndExam");
  41. connect(g_httpBllPtr.get(), &CHttpBll::sgnEndExam, this, &courseList::onEndExam);
  42. qRegisterMetaType<CGetOrgPropertiesByGroupWithoutCache>("CGetOrgPropertiesByGroupWithoutCache");
  43. connect(g_httpBllPtr.get(), &CHttpBll::sgnGetOrgPropertiesByGroupWithoutCache, this, &courseList::onGetOrgPropertiesByGroupWithoutCache);
  44. sqlite3_stmt *stmt;
  45. QString sSql = QString("select agreement from t_agreement where student_id=%1")
  46. .arg(g_appInfoPtr->m_nStudentId);
  47. if (!g_sysDBProcPtr->QuerySql(sSql.toStdString(), &stmt))
  48. {
  49. ShowMsg(QString::fromLocal8Bit("加载隐私协议信息失败!"), this, MSG_ICON_TYPE::mit_error);
  50. }
  51. bool bAgreement = false;
  52. int nField = 0;
  53. g_sysDBProcPtr->BeginGetFields(stmt);
  54. if (!g_sysDBProcPtr->Eof())
  55. {
  56. if (g_sysDBProcPtr->GetFields(0, nField, stmt) == 1)
  57. {
  58. bAgreement = true;
  59. }
  60. }
  61. g_sysDBProcPtr->EndGetFields(stmt);
  62. if (!bAgreement)
  63. {
  64. if (m_pPrivacyWidget == nullptr)
  65. {
  66. m_pPrivacyWidget = std::make_shared<privacyWidget>(this);
  67. connect(m_pPrivacyWidget.get(), &privacyWidget::agreement, this, [&]() {
  68. m_pPrivacyWidget.reset();
  69. getStudentInfoBySession();
  70. });
  71. connect(m_pPrivacyWidget.get(), &privacyWidget::disAgreement, this, [&]() {
  72. on_btn_exit_clicked();
  73. });
  74. }
  75. m_pPrivacyWidget->show();
  76. }
  77. else
  78. {
  79. getStudentInfoBySession();
  80. }
  81. initUI();
  82. m_pMobileLogin = nullptr;
  83. m_pStudentInfo = nullptr;
  84. m_pMobileLoginBtnTimer = std::make_shared<QTimer>();
  85. m_pMobileLoginBtnTimer->setInterval(500);
  86. connect(m_pMobileLoginBtnTimer.get(), &QTimer::timeout, this, &courseList::hideMobileLoginBtn);
  87. m_pStudentInfoBtnTimer = std::make_shared<QTimer>();
  88. m_pStudentInfoBtnTimer->setInterval(500);
  89. connect(m_pStudentInfoBtnTimer.get(), &QTimer::timeout, this, &courseList::hideStudentInfoBtn);
  90. m_pServerTime = std::make_shared<QTimer>();
  91. m_pServerTime->setInterval(1000);
  92. connect(m_pServerTime.get(), &QTimer::timeout, this, [&]() {
  93. ui->label_serverTime->adjustSize();
  94. ui->label_serverTime->setText(QString::fromLocal8Bit("服务器时间:%1")
  95. .arg(QDateTime::fromMSecsSinceEpoch(g_appInfoPtr->serverMTime()).toString("yyyy-MM-dd hh:mm:ss")));
  96. });
  97. m_pServerTime->start();
  98. m_pRefreshMenuTimer = std::make_shared<QTimer>();
  99. m_pRefreshMenuTimer->setInterval(1000 * 60 * 3);
  100. connect(m_pRefreshMenuTimer.get(), &QTimer::timeout, this, []() {
  101. CHttpRequestPackage hrp;
  102. hrp.sUri = "/api/ecs_core/rolePrivilege/getStudentClientMenu";
  103. hrp.nRequestType = RequestType::rtGetStudentClientMenu;
  104. hrp.sParamList.push_back(QString::fromLocal8Bit("rootOrgId,%1").arg(g_appInfoPtr->m_sRootOrgId));
  105. g_httpBllPtr->get(hrp);
  106. });
  107. m_pOnlineTimer = std::make_shared<QTimer>();
  108. m_pOnlineTimer->setInterval(1000*60*3);
  109. connect(m_pOnlineTimer.get(), &QTimer::timeout, this, []() {
  110. CHttpRequestPackage hrp1;
  111. hrp1.sUri = "/api/ecs_core/student/online_signal/" + QString::number(g_appInfoPtr->m_nStudentId);
  112. hrp1.nRequestType = RequestType::rtOnlineSignal;
  113. g_httpBllPtr->get(hrp1);
  114. });
  115. ui->btn_mobileLogin->installEventFilter(this);
  116. ui->btn_studentInfo->installEventFilter(this);
  117. m_pOnlineTimer->start();
  118. m_pRefreshMenuTimer->start();
  119. if (!g_appInfoPtr->m_sMenuLogoUrl.isEmpty())
  120. {
  121. QString sFileName = g_appInfoPtr->m_sMenuLogoUrl.right(g_appInfoPtr->m_sMenuLogoUrl.length() - g_appInfoPtr->m_sMenuLogoUrl.lastIndexOf("/") - 1);
  122. sFileName = g_appInfoPtr->m_sCacheFileDir + sFileName;
  123. CHttpRequestPackage hrp;
  124. hrp.sUri = g_appInfoPtr->m_sMenuLogoUrl;
  125. hrp.sCommonStr = sFileName;
  126. hrp.sCommonStr1 = __FILE__;
  127. hrp.sAdditionStr = "MenuLogoUrl";
  128. hrp.nRequestType = RequestType::rtDownLoadFile;
  129. hrp.nRetryCount = 3;
  130. g_httpBllPtr->downLoad(hrp);
  131. }
  132. else
  133. {
  134. ui->label_cl_org_icon->setPixmap(QPixmap(":/images/qm-logo.png").scaled(ui->label_cl_org_icon->width(), ui->label_cl_org_icon->height(),
  135. Qt::KeepAspectRatio, Qt::SmoothTransformation));
  136. }
  137. }
  138. courseList::~courseList()
  139. {
  140. awMsgBox::clear(this);
  141. delete ui;
  142. }
  143. void courseList::initUI()
  144. {
  145. QDesktopWidget *dekwiget = QApplication::desktop();
  146. setGeometry(0, 0, dekwiget->width(), dekwiget->height());
  147. ui->label_cl_company->setVisible(false);
  148. ui->widget_cl_BG->setGeometry(0, 0, dekwiget->width(), dekwiget->height());
  149. ui->widget_menu->setGeometry(0, 0, g_appInfoPtr->m_fRate*96, height());
  150. ui->widget_top->setGeometry(ui->widget_menu->width(), 0, width() - ui->widget_menu->width(), g_appInfoPtr->m_fRate*56);
  151. ui->widget_bottom->setGeometry(ui->widget_top->x(), height() - g_appInfoPtr->m_fRate*38, ui->widget_top->width(), g_appInfoPtr->m_fRate*38);
  152. ui->stw_courseList->setGeometry(ui->widget_top->x(), ui->widget_top->y() + ui->widget_top->height(),
  153. ui->widget_top->width(), height() - ui->widget_top->height() - ui->widget_bottom->height());
  154. /*
  155. clOnlineExam *cloe = new clOnlineExam;
  156. cloe->setUI(ui->stw_courseList->width(), ui->stw_courseList->height());
  157. ui->stw_courseList->addWidget(cloe);
  158. clOnlineHomework *clow = new clOnlineHomework;
  159. clow->setUI(ui->stw_courseList->width(), ui->stw_courseList->height());
  160. ui->stw_courseList->addWidget(clow);
  161. clOnlinePractice *clop = new clOnlinePractice;
  162. clop->setUI(ui->stw_courseList->width(), ui->stw_courseList->height());
  163. ui->stw_courseList->addWidget(clop);
  164. clOfflineExam *cloffe = new clOfflineExam;
  165. cloffe->setUI(ui->stw_courseList->width(), ui->stw_courseList->height());
  166. ui->stw_courseList->addWidget(cloffe);
  167. clNoticeList *clnl = new clNoticeList;
  168. clnl->setUI(ui->stw_courseList->width(), ui->stw_courseList->height());
  169. ui->stw_courseList->addWidget(clnl);
  170. clEditPassword *clep = new clEditPassword;
  171. clep->setUI(ui->stw_courseList->width(), ui->stw_courseList->height());
  172. ui->stw_courseList->addWidget(clep);
  173. ui->stw_courseList->setCurrentIndex(0);
  174. */
  175. ui->label_cl_org_icon->setGeometry(g_appInfoPtr->m_fRate*15, g_appInfoPtr->m_fRate*15, g_appInfoPtr->m_fRate*66, g_appInfoPtr->m_fRate*66);
  176. ui->btn_onlineExam->setGeometry(g_appInfoPtr->m_fRate*20, g_appInfoPtr->m_fRate*103, g_appInfoPtr->m_fRate*56, g_appInfoPtr->m_fRate*66);
  177. ui->btn_onlineHomework->setGeometry(ui->btn_onlineExam->x(), ui->btn_onlineExam->y() + ui->btn_onlineExam->height() + g_appInfoPtr->m_fRate*17,
  178. ui->btn_onlineExam->width(), ui->btn_onlineExam->height());
  179. ui->btn_onlinePractice->setGeometry(ui->btn_onlineExam->x(), ui->btn_onlineHomework->y() + ui->btn_onlineHomework->height() + g_appInfoPtr->m_fRate*17,
  180. ui->btn_onlineExam->width(), ui->btn_onlineExam->height());
  181. ui->btn_offlineExam->setGeometry(ui->btn_onlineExam->x(), ui->btn_onlinePractice->y() + ui->btn_onlinePractice->height() + g_appInfoPtr->m_fRate*17,
  182. ui->btn_onlineExam->width(), ui->btn_onlineExam->height());
  183. ui->btn_notice->setGeometry(ui->btn_onlineExam->x(), ui->btn_offlineExam->y() + ui->btn_offlineExam->height() + g_appInfoPtr->m_fRate*17,
  184. ui->btn_onlineExam->width(), ui->btn_onlineExam->height());
  185. ui->btn_noticeNum->setGeometry(ui->btn_notice->x() + ui->btn_notice->width() - g_appInfoPtr->m_fRate*16, ui->btn_notice->y(),
  186. g_appInfoPtr->m_fRate*16, g_appInfoPtr->m_fRate*16);
  187. ui->btn_noticeNum->setVisible(false);
  188. ui->btn_editPassword->setGeometry(ui->btn_onlineExam->x(), ui->btn_notice->y() + ui->btn_notice->height() + g_appInfoPtr->m_fRate*17,
  189. ui->btn_onlineExam->width(), ui->btn_onlineExam->height());
  190. ui->label_currentPlaceIcon->setGeometry(g_appInfoPtr->m_fRate*30, (ui->widget_top->height() - g_appInfoPtr->m_fRate*10)/2,
  191. g_appInfoPtr->m_fRate*10, g_appInfoPtr->m_fRate*10);
  192. ui->label_currrentPlace->adjustSize();
  193. ui->label_currrentPlace->setGeometry(ui->label_currentPlaceIcon->x() + ui->label_currentPlaceIcon->width() + g_appInfoPtr->m_fRate*10,
  194. (ui->widget_top->height() - ui->label_currrentPlace->height())/2, g_appInfoPtr->m_fRate*400, ui->label_currrentPlace->height());
  195. ui->btn_cl_close->setGeometry(ui->widget_top->width() - g_appInfoPtr->m_fRate*10 - g_appInfoPtr->m_fRate*24, g_appInfoPtr->m_fRate*16,
  196. g_appInfoPtr->m_fRate*24, g_appInfoPtr->m_fRate*24);
  197. ui->btn_minisize->setGeometry(ui->btn_cl_close->x() - g_appInfoPtr->m_fRate*6 - ui->btn_cl_close->width(), ui->btn_cl_close->y(),
  198. ui->btn_cl_close->width(), ui->btn_cl_close->height());
  199. ui->label_VLine->setGeometry(ui->btn_minisize->x() - g_appInfoPtr->m_fRate*21, ui->btn_cl_close->y(),
  200. g_appInfoPtr->m_fRate*1 < 1 ? 1 : g_appInfoPtr->m_fRate*1, g_appInfoPtr->m_fRate*24);
  201. ui->btn_exit->setGeometry(ui->label_VLine->x() - g_appInfoPtr->m_fRate*(20+24), ui->btn_cl_close->y(),
  202. ui->btn_cl_close->width(), ui->btn_cl_close->height());
  203. ui->btn_studentInfo->setGeometry(ui->btn_exit->x() - g_appInfoPtr->m_fRate*(10+90), ui->btn_cl_close->y(),
  204. g_appInfoPtr->m_fRate*90, g_appInfoPtr->m_fRate*24);
  205. ui->btn_studentInfo->setIconSize(QSize(g_appInfoPtr->m_fRate*8, g_appInfoPtr->m_fRate*8));
  206. ui->btn_studentInfo->setIcon(QIcon(":/images/icon-student-info.png"));
  207. ui->label_arrow->setGeometry(ui->btn_studentInfo->x() + (ui->btn_studentInfo->width() - g_appInfoPtr->m_fRate*12)/2,
  208. ui->btn_studentInfo->y() + ui->btn_studentInfo->height(),
  209. g_appInfoPtr->m_fRate*12, g_appInfoPtr->m_fRate*3);
  210. ui->label_arrow->setVisible(false);
  211. ui->btn_mobileLogin->setGeometry(ui->btn_studentInfo->x() - g_appInfoPtr->m_fRate*(10+167), ui->btn_cl_close->y(),
  212. g_appInfoPtr->m_fRate*167, g_appInfoPtr->m_fRate*24);
  213. ui->btn_mobileLogin->setIconSize(QSize(g_appInfoPtr->m_fRate*8, g_appInfoPtr->m_fRate*8));
  214. ui->btn_mobileLogin->setIcon(QIcon(":/images/icon-mobile-login.png"));
  215. ui->label_cl_company->adjustSize();
  216. ui->label_cl_company->setGeometry(g_appInfoPtr->m_fRate*30, (ui->widget_bottom->height() - ui->label_cl_company->height())/2,
  217. ui->label_cl_company->width(), ui->label_cl_company->height());
  218. ui->label_cl_version->adjustSize();
  219. ui->label_cl_version->setGeometry(ui->widget_bottom->width() - g_appInfoPtr->m_fRate*30 - ui->label_cl_version->width(),
  220. ui->label_cl_company->y(), ui->label_cl_version->width(), ui->label_cl_version->height());
  221. ui->label_serverTime->setText(QString::fromLocal8Bit("服务器时间:%1")
  222. .arg(QDateTime::fromMSecsSinceEpoch(g_appInfoPtr->serverMTime()).toString("yyyy-MM-dd hh:mm:ss")));
  223. ui->label_serverTime->adjustSize();
  224. ui->label_serverTime->setGeometry(ui->label_cl_version->x() - g_appInfoPtr->m_fRate*20 - ui->label_serverTime->width(), ui->label_cl_company->y(),
  225. ui->label_serverTime->width(), ui->label_serverTime->height());
  226. setCheck(COURSE_MENU_BTN_TYPE::cmbt_online_exam);
  227. }
  228. void courseList::menuBtnRePosistion()
  229. {
  230. int nTop = g_appInfoPtr->m_fRate * 103;
  231. if(ui->btn_onlineExam->isVisible())
  232. {
  233. ui->btn_onlineExam->setGeometry(g_appInfoPtr->m_fRate * 20, nTop, g_appInfoPtr->m_fRate * 56, g_appInfoPtr->m_fRate * 66);
  234. nTop = nTop + ui->btn_onlineExam->height() + g_appInfoPtr->m_fRate * 17;
  235. }
  236. if(ui->btn_onlineHomework->isVisible())
  237. {
  238. ui->btn_onlineHomework->setGeometry(ui->btn_onlineExam->x(), nTop,
  239. ui->btn_onlineExam->width(), ui->btn_onlineExam->height());
  240. nTop = nTop + ui->btn_onlineExam->height() + g_appInfoPtr->m_fRate * 17;
  241. }
  242. if (ui->btn_onlinePractice->isVisible())
  243. {
  244. ui->btn_onlinePractice->setGeometry(ui->btn_onlineExam->x(), nTop,
  245. ui->btn_onlineExam->width(), ui->btn_onlineExam->height());
  246. nTop = nTop + ui->btn_onlineExam->height() + g_appInfoPtr->m_fRate * 17;
  247. }
  248. if (ui->btn_offlineExam->isVisible())
  249. {
  250. ui->btn_offlineExam->setGeometry(ui->btn_onlineExam->x(), nTop,
  251. ui->btn_onlineExam->width(), ui->btn_onlineExam->height());
  252. nTop = nTop + ui->btn_onlineExam->height() + g_appInfoPtr->m_fRate * 17;
  253. }
  254. if (ui->btn_notice->isVisible())
  255. {
  256. ui->btn_notice->setGeometry(ui->btn_onlineExam->x(), nTop,
  257. ui->btn_onlineExam->width(), ui->btn_onlineExam->height());
  258. ui->btn_noticeNum->setGeometry(ui->btn_notice->x() + ui->btn_notice->width() - g_appInfoPtr->m_fRate * 16, ui->btn_notice->y(),
  259. g_appInfoPtr->m_fRate * 16, g_appInfoPtr->m_fRate * 16);
  260. nTop = nTop + ui->btn_onlineExam->height() + g_appInfoPtr->m_fRate * 17;
  261. }
  262. if (ui->btn_editPassword->isVisible())
  263. {
  264. ui->btn_editPassword->setGeometry(ui->btn_onlineExam->x(), ui->btn_notice->y() + ui->btn_notice->height() + g_appInfoPtr->m_fRate * 17,
  265. ui->btn_onlineExam->width(), ui->btn_onlineExam->height());
  266. }
  267. }
  268. void courseList::on_btn_minisize_clicked()
  269. {
  270. emit minisize();
  271. }
  272. void courseList::on_btn_cl_close_clicked()
  273. {
  274. // logout();
  275. // close();
  276. QCoreApplication::quit();
  277. }
  278. void courseList::setCheck(COURSE_MENU_BTN_TYPE cmbt)
  279. {
  280. QString sNormalSheet = QString(R"(outline:none;
  281. font-size:%1px;
  282. font-family:"Microsoft YaHei";
  283. font-weight:400;
  284. color:rgba(255,255,255,0.4);
  285. background:rgba(255,255,255,0);
  286. border-radius:%2;)").arg((int)(g_appInfoPtr->m_fRate*12)).arg(g_appInfoPtr->m_fRate*12);
  287. QString sCheckSheet = QString(R"(QPushButton
  288. {
  289. outline:none;
  290. font-size:%1px;
  291. font-family:"Microsoft YaHei";
  292. font-weight:400;
  293. color:rgba(255,255,255,1);
  294. border-radius:%2px;
  295. background:qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(16, 195, 182, 1), stop:1 rgba(39, 217, 146, 1));
  296. })").arg((int)(g_appInfoPtr->m_fRate*12)).arg(g_appInfoPtr->m_fRate*12);
  297. ui->btn_onlineExam->setStyleSheet(sNormalSheet);
  298. ui->btn_onlineHomework->setStyleSheet(sNormalSheet);
  299. ui->btn_onlinePractice->setStyleSheet(sNormalSheet);
  300. ui->btn_offlineExam->setStyleSheet(sNormalSheet);
  301. ui->btn_notice->setStyleSheet(sNormalSheet);
  302. ui->btn_editPassword->setStyleSheet(sNormalSheet);
  303. if (m_pOnlineExam != nullptr)
  304. {
  305. m_pOnlineExam->hide();
  306. }
  307. if (m_pOnlineHomework != nullptr)
  308. {
  309. m_pOnlineHomework->hide();
  310. }
  311. if (m_pOnlinePractice != nullptr)
  312. {
  313. m_pOnlinePractice->hide();
  314. m_pOnlinePractice->releaseClopResult();
  315. }
  316. if (m_pClopReport != nullptr)
  317. {
  318. m_pClopReport->hide();
  319. }
  320. if (m_pOfflineExam != nullptr)
  321. {
  322. m_pOfflineExam->hide();
  323. }
  324. if (m_pNoticeList != nullptr)
  325. {
  326. m_pNoticeList->hide();
  327. }
  328. if (m_pEditPassword != nullptr)
  329. {
  330. m_pEditPassword->hide();
  331. }
  332. QString sCurrentPlace = "";
  333. if (cmbt == COURSE_MENU_BTN_TYPE::cmbt_online_exam)
  334. {
  335. if (m_pOnlineExam == nullptr)
  336. {
  337. m_pOnlineExam = std::make_shared<clOnlineExam>(ui->stw_courseList);
  338. m_pOnlineExam->setUI(ui->stw_courseList->width(), ui->stw_courseList->height());
  339. connect(m_pOnlineExam.get(), &clOnlineExam::enterExam, this, &courseList::onEnterExam);
  340. }
  341. m_pOnlineExam->show();
  342. ui->btn_onlineExam->setStyleSheet(sCheckSheet);
  343. sCurrentPlace = QString::fromLocal8Bit("当前所在位置:在线考试");
  344. }
  345. else if(cmbt == COURSE_MENU_BTN_TYPE::cmbt_online_homework)
  346. {
  347. if (m_pOnlineHomework == nullptr)
  348. {
  349. m_pOnlineHomework = std::make_shared<clOnlineHomework>(ui->stw_courseList);
  350. m_pOnlineHomework->setUI(ui->stw_courseList->width(), ui->stw_courseList->height());
  351. connect(m_pOnlineHomework.get(), &clOnlineHomework::enterExam, this, &courseList::onEnterExam);
  352. }
  353. m_pOnlineHomework->show();
  354. ui->btn_onlineHomework->setStyleSheet(sCheckSheet);
  355. sCurrentPlace = QString::fromLocal8Bit("当前所在位置:在线作业");
  356. }
  357. else if(cmbt == COURSE_MENU_BTN_TYPE::cmbt_online_practice)
  358. {
  359. if (m_pOnlinePractice == nullptr)
  360. {
  361. m_pOnlinePractice = std::make_shared<clOnlinePractice>(ui->stw_courseList);
  362. m_pOnlinePractice->setUI(ui->stw_courseList->width(), ui->stw_courseList->height());
  363. connect(m_pOnlinePractice.get(), &clOnlinePractice::enterExam, this, &courseList::onEnterExam);
  364. }
  365. m_pOnlinePractice->show();
  366. ui->btn_onlinePractice->setStyleSheet(sCheckSheet);
  367. sCurrentPlace = QString::fromLocal8Bit("当前所在位置:在线练习");
  368. }
  369. else if(cmbt == COURSE_MENU_BTN_TYPE::cmbt_offline_exam)
  370. {
  371. if (m_pOfflineExam == nullptr)
  372. {
  373. m_pOfflineExam = std::make_shared<clOfflineExam>(ui->stw_courseList);
  374. m_pOfflineExam->setUI(ui->stw_courseList->width(), ui->stw_courseList->height());
  375. }
  376. m_pOfflineExam->show();
  377. ui->btn_offlineExam->setStyleSheet(sCheckSheet);
  378. sCurrentPlace = QString::fromLocal8Bit("当前所在位置:离线考试");
  379. }
  380. else if(cmbt == COURSE_MENU_BTN_TYPE::cmbt_notice)
  381. {
  382. if (m_pNoticeList == nullptr)
  383. {
  384. m_pNoticeList = std::make_shared<clNoticeList>(ui->stw_courseList);
  385. m_pNoticeList->setUI(ui->stw_courseList->width(), ui->stw_courseList->height());
  386. }
  387. m_pNoticeList->show();
  388. ui->btn_notice->setStyleSheet(sCheckSheet);
  389. sCurrentPlace = QString::fromLocal8Bit("当前所在位置:公告通知");
  390. }
  391. else if(cmbt == COURSE_MENU_BTN_TYPE::cmbt_edit_password)
  392. {
  393. if (m_pEditPassword == nullptr)
  394. {
  395. m_pEditPassword = std::make_shared<clEditPassword>(ui->stw_courseList);
  396. m_pEditPassword->setUI(ui->stw_courseList->width(), ui->stw_courseList->height());
  397. }
  398. m_pEditPassword->show();
  399. ui->btn_editPassword->setStyleSheet(sCheckSheet);
  400. sCurrentPlace = QString::fromLocal8Bit("当前所在位置:修改密码");
  401. }
  402. ui->label_currrentPlace->setText(sCurrentPlace);
  403. }
  404. void courseList::onEnterExam(CL_OPERATION_TYPE cot, __int64 nExamId, __int64 nExamStudentId, QString sCourseCode, QString sCourseName)
  405. {
  406. if(cot == CL_OPERATION_TYPE::cot_online_exam)
  407. {
  408. g_appInfoPtr->m_oExamInfo.sExamType = EXAM_TYPES::ONLINE;
  409. }
  410. g_appInfoPtr->m_oExamInfo.nExamId = nExamId;
  411. g_appInfoPtr->m_oExamInfo.nExamStudentId = nExamStudentId;
  412. g_appInfoPtr->m_oExamInfo.sCourseCode = sCourseCode;
  413. g_appInfoPtr->m_oExamInfo.sCourseName = sCourseName;
  414. //开考限流
  415. m_nRetryCount = 0;
  416. CHttpRequestPackage hrp;
  417. hrp.sUri = QString("https://tcc.qmth.com.cn/rate_limit/prod/startExam/%1").arg(100);
  418. hrp.nRequestType = RequestType::rtStartExamLimit;
  419. g_httpBllPtr->getUrl(hrp);
  420. }
  421. void courseList::onStartExamLimit(CStartExamLimit startExamLimit)
  422. {
  423. if (startExamLimit.nCode == 200)
  424. {
  425. ++m_nRetryCount;
  426. if (startExamLimit.bPass)
  427. {
  428. CHttpRequestPackage hrp;
  429. hrp.sUri = QString("/api/ecs_exam_work/exam/ipLimit/%1").arg(g_appInfoPtr->m_oExamInfo.nExamId);
  430. hrp.nRequestType = RequestType::rtIpLimit;
  431. g_httpBllPtr->get(hrp);
  432. }
  433. else
  434. {
  435. //重试
  436. if(m_nRetryCount >= 3)
  437. {
  438. ShowMsg(QString::fromLocal8Bit("系统繁忙,请稍后重试"), this, MSG_ICON_TYPE::mit_error);
  439. }
  440. else
  441. {
  442. QTimer::singleShot(3*1000, this, [](){
  443. CHttpRequestPackage hrp;
  444. hrp.sUri = QString("https://tcc.qmth.com.cn/rate_limit/prod/startExam/%1").arg(100);
  445. hrp.nRequestType = RequestType::rtStartExamLimit;
  446. g_httpBllPtr->getUrl(hrp);
  447. });
  448. }
  449. }
  450. }
  451. else
  452. {
  453. ShowMsg(QString::fromLocal8Bit("开考失败"), this, MSG_ICON_TYPE::mit_error);
  454. }
  455. }
  456. void courseList::onIpLimit(CIpLimit ipLimit)
  457. {
  458. if (ipLimit.nCode == 200)
  459. {
  460. if (!ipLimit.bLimited)
  461. {
  462. //断点
  463. CHttpRequestPackage hrp;
  464. hrp.sUri = "/api/ecs_oe_student/client/exam/process/checkExamInProgress";
  465. hrp.nRequestType = RequestType::rtCheckExamInProgress;
  466. hrp.sCommonStr = EXAM_INPROGRESS_ENTER_TYPE::EIET_ENTER_EXAM;
  467. g_httpBllPtr->post(hrp);
  468. }
  469. else
  470. {
  471. ShowMsg(QString::fromLocal8Bit("当前ip限制参加考试"), this, MSG_ICON_TYPE::mit_error);
  472. }
  473. }
  474. else
  475. {
  476. ShowMsg(QString::fromLocal8Bit("开考失败"), this, MSG_ICON_TYPE::mit_error);
  477. }
  478. }
  479. void courseList::onGetExamProperty(CGetExamProperty getExamProperty)
  480. {
  481. if (getExamProperty.nCode == 200)
  482. {
  483. if (getExamProperty.sType == "CHECK_ENVIRONMENT,IS_FACE_CHECK,SNAPSHOT_INTERVAL,FACE_VERIFY_START_MINUTE,FACE_VERIFY_END_MINUTE,IS_STRANGER_ENABLE,IS_FACE_VERIFY_BEFORE")
  484. {
  485. g_appInfoPtr->m_oExamInfo.bIsFaceCheck = getExamProperty.bIsFaceCheck;
  486. // g_appInfoPtr->m_oExamInfo.nFaceThreshold = getExamProperty.nFaceThreshold;
  487. g_appInfoPtr->m_oExamInfo.nSnapshotInterval = getExamProperty.nSnapshotInterval;
  488. g_appInfoPtr->m_oExamInfo.nFaceVerifyStartMinute = getExamProperty.nFaceVerifyStartMinute;
  489. g_appInfoPtr->m_oExamInfo.nFaceVerifyEndMinute = getExamProperty.nFaceVerifyEndMinute;
  490. g_appInfoPtr->m_oExamInfo.bIsStrangerEnable = getExamProperty.bIsStrangerEnable;
  491. g_appInfoPtr->m_oExamInfo.bIsLivenessBefore = getExamProperty.bIsLivenessBefore;
  492. if (getExamProperty.bCheckEnvironment && !g_appInfoPtr->m_oExamInfo.bIsExamInProgress)
  493. {
  494. if(m_pWhetherEnvTest == nullptr)
  495. {
  496. m_pWhetherEnvTest = std::make_shared<etWhetherEnvTest>(this);
  497. connect(m_pWhetherEnvTest.get(), &etWhetherEnvTest::envTest, this, [&](){
  498. m_pWhetherEnvTest.reset();
  499. //环境检测
  500. if (m_pEnvironmentalTest == nullptr)
  501. {
  502. m_pEnvironmentalTest = std::make_shared<environmentalTest>(this);
  503. connect(m_pEnvironmentalTest.get(), &environmentalTest::enterExam, this, [&](){
  504. m_pEnvironmentalTest.reset();
  505. //人脸识别
  506. CHttpRequestPackage hrp;
  507. hrp.sUri = QString("/api/ecs_exam_work/exam/faceCheckEnabled/%1")
  508. .arg(g_appInfoPtr->m_oExamInfo.nExamId);
  509. hrp.nRequestType = RequestType::rtFaceCheckEnabled;
  510. g_httpBllPtr->get(hrp);
  511. });
  512. }
  513. m_pEnvironmentalTest->show();
  514. });
  515. connect(m_pWhetherEnvTest.get(), &etWhetherEnvTest::skipEnvTest, this, [&](){
  516. m_pWhetherEnvTest.reset();
  517. //人脸识别
  518. CHttpRequestPackage hrp;
  519. hrp.sUri = QString("/api/ecs_exam_work/exam/faceCheckEnabled/%1")
  520. .arg(g_appInfoPtr->m_oExamInfo.nExamId);
  521. hrp.nRequestType = RequestType::rtFaceCheckEnabled;
  522. g_httpBllPtr->get(hrp);
  523. });
  524. }
  525. m_pWhetherEnvTest->show();
  526. }
  527. else
  528. {
  529. //人脸识别
  530. CHttpRequestPackage hrp;
  531. hrp.sUri = QString("/api/ecs_exam_work/exam/faceCheckEnabled/%1")
  532. .arg(g_appInfoPtr->m_oExamInfo.nExamId);
  533. hrp.nRequestType = RequestType::rtFaceCheckEnabled;
  534. g_httpBllPtr->get(hrp);
  535. }
  536. }
  537. }
  538. else
  539. {
  540. if(getExamProperty.sMessage.isEmpty())
  541. {
  542. ShowMsg(QString::fromLocal8Bit("获取考试信息失败"), this, MSG_ICON_TYPE::mit_error);
  543. }
  544. else
  545. {
  546. ShowMsg(getExamProperty.sMessage, this);
  547. }
  548. }
  549. }
  550. void courseList::onFaceCheckEnabled(CFaceCheckEnabled faceCheckEnabled)
  551. {
  552. if (faceCheckEnabled.nCode == 200)
  553. {
  554. //人脸检测
  555. g_appInfoPtr->m_oExamInfo.bFaceCheck = faceCheckEnabled.bEnabled;
  556. // if (faceCheckEnabled.bEnabled && !g_appInfoPtr->m_oExamInfo.bIsExamInProgress)
  557. // {
  558. // if (g_appInfoPtr->m_sStudentPhotoPath.isEmpty())
  559. // {
  560. // ShowMsg(QString::fromLocal8Bit("本场考试需要进行人脸检测,但是您没有上传底照,请联系老师"), this, MSG_ICON_TYPE::mit_error);
  561. // return;
  562. // }
  563. // if (m_pFaceCompare == nullptr)
  564. // {
  565. // m_pFaceCompare = std::make_shared<faceCompare>(this);
  566. // connect(m_pFaceCompare.get(), &faceCompare::exitFaceCompare, this, [&]() {
  567. // m_pFaceCompare.reset();
  568. // });
  569. // connect(m_pFaceCompare.get(), &faceCompare::faceComparePass, this, [&]() {
  570. // m_pFaceCompare.reset();
  571. // //活体检测
  572. // CHttpRequestPackage hrp;
  573. // hrp.sUri = QString("/api/ecs_exam_work/exam/identificationOfLivingEnabled/%1")
  574. // .arg(g_appInfoPtr->m_oExamInfo.nExamId);
  575. // hrp.nRequestType = RequestType::rtLivenessEnabled;
  576. // g_httpBllPtr->get(hrp);
  577. // });
  578. // }
  579. // m_pFaceCompare->show();
  580. // }
  581. // else
  582. {
  583. //活体检测
  584. CHttpRequestPackage hrp;
  585. hrp.sUri = QString("/api/ecs_exam_work/exam/identificationOfLivingEnabled/%1")
  586. .arg(g_appInfoPtr->m_oExamInfo.nExamId);
  587. hrp.nRequestType = RequestType::rtLivenessEnabled;
  588. g_httpBllPtr->get(hrp);
  589. }
  590. }
  591. else
  592. {
  593. if(faceCheckEnabled.sMessage.isEmpty())
  594. {
  595. ShowMsg(QString::fromLocal8Bit("获取人脸识别信息失败"), this, MSG_ICON_TYPE::mit_error);
  596. }
  597. else
  598. {
  599. ShowMsg(faceCheckEnabled.sMessage, this, MSG_ICON_TYPE::mit_error);
  600. }
  601. }
  602. }
  603. void courseList::doFaceCompare()
  604. {
  605. if (g_appInfoPtr->m_sStudentPhotoPath.isEmpty())
  606. {
  607. ShowMsg(QString::fromLocal8Bit("本场考试需要进行人脸检测,但是您没有上传底照,请联系老师"), this, MSG_ICON_TYPE::mit_error);
  608. return;
  609. }
  610. if (m_pFaceCompare == nullptr)
  611. {
  612. m_pFaceCompare = std::make_shared<faceCompare>(this);
  613. connect(m_pFaceCompare.get(), &faceCompare::exitFaceCompare, this, [&]() {
  614. m_pFaceCompare.reset();
  615. });
  616. connect(m_pFaceCompare.get(), &faceCompare::faceComparePass, this, [&]() {
  617. m_pFaceCompare.reset();
  618. //进入待考
  619. enterWaitExam();
  620. });
  621. }
  622. m_pFaceCompare->show();
  623. }
  624. void courseList::onLivenessEnabled(CLivenessEnabled livenessEnabled)
  625. {
  626. if (livenessEnabled.nCode == 200)
  627. {
  628. g_appInfoPtr->m_oExamInfo.bLivenessCheck = livenessEnabled.bEnabled;
  629. GetOrgPropertiesByGroupWithoutCache();
  630. //进入待考
  631. // enterWaitExam();
  632. }
  633. else
  634. {
  635. if(livenessEnabled.sMessage.isEmpty())
  636. {
  637. ShowMsg(QString::fromLocal8Bit("获取活体信息失败"), this, MSG_ICON_TYPE::mit_error);
  638. }
  639. else
  640. {
  641. ShowMsg(livenessEnabled.sMessage, this, MSG_ICON_TYPE::mit_error);
  642. }
  643. }
  644. }
  645. void courseList::doLiveness()
  646. {
  647. //活体检测
  648. if(m_pFaceLiveness == nullptr)
  649. {
  650. m_pFaceLiveness = std::make_shared<faceLiveness>(FACE_LIVENESS_TYPE::flt_entry_exam, this);
  651. connect(m_pFaceLiveness.get(), &faceLiveness::faceLivenessFaild, this, [&](){
  652. g_appInfoPtr->m_oExamInfo.nFaceLiveVerifyId = 0;
  653. m_pFaceLiveness.reset();
  654. });
  655. connect(m_pFaceLiveness.get(), &faceLiveness::faceLivenessSucceed, this, [&](){
  656. g_appInfoPtr->m_oExamInfo.nFaceLiveVerifyId = 0;
  657. m_pFaceLiveness.reset();
  658. //进入待考
  659. enterWaitExam();
  660. });
  661. m_pFaceLiveness->show();
  662. }
  663. }
  664. void courseList::GetOrgPropertiesByGroupWithoutCache()
  665. {
  666. CHttpRequestPackage hrp;
  667. hrp.sUri = QString("/api/ecs_core/org/getOrgPropertiesByGroupWithoutCache/%1/config4Edit1")
  668. .arg(g_appInfoPtr->m_sRootOrgId);
  669. hrp.nRequestType = RequestType::rtGetOrgPropertiesByGroupWithoutCache;
  670. g_httpBllPtr->get(hrp);
  671. }
  672. void courseList::onGetOrgPropertiesByGroupWithoutCache(CGetOrgPropertiesByGroupWithoutCache orgProperties)
  673. {
  674. if(orgProperties.nCode == 200)
  675. {
  676. m_nRetryCount = 0;
  677. g_appInfoPtr->m_oExamInfo.nActionNum = orgProperties.nActionNum;
  678. g_appInfoPtr->m_oExamInfo.sActionOptions = orgProperties.sActionOptions;
  679. g_appInfoPtr->m_oExamInfo.sActionOrder = orgProperties.sActionOrder;
  680. g_appInfoPtr->m_oExamInfo.nActionDuration = orgProperties.nActionDuration;
  681. g_appInfoPtr->m_oExamInfo.nActionAlert = orgProperties.nActionAlert;
  682. g_appInfoPtr->m_oExamInfo.nAllActionDuration = orgProperties.nAllActionDuration;
  683. g_appInfoPtr->m_oExamInfo.nFaceThreshold = orgProperties.nFaceThreshold;
  684. if(!g_appInfoPtr->m_oExamInfo.bIsExamInProgress)
  685. {
  686. if(g_appInfoPtr->m_oExamInfo.bIsLivenessBefore && g_appInfoPtr->m_oExamInfo.bIsFaceCheck)
  687. {
  688. doLiveness();
  689. }
  690. else if(g_appInfoPtr->m_oExamInfo.bFaceCheck)
  691. {
  692. doFaceCompare();
  693. }
  694. else
  695. {
  696. enterWaitExam();
  697. }
  698. }
  699. else
  700. {
  701. enterWaitExam();
  702. }
  703. }
  704. else
  705. {
  706. if(orgProperties.sMessage.isEmpty())
  707. {
  708. ShowMsg(QString::fromLocal8Bit("获取活体信息失败"), this, MSG_ICON_TYPE::mit_error);
  709. }
  710. else
  711. {
  712. ShowMsg(orgProperties.sMessage, this, MSG_ICON_TYPE::mit_error);
  713. }
  714. }
  715. }
  716. void courseList::enterWaitExam()
  717. {
  718. //进入待考
  719. if (m_pBackground == nullptr)
  720. {
  721. if (g_appInfoPtr->m_oExamInfo.bIsExamInProgress)
  722. {
  723. m_pBackground = std::make_shared<awBackground>(AW_WIDGET_TYPE::awwt_answerWidget, this);
  724. m_pResumeExam.reset();
  725. }
  726. else
  727. {
  728. m_pBackground = std::make_shared<awBackground>(AW_WIDGET_TYPE::awwt_waitExam, this);
  729. }
  730. connect(m_pBackground.get(), &awBackground::minisize, this, &courseList::minisize);
  731. connect(m_pBackground.get(), &awBackground::closeWidget, this, [&](){
  732. m_pBackground.reset();
  733. m_pRefreshMenuTimer->start();
  734. if(m_pOnlineExam)
  735. {
  736. m_pOnlineExam->refreshExam();
  737. }
  738. if(m_pOnlineHomework)
  739. {
  740. m_pOnlineHomework->refreshExam();
  741. }
  742. });
  743. connect(m_pBackground.get(), &awBackground::gobackLogin, this, [&](){
  744. m_pBackground.reset();
  745. logout();
  746. close();
  747. });
  748. connect(m_pBackground.get(), &awBackground::showPracticeInfo, this, [&](){
  749. m_pBackground.reset();
  750. CPracticeRecord pr;
  751. pr.nId = g_appInfoPtr->m_oExamInfo.nExamRecordDataId;
  752. pr.sCourseCode = g_appInfoPtr->m_oExamInfo.sCourseCode;
  753. pr.sCourseName = g_appInfoPtr->m_oExamInfo.sCourseName;
  754. if(m_pClopReport == nullptr)
  755. {
  756. m_pClopReport = std::make_shared<clopReport>(pr, true, ui->stw_courseList);
  757. connect(m_pClopReport.get(), &clopReport::goback, this, [&](){
  758. m_pClopReport.reset();
  759. if(m_pOnlinePractice)
  760. {
  761. m_pOnlinePractice->refreshExamInfo();
  762. }
  763. });
  764. m_pClopReport->setUI(0, 0, ui->stw_courseList->width(), ui->stw_courseList->height());
  765. }
  766. m_pClopReport->show();
  767. m_pRefreshMenuTimer->start();
  768. });
  769. }
  770. m_pBackground->show();
  771. m_pRefreshMenuTimer->stop();
  772. }
  773. void courseList::on_btn_onlineExam_clicked()
  774. {
  775. ui->stw_courseList->setCurrentIndex(0);
  776. setCheck(COURSE_MENU_BTN_TYPE::cmbt_online_exam);
  777. }
  778. void courseList::on_btn_onlineHomework_clicked()
  779. {
  780. ui->stw_courseList->setCurrentIndex(1);
  781. setCheck(COURSE_MENU_BTN_TYPE::cmbt_online_homework);
  782. }
  783. void courseList::on_btn_onlinePractice_clicked()
  784. {
  785. ui->stw_courseList->setCurrentIndex(2);
  786. setCheck(COURSE_MENU_BTN_TYPE::cmbt_online_practice);
  787. }
  788. void courseList::on_btn_offlineExam_clicked()
  789. {
  790. ui->stw_courseList->setCurrentIndex(3);
  791. setCheck(COURSE_MENU_BTN_TYPE::cmbt_offline_exam);
  792. }
  793. void courseList::on_btn_notice_clicked()
  794. {
  795. ui->stw_courseList->setCurrentIndex(4);
  796. setCheck(COURSE_MENU_BTN_TYPE::cmbt_notice);
  797. }
  798. void courseList::on_btn_editPassword_clicked()
  799. {
  800. ui->stw_courseList->setCurrentIndex(5);
  801. setCheck(COURSE_MENU_BTN_TYPE::cmbt_edit_password);
  802. }
  803. void courseList::on_btn_exit_clicked()
  804. {
  805. logout();
  806. close();
  807. }
  808. void courseList::logout()
  809. {
  810. CHttpRequestPackage hrp;
  811. hrp.sUri = "/api/ecs_core/auth/logout";
  812. hrp.nRequestType = RequestType::rtLogout;
  813. g_httpBllPtr->get(hrp);
  814. }
  815. bool courseList::eventFilter(QObject *obj, QEvent *ev)
  816. {
  817. if(ev->type() == QEvent::Enter)
  818. {
  819. if(obj == ui->btn_mobileLogin)
  820. {
  821. m_pMobileLoginBtnTimer->stop();
  822. if(m_pStudentInfo != nullptr)
  823. {
  824. m_pStudentInfo.reset();
  825. m_pStudentInfo = nullptr;
  826. }
  827. if(m_pMobileLogin == nullptr)
  828. {
  829. m_pMobileLogin = std::make_shared<clMobileLogin>(this);
  830. m_pMobileLogin->setUI(g_appInfoPtr->m_fRate*838, g_appInfoPtr->m_fRate*53, g_appInfoPtr->m_fRate*240, g_appInfoPtr->m_fRate*290);
  831. m_pMobileLogin->show();
  832. m_pMobileLogin->installEventFilter(this);
  833. }
  834. ui->btn_mobileLogin->setIcon(QIcon(":/images/icon-mobile-login-hover.png"));
  835. }
  836. else if(obj == ui->btn_studentInfo)
  837. {
  838. m_pStudentInfoBtnTimer->stop();
  839. if(m_pMobileLogin != nullptr)
  840. {
  841. m_pMobileLogin.reset();
  842. m_pMobileLogin = nullptr;
  843. }
  844. if(m_pStudentInfo == nullptr)
  845. {
  846. m_pStudentInfo = std::make_shared<clStudentInfo>(this);
  847. connect(m_pStudentInfo.get(), &clStudentInfo::sgnStudentLogout, this, [&]() {
  848. on_btn_exit_clicked();
  849. });
  850. connect(m_pStudentInfo.get(), &clStudentInfo::sgnStudentEditPassword, this, [&]() {
  851. if (m_pStudentInfo != nullptr)
  852. {
  853. m_pStudentInfo.reset();
  854. }
  855. on_btn_editPassword_clicked();
  856. });
  857. m_pStudentInfo->setUI(g_appInfoPtr->m_fRate*838, g_appInfoPtr->m_fRate*53, g_appInfoPtr->m_fRate*330, g_appInfoPtr->m_fRate*240);
  858. m_pStudentInfo->show();
  859. m_pStudentInfo->installEventFilter(this);
  860. }
  861. ui->btn_studentInfo->setIcon(QIcon(":/images/icon-student-info-hover.png"));
  862. }
  863. else if(obj == m_pMobileLogin.get())
  864. {
  865. m_pMobileLoginBtnTimer->stop();
  866. }
  867. else if(obj == m_pStudentInfo.get())
  868. {
  869. m_pStudentInfoBtnTimer->stop();
  870. }
  871. }
  872. else if(ev->type() == QEvent::Leave)
  873. {
  874. if(obj == ui->btn_mobileLogin || obj == m_pMobileLogin.get())
  875. {
  876. ui->btn_mobileLogin->setIcon(QIcon(":/images/icon-mobile-login.png"));
  877. m_pMobileLoginBtnTimer->start();
  878. }
  879. if(obj == ui->btn_studentInfo || obj == m_pStudentInfo.get())
  880. {
  881. ui->btn_studentInfo->setIcon(QIcon(":/images/icon-student-info.png"));
  882. m_pStudentInfoBtnTimer->start();
  883. }
  884. }
  885. return QWidget::eventFilter(obj, ev);
  886. }
  887. void courseList::hideStudentInfoBtn()
  888. {
  889. if(m_pStudentInfo != nullptr)
  890. {
  891. m_pStudentInfo.reset();
  892. }
  893. }
  894. void courseList::hideMobileLoginBtn()
  895. {
  896. if(m_pMobileLogin != nullptr)
  897. {
  898. m_pMobileLogin.reset();
  899. }
  900. }
  901. void courseList::getStudentInfoBySession()
  902. {
  903. CHttpRequestPackage hrp;
  904. hrp.sUri = "/api/ecs_core/student/getStudentInfoBySession";
  905. hrp.nRequestType = RequestType::rtGetStudentInfoBySession;
  906. hrp.nRetryCount = 3;
  907. g_httpBllPtr->get(hrp);
  908. }
  909. void courseList::onGetStudentInfoBySession(CGetStudentInfoBySession getStudentInfoBySession)
  910. {
  911. if (getStudentInfoBySession.nCode == 200)
  912. {
  913. g_appInfoPtr->m_nStudentId = getStudentInfoBySession.nId;
  914. g_appInfoPtr->m_sStudentName = getStudentInfoBySession.sName;
  915. g_appInfoPtr->m_nOrgId = getStudentInfoBySession.nOrgId;
  916. g_appInfoPtr->m_sOrgCode = getStudentInfoBySession.sOrgCode;
  917. g_appInfoPtr->m_sOrgName = getStudentInfoBySession.sOrgName;
  918. g_appInfoPtr->m_sStudentCode = getStudentInfoBySession.sStudentCode;
  919. g_appInfoPtr->m_sStudentIdentityNumber = getStudentInfoBySession.sIdentityNumber;
  920. g_appInfoPtr->m_sStudentPhotoPath = getStudentInfoBySession.sPhotoPath;
  921. g_appInfoPtr->m_bStudentEnable = getStudentInfoBySession.bEnable;
  922. ui->btn_studentInfo->setText(g_appInfoPtr->m_sStudentName);
  923. ui->btn_studentInfo->setVisible(g_appInfoPtr->m_bStudentEnable);
  924. ui->btn_mobileLogin->setVisible(g_appInfoPtr->m_bShowStudentClientAppQrcode);
  925. CHttpRequestPackage hrp;
  926. hrp.sUri = "/api/ecs_exam_work/exam_student/specialtyNameList";
  927. hrp.nRequestType = RequestType::rtSpecialtyNameList;
  928. g_httpBllPtr->get(hrp);
  929. if (!g_appInfoPtr->m_sStudentPhotoPath.isEmpty())
  930. {
  931. QString sFileName = g_appInfoPtr->m_sStudentPhotoPath.right(g_appInfoPtr->m_sStudentPhotoPath.length() - g_appInfoPtr->m_sStudentPhotoPath.lastIndexOf("/") - 1);
  932. sFileName = g_appInfoPtr->m_sCacheFileDir + sFileName;
  933. CHttpRequestPackage hrp;
  934. hrp.sUri = g_appInfoPtr->m_sStudentPhotoPath;
  935. hrp.sCommonStr = sFileName;
  936. hrp.sCommonStr1 = __FILE__;
  937. hrp.sAdditionStr = "StudentPhotoPath";
  938. hrp.nRequestType = RequestType::rtDownLoadFile;
  939. hrp.nRetryCount = 3;
  940. g_httpBllPtr->downLoad(hrp);
  941. }
  942. if (g_appInfoPtr->m_bShowStudentClientAppQrcode)
  943. {
  944. CHttpRequestPackage hrp;
  945. hrp.sUri = "/api/ecs_core/systemProperty/APP_DOWNLOAD_URL";
  946. hrp.nRequestType = RequestType::rtAppDownLoadUrl;
  947. g_httpBllPtr->get(hrp);
  948. }
  949. }
  950. else
  951. {
  952. if(getStudentInfoBySession.sMessage.isEmpty())
  953. {
  954. ShowMsg(QString::fromLocal8Bit("获取考生信息失败"), this, MSG_ICON_TYPE::mit_error);
  955. }
  956. else
  957. {
  958. ShowMsg(getStudentInfoBySession.sMessage, this, MSG_ICON_TYPE::mit_error);
  959. }
  960. courseList::getStudentInfoBySession();
  961. }
  962. }
  963. void courseList::onAppDownLoadUrl(CAppDownLoadUrl appDownLoadUrl)
  964. {
  965. if (appDownLoadUrl.nCode == 200)
  966. {
  967. g_appInfoPtr->m_sAppDownLoadUrl = appDownLoadUrl.sUrl;
  968. }
  969. else
  970. {
  971. if(appDownLoadUrl.sMessage.isEmpty())
  972. {
  973. ShowMsg(QString::fromLocal8Bit("获取APP下载地址失败"), this, MSG_ICON_TYPE::mit_error);
  974. }
  975. else
  976. {
  977. ShowMsg(appDownLoadUrl.sMessage, this, MSG_ICON_TYPE::mit_error);
  978. }
  979. }
  980. }
  981. void courseList::onDownLoadFile(CDownLoadFileInfo downLoadFileInfo)
  982. {
  983. if(downLoadFileInfo.sModuleName == __FILE__)
  984. {
  985. if (downLoadFileInfo.nCode == 200)
  986. {
  987. // QString sFileName = g_appInfoPtr->m_sStudentPhotoPath.right(g_appInfoPtr->m_sStudentPhotoPath.length() - g_appInfoPtr->m_sStudentPhotoPath.lastIndexOf("/") - 1);
  988. // sFileName = g_appInfoPtr->m_sCacheFileDir + sFileName;
  989. if (downLoadFileInfo.sAdditionStr == "MenuLogoUrl")
  990. {
  991. QString sFileName = g_appInfoPtr->m_sMenuLogoUrl.right(g_appInfoPtr->m_sMenuLogoUrl.length() - g_appInfoPtr->m_sMenuLogoUrl.lastIndexOf("/") - 1);
  992. sFileName = g_appInfoPtr->m_sCacheFileDir + sFileName;
  993. ui->label_cl_org_icon->setPixmap(QPixmap(sFileName).scaled(ui->label_cl_org_icon->width(), ui->label_cl_org_icon->height(),
  994. Qt::KeepAspectRatio, Qt::SmoothTransformation));
  995. }
  996. }
  997. else
  998. {
  999. if(downLoadFileInfo.sMessage.isEmpty())
  1000. {
  1001. ShowMsg(QString::fromLocal8Bit("下载失败"), this, MSG_ICON_TYPE::mit_error);
  1002. }
  1003. else
  1004. {
  1005. ShowMsg(downLoadFileInfo.sMessage, this, MSG_ICON_TYPE::mit_error);
  1006. }
  1007. }
  1008. }
  1009. }
  1010. void courseList::onSpecialtyNameList(CSpecialtyNameList specialtyNameList)
  1011. {
  1012. if (specialtyNameList.nCode == 200)
  1013. {
  1014. g_appInfoPtr->m_sSpecialtyName = specialtyNameList.sSpecialtyName;
  1015. CHttpRequestPackage hrp;
  1016. hrp.sUri = "/api/ecs_oe_student/client/exam/process/checkExamInProgress";
  1017. hrp.nRequestType = RequestType::rtCheckExamInProgress;
  1018. hrp.sCommonStr = EXAM_INPROGRESS_ENTER_TYPE::EIET_COURSE_LIST;
  1019. g_httpBllPtr->post(hrp);
  1020. }
  1021. else
  1022. {
  1023. if(specialtyNameList.sMessage.isEmpty())
  1024. {
  1025. ShowMsg(QString::fromLocal8Bit("获取专业信息失败"), this, MSG_ICON_TYPE::mit_error);
  1026. }
  1027. else
  1028. {
  1029. ShowMsg(specialtyNameList.sMessage, this, MSG_ICON_TYPE::mit_error);
  1030. }
  1031. }
  1032. }
  1033. void courseList::onCheckExamInProgress(CCheckExamInProgress checkExamInProgress)
  1034. {
  1035. if (checkExamInProgress.nCode == 200)
  1036. {
  1037. if (checkExamInProgress.bHasExamInProgress)
  1038. {
  1039. if (checkExamInProgress.bIsExceed)
  1040. {
  1041. //超过断点时长交卷
  1042. g_appInfoPtr->m_oExamInfo.nExamRecordDataId = checkExamInProgress.nExamRecordDataId;
  1043. g_appInfoPtr->m_oExamInfo.nExamId = checkExamInProgress.nExamId;
  1044. CHttpRequestPackage hrp;
  1045. hrp.sUri = QString("/api/ecs_oe_student/client/exam/process/endExam");
  1046. hrp.sCommonStr = __FILE__;
  1047. hrp.nRequestType = RequestType::rtEndExam;
  1048. g_httpBllPtr->post(hrp);
  1049. }
  1050. else
  1051. {
  1052. //进入断点
  1053. g_appInfoPtr->m_oExamInfo.nExamId = checkExamInProgress.nExamId;
  1054. g_appInfoPtr->m_oExamInfo.nExamRecordDataId = checkExamInProgress.nExamRecordDataId;
  1055. g_appInfoPtr->m_oExamInfo.sExamType = checkExamInProgress.sExamType;
  1056. g_appInfoPtr->m_oExamInfo.bIsExamInProgress = true;
  1057. if (m_pResumeExam == nullptr)
  1058. {
  1059. m_pResumeExam = std::make_shared<awResumeExam>(this);
  1060. }
  1061. m_pResumeExam->show();
  1062. //环境监测
  1063. getExamProperty();
  1064. }
  1065. }
  1066. else
  1067. {
  1068. g_appInfoPtr->m_oExamInfo.bIsExamInProgress = false;
  1069. if (checkExamInProgress.sEnterType == EXAM_INPROGRESS_ENTER_TYPE::EIET_COURSE_LIST)
  1070. {
  1071. CHttpRequestPackage hrp;
  1072. hrp.sUri = "/api/ecs_core/rolePrivilege/getStudentClientMenu";
  1073. hrp.nRequestType = RequestType::rtGetStudentClientMenu;
  1074. hrp.sParamList.push_back(QString::fromLocal8Bit("rootOrgId,%1").arg(g_appInfoPtr->m_sRootOrgId));
  1075. g_httpBllPtr->get(hrp);
  1076. if (m_pWelcomeWidget == nullptr)
  1077. {
  1078. m_pWelcomeWidget = std::make_shared<welcomeWidget>(g_appInfoPtr->m_sStudentName, g_appInfoPtr->m_sStudentCode, g_appInfoPtr->m_sSpecialtyName, this);
  1079. connect(m_pWelcomeWidget.get(), &welcomeWidget::exitWelcomeWidget, this, [&]() {
  1080. m_pWelcomeWidget.reset();
  1081. });
  1082. }
  1083. m_pWelcomeWidget->show();
  1084. }
  1085. else
  1086. {
  1087. //环境监测
  1088. getExamProperty();
  1089. }
  1090. }
  1091. }
  1092. else
  1093. {
  1094. if(checkExamInProgress.sMessage.isEmpty())
  1095. {
  1096. ShowMsg(QString::fromLocal8Bit("获取断点信息失败"), this, MSG_ICON_TYPE::mit_error);
  1097. }
  1098. else
  1099. {
  1100. ShowMsg(checkExamInProgress.sMessage, this, MSG_ICON_TYPE::mit_error);
  1101. }
  1102. }
  1103. }
  1104. void courseList::getExamProperty()
  1105. {
  1106. CHttpRequestPackage hrp;
  1107. hrp.sUri = QString("/api/ecs_exam_work/exam/getExamPropertyFromCacheByStudentSession/%1/%2")
  1108. .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");
  1109. hrp.nRequestType = RequestType::rtGetExamProperty;
  1110. hrp.sCommonStr = "CHECK_ENVIRONMENT,IS_FACE_CHECK,SNAPSHOT_INTERVAL,FACE_VERIFY_START_MINUTE,FACE_VERIFY_END_MINUTE,IS_STRANGER_ENABLE,IS_FACE_VERIFY_BEFORE";
  1111. g_httpBllPtr->get(hrp);
  1112. }
  1113. void courseList::onEndExam(CEndExam endExam)
  1114. {
  1115. if(endExam.sModuleName == __FILE__)
  1116. {
  1117. if (endExam.nCode == 200)
  1118. {
  1119. m_pRefreshMenuTimer->stop();
  1120. if(m_pBackground != nullptr)
  1121. {
  1122. m_pBackground.reset();
  1123. }
  1124. m_pBackground = std::make_shared<awBackground>(AW_WIDGET_TYPE::awwt_examScore, this);
  1125. connect(m_pBackground.get(), &awBackground::minisize, this, &courseList::minisize);
  1126. connect(m_pBackground.get(), &awBackground::closeWidget, this, [&](){
  1127. m_pBackground.reset();
  1128. m_pRefreshMenuTimer->start();
  1129. if(m_pOnlineExam)
  1130. {
  1131. m_pOnlineExam->refreshExam();
  1132. }
  1133. if(m_pOnlineHomework)
  1134. {
  1135. m_pOnlineHomework->refreshExam();
  1136. }
  1137. });
  1138. m_pBackground->show();
  1139. }
  1140. else
  1141. {
  1142. if(endExam.sMessage.isEmpty())
  1143. {
  1144. ShowMsg(QString::fromLocal8Bit("交卷失败"), g_appInfoPtr->m_pAnsBgWidget, MSG_ICON_TYPE::mit_error);
  1145. }
  1146. else
  1147. {
  1148. ShowMsg(endExam.sMessage, g_appInfoPtr->m_pAnsBgWidget, MSG_ICON_TYPE::mit_error);
  1149. }
  1150. }
  1151. }
  1152. }
  1153. void courseList::onGetStudentClientMenu(CGetStudentClientMenu getStudentClientMenu)
  1154. {
  1155. if (getStudentClientMenu.nCode == 200)
  1156. {
  1157. ui->btn_onlineExam->setVisible(false);
  1158. ui->btn_onlineHomework->setVisible(false);
  1159. ui->btn_onlinePractice->setVisible(false);
  1160. ui->btn_offlineExam->setVisible(false);
  1161. ui->btn_notice->setVisible(false);
  1162. ui->btn_editPassword->setVisible(false);
  1163. for (CStudentClientMenu scm : getStudentClientMenu.vMenus)
  1164. {
  1165. QString sMenuName = scm.sName;
  1166. sMenuName.insert(sMenuName.length()/2, '\n');
  1167. QString sMenuCode = scm.sCode.left(scm.sCode.lastIndexOf("_"));
  1168. if (sMenuCode == "stu_online_exam")
  1169. {
  1170. ui->btn_onlineExam->setVisible(true);
  1171. ui->btn_onlineExam->setText(sMenuName);
  1172. }
  1173. else if (sMenuCode == "stu_online_homework")
  1174. {
  1175. ui->btn_onlineHomework->setVisible(true);
  1176. ui->btn_onlineHomework->setText(sMenuName);
  1177. }
  1178. else if (sMenuCode == "stu_online_practice")
  1179. {
  1180. ui->btn_onlinePractice->setVisible(true);
  1181. ui->btn_onlinePractice->setText(sMenuName);
  1182. }
  1183. else if (sMenuCode == "stu_offline_exam")
  1184. {
  1185. ui->btn_offlineExam->setVisible(true);
  1186. ui->btn_offlineExam->setText(sMenuName);
  1187. }
  1188. else if (sMenuCode == "stu_notice")
  1189. {
  1190. ui->btn_notice->setVisible(true);
  1191. ui->btn_notice->setText(sMenuName);
  1192. CHttpRequestPackage hrp;
  1193. hrp.sUri = "/api/ecs_exam_work/notice/getUserNoticeList";
  1194. hrp.nRequestType = RequestType::rtGetUserNoticeList;
  1195. g_httpBllPtr->get(hrp);
  1196. }
  1197. else if (sMenuCode == "stu_modify_pwd")
  1198. {
  1199. ui->btn_editPassword->setVisible(true);
  1200. ui->btn_editPassword->setText(sMenuName);
  1201. }
  1202. }
  1203. menuBtnRePosistion();
  1204. }
  1205. else
  1206. {
  1207. if(getStudentClientMenu.sMessage.isEmpty())
  1208. {
  1209. ShowMsg(QString::fromLocal8Bit("获取菜单失败"), this, MSG_ICON_TYPE::mit_error);
  1210. }
  1211. else
  1212. {
  1213. ShowMsg(getStudentClientMenu.sMessage, this, MSG_ICON_TYPE::mit_error);
  1214. }
  1215. }
  1216. }
  1217. void courseList::onGetUserNoticeList(CGetUserNoticeList getUserNoticeList)
  1218. {
  1219. if (getUserNoticeList.nCode == 200)
  1220. {
  1221. if (m_pNoticeList == nullptr)
  1222. {
  1223. m_pNoticeList = std::make_shared<clNoticeList>(ui->stw_courseList);
  1224. m_pNoticeList->setUI(ui->stw_courseList->width(), ui->stw_courseList->height());
  1225. connect(m_pNoticeList.get(), &clNoticeList::unReadNoticeCount, this, [&](int nCount) {
  1226. ui->btn_noticeNum->setText(QString::number(nCount));
  1227. ui->btn_noticeNum->setVisible(nCount > 0);
  1228. });
  1229. connect(m_pNoticeList.get(), &clNoticeList::readNotice, this, [&](__int64 nId) {
  1230. m_pNoticePopWidget->setNoticeRead(nId);
  1231. });
  1232. }
  1233. m_pNoticeList->setNotice(getUserNoticeList.vNoticeList);
  1234. if (m_pNoticePopWidget == nullptr)
  1235. {
  1236. m_pNoticePopWidget = std::make_shared<clNoticePopWidget>(this);
  1237. m_pNoticePopWidget->setUI(g_appInfoPtr->m_fRate * 960, g_appInfoPtr->m_fRate * 558, g_appInfoPtr->m_fRate * 310, g_appInfoPtr->m_fRate * 200);
  1238. connect(m_pNoticePopWidget.get(), &clNoticePopWidget::showNoticeDetail, this, [&](__int64 nId){
  1239. setCheck(COURSE_MENU_BTN_TYPE::cmbt_notice);
  1240. m_pNoticeList->viewNotice(nId);
  1241. });
  1242. }
  1243. int nUnReadCount = 0;
  1244. for (CNoticeInfo ni : getUserNoticeList.vNoticeList)
  1245. {
  1246. if (!ni.bHasRead)
  1247. {
  1248. m_pNoticePopWidget->addNotice(ni);
  1249. ++nUnReadCount;
  1250. }
  1251. }
  1252. ui->btn_noticeNum->setText(QString::number(nUnReadCount));
  1253. ui->btn_noticeNum->setVisible(nUnReadCount > 0);
  1254. if(m_pNoticePopWidget->noticeCount() > 0)
  1255. {
  1256. m_pNoticePopWidget->show();
  1257. }
  1258. }
  1259. else
  1260. {
  1261. if(getUserNoticeList.sMessage.isEmpty())
  1262. {
  1263. ShowMsg(QString::fromLocal8Bit("获取通知信息失败"), this, MSG_ICON_TYPE::mit_error);
  1264. }
  1265. else
  1266. {
  1267. ShowMsg(getUserNoticeList.sMessage, this, MSG_ICON_TYPE::mit_error);
  1268. }
  1269. }
  1270. }