dusenyao 1 год назад
Родитель
Сommit
b8667c5bac
31 измененных файлов с 456 добавлено и 428 удалено
  1. 37 1
      src/views/exercise_questions/create/components/common/IntelligentRecognition.vue
  2. 5 1
      src/views/exercise_questions/create/components/common/QuestionHeader.vue
  3. 45 2
      src/views/exercise_questions/create/components/common/QuestionMixin.js
  4. 3 1
      src/views/exercise_questions/create/components/create.vue
  5. 1 27
      src/views/exercise_questions/create/components/exercises/AnswerQuestion.vue
  6. 16 36
      src/views/exercise_questions/create/components/exercises/ChineseQuestion.vue
  7. 5 25
      src/views/exercise_questions/create/components/exercises/ChooseToneQuestion.vue
  8. 68 13
      src/views/exercise_questions/create/components/exercises/DialogueQuestion.vue
  9. 1 27
      src/views/exercise_questions/create/components/exercises/EssayQuestion.vue
  10. 13 0
      src/views/exercise_questions/create/components/exercises/FillQuestion.vue
  11. 19 10
      src/views/exercise_questions/create/components/exercises/JudgeQuestion.vue
  12. 13 0
      src/views/exercise_questions/create/components/exercises/ListenFillQuestion.vue
  13. 3 10
      src/views/exercise_questions/create/components/exercises/ListenJudgeQuestion.vue
  14. 3 9
      src/views/exercise_questions/create/components/exercises/ListenSelectQuestion.vue
  15. 32 2
      src/views/exercise_questions/create/components/exercises/MatchingQuestion.vue
  16. 35 5
      src/views/exercise_questions/create/components/exercises/ReadAloudQuestion.vue
  17. 16 2
      src/views/exercise_questions/create/components/exercises/ReadQuestion.vue
  18. 3 23
      src/views/exercise_questions/create/components/exercises/RepeatQuestion.vue
  19. 16 36
      src/views/exercise_questions/create/components/exercises/ReplaceAnswerQuestion.vue
  20. 3 21
      src/views/exercise_questions/create/components/exercises/SelectQuestion.vue
  21. 9 30
      src/views/exercise_questions/create/components/exercises/SortQuestion.vue
  22. 46 0
      src/views/exercise_questions/create/components/exercises/TableFillQuestion.vue
  23. 1 20
      src/views/exercise_questions/create/components/exercises/TalkPictureQuestion.vue
  24. 22 42
      src/views/exercise_questions/create/components/exercises/WordCardQuestion.vue
  25. 12 32
      src/views/exercise_questions/create/components/exercises/WordDictationQuestion.vue
  26. 1 20
      src/views/exercise_questions/create/components/exercises/WritePictureQuestion.vue
  27. 9 26
      src/views/exercise_questions/create/components/exercises/WriteQuestion.vue
  28. 3 2
      src/views/exercise_questions/data/dialogue.js
  29. 10 1
      src/views/exercise_questions/data/judge.js
  30. 3 1
      src/views/exercise_questions/data/readAloud.js
  31. 3 3
      src/views/exercise_questions/data/tableFill.js

+ 37 - 1
src/views/exercise_questions/create/components/common/IntelligentRecognition.vue

@@ -1,6 +1,6 @@
 <template>
   <el-dialog :visible="visible" width="600px" @close="dialogClose">
-    <el-input v-model="text" type="textarea" rows="8" resize="none" placeholder="请输入内容" />
+    <el-input v-model="text" type="textarea" rows="8" resize="none" :placeholder="placeholder" />
 
     <template slot="footer">
       <el-button @click="dialogClose">取消</el-button>
@@ -17,12 +17,48 @@ export default {
       type: Boolean,
       required: true,
     },
+    type: {
+      type: String,
+      default: 'select',
+    },
   },
   data() {
     return {
       text: '',
+      placeholderList: {
+        select: '题干:xxx\r\n提示:xxx\r\n选项 1\r\n选项 2\r\n选项 3',
+        listen_select: '题干:xxx\r\n提示:xxx\r\n选项 1\r\n选项 2\r\n选项 3',
+        judge: '题干:xxx\r\n提示:xxx\r\n选项 1\r\n选项 2\r\n选项 3',
+        listen_judage: '题干:xxx\r\n提示:xxx\r\n选项 1\r\n选项 2\r\n选项 3',
+        fill: '题干:\r\n提示:\r\n填空____填空填空___\r\n填空___填空___\r\n填空___填空___',
+        listen_fill: '题干:\r\n提示:\r\n填空____填空填空___\r\n填空___填空___\r\n填空___填空___',
+        sort: '题干:xxxx\r\n提示:xxxx\r\n内容 内容 内容 内容 内容\r\n内容 内容 内容',
+        matching: '题干:xxx\r\n提示:xxx\r\n内容 - 内容\r\n内容 - 内容\r\n内容 - 内容',
+        choose_tone: '题干:xxx\r\n提示:xxx\r\nHe3n ha3o\r\nNi3 ha3o',
+        essay_question: '题干:xxx\r\n提示:xxx\r\n参考答案:xxx',
+        table_fill:
+          '题干:xxx\r\n提示:xxx\r\n表头-表头-表头\r\n(表格内容)(表格内容)(表格内容)\r\n()(表格内容)()\r\n参考答案:xxx',
+        read_aloud: '题干:xxx\r\n提示:xxx\r\n文段:xxx',
+        repeat: '题干:xxx\r\n提示:xxx\r\n选项 1\r\n选项 2\r\n选项 3',
+        talk_picture: '题干:xxx\r\n提示:xxx',
+        dialogue: '题干:xxx\r\n提示:xxx\r\n小明:内容内容\r\n小红:内容内容\r\n-学生\r\n小明:内容内容',
+        answer_question: '题干:xxx\r\n提示:xxx\r\n参考答案:xxx',
+        replace_answer: '题干:xxx\r\n提示:xxx\r\n内容1 内容2 内容3 内容4\r\n内容1 内容2 内容3 内容4',
+        chinese: '题干:xxxx\r\n提示:xxx\r\n字词/pinyin/释义/搭配\r\n字词/pinyin/释义/搭配',
+        word_dictation: '题干:xxx\r\n提示:xxx\r\n字词/pinyin\r\n字词/pinyin',
+        word_card:
+          '题干:xxx\r\n提示:xxx\r\n字词/拼音/释义/搭配/例句1/例句2/例句3\r\n字词/拼音/释义/搭配/例句1/例句2/例句3',
+        write: '题干:xxx\r\n提示:xxx\r\n范文:xxx',
+        write_picture: '题干:xxx\r\n提示:xxx',
+        read: '题干:xxx\r\n提示:xxx\r\n文章:xxx',
+      },
     };
   },
