Procházet zdrojové kódy

1.进入练习题编辑器默认展示个人题库 2.对话题 插入学生改为插入当前选中的角色 3.填空题修改识别

dusenyao před 1 rokem
rodič
revize
7447eba741

+ 5 - 1
src/components/common/RichText.vue

@@ -133,7 +133,7 @@ export default {
           });
 
           editor.on('click', () => {
-            if (editor.queryCommandState('ToggleToolbarDrawer')) {
+            if (editor?.queryCommandState('ToggleToolbarDrawer')) {
               editor.execCommand('ToggleToolbarDrawer');
             }
           });
@@ -366,6 +366,10 @@ export default {
     handleRichTextBlur() {
       this.$emit('handleRichTextBlur');
       let content = tinymce.get(this.id).getContent();
+      // 判断富文本中是否有 字母+数字+空格 的组合,如果没有,直接返回
+      if (!content.match(/[a-zA-Z]+\d(\s| )*/)) {
+        return;
+      }
       // 用标签分割富文本,保留标签
       let reg = /(<[^>]+>)/g;
       let text = content

+ 1 - 1
src/router/modules/basic.js

@@ -30,7 +30,7 @@ export const EnterSys = {
 export const HomePage = {
   path: '/',
   component: DEFAULT,
-  redirect: '/home',
+  redirect: '/personal_question',
   meta: { title: '练习管理', icon: 'practice' },
   children: [
     // 公共题库

+ 13 - 15
src/views/exercise_questions/create/components/exercises/DialogueQuestion.vue

@@ -14,25 +14,18 @@
       <div class="content-wrapper">
         <div class="content">
           <div
-            v-for="({ role, type, text }, i) in data.option_list"
+            v-for="({ role, file_id, type, text }, i) in data.option_list"
             :key="i"
             class="option-list"
-            :style="{ flexDirection: type === 'input_student' ? 'row-reverse' : 'row' }"
+            :style="{ flexDirection: type === 'input' ? 'row-reverse' : 'row' }"
           >
             <span
               class="avatar"
               :style="{
-                backgroundColor:
-                  type === 'input_student' && role.length === 0
-                    ? '#306EFF'
-                    : data.property.role_list.find((item) => item.mark === role).color,
+                backgroundColor: data.property.role_list.find((item) => item.mark === role).color,
               }"
             >
-              {{
-                type === 'input_student' && role.length === 0
-                  ? '学生'
-                  : data.property.role_list.find((item) => item.mark === role).name
-              }}
+              {{ data.property.role_list.find((item) => item.mark === role).name }}
             </span>
 
             <div v-if="type === 'text'" class="text">{{ text }}</div>
@@ -50,11 +43,11 @@
               />
             </div>
 
-            <div v-else-if="type === 'input_student'">
+            <div v-else-if="type === 'input'">
               <SoundRecordPreview type="small" :disabled="true" />
             </div>
 
-            <div class="content-operation" :style="{ flexDirection: type === 'input_student' ? 'row-reverse' : 'row' }">
+            <div class="content-operation" :style="{ flexDirection: type === 'input' ? 'row-reverse' : 'row' }">
               <div class="up-down">
                 <span :style="{ borderBottomColor: i === 0 ? '#c2c2c4' : '#000' }" @click="moveOption('up', i)"></span>
                 <span
@@ -337,6 +330,7 @@ export default {
       this.data.option_list.push({
         role: this.curRole,
         text: this.textInput.replace(/\n/, ''),
+        file_id: '',
         mark: getRandomNumber(),
         type: 'text',
       });
@@ -363,11 +357,15 @@ export default {
     },
     // 插入学生
     insertStudent() {
+      if (this.curRole.length <= 0) {
+        return this.$message.error('请先选择角色');
+      }
+
       this.data.option_list.push({
         mark: getRandomNumber(),
-        role: '',
+        role: this.curRole,
         file_id: '',
-        type: 'input_student',
+        type: 'input',
       });
     },
     /**

+ 37 - 25
src/views/exercise_questions/create/components/exercises/FillQuestion.vue

@@ -31,27 +31,31 @@
         />
 
         <el-button @click="identifyText">识别</el-button>
-        <div v-if="data.answer.answer_list.length > 0" class="subtitle">正确答案</div>
-        <div v-if="data.answer.answer_list.length > 0" class="correct-answer">
+        <template v-if="data.answer.answer_list.length > 0 && isEnable(data.property.is_enable_word_select_fill)">
+          <div class="subtitle">正确答案</div>
+          <div class="correct-answer">
+            <el-input
+              v-for="(item, i) in data.answer.answer_list.filter(({ type }) => type === 'any_one')"
+              :key="item.mark"
+              v-model="item.value"
+              @blur="handleTone(item.value, i)"
+            >
+              <span slot="prefix">{{ i + 1 }}.</span>
+            </el-input>
+          </div>
+        </template>
+
+        <template v-if="!isEnable(data.property.is_enable_word_select_fill)">
+          <div class="reference-title">参考答案:</div>
           <el-input
-            v-for="(item, i) in data.answer.answer_list.filter(({ type }) => type === 'any_one')"
-            :key="item.mark"
-            v-model="item.value"
-            @blur="handleTone(item.value, i)"
-          >
-            <span slot="prefix">{{ i + 1 }}.</span>
-          </el-input>
-        </div>
-
-        <el-input
-          v-if="!isEnable(data.property.is_enable_word_select_fill)"
-          v-model="data.reference_answer"
-          type="textarea"
-          class="reference-answer"
-          resize="none"
-          :autosize="{ minRows: 3 }"
-          placeholder="输入参考答案"
-        />
+            v-model="data.reference_answer"
+            type="textarea"
+            class="reference-answer"
+            resize="none"
+            :autosize="{ minRows: 3 }"
+            placeholder="输入参考答案"
+          />
+        </template>
       </div>
     </template>
 
@@ -179,11 +183,13 @@ export default {
           let content = arr[arr.length - 1].content;
           // 设置答案数组
           let isUnderline = /^_{3,}$/.test(content);
-          this.data.answer.answer_list.push({
-            value: isUnderline ? '' : content,
-            mark,
-            type: isUnderline ? 'any_one' : 'only_one',
-          });
+          if (this.isEnable(this.data.property.is_enable_word_select_fill)) {
+            this.data.answer.answer_list.push({
+              value: isUnderline ? '' : content,
+              mark,
+              type: isUnderline ? 'any_one' : 'only_one',
+            });
+          }
           // 将 content 设置为空,为预览准备
           arr[arr.length - 1].content = '';
         }
@@ -243,6 +249,12 @@ export default {
     }
   }
 
+  .reference-title {
+    margin-top: 8px;
+    font-size: 14px;
+    color: #000;
+  }
+
   .reference-answer {
     margin-top: 8px;
   }

+ 43 - 31
src/views/exercise_questions/create/components/exercises/ListenFillQuestion.vue

@@ -46,27 +46,31 @@
           <span class="button" @click="deleteFill">删除填空</span>
         </div>
         <el-button @click="identifyText">识别</el-button>
-        <div v-if="data.answer.answer_list.length > 0" class="correct-answer">
+        <template v-if="data.answer.answer_list.length > 0 && isEnable(data.property.is_enable_word_select_fill)">
           <div class="subtitle">正确答案</div>
-          <el-input
-            v-for="(item, i) in data.answer.answer_list.filter(({ type }) => type === 'any_one')"
-            :key="item.mark"
-            v-model="item.value"
-            @blur="handleTone(item.value, i)"
-          >
-            <span slot="prefix">{{ i + 1 }}.</span>
-          </el-input>
-        </div>
+          <div class="correct-answer">
+            <el-input
+              v-for="(item, i) in data.answer.answer_list.filter(({ type }) => type === 'any_one')"
+              :key="item.mark"
+              v-model="item.value"
+              @blur="handleTone(item.value, i)"
+            >
+              <span slot="prefix">{{ i + 1 }}.</span>
+            </el-input>
+          </div>
+        </template>
 
-        <el-input
-          v-if="!isEnable(data.property.is_enable_word_select_fill)"
-          v-model="data.reference_answer"
-          type="textarea"
-          class="reference-answer"
-          resize="none"
-          :autosize="{ minRows: 3 }"
-          placeholder="输入参考答案"
-        />
+        <template v-if="!isEnable(data.property.is_enable_word_select_fill)">
+          <div class="reference-title">参考答案:</div>
+          <el-input
+            v-model="data.reference_answer"
+            type="textarea"
+            class="reference-answer"
+            resize="none"
+            :autosize="{ minRows: 3 }"
+            placeholder="输入参考答案"
+          />
+        </template>
       </div>
     </template>
 
@@ -221,12 +225,14 @@ export default {
           arr[arr.length - 1].mark = mark;
           let content = arr[arr.length - 1].content;
           // 设置答案数组
-          let isUnderline = /^_{3,}$/.test(content);
-          this.data.answer.answer_list.push({
-            value: isUnderline ? '' : content,
-            mark,
-            type: isUnderline ? 'any_one' : 'only_one',
-          });
+          if (this.isEnable(this.data.property.is_enable_word_select_fill)) {
+            let isUnderline = /^_{3,}$/.test(content);
+            this.data.answer.answer_list.push({
+              value: isUnderline ? '' : content,
+              mark,
+              type: isUnderline ? 'any_one' : 'only_one',
+            });
+          }
           // 将 content 设置为空,为预览准备
           arr[arr.length - 1].content = '';
         }
@@ -284,13 +290,13 @@ export default {
     margin-top: 8px;
   }
 
-  .correct-answer {
-    .subtitle {
-      margin: 8px 0;
-      font-size: 14px;
-      color: #4e5969;
-    }
+  .subtitle {
+    margin: 8px 0;
+    font-size: 14px;
+    color: #4e5969;
+  }
 
+  .correct-answer {
     .el-input {
       width: 180px;
 
@@ -329,6 +335,12 @@ export default {
     }
   }
 
+  .reference-title {
+    margin-top: 8px;
+    font-size: 14px;
+    color: #000;
+  }
+
   .reference-answer {
     margin-top: 8px;
   }

+ 3 - 5
src/views/exercise_questions/data/dialogue.js

@@ -28,7 +28,7 @@ export function analysisRecognitionDialogueData(arr) {
   arr.forEach((item) => {
     if (item.match(/^-\S+/)) {
       let role = item.split(/^-/)[1];
-      if (!roleList.includes(role) && role !== '学生') {
+      if (!roleList.includes(role)) {
         roleList.push(role);
       }
     }
@@ -60,13 +60,11 @@ export function analysisRecognitionDialogueData(arr) {
     }
 
     if (item.match(/^-\S+/)) {
-      let isStudent = /^-学生$/.test(item); // 是否是学生
-
       option_list.push({
         mark: getRandomNumber(),
-        role: isStudent ? '' : role_list.find(({ name }) => name === item.split(/^-/)[1]).mark,
+        role: role_list.find(({ name }) => name === item.split(/^-/)[1]).mark,
         file_id: '',
-        type: 'input_student',
+        type: 'input',
       });
     }
   });

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

@@ -18,22 +18,15 @@
         v-for="(item, i) in optionList"
         :key="i"
         class="option-list"
-        :style="{ flexDirection: item.type === 'input_student' ? 'row-reverse' : 'row' }"
+        :style="{ flexDirection: item.type === 'input' ? 'row-reverse' : 'row' }"
       >
         <span
           class="avatar"
           :style="{
-            backgroundColor:
-              item.type === 'input_student' && item.role.length === 0
-                ? '#306EFF'
-                : data.property.role_list?.find(({ mark }) => mark === item.role).color,
+            backgroundColor: data.property.role_list?.find(({ mark }) => mark === item.role).color,
           }"
         >
-          {{
-            item.type === 'input_student' && item.role.length === 0
-              ? '学生'
-              : data.property.role_list?.find(({ mark }) => mark === item.role).name
-          }}
+          {{ data.property.role_list?.find(({ mark }) => mark === item.role).name }}
         </span>
 
         <div v-if="item.type === 'text'" class="text-wrapper">
@@ -53,7 +46,7 @@
           />
         </div>
 
-        <div v-else-if="item.type === 'input_student'">
+        <div v-else-if="item.type === 'input'">
           <SoundRecordPreview :wav-blob.sync="item.file_id" :disabled="disabled" type="small" />
         </div>
       </div>
@@ -111,7 +104,7 @@ export default {
       handler(val) {
         this.answer.answer_list = [];
         val.forEach(({ type, mark, file_id }) => {
-          if (type === 'input_student') {
+          if (type === 'input') {
             if (file_id.length <= 0) return;
             this.answer.answer_list.push({
               audio_file_id: file_id,

+ 2 - 0
src/views/exercise_questions/preview/FillPreview.vue

@@ -197,6 +197,7 @@ export default {
       if (!this.isJudgingRightWrong && !this.isShowRightAnswer) {
         return '';
       }
+      if (!this.data.property.is_enable_word_select_fill) return '';
       if (!this.isEnable(this.data.property.is_enable_word_select_fill)) return '';
       let selectOption = this.answer.answer_list.find((item) => item.mark === mark);
       let answerOption = this.data.answer.answer_list.find((item) => item.mark === mark);
@@ -224,6 +225,7 @@ export default {
      */
     computedAnswerText(mark) {
       if (!this.isShowRightAnswer) return '';
+      if (!this.data.property.is_enable_word_select_fill) return '';
       if (!this.isEnable(this.data.property.is_enable_word_select_fill)) return '';
       let selectOption = this.answer.answer_list.find((item) => item.mark === mark);
       let answerOption = this.data.answer.answer_list.find((item) => item.mark === mark);

+ 1 - 1
src/views/login/index.vue

@@ -88,7 +88,7 @@ export default {
         this.$store
           .dispatch('user/login', _form)
           .then(() => {
-            this.$router.push({ path: '/personal_question' });
+            this.$router.push({ path: '/' });
           })
           .catch(() => {
             this.updateVerificationCode();