|
|
@@ -10,25 +10,25 @@
|
|
|
:file-id="data.audio_file_id"
|
|
|
/>
|
|
|
<div class="fill-wrapper">
|
|
|
- <p v-for="(item, i) in modelEssay" :key="i">
|
|
|
- <template v-for="(li, j) in item">
|
|
|
+ <p>
|
|
|
+ <template v-for="(li, i) in modelEssay">
|
|
|
<template v-if="li.type === 'text'">
|
|
|
<PinyinText
|
|
|
v-if="isEnable(data.property.view_pinyin)"
|
|
|
- :key="`${i}-${j}`"
|
|
|
+ :key="`text-${i}`"
|
|
|
class="content"
|
|
|
:paragraph-list="li.paragraph_list"
|
|
|
:rich-text-list="li.rich_text_list"
|
|
|
:pinyin-position="data.property.pinyin_position"
|
|
|
:is-preview="true"
|
|
|
/>
|
|
|
- <span v-else :key="j" class="html-content" v-html="convertText(sanitizeHTML(li.content))"></span>
|
|
|
+ <span v-else :key="`text-${i}`" class="html-content" v-html="renderTextBlockContent(li)"></span>
|
|
|
</template>
|
|
|
<template v-if="li.type === 'input'">
|
|
|
<!-- 输入填空 -->
|
|
|
<template v-if="data.property.fill_type === fillTypeList[0].value">
|
|
|
<el-input
|
|
|
- :key="j"
|
|
|
+ :key="`input-${i}`"
|
|
|
:ref="`input-${li.mark}`"
|
|
|
v-model="li.input"
|
|
|
:disabled="disabled"
|
|
|
@@ -45,7 +45,7 @@
|
|
|
|
|
|
<!-- 选词填空 -->
|
|
|
<template v-else-if="data.property.fill_type === fillTypeList[1].value">
|
|
|
- <el-popover :key="j" placement="top" trigger="click">
|
|
|
+ <el-popover :key="`popover-${i}`" placement="top" trigger="click">
|
|
|
<div class="word-list">
|
|
|
<span
|
|
|
v-for="{ content, mark } in data.word_list"
|
|
|
@@ -68,7 +68,7 @@
|
|
|
|
|
|
<!-- 手写填空 -->
|
|
|
<template v-else-if="data.property.fill_type === fillTypeList[2].value">
|
|
|
- <span :key="j" class="write-click" @click="handleWriteClick(li.mark)">
|
|
|
+ <span :key="`write-${i}`" class="write-click" @click="handleWriteClick(li.mark)">
|
|
|
<img
|
|
|
v-show="li.write_base64"
|
|
|
style="background-color: #f4f4f4"
|
|
|
@@ -82,7 +82,7 @@
|
|
|
<template v-else-if="data.property.fill_type === fillTypeList[3].value">
|
|
|
<SoundRecordBox
|
|
|
ref="record"
|
|
|
- :key="j"
|
|
|
+ :key="`record-${i}`"
|
|
|
type="mini"
|
|
|
:many-times="false"
|
|
|
class="record-box"
|
|
|
@@ -112,8 +112,12 @@
|
|
|
</div>
|
|
|
|
|
|
<WriteDialog :visible.sync="writeVisible" @confirm="handleWriteConfirm" />
|
|
|
- <PreviewOperation :is-show-answer="isShowAnswer" @showAnswerAnalysis="showAnswerAnalysis" @retry="retry" />
|
|
|
- <AnswerCorrect :visible.sync="visibleAnswerCorrect" @closeAnswerCorrect="closeAnswerCorrect" />
|
|
|
+ <PreviewOperation @showAnswerAnalysis="showAnswerAnalysis" @judgeCorrect="judgeCorrect" @retry="retry" />
|
|
|
+ <AnswerCorrect
|
|
|
+ :visible.sync="visibleAnswerCorrect"
|
|
|
+ :is-check-correct="isCheckCorrect"
|
|
|
+ @closeAnswerCorrect="closeAnswerCorrect"
|
|
|
+ />
|
|
|
<AnswerAnalysis
|
|
|
:visible.sync="visibleAnswerAnalysis"
|
|
|
:answer-list="data.answer_list"
|
|
|
@@ -121,22 +125,22 @@
|
|
|
@closeAnswerAnalysis="closeAnswerAnalysis"
|
|
|
>
|
|
|
<div slot="right-answer" class="fill-wrapper">
|
|
|
- <p v-for="(item, i) in modelEssay" :key="i">
|
|
|
- <template v-for="(li, j) in item">
|
|
|
+ <p>
|
|
|
+ <template v-for="(li, i) in modelEssay">
|
|
|
<template v-if="li.type === 'text'">
|
|
|
<PinyinText
|
|
|
v-if="isEnable(data.property.view_pinyin)"
|
|
|
- :key="`${i}-${j}`"
|
|
|
+ :key="`answer-text-${i}`"
|
|
|
class="content"
|
|
|
:paragraph-list="li.paragraph_list"
|
|
|
:rich-text-list="li.rich_text_list"
|
|
|
:pinyin-position="data.property.pinyin_position"
|
|
|
:is-preview="true"
|
|
|
/>
|
|
|
- <span v-else :key="j" v-html="convertText(sanitizeHTML(li.content))"></span>
|
|
|
+ <span v-else :key="`answer-text-${i}`" class="html-content" v-html="renderTextBlockContent(li)"></span>
|
|
|
</template>
|
|
|
<template v-if="li.type === 'input'">
|
|
|
- <span v-show="computedAnswerText(li.mark).length > 0" :key="`answer-${j}`" class="right-answer">
|
|
|
+ <span v-show="computedAnswerText(li.mark).length > 0" :key="`answer-${i}`" class="right-answer">
|
|
|
{{ computedAnswerText(li.mark) }}
|
|
|
</span>
|
|
|
</template>
|
|
|
@@ -176,36 +180,13 @@ export default {
|
|
|
writeMark: '',
|
|
|
};
|
|
|
},
|
|
|
- computed: {
|
|
|
- isShowAnswer() {
|
|
|
- return (
|
|
|
- (Array.isArray(this.data.answer_list) && this.data.answer_list.length > 0) ||
|
|
|
- (Array.isArray(this.data.analysis_list) && this.data.analysis_list.length > 0)
|
|
|
- );
|
|
|
- },
|
|
|
- },
|
|
|
watch: {
|
|
|
'data.model_essay': {
|
|
|
handler(list) {
|
|
|
if (!list || !Array.isArray(list)) return;
|
|
|
|
|
|
this.modelEssay = JSON.parse(JSON.stringify(list));
|
|
|
- this.answer.answer_list = list
|
|
|
- .map((item) => {
|
|
|
- return item
|
|
|
- .map(({ type, content, audio_answer_list, mark }) => {
|
|
|
- if (type === 'input') {
|
|
|
- return {
|
|
|
- value: content,
|
|
|
- mark,
|
|
|
- audio_answer_list,
|
|
|
- write_base64: '',
|
|
|
- };
|
|
|
- }
|
|
|
- })
|
|
|
- .filter((item) => item);
|
|
|
- })
|
|
|
- .flat();
|
|
|
+ this.syncAnswerList(list);
|
|
|
},
|
|
|
deep: true,
|
|
|
immediate: true,
|
|
|
@@ -214,22 +195,7 @@ export default {
|
|
|
handler(list) {
|
|
|
if (!list || !Array.isArray(list)) return;
|
|
|
|
|
|
- this.answer.answer_list = list
|
|
|
- .map((item) => {
|
|
|
- return item
|
|
|
- .map(({ type, input, audio_answer_list, mark }) => {
|
|
|
- if (type === 'input') {
|
|
|
- return {
|
|
|
- value: input,
|
|
|
- mark,
|
|
|
- audio_answer_list,
|
|
|
- write_base64: '',
|
|
|
- };
|
|
|
- }
|
|
|
- })
|
|
|
- .filter((item) => item);
|
|
|
- })
|
|
|
- .flat();
|
|
|
+ this.syncAnswerList(list);
|
|
|
},
|
|
|
deep: true,
|
|
|
immediate: true,
|
|
|
@@ -238,13 +204,10 @@ export default {
|
|
|
if (!val) return;
|
|
|
|
|
|
this.answer.answer_list.forEach(({ mark, value }) => {
|
|
|
- this.modelEssay.forEach((item) => {
|
|
|
- item.forEach((li) => {
|
|
|
- if (li.mark === mark) {
|
|
|
- li.input = value;
|
|
|
- }
|
|
|
- });
|
|
|
- });
|
|
|
+ const li = this.modelEssay.find((item) => item.mark === mark);
|
|
|
+ if (li) {
|
|
|
+ li.input = value;
|
|
|
+ }
|
|
|
});
|
|
|
|
|
|
this.handleWav(this.answer.record_list);
|
|
|
@@ -257,6 +220,36 @@ export default {
|
|
|
handleWav(data) {
|
|
|
this.data.record_list = data;
|
|
|
},
|
|
|
+ renderContent(content) {
|
|
|
+ return this.convertText(this.sanitizeHTML(content));
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 渲染文本块内容
|
|
|
+ * @param {Object} textBlock 文本块对象,包含纯文本内容和富文本内容
|
|
|
+ */
|
|
|
+ renderTextBlockContent(textBlock) {
|
|
|
+ const richTextList = textBlock?.rich_text_list;
|
|
|
+ if (Array.isArray(richTextList) && richTextList.length > 0) {
|
|
|
+ const richHtml = richTextList.map((item) => item?.text || '').join('');
|
|
|
+ return this.renderContent(richHtml);
|
|
|
+ }
|
|
|
+ return this.renderContent(textBlock?.content || '');
|
|
|
+ },
|
|
|
+ syncAnswerList(list) {
|
|
|
+ this.answer.answer_list = list
|
|
|
+ .map(({ type, input, audio_answer_list, mark }) => {
|
|
|
+ if (type === 'input') {
|
|
|
+ return {
|
|
|
+ value: input,
|
|
|
+ mark,
|
|
|
+ audio_answer_list,
|
|
|
+ write_base64: '',
|
|
|
+ };
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ })
|
|
|
+ .filter((item) => item);
|
|
|
+ },
|
|
|
/**
|
|
|
* 处理小音频录音
|
|
|
* @param {Object} data 音频数据
|
|
|
@@ -264,12 +257,9 @@ export default {
|
|
|
*/
|
|
|
handleMiniWav(data, mark) {
|
|
|
if (!data || !mark) return;
|
|
|
- for (const item of this.modelEssay) {
|
|
|
- const li = item.find((li) => li?.mark === mark);
|
|
|
- if (li) {
|
|
|
- this.$set(li, 'audio_answer_list', data);
|
|
|
- break;
|
|
|
- }
|
|
|
+ const li = this.modelEssay.find((item) => item?.mark === mark);
|
|
|
+ if (li) {
|
|
|
+ this.$set(li, 'audio_answer_list', data);
|
|
|
}
|
|
|
},
|
|
|
/**
|
|
|
@@ -290,12 +280,9 @@ export default {
|
|
|
*/
|
|
|
handleWriteConfirm(data) {
|
|
|
if (!data) return;
|
|
|
- for (const item of this.modelEssay) {
|
|
|
- const li = item.find((li) => li?.mark === this.writeMark);
|
|
|
- if (li) {
|
|
|
- this.$set(li, 'write_base64', data);
|
|
|
- break;
|
|
|
- }
|
|
|
+ const li = this.modelEssay.find((item) => item?.mark === this.writeMark);
|
|
|
+ if (li) {
|
|
|
+ this.$set(li, 'write_base64', data);
|
|
|
}
|
|
|
},
|
|
|
handleWriteClick(mark) {
|
|
|
@@ -382,7 +369,7 @@ export default {
|
|
|
}
|
|
|
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 '';
|
|
|
+ if (!selectOption || !answerOption) return '';
|
|
|
let selectValue = selectOption.value;
|
|
|
let answerValue = answerOption.value;
|
|
|
let answerType = answerOption.type;
|
|
|
@@ -404,20 +391,21 @@ export default {
|
|
|
*/
|
|
|
computedAnswerText(mark) {
|
|
|
let answerOption = this.data.answer.answer_list.find((item) => item.mark === mark);
|
|
|
+ if (!answerOption) return '';
|
|
|
let answerValue = answerOption.value;
|
|
|
return `${answerValue}`;
|
|
|
},
|
|
|
// 重做
|
|
|
retry() {
|
|
|
- this.modelEssay.forEach((item) => {
|
|
|
- item.forEach((li) => {
|
|
|
- if (li.type === 'input') {
|
|
|
- li.input = '';
|
|
|
- li.write_base64 = '';
|
|
|
- }
|
|
|
- });
|
|
|
+ this.modelEssay.forEach((li) => {
|
|
|
+ if (li.type === 'input') {
|
|
|
+ li.input = '';
|
|
|
+ li.write_base64 = '';
|
|
|
+ }
|
|
|
});
|
|
|
this.selectedWordList = [];
|
|
|
+ this.isJudgingRightWrong = false;
|
|
|
+ this.isShowRightAnswer = false;
|
|
|
this.handleWav([]);
|
|
|
},
|
|
|
/**
|