/** * 全局底部悬浮播放控制条 * 监听 app 事件总线,实时同步播放状态 */ const app = getApp() Component({ data: { activeContent: null, isPlaying: false, progressPercent: 0, show: false, channelIcon: '📻' // 直接存储 emoji 字符(来自频道 cover 字段) }, 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 (data.duration > 0) { this.setData({ 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, 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' }) } } })