Files
soul-yongping/app/api/book/all-chapters/route.ts

162 lines
5.0 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.

import { NextResponse } from 'next/server'
import fs from 'fs'
import path from 'path'
import { query } from '@/lib/db'
export async function GET() {
try {
// 方案1: 优先从数据库读取(使用实际存在的 chapters 表,不是 sections
try {
const dbChapters = await query(`
SELECT
id, part_id, part_title, chapter_id, chapter_title, section_title, content,
word_count, is_free, price, sort_order, created_at, updated_at
FROM chapters
WHERE status = 'published'
ORDER BY sort_order ASC
`, []) as any[]
if (dbChapters && dbChapters.length > 0) {
console.log('[All Chapters API] 从数据库 chapters 表读取成功,共', dbChapters.length, '章')
const allChapters = dbChapters.map((row: any, idx: number) => ({
id: row.id,
sectionId: row.chapter_id || row.part_id,
title: row.chapter_title || row.section_title,
sectionTitle: row.part_title || row.section_title,
content: row.content,
isFree: !!row.is_free,
price: Number(row.price) || 0,
words: row.word_count || Math.floor(Math.random() * 3000) + 2000,
sectionOrder: row.sort_order ?? idx + 1,
chapterOrder: idx + 1,
createdAt: row.created_at,
updatedAt: row.updated_at
}))
return NextResponse.json({
success: true,
data: allChapters,
chapters: allChapters,
total: allChapters.length,
source: 'database'
})
}
} catch (dbError) {
console.log('[All Chapters API] 数据库读取失败,尝试文件读取:', (dbError as Error).message)
}
// 方案2: 从JSON文件读取
const possiblePaths = [
path.join(process.cwd(), 'public/book-chapters.json'),
path.join(process.cwd(), 'data/book-chapters.json'),
'/www/wwwroot/soul/public/book-chapters.json'
]
let chaptersData: any[] = []
let usedPath = ''
for (const dataPath of possiblePaths) {
try {
if (fs.existsSync(dataPath)) {
const fileContent = fs.readFileSync(dataPath, 'utf-8')
chaptersData = JSON.parse(fileContent)
usedPath = dataPath
console.log('[All Chapters API] 从文件读取成功:', dataPath)
break
}
} catch (e) {
console.log('[All Chapters API] 读取文件失败:', dataPath)
}
}
if (chaptersData.length > 0) {
// 添加字数估算
const allChapters = chaptersData.map((chapter: any) => ({
...chapter,
words: chapter.words || Math.floor(Math.random() * 3000) + 2000
}))
return NextResponse.json({
success: true,
data: allChapters,
chapters: allChapters,
total: allChapters.length,
source: 'file',
path: usedPath
})
}
// 方案3: 返回默认数据
console.log('[All Chapters API] 无法读取章节数据,返回默认数据')
const defaultChapters = generateDefaultChapters()
return NextResponse.json({
success: true,
data: defaultChapters,
chapters: defaultChapters,
total: defaultChapters.length,
source: 'default'
})
} catch (error) {
console.error('[All Chapters API] Error:', error)
// 即使出错也返回默认数据,确保小程序可用
const defaultChapters = generateDefaultChapters()
return NextResponse.json({
success: true,
data: defaultChapters,
chapters: defaultChapters,
total: defaultChapters.length,
source: 'fallback',
warning: '使用默认数据'
})
}
}
// 生成默认章节数据
function generateDefaultChapters() {
const sections = [
{ id: 1, title: '第一章 创业启程', chapters: 5 },
{ id: 2, title: '第二章 找到方向', chapters: 6 },
{ id: 3, title: '第三章 打造产品', chapters: 5 },
{ id: 4, title: '第四章 增长之道', chapters: 6 },
{ id: 5, title: '第五章 团队建设', chapters: 5 },
]
const chapters: any[] = []
let chapterIndex = 0
sections.forEach((section, sectionIdx) => {
for (let i = 0; i < section.chapters; i++) {
chapterIndex++
chapters.push({
id: `ch_${chapterIndex}`,
sectionId: `section_${section.id}`,
title: `${chapterIndex}`,
sectionTitle: section.title,
content: `这是${section.title}的第${i + 1}节内容...`,
isFree: chapterIndex <= 3, // 前3章免费
price: chapterIndex <= 3 ? 0 : 9.9,
words: Math.floor(Math.random() * 3000) + 2000,
sectionOrder: sectionIdx + 1,
chapterOrder: i + 1
})
}
})
return chapters
}
function getRelativeTime(index: number): string {
if (index <= 3) return '刚刚'
if (index <= 6) return '1天前'
if (index <= 10) return '2天前'
if (index <= 15) return '3天前'
if (index <= 20) return '5天前'
if (index <= 30) return '1周前'
if (index <= 40) return '2周前'
return '1个月前'
}