Commit 9ebefc69b3f2cb7f85d42d6a85dd19fe2001d885

Authored by xiaoyu
2 parents 22495953 911794fd

Merge remote-tracking branch 'origin/feat-wqf-payment' into xiaoyu_cocossteve

# Conflicts:
#	pubspec.yaml
Showing 53 changed files with 1270 additions and 469 deletions
lib/app/splash_page.dart
@@ -77,7 +77,7 @@ class _TransitionViewState extends State<TransitionView> { @@ -77,7 +77,7 @@ class _TransitionViewState extends State<TransitionView> {
77 }*/ 77 }*/
78 bool isAggreementAccepted = AppConfigHelper.getAgreementAccepted(); 78 bool isAggreementAccepted = AppConfigHelper.getAgreementAccepted();
79 if (isAggreementAccepted) { 79 if (isAggreementAccepted) {
80 - pushNamedAndRemoveUntil(AppRouteName.moduleSelect, (route) => false); 80 + pushNamedAndRemoveUntil(AppRouteName.home, (route) => false);
81 } else { 81 } else {
82 showDialog( 82 showDialog(
83 context: context, 83 context: context,
@@ -91,11 +91,11 @@ class _TransitionViewState extends State<TransitionView> { @@ -91,11 +91,11 @@ class _TransitionViewState extends State<TransitionView> {
91 leftTap: () { 91 leftTap: () {
92 AppConfigHelper.saveAgreementAccepted(true); 92 AppConfigHelper.saveAgreementAccepted(true);
93 pushNamedAndRemoveUntil( 93 pushNamedAndRemoveUntil(
94 - AppRouteName.moduleSelect, (route) => false); 94 + AppRouteName.home, (route) => false);
95 }, 95 },
96 rightTap: () { 96 rightTap: () {
97 // 退出应用 97 // 退出应用
98 - SystemNavigator.pop(); 98 + AppConfigHelper.exitApp();
99 }, 99 },
100 ), 100 ),
101 ); 101 );
lib/common/core/app_config_helper.dart
@@ -2,6 +2,8 @@ import 'dart:ffi'; @@ -2,6 +2,8 @@ import 'dart:ffi';
2 import 'dart:io'; 2 import 'dart:io';
3 3
4 import 'package:flutter/cupertino.dart'; 4 import 'package:flutter/cupertino.dart';
  5 +import 'package:flutter/foundation.dart';
  6 +import 'package:flutter/services.dart';
5 import 'package:package_info_plus/package_info_plus.dart'; 7 import 'package:package_info_plus/package_info_plus.dart';
6 import 'package:wow_english/common/core/sp_const.dart'; 8 import 'package:wow_english/common/core/sp_const.dart';
7 import 'package:wow_english/common/core/user_util.dart'; 9 import 'package:wow_english/common/core/user_util.dart';
@@ -16,6 +18,9 @@ class AppConfigHelper { @@ -16,6 +18,9 @@ class AppConfigHelper {
16 18
17 static String _versionCode = ''; 19 static String _versionCode = '';
18 20
  21 + // 是否检测过更新,因为路由混乱导致首页会多次启动,避免重复检测更新,先临时处理
  22 + static bool checkedUpdate = false;
  23 +
19 // 获取用户信息 24 // 获取用户信息
20 static Future<AppConfigEntity?> getAppConfig() async { 25 static Future<AppConfigEntity?> getAppConfig() async {
21 if (configEntityEntity != null) { 26 if (configEntityEntity != null) {
@@ -25,9 +30,15 @@ class AppConfigHelper { @@ -25,9 +30,15 @@ class AppConfigHelper {
25 return configEntityEntity; 30 return configEntityEntity;
26 } 31 }
27 32
  33 + // 是否是iOS平台
  34 + static bool isIosPlatform() {
  35 + return defaultTargetPlatform == TargetPlatform.iOS;
  36 + }
  37 +
28 // 是否需要隐藏... 38 // 是否需要隐藏...
29 static bool shouldHidePay() { 39 static bool shouldHidePay() {
30 - return configEntityEntity?.isAppReviewing() == true || UserUtil.getUser()?.phoneNum == "17730280759"; 40 + return isIosPlatform() &&
  41 + (configEntityEntity?.isAppReviewing() == true || UserUtil.getUser()?.phoneNum == "17730280759");
31 } 42 }
32 43
33 // 获取app版本号 44 // 获取app版本号
@@ -55,4 +66,13 @@ class AppConfigHelper { @@ -55,4 +66,13 @@ class AppConfigHelper {
55 static void _clearUserData() { 66 static void _clearUserData() {
56 SpUtil.getInstance().remove(SpConst.prefsKeyAgreementAccepted); 67 SpUtil.getInstance().remove(SpConst.prefsKeyAgreementAccepted);
57 } 68 }
  69 +
  70 + static void exitApp() {
  71 + if (Platform.isIOS) {
  72 + exit(0);
  73 + } else {
  74 + //此种方式在IOS上不生效
  75 + SystemNavigator.pop();
  76 + }
  77 + }
58 } 78 }
lib/common/core/user_util.dart
@@ -60,12 +60,11 @@ class UserUtil { @@ -60,12 +60,11 @@ class UserUtil {
60 if (currentPageName != AppRouteName.splash) { 60 if (currentPageName != AppRouteName.splash) {
61 Navigator.of(AppRouter.context).pushNamedAndRemoveUntil(AppRouteName.login, (route) => false); 61 Navigator.of(AppRouter.context).pushNamedAndRemoveUntil(AppRouteName.login, (route) => false);
62 }*/ 62 }*/
63 - Navigator.of(AppRouter.context).pushNamedAndRemoveUntil(AppRouteName.login, (route) => false, arguments: {'showPasswordPage': showPasswordLoginPage}); 63 + pushNamedAndRemoveUntil(AppRouteName.login, (route) => false, arguments: {'showPasswordPage': showPasswordLoginPage});
64 } 64 }
65 65
66 // 是否有游戏权限 66 // 是否有游戏权限
67 static bool hasGamePermission() { 67 static bool hasGamePermission() {
68 - debugPrint('hasGamePermission: ${_userEntity}');  
69 return _userEntity?.valid ?? false; 68 return _userEntity?.valid ?? false;
70 } 69 }
71 70
lib/common/permission/permissionRequestPage.dart
1 import 'dart:io'; 1 import 'dart:io';
2 import 'package:flutter/material.dart'; 2 import 'package:flutter/material.dart';
3 -import 'package:flutter/services.dart';  
4 import 'package:permission_handler/permission_handler.dart'; 3 import 'package:permission_handler/permission_handler.dart';
  4 +import 'package:wow_english/common/core/app_config_helper.dart';
5 5
6 import '../../utils/log_util.dart'; 6 import '../../utils/log_util.dart';
7 7
@@ -167,7 +167,7 @@ class _PermissionRequestPageState extends State&lt;PermissionRequestPage&gt; @@ -167,7 +167,7 @@ class _PermissionRequestPageState extends State&lt;PermissionRequestPage&gt;
167 167
168 /// 退出应用程序 168 /// 退出应用程序
169 void _quitApp() { 169 void _quitApp() {
170 - SystemChannels.platform.invokeMethod("SystemNavigator.pop"); 170 + AppConfigHelper.exitApp();
171 } 171 }
172 172
173 /// 关闭整个权限申请页面 173 /// 关闭整个权限申请页面
lib/common/request/apis.dart
@@ -6,6 +6,9 @@ class Apis { @@ -6,6 +6,9 @@ class Apis {
6 /// 接口地址:https://app.apifox.com/link/project/2684751/apis/api-89897678 6 /// 接口地址:https://app.apifox.com/link/project/2684751/apis/api-89897678
7 static const String appConfig = 'system/app/config'; 7 static const String appConfig = 'system/app/config';
8 8
  9 + /// app版本信息
  10 + static const String appVersion = 'system/app/version';
  11 +
9 /// 登录 12 /// 登录
10 static const String login = 'login'; 13 static const String login = 'login';
11 14
@@ -42,11 +45,17 @@ class Apis { @@ -42,11 +45,17 @@ class Apis {
42 // 接口地址:https://app.apifox.com/link/project/2684751/apis/api-89897663 45 // 接口地址:https://app.apifox.com/link/project/2684751/apis/api-89897663
43 static const String courseModule = 'home/courseModule'; 46 static const String courseModule = 'home/courseModule';
44 47
  48 + /// 课程单元列表
  49 + static const String courseUnit = 'home/courseUnit';
  50 +
45 /// 课程列表 51 /// 课程列表
46 // GET /home/courseLesson 52 // GET /home/courseLesson
47 // 接口地址:https://app.apifox.com/link/project/2684751/apis/api-89897662 53 // 接口地址:https://app.apifox.com/link/project/2684751/apis/api-89897662
48 static const String courseLesson = 'home/courseLesson'; 54 static const String courseLesson = 'home/courseLesson';
49 55
  56 + // 课程环节列表
  57 + static const String courseSection = 'course/courseLesson';
  58 +
50 /// 磨耳朵 59 /// 磨耳朵
51 /// GET 60 /// GET
52 static const String ears = 'course/grinding/ears'; 61 static const String ears = 'course/grinding/ears';
lib/common/request/dao/home_dao.dart renamed to lib/common/request/dao/lesson_dao.dart
1 import 'package:wow_english/common/request/request_client.dart'; 1 import 'package:wow_english/common/request/request_client.dart';
2 import 'package:wow_english/models/course_entity.dart'; 2 import 'package:wow_english/models/course_entity.dart';
  3 +import 'package:wow_english/models/course_section_entity.dart';
3 4
4 import '../../../models/course_module_entity.dart'; 5 import '../../../models/course_module_entity.dart';
  6 +import '../../../models/course_unit_entity.dart';
5 7
6 -class HomeDao {  
7 - ///获取课程模块信息 8 +class LessonDao {
  9 + ///获取课程模块(列表)信息
8 static Future<List<CourseModuleEntity?>?> courseModule() async { 10 static Future<List<CourseModuleEntity?>?> courseModule() async {
9 var data = await requestClient.get<List<CourseModuleEntity>>(Apis.courseModule); 11 var data = await requestClient.get<List<CourseModuleEntity>>(Apis.courseModule);
10 return data; 12 return data;
11 } 13 }
12 14
13 - ///课程列表  
14 - static Future<CourseEntity?> courseLesson({String moduleId = ''}) async { 15 + ///课程单元列表
  16 + static Future<CourseUnitEntity?> courseUnit(int? moduleId) async {
15 Map<String, dynamic> mapData = {}; 17 Map<String, dynamic> mapData = {};
16 - if (moduleId.isNotEmpty) { 18 + if (moduleId != null) {
17 mapData['moduleId'] = moduleId; 19 mapData['moduleId'] = moduleId;
18 } 20 }
  21 + var data = await requestClient.get<CourseUnitEntity>(Apis.courseUnit, queryParameters: mapData);
  22 + return data;
  23 + }
  24 +
  25 + ///课程列表
  26 + static Future<CourseEntity?> courseLesson({int? courseUnitId}) async {
  27 + Map<String, dynamic> mapData = {};
  28 + if (courseUnitId != null) {
  29 + mapData['courseUnitId'] = courseUnitId;
  30 + }
19 var data = await requestClient.get<CourseEntity>(Apis.courseLesson, queryParameters: mapData); 31 var data = await requestClient.get<CourseEntity>(Apis.courseLesson, queryParameters: mapData);
20 return data; 32 return data;
21 } 33 }
  34 +
  35 + ///课程(单元)列表
  36 + static Future<List<CourseSectionEntity>?> courseSection({required int courseUnitId}) async {
  37 + Map<String, dynamic> mapData = {};
  38 + mapData['courseUnitId'] = courseUnitId;
  39 + var data = await requestClient.get<List<CourseSectionEntity>?>(Apis.courseSection, queryParameters: mapData);
  40 + return data;
  41 + }
22 } 42 }
lib/common/request/dao/system_dao.dart
1 import '../../../models/app_config_entity.dart'; 1 import '../../../models/app_config_entity.dart';
  2 +import '../../../models/app_version_entity.dart';
2 import '../request_client.dart'; 3 import '../request_client.dart';
3 4
4 class SystemDao { 5 class SystemDao {
@@ -7,4 +8,9 @@ class SystemDao { @@ -7,4 +8,9 @@ class SystemDao {
7 static Future<AppConfigEntity?> getAppConfig() async { 8 static Future<AppConfigEntity?> getAppConfig() async {
8 return await requestClient.get(Apis.appConfig); 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 import 'package:dio/dio.dart'; 1 import 'package:dio/dio.dart';
  2 +import 'package:flutter/foundation.dart';
2 import 'package:wow_english/common/core/user_util.dart'; 3 import 'package:wow_english/common/core/user_util.dart';
3 4
4 import '../core/app_config_helper.dart'; 5 import '../core/app_config_helper.dart';
@@ -13,6 +14,7 @@ class TokenInterceptor extends Interceptor { @@ -13,6 +14,7 @@ class TokenInterceptor extends Interceptor {
13 // 在发送请求之前获取版本号 14 // 在发送请求之前获取版本号
14 String version = await AppConfigHelper.getAppVersion(); 15 String version = await AppConfigHelper.getAppVersion();
15 options.headers["version"] = version; 16 options.headers["version"] = version;
  17 + options.headers["User-Agent"] = AppConfigHelper.isIosPlatform() ? "ios" : "android";
16 super.onRequest(options, handler); 18 super.onRequest(options, handler);
17 } 19 }
18 } 20 }
lib/common/widgets/webview_dialog.dart
@@ -41,21 +41,26 @@ class WebviewDialog extends StatelessWidget { @@ -41,21 +41,26 @@ class WebviewDialog extends StatelessWidget {
41 } 41 }
42 })), 42 })),
43 actions: <Widget>[ 43 actions: <Widget>[
44 - TextButton(  
45 - child: 44 + Row(
  45 + mainAxisAlignment: MainAxisAlignment.spaceBetween,
  46 + children: [
  47 + TextButton(
  48 + child:
46 const Text('同意并继续', style: TextStyle(color: Color(0xFFFBB621))), 49 const Text('同意并继续', style: TextStyle(color: Color(0xFFFBB621))),
47 - onPressed: () {  
48 - // 处理接受按钮的点击事件  
49 - leftTap(); // 关闭对话框  
50 - },  
51 - ),  
52 - TextButton(  
53 - child: const Text('不同意,退出应用'),  
54 - onPressed: () {  
55 - // 处理拒绝按钮的点击事件  
56 - rightTap(); // 关闭对话框  
57 - },  
58 - ), 50 + onPressed: () {
  51 + // 处理接受按钮的点击事件
  52 + leftTap(); // 关闭对话框
  53 + },
  54 + ),
  55 + TextButton(
  56 + child: const Text('不同意,退出应用'),
  57 + onPressed: () {
  58 + // 处理拒绝按钮的点击事件
  59 + rightTap(); // 关闭对话框
  60 + },
  61 + ),
  62 + ],
  63 + )
59 ], 64 ],
60 ); 65 );
61 } 66 }
lib/generated/json/app_config_entity.g.dart
1 import 'package:wow_english/generated/json/base/json_convert_content.dart'; 1 import 'package:wow_english/generated/json/base/json_convert_content.dart';
2 import 'package:wow_english/models/app_config_entity.dart'; 2 import 'package:wow_english/models/app_config_entity.dart';
3 3
4 -AppConfigEntity $AppConfigEntityEntityFromJson(  
5 - Map<String, dynamic> json) {  
6 - final AppConfigEntity appConfigEntityEntity = AppConfigEntity();  
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 - } 4 +AppConfigEntity $AppConfigEntityFromJson(Map<String, dynamic> json) {
  5 + final AppConfigEntity appConfigEntity = AppConfigEntity();
45 final String? safe = jsonConvert.convert<String>(json['safe']); 6 final String? safe = jsonConvert.convert<String>(json['safe']);
46 if (safe != null) { 7 if (safe != null) {
47 - appConfigEntityEntity.safe = safe; 8 + appConfigEntity.safe = safe;
48 } 9 }
49 - return appConfigEntityEntity; 10 + return appConfigEntity;
50 } 11 }
51 12
52 -Map<String, dynamic> $AppConfigEntityEntityToJson(  
53 - AppConfigEntity entity) { 13 +Map<String, dynamic> $AppConfigEntityToJson(AppConfigEntity entity) {
54 final Map<String, dynamic> data = <String, dynamic>{}; 14 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; 15 data['safe'] = entity.safe;
64 return data; 16 return data;
65 } 17 }
66 18
67 -extension AppConfigEntityEntityExtension on AppConfigEntity { 19 +extension AppConfigEntityExtension on AppConfigEntity {
68 AppConfigEntity copyWith({ 20 AppConfigEntity 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, 21 String? safe,
78 }) { 22 }) {
79 return AppConfigEntity() 23 return AppConfigEntity()
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; 24 ..safe = safe ?? this.safe;
92 } 25 }
93 } 26 }
94 \ No newline at end of file 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 \ No newline at end of file 77 \ No newline at end of file
lib/generated/json/base/json_convert_content.dart
@@ -6,9 +6,12 @@ @@ -6,9 +6,12 @@
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/app_config_entity.dart';
  9 +import 'package:wow_english/models/app_version_entity.dart';
9 import 'package:wow_english/models/course_entity.dart'; 10 import 'package:wow_english/models/course_entity.dart';
10 import 'package:wow_english/models/course_module_entity.dart'; 11 import 'package:wow_english/models/course_module_entity.dart';
11 import 'package:wow_english/models/course_process_entity.dart'; 12 import 'package:wow_english/models/course_process_entity.dart';
  13 +import 'package:wow_english/models/course_section_entity.dart';
  14 +import 'package:wow_english/models/course_unit_entity.dart';
12 import 'package:wow_english/models/follow_read_entity.dart'; 15 import 'package:wow_english/models/follow_read_entity.dart';
13 import 'package:wow_english/models/listen_entity.dart'; 16 import 'package:wow_english/models/listen_entity.dart';
14 import 'package:wow_english/models/product_entity.dart'; 17 import 'package:wow_english/models/product_entity.dart';
@@ -159,6 +162,10 @@ class JsonConvert { @@ -159,6 +162,10 @@ class JsonConvert {
159 return data.map<AppConfigEntity>((Map<String, dynamic> e) => 162 return data.map<AppConfigEntity>((Map<String, dynamic> e) =>
160 AppConfigEntity.fromJson(e)).toList() as M; 163 AppConfigEntity.fromJson(e)).toList() as M;
161 } 164 }
  165 + if (<AppVersionEntity>[] is M) {
  166 + return data.map<AppVersionEntity>((Map<String, dynamic> e) =>
  167 + AppVersionEntity.fromJson(e)).toList() as M;
  168 + }
162 if (<CourseEntity>[] is M) { 169 if (<CourseEntity>[] is M) {
163 return data.map<CourseEntity>((Map<String, dynamic> e) => 170 return data.map<CourseEntity>((Map<String, dynamic> e) =>
164 CourseEntity.fromJson(e)).toList() as M; 171 CourseEntity.fromJson(e)).toList() as M;
@@ -192,6 +199,18 @@ class JsonConvert { @@ -192,6 +199,18 @@ class JsonConvert {
192 return data.map<CourseProcessVideos>((Map<String, dynamic> e) => 199 return data.map<CourseProcessVideos>((Map<String, dynamic> e) =>
193 CourseProcessVideos.fromJson(e)).toList() as M; 200 CourseProcessVideos.fromJson(e)).toList() as M;
194 } 201 }
  202 + if (<CourseSectionEntity>[] is M) {
  203 + return data.map<CourseSectionEntity>((Map<String, dynamic> e) =>
  204 + CourseSectionEntity.fromJson(e)).toList() as M;
  205 + }
  206 + if (<CourseUnitEntity>[] is M) {
  207 + return data.map<CourseUnitEntity>((Map<String, dynamic> e) =>
  208 + CourseUnitEntity.fromJson(e)).toList() as M;
  209 + }
  210 + if (<CourseUnitDetail>[] is M) {
  211 + return data.map<CourseUnitDetail>((Map<String, dynamic> e) =>
  212 + CourseUnitDetail.fromJson(e)).toList() as M;
  213 + }
195 if (<FollowReadEntity>[] is M) { 214 if (<FollowReadEntity>[] is M) {
196 return data.map<FollowReadEntity>((Map<String, dynamic> e) => 215 return data.map<FollowReadEntity>((Map<String, dynamic> e) =>
197 FollowReadEntity.fromJson(e)).toList() as M; 216 FollowReadEntity.fromJson(e)).toList() as M;
@@ -237,6 +256,7 @@ class JsonConvertClassCollection { @@ -237,6 +256,7 @@ class JsonConvertClassCollection {
237 (AliyunOssUploadStsCallbackParam) 256 (AliyunOssUploadStsCallbackParam)
238 .toString(): AliyunOssUploadStsCallbackParam.fromJson, 257 .toString(): AliyunOssUploadStsCallbackParam.fromJson,
239 (AppConfigEntity).toString(): AppConfigEntity.fromJson, 258 (AppConfigEntity).toString(): AppConfigEntity.fromJson,
  259 + (AppVersionEntity).toString(): AppVersionEntity.fromJson,
240 (CourseEntity).toString(): CourseEntity.fromJson, 260 (CourseEntity).toString(): CourseEntity.fromJson,
241 (CourseCourseLessons).toString(): CourseCourseLessons.fromJson, 261 (CourseCourseLessons).toString(): CourseCourseLessons.fromJson,
242 (CourseModuleEntity).toString(): CourseModuleEntity.fromJson, 262 (CourseModuleEntity).toString(): CourseModuleEntity.fromJson,
@@ -246,6 +266,9 @@ class JsonConvertClassCollection { @@ -246,6 +266,9 @@ class JsonConvertClassCollection {
246 (CourseProcessTopicsTopicAnswerList) 266 (CourseProcessTopicsTopicAnswerList)
247 .toString(): CourseProcessTopicsTopicAnswerList.fromJson, 267 .toString(): CourseProcessTopicsTopicAnswerList.fromJson,
248 (CourseProcessVideos).toString(): CourseProcessVideos.fromJson, 268 (CourseProcessVideos).toString(): CourseProcessVideos.fromJson,
  269 + (CourseSectionEntity).toString(): CourseSectionEntity.fromJson,
  270 + (CourseUnitEntity).toString(): CourseUnitEntity.fromJson,
  271 + (CourseUnitDetail).toString(): CourseUnitDetail.fromJson,
249 (FollowReadEntity).toString(): FollowReadEntity.fromJson, 272 (FollowReadEntity).toString(): FollowReadEntity.fromJson,
250 (ListenEntity).toString(): ListenEntity.fromJson, 273 (ListenEntity).toString(): ListenEntity.fromJson,
251 (ProductEntity).toString(): ProductEntity.fromJson, 274 (ProductEntity).toString(): ProductEntity.fromJson,
lib/generated/json/course_module_entity.g.dart
@@ -3,7 +3,7 @@ import &#39;package:wow_english/models/course_module_entity.dart&#39;; @@ -3,7 +3,7 @@ import &#39;package:wow_english/models/course_module_entity.dart&#39;;
3 3
4 CourseModuleEntity $CourseModuleEntityFromJson(Map<String, dynamic> json) { 4 CourseModuleEntity $CourseModuleEntityFromJson(Map<String, dynamic> json) {
5 final CourseModuleEntity courseModuleEntity = CourseModuleEntity(); 5 final CourseModuleEntity courseModuleEntity = CourseModuleEntity();
6 - final String? id = jsonConvert.convert<String>(json['id']); 6 + final int? id = jsonConvert.convert<int>(json['id']);
7 if (id != null) { 7 if (id != null) {
8 courseModuleEntity.id = id; 8 courseModuleEntity.id = id;
9 } 9 }
@@ -90,7 +90,7 @@ Map&lt;String, dynamic&gt; $CourseModuleEntityToJson(CourseModuleEntity entity) { @@ -90,7 +90,7 @@ Map&lt;String, dynamic&gt; $CourseModuleEntityToJson(CourseModuleEntity entity) {
90 90
91 extension CourseModuleEntityExtension on CourseModuleEntity { 91 extension CourseModuleEntityExtension on CourseModuleEntity {
92 CourseModuleEntity copyWith({ 92 CourseModuleEntity copyWith({
93 - String? id, 93 + int? id,
94 String? code, 94 String? code,
95 int? courseModuleThemeId, 95 int? courseModuleThemeId,
96 int? courseTotal, 96 int? courseTotal,
lib/generated/json/course_section_entity.g.dart 0 → 100644
  1 +import 'package:wow_english/generated/json/base/json_convert_content.dart';
  2 +import 'package:wow_english/models/course_section_entity.dart';
  3 +
  4 +CourseSectionEntity $CourseSectionEntityFromJson(Map<String, dynamic> json) {
  5 + final CourseSectionEntity courseSectionEntity = CourseSectionEntity();
  6 + final int? id = jsonConvert.convert<int>(json['id']);
  7 + if (id != null) {
  8 + courseSectionEntity.id = id;
  9 + }
  10 + final int? courseUnitId = jsonConvert.convert<int>(json['courseUnitId']);
  11 + if (courseUnitId != null) {
  12 + courseSectionEntity.courseUnitId = courseUnitId;
  13 + }
  14 + final int? courseModuleId = jsonConvert.convert<int>(json['courseModuleId']);
  15 + if (courseModuleId != null) {
  16 + courseSectionEntity.courseModuleId = courseModuleId;
  17 + }
  18 + final String? name = jsonConvert.convert<String>(json['name']);
  19 + if (name != null) {
  20 + courseSectionEntity.name = name;
  21 + }
  22 + final dynamic des = json['des'];
  23 + if (des != null) {
  24 + courseSectionEntity.des = des;
  25 + }
  26 + final int? courseType = jsonConvert.convert<int>(json['courseType']);
  27 + if (courseType != null) {
  28 + courseSectionEntity.courseType = courseType;
  29 + }
  30 + final dynamic coverUrl = json['coverUrl'];
  31 + if (coverUrl != null) {
  32 + courseSectionEntity.coverUrl = coverUrl;
  33 + }
  34 + final int? sortOrder = jsonConvert.convert<int>(json['sortOrder']);
  35 + if (sortOrder != null) {
  36 + courseSectionEntity.sortOrder = sortOrder;
  37 + }
  38 + final int? status = jsonConvert.convert<int>(json['status']);
  39 + if (status != null) {
  40 + courseSectionEntity.status = status;
  41 + }
  42 + final bool? lock = jsonConvert.convert<bool>(json['lock']);
  43 + if (lock != null) {
  44 + courseSectionEntity.lock = lock;
  45 + }
  46 + return courseSectionEntity;
  47 +}
  48 +
  49 +Map<String, dynamic> $CourseSectionEntityToJson(CourseSectionEntity entity) {
  50 + final Map<String, dynamic> data = <String, dynamic>{};
  51 + data['id'] = entity.id;
  52 + data['courseUnitId'] = entity.courseUnitId;
  53 + data['courseModuleId'] = entity.courseModuleId;
  54 + data['name'] = entity.name;
  55 + data['des'] = entity.des;
  56 + data['courseType'] = entity.courseType;
  57 + data['coverUrl'] = entity.coverUrl;
  58 + data['sortOrder'] = entity.sortOrder;
  59 + data['status'] = entity.status;
  60 + data['lock'] = entity.lock;
  61 + return data;
  62 +}
  63 +
  64 +extension CourseSectionEntityExtension on CourseSectionEntity {
  65 + CourseSectionEntity copyWith({
  66 + int? id,
  67 + int? courseUnitId,
  68 + int? courseModuleId,
  69 + String? name,
  70 + dynamic des,
  71 + int? courseType,
  72 + dynamic coverUrl,
  73 + int? sortOrder,
  74 + int? status,
  75 + bool? lock,
  76 + }) {
  77 + return CourseSectionEntity()
  78 + ..id = id ?? this.id
  79 + ..courseUnitId = courseUnitId ?? this.courseUnitId
  80 + ..courseModuleId = courseModuleId ?? this.courseModuleId
  81 + ..name = name ?? this.name
  82 + ..des = des ?? this.des
  83 + ..courseType = courseType ?? this.courseType
  84 + ..coverUrl = coverUrl ?? this.coverUrl
  85 + ..sortOrder = sortOrder ?? this.sortOrder
  86 + ..status = status ?? this.status
  87 + ..lock = lock ?? this.lock;
  88 + }
  89 +}
0 \ No newline at end of file 90 \ No newline at end of file
lib/generated/json/course_unit_entity.g.dart 0 → 100644
  1 +import 'package:wow_english/generated/json/base/json_convert_content.dart';
  2 +import 'package:wow_english/models/course_unit_entity.dart';
  3 +
  4 +CourseUnitEntity $CourseUnitEntityFromJson(Map<String, dynamic> json) {
  5 + final CourseUnitEntity courseUnitEntity = CourseUnitEntity();
  6 + final List<
  7 + CourseUnitDetail>? courseUnitVOList = (json['courseUnitVOList'] as List<
  8 + dynamic>?)
  9 + ?.map(
  10 + (e) => jsonConvert.convert<CourseUnitDetail>(e) as CourseUnitDetail)
  11 + .toList();
  12 + if (courseUnitVOList != null) {
  13 + courseUnitEntity.courseUnitVOList = courseUnitVOList;
  14 + }
  15 + final int? nowStep = jsonConvert.convert<int>(json['nowStep']);
  16 + if (nowStep != null) {
  17 + courseUnitEntity.nowStep = nowStep;
  18 + }
  19 + final int? total = jsonConvert.convert<int>(json['total']);
  20 + if (total != null) {
  21 + courseUnitEntity.total = total;
  22 + }
  23 + final int? nowCourseModuleId = jsonConvert.convert<int>(
  24 + json['nowCourseModuleId']);
  25 + if (nowCourseModuleId != null) {
  26 + courseUnitEntity.nowCourseModuleId = nowCourseModuleId;
  27 + }
  28 + final String? nowCourseModuleName = jsonConvert.convert<String>(
  29 + json['nowCourseModuleName']);
  30 + if (nowCourseModuleName != null) {
  31 + courseUnitEntity.nowCourseModuleName = nowCourseModuleName;
  32 + }
  33 + final String? courseModuleThemeColor = jsonConvert.convert<String>(
  34 + json['courseModuleThemeColor']);
  35 + if (courseModuleThemeColor != null) {
  36 + courseUnitEntity.courseModuleThemeColor = courseModuleThemeColor;
  37 + }
  38 + final String? courseModuleCode = jsonConvert.convert<String>(
  39 + json['courseModuleCode']);
  40 + if (courseModuleCode != null) {
  41 + courseUnitEntity.courseModuleCode = courseModuleCode;
  42 + }
  43 + return courseUnitEntity;
  44 +}
  45 +
  46 +Map<String, dynamic> $CourseUnitEntityToJson(CourseUnitEntity entity) {
  47 + final Map<String, dynamic> data = <String, dynamic>{};
  48 + data['courseUnitVOList'] =
  49 + entity.courseUnitVOList?.map((v) => v.toJson()).toList();
  50 + data['nowStep'] = entity.nowStep;
  51 + data['total'] = entity.total;
  52 + data['nowCourseModuleId'] = entity.nowCourseModuleId;
  53 + data['nowCourseModuleName'] = entity.nowCourseModuleName;
  54 + data['courseModuleThemeColor'] = entity.courseModuleThemeColor;
  55 + data['courseModuleCode'] = entity.courseModuleCode;
  56 + return data;
  57 +}
  58 +
  59 +extension CourseUnitEntityExtension on CourseUnitEntity {
  60 + CourseUnitEntity copyWith({
  61 + List<CourseUnitDetail>? courseUnitVOList,
  62 + int? nowStep,
  63 + int? total,
  64 + int? nowCourseModuleId,
  65 + String? nowCourseModuleName,
  66 + String? courseModuleThemeColor,
  67 + String? courseModuleCode,
  68 + }) {
  69 + return CourseUnitEntity()
  70 + ..courseUnitVOList = courseUnitVOList ?? this.courseUnitVOList
  71 + ..nowStep = nowStep ?? this.nowStep
  72 + ..total = total ?? this.total
  73 + ..nowCourseModuleId = nowCourseModuleId ?? this.nowCourseModuleId
  74 + ..nowCourseModuleName = nowCourseModuleName ?? this.nowCourseModuleName
  75 + ..courseModuleThemeColor = courseModuleThemeColor ??
  76 + this.courseModuleThemeColor
  77 + ..courseModuleCode = courseModuleCode ?? this.courseModuleCode;
  78 + }
  79 +}
  80 +
  81 +CourseUnitDetail $CourseUnitDetailFromJson(Map<String, dynamic> json) {
  82 + final CourseUnitDetail courseUnitDetail = CourseUnitDetail();
  83 + final int? courseModuleId = jsonConvert.convert<int>(json['courseModuleId']);
  84 + if (courseModuleId != null) {
  85 + courseUnitDetail.courseModuleId = courseModuleId;
  86 + }
  87 + final int? id = jsonConvert.convert<int>(json['id']);
  88 + if (id != null) {
  89 + courseUnitDetail.id = id;
  90 + }
  91 + final String? name = jsonConvert.convert<String>(json['name']);
  92 + if (name != null) {
  93 + courseUnitDetail.name = name;
  94 + }
  95 + final String? coverUrl = jsonConvert.convert<String>(json['coverUrl']);
  96 + if (coverUrl != null) {
  97 + courseUnitDetail.coverUrl = coverUrl;
  98 + }
  99 + final bool? lock = jsonConvert.convert<bool>(json['lock']);
  100 + if (lock != null) {
  101 + courseUnitDetail.lock = lock;
  102 + }
  103 + final int? sortOrder = jsonConvert.convert<int>(json['sortOrder']);
  104 + if (sortOrder != null) {
  105 + courseUnitDetail.sortOrder = sortOrder;
  106 + }
  107 + final int? status = jsonConvert.convert<int>(json['status']);
  108 + if (status != null) {
  109 + courseUnitDetail.status = status;
  110 + }
  111 + return courseUnitDetail;
  112 +}
  113 +
  114 +Map<String, dynamic> $CourseUnitDetailToJson(CourseUnitDetail entity) {
  115 + final Map<String, dynamic> data = <String, dynamic>{};
  116 + data['courseModuleId'] = entity.courseModuleId;
  117 + data['id'] = entity.id;
  118 + data['name'] = entity.name;
  119 + data['coverUrl'] = entity.coverUrl;
  120 + data['lock'] = entity.lock;
  121 + data['sortOrder'] = entity.sortOrder;
  122 + data['status'] = entity.status;
  123 + return data;
  124 +}
  125 +
  126 +extension CourseUnitDetailExtension on CourseUnitDetail {
  127 + CourseUnitDetail copyWith({
  128 + int? courseModuleId,
  129 + int? id,
  130 + String? name,
  131 + String? coverUrl,
  132 + bool? lock,
  133 + int? sortOrder,
  134 + int? status,
  135 + }) {
  136 + return CourseUnitDetail()
  137 + ..courseModuleId = courseModuleId ?? this.courseModuleId
  138 + ..id = id ?? this.id
  139 + ..name = name ?? this.name
  140 + ..coverUrl = coverUrl ?? this.coverUrl
  141 + ..lock = lock ?? this.lock
  142 + ..sortOrder = sortOrder ?? this.sortOrder
  143 + ..status = status ?? this.status;
  144 + }
  145 +}
0 \ No newline at end of file 146 \ No newline at end of file
lib/models/app_config_entity.dart
@@ -7,40 +7,15 @@ import &#39;../generated/json/app_config_entity.g.dart&#39;; @@ -7,40 +7,15 @@ import &#39;../generated/json/app_config_entity.g.dart&#39;;
7 @JsonSerializable() 7 @JsonSerializable()
8 class AppConfigEntity { 8 class AppConfigEntity {
9 9
10 - // 安卓是否强制更新  
11 - bool? androidForceUpdate;  
12 -  
13 - // 安卓是否推荐更新  
14 - bool? androidRecommendUpdate;  
15 -  
16 - // 安卓更新包地址  
17 - String? androidUpdatePackageUrl;  
18 -  
19 - // 安卓当前版本号  
20 - late int androidVersion;  
21 -  
22 - bool? iosForceUpdate;  
23 -  
24 - bool? iosRecommendUpdate;  
25 -  
26 - // ios版本  
27 - late int iosVersion;  
28 -  
29 - // 更新说明  
30 - String? updatePackageDescription;  
31 -  
32 - // 购前须知图片  
33 - String? noticeBeforePurchaseUrl;  
34 -  
35 // 当前是否安全,safe-安全 otherwise-隐藏pay 10 // 当前是否安全,safe-安全 otherwise-隐藏pay
36 String? safe; 11 String? safe;
37 12
38 13
39 AppConfigEntity(); 14 AppConfigEntity();
40 15
41 - factory AppConfigEntity.fromJson(Map<String, dynamic> json) => $AppConfigEntityEntityFromJson(json); 16 + factory AppConfigEntity.fromJson(Map<String, dynamic> json) => $AppConfigEntityFromJson(json);
42 17
43 - Map<String, dynamic> toJson() => $AppConfigEntityEntityToJson(this); 18 + Map<String, dynamic> toJson() => $AppConfigEntityToJson(this);
44 19
45 @override 20 @override
46 String toString() { 21 String toString() {
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 \ No newline at end of file 56 \ No newline at end of file
lib/models/course_module_entity.dart
@@ -5,7 +5,7 @@ import &#39;package:wow_english/generated/json/course_module_entity.g.dart&#39;; @@ -5,7 +5,7 @@ import &#39;package:wow_english/generated/json/course_module_entity.g.dart&#39;;
5 5
6 @JsonSerializable() 6 @JsonSerializable()
7 class CourseModuleEntity { 7 class CourseModuleEntity {
8 - late String id; 8 + int? id;
9 String? code; 9 String? code;
10 int? courseModuleThemeId; 10 int? courseModuleThemeId;
11 int? courseTotal; 11 int? courseTotal;
lib/models/course_section_entity.dart 0 → 100644
  1 +import 'package:wow_english/generated/json/base/json_field.dart';
  2 +import 'package:wow_english/generated/json/course_section_entity.g.dart';
  3 +import 'dart:convert';
  4 +export 'package:wow_english/generated/json/course_section_entity.g.dart';
  5 +
  6 +@JsonSerializable()
  7 +class CourseSectionEntity {
  8 + late int id;
  9 + late int courseUnitId;
  10 + late int courseModuleId;
  11 + late String name;
  12 + dynamic des;
  13 + late int courseType;
  14 + dynamic coverUrl;
  15 + late int sortOrder;
  16 + late int status;
  17 + late bool lock;
  18 +
  19 + CourseSectionEntity();
  20 +
  21 + factory CourseSectionEntity.fromJson(Map<String, dynamic> json) => $CourseSectionEntityFromJson(json);
  22 +
  23 + Map<String, dynamic> toJson() => $CourseSectionEntityToJson(this);
  24 +
  25 + @override
  26 + String toString() {
  27 + return jsonEncode(this);
  28 + }
  29 +}
0 \ No newline at end of file 30 \ No newline at end of file
lib/models/course_unit_entity.dart 0 → 100644
  1 +import 'package:wow_english/generated/json/base/json_field.dart';
  2 +import 'package:wow_english/generated/json/course_unit_entity.g.dart';
  3 +import 'dart:convert';
  4 +
  5 +export 'package:wow_english/generated/json/course_unit_entity.g.dart';
  6 +
  7 +@JsonSerializable()
  8 +class CourseUnitEntity {
  9 +
  10 + // 课程详情列表
  11 + List<CourseUnitDetail>? courseUnitVOList;
  12 +
  13 + // 当前进行了多少节课程
  14 + int? nowStep;
  15 +
  16 + // 当前模块一共多少节课程
  17 + int? total;
  18 +
  19 + // 当前模块id
  20 + int? nowCourseModuleId;
  21 +
  22 + // 当前模块名
  23 + String? nowCourseModuleName;
  24 +
  25 + // 主题颜色值
  26 + String? courseModuleThemeColor;
  27 +
  28 + // 课程模块code
  29 + String? courseModuleCode;
  30 +
  31 + CourseUnitEntity();
  32 +
  33 + factory CourseUnitEntity.fromJson(Map<String, dynamic> json) => $CourseUnitEntityFromJson(json);
  34 +
  35 + Map<String, dynamic> toJson() => $CourseUnitEntityToJson(this);
  36 +
  37 + @override
  38 + String toString() {
  39 + return jsonEncode(this);
  40 + }
  41 +}
  42 +
  43 +
  44 +@JsonSerializable()
  45 +class CourseUnitDetail {
  46 +
  47 + // 模块id
  48 + int? courseModuleId;
  49 +
  50 + // 单元
  51 + int? id;
  52 +
  53 + // 单元名称
  54 + String? name;
  55 +
  56 + // 单元封面
  57 + String? coverUrl;
  58 +
  59 + bool? lock;
  60 +
  61 + int? sortOrder;
  62 +
  63 + int? status;
  64 +
  65 + CourseUnitDetail();
  66 +
  67 + factory CourseUnitDetail.fromJson(Map<String, dynamic> json) => $CourseUnitDetailFromJson(json);
  68 +
  69 + Map<String, dynamic> toJson() => $CourseUnitDetailToJson(this);
  70 +
  71 + @override
  72 + String toString() {
  73 + return jsonEncode(this);
  74 + }
  75 +}
0 \ No newline at end of file 76 \ No newline at end of file
lib/pages/moduleSelect/bloc.dart renamed to lib/pages/home/bloc.dart
1 import 'package:bloc/bloc.dart'; 1 import 'package:bloc/bloc.dart';
2 import 'package:flutter/cupertino.dart'; 2 import 'package:flutter/cupertino.dart';
3 import 'package:flutter/foundation.dart'; 3 import 'package:flutter/foundation.dart';
4 -import 'package:wow_english/models/app_config_entity.dart';  
5 4
6 import '../../common/core/app_config_helper.dart'; 5 import '../../common/core/app_config_helper.dart';
  6 +import '../../common/request/dao/system_dao.dart';
  7 +import '../../models/app_version_entity.dart';
  8 +import '../../utils/log_util.dart';
7 import 'event.dart'; 9 import 'event.dart';
8 import 'state.dart'; 10 import 'state.dart';
9 11
10 -class ModuleSelectBloc extends Bloc<ModuleSelectEvent, ModuleSelectState> {  
11 - ModuleSelectBloc() : super(ModuleSelectState().init()) { 12 +class ModuleSelectBloc extends Bloc<HomeEvent, HomeState> {
  13 + ModuleSelectBloc() : super(HomeState().init()) {
12 on<InitEvent>(_init); 14 on<InitEvent>(_init);
13 } 15 }
14 16
15 - void _init(InitEvent event, Emitter<ModuleSelectState> emit) async { 17 + void _init(InitEvent event, Emitter<HomeState> emit) async {
16 await _checkUpdate(emit); 18 await _checkUpdate(emit);
17 debugPrint('WQF ModuleSelectBloc _init'); 19 debugPrint('WQF ModuleSelectBloc _init');
18 } 20 }
19 21
20 - Future<void> _checkUpdate(Emitter<ModuleSelectState> emit) async { 22 + Future<void> _checkUpdate(Emitter<HomeState> emit) async {
  23 + if (AppConfigHelper.checkedUpdate) {
  24 + return;
  25 + }
21 int localVersion = int.parse(await AppConfigHelper.getAppVersion()); 26 int localVersion = int.parse(await AppConfigHelper.getAppVersion());
22 - AppConfigEntity? appConfigEntity = await AppConfigHelper.getAppConfig();  
23 - if (appConfigEntity == null) { 27 + AppVersionEntity? appVersionEntity = await SystemDao.getVersionInfo();
  28 + AppConfigHelper.checkedUpdate = true;
  29 + if (appVersionEntity == null) {
24 return; 30 return;
25 } 31 }
26 - debugPrint('WQF _checkUpdate');  
27 - if (defaultTargetPlatform == TargetPlatform.iOS) {  
28 - if (localVersion < appConfigEntity.iosVersion &&  
29 - appConfigEntity.iosRecommendUpdate == true) {  
30 - emit(UpdateDialogState(  
31 - appConfigEntity.iosForceUpdate ?? false, appConfigEntity));  
32 - }  
33 - } else {  
34 - if (localVersion < appConfigEntity.androidVersion &&  
35 - appConfigEntity.androidRecommendUpdate == true) {  
36 - emit(UpdateDialogState(  
37 - appConfigEntity.androidForceUpdate ?? false, appConfigEntity,  
38 - ));  
39 - } 32 + Log.d("WQF _checkUpdate appVersionEntity: $appVersionEntity localVersion=$localVersion");
  33 + if (localVersion < int.parse(appVersionEntity.version ?? '0')) {
  34 + emit(UpdateDialogState(
  35 + appVersionEntity.volType == UpdateStrategy.FORCE.name, appVersionEntity));
40 } 36 }
41 } 37 }
42 } 38 }
lib/pages/home/event.dart 0 → 100644
  1 +abstract class HomeEvent {}
  2 +
  3 +class InitEvent extends HomeEvent {}
0 \ No newline at end of file 4 \ No newline at end of file
lib/pages/home/state.dart 0 → 100644
  1 +import 'package:wow_english/models/app_version_entity.dart';
  2 +
  3 +class HomeState {
  4 + HomeState init() {
  5 + return HomeState();
  6 + }
  7 +
  8 + HomeState clone() {
  9 + return HomeState();
  10 + }
  11 +}
  12 +
  13 +class UpdateDialogState extends HomeState {
  14 +
  15 + final AppVersionEntity appVersionEntity;
  16 +
  17 + final bool forceUpdate;
  18 +
  19 + UpdateDialogState(this.forceUpdate, this.appVersionEntity);
  20 +}
lib/pages/moduleSelect/view.dart renamed to lib/pages/home/view.dart
@@ -8,20 +8,21 @@ import &#39;package:flutter_bloc/flutter_bloc.dart&#39;; @@ -8,20 +8,21 @@ import &#39;package:flutter_bloc/flutter_bloc.dart&#39;;
8 import 'package:url_launcher/url_launcher.dart'; 8 import 'package:url_launcher/url_launcher.dart';
9 import 'package:wow_english/common/core/app_config_helper.dart'; 9 import 'package:wow_english/common/core/app_config_helper.dart';
10 import 'package:wow_english/common/extension/string_extension.dart'; 10 import 'package:wow_english/common/extension/string_extension.dart';
11 -import 'package:wow_english/pages/moduleSelect/state.dart';  
12 -import 'package:wow_english/pages/moduleSelect/widgets/BaseHomeHeaderWidget.dart'; 11 +import 'package:wow_english/models/app_version_entity.dart';
  12 +import 'package:wow_english/pages/home/state.dart';
  13 +import 'package:wow_english/pages/home/widgets/BaseHomeHeaderWidget.dart';
13 import 'package:wow_english/pages/user/bloc/user_bloc.dart'; 14 import 'package:wow_english/pages/user/bloc/user_bloc.dart';
14 15
15 import '../../common/core/user_util.dart'; 16 import '../../common/core/user_util.dart';
16 import '../../common/dialogs/show_dialog.dart'; 17 import '../../common/dialogs/show_dialog.dart';
17 -import '../../models/app_config_entity.dart'; 18 +import '../../utils/log_util.dart';
18 import 'bloc.dart'; 19 import 'bloc.dart';
19 import 'event.dart'; 20 import 'event.dart';
20 import 'package:flutter_screenutil/flutter_screenutil.dart'; 21 import 'package:flutter_screenutil/flutter_screenutil.dart';
21 import 'package:wow_english/route/route.dart'; 22 import 'package:wow_english/route/route.dart';
22 23
23 -class ModuleSelectPage extends StatelessWidget {  
24 - const ModuleSelectPage({super.key}); 24 +class HomePage extends StatelessWidget {
  25 + const HomePage({super.key});
25 26
26 @override 27 @override
27 Widget build(BuildContext context) { 28 Widget build(BuildContext context) {
@@ -41,10 +42,11 @@ class _HomePageView extends StatelessWidget { @@ -41,10 +42,11 @@ class _HomePageView extends StatelessWidget {
41 BlocListener<UserBloc, UserState>(listener: (context, state) { 42 BlocListener<UserBloc, UserState>(listener: (context, state) {
42 debugPrint('WQF ModuleSelectPage BlocListener state: $state'); 43 debugPrint('WQF ModuleSelectPage BlocListener state: $state');
43 }), 44 }),
44 - BlocListener<ModuleSelectBloc, ModuleSelectState>( 45 + BlocListener<ModuleSelectBloc, HomeState>(
45 listener: (context, state) { 46 listener: (context, state) {
  47 + Log.d("WQF HomePage listener state: $state");
46 if (state is UpdateDialogState) { 48 if (state is UpdateDialogState) {
47 - _showUpdateDialog(context, state.forceUpdate, state.appConfigEntity); 49 + _showUpdateDialog(context, state.forceUpdate, state.appVersionEntity);
48 } 50 }
49 }, 51 },
50 ), 52 ),
@@ -52,7 +54,7 @@ class _HomePageView extends StatelessWidget { @@ -52,7 +54,7 @@ class _HomePageView extends StatelessWidget {
52 } 54 }
53 55
54 Widget _homeView() => 56 Widget _homeView() =>
55 - BlocBuilder<ModuleSelectBloc, ModuleSelectState>( 57 + BlocBuilder<ModuleSelectBloc, HomeState>(
56 builder: (context, state) { 58 builder: (context, state) {
57 return Scaffold( 59 return Scaffold(
58 body: Container( 60 body: Container(
@@ -68,7 +70,7 @@ class _HomePageView extends StatelessWidget { @@ -68,7 +70,7 @@ class _HomePageView extends StatelessWidget {
68 child: GestureDetector( 70 child: GestureDetector(
69 onTap: () { 71 onTap: () {
70 if (UserUtil.isLogined()) { 72 if (UserUtil.isLogined()) {
71 - pushNamed(AppRouteName.home); 73 + pushNamed(AppRouteName.courseUnit);
72 } else { 74 } else {
73 pushNamed(AppRouteName.login); 75 pushNamed(AppRouteName.login);
74 } 76 }
@@ -169,7 +171,7 @@ class _HomePageView extends StatelessWidget { @@ -169,7 +171,7 @@ class _HomePageView extends StatelessWidget {
169 ///Flutter侧处理升级对话框 171 ///Flutter侧处理升级对话框
170 ///[forcedUpgrade] 是否强制升级 172 ///[forcedUpgrade] 是否强制升级
171 _showUpdateDialog(BuildContext context, bool forcedUpgrade, 173 _showUpdateDialog(BuildContext context, bool forcedUpgrade,
172 - AppConfigEntity appConfigEntity) { 174 + AppVersionEntity appVersionEntity) {
173 showDialog( 175 showDialog(
174 context: context, 176 context: context,
175 // 当我们点击除开对话框内容以外的区域是否关闭对话需用用到barrierDismissible参数 . 这个参数默认值是true ,但不能为null . 177 // 当我们点击除开对话框内容以外的区域是否关闭对话需用用到barrierDismissible参数 . 这个参数默认值是true ,但不能为null .
@@ -180,7 +182,7 @@ class _HomePageView extends StatelessWidget { @@ -180,7 +182,7 @@ class _HomePageView extends StatelessWidget {
180 child: AlertDialog( 182 child: AlertDialog(
181 title: const Text('发现新版本'), 183 title: const Text('发现新版本'),
182 content: Text( 184 content: Text(
183 - appConfigEntity.updatePackageDescription ?? 185 + appVersionEntity.remark ??
184 '修复了一些已知问题'), 186 '修复了一些已知问题'),
185 actions: <Widget>[ 187 actions: <Widget>[
186 TextButton( 188 TextButton(
@@ -188,7 +190,7 @@ class _HomePageView extends StatelessWidget { @@ -188,7 +190,7 @@ class _HomePageView extends StatelessWidget {
188 onPressed: () => 190 onPressed: () =>
189 { 191 {
190 if (forcedUpgrade) { 192 if (forcedUpgrade) {
191 - SystemNavigator.pop() 193 + AppConfigHelper.exitApp()
192 } else 194 } else
193 { 195 {
194 Navigator.of(context).pop() 196 Navigator.of(context).pop()
@@ -198,11 +200,11 @@ class _HomePageView extends StatelessWidget { @@ -198,11 +200,11 @@ class _HomePageView extends StatelessWidget {
198 TextButton( 200 TextButton(
199 child: const Text('升级'), 201 child: const Text('升级'),
200 onPressed: () async { 202 onPressed: () async {
201 - if (defaultTargetPlatform == TargetPlatform.iOS) { 203 + if (AppConfigHelper.isIosPlatform()) {
202 _launchAppStore("6450870731"); 204 _launchAppStore("6450870731");
203 return; 205 return;
204 } 206 }
205 - final String? apkUrl = appConfigEntity.androidUpdatePackageUrl; 207 + final String? apkUrl = appVersionEntity.packageUrl;
206 if (apkUrl == null || apkUrl.isEmpty) { 208 if (apkUrl == null || apkUrl.isEmpty) {
207 return; 209 return;
208 } 210 }
lib/pages/moduleSelect/widgets/BaseHomeHeaderWidget.dart renamed to lib/pages/home/widgets/BaseHomeHeaderWidget.dart
@@ -78,8 +78,8 @@ class BaseHomeHeaderWidget extends StatelessWidget { @@ -78,8 +78,8 @@ class BaseHomeHeaderWidget extends StatelessWidget {
78 textAlign: TextAlign.left, 78 textAlign: TextAlign.left,
79 style: TextStyle(color: Colors.white, fontSize: 30.0), 79 style: TextStyle(color: Colors.white, fontSize: 30.0),
80 )), 80 )),
81 - Visibility(  
82 - visible: !AppConfigHelper.shouldHidePay(), 81 + Offstage(
  82 + offstage: AppConfigHelper.shouldHidePay(),
83 child: Row(children: <Widget>[ 83 child: Row(children: <Widget>[
84 Image( 84 Image(
85 width: 20.0.w, 85 width: 20.0.w,
lib/pages/lessons/bloc/lesson_state.dart deleted
1 -part of 'lesson_bloc.dart';  
2 -  
3 -@immutable  
4 -abstract class LessonState {}  
5 -  
6 -class LessonInitial extends LessonState {}  
7 -  
8 -class PageIndexChangeState extends LessonState {}  
9 -  
10 -class LessonDataLoadState extends LessonState {}  
lib/pages/login/loginpage/login_page.dart
@@ -34,7 +34,7 @@ class _LoginPageView extends StatelessWidget { @@ -34,7 +34,7 @@ class _LoginPageView extends StatelessWidget {
34 if (state is LoginResultChangeState) { 34 if (state is LoginResultChangeState) {
35 // 调试用 35 // 调试用
36 // Navigator.of(context).pushNamed(AppRouteName.home); 36 // Navigator.of(context).pushNamed(AppRouteName.home);
37 - pushNamedAndRemoveUntil(AppRouteName.moduleSelect, (route) => false); 37 + pushNamedAndRemoveUntil(AppRouteName.home, (route) => false);
38 } 38 }
39 }, 39 },
40 child: _buildLoginViewWidget(), 40 child: _buildLoginViewWidget(),
lib/pages/lessons/bloc/lesson_bloc.dart renamed to lib/pages/module/bloc/module_bloc.dart
1 import 'package:flutter/cupertino.dart'; 1 import 'package:flutter/cupertino.dart';
2 import 'package:flutter_bloc/flutter_bloc.dart'; 2 import 'package:flutter_bloc/flutter_bloc.dart';
3 -import 'package:wow_english/common/request/dao/home_dao.dart'; 3 +import 'package:wow_english/common/request/dao/lesson_dao.dart';
4 import 'package:wow_english/common/request/exception.dart'; 4 import 'package:wow_english/common/request/exception.dart';
5 import 'package:wow_english/models/course_module_entity.dart'; 5 import 'package:wow_english/models/course_module_entity.dart';
6 import 'package:wow_english/utils/loading.dart'; 6 import 'package:wow_english/utils/loading.dart';
7 import 'package:wow_english/utils/toast_util.dart'; 7 import 'package:wow_english/utils/toast_util.dart';
8 8
9 -part 'lesson_event.dart';  
10 -part 'lesson_state.dart'; 9 +part 'module_event.dart';
  10 +part 'module_state.dart';
11 11
12 -class LessonBloc extends Bloc<LessonEvent, LessonState> { 12 +class ModuleBloc extends Bloc<ModuleEvent, ModuleState> {
13 final int pageIndex; 13 final int pageIndex;
14 14
15 final PageController pageController; 15 final PageController pageController;
@@ -22,22 +22,22 @@ class LessonBloc extends Bloc&lt;LessonEvent, LessonState&gt; { @@ -22,22 +22,22 @@ class LessonBloc extends Bloc&lt;LessonEvent, LessonState&gt; {
22 22
23 List<CourseModuleEntity?> get listData => _listData; 23 List<CourseModuleEntity?> get listData => _listData;
24 24
25 - LessonBloc(this.pageIndex, this.pageController) : super(LessonInitial()) { 25 + ModuleBloc(this.pageIndex, this.pageController) : super(ModuleInitial()) {
26 _currentPageIndex = pageIndex; 26 _currentPageIndex = pageIndex;
27 on<PageViewChangeIndexEvent>(_pageIndexChange); 27 on<PageViewChangeIndexEvent>(_pageIndexChange);
28 on<RequestDataEvent>(_requestData); 28 on<RequestDataEvent>(_requestData);
29 } 29 }
30 30
31 - void _pageIndexChange(PageViewChangeIndexEvent event, Emitter<LessonState> emitter) async { 31 + void _pageIndexChange(PageViewChangeIndexEvent event, Emitter<ModuleState> emitter) async {
32 _currentPageIndex = event.index; 32 _currentPageIndex = event.index;
33 emitter(PageIndexChangeState()); 33 emitter(PageIndexChangeState());
34 } 34 }
35 35
36 - void _requestData(RequestDataEvent event, Emitter<LessonState> emitter) async { 36 + void _requestData(RequestDataEvent event, Emitter<ModuleState> emitter) async {
37 try { 37 try {
38 await loading(() async { 38 await loading(() async {
39 - _listData = await HomeDao.courseModule() ?? [];  
40 - emitter(LessonDataLoadState()); 39 + _listData = await LessonDao.courseModule() ?? [];
  40 + emitter(ModuleDataLoadState());
41 }); 41 });
42 } catch (e) { 42 } catch (e) {
43 if (e is ApiException) { 43 if (e is ApiException) {
lib/pages/lessons/bloc/lesson_event.dart renamed to lib/pages/module/bloc/module_event.dart
1 -part of 'lesson_bloc.dart'; 1 +part of 'module_bloc.dart';
2 2
3 @immutable 3 @immutable
4 -abstract class LessonEvent {} 4 +abstract class ModuleEvent {}
5 5
6 -class PageViewChangeIndexEvent extends LessonEvent { 6 +class PageViewChangeIndexEvent extends ModuleEvent {
7 final int index; 7 final int index;
8 PageViewChangeIndexEvent(this.index); 8 PageViewChangeIndexEvent(this.index);
9 } 9 }
10 10
11 -class RequestDataEvent extends LessonEvent {} 11 +class RequestDataEvent extends ModuleEvent {}
lib/pages/module/bloc/module_state.dart 0 → 100644
  1 +part of 'module_bloc.dart';
  2 +
  3 +@immutable
  4 +abstract class ModuleState {}
  5 +
  6 +class ModuleInitial extends ModuleState {}
  7 +
  8 +class PageIndexChangeState extends ModuleState {}
  9 +
  10 +class ModuleDataLoadState extends ModuleState {}
lib/pages/lessons/lesson_page.dart renamed to lib/pages/module/module_page.dart
@@ -6,23 +6,21 @@ import &#39;package:wow_english/common/widgets/we_app_bar.dart&#39;; @@ -6,23 +6,21 @@ import &#39;package:wow_english/common/widgets/we_app_bar.dart&#39;;
6 import 'package:wow_english/models/course_module_entity.dart'; 6 import 'package:wow_english/models/course_module_entity.dart';
7 import 'package:wow_english/route/route.dart'; 7 import 'package:wow_english/route/route.dart';
8 8
9 -import 'bloc/lesson_bloc.dart';  
10 -import 'widgets/lesson_item_widget.dart'; 9 +import 'bloc/module_bloc.dart';
  10 +import 'widgets/module_item_widget.dart';
11 11
12 -class LessonPage extends StatelessWidget {  
13 - const LessonPage({super.key, this.starPageIndex}); 12 +// 阶段(模块)列表页
  13 +class ModulePage extends StatelessWidget {
  14 + const ModulePage({super.key, this.starPageIndex});
14 15
15 final int? starPageIndex; 16 final int? starPageIndex;
16 17
17 @override 18 @override
18 Widget build(BuildContext context) { 19 Widget build(BuildContext context) {
19 return BlocProvider( 20 return BlocProvider(
20 - create: (context) => LessonBloc(  
21 - starPageIndex??0,  
22 - PageController(  
23 - initialPage: starPageIndex??0,  
24 - viewportFraction: 0.3  
25 - ), 21 + create: (context) => ModuleBloc(
  22 + starPageIndex ?? 0,
  23 + PageController(initialPage: starPageIndex ?? 0, viewportFraction: 0.3),
26 )..add(RequestDataEvent()), 24 )..add(RequestDataEvent()),
27 child: _LessonPageView(), 25 child: _LessonPageView(),
28 ); 26 );
@@ -30,27 +28,25 @@ class LessonPage extends StatelessWidget { @@ -30,27 +28,25 @@ class LessonPage extends StatelessWidget {
30 } 28 }
31 29
32 class _LessonPageView extends StatelessWidget { 30 class _LessonPageView extends StatelessWidget {
33 -  
34 final double _cardHeight = 240.h; 31 final double _cardHeight = 240.h;
35 32
36 final double _scale = 0.8; 33 final double _scale = 0.8;
37 34
38 @override 35 @override
39 Widget build(BuildContext context) { 36 Widget build(BuildContext context) {
40 - return BlocListener<LessonBloc,LessonState>(  
41 - listener: (context, state){}, 37 + return BlocListener<ModuleBloc, ModuleState>(
  38 + listener: (context, state) {},
42 child: Scaffold( 39 child: Scaffold(
43 appBar: WEAppBar( 40 appBar: WEAppBar(
44 leading: IconButton( 41 leading: IconButton(
45 - onPressed: (){  
46 - popPage(); 42 + onPressed: () {
  43 + popPage();
47 }, 44 },
48 icon: Image.asset( 45 icon: Image.asset(
49 'back'.assetPng, 46 'back'.assetPng,
50 height: 43, 47 height: 43,
51 width: 43, 48 width: 43,
52 - )  
53 - ), 49 + )),
54 // actions: <Widget>[ 50 // actions: <Widget>[
55 // IconButton( 51 // IconButton(
56 // icon: Image.asset('shop'.assetPng), 52 // icon: Image.asset('shop'.assetPng),
@@ -66,9 +62,9 @@ class _LessonPageView extends StatelessWidget { @@ -66,9 +62,9 @@ class _LessonPageView extends StatelessWidget {
66 ); 62 );
67 } 63 }
68 64
69 - Widget _lessViewWidget() => BlocBuilder<LessonBloc,LessonState>(  
70 - builder: (context, state){  
71 - final bloc = BlocProvider.of<LessonBloc>(context); 65 + Widget _lessViewWidget() =>
  66 + BlocBuilder<ModuleBloc, ModuleState>(builder: (context, state) {
  67 + final bloc = BlocProvider.of<ModuleBloc>(context);
72 return Center( 68 return Center(
73 child: SafeArea( 69 child: SafeArea(
74 child: Column( 70 child: Column(
@@ -81,8 +77,7 @@ class _LessonPageView extends StatelessWidget { @@ -81,8 +77,7 @@ class _LessonPageView extends StatelessWidget {
81 onPageChanged: (int index) { 77 onPageChanged: (int index) {
82 bloc.add(PageViewChangeIndexEvent(index)); 78 bloc.add(PageViewChangeIndexEvent(index));
83 }, 79 },
84 - itemBuilder: (context,index) => _itemTransCard(index)  
85 - ), 80 + itemBuilder: (context, index) => _itemTransCard(index)),
86 ), 81 ),
87 32.verticalSpace, 82 32.verticalSpace,
88 SizedBox( 83 SizedBox(
@@ -91,7 +86,7 @@ class _LessonPageView extends StatelessWidget { @@ -91,7 +86,7 @@ class _LessonPageView extends StatelessWidget {
91 child: ListView.builder( 86 child: ListView.builder(
92 itemCount: bloc.listData.length, 87 itemCount: bloc.listData.length,
93 scrollDirection: Axis.horizontal, 88 scrollDirection: Axis.horizontal,
94 - itemBuilder: (BuildContext context,int index){ 89 + itemBuilder: (BuildContext context, int index) {
95 return Container( 90 return Container(
96 height: 32.h, 91 height: 32.h,
97 width: 66.w, 92 width: 66.w,
@@ -101,13 +96,19 @@ class _LessonPageView extends StatelessWidget { @@ -101,13 +96,19 @@ class _LessonPageView extends StatelessWidget {
101 if (index == bloc.currentPageIndex) { 96 if (index == bloc.currentPageIndex) {
102 return; 97 return;
103 } 98 }
104 - int mill = (index - bloc.currentPageIndex) > 0 ? 100 * (index - bloc.currentPageIndex):100 * (bloc.currentPageIndex-index);  
105 - bloc.pageController.animateToPage(index, duration: Duration(milliseconds: mill), curve: Curves.ease); 99 + int mill = (index - bloc.currentPageIndex) > 0
  100 + ? 100 * (index - bloc.currentPageIndex)
  101 + : 100 * (bloc.currentPageIndex - index);
  102 + bloc.pageController.animateToPage(index,
  103 + duration: Duration(milliseconds: mill),
  104 + curve: Curves.ease);
106 }, 105 },
107 child: Container( 106 child: Container(
108 - height: bloc.currentPageIndex == index ? 32:20, 107 + height: bloc.currentPageIndex == index ? 32 : 20,
109 decoration: BoxDecoration( 108 decoration: BoxDecoration(
110 - color: bloc.currentPageIndex == index ? Colors.red:Colors.white, 109 + color: bloc.currentPageIndex == index
  110 + ? Colors.red
  111 + : Colors.white,
111 borderRadius: BorderRadius.circular(5.r), 112 borderRadius: BorderRadius.circular(5.r),
112 border: Border.all( 113 border: Border.all(
113 width: 0.5, 114 width: 0.5,
@@ -116,10 +117,11 @@ class _LessonPageView extends StatelessWidget { @@ -116,10 +117,11 @@ class _LessonPageView extends StatelessWidget {
116 ), 117 ),
117 alignment: Alignment.center, 118 alignment: Alignment.center,
118 child: Text( 119 child: Text(
119 - (index+1).toString(), 120 + (index + 1).toString(),
120 style: TextStyle( 121 style: TextStyle(
121 - color: bloc.currentPageIndex == index ? Colors.white:Colors.black  
122 - ), 122 + color: bloc.currentPageIndex == index
  123 + ? Colors.white
  124 + : Colors.black),
123 ), 125 ),
124 ), 126 ),
125 ), 127 ),
@@ -132,49 +134,54 @@ class _LessonPageView extends StatelessWidget { @@ -132,49 +134,54 @@ class _LessonPageView extends StatelessWidget {
132 ); 134 );
133 }); 135 });
134 136
135 - Widget _itemTransCard(int index) => BlocBuilder<LessonBloc,LessonState>(  
136 - builder: (context, state) {  
137 - final bloc = BlocProvider.of<LessonBloc>(context);  
138 - Matrix4 matrix4 = Matrix4.identity();  
139 - if (index == bloc.currentPageIndex.floor()) {  
140 - //当前的item  
141 - double currScale = (1 - (bloc.currentPageIndex - index) * (1 - _scale)).toDouble();  
142 - var currTrans = _cardHeight * (1 - currScale) / 2; 137 + Widget _itemTransCard(int index) =>
  138 + BlocBuilder<ModuleBloc, ModuleState>(builder: (context, state) {
  139 + final bloc = BlocProvider.of<ModuleBloc>(context);
  140 + Matrix4 matrix4 = Matrix4.identity();
  141 + if (index == bloc.currentPageIndex.floor()) {
  142 + //当前的item
  143 + double currScale =
  144 + (1 - (bloc.currentPageIndex - index) * (1 - _scale)).toDouble();
  145 + var currTrans = _cardHeight * (1 - currScale) / 2;
143 146
144 - matrix4 = Matrix4.diagonal3Values(1.0, currScale, 1.0)  
145 - ..setTranslationRaw(0.0, currTrans, 0.0);  
146 - } else if (index == bloc.currentPageIndex.floor() + 1) {  
147 - //右边的item  
148 - var currScale = _scale + (bloc.currentPageIndex - index + 1) * (1 - _scale);  
149 - var currTrans = _cardHeight * (1 - currScale) / 2; 147 + matrix4 = Matrix4.diagonal3Values(1.0, currScale, 1.0)
  148 + ..setTranslationRaw(0.0, currTrans, 0.0);
  149 + } else if (index == bloc.currentPageIndex.floor() + 1) {
  150 + //右边的item
  151 + var currScale =
  152 + _scale + (bloc.currentPageIndex - index + 1) * (1 - _scale);
  153 + var currTrans = _cardHeight * (1 - currScale) / 2;
150 154
151 - matrix4 = Matrix4.diagonal3Values(1.0, currScale, 1.0)  
152 - ..setTranslationRaw(0.0, currTrans, 0.0);  
153 - } else if (index == bloc.currentPageIndex - 1) {  
154 - //左边  
155 - var currScale = (1 - (bloc.currentPageIndex - index) * (1 - _scale)).toDouble();  
156 - var currTrans = _cardHeight * (1 - currScale) / 2; 155 + matrix4 = Matrix4.diagonal3Values(1.0, currScale, 1.0)
  156 + ..setTranslationRaw(0.0, currTrans, 0.0);
  157 + } else if (index == bloc.currentPageIndex - 1) {
  158 + //左边
  159 + var currScale =
  160 + (1 - (bloc.currentPageIndex - index) * (1 - _scale)).toDouble();
  161 + var currTrans = _cardHeight * (1 - currScale) / 2;
157 162
158 - matrix4 = Matrix4.diagonal3Values(1.0, currScale, 1.0)  
159 - ..setTranslationRaw(0.0, currTrans, 0.0);  
160 - } else {  
161 - //其他,不在屏幕显示的item  
162 - matrix4 = Matrix4.diagonal3Values(1.0, _scale, 1.0)  
163 - ..setTranslationRaw(0.0, _cardHeight * (1 - _scale) / 2, 0.0);  
164 - }  
165 - CourseModuleEntity? model = bloc.listData[index];  
166 - return Transform(  
167 - transform: matrix4,  
168 - child: Padding(  
169 - padding: const EdgeInsets.symmetric(horizontal: 10),  
170 - child: LessonItemWidget(  
171 - model: model,  
172 - isSelected: bloc.currentPageIndex == index,  
173 - onClickEvent: () {  
174 - pushNamedAndRemoveUntil(AppRouteName.home, (route) => false,arguments: {'moduleId':model?.id});  
175 - }, 163 + matrix4 = Matrix4.diagonal3Values(1.0, currScale, 1.0)
  164 + ..setTranslationRaw(0.0, currTrans, 0.0);
  165 + } else {
  166 + //其他,不在屏幕显示的item
  167 + matrix4 = Matrix4.diagonal3Values(1.0, _scale, 1.0)
  168 + ..setTranslationRaw(0.0, _cardHeight * (1 - _scale) / 2, 0.0);
  169 + }
  170 + CourseModuleEntity? model = bloc.listData[index];
  171 + return Transform(
  172 + transform: matrix4,
  173 + child: Padding(
  174 + padding: const EdgeInsets.symmetric(horizontal: 10),
  175 + child: ModuleItemWidget(
  176 + model: model,
  177 + isSelected: bloc.currentPageIndex == index,
  178 + onClickEvent: () {
  179 + pushNamedAndRemoveUntil(
  180 + AppRouteName.courseUnit, (route) => route.isFirst,
  181 + arguments: {'courseModuleEntity': model});
  182 + },
  183 + ),
176 ), 184 ),
177 - ),  
178 - );  
179 - }); 185 + );
  186 + });
180 } 187 }
lib/pages/lessons/widgets/lesson_item_widget.dart renamed to lib/pages/module/widgets/module_item_widget.dart
@@ -4,10 +4,10 @@ import &#39;package:wow_english/common/extension/string_extension.dart&#39;; @@ -4,10 +4,10 @@ import &#39;package:wow_english/common/extension/string_extension.dart&#39;;
4 import 'package:wow_english/common/widgets/ow_image_widget.dart'; 4 import 'package:wow_english/common/widgets/ow_image_widget.dart';
5 import 'package:wow_english/models/course_module_entity.dart'; 5 import 'package:wow_english/models/course_module_entity.dart';
6 6
7 -import '../../home/courese_module_model.dart'; 7 +import '../../section/courese_module_model.dart';
8 8
9 -class LessonItemWidget extends StatelessWidget {  
10 - const LessonItemWidget({super.key, required this.isSelected, this.model, this.onClickEvent}); 9 +class ModuleItemWidget extends StatelessWidget {
  10 + const ModuleItemWidget({super.key, required this.isSelected, this.model, this.onClickEvent});
11 ///是否被选中 11 ///是否被选中
12 final bool isSelected; 12 final bool isSelected;
13 final CourseModuleEntity? model; 13 final CourseModuleEntity? model;
lib/pages/moduleSelect/event.dart deleted
1 -abstract class ModuleSelectEvent {}  
2 -  
3 -class InitEvent extends ModuleSelectEvent {}  
4 \ No newline at end of file 0 \ No newline at end of file
lib/pages/moduleSelect/state.dart deleted
1 -import '../../models/app_config_entity.dart';  
2 -  
3 -class ModuleSelectState {  
4 - ModuleSelectState init() {  
5 - return ModuleSelectState();  
6 - }  
7 -  
8 - ModuleSelectState clone() {  
9 - return ModuleSelectState();  
10 - }  
11 -}  
12 -  
13 -class UpdateDialogState extends ModuleSelectState {  
14 -  
15 - final AppConfigEntity appConfigEntity;  
16 -  
17 - final bool forceUpdate;  
18 -  
19 - UpdateDialogState(this.forceUpdate, this.appConfigEntity);  
20 -}  
lib/pages/home/bloc/home_bloc.dart renamed to lib/pages/section/bloc/section_bloc.dart
1 import 'package:flutter/cupertino.dart'; 1 import 'package:flutter/cupertino.dart';
2 import 'package:flutter/foundation.dart'; 2 import 'package:flutter/foundation.dart';
3 import 'package:flutter_bloc/flutter_bloc.dart'; 3 import 'package:flutter_bloc/flutter_bloc.dart';
4 -import 'package:wow_english/common/request/dao/home_dao.dart'; 4 +import 'package:wow_english/common/request/dao/lesson_dao.dart';
5 import 'package:wow_english/common/request/exception.dart'; 5 import 'package:wow_english/common/request/exception.dart';
6 -import 'package:wow_english/models/course_entity.dart';  
7 import 'package:wow_english/common/request/dao/listen_dao.dart'; 6 import 'package:wow_english/common/request/dao/listen_dao.dart';
8 import 'package:wow_english/models/course_process_entity.dart'; 7 import 'package:wow_english/models/course_process_entity.dart';
9 import 'package:wow_english/utils/loading.dart'; 8 import 'package:wow_english/utils/loading.dart';
10 import 'package:wow_english/utils/toast_util.dart'; 9 import 'package:wow_english/utils/toast_util.dart';
11 10
12 -part 'home_event.dart';  
13 -part 'home_state.dart'; 11 +import '../../../models/course_section_entity.dart';
  12 +import '../../../models/course_unit_entity.dart';
14 13
15 -class HomeBloc extends Bloc<HomeEvent, HomeState> {  
16 - final String? moduleId; 14 +part 'section_event.dart';
  15 +part 'section_state.dart';
17 16
18 - CourseEntity? _modelData; 17 +class SectionBloc extends Bloc<SectionEvent, SectionState> {
19 18
20 - CourseEntity? get modelData => _modelData; 19 + CourseUnitEntity _courseUnitEntity;
  20 +
  21 + CourseUnitEntity get courseUnitEntity => _courseUnitEntity;
  22 +
  23 + CourseUnitDetail _courseUnitDetail;
  24 +
  25 + CourseUnitDetail get courseUnitDetail => _courseUnitDetail;
  26 +
  27 + List<CourseSectionEntity>? _courseSectionDatas;
  28 +
  29 + List<CourseSectionEntity>? get courseSectionDatas => _courseSectionDatas;
21 30
22 CourseProcessEntity? _processEntity; 31 CourseProcessEntity? _processEntity;
23 32
24 CourseProcessEntity? get processEntity => _processEntity; 33 CourseProcessEntity? get processEntity => _processEntity;
25 34
26 - HomeBloc(this.moduleId) : super(HomeInitial()) { 35 + SectionBloc(this._courseUnitEntity, this._courseUnitDetail) : super(LessonInitial()) {
27 on<RequestDataEvent>(_requestData); 36 on<RequestDataEvent>(_requestData);
28 on<RequestExitClassEvent>(_requestExitClass); 37 on<RequestExitClassEvent>(_requestExitClass);
29 on<RequestEnterClassEvent>(_requestEnterClass); 38 on<RequestEnterClassEvent>(_requestEnterClass);
30 on<RequestVideoLessonEvent>(_requestVideoLesson); 39 on<RequestVideoLessonEvent>(_requestVideoLesson);
31 } 40 }
32 41
33 - void _requestData(RequestDataEvent event, Emitter<HomeState> emitter) async { 42 + void _requestData(RequestDataEvent event, Emitter<SectionState> emitter) async {
34 try { 43 try {
35 await loading(() async { 44 await loading(() async {
36 - _modelData = await HomeDao.courseLesson(moduleId: moduleId ?? '');  
37 - emitter(HomeDataLoadState()); 45 + _courseSectionDatas = await LessonDao.courseSection(courseUnitId: _courseUnitDetail.id!);
  46 + emitter(LessonDataLoadState());
38 }); 47 });
39 } catch (e) { 48 } catch (e) {
40 if (e is ApiException) { 49 if (e is ApiException) {
@@ -43,7 +52,7 @@ class HomeBloc extends Bloc&lt;HomeEvent, HomeState&gt; { @@ -43,7 +52,7 @@ class HomeBloc extends Bloc&lt;HomeEvent, HomeState&gt; {
43 } 52 }
44 } 53 }
45 54
46 - void _requestVideoLesson(RequestVideoLessonEvent event, Emitter<HomeState> emitter) async { 55 + void _requestVideoLesson(RequestVideoLessonEvent event, Emitter<SectionState> emitter) async {
47 try { 56 try {
48 await loading(() async { 57 await loading(() async {
49 _processEntity = await ListenDao.process(event.courseLessonId); 58 _processEntity = await ListenDao.process(event.courseLessonId);
@@ -57,7 +66,7 @@ class HomeBloc extends Bloc&lt;HomeEvent, HomeState&gt; { @@ -57,7 +66,7 @@ class HomeBloc extends Bloc&lt;HomeEvent, HomeState&gt; {
57 } 66 }
58 67
59 68
60 - void _requestEnterClass(RequestEnterClassEvent event,Emitter<HomeState> emitter) async { 69 + void _requestEnterClass(RequestEnterClassEvent event,Emitter<SectionState> emitter) async {
61 try { 70 try {
62 await loading(() async { 71 await loading(() async {
63 await ListenDao.enterClass(event.courseLessonId); 72 await ListenDao.enterClass(event.courseLessonId);
@@ -70,7 +79,7 @@ class HomeBloc extends Bloc&lt;HomeEvent, HomeState&gt; { @@ -70,7 +79,7 @@ class HomeBloc extends Bloc&lt;HomeEvent, HomeState&gt; {
70 } 79 }
71 } 80 }
72 81
73 - void _requestExitClass(RequestExitClassEvent event,Emitter<HomeState> emitter) async { 82 + void _requestExitClass(RequestExitClassEvent event,Emitter<SectionState> emitter) async {
74 await ListenDao.exitClass(event.courseLessonId,event.currentStep,event.currentTime); 83 await ListenDao.exitClass(event.courseLessonId,event.currentStep,event.currentTime);
75 } 84 }
76 } 85 }
lib/pages/home/bloc/home_event.dart renamed to lib/pages/section/bloc/section_event.dart
1 -part of 'home_bloc.dart'; 1 +part of 'section_bloc.dart';
2 2
3 @immutable 3 @immutable
4 -abstract class HomeEvent {} 4 +abstract class SectionEvent {}
5 5
6 -class RequestDataEvent extends HomeEvent {} 6 +class RequestDataEvent extends SectionEvent {}
7 7
8 ///获取视频课程内容 8 ///获取视频课程内容
9 -class RequestVideoLessonEvent extends HomeEvent { 9 +class RequestVideoLessonEvent extends SectionEvent {
10 final String courseLessonId; 10 final String courseLessonId;
11 final int courseType; 11 final int courseType;
12 RequestVideoLessonEvent(this.courseLessonId, this.courseType); 12 RequestVideoLessonEvent(this.courseLessonId, this.courseType);
13 } 13 }
14 14
15 ///进入课堂 15 ///进入课堂
16 -class RequestEnterClassEvent extends HomeEvent { 16 +class RequestEnterClassEvent extends SectionEvent {
17 final String courseLessonId; 17 final String courseLessonId;
18 final int courseType; 18 final int courseType;
19 RequestEnterClassEvent(this.courseLessonId,this.courseType); 19 RequestEnterClassEvent(this.courseLessonId,this.courseType);
20 } 20 }
21 21
22 ///退出课堂 22 ///退出课堂
23 -class RequestExitClassEvent extends HomeEvent { 23 +class RequestExitClassEvent extends SectionEvent {
24 final String courseLessonId; 24 final String courseLessonId;
25 final String currentStep; 25 final String currentStep;
26 final String currentTime; 26 final String currentTime;
lib/pages/home/bloc/home_state.dart renamed to lib/pages/section/bloc/section_state.dart
1 -part of 'home_bloc.dart'; 1 +part of 'section_bloc.dart';
2 2
3 @immutable 3 @immutable
4 -abstract class HomeState {} 4 +abstract class SectionState {}
5 5
6 -class HomeInitial extends HomeState {} 6 +class LessonInitial extends SectionState {}
7 7
8 -class HomeDataLoadState extends HomeState {} 8 +class LessonDataLoadState extends SectionState {}
9 9
10 -class RequestVideoLessonState extends HomeState { 10 +class RequestVideoLessonState extends SectionState {
11 final String courseLessonId; 11 final String courseLessonId;
12 final int type; 12 final int type;
13 RequestVideoLessonState(this.courseLessonId,this.type); 13 RequestVideoLessonState(this.courseLessonId,this.type);
14 } 14 }
15 15
16 -class RequestEnterClassState extends HomeState{ 16 +class RequestEnterClassState extends SectionState{
17 final String courseLessonId; 17 final String courseLessonId;
18 final int courseType; 18 final int courseType;
19 RequestEnterClassState(this.courseLessonId,this.courseType); 19 RequestEnterClassState(this.courseLessonId,this.courseType);
lib/pages/home/courese_module_model.dart renamed to lib/pages/section/courese_module_model.dart
@@ -2,9 +2,10 @@ import &#39;package:flutter/material.dart&#39;; @@ -2,9 +2,10 @@ import &#39;package:flutter/material.dart&#39;;
2 2
3 class CourseModuleModel { 3 class CourseModuleModel {
4 Color get color => getCourseColor(); 4 Color get color => getCourseColor();
5 - String get courseModuleTitle => getCourseModuleTitle();  
6 - String get courseModuleLogo => getCoureseImageName();  
7 5
  6 + String get courseModuleTitle => getCourseModuleTitle();
  7 +
  8 + String get courseModuleLogo => getCoureseImageName();
8 9
9 String course; 10 String course;
10 11
@@ -84,4 +85,4 @@ class CourseModuleModel { @@ -84,4 +85,4 @@ class CourseModuleModel {
84 } 85 }
85 return 'red_positive'; 86 return 'red_positive';
86 } 87 }
87 -}  
88 \ No newline at end of file 88 \ No newline at end of file
  89 +}
lib/pages/home/home_page.dart renamed to lib/pages/section/section_page.dart
@@ -3,60 +3,47 @@ import &#39;package:flutter_bloc/flutter_bloc.dart&#39;; @@ -3,60 +3,47 @@ import &#39;package:flutter_bloc/flutter_bloc.dart&#39;;
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'; 4 import 'package:wow_english/common/core/user_util.dart';
5 import 'package:wow_english/common/extension/string_extension.dart'; 5 import 'package:wow_english/common/extension/string_extension.dart';
6 -import 'package:wow_english/models/course_entity.dart';  
7 -import 'package:wow_english/pages/home/widgets/home_bouns_item.dart';  
8 -import 'package:wow_english/pages/home/widgets/home_tab_header_widget.dart';  
9 -import 'package:wow_english/pages/home/widgets/home_vidoe_item.dart'; 6 +import 'package:wow_english/models/course_unit_entity.dart';
  7 +import 'package:wow_english/pages/section/widgets/home_video_item.dart';
  8 +import 'package:wow_english/pages/section/widgets/section_bouns_item.dart';
  9 +import 'package:wow_english/pages/section/widgets/section_header_widget.dart';
10 import 'package:wow_english/route/route.dart'; 10 import 'package:wow_english/route/route.dart';
11 import 'package:wow_english/utils/toast_util.dart'; 11 import 'package:wow_english/utils/toast_util.dart';
12 12
13 -import 'bloc/home_bloc.dart'; 13 +import '../../models/course_section_entity.dart';
  14 +import 'bloc/section_bloc.dart';
14 import 'courese_module_model.dart'; 15 import 'courese_module_model.dart';
15 16
16 -class HomePage extends StatelessWidget {  
17 - const HomePage({super.key, this.moduleId}); 17 +/// 环节列表页
  18 +class SectionPage extends StatelessWidget {
  19 + const SectionPage({super.key, required this.courseUnitEntity, required this.courseUnitDetail});
18 20
19 - /// 模块id  
20 - final String? moduleId; 21 + final CourseUnitEntity courseUnitEntity;
  22 +
  23 + /// unitId
  24 + final CourseUnitDetail courseUnitDetail;
21 25
22 @override 26 @override
23 Widget build(BuildContext context) { 27 Widget build(BuildContext context) {
24 return BlocProvider( 28 return BlocProvider(
25 - create: (context) => HomeBloc(moduleId)..add(RequestDataEvent()),  
26 - child: _HomePageView(context), 29 + create: (context) => SectionBloc(courseUnitEntity, courseUnitDetail)..add(RequestDataEvent()),
  30 + child: _SectionPageView(context),
27 ); 31 );
28 } 32 }
29 } 33 }
30 34
31 -class _HomePageView extends StatelessWidget {  
32 -  
33 - const _HomePageView(this.context); 35 +class _SectionPageView extends StatelessWidget {
  36 + const _SectionPageView(this.context);
34 37
35 final BuildContext context; 38 final BuildContext context;
36 39
37 - void _headerActionEvent(HeaderActionType type) {  
38 - if (type == HeaderActionType.video) {  
39 - pushNamed(AppRouteName.reAfter);  
40 - } else if (type == HeaderActionType.phase) {  
41 - pushNamed(AppRouteName.lesson);  
42 - } else if (type == HeaderActionType.listen) {  
43 - pushNamed(AppRouteName.listen);  
44 - } else if (type == HeaderActionType.shop) {  
45 - pushNamed(AppRouteName.shop);  
46 - } else if (type == HeaderActionType.user) {  
47 - pushNamed(AppRouteName.user);  
48 - } else if (type == HeaderActionType.home) {  
49 - Navigator.pop(context);  
50 - }  
51 - }  
52 -  
53 @override 40 @override
54 Widget build(BuildContext context) { 41 Widget build(BuildContext context) {
55 - final bloc = BlocProvider.of<HomeBloc>(context);  
56 - return BlocListener<HomeBloc, HomeState>( 42 + final bloc = BlocProvider.of<SectionBloc>(context);
  43 + return BlocListener<SectionBloc, SectionState>(
57 listener: (context, state) { 44 listener: (context, state) {
58 if (state is RequestVideoLessonState) { 45 if (state is RequestVideoLessonState) {
59 - final videoUrl = bloc.processEntity?.videos?.videoUrl??''; 46 + final videoUrl = bloc.processEntity?.videos?.videoUrl ?? '';
60 var title = ''; 47 var title = '';
61 if (state.type == 1) { 48 if (state.type == 1) {
62 title = 'song'; 49 title = 'song';
@@ -73,9 +60,13 @@ class _HomePageView extends StatelessWidget { @@ -73,9 +60,13 @@ class _HomePageView extends StatelessWidget {
73 if (videoUrl.isEmpty || !videoUrl.contains('http')) { 60 if (videoUrl.isEmpty || !videoUrl.contains('http')) {
74 return; 61 return;
75 } 62 }
76 - pushNamed(AppRouteName.lookVideo,arguments: {'videoUrl':videoUrl,'title':title,'courseLessonId':state.courseLessonId}).then((value) { 63 + pushNamed(AppRouteName.lookVideo, arguments: {
  64 + 'videoUrl': videoUrl,
  65 + 'title': title,
  66 + 'courseLessonId': state.courseLessonId
  67 + }).then((value) {
77 if (value != null) { 68 if (value != null) {
78 - Map<String,String> dataMap = value as Map<String,String>; 69 + Map<String, String> dataMap = value as Map<String, String>;
79 bloc.add(RequestExitClassEvent( 70 bloc.add(RequestExitClassEvent(
80 dataMap['courseLessonId']!, 71 dataMap['courseLessonId']!,
81 '0', 72 '0',
@@ -87,35 +78,37 @@ class _HomePageView extends StatelessWidget { @@ -87,35 +78,37 @@ class _HomePageView extends StatelessWidget {
87 } 78 }
88 79
89 if (state is RequestEnterClassState) { 80 if (state is RequestEnterClassState) {
90 - if (state.courseType != 3 && state.courseType != 4) {///视频类型 81 + if (state.courseType != 3 && state.courseType != 4) {
  82 + ///视频类型
91 ///获取视频课程内容 83 ///获取视频课程内容
92 - bloc.add(RequestVideoLessonEvent(state.courseLessonId,state.courseType)); 84 + bloc.add(RequestVideoLessonEvent(
  85 + state.courseLessonId, state.courseType));
93 return; 86 return;
94 } 87 }
95 88
96 - if (state.courseType == 4) {//绘本  
97 - pushNamed(AppRouteName.reading, arguments: {'courseLessonId':state.courseLessonId}).then((value) { 89 + if (state.courseType == 4) {
  90 + //绘本
  91 + pushNamed(AppRouteName.reading,
  92 + arguments: {'courseLessonId': state.courseLessonId})
  93 + .then((value) {
98 if (value != null) { 94 if (value != null) {
99 - Map<String,String> dataMap = value as Map<String,String>; 95 + Map<String, String> dataMap = value as Map<String, String>;
100 bloc.add(RequestExitClassEvent( 96 bloc.add(RequestExitClassEvent(
101 - dataMap['courseLessonId']!,  
102 - dataMap['currentStep']!,  
103 - '0'  
104 - )); 97 + dataMap['courseLessonId']!, dataMap['currentStep']!, '0'));
105 } 98 }
106 }); 99 });
107 return; 100 return;
108 } 101 }
109 102
110 - if (state.courseType == 3) {//练习  
111 - pushNamed(AppRouteName.topicPic,arguments: {'courseLessonId':state.courseLessonId}).then((value) { 103 + if (state.courseType == 3) {
  104 + //练习
  105 + pushNamed(AppRouteName.topicPic,
  106 + arguments: {'courseLessonId': state.courseLessonId})
  107 + .then((value) {
112 if (value != null) { 108 if (value != null) {
113 - Map<String,String> dataMap = value as Map<String,String>; 109 + Map<String, String> dataMap = value as Map<String, String>;
114 bloc.add(RequestExitClassEvent( 110 bloc.add(RequestExitClassEvent(
115 - dataMap['courseLessonId']!,  
116 - dataMap['currentStep']!,  
117 - '0'  
118 - )); 111 + dataMap['courseLessonId']!, dataMap['currentStep']!, '0'));
119 } 112 }
120 }); 113 });
121 return; 114 return;
@@ -126,9 +119,9 @@ class _HomePageView extends StatelessWidget { @@ -126,9 +119,9 @@ class _HomePageView extends StatelessWidget {
126 ); 119 );
127 } 120 }
128 121
129 - Widget _homeView() => BlocBuilder<HomeBloc, HomeState>(  
130 - builder: (context, state) {  
131 - final bloc = BlocProvider.of<HomeBloc>(context); 122 + Widget _homeView() =>
  123 + BlocBuilder<SectionBloc, SectionState>(builder: (context, state) {
  124 + final bloc = BlocProvider.of<SectionBloc>(context);
132 return Scaffold( 125 return Scaffold(
133 body: Container( 126 body: Container(
134 color: Colors.white, 127 color: Colors.white,
@@ -136,19 +129,17 @@ class _HomePageView extends StatelessWidget { @@ -136,19 +129,17 @@ class _HomePageView extends StatelessWidget {
136 child: Column( 129 child: Column(
137 mainAxisAlignment: MainAxisAlignment.spaceBetween, 130 mainAxisAlignment: MainAxisAlignment.spaceBetween,
138 children: [ 131 children: [
139 - HomeTabHeaderWidget(  
140 - entity: bloc.modelData,  
141 - actionTap: (HeaderActionType type) {  
142 - _headerActionEvent(type);  
143 - },  
144 - ), 132 + SectionHeaderWidget(
  133 + title: bloc.courseUnitDetail.name,
  134 + courseModuleCode: bloc.courseUnitEntity.courseModuleCode),
145 Expanded( 135 Expanded(
146 child: ListView.builder( 136 child: ListView.builder(
147 - itemCount: bloc.modelData?.totalCourseLesson??0, 137 + itemCount: bloc.courseSectionDatas?.length ?? 0,
148 scrollDirection: Axis.horizontal, 138 scrollDirection: Axis.horizontal,
149 itemBuilder: (BuildContext context, int index) { 139 itemBuilder: (BuildContext context, int index) {
150 - CourseCourseLessons? data = bloc.modelData?.courseLessons?[index];  
151 - if (data?.courseType == 5) { 140 + CourseSectionEntity sectionData =
  141 + bloc.courseSectionDatas![index];
  142 + if (sectionData.courseType == 5) {
152 //彩蛋 143 //彩蛋
153 return GestureDetector( 144 return GestureDetector(
154 onTap: () { 145 onTap: () {
@@ -156,15 +147,17 @@ class _HomePageView extends StatelessWidget { @@ -156,15 +147,17 @@ class _HomePageView extends StatelessWidget {
156 pushNamed(AppRouteName.login); 147 pushNamed(AppRouteName.login);
157 return; 148 return;
158 } 149 }
159 - if (data!.lock!) { 150 + if (sectionData.lock == true) {
160 showToast('当前课程暂未解锁'); 151 showToast('当前课程暂未解锁');
161 return; 152 return;
162 } 153 }
  154 +
163 ///进入课堂 155 ///进入课堂
164 - bloc.add(RequestEnterClassEvent(data.id!,data.courseType!)); 156 + bloc.add(RequestEnterClassEvent(
  157 + sectionData.id.toString(), sectionData.courseType));
165 }, 158 },
166 - child: HomeBoundsItem(  
167 - imageUrl: data?.coverUrl, 159 + child: SectionBoundsItem(
  160 + imageUrl: sectionData.coverUrl,
168 ), 161 ),
169 ); 162 );
170 } else { 163 } else {
@@ -174,16 +167,18 @@ class _HomePageView extends StatelessWidget { @@ -174,16 +167,18 @@ class _HomePageView extends StatelessWidget {
174 pushNamed(AppRouteName.login); 167 pushNamed(AppRouteName.login);
175 return; 168 return;
176 } 169 }
177 - if (data!.lock!) { 170 + if (sectionData.lock == true) {
178 showToast('当前课程暂未解锁'); 171 showToast('当前课程暂未解锁');
179 return; 172 return;
180 } 173 }
  174 +
181 ///进入课堂 175 ///进入课堂
182 - bloc.add(RequestEnterClassEvent(data.id!,data.courseType!)); 176 + bloc.add(RequestEnterClassEvent(
  177 + sectionData.id.toString(), sectionData.courseType));
183 }, 178 },
184 - child: HomeVideoItem(  
185 - entity: bloc.modelData,  
186 - lessons: data, 179 + child: SectionVideoItem(
  180 + unitEntity: bloc.courseUnitEntity,
  181 + lessons: sectionData,
187 ), 182 ),
188 ); 183 );
189 } 184 }
@@ -200,17 +195,26 @@ class _HomePageView extends StatelessWidget { @@ -200,17 +195,26 @@ class _HomePageView extends StatelessWidget {
200 ), 195 ),
201 Container( 196 Container(
202 decoration: BoxDecoration( 197 decoration: BoxDecoration(
203 - color: CourseModuleModel(bloc.modelData?.courseModuleCode??'Phase-1').color, 198 + color: CourseModuleModel(
  199 + bloc.courseUnitEntity.courseModuleCode ??
  200 + 'Phase-1')
  201 + .color,
204 borderRadius: BorderRadius.circular(14.5.r), 202 borderRadius: BorderRadius.circular(14.5.r),
205 ), 203 ),
206 - padding: EdgeInsets.symmetric(vertical: 8.h, horizontal: 24.w), 204 + padding: EdgeInsets.symmetric(
  205 + vertical: 8.h, horizontal: 24.w),
207 child: Text( 206 child: Text(
208 - '${(bloc.modelData?.nowCourseLesson??0)}/${bloc.modelData?.totalCourseLesson??0}',  
209 - style: TextStyle(color: Colors.white, fontSize: 12.sp), 207 + '${(bloc.courseUnitEntity.nowStep ?? 0)}/${bloc.courseUnitEntity.total ?? 0}',
  208 + style: TextStyle(
  209 + color: Colors.white, fontSize: 12.sp),
210 ), 210 ),
211 ), 211 ),
212 Image.asset( 212 Image.asset(
213 - CourseModuleModel(bloc.modelData?.courseModuleCode??'Phase-1').courseModuleLogo.assetPng, 213 + CourseModuleModel(
  214 + bloc.courseUnitEntity.courseModuleCode ??
  215 + 'Phase-1')
  216 + .courseModuleLogo
  217 + .assetPng,
214 height: 47.h, 218 height: 47.h,
215 width: 80.w, 219 width: 80.w,
216 // color: Colors.red, 220 // color: Colors.red,
lib/pages/home/widgets/home_vidoe_item.dart renamed to lib/pages/section/widgets/home_video_item.dart
@@ -2,15 +2,16 @@ import &#39;package:flutter/material.dart&#39;; @@ -2,15 +2,16 @@ import &#39;package:flutter/material.dart&#39;;
2 import 'package:flutter_screenutil/flutter_screenutil.dart'; 2 import 'package:flutter_screenutil/flutter_screenutil.dart';
3 import 'package:wow_english/common/extension/string_extension.dart'; 3 import 'package:wow_english/common/extension/string_extension.dart';
4 import 'package:wow_english/common/widgets/ow_image_widget.dart'; 4 import 'package:wow_english/common/widgets/ow_image_widget.dart';
5 -import 'package:wow_english/models/course_entity.dart';  
6 5
  6 +import '../../../models/course_section_entity.dart';
  7 +import '../../../models/course_unit_entity.dart';
7 import '../courese_module_model.dart'; 8 import '../courese_module_model.dart';
8 9
9 -class HomeVideoItem extends StatelessWidget {  
10 - const HomeVideoItem({super.key, this.lessons, this.entity}); 10 +class SectionVideoItem extends StatelessWidget {
  11 + const SectionVideoItem({super.key, this.lessons, this.unitEntity});
11 12
12 - final CourseEntity? entity;  
13 - final CourseCourseLessons? lessons; 13 + final CourseUnitEntity? unitEntity;
  14 + final CourseSectionEntity? lessons;
14 15
15 @override 16 @override
16 Widget build(BuildContext context) { 17 Widget build(BuildContext context) {
@@ -50,7 +51,7 @@ class HomeVideoItem extends StatelessWidget { @@ -50,7 +51,7 @@ class HomeVideoItem extends StatelessWidget {
50 width: 2, 51 width: 2,
51 color: const Color(0xFF140C10), 52 color: const Color(0xFF140C10),
52 ), 53 ),
53 - color: CourseModuleModel(entity?.courseModuleCode??'Phase-1').color, 54 + color: CourseModuleModel(unitEntity?.courseModuleCode??'Phase-1').color,
54 borderRadius: BorderRadius.circular(6) 55 borderRadius: BorderRadius.circular(6)
55 ), 56 ),
56 padding: EdgeInsets.symmetric(horizontal: 10.w), 57 padding: EdgeInsets.symmetric(horizontal: 10.w),
lib/pages/home/widgets/home_bouns_item.dart renamed to lib/pages/section/widgets/section_bouns_item.dart
@@ -2,8 +2,8 @@ import &#39;package:flutter/cupertino.dart&#39;; @@ -2,8 +2,8 @@ import &#39;package:flutter/cupertino.dart&#39;;
2 import 'package:flutter_screenutil/flutter_screenutil.dart'; 2 import 'package:flutter_screenutil/flutter_screenutil.dart';
3 import 'package:wow_english/common/widgets/ow_image_widget.dart'; 3 import 'package:wow_english/common/widgets/ow_image_widget.dart';
4 4
5 -class HomeBoundsItem extends StatelessWidget {  
6 - const HomeBoundsItem({super.key, this.imageUrl}); 5 +class SectionBoundsItem extends StatelessWidget {
  6 + const SectionBoundsItem({super.key, this.imageUrl});
7 7
8 final String? imageUrl; 8 final String? imageUrl;
9 9
lib/pages/section/widgets/section_header_widget.dart 0 → 100644
  1 +import 'package:flutter/material.dart';
  2 +import 'package:flutter_bloc/flutter_bloc.dart';
  3 +import 'package:flutter_screenutil/flutter_screenutil.dart';
  4 +import 'package:wow_english/common/extension/string_extension.dart';
  5 +import 'package:wow_english/pages/user/bloc/user_bloc.dart';
  6 +
  7 +import '../courese_module_model.dart';
  8 +
  9 +class SectionHeaderWidget extends StatelessWidget {
  10 + const SectionHeaderWidget({super.key, this.title, this.courseModuleCode});
  11 +
  12 + final String? title;
  13 +
  14 + final String? courseModuleCode;
  15 +
  16 + @override
  17 + Widget build(BuildContext context) {
  18 + return BlocBuilder<UserBloc, UserState>(
  19 + builder: (context, state) {
  20 + return Container(
  21 + height: 45,
  22 + width: double.infinity,
  23 + color: CourseModuleModel(courseModuleCode ?? 'Phase-1').color,
  24 + padding: EdgeInsets.symmetric(horizontal: 9.5.w),
  25 + child: Row(
  26 + children: [
  27 + ScreenUtil().bottomBarHeight.horizontalSpace,
  28 + GestureDetector(
  29 + onTap: () {
  30 + Navigator.pop(context);
  31 + },
  32 + child: Container(
  33 + alignment: Alignment.center,
  34 + child: Image.asset(
  35 + 'back_around'.assetPng,
  36 + height: 40.h,
  37 + width: 40.w,
  38 + ),
  39 + ),
  40 + ),
  41 + 20.horizontalSpace,
  42 + Expanded(
  43 + child: Text(
  44 + title ??
  45 + CourseModuleModel(courseModuleCode ?? 'Phase-1')
  46 + .courseModuleTitle,
  47 + textAlign: TextAlign.left,
  48 + style: const TextStyle(color: Colors.white, fontSize: 30.0),
  49 + )),
  50 + ScreenUtil().bottomBarHeight.horizontalSpace,
  51 + ],
  52 + ));
  53 + },
  54 + );
  55 + }
  56 +}
lib/pages/shopping/bloc.dart
@@ -80,10 +80,9 @@ class ShoppingBloc extends Bloc&lt;ShoppingEvent, ShoppingState&gt; { @@ -80,10 +80,9 @@ class ShoppingBloc extends Bloc&lt;ShoppingEvent, ShoppingState&gt; {
80 await fluwx?.registerApi(appId: "wx365e5a79956a450a", 80 await fluwx?.registerApi(appId: "wx365e5a79956a450a",
81 universalLink: "https://app-api.wowenglish.com.cn/app/"); 81 universalLink: "https://app-api.wowenglish.com.cn/app/");
82 wxPayResponseListener = (WeChatResponse response) { 82 wxPayResponseListener = (WeChatResponse response) {
83 - debugPrint("WqfPay wxPayResponseListener $response"); 83 + debugPrint("wxPayResponseListener $response");
84 if (response is WeChatPaymentResponse) { 84 if (response is WeChatPaymentResponse) {
85 if (response.errCode == 0) { 85 if (response.errCode == 0) {
86 - debugPrint("WqfPay wxPayResponseListener response=${response.errCode}");  
87 showToast("支付成功"); 86 showToast("支付成功");
88 // Log.d("emitter isDone=${emitter.isDone}"); 87 // Log.d("emitter isDone=${emitter.isDone}");
89 88
lib/pages/tab/tab_page.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/pages/home/home_page.dart';  
4 -import 'package:wow_english/pages/lessons/lesson_page.dart'; 3 +import 'package:wow_english/pages/module/module_page.dart';
5 4
  5 +import '../unit/view.dart';
6 import 'blocs/tab_bloc.dart'; 6 import 'blocs/tab_bloc.dart';
7 7
8 class TabPage extends StatelessWidget { 8 class TabPage extends StatelessWidget {
9 const TabPage({super.key}); 9 const TabPage({super.key});
10 10
11 final _pages =const <Widget>[ 11 final _pages =const <Widget>[
12 - HomePage(),  
13 - LessonPage() 12 + UnitPage(),
  13 + ModulePage()
14 ]; 14 ];
15 15
16 final _tabIcons = const <Icon>[ 16 final _tabIcons = const <Icon>[
lib/pages/unit/bloc.dart 0 → 100644
  1 +import 'package:bloc/bloc.dart';
  2 +import 'package:wow_english/pages/unit/widget/home_tab_header_widget.dart';
  3 +
  4 +import '../../common/request/dao/lesson_dao.dart';
  5 +import '../../common/request/exception.dart';
  6 +import '../../models/course_module_entity.dart';
  7 +import '../../models/course_unit_entity.dart';
  8 +import '../../route/route.dart';
  9 +import '../../utils/loading.dart';
  10 +import '../../utils/toast_util.dart';
  11 +import 'event.dart';
  12 +import 'state.dart';
  13 +
  14 +class UnitBloc extends Bloc<UnitEvent, UnitState> {
  15 +
  16 + CourseModuleEntity? _moduleEntity;
  17 +
  18 + CourseModuleEntity? get moduleEntity => _moduleEntity;
  19 +
  20 + CourseUnitEntity? _unitData;
  21 +
  22 + CourseUnitEntity? get unitData => _unitData;
  23 +
  24 +
  25 + UnitBloc(CourseModuleEntity? courseEntity) : super(UnitState().init()) {
  26 + on<RequestUnitDataEvent>(_requestData);
  27 + }
  28 +
  29 + void _requestData(RequestUnitDataEvent event, Emitter<UnitState> emitter) async {
  30 + try {
  31 + await loading(() async {
  32 + _unitData = await LessonDao.courseUnit(event.moduleId);
  33 + emitter(UnitDataLoadState());
  34 + });
  35 + } catch (e) {
  36 + if (e is ApiException) {
  37 + showToast(e.message ?? '请求失败,请检查网络连接');
  38 + }
  39 + }
  40 + }
  41 +
  42 + String? getCourseModuleCode() {
  43 + return _moduleEntity?.code ?? _unitData?.courseModuleCode;
  44 + }
  45 +
  46 + void headerActionEvent(HeaderActionType type) {
  47 + if (type == HeaderActionType.video) {
  48 + pushNamed(AppRouteName.reAfter);
  49 + } else if (type == HeaderActionType.phase) {
  50 + pushNamed(AppRouteName.courseModule);
  51 + } else if (type == HeaderActionType.listen) {
  52 + pushNamed(AppRouteName.listen);
  53 + } else if (type == HeaderActionType.shop) {
  54 + pushNamed(AppRouteName.shop);
  55 + } else if (type == HeaderActionType.user) {
  56 + pushNamed(AppRouteName.user);
  57 + }
  58 + }
  59 +}
lib/pages/unit/event.dart 0 → 100644
  1 +abstract class UnitEvent {}
  2 +
  3 +// 获取课程单元数据
  4 +class RequestUnitDataEvent extends UnitEvent {
  5 + final int? moduleId;
  6 +
  7 + RequestUnitDataEvent(this.moduleId);
  8 +}
lib/pages/unit/state.dart 0 → 100644
  1 +class UnitState {
  2 + UnitState init() {
  3 + return UnitState();
  4 + }
  5 +
  6 + UnitState clone() {
  7 + return UnitState();
  8 + }
  9 +}
  10 +
  11 +class UnitDataLoadState extends UnitState {}
0 \ No newline at end of file 12 \ No newline at end of file
lib/pages/unit/view.dart 0 → 100644
  1 +import 'package:flutter/material.dart';
  2 +import 'package:flutter_bloc/flutter_bloc.dart';
  3 +import 'package:flutter_screenutil/flutter_screenutil.dart';
  4 +import 'package:wow_english/pages/unit/state.dart';
  5 +import 'package:wow_english/pages/unit/widget/course_unit_item.dart';
  6 +import 'package:wow_english/pages/unit/widget/home_tab_header_widget.dart';
  7 +import 'package:wow_english/route/route.dart';
  8 +
  9 +import '../../models/course_module_entity.dart';
  10 +import '../../models/course_unit_entity.dart';
  11 +import '../../utils/toast_util.dart';
  12 +import 'bloc.dart';
  13 +import 'event.dart';
  14 +
  15 +// 课程列表页(多unit,参考口语星球的框或分割标志)
  16 +class UnitPage extends StatelessWidget {
  17 + const UnitPage({super.key, this.courseModuleEntity});
  18 +
  19 + /// 模块
  20 + final CourseModuleEntity? courseModuleEntity;
  21 +
  22 + @override
  23 + Widget build(BuildContext context) {
  24 + return BlocProvider(
  25 + create: (BuildContext context) => UnitBloc(courseModuleEntity)
  26 + ..add(RequestUnitDataEvent(courseModuleEntity?.id)),
  27 + child: Builder(builder: (context) => _buildPage(context)),
  28 + );
  29 + }
  30 +
  31 + Widget _buildPage(BuildContext context) {
  32 + return BlocBuilder<UnitBloc, UnitState>(builder: (context, state) {
  33 + final bloc = BlocProvider.of<UnitBloc>(context);
  34 + return Scaffold(
  35 + body: Container(
  36 + color: Colors.white,
  37 + child: Center(
  38 + child: Column(
  39 + mainAxisAlignment: MainAxisAlignment.spaceBetween,
  40 + children: [
  41 + HomeTabHeaderWidget(
  42 + courseModuleCode: bloc.getCourseModuleCode(),
  43 + actionTap: (HeaderActionType type) {
  44 + bloc.headerActionEvent(type);
  45 + },
  46 + ),
  47 + Expanded(
  48 + child: Container(
  49 + margin: EdgeInsets.symmetric(horizontal: 12.w),
  50 + child: ListView.builder(
  51 + itemCount:
  52 + bloc.unitData?.courseUnitVOList?.length ?? 0,
  53 + scrollDirection: Axis.horizontal,
  54 + itemBuilder: (BuildContext context, int index) {
  55 + CourseUnitDetail? data =
  56 + bloc.unitData?.courseUnitVOList?[index];
  57 + return GestureDetector(
  58 + onTap: () {
  59 + if (data.lock == true) {
  60 + showToast('当前unit暂未解锁');
  61 + return;
  62 + }
  63 +
  64 + pushNamed(AppRouteName.courseSection,
  65 + arguments: {
  66 + 'courseUnitEntity': bloc.unitData,
  67 + 'courseUnitDetail': data
  68 + });
  69 + },
  70 + child: CourseUnitItem(
  71 + unitEntity: bloc.unitData!,
  72 + unitLesson: data!,
  73 + ),
  74 + );
  75 + })),
  76 + ),
  77 + SafeArea(
  78 + child: Column(
  79 + children: [
  80 + 6.verticalSpace,
  81 + ],
  82 + ),
  83 + )
  84 + ],
  85 + ),
  86 + ),
  87 + ),
  88 + );
  89 + });
  90 + }
  91 +}
lib/pages/unit/widget/course_unit_item.dart 0 → 100644
  1 +import 'package:flutter/material.dart';
  2 +import 'package:flutter_screenutil/flutter_screenutil.dart';
  3 +import 'package:wow_english/common/extension/string_extension.dart';
  4 +import 'package:wow_english/common/widgets/ow_image_widget.dart';
  5 +
  6 +import '../../../models/course_unit_entity.dart';
  7 +
  8 +class CourseUnitItem extends StatelessWidget {
  9 + const CourseUnitItem(
  10 + {super.key, required this.unitEntity, required this.unitLesson});
  11 +
  12 + final CourseUnitEntity unitEntity;
  13 + final CourseUnitDetail unitLesson;
  14 +
  15 + @override
  16 + Widget build(BuildContext context) {
  17 + return Padding(
  18 + padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 24.h),
  19 + child: Container(
  20 + width: 165.w,
  21 + padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 24.h),
  22 + decoration: BoxDecoration(
  23 + image: DecorationImage(
  24 + image: AssetImage('gendubeij'.assetPng), fit: BoxFit.fill),
  25 + ),
  26 + child: Column(
  27 + mainAxisAlignment: MainAxisAlignment.spaceBetween,
  28 + children: [
  29 + Expanded(
  30 + child: Container(
  31 + decoration: BoxDecoration(
  32 + border: Border.all(
  33 + width: 2,
  34 + color: const Color(0xFF140C10),
  35 + ),
  36 + borderRadius: BorderRadius.circular(6)),
  37 + child: OwImageWidget(
  38 + name: unitLesson.coverUrl ?? '',
  39 + fit: BoxFit.fitHeight,
  40 + ),
  41 + )),
  42 + 20.verticalSpace,
  43 + SizedBox(
  44 + height: 40.h,
  45 + child: Text(
  46 + unitLesson.name ?? '',
  47 + maxLines: 2,
  48 + overflow: TextOverflow.ellipsis,
  49 + style:
  50 + TextStyle(fontSize: 11.sp, color: const Color(0xFF140C10)),
  51 + ),
  52 + )
  53 + ],
  54 + ),
  55 + ),
  56 + );
  57 + }
  58 +}
lib/pages/home/widgets/home_tab_header_widget.dart renamed to lib/pages/unit/widget/home_tab_header_widget.dart
@@ -5,8 +5,7 @@ import &#39;package:wow_english/common/extension/string_extension.dart&#39;; @@ -5,8 +5,7 @@ import &#39;package:wow_english/common/extension/string_extension.dart&#39;;
5 import 'package:wow_english/pages/user/bloc/user_bloc.dart'; 5 import 'package:wow_english/pages/user/bloc/user_bloc.dart';
6 6
7 import '../../../common/core/app_config_helper.dart'; 7 import '../../../common/core/app_config_helper.dart';
8 -import '../../../models/course_entity.dart';  
9 -import '../courese_module_model.dart'; 8 +import '../../section/courese_module_model.dart';
10 9
11 enum HeaderActionType { 10 enum HeaderActionType {
12 //视频跟读 11 //视频跟读
@@ -19,14 +18,13 @@ enum HeaderActionType { @@ -19,14 +18,13 @@ enum HeaderActionType {
19 shop, 18 shop,
20 //个人信息 19 //个人信息
21 user, 20 user,
22 - //返回到(模块选择)首页  
23 - home,  
24 } 21 }
25 22
26 class HomeTabHeaderWidget extends StatelessWidget { 23 class HomeTabHeaderWidget extends StatelessWidget {
27 - const HomeTabHeaderWidget({super.key, this.entity, this.actionTap}); 24 + const HomeTabHeaderWidget({super.key, this.courseModuleCode, this.actionTap});
  25 +
  26 + final String? courseModuleCode;
28 27
29 - final CourseEntity? entity;  
30 final Function(HeaderActionType type)? actionTap; 28 final Function(HeaderActionType type)? actionTap;
31 29
32 @override 30 @override
@@ -37,16 +35,14 @@ class HomeTabHeaderWidget extends StatelessWidget { @@ -37,16 +35,14 @@ class HomeTabHeaderWidget extends StatelessWidget {
37 height: 45, 35 height: 45,
38 width: double.infinity, 36 width: double.infinity,
39 color: 37 color:
40 - CourseModuleModel(entity?.courseModuleCode ?? 'Phase-1').color, 38 + CourseModuleModel(courseModuleCode ?? 'Phase-1').color,
41 padding: EdgeInsets.symmetric(horizontal: 9.5.w), 39 padding: EdgeInsets.symmetric(horizontal: 9.5.w),
42 child: Row( 40 child: Row(
43 children: [ 41 children: [
44 ScreenUtil().bottomBarHeight.horizontalSpace, 42 ScreenUtil().bottomBarHeight.horizontalSpace,
45 GestureDetector( 43 GestureDetector(
46 onTap: () { 44 onTap: () {
47 - if (actionTap != null) {  
48 - actionTap!(HeaderActionType.home);  
49 - } 45 + Navigator.pop(context);
50 }, 46 },
51 child: Container( 47 child: Container(
52 alignment: Alignment.center, 48 alignment: Alignment.center,
@@ -96,7 +92,7 @@ class HomeTabHeaderWidget extends StatelessWidget { @@ -96,7 +92,7 @@ class HomeTabHeaderWidget extends StatelessWidget {
96 20.horizontalSpace, 92 20.horizontalSpace,
97 Expanded( 93 Expanded(
98 child: Text( 94 child: Text(
99 - CourseModuleModel(entity?.courseModuleCode ?? 'Phase-1') 95 + CourseModuleModel(courseModuleCode ?? 'Phase-1')
100 .courseModuleTitle, 96 .courseModuleTitle,
101 textAlign: TextAlign.left, 97 textAlign: TextAlign.left,
102 style: const TextStyle(color: Colors.white, fontSize: 30.0), 98 style: const TextStyle(color: Colors.white, fontSize: 30.0),
@@ -122,8 +118,8 @@ class HomeTabHeaderWidget extends StatelessWidget { @@ -122,8 +118,8 @@ class HomeTabHeaderWidget extends StatelessWidget {
122 } 118 }
123 }, 119 },
124 icon: Image.asset('listen'.assetPng)), 120 icon: Image.asset('listen'.assetPng)),
125 - Visibility(  
126 - visible: !AppConfigHelper.shouldHidePay(), 121 + Offstage(
  122 + offstage: AppConfigHelper.shouldHidePay(),
127 child: IconButton( 123 child: IconButton(
128 onPressed: () { 124 onPressed: () {
129 if (actionTap != null) { 125 if (actionTap != null) {
lib/pages/user/user_page.dart
@@ -4,6 +4,7 @@ import &#39;package:flutter/services.dart&#39;; @@ -4,6 +4,7 @@ import &#39;package:flutter/services.dart&#39;;
4 import 'package:flutter/material.dart'; 4 import 'package:flutter/material.dart';
5 import 'package:flutter_bloc/flutter_bloc.dart'; 5 import 'package:flutter_bloc/flutter_bloc.dart';
6 import 'package:flutter_screenutil/flutter_screenutil.dart'; 6 import 'package:flutter_screenutil/flutter_screenutil.dart';
  7 +import 'package:wow_english/common/core/app_config_helper.dart';
7 import 'package:wow_english/common/core/app_consts.dart'; 8 import 'package:wow_english/common/core/app_consts.dart';
8 import 'package:wow_english/common/core/assets_const.dart'; 9 import 'package:wow_english/common/core/assets_const.dart';
9 import 'package:wow_english/common/core/user_util.dart'; 10 import 'package:wow_english/common/core/user_util.dart';
@@ -163,9 +164,8 @@ class _UserView extends StatelessWidget { @@ -163,9 +164,8 @@ class _UserView extends StatelessWidget {
163 ), 164 ),
164 ), 165 ),
165 12.verticalSpace, 166 12.verticalSpace,
166 - // todo 为了过审,把测试账号兑换功能下掉  
167 Offstage( 167 Offstage(
168 - offstage: UserUtil.getUser()?.phoneNum == '17730280759', 168 + offstage: AppConfigHelper.shouldHidePay(),
169 child: OutlinedButton( 169 child: OutlinedButton(
170 onPressed: () => pushNamed(AppRouteName.exLesson), 170 onPressed: () => pushNamed(AppRouteName.exLesson),
171 style: normalButtonStyle, 171 style: normalButtonStyle,
@@ -175,7 +175,7 @@ class _UserView extends StatelessWidget { @@ -175,7 +175,7 @@ class _UserView extends StatelessWidget {
175 )), 175 )),
176 ), 176 ),
177 Offstage( 177 Offstage(
178 - offstage: UserUtil.getUser()?.phoneNum == '17730280759', 178 + offstage: AppConfigHelper.shouldHidePay(),
179 child: 12.verticalSpace, 179 child: 12.verticalSpace,
180 ), 180 ),
181 OutlinedButton( 181 OutlinedButton(
lib/route/route.dart
@@ -3,22 +3,21 @@ import &#39;package:flutter/material.dart&#39;; @@ -3,22 +3,21 @@ import &#39;package:flutter/material.dart&#39;;
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/generated/json/base/json_convert_content.dart';
  6 +import 'package:wow_english/models/course_unit_entity.dart';
6 import 'package:wow_english/models/product_entity.dart'; 7 import 'package:wow_english/models/product_entity.dart';
7 import 'package:wow_english/pages/games/view.dart'; 8 import 'package:wow_english/pages/games/view.dart';
8 -import 'package:wow_english/pages/home/home_page.dart';  
9 -import 'package:wow_english/pages/lessons/lesson_page.dart'; 9 +import 'package:wow_english/pages/home/view.dart';
10 import 'package:wow_english/pages/listen/listen_page.dart'; 10 import 'package:wow_english/pages/listen/listen_page.dart';
11 import 'package:wow_english/pages/login/forgetpwd/forget_password_home_page.dart'; 11 import 'package:wow_english/pages/login/forgetpwd/forget_password_home_page.dart';
12 import 'package:wow_english/pages/login/loginpage/login_page.dart'; 12 import 'package:wow_english/pages/login/loginpage/login_page.dart';
13 import 'package:wow_english/pages/login/setpwd/set_pwd_page.dart'; 13 import 'package:wow_english/pages/login/setpwd/set_pwd_page.dart';
14 -import 'package:wow_english/pages/moduleSelect/view.dart'; 14 +import 'package:wow_english/pages/module/module_page.dart';
15 import 'package:wow_english/pages/practice/topic_picture_page.dart'; 15 import 'package:wow_english/pages/practice/topic_picture_page.dart';
16 import 'package:wow_english/pages/repeatafter/repeat_after_page.dart'; 16 import 'package:wow_english/pages/repeatafter/repeat_after_page.dart';
17 import 'package:wow_english/pages/repeataftercontent/repeat_after_content_page.dart'; 17 import 'package:wow_english/pages/repeataftercontent/repeat_after_content_page.dart';
18 import 'package:wow_english/pages/shop/exchane/exchange_lesson_page.dart'; 18 import 'package:wow_english/pages/shop/exchane/exchange_lesson_page.dart';
19 import 'package:wow_english/pages/shop/exchangelist/exchange_lesson_list_page.dart'; 19 import 'package:wow_english/pages/shop/exchangelist/exchange_lesson_list_page.dart';
20 import 'package:wow_english/pages/shop/home/shop_home_page.dart'; 20 import 'package:wow_english/pages/shop/home/shop_home_page.dart';
21 -import 'package:wow_english/pages/tab/tab_page.dart';  
22 import 'package:wow_english/pages/user/information/user_information_page.dart'; 21 import 'package:wow_english/pages/user/information/user_information_page.dart';
23 import 'package:wow_english/pages/user/modify/modify_user_avatar_page.dart'; 22 import 'package:wow_english/pages/user/modify/modify_user_avatar_page.dart';
24 import 'package:wow_english/pages/user/modify/modify_user_information_page.dart'; 23 import 'package:wow_english/pages/user/modify/modify_user_information_page.dart';
@@ -26,24 +25,28 @@ import &#39;package:wow_english/pages/user/setting/setting_page.dart&#39;; @@ -26,24 +25,28 @@ import &#39;package:wow_english/pages/user/setting/setting_page.dart&#39;;
26 import 'package:wow_english/pages/user/user_page.dart'; 25 import 'package:wow_english/pages/user/user_page.dart';
27 import 'package:wow_english/pages/video/lookvideo/look_video_page.dart'; 26 import 'package:wow_english/pages/video/lookvideo/look_video_page.dart';
28 27
  28 +import '../models/course_module_entity.dart';
29 import '../pages/reading/reading_page.dart'; 29 import '../pages/reading/reading_page.dart';
  30 +import '../pages/section/section_page.dart';
30 import '../pages/shopping/view.dart'; 31 import '../pages/shopping/view.dart';
  32 +import '../pages/tab/tab_page.dart';
  33 +import '../pages/unit/view.dart';
31 import '../pages/user/setting/delete_account_page.dart'; 34 import '../pages/user/setting/delete_account_page.dart';
32 import '../pages/user/setting/reback_page.dart'; 35 import '../pages/user/setting/reback_page.dart';
33 -import '../utils/log_util.dart';  
34 36
35 class AppRouteName { 37 class AppRouteName {
36 static const String splash = 'splash'; 38 static const String splash = 'splash';
37 static const String login = 'login'; 39 static const String login = 'login';
38 - static const String moduleSelect = 'moduleSelect';  
39 - static const String games = 'games';  
40 static const String home = 'home'; 40 static const String home = 'home';
  41 + static const String games = 'games';
41 static const String fogPwd = 'fogPwd'; 42 static const String fogPwd = 'fogPwd';
42 43
43 /// 设置密码,修改密码;不要自己调用,使用[SetPassWordPage.push]方法,隐藏这种实现 44 /// 设置密码,修改密码;不要自己调用,使用[SetPassWordPage.push]方法,隐藏这种实现
44 //static const String setPwd = 'setPwd'; 45 //static const String setPwd = 'setPwd';
45 static const String webView = 'webView'; 46 static const String webView = 'webView';
46 - static const String lesson = 'lesson'; 47 + static const String courseModule = 'courseModules';
  48 + static const String courseUnit = 'courseUnits';
  49 + static const String courseSection = 'courseSections';
47 static const String listen = 'listen'; 50 static const String listen = 'listen';
48 static const String shop = 'shop'; 51 static const String shop = 'shop';
49 static const String exLesson = 'exLesson'; 52 static const String exLesson = 'exLesson';
@@ -55,6 +58,7 @@ class AppRouteName { @@ -55,6 +58,7 @@ class AppRouteName {
55 58
56 /// 用户详细信息页 59 /// 用户详细信息页
57 static const String userInformation = 'userInformation'; 60 static const String userInformation = 'userInformation';
  61 +
58 /// 修改用户头像 62 /// 修改用户头像
59 static const String userAvatar = 'userAvatar'; 63 static const String userAvatar = 'userAvatar';
60 64
@@ -62,15 +66,19 @@ class AppRouteName { @@ -62,15 +66,19 @@ class AppRouteName {
62 //static const String userModifyInformation = 'userModifyInformation'; 66 //static const String userModifyInformation = 'userModifyInformation';
63 ///看视频 67 ///看视频
64 static const String lookVideo = 'lookVideo'; 68 static const String lookVideo = 'lookVideo';
  69 +
65 ///绘本 70 ///绘本
66 static const String reading = 'reading'; 71 static const String reading = 'reading';
  72 +
67 ///视频跟读详情 73 ///视频跟读详情
68 static const String readAfterContent = 'readAfterContent'; 74 static const String readAfterContent = 'readAfterContent';
69 75
70 ///设置 76 ///设置
71 static const String setting = 'setting'; 77 static const String setting = 'setting';
  78 +
72 ///注销账号 79 ///注销账号
73 static const String deleteAccount = 'deleteAccount'; 80 static const String deleteAccount = 'deleteAccount';
  81 +
74 ///帮助与反馈 82 ///帮助与反馈
75 static const String reBack = 'reBack'; 83 static const String reBack = 'reBack';
76 84
@@ -93,25 +101,42 @@ class AppRouter { @@ -93,25 +101,42 @@ class AppRouter {
93 transitionsBuilder: (_, __, ___, child) => child); 101 transitionsBuilder: (_, __, ___, child) => child);
94 case AppRouteName.login: 102 case AppRouteName.login:
95 // 是否默认密码登录,修改密码后跳登录页,优先密码登录体验好点 103 // 是否默认密码登录,修改密码后跳登录页,优先密码登录体验好点
96 - final bool showPasswordPage = (settings.arguments as Map?)?.getOrNull('showPasswordPage') as bool? ?? false;  
97 - return CupertinoPageRoute(builder: (_) => LoginPage(preferencesPasswordLogin: showPasswordPage));  
98 - case AppRouteName.moduleSelect:  
99 - return CupertinoPageRoute(builder: (_) => const ModuleSelectPage()); 104 + final bool showPasswordPage = (settings.arguments as Map?)
  105 + ?.getOrNull('showPasswordPage') as bool? ??
  106 + false;
  107 + return CupertinoPageRoute(
  108 + builder: (_) =>
  109 + LoginPage(preferencesPasswordLogin: showPasswordPage));
  110 + case AppRouteName.home:
  111 + return CupertinoPageRoute(builder: (_) => const HomePage());
100 case AppRouteName.games: 112 case AppRouteName.games:
101 return CupertinoPageRoute(builder: (_) => const GamesPage()); 113 return CupertinoPageRoute(builder: (_) => const GamesPage());
102 - case AppRouteName.home:  
103 - var moduleId = ''; 114 + case AppRouteName.fogPwd:
  115 + return CupertinoPageRoute(
  116 + builder: (_) => const ForgetPasswordHomePage());
  117 + case AppRouteName.courseModule:
  118 + return CupertinoPageRoute(builder: (_) => const ModulePage());
  119 + case AppRouteName.courseUnit:
  120 + CourseModuleEntity courseModuleEntity = CourseModuleEntity();
104 if (settings.arguments != null) { 121 if (settings.arguments != null) {
105 - moduleId = (settings.arguments as Map)['moduleId'] as String; 122 + courseModuleEntity = (settings.arguments as Map)
  123 + .getOrNull('courseModuleEntity') as CourseModuleEntity;
106 } 124 }
107 return CupertinoPageRoute( 125 return CupertinoPageRoute(
108 - builder: (_) => HomePage(  
109 - moduleId: moduleId,  
110 - ));  
111 - case AppRouteName.fogPwd:  
112 - return CupertinoPageRoute(builder: (_) => const ForgetPasswordHomePage());  
113 - case AppRouteName.lesson:  
114 - return CupertinoPageRoute(builder: (_) => const LessonPage()); 126 + builder: (_) => UnitPage(courseModuleEntity: courseModuleEntity));
  127 + case AppRouteName.courseSection:
  128 + CourseUnitEntity courseUnitEntity = CourseUnitEntity();
  129 + CourseUnitDetail courseUnitDetail = CourseUnitDetail();
  130 + if (settings.arguments != null) {
  131 + courseUnitEntity = (settings.arguments as Map)
  132 + .getOrNull('courseUnitEntity') as CourseUnitEntity;
  133 + courseUnitDetail = (settings.arguments as Map)
  134 + .getOrNull('courseUnitDetail') as CourseUnitDetail;
  135 + }
  136 + return CupertinoPageRoute(
  137 + builder: (_) => SectionPage(
  138 + courseUnitEntity: courseUnitEntity,
  139 + courseUnitDetail: courseUnitDetail));
115 case AppRouteName.listen: 140 case AppRouteName.listen:
116 return CupertinoPageRoute(builder: (_) => const ListenPage()); 141 return CupertinoPageRoute(builder: (_) => const ListenPage());
117 case AppRouteName.shop: 142 case AppRouteName.shop:
@@ -121,11 +146,13 @@ class AppRouter { @@ -121,11 +146,13 @@ class AppRouter {
121 if (settings.arguments != null && settings.arguments is ProductEntity) { 146 if (settings.arguments != null && settings.arguments is ProductEntity) {
122 productEntity = settings.arguments as ProductEntity; 147 productEntity = settings.arguments as ProductEntity;
123 } 148 }
124 - return CupertinoPageRoute(builder: (_) => ShoppingPage(productEntity: productEntity)); 149 + return CupertinoPageRoute(
  150 + builder: (_) => ShoppingPage(productEntity: productEntity));
125 case AppRouteName.exLesson: 151 case AppRouteName.exLesson:
126 return CupertinoPageRoute(builder: (_) => const ExchangeLessonPage()); 152 return CupertinoPageRoute(builder: (_) => const ExchangeLessonPage());
127 case AppRouteName.exList: 153 case AppRouteName.exList:
128 - return CupertinoPageRoute(builder: (_) => const ExchangeLessonListPage()); 154 + return CupertinoPageRoute(
  155 + builder: (_) => const ExchangeLessonListPage());
129 case AppRouteName.reAfter: 156 case AppRouteName.reAfter:
130 return CupertinoPageRoute(builder: (_) => const RepeatAfterPage()); 157 return CupertinoPageRoute(builder: (_) => const RepeatAfterPage());
131 case AppRouteName.user: 158 case AppRouteName.user:
@@ -153,19 +180,22 @@ class AppRouter { @@ -153,19 +180,22 @@ class AppRouter {
153 case AppRouteName.topicPic: 180 case AppRouteName.topicPic:
154 var courseLessonId = ''; 181 var courseLessonId = '';
155 if (settings.arguments != null) { 182 if (settings.arguments != null) {
156 - courseLessonId = (settings.arguments as Map)['courseLessonId'] as String; 183 + courseLessonId =
  184 + (settings.arguments as Map)['courseLessonId'] as String;
157 } 185 }
158 - return CupertinoPageRoute(builder: (_) => TopicPicturePage(courseLessonId: courseLessonId)); 186 + return CupertinoPageRoute(
  187 + builder: (_) => TopicPicturePage(courseLessonId: courseLessonId));
159 case AppRouteName.lookVideo: 188 case AppRouteName.lookVideo:
160 final videoUrl = (settings.arguments as Map)['videoUrl'] as String; 189 final videoUrl = (settings.arguments as Map)['videoUrl'] as String;
161 final title = (settings.arguments as Map)['title'] as String?; 190 final title = (settings.arguments as Map)['title'] as String?;
162 - final courseLessonId = (settings.arguments as Map)['courseLessonId'] as String?; 191 + final courseLessonId =
  192 + (settings.arguments as Map)['courseLessonId'] as String?;
163 return CupertinoPageRoute( 193 return CupertinoPageRoute(
164 builder: (_) => LookVideoPage( 194 builder: (_) => LookVideoPage(
165 - videoUrl: videoUrl,  
166 - typeTitle: title,  
167 - courseLessonId: courseLessonId,  
168 - )); 195 + videoUrl: videoUrl,
  196 + typeTitle: title,
  197 + courseLessonId: courseLessonId,
  198 + ));
169 /*case AppRouteName.setPwd: 199 /*case AppRouteName.setPwd:
170 case AppRouteName.setPwd: 200 case AppRouteName.setPwd:
171 phoneNum: phoneNum, 201 phoneNum: phoneNum,
@@ -174,7 +204,8 @@ class AppRouter { @@ -174,7 +204,8 @@ class AppRouter {
174 ));*/ 204 ));*/
175 case AppRouteName.webView: 205 case AppRouteName.webView:
176 final urlStr = (settings.arguments as Map)['urlStr'] as String; 206 final urlStr = (settings.arguments as Map)['urlStr'] as String;
177 - final webViewTitle = (settings.arguments as Map)['webViewTitle'] as String; 207 + final webViewTitle =
  208 + (settings.arguments as Map)['webViewTitle'] as String;
178 return CupertinoPageRoute( 209 return CupertinoPageRoute(
179 builder: (_) => WowWebViewPage( 210 builder: (_) => WowWebViewPage(
180 urlStr: urlStr, 211 urlStr: urlStr,
@@ -183,13 +214,16 @@ class AppRouter { @@ -183,13 +214,16 @@ class AppRouter {
183 case AppRouteName.readAfterContent: 214 case AppRouteName.readAfterContent:
184 var videoFollowReadId = ''; 215 var videoFollowReadId = '';
185 if (settings.arguments != null) { 216 if (settings.arguments != null) {
186 - videoFollowReadId = (settings.arguments as Map)['videoFollowReadId'] as String; 217 + videoFollowReadId =
  218 + (settings.arguments as Map)['videoFollowReadId'] as String;
187 } 219 }
188 - return CupertinoPageRoute(builder: (_) => RepeatAfterContentPage(videoFollowReadId: videoFollowReadId)); 220 + return CupertinoPageRoute(
  221 + builder: (_) =>
  222 + RepeatAfterContentPage(videoFollowReadId: videoFollowReadId));
189 case AppRouteName.setting: 223 case AppRouteName.setting:
190 - return CupertinoPageRoute(builder: (_) => const SettingPage()); 224 + return CupertinoPageRoute(builder: (_) => const SettingPage());
191 case AppRouteName.deleteAccount: 225 case AppRouteName.deleteAccount:
192 - return CupertinoPageRoute(builder: (_) => const DeleteAccountPage()); 226 + return CupertinoPageRoute(builder: (_) => const DeleteAccountPage());
193 case AppRouteName.reBack: 227 case AppRouteName.reBack:
194 return CupertinoPageRoute(builder: (_) => const ReBackPage()); 228 return CupertinoPageRoute(builder: (_) => const ReBackPage());
195 case AppRouteName.tab: 229 case AppRouteName.tab:
@@ -202,26 +236,34 @@ class AppRouter { @@ -202,26 +236,34 @@ class AppRouter {
202 case AppRouteName.reading: 236 case AppRouteName.reading:
203 var courseLessonId = ''; 237 var courseLessonId = '';
204 if (settings.arguments != null) { 238 if (settings.arguments != null) {
205 - courseLessonId = (settings.arguments as Map)['courseLessonId'] as String; 239 + courseLessonId =
  240 + (settings.arguments as Map)['courseLessonId'] as String;
206 } 241 }
207 - return CupertinoPageRoute(builder: (_) => ReadingPage(courseLessonId: courseLessonId)); 242 + return CupertinoPageRoute(
  243 + builder: (_) => ReadingPage(courseLessonId: courseLessonId));
208 default: 244 default:
209 return CupertinoPageRoute( 245 return CupertinoPageRoute(
210 - builder: (_) => Scaffold(body: Center(child: Text('No route defined for ${settings.name}')))); 246 + builder: (_) => Scaffold(
  247 + body: Center(
  248 + child: Text('No route defined for ${settings.name}'))));
211 } 249 }
212 } 250 }
213 } 251 }
214 252
215 Future pushNamed(String routeName, {Object? arguments}) { 253 Future pushNamed(String routeName, {Object? arguments}) {
216 - return Navigator.of(AppRouter.context).pushNamed(routeName, arguments: arguments).then((value) { 254 + return Navigator.of(AppRouter.context)
  255 + .pushNamed(routeName, arguments: arguments)
  256 + .then((value) {
217 return value; 257 return value;
218 }); 258 });
219 } 259 }
220 260
221 -Future pushNamedAndRemoveUntil(String routeName, RoutePredicate predicate, {Object? arguments}) {  
222 - return Navigator.of(AppRouter.context).pushNamedAndRemoveUntil(routeName, predicate, arguments: arguments); 261 +Future pushNamedAndRemoveUntil(String routeName, RoutePredicate predicate,
  262 + {Object? arguments}) {
  263 + return Navigator.of(AppRouter.context)
  264 + .pushNamedAndRemoveUntil(routeName, predicate, arguments: arguments);
223 } 265 }
224 266
225 void popPage({dynamic data}) { 267 void popPage({dynamic data}) {
226 - Navigator.of(AppRouter.context).pop(data); 268 + Navigator.of(AppRouter.context).pop(data);
227 } 269 }
pubspec.yaml
@@ -16,7 +16,7 @@ publish_to: &#39;none&#39; # Remove this line if you wish to publish to pub.dev @@ -16,7 +16,7 @@ publish_to: &#39;none&#39; # Remove this line if you wish to publish to pub.dev
16 # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html 16 # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
17 # In Windows, build-name is used as the major, minor, and patch parts 17 # In Windows, build-name is used as the major, minor, and patch parts
18 # of the product and file versions while build-number is used as the build suffix. 18 # of the product and file versions while build-number is used as the build suffix.
19 -version: 1.0.3+2 19 +version: 1.0.3+3
20 20
21 environment: 21 environment:
22 sdk: '>=3.0.0 <4.0.0' 22 sdk: '>=3.0.0 <4.0.0'