Bladeren bron

Merge branch 'lhd'

natasha 1 week geleden
bovenliggende
commit
1dd956d588

+ 16 - 16
src/views/book/courseware/data/bookType.js

@@ -247,14 +247,14 @@ export const bookTypeOption = [
         set: ArticleSetting,
         preview: ArticlePreview,
       },
-      {
-        value: 'dialogue_article',
-        label: '对话课文',
-        icon: '',
-        component: DialogueArticlePage,
-        set: DialogueArticleSetting,
-        preview: DialogueArticlePreview,
-      },
+      // {
+      //   value: 'dialogue_article',
+      //   label: '对话课文',
+      //   icon: '',
+      //   component: DialogueArticlePage,
+      //   set: DialogueArticleSetting,
+      //   preview: DialogueArticlePreview,
+      // },
       {
         value: 'select',
         label: '选择组件',
@@ -351,14 +351,14 @@ export const bookTypeOption = [
         set: CharacterStructureSetting,
         preview: CharacterStructurePreview,
       },
-      // {
-      //   value: 'write',
-      //   label: '书写组件',
-      //   icon: '',
-      //   component: Write,
-      //   set: WriteSetting,
-      //   preview: WritePreview,
-      // },
+      {
+        value: 'write',
+        label: '书写组件',
+        icon: '',
+        component: Write,
+        set: WriteSetting,
+        preview: WritePreview,
+      },
       // {
       //   value: 'math',
       //   label: '公式组件',

+ 467 - 7
src/views/book/courseware/preview/components/character/CharacterPreview.vue

@@ -4,7 +4,122 @@
     <SerialNumberPosition v-if="isEnable(data.property.sn_display_mode)" :property="data.property" />
 
     <div class="main">
-      <div v-for="(item, index) in data.content_list" :key="index" class="content-box">
+      <template v-if="data.property.model === 'write'">
+        <div
+          class="item-box"
+          :class="[!item.is_margin ? 'item-box-write' : '']"
+          v-for="(item, index) in data.option_list"
+          :key="index"
+        >
+          <div
+            class="number-box"
+            :style="{
+              marginTop: isEnable(data.property.is_enable_pinyin) ? '30px' : '',
+            }"
+          >
+            <span class="number">{{ index + 1 }}</span>
+          </div>
+          <div class="pinyin-en" :class="[item.is_example ? 'item-example' : '']">
+            <div v-if="isEnable(data.property.is_enable_pinyin) && item.is_common_pinyin" class="pinyin">
+              {{ item.pinyin }}
+            </div>
+            <div class="items-flex">
+              <div class="items" v-for="(items, indexs) in item.content_list" :key="indexs">
+                <div v-if="isEnable(data.property.is_enable_pinyin) && !item.is_common_pinyin" class="pinyin">
+                  {{ items.pinyin }}
+                </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.is_margin && item.content_list.length > 1 && indexs == 0 ? 'leftBorderRadius' : '',
+
+                      !item.is_margin && item.content_list.length > 1 && indexs == item.content_list.length - 1
+                        ? 'rightBorderRadius'
+                        : '',
+                      !item.is_margin &&
+                      item.content_list.length > 1 &&
+                      indexs != item.content_list.length - 1 &&
+                      indexs != 0
+                        ? 'NoborderRadius'
+                        : '',
+                      !item.is_margin && item.content_list.length > 1 && indexs != item.content_list.length - 1
+                        ? 'NoborderRight'
+                        : '',
+                    ]"
+                  />
+
+                  <div
+                    :class="[
+                      'strockplay-newWord',
+                      !item.is_margin && item.content_list.length > 1 && indexs == 0 ? 'leftBorderRadius' : '',
+
+                      !item.is_margin && item.content_list.length > 1 && indexs == item.content_list.length - 1
+                        ? 'rightBorderRadius'
+                        : '',
+                      !item.is_margin &&
+                      item.content_list.length > 1 &&
+                      indexs != item.content_list.length - 1 &&
+                      indexs != 0
+                        ? 'NoborderRadius'
+                        : '',
+                      !item.is_margin && item.content_list.length > 1 && indexs != item.content_list.length - 1
+                        ? 'NoborderRight'
+                        : '',
+                    ]"
+                    v-if="items && items.type === 'write'"
+                    @click="
+                      freeWrite(
+                        userAnswer[index][indexs].imgArr ? userAnswer[index][indexs].imgArr : null,
+                        index,
+                        indexs,
+                      )
+                    "
+                  >
+                    <SvgIcon icon-class="hanzi-writer-bg" class="character-target-bg" />
+                    <img
+                      v-if="
+                        !play_status &&
+                        userAnswer[index][indexs].imgArr &&
+                        userAnswer[index][indexs].imgArr.strokes_image
+                      "
+                      class="hanzi-writer-img"
+                      :src="userAnswer[index][indexs].imgArr.strokes_image"
+                      alt=""
+                    />
+                  </div>
+                </div>
+              </div>
+            </div>
+            <div class="en-common">{{ item.shiyi }}</div>
+          </div>
+        </div>
+      </template>
+      <!-- <div v-for="(item, index) in data.option_list" :key="index" class="content-box">
         <div class="main-top" :style="{ width: item.hz_strokes_list.length * 64 + 'px' }">
           <AudioPlay v-if="isEnable(data.property.is_enable_voice)" :file-id="item.audio_file_id" theme-color="gray" />
           <span v-if="isEnable(data.property.is_enable_pinyin)" class="pinyin">{{ item.pinyin }}</span>
