import 'dart:async'; import 'dart:io'; import 'package:mqtt_client/mqtt_client.dart'; import 'package:pj_supermarket_cloud/common/index.dart'; class SyncCheckTool { static const _tag = "自动检查任务"; SyncCheckTool._privateConstructor(); static final SyncCheckTool _instance = SyncCheckTool._privateConstructor(); static SyncCheckTool get instance => _instance; bool _isRunning = false; // ************************************************************************** // 定时器配置 start // ************************************************************************** Duration mqInterval = const Duration(seconds: 60); Duration printInterval = const Duration(seconds: 60 * 10); Duration broadcastInterval = const Duration(seconds: 60 * 2); Duration deviceStatusInterval = const Duration(seconds: 60); Timer? mqTimer; Timer? printTimer; Timer? broadcastTimer; Timer? deviceStatusTimer; // ************************************************************************** // 定时器配置 end // ************************************************************************** void startAll() { if (_isRunning) return; _isRunning = true; checkMq(); checkPrint(); checkBroadcast(); checkDeviceStatus(); checkExpiredLog(); } void dispose() { _isRunning = false; mqTimer?.cancel(); mqTimer = null; printTimer?.cancel(); printTimer = null; broadcastTimer?.cancel(); broadcastTimer = null; deviceStatusTimer?.cancel(); deviceStatusTimer = null; } // 检查mq是否可以连接,是否需要重新连接 checkMq() { String logMsg = "检查mq是否可以连接,是否需要重新连接"; final inSeconds = mqInterval.inSeconds; if (mqTimer != null && mqTimer!.isActive) { mqTimer?.cancel(); mqTimer = null; } if (mqTimer != null) { mqTimer?.cancel(); mqTimer = null; } mqTimer = Timer.periodic(mqInterval, (Timer timer) async { final isNetwork = AppNetworkTool.isAutoNetwork(); if (!isNetwork) return; logger.i("|$_tag|$logMsg,$inSeconds秒一次,开始执行"); if (MqManager.state == MqttConnectionState.connected) return; try { AppMqTool.mqRefresh(); } catch (e) { logger.i("|$_tag|$logMsg,$inSeconds秒一次,执行失败,error:$e"); } finally { logger.i("|$_tag|$logMsg,$inSeconds秒一次,执行完成"); } }); } // 定时检查需不要打印 checkPrint() { String logMsg = "定时检查需不要打印"; final inSeconds = printInterval.inSeconds; if (printTimer != null && printTimer!.isActive) { printTimer?.cancel(); printTimer = null; } if (printTimer != null) { printTimer?.cancel(); printTimer = null; } printTimer = Timer.periodic(printInterval, (Timer timer) async { final isNetwork = AppNetworkTool.isAutoNetwork(); if (!isNetwork) return; logger.i("|$_tag|$logMsg,$inSeconds秒一次,开始执行"); try { await SyncPrintTool.doCheckPrint(); await SyncPrintTool.doCheckSync(); } catch (e) { logger.i("|$_tag|$logMsg,$inSeconds秒一次,执行失败,error:$e"); } finally { logger.i("|$_tag|$logMsg,$inSeconds秒一次,执行完成"); } }); } // 定时检查需不要广播 checkBroadcast() { String logMsg = "定时检查需不要广播"; final inSeconds = broadcastInterval.inSeconds; if (broadcastTimer != null && broadcastTimer!.isActive) { broadcastTimer?.cancel(); broadcastTimer = null; } if (broadcastTimer != null) { broadcastTimer?.cancel(); broadcastTimer = null; } broadcastTimer = Timer.periodic(broadcastInterval, (Timer timer) async { final isNetwork = AppNetworkTool.isAutoNetwork(); if (!isNetwork) return; logger.i("|$_tag|$logMsg,$inSeconds秒一次,开始执行"); try { final setting = await AppSettingTool.getSysSetting(); await SyncTakeFoodBroadcastTool.doCheckBroadcast( setting.hourType ?? ProductHourType.TOTAL, ); } catch (e) { logger.i("|$_tag|$logMsg,$inSeconds秒一次,执行失败,error:$e"); } finally { logger.i("|$_tag|$logMsg,$inSeconds秒一次,执行完成"); } }); } /// 设备状态检查不依赖网络,也不会主动开关串口或连接打印机。 void checkDeviceStatus() { final inSeconds = deviceStatusInterval.inSeconds; deviceStatusTimer?.cancel(); deviceStatusTimer = Timer.periodic(deviceStatusInterval, (timer) async { logger.i("|$_tag|检查终端设备状态,$inSeconds秒一次,开始执行"); try { await AppDeviceStatusTool.refreshAll(); } catch (e) { logger.i("|$_tag|检查终端设备状态执行失败,error:$e"); } finally { logger.i("|$_tag|检查终端设备状态执行完成"); } }); } // 检查过期日志(超过3个月的日志文件都要删除) checkExpiredLog() async { const logMsg = "检查过期日志"; try { final backupPath = await AppFileTool.getLoggerBackupPath(); if (backupPath == null || backupPath.isEmpty) { logger.w("|$_tag|$logMsg,日志备份路径为空"); return; } final loggerBackupDir = Directory(backupPath).parent.parent; if (!await loggerBackupDir.exists()) { logger.i("|$_tag|$logMsg,日志目录不存在 path:${loggerBackupDir.path}"); return; } final expireBefore = DateTime( DateTime.now().year, DateTime.now().month - 3, DateTime.now().day, ); final entities = loggerBackupDir.listSync(recursive: true); int deleteCount = 0; for (final entity in entities) { if (entity is! File) continue; if (!entity.path.endsWith(".log")) continue; final stat = await entity.stat(); if (stat.modified.isBefore(expireBefore)) { await entity.delete(); deleteCount++; logger.i("|$_tag|$logMsg,删除过期日志 path:${entity.path}"); } } final monthDirs = loggerBackupDir .listSync() .whereType() .toList() ..sort((a, b) => b.path.compareTo(a.path)); for (final dir in monthDirs) { if (!await dir.exists()) continue; final isEmpty = dir.listSync().isEmpty; if (isEmpty) { await dir.delete(); logger.i("|$_tag|$logMsg,删除空目录 path:${dir.path}"); } } logger.i("|$_tag|$logMsg,执行完成,删除日志数量:$deleteCount"); } catch (e, stack) { logger.e("|$_tag|$logMsg,执行失败,error:$e,stack:$stack"); } } }