natasha пре 1 месец
родитељ
комит
9ca17f8912

+ 73 - 2
src/views/book/courseware/create/components/base/pinyin_base/PinyinBase.vue

@@ -47,6 +47,17 @@
             <SoundRecord v-else :wav-blob.sync="data.audio_file_id" />
           </div>
         </template>
+        <el-button @click="identifyText" v-if="data.property.fun_type === 'input'">识别</el-button>
+        <div class="correct-answer" v-if="data.property.fun_type === 'input'">
+          <el-input
+            v-for="(item, i) in data.answer.answer_list"
+            :key="item.mark"
+            v-model="item.con"
+            @blur="handleTone(item.con, i)"
+          >
+            <span slot="prefix">{{ i + 1 }}.</span>
+          </el-input>
+        </div>
       </div>
     </template>
   </ModuleBase>
@@ -173,7 +184,10 @@ export default {
       this.res_arr = [];
       this.$set(this.matically_pinyin_obj, item.mark, []);
       this.$set(this.matically_pinyin_str, item.mark, '');
-      this.data.answer.answer_list = [];
+      if (this.data.property.fun_type !== 'input') {
+        this.data.answer.answer_list = [];
+      }
+
       content_arr.forEach((items, index) => {
         let items_trim = items.trim();
         if (items_trim) {
@@ -212,8 +226,10 @@ export default {
         mark: item.mark,
         value: select_item.split(' '),
       };
-      this.data.answer.answer_list.push(obj);
+
       item.content_view = content_preview.trim().split(' ');
+      if (this.data.property.fun_type === 'input') return;
+      this.data.answer.answer_list.push(obj);
       // item.matically_pinyin = matically_pinyin.trim().split(' ').join(',');
     },
     // 改变类型
@@ -226,6 +242,45 @@ export default {
         item.audio_file_id = '';
       }
     },
+    // 识别文本
+    identifyText() {
+      this.data.content_view = [];
+      this.data.answer.answer_list = [];
+      let arr = this.matically_pinyin_str[this.data.mark].split(/_{3,}/g);
+      let inputIndex = 0;
+      arr.forEach((item, index) => {
+        let obj = {
+          con: item,
+          type: 'text',
+        };
+        this.data.content_view.push(obj);
+        if (index !== arr.length - 1) {
+          let objs = {
+            con: '',
+            type: 'input',
+            inputIndex: inputIndex,
+            mark: getRandomNumber(),
+          };
+          this.data.content_view.push(objs);
+          this.data.answer.answer_list.push(JSON.parse(JSON.stringify(objs)));
+          inputIndex++;
+        }
+      });
+    },
+    handleTone(value, i) {
+      if (!/^[a-zA-Z0-9\s]+$/.test(value)) return;
+      this.data.answer.answer_list[i].con = value
+        .trim()
+        .split(/\s+/)
+        .map((item) => {
+          return handleToneValue(item);
+        })
+        .map((item) =>
+          item.map(({ number, con }) => (number && con ? addTone(Number(number), con) : number || con || '')),
+        )
+        .filter((item) => item.length > 0)
+        .join(' ');
+    },
   },
 };
 </script>
@@ -311,4 +366,20 @@ export default {
   display: flex;
   column-gap: 8px;
 }
+
+.correct-answer {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 8px;
+
+  .el-input {
+    width: 180px;
+
+    :deep &__prefix {
+      display: flex;
+      align-items: center;
+      color: $text-color;
+    }
+  }
+}
 </style>

+ 4 - 4
src/views/book/courseware/data/pinyinBase.js

@@ -41,10 +41,10 @@ export const funList = [
     value: 'show',
     label: '拼音展示',
   },
-  // {
-  //   value: 'input',
-  //   label: '输入',
-  // },
+  {
+    value: 'input',
+    label: '拼音输入',
+  },
 ];
 
 // 标声调类型

+ 104 - 28
src/views/book/courseware/preview/components/pinyin_base/PinyinBasePreview.vue

@@ -18,7 +18,30 @@
             :class="[isJudgingRightWrong ? (con_preview[0].all_right ? 'all-right' : 'has-error') : '']"
           >
             <span v-if="data.content_hz" class="items-hz">{{ data.content_hz }}</span>
-            <template v-if="data.property.answer_mode === 'select'">
+            <!-- 拼音输入 -->
+            <template v-if="data.property.fun_type === 'input'">
+              <span
+                v-for="(itemc, indexc) in con_preview"
+                :key="indexc"
+                :class="[
+                  'item-con',
+                  isJudgingRightWrong && itemc.type === 'input' && item.answer && item.con !== item.answer
+                    ? 'error'
+                    : '',
+                ]"
+              >
+                <el-input
+                  v-model="itemc.con"
+                  :disabled="disabled"
+                  :style="[{ width: Math.max(20, itemc.con.length * 10) + 'px' }]"
+                  class="item-input"
+                  v-if="itemc.type === 'input'"
+                  @blur="onInputChange(itemc)"
+                />
+                <span v-else>{{ itemc.con }}</span>
+              </span>
+            </template>
+            <template v-else-if="data.property.answer_mode === 'select'">
               <span
                 v-for="(itemc, indexc) in con_preview[0].item_con"
                 :key="indexc"
