diff --git a/marking_app/lib/common/model/event_bus/jobs/job_do_papers_student_bus.dart b/marking_app/lib/common/model/event_bus/jobs/job_do_papers_student_bus.dart index b181e37..4236105 100644 --- a/marking_app/lib/common/model/event_bus/jobs/job_do_papers_student_bus.dart +++ b/marking_app/lib/common/model/event_bus/jobs/job_do_papers_student_bus.dart @@ -10,6 +10,8 @@ class JobDoPapersStudentBus extends Object { @JsonKey(name: 'studentName') String studentName; + bool isFinish; + int pageIndex; bool isFirst; @@ -19,6 +21,7 @@ class JobDoPapersStudentBus extends Object { this.studentName, this.pageIndex, this.isFirst, + this.isFinish, ); factory JobDoPapersStudentBus.fromJson(Map srcJson) => _$JobDoPapersStudentBusFromJson(srcJson); diff --git a/marking_app/lib/common/model/job/marking_text_question_job.dart b/marking_app/lib/common/model/job/marking_text_question_job.dart index 8638ad6..625ece6 100644 --- a/marking_app/lib/common/model/job/marking_text_question_job.dart +++ b/marking_app/lib/common/model/job/marking_text_question_job.dart @@ -90,7 +90,9 @@ class Questions extends Object { @JsonKey(name: 'score') double? score; - Questions(this.questionNo, this.answer, [this.score]); + double accuracy; // 当前题正确率 + + Questions(this.questionNo, this.answer, this.accuracy, [this.score]); factory Questions.fromJson(Map srcJson) => _$QuestionsFromJson(srcJson); diff --git a/marking_app/lib/components/ReturnToHomepage.dart b/marking_app/lib/components/ReturnToHomepage.dart new file mode 100644 index 0000000..1d0bc08 --- /dev/null +++ b/marking_app/lib/components/ReturnToHomepage.dart @@ -0,0 +1,23 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:marking_app/routes/RouterManager.dart'; +import 'package:marking_app/utils/anti_shake_throttling.dart'; + +// 返回首页 +class ReturnToHomepage extends StatelessWidget { + const ReturnToHomepage({super.key}); + + @override + Widget build(BuildContext context) { + return InkWell( + onTap: () => easyThrottle('RETURN_TO_HOMEPAGE', () { + Navigator.of(context).popUntil(ModalRoute.withName(RouterManager.root)); + }), + child: Container( + padding: EdgeInsets.only(right: 4.5.w), + alignment: Alignment.center, + child: Icon(Icons.home_rounded, size: 22.sp, color: Color.fromRGBO(135, 135, 135, 1)), + ), + ); + } +} diff --git a/marking_app/lib/pages/homework_correction/do_papers_job.dart b/marking_app/lib/pages/homework_correction/do_papers_job.dart index 8b6ac8b..a9efb69 100644 --- a/marking_app/lib/pages/homework_correction/do_papers_job.dart +++ b/marking_app/lib/pages/homework_correction/do_papers_job.dart @@ -17,6 +17,7 @@ import 'package:marking_app/common/model/job/job_page_tab.dart'; import 'package:marking_app/common/model/job/job_review_submission.dart'; import 'package:marking_app/common/model/job/marking_text_question_job.dart'; import 'package:marking_app/common/model/job/marking_text_question_job_tab_params.dart'; +import 'package:marking_app/components/ReturnToHomepage.dart'; import 'package:marking_app/pages/common/event_bus_mixin.dart'; import 'package:marking_app/pages/homework_correction/components/new_version_of_homework/bottom_annotation_switch_job.dart'; import 'package:marking_app/pages/homework_correction/eventBus/marking_text_question_job_tab_params_bus.dart'; @@ -74,14 +75,8 @@ class DoPapersJob extends HookWidget with EventBusMixin { elevation: 0, actions: [ FavoriteWidget(() => refresh = true), - // Container( - // padding: EdgeInsets.only(right: 4.w), - // alignment: Alignment.center, - // child: Row( - // crossAxisAlignment: CrossAxisAlignment.end, - // children: [Icon(Icons.lightbulb_outline, size: 12.sp), SizedBox(width: 1.w), quickText('查看原卷')], - // ), - // ), + SizedBox(width: 5.w), + ReturnToHomepage(), ], ), body: SafeArea( @@ -132,8 +127,7 @@ class ReviewStatusInfo extends HookWidget with CommonMixin { try { ToastUtils.showLoading(); var _client = await getClient(); - var _result = await _client - .getJobWithStudents(JobConcernedWithStudentParams([taskId], isCommit: false, pageIndex: pageIndex)); + var _result = await _client.getJobWithStudents(JobConcernedWithStudentParams([taskId], isCommit: false, pageIndex: pageIndex)); if (_result.success) return _result.data; } catch (e) { ToastUtils.showError('获取数据失败,请重试'); @@ -218,8 +212,7 @@ class ReviewStatusInfo extends HookWidget with CommonMixin { crossAxisAlignment: CrossAxisAlignment.end, children: [ quickText('已阅', color: Color.fromRGBO(117, 117, 117, 1), size: 10.sp), - quickText(doMarkingInfo.value!.finishCount, - color: Color.fromRGBO(76, 199, 147, 1), size: 12.sp, fontWeight: FontWeight.bold), + quickText(doMarkingInfo.value!.finishCount, color: Color.fromRGBO(76, 199, 147, 1), size: 12.sp, fontWeight: FontWeight.bold), quickText('/', color: Color.fromRGBO(117, 117, 117, 1), size: 12.sp), quickText(doMarkingInfo.value!.surplusNo, color: Color.fromRGBO(117, 117, 117, 1), size: 10.sp), ], @@ -231,8 +224,7 @@ class ReviewStatusInfo extends HookWidget with CommonMixin { // 切换下拉框 (学生和试卷状态) @hwidget -Widget $dropdownBoxSwitchStudentsOrTypeView(BuildContext context, - {required Function() exitCallback, required int taskId, required int jobId}) { +Widget $dropdownBoxSwitchStudentsOrTypeView(BuildContext context, {required Function() exitCallback, required int taskId, required int jobId}) { UseSwitchStudentAndType _useSwitchStudentAndType = UseSwitchStudentAndType.use(); // 学生和试卷状态 // 当前tab改变时 @@ -275,23 +267,18 @@ Widget $dropdownBoxSwitchStudentsOrTypeView(BuildContext context, case JobDoPapersStudentBus: var studentInfo = val as JobDoPapersStudentBus; _useSwitchStudentAndType.studentBusInfo.value = studentInfo; // 赋值历史记录 - var selectedStudent = _useSwitchStudentAndType.studentData.value - .firstWhereOrNull((element) => element.studentId == studentInfo.studentId); + var selectedStudent = + _useSwitchStudentAndType.studentData.value.firstWhereOrNull((element) => element.studentId == studentInfo.studentId); if (selectedStudent == null) { // 当前学生集合中没有此学生 selectedStudent = JobConcernedWithStudent.fromJson(studentInfo.toJson()); - _useSwitchStudentAndType.studentData.value = [ - ..._useSwitchStudentAndType.studentData.value, - selectedStudent - ]; + _useSwitchStudentAndType.studentData.value = [..._useSwitchStudentAndType.studentData.value, selectedStudent]; _useSwitchStudentAndType.getDataForStudents(taskId: taskId); } _useSwitchStudentAndType.currentStudent.value = selectedStudent; - print('是否是优先批阅:${studentInfo.isFirst}'); + _useSwitchStudentAndType.isFinish.value = studentInfo.isFinish; _useSwitchStudentAndType.isFirst.value = studentInfo.isFirst; - _useSwitchStudentAndType.currentTab.value = - _useSwitchStudentAndType.tabs.value.firstWhere((e) => e.pageIndex == studentInfo.pageIndex); - print('是否是优先批阅1111:${_useSwitchStudentAndType.isFirst}'); + _useSwitchStudentAndType.currentTab.value = _useSwitchStudentAndType.tabs.value.firstWhere((e) => e.pageIndex == studentInfo.pageIndex); break; case JobCheckSwitchingQuestionTabBus: // 检查切换试题体型 @@ -311,7 +298,8 @@ Widget $dropdownBoxSwitchStudentsOrTypeView(BuildContext context, }; }, []); - print('加载的是否优先批阅:${_useSwitchStudentAndType.isFirst}'); + var _currentTab = _useSwitchStudentAndType.currentTab.value; + return Container( padding: EdgeInsets.only(bottom: 2.r, left: 12.r, right: 12.r), decoration: BoxDecoration( @@ -328,7 +316,7 @@ Widget $dropdownBoxSwitchStudentsOrTypeView(BuildContext context, child: Row( children: [ Expanded( - flex: 7, + flex: 3, child: Container( padding: EdgeInsets.only(left: 10.w), decoration: BoxDecoration( @@ -353,15 +341,14 @@ Widget $dropdownBoxSwitchStudentsOrTypeView(BuildContext context, ); }).toList(), onChanged: (value) { - _useSwitchStudentAndType.currentTab.value = - _useSwitchStudentAndType.tabs.value.firstWhere((element) => element.pageIndex == value); + _useSwitchStudentAndType.currentTab.value = _useSwitchStudentAndType.tabs.value.firstWhere((element) => element.pageIndex == value); }, ), ), ), Expanded(flex: 1, child: SizedBox()), Expanded( - flex: 7, + flex: 5, child: Container( padding: EdgeInsets.only(left: 10.w), decoration: BoxDecoration( @@ -389,28 +376,55 @@ Widget $dropdownBoxSwitchStudentsOrTypeView(BuildContext context, JobConcernedWithStudent? currentStudent = _useSwitchStudentAndType.currentStudent.value; if (currentStudent?.studentId == value) return; _useSwitchStudentAndType.studentBusInfo.value = null; // 置空BUS通知记录 - _useSwitchStudentAndType.currentStudent.value = _useSwitchStudentAndType.studentData.value - .firstWhereOrNull((element) => element.studentId == value); + _useSwitchStudentAndType.currentStudent.value = + _useSwitchStudentAndType.studentData.value.firstWhereOrNull((element) => element.studentId == value); }, ), ), ), Expanded(flex: 1, child: SizedBox()), Expanded( - flex: 3, + flex: 4, child: Row( crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.end, children: [ + if (_useSwitchStudentAndType.isFinish.value && _currentTab?.finishCount != _currentTab?.total) + Expanded( + child: Row( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Icon(Icons.flip_camera_android_outlined, size: 10.sp, color: Theme.of(context).primaryColor.withOpacity(0.8)), + SizedBox(width: 1.w), + InkWell( + onTap: () => easyThrottle( + 'DO_PAPERS_JOB_CONTINUE_TO_REVIEW', + () { + var _pageIndex = _useSwitchStudentAndType.currentTab.value?.pageIndex; + if (_pageIndex == null) return; + + _useSwitchStudentAndType.eventFire(model: MarkingTextQuestionJobTabParamsBus(taskId, _pageIndex)); + }, + ), + child: quickText( + '继续批阅', + size: 10.sp, + decoration: TextDecoration.underline, + color: Theme.of(context).primaryColor.withOpacity(0.9), + ), + ), + SizedBox(width: 2.w), + ], + ), + ), Stack( alignment: const FractionalOffset(0.52, 0.24), children: [ Icon( const IconData(0xe63d, fontFamily: "AlibabaIcon"), size: 12.sp, - color: _useSwitchStudentAndType.isFirst.value - ? Color.fromRGBO(76, 199, 147, 1) - : Color.fromRGBO(164, 164, 164, 1), + color: _useSwitchStudentAndType.isFirst.value ? Color.fromRGBO(76, 199, 147, 1) : Color.fromRGBO(164, 164, 164, 1), ), quickText('优先', size: 4.sp, color: Colors.white), ], @@ -419,9 +433,7 @@ Widget $dropdownBoxSwitchStudentsOrTypeView(BuildContext context, quickText( '优先批阅', size: 10.sp, - color: _useSwitchStudentAndType.isFirst.value - ? Color.fromRGBO(76, 199, 147, 1) - : Color.fromRGBO(164, 164, 164, 1), + color: _useSwitchStudentAndType.isFirst.value ? Color.fromRGBO(76, 199, 147, 1) : Color.fromRGBO(164, 164, 164, 1), ), ], ), @@ -535,8 +547,14 @@ class _EexamPaperAndScoringViewState extends ConsumerState(context, _future!, (jobData) { List questions = jobData?.questions ?? []; - bool canNormalPrevious = - jobData != null && (jobData.prevId != 0 || jobData.previousPageIndex != null); //是否可以正常点击切换上一题 + bool canNormalPrevious = jobData != null && (jobData.prevId != 0 || jobData.previousPageIndex != null); //是否可以正常点击切换上一题 bool canNormalNext = jobData != null && (jobData.nextId != 0 || jobData.nextPageIndex != null); //是否可以正常点击切换下一题 return Stack( @@ -630,8 +647,8 @@ class _EexamPaperAndScoringViewState extends ConsumerState easyThrottle('TestQuestionSwitch', - () => switchTestQuestions(jobData: jobData, toNextQuestion: false)), + onPressed: () => + easyThrottle('TestQuestionSwitch', () => switchTestQuestions(jobData: jobData, toNextQuestion: false)), child: Icon(Icons.arrow_back_ios, color: Colors.white, size: 22.sp), ), ), @@ -645,8 +662,7 @@ class _EexamPaperAndScoringViewState extends ConsumerState - easyThrottle('TestQuestionSwitch', () => switchTestQuestions(jobData: jobData)), + onPressed: () => easyThrottle('TestQuestionSwitch', () => switchTestQuestions(jobData: jobData)), child: Icon(Icons.arrow_forward_ios, color: Colors.white, size: 22.sp), ), ), @@ -691,10 +707,8 @@ class _EexamPaperAndScoringViewState extends ConsumerState easyThrottle('view_homework_notes', () => viewHomeworkNotes(subJobQuestion)), bgc: Color.fromRGBO(88, 87, 87, 1), child: Container( - width: double.infinity, - alignment: Alignment.center, - padding: EdgeInsets.symmetric(vertical: 8.h), - decoration: - BoxDecoration(border: Border(bottom: BorderSide(width: 0.2.r, color: Colors.white))), - child: Row( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - quickText(question.questionNo, size: 16.sp, color: textColor, fontWeight: FontWeight.bold), - Padding( - padding: EdgeInsets.only(bottom: 1.h), - child: quickText('题', size: 11.sp, color: textColor), + width: double.infinity, + alignment: Alignment.center, + padding: EdgeInsets.symmetric(vertical: 8.h, horizontal: 4.w), + decoration: BoxDecoration(border: Border(bottom: BorderSide(width: 0.2.r, color: Colors.white))), + child: Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Expanded( + child: Row( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + quickText(question.questionNo, size: 16.sp, color: textColor, fontWeight: FontWeight.bold), + Padding( + padding: EdgeInsets.only(bottom: 1.h), + child: quickText('题', size: 11.sp, color: textColor), + ), + ], ), - ], - )), + ), + if (question.accuracy > 0) + Padding( + padding: EdgeInsets.only(bottom: 1.5.h), + child: quickText('正确率:${question.accuracy}%', size: 8.sp, color: Colors.white, align: TextAlign.end), + ) + ], + ), + ), ), Container( child: Row( @@ -815,8 +841,7 @@ Widget $examPaperAndScoringKeyboardView( scoring: ScoringMethodEnum.CORRECT, questionNo: question.questionNo, ); - var noAnswerQuestion = - _useDoScoring.submittedData.value.questions.firstWhereOrNull((e) => e.score == null); + var noAnswerQuestion = _useDoScoring.submittedData.value.questions.firstWhereOrNull((e) => e.score == null); if (noAnswerQuestion == null) toSubmit(); }, child: Container( @@ -824,9 +849,7 @@ Widget $examPaperAndScoringKeyboardView( alignment: Alignment.center, child: quickText( '对', - color: subJobQuestion.score == 2 - ? Color.fromRGBO(255, 152, 0, 1) - : Color.fromRGBO(114, 114, 114, 1), + color: subJobQuestion.score == 2 ? Color.fromRGBO(255, 152, 0, 1) : Color.fromRGBO(114, 114, 114, 1), fontWeight: FontWeight.bold, size: 12.sp, ), @@ -841,8 +864,7 @@ Widget $examPaperAndScoringKeyboardView( scoring: ScoringMethodEnum.CORRECT_HALF, questionNo: question.questionNo, ); - var noAnswerQuestion = - _useDoScoring.submittedData.value.questions.firstWhereOrNull((e) => e.score == null); + var noAnswerQuestion = _useDoScoring.submittedData.value.questions.firstWhereOrNull((e) => e.score == null); if (noAnswerQuestion == null) toSubmit(); }, bgc: Color.fromRGBO(237, 237, 237, 1), @@ -851,9 +873,7 @@ Widget $examPaperAndScoringKeyboardView( alignment: Alignment.center, child: quickText( '半', - color: subJobQuestion.score == 1 - ? Color.fromRGBO(255, 152, 0, 1) - : Color.fromRGBO(114, 114, 114, 1), + color: subJobQuestion.score == 1 ? Color.fromRGBO(255, 152, 0, 1) : Color.fromRGBO(114, 114, 114, 1), fontWeight: FontWeight.bold, size: 12.sp, ), @@ -868,8 +888,7 @@ Widget $examPaperAndScoringKeyboardView( scoring: ScoringMethodEnum.WRONG, questionNo: question.questionNo, ); - var noAnswerQuestion = - _useDoScoring.submittedData.value.questions.firstWhereOrNull((e) => e.score == null); + var noAnswerQuestion = _useDoScoring.submittedData.value.questions.firstWhereOrNull((e) => e.score == null); if (noAnswerQuestion == null) toSubmit(); }, bgc: Color.fromRGBO(237, 237, 237, 1), @@ -878,9 +897,7 @@ Widget $examPaperAndScoringKeyboardView( alignment: Alignment.center, child: quickText( '错', - color: subJobQuestion.score == 0 - ? Color.fromRGBO(255, 152, 0, 1) - : Color.fromRGBO(114, 114, 114, 1), + color: subJobQuestion.score == 0 ? Color.fromRGBO(255, 152, 0, 1) : Color.fromRGBO(114, 114, 114, 1), fontWeight: FontWeight.bold, size: 12.sp, ), @@ -987,8 +1004,7 @@ Widget $examPaperAndScoringKeyboardView( bgc: Colors.white, splashColor: Theme.of(context).primaryColor.withOpacity(0.8), borderRadius: BorderRadius.circular(2.r), - onTap: () => easyThrottle('homework_review_submission_main_callback', () => toSubmit(), - duration: Duration(seconds: 1)), + onTap: () => easyThrottle('homework_review_submission_main_callback', () => toSubmit(), duration: Duration(seconds: 1)), child: Container( width: double.infinity, alignment: Alignment.center, @@ -1011,8 +1027,7 @@ Widget $examPaperAndScoringKeyboardView( } @swidget -Widget $materialBtn( - {required Widget child, Color? bgc, Color? splashColor, GestureTapCallback? onTap, BorderRadius? borderRadius}) { +Widget $materialBtn({required Widget child, Color? bgc, Color? splashColor, GestureTapCallback? onTap, BorderRadius? borderRadius}) { return Material( color: bgc, borderRadius: borderRadius, diff --git a/marking_app/lib/pages/homework_correction/hooks/do_papers_job/use_switch_student_and_type.dart b/marking_app/lib/pages/homework_correction/hooks/do_papers_job/use_switch_student_and_type.dart index 28b139b..0be114b 100644 --- a/marking_app/lib/pages/homework_correction/hooks/do_papers_job/use_switch_student_and_type.dart +++ b/marking_app/lib/pages/homework_correction/hooks/do_papers_job/use_switch_student_and_type.dart @@ -15,6 +15,8 @@ import 'package:marking_app/utils/request/rest_client.dart'; class UseSwitchStudentAndType with CommonMixin, EventBusMixin { ValueNotifier exitPromptFlag; // 退出提示 ValueNotifier isFirst; + ValueNotifier isFinish; + ValueNotifier> studentData; // 学生集合数据 ValueNotifier> tabs; // 学生集合数据 @@ -36,6 +38,7 @@ class UseSwitchStudentAndType with CommonMixin, EventBusMixin { required this.studentBusInfo, required this.exitPromptFlag, required this.isFirst, + required this.isFinish, }); // 工厂构造函数 @@ -60,6 +63,7 @@ class UseSwitchStudentAndType with CommonMixin, EventBusMixin { studentBusInfo: theStudentBus, exitPromptFlag: useState(false), isFirst: useState(false), + isFinish: useState(false), ); } @@ -95,8 +99,7 @@ class UseSwitchStudentAndType with CommonMixin, EventBusMixin { } /// 属性tab类型数据 - Future refreshQuestionTypeData(BuildContext context, - {required int taskId, required Function() exitCallback}) async { + Future refreshQuestionTypeData(BuildContext context, {required int taskId, required Function() exitCallback}) async { List? tabDatas = await getDataForTestpaper(taskId: taskId, synchronization: false); if (tabDatas?.isNotEmpty ?? false) { JobPageTab? tabJob = tabDatas!.firstWhereOrNull((e) => e.finishCount < e.total);