Ver código fonte

Merge branch 'master' into lhd

natasha 1 ano atrás
pai
commit
50d86e98cb

+ 46 - 13
src/views/exercise_questions/answer/index.vue

@@ -176,9 +176,8 @@ export default {
           : `${window.location.origin}/GCLS-Learn/#/main?tab=ExerciseList`, // 返回链接
       secondFormatConversion,
       isTeacher: this.$store.getters.isTeacher, // 是否是教师
-      user_answer_record_info: {
-        correct_answer_show_mode: 1, // 正确答案显示模式
-      }, // 当前用户的答题记录信息
+      user_answer_record_info: {}, // 当前用户的答题记录信息
+      correct_answer_show_mode: 1,
       // 问题列表
       questionList: [],
       // 当前问题
@@ -193,7 +192,7 @@ export default {
       answer_time_limit_minute: 30, // 答题时间限制
       time: 1800,
       isSubmit: false,
-      isView: false, // 练习模式下是否查看
+      isView: false, // 是否从答题报告跳转到题目
       curQuestionPage: '', // 当前问题页面
       remark: {
         is_remarked: 'false',
@@ -264,12 +263,16 @@ export default {
       if (this.share_record_id && !this.exercise_id) {
         this.loading = true;
         GetShareRecordInfo({ share_record_id: this.share_record_id }).then(
-          ({ user_answer_record_info, share_record: { exercise_id, answer_mode, answer_time_limit_minute } }) => {
+          ({
+            user_answer_record_info,
+            share_record: { exercise_id, answer_mode, answer_time_limit_minute, correct_answer_show_mode },
+          }) => {
             this.user_answer_record_info = user_answer_record_info;
             this.exercise_id = exercise_id;
             this.getExerciseQuestionIndexList();
             this.answer_time_limit_minute = answer_time_limit_minute;
             this.time = answer_time_limit_minute * 60;
+            this.correct_answer_show_mode = correct_answer_show_mode;
             this.loading = false;
             // 如果已经存在答题记录,则直接显示答题报告
             if (this.user_answer_record_info.is_exist_answer_record === 'true') {
@@ -291,7 +294,6 @@ export default {
         .then(({ answer_record, question_list }) => {
           if (answer_record.is_remarked === 'true') {
             this.isSubmit = true;
-            this.curQuestionIndex = 0;
           }
           this.recordReport = {
             answer_record,
@@ -398,11 +400,7 @@ export default {
           if (type === 'pre') return this.preQuestion();
           if (type === 'next') return this.nextQuestion();
         }
-        // 显示答案
-        this.$refs.exercise[0].showAnswer(
-          this.answer_mode === 1 || this.isTeacherAnnotations,
-          this.user_answer_record_info.correct_answer_show_mode === 1 || this.isTeacherAnnotations,
-        );
+        this.$refs.exercise[0].showAnswer(this.answer_mode === 1, this.correct_answer_show_mode === 1, null, true);
       });
     },
     getQuestionInfo() {
@@ -440,10 +438,45 @@ export default {
         // 如果已经填写过答案,直接显示答案
         if (is_fill_answer === 'true') {
           this.$nextTick().then(() => {
+            /**
+             * 是否判断对错
+             * 1. 答题模式为练习模式
+             * 2. 教师批改
+             * 3. 答题模式为考试模式,且已经批改过
+             * 4. 从答题报告跳转到题目
+             */
+            let isJudgingRightWrong =
+              this.answer_mode === 1 ||
+              this.isTeacherAnnotations ||
+              (this.isExamMode && this.recordReport.answer_record.is_remarked === 'true') ||
+              this.isView;
+            /**
+             * 是否显示正确答案
+             * 1. 答题模式为练习模式,且正确答案显示模式为答题后显示
+             * 2. 教师批改
+             * 3. 从答题报告跳转到题目
+             */
+            let isShowRightAnswer =
+              (this.answer_mode === 1 && this.correct_answer_show_mode === 1) ||
+              this.isTeacherAnnotations ||
+              this.isView;
+            /**
+             * 是否禁用答题
+             * 1. 教师批改
+             * 2. 答题模式为练习模式,且正确答案显示模式为答题后显示
+             * 3. 教师已经批改过
+             * 4. 从测试报告跳转到题目
+             */
+            let disabled =
+              this.isTeacherAnnotations ||
+              (this.answer_mode === 1 && this.correct_answer_show_mode === 1) ||
+              this.recordReport.answer_record.is_remarked === 'true' ||
+              this.isView;
             this.$refs.exercise?.[0].showAnswer(
-              this.answer_mode === 1 || this.isTeacherAnnotations,
-              this.user_answer_record_info.correct_answer_show_mode === 1 || this.isTeacherAnnotations,
+              isJudgingRightWrong,
+              isShowRightAnswer,
               content.length > 0 ? JSON.parse(content) : null,
+              disabled,
             );
           });
         }

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

@@ -66,6 +66,7 @@ import AnswerQuestion from './exercises/AnswerQuestion.vue';
 import WritePictureQuestion from './exercises/WritePictureQuestion.vue';
 import ReplaceAnswerQuestion from './exercises/ReplaceAnswerQuestion.vue';
 import EssayQuestion from './exercises/EssayQuestion.vue';
+import FillFormQuestion from './exercises/FillFormQuestion.vue';
 
 export default {
   name: 'CreateMain',
@@ -115,6 +116,7 @@ export default {
         write_picture: WritePictureQuestion,
         replace_answer: ReplaceAnswerQuestion,
         essay_question: EssayQuestion,
+        fill_form: FillFormQuestion,
       },
     };
   },

+ 84 - 0
src/views/exercise_questions/create/components/exercises/FillFormQuestion.vue

@@ -0,0 +1,84 @@
+<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="输入题干" />
+      </div>
+
+      <div class="content"></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 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 { getFillFormData } from '@/views/exercise_questions/data/fillForm';
+
+export default {
+  name: 'FillFormQuestion',
+  mixins: [QuestionMixin],
+  data() {
+    return {
+      data: getFillFormData(),
+    };
+  },
+  methods: {},
+};
+</script>
+
+<style lang="scss" scoped></style>

+ 29 - 0
src/views/exercise_questions/data/fillForm.js

@@ -0,0 +1,29 @@
+import { optionTypeList, stemTypeList, questionNumberTypeList, scoreTypeList, switchOption } from './common';
+
+/**
+ * 获取填表题数据模板(防止 mark 重复)
+ * @returns {object} 判断题数据模板
+ */
+export function getFillFormData() {
+  return {
+    type: 'fill_form', // 题型
+    stem: '', // 题干
+    option_number_show_mode: optionTypeList[0].value, // 选项类型
+    option_list: [], // 选项列表
+    answer: { answer_list: [], score: 1, score_type: scoreTypeList[0].value }, // 答案
+    // 题型属性
+    property: {
+      stem_type: stemTypeList[0].value, // 题干类型
+      question_number: '1', // 题号
+      score: 1, // 分值
+      score_type: scoreTypeList[0].value, // 分值类型
+      order_number_column: switchOption[0].value, // 序号列
+      row_number: 1, // 行数
+      column_number: 2, // 列数
+    },
+    // 其他属性
+    other: {
+      question_number_type: questionNumberTypeList[0].value, // 题号类型
+    },
+  };
+}

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

@@ -19,6 +19,7 @@ import { wordCardData } from './wordCard';
 import { writeData } from './write';
 import { writePictrueData } from './writePicture';
 import { readData } from './read';
+import { getFillFormData } from './fillForm';
 
 // 题型源数据
 export const questionTypeDataOption = [
@@ -34,6 +35,7 @@ export const questionTypeDataOption = [
       { label: '连线题', value: 'matching', data: getMatchingDataTemplate() },
       { label: '选择声调', value: 'choose_tone', data: ChooseToneData },
       { label: '问答题', value: 'essay_question', data: essayQuestionData },
+      // { label: '填表题', value: 'fill_form', data: getFillFormData() },
     ],
   },
   {

+ 2 - 2
src/views/exercise_questions/preview/JudgePreview.vue

@@ -24,7 +24,7 @@
           <div
             v-for="option_type in data.property.option_type_list"
             :key="option_type"
-            :style="{ cursor: isJudgingRightWrong || isShowRightAnswer ? 'not-allowed' : 'pointer' }"
+            :style="{ cursor: disabled ? 'not-allowed' : 'pointer' }"
             :class="[
               'option-type-item',
               {
@@ -65,7 +65,7 @@ export default {
     },
 
     selectAnswer(mark, option_type) {
-      if (this.isJudgingRightWrong || this.isShowRightAnswer) return;
+      if (this.disabled) return;
       const index = this.answer.answer_list.findIndex((li) => li.mark === mark);
       if (index === -1) {
         this.answer.answer_list.push({ mark, option_type });

+ 2 - 2
src/views/exercise_questions/preview/ListenJudgePreview.vue

@@ -24,7 +24,7 @@
           <div
             v-for="option_type in data.property.option_type_list"
             :key="option_type"
-            :style="{ cursor: isJudgingRightWrong || isShowRightAnswer ? 'not-allowed' : 'pointer' }"
+            :style="{ cursor: disabled ? 'not-allowed' : 'pointer' }"
             :class="[
               'option-type-item',
               {
@@ -65,7 +65,7 @@ export default {
     },
 
     selectAnswer(mark, option_type) {
-      if (this.isJudgingRightWrong || this.isShowRightAnswer) return;
+      if (this.disabled) return;
       const index = this.answer.answer_list.findIndex((li) => li.mark === mark);
       if (index === -1) {
         this.answer.answer_list.push({ mark, option_type });

+ 2 - 2
src/views/exercise_questions/preview/ListenSelectPreview.vue

@@ -14,7 +14,7 @@
       <li
         v-for="({ content, mark }, i) in data.option_list"
         :key="mark"
-        :style="{ cursor: isJudgingRightWrong || isShowRightAnswer ? 'not-allowed' : 'pointer' }"
+        :style="{ cursor: disabled ? 'not-allowed' : 'pointer' }"
         :class="['option-item', { active: isAnswer(mark) }, ...computedAnswerClass(mark)]"
         @click="selectAnswer(mark)"
       >
@@ -44,7 +44,7 @@ export default {
       return this.answer.answer_list.includes(mark);
     },
     selectAnswer(mark) {
-      if (this.isJudgingRightWrong || this.isShowRightAnswer) return;
+      if (this.disabled) return;
       const index = this.answer.answer_list.indexOf(mark);
       if (this.data.property.select_type === selectTypeList[0].value) {
         this.answer.answer_list = [mark];

+ 6 - 5
src/views/exercise_questions/preview/ReadPreview.vue

@@ -113,24 +113,25 @@ export default {
      * @param {Boolean} isJudgingRightWrong 是否判断对错
      * @param {Boolean} isShowRightAnswer 是否显示正确答案
      * @param {Object} userAnswer 用户答案
+     * @param {Boolean} disabled 是否禁用
      */
-    showAnswer(isJudgingRightWrong, isShowRightAnswer, userAnswer) {
+    showAnswer(isJudgingRightWrong, isShowRightAnswer, userAnswer, disabled) {
       this.isJudgingRightWrong = isJudgingRightWrong;
       this.isShowRightAnswer = isShowRightAnswer;
       if (userAnswer) this.answer = userAnswer;
       if (this.question_list.length === this.answer.question_list.length) {
-        return this.fillAnswer(isJudgingRightWrong, isShowRightAnswer);
+        return this.fillAnswer(isJudgingRightWrong, isShowRightAnswer, disabled);
       }
       this.$watch('question_list', (val) => {
         if (val.length !== this.answer.question_list.length) return;
-        this.fillAnswer(isJudgingRightWrong, isShowRightAnswer);
+        this.fillAnswer(isJudgingRightWrong, isShowRightAnswer, disabled);
       });
     },
-    fillAnswer(isJudgingRightWrong, isShowRightAnswer) {
+    fillAnswer(isJudgingRightWrong, isShowRightAnswer, disabled) {
       this.answer.question_list.forEach(({ id, answer_list }) => {
         const index = this.question_list.findIndex((item) => item.id === id);
         if (index !== -1) {
-          this.$refs.preview[index].showAnswer(isJudgingRightWrong, isShowRightAnswer, { answer_list });
+          this.$refs.preview[index].showAnswer(isJudgingRightWrong, isShowRightAnswer, { answer_list }, disabled);
         }
       });
     },

+ 2 - 2
src/views/exercise_questions/preview/SelectPreview.vue

@@ -14,7 +14,7 @@
       <li
         v-for="({ content, mark }, i) in data.option_list"
         :key="mark"
-        :style="{ cursor: isJudgingRightWrong || isShowRightAnswer ? 'not-allowed' : 'pointer' }"
+        :style="{ cursor: disabled ? 'not-allowed' : 'pointer' }"
         :class="['option-item', { active: isAnswer(mark) }, ...computedAnswerClass(mark)]"
         @click="selectAnswer(mark)"
       >
@@ -44,7 +44,7 @@ export default {
       return this.answer.answer_list.includes(mark);
     },
     selectAnswer(mark) {
-      if (this.isJudgingRightWrong || this.isShowRightAnswer) return;
+      if (this.disabled) return;
       const index = this.answer.answer_list.indexOf(mark);
       if (this.data.property.select_type === selectTypeList[0].value) {
         this.answer.answer_list = [mark];

+ 4 - 6
src/views/exercise_questions/preview/components/PreviewMixin.js

@@ -20,6 +20,7 @@ const PreviewMixin = {
       answer: { answer_list: [] }, // 答案
       isJudgingRightWrong: false, // 是否判断对错
       isShowRightAnswer: false, // 是否显示正确答案
+      disabled: false, // 是否禁用
     };
   },
   watch: {
@@ -31,11 +32,6 @@ const PreviewMixin = {
       immediate: true,
     },
   },
-  computed: {
-    disabled() {
-      return this.isJudgingRightWrong || this.isShowRightAnswer;
-    },
-  },
   methods: {
     /**
      * 获取答案
@@ -49,10 +45,12 @@ const PreviewMixin = {
      * @param {Boolean} isJudgingRightWrong 是否判断对错
      * @param {Boolean} isShowRightAnswer 是否显示正确答案
      * @param {Object} userAnswer 用户答案
+     * @param {Boolean} disabled 是否禁用
      */
-    showAnswer(isJudgingRightWrong, isShowRightAnswer, userAnswer) {
+    showAnswer(isJudgingRightWrong, isShowRightAnswer, userAnswer, disabled) {
       this.isJudgingRightWrong = isJudgingRightWrong;
       this.isShowRightAnswer = isShowRightAnswer;
+      this.disabled = disabled;
       if (userAnswer) this.answer = userAnswer;
     },
     /**

+ 18 - 14
src/views/home/personal_question/components/ShareDialog.vue

@@ -37,12 +37,14 @@
               {{ name }}
             </el-radio>
           </el-radio-group>
-          <span>正确答案</span>
-          <el-radio-group v-model="correct_answer_show_mode">
-            <el-radio v-for="{ type, name } in correctAnswerShowModeList" :key="type" :label="type">
-              {{ name }}
-            </el-radio>
-          </el-radio-group>
+          <template v-if="answer_mode === answerModes[0].type">
+            <span>正确答案</span>
+            <el-radio-group v-model="correct_answer_show_mode">
+              <el-radio v-for="{ type, name } in correctAnswerShowModeList" :key="type" :label="type">
+                {{ name }}
+              </el-radio>
+            </el-radio-group>
+          </template>
         </template>
         <template v-if="send_type === sendModes[1].type">
           <span>访问权限</span>
@@ -95,12 +97,14 @@
         <span slot="suffix">人</span>
       </el-input>
       <span class="tips">可直接输入人数</span>
-      <span class="disabled">正确答案</span>
-      <el-radio-group v-model="correct_answer_show_mode" :disabled="true" class="disabled">
-        <el-radio v-for="{ type, name } in correctAnswerShowModeList" :key="type" :label="type">
-          {{ name }}
-        </el-radio>
-      </el-radio-group>
+      <template v-if="answer_mode === answerModes[0].type && access_popedom === accessPermissions[1].type">
+        <span>正确答案</span>
+        <el-radio-group v-model="correct_answer_show_mode">
+          <el-radio v-for="{ type, name } in correctAnswerShowModeList" :key="type" :label="type">
+            {{ name }}
+          </el-radio>
+        </el-radio-group>
+      </template>
     </div>
 
     <div slot="footer" class="footer">
@@ -161,7 +165,7 @@ export default {
       correct_answer_show_mode: 1,
       correctAnswerShowModeList: [
         { type: 1, name: '答题后显示' },
-        { type: 2, name: '手动推送' },
+        { type: 2, name: '提交后显示' },
       ],
       max_person_count: '', // 访问人数
       begin_date: this.getNowDate(),
@@ -369,7 +373,7 @@ export default {
 
     .generate-condition {
       display: grid;
-      grid-template: 30px 32px 30px / repeat(auto-fill, 210px);
+      grid-template: 30px 32px 30px / 210px 260px;
       grid-auto-flow: column;
       column-gap: 32px;
       align-items: center;