Kaynağa Gözat

参考答案与解析、正确答案

dsy 2 ay önce
ebeveyn
işleme
568cd291c3
29 değiştirilmiş dosya ile 277 ekleme ve 39 silme
  1. 1 1
      src/views/book/courseware/create/components/common/AddAnswer.vue
  2. 6 7
      src/views/book/courseware/create/components/question/fill/Fill.vue
  3. 9 0
      src/views/book/courseware/create/components/question/input/Input.vue
  4. 2 0
      src/views/book/courseware/create/components/question/input/InputSetting.vue
  5. 9 0
      src/views/book/courseware/create/components/question/judge/Judge.vue
  6. 2 0
      src/views/book/courseware/create/components/question/judge/JudgeSetting.vue
  7. 9 0
      src/views/book/courseware/create/components/question/matching/Matching.vue
  8. 2 0
      src/views/book/courseware/create/components/question/matching/MatchingSetting.vue
  9. 9 0
      src/views/book/courseware/create/components/question/select/Select.vue
  10. 2 0
      src/views/book/courseware/create/components/question/select/SelectSetting.vue
  11. 9 0
      src/views/book/courseware/create/components/question/sort/Sort.vue
  12. 2 0
      src/views/book/courseware/create/components/question/sort/SortSetting.vue
  13. 9 0
      src/views/book/courseware/create/components/question/voice_matrix/VoiceMatrix.vue
  14. 2 0
      src/views/book/courseware/create/components/question/voice_matrix/VoiceMatrixSetting.vue
  15. 2 0
      src/views/book/courseware/data/input.js
  16. 2 0
      src/views/book/courseware/data/judge.js
  17. 2 0
      src/views/book/courseware/data/matching.js
  18. 2 0
      src/views/book/courseware/data/select.js
  19. 2 0
      src/views/book/courseware/data/sort.js
  20. 2 0
      src/views/book/courseware/data/voiceMatrix.js
  21. 7 1
      src/views/book/courseware/preview/common/AnswerAnalysis.vue
  22. 17 3
      src/views/book/courseware/preview/components/common/PreviewMixin.js
  23. 3 4
      src/views/book/courseware/preview/components/fill/FillPreview.vue
  24. 8 0
      src/views/book/courseware/preview/components/input/InputPreview.vue
  25. 61 1
      src/views/book/courseware/preview/components/judge/JudgePreview.vue
  26. 10 2
      src/views/book/courseware/preview/components/matching/MatchingPreview.vue
  27. 55 2
      src/views/book/courseware/preview/components/select/SelectPreview.vue
  28. 23 18
      src/views/book/courseware/preview/components/sort/SortPreview.vue
  29. 8 0
      src/views/book/courseware/preview/components/voice_matrix/VoiceMatrixPreview.vue

+ 1 - 1
src/views/book/courseware/create/components/common/AddAnswer.vue

@@ -1,7 +1,7 @@
 <template>
   <div>
     <el-divider />
-    <el-form-item label="附加功能">
+    <el-form-item label="附加功能" label-width="60">
       <el-button type="primary" size="mini" @click="addAnswerAndAnalysis('answer')">添加参考答案</el-button>
       <el-button type="primary" size="mini" @click="addAnswerAndAnalysis('analysis')">添加解析</el-button>
     </el-form-item>

+ 6 - 7
src/views/book/courseware/create/components/question/fill/Fill.vue

@@ -76,6 +76,12 @@
         </div>
       </template>
 
+      <MultilingualFill
+        :visible.sync="multilingualVisible"
+        :text="data.content"
+        :translations="data.multilingual"
+        @SubmitTranslation="handleMultilingualTranslation"
+      />
       <AnswerAnalysisList
         v-if="data.answer_list.length > 0 || data.analysis_list.length > 0"
         :answer-list="data.answer_list"
@@ -84,13 +90,6 @@
         @updateAnswerAnalysisFileList="updateAnswerAnalysisFileList"
         @deleteAnswerAnalysis="deleteAnswerAnalysis"
       />
-
-      <MultilingualFill
-        :visible.sync="multilingualVisible"
-        :text="data.content"
-        :translations="data.multilingual"
-        @SubmitTranslation="handleMultilingualTranslation"
-      />
     </template>
   </ModuleBase>
 </template>

