import 'dart:convert'; import 'dart:io'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:path_provider/path_provider.dart'; import 'package:share_plus/share_plus.dart'; import '../../controllers/history_controller.dart' as history_controller; class HistoryController extends GetxController { var historyList = >[].obs; var filteredHistoryList = >[].obs; var isLoading = true.obs; var searchKeyword = ''.obs; var selectedSortType = 0.obs; // 0: 时间倒序, 1: 时间正序, 2: 按名称排序 var currentPage = 1.obs; var totalPages = 1.obs; var pageSize = 20; var totalCount = 0.obs; final List sortTypes = ['时间倒序', '时间正序', '按名称排序']; @override void onInit() { super.onInit(); loadHistory(); } // === 加载历史记录 === Future loadHistory() async { isLoading.value = true; try { final history = await history_controller.HistoryController.getHistory(); historyList.value = history; totalCount.value = history.length; totalPages.value = (totalCount.value / pageSize).ceil(); filterAndSortHistory(); } catch (e) { print('加载历史记录失败: $e'); } finally { isLoading.value = false; } } // === 搜索历史记录 === void searchHistory(String keyword) { searchKeyword.value = keyword; currentPage.value = 1; filterAndSortHistory(); } // === 排序历史记录 === void sortHistory(int sortType) { selectedSortType.value = sortType; currentPage.value = 1; filterAndSortHistory(); } // === 过滤和排序历史记录 === void filterAndSortHistory() { var filtered = historyList; // 搜索过滤 if (searchKeyword.value.isNotEmpty) { filtered = historyList .where((item) { final name = item['name']?.toString().toLowerCase() ?? ''; final alias = item['alias']?.toString().toLowerCase() ?? ''; final introduce = item['introduce']?.toString().toLowerCase() ?? ''; final keyword = searchKeyword.value.toLowerCase(); return name.contains(keyword) || alias.contains(keyword) || introduce.contains(keyword); }) .toList() .obs; } // 排序 final sortedList = List>.from(filtered); switch (selectedSortType.value) { 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; } totalCount.value = sortedList.length; totalPages.value = (totalCount.value / pageSize).ceil(); filteredHistoryList.value = sortedList; } // === 获取当前页的数据 === List> getCurrentPageData() { final startIndex = (currentPage.value - 1) * pageSize; final endIndex = startIndex + pageSize; if (startIndex >= filteredHistoryList.length) { return []; } return filteredHistoryList.sublist( startIndex, endIndex > filteredHistoryList.length ? filteredHistoryList.length : endIndex, ); } // === 切换到下一页 === void nextPage() { if (currentPage.value < totalPages.value) { currentPage.value++; } } // === 切换到上一页 === void previousPage() { if (currentPage.value > 1) { currentPage.value--; } } // === 跳转到指定页 === void goToPage(int page) { if (page >= 1 && page <= totalPages.value) { currentPage.value = page; } } // === 清空历史记录 === Future clearHistory() async { try { final success = await history_controller.HistoryController.clearHistory(); if (success) { historyList.clear(); filteredHistoryList.clear(); totalCount.value = 0; totalPages.value = 1; currentPage.value = 1; Get.snackbar('提示', '历史记录已清空'); } else { Get.snackbar('提示', '清空失败'); } } catch (e) { print('清空历史记录失败: $e'); Get.snackbar('提示', '清空失败'); } } // === 删除单条记录 === Future deleteHistoryItem(int index, Map item) async { try { final poetryId = item['id'] as int; final success = await history_controller .HistoryController.removeFromHistory(poetryId); if (success) { await loadHistory(); Get.snackbar('提示', '删除成功'); } else { Get.snackbar('提示', '删除失败'); } } catch (e) { Get.snackbar('提示', '删除失败'); } } // === 导出历史记录 === Future exportHistory() async { try { if (filteredHistoryList.isEmpty) { Get.snackbar('提示', '无数据可导出'); return; } // 显示格式选择对话框 final selectedFormat = await Get.dialog( CupertinoAlertDialog( title: const Text('选择导出格式'), content: const Text('请选择要导出的文件格式'), actions: [ CupertinoDialogAction( child: const Text('JSON'), onPressed: () => Get.back(result: 'json'), ), CupertinoDialogAction( child: const Text('TXT'), onPressed: () => Get.back(result: 'txt'), ), CupertinoDialogAction( isDestructiveAction: true, child: const Text('取消'), onPressed: () => Get.back(result: null), ), ], ), ); if (selectedFormat == null) { return; // 用户取消 } // 生成导出内容 String content; String fileName; if (selectedFormat == 'json') { content = _generateJsonContent(); fileName = 'history_export_${DateTime.now().millisecondsSinceEpoch}.json'; } else { content = _generateTxtContent(); fileName = 'history_export_${DateTime.now().millisecondsSinceEpoch}.txt'; } // 保存到临时文件 final tempDir = await getTemporaryDirectory(); final file = File('${tempDir.path}/$fileName'); await file.writeAsString(content); // 使用 share_plus 分享文件 final result = await Share.shareXFiles( [XFile(file.path)], subject: '历史记录导出', text: '诗词历史记录导出文件', ); if (result.status == ShareResultStatus.success) { Get.snackbar('成功', '历史记录已导出并分享'); } else if (result.status == ShareResultStatus.dismissed) { Get.snackbar('提示', '分享已取消'); } // 清理临时文件 if (await file.exists()) { await file.delete(); } } catch (e) { print('导出历史记录失败: $e'); Get.snackbar('错误', '导出失败: $e'); } } // === 生成 JSON 格式内容 === String _generateJsonContent() { final exportData = { 'exportTime': DateTime.now().toIso8601String(), 'totalCount': filteredHistoryList.length, 'records': filteredHistoryList .map( (item) => { 'id': item['id'], 'name': item['name'], 'alias': item['alias'], 'date': item['date'], 'introduce': item['introduce'], 'timestamp': item['timestamp'], }, ) .toList(), }; return const JsonEncoder.withIndent(' ').convert(exportData); } // === 生成 TXT 格式内容 === String _generateTxtContent() { final buffer = StringBuffer(); buffer.writeln('诗词历史记录导出'); buffer.writeln('导出时间: ${DateTime.now()}'); buffer.writeln('记录总数: ${filteredHistoryList.length}'); buffer.writeln('=' * 50); buffer.writeln(); for (int i = 0; i < filteredHistoryList.length; i++) { final item = filteredHistoryList[i]; buffer.writeln('【${i + 1}】${item['name'] ?? '未知诗词'}'); buffer.writeln('朝代: ${item['alias'] ?? '未知朝代'}'); buffer.writeln('日期: ${item['date'] ?? ''}'); if (item['introduce']?.toString().isNotEmpty == true) { buffer.writeln('简介: ${item['introduce']}'); } buffer.writeln('-' * 50); buffer.writeln(); } return buffer.toString(); } // === 获取历史记录统计 === Future showStatsDialog() async { try { final stats = await history_controller.HistoryController.getHistoryStats(); if (stats.isEmpty) { Get.snackbar('提示', '暂无统计数据'); return; } Get.dialog( 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: () => Get.back(), child: const Text('关闭')), ], ), ); } catch (e) { Get.snackbar('提示', '获取统计失败'); } } }