natasha преди 1 година
родител
ревизия
3c36679de2

+ 16 - 7
src/views/bookShelf/articleDetail.vue

@@ -21,6 +21,7 @@
             <!-- 文章 -->
             <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"></phrase-model>
                 <div class="article-btn">
                     <div class="left">
                         <span :class="['support colloct-article',!noRead?'active':'']" @click="changeStatus('noRead')"><svg-icon icon-class="like-line"></svg-icon>2847</span>
@@ -48,12 +49,18 @@
                 </div>
                 <el-collapse-transition >
                     <div v-if="showGlossary">
-                        <h4 :style="{color:bgColorList[activeIndex].glossarySubtitle}">生词</h4>
-                        <new-word-list class="newWord-list" :list="articleInfo.art_voc_data" :style="{background:bgColorList[activeIndex].glossaryBg}" :colorObj="bgColorList[activeIndex]" :likeWordList="likeWordList" @changeLike="changeLike"></new-word-list>
-                        <h4 :style="{color:bgColorList[activeIndex].glossarySubtitle}">短语</h4>
-                        <phrase-list class="newWord-list" :list="articleInfo.art_phrase_data" :style="{background:bgColorList[activeIndex].glossaryBg}" :colorObj="bgColorList[activeIndex]" :likePhraseList="likePhraseList" @changeLike="changeLike"></phrase-list>
-                        <h4 :style="{color:bgColorList[activeIndex].glossarySubtitle}">注释</h4>
-                        <annotation-list class="newWord-list" :list="articleInfo.art_explain_data" :style="{background:bgColorList[activeIndex].glossaryBg}" :colorObj="bgColorList[activeIndex]"></annotation-list>
+                        <template v-if="articleInfo.art_voc_data.length>0">
+                            <h4 :style="{color:bgColorList[activeIndex].glossarySubtitle}">生词</h4>
+                            <new-word-list class="newWord-list" :list="articleInfo.art_voc_data" :style="{background:bgColorList[activeIndex].glossaryBg}" :colorObj="bgColorList[activeIndex]" :likeWordList="likeWordList" @changeLike="changeLike"></new-word-list>
+                        </template>
+                        <template v-if="articleInfo.art_phrase_data.length>0">
+                            <h4 :style="{color:bgColorList[activeIndex].glossarySubtitle}">短语</h4>
+                            <phrase-list class="newWord-list" :list="articleInfo.art_phrase_data" :style="{background:bgColorList[activeIndex].glossaryBg}" :colorObj="bgColorList[activeIndex]" :likePhraseList="likePhraseList" @changeLike="changeLike"></phrase-list>
+                        </template>
+                        <template v-if="articleInfo.art_explain_data.length>0">
+                            <h4 :style="{color:bgColorList[activeIndex].glossarySubtitle}">注释</h4>
+                            <annotation-list class="newWord-list" :list="articleInfo.art_explain_data" :style="{background:bgColorList[activeIndex].glossaryBg}" :colorObj="bgColorList[activeIndex]"></annotation-list>
+                        </template>
                     </div>
                 </el-collapse-transition>
                 <div class="title" :style="{color:bgColorList[activeIndex].glossaryTitle,marginTop:'40px'}">
@@ -125,6 +132,7 @@ import NewWordList from './components/NewWordList.vue';
 import PhraseList from './components/PhraseList.vue';
 import AnnotationList from './components/AnnotationList.vue'
 import NormalModel from "./components/NormalModel.vue"
+import PhraseModel from "./components/PhraseModel.vue"
 import MenuRight from "./components/MenuRight.vue"
 import * as echarts from "echarts";
 import { getLogin } from "@/api/ajax";
