Commit 993c1a046153fdc4ff0eca8a9188456b17ac25a4

Authored by liangchengyou
1 parent 13e6d11d

feat:添加数据模型

lib/common/request/apis.dart
@@ -22,4 +22,24 @@ class Apis { @@ -22,4 +22,24 @@ class Apis {
22 // GET /home/courseLesson 22 // GET /home/courseLesson
23 // 接口地址:https://app.apifox.com/link/project/2684751/apis/api-89897662 23 // 接口地址:https://app.apifox.com/link/project/2684751/apis/api-89897662
24 static const String courseLesson = 'home/courseLesson'; 24 static const String courseLesson = 'home/courseLesson';
  25 +
  26 + /// 磨耳朵
  27 + /// GET
  28 + static const String ears = '/course/grinding/ears';
  29 +
  30 + /// 视频跟读
  31 + /// GET
  32 + static const String followRead = '/course/video/follow/read';
  33 +
  34 + /// 视频跟读内容
  35 + /// GET
  36 + static const String readContent = '/course/video/follow/read/content';
  37 +
  38 + /// 视频跟读提交结果
  39 + /// POST
  40 + static const String followResult = '/course/submit/follow/result';
  41 +
  42 + /// 获取课程内容
  43 + /// GET
  44 + static const String process = '/course/process';
25 } 45 }
lib/common/request/dao/home_dao.dart
@@ -3,14 +3,14 @@ import 'package:wow_english/common/request/request_client.dart'; @@ -3,14 +3,14 @@ import 'package:wow_english/common/request/request_client.dart';
3 3
4 class HomeDao { 4 class HomeDao {
5 ///获取课程模块信息 5 ///获取课程模块信息
6 - static Future courseModule() async {  
7 - var data = requestClient.get(Apis.courseModule); 6 + static Future<List<dynamic>?> courseModule() async {
  7 + var data = await requestClient.get<List<dynamic>?>(Apis.courseModule);
8 return data; 8 return data;
9 } 9 }
10 10
11 ///课程列表 11 ///课程列表
12 static Future courseLesson() async { 12 static Future courseLesson() async {
13 - var data = requestClient.get(Apis.courseLesson); 13 + var data = await requestClient.get(Apis.courseLesson);
14 return data; 14 return data;
15 } 15 }
16 } 16 }
lib/common/request/dao/listen_dao.dart 0 → 100644
  1 +import 'package:wow_english/common/request/apis.dart';
  2 +import 'package:wow_english/common/request/request_client.dart';
  3 +
  4 +class ListenDao {
  5 + /// 磨耳朵
  6 + static Future listen() async {
  7 + var data = await requestClient.get(Apis.ears);
  8 + return data;
  9 + }
  10 +}
0 \ No newline at end of file 11 \ No newline at end of file
lib/generated/json/base/json_convert_content.dart
@@ -4,6 +4,8 @@ @@ -4,6 +4,8 @@
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/lesson_entity.dart';
  8 +import 'package:wow_english/models/listen_entity.dart';
