This commit is contained in:
Alex-larget
2026-03-27 20:23:02 +08:00
parent 7027d2405a
commit d3353e59c0
10 changed files with 223 additions and 281 deletions

View File

@@ -22,6 +22,7 @@ const { checkAndExecute } = require('../../utils/ruleEngine')
const soulBridge = require('../../utils/soulBridge.js')
const app = getApp()
const mpPagePopups = require('../../utils/mpPagePopups.js')
/** 阅读页解析正文用:人物字典 + #标签(与 /config/read-extras 一致) */
function getContentParseConfig() {
@@ -47,7 +48,7 @@ function chapterApiContent(res) {
}
/** 补全 mentionDisplay避免旧数据无字段昵称去空白防「@ 名」 */
/** 试读比例data.previewPercent兼容旧响应顶层 previewPercent缺省 20 */
/** 试读比例data.previewPercent(有效试读%;兼容旧响应顶层 previewPercent缺省 20 */
function normalizePreviewPercent(res) {
if (!res) return 20
const tryNum = (v) => {
@@ -147,9 +148,11 @@ Page({
previewMaxHeightPx: 0,
/** mpUi.readPage.beforeLoginHint未登录付费墙上方说明文案 */
readBeforeLoginHint: '',
/** 朋友圈单页标题与说明mpUi.readPage.singlePageTitle / singlePagePaywallHint */
readSinglePageTitle: '解锁全文',
readSinglePageHint: '',
/** 单页长文案title + sub + 分销pagePopupItemskey 沿用 singlePage* */
readSinglePageTitle: '解锁完整内容',
readSinglePagePaywallSub: '预览页不能直接付款,务必先点底栏「前往小程序」。',
readSinglePageShareLine1: '好友经你分享购买,你可获得约 90% 收益',
readSinglePageShareLine2: '转发给需要的人,一起学习还能赚佣金',
showPaywall: false,
// 上一篇/下一篇
@@ -199,8 +202,9 @@ Page({
},
/**
* 未解锁时:先渲染完整正文,再测量其高度,按 previewPercent 计算可见高度并裁切。
* 这样后端无需截断,避免 HTML/段落被截断导致的渲染失败
* 未解锁试读:先不设 max-heightpreviewMaxHeightPx=0让正文与图片在 DOM 里完整排版;
* 再量 #previewContentMeasure 总高度,按 previewPercent 换算 max-height + overflow:hidden
* 图片 widthFix 异步增高后由 onPreviewContentImageLoad 防抖再次测量。
*/
_updatePreviewClipHeight() {
const state = this.data.accessState
@@ -241,6 +245,16 @@ Page({
apply().catch(() => {})
},
/** 预览区内图片加载完成:布局高度变化,防抖后重新按完整高度裁切 */
onPreviewContentImageLoad() {
if (!this._isLockedState(this.data.accessState)) return
if (this._previewClipImgTimer) clearTimeout(this._previewClipImgTimer)
this._previewClipImgTimer = setTimeout(() => {
this._previewClipImgTimer = null
this._updatePreviewClipHeight()
}, 200)
},
/**
* 是否处于朋友圈等「单页预览」环境。
* 兼容:部分机型/基础库首帧 getSystemInfoSync().mode 未就绪,需结合 launch/enter scene 1154、getWindowInfo。
@@ -274,7 +288,7 @@ Page({
return !!app.globalData.isSinglePageMode
},
/** 单页模式下点「购买本章」:触觉反馈 + 展开极简说明;引导靠页内文案 + 底栏箭头,不再弹长 Modal */
/** 单页模式下点「支付解锁」行:触觉反馈;文案与底栏箭头默认已展开,不再弹长 Modal */
onUnlockTapInSinglePage() {
trackClick('read', 'btn_click', '单页_解锁引导')
try {
@@ -290,7 +304,7 @@ Page({
this.setData({
auditMode: app.globalData.auditMode || false,
readSinglePageMode: sp,
...(sp ? {} : { momentsPaywallExpanded: false }),
...(sp ? { momentsPaywallExpanded: true } : { momentsPaywallExpanded: false }),
})
},
@@ -306,16 +320,31 @@ Page({
const mp = (cfg && cfg.mpConfig) || {}
const auditMode = !!mp.auditMode
app.globalData.auditMode = auditMode
const rp = (mp.mpUi && mp.mpUi.readPage) || {}
const readBeforeLoginHint = String(rp.beforeLoginHint || '').trim()
const readSinglePageTitle = String(rp.singlePageTitle || '解锁全文').trim() || '解锁全文'
const readSinglePageHint = String(rp.singlePagePaywallHint || '').trim()
const readBeforeLoginHint =
mpPagePopups.getReadPageContent(app, 'beforeLoginHint') ||
String((mp.mpUi && mp.mpUi.readPage && mp.mpUi.readPage.beforeLoginHint) || '').trim()
let readSinglePageTitle =
mpPagePopups.getReadPageContent(app, 'singlePageTitle') ||
String((mp.mpUi && mp.mpUi.readPage && mp.mpUi.readPage.singlePageTitle) || '').trim() ||
'解锁完整内容'
readSinglePageTitle = readSinglePageTitle || '解锁完整内容'
const readSinglePagePaywallSub =
mpPagePopups.getReadPageContent(app, 'singlePagePaywallSub') ||
'预览页不能直接付款,务必先点底栏「前往小程序」。'
const readSinglePageShareLine1 =
mpPagePopups.getReadPageContent(app, 'singlePageShareEarn1') ||
'好友经你分享购买,你可获得约 90% 收益'
const readSinglePageShareLine2 =
mpPagePopups.getReadPageContent(app, 'singlePageShareEarn2') ||
'转发给需要的人,一起学习还能赚佣金'
if (typeof this.setData === 'function') {
this.setData({
auditMode,
readBeforeLoginHint,
readSinglePageTitle,
readSinglePageHint,
readSinglePagePaywallSub,
readSinglePageShareLine1,
readSinglePageShareLine2,
})
}
}
@@ -358,6 +387,7 @@ Page({
return
}
const spMode = this._detectReadSinglePage()
this.setData({
statusBarHeight: app.globalData.statusBarHeight,
navBarHeight: app.globalData.navBarHeight,
@@ -366,8 +396,8 @@ Page({
loading: true,
accessState: 'unknown',
pendingGiftRequestSn: giftRequestSn || '',
readSinglePageMode: this._detectReadSinglePage(),
momentsPaywallExpanded: false,
readSinglePageMode: spMode,
momentsPaywallExpanded: spMode,
})
if (ref) {
@@ -555,7 +585,6 @@ Page({
// 先关闭裁切,等 DOM 更新后再测量并按比例裁切
this.setData({ ...updates, previewMaxHeightPx: 0 })
this._updatePreviewClipHeight()
// 写入本地缓存(存 displayContent供离线/重试降级使用)
try { wx.setStorageSync(cacheKey, { ...res }) } catch (_) {}
if (accessManager.canAccessFullContent(accessState)) {
app.markSectionAsRead(id)
@@ -838,7 +867,7 @@ Page({
wx.showToast({ title: '暂无跳转地址', icon: 'none' })
},
// 点击正文图片 → 全屏预览
// 点击正文图片 → 全屏预览(预览区图片同时 bindload 触发 onPreviewContentImageLoad
onImageTap(e) {
const src = e.currentTarget.dataset.src
if (!src) return
@@ -1084,12 +1113,8 @@ Page({
setTimeout(() => {
wx.hideToast()
wx.showModal({
title:
mpPagePopups.getReadPageContent(app, 'readMomentsShareGuideTitle') ||
'分享到朋友圈',
content:
mpPagePopups.getReadPageContent(app, 'readMomentsShareGuideBody') ||
'已复制发圈文案(非分享给好友)。\n\n请点击右上角「···」→「分享到朋友圈」粘贴发布。',
title: '分享到朋友圈',
content: '已复制发圈文案(非分享给好友)。\n\n请点击右上角「···」→「分享到朋友圈」粘贴发布。',
showCancel: false,
confirmText: '知道了'
})
@@ -1265,12 +1290,8 @@ Page({
if (needProfile) {
const res = await new Promise(resolve => {
wx.showModal({
title:
mpPagePopups.getReadPageContent(app, 'beforePayAvatarNicknameTitle') ||
'设置头像与昵称',
content:
mpPagePopups.getReadPageContent(app, 'beforePayAvatarNicknameBody') ||
'支付订单会关联你的对外展示信息,请先设置头像与昵称,避免账单与对方看到默认占位。',
title: '设置头像与昵称',
content: '支付订单会关联你的对外展示信息,请先设置头像与昵称,避免账单与对方看到默认占位。',
confirmText: '去设置',
cancelText: '关闭',
success: resolve

View File

@@ -1,6 +1,6 @@
<!--pages/read/read.wxml-->
<!--卡若创业派对 - 阅读页-->
<view class="page {{readSinglePageMode ? 'page--single-preview' : ''}}">
<view class="page">
<!-- 阅读进度条 -->
<view class="progress-bar-fixed" style="top: {{statusBarHeight}}px;">
<view class="progress-fill" style="width: {{readingProgress}}%;"></view>
@@ -124,7 +124,7 @@
<view class="paragraph" wx:for="{{contentSegments}}" wx:key="index">
<text user-select wx:if="{{!(item.length === 1 && item[0].type === 'image')}}"><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>
<image wx:if="{{seg.type === 'image'}}" class="content-image" src="{{seg.src}}" mode="widthFix" show-menu-by-longpress bindload="onPreviewContentImageLoad" bindtap="onImageTap" data-src="{{seg.src}}"></image>
</block>
</view>
</view>
@@ -132,37 +132,44 @@
<view class="fade-mask"></view>
</view>
<!-- 付费墙 - 未登录:完整小程序登录+价;朋友圈单页与正文同款「购买本章 ¥1」点后再展开极简说明 -->
<!-- 付费墙 - 未登录:单页=短引导;完整端=长文案+登录 -->
<view class="paywall {{readSinglePageMode ? 'paywall--single-preview' : ''}}">
<view class="paywall-icon"><icon name="lock" size="80" color="#00CED1"></icon></view>
<!-- 单页预览:长文案(预览无法支付+分销);完整小程序:图二短文案 -->
<block wx:if="{{readSinglePageMode}}">
<text class="paywall-title">{{readSinglePageTitle}}</text>
<text class="paywall-desc" wx:if="{{!auditMode}}">试读 {{previewPercent}}%(与后台试读比例一致)</text>
<view class="purchase-options" wx:if="{{!auditMode}}">
<text class="paywall-sp-lead" wx:if="{{!auditMode}}">全文 ¥{{section && section.price != null ? section.price : sectionPrice}}。预览里无法完成支付:请先点屏幕底部「前往小程序」进入完整版,登录后再付款解锁。</text>
<view class="purchase-options paywall-sp-purchase-wrap" wx:if="{{!auditMode}}">
<view class="purchase-btn purchase-section" bindtap="onUnlockTapInSinglePage">
<text class="btn-label">购买本章</text>
<text class="btn-price brand-color">¥1</text>
<text class="btn-label">支付 ¥{{section && section.price != null ? section.price : sectionPrice}} 解锁全文</text>
<text class="btn-price brand-color">¥{{section && section.price != null ? section.price : sectionPrice}}</text>
</view>
</view>
<view class="paywall-audit-tip" wx:if="{{auditMode}}">审核中,暂不支持购买</view>
<text class="paywall-desc paywall-desc--moments-expanded" wx:if="{{momentsPaywallExpanded}}">{{readSinglePageHint || '预览不可付款,请点底部「前往小程序」。'}}</text>
<text class="paywall-sp-sub" wx:if="{{!auditMode}}">{{readSinglePagePaywallSub}}</text>
<view class="paywall-share-earn-wrap" wx:if="{{!auditMode}}">
<text class="share-tip-text">{{readSinglePageShareLine1}}</text>
<text class="share-tip-text paywall-share-earn-sub">{{readSinglePageShareLine2}}</text>
</view>
</block>
<block wx:else>
<text class="paywall-title">解锁完整内容</text>
<text class="paywall-desc paywall-desc--pre" wx:if="{{readBeforeLoginHint}}">{{readBeforeLoginHint}}</text>
<text class="paywall-desc">已阅读{{previewPercent}}%,登录并支付 ¥{{section && section.price != null ? section.price : sectionPrice}} 后阅读全文</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>
<text class="paywall-desc paywall-desc--pre" wx:if="{{readBeforeLoginHint && !auditMode}}">{{readBeforeLoginHint}}</text>
<block wx:if="{{!auditMode}}">
<text class="paywall-sp-lead paywall-sp-lead--short">可先上滑阅读预览;需要全文时,点下方「支付 ¥{{section && section.price != null ? section.price : sectionPrice}}」查看说明</text>
<view class="purchase-options paywall-sp-purchase-wrap">
<view class="purchase-btn purchase-section" bindtap="handlePurchaseSection">
<text class="btn-label">支付 ¥{{section && section.price != null ? section.price : sectionPrice}} 解锁全文</text>
<text class="btn-price brand-color">¥{{section && section.price != null ? section.price : sectionPrice}}</text>
</view>
</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}}">分享给好友一起学习,还能赚取佣金</text>
<view class="login-btn" bindtap="showLoginModal" style="margin-top:12px">
<text class="login-btn-text">手机号登录后购买</text>
</view>
</block>
<view class="paywall-audit-tip" wx:if="{{auditMode}}">审核中,暂不支持购买</view>
</block>
</view>
@@ -208,7 +215,7 @@
<view class="paragraph" wx:for="{{contentSegments}}" wx:key="index">
<text user-select wx:if="{{!(item.length === 1 && item[0].type === 'image')}}"><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>
<image wx:if="{{seg.type === 'image'}}" class="content-image" src="{{seg.src}}" mode="widthFix" show-menu-by-longpress bindload="onPreviewContentImageLoad" bindtap="onImageTap" data-src="{{seg.src}}"></image>
</block>
</view>
</view>
@@ -222,42 +229,47 @@
<block wx:if="{{readSinglePageMode}}">
<text class="paywall-title">{{readSinglePageTitle}}</text>
<text class="paywall-desc" wx:if="{{!auditMode}}">试读 {{previewPercent}}%(与后台试读比例一致)</text>
<view class="purchase-options" wx:if="{{!auditMode}}">
<text class="paywall-sp-lead" wx:if="{{!auditMode}}">全文 ¥{{section && section.price != null ? section.price : sectionPrice}}。预览里无法完成支付:请先点屏幕底部「前往小程序」进入完整版,登录后再付款解锁。</text>
<view class="purchase-options paywall-sp-purchase-wrap" wx:if="{{!auditMode}}">
<view class="purchase-btn purchase-section" bindtap="onUnlockTapInSinglePage">
<text class="btn-label">购买本章</text>
<text class="btn-price brand-color">¥1</text>
<text class="btn-label">支付 ¥{{section && section.price != null ? section.price : sectionPrice}} 解锁全文</text>
<text class="btn-price brand-color">¥{{section && section.price != null ? section.price : sectionPrice}}</text>
</view>
</view>
<view class="paywall-audit-tip" wx:if="{{auditMode}}">审核中,暂不支持购买</view>
<text class="paywall-desc paywall-desc--moments-expanded" wx:if="{{momentsPaywallExpanded}}">{{readSinglePageHint || '预览不可付款,请点底部「前往小程序」。'}}</text>
<text class="paywall-sp-sub" wx:if="{{!auditMode}}">{{readSinglePagePaywallSub}}</text>
<view class="paywall-share-earn-wrap" wx:if="{{!auditMode}}">
<text class="share-tip-text">{{readSinglePageShareLine1}}</text>
<text class="share-tip-text paywall-share-earn-sub">{{readSinglePageShareLine2}}</text>
</view>
</block>
<block wx:else>
<text class="paywall-title">解锁完整内容</text>
<text class="paywall-desc">已阅读{{previewPercent}}%,购买后继续阅读</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 >= 3}}">
<view class="btn-left">
<icon name="sparkles" size="32" color="#FFD700" customClass="btn-sparkle"></icon>
<text class="btn-label">解锁全部 {{totalSections}} 章</text>
<block wx:if="{{!auditMode}}">
<text class="paywall-sp-lead paywall-sp-lead--short">可先上滑阅读预览;需要全文时,点下方「支付 ¥{{section && section.price != null ? section.price : sectionPrice}}」查看说明</text>
<view class="purchase-options paywall-sp-purchase-wrap">
<view class="purchase-btn purchase-section" bindtap="handlePurchaseSection">
<text class="btn-label">支付 ¥{{section && section.price != null ? section.price : sectionPrice}} 解锁全文</text>
<text class="btn-price brand-color">¥{{section && section.price != null ? section.price : sectionPrice}}</text>
</view>
<view class="btn-right">
<text class="btn-price">¥{{fullBookPrice}}</text>
<text class="btn-discount">省82%</text>
<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}}</text>
<text class="btn-discount">省82%</text>
</view>
</view>
</view>
</view>
<view class="gift-share-row" bindtap="showGiftShareModal" wx:if="{{isLoggedIn}}">
<icon name="gift" size="40" color="#00CED1" customClass="gift-share-icon"></icon>
<text class="gift-share-text">代付分享</text>
</view>
</block>
<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>
</block>
</view>
@@ -401,11 +413,9 @@
</view>
</view>
<!-- 单页预览:竖直向下箭头指向微信底部「前往小程序」 -->
<view class="singlepage-launch-pointer" wx:if="{{readSinglePageMode}}" aria-hidden="true">
<view class="singlepage-launch-pointer__arrow-inner">
<view class="singlepage-launch-pointer__shaft"></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="分享到朋友圈">

View File

@@ -298,7 +298,35 @@
margin-bottom: 24rpx;
}
.paywall--single-preview .paywall-title {
margin-bottom: 20rpx;
}
/* 朋友圈单页图二:首段说明 + 与购买行间距收紧 */
.paywall-sp-lead {
font-size: 26rpx;
color: rgba(255, 255, 255, 0.62);
line-height: 1.55;
text-align: left;
display: block;
padding: 0 8rpx;
margin-bottom: 24rpx;
}
.paywall-sp-sub {
font-size: 24rpx;
color: rgba(255, 255, 255, 0.45);
text-align: center;
line-height: 1.5;
display: block;
margin-top: 20rpx;
margin-bottom: 28rpx;
padding: 0 12rpx;
}
.paywall--single-preview .paywall-sp-purchase-wrap {
margin-bottom: 0;
}
/* 单页短说明:居中,与图二一致 */
.paywall-sp-lead--short {
text-align: center;
color: rgba(255, 255, 255, 0.58);
}
.paywall-desc--moments-expanded {
margin-top: 28rpx !important;
@@ -1373,55 +1401,33 @@ button.action-share-native {
filter: drop-shadow(0 2rpx 4rpx rgba(0, 0, 0, 0.25));
}
/* 单页快照:为微信底部系统栏预留滚动空间(无自绘底栏) */
.page--single-preview .read-content {
padding-bottom: calc(96rpx + env(safe-area-inset-bottom));
}
/* 朋友圈单页竖直向下箭头90°指向底栏「前往小程序」 */
/* 朋友圈单页:垂直箭头指向底栏右侧「前往小程序」大致区域 */
.singlepage-launch-pointer {
position: fixed;
right: 40rpx;
bottom: calc(44rpx + env(safe-area-inset-bottom));
/* 与单页底栏右侧按钮区对齐(略偏左于右缘,对准按钮中心) */
right: 72rpx;
bottom: calc(168rpx + env(safe-area-inset-bottom));
z-index: 99985;
pointer-events: none;
width: 56rpx;
height: 220rpx;
overflow: visible;
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-end;
}
.singlepage-launch-pointer__arrow-inner {
animation: singlepage-launch-bounce 1.1s ease-in-out infinite;
.singlepage-launch-pointer__arrow {
font-size: 56rpx;
line-height: 1;
color: #00CED1;
text-shadow: 0 0 20rpx rgba(0, 206, 209, 0.55);
animation: singlepage-launch-pulse 1.25s ease-in-out infinite;
}
.singlepage-launch-pointer__shaft {
position: relative;
width: 10rpx;
height: 168rpx;
background: linear-gradient(180deg, rgba(0, 206, 209, 0.25), #00ced1);
border-radius: 5rpx;
box-shadow: 0 0 16rpx rgba(0, 206, 209, 0.55), 0 0 28rpx rgba(0, 206, 209, 0.35);
}
/* 三角在杆底端,朝下 */
.singlepage-launch-pointer__shaft::after {
content: '';
position: absolute;
left: 50%;
bottom: -4rpx;
margin-left: -16rpx;
border-style: solid;
border-width: 18rpx 16rpx 0 16rpx;
border-color: #00ced1 transparent transparent transparent;
}
/* 整段箭头持续上下位移,引导注意底部按钮 */
@keyframes singlepage-launch-bounce {
@keyframes singlepage-launch-pulse {
0%,
100% {
transform: translateY(-8rpx);
opacity: 0.75;
transform: translateY(0) scale(1);
}
50% {
transform: translateY(10rpx);
opacity: 1;
transform: translateY(12rpx) scale(1.06);
}
}

View File

@@ -24,11 +24,32 @@
"miniprogram": {
"list": [
{
"name": "35%",
"name": "pages/read/read",
"pathName": "pages/read/read",
"query": "mid=233",
"scene": null,
"launchMode": "singlePage"
},
{
"name": "个人资料",
"pathName": "pages/avatar-nickname/avatar-nickname",
"query": "",
"launchMode": "default",
"scene": null
},
{
"name": "代付",
"pathName": "pages/gift-pay/detail",
"query": "requestSn=GPRMP20260317145140501100",
"launchMode": "default",
"scene": null
},
{
"name": "pages/my/my",
"pathName": "pages/my/my",
"query": "",
"launchMode": "singlePage",
"scene": null
}
]
}

View File

@@ -4,15 +4,11 @@
*
* 当前代码显式引用的键(与 soul-admin 默认种子 / db.defaultMpUi 一致,勿改 key 除非双端同步):
* - MEMBER_PATH unlockIntroTitle, unlockIntroBody → member-detail.js _showUnlockIntroThenLogin
* - READ_PATH beforeLoginHint, singlePageTitle, singlePagePaywallHint → read.js onLoad
* - READ_PATH beforePayAvatarNicknameTitle, beforePayAvatarNicknameBody → read.js processPayment支付前头像昵称引导
* - READ_PATH readMomentsShareGuideTitle, readMomentsShareGuideBody → read.js shareToMoments
* - APP_GLOBAL_PATH global* → app.js单页拦截、头像引导、VIP 补全、更新提示等)
* - READ_PATH beforeLoginHint, singlePageTitle, singlePagePaywallHint(旧), singlePagePaywallSub, singlePageShareEarn1/2单页长文案区 → read.js onLoad
*/
const MEMBER_PATH = '/pages/member-detail/member-detail'
const READ_PATH = '/pages/read/read'
const APP_GLOBAL_PATH = '/app/global'
function getList(app) {
const mpUi = app.globalData.configCache && app.globalData.configCache.mpConfig
@@ -49,6 +45,9 @@ function getReadPageContent(app, key) {
if (key === 'beforeLoginHint') return String(rp.beforeLoginHint || '').trim()
if (key === 'singlePageTitle') return String(rp.singlePageTitle || '').trim()
if (key === 'singlePagePaywallHint') return String(rp.singlePagePaywallHint || '').trim()
if (key === 'singlePagePaywallSub') return String(rp.singlePagePaywallSub || '').trim()
if (key === 'singlePageShareEarn1') return String(rp.singlePageShareEarn1 || '').trim()
if (key === 'singlePageShareEarn2') return String(rp.singlePageShareEarn2 || '').trim()
return ''
}
@@ -63,17 +62,10 @@ function getMemberDetailContent(app, key) {
return ''
}
/** App 级多页共用弹窗pagePath=/app/global见管理端弹窗文案「全局」 */
function getGlobalPopupContent(app, key) {
return getPagePopupContent(app, APP_GLOBAL_PATH, key)
}
module.exports = {
getPagePopupContent,
getReadPageContent,
getMemberDetailContent,
getGlobalPopupContent,
MEMBER_PATH,
READ_PATH,
APP_GLOBAL_PATH,
}

View File

@@ -28,12 +28,8 @@ export type PagePopupItem = {
const MEMBER_PATH = '/pages/member-detail/member-detail'
const READ_PATH = '/pages/read/read'
/** 非真实页面路径App 内多处共用的弹窗文案app.js 等) */
export const APP_GLOBAL_PAGE_PATH = '/app/global'
/** 常见路径的默认页面名称(未单独填写 pageName 时表格展示用) */
export const KNOWN_PAGE_NAMES: Record<string, string> = {
[APP_GLOBAL_PAGE_PATH]: '全局App 多页)',
[MEMBER_PATH]: '成员详情',
[READ_PATH]: '文章详情 / 阅读',
}
@@ -43,7 +39,6 @@ export const KNOWN_PAGE_NAMES: Record<string, string> = {
* value 必须以 / 开头,与小程序 wx.navigateTo 路径一致
*/
export const POPUP_PAGE_PATH_OPTIONS: { value: string; label: string }[] = [
{ value: APP_GLOBAL_PAGE_PATH, label: '全局App 多页共用)' },
{ value: '/pages/index/index', label: '首页' },
{ value: '/pages/chapters/chapters', label: '目录' },
{ value: '/pages/match/match', label: '找伙伴' },
@@ -167,7 +162,10 @@ export function migrateLegacyPagePopups(raw: unknown): PagePopupItem[] {
const pairs: [string, string, PagePopupScope][] = [
['beforeLoginHint', '未登录时付费墙上方说明', 'fullApp'],
['singlePageTitle', '朋友圈单页 · 付费区标题', 'singlePage'],
['singlePagePaywallHint', '朋友圈单页 · 付费墙说明', 'singlePage'],
['singlePagePaywallHint', '朋友圈单页 · 付费墙说明(旧)', 'singlePage'],
['singlePagePaywallSub', '朋友圈单页 · 付费墙第二段小字', 'singlePage'],
['singlePageShareEarn1', '朋友圈单页 · 分销说明第一行', 'singlePage'],
['singlePageShareEarn2', '朋友圈单页 · 分销说明第二行', 'singlePage'],
]
for (const [k, behavior, scope] of pairs) {
if (typeof r[k] === 'string' && String(r[k]).trim()) {
@@ -293,10 +291,9 @@ export function summarizePopupRow(p: PagePopupItem): string {
* 对照(唯一来源清单):
* - `miniprogram/utils/mpPagePopups.js``getMemberDetailContent` / `getReadPageContent` 使用的 pagePath + key
* - `/pages/member-detail/member-detail.js` → `_showUnlockIntroThenLogin`unlockIntro*;正文兜底与下述 content 一致)
* - `/pages/read/read.js` → `onLoad` / `processPayment` / `shareToMoments` 等
* - `/app/global` → `app.js` ensureFullAppForAuth、头像引导、VIP 补全、更新提示等getGlobalPopupContent
* - `/pages/read/read.js` → `onLoad` 内 beforeLoginHint / singlePage*(标题兜底「解锁完整内容」)
*
* 当前共 21 条,勿随意改 key改文案请在后台或改此处种子后重新保存。
* 当前共 8 条,勿随意改 key改文案请在后台或改此处种子后重新保存。
*/
export const SEED_PAGE_POPUP_ITEMS: Omit<PagePopupItem, 'id'>[] = [
{
@@ -324,153 +321,46 @@ export const SEED_PAGE_POPUP_ITEMS: Omit<PagePopupItem, 'id'>[] = [
behavior: '未登录时付费墙上方说明',
content: '试读进度与下方百分比以后台配置为准;登录后可购买解锁全文。',
},
{
pageName: KNOWN_PAGE_NAMES[READ_PATH],
pagePath: READ_PATH,
scope: 'fullApp',
key: 'beforePayAvatarNicknameTitle',
behavior: '支付前 · 未完善头像昵称时弹窗标题wx.showModal',
content: '设置头像与昵称',
},
{
pageName: KNOWN_PAGE_NAMES[READ_PATH],
pagePath: READ_PATH,
scope: 'fullApp',
key: 'beforePayAvatarNicknameBody',
behavior: '支付前 · 未完善头像昵称时弹窗正文wx.showModal',
content:
'支付订单会关联你的对外展示信息,请先设置头像与昵称,避免账单与对方看到默认占位。',
},
{
pageName: KNOWN_PAGE_NAMES[READ_PATH],
pagePath: READ_PATH,
scope: 'singlePage',
key: 'singlePageTitle',
behavior: '朋友圈单页 · 付费区标题',
content: '解锁全文',
content: '解锁完整内容',
},
{
pageName: KNOWN_PAGE_NAMES[READ_PATH],
pagePath: READ_PATH,
scope: 'singlePage',
key: 'singlePagePaywallHint',
behavior: '朋友圈单页 · 付费墙说明',
behavior: '朋友圈单页 · 付费墙说明(旧版折叠区,当前页已不用)',
content:
'当前为朋友圈单页预览,无法在此登录或付款。请点击底部「前往小程序」进入完整版后再解锁本章。',
},
{
pageName: KNOWN_PAGE_NAMES[APP_GLOBAL_PAGE_PATH],
pagePath: APP_GLOBAL_PAGE_PATH,
pageName: KNOWN_PAGE_NAMES[READ_PATH],
pagePath: READ_PATH,
scope: 'singlePage',
key: 'globalSinglePageAuthTitle',
behavior: '单页模式 · 拦截登录/支付前弹窗标题app.ensureFullAppForAuth',
content: '请打开完整小程序',
},
{
pageName: KNOWN_PAGE_NAMES[APP_GLOBAL_PAGE_PATH],
pagePath: APP_GLOBAL_PAGE_PATH,
scope: 'singlePage',
key: 'globalSinglePageAuthBody',
behavior: '单页模式 · 拦截登录/支付前弹窗正文',
content:
'当前是朋友圈预览,无法在这里登录或付款。请先点击屏幕底部「前往小程序」,进入完整版后再解锁本章。',
},
{
pageName: KNOWN_PAGE_NAMES[APP_GLOBAL_PAGE_PATH],
pagePath: APP_GLOBAL_PAGE_PATH,
scope: 'fullApp',
key: 'globalAvatarGuideTitle',
behavior: '非 VIP · 每日头像昵称引导弹窗标题app.checkAvatarNicknameAndGuide',
content: '设置头像与昵称',
},
{
pageName: KNOWN_PAGE_NAMES[APP_GLOBAL_PAGE_PATH],
pagePath: APP_GLOBAL_PAGE_PATH,
scope: 'fullApp',
key: 'globalAvatarGuideBody',
behavior: '非 VIP · 每日头像昵称引导弹窗正文',
content: '头像与昵称会出现在名片与匹配卡片上,方便伙伴认出你。',
},
{
pageName: KNOWN_PAGE_NAMES[APP_GLOBAL_PAGE_PATH],
pagePath: APP_GLOBAL_PAGE_PATH,
scope: 'fullApp',
key: 'globalVipProfileHintTitle',
behavior: 'VIP · 补全头像昵称弹窗标题checkVipContactRequiredAndGuide',
content: '补全对外展示信息',
},
{
pageName: KNOWN_PAGE_NAMES[APP_GLOBAL_PAGE_PATH],
pagePath: APP_GLOBAL_PAGE_PATH,
scope: 'fullApp',
key: 'globalVipProfileHintBody',
behavior: 'VIP · 补全头像昵称弹窗正文',
content: 'VIP 名片与派对场景会展示头像与昵称,补全后对方更容易认出你。',
},
{
pageName: KNOWN_PAGE_NAMES[APP_GLOBAL_PAGE_PATH],
pagePath: APP_GLOBAL_PAGE_PATH,
scope: 'fullApp',
key: 'globalVipPhoneTitle',
behavior: 'VIP · 缺手机号弹窗标题',
content: '补全手机号',
},
{
pageName: KNOWN_PAGE_NAMES[APP_GLOBAL_PAGE_PATH],
pagePath: APP_GLOBAL_PAGE_PATH,
scope: 'fullApp',
key: 'globalVipPhoneBody',
behavior: 'VIP · 缺手机号弹窗正文',
content: '手机号用于找伙伴、提现验证与重要通知,仅本人可见。',
},
{
pageName: KNOWN_PAGE_NAMES[APP_GLOBAL_PAGE_PATH],
pagePath: APP_GLOBAL_PAGE_PATH,
scope: 'fullApp',
key: 'globalVipWechatOptionalTitle',
behavior: 'VIP · 可选补微信号弹窗标题',
content: '补全微信号(可选)',
},
{
pageName: KNOWN_PAGE_NAMES[APP_GLOBAL_PAGE_PATH],
pagePath: APP_GLOBAL_PAGE_PATH,
scope: 'fullApp',
key: 'globalVipWechatOptionalBody',
behavior: 'VIP · 可选补微信号弹窗正文',
content: '填写微信号后,对方在允许的场景下能更快加到你;不填也可继续使用。',
},
{
pageName: KNOWN_PAGE_NAMES[APP_GLOBAL_PAGE_PATH],
pagePath: APP_GLOBAL_PAGE_PATH,
scope: 'fullApp',
key: 'globalAppUpdateTitle',
behavior: '小程序热更新就绪弹窗标题checkUpdate',
content: '更新提示',
},
{
pageName: KNOWN_PAGE_NAMES[APP_GLOBAL_PAGE_PATH],
pagePath: APP_GLOBAL_PAGE_PATH,
scope: 'fullApp',
key: 'globalAppUpdateBody',
behavior: '小程序热更新就绪弹窗正文',
content: '新版本已准备好,重启后即可使用',
key: 'singlePagePaywallSub',
behavior: '朋友圈单页 · 付费墙第二段小字(按钮下方',
content: '预览页不能直接付款,务必先点底栏「前往小程序」。',
},
{
pageName: KNOWN_PAGE_NAMES[READ_PATH],
pagePath: READ_PATH,
scope: 'fullApp',
key: 'readMomentsShareGuideTitle',
behavior: '阅读页 · 复制发圈文案后引导弹窗标题shareToMoments',
content: '分享到朋友圈',
scope: 'singlePage',
key: 'singlePageShareEarn1',
behavior: '朋友圈单页 · 分销说明第一行',
content: '好友经你分享购买,你可获得约 90% 收益',
},
{
pageName: KNOWN_PAGE_NAMES[READ_PATH],
pagePath: READ_PATH,
scope: 'fullApp',
key: 'readMomentsShareGuideBody',
behavior: '阅读页 · 复制发圈文案后引导弹窗正文',
content:
'已复制发圈文案(非分享给好友)。\n\n请点击右上角「···」→「分享到朋友圈」粘贴发布。',
scope: 'singlePage',
key: 'singlePageShareEarn2',
behavior: '朋友圈单页 · 分销说明第二行',
content: '转发给需要的人,一起学习还能赚佣金',
},
]

View File

@@ -653,7 +653,7 @@ func effectivePreviewPercent(db *gorm.DB, ch *model.Chapter) int {
return getUnpaidPreviewPercent(db)
}
// chapterDetailDataMap 将章节详情序列化为 mapdata.previewPercent 为有效试读%(章节覆盖优先,否则全局),避免未配置章节时出现 JSON null 引起误解
// chapterDetailDataMap 将章节详情序列化为 mapdata.previewPercent 为有效试读%(章节覆盖优先,否则全局)。
func chapterDetailDataMap(ch model.Chapter, effectivePreview int) (map[string]interface{}, error) {
b, err := json.Marshal(ch)
if err != nil {
@@ -669,7 +669,7 @@ func chapterDetailDataMap(ch model.Chapter, effectivePreview int) (map[string]in
// findChapterAndRespond 按条件查章节并返回统一格式
// 免费判断优先级system_config.free_chapters / chapter_config.freeChapters > chapters.is_free/price
// data.content 始终返回完整正文;未解锁时的试读比例在 data.previewPercent由小程序 overflow:hidden + 高度裁切,禁止服务端按字符截断以免破坏 HTML
// data.content 始终返回完整正文;试读比例在 data.previewPercent由小程序 overflow:hidden 裁切;不返回顶层 content/previewPercent
// content 缓存:优先 Redis命中时仅查元数据不含 LONGTEXT未命中时查全量并回填缓存
func findChapterAndRespond(c *gin.Context, whereFn func(*gorm.DB) *gorm.DB) {
var ch model.Chapter
@@ -711,7 +711,6 @@ func findChapterAndRespond(c *gin.Context, whereFn func(*gorm.DB) *gorm.DB) {
effectivePreview := effectivePreviewPercent(db, &ch)
returnContent := ch.Content
// data 内为完整正文 + previewPercent供小程序安全裁切展示
chForResponse := ch
chForResponse.Content = returnContent
chForResponse.PartTitle = sanitizeChapterTitleField(ch.PartTitle)

View File

@@ -168,24 +168,11 @@ func defaultMpUi() gin.H {
gin.H{"id": "seed-unlock-title", "pageName": "成员详情", "pagePath": "/pages/member-detail/member-detail", "scope": "fullApp", "key": "unlockIntroTitle", "behavior": "解锁前说明弹窗 · 标题wx.showModal title", "content": "解锁与链接说明"},
gin.H{"id": "seed-unlock-body", "pageName": "成员详情", "pagePath": "/pages/member-detail/member-detail", "scope": "fullApp", "key": "unlockIntroBody", "behavior": "解锁前说明弹窗 · 正文wx.showModal content", "content": "「链接」用于提交留资,由对方通过获客计划跟进;「解锁」用于复制手机/微信号后自行添加好友。\n\n请确认已了解后再登录。"},
gin.H{"id": "seed-read-hint", "pageName": "文章详情 / 阅读", "pagePath": "/pages/read/read", "scope": "fullApp", "key": "beforeLoginHint", "behavior": "未登录时付费墙上方说明", "content": "试读进度与下方百分比以后台配置为准;登录后可购买解锁全文。"},
gin.H{"id": "seed-read-pay-profile-title", "pageName": "文章详情 / 阅读", "pagePath": "/pages/read/read", "scope": "fullApp", "key": "beforePayAvatarNicknameTitle", "behavior": "支付前 · 未完善头像昵称时弹窗标题wx.showModal", "content": "设置头像与昵称"},
gin.H{"id": "seed-read-pay-profile-body", "pageName": "文章详情 / 阅读", "pagePath": "/pages/read/read", "scope": "fullApp", "key": "beforePayAvatarNicknameBody", "behavior": "支付前 · 未完善头像昵称时弹窗正文wx.showModal", "content": "支付订单会关联你的对外展示信息,请先设置头像与昵称,避免账单与对方看到默认占位。"},
gin.H{"id": "seed-read-sp-title", "pageName": "文章详情 / 阅读", "pagePath": "/pages/read/read", "scope": "singlePage", "key": "singlePageTitle", "behavior": "朋友圈单页 · 付费区标题", "content": "解锁全文"},
gin.H{"id": "seed-read-sp-hint", "pageName": "文章详情 / 阅读", "pagePath": "/pages/read/read", "scope": "singlePage", "key": "singlePagePaywallHint", "behavior": "朋友圈单页 · 付费墙说明", "content": "当前为朋友圈单页预览,无法在此登录或付款。请点击底部「前往小程序」进入完整版后再解锁本章。"},
gin.H{"id": "seed-global-sp-auth-title", "pageName": "全局App 多页)", "pagePath": "/app/global", "scope": "singlePage", "key": "globalSinglePageAuthTitle", "behavior": "单页模式 · 拦截登录/支付前弹窗标题app.ensureFullAppForAuth", "content": "请打开完整小程序"},
gin.H{"id": "seed-global-sp-auth-body", "pageName": "全局App 多页)", "pagePath": "/app/global", "scope": "singlePage", "key": "globalSinglePageAuthBody", "behavior": "单页模式 · 拦截登录/支付前弹窗正文", "content": "当前是朋友圈预览,无法在这里登录或付款。请先点击屏幕底部「前往小程序」,进入完整版后再解锁本章。"},
gin.H{"id": "seed-global-avatar-title", "pageName": "全局App 多页)", "pagePath": "/app/global", "scope": "fullApp", "key": "globalAvatarGuideTitle", "behavior": "非 VIP · 每日头像昵称引导弹窗标题app.checkAvatarNicknameAndGuide", "content": "设置头像与昵称"},
gin.H{"id": "seed-global-avatar-body", "pageName": "全局App 多页)", "pagePath": "/app/global", "scope": "fullApp", "key": "globalAvatarGuideBody", "behavior": "非 VIP · 每日头像昵称引导弹窗正文", "content": "头像与昵称会出现在名片与匹配卡片上,方便伙伴认出你。"},
gin.H{"id": "seed-global-vip-profile-title", "pageName": "全局App 多页)", "pagePath": "/app/global", "scope": "fullApp", "key": "globalVipProfileHintTitle", "behavior": "VIP · 补全头像昵称弹窗标题checkVipContactRequiredAndGuide", "content": "补全对外展示信息"},
gin.H{"id": "seed-global-vip-profile-body", "pageName": "全局App 多页)", "pagePath": "/app/global", "scope": "fullApp", "key": "globalVipProfileHintBody", "behavior": "VIP · 补全头像昵称弹窗正文", "content": "VIP 名片与派对场景会展示头像与昵称,补全后对方更容易认出你。"},
gin.H{"id": "seed-global-vip-phone-title", "pageName": "全局App 多页)", "pagePath": "/app/global", "scope": "fullApp", "key": "globalVipPhoneTitle", "behavior": "VIP · 缺手机号弹窗标题", "content": "补全手机号"},
gin.H{"id": "seed-global-vip-phone-body", "pageName": "全局App 多页)", "pagePath": "/app/global", "scope": "fullApp", "key": "globalVipPhoneBody", "behavior": "VIP · 缺手机号弹窗正文", "content": "手机号用于找伙伴、提现验证与重要通知,仅本人可见。"},
gin.H{"id": "seed-global-vip-wx-title", "pageName": "全局App 多页)", "pagePath": "/app/global", "scope": "fullApp", "key": "globalVipWechatOptionalTitle", "behavior": "VIP · 可选补微信号弹窗标题", "content": "补全微信号(可选)"},
gin.H{"id": "seed-global-vip-wx-body", "pageName": "全局App 多页)", "pagePath": "/app/global", "scope": "fullApp", "key": "globalVipWechatOptionalBody", "behavior": "VIP · 可选补微信号弹窗正文", "content": "填写微信号后,对方在允许的场景下能更快加到你;不填也可继续使用。"},
gin.H{"id": "seed-global-update-title", "pageName": "全局App 多页)", "pagePath": "/app/global", "scope": "fullApp", "key": "globalAppUpdateTitle", "behavior": "小程序热更新就绪弹窗标题checkUpdate", "content": "更新提示"},
gin.H{"id": "seed-global-update-body", "pageName": "全局App 多页)", "pagePath": "/app/global", "scope": "fullApp", "key": "globalAppUpdateBody", "behavior": "小程序热更新就绪弹窗正文", "content": "新版本已准备好,重启后即可使用"},
gin.H{"id": "seed-read-moments-title", "pageName": "文章详情 / 阅读", "pagePath": "/pages/read/read", "scope": "fullApp", "key": "readMomentsShareGuideTitle", "behavior": "阅读页 · 复制发圈文案后引导弹窗标题shareToMoments", "content": "分享到朋友圈"},
gin.H{"id": "seed-read-moments-body", "pageName": "文章详情 / 阅读", "pagePath": "/pages/read/read", "scope": "fullApp", "key": "readMomentsShareGuideBody", "behavior": "阅读页 · 复制发圈文案后引导弹窗正文", "content": "已复制发圈文案(非分享给好友)。\n\n请点击右上角「···」→「分享到朋友圈」粘贴发布。"},
gin.H{"id": "seed-read-sp-title", "pageName": "文章详情 / 阅读", "pagePath": "/pages/read/read", "scope": "singlePage", "key": "singlePageTitle", "behavior": "朋友圈单页 · 付费区标题", "content": "解锁完整内容"},
gin.H{"id": "seed-read-sp-hint", "pageName": "文章详情 / 阅读", "pagePath": "/pages/read/read", "scope": "singlePage", "key": "singlePagePaywallHint", "behavior": "朋友圈单页 · 付费墙说明(旧)", "content": "当前为朋友圈单页预览,无法在此登录或付款。请点击底部「前往小程序」进入完整版后再解锁本章。"},
gin.H{"id": "seed-read-sp-sub", "pageName": "文章详情 / 阅读", "pagePath": "/pages/read/read", "scope": "singlePage", "key": "singlePagePaywallSub", "behavior": "朋友圈单页 · 付费墙第二段小字", "content": "预览页不能直接付款,务必先点底栏「前往小程序」。"},
gin.H{"id": "seed-read-sp-se1", "pageName": "文章详情 / 阅读", "pagePath": "/pages/read/read", "scope": "singlePage", "key": "singlePageShareEarn1", "behavior": "朋友圈单页 · 分销说明第一行", "content": "好友经你分享购买,你可获得约 90% 收益"},
gin.H{"id": "seed-read-sp-se2", "pageName": "文章详情 / 阅读", "pagePath": "/pages/read/read", "scope": "singlePage", "key": "singlePageShareEarn2", "behavior": "朋友圈单页 · 分销说明第二行", "content": "转发给需要的人,一起学习还能赚佣金"},
},
}
}

View File

@@ -22,7 +22,7 @@ type Chapter struct {
EditionStandard *bool `gorm:"column:edition_standard" json:"editionStandard,omitempty"` // 是否属于普通版
EditionPremium *bool `gorm:"column:edition_premium" json:"editionPremium,omitempty"` // 是否属于增值版
HotScore float64 `gorm:"column:hot_score;type:decimal(10,2);default:0" json:"hotScore"` // 热度分(加权计算),用于排名算法
PreviewPercent *int `gorm:"column:preview_percent" json:"previewPercent,omitempty"` // 章节私有试读%小程序读章节接口在 data 内返回合并后的有效试读%
PreviewPercent *int `gorm:"column:preview_percent" json:"previewPercent,omitempty"` // 章节私有试读%;读章节接口在 data 内返回合并后的有效试读%
CreatedAt time.Time `gorm:"column:created_at" json:"createdAt"`
UpdatedAt time.Time `gorm:"column:updated_at" json:"updatedAt"`
}

View File

@@ -156,3 +156,19 @@
{"level":"debug","timestamp":"2026-03-25T16:58:45+08:00","caller":"kernel/baseClient.go:459","content":"------------------response content:HTTP/1.1 200 OK\r\nContent-Length: 250\r\nCache-Control: no-cache, must-revalidate\r\nConnection: keep-alive\r\nContent-Language: zh-CN\r\nContent-Type: application/json; charset=utf-8\r\nDate: Wed, 25 Mar 2026 08:58:46 GMT\r\nKeep-Alive: timeout=8\r\nRequest-Id: 08C6C78ECE0610A50418F1C1EDF501208ADE0C28FAF901-0\r\nServer: nginx\r\nWechatpay-Nonce: b6c65db344d7ce4001d5728590e6088e\r\nWechatpay-Serial: 5F2543BF58239A4EB68FA4433DF1438A88B34B16\r\nWechatpay-Signature: TOyUE+f7QLbHH6FMi+1hGwFor1iRwHXwMYg4PL1eSrCamvhcJ8ivN75ZX3pzCiKPZoxfB98J4XtNJu5xvGBymxcgOMjodIKzzazXh0Q/BG1CXTbxk2DOvDkmL0GRxQyYlV9k6Z+EGBgscDGvlyYMsRtTzMRKHesjkV/omxrFJAvuuLTR50eGOeMeY5uTc3MKLtL2yQCHcJOV+Kb2hIL0TeIHMg6CrWkcZLQW/Pcdy2l25X6lJO9JRMVDfLr4ZNqaGHBmYC2F9kNFz8rCtXzfLLRTfdnYJy4lht7xgiSDUIwwzoMlLjYXQdokM0fdnODb2+jqQ2kaASbE7+xZTQkHbg==\r\nWechatpay-Signature-Type: WECHATPAY2-SHA256-RSA2048\r\nWechatpay-Timestamp: 1774429126\r\nX-Content-Type-Options: nosniff\r\n\r\n{\"amount\":{\"payer_currency\":\"CNY\",\"total\":3000},\"appid\":\"wxb8bbb2b10dec74aa\",\"mchid\":\"1318592501\",\"out_trade_no\":\"MP20260325163002440000\",\"promotion_detail\":[],\"scene_info\":{\"device_id\":\"\"},\"trade_state\":\"NOTPAY\",\"trade_state_desc\":\"订单未支付\"}"}
{"level":"debug","timestamp":"2026-03-25T17:03:45+08:00","caller":"kernel/baseClient.go:457","content":"GET https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/MP20260325163002440000?mchid=1318592501 request header: { Accept:*/*Content-Type:application/jsonAuthorization:WECHATPAY2-SHA256-RSA2048 mchid=\"1318592501\",nonce_str=\"fkyxgTAYA1XV1dxAYQtmZAFjGOOBJbQM\",timestamp=\"1774429425\",serial_no=\"4A1DB62CD5C9BE0B6FC51C30621D6F99686E75C5\",signature=\"1Yh14nDxhE/TfoVcXl9cCiUMCVZc+yosI25M6aEYBfFtzEV7TbjgQnUsmEE9xZfi8QOF+gciUYhrtRdL8a1all7AN1pdSPVDvcEhIi5zl5AfCYOm9vZaBSqDqmbe/7Ie5AibauT9wE8E2+6u/K3JJpvXZn90PvKAR0lwCjQ30Pyufs8t119Mq+4FnoJnttvp1jmyRBZpuu718H3Bxz9EdBhP7W/j9Iy86FDgacalypWFBbsOPD0tt0idzoVadLPe+aBL2d5DixX2HCwYTW6I/ohSIRWUbPMoKEPiZDflE9wB5ppkUCW1aA+vFiUYMOLf0TRnVccjFrwSHHSl9QOwBA==\"} request body:"}
{"level":"debug","timestamp":"2026-03-25T17:03:45+08:00","caller":"kernel/baseClient.go:459","content":"------------------response content:HTTP/1.1 200 OK\r\nContent-Length: 250\r\nCache-Control: no-cache, must-revalidate\r\nConnection: keep-alive\r\nContent-Language: zh-CN\r\nContent-Type: application/json; charset=utf-8\r\nDate: Wed, 25 Mar 2026 09:03:46 GMT\r\nKeep-Alive: timeout=8\r\nRequest-Id: 08F2C98ECE0610E10318C9D68C5820EAC80828AD9806-0\r\nServer: nginx\r\nWechatpay-Nonce: d2f2703df0c26e8eb2dc13fde1f46216\r\nWechatpay-Serial: 5F2543BF58239A4EB68FA4433DF1438A88B34B16\r\nWechatpay-Signature: EuCnXw6ZceRJZ+1C2UGy1q0TjwrM9UEmlBmYf4aTq4KiNAMddLZko2vkBIgYDOTxavHlrbYcqtgCCjDRb7wZ41ZVzdaWXciAeBdazsNbPiHIv76ue/rNrJOlBgJzaRz9V0iglXUP6LiZMheU9iZCiAAScDQ5vtkFP2SsITTSoGKfR8OpO4qLVIBXEEq9FD3hemiVPomGFS77EnmIVBOR+tTbC2jZP05WC7aPyLhmsdXrXqpGFNWRArayETOH3yd5YPwi/8V30FL3r2WyQQPCAvjktY2reFSYGoq4N+U/y+LBEcb564zGNwpIweUoKJJg/YYsj0RhIUlsnZvHMU00LA==\r\nWechatpay-Signature-Type: WECHATPAY2-SHA256-RSA2048\r\nWechatpay-Timestamp: 1774429426\r\nX-Content-Type-Options: nosniff\r\n\r\n{\"amount\":{\"payer_currency\":\"CNY\",\"total\":3000},\"appid\":\"wxb8bbb2b10dec74aa\",\"mchid\":\"1318592501\",\"out_trade_no\":\"MP20260325163002440000\",\"promotion_detail\":[],\"scene_info\":{\"device_id\":\"\"},\"trade_state\":\"NOTPAY\",\"trade_state_desc\":\"订单未支付\"}"}
{"level":"debug","timestamp":"2026-03-27T17:53:18+08:00","caller":"kernel/baseClient.go:457","content":"POST https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi request header: { Content-Type:application/jsonAuthorization:WECHATPAY2-SHA256-RSA2048 mchid=\"1318592501\",nonce_str=\"khwOGVSRc6IY3I2txzfR24XgURw2UaQY\",timestamp=\"1774605197\",serial_no=\"4A1DB62CD5C9BE0B6FC51C30621D6F99686E75C5\",signature=\"EyTR8iUguW9k6Oj5/3dmFe6cBisBfBzUGm3MExNWqcjGeWPpnWdOtREyV9thzcctZSPmortGUZ1KFs153sNA50yYgeg6gzGqXG+BsOLhpaqkk8d2+B9/HeK58haFQiWVSE78yYgbmrnfq/y5suOmbiVr1lzVUi58WErhQW9Mi1V5m3adq0453jE4iQt0kfjWJ1TwnZuV/6prsaIe1dRNwol86nRpNKjx7DA+GJvRoiXGQedAESBqBI0qROiui9mvYc8ePcHWhCYGZStFNh/bKIw4CTA7AattywhLK/YEeIXjQzf7XBiln+slvf9xsPL7NZiUe3CcghkM1/KoWGfITg==\"Accept:*/*} request body:"}
{"level":"debug","timestamp":"2026-03-27T17:53:18+08:00","caller":"kernel/baseClient.go:459","content":"------------------response content:HTTP/1.1 200 OK\r\nContent-Length: 52\r\nCache-Control: no-cache, must-revalidate\r\nConnection: keep-alive\r\nContent-Language: zh-CN\r\nContent-Type: application/json; charset=utf-8\r\nDate: Fri, 27 Mar 2026 09:53:19 GMT\r\nKeep-Alive: timeout=8\r\nRequest-Id: 088FA799CE06101718A294F5AF0120D4A81328A2A402-0\r\nServer: nginx\r\nWechatpay-Nonce: 30e26564c9e64ae7053291460d390147\r\nWechatpay-Serial: 5F2543BF58239A4EB68FA4433DF1438A88B34B16\r\nWechatpay-Signature: e5YPj8t8PJHSisZu/1GCgCreltpcq7+jQq+YACIe+AcuRFRb6ilVkVBynlAshC4HULFqgsQ/oo/2PV1R/vxjK8MARCruKCRJQ9wuRdQ0tcNkqGgUrQ6/n3Hqlq5npr+MeYg6RnH+T2e0s0d6I1v0IKewLu15Rf40Si/Woby4o3awddPXyoeekvRLEm6On2+ROj5FjcBZGa+qTvQPvYq7guMsVpDT7MV4RCKYWkimk+kXr8FoiLjTqald3rDKFmnXtbzTB8FYLu3ahHPx7SmkS2ib++hOzNhYhun6rGd4CIFCB6U8P3xpUeTx3fC+CEEeJphRGfE45md3TJeCtUJBrg==\r\nWechatpay-Signature-Type: WECHATPAY2-SHA256-RSA2048\r\nWechatpay-Timestamp: 1774605199\r\nX-Content-Type-Options: nosniff\r\n\r\n{\"prepay_id\":\"wx271753192500734780d8676d9a30b00000\"}"}
{"level":"debug","timestamp":"2026-03-27T17:58:13+08:00","caller":"kernel/baseClient.go:457","content":"GET https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/MP20260327175317081300?mchid=1318592501 request header: { Content-Type:application/jsonAuthorization:WECHATPAY2-SHA256-RSA2048 mchid=\"1318592501\",nonce_str=\"fEKGFLD3MUzGeHp7uQ9RVodNWxboXKd5\",timestamp=\"1774605493\",serial_no=\"4A1DB62CD5C9BE0B6FC51C30621D6F99686E75C5\",signature=\"e6pnoeeW2d5ZV15W4ypKL2PEeXcxDhLfpbhtb26InmkDBAJxZor+KbeQ0bBXGGIYC6q+9Z0oH8IZb1CxGjIGiv1hCe7UXZ2To4NsDMSNjhIqvyrCXdGlnxTjPpTMiCmUvVGiZHx8Vgtxl1/3AB9FjmpcIwpmqzEJnfYsWGg7GCTE7OdsG94tpwZBX/6EbFCfE8Q4KRHHn9xp6+OEsDYI3pX84xHJEdgxHoC27xuMWOQepOwUlAl1KbLKLYy4YrSs810coRTWiXpfhhkB+pTjv6h8TzXHi+upycquaijN+xqCPBTnk9Rt00Ui015sI9U5EM/+S/O1EqUhDrEsZYtdJA==\"Accept:*/*} request body:"}
{"level":"debug","timestamp":"2026-03-27T17:58:13+08:00","caller":"kernel/baseClient.go:459","content":"------------------response content:HTTP/1.1 200 OK\r\nContent-Length: 249\r\nCache-Control: no-cache, must-revalidate\r\nConnection: keep-alive\r\nContent-Language: zh-CN\r\nContent-Type: application/json; charset=utf-8\r\nDate: Fri, 27 Mar 2026 09:58:14 GMT\r\nKeep-Alive: timeout=8\r\nRequest-Id: 08B6A999CE0610A102188FAAC05520BE9B0A28EAC005-0\r\nServer: nginx\r\nWechatpay-Nonce: 0d905ffd8c7211f20642fd9b30cc2079\r\nWechatpay-Serial: 5F2543BF58239A4EB68FA4433DF1438A88B34B16\r\nWechatpay-Signature: VxT7fbg3yfmermArSjEWM8xvqx1dXyChnk/TW0wMLq3t+xdkIWymqS0yqPt+xFOIx1+SeNeDG0uN+nZEcw3NKw+N3Q5cDxwoHrWJKgO+lZ7e5hJM+eJXzhsXRzaZ1QO43hhtfZ3CMPALt+U3MNLsVEK2yt1bhelsRl8wzMo0niVn96ThL3ruvgnkZnNZG0WhWo6I/Lv72YJh/y+mQNtzpISdAKWOufTDT6297NQMM6mllVzCzxpSdQkoXGVr8npbXN9TrmnAHFGPQO/EioKjoZ3uXZMuiLYPStqIFeZWee7o6SFmSfTWka3G5aiWel8SvPrzGdlFFc0CX1SPkneQcA==\r\nWechatpay-Signature-Type: WECHATPAY2-SHA256-RSA2048\r\nWechatpay-Timestamp: 1774605494\r\nX-Content-Type-Options: nosniff\r\n\r\n{\"amount\":{\"payer_currency\":\"CNY\",\"total\":100},\"appid\":\"wxb8bbb2b10dec74aa\",\"mchid\":\"1318592501\",\"out_trade_no\":\"MP20260327175317081300\",\"promotion_detail\":[],\"scene_info\":{\"device_id\":\"\"},\"trade_state\":\"NOTPAY\",\"trade_state_desc\":\"订单未支付\"}"}
{"level":"debug","timestamp":"2026-03-27T18:03:13+08:00","caller":"kernel/baseClient.go:457","content":"GET https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/MP20260327175317081300?mchid=1318592501 request header: { Accept:*/*Content-Type:application/jsonAuthorization:WECHATPAY2-SHA256-RSA2048 mchid=\"1318592501\",nonce_str=\"8LsyEw2MjKa2IlhOOd2lfQAE3ogqWM3t\",timestamp=\"1774605793\",serial_no=\"4A1DB62CD5C9BE0B6FC51C30621D6F99686E75C5\",signature=\"UNGcqqnQI2k35n5w96Clxsp7p7chBA7AQB31uV9y9OCYID0IeqZmTfV+Qiq3Hj1C2BBB9ZF0xLvRc5aP/klfhMQODoTaukAG4LqGOy5lHfmtX7tpccBiwAHmzzPwpCiKiJ5jl5dpfKftrFff4HernE6yWEF9giGr0emiWjiDbTaRQ9vSjlVJFDPwEeQ5VE2azB3mK/71HKumb99NZJFWAbMtXgH0YM5Ycdhffm9alN9M00Mnqv9vGisPykL44Ol/ic5tKr2NEh1QEghzjNGs3UuvnLhk9pIsjtjvddKNvoZh0gRPYP49j19KLUoyPRvBjdPTTlJ4frqe2nlSs26b3A==\"} request body:"}
{"level":"debug","timestamp":"2026-03-27T18:03:13+08:00","caller":"kernel/baseClient.go:459","content":"------------------response content:HTTP/1.1 200 OK\r\nContent-Length: 249\r\nCache-Control: no-cache, must-revalidate\r\nConnection: keep-alive\r\nContent-Language: zh-CN\r\nContent-Type: application/json; charset=utf-8\r\nDate: Fri, 27 Mar 2026 10:03:14 GMT\r\nKeep-Alive: timeout=8\r\nRequest-Id: 08E2AB99CE0610840218C381ECAE01209C9B3028ABA105-0\r\nServer: nginx\r\nWechatpay-Nonce: 50f507b7265305ae21e37f767d5c9c2d\r\nWechatpay-Serial: 5F2543BF58239A4EB68FA4433DF1438A88B34B16\r\nWechatpay-Signature: oGPKUra0K/ZZmsnZ32XIJTHT5E8m6bvvud2gIbXQX9aoA9Zftca0ZWUWo5vh95AgYmzZyg+uUbXXuj2lO/Wl7MFTqUy+Yi5+xQPKwTGCpMZUozjM8DslHcSIziV3OzFWOKmsK7qpg7CqZVAQMkqLwlWP4IGQI6uTvJBpAGdev0zQmFKRsUbjWl3LZLpAfH7wVh0k/jqw24stV0JBiDw6Vaf3ZDtDiRINMcegoxGEg7Mi8yQCwQnDemLZwIlCW9IvAwhKeOVuaxgl+Of3qSDx1I4E+B0E91P8CWi1d8PmLDdt1R7h+R53+sLI7ps0iY/62YEiA/suy/bkyCMkGQ0wWA==\r\nWechatpay-Signature-Type: WECHATPAY2-SHA256-RSA2048\r\nWechatpay-Timestamp: 1774605794\r\nX-Content-Type-Options: nosniff\r\n\r\n{\"amount\":{\"payer_currency\":\"CNY\",\"total\":100},\"appid\":\"wxb8bbb2b10dec74aa\",\"mchid\":\"1318592501\",\"out_trade_no\":\"MP20260327175317081300\",\"promotion_detail\":[],\"scene_info\":{\"device_id\":\"\"},\"trade_state\":\"NOTPAY\",\"trade_state_desc\":\"订单未支付\"}"}
{"level":"debug","timestamp":"2026-03-27T18:08:13+08:00","caller":"kernel/baseClient.go:457","content":"GET https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/MP20260327175317081300?mchid=1318592501 request header: { Content-Type:application/jsonAuthorization:WECHATPAY2-SHA256-RSA2048 mchid=\"1318592501\",nonce_str=\"9EcGK3VOmuT0HFBKhyziePRUxAjDcjqk\",timestamp=\"1774606093\",serial_no=\"4A1DB62CD5C9BE0B6FC51C30621D6F99686E75C5\",signature=\"2upeZ9MVq+82VNine2RspaoM9J0mDmYFCdR2OBYqwInE3kF+xysjBG/Fh1IbP/i8WPrJMEzf4ff1dRdh2YqMwSFYC+UAlhkhaeakmSqOhEhPoQxjmKr3pE8eXU/SUAbNNFbiePl07KBseM2FJztUbHWJ4kKu26ZytkLiqJrX7kXoP4y1ApVDh3LPaQErZ86v+l0u1Hj2XNpIBcKHwnI8mIN+wYjGx6M21iPKE1Sv0tmTKmbsHyQPU0wqj1oytWKvN1eKmUgt9iOoS+H/05VVCjDEn+NpShh8StA2plvgsopGcK+IeZNSRbKiQ6FViXTmcO+bBO8qV2BC7xdVuf9Pcw==\"Accept:*/*} request body:"}
{"level":"debug","timestamp":"2026-03-27T18:08:13+08:00","caller":"kernel/baseClient.go:459","content":"------------------response content:HTTP/1.1 200 OK\r\nContent-Length: 249\r\nCache-Control: no-cache, must-revalidate\r\nConnection: keep-alive\r\nContent-Language: zh-CN\r\nContent-Type: application/json; charset=utf-8\r\nDate: Fri, 27 Mar 2026 10:08:14 GMT\r\nKeep-Alive: timeout=8\r\nRequest-Id: 088EAE99CE06109002189796F5AF0120D0A50C28AC9602-0\r\nServer: nginx\r\nWechatpay-Nonce: ff5d3cb3d838fbc71755b0b8e49829ce\r\nWechatpay-Serial: 5F2543BF58239A4EB68FA4433DF1438A88B34B16\r\nWechatpay-Signature: onazDrXCznG0dVP8XRicRNIKV0beKhoQweNuPtkcpsyZhH92DNuiN9WDGQk42dGxxdPs95TzmmbfhVk+lYzTbUwQjK9ZGxUfGf3pCd9s3kNdFvC43/lNXrDM71iNvjW7dIQLEMLEKJusZkOC2qDIvvX72cXAMUQuOV9eIWzKQxYzyAHYuiZLWqFAGvLG5Y/bhn5m8Uz98GbbFlZtyeCIXB5SnyRp4xF6JSanL1ZOfB6M1cY3TqAb8L0HgzFJgA4yLOiqEYoYX4qWUv+Q5BOSukwPY+ENfraIu+xuLdKnkefS4CP1gYZ7hJEBmwbBeKzR34nGbBJjr8N7ED9RykVGUw==\r\nWechatpay-Signature-Type: WECHATPAY2-SHA256-RSA2048\r\nWechatpay-Timestamp: 1774606094\r\nX-Content-Type-Options: nosniff\r\n\r\n{\"amount\":{\"payer_currency\":\"CNY\",\"total\":100},\"appid\":\"wxb8bbb2b10dec74aa\",\"mchid\":\"1318592501\",\"out_trade_no\":\"MP20260327175317081300\",\"promotion_detail\":[],\"scene_info\":{\"device_id\":\"\"},\"trade_state\":\"NOTPAY\",\"trade_state_desc\":\"订单未支付\"}"}
{"level":"debug","timestamp":"2026-03-27T18:13:13+08:00","caller":"kernel/baseClient.go:457","content":"GET https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/MP20260327175317081300?mchid=1318592501 request header: { Content-Type:application/jsonAuthorization:WECHATPAY2-SHA256-RSA2048 mchid=\"1318592501\",nonce_str=\"90ZigRwaZVV6MaA3tkMGsXLG47oe1AxP\",timestamp=\"1774606393\",serial_no=\"4A1DB62CD5C9BE0B6FC51C30621D6F99686E75C5\",signature=\"JqmLLy+qPZBjaWiGze9g1FfG6w68UUye1Lwzg/uDRupEUV4UJpXeBSPZC1F+xDZGvJiueR0D1Dh/Pcn0R4B23zZKg3MwmQ6MmJrA4s6fyCFMkaK/Z0Fa980PgP++Ln0axs2Dycc0kwtNysF/9dN3P8wicGkcczR7hNz1VVROCuNG/G+p4ubEhqCCMDJ2zu0MpFvcgWAkVPfMWZC21gNFlxM1UbxDUsPg7N4ncWMY0hP//Ilctu1uvo4dykIh5ufRK5d0hiRrZRUmwWJjaU0svUf2tO7JXpud+HhYH6TvXtdBBwUeqqAgpTYlgKVXzSSLxAFJ67ASFbysX7kqFBUgog==\"Accept:*/*} request body:"}
{"level":"debug","timestamp":"2026-03-27T18:13:13+08:00","caller":"kernel/baseClient.go:459","content":"------------------response content:HTTP/1.1 200 OK\r\nContent-Length: 249\r\nCache-Control: no-cache, must-revalidate\r\nConnection: keep-alive\r\nContent-Language: zh-CN\r\nContent-Type: application/json; charset=utf-8\r\nDate: Fri, 27 Mar 2026 10:13:14 GMT\r\nKeep-Alive: timeout=8\r\nRequest-Id: 08BAB099CE0610F40118ACB3C0552094E62828C2D304-0\r\nServer: nginx\r\nWechatpay-Nonce: 99bf8a61109d3423ef4f3214f020fdb8\r\nWechatpay-Serial: 5F2543BF58239A4EB68FA4433DF1438A88B34B16\r\nWechatpay-Signature: yRzB266IemII44A73T0t00CoQZ0YuXMjjubuL1ca7iaEXHUlFelfR0V/1kOk3rUhwVqixVkRqNJ9XP0JdwXctkjErr8H5i66jbSnZ43tBwfu05dnQ3vD6PsMsj51ka4NriBF0v9UmUv2CzdGA71GO+IdGLobAOyIi3diiysezZyJgFgbSPe7QeCsA/18aMQl6nu6xfDctj9pVUtmlh5TSZO83PcWdUBOZMJ/MlOHj2zrrBwOBYwIgrPc3u4PFMIaTsQGsmcZUgkLjbfNT2vnkYyOlTO0NxROtGj11i3T79eqFHRWFF51IrjTJC0Way2OLmYQ55BDWysGzwBRvI6g3g==\r\nWechatpay-Signature-Type: WECHATPAY2-SHA256-RSA2048\r\nWechatpay-Timestamp: 1774606394\r\nX-Content-Type-Options: nosniff\r\n\r\n{\"amount\":{\"payer_currency\":\"CNY\",\"total\":100},\"appid\":\"wxb8bbb2b10dec74aa\",\"mchid\":\"1318592501\",\"out_trade_no\":\"MP20260327175317081300\",\"promotion_detail\":[],\"scene_info\":{\"device_id\":\"\"},\"trade_state\":\"NOTPAY\",\"trade_state_desc\":\"订单未支付\"}"}
{"level":"debug","timestamp":"2026-03-27T18:18:13+08:00","caller":"kernel/baseClient.go:457","content":"GET https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/MP20260327175317081300?mchid=1318592501 request header: { Content-Type:application/jsonAuthorization:WECHATPAY2-SHA256-RSA2048 mchid=\"1318592501\",nonce_str=\"WL0voSr6DYnSAThfXvtxq0loPlCdzVjN\",timestamp=\"1774606693\",serial_no=\"4A1DB62CD5C9BE0B6FC51C30621D6F99686E75C5\",signature=\"Tw5irBn409281Ht9I4Lo+yJWwF6sL6vtt6mfbeBhnOO5FmrUIhi3IB2RCYFLlcXwBfToVafHlONRvYRas+L4zVC01iQbTxpqufrMgG/REDtqHC6i64kXOes/75xfwRVn6WSLm7odLb5AONNI68lk8OZt4URJuUR5aENTiglvt7qhglRiGBP8pay5tZL7PuspBNF/XXuVx9I/sx/JuGYR8tinqG2+UA3ctVLI6BDrVtJKBNOy0aWUJXbY82bu3FZ+FZnuQVirBBICBTGrq0eNWnPnZTeaoyIE7A/EsNs2bk2QByLWM2LxdyOeEJUSAn+ThZJ5071Fmcu/it7VftP+Mg==\"Accept:*/*} request body:"}
{"level":"debug","timestamp":"2026-03-27T18:18:13+08:00","caller":"kernel/baseClient.go:459","content":"------------------response content:HTTP/1.1 200 OK\r\nContent-Length: 249\r\nCache-Control: no-cache, must-revalidate\r\nConnection: keep-alive\r\nContent-Language: zh-CN\r\nContent-Type: application/json; charset=utf-8\r\nDate: Fri, 27 Mar 2026 10:18:14 GMT\r\nKeep-Alive: timeout=8\r\nRequest-Id: 08E6B299CE0610830218BBCCC05520F0870F28B2A704-0\r\nServer: nginx\r\nWechatpay-Nonce: a61f5a0008a7dbe7486801329c29673d\r\nWechatpay-Serial: 5F2543BF58239A4EB68FA4433DF1438A88B34B16\r\nWechatpay-Signature: J5RuIHybJBQr7CgIZBI5eNZjvbweMgrht0xh/P3iMq0Bh9MHysQbjPQ/dhCu0sqphUq3wwdK+f7l4SOtEMt/SoHVSDX1GNkWbsAH7Jrd3roJT5EfCkElNr48U72DA7jDgfOrTd3Ewvd43OXY7A/tWT2CV2KGSqpSB3XRklNeIcL2dL7G8348DyQ4k4N6siZdmYU3Ynn2AqUo3yh4/iesoKDp1DJpr4Lf8xvyMzcynlIIARB6FfH1YIvWpkzsJaJNuFCc4xI2jPJeBrAw2BnSP7D8GGJO3AozwiSlcPnscdTRRybqKxTN1KdDTVBsReL033tRFy2XIAAsxTgCpsjB2Q==\r\nWechatpay-Signature-Type: WECHATPAY2-SHA256-RSA2048\r\nWechatpay-Timestamp: 1774606694\r\nX-Content-Type-Options: nosniff\r\n\r\n{\"amount\":{\"payer_currency\":\"CNY\",\"total\":100},\"appid\":\"wxb8bbb2b10dec74aa\",\"mchid\":\"1318592501\",\"out_trade_no\":\"MP20260327175317081300\",\"promotion_detail\":[],\"scene_info\":{\"device_id\":\"\"},\"trade_state\":\"NOTPAY\",\"trade_state_desc\":\"订单未支付\"}"}
{"level":"debug","timestamp":"2026-03-27T18:23:13+08:00","caller":"kernel/baseClient.go:457","content":"GET https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/MP20260327175317081300?mchid=1318592501 request header: { Content-Type:application/jsonAuthorization:WECHATPAY2-SHA256-RSA2048 mchid=\"1318592501\",nonce_str=\"atU0yxrW58MizLaKTL4Ry5KlNRPTdH1X\",timestamp=\"1774606993\",serial_no=\"4A1DB62CD5C9BE0B6FC51C30621D6F99686E75C5\",signature=\"BL+cusf1OA6BGmgPi6yVQygxCHnW85J2jiTijjZP3pvwsVkgtN1MMU1oV5/HJekv05ETExZIRUP0Si2qa2PugkOOk9l9CGbSZiT1yHQSrLlorp0vOBaHZQP1rqjDDIbg9YW+RglEyGsNN4G++6zrH2cv58YScLnS/Rac/WKqkoTKyY8xUptN4Vh9F5ZKJNUU8tStLj1G7oFu7ByxLq51+DLJo8Q10nDV7VfHAKw3C1Tb3Ztp0zywiVQ4QJvzw4Lncd3rITPRmK63NCCP40Q94vTKHrMv4EiexQFoMN1OHOkuOdvbp+ekO3e7sxvmoRN3IP2uLiAGvOLIMMx3AbXRGA==\"Accept:*/*} request body:"}
{"level":"debug","timestamp":"2026-03-27T18:23:13+08:00","caller":"kernel/baseClient.go:459","content":"------------------response content:HTTP/1.1 200 OK\r\nContent-Length: 249\r\nCache-Control: no-cache, must-revalidate\r\nConnection: keep-alive\r\nContent-Language: zh-CN\r\nContent-Type: application/json; charset=utf-8\r\nDate: Fri, 27 Mar 2026 10:23:14 GMT\r\nKeep-Alive: timeout=8\r\nRequest-Id: 0892B599CE0610A60218D2CEC05520A8E02128EFD204-0\r\nServer: nginx\r\nWechatpay-Nonce: 6c9d80dc4bd6f0ec023fee64ecbaf517\r\nWechatpay-Serial: 5F2543BF58239A4EB68FA4433DF1438A88B34B16\r\nWechatpay-Signature: bNytAH4NrLgb8avYDtWnXqe73hze0ZfGlqzfEI0+alBAt3cErrOl/SJeochHiekplEuuqqvf549BMjRwp1xhSU8BmPZMNO5dDaGIVNCOD1eLKIMbFaEQsiT2EXo7Pueq6pZda13zMe5wPGCqNmIROs//nDRXk/TgLT79RXOKYmh7kDSoX/SGhjCymrmwKkaytcErpn8miWqpbwl+0ZKFaoeJDb9DO7sbj7IeTLJxK1QAQ8rg5LnnKRRWzipnEslSAO7quVZNSRV6iXGvgXac83k6B5I5NGCDCsg7StZI9v7JnVTOU9ggrwROWt6way9JmK1/BKbVK1pFpKw0c/zXEw==\r\nWechatpay-Signature-Type: WECHATPAY2-SHA256-RSA2048\r\nWechatpay-Timestamp: 1774606994\r\nX-Content-Type-Options: nosniff\r\n\r\n{\"amount\":{\"payer_currency\":\"CNY\",\"total\":100},\"appid\":\"wxb8bbb2b10dec74aa\",\"mchid\":\"1318592501\",\"out_trade_no\":\"MP20260327175317081300\",\"promotion_detail\":[],\"scene_info\":{\"device_id\":\"\"},\"trade_state\":\"NOTPAY\",\"trade_state_desc\":\"订单未支付\"}"}
{"level":"debug","timestamp":"2026-03-27T18:28:13+08:00","caller":"kernel/baseClient.go:457","content":"GET https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/MP20260327175317081300?mchid=1318592501 request header: { Content-Type:application/jsonAuthorization:WECHATPAY2-SHA256-RSA2048 mchid=\"1318592501\",nonce_str=\"t14tjFFt7TDBm6GRUgTOhT3qruhPSlWt\",timestamp=\"1774607293\",serial_no=\"4A1DB62CD5C9BE0B6FC51C30621D6F99686E75C5\",signature=\"gjyVaVX1Dl+NSsQf5rajxCZfKsrxlKIFbRooJI2NfzLioCYVy/vc21MuR+ImKcSQ1CCbeilpuTwo5vOjnq9p8pEZE+jK8PNg8oB+MsHfrkcZoQqKRK1Khvoj7LjElYWD3FtJy8l5slEY2ucwaQW2DiSuYBjazZG7cpprH4iwjBy3lUhX5xpoiK/5sdSBWcrdz/g5J1wPoeuzEonyWhEQH0NOWTJzhgP1Tw1/vRbjyeV0hAmfMjnKUm8zf94icCioSHi6UspXG2EvdWFQlBmirBJWs7sSFKDcFGhO8a3bvhX52CoPXL98uLZGVfj/HNJjgcnyqdUBc+vbB3+Kv52Piw==\"Accept:*/*} request body:"}
{"level":"debug","timestamp":"2026-03-27T18:28:13+08:00","caller":"kernel/baseClient.go:459","content":"------------------response content:HTTP/1.1 200 OK\r\nContent-Length: 249\r\nCache-Control: no-cache, must-revalidate\r\nConnection: keep-alive\r\nContent-Language: zh-CN\r\nContent-Type: application/json; charset=utf-8\r\nDate: Fri, 27 Mar 2026 10:28:14 GMT\r\nKeep-Alive: timeout=8\r\nRequest-Id: 08BEB799CE0610F30118C4A9C0552098860B2883D705-0\r\nServer: nginx\r\nWechatpay-Nonce: 19151c02244f70df955a28a0c795538a\r\nWechatpay-Serial: 5F2543BF58239A4EB68FA4433DF1438A88B34B16\r\nWechatpay-Signature: h970oEQru2q0k8GXAWL07TNFuV74qeQ1sX/4AE/xQP7bM0fsQGdf4XaHogF52Z6MQEBa/AHqmka9yhg0FZ5LINsj3s4J0EHIaOzxyhfaum83GjhIwtV0cadhmJG/y0xoUC/VfqpEKHXptlCgdBiTzEbrLML+r/izBYCGO0ufUr77HCh7O9VIYNLHeaDHmji2gNSfsD5ePQFSSksQZzouPMR21SORptdXAS0e5qN7SKS67/gMipJCtMUdkFTcEKyESBXzlKKA3NXiBg7tc9VO4Dit+xE9ruvdUJZ9VoGtVCoVDXBx994x+YYfnovIwVim8J804xySSn10FXio5tyb3g==\r\nWechatpay-Signature-Type: WECHATPAY2-SHA256-RSA2048\r\nWechatpay-Timestamp: 1774607294\r\nX-Content-Type-Options: nosniff\r\n\r\n{\"amount\":{\"payer_currency\":\"CNY\",\"total\":100},\"appid\":\"wxb8bbb2b10dec74aa\",\"mchid\":\"1318592501\",\"out_trade_no\":\"MP20260327175317081300\",\"promotion_detail\":[],\"scene_info\":{\"device_id\":\"\"},\"trade_state\":\"NOTPAY\",\"trade_state_desc\":\"订单未支付\"}"}