@@ -103,7 +126,7 @@
             <SvgIcon :icon-class="img" />
           </span>
         </div>
-        <template v-else-if="data.property.fun_type === 'show' && isEnable(data.property.is_enable_voice_answer)">
+        <template v-else-if="data.property.fun_type !== 'mark' && isEnable(data.property.is_enable_voice_answer)">
           <SoundRecord
             ref="record"
             type="normal"
@@ -124,6 +147,7 @@ import { getPinyinBaseData, arrangeTypeList, audioPositionList } from '@/views/b
 import PreviewMixin from '../common/PreviewMixin';
 import AudioPlay from '../character_base/components/AudioPlay.vue';
 import SoundRecord from '../../common/SoundRecord.vue';
+import { addTone, handleToneValue } from '@/utils/common';
 
 export default {
   name: 'PinyinBasePreview',
@@ -187,7 +211,7 @@ export default {
     };
   },
   created() {
-    // console.log(this.data);
+    console.log(this.data);
   },
   methods: {
     chooseTone(item, value) {
@@ -250,35 +274,58 @@ export default {
       if (!this.isJudgingRightWrong) {
         this.answer.answer_list = [];
       }
-      // this.data.option_list.forEach((item) => {
-      let con_arr = JSON.parse(JSON.stringify(this.data.content_view));
-      let user_answer = [];
-      let user_submit = []; // 用户提交答案
-      con_arr.forEach((items) => {
-        user_answer.push({
-          select_tone: null,
-          select_letter: '',
-          select_index: '',
+      if (this.data.property.fun_type === 'input') {
+        let arr = this.data.content.split(/_{3,}/g);
+        let inputIndex = 0;
+        arr.forEach((item, index) => {
+          let obj = {
+            con: item,
+            type: 'text',
+          };
+          if (index !== arr.length - 1) {
+            let objs = {
+              con: '',
+              type: 'input',
+              inputIndex: inputIndex,
+              answer: this.data.answer.answer_list[inputIndex] ? this.data.answer.answer_list[inputIndex].con : '',
+            };
+            this.con_preview.push(obj);
+            this.con_preview.push(JSON.parse(JSON.stringify(objs)));
+            inputIndex++;
+          }
+        });
+      } else {
+        // this.data.option_list.forEach((item) => {
+        let con_arr = JSON.parse(JSON.stringify(this.data.content_view));
+        let user_answer = [];
+        let user_submit = []; // 用户提交答案
+        con_arr.forEach((items) => {
+          user_answer.push({
+            select_tone: null,
+            select_letter: '',
+            select_index: '',
+          });
+          user_submit.push(this.data.property.answer_mode === 'label' ? items : '');
         });
-        user_submit.push(this.data.property.answer_mode === 'label' ? items : '');
-      });
-      let obj = {
-        item_con: con_arr,
-        item_con_yuan: JSON.parse(JSON.stringify(con_arr)),
-        mark: this.data.mark,
-        user_answer,
-        item_active_index: 0,
-        active_letter: '',
-      };
-      if (!this.isJudgingRightWrong) {
         let obj = {
+          item_con: con_arr,
+          item_con_yuan: JSON.parse(JSON.stringify(con_arr)),
           mark: this.data.mark,
-          value: user_submit,
+          user_answer,
+          item_active_index: 0,
+          active_letter: '',
         };
-        this.answer.answer_list.push(obj);
+        if (!this.isJudgingRightWrong) {
+          let obj = {
+            mark: this.data.mark,
+            value: user_submit,
+          };
+          this.answer.answer_list.push(obj);
+        }
+        this.con_preview.push(obj);
+        // });
       }
-      this.con_preview.push(obj);
-      // });
+      console.log(this.con_preview);
       this.show_preview = true;
     },
     handleReplaceTone(e, arr, index, resArr) {
@@ -406,7 +453,6 @@ export default {
       return cons;
     },
     handleSelectItemTone(i, indexc, indexi, itemi) {
-      console.log(this.data.property.fun_type);
       if (this.data.property.fun_type === 'show') {
         return;
       }
@@ -482,6 +528,22 @@ export default {
     handleWav(data) {
       this.data.record_list = data;
     },
+    onInputChange(item) {
+      let answer = item.con;
+
+      answer = answer
+        .trim()
+        .split(/\s+/)
+        .map((item) => {
+          return handleToneValue(item);
+        })
+        .map((item) =>
+          item.map(({ number, con }) => (number && con ? addTone(Number(number), con) : number || con || '')),
+        )
+        .filter((item) => item.length > 0)
+        .join(' ');
+      item.con = answer;
+    },
   },
 };
 </script>
@@ -595,5 +657,19 @@ export default {
     background: #f2f3f5;
     border-radius: 2px;
   }
+
+  .item-input {
+    :deep .el-input__inner {
+      padding: 0;
+      font-family: 'League';
+      font-size: 16px;
+      color: #1d2129;
+      text-align: center;
+      background-color: transparent;
+      border-width: 0;
+      border-bottom: 1px solid #1d2129;
+      border-radius: 0;
+    }
+  }
 }
 </style>