Browse Source

1. 答题增加选择题目 2. 填空题、听后填空增加选词填空、原先的描述改为提示

dusenyao 1 year ago
parent
commit
3a5443054c

+ 73 - 12
src/views/exercise_questions/answer/index.vue

@@ -6,10 +6,35 @@
         <span>返回</span>
       </div>
       <div class="question-info">
-        <div class="round">
-          <SvgIcon icon-class="list" />
-          <span>{{ curQuestionIndex + 1 }} / {{ questionList.length }}</span>
-        </div>
+        <el-popover
+          v-model="isShowQuestionList"
+          :width="200"
+          :disabled="isStart"
+          trigger="click"
+          popper-class="question-wrapper"
+        >
+          <ul class="question-list">
+            <li
+              v-for="({ id, type: question_type }, i) in questionList"
+              :key="id"
+              :class="[{ active: i === curQuestionIndex }]"
+              @click="selectQuestion(i)"
+            >
+              <span>{{ i + 1 }}.</span>
+              <span>{{ exerciseNames[question_type] }}</span>
+            </li>
+          </ul>
+
+          <div
+            slot="reference"
+            :style="{ backgroundColor: isShowQuestionList ? '#E9E8EA' : '' }"
+            class="round question-index"
+          >
+            <SvgIcon icon-class="list" />
+            <span>{{ curQuestionIndex + 1 }} / {{ questionList.length }}</span>
+            <span>{{ curQuestionIndex < 0 ? '' : exerciseNames[questionList[curQuestionIndex].type] }}</span>
+          </div>
+        </el-popover>
         <div v-if="!isTeacherAnnotations" class="round primary">
           <SvgIcon icon-class="hourglass" />{{ secondFormatConversion(time) }}
         </div>
@@ -18,12 +43,7 @@
 
     <main class="main">
       <StartQuestion
-        v-if="
-          curQuestionIndex === -1 &&
-          !(user_answer_record_info.is_exist_answer_record === 'true') &&
-          !isShow &&
-          !isSubmit
-        "
+        v-if="isStart"
         :question-length="questionList.length"
         :answer-time-limit-minute="answer_time_limit_minute"
         @startAnswer="startAnswer"
@@ -146,6 +166,7 @@ import {
 } from '@/api/exercise';
 import { subjectiveQuestionList } from './answer';
 import { fileUpload } from '@/api/app';
+import { exerciseNames } from '@/views/exercise_questions/data/questionType';
 
 import StartQuestion from './components/StartQuestion.vue';
 import AnswerReport from './components/AnswerReport.vue';
@@ -219,9 +240,19 @@ export default {
         },
         question_list: [],
       }, // 答题报告
