Files
soul-yongping/miniprogram/pages/read/read.js

208 lines
6.2 KiB
JavaScript

const app = getApp()
const FULL_BOOK_PRICE = 9.9
Page({
data: {
statusBarHeight: 44,
navBarHeight: 88,
id: '',
title: '',
partTitle: '',
chapterTitle: '',
content: '',
contentNodes: '',
contentType: 'text',
loading: true,
needPurchase: false,
canAccess: false,
error: '',
price: 1,
fullBookPrice: FULL_BOOK_PRICE,
totalSections: 62,
purchasedCount: 0,
showFullBookOption: false,
prevSection: null,
nextSection: null,
showShareModal: false,
shareCopied: false,
referralCode: '',
shareLink: ''
},
onLoad(options) {
const id = (options && options.id) ? decodeURIComponent(options.id) : ''
const statusBarHeight = app.globalData.statusBarHeight || 44
const navBarHeight = app.globalData.navBarHeight || (statusBarHeight + 44)
this.setData({
statusBarHeight,
navBarHeight,
id
})
this.syncUser()
if (id) {
this.loadAllSections().then(() => this.loadChapter(id))
} else {
this.setData({ loading: false, error: '缺少章节 id' })
}
},
syncUser() {
const purchasedSections = app.globalData.purchasedSections || []
const hasFullBook = !!app.globalData.hasFullBook
const total = this.data.totalSections || 62
const purchasedCount = hasFullBook ? total : purchasedSections.length
const user = app.globalData.userInfo || {}
this.setData({
purchasedCount,
showFullBookOption: purchasedSections.length >= 3,
referralCode: user.referralCode || ''
})
},
allSectionsList: [],
loadAllSections() {
return app.request('/api/book/all-chapters').then((res) => {
const list = (res && res.data) ? res.data : (res && res.chapters) ? res.chapters : []
const total = res.totalSections || res.total || list.length
const ids = list.map(s => s.id)
this.allSectionsList = ids
this.setData({ totalSections: total })
this.syncUser()
return list
}).catch(() => [])
},
getPrevNext(currentId) {
const list = this.allSectionsList
if (!list || !list.length) return { prev: null, next: null }
const i = list.indexOf(currentId)
return {
prev: i > 0 ? { id: list[i - 1], title: '' } : null,
next: i >= 0 && i < list.length - 1 ? { id: list[i + 1], title: '' } : null
}
},
loadChapter(id) {
this.setData({ loading: true, error: '' })
app.request('/api/book/chapter/' + encodeURIComponent(id))
.then((res) => {
if (!res || !res.success) {
this.setData({ loading: false, error: res && res.error ? res.error : '加载失败' })
return
}
const hasFullBook = !!app.globalData.hasFullBook
const purchasedSections = app.globalData.purchasedSections || []
const isPurchased = hasFullBook || purchasedSections.indexOf(res.id) >= 0
const canAccess = !!res.isFree || isPurchased
const raw = res.content || ''
const isHtml = typeof raw === 'string' && (raw.indexOf('<') >= 0 && raw.indexOf('>') >= 0)
const contentType = isHtml ? 'html' : 'text'
const contentNodes = isHtml ? raw : null
const content = isHtml ? '' : raw
const lines = content.split('\n').filter(l => l.trim())
const previewLineCount = Math.max(1, Math.ceil(lines.length * 0.2))
const previewContent = lines.slice(0, previewLineCount).join('\n')
const prevNext = this.getPrevNext(res.id)
this.syncUser()
this.setData({
title: res.title || res.sectionTitle || '',
partTitle: res.partTitle || '',
chapterTitle: res.chapterTitle || '',
content,
contentNodes,
contentType,
needPurchase: !!res.needPurchase && !canAccess,
canAccess,
loading: false,
error: '',
price: res.price != null ? res.price : 1,
previewContent,
prevSection: prevNext.prev,
nextSection: prevNext.next
})
})
.catch((err) => {
this.setData({
loading: false,
error: err && err.message ? err.message : '网络错误'
})
})
},
goBack() {
wx.navigateBack({ fail: () => wx.switchTab({ url: '/pages/index/index' }) })
},
goChapters() {
wx.switchTab({ url: '/pages/chapters/chapters' })
},
openShare() {
const link = this.getShareLink()
this.setData({ showShareModal: true, shareCopied: false, shareLink: link })
},
closeShare() {
this.setData({ showShareModal: false })
},
getShareLink() {
const baseUrl = app.globalData.baseUrl || 'https://soul.quwanzhi.com'
const ref = this.data.referralCode ? '?ref=' + this.data.referralCode : ''
return baseUrl + '/read/' + this.data.id + ref
},
copyLink() {
const link = this.getShareLink()
wx.setClipboardData({
data: link,
success: () => this.setData({ shareCopied: true })
})
},
copyWechatText() {
const link = this.getShareLink()
const text = '📚 推荐阅读《' + this.data.title + '》\n\n' + (this.data.content || '').slice(0, 100) + '...\n\n👉 点击阅读:' + link
wx.setClipboardData({
data: text,
success: () => wx.showToast({ title: '已复制,请粘贴到微信发送', icon: 'none' })
})
},
copyMomentText() {
const link = this.getShareLink()
const text = '📚 ' + this.data.title + '\n' + link
wx.setClipboardData({
data: text,
success: () => wx.showToast({ title: '朋友圈文案已复制', icon: 'none' })
})
},
goReferral() {
this.setData({ showShareModal: false })
wx.navigateTo({ url: '/pages/referral/referral' })
},
goPrev() {
const prev = this.data.prevSection
if (prev && prev.id) wx.navigateTo({ url: '/pages/read/read?id=' + encodeURIComponent(prev.id) })
},
goNext() {
const next = this.data.nextSection
if (next && next.id) wx.navigateTo({ url: '/pages/read/read?id=' + encodeURIComponent(next.id) })
},
purchaseSection() {
wx.showToast({ title: '请在小程序内完成支付', icon: 'none' })
wx.navigateTo({ url: '/pages/chapters/chapters' })
},
purchaseFullBook() {
wx.showToast({ title: '请在小程序内完成支付', icon: 'none' })
wx.navigateTo({ url: '/pages/chapters/chapters' })
}
})