diff --git a/making_school_asignment_app/lib/common/config/request_config.dart b/making_school_asignment_app/lib/common/config/request_config.dart index 2625524..9e7c759 100644 --- a/making_school_asignment_app/lib/common/config/request_config.dart +++ b/making_school_asignment_app/lib/common/config/request_config.dart @@ -20,7 +20,7 @@ class RequestConfig { static const connectTimeout = 8 * 1000; // 连接超时 static const receiveTimeout = 8 * 1000; // 接收超时 - static const bool requestDataPrinting = true; // 打印返回数据 + static const bool requestDataPrinting = false; // 打印返回数据 static const bool printSwitch = true; // 打印返回数据 static const successCode = [204, 200]; // 返回成功code static final BasePage basePage = BasePage(1, 10); // 分页参数 diff --git a/making_school_asignment_app/lib/common/job/homework_details.dart b/making_school_asignment_app/lib/common/job/homework_details.dart index c4a4d80..1ce5378 100644 --- a/making_school_asignment_app/lib/common/job/homework_details.dart +++ b/making_school_asignment_app/lib/common/job/homework_details.dart @@ -87,10 +87,12 @@ class Questions extends Object { @JsonKey(name: 'overallTitles') List? overallTitles; + @JsonKey(name: 'options') + List? options; Questions(this.id,this.templateId,this.questionNo,this.questionType,this.answer,this.score,this.questionPicture,this.subjectivePicture,this.knows,this.answerCount, this.answerRate,this.okRate,this.priorityInfo,this.noAnswerStudents,this.answerOkStudents,this.answerNgStudents,this.correctRate, - this.overallTitles); + this.overallTitles,this.options); factory Questions.fromJson(Map srcJson) => _$QuestionsFromJson(srcJson); @@ -274,4 +276,27 @@ class OverallTitles extends Object { Map toJson() => _$OverallTitlesToJson(this); +} + +@JsonSerializable() +class SelectionRate extends Object { + + @JsonKey(name: 'optionName') + String optionName; + + @JsonKey(name: 'rate') + int rate; + + @JsonKey(name: 'isCheck') + bool isCheck; + + @JsonKey(name: 'currentOptionStudents') + List currentOptionStudents; + + SelectionRate(this.optionName,this.rate,this.isCheck,this.currentOptionStudents,); + + factory SelectionRate.fromJson(Map srcJson) => _$SelectionRateFromJson(srcJson); + + Map toJson() => _$SelectionRateToJson(this); + } \ No newline at end of file diff --git a/making_school_asignment_app/lib/common/utils/utils.dart b/making_school_asignment_app/lib/common/utils/utils.dart index 21de0ed..bbbf694 100644 --- a/making_school_asignment_app/lib/common/utils/utils.dart +++ b/making_school_asignment_app/lib/common/utils/utils.dart @@ -12,7 +12,9 @@ import '../config/request_config.dart'; class Utils { static Utils? _instance; + Utils._internal(); + static Utils getInstance() { _instance ??= Utils._internal(); @@ -30,7 +32,8 @@ class Utils { } } - void setTimeOut(int seconds, call) => Future.delayed(Duration(seconds: seconds), call); + void setTimeOut(int seconds, call) => + Future.delayed(Duration(seconds: seconds), call); // 是否是平板 static bool isPad([double mobilePhoneScale = 1.2]) { @@ -94,30 +97,43 @@ class Utils { dataCount.kgtAnswerCount = kgt.where((w) => w.state != 0).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!); + dataCount.kgtAnswerRate = + Utils.calcRate(dataCount.kgtAnswerCount!, dataCount.kgtDtlCount!); + dataCount.kgtOkRate = + Utils.calcRate(dataCount.kgtOkCount!, dataCount.kgtDtlCount!); - dataCount.kgtCorrectRate = Utils.calcRate(dataCount.kgtOkCount!, dataCount.kgtAnswerCount!); - dataCount.kgtCount = data.questions.where((w) => w.questionType == 1).length; + dataCount.kgtCorrectRate = + Utils.calcRate(dataCount.kgtOkCount!, dataCount.kgtAnswerCount!); + dataCount.kgtCount = + data.questions.where((w) => w.questionType == 1).length; 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 == 3).length; dataCount.zgtDtlCount = zgt.length; - dataCount.zgtAnswerRate = Utils.calcRate(dataCount.zgtAnswerCount!, dataCount.zgtDtlCount!); - dataCount.zgtOkRate = Utils.calcRate(dataCount.zgtOkCount!, dataCount.zgtDtlCount!); + dataCount.zgtAnswerRate = + Utils.calcRate(dataCount.zgtAnswerCount!, dataCount.zgtDtlCount!); + dataCount.zgtOkRate = + Utils.calcRate(dataCount.zgtOkCount!, dataCount.zgtDtlCount!); - dataCount.zgtCorrectRate = Utils.calcRate(dataCount.zgtOkCount!, dataCount.zgtAnswerCount!); - dataCount.zgtCount = data.questions.where((w) => w.questionType == 2).length; + dataCount.zgtCorrectRate = + Utils.calcRate(dataCount.zgtOkCount!, dataCount.zgtAnswerCount!); + dataCount.zgtCount = + data.questions.where((w) => w.questionType == 2).length; dataCount.studentCount = data.students.length; - dataCount.priorityStudents = data.students.where((w) => w.priorityAnnotate!).toList(); + dataCount.priorityStudents = + data.students.where((w) => w.priorityAnnotate!).toList(); //已提交学生数 - dataCount.studentSubmitCount = data.students.where((s) => s.state != 0).length; - dataCount.studentSubmitStudents = data.students.where((s) => s.state != 0).toList(); + dataCount.studentSubmitCount = + data.students.where((s) => s.state != 0).length; + dataCount.studentSubmitStudents = + data.students.where((s) => s.state != 0).toList(); //未提交学生数 - dataCount.noAnswerCount = data.students.length - dataCount.studentSubmitCount!; - dataCount.noAnswerStudents = data.students.where((s) => s.state == 0).toList(); + dataCount.noAnswerCount = + data.students.length - dataCount.studentSubmitCount!; + dataCount.noAnswerStudents = + data.students.where((s) => s.state == 0).toList(); for (var stu in data.students) { stu.kgtStu = kgt.where((w) => w.studentId == stu.studentId).toList(); @@ -125,13 +141,16 @@ class Utils { // stu.kgtStu!.sort((a, b) => num.parse(a.questionNo).compareTo(num.parse(b.questionNo))); stu.kgtStu!.sort((a, b) { try { - if (RegExp(r'^\d*\.?\d+$').hasMatch(a.questionNo) && RegExp(r'^\d*\.?\d+$').hasMatch(b.questionNo)) { + if (RegExp(r'^\d*\.?\d+$').hasMatch(a.questionNo) && + RegExp(r'^\d*\.?\d+$').hasMatch(b.questionNo)) { return num.parse(a.questionNo).compareTo(num.parse(b.questionNo)); } else { throw Exception(); } } catch (e) { - return a.questionNo.toLowerCase().compareTo(b.questionNo.toLowerCase()); + return a.questionNo + .toLowerCase() + .compareTo(b.questionNo.toLowerCase()); } }); stu.kgtOkCount = stu.kgtStu!.where((w) => w.state == 3).length; @@ -142,13 +161,16 @@ class Utils { // stu.zgtStu!.sort((a, b) => num.parse(a.questionNo).compareTo(num.parse(b.questionNo))); stu.zgtStu!.sort((a, b) { try { - if (RegExp(r'^\d*\.?\d+$').hasMatch(a.questionNo) && RegExp(r'^\d*\.?\d+$').hasMatch(b.questionNo)) { + if (RegExp(r'^\d*\.?\d+$').hasMatch(a.questionNo) && + RegExp(r'^\d*\.?\d+$').hasMatch(b.questionNo)) { return num.parse(a.questionNo).compareTo(num.parse(b.questionNo)); } else { throw Exception(); } } catch (e) { - return a.questionNo.toLowerCase().compareTo(b.questionNo.toLowerCase()); + return a.questionNo + .toLowerCase() + .compareTo(b.questionNo.toLowerCase()); } }); //正确 @@ -159,13 +181,17 @@ class Utils { stu.zgtUnrated = stu.zgtStu!.where((w) => w.state == 1).length; //未做 stu.zgtAnswerCount = stu.zgtStu!.where((w) => w.state != 0).length; - stu.isAllCorrect = stu.kgtOkCount! + stu.zgtOkCount! == kgt.length + zgt.length ? true : false; + stu.isAllCorrect = + stu.kgtOkCount! + stu.zgtOkCount! == kgt.length + zgt.length + ? true + : false; 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) { + if (w.templateId == que.templateId && + w.questionNo == que.questionNo) { w.answer = que.answer; w.questionPicture = que.questionPicture; } @@ -173,15 +199,26 @@ class Utils { 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)) { + 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; + 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(); + 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); @@ -214,28 +251,42 @@ class Utils { return num2.compareTo(num1); }); //全对 - dataCount.allCorrect = data.students.where((w) => w.isAllCorrect == true).length; - dataCount.allCorrectStudents = data.students.where((w) => w.isAllCorrect == true).toList(); + dataCount.allCorrect = + data.students.where((w) => w.isAllCorrect == true).length; + dataCount.allCorrectStudents = + data.students.where((w) => w.isAllCorrect == true).toList(); //优 - dataCount.levelOneCount = data.students.where((s) => s.okRate! >= 85).length; - dataCount.levelOneStudents = data.students.where((s) => s.okRate! >= 85).toList(); + dataCount.levelOneCount = + data.students.where((s) => s.okRate! >= 85).length; + dataCount.levelOneStudents = + data.students.where((s) => s.okRate! >= 85).toList(); //良 - dataCount.levelTwoCount = data.students.where((s) => s.okRate! < 85 && s.okRate! >= 55).length; - dataCount.levelTwoStudents = data.students.where((s) => s.okRate! < 85 && s.okRate! >= 55).toList(); + dataCount.levelTwoCount = + data.students.where((s) => s.okRate! < 85 && s.okRate! >= 55).length; + dataCount.levelTwoStudents = + data.students.where((s) => s.okRate! < 85 && s.okRate! >= 55).toList(); //中 - dataCount.levelThreeCount = data.students.where((s) => s.okRate! < 55 && s.okRate! >= 25).length; - dataCount.levelThreeStudents = data.students.where((s) => s.okRate! < 55 && s.okRate! >= 25).toList(); + dataCount.levelThreeCount = + data.students.where((s) => s.okRate! < 55 && s.okRate! >= 25).length; + dataCount.levelThreeStudents = + data.students.where((s) => s.okRate! < 55 && s.okRate! >= 25).toList(); //差 - dataCount.levelFourCount = data.students.where((s) => s.okRate! < 25).length; - dataCount.levelFourStudents = data.students.where((s) => s.okRate! < 25).toList(); + dataCount.levelFourCount = + data.students.where((s) => s.okRate! < 25).length; + dataCount.levelFourStudents = + data.students.where((s) => s.okRate! < 25).toList(); for (var que in data.questions) { - List ques = data.dtls.where((w) => w.templateId == que.templateId && w.questionNo == que.questionNo).toList(); + 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!); + que.answerRate = + Utils.calcRate(que.answerCount!, dataCount.studentCount!); int okCount = ques.where((w) => w.state == 3).length; que.okRate = Utils.calcRate(okCount, dataCount.studentCount!); que.priorityInfo = ques.where((w) { @@ -248,7 +299,9 @@ class Utils { }).toList(); que.correctRate = Utils.calcRate(okCount, que.answerCount!); que.answerNgStudents = ques.where((w) { - w.studentName = data.students.firstWhere((s) => s.studentId == w.studentId).studentName; + w.studentName = data.students + .firstWhere((s) => s.studentId == w.studentId) + .studentName; return w.state == 2; }).toList(); @@ -263,23 +316,74 @@ class Utils { int middleTime = 0; if (ques.length % 2 == 0) { int index = (ques.length / 2).ceil(); - middleTime = ((ques[index].useTime + ques[index - 1].useTime) / 2).ceil(); + middleTime = + ((ques[index].useTime + ques[index - 1].useTime) / 2).ceil(); } else { int index = ((ques.length + 1) / 2).ceil(); middleTime = ques[index - 1].useTime; } - var excellent = ques.where((w) => w.state == 3 && w.useTime <= middleTime).length; - var good = ques.where((w) => w.state == 3 && w.useTime > middleTime).length; - var middle = ques.where((w) => w.state != 3 && w.useTime <= middleTime).length; - var differ = ques.where((w) => w.state != 3 && w.useTime > middleTime).length; + var excellent = + ques.where((w) => w.state == 3 && w.useTime <= middleTime).length; + var good = + ques.where((w) => w.state == 3 && w.useTime > middleTime).length; + var middle = + ques.where((w) => w.state != 3 && w.useTime <= middleTime).length; + var differ = + ques.where((w) => w.state != 3 && w.useTime > middleTime).length; - que.overallTitles = [OverallTitles('优秀', excellent), OverallTitles('良好', good), OverallTitles('中', middle), OverallTitles('差', differ)]; + que.overallTitles = [ + OverallTitles('优秀', excellent), + OverallTitles('良好', good), + OverallTitles('中', middle), + OverallTitles('差', differ) + ]; + + Map optInfos = {}; + print('opt====${que.questionNo}'); + for (var d in ques + .where((w) => w.questionType == 1 && w.studentAnswer != null)) { + final key = d.studentAnswer!; + if (optInfos[key] != null) { + optInfos[key] = optInfos[key]! + 1; + } else { + optInfos[key] = 1; + } + } + List student = []; + optInfos.forEach((key, value) { + // optInfos[key] = Utils.calcRate(value, ques.length).round(); + List currentOptionStudents = data.students.where((s) => ques + .where( + (w) => w.studentAnswer == key && w.studentId == s.studentId) + .isNotEmpty) + .toList(); + //字母排序 + String upStr = key.toUpperCase(); + List chars = upStr.split('')..sort(); + String sortedStr = chars.join(); + + student.add(SelectionRate(sortedStr, Utils.calcRate(value, ques.length).round(),false, currentOptionStudents)); + }); + print('optitems=$optInfos'); + /* var ARate = Utils.calcRate( + ques.where((w) => w.studentAnswer == "A").length, ques.length);*/ + + que.options = student; } 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(); + 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 == 3).length; know.ttlCount = queDtls.length; know.okRate = Utils.calcRate(know.okCount!, know.ttlCount!); @@ -317,7 +421,8 @@ bool isPad([double mobilePhoneScale = 1.2]) { return ScreenUtil().scaleWidth > mobilePhoneScale; } -void toUpState(Function(void Function()) setState, VoidCallback fn, bool mounted) { +void toUpState( + Function(void Function()) setState, VoidCallback fn, bool mounted) { if (mounted) setState(fn); } diff --git a/making_school_asignment_app/lib/page/global_widget/show_student_list.dart b/making_school_asignment_app/lib/page/global_widget/show_student_list.dart index 7e995e3..84af488 100644 --- a/making_school_asignment_app/lib/page/global_widget/show_student_list.dart +++ b/making_school_asignment_app/lib/page/global_widget/show_student_list.dart @@ -31,7 +31,7 @@ class ShowStudentList extends StatelessWidget { title, size: 18.sp, fontWeight: FontWeight.bold, - color: Color.fromRGBO(60, 60, 60, 1), + color: const Color.fromRGBO(60, 60, 60, 1), ), ), Expanded( diff --git a/making_school_asignment_app/lib/page/home_page/children/job_report/job_report_view.dart b/making_school_asignment_app/lib/page/home_page/children/job_report/job_report_view.dart index cdf4c0f..00ccad4 100644 --- a/making_school_asignment_app/lib/page/home_page/children/job_report/job_report_view.dart +++ b/making_school_asignment_app/lib/page/home_page/children/job_report/job_report_view.dart @@ -86,7 +86,8 @@ class _JobReportPageState extends State { zgtOkRate: state.dataCount.zgtOkRate!.toStringAsFixed(0), kgtCorrectRate: state.dataCount.kgtCorrectRate!.toStringAsFixed(0), zgtCorrectRate: state.dataCount.zgtCorrectRate!.toStringAsFixed(0), - subject: state.subject), + subject: state.subject, + ), // 掌握知识点的情况 Container( margin: EdgeInsets.symmetric(horizontal: 10.r), diff --git a/making_school_asignment_app/lib/page/home_page/children/quick_data_check/widget/report_table.dart b/making_school_asignment_app/lib/page/home_page/children/quick_data_check/widget/report_table.dart index 0c74896..df7360e 100644 --- a/making_school_asignment_app/lib/page/home_page/children/quick_data_check/widget/report_table.dart +++ b/making_school_asignment_app/lib/page/home_page/children/quick_data_check/widget/report_table.dart @@ -4,13 +4,17 @@ import 'package:flutter/material.dart'; import 'package:flutter_echart/flutter_echart.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; +import 'package:get/get_rx/get_rx.dart'; import 'package:making_school_asignment_app/common/job/annotated_class.dart'; import 'package:making_school_asignment_app/common/job/homework_details.dart'; import 'package:making_school_asignment_app/common/utils/toast_utils.dart'; import 'package:making_school_asignment_app/common/utils/utils.dart'; import 'package:making_school_asignment_app/page/global_widget/MyEmptyWidget.dart'; import 'package:making_school_asignment_app/page/global_widget/imgDialog.dart'; +import 'package:making_school_asignment_app/page/global_widget/my_text.dart'; +import 'package:making_school_asignment_app/page/home_page/widget/progress_bar.dart'; import 'package:making_school_asignment_app/routes/app_pages.dart'; +import 'package:auto_size_text/auto_size_text.dart'; class ReportTable extends StatefulWidget { final List headList; @@ -56,7 +60,8 @@ class _ReportTableState extends State { builder: (BuildContext context) { return AlertDialog( contentPadding: EdgeInsets.all(20.r), - shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(15.r))), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.circular(15.r))), content: SizedBox( width: MediaQuery.of(context).size.width * 0.5, height: MediaQuery.of(context).size.height * 0.4, @@ -64,10 +69,14 @@ class _ReportTableState extends State { children: [ Text( '作答效率', - style: TextStyle(fontSize: 15.sp, color: const Color(0xFF3C3C3C), fontWeight: FontWeight.w500), + style: TextStyle( + fontSize: 15.sp, + color: const Color(0xFF3C3C3C), + fontWeight: FontWeight.w500), ), Padding( - padding: EdgeInsets.symmetric(vertical: 20.r, horizontal: 10.r), + padding: + EdgeInsets.symmetric(vertical: 20.r, horizontal: 10.r), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ @@ -112,7 +121,9 @@ class _ReportTableState extends State { // borderSide:BorderSide(color: const Color(0xFF273366),width: 0.5.r), // title: e.title + (Utils.doubleToStringAsFixed(e.count / widget.studentCount * 100) + '%'), title: e.title + e.count.toString(), - titleStyle: TextStyle(fontSize: 12.sp, color: Color(0xFFFFFFFF)), + titleStyle: TextStyle( + fontSize: 12.sp, + color: const Color(0xFFFFFFFF)), ); }), ), @@ -153,14 +164,20 @@ class _ReportTableState extends State { }); } - void showPeopleListDialog({required BuildContext context, required String title, required String questionNo, required List arr, List? dcList}) { + void showPeopleListDialog( + {required BuildContext context, + required String title, + required String questionNo, + required List arr, + List? dcList}) { showDialog( context: context, builder: (BuildContext context) { return AlertDialog( // insetPadding: EdgeInsets.symmetric(vertical: 20.r,horizontal: 20.r), contentPadding: EdgeInsets.all(20.r), - shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(15.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, @@ -170,7 +187,10 @@ class _ReportTableState extends State { Center( child: Text( title, - style: TextStyle(fontSize: 15.sp, color: const Color(0xFF3C3C3C), fontWeight: FontWeight.w500), + style: TextStyle( + fontSize: 15.sp, + color: const Color(0xFF3C3C3C), + fontWeight: FontWeight.w500), ), ), SizedBox( @@ -180,15 +200,21 @@ class _ReportTableState extends State { children: [ Text( widget.isZG == true ? '主观题' : '客观题', - style: TextStyle(fontSize: 14.sp, color: Theme.of(context).primaryColor), + style: TextStyle( + fontSize: 14.sp, + color: Theme.of(context).primaryColor), ), Text( '―', - style: TextStyle(fontSize: 14.sp, color: Theme.of(context).primaryColor), + style: TextStyle( + fontSize: 14.sp, + color: Theme.of(context).primaryColor), ), Text( '第$questionNo题', - style: TextStyle(fontSize: 14.sp, color: Theme.of(context).primaryColor), + style: TextStyle( + fontSize: 14.sp, + color: Theme.of(context).primaryColor), ), ], ), @@ -203,21 +229,27 @@ class _ReportTableState extends State { child: Center( child: Text( '未作答人', - style: TextStyle(fontSize: 12.sp, color: Color(0xFF6A6A6A)), + style: TextStyle( + fontSize: 12.sp, + color: Color(0xFF6A6A6A)), ))), Expanded( flex: 1, child: Center( child: Text( '答对人数', - style: TextStyle(fontSize: 12.sp, color: Color(0xFF6A6A6A)), + style: TextStyle( + fontSize: 12.sp, + color: Color(0xFF6A6A6A)), ))), Expanded( flex: 1, child: Center( child: Text( '答错人', - style: TextStyle(fontSize: 12.sp, color: Color(0xFF6A6A6A)), + style: TextStyle( + fontSize: 12.sp, + color: Color(0xFF6A6A6A)), ))), ], ) @@ -225,7 +257,8 @@ class _ReportTableState extends State { padding: EdgeInsets.only(left: 15.r), child: Text( title, - style: TextStyle(fontSize: 12.sp, color: Color(0xFF6A6A6A)), + style: TextStyle( + fontSize: 12.sp, color: Color(0xFF6A6A6A)), ), ), SizedBox( @@ -239,41 +272,60 @@ class _ReportTableState extends State { var item = arr[index]; return Container( padding: EdgeInsets.symmetric(vertical: 5.r), - color: index.isOdd ? Colors.white : Color(0xFFF0F0F0), + color: + index.isOdd ? Colors.white : Color(0xFFF0F0F0), child: Row( children: [ Expanded( flex: 1, child: InkWell( onTap: () { - goQuickCheckPersonalPath(item['noAnswerStudents'].studentId); + goQuickCheckPersonalPath( + item['noAnswerStudents'] + .studentId); }, child: Center( child: Text( - item['noAnswerStudents']?.studentName ?? '--', - style: TextStyle(fontSize: 12.sp, color: Color(0xFF323232)), + item['noAnswerStudents'] + ?.studentName ?? + '--', + style: TextStyle( + fontSize: 12.sp, + color: Color(0xFF323232)), )))), Expanded( flex: 1, child: InkWell( onTap: () { - goQuickCheckPersonalPath(item['answerOkStudents'].studentId); + goQuickCheckPersonalPath( + item['answerOkStudents'] + .studentId); }, child: Center( child: Text( - item['answerOkStudents']?.studentName ?? '--', - style: TextStyle(fontSize: 12.sp, color: Color(0xFF323232)), + item['answerOkStudents'] + ?.studentName ?? + '--', + style: TextStyle( + fontSize: 12.sp, + color: Color(0xFF323232)), )))), Expanded( flex: 1, child: InkWell( onTap: () { - goQuickCheckPersonalPath(item['answerNgStudents'].studentId); + goQuickCheckPersonalPath( + item['answerNgStudents'] + .studentId); }, child: Center( child: Text( - item['answerNgStudents']?.studentName ?? '--', - style: TextStyle(fontSize: 12.sp, color: Color(0xFF323232)), + item['answerNgStudents'] + ?.studentName ?? + '--', + style: TextStyle( + fontSize: 12.sp, + color: Color(0xFF323232)), )))), ], ), @@ -294,11 +346,16 @@ class _ReportTableState extends State { goQuickCheckPersonalPath(item.studentId); }, child: Container( - padding: EdgeInsets.symmetric(vertical: 5.r, horizontal: 15.r), - color: index.isOdd ? Colors.white : Color(0xFFF0F0F0), + padding: EdgeInsets.symmetric( + vertical: 5.r, horizontal: 15.r), + color: index.isOdd + ? Colors.white + : Color(0xFFF0F0F0), child: Text( item.studentName! ?? '--', - style: TextStyle(fontSize: 12.sp, color: Color(0xFF323232)), + style: TextStyle( + fontSize: 12.sp, + color: Color(0xFF323232)), ), ), ); @@ -316,36 +373,50 @@ class _ReportTableState extends State { void goQuickCheckPersonalPath(id) { if (id != null) { - Get.toNamed(Routes.studentPersonalPage, arguments: {'studentId': id, 'homeworkId': widget.jobId, 'subject': widget.subject}); + Get.toNamed(Routes.studentPersonalPage, arguments: { + 'studentId': id, + 'homeworkId': widget.jobId, + 'subject': widget.subject + }); } } - void zdHandle(BuildContext context, String title, String questionNo, List noAnswerStudents, List answerNgStudents, List answerOkStudents) { + void zdHandle(BuildContext context, String title, String questionNo, + List noAnswerStudents, List answerNgStudents, List answerOkStudents) { List list = []; // Questions student = Questions('','',-1,-1,'',-1,'','',[],-1,-1,[] as double?); - if (noAnswerStudents.length > answerNgStudents.length && noAnswerStudents.length > answerOkStudents.length) { + if (noAnswerStudents.length > answerNgStudents.length && + noAnswerStudents.length > answerOkStudents.length) { for (int i = 0; i < noAnswerStudents.length; i++) { var obj = { 'noAnswerStudents': noAnswerStudents[i], - 'answerNgStudents': answerNgStudents.length > i ? answerNgStudents[i] : null, - 'answerOkStudents': answerOkStudents.length > i ? answerOkStudents[i] : null + 'answerNgStudents': + answerNgStudents.length > i ? answerNgStudents[i] : null, + 'answerOkStudents': + answerOkStudents.length > i ? answerOkStudents[i] : null }; list.add(obj); } - } else if (answerNgStudents.length > noAnswerStudents.length && answerNgStudents.length > answerOkStudents.length) { + } else if (answerNgStudents.length > noAnswerStudents.length && + answerNgStudents.length > answerOkStudents.length) { for (int i = 0; i < answerNgStudents.length; i++) { var obj = { - 'noAnswerStudents': noAnswerStudents.length > i ? noAnswerStudents[i] : null, + 'noAnswerStudents': + noAnswerStudents.length > i ? noAnswerStudents[i] : null, 'answerNgStudents': answerNgStudents[i], - 'answerOkStudents': answerOkStudents.length > i ? answerOkStudents[i] : null + 'answerOkStudents': + answerOkStudents.length > i ? answerOkStudents[i] : null }; list.add(obj); } - } else if (answerOkStudents.length > noAnswerStudents.length && answerOkStudents.length > answerNgStudents.length) { + } else if (answerOkStudents.length > noAnswerStudents.length && + answerOkStudents.length > answerNgStudents.length) { for (int i = 0; i < answerOkStudents.length; i++) { var obj = { - 'noAnswerStudents': noAnswerStudents.length > i ? noAnswerStudents[i] : null, - 'answerNgStudents': answerNgStudents.length > i ? answerNgStudents[i] : null, + 'noAnswerStudents': + noAnswerStudents.length > i ? noAnswerStudents[i] : null, + 'answerNgStudents': + answerNgStudents.length > i ? answerNgStudents[i] : null, 'answerOkStudents': answerOkStudents[i] }; list.add(obj); @@ -353,19 +424,28 @@ class _ReportTableState extends State { } else { for (int i = 0; i < answerOkStudents.length; i++) { var obj = { - 'noAnswerStudents': noAnswerStudents.length > i ? noAnswerStudents[i] : null, - 'answerNgStudents': answerNgStudents.length > i ? answerNgStudents[i] : null, + 'noAnswerStudents': + noAnswerStudents.length > i ? noAnswerStudents[i] : null, + 'answerNgStudents': + answerNgStudents.length > i ? answerNgStudents[i] : null, 'answerOkStudents': answerOkStudents[i] }; list.add(obj); } } - showPeopleListDialog(context: context, title: title, questionNo: questionNo, arr: list, dcList: []); + showPeopleListDialog( + context: context, + title: title, + questionNo: questionNo, + arr: list, + dcList: []); } - void dcHandle(BuildContext context, String title, String questionNo, List arr) { - showPeopleListDialog(context: context, title: title, questionNo: questionNo, arr: arr); + void dcHandle( + BuildContext context, String title, String questionNo, List arr) { + showPeopleListDialog( + context: context, title: title, questionNo: questionNo, arr: arr); } DataRow _getRow(int index, [Color? color]) { @@ -378,18 +458,42 @@ class _ReportTableState extends State { DataCell(Center( child: Padding( padding: EdgeInsets.symmetric(horizontal: 5.r), - child: Text(item.questionNo.toString(), style: TextStyle(fontSize: 10.sp, color: const Color(0xFF525252))), - ), - )), - DataCell(Center( - child: Padding( - padding: EdgeInsets.symmetric(horizontal: 5.r), - child: Text('${item.answerRate.toStringAsFixed(0)}%', style: TextStyle(fontSize: 10.sp, color: const Color(0xFF525252))), + child: Text(item.questionNo.toString(), + style: + TextStyle(fontSize: 10.sp, color: const Color(0xFF525252))), ), )), DataCell(InkWell( onTap: () { - zdHandle(context, '作答人数', item.questionNo.toString(), item.noAnswerStudents, item.answerNgStudents, item.answerOkStudents); + if (widget.isZG == false) { + showSelectRate( + questionNo: item.questionNo.toString(), + options: item.options, + answer: item.answer, + ); + } + }, + child: Center( + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 5.r), + child: Text('${item.answerRate.toStringAsFixed(0)}%', + style: TextStyle( + fontSize: 10.sp, + color: widget.isZG == false + ? Theme.of(context).primaryColor + : const Color(0xFF525252))), + ), + ), + )), + DataCell(InkWell( + onTap: () { + zdHandle( + context, + '作答人数', + item.questionNo.toString(), + item.noAnswerStudents, + item.answerNgStudents, + item.answerOkStudents); }, child: Center( child: Padding( @@ -397,7 +501,10 @@ class _ReportTableState extends State { child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ - Text('${item.answerCount}/${widget.studentCount}', style: TextStyle(fontSize: 10.sp, color: Theme.of(context).primaryColor)), + Text('${item.answerCount}/${widget.studentCount}', + style: TextStyle( + fontSize: 10.sp, + color: Theme.of(context).primaryColor)), Image.asset( 'assets/images/green_right_icon.png', width: 12.r, @@ -411,13 +518,17 @@ class _ReportTableState extends State { DataCell(Center( child: Padding( padding: EdgeInsets.symmetric(horizontal: 5.r), - child: Text('${item.correctRate.toStringAsFixed(0)}%', style: TextStyle(fontSize: 10.sp, color: Color(0xFF525252))), + child: Text('${item.correctRate.toStringAsFixed(0)}%', + style: + TextStyle(fontSize: 10.sp, color: const Color(0xFF525252))), ), )), DataCell(Center( child: Padding( padding: EdgeInsets.symmetric(horizontal: 5.r), - child: Text('${item.okRate.toStringAsFixed(0)}%', style: TextStyle(fontSize: 10.sp, color: Color(0xFF525252))), + child: Text('${item.okRate.toStringAsFixed(0)}%', + style: + TextStyle(fontSize: 10.sp, color: const Color(0xFF525252))), ), )), DataCell(Center( @@ -429,20 +540,30 @@ class _ReportTableState extends State { if (item.questionPicture == null) { ToastUtils.showInfo('当前试题没有原题'); } else { - ImageDialog.showImgDialog(context, item.questionPicture); + ImageDialog.showImgDialog( + context, item.questionPicture); } }, child: Text('原题', - style: TextStyle(fontSize: 10.sp, color: widget.isZG == true ? const Color(0xFFFF8A00) : Theme.of(context).primaryColor)), + style: TextStyle( + fontSize: 10.sp, + color: widget.isZG == true + ? const Color(0xFFFF8A00) + : Theme.of(context).primaryColor)), ) : Text(item.answer, - style: TextStyle(fontSize: 10.sp, color: widget.isZG == true ? const Color(0xFFFF8A00) : Theme.of(context).primaryColor)), + style: TextStyle( + fontSize: 10.sp, + color: widget.isZG == true + ? const Color(0xFFFF8A00) + : Theme.of(context).primaryColor)), ), )), DataCell(InkWell( onTap: () { // List parts = item.priorityGeneral.split('人'); - dcHandle(context, '优先批阅答错人', item.questionNo.toString(), item.priorityInfo); + dcHandle(context, '优先批阅答错人', item.questionNo.toString(), + item.priorityInfo); }, child: Center( child: Padding( @@ -450,7 +571,10 @@ class _ReportTableState extends State { child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ - Text('${item.priorityInfo.length}人答错', style: TextStyle(fontSize: 10.sp, color: Theme.of(context).primaryColor)), + Text('${item.priorityInfo.length}人答错', + style: TextStyle( + fontSize: 10.sp, + color: Theme.of(context).primaryColor)), Image.asset( 'assets/images/green_right_icon.png', width: 12.r, @@ -471,16 +595,344 @@ class _ReportTableState extends State { showAnswerEfficiency(item.overallTitles); }, child: Text('查看', - style: TextStyle(fontSize: 10.sp, color: widget.isZG == true ? const Color(0xFFFF8A00) : Theme.of(context).primaryColor)), + style: TextStyle( + fontSize: 10.sp, + color: widget.isZG == true + ? const Color(0xFFFF8A00) + : Theme.of(context).primaryColor)), ) : Text(item.answer, - style: TextStyle(fontSize: 10.sp, color: widget.isZG == true ? const Color(0xFFFF8A00) : Theme.of(context).primaryColor)), + style: TextStyle( + fontSize: 10.sp, + color: widget.isZG == true + ? const Color(0xFFFF8A00) + : Theme.of(context).primaryColor)), ), )), ], ); } + void showSelectRate( + {required String questionNo, + required List options, + required String answer}) { + RxList students = RxList(); + students.value = options; + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + // insetPadding: EdgeInsets.symmetric(vertical: 20.r,horizontal: 20.r), + contentPadding: EdgeInsets.all(0.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( + children: [ + Container( + decoration: BoxDecoration( + color: Theme.of(context).primaryColor, + borderRadius: BorderRadius.only( + topLeft: Radius.circular(10.r), + topRight: Radius.circular(10.r), + )), + width: double.infinity, + child: Container( + alignment: Alignment.center, + padding: EdgeInsets.symmetric(vertical: 8.h), + child: Text( + '第$questionNo题', + style: + TextStyle(fontSize: 16.sp, color: Colors.white), + )), + ), + Expanded( + child: Padding( + padding: + EdgeInsets.symmetric(vertical: 5.h, horizontal: 10.w), + child: Column( + children: [ + SizedBox( + height: 10.h, + ), + Row( + children: [ + Text( + '标准答案:', + style: TextStyle( + fontSize: 12.sp, + color: const Color(0xFF000101)), + ), + SizedBox( + width: 5.w, + ), + Container( + width: 20.r, + height: 20.r, + alignment: Alignment.center, + decoration: BoxDecoration( + color: const Color(0xFF4BC793), + borderRadius: + BorderRadius.all(Radius.circular(10.r)), + ), + child: AutoSizeText( + answer, + style: TextStyle( + fontSize: 12.sp, color: Colors.white), + maxLines: 1, + minFontSize: 10, + )) + ], + ), + SizedBox( + height: 10.h, + ), + Row( + children: [ + Text('选项', + style: TextStyle( + fontSize: 12.sp, + color: const Color(0xFF000101), + )), + SizedBox( + width: 10.w, + ), + Text('选择率', + style: TextStyle( + fontSize: 12.sp, + color: const Color(0xFF000101), + )), + ], + ), + SizedBox( + height: 5.h, + ), + Obx(() { + return Expanded( + child: students.isNotEmpty + ? ListView.builder( + // shrinkWrap: true, + // physics: NeverScrollableScrollPhysics(), + itemCount: students.length, + itemBuilder: (context, index) { + SelectionRate item = students[index]; + + return Container( + margin: EdgeInsets.only(bottom: 5.h), + decoration: BoxDecoration( + color: const Color(0xFFFAFAFA), + borderRadius: BorderRadius.all( + Radius.circular(5.r)), + ), + child: Column( + children: [ + SizedBox( + height: 5.h, + ), + Row( + crossAxisAlignment: + CrossAxisAlignment.center, + children: [ + item.optionName == answer + ? Container( + width: 20.r, + height: 20.r, + margin: + EdgeInsets.only( + left: 4.r), + alignment: + Alignment.center, + decoration: + BoxDecoration( + color: const Color( + 0xFF4BC793), + borderRadius: + BorderRadius.all( + Radius.circular( + 10.r)), + ), + child: AutoSizeText( + item.optionName, + style: TextStyle( + fontSize: 12.sp, + color: Colors + .white), + maxLines: 1, + minFontSize: 10, + )) + : Padding( + padding: + EdgeInsets.only( + left: 8.r), + child: Text( + item.optionName, + style: TextStyle( + fontSize: 12.sp, + color: const Color( + 0xFF000101), + ), + ), + ), + SizedBox( + width: 10.w, + ), + Expanded( + child: ProgressBar( + color: Theme.of(context) + .primaryColor, + percent: item.rate / 100, + title: '', + padingEdg: + EdgeInsets.only( + left: 5.w, + right: 10.w), + fontSize: 10.sp, + lineHeight: 6.h, + marginEdg: + EdgeInsets.only( + top: 0.h), + ), + ), + SizedBox( + width: 15.w, + ), + InkWell( + onTap: () { + item.isCheck = + !item.isCheck; + students[index] = item; + }, + child: item.isCheck + ? const Icon( + Icons + .arrow_drop_down_rounded, + size: 30, + color: Color( + 0xFF000101), + ) + : const Icon( + Icons + .arrow_right_rounded, + size: 30, + color: Color( + 0xFF000101), + ), + ), + ], + ), + SizedBox( + height: 5.h, + ), + item.isCheck + ? Container( + width: double.infinity, + height: 120.h, + decoration: BoxDecoration( + color: const Color( + 0xFFF2F2F2), + borderRadius: + BorderRadius.only( + bottomLeft: + Radius.circular( + 5.r), + bottomRight: + Radius.circular( + 5.r), + )), + padding: + EdgeInsets.symmetric( + vertical: 5.h, + horizontal: 10.w), + child: Column( + crossAxisAlignment: + CrossAxisAlignment + .start, + children: [ + Text( + '选择的学生(${item.currentOptionStudents.length})', + style: TextStyle( + fontSize: 12.sp, + color: const Color( + 0xFF000101)), + ), + SizedBox( + height: 5.h, + ), + Expanded( + child: + SingleChildScrollView( + child: Wrap( + spacing: 6.r, + // 主轴(水平)方向间距 + runSpacing: 4.r, + // 纵轴(垂直)方向间距 + alignment: + WrapAlignment + .start, + //沿主轴方向居中 + children: item + .currentOptionStudents + .map((e) { + return InkWell( + onTap: () { + Get.toNamed( + Routes + .studentPersonalPage, + arguments: { + 'studentId': + e.studentId, + 'homeworkId': + widget.jobId, + 'subject': + widget.subject + }); + }, + child: + Container( + padding: EdgeInsets.symmetric( + vertical: 4 + .r, + horizontal: + 8.r), + color:const Color(0xFFF0ECFF), + child: quickText( + e + .studentName, + color: const Color( + 0xFF505E6E), + size: + 10.sp), + ), + ); + }).toList(), + ), + ), + ), + ], + ), + ) + : Container() + ], + ), + ); + }) + : const MyEmptyWidget(), + ); + }) + ], + ), + ), + ) + ], + ), + ), + ); + }); + } + @override Widget build(BuildContext context) { bool isPadFlag = Utils.isPad(); @@ -492,10 +944,14 @@ class _ReportTableState extends State { dataRowHeight: 40.r, bottomMargin: 0, border: const 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), + 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: const BoxDecoration(color: Color(0xFFE6E6E6)), fixedColumnsColor: const Color(0xFFE6E6E6), fixedCornerColor: Colors.grey[400], @@ -517,7 +973,9 @@ class _ReportTableState extends State { mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ - Text(item, style: TextStyle(fontSize: 10.sp, color: const Color(0xFF505767))), + Text(item, + style: TextStyle( + fontSize: 10.sp, color: const Color(0xFF505767))), SizedBox( width: 2.r, ), @@ -536,7 +994,10 @@ class _ReportTableState extends State { mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ - Text(item, style: TextStyle(fontSize: 10.sp, color: const Color(0xFF505767))), + Text(item, + style: TextStyle( + fontSize: 10.sp, + color: const Color(0xFF505767))), SizedBox( width: 2.r, ), @@ -551,7 +1012,10 @@ class _ReportTableState extends State { ], ) : Center( - child: Text(item, style: TextStyle(fontSize: 10.sp, color: const Color(0xFF505767))), + child: Text(item, + style: TextStyle( + fontSize: 10.sp, + color: const Color(0xFF505767))), ), // size: ColumnSize.S, fixedWidth: index == 0 @@ -559,11 +1023,13 @@ class _ReportTableState extends State { : widget.headList.length > 6 ? 80.r : isPadFlag - ? (MediaQuery.of(context).size.width - 8.r) / widget.headList.length + ? (MediaQuery.of(context).size.width - 8.r) / + widget.headList.length : 85.r, ); }), - rows: List.generate(widget.bodyList.length, (index) => _getRow(index, const Color(0xFFF5F5F5)))); + rows: List.generate(widget.bodyList.length, + (index) => _getRow(index, const Color(0xFFF5F5F5)))); } } @@ -581,6 +1047,9 @@ Widget mapIcon(Color bgColor) { Widget mapTxt(String title) { return Text( title, - style: TextStyle(fontSize: 12.sp, color: const Color(0xFF525252), fontWeight: FontWeight.w400), + style: TextStyle( + fontSize: 12.sp, + color: const Color(0xFF525252), + fontWeight: FontWeight.w400), ); } diff --git a/making_school_asignment_app/pubspec.yaml b/making_school_asignment_app/pubspec.yaml index 7fb8c92..a784833 100644 --- a/making_school_asignment_app/pubspec.yaml +++ b/making_school_asignment_app/pubspec.yaml @@ -98,6 +98,7 @@ dependencies: icons_launcher: ^2.1.7 app_settings: ^5.1.1 device_info_plus: ^11.1.0 + auto_size_text: ^3.0.0