import 'dart:convert'; import 'dart:io'; import 'package:path_provider/path_provider.dart'; import 'package:flutter_app_group_directory/flutter_app_group_directory.dart'; import 'log/logger.dart'; class BoostLogger { static const String LOG_FOLDER = 'boost_logs'; static const String APP_LOG_FILE = 'app.json'; static const String CORE_LOG_FILE = 'core.json'; static const String TAG = 'BoostLogger'; Map _currentSession = {}; String? _logPath; /// 单例模式实现 static final BoostLogger _instance = BoostLogger._internal(); factory BoostLogger() => _instance; BoostLogger._internal(); /// 获取日志目录 Future _getLogDirectory() async { if (Platform.isAndroid) { final appDir = await getApplicationSupportDirectory(); final logDir = Directory('${appDir.path}/$LOG_FOLDER'); if (!await logDir.exists()) { await logDir.create(recursive: true); } return logDir; } else { try { // iOS 使用 App Group 目录 final Directory? appGroupDirectory = await FlutterAppGroupDirectory.getAppGroupDirectory( 'group.app.xixi.nomo', ); // 验证 App Group 目录是否有效 if (appGroupDirectory != null) { final logDir = Directory('${appGroupDirectory.path}/$LOG_FOLDER'); if (!await logDir.exists()) { await logDir.create(recursive: true); } return logDir; } else { // App Group 目录不可用,回退到应用文档目录 log( TAG, 'App Group directory not available, falling back to documents directory', ); final appDir = await getApplicationDocumentsDirectory(); final logDir = Directory('${appDir.path}/$LOG_FOLDER'); if (!await logDir.exists()) { await logDir.create(recursive: true); } return logDir; } } catch (e) { // 如果 App Group 出现错误,回退到应用文档目录 log( TAG, 'Error with App Group directory: $e, falling back to documents directory', ); final appDir = await getApplicationDocumentsDirectory(); final logDir = Directory('${appDir.path}/$LOG_FOLDER'); if (!await logDir.exists()) { await logDir.create(recursive: true); } return logDir; } } } /// 初始化日志系统 Future init() async { try { final logDir = await _getLogDirectory(); _logPath = logDir.path; // 清除旧的app日志文件 final appFile = File('${logDir.path}/$APP_LOG_FILE'); if (await appFile.exists()) { await appFile.delete(); } // 清除旧的内核日志文件 final coreFile = File('${logDir.path}/$CORE_LOG_FILE'); if (await coreFile.exists()) { await coreFile.delete(); } // 初始化空的会话数据 _currentSession = {}; await _saveSession(); } catch (e) { log(TAG, 'BoostLogger init error: $e'); } } //读取历史日志 Future readHistoryLog() async { try { final logDir = await _getLogDirectory(); _logPath = logDir.path; getCurrentSession(); } catch (e) { log(TAG, 'BoostLogger readHistoryLog error: $e'); } } /// 设置整个部分的数据 Future setSection(String section, Map data) async { try { _currentSession[section] = data; await _saveSession(); } catch (e) { log(TAG, 'BoostLogger setSection error: $e'); } } /// 设置整个部分的数据 Future setSectionObj(String section, dynamic data) async { try { _currentSession[section] = data; await _saveSession(); } catch (e) { log(TAG, 'BoostLogger setSectionObj error: $e'); } } /// 更新部分中的特定字段 Future updateField(String section, String field, dynamic value) async { try { final sectionData = _currentSession[section] as Map; sectionData[field] = value; _currentSession[section] = sectionData; await _saveSession(); } catch (e) { log(TAG, 'BoostLogger updateField error: $e'); } } /// 向数组添加数据 Future appendToArray( String section, String arrayField, Map data, ) async { try { final sectionData = _currentSession[section] as Map? ?? {}; final array = sectionData[arrayField] as List? ?? []; array.add(data); sectionData[arrayField] = array; _currentSession[section] = sectionData; await _saveSession(); } catch (e) { log(TAG, 'BoostLogger appendToArray error: $e'); } } /// 保存会话数据到文件 Future _saveSession() async { if (_logPath == null) return; try { final file = File('$_logPath/$APP_LOG_FILE'); // 使用 writeAsStringSync 确保写入完成 final jsonString = const JsonEncoder.withIndent( ' ', ).convert(_currentSession); await file.writeAsString(jsonString, flush: true); // 验证文件写入 final content = await file.readAsString(); final savedData = jsonDecode(content) as Map; log(TAG, 'BoostLogger verify saved data: $savedData'); } catch (e) { log(TAG, 'BoostLogger save session error: $e'); } } /// 获取当前会话数据 Map getCurrentSession() { try { // 从文件读取最新数据 final file = File('$_logPath/$APP_LOG_FILE'); if (file.existsSync()) { final content = file.readAsStringSync(); _currentSession = jsonDecode(content) as Map; } return Map.from(_currentSession); } catch (e) { log(TAG, 'BoostLogger getCurrentSession error: $e'); return {}; } } /// 获取日志文件路径 Future getAppLogFilePath() async { return _logPath != null ? '$_logPath/$APP_LOG_FILE' : null; } /// 获取核心日志文件路径 Future getCoreLogFilePath() async { return _logPath != null ? '$_logPath/$CORE_LOG_FILE' : null; } /// 清理资源 Future release() async { try { // 检查 _currentSession 是否为空 if (_currentSession.isEmpty) { return; } await _saveSession(); _currentSession.clear(); } catch (e) { log(TAG, 'BoostLogger release error: $e'); } } }