|
@@ -57,16 +57,61 @@
|
|
|
:class="[index === 0 ? 'pinyin-text-left' : '']"
|
|
|
>
|
|
|
<template v-if="item.type === 'input'">
|
|
|
- <el-input
|
|
|
- :key="index"
|
|
|
- v-model="item.value"
|
|
|
- :disabled="disabled"
|
|
|
- :style="[{ width: Math.max(80, item.value.length * 21.3) + 'px' }]"
|
|
|
- />
|
|
|
+ <template v-if="data.property.fill_type === fillTypeList[0].value">
|
|
|
+ <el-input
|
|
|
+ :key="index"
|
|
|
+ v-model="item.value"
|
|
|
+ :disabled="disabled"
|
|
|
+ :style="[{ width: Math.max(80, item.value.length * 21.3) + 'px' }]"
|
|
|
+ />
|
|
|
+ </template>
|
|
|
+ <template v-else-if="data.property.fill_type === fillTypeList[1].value">
|
|
|
+ <el-popover :key="index" placement="top" trigger="click">
|
|
|
+ <div class="word-list">
|
|
|
+ <span
|
|
|
+ v-for="{ content, mark } in data.word_list"
|
|
|
+ :key="mark"
|
|
|
+ class="word-item"
|
|
|
+ @click="handleSelectWord(content, mark, item)"
|
|
|
+ >
|
|
|
+ {{ content }}
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <el-input
|
|
|
+ slot="reference"
|
|
|
+ v-model="item.value"
|
|
|
+ :readonly="true"
|
|
|
+ :class="[data.property.fill_font, ...computedAnswerClass(item.mark)]"
|
|
|
+ :style="[{ width: Math.max(80, item.value.length * 21.3) + 'px' }]"
|
|
|
+ />
|
|
|
+ </el-popover>
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <template v-else-if="data.property.fill_type === fillTypeList[2].value">
|
|
|
+ <span :key="j" class="write-click" @click="handleWriteClick(item)">
|
|
|
+ <img
|
|
|
+ v-show="item.write_base64"
|
|
|
+ style="background-color: #f4f4f4"
|
|
|
+ :src="item.write_base64"
|
|
|
+ alt="write-show"
|
|
|
+ />
|
|
|
+ </span>
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <template v-else-if="data.property.fill_type === fillTypeList[3].value">
|
|
|
+ <SoundRecordBox
|
|
|
+ ref="record"
|
|
|
+ :key="j"
|
|
|
+ type="mini"
|
|
|
+ :many-times="false"
|
|
|
+ class="record-box"
|
|
|
+ :answer-record-list="data.audio_answer_list"
|
|
|
+ :task-model="isJudgingRightWrong ? 'ANSWER' : ''"
|
|
|
+ @handleWav="handleMiniWav($event, item)"
|
|
|
+ />
|
|
|
+ </template>
|
|
|
<span v-if="data.property.pinyin_position === 'bottom'" class="pinyin"> </span>
|
|
|
- <!-- <span v-show="computedAnswerText(li.mark).length > 0" :key="`answer-${indexs}`" class="right-answer">
|
|
|
- {{ computedAnswerText(li.mark) }}
|
|
|
- </span> -->
|
|
|
</template>
|
|
|
<template v-else>
|
|
|
<span v-if="data.property.pinyin_position === 'top'" class="pinyin">
|
|
@@ -85,12 +130,60 @@
|
|
|
<p v-for="(item, index) in col.model_essay" :key="index">
|
|
|
<span v-if="item.type === 'text'" :key="index" v-html="sanitizeHTML(item.value)"></span>
|
|
|
<template v-if="item.type === 'input'">
|
|
|
- <el-input
|
|
|
- :key="index"
|
|
|
- v-model="item.value"
|
|
|
- :disabled="disabled"
|
|
|
- :style="[{ width: Math.max(80, item.value.length * 21.3) + 'px' }]"
|
|
|
- />
|
|
|
+ <template v-if="data.property.fill_type === fillTypeList[0].value">
|
|
|
+ <el-input
|
|
|
+ :key="index"
|
|
|
+ v-model="item.value"
|
|
|
+ :disabled="disabled"
|
|
|
+ :style="[{ width: Math.max(80, item.value.length * 21.3) + 'px' }]"
|
|
|
+ />
|
|
|
+ </template>
|
|
|
+ <template v-else-if="data.property.fill_type === fillTypeList[1].value">
|
|
|
+ <el-popover :key="index" placement="top" trigger="click">
|
|
|
+ <div class="word-list">
|
|
|
+ <span
|
|
|
+ v-for="{ content, mark } in data.word_list"
|
|
|
+ :key="mark"
|
|
|
+ class="word-item"
|
|
|
+ @click="handleSelectWord(content, mark, item)"
|
|
|
+ >
|
|
|
+ {{ content }}
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <el-input
|
|
|
+ slot="reference"
|
|
|
+ v-model="item.value"
|
|
|
+ :readonly="true"
|
|
|
+ :class="[data.property.fill_font, ...computedAnswerClass(item.mark)]"
|
|
|
+ :style="[{ width: Math.max(80, item.value.length * 21.3) + 'px' }]"
|
|
|
+ />
|
|
|
+ </el-popover>
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <template v-else-if="data.property.fill_type === fillTypeList[2].value">
|
|
|
+ <span :key="j" class="write-click" @click="handleWriteClick(item)">
|
|
|
+ <img
|
|
|
+ v-show="item.write_base64"
|
|
|
+ style="background-color: #f4f4f4"
|
|
|
+ :src="item.write_base64"
|
|
|
+ alt="write-show"
|
|
|
+ />
|
|
|
+ </span>
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <template v-else-if="data.property.fill_type === fillTypeList[3].value">
|
|
|
+ <SoundRecordBox
|
|
|
+ ref="record"
|
|
|
+ :key="j"
|
|
|
+ type="mini"
|
|
|
+ :many-times="false"
|
|
|
+ class="record-box"
|
|
|
+ :answer-record-list="data.audio_answer_list"
|
|
|
+ :task-model="isJudgingRightWrong ? 'ANSWER' : ''"
|
|
|
+ @handleWav="handleMiniWav($event, item)"
|
|
|
+ />
|
|
|
+ </template>
|
|
|
<!-- <span v-show="computedAnswerText(li.mark).length > 0" :key="`answer-${indexs}`" class="right-answer">
|
|
|
{{ computedAnswerText(li.mark) }}
|
|
|
</span> -->
|
|
@@ -113,24 +206,30 @@
|
|
|
</table>
|
|
|
</div>
|
|
|
</div>
|
|
|
+ <WriteDialog :visible.sync="writeVisible" @confirm="handleWriteConfirm" />
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
-import { getTableData } from '@/views/book/courseware/data/table';
|
|
|
+import { getTableData, fillTypeList } from '@/views/book/courseware/data/table';
|
|
|
|
|
|
import PreviewMixin from '../common/PreviewMixin';
|
|
|
-import { isEnable } from '../../../data/common';
|
|
|
+import WriteDialog from '../fill/components/WriteDialog.vue';
|
|
|
+import SoundRecordBox from '@/views/book/courseware/preview/components/record_input/SoundRecord.vue';
|
|
|
|
|
|
export default {
|
|
|
name: 'TablePreview',
|
|
|
- components: {},
|
|
|
+ components: { SoundRecordBox, WriteDialog },
|
|
|
mixins: [PreviewMixin],
|
|
|
data() {
|
|
|
return {
|
|
|
data: getTableData(),
|
|
|
table_width: 0,
|
|
|
multilingualTextList: {}, // 多语言对应的切割后的翻译
|
|
|
+ fillTypeList,
|
|
|
+ selectedWordList: [], // 用于存储选中的词汇
|
|
|
+ writeVisible: false,
|
|
|
+ writeMark: '',
|
|
|
};
|
|
|
},
|
|
|
computed: {
|
|
@@ -186,7 +285,6 @@ export default {
|
|
|
this.$set(this.multilingualTextList, item.type, chunkedArr);
|
|
|
});
|
|
|
}
|
|
|
- console.log(this.data);
|
|
|
},
|
|
|
computedAnswerText(mark) {
|
|
|
if (!this.isShowRightAnswer) return '';
|
|
@@ -199,6 +297,65 @@ export default {
|
|
|
if (isRight) return '';
|
|
|
return `(${answerValue})`;
|
|
|
},
|
|
|
+ /**
|
|
|
+ * 计算答题对错选项字体颜色
|
|
|
+ * @param {string} mark 选项标识
|
|
|
+ */
|
|
|
+ computedAnswerClass(mark) {
|
|
|
+ if (!this.isJudgingRightWrong && !this.isShowRightAnswer) {
|
|
|
+ return '';
|
|
|
+ }
|
|
|
+ let selectOption = this.answer.answer_list.find((item) => item.mark === mark);
|
|
|
+ let answerOption = this.data.answer.answer_list.find((item) => item.mark === mark);
|
|
|
+ if (!selectOption) return '';
|
|
|
+ let selectValue = selectOption.value;
|
|
|
+ let answerValue = answerOption.value;
|
|
|
+ let answerType = answerOption.type;
|
|
|
+ let classList = [];
|
|
|
+ let isRight =
|
|
|
+ answerType === 'only_one' ? selectValue === answerValue : answerValue.split('/').includes(selectValue);
|
|
|
+ if (this.isJudgingRightWrong) {
|
|
|
+ isRight ? classList.push('right') : classList.push('wrong');
|
|
|
+ }
|
|
|
+
|
|
|
+ if (this.isShowRightAnswer && !isRight) {
|
|
|
+ classList.push('show-right-answer');
|
|
|
+ }
|
|
|
+ return classList;
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 处理小音频录音
|
|
|
+ * @param {Object} data 音频数据
|
|
|
+ * @param {String} mark 选项标识
|
|
|
+ */
|
|
|
+ handleMiniWav(data, mark) {
|
|
|
+ if (!data || !mark) return;
|
|
|
+ this.$set(mark, 'audio_answer_list', data);
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 处理选中词汇
|
|
|
+ * @param {String} content 选中的词汇内容
|
|
|
+ * @param {String} mark 选项标识
|
|
|
+ * @param {Object} li 当前输入框对象
|
|
|
+ */
|
|
|
+ handleSelectWord(content, mark, li) {
|
|
|
+ if (!content || !mark || !li) return;
|
|
|
+
|
|
|
+ li.value = content;
|
|
|
+ this.selectedWordList.push(mark);
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 处理书写区确认
|
|
|
+ * @param {String} data 书写区数据
|
|
|
+ */
|
|
|
+ handleWriteConfirm(data) {
|
|
|
+ if (!data) return;
|
|
|
+ this.$set(this.writeMark, 'write_base64', data);
|
|
|
+ },
|
|
|
+ handleWriteClick(mark) {
|
|
|
+ this.writeVisible = true;
|
|
|
+ this.writeMark = mark;
|
|
|
+ },
|
|
|
},
|
|
|
};
|
|
|
</script>
|
|
@@ -234,6 +391,28 @@ $border-color: #e6e6e6;
|
|
|
margin: 0;
|
|
|
}
|
|
|
|
|
|
+ .record-box {
|
|
|
+ display: inline-flex;
|
|
|
+ align-items: center;
|
|
|
+ background-color: #fff;
|
|
|
+ border-bottom: 1px solid $font-color;
|
|
|
+ }
|
|
|
+
|
|
|
+ .write-click {
|
|
|
+ display: inline-block;
|
|
|
+ width: 104px;
|
|
|
+ height: 32px;
|
|
|
+ padding: 0 4px;
|
|
|
+ vertical-align: bottom;
|
|
|
+ cursor: pointer;
|
|
|
+ border-bottom: 1px solid $font-color;
|
|
|
+
|
|
|
+ img {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
.el-input {
|
|
|
display: inline-flex;
|
|
|
align-items: center;
|
|
@@ -276,7 +455,8 @@ $border-color: #e6e6e6;
|
|
|
|
|
|
:deep input.el-input__inner {
|
|
|
padding: 0;
|
|
|
- font-size: 16pt;
|
|
|
+
|
|
|
+ // font-size: 16pt;
|
|
|
color: $font-color;
|
|
|
text-align: center;
|
|
|
background-color: #fff;
|
|
@@ -302,13 +482,14 @@ $border-color: #e6e6e6;
|
|
|
}
|
|
|
|
|
|
.pinyin {
|
|
|
+ height: 18px;
|
|
|
font-family: 'League';
|
|
|
font-size: 12px;
|
|
|
}
|
|
|
|
|
|
&-left {
|
|
|
span {
|
|
|
- text-align: left;
|
|
|
+ // text-align: left;
|
|
|
}
|
|
|
}
|
|
|
}
|