+ 9 - 0
src/views/book/courseware/create/components/question/input/Input.vue

@@ -17,6 +17,15 @@
         :translations="data.multilingual"
         @SubmitTranslation="handleMultilingualTranslation"
       />
+
+      <AnswerAnalysisList
+        v-if="data.answer_list.length > 0 || data.analysis_list.length > 0"
+        :answer-list="data.answer_list"
+        :analysis-list="data.analysis_list"
+        :unified-attrib="data.unified_attrib"
+        @updateAnswerAnalysisFileList="updateAnswerAnalysisFileList"
+        @deleteAnswerAnalysis="deleteAnswerAnalysis"
+      />
     </template>
   </ModuleBase>
 </template>

+ 2 - 0
src/views/book/courseware/create/components/question/input/InputSetting.vue

@@ -57,6 +57,8 @@
       <el-form-item label="输入框背景颜色" label-width="120px">
         <el-color-picker v-model="property.background_color" :show-alpha="true" />
       </el-form-item>
+
+      <AddAnswer />
     </el-form>
   </div>
 </template>

+ 9 - 0
src/views/book/courseware/create/components/question/judge/Judge.vue

@@ -50,6 +50,15 @@
         :pinyin-position="data.property.pinyin_position"
         @fillCorrectPinyin="fillCorrectPinyin($event, i)"
       />
+
+      <AnswerAnalysisList
+        v-if="data.answer_list.length > 0 || data.analysis_list.length > 0"
+        :answer-list="data.answer_list"
+        :analysis-list="data.analysis_list"
+        :unified-attrib="data.unified_attrib"
+        @updateAnswerAnalysisFileList="updateAnswerAnalysisFileList"
+        @deleteAnswerAnalysis="deleteAnswerAnalysis"
+      />
     </template>
   </ModuleBase>
 </template>

+ 2 - 0
src/views/book/courseware/create/components/question/judge/JudgeSetting.vue

@@ -40,6 +40,8 @@
           >句首大写</el-checkbox
         >
       </el-form-item>
+
+      <AddAnswer />
     </el-form>
   </div>
 </template>

+ 9 - 0
src/views/book/courseware/create/components/question/matching/Matching.vue

@@ -65,6 +65,15 @@
         :translations="data.option_list[curSelectRow][curSelectColumn].multilingual"
         @SubmitTranslation="handleMultilingualTranslation"
       />
+
+      <AnswerAnalysisList
+        v-if="data.answer_list.length > 0 || data.analysis_list.length > 0"
+        :answer-list="data.answer_list"
+        :analysis-list="data.analysis_list"
+        :unified-attrib="data.unified_attrib"
+        @updateAnswerAnalysisFileList="updateAnswerAnalysisFileList"
+        @deleteAnswerAnalysis="deleteAnswerAnalysis"
+      />
     </template>
   </ModuleBase>
 </template>

+ 2 - 0
src/views/book/courseware/create/components/question/matching/MatchingSetting.vue

@@ -49,6 +49,8 @@
           >句首大写</el-checkbox
         >
       </el-form-item>
+
+      <AddAnswer />
     </el-form>
   </div>
 </template>

+ 9 - 0
src/views/book/courseware/create/components/question/select/Select.vue

@@ -52,6 +52,15 @@
         :translations="data.option_list[curSelectIndex].multilingual"
         @SubmitTranslation="handleMultilingualTranslation"
       />
+
+      <AnswerAnalysisList
+        v-if="data.answer_list.length > 0 || data.analysis_list.length > 0"
+        :answer-list="data.answer_list"
+        :analysis-list="data.analysis_list"
+        :unified-attrib="data.unified_attrib"
+        @updateAnswerAnalysisFileList="updateAnswerAnalysisFileList"
+        @deleteAnswerAnalysis="deleteAnswerAnalysis"
+      />
     </template>
   </ModuleBase>
 </template>

+ 2 - 0
src/views/book/courseware/create/components/question/select/SelectSetting.vue

@@ -48,6 +48,8 @@
           >句首大写</el-checkbox
         >
       </el-form-item>
+
+      <AddAnswer />
     </el-form>
   </div>
 </template>

+ 9 - 0
src/views/book/courseware/create/components/question/sort/Sort.vue

