/** * 频道详情 — 从后端获取频道信息 + 节目列表 * * 性能优化: * - 使用 channel detail 返回的 hasSubscribed 字段,不再单独请求订阅列表 * - 展示 expiredAt 字段标记订阅到期时间 */ const app = getApp() const api = require('../../utils/api') const util = require('../../utils/util') Page({ data: { domain: {}, isSubscribed: false, isExpired: false, expiredAt: '', isFree: false, isVipOnly: false, isVip: false, canPlay: false, domainContents: [], isPlaying: false, loading: true }, onLoad(options) { const id = options.id this._domainId = id this._loadChannelDetail() }, onShow() { this._loadPrograms() this._onPlayerChange = () => this._updatePlayState() this._onSubChange = () => this._loadChannelDetail() this._onVipChange = () => this._loadChannelDetail() app.on('playerStateChange', this._onPlayerChange) app.on('subscriptionChange', this._onSubChange) app.on('vipChange', this._onVipChange) }, onHide() { if (this._onPlayerChange) app.off('playerStateChange', this._onPlayerChange) if (this._onSubChange) app.off('subscriptionChange', this._onSubChange) if (this._onVipChange) app.off('vipChange', this._onVipChange) }, /** * 加载频道详情 * hasSubscribed / expiredAt 都从这个接口返回 */ _loadChannelDetail() { const self = this api.getChannelDetail(this._domainId).then(function (res) { if (res.code === 200 && res.data) { const ch = res.data const isFree = ch.isFree === 1 var expiredAt = '' var isExpired = false var isSubscribed = false if (!isFree) { if (ch.expiredAt) { expiredAt = ch.expiredAt.substring(0, 10).replace(/-/g, '.') isExpired = new Date(ch.expiredAt) < new Date() } isSubscribed = ch.hasSubscribed === 1 && !isExpired } // 可播放:VIP 或免费频道或已订阅 const canPlay = app.globalData.isVip || isFree || isSubscribed self.setData({ domain: ch, isSubscribed, isExpired, expiredAt, isFree, isVipOnly: ch.isVipOnly === 1, isVip: app.globalData.isVip, canPlay }) // 详情加载后刷新节目列表(更新 _isLocked 状态) self._loadPrograms() } }).catch(function (err) { console.error('[ChannelDetail] 加载频道详情失败:', err) }) }, /** * 加载节目列表(静默刷新,不重复请求订阅状态) */ _loadPrograms() { const self = this api.getProgramList({ channelId: self._domainId, current: 1, pageSize: 50 }) .then(function (progRes) { var contents = [] if (progRes.code === 200 && progRes.data) { contents = progRes.data.list || progRes.data || [] } var gd = app.globalData var canPlay = self.data.canPlay var total = contents.length contents = contents.map(function (item, idx) { return Object.assign({}, item, { _displayIndex: String(total - idx).padStart(2, '0'), _dateDot: item.createdAt ? item.createdAt.substring(0, 10).replace(/-/g, '.') : '', durationText: item.duration > 0 ? util.formatTime(item.duration) : '', _isThisPlaying: gd.activeContent && gd.activeContent.id === item.id, _isLocked: !canPlay // 所有集全部锁定,没有试听 }) }) self.setData({ domainContents: contents, isPlaying: gd.isPlaying, loading: false }) }) .catch(function (err) { console.error('[ChannelDetail] 加载节目失败:', err) self.setData({ loading: false }) }) }, /** * 仅更新播放状态(不重新请求) */ _updatePlayState() { var gd = app.globalData var contents = this.data.domainContents.map(function (item) { return Object.assign({}, item, { _isThisPlaying: gd.activeContent && gd.activeContent.id === item.id }) }) this.setData({ domainContents: contents, isPlaying: gd.isPlaying }) }, onPlayItem(e) { const id = e.currentTarget.dataset.id const gd = app.globalData // 核心权限判断:VIP || 免费频道 || 已订阅 if (!this.data.canPlay) { // 引导到支付页 this.onSubscribe() return } var content = null for (var i = 0; i < this.data.domainContents.length; i++) { if (this.data.domainContents[i].id === id) { content = this.data.domainContents[i] break } } if (!content) return if (gd.activeContent && gd.activeContent.id === id) { app.togglePlay() } else { app.playContent(content) } }, onSubscribe() { const id = this._domainId const domain = this.data.domain // 已可播放(VIP / 免费 / 已订阅)——正常情况下不会触发此方法 if (this.data.canPlay) { wx.showToast({ title: '您已可收听该频道', icon: 'none' }) return } // VIP专享频道:不支持单独订阅,必须开通 VIP if (domain.isVipOnly === 1) { wx.navigateTo({ url: '/pages/vip/index' }) return } // 免费频道(理论上不会到这里,安全先) if (domain.isFree === 1) { wx.showToast({ title: '免费频道,直接收听!', icon: 'none' }) return } // 付费频道(未订阅 / 已过期)——跳转订阅/支付页 var params = 'channelId=' + id + '&channelName=' + encodeURIComponent(domain.name || '') + '&monthlyPrice=' + (domain.monthlyPrice || 0) + '&quarterlyPrice=' + (domain.quarterlyPrice || 0) + '&annualPrice=' + (domain.annualPrice || 0) wx.navigateTo({ url: '/pages/vip/index?' + params }) }, goFirstProgram() { // 权限保护:不可播放时引导到订阅/VIP if (!this.data.canPlay) { this.onSubscribe() return } var list = this.data.domainContents if (list && list.length > 0) { var first = list[0] if (app.globalData.activeContent && app.globalData.activeContent.id === first.id) { app.togglePlay() } else { app.playContent(first) } } else { wx.showToast({ title: '暂无节目', icon: 'none' }) } }, /** 续订:直接跳支付页,不走 canPlay 检查 */ onRenew() { const id = this._domainId const domain = this.data.domain var params = 'channelId=' + id + '&channelName=' + encodeURIComponent(domain.name || '') + '&monthlyPrice=' + (domain.monthlyPrice || 0) + '&quarterlyPrice=' + (domain.quarterlyPrice || 0) + '&annualPrice=' + (domain.annualPrice || 0) wx.navigateTo({ url: '/pages/vip/index?' + params }) }, goBack() { wx.navigateBack() }, // ===================== 分享钩子 ===================== onShareAppMessage() { const domain = this.data.domain || {} return { title: domain.name ? '听全声汇频道:' + domain.name : '全声汇 - 精选频道', path: '/pages/channel-detail/index?id=' + this._domainId, imageUrl: '' } }, onShareTimeline() { const domain = this.data.domain || {} return { title: domain.name ? '听全声汇频道:' + domain.name : '全声汇 - 精选频道', query: 'id=' + this._domainId, imageUrl: '' } } })