Files
Mycontent/miniprogram/pages/read/read.wxml
卡若 83375cc388 fix: 审核模式增强+登录弹窗脱敏+MBTI头像404修复
1. 登录弹窗:去掉「微」图标、改品牌色、文案改「手机号快捷登录」(审核驳回项)
2. 全站审核模式增强:设置页/匹配页/推广页/资料编辑/名片等页面
   - 审核模式下隐藏提现、联系方式绑定、收益卡片、购买弹窗
   - 所有用户可见的「微信号」→「联系方式」
3. MBTI头像404:/static/路径不再走OSS,由Gin本地静态服务

Made-with: Cursor
2026-04-08 18:08:57 +08:00

490 lines
28 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!--pages/read/read.wxml-->
<!--卡若创业派对 - 阅读页-->
<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>
<!-- 完整内容 - 免费或已购买 -->
<view class="article" wx:if="{{accessState === 'free' || accessState === 'unlocked_purchased'}}">
<block wx:for="{{contentSegments}}" wx:key="index">
<view wx:if="{{item.length === 1 && item[0].type === 'heading'}}" class="seg-heading seg-h{{item[0].level}}">
<text user-select>{{item[0].text}}</text>
</view>
<view wx:elif="{{item.length === 1 && item[0].type === 'quote'}}" class="seg-quote">
<text user-select>{{item[0].text}}</text>
</view>
<scroll-view wx:elif="{{item.length === 1 && item[0].type === 'table'}}" scroll-x class="table-scroll">
<view class="content-table">
<view class="table-row table-header-row" wx:if="{{item[0].headers.length}}">
<text class="table-cell table-header-cell" wx:for="{{item[0].headers}}" wx:key="index" wx:for-item="hdr">{{hdr}}</text>
</view>
<view class="table-row" wx:for="{{item[0].rows}}" wx:key="index" wx:for-item="row">
<text class="table-cell" wx:for="{{row}}" wx:key="index" wx:for-item="cell">{{cell}}</text>
</view>
</view>
</scroll-view>
<view wx:elif="{{item.length === 1 && item[0].type === 'listItem'}}" class="seg-list-item">
<text class="seg-list-marker" wx:if="{{item[0].ordered}}">{{item[0].number}}.</text>
<text class="seg-list-marker" wx:else>•</text>
<text class="seg-list-text" user-select>{{item[0].text}}</text>
</view>
<view wx:elif="{{item.length === 1 && item[0].type === 'image'}}" class="paragraph">
<image class="content-image" src="{{item[0].src}}" mode="widthFix" show-menu-by-longpress bindtap="onImageTap" data-src="{{item[0].src}}"></image>
</view>
<view wx:else class="paragraph">
<text user-select><block wx:for="{{item}}" wx:key="index" wx:for-item="seg"><text wx:if="{{seg.type === 'text'}}">{{seg.text}}</text><text wx:elif="{{seg.type === 'mention'}}" class="mention" bindtap="onMentionTap" data-user-id="{{seg.userId}}" data-nickname="{{seg.nickname}}">{{seg.mentionDisplay}}</text><text wx:elif="{{seg.type === 'linkTag'}}" class="link-tag" 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></block></text>
<block wx:for="{{item}}" wx:key="index" wx:for-item="seg">
<image wx:if="{{seg.type === 'image'}}" class="content-image" src="{{seg.src}}" mode="widthFix" show-menu-by-longpress bindtap="onImageTap" data-src="{{seg.src}}"></image>
</block>
</view>
</block>
<!-- 章节导航 -->
<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">
<button plain class="action-share-native action-tile-unified" open-type="share" hover-class="action-share-native-hover" hover-stop-propagation>
<icon name="share" size="32" color="#00CED1" customClass="action-icon-small"></icon>
<text class="action-text-small">分享给好友</text>
</button>
<button plain class="action-share-native action-tile-unified" bindtap="generatePoster" hover-class="action-share-native-hover" hover-stop-propagation>
<icon name="image" size="32" color="#00CED1" customClass="action-icon-small"></icon>
<text class="action-text-small">生成海报</text>
</button>
<button plain class="action-share-native action-tile-unified" bindtap="showGiftShareModal" wx:if="{{isLoggedIn && !auditMode}}" hover-class="action-share-native-hover" hover-stop-propagation>
<icon name="gift" size="32" color="#00CED1" customClass="action-icon-small"></icon>
<text class="action-text-small">代付分享</text>
</button>
</view>
<view class="share-tip-inline" wx:if="{{!auditMode}}">
<text class="share-tip-text">{{readUi.shareTipLine || ('好友经你分享购买,你可获得约 ' + (shareRate || 90) + '% 收益')}}</text>
</view>
</view>
</view>
</view>
<!-- 预览内容 + 付费墙 - 未登录(规则更新:前端按百分比裁切显示,后端不截断正文) -->
<view class="article preview" wx:if="{{accessState === 'locked_not_login'}}">
<view class="preview-wrap">
<view
id="previewContentMeasure"
class="preview-body"
style="{{previewMaxHeightPx > 0 ? ('max-height:' + previewMaxHeightPx + 'px; overflow:hidden;') : ''}}"
>
<block wx:for="{{contentSegments}}" wx:key="index">
<view wx:if="{{item.length === 1 && item[0].type === 'heading'}}" class="seg-heading seg-h{{item[0].level}}"><text user-select>{{item[0].text}}</text></view>
<view wx:elif="{{item.length === 1 && item[0].type === 'quote'}}" class="seg-quote"><text user-select>{{item[0].text}}</text></view>
<scroll-view wx:elif="{{item.length === 1 && item[0].type === 'table'}}" scroll-x class="table-scroll"><view class="content-table"><view class="table-row table-header-row" wx:if="{{item[0].headers.length}}"><text class="table-cell table-header-cell" wx:for="{{item[0].headers}}" wx:key="index" wx:for-item="hdr">{{hdr}}</text></view><view class="table-row" wx:for="{{item[0].rows}}" wx:key="index" wx:for-item="row"><text class="table-cell" wx:for="{{row}}" wx:key="index" wx:for-item="cell">{{cell}}</text></view></view></scroll-view>
<view wx:elif="{{item.length === 1 && item[0].type === 'listItem'}}" class="seg-list-item"><text class="seg-list-marker" wx:if="{{item[0].ordered}}">{{item[0].number}}.</text><text class="seg-list-marker" wx:else>•</text><text class="seg-list-text" user-select>{{item[0].text}}</text></view>
<view wx:elif="{{item.length === 1 && item[0].type === 'image'}}" class="paragraph"><image class="content-image" src="{{item[0].src}}" mode="widthFix" show-menu-by-longpress bindtap="onImageTap" data-src="{{item[0].src}}"></image></view>
<view wx:else class="paragraph"><text user-select><block wx:for="{{item}}" wx:key="index" wx:for-item="seg"><text wx:if="{{seg.type === 'text'}}">{{seg.text}}</text><text wx:elif="{{seg.type === 'mention'}}" class="mention" bindtap="onMentionTap" data-user-id="{{seg.userId}}" data-nickname="{{seg.nickname}}">{{seg.mentionDisplay}}</text><text wx:elif="{{seg.type === 'linkTag'}}" class="link-tag" 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></block></text><block wx:for="{{item}}" wx:key="index" wx:for-item="seg"><image wx:if="{{seg.type === 'image'}}" class="content-image" src="{{seg.src}}" mode="widthFix" show-menu-by-longpress bindtap="onImageTap" data-src="{{seg.src}}"></image></block></view>
</block>
</view>
<view class="fade-mask"></view>
</view>
<!-- 付费墙 - 未登录 -->
<view class="paywall {{readSinglePageMode ? 'paywall--single-preview' : ''}}">
<view class="paywall-icon"><icon name="lock" size="80" color="#00CED1"></icon></view>
<block wx:if="{{readSinglePageMode}}">
<view class="paywall-title-row">
<text class="paywall-title paywall-title--inline">解锁完整内容,分享得到</text>
<text class="paywall-highlight-pct">{{shareRate || 90}}%</text>
<text class="paywall-title paywall-title--inline">收益</text>
</view>
<view class="purchase-options" wx:if="{{!auditMode}}">
<view class="purchase-btn purchase-section purchase-btn--fulltext" bindtap="onUnlockTapInSinglePage">
<text class="btn-label btn-label--block">支付 ¥{{section && section.price != null ? section.price : sectionPrice}} 解锁全文</text>
</view>
</view>
<view class="paywall-audit-tip" wx:if="{{auditMode}}">审核中,暂不支持购买</view>
</block>
<block wx:else>
<text class="paywall-title">{{readUi.fullUnlockTitle || '加入365读书会'}}</text>
<text class="paywall-desc paywall-desc--pre" wx:if="{{readBeforeLoginHint}}">{{readBeforeLoginHint}}</text>
<text class="paywall-desc">{{readUi.notLoginUnlockDesc || '已预览部分内容,登录并支付后阅读全文'}}</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>
</view>
<view class="login-btn" bindtap="showLoginModal" style="margin-top:12px">
<text class="login-btn-text">手机号登录后购买</text>
</view>
<text class="paywall-tip" wx:if="{{!auditMode}}">{{readUi.notLoginPaywallTip || ('分享给好友,好友购买你可获得约 ' + (shareRate || 90) + '% 收益')}}</text>
</block>
</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="preview-wrap">
<view
id="previewContentMeasure"
class="preview-body"
style="{{previewMaxHeightPx > 0 ? ('max-height:' + previewMaxHeightPx + 'px; overflow:hidden;') : ''}}"
>
<block wx:for="{{contentSegments}}" wx:key="index">
<view wx:if="{{item.length === 1 && item[0].type === 'heading'}}" class="seg-heading seg-h{{item[0].level}}"><text user-select>{{item[0].text}}</text></view>
<view wx:elif="{{item.length === 1 && item[0].type === 'quote'}}" class="seg-quote"><text user-select>{{item[0].text}}</text></view>
<scroll-view wx:elif="{{item.length === 1 && item[0].type === 'table'}}" scroll-x class="table-scroll"><view class="content-table"><view class="table-row table-header-row" wx:if="{{item[0].headers.length}}"><text class="table-cell table-header-cell" wx:for="{{item[0].headers}}" wx:key="index" wx:for-item="hdr">{{hdr}}</text></view><view class="table-row" wx:for="{{item[0].rows}}" wx:key="index" wx:for-item="row"><text class="table-cell" wx:for="{{row}}" wx:key="index" wx:for-item="cell">{{cell}}</text></view></view></scroll-view>
<view wx:elif="{{item.length === 1 && item[0].type === 'listItem'}}" class="seg-list-item"><text class="seg-list-marker" wx:if="{{item[0].ordered}}">{{item[0].number}}.</text><text class="seg-list-marker" wx:else>•</text><text class="seg-list-text" user-select>{{item[0].text}}</text></view>
<view wx:elif="{{item.length === 1 && item[0].type === 'image'}}" class="paragraph"><image class="content-image" src="{{item[0].src}}" mode="widthFix" show-menu-by-longpress bindtap="onImageTap" data-src="{{item[0].src}}"></image></view>
<view wx:else class="paragraph"><text user-select><block wx:for="{{item}}" wx:key="index" wx:for-item="seg"><text wx:if="{{seg.type === 'text'}}">{{seg.text}}</text><text wx:elif="{{seg.type === 'mention'}}" class="mention" bindtap="onMentionTap" data-user-id="{{seg.userId}}" data-nickname="{{seg.nickname}}">{{seg.mentionDisplay}}</text><text wx:elif="{{seg.type === 'linkTag'}}" class="link-tag" 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></block></text><block wx:for="{{item}}" wx:key="index" wx:for-item="seg"><image wx:if="{{seg.type === 'image'}}" class="content-image" src="{{seg.src}}" mode="widthFix" show-menu-by-longpress bindtap="onImageTap" data-src="{{seg.src}}"></image></block></view>
</block>
</view>
<view class="fade-mask"></view>
</view>
<!-- 付费墙 - 已登录未购买 -->
<view class="paywall {{readSinglePageMode ? 'paywall--single-preview' : ''}}">
<view class="paywall-icon"><icon name="lock" size="80" color="#00CED1"></icon></view>
<block wx:if="{{readSinglePageMode}}">
<view class="paywall-title-row">
<text class="paywall-title paywall-title--inline">解锁完整内容,分享得到</text>
<text class="paywall-highlight-pct">{{shareRate || 90}}%</text>
<text class="paywall-title paywall-title--inline">收益</text>
</view>
<view class="purchase-options" wx:if="{{!auditMode}}">
<view class="purchase-btn purchase-section purchase-btn--fulltext" bindtap="onUnlockTapInSinglePage">
<text class="btn-label btn-label--block">支付 ¥{{section && section.price != null ? section.price : sectionPrice}} 解锁全文</text>
</view>
</view>
<view class="paywall-audit-tip" wx:if="{{auditMode}}">审核中,暂不支持购买</view>
</block>
<block wx:else>
<text class="paywall-title">{{readUi.fullUnlockTitle || '加入365读书会'}}</text>
<text class="paywall-desc">{{readUi.fullUnlockDesc || '可先上滑阅读预览'}}</text>
<text class="paywall-subdesc" wx:if="{{readUi.fullLockedProgressText}}">{{readUi.fullLockedProgressText}}</text>
<text class="paywall-subdesc" wx:else>已阅读约 {{effectivePreviewPercent}}% ,购买后继续阅读</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>
<view class="purchase-btn purchase-fullbook" bindtap="handlePurchaseFullBook" wx:if="{{purchasedCount >= fullbookShowThreshold}}">
<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}}</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}}">{{readUi.fullPaywallTip || ('分享给好友,好友购买你可获得约 ' + (shareRate || 90) + '% 收益')}}</text>
</block>
</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>
<!-- 海报生成弹窗:居中 + z-index 高于右下角悬浮,避免「空白」错觉 -->
<view class="modal-overlay modal-overlay-center" wx:if="{{showPosterModal}}" bindtap="closePosterModal">
<view class="modal-content modal-content-center 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 type="2d" 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>
<!-- 登录弹窗(公用组件) -->
<login-modal
show="{{showLoginModal}}"
desc="登录后可购买章节、解锁更多内容"
showPrivacyModal="{{showPrivacyModal}}"
bind:close="onLoginModalClose"
bind:success="onLoginModalSuccess"
bind:privacyagree="onLoginModalPrivacyAgree"
/>
<!-- 支付中提示 -->
<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="singlepage-launch-pointer" wx:if="{{readSinglePageMode && momentsPaywallExpanded}}" aria-hidden="true">
<view class="singlepage-launch-pointer__arrow">↓</view>
</view>
<view class="fab-share-moments" wx:if="{{!readSinglePageMode}}" bindtap="shareToMoments" hover-class="fab-share-moments-hover" aria-label="分享到朋友圈">
<icon name="share" size="44" color="#ffffff" customClass="fab-share-moments-icon"></icon>
</view>
<!-- 分享到朋友圈 自定义弹窗 -->
<view class="modal-overlay modal-overlay-center" wx:if="{{showMomentsModal}}" bindtap="closeMomentsModal">
<view class="modal-content modal-content-center moments-modal" catchtap="stopPropagation">
<view class="modal-header">
<text class="modal-title">分享到朋友圈</text>
<view class="modal-close" bindtap="closeMomentsModal"><icon name="x" size="36" color="#8e8e93"></icon></view>
</view>
<view class="moments-earn-banner">
<text class="moments-earn-text">好友购买,你获得</text>
<text class="moments-earn-pct">{{shareRate || 90}}%</text>
<text class="moments-earn-text">收益</text>
</view>
<view class="moments-steps">
<view class="moments-step">
<view class="moments-step-num">1</view>
<text class="moments-step-text">点击下方按钮复制文案</text>
</view>
<view class="moments-step">
<view class="moments-step-num">2</view>
<text class="moments-step-text">点击右上角「···」→「分享到朋友圈」</text>
</view>
<view class="moments-step">
<view class="moments-step-num">3</view>
<text class="moments-step-text">粘贴文案发布即可</text>
</view>
</view>
<view class="moments-copy-btn {{momentsCopied ? 'moments-copy-btn--done' : ''}}" bindtap="onMomentsCopy">
<text>{{momentsCopied ? '已复制,去发朋友圈' : '复制发圈文案'}}</text>
</view>
</view>
</view>
<!-- 朋友圈单页预览:点「支付解锁全文」→ 半透明遮罩 + 底部提示 + 向下箭头指向系统「前往小程序」底栏 -->
<view
class="moments-launch-guide-mask"
wx:if="{{readSinglePageMode && showMomentsLaunchGuideModal}}"
bindtap="closeMomentsLaunchGuideModal"
>
<view class="moments-launch-guide-sheet" catchtap="stopPropagation">
<text class="moments-launch-guide-text">请点击下方「前往小程序」查看全文</text>
<view class="moments-launch-guide-arrow-wrap" aria-hidden="true">
<text class="moments-launch-guide-arrow">↓</text>
</view>
</view>
</view>
</view>