+  computed: {
+    placeholder() {
+      return this.placeholderList[this.type] ?? '暂无智能识别';
+    },
+  },
   methods: {
     // 识别
     recognition() {

+ 5 - 1
src/views/exercise_questions/create/components/common/QuestionHeader.vue

@@ -13,7 +13,11 @@
     <SvgIcon v-if="isChild" class-name="pointer" icon-class="delete" :size="14" @click="$emit('deleteQuestion')" />
     <div v-else class="save-tip">{{ saveDate }} 已自动保存</div>
 
-    <IntelligentRecognition :visible.sync="dialogVisible" @recognition="handleRecognition" />
+    <IntelligentRecognition
+      :type="type[type.length - 1]"
+      :visible.sync="dialogVisible"
+      @recognition="handleRecognition"
+    />
   </div>
 </template>
 

+ 45 - 2
src/views/exercise_questions/create/components/common/QuestionMixin.js

@@ -81,7 +81,6 @@ const mixin = {
   },
   methods: {
     saveChildQuestion() {
-      console.log(this.data.type);
       SaveQuestion({
         question_id: this.questionId,
         type: this.data.type,
@@ -114,11 +113,55 @@ const mixin = {
     },
     /**
      * 删除选项
-     * @param {Number} i 索引
+     * @param {number} i 索引
      */
     deleteOption(i) {
       this.data.option_list.splice(i, 1);
     },
+    /**
+     * 智能识别公用方法
+     * @param {string} text 文本
+     * @param {boolean} isEnableReferenceAnswer 是否启用参考答案
+     */
+    recognitionCommon(text, isEnableReferenceAnswer = false) {
+      let arr = text
+        .split(/[\r\n]/)
+        .map((item) => item.trim())
+        .filter((item) => item);
+
+      if (arr.length === 0) return [];
+
+      let sliceLength = 0;
+      const stemReg = /^题干[::]/;
+      if (stemReg.test(arr[0])) {
+        this.data.stem = arr[0].replace(stemReg, '');
+        sliceLength += 1;
+      }
+
+      const desReg = /^提示[::]/;
+      if (desReg.test(arr[sliceLength])) {
+        this.data.description = arr[sliceLength].replace(desReg, '');
+        this.data.property.is_enable_description = 'true';
+        sliceLength += 1;
+      } else {
+        this.data.description = '';
+        this.data.property.is_enable_description = 'false';
+      }
+
+      if (isEnableReferenceAnswer) {
+        let referenceReg = /^参考答案[::]/;
+        let index = arr.findIndex((item) => referenceReg.test(item));
+        if (index === -1) {
+          this.data.reference_answer = '';
+          this.data.property.is_enable_reference_answer = 'false';
+        } else {
+          this.data.reference_answer = arr[index].replace(referenceReg, '');
+          this.data.property.is_enable_reference_answer = 'true';
+          arr.splice(index, 1);
+        }
+      }
+      return arr.slice(sliceLength);
+    },
   },
 };
 

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

@@ -27,7 +27,7 @@
       </div>
     </div>
     <div class="create-content">
-      <QuestionHeader v-if="indexList.length > 0" />
+      <QuestionHeader v-if="indexList.length > 0" :type="exerciseTypeList[indexList[curIndex].type]" />
       <template v-for="({ id }, i) in indexList">
         <component :is="curExercisePage" v-if="i === curIndex" :key="id" ref="exercise" :question-id="id" />
       </template>
@@ -38,6 +38,7 @@
 <script>
 import { SaveQuestion } from '@/api/exercise';
 import { timeFormatConversion } from '@/utils/transform';
+import { exerciseTypeList } from '@/views/exercise_questions/data/questionType';
 
 import QuestionHeader from './common/QuestionHeader.vue';
 import SelectQuestion from './exercises/SelectQuestion.vue';
@@ -91,6 +92,7 @@ export default {
   },
   data() {
     return {
+      exerciseTypeList,
       timer: null,
       curSaveDate: '',
       exerciseComponents: {

+ 1 - 27
src/views/exercise_questions/create/components/exercises/AnswerQuestion.vue

@@ -104,33 +104,7 @@ export default {
      * @param {String} text 识别数据
      */
     recognition(text) {
-      let arr = text
-        .split(/[\r\n]/)
-        .map((item) => item.trim())
-        .filter((item) => item);
-
-      if (arr.length > 0) {
-        let sliceLength = 0;
-        if (arr[0].substring(0, 3) === '题干:') {
-          this.data.stem = arr[0].substring(3);
-          sliceLength += 1;
-        }
-        if (arr.slice(sliceLength)[0] && arr.slice(sliceLength)[0].substring(0, 3) === '提示:') {
-          this.data.description = arr.slice(sliceLength)[0].substring(3);
-          this.data.property.is_enable_description = 'true';
-          sliceLength += 1;
-        } else {
-          this.data.description = '';
-          this.data.property.is_enable_description = 'false';
-        }
-        if (arr.slice(sliceLength)[0] && arr.slice(sliceLength)[0].substring(0, 5) === '参考答案:') {
-          this.data.reference_answer = arr.slice(sliceLength)[0].substring(5);
-          this.data.property.is_enable_reference_answer = 'true';
-        } else {
-          this.data.reference_answer = '';
-          this.data.property.is_enable_reference_answer = 'false';
-        }
-      }
+      this.recognitionCommon(text, true);
     },
   },
 };

+ 16 - 36
src/views/exercise_questions/create/components/exercises/ChineseQuestion.vue

@@ -355,43 +355,23 @@ export default {
      * @param {String} text 识别数据
      */
     recognition(text) {
-      let arr = text
-        .split(/[\r\n]/)
-        .map((item) => item.trim())
-        .filter((item) => item);
-
-      if (arr.length > 0) {
-        let sliceLength = 0;
-        if (arr[0].substring(0, 3) === '题干:') {
-          this.data.stem = arr[0].substring(3);
-          sliceLength += 1;
-        }
-        if (arr.slice(sliceLength)[0] && arr.slice(sliceLength)[0].substring(0, 3) === '提示:') {
-          this.data.description = arr.slice(sliceLength)[0].substring(3);
-          this.data.property.is_enable_description = 'true';
-          sliceLength += 1;
-        } else {
-          this.data.description = '';
-          this.data.property.is_enable_description = 'false';
-        }
-        let option_list = arr.slice(sliceLength);
-        this.data.option_list = [];
-        option_list.map((content, index) => {
-          let content_item = content.split('/');
-          this.data.option_list.push({
-            content: content_item[0] ? content_item[0] : '',
-            mark: getRandomNumber(),
-            audio_file_id: '',
-            pinyin: content_item[1] ? content_item[1] : '',
-            pinyin_item_list: [],
-            definition: content_item[2] ? content_item[2] : '',
-            collocation: content_item[3] ? content_item[3] : '',
-            hz_strokes_list: [],
-          });
-          this.handleSplitPy(this.data.option_list[index]);
-          this.handleChineseStrokes(this.data.option_list[index], index);
+      let arr = this.recognitionCommon(text);
+      this.data.option_list = [];
+      arr.map((content, index) => {
+        let content_item = content.split('/');
+        this.data.option_list.push({
+          content: content_item[0] ? content_item[0] : '',
+          mark: getRandomNumber(),
+          audio_file_id: '',
+          pinyin: content_item[1] ? content_item[1] : '',
+          pinyin_item_list: [],
+          definition: content_item[2] ? content_item[2] : '',
+          collocation: content_item[3] ? content_item[3] : '',
+          hz_strokes_list: [],
         });
-      }
+        this.handleSplitPy(this.data.option_list[index]);
+        this.handleChineseStrokes(this.data.option_list[index], index);
+      });
     },
   },
 };

+ 5 - 25
src/views/exercise_questions/create/components/exercises/ChooseToneQuestion.vue

@@ -337,31 +337,11 @@ export default {
      * @param {String} text 识别数据
      */
     recognition(text) {
-      let arr = text
-        .split(/[\r\n]/)
-        .map((item) => item.trim())
-        .filter((item) => item);
-
-      if (arr.length > 0) {
-        let sliceLength = 0;
-        if (arr[0].substring(0, 3) === '题干:') {
-          this.data.stem = arr[0].substring(3);
-          sliceLength += 1;
-        }
-        if (arr.slice(sliceLength)[0] && arr.slice(sliceLength)[0].substring(0, 3) === '提示:') {
-          this.data.description = arr.slice(sliceLength)[0].substring(3);
-          this.data.property.is_enable_description = 'true';
-          sliceLength += 1;
-        } else {
-          this.data.description = '';
-          this.data.property.is_enable_description = 'false';
-        }
-        let option_list = arr.slice(sliceLength);
-        this.data.option_list = option_list.map((content) => getOption(content));
-        this.data.option_list.forEach((item) => {
-          this.handleItemAnswer(item);
-        });
-      }
+      let arr = this.recognitionCommon(text);
+      this.data.option_list = arr.map((content) => getOption(content));
+      this.data.option_list.forEach((item) => {
+        this.handleItemAnswer(item);
+      });
     },
   },
 };

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

@@ -263,6 +263,51 @@ export default {
     },
   },
   methods: {
+    /**
+     * 智能识别
+     * @param {String} text 识别数据
+     */
+    recognition(text) {
+      let arr = this.recognitionCommon(text);
+      // 角色列表
+      let roleList = [];
+      arr.forEach((item) => {
+        if (!item.match(/.+[::].+/)) return;
+        let [role] = item.split(/[::]/);
+        if (!roleList.includes(role)) {
+          roleList.push(role);
+        }
+      });
+      if (roleList.length < 2 || roleList.length > 5) {
+        return this.$message.warning('角色数不符合要求,最小为 2,最大为 5');
+      }
+      this.data.property.role_number = roleList.length;
+      this.data.property.role_list = roleList.map((item, i) => getRole(i, item));
+
+      this.data.option_list = [];
+      arr.forEach((item) => {
+        if (item.match(/.+[::].+/)) {
+          let [role, content] = item.split(/[::]/);
+          let { hasFill, content_list } = this.getTextContenList(content);
+          this.data.option_list.push({
+            role: this.data.property.role_list.find((item) => item.name === role).mark,
+            text: content,
+            mark: getRandomNumber(),
+            file_id: '',
+            content_list,
+            type: hasFill ? 'input' : 'text',
+          });
+        }
+        if (item.match(/^-学生$/)) {
+          this.data.option_list.push({
+            mark: getRandomNumber(),
+            file_id: '',
+            type: 'input_student',
+          });
+        }
+      });
+      this.identifyText();
+    },
     // 识别
     identifyText() {
       let answer_list = [];
@@ -332,12 +377,30 @@ export default {
         return this.$message.error('请先选择角色');
       }
       let text = this.textInput.replace(/\n/, '');
+
+      let { hasFill, content_list } = this.getTextContenList(text);
+      this.data.option_list.push({
+        role: this.curRole,
+        text: this.textInput.replace(/\n/, ''),
+        mark: getRandomNumber(),
+        file_id: '',
+        content_list,
+        type: hasFill ? 'input' : 'text',
+      });
+      this.textInput = '';
+    },
+    /**
+     * 获取文本内容列表
+     * @param {string} text 文本
+     */
+    getTextContenList(text) {
+      let str = text;
       let reg = /_{3,}/;
-      let hasFill = reg.test(text); // 是否有填空
+      let hasFill = reg.test(str); // 是否有填空
       let content_list = [];
       if (hasFill) {
-        text = text.replace(/(_{3,})/g, '###$1###');
-        content_list = text
+        str = str.replace(/(_{3,})/g, '###$1###');
+        content_list = str
           .split('###')
           .filter((item) => item)
           .map((content) => {
@@ -351,21 +414,13 @@ export default {
       } else {
         content_list = [
           {
-            content: text,
+            content: str,
             mark: '',
             type: 'text',
           },
         ];
       }
-      this.data.option_list.push({
-        role: this.curRole,
-        text: this.textInput.replace(/\n/, ''),
-        mark: getRandomNumber(),
-        file_id: '',
-        content_list,
-        type: hasFill ? 'input' : 'text',
-      });
-      this.textInput = '';
+      return { hasFill, content_list };
     },
     /**
      * 移动选项

+ 1 - 27
src/views/exercise_questions/create/components/exercises/EssayQuestion.vue

@@ -101,33 +101,7 @@ export default {
      * @param {String} text 识别数据
      */
     recognition(text) {
-      let arr = text
-        .split(/[\r\n]/)
-        .map((item) => item.trim())
-        .filter((item) => item);
-
-      if (arr.length > 0) {
-        let sliceLength = 0;
-        if (arr[0].substring(0, 3) === '题干:') {
-          this.data.stem = arr[0].substring(3);
-          sliceLength += 1;
-        }
-        if (arr.slice(sliceLength)[0] && arr.slice(sliceLength)[0].substring(0, 3) === '提示:') {
-          this.data.description = arr.slice(sliceLength)[0].substring(3);
-          this.data.property.is_enable_description = 'true';
-          sliceLength += 1;
-        } else {
-          this.data.description = '';
-          this.data.property.is_enable_description = 'false';
-        }
-        if (arr.slice(sliceLength)[0] && arr.slice(sliceLength)[0].substring(0, 5) === '参考答案:') {
-          this.data.reference_answer = arr.slice(sliceLength)[0].substring(5);
-          this.data.property.is_enable_reference_answer = 'true';
-        } else {
-          this.data.reference_answer = '';
-          this.data.property.is_enable_reference_answer = 'false';
-        }
-      }
+      this.recognitionCommon(text, true);
     },
   },
 };

+ 13 - 0
src/views/exercise_questions/create/components/exercises/FillQuestion.vue

@@ -123,6 +123,19 @@ export default {
     };
   },
   methods: {
+    /**
+     * 智能识别
+     * @param {String} text 识别数据
+     */
+    recognition(text) {
+      let arr = this.recognitionCommon(text);
+      let str = '';
+      arr.forEach((text) => {
+        str += `<p>${text}</p>`; // 拼接成富文本
+      });
+      this.data.article = str;
+      this.identifyText();
+    },
     // 识别文本
     identifyText() {
       this.data.model_essay = [];

+ 19 - 10
src/views/exercise_questions/create/components/exercises/JudgeQuestion.vue

@@ -3,6 +3,12 @@
     <template #content>
       <div class="stem">
         <RichText v-model="data.stem" :font-size="18" placeholder="输入题干" />
+
+        <RichText
+          v-if="isEnable(data.property.is_enable_description)"
+          v-model="data.description"
+          placeholder="输入提示"
+        />
       </div>
 
       <div class="content">
@@ -65,6 +71,16 @@
             {{ 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-select v-model="data.property.stem_question_number_font_size">
             <el-option v-for="item in fontSizeList" :key="item" :label="item" :value="item" />
@@ -156,16 +172,9 @@ export default {
      * @param {String} text 识别数据
      */
     recognition(text) {
-      let arr = text
-        .split(/[\r\n]/)
-        .map((item) => item.trim())
-        .filter((item) => item);
-
-      if (arr.length > 0) {
-        this.data.stem = arr[0];
-        this.data.option_list = arr.slice(1).map((content) => getOption(content));
-        this.data.answer.answer_list = [];
-      }
+      let arr = this.recognitionCommon(text);
+      this.data.option_list = arr.map((content) => getOption(content));
+      this.data.answer.answer_list = [];
     },
     /**
      * 选择选项答案

+ 13 - 0
src/views/exercise_questions/create/components/exercises/ListenFillQuestion.vue

@@ -165,6 +165,19 @@ export default {
     window.removeEventListener('click', this.hideContentmenu);
   },
   methods: {
+    /**
+     * 智能识别
+     * @param {String} text 识别数据
+     */
+    recognition(text) {
+      let arr = this.recognitionCommon(text);
+      let str = '';
+      arr.forEach((text) => {
+        str += `<p>${text}</p>`; // 拼接成富文本
+      });
+      this.data.article = str;
+      this.identifyText();
+    },
     // 识别文本
     identifyText() {
       this.data.model_essay = [];

+ 3 - 10
src/views/exercise_questions/create/components/exercises/ListenJudgeQuestion.vue

@@ -193,16 +193,9 @@ export default {
      * @param {String} text 识别数据
      */
     recognition(text) {
-      let arr = text
-        .split(/[\r\n]/)
-        .map((item) => item.trim())
-        .filter((item) => item);
-
-      if (arr.length > 0) {
-        this.data.stem = arr[0];
-        this.data.option_list = arr.slice(1).map((content) => getOption(content));
-        this.data.answer.answer_list = [];
-      }
+      let arr = this.recognitionCommon(text);
+      this.data.option_list = arr.map((content) => getOption(content));
+      this.data.answer.answer_list = [];
     },
     /**
      * 选择选项答案

+ 3 - 9
src/views/exercise_questions/create/components/exercises/ListenSelectQuestion.vue

@@ -195,15 +195,9 @@ export default {
      * @param {String} text 识别数据
      */
     recognition(text) {
-      let arr = text
-        .split(/[\r\n]/)
-        .map((item) => item.trim())
-        .filter((item) => item);
-
-      if (arr.length > 0) {
-        this.data.stem = arr[0];
-        this.data.option_list = arr.slice(1).map((content) => getOption(content));
-      }
+      let arr = this.recognitionCommon(text);
+      this.data.option_list = arr.map((content) => getOption(content));
+      this.data.answer.answer_list = [];
     },
     changeSelectType(val) {
       if (val === selectTypeList[0].value && this.data.answer.answer_list.length > 1) {

+ 32 - 2
src/views/exercise_questions/create/components/exercises/MatchingQuestion.vue

@@ -107,7 +107,6 @@
 </template>
 
 <script>
-import RichText from '@/components/common/RichText.vue';
 import QuestionMixin from '../common/QuestionMixin.js';
 
 import { changeOptionType } from '@/views/exercise_questions/data/common';
@@ -115,7 +114,6 @@ import { columnNumberList, getOption, getMatchingDataTemplate } from '@/views/ex
 
 export default {
   name: 'MatchingQuestion',
-  components: { RichText },
   mixins: [QuestionMixin],
   data() {
     return {
@@ -138,6 +136,38 @@ export default {
     },
   },
   methods: {
+    /**
+     * 智能识别
+     * @param {String} text 识别数据
+     */
+    recognition(text) {
+      let arr = this.recognitionCommon(text);
+      if (arr.length === 0) {
+        this.data.option_list = [];
+        return;
+      }
+      let column = arr[0].split(' - ').length;
+      if (column !== 2 && column !== 3) {
+        this.$message.error('列数应为2列或3列');
+        return;
+      }
+      // 判断选项格式是否一致
+      let isQualify = arr.every((item) => {
+        if (item.split(' - ').length !== column) {
+          this.$message.error('选项格式不一致');
+          return false;
+        }
+        return true;
+      });
+      if (!isQualify) return;
+
+      this.data.property.column_number = column;
+      this.data.option_list = arr.map((item) => {
+        return item.split(' - ').map((li) => {
+          return getOption(li);
+        });
+      });
+    },
     addOption() {
       let newOption = [];
       for (let i = 0; i < this.data.property.column_number; i++) {

+ 35 - 5
src/views/exercise_questions/create/components/exercises/ReadAloudQuestion.vue

@@ -4,14 +4,20 @@
       <div class="stem">
         <RichText v-model="data.stem" :font-size="18" placeholder="输入题干" />
 
+        <RichText
+          v-if="isEnable(data.property.is_enable_description)"
+          v-model="data.description"
+          placeholder="输入提示"
+        />
+
+        <RichText v-model="data.paragraph" placeholder="输入文段" />
+
         <UploadAudio
           v-show="isEnable(data.property.is_enable_listening)"
           :file-id="data.file_id_list?.[0]"
           @upload="upload"
           @deleteFile="deleteFile"
         />
-
-        <RichText v-model="data.description" placeholder="输入文段" />
       </div>
     </template>
 
@@ -37,6 +43,17 @@
           </el-select>
         </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"
@@ -71,7 +88,6 @@
 </template>
 
 <script>
-import RichText from '@/components/common/RichText.vue';
 import QuestionMixin from '../common/QuestionMixin.js';
 import UploadAudio from '../common/UploadAudio.vue';
 
@@ -81,7 +97,6 @@ export default {
   name: 'ReadAloudQuestion',
   components: {
     UploadAudio,
-    RichText,
   },
   mixins: [QuestionMixin],
   data() {
@@ -89,7 +104,22 @@ export default {
       data: JSON.parse(JSON.stringify(readAloudData)),
     };
   },
-  methods: {},
+  methods: {
+    /**
+     * 智能识别
+     * @param {String} text 识别数据
+     */
+    recognition(text) {
+      let arr = this.recognitionCommon(text);
+      if (arr.length === 0) return;
+      let reg = /^文段[::]/;
+      if (reg.test(arr[0])) {
+        this.data.paragraph = arr[0].replace(reg, '');
+      } else {
+        this.data.paragraph = '';
+      }
+    },
+  },
 };
 </script>
 

+ 16 - 2
src/views/exercise_questions/create/components/exercises/ReadQuestion.vue

@@ -22,7 +22,7 @@
           :type="exerciseTypeList[item.type]"
           @updateCurQuestionType="updateCurQuestionType(i, $event)"
           @deleteQuestion="deleteQuestion(i)"
-          @recognition="recognition(i, $event)"
+          @recognition="recognitionChildren(i, $event)"
         />
         <KeepAlive>
           <component
@@ -162,10 +162,24 @@ export default {
 
     /**
      * 智能识别
+     * @param {String} text 识别数据
+     */
+    recognition(text) {
+      let arr = this.recognitionCommon(text);
+      if (arr.length < 0) return;
+      let reg = /^文章[::]/;
+      if (reg.test(arr[0])) {
+        this.data.article = arr[0].replace(reg, '');
+      } else {
+        this.data.article = '';
+      }
+    },
+    /**
+     * 智能识别
      * @param {Number} i 题目索引
      * @param {String} text 识别数据
      */
-    recognition(i, text) {
+    recognitionChildren(i, text) {
       this.$refs.exercise[i]?.recognition(text);
     },
 

+ 3 - 23
src/views/exercise_questions/create/components/exercises/RepeatQuestion.vue

@@ -1,4 +1,4 @@
-<!-- 听训练 -->
+<!-- 听训练 -->
 <template>
   <QuestionBase>
     <template #content>
@@ -178,28 +178,8 @@ export default {
      * @param {String} text 识别数据
      */
     recognition(text) {
-      let arr = text
-        .split(/[\r\n]/)
-        .map((item) => item.trim())
-        .filter((item) => item);
-
-      if (arr.length > 0) {
-        let sliceLength = 0;
-        if (arr[0].substring(0, 3) === '题干:') {
-          this.data.stem = arr[0].substring(3);
-          sliceLength += 1;
-        }
-        if (arr.slice(sliceLength)[0] && arr.slice(sliceLength)[0].substring(0, 3) === '提示:') {
-          this.data.description = arr.slice(sliceLength)[0].substring(3);
-          this.data.property.is_enable_description = 'true';
-          sliceLength += 1;
-        } else {
-          this.data.description = '';
-          this.data.property.is_enable_description = 'false';
-        }
-        let option_list = arr.slice(sliceLength);
-        this.data.option_list = option_list.map((content) => getOption(content));
-      }
+      let arr = this.recognitionCommon(text);
+      this.data.option_list = arr.map((content) => getOption(content));
     },
     addOption() {
       this.data.option_list.push(getOption());

+ 16 - 36
src/views/exercise_questions/create/components/exercises/ReplaceAnswerQuestion.vue

@@ -119,44 +119,24 @@ export default {
      * @param {String} text 识别数据
      */
     recognition(text) {
-      let arr = text
-        .split(/[\r\n]/)
-        .map((item) => item.trim())
-        .filter((item) => item);
-
-      if (arr.length > 0) {
-        let sliceLength = 0;
-        if (arr[0].substring(0, 3) === '题干:') {
-          this.data.stem = arr[0].substring(3);
-          sliceLength += 1;
-        }
-        if (arr.slice(sliceLength)[0] && arr.slice(sliceLength)[0].substring(0, 3) === '提示:') {
-          this.data.description = arr.slice(sliceLength)[0].substring(3);
-          this.data.property.is_enable_description = 'true';
-          sliceLength += 1;
-        } else {
-          this.data.description = '';
-          this.data.property.is_enable_description = 'false';
+      let arr = this.recognitionCommon(text);
+      this.data.option_list = [];
+      this.data.property.row_count = arr.length;
+      let column_count = 0;
+      arr.forEach((item) => {
+        let item_arr = item.split(' ');
+        if (item_arr.length > column_count) {
+          column_count = item_arr.length;
         }
-        let option_list = arr.slice(sliceLength);
-        this.data.option_list = [];
-        this.data.property.row_count = option_list.length;
-        let column_count = 0;
-        option_list.forEach((item) => {
-          let item_arr = item.split(' ');
-          if (item_arr.length > column_count) {
-            column_count = item_arr.length;
-          }
-        });
-        this.data.property.column_count = column_count;
-        for (let i = 0; i < option_list.length; i++) {
-          let table_item = [];
-          let item_arr = option_list[i].split(' ');
-          for (let j = 0; j < column_count; j++) {
-            table_item.push({ content: item_arr[j] ? item_arr[j] : '', mark: getRandomNumber() });
-          }
-          this.data.option_list.push(table_item);
+      });
+      this.data.property.column_count = column_count;
+      for (let i = 0; i < arr.length; i++) {
+        let table_item = [];
+        let item_arr = arr[i].split(' ');
+        for (let j = 0; j < column_count; j++) {
+          table_item.push({ content: item_arr[j] ? item_arr[j] : '', mark: getRandomNumber() });
         }
+        this.data.option_list.push(table_item);
       }
     },
     addOption() {

+ 3 - 21
src/views/exercise_questions/create/components/exercises/SelectQuestion.vue

@@ -179,27 +179,9 @@ export default {
      * @param {String} text 识别数据
      */
     recognition(text) {
-      let arr = text
-        .split(/[\r\n]/)
-        .map((item) => item.trim())
-        .filter((item) => item);
-
-      if (arr.length <= 0) return;
-
-      let sliceLength = 0;
-      if (arr[0].substring(0, 3) === '题干:') {
-        this.data.stem = arr[0].substring(3);
-        sliceLength += 1;
-      }
-      if (arr.slice(sliceLength)[0] && arr.slice(sliceLength)[0].substring(0, 3) === '提示:') {
-        this.data.description = arr.slice(sliceLength)[0].substring(3);
-        this.data.property.is_enable_description = 'true';
-        sliceLength += 1;
-      } else {
-        this.data.description = '';
-        this.data.property.is_enable_description = 'false';
-      }
-      this.data.option_list = arr.slice(sliceLength).map((content) => getOption(content));
+      let arr = this.recognitionCommon(text);
+      this.data.option_list = arr.map((content) => getOption(content));
+      this.data.answer.answer_list = [];
     },
     changeSelectType(val) {
       if (val === selectTypeList[0].value && this.data.answer.answer_list.length > 1) {

+ 9 - 30
src/views/exercise_questions/create/components/exercises/SortQuestion.vue

@@ -181,36 +181,15 @@ export default {
      * @param {String} text 识别数据
      */
     recognition(text) {
-      let arr = text
-        .split(/[\r\n]/)
-        .map((item) => item.trim())
-        .filter((item) => item);
-
-      if (arr.length > 0) {
-        let sliceLength = 0;
-        if (arr[0].substring(0, 3) === '题干:') {
-          this.data.stem = arr[0].substring(3);
-          sliceLength += 1;
-        }
-        if (arr.slice(sliceLength)[0] && arr.slice(sliceLength)[0].substring(0, 3) === '提示:') {
-          this.data.description = arr.slice(sliceLength)[0].substring(3);
-          this.data.property.is_enable_description = 'true';
-          sliceLength += 1;
-        } else {
-          this.data.description = '';
-          this.data.property.is_enable_description = 'false';
-        }
-        let option_list = arr.slice(sliceLength);
-        this.data.option_list = option_list.map((item) => {
-          let data_list = item.split(' ').map((content) => getOption(content));
-          let item_obj = {
-            mark: getRandomNumber(),
-            data_list,
-          };
-          return item_obj;
-        });
-        // this.data.option_list = arr.slice(1).map((content) => getOption(content));
-      }
+      let arr = this.recognitionCommon(text);
+      this.data.option_list = arr.map((item) => {
+        let data_list = item.split(' ').map((content) => getOption(content));
+        let item_obj = {
+          mark: getRandomNumber(),
+          data_list,
+        };
+        return item_obj;
+      });
     },
     changeType(item) {
       if (item === 'vertical') {

+ 46 - 0
src/views/exercise_questions/create/components/exercises/TableFillQuestion.vue

@@ -227,6 +227,52 @@ export default {
   },
   methods: {
     /**
+     * 智能识别
+     * @param {String} text 识别数据
+     */
+    recognition(text) {
+      let arr = this.recognitionCommon(text, true);
+      if (arr.length === 0) return;
+      // 表头
+      let headerNum = arr[0].split('-').length;
+      if (headerNum > 1 && (headerNum < 2 || headerNum > 5)) {
+        this.$message.error('行数在2-5之间');
+        return;
+      }
+      if (headerNum > 1) {
+        this.data.property.is_enable_table_header = 'true';
+        this.data.property.column_number = headerNum;
+        this.data.option_header_list = arr[0]
+          .split('-')
+          .map((item) => ({ mark: getRandomNumber(), text: item, width: 100 / headerNum }));
+        arr.shift();
+      } else {
+        this.data.property.is_enable_table_header = 'false';
+        this.data.option_header_list = [];
+      }
+
+      // 通过正则表达式匹配出表格内容
+      let matches = arr.map((str) => {
+        return str.match(/[((](.*?)[))]/g).map((item) => item.replace(/[((](.*?)[))]/g, '$1'));
+      });
+      let isMate = matches.every((item) => {
+        if (item.length !== headerNum) {
+          this.$message.error('表格列数不匹配');
+          return false;
+        }
+        return true;
+      });
+      if (!isMate) return;
+      if (this.data.property.row_number < 1 || this.data.property.row_number > 30) {
+        this.$message.error('行数在1-30之间');
+        return;
+      }
+      this.data.property.row_number = matches.length;
+      this.data.option_list = matches.map((item) => {
+        return item.map((li) => getOption(li));
+      });
+    },
+    /**
      *鼠标拖动更改列宽
      * @param {MouseEvent} e 鼠标事件
      * @param {number} i 选项列表的索引

+ 1 - 20
src/views/exercise_questions/create/components/exercises/TalkPictureQuestion.vue

@@ -185,26 +185,7 @@ export default {
      * @param {String} text 识别数据
      */
     recognition(text) {
-      let arr = text
-        .split(/[\r\n]/)
-        .map((item) => item.trim())
-        .filter((item) => item);
-
-      if (arr.length > 0) {
-        let sliceLength = 0;
-        if (arr[0].substring(0, 3) === '题干:') {
-          this.data.stem = arr[0].substring(3);
-          sliceLength += 1;
-        }
-        if (arr.slice(sliceLength)[0] && arr.slice(sliceLength)[0].substring(0, 3) === '提示:') {
-          this.data.description = arr.slice(sliceLength)[0].substring(3);
-          this.data.property.is_enable_description = 'true';
-          sliceLength += 1;
-        } else {
-          this.data.description = '';
-          this.data.property.is_enable_description = 'false';
-        }
-      }
+      this.recognitionCommon(text);
     },
   },
 };

+ 22 - 42
src/views/exercise_questions/create/components/exercises/WordCardQuestion.vue

@@ -407,49 +407,29 @@ export default {
      * @param {String} text 识别数据
      */
     recognition(text) {
-      let arr = text
-        .split(/[\r\n]/)
-        .map((item) => item.trim())
-        .filter((item) => item);
-
-      if (arr.length > 0) {
-        let sliceLength = 0;
-        if (arr[0].substring(0, 3) === '题干:') {
-          this.data.stem = arr[0].substring(3);
-          sliceLength += 1;
-        }
-        if (arr.slice(sliceLength)[0] && arr.slice(sliceLength)[0].substring(0, 3) === '提示:') {
-          this.data.description = arr.slice(sliceLength)[0].substring(3);
-          this.data.property.is_enable_description = 'true';
-          sliceLength += 1;
-        } else {
-          this.data.description = '';
-          this.data.property.is_enable_description = 'false';
-        }
-        let option_list = arr.slice(sliceLength);
-        this.data.option_list = [];
-        option_list.map((content, index) => {
-          let content_item = content.split('/');
-          this.data.option_list.push({
-            content: content_item[0] ? content_item[0] : '',
-            mark: getRandomNumber(),
-            audio_file_id: '',
-            pinyin: content_item[1] ? content_item[1] : '',
-            definition: content_item[2] ? content_item[2] : '',
-            collocation: content_item[3] ? content_item[3] : '',
-            example_sentence: content_item.length > 3 ? content_item.slice(4) : [''],
-            picture_file_id: '',
-            hz_strokes_list: [],
-          });
-          let obj = {
-            loading: false,
-            loadings: false,
-          };
-          this.loading_list.push(obj);
-          this.handleChineseStrokes(this.data.option_list[index], index);
-          this.changePinyin(this.data.option_list[index]);
+      let arr = this.recognitionCommon(text);
+      this.data.option_list = [];
+      arr.map((content, index) => {
+        let content_item = content.split('/');
+        this.data.option_list.push({
+          content: content_item[0] ? content_item[0] : '',
+          mark: getRandomNumber(),
+          audio_file_id: '',
+          pinyin: content_item[1] ? content_item[1] : '',
+          definition: content_item[2] ? content_item[2] : '',
+          collocation: content_item[3] ? content_item[3] : '',
+          example_sentence: content_item.length > 3 ? content_item.slice(4) : [''],
+          picture_file_id: '',
+          hz_strokes_list: [],
         });
-      }
+        let obj = {
+          loading: false,
+          loadings: false,
+        };
+        this.loading_list.push(obj);
+        this.handleChineseStrokes(this.data.option_list[index], index);
+        this.changePinyin(this.data.option_list[index]);
+      });
     },
   },
 };

+ 12 - 32
src/views/exercise_questions/create/components/exercises/WordDictationQuestion.vue

@@ -293,39 +293,19 @@ export default {
      * @param {String} text 识别数据
      */
     recognition(text) {
-      let arr = text
-        .split(/[\r\n]/)
-        .map((item) => item.trim())
-        .filter((item) => item);
-
-      if (arr.length > 0) {
-        let sliceLength = 0;
-        if (arr[0].substring(0, 3) === '题干:') {
-          this.data.stem = arr[0].substring(3);
-          sliceLength += 1;
-        }
-        if (arr.slice(sliceLength)[0] && arr.slice(sliceLength)[0].substring(0, 3) === '提示:') {
-          this.data.description = arr.slice(sliceLength)[0].substring(3);
-          this.data.property.is_enable_description = 'true';
-          sliceLength += 1;
-        } else {
-          this.data.description = '';
-          this.data.property.is_enable_description = 'false';
-        }
-        let option_list = arr.slice(sliceLength);
-        this.data.option_list = [];
-        option_list.map((content, index) => {
-          let content_item = content.split('/');
-          this.data.option_list.push({
-            content: content_item[0] ? content_item[0] : '',
-            mark: getRandomNumber(),
-            audio_file_id: '',
-            pinyin: content_item[1] ? content_item[1] : '',
-            pinyin_item_list: [],
-          });
-          this.handleSplitPy(this.data.option_list[index]);
+      let arr = this.recognitionCommon(text);
+      this.data.option_list = [];
+      arr.map((content, index) => {
+        let content_item = content.split('/');
+        this.data.option_list.push({
+          content: content_item[0] ? content_item[0] : '',
+          mark: getRandomNumber(),
+          audio_file_id: '',
+          pinyin: content_item[1] ? content_item[1] : '',
+          pinyin_item_list: [],
         });
-      }
+        this.handleSplitPy(this.data.option_list[index]);
+      });
     },
   },
 };

+ 1 - 20
src/views/exercise_questions/create/components/exercises/WritePictureQuestion.vue

@@ -189,26 +189,7 @@ export default {
      * @param {String} text 识别数据
      */
     recognition(text) {
-      let arr = text
-        .split(/[\r\n]/)
-        .map((item) => item.trim())
-        .filter((item) => item);
-
-      if (arr.length > 0) {
-        let sliceLength = 0;
-        if (arr[0].substring(0, 3) === '题干:') {
-          this.data.stem = arr[0].substring(3);
-          sliceLength += 1;
-        }
-        if (arr.slice(sliceLength)[0] && arr.slice(sliceLength)[0].substring(0, 3) === '提示:') {
-          this.data.description = arr.slice(sliceLength)[0].substring(3);
-          this.data.property.is_enable_description = 'true';
-          sliceLength += 1;
-        } else {
-          this.data.description = '';
-          this.data.property.is_enable_description = 'false';
-        }
-      }
+      this.recognitionCommon(text);
     },
   },
 };

+ 9 - 26
src/views/exercise_questions/create/components/exercises/WriteQuestion.vue

@@ -114,32 +114,15 @@ export default {
      * @param {String} text 识别数据
      */
     recognition(text) {
-      let arr = text
-        .split(/[\r\n]/)
-        .map((item) => item.trim())
-        .filter((item) => item);
-
-      if (arr.length > 0) {
-        let sliceLength = 0;
-        if (arr[0].substring(0, 3) === '题干:') {
-          this.data.stem = arr[0].substring(3);
-          sliceLength += 1;
-        }
-        if (arr.slice(sliceLength)[0] && arr.slice(sliceLength)[0].substring(0, 3) === '提示:') {
-          this.data.description = arr.slice(sliceLength)[0].substring(3);
-          this.data.property.is_enable_description = 'true';
-          sliceLength += 1;
-        } else {
-          this.data.description = '';
-          this.data.property.is_enable_description = 'false';
-        }
-        if (arr.slice(sliceLength)[0] && arr.slice(sliceLength)[0].substring(0, 3) === '范文:') {
-          this.data.sample_text = arr.slice(sliceLength)[0].substring(3);
-          this.data.property.is_enable_sample_text = 'true';
-        } else {
-          this.data.sample_text = '';
-          this.data.property.is_enable_sample_text = 'false';
-        }
+      let arr = this.recognitionCommon(text);
+      if (arr.length < 0) return;
+      let reg = /^范文[::]/;
+      if (reg.test(arr[0])) {
+        this.data.sample_text = arr[0].replace(reg, '');
+        this.data.property.is_enable_sample_text = 'true';
+      } else {
+        this.data.sample_text = '';
+        this.data.property.is_enable_sample_text = 'false';
       }
     },
   },

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

@@ -6,10 +6,11 @@ export const roleDefaultColorList = ['#306EFF', '#3ABD38', '#FC8E3D', '#FC493D',
 /**
  * 获取角色对象
  * @param {number} index 序号
+ * @param {string} name 名称
  */
-export function getRole(index) {
+export function getRole(index, name = '') {
   return {
-    name: `角色${index + 1}`,
+    name: name || `角色${index + 1}`,
     mark: getRandomNumber(),
     color: roleDefaultColorList[index],
   };

+ 10 - 1
src/views/exercise_questions/data/judge.js

@@ -1,4 +1,11 @@
-import { optionTypeList, stemTypeList, questionNumberTypeList, scoreTypeList, fontSizeList } from './common';
+import {
+  optionTypeList,
+  stemTypeList,
+  questionNumberTypeList,
+  scoreTypeList,
+  fontSizeList,
+  switchOption,
+} from './common';
 import { getRandomNumber } from '@/utils/index';
 
 // 选项类型列表
@@ -22,6 +29,7 @@ export function getJudgeData() {
   return {
     type: 'judge', // 题型
     stem: '', // 题干
+    description: '', // 提示
     option_number_show_mode: optionTypeList[0].value, // 选项类型
     option_list: [getOption(), getOption(), getOption()], // 选项
     file_id_list: [], // 文件 id 列表
@@ -30,6 +38,7 @@ export function getJudgeData() {
     property: {
       stem_type: stemTypeList[1].value, // 题干类型
       question_number: '1', // 题号
+      is_enable_description: switchOption[1].value,
       stem_question_number_font_size: fontSizeList[6], // 题干题号
       option_question_number_font_size: fontSizeList[5], // 选项题号
       option_type_list: [option_type_list[0].value, option_type_list[1].value], // 选项类型列表

+ 3 - 1
src/views/exercise_questions/data/readAloud.js

@@ -4,7 +4,8 @@ import { stemTypeList, questionNumberTypeList, scoreTypeList, switchOption, font
 export const readAloudData = {
   type: 'read_aloud', // 题型
   stem: '', // 题干
-  description: '', // 描述
+  description: '', // 提示
+  paragraph: '', // 文段
   file_id_list: [], // 文件 id 列表
   answer: {
     score: 1,
@@ -16,6 +17,7 @@ export const readAloudData = {
     question_number: '1', // 题号
     stem_question_number_font_size: fontSizeList[6], // 题干题号
     is_enable_listening: switchOption[0].value, // 是否开启听力
+    is_enable_description: switchOption[1].value, // 是否开启提示
     score: 1, // 分值
     score_type: scoreTypeList[0].value, // 分值类型
   },

+ 3 - 3
src/views/exercise_questions/data/tableFill.js

@@ -1,11 +1,11 @@
 import { getRandomNumber } from '@/utils';
 import { stemTypeList, questionNumberTypeList, scoreTypeList, switchOption, fontSizeList } from './common';
 
-export function getOption() {
+export function getOption(text = '') {
   return {
     mark: getRandomNumber(),
-    text: '',
-    type: 'input',
+    text,
+    type: text.length > 0 ? 'text' : 'input',
   };
 }