mine_countdown_timer_manager.dart 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. import 'dart:async';
  2. import 'package:flutter/foundation.dart';
  3. import '../../data/repositories/member_repository.dart';
  4. import '../member/member_page.dart';
  5. import 'mine_expiration_reminder_dialog.dart';
  6. /// 全局倒计时定时器管理器(单例模式)
  7. class MineCountdownTimerManager {
  8. static final MineCountdownTimerManager _instance = MineCountdownTimerManager._internal();
  9. factory MineCountdownTimerManager() => _instance;
  10. MineCountdownTimerManager._internal();
  11. // 存储所有倒计时任务
  12. final Map<String, Timer> _timers = {};
  13. final Map<String, StreamController<String>> _streamControllers = {};
  14. final Map<String, Completer<void>> _completers = {};
  15. var areShowAlartView = true;
  16. /// 启动倒计时
  17. Future<void> startCountdown({
  18. required String key, // 倒计时唯一标识
  19. required int endTimestamp, // 结束时间戳(毫秒)
  20. required VoidCallback onExpired, // 过期回调
  21. }) async {
  22. // 取消已存在的同名倒计时
  23. cancelCountdown(key);
  24. // 创建过期回调的Completer
  25. _completers[key] = Completer<void>();
  26. // 计算剩余时间
  27. DateTime endTime = DateTime.fromMillisecondsSinceEpoch(endTimestamp);
  28. Duration remaining = endTime.difference(DateTime.now());
  29. // 如果剩余时间小于等于0,直接触发过期回调
  30. if (remaining.inSeconds <= 0) {
  31. onExpired();
  32. return;
  33. }
  34. // 创建StreamController用于通知UI更新
  35. _streamControllers[key] = StreamController<String>.broadcast();
  36. // 创建定时器
  37. _timers[key] = Timer.periodic(Duration(seconds: 1), (timer) {
  38. DateTime currentTime = DateTime.now();
  39. Duration newRemaining = endTime.difference(currentTime);
  40. if (newRemaining.inSeconds <= 0) {
  41. // 倒计时结束
  42. timer.cancel();
  43. _timers.remove(key);
  44. _streamControllers[key]?.close();
  45. _streamControllers.remove(key);
  46. onExpired();
  47. _completers[key]?.complete();
  48. _completers.remove(key);
  49. if (areShowAlartView) {
  50. areShowAlartView = false;
  51. ///弹出提示框
  52. MemberRepository memberRepository = MemberRepository.getInstance();
  53. memberRepository
  54. .memberTrailInfo()
  55. .then((infoRespons) {
  56. MineExpirationReminderDialog.show(infoResponse: infoRespons,
  57. onDic: () {
  58. areShowAlartView = true;
  59. MemberPage.start(enterTyp: MemberPageType.afeterTrialMemberEnter);
  60. },
  61. cancelOnTap: () {
  62. areShowAlartView = true;
  63. }
  64. );
  65. //MineExpirationReminderDialog.show(infoResponse: infoResponse);
  66. }).catchError((){
  67. areShowAlartView = true;
  68. });
  69. }
  70. } else {
  71. // 发送更新通知
  72. String formattedTime = formatDuration(newRemaining);
  73. _streamControllers[key]?.add(formattedTime);
  74. }
  75. });
  76. }
  77. /// 取消倒计时
  78. void cancelCountdown(String key) {
  79. _timers[key]?.cancel();
  80. _timers.remove(key);
  81. _streamControllers[key]?.close();
  82. _streamControllers.remove(key);
  83. _completers[key]?.complete();
  84. _completers.remove(key);
  85. }
  86. /// 格式化时间
  87. String formatDuration(Duration duration) {
  88. String twoDigits(int n) => n.toString().padLeft(2, '0');
  89. String hours = twoDigits(duration.inHours);
  90. String minutes = twoDigits(duration.inMinutes.remainder(60));
  91. String seconds = twoDigits(duration.inSeconds.remainder(60));
  92. print("hourssfsdfsd---${seconds}");
  93. return '$hours:$minutes:$seconds';
  94. }
  95. /// 获取倒计时流
  96. Stream<String> getCountdownStream(String key) {
  97. return _streamControllers[key]?.stream ?? Stream.empty();
  98. }
  99. /// 等待倒计时结束
  100. Future<void> waitForCountdown(String key) {
  101. return _completers[key]?.future ?? Future.value();
  102. }
  103. /// 清理所有倒计时
  104. void dispose() {
  105. _timers.forEach((key, timer) => timer.cancel());
  106. _timers.clear();
  107. _streamControllers.forEach((key, controller) => controller.close());
  108. _streamControllers.clear();
  109. _completers.clear();
  110. }
  111. }