natasha 1 år sedan
förälder
incheckning
f644f8e88e

+ 3 - 0
src/views/exercise_questions/create/components/create.vue

@@ -62,6 +62,7 @@ import WordCardQuestion from './exercises/WordCardQuestion.vue';
 import AnswerQuestion from './exercises/AnswerQuestion.vue';
 import WritePictureQuestion from './exercises/WritePictureQuestion.vue';
 import ReplaceAnswerQuestion from './exercises/ReplaceAnswerQuestion.vue';
+import EssayQuestion from './exercises/EssayQuestion.vue';
 
 export default {
   name: 'CreateMain',
@@ -87,6 +88,7 @@ export default {
     AnswerQuestion,
     WritePictureQuestion,
     ReplaceAnswerQuestion,
+    EssayQuestion,
   },
   provide() {
     return {
@@ -130,6 +132,7 @@ export default {
         answer_question: AnswerQuestion,
         write_picture: WritePictureQuestion,
         replace_answer: ReplaceAnswerQuestion,
+        essay_question: EssayQuestion,
       },
     };
   },

+ 124 - 0
src/views/exercise_questions/create/components/exercises/EssayQuestion.vue

@@ -0,0 +1,124 @@
+<template>
+  <QuestionBase>
+    <template #content>
+      <div class="stem">
+        <el-input
+          v-if="data.property.stem_type === stemTypeList[0].value"
+          v-model="data.stem"
+          rows="3"
+          resize="none"
+          type="textarea"
+          placeholder="输入题干"
+        />
+
+        <RichText v-if="data.property.stem_type === stemTypeList[1].value" v-model="data.stem" placeholder="输入题干" />
+
+        <el-input
+          v-show="isEnable(data.property.is_enable_description)"
+          v-model="data.description"
+          rows="3"
+          resize="none"
+          type="textarea"
+          placeholder="输入描述"
+        />
+        <el-input
+          v-if="isEnable(data.property.is_enable_reference_answer)"
+          v-model="data.reference_answer"
+          type="textarea"
+          rows="3"
+          placeholder="输入参考答案"
+        />
+      </div>
+    </template>
+
+    <template #property>
+      <el-form :model="data.property">
+        <el-form-item label="题干">
+          <el-radio
+            v-for="{ value, label } in stemTypeList"
+            :key="value"
+            v-model="data.property.stem_type"
+            :label="value"
+          >
+            {{ label }}
+          </el-radio>
+        </el-form-item>
+        <el-form-item label="题号">
+          <el-input v-model="data.property.question_number" />
+        </el-form-item>
+        <el-form-item label-width="45px">
+          <el-radio
+            v-for="{ value, label } in questionNumberTypeList"
+            :key="value"
+            v-model="data.other.question_number_type"
+            :label="value"
+          >
+            {{ label }}
+          </el-radio>
+        </el-form-item>
+        <el-form-item label="描述">
+          <el-radio
+            v-for="{ value, label } in switchOption"
+            :key="value"
+            v-model="data.property.is_enable_description"
+            :label="value"
+          >
+            {{ label }}
+          </el-radio>
+        </el-form-item>
+        <el-form-item label="参考答案">
+          <el-radio
+            v-for="{ value, label } in switchOption"
+            :key="value"
+            v-model="data.property.is_enable_reference_answer"
+            :label="value"
+          >
+            {{ label }}
+          </el-radio>
+        </el-form-item>
+
+        <el-form-item label="分值">
+          <el-radio
+            v-for="{ value, label } in scoreTypeList"
+            :key="value"
+            v-model="data.property.score_type"
+            :label="value"
+          >
+            {{ label }}
+          </el-radio>
+        </el-form-item>
+        <el-form-item label-width="45px">
+          <el-input-number
+            v-model="data.property.score"
+            :min="0"
+            :step="data.property.score_type === scoreTypeList[0].value ? 1 : 0.1"
+          />
+        </el-form-item>
+      </el-form>
+    </template>
+  </QuestionBase>
+</template>
+
+<script>
+import QuestionMixin from '../common/QuestionMixin.js';
+
+import { essayQuestionData } from '@/views/exercise_questions/data/essayQuestion';
+
+export default {
+  name: 'EssayQuestion',
+  components: {},
+  mixins: [QuestionMixin],
+  data() {
+    return {
+      data: JSON.parse(JSON.stringify(essayQuestionData)),
+    };
+  },
+  methods: {},
+};
+</script>
+
+<style lang="scss" scoped>
+.stem {
+  border-bottom-width: 0 !important;
+}
+</style>

+ 3 - 0
src/views/exercise_questions/data/PreviewQuestionTypeMixin.js

@@ -18,6 +18,7 @@ import WordCardPreview from '../preview/WordCardPreview.vue';
 import AnswerQuestionPreview from '../preview/AnswerQuestionPreview.vue';
 import WritePictruePreview from '../preview/WritePictruePreview.vue';
 import ReplaceAnswerPreview from '../preview/ReplaceAnswerPreview.vue';
+import EssayQuestionPreview from '../preview/EssayQuestionPreview.vue';
 
 const PreviewQuestionTypeMixin = {
   components: {
@@ -41,6 +42,7 @@ const PreviewQuestionTypeMixin = {
     AnswerQuestionPreview,
     WritePictruePreview,
     ReplaceAnswerPreview,
+    EssayQuestionPreview,
   },
   data() {
     return {
@@ -65,6 +67,7 @@ const PreviewQuestionTypeMixin = {
         answer_question: AnswerQuestionPreview,
         write_picture: WritePictruePreview,
         replace_answer: ReplaceAnswerPreview,
+        essay_question: EssayQuestionPreview,
       },
     };
   },

+ 1 - 0
src/views/exercise_questions/data/common.js

@@ -12,6 +12,7 @@ export const questionTypeOption = [
       { label: '排序题', value: 'sort' },
       { label: '连线题', value: 'matching' },
       { label: '选择声调', value: 'choose_tone' },
+      { label: '问答题', value: 'essay_question' },
     ],
   },
   {

+ 25 - 0
src/views/exercise_questions/data/essayQuestion.js

@@ -0,0 +1,25 @@
+import { stemTypeList, questionNumberTypeList, scoreTypeList, switchOption } from './common';
+
+// 朗读题数据模板
+export const essayQuestionData = {
+  type: 'essay_question', // 题型
+  stem: '', // 题干
+  description: '', // 描述
+  answer: {
+    score: 0,
+    score_type: scoreTypeList[0].value,
+  }, // 答案
+  // 题型属性
+  property: {
+    stem_type: stemTypeList[0].value, // 题干类型
+    question_number: '1', // 题号
+    is_enable_description: switchOption[0].value, // 描述
+    is_enable_reference_answer: switchOption[0].value, // 是否开启参考答案
+    score: 1, // 分值
+    score_type: scoreTypeList[0].value, // 分值类型
+  },
+  // 其他属性
+  other: {
+    question_number_type: questionNumberTypeList[0].value, // 题号类型
+  },
+};

+ 102 - 0
src/views/exercise_questions/preview/EssayQuestionPreview.vue

@@ -0,0 +1,102 @@
+<!-- eslint-disable vue/no-v-html -->
+<template>
+  <div class="essayquestion-preview">
+    <div class="stem">
+      <span class="question-number">{{ data.property.question_number }}.</span>
+      <span v-html="sanitizeHTML(data.stem)"></span>
+    </div>
+    <div v-if="isEnable(data.property.is_enable_description)" class="description">{{ data.description }}</div>
+
+    <el-input
+      v-model="answer.answer_list.value"
+      rows="12"
+      resize="none"
+      type="textarea"
+      placeholder="请输入"
+      :maxlength="1000"
+      show-word-limit
+      @input="handleInput"
+    />
+    <SoundRecordPreview :wav-blob.sync="answer.answer_list.voice_file_id" />
+    <UploadFiles
+      :fille-number="999"
+      file-type-name="文件"
+      :upload-type="'*'"
+      :file-id-list="answer.answer_list.accessory_file_id"
+      upload-title="上传附件:"
+      @upload="handleUpload"
+      @deleteFile="handleDelete"
+    />
+    <div v-if="isEnable(data.property.is_enable_reference_answer) && 1 === 2" class="reference-box">
+      <h5 class="reference-title">参考答案</h5>
+      <span class="reference-answer" v-html="sanitizeHTML(data.reference_answer)"></span>
+    </div>
+  </div>
+</template>
+
+<script>
+import PreviewMixin from './components/PreviewMixin';
+import SoundRecordPreview from './components/common/SoundRecordPreview.vue';
+import UploadFiles from './components/common/UploadFiles.vue';
+
+export default {
+  name: 'EssayQuestionPreview',
+  components: {
+    SoundRecordPreview,
+    UploadFiles,
+  },
+  mixins: [PreviewMixin],
+  data() {
+    return {
+      answer: {
+        answer_list: {
+          voice_file_id: '',
+          value: '',
+          accessory_file_id: [],
+        },
+      },
+    };
+  },
+  created() {},
+  methods: {
+    // 文件上传成功
+    handleUpload(fileId) {
+      this.answer.answer_list.accessory_file_id.push(fileId);
+    },
+    // 删除文件
+    handleDelete(fileId) {
+      this.answer.answer_list.accessory_file_id.splice(this.answer.answer_list.accessory_file_id.indexOf(fileId), 1);
+    },
+    handleInput(value) {
+      if (value.length >= 1000) {
+        this.$message.warning(`字数达到1000字!`);
+      }
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+@use '@/styles/mixin.scss' as *;
+
+.essayquestion-preview {
+  @include preview;
+
+  :deep .sound-record-wrapper {
+    justify-content: center;
+  }
+
+  .reference-box {
+    padding: 12px;
+    background: #f9f8f9;
+
+    .reference-title {
+      margin: 0 0 10px;
+      font-size: 14px;
+      font-weight: 400;
+      line-height: 32px;
+      color: #4e5969;
+    }
+  }
+}
+</style>

+ 15 - 6
src/views/exercise_questions/preview/WritePictruePreview.vue

@@ -28,10 +28,18 @@
             />
           </el-carousel-item>
         </el-carousel>
-        <h3 class="pic-title" v-html="sanitizeHTML(data.option_list[active_index].picture_title)"></h3>
-        <p class="pic-info" v-html="sanitizeHTML(data.option_list[active_index].picture_info)"></p>
+        <h3
+          v-if="data.option_list[active_index] && data.option_list[active_index].picture_title"
+          class="pic-title"
+          v-html="sanitizeHTML(data.option_list[active_index].picture_title)"
+        ></h3>
+        <p
+          v-if="data.option_list[active_index] && data.option_list[active_index].picture_info"
+          class="pic-info"
+          v-html="sanitizeHTML(data.option_list[active_index].picture_info)"
+        ></p>
       </div>
-      <div class="content-right">
+      <div class="content-right" v-if="answer_list[active_index]">
         <el-input
           v-model="answer_list[active_index].value"
           rows="12"
@@ -54,6 +62,7 @@
         upload-title="上传附件:"
         @upload="handleUpload"
         @deleteFile="handleDelete"
+        v-if="answer_list[active_index]"
       />
     </template>
     <template v-if="isEnable(data.property.is_enable_sample_text)">
@@ -117,12 +126,12 @@ export default {
     },
     // 文件上传成功
     handleUpload(fileId) {
-      this.user_answer[this.active_index].accessory_file_id.push(fileId);
+      this.answer_list[this.active_index].accessory_file_id.push(fileId);
     },
     // 删除文件
     handleDelete(fileId) {
-      this.user_answer[this.active_index].accessory_file_id.splice(
-        this.user_answer.accessory_file_id.indexOf(fileId),
+      this.answer_list[this.active_index].accessory_file_id.splice(
+        this.answer_list[this.active_index].accessory_file_id.indexOf(fileId),
         1,
       );
     },