Commit 2187c85f138169f7b863bea0c5aff8b5d6cdf7b2

Authored by 吴启风
1 parent 2c079546

feat:课程结构调整

Showing 34 changed files with 576 additions and 354 deletions
lib/app/splash_page.dart
... ... @@ -77,7 +77,7 @@ class _TransitionViewState extends State<TransitionView> {
77 77 }*/
78 78 bool isAggreementAccepted = AppConfigHelper.getAgreementAccepted();
79 79 if (isAggreementAccepted) {
80   - pushNamedAndRemoveUntil(AppRouteName.moduleSelect, (route) => false);
  80 + pushNamedAndRemoveUntil(AppRouteName.home, (route) => false);
81 81 } else {
82 82 showDialog(
83 83 context: context,
... ... @@ -91,7 +91,7 @@ class _TransitionViewState extends State<TransitionView> {
91 91 leftTap: () {
92 92 AppConfigHelper.saveAgreementAccepted(true);
93 93 pushNamedAndRemoveUntil(
94   - AppRouteName.moduleSelect, (route) => false);
  94 + AppRouteName.home, (route) => false);
95 95 },
96 96 rightTap: () {
97 97 // 退出应用
... ...
lib/common/request/apis.dart
... ... @@ -53,6 +53,9 @@ class Apis {
53 53 // 接口地址:https://app.apifox.com/link/project/2684751/apis/api-89897662
54 54 static const String courseLesson = 'home/courseLesson';
55 55  
  56 + // 课程环节列表
  57 + static const String courseSection = 'course/courseLesson';
  58 +
56 59 /// 磨耳朵
57 60 /// GET
58 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 1 import 'package:wow_english/common/request/request_client.dart';
2 2 import 'package:wow_english/models/course_entity.dart';
  3 +import 'package:wow_english/models/course_section_entity.dart';
3 4  
4 5 import '../../../models/course_module_entity.dart';
5 6 import '../../../models/course_unit_entity.dart';
6 7  
7   -class HomeDao {
  8 +class LessonDao {
8 9 ///获取课程模块(列表)信息
9 10 static Future<List<CourseModuleEntity?>?> courseModule() async {
10 11 var data = await requestClient.get<List<CourseModuleEntity>>(Apis.courseModule);
... ... @@ -12,20 +13,30 @@ class HomeDao {
12 13 }
13 14  
14 15 ///课程单元列表
15   - static Future<CourseUnitEntity?> courseUnit(int moduleId) async {
  16 + static Future<CourseUnitEntity?> courseUnit(int? moduleId) async {
16 17 Map<String, dynamic> mapData = {};
17   - mapData['moduleId'] = moduleId;
  18 + if (moduleId != null) {
  19 + mapData['moduleId'] = moduleId;
  20 + }
18 21 var data = await requestClient.get<CourseUnitEntity>(Apis.courseUnit, queryParameters: mapData);
19 22 return data;
20 23 }
21 24  
22 25 ///课程列表
23   - static Future<CourseEntity?> courseLesson({int? moduleId}) async {
  26 + static Future<CourseEntity?> courseLesson({int? courseUnitId}) async {
24 27 Map<String, dynamic> mapData = {};
25   - if (moduleId != null) {
26   - mapData['moduleId'] = moduleId;
  28 + if (courseUnitId != null) {
  29 + mapData['courseUnitId'] = courseUnitId;
27 30 }
28 31 var data = await requestClient.get<CourseEntity>(Apis.courseLesson, queryParameters: mapData);
29 32 return data;
30 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 + }
31 42 }
... ...
lib/generated/json/base/json_convert_content.dart
... ... @@ -10,6 +10,7 @@ import &#39;package:wow_english/models/app_version_entity.dart&#39;;
10 10 import 'package:wow_english/models/course_entity.dart';
11 11 import 'package:wow_english/models/course_module_entity.dart';
12 12 import 'package:wow_english/models/course_process_entity.dart';
  13 +import 'package:wow_english/models/course_section_entity.dart';
13 14 import 'package:wow_english/models/course_unit_entity.dart';
14 15 import 'package:wow_english/models/follow_read_entity.dart';
15 16 import 'package:wow_english/models/listen_entity.dart';
... ... @@ -198,6 +199,10 @@ class JsonConvert {
198 199 return data.map<CourseProcessVideos>((Map<String, dynamic> e) =>
199 200 CourseProcessVideos.fromJson(e)).toList() as M;
200 201 }
  202 + if (<CourseSectionEntity>[] is M) {
  203 + return data.map<CourseSectionEntity>((Map<String, dynamic> e) =>
  204 + CourseSectionEntity.fromJson(e)).toList() as M;
  205 + }
201 206 if (<CourseUnitEntity>[] is M) {
202 207 return data.map<CourseUnitEntity>((Map<String, dynamic> e) =>
203 208 CourseUnitEntity.fromJson(e)).toList() as M;
... ... @@ -261,6 +266,7 @@ class JsonConvertClassCollection {
261 266 (CourseProcessTopicsTopicAnswerList)
262 267 .toString(): CourseProcessTopicsTopicAnswerList.fromJson,
263 268 (CourseProcessVideos).toString(): CourseProcessVideos.fromJson,
  269 + (CourseSectionEntity).toString(): CourseSectionEntity.fromJson,
264 270 (CourseUnitEntity).toString(): CourseUnitEntity.fromJson,
265 271 (CourseUnitDetail).toString(): CourseUnitDetail.fromJson,
266 272 (FollowReadEntity).toString(): FollowReadEntity.fromJson,
... ...
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 90 \ 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 5  
6 6 @JsonSerializable()
7 7 class CourseModuleEntity {
8   - late int id;
  8 + int? id;
9 9 String? code;
10 10 int? courseModuleThemeId;
11 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 30 \ No newline at end of file
... ...
lib/pages/moduleSelect/bloc.dart renamed to lib/pages/home/bloc.dart
1 1 import 'package:bloc/bloc.dart';
2 2 import 'package:flutter/cupertino.dart';
3 3 import 'package:flutter/foundation.dart';
4   -import 'package:wow_english/models/app_config_entity.dart';
5 4  
6 5 import '../../common/core/app_config_helper.dart';
7 6 import '../../common/request/dao/system_dao.dart';
... ... @@ -10,17 +9,17 @@ import &#39;../../utils/log_util.dart&#39;;
10 9 import 'event.dart';
11 10 import 'state.dart';
12 11  
13   -class ModuleSelectBloc extends Bloc<ModuleSelectEvent, ModuleSelectState> {
14   - ModuleSelectBloc() : super(ModuleSelectState().init()) {
  12 +class ModuleSelectBloc extends Bloc<HomeEvent, HomeState> {
  13 + ModuleSelectBloc() : super(HomeState().init()) {
15 14 on<InitEvent>(_init);
16 15 }
17 16  
18   - void _init(InitEvent event, Emitter<ModuleSelectState> emit) async {
  17 + void _init(InitEvent event, Emitter<HomeState> emit) async {
19 18 await _checkUpdate(emit);
20 19 debugPrint('WQF ModuleSelectBloc _init');
21 20 }
22 21  
23   - Future<void> _checkUpdate(Emitter<ModuleSelectState> emit) async {
  22 + Future<void> _checkUpdate(Emitter<HomeState> emit) async {
24 23 if (AppConfigHelper.checkedUpdate) {
25 24 return;
26 25 }
... ...
lib/pages/home/event.dart 0 → 100644
  1 +abstract class HomeEvent {}
  2 +
  3 +class InitEvent extends HomeEvent {}
0 4 \ No newline at end of file
... ...
lib/pages/moduleSelect/state.dart renamed to lib/pages/home/state.dart
1 1 import 'package:wow_english/models/app_version_entity.dart';
2 2  
3   -class ModuleSelectState {
4   - ModuleSelectState init() {
5   - return ModuleSelectState();
  3 +class HomeState {
  4 + HomeState init() {
  5 + return HomeState();
6 6 }
7 7  
8   - ModuleSelectState clone() {
9   - return ModuleSelectState();
  8 + HomeState clone() {
  9 + return HomeState();
10 10 }
11 11 }
12 12  
13   -class UpdateDialogState extends ModuleSelectState {
  13 +class UpdateDialogState extends HomeState {
14 14  
15 15 final AppVersionEntity appVersionEntity;
16 16  
... ...
lib/pages/moduleSelect/view.dart renamed to lib/pages/home/view.dart
... ... @@ -9,8 +9,8 @@ import &#39;package:url_launcher/url_launcher.dart&#39;;
9 9 import 'package:wow_english/common/core/app_config_helper.dart';
10 10 import 'package:wow_english/common/extension/string_extension.dart';
11 11 import 'package:wow_english/models/app_version_entity.dart';
12   -import 'package:wow_english/pages/moduleSelect/state.dart';
13   -import 'package:wow_english/pages/moduleSelect/widgets/BaseHomeHeaderWidget.dart';
  12 +import 'package:wow_english/pages/home/state.dart';
  13 +import 'package:wow_english/pages/home/widgets/BaseHomeHeaderWidget.dart';
14 14 import 'package:wow_english/pages/user/bloc/user_bloc.dart';
15 15  
16 16 import '../../common/core/user_util.dart';
... ... @@ -21,8 +21,8 @@ import &#39;event.dart&#39;;
21 21 import 'package:flutter_screenutil/flutter_screenutil.dart';
22 22 import 'package:wow_english/route/route.dart';
23 23  
24   -class ModuleSelectPage extends StatelessWidget {
25   - const ModuleSelectPage({super.key});
  24 +class HomePage extends StatelessWidget {
  25 + const HomePage({super.key});
26 26  
27 27 @override
28 28 Widget build(BuildContext context) {
... ... @@ -42,7 +42,7 @@ class _HomePageView extends StatelessWidget {
42 42 BlocListener<UserBloc, UserState>(listener: (context, state) {
43 43 debugPrint('WQF ModuleSelectPage BlocListener state: $state');
44 44 }),
45   - BlocListener<ModuleSelectBloc, ModuleSelectState>(
  45 + BlocListener<ModuleSelectBloc, HomeState>(
46 46 listener: (context, state) {
47 47 if (state is UpdateDialogState) {
48 48 _showUpdateDialog(context, state.forceUpdate, state.appVersionEntity);
... ... @@ -53,7 +53,7 @@ class _HomePageView extends StatelessWidget {
53 53 }
54 54  
55 55 Widget _homeView() =>
56   - BlocBuilder<ModuleSelectBloc, ModuleSelectState>(
  56 + BlocBuilder<ModuleSelectBloc, HomeState>(
57 57 builder: (context, state) {
58 58 return Scaffold(
59 59 body: Container(
... ... @@ -69,7 +69,7 @@ class _HomePageView extends StatelessWidget {
69 69 child: GestureDetector(
70 70 onTap: () {
71 71 if (UserUtil.isLogined()) {
72   - pushNamed(AppRouteName.home);
  72 + pushNamed(AppRouteName.courseUnit);
73 73 } else {
74 74 pushNamed(AppRouteName.login);
75 75 }
... ...
lib/pages/moduleSelect/widgets/BaseHomeHeaderWidget.dart renamed to lib/pages/home/widgets/BaseHomeHeaderWidget.dart
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 34 if (state is LoginResultChangeState) {
35 35 // 调试用
36 36 // Navigator.of(context).pushNamed(AppRouteName.home);
37   - pushNamedAndRemoveUntil(AppRouteName.moduleSelect, (route) => false);
  37 + pushNamedAndRemoveUntil(AppRouteName.home, (route) => false);
38 38 }
39 39 },
40 40 child: _buildLoginViewWidget(),
... ...
lib/pages/lessons/bloc/lesson_bloc.dart renamed to lib/pages/module/bloc/module_bloc.dart
1 1 import 'package:flutter/cupertino.dart';
2 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 4 import 'package:wow_english/common/request/exception.dart';
5 5 import 'package:wow_english/models/course_module_entity.dart';
6 6 import 'package:wow_english/utils/loading.dart';
7 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 13 final int pageIndex;
14 14  
15 15 final PageController pageController;
... ... @@ -22,22 +22,22 @@ class LessonBloc extends Bloc&lt;LessonEvent, LessonState&gt; {
22 22  
23 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 26 _currentPageIndex = pageIndex;
27 27 on<PageViewChangeIndexEvent>(_pageIndexChange);
28 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 32 _currentPageIndex = event.index;
33 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 37 try {
38 38 await loading(() async {
39   - _listData = await HomeDao.courseModule() ?? [];
40   - emitter(LessonDataLoadState());
  39 + _listData = await LessonDao.courseModule() ?? [];
  40 + emitter(ModuleDataLoadState());
41 41 });
42 42 } catch (e) {
43 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 3 @immutable
4   -abstract class LessonEvent {}
  4 +abstract class ModuleEvent {}
5 5  
6   -class PageViewChangeIndexEvent extends LessonEvent {
  6 +class PageViewChangeIndexEvent extends ModuleEvent {
7 7 final int index;
8 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 6 import 'package:wow_english/models/course_module_entity.dart';
7 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 16 final int? starPageIndex;
16 17  
17 18 @override
18 19 Widget build(BuildContext context) {
19 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 24 )..add(RequestDataEvent()),
27 25 child: _LessonPageView(),
28 26 );
... ... @@ -30,27 +28,25 @@ class LessonPage extends StatelessWidget {
30 28 }
31 29  
32 30 class _LessonPageView extends StatelessWidget {
33   -
34 31 final double _cardHeight = 240.h;
35 32  
36 33 final double _scale = 0.8;
37 34  
38 35 @override
39 36 Widget build(BuildContext context) {
40   - return BlocListener<LessonBloc,LessonState>(
41   - listener: (context, state){},
  37 + return BlocListener<ModuleBloc, ModuleState>(
  38 + listener: (context, state) {},
42 39 child: Scaffold(
43 40 appBar: WEAppBar(
44 41 leading: IconButton(
45   - onPressed: (){
46   - popPage();
  42 + onPressed: () {
  43 + popPage();
47 44 },
48 45 icon: Image.asset(
49 46 'back'.assetPng,
50 47 height: 43,
51 48 width: 43,
52   - )
53   - ),
  49 + )),
54 50 // actions: <Widget>[
55 51 // IconButton(
56 52 // icon: Image.asset('shop'.assetPng),
... ... @@ -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 68 return Center(
73 69 child: SafeArea(
74 70 child: Column(
... ... @@ -81,8 +77,7 @@ class _LessonPageView extends StatelessWidget {
81 77 onPageChanged: (int index) {
82 78 bloc.add(PageViewChangeIndexEvent(index));
83 79 },
84   - itemBuilder: (context,index) => _itemTransCard(index)
85   - ),
  80 + itemBuilder: (context, index) => _itemTransCard(index)),
86 81 ),
87 82 32.verticalSpace,
88 83 SizedBox(
... ... @@ -91,7 +86,7 @@ class _LessonPageView extends StatelessWidget {
91 86 child: ListView.builder(
92 87 itemCount: bloc.listData.length,
93 88 scrollDirection: Axis.horizontal,
94   - itemBuilder: (BuildContext context,int index){
  89 + itemBuilder: (BuildContext context, int index) {
95 90 return Container(
96 91 height: 32.h,
97 92 width: 66.w,
... ... @@ -101,13 +96,19 @@ class _LessonPageView extends StatelessWidget {
101 96 if (index == bloc.currentPageIndex) {
102 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 106 child: Container(
108   - height: bloc.currentPageIndex == index ? 32:20,
  107 + height: bloc.currentPageIndex == index ? 32 : 20,
109 108 decoration: BoxDecoration(
110   - color: bloc.currentPageIndex == index ? Colors.red:Colors.white,
  109 + color: bloc.currentPageIndex == index
  110 + ? Colors.red
  111 + : Colors.white,
111 112 borderRadius: BorderRadius.circular(5.r),
112 113 border: Border.all(
113 114 width: 0.5,
... ... @@ -116,10 +117,11 @@ class _LessonPageView extends StatelessWidget {
116 117 ),
117 118 alignment: Alignment.center,
118 119 child: Text(
119   - (index+1).toString(),
  120 + (index + 1).toString(),
120 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 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   - pushNamed(AppRouteName.unit, arguments: {'courseModuleEntity':model});
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 4 import 'package:wow_english/common/widgets/ow_image_widget.dart';
5 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 12 final bool isSelected;
13 13 final CourseModuleEntity? model;
... ...
lib/pages/moduleSelect/event.dart deleted
1   -abstract class ModuleSelectEvent {}
2   -
3   -class InitEvent extends ModuleSelectEvent {}
4 0 \ No newline at end of file
lib/pages/home/bloc/home_bloc.dart renamed to lib/pages/section/bloc/section_bloc.dart
1 1 import 'package:flutter/cupertino.dart';
2 2 import 'package:flutter/foundation.dart';
3 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 5 import 'package:wow_english/common/request/exception.dart';
6   -import 'package:wow_english/models/course_entity.dart';
7 6 import 'package:wow_english/common/request/dao/listen_dao.dart';
8 7 import 'package:wow_english/models/course_process_entity.dart';
9 8 import 'package:wow_english/utils/loading.dart';
10 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 int? 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 31 CourseProcessEntity? _processEntity;
23 32  
24 33 CourseProcessEntity? get processEntity => _processEntity;
25 34  
26   - HomeBloc(this.moduleId) : super(HomeInitial()) {
  35 + SectionBloc(this._courseUnitEntity, this._courseUnitDetail) : super(LessonInitial()) {
27 36 on<RequestDataEvent>(_requestData);
28 37 on<RequestExitClassEvent>(_requestExitClass);
29 38 on<RequestEnterClassEvent>(_requestEnterClass);
30 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 43 try {
35 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 48 } catch (e) {
40 49 if (e is ApiException) {
... ... @@ -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 56 try {
48 57 await loading(() async {
49 58 _processEntity = await ListenDao.process(event.courseLessonId);
... ... @@ -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 70 try {
62 71 await loading(() async {
63 72 await ListenDao.enterClass(event.courseLessonId);
... ... @@ -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 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 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 10 final String courseLessonId;
11 11 final int courseType;
12 12 RequestVideoLessonEvent(this.courseLessonId, this.courseType);
13 13 }
14 14  
15 15 ///进入课堂
16   -class RequestEnterClassEvent extends HomeEvent {
  16 +class RequestEnterClassEvent extends SectionEvent {
17 17 final String courseLessonId;
18 18 final int courseType;
19 19 RequestEnterClassEvent(this.courseLessonId,this.courseType);
20 20 }
21 21  
22 22 ///退出课堂
23   -class RequestExitClassEvent extends HomeEvent {
  23 +class RequestExitClassEvent extends SectionEvent {
24 24 final String courseLessonId;
25 25 final String currentStep;
26 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 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 11 final String courseLessonId;
12 12 final int type;
13 13 RequestVideoLessonState(this.courseLessonId,this.type);
14 14 }
15 15  
16   -class RequestEnterClassState extends HomeState{
  16 +class RequestEnterClassState extends SectionState{
17 17 final String courseLessonId;
18 18 final int courseType;
19 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 2  
3 3 class CourseModuleModel {
4 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 10 String course;
10 11  
... ... @@ -84,4 +85,4 @@ class CourseModuleModel {
84 85 }
85 86 return 'red_positive';
86 87 }
87   -}
88 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 3 import 'package:flutter_screenutil/flutter_screenutil.dart';
4 4 import 'package:wow_english/common/core/user_util.dart';
5 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_video_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 10 import 'package:wow_english/route/route.dart';
11 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 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 int? moduleId;
  21 + final CourseUnitEntity courseUnitEntity;
  22 +
  23 + /// unitId
  24 + final CourseUnitDetail courseUnitDetail;
21 25  
22 26 @override
23 27 Widget build(BuildContext context) {
24 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 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 40 @override
54 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 44 listener: (context, state) {
58 45 if (state is RequestVideoLessonState) {
59   - final videoUrl = bloc.processEntity?.videos?.videoUrl??'';
  46 + final videoUrl = bloc.processEntity?.videos?.videoUrl ?? '';
60 47 var title = '';
61 48 if (state.type == 1) {
62 49 title = 'song';
... ... @@ -73,9 +60,13 @@ class _HomePageView extends StatelessWidget {
73 60 if (videoUrl.isEmpty || !videoUrl.contains('http')) {
74 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 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 70 bloc.add(RequestExitClassEvent(
80 71 dataMap['courseLessonId']!,
81 72 '0',
... ... @@ -87,35 +78,37 @@ class _HomePageView extends StatelessWidget {
87 78 }
88 79  
89 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 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 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 96 bloc.add(RequestExitClassEvent(
101   - dataMap['courseLessonId']!,
102   - dataMap['currentStep']!,
103   - '0'
104   - ));
  97 + dataMap['courseLessonId']!, dataMap['currentStep']!, '0'));
105 98 }
106 99 });
107 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 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 110 bloc.add(RequestExitClassEvent(
115   - dataMap['courseLessonId']!,
116   - dataMap['currentStep']!,
117   - '0'
118   - ));
  111 + dataMap['courseLessonId']!, dataMap['currentStep']!, '0'));
119 112 }
120 113 });
121 114 return;
... ... @@ -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 125 return Scaffold(
133 126 body: Container(
134 127 color: Colors.white,
... ... @@ -136,19 +129,17 @@ class _HomePageView extends StatelessWidget {
136 129 child: Column(
137 130 mainAxisAlignment: MainAxisAlignment.spaceBetween,
138 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 135 Expanded(
146 136 child: ListView.builder(
147   - itemCount: bloc.modelData?.totalCourseLesson??0,
  137 + itemCount: bloc.courseSectionDatas?.length ?? 0,
148 138 scrollDirection: Axis.horizontal,
149 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 144 return GestureDetector(
154 145 onTap: () {
... ... @@ -156,15 +147,17 @@ class _HomePageView extends StatelessWidget {
156 147 pushNamed(AppRouteName.login);
157 148 return;
158 149 }
159   - if (data!.lock!) {
  150 + if (sectionData.lock == true) {
160 151 showToast('当前课程暂未解锁');
161 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 163 } else {
... ... @@ -174,16 +167,18 @@ class _HomePageView extends StatelessWidget {
174 167 pushNamed(AppRouteName.login);
175 168 return;
176 169 }
177   - if (data!.lock!) {
  170 + if (sectionData.lock == true) {
178 171 showToast('当前课程暂未解锁');
179 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 195 ),
201 196 Container(
202 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 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 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 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 218 height: 47.h,
215 219 width: 80.w,
216 220 // color: Colors.red,
... ...
lib/pages/home/widgets/home_video_item.dart renamed to lib/pages/section/widgets/home_video_item.dart
... ... @@ -2,15 +2,16 @@ import &#39;package:flutter/material.dart&#39;;
2 2 import 'package:flutter_screenutil/flutter_screenutil.dart';
3 3 import 'package:wow_english/common/extension/string_extension.dart';
4 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 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 16 @override
16 17 Widget build(BuildContext context) {
... ... @@ -50,7 +51,7 @@ class HomeVideoItem extends StatelessWidget {
50 51 width: 2,
51 52 color: const Color(0xFF140C10),
52 53 ),
53   - color: CourseModuleModel(entity?.courseModuleCode??'Phase-1').color,
  54 + color: CourseModuleModel(unitEntity?.courseModuleCode??'Phase-1').color,
54 55 borderRadius: BorderRadius.circular(6)
55 56 ),
56 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 2 import 'package:flutter_screenutil/flutter_screenutil.dart';
3 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 8 final String? imageUrl;
9 9  
... ...
lib/pages/unit/widget/course_unit_header_widget.dart renamed to lib/pages/section/widgets/section_header_widget.dart
... ... @@ -4,13 +4,14 @@ import &#39;package:flutter_screenutil/flutter_screenutil.dart&#39;;
4 4 import 'package:wow_english/common/extension/string_extension.dart';
5 5 import 'package:wow_english/pages/user/bloc/user_bloc.dart';
6 6  
7   -import '../../../models/course_module_entity.dart';
8   -import '../../home/courese_module_model.dart';
  7 +import '../courese_module_model.dart';
9 8  
10   -class CourseUnitHeaderWidget extends StatelessWidget {
11   - const CourseUnitHeaderWidget({super.key, this.entity});
  9 +class SectionHeaderWidget extends StatelessWidget {
  10 + const SectionHeaderWidget({super.key, this.title, this.courseModuleCode});
12 11  
13   - final CourseModuleEntity? entity;
  12 + final String? title;
  13 +
  14 + final String? courseModuleCode;
14 15  
15 16 @override
16 17 Widget build(BuildContext context) {
... ... @@ -19,8 +20,7 @@ class CourseUnitHeaderWidget extends StatelessWidget {
19 20 return Container(
20 21 height: 45,
21 22 width: double.infinity,
22   - color:
23   - CourseModuleModel(entity?.code ?? 'Phase-1').color,
  23 + color: CourseModuleModel(courseModuleCode ?? 'Phase-1').color,
24 24 padding: EdgeInsets.symmetric(horizontal: 9.5.w),
25 25 child: Row(
26 26 children: [
... ... @@ -40,9 +40,10 @@ class CourseUnitHeaderWidget extends StatelessWidget {
40 40 ),
41 41 20.horizontalSpace,
42 42 Expanded(
43   - child: Text(entity?.name ??
44   - CourseModuleModel(entity?.code ?? 'Phase-1')
45   - .courseModuleTitle,
  43 + child: Text(
  44 + title ??
  45 + CourseModuleModel(courseModuleCode ?? 'Phase-1')
  46 + .courseModuleTitle,
46 47 textAlign: TextAlign.left,
47 48 style: const TextStyle(color: Colors.white, fontSize: 30.0),
48 49 )),
... ...
lib/pages/tab/tab_page.dart
1 1 import 'package:flutter/material.dart';
2 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 6 import 'blocs/tab_bloc.dart';
7 7  
8 8 class TabPage extends StatelessWidget {
9 9 const TabPage({super.key});
10 10  
11 11 final _pages =const <Widget>[
12   - HomePage(),
13   - LessonPage()
  12 + UnitPage(),
  13 + ModulePage()
14 14 ];
15 15  
16 16 final _tabIcons = const <Icon>[
... ...
lib/pages/unit/bloc.dart
1 1 import 'package:bloc/bloc.dart';
  2 +import 'package:wow_english/pages/unit/widget/home_tab_header_widget.dart';
2 3  
3   -import '../../common/request/dao/home_dao.dart';
  4 +import '../../common/request/dao/lesson_dao.dart';
4 5 import '../../common/request/exception.dart';
  6 +import '../../models/course_module_entity.dart';
5 7 import '../../models/course_unit_entity.dart';
  8 +import '../../route/route.dart';
6 9 import '../../utils/loading.dart';
7 10 import '../../utils/toast_util.dart';
8 11 import 'event.dart';
... ... @@ -10,19 +13,23 @@ import &#39;state.dart&#39;;
10 13  
11 14 class UnitBloc extends Bloc<UnitEvent, UnitState> {
12 15  
13   - CourseUnitEntity? _modelData;
  16 + CourseModuleEntity? _moduleEntity;
14 17  
15   - CourseUnitEntity? get modelData => _modelData;
  18 + CourseModuleEntity? get moduleEntity => _moduleEntity;
16 19  
  20 + CourseUnitEntity? _unitData;
17 21  
18   - UnitBloc() : super(UnitState().init()) {
  22 + CourseUnitEntity? get unitData => _unitData;
  23 +
  24 +
  25 + UnitBloc(CourseModuleEntity? courseEntity) : super(UnitState().init()) {
19 26 on<RequestUnitDataEvent>(_requestData);
20 27 }
21 28  
22 29 void _requestData(RequestUnitDataEvent event, Emitter<UnitState> emitter) async {
23 30 try {
24 31 await loading(() async {
25   - _modelData = await HomeDao.courseUnit(event.moduleId);
  32 + _unitData = await LessonDao.courseUnit(event.moduleId);
26 33 emitter(UnitDataLoadState());
27 34 });
28 35 } catch (e) {
... ... @@ -31,4 +38,22 @@ class UnitBloc extends Bloc&lt;UnitEvent, UnitState&gt; {
31 38 }
32 39 }
33 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 + }
34 59 }
... ...
lib/pages/unit/event.dart
... ... @@ -2,7 +2,7 @@ abstract class UnitEvent {}
2 2  
3 3 // 获取课程单元数据
4 4 class RequestUnitDataEvent extends UnitEvent {
5   - final int moduleId;
  5 + final int? moduleId;
6 6  
7 7 RequestUnitDataEvent(this.moduleId);
8 8 }
... ...
lib/pages/unit/view.dart
... ... @@ -2,8 +2,8 @@ import &#39;package:flutter/material.dart&#39;;
2 2 import 'package:flutter_bloc/flutter_bloc.dart';
3 3 import 'package:flutter_screenutil/flutter_screenutil.dart';
4 4 import 'package:wow_english/pages/unit/state.dart';
5   -import 'package:wow_english/pages/unit/widget/course_unit_header_widget.dart';
6 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 7 import 'package:wow_english/route/route.dart';
8 8  
9 9 import '../../models/course_module_entity.dart';
... ... @@ -12,17 +12,18 @@ import &#39;../../utils/toast_util.dart&#39;;
12 12 import 'bloc.dart';
13 13 import 'event.dart';
14 14  
  15 +// 课程列表页(多unit,参考口语星球的框或分割标志)
15 16 class UnitPage extends StatelessWidget {
16   - const UnitPage({super.key, required this.courseEntity});
  17 + const UnitPage({super.key, this.courseModuleEntity});
17 18  
18 19 /// 模块
19   - final CourseModuleEntity courseEntity;
  20 + final CourseModuleEntity? courseModuleEntity;
20 21  
21 22 @override
22 23 Widget build(BuildContext context) {
23 24 return BlocProvider(
24   - create: (BuildContext context) =>
25   - UnitBloc()..add(RequestUnitDataEvent(courseEntity.id)),
  25 + create: (BuildContext context) => UnitBloc(courseModuleEntity)
  26 + ..add(RequestUnitDataEvent(courseModuleEntity?.id)),
26 27 child: Builder(builder: (context) => _buildPage(context)),
27 28 );
28 29 }
... ... @@ -37,36 +38,42 @@ class UnitPage extends StatelessWidget {
37 38 child: Column(
38 39 mainAxisAlignment: MainAxisAlignment.spaceBetween,
39 40 children: [
40   - CourseUnitHeaderWidget(entity: courseEntity),
  41 + HomeTabHeaderWidget(
  42 + courseModuleCode: bloc.getCourseModuleCode(),
  43 + actionTap: (HeaderActionType type) {
  44 + bloc.headerActionEvent(type);
  45 + },
  46 + ),
41 47 Expanded(
42   - child: ListView.builder(
43   - itemCount:
44   - bloc.modelData?.courseUnitVOList?.length ?? 0,
45   - scrollDirection: Axis.horizontal,
46   - itemBuilder: (BuildContext context, int index) {
47   - CourseUnitDetail? data =
48   - bloc.modelData?.courseUnitVOList?[index];
49   - return GestureDetector(
50   - onTap: () {
51   - if (data.lock == true) {
52   - showToast('当前unit暂未解锁');
53   - return;
54   - }
  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 + }
55 63  
56   - ///进入课堂
57   - pushNamedAndRemoveUntil(
58   - AppRouteName.home, (route) => route.isFirst,
59   - arguments: {
60   - 'moduleId': data.courseModuleId,
61   - 'unitId': data.id
62   - });
63   - },
64   - child: CourseUnitItem(
65   - unitEntity: bloc.modelData!,
66   - unitLesson: data!,
67   - ),
68   - );
69   - })),
  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 + ),
70 77 SafeArea(
71 78 child: Column(
72 79 children: [
... ...
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 5 import 'package:wow_english/pages/user/bloc/user_bloc.dart';
6 6  
7 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 10 enum HeaderActionType {
12 11 //视频跟读
... ... @@ -19,14 +18,13 @@ enum HeaderActionType {
19 18 shop,
20 19 //个人信息
21 20 user,
22   - //返回到(模块选择)首页
23   - home,
24 21 }
25 22  
26 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 28 final Function(HeaderActionType type)? actionTap;
31 29  
32 30 @override
... ... @@ -37,16 +35,14 @@ class HomeTabHeaderWidget extends StatelessWidget {
37 35 height: 45,
38 36 width: double.infinity,
39 37 color:
40   - CourseModuleModel(entity?.courseModuleCode ?? 'Phase-1').color,
  38 + CourseModuleModel(courseModuleCode ?? 'Phase-1').color,
41 39 padding: EdgeInsets.symmetric(horizontal: 9.5.w),
42 40 child: Row(
43 41 children: [
44 42 ScreenUtil().bottomBarHeight.horizontalSpace,
45 43 GestureDetector(
46 44 onTap: () {
47   - if (actionTap != null) {
48   - actionTap!(HeaderActionType.home);
49   - }
  45 + Navigator.pop(context);
50 46 },
51 47 child: Container(
52 48 alignment: Alignment.center,
... ... @@ -96,7 +92,7 @@ class HomeTabHeaderWidget extends StatelessWidget {
96 92 20.horizontalSpace,
97 93 Expanded(
98 94 child: Text(
99   - CourseModuleModel(entity?.courseModuleCode ?? 'Phase-1')
  95 + CourseModuleModel(courseModuleCode ?? 'Phase-1')
100 96 .courseModuleTitle,
101 97 textAlign: TextAlign.left,
102 98 style: const TextStyle(color: Colors.white, fontSize: 30.0),
... ...
lib/route/route.dart
... ... @@ -3,22 +3,21 @@ import &#39;package:flutter/material.dart&#39;;
3 3 import 'package:wow_english/app/splash_page.dart';
4 4 import 'package:wow_english/common/pages/wow_web_page.dart';
5 5 import 'package:wow_english/generated/json/base/json_convert_content.dart';
  6 +import 'package:wow_english/models/course_unit_entity.dart';
6 7 import 'package:wow_english/models/product_entity.dart';
7 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 10 import 'package:wow_english/pages/listen/listen_page.dart';
11 11 import 'package:wow_english/pages/login/forgetpwd/forget_password_home_page.dart';
12 12 import 'package:wow_english/pages/login/loginpage/login_page.dart';
13 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 15 import 'package:wow_english/pages/practice/topic_picture_page.dart';
16 16 import 'package:wow_english/pages/repeatafter/repeat_after_page.dart';
17 17 import 'package:wow_english/pages/repeataftercontent/repeat_after_content_page.dart';
18 18 import 'package:wow_english/pages/shop/exchane/exchange_lesson_page.dart';
19 19 import 'package:wow_english/pages/shop/exchangelist/exchange_lesson_list_page.dart';
20 20 import 'package:wow_english/pages/shop/home/shop_home_page.dart';
21   -import 'package:wow_english/pages/tab/tab_page.dart';
22 21 import 'package:wow_english/pages/user/information/user_information_page.dart';
23 22 import 'package:wow_english/pages/user/modify/modify_user_avatar_page.dart';
24 23 import 'package:wow_english/pages/user/modify/modify_user_information_page.dart';
... ... @@ -28,7 +27,9 @@ import &#39;package:wow_english/pages/video/lookvideo/look_video_page.dart&#39;;
28 27  
29 28 import '../models/course_module_entity.dart';
30 29 import '../pages/reading/reading_page.dart';
  30 +import '../pages/section/section_page.dart';
31 31 import '../pages/shopping/view.dart';
  32 +import '../pages/tab/tab_page.dart';
32 33 import '../pages/unit/view.dart';
33 34 import '../pages/user/setting/delete_account_page.dart';
34 35 import '../pages/user/setting/reback_page.dart';
... ... @@ -36,16 +37,16 @@ import &#39;../pages/user/setting/reback_page.dart&#39;;
36 37 class AppRouteName {
37 38 static const String splash = 'splash';
38 39 static const String login = 'login';
39   - static const String moduleSelect = 'moduleSelect';
40   - static const String games = 'games';
41 40 static const String home = 'home';
  41 + static const String games = 'games';
42 42 static const String fogPwd = 'fogPwd';
43 43  
44 44 /// 设置密码,修改密码;不要自己调用,使用[SetPassWordPage.push]方法,隐藏这种实现
45 45 //static const String setPwd = 'setPwd';
46 46 static const String webView = 'webView';
47   - static const String unit = 'courseUnits';
48   - static const String lesson = 'courseModules';
  47 + static const String courseModule = 'courseModules';
  48 + static const String courseUnit = 'courseUnits';
  49 + static const String courseSection = 'courseSections';
49 50 static const String listen = 'listen';
50 51 static const String shop = 'shop';
51 52 static const String exLesson = 'exLesson';
... ... @@ -57,6 +58,7 @@ class AppRouteName {
57 58  
58 59 /// 用户详细信息页
59 60 static const String userInformation = 'userInformation';
  61 +
60 62 /// 修改用户头像
61 63 static const String userAvatar = 'userAvatar';
62 64  
... ... @@ -64,15 +66,19 @@ class AppRouteName {
64 66 //static const String userModifyInformation = 'userModifyInformation';
65 67 ///看视频
66 68 static const String lookVideo = 'lookVideo';
  69 +
67 70 ///绘本
68 71 static const String reading = 'reading';
  72 +
69 73 ///视频跟读详情
70 74 static const String readAfterContent = 'readAfterContent';
71 75  
72 76 ///设置
73 77 static const String setting = 'setting';
  78 +
74 79 ///注销账号
75 80 static const String deleteAccount = 'deleteAccount';
  81 +
76 82 ///帮助与反馈
77 83 static const String reBack = 'reBack';
78 84  
... ... @@ -95,31 +101,42 @@ class AppRouter {
95 101 transitionsBuilder: (_, __, ___, child) => child);
96 102 case AppRouteName.login:
97 103 // 是否默认密码登录,修改密码后跳登录页,优先密码登录体验好点
98   - final bool showPasswordPage = (settings.arguments as Map?)?.getOrNull('showPasswordPage') as bool? ?? false;
99   - return CupertinoPageRoute(builder: (_) => LoginPage(preferencesPasswordLogin: showPasswordPage));
100   - case AppRouteName.moduleSelect:
101   - 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());
102 112 case AppRouteName.games:
103 113 return CupertinoPageRoute(builder: (_) => const GamesPage());
104   - case AppRouteName.home:
105   - int? 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();
106 121 if (settings.arguments != null) {
107   - moduleId = (settings.arguments as Map).getOrNull('moduleId') as int?;
  122 + courseModuleEntity = (settings.arguments as Map)
  123 + .getOrNull('courseModuleEntity') as CourseModuleEntity;
108 124 }
109 125 return CupertinoPageRoute(
110   - builder: (_) => HomePage(
111   - moduleId: moduleId,
112   - ));
113   - case AppRouteName.fogPwd:
114   - return CupertinoPageRoute(builder: (_) => const ForgetPasswordHomePage());
115   - case AppRouteName.lesson:
116   - return CupertinoPageRoute(builder: (_) => const LessonPage());
117   - case AppRouteName.unit:
118   - CourseModuleEntity courseEntity = CourseModuleEntity();
  126 + builder: (_) => UnitPage(courseModuleEntity: courseModuleEntity));
  127 + case AppRouteName.courseSection:
  128 + CourseUnitEntity courseUnitEntity = CourseUnitEntity();
  129 + CourseUnitDetail courseUnitDetail = CourseUnitDetail();
119 130 if (settings.arguments != null) {
120   - courseEntity = (settings.arguments as Map).getOrNull('courseModuleEntity') as CourseModuleEntity;
  131 + courseUnitEntity = (settings.arguments as Map)
  132 + .getOrNull('courseUnitEntity') as CourseUnitEntity;
  133 + courseUnitDetail = (settings.arguments as Map)
  134 + .getOrNull('courseUnitDetail') as CourseUnitDetail;
121 135 }
122   - return CupertinoPageRoute(builder: (_) => UnitPage(courseEntity: courseEntity));
  136 + return CupertinoPageRoute(
  137 + builder: (_) => SectionPage(
  138 + courseUnitEntity: courseUnitEntity,
  139 + courseUnitDetail: courseUnitDetail));
123 140 case AppRouteName.listen:
124 141 return CupertinoPageRoute(builder: (_) => const ListenPage());
125 142 case AppRouteName.shop:
... ... @@ -129,11 +146,13 @@ class AppRouter {
129 146 if (settings.arguments != null && settings.arguments is ProductEntity) {
130 147 productEntity = settings.arguments as ProductEntity;
131 148 }
132   - return CupertinoPageRoute(builder: (_) => ShoppingPage(productEntity: productEntity));
  149 + return CupertinoPageRoute(
  150 + builder: (_) => ShoppingPage(productEntity: productEntity));
133 151 case AppRouteName.exLesson:
134 152 return CupertinoPageRoute(builder: (_) => const ExchangeLessonPage());
135 153 case AppRouteName.exList:
136   - return CupertinoPageRoute(builder: (_) => const ExchangeLessonListPage());
  154 + return CupertinoPageRoute(
  155 + builder: (_) => const ExchangeLessonListPage());
137 156 case AppRouteName.reAfter:
138 157 return CupertinoPageRoute(builder: (_) => const RepeatAfterPage());
139 158 case AppRouteName.user:
... ... @@ -161,19 +180,22 @@ class AppRouter {
161 180 case AppRouteName.topicPic:
162 181 var courseLessonId = '';
163 182 if (settings.arguments != null) {
164   - courseLessonId = (settings.arguments as Map)['courseLessonId'] as String;
  183 + courseLessonId =
  184 + (settings.arguments as Map)['courseLessonId'] as String;
165 185 }
166   - return CupertinoPageRoute(builder: (_) => TopicPicturePage(courseLessonId: courseLessonId));
  186 + return CupertinoPageRoute(
  187 + builder: (_) => TopicPicturePage(courseLessonId: courseLessonId));
167 188 case AppRouteName.lookVideo:
168 189 final videoUrl = (settings.arguments as Map)['videoUrl'] as String;
169 190 final title = (settings.arguments as Map)['title'] as String?;
170   - final courseLessonId = (settings.arguments as Map)['courseLessonId'] as String?;
  191 + final courseLessonId =
  192 + (settings.arguments as Map)['courseLessonId'] as String?;
171 193 return CupertinoPageRoute(
172 194 builder: (_) => LookVideoPage(
173   - videoUrl: videoUrl,
174   - typeTitle: title,
175   - courseLessonId: courseLessonId,
176   - ));
  195 + videoUrl: videoUrl,
  196 + typeTitle: title,
  197 + courseLessonId: courseLessonId,
  198 + ));
177 199 /*case AppRouteName.setPwd:
178 200 case AppRouteName.setPwd:
179 201 phoneNum: phoneNum,
... ... @@ -182,7 +204,8 @@ class AppRouter {
182 204 ));*/
183 205 case AppRouteName.webView:
184 206 final urlStr = (settings.arguments as Map)['urlStr'] as String;
185   - final webViewTitle = (settings.arguments as Map)['webViewTitle'] as String;
  207 + final webViewTitle =
  208 + (settings.arguments as Map)['webViewTitle'] as String;
186 209 return CupertinoPageRoute(
187 210 builder: (_) => WowWebViewPage(
188 211 urlStr: urlStr,
... ... @@ -191,13 +214,16 @@ class AppRouter {
191 214 case AppRouteName.readAfterContent:
192 215 var videoFollowReadId = '';
193 216 if (settings.arguments != null) {
194   - videoFollowReadId = (settings.arguments as Map)['videoFollowReadId'] as String;
  217 + videoFollowReadId =
  218 + (settings.arguments as Map)['videoFollowReadId'] as String;
195 219 }
196   - return CupertinoPageRoute(builder: (_) => RepeatAfterContentPage(videoFollowReadId: videoFollowReadId));
  220 + return CupertinoPageRoute(
  221 + builder: (_) =>
  222 + RepeatAfterContentPage(videoFollowReadId: videoFollowReadId));
197 223 case AppRouteName.setting:
198   - return CupertinoPageRoute(builder: (_) => const SettingPage());
  224 + return CupertinoPageRoute(builder: (_) => const SettingPage());
199 225 case AppRouteName.deleteAccount:
200   - return CupertinoPageRoute(builder: (_) => const DeleteAccountPage());
  226 + return CupertinoPageRoute(builder: (_) => const DeleteAccountPage());
201 227 case AppRouteName.reBack:
202 228 return CupertinoPageRoute(builder: (_) => const ReBackPage());
203 229 case AppRouteName.tab:
... ... @@ -210,26 +236,34 @@ class AppRouter {
210 236 case AppRouteName.reading:
211 237 var courseLessonId = '';
212 238 if (settings.arguments != null) {
213   - courseLessonId = (settings.arguments as Map)['courseLessonId'] as String;
  239 + courseLessonId =
  240 + (settings.arguments as Map)['courseLessonId'] as String;
214 241 }
215   - return CupertinoPageRoute(builder: (_) => ReadingPage(courseLessonId: courseLessonId));
  242 + return CupertinoPageRoute(
  243 + builder: (_) => ReadingPage(courseLessonId: courseLessonId));
216 244 default:
217 245 return CupertinoPageRoute(
218   - 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}'))));
219 249 }
220 250 }
221 251 }
222 252  
223 253 Future pushNamed(String routeName, {Object? arguments}) {
224   - 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) {
225 257 return value;
226 258 });
227 259 }
228 260  
229   -Future pushNamedAndRemoveUntil(String routeName, RoutePredicate predicate, {Object? arguments}) {
230   - 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);
231 265 }
232 266  
233 267 void popPage({dynamic data}) {
234   - Navigator.of(AppRouter.context).pop(data);
  268 + Navigator.of(AppRouter.context).pop(data);
235 269 }
... ...