natasha 1 год назад
Родитель
Сommit
dfd2d77226

+ 525 - 0
src/components/common/AudioLineSentence.vue

@@ -0,0 +1,525 @@
+<template>
+  <!-- mp3Source && mp3Source == 'tts' ? 'Audio-tts' : '', -->
+  <div :class="['Audio', 'AudioFull']">
+    <div
+      :class="['audioLine3', bgIndex == 1 ? 'audioLine3-green' : '']"
+      @click="PlayAudio"
+    >
+      <div
+        class="play"
+        :class="[
+          audio.loading ? 'loadBtn' : audio.playing ? 'playBtn' : 'pauseBtn',
+        ]"
+      >
+        <svg-icon icon-class="play-fill" className="icon-svg"></svg-icon>
+      </div>
+    </div>
+
+    <!-- <div :class="['audioLine', bgIndex == 1 ? 'audioLine-green' : '']">
+      <div
+        class="play"
+        :class="[
+          audio.loading ? 'loadBtn' : audio.playing ? 'playBtn' : 'pauseBtn',
+        ]"
+        @click="PlayAudio"
+      />
+      <template >
+        <el-slider
+          v-model="playValue"
+          :style="{ width: sliderWidth + 'px', height: '6px' }"
+          :format-tooltip="formatProcessToolTip"
+          @change="changeCurrentTime"
+        />
+        <span :class="bgIndex == 1 ? 'color-white' : ''">
+          {{ realFormatSecond(audio.maxTime) }}
+
+        </span>
+      </template>
+    </div> -->
+    <!-- <div v-else class="audioLine2">
+      <div
+        class="play-icon"
+        :class="
+          audio.loading
+            ? 'loadBtn'
+            : audio.playing
+            ? 'playBtn-icon'
+            : 'pauseBtn-icon'
+        "
+        @click="PlayAudio"
+      />
+    </div> -->
+    <audio
+      :id="audioId"
+      :ref="audioId"
+      :src="mp3"
+      preload="meta"
+      @loadedmetadata="onLoadedmetadata"
+      @timeupdate="onTimeupdate"
+      @canplaythrough="oncanplaythrough"
+    />
+  </div>
+</template>
+
+<script>
+// 这里可以导入其它文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)
+// 例如:import 《组件名称》from ‘《组件路径》';
+export default {
+  // import引入的组件需要注入到对象中才能使用
+  components: {},
+  props: [
+    "mp3",
+    "mp3Source",
+    "getCurTime",
+    "stopAudio",
+    "width",
+    "isRepeat",
+    "themeColor",
+    "ed",
+    "bg",
+    "audioId",
+    "maxTime",
+    "hideSlider",
+    "bgIndex",
+    "wordPlay",
+    "isAuto",
+    "curTime",
+  ],
+  data() {
+    // 这里存放数据
+    return {
+      playValue: 0,
+      audio: {
+        // 该字段是音频是否处于播放状态的属性
+        playing: false,
+        // 音频当前播放时长
+        currentTime: 0,
+        // 音频最大播放时长
+        maxTime: 0,
+        isPlaying: false,
+        loading: false,
+      },
+      playTime: parseInt(this.maxTime),
+      audioAllTime: null, // 展示总时间
+      duioCurrentTime: null, // 剩余时间
+      count: 0,
+      loading: null,
+      playcount: 0,
+    };
+  },
+  // 计算属性 类似于data概念
+  computed: {
+    sliderWidth() {
+      let width = 0;
+      if (this.width) {
+        width = this.width;
+      } else {
+        width = 662;
+      }
+      return width;
+    },
+  },
+  // 监控data中数据变化
+  watch: {
+    stopAudio: {
+      handler(val, oldVal) {
+        const _this = this;
+        if (val) {
+          _this.$refs[_this.audioId].pause();
+          _this.audio.playing = false;
+        }
+      },
+      // 深度观察监听
+      deep: true,
+    },
+    "audio.playing": {
+      handler(val) {
+        this.$emit("playChange", val);
+        if (val) this.$emit("handleChangeStopAudio");
+      },
+    },
+  },
+  // 生命周期 - 创建完成(可以访问当前this实例)
+  created() {},
+  // 生命周期 - 挂载完成(可以访问DOM元素)
+  mounted() {
+    let _this = this;
+    _this.$nextTick(() => {
+      if (_this.wordPlay) {
+        _this.PlayAudio();
+      }
+      if (_this.isAuto) {
+        _this.PlayAudio();
+      }
+    });
+
+    let audioId = _this.audioId;
+    _this.$refs[audioId].addEventListener("loadstart", function () {});
+    _this.$refs[audioId].addEventListener("play", function () {
+      _this.audio.playing = true;
+      _this.audio.loading = false;
+    });
+    _this.$refs[audioId].addEventListener("pause", function () {
+      _this.audio.playing = false;
+      if (_this.audio.currentTime * 1000 + 500 > _this.ed) {
+        // _this.$emit("sentPause", true);
+        _this.playValue = 0;
+        _this.audio.isPlaying = false;
+      }
+      if (_this.wordPlay) {
+        _this.$emit("changePlayStatus");
+        _this.audio.isPlaying = false;
+      }
+    });
+    _this.$refs[audioId].addEventListener("ended", function () {
+      _this.audio.playing = false;
+      _this.audio.isPlaying = false;
+      _this.$emit("handleListenRead", false);
+    });
+
+    this.$nextTick(() => {
+      document
+        .getElementsByClassName("el-slider__button-wrapper")[0]
+        .addEventListener("mousedown", function () {
+          _this.$refs[audioId].pause();
+          _this.audio.playing = false;
+        });
+    });
+  },
+  // 生命周期-挂载之前
+  beforeMount() {},
+  // 生命周期-更新之后
+  updated() {},
+  // 如果页面有keep-alive缓存功能,这个函数会触发
+  activated() {},
+  // 方法集合
+  methods: {
+    PlayAudio() {
+      let audioId = this.audioId;
+      let audio = document.getElementsByTagName("audio");
+      if(audio&&audio.length>0&&window.location.href.indexOf('GCLS-Learn')==-1){
+        audio.forEach((item) => {
+            if (item.src == this.mp3) {
+            if (item.id !== audioId) {
+                item.pause();
+            }
+            } else {
+            item.pause();
+            }
+        });
+      }
+      let video = document.getElementsByTagName("video");
+      if(video&&video.length>0&&window.location.href.indexOf('GCLS-Learn')==-1){
+        video.forEach((vItem) => {
+            vItem.pause();
+        });
+      }
+      this.$set(this.audio, "isPlaying", true);
+
+      if (this.audio.playing) {
+        this.$refs[audioId].pause();
+        this.audio.playing = false;
+        this.$emit("handleListenRead", false);
+      } else {
+        if (this.count == 0) {
+          this.audio.loading = true;
+          this.count++;
+        }
+
+        this.$refs[audioId].play();
+        if (this.playcount == 0) {
+          this.onTimeupdateTime(this.bg / 1000);
+          this.playcount++;
+        }
+
+        this.$emit("handleChangeStopAudio");
+        this.$emit("handleListenRead", true);
+      }
+    },
+    oncanplaythrough() {
+      let _this = this;
+      // setTimeout(() => {
+      _this.audio.loading = false;
+
+      // }, 10000);
+    },
+    // 点击 拖拽播放音频
+    changeCurrentTime(value) {
+      let audioId = this.audioId;
+      this.$refs[audioId].play();
+      this.audio.playing = true;
+      this.$refs[audioId].currentTime = parseInt(
+        (value / 100) * this.audio.maxTime
+      );
+    },
+    mousedown() {
+      let audioId = this.audioId;
+      this.$refs[audioId].pause();
+      this.audio.playing = false;
+    },
+    // 进度条格式化toolTip
+    formatProcessToolTip(index) {
+      index = parseInt((this.audio.maxTime / 100) * index);
+      return this.realFormatSecond(index);
+    },
+    // 音频加载完之后
+    onLoadedmetadata(res) {
+      this.audio.maxTime = parseInt(this.maxTime);
+      // this.audio.maxTime = parseInt(res.target.duration);
+      // this.playTime = parseInt(this.maxTime);
+      // this.audioAllTime = this.realFormatSecond(this.audio.maxTime);
+    },
+    // 当音频当前时间改变后,进度条也要改变
+    onTimeupdate(res) {
+      let _this = this;
+      let audioId = _this.audioId;
+
+      _this.audio.currentTime = res.target.currentTime;
+      _this.getCurTime(res.target.currentTime);
+      let time = _this.audio.currentTime - _this.bg / 1000;
+      _this.playValue = (time / _this.audio.maxTime) * 100;
+      setTimeout(() => {
+        if (_this.audio.currentTime * 1000 > _this.ed) {
+          if (_this.$refs[audioId]) {
+            _this.$refs[audioId].pause();
+            _this.playcount = 0;
+          }
+        }
+      }, 50);
+    },
+    onTimeupdateTime(res, playFlag) {
+      if (!res) return;
+      let audioId = this.audioId;
+      this.$refs[audioId].currentTime = res;
+      let time = res - this.bg / 1000;
+      this.playValue = (time / this.audio.maxTime) * 100;
+      if (playFlag) {
+        let audio = document.getElementsByTagName("audio");
+        if(audio&&audio.length>0&&window.location.href.indexOf('GCLS-Learn')==-1){
+            audio.forEach((item) => {
+            if (item.id !== audioId) {
+                item.pause();
+            }
+            });
+        }
+        this.$refs[audioId].play();
+      }
+    },
+    // 将整数转换成 时:分:秒的格式
+    realFormatSecond(value) {
+      let theTime = parseInt(value); // 秒
+      let theTime1 = 0; // 分
+      let theTime2 = 0; // 小时
+      if (theTime > 60) {
+        theTime1 = parseInt(theTime / 60);
+        theTime = parseInt(theTime % 60);
+        if (theTime1 > 60) {
+          theTime2 = parseInt(theTime1 / 60);
+          theTime1 = parseInt(theTime1 % 60);
+        }
+      }
+      let result = String(parseInt(theTime));
+      if (result < 10) {
+        result = "0" + result;
+      }
+      if (theTime1 > 0) {
+        result = String(parseInt(theTime1)) + ":" + result;
+        if (theTime1 < 10) {
+          result = "0" + result;
+        }
+      } else {
+        result = "00:" + result;
+      }
+      if (theTime2 > 0) {
+        result = String(parseInt(theTime2)) + ":" + result;
+        if (theTime2 < 10) {
+          result = "0" + result;
+        }
+      } else {
+        // result = "00:" + result;
+      }
+      return result;
+    },
+  },
+  // 生命周期-创建之前
+  beforeCreated() {},
+  // 生命周期-更新之前
+  beforUpdate() {},
+  // 生命周期-销毁之前
+  beforeDestory() {},
+  // 生命周期-销毁完成
+  destoryed() {},
+};
+</script>
+<style lang="scss" scoped>
+/* @import url(); 引入css类 */
+.AudioFull {
+  .audioLine {
+    display: flex;
+    align-items: center;
+    width: 100%;
+    height: 40px;
+    background: #ffffff;
+    // border: 1px solid rgba(0, 0, 0, 0.1);
+    // box-shadow: 0px 2px 6px rgba(0, 0, 0, 0.1);
+    box-sizing: border-box;
+    border-radius: 4px;
+    &-green {
+      background: 0 0;
+    }
+    .play {
+      margin-right: 12px;
+      margin-left: 8px;
+      width: 16px;
+      min-width: 16px;
+      height: 16px;
+      cursor: pointer;
+      display: block;
+    }
+
+    span {
+      font-size: 16px;
+      line-height: 19px;
+      color: #000;
+      margin-left: 8px;
+      margin-right: 12px;
+      font-weight: bold;
+      font-size: 16px;
+      line-height: 24px;
+      text-align: right;
+      &.color-white {
+        color: #fff;
+      }
+    }
+  }
+  .audioLine2 {
+    .play-icon {
+      width: 16px;
+      height: 16px;
+      cursor: pointer;
+    //   &.playBtn-icon {
+    //     background: url("../../../assets/icon/pauseC-16-normal-red.png")
+    //       no-repeat left top;
+    //     background-size: 100% 100%;
+    //   }
+    //   &.pauseBtn-icon {
+    //     background: url("../../../assets/NPC/compare-pause-red.png") no-repeat
+    //       left top;
+    //     background-size: 100% 100%;
+    //   }
+    }
+  }
+  .loadBtn {
+    // background: url("../../../assets/NPC/loading-red.png") no-repeat left top;
+    // background-size: 100% 100%;
+  }
+  .audioLine3 {
+    width: 56px;
+    height: 56px;
+    background: #ffffff;
+    border: 1px solid rgba(0, 0, 0, 0.1);
+    border-radius: 40px;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+
+    .play {
+      width: 24px;
+      height: 24px;
+      cursor: pointer;
+    //   &.playBtn {
+    //     background: url("../../../assets/icon/pause-24-normal-red.png")
+    //       no-repeat left top;
+    //     background-size: 100% 100%;
+    //   }
+    //   &.pauseBtn {
+    //     background: url("../../../assets/icon/play-24-normal-red.png") no-repeat
+    //       left top;
+    //     background-size: 100% 100%;
+    //   }
+    }
+    &-green {
+      background: rgba(255, 255, 255, 0.1);
+      border: 1px solid rgba(0, 0, 0, 0.1);
+      .play {
+        // &.playBtn {
+        //   background: url("../../../assets/icon/pause-24-normal-yellow.png")
+        //     no-repeat left top;
+        //   background-size: 100% 100%;
+        // }
+        // &.pauseBtn {
+        //   background: url("../../../assets/icon/play-24-normal-yellow.png")
+        //     no-repeat left top;
+        //   background-size: 100% 100%;
+        // }
+      }
+    }
+  }
+}
+</style>
+<style lang="scss">
+.AudioFull {
+  .el-slider__button-wrapper {
+    position: relative;
+    z-index: 0;
+  }
+  .el-slider__button {
+    width: 6px;
+    height: 12px;
+    border-radius: 6px;
+    top: 12px;
+    position: absolute;
+  }
+  .el-slider__runway {
+    margin: 0;
+    padding: 0;
+    background: #e5e5e5;
+    border-radius: 6px;
+    height: 6px;
+  }
+  .el-slider {
+    position: relative;
+  }
+  .el-slider__bar {
+    height: 6px;
+    border-radius: 6px 0 0 6px;
+    background: #de4444;
+  }
+  .el-slider__button {
+    background: #de4444;
+    border: none;
+  }
+  .el-slider__button-wrapper {
+    width: 25px;
+  }
+  .audioLine-green {
+    .el-slider__bar {
+      background: #ffc600 !important;
+    }
+    .el-slider__button {
+      background: #ffc600 !important;
+    }
+  }
+}
+.NPC-Book-Sty {
+  .AudioFull {
+    .el-slider__bar {
+      height: 6px;
+      border-radius: 6px;
+      background: #de4444;
+    }
+    .el-slider__button {
+      background: #de4444;
+      border: none;
+    }
+    .audioLine-green {
+      .el-slider__bar {
+        background: #ffc600 !important;
+      }
+      .el-slider__button {
+        background: #ffc600 !important;
+      }
+    }
+  }
+}
+</style>

