voiceDetail.vue 9.7 KB

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