Files
soul/app/api/admin/chapters/route.ts
卡若 7ff181f743 fix: 全面优化小程序功能
🔧 数据库配置:
- 切换到腾讯云外网数据库
- 配置连接参数和连接池

🎨 界面优化:
- 未登录时只显示登录按钮,隐藏其他功能
- 优化登录卡片样式
- 修复章节图标和标题对齐问题

💳 支付流程优化:
- 增加重复购买检测,避免重复支付
- 优化openId获取逻辑,支持静默获取
- 已登录用户可直接支付,无需重复登录

📊 后台管理:
- 创建章节管理API (/api/admin/chapters)
- 创建章节管理页面 (/admin/chapters)
- 支持查看所有章节、修改价格、设置免费状态
2026-01-23 17:25:15 +08:00

320 lines
14 KiB
TypeScript
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.

/**
* 章节管理API - 后台管理功能
* 用于管理书籍章节、价格、状态等
*/
import { NextResponse } from 'next/server'
import fs from 'fs'
import path from 'path'
// 获取书籍目录
const BOOK_DIR = path.join(process.cwd(), 'book')
/**
* GET - 获取所有章节列表
*/
export async function GET(request: Request) {
try {
const { searchParams } = new URL(request.url)
const includeContent = searchParams.get('content') === 'true'
// 定义书籍结构
const bookStructure = [
{
id: 'part-preface',
title: '序言',
type: 'preface',
chapters: [
{
id: 'preface',
title: '序言为什么我每天早上6点在Soul开播?',
price: 0,
isFree: true,
status: 'published',
file: '序言为什么我每天早上6点在Soul开播?.md'
}
]
},
{
id: 'part-1',
title: '第一篇|真实的人',
type: 'part',
chapters: [
{
id: 'chapter-1',
title: '第1章人与人之间的底层逻辑',
sections: [
{ id: '1.1', title: '荷包:电动车出租的被动收入模式', price: 1, isFree: true, status: 'published' },
{ id: '1.2', title: '老墨:资源整合高手的社交方法', price: 1, isFree: false, status: 'published' },
{ id: '1.3', title: '笑声背后的MBTI为什么ENTJ适合做资源INTP适合做系统', price: 1, isFree: false, status: 'published' },
{ id: '1.4', title: '人性的三角结构:利益、情感、价值观', price: 1, isFree: false, status: 'published' },
{ id: '1.5', title: '沟通差的问题:为什么你说的别人听不懂', price: 1, isFree: false, status: 'published' }
]
},
{
id: 'chapter-2',
title: '第2章人性困境案例',
sections: [
{ id: '2.1', title: '相亲故事:你以为找的是人,实际是在找模式', price: 1, isFree: false, status: 'published' },
{ id: '2.2', title: '找工作迷茫者:为什么简历解决不了人生', price: 1, isFree: false, status: 'published' },
{ id: '2.3', title: '撸运费险:小钱困住大脑的真实心理', price: 1, isFree: false, status: 'published' },
{ id: '2.4', title: '游戏上瘾的年轻人:不是游戏吸引他,是生活没吸引力', price: 1, isFree: false, status: 'published' },
{ id: '2.5', title: '健康焦虑(我的糖尿病经历):疾病是人生的第一次清醒', price: 1, isFree: false, status: 'published' }
]
}
]
},
{
id: 'part-2',
title: '第二篇|真实的行业',
type: 'part',
chapters: [
{
id: 'chapter-3',
title: '第3章电商篇',
sections: [
{ id: '3.1', title: '3000万流水如何跑出来(退税模式解析)', price: 1, isFree: false, status: 'published' },
{ id: '3.2', title: '供应链之王 vs 打工人:利润不在前端', price: 1, isFree: false, status: 'published' },
{ id: '3.3', title: '社区团购的底层逻辑', price: 1, isFree: false, status: 'published' },
{ id: '3.4', title: '跨境电商与退税套利', price: 1, isFree: false, status: 'published' }
]
},
{
id: 'chapter-4',
title: '第4章内容商业篇',
sections: [
{ id: '4.1', title: '旅游号:30天10万粉的真实逻辑', price: 1, isFree: false, status: 'published' },
{ id: '4.2', title: '做号工厂:如何让一个号变成一个机器', price: 1, isFree: false, status: 'published' },
{ id: '4.3', title: '情绪内容为什么比专业内容更赚钱', price: 1, isFree: false, status: 'published' },
{ id: '4.4', title: '猫与宠物号:为什么宠物赛道永不过时', price: 1, isFree: false, status: 'published' },
{ id: '4.5', title: '直播间里的三种人:演员、技术工、系统流', price: 1, isFree: false, status: 'published' }
]
},
{
id: 'chapter-5',
title: '第5章传统行业篇',
sections: [
{ id: '5.1', title: '拍卖行抱朴一天240万的摇号生意', price: 1, isFree: false, status: 'published' },
{ id: '5.2', title: '土地拍卖:招拍挂背后的游戏规则', price: 1, isFree: false, status: 'published' },
{ id: '5.3', title: '地摊经济数字化一个月900块的餐车生意', price: 1, isFree: false, status: 'published' },
{ id: '5.4', title: '不良资产拍卖:我错过的一个亿佣金', price: 1, isFree: false, status: 'published' },
{ id: '5.5', title: '桶装水李总:跟物业合作的轻资产模式', price: 1, isFree: false, status: 'published' }
]
}
]
},
{
id: 'part-3',
title: '第三篇|真实的错误',
type: 'part',
chapters: [
{
id: 'chapter-6',
title: '第6章我人生错过的4件大钱',
sections: [
{ id: '6.1', title: '电商财税窗口2016年的千万级机会', price: 1, isFree: false, status: 'published' },
{ id: '6.2', title: '供应链金融:我不懂的杠杆游戏', price: 1, isFree: false, status: 'published' },
{ id: '6.3', title: '内容红利2019年我为什么没做抖音', price: 1, isFree: false, status: 'published' },
{ id: '6.4', title: '数据资产化:我还在观望的未来机会', price: 1, isFree: false, status: 'published' }
]
},
{
id: 'chapter-7',
title: '第7章别人犯的错误',
sections: [
{ id: '7.1', title: '投资房年轻人的迷茫:资金 vs 能力', price: 1, isFree: false, status: 'published' },
{ id: '7.2', title: '信息差骗局:永远有人靠卖学习赚钱', price: 1, isFree: false, status: 'published' },
{ id: '7.3', title: '在Soul找恋爱但想赚钱的人', price: 1, isFree: false, status: 'published' },
{ id: '7.4', title: '创业者的三种死法:冲动、轻信、没结构', price: 1, isFree: false, status: 'published' },
{ id: '7.5', title: '人情生意的终点:关系越多亏得越多', price: 1, isFree: false, status: 'published' }
]
}
]
},
{
id: 'part-4',
title: '第四篇|真实的赚钱',
type: 'part',
chapters: [
{
id: 'chapter-8',
title: '第8章底层结构',
sections: [
{ id: '8.1', title: '流量杠杆:抖音、Soul、飞书', price: 1, isFree: false, status: 'published' },
{ id: '8.2', title: '价格杠杆:供应链与信息差', price: 1, isFree: false, status: 'published' },
{ id: '8.3', title: '时间杠杆:自动化 + AI', price: 1, isFree: false, status: 'published' },
{ id: '8.4', title: '情绪杠杆:咨询、婚恋、生意场', price: 1, isFree: false, status: 'published' },
{ id: '8.5', title: '社交杠杆:认识谁比你会什么更重要', price: 1, isFree: false, status: 'published' },
{ id: '8.6', title: '云阿米巴:分不属于自己的钱', price: 1, isFree: false, status: 'published' }
]
},
{
id: 'chapter-9',
title: '第9章我在Soul上亲访的赚钱案例',
sections: [
{ id: '9.1', title: '游戏账号私域:账号即资产', price: 1, isFree: false, status: 'published' },
{ id: '9.2', title: '健康包模式:高复购、高毛利', price: 1, isFree: false, status: 'published' },
{ id: '9.3', title: '药物私域:长期关系赛道', price: 1, isFree: false, status: 'published' },
{ id: '9.4', title: '残疾机构合作:退税 × AI × 人力成本', price: 1, isFree: false, status: 'published' },
{ id: '9.5', title: '私域银行:粉丝即小股东', price: 1, isFree: false, status: 'published' },
{ id: '9.6', title: 'Soul派对房:陌生人成交的最快场景', price: 1, isFree: false, status: 'published' },
{ id: '9.7', title: '飞书中台:从聊天到成交的流程化体系', price: 1, isFree: false, status: 'published' },
{ id: '9.8', title: '餐饮女孩6万营收、1万利润的死撑生意', price: 1, isFree: false, status: 'published' },
{ id: '9.9', title: '电竞生态:从陪玩到签约到酒店的完整链条', price: 1, isFree: false, status: 'published' },
{ id: '9.10', title: '淘客大佬损耗30%的白色通道', price: 1, isFree: false, status: 'published' },
{ id: '9.11', title: '蔬菜供应链:农户才是最赚钱的人', price: 1, isFree: false, status: 'published' },
{ id: '9.12', title: '美业整合:一个人的公司如何月入十万', price: 1, isFree: false, status: 'published' },
{ id: '9.13', title: 'AI工具推广一个隐藏的高利润赛道', price: 1, isFree: false, status: 'published' },
{ id: '9.14', title: '大健康私域一个月150万的70后', price: 1, isFree: false, status: 'published' }
]
}
]
},
{
id: 'part-5',
title: '第五篇|真实的社会',
type: 'part',
chapters: [
{
id: 'chapter-10',
title: '第10章未来职业的变化趋势',
sections: [
{ id: '10.1', title: 'AI时代哪些工作会消失哪些会崛起', price: 1, isFree: false, status: 'published' },
{ id: '10.2', title: '一人公司:为什么越来越多人选择单干', price: 1, isFree: false, status: 'published' },
{ id: '10.3', title: '为什么链接能力会成为第一价值', price: 1, isFree: false, status: 'published' },
{ id: '10.4', title: '新型公司:Soul-飞书-线下的三位一体', price: 1, isFree: false, status: 'published' }
]
},
{
id: 'chapter-11',
title: '第11章中国社会商业生态的未来',
sections: [
{ id: '11.1', title: '私域经济:为什么流量越来越贵', price: 1, isFree: false, status: 'published' },
{ id: '11.2', title: '银发经济与孤独经济:两个被忽视的万亿市场', price: 1, isFree: false, status: 'published' },
{ id: '11.3', title: '流量红利的终局', price: 1, isFree: false, status: 'published' },
{ id: '11.4', title: '大模型 + 供应链的组合拳', price: 1, isFree: false, status: 'published' },
{ id: '11.5', title: '社会分层的最终逻辑', price: 1, isFree: false, status: 'published' }
]
}
]
},
{
id: 'part-epilogue',
title: '尾声',
type: 'epilogue',
chapters: [
{
id: 'epilogue',
title: '尾声|这本书的真实目的',
price: 0,
isFree: true,
status: 'published',
file: '尾声|这本书的真实目的.md'
}
]
},
{
id: 'part-appendix',
title: '附录',
type: 'appendix',
chapters: [
{ id: 'appendix-1', title: '附录1Soul派对房精选对话', price: 0, isFree: true, status: 'published' },
{ id: 'appendix-2', title: '附录2创业者自检清单', price: 0, isFree: true, status: 'published' },
{ id: 'appendix-3', title: '附录3本书提到的工具和资源', price: 0, isFree: true, status: 'published' }
]
}
]
// 计算统计数据
let totalSections = 0
let freeSections = 0
let paidSections = 0
bookStructure.forEach(part => {
if (part.chapters) {
part.chapters.forEach(chapter => {
if (chapter.sections) {
totalSections += chapter.sections.length
chapter.sections.forEach(s => {
if (s.isFree) freeSections++
else paidSections++
})
} else {
totalSections++
if (chapter.isFree) freeSections++
else paidSections++
}
})
}
})
return NextResponse.json({
success: true,
data: {
structure: bookStructure,
stats: {
totalSections,
freeSections,
paidSections,
totalParts: bookStructure.length
}
}
})
} catch (error) {
console.error('[AdminChapters] 获取章节失败:', error)
return NextResponse.json({
success: false,
error: '获取章节失败'
}, { status: 500 })
}
}
/**
* POST - 更新章节设置
*/
export async function POST(request: Request) {
try {
const body = await request.json()
const { action, chapterId, data } = body
console.log('[AdminChapters] 更新章节:', { action, chapterId })
switch (action) {
case 'updatePrice':
// 更新章节价格
// TODO: 保存到数据库
return NextResponse.json({
success: true,
data: { message: '价格更新成功', chapterId, price: data.price }
})
case 'toggleFree':
// 切换免费状态
return NextResponse.json({
success: true,
data: { message: '免费状态更新成功', chapterId, isFree: data.isFree }
})
case 'updateStatus':
// 更新发布状态
return NextResponse.json({
success: true,
data: { message: '发布状态更新成功', chapterId, status: data.status }
})
default:
return NextResponse.json({
success: false,
error: '未知操作'
}, { status: 400 })
}
} catch (error) {
console.error('[AdminChapters] 更新章节失败:', error)
return NextResponse.json({
success: false,
error: '更新章节失败'
}, { status: 500 })
}
}