+      exerciseNames,
+      isShowQuestionList: false, // 是否显示题目列表
     };
   },
   computed: {
+    isStart() {
+      return (
+        this.curQuestionIndex === -1 &&
+        !(this.user_answer_record_info.is_exist_answer_record === 'true') &&
+        !this.isShow &&
+        !this.isSubmit
+      );
+    },
     // 是否教师批改
     isTeacherAnnotations() {
       return this.question_index >= 0 && this.isTeacher && this.type !== 'show';
@@ -532,8 +563,10 @@ export default {
     },
 
     selectQuestion(i) {
-      this.isSubmit = false;
-      this.isView = true;
+      if (this.isSubmit) {
+        this.isSubmit = false;
+        this.isView = true;
+      }
       this.curQuestionIndex = i;
     },
     upload(file) {
@@ -591,6 +624,10 @@ export default {
     .question-info {
       display: flex;
       column-gap: 12px;
+
+      .question-index {
+        cursor: pointer;
+      }
     }
   }
 
@@ -735,4 +772,28 @@ export default {
     }
   }
 }
+
+.question-wrapper {
+  max-height: 60vh;
+  padding: 8px;
+  overflow: auto;
+  border-radius: 8px;
+  box-shadow: 0 2px 8px 0 #00000040;
+
+  .question-list {
+    li {
+      display: flex;
+      column-gap: 8px;
+      align-items: center;
+      padding: 8px 16px;
+      cursor: pointer;
+
+      &.active {
+        color: $main-color;
+        background-color: #f4f8ff;
+        border-radius: 2px;
+      }
+    }
+  }
+}
 </style>

+ 20 - 4
src/views/exercise_questions/create/components/exercises/FillQuestion.vue

@@ -5,12 +5,18 @@
         <RichText v-model="data.stem" :font-size="18" placeholder="输入题干" />
 
         <el-input
-          v-if="isEnable(data.property.is_enable_description)"
-          v-model="data.description"
+          v-if="isEnable(data.property.is_enable_word_fill)"
+          v-model="data.word_fill"
           rows="3"
           resize="none"
           type="textarea"
-          placeholder="输入填空内容"
+          placeholder="输入词汇"
+        />
+
+        <RichText
+          v-if="isEnable(data.property.is_enable_description)"
+          v-model="data.description"
+          placeholder="输入提示"
         />
       </div>
 
@@ -59,7 +65,17 @@
             <el-option v-for="item in fontSizeList" :key="item" :label="item" :value="item" />
           </el-select>
         </el-form-item>
-        <el-form-item label="描述">
+        <el-form-item label="选词填空">
+          <el-radio
+            v-for="{ value, label } in switchOption"
+            :key="value"
+            v-model="data.property.is_enable_word_fill"
+            :label="value"
+          >
+            {{ label }}
+          </el-radio>
+        </el-form-item>
+        <el-form-item label="提示">
           <el-radio
             v-for="{ value, label } in switchOption"
             :key="value"

+ 22 - 4
src/views/exercise_questions/create/components/exercises/ListenFillQuestion.vue

@@ -12,12 +12,18 @@
         />
 
         <el-input
-          v-if="isEnable(data.property.is_enable_description)"
-          v-model="data.description"
+          v-if="isEnable(data.property.is_enable_word_fill)"
+          v-model="data.word_fill"
           rows="3"
           resize="none"
           type="textarea"
-          placeholder="输入填空内容"
+          placeholder="输入词汇"
+        />
+
+        <RichText
+          v-if="isEnable(data.property.is_enable_description)"
+          v-model="data.description"
+          placeholder="输入提示"
         />
       </div>
 
@@ -74,7 +80,19 @@
             <el-option v-for="item in fontSizeList" :key="item" :label="item" :value="item" />
           </el-select>
         </el-form-item>
-        <el-form-item label="描述">
+
+        <el-form-item label="选词填空">
+          <el-radio
+            v-for="{ value, label } in switchOption"
+            :key="value"
+            v-model="data.property.is_enable_word_fill"
+            :label="value"
+          >
+            {{ label }}
+          </el-radio>
+        </el-form-item>
+
+        <el-form-item label="提示">
           <el-radio
             v-for="{ value, label } in switchOption"
             :key="value"

+ 2 - 0
src/views/exercise_questions/data/fill.js

@@ -25,6 +25,7 @@ export const fillData = {
   type: 'fill', // 题型
   stem: '', // 题干
   file_id_list: [], // 文件 id 列表
+  word_fill: '', // 选词
   description: '', // 描述
   article: '', // 文章
   model_essay: [], // 文章解析后的数据
@@ -34,6 +35,7 @@ export const fillData = {
     stem_type: stemTypeList[1].value, // 题干类型
     question_number: '1', // 题号
     stem_question_number_font_size: fontSizeList[6], // 题干题号
+    is_enable_word_fill: switchOption[0].value, // 选词填空
     is_enable_description: switchOption[0].value, // 描述
     score: 1, // 分值
     score_type: scoreTypeList[0].value, // 分值类型

+ 2 - 0
src/views/exercise_questions/data/listenFill.js

@@ -25,6 +25,7 @@ export const listenFillData = {
   type: 'listen_fill', // 题型
   stem: '', // 题干
   file_id_list: [], // 文件 id 列表
+  word_fill: '', // 选词
   description: '', // 描述
   article: '', // 文章
   model_essay: [], // 文章解析后的数据
@@ -35,6 +36,7 @@ export const listenFillData = {
     question_number: '1', // 题号
     stem_question_number_font_size: fontSizeList[6], // 题干题号
     is_enable_listening: switchOption[0].value, // 是否听力
+    is_enable_word_fill: switchOption[0].value, // 选词填空
     is_enable_description: switchOption[0].value, // 描述
     score: 1, // 分值
     score_type: scoreTypeList[0].value, // 分值类型

+ 12 - 5
src/views/exercise_questions/preview/FillPreview.vue

@@ -7,12 +7,19 @@
       </span>
       <span v-html="sanitizeHTML(data.stem)"></span>
     </div>
-    <div v-if="isEnable(data.property.is_enable_description)" class="description">
-      <span v-for="(text, i) in descriptionList" :key="i" class="description-item" @click="selectedDescription(text)">
+
+    <div v-if="isEnable(data.property.is_enable_word_fill)" class="word-fill">
+      <span v-for="(text, i) in wordFillList" :key="i" class="word-fill-item" @click="selectedDescription(text)">
         {{ text }}
       </span>
     </div>
 
+    <div
+      v-if="isEnable(data.property.is_enable_description)"
+      class="description rich-text"
+      v-html="sanitizeHTML(data.description)"
+    ></div>
+
     <div class="fill-wrapper">
       <p v-for="(item, i) in modelEssay" :key="i">
         <template v-for="(li, j) in item">
@@ -57,8 +64,8 @@ export default {
     };
   },
   computed: {
-    descriptionList() {
-      return this.data.description.split(/\s+/).filter((item) => item);
+    wordFillList() {
+      return this.data.word_fill.split(/\s+/).filter((item) => item);
     },
   },
   watch: {
@@ -221,7 +228,7 @@ export default {
 .fill-preview {
   @include preview;
 
-  .description {
+  .word-fill {
     display: flex;
     flex-wrap: wrap;
     gap: 4px 8px;

+ 11 - 5
src/views/exercise_questions/preview/ListenFillPreview.vue

@@ -7,12 +7,18 @@
       </span>
       <span v-html="sanitizeHTML(data.stem)"></span>
     </div>
-    <div v-if="isEnable(data.property.is_enable_description)" class="description">
-      <span v-for="(text, i) in descriptionList" :key="i" class="description-item" @click="selectedDescription(text)">
+    <div v-if="isEnable(data.property.is_enable_word_fill)" class="word-fill">
+      <span v-for="(text, i) in wordFillList" :key="i" class="word-fill-item" @click="selectedDescription(text)">
         {{ text }}
       </span>
     </div>
 
+    <div
+      v-if="isEnable(data.property.is_enable_description)"
+      class="description rich-text"
+      v-html="sanitizeHTML(data.description)"
+    ></div>
+
     <AudioPlay
       v-if="isEnable(data.property.is_enable_listening) && data.file_id_list.length > 0"
       :file-id="data.file_id_list[0]"
@@ -64,8 +70,8 @@ export default {
     };
   },
   computed: {
-    descriptionList() {
-      return this.data.description.split(/\s+/).filter((item) => item);
+    wordFillList() {
+      return this.data.word_fill.split(/\s+/).filter((item) => item);
     },
   },
   watch: {
@@ -207,7 +213,7 @@ export default {
 .fill-preview {
   @include preview;
 
-  .description {
+  .word-fill {
     display: flex;
     flex-wrap: wrap;
     gap: 4px 8px;