瀏覽代碼

Merge branch 'yb9.2'

jwyu 2 年之前
父節點
當前提交
1f63e34e18

+ 6 - 0
App.vue

@@ -37,6 +37,12 @@
 					console.log('设置屏幕常亮失败:',res);
 				}
 			})
+			if(ENV.envVersion!=='release'){
+				// 打开调试
+				wx.setEnableDebug({
+					enableDebug: true
+				})
+			}
 		},
 		onShow: function(options) {
 			console.log('App Show')

+ 57 - 0
api/voice.js

@@ -8,6 +8,8 @@ import { httpGet, httpPost } from "@/utils/request.js";
  * @param page_size
  * @param broadcast_id 语音id
  * @param section_id 板块id
+ * @param author_id 作者ID(我的语音播报列表)
+ * @param mine_status 语音播报状态:0-未发布 1-已发布 2-全部(我的语音播报列表)
  */
 export const apiVoiceList=params=>{
     return httpPost('/voice/broadcast/list',params)
@@ -51,4 +53,59 @@ export const apiVoiceDetail=params=>{
  */
 export const apiVoiceSendMsg=params=>{
     return httpPost('/voice/broadcast/msg_send',params)
+}
+
+/**
+ * 新增语音
+ * @param broadcast_name 语音标题
+ * @param section_id 板块ID
+ * @param section_name 板块名称
+ * @param variety_id 品种ID
+ * @param variety_name 品种名称
+ * @param author_id 作者ID
+ * @param author 作者名称
+ * @param imgs 图片:英文逗号拼接
+ * @param voice_seconds 音频时长
+ * @param voice_size 音频大小
+ * @param voice_url 音频地址
+ */
+export const apiVoiceAdd=params=>{
+    return httpPost('/voice/broadcast/add',params)
+}
+
+/**
+ * 编辑语音
+ * @param broadcast_id 语音播报ID
+ * @param broadcast_name 语音标题
+ * @param section_id 板块ID
+ * @param section_name 板块名称
+ * @param variety_id 品种ID
+ * @param variety_name 品种名称
+ * @param author_id 作者ID
+ * @param author 作者名称
+ * @param imgs 图片:英文逗号拼接
+ * @param voice_seconds 音频时长
+ * @param voice_size 音频大小
+ * @param voice_url 音频地址
+ */
+export const apiVoiceEdit=params=>{
+    return httpPost('/voice/broadcast/edit',params)
+}
+
+/**
+ * 发布语音
+ * @param broadcast_id 语音播报ID
+ * @param publish_type 发布类型:1-发布 2-定时发布
+ * @param pre_publish_time 预发布时间(类型为定时发布时必填)
+ */
+export const apiVoicePublish=params=>{
+    return httpPost('/voice/broadcast/publish',params)
+}
+
+/**
+ * 我的语音数量统计
+ * @param author_id
+ */
+export const apiMyVoiceCount=params=>{
+    return httpGet('/voice/broadcast/list_count',params)
 }

+ 316 - 79
pages-voice/addVoice.vue

@@ -29,6 +29,24 @@
             @click-icon="showFilter=true"
         />
 
+        <!-- 上传图片部分 -->
+        <view 
+            class="flex upload-img-box" 
+            v-if="recorderStatus!=='doing'&&recorderStatus!=='pause'"
+            :style="[{'height':recorderStatus==='stop'&&'auto'},{'border-bottom':recorderStatus==='stop'?'1px solid #E6E6E6':''}]"
+        >
+            <view class="item" v-for="(item,index) in imgList" :key="item" @click="handlePreViewImg(item)">
+                <image :src="item" mode="aspectFill"/>
+                <view class="del-btn" @click.stop="handleDelImg(index)">
+                    <van-icon name="cross" size="12" style="position: absolute;left:16rpx;top:8rpx" color="#ffffff"/>
+                </view>
+            </view>
+            <view class="item add-btn" @click="handleUploadImg" v-if="imgList.length<5">
+                <image src="./static/camera.png" mode="aspectFill" />
+            </view>
+              
+        </view>
+
         <view class="flex audio-box" v-if="recorderStatus==='stop'">
             <image 
                 :src="temAudio.paused?'../../../static/voice/pause.png':'../../../static/voice/playing.png'" 
@@ -49,14 +67,14 @@
                 <image src="./static/del.png" mode="aspectFill" />
                 <text>删除</text>
             </view>
-              
+            <view class="pre_publish_time" v-if="voiceId!=0">定时发布时间:{{pre_publish_time}}</view>
         </view>
           
 
-        <view class="empty-voice-box" v-if="recorderStatus==='start'">
+        <!-- <view class="empty-voice-box" v-if="recorderStatus==='start'">
             <image src="./static/record.png" mode="aspectFill" />
             <view>无录音(录音时长超过十分钟自动结束)</view>
-        </view>
+        </view> -->
 
         <view class="animat-box" v-if="recorderStatus==='doing'||recorderStatus==='pause'">
             <view class="con-box">
@@ -65,10 +83,10 @@
                 <image :class="['img move3',recorderStatus==='doing'?'animat-run':'animat-pause']" src="./static/record-img.png" mode="widthFix" />
             </view>
             <view class="bot-text">{{time|formatTime}}</view>
-        </view>
+        </view> 
 
         <view class="sound-record-wrap" v-if="recorderStatus!=='stop'">
-            <view class="top-text">点击开始录音</view>
+            <view class="top-text" v-show="recorderStatus=='start'">点击开始录音</view>
             <image class="btn" :src="btnImg" mode="aspectFill" @click="handleClickBtn" />
             <view 
                 class="del-btn" 
@@ -81,9 +99,13 @@
                 v-if="recorderStatus!=='start'"
                 @click="handleEndRecorder"
             >完成</view>
+            <view style="text-align:center;color:#999;margin-top:44rpx" v-if="recorderStatus==='start'">无录音(录音时长超过十分钟自动结束)</view>
         </view>
 
-        <view class="publish-btn" v-if="recorderStatus==='stop'" @click="handlePublish">发布</view>
+        <view class="publish-btn" v-if="recorderStatus==='stop'">
+            <text @click="handlePublish('time')">定时发布</text>
+            <text @click="handlePublish">立即发布</text>
+        </view>
         
         <!-- 筛选弹窗 -->
         <van-popup 
@@ -110,15 +132,67 @@
             </view>
         </van-popup>
 
-        <van-dialog id="van-dialog" />
+        <!-- 选择时间弹窗 -->
+        <van-popup 
+            :show="showTime" 
+            position="bottom"  
+            :close-on-click-overlay="true"
+            @close="showTime = false"
+            round
+        >
+            <van-datetime-picker
+                title="设置发布时间"
+                type="datetime"
+                :value="selectTime"
+                :min-date="minDate"
+                @confirm="handleConfirmTime"
+                @cancel="showTime = false"
+            />
+        </van-popup>
+
+        <!-- <van-dialog id="van-dialog" /> -->
+        <!-- 发布弹窗 -->
+        <van-dialog
+            use-slot
+            :show="showPublish"
+            confirm-button-text="发布且推送"
+            cancel-button-text="仅发布"
+            show-cancel-button
+            @confirm="handleConfirmPublish(1)"
+            @cancel="handleConfirmPublish(0)"
+            @close="showPublish=false"
+        >
+            <view style="padding:40px 20px 20px;text-align:center;position: relative;">
+                发布后将推送模板消息和客群,确认发布吗?
+                <van-icon name="cross" size="20" style="position: absolute;right:10px;top:10px" color="#6666" @click="showPublish=false"/>
+            </view>
+        </van-dialog>
+
+        <!-- 定时发布提示弹窗 -->
+        <van-dialog
+            use-slot
+            :show="showTimeAttention"
+            confirm-button-text="知道了"
+            confirm-button-color="#E3B377"
+            @confirm="showTime=true"
+            @close="showTimeAttention=false,showTime=true"
+        >
+            <view style="padding:40px 20px 20px;text-align:center;position: relative;">
+                设置定时发布后,会在设定的时间发布语音播报并推送模板消息
+                <van-icon name="cross" size="20" style="position: absolute;right:10px;top:10px" color="#666" @click="showTimeAttention=false,showTime=true"/>
+            </view>
+        </van-dialog>
     </view>
 </template>
 
 <script>
-import {apiVoiceSectionList,apiVoiceSendMsg} from '@/api/voice'
+import {apiVoiceSectionList,apiVoiceSendMsg,apiVoiceAdd,apiVoiceEdit,apiVoicePublish,apiVoiceDetail} from '@/api/voice'
 import {baseApiUrl} from '@/utils/config.js'
+import {apiGetSceneToParams} from '@/api/common'
 import CryptoJS from '@/utils/crypto.js'
 import uniAsync from "@/utils/uni-async.js"; // uni api async 化
+import {uploadImg,commonUploadAudio} from '@/utils/upload'
+const moment=require('@/utils/moment-with-locales.min')
 const recorderManager = wx.getRecorderManager();//录音实例
 let innerAudioContext = uni.createInnerAudioContext();//播放音频实例
 let TIMER=null//计时器
@@ -151,15 +225,18 @@ export default {
                 variety_id:'',
                 section_id:'',
                 section_name:'',
-                img_url:''
+                img_url:'',//分享时的底图
             },
+            voiceId:0,
+            voiceUrl:'',//编辑音频地址
+            pre_publish_time:'',
 
             recorderStatus:'start',//当前录音状态 start开始 doing正在录音 stop停止录音 pause录音暂停
             time:0,
             isReset:false,//是否点击了重置
 
             temAudio:{
-                url:'',//临时音频地址
+                url:'',//音频地址
                 duration:'',//时长
                 size:'',//大小
                 curTime:0,//播放时当前播放的时间
@@ -170,17 +247,26 @@ export default {
             options:[],
             mainActiveIndex:0,
             activeId:0,//选择的板块id
+
+            showPublish:false,
+
+            imgList:[],
+            showTime:false,
+            showTimeAttention:false,
+            selectTime:new Date().getTime(),
+            minDate:new Date().getTime()+600000,
         }
     },
-    onLoad(){
+    onLoad(options){
         // 调取用户授权使用麦克风
         uni.authorize({
             scope: 'scope.record',
             success() {}
         })
         this.listenVoice()
-        
         this.getOptionsList()
+
+        this.init(options)
     },
     onShow(){
         innerAudioContext = uni.createInnerAudioContext()
@@ -192,8 +278,45 @@ export default {
     },
     onUnload(){
         innerAudioContext.destroy()
+        clearInterval(TIMER)
 	},
     methods: {
+        async init(options){
+            if(options.scene){  
+                const res=await apiGetSceneToParams({scene_key:options.scene})
+                if(res.code===200){
+                    const obj=JSON.parse(res.data)
+                    this.voiceId=Number(obj.voiceId)
+                    this.getVoiceDetail()
+                }
+            }else if(options.voiceId){
+                this.voiceId=Number(options.voiceId)
+                this.getVoiceDetail()
+            }
+        },
+
+        //语音详情
+        async getVoiceDetail(){
+            uni.setNavigationBarTitle({ title: '编辑语音' })
+            const res=await apiVoiceDetail({broadcast_id:Number(this.voiceId)})
+            if(res.code===200){
+                this.form.title=res.data.BroadcastName
+                this.form.variety_name=res.data.VarietyName
+                this.form.variety_id=res.data.VarietyId
+                this.form.section_id=res.data.SectionId
+                this.form.section_name=res.data.SectionName
+                this.voiceUrl=res.data.VoiceUrl
+                this.temAudio.url=res.data.VoiceUrl
+                this.temAudio.duration=res.data.VoicePlaySeconds
+                this.temAudio.size=res.data.VoiceSize
+                this.activeId=res.data.SectionId
+                this.imgList=res.data.Imgs||[]
+                this.pre_publish_time=moment(res.data.PrePublishTime).format('YYYY-MM-DD HH:mm')
+                this.selectTime=moment(res.data.PrePublishTime).valueOf()
+                this.recorderStatus='stop'
+            }
+        },
+
         //录音事件
         listenVoice(){
             recorderManager.onStart(()=>{
@@ -392,7 +515,7 @@ export default {
         },
 
         // 发布
-        handlePublish(){
+        async handlePublish(type){
             if(!this.form.title||!this.form.variety_id){
                 uni.showToast({
 					title:'请将内容填写完整',
@@ -401,30 +524,37 @@ export default {
                 return
             }
 
-            this.$dialog.confirm({
-                title:'',
-                message: '发布后将推送模板消息和客群,确认发布吗?',
-                confirmButtonText:'发布且推送',
-                cancelButtonText:'仅发布'
-            }).then(()=>{
-                //发布且推送
-                this.handleConfirmPublish(false)
-            }).catch(()=>{
-                //仅仅是发布
-                this.handleConfirmPublish(true)
-            })
+            if(type==='time'){//定时发布
+                this.showTimeAttention=true
+            }else{
+                this.showPublish=true
+            }
         },
-        //确认发布 onlyPublished:true仅发布
-        handleConfirmPublish(onlyPublished){
-            let formData={
+
+        //确认发布 publishType 发布类型: 0-仅发布 1-发布并推送 2-定时发布
+        async handleConfirmPublish(publishType){
+
+            //上传音频
+            if(this.temAudio.url!=this.voiceUrl){
+                const voiceRes=await commonUploadAudio(this.temAudio.url)
+                if(voiceRes.code===200){
+                    this.temAudio.url=voiceRes.data.audio_url
+                }
+            }
+            
+            //新增、编辑语音
+            let params={
                 broadcast_name:this.form.title,
                 section_id:Number(this.form.section_id),
                 section_name:this.form.section_name,
                 variety_id:Number(this.form.variety_id),
                 variety_name:this.form.variety_name,
-                img_url:this.form.img_url,
                 author_id:Number(this.$store.state.user.userInfo.user_id),
-                author:this.$store.state.user.userInfo.real_name
+                author:this.$store.state.user.userInfo.real_name,
+                imgs:this.imgList.join(','),
+                voice_seconds:this.temAudio.duration.toString(),
+                voice_size:this.temAudio.size.toString(),
+                voice_url:this.temAudio.url
             }
             wx.showLoading({
                 title: '发布中...',
@@ -433,51 +563,61 @@ export default {
                 fail: () => {},
                 complete: () => {}
             });
-            uni.uploadFile({
-                url: baseApiUrl + "/voice/broadcast/add",
-                filePath: this.temAudio.url,
-                name: 'file',
-                header: {
-                    Authorization: this.$store.state.user.token,
-                },
-                formData: formData,
-                success: (result) => {
-                    const { envVersion } = uni.getAccountInfoSync().miniProgram
-                    const res =  envVersion === 'release' ? JSON.parse(CryptoJS.Des3Decrypt(result.data)) :  JSON.parse(result.data);
-                    console.log(res);
-                    wx.hideLoading();
-                    if(res.code===200){
-                        if(onlyPublished){
-                            uni.showToast({
-                                title:'发布成功',
-                                icon:'success'
-                            })
-                            setTimeout(() => {
-                                uni.$emit('addVoiceSuccess')
-                                uni.navigateBack()
-                            }, 1000);
-                        }else{
-                            //需要推送
-                            this.handleSendMsg(res.data)
-                        }
-                    }else{
+            let addRes=null
+            if(this.voiceId!=0){//编辑语音
+                params.broadcast_id=this.voiceId
+                addRes=await apiVoiceEdit(params)
+            }else{
+                addRes=await apiVoiceAdd(params)
+            }
+            if(addRes.code===200){
+                let par={
+                    broadcast_id:addRes.data.BroadcastId,
+                }
+                if(publishType===2){//定时发布
+                    par.publish_type=2
+                    par.pre_publish_time=moment(this.selectTime).format('YYYY-MM-DD HH:mm:ss')
+                }else{
+                    par.publish_type=1
+                }
+                //发布语音
+                const publishRes=await apiVoicePublish(par)
+                wx.hideLoading();
+                if(publishRes.code===200){
+                    if(publishType==0){//仅发布
                         uni.showToast({
-                            title:res.msg,
-                            icon:'none'
+                            title:'发布成功',
+                            icon:'success'
                         })
+                        setTimeout(() => {
+                            uni.$emit('addVoiceSuccess')
+                            uni.navigateBack()
+                        }, 1000);
+                    }else if(publishType==1){//发布并推送
+                        this.handleSendMsg(addRes.data.BroadcastId)
+                    }else{////定时发布
+                        uni.showToast({
+                            title:'定时发布成功',
+                            icon:'success'
+                        })
+                        setTimeout(() => {
+                            uni.$emit('addVoiceSuccess')
+                            uni.navigateBack()
+                        }, 1000);
                     }
-                },
-                fail: () => {
-                    console.log('发布失败');
+                }else{
                     uni.showToast({
-                        title:'发布失败,请稍后重试!',
+                        title:publishRes.msg,
                         icon:'none'
                     })
-                },
-                complete: () => {
-                    wx.hideLoading();
                 }
-            });
+            }else{
+                wx.hideLoading();
+                uni.showToast({
+                    title:addRes.msg,
+                    icon:'none'
+                })
+            }
         },
 
         //推送消息
@@ -494,7 +634,41 @@ export default {
                     }, 1000);
                 }
             })
-        }
+        },
+
+        //图片上传
+        handleUploadImg(e){
+            uploadImg({count:5-this.imgList.length}).then(res=>{
+                this.imgList=[...this.imgList,...res]
+            }).catch(err=>{
+                console.log(err);
+                if(err.errMsg=='chooseImage:fail cancel') return
+                uni.showToast({
+                    title:'上传失败,请重试!',
+                    icon:'none'
+                })
+            })
+        },
+
+        //预览图片
+        handlePreViewImg(item){
+            wx.previewImage({
+                urls:this.imgList,
+                current:item
+            })
+        },
+
+        //删除图片
+        handleDelImg(index){
+            this.imgList.splice(index,1)
+        },
+
+        //选择时间
+        handleConfirmTime(e){
+            this.selectTime=e.detail
+            this.showTime=false
+            this.handleConfirmPublish(2)
+        },
 
     },
 }
@@ -554,7 +728,7 @@ page{
 <style lang="scss" scoped>
 .add-voice-page{
     .empty-voice-box{
-        height: 50vh;
+        height: 36vh;
         padding-top: 150rpx;
         image{
             width: 140rpx;
@@ -648,19 +822,82 @@ page{
                 margin-right: 10rpx;
             }
         }
+        .pre_publish_time{
+            position: absolute;
+            bottom: -50rpx;
+            left: 0;
+            color: #999999;
+        }
     }
 
     .publish-btn{
-        width: 390rpx;
-        height: 80rpx;
+        // width: 390rpx;
+        // height: 80rpx;
+        // text-align: center;
+        // line-height: 80rpx;
+        // color: #fff;
+        // background: #E6B77D;
+        // font-size: 32rpx;
+        // border-radius: 40px;
+        // margin-left: auto;
+        // margin-right: auto;
         text-align: center;
-        line-height: 80rpx;
-        color: #fff;
-        background: #E6B77D;
-        font-size: 32rpx;
-        border-radius: 40px;
-        margin-left: auto;
-        margin-right: auto;
+        text{
+            width: 300rpx;
+            height: 80rpx;
+            text-align: center;
+            line-height: 80rpx;
+            display: inline-block;
+            font-size: 32rpx;
+            margin: 0 15rpx;
+            border-radius: 40rpx;
+        }
+        text:first-child{
+            border: 1px solid #E6B77D;
+            color: #E6B77D;
+        }
+        text:last-child{
+            background-color: #E6B77D;
+            color: #fff;
+        }
+    }
+
+    .upload-img-box{
+        padding: 34rpx 4rpx 34rpx 34rpx;
+        flex-wrap: wrap;
+        height: 50vh;
+        align-content: flex-start;
+        .item{
+            width: 200rpx;
+            height: 200rpx;
+            margin-right: 30rpx;
+            margin-bottom: 30rpx;
+            flex-shrink: 0;
+            position: relative;
+            image{
+                width: 100%;
+                height: 100%;
+            }
+            .del-btn{
+                position: absolute;
+                right: 0;
+                top: 0;
+                width: 48rpx;
+                height: 48rpx;
+                background-color: rgba(0, 0, 0, 0.7);
+                border-radius: 0 0 0 48rpx;
+            }
+        }
+        .add-btn{
+            background-color: #f7f7f7;
+            image{
+                width: 80rpx;
+                height: 80rpx;
+                position: absolute;
+                left: 60rpx;
+                top: 60rpx;
+            }
+        }
     }
 }
 

+ 449 - 0
pages-voice/myVoice.vue

@@ -0,0 +1,449 @@
+<template>
+    <view class="my-voice-page">
+        <view class="top-tab-warp">
+           <text 
+            :class="['item',status==opt.value?'item-active':'']" 
+            v-for="opt in statusOpt" 
+            :key="opt.value"
+            @click="handleOptChange(opt)"
+        >{{opt.lable}}({{opt.count}})</text>
+        </view>
+
+        <view class="empty-box" v-if="finished&&list.length==0">
+            <image :src="globalImgUrls.activityNoAuth" mode="widthFix" />
+            <view>暂无数据</view>
+        </view>
+        <view class="list-wrap" v-else>
+            <view class="item" v-for="item in list" :key="item.BroadcastId" @click="handleGoDetail(item)">
+                <view class="title">{{item.BroadcastName}}</view>
+                <view class="time" v-if="item.PublishState==0">保存时间:{{item.ModifyTime|formatTime}}</view>
+                <view class="time" v-else>发布时间:{{item.PublishTime|formatTime}}</view>
+                <view class="flex audio-box" @click.stop="handlePlay(item)">
+                    <image 
+                        :src="item.BroadcastId==curVoiceId&&!curAudioPaused?require('@/static/voice/playing.png'):require('@/static/voice/pause.png')" 
+                        mode="widthFix" 
+                    />
+                    <text>{{item.VoicePlaySeconds|formatVoiceTime}}</text>
+                </view>
+                <view class="btns-box">
+                    <button 
+                        v-if="item.PublishState!=0"
+                        class="btn" 
+                        open-type="share" 
+                        :data-item="item"
+                        @click.stop=""
+                    >
+                        <image class="share-img" src="@/static/share-icon.png" mode="aspectFill"/>
+                    </button>
+                    <button class="btn" @click.stop="handleDelItem(item)">
+                        <image class="del-img" src="@/static/voice/del.png" mode="widthFix" v-if="item.IsAuthor" />
+                    </button>
+                    <button class="btn" @click.stop="handleSendMsgItem(item)" v-if="item.CouldSendMsg&&item.PublishState!=0">
+                        <image class="publish-img" src="@/static/voice/publish.png" mode="widthFix" />
+                    </button>
+                    <button class="btn" @click.stop="handlePublish(item)" v-if="item.PublishState==0">
+                        <image class="clock-img" src="./static/clock-icon.png" mode="widthFix" />
+                    </button>
+                </view>
+            </view>
+        </view>
+
+
+        <!-- 音频悬浮 -->
+        <view v-if="showPage">
+        <audioBox v-if="showAudioPop"/>
+        </view>
+        
+        <van-dialog id="van-dialog" />
+    </view>
+</template>
+
+<script>
+import {apiVoiceList,apiVoicePlayRecord,apiVoiceDel,apiVoiceSendMsg,apiVoicePublish,apiMyVoiceCount} from '@/api/voice'
+import audioBox from '@/components/audioBox/audioBox.vue'
+const moment=require('@/utils/moment-with-locales.min')
+export default {
+    components:{
+        audioBox
+    },
+    filters:{
+        formatTime(e){
+            return moment(e).format('YYYY-MM-DD HH:mm:ss')
+        },
+        formatVoiceTime(e){
+            let m=parseInt(e/60)
+            let s=parseInt(e%60)
+            return `${m>9?m:'0'+m}:${s>9?s:'0'+s}`
+        }
+    },
+    computed:{
+        showAudioPop(){//是否显示音频弹窗
+            return this.$store.state.audio.show
+        },
+        showAudioBigPop(){
+            return this.$store.state.audio.showBig
+        },
+        curVoiceId(){//当前正在播放的音频id
+            return this.$store.state.audio.voiceId
+        },
+        curAudioPaused(){//当前音频是否暂停状态
+            return this.$store.state.audio.paused
+        },
+    },
+    data() {
+        return {
+            page:1,
+            pageSize:20,
+            list:[],
+            finished:false,
+            status:0,//0-未发布 1-已发布 2-全部(我的语音播报列表)
+            statusOpt:[
+                {
+                    lable:'未发布',
+                    count:0,
+                    value:0,
+                    key:'Unpublished'
+                },
+                {
+                    lable:'已发布',
+                    count:0,
+                    value:1,
+                    key:'Published'
+                },
+                {
+                    lable:'全部',
+                    count:0,
+                    value:2,
+                    key:'All'
+                }
+            ],
+
+            showPage:false,
+        }
+    },
+    onLoad(){
+        this.getCount()
+        this.getList()
+        this.addListenVoiceSuccess()
+    },
+    onShow(){
+        this.showPage=true
+    },
+    onHide(){
+        this.showPage=false
+    },
+    onUnload(){
+		uni.$off('addVoiceSuccess')
+	},
+    onPullDownRefresh(){
+        this.page=1
+        this.list=[]
+        this.finished=false
+        this.getList()
+        setTimeout(() => {
+            uni.stopPullDownRefresh()
+        }, 1500)
+    },
+    onReachBottom() {
+        if(this.finished) return
+        this.page++
+        this.getList()
+    },
+    onShareAppMessage({from,target}) {
+        console.log(from,target);
+        let path='/pages/voice/voice'
+        let title='语音播报'
+        let imageUrl=''
+        if(from=='button'){
+            title=`${target.dataset.item.SectionName}:${target.dataset.item.BroadcastName}`
+            path=`/pages-voice/voiceDetail?voiceId=${target.dataset.item.BroadcastId}`
+            imageUrl=target.dataset.item.ImgUrl
+        }
+        return {
+            title:title,
+            path:path,
+            imageUrl:imageUrl
+        }
+    },
+    methods: {  
+        // 监听添加音频成功刷新列表
+        addListenVoiceSuccess(){
+            uni.$on('addVoiceSuccess',()=>{
+                this.page=1
+                this.list=[]
+                this.finished=false
+                this.getCount()
+                this.getList()
+            })
+        },
+
+        //获取列表数据
+        async getList(){
+            const res=await apiVoiceList({
+                page_index:this.page,
+                page_size:this.pageSize,
+                author_id:Number(this.$store.state.user.userInfo.user_id),
+                mine_status:this.status
+            })
+            if(res.code===200){
+                let arr=res.data.List||[]
+                this.list=[...this.list,...arr]
+                if(arr.length===0){
+                    this.finished=true
+                }
+            }
+        },
+
+        //获取数量
+        async getCount(){
+            const res=await apiMyVoiceCount({author_id:this.$store.state.user.userInfo.user_id})
+            if(res.code===200){
+                this.statusOpt.forEach(item => {
+                    item.count=res.data[item.key]
+                })
+            }
+        },
+
+        //状态改变
+        handleOptChange(item){
+            this.status=item.value
+            this.page=1
+            this.list=[]
+            this.finished=false
+            this.getList()
+        },
+
+        //跳转详情
+        handleGoDetail(item){
+            if(item.PublishState==0){//未发布跳转编辑
+                uni.navigateTo({
+                    url: '/pages-voice/addVoice?voiceId='+item.BroadcastId,
+                });
+            }else{
+                uni.navigateTo({
+                    url: '/pages-voice/voiceDetail?voiceId='+item.BroadcastId,
+                });
+            }
+            
+        },
+        
+        //推送消息
+        handleSendMsgItem(item){
+            this.$dialog.confirm({
+                title:'',
+                message: '该操作将推送模板消息和客群,确认推送吗?',
+                confirmButtonText:'确认'
+            }).then(()=>{
+                apiVoiceSendMsg({broadcast_id:item.BroadcastId}).then(res=>{
+                    if(res.code===200){
+                        uni.showToast({
+                            title:"推送成功",
+                            icon:'success'
+                        })
+                        item.CouldSendMsg=false
+                    }
+                })
+            }).catch(()=>{})
+        },
+
+        //删除音频
+        handleDelItem(item){
+            this.$dialog.confirm({
+                title:'',
+                message: '确定要删除该语音播报吗?',
+                confirmButtonText:'确定'
+            }).then(()=>{
+                if(this.curVoiceId==item.BroadcastId&&!this.curAudioPaused){
+                    //删除的音频正好在播放则暂停
+                    this.globalBgMusic.stop()
+                }
+                apiVoiceDel({broadcast_id:Number(item.BroadcastId)}).then(res=>{
+                    if(res.code===200){
+                        uni.showToast({
+                            title:'操作成功',
+                            icon:'none'
+                        })
+                        this.page=1
+                        this.list=[]
+                        this.finished=false
+                        this.getList()
+                        this.getCount()
+                    }
+                })
+            }).catch(()=>{})
+        },
+
+        //未发布时点击立即发布并且推送
+        handlePublish(item){
+            this.$dialog.confirm({
+                title:'',
+                message: '该操作将发布并且推送模板消息和客群',
+                confirmButtonText:'确认'
+            }).then(async ()=>{
+                const pubRes=await apiVoicePublish({
+                    broadcast_id:Number(item.BroadcastId),
+                    publish_type:1
+                })
+                if(pubRes.code===200){
+                    const sendRes=await apiVoiceSendMsg({broadcast_id:item.BroadcastId})
+                    if(sendRes.code===200){
+                        uni.showToast({
+                            title:'发布且推送成功',
+                            icon:'success'
+                        })
+                        setTimeout(() => {
+                            this.page=1
+                            this.list=[]
+                            this.finished=false
+                            this.getList()
+                            this.getCount()
+                        }, 1000);
+                    }else{
+                        uni.showToast({
+                            title:sendRes.msg,
+                            icon:'none'
+                        })
+                    }
+                }else{
+                    uni.showToast({
+                        title:pubRes.msg,
+                        icon:'none'
+                    })
+                }
+            }).catch(()=>{})
+        },
+
+        //点击音频 播放或者暂停
+        handlePlay(item){
+            if(this.$store.state.audio.voiceId==item.BroadcastId){
+                if(this.globalBgMusic.paused){
+                    this.globalBgMusic.play()
+                }else{
+                    this.globalBgMusic.pause()
+                }
+            }else{
+                const list=[{url:item.VoiceUrl,time:item.VoicePlaySeconds,title:item.BroadcastName,}]
+                this.$store.commit('audio/addAudio',{
+                    list:list,
+                    voiceId:item.BroadcastId
+                })
+                this.handleVoicePlayRecord(item)
+            }
+        },
+
+        //上报音频播放记录
+        async handleVoicePlayRecord(item){
+            const res=await apiVoicePlayRecord({
+                broadcast_id:item.BroadcastId
+            })
+            if(res.code===200){
+                console.log('上报音频播放记录');
+            }
+        }
+    },
+}
+</script>
+
+<style lang="scss" scoped>
+.empty-box{
+    text-align: center;
+    font-size: 32rpx;
+    color: #999;
+    padding-top: 150rpx;
+    image{
+        width: 600rpx;
+        margin-bottom: 57rpx;
+    }
+}
+.top-tab-warp{
+    padding: 34rpx;
+    position: sticky;
+    top: 0;
+    left: 0;
+    background: #ffffff;
+    z-index: 99;
+    .item{
+        box-sizing: border-box;
+        width: 200rpx;
+        text-align: center;
+        padding: 20rpx 10rpx;
+        background: #F5F5F5;
+        border-radius: 4rpx;
+        margin-right: 30rpx;
+        display: inline-block;
+        &:last-child{
+            margin-right: 0;
+        }
+    }
+    .item-active{
+        background: #FDF8F2;
+        color: #E3B377;
+    }
+}
+.list-wrap{
+    padding: 0 34rpx 34rpx 34rpx;
+    .item{
+        border-bottom: 1px solid #CDCDCD;
+        padding: 30rpx 0;
+        position: relative;
+
+        .btns-box{
+            position: absolute;
+            bottom: 34rpx;
+            right: 0;
+            
+            .btn{
+                float: right;
+                margin-left: 60rpx;
+                background-color: transparent;
+                line-height: 1;
+                padding: 0;
+                &::after{
+                    border: none;
+                }
+                .publish-img{
+                    width: 34rpx;
+                    height: 34rpx;
+                }
+                .del-img{
+                    width: 34rpx;
+                    height: 34rpx;
+                }
+                .share-img{
+                    width: 32.5rpx;
+                    height: 32rpx;
+                }
+                .clock-img{
+                    width: 32rpx;
+                    height: 33.5rpx;
+                }
+            }
+        }
+
+
+        .title{
+            font-size: 32rpx;
+        }
+        .time{
+            font-size: 28rpx;
+            color: #666;
+            margin-top: 20rpx;
+            margin-bottom: 30rpx;
+        }
+        .audio-box{
+            width: 185rpx;
+            height: 56rpx;
+            align-items: center;
+            justify-content: center;
+            border-radius: 28rpx;
+            background-color: #F4E1C9;
+            color: #E3B377;
+            image{
+                width: 23rpx;
+                height: 28rpx;
+                margin-right: 20rpx;
+            }
+        }
+    }
+}
+</style>

二進制
pages-voice/static/camera.png


二進制
pages-voice/static/clock-icon.png


+ 28 - 0
pages-voice/voiceDetail.vue

@@ -22,6 +22,19 @@
         </view>
         <image class="del-btn" src="@/static/voice/del.png" mode="widthFix" @click="handleDel" v-if="info.IsAuthor"/>
         <image class="publish-btn" src="@/static/voice/publish.png" mode="widthFix" @click="handleSendMsg" v-if="info.CouldSendMsg"/>
+
+        <!-- 图片部分 -->
+        <view class="imgs-box">
+            <image 
+                v-for="item in info.Imgs"
+                :key="item"
+                :src="item" 
+                mode="widthFix" 
+                lazy-load="false"
+                @click="preViewImg(item)"
+            />
+        </view>
+          
         
         <view v-show="false"><audioBox v-if="showAudioPop"/></view>
 
@@ -204,6 +217,14 @@ export default {
             this.globalBgMusic.seek(value)
         },
 
+        //预览图片
+        preViewImg(item){
+            wx.previewImage({
+                current: item, // 当前显示图片的 http 链接
+                urls: this.info.Imgs||[] // 需要预览的图片 http 链接列表
+            })
+        }
+
 
     },
 }
@@ -273,5 +294,12 @@ export default {
             width: 36rpx;
             height: 36rpx;
         }
+        .imgs-box{
+            margin-top: 120rpx;
+            image{
+                width: 100%;
+                margin-bottom: 40rpx;
+            }
+        }
     }
 </style>

+ 9 - 1
pages.json

@@ -294,6 +294,13 @@
 					"style":{
 						"navigationBarTitleText": "播报详情"
 					}
+				},
+				{
+					"path": "myVoice",
+					"style":{
+						"navigationBarTitleText": "我的语音",
+						"enablePullDownRefresh": true
+					}
 				}
 			]
 		}
@@ -368,7 +375,8 @@
 			"van-progress": "/wxcomponents/vant/progress/index",
 			"van-dialog": "/wxcomponents/vant/dialog/index",
 			"van-cell": "/wxcomponents/vant/cell/index",
-			"van-tree-select": "/wxcomponents/vant/tree-select/index"
+			"van-tree-select": "/wxcomponents/vant/tree-select/index",
+			"van-datetime-picker": "/wxcomponents/vant/datetime-picker/index"
 		}
 	}
 }

+ 1 - 1
pages/pc.vue

@@ -20,7 +20,7 @@ const mapObj=new Map([
     ['pages/video/videoList','/video/list'],
 	['pages-sandTable/sandTable','/sandBox/list'],
     ['pages/voice/voice','/voice/list'],
-    ['pages-voice/voiceDetail','/voice/list'],
+    ['pages-voice/voiceDetail','/voice/detail'],
 ])//map映射小程序页面路径对应h5页面路径
 import {apiUserInfo} from '@/api/user'
 import {apiGetSceneToParams} from '@/api/common'

+ 1 - 1
pages/report/report.vue

@@ -20,7 +20,7 @@
 			:key="index" 
 			@click="linkPage(tab)"
 		>
-			<image :src="tab.icon+'?t='+new Date().getTime()" mode="aspectFill" class="card-ico"/>
+			<image :src="tab.icon+'?t='+new Date().getDay()" mode="aspectFill" class="card-ico"/>
 			<view class="title">{{tab.tab}}</view>
 		</view>
 	</view>

+ 13 - 0
pages/user/user.vue

@@ -71,6 +71,19 @@
 					<van-icon name="arrow"></van-icon>
 				</view>
 			</view>
+
+			<navigator url="/pages-voice/myVoice">
+				<view class="flex item-card">
+					<image src="../../static/voice/mine-voice-icon.png" mode="widthFix" />
+					<text class="label">我的语音</text>
+					<view class="right-text look">
+						<text>查看</text>
+						<van-icon name="arrow"></van-icon>
+					</view>
+				</view>
+				<view></view>
+			</navigator>
+
 			<view class="flex item-card" v-if="userInfo.status!='试用'">
 				<image src="../../static/calendar.png" mode="widthFix" />
 				<text class="label">服务截止日期</text>

+ 1 - 1
pages/voice/voice.vue

@@ -365,7 +365,7 @@ export default {
                 message: '确定要删除该语音播报吗?',
                 confirmButtonText:'确定'
             }).then(()=>{
-                if(this.temAudio.item&&this.temAudio.item.id==item.BroadcastId){
+                if(this.curVoiceId==item.BroadcastId&&!this.curAudioPaused){
                     //删除的音频正好在播放则暂停
                     this.globalBgMusic.stop()
                 }

二進制
static/voice/mine-voice-icon.png


+ 1 - 1
utils/config.js

@@ -11,7 +11,7 @@ if(env.envVersion==='develop'){//开发
 	 // h5BaseUrl='http://192.168.77.17:3000/xcx_h5'
     pcBaseUrl='https://ybpctest.hzinsights.com'
 }else if(env.envVersion==='trial'){//体验版
-    baseApiUrl='http://8.136.199.33:8612/api'
+    baseApiUrl='https://ybpctest.hzinsights.com/api'
     h5BaseUrl='http://xcxh5test.hzinsights.com/xcx_h5'
     pcBaseUrl='https://ybpctest.hzinsights.com'
 }else if(env.envVersion==='release'){//正式版

+ 43 - 1
utils/upload.js

@@ -49,7 +49,8 @@ export const uploadAudioToServer = async(tempFilePath)=>{
  * 上传图片
  * count 同时上传张数 默认:1
  */
-export const uploadImg = async (count = 1) => {
+export const uploadImg = async ({count = 1}) => {
+  console.log(count);
   const { tempFilePaths } = await uniAsync.chooseImage({ count });
   uni.showLoading({
     title: "上传中...",
@@ -68,6 +69,47 @@ export const uploadImg = async (count = 1) => {
       })
       .catch((res) => {
         uni.hideLoading();
+        reject(res)
       });
   });
 };
+
+
+/**
+ * 公共上传音频方法
+ */
+export const commonUploadAudio=(tempFilePath)=>{
+  const { envVersion } = uni.getAccountInfoSync().miniProgram
+  wx.showLoading({
+      title: '上传音频中...',
+      mask: true,
+      success: (result) => {},
+      fail: () => {},
+      complete: () => {}
+  });
+  return new Promise((resolve,reject)=>{
+    uni.uploadFile({
+      url: baseApiUrl + "/public/upload_audio",
+      filePath: tempFilePath,
+      name: 'file',
+      header: {
+        Authorization: store.state.user.token,
+      },
+      success: (result) =>{
+        const res =  envVersion === 'release' ? JSON.parse(CryptoJS.Des3Decrypt(result.data)) :  JSON.parse(result.data);
+        resolve(res)
+      },
+      fail: () => {
+        console.log('上传音频失败');
+        reject('上传音频失败')
+        uni.showToast({
+            title:'上传音频失败,请稍后重试!',
+            icon:'none'
+        })
+      },
+      complete: () => {
+        wx.hideLoading();
+      }
+    })
+  })
+}