Files
ln-ios/ln_jq_app/lib/pages/home/controller.dart
2026-03-13 17:09:30 +08:00

258 lines
8.3 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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<String, dynamic>;
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<void> 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<void> _setupIOSConfig() async {
await _aliyunPush.showIOSNoticeWhenForeground(true);
}
Future<void> _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<void> _onAndroidNotificationClickedWithNoAction(
Map<dynamic, dynamic> message,
) async {}
Future<void> _onAndroidNotificationReceivedInApp(Map<dynamic, dynamic> message) async {}
Future<void> _onMessage(Map<dynamic, dynamic> message) async {}
Future<void> _onNotification(Map<dynamic, dynamic> message) async {}
Future<void> _onNotificationOpened(Map<dynamic, dynamic> message) async {
await Get.to(() => const MessagePage());
}
Future<void> _onNotificationRemoved(Map<dynamic, dynamic> message) async {}
Future<void> _onIOSChannelOpened(Map<dynamic, dynamic> message) async {}
Future<void> _onIOSRegisterDeviceTokenSuccess(Map<dynamic, dynamic> message) async {}
Future<void> _onIOSRegisterDeviceTokenFailed(Map<dynamic, dynamic> message) async {}
}