+ 6 - 6
src/views/bookShelf/articleDetail.vue

@@ -20,12 +20,12 @@
         <div class="artricle-inner" :style="{background:bgColorList[activeIndex].contentInnerBg}">
             <!-- 文章 -->
             <div class="atricle-data">
-                <normal-model :titleFontsize="wordFontsize+30" :wordFontsize="wordFontsize" :colorObj="bgColorList[activeIndex]" :articleType="articleType" :style="{'padding':'0 40px'}" v-if="menuType==='original'" :articleInfo="articleInfo"></normal-model>
-                <phrase-model :titleFontsize="wordFontsize+30" :wordFontsize="wordFontsize" :colorObj="bgColorList[activeIndex]" :articleType="articleType" :style="{'padding':'0 40px'}" v-if="menuType==='newWord'" :articleInfo="articleInfo" :likePhraseList="likePhraseList" :likeWord="likeWordList" @changeLike="changeLike"></phrase-model>
-                <practice-model :titleFontsize="wordFontsize+30" :wordFontsize="wordFontsize" :colorObj="bgColorList[activeIndex]" :articleType="articleType" :style="{'padding':'0 40px'}" v-if="menuType==='practice'" :articleInfo="articleInfo"></practice-model>
-                <inner-text-search :titleFontsize="wordFontsize+30" :wordFontsize="wordFontsize" :colorObj="bgColorList[activeIndex]" :articleType="articleType" :style="{'padding':'0 40px'}" v-if="menuType==='search'" :articleInfo="articleInfo" ref="innerTextSearchs"></inner-text-search>
-                <lexical-type :titleFontsize="wordFontsize+30" :wordFontsize="wordFontsize" :colorObj="bgColorList[activeIndex]" :articleType="articleType" :style="{'padding':'0 40px'}" v-if="menuType==='filtrate'" :articleInfo="articleInfo" ref="lexicalType"></lexical-type>
-                <notes-model :titleFontsize="wordFontsize+30" :wordFontsize="wordFontsize" :colorObj="bgColorList[activeIndex]" :articleType="articleType" :style="{'padding':'0 40px'}" v-if="menuType==='notebook'" :articleInfo="articleInfo"></notes-model>
+                <normal-model :titleFontsize="wordFontsize+30" :wordFontsize="wordFontsize" :colorObj="bgColorList[activeIndex]" :articleType="articleType" :style="{'padding':'0 40px'}" v-if="menuType==='original'" :articleInfo="articleInfo" :likeSentencelist="likeSentencelist"></normal-model>
+                <phrase-model :titleFontsize="wordFontsize+30" :wordFontsize="wordFontsize" :colorObj="bgColorList[activeIndex]" :articleType="articleType" :style="{'padding':'0 40px'}" v-if="menuType==='newWord'" :articleInfo="articleInfo" :likePhraseList="likePhraseList" :likeWord="likeWordList" @changeLike="changeLike" :likeSentencelist="likeSentencelist"></phrase-model>
+                <practice-model :titleFontsize="wordFontsize+30" :wordFontsize="wordFontsize" :colorObj="bgColorList[activeIndex]" :articleType="articleType" :style="{'padding':'0 40px'}" v-if="menuType==='practice'" :articleInfo="articleInfo" :likeSentencelist="likeSentencelist"></practice-model>
+                <inner-text-search :titleFontsize="wordFontsize+30" :wordFontsize="wordFontsize" :colorObj="bgColorList[activeIndex]" :articleType="articleType" :style="{'padding':'0 40px'}" v-if="menuType==='search'" :articleInfo="articleInfo" ref="innerTextSearchs" :likeSentencelist="likeSentencelist"></inner-text-search>
+                <lexical-type :titleFontsize="wordFontsize+30" :wordFontsize="wordFontsize" :colorObj="bgColorList[activeIndex]" :articleType="articleType" :style="{'padding':'0 40px'}" v-if="menuType==='filtrate'" :articleInfo="articleInfo" ref="lexicalType" :likeSentencelist="likeSentencelist"></lexical-type>
+                <notes-model :titleFontsize="wordFontsize+30" :wordFontsize="wordFontsize" :colorObj="bgColorList[activeIndex]" :articleType="articleType" :style="{'padding':'0 40px'}" v-if="menuType==='notebook'" :articleInfo="articleInfo" :likeSentencelist="likeSentencelist"></notes-model>
                 <div class="article-btn" v-if="this.$route.query.iss_id&&menuType!=='practice'">
                     <div class="left">
                         <span :class="['support colloct-article',!noRead?'active':'']" @click="changeStatus('noRead')"><svg-icon icon-class="like-line" :style="{marginRight:articleNumber?'8px':'0px'}"></svg-icon>{{articleNumber?articleNumber:''}}</span>

+ 66 - 4
src/views/bookShelf/components/InnerTextSearch.vue

@@ -49,7 +49,7 @@
                 ref="audioLine"
                 :mp3Source="'mp3'"
             />
-            <svg-icon icon-class="icon-wrapper" class="wrapper"></svg-icon>
+            <svg-icon icon-class="icon-wrapper" class="wrapper" @click="fullScreen"></svg-icon>
         </div>
     </div>
     <template v-if="resArr.length > 0">
@@ -157,16 +157,29 @@
             </ul>
         </div>
     </div>
+    <div class="voice-full-screen" :id="'screen-' + mathNum">
+      <Voicefullscreen
+        v-if="isFull"
+        :curQue="articleInfo"
+        :sentIndex="0"
+        :mp3="articleInfo.art_sound_url"
+        :likeSentencelist="likeSentencelist"
+        @exitFullscreen="exitFullscreen"
+        @changeIsFull="changeIsFull"
+      />
+    </div>
   </div>
 </template>
 
 <script>
 import AudioLine from "@/components/common/AudioLine.vue"
+import Voicefullscreen from './Voicefullscreen.vue';
 export default {
   name: "ArticleView",
-  props: [ "titleFontsize", "wordFontsize", "colorObj","articleType","articleInfo"],
+  props: [ "titleFontsize", "wordFontsize", "colorObj","articleType","articleInfo","likeSentencelist"],
   components: {
     AudioLine,
+    Voicefullscreen
   },
   data() {
     return {
@@ -250,7 +263,9 @@ export default {
       currentcolorValue: [],
       currentBorderColorValue: [],
       searchResultList: [], // 匹配结果list
-      alreadySelectIndex: 0
+      alreadySelectIndex: 0,
+      isFull: false,
+      mathNum: Math.random().toString(36).substr(2),
     };
   },
   computed: {
@@ -461,7 +476,54 @@ export default {
                 }
             });
         });
-    }
+    },
+    pauseAudio() {
+      let audio = document.getElementsByTagName("audio");
+      audio.forEach((item) => {
+        item.pause();
+      });
+    },
+    pauseVideo() {
+      let video = document.getElementsByTagName("video");
+      video.forEach((item) => {
+        item.pause();
+      });
+    },
+    //语音全屏
+    fullScreen() {
+      this.pauseAudio();
+      this.pauseVideo();
+      this.isFull = true;
+      this.goFullscreen();
+    },
+    goFullscreen() {
+      let id = "screen-" + this.mathNum;
+      var element = document.getElementById(id);
+      if (element.requestFullscreen) {
+        element.requestFullscreen();
+      } else if (element.msRequestFullscreen) {
+        element.msRequestFullscreen();
+      } else if (element.mozRequestFullScreen) {
+        element.mozRequestFullScreen();
+      } else if (element.webkitRequestFullscreen) {
+        element.webkitRequestFullscreen();
+      }
+    },
+    exitFullscreen() {
+      this.isFull = false;
+      if (document.exitFullscreen) {
+        document.exitFullscreen();
+      } else if (document.msExitFullscreen) {
+        document.msExitFullscreen();
+      } else if (document.mozCancelFullScreen) {
+        document.mozCancelFullScreen();
+      } else if (document.webkitExitFullscreen) {
+        document.webkitExitFullscreen();
+      }
+    },
+    changeIsFull() {
+      this.isFull = false;
+    },
   },
   //生命周期 - 创建完成(可以访问当前this实例)
   created() {},

