import 'dart:io'; import 'package:aliyun_push_flutter/aliyun_push_flutter.dart'; import 'package:flutter/material.dart'; import 'package:flutter_app_update/flutter_app_update.dart'; import 'package:flutter_app_update/result_model.dart'; import 'package:flutter_native_splash/flutter_native_splash.dart'; import 'package:getx_scaffold/getx_scaffold.dart'; import 'package:ln_jq_app/common/model/base_model.dart'; import 'package:ln_jq_app/common/styles/theme.dart'; import 'package:ln_jq_app/pages/b_page/base_widgets/view.dart'; import 'package:ln_jq_app/pages/c_page/base_widgets/view.dart'; import 'package:ln_jq_app/pages/c_page/message/view.dart'; import 'package:ln_jq_app/pages/login/view.dart'; import '../../storage_service.dart'; class HomeController extends GetxController with BaseControllerMixin { @override String get builderId => 'home'; HomeController(); final _aliyunPush = AliyunPushFlutter(); @override bool get listenLifecycleEvent => true; @override void onInit() { super.onInit(); // 检查是否同意过隐私政策,只有同意后才初始化推送 if (StorageService.to.isPrivacyAgreed) { requestPermission(); initAliyunPush(); addPushCallback(); } FlutterNativeSplash.remove(); log('page-init'); // 页面初始化后执行版本检查 checkVersionInfo(); } String downloadUrl = ""; /// 检查 App 更新信息,增加版本号比对逻辑 void checkVersionInfo() async { try { final response = await HttpService.to.get('appointment/appConfig/get'); if (response != null) { final result = BaseModel.fromJson(response.data); if (result.code == 0 && result.data != null) { final data = result.data as Map; bool hasUpdate = data['hasUpdate']?.toString().toLowerCase() == "true"; bool isForce = data['isForce']?.toString().toLowerCase() == "true"; String versionName = data['versionName'] ?? "新版本"; String updateContent = data['updateContent'] ?? "优化系统性能,提升用户体验"; downloadUrl = data['downloadUrl'].toString(); // 获取服务器配置的目标构建号 int serverVersionCode = int.tryParse(data['versionCode']?.toString() ?? "0") ?? 0; int serverIosBuildId = int.tryParse(data['iosBuildId']?.toString() ?? "0") ?? 0; // 获取本地当前的构建号 String currentBuildStr = await getBuildNumber(); int currentBuild = int.tryParse(currentBuildStr) ?? 0; bool needUpdate = false; if (GetPlatform.isAndroid) { needUpdate = currentBuild < serverVersionCode; } else if (GetPlatform.isIOS) { needUpdate = currentBuild < serverIosBuildId; } // 如果服务器标记有更新,且本地版本号确实较低,则弹出更新 if (hasUpdate && needUpdate) { _showUpdateDialog("版本:$versionName\n\n更新内容:\n$updateContent", isForce); } } } } catch (e) { Logger.d("版本检查失败: $e"); } } /// 显示更新弹窗 void _showUpdateDialog(String content, bool isForce) { DialogX.to.showConfirmDialog( title: '升级提醒', confirmText: '立即升级', content: _buildDialogContent(content), // 如果是强制更新,取消按钮显示为空,即隐藏 cancelText: isForce ? "" : '以后再说', // 设置为 false,禁止点击背景和物理返回键关闭 barrierDismissible: false, onConfirm: () { jumpUpdateApp(); // ios如果是强制更新,点击后维持弹窗,防止用户进入 App if (isForce && GetPlatform.isIOS) { Future.delayed(const Duration(milliseconds: 500), () { _showUpdateDialog(content, isForce); }); } }, ); } Widget _buildDialogContent(String content) { return PopScope( canPop: false, // 关键:禁止 pop child: TextX.bodyMedium(content).padding(bottom: 16.h), ); } void jumpUpdateApp() { if (GetPlatform.isIOS) { // 跳转到 iOS 应用商店网页 openWebPage("https://apps.apple.com/cn/app/羚牛氢能/6756245815"); } else if (GetPlatform.isAndroid) { // Android 执行下载安装流程 showAndroidDownloadDialog(); } } void showAndroidDownloadDialog() { AzhonAppUpdate.listener((ResultModel model) { if (model.type == ResultType.start) { DialogX.to.showConfirmDialog( content: PopScope( canPop: false, child: Center( child: Column( children: [ TextX.bodyMedium('升级中...').padding(bottom: 45.h), CircularProgressIndicator(), ], ), ), ), confirmText: '', cancelText: "", barrierDismissible: false, ); } else if (model.type == ResultType.done) { Get.back(); } }); UpdateModel model = UpdateModel(downloadUrl, "xll.apk", "logo", '正在下载最新版本...'); AzhonAppUpdate.update(model); } // 根据登录状态和登录渠道返回不同的首页 Widget getHomePage() { if (StorageService.to.isLoggedIn) { if (StorageService.to.loginChannel == LoginChannel.station) { return B_BaseWidgetsPage(); } else if (StorageService.to.loginChannel == LoginChannel.driver) { return BaseWidgetsPage(); } else { return LoginPage(); } } else { return LoginPage(); } } void requestPermission() async { PermissionStatus status = await Permission.notification.status; if (status.isGranted) return; if (status.isDenied) { status = await Permission.notification.request(); } if (status.isGranted) { Logger.d('通知已开启'); } else if (status.isPermanentlyDenied) { Logger.d('通知权限已被拒绝,请到系统设置中开启'); } } ///推送相关初始化 (保持原样) Future initAliyunPush() async { final String appKey = Platform.isIOS ? AppTheme.ios_key : AppTheme.android_key; final String appSecret = Platform.isIOS ? AppTheme.ios_appsecret : AppTheme.android_appsecret; try { final result = await _aliyunPush.initPush(appKey: appKey, appSecret: appSecret); if (result['code'] != kAliyunPushSuccessCode) return; if (Platform.isIOS) { await _setupIOSConfig(); } else if (Platform.isAndroid) { await _setupAndroidConfig(); } } catch (e) { Logger.d('初始化异常: $e'); } } Future _setupIOSConfig() async { await _aliyunPush.showIOSNoticeWhenForeground(true); } Future _setupAndroidConfig() async { await _aliyunPush.setNotificationInGroup(true); await _aliyunPush.createAndroidChannel( "xll_push_android", '新消息通知', 4, '用于接收加氢站实时状态提醒', ); } void addPushCallback() { _aliyunPush.addMessageReceiver( onNotification: _onNotification, onNotificationOpened: _onNotificationOpened, onNotificationRemoved: _onNotificationRemoved, onMessage: _onMessage, onAndroidNotificationReceivedInApp: _onAndroidNotificationReceivedInApp, onAndroidNotificationClickedWithNoAction: _onAndroidNotificationClickedWithNoAction, onIOSChannelOpened: _onIOSChannelOpened, onIOSRegisterDeviceTokenSuccess: _onIOSRegisterDeviceTokenSuccess, onIOSRegisterDeviceTokenFailed: _onIOSRegisterDeviceTokenFailed, ); } Future _onAndroidNotificationClickedWithNoAction( Map message, ) async {} Future _onAndroidNotificationReceivedInApp(Map message) async {} Future _onMessage(Map message) async {} Future _onNotification(Map message) async {} Future _onNotificationOpened(Map message) async { await Get.to(() => const MessagePage()); } Future _onNotificationRemoved(Map message) async {} Future _onIOSChannelOpened(Map message) async {} Future _onIOSRegisterDeviceTokenSuccess(Map message) async {} Future _onIOSRegisterDeviceTokenFailed(Map message) async {} }