7 import 'package:wow_english/models/user_entity.dart'; 9 import 'package:wow_english/models/user_entity.dart';
8 10
9 JsonConvert jsonConvert = JsonConvert(); 11 JsonConvert jsonConvert = JsonConvert();
@@ -12,6 +14,8 @@ typedef EnumConvertFunction&lt;T&gt; = T Function(String value); @@ -12,6 +14,8 @@ typedef EnumConvertFunction&lt;T&gt; = T Function(String value);
12 14
13 class JsonConvert { 15 class JsonConvert {
14 static final Map<String, JsonConvertFunction> convertFuncMap = { 16 static final Map<String, JsonConvertFunction> convertFuncMap = {
  17 + (LessonEntity).toString(): LessonEntity.fromJson,
  18 + (ListenEntity).toString(): ListenEntity.fromJson,
15 (UserEntity).toString(): UserEntity.fromJson, 19 (UserEntity).toString(): UserEntity.fromJson,
16 }; 20 };
17 21
@@ -91,12 +95,18 @@ List&lt;T&gt;? convertListNotNull&lt;T&gt;(dynamic value, {EnumConvertFunction? enumConvert} @@ -91,12 +95,18 @@ List&lt;T&gt;? convertListNotNull&lt;T&gt;(dynamic value, {EnumConvertFunction? enumConvert}
91 95
92 //list is returned by type 96 //list is returned by type
93 static M? _getListChildType<M>(List<Map<String, dynamic>> data) { 97 static M? _getListChildType<M>(List<Map<String, dynamic>> data) {
  98 + if(<LessonEntity>[] is M){
  99 + return data.map<LessonEntity>((Map<String, dynamic> e) => LessonEntity.fromJson(e)).toList() as M;
  100 + }
  101 + if(<ListenEntity>[] is M){
  102 + return data.map<ListenEntity>((Map<String, dynamic> e) => ListenEntity.fromJson(e)).toList() as M;
  103 + }
94 if(<UserEntity>[] is M){ 104 if(<UserEntity>[] is M){
95 return data.map<UserEntity>((Map<String, dynamic> e) => UserEntity.fromJson(e)).toList() as M; 105 return data.map<UserEntity>((Map<String, dynamic> e) => UserEntity.fromJson(e)).toList() as M;
96 } 106 }
97 107
98 debugPrint("${M.toString()} not found"); 108 debugPrint("${M.toString()} not found");
99 - 109 +
100 return null; 110 return null;
101 } 111 }
102 112
@@ -107,4 +117,4 @@ List&lt;T&gt;? convertListNotNull&lt;T&gt;(dynamic value, {EnumConvertFunction? enumConvert} @@ -107,4 +117,4 @@ List&lt;T&gt;? convertListNotNull&lt;T&gt;(dynamic value, {EnumConvertFunction? enumConvert}
107 return jsonConvert.convert<M>(json); 117 return jsonConvert.convert<M>(json);
108 } 118 }
109 } 119 }
110 -} 120 -}
  121 +}
111 \ No newline at end of file 122 \ No newline at end of file
lib/generated/json/base/json_field.dart
@@ -14,12 +14,12 @@ class JSONField { @@ -14,12 +14,12 @@ class JSONField {
14 14
15 //Whether to participate in toJson 15 //Whether to participate in toJson
16 final bool? serialize; 16 final bool? serialize;
17 - 17 +
18 //Whether to participate in fromMap 18 //Whether to participate in fromMap
19 final bool? deserialize; 19 final bool? deserialize;
20 - 20 +
21 //Enumeration or not 21 //Enumeration or not
22 final bool? isEnum; 22 final bool? isEnum;
23 - 23 +
24 const JSONField({this.name, this.serialize, this.deserialize, this.isEnum}); 24 const JSONField({this.name, this.serialize, this.deserialize, this.isEnum});
25 } 25 }
lib/generated/json/lesson_entity.g.dart 0 → 100644
  1 +import 'package:wow_english/generated/json/base/json_convert_content.dart';
  2 +import 'package:wow_english/models/lesson_entity.dart';
  3 +
  4 +LessonEntity $LessonEntityFromJson(Map<String, dynamic> json) {
  5 + final LessonEntity lessonEntity = LessonEntity();
  6 + final String? code = jsonConvert.convert<String>(json['code']);
  7 + if (code != null) {
  8 + lessonEntity.code = code;
  9 + }
  10 + final int? courseModuleThemeId = jsonConvert.convert<int>(json['courseModuleThemeId']);
  11 + if (courseModuleThemeId != null) {
  12 + lessonEntity.courseModuleThemeId = courseModuleThemeId;
  13 + }
  14 + final int? courseTotal = jsonConvert.convert<int>(json['courseTotal']);
  15 + if (courseTotal != null) {
  16 + lessonEntity.courseTotal = courseTotal;
  17 + }
  18 + final String? coverUrl = jsonConvert.convert<String>(json['coverUrl']);
  19 + if (coverUrl != null) {
  20 + lessonEntity.coverUrl = coverUrl;
  21 + }
  22 + final String? createTime = jsonConvert.convert<String>(json['createTime']);
  23 + if (createTime != null) {
  24 + lessonEntity.createTime = createTime;
  25 + }
  26 + final String? deleted = jsonConvert.convert<String>(json['deleted']);
  27 + if (deleted != null) {
  28 + lessonEntity.deleted = deleted;
  29 + }
  30 + final String? des = jsonConvert.convert<String>(json['des']);
  31 + if (des != null) {
  32 + lessonEntity.des = des;
  33 + }
  34 + final String? id = jsonConvert.convert<String>(json['id']);
  35 + if (id != null) {
  36 + lessonEntity.id = id;
  37 + }
  38 + final String? modifyTime = jsonConvert.convert<String>(json['modifyTime']);
  39 + if (modifyTime != null) {
  40 + lessonEntity.modifyTime = modifyTime;
  41 + }
  42 + final String? name = jsonConvert.convert<String>(json['name']);
  43 + if (name != null) {
  44 + lessonEntity.name = name;
  45 + }
  46 + final int? opening = jsonConvert.convert<int>(json['opening']);
  47 + if (opening != null) {
  48 + lessonEntity.opening = opening;
  49 + }
  50 + final String? picUrl = jsonConvert.convert<String>(json['picUrl']);
  51 + if (picUrl != null) {
  52 + lessonEntity.picUrl = picUrl;
  53 + }
  54 + final int? sortOrder = jsonConvert.convert<int>(json['sortOrder']);
  55 + if (sortOrder != null) {
  56 + lessonEntity.sortOrder = sortOrder;
  57 + }
  58 + final int? status = jsonConvert.convert<int>(json['status']);
  59 + if (status != null) {
  60 + lessonEntity.status = status;
  61 + }
  62 + return lessonEntity;
  63 +}
  64 +
  65 +Map<String, dynamic> $LessonEntityToJson(LessonEntity entity) {
  66 + final Map<String, dynamic> data = <String, dynamic>{};
  67 + data['code'] = entity.code;
  68 + data['courseModuleThemeId'] = entity.courseModuleThemeId;
  69 + data['courseTotal'] = entity.courseTotal;
  70 + data['coverUrl'] = entity.coverUrl;
  71 + data['createTime'] = entity.createTime;
  72 + data['deleted'] = entity.deleted;
  73 + data['des'] = entity.des;
  74 + data['id'] = entity.id;
  75 + data['modifyTime'] = entity.modifyTime;
  76 + data['name'] = entity.name;
  77 + data['opening'] = entity.opening;
  78 + data['picUrl'] = entity.picUrl;
  79 + data['sortOrder'] = entity.sortOrder;
  80 + data['status'] = entity.status;
  81 + return data;
  82 +}