+ 66 - 4
src/views/bookShelf/components/LexicalType.vue

@@ -61,7 +61,7 @@
                 ref="audioLine"
                 :mp3Source="'mp3'"
             />
-            <svg-icon icon-class="icon-wrapper" class="wrapper"></svg-icon>
+            <svg-icon icon-class="icon-wrapper" class="wrapper" @click="fullScreen"></svg-icon>
         </div>
     </div>
     <template v-if="resArr.length > 0">
@@ -168,16 +168,29 @@
             <svg-icon icon-class="brush-line"></svg-icon>
         </div>
     </div>
+    <div class="voice-full-screen" :id="'screen-' + mathNum">
+      <Voicefullscreen
+        v-if="isFull"
+        :curQue="articleInfo"
+        :sentIndex="0"
+        :mp3="articleInfo.art_sound_url"
+        :likeSentencelist="likeSentencelist"
+        @exitFullscreen="exitFullscreen"
+        @changeIsFull="changeIsFull"
+      />
+    </div>
   </div>
 </template>
 
 <script>
 import AudioLine from "@/components/common/AudioLine.vue"
+import Voicefullscreen from './Voicefullscreen.vue';
 export default {
   name: "ArticleView",
-  props: [ "titleFontsize", "wordFontsize", "colorObj","articleType","articleInfo"],
+  props: [ "titleFontsize", "wordFontsize", "colorObj","articleType","articleInfo","likeSentencelist"],
   components: {
     AudioLine,
+    Voicefullscreen
   },
   data() {
     return {
@@ -358,7 +371,9 @@ export default {
       sentLenDistributeItems: [],
       vocabVlLevelItems: [],
       selectWordType: [],
-      hideSelectWord: false
+      hideSelectWord: false,
+      isFull: false,
+      mathNum: Math.random().toString(36).substr(2),
     };
   },
   computed: {
@@ -450,7 +465,54 @@ export default {
             this.selectSentenceType = []
         }
         this.$forceUpdate()
-    }
+    },
+    pauseAudio() {
+      let audio = document.getElementsByTagName("audio");
+      audio.forEach((item) => {
+        item.pause();
+      });
+    },
+    pauseVideo() {
+      let video = document.getElementsByTagName("video");
+      video.forEach((item) => {
+        item.pause();
+      });
+    },
+    //语音全屏
+    fullScreen() {
+      this.pauseAudio();
+      this.pauseVideo();
+      this.isFull = true;
+      this.goFullscreen();
+    },
+    goFullscreen() {
+      let id = "screen-" + this.mathNum;
+      var element = document.getElementById(id);
+      if (element.requestFullscreen) {
+        element.requestFullscreen();
+      } else if (element.msRequestFullscreen) {
+        element.msRequestFullscreen();
+      } else if (element.mozRequestFullScreen) {
+        element.mozRequestFullScreen();
+      } else if (element.webkitRequestFullscreen) {
+        element.webkitRequestFullscreen();
+      }
+    },
+    exitFullscreen() {
+      this.isFull = false;
+      if (document.exitFullscreen) {
+        document.exitFullscreen();
+      } else if (document.msExitFullscreen) {
+        document.msExitFullscreen();
+      } else if (document.mozCancelFullScreen) {
+        document.mozCancelFullScreen();
+      } else if (document.webkitExitFullscreen) {
+        document.webkitExitFullscreen();
+      }
+    },
+    changeIsFull() {
+      this.isFull = false;
+    },
   },
   //生命周期 - 创建完成(可以访问当前this实例)
   created() {},

+ 64 - 2
src/views/bookShelf/components/NormalModel.vue

@@ -76,7 +76,7 @@
                 ref="audioLine"
                 :mp3Source="'mp3'"
             />
-            <svg-icon icon-class="icon-wrapper" class="wrapper"></svg-icon>
+            <svg-icon icon-class="icon-wrapper" class="wrapper" @click="fullScreen"></svg-icon>
         </div>
     </div>
     <template v-if="resArr.length > 0">
@@ -177,16 +177,29 @@
     </template>
 
     <!-- <img src="../../../assets/article-img.png" style="max-width:100%;margin:24px 0;" /> -->
+    <div class="voice-full-screen" :id="'screen-' + mathNum">
+      <Voicefullscreen
+        v-if="isFull"
+        :curQue="articleInfo"
+        :sentIndex="0"
+        :mp3="articleInfo.art_sound_url"
+        :likeSentencelist="likeSentencelist"
+        @exitFullscreen="exitFullscreen"
+        @changeIsFull="changeIsFull"
+      />
+    </div>
   </div>
 </template>
 
 <script>
 import AudioLine from "@/components/common/AudioLine.vue"
+import Voicefullscreen from './Voicefullscreen.vue';
 export default {
   name: "ArticleView",
-  props: [ "titleFontsize", "wordFontsize", "colorObj","articleType","articleInfo"],
+  props: [ "titleFontsize", "wordFontsize", "colorObj","articleType","articleInfo","likeSentencelist"],
   components: {
     AudioLine,
+    Voicefullscreen
   },
   data() {
     return {
@@ -234,6 +247,8 @@ export default {
       articleImg: {}, // 文章图片
       paraIndex: -1, //段落索引
       sentIndex: -1, // 句子索引
+      isFull: false,
+      mathNum: Math.random().toString(36).substr(2),
     };
   },
   computed: {
@@ -295,6 +310,53 @@ export default {
       this.paraIndex = -1;
       this.sentIndex = -1;
     },
+    pauseAudio() {
+      let audio = document.getElementsByTagName("audio");
+      audio.forEach((item) => {
+        item.pause();
+      });
+    },
+    pauseVideo() {
+      let video = document.getElementsByTagName("video");
+      video.forEach((item) => {
+        item.pause();
+      });
+    },
+    //语音全屏
+    fullScreen() {
+      this.pauseAudio();
+      this.pauseVideo();
+      this.isFull = true;
+      this.goFullscreen();
+    },
+    goFullscreen() {
+      let id = "screen-" + this.mathNum;
+      var element = document.getElementById(id);
+      if (element.requestFullscreen) {
+        element.requestFullscreen();
+      } else if (element.msRequestFullscreen) {
+        element.msRequestFullscreen();
+      } else if (element.mozRequestFullScreen) {
+        element.mozRequestFullScreen();
+      } else if (element.webkitRequestFullscreen) {
+        element.webkitRequestFullscreen();
+      }
+    },
+    exitFullscreen() {
+      this.isFull = false;
+      if (document.exitFullscreen) {
+        document.exitFullscreen();
+      } else if (document.msExitFullscreen) {
+        document.msExitFullscreen();
+      } else if (document.mozCancelFullScreen) {
+        document.mozCancelFullScreen();
+      } else if (document.webkitExitFullscreen) {
+        document.webkitExitFullscreen();
+      }
+    },
+    changeIsFull() {
+      this.isFull = false;
+    },
   },
   //生命周期 - 创建完成(可以访问当前this实例)
   created() {},

+ 71 - 7
src/views/bookShelf/components/NotesModel.vue

@@ -1,7 +1,7 @@
 <!--  -->
 <template>
   <div id="notes-model">
-    <div class="NNPE-ArticleView" v-if="articleInfo">
+    <div class="NNPE-ArticleView" v-if="resArr">
         <template v-if="resArr[0]">
             <h2>
                 <span :style="{color:colorObj.titleColor,fontSize:(wordFontsize+30)+'px',lineHeight:(wordFontsize+38)+'px',marginRight:'10px',fontWeight:'700',cursor:'pointer'}">
@@ -30,7 +30,7 @@
                     ref="audioLine"
                     :mp3Source="'mp3'"
                 />
-                <svg-icon icon-class="icon-wrapper" class="wrapper"></svg-icon>
+                <svg-icon icon-class="icon-wrapper" class="wrapper" @click="fullScreen"></svg-icon>
             </div>
         </div>
         <template v-if="resArr.length > 0">
@@ -55,6 +55,7 @@
         :close-on-click-modal="false"
         width="367px"
         class="notes-dialog"
+        @close="handleData"
         v-if="notesFlag">
         <p>{{notesObj.title}}</p>
         <el-input
@@ -66,22 +67,35 @@
             v-model="notesObj.notes">
         </el-input>
         <div class="btn-box">
-            <el-button type="danger" plain size="small" @click="deleteNotes">删除</el-button>
+            <el-button type="danger" plain size="small" @click="deleteNotes" v-if="notesObj.id">删除</el-button>
             <el-button type="primary" @click="handleSave" size="small" :loading="loading">保存</el-button>
         </div>
     </el-dialog>
+    <div class="voice-full-screen" :id="'screen-' + mathNum">
+      <Voicefullscreen
+        v-if="isFull"
+        :curQue="articleInfo"
+        :sentIndex="0"
+        :mp3="articleInfo.art_sound_url"
+        :likeSentencelist="likeSentencelist"
+        @exitFullscreen="exitFullscreen"
+        @changeIsFull="changeIsFull"
+      />
+    </div>
   </div>
 </template>
 
 <script>
 import AudioLine from "@/components/common/AudioLine.vue"
+import Voicefullscreen from './Voicefullscreen.vue';
 import Highlighter from 'web-highlighter';
 import { getLogin } from "@/api/ajax";
 export default {
   name: "ArticleView",
-  props: [ "titleFontsize", "wordFontsize", "colorObj","articleType","articleInfo"],
+  props: [ "titleFontsize", "wordFontsize", "colorObj","articleType","articleInfo","likeSentencelist"],
   components: {
     AudioLine,
+    Voicefullscreen
   },
   data() {
     return {
@@ -140,7 +154,9 @@ export default {
       },
       activeSentObj: null, // 点击的句子
       loading: false,
-      highDataList: []
+      highDataList: [],
+      isFull: false,
+      mathNum: Math.random().toString(36).substr(2),
     };
   },
   computed: {
@@ -193,6 +209,7 @@ export default {
                 $root: document.getElementById("notes-model"),
                 exceptSelectors: ['pre', 'code']
             });
+            _this.highlighter.dispose()
             _this.highlighter
                 .on('selection:hover', ({id}) => {
                     // 通过添加 class,实现类似 hover 效果
@@ -221,7 +238,7 @@ export default {
                     // store.save(sources);
                 });
             _this.highlighter.run()
-        }, 1000);
+        }, 100);
     },
     // 高亮笔记句子
     async handleHighSentence(){
@@ -317,7 +334,54 @@ export default {
                 }
             })
         });