@@ -60,6 +60,15 @@
         :translations="data.option_list[curSelectIndex].multilingual"
         @SubmitTranslation="handleMultilingualTranslation"
       />
+
+      <AnswerAnalysisList
+        v-if="data.answer_list.length > 0 || data.analysis_list.length > 0"
+        :answer-list="data.answer_list"
+        :analysis-list="data.analysis_list"
+        :unified-attrib="data.unified_attrib"
+        @updateAnswerAnalysisFileList="updateAnswerAnalysisFileList"
+        @deleteAnswerAnalysis="deleteAnswerAnalysis"
+      />
     </template>
   </ModuleBase>
 </template>

+ 2 - 0
src/views/book/courseware/create/components/question/sort/SortSetting.vue

@@ -47,6 +47,8 @@
           >句首大写</el-checkbox
         >
       </el-form-item>
+
+      <AddAnswer />
     </el-form>
   </div>
 </template>

+ 9 - 0
src/views/book/courseware/create/components/question/voice_matrix/VoiceMatrix.vue

@@ -82,6 +82,15 @@
         :translations="data.option_list[curSelectRow][curSelectColumn].multilingual"
         @SubmitTranslation="handleMultilingualTranslation"
       />
+
+      <AnswerAnalysisList
+        v-if="data.answer_list.length > 0 || data.analysis_list.length > 0"
+        :answer-list="data.answer_list"
+        :analysis-list="data.analysis_list"
+        :unified-attrib="data.unified_attrib"
+        @updateAnswerAnalysisFileList="updateAnswerAnalysisFileList"
+        @deleteAnswerAnalysis="deleteAnswerAnalysis"
+      />
     </template>
   </ModuleBase>
 </template>

+ 2 - 0
src/views/book/courseware/create/components/question/voice_matrix/VoiceMatrixSetting.vue

@@ -30,6 +30,8 @@
           <el-radio v-for="{ value, label } in switchOption" :key="value" :label="value">{{ label }}</el-radio>
         </el-radio-group>
       </el-form-item>
+
+      <AddAnswer />
     </el-form>
   </div>
 </template>

+ 2 - 0
src/views/book/courseware/data/input.js

@@ -112,5 +112,7 @@ export function getInputData() {
       ],
     },
     multilingual: [], // 多语言
+    answer_list: [], // 答案列表
+    analysis_list: [], // 解析列表
   };
 }

+ 2 - 0
src/views/book/courseware/data/judge.js

@@ -58,5 +58,7 @@ export function getJudgeData() {
     mind_map: {
       node_list: [{ name: '4选项判断组件' }],
     },
+    answer_list: [], // 答案列表
+    analysis_list: [], // 解析列表
   };
 }

+ 2 - 0
src/views/book/courseware/data/matching.js

@@ -86,5 +86,7 @@ export function getMatchingData() {
     mind_map: {
       node_list: [{ name: '两行两列连线组件' }],
     },
+    answer_list: [], // 答案列表
+    analysis_list: [], // 解析列表
   };
 }

+ 2 - 0
src/views/book/courseware/data/select.js

@@ -65,5 +65,7 @@ export function getSelectData() {
     mind_map: {
       node_list: [{ name: '横排单选选择题' }],
     },
+    answer_list: [], // 答案列表
+    analysis_list: [], // 解析列表
   };
 }

+ 2 - 0
src/views/book/courseware/data/sort.js

@@ -56,5 +56,7 @@ export function getSortData() {
     mind_map: {
       node_list: [{ name: '3选项横排设定显示排序组件' }],
     },
+    answer_list: [], // 答案列表
+    analysis_list: [], // 解析列表
   };
 }

+ 2 - 0
src/views/book/courseware/data/voiceMatrix.js

@@ -72,5 +72,7 @@ export function getVoiceMatrixData() {
     mind_map: {
       node_list: [{ name: '语音矩阵' }],
     },
+    answer_list: [], // 答案列表
+    analysis_list: [], // 解析列表
   };
 }

+ 7 - 1
src/views/book/courseware/preview/common/AnswerAnalysis.vue

@@ -9,7 +9,7 @@
     :before-close="handleClose"
   >
     <!-- 正确答案 -->
