diff --git a/lib/common/request/apis.dart b/lib/common/request/apis.dart index d63624a..c57c30b 100644 --- a/lib/common/request/apis.dart +++ b/lib/common/request/apis.dart @@ -22,4 +22,24 @@ class Apis { // GET /home/courseLesson // 接口地址:https://app.apifox.com/link/project/2684751/apis/api-89897662 static const String courseLesson = 'home/courseLesson'; + + /// 磨耳朵 + /// GET + static const String ears = '/course/grinding/ears'; + + /// 视频跟读 + /// GET + static const String followRead = '/course/video/follow/read'; + + /// 视频跟读内容 + /// GET + static const String readContent = '/course/video/follow/read/content'; + + /// 视频跟读提交结果 + /// POST + static const String followResult = '/course/submit/follow/result'; + + /// 获取课程内容 + /// GET + static const String process = '/course/process'; } diff --git a/lib/common/request/dao/home_dao.dart b/lib/common/request/dao/home_dao.dart index dc73962..af37f82 100644 --- a/lib/common/request/dao/home_dao.dart +++ b/lib/common/request/dao/home_dao.dart @@ -3,14 +3,14 @@ import 'package:wow_english/common/request/request_client.dart'; class HomeDao { ///获取课程模块信息 - static Future courseModule() async { - var data = requestClient.get(Apis.courseModule); + static Future?> courseModule() async { + var data = await requestClient.get?>(Apis.courseModule); return data; } ///课程列表 static Future courseLesson() async { - var data = requestClient.get(Apis.courseLesson); + var data = await requestClient.get(Apis.courseLesson); return data; } } diff --git a/lib/common/request/dao/listen_dao.dart b/lib/common/request/dao/listen_dao.dart new file mode 100644 index 0000000..4745e02 --- /dev/null +++ b/lib/common/request/dao/listen_dao.dart @@ -0,0 +1,10 @@ +import 'package:wow_english/common/request/apis.dart'; +import 'package:wow_english/common/request/request_client.dart'; + +class ListenDao { + /// 磨耳朵 + static Future listen() async { + var data = await requestClient.get(Apis.ears); + return data; + } +} \ No newline at end of file diff --git a/lib/generated/json/base/json_convert_content.dart b/lib/generated/json/base/json_convert_content.dart index 26eff33..ce90351 100644 --- a/lib/generated/json/base/json_convert_content.dart +++ b/lib/generated/json/base/json_convert_content.dart @@ -4,6 +4,8 @@ // 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/lesson_entity.dart'; +import 'package:wow_english/models/listen_entity.dart'; import 'package:wow_english/models/user_entity.dart'; JsonConvert jsonConvert = JsonConvert(); @@ -12,6 +14,8 @@ typedef EnumConvertFunction = T Function(String value); class JsonConvert { static final Map convertFuncMap = { + (LessonEntity).toString(): LessonEntity.fromJson, + (ListenEntity).toString(): ListenEntity.fromJson, (UserEntity).toString(): UserEntity.fromJson, }; @@ -91,12 +95,18 @@ List? convertListNotNull(dynamic value, {EnumConvertFunction? enumConvert} //list is returned by type static M? _getListChildType(List> data) { + if([] is M){ + return data.map((Map e) => LessonEntity.fromJson(e)).toList() as M; + } + if([] is M){ + return data.map((Map e) => ListenEntity.fromJson(e)).toList() as M; + } if([] is M){ return data.map((Map e) => UserEntity.fromJson(e)).toList() as M; } debugPrint("${M.toString()} not found"); - + return null; } @@ -107,4 +117,4 @@ List? convertListNotNull(dynamic value, {EnumConvertFunction? enumConvert} return jsonConvert.convert(json); } } -} +} \ No newline at end of file diff --git a/lib/generated/json/base/json_field.dart b/lib/generated/json/base/json_field.dart index 39f3c15..a2fcac9 100644 --- a/lib/generated/json/base/json_field.dart +++ b/lib/generated/json/base/json_field.dart @@ -14,12 +14,12 @@ class JSONField { //Whether to participate in toJson final bool? serialize; - + //Whether to participate in fromMap final bool? deserialize; - + //Enumeration or not final bool? isEnum; - + const JSONField({this.name, this.serialize, this.deserialize, this.isEnum}); } diff --git a/lib/generated/json/lesson_entity.g.dart b/lib/generated/json/lesson_entity.g.dart new file mode 100644 index 0000000..f4a3cc4 --- /dev/null +++ b/lib/generated/json/lesson_entity.g.dart @@ -0,0 +1,82 @@ +import 'package:wow_english/generated/json/base/json_convert_content.dart'; +import 'package:wow_english/models/lesson_entity.dart'; + +LessonEntity $LessonEntityFromJson(Map json) { + final LessonEntity lessonEntity = LessonEntity(); + final String? code = jsonConvert.convert(json['code']); + if (code != null) { + lessonEntity.code = code; + } + final int? courseModuleThemeId = jsonConvert.convert(json['courseModuleThemeId']); + if (courseModuleThemeId != null) { + lessonEntity.courseModuleThemeId = courseModuleThemeId; + } + final int? courseTotal = jsonConvert.convert(json['courseTotal']); + if (courseTotal != null) { + lessonEntity.courseTotal = courseTotal; + } + final String? coverUrl = jsonConvert.convert(json['coverUrl']); + if (coverUrl != null) { + lessonEntity.coverUrl = coverUrl; + } + final String? createTime = jsonConvert.convert(json['createTime']); + if (createTime != null) { + lessonEntity.createTime = createTime; + } + final String? deleted = jsonConvert.convert(json['deleted']); + if (deleted != null) { + lessonEntity.deleted = deleted; + } + final String? des = jsonConvert.convert(json['des']); + if (des != null) { + lessonEntity.des = des; + } + final String? id = jsonConvert.convert(json['id']); + if (id != null) { + lessonEntity.id = id; + } + final String? modifyTime = jsonConvert.convert(json['modifyTime']); + if (modifyTime != null) { + lessonEntity.modifyTime = modifyTime; + } + final String? name = jsonConvert.convert(json['name']); + if (name != null) { + lessonEntity.name = name; + } + final int? opening = jsonConvert.convert(json['opening']); + if (opening != null) { + lessonEntity.opening = opening; + } + final String? picUrl = jsonConvert.convert(json['picUrl']); + if (picUrl != null) { + lessonEntity.picUrl = picUrl; + } + final int? sortOrder = jsonConvert.convert(json['sortOrder']); + if (sortOrder != null) { + lessonEntity.sortOrder = sortOrder; + } + final int? status = jsonConvert.convert(json['status']); + if (status != null) { + lessonEntity.status = status; + } + return lessonEntity; +} + +Map $LessonEntityToJson(LessonEntity entity) { + final Map data = {}; + data['code'] = entity.code; + data['courseModuleThemeId'] = entity.courseModuleThemeId; + data['courseTotal'] = entity.courseTotal; + data['coverUrl'] = entity.coverUrl; + data['createTime'] = entity.createTime; + data['deleted'] = entity.deleted; + data['des'] = entity.des; + data['id'] = entity.id; + data['modifyTime'] = entity.modifyTime; + data['name'] = entity.name; + data['opening'] = entity.opening; + data['picUrl'] = entity.picUrl; + data['sortOrder'] = entity.sortOrder; + data['status'] = entity.status; + return data; +} \ No newline at end of file diff --git a/lib/generated/json/listen_entity.g.dart b/lib/generated/json/listen_entity.g.dart new file mode 100644 index 0000000..15509b7 --- /dev/null +++ b/lib/generated/json/listen_entity.g.dart @@ -0,0 +1,67 @@ +import 'package:wow_english/generated/json/base/json_convert_content.dart'; +import 'package:wow_english/models/listen_entity.dart'; + +ListenEntity $ListenEntityFromJson(Map json) { + final ListenEntity listenEntity = ListenEntity(); + final String? coverUrl = jsonConvert.convert(json['coverUrl']); + if (coverUrl != null) { + listenEntity.coverUrl = coverUrl; + } + final String? createTime = jsonConvert.convert(json['createTime']); + if (createTime != null) { + listenEntity.createTime = createTime; + } + final String? deleted = jsonConvert.convert(json['deleted']); + if (deleted != null) { + listenEntity.deleted = deleted; + } + final String? id = jsonConvert.convert(json['id']); + if (id != null) { + listenEntity.id = id; + } + final bool? lock = jsonConvert.convert(json['lock']); + if (lock != null) { + listenEntity.lock = lock; + } + final String? modifyTime = jsonConvert.convert(json['modifyTime']); + if (modifyTime != null) { + listenEntity.modifyTime = modifyTime; + } + final double? sortOrder = jsonConvert.convert(json['sortOrder']); + if (sortOrder != null) { + listenEntity.sortOrder = sortOrder; + } + final double? status = jsonConvert.convert(json['status']); + if (status != null) { + listenEntity.status = status; + } + final String? subtitleUrl = jsonConvert.convert(json['subtitleUrl']); + if (subtitleUrl != null) { + listenEntity.subtitleUrl = subtitleUrl; + } + final String? title = jsonConvert.convert(json['title']); + if (title != null) { + listenEntity.title = title; + } + final String? videoUrl = jsonConvert.convert(json['videoUrl']); + if (videoUrl != null) { + listenEntity.videoUrl = videoUrl; + } + return listenEntity; +} + +Map $ListenEntityToJson(ListenEntity entity) { + final Map data = {}; + data['coverUrl'] = entity.coverUrl; + data['createTime'] = entity.createTime; + data['deleted'] = entity.deleted; + data['id'] = entity.id; + data['lock'] = entity.lock; + data['modifyTime'] = entity.modifyTime; + data['sortOrder'] = entity.sortOrder; + data['status'] = entity.status; + data['subtitleUrl'] = entity.subtitleUrl; + data['title'] = entity.title; + data['videoUrl'] = entity.videoUrl; + return data; +} \ No newline at end of file diff --git a/lib/generated/json/user_entity.g.dart b/lib/generated/json/user_entity.g.dart index aee254e..2217112 100644 --- a/lib/generated/json/user_entity.g.dart +++ b/lib/generated/json/user_entity.g.dart @@ -49,4 +49,4 @@ Map $UserEntityToJson(UserEntity entity) { data['token'] = entity.token; data['expireTime'] = entity.expireTime; return data; -} +} \ No newline at end of file diff --git a/lib/models/lesson_entity.dart b/lib/models/lesson_entity.dart new file mode 100644 index 0000000..fd22125 --- /dev/null +++ b/lib/models/lesson_entity.dart @@ -0,0 +1,32 @@ +import 'package:wow_english/generated/json/base/json_field.dart'; +import 'package:wow_english/generated/json/lesson_entity.g.dart'; +import 'dart:convert'; + +@JsonSerializable() +class LessonEntity { + String? code; + int? courseModuleThemeId; + int? courseTotal; + String? coverUrl; + String? createTime; + String? deleted; + String? des; + String? id; + String? modifyTime; + String? name; + int? opening; + String? picUrl; + int? sortOrder; + int? status; + + LessonEntity(); + + factory LessonEntity.fromJson(Map json) => $LessonEntityFromJson(json); + + Map toJson() => $LessonEntityToJson(this); + + @override + String toString() { + return jsonEncode(this); + } +} \ No newline at end of file diff --git a/lib/models/listen_entity.dart b/lib/models/listen_entity.dart new file mode 100644 index 0000000..b8eb8b5 --- /dev/null +++ b/lib/models/listen_entity.dart @@ -0,0 +1,29 @@ +import 'package:wow_english/generated/json/base/json_field.dart'; +import 'package:wow_english/generated/json/listen_entity.g.dart'; +import 'dart:convert'; + +@JsonSerializable() +class ListenEntity { + String? coverUrl; + String? createTime; + String? deleted; + String? id; + bool? lock; + String? modifyTime; + double? sortOrder; + double? status; + String? subtitleUrl; + String? title; + String? videoUrl; + + ListenEntity(); + + factory ListenEntity.fromJson(Map json) => $ListenEntityFromJson(json); + + Map toJson() => $ListenEntityToJson(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 b3a0880..501d81d 100644 --- a/lib/pages/home/bloc/home_bloc.dart +++ b/lib/pages/home/bloc/home_bloc.dart @@ -1,5 +1,6 @@ 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/utils/loading.dart'; @@ -9,9 +10,7 @@ part 'home_state.dart'; class HomeBloc extends Bloc { HomeBloc() : super(HomeInitial()) { - on((event, emit) { - // TODO: implement event handler - }); + on(_requestData); } Future requestData() async { @@ -22,8 +21,22 @@ class HomeBloc extends Bloc { }); } catch (e) { if (e is ApiException) { + EasyLoading.showToast(e.message.toString()); + } + } + } + void _requestData(RequestDataEvent event, Emitter emitter) async { + try { + await loading(() async { + HomeDao.courseLesson(); + emitter(HomeDataLoadState()); + }); + } catch (e) { + if (e is ApiException) { + EasyLoading.showToast(e.message.toString()); } } } } + diff --git a/lib/pages/home/bloc/home_event.dart b/lib/pages/home/bloc/home_event.dart index 33589ea..7717d15 100644 --- a/lib/pages/home/bloc/home_event.dart +++ b/lib/pages/home/bloc/home_event.dart @@ -2,3 +2,5 @@ part of 'home_bloc.dart'; @immutable abstract class HomeEvent {} + +class RequestDataEvent extends HomeEvent {} diff --git a/lib/pages/lessons/bloc/lesson_bloc.dart b/lib/pages/lessons/bloc/lesson_bloc.dart index a14f013..914f2e0 100644 --- a/lib/pages/lessons/bloc/lesson_bloc.dart +++ b/lib/pages/lessons/bloc/lesson_bloc.dart @@ -1,7 +1,11 @@ +import 'dart:convert'; + import 'package:flutter/cupertino.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:wow_english/common/request/dao/home_dao.dart'; import 'package:wow_english/common/request/exception.dart'; +import 'package:wow_english/models/lesson_entity.dart'; import 'package:wow_english/utils/loading.dart'; part 'lesson_event.dart'; @@ -17,6 +21,9 @@ class LessonBloc extends Bloc { int get currentPageIndex => _currentPageIndex; + List _listData = []; + List get listData => _listData; + LessonBloc(this.pageIndex,this.pageController) : super(LessonInitial()) { _currentPageIndex = pageIndex; on(_pageIndexChange); @@ -25,7 +32,13 @@ class LessonBloc extends Bloc { Future requestData() async { try { await loading(() async { - HomeDao.courseModule(); + List list = await HomeDao.courseModule()??[]; + // if (list.isNotEmpty) { + // for (dynamic jsonStr in list) { + // LessonEntity? data = LessonEntity.fromJson(jsonStr); + // _listData.add(data); + // } + // } emit(LessonDataLoadState()); }); } catch (e) { diff --git a/lib/pages/lessons/lesson_page.dart b/lib/pages/lessons/lesson_page.dart index 9a3d294..fb5c4fa 100644 --- a/lib/pages/lessons/lesson_page.dart +++ b/lib/pages/lessons/lesson_page.dart @@ -77,7 +77,7 @@ class _LessonPageView extends StatelessWidget { SizedBox( height: _cardHeight, child: PageView.builder( - itemCount: 10, + itemCount: bloc.listData.length, controller: bloc.pageController, onPageChanged: (int index) { bloc.add(PageViewChangeIndexEvent(index)); @@ -125,14 +125,6 @@ class _LessonPageView extends StatelessWidget { ), ); }), - // child: PageView.builder( - // itemCount: 10, - // controller: bloc.pageController, - // onPageChanged: (int index) { - // bloc.add(PageViewChangeIndexEvent(index)); - // }, - // itemBuilder: (context,index) => _itemNumCard(index) - // ), ) ], ), @@ -179,44 +171,4 @@ class _LessonPageView extends StatelessWidget { ), ); }); - - Widget _itemNumCard(int index) => BlocBuilder( - builder: (context, state) { - final bloc = BlocProvider.of(context); - bool isSelected = bloc.currentPageIndex.floor() == index; - Matrix4 matrix4 = Matrix4.identity(); - if (index == bloc.currentPageIndex.floor()) { - //当前的item - double currScale = (1 - (bloc.currentPageIndex - index) * (1 - _scale)).toDouble(); - var currTrans = _numItemHeight * (1 - currScale) / 2; - - matrix4 = Matrix4.diagonal3Values(1.0, currScale, 1.0) - ..setTranslationRaw(0.0, currTrans, 0.0); - } else if (index == bloc.currentPageIndex.floor() + 1) { - //右边的item - var currScale = _scale + (bloc.currentPageIndex - index + 1) * (1 - _scale); - var currTrans = _numItemHeight * (1 - currScale) / 2; - - matrix4 = Matrix4.diagonal3Values(1.0, currScale, 1.0) - ..setTranslationRaw(0.0, currTrans, 0.0); - } else if (index == bloc.currentPageIndex - 1) { - //左边 - var currScale = (1 - (bloc.currentPageIndex - index) * (1 - _scale)).toDouble(); - var currTrans = _numItemHeight * (1 - currScale) / 2; - - matrix4 = Matrix4.diagonal3Values(1.0, currScale, 1.0) - ..setTranslationRaw(0.0, currTrans, 0.0); - } else { - //其他,不在屏幕显示的item - matrix4 = Matrix4.diagonal3Values(1.0, _scale, 1.0) - ..setTranslationRaw(0.0, _numItemHeight * (1 - _scale) / 2, 0.0); - } - - return Transform( - transform: matrix4, - child: Container( - color: isSelected?Colors.red:Colors.yellow, - ), - ); - }); } \ No newline at end of file diff --git a/lib/pages/listen/bloc/listen_bloc.dart b/lib/pages/listen/bloc/listen_bloc.dart index cf2c7b6..4a23b46 100644 --- a/lib/pages/listen/bloc/listen_bloc.dart +++ b/lib/pages/listen/bloc/listen_bloc.dart @@ -1,14 +1,44 @@ +import 'dart:convert'; 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/listen_dao.dart'; +import 'package:wow_english/common/request/exception.dart'; +import 'package:wow_english/models/listen_entity.dart'; +import 'package:wow_english/utils/loading.dart'; part 'listen_event.dart'; part 'listen_state.dart'; class ListenBloc extends Bloc { + + final List _listData = []; + List get listData => _listData; + ListenBloc() : super(ListenInitial()) { on((event, emit) { // TODO: implement event handler }); } + + Future requestData() async { + try { + await loading(() async { + List list = await ListenDao.listen()??[]; + if (list.isNotEmpty) { + for (String jsonStr in list) { + ListenEntity? data = ListenEntity.fromJson(jsonDecode(jsonStr)); + _listData.add(data); + } + } + emit(RequestListenDataState()); + }); + } catch (e) { + if (e is ApiException) { + EasyLoading.showToast(e.message??'请求失败,请检查网络连接'); + } + } + } + } diff --git a/lib/pages/listen/bloc/listen_state.dart b/lib/pages/listen/bloc/listen_state.dart index dfb830f..9574743 100644 --- a/lib/pages/listen/bloc/listen_state.dart +++ b/lib/pages/listen/bloc/listen_state.dart @@ -4,3 +4,5 @@ part of 'listen_bloc.dart'; abstract class ListenState {} class ListenInitial extends ListenState {} + +class RequestListenDataState extends ListenState {} diff --git a/lib/pages/listen/listen_page.dart b/lib/pages/listen/listen_page.dart index e57725b..d252c00 100644 --- a/lib/pages/listen/listen_page.dart +++ b/lib/pages/listen/listen_page.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:wow_english/common/widgets/we_app_bar.dart'; +import 'package:wow_english/route/route.dart'; import 'bloc/listen_bloc.dart'; import 'widgets/listen_item_widget.dart'; @@ -12,7 +13,7 @@ class ListenPage extends StatelessWidget { @override Widget build(BuildContext context) { return BlocProvider( - create: (context) => ListenBloc(), + create: (context) => ListenBloc()..requestData(), child: _ListenPageView(), ); } @@ -37,15 +38,16 @@ class _ListenPageView extends StatelessWidget { Widget _listenView() => BlocBuilder( builder: (context, state) { + final bloc = BlocProvider.of(context); return ListView.builder( - itemCount: 10, + itemCount: bloc.listData.length, scrollDirection: Axis.horizontal, padding: EdgeInsets.symmetric(horizontal: 30.w,vertical: 36.h), itemBuilder: (BuildContext context,int index){ return ListenItemWidget( - isLock: (index < 5), + isLock: (index > 5), clickEvent: (){ - + Navigator.of(context).pushNamed(AppRouteName.lookVideo,arguments: {'videoUrl':'https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/7194236f31b2e1e3da0fe06cfed4ba2b.mp4'}); }); }); }); diff --git a/lib/pages/listen/widgets/listen_item_widget.dart b/lib/pages/listen/widgets/listen_item_widget.dart index 3f73252..374fbf6 100644 --- a/lib/pages/listen/widgets/listen_item_widget.dart +++ b/lib/pages/listen/widgets/listen_item_widget.dart @@ -32,16 +32,16 @@ class ListenItemWidget extends StatelessWidget { width: 180.h, fit: BoxFit.fill, ), - Offstage( - offstage: isLock, + Visibility( + visible: isLock, child: Container( height: 180.h, width: 180.h, color: const Color.fromRGBO(1, 1, 0, 0.5), ), ), - Offstage( - offstage: isLock, + Visibility( + visible: isLock, child: Image.asset( 'listen_lock'.assetPng, height: 36.h, diff --git a/lib/pages/video/lookvideo/look_video_page.dart b/lib/pages/video/lookvideo/look_video_page.dart index 44fc455..716cfec 100644 --- a/lib/pages/video/lookvideo/look_video_page.dart +++ b/lib/pages/video/lookvideo/look_video_page.dart @@ -5,7 +5,9 @@ import 'package:wow_english/pages/video/lookvideo/widgets/video_widget.dart'; import 'bloc/look_video_bloc.dart'; class LookVideoPage extends StatefulWidget { - const LookVideoPage({super.key}); + const LookVideoPage({super.key, this.videoUrl}); + + final String? videoUrl; @override State createState() { @@ -16,8 +18,8 @@ class LookVideoPage extends StatefulWidget { class _LookVideoPageState extends State { @override Widget build(BuildContext context) { - return const VideoWidget( - videoUrl: 'https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/7194236f31b2e1e3da0fe06cfed4ba2b.mp4', + return VideoWidget( + videoUrl: widget.videoUrl??'', ); } } diff --git a/lib/route/route.dart b/lib/route/route.dart index 0d665c6..0842221 100644 --- a/lib/route/route.dart +++ b/lib/route/route.dart @@ -89,7 +89,8 @@ class AppRouter { case AppRouteName.voiceAnswer: return CupertinoPageRoute(builder: (_) => const VoiceAnswerPage()); case AppRouteName.lookVideo: - return CupertinoPageRoute(builder: (_) => const LookVideoPage()); + final videoUrl = (settings.arguments as Map)['videoUrl'] as String; + return CupertinoPageRoute(builder: (_) => LookVideoPage(videoUrl: videoUrl,)); case AppRouteName.setPwd: final phoneNum = (settings.arguments as Map)['phoneNumber'] as String; return CupertinoPageRoute(builder: (_) => SetPassWordPage(phoneNum: phoneNum));