@@ -22,6 +137,65 @@
             :frame-color="data.property.frame_color"
           />
         </div>
+      </div> -->
+      <div v-if="if_free_show" class="practiceBox practice-box-strock">
+        <FreewriteLettle
+          ref="freePaint"
+          :current-tree-i-d="'1234456'"
+          :current-hz="current_hz"
+          :curren-hz-data="current_hz_data"
+          :row-index="active_index"
+          :col-index="active_col_index"
+          :disabled="disabled"
+          :show-play="isEnable(data.property.is_enable_play_back)"
+          @closeIfFreeShow="closeIfFreeShow"
+          @changePraShow="changePraShow"
+          @changeCurQue="changeCurQue"
+          @deleteWriteRecord="deleteWriteRecord"
+        />
+      </div>
+      <div v-if="if_miao_show" class="practiceBox practice-box-strock">
+        <div class="miao-box">
+          <i class="el-icon-close close-icon" @click="if_miao_show = false"></i>
+          <Strockplayredline
+            v-if="
+              (data.answer.answer_list[active_index].strokes_content_list[active_col_index] &&
+                data.answer.answer_list[active_index].strokes_content_list[active_col_index] === 'true') ||
+              disabled
+            "
+            :play-storkes="false"
+            :book-text="current_hz"
+            :target-div="'write-praT' + current_hz + active_col_index + Math.random().toString(36).substring(2, 10)"
+            :book-strokes="current_hz_data"
+            :stroke-color="
+              disabled &&
+              (!data.answer.answer_list[active_index].strokes_content_list[active_col_index] ||
+                (data.answer.answer_list[active_index].strokes_content_list[active_col_index] &&
+                  data.answer.answer_list[active_index].strokes_content_list[active_col_index] === 'false'))
+                ? '#ddd'
+                : ''
+            "
+          />
+          <Strockred
+            ref="strockRed"
+            :class="[
+              'strock-red',
+              data.answer.answer_list[active_index].strokes_content_list[active_col_index] &&
+              data.answer.answer_list[active_index].strokes_content_list[active_col_index] === 'true'
+                ? 'strock-red-zindex'
+                : '',
+            ]"
+            :book-text="current_hz"
+            :hanzi-color="hanzi_color"
+            :target-div="'write-praT' + current_hz + active_col_index + Math.random().toString(36).substring(2, 10)"
+            :book-strokes="current_hz_data"
+            :is-answer.sync="data.answer.answer_list[active_index].strokes_content_list[active_col_index]"
+            :show-error-tip="isEnable(data.property.is_enable_error)"
+          />
+          <div v-if="!disabled" :class="['reset-box']" @click="resetHanzi">
+            <SvgIcon icon-class="reset" class="reset-btn" />
+          </div>
+        </div>
       </div>
     </div>
   </div>