-    <div class="right-answer">
+    <div v-if="hasRightAnswerSlot" class="right-answer">
       <div class="right-answer-title">
         <span class="right-answer-title-icon"></span>
         <span class="right-answer-title-image"></span>
@@ -121,6 +121,12 @@ export default {
   data() {
     return {};
   },
+  computed: {
+    hasRightAnswerSlot() {
+      const slotContent = this.$slots['right-answer']; // 获取名为 'right-answer' 的插槽内容
+      return Array.isArray(slotContent) && slotContent.length > 0; // 检查插槽内容是否存在且不为空
+    },
+  },
   methods: {
     handleClose() {
       this.$emit('update:visible', false);

+ 17 - 3
src/views/book/courseware/preview/components/common/PreviewMixin.js

@@ -20,6 +20,7 @@ const mixin = {
       isEnable,
       loader: false,
       visibleAnswerAnalysis: false, // 是否显示答案解析弹窗
+      answerAnalysisState: null, // 答案解析弹窗前的状态快照
     };
   },
   inject: ['getLang', 'getChinese', 'convertText', 'getTitleList'],
@@ -192,15 +193,28 @@ const mixin = {
       };
     },
     showAnswerAnalysis() {
+      if (!this.answerAnalysisState) {
+        this.answerAnalysisState = {
+          disabled: this.disabled,
+          isJudgingRightWrong: this.isJudgingRightWrong,
+        };
+      }
       this.visibleAnswerAnalysis = true;
       this.disabled = true;
       this.isJudgingRightWrong = true;
       this.isShowRightAnswer = true;
     },
     closeAnswerAnalysis() {
-      this.disabled = false;
-      this.isJudgingRightWrong = false;
-      this.isShowRightAnswer = false;
+      if (this.answerAnalysisState) {
+        this.disabled = this.answerAnalysisState.disabled;
+        this.isJudgingRightWrong = this.answerAnalysisState.isJudgingRightWrong;
+        this.isShowRightAnswer = false;
+        this.answerAnalysisState = null;
+      } else {
+        this.disabled = false;
+        this.isJudgingRightWrong = false;
+        this.isShowRightAnswer = false;
+      }
     },
   },
 };

+ 3 - 4
src/views/book/courseware/preview/components/fill/FillPreview.vue

@@ -29,7 +29,7 @@
                   :key="j"
                   v-model="li.content"
                   :disabled="disabled"
-                  :class="[data.property.fill_font]"
+                  :class="[data.property.fill_font, ...computedAnswerClass(li.mark)]"
                   :style="[{ width: Math.max(80, li.content.length * 21.3) + 'px' }]"
                 />
               </template>
@@ -51,7 +51,7 @@
                     slot="reference"
                     v-model="li.content"
                     :readonly="true"
-                    :class="[data.property.fill_font]"
+                    :class="[data.property.fill_font, ...computedAnswerClass(li.mark)]"
                     class="pinyin"
                     :style="[{ width: Math.max(80, li.content.length * 21.3) + 'px' }]"
                   />
@@ -101,9 +101,8 @@
       </div>
     </div>
 
-    <PreviewOperation @showAnswerAnalysis="showAnswerAnalysis" />
-
     <WriteDialog :visible.sync="writeVisible" @confirm="handleWriteConfirm" />
+    <PreviewOperation @showAnswerAnalysis="showAnswerAnalysis" />
     <AnswerAnalysis
       :visible.sync="visibleAnswerAnalysis"
       :answer-list="data.answer_list"

+ 8 - 0
src/views/book/courseware/preview/components/input/InputPreview.vue

@@ -25,6 +25,14 @@
         {{ data.multilingual.find((item) => item.type === getLang())?.translation }}
       </div>
     </div>
+
+    <PreviewOperation @showAnswerAnalysis="showAnswerAnalysis" />
+    <AnswerAnalysis
+      :visible.sync="visibleAnswerAnalysis"
+      :answer-list="data.answer_list"
+      :analysis-list="data.analysis_list"
+      @closeAnswerAnalysis="closeAnswerAnalysis"
+    />
   </div>
 </template>
 

+ 61 - 1
src/views/book/courseware/preview/components/judge/JudgePreview.vue

@@ -39,7 +39,6 @@
                 {
                   active: isAnswer(mark, option_type),
                 },