0 \ No newline at end of file 83 \ No newline at end of file
lib/generated/json/listen_entity.g.dart 0 → 100644
  1 +import 'package:wow_english/generated/json/base/json_convert_content.dart';
  2 +import 'package:wow_english/models/listen_entity.dart';
  3 +
  4 +ListenEntity $ListenEntityFromJson(Map<String, dynamic> json) {
  5 + final ListenEntity listenEntity = ListenEntity();
  6 + final String? coverUrl = jsonConvert.convert<String>(json['coverUrl']);
  7 + if (coverUrl != null) {
  8 + listenEntity.coverUrl = coverUrl;
  9 + }
  10 + final String? createTime = jsonConvert.convert<String>(json['createTime']);
  11 + if (createTime != null) {
  12 + listenEntity.createTime = createTime;
  13 + }
  14 + final String? deleted = jsonConvert.convert<String>(json['deleted']);
  15 + if (deleted != null) {
  16 + listenEntity.deleted = deleted;
  17 + }
  18 + final String? id = jsonConvert.convert<String>(json['id']);
  19 + if (id != null) {
  20 + listenEntity.id = id;
  21 + }
  22 + final bool? lock = jsonConvert.convert<bool>(json['lock']);
  23 + if (lock != null) {
  24 + listenEntity.lock = lock;
  25 + }
  26 + final String? modifyTime = jsonConvert.convert<String>(json['modifyTime']);
  27 + if (modifyTime != null) {
  28 + listenEntity.modifyTime = modifyTime;
  29 + }
  30 + final double? sortOrder = jsonConvert.convert<double>(json['sortOrder']);
  31 + if (sortOrder != null) {
  32 + listenEntity.sortOrder = sortOrder;
  33 + }
  34 + final double? status = jsonConvert.convert<double>(json['status']);
  35 + if (status != null) {
  36 + listenEntity.status = status;
  37 + }
  38 + final String? subtitleUrl = jsonConvert.convert<String>(json['subtitleUrl']);
  39 + if (subtitleUrl != null) {
  40 + listenEntity.subtitleUrl = subtitleUrl;
  41 + }
  42 + final String? title = jsonConvert.convert<String>(json['title']);
  43 + if (title != null) {
  44 + listenEntity.title = title;
  45 + }
  46 + final String? videoUrl = jsonConvert.convert<String>(json['videoUrl']);
  47 + if (videoUrl != null) {
  48 + listenEntity.videoUrl = videoUrl;
  49 + }
  50 + return listenEntity;
  51 +}
  52 +
  53 +Map<String, dynamic> $ListenEntityToJson(ListenEntity entity) {
  54 + final Map<String, dynamic> data = <String, dynamic>{};
  55 + data['coverUrl'] = entity.coverUrl;
  56 + data['createTime'] = entity.createTime;
  57 + data['deleted'] = entity.deleted;
  58 + data['id'] = entity.id;
  59 + data['lock'] = entity.lock;
  60 + data['modifyTime'] = entity.modifyTime;
  61 + data['sortOrder'] = entity.sortOrder;
  62 + data['status'] = entity.status;
  63 + data['subtitleUrl'] = entity.subtitleUrl;
  64 + data['title'] = entity.title;
  65 + data['videoUrl'] = entity.videoUrl;
  66 + return data;
  67 +}
