|
@@ -0,0 +1,524 @@
|
|
|
+<template>
|
|
|
+ <div class="history-record-list" v-if="list">
|
|
|
+ <template v-if="!showItem">
|
|
|
+ <div class="list-top">
|
|
|
+ <h4><svg-icon icon-class="History"></svg-icon>历史记录</h4>
|
|
|
+ <i class="el-icon-close" @click="closeHistory"></i>
|
|
|
+ </div>
|
|
|
+ <div class="list-center">
|
|
|
+ <p>共{{showList.length}}条记录</p>
|
|
|
+ <span v-if="rangeStr">{{rangeStr}}</span>
|
|
|
+ </div>
|
|
|
+ <ul>
|
|
|
+ <li v-for="(item,index) in showList" :key="index" :class="[index%2===1?'odd':'']">
|
|
|
+ <b>{{index+1}}.</b>
|
|
|
+ <span>{{item.create_time.substring(0,16)}}</span>
|
|
|
+ <i class="el-icon-delete" @click="deleteRecord(item.id,index)"></i>
|
|
|
+ <i class="el-icon-arrow-right" @click="recordDetail(index)"></i>
|
|
|
+ </li>
|
|
|
+ </ul>
|
|
|
+ <div class="nodata" v-if="showList.length===0">
|
|
|
+ <img src="../../../assets/nodata.png" />
|
|
|
+ <p>还没有记录</p>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <template v-else>
|
|
|
+ <div class="list-item">
|
|
|
+ <div class="item-top">
|
|
|
+ <h4><svg-icon icon-class="History"></svg-icon>历史记录 {{showList[activeIndex].create_time.substring(0,16)}}</h4>
|
|
|
+ <i class="el-icon-close" @click="showItem=false"></i>
|
|
|
+ </div>
|
|
|
+ <div class="item-center">
|
|
|
+ <div class="item-sent">
|
|
|
+ <div class="nnpe-sentence-box">
|
|
|
+ <div v-for="(pItem, pIndex) in sentData" :key="'wordsList' + pIndex">
|
|
|
+ <template v-if="pItem.isShow">
|
|
|
+ <div
|
|
|
+ :class="[
|
|
|
+ 'NNPE-words',
|
|
|
+ ]"
|
|
|
+ @click="
|
|
|
+ handleChangeTime(
|
|
|
+ timeData &&
|
|
|
+ timeData &&
|
|
|
+ timeData.s
|
|
|
+ )
|
|
|
+ "
|
|
|
+ >
|
|
|
+ <span
|
|
|
+ class="NNPE-chs"
|
|
|
+ :class="[
|
|
|
+ timeData &&
|
|
|
+ timeData &&
|
|
|
+ timeData.e &&
|
|
|
+ timeData.tokens &&
|
|
|
+ timeData.tokens[pItem.wIndex]&&
|
|
|
+ curTime >=
|
|
|
+ timeData.tokens[pItem.wIndex].s &&
|
|
|
+ curTime <= timeData.e
|
|
|
+ ? 'wordActive'
|
|
|
+ : '',
|
|
|
+ pItem.tokens[9]===''?'marginRight':'',pItem.marginRight?'marginSingleRight':''
|
|
|
+ ]"
|
|
|
+ :style="{fontSize:wordFontsize + 'px'}"
|
|
|
+ >{{ pItem.tokens[2] }}</span
|
|
|
+ >
|
|
|
+ <span
|
|
|
+ class="NNPE-chs NNPE-chs-both"
|
|
|
+ v-if="sentData[pIndex + 1] &&
|
|
|
+ sentData[pIndex + 1].tokens[2] &&
|
|
|
+ enFhList.indexOf(sentData[pIndex + 1].tokens[2]) > -1"
|
|
|
+ :class="[
|
|
|
+ timeData &&
|
|
|
+ timeData &&
|
|
|
+ timeData.tokens[pItem.wIndex]&&
|
|
|
+ curTime >=
|
|
|
+ timeData.tokens[pItem.wIndex].s &&
|
|
|
+ curTime <= timeData.e
|
|
|
+ ? 'wordActive'
|
|
|
+ : '',
|
|
|
+ sentData[pIndex + 1].tokens[8]===''?'marginLeft':'',sentData[pIndex + 1].marginRight?'marginSingleRight':''
|
|
|
+ ]"
|
|
|
+ :style="{fontSize:wordFontsize + 'px'}"
|
|
|
+ >{{ sentData[pIndex + 1].tokens[2] }}</span
|
|
|
+ >
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <label>{{activeIndex+1}}/{{showList.length}}</label>
|
|
|
+ </div>
|
|
|
+ <div class="item-bottom">
|
|
|
+ <div class="operate-box-inner-content">
|
|
|
+ <div class="operate-item" @click="changePlaySent('-')">
|
|
|
+ <svg-icon icon-class="Go-start" :style="{color:colorObj.type==='white'||colorObj.type==='darkGreen'?'#000':'#fff'}"></svg-icon>
|
|
|
+ <span :style="{color:colorObj.type==='armyGreen'?'#7C8983':''}">上一句</span>
|
|
|
+ </div>
|
|
|
+ <div class="operate-item">
|
|
|
+ <svg-icon icon-class="Type-drive" :style="{color:colorObj.type==='white'||colorObj.type==='darkGreen'?'#000':'#fff'}"></svg-icon>
|
|
|
+ <span :style="{color:colorObj.type==='armyGreen'?'#7C8983':''}">听对比</span>
|
|
|
+ </div>
|
|
|
+ <div class="operate-item">
|
|
|
+ <b class="luyin-btn" @click="playSent">
|
|
|
+ <svg-icon icon-class="voice" :style="{color:'#fff'}"></svg-icon>
|
|
|
+ </b>
|
|
|
+ </div>
|
|
|
+ <div class="operate-item" @click="playmicrophone()">
|
|
|
+ <svg-icon icon-class="Headphone-sound" :style="{color:colorObj.type==='white'||colorObj.type==='darkGreen'?'#000':'#fff'}"></svg-icon>
|
|
|
+ <span :style="{color:colorObj.type==='armyGreen'?'#7C8983':''}">我读的</span>
|
|
|
+ </div>
|
|
|
+ <div class="operate-item" @click="changePlaySent('+')">
|
|
|
+ <svg-icon icon-class="Go-end" :style="{color:colorObj.type==='white'||colorObj.type==='darkGreen'?'#000':'#fff'}"></svg-icon>
|
|
|
+ <span :style="{color:colorObj.type==='armyGreen'?'#7C8983':''}">下一句</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+//这里可以导入其它文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)
|
|
|
+//例如:import 《组件名称》from ‘《组件路径》';
|
|
|
+import { getLogin } from "@/api/ajax";
|
|
|
+export default {
|
|
|
+ //import引入的组件需要注入到对象中才能使用
|
|
|
+ components: { },
|
|
|
+ props: ["list","sentData","timeData","mp3Url","colorObj","wordFontsize","parentCurtimt","parentPlay"],
|
|
|
+ data() {
|
|
|
+ //这里存放数据
|
|
|
+ return {
|
|
|
+ showItem: false,
|
|
|
+ rangeStr: '',
|
|
|
+ showList: JSON.parse(JSON.stringify(this.list)),
|
|
|
+ activeIndex: -1,
|
|
|
+ curTime: this.timeData.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",
|
|
|
+ "”",
|
|
|
+ ],
|
|
|
+ audio: new window.Audio(),
|
|
|
+ timeCur: null,
|
|
|
+ isPlay: false
|
|
|
+ }
|
|
|
+ },
|
|
|
+ //计算属性 类似于data概念
|
|
|
+ computed: {},
|
|
|
+ //监控data中数据变化
|
|
|
+ watch: {
|
|
|
+ list:{
|
|
|
+ handler(val, oldVal) {
|
|
|
+ const _this = this;
|
|
|
+ if (val) {
|
|
|
+ this.showList = JSON.parse(JSON.stringify(this.list))
|
|
|
+ this.handleData()
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 深度观察监听
|
|
|
+ deep: true,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ //方法集合
|
|
|
+ methods: {
|
|
|
+ // 关闭
|
|
|
+ closeHistory(){
|
|
|
+ this.$emit('closeHistory')
|
|
|
+ },
|
|
|
+ handleData(){
|
|
|
+ if(this.showList.length>0){
|
|
|
+ this.rangeStr = this.showList[0].create_time.substring(0,10)+'~'+this.showList[this.showList.length-1].create_time.substring(0,10)
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 删除一条录音记录
|
|
|
+ deleteRecord(id,index){
|
|
|
+ let MethodName = "/PaperServer/Client/UserSentRec/DeleteById";
|
|
|
+ let data = {
|
|
|
+ id: id
|
|
|
+ }
|
|
|
+ getLogin(MethodName, data)
|
|
|
+ .then((res) => {
|
|
|
+ if(res.status===1){
|
|
|
+ this.showList.splice(index,1)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ // 查看一条录音详情
|
|
|
+ recordDetail(index){
|
|
|
+ this.activeIndex = index
|
|
|
+ this.showItem = true
|
|
|
+ },
|
|
|
+ changePlaySent(type){
|
|
|
+ if(type==='-'){
|
|
|
+ if(this.activeIndex>0){
|
|
|
+ this.activeIndex--
|
|
|
+ }else{
|
|
|
+ this.activeIndex=0
|
|
|
+ }
|
|
|
+ }else{
|
|
|
+ if(this.activeIndex<this.showList.length-1){
|
|
|
+ this.activeIndex++
|
|
|
+ }else{
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ playmicrophone() {
|
|
|
+ if (this.hasMicro) {
|
|
|
+ this.isPlayings = true;
|
|
|
+ if (this.selectIndex || this.selectIndex == 0) {
|
|
|
+ let _this = this;
|
|
|
+ if (!this.audio.paused) {
|
|
|
+ this.audio.pause();
|
|
|
+ } else if (this.audio.paused && _this.oldIndex == _this.selectIndex) {
|
|
|
+ _this.audio.play();
|
|
|
+ if (_this.recordtime == 0) {
|
|
|
+ _this.playtime = 0;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ _this.audio.pause();
|
|
|
+ _this.audio.load();
|
|
|
+ _this.audio.src = _this.wavblob;
|
|
|
+ _this.oldIndex = _this.selectIndex;
|
|
|
+ _this.audio.play();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 播放句子
|
|
|
+ playSent(){
|
|
|
+ let _this = this
|
|
|
+ if(_this.curTime>=_this.timeData.e){
|
|
|
+ _this.curTime = _this.timeData.s
|
|
|
+ }
|
|
|
+ if(_this.parentPlay){
|
|
|
+ _this.$emit("handleChangeTime",_this.curTime,_this.timeData.e,true)
|
|
|
+ clearInterval(_this.timeCur)
|
|
|
+ }else{
|
|
|
+ _this.$emit("handleChangeTime",_this.curTime,_this.timeData.e)
|
|
|
+ _this.timeCur = setInterval(() => {
|
|
|
+ _this.curTime = _this.parentCurtimt
|
|
|
+ }, 1000);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ handleChangeTime(time){
|
|
|
+ if (time>=0) {
|
|
|
+ this.curTime = time;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ //生命周期 - 创建完成(可以访问当前this实例)
|
|
|
+ created() {
|
|
|
+ this.handleData()
|
|
|
+ },
|
|
|
+ //生命周期 - 挂载完成(可以访问DOM元素)
|
|
|
+ mounted() {
|
|
|
+
|
|
|
+ },
|
|
|
+ //生命周期-创建之前
|
|
|
+ beforeCreated() { },
|
|
|
+ //生命周期-挂载之前
|
|
|
+ beforeMount() {
|
|
|
+ clearInterval(this.timeCur)
|
|
|
+ },
|
|
|
+ //生命周期-更新之前
|
|
|
+ beforUpdate() { },
|
|
|
+ //生命周期-更新之后
|
|
|
+ updated() { },
|
|
|
+ //生命周期-销毁之前
|
|
|
+ beforeDestory() { },
|
|
|
+ //生命周期-销毁完成
|
|
|
+ destoryed() { },
|
|
|
+ //如果页面有keep-alive缓存功能,这个函数会触发
|
|
|
+ activated() { }
|
|
|
+}
|
|
|
+</script>
|
|
|
+<style lang="scss" scoped>
|
|
|
+/* @import url(); 引入css类 */
|
|
|
+.history-record-list{
|
|
|
+ padding: 24px;
|
|
|
+ background: #FFF;
|
|
|
+}
|
|
|
+.list-top{
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ h4{
|
|
|
+ color: #2F3742;
|
|
|
+ font-size: 24px;
|
|
|
+ font-weight: 400;
|
|
|
+ line-height: 32px;
|
|
|
+ margin: 0;
|
|
|
+ .svg-icon{
|
|
|
+ margin-right: 8px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .el-icon-close{
|
|
|
+ font-size: 24px;
|
|
|
+ cursor: pointer;
|
|
|
+ }
|
|
|
+}
|
|
|
+.list-center{
|
|
|
+ border-radius: 4px;
|
|
|
+ background:#F7F8FA;
|
|
|
+ padding: 8px 12px;
|
|
|
+ margin: 24px 0;
|
|
|
+ p{
|
|
|
+ color: #2F3742;
|
|
|
+ font-size: 16px;
|
|
|
+ font-weight: 500;
|
|
|
+ line-height: 24px;
|
|
|
+ margin: 0;
|
|
|
+ }
|
|
|
+ span{
|
|
|
+ color:#929CA8;
|
|
|
+ font-size: 12px;
|
|
|
+ font-weight: 400;
|
|
|
+ line-height: 20px;
|
|
|
+ margin-top: 4px;
|
|
|
+ }
|
|
|
+}
|
|
|
+ul{
|
|
|
+ margin: 0;
|
|
|
+ padding: 0;
|
|
|
+ li{
|
|
|
+ padding: 8px;
|
|
|
+ border-radius: 4px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ font-size: 14px;
|
|
|
+ font-weight: 400;
|
|
|
+ line-height: 22px;
|
|
|
+ &.odd{
|
|
|
+ background: #F7F8FA;
|
|
|
+ }
|
|
|
+ b{
|
|
|
+ width: 28px;
|
|
|
+ color: #929CA8;
|
|
|
+ }
|
|
|
+ span{
|
|
|
+ flex: 1;
|
|
|
+ color: #2F3742;
|
|
|
+ }
|
|
|
+ .el-icon-delete,.el-icon-arrow-right{
|
|
|
+ cursor: pointer;
|
|
|
+ color: #929CA8;
|
|
|
+ font-size: 16px;
|
|
|
+ padding: 3px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+.list-item{
|
|
|
+ padding: 16px;
|
|
|
+ .item-top{
|
|
|
+ padding: 8px 16px;
|
|
|
+ border-radius: 4px;
|
|
|
+ border: 1px solid rgba(0, 0, 0, 0.08);
|
|
|
+ background: #0081F1;
|
|
|
+ box-shadow: 0px 8px 10px -5px rgba(0, 0, 0, 0.08), 0px 16px 24px 2px rgba(0, 0, 0, 0.04), 0px 6px 30px 5px rgba(0, 0, 0, 0.05);
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ h4{
|
|
|
+ color: #FFF;
|
|
|
+ font-size: 16px;
|
|
|
+ font-weight: 400;
|
|
|
+ line-height: 24px;
|
|
|
+ margin: 0;
|
|
|
+ .svg-icon{
|
|
|
+ margin-right: 8px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .el-icon-close{
|
|
|
+ font-size: 16px;
|
|
|
+ padding: 4px;
|
|
|
+ cursor: pointer;
|
|
|
+ color: #FFF;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .item-center{
|
|
|
+ min-height: 300px;
|
|
|
+ padding: 40px 0;
|
|
|
+ position: relative;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ >label{
|
|
|
+ position: absolute;
|
|
|
+ bottom: 0px;
|
|
|
+ left: 50%;
|
|
|
+ margin-left: -27px;
|
|
|
+ padding: 1px 8px;
|
|
|
+ min-width: 54px;
|
|
|
+ border-radius: 2px;
|
|
|
+ background: #F2F3F5;
|
|
|
+ text-align: center;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .item-bottom{
|
|
|
+ border-top: 1px solid #EBEBEB;
|
|
|
+ padding-top: 40px;
|
|
|
+ .operate-box-inner-content{
|
|
|
+ width: 600px;
|
|
|
+ margin: 0 auto;
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ }
|
|
|
+ .operate-item{
|
|
|
+ text-align: center;
|
|
|
+ cursor: pointer;
|
|
|
+ .luyin-btn{
|
|
|
+ display: block;
|
|
|
+ width: 64px;
|
|
|
+ height: 64px;
|
|
|
+ padding: 10px;
|
|
|
+ border-radius: 60px;
|
|
|
+ background: #175DFF;
|
|
|
+ box-shadow: 0px 8px 10px -5px rgba(0, 0, 0, 0.08), 0px 16px 24px 2px rgba(0, 0, 0, 0.04), 0px 6px 30px 5px rgba(0, 0, 0, 0.05);
|
|
|
+ }
|
|
|
+ .luyin-gif{
|
|
|
+ display: block;
|
|
|
+ width: 64px;
|
|
|
+ height: 64px;
|
|
|
+ border-radius: 60px;
|
|
|
+ box-shadow: 0px 8px 10px -5px rgba(0, 0, 0, 0.08), 0px 16px 24px 2px rgba(0, 0, 0, 0.04), 0px 6px 30px 5px rgba(0, 0, 0, 0.05);
|
|
|
+ }
|
|
|
+ .svg-icon{
|
|
|
+ display: block;
|
|
|
+ width: 44px;
|
|
|
+ height: 44px;
|
|
|
+ margin: 0 auto;
|
|
|
+ padding: 6px;
|
|
|
+ }
|
|
|
+ span{
|
|
|
+ color: #929CA8;
|
|
|
+ font-size: 12px;
|
|
|
+ font-weight: 400;
|
|
|
+ line-height: 20px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+.item-sent{
|
|
|
+ width: 100%;
|
|
|
+}
|
|
|
+.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;
|
|
|
+ padding: 0 3px;
|
|
|
+ &.wordActive {
|
|
|
+ color: #175DFF;
|
|
|
+ }
|
|
|
+ &.marginRight{
|
|
|
+ padding-right: 0;
|
|
|
+ }
|
|
|
+ &.marginLeft{
|
|
|
+ padding-left: 0;
|
|
|
+ }
|
|
|
+ &.marginSingleRight{
|
|
|
+ padding-right: 3px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ &.padding {
|
|
|
+ padding: 0 3px;
|
|
|
+ cursor: pointer;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|