Browse Source

完成音频

jwyu 2 years ago
parent
commit
0f60e7b67f

+ 199 - 6
pages-report/components/audioBox.vue

@@ -1,5 +1,5 @@
 <template>
-    <view class="pop-audio-box">
+    <!-- <view class="pop-audio-box">
         <view class="name">{{title}}</view>
         <view class="flex">
             <text>{{currentTime|formatVoiceTime}}</text>
@@ -41,6 +41,70 @@
                 @click="handleAudioChange('next')"
             />
         </view>
+    </view> -->
+    <view class="pop-audio-wrap">
+        <view class="flex small-box" @click="handleOpenBig">
+            <image class="bg-img" src="" mode="aspectFill" />
+            <view class="flex con">
+                <view style="flex:1;overflow: hidden;">
+                    <view class="van-ellipsis name">{{title}}</view>
+                    <view class="time">时长 {{audioTime|formatVoiceTime}}</view>
+                </view>
+                <image 
+                    class="pause-img"  
+                    :src="play?'../static/audio-play.png':'../static/audio-pause.png'" 
+                    mode="aspectFill"
+                    @click.stop="handleChangePlayStatus"
+                />
+                <van-icon @click.stop="handleClosePopAudio" name="cross" size="18" color="#BBC3C9" />
+            </view>
+            <van-progress 
+                color="#D4AC78" 
+                track-color="#fff"
+                :show-pivot="false" 
+                stroke-width="2px" 
+                custom-class="bot-progress" 
+                :percentage="percentage" 
+            />
+        </view>
+        <view class="big-box" v-if="showBig">
+            <van-icon class="big-arrow-down" name="arrow-down" size="18" color="#BBC3C9" @click="showBig=false" />
+            <van-icon class="big-cross" @click.stop="handleClosePopAudio" name="cross" size="18" color="#BBC3C9"/>
+            <view class="name">{{title}}</view>
+            <view class="flex center-box">
+                <text>{{currentTime|formatVoiceTime}}</text>
+                <slider
+                    activeColor="#e3b377"
+                    :max="audioTime" 
+                    :value="currentTime" 
+                    @change="handleAudioSliderChange($event)"
+                    block-size="16"
+                    class="slider"
+                />
+                <text>{{audioTime|formatVoiceTime}}</text>
+            </view>
+            <view class="btn">
+                <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>
     </view>
 </template>
 
