deviceauth_controller.dart 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. import 'dart:async';
  2. import 'package:flutter/material.dart';
  3. import 'package:get/get.dart';
  4. import 'package:nomo/app/components/ix_snackbar.dart';
  5. import '../../../../config/translations/strings_enum.dart';
  6. class DeviceauthController extends GetxController {
  7. // 用户类型:true为VIP用户,false为免费用户
  8. final isPremium = true.obs;
  9. // 授权码相关
  10. final authCode = '673999'.obs;
  11. final countdownSeconds = 899.obs; // 15分钟 = 900秒,从899开始倒计时
  12. Timer? _countdownTimer;
  13. // 输入码相关
  14. final inputCode = ''.obs;
  15. final isCodeComplete = false.obs;
  16. final isAuthorizing = false.obs;
  17. // 设备管理
  18. final currentDevices = <DeviceInfo>[].obs;
  19. final maxDevices = 4;
  20. // 授权状态
  21. final authorizationStatus = AuthorizationStatus.waiting.obs;
  22. @override
  23. void onInit() {
  24. super.onInit();
  25. _initializeDevices();
  26. _startCountdown();
  27. }
  28. @override
  29. void onClose() {
  30. _countdownTimer?.cancel();
  31. super.onClose();
  32. }
  33. /// 初始化设备列表
  34. void _initializeDevices() {
  35. currentDevices.add(
  36. DeviceInfo(
  37. id: '1',
  38. name: Strings.currentDevice.tr,
  39. type: DeviceTypeEnum.ios,
  40. date: '2022/01/25 13:45',
  41. isCurrent: true,
  42. ),
  43. );
  44. }
  45. /// 开始倒计时
  46. void _startCountdown() {
  47. _countdownTimer = Timer.periodic(const Duration(seconds: 1), (timer) {
  48. if (countdownSeconds.value > 0) {
  49. countdownSeconds.value--;
  50. } else {
  51. // 倒计时结束,刷新授权码
  52. _refreshAuthCode();
  53. countdownSeconds.value = 899;
  54. }
  55. });
  56. }
  57. /// 刷新授权码
  58. void _refreshAuthCode() {
  59. // 生成新的6位随机码
  60. final random = DateTime.now().millisecondsSinceEpoch;
  61. authCode.value = (random % 900000 + 100000).toString();
  62. }
  63. /// 设置输入码(由pinput调用)
  64. void setInputCode(String code) {
  65. inputCode.value = code;
  66. isCodeComplete.value = code.length == 6;
  67. }
  68. /// 提交授权码
  69. void submitAuthCode() {
  70. if (inputCode.value.length == 6) {
  71. // 检查设备数量限制
  72. if (currentDevices.length >= maxDevices) {
  73. IXSnackBar.showIXErrorSnackBar(
  74. title: Strings.deviceLimitReached.tr,
  75. message:
  76. '${Strings.deviceLimitMessage.tr} $maxDevices ${Strings.devices.tr}',
  77. );
  78. inputCode.value = '';
  79. isCodeComplete.value = false;
  80. return;
  81. }
  82. isAuthorizing.value = true;
  83. authorizationStatus.value = AuthorizationStatus.configuring;
  84. // 模拟授权过程(实际应该调用API)
  85. Timer(const Duration(seconds: 2), () {
  86. isAuthorizing.value = false;
  87. authorizationStatus.value = AuthorizationStatus.success;
  88. // 添加新设备
  89. final newId = (currentDevices.length + 1).toString();
  90. currentDevices.add(
  91. DeviceInfo(
  92. id: newId,
  93. name: Strings.androidDevices.tr,
  94. type: DeviceTypeEnum.android,
  95. uid: 'UID 123-456-789-10$newId',
  96. date: _getCurrentDateTime(),
  97. isCurrent: false,
  98. ),
  99. );
  100. // 显示成功提示
  101. IXSnackBar.showIXSnackBar(
  102. title: Strings.deviceAuthorized.tr,
  103. message: Strings.deviceAuthorizedMessage.tr,
  104. );
  105. // 清空输入码
  106. inputCode.value = '';
  107. isCodeComplete.value = false;
  108. // 重置状态
  109. Timer(const Duration(milliseconds: 500), () {
  110. authorizationStatus.value = AuthorizationStatus.waiting;
  111. });
  112. });
  113. }
  114. }
  115. /// 获取当前日期时间
  116. String _getCurrentDateTime() {
  117. final now = DateTime.now();
  118. return '${now.year}/${now.month.toString().padLeft(2, '0')}/${now.day.toString().padLeft(2, '0')} '
  119. '${now.hour.toString().padLeft(2, '0')}:${now.minute.toString().padLeft(2, '0')}';
  120. }
  121. /// 移除设备
  122. void removeDevice(String deviceId) {
  123. final device = currentDevices.firstWhere((d) => d.id == deviceId);
  124. Get.dialog(
  125. AlertDialog(
  126. title: Text(Strings.relieveDevice.tr),
  127. content: Text(
  128. '${Strings.relieveDeviceMessage.tr} ${device.name}?\n\n'
  129. '${Strings.relieveDeviceLoseAccess.tr}',
  130. ),
  131. actions: [
  132. TextButton(
  133. onPressed: () => Get.back(),
  134. child: Text(Strings.cancel.tr),
  135. ),
  136. TextButton(
  137. onPressed: () {
  138. currentDevices.removeWhere((d) => d.id == deviceId);
  139. Get.back();
  140. Get.snackbar(
  141. Strings.deviceRelieved.tr,
  142. '${device.name} ${Strings.deviceRelievedMessage.tr}',
  143. snackPosition: SnackPosition.bottom,
  144. );
  145. },
  146. child: Text(
  147. Strings.relieveDevice.tr,
  148. style: const TextStyle(color: Colors.red),
  149. ),
  150. ),
  151. ],
  152. ),
  153. );
  154. }
  155. /// 复制授权码
  156. void copyAuthCode() {
  157. // TODO: 实现复制到剪贴板
  158. IXSnackBar.showIXSnackBar(
  159. title: Strings.copied.tr,
  160. message: Strings.authCodeCopied.tr,
  161. );
  162. }
  163. /// 获取倒计时显示文本
  164. String get countdownText {
  165. final minutes = countdownSeconds.value ~/ 60;
  166. final seconds = countdownSeconds.value % 60;
  167. return '${minutes.toString().padLeft(2, '0')}:${seconds.toString().padLeft(2, '0')}';
  168. }
  169. /// 获取当前设备数量
  170. int get currentDeviceCount => currentDevices.length;
  171. /// 获取设备数量显示文本
  172. String get deviceCountText => '$currentDeviceCount/$maxDevices';
  173. }
  174. /// 设备信息类
  175. class DeviceInfo {
  176. final String id;
  177. final String name;
  178. final DeviceTypeEnum type;
  179. final String? uid;
  180. final String? date;
  181. final bool isCurrent;
  182. DeviceInfo({
  183. required this.id,
  184. required this.name,
  185. required this.type,
  186. this.uid,
  187. this.date,
  188. this.isCurrent = false,
  189. });
  190. }
  191. /// 设备类型枚举
  192. enum DeviceTypeEnum { ios, android, windows, mac }
  193. /// 授权状态枚举
  194. enum AuthorizationStatus { waiting, configuring, success, failed }