import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import '../providers/app_provider.dart'; import '../models/data_models.dart'; import '../utils/app_theme.dart'; /// 书籍详情页 class BookDetailPage extends StatefulWidget { final Book book; const BookDetailPage({super.key, required this.book}); @override State createState() => _BookDetailPageState(); } class _BookDetailPageState extends State { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(widget.book.title), actions: [ IconButton( icon: const Icon(Icons.edit), onPressed: () => _navigateToEdit(context), ), IconButton( icon: const Icon(Icons.delete_outline), onPressed: () => _showDeleteDialog(context), ), ], ), body: SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // 封面区域 _buildCoverSection(context), // 基本信息 _buildInfoSection(context), // 笔记区域 if (widget.book.note != null && widget.book.note!.isNotEmpty) _buildNoteSection(context), ], ), ), ); } /// 构建封面区域 Widget _buildCoverSection(BuildContext context) { return Container( width: double.infinity, height: 250, decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.topLeft, end: Alignment.bottomRight, colors: [ Theme.of(context).colorScheme.primaryContainer, Theme.of(context).colorScheme.surface, ], ), ), child: Stack( children: [ Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( Icons.menu_book, size: 80, color: Theme.of(context).colorScheme.primary.withOpacity(0.6), ), const SizedBox(height: 16), Text( widget.book.title, style: Theme.of(context).textTheme.headlineSmall?.copyWith( fontWeight: FontWeight.bold, color: Theme.of(context).colorScheme.onSurface, ), textAlign: TextAlign.center, maxLines: 2, overflow: TextOverflow.ellipsis, ), ], ), ), Positioned( top: 16, right: 16, child: _buildStatusTag(context), ), ], ), ); } /// 构建状态标签 Widget _buildStatusTag(BuildContext context) { Color statusColor; String statusText; switch (widget.book.status) { case 'read': statusColor = AppTheme.readColor; statusText = '读完'; break; case 'reading': statusColor = AppTheme.readingColor; statusText = '在读'; break; case 'want_to_read': statusColor = AppTheme.wantToReadColor; statusText = '准备读'; break; default: statusColor = Colors.grey; statusText = '未知'; } return Container( padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6), decoration: BoxDecoration( color: statusColor.withOpacity(0.9), borderRadius: BorderRadius.circular(20), ), child: Text( statusText, style: const TextStyle( fontSize: 14, color: Colors.white, fontWeight: FontWeight.bold, ), ), ); } /// 构建信息区域 Widget _buildInfoSection(BuildContext context) { return Padding( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // 作者 if (widget.book.author != null && widget.book.author!.isNotEmpty) ...[ _buildInfoItem( context, icon: Icons.person, label: widget.book.author!, ), const SizedBox(height: 12), ], // 评分 if (widget.book.rating != null) ...[ _buildInfoItem( context, icon: Icons.star, label: widget.book.rating.toString(), iconColor: Colors.amber[700], textColor: Colors.amber[700], ), const SizedBox(height: 12), ], // 阅读日期 if (widget.book.readDate != null) _buildInfoItem( context, icon: Icons.event, label: '阅读日期:${_formatDate(widget.book.readDate!)}', ), ], ), ); } /// 构建信息项 Widget _buildInfoItem( BuildContext context, { required IconData icon, required String label, Color? iconColor, Color? textColor, }) { return Row( mainAxisSize: MainAxisSize.min, children: [ Icon(icon, size: 18, color: iconColor), const SizedBox(width: 4), Text( label, style: TextStyle( fontSize: 14, color: textColor ?? Theme.of(context).colorScheme.onSurfaceVariant, ), ), ], ); } /// 构建笔记区域 Widget _buildNoteSection(BuildContext context) { return Container( margin: const EdgeInsets.all(16), padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: Theme.of(context).colorScheme.surfaceContainerHighest, borderRadius: BorderRadius.circular(12), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Icon( Icons.edit_note, size: 20, color: Theme.of(context).colorScheme.primary, ), const SizedBox(width: 8), Text( '笔记', style: Theme.of(context).textTheme.titleMedium?.copyWith( fontWeight: FontWeight.bold, ), ), ], ), const SizedBox(height: 12), Text( widget.book.note!, style: Theme.of(context).textTheme.bodyMedium, ), ], ), ); } /// 格式化日期 String _formatDate(DateTime date) { return '${date.year}-${date.month.toString().padLeft(2, '0')}-${date.day.toString().padLeft(2, '0')}'; } /// 跳转到编辑页面 void _navigateToEdit(BuildContext context) { Navigator.pushNamed(context, '/book-form', arguments: widget.book).then((_) { context.read().loadBooks(); }); } /// 显示删除对话框 void _showDeleteDialog(BuildContext context) { showDialog( context: context, builder: (context) => AlertDialog( title: const Text('确认删除'), content: Text('确定要删除"${widget.book.title}"吗?此操作不可恢复。'), actions: [ TextButton( onPressed: () => Navigator.pop(context), child: const Text('取消'), ), TextButton( onPressed: () async { await context.read().removeBook(widget.book.id); if (!mounted) return; Navigator.pop(context); Navigator.pop(context); ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('已删除'), behavior: SnackBarBehavior.floating, ), ); }, child: const Text( '删除', style: TextStyle(color: Colors.red), ), ), ], ), ); } }