-                computedIsShowRightAnswer(mark, option_type),
               ]"
               @click="selectAnswer(mark, option_type)"
             >
@@ -56,6 +55,67 @@
         </li>
       </ul>
     </div>
+
+    <PreviewOperation @showAnswerAnalysis="showAnswerAnalysis" />
+    <AnswerAnalysis
+      :visible.sync="visibleAnswerAnalysis"
+      :answer-list="data.answer_list"
+      :analysis-list="data.analysis_list"
+      @closeAnswerAnalysis="closeAnswerAnalysis"
+    >
+      <ul slot="right-answer" class="option-list">
+        <li
+          v-for="({ content, mark, paragraph_list }, i) in data.option_list"
+          :key="mark"
+          :style="{ cursor: disabled ? 'not-allowed' : 'pointer' }"
+          :class="['option-item', { active: isAnswer(mark) }]"
+        >
+          <div
+            :style="{ borderColor: data.unified_attrib?.topic_color }"
+            :class="['option-content', computedIsJudgeRight(mark)]"
+          >
+            <span class="serial-number">{{ computedOptionNumber(i) }}.</span>
+            <PinyinText
+              v-if="isEnable(data.property.view_pinyin)"
+              class="content"
+              :paragraph-list="paragraph_list"
+              :pinyin-position="data.property.pinyin_position"
+              :is-preview="true"
+            />
+            <div
+              v-else
+              class="rich-text"
+              :style="{ fontSize: type === typeList[0] ? '12pt' : '' }"
+              v-html="convertText(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>
+    </AnswerAnalysis>
   </div>
 </template>
 

+ 10 - 2
src/views/book/courseware/preview/components/matching/MatchingPreview.vue

@@ -34,8 +34,16 @@
           </div>
         </li>
       </ul>
+    </div>
 
-      <div v-if="isShowRightAnswer" class="right-answer">
+    <PreviewOperation @showAnswerAnalysis="showAnswerAnalysis" />
+    <AnswerAnalysis
+      :visible.sync="visibleAnswerAnalysis"
+      :answer-list="data.answer_list"
+      :analysis-list="data.analysis_list"
+      @closeAnswerAnalysis="closeAnswerAnalysis"
+    >
+      <div slot="right-answer" class="right-answer">
         <div class="title">正确答案</div>
         <ul ref="answerList" class="option-list">
           <li v-for="(item, i) in data.option_list" :key="i" class="list-item">
@@ -45,7 +53,7 @@
           </li>
         </ul>
       </div>
-    </div>
+    </AnswerAnalysis>
   </div>
 </template>
 

+ 55 - 2
src/views/book/courseware/preview/components/select/SelectPreview.vue

@@ -38,6 +38,49 @@
         </li>
       </ul>
     </div>
+
+    <PreviewOperation @showAnswerAnalysis="showAnswerAnalysis" />
+    <AnswerAnalysis
+      :visible.sync="visibleAnswerAnalysis"
+      :answer-list="data.answer_list"
+      :analysis-list="data.analysis_list"
+      @closeAnswerAnalysis="closeAnswerAnalysis"
+    >
+      <ul
+        slot="right-answer"
+        class="option-list"
+        :style="{ flexDirection: data.property.arrange_type === arrangeTypeList[0].value ? 'row' : 'column' }"
+      >
+        <li
+          v-for="({ content, mark, multilingual, paragraph_list }, i) in data.option_list"
+          :key="mark"
+          :style="{ cursor: disabled ? 'not-allowed' : 'pointer', borderColor: data.unified_attrib?.topic_color }"
+          :class="['option-item', { active: isAnswer(mark) }, ...computedAnswerClass(mark, 'answer-analysis')]"
+          @click="selectAnswer(mark)"
+        >
+          <span :class="[isSingle ? 'radio' : 'checkbox']">
+            <SvgIcon icon-class="check-mark" width="10" height="7" />
+          </span>
+          <span class="serial-number"> {{ computedOptionNumber(i) }}. </span>
+          <PinyinText
+            v-if="isEnable(data.property.view_pinyin)"
+            class="content"
+            :paragraph-list="paragraph_list"
+            :pinyin-position="data.property.pinyin_position"
+            :is-preview="true"
+          />
+          <span
+            v-else
+            class="content rich-text"
+            :style="{ fontSize: type === typeList[0] ? '12pt' : '' }"
+            v-html="convertText(sanitizeHTML(content))"
+          ></span>
+          <div v-if="showLang" class="lang">
+            {{ multilingual.find((item) => item.type === getLang())?.translation }}
+          </div>
+        </li>
+      </ul>
+    </AnswerAnalysis>
   </div>
 </template>
 