0 \ No newline at end of file 68 \ No newline at end of file
lib/generated/json/user_entity.g.dart
@@ -49,4 +49,4 @@ Map&lt;String, dynamic&gt; $UserEntityToJson(UserEntity entity) { @@ -49,4 +49,4 @@ Map&lt;String, dynamic&gt; $UserEntityToJson(UserEntity entity) {
49 data['token'] = entity.token; 49 data['token'] = entity.token;
50 data['expireTime'] = entity.expireTime; 50 data['expireTime'] = entity.expireTime;
51 return data; 51 return data;
52 -} 52 -}
  53 +}
53 \ No newline at end of file 54 \ No newline at end of file
lib/models/lesson_entity.dart 0 → 100644
  1 +import 'package:wow_english/generated/json/base/json_field.dart';
  2 +import 'package:wow_english/generated/json/lesson_entity.g.dart';
  3 +import 'dart:convert';
  4 +
  5 +@JsonSerializable()
  6 +class LessonEntity {
  7 + String? code;
  8 + int? courseModuleThemeId;
  9 + int? courseTotal;
  10 + String? coverUrl;
  11 + String? createTime;
  12 + String? deleted;
  13 + String? des;
  14 + String? id;
  15 + String? modifyTime;
  16 + String? name;
  17 + int? opening;
  18 + String? picUrl;
  19 + int? sortOrder;
  20 + int? status;
  21 +
  22 + LessonEntity();
  23 +
  24 + factory LessonEntity.fromJson(Map<String, dynamic> json) => $LessonEntityFromJson(json);
  25 +
  26 + Map<String, dynamic> toJson() => $LessonEntityToJson(this);
  27 +
  28 + @override
  29 + String toString() {
  30 + return jsonEncode(this);
  31 + }
  32 +}
0 \ No newline at end of file 33 \ No newline at end of file
lib/models/listen_entity.dart 0 → 100644
  1 +import 'package:wow_english/generated/json/base/json_field.dart';
  2 +import 'package:wow_english/generated/json/listen_entity.g.dart';
  3 +import 'dart:convert';
  4 +
  5 +@JsonSerializable()
  6 +class ListenEntity {
  7 + String? coverUrl;
  8 + String? createTime;
  9 + String? deleted;
  10 + String? id;
  11 + bool? lock;
  12 + String? modifyTime;
  13 + double? sortOrder;
  14 + double? status;
  15 + String? subtitleUrl;
  16 + String? title;
  17 + String? videoUrl;
  18 +
  19 + ListenEntity();
  20 +
  21 + factory ListenEntity.fromJson(Map<String, dynamic> json) => $ListenEntityFromJson(json);
  22 +
  23 + Map<String, dynamic> toJson() => $ListenEntityToJson(this);
  24 +
  25 + @override
  26 + String toString() {
  27 + return jsonEncode(this);
  28 + }
  29 +}
