jwyu 2 年之前
父節點
當前提交
d727c29095
共有 8 個文件被更改,包括 463 次插入154 次删除
  1. 50 1
      api/voice.js
  2. 138 77
      pages-voice/addVoice.vue
  3. 204 74
      pages-voice/myVoice.vue
  4. 二進制
      pages-voice/static/clock-icon.png
  5. 28 0
      pages-voice/voiceDetail.vue
  6. 2 1
      pages.json
  7. 1 1
      pages/report/report.vue
  8. 40 0
      utils/upload.js

+ 50 - 1
api/voice.js

@@ -8,6 +8,8 @@ import { httpGet, httpPost } from "@/utils/request.js";
  * @param page_size
  * @param page_size
  * @param broadcast_id 语音id
  * @param broadcast_id 语音id
  * @param section_id 板块id
  * @param section_id 板块id
+ * @param author_id 作者ID(我的语音播报列表)
+ * @param mine_status 语音播报状态:0-未发布 1-已发布 2-全部(我的语音播报列表)
  */
  */
 export const apiVoiceList=params=>{
 export const apiVoiceList=params=>{
     return httpPost('/voice/broadcast/list',params)
     return httpPost('/voice/broadcast/list',params)
@@ -51,4 +53,51 @@ export const apiVoiceDetail=params=>{
  */
  */
 export const apiVoiceSendMsg=params=>{
 export const apiVoiceSendMsg=params=>{
     return httpPost('/voice/broadcast/msg_send',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)
+}

+ 138 - 77
pages-voice/addVoice.vue

@@ -30,7 +30,11 @@
         />
         />
 
 
         <!-- 上传图片部分 -->
         <!-- 上传图片部分 -->
-        <view class="flex upload-img-box">
+        <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)">
             <view class="item" v-for="(item,index) in imgList" :key="item" @click="handlePreViewImg(item)">
                 <image :src="item" mode="aspectFill"/>
                 <image :src="item" mode="aspectFill"/>
                 <view class="del-btn" @click.stop="handleDelImg(index)">
                 <view class="del-btn" @click.stop="handleDelImg(index)">
@@ -63,14 +67,14 @@
                 <image src="./static/del.png" mode="aspectFill" />
                 <image src="./static/del.png" mode="aspectFill" />
                 <text>删除</text>
                 <text>删除</text>
             </view>
             </view>
-              
+            <view class="pre_publish_time" v-if="voiceId!=0">定时发布时间:{{pre_publish_time}}</view>
         </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" />
             <image src="./static/record.png" mode="aspectFill" />
             <view>无录音(录音时长超过十分钟自动结束)</view>
             <view>无录音(录音时长超过十分钟自动结束)</view>
-        </view>
+        </view> -->
 
 
         <view class="animat-box" v-if="recorderStatus==='doing'||recorderStatus==='pause'">
         <view class="animat-box" v-if="recorderStatus==='doing'||recorderStatus==='pause'">
             <view class="con-box">
             <view class="con-box">
@@ -82,7 +86,7 @@
         </view> 
         </view> 
 
 
         <view class="sound-record-wrap" v-if="recorderStatus!=='stop'">
         <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" />
             <image class="btn" :src="btnImg" mode="aspectFill" @click="handleClickBtn" />
             <view 
             <view 
                 class="del-btn" 
                 class="del-btn" 
@@ -95,10 +99,11 @@
                 v-if="recorderStatus!=='start'"
                 v-if="recorderStatus!=='start'"
                 @click="handleEndRecorder"
                 @click="handleEndRecorder"
             >完成</view>
             >完成</view>
+            <view style="text-align:center;color:#999;margin-top:44rpx" v-if="recorderStatus==='start'">无录音(录音时长超过十分钟自动结束)</view>
         </view>
         </view>
 
 
         <view class="publish-btn" v-if="recorderStatus==='stop'">
         <view class="publish-btn" v-if="recorderStatus==='stop'">
-            <text @click="showTimeAttention=true">定时发布</text>
+            <text @click="handlePublish('time')">定时发布</text>
             <text @click="handlePublish">立即发布</text>
             <text @click="handlePublish">立即发布</text>
         </view>
         </view>
         
         
@@ -145,7 +150,7 @@
             />
             />
         </van-popup>
         </van-popup>
 
 
-        <van-dialog id="van-dialog" />
+        <!-- <van-dialog id="van-dialog" /> -->
         <!-- 发布弹窗 -->
         <!-- 发布弹窗 -->
         <van-dialog
         <van-dialog
             use-slot
             use-slot
@@ -153,8 +158,9 @@
             confirm-button-text="发布且推送"
             confirm-button-text="发布且推送"
             cancel-button-text="仅发布"
             cancel-button-text="仅发布"
             show-cancel-button
             show-cancel-button
-            @confirm="handleConfirmPublish(false)"
-            @cancel="handleConfirmPublish(true)"
+            @confirm="handleConfirmPublish(1)"
+            @cancel="handleConfirmPublish(0)"
+            @close="showPublish=false"
         >
         >
             <view style="padding:40px 20px 20px;text-align:center;position: relative;">
             <view style="padding:40px 20px 20px;text-align:center;position: relative;">
                 发布后将推送模板消息和客群,确认发布吗?
                 发布后将推送模板消息和客群,确认发布吗?
@@ -168,22 +174,24 @@
             :show="showTimeAttention"
             :show="showTimeAttention"
             confirm-button-text="知道了"
             confirm-button-text="知道了"
             confirm-button-color="#E3B377"
             confirm-button-color="#E3B377"
-            @confirm="showTimeAttention=true"
+            @confirm="showTime=true"
+            @close="showTimeAttention=false"
         >
         >
             <view style="padding:40px 20px 20px;text-align:center;position: relative;">
             <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"/>
+                <van-icon name="cross" size="20" style="position: absolute;right:10px;top:10px" color="#666" @click="showTime=true"/>
             </view>
             </view>
         </van-dialog>
         </van-dialog>
     </view>
     </view>
 </template>
 </template>
 
 
 <script>
 <script>
-import {apiVoiceSectionList,apiVoiceSendMsg} from '@/api/voice'
+import {apiVoiceSectionList,apiVoiceSendMsg,apiVoiceAdd,apiVoiceEdit,apiVoicePublish,apiVoiceDetail} from '@/api/voice'
 import {baseApiUrl} from '@/utils/config.js'
 import {baseApiUrl} from '@/utils/config.js'
 import CryptoJS from '@/utils/crypto.js'
 import CryptoJS from '@/utils/crypto.js'
 import uniAsync from "@/utils/uni-async.js"; // uni api async 化
 import uniAsync from "@/utils/uni-async.js"; // uni api async 化
-import {uploadImg} from '@/utils/upload'
+import {uploadImg,commonUploadAudio} from '@/utils/upload'
+const moment=require('@/utils/moment-with-locales.min')
 const recorderManager = wx.getRecorderManager();//录音实例
 const recorderManager = wx.getRecorderManager();//录音实例
 let innerAudioContext = uni.createInnerAudioContext();//播放音频实例
 let innerAudioContext = uni.createInnerAudioContext();//播放音频实例
 let TIMER=null//计时器
 let TIMER=null//计时器
@@ -216,15 +224,18 @@ export default {
                 variety_id:'',
                 variety_id:'',
                 section_id:'',
                 section_id:'',
                 section_name:'',
                 section_name:'',
-                img_url:''
+                img_url:'',//分享时的底图
             },
             },
+            voiceId:0,
+            voiceUrl:'',//编辑音频地址
+            pre_publish_time:'',
 
 
             recorderStatus:'start',//当前录音状态 start开始 doing正在录音 stop停止录音 pause录音暂停
             recorderStatus:'start',//当前录音状态 start开始 doing正在录音 stop停止录音 pause录音暂停
             time:0,
             time:0,
             isReset:false,//是否点击了重置
             isReset:false,//是否点击了重置
 
 
             temAudio:{
             temAudio:{
-                url:'',//临时音频地址
+                url:'',//音频地址
                 duration:'',//时长
                 duration:'',//时长
                 size:'',//大小
                 size:'',//大小
                 curTime:0,//播放时当前播放的时间
                 curTime:0,//播放时当前播放的时间
@@ -242,18 +253,22 @@ export default {
             showTime:false,
             showTime:false,
             showTimeAttention:false,
             showTimeAttention:false,
             selectTime:new Date().getTime(),
             selectTime:new Date().getTime(),
-            minDate:new Date().getTime()+60000,
+            minDate:new Date().getTime()+600000,
         }
         }
     },
     },
-    onLoad(){
+    onLoad(options){
         // 调取用户授权使用麦克风
         // 调取用户授权使用麦克风
         uni.authorize({
         uni.authorize({
             scope: 'scope.record',
             scope: 'scope.record',
             success() {}
             success() {}
         })
         })
         this.listenVoice()
         this.listenVoice()
-        
         this.getOptionsList()
         this.getOptionsList()
+
+        if(options.voiceId){
+            this.voiceId=Number(options.voiceId)
+            this.getVoiceDetail()
+        }
     },
     },
     onShow(){
     onShow(){
         innerAudioContext = uni.createInnerAudioContext()
         innerAudioContext = uni.createInnerAudioContext()
@@ -265,8 +280,31 @@ export default {
     },
     },
     onUnload(){
     onUnload(){
         innerAudioContext.destroy()
         innerAudioContext.destroy()
+        clearInterval(TIMER)
 	},
 	},
     methods: {
     methods: {
+        //语音详情
+        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(){
         listenVoice(){
             recorderManager.onStart(()=>{
             recorderManager.onStart(()=>{
@@ -465,7 +503,7 @@ export default {
         },
         },
 
 
         // 发布
         // 发布
-        handlePublish(){
+        async handlePublish(type){
             if(!this.form.title||!this.form.variety_id){
             if(!this.form.title||!this.form.variety_id){
                 uni.showToast({
                 uni.showToast({
 					title:'请将内容填写完整',
 					title:'请将内容填写完整',
@@ -474,32 +512,37 @@ export default {
                 return
                 return
             }
             }
 
 
-            this.showPublish=true
-
-            // 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,
                 broadcast_name:this.form.title,
                 section_id:Number(this.form.section_id),
                 section_id:Number(this.form.section_id),
                 section_name:this.form.section_name,
                 section_name:this.form.section_name,
                 variety_id:Number(this.form.variety_id),
                 variety_id:Number(this.form.variety_id),
                 variety_name:this.form.variety_name,
                 variety_name:this.form.variety_name,
-                img_url:this.form.img_url,
                 author_id:Number(this.$store.state.user.userInfo.user_id),
                 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({
             wx.showLoading({
                 title: '发布中...',
                 title: '发布中...',
@@ -508,51 +551,60 @@ export default {
                 fail: () => {},
                 fail: () => {},
                 complete: () => {}
                 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:'发布成功',
+                            icon:'success'
+                        })
+                        setTimeout(() => {
+                            uni.$emit('addVoiceSuccess')
+                            uni.navigateBack()
+                        }, 1000);
+                    }else if(publishType==1){//发布并推送
+                        this.handleSendMsg(addRes.data.BroadcastId)
+                    }else{////定时发布
                         uni.showToast({
                         uni.showToast({
-                            title:res.msg,
-                            icon:'none'
+                            title:'定时发布成功',
+                            icon:'success'
                         })
                         })
+                        setTimeout(() => {
+                            uni.navigateBack()
+                        }, 1000);
                     }
                     }
-                },
-                fail: () => {
-                    console.log('发布失败');
+                }else{
                     uni.showToast({
                     uni.showToast({
-                        title:'发布失败,请稍后重试!',
+                        title:publishRes.msg,
                         icon:'none'
                         icon:'none'
                     })
                     })
-                },
-                complete: () => {
-                    wx.hideLoading();
                 }
                 }
-            });
+            }else{
+                wx.hideLoading();
+                uni.showToast({
+                    title:addRes.msg,
+                    icon:'none'
+                })
+            }
         },
         },
 
 
         //推送消息
         //推送消息
@@ -600,7 +652,8 @@ export default {
         handleConfirmTime(e){
         handleConfirmTime(e){
             this.selectTime=e.detail
             this.selectTime=e.detail
             this.showTime=false
             this.showTime=false
-        }
+            this.handleConfirmPublish(2)
+        },
 
 
     },
     },
 }
 }
@@ -754,6 +807,12 @@ page{
                 margin-right: 10rpx;
                 margin-right: 10rpx;
             }
             }
         }
         }
+        .pre_publish_time{
+            position: absolute;
+            bottom: -50rpx;
+            left: 0;
+            color: #999999;
+        }
     }
     }
 
 
     .publish-btn{
     .publish-btn{
@@ -791,6 +850,8 @@ page{
     .upload-img-box{
     .upload-img-box{
         padding: 34rpx 4rpx 34rpx 34rpx;
         padding: 34rpx 4rpx 34rpx 34rpx;
         flex-wrap: wrap;
         flex-wrap: wrap;
+        height: 50vh;
+        align-content: flex-start;
         .item{
         .item{
             width: 200rpx;
             width: 200rpx;
             height: 200rpx;
             height: 200rpx;

+ 204 - 74
pages-voice/myVoice.vue

@@ -1,9 +1,12 @@
 <template>
 <template>
     <view class="my-voice-page">
     <view class="my-voice-page">
         <view class="top-tab-warp">
         <view class="top-tab-warp">
-           <text class="item">未发布(10)</text>
-           <text class="item">已发布(10)</text>
-           <text class="item">全部(20)</text>
+           <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>
 
 
         <view class="empty-box" v-if="finished&&list.length==0">
         <view class="empty-box" v-if="finished&&list.length==0">
@@ -13,7 +16,8 @@
         <view class="list-wrap" v-else>
         <view class="list-wrap" v-else>
             <view class="item" v-for="item in list" :key="item.BroadcastId" @click="handleGoDetail(item)">
             <view class="item" v-for="item in list" :key="item.BroadcastId" @click="handleGoDetail(item)">
                 <view class="title">{{item.BroadcastName}}</view>
                 <view class="title">{{item.BroadcastName}}</view>
-                <view class="time">发布时间:{{item.CreateTime|formatTime}}</view>
+                <view class="time" v-if="item.PublishState==0">保存时间:{{item.ModifyTime|formatTime}}</view>
+                <view class="time" v-else>发布时间:{{item.CreateTime|formatTime}}</view>
                 <view class="flex audio-box" @click.stop="handlePlay(item)">
                 <view class="flex audio-box" @click.stop="handlePlay(item)">
                     <image 
                     <image 
                         :src="item.BroadcastId==curVoiceId&&!curAudioPaused?require('@/static/voice/playing.png'):require('@/static/voice/pause.png')" 
                         :src="item.BroadcastId==curVoiceId&&!curAudioPaused?require('@/static/voice/playing.png'):require('@/static/voice/pause.png')" 
@@ -21,35 +25,43 @@
                     />
                     />
                     <text>{{item.VoicePlaySeconds|formatVoiceTime}}</text>
                     <text>{{item.VoicePlaySeconds|formatVoiceTime}}</text>
                 </view>
                 </view>
-                <button class="publish-btn" @click.stop="handleSendMsgItem(item)" v-if="item.CouldSendMsg">
-                    <image class="publish-img" src="@/static/voice/publish.png" mode="widthFix" />
-                </button>
-                <button class="del-btn" @click.stop="handleDelItem(item)">
-                    <image class="del-img" src="@/static/voice/del.png" mode="widthFix" v-if="item.IsAuthor" />
-                </button>
-                <button 
-                    class="share-btn" 
-                    open-type="share" 
-                    :data-item="item"
-                    @click.stop=""
-                >
-                    <image class="share-img" src="@/static/share-icon.png" mode="aspectFill"/>
-                </button>
+                <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>
         </view>
 
 
 
 
         <!-- 音频悬浮 -->
         <!-- 音频悬浮 -->
-        <!-- <view v-if="showPage"> -->
+        <view v-if="showPage">
         <audioBox v-if="showAudioPop"/>
         <audioBox v-if="showAudioPop"/>
-        <!-- </view> -->
-          
+        </view>
+        
+        <van-dialog id="van-dialog" />
     </view>
     </view>
 </template>
 </template>
 
 
 <script>
 <script>
-import {apiVoiceList,apiVoicePlayRecord,apiVoiceDel,apiVoiceSendMsg} from '@/api/voice'
+import {apiVoiceList,apiVoicePlayRecord,apiVoiceDel,apiVoiceSendMsg,apiVoicePublish} from '@/api/voice'
 import audioBox from '@/components/audioBox/audioBox.vue'
 import audioBox from '@/components/audioBox/audioBox.vue'
+const moment=require('@/utils/moment-with-locales.min')
 export default {
 export default {
     components:{
     components:{
         audioBox
         audioBox
@@ -83,15 +95,107 @@ export default {
             page:1,
             page:1,
             pageSize:20,
             pageSize:20,
             list:[],
             list:[],
-            finished:true
+            finished:false,
+            status:0,//0-未发布 1-已发布 2-全部(我的语音播报列表)
+            statusOpt:[
+                {
+                    lable:'未发布',
+                    count:0,
+                    value:0
+                },
+                {
+                    lable:'已发布',
+                    count:0,
+                    value:1
+                },
+                {
+                    lable:'全部',
+                    count:0,
+                    value:2
+                }
+            ],
+
+            showPage:false,
+        }
+    },
+    onLoad(){
+        this.getList()
+    },
+    onShow(){
+        this.showPage=true
+    },
+    onHide(){
+        this.showPage=false
+    },
+    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: {  
     methods: {  
+        //获取列表数据
+        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
+                }
+            }
+        },
+
+        //状态改变
+        handleOptChange(item){
+            this.status=item.value
+            this.page=1
+            this.list=[]
+            this.finished=false
+            this.getList()
+        },
+
         //跳转详情
         //跳转详情
         handleGoDetail(item){
         handleGoDetail(item){
-            uni.navigateTo({
-                url: '/pages-voice/voiceDetail?voiceId='+item.BroadcastId,
-            });
+            if(item.PublishState==0){//未发布跳转编辑
+                uni.navigateTo({
+                    url: '/pages-voice/addVoice?voiceId='+item.BroadcastId,
+                });
+            }else{
+                uni.navigateTo({
+                    url: '/pages-voice/voiceDetail?voiceId='+item.BroadcastId,
+                });
+            }
+            
         },
         },
         
         
         //推送消息
         //推送消息
@@ -140,6 +244,43 @@ export default {
             }).catch(()=>{})
             }).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'
+                        })
+                        this.page=1
+                        this.list=[]
+                        this.finished=false
+                        this.getList()
+                    }else{
+                        uni.showToast({
+                            title:sendRes.msg,
+                            icon:'none'
+                        })
+                    }
+                }else{
+                    uni.showToast({
+                        title:pubRes.msg,
+                        icon:'none'
+                    })
+                }
+            }).catch(()=>{})
+        },
+
         //点击音频 播放或者暂停
         //点击音频 播放或者暂停
         handlePlay(item){
         handlePlay(item){
             if(this.$store.state.audio.voiceId==item.BroadcastId){
             if(this.$store.state.audio.voiceId==item.BroadcastId){
@@ -187,6 +328,8 @@ export default {
     position: sticky;
     position: sticky;
     top: 0;
     top: 0;
     left: 0;
     left: 0;
+    background: #ffffff;
+    z-index: 99;
     .item{
     .item{
         box-sizing: border-box;
         box-sizing: border-box;
         width: 200rpx;
         width: 200rpx;
@@ -200,6 +343,10 @@ export default {
             margin-right: 0;
             margin-right: 0;
         }
         }
     }
     }
+    .item-active{
+        background: #FDF8F2;
+        color: #E3B377;
+    }
 }
 }
 .list-wrap{
 .list-wrap{
     padding: 0 34rpx 34rpx 34rpx;
     padding: 0 34rpx 34rpx 34rpx;
@@ -207,58 +354,41 @@ export default {
         border-bottom: 1px solid #CDCDCD;
         border-bottom: 1px solid #CDCDCD;
         padding: 30rpx 0;
         padding: 30rpx 0;
         position: relative;
         position: relative;
-        .publish-btn{
-            position: absolute;
-            right: 192rpx;
-            bottom: 30rpx;
-            width: 36rpx;
-            height: 36rpx;
-            background-color: transparent;
-            line-height: 1;
-            padding: 0;
-            &::after{
-                border: none;
-            }
-        }
-        .publish-img{
-            width: 34rpx;
-            height: 34rpx;
-        }
-        .del-btn{
-            position: absolute;
-            right: 96rpx;
-            bottom: 30rpx;
-            width: 36rpx;
-            height: 36rpx;
-            background-color: transparent;
-            line-height: 1;
-            padding: 0;
-            &::after{
-                border: none;
-            }
-        }
-        .del-img{
-            width: 34rpx;
-            height: 34rpx;
-        }
 
 
-        .share-btn{
+        .btns-box{
             position: absolute;
             position: absolute;
-            bottom: 30rpx;
-            right: 0rpx;
-            background-color: transparent;
-            width: 36rpx;
-            height: 36rpx;
-            line-height: 1;
-            padding: 0;
-            &::after{
-                border: none;
+            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;
+                }
             }
             }
         }
         }
-        .share-img{
-            width: 32.5rpx;
-            height: 32rpx;
-        }
+
+
         .title{
         .title{
             font-size: 32rpx;
             font-size: 32rpx;
         }
         }

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


+ 28 - 0
pages-voice/voiceDetail.vue

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

+ 2 - 1
pages.json

@@ -298,7 +298,8 @@
 				{
 				{
 					"path": "myVoice",
 					"path": "myVoice",
 					"style":{
 					"style":{
-						"navigationBarTitleText": "我的语音"
+						"navigationBarTitleText": "我的语音",
+						"enablePullDownRefresh": true
 					}
 					}
 				}
 				}
 			]
 			]

+ 1 - 1
pages/report/report.vue

@@ -20,7 +20,7 @@
 			:key="index" 
 			:key="index" 
 			@click="linkPage(tab)"
 			@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 class="title">{{tab.tab}}</view>
 		</view>
 		</view>
 	</view>
 	</view>

+ 40 - 0
utils/upload.js

@@ -73,3 +73,43 @@ export const uploadImg = async ({count = 1}) => {
       });
       });
   });
   });
 };
 };
+
+
+/**
+ * 公共上传音频方法
+ */
+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();
+      }
+    })
+  })
+}