实施美团式的支付流程,并增强相关功能

- 将支付流程统一至礼品支付页面,禁止从阅读页面进行支付,以优化用户体验。
- 更新了礼物支付详情页面,为发起人和朋友展示了不同的用户界面元素,包括为发起人提供的分享按钮和为朋友提供的支付按钮。
- 增强了后端逻辑,以确保在支付处理过程中正确将收益归因于发起人。
- 增加了每日章节更新,并改进了章节页面的加载状态,以提升用户交互体验。
- 更新了文档,以反映新的支付流程和相关变更。
This commit is contained in:
Alex-larget
2026-03-17 12:15:08 +08:00
parent 0d12ab1d07
commit 601044ec60
30 changed files with 822 additions and 238 deletions

View File

@@ -6,6 +6,7 @@
*/
const app = getApp()
const { trackClick } = require('../../utils/trackClick')
Page({
data: {
@@ -55,6 +56,7 @@ Page({
this.updateUserStatus()
this.loadVipStatus()
this.loadParts()
this.loadDailyChapters()
},
// 懒加载:仅拉取篇章列表 + totalSections + fixedSections
@@ -174,7 +176,34 @@ Page({
},
onPullDownRefresh() {
this.loadParts().then(() => wx.stopPullDownRefresh()).catch(() => wx.stopPullDownRefresh())
Promise.all([this.loadParts(), this.loadDailyChapters()])
.then(() => wx.stopPullDownRefresh())
.catch(() => wx.stopPullDownRefresh())
},
// 每日新增:用 latest-chapters 接口,展示最近更新章节
async loadDailyChapters() {
try {
const res = await app.request({ url: '/api/miniprogram/book/latest-chapters', silent: true })
const list = (res && res.data) ? res.data : []
const pt = (c) => (c.partTitle || c.part_title || '').toLowerCase()
const exclude = c => !pt(c).includes('序言') && !pt(c).includes('尾声') && !pt(c).includes('附录')
const daily = list
.filter(exclude)
.slice(0, 10)
.map(c => {
const d = new Date(c.updatedAt || c.updated_at || Date.now())
const title = c.section_title || c.sectionTitle || c.title || c.chapterTitle || ''
return {
id: c.id,
mid: c.mid ?? c.MID ?? 0,
title,
price: c.price ?? 1,
dateStr: `${d.getMonth() + 1}/${d.getDate()}`
}
})
this.setData({ dailyChapters: daily })
} catch (e) { console.log('[Chapters] 加载每日新增失败:', e) }
},
onShow() {
@@ -219,6 +248,7 @@ Page({
// 切换展开状态,展开时懒加载该篇章章节
async togglePart(e) {
trackClick('chapters', 'tab_click', e.currentTarget.dataset.id || '篇章')
const partId = e.currentTarget.dataset.id
const isExpanding = this.data.expandedPart !== partId
this.setData({
@@ -231,6 +261,7 @@ Page({
goToRead(e) {
const id = e.currentTarget.dataset.id
const mid = e.currentTarget.dataset.mid || app.getSectionMid(id)
trackClick('chapters', 'card_click', id || '章节')
const q = mid ? `mid=${mid}` : `id=${id}`
wx.navigateTo({ url: `/pages/read/read?${q}` })
},
@@ -249,6 +280,7 @@ Page({
// 跳转到搜索页
goToSearch() {
trackClick('chapters', 'nav_click', '搜索')
wx.navigateTo({ url: '/pages/search/search' })
},

View File

@@ -40,6 +40,31 @@
<!-- 目录内容 -->
<view class="chapters-content" wx:if="{{!partsLoading}}">
<!-- 每日新增(最近更新章节快捷入口) -->
<view class="daily-section" wx:if="{{dailyChapters.length > 0}}">
<view class="daily-header">
<text class="daily-title">每日新增</text>
<text class="daily-badge">+{{dailyChapters.length}}</text>
</view>
<view class="daily-list">
<view
class="daily-item"
wx:for="{{dailyChapters}}"
wx:key="id"
bindtap="goToRead"
data-id="{{item.id}}"
data-mid="{{item.mid}}"
>
<view class="daily-dot"></view>
<view class="daily-content">
<text class="daily-item-title">{{item.title}}</text>
<text class="daily-item-meta">{{item.dateStr}} · ¥{{item.price}}</text>
</view>
<text class="daily-arrow"></text>
</view>
</view>
</view>
<!-- 序言(优先传 mid阅读页用 by-mid 请求) -->
<view class="chapter-item" bindtap="goToRead" data-id="preface" data-mid="{{fixedSectionsMap.preface}}">
<view class="item-left">
@@ -83,6 +108,7 @@
<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>

View File

@@ -174,6 +174,89 @@
box-sizing: border-box;
}
/* ===== 每日新增 ===== */
.daily-section {
margin-bottom: 32rpx;
padding: 24rpx;
background: #1c1c1e;
border-radius: 24rpx;
border: 2rpx solid rgba(255, 255, 255, 0.05);
}
.daily-header {
display: flex;
align-items: center;
gap: 16rpx;
margin-bottom: 24rpx;
}
.daily-title {
font-size: 30rpx;
font-weight: 600;
color: #ffffff;
}
.daily-badge {
font-size: 22rpx;
padding: 4rpx 12rpx;
background: #F6AD55;
color: #ffffff;
border-radius: 20rpx;
}
.daily-list {
display: flex;
flex-direction: column;
gap: 0;
}
.daily-item {
display: flex;
align-items: center;
padding: 16rpx 0;
border-bottom: 1rpx solid rgba(255, 255, 255, 0.06);
}
.daily-item:last-child {
border-bottom: none;
}
.daily-dot {
width: 12rpx;
height: 12rpx;
border-radius: 50%;
background: rgba(0, 206, 209, 0.6);
margin-right: 20rpx;
flex-shrink: 0;
}
.daily-content {
flex: 1;
min-width: 0;
display: flex;
flex-direction: column;
gap: 4rpx;
}
.daily-item-title {
font-size: 26rpx;
color: #ffffff;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.daily-item-meta {
font-size: 22rpx;
color: rgba(255, 255, 255, 0.4);
}
.daily-arrow {
font-size: 28rpx;
color: rgba(255, 255, 255, 0.4);
margin-left: 16rpx;
}
/* ===== 章节项 ===== */
.chapter-item {
display: flex;

View File

@@ -10,7 +10,8 @@ Page({
requestSn: '',
detail: null,
loading: true,
paying: false
paying: false,
isInitiator: false // 是否发起人发起人看到「分享给好友」UI好友看到「帮他付款」
},
onLoad(options) {
@@ -32,7 +33,9 @@ Page({
try {
const res = await app.request(`/api/miniprogram/gift-pay/detail?requestSn=${encodeURIComponent(requestSn)}`)
if (res && res.success) {
this.setData({ detail: res, loading: false })
const myId = app.globalData.userInfo?.id || ''
const isInitiator = !!myId && res.initiatorUserId === myId
this.setData({ detail: res, loading: false, isInitiator })
} else {
this.setData({ loading: false })
wx.showToast({ title: res?.error || '加载失败', icon: 'none' })

View File

@@ -1,4 +1,4 @@
<!-- Soul创业派对 - 代付详情页 -->
<!-- Soul创业派对 - 代付详情页(美团式:发起人看到分享入口,好友看到帮他付款) -->
<view class="page">
<view class="nav-bar" style="padding-top: {{statusBarHeight}}px;">
<view class="nav-content">
@@ -6,7 +6,7 @@
<text class="back-arrow">←</text>
</view>
<view class="nav-info">
<text class="nav-title">帮他付款</text>
<text class="nav-title">{{isInitiator ? '找朋友代付' : '帮他付款'}}</text>
</view>
<view class="nav-right-placeholder"></view>
</view>
@@ -20,15 +20,22 @@
</view>
</block>
<block wx:elif="{{detail}}">
<!-- 营销:章节标题+内容预览,吸引代付人 -->
<view class="article-preview" wx:if="{{detail.sectionTitle || detail.contentPreview}}">
<text class="article-title">{{detail.sectionTitle || detail.description || '代付商品'}}</text>
<text class="article-content" wx:if="{{detail.contentPreview}}">{{detail.contentPreview}}</text>
</view>
<view class="card">
<view class="card-header">
<text class="card-title">代付订单</text>
<text class="initiator">{{detail.initiatorNickname || '好友'}} 请你帮忙付款</text>
<view class="card-badge">代付订单</view>
<text class="initiator" wx:if="{{!isInitiator}}">{{detail.initiatorNickname || '好友'}} 请你帮忙付款</text>
<text class="initiator" wx:else>分享给好友,好友帮你付款</text>
</view>
<view class="card-divider"></view>
<view class="card-body">
<view class="row">
<view class="row product-row" wx:if="{{!detail.contentPreview}}">
<text class="label">商品</text>
<text class="value">{{detail.description || '-'}}</text>
<text class="value product-desc">{{detail.sectionTitle || detail.description || '-'}}</text>
</view>
<view class="row amount-row">
<text class="label">金额</text>
@@ -36,12 +43,27 @@
</view>
</view>
</view>
<view class="tips">
<text>付款后,{{detail.initiatorNickname || '好友'}}将获得对应权益</text>
</view>
<button class="pay-btn" bindtap="doPay" disabled="{{paying}}">
{{paying ? '支付中...' : '帮他付款'}}
</button>
<!-- 发起人:分享给好友 -->
<block wx:if="{{isInitiator}}">
<view class="tips">
<text class="tips-icon">💡</text>
<text>分享给好友,好友打开后点击「帮他付款」即可为你代付</text>
</view>
<button class="pay-btn share-btn" open-type="share">
<image class="btn-icon-img" src="/assets/icons/share.svg" mode="aspectFit"/>
<text>分享给好友</text>
</button>
</block>
<!-- 好友:帮他付款 -->
<block wx:else>
<view class="tips">
<text class="tips-icon">✓</text>
<text>付款后,{{detail.initiatorNickname || '好友'}}将获得对应权益</text>
</view>
<button class="pay-btn" bindtap="doPay" disabled="{{paying}}">
{{paying ? '支付中...' : '帮他付款'}}
</button>
</block>
</block>
<block wx:else>
<view class="empty">

View File

@@ -1,7 +1,7 @@
/* Soul创业派对 - 代付详情页 */
.page {
min-height: 100vh;
background: #000;
background: linear-gradient(180deg, #0a0a0a 0%, #000 40%, #000 100%);
}
.nav-bar {
@@ -10,8 +10,10 @@
left: 0;
right: 0;
z-index: 100;
background: rgba(0, 0, 0, 0.9);
border-bottom: 1rpx solid rgba(255, 255, 255, 0.08);
background: rgba(0, 0, 0, 0.92);
backdrop-filter: blur(20rpx);
-webkit-backdrop-filter: blur(20rpx);
border-bottom: 1rpx solid rgba(255, 255, 255, 0.06);
}
.nav-content {
@@ -26,25 +28,31 @@
width: 72rpx;
height: 72rpx;
border-radius: 50%;
background: #1c1c1e;
background: rgba(255, 255, 255, 0.06);
display: flex;
align-items: center;
justify-content: center;
transition: opacity 0.2s;
}
.nav-back:active {
opacity: 0.7;
}
.back-arrow {
font-size: 36rpx;
color: rgba(255, 255, 255, 0.8);
color: rgba(255, 255, 255, 0.9);
}
.nav-title {
font-size: 32rpx;
font-size: 34rpx;
font-weight: 600;
color: #fff;
letter-spacing: 0.5rpx;
}
.content {
padding: 32rpx;
padding: 20rpx;
}
.loading-box {
@@ -58,7 +66,7 @@
.loading-spinner {
width: 48rpx;
height: 48rpx;
border: 4rpx solid rgba(0, 206, 209, 0.3);
border: 4rpx solid rgba(0, 206, 209, 0.2);
border-top-color: #00CED1;
border-radius: 50%;
animation: spin 0.8s linear infinite;
@@ -71,43 +79,86 @@
.loading-text {
margin-top: 24rpx;
font-size: 28rpx;
color: rgba(255, 255, 255, 0.5);
color: rgba(255, 255, 255, 0.45);
}
/* 营销:章节标题+内容预览,与订单卡片统一风格 */
.article-preview {
background: linear-gradient(145deg, #1a1a1c 0%, #141416 100%);
border-radius: 24rpx;
padding: 24rpx;
margin-bottom: 16rpx;
border: 1rpx solid rgba(0, 206, 209, 0.1);
}
.article-title {
display: block;
font-size: 30rpx;
font-weight: 600;
color: #fff;
line-height: 1.5;
margin-bottom: 12rpx;
}
.article-content {
font-size: 26rpx;
color: rgba(255, 255, 255, 0.6);
line-height: 1.65;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 4;
-webkit-box-orient: vertical;
}
/* 订单卡片:与文章预览统一圆角、边距 */
.card {
background: #1c1c1e;
background: linear-gradient(145deg, #1a1a1c 0%, #141416 100%);
border-radius: 24rpx;
overflow: hidden;
margin-bottom: 32rpx;
margin-bottom: 24rpx;
border: 1rpx solid rgba(0, 206, 209, 0.1);
}
.card-header {
padding: 32rpx;
border-bottom: 1rpx solid rgba(255, 255, 255, 0.06);
padding: 24rpx;
}
.card-title {
display: block;
font-size: 28rpx;
color: rgba(255, 255, 255, 0.5);
margin-bottom: 8rpx;
.card-badge {
display: inline-block;
font-size: 22rpx;
color: rgba(0, 206, 209, 0.9);
background: rgba(0, 206, 209, 0.08);
padding: 6rpx 14rpx;
border-radius: 8rpx;
margin-bottom: 12rpx;
letter-spacing: 0.5rpx;
}
.initiator {
font-size: 34rpx;
display: block;
font-size: 32rpx;
font-weight: 600;
color: #fff;
line-height: 1.4;
letter-spacing: 0.3rpx;
}
.card-divider {
height: 1rpx;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.08), transparent);
margin: 0 24rpx;
}
.card-body {
padding: 32rpx;
padding: 20rpx 24rpx 24rpx;
}
.row {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 24rpx;
align-items: flex-start;
margin-bottom: 16rpx;
}
.row:last-child {
@@ -115,46 +166,99 @@
}
.label {
font-size: 28rpx;
color: rgba(255, 255, 255, 0.5);
font-size: 26rpx;
color: rgba(255, 255, 255, 0.45);
flex-shrink: 0;
width: 80rpx;
}
.value {
.product-row .value {
flex: 1;
text-align: right;
font-size: 28rpx;
color: #fff;
color: rgba(255, 255, 255, 0.95);
line-height: 1.5;
word-break: break-all;
}
.product-desc {
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
.amount-row {
align-items: center;
}
.amount-row .amount {
font-size: 40rpx;
font-size: 44rpx;
font-weight: 700;
color: #00CED1;
letter-spacing: 1rpx;
text-shadow: 0 0 24rpx rgba(0, 206, 209, 0.3);
}
/* 提示文案 */
.tips {
padding: 0 8rpx 32rpx;
font-size: 24rpx;
color: rgba(255, 255, 255, 0.4);
display: flex;
align-items: flex-start;
gap: 10rpx;
padding: 0 4rpx 24rpx;
font-size: 26rpx;
color: rgba(255, 255, 255, 0.5);
line-height: 1.5;
}
.tips-icon {
flex-shrink: 0;
font-size: 28rpx;
opacity: 0.8;
}
/* 主按钮 */
.pay-btn {
width: 100%;
height: 96rpx;
line-height: 96rpx;
background: linear-gradient(90deg, #00CED1 0%, #20B2AA 100%);
background: linear-gradient(135deg, #00CED1 0%, #18a8a8 50%, #20B2AA 100%);
color: #fff;
font-size: 32rpx;
font-size: 34rpx;
font-weight: 600;
border-radius: 48rpx;
border-radius: 50rpx;
border: none;
box-shadow: 0 8rpx 24rpx rgba(0, 206, 209, 0.35);
transition: opacity 0.2s, transform 0.1s;
}
.pay-btn:active {
opacity: 0.92;
transform: scale(0.99);
}
.pay-btn[disabled] {
opacity: 0.6;
transform: none;
}
.share-btn {
display: flex;
align-items: center;
justify-content: center;
gap: 16rpx;
}
.btn-icon-img {
width: 40rpx;
height: 40rpx;
filter: brightness(0) invert(1);
}
.empty {
text-align: center;
padding: 120rpx 0;
font-size: 28rpx;
color: rgba(255, 255, 255, 0.5);
color: rgba(255, 255, 255, 0.45);
}

View File

@@ -50,7 +50,20 @@ Page({
}
},
goToDetail(e) {
const requestSn = e.currentTarget.dataset.sn
if (requestSn) {
wx.navigateTo({ url: `/pages/gift-pay/detail?requestSn=${encodeURIComponent(requestSn)}` })
}
},
shareRequest(e) {
e.stopPropagation()
wx.showToast({ title: '请点击右上角「...」分享给好友', icon: 'none', duration: 2500 })
},
async cancelRequest(e) {
e.stopPropagation()
const requestSn = e.currentTarget.dataset.sn
if (!requestSn) return
const ok = await new Promise(r => {
@@ -74,11 +87,6 @@ Page({
}
},
shareRequest(e) {
const requestSn = e.currentTarget.dataset.sn
wx.showToast({ title: '请点击右上角「...」分享给好友', icon: 'none', duration: 2500 })
},
goBack() {
app.goBackOrToHome()
},

View File

@@ -29,7 +29,7 @@
<view class="empty">暂无发起的代付</view>
</block>
<block wx:else>
<view class="card" wx:for="{{requests}}" wx:key="requestSn">
<view class="card" wx:for="{{requests}}" wx:key="requestSn" bindtap="goToDetail" data-sn="{{item.requestSn}}">
<view class="card-row">
<text class="desc">{{item.description}}</text>
<text class="amount">¥{{item.amount}}</text>
@@ -49,7 +49,7 @@
<view class="empty">暂无帮付记录</view>
</block>
<block wx:else>
<view class="card" wx:for="{{payments}}" wx:key="requestSn">
<view class="card" wx:for="{{payments}}" wx:key="requestSn" bindtap="goToDetail" data-sn="{{item.requestSn}}">
<view class="card-row">
<text class="desc">{{item.description}}</text>
<text class="amount">¥{{item.amount}}</text>

View File

@@ -17,6 +17,7 @@ import accessManager from '../../utils/chapterAccessManager'
import readingTracker from '../../utils/readingTracker'
const { parseScene } = require('../../utils/scene.js')
const contentParser = require('../../utils/contentParser.js')
const { trackClick } = require('../../utils/trackClick')
const app = getApp()
@@ -65,9 +66,6 @@ Page({
// 弹窗
showShareModal: false,
showGiftShareModal: false,
shareMode: '', // 'gift' = 代付分享onShareAppMessage 返回 gift-pay/detail
giftRequestSn: '', // 代付请求号,分享时用
showLoginModal: false,
agreeProtocol: false,
showPosterModal: false,
@@ -97,13 +95,15 @@ Page({
// 支持 scene扫码、mid、id、ref、gift代付
const sceneStr = (options && options.scene) || ''
const parsed = parseScene(sceneStr)
const mid = options.mid ? parseInt(options.mid, 10) : (parsed.mid || app.globalData.initialSectionMid || 0)
let id = options.id || parsed.id || app.globalData.initialSectionId
const ref = options.ref || parsed.ref
const isGift = options.gift === '1' || options.gift === 'true'
// 代付统一到代付页gift=1&ref=requestSn 时直接跳转,禁止在阅读页代付
if (isGift && ref) {
wx.setStorageSync('gift_for_ref', ref) // 代付模式:好友打开后,购买时传 giftFor后端待支持
wx.redirectTo({ url: `/pages/gift-pay/detail?requestSn=${encodeURIComponent(ref)}` })
return
}
const mid = options.mid ? parseInt(options.mid, 10) : (parsed.mid || app.globalData.initialSectionMid || 0)
let id = options.id || parsed.id || app.globalData.initialSectionId
if (app.globalData.initialSectionMid) delete app.globalData.initialSectionMid
if (app.globalData.initialSectionId) delete app.globalData.initialSectionId
@@ -657,7 +657,7 @@ Page({
this.setData({ showShareModal: false })
},
// 代付分享弹窗:创建代付请求后分享到代付页面
// 找好友代付:创建代付请求后跳转代付页(美团式,在代付页分享)
async showGiftShareModal() {
if (!app.globalData.userInfo?.id) {
wx.showToast({ title: '请先登录', icon: 'none' })
@@ -682,7 +682,7 @@ Page({
})
wx.hideLoading()
if (res && res.success && res.requestSn) {
this.setData({ showGiftShareModal: true, giftRequestSn: res.requestSn })
wx.navigateTo({ url: `/pages/gift-pay/detail?requestSn=${res.requestSn}` })
} else {
wx.showToast({ title: res?.error || '创建失败', icon: 'none' })
}
@@ -692,20 +692,6 @@ Page({
}
},
closeGiftShareModal() {
this.setData({ showGiftShareModal: false })
},
// 分享给好友(代付):引导用户点右上角,分享到代付详情页
shareGiftToFriend() {
this.setData({ shareMode: 'gift', showGiftShareModal: false })
wx.showToast({
title: '请点击右上角「...」→ 发送给好友',
icon: 'none',
duration: 2500
})
},
// 复制链接
copyLink() {
const userInfo = app.globalData.userInfo
@@ -741,29 +727,17 @@ Page({
})
},
// 分享到微信 - 自动带分享人IDshareMode=gift 时分享到代付详情页
// 分享到微信 - 自动带分享人ID
onShareAppMessage() {
const { section, sectionId, sectionMid, shareMode, giftRequestSn } = this.data
trackClick('read', 'btn_click', '分享_' + this.data.sectionId)
const { section, sectionId, sectionMid } = this.data
const ref = app.getMyReferralCode()
const q = sectionMid ? `mid=${sectionMid}` : `id=${sectionId}`
let path = ref ? `/pages/read/read?${q}&ref=${ref}` : `/pages/read/read?${q}`
let title = section?.title
const path = ref ? `/pages/read/read?${q}&ref=${ref}` : `/pages/read/read?${q}`
const title = section?.title
? `📚 ${section.title.length > 20 ? section.title.slice(0, 20) + '...' : section.title}`
: '📚 Soul创业派对 - 真实商业故事'
if (shareMode === 'gift' && giftRequestSn) {
path = `/pages/gift-pay/detail?requestSn=${giftRequestSn}`
title = '好友请你帮忙代付 - Soul创业派对'
this.setData({ shareMode: '', giftRequestSn: '' })
} else {
title = section?.title
? `📚 ${section.title.length > 20 ? section.title.slice(0, 20) + '...' : section.title}`
: '📚 Soul创业派对 - 真实商业故事'
}
return {
title,
path
// 不设置 imageUrl使用当前阅读页截图作为分享卡片中间图片
}
return { title, path }
},
// 底部「分享到朋友圈」按钮点击:微信不支持 button open-type=shareTimeline只能通过右上角菜单分享点击时引导用户
@@ -775,16 +749,12 @@ Page({
})
},
// 分享到朋友圈:带文章标题,过长时截断shareMode=gift 时 query 带 gift=1
// 分享到朋友圈:带文章标题,过长时截断
onShareTimeline() {
const { section, sectionId, sectionMid, chapterTitle, shareMode } = this.data
const { section, sectionId, sectionMid, chapterTitle } = this.data
const ref = app.getMyReferralCode()
const q = sectionMid ? `mid=${sectionMid}` : `id=${sectionId}`
let query = ref ? `${q}&ref=${ref}` : q
if (shareMode === 'gift' && ref) {
query = `${q}&ref=${ref}&gift=1`
this.setData({ shareMode: '' })
}
const query = ref ? `${q}&ref=${ref}` : q
const articleTitle = (section?.title || chapterTitle || '').trim()
const title = articleTitle
? (articleTitle.length > 28 ? articleTitle.slice(0, 28) + '...' : articleTitle)
@@ -918,6 +888,7 @@ Page({
// 购买章节 - 直接调起支付
async handlePurchaseSection() {
trackClick('read', 'btn_click', '购买章节_' + this.data.sectionId)
console.log('[Pay] 点击购买章节按钮')
wx.showLoading({ title: '处理中...', mask: true })

View File

@@ -298,23 +298,6 @@
</view>
</view>
<!-- 代付分享弹窗:分享到代付页面,好友打开后帮他付款 -->
<view class="modal-overlay" wx:if="{{showGiftShareModal}}" bindtap="closeGiftShareModal">
<view class="modal-content share-modal" catchtap="stopPropagation">
<view class="modal-header">
<text class="modal-title">找好友代付</text>
<view class="modal-close" bindtap="closeGiftShareModal">✕</view>
</view>
<text class="share-modal-desc">分享给好友,好友打开后点击「帮他付款」即可为你代付本章</text>
<view class="share-modal-actions">
<view class="share-modal-btn" bindtap="shareGiftToFriend">
<text class="btn-icon">👤</text>
<text>分享给好友</text>
</view>
</view>
</view>
</view>
<!-- 支付中提示 -->
<view class="modal-overlay" wx:if="{{isPaying}}" catchtap="">
<view class="loading-box">