0 \ No newline at end of file 30 \ No newline at end of file
lib/pages/home/bloc/home_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';
3 import 'package:wow_english/common/request/dao/home_dao.dart'; 4 import 'package:wow_english/common/request/dao/home_dao.dart';
4 import 'package:wow_english/common/request/exception.dart'; 5 import 'package:wow_english/common/request/exception.dart';
5 import 'package:wow_english/utils/loading.dart'; 6 import 'package:wow_english/utils/loading.dart';
@@ -9,9 +10,7 @@ part &#39;home_state.dart&#39;; @@ -9,9 +10,7 @@ part &#39;home_state.dart&#39;;
9 10
10 class HomeBloc extends Bloc<HomeEvent, HomeState> { 11 class HomeBloc extends Bloc<HomeEvent, HomeState> {
11 HomeBloc() : super(HomeInitial()) { 12 HomeBloc() : super(HomeInitial()) {
12 - on<HomeEvent>((event, emit) {  
13 - // TODO: implement event handler  
14 - }); 13 + on<RequestDataEvent>(_requestData);
15 } 14 }
16 15
17 Future<void> requestData() async { 16 Future<void> requestData() async {
@@ -22,8 +21,22 @@ class HomeBloc extends Bloc&lt;HomeEvent, HomeState&gt; { @@ -22,8 +21,22 @@ class HomeBloc extends Bloc&lt;HomeEvent, HomeState&gt; {
22 }); 21 });
23 } catch (e) { 22 } catch (e) {
24 if (e is ApiException) { 23 if (e is ApiException) {
  24 + EasyLoading.showToast(e.message.toString());
  25 + }
  26 + }
  27 + }
25 28
  29 + void _requestData(RequestDataEvent event, Emitter<HomeState> emitter) async {
  30 + try {
  31 + await loading(() async {
  32 + HomeDao.courseLesson();
  33 + emitter(HomeDataLoadState());
  34 + });
  35 + } catch (e) {
  36 + if (e is ApiException) {
  37 + EasyLoading.showToast(e.message.toString());
26 } 38 }
27 } 39 }
28 } 40 }
29 } 41 }
  42 +
lib/pages/home/bloc/home_event.dart
@@ -2,3 +2,5 @@ part of &#39;home_bloc.dart&#39;; @@ -2,3 +2,5 @@ part of &#39;home_bloc.dart&#39;;
2 2
3 @immutable 3 @immutable
4 abstract class HomeEvent {} 4 abstract class HomeEvent {}
  5 +
  6 +class RequestDataEvent extends HomeEvent {}
lib/pages/lessons/bloc/lesson_bloc.dart
  1 +import 'dart:convert';
  2 +
1 import 'package:flutter/cupertino.dart'; 3 import 'package:flutter/cupertino.dart';
  4 +import 'package:flutter/foundation.dart';
2 import 'package:flutter_bloc/flutter_bloc.dart'; 5 import 'package:flutter_bloc/flutter_bloc.dart';
3 import 'package:wow_english/common/request/dao/home_dao.dart'; 6 import 'package:wow_english/common/request/dao/home_dao.dart';
4 import 'package:wow_english/common/request/exception.dart'; 7 import 'package:wow_english/common/request/exception.dart';
  8 +import 'package:wow_english/models/lesson_entity.dart';
