import 'package:flutter/material.dart'; import 'package:ai_english_learning/core/network/api_client.dart'; import 'package:ai_english_learning/core/services/storage_service.dart'; import 'package:ai_english_learning/features/vocabulary/models/vocabulary_book_model.dart'; import 'package:ai_english_learning/features/vocabulary/models/word_model.dart'; import 'package:ai_english_learning/features/vocabulary/models/learning_session_model.dart'; import 'package:ai_english_learning/features/vocabulary/services/learning_service.dart'; import 'package:ai_english_learning/features/vocabulary/services/vocabulary_service.dart'; import 'package:ai_english_learning/features/vocabulary/widgets/study_card_widget.dart'; class StudyScreen extends StatefulWidget { final VocabularyBook vocabularyBook; final int dailyGoal; const StudyScreen({ Key? key, required this.vocabularyBook, this.dailyGoal = 20, }) : super(key: key); @override State createState() => _StudyScreenState(); } class _StudyScreenState extends State { late LearningService _learningService; late VocabularyService _vocabularyService; bool _isLoading = true; String? _error; LearningSession? _session; DailyLearningTasks? _tasks; List _wordsList = []; int _currentIndex = 0; int _studiedCount = 0; DateTime? _studyStartTime; @override void initState() { super.initState(); _init(); } Future _init() async { final storageService = await StorageService.getInstance(); _learningService = LearningService(apiClient: ApiClient.instance); _vocabularyService = VocabularyService( apiClient: ApiClient.instance, storageService: storageService, ); await _startLearning(); } Future _startLearning() async { setState(() { _isLoading = true; _error = null; }); try { // 1. 开始学习会话 final result = await _learningService.startLearning( widget.vocabularyBook.id, widget.dailyGoal, ); _session = result['session'] as LearningSession; _tasks = result['tasks'] as DailyLearningTasks; print('✅ 学习会话创建成功'); print('📝 新单词数量: ${_tasks!.newWords.length}'); print('🔄 复习单词数量: ${_tasks!.reviewWords.length}'); // 2. 加载单词详情 - 从词汇书API获取 if (_tasks!.newWords.isEmpty && _tasks!.reviewWords.isEmpty) { setState(() { _isLoading = false; _wordsList = []; }); return; } // 合并新单词和复习单词的ID(学习逻辑:新词 + 所有到期复习词) final allWordIds = { ..._tasks!.newWords, ..._tasks!.reviewWords.map((r) => r['vocabulary_id'] as int), }; final totalWords = allWordIds.length; print('📚 今日学习任务: ${_tasks!.newWords.length}个新词 + ${_tasks!.reviewWords.length}个复习词 = $totalWords个单词'); // 使用词汇书的单词加载API - 动态设置limit以包含所有需要的单词 final limit = (totalWords / 50).ceil() * 50; // 向上取整到50的倍数 final bookWords = await _vocabularyService.getVocabularyBookWords( widget.vocabularyBook.id, page: 1, limit: limit < 100 ? 100 : limit, ); // 筛选出需要学习的单词(新词 + 复习词) final words = []; for (final bookWord in bookWords) { if (bookWord.word == null) continue; final wordId = int.tryParse(bookWord.word!.id); if (wordId != null && allWordIds.contains(wordId)) { words.add(bookWord.word!); } if (words.length >= totalWords) break; } print('✅ 加载了 ${words.length} 个单词,需要 $totalWords 个'); setState(() { _wordsList = words; _isLoading = false; _studyStartTime = DateTime.now(); }); } catch (e, stackTrace) { print('❌ 开始学习失败: $e'); print('Stack trace: $stackTrace'); setState(() { _error = '加载学习内容失败,请稍后重试\n错误:$e'; _isLoading = false; }); } } Future _handleAnswer(StudyDifficulty difficulty) async { if (_currentIndex >= _wordsList.length) return; final word = _wordsList[_currentIndex]; final studyTime = _studyStartTime != null ? DateTime.now().difference(_studyStartTime!).inMilliseconds : 0; try { // 提交学习结果 await _learningService.submitWordStudy( word.id, difficulty, sessionId: int.tryParse(_session?.id ?? '0'), ); setState(() { _studiedCount++; _currentIndex++; _studyStartTime = DateTime.now(); }); // 检查是否完成 if (_currentIndex >= _wordsList.length) { _showCompletionDialog(); } } catch (e) { print('提交学习结果失败: $e'); ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('提交失败,请重试')), ); } } void _showCompletionDialog() { showDialog( context: context, barrierDismissible: false, builder: (context) => AlertDialog( title: const Text('🎉 今日学习完成!'), content: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('学习单词数:$_studiedCount'), Text('新学单词:${_tasks?.newWords.length ?? 0}'), Text('复习单词:${_tasks?.reviewWords.length ?? 0}'), ], ), actions: [ TextButton( onPressed: () { Navigator.of(context).pop(); Navigator.of(context).pop(true); // 返回到上一页 }, child: const Text('完成'), ), ], ), ); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(widget.vocabularyBook.name), actions: [ // 进度显示 Center( child: Padding( padding: const EdgeInsets.only(right: 16), child: Text( '$_studiedCount / ${_wordsList.length}', style: const TextStyle( fontSize: 16, fontWeight: FontWeight.bold, ), ), ), ), ], ), body: _buildBody(), ); } Widget _buildBody() { if (_isLoading) { return const Center(child: CircularProgressIndicator()); } if (_error != null) { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(Icons.error_outline, size: 64, color: Colors.grey[400]), const SizedBox(height: 16), Text( _error!, style: TextStyle(fontSize: 16, color: Colors.grey[600]), ), const SizedBox(height: 16), ElevatedButton( onPressed: _startLearning, child: const Text('重试'), ), ], ), ); } if (_wordsList.isEmpty) { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(Icons.check_circle, size: 64, color: Colors.green[400]), const SizedBox(height: 16), const Text( '今日任务已完成!', style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold), ), const SizedBox(height: 8), Text( '明天继续加油!', style: TextStyle(fontSize: 16, color: Colors.grey[600]), ), const SizedBox(height: 24), ElevatedButton( onPressed: () => Navigator.of(context).pop(), child: const Text('返回'), ), ], ), ); } if (_currentIndex >= _wordsList.length) { return const Center(child: CircularProgressIndicator()); } return Column( children: [ // 进度条 LinearProgressIndicator( value: _currentIndex / _wordsList.length, backgroundColor: Colors.grey[200], ), // 学习卡片 Expanded( child: Padding( padding: const EdgeInsets.all(16), child: StudyCardWidget( word: _wordsList[_currentIndex], onAnswer: _handleAnswer, ), ), ), ], ); } }