feat: 优化UI
This commit is contained in:
@@ -13,10 +13,12 @@ Page({
|
||||
data: {
|
||||
domain: {},
|
||||
isSubscribed: false,
|
||||
isExpired: false, // 订阅是否已过期
|
||||
expiredAt: '', // 到期时间(格式化)
|
||||
isFree: false, // 快捷字段,避免模板 domain.isFree
|
||||
isExpired: false,
|
||||
expiredAt: '',
|
||||
isFree: false,
|
||||
isVipOnly: false,
|
||||
isVip: false,
|
||||
canPlay: false,
|
||||
domainContents: [],
|
||||
isPlaying: false,
|
||||
loading: true
|
||||
@@ -52,7 +54,6 @@ Page({
|
||||
const ch = res.data
|
||||
const isFree = ch.isFree === 1
|
||||
|
||||
// 免费频道:不关心订阅状态和到期时间
|
||||
var expiredAt = ''
|
||||
var isExpired = false
|
||||
var isSubscribed = false
|
||||
@@ -64,13 +65,18 @@ Page({
|
||||
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
|
||||
isVipOnly: ch.isVipOnly === 1,
|
||||
isVip: app.globalData.isVip,
|
||||
canPlay
|
||||
})
|
||||
}
|
||||
}).catch(function (err) {
|
||||
@@ -92,8 +98,7 @@ Page({
|
||||
}
|
||||
|
||||
var gd = app.globalData
|
||||
var isSubscribed = self.data.isSubscribed
|
||||
var isFree = self.data.domain.isFree === 1
|
||||
var canPlay = self.data.canPlay
|
||||
var total = contents.length
|
||||
|
||||
contents = contents.map(function (item, idx) {
|
||||
@@ -102,7 +107,7 @@ Page({
|
||||
_dateDot: item.createdAt ? item.createdAt.substring(0, 10).replace(/-/g, '.') : '',
|
||||
durationText: util.formatTime(item.duration || 0),
|
||||
_isThisPlaying: gd.activeContent && gd.activeContent.id === item.id,
|
||||
_isLocked: !isSubscribed && !isFree && idx > 0
|
||||
_isLocked: !canPlay // 所有集全部锁定,没有试听
|
||||
})
|
||||
})
|
||||
|
||||
@@ -133,11 +138,12 @@ Page({
|
||||
|
||||
onPlayItem(e) {
|
||||
const id = e.currentTarget.dataset.id
|
||||
const idx = parseInt(e.currentTarget.dataset.idx)
|
||||
const gd = app.globalData
|
||||
|
||||
if (!this.data.isSubscribed && !(this.data.domain.isFree === 1) && idx > 0) {
|
||||
wx.showToast({ title: '请先订阅该频道以解锁往期内容', icon: 'none' })
|
||||
// 核心权限判断:VIP || 免费频道 || 已订阅
|
||||
if (!this.data.canPlay) {
|
||||
// 引导到支付页
|
||||
this.onSubscribe()
|
||||
return
|
||||
}
|
||||
|
||||
@@ -161,25 +167,51 @@ Page({
|
||||
const id = this._domainId
|
||||
const domain = this.data.domain
|
||||
|
||||
// 已订阅 → 已在订阅中,无需操作
|
||||
if (this.data.isSubscribed) {
|
||||
wx.showToast({ title: '您已订阅该频道', icon: 'none' })
|
||||
// 已可播放(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
|
||||
}
|
||||
|
||||
// VIP专享且未开通 → VIP页
|
||||
if (domain.isVipOnly === 1 && !app.globalData.isVip) {
|
||||
wx.navigateTo({ url: '/pages/vip/index' })
|
||||
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() {
|
||||
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)
|
||||
|
||||
@@ -9,10 +9,27 @@
|
||||
<text class="hero-name">{{domain.name}}</text>
|
||||
<text class="hero-tag">{{domain.tag || domain.description || ''}}</text>
|
||||
|
||||
<!-- ═══ 按钮区:根据频道类型和订阅状态分情况 ═══ -->
|
||||
<!-- ═══ 按钮区 ═══ -->
|
||||
|
||||
<!-- 1. 免费频道 -->
|
||||
<block wx:if="{{isFree}}">
|
||||
<!-- 0. 可播放(VIP / 免费 / 已订阅)→ 直接收听 -->
|
||||
<block wx:if="{{canPlay}}">
|
||||
<button class="hero-sub-btn free-btn" bindtap="goFirstProgram">
|
||||
<text>▶ 开始收听</text>
|
||||
</button>
|
||||
<!-- 副标签 -->
|
||||
<text wx:if="{{isVip}}" class="hero-expired">👑 VIP 会员畅享</text>
|
||||
<text wx:elif="{{isFree}}" class="hero-expired">🎁 永久免费频道</text>
|
||||
<view wx:elif="{{isSubscribed}}" class="hero-sub-row">
|
||||
<text class="hero-expired">有效至 {{expiredAt || '长期有效'}}</text>
|
||||
<!-- 续订按钮:付费已订阅频道才显示 -->
|
||||
<view wx:if="{{!isVipOnly}}" class="renew-inline-btn tap-active" bindtap="onRenew">
|
||||
<text class="renew-inline-text">续订</text>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
|
||||
<!-- 1. 免费频道(但不可播放,理论上不会到这里) -->
|
||||
<block wx:elif="{{isFree}}">
|
||||
<view class="hero-badge free-badge">🎁 永久免费</view>
|
||||
<button class="hero-sub-btn free-btn" bindtap="onSubscribe">
|
||||
<text>▶ 开始收听</text>
|
||||
@@ -27,24 +44,16 @@
|
||||
</button>
|
||||
</block>
|
||||
|
||||
<!-- 3. 已订阅且有效 -->
|
||||
<block wx:elif="{{isSubscribed}}">
|
||||
<button class="hero-sub-btn subscribed" bindtap="onSubscribe">
|
||||
<text>✓ 已订阅</text>
|
||||
</button>
|
||||
<text wx:if="{{expiredAt}}" class="hero-expired">有效至 {{expiredAt}}</text>
|
||||
</block>
|
||||
|
||||
<!-- 4. 订阅已过期(重新订阅) -->
|
||||
<!-- 3. 订阅已过期 -->
|
||||
<block wx:elif="{{isExpired}}">
|
||||
<view class="hero-badge expired-badge">⏰ 订阅已到期</view>
|
||||
<button class="hero-sub-btn renew-btn" bindtap="onSubscribe">
|
||||
<text>续费订阅</text>
|
||||
</button>
|
||||
<text wx:if="{{expiredAt}}" class="hero-expired">已于 {{expiredAt}} 到期</text>
|
||||
<text class="hero-expired">已于 {{expiredAt}} 到期</text>
|
||||
</block>
|
||||
|
||||
<!-- 5. 未订阅付费频道 -->
|
||||
<!-- 4. 未订阅付费频道 -->
|
||||
<block wx:else>
|
||||
<button class="hero-sub-btn" bindtap="onSubscribe">
|
||||
<text>订阅频道</text>
|
||||
@@ -61,7 +70,7 @@
|
||||
|
||||
<!-- 提示条:根据状态动态切换 -->
|
||||
<!-- VIP专享未开通 -->
|
||||
<view wx:if="{{isVipOnly && !isSubscribed}}" class="trial-notice vip-notice" bindtap="onSubscribe">
|
||||
<view wx:if="{{isVipOnly && !canPlay}}" class="trial-notice vip-notice" bindtap="onSubscribe">
|
||||
<text class="notice-icon">👑</text>
|
||||
<view class="notice-info">
|
||||
<text class="notice-title">VIP专属频道</text>
|
||||
@@ -80,14 +89,14 @@
|
||||
<text class="notice-action">续费 ›</text>
|
||||
</view>
|
||||
|
||||
<!-- 付费频道未订阅(试听) -->
|
||||
<view wx:elif="{{!isSubscribed && !isFree}}" class="trial-notice" bindtap="onSubscribe">
|
||||
<text class="notice-icon">🔒</text>
|
||||
<!-- 付费频道未订阅(全锁,无试听) -->
|
||||
<view wx:elif="{{!canPlay && !isFree}}" class="trial-notice locked-notice" bindtap="onSubscribe">
|
||||
<text class="notice-icon">🔐</text>
|
||||
<view class="notice-info">
|
||||
<text class="notice-title">试听模式</text>
|
||||
<text class="notice-desc">可试听最新一期,订阅后解锁全部历史内容</text>
|
||||
<text class="notice-title">频道未解锁</text>
|
||||
<text class="notice-desc">订阅频道或开通全频道会员,即可畅听全部内容</text>
|
||||
</view>
|
||||
<text class="notice-action">订阅 ›</text>
|
||||
<text class="notice-action">立即解锁 ›</text>
|
||||
</view>
|
||||
|
||||
<!-- 内容列表标题 -->
|
||||
@@ -119,18 +128,14 @@
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 播放按钮 -->
|
||||
<view wx:if="{{!item._isLocked}}" class="item-play-btn {{item._isThisPlaying ? 'active' : ''}}">
|
||||
<image
|
||||
wx:if="{{item._isThisPlaying && isPlaying}}"
|
||||
src="/assets/icons/pause.svg"
|
||||
class="item-play-icon"
|
||||
/>
|
||||
<image
|
||||
wx:else
|
||||
src="/assets/icons/play.svg"
|
||||
class="item-play-icon"
|
||||
/>
|
||||
<!-- 播放 / 锁定按钮 -->
|
||||
<view class="item-play-btn {{item._isThisPlaying ? 'active' : ''}} {{item._isLocked ? 'locked-btn' : ''}}">
|
||||
<text wx:if="{{item._isLocked}}" class="lock-icon">🔒</text>
|
||||
<view wx:elif="{{item._isThisPlaying && isPlaying}}" class="mini-pause">
|
||||
<view class="mp-bar"></view>
|
||||
<view class="mp-bar"></view>
|
||||
</view>
|
||||
<text wx:else class="play-tri">▶</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@@ -86,6 +86,24 @@
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
letter-spacing: 0.5rpx;
|
||||
}
|
||||
/* 到期日 + 续订按钮 同一行 */
|
||||
.hero-sub-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16rpx;
|
||||
margin-top: 12rpx;
|
||||
}
|
||||
.renew-inline-btn {
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
border: 1rpx solid rgba(255, 255, 255, 0.5);
|
||||
border-radius: 32rpx;
|
||||
padding: 6rpx 20rpx;
|
||||
}
|
||||
.renew-inline-text {
|
||||
font-size: 20rpx;
|
||||
color: #FFF;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* 徽标(免费 / VIP / 到期)*/
|
||||
.hero-badge {
|
||||
@@ -286,10 +304,39 @@
|
||||
border-color: transparent;
|
||||
box-shadow: 0 4rpx 16rpx rgba(255, 157, 66, 0.3);
|
||||
}
|
||||
.item-play-icon {
|
||||
width: 28rpx;
|
||||
height: 28rpx;
|
||||
/* 锁定状态的圆圈 */
|
||||
.item-play-btn.locked-btn {
|
||||
background: #F0F0F0;
|
||||
border-color: #E0E0E0;
|
||||
opacity: 0.6;
|
||||
}
|
||||
.item-play-btn.active .item-play-icon {
|
||||
filter: brightness(0) invert(1);
|
||||
.lock-icon {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
/* 纯文字播放三角 */
|
||||
.play-tri {
|
||||
font-size: 22rpx;
|
||||
color: #888;
|
||||
padding-left: 4rpx;
|
||||
}
|
||||
.item-play-btn.active .play-tri {
|
||||
color: #FFF;
|
||||
}
|
||||
/* 迷你暂停两条竖线 */
|
||||
.mini-pause {
|
||||
display: flex;
|
||||
gap: 6rpx;
|
||||
align-items: center;
|
||||
}
|
||||
.mp-bar {
|
||||
width: 5rpx;
|
||||
height: 26rpx;
|
||||
background: #FFF;
|
||||
border-radius: 3rpx;
|
||||
}
|
||||
|
||||
/* 全锁定提示条(橙色调) */
|
||||
.locked-notice {
|
||||
background: rgba(255, 157, 66, 0.06);
|
||||
border-color: rgba(255, 157, 66, 0.25);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user