更新小程序,新增VIP会员状态管理功能,优化章节解锁逻辑,支持VIP用户访问增值内容。调整用户详情页面,增加VIP相关字段和功能,提升用户体验。更新会议记录,反映最新讨论内容。
This commit is contained in:
@@ -16,6 +16,7 @@ Page({
|
||||
// 用户状态
|
||||
isLoggedIn: false,
|
||||
hasFullBook: false,
|
||||
isVip: false,
|
||||
purchasedSections: [],
|
||||
|
||||
// 书籍数据 - 完整真实标题
|
||||
@@ -212,6 +213,7 @@ Page({
|
||||
navBarHeight: app.globalData.navBarHeight
|
||||
})
|
||||
this.updateUserStatus()
|
||||
this.loadVipStatus()
|
||||
this.loadChaptersOnce()
|
||||
},
|
||||
|
||||
@@ -258,13 +260,19 @@ Page({
|
||||
})
|
||||
}
|
||||
const ch = part.chapters.get(cid)
|
||||
const isPremium =
|
||||
r.editionPremium === true ||
|
||||
r.edition_premium === true ||
|
||||
r.edition_premium === 1 ||
|
||||
r.edition_premium === '1'
|
||||
ch.sections.push({
|
||||
id: r.id,
|
||||
mid: r.mid ?? r.MID ?? 0,
|
||||
title: r.sectionTitle || r.section_title || r.title || '',
|
||||
isFree: r.isFree === true || (r.price !== undefined && r.price === 0),
|
||||
price: r.price ?? 1,
|
||||
isNew: r.isNew === true || r.is_new === true
|
||||
isNew: r.isNew === true || r.is_new === true,
|
||||
isPremium
|
||||
})
|
||||
})
|
||||
const bookData = Array.from(partMap.values()).map(p => ({
|
||||
@@ -310,12 +318,33 @@ Page({
|
||||
}
|
||||
}
|
||||
this.updateUserStatus()
|
||||
this.loadVipStatus()
|
||||
},
|
||||
|
||||
// 拉取 VIP 状态(isVip=会员,hasFullBook=9.9 买断)
|
||||
async loadVipStatus() {
|
||||
const userId = app.globalData.userInfo?.id
|
||||
if (!userId) return
|
||||
try {
|
||||
const res = await app.request({ url: `/api/miniprogram/vip/status?userId=${userId}`, silent: true, timeout: 3000 })
|
||||
if (res?.success) {
|
||||
app.globalData.isVip = !!res.data?.isVip
|
||||
app.globalData.vipExpireDate = res.data?.expireDate || ''
|
||||
this.setData({ isVip: app.globalData.isVip })
|
||||
const userInfo = app.globalData.userInfo || {}
|
||||
userInfo.isVip = app.globalData.isVip
|
||||
userInfo.vipExpireDate = app.globalData.vipExpireDate
|
||||
wx.setStorageSync('userInfo', userInfo)
|
||||
}
|
||||
} catch (e) {
|
||||
// 静默失败不影响目录展示
|
||||
}
|
||||
},
|
||||
|
||||
// 更新用户状态
|
||||
updateUserStatus() {
|
||||
const { isLoggedIn, hasFullBook, purchasedSections } = app.globalData
|
||||
this.setData({ isLoggedIn, hasFullBook, purchasedSections })
|
||||
const { isLoggedIn, hasFullBook, purchasedSections, isVip } = app.globalData
|
||||
this.setData({ isLoggedIn, hasFullBook, purchasedSections, isVip })
|
||||
},
|
||||
|
||||
// 切换展开状态
|
||||
@@ -335,8 +364,9 @@ Page({
|
||||
},
|
||||
|
||||
// 检查是否已购买
|
||||
hasPurchased(sectionId) {
|
||||
if (this.data.hasFullBook) return true
|
||||
hasPurchased(sectionId, isPremium) {
|
||||
if (this.data.isVip) return true
|
||||
if (!isPremium && this.data.hasFullBook) return true
|
||||
return this.data.purchasedSections.includes(sectionId)
|
||||
},
|
||||
|
||||
|
||||
@@ -73,13 +73,14 @@
|
||||
<block wx:for="{{chapter.sections}}" wx:key="id" wx:for-item="section">
|
||||
<view class="section-item" bindtap="goToRead" data-id="{{section.id}}" data-mid="{{section.mid}}">
|
||||
<view class="section-left">
|
||||
<text class="section-lock {{section.isFree || hasFullBook || purchasedSections.indexOf(section.id) > -1 ? 'lock-open' : 'lock-closed'}}">{{section.isFree || hasFullBook || purchasedSections.indexOf(section.id) > -1 ? '○' : '●'}}</text>
|
||||
<text class="section-title {{section.isFree || hasFullBook || purchasedSections.indexOf(section.id) > -1 ? '' : 'text-muted'}}">{{section.id}} {{section.title}}</text>
|
||||
<text class="section-lock {{section.isFree || isVip || (!section.isPremium && hasFullBook) || purchasedSections.indexOf(section.id) > -1 ? 'lock-open' : 'lock-closed'}}">{{section.isFree || isVip || (!section.isPremium && hasFullBook) || purchasedSections.indexOf(section.id) > -1 ? '○' : '●'}}</text>
|
||||
<text class="section-title {{section.isFree || isVip || (!section.isPremium && hasFullBook) || purchasedSections.indexOf(section.id) > -1 ? '' : 'text-muted'}}">{{section.id}} {{section.title}}</text>
|
||||
<text wx:if="{{section.isNew}}" class="tag tag-new">NEW</text>
|
||||
<text wx:if="{{section.isPremium}}" class="tag tag-vip">增值</text>
|
||||
</view>
|
||||
<view class="section-right">
|
||||
<text wx:if="{{section.isFree}}" class="tag tag-free">免费</text>
|
||||
<text wx:elif="{{hasFullBook || purchasedSections.indexOf(section.id) > -1}}" class="tag tag-purchased">已购</text>
|
||||
<text wx:elif="{{isVip || (!section.isPremium && hasFullBook) || purchasedSections.indexOf(section.id) > -1}}" class="tag tag-purchased">已解锁</text>
|
||||
<text wx:else class="section-price">¥{{section.price}}</text>
|
||||
<text class="section-arrow">›</text>
|
||||
</view>
|
||||
|
||||
@@ -232,6 +232,14 @@
|
||||
margin-left: 8rpx;
|
||||
}
|
||||
|
||||
.tag-vip {
|
||||
background: rgba(255, 215, 0, 0.12);
|
||||
color: #FFD700;
|
||||
font-size: 20rpx;
|
||||
padding: 2rpx 8rpx;
|
||||
margin-left: 8rpx;
|
||||
}
|
||||
|
||||
.text-brand {
|
||||
color: #00CED1;
|
||||
}
|
||||
|
||||
@@ -148,7 +148,7 @@ Page({
|
||||
}
|
||||
const d = this._getUnlockData(member.id)
|
||||
if (d[field]) return
|
||||
const isVip = app.globalData.hasFullBook
|
||||
const isVip = app.globalData.isVip
|
||||
const usedFree = this._hasUsedFreeForMember(member.id)
|
||||
if (isVip || !usedFree) {
|
||||
this._addUnlock(member.id, field)
|
||||
|
||||
@@ -742,20 +742,25 @@ Page({
|
||||
})
|
||||
},
|
||||
|
||||
// VIP状态查询(hasFullBook 优先,兼容模拟支付等本地已置 VIP 的情况)
|
||||
// VIP状态查询(注意:hasFullBook=9.9 买断,不等同 VIP)
|
||||
async loadVipStatus() {
|
||||
if (app.globalData.hasFullBook) {
|
||||
this.setData({ isVip: true, vipExpireDate: this.data.vipExpireDate || '' })
|
||||
}
|
||||
const userId = app.globalData.userInfo?.id
|
||||
if (!userId) return
|
||||
try {
|
||||
const res = await app.request({ url: `/api/miniprogram/vip/status?userId=${userId}`, silent: true })
|
||||
if (res?.success) {
|
||||
const isVip = !!res.data?.isVip
|
||||
app.globalData.isVip = isVip
|
||||
app.globalData.vipExpireDate = res.data?.expireDate || ''
|
||||
this.setData({
|
||||
isVip: res.data?.isVip || app.globalData.hasFullBook,
|
||||
isVip,
|
||||
vipExpireDate: res.data?.expireDate || this.data.vipExpireDate || ''
|
||||
})
|
||||
// 同步到 storage,便于其他页面复用(注意:hasFullBook=买断,isVip=会员)
|
||||
const userInfo = app.globalData.userInfo || {}
|
||||
userInfo.isVip = isVip
|
||||
userInfo.vipExpireDate = res.data?.expireDate || ''
|
||||
wx.setStorageSync('userInfo', userInfo)
|
||||
}
|
||||
} catch (e) { console.log('[My] VIP查询失败', e) }
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user