@@ -140,7 +148,8 @@ export default {
     PhraseList,
     AnnotationList,
     NormalModel,
-    MenuRight
+    MenuRight,
+    PhraseModel
   },
   data(){
     return{

+ 37 - 3
src/views/bookShelf/components/NormalModel.vue

@@ -10,8 +10,32 @@
                 )
                 "
                 @mouseover="handleMouseover(resArr[0])"
-                @mouseleave="handleMouseleave">
-            <span v-for="(itemR,indexR) in resArr[0].wordsList" :key="indexR" :style="{color:colorObj.titleColor,fontSize:(wordFontsize+30)+'px',lineHeight:(wordFontsize+38)+'px',marginRight:'8px',fontWeight:'700',cursor:'pointer'}">
+                @mouseleave="handleMouseleave"
+                :class="[
+                    'NNPE-words',
+                    isPlaying &&
+                    resArr[0].timeList &&
+                    resArr[0].timeList[0] &&
+                    curTime >= resArr[0].timeList[0].s &&
+                    curTime <= resArr[0].timeList[0].e
+                        ? 'sentActive'
+                        : '',
+                    resArr[0].wordsList[0].pno == paraIndex && resArr[0].wordsList[0].sno == sentIndex
+                        ? 'overActive'
+                        : '',
+                ]">
+            <span v-for="(itemR,indexR) in resArr[0].wordsList" :key="indexR" :style="{color:colorObj.titleColor,fontSize:(wordFontsize+30)+'px',lineHeight:(wordFontsize+38)+'px',marginRight:'8px',fontWeight:'700',cursor:'pointer'}" 
+            :class="[
+                    isPlaying &&
+                    resArr[0].timeList &&
+                    resArr[0].timeList[0] &&
+                    curTime >=
+                        resArr[0].timeList[0].tokens[indexR].s &&
+                    curTime <= resArr[0].timeList[0].e
+                        ? 'wordActive'
+                        : '',
+                    itemR.tokens[9]===' '?'marginRight':''
+                ]">
                 {{itemR.tokens[2]}}</span>
         </h2>
     </template>
