372 lines
16 KiB
Plaintext
372 lines
16 KiB
Plaintext
<!--pages/read/read.wxml-->
|
||
<!--Soul创业派对 - 阅读页-->
|
||
<view class="page">
|
||
<!-- 阅读进度条 -->
|
||
<view class="progress-bar-fixed" style="top: {{statusBarHeight}}px;">
|
||
<view class="progress-fill" style="width: {{readingProgress}}%;"></view>
|
||
</view>
|
||
|
||
<!-- 顶部导航栏 -->
|
||
<view class="nav-bar" style="padding-top: {{statusBarHeight}}px;">
|
||
<view class="nav-content">
|
||
<view class="nav-back" bindtap="goBack">
|
||
<icon name="chevron-left" size="44" color="#ffffff" customClass="back-arrow"></icon>
|
||
</view>
|
||
<view class="nav-info">
|
||
<text class="nav-chapter" wx:if="{{section.title || chapterTitle}}">{{section.title || chapterTitle}}</text>
|
||
</view>
|
||
<view class="nav-right-placeholder"></view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 导航栏占位 -->
|
||
<view class="nav-placeholder" style="height: {{statusBarHeight + 44}}px;"></view>
|
||
|
||
<!-- 阅读内容 -->
|
||
<view class="read-content">
|
||
<!-- 骨架屏:加载中时展示,模拟章节标题+正文布局 -->
|
||
<view class="skeleton-wrap" wx:if="{{accessState === 'unknown' && loading}}">
|
||
<view class="skeleton-header">
|
||
<view class="skeleton-meta"></view>
|
||
<view class="skeleton-title"></view>
|
||
</view>
|
||
<view class="skeleton-lines">
|
||
<view class="skeleton skeleton-1"></view>
|
||
<view class="skeleton skeleton-2"></view>
|
||
<view class="skeleton skeleton-3"></view>
|
||
<view class="skeleton skeleton-4"></view>
|
||
<view class="skeleton skeleton-5"></view>
|
||
<view class="skeleton skeleton-6"></view>
|
||
<view class="skeleton skeleton-7"></view>
|
||
<view class="skeleton skeleton-8"></view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 章节标题(加载完成后) -->
|
||
<view class="chapter-header" wx:elif="{{!loading}}">
|
||
<view class="chapter-meta">
|
||
<text class="chapter-id">{{section.id}}</text>
|
||
<text class="tag tag-free" wx:if="{{section.isFree}}">免费</text>
|
||
</view>
|
||
<text class="chapter-title" user-select>{{section.title}}</text>
|
||
</view>
|
||
|
||
<!-- 完整内容 - 免费或已购买(支持 @ mention / #linkTag / 图片) -->
|
||
<view class="article" wx:if="{{accessState === 'free' || accessState === 'unlocked_purchased'}}">
|
||
<view class="paragraph" wx:for="{{contentSegments}}" wx:key="index">
|
||
<block wx:for="{{item}}" wx:key="index" wx:for-item="seg">
|
||
<text wx:if="{{seg.type === 'text'}}" user-select>{{seg.text}}</text>
|
||
<text wx:elif="{{seg.type === 'mention'}}" class="mention" user-select bindtap="onMentionTap" data-user-id="{{seg.userId}}" data-nickname="{{seg.nickname}}">@{{seg.nickname}}</text>
|
||
<text wx:elif="{{seg.type === 'linkTag'}}" class="link-tag" user-select bindtap="onLinkTagTap" data-url="{{seg.url}}" data-label="{{seg.label}}" data-tag-type="{{seg.tagType}}" data-page-path="{{seg.pagePath}}" data-tag-id="{{seg.tagId}}" data-app-id="{{seg.appId}}" data-mp-key="{{seg.mpKey}}">#{{seg.label}}</text>
|
||
<image wx:elif="{{seg.type === 'image'}}" class="content-image" src="{{seg.src}}" mode="widthFix" show-menu-by-longpress bindtap="onImageTap" data-src="{{seg.src}}"></image>
|
||
</block>
|
||
</view>
|
||
|
||
<!-- 章节导航 -->
|
||
<view class="chapter-nav">
|
||
<view class="nav-buttons">
|
||
<view
|
||
class="nav-btn nav-prev {{!prevSection ? 'nav-disabled' : ''}}"
|
||
bindtap="goToPrev"
|
||
wx:if="{{prevSection}}"
|
||
>
|
||
<text class="btn-label">上一篇</text>
|
||
<text class="btn-title">{{prevSection.title}}</text>
|
||
</view>
|
||
<view class="nav-btn-placeholder" wx:else></view>
|
||
|
||
<view
|
||
class="nav-btn nav-next"
|
||
bindtap="goToNext"
|
||
wx:if="{{nextSection}}"
|
||
>
|
||
<text class="btn-label">下一篇</text>
|
||
<view class="btn-row">
|
||
<text class="btn-title">{{nextSection.title}}</text>
|
||
<icon name="chevron-right" size="28" color="#00CED1" customClass="btn-arrow"></icon>
|
||
</view>
|
||
</view>
|
||
<view class="nav-btn nav-end" wx:else>
|
||
<text class="btn-end-text">已是最后一篇</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 分享操作区 -->
|
||
<view class="action-section">
|
||
<view class="action-row-inline">
|
||
<view class="action-btn-inline btn-share-inline" bindtap="onShareTimelineTap">
|
||
<icon name="megaphone" size="32" color="#00CED1" customClass="action-icon-small"></icon>
|
||
<text class="action-text-small">分享到朋友圈</text>
|
||
</view>
|
||
<view class="action-btn-inline btn-poster-inline" bindtap="generatePoster">
|
||
<icon name="image" size="32" color="#00CED1" customClass="action-icon-small"></icon>
|
||
<text class="action-text-small">生成海报</text>
|
||
</view>
|
||
<view class="action-btn-inline btn-gift-inline" bindtap="showGiftShareModal" wx:if="{{isLoggedIn && !auditMode}}">
|
||
<icon name="gift" size="32" color="#00CED1" customClass="action-icon-small"></icon>
|
||
<text class="action-text-small">代付分享</text>
|
||
</view>
|
||
</view>
|
||
<view class="share-tip-inline" wx:if="{{!auditMode}}">
|
||
<text class="share-tip-text">分享后好友购买,你可获得 90% 收益</text>
|
||
</view>
|
||
</view>
|
||
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 预览内容 + 付费墙 - 未登录 -->
|
||
<view class="article preview" wx:if="{{accessState === 'locked_not_login'}}">
|
||
<view class="paragraph" wx:for="{{previewParagraphs}}" wx:key="index" wx:if="{{item}}">
|
||
<text user-select>{{item}}</text>
|
||
</view>
|
||
|
||
<!-- 渐变遮罩 -->
|
||
<view class="fade-mask"></view>
|
||
|
||
<!-- 付费墙 - 未登录 -->
|
||
<view class="paywall">
|
||
<view class="paywall-icon"><icon name="lock" size="80" color="#00CED1"></icon></view>
|
||
<text class="paywall-title">登录后继续阅读</text>
|
||
<text class="paywall-desc">已阅读50%,登录后查看完整内容</text>
|
||
|
||
<view class="login-btn" bindtap="showLoginModal">
|
||
<text class="login-btn-text">立即登录</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 章节导航 -->
|
||
<view class="chapter-nav chapter-nav-locked">
|
||
<view class="nav-buttons">
|
||
<view
|
||
class="nav-btn nav-prev {{!prevSection ? 'nav-disabled' : ''}}"
|
||
bindtap="goToPrev"
|
||
wx:if="{{prevSection}}"
|
||
>
|
||
<text class="btn-label">上一篇</text>
|
||
<text class="btn-title">章节 {{prevSection.id}}</text>
|
||
</view>
|
||
<view class="nav-btn-placeholder" wx:else></view>
|
||
|
||
<view
|
||
class="nav-btn nav-next"
|
||
bindtap="goToNext"
|
||
wx:if="{{nextSection}}"
|
||
>
|
||
<text class="btn-label">下一篇</text>
|
||
<view class="btn-row">
|
||
<text class="btn-title">{{nextSection.title}}</text>
|
||
<icon name="chevron-right" size="28" color="#00CED1" customClass="btn-arrow"></icon>
|
||
</view>
|
||
</view>
|
||
<view class="nav-btn nav-end" wx:else>
|
||
<text class="btn-end-text">已是最后一篇</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 预览内容 + 付费墙 - 已登录未购买 -->
|
||
<view class="article preview" wx:if="{{accessState === 'locked_not_purchased'}}">
|
||
<view class="paragraph" wx:for="{{previewParagraphs}}" wx:key="index" wx:if="{{item}}">
|
||
<text user-select>{{item}}</text>
|
||
</view>
|
||
|
||
<!-- 渐变遮罩 -->
|
||
<view class="fade-mask"></view>
|
||
|
||
<!-- 付费墙 - 已登录未购买 -->
|
||
<view class="paywall">
|
||
<view class="paywall-icon"><icon name="lock" size="80" color="#00CED1"></icon></view>
|
||
<text class="paywall-title">解锁完整内容</text>
|
||
<text class="paywall-desc">已阅读50%,购买后继续阅读</text>
|
||
|
||
<!-- 购买选项(审核模式隐藏) -->
|
||
<view class="purchase-options" wx:if="{{!auditMode}}">
|
||
<!-- 购买本章 - 直接调起支付 -->
|
||
<view class="purchase-btn purchase-section" bindtap="handlePurchaseSection">
|
||
<text class="btn-label">购买本章</text>
|
||
<text class="btn-price brand-color">¥{{section && section.price != null ? section.price : sectionPrice}}</text>
|
||
</view>
|
||
|
||
<!-- 解锁全书 - 只有购买超过3章才显示 -->
|
||
<view class="purchase-btn purchase-fullbook" bindtap="handlePurchaseFullBook" wx:if="{{purchasedCount >= 3}}">
|
||
<view class="btn-left">
|
||
<icon name="sparkles" size="32" color="#FFD700" customClass="btn-sparkle"></icon>
|
||
<text class="btn-label">解锁全部 {{totalSections}} 章</text>
|
||
</view>
|
||
<view class="btn-right">
|
||
<text class="btn-price">¥{{fullBookPrice || 9.9}}</text>
|
||
<text class="btn-discount">省82%</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="paywall-audit-tip" wx:if="{{auditMode}}">审核中,暂不支持购买</view>
|
||
|
||
<text class="paywall-tip" wx:if="{{!auditMode}}">分享给好友一起学习,还能赚取佣金</text>
|
||
<!-- 代付分享:帮好友购买(审核模式隐藏) -->
|
||
<view class="gift-share-row" bindtap="showGiftShareModal" wx:if="{{isLoggedIn && !auditMode}}">
|
||
<icon name="gift" size="40" color="#00CED1" customClass="gift-share-icon"></icon>
|
||
<text class="gift-share-text">代付分享</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 章节导航 -->
|
||
<view class="chapter-nav chapter-nav-locked">
|
||
<view class="nav-buttons">
|
||
<view
|
||
class="nav-btn nav-prev {{!prevSection ? 'nav-disabled' : ''}}"
|
||
bindtap="goToPrev"
|
||
wx:if="{{prevSection}}"
|
||
>
|
||
<text class="btn-label">上一篇</text>
|
||
<text class="btn-title">章节 {{prevSection.id}}</text>
|
||
</view>
|
||
<view class="nav-btn-placeholder" wx:else></view>
|
||
|
||
<view
|
||
class="nav-btn nav-next"
|
||
bindtap="goToNext"
|
||
wx:if="{{nextSection}}"
|
||
>
|
||
<text class="btn-label">下一篇</text>
|
||
<view class="btn-row">
|
||
<text class="btn-title">{{nextSection.title}}</text>
|
||
<icon name="chevron-right" size="28" color="#00CED1" customClass="btn-arrow"></icon>
|
||
</view>
|
||
</view>
|
||
<view class="nav-btn nav-end" wx:else>
|
||
<text class="btn-end-text">已是最后一篇</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 错误状态 - 网络异常 -->
|
||
<view class="article preview" wx:if="{{accessState === 'error'}}">
|
||
<view class="paragraph" wx:for="{{previewParagraphs}}" wx:key="index" wx:if="{{item}}">
|
||
<text user-select>{{item}}</text>
|
||
</view>
|
||
|
||
<!-- 渐变遮罩 -->
|
||
<view class="fade-mask"></view>
|
||
|
||
<!-- 错误提示 -->
|
||
<view class="paywall">
|
||
<view class="paywall-icon"><icon name="warning" size="80" color="#ff9500"></icon></view>
|
||
<text class="paywall-title">网络异常</text>
|
||
<text class="paywall-desc">无法确认权限,请检查网络后重试</text>
|
||
|
||
<view class="login-btn" bindtap="handleRetry">
|
||
<text class="login-btn-text">重新加载</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 海报生成弹窗 -->
|
||
<view class="modal-overlay" wx:if="{{showPosterModal}}" bindtap="closePosterModal">
|
||
<view class="modal-content poster-modal" catchtap="stopPropagation">
|
||
<view class="modal-header">
|
||
<text class="modal-title">生成海报</text>
|
||
<view class="modal-close" bindtap="closePosterModal"><icon name="x" size="36" color="#8e8e93"></icon></view>
|
||
</view>
|
||
|
||
<!-- 海报预览 -->
|
||
<view class="poster-preview">
|
||
<canvas canvas-id="posterCanvas" class="poster-canvas" style="width: 300px; height: 450px;"></canvas>
|
||
</view>
|
||
|
||
<view class="poster-actions">
|
||
<view class="poster-btn btn-save" bindtap="savePoster">
|
||
<icon name="save" size="36" color="#8e8e93" customClass="btn-icon"></icon>
|
||
<text>保存到相册</text>
|
||
</view>
|
||
</view>
|
||
|
||
<text class="poster-tip">长按海报可直接分享到微信</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 代付分享弹窗:阅读页内发起代付并支付 -->
|
||
<view class="modal-overlay modal-overlay-center" wx:if="{{showGiftModal}}" bindtap="closeGiftModal">
|
||
<view class="modal-content modal-content-center gift-modal-v2" catchtap="stopPropagation">
|
||
<view class="modal-header">
|
||
<text class="modal-title">{{giftPaid ? '代付已完成' : '生成代付链接'}}</text>
|
||
<view class="modal-close" bindtap="closeGiftModal"><icon name="x" size="36" color="#8e8e93"></icon></view>
|
||
</view>
|
||
|
||
<view class="gift-article-card">
|
||
<text class="gift-article-title">{{section.title || '代付商品'}}</text>
|
||
<text class="gift-article-desc" wx:if="{{section.desc}}">{{section.desc}}</text>
|
||
</view>
|
||
|
||
<view wx:if="{{!giftPaid}}">
|
||
<text class="gift-label">选择代付名额数</text>
|
||
<view class="gift-spots-grid">
|
||
<view class="gift-spot-btn {{giftQuantity===6?'gift-spot-active':''}}" bindtap="selectGiftQuantity" data-q="6">6</view>
|
||
<view class="gift-spot-btn {{giftQuantity===30?'gift-spot-active':''}}" bindtap="selectGiftQuantity" data-q="30">30</view>
|
||
<view class="gift-spot-btn {{giftQuantity===100?'gift-spot-active':''}}" bindtap="selectGiftQuantity" data-q="100">100</view>
|
||
<view class="gift-spot-btn {{giftQuantity===1000?'gift-spot-active':''}}" bindtap="selectGiftQuantity" data-q="1000">1000</view>
|
||
</view>
|
||
|
||
<view class="gift-price-box">
|
||
<text class="gift-price-label">待支付总价格</text>
|
||
<view class="gift-price-row">
|
||
<text class="gift-price-formula">¥{{giftUnitPrice}} × {{giftQuantity}} =</text>
|
||
<text class="gift-price-total">¥{{giftTotalPrice}}</text>
|
||
</view>
|
||
</view>
|
||
|
||
<button class="gift-pay-btn" bindtap="confirmGiftPay" disabled="{{giftPaying}}">
|
||
{{giftPaying ? '支付中...' : '确认并支付'}}
|
||
</button>
|
||
<view class="gift-cancel-text" bindtap="closeGiftModal">取消</view>
|
||
</view>
|
||
|
||
<view wx:else class="gift-paid-wrap">
|
||
<text class="gift-paid-tip">支付成功,点击下方按钮直接分享给好友。好友打开阅读页将自动领取并解锁。</text>
|
||
<button class="gift-share-btn" open-type="share" data-gift="1" data-request-sn="{{giftRequestSn}}">
|
||
发送给好友
|
||
</button>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 登录弹窗 - 须勾选同意协议,《用户协议》《隐私政策》可点击查看 -->
|
||
<view class="modal-overlay" wx:if="{{showLoginModal}}" bindtap="closeLoginModal">
|
||
<view class="modal-content login-modal" catchtap="stopPropagation">
|
||
<view class="modal-close" bindtap="closeLoginModal"><icon name="x" size="36" color="#8e8e93"></icon></view>
|
||
<view class="login-icon"><icon name="lock" size="80" color="#00CED1"></icon></view>
|
||
<text class="login-title">登录 Soul创业派对</text>
|
||
<text class="login-desc">登录后可购买章节、解锁更多内容</text>
|
||
|
||
<button class="btn-wechat {{agreeProtocol ? '' : 'btn-wechat-disabled'}}" bindtap="handleWechatLogin" disabled="{{!agreeProtocol}}">
|
||
<text class="btn-wechat-icon">微</text>
|
||
<text>微信快捷登录</text>
|
||
</button>
|
||
|
||
<view class="login-agree-row" catchtap="toggleAgree">
|
||
<view class="agree-checkbox {{agreeProtocol ? 'agree-checked' : ''}}"><icon wx:if="{{agreeProtocol}}" name="check" size="24" color="#34C759"></icon></view>
|
||
<text class="agree-text">我已阅读并同意</text>
|
||
<text class="agree-link" catchtap="openUserProtocol">《用户协议》</text>
|
||
<text class="agree-text">和</text>
|
||
<text class="agree-link" catchtap="openPrivacy">《隐私政策》</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 支付中提示 -->
|
||
<view class="modal-overlay" wx:if="{{isPaying}}" catchtap="">
|
||
<view class="loading-box">
|
||
<view class="loading-spinner"></view>
|
||
<text class="loading-text">支付处理中...</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 右下角悬浮按钮 - 分享到朋友圈 -->
|
||
<view class="fab-share" bindtap="shareToMoments">
|
||
<icon name="globe" size="40" color="#ffffff" customClass="fab-moments-icon"></icon>
|
||
</view>
|
||
</view>
|