| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 |
- import 'dart:developer' as developer;
- import 'package:flutter_riverpod/flutter_riverpod.dart';
- import 'package:shared_preferences/shared_preferences.dart';
- import '../core/config/app_config.dart';
- import '../core/network/dio_client.dart';
- import '../data/models/version/app_version.dart';
- import '../data/services/version_service.dart';
- // SharedPreferences keys for cached version data
- const _kCachedLowestVersion = 'version_cached_lowest';
- const _kCachedNewVersion = 'version_cached_new';
- const _kCachedDownloadUrl = 'version_cached_download_url';
- const _kCachedUpdateDesc = 'version_cached_update_desc';
- /// 版本检查结果
- class VersionCheckResult {
- final AppVersion version;
- final String currentVersion;
- final bool hasUpdate;
- final bool isForce;
- const VersionCheckResult({
- required this.version,
- required this.currentVersion,
- this.hasUpdate = false,
- this.isForce = false,
- });
- }
- /// 版本检查 Provider
- /// 返回 [VersionCheckResult],null 表示无需更新或检查失败
- /// 网络失败时回退到本地缓存,防止关网绕过强制更新
- final appVersionProvider =
- FutureProvider.autoDispose<VersionCheckResult?>((ref) async {
- final currentVersion = AppConfig.appVersion;
- AppVersion? version;
- try {
- final dio = ref.read(dioClientProvider);
- version = await VersionService(dio).getLatestVersion();
- developer.log(
- 'Version API response: newVersion=${version?.newVersion}, '
- 'lowestVersion=${version?.lowestVersion}, '
- 'downloadUrl=${version?.downloadUrl}',
- name: 'VersionCheck',
- );
- if (version != null && version.newVersion.isNotEmpty) {
- // 成功后写入缓存,供断网时使用
- final prefs = await SharedPreferences.getInstance();
- await prefs.setString(_kCachedLowestVersion, version.lowestVersion);
- await prefs.setString(_kCachedNewVersion, version.newVersion);
- await prefs.setString(_kCachedDownloadUrl, version.downloadUrl);
- await prefs.setString(_kCachedUpdateDesc, version.updateDescription);
- }
- } catch (e, st) {
- developer.log(
- 'Version check failed, falling back to cache: $e',
- name: 'VersionCheck',
- error: e,
- stackTrace: st,
- );
- // 网络失败时读缓存
- try {
- final prefs = await SharedPreferences.getInstance();
- final cachedLowest = prefs.getString(_kCachedLowestVersion) ?? '';
- if (cachedLowest.isNotEmpty) {
- version = AppVersion(
- lowestVersion: cachedLowest,
- newVersion: prefs.getString(_kCachedNewVersion) ?? '',
- downloadUrl: prefs.getString(_kCachedDownloadUrl) ?? '',
- updateDescription: prefs.getString(_kCachedUpdateDesc) ?? '',
- );
- developer.log(
- 'Using cached version: lowestVersion=$cachedLowest',
- name: 'VersionCheck',
- );
- }
- } catch (_) {}
- }
- if (version == null || version.newVersion.isEmpty) {
- // 缓存也没有,只检查 lowestVersion(断网首次启动的兜底)
- if (version == null) return null;
- }
- final hasUpdate = version.hasNewVersion(currentVersion);
- final isForce = version.isForceUpdate(currentVersion);
- developer.log(
- 'Current=$currentVersion, latest=${version.newVersion}, '
- 'hasUpdate=$hasUpdate, isForce=$isForce',
- name: 'VersionCheck',
- );
- // 即使 newVersion 为空(纯缓存 lowestVersion 场景),只要需要强制更新也弹窗
- if (!hasUpdate && !isForce) return null;
- return VersionCheckResult(
- version: version,
- currentVersion: currentVersion,
- hasUpdate: hasUpdate || isForce,
- isForce: isForce,
- );
- });
|