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' }) } })