5 import 'package:wow_english/utils/loading.dart'; 9 import 'package:wow_english/utils/loading.dart';
6 10
7 part 'lesson_event.dart'; 11 part 'lesson_event.dart';
@@ -17,6 +21,9 @@ class LessonBloc extends Bloc&lt;LessonEvent, LessonState&gt; { @@ -17,6 +21,9 @@ class LessonBloc extends Bloc&lt;LessonEvent, LessonState&gt; {
17 21
18 int get currentPageIndex => _currentPageIndex; 22 int get currentPageIndex => _currentPageIndex;
19 23
  24 + List<LessonEntity?> _listData = [];
  25 + List<LessonEntity?> get listData => _listData;
  26 +
20 LessonBloc(this.pageIndex,this.pageController) : super(LessonInitial()) { 27 LessonBloc(this.pageIndex,this.pageController) : super(LessonInitial()) {
21 _currentPageIndex = pageIndex; 28 _currentPageIndex = pageIndex;
22 on<PageViewChangeIndexEvent>(_pageIndexChange); 29 on<PageViewChangeIndexEvent>(_pageIndexChange);
@@ -25,7 +32,13 @@ class LessonBloc extends Bloc&lt;LessonEvent, LessonState&gt; { @@ -25,7 +32,13 @@ class LessonBloc extends Bloc&lt;LessonEvent, LessonState&gt; {
25 Future<void> requestData() async { 32 Future<void> requestData() async {
26 try { 33 try {
27 await loading(() async { 34 await loading(() async {
28 - HomeDao.courseModule(); 35 + List list = await HomeDao.courseModule()??[];
  36 + // if (list.isNotEmpty) {
  37 + // for (dynamic jsonStr in list) {
  38 + // LessonEntity? data = LessonEntity.fromJson(jsonStr);
  39 + // _listData.add(data);
  40 + // }
  41 + // }
29 emit(LessonDataLoadState()); 42 emit(LessonDataLoadState());
30 }); 43 });
31 } catch (e) { 44 } catch (e) {
lib/pages/lessons/lesson_page.dart
@@ -77,7 +77,7 @@ class _LessonPageView extends StatelessWidget { @@ -77,7 +77,7 @@ class _LessonPageView extends StatelessWidget {
77 SizedBox( 77 SizedBox(
78 height: _cardHeight, 78 height: _cardHeight,
79 child: PageView.builder( 79 child: PageView.builder(
80 - itemCount: 10, 80 + itemCount: bloc.listData.length,
81 controller: bloc.pageController, 81 controller: bloc.pageController,
82 onPageChanged: (int index) { 82 onPageChanged: (int index) {
83 bloc.add(PageViewChangeIndexEvent(index)); 83 bloc.add(PageViewChangeIndexEvent(index));
@@ -125,14 +125,6 @@ class _LessonPageView extends StatelessWidget { @@ -125,14 +125,6 @@ class _LessonPageView extends StatelessWidget {
125 ), 125 ),
126 ); 126 );
127 }), 127 }),
128 - // child: PageView.builder(  
129 - // itemCount: 10,  
130 - // controller: bloc.pageController,  
131 - // onPageChanged: (int index) {  
132 - // bloc.add(PageViewChangeIndexEvent(index));  
133 - // },  
134 - // itemBuilder: (context,index) => _itemNumCard(index)  
135 - // ),  
136 ) 128 )
137 ], 129 ],
138 ), 130 ),
@@ -179,44 +171,4 @@ class _LessonPageView extends StatelessWidget { @@ -179,44 +171,4 @@ class _LessonPageView extends StatelessWidget {
179 ), 171 ),
180 ); 172 );
181 }); 173 });
182 -  
183 - Widget _itemNumCard(int index) => BlocBuilder<LessonBloc,LessonState>(  
184 - builder: (context, state) {  
185 - final bloc = BlocProvider.of<LessonBloc>(context);  
186 - bool isSelected = bloc.currentPageIndex.floor() == index;  
187 - Matrix4 matrix4 = Matrix4.identity();  
188 - if (index == bloc.currentPageIndex.floor()) {  
189 - //当前的item  
190 - double currScale = (1 - (bloc.currentPageIndex - index) * (1 - _scale)).toDouble();  
191 - var currTrans = _numItemHeight * (1 - currScale) / 2;  
192 -  
193 - matrix4 = Matrix4.diagonal3Values(1.0, currScale, 1.0)  
194 - ..setTranslationRaw(0.0, currTrans, 0.0);  
195 - } else if (index == bloc.currentPageIndex.floor() + 1) {  
196 - //右边的item  
197 - var currScale = _scale + (bloc.currentPageIndex - index + 1) * (1 - _scale);  
198 - var currTrans = _numItemHeight * (1 - currScale) / 2;  
199 -  
200 - matrix4 = Matrix4.diagonal3Values(1.0, currScale, 1.0)  
201 - ..setTranslationRaw(0.0, currTrans, 0.0);  
202 - } else if (index == bloc.currentPageIndex - 1) {  
203 - //左边  
204 - var currScale = (1 - (bloc.currentPageIndex - index) * (1 - _scale)).toDouble();  
205 - var currTrans = _numItemHeight * (1 - currScale) / 2;  
206 -  
207 - matrix4 = Matrix4.diagonal3Values(1.0, currScale, 1.0)  
208 - ..setTranslationRaw(0.0, currTrans, 0.0);  
209 - } else {  
210 - //其他,不在屏幕显示的item  
211 - matrix4 = Matrix4.diagonal3Values(1.0, _scale, 1.0)  
212 - ..setTranslationRaw(0.0, _numItemHeight * (1 - _scale) / 2, 0.0);  
213 - }  
214 -  
215 - return Transform(  
216 - transform: matrix4,  
217 - child: Container(  
218 - color: isSelected?Colors.red:Colors.yellow,  
219 - ),  
220 - );  
221 - });  
222 } 174 }
223 \ No newline at end of file 175 \ No newline at end of file
lib/pages/listen/bloc/listen_bloc.dart
  1 +import 'dart:convert';
