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

224 lines
6.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* Soul创业派对 - 首页
* 开发: 卡若
* 技术支持: 存客宝
*/
console.log('[Index] ===== 首页文件开始加载 =====')
const app = getApp()
const PART_NUMBERS = { 'part-1': '一', 'part-2': '二', 'part-3': '三', 'part-4': '四', 'part-5': '五' }
Page({
data: {
// 系统信息
statusBarHeight: 44,
navBarHeight: 88,
// 用户信息
isLoggedIn: false,
hasFullBook: false,
readCount: 0,
totalSections: 62,
bookData: [],
featuredSections: [],
latestSection: null,
latestLabel: '最新更新',
partsList: [],
prefaceMid: 0,
loading: true
},
onLoad(options) {
console.log('[Index] ===== onLoad 触发 =====')
// 获取系统信息
this.setData({
statusBarHeight: app.globalData.statusBarHeight,
navBarHeight: app.globalData.navBarHeight
})
// 处理分享参数与扫码 scene推荐码绑定
if (options && (options.ref || options.scene)) {
app.handleReferralCode(options)
}
// 初始化数据
this.initData()
},
onShow() {
console.log('[Index] onShow 触发')
// 设置TabBar选中状态
if (typeof this.getTabBar === 'function' && this.getTabBar()) {
const tabBar = this.getTabBar()
console.log('[Index] TabBar 组件:', tabBar ? '已找到' : '未找到')
// 主动触发配置加载
if (tabBar && tabBar.loadFeatureConfig) {
console.log('[Index] 主动调用 TabBar.loadFeatureConfig()')
tabBar.loadFeatureConfig()
}
// 更新选中状态
if (tabBar && tabBar.updateSelected) {
tabBar.updateSelected()
} else if (tabBar) {
tabBar.setData({ selected: 0 })
}
} else {
console.log('[Index] TabBar 组件未找到或 getTabBar 方法不存在')
}
// 更新用户状态
this.updateUserStatus()
},
// 初始化数据
async initData() {
this.setData({ loading: true })
try {
await this.loadBookData()
} catch (e) {
console.error('初始化失败:', e)
} finally {
this.setData({ loading: false })
}
},
async loadBookData() {
try {
const [chaptersRes, hotRes] = await Promise.all([
app.request('/api/miniprogram/book/all-chapters'),
app.request('/api/miniprogram/book/hot')
])
const list = chaptersRes?.data || []
const hotList = hotRes?.data || []
app.globalData.bookData = list
const toSection = (ch) => ({
id: ch.id,
mid: ch.mid || 0,
title: ch.sectionTitle || ch.chapterTitle || ch.id,
part: ch.partTitle || ''
})
let featuredSections = []
if (hotList.length >= 3) {
const freeCh = list.find(c => c.isFree || c.id === '1.1' || c.id === 'preface')
const picks = []
if (freeCh) picks.push({ ...toSection(freeCh), tag: '免费', tagClass: 'tag-free' })
hotList.slice(0, 3 - picks.length).forEach((ch, i) => {
if (!picks.find(p => p.id === ch.id)) {
picks.push({ ...toSection(ch), tag: i === 0 ? '热门' : '推荐', tagClass: i === 0 ? 'tag-pink' : 'tag-purple' })
}
})
featuredSections = picks.slice(0, 3)
}
if (featuredSections.length < 3 && list.length > 0) {
const fallback = list.filter(c => c.id && !['preface', 'epilogue'].includes(c.id)).slice(0, 3)
featuredSections = fallback.map((ch, i) => ({
...toSection(ch),
tag: ch.isFree ? '免费' : (i === 0 ? '热门' : '推荐'),
tagClass: ch.isFree ? 'tag-free' : (i === 0 ? 'tag-pink' : 'tag-purple')
}))
}
const partMap = {}
list.forEach(ch => {
if (!ch.partId || ch.id === 'preface' || ch.id === 'epilogue' || (ch.id || '').startsWith('appendix')) return
if (!partMap[ch.partId]) {
partMap[ch.partId] = { id: ch.partId, number: PART_NUMBERS[ch.partId] || ch.partId, title: ch.partTitle || ch.partId, subtitle: ch.chapterTitle || '' }
}
})
const partsList = Object.values(partMap).sort((a, b) => (a.id || '').localeCompare(b.id || ''))
const paidCandidates = list.filter(c => c.id && !['preface', 'epilogue'].includes(c.id) && !(c.id || '').startsWith('appendix') && c.partId)
const { hasFullBook, purchasedSections } = app.globalData
let candidates = paidCandidates
if (!hasFullBook && purchasedSections?.length) {
const unpurchased = paidCandidates.filter(c => !purchasedSections.includes(c.id))
if (unpurchased.length > 0) candidates = unpurchased
}
const userId = app.globalData.userInfo?.id || wx.getStorageSync('userId') || 'guest'
const today = new Date().toISOString().split('T')[0]
const seed = (userId + today).split('').reduce((a, b) => a + b.charCodeAt(0), 0)
const selectedCh = candidates[seed % Math.max(candidates.length, 1)]
const latestSection = selectedCh ? { ...toSection(selectedCh), mid: selectedCh.mid || 0 } : null
const latestLabel = candidates.length === paidCandidates.length ? '推荐阅读' : '为你推荐'
const prefaceCh = list.find(c => c.id === 'preface')
const prefaceMid = prefaceCh?.mid || 0
this.setData({
bookData: list,
totalSections: list.length || 62,
featuredSections,
partsList,
latestSection,
latestLabel,
prefaceMid
})
} catch (e) {
console.error('加载书籍数据失败:', e)
this.setData({ featuredSections: [], partsList: [], latestSection: null })
}
},
// 更新用户状态(已读数 = 用户实际打开过的章节数,仅统计有权限阅读的)
updateUserStatus() {
const { isLoggedIn, hasFullBook, purchasedSections } = app.globalData
const readCount = Math.min(app.getReadCount(), this.data.totalSections || 62)
this.setData({
isLoggedIn,
hasFullBook,
readCount
})
},
// 跳转到目录
goToChapters() {
wx.switchTab({ url: '/pages/chapters/chapters' })
},
// 跳转到搜索页
goToSearch() {
wx.navigateTo({ url: '/pages/search/search' })
},
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}` })
},
// 跳转到匹配页
goToMatch() {
wx.switchTab({ url: '/pages/match/match' })
},
// 跳转到我的页面
goToMy() {
wx.switchTab({ url: '/pages/my/my' })
},
// 下拉刷新
async onPullDownRefresh() {
await this.initData()
this.updateUserStatus()
wx.stopPullDownRefresh()
},
onShareAppMessage() {
const ref = app.getMyReferralCode()
return {
title: 'Soul创业派对 - 真实商业故事',
path: ref ? `/pages/index/index?ref=${ref}` : '/pages/index/index'
}
}
})