|
@@ -0,0 +1,182 @@
|
|
|
+<template>
|
|
|
+ <div class="judge-preview" :style="getAreaStyle()">
|
|
|
+ <SerialNumberPosition v-if="isEnable(data.property.sn_display_mode)" :property="data.property" />
|
|
|
+ <div class="main">
|
|
|
+ <ul class="option-list">
|
|
|
+ <li
|
|
|
+ v-for="({ content, mark }, i) in data.option_list"
|
|
|
+ :key="mark"
|
|
|
+ :style="{ cursor: disabled ? 'not-allowed' : 'pointer' }"
|
|
|
+ :class="['option-item', { active: isAnswer(mark) }]"
|
|
|
+ >
|
|
|
+ <div :class="['option-content', computedIsJudgeRight(mark)]">
|
|
|
+ <span class="serial-number">{{ convertNumberToLetter(i) }}.</span>
|
|
|
+ <div class="rich-text" v-html="sanitizeHTML(content)"></div>
|
|
|
+ </div>
|
|
|
+ <div class="option-type">
|
|
|
+ <div
|
|
|
+ v-for="option_type in incertitudeList"
|
|
|
+ :key="option_type"
|
|
|
+ :style="{ cursor: disabled ? 'not-allowed' : 'pointer' }"
|
|
|
+ :class="[
|
|
|
+ 'option-type-item',
|
|
|
+ {
|
|
|
+ active: isAnswer(mark, option_type),
|
|
|
+ },
|
|
|
+ computedIsShowRightAnswer(mark, option_type),
|
|
|
+ ]"
|
|
|
+ @click="selectAnswer(mark, option_type)"
|
|
|
+ >
|
|
|
+ <SvgIcon
|
|
|
+ v-if="option_type === option_type_list[0].value"
|
|
|
+ icon-class="check-mark"
|
|
|
+ width="17"
|
|
|
+ height="12"
|
|
|
+ />
|
|
|
+ <SvgIcon v-if="option_type === option_type_list[1].value" icon-class="cross" size="12" />
|
|
|
+ <SvgIcon v-if="option_type === option_type_list[2].value" icon-class="circle" size="16" />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </li>
|
|
|
+ </ul>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import { getJudgeData, option_type_list, isEnable } from '@/views/book/courseware/data/judge';
|
|
|
+import PreviewMixin from '../common/PreviewMixin';
|
|
|
+
|
|
|
+export default {
|
|
|
+ name: 'JudgePreview',
|
|
|
+ mixins: [PreviewMixin],
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ data: getJudgeData(),
|
|
|
+ option_type_list,
|
|
|
+ isEnable,
|
|
|
+ };
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ incertitudeList() {
|
|
|
+ let _option_type_list = this.data.property.option_type_list;
|
|
|
+ if (isEnable(this.data.property.is_view_incertitude)) {
|
|
|
+ return _option_type_list;
|
|
|
+ }
|
|
|
+ // 返回不包含第三个元素的新数组
|
|
|
+ return [..._option_type_list.slice(0, 2), ..._option_type_list.slice(3)];
|
|
|
+ },
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ // 将数字转换为小写字母
|
|
|
+ convertNumberToLetter(number) {
|
|
|
+ return String.fromCharCode(97 + number);
|
|
|
+ },
|
|
|
+
|
|
|
+ isAnswer(mark, option_type) {
|
|
|
+ return this.answer.answer_list.some((li) => li.mark === mark && li.option_type === option_type);
|
|
|
+ },
|
|
|
+
|
|
|
+ //选择答案
|
|
|
+ selectAnswer(mark, option_type) {
|
|
|
+ if (this.disabled) return;
|
|
|
+ const index = this.answer.answer_list.findIndex((li) => li.mark === mark);
|
|
|
+ if (index === -1) {
|
|
|
+ this.answer.answer_list.push({ mark, option_type });
|
|
|
+ } else {
|
|
|
+ this.answer.answer_list[index].option_type = option_type;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 计算判断题小题题目样式
|
|
|
+ computedIsJudgeRight(mark) {
|
|
|
+ if (!this.isJudgingRightWrong) return '';
|
|
|
+ let selectOption = this.answer.answer_list.find((item) => item.mark === mark); // 查找是否已选中的选项
|
|
|
+ if (!selectOption) return 'wrong';
|
|
|
+ return this.data.answer.answer_list.find((item) => item.mark === mark).option_type === selectOption.option_type
|
|
|
+ ? 'right'
|
|
|
+ : 'wrong';
|
|
|
+ },
|
|
|
+ // 计算是否显示正确答案的样式
|
|
|
+ computedIsShowRightAnswer(mark, option_type) {
|
|
|
+ if (!this.isShowRightAnswer) return '';
|
|
|
+ let selectOption = this.answer.answer_list.find((item) => item.mark === mark); // 查找是否已选中的选项
|
|
|
+ // 是否是正确的选项类型
|
|
|
+ let isCorrectType = this.data.answer.answer_list.find((item) => item.mark === mark)?.option_type === option_type;
|
|
|
+ if (!selectOption) {
|
|
|
+ return isCorrectType ? 'answer-right' : '';
|
|
|
+ }
|
|
|
+ return isCorrectType && !(selectOption.option_type === option_type) ? 'answer-right' : '';
|
|
|
+ },
|
|
|
+ },
|
|
|
+};
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+@use '@/styles/mixin.scss' as *;
|
|
|
+
|
|
|
+.judge-preview {
|
|
|
+ @include preview-base;
|
|
|
+
|
|
|
+ .option-list {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ row-gap: 16px;
|
|
|
+
|
|
|
+ .option-item {
|
|
|
+ display: flex;
|
|
|
+ column-gap: 16px;
|
|
|
+
|
|
|
+ .option-content {
|
|
|
+ display: flex;
|
|
|
+ flex: 1;
|
|
|
+ column-gap: 8px;
|
|
|
+ align-items: center;
|
|
|
+ padding: 12px 24px;
|
|
|
+ background-color: $content-color;
|
|
|
+ border-radius: 40px;
|
|
|
+
|
|
|
+ &.right {
|
|
|
+ background-color: $right-bc-color;
|
|
|
+ }
|
|
|
+
|
|
|
+ &.wrong {
|
|
|
+ box-shadow: 0 0 0 1px $error-color;
|
|
|
+ }
|
|
|
+
|
|
|
+ .serial-number {
|
|
|
+ font-size: 16pt;
|
|
|
+ color: #000;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .option-type {
|
|
|
+ display: flex;
|
|
|
+ column-gap: 8px;
|
|
|
+ align-items: center;
|
|
|
+
|
|
|
+ &-item {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ width: 48px;
|
|
|
+ height: 48px;
|
|
|
+ color: #000;
|
|
|
+ cursor: pointer;
|
|
|
+ background-color: $content-color;
|
|
|
+ border-radius: 50%;
|
|
|
+
|
|
|
+ &.active {
|
|
|
+ color: #fff;
|
|
|
+ background-color: $light-main-color;
|
|
|
+ }
|
|
|
+
|
|
|
+ &.answer-right {
|
|
|
+ color: $right-color;
|
|
|
+ border: 1px solid $right-color;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|