1 2
2 import 'package:flutter/cupertino.dart'; 3 import 'package:flutter/cupertino.dart';
3 import 'package:flutter_bloc/flutter_bloc.dart'; 4 import 'package:flutter_bloc/flutter_bloc.dart';
  5 +import 'package:flutter_easyloading/flutter_easyloading.dart';
  6 +import 'package:wow_english/common/request/dao/listen_dao.dart';
  7 +import 'package:wow_english/common/request/exception.dart';
  8 +import 'package:wow_english/models/listen_entity.dart';
  9 +import 'package:wow_english/utils/loading.dart';
4 10
5 part 'listen_event.dart'; 11 part 'listen_event.dart';
6 part 'listen_state.dart'; 12 part 'listen_state.dart';
7 13
8 class ListenBloc extends Bloc<ListenEvent, ListenState> { 14 class ListenBloc extends Bloc<ListenEvent, ListenState> {
  15 +
  16 + final List<ListenEntity?> _listData = [];
  17 + List<ListenEntity?> get listData => _listData;
  18 +
9 ListenBloc() : super(ListenInitial()) { 19 ListenBloc() : super(ListenInitial()) {
10 on<ListenEvent>((event, emit) { 20 on<ListenEvent>((event, emit) {
11 // TODO: implement event handler 21 // TODO: implement event handler
12 }); 22 });
13 } 23 }
  24 +
  25 + Future<void> requestData() async {
  26 + try {
  27 + await loading(() async {
  28 + List<String> list = await ListenDao.listen()??[];
  29 + if (list.isNotEmpty) {
  30 + for (String jsonStr in list) {
  31 + ListenEntity? data = ListenEntity.fromJson(jsonDecode(jsonStr));
  32 + _listData.add(data);
  33 + }
  34 + }
  35 + emit(RequestListenDataState());
  36 + });
  37 + } catch (e) {
  38 + if (e is ApiException) {
  39 + EasyLoading.showToast(e.message??'请求失败,请检查网络连接');
  40 + }
  41 + }
  42 + }
  43 +
14 } 44 }
lib/pages/listen/bloc/listen_state.dart
@@ -4,3 +4,5 @@ part of &#39;listen_bloc.dart&#39;; @@ -4,3 +4,5 @@ part of &#39;listen_bloc.dart&#39;;
4 abstract class ListenState {} 4 abstract class ListenState {}
5 5
6 class ListenInitial extends ListenState {} 6 class ListenInitial extends ListenState {}
  7 +
  8 +class RequestListenDataState extends ListenState {}
lib/pages/listen/listen_page.dart
@@ -2,6 +2,7 @@ import &#39;package:flutter/material.dart&#39;; @@ -2,6 +2,7 @@ import &#39;package:flutter/material.dart&#39;;
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/widgets/we_app_bar.dart'; 4 import 'package:wow_english/common/widgets/we_app_bar.dart';
  5 +import 'package:wow_english/route/route.dart';
