2026-02-04 11:36:19 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* Soul创业派对 - 首页
|
|
|
|
|
|
* 开发: 卡若
|
|
|
|
|
|
* 技术支持: 存客宝
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
2026-02-04 14:24:50 +08:00
|
|
|
|
console.log('[Index] ===== 首页文件开始加载 =====')
|
|
|
|
|
|
|
2026-02-04 11:36:19 +08:00
|
|
|
|
const app = getApp()
|
2026-02-12 15:52:35 +08:00
|
|
|
|
const PART_NUMBERS = { 'part-1': '一', 'part-2': '二', 'part-3': '三', 'part-4': '四', 'part-5': '五' }
|
2026-02-04 11:36:19 +08:00
|
|
|
|
|
|
|
|
|
|
Page({
|
|
|
|
|
|
data: {
|
|
|
|
|
|
// 系统信息
|
|
|
|
|
|
statusBarHeight: 44,
|
|
|
|
|
|
navBarHeight: 88,
|
|
|
|
|
|
|
|
|
|
|
|
// 用户信息
|
|
|
|
|
|
isLoggedIn: false,
|
|
|
|
|
|
hasFullBook: false,
|
2026-02-04 21:36:26 +08:00
|
|
|
|
readCount: 0,
|
2026-02-04 11:36:19 +08:00
|
|
|
|
|
|
|
|
|
|
totalSections: 62,
|
|
|
|
|
|
bookData: [],
|
2026-02-12 15:52:35 +08:00
|
|
|
|
featuredSections: [],
|
2026-02-04 11:36:19 +08:00
|
|
|
|
latestSection: null,
|
|
|
|
|
|
latestLabel: '最新更新',
|
2026-02-12 15:52:35 +08:00
|
|
|
|
partsList: [],
|
|
|
|
|
|
prefaceMid: 0,
|
2026-02-04 11:36:19 +08:00
|
|
|
|
loading: true
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
onLoad(options) {
|
2026-02-04 14:24:50 +08:00
|
|
|
|
console.log('[Index] ===== onLoad 触发 =====')
|
|
|
|
|
|
|
2026-02-04 11:36:19 +08:00
|
|
|
|
// 获取系统信息
|
|
|
|
|
|
this.setData({
|
|
|
|
|
|
statusBarHeight: app.globalData.statusBarHeight,
|
|
|
|
|
|
navBarHeight: app.globalData.navBarHeight
|
|
|
|
|
|
})
|
|
|
|
|
|
|
2026-02-12 15:09:52 +08:00
|
|
|
|
// 处理分享参数与扫码 scene(推荐码绑定)
|
|
|
|
|
|
if (options && (options.ref || options.scene)) {
|
|
|
|
|
|
app.handleReferralCode(options)
|
2026-02-04 11:36:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 初始化数据
|
|
|
|
|
|
this.initData()
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
onShow() {
|
2026-02-04 14:24:50 +08:00
|
|
|
|
console.log('[Index] onShow 触发')
|
|
|
|
|
|
|
2026-02-04 11:36:19 +08:00
|
|
|
|
// 设置TabBar选中状态
|
|
|
|
|
|
if (typeof this.getTabBar === 'function' && this.getTabBar()) {
|
|
|
|
|
|
const tabBar = this.getTabBar()
|
2026-02-04 14:24:50 +08:00
|
|
|
|
console.log('[Index] TabBar 组件:', tabBar ? '已找到' : '未找到')
|
|
|
|
|
|
|
|
|
|
|
|
// 主动触发配置加载
|
|
|
|
|
|
if (tabBar && tabBar.loadFeatureConfig) {
|
|
|
|
|
|
console.log('[Index] 主动调用 TabBar.loadFeatureConfig()')
|
|
|
|
|
|
tabBar.loadFeatureConfig()
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 更新选中状态
|
|
|
|
|
|
if (tabBar && tabBar.updateSelected) {
|
2026-02-04 11:36:19 +08:00
|
|
|
|
tabBar.updateSelected()
|
2026-02-04 14:24:50 +08:00
|
|
|
|
} else if (tabBar) {
|
2026-02-04 11:36:19 +08:00
|
|
|
|
tabBar.setData({ selected: 0 })
|
|
|
|
|
|
}
|
2026-02-04 14:24:50 +08:00
|
|
|
|
} else {
|
|
|
|
|
|
console.log('[Index] TabBar 组件未找到或 getTabBar 方法不存在')
|
2026-02-04 11:36:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 更新用户状态
|
|
|
|
|
|
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 {
|
2026-02-12 15:52:35 +08:00
|
|
|
|
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' })
|
|
|
|
|
|
}
|
2026-02-04 11:36:19 +08:00
|
|
|
|
})
|
2026-02-12 15:52:35 +08:00
|
|
|
|
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
|
2026-02-04 11:36:19 +08:00
|
|
|
|
}
|
2026-02-12 15:52:35 +08:00
|
|
|
|
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
|
|
|
|
|
|
})
|
2026-02-04 11:36:19 +08:00
|
|
|
|
} catch (e) {
|
|
|
|
|
|
console.error('加载书籍数据失败:', e)
|
2026-02-12 15:52:35 +08:00
|
|
|
|
this.setData({ featuredSections: [], partsList: [], latestSection: null })
|
2026-02-04 11:36:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
2026-02-04 21:36:26 +08:00
|
|
|
|
// 更新用户状态(已读数 = 用户实际打开过的章节数,仅统计有权限阅读的)
|
2026-02-04 11:36:19 +08:00
|
|
|
|
updateUserStatus() {
|
|
|
|
|
|
const { isLoggedIn, hasFullBook, purchasedSections } = app.globalData
|
2026-02-04 21:36:26 +08:00
|
|
|
|
const readCount = Math.min(app.getReadCount(), this.data.totalSections || 62)
|
2026-02-04 11:36:19 +08:00
|
|
|
|
this.setData({
|
|
|
|
|
|
isLoggedIn,
|
|
|
|
|
|
hasFullBook,
|
2026-02-04 21:36:26 +08:00
|
|
|
|
readCount
|
2026-02-04 11:36:19 +08:00
|
|
|
|
})
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// 跳转到目录
|
|
|
|
|
|
goToChapters() {
|
|
|
|
|
|
wx.switchTab({ url: '/pages/chapters/chapters' })
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// 跳转到搜索页
|
|
|
|
|
|
goToSearch() {
|
|
|
|
|
|
wx.navigateTo({ url: '/pages/search/search' })
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
goToRead(e) {
|
|
|
|
|
|
const id = e.currentTarget.dataset.id
|
2026-02-12 15:52:35 +08:00
|
|
|
|
const mid = e.currentTarget.dataset.mid || app.getSectionMid(id)
|
|
|
|
|
|
const q = mid ? `mid=${mid}` : `id=${id}`
|
|
|
|
|
|
wx.navigateTo({ url: `/pages/read/read?${q}` })
|
2026-02-04 11:36:19 +08:00
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// 跳转到匹配页
|
|
|
|
|
|
goToMatch() {
|
|
|
|
|
|
wx.switchTab({ url: '/pages/match/match' })
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// 跳转到我的页面
|
|
|
|
|
|
goToMy() {
|
|
|
|
|
|
wx.switchTab({ url: '/pages/my/my' })
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// 下拉刷新
|
|
|
|
|
|
async onPullDownRefresh() {
|
|
|
|
|
|
await this.initData()
|
|
|
|
|
|
this.updateUserStatus()
|
|
|
|
|
|
wx.stopPullDownRefresh()
|
2026-02-12 15:09:52 +08:00
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
onShareAppMessage() {
|
|
|
|
|
|
const ref = app.getMyReferralCode()
|
|
|
|
|
|
return {
|
|
|
|
|
|
title: 'Soul创业派对 - 真实商业故事',
|
|
|
|
|
|
path: ref ? `/pages/index/index?ref=${ref}` : '/pages/index/index'
|
|
|
|
|
|
}
|
2026-02-04 11:36:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
})
|