344 lines
7.2 KiB
JavaScript
344 lines
7.2 KiB
JavaScript
|
|
// pages/read/read.js
|
|||
|
|
const app = getApp()
|
|||
|
|
const paymentUtil = require('../../utils/payment')
|
|||
|
|
|
|||
|
|
Page({
|
|||
|
|
data: {
|
|||
|
|
chapterId: '',
|
|||
|
|
chapterInfo: {},
|
|||
|
|
contentHtml: '',
|
|||
|
|
loading: true,
|
|||
|
|
hasPrev: false,
|
|||
|
|
hasNext: false,
|
|||
|
|
isBookmarked: false,
|
|||
|
|
showCatalog: false,
|
|||
|
|
allChapters: []
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
onLoad(options) {
|
|||
|
|
const chapterId = options.id
|
|||
|
|
if (chapterId) {
|
|||
|
|
this.setData({ chapterId })
|
|||
|
|
this.loadChapter(chapterId)
|
|||
|
|
this.loadAllChapters()
|
|||
|
|
this.checkBookmark(chapterId)
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 加载章节内容
|
|||
|
|
loadChapter(chapterId) {
|
|||
|
|
this.setData({ loading: true })
|
|||
|
|
|
|||
|
|
wx.showLoading({ title: '加载中...', mask: true })
|
|||
|
|
|
|||
|
|
wx.request({
|
|||
|
|
url: `${app.globalData.apiBase}/book/chapter/${chapterId}`,
|
|||
|
|
header: {
|
|||
|
|
'Authorization': `Bearer ${wx.getStorageSync('token')}`
|
|||
|
|
},
|
|||
|
|
success: (res) => {
|
|||
|
|
if (res.statusCode === 200) {
|
|||
|
|
const chapter = res.data
|
|||
|
|
|
|||
|
|
// 检查是否需要购买
|
|||
|
|
if (chapter.needPurchase && !this.checkPurchased()) {
|
|||
|
|
this.showPurchaseModal()
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
this.setData({
|
|||
|
|
chapterInfo: {
|
|||
|
|
title: chapter.title,
|
|||
|
|
updateTime: chapter.updateTime,
|
|||
|
|
words: chapter.words,
|
|||
|
|
readTime: Math.ceil(chapter.words / 300)
|
|||
|
|
},
|
|||
|
|
contentHtml: this.markdownToHtml(chapter.content),
|
|||
|
|
hasPrev: !!chapter.prevChapterId,
|
|||
|
|
hasNext: !!chapter.nextChapterId,
|
|||
|
|
loading: false
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
// 记录阅读进度
|
|||
|
|
this.recordReadProgress(chapterId)
|
|||
|
|
} else {
|
|||
|
|
wx.showToast({
|
|||
|
|
title: '章节加载失败',
|
|||
|
|
icon: 'none'
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
fail: () => {
|
|||
|
|
// 使用Mock数据
|
|||
|
|
this.loadMockChapter(chapterId)
|
|||
|
|
},
|
|||
|
|
complete: () => {
|
|||
|
|
wx.hideLoading()
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 加载Mock章节
|
|||
|
|
loadMockChapter(chapterId) {
|
|||
|
|
const mockContent = `
|
|||
|
|
# 这是章节标题
|
|||
|
|
|
|||
|
|
这是第一段内容,介绍了关于私域运营的基本概念...
|
|||
|
|
|
|||
|
|
## 第一小节
|
|||
|
|
|
|||
|
|
详细内容描述...
|
|||
|
|
|
|||
|
|
### 要点总结
|
|||
|
|
|
|||
|
|
1. 第一点
|
|||
|
|
2. 第二点
|
|||
|
|
3. 第三点
|
|||
|
|
|
|||
|
|
**重点强调的内容**
|
|||
|
|
|
|||
|
|
> 引用的内容或者金句
|
|||
|
|
`
|
|||
|
|
|
|||
|
|
this.setData({
|
|||
|
|
chapterInfo: {
|
|||
|
|
title: '第一章|我是谁',
|
|||
|
|
updateTime: '2天前',
|
|||
|
|
words: 3200,
|
|||
|
|
readTime: 11
|
|||
|
|
},
|
|||
|
|
contentHtml: this.markdownToHtml(mockContent),
|
|||
|
|
hasPrev: false,
|
|||
|
|
hasNext: true,
|
|||
|
|
loading: false
|
|||
|
|
})
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// Markdown转HTML(简单实现)
|
|||
|
|
markdownToHtml(markdown) {
|
|||
|
|
if (!markdown) return ''
|
|||
|
|
|
|||
|
|
let html = markdown
|
|||
|
|
.replace(/### (.*)/g, '<h3>$1</h3>')
|
|||
|
|
.replace(/## (.*)/g, '<h2>$1</h2>')
|
|||
|
|
.replace(/# (.*)/g, '<h1>$1</h1>')
|
|||
|
|
.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')
|
|||
|
|
.replace(/\*(.*?)\*/g, '<em>$1</em>')
|
|||
|
|
.replace(/> (.*)/g, '<blockquote>$1</blockquote>')
|
|||
|
|
.replace(/\n/g, '<br/>')
|
|||
|
|
|
|||
|
|
return html
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 检查是否已购买
|
|||
|
|
checkPurchased() {
|
|||
|
|
return paymentUtil.checkPurchaseStatus()
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 显示购买弹窗
|
|||
|
|
showPurchaseModal() {
|
|||
|
|
wx.showModal({
|
|||
|
|
title: '需要购买',
|
|||
|
|
content: '此章节需要购买完整版才能阅读',
|
|||
|
|
confirmText: '立即购买',
|
|||
|
|
success: (res) => {
|
|||
|
|
if (res.confirm) {
|
|||
|
|
this.purchase()
|
|||
|
|
} else {
|
|||
|
|
wx.navigateBack()
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 购买
|
|||
|
|
purchase() {
|
|||
|
|
paymentUtil.purchaseFullBook(
|
|||
|
|
() => {
|
|||
|
|
wx.showToast({
|
|||
|
|
title: '购买成功',
|
|||
|
|
icon: 'success'
|
|||
|
|
})
|
|||
|
|
// 重新加载章节
|
|||
|
|
setTimeout(() => {
|
|||
|
|
this.loadChapter(this.data.chapterId)
|
|||
|
|
}, 1500)
|
|||
|
|
},
|
|||
|
|
() => {
|
|||
|
|
wx.showToast({
|
|||
|
|
title: '购买失败',
|
|||
|
|
icon: 'none'
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
)
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 记录阅读进度
|
|||
|
|
recordReadProgress(chapterId) {
|
|||
|
|
wx.request({
|
|||
|
|
url: `${app.globalData.apiBase}/user/read-progress`,
|
|||
|
|
method: 'POST',
|
|||
|
|
header: {
|
|||
|
|
'Authorization': `Bearer ${wx.getStorageSync('token')}`
|
|||
|
|
},
|
|||
|
|
data: {
|
|||
|
|
chapterId,
|
|||
|
|
timestamp: Date.now()
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 加载所有章节
|
|||
|
|
loadAllChapters() {
|
|||
|
|
wx.request({
|
|||
|
|
url: `${app.globalData.apiBase}/book/chapters`,
|
|||
|
|
success: (res) => {
|
|||
|
|
if (res.statusCode === 200) {
|
|||
|
|
this.setData({
|
|||
|
|
allChapters: res.data.chapters || []
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 检查书签
|
|||
|
|
checkBookmark(chapterId) {
|
|||
|
|
const bookmarks = wx.getStorageSync('bookmarks') || []
|
|||
|
|
const isBookmarked = bookmarks.includes(chapterId)
|
|||
|
|
this.setData({ isBookmarked })
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 上一章
|
|||
|
|
prevChapter() {
|
|||
|
|
if (!this.data.hasPrev) return
|
|||
|
|
|
|||
|
|
// TODO: 获取上一章ID
|
|||
|
|
wx.showToast({
|
|||
|
|
title: '功能开发中',
|
|||
|
|
icon: 'none'
|
|||
|
|
})
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 下一章
|
|||
|
|
nextChapter() {
|
|||
|
|
if (!this.data.hasNext) return
|
|||
|
|
|
|||
|
|
// TODO: 获取下一章ID
|
|||
|
|
wx.showToast({
|
|||
|
|
title: '功能开发中',
|
|||
|
|
icon: 'none'
|
|||
|
|
})
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 返回
|
|||
|
|
goBack() {
|
|||
|
|
wx.navigateBack()
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 显示菜单
|
|||
|
|
showMenu() {
|
|||
|
|
wx.showActionSheet({
|
|||
|
|
itemList: ['调整字体', '夜间模式', '分享好友'],
|
|||
|
|
success: (res) => {
|
|||
|
|
switch(res.tapIndex) {
|
|||
|
|
case 0:
|
|||
|
|
this.adjustFont()
|
|||
|
|
break
|
|||
|
|
case 1:
|
|||
|
|
this.toggleNightMode()
|
|||
|
|
break
|
|||
|
|
case 2:
|
|||
|
|
this.share()
|
|||
|
|
break
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 书签
|
|||
|
|
bookmark() {
|
|||
|
|
const chapterId = this.data.chapterId
|
|||
|
|
let bookmarks = wx.getStorageSync('bookmarks') || []
|
|||
|
|
|
|||
|
|
if (this.data.isBookmarked) {
|
|||
|
|
// 移除书签
|
|||
|
|
bookmarks = bookmarks.filter(id => id !== chapterId)
|
|||
|
|
wx.showToast({
|
|||
|
|
title: '已移除书签',
|
|||
|
|
icon: 'success'
|
|||
|
|
})
|
|||
|
|
} else {
|
|||
|
|
// 添加书签
|
|||
|
|
bookmarks.push(chapterId)
|
|||
|
|
wx.showToast({
|
|||
|
|
title: '已添加书签',
|
|||
|
|
icon: 'success'
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
wx.setStorageSync('bookmarks', bookmarks)
|
|||
|
|
this.setData({
|
|||
|
|
isBookmarked: !this.data.isBookmarked
|
|||
|
|
})
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 笔记
|
|||
|
|
note() {
|
|||
|
|
wx.navigateTo({
|
|||
|
|
url: `/pages/note/edit?chapterId=${this.data.chapterId}`
|
|||
|
|
})
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 显示目录
|
|||
|
|
showCatalog() {
|
|||
|
|
this.setData({ showCatalog: true })
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 隐藏目录
|
|||
|
|
hideCatalog() {
|
|||
|
|
this.setData({ showCatalog: false })
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 选择章节
|
|||
|
|
selectChapter(e) {
|
|||
|
|
const chapterId = e.currentTarget.dataset.id
|
|||
|
|
this.setData({
|
|||
|
|
chapterId,
|
|||
|
|
showCatalog: false
|
|||
|
|
})
|
|||
|
|
this.loadChapter(chapterId)
|
|||
|
|
this.checkBookmark(chapterId)
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 分享
|
|||
|
|
share() {
|
|||
|
|
wx.showShareMenu({
|
|||
|
|
withShareTicket: true,
|
|||
|
|
menus: ['shareAppMessage', 'shareTimeline']
|
|||
|
|
})
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 跳转到推广页面
|
|||
|
|
goToReferral() {
|
|||
|
|
wx.switchTab({
|
|||
|
|
url: '/pages/my/my?tab=referral'
|
|||
|
|
})
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 阻止冒泡
|
|||
|
|
stopPropagation() {},
|
|||
|
|
|
|||
|
|
// 分享给好友
|
|||
|
|
onShareAppMessage() {
|
|||
|
|
const userInfo = app.getUserInfo()
|
|||
|
|
const inviteCode = userInfo ? userInfo.inviteCode : ''
|
|||
|
|
|
|||
|
|
return {
|
|||
|
|
title: this.data.chapterInfo.title,
|
|||
|
|
path: `/pages/read/read?id=${this.data.chapterId}&invite=${inviteCode}`,
|
|||
|
|
imageUrl: '/assets/images/share-chapter.png'
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
})
|