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

170 lines
4.6 KiB
JavaScript

/**
* Soul创业派对 - 目录页
* 开发: 卡若
* 技术支持: 存客宝
* 数据: 完整真实文章标题
*/
const app = getApp()
const PART_NUMBERS = { 'part-1': '一', 'part-2': '二', 'part-3': '三', 'part-4': '四', 'part-5': '五' }
function buildNestedBookData(list) {
const parts = {}
const appendices = []
let epilogueMid = 0
let prefaceMid = 0
list.forEach(ch => {
if (ch.id === 'preface') {
prefaceMid = ch.mid || 0
return
}
const section = {
id: ch.id,
mid: ch.mid || 0,
title: ch.sectionTitle || ch.chapterTitle || ch.id,
isFree: !!ch.isFree,
price: ch.price != null ? Number(ch.price) : 1
}
if (ch.id === 'epilogue') {
epilogueMid = ch.mid || 0
return
}
if ((ch.id || '').startsWith('appendix')) {
appendices.push({ id: ch.id, mid: ch.mid || 0, title: ch.sectionTitle || ch.chapterTitle || ch.id })
return
}
if (!ch.partId || ch.id === 'preface') return
const pid = ch.partId
const cid = ch.chapterId || 'chapter-' + (ch.id || '').split('.')[0]
if (!parts[pid]) {
parts[pid] = { id: pid, number: PART_NUMBERS[pid] || pid, title: ch.partTitle || pid, subtitle: ch.chapterTitle || '', chapters: {} }
}
if (!parts[pid].chapters[cid]) {
parts[pid].chapters[cid] = { id: cid, title: ch.chapterTitle || cid, sections: [] }
}
parts[pid].chapters[cid].sections.push(section)
})
const bookData = Object.values(parts)
.sort((a, b) => (a.id || '').localeCompare(b.id || ''))
.map(p => ({
...p,
chapters: Object.values(p.chapters).sort((a, b) => (a.id || '').localeCompare(b.id || ''))
}))
return { bookData, appendixList: appendices, epilogueMid, prefaceMid }
}
Page({
data: {
statusBarHeight: 44,
navBarHeight: 88,
isLoggedIn: false,
hasFullBook: false,
purchasedSections: [],
totalSections: 62,
bookData: [],
expandedPart: null,
appendixList: [],
epilogueMid: 0,
prefaceMid: 0
},
onLoad() {
this.setData({
statusBarHeight: app.globalData.statusBarHeight,
navBarHeight: app.globalData.navBarHeight
})
this.updateUserStatus()
this.loadAndEnrichBookData()
},
async loadAndEnrichBookData() {
try {
let list = app.globalData.bookData || []
if (!list.length) {
const res = await app.request('/api/miniprogram/book/all-chapters')
if (res?.data) {
list = res.data
app.globalData.bookData = list
}
}
if (!list.length) {
this.setData({ bookData: [], appendixList: [] })
return
}
const { bookData, appendixList, epilogueMid, prefaceMid } = buildNestedBookData(list)
const firstPartId = bookData[0]?.id || null
this.setData({
bookData,
appendixList,
epilogueMid,
prefaceMid,
totalSections: list.length,
expandedPart: firstPartId || this.data.expandedPart
})
} catch (e) {
console.error('[Chapters] 加载目录失败:', e)
this.setData({ bookData: [], appendixList: [] })
}
},
onShow() {
this.updateUserStatus()
if (!app.globalData.bookData?.length) {
this.loadAndEnrichBookData()
}
if (typeof this.getTabBar === 'function' && this.getTabBar()) {
const tabBar = this.getTabBar()
if (tabBar.updateSelected) {
tabBar.updateSelected()
} else {
tabBar.setData({ selected: 1 })
}
}
},
// 更新用户状态
updateUserStatus() {
const { isLoggedIn, hasFullBook, purchasedSections } = app.globalData
this.setData({ isLoggedIn, hasFullBook, purchasedSections })
},
// 切换展开状态
togglePart(e) {
const partId = e.currentTarget.dataset.id
this.setData({
expandedPart: this.data.expandedPart === partId ? null : partId
})
},
goToRead(e) {
const id = e.currentTarget.dataset.id
const mid = e.currentTarget.dataset.mid || app.getSectionMid(id)
const q = mid ? `mid=${mid}` : `id=${id}`
wx.navigateTo({ url: `/pages/read/read?${q}` })
},
// 检查是否已购买
hasPurchased(sectionId) {
if (this.data.hasFullBook) return true
return this.data.purchasedSections.includes(sectionId)
},
// 返回首页
goBack() {
wx.switchTab({ url: '/pages/index/index' })
},
// 跳转到搜索页
goToSearch() {
wx.navigateTo({ url: '/pages/search/search' })
},
onShareAppMessage() {
const ref = app.getMyReferralCode()
return {
title: 'Soul创业派对 - 目录',
path: ref ? `/pages/chapters/chapters?ref=${ref}` : '/pages/chapters/chapters'
}
}
})