Commit 8988aa690fea78ce7e3c840a673d9ed7de283c0a
1 parent
bcd47f52
feat:首页+课程列表数据获取
Showing
13 changed files
with
341 additions
and
44 deletions
lib/common/request/dao/home_dao.dart
| 1 | +import 'package:flutter/foundation.dart'; | ||
| 1 | import 'package:wow_english/common/request/apis.dart'; | 2 | import 'package:wow_english/common/request/apis.dart'; |
| 2 | import 'package:wow_english/common/request/request_client.dart'; | 3 | import 'package:wow_english/common/request/request_client.dart'; |
| 4 | +import 'package:wow_english/models/course_entity.dart'; | ||
| 3 | 5 | ||
| 4 | import '../../../models/course_module_entity.dart'; | 6 | import '../../../models/course_module_entity.dart'; |
| 5 | 7 | ||
| @@ -11,8 +13,18 @@ class HomeDao { | @@ -11,8 +13,18 @@ class HomeDao { | ||
| 11 | } | 13 | } |
| 12 | 14 | ||
| 13 | ///课程列表 | 15 | ///课程列表 |
| 14 | - static Future courseLesson() async { | ||
| 15 | - var data = await requestClient.get(Apis.courseLesson); | 16 | + static Future<CourseEntity?> courseLesson({String moduleId = ''}) async { |
| 17 | + Map<String, dynamic> mapData = {}; | ||
| 18 | + if (moduleId.isNotEmpty) { | ||
| 19 | + mapData['moduleId'] = moduleId; | ||
| 20 | + } | ||
| 21 | + var data = await requestClient.get<CourseEntity>( | ||
| 22 | + Apis.courseLesson, | ||
| 23 | + queryParameters: mapData | ||
| 24 | + ); | ||
| 25 | + if (kDebugMode) { | ||
| 26 | + print('>>>>>>>>>${data.runtimeType}'); | ||
| 27 | + } | ||
| 16 | return data; | 28 | return data; |
| 17 | } | 29 | } |
| 18 | } | 30 | } |
lib/generated/json/base/json_convert_content.dart
| @@ -4,6 +4,7 @@ | @@ -4,6 +4,7 @@ | ||
| 4 | 4 | ||
| 5 | // This file is automatically generated. DO NOT EDIT, all your changes would be lost. | 5 | // This file is automatically generated. DO NOT EDIT, all your changes would be lost. |
| 6 | import 'package:flutter/material.dart' show debugPrint; | 6 | import 'package:flutter/material.dart' show debugPrint; |
| 7 | +import 'package:wow_english/models/course_entity.dart'; | ||
| 7 | import 'package:wow_english/models/course_module_entity.dart'; | 8 | import 'package:wow_english/models/course_module_entity.dart'; |
| 8 | import 'package:wow_english/models/listen_entity.dart'; | 9 | import 'package:wow_english/models/listen_entity.dart'; |
| 9 | import 'package:wow_english/models/user_entity.dart'; | 10 | import 'package:wow_english/models/user_entity.dart'; |
| @@ -14,6 +15,8 @@ typedef EnumConvertFunction<T> = T Function(String value); | @@ -14,6 +15,8 @@ typedef EnumConvertFunction<T> = T Function(String value); | ||
| 14 | 15 | ||
| 15 | class JsonConvert { | 16 | class JsonConvert { |
| 16 | static final Map<String, JsonConvertFunction> convertFuncMap = { | 17 | static final Map<String, JsonConvertFunction> convertFuncMap = { |
| 18 | + (CourseEntity).toString(): CourseEntity.fromJson, | ||
| 19 | + (CourseCourseLessons).toString(): CourseCourseLessons.fromJson, | ||
| 17 | (CourseModuleEntity).toString(): CourseModuleEntity.fromJson, | 20 | (CourseModuleEntity).toString(): CourseModuleEntity.fromJson, |
| 18 | (ListenEntity).toString(): ListenEntity.fromJson, | 21 | (ListenEntity).toString(): ListenEntity.fromJson, |
| 19 | (UserEntity).toString(): UserEntity.fromJson, | 22 | (UserEntity).toString(): UserEntity.fromJson, |
| @@ -95,6 +98,12 @@ List<T>? convertListNotNull<T>(dynamic value, {EnumConvertFunction? enumConvert} | @@ -95,6 +98,12 @@ List<T>? convertListNotNull<T>(dynamic value, {EnumConvertFunction? enumConvert} | ||
| 95 | 98 | ||
| 96 | //list is returned by type | 99 | //list is returned by type |
| 97 | static M? _getListChildType<M>(List<Map<String, dynamic>> data) { | 100 | static M? _getListChildType<M>(List<Map<String, dynamic>> data) { |
| 101 | + if(<CourseEntity>[] is M){ | ||
| 102 | + return data.map<CourseEntity>((Map<String, dynamic> e) => CourseEntity.fromJson(e)).toList() as M; | ||
| 103 | + } | ||
| 104 | + if(<CourseCourseLessons>[] is M){ | ||
| 105 | + return data.map<CourseCourseLessons>((Map<String, dynamic> e) => CourseCourseLessons.fromJson(e)).toList() as M; | ||
| 106 | + } | ||
| 98 | if(<CourseModuleEntity>[] is M){ | 107 | if(<CourseModuleEntity>[] is M){ |
| 99 | return data.map<CourseModuleEntity>((Map<String, dynamic> e) => CourseModuleEntity.fromJson(e)).toList() as M; | 108 | return data.map<CourseModuleEntity>((Map<String, dynamic> e) => CourseModuleEntity.fromJson(e)).toList() as M; |
| 100 | } | 109 | } |
| @@ -106,7 +115,7 @@ List<T>? convertListNotNull<T>(dynamic value, {EnumConvertFunction? enumConvert} | @@ -106,7 +115,7 @@ List<T>? convertListNotNull<T>(dynamic value, {EnumConvertFunction? enumConvert} | ||
| 106 | } | 115 | } |
| 107 | 116 | ||
| 108 | debugPrint("${M.toString()} not found"); | 117 | debugPrint("${M.toString()} not found"); |
| 109 | - | 118 | + |
| 110 | return null; | 119 | return null; |
| 111 | } | 120 | } |
| 112 | 121 | ||
| @@ -117,4 +126,4 @@ List<T>? convertListNotNull<T>(dynamic value, {EnumConvertFunction? enumConvert} | @@ -117,4 +126,4 @@ List<T>? convertListNotNull<T>(dynamic value, {EnumConvertFunction? enumConvert} | ||
| 117 | return jsonConvert.convert<M>(json); | 126 | return jsonConvert.convert<M>(json); |
| 118 | } | 127 | } |
| 119 | } | 128 | } |
| 120 | -} | 129 | -} |
| 130 | +} | ||
| 121 | \ No newline at end of file | 131 | \ No newline at end of file |
lib/generated/json/course_entity.g.dart
0 → 100644
| 1 | +import 'package:wow_english/generated/json/base/json_convert_content.dart'; | ||
| 2 | +import 'package:wow_english/models/course_entity.dart'; | ||
| 3 | + | ||
| 4 | +CourseEntity $CourseEntityFromJson(Map<String, dynamic> json) { | ||
| 5 | + final CourseEntity courseEntity = CourseEntity(); | ||
| 6 | + final List<CourseCourseLessons>? courseLessons = jsonConvert.convertListNotNull<CourseCourseLessons>(json['courseLessons']); | ||
| 7 | + if (courseLessons != null) { | ||
| 8 | + courseEntity.courseLessons = courseLessons; | ||
| 9 | + } | ||
| 10 | + final int? nowCourseLesson = jsonConvert.convert<int>(json['nowCourseLesson']); | ||
| 11 | + if (nowCourseLesson != null) { | ||
| 12 | + courseEntity.nowCourseLesson = nowCourseLesson; | ||
| 13 | + } | ||
| 14 | + final int? nowCourseModuleId = jsonConvert.convert<int>(json['nowCourseModuleId']); | ||
| 15 | + if (nowCourseModuleId != null) { | ||
| 16 | + courseEntity.nowCourseModuleId = nowCourseModuleId; | ||
| 17 | + } | ||
| 18 | + final String? nowCourseModuleName = jsonConvert.convert<String>(json['nowCourseModuleName']); | ||
| 19 | + if (nowCourseModuleName != null) { | ||
| 20 | + courseEntity.nowCourseModuleName = nowCourseModuleName; | ||
| 21 | + } | ||
| 22 | + final int? totalCourseLesson = jsonConvert.convert<int>(json['totalCourseLesson']); | ||
| 23 | + if (totalCourseLesson != null) { | ||
| 24 | + courseEntity.totalCourseLesson = totalCourseLesson; | ||
| 25 | + } | ||
| 26 | + return courseEntity; | ||
| 27 | +} | ||
| 28 | + | ||
| 29 | +Map<String, dynamic> $CourseEntityToJson(CourseEntity entity) { | ||
| 30 | + final Map<String, dynamic> data = <String, dynamic>{}; | ||
| 31 | + data['courseLessons'] = entity.courseLessons?.map((v) => v.toJson()).toList(); | ||
| 32 | + data['nowCourseLesson'] = entity.nowCourseLesson; | ||
| 33 | + data['nowCourseModuleId'] = entity.nowCourseModuleId; | ||
| 34 | + data['nowCourseModuleName'] = entity.nowCourseModuleName; | ||
| 35 | + data['totalCourseLesson'] = entity.totalCourseLesson; | ||
| 36 | + return data; | ||
| 37 | +} | ||
| 38 | + | ||
| 39 | +CourseCourseLessons $CourseCourseLessonsFromJson(Map<String, dynamic> json) { | ||
| 40 | + final CourseCourseLessons courseCourseLessons = CourseCourseLessons(); | ||
| 41 | + final int? courseModuleId = jsonConvert.convert<int>(json['courseModuleId']); | ||
| 42 | + if (courseModuleId != null) { | ||
| 43 | + courseCourseLessons.courseModuleId = courseModuleId; | ||
| 44 | + } | ||
| 45 | + final int? courseType = jsonConvert.convert<int>(json['courseType']); | ||
| 46 | + if (courseType != null) { | ||
| 47 | + courseCourseLessons.courseType = courseType; | ||
| 48 | + } | ||
| 49 | + final String? coverUrl = jsonConvert.convert<String>(json['coverUrl']); | ||
| 50 | + if (coverUrl != null) { | ||
| 51 | + courseCourseLessons.coverUrl = coverUrl; | ||
| 52 | + } | ||
| 53 | + final String? createTime = jsonConvert.convert<String>(json['createTime']); | ||
| 54 | + if (createTime != null) { | ||
| 55 | + courseCourseLessons.createTime = createTime; | ||
| 56 | + } | ||
| 57 | + final String? deleted = jsonConvert.convert<String>(json['deleted']); | ||
| 58 | + if (deleted != null) { | ||
| 59 | + courseCourseLessons.deleted = deleted; | ||
| 60 | + } | ||
| 61 | + final String? des = jsonConvert.convert<String>(json['des']); | ||
| 62 | + if (des != null) { | ||
| 63 | + courseCourseLessons.des = des; | ||
| 64 | + } | ||
| 65 | + final String? id = jsonConvert.convert<String>(json['id']); | ||
| 66 | + if (id != null) { | ||
| 67 | + courseCourseLessons.id = id; | ||
| 68 | + } | ||
| 69 | + final bool? lock = jsonConvert.convert<bool>(json['lock']); | ||
| 70 | + if (lock != null) { | ||
| 71 | + courseCourseLessons.lock = lock; | ||
| 72 | + } | ||
| 73 | + final String? modifyTime = jsonConvert.convert<String>(json['modifyTime']); | ||
| 74 | + if (modifyTime != null) { | ||
| 75 | + courseCourseLessons.modifyTime = modifyTime; | ||
| 76 | + } | ||
| 77 | + final String? name = jsonConvert.convert<String>(json['name']); | ||
| 78 | + if (name != null) { | ||
| 79 | + courseCourseLessons.name = name; | ||
| 80 | + } | ||
| 81 | + final int? sortOrder = jsonConvert.convert<int>(json['sortOrder']); | ||
| 82 | + if (sortOrder != null) { | ||
| 83 | + courseCourseLessons.sortOrder = sortOrder; | ||
| 84 | + } | ||
| 85 | + final int? status = jsonConvert.convert<int>(json['status']); | ||
| 86 | + if (status != null) { | ||
| 87 | + courseCourseLessons.status = status; | ||
| 88 | + } | ||
| 89 | + return courseCourseLessons; | ||
| 90 | +} | ||
| 91 | + | ||
| 92 | +Map<String, dynamic> $CourseCourseLessonsToJson(CourseCourseLessons entity) { | ||
| 93 | + final Map<String, dynamic> data = <String, dynamic>{}; | ||
| 94 | + data['courseModuleId'] = entity.courseModuleId; | ||
| 95 | + data['courseType'] = entity.courseType; | ||
| 96 | + data['coverUrl'] = entity.coverUrl; | ||
| 97 | + data['createTime'] = entity.createTime; | ||
| 98 | + data['deleted'] = entity.deleted; | ||
| 99 | + data['des'] = entity.des; | ||
| 100 | + data['id'] = entity.id; | ||
| 101 | + data['lock'] = entity.lock; | ||
| 102 | + data['modifyTime'] = entity.modifyTime; | ||
| 103 | + data['name'] = entity.name; | ||
| 104 | + data['sortOrder'] = entity.sortOrder; | ||
| 105 | + data['status'] = entity.status; | ||
| 106 | + return data; | ||
| 107 | +} | ||
| 0 | \ No newline at end of file | 108 | \ No newline at end of file |
lib/generated/json/course_module_entity.g.dart
| @@ -79,4 +79,4 @@ Map<String, dynamic> $CourseModuleEntityToJson(CourseModuleEntity entity) { | @@ -79,4 +79,4 @@ Map<String, dynamic> $CourseModuleEntityToJson(CourseModuleEntity entity) { | ||
| 79 | data['sortOrder'] = entity.sortOrder; | 79 | data['sortOrder'] = entity.sortOrder; |
| 80 | data['status'] = entity.status; | 80 | data['status'] = entity.status; |
| 81 | return data; | 81 | return data; |
| 82 | -} | 82 | -} |
| 83 | +} | ||
| 83 | \ No newline at end of file | 84 | \ No newline at end of file |
lib/models/course_entity.dart
0 → 100644
| 1 | +import 'package:wow_english/generated/json/base/json_field.dart'; | ||
| 2 | +import 'package:wow_english/generated/json/course_entity.g.dart'; | ||
| 3 | +import 'dart:convert'; | ||
| 4 | + | ||
| 5 | +@JsonSerializable() | ||
| 6 | +class CourseEntity { | ||
| 7 | + List<CourseCourseLessons>? courseLessons; | ||
| 8 | + int? nowCourseLesson; | ||
| 9 | + int? nowCourseModuleId; | ||
| 10 | + String? nowCourseModuleName; | ||
| 11 | + int? totalCourseLesson; | ||
| 12 | + | ||
| 13 | + CourseEntity(); | ||
| 14 | + | ||
| 15 | + factory CourseEntity.fromJson(Map<String, dynamic> json) => $CourseEntityFromJson(json); | ||
| 16 | + | ||
| 17 | + Map<String, dynamic> toJson() => $CourseEntityToJson(this); | ||
| 18 | + | ||
| 19 | + @override | ||
| 20 | + String toString() { | ||
| 21 | + return jsonEncode(this); | ||
| 22 | + } | ||
| 23 | +} | ||
| 24 | + | ||
| 25 | +@JsonSerializable() | ||
| 26 | +class CourseCourseLessons { | ||
| 27 | + int? courseModuleId; | ||
| 28 | + int? courseType; | ||
| 29 | + String? coverUrl; | ||
| 30 | + String? createTime; | ||
| 31 | + String? deleted; | ||
| 32 | + String? des; | ||
| 33 | + String? id; | ||
| 34 | + bool? lock; | ||
| 35 | + String? modifyTime; | ||
| 36 | + String? name; | ||
| 37 | + int? sortOrder; | ||
| 38 | + int? status; | ||
| 39 | + | ||
| 40 | + CourseCourseLessons(); | ||
| 41 | + | ||
| 42 | + factory CourseCourseLessons.fromJson(Map<String, dynamic> json) => $CourseCourseLessonsFromJson(json); | ||
| 43 | + | ||
| 44 | + Map<String, dynamic> toJson() => $CourseCourseLessonsToJson(this); | ||
| 45 | + | ||
| 46 | + @override | ||
| 47 | + String toString() { | ||
| 48 | + return jsonEncode(this); | ||
| 49 | + } | ||
| 50 | +} | ||
| 0 | \ No newline at end of file | 51 | \ No newline at end of file |
lib/pages/home/bloc/home_bloc.dart
| 1 | import 'package:flutter/cupertino.dart'; | 1 | import 'package:flutter/cupertino.dart'; |
| 2 | +import 'package:flutter/foundation.dart'; | ||
| 2 | import 'package:flutter_bloc/flutter_bloc.dart'; | 3 | import 'package:flutter_bloc/flutter_bloc.dart'; |
| 3 | import 'package:flutter_easyloading/flutter_easyloading.dart'; | 4 | import 'package:flutter_easyloading/flutter_easyloading.dart'; |
| 4 | import 'package:wow_english/common/request/dao/home_dao.dart'; | 5 | import 'package:wow_english/common/request/dao/home_dao.dart'; |
| 5 | import 'package:wow_english/common/request/exception.dart'; | 6 | import 'package:wow_english/common/request/exception.dart'; |
| 7 | +import 'package:wow_english/models/course_entity.dart'; | ||
| 8 | +// import 'package:wow_english/models/course_lesson_entity.dart'; | ||
| 6 | import 'package:wow_english/utils/loading.dart'; | 9 | import 'package:wow_english/utils/loading.dart'; |
| 7 | 10 | ||
| 8 | part 'home_event.dart'; | 11 | part 'home_event.dart'; |
| 9 | part 'home_state.dart'; | 12 | part 'home_state.dart'; |
| 10 | 13 | ||
| 11 | class HomeBloc extends Bloc<HomeEvent, HomeState> { | 14 | class HomeBloc extends Bloc<HomeEvent, HomeState> { |
| 12 | - HomeBloc() : super(HomeInitial()) { | 15 | + final String? moduleId; |
| 16 | + | ||
| 17 | + CourseEntity? _modelData; | ||
| 18 | + CourseEntity? get modelData => _modelData; | ||
| 19 | + | ||
| 20 | + HomeBloc(this.moduleId) : super(HomeInitial()) { | ||
| 13 | on<RequestDataEvent>(_requestData); | 21 | on<RequestDataEvent>(_requestData); |
| 14 | } | 22 | } |
| 15 | 23 | ||
| 16 | Future<void> requestData() async { | 24 | Future<void> requestData() async { |
| 17 | try { | 25 | try { |
| 18 | await loading(() async { | 26 | await loading(() async { |
| 19 | - HomeDao.courseLesson(); | 27 | + await HomeDao.courseLesson(moduleId: moduleId??''); |
| 28 | + // _modelData = await HomeDao.courseLesson(moduleId: moduleId??''); | ||
| 20 | emit(HomeDataLoadState()); | 29 | emit(HomeDataLoadState()); |
| 21 | }); | 30 | }); |
| 22 | } catch (e) { | 31 | } catch (e) { |
lib/pages/home/home_page.dart
| @@ -2,19 +2,24 @@ import 'package:flutter/material.dart'; | @@ -2,19 +2,24 @@ import 'package:flutter/material.dart'; | ||
| 2 | import 'package:flutter_bloc/flutter_bloc.dart'; | 2 | import 'package:flutter_bloc/flutter_bloc.dart'; |
| 3 | import 'package:flutter_screenutil/flutter_screenutil.dart'; | 3 | import 'package:flutter_screenutil/flutter_screenutil.dart'; |
| 4 | import 'package:wow_english/common/extension/string_extension.dart'; | 4 | import 'package:wow_english/common/extension/string_extension.dart'; |
| 5 | -import 'package:wow_english/pages/home/widgets/home_lesson_item_widget.dart'; | 5 | +import 'package:wow_english/models/course_entity.dart'; |
| 6 | +import 'package:wow_english/pages/home/widgets/home_bouns_item.dart'; | ||
| 6 | import 'package:wow_english/pages/home/widgets/home_tab_header_widget.dart'; | 7 | import 'package:wow_english/pages/home/widgets/home_tab_header_widget.dart'; |
| 8 | +import 'package:wow_english/pages/home/widgets/home_vidoe_item.dart'; | ||
| 7 | import 'package:wow_english/route/route.dart'; | 9 | import 'package:wow_english/route/route.dart'; |
| 8 | 10 | ||
| 9 | import 'bloc/home_bloc.dart'; | 11 | import 'bloc/home_bloc.dart'; |
| 10 | 12 | ||
| 11 | class HomePage extends StatelessWidget { | 13 | class HomePage extends StatelessWidget { |
| 12 | - const HomePage({super.key}); | 14 | + const HomePage({super.key, this.moduleId}); |
| 15 | + | ||
| 16 | + /// 模块id | ||
| 17 | + final String? moduleId; | ||
| 13 | 18 | ||
| 14 | @override | 19 | @override |
| 15 | Widget build(BuildContext context) { | 20 | Widget build(BuildContext context) { |
| 16 | return BlocProvider( | 21 | return BlocProvider( |
| 17 | - create: (context) => HomeBloc()..requestData(), | 22 | + create: (context) => HomeBloc(moduleId)..requestData(), |
| 18 | child: _HomePageView(), | 23 | child: _HomePageView(), |
| 19 | ); | 24 | ); |
| 20 | } | 25 | } |
| @@ -67,10 +72,20 @@ class _HomePageView extends StatelessWidget { | @@ -67,10 +72,20 @@ class _HomePageView extends StatelessWidget { | ||
| 67 | ), | 72 | ), |
| 68 | Expanded( | 73 | Expanded( |
| 69 | child: ListView.builder( | 74 | child: ListView.builder( |
| 70 | - itemCount: 10, | 75 | + itemCount: 0, |
| 71 | scrollDirection: Axis.horizontal, | 76 | scrollDirection: Axis.horizontal, |
| 72 | itemBuilder: (BuildContext context, int index){ | 77 | itemBuilder: (BuildContext context, int index){ |
| 73 | - return const HomeLessonItem(); | 78 | + String? title = bloc.modelData?.courseLessons?[index]?.name; |
| 79 | + CourseCourseLessons? data = bloc.modelData?.courseLessons?[index]; | ||
| 80 | + if (data?.courseType == 5) {//彩蛋 | ||
| 81 | + return HomeBoundsItem( | ||
| 82 | + imageUrl: data?.coverUrl, | ||
| 83 | + ); | ||
| 84 | + } else { | ||
| 85 | + return HomeVideoItem( | ||
| 86 | + lessons: data, | ||
| 87 | + ); | ||
| 88 | + } | ||
| 74 | }) | 89 | }) |
| 75 | ), | 90 | ), |
| 76 | SafeArea( | 91 | SafeArea( |
| @@ -90,7 +105,7 @@ class _HomePageView extends StatelessWidget { | @@ -90,7 +105,7 @@ class _HomePageView extends StatelessWidget { | ||
| 90 | ), | 105 | ), |
| 91 | padding: EdgeInsets.symmetric(vertical: 8.h,horizontal: 24.w), | 106 | padding: EdgeInsets.symmetric(vertical: 8.h,horizontal: 24.w), |
| 92 | child: Text( | 107 | child: Text( |
| 93 | - '3/67', | 108 | + '${(bloc.modelData?.nowCourseLesson)}/${bloc.modelData?.totalCourseLesson}', |
| 94 | style: TextStyle( | 109 | style: TextStyle( |
| 95 | color: Colors.white, | 110 | color: Colors.white, |
| 96 | fontSize: 12.sp | 111 | fontSize: 12.sp |
lib/pages/home/widgets/home_bouns_item.dart
0 → 100644
| 1 | +import 'package:flutter/cupertino.dart'; | ||
| 2 | +import 'package:flutter_screenutil/flutter_screenutil.dart'; | ||
| 3 | + | ||
| 4 | +class HomeBoundsItem extends StatelessWidget { | ||
| 5 | + const HomeBoundsItem({super.key, this.imageUrl}); | ||
| 6 | + | ||
| 7 | + final String? imageUrl; | ||
| 8 | + | ||
| 9 | + @override | ||
| 10 | + Widget build(BuildContext context) { | ||
| 11 | + return SizedBox( | ||
| 12 | + height: 207.h, | ||
| 13 | + width: 169.w, | ||
| 14 | + child: Image.network(imageUrl??''), | ||
| 15 | + ); | ||
| 16 | + } | ||
| 17 | +} | ||
| 0 | \ No newline at end of file | 18 | \ No newline at end of file |
lib/pages/home/widgets/home_vidoe_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/models/course_entity.dart'; | ||
| 5 | + | ||
| 6 | +class HomeVideoItem extends StatelessWidget { | ||
| 7 | + const HomeVideoItem({super.key, this.lessons}); | ||
| 8 | + | ||
| 9 | + final CourseCourseLessons? lessons; | ||
| 10 | + | ||
| 11 | + @override | ||
| 12 | + Widget build(BuildContext context) { | ||
| 13 | + return Container( | ||
| 14 | + height: 202.h, | ||
| 15 | + width: 165.w, | ||
| 16 | + padding: EdgeInsets.symmetric(horizontal: 16.w,vertical: 12.h), | ||
| 17 | + decoration: BoxDecoration( | ||
| 18 | + image: DecorationImage( | ||
| 19 | + image: AssetImage(''.assetPng) | ||
| 20 | + ) | ||
| 21 | + ), | ||
| 22 | + child: Column( | ||
| 23 | + children: [ | ||
| 24 | + Container( | ||
| 25 | + decoration: BoxDecoration( | ||
| 26 | + border: Border.all( | ||
| 27 | + width: 2, | ||
| 28 | + color: const Color(0xFF140C10), | ||
| 29 | + ), | ||
| 30 | + borderRadius: BorderRadius.circular(6) | ||
| 31 | + ), | ||
| 32 | + child: Image.network(lessons?.coverUrl??''), | ||
| 33 | + ), | ||
| 34 | + Container( | ||
| 35 | + decoration: BoxDecoration( | ||
| 36 | + border: Border.all( | ||
| 37 | + width: 2, | ||
| 38 | + color: const Color(0xFF140C10), | ||
| 39 | + ), | ||
| 40 | + borderRadius: BorderRadius.circular(6) | ||
| 41 | + ), | ||
| 42 | + padding: EdgeInsets.symmetric(horizontal: 10.w,vertical: 8.h), | ||
| 43 | + child: Text( | ||
| 44 | + lessons?.name??'', | ||
| 45 | + style: TextStyle( | ||
| 46 | + fontSize: 25.sp, | ||
| 47 | + color: const Color(0xFF333333) | ||
| 48 | + ), | ||
| 49 | + ), | ||
| 50 | + ) | ||
| 51 | + ], | ||
| 52 | + ), | ||
| 53 | + ); | ||
| 54 | + } | ||
| 55 | +} | ||
| 0 | \ No newline at end of file | 56 | \ No newline at end of file |
lib/pages/lessons/bloc/lesson_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:flutter_easyloading/flutter_easyloading.dart'; | ||
| 4 | import 'package:wow_english/common/request/dao/home_dao.dart'; | 3 | import 'package:wow_english/common/request/dao/home_dao.dart'; |
| 5 | import 'package:wow_english/common/request/exception.dart'; | 4 | import 'package:wow_english/common/request/exception.dart'; |
| 6 | import 'package:wow_english/models/course_module_entity.dart'; | 5 | import 'package:wow_english/models/course_module_entity.dart'; |
| @@ -10,6 +9,7 @@ part 'lesson_event.dart'; | @@ -10,6 +9,7 @@ part 'lesson_event.dart'; | ||
| 10 | part 'lesson_state.dart'; | 9 | part 'lesson_state.dart'; |
| 11 | 10 | ||
| 12 | class LessonBloc extends Bloc<LessonEvent, LessonState> { | 11 | class LessonBloc extends Bloc<LessonEvent, LessonState> { |
| 12 | + | ||
| 13 | final int pageIndex; | 13 | final int pageIndex; |
| 14 | 14 | ||
| 15 | final PageController pageController; | 15 | final PageController pageController; |
| @@ -22,7 +22,7 @@ class LessonBloc extends Bloc<LessonEvent, LessonState> { | @@ -22,7 +22,7 @@ class LessonBloc extends Bloc<LessonEvent, LessonState> { | ||
| 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 | + LessonBloc(this.pageIndex,this.pageController) : super(LessonInitial()) { |
| 26 | _currentPageIndex = pageIndex; | 26 | _currentPageIndex = pageIndex; |
| 27 | on<PageViewChangeIndexEvent>(_pageIndexChange); | 27 | on<PageViewChangeIndexEvent>(_pageIndexChange); |
| 28 | } | 28 | } |
| @@ -30,21 +30,17 @@ class LessonBloc extends Bloc<LessonEvent, LessonState> { | @@ -30,21 +30,17 @@ class LessonBloc extends Bloc<LessonEvent, LessonState> { | ||
| 30 | Future<void> requestData() async { | 30 | Future<void> requestData() async { |
| 31 | try { | 31 | try { |
| 32 | await loading(() async { | 32 | await loading(() async { |
| 33 | - var list = await HomeDao.courseModule(); | ||
| 34 | - if (list?.isNotEmpty == true) { | ||
| 35 | - _listData = list!; | ||
| 36 | - emit(LessonDataLoadState()); | ||
| 37 | - } else { | ||
| 38 | - EasyLoading.showToast("数据获取失败!"); | ||
| 39 | - } | 33 | + _listData = await HomeDao.courseModule()??[]; |
| 34 | + emit(LessonDataLoadState()); | ||
| 40 | }); | 35 | }); |
| 41 | } catch (e) { | 36 | } catch (e) { |
| 42 | if (e is ApiException) { | 37 | if (e is ApiException) { |
| 38 | + | ||
| 43 | } | 39 | } |
| 44 | } | 40 | } |
| 45 | } | 41 | } |
| 46 | 42 | ||
| 47 | - void _pageIndexChange(PageViewChangeIndexEvent event, Emitter<LessonState> emitter) async { | 43 | + void _pageIndexChange(PageViewChangeIndexEvent event,Emitter<LessonState> emitter) async { |
| 48 | _currentPageIndex = event.index; | 44 | _currentPageIndex = event.index; |
| 49 | emitter(PageIndexChangeState()); | 45 | emitter(PageIndexChangeState()); |
| 50 | } | 46 | } |
lib/pages/lessons/lesson_page.dart
| @@ -4,6 +4,8 @@ import 'package:flutter_easyloading/flutter_easyloading.dart'; | @@ -4,6 +4,8 @@ import 'package:flutter_easyloading/flutter_easyloading.dart'; | ||
| 4 | import 'package:flutter_screenutil/flutter_screenutil.dart'; | 4 | import 'package:flutter_screenutil/flutter_screenutil.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/common/widgets/we_app_bar.dart'; | 6 | import 'package:wow_english/common/widgets/we_app_bar.dart'; |
| 7 | +import 'package:wow_english/models/course_module_entity.dart'; | ||
| 8 | +import 'package:wow_english/route/route.dart'; | ||
| 7 | 9 | ||
| 8 | import 'bloc/lesson_bloc.dart'; | 10 | import 'bloc/lesson_bloc.dart'; |
| 9 | import 'widgets/lesson_item_widget.dart'; | 11 | import 'widgets/lesson_item_widget.dart'; |
| @@ -32,8 +34,6 @@ class _LessonPageView extends StatelessWidget { | @@ -32,8 +34,6 @@ class _LessonPageView extends StatelessWidget { | ||
| 32 | 34 | ||
| 33 | final double _cardHeight = 240.h; | 35 | final double _cardHeight = 240.h; |
| 34 | 36 | ||
| 35 | - final double _numItemHeight = 32.0; | ||
| 36 | - | ||
| 37 | final double _scale = 0.8; | 37 | final double _scale = 0.8; |
| 38 | 38 | ||
| 39 | @override | 39 | @override |
| @@ -88,9 +88,9 @@ class _LessonPageView extends StatelessWidget { | @@ -88,9 +88,9 @@ class _LessonPageView extends StatelessWidget { | ||
| 88 | 32.verticalSpace, | 88 | 32.verticalSpace, |
| 89 | SizedBox( | 89 | SizedBox( |
| 90 | height: 32.h, | 90 | height: 32.h, |
| 91 | - width: 660.w, | 91 | + width: double.infinity, |
| 92 | child: ListView.builder( | 92 | child: ListView.builder( |
| 93 | - itemCount: 10, | 93 | + itemCount: bloc.listData.length, |
| 94 | scrollDirection: Axis.horizontal, | 94 | scrollDirection: Axis.horizontal, |
| 95 | itemBuilder: (BuildContext context,int index){ | 95 | itemBuilder: (BuildContext context,int index){ |
| 96 | return Container( | 96 | return Container( |
| @@ -162,12 +162,18 @@ class _LessonPageView extends StatelessWidget { | @@ -162,12 +162,18 @@ class _LessonPageView extends StatelessWidget { | ||
| 162 | matrix4 = Matrix4.diagonal3Values(1.0, _scale, 1.0) | 162 | matrix4 = Matrix4.diagonal3Values(1.0, _scale, 1.0) |
| 163 | ..setTranslationRaw(0.0, _cardHeight * (1 - _scale) / 2, 0.0); | 163 | ..setTranslationRaw(0.0, _cardHeight * (1 - _scale) / 2, 0.0); |
| 164 | } | 164 | } |
| 165 | - | 165 | + CourseModuleEntity? model = bloc.listData[index]; |
| 166 | return Transform( | 166 | return Transform( |
| 167 | transform: matrix4, | 167 | transform: matrix4, |
| 168 | child: Padding( | 168 | child: Padding( |
| 169 | padding: const EdgeInsets.symmetric(horizontal: 10), | 169 | padding: const EdgeInsets.symmetric(horizontal: 10), |
| 170 | - child: LessonItemWidget(isSelected: bloc.currentPageIndex == index), | 170 | + child: LessonItemWidget( |
| 171 | + model: model, | ||
| 172 | + isSelected: bloc.currentPageIndex == index, | ||
| 173 | + onClickEvent: () { | ||
| 174 | + Navigator.of(context).pushNamedAndRemoveUntil(AppRouteName.home, (route) => false,arguments: {'moduleId':model?.id}); | ||
| 175 | + }, | ||
| 176 | + ), | ||
| 171 | ), | 177 | ), |
| 172 | ); | 178 | ); |
| 173 | }); | 179 | }); |
lib/pages/lessons/widgets/lesson_item_widget.dart
| 1 | import 'package:flutter/material.dart'; | 1 | import 'package:flutter/material.dart'; |
| 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'; | ||
| 4 | +import 'package:wow_english/models/course_module_entity.dart'; | ||
| 3 | 5 | ||
| 4 | class LessonItemWidget extends StatelessWidget { | 6 | class LessonItemWidget extends StatelessWidget { |
| 5 | - const LessonItemWidget({super.key, required this.isSelected}); | 7 | + const LessonItemWidget({super.key, required this.isSelected, this.model, this.onClickEvent}); |
| 6 | ///是否被选中 | 8 | ///是否被选中 |
| 7 | final bool isSelected; | 9 | final bool isSelected; |
| 10 | + final CourseModuleEntity? model; | ||
| 11 | + final Function()? onClickEvent; | ||
| 8 | 12 | ||
| 9 | @override | 13 | @override |
| 10 | Widget build(BuildContext context) { | 14 | Widget build(BuildContext context) { |
| 11 | - return isSelected?_selectWidget():_unSelectWidget(); | 15 | + return GestureDetector( |
| 16 | + onTap: () { | ||
| 17 | + if (!isSelected) { | ||
| 18 | + return; | ||
| 19 | + } | ||
| 20 | + onClickEvent?.call(); | ||
| 21 | + }, | ||
| 22 | + child: isSelected?_selectWidget():_unSelectWidget(), | ||
| 23 | + ); | ||
| 12 | } | 24 | } |
| 13 | 25 | ||
| 14 | Widget _unSelectWidget() { | 26 | Widget _unSelectWidget() { |
| 15 | return Container( | 27 | return Container( |
| 16 | - decoration: const BoxDecoration( | 28 | + decoration: BoxDecoration( |
| 17 | image: DecorationImage( | 29 | image: DecorationImage( |
| 18 | - image: NetworkImage('https://img.liblibai.com/web/648331d033b41.png?image_process=format,webp&x-oss-process=image/resize,w_2980,m_lfit/format,webp'), | 30 | + image: AssetImage('gendubeij'.assetPng) |
| 19 | ) | 31 | ) |
| 20 | ), | 32 | ), |
| 33 | + child: Image.network( | ||
| 34 | + model?.picUrl??'', | ||
| 35 | + ), | ||
| 21 | ); | 36 | ); |
| 22 | } | 37 | } |
| 23 | 38 | ||
| @@ -25,28 +40,30 @@ class LessonItemWidget extends StatelessWidget { | @@ -25,28 +40,30 @@ class LessonItemWidget extends StatelessWidget { | ||
| 25 | return Container( | 40 | return Container( |
| 26 | padding: const EdgeInsets.all(10), | 41 | padding: const EdgeInsets.all(10), |
| 27 | decoration: BoxDecoration( | 42 | decoration: BoxDecoration( |
| 28 | - border: Border.all( | ||
| 29 | - width: 2.0, | ||
| 30 | - color: Colors.red, | ||
| 31 | - style: BorderStyle.solid | ||
| 32 | - ), | 43 | + image: DecorationImage( |
| 44 | + image: AssetImage('gendubeij'.assetPng) | ||
| 45 | + ) | ||
| 33 | ), | 46 | ), |
| 34 | child: Column( | 47 | child: Column( |
| 35 | mainAxisAlignment: MainAxisAlignment.spaceBetween, | 48 | mainAxisAlignment: MainAxisAlignment.spaceBetween, |
| 36 | children: [ | 49 | children: [ |
| 37 | Expanded( | 50 | Expanded( |
| 38 | child: Image.network( | 51 | child: Image.network( |
| 39 | - 'https://img.liblibai.com/web/648331d5a2cb5.png?image_process=format,webp&x-oss-process=image/resize,w_2980,m_lfit/format,webp', | 52 | + model?.picUrl??'', |
| 53 | + fit: BoxFit.contain | ||
| 40 | ), | 54 | ), |
| 41 | ), | 55 | ), |
| 42 | 10.verticalSpace, | 56 | 10.verticalSpace, |
| 43 | Container( | 57 | Container( |
| 44 | color: Colors.red, | 58 | color: Colors.red, |
| 45 | - width: double.infinity, | ||
| 46 | - child: const Column( | 59 | + padding: EdgeInsets.symmetric(horizontal: 10.w), |
| 60 | + child: Column( | ||
| 47 | children: [ | 61 | children: [ |
| 48 | - Text('red'), | ||
| 49 | - Text('第三段') | 62 | + Text(model?.name??''), |
| 63 | + Text( | ||
| 64 | + model?.des??'', | ||
| 65 | + maxLines: 1, | ||
| 66 | + ) | ||
| 50 | ], | 67 | ], |
| 51 | ), | 68 | ), |
| 52 | ) | 69 | ) |
lib/route/route.dart
| @@ -61,7 +61,11 @@ class AppRouter { | @@ -61,7 +61,11 @@ class AppRouter { | ||
| 61 | case AppRouteName.login: | 61 | case AppRouteName.login: |
| 62 | return CupertinoPageRoute(builder: (_) => const LoginPage()); | 62 | return CupertinoPageRoute(builder: (_) => const LoginPage()); |
| 63 | case AppRouteName.home: | 63 | case AppRouteName.home: |
| 64 | - return CupertinoPageRoute(builder: (_) => const HomePage()); | 64 | + var moduleId = ''; |
| 65 | + if (settings.arguments != null) { | ||
| 66 | + moduleId = (settings.arguments as Map)['moduleId'] as String; | ||
| 67 | + } | ||
| 68 | + return CupertinoPageRoute(builder: (_) => HomePage(moduleId: moduleId,)); | ||
| 65 | case AppRouteName.fogPwd: | 69 | case AppRouteName.fogPwd: |
| 66 | return CupertinoPageRoute(builder: (_) => const ForgetPasswordHomePage()); | 70 | return CupertinoPageRoute(builder: (_) => const ForgetPasswordHomePage()); |
| 67 | case AppRouteName.lesson: | 71 | case AppRouteName.lesson: |