Browse Source

Merge branch 'master' of http://gcls-git.helxsoft.cn/GCLS/eep_page

zq 1 week ago
parent
commit
6e41ee34e1

+ 124 - 23
src/views/book/courseware/create/components/question/newWord_template/NewWordTemplate.vue

@@ -10,6 +10,14 @@
           >{{ label }}</a
         >
       </div>
+      <div class="answer-type" v-if="data.property.model === 'input'">
+        <span>答题方式:</span>
+        <el-checkbox-group v-model="data.answer_type">
+          <el-checkbox label="pinyin">填拼音</el-checkbox>
+          <el-checkbox label="en">填释义</el-checkbox>
+          <!-- <el-checkbox label="con">写汉字</el-checkbox> -->
+        </el-checkbox-group>
+      </div>
       <div class="content-box" v-for="(item, index) in data.option_list" :key="index">
         <div class="content-item">
           <el-input
@@ -21,6 +29,51 @@
           ></el-input>
           <el-button @click="identify(item)">识别</el-button>
         </div>
+        <div class="option-item">
+          <template v-if="isEnable(data.property.is_enable_pinyin) || data.answer_type.indexOf('pinyin') > -1">
+            <span>共用拼音:</span>
+            <el-radio-group v-model="item.is_common_pinyin">
+              <el-radio :label="true">是</el-radio>
+              <el-radio :label="false">否</el-radio>
+            </el-radio-group>
+            <template
+              v-if="
+                isEnable(data.property.is_enable_pinyin) && data.property.model === 'input' && item.is_common_pinyin
+              "
+            >
+              <span>拼音</span>
+              <el-input v-model="item.pinyin" placeholder="输入拼音"></el-input>
+            </template>
+            <template
+              v-if="data.answer_type.indexOf('pinyin') > -1 && data.property.model === 'input' && item.is_common_pinyin"
+            >
+              <span>拼音答案</span>
+              <el-input v-model="item.answer_pinyin" placeholder="输入拼音"></el-input>
+            </template>
+
+            <template v-if="isEnable(data.property.is_enable_shiyi) && data.property.model === 'input'">
+              <span>释义</span>
+              <el-input v-model="item.shiyi" placeholder="输入释义"></el-input>
+            </template>
+            <template v-if="data.answer_type.indexOf('en') > -1 && data.property.model === 'input'">
+              <span>释义答案</span>
+              <el-input v-model="item.answer_en" placeholder="输入释义"></el-input>
+            </template>
+            <template
+              v-if="
+                data.property.model === 'input' &&
+                (data.answer_type.indexOf('en') > -1 ||
+                  (data.answer_type.indexOf('pinyin') > -1 && item.is_common_pinyin))
+              "
+            >
+              <span>例子</span>
+              <el-radio-group v-model="item.is_example">
+                <el-radio :label="true">是</el-radio>
+                <el-radio :label="false">否</el-radio>
+              </el-radio-group>
+            </template>
+          </template>
+        </div>
         <div class="content-items" v-for="(items, indexs) in item.content_list" :key="indexs">
           <template v-if="items">
             <label>内容:{{ items.con }} </label>
@@ -37,14 +90,19 @@
               @updateFileList="updateFileList"
             />
             <div class="option-item">
-              <template v-if="isEnable(data.property.is_enable_pinyin)">
+              <template
+                v-if="
+                  isEnable(data.property.is_enable_pinyin) &&
+                  (data.property.model === 'miao' || (data.property.model === 'input' && !item.is_common_pinyin))
+                "
+              >
                 <span>拼音</span>
-                <el-input v-model="items.pinyin"></el-input>
+                <el-input v-model="items.pinyin" placeholder="输入拼音"></el-input>
               </template>
-              <template v-if="isEnable(data.property.is_enable_shiyi) && data.property.model === 'input'">
+              <!-- <template v-if="isEnable(data.property.is_enable_shiyi) && data.property.model === 'input'">
                 <span>释义</span>
-                <el-input v-model="items.shiyi"></el-input>
-              </template>
+                <el-input v-model="items.shiyi" placeholder="输入释义"></el-input>
+              </template> -->
               <template v-if="data.property.model === 'miao' && items.type === 'hanzi'">
                 <span>可输入</span>
                 <el-radio-group v-model="items.is_can_input_answer">
@@ -62,6 +120,29 @@
                   <el-radio :label="false">否</el-radio>
                 </el-radio-group>
               </template>