5 6
6 import 'bloc/listen_bloc.dart'; 7 import 'bloc/listen_bloc.dart';
7 import 'widgets/listen_item_widget.dart'; 8 import 'widgets/listen_item_widget.dart';
@@ -12,7 +13,7 @@ class ListenPage extends StatelessWidget { @@ -12,7 +13,7 @@ class ListenPage extends StatelessWidget {
12 @override 13 @override
13 Widget build(BuildContext context) { 14 Widget build(BuildContext context) {
14 return BlocProvider( 15 return BlocProvider(
15 - create: (context) => ListenBloc(), 16 + create: (context) => ListenBloc()..requestData(),
16 child: _ListenPageView(), 17 child: _ListenPageView(),
17 ); 18 );
18 } 19 }
@@ -37,15 +38,16 @@ class _ListenPageView extends StatelessWidget { @@ -37,15 +38,16 @@ class _ListenPageView extends StatelessWidget {
37 38
38 Widget _listenView() => BlocBuilder<ListenBloc, ListenState>( 39 Widget _listenView() => BlocBuilder<ListenBloc, ListenState>(
39 builder: (context, state) { 40 builder: (context, state) {
  41 + final bloc = BlocProvider.of<ListenBloc>(context);
40 return ListView.builder( 42 return ListView.builder(
41 - itemCount: 10, 43 + itemCount: bloc.listData.length,
42 scrollDirection: Axis.horizontal, 44 scrollDirection: Axis.horizontal,
43 padding: EdgeInsets.symmetric(horizontal: 30.w,vertical: 36.h), 45 padding: EdgeInsets.symmetric(horizontal: 30.w,vertical: 36.h),
44 itemBuilder: (BuildContext context,int index){ 46 itemBuilder: (BuildContext context,int index){
45 return ListenItemWidget( 47 return ListenItemWidget(
46 - isLock: (index < 5), 48 + isLock: (index > 5),
47 clickEvent: (){ 49 clickEvent: (){
48 - 50 + Navigator.of(context).pushNamed(AppRouteName.lookVideo,arguments: {'videoUrl':'https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/7194236f31b2e1e3da0fe06cfed4ba2b.mp4'});
49 }); 51 });
50 }); 52 });
51 }); 53 });
lib/pages/listen/widgets/listen_item_widget.dart
@@ -32,16 +32,16 @@ class ListenItemWidget extends StatelessWidget { @@ -32,16 +32,16 @@ class ListenItemWidget extends StatelessWidget {
32 width: 180.h, 32 width: 180.h,
33 fit: BoxFit.fill, 33 fit: BoxFit.fill,
34 ), 34 ),
35 - Offstage(  
36 - offstage: isLock, 35 + Visibility(
  36 + visible: isLock,
37 child: Container( 37 child: Container(
38 height: 180.h, 38 height: 180.h,
39 width: 180.h, 39 width: 180.h,
40 color: const Color.fromRGBO(1, 1, 0, 0.5), 40 color: const Color.fromRGBO(1, 1, 0, 0.5),
41 ), 41 ),
42 ), 42 ),
43 - Offstage(  
44 - offstage: isLock, 43 + Visibility(
  44 + visible: isLock,
45 child: Image.asset( 45 child: Image.asset(
46 'listen_lock'.assetPng, 46 'listen_lock'.assetPng,
47 height: 36.h, 47 height: 36.h,
lib/pages/video/lookvideo/look_video_page.dart
@@ -5,7 +5,9 @@ import &#39;package:wow_english/pages/video/lookvideo/widgets/video_widget.dart&#39;; @@ -5,7 +5,9 @@ import &#39;package:wow_english/pages/video/lookvideo/widgets/video_widget.dart&#39;;
5 import 'bloc/look_video_bloc.dart'; 5 import 'bloc/look_video_bloc.dart';
6 6
7 class LookVideoPage extends StatefulWidget { 7 class LookVideoPage extends StatefulWidget {
8 - const LookVideoPage({super.key}); 8 + const LookVideoPage({super.key, this.videoUrl});
  9 +
  10 + final String? videoUrl;
9 11
10 @override 12 @override
11 State<StatefulWidget> createState() { 13 State<StatefulWidget> createState() {
@@ -16,8 +18,8 @@ class LookVideoPage extends StatefulWidget { @@ -16,8 +18,8 @@ class LookVideoPage extends StatefulWidget {
16 class _LookVideoPageState extends State<LookVideoPage> { 18 class _LookVideoPageState extends State<LookVideoPage> {
17 @override 19 @override
18 Widget build(BuildContext context) { 20 Widget build(BuildContext context) {
19 - return const VideoWidget(  
20 - videoUrl: 'https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/7194236f31b2e1e3da0fe06cfed4ba2b.mp4', 21 + return VideoWidget(
  22 + videoUrl: widget.videoUrl??'',
21 ); 23 );
22 } 24 }
23 } 25 }
lib/route/route.dart
@@ -89,7 +89,8 @@ class AppRouter { @@ -89,7 +89,8 @@ class AppRouter {
89 case AppRouteName.voiceAnswer: 89 case AppRouteName.voiceAnswer:
90 return CupertinoPageRoute(builder: (_) => const VoiceAnswerPage()); 90 return CupertinoPageRoute(builder: (_) => const VoiceAnswerPage());
91 case AppRouteName.lookVideo: 91 case AppRouteName.lookVideo:
92 - return CupertinoPageRoute(builder: (_) => const LookVideoPage()); 92 + final videoUrl = (settings.arguments as Map)['videoUrl'] as String;
  93 + return CupertinoPageRoute(builder: (_) => LookVideoPage(videoUrl: videoUrl,));
93 case AppRouteName.setPwd: 94 case AppRouteName.setPwd:
94 final phoneNum = (settings.arguments as Map)['phoneNumber'] as String; 95 final phoneNum = (settings.arguments as Map)['phoneNumber'] as String;
95 return CupertinoPageRoute(builder: (_) => SetPassWordPage(phoneNum: phoneNum)); 96 return CupertinoPageRoute(builder: (_) => SetPassWordPage(phoneNum: phoneNum));