19 changed files with 1379 additions and 132 deletions
@ -0,0 +1,151 @@ |
|||
import 'package:json_annotation/json_annotation.dart'; |
|||
|
|||
part 'channel_app_model.g.dart'; |
|||
|
|||
/// 渠道应用信息响应模型 |
|||
@JsonSerializable() |
|||
class ChannelAppResponse { |
|||
@JsonKey(name: 'code') |
|||
final int code; |
|||
|
|||
@JsonKey(name: 'data') |
|||
final ChannelAppData? data; |
|||
|
|||
@JsonKey(name: 'msg') |
|||
final String msg; |
|||
|
|||
const ChannelAppResponse({ |
|||
required this.code, |
|||
this.data, |
|||
required this.msg, |
|||
}); |
|||
|
|||
factory ChannelAppResponse.fromJson(Map<String, dynamic> json) => |
|||
_$ChannelAppResponseFromJson(json); |
|||
|
|||
Map<String, dynamic> toJson() => _$ChannelAppResponseToJson(this); |
|||
} |
|||
|
|||
/// 渠道应用数据模型 |
|||
@JsonSerializable() |
|||
class ChannelAppData { |
|||
@JsonKey(name: 'app') |
|||
final AppInfo app; |
|||
|
|||
const ChannelAppData({ |
|||
required this.app, |
|||
}); |
|||
|
|||
factory ChannelAppData.fromJson(Map<String, dynamic> json) => |
|||
_$ChannelAppDataFromJson(json); |
|||
|
|||
Map<String, dynamic> toJson() => _$ChannelAppDataToJson(this); |
|||
} |
|||
|
|||
/// 应用信息模型 |
|||
@JsonSerializable() |
|||
class AppInfo { |
|||
/// 下载地址 |
|||
@JsonKey(name: 'address') |
|||
final String address; |
|||
|
|||
/// 渠道标识 |
|||
@JsonKey(name: 'channel') |
|||
final String channel; |
|||
|
|||
/// 应用描述 |
|||
@JsonKey(name: 'description') |
|||
final String description; |
|||
|
|||
/// 最新版本号 |
|||
@JsonKey(name: 'version') |
|||
final String version; |
|||
|
|||
const AppInfo({ |
|||
required this.address, |
|||
required this.channel, |
|||
required this.description, |
|||
required this.version, |
|||
}); |
|||
|
|||
factory AppInfo.fromJson(Map<String, dynamic> json) => |
|||
_$AppInfoFromJson(json); |
|||
|
|||
Map<String, dynamic> toJson() => _$AppInfoToJson(this); |
|||
} |
|||
|
|||
/// 版本更新信息模型 |
|||
class VersionUpdateInfo { |
|||
/// 是否有新版本 |
|||
final bool hasUpdate; |
|||
|
|||
/// 当前版本 |
|||
final String currentVersion; |
|||
|
|||
/// 最新版本 |
|||
final String latestVersion; |
|||
|
|||
/// 应用信息 |
|||
final AppInfo? appInfo; |
|||
|
|||
/// 更新类型 |
|||
final UpdateType updateType; |
|||
|
|||
const VersionUpdateInfo({ |
|||
required this.hasUpdate, |
|||
required this.currentVersion, |
|||
required this.latestVersion, |
|||
this.appInfo, |
|||
required this.updateType, |
|||
}); |
|||
} |
|||
|
|||
/// 更新类型枚举 |
|||
enum UpdateType { |
|||
/// 无需更新 |
|||
none, |
|||
/// 可选更新 |
|||
optional, |
|||
/// 强制更新 |
|||
force, |
|||
} |
|||
|
|||
/// 应用商店类型枚举 |
|||
enum AppStoreType { |
|||
/// iOS App Store |
|||
appStore, |
|||
/// Google Play |
|||
googlePlay, |
|||
/// 华为应用市场 |
|||
huawei, |
|||
/// 小米应用商店 |
|||
xiaomi, |
|||
/// OPPO软件商店 |
|||
oppo, |
|||
/// vivo应用商店 |
|||
vivo, |
|||
/// 荣耀应用市场 |
|||
honor, |
|||
/// 官网下载 |
|||
official, |
|||
/// 未知 |
|||
unknown, |
|||
} |
|||
|
|||
/// 平台信息模型 |
|||
class PlatformInfo { |
|||
/// 平台类型 |
|||
final String platform; |
|||
|
|||
/// 应用商店类型 |
|||
final AppStoreType storeType; |
|||
|
|||
/// 渠道标识 |
|||
final String channel; |
|||
|
|||
const PlatformInfo({ |
|||
required this.platform, |
|||
required this.storeType, |
|||
required this.channel, |
|||
}); |
|||
} |
|||
@ -0,0 +1,47 @@ |
|||
// GENERATED CODE - DO NOT MODIFY BY HAND |
|||
|
|||
part of 'channel_app_model.dart'; |
|||
|
|||
// ************************************************************************** |
|||
// JsonSerializableGenerator |
|||
// ************************************************************************** |
|||
|
|||
ChannelAppResponse _$ChannelAppResponseFromJson(Map<String, dynamic> json) => |
|||
ChannelAppResponse( |
|||
code: (json['code'] as num).toInt(), |
|||
data: json['data'] == null |
|||
? null |
|||
: ChannelAppData.fromJson(json['data'] as Map<String, dynamic>), |
|||
msg: json['msg'] as String, |
|||
); |
|||
|
|||
Map<String, dynamic> _$ChannelAppResponseToJson(ChannelAppResponse instance) => |
|||
<String, dynamic>{ |
|||
'code': instance.code, |
|||
'data': instance.data, |
|||
'msg': instance.msg, |
|||
}; |
|||
|
|||
ChannelAppData _$ChannelAppDataFromJson(Map<String, dynamic> json) => |
|||
ChannelAppData( |
|||
app: AppInfo.fromJson(json['app'] as Map<String, dynamic>), |
|||
); |
|||
|
|||
Map<String, dynamic> _$ChannelAppDataToJson(ChannelAppData instance) => |
|||
<String, dynamic>{ |
|||
'app': instance.app, |
|||
}; |
|||
|
|||
AppInfo _$AppInfoFromJson(Map<String, dynamic> json) => AppInfo( |
|||
address: json['address'] as String, |
|||
channel: json['channel'] as String, |
|||
description: json['description'] as String, |
|||
version: json['version'] as String, |
|||
); |
|||
|
|||
Map<String, dynamic> _$AppInfoToJson(AppInfo instance) => <String, dynamic>{ |
|||
'address': instance.address, |
|||
'channel': instance.channel, |
|||
'description': instance.description, |
|||
'version': instance.version, |
|||
}; |
|||
@ -0,0 +1,315 @@ |
|||
import 'dart:io'; |
|||
import 'package:flutter/foundation.dart'; |
|||
import 'package:get/get.dart'; |
|||
import 'package:package_info_plus/package_info_plus.dart'; |
|||
import 'package:url_launcher/url_launcher.dart'; |
|||
import 'package:logger/logger.dart'; |
|||
import 'package:device_info_plus/device_info_plus.dart'; |
|||
import '../models/channel_app_model.dart'; |
|||
import 'network/api.dart'; |
|||
|
|||
/// 版本更新服务类 |
|||
class VersionUpdateService extends GetxService { |
|||
static VersionUpdateService get to => Get.find(); |
|||
|
|||
final Logger _logger = Logger(); |
|||
|
|||
/// 获取当前应用版本信息 |
|||
Future<String> getCurrentVersion() async { |
|||
try { |
|||
final packageInfo = await PackageInfo.fromPlatform(); |
|||
return '${packageInfo.version}+${packageInfo.buildNumber}'; |
|||
} catch (e) { |
|||
_logger.e('获取当前版本信息失败: $e'); |
|||
return '1.0.0'; |
|||
} |
|||
} |
|||
|
|||
/// 获取当前平台信息 |
|||
Future<PlatformInfo> getCurrentPlatformInfo() async { |
|||
if (kIsWeb) { |
|||
return const PlatformInfo( |
|||
platform: 'web', |
|||
storeType: AppStoreType.official, |
|||
channel: '官方网站', |
|||
); |
|||
} |
|||
|
|||
if (Platform.isIOS) { |
|||
return const PlatformInfo( |
|||
platform: 'ios', |
|||
storeType: AppStoreType.appStore, |
|||
channel: 'App Store', |
|||
); |
|||
} |
|||
|
|||
if (Platform.isAndroid) { |
|||
// 根据设备品牌判断应用商店类型 |
|||
return await getAndroidStoreInfoByBrand(); |
|||
} |
|||
|
|||
return const PlatformInfo( |
|||
platform: 'unknown', |
|||
storeType: AppStoreType.unknown, |
|||
channel: '未知', |
|||
); |
|||
} |
|||
|
|||
/// 根据设备品牌获取应用商店信息 |
|||
Future<PlatformInfo> getAndroidStoreInfoByBrand() async { |
|||
try { |
|||
final deviceInfo = DeviceInfoPlugin(); |
|||
final androidInfo = await deviceInfo.androidInfo; |
|||
final brand = androidInfo.brand.toLowerCase(); |
|||
|
|||
return const PlatformInfo( |
|||
platform: 'android', |
|||
storeType: AppStoreType.official, |
|||
channel: '官方内测', |
|||
); |
|||
|
|||
// switch (brand) { |
|||
// case 'huawei': |
|||
// case 'honor': |
|||
// return PlatformInfo( |
|||
// platform: 'android', |
|||
// storeType: |
|||
// brand == 'huawei' ? AppStoreType.huawei : AppStoreType.honor, |
|||
// channel: brand == 'huawei' ? '华为应用市场' : '荣耀应用市场', |
|||
// ); |
|||
// case 'xiaomi': |
|||
// case 'redmi': |
|||
// return const PlatformInfo( |
|||
// platform: 'android', |
|||
// storeType: AppStoreType.xiaomi, |
|||
// channel: '小米应用商店', |
|||
// ); |
|||
// case 'oppo': |
|||
// case 'oneplus': |
|||
// return const PlatformInfo( |
|||
// platform: 'android', |
|||
// storeType: AppStoreType.oppo, |
|||
// channel: 'OPPO软件商店', |
|||
// ); |
|||
// case 'vivo': |
|||
// case 'iqoo': |
|||
// return const PlatformInfo( |
|||
// platform: 'android', |
|||
// storeType: AppStoreType.vivo, |
|||
// channel: 'vivo应用商店', |
|||
// ); |
|||
// default: |
|||
// return const PlatformInfo( |
|||
// platform: 'android', |
|||
// storeType: AppStoreType.googlePlay, |
|||
// channel: 'Google Play', |
|||
// ); |
|||
// } |
|||
} catch (e) { |
|||
_logger.e('获取Android设备信息失败: $e'); |
|||
return const PlatformInfo( |
|||
platform: 'android', |
|||
storeType: AppStoreType.googlePlay, |
|||
channel: 'Google Play', |
|||
); |
|||
} |
|||
} |
|||
|
|||
/// 检查版本更新 |
|||
Future<VersionUpdateInfo> checkForUpdate() async { |
|||
try { |
|||
final currentVersion = await getCurrentVersion(); |
|||
final platformInfo = await getCurrentPlatformInfo(); |
|||
|
|||
// 调用后端接口获取最新版本信息 |
|||
final response = |
|||
await Api.getChannelApp({'channel': platformInfo.channel}); |
|||
|
|||
print('获取渠道包信息:$response'); |
|||
|
|||
if (response == null || !response.containsKey('app')) { |
|||
return VersionUpdateInfo( |
|||
hasUpdate: false, |
|||
currentVersion: currentVersion, |
|||
latestVersion: currentVersion, |
|||
updateType: UpdateType.none, |
|||
); |
|||
} |
|||
|
|||
//final channelAppResponse = ChannelAppResponse.fromJson(response); |
|||
// 直接从response中获取app信息 |
|||
final appInfo = AppInfo.fromJson(response['app']); |
|||
|
|||
// if (channelAppResponse.code != 0 || channelAppResponse.data == null) { |
|||
// _logger.w('获取版本信息失败: ${channelAppResponse.msg}'); |
|||
// return VersionUpdateInfo( |
|||
// hasUpdate: false, |
|||
// currentVersion: currentVersion, |
|||
// latestVersion: currentVersion, |
|||
// updateType: UpdateType.none, |
|||
// ); |
|||
// } |
|||
|
|||
// final appInfo = channelAppResponse.data!.app; |
|||
final hasUpdate = _compareVersions(currentVersion, appInfo.version); |
|||
|
|||
return VersionUpdateInfo( |
|||
hasUpdate: hasUpdate, |
|||
currentVersion: currentVersion, |
|||
latestVersion: appInfo.version, |
|||
appInfo: appInfo, |
|||
updateType: hasUpdate ? UpdateType.optional : UpdateType.none, |
|||
); |
|||
} catch (e) { |
|||
_logger.e('检查版本更新失败: $e'); |
|||
final currentVersion = await getCurrentVersion(); |
|||
return VersionUpdateInfo( |
|||
hasUpdate: false, |
|||
currentVersion: currentVersion, |
|||
latestVersion: currentVersion, |
|||
updateType: UpdateType.none, |
|||
); |
|||
} |
|||
} |
|||
|
|||
/// 比较版本号 |
|||
/// 返回true表示需要更新(远程版本更高) |
|||
bool _compareVersions(String current, String latest) { |
|||
// 拆分版本号与构建号 |
|||
final currentParts = current.split('+'); |
|||
final latestParts = latest.split('+'); |
|||
|
|||
// 解析版本号 (major.minor.patch) |
|||
final currentVersions = currentParts[0].split('.').map(int.parse).toList(); |
|||
final latestVersions = latestParts[0].split('.').map(int.parse).toList(); |
|||
|
|||
// 逐级比较版本号 |
|||
for (var i = 0; i < currentVersions.length; i++) { |
|||
if (latestVersions[i] > currentVersions[i]) return true; |
|||
if (latestVersions[i] < currentVersions[i]) return false; |
|||
} |
|||
|
|||
// 版本号相同则比较构建号 |
|||
if (latestParts.length > 1 && currentParts.length > 1) { |
|||
return int.parse(latestParts[1]) > int.parse(currentParts[1]); |
|||
} |
|||
return false; |
|||
} |
|||
|
|||
/// 解析版本号字符串为数字数组 |
|||
List<int> _parseVersion(String version) { |
|||
final parts = version.split('.'); |
|||
final result = <int>[]; |
|||
|
|||
for (int i = 0; i < 3; i++) { |
|||
if (i < parts.length) { |
|||
result.add(int.tryParse(parts[i]) ?? 0); |
|||
} else { |
|||
result.add(0); |
|||
} |
|||
} |
|||
|
|||
return result; |
|||
} |
|||
|
|||
/// 执行更新操作 |
|||
Future<bool> performUpdate(VersionUpdateInfo updateInfo) async { |
|||
if (!updateInfo.hasUpdate || updateInfo.appInfo == null) { |
|||
return false; |
|||
} |
|||
|
|||
final platformInfo = await getCurrentPlatformInfo(); |
|||
|
|||
try { |
|||
switch (platformInfo.storeType) { |
|||
case AppStoreType.appStore: |
|||
return await _openAppStore(); |
|||
case AppStoreType.googlePlay: |
|||
return await _openGooglePlay(); |
|||
case AppStoreType.huawei: |
|||
return await _openHuaweiStore(); |
|||
case AppStoreType.xiaomi: |
|||
return await _openXiaomiStore(); |
|||
case AppStoreType.oppo: |
|||
return await _openOppoStore(); |
|||
case AppStoreType.vivo: |
|||
return await _openVivoStore(); |
|||
case AppStoreType.honor: |
|||
return await _openHonorStore(); |
|||
case AppStoreType.official: |
|||
return await _openOfficialDownload(updateInfo.appInfo!.address); |
|||
default: |
|||
return await _openOfficialDownload(updateInfo.appInfo!.address); |
|||
} |
|||
} catch (e) { |
|||
_logger.e('执行更新失败: $e'); |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
/// 打开iOS App Store |
|||
Future<bool> _openAppStore() async { |
|||
// 这里需要替换为实际的App Store ID |
|||
const appStoreUrl = 'https://apps.apple.com/app/id你的应用ID'; |
|||
return await _launchUrl(appStoreUrl); |
|||
} |
|||
|
|||
/// 打开Google Play |
|||
Future<bool> _openGooglePlay() async { |
|||
// 这里需要替换为实际的包名 |
|||
const packageName = 'com.yourcompany.deepvoice'; |
|||
const playStoreUrl = |
|||
'https://play.google.com/store/apps/details?id=$packageName'; |
|||
return await _launchUrl(playStoreUrl); |
|||
} |
|||
|
|||
/// 打开华为应用市场 |
|||
Future<bool> _openHuaweiStore() async { |
|||
const huaweiStoreUrl = 'appmarket://details?id=com.yourcompany.deepvoice'; |
|||
return await _launchUrl(huaweiStoreUrl); |
|||
} |
|||
|
|||
/// 打开小米应用商店 |
|||
Future<bool> _openXiaomiStore() async { |
|||
const xiaomiStoreUrl = 'mimarket://details?id=com.yourcompany.deepvoice'; |
|||
return await _launchUrl(xiaomiStoreUrl); |
|||
} |
|||
|
|||
/// 打开OPPO软件商店 |
|||
Future<bool> _openOppoStore() async { |
|||
const oppoStoreUrl = |
|||
'oppomarket://details?packagename=com.yourcompany.deepvoice'; |
|||
return await _launchUrl(oppoStoreUrl); |
|||
} |
|||
|
|||
/// 打开vivo应用商店 |
|||
Future<bool> _openVivoStore() async { |
|||
const vivoStoreUrl = 'vivomarket://details?id=com.yourcompany.deepvoice'; |
|||
return await _launchUrl(vivoStoreUrl); |
|||
} |
|||
|
|||
/// 打开荣耀应用市场 |
|||
Future<bool> _openHonorStore() async { |
|||
const honorStoreUrl = 'honormarket://details?id=com.yourcompany.deepvoice'; |
|||
return await _launchUrl(honorStoreUrl); |
|||
} |
|||
|
|||
/// 打开官网下载 |
|||
Future<bool> _openOfficialDownload(String downloadUrl) async { |
|||
return await _launchUrl(downloadUrl); |
|||
} |
|||
|
|||
/// 启动URL |
|||
Future<bool> _launchUrl(String url) async { |
|||
try { |
|||
final uri = Uri.parse(url); |
|||
if (await canLaunchUrl(uri)) { |
|||
return await launchUrl(uri, mode: LaunchMode.externalApplication); |
|||
} |
|||
return false; |
|||
} catch (e) { |
|||
_logger.e('启动URL失败: $e'); |
|||
return false; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,226 @@ |
|||
import 'package:flutter/material.dart'; |
|||
import 'package:flutter_screenutil/flutter_screenutil.dart'; |
|||
import 'package:get/get.dart'; |
|||
import '../../../data/models/channel_app_model.dart'; |
|||
import '../../../data/services/version_update_service.dart'; |
|||
|
|||
/// 版本更新提示对话框 |
|||
class VersionUpdateDialog extends StatelessWidget { |
|||
final VersionUpdateInfo updateInfo; |
|||
final VoidCallback? onCancel; |
|||
final VoidCallback? onUpdate; |
|||
|
|||
const VersionUpdateDialog({ |
|||
super.key, |
|||
required this.updateInfo, |
|||
this.onCancel, |
|||
this.onUpdate, |
|||
}); |
|||
|
|||
@override |
|||
Widget build(BuildContext context) { |
|||
final isDarkMode = Theme.of(context).brightness == Brightness.dark; |
|||
|
|||
return Dialog( |
|||
shape: RoundedRectangleBorder( |
|||
borderRadius: BorderRadius.circular(16.r), |
|||
), |
|||
child: Container( |
|||
width: 320.w, |
|||
padding: EdgeInsets.all(24.w), |
|||
decoration: BoxDecoration( |
|||
color: isDarkMode ? Colors.grey[900] : Colors.white, |
|||
borderRadius: BorderRadius.circular(16.r), |
|||
), |
|||
child: Column( |
|||
mainAxisSize: MainAxisSize.min, |
|||
children: [ |
|||
// 标题图标 |
|||
Container( |
|||
width: 64.w, |
|||
height: 64.w, |
|||
decoration: BoxDecoration( |
|||
color: Colors.blue.withOpacity(0.1), |
|||
borderRadius: BorderRadius.circular(32.r), |
|||
), |
|||
child: Icon( |
|||
Icons.system_update, |
|||
size: 32.sp, |
|||
color: Colors.blue, |
|||
), |
|||
), |
|||
|
|||
SizedBox(height: 16.h), |
|||
|
|||
// 标题 |
|||
Text( |
|||
'发现新版本', |
|||
style: TextStyle( |
|||
fontSize: 20.sp, |
|||
fontWeight: FontWeight.bold, |
|||
color: isDarkMode ? Colors.white : Colors.black87, |
|||
), |
|||
), |
|||
|
|||
SizedBox(height: 8.h), |
|||
|
|||
// 版本信息 |
|||
Text( |
|||
'${updateInfo.currentVersion} → ${updateInfo.latestVersion}', |
|||
style: TextStyle( |
|||
fontSize: 14.sp, |
|||
color: isDarkMode ? Colors.grey[400] : Colors.grey[600], |
|||
), |
|||
), |
|||
|
|||
SizedBox(height: 16.h), |
|||
|
|||
// 更新描述 |
|||
if (updateInfo.appInfo?.description.isNotEmpty == true) ...[ |
|||
Container( |
|||
width: double.infinity, |
|||
padding: EdgeInsets.all(12.w), |
|||
decoration: BoxDecoration( |
|||
color: isDarkMode ? Colors.grey[800] : Colors.grey[100], |
|||
borderRadius: BorderRadius.circular(8.r), |
|||
), |
|||
child: Text( |
|||
updateInfo.appInfo!.description, |
|||
style: TextStyle( |
|||
fontSize: 14.sp, |
|||
color: isDarkMode ? Colors.grey[300] : Colors.grey[700], |
|||
height: 1.4, |
|||
), |
|||
), |
|||
), |
|||
SizedBox(height: 20.h), |
|||
], |
|||
|
|||
// 按钮区域 |
|||
Row( |
|||
children: [ |
|||
// 取消按钮(仅在非强制更新时显示) |
|||
if (updateInfo.updateType != UpdateType.force) ...[ |
|||
Expanded( |
|||
child: TextButton( |
|||
onPressed: () { |
|||
Get.back(); |
|||
onCancel?.call(); |
|||
}, |
|||
style: TextButton.styleFrom( |
|||
padding: EdgeInsets.symmetric(vertical: 12.h), |
|||
shape: RoundedRectangleBorder( |
|||
borderRadius: BorderRadius.circular(8.r), |
|||
side: BorderSide( |
|||
color: isDarkMode ? Colors.grey[600]! : Colors.grey[300]!, |
|||
), |
|||
), |
|||
), |
|||
child: Text( |
|||
'稍后提醒', |
|||
style: TextStyle( |
|||
fontSize: 16.sp, |
|||
color: isDarkMode ? Colors.grey[400] : Colors.grey[600], |
|||
), |
|||
), |
|||
), |
|||
), |
|||
SizedBox(width: 12.w), |
|||
], |
|||
|
|||
// 更新按钮 |
|||
Expanded( |
|||
child: ElevatedButton( |
|||
onPressed: () async { |
|||
Get.back(); |
|||
await _handleUpdate(); |
|||
onUpdate?.call(); |
|||
}, |
|||
style: ElevatedButton.styleFrom( |
|||
backgroundColor: Colors.blue, |
|||
foregroundColor: Colors.white, |
|||
padding: EdgeInsets.symmetric(vertical: 12.h), |
|||
shape: RoundedRectangleBorder( |
|||
borderRadius: BorderRadius.circular(8.r), |
|||
), |
|||
elevation: 0, |
|||
), |
|||
child: Text( |
|||
_getUpdateButtonText(), |
|||
style: TextStyle( |
|||
fontSize: 16.sp, |
|||
fontWeight: FontWeight.w600, |
|||
), |
|||
), |
|||
), |
|||
), |
|||
], |
|||
), |
|||
], |
|||
), |
|||
), |
|||
); |
|||
} |
|||
|
|||
/// 获取更新按钮文本 |
|||
String _getUpdateButtonText() { |
|||
switch (updateInfo.updateType) { |
|||
case UpdateType.force: |
|||
return '立即更新'; |
|||
case UpdateType.optional: |
|||
return '立即更新'; |
|||
default: |
|||
return '检查更新'; |
|||
} |
|||
} |
|||
|
|||
/// 处理更新操作 |
|||
Future<void> _handleUpdate() async { |
|||
try { |
|||
// 显示加载提示 |
|||
Get.dialog( |
|||
const Center( |
|||
child: CircularProgressIndicator(), |
|||
), |
|||
barrierDismissible: false, |
|||
); |
|||
|
|||
final versionService = VersionUpdateService.to; |
|||
final success = await versionService.performUpdate(updateInfo); |
|||
|
|||
// 关闭加载提示 |
|||
Get.back(); |
|||
|
|||
if (!success) { |
|||
Get.snackbar( |
|||
'更新失败', |
|||
'无法打开应用商店,请手动前往应用商店更新', |
|||
snackPosition: SnackPosition.TOP, |
|||
backgroundColor: Colors.red.withOpacity(0.8), |
|||
colorText: Colors.white, |
|||
); |
|||
} |
|||
} catch (e) { |
|||
// 关闭加载提示 |
|||
if (Get.isDialogOpen == true) { |
|||
Get.back(); |
|||
} |
|||
|
|||
Get.snackbar( |
|||
'更新失败', |
|||
'更新过程中发生错误,请稍后重试', |
|||
snackPosition: SnackPosition.TOP, |
|||
backgroundColor: Colors.red.withOpacity(0.8), |
|||
colorText: Colors.white, |
|||
); |
|||
} |
|||
} |
|||
|
|||
/// 显示版本更新对话框 |
|||
static Future<void> show(VersionUpdateInfo updateInfo) async { |
|||
await Get.dialog( |
|||
VersionUpdateDialog(updateInfo: updateInfo), |
|||
barrierDismissible: updateInfo.updateType != UpdateType.force, |
|||
); |
|||
} |
|||
} |
|||
Loading…
Reference in new issue