256 lines
8.5 KiB
JavaScript
256 lines
8.5 KiB
JavaScript
/**
|
|
* 频道详情 — 从后端获取频道信息 + 节目列表
|
|
*
|
|
* 性能优化:
|
|
* - 使用 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: ''
|
|
}
|
|
}
|
|
})
|