@@ -83,6 +126,10 @@ export default {
       if (!type) return number + 1;
       return computeOptionMethods[type](number);
     },
+    /**
+     * 判断选项是否被选中
+     * @param {string} mark - 选项的标识
+     */
     isAnswer(mark) {
       return this.answer.answer_list.includes(mark);
     },
@@ -99,7 +146,13 @@ export default {
 
       this.answer.answer_list = isSelected ? list.filter((item) => item !== mark) : list.concat(mark);
     },
-    computedAnswerClass(mark) {
+    /**
+     * 计算选项的类名
+     * @param {string} mark - 选项的标识
+     * @param {string} type - 计算类名的类型,默认为 'default',可选值为 'answer-analysis'
+     * @returns {Array} - 选项的类名数组
+     */
+    computedAnswerClass(mark, type = 'default') {
       if (!this.isJudgingRightWrong && !this.isShowRightAnswer) {
         return [];
       }
@@ -107,7 +160,7 @@ export default {
       let isRight = this.data.answer.answer_list.includes(mark); // 是否是正确答案
 
       let answerClass = [];
-      if (!isHas && this.isShowRightAnswer) {
+      if (!isHas && this.isShowRightAnswer && type === 'answer-analysis') {
         answerClass = isRight ? ['answer-right'] : [];
       }
       // 判断是否是正确答案

+ 23 - 18
src/views/book/courseware/preview/components/sort/SortPreview.vue

@@ -39,25 +39,30 @@
           </transition-group>
         </draggable>
       </ul>
-
-      <template v-if="isShowRightAnswer && !is_all_right">
-        <div class="right-title">正确答案:</div>
-        <ul class="option-list">
-          <draggable v-model="right_answer_list" animation="300" :disabled="true">
-            <transition-group
-              class="group"
-              :style="{
-                flexDirection: data.property.arrange_direction === arrangeTypeList[0].value ? 'row' : 'column',
-              }"
-            >
-              <li v-for="(item, i) in right_answer_list" :key="i" :class="['drag-item']">
-                <span class="rich-text" v-html="convertText(sanitizeHTML(item.content))"></span>
-              </li>
-            </transition-group>
-          </draggable>
-        </ul>
-      </template>
     </div>
+
+    <PreviewOperation @showAnswerAnalysis="showAnswerAnalysis" />
+    <AnswerAnalysis
+      :visible.sync="visibleAnswerAnalysis"
+      :answer-list="data.answer_list"
+      :analysis-list="data.analysis_list"
+      @closeAnswerAnalysis="closeAnswerAnalysis"
+    >
+      <ul slot="right-answer" class="option-list">
+        <draggable v-model="right_answer_list" animation="300" :disabled="true">
+          <transition-group
+            class="group"
+            :style="{
+              flexDirection: data.property.arrange_direction === arrangeTypeList[0].value ? 'row' : 'column',
+            }"
+          >
+            <li v-for="(item, i) in right_answer_list" :key="i" :class="['drag-item']">
+              <span class="rich-text" v-html="convertText(sanitizeHTML(item.content))"></span>
+            </li>
+          </transition-group>
+        </draggable>
+      </ul>
+    </AnswerAnalysis>
   </div>
 </template>
 

+ 8 - 0
src/views/book/courseware/preview/components/voice_matrix/VoiceMatrixPreview.vue

@@ -208,6 +208,14 @@
         />
       </div>
     </div>
+
+    <PreviewOperation @showAnswerAnalysis="showAnswerAnalysis" />
+    <AnswerAnalysis
+      :visible.sync="visibleAnswerAnalysis"
+      :answer-list="data.answer_list"
+      :analysis-list="data.analysis_list"
+      @closeAnswerAnalysis="closeAnswerAnalysis"
+    />
   </div>
 </template>