import '../database/app_usage_dao.dart'; import '../database/daily_stats_dao.dart'; import '../theme/app_theme.dart'; class ExportService { final AppUsageDao _appUsageDao = AppUsageDao(); final DailyStatsDao _dailyStatsDao = DailyStatsDao(); /// 导出 CSV 格式数据 Future exportToCSV({ required DateTime startDate, required DateTime endDate, }) async { final appUsages = await _appUsageDao.getAppUsages( startTime: startDate, endTime: endDate, ); final buffer = StringBuffer(); // CSV 头部 buffer.writeln('应用名称,包名,开始时间,结束时间,使用时长(秒),使用时长(格式化),分类'); // 数据行 for (final usage in appUsages) { buffer.writeln([ _escapeCsvField(usage.appName), _escapeCsvField(usage.packageName), usage.startTime.toIso8601String(), usage.endTime.toIso8601String(), usage.duration.toString(), usage.formattedDuration, AppTheme.getCategoryName(usage.category), ].join(',')); } return buffer.toString(); } /// 导出统计报告(文本格式) Future exportStatsReport({ required DateTime startDate, required DateTime endDate, }) async { final stats = await _dailyStatsDao.getStatsRange( startDate: startDate, endDate: endDate, ); final buffer = StringBuffer(); buffer.writeln('=== AutoTime Tracker 统计报告 ==='); buffer.writeln('报告时间: ${startDate.toString().split(' ')[0]} 至 ${endDate.toString().split(' ')[0]}'); buffer.writeln(''); buffer.writeln('日期统计:'); buffer.writeln(''); int totalWorkTime = 0; int totalStudyTime = 0; int totalEntertainmentTime = 0; int totalSocialTime = 0; int totalToolTime = 0; int totalTime = 0; for (final stat in stats) { buffer.writeln('${stat.date.toString().split(' ')[0]}:'); buffer.writeln(' 总时长: ${stat.formattedTotalTime}'); buffer.writeln(' 工作: ${_formatTime(stat.workTime)}'); buffer.writeln(' 学习: ${_formatTime(stat.studyTime)}'); buffer.writeln(' 娱乐: ${_formatTime(stat.entertainmentTime)}'); buffer.writeln(' 社交: ${_formatTime(stat.socialTime)}'); buffer.writeln(' 工具: ${_formatTime(stat.toolTime)}'); if (stat.efficiencyScore != null) { buffer.writeln(' 效率评分: ${stat.efficiencyScore}%'); } buffer.writeln(''); totalWorkTime += stat.workTime; totalStudyTime += stat.studyTime; totalEntertainmentTime += stat.entertainmentTime; totalSocialTime += stat.socialTime; totalToolTime += stat.toolTime; totalTime += stat.totalTime; } buffer.writeln('总计:'); buffer.writeln(' 总时长: ${_formatTime(totalTime)}'); buffer.writeln(' 工作: ${_formatTime(totalWorkTime)} (${(totalWorkTime / totalTime * 100).toStringAsFixed(1)}%)'); buffer.writeln(' 学习: ${_formatTime(totalStudyTime)} (${(totalStudyTime / totalTime * 100).toStringAsFixed(1)}%)'); buffer.writeln(' 娱乐: ${_formatTime(totalEntertainmentTime)} (${(totalEntertainmentTime / totalTime * 100).toStringAsFixed(1)}%)'); buffer.writeln(' 社交: ${_formatTime(totalSocialTime)} (${(totalSocialTime / totalTime * 100).toStringAsFixed(1)}%)'); buffer.writeln(' 工具: ${_formatTime(totalToolTime)} (${(totalToolTime / totalTime * 100).toStringAsFixed(1)}%)'); return buffer.toString(); } /// 导出今日报告 Future exportTodayReport() async { final today = DateTime.now(); final startOfDay = DateTime(today.year, today.month, today.day); final endOfDay = startOfDay.add(const Duration(days: 1)); final stats = await _dailyStatsDao.getTodayStats(); final topApps = await _appUsageDao.getTopApps( startTime: startOfDay, endTime: endOfDay, limit: 10, ); final buffer = StringBuffer(); buffer.writeln('=== AutoTime Tracker 今日报告 ==='); buffer.writeln('日期: ${today.toString().split(' ')[0]}'); buffer.writeln(''); if (stats != null) { buffer.writeln('总时长: ${stats.formattedTotalTime}'); buffer.writeln('工作: ${_formatTime(stats.workTime)}'); buffer.writeln('学习: ${_formatTime(stats.studyTime)}'); buffer.writeln('娱乐: ${_formatTime(stats.entertainmentTime)}'); buffer.writeln('社交: ${_formatTime(stats.socialTime)}'); buffer.writeln('工具: ${_formatTime(stats.toolTime)}'); if (stats.efficiencyScore != null) { buffer.writeln('效率评分: ${stats.efficiencyScore}%'); } buffer.writeln(''); } if (topApps.isNotEmpty) { buffer.writeln('Top 应用:'); for (int i = 0; i < topApps.length; i++) { final app = topApps[i]; buffer.writeln('${i + 1}. ${app.appName}: ${app.formattedDuration} (${AppTheme.getCategoryName(app.category)})'); } } return buffer.toString(); } String _escapeCsvField(String field) { if (field.contains(',') || field.contains('"') || field.contains('\n')) { return '"${field.replaceAll('"', '""')}"'; } return field; } String _formatTime(int seconds) { final hours = seconds ~/ 3600; final minutes = (seconds % 3600) ~/ 60; if (hours > 0) { return '${hours}h ${minutes}m'; } return '${minutes}m'; } }