163 lines
4.9 KiB
TypeScript
163 lines
4.9 KiB
TypeScript
import { NextResponse } from 'next/server'
|
|
import fs from 'fs'
|
|
import path from 'path'
|
|
import { query } from '@/lib/db'
|
|
|
|
export async function GET() {
|
|
try {
|
|
// 方案1: 优先从数据库读取章节数据
|
|
try {
|
|
const dbChapters = await query(`
|
|
SELECT
|
|
id, section_id, title, section_title, content,
|
|
is_free, price, words, section_order, chapter_order,
|
|
created_at, updated_at
|
|
FROM sections
|
|
ORDER BY section_order ASC, chapter_order ASC
|
|
`) as any[]
|
|
|
|
if (dbChapters && dbChapters.length > 0) {
|
|
console.log('[All Chapters API] 从数据库读取成功,共', dbChapters.length, '章')
|
|
|
|
// 格式化数据
|
|
const allChapters = dbChapters.map((chapter: any) => ({
|
|
id: chapter.id,
|
|
sectionId: chapter.section_id,
|
|
title: chapter.title,
|
|
sectionTitle: chapter.section_title,
|
|
content: chapter.content,
|
|
isFree: !!chapter.is_free,
|
|
price: chapter.price || 0,
|
|
words: chapter.words || Math.floor(Math.random() * 3000) + 2000,
|
|
sectionOrder: chapter.section_order,
|
|
chapterOrder: chapter.chapter_order,
|
|
createdAt: chapter.created_at,
|
|
updatedAt: chapter.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个月前'
|
|
}
|