'use client' import { useState, useEffect } from 'react' import Link from 'next/link' interface Section { id: string title: string price: number isFree: boolean status: string } interface Chapter { id: string title: string sections?: Section[] price?: number isFree?: boolean status?: string } interface Part { id: string title: string type: string chapters: Chapter[] } interface Stats { totalSections: number freeSections: number paidSections: number totalParts: number } export default function ChaptersManagement() { const [structure, setStructure] = useState([]) const [stats, setStats] = useState(null) const [loading, setLoading] = useState(true) const [expandedParts, setExpandedParts] = useState([]) const [editingSection, setEditingSection] = useState(null) const [editPrice, setEditPrice] = useState(1) useEffect(() => { loadChapters() }, []) const loadChapters = async () => { try { const response = await fetch('/api/admin/chapters') const data = await response.json() if (data.success) { setStructure(data.data.structure) setStats(data.data.stats) } } catch (error) { console.error('加载章节失败:', error) } finally { setLoading(false) } } const togglePart = (partId: string) => { setExpandedParts(prev => prev.includes(partId) ? prev.filter(id => id !== partId) : [...prev, partId] ) } const handleUpdatePrice = async (sectionId: string) => { try { const response = await fetch('/api/admin/chapters', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ action: 'updatePrice', chapterId: sectionId, data: { price: editPrice } }) }) const result = await response.json() if (result.success) { alert('价格更新成功') setEditingSection(null) loadChapters() } } catch (error) { console.error('更新价格失败:', error) } } const handleToggleFree = async (sectionId: string, currentFree: boolean) => { try { const response = await fetch('/api/admin/chapters', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ action: 'toggleFree', chapterId: sectionId, data: { isFree: !currentFree } }) }) const result = await response.json() if (result.success) { alert('状态更新成功') loadChapters() } } catch (error) { console.error('更新状态失败:', error) } } if (loading) { return (
加载中...
) } return (
{/* 导航栏 */}
← 返回

章节管理

{/* 统计卡片 */} {stats && (
{stats.totalSections}
总章节数
{stats.freeSections}
免费章节
{stats.paidSections}
付费章节
{stats.totalParts}
篇章数
)} {/* 章节列表 */}
{structure.map(part => (
{/* 篇标题 */}
togglePart(part.id)} >
{part.type === 'preface' ? '📖' : part.type === 'epilogue' ? '🎬' : part.type === 'appendix' ? '📎' : '📚'} {part.title} ({part.chapters.reduce((acc, ch) => acc + (ch.sections?.length || 1), 0)} 节)
{expandedParts.includes(part.id) ? '▲' : '▼'}
{/* 章节内容 */} {expandedParts.includes(part.id) && (
{part.chapters.map(chapter => (
{/* 章标题 */} {chapter.sections ? ( <>
{chapter.title}
{/* 小节列表 */}
{chapter.sections.map(section => (
{section.isFree ? '🔓' : '🔒'} {section.id} {section.title}
{editingSection === section.id ? (
setEditPrice(Number(e.target.value))} className="w-20 px-2 py-1 bg-white/10 border border-white/20 rounded text-white" min="0" step="0.1" />
) : ( <> {section.isFree ? '免费' : `¥${section.price}`} )}
))}
) : (
{chapter.isFree ? '🔓' : '🔒'} {chapter.title}
{chapter.isFree ? '免费' : `¥${chapter.price || 1}`}
)}
))}
)}
))}
) }