123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257 |
- <!-- eslint-disable vue/no-v-html -->
- <template>
- <div v-if="show_preview" class="replace-preview">
- <div class="stem">
- <span class="question-number" :style="{ fontSize: data.property.stem_question_number_font_size }">
- {{ questionNumberEndIsBracket(data.property.question_number) }}
- </span>
- <span v-html="sanitizeHTML(data.stem)"></span>
- </div>
- <div
- v-if="isEnable(data.property.is_enable_description)"
- class="description rich-text"
- v-html="sanitizeHTML(data.description)"
- ></div>
- <div class="option-list">
- <div v-for="(item, i) in option_list" :key="i" :class="['option-item']">
- <template v-if="item.length > 1">
- <span class="select-item select-active">{{ active_content[i] }}</span>
- <ul
- :ref="'ui' + i"
- class="replace-ul"
- :style="{ overflow: disabled ? 'hidden' : 'scroll' }"
- @scroll="handleScroll($event, i)"
- >
- <li
- v-for="(items, j) in item"
- :key="j"
- :class="[computedAnswerClass(i, items)]"
- @click="handleClickItem(i, j)"
- >
- {{ items.content }}
- </li>
- </ul>
- </template>
- <span v-else class="select-item replace-ul">{{ item[0].content }}</span>
- </div>
- <SoundRecordPreview
- :wav-blob.sync="answer.answer_list[0].audio_file_id"
- :disabled="disabled"
- position="center"
- v-if="answer.answer_list[0] && answer.answer_list[0].hasOwnProperty('audio_file_id')"
- />
- </div>
- <div v-if="isEnable(data.property.is_enable_reference_answer) && isShowRightAnswer" class="reference-box">
- <h5 class="reference-title">参考答案</h5>
- <span class="reference-answer rich-text" v-html="sanitizeHTML(data.reference_answer)"></span>
- </div>
- <div v-if="isEnable(data.property.is_enable_analysis) && isShowRightAnswer" class="analysis">
- <span class="analysis-title">解析</span>
- <div class="analysis-content" v-html="sanitizeHTML(data.analysis)"></div>
- </div>
- </div>
- </template>
- <script>
- import PreviewMixin from './components/PreviewMixin';
- import { computeOptionMethods } from '@/views/exercise_questions/data/common';
- import SoundRecordPreview from './components/common/SoundRecordPreview.vue';
- export default {
- name: 'ReplaceAnswerPreview',
- components: {
- SoundRecordPreview,
- },
- mixins: [PreviewMixin],
- data() {
- return {
- computeOptionMethods,
- option_list: [],
- active_content: [],
- show_preview: false,
- };
- },
- watch: {
- data: {
- handler(val) {
- if (!val || this.data.type !== 'replace_answer') return;
- this.handleData();
- },
- deep: true,
- immediate: true,
- },
- isJudgingRightWrong: {
- handler(val) {
- if (!val) return;
- this.handleData();
- },
- immediate: true,
- },
- },
- created() {},
- mounted() {},
- methods: {
- // 初始化数据
- handleData() {
- this.option_list = [];
- this.active_content = [];
- if (!this.isJudgingRightWrong) {
- this.answer.answer_list = [
- {
- audio_file_id: '',
- mark_list: [],
- },
- ];
- }
- let option_lists = [];
- this.data.option_list[0].forEach(() => {
- option_lists.push([]);
- });
- this.data.option_list.forEach((item) => {
- item.forEach((items, i) => {
- if (items.content) {
- option_lists[i].push(items);
- }
- });
- });
- option_lists.forEach((option_item) => {
- if (option_item.length > 0) {
- this.option_list.push(option_item);
- if (this.isJudgingRightWrong) {
- this.active_content.push('');
- this.answer.answer_list[0].mark_list.forEach((item_mark, index_mark) => {
- this.$refs[`ui${index_mark}`][0].scrollTop = 0;
- option_item.forEach((option_items, index_items) => {
- if (item_mark === option_items.mark) {
- this.active_content[index_mark] = option_items.content;
- setTimeout(() => {
- this.$refs[`ui${index_mark}`][0].scrollTop = index_items * 48;
- }, 100);
- }
- });
- });
- } else {
- this.answer.answer_list[0].mark_list.push(option_item.length > 1 ? option_item[0].mark : '');
- this.active_content.push(option_item.length > 1 ? option_item[0].content : '');
- }
- }
- });
- this.show_preview = true;
- },
- // 处理滚动
- handleScroll(event, i) {
- let scrollTop = event.target.scrollTop;
- let scrollIndex = Math.round(scrollTop / 48);
- this.active_content[i] = this.option_list[i][scrollIndex].content;
- this.answer.answer_list[0].mark_list[i] = this.option_list[i][scrollIndex].mark;
- this.$forceUpdate();
- },
- handleClickItem(i, j) {
- if (this.disabled) return;
- this.$refs[`ui${i}`][0].scrollTop = j * 48;
- this.active_content[i] = this.option_list[i][j].content;
- this.answer.answer_list[0].mark_list[i] = this.option_list[i][j].mark;
- this.$forceUpdate();
- },
- computedAnswerClass(i, item) {
- return this.answer.answer_list[0] &&
- this.answer.answer_list[0].mark_list &&
- this.answer.answer_list[0].mark_list[i] === item.mark
- ? 'active'
- : '';
- },
- },
- };
- </script>
- <style lang="scss" scoped>
- @use '@/styles/mixin.scss' as *;
- .replace-preview {
- @include preview;
- .option-list {
- display: flex;
- flex-wrap: wrap;
- align-items: center;
- justify-content: center;
- width: max-content;
- margin: 0 auto;
- border-left: 1px solid rgba(0, 0, 0, 8%);
- .option-item {
- position: relative;
- display: flex;
- align-items: center;
- height: 356px;
- border-right: 1px solid rgba(0, 0, 0, 8%);
- }
- .select-item {
- padding: 6px 8px;
- font-size: 20px;
- line-height: 28px;
- color: #1d2129;
- background-color: rgba(239, 239, 239, 100%);
- }
- .select-active {
- position: absolute;
- top: 50%;
- left: 0;
- z-index: 1;
- display: block;
- width: 100%;
- height: 40px;
- margin-top: -20px;
- color: rgba(29, 33, 41, 100%);
- background-color: rgba(239, 239, 239, 100%);
- }
- ul {
- height: 356px;
- padding: 158px 0 150px;
- overflow-y: scroll;
- &::-webkit-scrollbar {
- display: none;
- }
- li {
- padding: 6px 8px;
- margin-bottom: 8px;
- font-size: 20px;
- line-height: 28px;
- color: rgba(29, 33, 41, 100%);
- opacity: 0.4;
- }
- }
- }
- .sound-record-preview {
- display: flex;
- flex-wrap: wrap;
- justify-content: center;
- width: 280px;
- margin-left: 80px;
- }
- .reference-box {
- padding: 12px;
- background: $content-color;
- .reference-title {
- margin: 0 0 10px;
- font-size: 14px;
- font-weight: 400;
- line-height: 32px;
- color: $font-light-color;
- }
- :deep p {
- margin: 0;
- }
- }
- }
- </style>
|