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