voiceDetail.vue 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. <template>
  2. <view class="voice-detail" v-if="isAuth">
  3. <!-- <view class="section-name">{{info.SectionName}}</view> -->
  4. <view class="title">{{info.BroadcastName}}</view>
  5. <view class="time">发布时间:{{info.PublishTime|formatTime}}</view>
  6. <view class="flex audio-box">
  7. <image
  8. :src="voiceId==curVoiceId&&!curAudioPaused?require('@/static/voice/playing.png'):require('@/static/voice/pause.png')"
  9. mode="aspectFill"
  10. @click="handlePlayAudio"
  11. />
  12. <slider
  13. activeColor="#E6B77D"
  14. :max="duration"
  15. :value="curTime"
  16. @change="handleAudioSliderChange($event)"
  17. block-size="12"
  18. class="slider"
  19. />
  20. <text class="left-time">{{curTime|formatVoiceTime}}</text>
  21. <text class="right-time">{{duration|formatVoiceTime}}</text>
  22. </view>
  23. <image class="del-btn" src="@/static/voice/del.png" mode="widthFix" @click="handleDel" v-if="info.IsAuthor"/>
  24. <image class="publish-btn" src="@/static/voice/publish.png" mode="widthFix" @click="handleSendMsg" v-if="info.CouldSendMsg"/>
  25. <!-- 图片部分 -->
  26. <view class="imgs-box">
  27. <image
  28. v-for="item in info.Imgs"
  29. :key="item"
  30. :src="item"
  31. mode="widthFix"
  32. lazy-load="false"
  33. @click="preViewImg(item)"
  34. />
  35. </view>
  36. <view v-show="false"><audioBox v-if="showAudioPop"/></view>
  37. <van-dialog id="van-dialog" />
  38. </view>
  39. <noAuth :info="noAuthData" v-else/>
  40. </template>
  41. <script>
  42. import {apiVoicePlayRecord,apiVoiceDel,apiVoiceDetail,apiVoiceSendMsg} from '@/api/voice'
  43. import {apiGetSceneToParams} from '@/api/common'
  44. import noAuth from '@/pages/voice/components/noAuth.vue'
  45. import audioBox from '@/components/audioBox/audioBox.vue'
  46. const moment=require('@/utils/moment-with-locales.min')
  47. export default {
  48. components:{
  49. noAuth,
  50. audioBox
  51. },
  52. computed:{
  53. showAudioPop(){//是否显示音频弹窗
  54. return this.$store.state.audio.show
  55. },
  56. curVoiceId(){//当前正在播放的音频id
  57. return this.$store.state.audio.voiceId
  58. },
  59. curAudioPaused(){//当前音频是否暂停状态
  60. return this.$store.state.audio.paused
  61. },
  62. curTime(){
  63. let t=0
  64. if(this.voiceId==this.$store.state.audio.voiceId){
  65. t=this.$store.state.audio.curTime
  66. }
  67. return t
  68. }
  69. },
  70. filters:{
  71. formatTime(e){
  72. return moment(e).format('YYYY-MM-DD HH:mm:ss')
  73. },
  74. formatVoiceTime(e){
  75. let m=parseInt(e/60)
  76. let s=parseInt(e%60)
  77. return `${m>9?m:'0'+m}:${s>9?s:'0'+s}`
  78. }
  79. },
  80. data() {
  81. return {
  82. voiceId:'',
  83. isAuth:true,
  84. noAuthData:null,
  85. info:{},
  86. // curTime:0,
  87. duration:0,
  88. }
  89. },
  90. onLoad(options){
  91. this.init(options)
  92. },
  93. onShareAppMessage(){
  94. const title=`${this.info.SectionName}:${this.info.BroadcastName}`
  95. return {
  96. title:title,
  97. imageUrl:this.info.ImgUrl
  98. }
  99. },
  100. methods: {
  101. async init(options){
  102. if(options.scene){
  103. const res=await apiGetSceneToParams({scene_key:options.scene})
  104. if(res.code===200){
  105. const obj=JSON.parse(res.data)
  106. this.voiceId=obj.voiceId
  107. }
  108. }else{
  109. this.voiceId=options.voiceId||0
  110. }
  111. this.getDetail()
  112. },
  113. async getDetail(){
  114. const res=await apiVoiceDetail({broadcast_id:Number(this.voiceId)})
  115. if(res.code===200){
  116. this.info=res.data
  117. uni.setNavigationBarTitle({ title: res.data.SectionName||'播报详情' })
  118. this.duration=Number(res.data.VoicePlaySeconds)||0
  119. this.isAuth=true
  120. }else if(res.code===403){
  121. this.isAuth=false
  122. this.noAuthData=res.data
  123. }
  124. },
  125. //删除
  126. handleDel(){
  127. this.$dialog.confirm({
  128. title:'',
  129. message: '确定要删除该语音播报吗?',
  130. confirmButtonText:'确定'
  131. }).then(()=>{
  132. apiVoiceDel({broadcast_id:Number(this.voiceId)}).then(res=>{
  133. if(res.code===200){
  134. uni.showToast({
  135. title:'操作成功',
  136. icon:'none'
  137. })
  138. setTimeout(() => {
  139. uni.$emit('addVoiceSuccess')
  140. uni.switchTab({
  141. url: '/pages/voice/voice'
  142. });
  143. }, 1000);
  144. }
  145. })
  146. }).catch(()=>{})
  147. },
  148. // 推送消息
  149. handleSendMsg(){
  150. this.$dialog.confirm({
  151. title:'',
  152. message: '该操作将推送模板消息和客群,确认推送吗?',
  153. confirmButtonText:'确认'
  154. }).then(()=>{
  155. apiVoiceSendMsg({broadcast_id:Number(this.voiceId)}).then(res=>{
  156. if(res.code===200){
  157. uni.showToast({
  158. title:'操作成功',
  159. icon:'none'
  160. })
  161. setTimeout(() => {
  162. uni.$emit('addVoiceSuccess')
  163. uni.switchTab({
  164. url: '/pages/voice/voice'
  165. });
  166. }, 1000);
  167. }
  168. })
  169. }).catch(()=>{})
  170. },
  171. //上报音频播放记录
  172. async handleVoicePlayRecord(){
  173. const res=await apiVoicePlayRecord({
  174. broadcast_id:Number(this.voiceId)
  175. })
  176. if(res.code===200){
  177. console.log('上报音频播放记录');
  178. }
  179. },
  180. //点击播放\暂停音频
  181. handlePlayAudio(){
  182. if(this.$store.state.audio.voiceId==this.voiceId){
  183. if(this.globalBgMusic.paused){
  184. this.globalBgMusic.play()
  185. }else{
  186. this.globalBgMusic.pause()
  187. }
  188. }else{
  189. const list=[{url:this.info.VoiceUrl,time:this.info.VoicePlaySeconds,title:this.info.BroadcastName,}]
  190. this.$store.commit('audio/addAudio',{
  191. list:list,
  192. voiceId:this.voiceId
  193. })
  194. this.handleVoicePlayRecord()
  195. }
  196. },
  197. //拖动音频播放进度条
  198. handleAudioSliderChange(e){
  199. const value=e.detail.value
  200. this.globalBgMusic.seek(value)
  201. },
  202. //预览图片
  203. preViewImg(item){
  204. wx.previewImage({
  205. current: item, // 当前显示图片的 http 链接
  206. urls: this.info.Imgs||[] // 需要预览的图片 http 链接列表
  207. })
  208. }
  209. },
  210. }
  211. </script>
  212. <style lang="scss" scoped>
  213. .voice-detail{
  214. padding: 50rpx 34rpx;
  215. .section-name{
  216. background: #FDF8F2;
  217. border-radius: 8rpx;
  218. border: 1px solid #E3B377;
  219. display: inline-block;
  220. padding: 19rpx 27rpx;
  221. margin-bottom: 40rpx;
  222. }
  223. .title{
  224. font-size: 32rpx;
  225. line-height: 38rpx;
  226. margin-bottom: 20rpx;
  227. }
  228. .time{
  229. color: #999;
  230. font-size: 28rpx;
  231. line-height: 33rpx;
  232. }
  233. .audio-box{
  234. background-color: #FDF8F2;
  235. height: 123rpx;
  236. align-items: center;
  237. margin-top: 50rpx;
  238. margin-bottom: 40rpx;
  239. padding: 0 30rpx;
  240. position: relative;
  241. .left-time{
  242. position: absolute;
  243. bottom: 20rpx;
  244. left: 100rpx;
  245. color: #999999;
  246. font-size: 20rpx;
  247. }
  248. .right-time{
  249. position: absolute;
  250. bottom: 20rpx;
  251. right: 40rpx;
  252. color: #999999;
  253. font-size: 20rpx;
  254. }
  255. image{
  256. width: 40rpx;
  257. height: 48rpx;
  258. flex-shrink: 0;
  259. margin-right: 30rpx;
  260. }
  261. .slider{
  262. flex: 1;
  263. margin: 0 10rpx;
  264. }
  265. }
  266. .del-btn{
  267. float: left;
  268. width: 36rpx;
  269. height: 36rpx;
  270. }
  271. .publish-btn{
  272. float: right;
  273. width: 36rpx;
  274. height: 36rpx;
  275. }
  276. .imgs-box{
  277. margin-top: 120rpx;
  278. image{
  279. width: 100%;
  280. margin-bottom: 40rpx;
  281. }
  282. }
  283. }
  284. </style>