/** * Soul创业实验 - 文章数据API * 用于存储和获取章节数据 */ import { NextResponse } from 'next/server' import fs from 'fs' import path from 'path' // 文章数据结构 interface Section { id: string title: string isFree: boolean price: number content?: string filePath?: string } interface Chapter { id: string title: string sections: Section[] } interface Part { id: string number: string title: string subtitle: string chapters: Chapter[] } // 书籍目录结构映射 const BOOK_STRUCTURE = [ { id: 'part-1', number: '一', title: '真实的人', subtitle: '人与人之间的底层逻辑', folder: '第一篇|真实的人', chapters: [ { id: 'chapter-1', title: '第1章|人与人之间的底层逻辑', folder: '第1章|人与人之间的底层逻辑' }, { id: 'chapter-2', title: '第2章|人性困境案例', folder: '第2章|人性困境案例' } ] }, { id: 'part-2', number: '二', title: '真实的行业', subtitle: '电商、内容、传统行业解析', folder: '第二篇|真实的行业', chapters: [ { id: 'chapter-3', title: '第3章|电商篇', folder: '第3章|电商篇' }, { id: 'chapter-4', title: '第4章|内容商业篇', folder: '第4章|内容商业篇' }, { id: 'chapter-5', title: '第5章|传统行业篇', folder: '第5章|传统行业篇' } ] }, { id: 'part-3', number: '三', title: '真实的错误', subtitle: '我和别人犯过的错', folder: '第三篇|真实的错误', chapters: [ { id: 'chapter-6', title: '第6章|我人生错过的4件大钱', folder: '第6章|我人生错过的4件大钱' }, { id: 'chapter-7', title: '第7章|别人犯的错误', folder: '第7章|别人犯的错误' } ] }, { id: 'part-4', number: '四', title: '真实的赚钱', subtitle: '底层结构与真实案例', folder: '第四篇|真实的赚钱', chapters: [ { id: 'chapter-8', title: '第8章|底层结构', folder: '第8章|底层结构' }, { id: 'chapter-9', title: '第9章|我在Soul上亲访的赚钱案例', folder: '第9章|我在Soul上亲访的赚钱案例' } ] }, { id: 'part-5', number: '五', title: '真实的社会', subtitle: '未来职业与商业生态', folder: '第五篇|真实的社会', chapters: [ { id: 'chapter-10', title: '第10章|未来职业的变化趋势', folder: '第10章|未来职业的变化趋势' }, { id: 'chapter-11', title: '第11章|中国社会商业生态的未来', folder: '第11章|中国社会商业生态的未来' } ] } ] // 免费章节ID const FREE_SECTIONS = ['1.1', 'preface', 'epilogue', 'appendix-1', 'appendix-2', 'appendix-3'] // 从book目录读取真实文章数据 function loadBookData(): Part[] { const bookPath = path.join(process.cwd(), 'book') const parts: Part[] = [] for (const partConfig of BOOK_STRUCTURE) { const part: Part = { id: partConfig.id, number: partConfig.number, title: partConfig.title, subtitle: partConfig.subtitle, chapters: [] } for (const chapterConfig of partConfig.chapters) { const chapter: Chapter = { id: chapterConfig.id, title: chapterConfig.title, sections: [] } const chapterPath = path.join(bookPath, partConfig.folder, chapterConfig.folder) try { const files = fs.readdirSync(chapterPath) const mdFiles = files.filter(f => f.endsWith('.md')).sort() for (const file of mdFiles) { // 从文件名提取ID和标题 const match = file.match(/^(\d+\.\d+)\s+(.+)\.md$/) if (match) { const [, id, title] = match const filePath = path.join(chapterPath, file) chapter.sections.push({ id, title: title.replace(/[::]/g, ':'), // 统一冒号格式 isFree: FREE_SECTIONS.includes(id), price: 1, filePath }) } } // 按ID数字排序 chapter.sections.sort((a, b) => { const [aMajor, aMinor] = a.id.split('.').map(Number) const [bMajor, bMinor] = b.id.split('.').map(Number) return aMajor !== bMajor ? aMajor - bMajor : aMinor - bMinor }) } catch (e) { console.error(`读取章节目录失败: ${chapterPath}`, e) } part.chapters.push(chapter) } parts.push(part) } return parts } // 读取文章内容 function getArticleContent(sectionId: string): string | null { const bookData = loadBookData() for (const part of bookData) { for (const chapter of part.chapters) { const section = chapter.sections.find(s => s.id === sectionId) if (section?.filePath) { try { return fs.readFileSync(section.filePath, 'utf-8') } catch (e) { console.error(`读取文章内容失败: ${section.filePath}`, e) } } } } return null } // GET - 获取所有章节数据 export async function GET(request: Request) { const { searchParams } = new URL(request.url) const sectionId = searchParams.get('id') const includeContent = searchParams.get('content') === 'true' try { // 如果指定了章节ID,返回单篇文章内容 if (sectionId) { const content = getArticleContent(sectionId) if (content) { return NextResponse.json({ success: true, data: { id: sectionId, content } }) } else { return NextResponse.json({ success: false, error: '文章不存在' }, { status: 404 }) } } // 返回完整书籍结构 const bookData = loadBookData() // 统计总章节数 let totalSections = 0 for (const part of bookData) { for (const chapter of part.chapters) { totalSections += chapter.sections.length } } // 加上序言、尾声和3个附录 totalSections += 5 return NextResponse.json({ success: true, data: { totalSections, parts: bookData, appendix: [ { id: 'appendix-1', title: '附录1|Soul派对房精选对话', isFree: true }, { id: 'appendix-2', title: '附录2|创业者自检清单', isFree: true }, { id: 'appendix-3', title: '附录3|本书提到的工具和资源', isFree: true } ], preface: { id: 'preface', title: '序言|为什么我每天早上6点在Soul开播?', isFree: true }, epilogue: { id: 'epilogue', title: '尾声|这本书的真实目的', isFree: true } } }) } catch (error) { console.error('获取章节数据失败:', error) return NextResponse.json({ success: false, error: '获取数据失败' }, { status: 500 }) } } // POST - 同步章节数据到数据库(预留接口) export async function POST(request: Request) { try { const bookData = loadBookData() // 这里可以添加数据库写入逻辑 // 目前先返回成功,数据已从文件系统读取 let totalSections = 0 for (const part of bookData) { for (const chapter of part.chapters) { totalSections += chapter.sections.length } } totalSections += 5 // 序言、尾声、3个附录 return NextResponse.json({ success: true, message: '章节数据同步成功', data: { totalSections, partsCount: bookData.length, chaptersCount: bookData.reduce((acc, p) => acc + p.chapters.length, 0) } }) } catch (error) { console.error('同步章节数据失败:', error) return NextResponse.json({ success: false, error: '同步数据失败' }, { status: 500 }) } }