Commit ed94c3db741cfb8ab06d1d12dacb719afdec2c5a
Merge remote-tracking branch 'origin/feat-wqf-payment' into xiaoyu_cocossteve
Showing
24 changed files
with
508 additions
and
240 deletions
android/app/build.gradle
| @@ -93,5 +93,5 @@ dependencies { | @@ -93,5 +93,5 @@ dependencies { | ||
| 93 | implementation 'com.geyifeng.immersionbar:immersionbar:3.2.2' | 93 | implementation 'com.geyifeng.immersionbar:immersionbar:3.2.2' |
| 94 | // kotlin扩展(可选) | 94 | // kotlin扩展(可选) |
| 95 | implementation 'com.geyifeng.immersionbar:immersionbar-ktx:3.2.2' | 95 | implementation 'com.geyifeng.immersionbar:immersionbar-ktx:3.2.2' |
| 96 | - implementation 'io.keyss.android.library:bjgame:1.0.2' | 96 | + implementation 'io.keyss.android.library:bjgame:1.0.3' |
| 97 | } | 97 | } |
lib/app/splash_page.dart
| @@ -6,6 +6,7 @@ import 'package:flutter/foundation.dart'; | @@ -6,6 +6,7 @@ import 'package:flutter/foundation.dart'; | ||
| 6 | import 'package:flutter/material.dart'; | 6 | import 'package:flutter/material.dart'; |
| 7 | import 'package:flutter/services.dart'; | 7 | import 'package:flutter/services.dart'; |
| 8 | import 'package:limiting_direction_csx/limiting_direction_csx.dart'; | 8 | import 'package:limiting_direction_csx/limiting_direction_csx.dart'; |
| 9 | +import 'package:wow_english/common/core/app_config_helper.dart'; | ||
| 9 | import 'package:wow_english/common/core/user_util.dart'; | 10 | import 'package:wow_english/common/core/user_util.dart'; |
| 10 | import 'package:wow_english/common/extension/string_extension.dart'; | 11 | import 'package:wow_english/common/extension/string_extension.dart'; |
| 11 | import 'package:wow_english/common/request/config.dart'; | 12 | import 'package:wow_english/common/request/config.dart'; |
| @@ -44,9 +45,11 @@ class _TransitionViewState extends State<TransitionView> { | @@ -44,9 +45,11 @@ class _TransitionViewState extends State<TransitionView> { | ||
| 44 | //Log.d('Splash读当前页面:$currentPageName'); | 45 | //Log.d('Splash读当前页面:$currentPageName'); |
| 45 | Log.d('Splash读本地, userEntity: $userEntity'); | 46 | Log.d('Splash读本地, userEntity: $userEntity'); |
| 46 | int apartInMilliseconds = 0; | 47 | int apartInMilliseconds = 0; |
| 48 | + // 阻塞获取系统配置信息 | ||
| 49 | + await AppConfigHelper.getAppConfig(); | ||
| 47 | // 调一下接口判断一下有效性再往下 | 50 | // 调一下接口判断一下有效性再往下 |
| 48 | - if (userEntity != null) { | ||
| 49 | - String token = userEntity.token; | 51 | + if (userEntity != null && userEntity.token != null) { |
| 52 | + String token = userEntity.token!; | ||
| 50 | DateTime startTime = DateTime.now(); | 53 | DateTime startTime = DateTime.now(); |
| 51 | try { | 54 | try { |
| 52 | userEntity = await UserDao.getUserInfo(); | 55 | userEntity = await UserDao.getUserInfo(); |
lib/common/core/app_config_helper.dart
0 → 100644
| 1 | +import 'dart:ffi'; | ||
| 2 | +import 'dart:io'; | ||
| 3 | + | ||
| 4 | +import 'package:flutter/cupertino.dart'; | ||
| 5 | +import 'package:package_info_plus/package_info_plus.dart'; | ||
| 6 | +import 'package:wow_english/common/core/user_util.dart'; | ||
| 7 | + | ||
| 8 | +import '../../models/app_config_entity.dart'; | ||
| 9 | +import '../request/dao/system_dao.dart'; | ||
| 10 | + | ||
| 11 | +class AppConfigHelper { | ||
| 12 | + | ||
| 13 | + static AppConfigEntityEntity? configEntityEntity; | ||
| 14 | + | ||
| 15 | + static String versionCode = ''; | ||
| 16 | + | ||
| 17 | + /// 获取用户信息 | ||
| 18 | + static Future<Void?> getAppConfig() async { | ||
| 19 | + configEntityEntity = await SystemDao.getAppConfig(); | ||
| 20 | + return null; | ||
| 21 | + } | ||
| 22 | + | ||
| 23 | + // 是否需要隐藏... | ||
| 24 | + static bool shouldHidePay() { | ||
| 25 | + return configEntityEntity?.isAppReviewing() == true || UserUtil.getUser()?.phoneNum == "17730280759"; | ||
| 26 | + } | ||
| 27 | + | ||
| 28 | + // 获取app版本号 | ||
| 29 | + static Future<String> getAppVersion() async { | ||
| 30 | + if (versionCode.isNotEmpty) { | ||
| 31 | + return versionCode; | ||
| 32 | + } | ||
| 33 | + PackageInfo packageInfo = await PackageInfo.fromPlatform(); | ||
| 34 | + String version = packageInfo.version; // 版本号 | ||
| 35 | + String buildNumber = packageInfo.buildNumber; // 构建号 | ||
| 36 | + versionCode = version; | ||
| 37 | + | ||
| 38 | + debugPrint('versionCode=$versionCode platForm=${Platform.operatingSystem}'); | ||
| 39 | + return versionCode; | ||
| 40 | + } | ||
| 41 | +} |
lib/common/core/user_util.dart
| @@ -11,8 +11,6 @@ import 'package:wow_english/utils/sp_util.dart'; | @@ -11,8 +11,6 @@ import 'package:wow_english/utils/sp_util.dart'; | ||
| 11 | class UserUtil { | 11 | class UserUtil { |
| 12 | static UserEntity? _userEntity; | 12 | static UserEntity? _userEntity; |
| 13 | 13 | ||
| 14 | - static String get token => _userEntity?.token ?? ''; | ||
| 15 | - | ||
| 16 | static void saveUser(UserEntity? user) { | 14 | static void saveUser(UserEntity? user) { |
| 17 | if (user == null) { | 15 | if (user == null) { |
| 18 | _clearUserData(); | 16 | _clearUserData(); |
| @@ -54,7 +52,7 @@ class UserUtil { | @@ -54,7 +52,7 @@ class UserUtil { | ||
| 54 | SpUtil.getInstance().remove(SpConst.prefsKeyUserInfo); | 52 | SpUtil.getInstance().remove(SpConst.prefsKeyUserInfo); |
| 55 | } | 53 | } |
| 56 | 54 | ||
| 57 | - static void logout() { | 55 | + static void logout([bool showPasswordLoginPage = false]) { |
| 58 | _clearUserData(); | 56 | _clearUserData(); |
| 59 | // 判断下不在Splash页就跳转 | 57 | // 判断下不在Splash页就跳转 |
| 60 | /*var currentPageName = ModalRoute.of(AppRouter.context)?.settings.name; | 58 | /*var currentPageName = ModalRoute.of(AppRouter.context)?.settings.name; |
| @@ -62,6 +60,25 @@ class UserUtil { | @@ -62,6 +60,25 @@ class UserUtil { | ||
| 62 | if (currentPageName != AppRouteName.splash) { | 60 | if (currentPageName != AppRouteName.splash) { |
| 63 | Navigator.of(AppRouter.context).pushNamedAndRemoveUntil(AppRouteName.login, (route) => false); | 61 | Navigator.of(AppRouter.context).pushNamedAndRemoveUntil(AppRouteName.login, (route) => false); |
| 64 | }*/ | 62 | }*/ |
| 65 | - Navigator.of(AppRouter.context).pushNamedAndRemoveUntil(AppRouteName.login, (route) => false); | 63 | + Navigator.of(AppRouter.context).pushNamedAndRemoveUntil(AppRouteName.login, (route) => false, arguments: {'showPasswordPage': showPasswordLoginPage}); |
| 64 | + } | ||
| 65 | + | ||
| 66 | + // 是否有游戏权限 | ||
| 67 | + static bool hasGamePermission() { | ||
| 68 | + return _userEntity?.valid ?? false; | ||
| 69 | + } | ||
| 70 | + | ||
| 71 | + // 是否登录(token是否有效) | ||
| 72 | + static bool isLogined() { | ||
| 73 | + return getUserToken().isNotEmpty; | ||
| 74 | + } | ||
| 75 | + | ||
| 76 | + static String getUserToken() { | ||
| 77 | + return _userEntity?.token ?? ''; | ||
| 78 | + } | ||
| 79 | + | ||
| 80 | + // (vip)剩余有效期 | ||
| 81 | + static int getRemainingValidity() { | ||
| 82 | + return _userEntity?.validDay ?? 0; | ||
| 66 | } | 83 | } |
| 67 | } | 84 | } |
lib/common/request/dao/system_dao.dart
0 → 100644
lib/common/request/dao/user_dao.dart
| @@ -16,6 +16,12 @@ class UserDao { | @@ -16,6 +16,12 @@ class UserDao { | ||
| 16 | ); | 16 | ); |
| 17 | if (data != null) { | 17 | if (data != null) { |
| 18 | UserUtil.saveUser(data); | 18 | UserUtil.saveUser(data); |
| 19 | + // 由于userInfo接口不会返回token,所以这里需要再次保存一下token | ||
| 20 | + final token = data.token; | ||
| 21 | + //登录成功后zip一下getUserInfo,因为进入首页需要的信息在userinfo里,保证进入首页数据是最新的 | ||
| 22 | + data = await getUserInfo(); | ||
| 23 | + data?.token = token; | ||
| 24 | + UserUtil.saveUser(data); | ||
| 19 | } | 25 | } |
| 20 | return data; | 26 | return data; |
| 21 | } | 27 | } |
lib/common/request/token_interceptor.dart
| 1 | import 'package:dio/dio.dart'; | 1 | import 'package:dio/dio.dart'; |
| 2 | import 'package:wow_english/common/core/user_util.dart'; | 2 | import 'package:wow_english/common/core/user_util.dart'; |
| 3 | 3 | ||
| 4 | +import '../core/app_config_helper.dart'; | ||
| 5 | + | ||
| 4 | class TokenInterceptor extends Interceptor { | 6 | class TokenInterceptor extends Interceptor { |
| 5 | @override | 7 | @override |
| 6 | - void onRequest(RequestOptions options, RequestInterceptorHandler handler) { | 8 | + void onRequest(RequestOptions options, RequestInterceptorHandler handler) async { |
| 7 | // 判断token不为空插入, todo token的取法应该跟user在一起,这里取不到user | 9 | // 判断token不为空插入, todo token的取法应该跟user在一起,这里取不到user |
| 8 | - if (UserUtil.token.isNotEmpty) { | ||
| 9 | - options.headers["Auth-token"] = UserUtil.token; | 10 | + if (UserUtil.isLogined()) { |
| 11 | + options.headers["Auth-token"] = UserUtil.getUserToken(); | ||
| 10 | } | 12 | } |
| 11 | - options.headers["version"] = '1.0.0'; | 13 | + // 在发送请求之前获取版本号 |
| 14 | + String version = await AppConfigHelper.getAppVersion(); | ||
| 15 | + options.headers["version"] = version; | ||
| 12 | super.onRequest(options, handler); | 16 | super.onRequest(options, handler); |
| 13 | } | 17 | } |
| 14 | } | 18 | } |
lib/generated/json/app_config_entity.g.dart
0 → 100644
| 1 | +import 'package:wow_english/generated/json/base/json_convert_content.dart'; | ||
| 2 | +import 'package:wow_english/models/app_config_entity.dart'; | ||
| 3 | + | ||
| 4 | +AppConfigEntityEntity $AppConfigEntityEntityFromJson( | ||
| 5 | + Map<String, dynamic> json) { | ||
| 6 | + final AppConfigEntityEntity appConfigEntityEntity = AppConfigEntityEntity(); | ||
| 7 | + final bool? androidForceUpdate = jsonConvert.convert<bool>( | ||
| 8 | + json['androidForceUpdate']); | ||
| 9 | + if (androidForceUpdate != null) { | ||
| 10 | + appConfigEntityEntity.androidForceUpdate = androidForceUpdate; | ||
| 11 | + } | ||
| 12 | + final bool? androidRecommendUpdate = jsonConvert.convert<bool>( | ||
| 13 | + json['androidRecommendUpdate']); | ||
| 14 | + if (androidRecommendUpdate != null) { | ||
| 15 | + appConfigEntityEntity.androidRecommendUpdate = androidRecommendUpdate; | ||
| 16 | + } | ||
| 17 | + final String? androidUpdatePackageUrl = jsonConvert.convert<String>( | ||
| 18 | + json['androidUpdatePackageUrl']); | ||
| 19 | + if (androidUpdatePackageUrl != null) { | ||
| 20 | + appConfigEntityEntity.androidUpdatePackageUrl = androidUpdatePackageUrl; | ||
| 21 | + } | ||
| 22 | + final int? androidVersion = jsonConvert.convert<int>(json['androidVersion']); | ||
| 23 | + if (androidVersion != null) { | ||
| 24 | + appConfigEntityEntity.androidVersion = androidVersion; | ||
| 25 | + } | ||
| 26 | + final bool? iosForceUpdate = jsonConvert.convert<bool>( | ||
| 27 | + json['iosForceUpdate']); | ||
| 28 | + if (iosForceUpdate != null) { | ||
| 29 | + appConfigEntityEntity.iosForceUpdate = iosForceUpdate; | ||
| 30 | + } | ||
| 31 | + final bool? iosRecommendUpdate = jsonConvert.convert<bool>( | ||
| 32 | + json['iosRecommendUpdate']); | ||
| 33 | + if (iosRecommendUpdate != null) { | ||
| 34 | + appConfigEntityEntity.iosRecommendUpdate = iosRecommendUpdate; | ||
| 35 | + } | ||
| 36 | + final int? iosVersion = jsonConvert.convert<int>(json['iosVersion']); | ||
| 37 | + if (iosVersion != null) { | ||
| 38 | + appConfigEntityEntity.iosVersion = iosVersion; | ||
| 39 | + } | ||
| 40 | + final String? noticeBeforePurchaseUrl = jsonConvert.convert<String>( | ||
| 41 | + json['noticeBeforePurchaseUrl']); | ||
| 42 | + if (noticeBeforePurchaseUrl != null) { | ||
| 43 | + appConfigEntityEntity.noticeBeforePurchaseUrl = noticeBeforePurchaseUrl; | ||
| 44 | + } | ||
| 45 | + final String? safe = jsonConvert.convert<String>(json['safe']); | ||
| 46 | + if (safe != null) { | ||
| 47 | + appConfigEntityEntity.safe = safe; | ||
| 48 | + } | ||
| 49 | + return appConfigEntityEntity; | ||
| 50 | +} | ||
| 51 | + | ||
| 52 | +Map<String, dynamic> $AppConfigEntityEntityToJson( | ||
| 53 | + AppConfigEntityEntity entity) { | ||
| 54 | + final Map<String, dynamic> data = <String, dynamic>{}; | ||
| 55 | + data['androidForceUpdate'] = entity.androidForceUpdate; | ||
| 56 | + data['androidRecommendUpdate'] = entity.androidRecommendUpdate; | ||
| 57 | + data['androidUpdatePackageUrl'] = entity.androidUpdatePackageUrl; | ||
| 58 | + data['androidVersion'] = entity.androidVersion; | ||
| 59 | + data['iosForceUpdate'] = entity.iosForceUpdate; | ||
| 60 | + data['iosRecommendUpdate'] = entity.iosRecommendUpdate; | ||
| 61 | + data['iosVersion'] = entity.iosVersion; | ||
| 62 | + data['noticeBeforePurchaseUrl'] = entity.noticeBeforePurchaseUrl; | ||
| 63 | + data['safe'] = entity.safe; | ||
| 64 | + return data; | ||
| 65 | +} | ||
| 66 | + | ||
| 67 | +extension AppConfigEntityEntityExtension on AppConfigEntityEntity { | ||
| 68 | + AppConfigEntityEntity copyWith({ | ||
| 69 | + bool? androidForceUpdate, | ||
| 70 | + bool? androidRecommendUpdate, | ||
| 71 | + String? androidUpdatePackageUrl, | ||
| 72 | + int? androidVersion, | ||
| 73 | + bool? iosForceUpdate, | ||
| 74 | + bool? iosRecommendUpdate, | ||
| 75 | + int? iosVersion, | ||
| 76 | + String? noticeBeforePurchaseUrl, | ||
| 77 | + String? safe, | ||
| 78 | + }) { | ||
| 79 | + return AppConfigEntityEntity() | ||
| 80 | + ..androidForceUpdate = androidForceUpdate ?? this.androidForceUpdate | ||
| 81 | + ..androidRecommendUpdate = androidRecommendUpdate ?? | ||
| 82 | + this.androidRecommendUpdate | ||
| 83 | + ..androidUpdatePackageUrl = androidUpdatePackageUrl ?? | ||
| 84 | + this.androidUpdatePackageUrl | ||
| 85 | + ..androidVersion = androidVersion ?? this.androidVersion | ||
| 86 | + ..iosForceUpdate = iosForceUpdate ?? this.iosForceUpdate | ||
| 87 | + ..iosRecommendUpdate = iosRecommendUpdate ?? this.iosRecommendUpdate | ||
| 88 | + ..iosVersion = iosVersion ?? this.iosVersion | ||
| 89 | + ..noticeBeforePurchaseUrl = noticeBeforePurchaseUrl ?? | ||
| 90 | + this.noticeBeforePurchaseUrl | ||
| 91 | + ..safe = safe ?? this.safe; | ||
| 92 | + } | ||
| 93 | +} | ||
| 0 | \ No newline at end of file | 94 | \ No newline at end of file |
lib/generated/json/base/json_convert_content.dart
| @@ -5,6 +5,7 @@ | @@ -5,6 +5,7 @@ | ||
| 5 | // This file is automatically generated. DO NOT EDIT, all your changes would be lost. | 5 | // This file is automatically generated. DO NOT EDIT, all your changes would be lost. |
| 6 | import 'package:flutter/material.dart' show debugPrint; | 6 | import 'package:flutter/material.dart' show debugPrint; |
| 7 | import 'package:wow_english/models/aliyun_oss_upload_sts_entity.dart'; | 7 | import 'package:wow_english/models/aliyun_oss_upload_sts_entity.dart'; |
| 8 | +import 'package:wow_english/models/app_config_entity.dart'; | ||
| 8 | import 'package:wow_english/models/course_entity.dart'; | 9 | import 'package:wow_english/models/course_entity.dart'; |
| 9 | import 'package:wow_english/models/course_module_entity.dart'; | 10 | import 'package:wow_english/models/course_module_entity.dart'; |
| 10 | import 'package:wow_english/models/course_process_entity.dart'; | 11 | import 'package:wow_english/models/course_process_entity.dart'; |
| @@ -154,6 +155,10 @@ class JsonConvert { | @@ -154,6 +155,10 @@ class JsonConvert { | ||
| 154 | Map<String, dynamic> e) => | 155 | Map<String, dynamic> e) => |
| 155 | AliyunOssUploadStsCallbackParam.fromJson(e)).toList() as M; | 156 | AliyunOssUploadStsCallbackParam.fromJson(e)).toList() as M; |
| 156 | } | 157 | } |
| 158 | + if (<AppConfigEntityEntity>[] is M) { | ||
| 159 | + return data.map<AppConfigEntityEntity>((Map<String, dynamic> e) => | ||
| 160 | + AppConfigEntityEntity.fromJson(e)).toList() as M; | ||
| 161 | + } | ||
| 157 | if (<CourseEntity>[] is M) { | 162 | if (<CourseEntity>[] is M) { |
| 158 | return data.map<CourseEntity>((Map<String, dynamic> e) => | 163 | return data.map<CourseEntity>((Map<String, dynamic> e) => |
| 159 | CourseEntity.fromJson(e)).toList() as M; | 164 | CourseEntity.fromJson(e)).toList() as M; |
| @@ -231,6 +236,7 @@ class JsonConvertClassCollection { | @@ -231,6 +236,7 @@ class JsonConvertClassCollection { | ||
| 231 | (AliyunOssUploadStsEntity).toString(): AliyunOssUploadStsEntity.fromJson, | 236 | (AliyunOssUploadStsEntity).toString(): AliyunOssUploadStsEntity.fromJson, |
| 232 | (AliyunOssUploadStsCallbackParam) | 237 | (AliyunOssUploadStsCallbackParam) |
| 233 | .toString(): AliyunOssUploadStsCallbackParam.fromJson, | 238 | .toString(): AliyunOssUploadStsCallbackParam.fromJson, |
| 239 | + (AppConfigEntityEntity).toString(): AppConfigEntityEntity.fromJson, | ||
| 234 | (CourseEntity).toString(): CourseEntity.fromJson, | 240 | (CourseEntity).toString(): CourseEntity.fromJson, |
| 235 | (CourseCourseLessons).toString(): CourseCourseLessons.fromJson, | 241 | (CourseCourseLessons).toString(): CourseCourseLessons.fromJson, |
| 236 | (CourseModuleEntity).toString(): CourseModuleEntity.fromJson, | 242 | (CourseModuleEntity).toString(): CourseModuleEntity.fromJson, |
lib/generated/json/user_entity.g.dart
| @@ -45,6 +45,14 @@ UserEntity $UserEntityFromJson(Map<String, dynamic> json) { | @@ -45,6 +45,14 @@ UserEntity $UserEntityFromJson(Map<String, dynamic> json) { | ||
| 45 | if (effectiveDate != null) { | 45 | if (effectiveDate != null) { |
| 46 | userEntity.effectiveDate = effectiveDate; | 46 | userEntity.effectiveDate = effectiveDate; |
| 47 | } | 47 | } |
| 48 | + final int? validDay = jsonConvert.convert<int>(json['validDay']); | ||
| 49 | + if (validDay != null) { | ||
| 50 | + userEntity.validDay = validDay; | ||
| 51 | + } | ||
| 52 | + final bool? valid = jsonConvert.convert<bool>(json['valid']); | ||
| 53 | + if (valid != null) { | ||
| 54 | + userEntity.valid = valid; | ||
| 55 | + } | ||
| 48 | return userEntity; | 56 | return userEntity; |
| 49 | } | 57 | } |
| 50 | 58 | ||
| @@ -60,6 +68,8 @@ Map<String, dynamic> $UserEntityToJson(UserEntity entity) { | @@ -60,6 +68,8 @@ Map<String, dynamic> $UserEntityToJson(UserEntity entity) { | ||
| 60 | data['fillUserInfo'] = entity.fillUserInfo; | 68 | data['fillUserInfo'] = entity.fillUserInfo; |
| 61 | data['nowCourseModuleId'] = entity.nowCourseModuleId; | 69 | data['nowCourseModuleId'] = entity.nowCourseModuleId; |
| 62 | data['effectiveDate'] = entity.effectiveDate; | 70 | data['effectiveDate'] = entity.effectiveDate; |
| 71 | + data['validDay'] = entity.validDay; | ||
| 72 | + data['valid'] = entity.valid; | ||
| 63 | return data; | 73 | return data; |
| 64 | } | 74 | } |
| 65 | 75 | ||
| @@ -75,6 +85,8 @@ extension UserEntityExtension on UserEntity { | @@ -75,6 +85,8 @@ extension UserEntityExtension on UserEntity { | ||
| 75 | int? fillUserInfo, | 85 | int? fillUserInfo, |
| 76 | int? nowCourseModuleId, | 86 | int? nowCourseModuleId, |
| 77 | String? effectiveDate, | 87 | String? effectiveDate, |
| 88 | + int? validDay, | ||
| 89 | + bool? valid, | ||
| 78 | }) { | 90 | }) { |
| 79 | return UserEntity() | 91 | return UserEntity() |
| 80 | ..id = id ?? this.id | 92 | ..id = id ?? this.id |
| @@ -86,6 +98,8 @@ extension UserEntityExtension on UserEntity { | @@ -86,6 +98,8 @@ extension UserEntityExtension on UserEntity { | ||
| 86 | ..phoneNum = phoneNum ?? this.phoneNum | 98 | ..phoneNum = phoneNum ?? this.phoneNum |
| 87 | ..fillUserInfo = fillUserInfo ?? this.fillUserInfo | 99 | ..fillUserInfo = fillUserInfo ?? this.fillUserInfo |
| 88 | ..nowCourseModuleId = nowCourseModuleId ?? this.nowCourseModuleId | 100 | ..nowCourseModuleId = nowCourseModuleId ?? this.nowCourseModuleId |
| 89 | - ..effectiveDate = effectiveDate ?? this.effectiveDate; | 101 | + ..effectiveDate = effectiveDate ?? this.effectiveDate |
| 102 | + ..validDay = validDay ?? this.validDay | ||
| 103 | + ..valid = valid ?? this.valid; | ||
| 90 | } | 104 | } |
| 91 | } | 105 | } |
| 92 | \ No newline at end of file | 106 | \ No newline at end of file |
lib/models/app_config_entity.dart
0 → 100644
| 1 | +import 'package:wow_english/generated/json/base/json_field.dart'; | ||
| 2 | +import 'dart:convert'; | ||
| 3 | + | ||
| 4 | +import '../generated/json/app_config_entity.g.dart'; | ||
| 5 | + | ||
| 6 | + | ||
| 7 | +@JsonSerializable() | ||
| 8 | +class AppConfigEntityEntity { | ||
| 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? noticeBeforePurchaseUrl; | ||
| 31 | + | ||
| 32 | + // 当前是否安全,safe-安全 otherwise-隐藏pay | ||
| 33 | + String? safe; | ||
| 34 | + | ||
| 35 | + | ||
| 36 | + AppConfigEntityEntity(); | ||
| 37 | + | ||
| 38 | + factory AppConfigEntityEntity.fromJson(Map<String, dynamic> json) => $AppConfigEntityEntityFromJson(json); | ||
| 39 | + | ||
| 40 | + Map<String, dynamic> toJson() => $AppConfigEntityEntityToJson(this); | ||
| 41 | + | ||
| 42 | + @override | ||
| 43 | + String toString() { | ||
| 44 | + return jsonEncode(this); | ||
| 45 | + } | ||
| 46 | + | ||
| 47 | + // 是否审核中(null或者非"safe"即不安全) | ||
| 48 | + bool isAppReviewing() { | ||
| 49 | + return safe != "safe"; | ||
| 50 | + } | ||
| 51 | +} | ||
| 0 | \ No newline at end of file | 52 | \ No newline at end of file |
lib/models/user_entity.dart
| @@ -9,7 +9,7 @@ class UserEntity { | @@ -9,7 +9,7 @@ class UserEntity { | ||
| 9 | late String name; | 9 | late String name; |
| 10 | 10 | ||
| 11 | /// 一定有也必须要有 | 11 | /// 一定有也必须要有 |
| 12 | - late String token; | 12 | + String? token; |
| 13 | 13 | ||
| 14 | //late int expireTime; | 14 | //late int expireTime; |
| 15 | 15 | ||
| @@ -29,6 +29,12 @@ class UserEntity { | @@ -29,6 +29,12 @@ class UserEntity { | ||
| 29 | /// 有效时间,VIP,为null没有 | 29 | /// 有效时间,VIP,为null没有 |
| 30 | String? effectiveDate; | 30 | String? effectiveDate; |
| 31 | 31 | ||
| 32 | + /// 有效天数 | ||
| 33 | + int? validDay; | ||
| 34 | + | ||
| 35 | + /// 游戏权限 | ||
| 36 | + bool? valid; | ||
| 37 | + | ||
| 32 | UserEntity(); | 38 | UserEntity(); |
| 33 | 39 | ||
| 34 | factory UserEntity.fromJson(Map<String, dynamic> json) => $UserEntityFromJson(json); | 40 | factory UserEntity.fromJson(Map<String, dynamic> json) => $UserEntityFromJson(json); |
lib/pages/home/home_page.dart
| @@ -23,33 +23,30 @@ class HomePage extends StatelessWidget { | @@ -23,33 +23,30 @@ class HomePage extends StatelessWidget { | ||
| 23 | Widget build(BuildContext context) { | 23 | Widget build(BuildContext context) { |
| 24 | return BlocProvider( | 24 | return BlocProvider( |
| 25 | create: (context) => HomeBloc(moduleId)..add(RequestDataEvent()), | 25 | create: (context) => HomeBloc(moduleId)..add(RequestDataEvent()), |
| 26 | - child: _HomePageView(), | 26 | + child: _HomePageView(context), |
| 27 | ); | 27 | ); |
| 28 | } | 28 | } |
| 29 | } | 29 | } |
| 30 | 30 | ||
| 31 | class _HomePageView extends StatelessWidget { | 31 | class _HomePageView extends StatelessWidget { |
| 32 | + | ||
| 33 | + const _HomePageView(this.context); | ||
| 34 | + | ||
| 35 | + final BuildContext context; | ||
| 36 | + | ||
| 32 | void _headerActionEvent(HeaderActionType type) { | 37 | void _headerActionEvent(HeaderActionType type) { |
| 33 | if (type == HeaderActionType.video) { | 38 | if (type == HeaderActionType.video) { |
| 34 | pushNamed(AppRouteName.reAfter); | 39 | pushNamed(AppRouteName.reAfter); |
| 35 | } else if (type == HeaderActionType.phase) { | 40 | } else if (type == HeaderActionType.phase) { |
| 36 | - if(UserUtil.token.isEmpty) { | ||
| 37 | - pushNamed(AppRouteName.login); | ||
| 38 | - } else { | ||
| 39 | - pushNamed(AppRouteName.lesson); | ||
| 40 | - } | 41 | + pushNamed(AppRouteName.lesson); |
| 41 | } else if (type == HeaderActionType.listen) { | 42 | } else if (type == HeaderActionType.listen) { |
| 42 | pushNamed(AppRouteName.listen); | 43 | pushNamed(AppRouteName.listen); |
| 43 | } else if (type == HeaderActionType.shop) { | 44 | } else if (type == HeaderActionType.shop) { |
| 44 | pushNamed(AppRouteName.shop); | 45 | pushNamed(AppRouteName.shop); |
| 45 | } else if (type == HeaderActionType.user) { | 46 | } else if (type == HeaderActionType.user) { |
| 46 | - if(UserUtil.token.isEmpty) { | ||
| 47 | - pushNamed(AppRouteName.login); | ||
| 48 | - } else { | ||
| 49 | - pushNamed(AppRouteName.user); | ||
| 50 | - } | ||
| 51 | - } else { | ||
| 52 | - | 47 | + pushNamed(AppRouteName.user); |
| 48 | + } else if (type == HeaderActionType.home) { | ||
| 49 | + Navigator.pop(context); | ||
| 53 | } | 50 | } |
| 54 | } | 51 | } |
| 55 | 52 | ||
| @@ -155,7 +152,7 @@ class _HomePageView extends StatelessWidget { | @@ -155,7 +152,7 @@ class _HomePageView extends StatelessWidget { | ||
| 155 | //彩蛋 | 152 | //彩蛋 |
| 156 | return GestureDetector( | 153 | return GestureDetector( |
| 157 | onTap: () { | 154 | onTap: () { |
| 158 | - if(UserUtil.token.isEmpty) { | 155 | + if (!UserUtil.isLogined()) { |
| 159 | pushNamed(AppRouteName.login); | 156 | pushNamed(AppRouteName.login); |
| 160 | return; | 157 | return; |
| 161 | } | 158 | } |
| @@ -173,7 +170,7 @@ class _HomePageView extends StatelessWidget { | @@ -173,7 +170,7 @@ class _HomePageView extends StatelessWidget { | ||
| 173 | } else { | 170 | } else { |
| 174 | return GestureDetector( | 171 | return GestureDetector( |
| 175 | onTap: () { | 172 | onTap: () { |
| 176 | - if(UserUtil.token.isEmpty) { | 173 | + if (!UserUtil.isLogined()) { |
| 177 | pushNamed(AppRouteName.login); | 174 | pushNamed(AppRouteName.login); |
| 178 | return; | 175 | return; |
| 179 | } | 176 | } |
lib/pages/home/widgets/home_tab_header_widget.dart
| 1 | import 'package:flutter/material.dart'; | 1 | import 'package:flutter/material.dart'; |
| 2 | import 'package:flutter_bloc/flutter_bloc.dart'; | 2 | import 'package:flutter_bloc/flutter_bloc.dart'; |
| 3 | import 'package:flutter_screenutil/flutter_screenutil.dart'; | 3 | import 'package:flutter_screenutil/flutter_screenutil.dart'; |
| 4 | -import 'package:wow_english/common/core/user_util.dart'; | ||
| 5 | import 'package:wow_english/common/extension/string_extension.dart'; | 4 | import 'package:wow_english/common/extension/string_extension.dart'; |
| 6 | import 'package:wow_english/pages/user/bloc/user_bloc.dart'; | 5 | import 'package:wow_english/pages/user/bloc/user_bloc.dart'; |
| 7 | -import 'package:wow_english/utils/image_util.dart'; | ||
| 8 | 6 | ||
| 7 | +import '../../../common/core/app_config_helper.dart'; | ||
| 9 | import '../../../models/course_entity.dart'; | 8 | import '../../../models/course_entity.dart'; |
| 10 | import '../courese_module_model.dart'; | 9 | import '../courese_module_model.dart'; |
| 11 | 10 | ||
| @@ -19,70 +18,89 @@ enum HeaderActionType { | @@ -19,70 +18,89 @@ enum HeaderActionType { | ||
| 19 | //购买 | 18 | //购买 |
| 20 | shop, | 19 | shop, |
| 21 | //个人信息 | 20 | //个人信息 |
| 22 | - user | 21 | + user, |
| 22 | + //返回到(模块选择)首页 | ||
| 23 | + home, | ||
| 23 | } | 24 | } |
| 24 | 25 | ||
| 25 | class HomeTabHeaderWidget extends StatelessWidget { | 26 | class HomeTabHeaderWidget extends StatelessWidget { |
| 26 | - const HomeTabHeaderWidget({super.key,this.entity, this.actionTap}); | 27 | + const HomeTabHeaderWidget({super.key, this.entity, this.actionTap}); |
| 27 | 28 | ||
| 28 | final CourseEntity? entity; | 29 | final CourseEntity? entity; |
| 29 | final Function(HeaderActionType type)? actionTap; | 30 | final Function(HeaderActionType type)? actionTap; |
| 30 | 31 | ||
| 31 | @override | 32 | @override |
| 32 | Widget build(BuildContext context) { | 33 | Widget build(BuildContext context) { |
| 33 | - return BlocBuilder<UserBloc,UserState>( | ||
| 34 | - builder: (context,state) { | 34 | + return BlocBuilder<UserBloc, UserState>( |
| 35 | + builder: (context, state) { | ||
| 35 | return Container( | 36 | return Container( |
| 36 | height: 45, | 37 | height: 45, |
| 37 | width: double.infinity, | 38 | width: double.infinity, |
| 38 | - color: CourseModuleModel(entity?.courseModuleCode??'Phase-1').color, | 39 | + color: |
| 40 | + CourseModuleModel(entity?.courseModuleCode ?? 'Phase-1').color, | ||
| 39 | padding: EdgeInsets.symmetric(horizontal: 9.5.w), | 41 | padding: EdgeInsets.symmetric(horizontal: 9.5.w), |
| 40 | child: Row( | 42 | child: Row( |
| 41 | children: [ | 43 | children: [ |
| 42 | ScreenUtil().bottomBarHeight.horizontalSpace, | 44 | ScreenUtil().bottomBarHeight.horizontalSpace, |
| 43 | GestureDetector( | 45 | GestureDetector( |
| 44 | - onTap: () => actionTap?.call(HeaderActionType.user), | ||
| 45 | - child: Container( | ||
| 46 | - decoration: BoxDecoration( | ||
| 47 | - border: Border.all( | ||
| 48 | - width: 1.0, | ||
| 49 | - color: const Color(0xFF140C10), | ||
| 50 | - ), | ||
| 51 | - borderRadius: BorderRadius.circular(21), | ||
| 52 | - ), | ||
| 53 | - child: CircleAvatar( | ||
| 54 | - radius: 21, | ||
| 55 | - backgroundImage: ImageUtil.getImageProviderOnDefault(UserUtil.getUser()?.avatarUrl), | ||
| 56 | - ), | ||
| 57 | - ), | ||
| 58 | - ), | ||
| 59 | - GestureDetector( | ||
| 60 | onTap: () { | 46 | onTap: () { |
| 61 | if (actionTap != null) { | 47 | if (actionTap != null) { |
| 62 | - actionTap!(HeaderActionType.user); | 48 | + actionTap!(HeaderActionType.home); |
| 63 | } | 49 | } |
| 64 | }, | 50 | }, |
| 65 | child: Container( | 51 | child: Container( |
| 66 | - margin: const EdgeInsets.only(left: 7), | ||
| 67 | - padding: const EdgeInsets.all(4.0), | ||
| 68 | - decoration: BoxDecoration( | ||
| 69 | - color: Colors.white, | ||
| 70 | - borderRadius: BorderRadius.circular(2), | ||
| 71 | - border: Border.all(width: 1.0, color: const Color(0xFF140C10), style: BorderStyle.solid), | ||
| 72 | - ), | ||
| 73 | - child: Text( | ||
| 74 | - UserUtil.getUser()?.name ?? '未登录', | ||
| 75 | - style: TextStyle(color: const Color(0xFF333333), fontSize: 16.sp), | 52 | + alignment: Alignment.center, |
| 53 | + child: Image.asset( | ||
| 54 | + 'back_around'.assetPng, | ||
| 55 | + height: 40.h, | ||
| 56 | + width: 40.w, | ||
| 76 | ), | 57 | ), |
| 77 | ), | 58 | ), |
| 78 | ), | 59 | ), |
| 60 | + // GestureDetector( | ||
| 61 | + // onTap: () => actionTap?.call(HeaderActionType.user), | ||
| 62 | + // child: Container( | ||
| 63 | + // decoration: BoxDecoration( | ||
| 64 | + // border: Border.all( | ||
| 65 | + // width: 1.0, | ||
| 66 | + // color: const Color(0xFF140C10), | ||
| 67 | + // ), | ||
| 68 | + // borderRadius: BorderRadius.circular(21), | ||
| 69 | + // ), | ||
| 70 | + // child: CircleAvatar( | ||
| 71 | + // radius: 21, | ||
| 72 | + // backgroundImage: ImageUtil.getImageProviderOnDefault(UserUtil.getUser()?.avatarUrl), | ||
| 73 | + // ), | ||
| 74 | + // ), | ||
| 75 | + // ), | ||
| 76 | + // GestureDetector( | ||
| 77 | + // onTap: () { | ||
| 78 | + // if (actionTap != null) { | ||
| 79 | + // actionTap!(HeaderActionType.user); | ||
| 80 | + // } | ||
| 81 | + // }, | ||
| 82 | + // child: Container( | ||
| 83 | + // margin: const EdgeInsets.only(left: 7), | ||
| 84 | + // padding: const EdgeInsets.all(4.0), | ||
| 85 | + // decoration: BoxDecoration( | ||
| 86 | + // color: Colors.white, | ||
| 87 | + // borderRadius: BorderRadius.circular(2), | ||
| 88 | + // border: Border.all(width: 1.0, color: const Color(0xFF140C10), style: BorderStyle.solid), | ||
| 89 | + // ), | ||
| 90 | + // child: Text( | ||
| 91 | + // UserUtil.getUser()?.name ?? '未登录', | ||
| 92 | + // style: TextStyle(color: const Color(0xFF333333), fontSize: 16.sp), | ||
| 93 | + // ), | ||
| 94 | + // ), | ||
| 95 | + // ), | ||
| 79 | 20.horizontalSpace, | 96 | 20.horizontalSpace, |
| 80 | Expanded( | 97 | Expanded( |
| 81 | child: Text( | 98 | child: Text( |
| 82 | - CourseModuleModel(entity?.courseModuleCode??'Phase-1').courseModuleTitle, | ||
| 83 | - textAlign: TextAlign.left, | ||
| 84 | - style: const TextStyle(color: Colors.white, fontSize: 30.0), | ||
| 85 | - )), | 99 | + CourseModuleModel(entity?.courseModuleCode ?? 'Phase-1') |
| 100 | + .courseModuleTitle, | ||
| 101 | + textAlign: TextAlign.left, | ||
| 102 | + style: const TextStyle(color: Colors.white, fontSize: 30.0), | ||
| 103 | + )), | ||
| 86 | // IconButton( | 104 | // IconButton( |
| 87 | // onPressed: () { | 105 | // onPressed: () { |
| 88 | // if (actionTap != null) { | 106 | // if (actionTap != null) { |
| @@ -104,18 +122,19 @@ class HomeTabHeaderWidget extends StatelessWidget { | @@ -104,18 +122,19 @@ class HomeTabHeaderWidget extends StatelessWidget { | ||
| 104 | } | 122 | } |
| 105 | }, | 123 | }, |
| 106 | icon: Image.asset('listen'.assetPng)), | 124 | icon: Image.asset('listen'.assetPng)), |
| 107 | - IconButton( | ||
| 108 | - onPressed: (){ | ||
| 109 | - if(actionTap != null) { | ||
| 110 | - actionTap!(HeaderActionType.shop); | ||
| 111 | - } | ||
| 112 | - }, | ||
| 113 | - icon: Image.asset('shop'.assetPng) | 125 | + Visibility( |
| 126 | + visible: !AppConfigHelper.shouldHidePay(), | ||
| 127 | + child: IconButton( | ||
| 128 | + onPressed: () { | ||
| 129 | + if (actionTap != null) { | ||
| 130 | + actionTap!(HeaderActionType.shop); | ||
| 131 | + } | ||
| 132 | + }, | ||
| 133 | + icon: Image.asset('shop'.assetPng)), | ||
| 114 | ), | 134 | ), |
| 115 | ScreenUtil().bottomBarHeight.horizontalSpace, | 135 | ScreenUtil().bottomBarHeight.horizontalSpace, |
| 116 | ], | 136 | ], |
| 117 | - ) | ||
| 118 | - ); | 137 | + )); |
| 119 | }, | 138 | }, |
| 120 | ); | 139 | ); |
| 121 | } | 140 | } |
lib/pages/login/loginpage/bloc/login_bloc.dart
| @@ -45,7 +45,8 @@ class LoginBloc extends Bloc<LoginEvent, LoginState> { | @@ -45,7 +45,8 @@ class LoginBloc extends Bloc<LoginEvent, LoginState> { | ||
| 45 | 45 | ||
| 46 | bool get canSendSms => _canSendSms; | 46 | bool get canSendSms => _canSendSms; |
| 47 | 47 | ||
| 48 | - LoginBloc() : super(LoginInitial()) { | 48 | + LoginBloc(bool preferencesPasswordLogin) : super(LoginInitial()) { |
| 49 | + _isSmsLoginType = !preferencesPasswordLogin; | ||
| 49 | on<RequestLoginEvent>(_requestLoginApi); | 50 | on<RequestLoginEvent>(_requestLoginApi); |
| 50 | on<ChangeLoginTypeEvent>(_changeLoginType); | 51 | on<ChangeLoginTypeEvent>(_changeLoginType); |
| 51 | on<PhoneNumChangeEvent>(_changePhoneNumber); | 52 | on<PhoneNumChangeEvent>(_changePhoneNumber); |
lib/pages/login/loginpage/login_page.dart
| @@ -11,12 +11,16 @@ import 'package:wow_english/route/route.dart'; | @@ -11,12 +11,16 @@ import 'package:wow_english/route/route.dart'; | ||
| 11 | import 'bloc/login_bloc.dart'; | 11 | import 'bloc/login_bloc.dart'; |
| 12 | 12 | ||
| 13 | class LoginPage extends StatelessWidget { | 13 | class LoginPage extends StatelessWidget { |
| 14 | - const LoginPage({super.key}); | 14 | + |
| 15 | + // 优先展示密码登录 | ||
| 16 | + final bool preferencesPasswordLogin; | ||
| 17 | + | ||
| 18 | + const LoginPage({super.key, this.preferencesPasswordLogin = false}); | ||
| 15 | 19 | ||
| 16 | @override | 20 | @override |
| 17 | Widget build(BuildContext context) { | 21 | Widget build(BuildContext context) { |
| 18 | return BlocProvider( | 22 | return BlocProvider( |
| 19 | - create: (context) => LoginBloc(), | 23 | + create: (context) => LoginBloc(preferencesPasswordLogin), |
| 20 | child: _LoginPageView(), | 24 | child: _LoginPageView(), |
| 21 | ); | 25 | ); |
| 22 | } | 26 | } |
| @@ -30,7 +34,7 @@ class _LoginPageView extends StatelessWidget { | @@ -30,7 +34,7 @@ class _LoginPageView extends StatelessWidget { | ||
| 30 | if (state is LoginResultChangeState) { | 34 | if (state is LoginResultChangeState) { |
| 31 | // 调试用 | 35 | // 调试用 |
| 32 | // Navigator.of(context).pushNamed(AppRouteName.home); | 36 | // Navigator.of(context).pushNamed(AppRouteName.home); |
| 33 | - pushNamedAndRemoveUntil(AppRouteName.home, (route) => false); | 37 | + pushNamedAndRemoveUntil(AppRouteName.moduleSelect, (route) => false); |
| 34 | } | 38 | } |
| 35 | }, | 39 | }, |
| 36 | child: _buildLoginViewWidget(), | 40 | child: _buildLoginViewWidget(), |
lib/pages/login/setpwd/set_pwd_page.dart
| @@ -7,6 +7,7 @@ import 'package:wow_english/common/widgets/textfield_customer_widget.dart'; | @@ -7,6 +7,7 @@ import 'package:wow_english/common/widgets/textfield_customer_widget.dart'; | ||
| 7 | import 'package:wow_english/route/route.dart'; | 7 | import 'package:wow_english/route/route.dart'; |
| 8 | import 'package:wow_english/utils/toast_util.dart'; | 8 | import 'package:wow_english/utils/toast_util.dart'; |
| 9 | 9 | ||
| 10 | +import '../../../common/core/user_util.dart'; | ||
| 10 | import 'bloc/set_pwd_bloc.dart'; | 11 | import 'bloc/set_pwd_bloc.dart'; |
| 11 | 12 | ||
| 12 | enum SetPwdPageType { | 13 | enum SetPwdPageType { |
| @@ -59,9 +60,9 @@ class _SetPassWordPageView extends StatelessWidget { | @@ -59,9 +60,9 @@ class _SetPassWordPageView extends StatelessWidget { | ||
| 59 | if (bloc.pageType == SetPwdPageType.initPwd) { | 60 | if (bloc.pageType == SetPwdPageType.initPwd) { |
| 60 | showToast('密码设置成功'); | 61 | showToast('密码设置成功'); |
| 61 | } else { | 62 | } else { |
| 62 | - showToast('密码修改成功'); | 63 | + showToast('密码修改成功,请重新登录'); |
| 63 | } | 64 | } |
| 64 | - pushNamedAndRemoveUntil(AppRouteName.home, (route) => false); | 65 | + UserUtil.logout(true); |
| 65 | } else if (state is PasswordSetFailedState) { | 66 | } else if (state is PasswordSetFailedState) { |
| 66 | state.message.toast(); | 67 | state.message.toast(); |
| 67 | } | 68 | } |
lib/pages/moduleSelect/view.dart
| 1 | import 'package:flutter/material.dart'; | 1 | import 'package:flutter/material.dart'; |
| 2 | import 'package:flutter_bloc/flutter_bloc.dart'; | 2 | import 'package:flutter_bloc/flutter_bloc.dart'; |
| 3 | +import 'package:wow_english/common/core/app_config_helper.dart'; | ||
| 3 | import 'package:wow_english/common/extension/string_extension.dart'; | 4 | import 'package:wow_english/common/extension/string_extension.dart'; |
| 4 | import 'package:wow_english/pages/moduleSelect/state.dart'; | 5 | import 'package:wow_english/pages/moduleSelect/state.dart'; |
| 5 | import 'package:wow_english/pages/moduleSelect/widgets/BaseHomeHeaderWidget.dart'; | 6 | import 'package:wow_english/pages/moduleSelect/widgets/BaseHomeHeaderWidget.dart'; |
| 6 | 7 | ||
| 8 | +import '../../common/core/user_util.dart'; | ||
| 9 | +import '../../common/dialogs/show_dialog.dart'; | ||
| 7 | import 'bloc.dart'; | 10 | import 'bloc.dart'; |
| 8 | import 'event.dart'; | 11 | import 'event.dart'; |
| 9 | import 'package:flutter_screenutil/flutter_screenutil.dart'; | 12 | import 'package:flutter_screenutil/flutter_screenutil.dart'; |
| @@ -47,7 +50,11 @@ class _HomePageView extends StatelessWidget { | @@ -47,7 +50,11 @@ class _HomePageView extends StatelessWidget { | ||
| 47 | Expanded( | 50 | Expanded( |
| 48 | child: GestureDetector( | 51 | child: GestureDetector( |
| 49 | onTap: () { | 52 | onTap: () { |
| 50 | - pushNamed(AppRouteName.home); | 53 | + if (UserUtil.isLogined()) { |
| 54 | + pushNamed(AppRouteName.home); | ||
| 55 | + } else { | ||
| 56 | + pushNamed(AppRouteName.login); | ||
| 57 | + } | ||
| 51 | }, | 58 | }, |
| 52 | child: Column( | 59 | child: Column( |
| 53 | mainAxisAlignment: MainAxisAlignment.center, | 60 | mainAxisAlignment: MainAxisAlignment.center, |
| @@ -74,7 +81,27 @@ class _HomePageView extends StatelessWidget { | @@ -74,7 +81,27 @@ class _HomePageView extends StatelessWidget { | ||
| 74 | Expanded( | 81 | Expanded( |
| 75 | child: GestureDetector( | 82 | child: GestureDetector( |
| 76 | onTap: () { | 83 | onTap: () { |
| 77 | - pushNamed(AppRouteName.games); | 84 | + //如果没登录先登录 |
| 85 | + if (UserUtil.isLogined()) { | ||
| 86 | + if (AppConfigHelper.shouldHidePay()) { | ||
| 87 | + pushNamed(AppRouteName.games); | ||
| 88 | + } else { | ||
| 89 | + if (UserUtil.hasGamePermission()) { | ||
| 90 | + pushNamed(AppRouteName.games); | ||
| 91 | + } else { | ||
| 92 | + showTwoActionDialog( | ||
| 93 | + '提示', '忽略', '去续费', | ||
| 94 | + '您的课程已到期,请快快续费继续学习吧!', leftTap: () { | ||
| 95 | + popPage(); | ||
| 96 | + }, rightTap: () { | ||
| 97 | + popPage(); | ||
| 98 | + pushNamed(AppRouteName.shop); | ||
| 99 | + }); | ||
| 100 | + } | ||
| 101 | + } | ||
| 102 | + } else { | ||
| 103 | + pushNamed(AppRouteName.login); | ||
| 104 | + } | ||
| 78 | }, | 105 | }, |
| 79 | child: Column( | 106 | child: Column( |
| 80 | mainAxisAlignment: MainAxisAlignment.center, | 107 | mainAxisAlignment: MainAxisAlignment.center, |
lib/pages/moduleSelect/widgets/BaseHomeHeaderWidget.dart
| 1 | import 'package:flutter/material.dart'; | 1 | import 'package:flutter/material.dart'; |
| 2 | import 'package:flutter_bloc/flutter_bloc.dart'; | 2 | import 'package:flutter_bloc/flutter_bloc.dart'; |
| 3 | import 'package:flutter_screenutil/flutter_screenutil.dart'; | 3 | import 'package:flutter_screenutil/flutter_screenutil.dart'; |
| 4 | +import 'package:wow_english/common/core/app_config_helper.dart'; | ||
| 4 | import 'package:wow_english/common/extension/string_extension.dart'; | 5 | import 'package:wow_english/common/extension/string_extension.dart'; |
| 5 | 6 | ||
| 6 | import '../../../common/core/user_util.dart'; | 7 | import '../../../common/core/user_util.dart'; |
| @@ -77,16 +78,19 @@ class BaseHomeHeaderWidget extends StatelessWidget { | @@ -77,16 +78,19 @@ class BaseHomeHeaderWidget extends StatelessWidget { | ||
| 77 | textAlign: TextAlign.left, | 78 | textAlign: TextAlign.left, |
| 78 | style: TextStyle(color: Colors.white, fontSize: 30.0), | 79 | style: TextStyle(color: Colors.white, fontSize: 30.0), |
| 79 | )), | 80 | )), |
| 80 | - Row(children: <Widget>[ | ||
| 81 | - Image( | ||
| 82 | - width: 20.0.w, | ||
| 83 | - height: 20.0.h, | ||
| 84 | - image: AssetImage('ic_countdown'.assetPng)), | ||
| 85 | - // 替换为你的图片资源路径 | ||
| 86 | - const SizedBox(width: 10.0), | ||
| 87 | - // 图片和文本之间的间隔 | ||
| 88 | - const Text('还剩29天'), | ||
| 89 | - ]), | 81 | + Visibility( |
| 82 | + visible: !AppConfigHelper.shouldHidePay(), | ||
| 83 | + child: Row(children: <Widget>[ | ||
| 84 | + Image( | ||
| 85 | + width: 20.0.w, | ||
| 86 | + height: 20.0.h, | ||
| 87 | + image: AssetImage('ic_countdown'.assetPng)), | ||
| 88 | + // 替换为你的图片资源路径 | ||
| 89 | + const SizedBox(width: 10.0), | ||
| 90 | + // 图片和文本之间的间隔 | ||
| 91 | + Text('还剩${UserUtil.getRemainingValidity()}天'), | ||
| 92 | + ]), | ||
| 93 | + ), | ||
| 90 | ScreenUtil().bottomBarHeight.horizontalSpace, | 94 | ScreenUtil().bottomBarHeight.horizontalSpace, |
| 91 | ], | 95 | ], |
| 92 | )); | 96 | )); |
| @@ -96,9 +100,9 @@ class BaseHomeHeaderWidget extends StatelessWidget { | @@ -96,9 +100,9 @@ class BaseHomeHeaderWidget extends StatelessWidget { | ||
| 96 | } | 100 | } |
| 97 | 101 | ||
| 98 | void onUserClick() { | 102 | void onUserClick() { |
| 99 | - if (UserUtil.token.isEmpty) { | ||
| 100 | - pushNamed(AppRouteName.login); | ||
| 101 | - } else { | 103 | + if (UserUtil.isLogined()) { |
| 102 | pushNamed(AppRouteName.user); | 104 | pushNamed(AppRouteName.user); |
| 105 | + } else { | ||
| 106 | + pushNamed(AppRouteName.login); | ||
| 103 | } | 107 | } |
| 104 | } | 108 | } |
lib/pages/shop/home/widgets/product_item.dart
| @@ -4,8 +4,7 @@ import 'package:flutter_screenutil/flutter_screenutil.dart'; | @@ -4,8 +4,7 @@ import 'package:flutter_screenutil/flutter_screenutil.dart'; | ||
| 4 | import 'package:wow_english/models/product_entity.dart'; | 4 | import 'package:wow_english/models/product_entity.dart'; |
| 5 | 5 | ||
| 6 | class ProductItem extends StatelessWidget { | 6 | class ProductItem extends StatelessWidget { |
| 7 | - const ProductItem({super.key, | ||
| 8 | - required this.onTap, this.entity}); | 7 | + const ProductItem({super.key, required this.onTap, this.entity}); |
| 9 | 8 | ||
| 10 | final ProductEntity? entity; | 9 | final ProductEntity? entity; |
| 11 | 10 | ||
| @@ -15,52 +14,27 @@ class ProductItem extends StatelessWidget { | @@ -15,52 +14,27 @@ class ProductItem extends StatelessWidget { | ||
| 15 | Widget build(BuildContext context) { | 14 | Widget build(BuildContext context) { |
| 16 | return Container( | 15 | return Container( |
| 17 | decoration: BoxDecoration( | 16 | decoration: BoxDecoration( |
| 18 | - borderRadius: BorderRadius.circular(10.r), | ||
| 19 | - border: Border.all( | ||
| 20 | - width: 1.0, | ||
| 21 | - color: Colors.black | ||
| 22 | - ) | ||
| 23 | - // image: DecorationImage( | ||
| 24 | - // image: AssetImage( | ||
| 25 | - // ''.assetPng, | ||
| 26 | - // ), | ||
| 27 | - // fit: BoxFit.fill | ||
| 28 | - // ) | ||
| 29 | - ), | ||
| 30 | - padding: EdgeInsets.symmetric(horizontal: 16.w,vertical: 16.h), | 17 | + borderRadius: BorderRadius.circular(10.r), |
| 18 | + border: Border.all(width: 1.0, color: Colors.black)), | ||
| 19 | + padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 16.h), | ||
| 31 | child: Row( | 20 | child: Row( |
| 32 | mainAxisAlignment: MainAxisAlignment.spaceBetween, | 21 | mainAxisAlignment: MainAxisAlignment.spaceBetween, |
| 33 | children: [ | 22 | children: [ |
| 34 | Container( | 23 | Container( |
| 35 | - width: 124.w, | 24 | + width: 124.w, // 图片宽度 |
| 25 | + height: 124.h, // 图片高度 | ||
| 36 | decoration: BoxDecoration( | 26 | decoration: BoxDecoration( |
| 37 | - border: Border.all( | ||
| 38 | - width: 1.0, | ||
| 39 | - color: const Color(0xFF333333), | ||
| 40 | - ), | ||
| 41 | - image: DecorationImage( | ||
| 42 | - image: NetworkImage(entity?.picUrl ?? ''), | ||
| 43 | - ) | 27 | + borderRadius: BorderRadius.circular(5), |
| 28 | + // 圆角为5 | ||
| 29 | + border: Border.all(width: 1.w, color: const Color(0xFF333333)), | ||
| 30 | + // 边框宽度为1 | ||
| 31 | + // 使用ClipRRect圆角会有间隙,ClipRRect在裁剪时可能会导致圆角部分的边框显示不完整。 | ||
| 32 | + image: DecorationImage( | ||
| 33 | + image: NetworkImage(entity?.picUrl ?? ''), // 图片地址 | ||
| 34 | + fit: BoxFit.cover, // 图片填充方式 | ||
| 35 | + ), | ||
| 44 | ), | 36 | ), |
| 45 | ), | 37 | ), |
| 46 | - // CachedNetworkImage( | ||
| 47 | - // imageUrl: entity?.picUrl ?? '', | ||
| 48 | - // fit: BoxFit.fill, | ||
| 49 | - // imageBuilder: (context, imageProvider) => | ||
| 50 | - // Container( | ||
| 51 | - // decoration: BoxDecoration( | ||
| 52 | - // border: Border.all( | ||
| 53 | - // width: 1.0, | ||
| 54 | - // color: const Color(0xFF333333), | ||
| 55 | - // ), | ||
| 56 | - // borderRadius: BorderRadius.circular(5.0), | ||
| 57 | - // ), | ||
| 58 | - // ), | ||
| 59 | - // placeholder: (context, url) => const CircularProgressIndicator(), | ||
| 60 | - // // errorWidget: (context, url, error) => const Icon(Icons.error), | ||
| 61 | - // height: 124.h, | ||
| 62 | - // width: 124.w, | ||
| 63 | - // ), | ||
| 64 | 21.5.horizontalSpace, | 38 | 21.5.horizontalSpace, |
| 65 | Expanded( | 39 | Expanded( |
| 66 | child: Column( | 40 | child: Column( |
| @@ -72,29 +46,24 @@ class ProductItem extends StatelessWidget { | @@ -72,29 +46,24 @@ class ProductItem extends StatelessWidget { | ||
| 72 | softWrap: true, | 46 | softWrap: true, |
| 73 | textAlign: TextAlign.left, | 47 | textAlign: TextAlign.left, |
| 74 | style: TextStyle( | 48 | style: TextStyle( |
| 75 | - fontSize: 12.sp, | ||
| 76 | - color: const Color(0xFF333333) | ||
| 77 | - ), | 49 | + fontSize: 16.sp, color: const Color(0xFF333333)), |
| 78 | ), | 50 | ), |
| 79 | RichText( | 51 | RichText( |
| 80 | - text: TextSpan( | ||
| 81 | - children:[ | ||
| 82 | - TextSpan( | ||
| 83 | - text: '¥', | ||
| 84 | - style: TextStyle( | ||
| 85 | - fontSize: 21.sp, | ||
| 86 | - color: const Color(0xFFF51A1A), | ||
| 87 | - ) | ||
| 88 | - ), | ||
| 89 | - TextSpan( | ||
| 90 | - text: entity?.price?.toString() ?? '', | ||
| 91 | - style: TextStyle( | ||
| 92 | - fontSize: 40.sp, | ||
| 93 | - color: const Color(0xFFF51A1A), | ||
| 94 | - ), | ||
| 95 | - ) | ||
| 96 | - ] | ||
| 97 | - ), | 52 | + text: TextSpan(children: [ |
| 53 | + TextSpan( | ||
| 54 | + text: '¥', | ||
| 55 | + style: TextStyle( | ||
| 56 | + fontSize: 21.sp, | ||
| 57 | + color: const Color(0xFFF51A1A), | ||
| 58 | + )), | ||
| 59 | + TextSpan( | ||
| 60 | + text: entity?.price?.toString() ?? '', | ||
| 61 | + style: TextStyle( | ||
| 62 | + fontSize: 40.sp, | ||
| 63 | + color: const Color(0xFFF51A1A), | ||
| 64 | + ), | ||
| 65 | + ) | ||
| 66 | + ]), | ||
| 98 | ), | 67 | ), |
| 99 | GestureDetector( | 68 | GestureDetector( |
| 100 | onTap: () { | 69 | onTap: () { |
| @@ -107,8 +76,7 @@ class ProductItem extends StatelessWidget { | @@ -107,8 +76,7 @@ class ProductItem extends StatelessWidget { | ||
| 107 | border: Border.all( | 76 | border: Border.all( |
| 108 | color: const Color(0xFF333333), | 77 | color: const Color(0xFF333333), |
| 109 | width: 1.0, | 78 | width: 1.0, |
| 110 | - ) | ||
| 111 | - ), | 79 | + )), |
| 112 | padding: EdgeInsets.symmetric( | 80 | padding: EdgeInsets.symmetric( |
| 113 | vertical: 1.h, | 81 | vertical: 1.h, |
| 114 | horizontal: 26.5.w, | 82 | horizontal: 26.5.w, |
| @@ -116,9 +84,7 @@ class ProductItem extends StatelessWidget { | @@ -116,9 +84,7 @@ class ProductItem extends StatelessWidget { | ||
| 116 | child: Text( | 84 | child: Text( |
| 117 | '立即购买', | 85 | '立即购买', |
| 118 | style: TextStyle( | 86 | style: TextStyle( |
| 119 | - fontSize: 10.sp, | ||
| 120 | - color: const Color(0xFF333333) | ||
| 121 | - ), | 87 | + fontSize: 10.sp, color: const Color(0xFF333333)), |
| 122 | ), | 88 | ), |
| 123 | ), | 89 | ), |
| 124 | ) | 90 | ) |
| @@ -129,4 +95,4 @@ class ProductItem extends StatelessWidget { | @@ -129,4 +95,4 @@ class ProductItem extends StatelessWidget { | ||
| 129 | ), | 95 | ), |
| 130 | ); | 96 | ); |
| 131 | } | 97 | } |
| 132 | -} | ||
| 133 | \ No newline at end of file | 98 | \ No newline at end of file |
| 99 | +} |
lib/pages/shopping/view.dart
| @@ -19,33 +19,31 @@ Widget buildRadioOption({ | @@ -19,33 +19,31 @@ Widget buildRadioOption({ | ||
| 19 | required bool isSelected, | 19 | required bool isSelected, |
| 20 | required ValueChanged onSelect, | 20 | required ValueChanged onSelect, |
| 21 | }) { | 21 | }) { |
| 22 | - return | ||
| 23 | - GestureDetector( | ||
| 24 | - onTap: () { | ||
| 25 | - onSelect(value); | ||
| 26 | - }, | ||
| 27 | - child: Row( | ||
| 28 | - crossAxisAlignment: CrossAxisAlignment.center, | ||
| 29 | - children: [ | ||
| 30 | - Image(image: icon, width: 25.0.w, height: 25.0.h, fit: BoxFit.contain), | ||
| 31 | - const SizedBox(width: 10.0), | ||
| 32 | - Expanded( | ||
| 33 | - child: Text( | ||
| 34 | - text, | ||
| 35 | - style: TextStyle(color: const Color(0xFF333333), fontSize: 12.5.sp), | ||
| 36 | - ), | 22 | + return GestureDetector( |
| 23 | + onTap: () { | ||
| 24 | + onSelect(value); | ||
| 25 | + }, | ||
| 26 | + child: Row( | ||
| 27 | + crossAxisAlignment: CrossAxisAlignment.center, | ||
| 28 | + children: [ | ||
| 29 | + Image(image: icon, width: 25.0.w, height: 25.0.h, fit: BoxFit.contain), | ||
| 30 | + const SizedBox(width: 10.0), | ||
| 31 | + Expanded( | ||
| 32 | + child: Text( | ||
| 33 | + text, | ||
| 34 | + style: TextStyle(color: const Color(0xFF333333), fontSize: 12.5.sp), | ||
| 37 | ), | 35 | ), |
| 38 | - Image( | ||
| 39 | - image: isSelected | ||
| 40 | - ? AssetImage('checked'.assetPng) | ||
| 41 | - : AssetImage('unchecked'.assetPng), | ||
| 42 | - width: 22.0.w, | ||
| 43 | - height: 22.0.h, | ||
| 44 | - ), | ||
| 45 | - ], | ||
| 46 | - ), | ||
| 47 | - ); | ||
| 48 | - | 36 | + ), |
| 37 | + Image( | ||
| 38 | + image: isSelected | ||
| 39 | + ? AssetImage('checked'.assetPng) | ||
| 40 | + : AssetImage('unchecked'.assetPng), | ||
| 41 | + width: 22.0.w, | ||
| 42 | + height: 22.0.h, | ||
| 43 | + ), | ||
| 44 | + ], | ||
| 45 | + ), | ||
| 46 | + ); | ||
| 49 | } | 47 | } |
| 50 | 48 | ||
| 51 | class ShoppingPage extends StatelessWidget { | 49 | class ShoppingPage extends StatelessWidget { |
| @@ -83,22 +81,22 @@ class _ShoppingView extends StatelessWidget { | @@ -83,22 +81,22 @@ class _ShoppingView extends StatelessWidget { | ||
| 83 | child: Row( | 81 | child: Row( |
| 84 | crossAxisAlignment: CrossAxisAlignment.start, | 82 | crossAxisAlignment: CrossAxisAlignment.start, |
| 85 | children: [ | 83 | children: [ |
| 86 | - CachedNetworkImage( | ||
| 87 | - imageUrl: bloc.productData?.detailPicUrl ?? '', | ||
| 88 | - imageBuilder: (context, imageProvider) => Container( | ||
| 89 | - decoration: BoxDecoration( | ||
| 90 | - image: DecorationImage( | ||
| 91 | - image: imageProvider, | ||
| 92 | - fit: BoxFit.cover, | ||
| 93 | - ), | ||
| 94 | - borderRadius: BorderRadius.circular(5.0), | 84 | + Container( |
| 85 | + width: 210.w, // 图片宽度 | ||
| 86 | + height: 210.h, // 图片高度 | ||
| 87 | + decoration: BoxDecoration( | ||
| 88 | + borderRadius: BorderRadius.circular(5.w), | ||
| 89 | + // 圆角为5 | ||
| 90 | + border: | ||
| 91 | + Border.all(width: 1.w, color: const Color(0xFF333333)), | ||
| 92 | + // 边框宽度为1 | ||
| 93 | + // 使用ClipRRect圆角会有间隙,ClipRRect在裁剪时可能会导致圆角部分的边框显示不完整。 | ||
| 94 | + image: DecorationImage( | ||
| 95 | + image: NetworkImage(bloc.productData?.detailPicUrl ?? ''), | ||
| 96 | + // 图片地址 | ||
| 97 | + fit: BoxFit.cover, // 图片填充方式 | ||
| 95 | ), | 98 | ), |
| 96 | ), | 99 | ), |
| 97 | - placeholder: (context, url) => | ||
| 98 | - const CircularProgressIndicator(), | ||
| 99 | - // errorWidget: (context, url, error) => const Icon(Icons.error), | ||
| 100 | - height: 210.0.h, | ||
| 101 | - width: 210.0.w, | ||
| 102 | ), | 100 | ), |
| 103 | const SizedBox(width: 35.5), | 101 | const SizedBox(width: 35.5), |
| 104 | Expanded(child: _paymentWidget()) | 102 | Expanded(child: _paymentWidget()) |
| @@ -117,26 +115,21 @@ Widget _paymentWidget() => BlocBuilder<ShoppingBloc, ShoppingState>( | @@ -117,26 +115,21 @@ Widget _paymentWidget() => BlocBuilder<ShoppingBloc, ShoppingState>( | ||
| 117 | crossAxisAlignment: CrossAxisAlignment.start, | 115 | crossAxisAlignment: CrossAxisAlignment.start, |
| 118 | children: [ | 116 | children: [ |
| 119 | RichText( | 117 | RichText( |
| 120 | - text: TextSpan( | ||
| 121 | - children: [ | ||
| 122 | - TextSpan( | ||
| 123 | - text: '套餐价格:', | ||
| 124 | - style: | ||
| 125 | - TextStyle(color: const Color(0xFF333333), fontSize: 16.5.sp) | ||
| 126 | - ), | ||
| 127 | - TextSpan( | ||
| 128 | - text: '¥${bloc.productData?.price ?? ''}', | ||
| 129 | - style: | ||
| 130 | - TextStyle(color: const Color(0xFFE5262A), fontSize: 16.5.sp) | ||
| 131 | - ), | ||
| 132 | - ] | ||
| 133 | - ), | 118 | + text: TextSpan(children: [ |
| 119 | + TextSpan( | ||
| 120 | + text: '套餐价格:', | ||
| 121 | + style: TextStyle( | ||
| 122 | + color: const Color(0xFF333333), fontSize: 16.5.sp)), | ||
| 123 | + TextSpan( | ||
| 124 | + text: '¥${bloc.productData?.price ?? ''}', | ||
| 125 | + style: TextStyle( | ||
| 126 | + color: const Color(0xFFE5262A), fontSize: 16.5.sp)), | ||
| 127 | + ]), | ||
| 134 | ), | 128 | ), |
| 135 | const SizedBox(height: 14.5), | 129 | const SizedBox(height: 14.5), |
| 136 | Text( | 130 | Text( |
| 137 | '套餐名称:${bloc.productData?.name}', | 131 | '套餐名称:${bloc.productData?.name}', |
| 138 | - style: | ||
| 139 | - TextStyle(color: const Color(0xFF333333), fontSize: 16.sp), | 132 | + style: TextStyle(color: const Color(0xFF333333), fontSize: 16.sp), |
| 140 | maxLines: 2, | 133 | maxLines: 2, |
| 141 | ), | 134 | ), |
| 142 | const SizedBox(height: 14.5), | 135 | const SizedBox(height: 14.5), |
| @@ -158,7 +151,8 @@ Widget _paymentWidget() => BlocBuilder<ShoppingBloc, ShoppingState>( | @@ -158,7 +151,8 @@ Widget _paymentWidget() => BlocBuilder<ShoppingBloc, ShoppingState>( | ||
| 158 | value: PaymentChannel.wechatPay.payChannelType, | 151 | value: PaymentChannel.wechatPay.payChannelType, |
| 159 | icon: AssetImage('weixin'.assetPng), | 152 | icon: AssetImage('weixin'.assetPng), |
| 160 | text: PaymentChannel.wechatPay.payChannelName, | 153 | text: PaymentChannel.wechatPay.payChannelName, |
| 161 | - isSelected: bloc.curPaymentChannel.payChannelType == PaymentChannel.wechatPay.payChannelType, | 154 | + isSelected: bloc.curPaymentChannel.payChannelType == |
| 155 | + PaymentChannel.wechatPay.payChannelType, | ||
| 162 | onSelect: (newValue) { | 156 | onSelect: (newValue) { |
| 163 | bloc.add(ChangePaymentChannelEvent(PaymentChannel.wechatPay)); | 157 | bloc.add(ChangePaymentChannelEvent(PaymentChannel.wechatPay)); |
| 164 | }, | 158 | }, |
| @@ -168,7 +162,8 @@ Widget _paymentWidget() => BlocBuilder<ShoppingBloc, ShoppingState>( | @@ -168,7 +162,8 @@ Widget _paymentWidget() => BlocBuilder<ShoppingBloc, ShoppingState>( | ||
| 168 | value: PaymentChannel.aliPay.payChannelType, | 162 | value: PaymentChannel.aliPay.payChannelType, |
| 169 | icon: AssetImage('zhifubao'.assetPng), | 163 | icon: AssetImage('zhifubao'.assetPng), |
| 170 | text: PaymentChannel.aliPay.payChannelName, | 164 | text: PaymentChannel.aliPay.payChannelName, |
| 171 | - isSelected: bloc.curPaymentChannel.payChannelType == PaymentChannel.aliPay.payChannelType, | 165 | + isSelected: bloc.curPaymentChannel.payChannelType == |
| 166 | + PaymentChannel.aliPay.payChannelType, | ||
| 172 | onSelect: (newValue) { | 167 | onSelect: (newValue) { |
| 173 | bloc.add(ChangePaymentChannelEvent(PaymentChannel.aliPay)); | 168 | bloc.add(ChangePaymentChannelEvent(PaymentChannel.aliPay)); |
| 174 | }, | 169 | }, |
| @@ -178,25 +173,26 @@ Widget _paymentWidget() => BlocBuilder<ShoppingBloc, ShoppingState>( | @@ -178,25 +173,26 @@ Widget _paymentWidget() => BlocBuilder<ShoppingBloc, ShoppingState>( | ||
| 178 | mainAxisAlignment: MainAxisAlignment.spaceBetween, | 173 | mainAxisAlignment: MainAxisAlignment.spaceBetween, |
| 179 | children: [ | 174 | children: [ |
| 180 | RichText( | 175 | RichText( |
| 181 | - text: TextSpan( | ||
| 182 | - children: [ | ||
| 183 | - const TextSpan( | ||
| 184 | - text: '需支付:', | ||
| 185 | - style: | ||
| 186 | - TextStyle(color: Color(0xFF333333), fontSize: 12.5, fontFamily: 'PingFangSC-Regular') | ||
| 187 | - ), | ||
| 188 | - TextSpan( | ||
| 189 | - text: '¥${bloc.productData?.price ?? ''}', | ||
| 190 | - style: | ||
| 191 | - TextStyle(color: const Color(0xFFE7383B), fontSize: 41.sp, fontFamily: 'PingFangSC-Regular') | ||
| 192 | - ), | ||
| 193 | - ] | ||
| 194 | - ), | 176 | + text: TextSpan(children: [ |
| 177 | + const TextSpan( | ||
| 178 | + text: '需支付:', | ||
| 179 | + style: TextStyle( | ||
| 180 | + color: Color(0xFF333333), | ||
| 181 | + fontSize: 12.5, | ||
| 182 | + fontFamily: 'PingFangSC-Regular')), | ||
| 183 | + TextSpan( | ||
| 184 | + text: '¥${bloc.productData?.price ?? ''}', | ||
| 185 | + style: TextStyle( | ||
| 186 | + color: const Color(0xFFE7383B), | ||
| 187 | + fontSize: 41.sp, | ||
| 188 | + fontFamily: 'PingFangSC-Regular')), | ||
| 189 | + ]), | ||
| 195 | ), | 190 | ), |
| 196 | // 确认支付按钮 | 191 | // 确认支付按钮 |
| 197 | GestureDetector( | 192 | GestureDetector( |
| 198 | onTap: () { | 193 | onTap: () { |
| 199 | - bloc.add(DoPayEvent(bloc.productData, bloc.curPaymentChannel)); | 194 | + bloc.add( |
| 195 | + DoPayEvent(bloc.productData, bloc.curPaymentChannel)); | ||
| 200 | }, | 196 | }, |
| 201 | child: Image( | 197 | child: Image( |
| 202 | width: 105.w, | 198 | width: 105.w, |
lib/pages/user/modify/modify_user_information_page.dart
| @@ -66,7 +66,6 @@ class ModifyUserInformationPage extends StatelessWidget { | @@ -66,7 +66,6 @@ class ModifyUserInformationPage extends StatelessWidget { | ||
| 66 | if (bloc.isChangeInfo) { | 66 | if (bloc.isChangeInfo) { |
| 67 | showTwoActionDialog('提示', '确定离开', '继续修改', '您的信息尚未保存',leftTap: (){ | 67 | showTwoActionDialog('提示', '确定离开', '继续修改', '您的信息尚未保存',leftTap: (){ |
| 68 | popPage(); | 68 | popPage(); |
| 69 | - popPage(); | ||
| 70 | },rightTap: (){ | 69 | },rightTap: (){ |
| 71 | popPage(); | 70 | popPage(); |
| 72 | }); | 71 | }); |
lib/route/route.dart
| @@ -2,6 +2,7 @@ import 'package:flutter/cupertino.dart'; | @@ -2,6 +2,7 @@ import 'package:flutter/cupertino.dart'; | ||
| 2 | import 'package:flutter/material.dart'; | 2 | import 'package:flutter/material.dart'; |
| 3 | import 'package:wow_english/app/splash_page.dart'; | 3 | import 'package:wow_english/app/splash_page.dart'; |
| 4 | import 'package:wow_english/common/pages/wow_web_page.dart'; | 4 | import 'package:wow_english/common/pages/wow_web_page.dart'; |
| 5 | +import 'package:wow_english/generated/json/base/json_convert_content.dart'; | ||
| 5 | import 'package:wow_english/models/product_entity.dart'; | 6 | import 'package:wow_english/models/product_entity.dart'; |
| 6 | import 'package:wow_english/pages/games/view.dart'; | 7 | import 'package:wow_english/pages/games/view.dart'; |
| 7 | import 'package:wow_english/pages/home/home_page.dart'; | 8 | import 'package:wow_english/pages/home/home_page.dart'; |
| @@ -91,7 +92,9 @@ class AppRouter { | @@ -91,7 +92,9 @@ class AppRouter { | ||
| 91 | transitionDuration: Duration.zero, | 92 | transitionDuration: Duration.zero, |
| 92 | transitionsBuilder: (_, __, ___, child) => child); | 93 | transitionsBuilder: (_, __, ___, child) => child); |
| 93 | case AppRouteName.login: | 94 | case AppRouteName.login: |
| 94 | - return CupertinoPageRoute(builder: (_) => const LoginPage()); | 95 | + // 是否默认密码登录,修改密码后跳登录页,优先密码登录体验好点 |
| 96 | + final bool showPasswordPage = (settings.arguments as Map?)?.getOrNull('showPasswordPage') as bool? ?? false; | ||
| 97 | + return CupertinoPageRoute(builder: (_) => LoginPage(preferencesPasswordLogin: showPasswordPage)); | ||
| 95 | case AppRouteName.moduleSelect: | 98 | case AppRouteName.moduleSelect: |
| 96 | return CupertinoPageRoute(builder: (_) => const ModuleSelectPage()); | 99 | return CupertinoPageRoute(builder: (_) => const ModuleSelectPage()); |
| 97 | case AppRouteName.games: | 100 | case AppRouteName.games: |
pubspec.yaml
| @@ -104,7 +104,7 @@ dependencies: | @@ -104,7 +104,7 @@ dependencies: | ||
| 104 | # 阿里云oss https://pub.dev/packages/flutter_oss_aliyun | 104 | # 阿里云oss https://pub.dev/packages/flutter_oss_aliyun |
| 105 | flutter_oss_aliyun: ^6.2.7 | 105 | flutter_oss_aliyun: ^6.2.7 |
| 106 | # App信息 https://pub.dev/packages/package_info_plus | 106 | # App信息 https://pub.dev/packages/package_info_plus |
| 107 | - package_info_plus: ^4.0.2 | 107 | + package_info_plus: ^4.2.0 |
| 108 | 108 | ||
| 109 | dev_dependencies: | 109 | dev_dependencies: |
| 110 | build_runner: ^2.4.4 | 110 | build_runner: ^2.4.4 |