@@ -32,24 +206,128 @@ import { getCharacterData } from '@/views/book/courseware/data/character';
 
 import PreviewMixin from '../common/PreviewMixin';
 import AudioPlay from '../character_base/components/AudioPlay.vue';
-import Strockplayredline from '../character_base/components/Strockplayredline.vue';
+import Strockplayredline from '../newWord_template/components/Strockplayredline.vue';
+import Strockred from '../character_base/components/Strockred.vue';
+import FreewriteLettle from '../character_base/components/FreewriteLettle.vue';
 
 export default {
   name: 'CharacterPreview',
   components: {
     AudioPlay,
     Strockplayredline,
+    Strockred,
+    FreewriteLettle,
   },
   mixins: [PreviewMixin],
   data() {
     return {
       data: getCharacterData(),
+      userAnswer: [],
+      hanzi_color: '#404040', // 描红汉字底色
+      writer_number_yuan: 15,
+      writer_number: null, // 书写个数
+      miao_number: null, // 描红个数
+      if_free_show: false,
+      free_img: [],
+      active_index: null,
+      active_col_index: null,
+      current_hz: '', // 当前汉字
+      current_hz_data: null, // 当前汉字数据
+      play_status: false, // 播放状态
+      active_mark: '',
+      option_list: [],
+      show_preview: false,
+      miao_arr: [],
+      if_miao_show: false, // 描红模块
     };
   },
   computed: {},
-  watch: {},
+  watch: {
+    'data.option_list': {
+      handler(val) {
+        if (val) {
+          this.handleData();
+        }
+      },
+      deep: true,
+      immediate: true,
+    },
+  },
   created() {},
-  methods: {},
+  methods: {
+    handleData() {
+      console.log(this.data.option_list);
+      let answer_list = [];
+      this.data.option_list.forEach((item) => {
+        let arr = [];
+        item.content_list.forEach((items) => {
+          if (this.data.property.model === 'write') {
+            let obj = null;
+            if (items.type === 'write') {
+              obj = {
+                imgArr: null,
+              };
+            }
+            arr.push(obj);
+          } else {
+          }
+        });
+        answer_list.push(arr);
+      });
+      this.userAnswer = answer_list;
+    },
+    changePraShow() {
+      this.if_free_show = false;
+    },
+    closeIfFreeShow(data, rowIndex, colIndex, mark) {
+      // this.option_list[rowIndex].imgArr[colIndex] = JSON.stringify(data);
+      this.if_free_show = false;
+      this.freeWrite(data, rowIndex, colIndex);
+      this.$forceUpdate();
+    },
+    freeWrite(imgUrl, index, indexs) {
+      this.if_free_show = true;
+      this.active_index = index;
+      this.active_col_index = indexs;
+
+      this.current_hz = this.data.option_list[index].content_list[indexs].con;
+      this.current_hz_data = imgUrl;
+    },
+    // 删除记录
+    deleteWriteRecord(rowIndex, colIndex) {
+      this.$set(this.option_list[rowIndex].imgArr, colIndex, JSON.stringify({}));
+      this.changeCurQue(null, rowIndex, colIndex);
+      this.current_hz_data = null;
+      this.active_mark = '';
+      this.$forceUpdate();
+    },
+    changeCurQue(answer, rowIndex, colIndex) {
+      if (answer) {
+        this.userAnswer[rowIndex][colIndex].imgArr = answer;
+        this.$forceUpdate();
+      }
+    },
+    // 点击描红模块
+    miaoStorkes(index, indexs, mark, content, storkes) {
+      this.if_miao_show = true;
+      this.active_index = index;
+      this.active_col_index = indexs;
+      this.active_mark = mark;
+      this.current_hz = content;
+      this.current_hz_data = storkes;
+    },
+    // 保存描红
+    saveComplete(flag) {
+      this.answer.answer_list[this.active_index].strokes_content_list[this.active_col_index] = flag;
+    },
+    resetHanzi() {
+      this.$refs.strockRed.resetHanzi();
+    },
+    updateColor(color) {
+      this.writer.updateColor('strokeColor', color);
+      this.writer.updateColor('drawingColor', color);
+    },
+  },
 };
 </script>
 
