|  | @@ -0,0 +1,307 @@
 | 
	
		
			
				|  |  | +<!--  -->
 | 
	
		
			
				|  |  | +<template>
 | 
	
		
			
				|  |  | +  <div class="NNPE-ArticleView" v-if="curQue">
 | 
	
		
			
				|  |  | +    <AudioLine
 | 
	
		
			
				|  |  | +      :mp3="curQue.mp3_list[0].url"
 | 
	
		
			
				|  |  | +      :getCurTime="getCurTime"
 | 
	
		
			
				|  |  | +      ref="audioLine"
 | 
	
		
			
				|  |  | +    />
 | 
	
		
			
				|  |  | +    <template v-if="resObj">
 | 
	
		
			
				|  |  | +      <div
 | 
	
		
			
				|  |  | +        class="NNPE-detail"
 | 
	
		
			
				|  |  | +        v-for="(item, index) in resObj.sentList"
 | 
	
		
			
				|  |  | +        :key="'detail' + index"
 | 
	
		
			
				|  |  | +        @click="handleChangeTime(resObj.timeList[index])"
 | 
	
		
			
				|  |  | +      >
 | 
	
		
			
				|  |  | +        <div
 | 
	
		
			
				|  |  | +          class="NNPE-words"
 | 
	
		
			
				|  |  | +          v-for="(pItem, pIndex) in item"
 | 
	
		
			
				|  |  | +          :key="'wordsList' + pIndex"
 | 
	
		
			
				|  |  | +          :class="[pItem.wordIndex == 0 ? 'textLeft' : 'textCenter']"
 | 
	
		
			
				|  |  | +        >
 | 
	
		
			
				|  |  | +          <template v-if="!pItem.width">
 | 
	
		
			
				|  |  | +            <span
 | 
	
		
			
				|  |  | +              class="NNPE-pinyin"
 | 
	
		
			
				|  |  | +              :class="[
 | 
	
		
			
				|  |  | +                pItem.padding ? 'padding' : '',
 | 
	
		
			
				|  |  | +                pItem.className ? pItem.className : '',
 | 
	
		
			
				|  |  | +              ]"
 | 
	
		
			
				|  |  | +              >{{ pItem.pinyin }}</span
 | 
	
		
			
				|  |  | +            >
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            <span
 | 
	
		
			
				|  |  | +              class="NNPE-chs"
 | 
	
		
			
				|  |  | +              :class="[
 | 
	
		
			
				|  |  | +                curTime >= resObj.timeList[index] &&
 | 
	
		
			
				|  |  | +                curTime <= resObj.timeList[index + 1] &&
 | 
	
		
			
				|  |  | +                curTime >= pItem.startTime
 | 
	
		
			
				|  |  | +                  ? 'active'
 | 
	
		
			
				|  |  | +                  : '',
 | 
	
		
			
				|  |  | +                pItem.padding ? 'padding' : '',
 | 
	
		
			
				|  |  | +              ]"
 | 
	
		
			
				|  |  | +              >{{ pItem.chs }}</span
 | 
	
		
			
				|  |  | +            >
 | 
	
		
			
				|  |  | +          </template>
 | 
	
		
			
				|  |  | +          <template v-else>
 | 
	
		
			
				|  |  | +            <span
 | 
	
		
			
				|  |  | +              :style="{
 | 
	
		
			
				|  |  | +                height: pItem.height + 'px',
 | 
	
		
			
				|  |  | +                width: pItem.width + 'px',
 | 
	
		
			
				|  |  | +              }"
 | 
	
		
			
				|  |  | +            ></span>
 | 
	
		
			
				|  |  | +          </template>
 | 
	
		
			
				|  |  | +        </div>
 | 
	
		
			
				|  |  | +      </div>
 | 
	
		
			
				|  |  | +    </template>
 | 
	
		
			
				|  |  | +  </div>
 | 
	
		
			
				|  |  | +</template>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +<script>
 | 
	
		
			
				|  |  | +import { timeStrToSen } from "@/utils/index";
 | 
	
		
			
				|  |  | +import AudioLine from "../AudioLine.vue";
 | 
	
		
			
				|  |  | +export default {
 | 
	
		
			
				|  |  | +  name: "ArticleView",
 | 
	
		
			
				|  |  | +  props: ["curQue"],
 | 
	
		
			
				|  |  | +  components: {
 | 
	
		
			
				|  |  | +    AudioLine,
 | 
	
		
			
				|  |  | +  },
 | 
	
		
			
				|  |  | +  data() {
 | 
	
		
			
				|  |  | +    return {
 | 
	
		
			
				|  |  | +      resObj: null,
 | 
	
		
			
				|  |  | +      curTime: 0, //单位s
 | 
	
		
			
				|  |  | +      chsFhList: [",", "。", "“", ":", "》", "《", "?", "!", ";"],
 | 
	
		
			
				|  |  | +      enFhList: [",", ".", ";", "?", "!", ":", ">", "<"],
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +  },
 | 
	
		
			
				|  |  | +  computed: {},
 | 
	
		
			
				|  |  | +  watch: {},
 | 
	
		
			
				|  |  | +  //方法集合
 | 
	
		
			
				|  |  | +  methods: {
 | 
	
		
			
				|  |  | +    getCurTime(curTime) {
 | 
	
		
			
				|  |  | +      this.curTime = curTime;
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +    handleData() {
 | 
	
		
			
				|  |  | +      let resArr = [],
 | 
	
		
			
				|  |  | +        timeArr = [];
 | 
	
		
			
				|  |  | +      let leg = this.curQue.detail.length;
 | 
	
		
			
				|  |  | +      let curQue = JSON.parse(JSON.stringify(this.curQue));
 | 
	
		
			
				|  |  | +      curQue.detail.forEach((dItem, dIndex) => {
 | 
	
		
			
				|  |  | +        let endTime = 0;
 | 
	
		
			
				|  |  | +        if (dIndex < leg - 1) {
 | 
	
		
			
				|  |  | +          endTime = curQue.detail[dIndex + 1].timeList[0];
 | 
	
		
			
				|  |  | +          dItem.timeList.push(endTime);
 | 
	
		
			
				|  |  | +          dItem.timeList = this.handleTimeList(dItem.timeList);
 | 
	
		
			
				|  |  | +        } else {
 | 
	
		
			
				|  |  | +          dItem.timeList = this.handleTimeList(dItem.timeList);
 | 
	
		
			
				|  |  | +          endTime = curQue.mp3_list[0].duration;
 | 
	
		
			
				|  |  | +          dItem.timeList.push(endTime);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        dItem.wordsList.forEach((sItem, sIndex) => {
 | 
	
		
			
				|  |  | +          let sentArr = [];
 | 
	
		
			
				|  |  | +          sItem.forEach((wItem, wIndex) => {
 | 
	
		
			
				|  |  | +            let obj = {
 | 
	
		
			
				|  |  | +              paraIndex: dIndex, //段落索引
 | 
	
		
			
				|  |  | +              sentIndex: sIndex, //在段落中句子索引
 | 
	
		
			
				|  |  | +              wordIndex: wIndex, //单词的索引
 | 
	
		
			
				|  |  | +              pinyin: wItem.pinyin,
 | 
	
		
			
				|  |  | +              chs: wItem.chs,
 | 
	
		
			
				|  |  | +              padding: wItem.padding,
 | 
	
		
			
				|  |  | +              className: wItem.className,
 | 
	
		
			
				|  |  | +              startTime: startTime,
 | 
	
		
			
				|  |  | +              endTime: endTime,
 | 
	
		
			
				|  |  | +            };
 | 
	
		
			
				|  |  | +            sentArr.push(obj);
 | 
	
		
			
				|  |  | +          });
 | 
	
		
			
				|  |  | +          resArr.push(sentArr);
 | 
	
		
			
				|  |  | +        });
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        timeArr.push(dItem.timeList);
 | 
	
		
			
				|  |  | +      });
 | 
	
		
			
				|  |  | +      let timeList = [];
 | 
	
		
			
				|  |  | +      timeArr.forEach((item) => {
 | 
	
		
			
				|  |  | +        item.forEach((aItem) => {
 | 
	
		
			
				|  |  | +          if (timeList.indexOf(aItem) < 0) {
 | 
	
		
			
				|  |  | +            timeList.push(aItem);
 | 
	
		
			
				|  |  | +          }
 | 
	
		
			
				|  |  | +        });
 | 
	
		
			
				|  |  | +      });
 | 
	
		
			
				|  |  | +      this.resObj = { sentList: resArr, timeList: timeList };
 | 
	
		
			
				|  |  | +      console.log(this.resObj);
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +    handleData2() {
 | 
	
		
			
				|  |  | +      let resArr = [],
 | 
	
		
			
				|  |  | +        timeArr = [];
 | 
	
		
			
				|  |  | +      let leg = this.curQue.detail.length;
 | 
	
		
			
				|  |  | +      let curQue = JSON.parse(JSON.stringify(this.curQue));
 | 
	
		
			
				|  |  | +      curQue.detail.forEach((dItem, dIndex) => {
 | 
	
		
			
				|  |  | +        let endTime = 0;
 | 
	
		
			
				|  |  | +        if (dIndex < leg - 1) {
 | 
	
		
			
				|  |  | +          endTime = curQue.detail[dIndex + 1].timeList[0];
 | 
	
		
			
				|  |  | +          dItem.timeList.push(endTime);
 | 
	
		
			
				|  |  | +          dItem.timeList = this.handleTimeList(dItem.timeList);
 | 
	
		
			
				|  |  | +        } else {
 | 
	
		
			
				|  |  | +          dItem.timeList = this.handleTimeList(dItem.timeList);
 | 
	
		
			
				|  |  | +          endTime = curQue.mp3_list[0].duration;
 | 
	
		
			
				|  |  | +          dItem.timeList.push(endTime);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        dItem.wordsList.forEach((sItem, sIndex) => {
 | 
	
		
			
				|  |  | +          let time_diff = dItem.timeList[sIndex + 1] - dItem.timeList[sIndex];
 | 
	
		
			
				|  |  | +          let wordsLeg = dItem.sentences[sIndex].length;
 | 
	
		
			
				|  |  | +          let wordTime = time_diff / wordsLeg;
 | 
	
		
			
				|  |  | +          // console.log(time_diff, wordsLeg, wordTime);
 | 
	
		
			
				|  |  | +          let sentArr = [];
 | 
	
		
			
				|  |  | +          sItem.forEach((wItem, wIndex) => {
 | 
	
		
			
				|  |  | +            let preTotal = wIndex > 0 ? sentArr[wIndex - 1].endTime : 0;
 | 
	
		
			
				|  |  | +            let endTime =
 | 
	
		
			
				|  |  | +              wIndex > 0
 | 
	
		
			
				|  |  | +                ? wordTime * wItem.chs.length + preTotal
 | 
	
		
			
				|  |  | +                : dItem.timeList[sIndex] + wordTime * wItem.chs.length;
 | 
	
		
			
				|  |  | +            //console.log("endTime" + endTime);
 | 
	
		
			
				|  |  | +            let startTime =
 | 
	
		
			
				|  |  | +              wIndex > 0 ? sentArr[wIndex - 1].endTime : dItem.timeList[sIndex];
 | 
	
		
			
				|  |  | +            this.judgePad(sItem, wItem, wIndex);
 | 
	
		
			
				|  |  | +            let obj = {
 | 
	
		
			
				|  |  | +              paraIndex: dIndex, //段落索引
 | 
	
		
			
				|  |  | +              sentIndex: sIndex, //在段落中句子索引
 | 
	
		
			
				|  |  | +              wordIndex: wIndex, //单词的索引
 | 
	
		
			
				|  |  | +              pinyin: wItem.pinyin,
 | 
	
		
			
				|  |  | +              chs: wItem.chs,
 | 
	
		
			
				|  |  | +              padding: wItem.padding,
 | 
	
		
			
				|  |  | +              className: wItem.className,
 | 
	
		
			
				|  |  | +              startTime: startTime,
 | 
	
		
			
				|  |  | +              endTime: endTime,
 | 
	
		
			
				|  |  | +            };
 | 
	
		
			
				|  |  | +            sentArr.push(obj);
 | 
	
		
			
				|  |  | +          });
 | 
	
		
			
				|  |  | +          resArr.push(sentArr);
 | 
	
		
			
				|  |  | +        });
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        timeArr.push(dItem.timeList);
 | 
	
		
			
				|  |  | +      });
 | 
	
		
			
				|  |  | +      let timeList = [];
 | 
	
		
			
				|  |  | +      timeArr.forEach((item) => {
 | 
	
		
			
				|  |  | +        item.forEach((aItem) => {
 | 
	
		
			
				|  |  | +          if (timeList.indexOf(aItem) < 0) {
 | 
	
		
			
				|  |  | +            timeList.push(aItem);
 | 
	
		
			
				|  |  | +          }
 | 
	
		
			
				|  |  | +        });
 | 
	
		
			
				|  |  | +      });
 | 
	
		
			
				|  |  | +      this.resObj = { sentList: resArr, timeList: timeList };
 | 
	
		
			
				|  |  | +      console.log(this.resObj);
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +    //判断是否有padding
 | 
	
		
			
				|  |  | +    judgePad(sItem, wItem, curIndex) {
 | 
	
		
			
				|  |  | +      let leg = sItem.length;
 | 
	
		
			
				|  |  | +      if (curIndex < leg - 1) {
 | 
	
		
			
				|  |  | +        let nextIndex = curIndex + 1;
 | 
	
		
			
				|  |  | +        let chs = sItem[nextIndex].chs;
 | 
	
		
			
				|  |  | +        if (
 | 
	
		
			
				|  |  | +          this.chsFhList.indexOf(chs) > -1 ||
 | 
	
		
			
				|  |  | +          this.chsFhList.indexOf(wItem.chs) > -1
 | 
	
		
			
				|  |  | +        ) {
 | 
	
		
			
				|  |  | +          wItem.padding = false;
 | 
	
		
			
				|  |  | +        } else {
 | 
	
		
			
				|  |  | +          wItem.padding = true;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        if (this.enFhList.indexOf(wItem.pinyin) > -1) {
 | 
	
		
			
				|  |  | +          wItem.className = "textLeft";
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +    //转化时间
 | 
	
		
			
				|  |  | +    handleTimeList(list) {
 | 
	
		
			
				|  |  | +      let listRes = [];
 | 
	
		
			
				|  |  | +      list.forEach((item) => {
 | 
	
		
			
				|  |  | +        let res = timeStrToSen(item);
 | 
	
		
			
				|  |  | +        listRes.push(res);
 | 
	
		
			
				|  |  | +      });
 | 
	
		
			
				|  |  | +      return listRes;
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +    //计算总时间
 | 
	
		
			
				|  |  | +    countWordTime(sentArr) {
 | 
	
		
			
				|  |  | +      let total = 0;
 | 
	
		
			
				|  |  | +      sentArr.forEach((item) => {
 | 
	
		
			
				|  |  | +        total += item.endTime;
 | 
	
		
			
				|  |  | +      });
 | 
	
		
			
				|  |  | +      return total;
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +    //点击播放某个句子
 | 
	
		
			
				|  |  | +    handleChangeTime(time) {
 | 
	
		
			
				|  |  | +      this.curTime = time;
 | 
	
		
			
				|  |  | +      this.$refs.audioLine.onTimeupdateTime(time);
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +  },
 | 
	
		
			
				|  |  | +  //生命周期 - 创建完成(可以访问当前this实例)
 | 
	
		
			
				|  |  | +  created() {},
 | 
	
		
			
				|  |  | +  //生命周期 - 挂载完成(可以访问DOM元素)
 | 
	
		
			
				|  |  | +  mounted() {
 | 
	
		
			
				|  |  | +    console.log(this.curQue);
 | 
	
		
			
				|  |  | +    if (this.curQue) {
 | 
	
		
			
				|  |  | +      this.handleData();
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  },
 | 
	
		
			
				|  |  | +  beforeCreate() {}, //生命周期 - 创建之前
 | 
	
		
			
				|  |  | +  beforeMount() {}, //生命周期 - 挂载之前
 | 
	
		
			
				|  |  | +  beforeUpdate() {}, //生命周期 - 更新之前
 | 
	
		
			
				|  |  | +  updated() {}, //生命周期 - 更新之后
 | 
	
		
			
				|  |  | +  beforeDestroy() {}, //生命周期 - 销毁之前
 | 
	
		
			
				|  |  | +  destroyed() {}, //生命周期 - 销毁完成
 | 
	
		
			
				|  |  | +  activated() {}, //如果页面有keep-alive缓存功能,这个函数会触发
 | 
	
		
			
				|  |  | +};
 | 
	
		
			
				|  |  | +</script>
 | 
	
		
			
				|  |  | +<style lang='scss' scoped>
 | 
	
		
			
				|  |  | +//@import url(); 引入公共css类
 | 
	
		
			
				|  |  | +.NNPE-ArticleView {
 | 
	
		
			
				|  |  | +  width: 100%;
 | 
	
		
			
				|  |  | +  .NNPE-detail {
 | 
	
		
			
				|  |  | +    clear: both;
 | 
	
		
			
				|  |  | +    overflow: hidden;
 | 
	
		
			
				|  |  | +    width: 100%;
 | 
	
		
			
				|  |  | +    background: #ffffff;
 | 
	
		
			
				|  |  | +    border: 1px solid rgba(0, 0, 0, 0.1);
 | 
	
		
			
				|  |  | +    box-sizing: border-box;
 | 
	
		
			
				|  |  | +    border-radius: 8px;
 | 
	
		
			
				|  |  | +    margin-bottom: 8px;
 | 
	
		
			
				|  |  | +    box-sizing: border-box;
 | 
	
		
			
				|  |  | +    padding: 8px 16px 0px;
 | 
	
		
			
				|  |  | +    .NNPE-words {
 | 
	
		
			
				|  |  | +      float: left;
 | 
	
		
			
				|  |  | +      padding: 0 0px 8px 0px;
 | 
	
		
			
				|  |  | +      &.textLeft {
 | 
	
		
			
				|  |  | +        text-align: left;
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +      &.textCenter {
 | 
	
		
			
				|  |  | +        text-align: center;
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +      > span {
 | 
	
		
			
				|  |  | +        display: block;
 | 
	
		
			
				|  |  | +        &.NNPE-pinyin {
 | 
	
		
			
				|  |  | +          font-family: "GB-PINYINOK-B";
 | 
	
		
			
				|  |  | +          font-weight: normal;
 | 
	
		
			
				|  |  | +          font-size: 14px;
 | 
	
		
			
				|  |  | +          line-height: 20px;
 | 
	
		
			
				|  |  | +          color: #000000;
 | 
	
		
			
				|  |  | +          height: 20px;
 | 
	
		
			
				|  |  | +          &.textLeft {
 | 
	
		
			
				|  |  | +            text-align: left;
 | 
	
		
			
				|  |  | +          }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        &.NNPE-chs {
 | 
	
		
			
				|  |  | +          font-family: "FZJCGFKTK";
 | 
	
		
			
				|  |  | +          font-size: 20px;
 | 
	
		
			
				|  |  | +          line-height: 150%;
 | 
	
		
			
				|  |  | +          color: #000000;
 | 
	
		
			
				|  |  | +          &.active {
 | 
	
		
			
				|  |  | +            background: rgba(60, 200, 99, 0.2);
 | 
	
		
			
				|  |  | +          }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        &.padding {
 | 
	
		
			
				|  |  | +          padding-right: 6px;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +</style>
 |