read-question.vue 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. <template>
  2. <!-- 阅读题 -->
  3. <view class="read-area" v-model="questionData">
  4. <view class="question_title">
  5. <text class="question_number">
  6. {{ questionNumberEndIsBracket(questionData.property.question_number) }}
  7. </text>
  8. <text class="question_stem" v-html="sanitizeHTML(questionData.stem)"
  9. :ref="'richText-1-1'+questionData.question_id"
  10. @longpress="previewByRichTextImg(-1,-1,questionData.question_id)"></text>
  11. </view>
  12. <view class="description"
  13. v-if="isEnable(questionData.property.is_enable_description)&&questionData.description.length > 0"
  14. v-html="sanitizeHTML(questionData.description)" :ref="'richText-2-2'+questionData.question_id"
  15. @longpress="previewByRichTextImg(-2,-2,questionData.question_id)">
  16. </view>
  17. <view class="article-area">
  18. <text class="article" v-html="sanitizeHTML(questionData.article)" :ref="'richText-3-3'+questionData.question_id"
  19. @longpress="previewByRichTextImg(-3,-3,questionData.question_id)"></text>
  20. </view>
  21. <view class="title-split"></view>
  22. <view class="option-area">
  23. <view v-if="isViewQuestion" v-for="(item, index) in questionData.question_list" :key="index">
  24. <SelectQuestion :questionData="item" :isEnableManualModify="questionData.property.is_enable_manual_modify"
  25. @setSubAnswer="setSubAnswer" v-if="item.type==='select' && item.isLoaded" ref="sub_exercise">
  26. </SelectQuestion>
  27. <JudgeQuestion :questionData="item" :isEnableManualModify="questionData.property.is_enable_manual_modify"
  28. @setSubAnswer="setSubAnswer" v-if="item.type==='judge'&&item.isLoaded" ref="sub_exercise">
  29. </JudgeQuestion>
  30. <MatchingQuestion :questionData="item" :isEnableManualModify="questionData.property.is_enable_manual_modify"
  31. @setSubAnswer="setSubAnswer" v-if="item.type==='matching'&&item.isLoaded" ref="sub_exercise">
  32. </MatchingQuestion>
  33. <FillQuestion :questionData="item" @setSubAnswer="setSubAnswer" v-if="item.type==='fill'&&item.isLoaded"
  34. ref="sub_exercise">
  35. </FillQuestion>
  36. <EssayQuestion :questionData="item" @setSubAnswer="setSubAnswer"
  37. v-if="item.type==='essay_question'&&item.isLoaded" ref="sub_exercise">
  38. </EssayQuestion>
  39. </view>
  40. </view>
  41. </view>
  42. </template>
  43. <script>
  44. import {
  45. questionData,
  46. sanitizeHTML,
  47. isEnable,
  48. answer_control,
  49. } from '@/pages/answer_question/common/data/common.js';
  50. import {
  51. GetShareRecordInfo,
  52. GetExerciseQuestionIndexList,
  53. GetQuestionInfo,
  54. StartAnswer,
  55. GetQuestionInfo_AnswerRecord,
  56. FillQuestionAnswer,
  57. SubmitAnswer
  58. } from '@/api/exercise.js';
  59. import SelectQuestion from '@/components/select-question/select-question.vue';
  60. import JudgeQuestion from '@/components/judge-question/judge-question.vue';
  61. import MatchingQuestion from '@/components/matching-question/matching-question.vue';
  62. import FillQuestion from '@/components/fill-question/fill-question.vue';
  63. import ShortAnswerQuestion from '@/components/short-answer-question/short-answer-question.vue';
  64. import EssayQuestion from '@/components/essay-question/essay-question.vue';
  65. import AnswerControlMixin from '@/pages/answer_question/common/data/AnswerControlMixin.js';
  66. export default {
  67. name: "read-question",
  68. mixins: [AnswerControlMixin],
  69. components: {
  70. SelectQuestion,
  71. JudgeQuestion,
  72. MatchingQuestion,
  73. FillQuestion,
  74. ShortAnswerQuestion,
  75. EssayQuestion,
  76. },
  77. props: {
  78. questionData: questionData
  79. },
  80. data() {
  81. return {
  82. sanitizeHTML,
  83. isEnable,
  84. answer_control,
  85. isViewQuestion: true,
  86. readQuestionData: questionData,
  87. readQuestionAnswerList: [],
  88. read_question_id: '',
  89. };
  90. },
  91. watch: {
  92. 'questionData.question_list': {
  93. handler(val) {
  94. this.questionData.user_answer.isEdit = true;
  95. },
  96. immediate: true,
  97. deep: true
  98. },
  99. 'questionData.question_id': {
  100. handler(val) {
  101. this.$emit("getUserAnswer", val, null);
  102. var that = this;
  103. var callback = function() {
  104. that.readQuestionData.answer_record_id = that.questionData.answer_record_id;
  105. that.loopWithAsyncAwait().then(function() {
  106. // 循环完成后执行后续操作...
  107. that.isViewQuestion = true;
  108. });
  109. }
  110. this.getReadQuestionUserAnswer(callback);
  111. },
  112. immediate: true,
  113. deep: true
  114. },
  115. 'questionData.isReadQuestionWatch': {
  116. handler(val) {
  117. this.$nextTick().then(() => {
  118. let parent_answer_control = this.commonComputedAnswerControl(this.questionData.question_id);
  119. if (this.$refs.sub_exercise && this.$refs.sub_exercise.length > 0) {
  120. this.questionData.question_list.forEach((p, i) => {
  121. this.$refs.sub_exercise[i]?.showAnswer(
  122. parent_answer_control.isJudgeAnswer,
  123. parent_answer_control.isViewRightAnswer,
  124. parent_answer_control.isReadOnly,
  125. p.question_id,
  126. null,
  127. parent_answer_control.is_objective
  128. );
  129. })
  130. }
  131. })
  132. },
  133. immediate: true,
  134. deep: true
  135. },
  136. },
  137. methods: {
  138. async loopWithAsyncAwait() {
  139. for (let i = 0; i < this.questionData.question_list.length; i++) {
  140. var cur = this.questionData.question_list[i];
  141. await this.getReadQuestionInfo(cur);
  142. this.readQuestionData.parentType = this.questionData.type;
  143. this.readQuestionData.isSubSub = true;
  144. this.readQuestionData.isLoaded = true;
  145. var answer = this.readQuestionAnswerList.find(p => p.id == cur.id);
  146. if (answer) {
  147. this.readQuestionData.user_answer[cur.id].answer_list = answer.answer_list;
  148. this.setDefaultData(this.questionData.user_answer, cur.id);
  149. this.questionData.user_answer[cur.id].answer_list = answer.answer_list;
  150. }
  151. this.questionData.question_list[i] = this.readQuestionData;
  152. this.$forceUpdate();
  153. }
  154. },
  155. //获取题目详情
  156. async getReadQuestionInfo(question) {
  157. var that = this;
  158. await GetQuestionInfo({
  159. "question_id": question.id
  160. }).then((res) => {
  161. if (res.status && res.question && res.question.content) {
  162. var _questionData = JSON.parse(res.question.content);
  163. if (Array.isArray(_questionData.option_list)) {
  164. _questionData.option_list.forEach(p => {
  165. p.answer = '',
  166. p.checked = false
  167. })
  168. }
  169. _questionData.file_list = res.file_list;
  170. _questionData.question_id = question.id;
  171. //this.questionData, _questionData合并为新对象{},属性值重复的后者覆盖前者
  172. that.readQuestionData = Object.assign({}, that.readQuestionData, _questionData);
  173. this.setDefaultData(that.readQuestionData.user_answer, question.id);
  174. }
  175. })
  176. },
  177. setSubAnswer(userAnswer, sub_question_id) {
  178. // console.log('设置答案', userAnswer);
  179. var parent_question_id = this.questionData.question_id;
  180. this.questionData.user_answer[parent_question_id].isEdit = true;
  181. this.questionData.user_answer[sub_question_id] = userAnswer;
  182. },
  183. //设置某个题目的答案默认格式
  184. setDefaultData(userAnswer, question_id) {
  185. if (!userAnswer[question_id]) {
  186. userAnswer[question_id] = {
  187. is_fill_answer: false, // 用户是否填写答案,
  188. content: '', // 答案内容(JSON 格式文本),
  189. answer_list: [],
  190. isEdit: false,
  191. }
  192. }
  193. },
  194. //获取答案
  195. getReadQuestionUserAnswer: function(callback) {
  196. var that = this;
  197. GetQuestionInfo_AnswerRecord({
  198. answer_record_id: that.questionData.answer_record_id,
  199. question_id: that.questionData.question_id
  200. }).then((res) => {
  201. // if (!res.status) return;
  202. that.questionData.remark = res.remark;
  203. let lst = [];
  204. if (res.user_answer.content) {
  205. var obj = JSON.parse(res.user_answer.content);
  206. if (obj)
  207. lst = obj.question_list;
  208. }
  209. that.readQuestionAnswerList = lst;
  210. if (callback && typeof callback === 'function') {
  211. callback();
  212. }
  213. })
  214. },
  215. },
  216. }
  217. </script>
  218. <style lang="scss" scoped>
  219. .read-area {
  220. .article-area {
  221. margin-top: 32rpx;
  222. font-size: $font-size-serial;
  223. background-color: $uni-bg-color-grey;
  224. border-radius: 16rpx;
  225. padding: 24rpx;
  226. }
  227. .title-split {
  228. margin: 48rpx 0 28rpx 0;
  229. height: 20rpx;
  230. position: relative;
  231. width: 110%;
  232. left: -5%;
  233. background: $uni-bg-color-grey;
  234. box-shadow: 0px 2px 10px rgba(0, 0, 0, 0.1) inset;
  235. }
  236. .option-area {
  237. display: flex;
  238. flex-direction: column;
  239. row-gap: 32rpx;
  240. uni-view:not(:last-child) {
  241. border-bottom: 1px solid #CDCDCD;
  242. }
  243. }
  244. }
  245. </style>