Commit 66a7e3e72c3c4e51c9848544ff0cc8b9202b828e

Authored by 吴启风
1 parent 22f36232

feat:退出课堂和结束课堂优化

lib/common/request/dao/listen_dao.dart
... ... @@ -15,43 +15,66 @@ class ListenDao {
15 15  
16 16 ///视频跟读
17 17 static Future<List<FollowReadEntity?>?> followRead() async {
18   - var data = await requestClient.get<List<FollowReadEntity?>>(Apis.followRead);
  18 + var data =
  19 + await requestClient.get<List<FollowReadEntity?>>(Apis.followRead);
19 20 return data;
20 21 }
21 22  
22 23 ///课程内容
23 24 static Future<CourseProcessEntity?> process(courseLessonId) async {
24   - var data = await requestClient.get<CourseProcessEntity>(Apis.process,queryParameters: {'courseLessonId':courseLessonId});
  25 + var data = await requestClient.get<CourseProcessEntity>(Apis.process,
  26 + queryParameters: {'courseLessonId': courseLessonId});
25 27 return data;
26 28 }
27 29  
28 30 ///获取视频跟读内容
29   - static Future<List<ReadContentEntity?>?> readContent(videoFollowReadId) async {
30   - var data = await requestClient.get<List<ReadContentEntity?>>(Apis.readContent,queryParameters: {'videoFollowReadId':videoFollowReadId});
  31 + static Future<List<ReadContentEntity?>?> readContent(
  32 + videoFollowReadId) async {
  33 + var data = await requestClient.get<List<ReadContentEntity?>>(
  34 + Apis.readContent,
  35 + queryParameters: {'videoFollowReadId': videoFollowReadId});
31 36 return data;
32 37 }
33 38  
34 39 ///视频跟读提交结果
35   - static Future followResult(frequency,videoFollowReadId) async {
36   - var data = await requestClient.post(Apis.followResult,data: {'frequency':frequency,'videoFollowReadContentId':videoFollowReadId});
  40 + static Future followResult(frequency, videoFollowReadId) async {
  41 + var data = await requestClient.post(Apis.followResult, data: {
  42 + 'frequency': frequency,
  43 + 'videoFollowReadContentId': videoFollowReadId
  44 + });
37 45 return data;
38 46 }
39 47  
40 48 ///进入课堂
41 49 static Future enterClass(courseLessonId) async {
42   - var data = await requestClient.post(Apis.enterClass,data: {'courseLessonId':courseLessonId});
  50 + var data = await requestClient
  51 + .post(Apis.enterClass, data: {'courseLessonId': courseLessonId});
43 52 return data;
44 53 }
45 54  
46 55 ///退出课堂
47   - static Future exitClass(courseLessonId,currentStep,{int? currentTime}) async {
48   - var data = await requestClient.post(Apis.exitClass,data: {'courseLessonId':courseLessonId,'currentStep':currentStep,'currentTime':currentTime ?? getTimestampOfSecond()});
  56 + static Future exitClass(courseLessonId,
  57 + {int? currentStep, int? currentTime}) async {
  58 + var data = await requestClient.post(Apis.exitClass, data: {
  59 + 'courseLessonId': courseLessonId,
  60 +
  61 + ///如果currentStep不为空,才传currentStep参数
  62 + if (currentStep != null) 'currentStep': currentStep,
  63 +
  64 + ///如果currentTime不为空,才传currentTime参数
  65 + if (currentTime != null) 'currentTime': currentTime
  66 + });
49 67 return data;
50 68 }
51 69  
52 70 ///完成课堂
53   - static Future endClass(courseLessonId,currentStep,{int? currentTime}) async {
54   - var data = await requestClient.post(Apis.endClass,data: {'courseLessonId':courseLessonId,'currentStep':currentStep,'currentTime':currentTime ?? getTimestampOfSecond()});
  71 + static Future endClass(courseLessonId,
  72 + {int? currentStep, int? currentTime}) async {
  73 + var data = await requestClient.post(Apis.endClass, data: {
  74 + 'courseLessonId': courseLessonId,
  75 + if (currentStep != null) 'currentStep': currentStep,
  76 + if (currentTime != null) 'currentTime': currentTime
  77 + });
55 78 return data;
56 79 }
57 80 }
... ...
lib/pages/practice/bloc/topic_picture_bloc.dart
... ... @@ -326,9 +326,9 @@ class TopicPictureBloc extends BaseSectionBloc&lt;TopicPictureEvent, TopicPictureSt
326 326 sectionComplete(() {
327 327 popPage(
328 328 data:{
329   - 'currentStep':currentPage.toString(),
  329 + 'currentStep':currentPage,
330 330 'courseLessonId':courseLessonId,
331   - 'isLastPage': true,
  331 + 'isCompleted': true,
332 332 'nextSection': true
333 333 });
334 334 }, againSectionTap: () {
... ...
lib/pages/practice/topic_picture_page.dart
... ... @@ -71,9 +71,9 @@ class _TopicPicturePage extends StatelessWidget {
71 71 onTap: () {
72 72 popPage(
73 73 data:{
74   - 'currentStep':bloc.currentPage.toString(),
  74 + 'currentStep':bloc.currentPage,
75 75 'courseLessonId':bloc.courseLessonId,
76   - 'isLastPage': bloc.isLastPage(),
  76 + 'isCompleted': bloc.isLastPage(),
77 77 });
78 78 // Navigator.pop(context);
79 79 },
... ...
lib/pages/repeataftercontent/widgets/repeat_video_widget.dart
... ... @@ -140,13 +140,14 @@ class _RepeatVideoWidgetState extends State&lt;RepeatVideoWidget&gt; {
140 140 :
141 141 Container(
142 142 color: Colors.white,
143   - child: Text(
144   - '视频加载中....',
145   - style: TextStyle(
146   - fontSize: 20.sp,
147   - color: Colors.black
148   - ),
149   - ),
  143 + child: const CircularProgressIndicator(),
  144 + // Text(
  145 + // '视频加载中....',
  146 + // style: TextStyle(
  147 + // fontSize: 20.sp,
  148 + // color: Colors.black
  149 + // ),
  150 + // ),
150 151 ),
151 152 );
152 153 }
... ...
lib/pages/section/bloc/section_bloc.dart
... ... @@ -34,34 +34,31 @@ class SectionBloc extends Bloc&lt;SectionEvent, SectionState&gt; {
34 34  
35 35 CourseUnitEntity get courseUnitEntity => _courseUnitEntity;
36 36  
37   - CourseUnitDetail _courseUnitDetail;
  37 + ///courseUnitId与课程环节列表的映射
  38 + final Map<int, List<CourseSectionEntity>?> _courseSectionDatasMap = {};
38 39  
39   - CourseUnitDetail get courseUnitDetail => _courseUnitDetail;
40   -
41   - List<CourseSectionEntity>? _courseSectionDatas;
42   -
43   - List<CourseSectionEntity>? get courseSectionDatas => _courseSectionDatas;
  40 + Map<int, List<CourseSectionEntity>?> get courseSectionDatasMap => _courseSectionDatasMap;
44 41  
45 42 CourseProcessEntity? _processEntity;
46 43  
47 44 CourseProcessEntity? get processEntity => _processEntity;
48 45  
49   - SectionBloc(this._courseUnitEntity, this._courseUnitDetail,
  46 + SectionBloc(this._courseUnitEntity, this._currentPage,
50 47 this._pageController, this._listController)
51 48 : super(LessonInitial()) {
52   - on<RequestDataEvent>(_requestData);
  49 + on<RequestDataEvent>(_requestSectionsData);
53 50 on<RequestEndClassEvent>(_requestEndClass);
54 51 on<RequestEnterClassEvent>(_requestEnterClass);
55 52 on<RequestVideoLessonEvent>(_requestVideoLesson);
56 53 on<CurrentUnitIndexChangeEvent>(_pageControllerChange);
57 54 }
58 55  
59   - void _requestData(
  56 + void _requestSectionsData(
60 57 RequestDataEvent event, Emitter<SectionState> emitter) async {
61 58 try {
62 59 await loading(() async {
63   - _courseSectionDatas =
64   - await LessonDao.courseSection(courseUnitId: _courseUnitDetail.id!);
  60 + _courseSectionDatasMap[event.courseUnitId] =
  61 + await LessonDao.courseSection(courseUnitId: event.courseUnitId);
65 62 emitter(LessonDataLoadState());
66 63 });
67 64 } catch (e) {
... ... @@ -102,18 +99,18 @@ class SectionBloc extends Bloc&lt;SectionEvent, SectionState&gt; {
102 99  
103 100 void _requestEndClass(
104 101 RequestEndClassEvent event, Emitter<SectionState> emitter) async {
105   - if (event.isLastPage) {
106   - await await ListenDao.endClass(event.courseLessonId, event.currentStep,
  102 + if (event.isCompleted) {
  103 + await await ListenDao.endClass(event.courseLessonId,
  104 + currentStep: event.currentStep,
107 105 currentTime: event.currentTime);
108 106 } else {
109   - await await ListenDao.exitClass(event.courseLessonId, event.currentStep,
  107 + await await ListenDao.exitClass(event.courseLessonId,
  108 + currentStep: event.currentStep,
110 109 currentTime: event.currentTime);
111 110 }
112   - debugPrint("WQF _requestEndClass autoNextSection=${event.autoNextSection}");
113 111 if (event.autoNextSection) {
114 112 final nextCourseSection =
115   - getNextCourseSectionBySort(int.parse(event.courseLessonId));
116   - debugPrint("WQF nextCourseSection = $nextCourseSection");
  113 + getNextCourseSection(int.parse(event.courseLessonId));
117 114 ///进入课堂
118 115 add(RequestEnterClassEvent(nextCourseSection!.id.toString(),
119 116 nextCourseSection.courseType));
... ... @@ -126,30 +123,72 @@ class SectionBloc extends Bloc&lt;SectionEvent, SectionState&gt; {
126 123 emitter(CurrentPageIndexState());
127 124 }
128 125  
129   - // 未锁定的页
  126 + // 未锁定的页(单元)
130 127 int unlockPageCount() {
131 128 return _courseUnitEntity.courseUnitVOList
132 129 ?.indexWhereOrNull((element) => element.lock == true) ??
133 130 1;
134 131 }
135 132  
136   - CourseSectionEntity? getNextCourseSectionBySort(int courseLessonId) {
137   - final curCourseSectionEntity = _courseSectionDatas
138   - ?.firstWhere((element) => element.id == courseLessonId);
139   - final curSort = curCourseSectionEntity?.sortOrder ?? 0;
140   - CourseSectionEntity? nextCourseSectionEntity = _courseSectionDatas
141   - ?.firstWhere((element) => element.sortOrder == curSort + 1);
  133 + CourseUnitDetail getCourseUnitDetail({int? pageIndex}) {
  134 + return _courseUnitEntity.courseUnitVOList![pageIndex ?? _currentPage];
  135 + }
  136 +
  137 + ///根据courseLessonId查找对应的courseSection
  138 + CourseSectionEntity? findCourseSectionById(int courseLessonId) {
  139 + for (var entry in courseSectionDatasMap.entries) {
  140 + var sectionList = entry.value;
  141 + if (sectionList != null) {
  142 + for (var section in sectionList) {
  143 + if (section.id == courseLessonId) {
  144 + return section;
  145 + }
  146 + }
  147 + }
  148 + }
  149 + return null;
  150 + }
  151 +
  152 + ///根据sortOrder查找对应的courseSection
  153 + CourseSectionEntity? findCourseSectionBySort(int sortOrder) {
  154 + for (var entry in courseSectionDatasMap.entries) {
  155 + var sectionList = entry.value;
  156 + if (sectionList != null) {
  157 + for (var section in sectionList) {
  158 + if (section.sortOrder == sortOrder) {
  159 + return section;
  160 + }
  161 + }
  162 + }
  163 + }
  164 + return null;
  165 + }
  166 +
  167 + ///根据courseLessonId查找对应的CourseUnitDetail
  168 + CourseUnitDetail? findCourseUnitDetailById(int courseLessonId) {
  169 + final curCourseSectionEntity = findCourseSectionById(courseLessonId);
  170 + if (curCourseSectionEntity != null) {
  171 + final curCourseUnitDetail = _courseUnitEntity.courseUnitVOList?.firstWhere((element) =>
  172 + element.id == curCourseSectionEntity.courseUnitId);
  173 + return curCourseUnitDetail;
  174 + }
  175 + return null;
  176 + }
  177 +
  178 + CourseSectionEntity? getNextCourseSection(int courseLessonId) {
  179 + final curCourseSectionEntity = findCourseSectionById(courseLessonId);
  180 + final curSectionSort = curCourseSectionEntity?.sortOrder ?? 0;
  181 + final nextCourseSectionEntity = findCourseSectionBySort(curSectionSort + 1);
142 182 if (nextCourseSectionEntity != null) {
143 183 return nextCourseSectionEntity;
144 184 } else {
145 185 ///跨unit选lesson
146   - final curCourseUnitDetail = _courseUnitEntity.courseUnitVOList
147   - ?.firstWhere(
148   - (element) => element.id == curCourseSectionEntity?.courseUnitId);
  186 + final curCourseUnitDetail = findCourseUnitDetailById(courseLessonId);
149 187 if (curCourseUnitDetail != null) {
150 188 final nextCourseUnitDetail = _courseUnitEntity.courseUnitVOList
151   - ?.firstWhere((element) => element.sortOrder == 0);
  189 + ?.firstWhere((element) => element.sortOrder == (curCourseUnitDetail.sortOrder! + 1));
152 190 if (nextCourseUnitDetail != null) {
  191 + add(RequestDataEvent(nextCourseUnitDetail.id!));
153 192 ///pageView翻页了,可能需要预加载 todo
154 193 return null;
155 194 } else {
... ...
lib/pages/section/bloc/section_event.dart
... ... @@ -3,7 +3,11 @@ part of &#39;section_bloc.dart&#39;;
3 3 @immutable
4 4 abstract class SectionEvent {}
5 5  
6   -class RequestDataEvent extends SectionEvent {}
  6 +class RequestDataEvent extends SectionEvent {
  7 + final int courseUnitId;
  8 +
  9 + RequestDataEvent(this.courseUnitId);
  10 +}
7 11  
8 12 ///获取视频课程内容
9 13 class RequestVideoLessonEvent extends SectionEvent {
... ... @@ -24,17 +28,23 @@ class RequestEnterClassEvent extends SectionEvent {
24 28 ///结束课堂
25 29 class RequestEndClassEvent extends SectionEvent {
26 30 final String courseLessonId;
27   - final String currentStep;
28 31  
29   - ///是否是最后一页(决定调结束接口还是退出接口)
30   - final bool isLastPage;
  32 + ///当前进展(进度类,比如练习、绘本)
  33 + final int? currentStep;
  34 +
  35 + ///当前时间(进度类,比如音视频)
31 36 final int? currentTime;
32 37  
  38 + ///课程环节是否完成(决定调结束接口还是退出接口)
  39 + final bool isCompleted;
  40 +
33 41 ///自动进入下一环节
34 42 final bool autoNextSection;
35 43  
36   - RequestEndClassEvent(this.courseLessonId, this.currentStep, this.isLastPage,
37   - {this.currentTime, this.autoNextSection = false});
  44 + RequestEndClassEvent(this.courseLessonId, isCompleted,
  45 + {this.currentStep, this.currentTime, autoNextSection})
  46 + : isCompleted = isCompleted ?? false,
  47 + autoNextSection = autoNextSection ?? false;
38 48 }
39 49  
40 50 ///页面切换
... ...
lib/pages/section/section_page.dart
... ... @@ -20,21 +20,21 @@ import &#39;courese_module_model.dart&#39;;
20 20 /// 环节列表页
21 21 class SectionPage extends StatelessWidget {
22 22 const SectionPage(
23   - {super.key,
24   - required this.courseUnitEntity,
25   - required this.courseUnitDetail});
  23 + {super.key, required this.courseUnitEntity, required this.courseUnitId});
26 24  
27 25 final CourseUnitEntity courseUnitEntity;
28 26  
29 27 /// unitId
30   - final CourseUnitDetail courseUnitDetail;
  28 + final int courseUnitId;
31 29  
32 30 @override
33 31 Widget build(BuildContext context) {
  32 + int initialPage = courseUnitEntity.courseUnitVOList
  33 + ?.indexWhere((element) => element.id == courseUnitId) ??
  34 + 0;
34 35 return BlocProvider(
35   - create: (context) => SectionBloc(courseUnitEntity, courseUnitDetail,
36   - PageController(), ScrollController())
37   - ..add(RequestDataEvent()),
  36 + create: (context) => SectionBloc(courseUnitEntity, initialPage,
  37 + PageController(initialPage: initialPage), ScrollController()),
38 38 child: _SectionPageView(context),
39 39 );
40 40 }
... ... @@ -76,16 +76,18 @@ class _SectionPageView extends StatelessWidget {
76 76 }).then((value) {
77 77 if (value != null) {
78 78 Map<String, dynamic> dataMap = value as Map<String, dynamic>;
79   - bloc.add(RequestEndClassEvent(dataMap['courseLessonId']!,
80   - dataMap['currentTime']!, true, autoNextSection: dataMap['nextSection'] as bool));
  79 + bloc.add(RequestEndClassEvent(
  80 + dataMap['courseLessonId']!, dataMap['isCompleted'],
  81 + currentTime: dataMap['currentTime'],
  82 + autoNextSection: dataMap['nextSection']));
81 83 }
82 84 });
83 85 return;
84 86 }
85 87  
86 88 if (state is RequestEnterClassState) {
87   - if (state.courseType != SectionType.practice.value
88   - && state.courseType != SectionType.pictureBook.value) {
  89 + if (state.courseType != SectionType.practice.value &&
  90 + state.courseType != SectionType.pictureBook.value) {
89 91 ///视频类型
90 92 ///获取视频课程内容
91 93 bloc.add(RequestVideoLessonEvent(
... ... @@ -101,8 +103,11 @@ class _SectionPageView extends StatelessWidget {
101 103 if (value != null) {
102 104 Map<String, dynamic> dataMap = value as Map<String, dynamic>;
103 105 bloc.add(RequestEndClassEvent(
104   - dataMap['courseLessonId']!, dataMap['currentStep']!,
105   - dataMap['isLastPage']! as bool, autoNextSection: dataMap['nextSection'] as bool));
  106 + dataMap['courseLessonId']!,
  107 + dataMap['isCompleted'],
  108 + currentStep: dataMap['currentStep'],
  109 + autoNextSection: dataMap['nextSection'],
  110 + ));
106 111 }
107 112 });
108 113 return;
... ... @@ -116,8 +121,9 @@ class _SectionPageView extends StatelessWidget {
116 121 if (value != null) {
117 122 Map<String, dynamic> dataMap = value as Map<String, dynamic>;
118 123 bloc.add(RequestEndClassEvent(
119   - dataMap['courseLessonId']!, dataMap['currentStep']!,
120   - dataMap['isLastPage']! as bool, autoNextSection: dataMap['nextSection'] as bool));
  124 + dataMap['courseLessonId']!, dataMap['isCompleted'],
  125 + currentStep: dataMap['currentStep'],
  126 + autoNextSection: dataMap['nextSection']));
121 127 }
122 128 });
123 129 return;
... ... @@ -139,7 +145,7 @@ class _SectionPageView extends StatelessWidget {
139 145 mainAxisAlignment: MainAxisAlignment.spaceBetween,
140 146 children: [
141 147 SectionHeaderWidget(
142   - title: bloc.courseUnitDetail.name,
  148 + title: bloc.getCourseUnitDetail().name,
143 149 courseModuleCode: bloc.courseUnitEntity.courseModuleCode),
144 150 Expanded(
145 151 child: Padding(
... ... @@ -156,7 +162,10 @@ class _SectionPageView extends StatelessWidget {
156 162 ///去掉 Android 上默认的边缘拖拽效果
157 163 behavior: ScrollConfiguration.of(context)
158 164 .copyWith(overscroll: false),
159   - child: _itemTransCard(index, context),
  165 + child: _itemTransCard(
  166 + bloc.getCourseUnitDetail(pageIndex: index),
  167 + index,
  168 + context),
160 169 );
161 170 }),
162 171 ), // 设置外部padding,
... ... @@ -209,55 +218,80 @@ class _SectionPageView extends StatelessWidget {
209 218 });
210 219 }
211 220  
212   -Widget _itemTransCard(int index, BuildContext context) {
  221 +Widget _itemTransCard(
  222 + CourseUnitDetail courseUnitDetail, int pageIndex, BuildContext context) {
213 223 final bloc = BlocProvider.of<SectionBloc>(context);
214   - return NestedListView.builder(
215   - itemCount: bloc.courseSectionDatas?.length ?? 0,
216   - scrollDirection: Axis.horizontal,
217   - itemBuilder: (BuildContext context, int index) {
218   - CourseSectionEntity sectionData = bloc.courseSectionDatas![index];
219   - if (sectionData.courseType == SectionType.bouns.value) {
220   - //彩蛋
221   - return GestureDetector(
222   - onTap: () {
223   - if (!UserUtil.isLogined()) {
224   - pushNamed(AppRouteName.login);
225   - return;
226   - }
227   - if (sectionData.lock == true) {
228   - showToast('当前课程暂未解锁');
229   - return;
230   - }
  224 + List<CourseSectionEntity>? courseSectionEntities =
  225 + bloc.courseSectionDatasMap[courseUnitDetail.id];
  226 + if (courseSectionEntities == null) {
  227 + bloc.add(RequestDataEvent(courseUnitDetail.id!));
  228 + return Center(
  229 + child: Column(
  230 + mainAxisAlignment: MainAxisAlignment.center,
  231 + children: [
  232 + const Text(
  233 + '暂无数据',
  234 + style: TextStyle(fontSize: 24.0),
  235 + ),
  236 + const SizedBox(height: 16.0),
  237 + // 间距
  238 + CircularProgressIndicator(
  239 + color: CourseModuleModel(
  240 + bloc.courseUnitEntity.courseModuleCode ?? 'Phase-1')
  241 + .color),
  242 + // 加载动画
  243 + ],
  244 + ),
  245 + );
  246 + } else {
  247 + return NestedListView.builder(
  248 + itemCount: bloc.courseSectionDatasMap[courseUnitDetail.id]?.length ?? 0,
  249 + scrollDirection: Axis.horizontal,
  250 + itemBuilder: (BuildContext context, int index) {
  251 + CourseSectionEntity sectionData = courseSectionEntities[index];
  252 + if (sectionData.courseType == SectionType.bouns.value) {
  253 + //彩蛋
  254 + return GestureDetector(
  255 + onTap: () {
  256 + if (!UserUtil.isLogined()) {
  257 + pushNamed(AppRouteName.login);
  258 + return;
  259 + }
  260 + if (sectionData.lock == true) {
  261 + showToast('当前课程暂未解锁');
  262 + return;
  263 + }
231 264  
232   - ///进入课堂
233   - bloc.add(RequestEnterClassEvent(
234   - sectionData.id.toString(), sectionData.courseType));
235   - },
236   - child: SectionBoundsItem(
237   - imageUrl: sectionData.coverUrl,
238   - ),
239   - );
240   - } else {
241   - return GestureDetector(
242   - onTap: () {
243   - if (!UserUtil.isLogined()) {
244   - pushNamed(AppRouteName.login);
245   - return;
246   - }
247   - if (sectionData.lock == true) {
248   - showToast('当前课程暂未解锁');
249   - return;
250   - }
  265 + ///进入课堂
  266 + bloc.add(RequestEnterClassEvent(
  267 + sectionData.id.toString(), sectionData.courseType));
  268 + },
  269 + child: SectionBoundsItem(
  270 + imageUrl: sectionData.coverUrl,
  271 + ),
  272 + );
  273 + } else {
  274 + return GestureDetector(
  275 + onTap: () {
  276 + if (!UserUtil.isLogined()) {
  277 + pushNamed(AppRouteName.login);
  278 + return;
  279 + }
  280 + if (sectionData.lock == true) {
  281 + showToast('当前课程暂未解锁');
  282 + return;
  283 + }
251 284  
252   - ///进入课堂
253   - bloc.add(RequestEnterClassEvent(
254   - sectionData.id.toString(), sectionData.courseType));
255   - },
256   - child: SectionVideoItem(
257   - unitEntity: bloc.courseUnitEntity,
258   - lessons: sectionData,
259   - ),
260   - );
261   - }
262   - });
  285 + ///进入课堂
  286 + bloc.add(RequestEnterClassEvent(
  287 + sectionData.id.toString(), sectionData.courseType));
  288 + },
  289 + child: SectionVideoItem(
  290 + unitEntity: bloc.courseUnitEntity,
  291 + lessons: sectionData,
  292 + ),
  293 + );
  294 + }
  295 + });
  296 + }
263 297 }
... ...
lib/pages/unit/view.dart
... ... @@ -64,7 +64,7 @@ class UnitPage extends StatelessWidget {
64 64 pushNamed(AppRouteName.courseSection,
65 65 arguments: {
66 66 'courseUnitEntity': bloc.unitData,
67   - 'courseUnitDetail': data
  67 + 'courseUnitId': data.id
68 68 });
69 69 },
70 70 child: CourseUnitItem(
... ...
lib/pages/video/lookvideo/widgets/video_widget.dart
... ... @@ -51,10 +51,7 @@ class _VideoWidgetState extends State&lt;VideoWidget&gt; {
51 51 if (_controller!.value.isInitialized) {
52 52 if (_controller!.value.isPlaying) {
53 53 setState(() {
54   - double currentSecond =
55   - (_controller!.value.position.inMinutes.remainder(60) * 60 +
56   - _controller!.value.position.inSeconds.remainder(60))
57   - .toDouble();
  54 + double currentSecond = getCurrentPositionSeconds().toDouble();
58 55 int totalSecond =
59 56 _controller!.value.duration.inMinutes.remainder(60) * 60 +
60 57 _controller!.value.duration.inSeconds.remainder(60);
... ... @@ -75,13 +72,10 @@ class _VideoWidgetState extends State&lt;VideoWidget&gt; {
75 72 _controller!.value.duration.inSeconds) {
76 73 final lookVideoBloc = context.read<LookVideoBloc>();
77 74 lookVideoBloc.sectionComplete(() {
78   - String currentTime =
79   - (_controller!.value.position.inMinutes.remainder(60) * 60 +
80   - _controller!.value.position.inSeconds.remainder(60))
81   - .toString();
82 75 popPage(data: {
83 76 'courseLessonId': widget.courseLessonId,
84   - 'currentTime': currentTime,
  77 + 'currentTime': getCurrentPositionSeconds(),
  78 + 'isCompleted': true,
85 79 'nextSection': widget.isTopic
86 80 });
87 81 } as VoidCallback,
... ... @@ -127,13 +121,9 @@ class _VideoWidgetState extends State&lt;VideoWidget&gt; {
127 121 popPage();
128 122 return;
129 123 }
130   - String currentTime =
131   - (_controller!.value.position.inMinutes.remainder(60) * 60 +
132   - _controller!.value.position.inSeconds.remainder(60))
133   - .toString();
134 124 popPage(data: {
135 125 'courseLessonId': widget.courseLessonId,
136   - 'currentTime': currentTime
  126 + 'currentTime': getCurrentPositionSeconds(),
137 127 });
138 128 }
139 129 } else if (type == OperationType.playState) {
... ... @@ -250,10 +240,11 @@ class _VideoWidgetState extends State&lt;VideoWidget&gt; {
250 240 )
251 241 : Container(
252 242 color: Colors.white,
253   - child: Text(
254   - '视频加载中....',
255   - style: TextStyle(fontSize: 20.sp, color: Colors.black),
256   - ),
  243 + child: const CircularProgressIndicator(),
  244 + // Text(
  245 + // '视频加载中....',
  246 + // style: TextStyle(fontSize: 20.sp, color: Colors.black),
  247 + // ),
257 248 ),
258 249 ),
259 250 ),
... ... @@ -270,4 +261,10 @@ class _VideoWidgetState extends State&lt;VideoWidget&gt; {
270 261 }
271 262 super.dispose();
272 263 }
  264 +
  265 + ///获取当前进度秒数
  266 + int getCurrentPositionSeconds() {
  267 + return (_controller!.value.position.inMinutes.remainder(60) * 60 +
  268 + _controller!.value.position.inSeconds.remainder(60));
  269 + }
273 270 }
... ...
lib/route/route.dart
... ... @@ -126,17 +126,17 @@ class AppRouter {
126 126 builder: (_) => UnitPage(courseModuleEntity: courseModuleEntity));
127 127 case AppRouteName.courseSection:
128 128 CourseUnitEntity courseUnitEntity = CourseUnitEntity();
129   - CourseUnitDetail courseUnitDetail = CourseUnitDetail();
  129 + int courseUnitDetail = 0;
130 130 if (settings.arguments != null) {
131 131 courseUnitEntity = (settings.arguments as Map)
132 132 .getOrNull('courseUnitEntity') as CourseUnitEntity;
133 133 courseUnitDetail = (settings.arguments as Map)
134   - .getOrNull('courseUnitDetail') as CourseUnitDetail;
  134 + .getOrNull('courseUnitId');
135 135 }
136 136 return CupertinoPageRoute(
137 137 builder: (_) => SectionPage(
138 138 courseUnitEntity: courseUnitEntity,
139   - courseUnitDetail: courseUnitDetail));
  139 + courseUnitId: courseUnitDetail));
140 140 case AppRouteName.listen:
141 141 return CupertinoPageRoute(builder: (_) => const ListenPage());
142 142 case AppRouteName.shop:
... ...