|
@@ -0,0 +1,431 @@
|
|
|
+<!-- -->
|
|
|
+<template>
|
|
|
+ <div class="NNPE-ArticleView" v-if="articleInfo">
|
|
|
+ <template v-if="resArr[0]&&resArr[0].wordsList[0]&&resArr[0].wordsList[0].hasOwnProperty('pno')&&resArr[0].wordsList[0].pno===0">
|
|
|
+ <h2 @click="
|
|
|
+ handleChangeTime(
|
|
|
+ resArr[0].timeList &&
|
|
|
+ resArr[0].timeList[0] &&
|
|
|
+ resArr[0].timeList[0].s
|
|
|
+ )
|
|
|
+ "
|
|
|
+ @mouseover="handleMouseover(resArr[0])"
|
|
|
+ @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:'10px',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]===' '||itemR.marginRight?'marginRight':''
|
|
|
+ ]">
|
|
|
+ <template v-if="itemR.isShow">
|
|
|
+ <span
|
|
|
+ class="NNPE-chs"
|
|
|
+ :class="[
|
|
|
+ itemR.type,itemR.tokens[9]===' '||itemR.marginRight?'marginRight':'',itemR.highIndex?'fontWeight':''
|
|
|
+ ]"
|
|
|
+ >{{ itemR.tokens[2] }}</span
|
|
|
+ >
|
|
|
+ <span
|
|
|
+ class="NNPE-chs NNPE-chs-both"
|
|
|
+ v-if="resArr[0].wordsList[indexR + 1] &&
|
|
|
+ resArr[0].wordsList[indexR + 1].tokens[2] &&
|
|
|
+ enFhList.indexOf(resArr[0].wordsList[indexR + 1].tokens[2]) > -1"
|
|
|
+ :class="[
|
|
|
+ resArr[0].wordsList[indexR + 1].type,resArr[0].wordsList[indexR + 1].tokens[9]===' '||resArr[0].wordsList[indexR + 1].marginRight?'marginRight':'',resArr[0].wordsList[indexR + 1].highIndex?'fontWeight':''
|
|
|
+ ]"
|
|
|
+ >{{ resArr[0].wordsList[indexR + 1].tokens[2] }}</span
|
|
|
+ >
|
|
|
+ </template>
|
|
|
+ <!-- {{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">
|
|
|
+ <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',
|
|
|
+ isPlaying &&
|
|
|
+ item.timeList &&
|
|
|
+ item.timeList[pItem.sno] &&
|
|
|
+ curTime >= item.timeList[pItem.sno].s &&
|
|
|
+ curTime <= item.timeList[pItem.sno].e
|
|
|
+ ? 'sentActive'
|
|
|
+ : '',
|
|
|
+ pItem.pno == paraIndex && pItem.sno == sentIndex
|
|
|
+ ? 'overActive'
|
|
|
+ : '',
|
|
|
+ ]"
|
|
|
+ @click="
|
|
|
+ handleChangeTime(
|
|
|
+ item.timeList &&
|
|
|
+ item.timeList[pItem.sno] &&
|
|
|
+ item.timeList[pItem.sno].s
|
|
|
+ )
|
|
|
+ "
|
|
|
+ @mouseover="handleMouseover(pItem)"
|
|
|
+ @mouseleave="handleMouseleave"
|
|
|
+ >
|
|
|
+ <span
|
|
|
+ class="NNPE-chs"
|
|
|
+ :class="[
|
|
|
+ isPlaying &&
|
|
|
+ item.timeList &&
|
|
|
+ item.timeList[pItem.sno] &&
|
|
|
+ item.timeList[pItem.sno].e &&
|
|
|
+ item.timeList[pItem.sno].tokens &&
|
|
|
+ item.timeList[pItem.sno].tokens[pItem.wIndex]&&
|
|
|
+ curTime >=
|
|
|
+ item.timeList[pItem.sno].tokens[pItem.wIndex].s &&
|
|
|
+ curTime <= item.timeList[pItem.sno].e
|
|
|
+ ? 'wordActive'
|
|
|
+ : '',
|
|
|
+ pItem.tokens[9]===' '||pItem.marginRight?'marginRight':''
|
|
|
+ ]"
|
|
|
+ :style="{fontSize:wordFontsize + 'px',color: isPlaying &&
|
|
|
+ item.timeList &&
|
|
|
+ item.timeList[pItem.sno] &&
|
|
|
+ item.timeList[pItem.sno].tokens[pItem.wIndex]&&
|
|
|
+ curTime >=
|
|
|
+ item.timeList[pItem.sno].tokens[pItem.wIndex].s &&
|
|
|
+ curTime <= item.timeList[pItem.sno].tokens[pItem.wIndex].e?colorObj.statisticValue: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="[
|
|
|
+ isPlaying &&
|
|
|
+ item.timeList &&
|
|
|
+ item.timeList[pItem.sno] &&
|
|
|
+ item.timeList[pItem.sno].tokens[pItem.wIndex]&&
|
|
|
+ curTime >=
|
|
|
+ item.timeList[pItem.sno].tokens[pItem.wIndex].s &&
|
|
|
+ curTime <= item.timeList[pItem.sno].e
|
|
|
+ ? 'wordActive'
|
|
|
+ : '',
|
|
|
+ item.wordsList[pIndex + 1].tokens[9]===' '||item.wordsList[pIndex + 1].marginRight?'marginRight':''
|
|
|
+ ]"
|
|
|
+ :style="{fontSize:wordFontsize + 'px',color: isPlaying &&
|
|
|
+ item.timeList &&
|
|
|
+ item.timeList[pItem.sno] &&
|
|
|
+ item.timeList[pItem.sno].tokens[pItem.wIndex]&&
|
|
|
+ curTime >=
|
|
|
+ item.timeList[pItem.sno].tokens[pItem.wIndex].s &&
|
|
|
+ curTime <= item.timeList[pItem.sno].tokens[pItem.wIndex].e?colorObj.statisticValue: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"
|
|
|
+import MagazineVideo from "./MagazineVideo.vue"
|
|
|
+export default {
|
|
|
+ name: "ArticleView",
|
|
|
+ props: [ "titleFontsize", "wordFontsize", "colorObj","articleType","articleInfo"],
|
|
|
+ components: {
|
|
|
+ AudioLine,
|
|
|
+ MagazineVideo
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ resArr: [],
|
|
|
+ curTime: 0, //单位s
|
|
|
+ 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",
|
|
|
+ "”",
|
|
|
+ ],
|
|
|
+ articleImg: {}, // 文章图片
|
|
|
+ paraIndex: -1, //段落索引
|
|
|
+ sentIndex: -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 resArr = [];
|
|
|
+ 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,
|
|
|
+ wIndex: indexs,
|
|
|
+ isShow: this.enFhList.indexOf(items[2])==-1,
|
|
|
+ marginRight: indexs===item.tokens.length-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;
|
|
|
+ }
|
|
|
+ h2{
|
|
|
+ display: flex;
|
|
|
+ flex-flow: wrap;
|
|
|
+ &.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;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .wordsList-box {
|
|
|
+ flex: 1;
|
|
|
+ padding: 6px 0 12px 0;
|
|
|
+ .nnpe-sentence-box {
|
|
|
+ display: flex;
|
|
|
+ flex-flow: wrap;
|
|
|
+ }
|
|
|
+ > img {
|
|
|
+ max-width: 50%;
|
|
|
+ display: block;
|
|
|
+ padding: 16px 0;
|
|
|
+ margin: 0 auto;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .NNPE-detail {
|
|
|
+ clear: both;
|
|
|
+ overflow: hidden;
|
|
|
+ display: flex;
|
|
|
+ .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;
|
|
|
+}
|
|
|
+.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>
|