import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../models/writing_task.dart'; import 'writing_exercise_screen.dart'; import '../providers/writing_provider.dart'; /// 写作练习详情页面 class WritingDetailScreen extends ConsumerWidget { final WritingTask task; const WritingDetailScreen({ super.key, required this.task, }); @override Widget build(BuildContext context, WidgetRef ref) { return Scaffold( backgroundColor: const Color(0xFFF5F5F5), appBar: AppBar( title: const Text('写作详情'), backgroundColor: Colors.white, foregroundColor: Colors.black, elevation: 0, ), body: SingleChildScrollView( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ _buildTaskHeader(), const SizedBox(height: 20), _buildTaskInfo(), const SizedBox(height: 20), _buildPrompt(), const SizedBox(height: 20), _buildRequirements(), if (task.keywords.isNotEmpty) ...[ const SizedBox(height: 20), _buildKeywords(), ], const SizedBox(height: 30), _buildStartButton(context, ref), ], ), ), ); } Widget _buildTaskHeader() { return Container( padding: const EdgeInsets.all(20), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(16), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.05), blurRadius: 10, offset: const Offset(0, 2), ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Expanded( child: Text( task.title, style: const TextStyle( fontSize: 24, fontWeight: FontWeight.bold, ), ), ), Container( padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6), decoration: BoxDecoration( color: _getDifficultyColor(task.difficulty), borderRadius: BorderRadius.circular(16), ), child: Text( task.difficulty.displayName, style: const TextStyle( fontSize: 14, color: Colors.white, fontWeight: FontWeight.bold, ), ), ), ], ), const SizedBox(height: 12), Text( task.description, style: const TextStyle( fontSize: 16, color: Colors.grey, height: 1.5, ), ), ], ), ); } Widget _buildTaskInfo() { return Container( padding: const EdgeInsets.all(20), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(16), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.05), blurRadius: 10, offset: const Offset(0, 2), ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( '任务信息', style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, ), ), const SizedBox(height: 16), Row( children: [ Expanded( child: _buildInfoItem( Icons.category, '类型', task.type.displayName, const Color(0xFF2196F3), ), ), Expanded( child: _buildInfoItem( Icons.timer, '时间限制', '${task.timeLimit}分钟', const Color(0xFF4CAF50), ), ), ], ), const SizedBox(height: 16), Row( children: [ Expanded( child: _buildInfoItem( Icons.text_fields, '字数要求', '${task.wordLimit}词', const Color(0xFFFF9800), ), ), Expanded( child: _buildInfoItem( Icons.star, '难度等级', '${task.difficulty.level}级', _getDifficultyColor(task.difficulty), ), ), ], ), ], ), ); } Widget _buildInfoItem(IconData icon, String label, String value, Color color) { return Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: color.withOpacity(0.1), borderRadius: BorderRadius.circular(12), ), child: Column( children: [ Icon( icon, color: color, size: 24, ), const SizedBox(height: 8), Text( label, style: const TextStyle( fontSize: 12, color: Colors.grey, ), ), const SizedBox(height: 4), Text( value, style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, color: color, ), ), ], ), ); } Widget _buildPrompt() { return Container( padding: const EdgeInsets.all(20), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(16), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.05), blurRadius: 10, offset: const Offset(0, 2), ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( '写作提示', style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, ), ), const SizedBox(height: 12), Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: const Color(0xFF2196F3).withOpacity(0.1), borderRadius: BorderRadius.circular(12), border: Border.all( color: const Color(0xFF2196F3).withOpacity(0.3), ), ), child: Text( task.prompt ?? '暂无写作提示', style: const TextStyle( fontSize: 16, height: 1.6, ), ), ), ], ), ); } Widget _buildRequirements() { return Container( padding: const EdgeInsets.all(20), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(16), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.05), blurRadius: 10, offset: const Offset(0, 2), ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( '写作要求', style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, ), ), const SizedBox(height: 12), ...task.requirements.map((requirement) => Padding( padding: const EdgeInsets.only(bottom: 8), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Icon( Icons.check_circle, color: Color(0xFF4CAF50), size: 20, ), const SizedBox(width: 8), Expanded( child: Text( requirement, style: const TextStyle( fontSize: 14, height: 1.5, ), ), ), ], ), )).toList(), ], ), ); } Widget _buildKeywords() { return Container( padding: const EdgeInsets.all(20), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(16), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.05), blurRadius: 10, offset: const Offset(0, 2), ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( '关键词提示', style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, ), ), const SizedBox(height: 12), Wrap( spacing: 8, runSpacing: 8, children: task.keywords.map((keyword) => Container( padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6), decoration: BoxDecoration( color: const Color(0xFFFF9800).withOpacity(0.1), borderRadius: BorderRadius.circular(16), border: Border.all( color: const Color(0xFFFF9800).withOpacity(0.3), ), ), child: Text( keyword, style: const TextStyle( fontSize: 14, color: Color(0xFFFF9800), fontWeight: FontWeight.w500, ), ), )).toList(), ), ], ), ); } Widget _buildStartButton(BuildContext context, WidgetRef ref) { return SizedBox( width: double.infinity, height: 56, child: ElevatedButton( onPressed: () async { showDialog( context: context, barrierDismissible: false, builder: (context) => const Center(child: CircularProgressIndicator()), ); try { final service = ref.read(writingServiceProvider); final freshTask = await service.getWritingTask(task.id); Navigator.pop(context); Navigator.push( context, MaterialPageRoute( builder: (context) => WritingExerciseScreen(task: freshTask), ), ); } catch (e) { Navigator.pop(context); showDialog( context: context, builder: (context) => AlertDialog( title: const Text('加载失败'), content: const Text('无法获取最新任务,稍后重试'), actions: [ TextButton( onPressed: () => Navigator.pop(context), child: const Text('确定'), ), ], ), ); } }, style: ElevatedButton.styleFrom( backgroundColor: const Color(0xFF2196F3), foregroundColor: Colors.white, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(16), ), elevation: 0, ), child: const Text( '开始写作', style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, ), ), ), ); } Color _getDifficultyColor(WritingDifficulty difficulty) { switch (difficulty) { case WritingDifficulty.beginner: return const Color(0xFF4CAF50); case WritingDifficulty.elementary: return const Color(0xFF8BC34A); case WritingDifficulty.intermediate: return const Color(0xFFFF9800); case WritingDifficulty.upperIntermediate: return const Color(0xFFFF5722); case WritingDifficulty.advanced: return const Color(0xFFF44336); } } }