diff --git a/marking_app/assets/images/report_student_history_bg.png b/marking_app/assets/images/report_student_history_bg.png new file mode 100644 index 0000000..51b2526 Binary files /dev/null and b/marking_app/assets/images/report_student_history_bg.png differ diff --git a/marking_app/lib/common/model/report/report_student_history_record.dart b/marking_app/lib/common/model/report/report_student_history_record.dart new file mode 100644 index 0000000..88dca77 --- /dev/null +++ b/marking_app/lib/common/model/report/report_student_history_record.dart @@ -0,0 +1,50 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'report_student_history_record.g.dart'; + + +@JsonSerializable() +class ReportStudentHistoryRecord extends Object { + + @JsonKey(name: 'ExamId') + int examId; + + @JsonKey(name: 'ExamName') + String examName; + + @JsonKey(name: 'ExamStartTime') + String examStartTime; + + @JsonKey(name: 'StudentExamNum') + String studentExamNum; + + @JsonKey(name: 'ScoreInfo') + List scoreInfo; + + ReportStudentHistoryRecord(this.examId,this.examName,this.examStartTime,this.studentExamNum,this.scoreInfo,); + + factory ReportStudentHistoryRecord.fromJson(Map srcJson) => _$ReportStudentHistoryRecordFromJson(srcJson); + + Map toJson() => _$ReportStudentHistoryRecordToJson(this); + +} + + +@JsonSerializable() +class ScoreInfo extends Object { + + @JsonKey(name: 'Value') + double value; + + @JsonKey(name: 'Text') + String text; + + ScoreInfo(this.value,this.text,); + + factory ScoreInfo.fromJson(Map srcJson) => _$ScoreInfoFromJson(srcJson); + + Map toJson() => _$ScoreInfoToJson(this); + +} + + diff --git a/marking_app/lib/common/model/report/report_student_info.dart b/marking_app/lib/common/model/report/report_student_info.dart new file mode 100644 index 0000000..7345f50 --- /dev/null +++ b/marking_app/lib/common/model/report/report_student_info.dart @@ -0,0 +1,77 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'report_student_info.g.dart'; + + +@JsonSerializable() +class ReportStudentInfo extends Object { + + @JsonKey(name: 'ExamId') + int examId; + + @JsonKey(name: 'UserId') + int userId; + + @JsonKey(name: 'ClassId') + int classId; + + @JsonKey(name: 'ExamName') + String examName; + + @JsonKey(name: 'ExamNo') + String examNo; + + @JsonKey(name: 'UserName') + String userName; + + @JsonKey(name: 'ScoreInfo') + List scoreInfo; + + @JsonKey(name: 'Subject') + List subject; + + ReportStudentInfo(this.examId,this.userId,this.classId,this.examName,this.examNo,this.userName,this.scoreInfo,this.subject,); + + factory ReportStudentInfo.fromJson(Map srcJson) => _$ReportStudentInfoFromJson(srcJson); + + Map toJson() => _$ReportStudentInfoToJson(this); + +} + + +@JsonSerializable() +class ScoreInfo extends Object { + + @JsonKey(name: 'Value') + double value; + + @JsonKey(name: 'Text') + String text; + + ScoreInfo(this.value,this.text,); + + factory ScoreInfo.fromJson(Map srcJson) => _$ScoreInfoFromJson(srcJson); + + Map toJson() => _$ScoreInfoToJson(this); + +} + + +@JsonSerializable() +class Subject extends Object { + + @JsonKey(name: 'Value') + int value; + + @JsonKey(name: 'Text') + String text; + + Subject(this.value,this.text,); + + factory Subject.fromJson(Map srcJson) => _$SubjectFromJson(srcJson); + + Map toJson() => _$SubjectToJson(this); + +} + + diff --git a/marking_app/lib/pages/report_detail/completed_report.dart b/marking_app/lib/pages/report_detail/completed_report.dart new file mode 100644 index 0000000..c425874 --- /dev/null +++ b/marking_app/lib/pages/report_detail/completed_report.dart @@ -0,0 +1,499 @@ +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_report.dart'; +import 'package:marking_app/common/model/report/report_marking_detail.dart'; +import 'package:marking_app/common/model/report/report_marking_detail.dart'; +import 'package:marking_app/common/model/report/report_marking_detail_params.dart'; +import 'package:marking_app/common/model/report/report_student_info.dart'; +import 'package:marking_app/components/ReturnToHomepage.dart'; +import 'package:marking_app/pages/report_detail/widgets/complete_table.dart'; +import 'package:marking_app/routes/RouterManager.dart'; +import 'package:marking_app/utils/easy_refresh/MyEmptyWidget.dart'; +import 'package:marking_app/utils/request/rest_client_report.dart'; + +import 'widgets/custom_rect.dart'; + +class CompletedReport extends StatefulWidget { + final int examId; + final String studentNo; + + const CompletedReport( + {Key? key, required this.examId, required this.studentNo}) + : super(key: key); + + @override + State createState() => _CompletedReportState(); +} + +class _CompletedReportState extends State with CommonMixin { + ReportStudentInfo? studentInfo; + int currentSubjectId = 0; + ExamOriginPapers? examOrigin; + List examOriginList = []; + List questionAnswers = []; + final viewTransformationController = TransformationController(); + bool isList = false; + + @override + void initState() { + final zoomFactor = 0.5; + final xTranslate = 0.0; + final yTranslate = 0.0; + // final yTranslate = examOrigin!.width/2; + viewTransformationController.value.setEntry(0, 0, zoomFactor); + viewTransformationController.value.setEntry(1, 1, zoomFactor); + viewTransformationController.value.setEntry(2, 2, zoomFactor); + viewTransformationController.value.setEntry(0, 3, -xTranslate); + viewTransformationController.value.setEntry(1, 3, -yTranslate); + super.initState(); + getInfo(); + } + + void getInfo() async { + EasyLoading.show(status: 'loading...'); + RestClientReport clientReport = await getClientReport(); + BaseStructureResultReport res = + await clientReport.getStudentInfo(widget.examId, widget.studentNo); + if (res.success) { + setState(() { + studentInfo = res.data!; + currentSubjectId = + studentInfo!.subject.length > 0 ? studentInfo!.subject[0].value : 0; + getImageDetail(); + }); + } else { + EasyLoading.dismiss(); + } + } + + void getImageDetail() async { + RestClientReport clientReport = await getClientReport(); + ReportMarkingDetailParams params = + ReportMarkingDetailParams(currentSubjectId, widget.studentNo); + BaseStructureResultReport res = + await clientReport.getMarkingDetail(params); + + setState(() { + if (res.data != null) { + examOrigin = res.data!.examOriginPapers[0]; + examOriginList = res.data!.examOriginPapers; + questionAnswers = res.data!.questionAnswers; + } else { + examOriginList = []; + examOrigin = null; + questionAnswers = []; + } + }); + EasyLoading.dismiss(); + } + + @override + Widget build(BuildContext context) { + if (studentInfo == null) { + return Container(); + } + return Scaffold( + backgroundColor: Color(0xFFEDF0FF), + appBar: AppBar( + backgroundColor: Colors.white, + title: Text( + '${studentInfo!.userName}已完成考试报告', + style: TextStyle(fontSize: 14.r, color: Color(0xFF000000)), + ), + centerTitle: true, + leading: IconButton( + icon: Icon(Icons.arrow_back_ios, color: Colors.black), + onPressed: () => Navigator.of(context).pop(), + ), + actions: [ + ReturnToHomepage(), + InkWell( + onTap: () { + RouterManager.router.navigateTo(context, + '${RouterManager.reportHistoryPath}?classId=${studentInfo!.classId}&userId=${studentInfo!.userId}&studentName=${Uri.encodeComponent(studentInfo!.userName)}'); + }, + child: UnconstrainedBox( + child: Container( + padding: EdgeInsets.symmetric(horizontal: 5.r), + margin: EdgeInsets.only(right: 14.r), + height: 22.r, + decoration: BoxDecoration( + border: Border.all(width: 1.r, color: Color(0xFF6988FD)), + borderRadius: BorderRadius.circular(5.r), + ), + child: Center( + child: Text( + '历次成绩', + style: TextStyle(fontSize: 10.r, color: Color(0xFF6988FD)), + ), + ), + ), + ), + ), + ], + ), + body: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.only(top: 10.r, left: 14.r, right: 14.r), + child: Text( + '${studentInfo!.userName}${studentInfo!.examName}', + style: TextStyle( + fontSize: 14.sp, + color: Color(0xFF6787FD), + fontWeight: FontWeight.w500), + ), + ), + Container( + margin: EdgeInsets.only(top: 10.r, left: 14.r, right: 14.r), + padding: EdgeInsets.symmetric(horizontal: 10.r), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(4.r), + color: Colors.white, + boxShadow: [ + BoxShadow( + color: const Color.fromRGBO(0, 0, 0, 0.1), + offset: Offset(0, 0), //阴影y轴偏移量 + blurRadius: 2, //阴影模糊程度 + spreadRadius: 1, //阴影扩散程度 + ) + ], + ), + child: Column( + children: [ + Container( + margin: EdgeInsets.only(top: 10.r), + width: double.infinity, + height: 30.r, + decoration: BoxDecoration( + color: Color(0xFFEFF1FF), + borderRadius: BorderRadius.all(Radius.circular(2.r))), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: List.generate( + studentInfo!.scoreInfo.length > 7 + ? 7 + : studentInfo!.scoreInfo.length, (index) { + var item = studentInfo!.scoreInfo[index]; + return Container( + width: (MediaQuery.of(context).size.width - 48.r) / 7, + child: _subjectText(item.text)); + }), + ), + ), + Container( + width: double.infinity, + height: 30.r, + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(2.r))), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: List.generate( + studentInfo!.scoreInfo.length > 7 + ? 7 + : studentInfo!.scoreInfo.length, (index) { + var item = studentInfo!.scoreInfo[index]; + return Container( + width: (MediaQuery.of(context).size.width - 48.r) / 7, + child: _subjectText(item.value.toString())); + }), + ), + ), + if (studentInfo!.scoreInfo.length > 7) + Container( + width: double.infinity, + height: 30.r, + decoration: BoxDecoration( + color: Color(0xFFEFF1FF), + borderRadius: BorderRadius.all(Radius.circular(2.r))), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: List.generate(studentInfo!.scoreInfo.length - 7, + (index) { + var item = studentInfo!.scoreInfo[index + 7]; + return Container( + width: + (MediaQuery.of(context).size.width - 48.r) / 7, + child: _subjectText(item.text)); + }), + ), + ), + if (studentInfo!.scoreInfo.length > 7) + Container( + width: double.infinity, + height: 30.r, + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(2.r))), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: List.generate(studentInfo!.scoreInfo.length - 7, + (index) { + var subject = studentInfo!.scoreInfo[index + 7]; + return Container( + width: + (MediaQuery.of(context).size.width - 48.r) / 7, + child: _subjectText(subject.value.toString())); + }), + ), + ), + ], + ), + ), + SizedBox( + height: 10.r, + ), + Expanded( + child: Stack( + children: [ + Container( + margin: EdgeInsets.only(top: 10.r, left: 14.r, right: 14.r), + padding: EdgeInsets.symmetric(vertical: 15.r, horizontal: 10.r), + width: double.infinity, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(4.r), + color: Colors.white, + boxShadow: [ + BoxShadow( + color: const Color.fromRGBO(0, 0, 0, 0.1), + offset: Offset(0, 0), //阴影y轴偏移量 + blurRadius: 2, //阴影模糊程度 + spreadRadius: 1, //阴影扩散程度 + ) + ], + ), + child: Column( + children: [ + SizedBox( + height: 30.r, + width: MediaQuery.of(context).size.width, + child: ListView.builder( + itemBuilder: (BuildContext context, int index) { + Subject item = studentInfo!.subject[index]; + return InkWell( + onTap: () { + setState(() { + currentSubjectId = item.value; + EasyLoading.show(status: 'loading...'); + getImageDetail(); + }); + }, + child: Container( + width: 30.r, + height: 30.r, + margin: EdgeInsets.only( + right: index == studentInfo!.subject.length + ? 0 + : (MediaQuery.of(context).size.width - + 30.r * 9 - + 104.r) / + 8), + decoration: BoxDecoration( + color: currentSubjectId == item.value + ? Color(0xFF6787FD) + : Color(0xFFFFFFFF), + shape: BoxShape.circle, + // borderRadius: BorderRadius.all(Radius.circular(13.r)), + ), + child: Center( + child: Text( + item.text, + style: TextStyle( + fontSize: 11.sp, + color: currentSubjectId == item.value + ? Colors.white + : Color(0xFF667095), + fontWeight: FontWeight.w400), + )), + ), + ); + }, + itemCount: studentInfo!.subject.length, + scrollDirection: Axis.horizontal, + ), + ), + Expanded( + child: examOrigin != null && examOrigin!.imageUrl != '' + ? !isList + ? Padding( + padding: EdgeInsets.only(top: 5.r), + child: InteractiveViewer( + transformationController: + viewTransformationController, + constrained: false, + boundaryMargin: EdgeInsets.all(140.r), + minScale: 0.1, + // 最小缩放 + maxScale: 4.0, + // 最大缩放 + child: CustomRect(examOrigin!)), + ) + : Padding( + padding: EdgeInsets.only(top: 10.r), + child: questionAnswers.length > 0 + ? CompleteTable( + fixedCols: 0, + fixedRows: 1, + bodyList: questionAnswers, + ) + : MyEmptyWidget(), + ) + : MyEmptyWidget(), + ), + SizedBox( + height: 15.r, + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Flexible( + flex: 1, + child: InkWell( + onTap: () { + isList = false; + setState(() {}); + }, + child: Container( + height: 27.r, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(4.r), + color: !isList + ? Color(0xFF6988FD) + : Color(0xFFEDEFFF), + ), + child: Center( + child: Text( + '查看原卷', + style: TextStyle( + fontSize: 12.sp, + color: !isList + ? Colors.white + : Color(0xFF7B7B7E)), + ), + ), + ), + ), + ), + SizedBox( + width: 20.r, + ), + Flexible( + flex: 1, + child: InkWell( + onTap: () { + isList = true; + setState(() {}); + }, + child: Container( + height: 27.r, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(4.r), + color: isList + ? Color(0xFF6988FD) + : Color(0xFFEDEFFF), + ), + child: Center( + child: Text( + '查看列题', + style: TextStyle( + fontSize: 12.sp, + color: isList + ? Colors.white + : Color(0xFF7B7B7E)), + ), + ), + ), + ), + ), + ], + ), + ], + ), + ), + if (!isList) + Positioned( + left: 0.r, + top: MediaQuery.of(context).size.height / 4, + child: InkWell( + onTap: () { + var num = examOrigin!.pageIndex; + if (num > 1) { + setState(() { + examOrigin = examOriginList[num - 1 - 1]; + }); + } + }, + child: Opacity( + opacity: examOrigin != null && examOrigin!.pageIndex > 1 + ? 1 + : 0.3, + child: Image.asset( + 'assets/images/report_left_icon.png', + width: 33.r, + height: 33.r, + )), + ), + ), + if (!isList) + Positioned( + right: 0, + top: MediaQuery.of(context).size.height / 4, + child: InkWell( + onTap: () { + var num = examOrigin!.pageIndex; + if (num < examOriginList.length) { + setState(() { + examOrigin = examOriginList[num]; + }); + } + }, + child: Opacity( + opacity: examOrigin != null && + examOrigin!.pageIndex < examOriginList.length + ? 1 + : 0.3, + child: Image.asset( + 'assets/images/report_right_icon.png', + width: 33.r, + height: 33.r, + )), + /* Image.asset( + 'assets/images/report_right_icon.png', + width: 33.r, + height: 33.r, + )*/ + ), + ) + ], + )), + SizedBox( + height: 10.r, + ), + ], + ), + ); + } +} + +class _subjectText extends StatelessWidget { + final String name; + final bool isTitle; + + const _subjectText(this.name, {this.isTitle = true, Key? key}) + : super(key: key); + + @override + Widget build(BuildContext context) { + return Center( + child: Text( + name, + style: TextStyle( + fontSize: isTitle ? 11.sp : 12.sp, + color: isTitle ? Color(0xFF667095) : Color(0xFF424242), + fontWeight: FontWeight.w400), + ), + ); + } +} diff --git a/marking_app/lib/pages/report_detail/index.dart b/marking_app/lib/pages/report_detail/index.dart index a4506b4..16a185e 100644 --- a/marking_app/lib/pages/report_detail/index.dart +++ b/marking_app/lib/pages/report_detail/index.dart @@ -23,6 +23,7 @@ import 'package:marking_app/pages/report_detail/widgets/no_data.dart'; import 'package:marking_app/pages/report_detail/widgets/overall_level_table.dart'; import 'package:marking_app/pages/report_detail/widgets/report_card_dialog.dart'; import 'package:marking_app/pages/report_detail/widgets/question_table.dart'; +import 'package:marking_app/routes/RouterManager.dart'; import 'package:marking_app/utils/request/rest_client_report.dart'; import 'package:marking_app/utils/toast_utils.dart'; @@ -105,7 +106,6 @@ class _ReportDetailState extends ConsumerState with CommonMixin { BaseStructureResultReport result = await clientReport.getReportDetail(widget.examId, widget.showGrade && isGrade ? -1 : currentClass.value); - // print('*************result=${result.message}'); if (result.code == 200) { setState(() { currentPage = 1; @@ -139,9 +139,7 @@ class _ReportDetailState extends ConsumerState with CommonMixin { limit: pageSize); BaseStructureResultReport res = await clientReport.getQuestion(params); - print( - 'res.data!.total=${res.code == 200 ? res.data!.bodyExcelData.sheets[0].bodyData.length : ''}'); - if (res.code != 200 || res.data == null) { + if (res.code != 200 || res.data == null) { setState(() { smallQuestionRes = null; questionTotalPage = 0; @@ -212,7 +210,10 @@ class _ReportDetailState extends ConsumerState with CommonMixin { }); EasyLoading.dismiss(); } + goCompleteReport(BuildContext context, int index,{String studentNo = 'true'}){ + RouterManager.router.navigateTo(context, '${RouterManager.completedReportPath}?examId=${widget.examId}&studentNo=${studentNo == 'true'?initialList[index].examStudentId:studentNo}'); + } //成绩单详情 void showAlertDialog(BuildContext context, int index) { List detailHead = []; @@ -518,6 +519,7 @@ class _ReportDetailState extends ConsumerState with CommonMixin { isHtml:true, fixedRows: 1, fixedCols: 1, + showCardDetail: goCompleteReport, ), ) : NoData(), @@ -540,6 +542,7 @@ class _ReportDetailState extends ConsumerState with CommonMixin { isHtml:true, fixedRows: 1, fixedCols: 1, + showCardDetail: goCompleteReport, ), ), Row( @@ -668,6 +671,8 @@ class _ReportDetailState extends ConsumerState with CommonMixin { isScore: true, fixedRows: 1, fixedCols: 3, + showCardDetail: goCompleteReport, + smallQuestion:true, ), ) : NoData(), @@ -797,7 +802,8 @@ class _ReportDetailState extends ConsumerState with CommonMixin { child: CardList( headList: cardHeadList, bodyList: cardBodyList, - showCardDetail: showAlertDialog, + // showCardDetail: showAlertDialog, + showCardDetail: goCompleteReport, fixedRows: 1, fixedCols: 3, ), diff --git a/marking_app/lib/pages/report_detail/report_history.dart b/marking_app/lib/pages/report_detail/report_history.dart index 34ec256..449b0be 100644 --- a/marking_app/lib/pages/report_detail/report_history.dart +++ b/marking_app/lib/pages/report_detail/report_history.dart @@ -1,15 +1,81 @@ import 'package:flutter/material.dart'; +import 'package:flutter_easyloading/flutter_easyloading.dart'; +import 'package:flutter_easyrefresh/easy_refresh.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:functional_widget_annotation/functional_widget_annotation.dart'; +import 'package:marking_app/common/mixin/common.dart'; +import 'package:marking_app/common/model/common/base_structure_result_report.dart'; +import 'package:marking_app/common/model/report/report_student_history_record.dart'; +import 'package:marking_app/components/ReturnToHomepage.dart'; +import 'package:marking_app/routes/RouterManager.dart'; +import 'package:marking_app/utils/common_utils.dart'; +import 'package:marking_app/utils/easy_refresh/MyEmptyWidget.dart'; +import 'package:marking_app/utils/index.dart'; +import 'package:marking_app/utils/request/rest_client_report.dart'; +import 'package:syncfusion_flutter_datepicker/datepicker.dart'; class ReportHistory extends StatefulWidget { - const ReportHistory({Key? key}) : super(key: key); + final int userId; + final int classId; + final String studentName; + + const ReportHistory({Key? key, required this.classId, required this.userId,required this.studentName}) + : super(key: key); @override State createState() => _ReportHistoryState(); } -class _ReportHistoryState extends State { +class _ReportHistoryState extends State + with CommonMixin, TickerProviderStateMixin { bool isWork = true; + String startDataTime = + CommonUtils.getWeekStartDate().toString().substring(0, 10); + String endDataTime = CommonUtils.getWeekEndDate().toString().substring(0, 10); + String customTimeStr = '自定义'; + late TabController tabController; + List dataList = []; + late final EasyRefreshController refreshController; + + @override + void initState() { + print('userId=${widget.userId}&classId=${widget.classId}'); + super.initState(); + refreshController = EasyRefreshController(); + tabController = TabController(length: 3, vsync: this); + EasyLoading.show(status: 'loading...'); + getList(); + } + + void getList() async { + if (startDataTime == DateTime.now().toString().substring(0, 10) || + DateTime.parse(startDataTime).isAfter(DateTime.now())) { + DateTime now = DateTime.parse(startDataTime); + endDataTime = now.add(Duration(days: 1)).toString().substring(0, 10); + print(now.add(Duration(days: 1))); + } else { + endDataTime = DateTime.now().toString().substring(0, 10); + } + RestClientReport clientReport = await getClientReport(); + BaseStructureResultReport> res = + // 488491659239519, 488491659190341, '2023-03-08', '2024-04-19' + await clientReport.getStudentHistroyRecords( + widget.userId, widget.classId, startDataTime, endDataTime); + if (res.success) { + setState(() { + dataList = res.data!; + }); + } + + EasyLoading.dismiss(); + } + + @override + void dispose() { + // TODO: implement dispose + super.dispose(); + tabController.dispose(); + } @override Widget build(BuildContext context) { @@ -18,7 +84,7 @@ class _ReportHistoryState extends State { appBar: AppBar( backgroundColor: Colors.white, title: Text( - '已完成报告', + '${widget.studentName}已完成考试报告', style: TextStyle(fontSize: 14.r, color: Color(0xFF000000)), ), centerTitle: true, @@ -26,10 +92,13 @@ class _ReportHistoryState extends State { icon: Icon(Icons.arrow_back_ios, color: Colors.black), onPressed: () => Navigator.of(context).pop(), ), + actions: [ + ReturnToHomepage(), + ], ), body: Column( children: [ - Container( + /* Container( width: MediaQuery.of(context).size.width * 0.8, height: 40.r, margin: EdgeInsets.only( @@ -89,9 +158,400 @@ class _ReportHistoryState extends State { )), ], ), - ) + ),*/ + SizedBox( + height: 10.r, + ), + jobConditionFilter(context, + controller: tabController, + customTimeStr: customTimeStr, + customTime: tabController.index != 3 || + ((endDataTime == null || endDataTime == '') && + (startDataTime == null || startDataTime == '')) + ? null + : PickerDateRange( + startDataTime == null || startDataTime == '' + ? null + : DateTime.parse(startDataTime!), + endDataTime == null || endDataTime == '' + ? null + : DateTime.parse(endDataTime!), + ), onTimeFilter: (String? startTime, String? endTime) { + if (startTime == null && endTime == null) { + if (tabController.index == 3) { + tabController.animateTo(0); + } + startDataTime = ''; + endDataTime = ''; + customTimeStr = '自定义'; + } else { + EasyLoading.show(status: 'loading...'); + startDataTime = startTime != null ? startTime : ''; + endDataTime = endTime != null ? endTime : ''; + setState(() {}); + getList(); + } + + // _refreshController2.callRefresh(); + }, refreshTime: (value) { + if (value != null && value.startDate != null) { + customTimeStr = + value.startDate?.toString().substring(0, 10) ?? ''; + setState(() {}); + if (value.endDate != null) { + if (value.startDate!.year == value.endDate!.year) { + customTimeStr = value.startDate.toString().substring(5, 10) + + '~${value.endDate.toString().substring(5, 10)}'; + setState(() {}); + } else { + customTimeStr = + '$customTimeStr~${value.endDate?.toString().substring(0, 10)}'; + setState(() {}); + } + } + } + }), + Expanded( + child: Padding( + padding: EdgeInsets.symmetric(vertical: 14.r, horizontal: 14.r), + child: EasyRefresh( + firstRefresh: false, + taskIndependence: true, + controller: refreshController, + header: MaterialHeader(), + footer: TaurusFooter(), + onRefresh: () async { + getList(); + }, + child: dataList.length > 0 + ? ListView.builder( + itemCount: dataList.length, + itemBuilder: (context, index) { + ReportStudentHistoryRecord item = dataList[index]; + return InkWell( + onTap: (){ + RouterManager.router.navigateTo(context, '${RouterManager.completedReportPath}?examId=${item.examId}&studentNo=${item.studentExamNum}'); + }, + child: Container( + // padding: EdgeInsets.all(6.r), + margin: EdgeInsets.only(bottom: 10.r), + width: double.infinity, + decoration: BoxDecoration( + image: DecorationImage( + image: AssetImage( + 'assets/images/report_student_history_bg.png'), + fit: BoxFit.fill, + ), + border: Border.all( + width: 1.r, + color: Color.fromRGBO(46, 91, 255, 0.2)), + borderRadius: BorderRadius.circular(5.r), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.symmetric( + vertical: 10.r, + horizontal: 10.r, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.center, + children: [ + Text( + item.examName, + style: TextStyle( + fontSize: 12.sp, + color: Color(0xFF000000)), + ), + Spacer(), + Text( + item.examStartTime, + style: TextStyle( + fontSize: 12.sp, + color: Color(0xFF4A4A4A)), + ) + ], + ), + ), + SizedBox( + height: 2.r, + ), + Container( + padding: + EdgeInsets.symmetric(horizontal: 10.r), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(5.r), + ), + child: item.scoreInfo.length > 0 + ? Scrollbar( + // thumbVisibility:true, + child: SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: Row( + children: List.generate( + item.scoreInfo.length, (i) { + ScoreInfo score = + item.scoreInfo[i]; + return Row( + children: [ + Column( + children: [ + Container( + height: 22.r, + width: item.scoreInfo + .length > + 4 + ? 90.r + : (MediaQuery.of( + context) + .size + .width - + 48.r - + (item.scoreInfo + .length - 1) * + 1.5 + .r) / + item.scoreInfo + .length, + decoration: + BoxDecoration( + borderRadius: BorderRadius.only( + topLeft: i == 0 + ? Radius + .circular( + 4.r) + : Radius + .zero, + topRight: i == + item.scoreInfo.length - + 1 + ? Radius + .circular( + 4.r) + : Radius + .zero), + color: Color( + 0xFFECECEC), + ), + child: Center( + child: Text( + score.text, + style: TextStyle( + fontSize: + 12.sp, + color: Color( + 0xFF8A8A8A)), + ), + ), + ), + Container( + height: 30.r, + width: item.scoreInfo + .length > + 4 + ? 90.r + : (MediaQuery.of( + context) + .size + .width - + 48.r - + (item.scoreInfo + .length - 1) * + 1.5.r) / + item.scoreInfo + .length, + decoration: + BoxDecoration( + borderRadius: BorderRadius.only( + bottomLeft: i == + 0 + ? Radius + .circular( + 4.r) + : Radius + .zero, + bottomRight: i == + item.scoreInfo.length - + 1 + ? Radius + .circular( + 4.r) + : Radius + .zero), + color: Colors.white, + ), + child: Center( + child: Text( + score.value + .toString(), + style: TextStyle( + fontSize: + 12.sp, + color: Color( + 0xFF4A4A4A)), + ), + ), + ), + ], + ), + SizedBox( + width: i < + item.scoreInfo + .length - 1 + ? 1.5.r + : 0.r, + ), + ], + ); + }), + ), + ), + ) + : Center( + child: Text( + '-暂无数据-', + style: TextStyle( + fontSize: 12.sp, + color: Color(0xFF8A8A8A)), + )), + ), + SizedBox( + height: 20.r, + ), + ], + ), + ), + ); + }) + : MyEmptyWidget(), + ), + ), + ), ], ), ); } } + +@hwidget +Widget jobConditionFilter(BuildContext context, + {required TabController controller, + PickerDateRange? customTime, + required Function refreshTime, + required String customTimeStr, + required Function(String? startTime, String? endTime) onTimeFilter}) { + var customTimeState = PickerDateRange(null, null); + if (customTime != null) { + customTimeState = PickerDateRange( + customTime!.startDate != null ? customTime!.startDate : null, + customTime!.endDate != null ? customTime!.endDate : null); + } + + DateTime getMonthStartDate() { + DateTime now = DateTime.now(); + return DateTime(now.year, now.month, 1); // 获取当前月份的第一天 + } + + DateTime getMonthEndDate() { + DateTime now = DateTime.now(); + int nextMonth = now.month + 1; + if (nextMonth > 12) { + nextMonth = 1; + now = now.add(Duration(days: 31 - now.day)); // 跨年了,所以加到当前月的最后一天 + } else { + now = now.add(Duration( + days: DateTime(now.year, nextMonth, 0).day - + now.day)); // 加到下个月的第一天的前一天,即本月最后一天 + } + return now; + } + + return Container( + decoration: BoxDecoration( + // color: Color.fromRGBO(244, 244, 244, 1), + // border: Border(bottom: BorderSide(color: Color.fromRGBO(204, 204, 204, 1), width: 1)), + ), + child: Container( + alignment: Alignment.centerLeft, + decoration: BoxDecoration( + border: + Border(bottom: BorderSide(width: 1.r, color: Color(0xFFCCCCCC)))), + child: TabBar( + controller: controller, + unselectedLabelStyle: TextStyle( + fontSize: 12.sp, color: const Color.fromRGBO(102, 102, 102, 1)), + labelStyle: TextStyle( + fontSize: 12.sp, + fontWeight: FontWeight.bold, + color: Color.fromRGBO(116, 145, 253, 1), + ), + isScrollable: true, + labelColor: Color(0xFF7491FD), + unselectedLabelColor: Color(0xFF505E6E), + padding: EdgeInsets.symmetric(horizontal: 14.r), + // indicatorSize: TabBarIndicatorSize.label, // 设置指示器高度和标签一样高 + onTap: (int val) async { + switch (val) { + case 0: // 近一周 + onTimeFilter( + CommonUtils.getWeekStartDate().toString().substring(0, 10), + CommonUtils.getWeekEndDate().toString().substring(0, 10), + ); + break; + case 1: // 近一个月 + onTimeFilter( + getMonthStartDate().toString().substring(0, 10), + getMonthEndDate().toString().substring(0, 10), + ); + break; + default: // 自定义 + var dialogData = await showDialog( + context: context, + builder: (BuildContext context1) { + return Center( + child: Container( + color: Colors.white, + width: isPad() + ? ScreenUtil().screenWidth / 2 + : ScreenUtil().screenWidth / 1.3, + height: ScreenUtil().screenHeight / 2, + child: SfDateRangePicker( + showActionButtons: true, + confirmText: '确定', + cancelText: '取消', + onSubmit: (p0) { + print(p0); + Navigator.of(context1).pop(p0); + refreshTime(p0); + }, + onCancel: () { + Navigator.of(context1).pop(); + }, + selectionMode: DateRangePickerSelectionMode.range, + initialSelectedRange: customTimeState, + ), + ), + ); + }); + // startDate: 2024-03-04 18:47:00.117958, endDate: 2024-03-11 18:47:00.117986 + // if (dialogData != null && (dialogData.startDate != null || dialogData.endDate != null)) {} + onTimeFilter( + dialogData?.startDate?.toString().substring(0, 10), + dialogData?.endDate?.toString().substring(0, 10), + ); + // customTimeState = dialogData!; + customTimeState = dialogData ?? PickerDateRange(null, null); + } + }, + tabs: [ + const Tab(text: '近一周'), + const Tab(text: '近一月'), + Tab(text: customTimeStr), + ], + ), + ), + ); +} diff --git a/marking_app/lib/pages/report_detail/widgets/card_table.dart b/marking_app/lib/pages/report_detail/widgets/card_table.dart index d860f95..640d3fa 100644 --- a/marking_app/lib/pages/report_detail/widgets/card_table.dart +++ b/marking_app/lib/pages/report_detail/widgets/card_table.dart @@ -2,6 +2,7 @@ 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'; +import 'package:marking_app/routes/RouterManager.dart'; class CardList extends StatefulWidget { final List headList; @@ -11,6 +12,7 @@ class CardList extends StatefulWidget { final int? fixedRows; final int? fixedCols; final bool? isHtml; + final bool? smallQuestion; const CardList({ Key? key, @@ -19,6 +21,7 @@ class CardList extends StatefulWidget { this.showCardDetail, this.isScore = false, this.isHtml = false, + this.smallQuestion = false, this.fixedCols, this.fixedRows, }) : super(key: key); @@ -32,6 +35,7 @@ class _CardListState extends State { int? _sortColumnIndex; bool _sortAscending = true; + DataRow _getRow(int index, [Color? color]) { assert(index >= 0); var body = widget.bodyList[index]; @@ -40,16 +44,19 @@ class _CardListState extends State { color: color != null ? MaterialStateProperty.all(color) : null, cells: List.generate(widget.headList.length, (itemIndex) { var item = body[itemIndex]; + // print(item); return itemIndex == 0 && widget.isScore == false ?DataCell(Center( child: Text((index + 1).toString(), style: TextStyle(fontSize: 12.sp, color: Color(0xFF262626))), )): - DataCell(itemIndex == 2 && widget.isScore == false + DataCell((itemIndex == 2 && widget.isScore == false)||(itemIndex == 1 && widget.smallQuestion == true) ? InkWell( onTap: () { - if (widget.showCardDetail != null) { + if (widget.showCardDetail != null && itemIndex == 1 && item.toString().contains('{') && item['ExamNo'] != '') { + widget.showCardDetail!(context, index,studentNo:item['ExamNo']); + }else if (widget.showCardDetail != null && itemIndex == 2) { widget.showCardDetail!(context, index); } }, @@ -58,7 +65,7 @@ class _CardListState extends State { children: [ Expanded( child: Center( - child: Text(item.toString(), + child: Text(item.toString().contains('{')?item['Name']:item.toString(), style: TextStyle( fontSize: 12.sp, color: Color(0xFF262626))), ), @@ -74,16 +81,24 @@ class _CardListState extends State { ], ), ) - : Center( - child: Padding( - padding: EdgeInsets.symmetric(horizontal: 5.r), - child: - widget.isHtml == true?HtmlWidget(item.toString(),textStyle: TextStyle(fontSize: 12.sp,color: Color(0xFF262626)),): - Text(item.toString(), - style: - TextStyle(fontSize: 12.sp, color: Color(0xFF262626))), + : InkWell( + onTap: (){ + if (widget.showCardDetail != null && item.toString().contains('{') && item['ExamNo'] != '') { + // print(item); + widget.showCardDetail!(context, index,studentNo:item['ExamNo']); + } + }, + child: Center( + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 5.r), + child: + widget.isHtml == true?HtmlWidget(item.toString().contains('{')?item['Name']: item.toString(),textStyle: TextStyle(fontSize: 12.sp,color: item.toString().contains('{') && item['ExamNo'] != ''?Color(0xFF6988FD):Color(0xFF262626)),): + Text(item.toString().contains('{')?item['Name']:item.toString(), + style: + TextStyle(fontSize: 12.sp, color: Color(0xFF262626))), + ), ), - )); + )); }), ); } diff --git a/marking_app/lib/pages/report_detail/widgets/complete_table.dart b/marking_app/lib/pages/report_detail/widgets/complete_table.dart new file mode 100644 index 0000000..fa8bc0e --- /dev/null +++ b/marking_app/lib/pages/report_detail/widgets/complete_table.dart @@ -0,0 +1,161 @@ +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'; +import 'package:marking_app/common/model/report/report_marking_detail.dart'; +import 'package:photo_view/photo_view.dart'; + +class CompleteTable extends StatefulWidget { + final List bodyList; + final int? fixedRows; + final int? fixedCols; + + const CompleteTable({ + Key? key, + required this.bodyList, + this.fixedCols, + this.fixedRows, + }) : super(key: key); + + @override + State createState() => _CompleteTableState(); +} + +class _CompleteTableState extends State { + final ScrollController _controller = ScrollController(); + int? _sortColumnIndex; + bool _sortAscending = true; + final List headList = ['题号','小题分','得分','用户答案','正确答案']; + + showImg(String imgUrl) { + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + // insetPadding: EdgeInsets.symmetric(vertical: 10.r,horizontal: 45.r), + backgroundColor: Colors.transparent, + contentPadding: EdgeInsets.all(0), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.circular(15.r))), + content: Container( + width: MediaQuery.of(context).size.width - 48.r, + height: MediaQuery.of(context).size.height * 0.6, + color: Colors.white, + child: PhotoView(imageProvider: NetworkImage(imgUrl),backgroundDecoration: BoxDecoration(color: Colors.transparent),)), + ); + }, + ); + } + + DataRow _getRow(int index, [Color? color]) { + assert(index >= 0); + QuestionAnswers body = 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(body.questionNum, + style: + TextStyle(fontSize: 12.sp, color: Color(0xFF262626))), + ), + )), + DataCell( + Center( + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 5.r), + child: Text(body.totalScore.toString(), + style: + TextStyle(fontSize: 12.sp, color: Color(0xFF262626))), + ), + )), + DataCell( + Center( + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 5.r), + child: Text(body.score.toString(), + style: + TextStyle(fontSize: 12.sp, color: Color(0xFF262626))), + ), + )), + DataCell( + Center( + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 5.r), + child: + body.yourAnswer.contains('http')? + InkWell( + onTap: (){ + showImg(body.yourAnswer); + }, + child: Text('查看原题',style: TextStyle(fontSize: 12.sp,color: Color(0xFF6988FD)),), + ): + Text(body.yourAnswer, + style: + TextStyle(fontSize: 12.sp, color: Color(0xFF262626))) + , + ), + )), + DataCell( + Center( + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 5.r), + child: Text(body.answer, + style: + TextStyle(fontSize: 12.sp, color: Color(0xFF262626))), + ), + )), + ], + ); + } + + @override + Widget build(BuildContext context) { + return DataTable2( + dividerThickness: 0, + scrollController: _controller, + columnSpacing: 0, + horizontalMargin: 0, + dataRowHeight:40.r, + headingRowHeight: 30.r, + bottomMargin: 0, + border: TableBorder( + left: BorderSide( + width: 1, color: Color(0xFFEAEAEA), style: BorderStyle.solid), + right: BorderSide( + width: 1, color: Color(0xFFEAEAEA), style: BorderStyle.solid), + horizontalInside: BorderSide( + width: 1, color: Color(0xFFEAEAEA), style: BorderStyle.solid), + bottom: BorderSide( + width: 1, color: Color(0xFFEAEAEA), style: BorderStyle.solid), + verticalInside: BorderSide( + width: 1, color: Color(0xFFEAEAEA), style: BorderStyle.solid)), + headingRowColor: MaterialStateProperty.resolveWith((states) => + widget.fixedCols! > 0 ? Color(0xFFF0F3FF) : Colors.transparent), + headingRowDecoration: BoxDecoration(color: Color(0xFFF0F3FF)), + fixedColumnsColor: Color(0xFFF0F3FF), + 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(headList.length, (index) { + var item = 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 - 48.r)/headList.length, + ); + }), + rows: List.generate(widget.bodyList.length, + (index) => _getRow(index, Colors.transparent))); + } +} diff --git a/marking_app/lib/pages/report_detail/widgets/report_card_dialog.dart b/marking_app/lib/pages/report_detail/widgets/report_card_dialog.dart index a142e72..993a77e 100644 --- a/marking_app/lib/pages/report_detail/widgets/report_card_dialog.dart +++ b/marking_app/lib/pages/report_detail/widgets/report_card_dialog.dart @@ -10,6 +10,7 @@ import 'package:marking_app/common/model/report/report_card.dart'; import 'package:marking_app/common/model/report/report_marking_detail.dart'; import 'package:marking_app/common/model/report/report_marking_detail_params.dart'; import 'package:marking_app/pages/report_detail/widgets/custom_rect.dart'; +import 'package:marking_app/routes/RouterManager.dart'; import 'package:marking_app/utils/easy_refresh/MyEmptyWidget.dart'; import 'package:marking_app/utils/request/rest_client_report.dart'; @@ -32,6 +33,7 @@ class _ReportCardDialogState extends ConsumerState int currentSubjectId = 0; final viewTransformationController = TransformationController(); + bool isList = false; void initState() { final zoomFactor = 0.5; @@ -68,7 +70,6 @@ class _ReportCardDialogState extends ConsumerState if(res.data!=null){ examOrigin = res.data!.examOriginPapers[0]; examOriginList = res.data!.examOriginPapers; - // print('examOrigin!.width=${examOrigin!.width}'); }else{ examOriginList = []; examOrigin = null; @@ -83,28 +84,66 @@ class _ReportCardDialogState extends ConsumerState return Container( width: MediaQuery.of(context).size.width, height: MediaQuery.of(context).size.height, - child: Column(children: [ - Padding( - padding: EdgeInsets.only(top: 10.r, left: 20.r, right: 20.r), + color: Color(0xFFEDEFFF), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + widget.cardItem.name, + style: TextStyle( + fontSize: 14.sp, + color: Color(0xFF6787FD), + fontWeight: FontWeight.w500), + ), + InkWell( + onTap: (){ + Navigator.pop(context); + }, + child: Icon(Icons.close,color: Colors.grey,size: 20.r,)) + ], + ), + Text( + '张沫凡重庆八中2023.2024 高二定时训练', + style: TextStyle( + fontSize: 14.sp, + color: Color(0xFF6787FD), + fontWeight: FontWeight.w500), + ), + InkWell( + onTap: (){ + RouterManager.router.navigateTo(context, RouterManager.reportHistoryPath); + }, + child: Container( + padding: EdgeInsets.symmetric(vertical: 3.r,horizontal: 5.r), + decoration: BoxDecoration( + border: Border.all(width: 1.r,color: Color(0xFF6988FD)), + borderRadius: BorderRadius.circular(5.r), + ), + child: Center( + child: Text('历次成绩',style: TextStyle(fontSize: 10.r,color: Color(0xFF6988FD)),), + ), + ), + ), + Container( + margin: EdgeInsets.only(top: 10.r, left: 14.r, right: 14.r), + padding: EdgeInsets.symmetric(horizontal: 10.r), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(4.r), + color: Colors.white, + boxShadow: [ + BoxShadow( + color: const Color.fromRGBO(0, 0, 0, 0.1), + offset: Offset(0, 0), //阴影y轴偏移量 + blurRadius: 2, //阴影模糊程度 + spreadRadius: 1, //阴影扩散程度 + ) + ], + ), child: Column( children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - widget.cardItem.name, - style: TextStyle( - fontSize: 14.sp, - color: Color(0xFF6787FD), - fontWeight: FontWeight.w500), - ), - InkWell( - onTap: (){ - Navigator.pop(context); - }, - child: Icon(Icons.close,color: Colors.grey,size: 20.r,)) - ], - ), Container( margin: EdgeInsets.only(top: 10.r), width: double.infinity, @@ -119,7 +158,7 @@ class _ReportCardDialogState extends ConsumerState (index) { var item = widget.headList[index]; return Container( - width: (MediaQuery.of(context).size.width - 90.r) / 7, + width: (MediaQuery.of(context).size.width - 104.r) / 7, child: _subjectText(item)); }), ), @@ -133,20 +172,20 @@ class _ReportCardDialogState extends ConsumerState mainAxisAlignment: MainAxisAlignment.start, children: [ Container( - width: (MediaQuery.of(context).size.width - 90.r) / 7, + width: (MediaQuery.of(context).size.width - 104.r) / 7, child: _subjectText( widget.cardItem.totalScore.toString())), Container( - width: (MediaQuery.of(context).size.width - 90.r) / 7, + width: (MediaQuery.of(context).size.width - 104.r) / 7, child: _subjectText( widget.cardItem.totalClassRanking.toString())), Container( - width: (MediaQuery.of(context).size.width - 90.r) / 7, + width: (MediaQuery.of(context).size.width - 104.r) / 7, child: _subjectText( widget.cardItem.totalRanking.toString())), SizedBox( width: - (MediaQuery.of(context).size.width - 90.r) / 7 * 4, + (MediaQuery.of(context).size.width - 104.r) / 7 * 4, child: Row( children: List.generate( widget.cardItem.subjectDetails.length > 4 @@ -156,7 +195,7 @@ class _ReportCardDialogState extends ConsumerState var subject = widget.cardItem.subjectDetails[index]; return Container( width: - (MediaQuery.of(context).size.width - 90.r) / + (MediaQuery.of(context).size.width - 104.r) / 7, child: _subjectText(subject.score)); }), @@ -177,7 +216,7 @@ class _ReportCardDialogState extends ConsumerState List.generate(widget.headList.length - 7, (index) { var item = widget.headList[index + 7]; return Container( - width: (MediaQuery.of(context).size.width - 90.r) / 7, + width: (MediaQuery.of(context).size.width - 104.r) / 7, child: _subjectText(item)); }), ), @@ -194,7 +233,7 @@ class _ReportCardDialogState extends ConsumerState widget.cardItem.subjectDetails.length - 4, (index) { var subject = widget.cardItem.subjectDetails[index + 4]; return Container( - width: (MediaQuery.of(context).size.width - 90.r) / 7, + width: (MediaQuery.of(context).size.width - 104.r) / 7, child: _subjectText(subject.score)); }), ), @@ -202,161 +241,276 @@ class _ReportCardDialogState extends ConsumerState ], ), ), + SizedBox(height: 10.r,), Expanded( - child: Container( - margin: EdgeInsets.only(top: 0.r), - padding: EdgeInsets.symmetric(vertical: 5.r, horizontal: 20.r), + child: Stack( + children: [ + Container( + margin: EdgeInsets.only(top: 10.r, left: 14.r, right: 14.r), + padding: EdgeInsets.symmetric(vertical:15.r,horizontal: 10.r), + /* margin: EdgeInsets.only(top: 0.r), + padding: EdgeInsets.symmetric(vertical: 5.r, horizontal: 20.r),*/ width: double.infinity, - decoration: BoxDecoration( - color: Color(0xFFEFF1FF), - borderRadius: BorderRadius.only( - bottomLeft: Radius.circular(15.r), - bottomRight: Radius.circular(15.r))), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(4.r), + color: Colors.white, + boxShadow: [ + BoxShadow( + color: const Color.fromRGBO(0, 0, 0, 0.1), + offset: Offset(0, 0), //阴影y轴偏移量 + blurRadius: 2, //阴影模糊程度 + spreadRadius: 1, //阴影扩散程度 + ) + ], + ), child: Column( - children: [ - SizedBox( - height: 30.r, - width: MediaQuery.of(context).size.width, - child: ListView.builder( - itemBuilder: (BuildContext context, int index) { - var item = subjectList[index]; - return InkWell( - onTap: () { - setState(() { - subjectList.forEach((element) { - element.isCheck = false; - }); - item.isCheck = true; - currentSubjectId = item.value; - EasyLoading.show(status: 'loading...'); - getImageDetail(); - }); - }, - child: Container( - width: 30.r, - height: 30.r, - margin: EdgeInsets.only( - right: index == subjectList.length - ? 0 - : (MediaQuery.of(context).size.width - - 30.r * 9 - - 110.r) / - 8), - decoration: BoxDecoration( - color: item.isCheck - ? Color(0xFF6787FD) - : Color(0xFFFFFFFF), - shape: BoxShape.circle, - // borderRadius: BorderRadius.all(Radius.circular(13.r)), - ), - child: Center( - child: Text( - item.text, - style: TextStyle( - fontSize: 11.sp, - color: item.isCheck - ? Colors.white - : Color(0xFF667095), - fontWeight: FontWeight.w400), - )), - ), - ); - }, - itemCount: subjectList.length, - scrollDirection: Axis.horizontal, - ), - ), - Expanded( - child: examOrigin != null && examOrigin!.imageUrl != '' - ? Padding( - padding: EdgeInsets.only(top:5.r), - child: InteractiveViewer( - transformationController: viewTransformationController, - constrained: false, - boundaryMargin: EdgeInsets.all(140.r), - minScale: 0.1, // 最小缩放 - maxScale: 4.0, // 最大缩放 - child: CustomRect(examOrigin!)), - ) - : MyEmptyWidget(), - ), - SizedBox(height: 6.r,), - Row( - mainAxisAlignment: MainAxisAlignment.center, children: [ - InkWell( - onTap: () { - var num = examOrigin!.pageIndex; - if (num > 1) { - setState(() { - examOrigin = examOriginList[num - 1 - 1]; - }); - } - }, - child:Container( - padding: EdgeInsets.symmetric( - vertical: 2.r, horizontal: 5.r), - decoration: BoxDecoration( - border: Border.all( - color: examOrigin != null && examOrigin!.pageIndex > 1?Color(0xFF6787FD): Color(0xFFB3B9B9), - width: 1.r), - borderRadius: BorderRadius.all( - Radius.circular(2.r)), - ), - child: Text( - '上一页', - style: TextStyle( - color: examOrigin != null && examOrigin!.pageIndex > 1?Color(0xFF6787FD): Color(0xFFB3B9B9), - ), - ), - ), - /* Image.asset( - 'assets/images/report_left_icon.png', - width: 33.r, - height: 33.r, - )*/ - ), SizedBox( - width: 15.r, - ), - InkWell( - onTap: () { - var num = examOrigin!.pageIndex; - if (num < examOriginList.length) { - setState(() { - examOrigin = examOriginList[num]; - }); - - } + height: 30.r, + width: MediaQuery.of(context).size.width, + child: ListView.builder( + itemBuilder: (BuildContext context, int index) { + var item = subjectList[index]; + return InkWell( + onTap: () { + setState(() { + subjectList.forEach((element) { + element.isCheck = false; + }); + item.isCheck = true; + currentSubjectId = item.value; + EasyLoading.show(status: 'loading...'); + getImageDetail(); + }); + }, + child: Container( + width: 30.r, + height: 30.r, + margin: EdgeInsets.only( + right: index == subjectList.length + ? 0 + : (MediaQuery.of(context).size.width - + 30.r * 9 - + 104.r) / + 8), + decoration: BoxDecoration( + color: item.isCheck + ? Color(0xFF6787FD) + : Color(0xFFFFFFFF), + shape: BoxShape.circle, + // borderRadius: BorderRadius.all(Radius.circular(13.r)), + ), + child: Center( + child: Text( + item.text, + style: TextStyle( + fontSize: 11.sp, + color: item.isCheck + ? Colors.white + : Color(0xFF667095), + fontWeight: FontWeight.w400), + )), + ), + ); }, - child: Container( - padding: EdgeInsets.symmetric( - vertical: 2.r, horizontal: 5.r), - decoration: BoxDecoration( - border: Border.all( - color: examOrigin != null && examOrigin!.pageIndex < examOriginList.length?Color(0xFF6787FD): Color(0xFFB3B9B9), - width: 1.r), - borderRadius: BorderRadius.all( - Radius.circular(2.r)), - ), - child: Text( - '下一页', - style: TextStyle( - color: examOrigin != null && examOrigin!.pageIndex < examOriginList.length?Color(0xFF6787FD): Color(0xFFB3B9B9), + itemCount: subjectList.length, + scrollDirection: Axis.horizontal, + ), + ), + Expanded( + child: examOrigin != null && examOrigin!.imageUrl != '' + ? !isList?Padding( + padding: EdgeInsets.only(top:5.r), + child: InteractiveViewer( + transformationController: viewTransformationController, + constrained: false, + boundaryMargin: EdgeInsets.all(140.r), + minScale: 0.1, // 最小缩放 + maxScale: 4.0, // 最大缩放 + child: CustomRect(examOrigin!)), + ):Text('list') + : MyEmptyWidget(), + ), + SizedBox(height: 6.r,), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Flexible( + flex: 1, + child: InkWell( + onTap:(){ + isList = false; + setState(() { + + }); + }, + child: Container( + height: 27.r, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(4.r), + color: !isList?Color(0xFF6988FD):Color(0xFFEDEFFF), + ), + child: Center( + child: Text('查看原卷',style: TextStyle(fontSize: 12.sp,color: !isList?Colors.white:Color(0xFF7B7B7E)),), + ), ), ), ), - /* Image.asset( - 'assets/images/report_right_icon.png', - width: 33.r, - height: 33.r, - )*/ + SizedBox(width: 20.r,), + Flexible( + flex: 1, + child: InkWell( + onTap: (){ + isList = true; + setState(() { + + }); + }, + child: Container( + height: 27.r, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(4.r), + color: isList?Color(0xFF6988FD):Color(0xFFEDEFFF), + ), + child: Center( + child: Text('查看列题',style: TextStyle(fontSize: 12.sp,color: isList?Colors.white:Color(0xFF7B7B7E)),), + ), + ), + ), + ), + ], ), + /*if(!isList) + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + InkWell( + onTap: () { + var num = examOrigin!.pageIndex; + if (num > 1) { + setState(() { + examOrigin = examOriginList[num - 1 - 1]; + }); + } + }, + child:Column( + children: [ + Opacity( + opacity: examOrigin != null && examOrigin!.pageIndex > 1?1:0.3, + child: Image.asset('assets/images/report_left_icon.png',width: 33.r,height: 33.r,)), + Container( + padding: EdgeInsets.symmetric( horizontal: 5.r), + decoration: BoxDecoration( + *//* border: Border.all( + color: examOrigin != null && examOrigin!.pageIndex > 1?Color(0xFF6787FD): Color(0xFFB3B9B9), + width: 1.r),*//* + borderRadius: BorderRadius.all( + Radius.circular(2.r)), + ), + child: Text( + '上一页', + style: TextStyle( + color: examOrigin != null && examOrigin!.pageIndex > 1?Color(0xFF6787FD): Color(0xFFB3B9B9), + ), + ), + ), + ], + ), + *//* Image.asset( + 'assets/images/report_left_icon.png', + width: 33.r, + height: 33.r, + )*//* + ), + SizedBox( + width: 15.r, + ), + InkWell( + onTap: () { + var num = examOrigin!.pageIndex; + if (num < examOriginList.length) { + setState(() { + examOrigin = examOriginList[num]; + }); + + } + }, + child: Column( + children: [ + Opacity( + opacity:examOrigin != null && examOrigin!.pageIndex < examOriginList.length?1:0.3, + child: Image.asset('assets/images/report_right_icon.png',width: 33.r,height: 33.r,)), + Container( + padding: EdgeInsets.symmetric(horizontal: 5.r), + decoration: BoxDecoration( + *//* border: Border.all( + color: examOrigin != null && examOrigin!.pageIndex < examOriginList.length?Color(0xFF6787FD): Color(0xFFB3B9B9), + width: 1.r),*//* + borderRadius: BorderRadius.all( + Radius.circular(2.r)), + ), + child: Text( + '下一页', + style: TextStyle( + color: examOrigin != null && examOrigin!.pageIndex < examOriginList.length?Color(0xFF6787FD): Color(0xFFB3B9B9), + ), + ), + ), + ], + ), + *//* Image.asset( + 'assets/images/report_right_icon.png', + width: 33.r, + height: 33.r, + )*//* + ), + ], + ),*/ ], - ), - ], ), - )) + ), + if(!isList) + Positioned( + left:0.r, + top: MediaQuery.of(context).size.height/4, + child: InkWell( + onTap: () { + var num = examOrigin!.pageIndex; + if (num > 1) { + setState(() { + examOrigin = examOriginList[num - 1 - 1]; + }); + } + }, + child:Opacity( + opacity: examOrigin != null && examOrigin!.pageIndex > 1?1:0.3, + child: Image.asset('assets/images/report_left_icon.png',width: 33.r,height: 33.r,)), + ),), + if(!isList) + Positioned( + right: 0, + top: MediaQuery.of(context).size.height/4, + child: InkWell( + onTap: () { + var num = examOrigin!.pageIndex; + if (num < examOriginList.length) { + setState(() { + examOrigin = examOriginList[num]; + }); + + } + }, + child: Opacity( + opacity:examOrigin != null && examOrigin!.pageIndex < examOriginList.length?1:0.3, + child: Image.asset('assets/images/report_right_icon.png',width: 33.r,height: 33.r,)), + /* Image.asset( + 'assets/images/report_right_icon.png', + width: 33.r, + height: 33.r, + )*/ + ),) + ], + )) ]), ); } diff --git a/marking_app/lib/routes/RouterManager.dart b/marking_app/lib/routes/RouterManager.dart index 2c2ca3a..c14afcd 100644 --- a/marking_app/lib/routes/RouterManager.dart +++ b/marking_app/lib/routes/RouterManager.dart @@ -36,7 +36,6 @@ import 'package:marking_app/pages/mine/index.dart'; import 'package:marking_app/pages/mine/log_off.dart'; import 'package:marking_app/pages/mine/other_pages/index.dart'; import 'package:marking_app/pages/other/agreement_page.dart'; -import 'package:marking_app/pages/register/index.dart'; import 'package:marking_app/pages/report_detail/index.dart'; import 'package:marking_app/pages/report_detail/report_history.dart'; import 'package:marking_app/pages/reports/report_class_teacher.dart'; @@ -44,7 +43,8 @@ import 'package:marking_app/pages/reports/report_personal_subject.dart'; import 'package:marking_app/pages/reports/report_subject_teacher.dart'; import 'package:marking_app/utils/const_text.dart'; import 'package:marking_app/utils/the_global.dart'; - +import 'package:marking_app/pages/register/index.dart'; +import 'package:marking_app/pages/report_detail/completed_report.dart'; import '../utils/index.dart'; class RouterManager { @@ -89,6 +89,7 @@ class RouterManager { static const String jobKnowledgePointsDetailPath = '/homework_correction/job_knowledge_points_detail'; static const String answerTrajectoryPath = '/homework_correction/answer_trajectory'; static const String answerTrajectoryJobDetailPath = '/homework_correction/answer_trajectory_job_detail'; + static const String completedReportPath = '/report_detail/completed_report'; // TheMine static final FluroRouter router = FluroRouter(); @@ -111,14 +112,18 @@ class RouterManager { } // 启动页 - static final _startUpPageHandler = Handler(handlerFunc: (BuildContext? context, Map> params) => const StartUpPage()); + static final _startUpPageHandler = + Handler(handlerFunc: (BuildContext? context, Map> params) => const StartUpPage()); // 主页 - static final _mainPageHandler = Handler(handlerFunc: (BuildContext? context, Map> params) => const TheMainPage()); + static final _mainPageHandler = + Handler(handlerFunc: (BuildContext? context, Map> params) => const TheMainPage()); // 登录页 - static final _loginPageHandler = Handler(handlerFunc: (BuildContext? context, Map> params) => const TheLogin()); + static final _loginPageHandler = + Handler(handlerFunc: (BuildContext? context, Map> params) => const TheLogin()); // 阅卷进度页面 static final _progressPageHandler = Handler( - handlerFunc: (BuildContext? context, Map> params) => Progress(int.parse(params['examSubjectId']![0]), params['name']![0])); + handlerFunc: (BuildContext? context, Map> params) => + Progress(int.parse(params['examSubjectId']![0]), params['name']![0])); // 回评页面 static final _reviewPageHandler = Handler(handlerFunc: (BuildContext? context, Map> params) { int markingUserId = int.parse(params['markingUserId']![0]); @@ -137,8 +142,11 @@ class RouterManager { // 回评异常页面 static final _reviewAbnormalPageHandler = Handler( - handlerFunc: (BuildContext? context, Map> params) => - ProgressAbnormal(int.parse(params['examSubjectId']![0]), params['markingId']![0], params['name']![0], params['questionNum']![0])); + handlerFunc: (BuildContext? context, Map> params) => ProgressAbnormal( + int.parse(params['examSubjectId']![0]), + params['markingId']![0], + params['name']![0], + params['questionNum']![0])); // 阅卷页面 static final _markingDoPageHandler = Handler(handlerFunc: (BuildContext? context, Map> params) { try { @@ -180,7 +188,8 @@ class RouterManager { } }); // 批阅作业页面 - static final _markingHomeworkDoPageHandler = Handler(handlerFunc: (BuildContext? context, Map> params) { + static final _markingHomeworkDoPageHandler = + Handler(handlerFunc: (BuildContext? context, Map> params) { try { int taskId = int.parse(params['taskId']![0]); int jobId = int.parse(params['jobId']![0]); @@ -224,7 +233,8 @@ class RouterManager { handlerFunc: (BuildContext? context, Map> params) => const OhterPage(), ); - static final _reportClassTeacherPageHandler = Handler(handlerFunc: (BuildContext? context, Map> params) { + static final _reportClassTeacherPageHandler = + Handler(handlerFunc: (BuildContext? context, Map> params) { int examId = int.parse(params['examId']![0]); return ReportClassTeacher(examId: examId); @@ -294,7 +304,7 @@ class RouterManager { if (params['gradeId'] != null && params['gradeId']?[0] != null && params['gradeId']![0] != 'null') { gradeId = int.parse(params['gradeId']![0]); } - return QuickDataCheckPage(jobId: jobId, className: className, gradeName: gradeName, schoolId: schoolId, gradeId: gradeId); + return QuickDataCheckPage(jobId: jobId, className: className,gradeName:gradeName,schoolId:schoolId,gradeId:gradeId); }, ); @@ -313,7 +323,7 @@ class RouterManager { String groupId = params['groupId']![0]; String title = params['title']![0]; String? page = params['page']?[0]; - return JobPriorityReviewSet(groupId: groupId, title: title, page: page); + return JobPriorityReviewSet(groupId: groupId,title:title,page:page); }, ); @@ -321,7 +331,7 @@ class RouterManager { static final _jobStudentGroupPageHandler = Handler( handlerFunc: (BuildContext? context, Map> params) { String page = params['page']![0]; - return JobStudentGroup(page: page); + return JobStudentGroup(page:page); }, ); //作业收藏页面 @@ -338,7 +348,7 @@ class RouterManager { if (params['gradeId'] != null && params['gradeId']?[0] != null && params['gradeId']![0] != 'null') { gradeId = int.parse(params['gradeId']![0]); } - return JobFavorite(jobId: jobId, gradeId: gradeId, schoolId: schoolId, className: className, jobName: jobName); + return JobFavorite(jobId: jobId, gradeId: gradeId, schoolId: schoolId, className: className,jobName:jobName); }, ); @@ -347,7 +357,7 @@ class RouterManager { handlerFunc: (BuildContext? context, Map> params) { String studentName = params['studentName']![0]; int studentId = int.parse(params['studentId']![0]); - return JobPersonalDetail(studentId: studentId, studentName: studentName); + return JobPersonalDetail(studentId: studentId,studentName:studentName); }, ); @@ -359,7 +369,7 @@ class RouterManager { // 学生报告详情 static final _reportCardDialogPathHandler = Handler( handlerFunc: (BuildContext? context, Map> params) { - /* String studentName = params['studentName']![0]; + /* String studentName = params['studentName']![0]; int studentId = int.parse(params['studentId']![0]); return ReportCardDialog(studentId: studentId,studentName:studentName);*/ }, @@ -367,9 +377,10 @@ class RouterManager { // 学生历史报告 static final _reportHistoryPathHandler = Handler( handlerFunc: (BuildContext? context, Map> params) { - /* String studentName = params['studentName']![0]; - int studentId = int.parse(params['studentId']![0]);*/ - return ReportHistory(); + int classId = int.parse(params['classId']![0]); + int userId = int.parse(params['userId']![0]); + String studentName = params['studentName']![0]; + return ReportHistory(classId:classId,userId:userId,studentName:studentName); }, ); @@ -391,9 +402,9 @@ class RouterManager { // 知识点掌握详情 static final _jobKnowledgePointsDetailPathHandler = Handler( handlerFunc: (BuildContext? context, Map> params) { - String knowledgeName = params['knowledgeName']![0]; + String knowledgeName = params['knowledgeName']![0]; int knowledgeId = int.parse(params['knowledgeId']![0]); - return JobKnowledgePointsDetail(knowledgeName: knowledgeName, knowledgeId: knowledgeId); + return JobKnowledgePointsDetail(knowledgeName:knowledgeName,knowledgeId:knowledgeId); }, ); @@ -410,9 +421,19 @@ class RouterManager { int jobId = int.parse(params['jobId']![0]); String jobName = params['jobName']![0]; String genderName = params['genderName']![0]; - return AnswerTrajectoryJobDetail(jobId: jobId, jobName: jobName, genderName: genderName); + return AnswerTrajectoryJobDetail(jobId:jobId,jobName:jobName,genderName:genderName); }, ); + + //已完成考试报告 + static final _completedReportPathHandler = Handler( + handlerFunc: (BuildContext? context, Map> params) { + int examId = int.parse(params['examId']![0]); + String studentNo = params['studentNo']![0]; + return CompletedReport(examId:examId,studentNo:studentNo); + }, + ); + // 开始阅卷页面 // static final _doMarkingPapers = Handler(handlerFunc: (BuildContext? context, Map> params) => MarkingPapers()); @@ -430,22 +451,30 @@ class RouterManager { router.define(markingReviewPath, handler: _reviewPageHandler, transitionType: TransitionType.material); router.define(markingJobReviewPath, handler: _reviewJobPageHandler, transitionType: TransitionType.material); router.define(markingDoPath, handler: _markingDoPageHandler, transitionType: TransitionType.material); - router.define(markingHomeworkDoPath, handler: _markingHomeworkDoPageHandler, transitionType: TransitionType.material); - router.define(markingReviewAbnormalPath, handler: _reviewAbnormalPageHandler, transitionType: TransitionType.material); + router.define(markingHomeworkDoPath, + handler: _markingHomeworkDoPageHandler, transitionType: TransitionType.material); + router.define(markingReviewAbnormalPath, + handler: _reviewAbnormalPageHandler, transitionType: TransitionType.material); router.define(agreementPath, handler: _agreementPageHandler, transitionType: TransitionType.material); router.define(ohterMainPagePath, handler: _ohterMainPageHandler, transitionType: TransitionType.material); - router.define(reportClassTeacherPath, handler: _reportClassTeacherPageHandler, transitionType: TransitionType.material); - router.define(reportSubjectTeacherPath, handler: _reportSubjectTeacherPageHandler, transitionType: TransitionType.material); - router.define(reportPersonalSubjectPath, handler: _reportPersonalSubjectPageHandler, transitionType: TransitionType.material); + router.define(reportClassTeacherPath, + handler: _reportClassTeacherPageHandler, transitionType: TransitionType.material); + router.define(reportSubjectTeacherPath, + handler: _reportSubjectTeacherPageHandler, transitionType: TransitionType.material); + router.define(reportPersonalSubjectPath, + handler: _reportPersonalSubjectPageHandler, transitionType: TransitionType.material); router.define(userMinePath, handler: _userMinePageHandler, transitionType: TransitionType.material); 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(jobListParticipateInClassPath, handler: _jobListParticipateInClassHandler, transitionType: TransitionType.material); + router.define(jobListParticipateInClassPath, + handler: _jobListParticipateInClassHandler, transitionType: TransitionType.material); router.define(quickDataCheckPath, handler: _quickDataCheckPageHandler, transitionType: TransitionType.material); - router.define(quickCheckPersonalPath, handler: _quickCheckPersonalPageHandler, transitionType: TransitionType.material); - router.define(jobPriorityReviewSetPath, handler: _jobPriorityReviewSetPageHandler, transitionType: TransitionType.material); + router.define(quickCheckPersonalPath, + handler: _quickCheckPersonalPageHandler, transitionType: TransitionType.material); + router.define(jobPriorityReviewSetPath, + handler: _jobPriorityReviewSetPageHandler, transitionType: TransitionType.material); router.define(jobStudentGroupPath, handler: _jobStudentGroupPageHandler, transitionType: TransitionType.material); router.define(jobFavoritePagePath, handler: _jobFavoritePagePathHandler, transitionType: TransitionType.material); router.define(jobPersonalDetailPath, handler: _jobPersonalDetailPathHandler, transitionType: TransitionType.material); @@ -458,6 +487,9 @@ class RouterManager { router.define(jobKnowledgePointsDetailPath, handler: _jobKnowledgePointsDetailPathHandler, transitionType: TransitionType.material); router.define(answerTrajectoryPath, handler: _answerTrajectoryPathHandler, transitionType: TransitionType.material); router.define(answerTrajectoryJobDetailPath, handler: _answerTrajectoryJobDetailPathHandler, transitionType: TransitionType.material); + router.define(completedReportPath, handler: _completedReportPathHandler, transitionType: TransitionType.material); + +// getTransition() router.notFoundHandler = Handler(handlerFunc: (BuildContext? context, Map> params) { toPrint(val: "ROUTE WAS NOT FOUND !!!"); diff --git a/marking_app/lib/utils/request/rest_client_report.dart b/marking_app/lib/utils/request/rest_client_report.dart index bd07c13..8bc43c5 100644 --- a/marking_app/lib/utils/request/rest_client_report.dart +++ b/marking_app/lib/utils/request/rest_client_report.dart @@ -30,6 +30,8 @@ import 'package:marking_app/common/model/report/report_for_subject_teacher_param import 'package:marking_app/common/model/report/report_home_model.dart'; import 'package:marking_app/common/model/report/report_marking_detail.dart'; import 'package:marking_app/common/model/report/report_marking_detail_params.dart'; +import 'package:marking_app/common/model/report/report_student_history_record.dart'; +import 'package:marking_app/common/model/report/report_student_info.dart'; import 'package:marking_app/common/model/report/small_question.dart'; import 'package:marking_app/common/model/user/user_info_report.dart'; import 'package:retrofit/retrofit.dart' as the_retrofit; @@ -143,4 +145,20 @@ abstract class RestClientReport { Future> getQuestion( @the_retrofit.Body() ReportCardParams params ); + + // 报告 => 考试学生信息 + @the_retrofit.GET("/api/exam/report/examstudentinfo") + Future> getStudentInfo( + @the_retrofit.Query("examId") int examId, + @the_retrofit.Query("studentNo") String studentNo, + ); + + // 报告 => 学生考试历史记录 + @the_retrofit.GET("/api/exam/report/studentexamrecords") + Future>> getStudentHistroyRecords( + @the_retrofit.Query("userId") int userId, + @the_retrofit.Query("classId") int classId, + @the_retrofit.Query("startTime") String startTime, + @the_retrofit.Query("endTime") String endTime, + ); }