From 624fb083df4faf4dd45c72246efd952bae08a55d Mon Sep 17 00:00:00 2001 From: machuanyu <840649825@qq.com> Date: Fri, 8 Mar 2024 10:24:25 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BD=9C=E4=B8=9A=E6=8A=A5=E5=91=8A=EF=BC=8C?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=BF=AB=E6=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../assets/images/job_data_right_icon.png | Bin 0 -> 326 bytes .../images/job_personal_correct_icon.png | Bin 0 -> 465 bytes .../assets/images/job_personal_error_icon.png | Bin 0 -> 290 bytes .../assets/images/job_report_class_icon.png | Bin 0 -> 1877 bytes marking_app/assets/images/sort_icon.png | Bin 0 -> 443 bytes .../lib/common/model/job/job_data_report.dart | 125 +++ .../common/model/job/job_report_model.dart | 92 +- .../pages/homework_correction/job_report.dart | 936 ++++++++++++------ .../quick_check_personal.dart | 156 +++ .../homework_correction/quick_data_check.dart | 324 ++++++ .../widget/quick_student_data_table.dart | 193 ++++ .../widget/report_table.dart | 148 +++ .../widget/student_kg_table.dart | 103 ++ .../widget/student_zg_table.dart | 157 +++ .../homework_correction/widget/top_count.dart | 266 +++++ marking_app/lib/routes/RouterManager.dart | 25 + .../lib/utils/request/rest_client.dart | 9 + 17 files changed, 2255 insertions(+), 279 deletions(-) create mode 100644 marking_app/assets/images/job_data_right_icon.png create mode 100644 marking_app/assets/images/job_personal_correct_icon.png create mode 100644 marking_app/assets/images/job_personal_error_icon.png create mode 100644 marking_app/assets/images/job_report_class_icon.png create mode 100644 marking_app/assets/images/sort_icon.png create mode 100644 marking_app/lib/common/model/job/job_data_report.dart create mode 100644 marking_app/lib/pages/homework_correction/quick_check_personal.dart create mode 100644 marking_app/lib/pages/homework_correction/quick_data_check.dart create mode 100644 marking_app/lib/pages/homework_correction/widget/quick_student_data_table.dart create mode 100644 marking_app/lib/pages/homework_correction/widget/report_table.dart create mode 100644 marking_app/lib/pages/homework_correction/widget/student_kg_table.dart create mode 100644 marking_app/lib/pages/homework_correction/widget/student_zg_table.dart create mode 100644 marking_app/lib/pages/homework_correction/widget/top_count.dart diff --git a/marking_app/assets/images/job_data_right_icon.png b/marking_app/assets/images/job_data_right_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..7c7edf40637fd4a2143b57e123a07988fc96d084 GIT binary patch literal 326 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc1|)ksWqE-VXMsm#F$05`DhM-r2B~}i3NjW4 zxjQkeJ16rJ$YDu$^mSxl*x1kgCy^D%zwPPb7*fG_b>c?BCIgYScm<1gvamzbwFdodq7Y_{_1Dc_3Pz#Dt(wV#|2zT21fYI578ms1z&$4j2{ zlK*un^x2&PY&s`Li7OVNe7fj5X&#bv!gvk~0IO^mLZBjgC(2rk-; znL?z&eq=&E5atgdB#ZEyVHhTWN~Kbj+wuE-zvtfF#Lo;BcJ}#jt`R02WT0x$iEA0* zBD@8WU)$Rs#P10eBruFL2aE-Jz0tMX!x^dqZNrof+Jz|N*naMacHPR=CQ>%%Ltzx19N?}Ba zHPm+>jRl2H$Pj$h=iRrqDfKZiyJD7EG|nZaa}hwYKZ`mmDi6$BP!?2Pn2n$qHD}?J z6Z~zcJTan;#}E79(kJjCaTty7nuQWDqMaM#sW%!#2dHs$J->9WhDBmhf!3jl!lVYR zqQGHu;zkh|DbN!2F}miQECK~ZU^3N<{u27$Qwu7U>Yw%lHFVGT#d8W~00000NkvXX Hu0mjf{6fCQ literal 0 HcmV?d00001 diff --git a/marking_app/assets/images/job_personal_error_icon.png b/marking_app/assets/images/job_personal_error_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..8c82f97bf20cef8ddc60b2b221fb25bc7020a2b7 GIT binary patch literal 290 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc1|)ksWqE-VXMsm#F$05`DhM-r2B~}i3NjW4 zxjQkeJ16rJ$YDu$^mSxl*x1kgCy^D%-|p$+7*fHw_0nnHRs{jp3z9v5Z**}dZ;{G9 z*2^8WQNG#cVQxsvPnCP34~vb2*&cNNNZhdRwN${d{^ZBM@3n31wC*qtnaag0A=7Sq z|NKNRzB$>2vF3tlKHaA`-F49X)uyT-el~HvLhG~*Iy0O#*KpVcuE<_sAhc(pB8%Ai z29@7_aSylFgo&9;D7)65TIzewLs8uOoRNl?0bf^8k5gdt)PO5VmS61K&-qH}go)g1 g*=Us3r2mQer}4|~#8kG`Krb+Oy85}Sb4q9e0OB-eD*ylh literal 0 HcmV?d00001 diff --git a/marking_app/assets/images/job_report_class_icon.png b/marking_app/assets/images/job_report_class_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..525b1d5b32aa3686a45b0b355057381d12f68ff0 GIT binary patch literal 1877 zcmV-b2demqP)Na)LO^tS~~XkU}^?a)WS$oPd}eyEx(icDO*y32-8zNPv_? zViDP|yQtspnik@P!4x6O>=v+|q2pJs{L z-GAF%Tf^^988)pQAJaYF_i9cwVL zl?vZEMDE0nSeV9*zsi6FrMy?r_jZ7OnntSb44s3Hzz%m^+~C)*Y2#$1&B5%%0CQne z=v}h;p!WI%eyufmzz5mk70yf`h;a4S6mN|g)F%3ICK&wZYr4Vv@AIsUDjii_CGIvQ=zdjnlPihckKt!? zu6*$AZ3!{4d!-Xr*(6>$E3j4!e)WpxLxm?5VT0Fs#w-1B{n~Kw*WdMMn8D|@5)O@G z4J@&Q3Xi}33EqYYjXij)5FLb17HQVbalXN`EAXHa%=xHCpM5%PM?V8cb+mZkjgS;xE-4Gi(wL~{INOzjMhUJd2j8ALT1$J`3 z#93i4js=jFf-U6lMLdG+UgCZd#IO|90|`3vd*S{nW2=5f^3M_zrK*gPjZv_4J^fAo zM>?OwYp`~BT=Z=7=g(>5=1qKK2eCkQZehz5-cVzN{8J~NX>-?IN1Y9%tfuk2r0!P^c211;wFm5UpaiL z-k{P1O6bA`_Ic=ip0^!+LO-lvYSs(1G>JDIFe)}Pqq>@S1=n(-&x>^4Dz<8;(>{{z za2mqpm{al+HY=atR7`0RTUQYtPBT~x zWJNesUV-sgB3HE7q8gNkMR{q_t?FP(AlVXJL1H|FN*IqtZ79|dweaya-*|3uG6`Wr z1`kAwd6F2sH)`2N7_K8R-W#B6#*|bqMyVmjVThn@t>gn!y9?t)JkJyutQ9^SGWs z0x}mREdV3aVXqCATkA_>lMbWFp7A)}WO_T5!_sauk53A{R37~^-Y{(h&t}j#=bZHK z)ZUx6mdIdTi%rKN_}sGGSlS-eH(r1edd7--BhY;shMmDvD5NTtsPoop3aK~usOSd_<>U4AiZanucgR0L-j>aUeB>8=H!&7dB9de9Y{hO-R5 za~tKc(MwLt*Vx{VyPk@XU1N=dy>8ID#dxWF9n-wDMyertjgj;i>y#VEa$_*|`Q@It z$P;MX^9>VE$L@jltR-Jfz$&@^+%3xb<|$gZ(#AS8rGQ^CxWY4@crVp6A-8_-%7FsV z9y@vNO$8Tu!DLe0dF_WpE9k-X`91AigV{v~eZ$7WZbi!f7*DWTdEw}{ki)oDWP^Hg z$@^$2v1-qm9G3Rg9p-U?7gD<_-^i{*p`FTO*W+=lR_D6@s;-jP8+NPEdb;Uz`Zs-s zs8f{3bdg#jHx9a8=ITSgg{3DzNeN(4hB`YM+WMB$q!$|;2SB|tqo^@O-rmAR5tg=I zhewRe8$)vN`&rIj`ryuP89j56p_D2*A729TVr7Ti6=Pm4sH&lvmFkmaTM#C;pMRmP z@tF4b;9tUqK~#7F?Ug}J zgFqC9|3|UlN{)ax(Hn3Cmvz@Ix}mGamAE6is5da4pn3x93E&90Vu*!tAkK(HYsWyN z3Eu+Vyf-g@-h(#-4E%RU8q-Veu)KUi#}G$q<;HOsP+F}`8DI>Kkay8BT$IEt<_NPE zq-OB+V(sw~4mu|C&07rohH1c^$vks6?J>|H%r5Rg<9ITE4Y3PB1<}EGA+x#osU2 studentDetails; + + JobDataReport(this.jobId,this.jobName,this.gradeName,this.className,this.validCount,this.noAnswerCount,this.kgValidRate,this.kgQuestionCount,this.zgValidRate,this.zgQuestionCount,this.studentDetails,); + + factory JobDataReport.fromJson(Map srcJson) => _$JobDataReportFromJson(srcJson); + + Map toJson() => _$JobDataReportToJson(this); + +} + + +@JsonSerializable() +class StudentDetails extends Object { + + @JsonKey(name: 'studentId') + int studentId; + + @JsonKey(name: 'studentName') + String studentName; + + @JsonKey(name: 'kgValidCount') + int kgValidCount; + + @JsonKey(name: 'kgValidRate') + int kgValidRate; + + @JsonKey(name: 'zgValidCount') + int zgValidCount; + + @JsonKey(name: 'zgValidRate') + int zgValidRate; + + @JsonKey(name: 'kgDetails') + List kgDetails; + + @JsonKey(name: 'zgDetails') + List zgDetails; + + StudentDetails(this.studentId,this.studentName,this.kgValidCount,this.kgValidRate,this.zgValidCount,this.zgValidRate,this.kgDetails,this.zgDetails,); + + factory StudentDetails.fromJson(Map srcJson) => _$StudentDetailsFromJson(srcJson); + + Map toJson() => _$StudentDetailsToJson(this); + +} + + +@JsonSerializable() +class KgDetails extends Object { + + @JsonKey(name: 'questionNo') + String questionNo; + + @JsonKey(name: 'questionId') + int questionId; + + @JsonKey(name: 'partName') + String partName; + + @JsonKey(name: 'state') + int state; + + @JsonKey(name: 'studentAnswer') + String? studentAnswer; + + @JsonKey(name: 'questionAnswer') + String? questionAnswer; + + @JsonKey(name: 'useTime') + int? useTime; + + @JsonKey(name: 'annotateAnswers') + String? annotateAnswers; + + @JsonKey(name: 'score') + double? score; + + KgDetails(this.questionNo,this.questionId,this.partName,this.state,this.studentAnswer,this.questionAnswer,this.useTime,this.annotateAnswers,this.score,); + + factory KgDetails.fromJson(Map srcJson) => _$KgDetailsFromJson(srcJson); + + Map toJson() => _$KgDetailsToJson(this); + +} + + diff --git a/marking_app/lib/common/model/job/job_report_model.dart b/marking_app/lib/common/model/job/job_report_model.dart index 2eb5a81..7682e09 100644 --- a/marking_app/lib/common/model/job/job_report_model.dart +++ b/marking_app/lib/common/model/job/job_report_model.dart @@ -51,6 +51,12 @@ class JobReportModel extends Object { @JsonKey(name: 'overallTitles') List overallTitles; + @JsonKey(name: 'kgReport') + KgReport kgReport; + + @JsonKey(name: 'zgReport') + ZgReport zgReport; + // 前端自定义 -- 全对学生 @JsonKey(name: 'allpairsStudents') List? allpairsStudents; @@ -82,7 +88,10 @@ class JobReportModel extends Object { this.knowledgeInfos, this.questionAnswerInfos, this.studentAnswerInfos, - this.overallTitles, [ + this.overallTitles, + this.kgReport, + this.zgReport, + [ this.allpairsStudents, this.passStudents, this.disqualifiedStudents, @@ -274,3 +283,84 @@ class OverallTitles extends Object { Map toJson() => _$OverallTitlesToJson(this); } + +@JsonSerializable() +class KgReport extends Object { + + @JsonKey(name: 'correctRate') + int correctRate; + + @JsonKey(name: 'details') + List
details; + + KgReport(this.correctRate,this.details,); + + factory KgReport.fromJson(Map srcJson) => _$KgReportFromJson(srcJson); + + Map toJson() => _$KgReportToJson(this); + +} + +@JsonSerializable() +class ZgReport extends Object { + + @JsonKey(name: 'correctRate') + int correctRate; + + @JsonKey(name: 'details') + List
details; + + ZgReport(this.correctRate,this.details,); + + factory ZgReport.fromJson(Map srcJson) => _$ZgReportFromJson(srcJson); + + Map toJson() => _$ZgReportToJson(this); + +} + +@JsonSerializable() +class Details extends Object { + + @JsonKey(name: 'questionNo') + String questionNo; + + @JsonKey(name: 'questionId') + int questionId; + + @JsonKey(name: 'partName') + String partName; + + @JsonKey(name: 'questionType') + int questionType; + + @JsonKey(name: 'validRate') + int validRate; + + @JsonKey(name: 'validCount') + String validCount; + + @JsonKey(name: 'validStudentNames') + List validStudentNames; + + @JsonKey(name: 'correctRate') + int correctRate; + + @JsonKey(name: 'questionAnswer') + String questionAnswer; + + @JsonKey(name: 'questionPicture') + String? questionPicture; + + @JsonKey(name: 'priorityGeneral') + String priorityGeneral; + + @JsonKey(name: 'priorityStudentNames') + List priorityStudentNames; + + Details(this.questionNo,this.questionId,this.partName,this.questionType,this.validRate,this.validCount,this.validStudentNames,this.correctRate,this.questionAnswer,this.questionPicture,this.priorityGeneral,this.priorityStudentNames,); + + factory Details.fromJson(Map srcJson) => _$DetailsFromJson(srcJson); + + Map toJson() => _$DetailsToJson(this); + +} \ No newline at end of file diff --git a/marking_app/lib/pages/homework_correction/job_report.dart b/marking_app/lib/pages/homework_correction/job_report.dart index 661c5b4..7eaab53 100644 --- a/marking_app/lib/pages/homework_correction/job_report.dart +++ b/marking_app/lib/pages/homework_correction/job_report.dart @@ -7,6 +7,9 @@ import 'package:marking_app/common/model/common/base_structure_result.dart'; import 'package:marking_app/common/model/job/job_report_join_class.dart'; import 'package:marking_app/common/model/job/job_report_knowledge_model.dart'; import 'package:marking_app/common/model/job/job_report_model.dart'; +import 'package:marking_app/pages/homework_correction/widget/report_table.dart'; +import 'package:marking_app/pages/homework_correction/widget/top_count.dart'; +import 'package:marking_app/routes/RouterManager.dart'; import 'package:marking_app/utils/index.dart'; import 'package:marking_app/utils/my_text.dart'; import 'package:marking_app/utils/request/rest_client.dart'; @@ -21,6 +24,7 @@ part 'job_report.g.dart'; class JobReport extends StatefulWidget { final int id; final String title; + const JobReport({required this.id, required this.title, super.key}); @override @@ -44,10 +48,14 @@ class _JobReportState extends State with CommonMixin { Future getInvolveClasses() async { try { RestClient _client = await getClient(); - BaseStructureResult> result = await _client.getJobReportJoinClasses(widget.id); + BaseStructureResult> result = + await _client.getJobReportJoinClasses(widget.id); if (result.success) { toUpState(setState, () { - involveClasses = [JobReportJoinClass(-1, '全部', -1, '全部', '全部', '全部', -1, -1, '-1'), ...(result.data ?? [])]; + involveClasses = [ + JobReportJoinClass(-1, '全部', -1, '全部', '全部', '全部', -1, -1, '-1'), + ...(result.data ?? []) + ]; }, mounted); } } catch (e) { @@ -60,7 +68,9 @@ class _JobReportState extends State with CommonMixin { RestClient _client = await getClient(); Map param = classData?.toJson() ?? {}; param['jobid'] = widget.id; - BaseStructureResult data = await _client.getJobReport(param); + print('widget.id=${widget.id}'); + BaseStructureResult data = + await _client.getJobReport(param); if (!data.success) { throw Exception(data.message ?? '获取报告失败'); } @@ -78,7 +88,8 @@ class _JobReportState extends State with CommonMixin { RestClient _client = await getClient(); BaseStructureResult> datas = await _client.getDetailKnowledge(widget.id, knowledge.knowledgeId); - if (!datas.success) return ToastUtils.showInfo(datas.message ?? '获取知识点失败'); + if (!datas.success) + return ToastUtils.showInfo(datas.message ?? '获取知识点失败'); knowledge.details = datas.data; } @@ -100,7 +111,9 @@ class _JobReportState extends State with CommonMixin { mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.end, children: [ - quickText(knowledge.knowledgeName, color: Theme.of(context1).primaryColor, size: 16.sp), + quickText(knowledge.knowledgeName, + color: Theme.of(context1).primaryColor, + size: 16.sp), quickText( '的掌握情况', color: Color.fromRGBO(60, 60, 60, 1), @@ -110,102 +123,157 @@ class _JobReportState extends State with CommonMixin { ], )), Expanded( - child: ListView(padding: EdgeInsets.symmetric(horizontal: 12.w), children: [ - DataTable( - sortAscending: false, - columns: [ - DataColumn( - label: quickText('班级', - color: Color.fromRGBO(114, 114, 114, 1), size: 14.sp, fontWeight: FontWeight.bold), - ), - DataColumn( - label: quickText('掌握度', - color: Color.fromRGBO(114, 114, 114, 1), size: 14.sp, fontWeight: FontWeight.bold), - ), - DataColumn( - label: quickText('人数', - color: Color.fromRGBO(114, 114, 114, 1), size: 14.sp, fontWeight: FontWeight.bold), - ), - DataColumn( - label: quickText('操作', - color: Color.fromRGBO(114, 114, 114, 1), size: 14.sp, fontWeight: FontWeight.bold), - ), - ], - rows: [ - ...knowledge.details?.map((e) { - return DataRow(cells: [ - DataCell(quickText(e.className, color: Color.fromRGBO(61, 61, 61, 1))), - DataCell(quickText(e.rate > 0 ? doubleToStringAsFixed(e.rate) + '%' : 0, - color: Color.fromRGBO(61, 61, 61, 1))), - DataCell(quickText(e.ratio, color: Color.fromRGBO(61, 61, 61, 1))), - DataCell(quickText('详情', color: Color.fromRGBO(239, 135, 20, 1)), onTap: () { - showDialog( - context: context1, - builder: (BuildContext context2) { - return Container( - margin: EdgeInsets.symmetric(vertical: 150.h, horizontal: 24.w), - padding: EdgeInsets.symmetric(vertical: 15.h), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(18.sp), - ), - child: Column( - children: [ - Container( - child: quickText( - '${e.className}的掌握情况', - color: Color.fromRGBO(239, 135, 20, 1), - size: 16.sp, - maxLines: 2, - fontWeight: FontWeight.bold, - )), - SizedBox(height: 20.h), - Expanded( - child: - ListView(padding: EdgeInsets.symmetric(horizontal: 12.w), children: [ - DataTable( - sortAscending: false, - columns: [ - DataColumn( - label: quickText('学生名字', - color: Color.fromRGBO(114, 114, 114, 1), - size: 14.sp, - fontWeight: FontWeight.bold), - ), - DataColumn( - label: quickText('掌握度', - color: Color.fromRGBO(114, 114, 114, 1), - size: 14.sp, - fontWeight: FontWeight.bold), - ), - ], - rows: [ - ...e.studentReports.map((e) { - return DataRow( - cells: [ - DataCell(quickText(e.studentName)), - DataCell(e.pass - ? Icon(Icons.check_outlined, color: Colors.green) - : Icon(Icons.close_outlined, color: Colors.red)), - ], - ); - }).toList() - ], - ), - ]), - ) - ], - ), + child: ListView( + padding: EdgeInsets.symmetric(horizontal: 12.w), + children: [ + DataTable( + sortAscending: false, + columns: [ + DataColumn( + label: quickText('班级', + color: Color.fromRGBO(114, 114, 114, 1), + size: 14.sp, + fontWeight: FontWeight.bold), + ), + DataColumn( + label: quickText('掌握度', + color: Color.fromRGBO(114, 114, 114, 1), + size: 14.sp, + fontWeight: FontWeight.bold), + ), + DataColumn( + label: quickText('人数', + color: Color.fromRGBO(114, 114, 114, 1), + size: 14.sp, + fontWeight: FontWeight.bold), + ), + DataColumn( + label: quickText('操作', + color: Color.fromRGBO(114, 114, 114, 1), + size: 14.sp, + fontWeight: FontWeight.bold), + ), + ], + rows: [ + ...knowledge.details?.map((e) { + return DataRow(cells: [ + DataCell(quickText(e.className, + color: Color.fromRGBO(61, 61, 61, 1))), + DataCell(quickText( + e.rate > 0 + ? doubleToStringAsFixed(e.rate) + + '%' + : 0, + color: Color.fromRGBO(61, 61, 61, 1))), + DataCell(quickText(e.ratio, + color: Color.fromRGBO(61, 61, 61, 1))), + DataCell( + quickText('详情', + color: Color.fromRGBO( + 239, 135, 20, 1)), onTap: () { + showDialog( + context: context1, + builder: (BuildContext context2) { + return Container( + margin: EdgeInsets.symmetric( + vertical: 150.h, + horizontal: 24.w), + padding: EdgeInsets.symmetric( + vertical: 15.h), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: + BorderRadius.circular(18.sp), + ), + child: Column( + children: [ + Container( + child: quickText( + '${e.className}的掌握情况', + color: Color.fromRGBO( + 239, 135, 20, 1), + size: 16.sp, + maxLines: 2, + fontWeight: FontWeight.bold, + )), + SizedBox(height: 20.h), + Expanded( + child: ListView( + padding: + EdgeInsets.symmetric( + horizontal: 12.w), + children: [ + DataTable( + sortAscending: false, + columns: [ + DataColumn( + label: quickText( + '学生名字', + color: Color + .fromRGBO( + 114, + 114, + 114, + 1), + size: 14.sp, + fontWeight: + FontWeight + .bold), + ), + DataColumn( + label: quickText( + '掌握度', + color: Color + .fromRGBO( + 114, + 114, + 114, + 1), + size: 14.sp, + fontWeight: + FontWeight + .bold), + ), + ], + rows: [ + ...e.studentReports + .map((e) { + return DataRow( + cells: [ + DataCell( + quickText( + e.studentName)), + DataCell(e + .pass + ? Icon( + Icons + .check_outlined, + color: Colors + .green) + : Icon( + Icons + .close_outlined, + color: + Colors.red)), + ], + ); + }).toList() + ], + ), + ]), + ) + ], + ), + ); + }, ); - }, - ); - }), - ]); - }).toList() ?? - [], - ], - ), - ]), + }), + ]); + }).toList() ?? + [], + ], + ), + ]), ) ], ), @@ -224,12 +292,17 @@ class _JobReportState extends State with CommonMixin { backgroundColor: Color.fromRGBO(245, 245, 245, 1), appBar: AppBar( backgroundColor: Colors.white, - title: quickText(widget.title, size: 16.sp, color: Color.fromRGBO(51, 51, 51, 1)), + title: Center( + child: quickText( + widget.title + '作业报告', + size: 16.sp, + color: Color.fromRGBO(51, 51, 51, 1), + )), leading: IconButton( icon: Icon(Icons.arrow_back_ios, color: Colors.black), onPressed: () => Navigator.of(context).pop(), ), - actions: [ + /*actions: [ // 下拉框 $DropdownSelection(involveClasses, classData, call: (JobReportJoinClass _classData) { classData = _classData; @@ -237,9 +310,10 @@ class _JobReportState extends State with CommonMixin { _future = getReport(); toUpState(setState, () {}, mounted); }), - ], + ],*/ ), - body: MyFutureBuilder.buildFutureBuilderOfSingleInstance(context, _future, (data) { + body: MyFutureBuilder.buildFutureBuilderOfSingleInstance( + context, _future, (data) { if (data == null) return Container( alignment: Alignment.center, @@ -252,10 +326,107 @@ class _JobReportState extends State with CommonMixin { ); return ListView( - padding: EdgeInsets.symmetric(horizontal: 10.w), + padding: EdgeInsets.symmetric(horizontal: 0.w), children: [ - // 顶部图形数据 - $TopGraphic(data), + // 下拉框 + Container( + padding: EdgeInsets.symmetric(vertical: 10.h, horizontal: 10.w), + decoration: BoxDecoration( + color: Colors.white, + ), + child: Row( + children: [ + $DropdownSelection(involveClasses, classData, + call: (JobReportJoinClass _classData) { + classData = _classData; + if (_classData.gradeId == -1) classData = null; + _future = getReport(); + toUpState(setState, () {}, mounted); + }), + // Expanded(child: Text('')), + ], + ), + ), + //完成率、正确率 + TopCount(data), + InkWell( + onTap: (){ + RouterManager.router.navigateTo( + context, + RouterManager.quickDataCheckPath + + '?jobId=${1}&className=', + transition: getTransition(), + ); + }, + child: Text('数据快查'), + ), + //客观题 + Container( + padding: EdgeInsets.symmetric(vertical: 10.r, horizontal: 10.r), + margin: EdgeInsets.symmetric(vertical: 10.r, horizontal: 10.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.w500),), + SizedBox(width: 10.r,), + Text('${data.kgReport.correctRate}%',style: TextStyle(fontSize: 14.sp,color: Color(0xFF6888FD),fontWeight: FontWeight.w500),), + ], + ), + SizedBox(height: 10.r,), + SizedBox( + height: data.kgReport.details.length>10?300.r:data.kgReport.details.length * 50.r + 20.r, + child: ReportTable( + headList: ['题', '作答率','作答人数', '正确率', '标准答案', '优先批阅概况'], + bodyList: data.kgReport.details, + fixedCols: 1, + fixedRows: 1, + ), + ) + ], + ), + ), + //主观题 + Container( + padding: EdgeInsets.symmetric(vertical: 10.r, horizontal: 10.r), + margin: EdgeInsets.symmetric(vertical: 10.r, horizontal: 10.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.w500),), + SizedBox(width: 10.r,), + Text('${data.zgReport.correctRate}%',style: TextStyle(fontSize: 14.sp,color: Color(0xFF6888FD),fontWeight: FontWeight.w500),), + ], + ), + SizedBox(height: 10.r,), + SizedBox( + height: data.zgReport.details.length>10?300.r:data.zgReport.details.length * 50.r + 20.r, + child: ReportTable( + headList: ['题', '作答率','作答人数', '正确率', '查看原题', '优先批阅概况'], + bodyList: data.zgReport.details, + fixedCols: 1, + fixedRows: 1, + isKG:true, + ), + ) + ], + ), + ), + // 顶部图形数据 + /* $TopGraphic(data),*/ // 掌握知识点的情况 $MasterKnowledgePoint(data.knowledgeInfos, detailKnowledgeCall), // 掌握知识点的情况 @@ -273,22 +444,37 @@ class _JobReportState extends State with CommonMixin { /// 下拉选择框 @swidget -Widget $dropdownSelection(List? involveClasses, JobReportJoinClass? classData, +Widget $dropdownSelection( + List? involveClasses, JobReportJoinClass? classData, {required Function(JobReportJoinClass) call}) { - if (involveClasses == null) return Container(child: quickText('点击重试')); // 点击重试 - return DropdownButton( - value: classData?.uniqueId ?? '-1', - style: TextStyle(color: Color.fromRGBO(89, 89, 89, 1), fontSize: 12.sp), - items: involveClasses.map((e) { - return DropdownMenuItem( - value: e.uniqueId!, - child: quickText(e.graduationYear + e.className, size: 12.sp, color: Colors.black), - ); - }).toList(), - onChanged: (String? value) { - if (value == null) return; - call(involveClasses.firstWhere((element) => element.uniqueId == value)); - }, + if (involveClasses == null) + return Container(child: quickText('点击重试')); // 点击重试 + return Container( + // width: 200.r, + padding: EdgeInsets.symmetric(horizontal: 10.r), + decoration: BoxDecoration( + color: Color(0xFFF5F5F5), + borderRadius: BorderRadius.vertical( + top: Radius.elliptical(10, 10), + bottom: Radius.elliptical(10, 10), + )), + child: DropdownButton( + value: classData?.uniqueId ?? '-1', + style: TextStyle(color: Color.fromRGBO(89, 89, 89, 1), fontSize: 12.sp), + underline: Container(), + // isExpanded:true, + items: involveClasses.map((e) { + return DropdownMenuItem( + value: e.uniqueId!, + child: quickText(e.graduationYear + e.className, + size: 12.sp, color: Colors.black), + ); + }).toList(), + onChanged: (String? value) { + if (value == null) return; + call(involveClasses.firstWhere((element) => element.uniqueId == value)); + }, + ), ); } @@ -333,42 +519,58 @@ Widget $topGraphic(BuildContext context, JobReportModel data) { ), child: Column( children: [ - Container(child: quickText('$title学生', color: Color.fromRGBO(60, 60, 60, 1), size: 15.sp)), + Container( + child: quickText('$title学生', + color: Color.fromRGBO(60, 60, 60, 1), size: 15.sp)), Expanded( - child: ListView(padding: EdgeInsets.symmetric(horizontal: 12.w), children: [ - DataTable( - sortAscending: false, - columns: [ - DataColumn( - label: quickText('姓名', - color: Color.fromRGBO(114, 114, 114, 1), size: 14.sp, fontWeight: FontWeight.bold), + child: ListView( + padding: EdgeInsets.symmetric(horizontal: 12.w), + children: [ + DataTable( + sortAscending: false, + columns: [ + DataColumn( + label: quickText('姓名', + color: Color.fromRGBO(114, 114, 114, 1), + size: 14.sp, + fontWeight: FontWeight.bold), + ), + DataColumn( + label: quickText('正确率', + color: Color.fromRGBO(114, 114, 114, 1), + size: 14.sp, + fontWeight: FontWeight.bold), + ), + DataColumn( + label: quickText('未答题数', + color: Color.fromRGBO(114, 114, 114, 1), + size: 14.sp, + fontWeight: FontWeight.bold), + ), + DataColumn( + label: quickText('用时(秒)', + color: Color.fromRGBO(114, 114, 114, 1), + size: 14.sp, + fontWeight: FontWeight.bold), + ), + ], + rows: [ + ...students.map((e) { + return DataRow(cells: [ + DataCell(quickText(e.studentName, + color: Color.fromRGBO(61, 61, 61, 1))), + DataCell(quickText( + doubleToStringAsFixed(e.correctRate) + '%', + color: Color.fromRGBO(61, 61, 61, 1))), + DataCell(quickText(e.noAnswerCount, + color: Color.fromRGBO(61, 61, 61, 1))), + DataCell(quickText(e.useTime, + color: Color.fromRGBO(61, 61, 61, 1))), + ]); + }).toList(), + ], ), - DataColumn( - label: quickText('正确率', - color: Color.fromRGBO(114, 114, 114, 1), size: 14.sp, fontWeight: FontWeight.bold), - ), - DataColumn( - label: quickText('未答题数', - color: Color.fromRGBO(114, 114, 114, 1), size: 14.sp, fontWeight: FontWeight.bold), - ), - DataColumn( - label: quickText('用时(秒)', - color: Color.fromRGBO(114, 114, 114, 1), size: 14.sp, fontWeight: FontWeight.bold), - ), - ], - rows: [ - ...students.map((e) { - return DataRow(cells: [ - DataCell(quickText(e.studentName, color: Color.fromRGBO(61, 61, 61, 1))), - DataCell(quickText(doubleToStringAsFixed(e.correctRate) + '%', - color: Color.fromRGBO(61, 61, 61, 1))), - DataCell(quickText(e.noAnswerCount, color: Color.fromRGBO(61, 61, 61, 1))), - DataCell(quickText(e.useTime, color: Color.fromRGBO(61, 61, 61, 1))), - ]); - }).toList(), - ], - ), - ]), + ]), ) ], ), @@ -380,7 +582,8 @@ Widget $topGraphic(BuildContext context, JobReportModel data) { return Container( margin: EdgeInsets.only(top: 16.h, bottom: 10.h), padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 14.h), - decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(16.r)), + decoration: BoxDecoration( + color: Colors.white, borderRadius: BorderRadius.circular(16.r)), child: Column( mainAxisSize: MainAxisSize.min, children: [ @@ -430,12 +633,16 @@ Widget $topGraphic(BuildContext context, JobReportModel data) { ), ), alignment: Alignment.center, - child: quickText(data.scoreTitle, color: Colors.white, size: 32.sp, fontWeight: FontWeight.bold), + child: quickText(data.scoreTitle, + color: Colors.white, + size: 32.sp, + fontWeight: FontWeight.bold), ), ), ), ), - Image.asset("assets/images/job_report_scale.png", width: 230.r, fit: BoxFit.fill), + Image.asset("assets/images/job_report_scale.png", + width: 230.r, fit: BoxFit.fill), ], ), @@ -456,8 +663,10 @@ Widget $topGraphic(BuildContext context, JobReportModel data) { children: [ Expanded( flex: 2, - child: - quickText('${data.validCount}份', color: Colors.white, size: 10.sp, fontWeight: FontWeight.bold), + child: quickText('${data.validCount}份', + color: Colors.white, + size: 10.sp, + fontWeight: FontWeight.bold), ), SizedBox(width: 1.2.w), Expanded( @@ -471,8 +680,11 @@ Widget $topGraphic(BuildContext context, JobReportModel data) { children: [ Expanded( flex: 2, - child: quickText('${doubleToStringAsFixed(data.correctRate)}%', - color: Colors.white, size: 10.sp, fontWeight: FontWeight.bold)), + child: quickText( + '${doubleToStringAsFixed(data.correctRate)}%', + color: Colors.white, + size: 10.sp, + fontWeight: FontWeight.bold)), Expanded( flex: 5, child: Container( @@ -483,8 +695,11 @@ Widget $topGraphic(BuildContext context, JobReportModel data) { shape: BoxShape.circle, // 设置为圆形 color: Color.fromRGBO(254, 151, 40, 1), ), - child: quickText('${doubleToStringAsFixed(data.finishRate)}%', - color: Colors.white, size: 14.sp, fontWeight: FontWeight.bold), + child: quickText( + '${doubleToStringAsFixed(data.finishRate)}%', + color: Colors.white, + size: 14.sp, + fontWeight: FontWeight.bold), ), ), ], @@ -512,10 +727,13 @@ Widget $topGraphic(BuildContext context, JobReportModel data) { ), ), SizedBox(width: 5.w), - quickText('作业完成率', color: Color.fromRGBO(114, 114, 114, 1), size: 12.sp), + quickText('作业完成率', + color: Color.fromRGBO(114, 114, 114, 1), size: 12.sp), SizedBox(width: 4.w), quickText('${doubleToStringAsFixed(data.finishRate)}%', - color: Color.fromRGBO(72, 72, 72, 1), size: 13.sp, fontWeight: FontWeight.bold), + color: Color.fromRGBO(72, 72, 72, 1), + size: 13.sp, + fontWeight: FontWeight.bold), ], ), SizedBox(height: 14.h), @@ -531,10 +749,13 @@ Widget $topGraphic(BuildContext context, JobReportModel data) { ), ), SizedBox(width: 5.w), - quickText('作业正确率', color: Color.fromRGBO(114, 114, 114, 1), size: 12.sp), + quickText('作业正确率', + color: Color.fromRGBO(114, 114, 114, 1), size: 12.sp), SizedBox(width: 4.w), quickText('${doubleToStringAsFixed(data.correctRate)}%', - color: Color.fromRGBO(72, 72, 72, 1), size: 13.sp, fontWeight: FontWeight.bold), + color: Color.fromRGBO(72, 72, 72, 1), + size: 13.sp, + fontWeight: FontWeight.bold), ], ), SizedBox(height: 14.h), @@ -550,10 +771,13 @@ Widget $topGraphic(BuildContext context, JobReportModel data) { ), ), SizedBox(width: 5.w), - quickText('作业有效份数', color: Color.fromRGBO(114, 114, 114, 1), size: 12.sp), + quickText('作业有效份数', + color: Color.fromRGBO(114, 114, 114, 1), size: 12.sp), SizedBox(width: 4.w), quickText('${data.validCount}份', - color: Color.fromRGBO(72, 72, 72, 1), size: 13.sp, fontWeight: FontWeight.bold), + color: Color.fromRGBO(72, 72, 72, 1), + size: 13.sp, + fontWeight: FontWeight.bold), ], ), ], @@ -582,11 +806,16 @@ Widget $topGraphic(BuildContext context, JobReportModel data) { color: Color.fromRGBO(241, 241, 241, 1), ), child: FlutterWaveLoading( - width: 140.w, //宽 - height: 170.h, //高 - isOval: false, // 是否椭圆裁切 - progress: data.allCorrect / data.studentCount, // 进度 - waveHeight: 8, //波浪高 + width: 140.w, + //宽 + height: 170.h, + //高 + isOval: false, + // 是否椭圆裁切 + progress: data.allCorrect / data.studentCount, + // 进度 + waveHeight: 8, + //波浪高 milliseconds: 5000, color: Color.fromRGBO(0, 179, 134, 1), //颜色 ), @@ -610,21 +839,30 @@ Widget $topGraphic(BuildContext context, JobReportModel data) { Column( mainAxisSize: MainAxisSize.min, children: [ - quickText('人', size: 18.sp, color: Color.fromRGBO(122, 122, 122, 1)), + quickText('人', + size: 18.sp, + color: + Color.fromRGBO(122, 122, 122, 1)), SizedBox(height: 4.h) ], ) ], ), - quickText('全对', color: Color.fromRGBO(164, 164, 164, 1), size: 16.sp), + quickText('全对', + color: Color.fromRGBO(164, 164, 164, 1), + size: 16.sp), ], )), Row( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.end, children: [ - quickText(doubleToStringAsFixed(data.allCorrect / data.studentCount * 100), - size: 34.sp, color: Colors.white, fontWeight: FontWeight.bold), + quickText( + doubleToStringAsFixed( + data.allCorrect / data.studentCount * 100), + size: 34.sp, + color: Colors.white, + fontWeight: FontWeight.bold), SizedBox(width: 1.5.w), quickText('%', size: 22.sp, color: Colors.white) ], @@ -640,14 +878,18 @@ Widget $topGraphic(BuildContext context, JobReportModel data) { padding: EdgeInsets.symmetric(vertical: 4.h), decoration: BoxDecoration( borderRadius: BorderRadius.circular(77.r), - border: Border.all(color: Color.fromRGBO(188, 188, 188, 1)), + border: + Border.all(color: Color.fromRGBO(188, 188, 188, 1)), ), child: Row( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children: [ - quickText('查看', size: 11.sp, color: Color.fromRGBO(118, 118, 118, 1)), - Icon(Icons.arrow_forward_ios, size: 11.sp, color: Color.fromRGBO(95, 95, 95, 1)) + quickText('查看', + size: 11.sp, + color: Color.fromRGBO(118, 118, 118, 1)), + Icon(Icons.arrow_forward_ios, + size: 11.sp, color: Color.fromRGBO(95, 95, 95, 1)) ], ), ), @@ -670,11 +912,16 @@ Widget $topGraphic(BuildContext context, JobReportModel data) { color: Color.fromRGBO(241, 241, 241, 1), ), child: FlutterWaveLoading( - width: 140.w, //宽 - height: 170.h, //高 - isOval: false, // 是否椭圆裁切 - progress: data.passCount / data.studentCount, // 进度 - waveHeight: 8, //波浪高 + width: 140.w, + //宽 + height: 170.h, + //高 + isOval: false, + // 是否椭圆裁切 + progress: data.passCount / data.studentCount, + // 进度 + waveHeight: 8, + //波浪高 milliseconds: 8000, color: Color.fromRGBO(255, 134, 0, 0.84), //颜色 ), @@ -698,21 +945,30 @@ Widget $topGraphic(BuildContext context, JobReportModel data) { Column( mainAxisSize: MainAxisSize.min, children: [ - quickText('人', size: 18.sp, color: Color.fromRGBO(122, 122, 122, 1)), + quickText('人', + size: 18.sp, + color: + Color.fromRGBO(122, 122, 122, 1)), SizedBox(height: 4.h) ], ) ], ), - quickText('及格', color: Color.fromRGBO(164, 164, 164, 1), size: 16.sp), + quickText('及格', + color: Color.fromRGBO(164, 164, 164, 1), + size: 16.sp), ], )), Row( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.end, children: [ - quickText(doubleToStringAsFixed(data.passCount / data.studentCount * 100), - size: 34.sp, color: Colors.white, fontWeight: FontWeight.bold), + quickText( + doubleToStringAsFixed( + data.passCount / data.studentCount * 100), + size: 34.sp, + color: Colors.white, + fontWeight: FontWeight.bold), SizedBox(width: 1.5.w), quickText('%', size: 22.sp, color: Colors.white) ], @@ -728,14 +984,18 @@ Widget $topGraphic(BuildContext context, JobReportModel data) { padding: EdgeInsets.symmetric(vertical: 4.h), decoration: BoxDecoration( borderRadius: BorderRadius.circular(77.r), - border: Border.all(color: Color.fromRGBO(188, 188, 188, 1)), + border: + Border.all(color: Color.fromRGBO(188, 188, 188, 1)), ), child: Row( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children: [ - quickText('查看', size: 11.sp, color: Color.fromRGBO(118, 118, 118, 1)), - Icon(Icons.arrow_forward_ios, size: 11.sp, color: Color.fromRGBO(95, 95, 95, 1)) + quickText('查看', + size: 11.sp, + color: Color.fromRGBO(118, 118, 118, 1)), + Icon(Icons.arrow_forward_ios, + size: 11.sp, color: Color.fromRGBO(95, 95, 95, 1)) ], ), ), @@ -758,11 +1018,16 @@ Widget $topGraphic(BuildContext context, JobReportModel data) { color: Color.fromRGBO(241, 241, 241, 1), ), child: FlutterWaveLoading( - width: 140.w, //宽 - height: 170.h, //高 - isOval: false, // 是否椭圆裁切 - progress: data.failCount / data.studentCount, // 进度 - waveHeight: 8, //波浪高 + width: 140.w, + //宽 + height: 170.h, + //高 + isOval: false, + // 是否椭圆裁切 + progress: data.failCount / data.studentCount, + // 进度 + waveHeight: 8, + //波浪高 milliseconds: 7000, color: Color.fromRGBO(255, 106, 106, 1), //颜色 ), @@ -786,21 +1051,30 @@ Widget $topGraphic(BuildContext context, JobReportModel data) { Column( mainAxisSize: MainAxisSize.min, children: [ - quickText('人', size: 18.sp, color: Color.fromRGBO(122, 122, 122, 1)), + quickText('人', + size: 18.sp, + color: + Color.fromRGBO(122, 122, 122, 1)), SizedBox(height: 4.h) ], ) ], ), - quickText('不及格', color: Color.fromRGBO(164, 164, 164, 1), size: 16.sp), + quickText('不及格', + color: Color.fromRGBO(164, 164, 164, 1), + size: 16.sp), ], )), Row( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.end, children: [ - quickText(doubleToStringAsFixed(data.failCount / data.studentCount * 100), - size: 34.sp, color: Colors.white, fontWeight: FontWeight.bold), + quickText( + doubleToStringAsFixed( + data.failCount / data.studentCount * 100), + size: 34.sp, + color: Colors.white, + fontWeight: FontWeight.bold), SizedBox(width: 1.5.w), quickText('%', size: 22.sp, color: Colors.white) ], @@ -816,14 +1090,18 @@ Widget $topGraphic(BuildContext context, JobReportModel data) { padding: EdgeInsets.symmetric(vertical: 4.h), decoration: BoxDecoration( borderRadius: BorderRadius.circular(77.r), - border: Border.all(color: Color.fromRGBO(188, 188, 188, 1)), + border: + Border.all(color: Color.fromRGBO(188, 188, 188, 1)), ), child: Row( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children: [ - quickText('查看', size: 11.sp, color: Color.fromRGBO(118, 118, 118, 1)), - Icon(Icons.arrow_forward_ios, size: 11.sp, color: Color.fromRGBO(95, 95, 95, 1)) + quickText('查看', + size: 11.sp, + color: Color.fromRGBO(118, 118, 118, 1)), + Icon(Icons.arrow_forward_ios, + size: 11.sp, color: Color.fromRGBO(95, 95, 95, 1)) ], ), ), @@ -846,11 +1124,16 @@ Widget $topGraphic(BuildContext context, JobReportModel data) { color: Color.fromRGBO(241, 241, 241, 1), ), child: FlutterWaveLoading( - width: 140.w, //宽 - height: 170.h, //高 - isOval: false, // 是否椭圆裁切 - progress: data.noAnswerCount / data.studentCount, // 进度 - waveHeight: 8, //波浪高 + width: 140.w, + //宽 + height: 170.h, + //高 + isOval: false, + // 是否椭圆裁切 + progress: data.noAnswerCount / data.studentCount, + // 进度 + waveHeight: 8, + //波浪高 milliseconds: 6000, color: Color.fromRGBO(96, 96, 96, 1), //颜色 ), @@ -874,13 +1157,18 @@ Widget $topGraphic(BuildContext context, JobReportModel data) { Column( mainAxisSize: MainAxisSize.min, children: [ - quickText('人', size: 18.sp, color: Color.fromRGBO(122, 122, 122, 1)), + quickText('人', + size: 18.sp, + color: + Color.fromRGBO(122, 122, 122, 1)), SizedBox(height: 4.h) ], ) ], ), - quickText('未做', color: Color.fromRGBO(164, 164, 164, 1), size: 16.sp), + quickText('未做', + color: Color.fromRGBO(164, 164, 164, 1), + size: 16.sp), ], ), ), @@ -888,8 +1176,12 @@ Widget $topGraphic(BuildContext context, JobReportModel data) { mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.end, children: [ - quickText(doubleToStringAsFixed(data.noAnswerCount / data.studentCount * 100), - size: 34.sp, color: Colors.white, fontWeight: FontWeight.bold), + quickText( + doubleToStringAsFixed( + data.noAnswerCount / data.studentCount * 100), + size: 34.sp, + color: Colors.white, + fontWeight: FontWeight.bold), SizedBox(width: 1.5.w), quickText('%', size: 22.sp, color: Colors.white) ], @@ -905,14 +1197,18 @@ Widget $topGraphic(BuildContext context, JobReportModel data) { padding: EdgeInsets.symmetric(vertical: 4.h), decoration: BoxDecoration( borderRadius: BorderRadius.circular(77.r), - border: Border.all(color: Color.fromRGBO(188, 188, 188, 1)), + border: + Border.all(color: Color.fromRGBO(188, 188, 188, 1)), ), child: Row( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children: [ - quickText('查看', size: 11.sp, color: Color.fromRGBO(118, 118, 118, 1)), - Icon(Icons.arrow_forward_ios, size: 11.sp, color: Color.fromRGBO(95, 95, 95, 1)) + quickText('查看', + size: 11.sp, + color: Color.fromRGBO(118, 118, 118, 1)), + Icon(Icons.arrow_forward_ios, + size: 11.sp, color: Color.fromRGBO(95, 95, 95, 1)) ], ), ), @@ -930,7 +1226,9 @@ Widget $topGraphic(BuildContext context, JobReportModel data) { /// 掌握知识点的情况 @swidget -Widget $masterKnowledgePoint(BuildContext context, List knowledgeInfos, +Widget $masterKnowledgePoint( + BuildContext context, + List knowledgeInfos, Future Function(KnowledgeInfos knowledge) detailCall) { Widget childItem(int serialNumber, KnowledgeInfos knowItem) => Container( margin: EdgeInsets.only(bottom: 20.h), @@ -946,10 +1244,14 @@ Widget $masterKnowledgePoint(BuildContext context, List knowledg child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - quickText('${(serialNumber + 1).toString() + '.' + knowItem.knowledgeName}', - size: 12.sp, color: Color.fromRGBO(152, 152, 152, 1)), + quickText( + '${(serialNumber + 1).toString() + '.' + knowItem.knowledgeName}', + size: 12.sp, + color: Color.fromRGBO(152, 152, 152, 1)), quickText('${doubleToStringAsFixed(knowItem.rate)}%', - size: 14.sp, color: Color.fromRGBO(64, 64, 64, 1), fontWeight: FontWeight.bold), + size: 14.sp, + color: Color.fromRGBO(64, 64, 64, 1), + fontWeight: FontWeight.bold), ], ), ), @@ -983,8 +1285,10 @@ Widget $masterKnowledgePoint(BuildContext context, List knowledg child: Row( mainAxisSize: MainAxisSize.min, children: [ - quickText('查看', size: 14.sp, color: Color.fromRGBO(239, 135, 20, 1)), - Icon(Icons.arrow_forward_ios, size: 11.sp, color: Color.fromRGBO(239, 135, 20, 1)), + quickText('查看', + size: 14.sp, color: Color.fromRGBO(239, 135, 20, 1)), + Icon(Icons.arrow_forward_ios, + size: 11.sp, color: Color.fromRGBO(239, 135, 20, 1)), ], ), ), @@ -997,16 +1301,25 @@ Widget $masterKnowledgePoint(BuildContext context, List knowledg 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)), + decoration: BoxDecoration( + color: Colors.white, borderRadius: BorderRadius.circular(10.r)), child: Column( children: [ Container( - child: quickText('知识点掌握情况', color: Color.fromRGBO(92, 92, 92, 1), size: 14.sp, fontWeight: FontWeight.bold), + child: quickText('知识点掌握情况', + color: Color.fromRGBO(92, 92, 92, 1), + size: 14.sp, + fontWeight: FontWeight.bold), margin: EdgeInsets.only(bottom: 24.h), ), // ...knowledgeInfos.asMap().keys.map((e) => childItem(e, knowledgeInfos[e])).toList() Expanded( - child: ListView(children: knowledgeInfos.asMap().keys.map((e) => childItem(e, knowledgeInfos[e])).toList()), + child: ListView( + children: knowledgeInfos + .asMap() + .keys + .map((e) => childItem(e, knowledgeInfos[e])) + .toList()), ), ], )); @@ -1015,13 +1328,13 @@ Widget $masterKnowledgePoint(BuildContext context, List knowledg /// 整体表现 @swidget Widget $overallPerformance(int totalNumber, List overallTitles) { - Map colorMap = { - '优秀': Color.fromRGBO(104, 136, 253, 1), - '良好': Color.fromRGBO(255, 186, 33, 1), - '一般': Color.fromRGBO(243, 163, 44, 1), - '较差': Color.fromRGBO(211, 211, 211, 1).withOpacity(0.5), - '很差': Color.fromRGBO(211, 211, 211, 1), - }; + List colorMap = [ + Color.fromRGBO(104, 136, 253, 1), + Color.fromRGBO(255, 186, 33, 1), + Color.fromRGBO(243, 163, 44, 1), + Color.fromRGBO(211, 211, 211, 1).withOpacity(0.5), + Color.fromRGBO(211, 211, 211, 1), + ]; return Container( margin: EdgeInsets.only(top: 20.h), padding: EdgeInsets.symmetric(vertical: 16.h, horizontal: 16.w), @@ -1035,7 +1348,10 @@ Widget $overallPerformance(int totalNumber, List overallTitles) { children: [ Container( alignment: Alignment.center, - child: quickText('整体表现', color: Color.fromRGBO(92, 92, 92, 1), size: 14.sp, fontWeight: FontWeight.bold), + child: quickText('整体表现', + color: Color.fromRGBO(92, 92, 92, 1), + size: 14.sp, + fontWeight: FontWeight.bold), margin: EdgeInsets.only(bottom: 20.h), ), Expanded( @@ -1044,13 +1360,19 @@ Widget $overallPerformance(int totalNumber, List overallTitles) { borderData: FlBorderData(show: false), sectionsSpace: 2, centerSpaceRadius: 0, - sections: overallTitles.map((e) { + sections: overallTitles.asMap().keys.map((index) { + var e = overallTitles[index]; return PieChartSectionData( - color: colorMap[e.title], + color: colorMap[index], value: e.count / totalNumber * 100, radius: 110, - title: e.title + (doubleToStringAsFixed(e.count / totalNumber * 100) + '%'), - titleStyle: TextStyle(fontSize: 14.sp, color: Colors.white, fontWeight: FontWeight.bold), + title: e.title + + (doubleToStringAsFixed(e.count / totalNumber * 100) + + '%'), + titleStyle: TextStyle( + fontSize: 14.sp, + color: Colors.white, + fontWeight: FontWeight.bold), ); }).toList(), ), @@ -1063,12 +1385,14 @@ Widget $overallPerformance(int totalNumber, List overallTitles) { /// 单位时间答题情况 @swidget -Widget $unitTimeAnsweringSituation(BuildContext context, int jobid, List questionAnswerInfos) { +Widget $unitTimeAnsweringSituation(BuildContext context, int jobid, + List questionAnswerInfos) { List questionNos = []; // 题号 List questionTypes = []; // 题型 List completionStatusWithinThirtySeconds = []; // 30s内完成情况 List completionStatusWithinThirtyOneSixtySeconds = []; // 31s-60s内完成情况 - List completionStatusWithinSixtyOneOneHundredAndTwenty = []; // 61s-120s内完成情况 + List completionStatusWithinSixtyOneOneHundredAndTwenty = + []; // 61s-120s内完成情况 List accuracys = []; // 正确率 List errorRate = []; // 错误率 List notDone = []; // 未做 @@ -1105,15 +1429,15 @@ Widget $unitTimeAnsweringSituation(BuildContext context, int jobid, List studentAnswerInfos) { +Widget $personnelDataOverview( + BuildContext context, List studentAnswerInfos) { List names = []; List useTimes = []; List correctRates = []; @@ -1313,12 +1667,16 @@ Widget $personnelDataOverview(BuildContext context, List stu height: 290.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)), + decoration: BoxDecoration( + color: Colors.white, borderRadius: BorderRadius.circular(10.r)), child: Column( mainAxisSize: MainAxisSize.min, children: [ Container( - child: quickText('人员数据概况', color: Color.fromRGBO(92, 92, 92, 1), size: 14.sp, fontWeight: FontWeight.bold), + child: quickText('人员数据概况', + color: Color.fromRGBO(92, 92, 92, 1), + size: 14.sp, + fontWeight: FontWeight.bold), margin: EdgeInsets.only(bottom: 20.h), ), Expanded( @@ -1328,7 +1686,8 @@ Widget $personnelDataOverview(BuildContext context, List stu crossAxisAlignment: CrossAxisAlignment.start, children: [ ...mapData.entries.map((entrie) { - bool isTransparentChinese = ['答题时长', '正确率', '未答题数'].contains(entrie.key); // 透明中文 + bool isTransparentChinese = + ['答题时长', '正确率', '未答题数'].contains(entrie.key); // 透明中文 return Row( crossAxisAlignment: CrossAxisAlignment.start, @@ -1338,28 +1697,44 @@ Widget $personnelDataOverview(BuildContext context, List stu alignment: Alignment.center, color: 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), + 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; + 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), + 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) + ? 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), + quickText('透', + color: Colors.transparent, + size: 12.sp), ], ) - : quickText(e, color: Color.fromRGBO(82, 82, 82, 1), size: 12.sp, maxLines: 2), + : quickText(e, + color: Color.fromRGBO(82, 82, 82, 1), + size: 12.sp, + maxLines: 2), ); }).toList(), ], @@ -1398,5 +1773,10 @@ class QuestionPictureModel extends Object { String questionNo; int questionid; int jobid; - QuestionPictureModel({required this.jobid, required this.questionid, required this.questionNo, this.questionPicture}); + + QuestionPictureModel( + {required this.jobid, + required this.questionid, + required this.questionNo, + this.questionPicture}); } diff --git a/marking_app/lib/pages/homework_correction/quick_check_personal.dart b/marking_app/lib/pages/homework_correction/quick_check_personal.dart new file mode 100644 index 0000000..e020182 --- /dev/null +++ b/marking_app/lib/pages/homework_correction/quick_check_personal.dart @@ -0,0 +1,156 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_easyloading/flutter_easyloading.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:marking_app/common/mixin/common.dart'; +import 'package:marking_app/common/model/common/base_structure_result.dart'; +import 'package:marking_app/common/model/job/job_data_report.dart'; +import 'package:marking_app/pages/homework_correction/widget/student_kg_table.dart'; +import 'package:marking_app/pages/homework_correction/widget/student_zg_table.dart'; +import 'package:marking_app/utils/request/rest_client.dart'; + +class QuickCheckPersonal extends StatefulWidget { + final int jobId; + final int studentId; + + const QuickCheckPersonal( + {Key? key, required this.jobId, required this.studentId}) + : super(key: key); + + @override + State createState() => _QuickCheckPersonalState(); +} + +class _QuickCheckPersonalState extends State + with CommonMixin { + StudentDetails? studentInfo; + + void initState() { + super.initState(); + EasyLoading.show(status: 'loading...'); + getJobPersonal(); + } + + void getJobPersonal() async { + RestClient _client = await getClient(); + Map params = {}; + // params['jobid'] = widget.jobId; + params['jobid'] = '521646983660101'; + params['studentId'] = widget.studentId; + BaseStructureResult data = + await _client.getJobPersonalReport(params); + EasyLoading.dismiss(); + setState(() { + studentInfo = data.data; + }); + } + + @override + Widget build(BuildContext context) { + if (studentInfo == null) { + return Container(); + } + return Scaffold( + backgroundColor: Color.fromRGBO(245, 245, 245, 1), + appBar: AppBar( + backgroundColor: Colors.white, + title: Text( + studentInfo!.studentName, + style: TextStyle(fontSize: 16.sp, color: Color(0xFF000000)), + ), + centerTitle: true, + leading: IconButton( + icon: Icon(Icons.arrow_back_ios, color: Colors.black), + onPressed: () => Navigator.of(context).pop(), + ), + ), + + body: SingleChildScrollView( + child: Column( + children: [ + //客观题 + 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)), + ), + SizedBox( + width: 10.r, + ), + Text( + '${studentInfo!.kgValidRate}%', + style: TextStyle( + fontSize: 14.sp, color: Color(0xFF6888FD)), + ), + ], + ), + SizedBox(height: 10.r,), + SizedBox( + height: studentInfo!.kgDetails.length>8?300.r:studentInfo!.kgDetails.length * 40.r + 40.r, + child: StudentKgTable( + headList: ['题号', '学生答案', '标准答案'], + bodyList: studentInfo!.kgDetails, + ), + ) + ], + ), + ), + 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)), + ), + SizedBox( + width: 10.r, + ), + Text( + '${studentInfo!.zgValidRate}%', + style: TextStyle( + fontSize: 14.sp, color: Color(0xFF6888FD)), + ), + ], + ), + SizedBox(height: 10.r,), + SizedBox( + height: studentInfo!.zgDetails.length>8?300.r:studentInfo!.zgDetails.length * 40.r + 40.r, + child: StudentZgTable( + headList: ['题号', '用时', '批注结果','答案','批注'], + bodyList: studentInfo!.zgDetails, + ), + ) + ], + ), + ), + ], + ), + ), + ); + } +} diff --git a/marking_app/lib/pages/homework_correction/quick_data_check.dart b/marking_app/lib/pages/homework_correction/quick_data_check.dart new file mode 100644 index 0000000..0810109 --- /dev/null +++ b/marking_app/lib/pages/homework_correction/quick_data_check.dart @@ -0,0 +1,324 @@ +import 'package:fl_chart/fl_chart.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_easyloading/flutter_easyloading.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:marking_app/common/mixin/common.dart'; +import 'package:marking_app/common/model/common/base_structure_result.dart'; +import 'package:marking_app/common/model/job/job_data_report.dart'; +import 'package:marking_app/common/model/job/job_report_join_class.dart'; +import 'package:marking_app/pages/homework_correction/widget/quick_student_data_table.dart'; +import 'package:marking_app/utils/index.dart'; +import 'package:marking_app/utils/request/rest_client.dart'; +import 'package:percent_indicator/linear_percent_indicator.dart'; + +class QuickDataCheck extends StatefulWidget { + final int jobId; + final String className; + + const QuickDataCheck({Key? key, required this.jobId,required this.className}) : super(key: key); + + @override + State createState() => _QuickDataCheckState(); +} + +class _QuickDataCheckState extends State with CommonMixin { + JobDataReport? jobData; + + void initState() { + super.initState(); + EasyLoading.show(status:'loading...'); + getJobDataReport(); + } + + void getJobDataReport() async { + RestClient _client = await getClient(); + Map params = {}; + // params['jobid'] = widget.jobId; + params['jobid'] = '521646983660101'; + BaseStructureResult data = + await _client.getJobDataCenterReport(params); + EasyLoading.dismiss(); + setState(() { + jobData = data.data; + }); + + } + + @override + Widget build(BuildContext context) { + if (jobData == null) { + return Container(); + } + return AnnotatedRegion( + value: const SystemUiOverlayStyle( + statusBarColor: Colors.transparent, + systemNavigationBarIconBrightness: Brightness.light, + statusBarIconBrightness: Brightness.light, + statusBarBrightness: Brightness.dark, + ), + child: Container( + padding: EdgeInsets.only(top: MediaQuery.of(context).padding.top), + height: MediaQuery.of(context).size.height, + decoration: BoxDecoration( + gradient: LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: [ + Color(0xFF6889FD), + Color(0xFFF5F5F5), + ], + stops: [ + 0.09, + 0.3 + ])), + child: SingleChildScrollView( + child: Column( + children: [ + Row( + children: [ + IconButton( + icon: Icon(Icons.arrow_back_ios, color: Colors.white), + onPressed: () => Navigator.of(context).pop(), + ), + Expanded( + child: Center( + child: Text( + '数据快查', + style: TextStyle(fontSize: 16.sp, color: Colors.white), + ))), + ], + ), + Padding( + padding: EdgeInsets.only(left: 14.r, top: 10.r), + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Image.asset( + 'assets/images/job_report_class_icon.png', + width: 22.r, + height: 22.r, + ), + SizedBox( + width: 6.r, + ), + Text( + widget.className, + style: TextStyle(fontSize: 14.r, color: Colors.white), + ) + ], + ), + ), + Container( + padding: EdgeInsets.symmetric(vertical: 10.r, horizontal: 15.r), + margin: EdgeInsets.symmetric(vertical: 10.r, horizontal: 14.r), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.all(Radius.circular(6.r))), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Container( + width: 14.r, + height: 14.r, + decoration: BoxDecoration( + color: Color(0xFF4CC793), + borderRadius: + BorderRadius.all(Radius.circular(7.r))), + ), + SizedBox( + width: 6.r, + ), + Text( + '已提交', + style: TextStyle( + fontSize: 12.sp, color: Color(0xFF333333)), + ), + SizedBox( + width: 35.r, + ), + Container( + width: 14.r, + height: 14.r, + decoration: BoxDecoration( + color: Color(0xFF6888FD), + borderRadius: + BorderRadius.all(Radius.circular(7.r))), + ), + SizedBox( + width: 6.r, + ), + Text( + '未提交', + style: TextStyle( + fontSize: 12.sp, color: Color(0xFF333333)), + ) + ], + ), + //环形图 + SizedBox( + height: MediaQuery.of(context).size.width * 0.5, + child: PieChart( + PieChartData( + borderData: FlBorderData(show: false), + sectionsSpace: 0, + centerSpaceRadius: MediaQuery.of(context).size.width * 0.1, + sections: [ + PieChartSectionData( + color: Color(0xFF4CC793), + value: jobData!.validCount/(jobData!.validCount+jobData!.noAnswerCount) * 100, + radius: MediaQuery.of(context).size.width * 0.1 + 5, + title: '${jobData!.validCount}人', + titleStyle: TextStyle( + fontSize: 14.sp, + color: Colors.white, + ), + ), + PieChartSectionData( + color: Color(0xFF6888FD), + value: jobData!.noAnswerCount/(jobData!.validCount+jobData!.noAnswerCount) * 100, + radius: MediaQuery.of(context).size.width * 0.1, + title: '${jobData!.noAnswerCount}人', + titleStyle: TextStyle( + fontSize: 14.sp, + color: Colors.white, + ), + ), + ], + ), + ), + ), + // 客观进度条 + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + '客观题答题进度', + style: TextStyle( + fontSize: 10.sp, color: Color(0xFF8B8B8B)), + ), + Text('${doubleToStringAsFixed(jobData!.kgValidRate)}%', + style: TextStyle( + fontSize: 10.sp, color: Color(0xFF333333)), + ), + ], + ), + SizedBox(height: 6.r), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + flex: 10, + child: LinearPercentIndicator( + padding: EdgeInsets.zero, + animation: true, + lineHeight: 9.h, + animationDuration: 2500, + percent: jobData!.kgValidRate/100, + progressColor: Color(0xFFFF7F22), + backgroundColor: Color(0xFFEAEAEA), + barRadius: Radius.circular(10.r), + )), + ], + ), + SizedBox(height: 20.r), + // 主观进度条 + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + '主观题答题进度', + style: TextStyle( + fontSize: 10.sp, color: Color(0xFF8B8B8B)), + ), + Text( + '${doubleToStringAsFixed(jobData!.zgValidRate)}%', + style: TextStyle( + fontSize: 10.sp, color: Color(0xFF333333)), + ), + ], + ), + SizedBox(height: 6.r), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + flex: 10, + child: LinearPercentIndicator( + padding: EdgeInsets.zero, + animation: true, + lineHeight: 9.h, + animationDuration: 2500, + percent: jobData!.zgValidRate/100, + progressColor: Color(0xFFFF7F22), + backgroundColor: Color(0xFFEAEAEA), + barRadius: Radius.circular(10.r), + )), + ], + ), + ], + ), + ), + Container( + padding: EdgeInsets.symmetric(vertical: 10.r, horizontal: 10.r), + margin: EdgeInsets.symmetric(vertical: 10.r, horizontal: 14.r), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.all(Radius.circular(6.r))), + child: Column( + children: [ + InkWell( + onTap: (){ + jobData!.studentDetails.sort((a, b) { + int num1 = a.kgValidRate + a.zgValidRate; + int num2 = b.kgValidRate + b.zgValidRate; + return num2.compareTo(num1); + }); + setState(() { + jobData!.studentDetails; + }); + }, + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Text( + '未提交排序', + style: TextStyle( + fontSize: 12.sp, color: Color(0xFF6888FD)), + ), + SizedBox( + width: 10.r, + ), + Image.asset( + 'assets/images/sort_icon.png', + width: 14.r, + height: 14.r, + ), + ], + ), + ), + SizedBox(height: 10.r,), + SizedBox( + height: jobData!.studentDetails.length>5?300.r:jobData!.studentDetails.length * 50.r + 40.r, + child: QuickStudentDataTable( + headList: ['学生姓名','客观题','主观题','客观题错题','主观题错题'], + bodyList: jobData!.studentDetails, + jobId: widget.jobId, + fixedRows: 1, + fixedCols: 0, + ), + ) + ], + ), + ), + ], + ), + ), + ), + ); + } +} diff --git a/marking_app/lib/pages/homework_correction/widget/quick_student_data_table.dart b/marking_app/lib/pages/homework_correction/widget/quick_student_data_table.dart new file mode 100644 index 0000000..7fb44fd --- /dev/null +++ b/marking_app/lib/pages/homework_correction/widget/quick_student_data_table.dart @@ -0,0 +1,193 @@ +import 'package:data_table_2/data_table_2.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:marking_app/common/model/job/job_data_report.dart'; +import 'package:marking_app/routes/RouterManager.dart'; +import 'package:marking_app/utils/index.dart'; + +class QuickStudentDataTable extends StatefulWidget { + final List headList; + final List bodyList; + final int? fixedRows; + final int? fixedCols; + final int jobId; + + const QuickStudentDataTable({ + Key? key, + required this.headList, + required this.bodyList, + required this.jobId, + this.fixedCols = 0, + this.fixedRows = 0, + }) : super(key: key); + + @override + State createState() => _QuickStudentDataTableState(); +} + +class _QuickStudentDataTableState extends State { + final ScrollController _controller = ScrollController(); + int? _sortColumnIndex; + bool _sortAscending = true; + + DataRow _getRow(int index, [Color? color]) { + assert(index >= 0); + StudentDetails item = widget.bodyList[index]; + int num = 0; + item.kgDetails.forEach((element) { + if(element.state == 0){ + num = num + 1; + } + }); + item.zgDetails.forEach((element) { + if(element.state == 0){ + num = num + 1; + } + }); + return DataRow2.byIndex( + index: index, + color: color != null ? num == 0?MaterialStateProperty.all(color):MaterialStateProperty.all(Color(0xFFFFD79C)): null, + cells: [ + DataCell(InkWell( + onTap: (){ + RouterManager.router.navigateTo( + context, + RouterManager.quickCheckPersonalPath + + '?jobId=${521646983660101}&studentId=${item.studentId}', + transition: getTransition(), + ); + }, + child: Center( + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 5.r), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text(item.studentName, + style: TextStyle(fontSize: 12.sp, color: Color(0xFF6888FD))), + SizedBox(width: 5.r,), + Image.asset('assets/images/job_data_right_icon.png',width: 10.r,height: 10.r,) + ], + ), + ), + ), + )), + DataCell(Center( + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 5.r), + child: Text( + '${(item.kgValidRate / 100 * item.kgValidCount).toInt()}/${item.kgValidCount}', + style: TextStyle(fontSize: 12.sp, color: Color(0xFF525252))), + ), + )), + DataCell(Center( + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 5.r), + child: Text( + '${(item.zgValidRate / 100 * item.zgValidCount).toInt()}/${item.zgValidCount}', + style: TextStyle(fontSize: 12.sp, color: Color(0xFF525252))), + ), + )), + DataCell( + Padding( + padding: EdgeInsets.symmetric(vertical:2.r,horizontal: 5.r), + child: SingleChildScrollView( + child: Wrap( + direction: Axis.horizontal, + alignment: WrapAlignment.center, + spacing: 2, + runSpacing: 2, + children: List.generate(item.kgDetails.length, (index) { + KgDetails kgInfo = item.kgDetails[index]; + return Container( + width: 14.r, + height: 14.r, + decoration: BoxDecoration( + color: kgInfo.state == 0?Color(0xFFD9D9D9):kgInfo.state == 1?Color(0xFFFF7474):Color(0xFF4CC793), + borderRadius: BorderRadius.all(Radius.circular(7.r)) + ), + child: Center(child: Text(kgInfo.questionNo,style: TextStyle(fontSize:10.sp,color: kgInfo.state == 0?Color(0xFF525252):Colors.white),)), + ); + })), + ), + ), + ), + DataCell( Padding( + padding: EdgeInsets.symmetric(vertical:2.r,horizontal: 5.r), + child: SingleChildScrollView( + child: Wrap( + direction: Axis.horizontal, + alignment: WrapAlignment.center, + spacing: 2, + runSpacing: 2, + children: List.generate(item.zgDetails.length, (index) { + KgDetails kgInfo = item.zgDetails[index]; + return Container( + width: 14.r, + height: 14.r, + decoration: BoxDecoration( + color: kgInfo.state == 0?Color(0xFFD9D9D9):kgInfo.state == 1?Color(0xFFFF7474):Color(0xFF4CC793), + borderRadius: BorderRadius.all(Radius.circular(7.r)) + ), + child: Center(child: Text(kgInfo.questionNo,style: TextStyle(fontSize:10.sp,color: kgInfo.state == 0?Color(0xFF525252):Colors.white),)), + ); + })), + ), + ),), + ], + ); + } + + @override + Widget build(BuildContext context) { + return DataTable2( + dividerThickness: 0, + scrollController: _controller, + columnSpacing: 0, + horizontalMargin: 0, + bottomMargin: 0, + dataRowHeight: 50.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( + gradient: LinearGradient( + colors: [ + Colors.grey[400]!, + Colors.grey[200]!, + ], + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + ), + ),*/ + 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)/5, + ); + }), + rows: List.generate(widget.bodyList.length, + (index) => _getRow(index, Color(0xFFF5F5F5)))); + } +} diff --git a/marking_app/lib/pages/homework_correction/widget/report_table.dart b/marking_app/lib/pages/homework_correction/widget/report_table.dart new file mode 100644 index 0000000..712ae90 --- /dev/null +++ b/marking_app/lib/pages/homework_correction/widget/report_table.dart @@ -0,0 +1,148 @@ +import 'package:data_table_2/data_table_2.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:flutter_widget_from_html_core/flutter_widget_from_html_core.dart'; + +class ReportTable extends StatefulWidget { + final List headList; + final List bodyList; + final int? fixedRows; + final int? fixedCols; + final bool? isKG; + + const ReportTable({ + Key? key, + required this.headList, + required this.bodyList, + this.fixedCols = 0, + this.fixedRows = 0, + this.isKG = false, + }) : super(key: key); + + @override + State createState() => _ReportTableState(); +} + +class _ReportTableState extends State { + final ScrollController _controller = ScrollController(); + int? _sortColumnIndex; + bool _sortAscending = true; + + DataRow _getRow(int index, [Color? color]) { + assert(index >= 0); + var item = widget.bodyList[index]; + return DataRow2.byIndex( + index: index, + color: color != null ? MaterialStateProperty.all(color) : null, + cells: [ + DataCell( Center( + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 5.r), + child: + Text(item.questionNo, + style: + TextStyle(fontSize: 12.sp, color: Color(0xFF525252))), + ), + )), + DataCell( Center( + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 5.r), + child: + Text('${item.validRate}%', + style: + TextStyle(fontSize: 12.sp, color: Color(0xFF525252))), + ), + )), + DataCell( Center( + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 5.r), + child: + Text(item.validCount, + style: + TextStyle(fontSize: 12.sp, color: Color(0xFF4CC793))), + ), + )), + DataCell( Center( + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 5.r), + child: + Text('${item.correctRate}%', + style: + TextStyle(fontSize: 12.sp, color: Color(0xFF525252))), + ), + )), + DataCell( Center( + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 5.r), + child: + Text( + widget.isKG == true?'原题':item.questionAnswer, + style: + TextStyle(fontSize: 12.sp, color: widget.isKG == true?Color(0xFFFF8A00):Color(0xFF4CC793))), + ), + )), + DataCell( Center( + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 5.r), + child: + Text(item.priorityGeneral, + style: + TextStyle(fontSize: 12.sp, color: Color(0xFF6888FD))), + ), + )), + ], + ); + } + + @override + Widget build(BuildContext context) { + return DataTable2( + dividerThickness: 0, + scrollController: _controller, + columnSpacing: 0, + horizontalMargin: 0, + dataRowHeight:40.r, + bottomMargin: 0, + 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( + gradient: LinearGradient( + colors: [ + Colors.grey[400]!, + Colors.grey[200]!, + ], + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + ), + ),*/ + headingRowDecoration: BoxDecoration(color: Color(0xFFE6E6E6)), + fixedColumnsColor: Color(0xFFE6E6E6), + fixedCornerColor: Colors.grey[400], + minWidth: widget.headList.length > 6?80.r * widget.headList.length: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: index == 0 ? 40.r:widget.headList.length > 6 ?80.r:(MediaQuery.of(context).size.width)/widget.headList.length, + ); + }), + rows: List.generate(widget.bodyList.length, + (index) => _getRow(index, Color(0xFFF5F5F5)))); + } +} diff --git a/marking_app/lib/pages/homework_correction/widget/student_kg_table.dart b/marking_app/lib/pages/homework_correction/widget/student_kg_table.dart new file mode 100644 index 0000000..4110d45 --- /dev/null +++ b/marking_app/lib/pages/homework_correction/widget/student_kg_table.dart @@ -0,0 +1,103 @@ +import 'package:data_table_2/data_table_2.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:marking_app/common/model/job/job_data_report.dart'; + +class StudentKgTable extends StatefulWidget { + final List headList; + final List bodyList; + final int? fixedRows; + final int? fixedCols; + + const StudentKgTable({ + Key? key, + required this.headList, + required this.bodyList, + this.fixedCols = 0, + this.fixedRows = 0, + }) : super(key: key); + + @override + State createState() => _StudentKgTableState(); +} + +class _StudentKgTableState extends State { + final ScrollController _controller = ScrollController(); + int? _sortColumnIndex; + bool _sortAscending = true; + + DataRow _getRow(int index, [Color? color]) { + assert(index >= 0); + KgDetails item = widget.bodyList[index]; + return DataRow2.byIndex( + index: index, + color: color != null ? MaterialStateProperty.all(color): null, + cells: [ + DataCell(Center( + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 5.r), + child: Text(item.questionNo, + 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: Color(0xFF525252))), + ), + )), + DataCell(Center( + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 5.r), + child: Text(item.annotateAnswers == null ?'无':item.annotateAnswers!, + 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/marking_app/lib/pages/homework_correction/widget/student_zg_table.dart b/marking_app/lib/pages/homework_correction/widget/student_zg_table.dart new file mode 100644 index 0000000..d60d374 --- /dev/null +++ b/marking_app/lib/pages/homework_correction/widget/student_zg_table.dart @@ -0,0 +1,157 @@ +import 'package:data_table_2/data_table_2.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:marking_app/common/model/job/job_data_report.dart'; +import 'package:marking_app/utils/easy_refresh/MyEmptyWidget.dart'; + +class StudentZgTable extends StatefulWidget { + final List headList; + final List bodyList; + final int? fixedRows; + final int? fixedCols; + + const StudentZgTable({ + Key? key, + required this.headList, + required this.bodyList, + this.fixedCols = 0, + this.fixedRows = 0, + }) : super(key: key); + + @override + State createState() => _StudentZgTableState(); +} + +class _StudentZgTableState extends State { + final ScrollController _controller = ScrollController(); + int? _sortColumnIndex; + bool _sortAscending = true; + + void showImgDialog(BuildContext context,String imgUrl){ + 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))), + content: SizedBox( + width: MediaQuery.of(context).size.width * 0.6, + height: MediaQuery.of(context).size.height * 0.6, + child: Column( + children: [ + Center( + child: Text('批注答案',style: TextStyle(fontSize: 15.sp,color: Color(0xFF3C3C3C)),), + ), + SizedBox(height: 10.r,), + Image.network(imgUrl,fit: BoxFit.cover, errorBuilder: (context, error, stackTrace) { + return Padding( + padding: EdgeInsets.only(top: 20.r), + child: const MyEmptyWidget()); + }), + ], + ), + ), + ); + }); + } + + DataRow _getRow(int index, [Color? color]) { + assert(index >= 0); + KgDetails item = widget.bodyList[index]; + return DataRow2.byIndex( + index: index, + color: color != null ? MaterialStateProperty.all(color): null, + cells: [ + DataCell(Center( + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 5.r), + child: Text(item.questionNo, + style: TextStyle(fontSize: 12.sp, color: Color(0xFF6888FD))), + ), + )), + DataCell(Center( + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 5.r), + child: Text(item.useTime.toString(), + style: TextStyle(fontSize: 12.sp, color: Color(0xFF525252))), + ), + )), + DataCell(Center( + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 5.r), + child: item.state == 2? + 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: (){ + showImgDialog(context,item.studentAnswer!); + }, + child: Center( + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 5.r), + child: Text('查看', + style: TextStyle(fontSize: 12.sp, color: Color(0xFF3661FE))), + ), + ), + )), + DataCell(InkWell( + onTap: (){ + showImgDialog(context,item.annotateAnswers!); + }, + 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)/5, + ); + }), + rows: List.generate(widget.bodyList.length, + (index) => _getRow(index, Color(0xFFF5F5F5)))); + } +} diff --git a/marking_app/lib/pages/homework_correction/widget/top_count.dart b/marking_app/lib/pages/homework_correction/widget/top_count.dart new file mode 100644 index 0000000..98e0e46 --- /dev/null +++ b/marking_app/lib/pages/homework_correction/widget/top_count.dart @@ -0,0 +1,266 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:marking_app/common/model/job/job_report_model.dart'; +import 'package:marking_app/utils/index.dart'; + +class TopCount extends StatelessWidget { + final JobReportModel data; + const TopCount(this.data,{Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Container( + padding: EdgeInsets.symmetric(vertical: 10.r), + margin: EdgeInsets.symmetric(vertical: 10.r, horizontal: 10.r), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.all(Radius.circular(6.r)), + ), + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Container( + width: 81.r, + padding: EdgeInsets.symmetric( + vertical: 10.r, horizontal: 6.r), + decoration: BoxDecoration( + border: Border.all( + width: 1.r, + color: Color(0xFF4CC793), + style: BorderStyle.solid), + borderRadius: BorderRadius.all(Radius.circular(6.r)), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Text( + doubleToStringAsFixed(data.finishRate), + style: TextStyle( + fontSize: 24.sp, + color: Color(0xFF4CC793), + fontWeight: FontWeight.w600), + ), + Text( + '%', + style: TextStyle( + fontSize: 16.sp, + color: Color(0xFF4CC793), + fontWeight: FontWeight.w600), + ), + ], + ), + SizedBox( + height: 15.r, + child: Row( + children: [ + Text( + data.validCount.toString(), + style: TextStyle( + fontSize: 10.sp, + color: Color(0xFFB0B0B0)), + ), + Text( + '/', + style: TextStyle( + fontSize: 10.sp, + color: Color(0xFFB0B0B0)), + ), + Text( + data.studentCount.toString(), + style: TextStyle( + fontSize: 10.sp, + color: Color(0xFFB0B0B0)), + ), + ], + ), + ), + Text( + '完成率', + style: TextStyle( + fontSize: 12.sp, color: Color(0xFF818181)), + ) + ], + ), + ), + Container( + width: 81.r, + padding: EdgeInsets.symmetric( + vertical: 10.r, horizontal: 6.r), + decoration: BoxDecoration( + border: Border.all( + width: 1.r, + color: Color(0xFF4CC793), + style: BorderStyle.solid), + borderRadius: BorderRadius.all(Radius.circular(6.r)), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Text( + doubleToStringAsFixed(data.correctRate), + style: TextStyle( + fontSize: 24.sp, + color: Color(0xFF4CC793), + fontWeight: FontWeight.w600), + ), + Text( + '%', + style: TextStyle( + fontSize: 16.sp, + color: Color(0xFF4CC793), + fontWeight: FontWeight.w600), + ), + ], + ), + SizedBox( + height: 15.r, + ), + Text( + '正确率', + style: TextStyle( + fontSize: 12.sp, color: Color(0xFF818181)), + ) + ], + ), + ), + Container( + width: 81.r, + padding: EdgeInsets.symmetric( + vertical: 10.r, horizontal: 6.r), + decoration: BoxDecoration( + border: Border.all( + width: 1.r, + color: Color(0xFF4CC793), + style: BorderStyle.solid), + borderRadius: BorderRadius.all(Radius.circular(6.r)), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Text( + data.allCorrect.toString(), + style: TextStyle( + fontSize: 24.sp, + color: Color(0xFF4CC793), + fontWeight: FontWeight.w600), + ), + Text( + '人', + style: TextStyle( + fontSize: 16.sp, + color: Color(0xFF4CC793), + fontWeight: FontWeight.w600), + ), + ], + ), + SizedBox( + height: 10.r, + ), + Text( + '全对', + style: TextStyle( + fontSize: 12.sp, color: Color(0xFF818181)), + ) + ], + ), + ), + ], + ), + SizedBox( + height: 15.r, + ), + Padding( + padding: EdgeInsets.symmetric(horizontal: 15.r), + child: GridView.builder( + shrinkWrap: true, + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + childAspectRatio: 150 / 46, + crossAxisSpacing: 2.r, //水平子 Widget 之间间距 + mainAxisSpacing: 2.r, //垂直子 Widget 之间间距 + crossAxisCount: 2, //一行的 Widget 数量 + ), + itemCount: data.overallTitles.length, + itemBuilder: (BuildContext context, index){ + var item = data.overallTitles[index]; + Color bgColor = Color(0xFF4CC793); + if(item.title == '优'){ + bgColor = Color(0xFF4CC793); + }else if(item.title == '良'){ + bgColor = Color(0xFFF8700D); + }else if(item.title == '中'){ + bgColor = Color(0xFF4CC7B8); + }else if(item.title == '差'){ + bgColor = Color(0xFFFF6F6F); + } + return Container( + padding: EdgeInsets.symmetric(vertical: 10.r), + width: (MediaQuery.of(context).size.width - 55.r) / 2, + color: Color(0xFFF5F5F5), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + SizedBox( + width: (MediaQuery.of(context).size.width - 55.r)/4 - 20.r, + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Container( + width: 28.r, + height: 28.r, + decoration: BoxDecoration( + color: Colors.white, + border: Border.all( + color: bgColor, + width: 1.r, + style: BorderStyle.solid), + borderRadius: BorderRadius.circular(14.r)), + child: Center( + child: Text( + item.title, + style: TextStyle( + color: bgColor, fontSize: 14.r), + )), + ), + ], + ), + ), + SizedBox( + width: 20.r, + ), + Text( + item.count.toString(), + style: TextStyle( + fontSize: 24.sp, + fontWeight: FontWeight.w600, + color: Color(0xFF595959)), + ), + Text( + '人', + style: TextStyle( + fontSize: 16.sp, + fontWeight: FontWeight.w600, + color: Color(0xFF595959)), + ), + ], + ), + ); + }, + ), + ), + ], + ), + ); + } +} diff --git a/marking_app/lib/routes/RouterManager.dart b/marking_app/lib/routes/RouterManager.dart index 20a8f4c..b2ce149 100644 --- a/marking_app/lib/routes/RouterManager.dart +++ b/marking_app/lib/routes/RouterManager.dart @@ -15,6 +15,8 @@ import 'package:marking_app/common/model/enum/marking_list_type.dart'; import 'package:marking_app/pages/common/startUpPage.dart'; import 'package:marking_app/pages/homework_correction/do_papers_job_exam.dart'; import 'package:marking_app/pages/homework_correction/job_report.dart'; +import 'package:marking_app/pages/homework_correction/quick_check_personal.dart'; +import 'package:marking_app/pages/homework_correction/quick_data_check.dart'; import 'package:marking_app/pages/homework_correction/review_job.dart'; import 'package:marking_app/pages/login/index.dart'; @@ -59,6 +61,9 @@ class RouterManager { static const String reportPersonalSubjectPath = 'report/details/reportPersonalSubject'; static const String userMinePath = 'user/mine/index'; static const String reportDetailPath = '/report_detail/index'; + static const String quickDataCheckPath = '/homework_correction/quick_data_check'; + static const String quickCheckPersonalPath = '/homework_correction/quick_check_personal'; + // TheMine static final FluroRouter router = FluroRouter(); @@ -239,6 +244,24 @@ class RouterManager { }, ); +// 数据快查 + static final _quickDataCheckPageHandler = Handler( + handlerFunc: (BuildContext? context, Map> params){ + int jobId = int.parse(params['jobId']![0]); + String className = params['className']![0]; + return QuickDataCheck(jobId: jobId,className:className); + }, + ); + + // 数据快查-个人信息 + static final _quickCheckPersonalPageHandler = Handler( + handlerFunc: (BuildContext? context, Map> params){ + int jobId = int.parse(params['jobId']![0]); + int studentId = int.parse(params['studentId']![0]); + return QuickCheckPersonal(jobId: jobId,studentId:studentId); + }, + ); + // 开始阅卷页面 // static final _doMarkingPapers = Handler(handlerFunc: (BuildContext? context, Map> params) => MarkingPapers()); @@ -273,6 +296,8 @@ class RouterManager { router.define(reportDetailPath, handler: _reportDetailPath, transitionType: TransitionType.material); router.define(jobReportPagePath, handler: _jobReportPageHandler, transitionType: TransitionType.material); router.define(jobExamPagePath, handler: _jobExamPageHandler, transitionType: TransitionType.material); + router.define(quickDataCheckPath, handler: _quickDataCheckPageHandler, transitionType: TransitionType.material); + router.define(quickCheckPersonalPath, handler: _quickCheckPersonalPageHandler, transitionType: TransitionType.material); // getTransition() diff --git a/marking_app/lib/utils/request/rest_client.dart b/marking_app/lib/utils/request/rest_client.dart index 53ef6aa..30bd0ad 100644 --- a/marking_app/lib/utils/request/rest_client.dart +++ b/marking_app/lib/utils/request/rest_client.dart @@ -15,6 +15,7 @@ import 'package:marking_app/common/model/common/upload_img_secret_key.dart'; import 'package:marking_app/common/model/job/job_collect_params.dart'; import 'package:marking_app/common/model/job/job_concerned_with_student.dart'; import 'package:marking_app/common/model/job/job_concerned_with_student_params.dart'; +import 'package:marking_app/common/model/job/job_data_report.dart'; import 'package:marking_app/common/model/job/job_do_marking_status_info.dart'; import 'package:marking_app/common/model/job/job_note_taking_trajectory.dart'; import 'package:marking_app/common/model/job/job_page_tab.dart'; @@ -285,4 +286,12 @@ abstract class RestClient { @the_retrofit.GET("/api/jobs/job-report-question-detail") Future>> getJobReportQuestionDetail( @the_retrofit.Query("jobid") int jobId, @the_retrofit.Query("questionid") int questionid); + + // 作业 => 数据快查 + @the_retrofit.GET("/api/read/job-data-center-report") + Future> getJobDataCenterReport(@the_retrofit.Queries() Map params); + + // 作业 => 数据快查--个人 + @the_retrofit.GET("/api/read/job-data-center-student-report") + Future> getJobPersonalReport(@the_retrofit.Queries() Map params); }