/// 时间: 2025-03-21 /// 功能: 历史记录页面 /// 介绍: 独立的历史记录管理页面,支持查看、搜索、删除和导出功能 /// 最新变化: 新创建文件,实现历史记录的独立页面功能 import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import '../../constants/app_constants.dart'; import '../../controllers/history_controller.dart'; import '../../utils/flutter_compatibility_fix.dart'; class HistoryPage extends StatefulWidget { const HistoryPage({super.key}); @override State createState() => _HistoryPageState(); } class _HistoryPageState extends State { List> _historyList = []; List> _filteredHistoryList = []; bool _isLoading = true; String _searchKeyword = ''; int _selectedSortType = 0; // 0: 时间倒序, 1: 时间正序, 2: 按名称排序 final List _sortTypes = ['时间倒序', '时间正序', '按名称排序']; @override void initState() { super.initState(); _loadHistory(); } // === 加载历史记录 === Future _loadHistory() async { setState(() { _isLoading = true; }); try { final history = await HistoryController.getHistory(); setState(() { _historyList = history; _filteredHistoryList = history; _isLoading = false; }); } catch (e) { print('加载历史记录失败: $e'); setState(() { _isLoading = false; }); } } // === 搜索历史记录 === void _searchHistory(String keyword) { setState(() { _searchKeyword = keyword; }); if (keyword.isEmpty) { setState(() { _filteredHistoryList = _historyList; }); return; } _performSearch(keyword); } Future _performSearch(String keyword) async { try { final searchResults = await HistoryController.searchHistory(keyword); setState(() { _filteredHistoryList = searchResults; }); } catch (e) { print('搜索历史记录失败: $e'); } } // === 排序历史记录 === void _sortHistory(int sortType) { setState(() { _selectedSortType = sortType; }); final sortedList = List>.from(_filteredHistoryList); switch (sortType) { case 0: // 时间倒序 sortedList.sort((a, b) => (b['timestamp'] ?? 0).compareTo(a['timestamp'] ?? 0)); break; case 1: // 时间正序 sortedList.sort((a, b) => (a['timestamp'] ?? 0).compareTo(b['timestamp'] ?? 0)); break; case 2: // 按名称排序 sortedList.sort((a, b) => (a['name'] ?? '').compareTo(b['name'] ?? '')); break; } setState(() { _filteredHistoryList = sortedList; }); } // === 清空历史记录 === Future _clearHistory() async { final confirmed = await _showConfirmDialog( '清空历史记录', '确定要清空所有历史记录吗?此操作不可撤销。', ); if (confirmed == null || !confirmed) return; try { final success = await HistoryController.clearHistory(); if (success) { setState(() { _historyList.clear(); _filteredHistoryList.clear(); }); _showSnackBar('历史记录已清空'); } else { _showSnackBar('清空失败'); } } catch (e) { print('清空历史记录失败: $e'); _showSnackBar('清空失败'); } } // === 删除单条记录 === Future _deleteHistoryItem(int index, Map item) async { final confirmed = await _showConfirmDialog( '删除记录', '确定要删除这条历史记录吗?', ); if (confirmed == null || !confirmed) return; try { final poetryId = item['id'] as int; final success = await HistoryController.removeFromHistory(poetryId); if (success) { // 重新加载历史记录,避免索引不匹配问题 await _loadHistory(); _showSnackBar('删除成功'); } else { _showSnackBar('删除失败'); } } catch (e) { print('删除历史记录失败: $e'); _showSnackBar('删除失败'); } } // === 导出历史记录 === Future _exportHistory() async { try { final exportData = await HistoryController.exportHistory(format: 'json'); if (exportData.isNotEmpty) { // 这里可以实现文件保存功能 _showSnackBar('导出功能开发中...'); } else { _showSnackBar('无数据可导出'); } } catch (e) { print('导出历史记录失败: $e'); _showSnackBar('导出失败'); } } // === 显示确认对话框 === Future _showConfirmDialog(String title, String content) async { return await showDialog( context: context, builder: (context) => AlertDialog( title: Text(title), content: Text(content), actions: [ TextButton( onPressed: () => Navigator.pop(context, false), child: const Text('取消'), ), TextButton( onPressed: () => Navigator.pop(context, true), child: const Text('确定'), ), ], ), ); } // === 显示历史记录统计 === void _showStatsDialog() async { try { final stats = await HistoryController.getHistoryStats(); if (stats.isEmpty) { _showSnackBar('暂无统计数据'); return; } showDialog( context: context, builder: (context) => AlertDialog( title: const Text('历史记录统计'), content: SingleChildScrollView( child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('总数: ${stats['totalCount']}'), Text('今日: ${stats['todayCount']}'), Text('本周: ${stats['thisWeekCount']}'), Text('本月: ${stats['thisMonthCount']}'), const SizedBox(height: 16), const Text('热门朝代:'), if (stats['topDynasties'] != null && stats['topDynasties'] is Map) ...[ ...(stats['topDynasties'] as Map).entries .map((entry) => Text('${entry.key}: ${entry.value}')) .toList(), ], ], ), ), actions: [ TextButton( onPressed: () => Navigator.pop(context), child: const Text('关闭'), ), ], ), ); } catch (e) { print('获取统计失败: $e'); _showSnackBar('获取统计失败'); } } void _showSnackBar(String message) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text(message), backgroundColor: AppConstants.primaryColor, duration: const Duration(seconds: 2), ), ); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: const Color(0xFFF5F5F5), appBar: _buildAppBar(), body: Column( children: [ _buildSearchBar(), _buildSortOptions(), Expanded( child: _isLoading ? _buildLoadingWidget() : _filteredHistoryList.isEmpty ? _buildEmptyWidget() : _buildHistoryList(), ), ], ), ); } // === 顶部导航栏 === PreferredSizeWidget _buildAppBar() { return AppBar( title: Text( '历史记录', style: TextStyle( color: AppConstants.primaryColor, fontWeight: FontWeight.bold, ), ), backgroundColor: Colors.white, elevation: 0, centerTitle: true, actions: [ IconButton( icon: Icon( Icons.delete_sweep, color: AppConstants.primaryColor, ), onPressed: _historyList.isEmpty ? null : _clearHistory, ), IconButton( icon: Icon( Icons.bar_chart, color: AppConstants.primaryColor, ), onPressed: _showStatsDialog, ), IconButton( icon: Icon( Icons.file_download, color: AppConstants.primaryColor, ), onPressed: _exportHistory, ), ], ); } // === 搜索栏 === Widget _buildSearchBar() { return Container( padding: const EdgeInsets.all(16), child: TextField( onChanged: _searchHistory, decoration: InputDecoration( hintText: '搜索历史记录...', prefixIcon: const Icon(Icons.search), suffixIcon: _searchKeyword.isNotEmpty ? IconButton( icon: const Icon(Icons.clear), onPressed: () => _searchHistory(''), ) : null, border: OutlineInputBorder( borderRadius: BorderRadius.circular(25), borderSide: BorderSide(color: Colors.grey[300]!), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(25), borderSide: BorderSide(color: AppConstants.primaryColor), ), filled: true, fillColor: Colors.white, contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), ), ), ); } // === 排序选项 === Widget _buildSortOptions() { return Container( padding: const EdgeInsets.symmetric(horizontal: 16), child: Row( children: [ const Text('排序方式:'), const SizedBox(width: 16), Expanded( child: Container( padding: const EdgeInsets.symmetric(horizontal: 12), decoration: BoxDecoration( border: Border.all(color: Colors.grey[300]!), borderRadius: BorderRadius.circular(20), ), child: DropdownButton( value: _sortTypes[_selectedSortType], isExpanded: true, underline: Container(), items: _sortTypes.map((type) { return DropdownMenuItem( value: type, child: Text(type), ); }).toList(), onChanged: (value) { if (value != null) { _sortHistory(_sortTypes.indexOf(value!)); } }, ), ), ), ], ), ); } // === 加载状态 === Widget _buildLoadingWidget() { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ CircularProgressIndicator(), SizedBox(height: 16), Text( '加载历史记录...', style: TextStyle( fontSize: 16, color: Colors.grey[600]!, ), ), ], ), ); } // === 空状态 === Widget _buildEmptyWidget() { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( Icons.history, size: 64, color: Colors.grey[400]!, ), SizedBox(height: 16), Text( '暂无历史记录', style: TextStyle( fontSize: 16, color: Colors.grey[600]!, ), ), SizedBox(height: 16), ElevatedButton( onPressed: () => Navigator.pop(context), style: ElevatedButton.styleFrom( backgroundColor: AppConstants.primaryColor, ), child: Text('返回'), ), ], ), ); } // === 历史记录列表 === Widget _buildHistoryList() { return ListView.builder( padding: const EdgeInsets.all(16), itemCount: _filteredHistoryList.length, itemBuilder: (context, index) { final item = _filteredHistoryList[index]; return Card( margin: const EdgeInsets.only(bottom: 8), child: ListTile( leading: CircleAvatar( radius: 20, backgroundColor: AppConstants.primaryColor.withOpacity(0.1), child: Text( '${index + 1}', style: TextStyle( fontSize: 12, color: AppConstants.primaryColor, fontWeight: FontWeight.bold, ), ), ), title: Text( item['name'] ?? '未知诗词', style: const TextStyle( fontSize: 14, fontWeight: FontWeight.w500, ), maxLines: 2, overflow: TextOverflow.ellipsis, ), subtitle: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( '${item['alias'] ?? '未知朝代'} • ${item['date'] ?? ''}', style: const TextStyle( fontSize: 12, color: Colors.grey, ), ), if (item['introduce']?.toString().isNotEmpty == true) Text( item['introduce']?.toString() ?? '', style: TextStyle( fontSize: 11, color: Colors.grey[600]!, ), maxLines: 2, overflow: TextOverflow.ellipsis, ), ], ), trailing: PopupMenuButton( onSelected: (value) { switch (value) { case 'delete': _deleteHistoryItem(index, item); break; case 'share': _showSnackBar('分享功能开发中...'); break; case 'view': _showSnackBar('查看详情功能开发中...'); break; } }, itemBuilder: (context) => [ const PopupMenuItem( value: 'delete', child: Row( children: [ Icon(Icons.delete, color: Colors.red), SizedBox(width: 8), Text('删除'), ], ), ), const PopupMenuItem( value: 'share', child: Row( children: [ Icon(Icons.share, color: AppConstants.primaryColor), SizedBox(width: 8), Text('分享'), ], ), ), const PopupMenuItem( value: 'view', child: Row( children: [ Icon(Icons.visibility, color: AppConstants.primaryColor), SizedBox(width: 8), Text('查看'), ], ), ), ], ), onTap: () { // 可以添加点击查看详情的功能 HapticFeedback.lightImpact(); }, ), ); }, ); } }