Files
soul/miniprogram/pages/index/index.js
卡若 7551840c86 feat: 管理后台改造 + 小程序最新章节逻辑 + 变更文档
【soul-admin 管理后台】
- 交易中心 → 推广中心(侧边栏与页面标题)
- 移除 5 个冗余按钮,仅保留「API 接口」
- 删除按钮改为悬停显示
- 免费/付费可点击切换(单击切换,双击付费可设金额)
- 加号移至章节右侧(序言、附录等),小节内移除加号
- 章节与小节支持拖拽排序
- 持续隐藏「上传内容」等按钮,解决双页面问题

【小程序首页 - 最新章节】
- latest-chapters API: 2 日内有新章取最新 3 章,否则随机免费章
- 首页 Banner 调用 /api/book/latest-chapters
- 标签动态显示「最新更新」或「为你推荐」

【开发文档】
- 新增 soul-admin变更记录_v2026-02.md

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-21 20:44:38 +08:00

207 lines
5.9 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创业派对 - 首页
* 开发: 卡若
* 技术支持: 存客宝
*/
const app = getApp()
Page({
data: {
// 系统信息
statusBarHeight: 44,
navBarHeight: 88,
// 用户信息
isLoggedIn: false,
hasFullBook: false,
purchasedCount: 0,
// 书籍数据
totalSections: 62,
bookData: [],
// 推荐章节
featuredSections: [
{ id: '1.1', title: '荷包:电动车出租的被动收入模式', tag: '免费', tagClass: 'tag-free', part: '真实的人' },
{ id: '3.1', title: '3000万流水如何跑出来', tag: '热门', tagClass: 'tag-pink', part: '真实的行业' },
{ id: '8.1', title: '流量杠杆:抖音、Soul、飞书', tag: '推荐', tagClass: 'tag-purple', part: '真实的赚钱' }
],
// 最新章节(动态计算)
latestSection: null,
latestLabel: '最新更新',
// 内容概览
partsList: [
{ id: 'part-1', number: '一', title: '真实的人', subtitle: '人与人之间的底层逻辑' },
{ id: 'part-2', number: '二', title: '真实的行业', subtitle: '电商、内容、传统行业解析' },
{ id: 'part-3', number: '三', title: '真实的错误', subtitle: '我和别人犯过的错' },
{ id: 'part-4', number: '四', title: '真实的赚钱', subtitle: '底层结构与真实案例' },
{ id: 'part-5', number: '五', title: '真实的社会', subtitle: '未来职业与商业生态' }
],
// 加载状态
loading: true
},
onLoad(options) {
// 获取系统信息
this.setData({
statusBarHeight: app.globalData.statusBarHeight,
navBarHeight: app.globalData.navBarHeight
})
// 处理分享参数(推荐码绑定)
if (options && options.ref) {
console.log('[Index] 检测到推荐码:', options.ref)
app.handleReferralCode({ query: options })
}
// 初始化数据
this.initData()
},
onShow() {
// 设置TabBar选中状态
if (typeof this.getTabBar === 'function' && this.getTabBar()) {
this.getTabBar().setData({ selected: 0 })
}
// 更新用户状态
this.updateUserStatus()
},
// 初始化数据
async initData() {
this.setData({ loading: true })
try {
await this.loadBookData()
await this.loadLatestSection()
} catch (e) {
console.error('初始化失败:', e)
this.computeLatestSectionFallback()
} finally {
this.setData({ loading: false })
}
},
// 从后端获取最新章节2日内有新章取最新3章否则随机免费章
async loadLatestSection() {
try {
const res = await app.request('/api/book/latest-chapters')
if (res && res.success && res.banner) {
this.setData({
latestSection: res.banner,
latestLabel: res.label || '最新更新'
})
return
}
} catch (e) {
console.warn('latest-chapters API 失败,使用兜底逻辑:', e.message)
}
this.computeLatestSectionFallback()
},
// 兜底API 失败时从 bookData 计算(随机选免费章节)
computeLatestSectionFallback() {
const bookData = app.globalData.bookData || this.data.bookData || []
let sections = []
if (Array.isArray(bookData)) {
sections = bookData.map(s => ({
id: s.id,
title: s.title || s.sectionTitle,
part: s.part || s.sectionTitle || '真实的行业',
isFree: s.isFree,
price: s.price
}))
} else if (bookData && typeof bookData === 'object') {
const parts = bookData.parts || (Array.isArray(bookData) ? bookData : [])
if (Array.isArray(parts)) {
parts.forEach(p => {
(p.chapters || p.sections || []).forEach(c => {
(c.sections || [c]).forEach(s => {
sections.push({
id: s.id,
title: s.title || s.section_title,
part: p.title || p.part_title || c.title || '',
isFree: s.isFree,
price: s.price
})
})
})
})
}
}
const free = sections.filter(s => s.isFree !== false && (s.price === 0 || !s.price))
const candidates = free.length > 0 ? free : sections
if (candidates.length === 0) {
this.setData({ latestSection: { id: '1.1', title: '开始阅读', part: '真实的人' }, latestLabel: '为你推荐' })
return
}
const idx = Math.floor(Math.random() * candidates.length)
const selected = { id: candidates[idx].id, title: candidates[idx].title, part: candidates[idx].part || '真实的行业' }
this.setData({ latestSection: selected, latestLabel: '为你推荐' })
},
// 加载书籍数据
async loadBookData() {
try {
const res = await app.request('/api/book/all-chapters')
if (res && res.data) {
this.setData({
bookData: res.data,
totalSections: res.totalSections || 62
})
}
} catch (e) {
console.error('加载书籍数据失败:', e)
}
},
// 更新用户状态
updateUserStatus() {
const { isLoggedIn, hasFullBook, purchasedSections } = app.globalData
this.setData({
isLoggedIn,
hasFullBook,
purchasedCount: hasFullBook ? this.data.totalSections : (purchasedSections?.length || 0)
})
},
// 跳转到目录
goToChapters() {
wx.switchTab({ url: '/pages/chapters/chapters' })
},
// 跳转到搜索页
goToSearch() {
wx.navigateTo({ url: '/pages/search/search' })
},
// 跳转到阅读页
goToRead(e) {
const id = e.currentTarget.dataset.id
wx.navigateTo({ url: `/pages/read/read?id=${id}` })
},
// 跳转到匹配页
goToMatch() {
wx.switchTab({ url: '/pages/match/match' })
},
// 跳转到我的页面
goToMy() {
wx.switchTab({ url: '/pages/my/my' })
},
// 下拉刷新
async onPullDownRefresh() {
await this.initData()
this.updateUserStatus()
wx.stopPullDownRefresh()
}
})