useInitExamData.ts 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. import { httpApp } from "@/plugins/axiosApp";
  2. import { store } from "@/store/store";
  3. import { ExamQuestion, PaperStruct, Store } from "@/types/student-client";
  4. import { dimensionLog } from "@/utils/logger";
  5. type PRACTICE_TYPE = "IN_PRACTICE" | "NO_ANSWER";
  6. export async function initExamData(examId: number, examRecordDataId: number) {
  7. logger({ cnl: ["server", "local"], pgn: "答题页面", act: "before initData" });
  8. const { courseName, courseCode } = (
  9. await httpApp.post<{ courseName: string; courseCode: string }>(
  10. "/api/ecs_oe_student/examControl/getCourseInfo/" + examRecordDataId,
  11. { "axios-retry": { retries: 4 }, noErrorMessage: true }
  12. )
  13. ).data;
  14. const [
  15. { data: weixinAnswerEnabled },
  16. { data: faceCheckEnabled },
  17. { data: faceLivenessEnabled },
  18. { data: examProp },
  19. { data: exam },
  20. { data: paperStruct },
  21. { data: examQuestionListOrig },
  22. ] = await Promise.all([
  23. // 是否开放微信小程序作答
  24. httpApp.get<boolean>(
  25. `/api/ecs_exam_work/exam/weixinAnswerEnabled/${examId}?courseCode=${courseCode}`,
  26. {
  27. "axios-retry": { retries: 4 },
  28. noErrorMessage: true,
  29. }
  30. ),
  31. // 是否支持人脸识别
  32. httpApp.get<boolean>("/api/ecs_exam_work/exam/faceCheckEnabled/" + examId, {
  33. "axios-retry": { retries: 4 },
  34. noErrorMessage: true,
  35. }),
  36. // 是否支持活体检测
  37. httpApp.get<boolean>(
  38. "/api/ecs_exam_work/exam/identificationOfLivingEnabled/" + examId,
  39. { "axios-retry": { retries: 4 }, noErrorMessage: true }
  40. ),
  41. // 查询考生的考试批次属性集; 实际上后台都是字符串 {PRACTICE_TYPE: string | null; FREEZE_TIME: string; SNAPSHOT_INTERVAL: string; }
  42. httpApp.get<{
  43. PRACTICE_TYPE: string | null;
  44. FREEZE_TIME: number | null;
  45. SNAPSHOT_INTERVAL: number;
  46. }>(
  47. "/api/ecs_exam_work/exam/getExamPropertyFromCacheByStudentSession/" +
  48. examId +
  49. `/SNAPSHOT_INTERVAL,PRACTICE_TYPE,FREEZE_TIME`,
  50. { "axios-retry": { retries: 4 }, noErrorMessage: true }
  51. ),
  52. // 按ID查询考试批次信息
  53. httpApp.get<Store["exam"]>("/api/ecs_exam_work/exam/" + examId, {
  54. "axios-retry": { retries: 4 },
  55. noErrorMessage: true,
  56. }),
  57. // 获取考试记录试卷结构
  58. httpApp.get<PaperStruct>(
  59. "/api/ecs_oe_student/examRecordPaperStruct/getExamRecordPaperStruct?examRecordDataId=" +
  60. examRecordDataId,
  61. { "axios-retry": { retries: 4 }, noErrorMessage: true }
  62. ),
  63. // 获取试题列表
  64. httpApp.get<ExamQuestion[]>(
  65. "/api/ecs_oe_student/examQuestion/findExamQuestionList",
  66. { "axios-retry": { retries: 4 }, noErrorMessage: true }
  67. ),
  68. ]);
  69. store.exam.courseName = courseName;
  70. let examQuestionList = examQuestionListOrig;
  71. logger({
  72. cnl: ["server", "local"],
  73. pgn: "答题页面",
  74. dtl: `end${typeof Object.fromEntries === "function" ? " " : " "}initData`,
  75. });
  76. dimensionLog("答题页面");
  77. if (exam.examType === "PRACTICE") {
  78. exam.practiceType = examProp.PRACTICE_TYPE as PRACTICE_TYPE;
  79. }
  80. exam.freezeTime = JSON.parse("" + examProp.FREEZE_TIME);
  81. exam.SNAPSHOT_INTERVAL = JSON.parse("" + examProp.SNAPSHOT_INTERVAL);
  82. exam.WEIXIN_ANSWER_ENABLED = weixinAnswerEnabled;
  83. store.exam.faceCheckEnabled = faceCheckEnabled;
  84. store.exam.faceLivenessEnabled = faceLivenessEnabled;
  85. logger({
  86. cnl: ["server", "local"],
  87. pgn: "答题页面",
  88. ext: {
  89. examRecordDataId: examRecordDataId,
  90. faceCheckEnabled: faceCheckEnabled,
  91. faceLivenessEnabled: faceLivenessEnabled,
  92. WEIXIN_ANSWER_ENABLED: exam.WEIXIN_ANSWER_ENABLED,
  93. SNAPSHOT_INTERVAL: examProp.SNAPSHOT_INTERVAL,
  94. PRACTICE_TYPE: examProp.PRACTICE_TYPE,
  95. FREEZE_TIME: examProp.FREEZE_TIME,
  96. },
  97. });
  98. // parentQuestionBody
  99. // questionUnitWrapperList
  100. // questionBody => from examQuestionList
  101. // questionUnitList =>
  102. // studentAnswer
  103. // rightAnswer
  104. // init subNumber
  105. let questionId: string | null = null;
  106. let i = 1;
  107. examQuestionList = examQuestionList.map((eq) => {
  108. if (questionId == eq.questionId) {
  109. eq.subNumber = i++;
  110. } else {
  111. i = 1;
  112. questionId = eq.questionId;
  113. eq.subNumber = i++;
  114. }
  115. return eq;
  116. });
  117. let groupOrder = 1;
  118. let mainNumber = 0;
  119. examQuestionList = examQuestionList.map((eq) => {
  120. if (mainNumber == eq.mainNumber) {
  121. eq.inGroupOrder = groupOrder++;
  122. } else {
  123. mainNumber = eq.mainNumber;
  124. groupOrder = 1;
  125. eq.inGroupOrder = groupOrder++;
  126. }
  127. const questionWrapperList =
  128. paperStruct.defaultPaper.questionGroupList[eq.mainNumber - 1]
  129. .questionWrapperList;
  130. const groupName =
  131. paperStruct.defaultPaper.questionGroupList[eq.mainNumber - 1].groupName;
  132. const groupTotal = questionWrapperList.reduce(
  133. (accumulator, questionWrapper) =>
  134. accumulator + questionWrapper.questionUnitWrapperList.length,
  135. 0
  136. );
  137. eq.groupName = groupName;
  138. eq.groupTotal = groupTotal;
  139. return eq;
  140. });
  141. store.exam.examQuestionList = examQuestionList.map((eq) => {
  142. const paperStructQuestion = paperStruct.defaultPaper.questionGroupList[
  143. eq.mainNumber - 1
  144. ].questionWrapperList.find((q) => q.questionId === eq.questionId);
  145. return Object.assign(eq, {
  146. limitedPlayTimes: paperStructQuestion!.limitedPlayTimes,
  147. });
  148. });
  149. Object.assign(store.exam, exam);
  150. store.exam.paperStruct = paperStruct;
  151. // TODO: 此处类型待优化
  152. store.exam.allAudioPlayTimes =
  153. JSON.parse(
  154. store.exam.examQuestionList[0].audioPlayTimes as unknown as string
  155. ) || [];
  156. }