guanchunjie пре 3 година
родитељ
комит
62ddfe29cb

BIN
src/assets/NPC/loading-red.png


BIN
src/assets/NPC/tts-loading.png


+ 2 - 2
src/components/Adult/Preview.vue

@@ -291,7 +291,7 @@
                   <NewWordShow
                     :cur-que="itemss.data"
                     :theme-color="themeColor"
-                    :indexStr="index+'_'+indexs+'_'+indexss"
+                    :indexStr="index + '_' + indexs + '_' + indexss"
                     v-if="refresh"
                   />
                 </template>
@@ -686,7 +686,7 @@ export default {
   width: 860px;
   margin: 0 auto;
   position: relative;
-  padding-bottom:120px;
+  padding-bottom: 120px;
   .NNPE-title {
     background: #e35454;
     border-radius: 0px 0px 16px 16px;

+ 5 - 1
src/components/Adult/preview/ArticleViewChs/NormalModelChs.vue

@@ -11,6 +11,7 @@
         audioId="artNormalAudio"
         :mp3="curQue.mp3_list[0].id"
         :getCurTime="getCurTime"
+        :duration="curQue.mp3_list[0].media_duration"
         ref="audioLine"
       />
     </div>
@@ -256,7 +257,10 @@ export default {
   },
   computed: {
     isPlaying: function () {
-      let playing = this.$refs.audioLine.audio.isPlaying;
+      let playing = false;
+      if (this.$refs.audioLine) {
+        playing = this.$refs.audioLine.audio.isPlaying;
+      }
       return playing;
     },
   },

+ 9 - 1
src/components/Adult/preview/ArticleViewChs/PhraseModelChs.vue

@@ -166,7 +166,14 @@ import AudioLine from "../AudioLine.vue";
 import Wordcard from "../components/Wordcard.vue"; // 卡片
 export default {
   name: "PhraseModelChs",
-  props: ["curQue", "bodyLeft", "NNPENewWordList", "themeColor", "noFont","currentTreeID"],
+  props: [
+    "curQue",
+    "bodyLeft",
+    "NNPENewWordList",
+    "themeColor",
+    "noFont",
+    "currentTreeID",
+  ],
   components: {
     AudioLine,
     Wordcard,
@@ -541,6 +548,7 @@ export default {
   }
   .NNPE-wordDetail {
     position: fixed;
+    z-index: 9999;
     //   width: 260px;
     //   height: 200px;
     //   background: #cc0;

+ 4 - 1
src/components/Adult/preview/ArticleViewChs/Practicechs.vue

@@ -287,7 +287,10 @@ export default {
   },
   computed: {
     isPlaying: function () {
-      let playing = this.$refs.audioLine.audio.isPlaying;
+      let playing = false;
+      if (this.$refs.audioLine) {
+        playing = this.$refs.audioLine.audio.isPlaying;
+      }
       return playing;
     },
   },

+ 10 - 2
src/components/Adult/preview/ArticleViewChs/WordModelChs.vue

@@ -145,7 +145,13 @@ import AudioLine from "../AudioLine.vue";
 import Wordcard from "../components/Wordcard.vue"; // 卡片
 export default {
   name: "WordModelChs",
-  props: ["curQue", "bodyLeft", "NNPENewWordList", "themeColor","currentTreeID"],
+  props: [
+    "curQue",
+    "bodyLeft",
+    "NNPENewWordList",
+    "themeColor",
+    "currentTreeID",
+  ],
   components: {
     AudioLine,
     Wordcard,
@@ -504,14 +510,16 @@ export default {
         clear: both;
       }
       > img {
-        width: 100%;
+        max-width: 100%;
         display: block;
+        margin: 0 auto;
       }
     }
   }
 }
 .NNPE-wordDetail {
   position: fixed;
+  z-index: 9999;
   //   width: 260px;
   //   height: 200px;
   //   background: #cc0;

+ 1 - 0
src/components/Adult/preview/ArticleViewChs/index.vue

@@ -81,6 +81,7 @@
         :NNPENewWordList="NNPENewWordList"
         :themeColor="themeColor"
         :noFont="noFont"
+        :currentTreeID="currentTreeID"
         v-if="showWord"
       />
     </div>

+ 431 - 0
src/components/Adult/preview/AudioLine copy.vue

@@ -0,0 +1,431 @@
+<template>
+  <div class="Audio">
+    <div class="audioLine" v-if="!hideSlider">
+      <div
+        class="play"
+        :class="audio.playing ? 'playBtn' : 'pauseBtn'"
+        @click="PlayAudio"
+      />
+      <template v-if="!isRepeat">
+        <el-slider
+          v-model="playValue"
+          :style="{ width: sliderWidth + 'px', height: '2px' }"
+          :format-tooltip="formatProcessToolTip"
+          @change="changeCurrentTime"
+        />
+        <span
+          ><template v-if="audio.playing">-</template
+          >{{
+            audio.maxTime
+              ? realFormatSecond(audio.maxTime - audio.currentTime)
+              : ""
+          }}</span
+        >
+      </template>
+      <audio
+        ref="audio"
+        :src="mp3"
+        @loadedmetadata="onLoadedmetadata"
+        @timeupdate="onTimeupdate"
+      />
+    </div>
+    <div class="audioLine2" v-else>
+      <div
+        class="play-icon"
+        :class="audio.playing ? 'playBtn-icon' : 'pauseBtn-icon'"
+        @click="PlayAudio"
+      />
+    </div>
+    <audio
+      :ref="audioId"
+      :src="mp3"
+      @loadedmetadata="onLoadedmetadata"
+      @timeupdate="onTimeupdate"
+      @canplay="oncanplay"
+      :id="audioId"
+    />
+  </div>
+</template>
+
+<script>
+// 这里可以导入其它文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)
+// 例如:import 《组件名称》from ‘《组件路径》';
+export default {
+  // import引入的组件需要注入到对象中才能使用
+  components: {},
+  props: [
+    "mp3",
+    "getCurTime",
+    "stopAudio",
+    "width",
+    "isRepeat",
+    "themeColor",
+    "hideSlider",
+    "ed",
+    "bg",
+    "audioId",
+  ],
+  data() {
+    // 这里存放数据
+    return {
+      playValue: 0,
+      audio: {
+        // 该字段是音频是否处于播放状态的属性
+        playing: false,
+        // 音频当前播放时长
+        currentTime: 0,
+        // 音频最大播放时长
+        maxTime: 0,
+        isPlaying: false,
+        loading: false,
+      },
+      audioAllTime: null, // 展示总时间
+      duioCurrentTime: null, // 剩余时间
+    };
+  },
+  // 计算属性 类似于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;
+    let audioId = _this.audioId;
+    _this.$refs[audioId].addEventListener("play", function () {
+      _this.audio.playing = true;
+      _this.audio.isPlaying = true;
+    });
+    _this.$refs[audioId].addEventListener("pause", function () {
+      _this.audio.playing = false;
+    });
+    _this.$refs[audioId].addEventListener("ended", function () {
+      _this.audio.playing = false;
+      _this.audio.isPlaying = 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");
+      audio.forEach((item) => {
+        if (item.src == this.mp3) {
+          if (item.id !== audioId) {
+            item.pause();
+          }
+        } else {
+          item.pause();
+        }
+      });
+
+      if (this.audio.playing) {
+        this.$refs[audioId].pause();
+        this.audio.playing = false;
+        this.$emit("handleListenRead", false);
+      } else {
+        if (this.hideSlider) {
+          this.$refs[audioId].play();
+          this.onTimeupdateTime(this.bg / 1000);
+        } else {
+          this.$refs[audioId].play();
+        }
+        this.audio.playing = true;
+        this.$emit("handleChangeStopAudio");
+        this.$emit("handleListenRead", true);
+      }
+    },
+    oncanplay() {},
+    // 点击 拖拽播放音频
+    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(res.target.duration);
+      this.audioAllTime = this.realFormatSecond(this.audio.maxTime);
+    },
+    // 当音频当前时间改变后,进度条也要改变
+    onTimeupdate(res) {
+      let audioId = this.audioId;
+      this.audio.currentTime = res.target.currentTime;
+      this.getCurTime(res.target.currentTime);
+      this.playValue = (this.audio.currentTime / this.audio.maxTime) * 100;
+      if (this.audio.currentTime * 1000 > this.ed) {
+        this.$refs[audioId].pause();
+      }
+    },
+    onTimeupdateTime(res, playFlag) {
+      let audioId = this.audioId;
+      this.$refs[audioId].currentTime = res;
+      this.playValue = (res / this.audio.maxTime) * 100;
+      if (playFlag) {
+        let audio = document.getElementsByTagName("audio");
+        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类 */
+.Audio {
+  width: 100%;
+  .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;
+    .play {
+      margin-right: 12px;
+      margin-left: 8px;
+      width: 16px;
+      height: 16px;
+      cursor: pointer;
+      display: block;
+      // &.playBtn {
+      //   background: url("../../../assets/pause.png") no-repeat left top;
+      //   background-size: 100% 100%;
+      // }
+      // &.pauseBtn {
+      //   background: url("../../../assets/play.png") no-repeat left top;
+      //   background-size: 100% 100%;
+      // }
+    }
+
+    span {
+      font-size: 16px;
+      line-height: 19px;
+      color: #000;
+      margin-left: 8px;
+      margin-right: 12px;
+      min-width: 56px;
+      text-align: right;
+    }
+  }
+  > .audioLine2 {
+    .play-icon {
+      width: 16px;
+      height: 16px;
+      cursor: pointer;
+      &.playBtn-icon {
+        background: url("../../../assets/NPC/icon-voice-play-red.png") no-repeat
+          left top;
+        background-size: 100% 100%;
+      }
+      &.pauseBtn-icon {
+        background: url("../../../assets/NPC/play-red.png") no-repeat left top;
+        background-size: 100% 100%;
+      }
+    }
+  }
+}
+.NPC-Big-Book-preview-green {
+  .playBtn-icon {
+    background: url("../../../assets/NPC/icon-voice-play-green.png") no-repeat
+      left top;
+    background-size: 100% 100%;
+  }
+  .pauseBtn-icon {
+    background: url("../../../assets/NPC/play-green.png") no-repeat left top;
+    background-size: 100% 100%;
+  }
+}
+.NPC-Big-Book-preview-red {
+  .playBtn-icon {
+    background: url("../../../assets/NPC/icon-voice-play-red.png") no-repeat
+      left top;
+    background-size: 100% 100%;
+  }
+  .pauseBtn-icon {
+    background: url("../../../assets/NPC/play-red.png") no-repeat left top;
+    background-size: 100% 100%;
+  }
+}
+.NPC-Big-Book-preview-brown {
+  .playBtn-icon {
+    background: url("../../../assets/NPC/icon-voice-play-brown.png") no-repeat
+      left top;
+    background-size: 100% 100%;
+  }
+  .pauseBtn-icon {
+    background: url("../../../assets/NPC/play-brown.png") no-repeat left top;
+    background-size: 100% 100%;
+  }
+}
+</style>
+<style lang="scss">
+.Audio {
+  .el-slider__button-wrapper {
+    position: relative;
+    z-index: 0;
+  }
+  .el-slider__button {
+    width: 8px;
+    height: 8px;
+    top: 12px;
+    position: absolute;
+  }
+  .el-slider__runway {
+    margin: 0;
+    padding: 0;
+    background: #e5e5e5;
+    border-radius: 0px;
+    height: 2px;
+  }
+  .el-slider {
+    position: relative;
+  }
+  .el-slider__bar {
+    height: 2px;
+    background: rgba(118, 99, 236, 1);
+  }
+  .el-slider__button {
+    background: rgba(118, 99, 236, 1);
+    border: none;
+  }
+}
+.NPC-Book-Sty {
+  .Audio {
+    .el-slider__bar {
+      height: 2px;
+      background: #de4444;
+    }
+    .el-slider__button {
+      background: #de4444;
+      border: none;
+    }
+  }
+}
+.NPC-Big-Book-preview-green {
+  .Audio {
+    .el-slider__bar {
+      background: #24b99e !important;
+    }
+    .el-slider__button {
+      background: #24b99e !important;
+    }
+  }
+}
+.NPC-Big-Book-preview-brown {
+  .Audio {
+    .el-slider__bar {
+      background: #bd8865 !important;
+    }
+    .el-slider__button {
+      background: #bd8865 !important;
+    }
+  }
+}
+</style>

+ 24 - 8
src/components/Adult/preview/AudioLine.vue

@@ -3,7 +3,9 @@
     <div class="audioLine" v-if="!hideSlider">
       <div
         class="play"
-        :class="audio.playing ? 'playBtn' : 'pauseBtn'"
+        :class="
+          audio.loading ? 'loadBtn' : audio.playing ? 'playBtn' : 'pauseBtn'
+        "
         @click="PlayAudio"
       />
       <template v-if="!isRepeat">
@@ -22,12 +24,6 @@
           }}</span
         >
       </template>
-      <audio
-        ref="audio"
-        :src="mp3"
-        @loadedmetadata="onLoadedmetadata"
-        @timeupdate="onTimeupdate"
-      />
     </div>
     <div class="audioLine2" v-else>
       <div
@@ -41,6 +37,8 @@
       :src="mp3"
       @loadedmetadata="onLoadedmetadata"
       @timeupdate="onTimeupdate"
+      @canplaythrough="oncanplaythrough"
+      preload="meta"
       :id="audioId"
     />
   </div>
@@ -76,6 +74,7 @@ export default {
         // 音频最大播放时长
         maxTime: 0,
         isPlaying: false,
+        loading: false,
       },
       audioAllTime: null, // 展示总时间
       duioCurrentTime: null, // 剩余时间
@@ -119,7 +118,11 @@ export default {
   mounted() {
     let _this = this;
     let audioId = _this.audioId;
+    _this.$refs[audioId].addEventListener("loadstart", function () {
+      console.log("音频开始加载");
+    });
     _this.$refs[audioId].addEventListener("play", function () {
+      console.log("音频开始播放了");
       _this.audio.playing = true;
       _this.audio.isPlaying = true;
     });
@@ -130,6 +133,7 @@ export default {
       _this.audio.playing = false;
       _this.audio.isPlaying = false;
     });
+
     this.$nextTick(() => {
       document
         .getElementsByClassName("el-slider__button-wrapper")[0]
@@ -165,17 +169,24 @@ export default {
         this.audio.playing = false;
         this.$emit("handleListenRead", false);
       } else {
+        if (this.count == 0) {
+          this.audio.loading = true;
+          this.count++;
+        }
         if (this.hideSlider) {
           this.$refs[audioId].play();
           this.onTimeupdateTime(this.bg / 1000);
         } else {
           this.$refs[audioId].play();
         }
-        this.audio.playing = true;
         this.$emit("handleChangeStopAudio");
         this.$emit("handleListenRead", true);
       }
     },
+    oncanplaythrough() {
+      console.log("音频加载完成");
+      this.audio.loading = false;
+    },
     // 点击 拖拽播放音频
     changeCurrentTime(value) {
       let audioId = this.audioId;
@@ -291,6 +302,11 @@ export default {
       height: 16px;
       cursor: pointer;
       display: block;
+      &.loadBtn {
+        background: url("../../../assets/NPC/loading-red.png") no-repeat left
+          top;
+        background-size: 100% 100%;
+      }
       // &.playBtn {
       //   background: url("../../../assets/pause.png") no-repeat left top;
       //   background-size: 100% 100%;

+ 4 - 1
src/components/Adult/preview/DialogueArticleViewChs/NormalModelChs.vue

@@ -353,7 +353,10 @@ export default {
   },
   computed: {
     isPlaying: function () {
-      let playing = this.$refs.audioLine.audio.isPlaying;
+      let playing = false;
+      if (this.$refs.audioLine) {
+        playing = this.$refs.audioLine.audio.isPlaying;
+      }
       return playing;
     },
   },

+ 2 - 0
src/components/Adult/preview/DialogueArticleViewChs/PhraseModelChs.vue

@@ -240,6 +240,7 @@ export default {
     "colorBox",
     "themeColor",
     "noFont",
+    "currentTreeID"
   ],
   components: {
     AudioLine,
@@ -865,6 +866,7 @@ export default {
   }
   .NNPE-wordDetail {
     position: fixed;
+    z-index: 9999;
   }
 }
 </style>

+ 4 - 1
src/components/Adult/preview/DialogueArticleViewChs/Practicechs.vue

@@ -420,7 +420,10 @@ export default {
   },
   computed: {
     isPlaying: function () {
-      let playing = this.$refs.audioLine.audio.isPlaying;
+      let playing = false;
+      if (this.$refs.audioLine) {
+        playing = this.$refs.audioLine.audio.isPlaying;
+      }
       return playing;
     },
   },

+ 3 - 2
src/components/Adult/preview/DialogueArticleViewChs/WordModelChs.vue

@@ -236,7 +236,7 @@ export default {
     "colorBox",
     "themeColor",
     "noFont",
-    "currentTreeID"
+    "currentTreeID",
   ],
   components: {
     AudioLine,
@@ -841,7 +841,7 @@ export default {
         border-radius: 8px;
       }
       > img {
-        width: 100%;
+        max-width: 100%;
         display: block;
       }
     }
@@ -861,6 +861,7 @@ export default {
 }
 .NNPE-wordDetail {
   position: fixed;
+  z-index: 9999;
   //   width: 260px;
   //   height: 200px;
   //   background: #cc0;

+ 5 - 4
src/components/Adult/preview/DialogueArticleViewChs/index.vue

@@ -175,10 +175,11 @@ export default {
   mounted() {
     console.log("我是文章预览");
     console.log(this.curQue);
-
-    this.$nextTick(() => {
-      this.bodyLeft = this.$refs.ArticleViewbody.getBoundingClientRect().left;
-    });
+    if (this.curQue) {
+      this.$nextTick(() => {
+        this.bodyLeft = this.$refs.ArticleViewbody.getBoundingClientRect().left;
+      });
+    }
     console.log(this.NNPENewWordList);
   },
   beforeCreate() {}, //生命周期 - 创建之前

+ 127 - 102
src/components/Adult/preview/WordPhrase.vue

@@ -1,99 +1,101 @@
 <template>
   <div class="NPC-zhedie">
-          <div class="topTitle">
-            <div class="NPC-top-left">
-              <span class="NPC-topTitle-text">{{ curQue.title }}</span>
-              <span
-                :class="['NPC-play-all', playClass]"
-                @click.stop="playNewwords"
-              ></span>
-            </div>
-            <div class="NPC-top-right">
-                <span class="NPC-top-right-text" @click="handleChangeTab">{{
-                  wordShow ? "收起" : "展开"
-                }}</span>
-              <img
-                v-if="wordShow"
-                src="../../../assets/NPC/down.png"
-                alt=""
-              />
-              <img v-else src="../../../assets/NPC/up.png" alt="" />
-            </div>
-          </div>
-          <el-collapse-transition>
+    <div class="topTitle">
+      <div class="NPC-top-left">
+        <span class="NPC-topTitle-text">{{ curQue.title }}</span>
+        <span
+          :class="['NPC-play-all', playClass]"
+          @click.stop="playNewwords"
+        ></span>
+      </div>
+      <div class="NPC-top-right">
+        <span class="NPC-top-right-text" @click="handleChangeTab">{{
+          wordShow ? "收起" : "展开"
+        }}</span>
+        <img v-if="wordShow" src="../../../assets/NPC/down.png" alt="" />
+        <img v-else src="../../../assets/NPC/up.png" alt="" />
+      </div>
+    </div>
+    <el-collapse-transition>
+      <div
+        class="NPC-word-list"
+        v-if="curQue.option && curQue.option.length > 0"
+        v-show="wordShow"
+      >
+        <ul class="NPC-word-table" cellspacing="0" border="0" cellpadding="0">
+          <li
+            class="NPC-word-tr"
+            v-for="(item, index) in curQue.option"
+            :key="'curQue.option' + index"
+          >
             <div
-            class="NPC-word-list"
-            v-if="curQue.option && curQue.option.length > 0"
-            v-show="wordShow"
+              :class="[
+                'NPC-word-row',
+                mp3_index == sItem.sIndex ? 'active' : '',
+              ]"
+              v-for="(sItem, sIndex) in item"
+              :key="'curQue.option.child' + sIndex"
             >
-            <ul class="NPC-word-table" cellspacing="0" border="0" cellpadding="0">
-                <li
-                class="NPC-word-tr"
-                v-for="(item, index) in curQue.option"
-                :key="'curQue.option' + index"
-                >
-                <div
-                    :class="['NPC-word-row',mp3_index == sItem.sIndex?'active':'']"
-                    v-for="(sItem, sIndex) in item"
-                    :key="'curQue.option.child' + sIndex"
-                >
-                    <template
-                    v-if="
-                        sItem.mp3_list &&
-                        sItem.mp3_list.length > 0 &&
-                        sItem.mp3_list[0].id
-                    "
-                    >
-                    <span
-                        :class="[
-                        themeColor == 'green'
-                            ? 'NPC-play-btn-green'
-                            : themeColor == 'red'
-                            ? 'NPC-play-btn-red'
-                            : 'NPC-play-btn-brown',
-                        mp3_index == sItem.sIndex ? 'active' : '',
-                        ]"
-                        @click="palyAudio(sItem.sIndex)"
-                    ></span>
-                    <audio
-                        :id="'word' + indexs + indexss + sItem.sIndex"
-                        :src="sItem.mp3_list[0].id"
-                    ></audio>
-                    </template>
-                    <template v-else>
-                    <span style="width: 16px; height: 16px"></span>
-                    </template>
-                    <span class="tabNum"
-                    ><template v-if="sItem.mIndex == 0"
-                        >{{ index + 1 }}.</template
-                    ></span
-                    >
+              <template
+                v-if="
+                  sItem.mp3_list &&
+                  sItem.mp3_list.length > 0 &&
+                  sItem.mp3_list[0].id
+                "
+              >
+                <span
+                  :class="[
+                    themeColor == 'green'
+                      ? 'NPC-play-btn-green'
+                      : themeColor == 'red'
+                      ? 'NPC-play-btn-red'
+                      : 'NPC-play-btn-brown',
+                    mp3_index == sItem.sIndex ? 'active' : '',
+                  ]"
+                  @click="palyAudio(sItem.sIndex)"
+                ></span>
+                <audio
+                  :id="'word' + indexs + indexss + sItem.sIndex"
+                  :src="sItem.mp3_list[0].id"
+                ></audio>
+              </template>
+              <template v-else>
+                <span style="width: 16px; height: 16px"></span>
+              </template>
+              <template v-if="sItem.mIndex == 0">
+                <b class="tabNum">{{ index + 1 }}</b>
+              </template>
+              <div
+                v-else
+                style="width: 16px; height: 16px; margin-left: 8px"
+              ></div>
 
-                    <span class="NPC-word-tab-common NPC-word-tab-pinyin">
-                    {{ sItem.pinyin }}
-                    </span>
-                    <span class="NPC-word-tab-common NPC-word-tab-word">
-                    {{ sItem.new_word }}
-                    </span>
-                    <span class="NPC-word-tab-common NPC-word-tab-cixing">
-                    {{ sItem.cixing }}
-                    </span>
-                    <span
-                    class="NPC-word-tab-common NPC-word-tab-def"
-                    v-html="sItem.def_str"
-                    ></span>
-                    <span>
-                    <img
-                        src="../../../assets/NPC/detail-icon.png"
-                        class="detail-icon"
-                        @click="showDetail(sItem)"
-                    />
-                    </span>
-                </div>
-                </li>
-            </ul>
+              <span class="NPC-word-tab-common NPC-word-tab-pinyin">
+                {{ sItem.pinyin }}
+              </span>
+              <span class="NPC-word-tab-common NPC-word-tab-word">
+                {{ sItem.new_word }}
+              </span>
+              <span
+                class="NPC-word-tab-common NPC-word-tab-cixing"
+                v-html="sItem.cixing"
+              ></span>
+              <span
+                class="NPC-word-tab-common NPC-word-tab-def"
+                v-html="sItem.def_str"
+              ></span>
+              <span>
+                <img
+                  src="../../../assets/NPC/detail-icon.png"
+                  class="detail-icon"
+                  @click="showDetail(sItem)"
+                />
+              </span>
             </div>
-          </el-collapse-transition>
+          </li>
+        </ul>
+      </div>
+    </el-collapse-transition>
     <div v-if="detailShow">
       <WordPhraseDetail
         v-if="isSuccess"
@@ -321,9 +323,9 @@ export default {
         this.mp3List = mp3List;
       }
     },
-    handleChangeTab(){
-        this.wordShow = !this.wordShow
-    }
+    handleChangeTab() {
+      this.wordShow = !this.wordShow;
+    },
   },
   //生命周期 - 创建完成(可以访问当前this实例)
   created() {
@@ -363,21 +365,30 @@ export default {
 .NPC-zhedie {
   width: 780px;
   margin-bottom: 16px;
-
+  .NPC-word-list {
+    background: #f7f7f7;
+  }
   .NPC-word-table {
     width: 100%;
     > .NPC-word-tr {
       background: #fff;
       border-radius: 8px;
-      padding: 4px 0px 4px 0px;
+
       margin-bottom: 8px;
+
       .NPC-word-row {
         cursor: pointer;
         display: flex;
         justify-content: flex-start;
-        padding: 4px 16px 4px 16px;
-        &.active{
-          background:rgba(222, 68, 68, 0.15); 
+        padding: 8px 13px 8px 12px;
+        border-radius: 8px;
+        &.active {
+          background: linear-gradient(
+              0deg,
+              rgba(0, 0, 0, 0.08),
+              rgba(0, 0, 0, 0.08)
+            ),
+            #ffffff;
         }
         > span {
           font-size: 16px;
@@ -386,9 +397,17 @@ export default {
         }
       }
       .tabNum {
-        width: 28px;
-        text-align: right;
-        margin-left: 4px;
+        background: #de4444;
+        text-align: center;
+        width: 16px;
+        height: 16px;
+        color: #ffffff;
+        border-radius: 50%;
+        font-size: 12px;
+        font-family: "robot";
+        line-height: 16px;
+        margin-top: 4px;
+        margin-left: 8px;
       }
       .NPC-word-tab-common {
         padding-left: 8px;
@@ -409,7 +428,7 @@ export default {
         box-sizing: border-box;
       }
       .NPC-word-tab-def {
-        width: 296px;
+        flex: 1;
         font-family: "robot";
         word-break: break-word;
         box-sizing: border-box;
@@ -592,6 +611,9 @@ export default {
     .topTitle {
       background: #24b99e !important;
     }
+    .tabNum {
+      background: #24b99e;
+    }
   }
 }
 .NPC-Big-Book-preview-brown {
@@ -599,6 +621,9 @@ export default {
     .topTitle {
       background: #bd8865 !important;
     }
+    .tabNum {
+      background: #bd8865;
+    }
   }
 }
 </style>

+ 120 - 106
src/components/Adult/preview/components/WordPhraseDetail.vue

@@ -8,27 +8,29 @@
     }"
   >
     <div class="module-inner">
-      <div class="top" v-if="data && data.pinyin">
+      <div class="top" v-if="data">
         <div class="operation">
           <div>
-            <img
-              src="../../../../assets/adult/sc.png"
-              alt=""
-              v-if="!notshowNext"
-            />
-            <img
-              style="margin-right: 8px"
-              src="../../../../assets/adult/word-left.png"
-              alt=""
-              @click="lastDetail"
-              v-if="!notshowNext"
-            />
-            <img
-              src="../../../../assets/adult/word-right.png"
-              alt=""
-              @click="nextDetail"
-              v-if="!notshowNext"
-            />
+            <template v-if="optionRes && optionRes.length > 0">
+              <img
+                src="../../../../assets/adult/sc.png"
+                alt=""
+                v-if="!notshowNext"
+              />
+              <img
+                style="margin-right: 8px"
+                src="../../../../assets/adult/word-left.png"
+                alt=""
+                @click="lastDetail"
+                v-if="!notshowNext"
+              />
+              <img
+                src="../../../../assets/adult/word-right.png"
+                alt=""
+                @click="nextDetail"
+                v-if="!notshowNext"
+              />
+            </template>
             <img
               @click="closeWordShow"
               src="../../../../assets/adult/word-close.png"
@@ -46,7 +48,6 @@
                 ? 'red-border'
                 : 'brown-border',
             ]"
-            v-if="isShow"
           >
             <div
               class="strockplay"
@@ -82,97 +83,106 @@
                 <Audio :mp3="data.mp3_list[0].id" :themeColor="themeColor" />
               </template>
             </div>
-            <p class="jieshu" v-for="(fy, i) in data.definition_list" :key="i">
-              {{ fy }}
-            </p>
+            <p
+              class="jieshu"
+              v-for="(fy, i) in data.definition_list"
+              :key="i"
+              v-html="fy"
+            ></p>
           </div>
         </div>
         <div class="zhedie-white">
           <div v-if="data.list1.length > 0">
             <div class="topTitle">
-                <span>本课例句</span>
-                <span @click="handleChangeTab('wordShow')"
-                    >{{ wordShow ? "收起" : "展开" }}
-                    <img
-                    v-if="wordShow"
-                    src="../../../../assets/newImage/common/show-black.png"
-                    alt=""
-                    />
-                    <img
-                    v-else
-                    src="../../../../assets/newImage/common/hide-black.png"
-                    alt=""
-                    />
-                </span>
+              <span>本课例句</span>
+              <span @click="handleChangeTab('wordShow')"
+                >{{ wordShow ? "收起" : "展开" }}
+                <img
+                  v-if="wordShow"
+                  src="../../../../assets/newImage/common/show-black.png"
+                  alt=""
+                />
+                <img
+                  v-else
+                  src="../../../../assets/newImage/common/hide-black.png"
+                  alt=""
+                />
+              </span>
             </div>
             <el-collapse-transition>
-                <div class="liju" v-show="wordShow">
-                    <div v-for="(item, i) in data.list1" :key="i">
-                        <p v-html="item.res"></p>
-                    </div>
+              <div class="liju" v-show="wordShow">
+                <div v-for="(item, i) in data.list1" :key="i">
+                  <div>{{ i + 1 }}.</div>
+                  <div>
+                    <p v-html="item.res"></p>
+                    <p class="p2">
+                      来源:{{ item.source_courseware_name_path }}
+                    </p>
+                  </div>
                 </div>
+              </div>
             </el-collapse-transition>
           </div>
           <div v-if="data.list2.length > 0">
-                <div class="topTitle">
-                    <span>本书例句</span>
-                    <span @click="handleChangeTab('wordShow2')"
-                      >{{ wordShow2 ? "收起" : "展开" }}
-                      <img
-                        v-if="wordShow2"
-                        src="../../../../assets/newImage/common/show-black.png"
-                        alt=""
-                      />
-                      <img
-                        v-else
-                        src="../../../../assets/newImage/common/hide-black.png"
-                        alt=""
-                      />
-                    </span>
+            <div class="topTitle">
+              <span>本书例句</span>
+              <span @click="handleChangeTab('wordShow2')"
+                >{{ wordShow2 ? "收起" : "展开" }}
+                <img
+                  v-if="wordShow2"
+                  src="../../../../assets/newImage/common/show-black.png"
+                  alt=""
+                />
+                <img
+                  v-else
+                  src="../../../../assets/newImage/common/hide-black.png"
+                  alt=""
+                />
+              </span>
             </div>
             <el-collapse-transition>
-                <div class="liju" v-show="wordShow2">
-                  <div v-for="(item, i) in data.list2" :key="i">
-                    <div>{{ i + 1 }}.</div>
-                    <div>
-                      <p v-html="item.res"></p>
-                      <p class="p2">
-                        来源:{{ item.source_courseware_name_path }}
-                      </p>
-                    </div>
+              <div class="liju" v-show="wordShow2">
+                <div v-for="(item, i) in data.list2" :key="i">
+                  <div>{{ i + 1 }}.</div>
+                  <div>
+                    <p v-html="item.res"></p>
+                    <p class="p2">
+                      来源:{{ item.source_courseware_name_path }}
+                    </p>
                   </div>
                 </div>
+              </div>
             </el-collapse-transition>
           </div>
           <div v-if="data.list3.length > 0">
-                  <div class="topTitle">
-                    <span>本套教材例句</span>
-                    <span @click="handleChangeTab('wordShow3')"
-                      >{{ wordShow3 ? "收起" : "展开" }}
-                      <img
-                        v-if="wordShow3"
-                        src="../../../../assets/newImage/common/show-black.png"
-                        alt=""
-                      />
-                      <img
-                        v-else
-                        src="../../../../assets/newImage/common/hide-black.png"
-                        alt=""
-                      />
-                    </span>
-                  </div>
+            <div class="topTitle">
+              <span>本套教材例句</span>
+              <span @click="handleChangeTab('wordShow3')"
+                >{{ wordShow3 ? "收起" : "展开" }}
+                <img
+                  v-if="wordShow3"
+                  src="../../../../assets/newImage/common/show-black.png"
+                  alt=""
+                />
+                <img
+                  v-else
+                  src="../../../../assets/newImage/common/hide-black.png"
+                  alt=""
+                />
+              </span>
+            </div>
             <el-collapse-transition>
-                <div class="liju">
-                  <div v-for="(item, i) in data.list3" :key="i">
-                    <div>{{ data.list3.length + i + 1 }}.</div>
-                    <div>
-                      <p>{{ item.sentence }}</p>
-                      <p class="p2">
-                        来源:{{ item.source_courseware_name_path }}
-                      </p>
-                    </div>
+              <div class="liju">
+                <div v-for="(item, i) in data.list3" :key="i">
+                  <div>{{ data.list3.length + i + 1 }}.</div>
+                  <div>
+                    <p>{{ item.sentence }}</p>
+                    <p class="p2">
+                      来源:{{ item.source_courseware_name_path }}
+                    </p>
                   </div>
                 </div>
+              </div>
             </el-collapse-transition>
           </div>
         </div>
@@ -255,9 +265,9 @@ export default {
     return {
       height: "",
       margintop: "",
-      wordShow: false,
-      wordShow2: false,
-      wordShow3: false,
+      wordShow: true,
+      wordShow2: true,
+      wordShow3: true,
       list1: [],
       isShow: false,
       old_word: "",
@@ -322,16 +332,19 @@ export default {
       });
     },
     initData() {
-      if (this.curQue) {
-        this.isShow = true;
-        if (this.data.list1 && this.data.list1.length > 0) {
-          this.handleExample(this.data.list1);
-        }
-        if (this.data.list2 && this.data.list2.length > 0) {
-          this.handleExample(this.data.list2);
-        }
-        this.old_word = this.optionRes.new_word;
+      // if (this.curQue) {
+      //   this.isShow = true;
+      if (this.data.list1 && this.data.list1.length > 0) {
+        this.handleExample(this.data.list1);
+      }
+      if (this.data.list2 && this.data.list2.length > 0) {
+        this.handleExample(this.data.list2);
       }
+      if (this.data.list3 && this.data.list3.length > 0) {
+        this.handleExample(this.data.list3);
+      }
+      this.old_word = this.optionRes ? this.optionRes.new_word : "";
+      //}
       let Fathernode = document.getElementsByClassName(
         "NPC-Big-Book-preview"
       )[0];
@@ -341,9 +354,9 @@ export default {
         this.margintop = "-" + window.innerHeight / 2 + "px";
       }
     },
-    handleChangeTab(flag){
-        this[flag] = !this[flag]
-    }
+    handleChangeTab(flag) {
+      this[flag] = !this[flag];
+    },
   },
   //生命周期 - 创建完成(可以访问当前this实例)
   created() {},
@@ -484,6 +497,7 @@ export default {
             display: flex;
             align-items: center;
             margin-right: 8px;
+            word-break: normal;
           }
         }
       }
@@ -548,7 +562,7 @@ export default {
       .liju {
         padding-bottom: 16px;
         padding-right: 24px;
-        background: #F7F7F7;
+        background: #f7f7f7;
         border: 1px solid rgba(0, 0, 0, 0.1);
         border-top: none;
         border-radius: 0 0 4px 4px;

+ 18 - 33
src/components/Adult/preview/components/Wordcard.vue

@@ -80,10 +80,7 @@
       class="bwc-word-en"
       v-if="word.detail && word.detail.definition_list.length > 0"
     >
-      <span v-for="(item, index) in word.detail.definition_list" :key="index">
-        {{ item
-        }}{{ index == word.detail.definition_list.length - 1 ? "" : ";" }}
-      </span>
+      <span v-html="defStr"> </span>
     </div>
     <div class="bwc-more-intp" @click="viewIntp">更多释义</div>
     <div class="bwc-footer">
@@ -131,7 +128,7 @@
     </div>
     <div class="practiceBox" v-if="isIntpShow">
       <WordPhraseDetail
-        :closeWord ="changeIntpShow"
+        :closeWord="changeIntpShow"
         :data="word.detail"
         :themeColor="themeColor"
       />
@@ -145,6 +142,7 @@ import Strockplayredline from "./Strockplayredline.vue";
 import Practice from "./Practice.vue";
 import WordPhraseDetail from "./WordPhraseDetail.vue";
 import { getContentFile, getContent } from "@/api/ajax";
+
 export default {
   name: "Wordcard",
   components: {
@@ -159,22 +157,16 @@ export default {
       isPraShow: false,
       isIntpShow: false,
       curData: null,
+      defStr: "",
     };
   },
   computed: {},
   watch: {
     word: {
       handler: function (val, oldVal) {
-        let _this = this;
-        // this.curData = {
-        //   stem: [
-        //     {
-        //       con: val.detail && val.detail.new_word ? val.detail.new_word : "",
-        //       pinyin: val.detail && val.detail.pinyin ? val.detail.pinyin : "",
-        //       mp3_url: "",
-        //     },
-        //   ],
-        // };
+        if (val && val.detail) {
+          this.defStr = val.detail.definition_list.join(";");
+        }
       },
       // 深度观察监听
       deep: true,
@@ -206,6 +198,7 @@ export default {
       this.isPraShow = false;
     },
     viewIntp() {
+      debugger;
       this.isIntpShow = false;
       this.word.detail.list1 = [];
       this.word.detail.list2 = [];
@@ -219,14 +212,14 @@ export default {
         search_scope: 2, //检索范围0 本课件  1本教材 2本套
         is_contain_word_variants: false,
       }).then((res) => {
-        this.word.detail.list3 = res.sentence_list;
+        this.$set(this.word.detail, "list3", res.sentence_list);
         getContent(Mname, {
           courseware_id: this.currentTreeID, // 课件id
           word: this.word.detail.new_word, //生词
           search_scope: 1, //检索范围0 本课件  1本教材 2本套
           is_contain_word_variants: false,
         }).then((res) => {
-          this.word.detail.list2 = res.sentence_list;
+          this.$set(this.word.detail, "list2", res.sentence_list);
           getContent(Mname, {
             courseware_id: this.currentTreeID, // 课件id
             word: this.word.detail.new_word, //生词
@@ -250,22 +243,14 @@ export default {
   //生命周期 - 挂载完成(可以访问DOM元素)
   mounted() {
     let _this = this;
-    if (this.word) {
-      //   this.curData = {
-      //     stem: [
-      //       {
-      //         con:
-      //           _this.word.detail && _this.word.detail.new_word
-      //             ? _this.word.detail.new_word
-      //             : "",
-      //         pinyin:
-      //           _this.word.detail && _this.word.detail.pinyin
-      //             ? _this.word.detail.pinyin
-      //             : "",
-      //         mp3_url: "",
-      //       },
-      //     ],
-      //   };
+    console.log("this.word====");
+    console.log(this.word);
+    if (_this.word && _this.word.detail) {
+      _this.defStr =
+        _this.word.detail.definition_list &&
+        _this.word.detail.definition_list.length > 0
+          ? _this.word.detail.definition_list.join(";")
+          : "";
     }
   },
   beforeCreate() {}, //生命周期 - 创建之前

+ 0 - 3
src/views/adultInput.vue

@@ -718,8 +718,6 @@ import VideoControl from "@/components/Adult/inputModules/VideoControl.vue";
 import Table from "@/components/Adult/inputModules/Table.vue";
 import PlayRecord from "@/components/Adult/inputModules/PlayRecord.vue";
 
-
-
 import Textdes from "@/components/Adult/inputModules/Textdes.vue";
 import Record from "@/components/Adult/inputModules/Record.vue";
 import Hanzi from "@/components/Adult/inputModules/Hanzi.vue";
@@ -742,7 +740,6 @@ import SentenceSortQP from "@/components/Adult/preview/SentenceSortQP.vue";
 import TableView from "@/components/Adult/preview/TableView.vue";
 import PlayRecordView from "@/components/Adult/preview/PlayRecordView.vue";
 
-
 import DialogueAnswerViewChs from "@/components/Adult/preview/DialogueArticleViewChs/DialogueAnswerViewChs.vue";
 import Preview from "@/components/Adult/Preview.vue";
 import fn from "@/components/Adult/common/data.js";

+ 1 - 0
vue.config.js

@@ -43,6 +43,7 @@ module.exports = {
       // detail: https://cli.vuejs.org/config/#devserver-proxy
       [process.env.VUE_APP_BASE_API]: {
         target: `http://gcls.utschool.cn/`,
+        //target: `http://gcls.helxsoft.cn/`,
         changeOrigin: true,
         pathRewrite: {
           ['^' + process.env.VUE_APP_BASE_API]: ''