Commit 2c0795464703ea3c632f3e3504b5f9761070cbce

Authored by 吴启风
1 parent 69a01aa2

feat:应用内更新接口替换

lib/common/core/app_config_helper.dart
... ... @@ -17,6 +17,9 @@ class AppConfigHelper {
17 17  
18 18 static String _versionCode = '';
19 19  
  20 + // 是否检测过更新,因为路由混乱导致首页会多次启动,避免重复检测更新,先临时处理
  21 + static bool checkedUpdate = false;
  22 +
20 23 // 获取用户信息
21 24 static Future<AppConfigEntity?> getAppConfig() async {
22 25 if (configEntityEntity != null) {
... ...
lib/common/request/apis.dart
... ... @@ -6,6 +6,9 @@ class Apis {
6 6 /// 接口地址:https://app.apifox.com/link/project/2684751/apis/api-89897678
7 7 static const String appConfig = 'system/app/config';
8 8  
  9 + /// app版本信息
  10 + static const String appVersion = 'system/app/version';
  11 +
9 12 /// 登录
10 13 static const String login = 'login';
11 14  
... ...
lib/common/request/dao/system_dao.dart
1 1 import '../../../models/app_config_entity.dart';
  2 +import '../../../models/app_version_entity.dart';
2 3 import '../request_client.dart';
3 4  
4 5 class SystemDao {
... ... @@ -7,4 +8,9 @@ class SystemDao {
7 8 static Future<AppConfigEntity?> getAppConfig() async {
8 9 return await requestClient.get(Apis.appConfig);
9 10 }
  11 +
  12 + // 获取app版本信息
  13 + static Future<AppVersionEntity?> getVersionInfo() async {
  14 + return await requestClient.get(Apis.appVersion);
  15 + }
10 16 }
... ...
lib/common/request/token_interceptor.dart
1 1 import 'package:dio/dio.dart';
  2 +import 'package:flutter/foundation.dart';
2 3 import 'package:wow_english/common/core/user_util.dart';
3 4  
4 5 import '../core/app_config_helper.dart';
... ... @@ -13,6 +14,7 @@ class TokenInterceptor extends Interceptor {
13 14 // 在发送请求之前获取版本号
14 15 String version = await AppConfigHelper.getAppVersion();
15 16 options.headers["version"] = version;
  17 + options.headers["User-Agent"] = defaultTargetPlatform == TargetPlatform.iOS ? "ios" : "android";
16 18 super.onRequest(options, handler);
17 19 }
18 20 }
... ...
lib/generated/json/app_config_entity.g.dart
... ... @@ -3,49 +3,6 @@ import &#39;package:wow_english/models/app_config_entity.dart&#39;;
3 3  
4 4 AppConfigEntity $AppConfigEntityFromJson(Map<String, dynamic> json) {
5 5 final AppConfigEntity appConfigEntity = AppConfigEntity();
6   - final bool? androidForceUpdate = jsonConvert.convert<bool>(
7   - json['androidForceUpdate']);
8   - if (androidForceUpdate != null) {
9   - appConfigEntity.androidForceUpdate = androidForceUpdate;
10   - }
11   - final bool? androidRecommendUpdate = jsonConvert.convert<bool>(
12   - json['androidRecommendUpdate']);
13   - if (androidRecommendUpdate != null) {
14   - appConfigEntity.androidRecommendUpdate = androidRecommendUpdate;
15   - }
16   - final String? androidUpdatePackageUrl = jsonConvert.convert<String>(
17   - json['androidUpdatePackageUrl']);
18   - if (androidUpdatePackageUrl != null) {
19   - appConfigEntity.androidUpdatePackageUrl = androidUpdatePackageUrl;
20   - }
21   - final int? androidVersion = jsonConvert.convert<int>(json['androidVersion']);
22   - if (androidVersion != null) {
23   - appConfigEntity.androidVersion = androidVersion;
24   - }
25   - final bool? iosForceUpdate = jsonConvert.convert<bool>(
26   - json['iosForceUpdate']);
27   - if (iosForceUpdate != null) {
28   - appConfigEntity.iosForceUpdate = iosForceUpdate;
29   - }
30   - final bool? iosRecommendUpdate = jsonConvert.convert<bool>(
31   - json['iosRecommendUpdate']);
32   - if (iosRecommendUpdate != null) {
33   - appConfigEntity.iosRecommendUpdate = iosRecommendUpdate;
34   - }
35   - final int? iosVersion = jsonConvert.convert<int>(json['iosVersion']);
36   - if (iosVersion != null) {
37   - appConfigEntity.iosVersion = iosVersion;
38   - }
39   - final String? updatePackageDescription = jsonConvert.convert<String>(
40   - json['updatePackageDescription']);
41   - if (updatePackageDescription != null) {
42   - appConfigEntity.updatePackageDescription = updatePackageDescription;
43   - }
44   - final String? noticeBeforePurchaseUrl = jsonConvert.convert<String>(
45   - json['noticeBeforePurchaseUrl']);
46   - if (noticeBeforePurchaseUrl != null) {
47   - appConfigEntity.noticeBeforePurchaseUrl = noticeBeforePurchaseUrl;
48   - }
49 6 final String? safe = jsonConvert.convert<String>(json['safe']);
50 7 if (safe != null) {
51 8 appConfigEntity.safe = safe;
... ... @@ -55,46 +12,15 @@ AppConfigEntity $AppConfigEntityFromJson(Map&lt;String, dynamic&gt; json) {
55 12  
56 13 Map<String, dynamic> $AppConfigEntityToJson(AppConfigEntity entity) {
57 14 final Map<String, dynamic> data = <String, dynamic>{};
58   - data['androidForceUpdate'] = entity.androidForceUpdate;
59   - data['androidRecommendUpdate'] = entity.androidRecommendUpdate;
60   - data['androidUpdatePackageUrl'] = entity.androidUpdatePackageUrl;
61   - data['androidVersion'] = entity.androidVersion;
62   - data['iosForceUpdate'] = entity.iosForceUpdate;
63   - data['iosRecommendUpdate'] = entity.iosRecommendUpdate;
64   - data['iosVersion'] = entity.iosVersion;
65   - data['updatePackageDescription'] = entity.updatePackageDescription;
66   - data['noticeBeforePurchaseUrl'] = entity.noticeBeforePurchaseUrl;
67 15 data['safe'] = entity.safe;
68 16 return data;
69 17 }
70 18  
71 19 extension AppConfigEntityExtension on AppConfigEntity {
72 20 AppConfigEntity copyWith({
73   - bool? androidForceUpdate,
74   - bool? androidRecommendUpdate,
75   - String? androidUpdatePackageUrl,
76   - int? androidVersion,
77   - bool? iosForceUpdate,
78   - bool? iosRecommendUpdate,
79   - int? iosVersion,
80   - String? updatePackageDescription,
81   - String? noticeBeforePurchaseUrl,
82 21 String? safe,
83 22 }) {
84 23 return AppConfigEntity()
85   - ..androidForceUpdate = androidForceUpdate ?? this.androidForceUpdate
86   - ..androidRecommendUpdate = androidRecommendUpdate ??
87   - this.androidRecommendUpdate
88   - ..androidUpdatePackageUrl = androidUpdatePackageUrl ??
89   - this.androidUpdatePackageUrl
90   - ..androidVersion = androidVersion ?? this.androidVersion
91   - ..iosForceUpdate = iosForceUpdate ?? this.iosForceUpdate
92   - ..iosRecommendUpdate = iosRecommendUpdate ?? this.iosRecommendUpdate
93   - ..iosVersion = iosVersion ?? this.iosVersion
94   - ..updatePackageDescription = updatePackageDescription ??
95   - this.updatePackageDescription
96   - ..noticeBeforePurchaseUrl = noticeBeforePurchaseUrl ??
97   - this.noticeBeforePurchaseUrl
98 24 ..safe = safe ?? this.safe;
99 25 }
100 26 }
101 27 \ No newline at end of file
... ...
lib/generated/json/app_version_entity.g.dart 0 → 100644
  1 +import 'package:wow_english/generated/json/base/json_convert_content.dart';
  2 +import 'package:wow_english/models/app_version_entity.dart';
  3 +
  4 +AppVersionEntity $AppVersionEntityFromJson(Map<String, dynamic> json) {
  5 + final AppVersionEntity appVersionEntity = AppVersionEntity();
  6 + final String? packageUrl = jsonConvert.convert<String>(json['packageUrl']);
  7 + if (packageUrl != null) {
  8 + appVersionEntity.packageUrl = packageUrl;
  9 + }
  10 + final String? packageName = jsonConvert.convert<String>(json['packageName']);
  11 + if (packageName != null) {
  12 + appVersionEntity.packageName = packageName;
  13 + }
  14 + final String? packageSize = jsonConvert.convert<String>(json['packageSize']);
  15 + if (packageSize != null) {
  16 + appVersionEntity.packageSize = packageSize;
  17 + }
  18 + final String? platformType = jsonConvert.convert<String>(
  19 + json['platformType']);
  20 + if (platformType != null) {
  21 + appVersionEntity.platformType = platformType;
  22 + }
  23 + final String? remark = jsonConvert.convert<String>(json['remark']);
  24 + if (remark != null) {
  25 + appVersionEntity.remark = remark;
  26 + }
  27 + final String? status = jsonConvert.convert<String>(json['status']);
  28 + if (status != null) {
  29 + appVersionEntity.status = status;
  30 + }
  31 + final String? version = jsonConvert.convert<String>(json['version']);
  32 + if (version != null) {
  33 + appVersionEntity.version = version;
  34 + }
  35 + final String? volType = jsonConvert.convert<String>(json['volType']);
  36 + if (volType != null) {
  37 + appVersionEntity.volType = volType;
  38 + }
  39 + return appVersionEntity;
  40 +}
  41 +
  42 +Map<String, dynamic> $AppVersionEntityToJson(AppVersionEntity entity) {
  43 + final Map<String, dynamic> data = <String, dynamic>{};
  44 + data['packageUrl'] = entity.packageUrl;
  45 + data['packageName'] = entity.packageName;
  46 + data['packageSize'] = entity.packageSize;
  47 + data['platformType'] = entity.platformType;
  48 + data['remark'] = entity.remark;
  49 + data['status'] = entity.status;
  50 + data['version'] = entity.version;
  51 + data['volType'] = entity.volType;
  52 + return data;
  53 +}
  54 +
  55 +extension AppVersionEntityExtension on AppVersionEntity {
  56 + AppVersionEntity copyWith({
  57 + String? packageUrl,
  58 + String? packageName,
  59 + String? packageSize,
  60 + String? platformType,
  61 + String? remark,
  62 + String? status,
  63 + String? version,
  64 + String? volType,
  65 + }) {
  66 + return AppVersionEntity()
  67 + ..packageUrl = packageUrl ?? this.packageUrl
  68 + ..packageName = packageName ?? this.packageName
  69 + ..packageSize = packageSize ?? this.packageSize
  70 + ..platformType = platformType ?? this.platformType
  71 + ..remark = remark ?? this.remark
  72 + ..status = status ?? this.status
  73 + ..version = version ?? this.version
  74 + ..volType = volType ?? this.volType;
  75 + }
  76 +}
0 77 \ No newline at end of file
... ...
lib/generated/json/base/json_convert_content.dart
... ... @@ -6,6 +6,7 @@
6 6 import 'package:flutter/material.dart' show debugPrint;
7 7 import 'package:wow_english/models/aliyun_oss_upload_sts_entity.dart';
8 8 import 'package:wow_english/models/app_config_entity.dart';
  9 +import 'package:wow_english/models/app_version_entity.dart';
9 10 import 'package:wow_english/models/course_entity.dart';
10 11 import 'package:wow_english/models/course_module_entity.dart';
11 12 import 'package:wow_english/models/course_process_entity.dart';
... ... @@ -160,6 +161,10 @@ class JsonConvert {
160 161 return data.map<AppConfigEntity>((Map<String, dynamic> e) =>
161 162 AppConfigEntity.fromJson(e)).toList() as M;
162 163 }
  164 + if (<AppVersionEntity>[] is M) {
  165 + return data.map<AppVersionEntity>((Map<String, dynamic> e) =>
  166 + AppVersionEntity.fromJson(e)).toList() as M;
  167 + }
163 168 if (<CourseEntity>[] is M) {
164 169 return data.map<CourseEntity>((Map<String, dynamic> e) =>
165 170 CourseEntity.fromJson(e)).toList() as M;
... ... @@ -246,6 +251,7 @@ class JsonConvertClassCollection {
246 251 (AliyunOssUploadStsCallbackParam)
247 252 .toString(): AliyunOssUploadStsCallbackParam.fromJson,
248 253 (AppConfigEntity).toString(): AppConfigEntity.fromJson,
  254 + (AppVersionEntity).toString(): AppVersionEntity.fromJson,
249 255 (CourseEntity).toString(): CourseEntity.fromJson,
250 256 (CourseCourseLessons).toString(): CourseCourseLessons.fromJson,
251 257 (CourseModuleEntity).toString(): CourseModuleEntity.fromJson,
... ...
lib/models/app_config_entity.dart
... ... @@ -7,31 +7,6 @@ import &#39;../generated/json/app_config_entity.g.dart&#39;;
7 7 @JsonSerializable()
8 8 class AppConfigEntity {
9 9  
10   - // 安卓是否强制更新
11   - bool? androidForceUpdate;
12   -
13   - // 安卓是否推荐更新
14   - bool? androidRecommendUpdate;
15   -
16   - // 安卓更新包地址
17   - String? androidUpdatePackageUrl;
18   -
19   - // 安卓当前版本号
20   - int? androidVersion;
21   -
22   - bool? iosForceUpdate;
23   -
24   - bool? iosRecommendUpdate;
25   -
26   - // ios版本
27   - int? iosVersion;
28   -
29   - // 更新说明
30   - String? updatePackageDescription;
31   -
32   - // 购前须知图片
33   - String? noticeBeforePurchaseUrl;
34   -
35 10 // 当前是否安全,safe-安全 otherwise-隐藏pay
36 11 String? safe;
37 12  
... ...
lib/models/app_version_entity.dart 0 → 100644
  1 +import 'package:wow_english/generated/json/base/json_field.dart';
  2 +import 'package:wow_english/generated/json/app_version_entity.g.dart';
  3 +import 'dart:convert';
  4 +export 'package:wow_english/generated/json/app_version_entity.g.dart';
  5 +
  6 +@JsonSerializable()
  7 +class AppVersionEntity {
  8 +
  9 + // 更新包地址
  10 + String? packageUrl;
  11 +
  12 + // 更新包名
  13 + String? packageName;
  14 +
  15 + // 更新包大小
  16 + String? packageSize;
  17 +
  18 + // 平台类型
  19 + String? platformType;
  20 +
  21 + // 更新说明
  22 + String? remark;
  23 +
  24 + // 状态
  25 + String? status;
  26 +
  27 + // app版本号
  28 + String? version;
  29 +
  30 + // 强更类型
  31 + String? volType;
  32 +
  33 +
  34 + AppVersionEntity();
  35 +
  36 + factory AppVersionEntity.fromJson(Map<String, dynamic> json) => $AppVersionEntityFromJson(json);
  37 +
  38 + Map<String, dynamic> toJson() => $AppVersionEntityToJson(this);
  39 +
  40 + @override
  41 + String toString() {
  42 + return jsonEncode(this);
  43 + }
  44 +}
  45 +
  46 +enum UpdateStrategy {
  47 + SUGGEST("suggest", "建议更新"),
  48 + FORCE("force", "强制更新");
  49 +
  50 + const UpdateStrategy(this.name, this.chineseName);
  51 +
  52 + final String name;
  53 +
  54 + final String chineseName;
  55 +}
0 56 \ No newline at end of file
... ...
lib/pages/moduleSelect/bloc.dart
... ... @@ -4,6 +4,9 @@ import &#39;package:flutter/foundation.dart&#39;;
4 4 import 'package:wow_english/models/app_config_entity.dart';
5 5  
6 6 import '../../common/core/app_config_helper.dart';
  7 +import '../../common/request/dao/system_dao.dart';
  8 +import '../../models/app_version_entity.dart';
  9 +import '../../utils/log_util.dart';
7 10 import 'event.dart';
8 11 import 'state.dart';
9 12  
... ... @@ -18,23 +21,25 @@ class ModuleSelectBloc extends Bloc&lt;ModuleSelectEvent, ModuleSelectState&gt; {
18 21 }
19 22  
20 23 Future<void> _checkUpdate(Emitter<ModuleSelectState> emit) async {
  24 + if (AppConfigHelper.checkedUpdate) {
  25 + return;
  26 + }
21 27 int localVersion = int.parse(await AppConfigHelper.getAppVersion());
22   - AppConfigEntity? appConfigEntity = await AppConfigHelper.getAppConfig();
23   - if (appConfigEntity == null) {
  28 + AppVersionEntity? appVersionEntity = await SystemDao.getVersionInfo();
  29 + AppConfigHelper.checkedUpdate = true;
  30 + if (appVersionEntity == null) {
24 31 return;
25 32 }
  33 + Log.d("WQF _checkUpdate appVersionEntity: $appVersionEntity localVersion=$localVersion");
26 34 if (defaultTargetPlatform == TargetPlatform.iOS) {
27   - if (localVersion < (appConfigEntity.iosVersion ?? 0) &&
28   - appConfigEntity.iosRecommendUpdate == true) {
  35 + if (localVersion < int.parse(appVersionEntity.version ?? '0')) {
29 36 emit(UpdateDialogState(
30   - appConfigEntity.iosForceUpdate ?? false, appConfigEntity));
  37 + appVersionEntity.volType == UpdateStrategy.FORCE.name, appVersionEntity));
31 38 }
32 39 } else {
33   - if (localVersion < (appConfigEntity.androidVersion ?? 0) &&
34   - appConfigEntity.androidRecommendUpdate == true) {
  40 + if (localVersion < int.parse(appVersionEntity.version ?? '0')) {
35 41 emit(UpdateDialogState(
36   - appConfigEntity.androidForceUpdate ?? false, appConfigEntity,
37   - ));
  42 + appVersionEntity.volType == UpdateStrategy.FORCE.name, appVersionEntity));
38 43 }
39 44 }
40 45 }
... ...
lib/pages/moduleSelect/state.dart
1   -import '../../models/app_config_entity.dart';
  1 +import 'package:wow_english/models/app_version_entity.dart';
2 2  
3 3 class ModuleSelectState {
4 4 ModuleSelectState init() {
... ... @@ -12,9 +12,9 @@ class ModuleSelectState {
12 12  
13 13 class UpdateDialogState extends ModuleSelectState {
14 14  
15   - final AppConfigEntity appConfigEntity;
  15 + final AppVersionEntity appVersionEntity;
16 16  
17 17 final bool forceUpdate;
18 18  
19   - UpdateDialogState(this.forceUpdate, this.appConfigEntity);
  19 + UpdateDialogState(this.forceUpdate, this.appVersionEntity);
20 20 }
... ...
lib/pages/moduleSelect/view.dart
... ... @@ -8,13 +8,14 @@ import &#39;package:flutter_bloc/flutter_bloc.dart&#39;;
8 8 import 'package:url_launcher/url_launcher.dart';
9 9 import 'package:wow_english/common/core/app_config_helper.dart';
10 10 import 'package:wow_english/common/extension/string_extension.dart';
  11 +import 'package:wow_english/models/app_version_entity.dart';
11 12 import 'package:wow_english/pages/moduleSelect/state.dart';
12 13 import 'package:wow_english/pages/moduleSelect/widgets/BaseHomeHeaderWidget.dart';
13 14 import 'package:wow_english/pages/user/bloc/user_bloc.dart';
14 15  
15 16 import '../../common/core/user_util.dart';
16 17 import '../../common/dialogs/show_dialog.dart';
17   -import '../../models/app_config_entity.dart';
  18 +import '../../utils/log_util.dart';
18 19 import 'bloc.dart';
19 20 import 'event.dart';
20 21 import 'package:flutter_screenutil/flutter_screenutil.dart';
... ... @@ -44,7 +45,7 @@ class _HomePageView extends StatelessWidget {
44 45 BlocListener<ModuleSelectBloc, ModuleSelectState>(
45 46 listener: (context, state) {
46 47 if (state is UpdateDialogState) {
47   - _showUpdateDialog(context, state.forceUpdate, state.appConfigEntity);
  48 + _showUpdateDialog(context, state.forceUpdate, state.appVersionEntity);
48 49 }
49 50 },
50 51 ),
... ... @@ -169,7 +170,7 @@ class _HomePageView extends StatelessWidget {
169 170 ///Flutter侧处理升级对话框
170 171 ///[forcedUpgrade] 是否强制升级
171 172 _showUpdateDialog(BuildContext context, bool forcedUpgrade,
172   - AppConfigEntity appConfigEntity) {
  173 + AppVersionEntity appVersionEntity) {
173 174 showDialog(
174 175 context: context,
175 176 // 当我们点击除开对话框内容以外的区域是否关闭对话需用用到barrierDismissible参数 . 这个参数默认值是true ,但不能为null .
... ... @@ -180,7 +181,7 @@ class _HomePageView extends StatelessWidget {
180 181 child: AlertDialog(
181 182 title: const Text('发现新版本'),
182 183 content: Text(
183   - appConfigEntity.updatePackageDescription ??
  184 + appVersionEntity.remark ??
184 185 '修复了一些已知问题'),
185 186 actions: <Widget>[
186 187 TextButton(
... ... @@ -202,7 +203,7 @@ class _HomePageView extends StatelessWidget {
202 203 _launchAppStore("6450870731");
203 204 return;
204 205 }
205   - final String? apkUrl = appConfigEntity.androidUpdatePackageUrl;
  206 + final String? apkUrl = appVersionEntity.packageUrl;
206 207 if (apkUrl == null || apkUrl.isEmpty) {
207 208 return;
208 209 }
... ...