@@ -49,13 +113,15 @@ export default {
     computed: {
         audioData(){
             return this.$store.state.report.audioData
+        },
+        percentage(){
+            return parseInt((this.currentTime/this.audioTime)*100)
         }
     },
     watch: {
         'audioData.list':{
             handler(nval,old){
-                console.log('watch',nval,old);
-                
+                // console.log('watch',nval,old);
                 if(nval.length>0){
                     if(old){
                         this.init('change')
@@ -73,7 +139,9 @@ export default {
             title:'',
             audioTime:0,
             currentTime:0,
-            play:false
+            play:false,
+
+            showBig:false
         }
     },
     methods: {
@@ -81,12 +149,16 @@ export default {
             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);
-                console.log(type);
+                // console.log(this.globalBgMusic);
+                console.log('type',type);
                 if(type==='change'){
                     this.globalBgMusic.src=curAudio.video_url
                     this.globalBgMusic.title=curAudio.video_name
                 }else{
+                    if(!this.globalBgMusic.paused){
+                        this.globalBgMusic.src=curAudio.video_url
+                        this.globalBgMusic.title=curAudio.video_name
+                    }
                     this.currentTime=parseInt(this.globalBgMusic.currentTime)
                     this.play=!this.globalBgMusic.paused
                 }
@@ -166,12 +238,133 @@ export default {
         handleAudioSliderChange(e){
             const value=e.detail.value
             this.globalBgMusic.seek(value)
+        },
+
+        //关闭弹窗
+        handleClosePopAudio(){
+            this.$store.commit('closePopAudio')
+        },
+
+        //点击展开
+        handleOpenBig(){
+            this.showBig=true
         }
     }
 }
 </script>
 
+
+<style>
+.bot-progress{
+    position: absolute;
+    bottom: 0;
+    left: 0;
+    right: 0;
+}
+.big-arrow-down{
+    position: absolute;
+    left: 25rpx;
+    top: 25rpx;
+}
+.big-cross{
+    position: absolute;
+    top: 25rpx;
+    right: 25rpx;
+}
+</style>
 <style lang="scss" scoped>
+.pop-audio-wrap{
+    .small-box{
+        position: fixed;
+        z-index: 99;
+        height: 120rpx;
+        left: 50%;
+        width: calc(100vw - 40rpx);
+        bottom: 67rpx;
+        transform: translateX(-50%);
+        background: #FFFFFF;
+        box-shadow: 0px 0px 40rpx 1px rgba(50,35,17,0.25);
+        border: 1px solid #E4E4E4;
+        overflow: hidden;
+        .bg-img{
+            width: 90rpx;
+            height: 100%;
+            background-color: #ccc;
+            flex-shrink: 0;
+            margin-right: 20rpx;
+        }
+        .con{
+            flex: 1;
+            padding-right: 40rpx;
+            overflow: hidden;
+            align-items: center;
+            .name{
+                font-size: 28rpx;
+                margin-bottom: 11rpx;
+            }
+            .time{
+                font-size: 24rpx;
+                color: #666;
+            }
+            .pause-img{
+                width: 60rpx;
+                height: 60rpx;
+                flex-shrink: 0;
+                margin-right: 44rpx;
+            }
+        }
+    }
+    .big-box{
+        position: fixed;
+        z-index: 100;
+        left: 50%;
+        width: calc(100vw - 40rpx);
+        bottom: 67rpx;
+        transform: translateX(-50%);
+        background: #FFFFFF;
+        box-shadow: 0px 0px 33rpx 1px rgba(50,35,17,0.25);
+        border: 1px solid #E4E4E4;
+        overflow: hidden;
+        padding: 25rpx;
+        .name{
+            padding: 0 35rpx;
+            font-size: 23rpx;
+            text-align: center;
+            margin-bottom: 20rpx;
+        }
+        .center-box{
+            align-items: center;
+            text{
+                flex-shrink: 0;
+                font-size: 20rpx;
+                color: #666;
+            }
+            .slider{
+                flex: 1;
+                margin: 0 20rpx;
+            }
+        }
+        .btn{
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            margin-top: 20rpx;
+            image{
+                display: block;
+            }
+            .aside{
+                width: 49rpx;
+                height: 49rpx;
+            }
+            .center{
+                width: 49rpx;
+                height: 49rpx;
+                margin: 0 49rpx;
+            }
+        }
+    }
+}
+
 .pop-audio-box{
     position: fixed;
     width: 90vw;

+ 5 - 0
pages-report/components/searchBox.vue

@@ -16,6 +16,7 @@
             @confirm="handleSearch"
             @input="handleInput"
             confirm-type="search"
+            :disabled="disabled"
         />
         <image 
             class="search-clear" 
@@ -42,6 +43,10 @@ export default {
         focus:{
             type:Boolean,
             default:false
+        },
+        disabled:{
+            type:Boolean,
+            default:false
         }
     },
     data () {

+ 16 - 2
pages-report/reportList.vue

@@ -2,7 +2,13 @@
   <view class="report-list-page">
     <van-sticky style="background: #fff">
       <view class="flex search-wrap">
-        <searchBox style="flex: 1" :focus="focus" placeholder="请输入报告标题或关键字" :hasRightBtn="false" @change="onChange" @search="onSearch"></searchBox>
+        <view style="flex: 1" @click="goSearch" >
+        <searchBox 
+          placeholder="请输入报告标题或关键字" 
+          :hasRightBtn="false" 
+          :disabled="true"
+        ></searchBox>
+        </view>
         <view class="filter-box" @click="showFilter=true" v-if="classifyList.length>0">
           <image src="./static/filter-icon.png" mode="aspectFill"></image>
           <text>筛选</text>
@@ -13,7 +19,7 @@
       <image :src="globalImgUrls.chartEmpty" mode="widthFix" />
       <view>{{searchVal?'找不到对应报告,试试别的搜索词吧':'暂无报告'}}</view>
     </view>
-    <view class="report-list-wrap" :style="{paddingBottom:showAudioPop&&'90px'}" v-else>
+    <view class="report-list-wrap" :style="{paddingBottom:showAudioPop&&'150px'}" 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" lazy-load />
         <view class="con">
@@ -187,12 +193,20 @@ export default {
       if(this.$store.state.report.audioData.reportId==item.report_id){
         if(this.globalBgMusic.paused){
           this.globalBgMusic.play()
+          this.$store.commit('showPopAudio')
         }else{
           this.globalBgMusic.pause()
         }
       }else{
         this.$store.commit('addAudio', {list:item.video_list,reportId:item.report_id})
       }
+    },
+
+    // 跳转搜索
+    goSearch(){
+      uni.navigateTo({
+        url:`/pages-report/reportListSearch?classify_id_first=${this.classifyId}&classifyName=${this.classifyName}`
+      })
     }
 
   },

+ 206 - 0
pages-report/reportListSearch.vue

@@ -0,0 +1,206 @@
+<template>
+    <view class="report-list-page">
+        <van-sticky style="background: #fff">
+            <view style="padding:30rpx 34rpx;background: #fff">
+                <searchBox
+                    :focus="focus" 
+                    placeholder="请输入报告标题或关键字"
+                    @change="onChange" 
+                    @search="onSearch"
+                ></searchBox>
+            </view>
+        </van-sticky>
+        <view class="report-empty-box" v-if="finished&&list.length==0">
+            <image :src="globalImgUrls.chartEmpty" mode="widthFix" />
+            <view>找不到对应报告,试试别的搜索词吧</view>
+        </view>
+        <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" lazy-load />
+                <view class="con">
+                <view class="title" v-html="item.title"></view>
+                <view class="info" v-html="item.classify_name_second"></view>
+                <view class="time">{{item.stage}}期 | {{item.publish_time|formatReportTime}}</view>
+                <view :class="['audio-box',!item.auth_ok&&'grey-audio-box']" @click.stop="handleClickAudio(item)" v-if="item.auth_ok">
+                    <image :src="curAudioReportId==item.report_id&&!curAudioPaused?'./static/audio-s.png':'./static/audio.png'" mode="aspectFill"/>
+                    <text>{{curAudioReportId==item.report_id&&!curAudioPaused?'暂停':'播放'}}</text>
+                </view>
+                </view>
+            </view>
+        </view>
+
+        <!-- 音频弹窗 -->
+        <audioBox v-if="showAudioPop"></audioBox>
+    </view>
+</template>
+
+<script>
+import searchBox from "./components/searchBox.vue";
+import audioBox from './components/audioBox.vue'
+import {apiReportList} from '@/api/report'
+export default {
+    computed: {
+        showAudioPop(){//是否显示音频弹窗
+            return this.$store.state.report.audioData.show 
+        },
+        curAudioReportId(){//当前播放的音频所属报告
+            return this.$store.state.report.audioData.reportId
+        },
+        curAudioPaused(){//当前音频是否暂停状态
+            return this.$store.state.report.audioData.paused
+        }
+    },
+    components: {
+        searchBox,
+        audioBox
+    },
+    data() {
+        return {
+            classify_id_first:0,
+            classifyName:'',
+
+            searchVal: "",
+            focus:true,
+            list:[],
+            finished:false,
+            page:1,
+            pageSize:20
+        };
+    },
+    onLoad(options) {
+        this.classify_id_first=options.classify_id_first
+        this.classifyName=decodeURIComponent(options.classifyName)
+        // 设置title
+        uni.setNavigationBarTitle({ title: decodeURIComponent(options.classifyName) })
+    },
+    onReachBottom() {
+        if(this.finished) return
+        this.page++
+        this.getList()
+    },
+    methods: {
+        //获取研报列表
+        async getList(){
+            const res=await apiReportList({
+                classify_id_first:Number(this.classify_id_first),
+                classify_id_second:0,
+                key_word:this.searchVal,
+                current_index:this.page,
+                page_size:this.pageSize
+            })
+            if(res.code===200){
+                let arr=res.data.list||[]
+                this.list=[...this.list,...arr]
+                if(res.data.paging.is_end){
+                this.finished=true
+                }
+            }
+        },
+
+        onChange(e) {
+            this.searchVal = e;
+        },
+
+        onSearch() {
+            console.log("搜索", this.searchVal);
+            this.page=1
+            this.finished=false
+            this.list=[]
+            if(!this.searchVal) return
+            this.getList()
+        },
+
+        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
+            }
+            // 判断是否为同一个音频
+            if(this.$store.state.report.audioData.reportId==item.report_id){
+                if(this.globalBgMusic.paused){
+                    this.globalBgMusic.play()
+                    this.$store.commit('showPopAudio')
+                }else{
+                    this.globalBgMusic.pause()
+                }
+            }else{
+                this.$store.commit('addAudio', {list:item.video_list,reportId:item.report_id})
+            }
+        },
+
+    }
+}
+</script>
+
+<style>
+page{
+  padding-bottom: 0;
+}
+</style>
+
+<style lang="scss" scoped>
+.report-list-wrap {
+  padding: 0 34rpx;
+  .item {
+    padding-bottom: 30rpx;
+    margin-bottom: 30rpx;
+    border-bottom: 1px solid #EDEDED;
+    .img {
+      width: 120rpx;
+      height: 160rpx;
+      background-color: #f5f5f5;
+      flex-shrink: 0;
+      margin-right: 20rpx;
+      border-radius: 16rpx;
+    }
+    .con {
+      flex: 1;
+      position: relative;
+      overflow: hidden;
+      .title {
+        font-size: 32rpx;
+        font-weight: bold;
+        margin-bottom: 8rpx;
+      }
+      
+      .time {
+        position: absolute;
+        color: #666666;
+        bottom: 0;
+        left: 0;
+        font-size: 28rpx;
+      }
+      .audio-box {
+        position: absolute;
+        bottom: 0;
+        right: 0;
+        width: 99rpx;
+        height: 39rpx;
+        background: #E3B377;
+        border-radius: 20rpx;
+        color: #fff;
+        font-size: 24rpx;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        image{
+          width: 30rpx;
+          height: 30rpx;
+          margin-right: 4rpx;
+        }
+      }
+      .grey-audio-box {
+        background: linear-gradient(114deg, #b0b0b0 0%, #e5e2e2 100%);
+      }
+    }
+  }
+}
+</style>

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

@@ -143,8 +143,8 @@ export default {
             if(!this.info.auth_ok) return
             if(!item.video_url){
                 uni.showToast({
-                title: '暂无音频',
-                icon: 'none'
+                    title: '暂无音频',
+                    icon: 'none'
                 })
                 return
             }
@@ -152,6 +152,7 @@ export default {
             if(this.$store.state.report.audioData.reportId==item.report_id){
                 if(this.globalBgMusic.paused){
                     this.globalBgMusic.play()
+                    this.$store.commit('showPopAudio')
                 }else{
                     this.globalBgMusic.pause()
                 }

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


+ 6 - 1
pages.json

@@ -177,6 +177,10 @@
 						"enablePullDownRefresh": true
 					}
 				},
+				// 报告列表搜索页
+				{
+					"path": "reportListSearch"
+				},
 				//报告详情
 				{
 					"path": "reportDetail"
@@ -257,7 +261,8 @@
   		"van-collapse-item": "/wxcomponents/vant/collapse-item/index",
 			"van-tag": "/wxcomponents/vant/tag/index",
 			"van-row": "/wxcomponents/vant/row/index",
-  		"van-col": "/wxcomponents/vant/col/index"
+  		"van-col": "/wxcomponents/vant/col/index",
+			"van-progress": "/wxcomponents/vant/progress/index"
 		}
 	}
 }

+ 10 - 0
store/modules/report.js

@@ -6,6 +6,7 @@ const reportModules={
             index:0,//当前是播放第几个
             reportId:0,//当前是哪个报告的音频
             paused:true,//当前是否音频正在播放 true暂停状态
+
         }
     },
     mutations: {
@@ -18,6 +19,7 @@ const reportModules={
         updateAudioIndex(state,e){
             state.audioData.index=e
         },
+        // 音频状态
         updateAudioPause(state,e){
             state.audioData.paused=e
         },
@@ -27,6 +29,14 @@ const reportModules={
             state.audioData.index=0
             state.audioData.reportId=0
             state.audioData.paused=true
+        },
+        //显示弹窗
+        showPopAudio(state){
+            state.audioData.show=true
+        },
+        // 关闭弹窗
+        closePopAudio(state){
+            state.audioData.show=false
         }
     }
 }