-    }
+    },
+    pauseAudio() {
+      let audio = document.getElementsByTagName("audio");
+      audio.forEach((item) => {
+        item.pause();
+      });
+    },
+    pauseVideo() {
+      let video = document.getElementsByTagName("video");
+      video.forEach((item) => {
+        item.pause();
+      });
+    },
+    //语音全屏
+    fullScreen() {
+      this.pauseAudio();
+      this.pauseVideo();
+      this.isFull = true;
+      this.goFullscreen();
+    },
+    goFullscreen() {
+      let id = "screen-" + this.mathNum;
+      var element = document.getElementById(id);
+      if (element.requestFullscreen) {
+        element.requestFullscreen();
+      } else if (element.msRequestFullscreen) {
+        element.msRequestFullscreen();
+      } else if (element.mozRequestFullScreen) {
+        element.mozRequestFullScreen();
+      } else if (element.webkitRequestFullscreen) {
+        element.webkitRequestFullscreen();
+      }
+    },
+    exitFullscreen() {
+      this.isFull = false;
+      if (document.exitFullscreen) {
+        document.exitFullscreen();
+      } else if (document.msExitFullscreen) {
+        document.msExitFullscreen();
+      } else if (document.mozCancelFullScreen) {
+        document.mozCancelFullScreen();
+      } else if (document.webkitExitFullscreen) {
+        document.webkitExitFullscreen();
+      }
+    },
+    changeIsFull() {
+      this.isFull = false;
+    },
   },
   //生命周期 - 创建完成(可以访问当前this实例)
   created() {},

+ 66 - 4
src/views/bookShelf/components/PhraseModel.vue

@@ -62,7 +62,7 @@
                 ref="audioLine"
                 :mp3Source="'mp3'"
             />
-            <svg-icon icon-class="icon-wrapper" class="wrapper"></svg-icon>
+            <svg-icon icon-class="icon-wrapper" class="wrapper" @click="fullScreen"></svg-icon>
         </div>
     </div>
     <template v-if="resArr.length > 0">
@@ -152,6 +152,17 @@
         v-if="showWordFlag">
         <WordCard @closeWord="closeExplain" :dataObj="showObj" @changeLike="changeLike" :likePhrase="likeWord"/>
     </el-dialog>
+    <div class="voice-full-screen" :id="'screen-' + mathNum">
+      <Voicefullscreen
+        v-if="isFull"
+        :curQue="articleInfo"
+        :sentIndex="0"
+        :mp3="articleInfo.art_sound_url"
+        :likeSentencelist="likeSentencelist"
+        @exitFullscreen="exitFullscreen"
+        @changeIsFull="changeIsFull"
+      />
+    </div>
   </div>
 </template>
 
@@ -159,13 +170,15 @@
 import AudioLine from "@/components/common/AudioLine.vue"
 import PhraseCard from "./PhraseCard.vue"
 import WordCard from "../../personalCenter/components/WordCard.vue"
