/** * 全局底部悬浮播放控制条 * 监听 app 事件总线,实时同步播放状态 */ const app = getApp() Component({ data: { activeContent: null, isPlaying: false, progressPercent: 0, currentTime: 0, duration: 0, show: false, channelIcon: '📻' }, lifetimes: { attached() { // 初始化状态 this._syncState() // 监听播放状态变化 this._onPlayerChange = (state) => { this.setData({ activeContent: state.activeContent, isPlaying: state.isPlaying, show: !!state.activeContent }) this._computeIcon(state.activeContent) } app.on('playerStateChange', this._onPlayerChange) // 监听时间更新 this._onTimeUpdate = (data) => { if (this._isSeeking) return if (data.duration > 0) { this.setData({ currentTime: Math.floor(data.currentTime), duration: Math.floor(data.duration), progressPercent: Math.min((data.currentTime / data.duration) * 100, 100) }) } } app.on('timeUpdate', this._onTimeUpdate) }, detached() { app.off('playerStateChange', this._onPlayerChange) app.off('timeUpdate', this._onTimeUpdate) } }, pageLifetimes: { show() { this._syncState() } }, methods: { /** * 同步播放器状态 */ _syncState() { const gd = app.globalData this.setData({ activeContent: gd.activeContent, isPlaying: gd.isPlaying, show: !!gd.activeContent, currentTime: Math.floor(gd.currentTime || 0), duration: Math.floor(gd.duration || 0), progressPercent: gd.duration > 0 ? Math.min((gd.currentTime / gd.duration) * 100, 100) : 0 }) this._computeIcon(gd.activeContent) }, /** * 获取频道 emoji(后端直接返回 emoji 字符、存在 cover 字段中) */ _computeIcon(content) { if (!content) return const ch = content.channel || {} var icon = ch.cover || ch.icon || content.cover || '📻' this.setData({ channelIcon: icon }) }, /** * 切换播放/暂停 */ onTogglePlay() { app.togglePlay() }, /** * 跳转到播放器详情页 */ goToPlayer() { wx.navigateTo({ url: '/pages/player/index', routeType: 'none' }) }, /** * 进度条拖动中 */ onProgressChanging(e) { this._isSeeking = true this.setData({ currentTime: e.detail.value }) }, /** * 进度条拖动结束 */ onProgressChange(e) { this._isSeeking = false app.seekTo(e.detail.value) } } })