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

224 lines
6.8 KiB
JavaScript
Raw Normal View History

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