+              <template
+                v-if="
+                  data.answer_type.indexOf('pinyin') > -1 && data.property.model === 'input' && !item.is_common_pinyin
+                "
+              >
+                <span>拼音答案</span>
+                <el-input v-model="items.answer_pinyin" placeholder="输入拼音"></el-input>
+              </template>
+              <template
+                v-if="
+                  data.property.model === 'input' && data.answer_type.indexOf('pinyin') > -1 && !item.is_common_pinyin
+                "
+              >
+                <span>例子</span>
+                <el-radio-group v-model="items.is_example">
+                  <el-radio :label="true">是</el-radio>
+                  <el-radio :label="false">否</el-radio>
+                </el-radio-group>
+              </template>
+              <template v-if="isEnable(data.property.is_enable_high_strokes) && data.property.model === 'input'">
+                <span>高亮笔画</span>
+                <el-input v-model="items.high_strokes" placeholder="多笔用、隔开"></el-input>
+              </template>
             </div>
           </template>
         </div>
@@ -162,6 +243,8 @@ export default {
                   answer_en: '',
                   is_example: false,
                   is_can_input_answer: true,
+                  is_can_input_pinyin: true,
+                  high_strokes: '',
                 };
               } else if (item === '#') {
                 // 书写
@@ -177,6 +260,7 @@ export default {
                   answer_pinyin: '',
                   answer_en: '',
                   is_can_input_answer: true,
+                  high_strokes: '',
                 };
               } else if (regex.test(item)) {
                 // 汉字
@@ -200,6 +284,7 @@ export default {
                   answer_pinyin: '',
                   answer_en: '',
                   is_can_input_answer: true,
+                  high_strokes: '',
                 };
               } else {
                 // 连字符
@@ -213,6 +298,7 @@ export default {
                   answer_en: '',
                   is_example: false,
                   is_can_input_answer: true,
+                  high_strokes: '',
                 };
               }
               this.$set(items.content_list, index, objs);
@@ -301,28 +387,43 @@ export default {
     line-height: 34px;
     color: #4e5969;
   }
+}
 
