From 1f0f1d48790d1516c531d15c8047877afa4f164e Mon Sep 17 00:00:00 2001 From: machuanyu <840649825@qq.com> Date: Fri, 24 May 2024 15:24:44 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9F=A5=E7=9C=8B=E6=8A=A5=E5=91=8A=EF=BC=8C?= =?UTF-8?q?=E4=BC=98=E5=85=88=E6=89=B9=E9=98=85=EF=BC=8C=E5=8E=86=E5=8F=B2?= =?UTF-8?q?=E4=BD=9C=E4=B8=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/common/api/retrofit_client.dart | 24 +- lib/common/job/annotated_class.dart | 15 +- lib/common/job/class_item.dart | 5 +- lib/common/job/homework_details.dart | 27 +- lib/common/job/student_history.dart | 160 +++++ lib/common/job/student_history_params.dart | 38 ++ lib/common/job/student_item.dart | 97 +-- lib/common/job/student_personal_info.dart | 104 +++ lib/common/utils/utils.dart | 83 ++- lib/main.dart | 21 +- lib/page/global_widget/MyEmptyWidget.dart | 4 +- .../annotate_class/annotate_class_view.dart | 292 +-------- .../annotate_class/widget/annotate_item.dart | 238 +++++++ .../annotate_class/widget/item_btn.dart | 41 ++ .../class_student/class_student_logic.dart | 15 +- .../class_student/class_student_state.dart | 4 +- .../class_student/class_student_view.dart | 581 ++++++++--------- .../children/job_report/job_report_logic.dart | 49 +- .../children/job_report/job_report_state.dart | 21 + .../children/job_report/job_report_view.dart | 108 +++- .../job_report/widget/dropdown_selection.dart | 51 ++ .../job_report/widget/knowledge_point.dart | 291 +++++++++ .../widget/personnel_data_overview.dart | 143 +++++ .../quick_data_check_logic.dart | 4 +- .../quick_data_check_state.dart | 2 +- .../widget/kgt_zgt_table.dart | 11 +- .../widget/quick_data_check_bottom.dart | 1 + .../widget/quick_student_data_table.dart | 3 + .../quick_data_check/widget/report_table.dart | 3 - .../student_history_work_logic.dart | 4 +- .../student_personal_binding.dart | 10 + .../student_personal_logic.dart | 23 + .../student_personal_state.dart | 13 + .../student_personal_view.dart | 232 +++++++ .../widget/student_kg_table.dart | 118 ++++ .../widget/student_zg_table.dart | 152 +++++ .../student_work_detail_binding.dart | 10 + .../student_work_detail_logic.dart | 64 ++ .../student_work_detail_state.dart | 19 + .../student_work_detail_view.dart | 598 ++++++++++++++++++ .../widget/job_condition_filter.dart | 127 ++++ .../widget/personal_detail_topbar.dart | 52 ++ lib/page/home_page/home_logic.dart | 2 +- .../home_page/widget/student_group_list.dart | 4 +- lib/routes/app_pages.dart | 6 + lib/routes/app_routes.dart | 2 + pubspec.lock | 45 ++ pubspec.yaml | 5 + 48 files changed, 3226 insertions(+), 696 deletions(-) create mode 100644 lib/common/job/student_history.dart create mode 100644 lib/common/job/student_history_params.dart create mode 100644 lib/common/job/student_personal_info.dart create mode 100644 lib/page/home_page/children/annotate_class/widget/annotate_item.dart create mode 100644 lib/page/home_page/children/annotate_class/widget/item_btn.dart create mode 100644 lib/page/home_page/children/job_report/widget/dropdown_selection.dart create mode 100644 lib/page/home_page/children/job_report/widget/knowledge_point.dart create mode 100644 lib/page/home_page/children/job_report/widget/personnel_data_overview.dart create mode 100644 lib/page/home_page/children/student_personal/student_personal_binding.dart create mode 100644 lib/page/home_page/children/student_personal/student_personal_logic.dart create mode 100644 lib/page/home_page/children/student_personal/student_personal_state.dart create mode 100644 lib/page/home_page/children/student_personal/student_personal_view.dart create mode 100644 lib/page/home_page/children/student_personal/widget/student_kg_table.dart create mode 100644 lib/page/home_page/children/student_personal/widget/student_zg_table.dart create mode 100644 lib/page/home_page/children/student_work_detail/student_work_detail_binding.dart create mode 100644 lib/page/home_page/children/student_work_detail/student_work_detail_logic.dart create mode 100644 lib/page/home_page/children/student_work_detail/student_work_detail_state.dart create mode 100644 lib/page/home_page/children/student_work_detail/student_work_detail_view.dart create mode 100644 lib/page/home_page/children/student_work_detail/widget/job_condition_filter.dart create mode 100644 lib/page/home_page/children/student_work_detail/widget/personal_detail_topbar.dart diff --git a/lib/common/api/retrofit_client.dart b/lib/common/api/retrofit_client.dart index 0bc8129..393bfba 100644 --- a/lib/common/api/retrofit_client.dart +++ b/lib/common/api/retrofit_client.dart @@ -7,7 +7,10 @@ import 'package:school_asignment_app/common/job/common/base_app_version.dart'; import 'package:school_asignment_app/common/job/common/base_page_data.dart'; import 'package:school_asignment_app/common/job/enum_subject.dart'; import 'package:school_asignment_app/common/job/homework_details.dart'; +import 'package:school_asignment_app/common/job/student_history.dart'; +import 'package:school_asignment_app/common/job/student_history_params.dart'; import 'package:school_asignment_app/common/job/student_item.dart'; +import 'package:school_asignment_app/common/job/student_personal_info.dart'; import 'package:school_asignment_app/common/job/user_info_detail.dart'; import 'package:school_asignment_app/common/job/work_student.dart'; import 'package:school_asignment_app/common/job/work_student_params.dart'; @@ -40,12 +43,12 @@ abstract class RetrofitClient { Future>> getEnumSubjectList(@Query('enumNames') List enumNames); //学生班级 - @GET("/api/rbac/Class/GetTeacherClasses") + @GET("/api/rbac/SchoolUser/GetTeacherClassSubject") Future> getStudentClass(); - //班级学生列表 - @GET("/api/rbac/Class/GetClassStudents") - Future getStudentList(@Query('ClassId') String classId); + //获取优先批阅状态学生列表 + @GET("/api/rbac/Student/GetPriorityAnnotateStudents") + Future> getStudentList(@Query('ClassId') String classId,@Query('Subject') int subject ); //待批阅列表 @GET("/api/hms/Annotate/GetUnAnnotateList") @@ -62,4 +65,17 @@ abstract class RetrofitClient { //作业明细 @GET("/api/hms/HmsReport/GetHomeworkDtls") Future getHomeworkDetails(@Query('homeworkId') String homeworkId,@Query('classId') String classId); + + //学生历史作业 + @GET("/api/hms/HmsReport/GetStudentHistory") + Future getStudentHistory(@Queries() StudentHistoryParams params); + + //修改学生优先批阅状态 + @POST("/api/rbac/Student/PriorityAnnotateStudent") + Future getAnnotateStudent(@Field() String classId, @Field() int studentId,@Field() bool priorityAnnotate,@Field() int subject); + + //学生作业信息 + @GET("/api/hms/HmsReport/GetStudentHomework") + Future getStudentHomework(@Query('HomeworkId') String homeworkId,@Query('StudentId') int studentId); + } diff --git a/lib/common/job/annotated_class.dart b/lib/common/job/annotated_class.dart index 89fb098..5df2396 100644 --- a/lib/common/job/annotated_class.dart +++ b/lib/common/job/annotated_class.dart @@ -9,6 +9,9 @@ class AnnotatedClass extends Object { @JsonKey(name: 'schoolName') String schoolName; + @JsonKey(name: 'grade') + int grade; + @JsonKey(name: 'classId') String classId; @@ -34,7 +37,7 @@ class AnnotatedClass extends Object { int annotateRate; @JsonKey(name: 'students') - List students; + List students; @JsonKey(name: 'homeworkFavs') List homeworkFavs; @@ -54,7 +57,7 @@ class AnnotatedClass extends Object { @JsonKey(name: 'noCommitStudentCount') int? noCommitStudentCount; - AnnotatedClass(this.schoolName,this.classId,this.className,this.finishTime,this.questionCount,this.answerCount,this.answerRate,this.unAnnotateCount,this.annotateRate,this.students,this.homeworkFavs,this.kgtCorrectRate,this.zgtCorrectRate,this.correctRate,this.commitStudentCount,this.noCommitStudentCount); + AnnotatedClass(this.schoolName,this.grade,this.classId,this.className,this.finishTime,this.questionCount,this.answerCount,this.answerRate,this.unAnnotateCount,this.annotateRate,this.students,this.homeworkFavs,this.kgtCorrectRate,this.zgtCorrectRate,this.correctRate,this.commitStudentCount,this.noCommitStudentCount); factory AnnotatedClass.fromJson(Map srcJson) => _$AnnotatedClassFromJson(srcJson); @@ -64,7 +67,7 @@ class AnnotatedClass extends Object { @JsonSerializable() -class Students extends Object { +class AnnotatedStudents extends Object { @JsonKey(name: 'id') String? id; @@ -87,11 +90,11 @@ class Students extends Object { @JsonKey(name: 'state') int state; - Students(this.id,this.isDeleted,this.homeworkId,this.classId,this.studentId,this.studentName,this.state,); + AnnotatedStudents(this.id,this.isDeleted,this.homeworkId,this.classId,this.studentId,this.studentName,this.state,); - factory Students.fromJson(Map srcJson) => _$StudentsFromJson(srcJson); + factory AnnotatedStudents.fromJson(Map srcJson) => _$AnnotatedStudentsFromJson(srcJson); - Map toJson() => _$StudentsToJson(this); + Map toJson() => _$AnnotatedStudentsToJson(this); } diff --git a/lib/common/job/class_item.dart b/lib/common/job/class_item.dart index 2a55638..9ba5342 100644 --- a/lib/common/job/class_item.dart +++ b/lib/common/job/class_item.dart @@ -18,10 +18,13 @@ class ClassItem extends Object { @JsonKey(name: 'className') String className; + @JsonKey(name: 'classId') + String classId; + @JsonKey(name: 'subject') int? subject; - ClassItem(this.id,this.schoolName,this.grade,this.className,this.subject,); + ClassItem(this.id,this.schoolName,this.grade,this.className,this.subject,this.classId); factory ClassItem.fromJson(Map srcJson) => _$ClassItemFromJson(srcJson); diff --git a/lib/common/job/homework_details.dart b/lib/common/job/homework_details.dart index 2a7c500..7a2d135 100644 --- a/lib/common/job/homework_details.dart +++ b/lib/common/job/homework_details.dart @@ -106,7 +106,10 @@ class Knows extends Object { @JsonKey(name: 'okRate') double? okRate; - Knows(this.knowledgeId,this.knowledgeName,this.okCount,this.ttlCount,this.okRate); + @JsonKey(name: 'queDtls') + List? queDtls; + + Knows(this.knowledgeId,this.knowledgeName,this.okCount,this.ttlCount,this.okRate,this.queDtls); factory Knows.fromJson(Map srcJson) => _$KnowsFromJson(srcJson); @@ -163,7 +166,19 @@ class Students extends Object { @JsonKey(name: 'allNotDone') bool? allNotDone; - Students(this.studentId,this.studentName,this.state,this.priorityAnnotate,this.kgtStu,this.kgtOkCount,this.kgtAnswerCount,this.zgtStu,this.zgtAnswerCount,this.zgtOkCount,this.allOk,this.kgtErrorCount,this.zgtErrorCount,this.zgtUnrated,this.allNotDone); + @JsonKey(name: 'queDtls') + List? queDtls; + + @JsonKey(name: 'okRate') + double? okRate; + + @JsonKey(name: 'noAnswerCount') + int? noAnswerCount; + + @JsonKey(name: 'useTime') + int? useTime; + + Students(this.studentId,this.studentName,this.state,this.priorityAnnotate,this.kgtStu,this.kgtOkCount,this.kgtAnswerCount,this.zgtStu,this.zgtAnswerCount,this.zgtOkCount,this.allOk,this.kgtErrorCount,this.zgtErrorCount,this.zgtUnrated,this.allNotDone,this.queDtls,this.okRate,this.noAnswerCount,this.useTime); factory Students.fromJson(Map srcJson) => _$StudentsFromJson(srcJson); @@ -208,7 +223,13 @@ class Dtls extends Object { @JsonKey(name: 'annotatePicture') String? annotatePicture; - Dtls(this.id,this.classId,this.studentId,this.templateId,this.questionNo,this.questionType,this.studentAnswer,this.state,this.useTime,this.annotatePicture,this.studentName); + @JsonKey(name: 'answer') + String? answer; + + @JsonKey(name: 'questionPicture') + String? questionPicture; + + Dtls(this.id,this.classId,this.studentId,this.templateId,this.questionNo,this.questionType,this.studentAnswer,this.state,this.useTime,this.annotatePicture,this.studentName,this.answer,this.questionPicture); factory Dtls.fromJson(Map srcJson) => _$DtlsFromJson(srcJson); diff --git a/lib/common/job/student_history.dart b/lib/common/job/student_history.dart new file mode 100644 index 0000000..d13941c --- /dev/null +++ b/lib/common/job/student_history.dart @@ -0,0 +1,160 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'student_history.g.dart'; + + +@JsonSerializable() +class StudentHistory extends Object { + + @JsonKey(name: 'kgtCorrectRate') + int kgtCorrectRate; + + @JsonKey(name: 'zgtCorrectRate') + int zgtCorrectRate; + + @JsonKey(name: 'items') + Items items; + + @JsonKey(name: 'correctRate') + int correctRate; + + StudentHistory(this.kgtCorrectRate,this.zgtCorrectRate,this.items,this.correctRate); + + factory StudentHistory.fromJson(Map srcJson) => _$StudentHistoryFromJson(srcJson); + + Map toJson() => _$StudentHistoryToJson(this); + +} + + +@JsonSerializable() +class Items extends Object { + + @JsonKey(name: 'items') + List items; + + @JsonKey(name: 'totalCount') + int totalCount; + + Items(this.items,this.totalCount,); + + factory Items.fromJson(Map srcJson) => _$ItemsFromJson(srcJson); + + Map toJson() => _$ItemsToJson(this); + +} + + +@JsonSerializable() +class StudentItems extends Object { + + @JsonKey(name: 'id') + String id; + + @JsonKey(name: 'assessType') + int assessType; + + @JsonKey(name: 'name') + String name; + + @JsonKey(name: 'grade') + int grade; + + @JsonKey(name: 'subject') + int subject; + + @JsonKey(name: 'publishTime') + String publishTime; + + @JsonKey(name: 'state') + int state; + + @JsonKey(name: 'kgtCorrectRate') + int kgtCorrectRate; + + @JsonKey(name: 'kgtList') + List kgtList; + + @JsonKey(name: 'zgtCorrectRate') + int zgtCorrectRate; + + @JsonKey(name: 'zgtList') + List zgtList; + + @JsonKey(name: 'correctRate') + int correctRate; + + //全部未做 + @JsonKey(name: 'allNotDone') + bool allNotDone; + + StudentItems(this.id,this.assessType,this.name,this.grade,this.subject,this.publishTime,this.state,this.kgtCorrectRate,this.kgtList,this.zgtCorrectRate,this.zgtList,this.correctRate, + [this.allNotDone = false]); + + factory StudentItems.fromJson(Map srcJson) => _$StudentItemsFromJson(srcJson); + + Map toJson() => _$StudentItemsToJson(this); + +} + + +@JsonSerializable() +class KgtList extends Object { + + @JsonKey(name: 'id') + String id; + + @JsonKey(name: 'questionNo') + int questionNo; + + @JsonKey(name: 'questionType') + int questionType; + + @JsonKey(name: 'state') + int state; + + @JsonKey(name: 'useTime') + int? useTime; + + @JsonKey(name: 'picture') + String? picture; + + KgtList(this.id,this.questionNo,this.questionType,this.state,this.useTime,this.picture,); + + factory KgtList.fromJson(Map srcJson) => _$KgtListFromJson(srcJson); + + Map toJson() => _$KgtListToJson(this); + +} + + +@JsonSerializable() +class ZgtList extends Object { + + @JsonKey(name: 'id') + String id; + + @JsonKey(name: 'questionNo') + int questionNo; + + @JsonKey(name: 'questionType') + int questionType; + + @JsonKey(name: 'state') + int state; + + @JsonKey(name: 'useTime') + int? useTime; + + @JsonKey(name: 'picture') + String? picture; + + ZgtList(this.id,this.questionNo,this.questionType,this.state,this.useTime,this.picture,); + + factory ZgtList.fromJson(Map srcJson) => _$ZgtListFromJson(srcJson); + + Map toJson() => _$ZgtListToJson(this); + +} + + diff --git a/lib/common/job/student_history_params.dart b/lib/common/job/student_history_params.dart new file mode 100644 index 0000000..1838c4c --- /dev/null +++ b/lib/common/job/student_history_params.dart @@ -0,0 +1,38 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'student_history_params.g.dart'; + + +@JsonSerializable() +class StudentHistoryParams extends Object { + + @JsonKey(name: 'Subject') + int? subject; + + @JsonKey(name: 'StudentId') + int studentId; + + @JsonKey(name: 'DateStart') + String dateStart; + + @JsonKey(name: 'DateEnd') + String? dateEnd; + + @JsonKey(name: 'AssessType') + int assessType; + + @JsonKey(name: 'PageNumber') + int pageNumber; + + @JsonKey(name: 'PageSize') + int pageSize; + + StudentHistoryParams({this.subject,this.studentId = -1,this.dateStart = '',this.dateEnd,this.assessType = 0,this.pageNumber = 1,this.pageSize = 10}); + + factory StudentHistoryParams.fromJson(Map srcJson) => _$StudentHistoryParamsFromJson(srcJson); + + Map toJson() => _$StudentHistoryParamsToJson(this); + +} + + diff --git a/lib/common/job/student_item.dart b/lib/common/job/student_item.dart index 410fdc8..d3e84ef 100644 --- a/lib/common/job/student_item.dart +++ b/lib/common/job/student_item.dart @@ -6,13 +6,19 @@ part 'student_item.g.dart'; @JsonSerializable() class StudentItem extends Object { - @JsonKey(name: 'items') - List items; + @JsonKey(name: 'name') + String name; - @JsonKey(name: 'totalCount') - int totalCount; + @JsonKey(name: 'isActive') + bool isActive; - StudentItem(this.items,this.totalCount,); + @JsonKey(name: 'priorityAnnotate') + bool priorityAnnotate; + + @JsonKey(name: 'id') + int id; + + StudentItem(this.name,this.isActive,this.priorityAnnotate,this.id,); factory StudentItem.fromJson(Map srcJson) => _$StudentItemFromJson(srcJson); @@ -21,84 +27,3 @@ class StudentItem extends Object { } -@JsonSerializable() -class Items extends Object { - - @JsonKey(name: 'id') - String id; - - @JsonKey(name: 'studentCode') - String studentCode; - - @JsonKey(name: 'name') - String name; - - @JsonKey(name: 'gender') - int gender; - - @JsonKey(name: 'guardianPhone') - String? guardianPhone; - - @JsonKey(name: 'idCard') - String? idCard; - - @JsonKey(name: 'penSerial') - String penSerial; - - @JsonKey(name: 'isActive') - bool isActive; - - @JsonKey(name: 'classStudentId') - String classStudentId; - - @JsonKey(name: 'grade') - int grade; - - @JsonKey(name: 'classId') - String classId; - - @JsonKey(name: 'className') - String className; - - @JsonKey(name: 'evaluationLevel') - int evaluationLevel; - - @JsonKey(name: 'subjectStatus') - List subjectStatus; - - @JsonKey(name: 'creatorName') - String creatorName; - - @JsonKey(name: 'creationTime') - String creationTime; - - Items(this.id,this.studentCode,this.name,this.gender,this.guardianPhone,this.idCard,this.penSerial,this.isActive,this.classStudentId,this.grade,this.classId,this.className,this.evaluationLevel,this.subjectStatus,this.creatorName,this.creationTime,); - - factory Items.fromJson(Map srcJson) => _$ItemsFromJson(srcJson); - - Map toJson() => _$ItemsToJson(this); - -} - - -@JsonSerializable() -class SubjectStatus extends Object { - - @JsonKey(name: 'subject') - int subject; - - @JsonKey(name: 'evaluationLevel') - int evaluationLevel; - - @JsonKey(name: 'priorityAnnotate') - bool priorityAnnotate; - - SubjectStatus(this.subject,this.evaluationLevel,this.priorityAnnotate,); - - factory SubjectStatus.fromJson(Map srcJson) => _$SubjectStatusFromJson(srcJson); - - Map toJson() => _$SubjectStatusToJson(this); - -} - - diff --git a/lib/common/job/student_personal_info.dart b/lib/common/job/student_personal_info.dart new file mode 100644 index 0000000..4009ff9 --- /dev/null +++ b/lib/common/job/student_personal_info.dart @@ -0,0 +1,104 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'student_personal_info.g.dart'; + + +@JsonSerializable() +class StudentPersonalInfo extends Object { + + @JsonKey(name: 'studentId') + int studentId; + + @JsonKey(name: 'studentName') + String studentName; + + @JsonKey(name: 'correctRate') + int correctRate; + + @JsonKey(name: 'kgtCorrectRate') + int kgtCorrectRate; + + @JsonKey(name: 'kgtList') + List kgtList; + + @JsonKey(name: 'zgtCorrectRate') + int zgtCorrectRate; + + @JsonKey(name: 'zgtList') + List zgtList; + + StudentPersonalInfo(this.studentId,this.studentName,this.correctRate,this.kgtCorrectRate,this.kgtList,this.zgtCorrectRate,this.zgtList,); + + factory StudentPersonalInfo.fromJson(Map srcJson) => _$StudentPersonalInfoFromJson(srcJson); + + Map toJson() => _$StudentPersonalInfoToJson(this); + +} + + +@JsonSerializable() +class KgtList extends Object { + + @JsonKey(name: 'templateId') + int templateId; + + @JsonKey(name: 'questionNo') + int questionNo; + + @JsonKey(name: 'answer') + String? answer; + + @JsonKey(name: 'studentAnswer') + String? studentAnswer; + + @JsonKey(name: 'useTime') + int useTime; + + @JsonKey(name: 'isCorrect') + bool? isCorrect; + + @JsonKey(name: 'picture') + String? picture; + + KgtList(this.templateId,this.questionNo,this.answer,this.studentAnswer,this.useTime,this.isCorrect,this.picture,); + + factory KgtList.fromJson(Map srcJson) => _$KgtListFromJson(srcJson); + + Map toJson() => _$KgtListToJson(this); + +} + + +@JsonSerializable() +class ZgtList extends Object { + + @JsonKey(name: 'templateId') + int templateId; + + @JsonKey(name: 'questionNo') + int questionNo; + + @JsonKey(name: 'answer') + String? answer; + + @JsonKey(name: 'studentAnswer') + String? studentAnswer; + + @JsonKey(name: 'useTime') + int useTime; + + @JsonKey(name: 'isCorrect') + bool? isCorrect; + + @JsonKey(name: 'picture') + String? picture; + + ZgtList(this.templateId,this.questionNo,this.answer,this.studentAnswer,this.useTime,this.isCorrect,this.picture,); + + factory ZgtList.fromJson(Map srcJson) => _$ZgtListFromJson(srcJson); + + Map toJson() => _$ZgtListToJson(this); + +} + + diff --git a/lib/common/utils/utils.dart b/lib/common/utils/utils.dart index c4f2b33..afa7987 100644 --- a/lib/common/utils/utils.dart +++ b/lib/common/utils/utils.dart @@ -49,17 +49,38 @@ class Utils{ return ((100 * divisor) / dividend); // return ((100 * divisor) / dividend).toStringAsFixed(0); }else{ - return 0; + return 0.0; } } + /// 秒转时分秒 + static String second2HMS(int sec, {bool isEasy = false}) { + String hms = "0"; + if (!isEasy) hms = "0秒"; + if (sec > 0) { + int h = sec ~/ 3600; + int m = (sec % 3600) ~/ 60; + int s = sec % 60; + if(h>0){ + hms = "$h时$m分$s秒"; + }else{ + if(m>0){ + hms = "$m分$s秒"; + }else{ + hms = "$s秒"; + } + } + } + return hms; + } + static getHomeworkData(HomeworkDetails data){ CountData dataCount = CountData(); List kgt = data.dtls.where((w) => w.questionType == 1).toList(); dataCount.kgtAnswerCount = kgt.where((w) => w.state != 0).length; - dataCount.kgtOkCount = kgt.where((w) => w.state == 4).length; + dataCount.kgtOkCount = kgt.where((w) => w.state == 3).length; dataCount.kgtDtlCount = kgt.length; dataCount.kgtAnswerRate = Utils.calcRate(dataCount.kgtAnswerCount!, dataCount.kgtDtlCount!); dataCount.kgtOkRate = Utils.calcRate(dataCount.kgtOkCount!, dataCount.kgtDtlCount!); @@ -67,7 +88,7 @@ class Utils{ List zgt = data.dtls.where((w) => w.questionType == 2).toList(); dataCount.zgtAnswerCount = zgt.where((w) => w.state != 0).length; - dataCount.zgtOkCount = zgt.where((w) => w.state == 4).length; + dataCount.zgtOkCount = zgt.where((w) => w.state == 3).length; dataCount.zgtDtlCount = zgt.length; dataCount.zgtAnswerRate = Utils.calcRate(dataCount.zgtAnswerCount!, dataCount.zgtDtlCount!); dataCount.zgtOkRate = Utils.calcRate(dataCount.zgtOkCount!, dataCount.zgtDtlCount!); @@ -80,13 +101,13 @@ class Utils{ List ques = data.dtls.where((w) => w.templateId == que.templateId && w.questionNo == que.questionNo).toList(); que.answerCount = ques.where((w) => w.state != 0).length; que.answerRate = Utils.calcRate(que.answerCount!, dataCount.studentCount!); - int okCount = ques.where((w) => w.state == 4).length; + int okCount = ques.where((w) => w.state == 3).length; que.okRate = Utils.calcRate(okCount, dataCount.studentCount!) ; que.priorityInfo = ques.where((w) { return dataCount.priorityStudents!.indexWhere((s) { w.studentName = s.studentName; return s.studentId == w.studentId; - }) > -1 && w.state != 4; + }) > -1 && w.state != 3; }).toList(); que.answerNgStudents = ques.where((w) { @@ -98,35 +119,51 @@ class Utils{ return w.state == 0; }).toList(); que.answerOkStudents = ques.where((w) { - return w.state == 4; + return w.state == 3; }).toList(); } - - - dataCount.studentSubmitCount = data.students.where((s) => s.state != 0).length; for(var stu in data.students){ stu.kgtStu = kgt.where((w) => w.studentId == stu.studentId).toList(); stu.kgtStu!.sort((a, b) => a.questionNo.compareTo(b.questionNo)); - stu.kgtOkCount = stu.kgtStu!.where((w) => w.state == 4).length; + stu.kgtOkCount = stu.kgtStu!.where((w) => w.state == 3).length; stu.kgtErrorCount = stu.kgtStu!.where((w) => w.state == 2).length; stu.kgtAnswerCount = stu.kgtStu!.where((w) => w.state != 0).length; stu.zgtStu = zgt.where((w) => w.studentId == stu.studentId).toList(); stu.zgtStu!.sort((a, b) => a.questionNo.compareTo(b.questionNo)); - stu.zgtOkCount = stu.zgtStu!.where((w) => w.state == 4).length; + stu.zgtOkCount = stu.zgtStu!.where((w) => w.state == 3).length; stu.zgtErrorCount = stu.zgtStu!.where((w) => w.state == 2).length; stu.zgtUnrated = stu.zgtStu!.where((w) => w.state == 1).length; stu.zgtAnswerCount = stu.zgtStu!.where((w) => w.state != 0).length; - stu.allOk = data.dtls.where((w) => w.studentId == stu.studentId && w.state != 4).length??0; + stu.allOk = data.dtls.where((w) { + if(stu.studentId == w.studentId){ + stu.useTime = w.useTime; + } + for(var que in data.questions){ + if(w.templateId == que.templateId && w.questionNo == que.questionNo){ + w.answer = que.answer; + w.questionPicture = que.questionPicture; + } + } + return w.studentId == stu.studentId && w.state != 3; + } ).length??0; if( (stu.kgtStu!.length - stu.kgtAnswerCount!) + (stu.zgtStu!.length-stu.zgtAnswerCount!) == (stu.kgtStu!.length + stu.zgtStu!.length)){ stu.allNotDone = true; }else{ stu.allNotDone = false; } + stu.noAnswerCount = data.dtls.where((w) => w.state == 0 && stu.studentId == w.studentId).length; + + List ques = data.questions; + stu.queDtls =data.dtls.where((w) => w.studentId == stu.studentId && ques.indexWhere((q) => w.templateId == q.templateId && w.questionNo == q.questionNo) > -1).toList(); + int okCount = stu.queDtls!.where((w) => w.state == 3).length; + int ttlCount = stu.queDtls!.length; + stu.okRate = Utils.calcRate(okCount, ttlCount); + } data.students.sort((a, b) { @@ -138,11 +175,31 @@ class Utils{ for(var know in data.knows){ List ques = data.questions.where((w) => w.knows.indexWhere((k) => k.knowledgeId == know.knowledgeId) > -1).toList(); List queDtls = data.dtls.where((w) => ques.indexWhere((q) => w.templateId == q.templateId && w.questionNo == q.questionNo) > -1).toList(); - know.okCount = queDtls.where((w) => w.state == 4).length; + know.okCount = queDtls.where((w) => w.state == 3).length; know.ttlCount = queDtls.length; know.okRate = Utils.calcRate(know.okCount!, know.ttlCount!); } return dataCount; } + + static DateTime getWeekStartDate() { + DateTime now = DateTime.now(); + int dayOfWeek = now.weekday; // 获取今天是周几(1代表周一,7代表周日) + int diff = dayOfWeek - 1; // 计算今天距离周一的天数差 + if (diff < 0) { + diff += 7; // 如果是周日,则需要加上一周的天数 + } + return now.subtract(Duration(days: diff)); // 减去天数差,得到本周一的时间 + } + + static DateTime getWeekEndDate() { + DateTime now = DateTime.now(); + int dayOfWeek = now.weekday; // 获取今天是周几 + int diff = 7 - dayOfWeek; // 计算今天距离周日的天数差 + if (diff == 0) { + diff = 7; // 如果是周日,则加上一周的天数 + } + return now.add(Duration(days: diff)); // 加上天数差减一,得到本周日的时间 + } } \ No newline at end of file diff --git a/lib/main.dart b/lib/main.dart index 21d2e0e..e6cad94 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import 'package:school_asignment_app/common/config/app_config.dart'; @@ -33,6 +34,8 @@ class MyApp extends StatelessWidget { Widget build(BuildContext context) { return ScreenUtilInit( designSize: const Size(AppConfig.UI_WIDTH, AppConfig.UI_HEIGHT), + minTextAdapt: true, + splitScreenMode: true, builder: (BuildContext context, Widget? child) => GetMaterialApp( title: '作业', theme: ThemeData( @@ -49,11 +52,27 @@ class MyApp extends StatelessWidget { logWriterCallback: (text, {bool isError = false}) { // isError ? LoggerUtils.e(text) : LoggerUtils.i(text); }, + // 这里是国际化支持,确保添加flutter_localizations依赖 + supportedLocales: const [ + Locale('zh', 'CN'), // 中文简体 + // 其他支持的locale可以在这里添加 + ], + localizationsDelegates: const [ + // ...其他delegates + GlobalMaterialLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + GlobalCupertinoLocalizations.delegate, // 如果你使用了Cupertino风格的组件 + // ...添加其他必要的delegates + ], + localeResolutionCallback: (locale, supportedLocales) { + // 在这里可以实现自定义的locale解析逻辑 + // 如果需要,返回你想要的Locale对象 + return locale; + }, //默认专场动画 defaultTransition: Transition.fade, //初始化路由页面 initialRoute: Routes.startPage, - /// 路由表 getPages: AppPages.pages, builder: EasyLoading.init( diff --git a/lib/page/global_widget/MyEmptyWidget.dart b/lib/page/global_widget/MyEmptyWidget.dart index 4febf96..884f7a8 100644 --- a/lib/page/global_widget/MyEmptyWidget.dart +++ b/lib/page/global_widget/MyEmptyWidget.dart @@ -19,12 +19,14 @@ class MyEmptyWidget extends StatelessWidget { final EdgeInsets? padding; final double? imgWidth; final double? imgHeight; + final double? font; const MyEmptyWidget( {this.imgWidth, this.imgHeight, this.textVal, this.padding, this.imgAssetPath, + this.font, this.alignment = Alignment.center, Key? key}) : super(key: key); @@ -50,7 +52,7 @@ class MyEmptyWidget extends StatelessWidget { padding: EdgeInsets.only(top: 5.h), child: Text( textVal ?? defText, - style: TextStyle(fontSize: 12.sp, color: const Color(0xB2898B8D)), + style: TextStyle(fontSize: font ?? 12.sp, color: const Color(0xB2898B8D)), ), ) ], diff --git a/lib/page/home_page/children/annotate_class/annotate_class_view.dart b/lib/page/home_page/children/annotate_class/annotate_class_view.dart index bc34148..465113e 100644 --- a/lib/page/home_page/children/annotate_class/annotate_class_view.dart +++ b/lib/page/home_page/children/annotate_class/annotate_class_view.dart @@ -1,10 +1,13 @@ import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart'; import 'package:get/get.dart'; import 'package:percent_indicator/percent_indicator.dart'; import 'package:school_asignment_app/common/job/annotated_class.dart'; +import 'package:school_asignment_app/common/utils/utils.dart'; import 'package:school_asignment_app/page/global_widget/ReturnToHomepage.dart'; import 'package:school_asignment_app/page/global_widget/my_text.dart'; +import 'package:school_asignment_app/page/home_page/children/annotate_class/widget/annotate_item.dart'; import 'package:school_asignment_app/page/home_page/widget/progress_bar.dart'; import 'package:school_asignment_app/routes/app_pages.dart'; import 'annotate_class_logic.dart'; @@ -43,285 +46,22 @@ class _AnnotateClassPageState extends State { body: Padding( padding: EdgeInsets.symmetric(vertical: 14.r, horizontal: 14.r), child: Obx(() { - return ListView.builder( + return + Utils.isPad()?MasonryGridView.count( + crossAxisCount: 2, //几列 + mainAxisSpacing: 4.w, // 间距 + crossAxisSpacing: 4.h, // 纵向间距? itemCount: state.classList.length, itemBuilder: (context, index) { AnnotatedClass item = state.classList[index]; - return Container( - padding: EdgeInsets.only(top: 10.r), - margin: EdgeInsets.only(bottom: 10.r), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadiusDirectional.circular(4.r), - boxShadow: const [BoxShadow(color: Color.fromRGBO(0, 0, 0, 0.15), blurRadius: 10)], - ), - child: Column( - children: [ - Padding( - padding: EdgeInsets.symmetric(horizontal: 10.r), - child: Row( - children: [ - Text( - item.className, - style: TextStyle( - fontSize: 14.sp, - color: const Color(0xFF000000)), - ), - const Spacer(), - Text( - '已交:${item.commitStudentCount}', - style: TextStyle( - fontSize: 12.sp, - color: const Color(0xFF6888FD)), - ), - SizedBox( - width: 20.r, - ), - Text( - '未交:${item.noCommitStudentCount}', - style: TextStyle( - fontSize: 12.sp, - color: const Color(0xFFFF5656)), - ), - ], - ), - ), - SizedBox( - height: 10.r, - ), - Padding( - padding: EdgeInsets.symmetric(horizontal: 10.r), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: - item.finishTime != null ? - [ - Expanded( - flex:4, - child: InkWell( - splashColor: Theme.of(context).primaryColor, - child: ElevatedButton( - style: ButtonStyle( - overlayColor:MaterialStateProperty.all( - const Color(0xFF6888FD)), - backgroundColor: - MaterialStateProperty.all( - const Color(0xFFF4F4F4)), - // foregroundColor: MaterialStateProperty.all(Colors.red.shade200),//文字颜色 - shape: MaterialStateProperty.all( - RoundedRectangleBorder( - borderRadius: - BorderRadius.circular(22), //设置圆角 - ))), - onPressed: () {}, - child: Text( - "收藏夹", - style: TextStyle( - fontSize: 10.sp, - color: const Color(0xFF666666)), - )), - ), - ), - const Expanded(flex: 1, child: SizedBox()), - const Expanded(flex: 4, child: SizedBox()), - const Expanded(flex: 1, child: SizedBox()), - const Expanded(flex: 4, child: SizedBox()), - - ]:[ - Expanded( - flex: 4, - child: ElevatedButton( - style: ButtonStyle( - overlayColor:MaterialStateProperty.all( - const Color(0xFF6888FD)), - backgroundColor: - MaterialStateProperty.all( - const Color(0xFFF4F4F4)), - // foregroundColor: MaterialStateProperty.all(Colors.red.shade200),//文字颜色 - shape: MaterialStateProperty.all( - RoundedRectangleBorder( - borderRadius: - BorderRadius.circular(22), //设置圆角 - ))), - onPressed: () {}, - child: Text( - "一键批阅", - style: TextStyle( - fontSize: 10.sp, color: const Color(0xFF666666)), - )), - ), - const Expanded(flex: 1,child: Text(''),), - Expanded( - flex:4, - child: ElevatedButton( - style: ButtonStyle( - overlayColor:MaterialStateProperty.all( - const Color(0xFF6888FD)), - backgroundColor: - MaterialStateProperty.all( - const Color(0xFFF4F4F4)), - // foregroundColor: MaterialStateProperty.all(Colors.red.shade200),//文字颜色 - shape: MaterialStateProperty.all( - RoundedRectangleBorder( - borderRadius: - BorderRadius.circular(22), //设置圆角 - ))), - onPressed: () { - Get.toNamed(Routes.quickDataCheckPage,arguments: {'homeworkId':state.homeworkId.value,'classId':item.classId,'grade':state.grade,'className':item.className - }); - }, - child: Text( - "数据快查", - style: TextStyle( - fontSize: 10.sp, - color: const Color(0xFF666666)), - )), - ), - const Expanded(flex: 1,child: Text(''),), - Expanded( - flex:4, - child: ElevatedButton( - style: ButtonStyle( - overlayColor:MaterialStateProperty.all( - const Color(0xFF6888FD)), - backgroundColor: - MaterialStateProperty.all( - const Color(0xFFF4F4F4)), - // foregroundColor: MaterialStateProperty.all(Colors.red.shade200),//文字颜色 - shape: MaterialStateProperty.all( - RoundedRectangleBorder( - borderRadius: - BorderRadius.circular(22), //设置圆角 - ))), - onPressed: () {}, - child: Text( - "收藏夹", - style: TextStyle( - fontSize: 10.sp, - color: const Color(0xFF666666)), - )), - ), - ], - ), - ), - Padding( - padding: EdgeInsets.symmetric(vertical: 10.r,horizontal: 14.r), - child: Row( - children: [ - Expanded( - child: LinearPercentIndicator( - padding: EdgeInsets.zero, - animation: true, - lineHeight: 8.h, - animationDuration: 2500, - - percent: item.annotateRate / 100, - linearGradient: LinearGradient( - tileMode: TileMode.mirror, - stops: const [0.0, 1.0], - colors: item.annotateRate / 100 != 1 - ? [Theme.of(context).primaryColor.withOpacity(0.1), Theme.of(context).primaryColor] - : [ - const Color.fromRGBO(144, 224, 190, 1).withOpacity(0.1), - const Color.fromRGBO(144, 224, 190, 1), - ], - ), - // linearStrokeCap: LinearStrokeCap.butt, - // progressColor: Theme.of(context).primaryColor, - backgroundColor: const Color.fromRGBO(232, 232, 232, 1), - barRadius: Radius.circular(10.r), - ), - ), - SizedBox(width: 7.w), - quickText('${item.annotateRate}%', - size: 10.sp, color: const Color.fromRGBO(70, 70, 70, 1)) - ], - ), - ), - ProgressBar( - title: '客观题正确率:', - color: const Color(0xFFB8C7FF), - percent: item.kgtCorrectRate / 100, - marginEdg: EdgeInsets.zero, - padingEdg: EdgeInsets.only(top: 8.h,left: 14.r,right: 14.r)), - ProgressBar( - title: '主观题正确率:', - color: const Color(0xFFB8C7FF), - percent: item.zgtCorrectRate / 100, - padingEdg: EdgeInsets.symmetric(horizontal: 10.r), - marginEdg: EdgeInsets.only(top: 8.h)), - ProgressBar( - title: '总正确率:', - color: const Color(0xFFB8C7FF), - percent: item.correctRate / 100, - padingEdg: EdgeInsets.symmetric(horizontal: 10.r), - marginEdg: EdgeInsets.only(top: 8.h)), - - Container( - margin: EdgeInsets.only(top: 10.r), - decoration: BoxDecoration( - borderRadius: BorderRadius.only(bottomLeft: Radius.circular(4.r), bottomRight: Radius.circular(4.r)), - color: Colors.white, - boxShadow: const [ - BoxShadow( - color: Color.fromRGBO(0, 0, 0, 0.15), - offset: Offset(0, -0.0001), //阴影y轴偏移量 - blurRadius: 4, //阴影模糊程度 - spreadRadius: 0, //阴影扩散程度 - ) - ], - ), - - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: - item.finishTime != null ? - [ - Expanded( - child: InkWell( - onTap: () {}, - child: Container( - alignment: Alignment.center, - child: quickText('数据快查', color: Color.fromRGBO(118, 118, 118, 1), size: 12.sp), - ), - ), - ), - Container(width: 1.w, height: 30.h, color: const Color.fromRGBO(221, 221, 221, 1)), - Expanded( - child: InkWell( - onTap: () {}, - child: Container( - alignment: Alignment.center, - child: quickText('查看报告', color: Color.fromRGBO(118, 118, 118, 1), size: 12.sp), - ), - )), - ] - : - [ - Expanded( - child: InkWell( - onTap: () {}, - child: Container( - alignment: Alignment.center, - child: quickText('批阅', color: const Color.fromRGBO(118, 118, 118, 1), size: 12.sp), - ), - ), - ), - Container(width: 1.w, height: 30.h, color: const Color.fromRGBO(221, 221, 221, 1)), - Expanded( - child: InkWell( - onTap: () {}, - child: Container( - alignment: Alignment.center, - child: quickText('结束批阅', color: const Color.fromRGBO(118, 118, 118, 1), size: 12.sp), - ), - )), - ], - ), - ) - ], - ), - ); + return AnnotateItem(item: item,font: 8.sp,state: state,name: state.name.value,); + }, + ): + ListView.builder( + itemCount: state.classList.length, + itemBuilder: (context, index) { + AnnotatedClass item = state.classList[index]; + return AnnotateItem(item: item,font: 12.sp,state: state,name: state.name.value,); }); }), ), diff --git a/lib/page/home_page/children/annotate_class/widget/annotate_item.dart b/lib/page/home_page/children/annotate_class/widget/annotate_item.dart new file mode 100644 index 0000000..4a1f6be --- /dev/null +++ b/lib/page/home_page/children/annotate_class/widget/annotate_item.dart @@ -0,0 +1,238 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:get/get.dart'; +import 'package:percent_indicator/percent_indicator.dart'; +import 'package:school_asignment_app/common/job/annotated_class.dart'; +import 'package:school_asignment_app/common/utils/enum_untils.dart'; +import 'package:school_asignment_app/page/global_widget/my_text.dart'; +import 'package:school_asignment_app/page/home_page/children/annotate_class/annotate_class_state.dart'; +import 'package:school_asignment_app/page/home_page/children/annotate_class/widget/item_btn.dart'; +import 'package:school_asignment_app/page/home_page/widget/progress_bar.dart'; +import 'package:school_asignment_app/routes/app_pages.dart'; + +class AnnotateItem extends StatefulWidget { +final AnnotatedClass item; +final double font; +final AnnotateClassState state; +final String name; + const AnnotateItem({Key? key, required this.item,required this.font,required this.state,required this.name}) : super(key: key); + + @override + State createState() => _AnnotateItemState(); +} + +class _AnnotateItemState extends State { + @override + Widget build(BuildContext context) { + return Container( + padding: EdgeInsets.only(top: 10.r), + margin: EdgeInsets.only(bottom: 10.r), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadiusDirectional.circular(4.r), + boxShadow: const [BoxShadow(color: Color.fromRGBO(0, 0, 0, 0.15), blurRadius: 10)], + ), + child: Column( + children: [ + Padding( + padding: EdgeInsets.symmetric(horizontal: 10.r), + child: Row( + children: [ + Text( + '${EnumUtils.formatGrade(widget.item.grade)}${widget.item.className}', + style: TextStyle( + fontSize: widget.font, + color: const Color(0xFF000000)), + ), + const Spacer(), + Text( + '已交:${widget.item.commitStudentCount}', + style: TextStyle( + fontSize: widget.font - 2.sp, + color: const Color(0xFF6888FD)), + ), + SizedBox( + width: 20.r, + ), + Text( + '未交:${widget.item.noCommitStudentCount}', + style: TextStyle( + fontSize: widget.font - 2.sp, + color: const Color(0xFFFF5656)), + ), + ], + ), + ), + SizedBox( + height: 10.r, + ), + Padding( + padding: EdgeInsets.symmetric(horizontal: 8.r), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: + widget.item.finishTime != null ? + [ + Expanded( + flex:4, + child:ItemBtn(title: "收藏夹",font: widget.font - 2.sp, + clickFunction: (){ + + },), + ), + const Expanded(flex: 1, child: SizedBox()), + const Expanded(flex: 4, child: SizedBox()), + const Expanded(flex: 1, child: SizedBox()), + const Expanded(flex: 4, child: SizedBox()), + + ]:[ + Expanded( + flex: 4, + child: ItemBtn(title: "一键批阅",font: widget.font - 2.sp, + clickFunction: (){ + + },), + ), + const Expanded(flex: 1,child: Text(''),), + Expanded( + flex:4, + child: ItemBtn(title: "数据快查",font: widget.font - 2.sp,clickFunction: (){ + Get.toNamed(Routes.quickDataCheckPage,arguments: {'homeworkId':widget.state.homeworkId.value,'classId':widget.item.classId,'grade':widget.state.grade,'className':widget.item.className + }); + // Get.toNamed(Routes.jobReportPage,arguments: {'title':widget.name,'homeworkId':widget.state.homeworkId.value,'classId':widget.item.classId,'grade':widget.state.grade,'className':widget.item.className}); + },), + ), + const Expanded(flex: 1,child: Text(''),), + Expanded( + flex:4, + child: ItemBtn(title: "收藏夹",font: widget.font - 2.sp, + clickFunction: (){ + + },), + ), + ], + ), + ), + Padding( + padding: EdgeInsets.symmetric(vertical: 10.r,horizontal: 14.r), + child: Row( + children: [ + Expanded( + child: LinearPercentIndicator( + padding: EdgeInsets.zero, + animation: true, + lineHeight: 8.h, + animationDuration: 2500, + + percent: widget.item.annotateRate / 100, + linearGradient: LinearGradient( + tileMode: TileMode.mirror, + stops: const [0.0, 1.0], + colors: widget.item.annotateRate / 100 != 1 + ? [Theme.of(context).primaryColor.withOpacity(0.1), Theme.of(context).primaryColor] + : [ + const Color.fromRGBO(144, 224, 190, 1).withOpacity(0.1), + const Color.fromRGBO(144, 224, 190, 1), + ], + ), + // linearStrokeCap: LinearStrokeCap.butt, + // progressColor: Theme.of(context).primaryColor, + backgroundColor: const Color.fromRGBO(232, 232, 232, 1), + barRadius: Radius.circular(10.r), + ), + ), + SizedBox(width: 7.w), + quickText('${widget.item.annotateRate}%', + size: widget.font - 2.sp, color: const Color.fromRGBO(70, 70, 70, 1)) + ], + ), + ), + ProgressBar( + title: '客观题正确率:', + color: const Color(0xFFB8C7FF), + percent: widget.item.kgtCorrectRate / 100, + marginEdg: EdgeInsets.zero, + padingEdg: EdgeInsets.only(top: 8.h,left: 14.r,right: 14.r), + fontSize:widget.font - 2.sp), + ProgressBar( + title: '主观题正确率:', + color: const Color(0xFFB8C7FF), + percent: widget.item.zgtCorrectRate / 100, + padingEdg: EdgeInsets.symmetric(horizontal: 10.r), + marginEdg: EdgeInsets.only(top: 8.h), + fontSize:widget.font - 2.sp), + ProgressBar( + title: '总正确率:', + color: const Color(0xFFB8C7FF), + percent: widget.item.correctRate / 100, + padingEdg: EdgeInsets.symmetric(horizontal: 10.r), + marginEdg: EdgeInsets.only(top: 8.h), + fontSize:widget.font - 2.sp), + + Container( + margin: EdgeInsets.only(top: 10.r), + decoration: BoxDecoration( + borderRadius: BorderRadius.only(bottomLeft: Radius.circular(4.r), bottomRight: Radius.circular(4.r)), + color: Colors.white, + boxShadow: const [ + BoxShadow( + color: Color.fromRGBO(0, 0, 0, 0.15), + offset: Offset(0, -0.0001), //阴影y轴偏移量 + blurRadius: 4, //阴影模糊程度 + spreadRadius: 0, //阴影扩散程度 + ) + ], + ), + + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: + widget.item.finishTime != null ? + [ + Expanded( + child: InkWell( + onTap: () {}, + child: Container( + alignment: Alignment.center, + child: quickText('数据快查', color: Color.fromRGBO(118, 118, 118, 1), size: widget.font), + ), + ), + ), + Container(width: 1.w, height: 30.h, color: const Color.fromRGBO(221, 221, 221, 1)), + Expanded( + child: InkWell( + onTap: () {}, + child: Container( + alignment: Alignment.center, + child: quickText('查看报告', color: Color.fromRGBO(118, 118, 118, 1), size: widget.font), + ), + )), + ] + : + [ + Expanded( + child: InkWell( + onTap: () {}, + child: Container( + alignment: Alignment.center, + child: quickText('批阅', color: const Color.fromRGBO(118, 118, 118, 1), size: widget.font), + ), + ), + ), + Container(width: 1.w, height: 30.h, color: const Color.fromRGBO(221, 221, 221, 1)), + Expanded( + child: InkWell( + onTap: () {}, + child: Container( + alignment: Alignment.center, + child: quickText('结束批阅', color: const Color.fromRGBO(118, 118, 118, 1), size: widget.font), + ), + )), + ], + ), + ) + ], + ), + ); + } +} diff --git a/lib/page/home_page/children/annotate_class/widget/item_btn.dart b/lib/page/home_page/children/annotate_class/widget/item_btn.dart new file mode 100644 index 0000000..fa50059 --- /dev/null +++ b/lib/page/home_page/children/annotate_class/widget/item_btn.dart @@ -0,0 +1,41 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; + +class ItemBtn extends StatelessWidget { + final String title; + final double font; + final Function? clickFunction; + const ItemBtn({Key? key,required this.title,required this.font,this.clickFunction}) : super(key: key); + + @override + Widget build(BuildContext context) { + return SizedBox( + height:20.r, + child: ElevatedButton( + style: ButtonStyle( + overlayColor:MaterialStateProperty.all( + const Color(0xFF6888FD)), + backgroundColor: + MaterialStateProperty.all( + const Color(0xFFF4F4F4)), + // foregroundColor: MaterialStateProperty.all(Colors.red.shade200),//文字颜色 + shape: MaterialStateProperty.all( + RoundedRectangleBorder( + borderRadius: + BorderRadius.circular(22), //设置圆角 + )), + padding: MaterialStateProperty.all( + EdgeInsets.zero, + )), + onPressed: () { + clickFunction!(); + }, + child: Text( + title, + style: TextStyle( + fontSize: font, + color: const Color(0xFF666666)), + )), + ); + } +} diff --git a/lib/page/home_page/children/class_student/class_student_logic.dart b/lib/page/home_page/children/class_student/class_student_logic.dart index 345fff1..41822f8 100644 --- a/lib/page/home_page/children/class_student/class_student_logic.dart +++ b/lib/page/home_page/children/class_student/class_student_logic.dart @@ -16,6 +16,7 @@ class ClassStudentLogic extends GetxController with RequestToolMixin{ super.onInit(); state.title.value = Get.arguments['title']??''; state.classId = Get.arguments['classId']??''; + state.subject = Get.arguments['subject']??-1; state.page = Get.arguments['page']??''; EasyLoading.show(status: 'loading...'); refreshController = EasyRefreshController(); @@ -23,12 +24,22 @@ class ClassStudentLogic extends GetxController with RequestToolMixin{ } void getList() async{ - StudentItem res = await getClient().getStudentList(state.classId); - state.studentList.value = res.items; + List res = await getClient().getStudentList(state.classId,state.subject); + state.studentList.value = res; + state.studentList.sort((a, b) => a.priorityAnnotate?-1:1); EasyLoading.dismiss(); refreshController.finishRefresh(); } + void setJobReadLevel(studentId,priorityAnnotate) async{ + if(state.isClicking){ + state.isClicking = false; + await getClient().getAnnotateStudent(state.classId,studentId,priorityAnnotate,state.subject); + state.isClicking = true; + getList(); + } + } + @override void dispose() { super.dispose(); diff --git a/lib/page/home_page/children/class_student/class_student_state.dart b/lib/page/home_page/children/class_student/class_student_state.dart index 6b6db42..d786f5a 100644 --- a/lib/page/home_page/children/class_student/class_student_state.dart +++ b/lib/page/home_page/children/class_student/class_student_state.dart @@ -8,6 +8,8 @@ class ClassStudentState { late RxString title = ''.obs; late final String classId; - late RxList studentList = RxList(); + late final int subject; + late RxList studentList = RxList(); late String page = ''; + late bool isClicking = true; } diff --git a/lib/page/home_page/children/class_student/class_student_view.dart b/lib/page/home_page/children/class_student/class_student_view.dart index 1250e30..fc3f928 100644 --- a/lib/page/home_page/children/class_student/class_student_view.dart +++ b/lib/page/home_page/children/class_student/class_student_view.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:flutter_easyrefresh/easy_refresh.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; @@ -6,6 +7,7 @@ import 'package:school_asignment_app/common/job/student_item.dart'; import 'package:school_asignment_app/common/utils/utils.dart'; import 'package:school_asignment_app/page/global_widget/MyEmptyWidget.dart'; import 'package:school_asignment_app/page/global_widget/ReturnToHomepage.dart'; +import 'package:school_asignment_app/routes/app_pages.dart'; import 'class_student_logic.dart'; @@ -43,291 +45,302 @@ class _ClassStudentPageState extends State { ReturnToHomepage(), ], ), - body: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - height: 10.r, - ), - Expanded( - child: Padding( - padding: EdgeInsets.symmetric(vertical: 14.r, horizontal: 14.r), - child: EasyRefresh( - firstRefresh: true, - taskIndependence: true, - controller: logic.refreshController, - header: MaterialHeader(), - footer: TaurusFooter(), - onRefresh: () async { - logic.getList(); - }, - child: Obx((){ - return state.studentList.isNotEmpty - ? Utils.isPad() - ? GridView( - shrinkWrap: true, - gridDelegate: - SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 2, - mainAxisSpacing: 10.r, - crossAxisSpacing: 10.r, - childAspectRatio: 556 / 112, - ), - children: List.generate(state.studentList.length, (index) { - Items item = state.studentList[index]; - return InkWell( - onTap: (){ - // RouterManager.router.navigateTo(context, - // '${RouterManager.jobPersonalDetailPath}?studentId=${item.studentId}&studentName=${Uri.encodeComponent(item.studentName)}'); - }, - child: Container( - padding: EdgeInsets.symmetric(horizontal: 10.r), - decoration: BoxDecoration( - borderRadius: - BorderRadius.all(Radius.circular(10.r)), - color: Colors.white, - ), - child: Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Text( - item.name, - style: TextStyle( - fontSize: 12.sp, - color: const Color(0xFF6888FD)), - )), - - state.page == 'answerTrajectory'?Container( - height: 20.r, - width: 70.r, - decoration: BoxDecoration( - border: Border.all(width: 1.r,color: const Color(0xFFFFA41E)), - borderRadius: BorderRadius.all(Radius.circular(20.r)), - - ), - child: Center(child: Text('详情',style: TextStyle(fontSize: 10.r,color: Color(0xFFFFA41E))), - )):state.page == 'history'?Container( - height: 20.r, - width: 70.r, - decoration: BoxDecoration( - color: const Color(0xFF6888FD), - borderRadius: BorderRadius.all(Radius.circular(20.r)) - ), - child: Center(child: Text('历史作业',style: TextStyle(fontSize: 10.r,color: Colors.white),)), - ): - item.evaluationLevel == 1 - ? - InkWell( - onTap: () { - /* isClicking = true; - setJobReadLevel( - item.studentGroupDetailId, 0); - EasyLoading.show( - status: 'loading...');*/ - }, - child:Container( - height: 20.r, - width: 80.r, - decoration: BoxDecoration( - borderRadius: BorderRadius.all( - Radius.circular(4.r)), - color:const Color(0xFFB7FFE0), - ), - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: EdgeInsets.only(left: 3.r), - child: Image.asset('assets/images/youx_icon_active.png',width: 14.r,height: 14.r,), - ), - Padding( - padding: EdgeInsets.only(top: 2.r,left: 4.r), - child: Text( - '优先批阅', - style: TextStyle( - fontSize: 10.sp, - color: const Color(0xFF4CC793)), - ), - ), - ], - ), - ), - ) - :InkWell( - onTap: () { - /* isClicking = true; - setJobReadLevel( - item.studentGroupDetailId, 1); - EasyLoading.show( - status: 'loading...');*/ - }, - child: Container( - height: 20.r, - width: 80.r, - decoration: BoxDecoration( - borderRadius: BorderRadius.all( - Radius.circular(4.r)), - color: const Color(0xFFE1E1E1), - ), - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: EdgeInsets.only(left: 3.r), - child: Image.asset('assets/images/youx_icon_default.png',width: 14.r,height: 14.r,), - ), - Padding( - padding: EdgeInsets.only(top: 2.r,left: 4.r), - child: Text( - '优先批阅', - style: TextStyle( - fontSize: 10.sp, - color: const Color(0xFF8A9691)), - ), - ), - ], - ), - ), - ), - ], - ), - ), - ); - }), - ) - : ListView.builder( - itemBuilder: (context, index) { - Items item = state.studentList[index]; - return InkWell( - onTap: (){ - // RouterManager.router.navigateTo(context, - // '${RouterManager.jobPersonalDetailPath}?studentId=${item.studentId}&studentName=${Uri.encodeComponent(item.studentName)}'); - }, - child: Container( - padding: EdgeInsets.symmetric( - vertical: 20.r, horizontal: 15.r), - margin: EdgeInsets.only(bottom: 15.r), - decoration: BoxDecoration( - borderRadius: - BorderRadius.all(Radius.circular(10.r)), - color: Colors.white, - ), - child: Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Text( - item.name, - style: TextStyle( - fontSize: 12.sp, - color: Color(0xFF6888FD)), - )), - state.page == 'answerTrajectory'?Container( - height: 24.r, - width: 72.r, - decoration: BoxDecoration( - border: Border.all(width: 1.r,color: Color(0xFFFFA41E)), - borderRadius: BorderRadius.all(Radius.circular(20.r)), - - ), - child: Center(child: Text('详情',style: TextStyle(fontSize: 10.r,color: Color(0xFFFFA41E))), - )):state.page == 'history'?Container( - height: 24.r, - width: 82.r, - decoration: BoxDecoration( - color: Color(0xFF6888FD), - borderRadius: BorderRadius.all(Radius.circular(20.r)) - ), - child: Center(child: Text('历史作业',style: TextStyle(fontSize: 10.r,color: Colors.white),)), - ): - item.evaluationLevel == 1 - ? InkWell( - onTap: () { - /*isClicking = true; - setJobReadLevel( - item.studentGroupDetailId, 0); - EasyLoading.show( - status: 'loading...');*/ - }, - child: Container( - height: 24.r, - width: 82.r, - decoration: BoxDecoration( - borderRadius: BorderRadius.all( - Radius.circular(4.r)), - color:Color(0xFFB7FFE0), - ), - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: EdgeInsets.only(left: 3.r), - child: Image.asset('assets/images/youx_icon_active.png',width: 14.r,height: 14.r,), - ), - Padding( - padding: EdgeInsets.only(top: 2.r,left: 4.r), - child: Text( - '优先批阅', - style: TextStyle( - fontSize: 10.sp, - color: const Color(0xFF4CC793)), - ), - ), - ], - ), - ), - ) - : InkWell( - onTap: () { - /* setJobReadLevel( - item.studentGroupDetailId, 1); - EasyLoading.show( - status: 'loading...');*/ - }, - child: Container( - height: 24.r, - width: 82.r, - decoration: BoxDecoration( - borderRadius: BorderRadius.all( - Radius.circular(4.r)), - color: const Color(0xFFE1E1E1), - ), - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: EdgeInsets.only(left: 3.r), - child: Image.asset('assets/images/youx_icon_default.png',width: 14.r,height: 14.r,), - ), - Padding( - padding: EdgeInsets.only(top: 2.r,left: 4.r), - child: Text( - '优先批阅', - style: TextStyle( - fontSize: 10.sp, - color: const Color(0xFF8A9691)), - ), - ), - ], - ), - ), - ), - ], - ), - ), - ); - }, - itemCount: state.studentList.length, - ) - : const MyEmptyWidget(); - }), + body: Padding( + padding: EdgeInsets.symmetric(vertical: 14.r, horizontal: 14.r), + child: Obx(() { + return EasyRefresh( + firstRefresh: false, + taskIndependence: true, + controller: logic.refreshController, + header: MaterialHeader(), + footer: TaurusFooter(), + onRefresh: () async { + logic.getList(); + }, + child: state.studentList.isNotEmpty + ? Utils.isPad() + ? GridView( + shrinkWrap: true, + gridDelegate: + SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, + mainAxisSpacing: 10.r, + crossAxisSpacing: 10.r, + childAspectRatio: 556 / 112, ), - ), - ) - ], + children: List.generate(state.studentList.length, (index) { + StudentItem item = state.studentList[index]; + return InkWell( + onTap: () { + // RouterManager.router.navigateTo(context, + // '${RouterManager.jobPersonalDetailPath}?studentId=${item.studentId}&studentName=${Uri.encodeComponent(item.studentName)}'); + Get.toNamed(Routes.studentWorkDetailPage,arguments: {'studentName':item.name,'studentId':item.id}); + }, + child: Container( + padding: EdgeInsets.symmetric(horizontal: 10.r), + decoration: BoxDecoration( + borderRadius: + BorderRadius.all(Radius.circular(10.r)), + color: Colors.white, + ), + child: Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Text( + item.name, + style: TextStyle( + fontSize: 12.sp, + color: const Color(0xFF6888FD)), + )), + + state.page == 'answerTrajectory' ? Container( + height: 20.r, + width: 70.r, + decoration: BoxDecoration( + border: Border.all( + width: 1.r, color: const Color(0xFFFFA41E)), + borderRadius: BorderRadius.all( + Radius.circular(20.r)), + + ), + child: Center(child: Text('详情', style: TextStyle( + fontSize: 10.r, color: Color(0xFFFFA41E))), + )) : state.page == 'history' ? Container( + height: 20.r, + width: 70.r, + decoration: BoxDecoration( + color: const Color(0xFF6888FD), + borderRadius: BorderRadius.all( + Radius.circular(20.r)) + ), + child: Center(child: Text('历史作业', style: TextStyle( + fontSize: 10.r, color: Colors.white),)), + ) : + item.priorityAnnotate + ? + InkWell( + onTap: () { + logic.setJobReadLevel( + item.id, false); + EasyLoading.show( + status: 'loading...'); + }, + child: Container( + height: 20.r, + width: 80.r, + decoration: BoxDecoration( + borderRadius: BorderRadius.all( + Radius.circular(4.r)), + color: const Color(0xFFB7FFE0), + ), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.only(left: 3.r), + child: Image.asset( + 'assets/images/youx_icon_active.png', + width: 14.r, height: 14.r,), + ), + Padding( + padding: EdgeInsets.only( + top: 2.r, left: 4.r), + child: Text( + '优先批阅', + style: TextStyle( + fontSize: 10.sp, + color: const Color(0xFF4CC793)), + ), + ), + ], + ), + ), + ) + : InkWell( + onTap: () { + logic.setJobReadLevel( + item.id, true); + EasyLoading.show( + status: 'loading...'); + }, + child: Container( + height: 20.r, + width: 80.r, + decoration: BoxDecoration( + borderRadius: BorderRadius.all( + Radius.circular(4.r)), + color: const Color(0xFFE1E1E1), + ), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.only(left: 3.r), + child: Image.asset( + 'assets/images/youx_icon_default.png', + width: 14.r, height: 14.r,), + ), + Padding( + padding: EdgeInsets.only( + top: 2.r, left: 4.r), + child: Text( + '优先批阅', + style: TextStyle( + fontSize: 10.sp, + color: const Color(0xFF8A9691)), + ), + ), + ], + ), + ), + ), + ], + ), + ), + ); + }), + ) + : ListView.builder( + itemBuilder: (context, index) { + StudentItem item = state.studentList[index]; + return InkWell( + onTap: () { + // RouterManager.router.navigateTo(context, + // '${RouterManager.jobPersonalDetailPath}?studentId=${item.studentId}&studentName=${Uri.encodeComponent(item.studentName)}'); + Get.toNamed(Routes.studentWorkDetailPage,arguments: {'studentName':item.name,'studentId':item.id}); + }, + child: Container( + padding: EdgeInsets.symmetric( + vertical: 20.r, horizontal: 15.r), + margin: EdgeInsets.only(bottom: 15.r), + decoration: BoxDecoration( + borderRadius: + BorderRadius.all(Radius.circular(10.r)), + color: Colors.white, + ), + child: Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Text( + item.name, + style: TextStyle( + fontSize: 12.sp, + color: Color(0xFF6888FD)), + )), + state.page == 'answerTrajectory' ? Container( + height: 24.r, + width: 72.r, + decoration: BoxDecoration( + border: Border.all( + width: 1.r, color: Color(0xFFFFA41E)), + borderRadius: BorderRadius.all( + Radius.circular(20.r)), + + ), + child: Center(child: Text('详情', style: TextStyle( + fontSize: 10.r, color: Color(0xFFFFA41E))), + )) : state.page == 'history' ? Container( + height: 24.r, + width: 82.r, + decoration: BoxDecoration( + color: Color(0xFF6888FD), + borderRadius: BorderRadius.all( + Radius.circular(20.r)) + ), + child: Center(child: Text('历史作业', style: TextStyle( + fontSize: 10.r, color: Colors.white),)), + ) : + item.priorityAnnotate + ? InkWell( + onTap: () { + logic.setJobReadLevel( + item.id, false); + EasyLoading.show( + status: 'loading...'); + }, + child: Container( + height: 24.r, + width: 82.r, + decoration: BoxDecoration( + borderRadius: BorderRadius.all( + Radius.circular(4.r)), + color: Color(0xFFB7FFE0), + ), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.only(left: 3.r), + child: Image.asset( + 'assets/images/youx_icon_active.png', + width: 14.r, height: 14.r,), + ), + Padding( + padding: EdgeInsets.only( + top: 2.r, left: 4.r), + child: Text( + '优先批阅', + style: TextStyle( + fontSize: 10.sp, + color: const Color(0xFF4CC793)), + ), + ), + ], + ), + ), + ) + : InkWell( + onTap: () { + logic.setJobReadLevel( + item.id, true); + EasyLoading.show( + status: 'loading...'); + }, + child: Container( + height: 24.r, + width: 82.r, + decoration: BoxDecoration( + borderRadius: BorderRadius.all( + Radius.circular(4.r)), + color: const Color(0xFFE1E1E1), + ), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.only(left: 3.r), + child: Image.asset( + 'assets/images/youx_icon_default.png', + width: 14.r, height: 14.r,), + ), + Padding( + padding: EdgeInsets.only( + top: 2.r, left: 4.r), + child: Text( + '优先批阅', + style: TextStyle( + fontSize: 10.sp, + color: const Color(0xFF8A9691)), + ), + ), + ], + ), + ), + ), + ], + ), + ), + ); + }, + itemCount: state.studentList.length, + ) + : const MyEmptyWidget(), + ); + }), ), ); } diff --git a/lib/page/home_page/children/job_report/job_report_logic.dart b/lib/page/home_page/children/job_report/job_report_logic.dart index 4548d4e..fe483ab 100644 --- a/lib/page/home_page/children/job_report/job_report_logic.dart +++ b/lib/page/home_page/children/job_report/job_report_logic.dart @@ -1,7 +1,54 @@ +import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:get/get.dart'; +import 'package:school_asignment_app/common/job/annotated_class.dart'; +import 'package:school_asignment_app/common/job/homework_details.dart'; +import 'package:school_asignment_app/common/mixins/request_tool_mixin.dart'; +import 'package:school_asignment_app/common/utils/utils.dart'; import 'job_report_state.dart'; -class JobReportLogic extends GetxController { +class JobReportLogic extends GetxController with RequestToolMixin { final JobReportState state = JobReportState(); + + @override + void onInit(){ + super.onInit(); + state.title.value = Get.arguments['title']??''; + state.homeworkId.value = Get.arguments['homeworkId']??''; + state.classId.value = Get.arguments['classId']??''; + state.className.value = Get.arguments['className']??''; + state.grade = Get.arguments['grade']??''; + EasyLoading.show(status: 'loading...'); + getClass(); + } + void getClass() async{ + List data = await getClient(). getAnnotatedClassList(state.homeworkId.value); + state.involveClasses.value = data; + + state.involveClasses.value = [state.classData.value, ...(data ?? [])]; + for (var element in state.involveClasses) { + if (element.className == state.className.value && element.grade == state.grade ) { + state.classData.value = element; + } + } + getWorkData(); + } + void getWorkData() async{ + HomeworkDetails data = await getClient(). getHomeworkDetails(state.homeworkId.value,state.classData.value.classId != '-1' ? state.classData.value.classId : ''); + state.dataCount = Utils.getHomeworkData(data); + state.homeData = data; + state.kgReport.value = data.questions.where((w)=>w.questionType == 1).toList(); + state.zgReport.value = data.questions.where((w)=>w.questionType == 2).toList(); + state.studentList.value = [...data.students]; + state.knowsList.value = data.knows; + state.hasData.value = true; + EasyLoading.dismiss(); + + state.studentList.sort((a, b) { + int num1 = a.kgtOkCount!+a.zgtOkCount!; + int num2 = b.kgtOkCount!+b.zgtOkCount!; + return num2.compareTo(num1); + }); + + } } diff --git a/lib/page/home_page/children/job_report/job_report_state.dart b/lib/page/home_page/children/job_report/job_report_state.dart index 2e189ab..8f35fca 100644 --- a/lib/page/home_page/children/job_report/job_report_state.dart +++ b/lib/page/home_page/children/job_report/job_report_state.dart @@ -1,5 +1,26 @@ +import 'package:get/get.dart'; +import 'package:school_asignment_app/common/job/annotated_class.dart'; +import 'package:school_asignment_app/common/job/homework_details.dart'; +import 'package:school_asignment_app/page/home_page/children/quick_data_check/quick_data_check_state.dart'; + class JobReportState { JobReportState() { ///Initialize variables } + + late RxString title = ''.obs; + late RxString homeworkId = ''.obs; + late RxString classId = ''.obs; + late RxString className = ''.obs; + late int grade; + late CountData dataCount = CountData(); + late RxBool hasData = false.obs; + late RxList kgReport = RxList(); + late RxList zgReport = RxList(); + late RxList studentList = RxList(); + late RxList knowsList = RxList(); + late HomeworkDetails homeData; + late RxList involveClasses = RxList(); + late AnnotatedClass defaultClass = AnnotatedClass('',-1,'-1','','',-1,-1,-1,-1,-1,[],[],-1,-1,-1,-1,-1); + late Rx classData = defaultClass.obs; } diff --git a/lib/page/home_page/children/job_report/job_report_view.dart b/lib/page/home_page/children/job_report/job_report_view.dart index 7fdabe2..900192b 100644 --- a/lib/page/home_page/children/job_report/job_report_view.dart +++ b/lib/page/home_page/children/job_report/job_report_view.dart @@ -1,5 +1,14 @@ import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; +import 'package:school_asignment_app/common/job/annotated_class.dart'; +import 'package:school_asignment_app/page/global_widget/MyEmptyWidget.dart'; +import 'package:school_asignment_app/page/global_widget/ReturnToHomepage.dart'; +import 'package:school_asignment_app/page/home_page/children/job_report/widget/dropdown_selection.dart'; +import 'package:school_asignment_app/page/global_widget/my_text.dart'; +import 'package:school_asignment_app/page/home_page/children/job_report/widget/knowledge_point.dart'; +import 'package:school_asignment_app/page/home_page/children/job_report/widget/personnel_data_overview.dart'; +import 'package:school_asignment_app/page/home_page/children/quick_data_check/widget/kgt_zgt_table.dart'; import 'job_report_logic.dart'; @@ -12,11 +21,106 @@ class JobReportPage extends StatefulWidget { class _JobReportPageState extends State { final logic = Get.find(); - final state = Get.find().state; + final state = Get + .find() + .state; @override Widget build(BuildContext context) { - return Container(); + return Scaffold( + backgroundColor: Color.fromRGBO(245, 245, 245, 1), + appBar: AppBar( + backgroundColor: Colors.white, + centerTitle: true, + title: Center( + child: Obx(() { + return quickText( + '${state.title.value}作业报告', + size: 14.sp, + color: const Color.fromRGBO(51, 51, 51, 1), + ); + })), + leading: IconButton( + icon: const Icon(Icons.arrow_back_ios, color: Colors.black), + onPressed: () => Navigator.of(context).pop(), + ), + actions: const [ + ReturnToHomepage(), + ], + ), + body: Obx(() { + if (state.hasData.value) { + return SingleChildScrollView( + child: Column( + children: [ + // 下拉框 + Container( + padding: EdgeInsets.symmetric(vertical: 10.h, horizontal: 10.w), + decoration: const BoxDecoration( + color: Colors.white, + ), + child: Row( + children: [ + Obx(() { + return DropdownSelection(involveClasses: state + .involveClasses.value, + classData: state.classData.value, + call: (AnnotatedClass item) { + state.classData.value = item; + if (item.grade == -1) state.classData.value = state.defaultClass; + logic.getWorkData(); + }); + }), + // Expanded(child: Text('')), + ], + ), + ), + //完成率、正确率 + /* TopCount( + data, classData == null ? '' : classData!.className, widget.id),*/ + //客观题、主观题 + KgtZgtTable(studentCount: state.dataCount.studentCount!, + homeworkId: state.homeworkId.value, + kgReport: state.kgReport, + zgReport: state.zgReport, + kgtOkRate: state.dataCount.kgtOkRate! + .toStringAsFixed(0), + zgtOkRate: state.dataCount.zgtOkRate! + .toStringAsFixed(0)), + // 掌握知识点的情况 + Container( + margin: EdgeInsets.symmetric(horizontal: 10.r), + child: KnowledgePoint( + knowsList:state.knowsList,data:state.homeData,className: state.className.value,)), + // 掌握知识点的情况 + /* Container( + margin: EdgeInsets.symmetric(horizontal: 10.r), + child: $OverallPerformance(data.studentCount, data.overallTitles)), + // 单位时间答题情况 + Container( + margin: EdgeInsets.symmetric(horizontal: 10.r), + child: $UnitTimeAnsweringSituation(widget.id, data.questionAnswerInfos)),*/ + // 人员数据概况 + Container( + margin: EdgeInsets.symmetric(horizontal: 10.r), + child: PersonnelDataOverview(studentList:state.studentList.value)), + + SizedBox(height: 30.r,), + ], + ), + ); + } else { + return Padding( + padding: EdgeInsets.only( + top: MediaQuery + .of(context) + .size + .height / 2 - 200.r), + child: const MyEmptyWidget() + ); + } + }), + ); } @override diff --git a/lib/page/home_page/children/job_report/widget/dropdown_selection.dart b/lib/page/home_page/children/job_report/widget/dropdown_selection.dart new file mode 100644 index 0000000..094fd1a --- /dev/null +++ b/lib/page/home_page/children/job_report/widget/dropdown_selection.dart @@ -0,0 +1,51 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:school_asignment_app/common/job/annotated_class.dart'; +import 'package:school_asignment_app/common/utils/enum_untils.dart'; +import 'package:school_asignment_app/page/global_widget/my_text.dart'; + +class DropdownSelection extends StatefulWidget { + final List? involveClasses; + final AnnotatedClass? classData; + final Function(AnnotatedClass) call; + const DropdownSelection({Key? key,required this.involveClasses,required this.classData,required this.call}) : super(key: key); + + @override + State createState() => _DropdownSelectionState(); +} + +class _DropdownSelectionState extends State { + @override + Widget build(BuildContext context) { + return Container( + // width: 200.r, + padding: EdgeInsets.symmetric(horizontal: 10.r), + decoration: const BoxDecoration( + color: Color(0xFFF5F5F5), + borderRadius: BorderRadius.vertical( + top: Radius.elliptical(10, 10), + bottom: Radius.elliptical(10, 10), + )), + child: DropdownButton( + value: widget.classData?.classId ?? '-1', + style: TextStyle(color: Color.fromRGBO(89, 89, 89, 1), fontSize: 12.sp), + underline: Container(), + // isExpanded:true, + items: widget.involveClasses?.map((e) { + return DropdownMenuItem( + value: e.classId!, + child: quickText( + e.classId == '-1' + ? '全部' + : + ' ${EnumUtils.formatGrade(e.grade)}${e.className}', size: 12.sp, color: Colors.black), + ); + }).toList(), + onChanged: (value) { + if (value == null) return; + widget.call(widget.involveClasses!.firstWhere((element) => element.classId == value)); + }, + ), + ); + } +} diff --git a/lib/page/home_page/children/job_report/widget/knowledge_point.dart b/lib/page/home_page/children/job_report/widget/knowledge_point.dart new file mode 100644 index 0000000..0ae6e0e --- /dev/null +++ b/lib/page/home_page/children/job_report/widget/knowledge_point.dart @@ -0,0 +1,291 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:get/get.dart'; +import 'package:percent_indicator/linear_percent_indicator.dart'; +import 'package:school_asignment_app/common/job/homework_details.dart'; +import 'package:school_asignment_app/common/utils/utils.dart'; +import 'package:school_asignment_app/page/global_widget/MyEmptyWidget.dart'; +import 'package:school_asignment_app/page/global_widget/my_text.dart'; + +class KnowledgePoint extends StatefulWidget { + final RxList knowsList; + final HomeworkDetails data; + final String className; + KnowledgePoint({Key? key,required this.knowsList,required this.data,required this.className}) : super(key: key); + + @override + State createState() => _KnowledgePointState(); +} + +class _KnowledgePointState extends State { + + void showPeopleListDialog( + {required BuildContext context, + required String title, + required List arr,}) { + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + // insetPadding: EdgeInsets.symmetric(vertical: 20.r,horizontal: 20.r), + backgroundColor:const Color(0xFFFFFFFF), + contentPadding: EdgeInsets.all(20.r), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.circular(15.r))), + content: SizedBox( + width: MediaQuery.of(context).size.width * 0.7, + height: MediaQuery.of(context).size.height * 0.7, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Center( + child: Text( + title, + style: TextStyle( + fontSize: 15.sp, + color: const Color(0xFF3C3C3C), + fontWeight: FontWeight.w500), + ), + ), + SizedBox( + height: 10.r, + ), + Row( + children: [ + Expanded( + flex: 2, + child: Center( + child: Text( + '姓名', + style: TextStyle( + fontSize: 12.sp, + color: const Color(0xFF6A6A6A)), + ))), + SizedBox(width: 10.r,), + Expanded( + flex: 1, + child: Center( + child: Text( + '班级', + style: TextStyle( + fontSize: 12.sp, + color: const Color(0xFF6A6A6A)), + ))), + SizedBox(width: 10.r,), + Expanded( + flex: 2, + child: Center( + child: Text( + '掌握度', + style: TextStyle( + fontSize: 12.sp, + color: const Color(0xFF6A6A6A)), + ))), + SizedBox(width: 10.r,), + Expanded( + flex: 3, + child: Center( + child: Text( + '掌握情况', + style: TextStyle( + fontSize: 12.sp, + color: const Color(0xFF6A6A6A)), + ))), + ], + ), + SizedBox( + height: 5.r, + ), + + arr.isNotEmpty? Expanded( + child: ListView.builder( + shrinkWrap: true, + itemBuilder: (context, index) { + var item = arr[index]; + return Container( + padding: EdgeInsets.symmetric(vertical: 5.r), + color: const Color(0xFFF0F0F0), + margin:EdgeInsets.only(bottom: 2.r), + child: Row( + children: [ + Expanded( + flex: 2, + child: InkWell( + onTap: () { + /* goQuickCheckPersonalPath( + item['noAnswerStudents'].id);*/ + }, + child: Center( + child: Text( + item.studentName!, + style: TextStyle( + fontSize: 12.sp, + color: const Color(0xFF323232)), + )))), + SizedBox(width: 10.r,), + Expanded( + flex: 1, + child: Center( + child: Text( + widget.className, + style: TextStyle( + fontSize: 12.sp, + color: Color(0xFF323232)), + ))), + SizedBox(width: 10.r,), + Expanded( + flex: 2, + child: Center( + child: Text( + '${item.okRate!.toStringAsFixed(0)}%', + style: TextStyle( + fontSize: 12.sp, + color: Color(0xFF323232)), + ))), + SizedBox(width: 10.r,), + Expanded( + flex: 3, + child: Padding( + padding: EdgeInsets.symmetric(vertical: 2.r, horizontal: 5.r), + child: SingleChildScrollView( + child: Wrap( + direction: Axis.horizontal, + alignment: WrapAlignment.start, + spacing: 5, + runSpacing: 3, + children: List.generate(item.queDtls!.length, (index) { + Dtls kgInfo = item.queDtls![index]; + return Container( + width: 14.r, + height: 14.r, + decoration: BoxDecoration( + color: kgInfo.state == 0 + ? const Color(0xFFD3D3D3) + : kgInfo.state == 1?Colors.white:kgInfo.state == 2 + ? const Color(0xFFFF7474) + : const Color(0xFF4CC793), + borderRadius: BorderRadius.all(Radius.circular(7.r))), + child: Center( + child: Text( + kgInfo.questionNo.toString(), + style: TextStyle( + fontSize: 8.sp, + color: kgInfo.state == 1 + ? Color(0xFF525252) + : Colors.white), + )), + ); + })), + ), + ),), + ], + ), + ); + }, + itemCount: arr.length, + ), + ): const MyEmptyWidget() + ], + ), + ), + ); + }); + } + + @override + Widget build(BuildContext context) { + return Container( + margin: EdgeInsets.only(top: 10.h), + padding: EdgeInsets.symmetric(vertical: 16.h, horizontal: 12.w), + constraints: BoxConstraints(maxHeight: 320.h), + decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(10.r)), + child: Column( + children: [ + Container( + margin: EdgeInsets.only(bottom: 24.h), + child: quickText('知识点掌握情况', color: const Color.fromRGBO(92, 92, 92, 1), size: 14.sp, fontWeight: FontWeight.bold), + ), + Expanded( + child: ListView(children: widget.knowsList.value.map((item) { + return Container( + margin: EdgeInsets.only(bottom: 15.h, left: 15.r, right: 15.r), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + children: [ + Expanded( + flex: 10, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + quickText(item.knowledgeName, + size: 12.sp, color: const Color.fromRGBO(152, 152, 152, 1)), + quickText('${item.okRate!.toStringAsFixed(0)}%', + size: 12.sp, color: const Color.fromRGBO(64, 64, 64, 1)), + ], + ), + ), + SizedBox(width: 10.w), + const Expanded(flex: 1, child: SizedBox()), + ], + ), + SizedBox(height: 3.h), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + flex: 10, + child: LinearPercentIndicator( + padding: EdgeInsets.zero, + animation: true, + lineHeight: 10.h, + animationDuration: 2500, + percent: item.okRate! / 100, + progressColor: Theme.of(context).primaryColor, + backgroundColor: const Color.fromRGBO(219, 224, 243, 1), + barRadius: Radius.circular(10.r), + )), + SizedBox(width: 10.w), + InkWell( + onTap: () { + List ques = widget.data.questions.where((w) => w.knows.indexWhere((k) => k.knowledgeId == item.knowledgeId) > -1).toList(); + List array2 = [...widget.data.students]; + for(var stu in array2){ + stu.queDtls = widget.data.dtls.where((w) => w.studentId == stu.studentId && ques.indexWhere((q) => w.templateId == q.templateId && w.questionNo == q.questionNo) > -1).toList(); + int okCount = stu.queDtls!.where((w) => w.state == 3).length; + int ttlCount = stu.queDtls!.length; + stu.okRate = Utils.calcRate(okCount, ttlCount); + stu.queDtls!.sort((a, b) { + int num1 = a.questionNo; + int num2 = b.questionNo; + return num1.compareTo(num2); + }); + } + + showPeopleListDialog( + context: context, + title: item.knowledgeName, + arr: array2,); + }, + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + quickText('查看', size: 12.sp, color: const Color.fromRGBO(239, 135, 20, 1)), + Icon(Icons.arrow_forward_ios, size: 11.sp, color: const Color.fromRGBO(239, 135, 20, 1)), + ], + ), + ), + ], + ) + ], + ), + ); + }).toList()), + ), + ], + )); + } +} diff --git a/lib/page/home_page/children/job_report/widget/personnel_data_overview.dart b/lib/page/home_page/children/job_report/widget/personnel_data_overview.dart new file mode 100644 index 0000000..b3f6577 --- /dev/null +++ b/lib/page/home_page/children/job_report/widget/personnel_data_overview.dart @@ -0,0 +1,143 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:school_asignment_app/common/job/homework_details.dart'; +import 'package:school_asignment_app/page/global_widget/my_text.dart'; + +class PersonnelDataOverview extends StatefulWidget { + final List studentList; + const PersonnelDataOverview({Key? key,required this.studentList}) : super(key: key); + + @override + State createState() => _PersonnelDataOverviewState(); +} + +class _PersonnelDataOverviewState extends State { + + List names = []; + List useTimes = []; + List correctRates = []; + List noAnswerCounts = []; + List rankings = []; + Map> mapData = {}; + + @override + void initState(){ + super.initState(); + + + for (var i = 0;i 0) timeerStr = timeUnits.hours.toString() + ':'; + if (timeUnits.minutes > 0) timeerStr += timeUnits.minutes.toString() + ':'; + timeerStr += timeUnits.seconds.toString(); + + names.add(student.studentName); + useTimes.add(timeerStr); + correctRates.add(student.okRate!.toStringAsFixed(0) + '%'); + noAnswerCounts.add(student.noAnswerCount.toString()); + rankings.add('${i + 1}名'); + } + mapData = { + '姓名': names, + '答题时长': useTimes, + '正确率': correctRates, + '未答题数': noAnswerCounts, + '班级排名': rankings, + }; + + } + + @override + Widget build(BuildContext context) { + return Container( + width: double.infinity, + // height: isPad() ? 290.h : 264.h, + margin: EdgeInsets.only(top: 20.h), + padding: EdgeInsets.symmetric(vertical: 16.h, horizontal: 12.w), + decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(10.r)), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + margin: EdgeInsets.only(bottom: 20.h), + child: quickText('人员数据概况', color: Color.fromRGBO(92, 92, 92, 1), size: 14.sp, fontWeight: FontWeight.bold), + ), + Scrollbar( + thickness: 8.w, + thumbVisibility: true, + trackVisibility: true, + radius: Radius.circular(10.r), + controller: ScrollController(),//滑动条使用的控制器 + child: SingleChildScrollView( + scrollDirection: Axis.horizontal, + primary: true, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ...mapData.entries.map((entrie) { + bool isTransparentChinese = ['答题时长', '正确率', '未答题数'].contains(entrie.key); // 透明中文 + + return Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + width: 94.r, + alignment: Alignment.center, + color: const Color.fromRGBO(230, 230, 230, 1), + margin: EdgeInsets.only(bottom: 1.h, right: 1.w), + padding: EdgeInsets.symmetric(vertical: 10.h, horizontal: 8.w), + child: quickText(entrie.key, color: Color.fromRGBO(24, 35, 77, 1), size: 12.sp, maxLines: 2), + ), + ...entrie.value.map((e) { + bool isTransparentChineseNew = isTransparentChinese && (e?.length ?? 0) == 0; + return Container( + width: 100.r, + alignment: Alignment.center, + margin: EdgeInsets.only(bottom: 1.h, right: 1.w), + padding: EdgeInsets.symmetric(vertical: 10.h, horizontal: 8.w), + color: Color.fromRGBO(245, 245, 245, 1), + child: isTransparentChineseNew + ? quickText('透明', color: Colors.transparent, size: 12.sp) + :RegExp(r'^\d+$').hasMatch(e) || e.contains('%') + ? Row( + mainAxisSize: MainAxisSize.min, + children: [ + quickText(e, color: Color.fromRGBO(82, 82, 82, 1), size: 12.sp, maxLines: 2), + quickText('透', color: Colors.transparent, size: 12.sp), + ], + ) + : quickText(e, color: Color.fromRGBO(82, 82, 82, 1), size: 12.sp, maxLines: 2), + ); + }).toList(), + ], + ); + }).toList(), + ], + ), + ), + ), + ], + ), + ); + } +} +// 定义一个类来保存转换后的时间单位 +class TimeUnits { + int hours; + int minutes; + int seconds; + + TimeUnits(this.hours, this.minutes, this.seconds); +} +// 毫秒转小时、分钟、秒的函数 +TimeUnits convertMilliseconds(int totalSeconds) { + int hours = totalSeconds ~/ 3600; // 整除得到小时数 + int remainingSeconds = totalSeconds % 3600; // 求余得到剩余的秒数 + int minutes = remainingSeconds ~/ 60; // 整除得到分钟数 + int seconds = remainingSeconds % 60; // 求余得到秒数 + + return TimeUnits(hours, minutes, seconds); + +} \ No newline at end of file diff --git a/lib/page/home_page/children/quick_data_check/quick_data_check_logic.dart b/lib/page/home_page/children/quick_data_check/quick_data_check_logic.dart index 3456847..e87d7bd 100644 --- a/lib/page/home_page/children/quick_data_check/quick_data_check_logic.dart +++ b/lib/page/home_page/children/quick_data_check/quick_data_check_logic.dart @@ -13,7 +13,7 @@ class QuickDataCheckLogic extends GetxController with RequestToolMixin{ void onInit(){ super.onInit(); state.homeworkId.value = Get.arguments['homeworkId']??''; - state.classId.value = Get.arguments['classId']??''; + state.classId.value = Get.arguments['classId']??''; state.className.value = Get.arguments['className']??''; state.grade = Get.arguments['grade']; EasyLoading.show(status: 'loading...'); @@ -22,8 +22,8 @@ class QuickDataCheckLogic extends GetxController with RequestToolMixin{ void getWorkData() async{ HomeworkDetails data = await getClient(). getHomeworkDetails(state.homeworkId.value,state.classId.value); - state.homeData = data; state.dataCount = Utils.getHomeworkData(data); + state.homeData = data; state.kgReport.value = data.questions.where((w)=>w.questionType == 1).toList(); state.zgReport.value = data.questions.where((w)=>w.questionType == 2).toList(); state.studentList.value = data.students; diff --git a/lib/page/home_page/children/quick_data_check/quick_data_check_state.dart b/lib/page/home_page/children/quick_data_check/quick_data_check_state.dart index 21ee678..e99610a 100644 --- a/lib/page/home_page/children/quick_data_check/quick_data_check_state.dart +++ b/lib/page/home_page/children/quick_data_check/quick_data_check_state.dart @@ -15,7 +15,7 @@ class QuickDataCheckState { late RxList kgReport = RxList(); late RxList zgReport = RxList(); late RxList studentList = RxList(); - late final HomeworkDetails homeData; + late HomeworkDetails homeData; } class CountData extends Object { diff --git a/lib/page/home_page/children/quick_data_check/widget/kgt_zgt_table.dart b/lib/page/home_page/children/quick_data_check/widget/kgt_zgt_table.dart index 22771d7..3694375 100644 --- a/lib/page/home_page/children/quick_data_check/widget/kgt_zgt_table.dart +++ b/lib/page/home_page/children/quick_data_check/widget/kgt_zgt_table.dart @@ -3,6 +3,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:school_asignment_app/common/job/homework_details.dart'; import 'package:school_asignment_app/common/utils/utils.dart'; +import 'package:school_asignment_app/page/global_widget/MyEmptyWidget.dart'; import 'package:school_asignment_app/page/home_page/children/quick_data_check/widget/report_table.dart'; class KgtZgtTable extends StatefulWidget { @@ -31,8 +32,6 @@ class _KgtZgtTableState extends State { @override void initState() { super.initState(); - - } @override @@ -88,7 +87,9 @@ class _KgtZgtTableState extends State { jobId: widget.homeworkId, studentCount: widget.studentCount, ), - ) + ), + if(widget.kgReport.isEmpty) + MyEmptyWidget(imgWidth:100.r,imgHeight: 100.r,font:8.sp), ], ), ), @@ -142,7 +143,9 @@ class _KgtZgtTableState extends State { jobId: widget.homeworkId, studentCount: widget.studentCount, ), - ) + ), + if(widget.zgReport.isEmpty) + MyEmptyWidget(imgWidth:100.r,imgHeight: 100.r,font:8.sp), ], ), ), diff --git a/lib/page/home_page/children/quick_data_check/widget/quick_data_check_bottom.dart b/lib/page/home_page/children/quick_data_check/widget/quick_data_check_bottom.dart index d6bc129..25ecdd5 100644 --- a/lib/page/home_page/children/quick_data_check/widget/quick_data_check_bottom.dart +++ b/lib/page/home_page/children/quick_data_check/widget/quick_data_check_bottom.dart @@ -24,6 +24,7 @@ class _QuickDataCheckBottomState extends State { RxBool sortType = true.obs; RxBool sortLevel = false.obs; + @override void initState() { super.initState(); showList.value = widget.jobData!; diff --git a/lib/page/home_page/children/quick_data_check/widget/quick_student_data_table.dart b/lib/page/home_page/children/quick_data_check/widget/quick_student_data_table.dart index f364ecd..c3da0ea 100644 --- a/lib/page/home_page/children/quick_data_check/widget/quick_student_data_table.dart +++ b/lib/page/home_page/children/quick_data_check/widget/quick_student_data_table.dart @@ -1,7 +1,9 @@ import 'package:data_table_2/data_table_2.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:get/get.dart'; import 'package:school_asignment_app/common/job/homework_details.dart'; +import 'package:school_asignment_app/routes/app_pages.dart'; class QuickStudentDataTable extends StatefulWidget { final List headList; @@ -54,6 +56,7 @@ class _QuickStudentDataTableState extends State { '?jobId=${widget.jobId}&studentId=${item.studentId}', transition: getTransition(), );*/ + Get.toNamed(Routes.studentPersonalPage,arguments: {'studentId':item.studentId,'homeworkId':widget.jobId}); }, child: Center( child: Padding( diff --git a/lib/page/home_page/children/quick_data_check/widget/report_table.dart b/lib/page/home_page/children/quick_data_check/widget/report_table.dart index 56ab672..000ad22 100644 --- a/lib/page/home_page/children/quick_data_check/widget/report_table.dart +++ b/lib/page/home_page/children/quick_data_check/widget/report_table.dart @@ -248,9 +248,6 @@ class _ReportTableState extends State { List noAnswerStudents, List answerNgStudents, List answerOkStudents) { List list = []; // Questions student = Questions('','',-1,-1,'',-1,'','',[],-1,-1,[] as double?); - print('noAnswerStudents.length=${noAnswerStudents.length}'); - print('answerNgStudents.length=${answerNgStudents.length}'); - print('answerOkStudents.length=${answerOkStudents.length}'); if (noAnswerStudents.length > answerNgStudents.length && noAnswerStudents.length > answerOkStudents.length) { for (int i = 0; i < noAnswerStudents.length; i++) { diff --git a/lib/page/home_page/children/student_history_work/student_history_work_logic.dart b/lib/page/home_page/children/student_history_work/student_history_work_logic.dart index 2baf451..d218e59 100644 --- a/lib/page/home_page/children/student_history_work/student_history_work_logic.dart +++ b/lib/page/home_page/children/student_history_work/student_history_work_logic.dart @@ -28,8 +28,8 @@ class StudentHistoryWorkLogic extends GetxController with RequestToolMixin { refreshController.finishRefresh(); } - void goNextPage(String id,String title) { - Get.toNamed(Routes.classStudentPage,arguments: {'title':title,'classId':id,'page':nextPage}); + void goNextPage(String id,String title,int subject) { + Get.toNamed(Routes.classStudentPage,arguments: {'title':title,'classId':id,'page':nextPage,'subject':subject}); } @override diff --git a/lib/page/home_page/children/student_personal/student_personal_binding.dart b/lib/page/home_page/children/student_personal/student_personal_binding.dart new file mode 100644 index 0000000..4e7c6fc --- /dev/null +++ b/lib/page/home_page/children/student_personal/student_personal_binding.dart @@ -0,0 +1,10 @@ +import 'package:get/get.dart'; + +import 'student_personal_logic.dart'; + +class StudentPersonalBinding extends Bindings { + @override + void dependencies() { + Get.lazyPut(() => StudentPersonalLogic()); + } +} diff --git a/lib/page/home_page/children/student_personal/student_personal_logic.dart b/lib/page/home_page/children/student_personal/student_personal_logic.dart new file mode 100644 index 0000000..ad5d317 --- /dev/null +++ b/lib/page/home_page/children/student_personal/student_personal_logic.dart @@ -0,0 +1,23 @@ +import 'package:get/get.dart'; +import 'package:school_asignment_app/common/job/student_personal_info.dart'; +import 'package:school_asignment_app/common/mixins/request_tool_mixin.dart'; + +import 'student_personal_state.dart'; + +class StudentPersonalLogic extends GetxController with RequestToolMixin{ + final StudentPersonalState state = StudentPersonalState(); + + @override + void onInit(){ + super.onInit(); + state.studentId = Get.arguments['studentId']; + state.homeworkId = Get.arguments['homeworkId']; + getInfo(); + } + + void getInfo() async{ + StudentPersonalInfo data = await getClient().getStudentHomework(state.homeworkId,state.studentId); + state.studentInfo.value = data; + + } +} diff --git a/lib/page/home_page/children/student_personal/student_personal_state.dart b/lib/page/home_page/children/student_personal/student_personal_state.dart new file mode 100644 index 0000000..89b4b56 --- /dev/null +++ b/lib/page/home_page/children/student_personal/student_personal_state.dart @@ -0,0 +1,13 @@ +import 'package:get/get.dart'; +import 'package:school_asignment_app/common/job/homework_details.dart'; +import 'package:school_asignment_app/common/job/student_personal_info.dart'; + +class StudentPersonalState { + StudentPersonalState() { + ///Initialize variables + } + late Rx studentInfo = Rx(StudentPersonalInfo(0,'',0,0,[],0,[])); + late int studentId; + late String homeworkId; + +} diff --git a/lib/page/home_page/children/student_personal/student_personal_view.dart b/lib/page/home_page/children/student_personal/student_personal_view.dart new file mode 100644 index 0000000..19b4ae9 --- /dev/null +++ b/lib/page/home_page/children/student_personal/student_personal_view.dart @@ -0,0 +1,232 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:get/get.dart'; +import 'package:school_asignment_app/common/utils/utils.dart'; +import 'package:school_asignment_app/page/global_widget/ReturnToHomepage.dart'; +import 'package:school_asignment_app/page/home_page/children/student_personal/widget/student_kg_table.dart'; +import 'package:school_asignment_app/page/home_page/children/student_personal/widget/student_zg_table.dart'; +import 'package:school_asignment_app/routes/app_pages.dart'; + +import 'student_personal_logic.dart'; + +class StudentPersonalPage extends StatefulWidget { + const StudentPersonalPage({Key? key}) : super(key: key); + + @override + State createState() => _StudentPersonalPageState(); +} + +class _StudentPersonalPageState extends State { + final logic = Get.find(); + final state = Get + .find() + .state; + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Color.fromRGBO(245, 245, 245, 1), + appBar: AppBar( + backgroundColor: Colors.white, + title: Obx(() { + return Text( + state.studentInfo.value.studentName, + style: TextStyle(fontSize: 14.sp, color: Color(0xFF000000)), + ); + }), + centerTitle: true, + leading: IconButton( + icon: Icon(Icons.arrow_back_ios, color: Colors.black), + onPressed: () => Navigator.of(context).pop(), + ), + actions: const [ + ReturnToHomepage(), + ], + ), + body: SingleChildScrollView( + child: Column( + children: [ + Padding( + padding: EdgeInsets.only(top: 14.r, left: 14.r), + child: Row( + children: [ + InkWell( + onTap: () { + // RouterManager.router.navigateTo(context, + // '${RouterManager.jobPersonalDetailPath}?studentId=${widget.studentId}&studentName=${Uri.encodeComponent(state.studentInfo.studentName!)}'); + Get.toNamed(Routes.studentWorkDetailPage, arguments: { + 'studentId': state.studentInfo.value.studentId, + 'studentName': state.studentInfo.value.studentName + }); + }, + child: Container( + width: 93.r, + height: 28.r, + decoration: BoxDecoration( + color: Color(0xFFEAF3FF), + borderRadius: BorderRadius.circular(4.r), + ), + child: Center( + child: Text( + '历史作业', + style: TextStyle(fontSize: 10.r, + color: Color(0xFF2080F7)), + ), + ), + ), + ), + SizedBox( + width: 10.r, + ), + InkWell( + onTap: () { + /* showAnswerHandwriting(context, jobId: widget.jobId, studentId: widget.studentId).then((value) { + ref.read(jobHandwritingDrawingTrajectoryProvider.notifier).setVal([]); + });*/ + }, + child: Container( + width: 93.r, + height: 28.r, + decoration: BoxDecoration( + color: Color(0xFFEDFFF7), + borderRadius: BorderRadius.circular(4.r), + ), + child: Center( + child: Text( + '原稿笔迹', + style: TextStyle(fontSize: 10.r, + color: Color(0xFF4CC793)), + ), + ), + ), + ), + ], + ), + ), + //客观题 + Container( + padding: EdgeInsets.symmetric(vertical: 14.r, horizontal: 10.r), + margin: EdgeInsets.symmetric(vertical: 14.r, horizontal: 14.r), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.all(Radius.circular(6.r)), + ), + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Text( + '客观题', + style: TextStyle(fontSize: 14.sp, + color: Color(0xFF5C5C5C), + fontWeight: FontWeight.w600), + ), + SizedBox( + width: 10.r, + ), + Obx(() { + return Text( + '${state.studentInfo.value.kgtCorrectRate}%', + style: TextStyle(fontSize: 14.sp, + color: Color(0xFF6888FD), + fontWeight: FontWeight.w600), + ); + }), + ], + ), + SizedBox( + height: 10.r, + ), + Obx(() { + return SizedBox( + height: state.studentInfo.value.kgtList.length > 8 + ? 300.r + : state + .studentInfo.value.kgtList.length * 40.r + 40.r, + child: StudentKgTable( + headList: ['题号', '学生答案', '标准答案'], + bodyList: state.studentInfo.value.kgtList, + questionNumCall: (no) { + // showAnswerHandwriting(context, jobId: widget.jobId, studentId: widget.studentId, questionNo: int.parse(no)).then((value) { + // ref.read(jobHandwritingDrawingTrajectoryProvider.notifier).setVal([]); + // }); + }, + ), + ); + }) + ], + ), + ), + SizedBox( + height: 15.r, + ), + //主观题 + Container( + padding: EdgeInsets.symmetric(vertical: 14.r, horizontal: 10.r), + margin: EdgeInsets.symmetric(vertical: 14.r, horizontal: 14.r), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.all(Radius.circular(6.r)), + ), + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Text( + '主观题', + style: TextStyle(fontSize: 14.sp, + color: Color(0xFF5C5C5C), + fontWeight: FontWeight.w600), + ), + SizedBox( + width: 10.r, + ), + Obx(() { + return Text( + '${state.studentInfo.value.zgtCorrectRate}%', + style: TextStyle(fontSize: 14.sp, + color: Color(0xFF6888FD), + fontWeight: FontWeight.w600), + ); + }), + ], + ), + SizedBox( + height: 10.r, + ), + Obx(() { + return SizedBox( + height: state.studentInfo.value.zgtList.length > 8 + ? 300.r + : state + .studentInfo.value.zgtList.length * 40.r + 40.r, + child: StudentZgTable( + headList: ['题号', '用时', '批注结果', '答案'], + bodyList: state.studentInfo.value.zgtList, + questionNumCall: (no) { + /* showAnswerHandwriting(context, jobId: widget.jobId, studentId: widget.studentId, questionNo: int.parse(no)).then((value) { + ref.read(jobHandwritingDrawingTrajectoryProvider.notifier).setVal([]); + });*/ + }, + ), + ); + }) + ], + ), + ), + ], + ), + ), + ); + } + + @override + void dispose() { + Get.delete(); + super.dispose(); + } +} \ No newline at end of file diff --git a/lib/page/home_page/children/student_personal/widget/student_kg_table.dart b/lib/page/home_page/children/student_personal/widget/student_kg_table.dart new file mode 100644 index 0000000..5d129eb --- /dev/null +++ b/lib/page/home_page/children/student_personal/widget/student_kg_table.dart @@ -0,0 +1,118 @@ +import 'package:data_table_2/data_table_2.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:school_asignment_app/common/job/homework_details.dart'; +import 'package:school_asignment_app/common/job/student_personal_info.dart'; + +class StudentKgTable extends StatefulWidget { + final List headList; + final List bodyList; + final int? fixedRows; + final int? fixedCols; + final Function(String)? questionNumCall; + + const StudentKgTable({ + Key? key, + required this.headList, + required this.bodyList, + this.fixedCols = 0, + this.fixedRows = 0, + this.questionNumCall, + }) : super(key: key); + + @override + State createState() => _StudentKgTableState(); +} + +class _StudentKgTableState extends State { + final ScrollController _controller = ScrollController(); + int? _sortColumnIndex; + final bool _sortAscending = true; + + String sortString(String str) { + return String.fromCharCodes(str.codeUnits.toList()..sort()); + } + + DataRow _getRow(int index, [Color? color]) { + assert(index >= 0); + KgtList item = widget.bodyList[index]; + return DataRow2.byIndex( + index: index, + color: color != null ? MaterialStateProperty.all(color) : null, + cells: [ + DataCell( + InkWell( + onTap: () { + if (widget.questionNumCall != null) { + widget.questionNumCall!(item.questionNo.toString()); + } + }, + child: Center( + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 5.r), + child: Text(item.questionNo.toString(), style: TextStyle(fontSize: 12.sp, color: Color(0xFF6888FD))), + ), + ), + ), + ), + DataCell(Center( + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 5.r), + child: Text( + item.studentAnswer == null ? '未作答' : item.studentAnswer!, + style: TextStyle( + fontSize: 12.sp, + color: item.studentAnswer == null + ? Color(0xFF525252) + : item.isCorrect! + ? const Color(0xFF4CC793) + : const Color(0xFFFF7474)), + ), + ))), + DataCell(Center( + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 5.r), + child: Text(item.answer == null ? '无' : item.answer!, style: TextStyle(fontSize: 12.sp, color: Color(0xFF525252))), + ), + )), + ], + ); + } + + @override + Widget build(BuildContext context) { + return DataTable2( + dividerThickness: 0, + scrollController: _controller, + columnSpacing: 0, + horizontalMargin: 0, + bottomMargin: 0, + dataRowHeight: 40.r, + headingRowHeight: 40.r, + border: TableBorder( + horizontalInside: BorderSide(width: 1, color: Colors.white, style: BorderStyle.solid), + bottom: BorderSide(width: 1, color: Colors.white, style: BorderStyle.solid), + verticalInside: BorderSide(width: 1, color: Colors.white, style: BorderStyle.solid)), + headingRowColor: MaterialStateProperty.resolveWith((states) => widget.fixedCols! > 0 ? Colors.white : Colors.transparent), + headingRowDecoration: BoxDecoration(color: Color(0xFFE6E6E6)), + fixedColumnsColor: Color(0xFFE6E6E6), + fixedCornerColor: Colors.grey[400], + minWidth: MediaQuery.of(context).size.width, + fixedTopRows: widget.fixedRows!, + fixedLeftColumns: widget.fixedCols!, + sortColumnIndex: _sortColumnIndex, + sortAscending: _sortAscending, + // onSelectAll: (val) => setState(() => selectAll(val)), + columns: List.generate(widget.headList.length, (index) { + var item = widget.headList[index]; + return DataColumn2( + label: Center( + child: Text(item, style: TextStyle(fontSize: 12.sp, color: Color(0xFF505767))), + ), + // size: ColumnSize.S, + fixedWidth: (MediaQuery.of(context).size.width - 20.r - 28.r) / 3, + ); + }), + rows: List.generate(widget.bodyList.length, (index) => _getRow(index, Color(0xFFF5F5F5)))); + } +} diff --git a/lib/page/home_page/children/student_personal/widget/student_zg_table.dart b/lib/page/home_page/children/student_personal/widget/student_zg_table.dart new file mode 100644 index 0000000..cdcc303 --- /dev/null +++ b/lib/page/home_page/children/student_personal/widget/student_zg_table.dart @@ -0,0 +1,152 @@ +import 'package:data_table_2/data_table_2.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:school_asignment_app/common/job/homework_details.dart'; +import 'package:school_asignment_app/common/job/student_personal_info.dart'; +import 'package:school_asignment_app/common/utils/utils.dart'; +import 'package:school_asignment_app/page/global_widget/imgDialog.dart'; + +class StudentZgTable extends StatefulWidget { + final List headList; + final List bodyList; + final int? fixedRows; + final int? fixedCols; + final Function(String)? questionNumCall; + + const StudentZgTable({ + Key? key, + required this.headList, + required this.bodyList, + this.fixedCols = 0, + this.fixedRows = 0, + this.questionNumCall, + }) : super(key: key); + + @override + State createState() => _StudentZgTableState(); +} + +class _StudentZgTableState extends State { + final ScrollController _controller = ScrollController(); + int? _sortColumnIndex; + bool _sortAscending = true; + + DataRow _getRow(int index, [Color? color]) { + assert(index >= 0); + ZgtList item = widget.bodyList[index]; + return DataRow2.byIndex( + index: index, + color: color != null ? MaterialStateProperty.all(color) : null, + cells: [ + DataCell(InkWell( + onTap: () { + if (widget.questionNumCall != null) { + widget.questionNumCall!(item.questionNo.toString()); + } + }, + child: Center( + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 5.r), + child: Text(item.questionNo.toString(), + style: TextStyle(fontSize: 12.sp, color: Color(0xFF6888FD))), + ), + ), + )), + DataCell(Center( + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 5.r), + child: Text(Utils.second2HMS(item.useTime!), + style: TextStyle(fontSize: 12.sp, color: Color(0xFF525252))), + ), + )), + /* DataCell(InkWell( + onTap: () { + if (item.state != 0) { + ImageDialog.showImgDialog(context, item.studentAnswer!); + } + }, + child: Center( + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 5.r), + child: Text(item.state != 0 ? '查看' : '--', style: TextStyle(fontSize: 12.sp, color: Color(0xFF3661FE))), + ), + ), + )),*/ + DataCell(Center( + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 5.r), + child: item.isCorrect == null + ? Text('', + style: TextStyle(fontSize: 12.sp, color: Color(0xFF525252))) + : item.isCorrect! + ? Image.asset( + 'assets/images/job_personal_correct_icon.png', + width: 18.r, + height: 18.r, + ) + : Image.asset( + 'assets/images/job_personal_error_icon.png', + width: 10.r, + height: 10.r, + ), + ), + )), + DataCell(InkWell( + onTap: () { + ImageDialog.showImgDialog(context, item.picture!); + }, + child: Center( + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 5.r), + child: Text('查看', + style: TextStyle(fontSize: 12.sp, color: Color(0xFF3661FE))), + ), + ), + )), + ], + ); + } + + @override + Widget build(BuildContext context) { + return DataTable2( + dividerThickness: 0, + scrollController: _controller, + columnSpacing: 0, + horizontalMargin: 0, + bottomMargin: 0, + headingRowHeight: 40.r, + dataRowHeight: 40.r, + border: TableBorder( + horizontalInside: BorderSide( + width: 1, color: Colors.white, style: BorderStyle.solid), + bottom: BorderSide( + width: 1, color: Colors.white, style: BorderStyle.solid), + verticalInside: BorderSide( + width: 1, color: Colors.white, style: BorderStyle.solid)), + headingRowColor: MaterialStateProperty.resolveWith((states) => + widget.fixedCols! > 0 ? Colors.white : Colors.transparent), + headingRowDecoration: BoxDecoration(color: Color(0xFFE6E6E6)), + fixedColumnsColor: Color(0xFFE6E6E6), + fixedCornerColor: Colors.grey[400], + minWidth: MediaQuery.of(context).size.width, + fixedTopRows: widget.fixedRows!, + fixedLeftColumns: widget.fixedCols!, + sortColumnIndex: _sortColumnIndex, + sortAscending: _sortAscending, + // onSelectAll: (val) => setState(() => selectAll(val)), + columns: List.generate(widget.headList.length, (index) { + var item = widget.headList[index]; + return DataColumn2( + label: Center( + child: Text(item, + style: TextStyle(fontSize: 12.sp, color: Color(0xFF505767))), + ), + // size: ColumnSize.S, + fixedWidth: (MediaQuery.of(context).size.width - 20.r - 28.r) / 4, + ); + }), + rows: List.generate(widget.bodyList.length, + (index) => _getRow(index, Color(0xFFF5F5F5)))); + } +} diff --git a/lib/page/home_page/children/student_work_detail/student_work_detail_binding.dart b/lib/page/home_page/children/student_work_detail/student_work_detail_binding.dart new file mode 100644 index 0000000..fa3005b --- /dev/null +++ b/lib/page/home_page/children/student_work_detail/student_work_detail_binding.dart @@ -0,0 +1,10 @@ +import 'package:get/get.dart'; + +import 'student_work_detail_logic.dart'; + +class StudentWorkDetailBinding extends Bindings { + @override + void dependencies() { + Get.lazyPut(() => StudentWorkDetailLogic()); + } +} diff --git a/lib/page/home_page/children/student_work_detail/student_work_detail_logic.dart b/lib/page/home_page/children/student_work_detail/student_work_detail_logic.dart new file mode 100644 index 0000000..74db89f --- /dev/null +++ b/lib/page/home_page/children/student_work_detail/student_work_detail_logic.dart @@ -0,0 +1,64 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_easyloading/flutter_easyloading.dart'; +import 'package:flutter_easyrefresh/easy_refresh.dart'; +import 'package:get/get.dart'; +import 'package:school_asignment_app/common/job/student_history.dart'; +import 'package:school_asignment_app/common/job/student_history_params.dart'; +import 'package:school_asignment_app/common/mixins/request_tool_mixin.dart'; + +import 'student_work_detail_state.dart'; + +class StudentWorkDetailLogic extends GetxController with RequestToolMixin, GetSingleTickerProviderStateMixin{ + final StudentWorkDetailState state = StudentWorkDetailState(); + late TabController tabController; + late final EasyRefreshController refreshController; + + @override + void onInit() { + super.onInit(); + state.studentName.value = Get.arguments['studentName'] ?? ''; + state.studentId = Get.arguments['studentId'] ?? -1; + tabController = TabController(length: 3, vsync: this); + refreshController = EasyRefreshController(); + EasyLoading.show(status: 'loading...'); + getList(); + } + + void getList() async { + StudentHistoryParams params = StudentHistoryParams( + assessType: state.isJob.value?0:1, + studentId: state.studentId, + dateStart: state.dateStart, + dateEnd: state.dateEnd, + pageNumber: state.page, + pageSize: 10, + ); + StudentHistory data = await getClient().getStudentHistory(params); + state.studentData.value = data; + for(var element in state.studentData.value.items.items){ + int num = 0; + for (var item in element.kgtList) { + if (item.state == 0) { + num = num + 1; + } + } + for (var subject in element.zgtList) { + if (subject.state == 0) { + num = num + 1; + } + } + if (num == (element.kgtList.length + element.zgtList.length)) { + element.allNotDone = true; + } + + } + EasyLoading.dismiss(); + } + + @override + void dispose() { + super.dispose(); + tabController.dispose(); + refreshController.dispose(); + } +} diff --git a/lib/page/home_page/children/student_work_detail/student_work_detail_state.dart b/lib/page/home_page/children/student_work_detail/student_work_detail_state.dart new file mode 100644 index 0000000..09ca2f5 --- /dev/null +++ b/lib/page/home_page/children/student_work_detail/student_work_detail_state.dart @@ -0,0 +1,19 @@ +import 'package:get/get.dart'; +import 'package:school_asignment_app/common/job/student_history.dart'; +import 'package:school_asignment_app/common/utils/utils.dart'; + +class StudentWorkDetailState { + StudentWorkDetailState() { + ///Initialize variables + } + + late RxString studentName = ''.obs; + late int studentId = -1; + late RxBool isJob = true.obs; + late int page = 1; + late int totalPages = 0; + late String dateStart = Utils.getWeekStartDate().toString().substring(0, 10); + late String dateEnd = Utils.getWeekEndDate().toString().substring(0, 10); + late RxString customTimeStr = '自定义'.obs; + late Rx studentData = Rx(StudentHistory(0,0,Items([],0),0)); +} diff --git a/lib/page/home_page/children/student_work_detail/student_work_detail_view.dart b/lib/page/home_page/children/student_work_detail/student_work_detail_view.dart new file mode 100644 index 0000000..acd3ea5 --- /dev/null +++ b/lib/page/home_page/children/student_work_detail/student_work_detail_view.dart @@ -0,0 +1,598 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_easyloading/flutter_easyloading.dart'; +import 'package:flutter_easyrefresh/easy_refresh.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:get/get.dart'; +import 'package:school_asignment_app/common/job/student_history.dart'; +import 'package:school_asignment_app/common/utils/enum_untils.dart'; +import 'package:school_asignment_app/common/utils/utils.dart'; +import 'package:school_asignment_app/page/global_widget/MyEmptyWidget.dart'; +import 'package:school_asignment_app/page/global_widget/ReturnToHomepage.dart'; +import 'package:school_asignment_app/page/home_page/children/student_work_detail/widget/job_condition_filter.dart'; +import 'package:school_asignment_app/page/home_page/widget/progress_bar.dart'; +import 'package:school_asignment_app/routes/app_pages.dart'; +import 'package:syncfusion_flutter_datepicker/datepicker.dart'; + +import 'student_work_detail_logic.dart'; + +class StudentWorkDetailPage extends StatefulWidget { + const StudentWorkDetailPage({Key? key}) : super(key: key); + + @override + State createState() => _StudentWorkDetailPageState(); +} + +class _StudentWorkDetailPageState extends State { + final logic = Get.find(); + final state = Get + .find() + .state; + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Color.fromRGBO(245, 245, 245, 1), + appBar: AppBar( + backgroundColor: Colors.white, + title: Text('${state.studentName}作业详情', + style: TextStyle(fontSize: 14.sp, color: Color(0xFF333333))), + centerTitle: true, + leading: IconButton( + icon: Icon(Icons.arrow_back_ios, color: Colors.black), + onPressed: () => Navigator.of(context).pop(), + ), + actions: const [ + ReturnToHomepage(), + ], + elevation: 0, + ), + body: Column( + children: [ + Container( + height: 1.r, + width: MediaQuery + .of(context) + .size + .width, + color: Color.fromRGBO(179, 179, 179, 0.3), + ), + Container( + color: Colors.white, + padding: EdgeInsets.symmetric(vertical: 2.r), + child: Row( + children: [ + InkWell( + onTap: () { + EasyLoading.show(status: 'loading...'); + state.page = 1; + state.totalPages = 0; + state.isJob.value = true; + logic.getList(); + }, + child: SizedBox( + width: (MediaQuery + .of(context) + .size + .width - 1.r) / 2, + height: 40.r, + child: Obx(() { + return Center( + child: Text( + '作业', + style: TextStyle(fontSize: 14.sp, + color: state.isJob.value + ? Color(0xFF7491FD) + : Color(0xFF505E6E)), + )); + }), + ), + ), + Container( + height: 40.r, + width: 1.r, + color: Color.fromRGBO(179, 179, 179, 0.3), + ), + InkWell( + onTap: () { + EasyLoading.show(status: 'loading...'); + state.isJob.value = false; + state.page = 1; + state.totalPages = 0; + logic.getList(); + }, + child: SizedBox( + width: (MediaQuery + .of(context) + .size + .width - 1.r) / 2, + height: 40.r, + child: Center( + child: Obx(() { + return Text( + '考试', + style: TextStyle( + fontSize: 14.sp, color: !state.isJob.value + ? Color(0xFF7491FD) + : Color(0xFF505E6E)), + ); + })), + ), + ), + ], + ), + ), + Obx(() { + return Container( + margin: EdgeInsets.symmetric(vertical: 10.r, horizontal: 14.r), + padding: EdgeInsets.only( + top: 10.r, left: 10.r, right: 10.r, bottom: 10.r), + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(10.r)), + color: Colors.white), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + '总览:', + style: TextStyle(fontSize: 12.sp, + color: Color(0xFF7491FD), + fontWeight: FontWeight.w600), + ), + ProgressBar( + title: '客观题正确率:', + color: Color(0xFFB8C7FF), + percent: state.studentData.value.kgtCorrectRate / 100, + padingEdg: EdgeInsets.zero, + marginEdg: EdgeInsets.only(top: 8.h)), + ProgressBar( + title: '主观题正确率:', + color: Color(0xFFB8C7FF), + percent: state.studentData.value.zgtCorrectRate / 100, + padingEdg: EdgeInsets.zero, + marginEdg: EdgeInsets.only(top: 8.h)), + ProgressBar( + title: '总正确率:', + color: Color(0xFFB8C7FF), + percent: state.studentData.value.correctRate / 100, + padingEdg: EdgeInsets.zero, + marginEdg: EdgeInsets.only(top: 8.h)), + ], + ), + ); + }), + + + Obx(() { + return JobConditionFilter( + controller: logic.tabController, + jobType: state.isJob.value ? 1 : 2, + customTimeStr: state.customTimeStr.value, + customTime: logic.tabController.index != 2 || + ((state.dateEnd == null || state.dateEnd == '') && + (state.dateStart == null || state.dateStart == '')) + ? null + : PickerDateRange( + state.dateStart == null || state.dateStart == '' + ? null + : DateTime + .parse(state.dateStart!), + state.dateEnd == null || state.dateEnd == '' ? null : DateTime + .parse(state.dateEnd!), + ), + onTimeFilter: (String? startTime, String? endTime) { + EasyLoading.show(status: 'loading...'); + if (startTime == null && endTime == null) { + if (logic.tabController.index == 2) { + logic.tabController.animateTo(0); + } + state.dateStart = + Utils.getWeekStartDate().toString().substring(0, 10); + state.dateEnd = + Utils.getWeekEndDate().toString().substring(0, 10); + state.customTimeStr.value = '自定义'; + } else { + state.dateStart = startTime ?? ''; + state.dateEnd = endTime ?? ''; + } + state.page = 1; + logic.getList(); + }, + refreshTime: (value) { + if (value != null && value.startDate != null) { + state.customTimeStr.value = + value.startDate?.toString().substring(0, 10) ?? ''; + + if (value.endDate != null) { + if (!Utils.isPad() && + value.startDate!.year == value.endDate!.year) { + state.customTimeStr.value = + '${value.startDate.toString().substring(5, 10)}~${value + .endDate.toString().substring(5, 10)}'; + } else { + state.customTimeStr.value = + '${state.customTimeStr.value}~${value.endDate + ?.toString() + .substring( + 0, 10)}'; + } + } + } + }); + }), + Padding( + padding: EdgeInsets.only(top: 14.r, right: 14.r), + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Text( + '注:', + style: TextStyle(fontSize: 8.sp, color: Color(0xFF8B8B8B)), + ), + Container( + width: 10.r, + height: 10.r, + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(5.r)), + // color: Color(0xFF4CC793), + border: Border.all(width: 1.r, color: Color(0xFF4CC793)), + ), + ), + SizedBox( + width: 2.r, + ), + Text( + '正确', + style: TextStyle(fontSize: 8.sp, color: Color(0xFF8B8B8B)), + ), + SizedBox( + width: 15.r, + ), + Container( + width: 10.r, + height: 10.r, + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(5.r)), + // color: Color(0xFFFF7474), + border: Border.all(width: 1.r, color: Color(0xFFFF7474)), + ), + ), + SizedBox( + width: 2.r, + ), + Text( + '错误', + style: TextStyle(fontSize: 8.sp, color: Color(0xFF8B8B8B)), + ), + SizedBox( + width: 15.r, + ), + Container( + width: 10.r, + height: 10.r, + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(5.r)), + // color: Color(0xFF666666), + border: Border.all(width: 1.r, color: Color(0xFF666666)), + // border: Border.all(width: 1.r,color: Colors.grey), + /* boxShadow: [ + BoxShadow( + color: Colors.grey, + offset: Offset(1.w, 1.h), //阴影y轴偏移量 + blurRadius: 4, //阴影模糊程度 + spreadRadius: 0.1, //阴影扩散程度 + ) + ],*/ + ), + ), + SizedBox( + width: 2.r, + ), + Text( + '已作答未批阅', + style: TextStyle(fontSize: 8.sp, color: Color(0xFF8B8B8B)), + ), + SizedBox( + width: 15.r, + ), + Container( + width: 10.r, + height: 10.r, + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(5.r)), + border: Border.all(width: 1.r, color: Color(0xFFDDDDDD)), + // color: Color(0xFFDDDDDD), + ), + ), + SizedBox( + width: 2.r, + ), + Text( + '未做', + style: TextStyle(fontSize: 8.sp, color: Color(0xFF8B8B8B)), + ), + ], + ), + ), + Expanded( + child: Padding( + padding: EdgeInsets.symmetric(vertical: 10.r), + child: Obx(() { + return EasyRefresh( + firstRefresh: false, + taskIndependence: true, + controller: logic.refreshController, + header: MaterialHeader(), + footer: TaurusFooter(), + onRefresh: () async { + state.page = 1; + logic.getList(); + }, + onLoad: () async { + if (state.page < state.totalPages) { + state.page += 1; + logic.getList(); + } + }, + child: state.studentData.value.items.items.isNotEmpty + ? ListView.builder( + itemCount: state.studentData.value.items.items.length, + itemBuilder: (context, index) { + StudentItems item = state.studentData.value.items + .items[index]; + return InkWell( + onTap: () { + Get.toNamed(Routes.studentPersonalPage, arguments: { + 'homeworkId': item.id, + 'studentId': state.studentId + }); + }, + child: Container( + margin: EdgeInsets.symmetric(vertical: 5.r, + horizontal: 14.r), + padding: EdgeInsets.symmetric(vertical: 14.r, + horizontal: 10.r), + decoration: BoxDecoration( + borderRadius: BorderRadius.all( + Radius.circular(10.r)), + color: item.allNotDone + ? const Color(0xFFFFEDD3) + : Colors.white), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Container( + width: 32.w, + height: 18.h, + alignment: Alignment.center, + padding: EdgeInsets.only(left: 2.w), + decoration: BoxDecoration( + color: state.isJob.value ? const Color + .fromRGBO( + 104, 136, 253, 1) : const Color( + 0xFFFFA116), + borderRadius: BorderRadius.only( + topLeft: Radius.circular(14.r), + topRight: Radius.circular(3.r), + bottomLeft: Radius.circular(4.r), + bottomRight: Radius.circular(4.r), + ), + ), + margin: EdgeInsets.only(right: 4.w), + child: Text( + state.isJob.value ? '作业' : '考试', + style: TextStyle( + fontSize: 10.sp, + color: Colors.white), + ), + ), + Expanded( + child: Text( + item.name, + style: TextStyle(fontSize: 12.sp, + color: Color(0xFF464646)), + )), + // SizedBox(width: 5.r,), + // Text('2024.1',style: TextStyle(fontSize: 12.sp,color: Color(0xFF5B5B5B)),), + + Container( + width: 40.r, + height: 20.r, + decoration: BoxDecoration( + borderRadius: BorderRadius.all( + Radius.circular(4.r)), + border: Border.all( + width: 1.r, + color: Color(0xFF4CC793)), + ), + child: Center( + child: Text( + EnumUtils.formatSubject( + item.subject), + style: TextStyle(fontSize: 10.sp, + color: Color(0xFF4CC793)), + )), + ), + ], + ), + SizedBox( + height: 10.r, + ), + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + '客:', + style: TextStyle(fontSize: 12.sp, + color: Color(0xFF5B5B5B)), + ), + SizedBox( + width: 5.r, + ), + item.kgtList.isNotEmpty + ? Expanded( + child: Wrap( + direction: Axis.horizontal, + alignment: WrapAlignment.start, + spacing: 8, + runSpacing: 5, + children: List.generate( + item.kgtList.length, (i) { + KgtList subjective = item + .kgtList[i]; + return Container( + width: 20.r, + height: 20.r, + decoration: BoxDecoration( + color: Colors.transparent, + border: Border.all( + width: 1.r, + color: subjective.state == 0 + ? Color(0xFFDDDDDD) + : subjective.state == 3 + ? Color(0xFF4CC793) + : subjective.state == 2 + ? Color(0xFFFF7474) + : Color(0xFF666666)), + borderRadius: BorderRadius.all( + Radius.circular(10.r))), + child: Center( + child: Text( + subjective.questionNo + .toString(), + style: TextStyle( + fontSize: 10.r, + color: subjective.state == + 0 + ? Color(0xFFDDDDDD) + : subjective.state == + 3 + ? Color(0xFF4CC793) + : subjective.state == + 2 + ? Color(0xFFFF7474) + : Color(0xFF666666)), + )), + ); + }), + ), + ) + : Text( + '无', + style: TextStyle(fontSize: 12.sp, + color: Color(0xFF5B5B5B)), + ), + ], + ), + SizedBox( + height: 10.r, + ), + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + '主:', + style: TextStyle(fontSize: 12.sp, + color: Color(0xFF5B5B5B)), + ), + SizedBox( + width: 5.r, + ), + item.zgtList.isNotEmpty + ? Expanded( + child: Wrap( + direction: Axis.horizontal, + alignment: WrapAlignment.start, + spacing: 8, + runSpacing: 5, + children: List.generate( + item.zgtList.length, (i) { + ZgtList subjective = item + .zgtList[i]; + return Container( + width: 20.r, + height: 20.r, + decoration: BoxDecoration( + color: Colors.transparent, + border: Border.all( + width: 1.r, + color: subjective.state == 0 + ? Color(0xFFDDDDDD) + : subjective.state == 3 + ? Color(0xFF4CC793) + : subjective.state == 2 + ? Color(0xFFFF7474) + : Color(0xFF666666)), + borderRadius: BorderRadius.all( + Radius.circular(10.r))), + child: Center( + child: Text( + subjective.questionNo + .toString(), + style: TextStyle( + fontSize: 10.r, + color: subjective.state == + 0 + ? Color(0xFFDDDDDD) + : subjective.state == + 3 + ? Color(0xFF4CC793) + : subjective.state == + 2 + ? Color(0xFFFF7474) + : Color(0xFF666666)), + )), + ); + }), + ), + ) + : Text( + '无', + style: TextStyle(fontSize: 12.sp, + color: Color(0xFF5B5B5B)), + ), + ], + ), + ProgressBar( + title: '客观题正确率:', + color: Color(0xFF90E0BE), + percent: item.kgtCorrectRate / 100, + padingEdg: EdgeInsets.zero, + marginEdg: EdgeInsets.only(top: 8.h)), + ProgressBar( + title: '主观题正确率:', + color: Color(0xFF90E0BE), + percent: item.zgtCorrectRate / 100, + padingEdg: EdgeInsets.zero, + marginEdg: EdgeInsets.only(top: 8.h)), + ProgressBar( + title: '总正确率:', + color: Color(0xFF90E0BE), + percent: item.correctRate / 100, + padingEdg: EdgeInsets.zero, + marginEdg: EdgeInsets.only(top: 8.h)), + ], + ), + ), + ); + }) + : const MyEmptyWidget(), + ); + }), + ), + ), + ], + ), + ); + } + + @override + void dispose() { + Get.delete(); + super.dispose(); + } +} \ No newline at end of file diff --git a/lib/page/home_page/children/student_work_detail/widget/job_condition_filter.dart b/lib/page/home_page/children/student_work_detail/widget/job_condition_filter.dart new file mode 100644 index 0000000..3c19165 --- /dev/null +++ b/lib/page/home_page/children/student_work_detail/widget/job_condition_filter.dart @@ -0,0 +1,127 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:get/get.dart'; +import 'package:school_asignment_app/common/utils/utils.dart'; +import 'package:school_asignment_app/page/home_page/children/student_work_detail/widget/personal_detail_topbar.dart'; +import 'package:syncfusion_flutter_datepicker/datepicker.dart'; + +class JobConditionFilter extends StatefulWidget { +final TabController controller; +final int jobType; +final PickerDateRange? customTime; +final Function refreshTime; +final String customTimeStr; +final Function(String? startTime, String? endTime) onTimeFilter; + const JobConditionFilter({Key? key, + required this.controller, + required this.jobType, + this.customTime, + required this.refreshTime, + required this.customTimeStr, + required this.onTimeFilter}) : super(key: key); + + @override + State createState() => _JobConditionFilterState(); +} + +class _JobConditionFilterState extends State { + + var customTimeState = const PickerDateRange(null, null); + + @override + void initState() { + super.initState(); + if (widget.customTime != null) { + customTimeState = PickerDateRange(widget.customTime!.startDate, + widget.customTime!.endDate); + } + } + + DateTime getMonthStartDate() { + DateTime now = DateTime.now(); + return DateTime(now.year, now.month, 1); // 获取当前月份的第一天 + } + + DateTime getMonthEndDate() { + DateTime now = DateTime.now(); + int nextMonth = now.month + 1; + if (nextMonth > 12) { + nextMonth = 1; + now = now.add(Duration(days: 31 - now.day)); // 跨年了,所以加到当前月的最后一天 + } else { + now = now.add(Duration(days: DateTime(now.year, nextMonth, 0).day - now.day)); // 加到下个月的第一天的前一天,即本月最后一天 + } + return now; + } + + + + @override + Widget build(BuildContext context) { + return Container( + // height: 39.h, + // padding: EdgeInsets.only(left: 4.w, right: 12.w), + decoration: const BoxDecoration( + color: Color.fromRGBO(244, 244, 244, 1), + // border: Border(bottom: BorderSide(color: Color.fromRGBO(204, 204, 204, 1), width: 1)), + ), + child: PersonalDetailTopBar( + controller: widget.controller, + customTimeStr: widget.customTimeStr, + onTap: (int val) async { + switch (val) { + /*case 0: // 全部 + widget.onTimeFilter(null, null); + break;*/ + case 0: // 近一周 + widget.onTimeFilter( + Utils.getWeekStartDate().toString().substring(0, 10), + Utils.getWeekEndDate().toString().substring(0, 10), + ); + break; + case 1: // 近一个月 + widget.onTimeFilter( + getMonthStartDate().toString().substring(0, 10), + getMonthEndDate().toString().substring(0, 10), + ); + break; + default: // 自定义 + var dialogData = await showDialog( + context: context, + builder: (BuildContext context1) { + return Center( + child: Container( + color: Colors.white, + width: Utils.isPad() ? ScreenUtil().screenWidth / 2 : ScreenUtil().screenWidth / 1.3, + height: ScreenUtil().screenHeight / 2, + child: SfDateRangePicker( + showActionButtons: true, + confirmText: '确定', + cancelText: '取消', + onSubmit: (p0) { + print(p0); + Get.back(result: p0); + // Navigator.of(context1).pop(p0); + widget.refreshTime(p0); + }, + onCancel: () { + Get.back(); + // Navigator.of(context1).pop(); + }, + selectionMode: DateRangePickerSelectionMode.range, + initialSelectedRange: customTimeState, + ), + ), + ); + }); + widget.onTimeFilter( + dialogData?.startDate?.toString().substring(0, 10), + dialogData?.endDate?.toString().substring(0, 10), + ); + customTimeState = dialogData!; + } + }, + ), + ); + } +} diff --git a/lib/page/home_page/children/student_work_detail/widget/personal_detail_topbar.dart b/lib/page/home_page/children/student_work_detail/widget/personal_detail_topbar.dart new file mode 100644 index 0000000..12d1d32 --- /dev/null +++ b/lib/page/home_page/children/student_work_detail/widget/personal_detail_topbar.dart @@ -0,0 +1,52 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; + +class PersonalDetailTopBar extends StatefulWidget { + final TabController controller; + final ValueChanged? onTap; + final String customTimeStr; + final bool? hasAll; + const PersonalDetailTopBar({Key? key,required this.controller, this.onTap, required this.customTimeStr,this.hasAll=false}) : super(key: key); + + @override + State createState() => _PersonalDetailTopBarState(); +} + +class _PersonalDetailTopBarState extends State { + @override + void initState(){ + super.initState(); + } + + @override + Widget build(BuildContext context) { + return Container( + alignment: Alignment.centerLeft, + decoration: BoxDecoration( + border: Border(bottom: BorderSide(width: 1.r,color: Color(0xFFCCCCCC))) + ), + child: TabBar( + controller: widget.controller, + unselectedLabelStyle: TextStyle(fontSize: 12.sp, color: const Color.fromRGBO(102, 102, 102, 1)), + labelStyle: TextStyle( + fontSize: 12.sp, + fontWeight: FontWeight.bold, + color: const Color.fromRGBO(116, 145, 253, 1), + ), + isScrollable: true, + labelColor: const Color(0xFF7491FD), + unselectedLabelColor: const Color(0xFF505E6E), + padding: EdgeInsets.symmetric(horizontal: 14.r), + // indicatorSize: TabBarIndicatorSize.label, // 设置指示器高度和标签一样高 + onTap: widget.onTap, + tabs: [ + if(widget.hasAll == true) + const Tab(text: '全部'), + const Tab(text: '近一周'), + const Tab(text: '近一月'), + Tab(text: widget.customTimeStr), + ], + ), + ); + } +} diff --git a/lib/page/home_page/home_logic.dart b/lib/page/home_page/home_logic.dart index f8cc40f..ffe6873 100644 --- a/lib/page/home_page/home_logic.dart +++ b/lib/page/home_page/home_logic.dart @@ -17,7 +17,7 @@ class HomeLogic extends GetxController with RequestToolMixin, GetTickerProviderS WorkStudentParams params = WorkStudentParams( assessType: 0, ); - WorkStudent data = await getClient().getWorkList(params); + WorkStudent data = await getClient().getUnAnnotateList(params); UserStore.to.readOver.value = data.items.length; } diff --git a/lib/page/home_page/widget/student_group_list.dart b/lib/page/home_page/widget/student_group_list.dart index 3cb9f5a..04f8007 100644 --- a/lib/page/home_page/widget/student_group_list.dart +++ b/lib/page/home_page/widget/student_group_list.dart @@ -32,7 +32,7 @@ class StudentGroupList extends StatelessWidget { ClassItem item = studentGroups[index]; return InkWell( onTap: () { - goNextPage(item.id,'${EnumUtils.formatGrade(item.grade)}${item.className}'); + goNextPage(item.classId,'${EnumUtils.formatGrade(item.grade)}${item.className}',item.subject); }, child: Container( padding: EdgeInsets.symmetric(horizontal: 10.r), @@ -94,7 +94,7 @@ class StudentGroupList extends StatelessWidget { ClassItem item = studentGroups[index]; return InkWell( onTap: () { - // goNextPage(item.groupId, item.groupName); + goNextPage(item.classId,'${EnumUtils.formatGrade(item.grade)}${item.className}',item.subject); }, child: Container( padding: diff --git a/lib/routes/app_pages.dart b/lib/routes/app_pages.dart index 7cbbd4c..7fe3d41 100644 --- a/lib/routes/app_pages.dart +++ b/lib/routes/app_pages.dart @@ -14,6 +14,10 @@ import 'package:school_asignment_app/page/home_page/children/read_over/read_over import 'package:school_asignment_app/page/home_page/children/read_over/read_over_view.dart'; import 'package:school_asignment_app/page/home_page/children/student_history_work/student_history_work_binding.dart'; import 'package:school_asignment_app/page/home_page/children/student_history_work/student_history_work_view.dart'; +import 'package:school_asignment_app/page/home_page/children/student_personal/student_personal_binding.dart'; +import 'package:school_asignment_app/page/home_page/children/student_personal/student_personal_view.dart'; +import 'package:school_asignment_app/page/home_page/children/student_work_detail/student_work_detail_binding.dart'; +import 'package:school_asignment_app/page/home_page/children/student_work_detail/student_work_detail_view.dart'; import 'package:school_asignment_app/page/home_page/home_binding.dart'; import 'package:school_asignment_app/page/home_page/home_view.dart'; import 'package:school_asignment_app/page/login_page/children/agreement_page.dart'; @@ -38,6 +42,8 @@ abstract class AppPages { GetPage(name: Routes.annotateClassPage, page: () => const AnnotateClassPage(), binding: AnnotateClassBinding(), transition: Transition.noTransition), GetPage(name: Routes.quickDataCheckPage, page: () => const QuickDataCheckPage(), binding: QuickDataCheckBinding(), transition: Transition.noTransition), GetPage(name: Routes.jobReportPage, page: () => const JobReportPage(), binding: JobReportBinding(), transition: Transition.noTransition), + GetPage(name: Routes.studentPersonalPage, page: () => const StudentPersonalPage(), binding: StudentPersonalBinding(), transition: Transition.noTransition), + GetPage(name: Routes.studentWorkDetailPage, page: () => const StudentWorkDetailPage(), binding: StudentWorkDetailBinding(), transition: Transition.noTransition), ]; } diff --git a/lib/routes/app_routes.dart b/lib/routes/app_routes.dart index 5b51d1e..d9124ef 100644 --- a/lib/routes/app_routes.dart +++ b/lib/routes/app_routes.dart @@ -14,4 +14,6 @@ abstract class Routes { static const annotateClassPage = '/annotateClassPage'; static const quickDataCheckPage = '/quickDataCheckPage'; static const jobReportPage = '/jobReportPage'; + static const studentPersonalPage = '/studentPersonalPage'; + static const studentWorkDetailPage = '/studentWorkDetailPage'; } \ No newline at end of file diff --git a/pubspec.lock b/pubspec.lock index f25000c..9917f15 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -257,6 +257,14 @@ packages: url: "https://pub.dev" source: hosted version: "5.4.2+1" + dropdown_button2: + dependency: "direct main" + description: + name: dropdown_button2 + sha256: b0fe8d49a030315e9eef6c7ac84ca964250155a6224d491c1365061bc974a9e1 + url: "https://pub.dev" + source: hosted + version: "2.3.9" equatable: dependency: transitive description: @@ -342,6 +350,11 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.3" + flutter_localizations: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" flutter_screenutil: dependency: "direct main" description: @@ -358,6 +371,14 @@ packages: url: "https://pub.dev" source: hosted version: "5.2.1" + flutter_staggered_grid_view: + dependency: "direct main" + description: + name: flutter_staggered_grid_view + sha256: "1312314293acceb65b92754298754801b0e1f26a1845833b740b30415bbbcf07" + url: "https://pub.dev" + source: hosted + version: "0.6.2" flutter_test: dependency: "direct dev" description: flutter @@ -464,6 +485,14 @@ packages: url: "https://pub.dev" source: hosted version: "4.0.2" + intl: + dependency: transitive + description: + name: intl + sha256: a3715e3bc90294e971cb7dc063fbf3cd9ee0ebf8604ffeafabd9e6f16abbdbe6 + url: "https://pub.dev" + source: hosted + version: "0.18.0" io: dependency: transitive description: @@ -829,6 +858,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.2.0" + syncfusion_flutter_core: + dependency: transitive + description: + name: syncfusion_flutter_core + sha256: "8db8f55c77f56968681447d3837c10f27a9e861e238a898fda116c7531def979" + url: "https://pub.dev" + source: hosted + version: "21.2.10" + syncfusion_flutter_datepicker: + dependency: "direct main" + description: + name: syncfusion_flutter_datepicker + sha256: "6b0dacfe2f968de2b9107e2dc24fcaa2499415ae655df8f0d3ad0356eb090213" + url: "https://pub.dev" + source: hosted + version: "21.2.10" synchronized: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 0392ebb..3548ccc 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -30,6 +30,8 @@ environment: dependencies: flutter: sdk: flutter + flutter_localizations: + sdk: flutter # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. @@ -73,6 +75,9 @@ dependencies: # 图表 fl_chart: ^0.62.0 data_table_2: ^2.5.10 + flutter_staggered_grid_view: ^0.6.2 + dropdown_button2: ^2.3.9 + syncfusion_flutter_datepicker: ^21.2.10 dev_dependencies: flutter_test: