examPaperDetail.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. <template>
  2. <div id="paperView">
  3. <div id="paperName">{{ paperStruct.name }}</div>
  4. <div id="studentInfoDiv">
  5. <table id="studentInfoTable" border>
  6. <thead>
  7. <tr>
  8. <th>考试ID</th>
  9. <th>学号</th>
  10. <th>姓名</th>
  11. <th>课程</th>
  12. </tr>
  13. </thead>
  14. <tbody>
  15. <tr>
  16. <td>{{ examRecordData.id }}</td>
  17. <td>{{ examRecord.studentCode }}</td>
  18. <td>{{ examRecord.studentName }}</td>
  19. <td>{{ courseInfo.name }}({{ courseInfo.code }})</td>
  20. </tr>
  21. </tbody>
  22. </table>
  23. </div>
  24. <!-- 遍历大题 -->
  25. <div
  26. v-for="(questionGroup, index) in paperStruct.questionGroupList"
  27. :key="index"
  28. class="mainQuestionDiv"
  29. >
  30. <div style="font-size: 16px;font-weight: bold;">
  31. {{ toChineseNumber(index + 1) }}、{{ questionGroup.groupName }}({{
  32. questionGroup.groupScore
  33. }}分)
  34. </div>
  35. <div>{{ questionGroup.score }}</div>
  36. <!-- 遍历大题下的小题 -->
  37. <div
  38. v-for="(questionWrapper, index) in questionGroup.questionWrapperList"
  39. :key="index"
  40. >
  41. <div
  42. v-for="(question, index) in questionWrapper.questionList"
  43. :key="index"
  44. >
  45. <div style="display: flex;flex-direction:row;">
  46. <div v-html="restoreAudio(question.body)"></div>
  47. </div>
  48. <div
  49. v-for="(questionUnit, index) in question.questionUnitList"
  50. :key="index"
  51. >
  52. <div style="display: flex;flex-direction:row;">
  53. <div>{{ questionUnit.order }}、</div>
  54. <div v-html="restoreAudio(questionUnit.body)"></div>
  55. <span>({{ questionUnit.questionScore }}分)</span>
  56. </div>
  57. <div
  58. v-for="(option, index) in questionUnit.quesOptions"
  59. :key="index"
  60. >
  61. <div style="display: flex;flex-direction:row;">
  62. <div>{{ option.letter }}.</div>
  63. <div v-html="restoreAudio(option.body)"></div>
  64. </div>
  65. </div>
  66. <div>
  67. <div
  68. style="display: flex;flex-direction:row;color: green;font-weight: bold;"
  69. >
  70. <div>标准答案:</div>
  71. <span v-html="questionUnit.correctAnswer"></span>
  72. </div>
  73. <div style="color: blue;font-weight: bold;">
  74. 学生答案:<span v-html="questionUnit.studentAnswer"></span>
  75. <i
  76. class="el-icon-check"
  77. v-show="
  78. questionUnit.isObjectiveQuestion && questionUnit.isRight
  79. "
  80. ></i>
  81. <i
  82. class="el-icon-close"
  83. v-show="
  84. questionUnit.isObjectiveQuestion && !questionUnit.isRight
  85. "
  86. ></i>
  87. </div>
  88. </div>
  89. </div>
  90. </div>
  91. </div>
  92. </div>
  93. </div>
  94. </template>
  95. <script>
  96. export default {
  97. data() {
  98. return {
  99. courseId: "",
  100. examRecordDataId: "",
  101. examRecordData: {},
  102. examRecord: {},
  103. courseInfo: {},
  104. paperStruct: {},
  105. examQuestionList: []
  106. };
  107. },
  108. methods: {
  109. getExamRecordData() {
  110. this.$http
  111. .get("/api/ecs_oe_admin/exam/record/data/findExamRecordDataEntity", {
  112. params: { examRecordDataId: this.examRecordDataId }
  113. })
  114. .then(response => {
  115. this.examRecordData = response.data;
  116. this.examRecord = response.data.examRecord;
  117. });
  118. },
  119. getCourseInfo() {
  120. this.$http.get("/api/ecs_core/course/" + this.courseId).then(response => {
  121. this.courseInfo = response.data;
  122. });
  123. },
  124. getPaperData() {
  125. this.$http
  126. .get(
  127. "/api/ecs_oe_admin/examRecordPaperStruct/getExamRecordPaperStruct",
  128. { params: { examRecordDataId: this.examRecordDataId } }
  129. )
  130. .then(response => {
  131. this.paperStruct = response.data.defaultPaper;
  132. var questionGroupList = this.paperStruct.questionGroupList; //大题集合
  133. this.$http
  134. .get(
  135. "/api/ecs_oe_admin/examRecordQuestions/getExamRecordQuestions",
  136. { params: { examRecordDataId: this.examRecordDataId } }
  137. )
  138. .then(response => {
  139. this.examQuestionList = response.data.examQuestionEntities;
  140. var order = 0;
  141. for (var i = 0; i < questionGroupList.length; i++) {
  142. var questionGroup = questionGroupList[i]; //大题
  143. var questionWrapperList = questionGroup.questionWrapperList; //大题下小题集合
  144. for (var j = 0; j < questionWrapperList.length; j++) {
  145. var questionWrapper = questionWrapperList[j];
  146. order += questionWrapper.questionUnitWrapperList.length;
  147. this.getQuestionContent(
  148. questionWrapper.questionId,
  149. questionWrapper,
  150. order
  151. );
  152. }
  153. }
  154. });
  155. });
  156. },
  157. getQuestionContent(questionId, questionWrapper, order) {
  158. var params = {
  159. examId: this.examRecordData.examRecord.examId,
  160. courseCode: this.courseInfo.code,
  161. groupCode: this.examRecordData.examRecord.paperType,
  162. questionId: questionId
  163. };
  164. this.$http
  165. .post("/api/ecs_ques/default_question/question", params)
  166. .then(response => {
  167. var question = response.data.masterVersion;
  168. var questionUnitList = question.questionUnitList;
  169. var num = questionUnitList.length;
  170. for (var i = 0; i < questionUnitList.length; i++) {
  171. this.reOrderOptions(questionUnitList[i], order - num + 1);
  172. num--;
  173. }
  174. var questionList = questionWrapper.questionList;
  175. if (!questionList) {
  176. questionList = [];
  177. questionList.push(question);
  178. } else {
  179. questionList.push(question);
  180. }
  181. questionWrapper.questionList = questionList;
  182. });
  183. },
  184. reOrderOptions(question, order) {
  185. question.order = order; //设置序号
  186. var questionScore = this.examQuestionList[order - 1].questionScore;
  187. var studentAnswer = this.examQuestionList[order - 1].studentAnswer;
  188. var correctAnswer = question.rightAnswer; //从题中获取正确答案
  189. var optionList = question.questionOptionList;
  190. //单选,多选
  191. if (optionList && optionList.length > 0) {
  192. var correctAnswerInExamQuestion = this.examQuestionList[order - 1]
  193. .correctAnswer;
  194. //如果是字母,说明是旧数据
  195. var reg = /^[a-zA-Z]+$/; //匹配任意字母
  196. if (
  197. correctAnswerInExamQuestion &&
  198. reg.test(correctAnswerInExamQuestion)
  199. ) {
  200. question.studentAnswer = studentAnswer;
  201. question.correctAnswer = correctAnswerInExamQuestion;
  202. for (var i1 = 0; i1 < optionList.length; i1++) {
  203. var letter1 = String.fromCharCode(i1 + 65);
  204. optionList[i1].letter = letter1;
  205. }
  206. question.quesOptions = optionList; //选项
  207. } else {
  208. var optionPermutation = this.examQuestionList[order - 1]
  209. .optionPermutation;
  210. for (var i2 = 0; i2 < optionList.length; i2++) {
  211. optionList[i2].optionId = i2;
  212. }
  213. //按照optionPermutation排序
  214. var newOptionList = [];
  215. for (var i3 = 0; i3 < optionPermutation.length; i3++) {
  216. var optionId = optionPermutation[i3];
  217. for (var i4 = 0; i4 < optionList.length; i4++) {
  218. if (optionList[i4].optionId == optionId) {
  219. newOptionList.push(optionList[i4]);
  220. break;
  221. }
  222. }
  223. }
  224. var newCorrectAnswer = []; //正确答案
  225. var newStudentAnswer = []; //考生作答
  226. for (var i5 = 0; i5 < newOptionList.length; i5++) {
  227. var letter = String.fromCharCode(i5 + 65);
  228. newOptionList[i5].letter = letter;
  229. if (
  230. correctAnswer &&
  231. correctAnswer.indexOf(newOptionList[i5].optionId.toString()) > -1
  232. ) {
  233. newCorrectAnswer.push(letter);
  234. }
  235. if (
  236. studentAnswer &&
  237. studentAnswer.indexOf(newOptionList[i5].optionId.toString()) > -1
  238. ) {
  239. newStudentAnswer.push(letter);
  240. }
  241. }
  242. question.quesOptions = newOptionList; //选项
  243. question.correctAnswer = newCorrectAnswer;
  244. question.studentAnswer = newStudentAnswer;
  245. }
  246. } else {
  247. question.studentAnswer = studentAnswer;
  248. question.correctAnswer = correctAnswer;
  249. if (question.questionType == "TRUE_OR_FALSE") {
  250. if (studentAnswer == "true") {
  251. question.studentAnswer = "正确";
  252. } else if (studentAnswer == "false") {
  253. question.studentAnswer = "错误";
  254. }
  255. if (correctAnswer == "true") {
  256. question.correctAnswer = "正确";
  257. } else if (correctAnswer == "false") {
  258. question.correctAnswer = "错误";
  259. }
  260. }
  261. }
  262. question.questionScore = questionScore;
  263. if (question.studentAnswer) {
  264. question.studentAnswer = question.studentAnswer.toString();
  265. }
  266. if (question.correctAnswer) {
  267. question.correctAnswer = question.correctAnswer.toString();
  268. }
  269. if (
  270. question.questionType == "SINGLE_CHOICE" ||
  271. question.questionType == "MULTIPLE_CHOICE" ||
  272. question.questionType == "TRUE_OR_FALSE"
  273. ) {
  274. question.isObjectiveQuestion = true;
  275. }
  276. if (
  277. question.studentAnswer &&
  278. question.correctAnswer &&
  279. question.studentAnswer == question.correctAnswer
  280. ) {
  281. question.isRight = true;
  282. } else {
  283. question.isRight = false;
  284. }
  285. this.$forceUpdate(); //刷新视图
  286. },
  287. toChineseNumber(num) {
  288. return num.toLocaleString("zh-u-nu-hanidec");
  289. },
  290. restoreAudio(str) {
  291. return (str || "")
  292. .replace(/<a/g, "<audio controls ")
  293. .replace(/url=/g, "src=")
  294. .replace(/a>/g, "audio>");
  295. }
  296. },
  297. created() {
  298. this.courseId = this.$route.params.courseId;
  299. this.examRecordDataId = this.$route.params.examRecordDataId;
  300. this.getExamRecordData();
  301. this.getCourseInfo();
  302. this.getPaperData();
  303. }
  304. };
  305. </script>
  306. <style scoped>
  307. #paperView {
  308. background-color: white;
  309. }
  310. #paperName {
  311. text-align: center;
  312. font-size: 32px;
  313. font-weight: bold;
  314. }
  315. #studentInfoDiv {
  316. text-align: center;
  317. margin: 20px 60px;
  318. }
  319. #studentInfoTable {
  320. width: 100%;
  321. height: 70px;
  322. border-collapse: collapse;
  323. }
  324. .mainQuestionDiv {
  325. font-size: 14px;
  326. margin: 20px 60px;
  327. border-bottom: 1px dashed black;
  328. }
  329. .el-icon-check {
  330. color: green;
  331. font-size: 16px;
  332. font-weight: bold;
  333. }
  334. .el-icon-close {
  335. color: red;
  336. font-size: 16px;
  337. font-weight: bold;
  338. }
  339. </style>