+import Voicefullscreen from './Voicefullscreen.vue';
 export default {
   name: "ArticleView",
-  props: [ "titleFontsize", "wordFontsize", "colorObj","articleType","articleInfo","likePhraseList","likeWord"],
+  props: [ "titleFontsize", "wordFontsize", "colorObj","articleType","articleInfo","likePhraseList","likeWord","likeSentencelist"],
   components: {
     AudioLine,
     PhraseCard,
-    WordCard
+    WordCard,
+    Voicefullscreen
   },
   data() {
     return {
@@ -222,6 +235,8 @@ export default {
       showWordFlag: false,
       showPhraseFlag: false,
       showExplainFlag: false,
+      isFull: false,
+      mathNum: Math.random().toString(36).substr(2),
     };
   },
   computed: {
@@ -427,7 +442,54 @@ export default {
     },
     changeLike(obj,list){
         this.$emit('changeLike',obj,list)
-    }
+    },
+    pauseAudio() {
+      let audio = document.getElementsByTagName("audio");
+      audio.forEach((item) => {
+        item.pause();
+      });
+    },
+    pauseVideo() {
+      let video = document.getElementsByTagName("video");
+      video.forEach((item) => {
+        item.pause();
+      });
+    },
+    //语音全屏
+    fullScreen() {
+      this.pauseAudio();
+      this.pauseVideo();
+      this.isFull = true;
+      this.goFullscreen();
+    },
+    goFullscreen() {
+      let id = "screen-" + this.mathNum;
+      var element = document.getElementById(id);
+      if (element.requestFullscreen) {
+        element.requestFullscreen();
+      } else if (element.msRequestFullscreen) {
+        element.msRequestFullscreen();
+      } else if (element.mozRequestFullScreen) {
+        element.mozRequestFullScreen();
+      } else if (element.webkitRequestFullscreen) {
+        element.webkitRequestFullscreen();
+      }
+    },
+    exitFullscreen() {
+      this.isFull = false;
+      if (document.exitFullscreen) {
+        document.exitFullscreen();
+      } else if (document.msExitFullscreen) {
+        document.msExitFullscreen();
+      } else if (document.mozCancelFullScreen) {
+        document.mozCancelFullScreen();
+      } else if (document.webkitExitFullscreen) {
+        document.webkitExitFullscreen();
+      }
+    },
+    changeIsFull() {
+      this.isFull = false;
+    },
   },
   //生命周期 - 创建完成(可以访问当前this实例)
   created() {},

+ 66 - 6
src/views/bookShelf/components/PracticeModel.vue

@@ -51,7 +51,7 @@
                 :showEd="showEd"
                 @emptyEd="emptyEd"
             />
-            <svg-icon icon-class="icon-wrapper" class="wrapper"></svg-icon>
+            <svg-icon icon-class="icon-wrapper" class="wrapper" @click="fullScreen"></svg-icon>
         </div>
     </div>
     <template v-if="resArr.wordsList&&resArr.wordsList.length > 0">
@@ -232,7 +232,17 @@
         v-if="historyFlag">
         <history-record-list :list="historySentRecordList" :sentData="resArr.wordsList[playSentIndex]" :timeData="resArr.timeList[playSentIndex]" :mp3Url="articleInfo.art_sound_url" @closeHistory="closeHistory" :colorObj="colorObj" :wordFontsize="wordFontsize" @handleChangeTime="handleChangeTime" @returnCurrentTime="returnCurrentTime" :parentCurtimt="curTime" :parentPlay="Playing" v-loading="historyLoading"></history-record-list>
     </el-dialog>
-
+    <div class="voice-full-screen" :id="'screen-' + mathNum">
+      <Voicefullscreen
+        v-if="isFull"
+        :curQue="articleInfo"
+        :sentIndex="playSentIndex===-1?0:playSentIndex"
+        :mp3="articleInfo.art_sound_url"
+        :likeSentencelist="likeSentencelist"
+        @exitFullscreen="exitFullscreen"
+        @changeIsFull="changeIsFull"
+      />
+    </div>
   </div>
 </template>
 
@@ -241,13 +251,14 @@ import AudioLine from "@/components/common/AudioLine.vue"
 import HistoryRecordList from "./HistoryRecordList.vue"
 import Recorder from "js-audio-recorder"; // 录音插件
 import { getLogin } from "@/api/ajax";
-
+import Voicefullscreen from './Voicefullscreen.vue';
 export default {
   name: "ArticleView",
-  props: [ "titleFontsize", "wordFontsize", "colorObj","articleType","articleInfo"],
+  props: [ "titleFontsize", "wordFontsize", "colorObj","articleType","articleInfo","likeSentencelist"],
   components: {
     AudioLine,
-    HistoryRecordList
+    HistoryRecordList,
+    Voicefullscreen
   },
   data() {
     return {
@@ -323,7 +334,9 @@ export default {
       showEd: false, //是否看ed的值
       historyLoading: false,
       timeC: null,
-      isCompare: false
+      isCompare: false,
+      isFull: false,
+      mathNum: Math.random().toString(36).substr(2),
     };
   },
   computed: {
@@ -715,6 +728,53 @@ export default {
             _this.isCompare = false
         });
     },
+    pauseAudio() {
+      let audio = document.getElementsByTagName("audio");
+      audio.forEach((item) => {
+        item.pause();
+      });
+    },
+    pauseVideo() {
+      let video = document.getElementsByTagName("video");
+      video.forEach((item) => {
+        item.pause();
+      });
+    },
+    //语音全屏
+    fullScreen() {
+      this.pauseAudio();
+      this.pauseVideo();
+      this.isFull = true;
+      this.goFullscreen();
+    },
+    goFullscreen() {
+      let id = "screen-" + this.mathNum;
+      var element = document.getElementById(id);
+      if (element.requestFullscreen) {
+        element.requestFullscreen();
+      } else if (element.msRequestFullscreen) {
+        element.msRequestFullscreen();
+      } else if (element.mozRequestFullScreen) {
+        element.mozRequestFullScreen();
+      } else if (element.webkitRequestFullscreen) {
+        element.webkitRequestFullscreen();
+      }
+    },
+    exitFullscreen() {
+      this.isFull = false;
+      if (document.exitFullscreen) {
+        document.exitFullscreen();
+      } else if (document.msExitFullscreen) {
+        document.msExitFullscreen();
+      } else if (document.mozCancelFullScreen) {
+        document.mozCancelFullScreen();
+      } else if (document.webkitExitFullscreen) {
+        document.webkitExitFullscreen();
+      }
+    },
+    changeIsFull() {
+      this.isFull = false;
+    },
   },
   //生命周期 - 创建完成(可以访问当前this实例)
   created() {},

+ 1591 - 0
src/views/bookShelf/components/Voicefullscreen.vue

@@ -0,0 +1,1591 @@
+<!--  -->
+<template>
+  <div :class="['voicefull', bgIndex == 0 ? 'bg1' : 'bg2']" v-if="item">
+    <div
+      class="voicefull-top"
+      @mouseover="setTopShow(true)"
+      @mouseleave="setTopShow(false)"
+    >
+      <div :class="[isTopShow ? 'voicefull-top-show' : 'voicefull-top-hidden']">
+        <div class="top-left">
+          <div :class="['select-bg', bgIndex == 1 ? 'select-bg-blue' : '']">
+            <div :class="['bg-green-box', bgIndex == 1 ? 'active' : '']">
+              <span
+                :class="['bg-green', bgIndex == 1 ? 'active' : '']"
+                @click="changeBg(1)"
+              ></span>
+            </div>
+            <div :class="['bg-white-box', bgIndex == 0 ? 'active' : '']">
+              <span
+                :class="['bg-white', bgIndex == 0 ? 'active' : '']"
+                @click="changeBg(0)"
+              ></span>
+            </div>
+          </div>
+          <div
+            :class="['set-fontSize', bgIndex == 1 ? 'set-fontSize-green' : '']"
+          >
+            <template v-if="hzSize >= 34">
+              <span
+                :class="[
+                  'font-jian-black',
+                  bgIndex == 1 ? 'font-jian-yellow' : '',
+                ]"
+                @click="setFontSize('-')"
+              >
+                <i class="el-icon-minus"></i>
+              </span>
+            </template>
+            <!-- <template v-else>
+              <span
+                :class="[
+                  'font-jian-black',
+                  bgIndex == 1
+                    ? 'font-jian-yellow-disabled'
+                    : 'font-jian-white-disabled',
+                ]"
+              >
+                <i class="el-icon-plus"></i>
+              </span>
+            </template> -->
+            <span
+              :class="['font-img-black', bgIndex == 1 ? 'font-img-yellow' : '']"
+            ></span>
+            <template v-if="hzSize <= 76">
+              <span
+                :class="[
+                  'font-jia-black',
+                  bgIndex == 1 ? 'font-jia-yellow' : '',
+                ]"
+                @click="setFontSize('+')"
+              >
+                <i class="el-icon-plus"></i>
+              </span>
+            </template>
+            <!-- <template v-else>
+              <span
+                :class="[
+                  'font-jia-black',
+                  bgIndex == 1
+                    ? 'font-jia-yellow-disabled'
+                    : 'font-jia-white-disabled',
+                ]"
+              ></span>
+            </template> -->
+          </div>
+        </div>
+        <div class="top-middle">
+          <template v-if="mp3">
+            <AudioLineSentence
+              :key="'sent' + curSentIndex"
+              :mp3="mp3"
+              :getCurTime="getCurTime"
+              ref="audioLineSent"
+              :audioId="'artPraAudioId' + curSentIndex"
+              :stopAudio="stopAudio"
+              :width="120"
+              :hideSlider="true"
+              :bg="bg"
+              :ed="ed"
+              :curTime="curTime"
+              :maxTime="maxTime"
+              :bgIndex="bgIndex"
+              :isRepeat="isRepeat"
+              :isAuto="isAuto"
+              @playChange="playChange"
+              @rollSentence="rollSentence"
+            />
+          </template>
+          <div
+            :class="['op-btn', bgIndex == 1 ? 'op-btn-green' : '']"
+            @click="setStatus"
+          >
+            <span
+              :class="[
+                'repeat-icon',
+                !isRepeat && !isAuto ? 'disabled' : '',
+                !isRepeat && isAuto ? 'auto-icon' : '',
+                isRepeat && bgIndex == 1 ? 'repeat-icon-yellow' : '',
+                !isRepeat && isAuto && bgIndex == 1 ? 'auto-icon-yellow' : '',
+              ]"
+            >
+            <svg-icon icon-class="repeat"></svg-icon>
+            </span>
+          </div>
+          <div
+            :class="['op-btn', bgIndex == 1 ? 'op-btn-green' : '']"
+            @click="handleColl"
+            title="点击收藏后可在“个人中心”-“我的收藏”查看"
+          >
+            <span
+              :class="[
+                'coll-icon',
+                !isCollArr[curSentIndex] ? 'disabled' : '',
+                isCollArr[curSentIndex] && bgIndex == 1
+                  ? 'coll-icon-yellow'
+                  : '',
+              ]"
+            >
+                <svg-icon icon-class="like-line" className="icon-like"></svg-icon>
+            </span>
+          </div>
+        </div>
+        <div
+          :class="['op-btn', bgIndex == 1 ? 'op-btn-green' : '']"
+          @click="exitFullScreen"
+        >
+          <span
+            :class="['close-icon', bgIndex == 1 ? 'close-icon-white' : '']"
+          >
+            <i class="el-icon-close"></i>
+          </span>
+        </div>
+      </div>
+    </div>
+    <div class="voicefull-content" v-if="item">
+      <div
+        class="vc-box"
+        @mousemove="showPrevNext(true, 'isShowLeft')"
+        @mouseleave="showPrevNext(false, 'isShowLeft')"
+      >
+        <div
+          :class="[
+            'vc-left vc-left-grey',
+            isShowLeft && bgIndex == 0 ? 'vc-left-black' : '',
+            isShowLeft && bgIndex == 1 ? 'vc-left-white' : '',
+            curSentIndex == 0 ? 'hidden' : '',
+          ]"
+          @click="prevSentence"
+        ></div>
+      </div>
+      <div class="vc-main">
+        <div class="item-sent">
+          <div style="clear: both; overflow: hidden"></div>
+          <div
+            class="nnpe-sentence-box"
+            v-for="(pItem, pIndex) in item"
+            :key="'wordsList' + pIndex"
+            @dblclick="showWordDetail($event, pItem)"
+            @click="playWord(pItem,pIndex)"
+          >
+            <template v-if="pItem.isShow">
+                <div
+                    :class="[
+                    'NNPE-words',
+                    ]"
+                >
+                    <span
+                        class="NNPE-chs"
+                        :class="[
+                            resArr.timeList[curSentIndex] &&
+                            resArr.timeList[curSentIndex] &&
+                            resArr.timeList[curSentIndex].e &&
+                            resArr.timeList[curSentIndex].tokens &&
+                            resArr.timeList[curSentIndex].tokens[pItem.wIndex]&&
+                            curTime >=
+                                resArr.timeList[curSentIndex].tokens[pItem.wIndex].s &&
+                            curTime <= resArr.timeList[curSentIndex].e
+                                ? 'wordActive'
+                                : '',
+                            pItem.tokens[9]===''?'marginRight':'',pItem.marginRight?'marginSingleRight':''
+                        ]"
+                        :style="{fontSize:hzSize + 'px'}"
+                        >{{ pItem.tokens[2] }}</span
+                    >
+                    <span
+                    class="NNPE-chs NNPE-chs-both"
+                    v-if="item[pIndex + 1] &&
+                    item[pIndex + 1].tokens[2] &&
+                    enFhList.indexOf(item[pIndex + 1].tokens[2]) > -1"
+                    :class="[
+                            resArr.timeList[curSentIndex] &&
+                            resArr.timeList[curSentIndex] &&
+                            resArr.timeList[curSentIndex].tokens[pItem.wIndex]&&
+                            curTime >=
+                                resArr.timeList[curSentIndex].tokens[pItem.wIndex].s &&
+                            curTime <= resArr.timeList[curSentIndex].e
+                                ? 'wordActive'
+                                : '',
+                            item[pIndex + 1].tokens[8]===''?'marginLeft':'',item[pIndex + 1].marginRight?'marginSingleRight':''
+                        ]"
+                        :style="{fontSize:hzSize + 'px'}"
+                    >{{ item[pIndex + 1].tokens[2] }}</span
+                    >
+                </div>
+            </template>
+          </div>
+        </div>
+        <div style="clear: both; overflow: hidden"></div>
+      </div>
+    </div>
+    <div
+      class="voicefull-bottom"
+      @mouseover="setBottomShow(true)"
+      @mouseleave="setBottomShow(false)"
+    >
+      <div
+        :class="[
+          isBottomShow ? 'voicefull-bottom-show' : 'voicefull-bottom-hidden',
+        ]"
+      >
+        <div
+          :class="[
+            'bottom-left',
+          ]"
+        >Soundrecorddiff
+          <!-- <Soundrecorddiff
+            ref="Soundrecorddiff"
+            @handleWav="handleWav"
+            @getWavblob="getWavblob"
+            @handleParentPlay="handleParentPlay"
+            @sentPause="sentPause"
+            @getRerordStatus="getRerordStatus"
+            @getMicrophoneStatus="getMicrophoneStatus"
+            @getPlayStatus="getPlayStatus"
+            :bgIndex="bgIndex"
+            :TaskModel="TaskModel"
+            :answerRecordList="
+              curQue.Bookanswer.practiceModel[curSentIndex] &&
+              curQue.Bookanswer.practiceModel[curSentIndex].recordList
+            "
+            :tmIndex="curSentIndex"
+            :key="'Soundrecorddiff' + curSentIndex"
+          /> -->
+          <div
+            :class="['compare-box', bgIndex == 1 ? 'compare-box-white' : '']"
+            v-if="isShowCompare"
+          >
+          Audio-compare
+            <!-- <Audio-compare
+              :bgIndex="bgIndex"
+              type="full"
+              :themeColor="themeColor"
+              :index="curSentIndex"
+              :sentIndex="curSentIndex"
+              :url="curQue.mp3_list[0].id"
+              :bg="bg"
+              :ed="ed"
+              :wavblob="wavblob"
+              :getCurTime="getCurCompareTime"
+              :sentPause="sentPause"
+              :isRecord="isRecord"
+              :handleChangeStopAudio="handleChangeStopAudio"
+              :getPlayStatus="getPlayStatus"
+              :key="'mp3Compare' + curSentIndex"
+            /> -->
+          </div>
+        </div>
+        <div
+          :class="[
+            'page-count',
+            bgIndex == 0 ? 'page-count-white' : 'page-count-green',
+          ]"
+        >
+          {{ curSentIndex + 1 }}/{{ this.resArr.wordsList.length }}
+        </div>
+      </div>
+    </div>
+
+    <template v-if="isShow">
+      <div
+        ref="wordcard"
+        class="NNPE-wordDetail"
+        :style="{ left: left + 'px' }"
+      >Wordcard
+        <!-- <Wordcard
+          :word="word"
+          :changeWordCard="changeWordCard"
+          :themeColor="themeColor"
+          :currentTreeID="currentTreeID"
+        /> -->
+      </div>
+    </template>
+    <div class="word-play-audio" v-if="isWordPlay">
+      <AudioLineSentence
+        :mp3="mp3"
+        :getCurTime="getCurWordTime"
+        ref="audioLineWord"
+        :audioId="'artPraAudioId' + curSentIndex + wordIndex"
+        :stopAudio="stopAudio"
+        :width="120"
+        :hideSlider="false"
+        :bg="wordbg"
+        :ed="worded"
+        :maxTime="wordMaxTime"
+        :bgIndex="bgIndex"
+        :isRepeat="isRepeat"
+        :wordPlay="true"
+        @changePlayStatus="changePlayStatus"
+      />
+    </div>
+  </div>
+</template>
+
+<script>
+import AudioLineSentence from "../../../components/common/AudioLineSentence.vue";
+// import Soundrecorddiff from "./Soundrecorddiff.vue";
+// import AudioCompare from "./AudioCompare.vue";
+// import Wordcard from "./components/Wordcard.vue";
+import { getLogin } from "@/api/ajax";
+export default {
+  components: {
+    AudioLineSentence,
+    // Soundrecorddiff,
+    // AudioCompare,
+    // Wordcard,
+  },
+  props: [
+    "sentIndex",
+    "mp3",
+    "curQue",
+    "likeSentencelist"
+  ],
+  data() {
+    return {
+      pySize: 32,
+      hzSize: 48,
+      enSize: 24,
+      bgIndex: 1,
+      maxTime: 0,
+      item: null,
+      bg: 0,
+      ed: 0,
+      isRepeat: false,
+      curTime: 0,
+      wavblob: null,
+      stopAudio: false,
+      isRecord: false,
+      isShowCompare: false,
+      isShowRight: false,
+      isShowLeft: false,
+      curSentIndex: 0,
+      oldHz: "",
+      hz: "",
+      clientY: 0,
+      top: 0,
+      left: 0,
+      newWordList: [],
+      pinyin: "",
+      wordIndex: -1,
+      isShow: false,
+      wordbg: 0,
+      worded: 0,
+      wordMaxTime: 0,
+      isWordPlay: false,
+      curWordTime: 0,
+      isPlaying: false,
+      isAuto: false,
+      key: "isRepeat",
+      isKeyboard: true,
+      isTopShow: false,
+      isBottomShow: false,
+      isRecording: false,
+      recordPlaying: false,
+      isCollArr: [],
+      enwords: "",
+      screenHeight: 0,
+      resArr: [],
+      historySentRecordList: [], // 单句历史录音list
+      enFhList: [
+        ",",
+        ".",
+        ";",
+        "?",
+        "!",
+        ":",
+        ">",
+        "<",
+        "'",
+        "’",
+        "n't",
+        "n’t",
+        "n’ts",
+        "n‘t",
+        "'t",
+        "’t",
+        "‘t",
+        "'s",
+        "’s",
+        "‘s",
+        "'m",
+        "’m",
+        "‘m",
+        "'re",
+        "’re",
+        "‘re",
+        "'d",
+        "’d",
+        "‘d",
+        "'ve",
+        "’ve",
+        "‘ve",
+        ")",
+        "'ll",
+        "’ll",
+        "‘ll",
+        "”",
+      ],
+    };
+  },
+  computed: {
+    // isPlaying: function () {
+    //   let playing = false;
+    //   if (this.$refs.audioLineSent) {
+    //     playing = this.$refs.audioLineSent.audio.isPlaying;
+    //   }
+    //   console.log(playing);
+    //   return playing;
+    // },
+  },
+  watch: {
+    isRecording: {
+      handler: function (newVal, oldVal) {
+        if (newVal) {
+          this.isBottomShow = newVal;
+        }
+      },
+      deep: true,
+    },
+    recordPlaying: {
+      handler: function (newVal, oldVal) {
+        if (newVal) {
+          this.isBottomShow = newVal;
+        }
+      },
+      deep: true,
+    },
+    sentIndex: {
+      handler: function (newVal, oldVal) {
+        this.curSentIndex = newVal;
+        this.getSentence();
+      },
+      deep: true,
+    },
+    hz: {
+      handler: function (val, oldVal) {
+        let _this = this;
+        if (val) {
+          _this.handleNewWords(val);
+        }
+      },
+      // 深度观察监听
+      deep: true,
+    },
+    isShow: {
+      handler: function (val, oldVal) {
+        let _this = this;
+        if (val) {
+          setTimeout(() => {
+            _this.cardHeight = _this.$refs.wordcard.offsetHeight;
+            if (_this.screenHeight - _this.clientY > _this.cardHeight) {
+              _this.top = _this.clientY + 20;
+            } else {
+              _this.top = _this.clientY - _this.cardHeight - 30;
+            }
+          }, 50);
+        }
+      },
+      // 深度观察监听
+      deep: true,
+    },
+  },
+  //方法集合
+  methods: {
+    setTopShow(bool) {
+      this.isTopShow = bool;
+    },
+    setBottomShow(bool) {
+      if (!this.recordPlaying && !this.isRecording) {
+        this.isBottomShow = bool;
+      }
+    },
+    getPlayStatus(bool) {
+      this.recordPlaying = bool;
+    },
+    setFontSize(type) {
+      let _this = this;
+      if (type == "-") {
+        if (_this.hzSize >= 34) {
+          this.hzSize = this.hzSize - 4;
+        }
+      }
+      if (type == "+") {
+        if (_this.hzSize <= 76) {
+          this.hzSize = this.hzSize + 4;
+        }
+      }
+      _this.pySize = parseInt(_this.hzSize / 1.5);
+    },
+    playChange(bool) {
+      this.isPlaying = bool;
+    },
+    handleColl() {
+      let _this = this;
+      if (_this.isCollArr[_this.curSentIndex]) {
+        _this.cancleColl();
+      } else {
+        _this.addColl();
+      }
+    },
+    //添加收藏
+    addColl() {
+        let MethodName = "/ShopServer/Client/CollectManager/AddCollect_Sentence";
+        let data = {
+            sentence_id: this.curQue.art_corpus_data.sentList[this.curSentIndex].id,
+            audio_file_id: this.curQue.art_sound_srt_data.mp3,
+            audio_begin_time: this.curQue.art_sound_srt_data?this.articleInfo.art_sound_srt_data.sents[this.curSentIndex].s:null,
+            audio_end_time: this.curQue.art_sound_srt_data?this.articleInfo.art_sound_srt_data.sents[this.curSentIndex].e:null
+        };
+        getLogin(MethodName, data).then((res) => {
+            this.$set(this.isCollArr, this.curSentIndex, true);
+            this.$message.success("收藏成功!");
+        });
+    },
+    //取消收藏
+    cancleColl() {
+      let MethodName = "/ShopServer/Client/CollectManager/CancelCollect_Sentence";
+      let data = {
+        sentence_id: this.curQue.art_corpus_data.sentList[this.curSentIndex].id
+      };
+      getLogin(MethodName, data).then((res) => {
+        this.$set(this.isCollArr, this.curSentIndex, false);
+        this.$message.success("取消成功!");
+      });
+    },
+    //检查收藏状态
+    checkCollStatus() {
+        let collFlag = this.likeSentencelist&&this.likeSentencelist.length>0&&this.likeSentencelist.indexOf(this.curQue.art_corpus_data.sentList[this.curSentIndex].id)>-1 ? true : false;
+        this.$set(this.isCollArr, this.curSentIndex, collFlag);
+    },
+    showPrevNext(bool, key) {
+      this[key] = bool;
+    },
+    prevSentence() {
+      let _this = this;
+      if (_this.curSentIndex == 0) {
+        _this.$message.warning("已经是第一个句子了");
+        return;
+      }
+      _this.curSentIndex = _this.curSentIndex - 1;
+      _this.getSentence();
+      if (_this.isAuto) {
+        _this.curTime = _this.bg;
+        _this.$refs.audioLineSent.onTimeupdateTime(_this.bg / 1000);
+      }
+    },
+    nextSentence() {
+      if (this.curSentIndex == this.resArr.wordsList.length - 1) {
+        this.$message.warning("已经是最后一个句子了");
+        return;
+      }
+      this.curSentIndex = this.curSentIndex + 1;
+      this.getSentence();
+    },
+    rollSentence() {
+      if (this.curSentIndex == this.resArr.wordsList.length - 1) {
+        this.curSentIndex = 0;
+      } else {
+        this.curSentIndex = this.curSentIndex + 1;
+      }
+      this.getSentence();
+    },
+    changeStatus(key) {
+      this[key] = !this[key];
+    },
+    changePinyin() {
+      this.$emit("changePinyin");
+    },
+    changeEN() {
+      this.$emit("changeEN");
+    },
+    setStatus() {
+      let _this = this;
+      if (_this.key == "isRepeat") {
+        if (_this.isRepeat) {
+          _this.isRepeat = false;
+          _this.isAuto = true;
+          _this.key = "isAuto";
+        } else {
+          _this.isRepeat = true;
+          _this.key = "isRepeat";
+        }
+      } else if (_this.key == "isAuto") {
+        if (_this.isAuto) {
+          _this.isRepeat = false;
+          _this.isAuto = false;
+          _this.key = "isRepeat";
+        }
+      }
+    },
+    getRerordStatus(bool) {
+      this.isShowCompare = bool;
+    },
+    getMicrophoneStatus(bool) {
+      this.isRecording = bool;
+    },
+    getWavblob(wavblob) {
+      this.wavblob = wavblob;
+    },
+    sentPause(isRecord) {
+      this.isRecord = isRecord;
+    },
+    getCurTime(curTime) {
+      let _this = this;
+      if (_this.isRepeat) {
+        let time = curTime * 1000;
+        if (time > _this.ed || time < _this.bg) {
+          _this.curTime = _this.bg;
+          this.$refs.audioLineSent.onTimeupdateTime(_this.bg / 1000);
+        } else {
+          _this.curTime = curTime * 1000;
+        }
+      } else if (_this.isAuto) {
+        let time = curTime * 1000;
+
+        if (time > _this.ed) {
+          _this.rollSentence();
+          _this.curTime = _this.bg;
+          _this.$refs.audioLineSent.onTimeupdateTime(_this.bg / 1000);
+        } else {
+          _this.curTime = curTime * 1000;
+        }
+      } else {
+        _this.curTime = curTime * 1000;
+      }
+    },
+    getCurCompareTime(curTime) {
+      let _this = this;
+      _this.curTime = curTime * 1000;
+    },
+    getCurWordTime(curTime) {
+      let _this = this;
+      _this.curWordTime = curTime * 1000;
+    },
+    changeBg(bgIndex) {
+      this.bgIndex = bgIndex;
+    },
+    getSentence() {
+        let _this = this;
+        let MethodName = "/PaperServer/Client/UserSentRec/RecListInUserSent";
+        let data = {
+            sent_id: this.curQue.art_corpus_data.sentList[this.curSentIndex].id,
+            got_rec_data_flag: true
+        }
+        getLogin(MethodName, data)
+        .then((res) => {
+            if(res.status===1){
+                this.historySentRecordList = res.data.all
+            }
+        })
+      _this.isShowCompare = _this.historySentRecordList.length > 0;
+      _this.pauseAudio();
+      _this.isPlaying = false;
+      let item = JSON.parse(JSON.stringify(_this.resArr.wordsList[_this.curSentIndex]));
+      console.log(item)
+      _this.item = item
+      _this.resArr.wordsList.forEach((item) => {
+        this.isCollArr.push(false);
+      });
+      _this.bg = _this.resArr.timeList[_this.curSentIndex].s;
+      _this.ed = _this.resArr.timeList[_this.curSentIndex].e;
+      let maxTime = (_this.ed - _this.bg) / 1000;
+      if (maxTime < 1) {
+        _this.maxTime = 1;
+      } else {
+        _this.maxTime = maxTime;
+      }
+      _this.checkCollStatus();
+    },
+    pauseAudio() {
+      let audio = document.getElementsByTagName("audio");
+      if(audio&&audio.length>0&&window.location.href.indexOf('GCLS-Learn')==-1){
+        audio.forEach((item) => {
+            item.pause();
+        });
+      }
+    },
+    exitFullScreen() {
+      this.pauseAudio();
+      this.$emit("exitFullscreen");
+    },
+    changeFullScreen() {
+      this.pauseAudio();
+      this.$emit("changeIsFull");
+    },
+    handleWav(list, tmIndex) {
+      tmIndex = tmIndex ? tmIndex : 0;
+    //   this.$emit("handleWav", list, tmIndex);
+    },
+    // 录音时暂停音频播放
+    handleParentPlay() {
+      this.stopAudio = true;
+    },
+    // 音频播放时改变布尔值
+    handleChangeStopAudio() {
+      this.stopAudio = false;
+    },
+    //播放音频
+    playWord(item,index) {
+      let _this = this;
+      _this.pauseAudio();
+      _this.isWordPlay = false;
+      _this.wordIndex = item.wIndex;
+      setTimeout(() => {
+        let leg = _this.resArr.timeList[_this.curSentIndex].tokens.length;
+        _this.wordbg = _this.resArr.timeList[_this.curSentIndex].s;
+        _this.worded = _this.resArr.timeList[_this.curSentIndex].e;
+        let wordMaxTime = (_this.worded - _this.wordbg) / 1000;
+        if (wordMaxTime < 1) {
+          _this.wordMaxTime = 1;
+        } else {
+          _this.wordMaxTime = wordMaxTime;
+        }
+        _this.isWordPlay = true;
+      }, 50);
+    },
+    changePlayStatus() {
+      this.isWordPlay = false;
+      this.wordIndex = -1;
+    },
+    showWordDetail(e, item) {
+      let _this = this;
+    //   if (_this.TaskModel == "ANSWER") {
+    //     return;
+    //   }
+    //   if (_this.chsFhList.indexOf(item.chs) > -1) {
+    //     return;
+    //   }
+    //   if (_this.oldHz != item.chs) {
+    //     this.isShow = false;
+    //     setTimeout(() => {
+    //       _this.hz = item.chs;
+    //       _this.pinyin = item.pinyin;
+    //       _this.wordIndex = item.wordIndex;
+    //     }, 50);
+    //   }
+    //   _this.clientY = e.clientY;
+
+    //   let left = e.clientX;
+    //   let width = 0;
+    //   if (item.chs.length == 1 || item.chs.length == 2) {
+    //     width = 304;
+    //   } else if (item.chs.length == 3 || item.chs.length == 4) {
+    //     width = 432;
+    //   } else if (item.chs.length > 3) {
+    //     width = 560;
+    //   }
+      // if (left - this.bodyLeft > this.contentWidth / 2) {
+      //   _this.left = left - width + 10;
+      // } else {
+      _this.left = left - width / 2;
+      //}
+    },
+    changeWordCard(isShow) {
+      let _this = this;
+      _this.isShow = isShow;
+      _this.oldHz = "";
+      _this.hz = "";
+      _this.wordIndex = -1;
+    },
+    // 处理分词数据
+    handleNewWords(val) {
+      let _this = this;
+      _this.isShow = true;
+      _this.word = null;
+
+    //   if (_this.newWordList.indexOf(val) > -1) {
+    //     for (let i = 0; i < this.NNPENewWordList.length; i++) {
+    //       let pItem = this.NNPENewWordList[i];
+    //       for (let j = 0; j < pItem.length; j++) {
+    //         let item = pItem[j];
+    //         if (item.new_word.trim() == val.trim()) {
+    //           let wordlist = val.split("");
+    //           this.word = { list: wordlist, detail: item };
+    //           break;
+    //         }
+    //       }
+    //     }
+    //   } else {
+    //     let wordlist = val.split("");
+    //     let option = {
+    //       definition_list: [],
+    //       mp3_list: [],
+    //       new_word: val,
+    //       pinyin: _this.pinyin,
+    //     };
+    //     _this.word = { list: wordlist, detail: option };
+    //   }
+      _this.oldHz = val;
+    },
+    handleNewword() {
+    //   let NewWordList = [];
+    //   this.NNPENewWordList.forEach((item) => {
+    //     item.forEach((wItem) => {
+    //       NewWordList.push(wItem.new_word);
+    //     });
+    //   });
+    //   this.newWordList = JSON.parse(JSON.stringify(NewWordList));
+    },
+    getScreenHeight() {
+      this.screenHeight = window.innerHeight;
+    },
+    handleData() {
+      let resArr = {
+            wordsList: [],
+            timeList: [],
+        };
+      let articleInfo = JSON.parse(JSON.stringify(this.curQue));
+      articleInfo.art_corpus_data.sentList.forEach((item,index) => {
+        let wordlist = []
+        item.tokens.forEach((items,indexs)=>{
+            let obj = {
+                sent_id:item.id,
+                sno: item.sno-1,
+                pno: item.pno,
+                text: item.text,
+                tokens: items,
+                wIndex: indexs,
+                isShow: this.enFhList.indexOf(items[2])==-1,
+                marginRight: indexs===item.tokens.length-1
+            }
+            wordlist.push(obj)
+        })
+        resArr.wordsList.push(wordlist)
+        resArr.timeList.push(articleInfo.art_sound_srt_data.sents[index])
+      });
+      this.resArr = resArr;
+    },
+  },
+  //生命周期 - 创建完成(可以访问当前this实例)
+  created() {
+    this.handleData()
+  },
+  //生命周期 - 挂载完成(可以访问DOM元素)
+  mounted() {
+    let _this = this;
+    $(window).resize(() => {
+      _this.getScreenHeight();
+    });
+    _this.getScreenHeight();
+    document.addEventListener("keyup", function (e) {
+      if (_this.isKeyboard) {
+        if (e.keyCode == 32) {
+          //空格
+          _this.$nextTick(() => {
+            if (_this.$refs.audioLineSent) {
+              _this.$refs.audioLineSent.PlayAudio();
+            }
+          });
+        } else if (e.keyCode == 38) {
+          _this.prevSentence();
+        } else if (e.keyCode == 40) {
+          _this.nextSentence();
+        } else if (e.keyCode == 13) {
+          _this.$nextTick(() => {
+            _this.$refs.Soundrecorddiff.microphone();
+          });
+        }
+      }
+    });
+    if (_this.NNPENewWordList) {
+      _this.handleNewword();
+    }
+    _this.curSentIndex = _this.sentIndex;
+    _this.getSentence();
+    document.addEventListener("fullscreenchange", () => {
+      let isFullscreen =
+        document.fullscreenElement ||
+        document.mozFullScreenElement ||
+        document.webkitFullscreenElement ||
+        document.fullScreen ||
+        document.mozFullScreen ||
+        document.webkitIsFullScreen;
+
+      if (!isFullscreen) {
+        _this.changeFullScreen();
+      }
+    });
+    document.addEventListener("mozfullscreenchange", () => {
+      let isFullscreen =
+        document.fullscreenElement ||
+        document.mozFullScreenElement ||
+        document.webkitFullscreenElement ||
+        document.fullScreen ||
+        document.mozFullScreen ||
+        document.webkitIsFullScreen;
+
+      if (!isFullscreen) {
+        _this.changeFullScreen();
+      }
+    });
+    document.addEventListener("webkitfullscreenchange", () => {
+      let isFullscreen =
+        document.fullscreenElement ||
+        document.mozFullScreenElement ||
+        document.webkitFullscreenElement ||
+        document.fullScreen ||
+        document.mozFullScreen ||
+        document.webkitIsFullScreen;
+
+      if (!isFullscreen) {
+        _this.changeFullScreen();
+      }
+    });
+    document.addEventListener("msfullscreenchange", () => {
+      let isFullscreen =
+        document.fullscreenElement ||
+        document.mozFullScreenElement ||
+        document.webkitFullscreenElement ||
+        document.fullScreen ||
+        document.mozFullScreen ||
+        document.webkitIsFullScreen;
+
+      if (!isFullscreen) {
+        _this.changeFullScreen();
+      }
+    });
+  },
+  beforeCreate() {}, //生命周期 - 创建之前
+  beforeMount() {}, //生命周期 - 挂载之前
+  beforeUpdate() {}, //生命周期 - 更新之前
+  updated() {}, //生命周期 - 更新之后
+  beforeDestroy() {}, //生命周期 - 销毁之前
+  destroyed() {}, //生命周期 - 销毁完成
+  activated() {}, //如果页面有keep-alive缓存功能,这个函数会触发
+};
+</script>
+<style lang='scss' scoped>
+//@import url(); 引入公共css类
+.voicefull {
+  width: 100%;
+  height: 100vh;
+  overflow: hidden;
+  display: flex;
+  flex-direction: column;
+  .NNPE-wordDetail {
+    position: fixed;
+    z-index: 9999;
+    top: 50%;
+    margin-top: -196px;
+  }
+  &.bg1 {
+    background: #fff;
+  }
+  &.bg2 {
+    background: linear-gradient(180deg, #274533 0%, #385f45 100%);
+  }
+  &-top {
+    height: 136px;
+    width: 100%;
+    box-sizing: border-box;
+
+    padding: 0 40px;
+
+    .voicefull-top-hidden {
+      width: 100%;
+      height: 136px;
+      visibility: hidden;
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+    }
+    .voicefull-top-show {
+      width: 100%;
+      height: 136px;
+      visibility: visible;
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+    }
+    .top-left {
+      display: flex;
+      justify-content: flex-start;
+      align-items: center;
+    }
+    .select-bg {
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      width: 96px;
+      height: 56px;
+      border: 1px solid rgba(0, 0, 0, 0.1);
+      border-radius: 40px;
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      box-sizing: border-box;
+      margin-right: 32px;
+      &.select-bg-blue {
+        background: rgba(255, 255, 255, 0.1);
+        border: 1px solid rgba(0, 0, 0, 0.1);
+      }
+      > div {
+        width: 36px;
+        height: 36px;
+        border-radius: 100%;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        &.bg-white-box {
+          background: 0 0;
+          margin-right: 4px;
+          &.active {
+            background: #de4444;
+          }
+        }
+        &.bg-green-box {
+          background: #fff;
+          &.active {
+            background: #ffc600;
+          }
+        }
+
+        > span {
+          width: 24px;
+          height: 24px;
+          border-radius: 100%;
+          box-sizing: border-box;
+          cursor: pointer;
+          &.bg-white {
+            background: #fff;
+          }
+          &.bg-green {
+            background: linear-gradient(180deg, #274533 0%, #385f45 100%);
+          }
+        }
+      }
+    }
+    .set-fontSize {
+      padding: 0 20px;
+      height: 56px;
+      background: #ffffff;
+      border: 1px solid rgba(0, 0, 0, 0.1);
+      border-radius: 40px;
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      &-green {
+        background: rgba(255, 255, 255, 0.1);
+        border: 1px solid rgba(0, 0, 0, 0.1);
+      }
+      > span {
+        width: 24px;
+        height: 24px;
+        margin: 0 4px;
+        &.font-jian {
+        //   &-black {
+        //     background: url("../../../assets/NPC/jian-black.png") no-repeat left
+        //       top;
+        //     background-size: 100% 100%;
+        //     cursor: pointer;
+        //   }
+        //   &-yellow {
+        //     background: url("../../../assets/NPC/jian-white.png") no-repeat left
+        //       top;
+        //     background-size: 100% 100%;
+        //     cursor: pointer;
+        //   }
+        //   &-white-disabled {
+        //     background: url("../../../assets/NPC/jian-white-disabled.png")
+        //       no-repeat left top;
+        //     background-size: 100% 100%;
+        //     cursor: pointer;
+        //   }
+        //   &-yellow-disabled {
+        //     background: url("../../../assets/NPC/jian-yellow-disabled.png")
+        //       no-repeat left top;
+        //     background-size: 100% 100%;
+        //     cursor: pointer;
+        //   }
+        }
+        &.font-img {
+        //   &-black {
+        //     background: url("../../../assets/NPC/fontSize-black.png") no-repeat
+        //       left top;
+        //     background-size: 100% 100%;
+        //   }
+        //   &-yellow {
+        //     background: url("../../../assets/NPC/fontSize-white.png") no-repeat
+        //       left top;
+        //     background-size: 100% 100%;
+        //   }
+        }
+        &.font-jia {
+        //   &-black {
+        //     background: url("../../../assets/NPC/jia-black.png") no-repeat left
+        //       top;
+        //     background-size: 100% 100%;
+        //     cursor: pointer;
+        //   }
+        //   &-yellow {
+        //     background: url("../../../assets/NPC/jia-white.png") no-repeat left
+        //       top;
+        //     background-size: 100% 100%;
+        //     cursor: pointer;
+        //   }
+        //   &-white-disabled {
+        //     background: url("../../../assets/NPC/jia-white-disabled.png")
+        //       no-repeat left top;
+        //     background-size: 100% 100%;
+        //     cursor: pointer;
+        //   }
+        //   &-yellow-disabled {
+        //     background: url("../../../assets/NPC/jia-yellow-disabled.png")
+        //       no-repeat left top;
+        //     background-size: 100% 100%;
+        //     cursor: pointer;
+        //   }
+        }
+      }
+    }
+    .top-middle {
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      .audio-box {
+        width: 56px;
+        height: 56px;
+        background: #ffffff;
+        border: 1px solid rgba(0, 0, 0, 0.1);
+        border-radius: 40px;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        &-green {
+          background: rgba(255, 255, 255, 0.1);
+          border: 1px solid rgba(0, 0, 0, 0.1);
+        }
+      }
+    }
+  }
+  .op-btn {
+    width: 56px;
+    height: 56px;
+    border-radius: 100%;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+
+    cursor: pointer;
+    margin-left: 32px;
+    background: #ffffff;
+    border: 1px solid rgba(0, 0, 0, 0.1);
+    box-sizing: border-box;
+    &-green {
+      background: rgba(255, 255, 255, 0.1);
+      border: 1px solid rgba(0, 0, 0, 0.1);
+    }
+    &.close-btn {
+      background: #274533;
+      border: 1px solid rgba(0, 0, 0, 0.1);
+    }
+    > span {
+      width: 24px;
+      height: 24px;
+      &.close-icon {
+        // background: url("../../../assets/icon/cross-24-normal-black.png")
+        //   no-repeat left top;
+        // background-size: 100% 100%;
+        // &-white {
+        //   background: url("../../../assets/icon/cross-24-normal-white.png")
+        //     no-repeat left top;
+        //   background-size: 100% 100%;
+        // }
+      }
+    }
+  }
+  .repeat-icon {
+    // background: url("../../../assets/icon/Repeat-24-normal-red.png") no-repeat
+    //   left top;
+    // background-size: 100% 100%;
+    // &.disabled {
+    //   background: url("../../../assets/icon/Repeat-24-disable-Black.png")
+    //     no-repeat left top;
+    //   background-size: 100% 100%;
+    // }
+    // &-yellow {
+    //   background: url("../../../assets/icon/Repeat-24-normal-yellow.png")
+    //     no-repeat left top;
+    //   background-size: 100% 100%;
+    // }
+    // &.auto-icon {
+    //   background: url("../../../assets/icon/Auto-24-next-red.png") no-repeat
+    //     left top;
+    //   background-size: 100% 100%;
+    //   &-yellow {
+    //     background: url("../../../assets/icon/Auto-24-next-yellow.png")
+    //       no-repeat left top;
+    //     background-size: 100% 100%;
+    //   }
+    // }
+  }
+  .pinyin-icon {
+    // background: url("../../../assets/icon/pinyin-24-normal-red.png") no-repeat
+    //   left top;
+    // background-size: 100% 100%;
+    // &.disabled {
+    //   background: url("../../../assets/icon/pinyin-24-disable-Black.png")
+    //     no-repeat left top;
+    //   background-size: 100% 100%;
+    // }
+    // &-yellow {
+    //   background: url("../../../assets/icon/pinyin-24-normal-yellow.png")
+    //     no-repeat left top;
+    //   background-size: 100% 100%;
+    // }
+  }
+  .en-icon {
+    // background: url("../../../assets/icon/EN-24-normal-Red.png") no-repeat left
+    //   top;
+    // background-size: 100% 100%;
+    // &.disabled {
+    //   background: url("../../../assets/icon/EN-24-disable-Black.png") no-repeat
+    //     left top;
+    //   background-size: 100% 100%;
+    // }
+    // &-yellow {
+    //   background: url("../../../assets/icon/EN-24-normal-yellow.png") no-repeat
+    //     left top;
+    //   background-size: 100% 100%;
+    // }
+  }
+  .coll-icon {
+    // background: url("../../../assets/icon/bookmarkfill-24-normal-red.png")
+    //   no-repeat left top;
+    // background-size: 100% 100%;
+    // &.disabled {
+    //   background: url("../../../assets/icon/bookmarkfill-24-disable-Black.png")
+    //     no-repeat left top;
+    //   background-size: 100% 100%;
+    // }
+    // &-yellow {
+    //   background: url("../../../assets/icon/bookmarkfill-24-normal-yellow.png")
+    //     no-repeat left top;
+    //   background-size: 100% 100%;
+    // }
+  }
+  .keyboard-icon {
+    // background: url("../../../assets/icon/enter-24-keyboard-red.png") no-repeat
+    //   left top;
+    // background-size: 100% 100%;
+    // &.disabled {
+    //   background: url("../../../assets/icon/enter-24-keyboard-disable-Black.png")
+    //     no-repeat left top;
+    //   background-size: 100% 100%;
+    // }
+    // &-yellow {
+    //   background: url("../../../assets/icon/enter-24-keyboard-yellow.png")
+    //     no-repeat left top;
+    //   background-size: 100% 100%;
+    // }
+  }
+  &-content {
+    flex: 1;
+    width: 100%;
+    box-sizing: border-box;
+    display: flex;
+    align-items: center;
+    .vc-box {
+      padding: 0 8px 0 36px;
+      &-right {
+        padding: 0 36px 0 8px;
+      }
+    }
+    .vc-left {
+      width: 64px;
+      height: 64px;
+      cursor: pointer;
+    //   &-grey {
+    //     background: url("../../../assets/NPC/left-grey.png") no-repeat left top;
+    //     background-size: 100% 100%;
+    //   }
+    //   &-black {
+    //     background: url("../../../assets/NPC/left-black.png") no-repeat left top;
+    //     background-size: 100% 100%;
+    //   }
+    //   &-white {
+    //     background: url("../../../assets/NPC/left-white.png") no-repeat left top;
+    //     background-size: 100% 100%;
+    //   }
+      &.hidden {
+        visibility: hidden;
+      }
+    }
+    .vc-right {
+      width: 64px;
+      height: 64px;
+      cursor: pointer;
+    //   &-grey {
+    //     background: url("../../../assets/NPC/right-grey.png") no-repeat left top;
+    //     background-size: 100% 100%;
+    //   }
+    //   &-black {
+    //     background: url("../../../assets/NPC/right-black.png") no-repeat left
+    //       top;
+    //     background-size: 100% 100%;
+    //   }
+    //   &-white {
+    //     background: url("../../../assets/NPC/right-white.png") no-repeat left
+    //       top;
+    //     background-size: 100% 100%;
+    //   }
+    }
+    .vc-main {
+      width: fit-content;
+      margin: 0 auto;
+      padding: 0 67px;
+    }
+    .NNPE-words {
+      float: left;
+      user-select: none;
+      -webkit-user-select: none;
+      -moz-user-select: none;
+      -ms-user-select: none;
+      &-box {
+        float: left;
+        > span {
+          display: block;
+          &.NNPE-pinyin {
+            font-family: "GB-PINYINOK-B";
+            font-weight: normal;
+            font-size: 32px;
+            line-height: 1.25;
+            box-sizing: border-box;
+            color: rgba(0, 0, 0, 0.85);
+            &.bottom {
+              padding-bottom: 16px;
+            }
+            &.noFont {
+              font-family: initial;
+            }
+            &.textLeft {
+              text-align: left;
+            }
+            &.font-white {
+              color: #fff;
+            }
+            &.wordBlank {
+              color: rgba(0, 0, 0, 0.85);
+            }
+          }
+          &.NNPE-chs {
+            font-family: "FZJCGFKTK";
+            font-size: 48px;
+            line-height: 1.17;
+            color: rgba(0, 0, 0, 0.85);
+            &.bottom {
+              padding-bottom: 16px;
+            }
+            .font-white {
+              color: #fff;
+            }
+            .active {
+              color: #de4444;
+              &-yellow {
+                color: #ffc600;
+              }
+            }
+
+            .wordActive {
+              color: #de4444;
+            }
+            .wordActive-blue {
+              color: #ffc600;
+            }
+          }
+          // &.padding {
+          //   padding-right: 6px;
+          // }
+        }
+      }
+      &.textLeft {
+        text-align: left;
+      }
+      &.textCenter {
+        text-align: center;
+      }
+      &.textRight {
+        text-align: right;
+      }
+      > span {
+        display: block;
+        &.NNPE-pinyin {
+          font-family: "GB-PINYINOK-B";
+          font-weight: normal;
+          font-size: 32px;
+          line-height: 1.25;
+          box-sizing: border-box;
+          color: rgba(0, 0, 0, 0.85);
+          &.bottom {
+            padding-bottom: 16px;
+          }
+          &.font-white {
+            color: #fff;
+          }
+          &.noFont {
+            font-family: initial;
+          }
+          &.textLeft {
+            text-align: left;
+          }
+          &.wordBlank {
+            color: rgba(0, 0, 0, 0.85);
+          }
+        }
+        &.NNPE-chs {
+          font-family: "FZJCGFKTK";
+          font-size: 48px;
+          line-height: 1.17;
+          color: rgba(0, 0, 0, 0.85);
+          &.bottom {
+            padding-bottom: 16px;
+          }
+          .font-white {
+            color: #fff;
+          }
+          .active {
+            color: #de4444;
+            &-yellow {
+              color: #ffc600;
+            }
+          }
+          .wordActive {
+            color: #de4444;
+          }
+          .wordActive-blue {
+            color: #ffc600;
+          }
+        }
+        &.padding {
+          padding-left: 3px;
+          padding-right: 3px;
+        }
+      }
+    }
+    .nnpe-sentence-box{
+        float: left;
+    }
+    .NNPE-words {
+        float: left;
+        padding: 0;
+        user-select: none;
+        -webkit-user-select: none;
+        -moz-user-select: none;
+        -ms-user-select: none;
+        &.noPadding{
+            padding:0;
+        }
+        &.sentActive {
+            background: rgba(24, 144, 255, 0.1);
+        }
+        &.overActive {
+            background: rgba(0, 0, 0, 0.06);
+        }
+        &.textLeft {
+            text-align: left;
+        }
+        &.textCenter {
+            text-align: center;
+        }
+        > span {
+            float: left;
+            cursor: pointer;
+            &.NNPE-chs {
+                //   font-size: 24px;
+                font-family: 'Smartisan';
+                line-height: 150%;
+                color: #000000;
+                padding: 0 5px;
+                font-weight: 700;
+                &.wordActive {
+                color: #175DFF;
+                }
+                &.marginRight{
+                padding-right: 0;
+                }
+                &.marginLeft{
+                padding-left: 0;
+                }
+                &.marginSingleRight{
+                padding-right: 3px;
+                }
+            }
+            &.padding {
+                padding: 0 3px;
+                cursor: pointer;
+            }
+        }
+    }
+  }
+  &-bottom {
+    height: 136px;
+    width: 100%;
+    box-sizing: border-box;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    padding-right: 40px;
+
+    .voicefull-bottom-show {
+      height: 136px;
+      width: 100%;
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      visibility: visible;
+    }
+    .voicefull-bottom-hidden {
+      height: 136px;
+      width: 100%;
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      visibility: hidden;
+    }
+    .bottom-left {
+      display: flex;
+      justify-content: flex-start;
+      align-items: center;
+      &-margin {
+        margin-left: 40px;
+      }
+      .compare-box {
+        height: 56px;
+        padding: 16px 16px;
+        box-sizing: border-box;
+        border: 1px solid rgba(0, 0, 0, 0.1);
+        border-radius: 0 40px 40px 0;
+        border-left: 0px solid rgba(0, 0, 0, 0.1);
+        &-white {
+          background: rgba(255, 255, 255, 0.1);
+          border: 1px solid rgba(0, 0, 0, 0.1);
+          border-left: 0;
+        }
+        &-answer {
+          border-radius: 40px;
+        }
+      }
+    }
+    .page-count {
+      padding: 8px;
+      font-size: 16px;
+      line-height: 24px;
+      font-family: "robot";
+      color: #000000;
+      min-width: 60px;
+      box-sizing: border-box;
+      border-radius: 8px;
+      background: #fff;
+      text-align: center;
+      &-green {
+        color: #ffffff;
+        background: rgba(255, 255, 255, 0.2);
+      }
+    }
+  }
+}
+.word-play-audio {
+  position: absolute;
+  left: -1000px;
+}
+</style>