@@ -116,9 +394,10 @@ export default {
     position: relative;
     box-sizing: border-box;
     flex-shrink: 0;
-    width: 64px;
-    height: 64px;
-    border: 1px solid #e81b1b;
+    width: 80px;
+    height: 80px;
+    border: 2px solid #346cda;
+    border-radius: 8px;
 
     .character-target-bg,
     .hanzi-writer-img {
@@ -138,5 +417,186 @@ export default {
   .border-right-none {
     border-right: none;
   }
+
+  .item-box {
+    display: flex;
+    gap: 5px;
+  }
+
+  .number-box {
+    display: flex;
+    align-items: center;
+    height: 80px;
+    margin-right: 16px;
+
+    .number {
+      display: block;
+      width: 24px;
+      height: 24px;
+      font-family: 'arial';
+      font-size: 14px;
+      font-weight: bold;
+      line-height: 24px;
+      color: #fff;
+      text-align: center;
+      background: #346cda;
+      border-radius: 100%;
+    }
+  }
+
+  .items {
+    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;
+    height: 80px;
+    overflow: hidden;
+    border: 2px solid #346cda;
+    border-radius: 8px;
+  }
+
+  .items-lian {
+    display: block;
+    height: 80px;
+    padding: 0 10px;
+    font-size: 34px;
+    line-height: 80px;
+    color: #346cda;
+  }
+
+  .items-flex {
+    display: flex;
+    gap: 5px;
+  }
+
+  .item-box-write {
+    .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;
+  }
+
+  .practiceBox {
+    position: fixed;
+    top: 0;
+    left: 0;
+    z-index: 101;
+    box-sizing: border-box;
+    width: 100%;
+    height: 100vh;
+    overflow: hidden;
+    overflow-y: auto;
+    background: rgba(0, 0, 0, 19%);
+
+    &.practice-box-strock {
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      padding-top: 0;
+    }
+
+    .miao-box {
+      position: relative;
+      width: 332px;
+      height: 360px;
+      padding: 30px 16px;
+      margin: 0 auto;
+      background: #f3f3f3;
+      border-radius: 8px;
+      box-shadow: 0 4px 16px rgba(0, 0, 0, 15%);
+
+      .close-icon {
+        position: absolute;
+        top: 0;
+        right: 8px;
+        z-index: 2;
+        width: 32px;
+        height: 32px;
+        padding: 8px;
+        cursor: pointer;
+      }
+
+      .strockredBox,
+      .strockplay-redInner {
+        width: 300px;
+        height: 300px;
+        margin: 0 auto;
+      }
+
+      .strock-red {
+        position: absolute;
+        top: 30px;
+        left: 16px;
+
+        &-zindex {
+          z-index: -1;
+        }
+      }
+
+      .reset-box {
+        position: absolute;
+        right: 22px;
+        bottom: 22px;
+        z-index: 100;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        width: 11px;
+        height: 11px;
+        color: $text-color;
+        cursor: pointer;
+
+        &:hover {
+          color: #000;
+        }
+      }
+    }
+  }
 }
 </style>

+ 1 - 1
src/views/book/courseware/preview/components/character_base/components/FreewriteLettle.vue

@@ -200,7 +200,7 @@ export default {
           strokes_content: JSON.stringify(this.$refs.esign.history),
           strokes_image: write_img,
         };
-        this.$emit('changeCurQue', answer, this.colIndex);
+        this.$emit('changeCurQue', answer, this.rowIndex, this.colIndex);
         let obj = {
           hz: this.currentHz,
           strokes_content: JSON.stringify(this.$refs.esign.history),