@@ -318,7 +342,6 @@ export default {
       this.resArr = resArr;
     },
     handleChangeTime(time) {
-        console.log(time)
       if (time>=0) {
         this.curTime = time;
         this.$refs.audioLine.onTimeupdateTime(time / 1000, true);
@@ -372,6 +395,17 @@ export default {
           text-align: right;
       }
   }
+  h2{
+    &.sentActive {
+        background: rgba(24, 144, 255, 0.1);
+    }
+    &.overActive {
+        background: rgba(0, 0, 0, 0.06);
+    }
+    .wordActive {
+        color: #175DFF !important;
+    }
+  }
   .table-box {
     // background: #f7f7f7;
     // border-top: 1px solid rgba(0, 0, 0, 0.1);

+ 660 - 0
src/views/bookShelf/components/PhraseModel.vue

@@ -0,0 +1,660 @@
+<!--  -->
+<template>
+  <div class="NNPE-ArticleView" v-if="articleInfo">
+    <template v-if="resArr[0]&&resArr[0].wordsList[0].pno===0">
+        <h2>
+            <span v-for="(itemR,indexR) in resArr[0].wordsList" :key="indexR" :style="{color:colorObj.titleColor,fontSize:(wordFontsize+30)+'px',lineHeight:(wordFontsize+38)+'px',marginRight:'8px',fontWeight:'700',cursor:'pointer'}" 
+            :class="[
+                    itemR.tokens[9]===' '?'marginRight':''
+                ]">
+                {{itemR.tokens[2]}}</span>
+        </h2>
+    </template>
+    <h6 class="nnpe-article-author" :style="{color:colorObj.sourceColor,fontSize:(wordFontsize-4)+'px',lineHeight:(wordFontsize+4)+'px',fontWeight:'400'}">
+        {{articleInfo.art_author+' · '+articleInfo.study_phase_name+'版 · 第 '+articleInfo.iss_no+' 期 · '+articleInfo.release_date+' · '+articleInfo.chn_item+(articleInfo.page_no_in_pub?' · P'+articleInfo.page_no_in_pub:'')}}
+    </h6>
+    <div class="audio-box">
+        <div
+            class="aduioLine-content aduioLine-box"
+            v-if="
+                articleInfo.art_sound_url
+            " :style="{background:colorObj.audiobg,borderColor:colorObj.audioBorder}"
+        >
+            <AudioLine
+                audioId="artNormalAudio"
+                :mp3="articleInfo.art_sound_url"
+                :getCurTime="getCurTime"
+                ref="audioLine"
+                :mp3Source="'mp3'"
+            />
+            <svg-icon icon-class="icon-wrapper" class="wrapper"></svg-icon>
+        </div>
+    </div>
+    <template v-if="resArr.length > 0">
+      <div class="table-box">
+        <div
+          :class="['NNPE-detail']"
+          v-for="(item, index) in resArr"
+          :key="'detail' + index"
+        >
+          <div class="wordsList-box">
+            <!-- class="nnpr-sentence-box-new" -->
+            <div class="nnpe-sentence-box">
+              <div v-for="(pItem, pIndex) in item.wordsList" :key="'wordsList' + pIndex">
+                <template v-if="pItem.pno!==0">
+                    <template v-if="pItem.isShow">
+                    <div
+                        :class="[
+                        'NNPE-words',
+                        ]"
+                    >
+                            <span
+                                class="NNPE-chs"
+                                :class="[
+                                    
+                                    pItem.tokens[9]===' '?'marginRight':''
+                                ]"
+                                :style="{fontSize:wordFontsize + 'px',color: colorObj.contentColor}"
+                                >{{ pItem.tokens[2] }}</span
+                            >
+                            <span
+                            class="NNPE-chs NNPE-chs-both"
+                            v-if="item.wordsList[pIndex + 1] &&
+                            item.wordsList[pIndex + 1].tokens[2] &&
+                            enFhList.indexOf(item.wordsList[pIndex + 1].tokens[2]) > -1"
+                            :class="[
+                                    item.wordsList[pIndex + 1].tokens[9]===' '?'marginRight':''
+                                ]"
+                                :style="{fontSize:wordFontsize + 'px',color: colorObj.contentColor}"
+                            >{{ item.wordsList[pIndex + 1].tokens[2] }}</span
+                        >
+                    </div>
+                    </template>
+                </template>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </template>
+
+    <!-- <img src="../../../assets/article-img.png" style="max-width:100%;margin:24px 0;" /> -->
+  </div>
+</template>
+
+<script>
+import AudioLine from "@/components/common/AudioLine.vue"
+export default {
+  name: "ArticleView",
+  props: [ "titleFontsize", "wordFontsize", "colorObj","articleType","articleInfo"],
+  components: {
+    AudioLine,
+  },
+  data() {
+    return {
+      resArr: [],
+      curTime: 0, //单位s
+      chsFhList: [",", "。", "“", ":", "》", "《", "?", "!", ";", "("],
+      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",
+        "”",
+      ],
+      lastEnFhlist: [',','.',';',':','?','!'],
+      firstEnFhlist: ["'","‘","“",'"',"("],
+      noPaddingList: ['(', '"'],
+      articleImg: {}, // 文章图片
+      paraIndex: -1, //段落索引
+      sentIndex: -1, // 句子索引
+      paraNumber: 1,
+      
+    };
+  },
+  computed: {
+    isPlaying: function () {
+      let playing = false;
+      if (this.$refs.audioLine) {
+        playing = this.$refs.audioLine.audio.isPlaying;
+      }
+      return playing;
+    },
+  },
+  watch: {},
+  //方法集合
+  methods: {
+    getCurTime(curTime) {
+      this.curTime = curTime * 1000;
+    },
+    handleData() {
+      let _this = this;
+      _this.paraNumber = 1
+      let resArr = [];
+    //   let leg = this.curQue.detail.length;
+    //   let curQue = JSON.parse(JSON.stringify(this.curQue));
+    //   curQue.detail.forEach((dItem, dIndex) => {
+    //     let paraArr = [];
+    //     if (dItem.paragraphAttr&&dItem.paragraphAttr.paragraphIndentation&&!dItem.isTitle) {
+    //       paraArr = [
+    //         {
+    //           width: 9,
+    //           height: 20,
+    //         },
+    //         {
+    //           width: 9,
+    //           height: 20,
+    //         },
+    //       ];
+    //     }
+    //     dItem.segList.forEach((sItem, sIndex) => {
+    //       sItem.forEach((wItem, wIndex) => {
+    //           let styles = ''
+    //           if(dItem.wordStyle&&dItem.wordStyle[sIndex]&&dItem.wordStyle[sIndex][wIndex]){
+    //               for(let k in dItem.wordStyle[sIndex][wIndex]){
+    //                 if(dItem.wordStyle[sIndex][wIndex][k]&&k!='styleList'&&k!='paddingList'){
+    //                     styles += dItem.wordStyle[sIndex][wIndex][k]+' '
+    //                 }else if(k =='styleList'||k=='paddingList'){
+    //                     dItem.wordStyle[sIndex][wIndex][k].forEach(itemK=>{
+    //                         styles += itemK + ' '
+    //                     })
+    //                 }
+    //             }  
+    //           }
+    //         let obj = {
+    //           paraIndex: dIndex, //段落索引
+    //           sentIndex: sIndex, //在段落中句子索引
+    //           wordIndex: wIndex, //单词的索引
+    //           en: wItem,
+    //           padding: true,
+    //           isShow: this.mergeWordSymbol(wItem),
+    //           className: styles,
+    //         };
+    //         //this.judgePad(sItem, obj, wIndex);
+    //         paraArr.push(obj);
+    //       });
+    //     });
+
+    //     let curSentencesLeg = dItem.sentences.length;
+    //     let startLeg = dIndex == 0 ? 0 : curQue.detail[dIndex - 1].endLeg;
+    //     let endLeg = startLeg + curSentencesLeg;
+    //     dItem.endLeg = endLeg;
+    //     let timeList = curQue.wordTime.slice(startLeg, endLeg);
+
+    //     if(dItem.isTitle||(dItem.isLittleTitle&&dItem.paragraphAttr.paragraphLittleNumber&&dItem.paragraphAttr.paragraphLittleNumber==false)||(dItem.isLittleTitle&&!dItem.paragraphAttr.paragraphLittleNumber) || (dItem.paragraphAttr&&!dItem.paragraphAttr.paragraphNumber)){
+    //         dItem.paraNumber = ''
+    //     }else{
+    //         dItem.paraNumber = _this.paraNumber
+    //         _this.paraNumber ++
+    //     }
+    //     let paraObj = {
+    //       wordsList: paraArr,
+    //       timeList: timeList,
+    //       isTitle: dItem.isTitle,
+    //       paraNumber: dItem.paraNumber
+    //     };
+    //     resArr.push(paraObj);
+    //   });
+    //   this.resArr = resArr;
+    //   // 循环文章图片
+    //   if (curQue.img_list) {
+    //     curQue.img_list.forEach((item) => {
+    //       _this.articleImg[item.imgNumber] = item.id;
+    //     });
+    //   }
+      let articleInfo = JSON.parse(JSON.stringify(this.articleInfo));
+      let leg = articleInfo.art_corpus_data.sentList[articleInfo.art_corpus_data.sentList.length-1].pno
+      for(let i=0;i<leg+1;i++){
+        let obj = {
+            wordsList: [],
+            timeList: [],
+        }
+        resArr.push(obj)
+      }
+      articleInfo.art_corpus_data.sentList.forEach((item,index) => {
+        item.tokens.forEach((items,indexs)=>{
+            let obj = {
+                sent_id:item.id,
+                sno: item.sno-1,
+                pno: item.pno,
+                text: item.text,
+                tokens: items,
+                isShow: this.enFhList.indexOf(items[2])==-1
+            }
+            resArr[item.pno].wordsList.push(obj)
+        })
+        resArr[item.pno].timeList.push(articleInfo.art_sound_srt_data.sents[index])
+      });
+      this.resArr = resArr;
+    },
+    handleChangeTime(time) {
+      if (time>=0) {
+        this.curTime = time;
+        this.$refs.audioLine.onTimeupdateTime(time / 1000, true);
+      }
+    },
+    //经过每个词,高亮句子
+    handleMouseover(pItem) {
+      this.paraIndex = pItem.pno;
+      this.sentIndex = pItem.sno;
+    },
+    handleMouseleave() {
+      this.paraIndex = -1;
+      this.sentIndex = -1;
+    },
+  },
+  //生命周期 - 创建完成(可以访问当前this实例)
+  created() {},
+  //生命周期 - 挂载完成(可以访问DOM元素)
+  mounted() {
+    if (this.articleInfo) {
+      this.handleData();
+    }
+  },
+  beforeCreate() {}, //生命周期 - 创建之前
+  beforeMount() {}, //生命周期 - 挂载之前
+  beforeUpdate() {}, //生命周期 - 更新之前
+  updated() {}, //生命周期 - 更新之后
+  beforeDestroy() {}, //生命周期 - 销毁之前
+  destroyed() {}, //生命周期 - 销毁完成
+  activated() {}, //如果页面有keep-alive缓存功能,这个函数会触发
+};
+</script>
+<style lang='scss' scoped>
+//@import url(); 引入公共css类
+.NNPE-ArticleView {
+  width: 100%;
+  .nnpe-article-author{
+      margin: 24px 0;
+      &.nnpe-article-author-left{
+          text-align: left;
+      }
+      &.nnpe-article-author-right{
+          text-align: right;
+      }
+  }
+  h2{
+    &.sentActive {
+        background: rgba(24, 144, 255, 0.1);
+    }
+    &.overActive {
+        background: rgba(0, 0, 0, 0.06);
+    }
+    .wordActive {
+        color: #175DFF !important;
+    }
+  }
+  .table-box {
+    // background: #f7f7f7;
+    // border-top: 1px solid rgba(0, 0, 0, 0.1);
+    :last-child {
+      :last-child.wordsList-box {
+        padding-bottom: 40px;
+      }
+    }
+    .index {
+      width: 48px;
+      box-sizing: border-box;
+      padding: 8px;
+      text-align: right;
+      border-right: 1px solid rgba(0, 0, 0, 0.1);
+      b {
+        font-weight: 400;
+        color: #000000;
+        line-height: 1.5;
+      }
+    }
+    .wordsList-box {
+      flex: 1;
+      padding: 6px 0 12px 0;
+      &.wordsList-box-indent{
+          padding-left: 42px;
+      }
+      .nnpe-sentence-box {
+        display: flex;
+        flex-flow: wrap;
+        &.nnpe-sentence-box-right{
+            justify-content: flex-end;
+        }
+        .nnpe-paragraph-con{
+            line-height: 24px;
+            padding: 0 3px;
+        }
+        .nnpr-sentence-box-new{
+            clear: both;
+            overflow: hidden;
+        }
+      }
+      > img {
+        max-width: 50%;
+        display: block;
+        padding: 16px 0;
+        margin: 0 auto;
+      }
+    }
+  }
+  .NNPE-detail {
+    clear: both;
+    overflow: hidden;
+    display: flex;
+    &.NNPE-detail-title {
+      .wordsList-box {
+        > div {
+          display: flex;
+          justify-content: center;
+        }
+      }
+    }
+    &.NNPE-detail-title-left {
+      .wordsList-box {
+        .nnpe-sentence-box {
+          justify-content: flex-start;
+        }
+      }
+    }
+    &.NNPE-detail-title-right {
+      .wordsList-box {
+        .nnpe-sentence-box {
+          justify-content: flex-end;
+        }
+      }
+    }
+    &.NNPE-detail-littleTitle{
+        margin-bottom: -18px;
+    }
+    .NNPE-words {
+      float: left;
+      padding: 0;
+      &.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;
+          &.wordActive {
+            color: #175DFF !important;
+          }
+          &.marginRight{
+            padding: 0 6px 0 0;
+          }
+        }
+        &.padding {
+          padding: 0 3px;
+          cursor: pointer;
+        }
+      }
+    }
+  }
+}
+.audio-box{
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    .explain-video{
+        background: #FFB224;
+        border-color: #FFB224;
+        color: #FFFFFF;
+        width: 136px;
+        height: 48px;
+        padding: 0;
+        font-weight: 500;
+        font-size: 16px;
+        border-radius: 30px;
+        .svg-icon{
+            margin-right: 8px;
+        }
+    }
+}
+.aduioLine-box{
+    width: 516px;
+    height: 48px;
+    background: #FFFFFF;
+    border: 1px solid #EBEBEB;
+    border-radius: 30px;
+    display: flex;
+    align-items: center;
+    padding: 8px 24px;
+    .wrapper{
+        width: 24px;
+        height: 24px;
+        flex-shrink: 0;
+        color: #175DFF;
+        margin-left: 8px;
+    }
+    .Audio{
+        width: 430px;
+    }
+}
+</style>
+<style lang="scss">
+.words-notes {
+  position: fixed;
+  width: 475px;
+  z-index: 2;
+  .close-btn {
+    position: absolute;
+    width: 32px;
+    height: 32px;
+    box-shadow: 0px 4px 24px rgba(0, 0, 0, 0.25);
+    // background: url("../../../../assets/newImage/common/icon-close-write.png")
+    //   center no-repeat;
+    background-size: cover;
+    top: -40px;
+    right: 0px;
+    border-radius: 40px;
+  }
+  .words-top {
+    background: #ffffff;
+    box-shadow: 0px 4px 24px rgba(0, 0, 0, 0.25);
+    border-radius: 8px;
+    margin-bottom: 10px;
+    padding: 8px 24px;
+    > div {
+      display: flex;
+    }
+    p {
+      font-size: 16px;
+      line-height: 150%;
+      color: #000000;
+      margin: 8px 0;
+      &.hasCn{
+        font-family: 'Smartisan';
+      }
+    }
+    b {
+      font-size: 16px;
+      line-height: 150%;
+      color: #000000;
+      margin: 8px 16px;
+      max-width: 70%;
+      word-break: break-word;
+    }
+    .shiyi {
+      margin-left: 16px;
+      font-size: 16px;
+      line-height: 150%;
+      color: #000000;
+      flex: 1;
+    }
+  }
+  .words-bottom {
+    background: #ffffff;
+    box-shadow: 0px 4px 24px rgba(0, 0, 0, 0.25);
+    border-radius: 8px;
+    padding: 16px 24px 24px 40px;
+    max-height: 350px;
+    overflow: auto;
+    h3 {
+      text-align: right;
+      font-size: 14px;
+      line-height: 16px;
+      font-weight: normal;
+      color: rgba($color: #000000, $alpha: 0.2);
+      margin: 0;
+    }
+    b {
+      font-size: 24px;
+      line-height: 28px;
+      margin: 8px 0 16px 0;
+      color: #000000;
+      display: block;
+    }
+    span {
+      font-size: 16px;
+      line-height: 150%;
+      color: #000000;
+      display: flex;
+      align-items: center;
+      a {
+        margin: 0 0 0 8px;
+      }
+    }
+    .voice-box {
+      display: flex;
+      :first-child {
+        a {
+          margin-right: 24px;
+        }
+      }
+    }
+    .shiyi {
+      padding: 11px 0 2px 0;
+      max-height: 116px;
+      overflow: hidden;
+      > div {
+        display: flex;
+        margin: 5px 0;
+      }
+      b {
+        font-weight: normal;
+        font-size: 16px;
+        line-height: 150%;
+        color: #000000;
+        margin: 0 4px 0 0;
+        //   width: ;
+      }
+      p {
+        font-size: 16px;
+        line-height: 150%;
+        color: #000000;
+        width: 350px;
+        margin: 0;
+      }
+      .hasCn{
+        font-family: 'Smartisan';
+      }
+    }
+    .text-right {
+      text-align: right;
+      a {
+        // background: url("../../../../assets/adult/detail.png") center right
+        //   no-repeat;
+        background-size: 24px;
+        padding-right: 26px;
+        color: #000000;
+        opacity: 0.3;
+      }
+    }
+  }
+  .play {
+    width: 16px;
+    height: 16px;
+    cursor: pointer;
+    display: inline-block;
+    margin: 12px 0;
+    &.playBtn {
+    //   background: url("../../../../assets/NNPE/icon-voice.png")
+    //     no-repeat left top;
+      background-size: 100% 100%;
+    }
+    &.voice-playing {
+    //   background: url("../../../../assets/NNPE/icon-voice-play-blue.png")
+    //     no-repeat left top;
+      background-size: 100% 100%;
+    }
+  }
+}
+.words-annotation {
+  position: fixed;
+  z-index: 2;
+  background: #394D95;
+  box-shadow: 0px 4px 24px rgba(0, 0, 0, 0.25);
+  border-radius: 8px;
+  width: 345px;
+  padding: 16px;
+  .close-btn {
+    position: absolute;
+    width: 32px;
+    height: 32px;
+    box-shadow: 0px 4px 24px rgba(0, 0, 0, 0.25);
+    // background: url("../../../../assets/NNPE/icon-close-blue.png")
+    //   center no-repeat;
+    background-size: cover;
+    top: -32px;
+    right: -32px;
+    border-radius: 40px;
+  }
+  b {
+    display: block;
+    font-size: 16px;
+    line-height: 19px;
+    color: #ffffff;
+    margin-bottom: 8px;
+    word-break: break-word;
+  }
+  p {
+    font-size: 16px;
+    line-height: 19px;
+    color: #ffffff;
+  }
+}
+</style>

+ 4 - 4
src/views/personalCenter/components/WordCard.vue

@@ -1,5 +1,5 @@
 <template>
-  <div class="word-card" v-if="" v-loading="loading">
+  <div class="word-card" v-loading="loading">
     <div class="word-card-top">
         <span class="progress">1 / 10</span>
         <div class="btn-box">
@@ -10,13 +10,13 @@
         </div>
     </div>
     <div class="word-card-center">
-        <div class="word-card-center-box">
+        <div class="word-card-center-box" v-if="data.rate||data.typeC">
             <span class="star word-card-rate">
                 <template v-if="data.rate">
                     <svg-icon icon-class="star-filled" v-for="(itemS,indexS) in data.rate" :key="indexS" :style="{color:'#FFB224'}"></svg-icon>
                 </template>
             </span>
-            <span class="wordType">{{data.typeCn}}</span>
+            <span class="wordType" v-if="data.typeCn">{{data.typeCn}}</span>
         </div>
         <h3 class="word">{{data.word}}</h3>
         <div class="symbol-box">
@@ -32,7 +32,7 @@
             </div>
         </div>
         <el-divider content-position="left">例句</el-divider>
-        <div class="number-list">
+        <div class="number-list" v-if="sentKwicData">
             <div class="number-item" :class="[activeIndex===0?'active':'']" @click="handleLookStore(0)">
                 <label>全部</label>
                 <span>{{sentKwicData.total}}</span>