diff --git a/lib/common/request/dao/home_dao.dart b/lib/common/request/dao/home_dao.dart index 1a980df..c6ae3de 100644 --- a/lib/common/request/dao/home_dao.dart +++ b/lib/common/request/dao/home_dao.dart @@ -1,5 +1,7 @@ +import 'package:flutter/foundation.dart'; import 'package:wow_english/common/request/apis.dart'; import 'package:wow_english/common/request/request_client.dart'; +import 'package:wow_english/models/course_entity.dart'; import '../../../models/course_module_entity.dart'; @@ -11,8 +13,18 @@ class HomeDao { } ///课程列表 - static Future courseLesson() async { - var data = await requestClient.get(Apis.courseLesson); + static Future courseLesson({String moduleId = ''}) async { + Map mapData = {}; + if (moduleId.isNotEmpty) { + mapData['moduleId'] = moduleId; + } + var data = await requestClient.get( + Apis.courseLesson, + queryParameters: mapData + ); + if (kDebugMode) { + print('>>>>>>>>>${data.runtimeType}'); + } return data; } } diff --git a/lib/generated/json/base/json_convert_content.dart b/lib/generated/json/base/json_convert_content.dart index 420da84..1f66c90 100644 --- a/lib/generated/json/base/json_convert_content.dart +++ b/lib/generated/json/base/json_convert_content.dart @@ -4,6 +4,7 @@ // This file is automatically generated. DO NOT EDIT, all your changes would be lost. import 'package:flutter/material.dart' show debugPrint; +import 'package:wow_english/models/course_entity.dart'; import 'package:wow_english/models/course_module_entity.dart'; import 'package:wow_english/models/listen_entity.dart'; import 'package:wow_english/models/user_entity.dart'; @@ -14,6 +15,8 @@ typedef EnumConvertFunction = T Function(String value); class JsonConvert { static final Map convertFuncMap = { + (CourseEntity).toString(): CourseEntity.fromJson, + (CourseCourseLessons).toString(): CourseCourseLessons.fromJson, (CourseModuleEntity).toString(): CourseModuleEntity.fromJson, (ListenEntity).toString(): ListenEntity.fromJson, (UserEntity).toString(): UserEntity.fromJson, @@ -95,6 +98,12 @@ List? convertListNotNull(dynamic value, {EnumConvertFunction? enumConvert} //list is returned by type static M? _getListChildType(List> data) { + if([] is M){ + return data.map((Map e) => CourseEntity.fromJson(e)).toList() as M; + } + if([] is M){ + return data.map((Map e) => CourseCourseLessons.fromJson(e)).toList() as M; + } if([] is M){ return data.map((Map e) => CourseModuleEntity.fromJson(e)).toList() as M; } @@ -106,7 +115,7 @@ List? convertListNotNull(dynamic value, {EnumConvertFunction? enumConvert} } debugPrint("${M.toString()} not found"); - + return null; } @@ -117,4 +126,4 @@ List? convertListNotNull(dynamic value, {EnumConvertFunction? enumConvert} return jsonConvert.convert(json); } } -} +} \ No newline at end of file diff --git a/lib/generated/json/course_entity.g.dart b/lib/generated/json/course_entity.g.dart new file mode 100644 index 0000000..9e8b37d --- /dev/null +++ b/lib/generated/json/course_entity.g.dart @@ -0,0 +1,107 @@ +import 'package:wow_english/generated/json/base/json_convert_content.dart'; +import 'package:wow_english/models/course_entity.dart'; + +CourseEntity $CourseEntityFromJson(Map json) { + final CourseEntity courseEntity = CourseEntity(); + final List? courseLessons = jsonConvert.convertListNotNull(json['courseLessons']); + if (courseLessons != null) { + courseEntity.courseLessons = courseLessons; + } + final int? nowCourseLesson = jsonConvert.convert(json['nowCourseLesson']); + if (nowCourseLesson != null) { + courseEntity.nowCourseLesson = nowCourseLesson; + } + final int? nowCourseModuleId = jsonConvert.convert(json['nowCourseModuleId']); + if (nowCourseModuleId != null) { + courseEntity.nowCourseModuleId = nowCourseModuleId; + } + final String? nowCourseModuleName = jsonConvert.convert(json['nowCourseModuleName']); + if (nowCourseModuleName != null) { + courseEntity.nowCourseModuleName = nowCourseModuleName; + } + final int? totalCourseLesson = jsonConvert.convert(json['totalCourseLesson']); + if (totalCourseLesson != null) { + courseEntity.totalCourseLesson = totalCourseLesson; + } + return courseEntity; +} + +Map $CourseEntityToJson(CourseEntity entity) { + final Map data = {}; + data['courseLessons'] = entity.courseLessons?.map((v) => v.toJson()).toList(); + data['nowCourseLesson'] = entity.nowCourseLesson; + data['nowCourseModuleId'] = entity.nowCourseModuleId; + data['nowCourseModuleName'] = entity.nowCourseModuleName; + data['totalCourseLesson'] = entity.totalCourseLesson; + return data; +} + +CourseCourseLessons $CourseCourseLessonsFromJson(Map json) { + final CourseCourseLessons courseCourseLessons = CourseCourseLessons(); + final int? courseModuleId = jsonConvert.convert(json['courseModuleId']); + if (courseModuleId != null) { + courseCourseLessons.courseModuleId = courseModuleId; + } + final int? courseType = jsonConvert.convert(json['courseType']); + if (courseType != null) { + courseCourseLessons.courseType = courseType; + } + final String? coverUrl = jsonConvert.convert(json['coverUrl']); + if (coverUrl != null) { + courseCourseLessons.coverUrl = coverUrl; + } + final String? createTime = jsonConvert.convert(json['createTime']); + if (createTime != null) { + courseCourseLessons.createTime = createTime; + } + final String? deleted = jsonConvert.convert(json['deleted']); + if (deleted != null) { + courseCourseLessons.deleted = deleted; + } + final String? des = jsonConvert.convert(json['des']); + if (des != null) { + courseCourseLessons.des = des; + } + final String? id = jsonConvert.convert(json['id']); + if (id != null) { + courseCourseLessons.id = id; + } + final bool? lock = jsonConvert.convert(json['lock']); + if (lock != null) { + courseCourseLessons.lock = lock; + } + final String? modifyTime = jsonConvert.convert(json['modifyTime']); + if (modifyTime != null) { + courseCourseLessons.modifyTime = modifyTime; + } + final String? name = jsonConvert.convert(json['name']); + if (name != null) { + courseCourseLessons.name = name; + } + final int? sortOrder = jsonConvert.convert(json['sortOrder']); + if (sortOrder != null) { + courseCourseLessons.sortOrder = sortOrder; + } + final int? status = jsonConvert.convert(json['status']); + if (status != null) { + courseCourseLessons.status = status; + } + return courseCourseLessons; +} + +Map $CourseCourseLessonsToJson(CourseCourseLessons entity) { + final Map data = {}; + data['courseModuleId'] = entity.courseModuleId; + data['courseType'] = entity.courseType; + data['coverUrl'] = entity.coverUrl; + data['createTime'] = entity.createTime; + data['deleted'] = entity.deleted; + data['des'] = entity.des; + data['id'] = entity.id; + data['lock'] = entity.lock; + data['modifyTime'] = entity.modifyTime; + data['name'] = entity.name; + data['sortOrder'] = entity.sortOrder; + data['status'] = entity.status; + return data; +} \ No newline at end of file diff --git a/lib/generated/json/course_module_entity.g.dart b/lib/generated/json/course_module_entity.g.dart index ced031f..cf8bb40 100644 --- a/lib/generated/json/course_module_entity.g.dart +++ b/lib/generated/json/course_module_entity.g.dart @@ -79,4 +79,4 @@ Map $CourseModuleEntityToJson(CourseModuleEntity entity) { data['sortOrder'] = entity.sortOrder; data['status'] = entity.status; return data; -} +} \ No newline at end of file diff --git a/lib/models/course_entity.dart b/lib/models/course_entity.dart new file mode 100644 index 0000000..a58a578 --- /dev/null +++ b/lib/models/course_entity.dart @@ -0,0 +1,50 @@ +import 'package:wow_english/generated/json/base/json_field.dart'; +import 'package:wow_english/generated/json/course_entity.g.dart'; +import 'dart:convert'; + +@JsonSerializable() +class CourseEntity { + List? courseLessons; + int? nowCourseLesson; + int? nowCourseModuleId; + String? nowCourseModuleName; + int? totalCourseLesson; + + CourseEntity(); + + factory CourseEntity.fromJson(Map json) => $CourseEntityFromJson(json); + + Map toJson() => $CourseEntityToJson(this); + + @override + String toString() { + return jsonEncode(this); + } +} + +@JsonSerializable() +class CourseCourseLessons { + int? courseModuleId; + int? courseType; + String? coverUrl; + String? createTime; + String? deleted; + String? des; + String? id; + bool? lock; + String? modifyTime; + String? name; + int? sortOrder; + int? status; + + CourseCourseLessons(); + + factory CourseCourseLessons.fromJson(Map json) => $CourseCourseLessonsFromJson(json); + + Map toJson() => $CourseCourseLessonsToJson(this); + + @override + String toString() { + return jsonEncode(this); + } +} \ No newline at end of file diff --git a/lib/pages/home/bloc/home_bloc.dart b/lib/pages/home/bloc/home_bloc.dart index 501d81d..1daf7e2 100644 --- a/lib/pages/home/bloc/home_bloc.dart +++ b/lib/pages/home/bloc/home_bloc.dart @@ -1,22 +1,31 @@ import 'package:flutter/cupertino.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:wow_english/common/request/dao/home_dao.dart'; import 'package:wow_english/common/request/exception.dart'; +import 'package:wow_english/models/course_entity.dart'; +// import 'package:wow_english/models/course_lesson_entity.dart'; import 'package:wow_english/utils/loading.dart'; part 'home_event.dart'; part 'home_state.dart'; class HomeBloc extends Bloc { - HomeBloc() : super(HomeInitial()) { + final String? moduleId; + + CourseEntity? _modelData; + CourseEntity? get modelData => _modelData; + + HomeBloc(this.moduleId) : super(HomeInitial()) { on(_requestData); } Future requestData() async { try { await loading(() async { - HomeDao.courseLesson(); + await HomeDao.courseLesson(moduleId: moduleId??''); + // _modelData = await HomeDao.courseLesson(moduleId: moduleId??''); emit(HomeDataLoadState()); }); } catch (e) { diff --git a/lib/pages/home/home_page.dart b/lib/pages/home/home_page.dart index 01e72d4..2ad7be1 100644 --- a/lib/pages/home/home_page.dart +++ b/lib/pages/home/home_page.dart @@ -2,19 +2,24 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:wow_english/common/extension/string_extension.dart'; -import 'package:wow_english/pages/home/widgets/home_lesson_item_widget.dart'; +import 'package:wow_english/models/course_entity.dart'; +import 'package:wow_english/pages/home/widgets/home_bouns_item.dart'; import 'package:wow_english/pages/home/widgets/home_tab_header_widget.dart'; +import 'package:wow_english/pages/home/widgets/home_vidoe_item.dart'; import 'package:wow_english/route/route.dart'; import 'bloc/home_bloc.dart'; class HomePage extends StatelessWidget { - const HomePage({super.key}); + const HomePage({super.key, this.moduleId}); + + /// 模块id + final String? moduleId; @override Widget build(BuildContext context) { return BlocProvider( - create: (context) => HomeBloc()..requestData(), + create: (context) => HomeBloc(moduleId)..requestData(), child: _HomePageView(), ); } @@ -67,10 +72,20 @@ class _HomePageView extends StatelessWidget { ), Expanded( child: ListView.builder( - itemCount: 10, + itemCount: 0, scrollDirection: Axis.horizontal, itemBuilder: (BuildContext context, int index){ - return const HomeLessonItem(); + String? title = bloc.modelData?.courseLessons?[index]?.name; + CourseCourseLessons? data = bloc.modelData?.courseLessons?[index]; + if (data?.courseType == 5) {//彩蛋 + return HomeBoundsItem( + imageUrl: data?.coverUrl, + ); + } else { + return HomeVideoItem( + lessons: data, + ); + } }) ), SafeArea( @@ -90,7 +105,7 @@ class _HomePageView extends StatelessWidget { ), padding: EdgeInsets.symmetric(vertical: 8.h,horizontal: 24.w), child: Text( - '3/67', + '${(bloc.modelData?.nowCourseLesson)}/${bloc.modelData?.totalCourseLesson}', style: TextStyle( color: Colors.white, fontSize: 12.sp diff --git a/lib/pages/home/widgets/home_bouns_item.dart b/lib/pages/home/widgets/home_bouns_item.dart new file mode 100644 index 0000000..f805a1f --- /dev/null +++ b/lib/pages/home/widgets/home_bouns_item.dart @@ -0,0 +1,17 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; + +class HomeBoundsItem extends StatelessWidget { + const HomeBoundsItem({super.key, this.imageUrl}); + + final String? imageUrl; + + @override + Widget build(BuildContext context) { + return SizedBox( + height: 207.h, + width: 169.w, + child: Image.network(imageUrl??''), + ); + } +} \ No newline at end of file diff --git a/lib/pages/home/widgets/home_vidoe_item.dart b/lib/pages/home/widgets/home_vidoe_item.dart new file mode 100644 index 0000000..3b21b46 --- /dev/null +++ b/lib/pages/home/widgets/home_vidoe_item.dart @@ -0,0 +1,55 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:wow_english/common/extension/string_extension.dart'; +import 'package:wow_english/models/course_entity.dart'; + +class HomeVideoItem extends StatelessWidget { + const HomeVideoItem({super.key, this.lessons}); + + final CourseCourseLessons? lessons; + + @override + Widget build(BuildContext context) { + return Container( + height: 202.h, + width: 165.w, + padding: EdgeInsets.symmetric(horizontal: 16.w,vertical: 12.h), + decoration: BoxDecoration( + image: DecorationImage( + image: AssetImage(''.assetPng) + ) + ), + child: Column( + children: [ + Container( + decoration: BoxDecoration( + border: Border.all( + width: 2, + color: const Color(0xFF140C10), + ), + borderRadius: BorderRadius.circular(6) + ), + child: Image.network(lessons?.coverUrl??''), + ), + Container( + decoration: BoxDecoration( + border: Border.all( + width: 2, + color: const Color(0xFF140C10), + ), + borderRadius: BorderRadius.circular(6) + ), + padding: EdgeInsets.symmetric(horizontal: 10.w,vertical: 8.h), + child: Text( + lessons?.name??'', + style: TextStyle( + fontSize: 25.sp, + color: const Color(0xFF333333) + ), + ), + ) + ], + ), + ); + } +} \ No newline at end of file diff --git a/lib/pages/lessons/bloc/lesson_bloc.dart b/lib/pages/lessons/bloc/lesson_bloc.dart index 6645ca1..ac59ef4 100644 --- a/lib/pages/lessons/bloc/lesson_bloc.dart +++ b/lib/pages/lessons/bloc/lesson_bloc.dart @@ -1,6 +1,5 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:wow_english/common/request/dao/home_dao.dart'; import 'package:wow_english/common/request/exception.dart'; import 'package:wow_english/models/course_module_entity.dart'; @@ -10,6 +9,7 @@ part 'lesson_event.dart'; part 'lesson_state.dart'; class LessonBloc extends Bloc { + final int pageIndex; final PageController pageController; @@ -22,7 +22,7 @@ class LessonBloc extends Bloc { List get listData => _listData; - LessonBloc(this.pageIndex, this.pageController) : super(LessonInitial()) { + LessonBloc(this.pageIndex,this.pageController) : super(LessonInitial()) { _currentPageIndex = pageIndex; on(_pageIndexChange); } @@ -30,21 +30,17 @@ class LessonBloc extends Bloc { Future requestData() async { try { await loading(() async { - var list = await HomeDao.courseModule(); - if (list?.isNotEmpty == true) { - _listData = list!; - emit(LessonDataLoadState()); - } else { - EasyLoading.showToast("数据获取失败!"); - } + _listData = await HomeDao.courseModule()??[]; + emit(LessonDataLoadState()); }); } catch (e) { if (e is ApiException) { + } } } - void _pageIndexChange(PageViewChangeIndexEvent event, Emitter emitter) async { + void _pageIndexChange(PageViewChangeIndexEvent event,Emitter emitter) async { _currentPageIndex = event.index; emitter(PageIndexChangeState()); } diff --git a/lib/pages/lessons/lesson_page.dart b/lib/pages/lessons/lesson_page.dart index fb5c4fa..24302f3 100644 --- a/lib/pages/lessons/lesson_page.dart +++ b/lib/pages/lessons/lesson_page.dart @@ -4,6 +4,8 @@ import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:wow_english/common/extension/string_extension.dart'; import 'package:wow_english/common/widgets/we_app_bar.dart'; +import 'package:wow_english/models/course_module_entity.dart'; +import 'package:wow_english/route/route.dart'; import 'bloc/lesson_bloc.dart'; import 'widgets/lesson_item_widget.dart'; @@ -32,8 +34,6 @@ class _LessonPageView extends StatelessWidget { final double _cardHeight = 240.h; - final double _numItemHeight = 32.0; - final double _scale = 0.8; @override @@ -88,9 +88,9 @@ class _LessonPageView extends StatelessWidget { 32.verticalSpace, SizedBox( height: 32.h, - width: 660.w, + width: double.infinity, child: ListView.builder( - itemCount: 10, + itemCount: bloc.listData.length, scrollDirection: Axis.horizontal, itemBuilder: (BuildContext context,int index){ return Container( @@ -162,12 +162,18 @@ class _LessonPageView extends StatelessWidget { matrix4 = Matrix4.diagonal3Values(1.0, _scale, 1.0) ..setTranslationRaw(0.0, _cardHeight * (1 - _scale) / 2, 0.0); } - + CourseModuleEntity? model = bloc.listData[index]; return Transform( transform: matrix4, child: Padding( padding: const EdgeInsets.symmetric(horizontal: 10), - child: LessonItemWidget(isSelected: bloc.currentPageIndex == index), + child: LessonItemWidget( + model: model, + isSelected: bloc.currentPageIndex == index, + onClickEvent: () { + Navigator.of(context).pushNamedAndRemoveUntil(AppRouteName.home, (route) => false,arguments: {'moduleId':model?.id}); + }, + ), ), ); }); diff --git a/lib/pages/lessons/widgets/lesson_item_widget.dart b/lib/pages/lessons/widgets/lesson_item_widget.dart index f75319c..142ad4e 100644 --- a/lib/pages/lessons/widgets/lesson_item_widget.dart +++ b/lib/pages/lessons/widgets/lesson_item_widget.dart @@ -1,23 +1,38 @@ import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:wow_english/common/extension/string_extension.dart'; +import 'package:wow_english/models/course_module_entity.dart'; class LessonItemWidget extends StatelessWidget { - const LessonItemWidget({super.key, required this.isSelected}); + const LessonItemWidget({super.key, required this.isSelected, this.model, this.onClickEvent}); ///是否被选中 final bool isSelected; + final CourseModuleEntity? model; + final Function()? onClickEvent; @override Widget build(BuildContext context) { - return isSelected?_selectWidget():_unSelectWidget(); + return GestureDetector( + onTap: () { + if (!isSelected) { + return; + } + onClickEvent?.call(); + }, + child: isSelected?_selectWidget():_unSelectWidget(), + ); } Widget _unSelectWidget() { return Container( - decoration: const BoxDecoration( + decoration: BoxDecoration( image: DecorationImage( - image: NetworkImage('https://img.liblibai.com/web/648331d033b41.png?image_process=format,webp&x-oss-process=image/resize,w_2980,m_lfit/format,webp'), + image: AssetImage('gendubeij'.assetPng) ) ), + child: Image.network( + model?.picUrl??'', + ), ); } @@ -25,28 +40,30 @@ class LessonItemWidget extends StatelessWidget { return Container( padding: const EdgeInsets.all(10), decoration: BoxDecoration( - border: Border.all( - width: 2.0, - color: Colors.red, - style: BorderStyle.solid - ), + image: DecorationImage( + image: AssetImage('gendubeij'.assetPng) + ) ), child: Column( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Expanded( child: Image.network( - 'https://img.liblibai.com/web/648331d5a2cb5.png?image_process=format,webp&x-oss-process=image/resize,w_2980,m_lfit/format,webp', + model?.picUrl??'', + fit: BoxFit.contain ), ), 10.verticalSpace, Container( color: Colors.red, - width: double.infinity, - child: const Column( + padding: EdgeInsets.symmetric(horizontal: 10.w), + child: Column( children: [ - Text('red'), - Text('第三段') + Text(model?.name??''), + Text( + model?.des??'', + maxLines: 1, + ) ], ), ) diff --git a/lib/route/route.dart b/lib/route/route.dart index 0842221..e8ffe60 100644 --- a/lib/route/route.dart +++ b/lib/route/route.dart @@ -61,7 +61,11 @@ class AppRouter { case AppRouteName.login: return CupertinoPageRoute(builder: (_) => const LoginPage()); case AppRouteName.home: - return CupertinoPageRoute(builder: (_) => const HomePage()); + var moduleId = ''; + if (settings.arguments != null) { + moduleId = (settings.arguments as Map)['moduleId'] as String; + } + return CupertinoPageRoute(builder: (_) => HomePage(moduleId: moduleId,)); case AppRouteName.fogPwd: return CupertinoPageRoute(builder: (_) => const ForgetPasswordHomePage()); case AppRouteName.lesson: