1
This commit is contained in:
@@ -136,6 +136,8 @@ Page({
|
||||
readingProgress: 0,
|
||||
/** 未解锁付费墙:合并 data.previewPercent(章节)与顶层 previewPercent(全局) */
|
||||
previewPercent: 20,
|
||||
/** 未解锁时:按 previewPercent 裁切可见高度(px)。0 表示未启用/待测量 */
|
||||
previewMaxHeightPx: 0,
|
||||
/** mpUi.readPage.beforeLoginHint:未登录付费墙上方说明文案 */
|
||||
readBeforeLoginHint: '',
|
||||
/** 朋友圈单页:标题与说明(mpUi.readPage.singlePageTitle / singlePagePaywallHint) */
|
||||
@@ -185,6 +187,53 @@ Page({
|
||||
momentsPaywallExpanded: false,
|
||||
},
|
||||
|
||||
_isLockedState(state) {
|
||||
return state === 'locked_not_login' || state === 'locked_not_purchased'
|
||||
},
|
||||
|
||||
/**
|
||||
* 未解锁时:先渲染完整正文,再测量其高度,按 previewPercent 计算可见高度并裁切。
|
||||
* 这样后端无需截断,避免 HTML/段落被截断导致的渲染失败。
|
||||
*/
|
||||
_updatePreviewClipHeight() {
|
||||
const state = this.data.accessState
|
||||
if (!this._isLockedState(state)) {
|
||||
if (this.data.previewMaxHeightPx !== 0) this.setData({ previewMaxHeightPx: 0 })
|
||||
return
|
||||
}
|
||||
|
||||
const percent = Number(this.data.previewPercent) || 20
|
||||
// 先关闭裁切,确保测到“完整高度”
|
||||
if (this.data.previewMaxHeightPx !== 0) {
|
||||
this.setData({ previewMaxHeightPx: 0 })
|
||||
}
|
||||
|
||||
const measure = () =>
|
||||
new Promise((resolve) => {
|
||||
wx.createSelectorQuery()
|
||||
.in(this)
|
||||
.select('#previewContentMeasure')
|
||||
.boundingClientRect((rect) => resolve(rect || null))
|
||||
.exec()
|
||||
})
|
||||
|
||||
const apply = async () => {
|
||||
// nextTick 让 setData 的 DOM 更新生效
|
||||
await new Promise((r) => (typeof wx.nextTick === 'function' ? wx.nextTick(r) : setTimeout(r, 0)))
|
||||
const rect = await measure()
|
||||
const fullH = rect && rect.height ? rect.height : 0
|
||||
if (!fullH || fullH < 20) return
|
||||
|
||||
const clipped = Math.max(120, Math.floor((fullH * Math.min(Math.max(percent, 1), 100)) / 100))
|
||||
// 只在仍处于锁定态时应用,避免切换状态后误裁切
|
||||
if (this._isLockedState(this.data.accessState)) {
|
||||
this.setData({ previewMaxHeightPx: clipped })
|
||||
}
|
||||
}
|
||||
|
||||
apply().catch(() => {})
|
||||
},
|
||||
|
||||
/**
|
||||
* 是否处于朋友圈等「单页预览」环境。
|
||||
* 兼容:部分机型/基础库首帧 getSystemInfoSync().mode 未就绪,需结合 launch/enter scene 1154、getWindowInfo。
|
||||
@@ -480,11 +529,12 @@ Page({
|
||||
}
|
||||
this.setData({ section })
|
||||
|
||||
// 已解锁用 data.content(完整内容),未解锁用 content(预览);先 determineAccessState 再 loadContent 保证顺序正确
|
||||
const displayContent = accessManager.canAccessFullContent(accessState) ? (res.data?.content ?? res.content) : res.content
|
||||
// 规则更新:小程序端始终使用“完整正文”渲染;未解锁时通过前端裁切可见比例实现预览
|
||||
// 兼容老返回:完整正文可能在 res.data.content,老链路只有 res.content
|
||||
const displayContent = (res.data?.content ?? res.content)
|
||||
if (res && displayContent) {
|
||||
const { lines, segments } = contentParser.parseContent(displayContent, parseCfg)
|
||||
// 预览内容由后端统一截取比例,这里展示全部预览内容
|
||||
// 预览比例由前端按高度裁切,这里渲染完整内容(避免后端截断导致渲染失败)
|
||||
const previewCount = lines.length
|
||||
const updates = {
|
||||
content: displayContent,
|
||||
@@ -496,7 +546,9 @@ Page({
|
||||
previewPercent: normalizePreviewPercent(res),
|
||||
}
|
||||
if (res.mid) updates.sectionMid = res.mid
|
||||
this.setData(updates)
|
||||
// 先关闭裁切,等 DOM 更新后再测量并按比例裁切
|
||||
this.setData({ ...updates, previewMaxHeightPx: 0 })
|
||||
this._updatePreviewClipHeight()
|
||||
// 写入本地缓存(存 displayContent,供离线/重试降级使用)
|
||||
try { wx.setStorageSync(cacheKey, { ...res, content: displayContent }) } catch (_) {}
|
||||
if (accessManager.canAccessFullContent(accessState)) {
|
||||
@@ -511,7 +563,7 @@ Page({
|
||||
if (cached && cached.content) {
|
||||
await app.getReadExtras()
|
||||
const { lines, segments } = contentParser.parseContent(cached.content, getContentParseConfig())
|
||||
// 预览内容由后端统一截取比例,这里展示全部预览内容
|
||||
// 预览比例由前端按高度裁切,这里渲染完整内容
|
||||
const previewCount = lines.length
|
||||
this.setData({
|
||||
content: cached.content,
|
||||
@@ -521,7 +573,9 @@ Page({
|
||||
partTitle: cached.partTitle || '',
|
||||
chapterTitle: cached.chapterTitle || '',
|
||||
previewPercent: normalizePreviewPercent(cached),
|
||||
previewMaxHeightPx: 0,
|
||||
})
|
||||
this._updatePreviewClipHeight()
|
||||
app.touchRecentSection(id)
|
||||
console.log('[Read] 从本地缓存加载成功')
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user