import 'dart:io'; import 'package:archive/archive_io.dart'; import 'package:path_provider/path_provider.dart'; import 'package:intl/intl.dart'; import 'package:share_plus/share_plus.dart'; import 'dart:convert'; class DailyLogUtils { // 获取当天日志文件路径 static Future _getLogFile() async { final dir = await getApplicationDocumentsDirectory(); final date = DateFormat('yyyy-MM-dd').format(DateTime.now()); final file = File('${dir.path}/$date.log'); if (!await file.exists()) { await file.create(recursive: true); } return file; } // 写日志核心方法,带日志等级,固定 UTF-8 static Future _writeLogWithLevel(String level, String content) async { final file = await _getLogFile(); final now = DateTime.now(); final time = DateFormat('HH:mm:ss').format(now); final logLine = '[$time][$level] $content\n'; await file.writeAsString(logLine, mode: FileMode.append, encoding: utf8); } // Info 日志 static Future writeLog(String content) async { print("[dailylog-->info] $content"); await _writeLogWithLevel('INFO', content); } // Warning 日志 static Future writeWarning(String content) async { print("[dailylog-->warning] $content"); await _writeLogWithLevel('WARNING', content); } // Error 日志 static Future writeError(String content) async { print("[dailylog-->error] $content"); await _writeLogWithLevel('ERROR', content); } // Debug 日志 static Future writeDebug(String content) async { print("[dailylog-->debug] $content"); await _writeLogWithLevel('DEBUG', content); } // 读取当天日志,容错 UTF-8 static Future readTodayLog() async { final file = await _getLogFile(); try { return await file.readAsString(encoding: utf8); } catch (e) { final bytes = await file.readAsBytes(); return utf8.decode(bytes, allowMalformed: true); } } // 获取所有日志文件 static Future> listLogFiles() async { final dir = await getApplicationDocumentsDirectory(); final files = dir.listSync(); return files.where((f) => f.path.endsWith('.log')).toList(); } // 清除所有日志 static Future clearAllLogs() async { final files = await listLogFiles(); for (final f in files) { await File(f.path).delete(); } } // 获取指定日期范围内日志文件 static Future> getLogsBetween( DateTime fromDate, DateTime toDate) async { final dir = await getApplicationDocumentsDirectory(); final logFiles = []; final dateFormat = DateFormat('yyyy-MM-dd'); for (DateTime date = fromDate; !date.isAfter(toDate); date = date.add(Duration(days: 1))) { final file = File('${dir.path}/${dateFormat.format(date)}.log'); if (await file.exists()) logFiles.add(file); } return logFiles; } // 读取日期范围内日志,合并返回 static Future readLogsByDateRange( DateTime fromDate, DateTime toDate) async { try { final dir = await getApplicationDocumentsDirectory(); final dateFormat = DateFormat('yyyy-MM-dd'); String combinedLogs = ''; for (DateTime date = fromDate; !date.isAfter(toDate); date = date.add(Duration(days: 1))) { final file = File('${dir.path}/${dateFormat.format(date)}.log'); if (await file.exists()) { String content; try { content = await file.readAsString(encoding: utf8); } catch (_) { final bytes = await file.readAsBytes(); content = utf8.decode(bytes, allowMalformed: true); } combinedLogs += '日志日期: ${dateFormat.format(date)}\n$content\n\n'; } } return combinedLogs.isNotEmpty ? combinedLogs : '该时间段内没有日志记录'; } catch (e) { return '读取日志失败: $e'; } } // 导出所有日志为 zip 并分享(系统分享) static Future exportAllLogs() async { try { final dir = await getApplicationDocumentsDirectory(); final dateStr = DateFormat('yyyy-MM-dd_HH-mm-ss').format(DateTime.now()); final zipPath = '${dir.path}/logs_$dateStr.zip'; final archive = Archive(); // 遍历日志文件 final logFiles = dir .listSync() .whereType() .where((f) => f.path.endsWith('.log') && f.existsSync()); if (logFiles.isEmpty) { print("没有日志文件可压缩!"); return; } for (var file in logFiles) { final name = file.path.split('/').last; final bytes = await file.readAsBytes(); // 读取原始字节 final content = utf8.decode(bytes, allowMalformed: true); // 转 UTF-8,允许非 UTF-8 final utf8Bytes = utf8.encode(content); // 写入压缩包 archive.addFile(ArchiveFile(name, utf8Bytes.length, utf8Bytes)); print("添加日志文件: ${file.path}, 大小: ${utf8Bytes.length}"); } // 写入 zip 文件 final zipData = ZipEncoder().encode(archive); final zipFile = File(zipPath); await zipFile.writeAsBytes(zipData!); print("压缩包生成成功: ${zipFile.path}, 大小: ${await zipFile.length()} 字节"); // 分享 await Share.shareXFiles([XFile(zipFile.path)], text: '应用日志打包 $dateStr'); } catch (e) { print('导出日志失败: $e'); } } static Future printLog(String content) async { print("logger---> $content"); // 如果你希望顺便写入 info 日志,也可以取消下面注释 // await writeLog(content); } static Future readLogByDate(DateTime date) async { // 调用 readLogsByDateRange,fromDate 和 toDate 都是同一天 return await readLogsByDateRange(date, date); } }