Browse Source

完成音频

jwyu 3 years ago
parent
commit
1133af36ab

+ 222 - 0
pages-report/components/audioBox.vue

@@ -0,0 +1,222 @@
+<template>
+    <view class="pop-audio-box">
+        <view class="name">{{title}}</view>
+        <view class="flex">
+            <text>{{currentTime|formatVoiceTime}}</text>
+            <slider
+                activeColor="#e3b377"
+                :max="audioTime" 
+                :value="currentTime" 
+                @change="handleAudioSliderChange($event)"
+                block-size="16"
+                class="slider"
+            />
+            <text>{{audioTime|formatVoiceTime}}</text>
+            <image 
+                class="small-img"  
+                :src="play?'../static/audio-play.png':'../static/audio-pause.png'" 
+                mode="aspectFill" 
+                v-if="audioData.list.length==1"
+                @click="handleChangePlayStatus"
+            />
+        </view>
+        <view class="btn" v-if="audioData.list.length>1">
+            <image 
+                :src="audioData.index==0?'../static/audio-change-grey.png':'../static/audio-change.png'" 
+                mode="aspectFill" 
+                class="aside"
+                @click="handleAudioChange('before')"
+            />
+            <image 
+                :src="play?'../static/audio-play.png':'../static/audio-pause.png'" 
+                mode="aspectFill" 
+                class="center"
+                @click="handleChangePlayStatus"
+            />
+            <image 
+                :src="audioData.index==audioData.list.length-1?'../static/audio-change-grey.png':'../static/audio-change.png'" 
+                mode="aspectFill" 
+                class="aside" 
+                style="transform: rotate(180deg)"
+                @click="handleAudioChange('next')"
+            />
+        </view>
+    </view>
+</template>
+
+<script>
+export default {
+    computed: {
+        audioData(){
+            return this.$store.state.report.audioData
+        }
+    },
+    watch: {
+        'audioData.list':{
+            handler(nval,old){
+                console.log('watch',nval,old);
+                
+                if(nval.length>0){
+                    if(old){
+                        this.init('change')
+                    }else{
+                        this.init()
+                    }
+                }
+            },
+            deep:true,
+            immediate:true
+        }
+    },
+    data () {
+        return {
+            title:'',
+            audioTime:0,
+            currentTime:0,
+            play:false
+        }
+    },
+    methods: {
+        init(type){
+            console.log('init',this.$store.state.report.audioData);
+            let curAudio=this.$store.state.report.audioData.list[this.$store.state.report.audioData.index]
+            if(this.globalBgMusic.src){
+                console.log(this.globalBgMusic);
+                if(type==='change'){
+                    this.globalBgMusic.src=curAudio.video_url
+                    this.globalBgMusic.title=curAudio.video_name
+                }else{
+                    this.currentTime=parseInt(this.globalBgMusic.currentTime)
+                }
+            }else{
+                this.globalBgMusic.src=curAudio.video_url
+                this.globalBgMusic.title=curAudio.video_name
+            }
+            this.title=curAudio.video_name
+            this.audioTime=curAudio.video_play_seconds
+            this.handleAudioFun()
+        },
+
+        // 音频事件
+        handleAudioFun(){
+            this.globalBgMusic.onPlay(()=>{
+                this.play=true
+            })
+            this.globalBgMusic.onPause(()=>{
+                this.play=false
+            })
+            this.globalBgMusic.onStop(()=>{
+                this.$store.commit('removeAudio')
+            })
+            this.globalBgMusic.onEnded(()=>{
+                console.log('onEnded');
+                // this.play=false
+                let index=this.$store.state.report.audioData.index
+                if(index==this.$store.state.report.audioData.list.length-1){
+                    this.$store.commit('removeAudio')
+                }else{
+                    this.handleAudioChange('next')
+                }
+            })
+            this.globalBgMusic.onError((e)=>{
+                console.log('onError',e);
+                uni.showToast({
+                    title: '音频播放错误',
+                    icon: 'none'
+                })
+            })
+            this.globalBgMusic.onTimeUpdate(()=>{
+                // console.log('时间更新');
+                this.currentTime=parseInt(this.globalBgMusic.currentTime)
+            })
+        },
+
+        //音频点击暂停播放
+        handleChangePlayStatus(){
+            if(this.play){
+                this.globalBgMusic.pause()
+            }else{
+                this.globalBgMusic.play()
+            }
+        },
+
+        //音频切换
+        handleAudioChange(type){
+            let temIndex=this.$store.state.report.audioData.index
+            if(type=='before'){
+                if(temIndex>0){
+                    let index=temIndex-1
+                    this.$store.commit('updateAudioIndex', index)
+                    this.init()
+                }
+            }else{
+                if(temIndex<this.$store.state.report.audioData.list.length-1){
+                    let index=temIndex+1
+                    this.$store.commit('updateAudioIndex', index)
+                    this.init()
+                }
+            }
+        },
+
+        //拖动进度条
+        handleAudioSliderChange(e){
+            const value=e.detail.value
+            this.globalBgMusic.seek(value)
+        }
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+.pop-audio-box{
+    position: fixed;
+    width: 90vw;
+    min-height: 50rpx;
+    left: 5vw;
+    bottom: 30rpx;
+    z-index: 99;
+    background-color: #fff;
+    border: 2px solid rgba(240, 234, 226, 0.32);
+    border-radius: 8rpx;
+    padding: 10rpx 15rpx;
+    .name{
+        text-align: center;
+        font-size: 24rpx;
+    }
+    .flex{
+        align-items: center;
+        text{
+            flex-shrink: 0;
+            font-size: 20rpx;
+        }
+        .slider{
+            flex: 1;
+            margin: 0 20rpx;
+        }
+        .small-img{
+            width: 36rpx;
+            height: 36rpx;
+            display: block;
+            margin-left: 10rpx;
+            flex-shrink: 0;
+        }
+    }
+    .btn{
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        image{
+            display: block;
+        }
+        .aside{
+            width: 36rpx;
+            height: 36rpx;
+        }
+        .center{
+            width: 44rpx;
+            height: 44rpx;
+            margin: 0 20rpx;
+        }
+    }
+}
+</style>

+ 24 - 4
pages-report/reportList.vue

@@ -13,14 +13,14 @@
       <image :src="globalImgUrls.chartEmpty" mode="widthFix" />
       <view>找不到对应报告,试试别的搜索词吧</view>
     </view>
-    <view class="report-list-wrap" v-else>
+    <view class="report-list-wrap" :style="{paddingBottom:showAudioPop&&'90px'}" v-else>
       <view class="flex item" v-for="item in list" :key="item.report_id" @click="goReportDetail(item)">
         <image class="img" :src="item.report_img_url" mode="aspectFill" />
         <view class="con">
           <view class="title" v-html="item.title"></view>
           <view class="van-ellipsis tips" v-html="item.abstract"></view>
           <view class="time">{{item.publish_time|formatReportTime}}</view>
-          <view :class="['audio-box',!item.auth_ok&&'grey-audio-box']">
+          <view :class="['audio-box',!item.auth_ok&&'grey-audio-box']" @click.stop="handleClickAudio(item)">
             <image src="./static/audio.png" mode="aspectFill"/>
             <text>播放</text>
           </view>
@@ -47,15 +47,25 @@
             </view>
         </view>
     </van-popup>
+
+    <!-- 音频弹窗 -->
+    <audioBox v-if="showAudioPop"></audioBox>
   </view>
 </template>
 
 <script>
 import searchBox from "./components/searchBox.vue";
+import audioBox from './components/audioBox.vue'
 import {apiReportList,apiSubClassifyList} from '@/api/report'
 export default {
+  computed: {
+    showAudioPop(){//是否显示音频弹窗
+      return this.$store.state.report.audioData.show 
+    }
+  },
   components: {
     searchBox,
+    audioBox
   },
   data() {
     return {
@@ -138,7 +148,6 @@ export default {
       this.getList()
     },
 
-
     onChange(e) {
       this.searchVal = e;
     },
@@ -153,8 +162,19 @@ export default {
 
     goReportDetail(item){
       uni.navigateTo({ url: '/pages-report/reportDetail?reportId='+item.report_id })
-    }
+    },
 
+    handleClickAudio(item){
+      if(!item.auth_ok) return
+      if(!item.video_list||item.video_list.length==0){
+        uni.showToast({
+          title: '暂无音频',
+          icon: 'none'
+        })
+        return
+      }
+      this.$store.commit('addAudio', item.video_list)
+    }
 
   },
 };

+ 26 - 2
pages-report/specialColumn/detail.vue

@@ -26,7 +26,7 @@
                     <view class="title">【第{{item.stage}}期|FICC】{{item.classify_name_second}}</view>
                     <view class="van-ellipsis tips">摘要:{{item.abstract}}</view>
                     <view class="time">{{item.publish_time|formatReportTime}}</view>
-                    <view :class="['audio-box',!info.auth_ok&&'grey-audio-box']">
+                    <view :class="['audio-box',!info.auth_ok&&'grey-audio-box']" @click.stop="handleClickAudio(item)">
                         <image src="../static/audio.png" mode="aspectFill"/>
                         <text>播放</text>
                     </view>
@@ -34,12 +34,24 @@
             </view>
         </view>
         <view class="contact-box" v-if="!info.auth_ok&&!info.permission_check.mobile" @click="handleContact">联系我们</view>
+
+        <!-- 音频弹窗 -->
+        <audioBox v-if="showAudioPop"></audioBox>
     </view>
 </template>
 
 <script>
 import {apiSpecialColumnDetail,apiSpecialColumnReportList} from '@/api/report'
+import audioBox from '../components/audioBox.vue'
 export default {
+    computed: {
+        showAudioPop(){//是否显示音频弹窗
+            return this.$store.state.report.audioData.show 
+        }
+    },
+    components: {
+        audioBox
+    },
     data () {
         return {
             tabActive:'专栏介绍',
@@ -114,6 +126,18 @@ export default {
             uni.makePhoneCall({
                 phoneNumber: this.info.permission_check.hz_phone
             })
+        },
+
+        handleClickAudio(item){
+            if(!this.info.auth_ok) return
+            if(!item.video_url){
+                uni.showToast({
+                title: '暂无音频',
+                icon: 'none'
+                })
+                return
+            }
+            this.$store.commit('addAudio', [{video_url:item.video_url,video_name:item.video_name,video_play_seconds:item.video_play_seconds}])
         }
     }
 }
@@ -178,7 +202,7 @@ page{
         .user-intro{
             font-size: 24rpx;
             color: #666666;
-            line-height: 1.5;
+            line-height: 1.7;
         }
     }
     .tab-box{

BIN
pages-report/static/audio-change-grey.png


BIN
pages-report/static/audio-change.png


BIN
pages-report/static/audio-pause.png


BIN
pages-report/static/audio-play.png


+ 3 - 1
store/index.js

@@ -2,6 +2,7 @@ import Vue from 'vue'
 import Vuex from 'vuex'
 import user from './modules/user.js'
 import activity from './modules/activity'
+import report from './modules/report'
 Vue.use(Vuex);//vue的插件机制
 
 //Vuex.Store 构造器选项
@@ -11,7 +12,8 @@ const store = new Vuex.Store({
 	actions:{},
 	modules:{
 		user,
-		activity
+		activity,
+		report
 	}
 })
 export default store

+ 26 - 0
store/modules/report.js

@@ -0,0 +1,26 @@
+const reportModules={
+    state:{
+        audioData:{
+            show:false,//是否显示音频弹窗
+            list:[],
+            index:0,//当前是播放第几个
+        }
+    },
+    mutations: {
+        addAudio(state,e){
+            state.audioData.show=true
+            state.audioData.list=e
+            state.audioData.index=0
+        },
+        updateAudioIndex(state,e){
+            state.audioData.index=e
+        },
+        removeAudio(state,e){
+            state.audioData.show=false
+            state.audioData.list=[]
+            state.audioData.index=0
+        }
+    }
+}
+
+export default reportModules;