judge-question.vue 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. <template>
  2. <!-- 判断题 -->
  3. <view class="judge-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="judge" v-for="(item,index) in questionData.option_list" :key="index" v-if="questionChanged">
  13. <view class="option-left">
  14. <view :class="['option-bj', computedIsJudgeRight(item.mark)]">
  15. <text class="serial-number" :style="{'font-size':questionData.property.option_question_number_font_size}">
  16. {{ isEnable(isEnableManualModify)?(item.custom_number?item.custom_number+'.':''):computedQuestionNumber(index,questionData.option_number_show_mode) }}
  17. </text>
  18. <text v-html="sanitizeHTML(item.content)" :ref="'richText'+index+1+questionData.question_id"
  19. @longpress="previewByRichTextImg(index,1,questionData.question_id)"></text>
  20. </view>
  21. </view>
  22. <view class="determine-right">
  23. <view v-for="option_type in questionData.property.option_type_list" :key="option_type"
  24. @click="determine(item,option_type,index)" :class="[
  25. 'circle-bj',
  26. {
  27. active: isAnswer(item.mark, option_type),
  28. },
  29. isAnswer(item.mark, option_type)?'':computedIsShowRightAnswer(item.mark, option_type),
  30. ]">
  31. <SvgIcon v-if="option_type===option_type_list[0].value" icon-class="checkmarkempty" size="18" />
  32. <SvgIcon v-if="option_type===option_type_list[1].value" icon-class="closeempty" size="14" />
  33. <SvgIcon v-if="option_type===option_type_list[2].value" icon-class="neutral-tone" size="20" />
  34. </view>
  35. </view>
  36. </view>
  37. <view class="reference" v-if="isViewAnalysis&&answer_control[questionData.question_id].isViewRightAnswer">
  38. <text class="reference-title">解析</text>
  39. <text class="reference-answer" v-html="sanitizeHTML(questionData.analysis)"
  40. :ref="'richText-2-2'+questionData.question_id"
  41. @longpress="previewByRichTextImg(-2,-2,questionData.question_id)">
  42. </text>
  43. </view>
  44. </view>
  45. </template>
  46. <script>
  47. import {
  48. questionData,
  49. option_type_list,
  50. sanitizeHTML,
  51. isEnable,
  52. computedQuestionNumber,
  53. answer_control,
  54. } from '@/pages/answer_question/common/data/common.js';
  55. import {
  56. changeNumToHan,
  57. checkNum
  58. } from '@/utils/transform.js';
  59. import AnswerControlMixin from '@/pages/answer_question/common/data/AnswerControlMixin.js';
  60. import {
  61. GetFileURLMap
  62. } from '@/api/api.js';
  63. export default {
  64. name: "judge-question",
  65. mixins: [AnswerControlMixin],
  66. props: {
  67. questionData: questionData,
  68. isEnableManualModify: {
  69. type: String,
  70. default: 'false',
  71. },
  72. },
  73. data() {
  74. return {
  75. computedQuestionNumber,
  76. isEnable,
  77. sanitizeHTML,
  78. option_type_list,
  79. answer_control,
  80. }
  81. },
  82. watch: {
  83. 'questionData': {
  84. handler(val) {
  85. this.$forceUpdate();
  86. },
  87. immediate: true,
  88. deep: true
  89. },
  90. },
  91. computed: {
  92. questionChanged: function() {
  93. this.setUserAnswer()
  94. return true;
  95. },
  96. isViewAnalysis: function() {
  97. return isEnable(this.questionData.property.is_enable_analysis);
  98. }
  99. },
  100. methods: {
  101. determine(item, answer, index) {
  102. if (this.answer_control[this.questionData.question_id].isReadOnly) return;
  103. var questionId = this.questionData.question_id;
  104. this.questionData.user_answer[questionId].isEdit = true;
  105. if (item.answer !== answer)
  106. item.answer = answer;
  107. else
  108. item.answer = '';
  109. var ans = {
  110. mark: item.mark,
  111. option_type: item.answer
  112. };
  113. var preAnswer = this.questionData.user_answer[questionId].answer_list.find(p => p.mark === ans.mark);
  114. if (!preAnswer)
  115. this.questionData.user_answer[questionId].answer_list.push(ans);
  116. else
  117. preAnswer.option_type = item.answer;
  118. var ansed = this.questionData.user_answer[questionId].answer_list.filter(p => p.option_type != '');
  119. this.questionData.user_answer[questionId].is_fill_answer = ansed.length > 0;
  120. this.questionData.user_answer[questionId].content = JSON.stringify(ansed);
  121. this.$set(this.questionData.user_answer[questionId], 'answer_list', ansed);
  122. this.$emit("setSubAnswer", this.questionData.user_answer[questionId], questionId);
  123. },
  124. setUserAnswer: function() {
  125. var that = this;
  126. var callback = function() {
  127. var userAnswer = [];
  128. var questionId = that.questionData.question_id;
  129. var _ua = that.questionData.user_answer[questionId];
  130. if (_ua && _ua.answer_list && _ua.answer_list.length > 0)
  131. userAnswer = _ua.answer_list;
  132. if (userAnswer.length == 0) return;
  133. that.questionData.option_list.forEach(p => {
  134. var _ans = userAnswer.find(x => x.mark === p.mark);
  135. if (_ans)
  136. p.answer = _ans.option_type
  137. })
  138. }
  139. if (that.questionData.isSubSub) {
  140. callback();
  141. } else {
  142. this.$emit("getUserAnswer", this.questionData.question_id, callback);
  143. }
  144. },
  145. isAnswer(mark, option_type) {
  146. return this.questionData.user_answer[this.questionData.question_id].answer_list.some((li) => li.mark === mark &&
  147. li.option_type === option_type);
  148. },
  149. /**
  150. * 计算是否显示正确答案的样式
  151. * @param {string} mark 选项标识
  152. * @param {string} option_type 选项类型
  153. */
  154. computedIsShowRightAnswer(mark, option_type) {
  155. var cur = this.commonComputedAnswerControl(this.questionData.question_id);
  156. if (!cur.isJudgeAnswer && !cur.isViewRightAnswer) {
  157. return [];
  158. }
  159. if (!cur.isViewRightAnswer) return '';
  160. // let selectOption = this.questionData.user_answer[this.questionData.question_id].answer_list.find((item) => item
  161. // .mark === mark); // 查找是否已选中的选项
  162. // if (!selectOption) return '';
  163. // return this.questionData.answer.answer_list.find((item) => item.mark === mark).option_type === option_type &&
  164. // !(selectOption.option_type === option_type) ?
  165. // 'answer-right' :
  166. // '';
  167. //未答题也显示正确样式
  168. return this.questionData.answer.answer_list.find((item) => item.mark === mark).option_type === option_type ?
  169. 'answer-right' :
  170. '';
  171. },
  172. /**
  173. * 计算判断题题干的样式
  174. * @param {string} mark 选项标识
  175. */
  176. computedIsJudgeRight(mark) {
  177. var cur = this.commonComputedAnswerControl(this.questionData.question_id);
  178. if (!cur.isJudgeAnswer && !cur.isViewRightAnswer) {
  179. return [];
  180. }
  181. if (!cur.isJudgeAnswer) return '';
  182. let selectOption = this.questionData.user_answer[this.questionData.question_id].answer_list.find((item) => item
  183. .mark === mark); // 查找是否已选中的选项
  184. if (!selectOption) return 'wrong';
  185. return this.questionData.answer.answer_list.find((item) => item.mark === mark).option_type === selectOption
  186. .option_type ?
  187. 'right' :
  188. 'wrong';
  189. },
  190. }
  191. }
  192. </script>
  193. <style lang="scss" scoped>
  194. .judge {
  195. display: flex;
  196. flex-direction: row;
  197. align-items: center;
  198. margin-bottom: 32rpx;
  199. column-gap: 28rpx;
  200. .option-left {
  201. display: flex;
  202. width: 100%;
  203. font-size: $font-size-serial;
  204. .option-bj {
  205. flex: 1;
  206. display: flex;
  207. align-items: center;
  208. column-gap: 8rpx;
  209. border-radius: 40rpx;
  210. background-color: $uni-bg-color-grey;
  211. padding: 16rpx 24rpx;
  212. &.right {
  213. background-color: $right-bc-color;
  214. }
  215. &.wrong {
  216. border: 1px solid $error-color;
  217. }
  218. .serial-number {
  219. align-self: flex-start;
  220. }
  221. }
  222. }
  223. .determine-right {
  224. display: flex;
  225. column-gap: 10rpx;
  226. .circle-bj {
  227. flex: 1;
  228. display: flex;
  229. align-items: center;
  230. justify-content: center;
  231. width: 80rpx;
  232. height: 80rpx;
  233. border-radius: 50%;
  234. background-color: $uni-bg-color-grey;
  235. &.active {
  236. color: #ffffff;
  237. background-color: $light-main-color;
  238. }
  239. &.answer-right {
  240. color: $right-color;
  241. border: 1px solid $right-color;
  242. }
  243. }
  244. }
  245. }
  246. .reference {
  247. margin: 32rpx 0;
  248. background-color: #f9f8f9;
  249. padding: 24rpx;
  250. .reference-title {
  251. display: block;
  252. line-height: 64rpx;
  253. color: #4E5969;
  254. font-size: 28rpx;
  255. }
  256. .reference-answer {
  257. color: #1D2129;
  258. line-height: 48rpx;
  259. font-size: 14pt;
  260. }
  261. }
  262. </style>