/** * 频道广场 — 从后端获取分类 + 频道列表 * * 性能优化:直接使用 channel list 返回的 hasSubscribed 字段, * 无需额外请求订阅列表,减少一次 HTTP 请求 */ const app = getApp() const api = require('../../utils/api') Page({ data: { isVip: false, vipPriceText: '', categories: [], activeFilter: '', filteredDomains: [], loading: true }, onLoad() { this._loadCategories() }, onShow() { this._loadChannels() this._loadVipPrice() this._onSubChange = () => this._loadChannels() this._onVipChange = () => this._loadChannels() app.on('subscriptionChange', this._onSubChange) app.on('vipChange', this._onVipChange) }, onHide() { if (this._onSubChange) app.off('subscriptionChange', this._onSubChange) if (this._onVipChange) app.off('vipChange', this._onVipChange) }, /** * 加载分类列表 */ _loadCategories() { const self = this api.getCategoryList().then(function (res) { if (res.code === 200 && res.data) { const list = Array.isArray(res.data) ? res.data : (res.data.list || []) const categories = [{ id: '', name: '全部' }].concat(list) self.setData({ categories: categories }) } }).catch(function (err) { console.error('[Discover] 加载分类失败:', err) }) }, /** * 加载频道列表 * 直接使用后端返回的 hasSubscribed 字段,无需单独请求订阅列表 */ _loadChannels() { const self = this const gd = app.globalData const isFirstLoad = self.data.filteredDomains.length === 0 if (isFirstLoad) self.setData({ loading: true }) api.getChannelList({ categoryId: self.data.activeFilter, current: 1, pageSize: 50 }) .then(function (channelRes) { var channels = [] if (channelRes.code === 200 && channelRes.data) { channels = channelRes.data.list || channelRes.data || [] } var filtered = channels.map(function (ch) { var isFree = ch.isFree === 1 var isVipOnly = ch.isVipOnly === 1 var isSubscribed = ch.hasSubscribed === 1 // VIP 用户可播放所有频道 var canPlay = gd.isVip || isFree || isSubscribed // 最低价(分→元) var lowestPrice = null if (!isFree && !isVipOnly) { var prices = [ { label: '包月', value: ch.monthlyPrice }, { label: '包季', value: ch.quarterlyPrice }, { label: '包年', value: ch.annualPrice } ].filter(function (p) { return p.value > 0 }) if (prices.length > 0) { prices.sort(function (a, b) { return a.value - b.value }) lowestPrice = { label: prices[0].label, value: (prices[0].value / 100).toFixed(2) } } } return Object.assign({}, ch, { _isSubscribed: isSubscribed, _isFree: isFree, _isVipOnly: isVipOnly, _lowestPrice: lowestPrice, _canPlay: canPlay }) }) self.setData({ isVip: gd.isVip, filteredDomains: filtered, loading: false }) }) .catch(function (err) { console.error('[Discover] 加载频道失败:', err) self.setData({ loading: false }) }) }, _loadVipPrice() { var self = this api.getVipConfig().then(function (res) { if (res.code === 200 && res.data) { var cfg = res.data var p = cfg.discountedPrice > 0 ? cfg.discountedPrice : cfg.price self.setData({ vipPriceText: (p / 100).toFixed(2) + '元' }) } }).catch(function () { self.setData({ vipPriceText: '' }) }) }, /** * 切换分类筛选 */ onFilter(e) { this.setData({ activeFilter: e.currentTarget.dataset.cat }) this._loadChannels() }, /** * 按鈕操作 * 1. 已订阅 → 跳转频道详情 * 2. isFree → 直接跳转频道详情(收听) * 3. isVipOnly → 引导去 VIP 页 * 4. 付费订阅 → 跳转支付页 */ onAction(e) { const id = e.currentTarget.dataset.id var channel = null for (var i = 0; i < this.data.filteredDomains.length; i++) { if (this.data.filteredDomains[i].id === id) { channel = this.data.filteredDomains[i] break } } if (!channel) return // 规则1:canPlay(VIP || isFree || hasSubscribed)→ 进频道详情 if (channel._canPlay) { wx.navigateTo({ url: '/pages/channel-detail/index?id=' + id }) return } // 规则2:VIP专享 → 只能开通VIP,不可订阅 if (channel._isVipOnly) { wx.navigateTo({ url: '/pages/vip/index' }) return } // 付费频道未订阅 → 跳转订阅页 var params = 'channelId=' + id + '&channelName=' + encodeURIComponent(channel.name || '') + '&monthlyPrice=' + (channel.monthlyPrice || 0) + '&quarterlyPrice=' + (channel.quarterlyPrice || 0) + '&annualPrice=' + (channel.annualPrice || 0) wx.navigateTo({ url: '/pages/vip/index?' + params }) }, /** * 跳转频道详情 */ goDetail(e) { wx.navigateTo({ url: '/pages/channel-detail/index?id=' + e.currentTarget.dataset.id }) }, /** * 跳转VIP */ goVip() { wx.navigateTo({ url: '/pages/vip/index' }) } })