-  .option-item {
-    display: flex;
-    align-items: center;
-    margin-top: 5px;
+.option-item {
+  display: flex;
+  flex-flow: wrap;
+  align-items: center;
+  margin-top: 5px;
 
-    span {
-      flex-shrink: 0;
-      width: max-content;
-      margin-right: 10px;
-      font-size: 14px;
-      color: #4e5969;
-    }
+  span {
+    flex-shrink: 0;
+    width: max-content;
+    margin-right: 10px;
+    font-size: 14px;
+    color: #4e5969;
+  }
 
-    .el-input {
-      max-width: 100px;
-      margin-right: 30px;
-    }
+  .el-input {
+    max-width: 100px;
+    margin-right: 30px;
+  }
 
-    .el-radio-group {
-      margin-right: 30px;
-    }
+  .el-radio-group {
+    margin-right: 30px;
+  }
+}
+
+.answer-type {
+  display: flex;
+  gap: 10px;
+  margin: 10px 0;
+
+  span {
+    flex-shrink: 0;
+    width: max-content;
+    margin-right: 10px;
+    font-size: 14px;
+    color: #4e5969;
   }
 }
 </style>

+ 4 - 1
src/views/book/courseware/data/newWordTemplate.js

@@ -66,9 +66,12 @@ export function getOption() {
   return {
     content: '',
     pinyin: '',
+    shiyi:'',
     mark: getRandomNumber(),
     is_example: false,
     answer: '',
+    answer_pinyin: '', // 共用拼音时答案
+    answer_en:'', // 释义答案
     hz_info: [],
     file_list: [],
     file_id_list: [],
@@ -103,7 +106,7 @@ export function getNewWordTemplateData() {
     title: '生字',
     property: getNewWordTemplateProperty(),
     option_list: [getOption()],
-    answer_type:'',
+    answer_type: [],
     mind_map: {
       node_list: [{ name: '生字' }], // 思维导图数据
     },

+ 250 - 29
src/views/book/courseware/preview/components/newWord_template/NewWordTemplatePreview.vue

@@ -4,32 +4,126 @@
     <SerialNumberPosition v-if="isEnable(data.property.sn_display_mode)" :property="data.property" />
 
     <div class="main">
-      <div class="item-box" v-for="(item, index) in data.option_list" :key="index">
-        <div class="number-box">
+      <div
+        class="item-box"
+        :class="['item-box-' + data.property.model]"
+        v-for="(item, index) in data.option_list"
+        :key="index"
+      >
+        <div
+          class="number-box"
+          :style="{
+            marginTop: isEnable(data.property.is_enable_pinyin)
+              ? '30px'
+              : data.answer_type.indexOf('pinyin') > -1 && data.property.model === 'input'
+                ? '52px'
+                : '',
+          }"
+        >
           <span class="number">{{ index + 1 }}</span>
         </div>
-        <div class="items" v-for="(items, indexs) in item.content_list" :key="indexs">
-          <template v-if="items && items.type === 'img'">
-            <el-image
-              class="items-image"
-              v-if="items.file_list[0]"
-              :src="items.file_list[0].file_url"
-              fit="contain"
-            ></el-image>
-          </template>
-          <template v-else-if="items && items.type === 'lian'">
-            <span class="items-lian">{{ items.con }}</span>
-          </template>
-          <Strockplayredline
-            v-else-if="items && items.type === 'hanzi'"
-            :Book_text="items.con"
-            :playStorkes="isEnable(data.property.is_enable_play_structure)"
-            :curItem="isEnable(data.property.is_enable_high_strokes) ? items : null"
-            :type="data.type"
-            :targetDiv="'newWordTemplate' + index + indexs"
-            :hz_json="items.hz_info[0].hzDetail.hz_json"
-            class="hanzi-storck"
-          />
+        <div class="pinyin-en" :class="[item.is_example ? 'item-example' : '']">
+          <div
+            v-if="isEnable(data.property.is_enable_pinyin) && data.property.model === 'input' && item.is_common_pinyin"
+            class="pinyin"
+          >
+            {{ item.pinyin }}
+          </div>
+          <div
+            class="inputdv pinyin-common"
+            v-if="data.answer_type.indexOf('pinyin') > -1 && data.property.model === 'input' && item.is_common_pinyin"
+          >
+            <EditDiv
+              :id="'b' + item.content + index"
+              :canEdit="!item.is_example"
+              v-model="userAnswer[index].answer_pinyin"
+              :textAlign="'center'"
+              @input="changeAnswer(item, index)"
+            />
+          </div>
+          <div class="items-flex">
+            <div
+              class="items"
+              :class="[items.is_example ? 'items-example' : '']"
+              v-for="(items, indexs) in item.content_list"
+              :key="indexs"
+            >
+              {{ items.high_strokes }}
+              <div v-if="isEnable(data.property.is_enable_pinyin)" class="pinyin">{{ items.pinyin }}</div>
+              <div
+                class="inputdv pinyin-common"
+                v-if="
+                  data.answer_type.indexOf('pinyin') > -1 && data.property.model === 'input' && !item.is_common_pinyin
+                "
+              >
+                <EditDiv
+                  :id="'c' + items.con + index + indexs"
+                  :canEdit="!items.is_example"
+                  v-model="userAnswer[index].item[indexs].answer_pinyin"
+                  :textAlign="'center'"
+                  @input="changeAnswer(item, index, indexs)"
+                />
+              </div>
+              <div class="items-content">
+                <template v-if="items && items.type === 'img'">
+                  <el-image
+                    class="items-image"
+                    v-if="items.file_list[0]"
+                    :src="items.file_list[0].file_url"
+                    fit="contain"
+                  ></el-image>
+                </template>
+                <template v-else-if="items && items.type === 'lian'">
+                  <span class="items-lian">{{ items.con }}</span>
+                </template>
+                <Strockplayredline
+                  v-if="items && items.type === 'hanzi'"
+                  :Book_text="items.con"
+                  :playStorkes="isEnable(data.property.is_enable_play_structure)"
+                  :curItem="
+                    isEnable(data.property.is_enable_high_strokes)
+                      ? data.property.model === 'input'
+                        ? items.high_strokes
+                        : userAnswer[index].item[indexs]
+                      : null
+                  "
+                  :type="data.property.model === 'input' ? 'newWord-template-input' : data.type"
+                  :targetDiv="'newWordTemplate' + items.con + index + indexs"
+                  :hz_json="items.hz_info[0].hzDetail.hz_json"
+                  class="hanzi-storck"
+                  :class="[
+                    item.content_list.length > 1 && indexs == 0 ? 'leftBorderRadius' : '',
+
+                    item.content_list.length > 1 && indexs == item.content_list.length - 1 ? 'rightBorderRadius' : '',
+                    item.content_list.length > 1 && indexs != item.content_list.length - 1 && indexs != 0
+                      ? 'NoborderRadius'
+                      : '',
+                    item.content_list.length > 1 && indexs != item.content_list.length - 1 ? 'NoborderRight' : '',
+                  ]"
+                />
+              </div>
+              <div class="inputdv" v-if="data.property.model === 'miao'">
+                <EditDiv
+                  v-if="items && items.type === 'hanzi' && items.is_can_input_answer"
+                  :id="'a' + items.con + index + indexs"
+                  :canEdit="!items.is_example"
+                  v-model="userAnswer[index].item[indexs].answer"
+                  :textAlign="'center'"
+                  @input="changeAnswer(items, index, indexs)"
+                />
+              </div>
+            </div>
+          </div>
+          <div class="inputdv en-common" v-if="data.answer_type.indexOf('en') > -1 && data.property.model === 'input'">
+            <EditDiv
+              :id="'d' + item.content + index"
+              :canEdit="!item.is_example"
+              v-model="userAnswer[index].answer_en"
+              :textAlign="'center'"
+              @input="changeAnswer(item, index)"
+            />
+          </div>
+          <div class="en-common" v-if="data.property.model === 'input'">{{ item.shiyi }}</div>
         </div>
       </div>
     </div>
@@ -41,27 +135,75 @@ import { getNewWordTemplateData } from '@/views/book/courseware/data/newWordTemp
 
 import PreviewMixin from '../common/PreviewMixin';
 import Strockplayredline from './components/Strockplayredline.vue';
+import EditDiv from './components/EditDiv.vue';
 export default {
   name: 'NewWordPreview',
 
-  components: { Strockplayredline },
+  components: { Strockplayredline, EditDiv },
   mixins: [PreviewMixin],
   data() {
     return {
       data: getNewWordTemplateData(),
+      userAnswer: [],
     };
   },
   watch: {
-    data: {
+    'data.option_list': {
       handler(val) {
         if (val) {
+          this.handleData();
         }
       },
       deep: true,
       immediate: true,
     },
   },
-  methods: {},
+  methods: {
+    // 修改数字高亮对应笔画(待优化)
+    changeAnswer(items, col, row) {
+      // items.isShow = false;
+      setTimeout(() => {
+        // items.isShow = true;
+        // if (items.answer) {
+        //   if (items.answer == this.curQue.Bookanswer[col][row].answer) {
+        //     this.curQue.Bookanswer[col][row].userAnswerJudge =
+        //       "[JUDGE##T##JUDGE]";
+        //   } else if (items.answer != this.curQue.Bookanswer[col][row].answer) {
+        //     this.curQue.Bookanswer[col][row].userAnswerJudge =
+        //       "[JUDGE##F##JUDGE]";
+        //   }
+        // }
+        this.$forceUpdate();
+      }, 10);
+    },
+    handleData() {
+      let answer_list = [];
+      this.data.option_list.forEach((item) => {
+        let arr = [];
+        item.content_list.forEach((items) => {
+          if (items.is_example) {
+            arr.push({
+              answer: items.answer,
+              answer_pinyin: items.answer_pinyin,
+              answer_en: items.answer_en,
+            });
+          } else {
+            arr.push({
+              answer: '',
+              answer_pinyin: '',
+              answer_en: '',
+            });
+          }
+        });
+        answer_list.push({
+          answer_pinyin: item.is_example ? item.answer_pinyin : '',
+          answer_en: item.is_example ? item.answer_en : '',
+          item: arr,
+        });
+      });
+      this.userAnswer = answer_list;
+    },
+  },
 };
 </script>
 
@@ -69,9 +211,15 @@ export default {
 @use '@/styles/mixin.scss' as *;
 
 .newWord-template-preview {
+  .main {
+    display: flex;
+    flex-flow: wrap;
+    gap: 30px;
+  }
+
   .item-box {
     display: flex;
-    align-items: end;
+    gap: 5px;
   }
 
   .number-box {
@@ -99,6 +247,16 @@ export default {
     font-size: 0;
   }
 
+  .pinyin {
+    height: 30px;
+    min-height: 16px;
+    font-family: 'League';
+    font-size: 20px;
+    font-weight: 400;
+    color: rgba(0, 0, 0, 50%);
+    text-align: center;
+  }
+
   .items-image,
   .hanzi-storck {
     width: 80px;
@@ -117,7 +275,70 @@ export default {
     color: #346cda;
   }
 
-  .hanzi-storck {
+  .inputdv {
+    min-height: 32px;
+    margin-top: 16px;
+
+    :deep .edit-div {
+      min-height: 32px;
+      font-size: 16px;
+      line-height: 32px;
+      color: #000;
+      background-color: #deebff;
+      border-radius: 8px;
+    }
+  }
+
+  .items-example,
+  .item-example {
+    :deep .edit-div {
+      color: #346cda;
+    }
+  }
+
+  .items-flex {
+    display: flex;
+    gap: 5px;
+  }
+
+  .item-box-input {
+    .items-flex {
+      gap: 0;
+    }
+
+    .NoborderRadius {
+      border-radius: 0;
+    }
+
+    .rightBorderRadius {
+      border-radius: 0;
+      border-top-right-radius: 8px;
+      border-bottom-right-radius: 8px;
+    }
+
+    .leftBorderRadius {
+      border-radius: 0;
+      border-top-left-radius: 8px;
+      border-bottom-left-radius: 8px;
+    }
+
+    .NoborderRight {
+      border-right: none;
+    }
+  }
+
+  .pinyin-common {
+    margin-bottom: 5px;
+
+    :deep .edit-div {
+      font-family: 'League';
+    }
+  }
+
+  .en-common {
+    margin-top: 8px;
+    text-align: center;
+    word-break: break-word;
   }
 }
 </style>

+ 311 - 0
src/views/book/courseware/preview/components/newWord_template/components/EditDiv.vue

@@ -0,0 +1,311 @@
+<template>
+  <div>
+    <div
+      :id="id"
+      class="edit-div"
+      v-html="content"
+      :contenteditable="canEdit"
+      @compositionstart="compositStart"
+      @compositionend="compositEnd"
+      @paste="copyText"
+      @focus="isLocked = true"
+      @blur="handleBlur"
+      @input="input"
+      @keyup.enter="handleReplaceTone"
+      :style="{ textAlign: textAlign }"
+      placeholder=" "
+    ></div>
+    <!-- :placeholder="placeholder_value" -->
+    <div class="limit" v-if="isShow">{{ textSize }}/{{ maxLength }}</div>
+  </div>
+</template>
+<script>
+export default {
+  name: 'editDiv',
+  props: {
+    value: {
+      type: String,
+      default: '',
+    },
+    canEdit: {
+      type: Boolean,
+      default: true,
+    },
+    placeholder: {
+      type: String,
+      default: '',
+    },
+    id: {
+      type: String,
+      default: 'sendMsg',
+    },
+    textAlign: {
+      type: String,
+      default: 'left',
+    },
+    isShow: {
+      type: Boolean,
+      default: false,
+    },
+    maxLength: {
+      type: Number,
+      default: 200,
+    },
+    hengIndex: {
+      type: Number,
+      default: null,
+    },
+  },
+  data() {
+    return {
+      isLocked: false,
+      textSize: 0,
+      lock: true,
+      fullContent: '',
+      content: this.value, // 文本数据
+      tableData: [
+        ['ā', 'á', 'ǎ', 'à', 'a'],
+        ['ō', 'ó', 'ǒ', 'ò', 'o'],
+        ['ē', 'é', 'ě', 'è', 'e'],
+        ['ī', 'í', 'ǐ', 'ì', 'i'],
+        ['ū', 'ú', 'ǔ', 'ù', 'u'],
+        ['ǖ', 'ǘ', 'ǚ', 'ǜ', 'ü'],
+        ['Ā', 'Á', 'Â', 'À', 'A'],
+        ['Ō', 'Ó', 'Ô', 'Ò', 'O'],
+        ['Ē', 'É', 'Ê', 'È', 'E'],
+        ['Ī', 'Í', 'Î', 'Ì', 'I'],
+        ['Ū', 'Ú', 'Û', 'Ù', 'U'],
+      ],
+    };
+  },
+  watch: {
+    value() {
+      if (!this.isLocked && !this.content) {
+        this.content = this.value;
+      }
+    },
+  },
+  computed: {
+    placeholder_value() {
+      let value = '';
+      let _this = this;
+      if (_this.placeholder == 'place_en') {
+        value = '';
+      } else {
+        value = '';
+      }
+      if (_this.textAlign == 'left' || !_this.textAlign) {
+        value = ' ' + value;
+      } else if (_this.textAlign == 'center') {
+        value = value;
+      } else if (_this.textAlign == 'right') {
+        value = value + ' ';
+      }
+      return value;
+    },
+  },
+  methods: {
+    // 输入中文开始时
+    compositStart(e) {
+      this.lock = false;
+      let id = '#' + this.id;
+      document.querySelector(id).focus();
+      document.execCommand('selectAll', false, null);
+      document.getSelection().collapseToEnd();
+    },
+    // 输入中文结束时
+    compositEnd(e) {
+      this.lock = true;
+      this.input(e);
+    },
+    input(e) {
+      if (this.lock) {
+        this.textSize = e.target.innerHTML.length;
+        if (this.textSize >= this.maxLength) {
+          this.textSize = this.maxLength;
+          this.fullContent = e.target.innerHTML.substring(0, this.maxLength);
+          e.target.innerHTML = e.target.innerHTML.substring(0, this.maxLength);
+        } else {
+          this.fullContent = '';
+        }
+        this.$emit('input', e.target.innerHTML);
+        //this.content = e.target.innerHTML;
+        this.textFocus();
+      } else if (this.fullContent) {
+        // 目标对象:超过200字时候的中文输入法
+        // 原由:虽然不会输入成功,但是输入过程中字母依然会显现在输入框内
+        // 弊端:谷歌浏览器输入法的界面偶尔会闪现
+        e.target.innerHTML = this.fullContent;
+        this.lock = true;
+        this.textFocus();
+      }
+      this.$emit('saveBlankTF', e.target.innerHTML, this.hengIndex);
+    },
+    // 粘贴富文本转为纯文本
+    copyText(e) {
+      e.stopPropagation();
+      e.preventDefault();
+      let text = '',
+        event = e.originalEvent || e;
+      if (event.clipboardData && event.clipboardData.getData) {
+        text = event.clipboardData.getData('text/plain');
+      } else if (window.clipboardData && window.clipboardData.getData) {
+        text = window.clipboardData.getData('Text');
+      }
+      if (document.queryCommandSupported('insertText')) {
+        document.execCommand('insertText', false, text);
+      } else {
+        document.execCommand('paste', false, text);
+      }
+    },
+    // 文本输入框聚焦,焦点在最后位置
+    textFocus() {
+      let _this = this;
+      setTimeout(() => {
+        let id = '#' + _this.id;
+        document.querySelector(id).focus();
+        document.execCommand('selectAll', false, null);
+        document.getSelection().collapseToEnd();
+      }, 0);
+    },
+    handleReplaceTone(e) {
+      let _this = this;
+      _this.$nextTick(() => {
+        let value = e.target.innerHTML;
+        _this.resArr = [];
+        if (value) {
+          let reg = /\s+/g;
+          let valueArr = value.split(reg);
+          valueArr.forEach((item, index) => {
+            this.handleValue(item);
+          });
+          let str = '';
+          setTimeout(() => {
+            _this.resArr.forEach((item) => {
+              str += ' ';
+              item.forEach((sItem) => {
+                if (sItem.number && sItem.con) {
+                  let number = Number(sItem.number);
+                  let con = sItem.con;
+                  let word = _this.addTone(number, con);
+                  str += word;
+                } else {
+                  if (sItem.number) {
+                    str += sItem.number;
+                  } else if (sItem.con) {
+                    str += ' ' + sItem.con + ' ';
+                  }
+                }
+              });
+            });
+            e.target.innerHTML = str.trim();
+            _this.fullContent = str.trim();
+            _this.$emit('input', str.trim());
+            _this.textFocus();
+          }, 10);
+        }
+      });
+    },
+    handleValue(valItem) {
+      let reg = /\d/;
+      let reg2 = /[A-Za-z]+\d/g;
+      let numList = [];
+      let valArr = valItem.split('');
+      if (reg2.test(valItem)) {
+        for (let i = 0; i < valArr.length; i++) {
+          let item = valItem[i];
+          if (reg.test(item)) {
+            let numIndex = numList.length == 0 ? 0 : numList[numList.length - 1].index;
+            let con = valItem.substring(numIndex, i);
+            con = con.replace(/\d/g, '');
+            let obj = {
+              index: i,
+              number: item,
+              con: con,
+              isTran: true,
+            };
+            numList.push(obj);
+          }
+        }
+      } else {
+        numList = [];
+      }
+      if (numList.length == 0) {
+        this.resArr.push([{ con: valItem }]);
+      } else {
+        this.resArr.push(numList);
+      }
+    },
+    addTone(number, con) {
+      let _this = this;
+      let zmList = ['a', 'o', 'e', 'i', 'u', 'v', 'A', 'O', 'E', 'I', 'U'];
+      if (number) {
+        for (let i = 0; i < zmList.length; i++) {
+          let zm = zmList[i];
+          if (con.indexOf(zm) > -1) {
+            let zm2 = _this.tableData[i][number - 1];
+            if (con.indexOf('iu') > -1) {
+              zm2 = _this.tableData[4][number - 1];
+              con = con.replace('u', zm2);
+            } else if (con.indexOf('ui') > -1) {
+              zm2 = _this.tableData[3][number - 1];
+              con = con.replace('i', zm2);
+            } else if (
+              con.indexOf('yv') > -1 ||
+              con.indexOf('jv') > -1 ||
+              con.indexOf('qv') > -1 ||
+              con.indexOf('xv') > -1
+            ) {
+              zm2 = _this.tableData[4][number - 1];
+              con = con.replace('v', zm2);
+            } else {
+              con = con.replace(zm, zm2);
+            }
+
+            break;
+          }
+        }
+      }
+      return con;
+    },
+    handleBlur(e) {
+      this.isLocked = false;
+      e.target.innerHTML = e.target.innerHTML.replace(/&nbsp;/gi, '').trim();
+      this.$emit('input', e.target.innerHTML);
+    },
+  },
+  mounted() {
+    if (this.content) {
+      this.textSize = this.content.length;
+    }
+  },
+};
+</script>
+<style lang="scss" rel="stylesheet/scss">
+.edit-div {
+  width: 100%;
+  // height: 100%; 不可加
+  overflow: auto;
+  word-break: break-all;
+  outline: none;
+  user-select: text;
+  white-space: pre-wrap;
+  text-align: left;
+  &[contenteditable='true'] {
+    user-modify: read-write-plaintext-only;
+    &:empty:before {
+      content: attr(placeholder);
+      display: block;
+      color: #ccc;
+    }
+  }
+}
+.limit {
+  position: absolute;
+  right: 0px;
+  bottom: 0px;
+  font-size: 16px;
+  line-height: 24px;
+  color: rgba(0, 0, 0, 0.45);
+}
+</style>

+ 16 - 3
src/views/book/courseware/preview/components/newWord_template/components/Strockplayredline.vue

@@ -58,7 +58,7 @@ export default {
   watch: {
     targetDiv: {
       handler: function (val, oldVal) {
-        if (val != oldVal) {
+        if (val !== oldVal) {
           let _this = this;
           _this.$nextTick(() => {
             _this.initHanziwrite();
@@ -68,6 +68,17 @@ export default {
       // 深度观察监听
       deep: true,
     },
+    'curItem.answer': {
+      handler: function (val, oldVal) {
+        document.getElementById(this.targetDiv).innerHTML = '';
+        let _this = this;
+        _this.$nextTick(() => {
+          _this.initHanziwrite();
+        });
+      },
+      // 深度观察监听
+      deep: true,
+    },
   },
   //方法集合
   methods: {
@@ -83,7 +94,9 @@ export default {
           strokeColor: _this.strokeColor ? (_this.judgeAnswer ? 'rgba(44, 44, 44, 0.45)' : _this.strokeColor) : '#333',
           radicalColor: _this.judgeAnswer ? '#333' : '#ED5050',
           charDataLoader: function (char, onComplete) {
-            let charData = _this.handleData(_this.curItem.answer);
+            let charData = _this.handleData(
+              _this.type === 'newWord-template-input' ? _this.curItem : _this.curItem.answer,
+            );
             onComplete(charData);
           },
         });
@@ -109,7 +122,7 @@ export default {
         let charData = JSON.parse(JSON.stringify(this.hz_json));
         if (stroke_num) {
           let stroke_arr = null;
-          if (this.type == 'newWord_template') {
+          if (this.type === 'newWord_template' || this.type === 'newWord-template-input') {
             stroke_arr = stroke_num.split('、');
           } else {
             stroke_arr = stroke_num.split('#');