From e1db8ae9b9c71fddcd37bb8fcbd355c518932876 Mon Sep 17 00:00:00 2001 From: "1147192855@qq.com" <1147192855@qq.com> Date: Wed, 6 Mar 2024 18:15:43 +0800 Subject: [PATCH 01/22] no message --- .../lib/common/config/request_config.dart | 9 +- .../model/enum/job_marking_type_enum.dart | 10 + .../lib/common/model/job/job_task_item.dart | 49 +- .../homework_tasks_view_item.dart | 674 +----------------- .../lib/pages/homework_correction/index.dart | 6 +- .../pages/job_list_participate_in_class.dart | 447 ++++++++++++ marking_app/lib/routes/RouterManager.dart | 15 + .../lib/utils/request/rest_client.dart | 5 + marking_app/pubspec.yaml | 2 +- 9 files changed, 555 insertions(+), 662 deletions(-) create mode 100644 marking_app/lib/common/model/enum/job_marking_type_enum.dart create mode 100644 marking_app/lib/pages/homework_correction/pages/job_list_participate_in_class.dart diff --git a/marking_app/lib/common/config/request_config.dart b/marking_app/lib/common/config/request_config.dart index 2073b94..2825ae1 100644 --- a/marking_app/lib/common/config/request_config.dart +++ b/marking_app/lib/common/config/request_config.dart @@ -15,15 +15,16 @@ class RequestConfig { static const devLoginBaseUrl = "http://192.168.2.9:6400"; // 基本请求接口 static const devBaseUrlOfReport = "http://192.168.2.9:4000"; // 获取报告接口*/ - static const devBaseUrl = "https://mk-hw.23544.com"; // 基本请求 - static const devLoginBaseUrl = "https://mk-hw.23544.com"; // 登录接口 - static const devBaseUrlOfReport = "https://dc-api.23544.com"; // 获取报告接口 + static const devBaseUrl = "https://mhw.qwit.top"; // 基本请求 + static const devLoginBaseUrl = "https://mhw.qwit.top"; // 登录接口 + static const devBaseUrlOfReport = "https://mhw.qwit.top"; // 获取报告接口 + static const proBaseUrlOfHomework = "https://mhw.qwit.top/hw"; // 获取作业接口 /* 正式地址 */ static const proBaseUrl = "https://mk-hw.23544.com"; // 基本请求 static const proLoginBaseUrl = "https://mk-hw.23544.com"; // 登录接口 static const proBaseUrlOfReport = "https://dc-api.23544.com"; // 获取报告接口 - static const proBaseUrlOfHomework = "https://mk-hw.23544.com/hw"; // 获取作业接口 + // static const proBaseUrlOfHomework = "https://mk-hw.23544.com/hw"; // 获取作业接口 static const hwProxyKeywords = "/hw"; // 作业代理条件关键字 diff --git a/marking_app/lib/common/model/enum/job_marking_type_enum.dart b/marking_app/lib/common/model/enum/job_marking_type_enum.dart new file mode 100644 index 0000000..0fbc393 --- /dev/null +++ b/marking_app/lib/common/model/enum/job_marking_type_enum.dart @@ -0,0 +1,10 @@ +// 作业类型枚举 +enum JobMarkingTypeEnum { + UNUSED(name: '未使用废弃', indexValue: 0), + JOB(name: '作业', indexValue: 1), + EXAMINATION(name: '考试', indexValue: 2); + + const JobMarkingTypeEnum({required this.name, required this.indexValue}); + final String name; + final int indexValue; +} diff --git a/marking_app/lib/common/model/job/job_task_item.dart b/marking_app/lib/common/model/job/job_task_item.dart index 6d817c9..70ba21c 100644 --- a/marking_app/lib/common/model/job/job_task_item.dart +++ b/marking_app/lib/common/model/job/job_task_item.dart @@ -1,4 +1,5 @@ import 'package:json_annotation/json_annotation.dart'; +import 'package:marking_app/common/model/enum/job_marking_type_enum.dart'; part 'job_task_item.g.dart'; @@ -40,8 +41,8 @@ class JobTaskItem extends Object { @JsonKey(name: 'precision') double precision; - @JsonKey(name: 'markingTasks') - List markingTasks; + // @JsonKey(name: 'markingTasks') + // List markingTasks; @JsonKey(name: 'createTime') String createTime; @@ -49,23 +50,30 @@ class JobTaskItem extends Object { @JsonKey(name: 'progressPercentage') double progressPercentage; // 进度百分比 + @JsonKey(name: 'markingType') + int markingType; // 考试类型 + + @JsonKey(name: 'markingTypeEnum') + JobMarkingTypeEnum markingTypeEnum; // 考试类型 + JobTaskItem( - this.id, - this.title, - this.subjectName, - this.genderName, - this.isFinish, - this.studentCount, - this.commitStudentCount, - this.totalCount, - this.finishCount, - this.objectivePrecision, - this.subjectivePrecision, - this.precision, - this.markingTasks, - this.createTime, { - this.progressPercentage = 0, - }) { + this.id, + this.title, + this.subjectName, + this.genderName, + this.isFinish, + this.studentCount, + this.commitStudentCount, + this.totalCount, + this.finishCount, + this.objectivePrecision, + this.subjectivePrecision, + this.precision, + // this.markingTasks, + this.createTime, + this.markingType, + {this.progressPercentage = 0, + this.markingTypeEnum = JobMarkingTypeEnum.UNUSED}) { try { progressPercentage = (finishCount / totalCount) * 100; if (progressPercentage.isNaN) { @@ -76,6 +84,11 @@ class JobTaskItem extends Object { } catch (e) { progressPercentage = 0; } + try { + markingTypeEnum = JobMarkingTypeEnum.values[this.markingType]; + } catch (e) { + markingTypeEnum = JobMarkingTypeEnum.UNUSED; + } } factory JobTaskItem.fromJson(Map srcJson) => _$JobTaskItemFromJson(srcJson); diff --git a/marking_app/lib/pages/homework_correction/components/new_version_of_homework/homework_tasks_view_item.dart b/marking_app/lib/pages/homework_correction/components/new_version_of_homework/homework_tasks_view_item.dart index 7d2fc42..a72a37e 100644 --- a/marking_app/lib/pages/homework_correction/components/new_version_of_homework/homework_tasks_view_item.dart +++ b/marking_app/lib/pages/homework_correction/components/new_version_of_homework/homework_tasks_view_item.dart @@ -46,30 +46,29 @@ class HomeworkTasksViewItem extends StatelessWidget with CommonMixin { /// @param {bool} className 班级名称(不传此参数为主任务;传此参数为子任务) /// @param {bool} submitted 是否已提交(默认未提交) Future showStudents( - BuildContext context, - List taskIds, [ + BuildContext context, [ bool? submitted = false, String? className, ]) async { ToastUtils.showLoading(); List students = []; - try { - RestClient _client = await getClient(); - BaseStructureResult> _result = await _client.getJobWithStudents( - JobConcernedWithStudentParams(taskIds, isCommit: submitted), - ); - if (!_result.success) { - return ToastUtils.showError(_result.message ?? '获取学生列表失败'); - } - if (_result.data?.isEmpty ?? true) { - return ToastUtils.showError('获取到的学生列表为空'); - } - students = _result.data!; - } catch (e) { - return ToastUtils.showError('获取学生列表失败'); - } finally { - ToastUtils.dismiss(); - } + // try { + // RestClient _client = await getClient(); + // BaseStructureResult> _result = await _client.getJobWithStudents( + // JobConcernedWithStudentParams(taskIds, isCommit: submitted), + // ); + // if (!_result.success) { + // return ToastUtils.showError(_result.message ?? '获取学生列表失败'); + // } + // if (_result.data?.isEmpty ?? true) { + // return ToastUtils.showError('获取到的学生列表为空'); + // } + // students = _result.data!; + // } catch (e) { + // return ToastUtils.showError('获取学生列表失败'); + // } finally { + // ToastUtils.dismiss(); + // } showModalBottomSheet( context: context, @@ -125,28 +124,19 @@ class HomeworkTasksViewItem extends StatelessWidget with CommonMixin { ); } - void oneClickReview(int taskId) async { - try { - ToastUtils.showLoading(); - RestClient _client = await getClient(); - BaseStructureResult res = await _client.toJobOneClickReview(taskId); - if (res.success) return call(); - ToastUtils.showError(res.message ?? '操作失败'); - } catch (e) { - } finally { - ToastUtils.dismiss(); - } - } - @override Widget build(BuildContext context) { return completed ? $CompletedHomeworkView(jobTaskItem: jobTaskItem, showStudentsCall: showStudents) - : $UnfinishedHomework( - jobTaskItem: jobTaskItem, - refreshCallback: call, - endReviewCallback: endReview, - oneClickReviewCallback: oneClickReview, + : InkWell( + onTap: () { + String url = + '${RouterManager.jobListParticipateInClassPath}?&jobId=${jobTaskItem.id}&genderName=${Uri.encodeComponent(jobTaskItem.genderName)}&jobName=${Uri.encodeComponent(jobTaskItem.title)}'; + RouterManager.router.navigateTo(context, url, transition: getTransition()).then((value) { + if (value != null && value == true) call(); + }); + }, + child: $UnfinishedHomework(jobTaskItem: jobTaskItem), ); } } @@ -244,7 +234,6 @@ Widget $completedHomeworkView(BuildContext context, precision: jobTaskItem.precision / 100, objectivePrecision: jobTaskItem.objectivePrecision / 100, subjectivePrecision: jobTaskItem.subjectivePrecision / 100, - taskIds: jobTaskItem.markingTasks.map((e) => e.id).toList(), ), InkWell( onTap: () { @@ -277,55 +266,7 @@ Widget $completedHomeworkView(BuildContext context, Expanded(flex: 1, child: SizedBox()), ], ), - ), - SizedBox(height: 10.h), - ExpansionTile( - tilePadding: EdgeInsets.only(right: 10.w, bottom: 0), - title: Row( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - // badges.Badge( - // position: badges.BadgePosition.topEnd(top: -3.r, end: -12.r), - // badgeStyle: BadgeStyle(badgeColor: Theme.of(context).primaryColor.withOpacity(0.7)), - // badgeContent: Text( - // jobTaskItem.markingTasks.length.toString(), - // style: TextStyle(color: Colors.white, fontSize: 10.sp), - // ), - // child: quickText('班级列表 ', size: 17.sp), - // ), - badges.Badge( - badgeStyle: badges.BadgeStyle( - shape: badges.BadgeShape.square, - borderRadius: BorderRadius.circular(5.r), - padding: EdgeInsets.all(2.r), - badgeGradient: badges.BadgeGradient.linear( - colors: [ - Colors.purple, - Colors.blue, - ], - begin: Alignment.topLeft, - end: Alignment.bottomRight, - ), - ), - position: badges.BadgePosition.topEnd(top: -2.r, end: -8.r), - badgeContent: Text( - jobTaskItem.markingTasks.length.toString(), - style: TextStyle(color: Colors.white, fontSize: 10, fontWeight: FontWeight.bold), - ), - child: quickText('班级列表 ', size: 17.sp), - ), - ], - ), - childrenPadding: EdgeInsets.only(top: 0.h), - children: jobTaskItem.markingTasks.map((e) { - return $CompletedHomeworkChildView( - jobTaskItem: jobTaskItem, - taskItem: e, - showStudentsCall: showStudentsCall, - ); - }).toList(), - ), + ) ], ), ); @@ -364,7 +305,6 @@ Widget $completedHomeworkChildView( submittedQuantity: taskItem.commitStudentCount, unsubmittedQuantity: taskItem.studentCount - taskItem.commitStudentCount, showStudentsCall: showStudentsCall, - taskIds: [taskItem.id], className: taskItem.className, ), ], @@ -375,7 +315,6 @@ Widget $completedHomeworkChildView( @swidget Widget $completedHomeworkBtn( BuildContext context, { - required List taskIds, required int submittedQuantity, required int unsubmittedQuantity, required ShowStudentsCall showStudentsCall, @@ -391,7 +330,7 @@ Widget $completedHomeworkBtn( child: InkWell( onTap: () { if (unsubmittedQuantity <= 0) return ToastUtils.showInfo('没有未提交的作业'); - showStudentsCall(context, taskIds, false, className); + showStudentsCall(context, false, className); }, borderRadius: BorderRadius.circular(8.r), child: Container( @@ -413,7 +352,7 @@ Widget $completedHomeworkBtn( child: InkWell( onTap: () async { if (submittedQuantity <= 0) return ToastUtils.showInfo('没有已提交的作业'); - showStudentsCall(context, taskIds, true, className); + showStudentsCall(context, true, className); }, borderRadius: BorderRadius.circular(8.r), child: Container( @@ -511,7 +450,6 @@ Widget $completedHomeworkProgressBar( @swidget Widget $completedHomeworkInfoBox( BuildContext context, { - required List taskIds, required int unsubmittedQuantity, required int submittedQuantity, required double objectivePrecision, // 客观题正确率 @@ -524,7 +462,6 @@ Widget $completedHomeworkInfoBox( return Column( children: [ $CompletedHomeworkBtn( - taskIds: taskIds, className: className, unsubmittedQuantity: unsubmittedQuantity, submittedQuantity: submittedQuantity, @@ -557,13 +494,7 @@ Widget $completedHomeworkInfoBox( // 未完成作业单个view @swidget -Widget $unfinishedHomework( - BuildContext context, { - required JobTaskItem jobTaskItem, - required VoidCallback refreshCallback, - required EndReviewCall endReviewCallback, - required Function(int) oneClickReviewCallback, -}) { +Widget $unfinishedHomework(BuildContext context, {required JobTaskItem jobTaskItem}) { return Stack( alignment: const FractionalOffset(0.95, 0), children: [ @@ -599,7 +530,9 @@ Widget $unfinishedHomework( alignment: Alignment.center, padding: EdgeInsets.only(left: 2.w), decoration: BoxDecoration( - color: Color.fromRGBO(104, 136, 253, 1), + color: jobTaskItem.markingTypeEnum.name == '作业' + ? const Color.fromRGBO(104, 136, 253, 1) + : const Color.fromRGBO(255, 175, 56, 1), borderRadius: BorderRadius.only( topLeft: Radius.circular(18.r), topRight: Radius.circular(3.r), @@ -608,7 +541,7 @@ Widget $unfinishedHomework( ), ), margin: EdgeInsets.only(right: 4.w), - child: quickText('作业', color: Colors.white, size: 10.sp), + child: quickText(jobTaskItem.markingTypeEnum.name, color: Colors.white, size: 10.sp), ), quickText( jobTaskItem.title, @@ -653,50 +586,6 @@ Widget $unfinishedHomework( ), ], ), - // 未完成按钮 - $UnfinishedBtn( - isChild: false, - jobTaskItem: jobTaskItem, - endCallback: endReviewCallback, - refreshcall: refreshCallback, - ), - SizedBox(height: 20.h), - ExpansionTile( - tilePadding: EdgeInsets.only(right: 10.w), - title: Row( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - badges.Badge( - badgeStyle: badges.BadgeStyle( - shape: badges.BadgeShape.square, - borderRadius: BorderRadius.circular(5.r), - padding: EdgeInsets.all(2.r), - badgeGradient: badges.BadgeGradient.linear( - colors: [Colors.purple, Colors.blue], - begin: Alignment.topLeft, - end: Alignment.bottomRight, - ), - ), - position: badges.BadgePosition.topEnd(top: -2.r, end: -8.r), - badgeContent: Text( - jobTaskItem.markingTasks.length.toString(), - style: TextStyle(color: Colors.white, fontSize: 10, fontWeight: FontWeight.bold), - ), - child: quickText('班级列表 ', size: 17.sp), - ), - ], - ), - children: jobTaskItem.markingTasks.map((e) { - return $UnfinishedClassItem( - jobTaskItem: jobTaskItem, - jobTaskClassItem: e, - endReviewCallback: endReviewCallback, - refreshCallback: refreshCallback, - oneClickReviewCallback: oneClickReviewCallback, - ); - }).toList(), - ), ], ), ), @@ -752,500 +641,9 @@ Widget $unfinishedHomework( ); } -// 未完成作业按钮 (名称和数量) -@swidget -Widget $unfinishedBtn( - BuildContext context, { - required JobTaskItem jobTaskItem, - required VoidCallback refreshcall, - required EndReviewCall endCallback, - MarkingTasks? jobTaskClassItem, - bool isChild = true, -}) { - if (!isChild) { - MarkingTasks? theCanReviewChild = jobTaskItem.markingTasks.firstWhereOrNull((e) => e.canGoReview); - - List canEndTaskChilds = jobTaskItem.markingTasks.where((e) => !e.isFinish && e.canMarking).toList(); - return Container( - margin: EdgeInsets.only(top: 22.h), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - Expanded( - flex: 2, - child: Material( - color: theCanReviewChild != null ? Colors.white : Colors.grey[300], - borderRadius: BorderRadius.circular(30.r), - child: InkWell( - onTap: () { - MarkingTasks? markingTask = - jobTaskItem.markingTasks.firstWhereOrNull((e) => e.canMarking && e.totalCount > 0 && !e.isFinish); - if (markingTask == null) { - ToastUtils.showInfo('没有找到可以批阅的任务'); - // AchievementView( - // elevation: 0.5, - // duration: Duration(seconds: 1), - // title: "提示", - // subTitle: "没有找到可以批阅的任务", - // color: Theme.of(context).primaryColor, - // ).show(context); - return; - } - String url = - '${RouterManager.markingHomeworkDoPath}?taskId=${markingTask.id}&jobId=${jobTaskItem.id}&taskName=${Uri.encodeComponent(jobTaskItem.title)}&className=${Uri.encodeComponent(jobTaskItem.genderName + markingTask.className)}'; - RouterManager.router.navigateTo(context, url, transition: getTransition()).then((value) { - if (value != null && value == true) refreshcall(); - }); - }, - borderRadius: BorderRadius.circular(30.r), - child: Container( - height: 36.h, - padding: EdgeInsets.symmetric(vertical: 3.h), - alignment: Alignment.center, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(30.r), - border: Border.all(color: Theme.of(context).primaryColor), - ), - child: quickText('批阅', color: Theme.of(context).primaryColor, size: 14.sp), - ), - ), - ), - ), - Expanded( - flex: 1, - child: SizedBox(width: 5.w), - ), - Expanded( - flex: 2, - child: Material( - color: canEndTaskChilds.isNotEmpty ? Color.fromRGBO(104, 136, 253, 1) : Colors.grey, - borderRadius: BorderRadius.circular(30.r), - child: InkWell( - onTap: () async { - List childTasks = - jobTaskItem.markingTasks.where((e) => !e.isFinish && e.canMarking).toList(); - if (childTasks.isEmpty) return ToastUtils.showInfo('没有可以结束的任务'); - - // 未完成批阅任务提示 - List incompleteTasks = childTasks.where((e) => e.finishCount < e.totalCount).toList(); - if (incompleteTasks.isNotEmpty) { - var continueFlag = await showDialog( - context: context, - builder: (BuildContext context1) { - return AlertDialog( - title: Text('未完成批阅提示'), - content: Text('当前批阅任务未完成,请确认需要结束此任务?'), - actions: [ - TextButton( - child: Text('否'), - onPressed: () { - // 在这里处理删除操作 - Navigator.of(context1).pop(false); - }, - ), - TextButton( - child: Text('是'), - onPressed: () { - Navigator.of(context1).pop(true); - }, - ), - ], - ); - }, - ); - if (continueFlag == null || !continueFlag) { - return; - } - } - - showDialog( - context: context, - builder: (BuildContext context1) { - return AlertDialog( - title: Text('提示'), - content: Text('确认完成以下${childTasks.map((e) => e.className).toList().join(",")}的批阅任务?'), - actions: [ - TextButton( - child: Text('否'), - onPressed: () { - // 在这里处理删除操作 - Navigator.of(context1).pop(); - }, - ), - TextButton( - child: Text('确定'), - onPressed: () async { - try { - bool result = await endCallback(childTasks); - if (result) refreshcall(); - } catch (e) { - } finally { - ToastUtils.dismiss(); - Navigator.of(context1).pop(); - } - }, - ), - ], - ); - }, - ); - }, - borderRadius: BorderRadius.circular(30.r), - child: Container( - height: 36.h, - padding: EdgeInsets.symmetric(vertical: 3.5.h), - alignment: Alignment.center, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(30.r), - ), - child: quickText('结束批阅', size: 14.sp, color: Colors.white), - ), - ), - ), - ), - ], - ), - ); - } - - if (!jobTaskClassItem!.canMarking) - return Container( - alignment: Alignment.centerRight, - child: jobTaskClassItem.isFinish - ? Row( - mainAxisAlignment: MainAxisAlignment.end, - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - quickText(jobTaskClassItem.finishTime?.substring(0, 16), - size: 10.sp, color: Color.fromRGBO(170, 170, 170, 1)), - SizedBox(width: 4.w), - quickText('已批阅', size: 10.sp, color: Theme.of(context).primaryColor), - ], - ) - : quickText( - '待批阅', - size: 10.sp, - color: Color.fromRGBO(255, 138, 0, 1), - ), - ); - - return Container( - child: jobTaskClassItem.isFinish - ? Row( - mainAxisAlignment: MainAxisAlignment.end, - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - quickText(jobTaskClassItem.finishTime?.substring(0, 16), - size: 12.sp, color: Color.fromRGBO(170, 170, 170, 1)), - SizedBox(width: 4.w), - quickText('已批阅', size: 13.sp, color: Theme.of(context).primaryColor), - ], - ) - : Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - Expanded( - flex: 5, - child: Material( - color: jobTaskClassItem.canGoReview ? Colors.white : Colors.grey[300], - borderRadius: BorderRadius.circular(4.r), - child: InkWell( - onTap: () { - if (jobTaskClassItem.totalCount <= 0) { - return ToastUtils.showInfo('没有找到可以批阅的任务'); - } - - if (!jobTaskClassItem.canMarking) { - return AchievementView( - elevation: 0.5, - duration: Duration(seconds: 1), - title: "提示", - subTitle: "此账号无法批阅该任务", - color: Theme.of(context).primaryColor, - ).show(context); - } - - if (jobTaskClassItem.isFinish) { - return AchievementView( - elevation: 0.5, - duration: Duration(seconds: 1), - title: "提示", - subTitle: "此批阅任务已完成", - color: Theme.of(context).primaryColor, - ).show(context); - } - - String url = - '${RouterManager.markingHomeworkDoPath}?taskId=${jobTaskClassItem.id}&jobId=${jobTaskItem.id}&taskName=${Uri.encodeComponent(jobTaskItem.title)}&className=${Uri.encodeComponent(jobTaskItem.genderName + jobTaskClassItem.className)}'; - RouterManager.router.navigateTo(context, url, transition: getTransition()).then((value) { - if (value == true) refreshcall(); - }); - }, - child: Container( - padding: EdgeInsets.symmetric(vertical: 6.h), - alignment: Alignment.center, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(4.r), - border: Border.all(color: Theme.of(context).primaryColor), - ), - child: quickText('批阅', color: Theme.of(context).primaryColor, size: 12.sp), - ), - ), - )), - Expanded(flex: 1, child: SizedBox()), - Expanded( - flex: 5, - child: Material( - color: !jobTaskClassItem.isFinish && jobTaskClassItem.canMarking - ? Color.fromRGBO(237, 240, 255, 1) - : Colors.grey, - borderRadius: BorderRadius.circular(4.r), - child: InkWell( - onTap: () async { - if (!jobTaskClassItem.canMarking) return ToastUtils.showInfo('此任务非该账号任务'); - if (jobTaskClassItem.isFinish) return ToastUtils.showInfo('此任务已经结束'); - - // 未完成批阅任务提示 - if (jobTaskClassItem.finishCount < jobTaskClassItem.totalCount) { - var continueFlag = await showDialog( - context: context, - builder: (BuildContext context1) { - return AlertDialog( - title: Text('未完成批阅提示'), - content: Text('当前批阅任务未完成,请确认需要结束此任务?'), - actions: [ - TextButton( - child: Text('否'), - onPressed: () { - // 在这里处理删除操作 - Navigator.of(context1).pop(false); - }, - ), - TextButton( - child: Text('是'), - onPressed: () { - Navigator.of(context1).pop(true); - }, - ), - ], - ); - }, - ); - if (continueFlag == null || !continueFlag) { - return; - } - } - - showDialog( - context: context, - builder: (BuildContext context1) { - return AlertDialog( - title: Text('提示'), - content: Text('确认完成当前${jobTaskClassItem.className}批阅任务?'), - actions: [ - TextButton( - child: Text('否'), - onPressed: () { - // 在这里处理删除操作 - Navigator.of(context1).pop(); - }, - ), - TextButton( - child: Text('确定'), - onPressed: () async { - try { - bool result = await endCallback([jobTaskClassItem]); - if (result) refreshcall(); - } catch (e) { - } finally { - ToastUtils.dismiss(); - Navigator.of(context1).pop(); - } - }, - ), - ], - ); - }, - ); - }, - child: Container( - padding: EdgeInsets.symmetric(vertical: 6.h), - alignment: Alignment.center, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(4.r), - border: Border.all(color: Color.fromRGBO(130, 156, 255, 1)), - ), - child: quickText('结束批阅', size: 12.sp, color: Color.fromRGBO(104, 136, 253, 1)), - ), - ), - )), - ], - ), - ); -} - -// 未完成作业单个班级view -@swidget -Widget $unfinishedClassItem( - BuildContext context, { - required JobTaskItem jobTaskItem, - required MarkingTasks jobTaskClassItem, - required VoidCallback refreshCallback, - required EndReviewCall endReviewCallback, - required Function(int) oneClickReviewCallback, -}) { - return Container( - padding: EdgeInsets.only(bottom: 14.w), - margin: EdgeInsets.only(bottom: 20.h), - decoration: BoxDecoration(border: Border(bottom: BorderSide(color: Color.fromRGBO(233, 233, 233, 1), width: 1.r))), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - children: [ - Expanded( - child: quickText(jobTaskItem.genderName + jobTaskClassItem.className, - color: Color.fromRGBO(255, 123, 1, 1), size: 14.sp)), - if (!jobTaskClassItem.isFinish) - Expanded( - child: Container( - child: Row( - children: [ - Expanded( - child: Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10.r), - boxShadow: [ - BoxShadow( - color: Color.fromRGBO(104, 136, 253, 1), - spreadRadius: 0.5, - blurRadius: 1, - offset: Offset(0, 0), - ), - ], - ), - child: LinearPercentIndicator( - padding: EdgeInsets.zero, - animation: true, - lineHeight: 10.h, - animationDuration: 2500, - percent: jobTaskClassItem.progressPercentage / 100, - center: Text( - '${getDoubleRemoveZero(jobTaskClassItem.progressPercentage)}%', - style: TextStyle(color: Colors.white, fontSize: 8.sp), - ), - linearGradient: LinearGradient( - tileMode: TileMode.mirror, - stops: [0.0, 1.0], - colors: [ - Theme.of(context).primaryColor.withOpacity(0.1), - Theme.of(context).primaryColor, - ], - ), - // linearStrokeCap: LinearStrokeCap.butt, - // progressColor: Theme.of(context).primaryColor, - backgroundColor: Colors.white, - barRadius: Radius.circular(10.r), - ), - ), - ), - SizedBox(width: 4.w), - quickText('${getDoubleRemoveZero(jobTaskClassItem.progressPercentage)}%', - size: 10.sp, color: Color.fromRGBO(104, 136, 253, 1)) - ], - ), - ), - ), - ], - ), - SizedBox(height: 14.h), - Container( - child: Row( - children: [ - Expanded( - child: Row(children: [ - quickText('题量:${jobTaskClassItem.totalCount}'), - SizedBox(width: 20.w), - quickText(jobTaskClassItem.teacherName) - ])), - Expanded( - child: $UnfinishedBtn( - jobTaskItem: jobTaskItem, - jobTaskClassItem: jobTaskClassItem, - endCallback: endReviewCallback, - refreshcall: refreshCallback, - ), - ), - ], - ), - ), - if (jobTaskClassItem.canGoReview) SizedBox(height: 6.h), - if (jobTaskClassItem.canGoReview) - Material( - borderRadius: BorderRadius.circular(30.r), - child: InkWell( - onTap: () => easyThrottle('OneClickReview', () async { - var continueFlag = await showDialog( - context: context, - builder: (BuildContext context1) { - return AlertDialog( - title: Text('一键批阅'), - content: Text('一键批阅后,默认学生答题结果全部正确,是否进行此操作?'), - actions: [ - TextButton( - child: Text('否'), - onPressed: () { - // 在这里处理删除操作 - Navigator.of(context1).pop(false); - }, - ), - TextButton( - child: Text('是'), - onPressed: () { - Navigator.of(context1).pop(true); - }, - ), - ], - ); - }, - ); - if (continueFlag == null || !continueFlag) return; - oneClickReviewCallback(jobTaskClassItem.id); - }), - borderRadius: BorderRadius.circular(30.r), - child: Container( - height: 20.h, - constraints: BoxConstraints(minWidth: 50.w, maxWidth: 60.w), - alignment: Alignment.center, - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(30.r), - border: Border.all(color: Color.fromRGBO(76, 199, 147, 1)), - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - quickText('一键批阅', color: Color.fromRGBO(76, 199, 147, 1), size: 10.sp), - Padding( - padding: EdgeInsets.only(top: 1.1.h), - child: Icon(Icons.arrow_forward_ios, size: 8.sp, color: Color.fromRGBO(76, 199, 147, 1)), - ), - ], - ), - ), - ), - ), - ], - ), - ); -} - typedef EndReviewCall = Future Function(List markingTasks); typedef ShowStudentsCall = Future Function( - BuildContext context, - List taskIds, [ + BuildContext context, [ bool? submitted, String? className, ]); diff --git a/marking_app/lib/pages/homework_correction/index.dart b/marking_app/lib/pages/homework_correction/index.dart index adcdf12..84b6783 100644 --- a/marking_app/lib/pages/homework_correction/index.dart +++ b/marking_app/lib/pages/homework_correction/index.dart @@ -167,6 +167,7 @@ class _HomeworkCorrectionState extends ConsumerState margin: EdgeInsets.only(top: MediaQuery.of(context).padding.top), padding: EdgeInsets.only(bottom: 9.h, top: 4.h), child: Row( + crossAxisAlignment: CrossAxisAlignment.center, children: [ Expanded( flex: 1, @@ -254,7 +255,10 @@ class _HomeworkCorrectionState extends ConsumerState ), Expanded( flex: 1, - child: SizedBox(), + child: InkWell( + onTap: () {}, + child: Icon(Icons.settings_outlined, color: Color.fromRGBO(44, 48, 63, 1), size: 24.sp), + ), ), ], ), diff --git a/marking_app/lib/pages/homework_correction/pages/job_list_participate_in_class.dart b/marking_app/lib/pages/homework_correction/pages/job_list_participate_in_class.dart new file mode 100644 index 0000000..38a3970 --- /dev/null +++ b/marking_app/lib/pages/homework_correction/pages/job_list_participate_in_class.dart @@ -0,0 +1,447 @@ +import 'package:achievement_view/achievement_view.dart'; +import 'package:flutter/material.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_task_item.dart'; +import 'package:marking_app/routes/RouterManager.dart'; +import 'package:marking_app/utils/index.dart'; +import 'package:marking_app/utils/my_future_builder.dart'; +import 'package:marking_app/utils/my_text.dart'; +import 'package:marking_app/utils/request/rest_client.dart'; +import 'package:percent_indicator/linear_percent_indicator.dart'; + +class JobListParticipateInClass extends StatefulWidget { + final int jobId; + final String jobName; + final String genderName; + const JobListParticipateInClass({required this.jobId, required this.jobName, required this.genderName, super.key}); + + @override + State createState() => _JobListParticipateInClassState(); +} + +class _JobListParticipateInClassState extends State with CommonMixin { + late Future?> _future; + + bool isRefresh = false; + + @override + void initState() { + // TODO: implement initState + super.initState(); + _future = getData(); + } + + @override + void dispose() { + // TODO: implement dispose + super.dispose(); + } + + Future?> getData() async { + RestClient _client = await getClient(); + BaseStructureResult> _result = await _client.getJobListParticipateInClass(widget.jobId); + return _result.data; + } + + // 结束批阅方法 + Future endReview(List markingTasks) async { + try { + ToastUtils.showLoading(); + RestClient client = await getClient(); + BaseStructureResult res = await client.toEndReviewJob(markingTasks.map((e) => e.id).toList()); + if (!res.success) ToastUtils.showError('结束失败,请重试'); + return res.success; + } catch (e) { + ToastUtils.showError('结束失败,请重试'); + return false; + } + } + + void oneClickReview(int taskId) async { + try { + ToastUtils.showLoading(); + RestClient _client = await getClient(); + BaseStructureResult res = await _client.toJobOneClickReview(taskId); + if (res.success) { + isRefresh = true; + _future = getData(); + toUpState(setState, () {}, mounted); + return; + } + ToastUtils.showError(res.message ?? '操作失败'); + } catch (e) { + } finally { + ToastUtils.dismiss(); + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: const Color.fromRGBO(245, 245, 245, 1), + appBar: AppBar( + leading: IconButton( + icon: Icon(Icons.arrow_back_ios, color: Color.fromRGBO(51, 51, 51, 1)), + onPressed: () => Navigator.of(context).pop()), + title: Container( + child: + quickText(widget.jobName, size: 16.sp, color: Color.fromRGBO(51, 51, 51, 1), fontWeight: FontWeight.w500), + alignment: Alignment.center, + ), + backgroundColor: Colors.white, + ), + body: MyFutureBuilder.buildFutureBuilderOfSingleInstance?>(context, _future, (value) { + if (value == null) return Container(); + + return ListView( + padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 16.w), + children: value.map((e) { + return Container( + padding: EdgeInsets.only(top: 11.h), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadiusDirectional.circular(10.r), + boxShadow: [ + BoxShadow( + color: Color.fromRGBO(0, 0, 0, 0.15), + blurRadius: 10, + ), + ], + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Padding( + padding: EdgeInsets.only(left: 10.w, right: 10.w), + child: Row( + children: [ + quickText(widget.genderName + e.className, color: Color.fromRGBO(0, 0, 0, 1), size: 14.sp), + Expanded(child: SizedBox()), + quickText('已交:${e.commitStudentCount}', color: Color.fromRGBO(104, 136, 253, 1), size: 12.sp), + SizedBox(width: 16.w), + quickText('未交:${e.studentCount - e.commitStudentCount}', + color: Color.fromRGBO(255, 86, 86, 1), size: 12.sp), + ], + ), + ), + SizedBox(height: 13.h), + Padding( + padding: EdgeInsets.only(left: 10.w, right: 10.w), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + flex: 3, + child: Material( + color: Color.fromRGBO(104, 136, 253, 1), + borderRadius: BorderRadius.circular(16.r), + child: InkWell( + onTap: () => easyThrottle('OneClickReview', () async { + var continueFlag = await showDialog( + context: context, + builder: (BuildContext context1) { + return Center( + child: Container( + padding: EdgeInsets.symmetric(vertical: 25.h, horizontal: 18.w), + decoration: BoxDecoration( + color: Colors.white, borderRadius: BorderRadiusDirectional.circular(12.r)), + height: 150.h, + width: 280.w, + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + children: [ + Expanded( + child: quickText('一键批阅后,默认学生答题结果全部正确,是否进行此操作?', + maxLines: 3, + size: 14.sp, + color: Color.fromRGBO(80, 94, 110, 1))) + ], + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + InkWell( + onTap: () { + Navigator.of(context1).pop(false); + }, + child: Container( + padding: EdgeInsetsDirectional.symmetric( + horizontal: 36.w, vertical: 7.h), + decoration: BoxDecoration( + color: Color.fromRGBO(244, 244, 244, 1), + borderRadius: BorderRadius.circular(20.r)), + child: quickText('取消', + size: 14.sp, color: Color.fromRGBO(102, 102, 102, 1)), + ), + ), + InkWell( + onTap: () { + Navigator.of(context1).pop(true); + }, + child: Container( + padding: EdgeInsetsDirectional.symmetric( + horizontal: 36.w, vertical: 7.h), + decoration: BoxDecoration( + color: Theme.of(context).primaryColor, + borderRadius: BorderRadius.circular(20.r)), + child: quickText('确认', + size: 14.sp, color: Color.fromRGBO(255, 255, 255, 1)), + ), + ), + ], + ) + ], + ), + )); + }, + ); + if (continueFlag == null || !continueFlag) return; + oneClickReview(e.id); + }), + borderRadius: BorderRadius.circular(8.r), + child: Container( + alignment: Alignment.center, + padding: EdgeInsets.symmetric(vertical: 5.h), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(20.r), + ), + child: quickText('一键批阅', size: 10.sp, color: Colors.white), + ), + ), + ), + ), + Expanded(flex: 1, child: SizedBox()), + Expanded( + flex: 3, + child: Material( + color: Color.fromRGBO(244, 244, 244, 1), + borderRadius: BorderRadius.circular(20.r), + child: InkWell( + onTap: () async {}, + borderRadius: BorderRadius.circular(8.r), + child: Container( + alignment: Alignment.center, + padding: EdgeInsets.symmetric(vertical: 5.h), + decoration: BoxDecoration(borderRadius: BorderRadius.circular(20.r)), + child: quickText('数据快查', size: 10.sp, color: Color.fromRGBO(102, 102, 102, 1)), + ), + ), + ), + ), + Expanded(flex: 1, child: SizedBox()), + Expanded( + flex: 3, + child: Material( + color: Color.fromRGBO(244, 244, 244, 1), + borderRadius: BorderRadius.circular(20.r), + child: InkWell( + onTap: () async {}, + borderRadius: BorderRadius.circular(8.r), + child: Container( + alignment: Alignment.center, + padding: EdgeInsets.symmetric(vertical: 5.h), + decoration: BoxDecoration(borderRadius: BorderRadius.circular(20.r)), + child: quickText('收藏夹(2)', size: 10.sp, color: Color.fromRGBO(102, 102, 102, 1)), + ), + ), + )), + ], + ), + ), + SizedBox(height: 13.h), + Padding( + padding: EdgeInsets.only(left: 10.w, right: 10.w), + child: Row( + children: [ + Expanded( + child: LinearPercentIndicator( + padding: EdgeInsets.zero, + animation: true, + lineHeight: 6.h, + animationDuration: 2500, + + percent: e.progressPercentage / 100, + // center: Text( + // '${getDoubleRemoveZero(jobTaskClassItem.progressPercentage)}%', + // style: TextStyle(color: Colors.white, fontSize: 8.sp), + // ), + linearGradient: LinearGradient( + tileMode: TileMode.mirror, + stops: [0.0, 1.0], + colors: e.progressPercentage / 100 != 1 + ? [Theme.of(context).primaryColor.withOpacity(0.1), Theme.of(context).primaryColor] + : [ + Color.fromRGBO(144, 224, 190, 1).withOpacity(0.1), + Color.fromRGBO(144, 224, 190, 1), + ], + ), + // linearStrokeCap: LinearStrokeCap.butt, + // progressColor: Theme.of(context).primaryColor, + backgroundColor: Color.fromRGBO(232, 232, 232, 1), + barRadius: Radius.circular(10.r), + ), + ), + SizedBox(width: 7.w), + quickText('${getDoubleRemoveZero(e.progressPercentage)}%', + size: 10.sp, color: Color.fromRGBO(70, 70, 70, 1)) + ], + ), + ), + SizedBox(height: 13.h), + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.only( + bottomLeft: Radius.circular(10.r), + bottomRight: Radius.circular(10.r), + ), + color: Colors.white, + boxShadow: [ + BoxShadow( + color: const Color.fromRGBO(0, 0, 0, 0.15), + offset: Offset(0, -0.0001), //阴影y轴偏移量 + blurRadius: 5, //阴影模糊程度 + spreadRadius: 0, //阴影扩散程度 + ) + ], + ), + child: Row( + children: [ + Expanded( + child: InkWell( + onTap: () { + if (e.totalCount <= 0) { + return ToastUtils.showInfo('没有找到可以批阅的任务'); + } + + if (!e.canMarking) { + return AchievementView( + elevation: 0.5, + duration: Duration(seconds: 1), + title: "提示", + subTitle: "此账号无法批阅该任务", + color: Theme.of(context).primaryColor, + ).show(context); + } + + if (e.isFinish) { + return AchievementView( + elevation: 0.5, + duration: Duration(seconds: 1), + title: "提示", + subTitle: "此批阅任务已完成", + color: Theme.of(context).primaryColor, + ).show(context); + } + + String url = + '${RouterManager.markingHomeworkDoPath}?taskId=${e.id}&jobId=${widget.jobId}&taskName=${Uri.encodeComponent(widget.jobName)}&className=${Uri.encodeComponent(widget.genderName + e.className)}'; + RouterManager.router + .navigateTo(context, url, transition: getTransition()) + .then((value) { + if (value == true) { + isRefresh = true; + _future = getData(); + toUpState(setState, () {}, mounted); + } + }); + }, + child: Container( + alignment: Alignment.center, + child: quickText('批阅', color: Color.fromRGBO(79, 79, 79, 1), size: 13.sp), + ), + ), + ), + Container(width: 1.w, height: 32.h, color: Color.fromRGBO(221, 221, 221, 1)), + Expanded( + child: InkWell( + onTap: () async { + if (!e.canMarking) return ToastUtils.showInfo('此任务非该账号任务'); + if (e.isFinish) return ToastUtils.showInfo('此任务已经结束'); + + // 未完成批阅任务提示 + if (e.finishCount < e.totalCount) { + var continueFlag = await showDialog( + context: context, + builder: (BuildContext context1) { + return AlertDialog( + title: Text('未完成批阅提示'), + content: Text('当前批阅任务未完成,请确认需要结束此任务?'), + actions: [ + TextButton( + child: Text('否'), + onPressed: () { + // 在这里处理删除操作 + Navigator.of(context1).pop(false); + }, + ), + TextButton( + child: Text('是'), + onPressed: () { + Navigator.of(context1).pop(true); + }, + ), + ], + ); + }, + ); + if (continueFlag == null || !continueFlag) { + return; + } + } + + showDialog( + context: context, + builder: (BuildContext context1) { + return AlertDialog( + title: Text('提示'), + content: Text('确认完成当前${e.className}批阅任务?'), + actions: [ + TextButton( + child: Text('否'), + onPressed: () { + // 在这里处理删除操作 + Navigator.of(context1).pop(); + }, + ), + TextButton( + child: Text('确定'), + onPressed: () async { + try { + bool result = await endReview([e]); + if (result) { + isRefresh = true; + _future = getData(); + toUpState(setState, () {}, mounted); + } + } catch (e) { + } finally { + ToastUtils.dismiss(); + Navigator.of(context1).pop(); + } + }, + ), + ], + ); + }, + ); + }, + child: Container( + alignment: Alignment.center, + child: quickText('结束批阅', color: Color.fromRGBO(118, 118, 118, 1), size: 12.sp), + ), + )), + ], + ), + ), + ], + )); + }).toList(), + ); + }), + ); + } +} diff --git a/marking_app/lib/routes/RouterManager.dart b/marking_app/lib/routes/RouterManager.dart index 20a8f4c..fec4960 100644 --- a/marking_app/lib/routes/RouterManager.dart +++ b/marking_app/lib/routes/RouterManager.dart @@ -15,6 +15,7 @@ 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/pages/job_list_participate_in_class.dart'; import 'package:marking_app/pages/homework_correction/review_job.dart'; import 'package:marking_app/pages/login/index.dart'; @@ -53,6 +54,8 @@ class RouterManager { static const String jobReportPagePath = '/job/report/index'; // 作业 ==> 横屏考试 static const String jobExamPagePath = '/job/exam/index'; + // 作业 ==> 列表 ==> 参与班级 + static const String jobListParticipateInClassPath = '/job/list/participateInClass'; static const String reportClassTeacherPath = 'report/details/reportClassTeacher'; static const String reportSubjectTeacherPath = 'report/details/reportSubjectTeacher'; @@ -239,6 +242,16 @@ class RouterManager { }, ); + static final _jobListParticipateInClassHandler = Handler( + handlerFunc: (BuildContext? context, Map> params) { + int jobId = int.parse(params['jobId']![0]); + String jobName = params['jobName']![0]; + String genderName = params['genderName']![0]; + + return JobListParticipateInClass(jobId: jobId, jobName: jobName, genderName: genderName); + }, + ); + // 开始阅卷页面 // static final _doMarkingPapers = Handler(handlerFunc: (BuildContext? context, Map> params) => MarkingPapers()); @@ -273,6 +286,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(jobListParticipateInClassPath, + handler: _jobListParticipateInClassHandler, 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..1ef80ca 100644 --- a/marking_app/lib/utils/request/rest_client.dart +++ b/marking_app/lib/utils/request/rest_client.dart @@ -285,4 +285,9 @@ 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("${RequestConfig.hwProxyKeywords}/api/Task/tasks") + Future>> getJobListParticipateInClass( + @the_retrofit.Query("markingId") int jobId); } diff --git a/marking_app/pubspec.yaml b/marking_app/pubspec.yaml index 57b548e..92c49cc 100644 --- a/marking_app/pubspec.yaml +++ b/marking_app/pubspec.yaml @@ -15,7 +15,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.95 +version: 1.0.87 environment: sdk: ">=2.17.1 <3.0.0" -- 2.40.1 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 02/22] =?UTF-8?q?=E4=BD=9C=E4=B8=9A=E6=8A=A5=E5=91=8A?= =?UTF-8?q?=EF=BC=8C=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); } -- 2.40.1 From ff1b70d39d4cbeac3ce71794f82a08e23044dd3d Mon Sep 17 00:00:00 2001 From: "1147192855@qq.com" <1147192855@qq.com> Date: Fri, 8 Mar 2024 10:49:16 +0800 Subject: [PATCH 03/22] =?UTF-8?q?=E5=88=97=E8=A1=A8=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../homework_tasks_view_item.dart | 219 +-- .../lib/pages/homework_correction/index.dart | 149 +- .../pages/job_list_participate_in_class.dart | 1264 ++++++++++++----- marking_app/lib/utils/index.dart | 6 + 4 files changed, 1171 insertions(+), 467 deletions(-) diff --git a/marking_app/lib/pages/homework_correction/components/new_version_of_homework/homework_tasks_view_item.dart b/marking_app/lib/pages/homework_correction/components/new_version_of_homework/homework_tasks_view_item.dart index a72a37e..d757d83 100644 --- a/marking_app/lib/pages/homework_correction/components/new_version_of_homework/homework_tasks_view_item.dart +++ b/marking_app/lib/pages/homework_correction/components/new_version_of_homework/homework_tasks_view_item.dart @@ -147,7 +147,7 @@ Widget $completedHomeworkView(BuildContext context, {required JobTaskItem jobTaskItem, required ShowStudentsCall showStudentsCall}) { return Container( width: double.infinity, - padding: EdgeInsets.symmetric(vertical: 20.h, horizontal: 10.w), + padding: EdgeInsets.only(top: 20.h), margin: EdgeInsets.only(bottom: 12.h), decoration: BoxDecoration( borderRadius: BorderRadius.circular(6.r), @@ -164,109 +164,134 @@ Widget $completedHomeworkView(BuildContext context, child: Column( children: [ // 顶部任务名称 - Row( - children: [ - Container( - width: 32.w, - height: 18.h, - alignment: Alignment.center, - padding: EdgeInsets.only(left: 2.w), - decoration: BoxDecoration( - color: Color.fromRGBO(104, 136, 253, 1), - borderRadius: BorderRadius.only( - topLeft: Radius.circular(18.r), - topRight: Radius.circular(3.r), - bottomLeft: Radius.circular(4.r), - bottomRight: Radius.circular(4.r), - ), - ), - margin: EdgeInsets.only(right: 4.w), - child: quickText('作业', color: Colors.white, size: 10.sp), - ), - quickText( - jobTaskItem.title, - size: 16.sp, - color: Color.fromRGBO(70, 70, 70, 1), - fontWeight: FontWeight.bold, - ) - ], - ), - SizedBox(height: 12.h), - Row( - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - quickText( - jobTaskItem.subjectName, - color: Color.fromRGBO(97, 97, 97, 1), - size: 14.sp, - fontWeight: FontWeight.w600, - ), - quickText(' / ', color: Color.fromRGBO(130, 130, 130, 1), size: 12.sp, fontWeight: FontWeight.w500), - Container( - child: Row( - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - quickText('题量:', color: Color.fromRGBO(130, 130, 130, 1), size: 13.sp), - quickText( - jobTaskItem.totalCount, - color: Color.fromRGBO(97, 97, 97, 1), - size: 14.sp, - fontWeight: FontWeight.w500, - ), - ], - ), - ), - quickText(' / ', color: Color.fromRGBO(130, 130, 130, 1), size: 12.sp, fontWeight: FontWeight.w500), - quickText( - jobTaskItem.createTime.substring(0, 16), - color: Color.fromRGBO(97, 97, 97, 1), - size: 14.sp, - fontWeight: FontWeight.w500, - ), - ], - ), - SizedBox(height: 20.h), - $CompletedHomeworkInfoBox( - segmentation: false, - showStudentsCall: showStudentsCall, - unsubmittedQuantity: jobTaskItem.studentCount - jobTaskItem.commitStudentCount, - submittedQuantity: jobTaskItem.commitStudentCount, - precision: jobTaskItem.precision / 100, - objectivePrecision: jobTaskItem.objectivePrecision / 100, - subjectivePrecision: jobTaskItem.subjectivePrecision / 100, - ), - InkWell( - onTap: () { - RouterManager.router.navigateTo( - context, - RouterManager.jobReportPagePath + '?title=${Uri.encodeComponent(jobTaskItem.title)}&id=${jobTaskItem.id}', - transition: getTransition(), - ); - }, + Padding( + padding: EdgeInsets.symmetric(horizontal: 10.w), child: Row( children: [ - Expanded(flex: 1, child: SizedBox()), - Expanded( - flex: 9, - child: Container( - alignment: Alignment.center, - margin: EdgeInsets.only(top: 20.h), - padding: EdgeInsets.symmetric(vertical: 7.h), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(20), - gradient: LinearGradient( - begin: Alignment.centerLeft, - end: Alignment.centerRight, - colors: [Color.fromRGBO(95, 197, 255, 1), Color.fromRGBO(61, 68, 255, 0.82)], - ), + Container( + width: 32.w, + height: 18.h, + alignment: Alignment.center, + padding: EdgeInsets.only(left: 2.w), + decoration: BoxDecoration( + color: Color.fromRGBO(104, 136, 253, 1), + borderRadius: BorderRadius.only( + topLeft: Radius.circular(18.r), + topRight: Radius.circular(3.r), + bottomLeft: Radius.circular(4.r), + bottomRight: Radius.circular(4.r), ), - child: quickText('查看报告', color: Colors.white, size: 12.sp), ), + margin: EdgeInsets.only(right: 4.w), + child: quickText('作业', color: Colors.white, size: 10.sp), ), - Expanded(flex: 1, child: SizedBox()), + quickText( + jobTaskItem.title, + size: 16.sp, + color: Color.fromRGBO(70, 70, 70, 1), + fontWeight: FontWeight.bold, + ) ], ), - ) + ), + + SizedBox(height: 12.h), + Padding( + padding: EdgeInsets.symmetric(horizontal: 10.w), + child: Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + quickText( + jobTaskItem.createTime.substring(0, 10), + color: Color.fromRGBO(97, 97, 97, 1), + size: 14.sp, + fontWeight: FontWeight.w500, + ), + quickText(' / ', color: Color.fromRGBO(76, 199, 147, 1), size: 12.sp, fontWeight: FontWeight.w500), + quickText( + '参与班级:字段待定', + color: Color.fromRGBO(76, 199, 147, 1), + size: 12.sp, + fontWeight: FontWeight.w600, + ), + quickText(' / ', color: Color.fromRGBO(116, 145, 253, 1), size: 12.sp, fontWeight: FontWeight.w500), + quickText( + '科目:' + jobTaskItem.subjectName, + color: Color.fromRGBO(116, 145, 253, 1), + size: 12.sp, + fontWeight: FontWeight.w600, + ), + ], + ), + ), + + SizedBox(height: 20.h), + Container( + padding: EdgeInsets.symmetric(vertical: 8.h), + decoration: BoxDecoration( + borderRadius: BorderRadius.only(bottomLeft: Radius.circular(6.r), bottomRight: Radius.circular(6.r)), + color: Colors.white, + boxShadow: [ + BoxShadow( + color: const Color.fromRGBO(0, 0, 0, 0.15), + offset: Offset(0, -0.0001), //阴影y轴偏移量 + blurRadius: 4, //阴影模糊程度 + spreadRadius: 0, //阴影扩散程度 + ) + ], + ), + child: Row(children: [ + Expanded( + child: InkWell( + onTap: () => easyThrottle('go_to_homework_report', () => {}), + child: Container( + alignment: Alignment.center, + child: quickText('查看报告', color: Color.fromRGBO(118, 118, 118, 1), size: 12.sp), + ), + )), + ]), + ), + // $CompletedHomeworkInfoBox( + // segmentation: false, + // showStudentsCall: showStudentsCall, + // unsubmittedQuantity: jobTaskItem.studentCount - jobTaskItem.commitStudentCount, + // submittedQuantity: jobTaskItem.commitStudentCount, + // precision: jobTaskItem.precision / 100, + // objectivePrecision: jobTaskItem.objectivePrecision / 100, + // subjectivePrecision: jobTaskItem.subjectivePrecision / 100, + // ), + // InkWell( + // onTap: () { + // RouterManager.router.navigateTo( + // context, + // RouterManager.jobReportPagePath + '?title=${Uri.encodeComponent(jobTaskItem.title)}&id=${jobTaskItem.id}', + // transition: getTransition(), + // ); + // }, + // child: Row( + // children: [ + // Expanded(flex: 1, child: SizedBox()), + // Expanded( + // flex: 9, + // child: Container( + // alignment: Alignment.center, + // margin: EdgeInsets.only(top: 20.h), + // padding: EdgeInsets.symmetric(vertical: 7.h), + // decoration: BoxDecoration( + // borderRadius: BorderRadius.circular(20), + // gradient: LinearGradient( + // begin: Alignment.centerLeft, + // end: Alignment.centerRight, + // colors: [Color.fromRGBO(95, 197, 255, 1), Color.fromRGBO(61, 68, 255, 0.82)], + // ), + // ), + // child: quickText('查看报告', color: Colors.white, size: 12.sp), + // ), + // ), + // Expanded(flex: 1, child: SizedBox()), + // ], + // ), + // ) ], ), ); diff --git a/marking_app/lib/pages/homework_correction/index.dart b/marking_app/lib/pages/homework_correction/index.dart index 84b6783..2c45474 100644 --- a/marking_app/lib/pages/homework_correction/index.dart +++ b/marking_app/lib/pages/homework_correction/index.dart @@ -308,6 +308,7 @@ Widget $easyRefresh({ required int tab, }) { bool completed = tab == 2; // 是否是待批阅 + bool isPadFlag = isPad(); return EasyRefresh( firstRefresh: true, taskIndependence: true, @@ -317,18 +318,144 @@ Widget $easyRefresh({ controller: controller, header: MaterialHeader(), footer: TaurusFooter(), - child: ListView.builder( - padding: EdgeInsets.only(top: 11.h, bottom: 10.h, left: 16.w, right: 16.w), - itemBuilder: (context, index) { - return HomeworkTasksViewItem( - completed: completed, - jobTaskItem: data[index], - call: () => controller.callRefresh(), - ); - }, - itemCount: data.length, - ), + child: completed && isPadFlag + ? GridView( + padding: EdgeInsets.only(top: 11.h, bottom: 10.h, left: 12.w, right: 12.w), + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, //横轴三个子widget + mainAxisSpacing: 10.h, + crossAxisSpacing: 6.w, + childAspectRatio: 2.2 //宽高比为1时,子widget + ), + children: data.map((e) { + return $ReviewedItem(jobTaskItem: e); + }).toList(), + ) + : ListView.builder( + padding: EdgeInsets.only(top: 11.h, bottom: 10.h, left: 12.w, right: 12.w), + itemBuilder: (context, index) { + return HomeworkTasksViewItem( + completed: completed, + jobTaskItem: data[index], + call: () => controller.callRefresh(), + ); + }, + itemCount: data.length, + ), onRefresh: () => onRefresh(controller, params, tab), onLoad: () => onLoad(controller, params, tab), ); } + +@swidget +Widget $reviewedItem(BuildContext context, {required JobTaskItem jobTaskItem}) { + EdgeInsets padEdg = EdgeInsets.symmetric(horizontal: 10.w); + return Container( + padding: EdgeInsets.only(top: 10.h), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(6.r), + color: Colors.white, + boxShadow: [ + BoxShadow( + color: const Color.fromRGBO(210, 216, 241, 1), + offset: Offset.zero, //阴影y轴偏移量 + blurRadius: 5.8, //阴影模糊程度 + spreadRadius: 0, //阴影扩散程度 + ) + ], + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + // 顶部任务名称 + Padding( + padding: padEdg, + child: Row( + children: [ + Container( + width: 32.w, + height: 18.h, + alignment: Alignment.center, + padding: EdgeInsets.only(left: 2.w), + decoration: BoxDecoration( + color: jobTaskItem.markingTypeEnum.name == '作业' + ? const Color.fromRGBO(104, 136, 253, 1) + : const Color.fromRGBO(255, 175, 56, 1), + borderRadius: BorderRadius.only( + topLeft: Radius.circular(18.r), + topRight: Radius.circular(3.r), + bottomLeft: Radius.circular(4.r), + bottomRight: Radius.circular(4.r), + ), + ), + margin: EdgeInsets.only(right: 4.w), + child: quickText(jobTaskItem.markingTypeEnum.name, color: Colors.white, size: 10.sp), + ), + quickText( + jobTaskItem.title, + size: 16.sp, + color: Color.fromRGBO(70, 70, 70, 1), + fontWeight: FontWeight.bold, + ) + ], + ), + ), + + Padding( + padding: padEdg, + child: Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + quickText( + jobTaskItem.createTime.substring(0, 10), + color: Color.fromRGBO(97, 97, 97, 1), + size: 10.sp, + fontWeight: FontWeight.w500, + ), + quickText(' / ', color: Color.fromRGBO(76, 199, 147, 1), size: 10.sp, fontWeight: FontWeight.w500), + quickText( + '参与班级:2', + color: Color.fromRGBO(76, 199, 147, 1), + size: 10.sp, + fontWeight: FontWeight.w600, + ), + quickText(' / ', color: Color.fromRGBO(116, 145, 253, 1), size: 10.sp, fontWeight: FontWeight.w500), + quickText( + '科目:' + jobTaskItem.subjectName, + color: Color.fromRGBO(116, 145, 253, 1), + size: 10.sp, + fontWeight: FontWeight.w600, + ), + ], + ), + ), + + Container( + padding: EdgeInsets.symmetric(vertical: 6.h), + decoration: BoxDecoration( + borderRadius: BorderRadius.only(bottomLeft: Radius.circular(6.r), bottomRight: Radius.circular(6.r)), + color: Colors.white, + boxShadow: [ + BoxShadow( + color: const Color.fromRGBO(0, 0, 0, 0.15), + offset: Offset(0, -0.0001), //阴影y轴偏移量 + blurRadius: 4, //阴影模糊程度 + spreadRadius: 0, //阴影扩散程度 + ) + ], + ), + child: Row(children: [ + Expanded( + child: InkWell( + onTap: () => easyThrottle('go_to_homework_report', () => {}), + child: Container( + alignment: Alignment.center, + child: quickText('查看报告', color: Color.fromRGBO(118, 118, 118, 1), size: 11.sp), + ), + )), + ]), + ), + ], + ), + ); +} diff --git a/marking_app/lib/pages/homework_correction/pages/job_list_participate_in_class.dart b/marking_app/lib/pages/homework_correction/pages/job_list_participate_in_class.dart index 38a3970..429bb86 100644 --- a/marking_app/lib/pages/homework_correction/pages/job_list_participate_in_class.dart +++ b/marking_app/lib/pages/homework_correction/pages/job_list_participate_in_class.dart @@ -1,16 +1,18 @@ import 'package:achievement_view/achievement_view.dart'; import 'package:flutter/material.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.dart'; import 'package:marking_app/common/model/job/job_task_item.dart'; import 'package:marking_app/routes/RouterManager.dart'; import 'package:marking_app/utils/index.dart'; -import 'package:marking_app/utils/my_future_builder.dart'; import 'package:marking_app/utils/my_text.dart'; import 'package:marking_app/utils/request/rest_client.dart'; import 'package:percent_indicator/linear_percent_indicator.dart'; +part 'job_list_participate_in_class.g.dart'; + class JobListParticipateInClass extends StatefulWidget { final int jobId; final String jobName; @@ -31,6 +33,10 @@ class _JobListParticipateInClassState extends State w // TODO: implement initState super.initState(); _future = getData(); + Future.delayed(Duration.zero, () { + print(ScreenUtil().scaleWidth); + print(MediaQuery.of(context).devicePixelRatio); + }); } @override @@ -45,21 +51,60 @@ class _JobListParticipateInClassState extends State w return _result.data; } - // 结束批阅方法 - Future endReview(List markingTasks) async { - try { - ToastUtils.showLoading(); - RestClient client = await getClient(); - BaseStructureResult res = await client.toEndReviewJob(markingTasks.map((e) => e.id).toList()); - if (!res.success) ToastUtils.showError('结束失败,请重试'); - return res.success; - } catch (e) { - ToastUtils.showError('结束失败,请重试'); - return false; - } - } - + // 一键批阅 void oneClickReview(int taskId) async { + var continueFlag = await showDialog( + context: context, + builder: (BuildContext context1) { + return Center( + child: Container( + padding: EdgeInsets.symmetric(vertical: 25.h, horizontal: 18.w), + decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadiusDirectional.circular(12.r)), + height: 150.h, + width: 280.w, + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + children: [ + Expanded( + child: quickText('一键批阅后,默认学生答题结果全部正确,是否进行此操作?', + maxLines: 3, size: 14.sp, color: Color.fromRGBO(80, 94, 110, 1))) + ], + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + InkWell( + onTap: () { + Navigator.of(context1).pop(false); + }, + child: Container( + padding: EdgeInsetsDirectional.symmetric(horizontal: 36.w, vertical: 7.h), + decoration: BoxDecoration( + color: Color.fromRGBO(244, 244, 244, 1), borderRadius: BorderRadius.circular(20.r)), + child: quickText('取消', size: 14.sp, color: Color.fromRGBO(102, 102, 102, 1)), + ), + ), + InkWell( + onTap: () { + Navigator.of(context1).pop(true); + }, + child: Container( + padding: EdgeInsetsDirectional.symmetric(horizontal: 36.w, vertical: 7.h), + decoration: BoxDecoration( + color: Theme.of(context).primaryColor, borderRadius: BorderRadius.circular(20.r)), + child: quickText('确认', size: 14.sp, color: Color.fromRGBO(255, 255, 255, 1)), + ), + ), + ], + ) + ], + ), + )); + }, + ); + if (continueFlag == null || !continueFlag) return; try { ToastUtils.showLoading(); RestClient _client = await getClient(); @@ -77,6 +122,138 @@ class _JobListParticipateInClassState extends State w } } + /// 前往批阅 + void goToReview(MarkingTasks task) { + if (task.totalCount <= 0) { + return ToastUtils.showInfo('没有找到可以批阅的任务'); + } + + if (!task.canMarking) { + return AchievementView( + elevation: 0.5, + duration: Duration(seconds: 1), + title: "提示", + subTitle: "此账号无法批阅该任务", + color: Theme.of(context).primaryColor, + ).show(context); + } + + if (task.isFinish) { + return AchievementView( + elevation: 0.5, + duration: Duration(seconds: 1), + title: "提示", + subTitle: "此批阅任务已完成", + color: Theme.of(context).primaryColor, + ).show(context); + } + + String url = + '${RouterManager.markingHomeworkDoPath}?taskId=${task.id}&jobId=${widget.jobId}&taskName=${Uri.encodeComponent(widget.jobName)}&className=${Uri.encodeComponent(widget.genderName + task.className)}'; + RouterManager.router.navigateTo(context, url, transition: getTransition()).then((value) { + if (value == true) { + isRefresh = true; + _future = getData(); + toUpState(setState, () {}, mounted); + } + }); + } + + // 结束批阅请求方法 + Future endReviewInitialRequest(List markingTasks) async { + try { + ToastUtils.showLoading(); + RestClient client = await getClient(); + BaseStructureResult res = await client.toEndReviewJob(markingTasks.map((e) => e.id).toList()); + if (!res.success) ToastUtils.showError('结束失败,请重试'); + return res.success; + } catch (e) { + ToastUtils.showError('结束失败,请重试'); + return false; + } + } + + void endReview(MarkingTasks task) async { + /// 结束批阅逻辑 + if (!task.canMarking) return ToastUtils.showInfo('此任务非该账号任务'); + if (task.isFinish) return ToastUtils.showInfo('此任务已经结束'); + + // 未完成批阅任务提示 + if (task.finishCount < task.totalCount) { + var continueFlag = await showDialog( + context: context, + builder: (BuildContext context1) { + return AlertDialog( + title: Text('未完成批阅提示'), + content: Text('当前批阅任务未完成,请确认需要结束此任务?'), + actions: [ + TextButton( + child: Text('否'), + onPressed: () { + // 在这里处理删除操作 + Navigator.of(context1).pop(false); + }, + ), + TextButton( + child: Text('是'), + onPressed: () { + Navigator.of(context1).pop(true); + }, + ), + ], + ); + }, + ); + if (continueFlag == null || !continueFlag) { + return; + } + } + + showDialog( + context: context, + builder: (BuildContext context1) { + return AlertDialog( + title: Text('提示'), + content: Text('确认完成当前${task.className}批阅任务?'), + actions: [ + TextButton( + child: Text('否'), + onPressed: () { + // 在这里处理删除操作 + Navigator.of(context1).pop(); + }, + ), + TextButton( + child: Text('确定'), + onPressed: () async { + try { + bool result = await endReviewInitialRequest([task]); + if (result) { + isRefresh = true; + _future = getData(); + toUpState(setState, () {}, mounted); + } + } catch (e) { + } finally { + ToastUtils.dismiss(); + Navigator.of(context1).pop(); + } + }, + ), + ], + ); + }, + ); + } + + // 收藏夹 + void bookmarks(MarkingTasks task) {} + + // 数据快查 + void quickDataCheck(MarkingTasks task) {} + + // 查看作业报告 + void jobViewReport(MarkingTasks task) {} @override Widget build(BuildContext context) { return Scaffold( @@ -95,353 +272,722 @@ class _JobListParticipateInClassState extends State w body: MyFutureBuilder.buildFutureBuilderOfSingleInstance?>(context, _future, (value) { if (value == null) return Container(); - return ListView( - padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 16.w), - children: value.map((e) { - return Container( - padding: EdgeInsets.only(top: 11.h), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadiusDirectional.circular(10.r), - boxShadow: [ - BoxShadow( - color: Color.fromRGBO(0, 0, 0, 0.15), - blurRadius: 10, - ), - ], - ), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Padding( - padding: EdgeInsets.only(left: 10.w, right: 10.w), - child: Row( - children: [ - quickText(widget.genderName + e.className, color: Color.fromRGBO(0, 0, 0, 1), size: 14.sp), - Expanded(child: SizedBox()), - quickText('已交:${e.commitStudentCount}', color: Color.fromRGBO(104, 136, 253, 1), size: 12.sp), - SizedBox(width: 16.w), - quickText('未交:${e.studentCount - e.commitStudentCount}', - color: Color.fromRGBO(255, 86, 86, 1), size: 12.sp), - ], - ), - ), - SizedBox(height: 13.h), - Padding( - padding: EdgeInsets.only(left: 10.w, right: 10.w), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - flex: 3, - child: Material( - color: Color.fromRGBO(104, 136, 253, 1), - borderRadius: BorderRadius.circular(16.r), - child: InkWell( - onTap: () => easyThrottle('OneClickReview', () async { - var continueFlag = await showDialog( - context: context, - builder: (BuildContext context1) { - return Center( - child: Container( - padding: EdgeInsets.symmetric(vertical: 25.h, horizontal: 18.w), - decoration: BoxDecoration( - color: Colors.white, borderRadius: BorderRadiusDirectional.circular(12.r)), - height: 150.h, - width: 280.w, - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Row( - children: [ - Expanded( - child: quickText('一键批阅后,默认学生答题结果全部正确,是否进行此操作?', - maxLines: 3, - size: 14.sp, - color: Color.fromRGBO(80, 94, 110, 1))) - ], - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - InkWell( - onTap: () { - Navigator.of(context1).pop(false); - }, - child: Container( - padding: EdgeInsetsDirectional.symmetric( - horizontal: 36.w, vertical: 7.h), - decoration: BoxDecoration( - color: Color.fromRGBO(244, 244, 244, 1), - borderRadius: BorderRadius.circular(20.r)), - child: quickText('取消', - size: 14.sp, color: Color.fromRGBO(102, 102, 102, 1)), - ), - ), - InkWell( - onTap: () { - Navigator.of(context1).pop(true); - }, - child: Container( - padding: EdgeInsetsDirectional.symmetric( - horizontal: 36.w, vertical: 7.h), - decoration: BoxDecoration( - color: Theme.of(context).primaryColor, - borderRadius: BorderRadius.circular(20.r)), - child: quickText('确认', - size: 14.sp, color: Color.fromRGBO(255, 255, 255, 1)), - ), - ), - ], - ) - ], - ), - )); - }, - ); - if (continueFlag == null || !continueFlag) return; - oneClickReview(e.id); - }), - borderRadius: BorderRadius.circular(8.r), - child: Container( - alignment: Alignment.center, - padding: EdgeInsets.symmetric(vertical: 5.h), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(20.r), - ), - child: quickText('一键批阅', size: 10.sp, color: Colors.white), - ), - ), - ), - ), - Expanded(flex: 1, child: SizedBox()), - Expanded( - flex: 3, - child: Material( - color: Color.fromRGBO(244, 244, 244, 1), - borderRadius: BorderRadius.circular(20.r), - child: InkWell( - onTap: () async {}, - borderRadius: BorderRadius.circular(8.r), - child: Container( - alignment: Alignment.center, - padding: EdgeInsets.symmetric(vertical: 5.h), - decoration: BoxDecoration(borderRadius: BorderRadius.circular(20.r)), - child: quickText('数据快查', size: 10.sp, color: Color.fromRGBO(102, 102, 102, 1)), - ), - ), - ), - ), - Expanded(flex: 1, child: SizedBox()), - Expanded( - flex: 3, - child: Material( - color: Color.fromRGBO(244, 244, 244, 1), - borderRadius: BorderRadius.circular(20.r), - child: InkWell( - onTap: () async {}, - borderRadius: BorderRadius.circular(8.r), - child: Container( - alignment: Alignment.center, - padding: EdgeInsets.symmetric(vertical: 5.h), - decoration: BoxDecoration(borderRadius: BorderRadius.circular(20.r)), - child: quickText('收藏夹(2)', size: 10.sp, color: Color.fromRGBO(102, 102, 102, 1)), - ), - ), - )), - ], - ), - ), - SizedBox(height: 13.h), - Padding( - padding: EdgeInsets.only(left: 10.w, right: 10.w), - child: Row( - children: [ - Expanded( - child: LinearPercentIndicator( - padding: EdgeInsets.zero, - animation: true, - lineHeight: 6.h, - animationDuration: 2500, + if (isPad()) + return TabletEnd( + data: value, + genderName: widget.genderName, + bookmarks: bookmarks, + endReview: endReview, + goToReview: goToReview, + jobViewReport: jobViewReport, + quickDataCheck: quickDataCheck, + oneClickReview: oneClickReview, + ); - percent: e.progressPercentage / 100, - // center: Text( - // '${getDoubleRemoveZero(jobTaskClassItem.progressPercentage)}%', - // style: TextStyle(color: Colors.white, fontSize: 8.sp), - // ), - linearGradient: LinearGradient( - tileMode: TileMode.mirror, - stops: [0.0, 1.0], - colors: e.progressPercentage / 100 != 1 - ? [Theme.of(context).primaryColor.withOpacity(0.1), Theme.of(context).primaryColor] - : [ - Color.fromRGBO(144, 224, 190, 1).withOpacity(0.1), - Color.fromRGBO(144, 224, 190, 1), - ], - ), - // linearStrokeCap: LinearStrokeCap.butt, - // progressColor: Theme.of(context).primaryColor, - backgroundColor: Color.fromRGBO(232, 232, 232, 1), - barRadius: Radius.circular(10.r), - ), - ), - SizedBox(width: 7.w), - quickText('${getDoubleRemoveZero(e.progressPercentage)}%', - size: 10.sp, color: Color.fromRGBO(70, 70, 70, 1)) - ], - ), - ), - SizedBox(height: 13.h), - Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.only( - bottomLeft: Radius.circular(10.r), - bottomRight: Radius.circular(10.r), - ), - color: Colors.white, - boxShadow: [ - BoxShadow( - color: const Color.fromRGBO(0, 0, 0, 0.15), - offset: Offset(0, -0.0001), //阴影y轴偏移量 - blurRadius: 5, //阴影模糊程度 - spreadRadius: 0, //阴影扩散程度 - ) - ], - ), - child: Row( - children: [ - Expanded( - child: InkWell( - onTap: () { - if (e.totalCount <= 0) { - return ToastUtils.showInfo('没有找到可以批阅的任务'); - } - - if (!e.canMarking) { - return AchievementView( - elevation: 0.5, - duration: Duration(seconds: 1), - title: "提示", - subTitle: "此账号无法批阅该任务", - color: Theme.of(context).primaryColor, - ).show(context); - } - - if (e.isFinish) { - return AchievementView( - elevation: 0.5, - duration: Duration(seconds: 1), - title: "提示", - subTitle: "此批阅任务已完成", - color: Theme.of(context).primaryColor, - ).show(context); - } - - String url = - '${RouterManager.markingHomeworkDoPath}?taskId=${e.id}&jobId=${widget.jobId}&taskName=${Uri.encodeComponent(widget.jobName)}&className=${Uri.encodeComponent(widget.genderName + e.className)}'; - RouterManager.router - .navigateTo(context, url, transition: getTransition()) - .then((value) { - if (value == true) { - isRefresh = true; - _future = getData(); - toUpState(setState, () {}, mounted); - } - }); - }, - child: Container( - alignment: Alignment.center, - child: quickText('批阅', color: Color.fromRGBO(79, 79, 79, 1), size: 13.sp), - ), - ), - ), - Container(width: 1.w, height: 32.h, color: Color.fromRGBO(221, 221, 221, 1)), - Expanded( - child: InkWell( - onTap: () async { - if (!e.canMarking) return ToastUtils.showInfo('此任务非该账号任务'); - if (e.isFinish) return ToastUtils.showInfo('此任务已经结束'); - - // 未完成批阅任务提示 - if (e.finishCount < e.totalCount) { - var continueFlag = await showDialog( - context: context, - builder: (BuildContext context1) { - return AlertDialog( - title: Text('未完成批阅提示'), - content: Text('当前批阅任务未完成,请确认需要结束此任务?'), - actions: [ - TextButton( - child: Text('否'), - onPressed: () { - // 在这里处理删除操作 - Navigator.of(context1).pop(false); - }, - ), - TextButton( - child: Text('是'), - onPressed: () { - Navigator.of(context1).pop(true); - }, - ), - ], - ); - }, - ); - if (continueFlag == null || !continueFlag) { - return; - } - } - - showDialog( - context: context, - builder: (BuildContext context1) { - return AlertDialog( - title: Text('提示'), - content: Text('确认完成当前${e.className}批阅任务?'), - actions: [ - TextButton( - child: Text('否'), - onPressed: () { - // 在这里处理删除操作 - Navigator.of(context1).pop(); - }, - ), - TextButton( - child: Text('确定'), - onPressed: () async { - try { - bool result = await endReview([e]); - if (result) { - isRefresh = true; - _future = getData(); - toUpState(setState, () {}, mounted); - } - } catch (e) { - } finally { - ToastUtils.dismiss(); - Navigator.of(context1).pop(); - } - }, - ), - ], - ); - }, - ); - }, - child: Container( - alignment: Alignment.center, - child: quickText('结束批阅', color: Color.fromRGBO(118, 118, 118, 1), size: 12.sp), - ), - )), - ], - ), - ), - ], - )); - }).toList(), + return MobileEnd( + data: value, + genderName: widget.genderName, + bookmarks: bookmarks, + endReview: endReview, + goToReview: goToReview, + jobViewReport: jobViewReport, + quickDataCheck: quickDataCheck, + oneClickReview: oneClickReview, ); }), ); } } + +/// 平板电脑端 +class TabletEnd extends StatelessWidget { + final String genderName; + final List data; + + final EndReview endReview; // 结束批阅 + final Bookmarks bookmarks; // 收藏夹 + final GoToReview goToReview; // 前往批阅 + final JobViewReport jobViewReport; + final OneClickReview oneClickReview; // 一键批阅 + final QuickDataCheck quickDataCheck; // 数据快查 + const TabletEnd({ + required this.genderName, + required this.data, + + /// 方法 + required this.endReview, + required this.bookmarks, + required this.goToReview, + required this.jobViewReport, + required this.oneClickReview, + required this.quickDataCheck, + super.key, + }); + + @override + Widget build(BuildContext context) { + return Container( + width: ScreenUtil().screenWidth, + padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 16.h), + child: Wrap( + spacing: 8.0.w, // 子元素之间的间距 + runSpacing: 10.h, // 主轴方向上不同行之间的间距 + children: [...data, ...data, ...data] + .map((e) => $ItemDataViewOfPad( + task: e, + bookmarks: bookmarks, + endReview: endReview, + genderName: genderName, + goToReview: goToReview, + jobViewReport: jobViewReport, + quickDataCheck: quickDataCheck, + oneClickReview: oneClickReview, + )) + .toList(), + ), + ); + } +} + +/// 移动端 +class MobileEnd extends StatelessWidget { + final String genderName; + final List data; + + final EndReview endReview; // 结束批阅 + final Bookmarks bookmarks; // 收藏夹 + final GoToReview goToReview; // 前往批阅 + final JobViewReport jobViewReport; + final OneClickReview oneClickReview; // 一键批阅 + final QuickDataCheck quickDataCheck; // 数据快查 + + const MobileEnd({ + required this.genderName, + required this.data, + + /// 方法 + required this.endReview, + required this.bookmarks, + required this.goToReview, + required this.jobViewReport, + required this.oneClickReview, + required this.quickDataCheck, + super.key, + }); + + @override + Widget build(BuildContext context) { + return ListView( + padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 16.h), + children: data.map((e) { + return $ItemDataView( + task: e, + bookmarks: bookmarks, + endReview: endReview, + genderName: genderName, + goToReview: goToReview, + jobViewReport: jobViewReport, + quickDataCheck: quickDataCheck, + oneClickReview: oneClickReview, + ); + }).toList(), + ); + } +} + +/// pad item view +@swidget +Widget $itemDataViewOfPad( + BuildContext context, { + required MarkingTasks task, + required String genderName, + + /// 方法 + required EndReview endReview, + required Bookmarks bookmarks, + required GoToReview goToReview, + required JobViewReport jobViewReport, + required OneClickReview oneClickReview, + required QuickDataCheck quickDataCheck, +}) { + EdgeInsets edgins = EdgeInsets.only(left: 8.w, right: 8.w); + return Container( + width: ScreenUtil().screenWidth / 2 - (12.w + 4.w), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadiusDirectional.circular(4.r), + boxShadow: [BoxShadow(color: Color.fromRGBO(0, 0, 0, 0.15), blurRadius: 10)], + ), + padding: EdgeInsets.only(top: 10.h), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Padding( + padding: edgins, + child: Row( + children: [ + quickText(genderName + task.className, color: Color.fromRGBO(0, 0, 0, 1), size: 10.sp), + Expanded(child: SizedBox()), + quickText('已交:${task.commitStudentCount}', color: Color.fromRGBO(104, 136, 253, 1), size: 8.sp), + SizedBox(width: 10.w), + quickText('未交:${task.studentCount - task.commitStudentCount}', + color: Color.fromRGBO(255, 86, 86, 1), size: 8.sp), + ], + ), + ), + SizedBox(height: 10.h), + Padding( + padding: edgins, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: task.isFinish + ? [ + Expanded( + flex: 3, + child: Material( + color: Color.fromRGBO(244, 244, 244, 1), + borderRadius: BorderRadius.circular(20.r), + child: InkWell( + onTap: () async {}, + borderRadius: BorderRadius.circular(8.r), + child: Container( + alignment: Alignment.center, + padding: EdgeInsets.symmetric(vertical: 3.h), + decoration: BoxDecoration(borderRadius: BorderRadius.circular(20.r)), + child: quickText('收藏夹(2)', size: 8.sp, color: Color.fromRGBO(102, 102, 102, 1)), + ), + ), + )), + Expanded(flex: 1, child: SizedBox()), + Expanded(flex: 3, child: SizedBox()), + Expanded(flex: 1, child: SizedBox()), + Expanded(flex: 3, child: SizedBox()), + ] + : [ + Expanded( + flex: 3, + child: Material( + color: Color.fromRGBO(104, 136, 253, 1), + borderRadius: BorderRadius.circular(16.r), + child: InkWell( + onTap: () => easyThrottle('OneClickReview', () => oneClickReview(task.id)), + borderRadius: BorderRadius.circular(8.r), + child: Container( + alignment: Alignment.center, + padding: EdgeInsets.symmetric(vertical: 3.h), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(20.r), + ), + child: quickText('一键批阅', size: 8.sp, color: Colors.white), + ), + ), + ), + ), + Expanded(flex: 1, child: SizedBox()), + Expanded( + flex: 3, + child: Material( + color: Color.fromRGBO(244, 244, 244, 1), + borderRadius: BorderRadius.circular(20.r), + child: InkWell( + onTap: () async {}, + borderRadius: BorderRadius.circular(8.r), + child: Container( + alignment: Alignment.center, + padding: EdgeInsets.symmetric(vertical: 3.h), + decoration: BoxDecoration(borderRadius: BorderRadius.circular(20.r)), + child: quickText('数据快查', size: 8.sp, color: Color.fromRGBO(102, 102, 102, 1)), + ), + ), + ), + ), + Expanded(flex: 1, child: SizedBox()), + Expanded( + flex: 3, + child: Material( + color: Color.fromRGBO(244, 244, 244, 1), + borderRadius: BorderRadius.circular(20.r), + child: InkWell( + onTap: () async {}, + borderRadius: BorderRadius.circular(8.r), + child: Container( + alignment: Alignment.center, + padding: EdgeInsets.symmetric(vertical: 3.h), + decoration: BoxDecoration(borderRadius: BorderRadius.circular(20.r)), + child: quickText('收藏夹(2)', size: 8.sp, color: Color.fromRGBO(102, 102, 102, 1)), + ), + ), + )), + ], + ), + ), + SizedBox(height: 8.h), + Padding( + padding: EdgeInsets.only(left: 10.w, right: 10.w), + child: Row( + children: [ + Expanded( + child: LinearPercentIndicator( + padding: EdgeInsets.zero, + animation: true, + lineHeight: 5.h, + animationDuration: 2500, + percent: task.progressPercentage / 100, + linearGradient: LinearGradient( + tileMode: TileMode.mirror, + stops: [0.0, 1.0], + colors: task.progressPercentage / 100 != 1 + ? [Theme.of(context).primaryColor.withOpacity(0.1), Theme.of(context).primaryColor] + : [ + Color.fromRGBO(144, 224, 190, 1).withOpacity(0.1), + Color.fromRGBO(144, 224, 190, 1), + ], + ), + backgroundColor: Color.fromRGBO(232, 232, 232, 1), + barRadius: Radius.circular(10.r), + ), + ), + SizedBox(width: 7.w), + quickText('${getDoubleRemoveZero(task.progressPercentage)}%', + size: 8.sp, color: Color.fromRGBO(70, 70, 70, 1)) + ], + ), + ), + if (task.isFinish) + $CompletedHomeworkProgressBar( + fontSize: 8.sp, + lineHeight: 6.h, + color: Color.fromRGBO(76, 199, 147, 1), + percent: task.objectivePrecision, + title: '客观题正确率:', + padingEdg: edgins, + marginEdg: EdgeInsets.only(top: 8.h), + ), + if (task.isFinish) + $CompletedHomeworkProgressBar( + fontSize: 8.sp, + lineHeight: 6.h, + color: Color.fromRGBO(255, 190, 91, 1), + percent: task.subjectivePrecision, + title: '主观题正确率:', + padingEdg: edgins, + marginEdg: EdgeInsets.only(top: 8.h), + ), + if (task.isFinish) + $CompletedHomeworkProgressBar( + fontSize: 8.sp, + lineHeight: 6.h, + color: Color.fromRGBO(166, 139, 242, 1), + percent: task.precision, + title: '总正确率:', + padingEdg: edgins, + marginEdg: EdgeInsets.only(top: 8.h), + ), + SizedBox(height: 8.h), + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.only(bottomLeft: Radius.circular(4.r), bottomRight: Radius.circular(4.r)), + color: Colors.white, + boxShadow: [ + BoxShadow( + color: const Color.fromRGBO(0, 0, 0, 0.15), + offset: Offset(0, -0.0001), //阴影y轴偏移量 + blurRadius: 4, //阴影模糊程度 + spreadRadius: 0, //阴影扩散程度 + ) + ], + ), + child: Row( + children: task.isFinish + ? [ + Expanded( + child: InkWell( + onTap: () => easyThrottle('go_to_review_homework', () => quickDataCheck(task)), + child: Container( + alignment: Alignment.center, + child: quickText('数据快查', color: Color.fromRGBO(79, 79, 79, 1), size: 13.sp), + ), + ), + ), + Container(width: 1.w, height: 32.h, color: Color.fromRGBO(221, 221, 221, 1)), + Expanded( + child: InkWell( + onTap: () => easyThrottle('go_to_end_review_homework', () => jobViewReport(task)), + child: Container( + alignment: Alignment.center, + child: quickText('查看报告', color: Color.fromRGBO(118, 118, 118, 1), size: 12.sp), + ), + )), + ] + : [ + Expanded( + child: InkWell( + onTap: () => easyThrottle('go_to_review_homework', () => goToReview(task)), + child: Container( + alignment: Alignment.center, + child: quickText('批阅', color: Color.fromRGBO(79, 79, 79, 1), size: 11.sp), + ), + ), + ), + Container(width: 0.3.w, height: 24.h, color: Color.fromRGBO(221, 221, 221, 1)), + Expanded( + child: InkWell( + onTap: () => easyThrottle('go_to_end_review_homework', () => endReview(task)), + child: Container( + alignment: Alignment.center, + child: quickText('结束批阅', color: Color.fromRGBO(118, 118, 118, 1), size: 10.sp), + ), + )), + ], + ), + ), + ], + ), + ); +} + +/// item view +@swidget +Widget $itemDataView( + BuildContext context, { + required MarkingTasks task, + required String genderName, + + /// 方法 + required EndReview endReview, + required Bookmarks bookmarks, + required GoToReview goToReview, + required OneClickReview oneClickReview, + required QuickDataCheck quickDataCheck, + required JobViewReport jobViewReport, +}) { + var padingEdg = EdgeInsets.only(left: 10.w, right: 10.w); + return Container( + padding: EdgeInsets.only(top: 11.h), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadiusDirectional.circular(10.r), + boxShadow: [BoxShadow(color: Color.fromRGBO(0, 0, 0, 0.15), blurRadius: 10)], + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Padding( + padding: padingEdg, + child: Row( + children: [ + quickText(genderName + task.className, color: Color.fromRGBO(0, 0, 0, 1), size: 14.sp), + Expanded(child: SizedBox()), + quickText('已交:${task.commitStudentCount}', color: Color.fromRGBO(104, 136, 253, 1), size: 12.sp), + SizedBox(width: 16.w), + quickText('未交:${task.studentCount - task.commitStudentCount}', + color: Color.fromRGBO(255, 86, 86, 1), size: 12.sp), + ], + ), + ), + SizedBox(height: 13.h), + Padding( + padding: padingEdg, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: task.isFinish + ? [ + Expanded( + flex: 3, + child: Material( + color: Color.fromRGBO(244, 244, 244, 1), + borderRadius: BorderRadius.circular(20.r), + child: InkWell( + onTap: () async {}, + borderRadius: BorderRadius.circular(8.r), + child: Container( + alignment: Alignment.center, + padding: EdgeInsets.symmetric(vertical: 5.h), + decoration: BoxDecoration(borderRadius: BorderRadius.circular(20.r)), + child: quickText('收藏夹(2)', size: 10.sp, color: Color.fromRGBO(102, 102, 102, 1)), + ), + ), + )), + Expanded(flex: 1, child: SizedBox()), + Expanded(flex: 3, child: SizedBox()), + Expanded(flex: 1, child: SizedBox()), + Expanded(flex: 3, child: SizedBox()), + ] + : [ + Expanded( + flex: 3, + child: Material( + color: Color.fromRGBO(104, 136, 253, 1), + borderRadius: BorderRadius.circular(16.r), + child: InkWell( + onTap: () => easyThrottle('OneClickReview', () => oneClickReview(task.id)), + borderRadius: BorderRadius.circular(8.r), + child: Container( + alignment: Alignment.center, + padding: EdgeInsets.symmetric(vertical: 5.h), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(20.r), + ), + child: quickText('一键批阅', size: 10.sp, color: Colors.white), + ), + ), + ), + ), + Expanded(flex: 1, child: SizedBox()), + Expanded( + flex: 3, + child: Material( + color: Color.fromRGBO(244, 244, 244, 1), + borderRadius: BorderRadius.circular(20.r), + child: InkWell( + onTap: () async {}, + borderRadius: BorderRadius.circular(8.r), + child: Container( + alignment: Alignment.center, + padding: EdgeInsets.symmetric(vertical: 5.h), + decoration: BoxDecoration(borderRadius: BorderRadius.circular(20.r)), + child: quickText('数据快查', size: 10.sp, color: Color.fromRGBO(102, 102, 102, 1)), + ), + ), + ), + ), + Expanded(flex: 1, child: SizedBox()), + Expanded( + flex: 3, + child: Material( + color: Color.fromRGBO(244, 244, 244, 1), + borderRadius: BorderRadius.circular(20.r), + child: InkWell( + onTap: () async {}, + borderRadius: BorderRadius.circular(8.r), + child: Container( + alignment: Alignment.center, + padding: EdgeInsets.symmetric(vertical: 5.h), + decoration: BoxDecoration(borderRadius: BorderRadius.circular(20.r)), + child: quickText('收藏夹(2)', size: 10.sp, color: Color.fromRGBO(102, 102, 102, 1)), + ), + ), + )), + ], + ), + ), + SizedBox(height: 13.h), + Padding( + padding: padingEdg, + child: Row( + children: [ + Expanded( + child: LinearPercentIndicator( + padding: EdgeInsets.zero, + animation: true, + lineHeight: 8.h, + animationDuration: 2500, + + percent: task.progressPercentage / 100, + // center: Text( + // '${getDoubleRemoveZero(jobTaskClassItem.progressPercentage)}%', + // style: TextStyle(color: Colors.white, fontSize: 8.sp), + // ), + linearGradient: LinearGradient( + tileMode: TileMode.mirror, + stops: [0.0, 1.0], + colors: task.progressPercentage / 100 != 1 + ? [Theme.of(context).primaryColor.withOpacity(0.1), Theme.of(context).primaryColor] + : [ + Color.fromRGBO(144, 224, 190, 1).withOpacity(0.1), + Color.fromRGBO(144, 224, 190, 1), + ], + ), + // linearStrokeCap: LinearStrokeCap.butt, + // progressColor: Theme.of(context).primaryColor, + backgroundColor: Color.fromRGBO(232, 232, 232, 1), + barRadius: Radius.circular(10.r), + ), + ), + SizedBox(width: 7.w), + quickText('${getDoubleRemoveZero(task.progressPercentage)}%', + size: 10.sp, color: Color.fromRGBO(70, 70, 70, 1)) + ], + ), + ), + if (task.isFinish) + $CompletedHomeworkProgressBar( + color: Color.fromRGBO(76, 199, 147, 1), + percent: task.objectivePrecision, + title: '客观题正确率:', + padingEdg: padingEdg, + marginEdg: EdgeInsets.only(top: 8.h), + ), + if (task.isFinish) + $CompletedHomeworkProgressBar( + color: Color.fromRGBO(255, 190, 91, 1), + percent: task.subjectivePrecision, + title: '主观题正确率:', + padingEdg: padingEdg, + marginEdg: EdgeInsets.only(top: 8.h), + ), + if (task.isFinish) + $CompletedHomeworkProgressBar( + color: Color.fromRGBO(166, 139, 242, 1), + percent: task.precision, + title: '总正确率:', + padingEdg: padingEdg, + marginEdg: EdgeInsets.only(top: 8.h), + ), + SizedBox(height: 13.h), + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.only( + bottomLeft: Radius.circular(10.r), + bottomRight: Radius.circular(10.r), + ), + color: Colors.white, + boxShadow: [ + BoxShadow( + color: const Color.fromRGBO(0, 0, 0, 0.15), + offset: Offset(0, -0.0001), //阴影y轴偏移量 + blurRadius: 5, //阴影模糊程度 + spreadRadius: 0, //阴影扩散程度 + ) + ], + ), + child: Row( + children: task.isFinish + ? [ + Expanded( + child: InkWell( + onTap: () => easyThrottle('go_to_review_homework', () => quickDataCheck(task)), + child: Container( + alignment: Alignment.center, + child: quickText('数据快查', color: Color.fromRGBO(79, 79, 79, 1), size: 13.sp), + ), + ), + ), + Container(width: 1.w, height: 32.h, color: Color.fromRGBO(221, 221, 221, 1)), + Expanded( + child: InkWell( + onTap: () => easyThrottle('go_to_end_review_homework', () => jobViewReport(task)), + child: Container( + alignment: Alignment.center, + child: quickText('查看报告', color: Color.fromRGBO(118, 118, 118, 1), size: 12.sp), + ), + )), + ] + : [ + Expanded( + child: InkWell( + onTap: () => easyThrottle('go_to_review_homework', () => goToReview(task)), + child: Container( + alignment: Alignment.center, + child: quickText('批阅', color: Color.fromRGBO(79, 79, 79, 1), size: 13.sp), + ), + ), + ), + Container(width: 1.w, height: 32.h, color: Color.fromRGBO(221, 221, 221, 1)), + Expanded( + child: InkWell( + onTap: () => easyThrottle('go_to_end_review_homework', () => endReview(task)), + child: Container( + alignment: Alignment.center, + child: quickText('结束批阅', color: Color.fromRGBO(118, 118, 118, 1), size: 12.sp), + ), + )), + ], + ), + ), + ], + )); +} + +@swidget +Widget $completedHomeworkProgressBar( + BuildContext context, { + double? fontSize, + double? lineHeight, + required String title, + required Color color, + required double percent, + required EdgeInsets padingEdg, + required EdgeInsets marginEdg, +}) { + var percentStr = '${doubleToStringAsFixed(percent * 100)}%'; + print(fontSize); + fontSize ??= 10.sp; + lineHeight ??= 8.h; + return Container( + margin: marginEdg, + padding: padingEdg, + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + if (title == '总正确率:') quickText('确率', color: Colors.transparent, size: fontSize), + quickText(title, color: Color.fromRGBO(139, 139, 139, 1), size: fontSize), + Expanded( + flex: 1, + child: Container( + child: Row( + children: [ + Expanded( + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10.r), + boxShadow: [ + BoxShadow( + color: color, + spreadRadius: 0.6, + blurRadius: 3, + offset: Offset(0, 0), + ), + ], + ), + child: LinearPercentIndicator( + padding: EdgeInsets.zero, + animation: true, + lineHeight: lineHeight, + animationDuration: 2500, + percent: percent, + center: Text( + percentStr, + style: TextStyle(color: Colors.white, fontSize: 8.sp), + ), + // linearStrokeCap: LinearStrokeCap.butt, + progressColor: color, + backgroundColor: Colors.white, + barRadius: Radius.circular(10.r), + // linearGradient: LinearGradient( + // tileMode: TileMode.mirror, + // stops: [0.0, 1.0], + // colors: [color.withOpacity(0.1), color], + // ), + ), + ), + ), + SizedBox(width: 4.w), + quickText(percentStr, size: fontSize, color: color) + ], + ), + ), + ), + ], + ), + ); +} + +/// 一键批阅 +typedef OneClickReview = void Function(int); + +/// 前往批阅 +typedef GoToReview = void Function(MarkingTasks); + +/// 结束批阅 +typedef EndReview = void Function(MarkingTasks); + +/// 数据快查 +typedef QuickDataCheck = void Function(MarkingTasks); + +/// 收藏夹 +typedef Bookmarks = void Function(MarkingTasks); + +/// 查看作业报告 +typedef JobViewReport = void Function(MarkingTasks); diff --git a/marking_app/lib/utils/index.dart b/marking_app/lib/utils/index.dart index 6b9db0c..7a2354e 100644 --- a/marking_app/lib/utils/index.dart +++ b/marking_app/lib/utils/index.dart @@ -21,6 +21,7 @@ import 'dart:math'; import 'package:fluro/fluro.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:marking_app/common/config/request_config.dart'; export "./colorUtils.dart"; @@ -105,6 +106,11 @@ void toPrint({required dynamic val, bool toPrintJson = false}) { if (printSwitch && val != null) toPrintJson ? printJson(val) : print(val); } +// 是否是平板 +bool isPad([double mobilePhoneScale = 1.2]) { + return ScreenUtil().scaleWidth > mobilePhoneScale; +} + class EUMNoScrollBehavior extends ScrollBehavior { @override Widget buildViewportChrome(BuildContext context, Widget child, AxisDirection axisDirection) { -- 2.40.1 From 2ca30595d97c2ad2727472269a966f8549c6c600 Mon Sep 17 00:00:00 2001 From: machuanyu <840649825@qq.com> Date: Fri, 8 Mar 2024 10:50:06 +0800 Subject: [PATCH 04/22] =?UTF-8?q?=E6=BB=9A=E5=8A=A8=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../homework_correction/quick_data_check.dart | 447 +++++++++--------- 1 file changed, 226 insertions(+), 221 deletions(-) diff --git a/marking_app/lib/pages/homework_correction/quick_data_check.dart b/marking_app/lib/pages/homework_correction/quick_data_check.dart index 0810109..17fef7b 100644 --- a/marking_app/lib/pages/homework_correction/quick_data_check.dart +++ b/marking_app/lib/pages/homework_correction/quick_data_check.dart @@ -73,250 +73,255 @@ class _QuickDataCheckState extends State with CommonMixin { 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), - ) - ], + child: Column( + children: [ + Row( + children: [ + IconButton( + icon: Icon(Icons.arrow_back_ios, color: Colors.white), + onPressed: () => Navigator.of(context).pop(), ), - ), - 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, + Expanded( + child: Center( + child: Text( + '数据快查', + style: TextStyle(fontSize: 16.sp, color: Colors.white), + ))), + ], + ), + SizedBox(height:10.r), + Expanded(child: SingleChildScrollView( + child: Column( + children: [ + Padding( + padding: EdgeInsets.only(left: 14.r, top: 2.r), + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, children: [ - Container( - width: 14.r, - height: 14.r, - decoration: BoxDecoration( - color: Color(0xFF4CC793), - borderRadius: - BorderRadius.all(Radius.circular(7.r))), + Image.asset( + 'assets/images/job_report_class_icon.png', + width: 22.r, + height: 22.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)), + widget.className, + style: TextStyle(fontSize: 14.r, color: Colors.white), ) ], ), - //环形图 - 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, - ), + ), + 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))), ), - 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, - ), + 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)), ), ], ), - ), - ), - // 客观进度条 - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - '客观题答题进度', - style: TextStyle( - fontSize: 10.sp, color: Color(0xFF8B8B8B)), + 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), + )), + ], ), - Text('${doubleToStringAsFixed(jobData!.kgValidRate)}%', - style: TextStyle( - fontSize: 10.sp, color: Color(0xFF333333)), + 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), + )), + ], ), ], ), - SizedBox(height: 6.r), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, + ), + 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: [ - 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)), + 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?350.r:jobData!.studentDetails.length * 50.r + 40.r, + child: QuickStudentDataTable( + headList: ['学生姓名','客观题','主观题','客观题错题','主观题错题'], + bodyList: jobData!.studentDetails, + jobId: widget.jobId, + fixedRows: 1, + fixedCols: 0, + ), + ) ], ), - 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, - ), - ) - ], - ), - ), - ], - ), + )) + ], ), ), ); -- 2.40.1 From 35eaa570d1230f0ce76d8f71c66be9ef3affe646 Mon Sep 17 00:00:00 2001 From: "1147192855@qq.com" <1147192855@qq.com> Date: Fri, 8 Mar 2024 10:55:12 +0800 Subject: [PATCH 05/22] no message --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index e6fa9ab..60eaaac 100644 --- a/.gitignore +++ b/.gitignore @@ -200,3 +200,4 @@ marking_app/lib/common/model/job/job_report_knowledge_model.g.dart marking_app/lib/common/model/job/job_report_question_deatil_model.g.dart marking_app/lib/common/model/job/job_do_marking_status_info.g.dart marking_app/lib/common/model/report/small_question.g.dart +marking_app/lib/pages/homework_correction/pages/job_list_participate_in_class.g.dart -- 2.40.1 From 1de02f27e24c70a7b637feca1a9fedfbade79b35 Mon Sep 17 00:00:00 2001 From: machuanyu <840649825@qq.com> Date: Fri, 8 Mar 2024 11:04:46 +0800 Subject: [PATCH 06/22] =?UTF-8?q?=E5=90=88=E5=B9=B6=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../homework_correction/quick_data_check.dart | 8 ++++---- marking_app/lib/routes/RouterManager.dart | 2 +- marking_app/lib/utils/request/rest_client.dart | 15 ++++++++------- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/marking_app/lib/pages/homework_correction/quick_data_check.dart b/marking_app/lib/pages/homework_correction/quick_data_check.dart index 17fef7b..d36e023 100644 --- a/marking_app/lib/pages/homework_correction/quick_data_check.dart +++ b/marking_app/lib/pages/homework_correction/quick_data_check.dart @@ -13,17 +13,17 @@ 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 { +class QuickDataCheckPage extends StatefulWidget { final int jobId; final String className; - const QuickDataCheck({Key? key, required this.jobId,required this.className}) : super(key: key); + const QuickDataCheckPage({Key? key, required this.jobId,required this.className}) : super(key: key); @override - State createState() => _QuickDataCheckState(); + State createState() => _QuickDataCheckPageState(); } -class _QuickDataCheckState extends State with CommonMixin { +class _QuickDataCheckPageState extends State with CommonMixin { JobDataReport? jobData; void initState() { diff --git a/marking_app/lib/routes/RouterManager.dart b/marking_app/lib/routes/RouterManager.dart index 8ff877f..a75d82d 100644 --- a/marking_app/lib/routes/RouterManager.dart +++ b/marking_app/lib/routes/RouterManager.dart @@ -261,7 +261,7 @@ class RouterManager { handlerFunc: (BuildContext? context, Map> params){ int jobId = int.parse(params['jobId']![0]); String className = params['className']![0]; - return QuickDataCheck(jobId: jobId,className:className); + return QuickDataCheckPage(jobId: jobId,className:className); }, ); diff --git a/marking_app/lib/utils/request/rest_client.dart b/marking_app/lib/utils/request/rest_client.dart index 6fb3364..6aca9ec 100644 --- a/marking_app/lib/utils/request/rest_client.dart +++ b/marking_app/lib/utils/request/rest_client.dart @@ -291,12 +291,13 @@ abstract class RestClient { @the_retrofit.GET("${RequestConfig.hwProxyKeywords}/api/Task/tasks") Future>> getJobListParticipateInClass( @the_retrofit.Query("markingId") int jobId); -} -// 作业 => 数据快查 -@the_retrofit.GET("/api/read/job-data-center-report") -Future> getJobDataCenterReport(@the_retrofit.Queries() Map params); + + // 作业 => 数据快查 + @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); -} \ No newline at end of file + @the_retrofit.GET("/api/read/job-data-center-student-report") + Future> getJobPersonalReport(@the_retrofit.Queries() Map params); +} + -- 2.40.1 From 02a7b748e11eba3071ff4fe0b5348c66c1af3ce4 Mon Sep 17 00:00:00 2001 From: "1147192855@qq.com" <1147192855@qq.com> Date: Sat, 9 Mar 2024 21:56:32 +0800 Subject: [PATCH 07/22] =?UTF-8?q?=E5=A4=84=E7=90=86=E5=88=97=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/model/job/job_data_report.g.dart | 91 ++++ .../lib/common/model/job/job_task_item.dart | 3 + .../model/marking/marking_list_params.dart | 12 +- marking_app/lib/main.dart | 23 + marking_app/lib/pages/home/index.dart | 23 - .../homework_tasks_view_item.dart | 296 +++++------ .../lib/pages/homework_correction/index.dart | 464 ++++++++++++---- .../pages/job_list_participate_in_class.dart | 500 +++++++++++++++++- marking_app/lib/pages/marking/index.dart | 3 - marking_app/lib/routes/RouterManager.dart | 16 +- marking_app/pubspec.yaml | 16 +- 11 files changed, 1146 insertions(+), 301 deletions(-) create mode 100644 marking_app/lib/common/model/job/job_data_report.g.dart diff --git a/marking_app/lib/common/model/job/job_data_report.g.dart b/marking_app/lib/common/model/job/job_data_report.g.dart new file mode 100644 index 0000000..dcd6608 --- /dev/null +++ b/marking_app/lib/common/model/job/job_data_report.g.dart @@ -0,0 +1,91 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'job_data_report.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +JobDataReport _$JobDataReportFromJson(Map json) => + JobDataReport( + json['jobId'] as int, + json['jobName'] as String, + json['gradeName'] as String, + json['className'] as String?, + json['validCount'] as int, + json['noAnswerCount'] as int, + (json['kgValidRate'] as num).toDouble(), + json['kgQuestionCount'] as int, + (json['zgValidRate'] as num).toDouble(), + json['zgQuestionCount'] as int, + (json['studentDetails'] as List) + .map((e) => StudentDetails.fromJson(e as Map)) + .toList(), + ); + +Map _$JobDataReportToJson(JobDataReport instance) => + { + 'jobId': instance.jobId, + 'jobName': instance.jobName, + 'gradeName': instance.gradeName, + 'className': instance.className, + 'validCount': instance.validCount, + 'noAnswerCount': instance.noAnswerCount, + 'kgValidRate': instance.kgValidRate, + 'kgQuestionCount': instance.kgQuestionCount, + 'zgValidRate': instance.zgValidRate, + 'zgQuestionCount': instance.zgQuestionCount, + 'studentDetails': instance.studentDetails, + }; + +StudentDetails _$StudentDetailsFromJson(Map json) => + StudentDetails( + json['studentId'] as int, + json['studentName'] as String, + json['kgValidCount'] as int, + json['kgValidRate'] as int, + json['zgValidCount'] as int, + json['zgValidRate'] as int, + (json['kgDetails'] as List) + .map((e) => KgDetails.fromJson(e as Map)) + .toList(), + (json['zgDetails'] as List) + .map((e) => KgDetails.fromJson(e as Map)) + .toList(), + ); + +Map _$StudentDetailsToJson(StudentDetails instance) => + { + 'studentId': instance.studentId, + 'studentName': instance.studentName, + 'kgValidCount': instance.kgValidCount, + 'kgValidRate': instance.kgValidRate, + 'zgValidCount': instance.zgValidCount, + 'zgValidRate': instance.zgValidRate, + 'kgDetails': instance.kgDetails, + 'zgDetails': instance.zgDetails, + }; + +KgDetails _$KgDetailsFromJson(Map json) => KgDetails( + json['questionNo'] as String, + json['questionId'] as int, + json['partName'] as String, + json['state'] as int, + json['studentAnswer'] as String?, + json['questionAnswer'] as String?, + json['useTime'] as int?, + json['annotateAnswers'] as String?, + (json['score'] as num?)?.toDouble(), + ); + +Map _$KgDetailsToJson(KgDetails instance) => { + 'questionNo': instance.questionNo, + 'questionId': instance.questionId, + 'partName': instance.partName, + 'state': instance.state, + 'studentAnswer': instance.studentAnswer, + 'questionAnswer': instance.questionAnswer, + 'useTime': instance.useTime, + 'annotateAnswers': instance.annotateAnswers, + 'score': instance.score, + }; diff --git a/marking_app/lib/common/model/job/job_task_item.dart b/marking_app/lib/common/model/job/job_task_item.dart index 70ba21c..1cd83ff 100644 --- a/marking_app/lib/common/model/job/job_task_item.dart +++ b/marking_app/lib/common/model/job/job_task_item.dart @@ -56,6 +56,8 @@ class JobTaskItem extends Object { @JsonKey(name: 'markingTypeEnum') JobMarkingTypeEnum markingTypeEnum; // 考试类型 + int taskCount; // 参与班级数量 + JobTaskItem( this.id, this.title, @@ -72,6 +74,7 @@ class JobTaskItem extends Object { // this.markingTasks, this.createTime, this.markingType, + this.taskCount, {this.progressPercentage = 0, this.markingTypeEnum = JobMarkingTypeEnum.UNUSED}) { try { diff --git a/marking_app/lib/common/model/marking/marking_list_params.dart b/marking_app/lib/common/model/marking/marking_list_params.dart index da455b5..2906d6e 100644 --- a/marking_app/lib/common/model/marking/marking_list_params.dart +++ b/marking_app/lib/common/model/marking/marking_list_params.dart @@ -21,12 +21,22 @@ class MarkingListParams extends BasePage { @JsonKey(name: 'PageType') int pageType; + String? startTime; + String? endTime; + + int? markingType; // 1 作业 2考试 + MarkingListParams({ required this.isFinish, required this.pageType, required page, required limit, - }) : super(page, limit); + this.markingType, + this.startTime, + this.endTime, + }) : super(page, limit) { + this.markingType ??= 1; + } factory MarkingListParams.fromJson(Map srcJson) => _$MarkingListParamsFromJson(srcJson); diff --git a/marking_app/lib/main.dart b/marking_app/lib/main.dart index 6b57722..96d52e9 100644 --- a/marking_app/lib/main.dart +++ b/marking_app/lib/main.dart @@ -10,6 +10,7 @@ import 'dart:async'; import 'package:connectivity_plus/connectivity_plus.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter/services.dart'; @@ -83,6 +84,28 @@ class _MyAppState extends State { title: '远轩阅卷系统', navigatorKey: TheGlobal.navigatorKey, debugShowCheckedModeBanner: false, + // locale: const Locale('zh', 'CN'), // 中文简体 , + // supportedLocales: [ + // const Locale('zh', 'CN'), // 中文简体 + // // 其他支持的locale可以在这里添加 + // ], + // 这里是国际化支持,确保添加flutter_localizations依赖 + supportedLocales: [ + const Locale('zh', 'CN'), // 中文简体 + // 其他支持的locale可以在这里添加 + ], + localizationsDelegates: [ + // ...其他delegates + GlobalMaterialLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + GlobalCupertinoLocalizations.delegate, // 如果你使用了Cupertino风格的组件 + // ...添加其他必要的delegates + ], + localeResolutionCallback: (locale, supportedLocales) { + // 在这里可以实现自定义的locale解析逻辑 + // 如果需要,返回你想要的Locale对象 + return locale; + }, theme: ThemeData( primarySwatch: createMaterialColor(const Color.fromRGBO(46, 91, 255, 1)), // textTheme: Typography.englishLike2018.apply(fontSizeFactor: 1.sp,), diff --git a/marking_app/lib/pages/home/index.dart b/marking_app/lib/pages/home/index.dart index 20a94c6..978c9a3 100644 --- a/marking_app/lib/pages/home/index.dart +++ b/marking_app/lib/pages/home/index.dart @@ -357,29 +357,6 @@ Widget $theTabBar({required TabController controller, ValueChanged? onTap}) isScrollable: true, labelColor: const Color.fromRGBO(45, 56, 76, 1), indicatorSize: TabBarIndicatorSize.label, // 设置指示器高度和标签一样高 - // labelPadding: EdgeInsets.symmetric(vertical: 0), // 设置标签的内边距 - // background: linear-gradient(270deg, #2E5BFF 30.23%, rgba(46, 91, 255, 0.00) 96.59%); - // indicatorColor: RectangleIndicator(), - // indicator: BoxDecoration( - // gradient: LinearGradient( - // begin: Alignment.centerLeft, - // end: Alignment.centerRight, - // colors: [ - // Color.fromRGBO(46, 91, 255, 0.00), - // Color(0xFF2E5BFF), - // ], - // stops: [0.3023, 0.9659], - // // transform: GradientRotation(3.14 / 2), //将270度转换为弧度 - // ), - // ), - // indicator: BoxDecoration( - // // 设置指示器样式 - // gradient: LinearGradient( - // colors: [Colors.yellow, Colors.green], // 设置渐变色 - // begin: Alignment.centerLeft, - // end: Alignment.centerRight, - // ), - // ), onTap: onTap, tabs: const [Tab(text: '阅卷'), Tab(text: '作业')], ), diff --git a/marking_app/lib/pages/homework_correction/components/new_version_of_homework/homework_tasks_view_item.dart b/marking_app/lib/pages/homework_correction/components/new_version_of_homework/homework_tasks_view_item.dart index d757d83..872261a 100644 --- a/marking_app/lib/pages/homework_correction/components/new_version_of_homework/homework_tasks_view_item.dart +++ b/marking_app/lib/pages/homework_correction/components/new_version_of_homework/homework_tasks_view_item.dart @@ -145,154 +145,161 @@ class HomeworkTasksViewItem extends StatelessWidget with CommonMixin { @hwidget Widget $completedHomeworkView(BuildContext context, {required JobTaskItem jobTaskItem, required ShowStudentsCall showStudentsCall}) { - return Container( - width: double.infinity, - padding: EdgeInsets.only(top: 20.h), - margin: EdgeInsets.only(bottom: 12.h), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(6.r), - color: const Color.fromRGBO(255, 255, 255, 1), - boxShadow: [ - BoxShadow( - color: const Color.fromRGBO(210, 216, 241, 1), - offset: Offset.zero, //阴影y轴偏移量 - blurRadius: 5.8, //阴影模糊程度 - spreadRadius: 0, //阴影扩散程度 - ) - ], - ), - child: Column( - children: [ - // 顶部任务名称 - Padding( - padding: EdgeInsets.symmetric(horizontal: 10.w), - child: Row( - children: [ - Container( - width: 32.w, - height: 18.h, - alignment: Alignment.center, - padding: EdgeInsets.only(left: 2.w), - decoration: BoxDecoration( - color: Color.fromRGBO(104, 136, 253, 1), - borderRadius: BorderRadius.only( - topLeft: Radius.circular(18.r), - topRight: Radius.circular(3.r), - bottomLeft: Radius.circular(4.r), - bottomRight: Radius.circular(4.r), + return InkWell( + onTap: () { + String url = + '${RouterManager.jobListParticipateInClassPath}?&jobId=${jobTaskItem.id}&genderName=${Uri.encodeComponent(jobTaskItem.genderName)}&jobName=${Uri.encodeComponent(jobTaskItem.title)}&completed=${true}'; + RouterManager.router.navigateTo(context, url, transition: getTransition()); + }, + child: Container( + width: double.infinity, + padding: EdgeInsets.only(top: 20.h), + margin: EdgeInsets.only(bottom: 12.h), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(6.r), + color: const Color.fromRGBO(255, 255, 255, 1), + boxShadow: [ + BoxShadow( + color: const Color.fromRGBO(210, 216, 241, 1), + offset: Offset.zero, //阴影y轴偏移量 + blurRadius: 5.8, //阴影模糊程度 + spreadRadius: 0, //阴影扩散程度 + ) + ], + ), + child: Column( + children: [ + // 顶部任务名称 + Padding( + padding: EdgeInsets.symmetric(horizontal: 10.w), + child: Row( + children: [ + Container( + width: 32.w, + height: 18.h, + alignment: Alignment.center, + padding: EdgeInsets.only(left: 2.w), + decoration: BoxDecoration( + color: Color.fromRGBO(104, 136, 253, 1), + borderRadius: BorderRadius.only( + topLeft: Radius.circular(18.r), + topRight: Radius.circular(3.r), + bottomLeft: Radius.circular(4.r), + bottomRight: Radius.circular(4.r), + ), ), + margin: EdgeInsets.only(right: 4.w), + child: quickText('作业', color: Colors.white, size: 10.sp), ), - margin: EdgeInsets.only(right: 4.w), - child: quickText('作业', color: Colors.white, size: 10.sp), - ), - quickText( - jobTaskItem.title, - size: 16.sp, - color: Color.fromRGBO(70, 70, 70, 1), - fontWeight: FontWeight.bold, - ) - ], + quickText( + jobTaskItem.title, + size: 16.sp, + color: Color.fromRGBO(70, 70, 70, 1), + fontWeight: FontWeight.bold, + ) + ], + ), ), - ), - SizedBox(height: 12.h), - Padding( - padding: EdgeInsets.symmetric(horizontal: 10.w), - child: Row( - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - quickText( - jobTaskItem.createTime.substring(0, 10), - color: Color.fromRGBO(97, 97, 97, 1), - size: 14.sp, - fontWeight: FontWeight.w500, - ), - quickText(' / ', color: Color.fromRGBO(76, 199, 147, 1), size: 12.sp, fontWeight: FontWeight.w500), - quickText( - '参与班级:字段待定', - color: Color.fromRGBO(76, 199, 147, 1), - size: 12.sp, - fontWeight: FontWeight.w600, - ), - quickText(' / ', color: Color.fromRGBO(116, 145, 253, 1), size: 12.sp, fontWeight: FontWeight.w500), - quickText( - '科目:' + jobTaskItem.subjectName, - color: Color.fromRGBO(116, 145, 253, 1), - size: 12.sp, - fontWeight: FontWeight.w600, - ), - ], + SizedBox(height: 12.h), + Padding( + padding: EdgeInsets.symmetric(horizontal: 10.w), + child: Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + quickText( + jobTaskItem.createTime.substring(0, 10), + color: Color.fromRGBO(97, 97, 97, 1), + size: 14.sp, + fontWeight: FontWeight.w500, + ), + quickText(' / ', color: Color.fromRGBO(76, 199, 147, 1), size: 12.sp, fontWeight: FontWeight.w500), + quickText( + '参与班级:${jobTaskItem.taskCount}', + color: Color.fromRGBO(76, 199, 147, 1), + size: 12.sp, + fontWeight: FontWeight.w600, + ), + quickText(' / ', color: Color.fromRGBO(116, 145, 253, 1), size: 12.sp, fontWeight: FontWeight.w500), + quickText( + '科目:' + jobTaskItem.subjectName, + color: Color.fromRGBO(116, 145, 253, 1), + size: 12.sp, + fontWeight: FontWeight.w600, + ), + ], + ), ), - ), - SizedBox(height: 20.h), - Container( - padding: EdgeInsets.symmetric(vertical: 8.h), - decoration: BoxDecoration( - borderRadius: BorderRadius.only(bottomLeft: Radius.circular(6.r), bottomRight: Radius.circular(6.r)), - color: Colors.white, - boxShadow: [ - BoxShadow( - color: const Color.fromRGBO(0, 0, 0, 0.15), - offset: Offset(0, -0.0001), //阴影y轴偏移量 - blurRadius: 4, //阴影模糊程度 - spreadRadius: 0, //阴影扩散程度 - ) - ], + SizedBox(height: 20.h), + Container( + padding: EdgeInsets.symmetric(vertical: 8.h), + decoration: BoxDecoration( + borderRadius: BorderRadius.only(bottomLeft: Radius.circular(6.r), bottomRight: Radius.circular(6.r)), + color: Colors.white, + boxShadow: [ + BoxShadow( + color: const Color.fromRGBO(0, 0, 0, 0.15), + offset: Offset(0, -0.0001), //阴影y轴偏移量 + blurRadius: 4, //阴影模糊程度 + spreadRadius: 0, //阴影扩散程度 + ) + ], + ), + child: Row(children: [ + Expanded( + child: InkWell( + onTap: () => easyThrottle('go_to_homework_report', () => {}), + child: Container( + alignment: Alignment.center, + child: quickText('查看报告', color: Color.fromRGBO(118, 118, 118, 1), size: 12.sp), + ), + )), + ]), ), - child: Row(children: [ - Expanded( - child: InkWell( - onTap: () => easyThrottle('go_to_homework_report', () => {}), - child: Container( - alignment: Alignment.center, - child: quickText('查看报告', color: Color.fromRGBO(118, 118, 118, 1), size: 12.sp), - ), - )), - ]), - ), - // $CompletedHomeworkInfoBox( - // segmentation: false, - // showStudentsCall: showStudentsCall, - // unsubmittedQuantity: jobTaskItem.studentCount - jobTaskItem.commitStudentCount, - // submittedQuantity: jobTaskItem.commitStudentCount, - // precision: jobTaskItem.precision / 100, - // objectivePrecision: jobTaskItem.objectivePrecision / 100, - // subjectivePrecision: jobTaskItem.subjectivePrecision / 100, - // ), - // InkWell( - // onTap: () { - // RouterManager.router.navigateTo( - // context, - // RouterManager.jobReportPagePath + '?title=${Uri.encodeComponent(jobTaskItem.title)}&id=${jobTaskItem.id}', - // transition: getTransition(), - // ); - // }, - // child: Row( - // children: [ - // Expanded(flex: 1, child: SizedBox()), - // Expanded( - // flex: 9, - // child: Container( - // alignment: Alignment.center, - // margin: EdgeInsets.only(top: 20.h), - // padding: EdgeInsets.symmetric(vertical: 7.h), - // decoration: BoxDecoration( - // borderRadius: BorderRadius.circular(20), - // gradient: LinearGradient( - // begin: Alignment.centerLeft, - // end: Alignment.centerRight, - // colors: [Color.fromRGBO(95, 197, 255, 1), Color.fromRGBO(61, 68, 255, 0.82)], - // ), - // ), - // child: quickText('查看报告', color: Colors.white, size: 12.sp), - // ), - // ), - // Expanded(flex: 1, child: SizedBox()), - // ], - // ), - // ) - ], + // $CompletedHomeworkInfoBox( + // segmentation: false, + // showStudentsCall: showStudentsCall, + // unsubmittedQuantity: jobTaskItem.studentCount - jobTaskItem.commitStudentCount, + // submittedQuantity: jobTaskItem.commitStudentCount, + // precision: jobTaskItem.precision / 100, + // objectivePrecision: jobTaskItem.objectivePrecision / 100, + // subjectivePrecision: jobTaskItem.subjectivePrecision / 100, + // ), + // InkWell( + // onTap: () { + // RouterManager.router.navigateTo( + // context, + // RouterManager.jobReportPagePath + '?title=${Uri.encodeComponent(jobTaskItem.title)}&id=${jobTaskItem.id}', + // transition: getTransition(), + // ); + // }, + // child: Row( + // children: [ + // Expanded(flex: 1, child: SizedBox()), + // Expanded( + // flex: 9, + // child: Container( + // alignment: Alignment.center, + // margin: EdgeInsets.only(top: 20.h), + // padding: EdgeInsets.symmetric(vertical: 7.h), + // decoration: BoxDecoration( + // borderRadius: BorderRadius.circular(20), + // gradient: LinearGradient( + // begin: Alignment.centerLeft, + // end: Alignment.centerRight, + // colors: [Color.fromRGBO(95, 197, 255, 1), Color.fromRGBO(61, 68, 255, 0.82)], + // ), + // ), + // child: quickText('查看报告', color: Colors.white, size: 12.sp), + // ), + // ), + // Expanded(flex: 1, child: SizedBox()), + // ], + // ), + // ) + ], + ), ), ); } @@ -654,13 +661,6 @@ Widget $unfinishedHomework(BuildContext context, {required JobTaskItem jobTaskIt ), backgroundColor: Color.fromRGBO(244, 244, 244, 1), ), - // Container( - // child: Container( - // color: Colors.red, - // height: 40.r, - // width: 40.r, - // ) - // ), ), ], ); diff --git a/marking_app/lib/pages/homework_correction/index.dart b/marking_app/lib/pages/homework_correction/index.dart index 2c45474..0706791 100644 --- a/marking_app/lib/pages/homework_correction/index.dart +++ b/marking_app/lib/pages/homework_correction/index.dart @@ -9,6 +9,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:functional_widget_annotation/functional_widget_annotation.dart'; import 'package:marking_app/common/mixin/common.dart'; import 'package:flutter_easyrefresh/easy_refresh.dart'; @@ -18,6 +19,7 @@ import 'package:marking_app/common/config/request_config.dart'; import 'package:marking_app/common/model/job/job_task_item.dart'; import 'package:marking_app/pages/homework_correction/components/new_version_of_homework/homework_tasks_view_item.dart'; import 'package:marking_app/provider/review_provider.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'; @@ -25,6 +27,7 @@ import 'package:marking_app/common/model/common/base_page_data.dart'; import 'package:marking_app/common/model/marking/marking_list_params.dart'; import 'package:marking_app/utils/easy_refresh/MyEmptyWidget.dart'; import 'package:marking_app/utils/easy_refresh/mixin/refresh_data_handle.dart'; +import 'package:syncfusion_flutter_datepicker/datepicker.dart'; part 'index.g.dart'; @@ -39,7 +42,7 @@ class HomeworkCorrection extends StatefulHookConsumerWidget { class _HomeworkCorrectionState extends ConsumerState with CommonMixin, - SingleTickerProviderStateMixin, + TickerProviderStateMixin, RefreshDataHandle, AutomaticKeepAliveClientMixin { @override @@ -47,6 +50,8 @@ class _HomeworkCorrectionState extends ConsumerState /* Tab控制器 */ late TabController _tabController; + late TabController _tabController2; + int _tabIndex = 0; bool completedToRefresh = true; @@ -95,6 +100,7 @@ class _HomeworkCorrectionState extends ConsumerState length: 2, vsync: this, ); + _tabController2 = TabController(length: 4, vsync: this); _refreshController1 = EasyRefreshController(); _refreshController2 = EasyRefreshController(); @@ -117,6 +123,7 @@ class _HomeworkCorrectionState extends ConsumerState if (_currentTaskIdListener != null) { _currentTaskIdListener!(); } + _tabController2.dispose(); _tabController.dispose(); _refreshController1.dispose(); _refreshController2.dispose(); @@ -169,10 +176,7 @@ class _HomeworkCorrectionState extends ConsumerState child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ - Expanded( - flex: 1, - child: SizedBox(), - ), + Expanded(flex: 1, child: SizedBox()), Expanded( flex: 4, child: Container( @@ -263,6 +267,29 @@ class _HomeworkCorrectionState extends ConsumerState ], ), ), + if (_tabIndex == 1) + $CompletedJobConditionFilter( + controller: _tabController2, + jobType: params2.markingType ?? 1, + customTime: _tabController2.index != 3 || (params2.startTime == null && params2.endTime == null) + ? null + : PickerDateRange( + params2.startTime == null ? null : DateTime.parse(params2.startTime!), + params2.endTime == null ? null : DateTime.parse(params2.endTime!), + ), + onJobTypeTap: (int jobTypeVal) { + params2.markingType = jobTypeVal; + _refreshController2.callRefresh(); + }, + onTimeFilter: (String? startTime, String? endTime) { + if (startTime == null && endTime == null && _tabController2.index == 3) { + _tabController2.animateTo(0); + } + params2.endTime = endTime; + params2.startTime = startTime; + _refreshController2.callRefresh(); + }, + ), Expanded( child: IndexedStack( index: _tabIndex, @@ -350,111 +377,336 @@ Widget $easyRefresh({ @swidget Widget $reviewedItem(BuildContext context, {required JobTaskItem jobTaskItem}) { EdgeInsets padEdg = EdgeInsets.symmetric(horizontal: 10.w); - return Container( - padding: EdgeInsets.only(top: 10.h), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(6.r), - color: Colors.white, - boxShadow: [ - BoxShadow( - color: const Color.fromRGBO(210, 216, 241, 1), - offset: Offset.zero, //阴影y轴偏移量 - blurRadius: 5.8, //阴影模糊程度 - spreadRadius: 0, //阴影扩散程度 - ) - ], - ), - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - // 顶部任务名称 - Padding( - padding: padEdg, - child: Row( - children: [ - Container( - width: 32.w, - height: 18.h, - alignment: Alignment.center, - padding: EdgeInsets.only(left: 2.w), - decoration: BoxDecoration( - color: jobTaskItem.markingTypeEnum.name == '作业' - ? const Color.fromRGBO(104, 136, 253, 1) - : const Color.fromRGBO(255, 175, 56, 1), - borderRadius: BorderRadius.only( - topLeft: Radius.circular(18.r), - topRight: Radius.circular(3.r), - bottomLeft: Radius.circular(4.r), - bottomRight: Radius.circular(4.r), + return InkWell( + onTap: () { + String url = + '${RouterManager.jobListParticipateInClassPath}?&jobId=${jobTaskItem.id}&genderName=${Uri.encodeComponent(jobTaskItem.genderName)}&jobName=${Uri.encodeComponent(jobTaskItem.title)}&completed=${true}'; + RouterManager.router.navigateTo(context, url, transition: getTransition()); + }, + child: Container( + padding: EdgeInsets.only(top: 10.h), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(6.r), + color: Colors.white, + boxShadow: [ + BoxShadow( + color: const Color.fromRGBO(210, 216, 241, 1), + offset: Offset.zero, //阴影y轴偏移量 + blurRadius: 5.8, //阴影模糊程度 + spreadRadius: 0, //阴影扩散程度 + ) + ], + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + // 顶部任务名称 + Padding( + padding: padEdg, + child: Row( + children: [ + Container( + width: 32.w, + height: 18.h, + alignment: Alignment.center, + padding: EdgeInsets.only(left: 2.w), + decoration: BoxDecoration( + color: jobTaskItem.markingTypeEnum.name == '作业' + ? const Color.fromRGBO(104, 136, 253, 1) + : const Color.fromRGBO(255, 175, 56, 1), + borderRadius: BorderRadius.only( + topLeft: Radius.circular(18.r), + topRight: Radius.circular(3.r), + bottomLeft: Radius.circular(4.r), + bottomRight: Radius.circular(4.r), + ), + ), + margin: EdgeInsets.only(right: 4.w), + child: quickText(jobTaskItem.markingTypeEnum.name, color: Colors.white, size: 10.sp), + ), + quickText( + jobTaskItem.title, + size: 16.sp, + color: Color.fromRGBO(70, 70, 70, 1), + fontWeight: FontWeight.bold, + ) + ], + ), + ), + + Padding( + padding: padEdg, + child: Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + quickText( + jobTaskItem.createTime.substring(0, 10), + color: Color.fromRGBO(97, 97, 97, 1), + size: 10.sp, + fontWeight: FontWeight.w500, + ), + quickText(' / ', color: Color.fromRGBO(76, 199, 147, 1), size: 10.sp, fontWeight: FontWeight.w500), + quickText( + '参与班级:${jobTaskItem.taskCount}', + color: Color.fromRGBO(76, 199, 147, 1), + size: 10.sp, + fontWeight: FontWeight.w600, + ), + quickText(' / ', color: Color.fromRGBO(116, 145, 253, 1), size: 10.sp, fontWeight: FontWeight.w500), + quickText( + '科目:' + jobTaskItem.subjectName, + color: Color.fromRGBO(116, 145, 253, 1), + size: 10.sp, + fontWeight: FontWeight.w600, + ), + ], + ), + ), + GestureDetector( + onTap: () => easyThrottle('go_to_homework_report', () { + print('子级点击方法'); + }), + child: Container( + padding: EdgeInsets.symmetric(vertical: 6.h), + decoration: BoxDecoration( + borderRadius: BorderRadius.only(bottomLeft: Radius.circular(6.r), bottomRight: Radius.circular(6.r)), + color: Colors.white, + boxShadow: [ + BoxShadow( + color: const Color.fromRGBO(0, 0, 0, 0.15), + offset: Offset(0, -0.0001), //阴影y轴偏移量 + blurRadius: 4, //阴影模糊程度 + spreadRadius: 0, //阴影扩散程度 + ) + ], + ), + child: Row(children: [ + Expanded( + child: Container( + alignment: Alignment.center, + child: quickText('查看报告', color: Color.fromRGBO(118, 118, 118, 1), size: 11.sp), ), ), - margin: EdgeInsets.only(right: 4.w), - child: quickText(jobTaskItem.markingTypeEnum.name, color: Colors.white, size: 10.sp), - ), - quickText( - jobTaskItem.title, - size: 16.sp, - color: Color.fromRGBO(70, 70, 70, 1), - fontWeight: FontWeight.bold, - ) - ], + ]), + ), ), - ), + ], + ), + ), + ); +} - Padding( - padding: padEdg, - child: Row( - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - quickText( - jobTaskItem.createTime.substring(0, 10), - color: Color.fromRGBO(97, 97, 97, 1), - size: 10.sp, - fontWeight: FontWeight.w500, - ), - quickText(' / ', color: Color.fromRGBO(76, 199, 147, 1), size: 10.sp, fontWeight: FontWeight.w500), - quickText( - '参与班级:2', - color: Color.fromRGBO(76, 199, 147, 1), - size: 10.sp, - fontWeight: FontWeight.w600, - ), - quickText(' / ', color: Color.fromRGBO(116, 145, 253, 1), size: 10.sp, fontWeight: FontWeight.w500), - quickText( - '科目:' + jobTaskItem.subjectName, - color: Color.fromRGBO(116, 145, 253, 1), - size: 10.sp, - fontWeight: FontWeight.w600, - ), - ], - ), - ), - - Container( - padding: EdgeInsets.symmetric(vertical: 6.h), - decoration: BoxDecoration( - borderRadius: BorderRadius.only(bottomLeft: Radius.circular(6.r), bottomRight: Radius.circular(6.r)), - color: Colors.white, - boxShadow: [ - BoxShadow( - color: const Color.fromRGBO(0, 0, 0, 0.15), - offset: Offset(0, -0.0001), //阴影y轴偏移量 - blurRadius: 4, //阴影模糊程度 - spreadRadius: 0, //阴影扩散程度 - ) - ], - ), - child: Row(children: [ - Expanded( - child: InkWell( - onTap: () => easyThrottle('go_to_homework_report', () => {}), - child: Container( - alignment: Alignment.center, - child: quickText('查看报告', color: Color.fromRGBO(118, 118, 118, 1), size: 11.sp), - ), - )), - ]), - ), +// 筛选时间 +@swidget +Widget $theTabBar({required TabController controller, ValueChanged? onTap, PickerDateRange? customTime}) { + var customTimeStr = '自定义'; + if (customTime != null) { + customTimeStr = customTime.startDate?.toString().substring(0, 10) ?? ''; + if (customTime.endDate != null) { + print(customTime.startDate!.year == customTime.endDate!.year); + if (!isPad() && customTime.startDate!.year == customTime.endDate!.year) { + customTimeStr = + customTime.startDate.toString().substring(5, 10) + '~${customTime.endDate.toString().substring(5, 10)}'; + } else { + customTimeStr += '~${customTime.endDate?.toString().substring(0, 10)}'; + } + } + } + return Container( + alignment: Alignment.centerLeft, + 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: const Color.fromRGBO(45, 56, 76, 1), + indicatorSize: TabBarIndicatorSize.label, // 设置指示器高度和标签一样高 + onTap: onTap, + tabs: [ + const Tab(text: '全部'), + const Tab(text: '近一周'), + const Tab(text: '近一月'), + Tab(text: customTimeStr), + ], + ), + ); +} + +/// 已完成作业条件筛选栏 +@hwidget +Widget $completedJobConditionFilter(BuildContext context, + {required TabController controller, + required int jobType, + PickerDateRange? customTime, + required ValueChanged onJobTypeTap, + required Function(String? startTime, String? endTime) onTimeFilter}) { + List> jobTypes = [ + {'type': 1, 'name': '作业'}, + {'type': 2, 'name': '考试'} + ]; + var jobTypeState = useState(0); + var customTimeState = useState(null); + + useEffect(() { + if (jobTypeState.value != jobType) jobTypeState.value = jobType; + if (customTimeState.value != customTime) customTimeState.value = customTime; + + return () {}; + }, []); + + DateTime getWeekStartDate() { + DateTime now = DateTime.now(); + int dayOfWeek = now.weekday; // 获取今天是周几(1代表周一,7代表周日) + int diff = dayOfWeek - 1; // 计算今天距离周一的天数差 + if (diff < 0) { + diff += 7; // 如果是周日,则需要加上一周的天数 + } + return now.subtract(Duration(days: diff)); // 减去天数差,得到本周一的时间 + } + + DateTime getWeekEndDate() { + DateTime now = DateTime.now(); + int dayOfWeek = now.weekday; // 获取今天是周几 + int diff = 7 - dayOfWeek; // 计算今天距离周日的天数差 + if (diff == 0) { + diff = 7; // 如果是周日,则加上一周的天数 + } + return now.add(Duration(days: diff)); // 加上天数差减一,得到本周日的时间 + } + + 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( + height: 36.h, + padding: EdgeInsets.only(left: 4.w, right: 12.w), + decoration: BoxDecoration( + color: Color.fromRGBO(244, 244, 244, 1), + border: Border(bottom: BorderSide(color: Color.fromRGBO(204, 204, 204, 1), width: 1)), + ), + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + $TheTabBar( + controller: controller, + customTime: customTimeState.value, + onTap: (int val) async { + switch (val) { + case 0: // 全部 + onTimeFilter(null, null); + break; + case 1: // 近一周 + onTimeFilter( + getWeekStartDate().toString().substring(0, 10), + getWeekEndDate().toString().substring(0, 10), + ); + break; + case 2: // 近一个月 + onTimeFilter( + getMonthStartDate().toString().substring(0, 10), + getMonthEndDate().toString().substring(0, 10), + ); + break; + default: // 自定义 + // DateTimeRange? range = await showDateRangePicker( + // // locale: const Locale('zh', 'CN'), + // locale: const Locale('zh', 'CN'), + // context: context, + // confirmText: '搜索', + // initialEntryMode: DatePickerEntryMode.calendarOnly, + // currentDate: DateTime.now(), + // firstDate: DateTime.now().subtract(const Duration(days: 4)), + // lastDate: DateTime.now().add(const Duration(days: 3)), + // ); + + 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); + }, + onCancel: () { + Navigator.of(context1).pop(); + }, + selectionMode: DateRangePickerSelectionMode.range, + initialSelectedRange: customTimeState.value, + ), + ), + ); + }); + // 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.value = dialogData; + } + }, + ), + Expanded(child: SizedBox()), + Container( + width: 74.r, + margin: EdgeInsets.symmetric(vertical: 5.h), + padding: EdgeInsets.symmetric(horizontal: 10.r), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.vertical( + top: Radius.elliptical(6, 6), + bottom: Radius.elliptical(6, 6), + ), + ), + child: DropdownButton( + icon: Icon(Icons.expand_more_outlined), + padding: EdgeInsets.zero, + // value: params2.jobType ?? 1, + value: jobType, + style: TextStyle(color: Color.fromRGBO(89, 89, 89, 1), fontSize: 12.sp), + underline: Container(), + isExpanded: true, + items: jobTypes.map((e) { + return DropdownMenuItem( + value: e['type'], + child: quickText(e['name'], size: 12.sp, color: Colors.black), + ); + }).toList(), + onChanged: (dynamic value) { + if (value != null) { + jobTypeState.value = value; + onJobTypeTap(value as int); + } + // jobTypeState + }, + ), + ) ], ), ); diff --git a/marking_app/lib/pages/homework_correction/pages/job_list_participate_in_class.dart b/marking_app/lib/pages/homework_correction/pages/job_list_participate_in_class.dart index 429bb86..3842766 100644 --- a/marking_app/lib/pages/homework_correction/pages/job_list_participate_in_class.dart +++ b/marking_app/lib/pages/homework_correction/pages/job_list_participate_in_class.dart @@ -17,7 +17,9 @@ class JobListParticipateInClass extends StatefulWidget { final int jobId; final String jobName; final String genderName; - const JobListParticipateInClass({required this.jobId, required this.jobName, required this.genderName, super.key}); + final bool completed; + const JobListParticipateInClass( + {required this.jobId, required this.jobName, required this.genderName, this.completed = false, super.key}); @override State createState() => _JobListParticipateInClassState(); @@ -254,6 +256,9 @@ class _JobListParticipateInClassState extends State w // 查看作业报告 void jobViewReport(MarkingTasks task) {} + + /// 查看学生名单 + void showStudentList([bool submitted = false]) {} @override Widget build(BuildContext context) { return Scaffold( @@ -271,8 +276,31 @@ class _JobListParticipateInClassState extends State w ), body: MyFutureBuilder.buildFutureBuilderOfSingleInstance?>(context, _future, (value) { if (value == null) return Container(); + bool thePadTerminal = isPad(); + if (widget.completed) { + // 已完成 + if (thePadTerminal) + return TabletEndCompleted( + data: value, + genderName: widget.genderName, + bookmarks: bookmarks, + jobViewReport: jobViewReport, + quickDataCheck: quickDataCheck, + ); - if (isPad()) + // 已完成手机端 + return MobileEndCompleted( + data: value, + genderName: widget.genderName, + bookmarks: bookmarks, + jobViewReport: jobViewReport, + quickDataCheck: quickDataCheck, + showStudentList: showStudentList, + ); + } + + // 未完成页面 + if (thePadTerminal) return TabletEnd( data: value, genderName: widget.genderName, @@ -299,7 +327,7 @@ class _JobListParticipateInClassState extends State w } } -/// 平板电脑端 +/// 平板电脑端(未完成) class TabletEnd extends StatelessWidget { final String genderName; final List data; @@ -332,7 +360,7 @@ class TabletEnd extends StatelessWidget { child: Wrap( spacing: 8.0.w, // 子元素之间的间距 runSpacing: 10.h, // 主轴方向上不同行之间的间距 - children: [...data, ...data, ...data] + children: data .map((e) => $ItemDataViewOfPad( task: e, bookmarks: bookmarks, @@ -349,6 +377,462 @@ class TabletEnd extends StatelessWidget { } } +/// 平板展示(已完成) +class TabletEndCompleted extends StatelessWidget { + final String genderName; + final List data; + + final Bookmarks bookmarks; // 收藏夹 + final JobViewReport jobViewReport; + final QuickDataCheck quickDataCheck; // 数据快查 + const TabletEndCompleted({ + required this.genderName, + required this.data, + + /// 方法 + required this.bookmarks, + required this.jobViewReport, + required this.quickDataCheck, + super.key, + }); + + @override + Widget build(BuildContext context) { + var padingEdg = EdgeInsets.only(left: 10.w, right: 10.w); + return Container( + width: ScreenUtil().screenWidth, + padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 16.h), + child: GridView( + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, //横轴三个子widget + mainAxisSpacing: 10.h, + crossAxisSpacing: 6.w, + childAspectRatio: 1.48 //宽高比为1时,子widget + ), + children: data.map((taskItem) { + return Container( + decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(6.r)), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Container( + padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 6.h), + alignment: Alignment.centerLeft, + decoration: BoxDecoration( + border: Border(bottom: BorderSide(color: Color.fromRGBO(238, 238, 238, 1), width: 0.5.r)), + ), + child: quickText(taskItem.className, color: Color.fromRGBO(104, 136, 253, 1), size: 12.sp), + ), + Column( + mainAxisSize: MainAxisSize.min, + children: [ + $CompletedHomeworkProgressBar( + color: Color.fromRGBO(76, 199, 147, 1), + percent: taskItem.objectivePrecision, + title: '客观题正确率:', + padingEdg: padingEdg, + fontSize: 8.sp, + lineHeight: 5.h, + marginEdg: EdgeInsets.only(top: 5.h), + ), + $CompletedHomeworkProgressBar( + color: Color.fromRGBO(255, 190, 91, 1), + percent: taskItem.subjectivePrecision, + title: '主观题正确率:', + fontSize: 8.sp, + lineHeight: 5.h, + padingEdg: padingEdg, + marginEdg: EdgeInsets.only(top: 5.h), + ), + $CompletedHomeworkProgressBar( + color: Color.fromRGBO(166, 139, 242, 1), + percent: taskItem.precision, + title: '总正确率:', + fontSize: 8.sp, + lineHeight: 5.h, + padingEdg: padingEdg, + marginEdg: EdgeInsets.only(top: 5.h), + ), + ], + ), + SizedBox(height: 4.h), + Padding( + padding: padingEdg, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + flex: 3, + child: Material( + color: Color.fromRGBO(104, 136, 253, 1), + borderRadius: BorderRadius.circular(16.r), + child: InkWell( + onTap: () => easyThrottle('OneClickReview', () {}), + borderRadius: BorderRadius.circular(8.r), + child: Container( + alignment: Alignment.center, + padding: EdgeInsets.symmetric(vertical: 4.h), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(20.r), + ), + child: quickText('已提交(${taskItem.commitStudentCount})', size: 8.sp, color: Colors.white), + ), + ), + ), + ), + Expanded(flex: 1, child: SizedBox()), + Expanded( + flex: 3, + child: Material( + color: Color.fromRGBO(244, 244, 244, 1), + borderRadius: BorderRadius.circular(20.r), + child: InkWell( + onTap: () async {}, + borderRadius: BorderRadius.circular(8.r), + child: Container( + alignment: Alignment.center, + padding: EdgeInsets.symmetric(vertical: 4.h), + decoration: BoxDecoration(borderRadius: BorderRadius.circular(20.r)), + child: quickText('数据快查', size: 8.sp, color: Color.fromRGBO(102, 102, 102, 1)), + ), + ), + ), + ), + Expanded(flex: 1, child: SizedBox()), + Expanded( + flex: 3, + child: Material( + color: Color.fromRGBO(244, 244, 244, 1), + borderRadius: BorderRadius.circular(20.r), + child: InkWell( + onTap: () async {}, + borderRadius: BorderRadius.circular(8.r), + child: Container( + alignment: Alignment.center, + padding: EdgeInsets.symmetric(vertical: 4.h), + decoration: BoxDecoration(borderRadius: BorderRadius.circular(20.r)), + child: quickText('收藏夹(2)', size: 8.sp, color: Color.fromRGBO(102, 102, 102, 1)), + ), + ), + )), + ], + ), + ), + SizedBox(height: 4.h), + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.only( + bottomLeft: Radius.circular(10.r), + bottomRight: Radius.circular(10.r), + ), + color: Colors.white, + boxShadow: [ + BoxShadow( + color: const Color.fromRGBO(0, 0, 0, 0.15), + offset: Offset(0, -0.0001), //阴影y轴偏移量 + blurRadius: 5, //阴影模糊程度 + spreadRadius: 0, //阴影扩散程度 + ) + ], + ), + child: Row(children: [ + Expanded( + child: InkWell( + onTap: () => easyThrottle('go_to_review_homework', () => quickDataCheck(taskItem)), + child: Container( + alignment: Alignment.center, + child: quickText('数据快查', color: Color.fromRGBO(79, 79, 79, 1), size: 11.sp), + ), + ), + ), + Container(width: 1.w, height: 26.h, color: Color.fromRGBO(221, 221, 221, 1)), + Expanded( + child: InkWell( + onTap: () => easyThrottle('go_to_end_review_homework', () => jobViewReport(taskItem)), + child: Container( + alignment: Alignment.center, + child: quickText('查看报告', color: Color.fromRGBO(118, 118, 118, 1), size: 10.sp), + ), + )), + ]), + ), + ], + ), + ); + }).toList(), + ), + ); + } +} + +/// 手机端(已完成) +class MobileEndCompleted extends StatelessWidget { + final String genderName; + final List data; + + final Bookmarks bookmarks; // 收藏夹 + final JobViewReport jobViewReport; // 查看报告 + final QuickDataCheck quickDataCheck; // 数据快查 + final ShowStudentList showStudentList; + + const MobileEndCompleted({ + required this.genderName, + required this.data, + + /// 方法 + required this.bookmarks, + required this.showStudentList, + required this.jobViewReport, + required this.quickDataCheck, + super.key, + }); + + @override + Widget build(BuildContext context) { + var padingEdg = EdgeInsets.only(left: 10.w, right: 10.w); + return ListView( + padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 16.h), + children: data.map((task) { + return Container( + padding: EdgeInsets.only(top: 11.h), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadiusDirectional.circular(10.r), + boxShadow: [BoxShadow(color: Color.fromRGBO(0, 0, 0, 0.15), blurRadius: 10)], + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Padding( + padding: padingEdg, + child: Row( + children: [ + quickText(genderName + task.className, color: Color.fromRGBO(0, 0, 0, 1), size: 14.sp), + Expanded(child: SizedBox()), + quickText('已交:${task.commitStudentCount}', color: Color.fromRGBO(104, 136, 253, 1), size: 12.sp), + SizedBox(width: 16.w), + quickText('未交:${task.studentCount - task.commitStudentCount}', + color: Color.fromRGBO(255, 86, 86, 1), size: 12.sp), + ], + ), + ), + SizedBox(height: 13.h), + Padding( + padding: padingEdg, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: task.isFinish + ? [ + Expanded( + flex: 3, + child: Material( + color: Color.fromRGBO(244, 244, 244, 1), + borderRadius: BorderRadius.circular(20.r), + child: InkWell( + onTap: () async {}, + borderRadius: BorderRadius.circular(8.r), + child: Container( + alignment: Alignment.center, + padding: EdgeInsets.symmetric(vertical: 5.h), + decoration: BoxDecoration(borderRadius: BorderRadius.circular(20.r)), + child: quickText('收藏夹(2)', size: 10.sp, color: Color.fromRGBO(102, 102, 102, 1)), + ), + ), + )), + Expanded(flex: 1, child: SizedBox()), + Expanded(flex: 3, child: SizedBox()), + Expanded(flex: 1, child: SizedBox()), + Expanded(flex: 3, child: SizedBox()), + ] + : [ + Expanded( + flex: 3, + child: Material( + color: Color.fromRGBO(104, 136, 253, 1), + borderRadius: BorderRadius.circular(16.r), + child: InkWell( + onTap: () => easyThrottle('OneClickReview', () {}), + borderRadius: BorderRadius.circular(8.r), + child: Container( + alignment: Alignment.center, + padding: EdgeInsets.symmetric(vertical: 5.h), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(20.r), + ), + child: quickText('一键批阅', size: 10.sp, color: Colors.white), + ), + ), + ), + ), + Expanded(flex: 1, child: SizedBox()), + Expanded( + flex: 3, + child: Material( + color: Color.fromRGBO(244, 244, 244, 1), + borderRadius: BorderRadius.circular(20.r), + child: InkWell( + onTap: () async {}, + borderRadius: BorderRadius.circular(8.r), + child: Container( + alignment: Alignment.center, + padding: EdgeInsets.symmetric(vertical: 5.h), + decoration: BoxDecoration(borderRadius: BorderRadius.circular(20.r)), + child: quickText('数据快查', size: 10.sp, color: Color.fromRGBO(102, 102, 102, 1)), + ), + ), + ), + ), + Expanded(flex: 1, child: SizedBox()), + Expanded( + flex: 3, + child: Material( + color: Color.fromRGBO(244, 244, 244, 1), + borderRadius: BorderRadius.circular(20.r), + child: InkWell( + onTap: () async {}, + borderRadius: BorderRadius.circular(8.r), + child: Container( + alignment: Alignment.center, + padding: EdgeInsets.symmetric(vertical: 5.h), + decoration: BoxDecoration(borderRadius: BorderRadius.circular(20.r)), + child: quickText('收藏夹(2)', size: 10.sp, color: Color.fromRGBO(102, 102, 102, 1)), + ), + ), + )), + ], + ), + ), + SizedBox(height: 13.h), + Padding( + padding: padingEdg, + child: Row( + children: [ + Expanded( + child: LinearPercentIndicator( + padding: EdgeInsets.zero, + animation: true, + lineHeight: 8.h, + animationDuration: 2500, + + percent: task.progressPercentage / 100, + // center: Text( + // '${getDoubleRemoveZero(jobTaskClassItem.progressPercentage)}%', + // style: TextStyle(color: Colors.white, fontSize: 8.sp), + // ), + linearGradient: LinearGradient( + tileMode: TileMode.mirror, + stops: [0.0, 1.0], + colors: task.progressPercentage / 100 != 1 + ? [Theme.of(context).primaryColor.withOpacity(0.1), Theme.of(context).primaryColor] + : [ + Color.fromRGBO(144, 224, 190, 1).withOpacity(0.1), + Color.fromRGBO(144, 224, 190, 1), + ], + ), + // linearStrokeCap: LinearStrokeCap.butt, + // progressColor: Theme.of(context).primaryColor, + backgroundColor: Color.fromRGBO(232, 232, 232, 1), + barRadius: Radius.circular(10.r), + ), + ), + SizedBox(width: 7.w), + quickText('${getDoubleRemoveZero(task.progressPercentage)}%', + size: 10.sp, color: Color.fromRGBO(70, 70, 70, 1)) + ], + ), + ), + if (task.isFinish) + $CompletedHomeworkProgressBar( + color: Color.fromRGBO(76, 199, 147, 1), + percent: task.objectivePrecision, + title: '客观题正确率:', + padingEdg: padingEdg, + marginEdg: EdgeInsets.only(top: 8.h), + ), + if (task.isFinish) + $CompletedHomeworkProgressBar( + color: Color.fromRGBO(255, 190, 91, 1), + percent: task.subjectivePrecision, + title: '主观题正确率:', + padingEdg: padingEdg, + marginEdg: EdgeInsets.only(top: 8.h), + ), + if (task.isFinish) + $CompletedHomeworkProgressBar( + color: Color.fromRGBO(166, 139, 242, 1), + percent: task.precision, + title: '总正确率:', + padingEdg: padingEdg, + marginEdg: EdgeInsets.only(top: 8.h), + ), + SizedBox(height: 13.h), + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.only( + bottomLeft: Radius.circular(10.r), + bottomRight: Radius.circular(10.r), + ), + color: Colors.white, + boxShadow: [ + BoxShadow( + color: const Color.fromRGBO(0, 0, 0, 0.15), + offset: Offset(0, -0.0001), //阴影y轴偏移量 + blurRadius: 5, //阴影模糊程度 + spreadRadius: 0, //阴影扩散程度 + ) + ], + ), + child: Row( + children: task.isFinish + ? [ + Expanded( + child: InkWell( + onTap: () => easyThrottle('go_to_review_homework', () => quickDataCheck(task)), + child: Container( + alignment: Alignment.center, + child: quickText('数据快查', color: Color.fromRGBO(79, 79, 79, 1), size: 13.sp), + ), + ), + ), + Container(width: 1.w, height: 32.h, color: Color.fromRGBO(221, 221, 221, 1)), + Expanded( + child: InkWell( + onTap: () => easyThrottle('go_to_end_review_homework', () => jobViewReport(task)), + child: Container( + alignment: Alignment.center, + child: quickText('查看报告', color: Color.fromRGBO(118, 118, 118, 1), size: 12.sp), + ), + )), + ] + : [ + Expanded( + child: InkWell( + onTap: () => easyThrottle('go_to_review_homework', () {}), + child: Container( + alignment: Alignment.center, + child: quickText('批阅', color: Color.fromRGBO(79, 79, 79, 1), size: 13.sp), + ), + ), + ), + Container(width: 1.w, height: 32.h, color: Color.fromRGBO(221, 221, 221, 1)), + Expanded( + child: InkWell( + onTap: () => easyThrottle('go_to_end_review_homework', () => {}), + child: Container( + alignment: Alignment.center, + child: quickText('结束批阅', color: Color.fromRGBO(118, 118, 118, 1), size: 12.sp), + ), + )), + ], + ), + ), + ], + )); + }).toList(), + ); + } +} + /// 移动端 class MobileEnd extends StatelessWidget { final String genderName; @@ -991,3 +1475,11 @@ typedef Bookmarks = void Function(MarkingTasks); /// 查看作业报告 typedef JobViewReport = void Function(MarkingTasks); + +/// 展示学生名单 +typedef ShowStudentList = void Function([bool submitted]); + +/// 查看学生名单 +// void showStudentList([bool submitted = false]) { + +// } diff --git a/marking_app/lib/pages/marking/index.dart b/marking_app/lib/pages/marking/index.dart index 9800ff3..612e3f7 100644 --- a/marking_app/lib/pages/marking/index.dart +++ b/marking_app/lib/pages/marking/index.dart @@ -10,7 +10,6 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_easyrefresh/easy_refresh.dart'; -import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:marking_app/common/config/request_config.dart'; @@ -21,8 +20,6 @@ import 'package:marking_app/common/model/event_bus/marking_statistics_bus.dart'; import 'package:marking_app/common/model/marking/marking_statistics.dart'; import 'package:marking_app/pages/common/event_bus_mixin.dart'; import 'package:marking_app/provider/review_provider.dart'; -import 'package:marking_app/utils/anti_shake_throttling.dart'; -import 'package:marking_app/utils/index.dart'; import 'package:marking_app/utils/request/rest_client.dart'; import 'package:marking_app/common/model/common/base_page_data.dart'; import 'package:marking_app/common/model/marking/marking_item.dart'; diff --git a/marking_app/lib/routes/RouterManager.dart b/marking_app/lib/routes/RouterManager.dart index a75d82d..e98c78b 100644 --- a/marking_app/lib/routes/RouterManager.dart +++ b/marking_app/lib/routes/RouterManager.dart @@ -251,26 +251,27 @@ class RouterManager { int jobId = int.parse(params['jobId']![0]); String jobName = params['jobName']![0]; String genderName = params['genderName']![0]; - - return JobListParticipateInClass(jobId: jobId, jobName: jobName, genderName: genderName); + // ignore: sdk_version_since + bool completed = bool.parse(params['completed']?[0] ?? 'false'); + return JobListParticipateInClass(jobId: jobId, jobName: jobName, genderName: genderName, completed: completed); }, ); // 数据快查 static final _quickDataCheckPageHandler = Handler( - handlerFunc: (BuildContext? context, Map> params){ + handlerFunc: (BuildContext? context, Map> params) { int jobId = int.parse(params['jobId']![0]); String className = params['className']![0]; - return QuickDataCheckPage(jobId: jobId,className:className); + return QuickDataCheckPage(jobId: jobId, className: className); }, ); // 数据快查-个人信息 static final _quickCheckPersonalPageHandler = Handler( - handlerFunc: (BuildContext? context, Map> params){ + 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); + return QuickCheckPersonal(jobId: jobId, studentId: studentId); }, ); // 开始阅卷页面 @@ -310,7 +311,8 @@ class RouterManager { 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(quickCheckPersonalPath, + handler: _quickCheckPersonalPageHandler, transitionType: TransitionType.material); // getTransition() diff --git a/marking_app/pubspec.yaml b/marking_app/pubspec.yaml index 92c49cc..5cebb4e 100644 --- a/marking_app/pubspec.yaml +++ b/marking_app/pubspec.yaml @@ -3,7 +3,7 @@ description: A new Flutter project. # The following line prevents the package from being accidentally published to # pub.dev using `flutter pub publish`. This is preferred for private packages. -publish_to: "none" # Remove this line if you wish to publish to pub.dev +publish_to: 'none' # Remove this line if you wish to publish to pub.dev # The following defines the version and build number for your application. # A version number is three numbers separated by dots, like 1.2.43 @@ -18,7 +18,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev version: 1.0.87 environment: - sdk: ">=2.17.1 <3.0.0" + sdk: '>=2.17.1 <3.0.0' # Dependencies specify other packages that your package needs in order to woyrk. # To automatically upgrade your package dependencies to the latest versions @@ -29,7 +29,8 @@ environment: dependencies: flutter: sdk: flutter - + flutter_localizations: + sdk: flutter # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.2 @@ -39,7 +40,7 @@ dependencies: # easy_refresh: ^3.3.2+1 retrofit: ^3.3.1 logger: ^1.1.0 - + flutter_lints: ^2.0.0 fluttertoast: ^8.2.3 json_annotation: ^4.8.1 @@ -60,7 +61,6 @@ dependencies: permission_handler: ^11.0.1 flutter_widget_from_html_core: ^0.10.3 - # 事件总线 event_bus: ^2.0.0 image_picker: ^0.8.6 @@ -108,6 +108,7 @@ dependencies: badges: ^3.1.2 horizontal_data_table: ^4.1.1 data_table_2: ^2.5.10 + syncfusion_flutter_datepicker: ^21.2.4 dev_dependencies: flutter_test: @@ -117,16 +118,13 @@ dev_dependencies: json_serializable: ^6.3.1 # 分离样式 functional_widget: ^0.10.1 - - + # The "flutter_lints" package below contains a set of recommended lints to # encourage good coding practices. The lint set provided by the package is # activated in the `analysis_options.yaml` file located at the root of your # package. See that file for information about deactivating specific lint # rules and activating additional ones. - - # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec -- 2.40.1 From 7e1ce0ef7298b923ba151e3d33e7fbc1b8eebe22 Mon Sep 17 00:00:00 2001 From: machuanyu <840649825@qq.com> Date: Mon, 11 Mar 2024 10:25:12 +0800 Subject: [PATCH 08/22] =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E5=85=A5=E5=8F=82?= =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lib/pages/homework_correction/index.dart | 5 +- .../job_priority_review_set.dart | 125 ++++++++++++++++++ .../pages/homework_correction/job_report.dart | 3 +- .../widget/quick_student_data_table.dart | 105 ++++++++++----- marking_app/lib/routes/RouterManager.dart | 14 +- 5 files changed, 214 insertions(+), 38 deletions(-) create mode 100644 marking_app/lib/pages/homework_correction/job_priority_review_set.dart diff --git a/marking_app/lib/pages/homework_correction/index.dart b/marking_app/lib/pages/homework_correction/index.dart index 2c45474..b8c5525 100644 --- a/marking_app/lib/pages/homework_correction/index.dart +++ b/marking_app/lib/pages/homework_correction/index.dart @@ -18,6 +18,7 @@ import 'package:marking_app/common/config/request_config.dart'; import 'package:marking_app/common/model/job/job_task_item.dart'; import 'package:marking_app/pages/homework_correction/components/new_version_of_homework/homework_tasks_view_item.dart'; import 'package:marking_app/provider/review_provider.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'; @@ -256,7 +257,9 @@ class _HomeworkCorrectionState extends ConsumerState Expanded( flex: 1, child: InkWell( - onTap: () {}, + onTap: () { + RouterManager.router.navigateTo(context, RouterManager.jobPriorityReviewSetPath,transition: getTransition()); + }, child: Icon(Icons.settings_outlined, color: Color.fromRGBO(44, 48, 63, 1), size: 24.sp), ), ), diff --git a/marking_app/lib/pages/homework_correction/job_priority_review_set.dart b/marking_app/lib/pages/homework_correction/job_priority_review_set.dart new file mode 100644 index 0000000..3c958ed --- /dev/null +++ b/marking_app/lib/pages/homework_correction/job_priority_review_set.dart @@ -0,0 +1,125 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_easyrefresh/easy_refresh.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; + +class JobPriorityReviewSet extends StatefulWidget { + const JobPriorityReviewSet({Key? key}) : super(key: key); + + @override + State createState() => _JobPriorityReviewSetState(); +} + +class _JobPriorityReviewSetState extends State + with SingleTickerProviderStateMixin { + late final EasyRefreshController refreshController; + late TabController tabController; + int tabIndex = 0; + + @override + void initState() { + super.initState(); + refreshController = EasyRefreshController(); + tabController = + TabController(initialIndex: tabIndex, length: 2, vsync: this); + } + + @override + void dispose() { + super.dispose(); + refreshController.dispose(); + tabController.dispose(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Color.fromRGBO(245, 245, 245, 1), + appBar: AppBar( + backgroundColor: Colors.white, + title: Text( + '优先批阅人配置', + style: TextStyle(fontSize: 16.sp, color: Color(0xFF333333)), + ), + centerTitle: true, + leading: IconButton( + icon: Icon(Icons.arrow_back_ios, color: Colors.black), + onPressed: () => Navigator.of(context).pop(), + ), + ), + body: EasyRefresh( + firstRefresh: true, + taskIndependence: true, + enableControlFinishLoad: true, + enableControlFinishRefresh: true, + // emptyWidget: data.isEmpty ? const MyEmptyWidget() : null, + controller: refreshController, + header: MaterialHeader(), + footer: TaurusFooter(), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.symmetric(horizontal: 14.r), + child: TabBar( + onTap: (int val) { + setState(() { + tabIndex = val; + }); + }, + tabs: [ + SizedBox( + width: (MediaQuery.of(context).size.width - 28.r) /2, + child: Tab( + text: '优先批阅', + ), + ), + SizedBox( + width: (MediaQuery.of(context).size.width - 28.r) /2, + child: Tab( + text: '默认批阅', + ), + ) + ], + controller: tabController, + unselectedLabelStyle: TextStyle( + fontSize: 14.sp, color:Color(0xFF666666)), + labelStyle: TextStyle( + fontSize: 14.sp, + color: Color(0xFF6888FD), + ), + isScrollable: true, + labelColor: Color(0xFF6888FD), + unselectedLabelColor: Color(0xFF666666), + indicatorSize: TabBarIndicatorSize.label, + labelPadding: const EdgeInsets.all(0), + ), + ), + Container( + padding: EdgeInsets.symmetric(horizontal: 15.r), + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(10.r)), + color: Colors.white, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text('张小凡',style: TextStyle(fontSize: 12.sp,color: Color(0xFF6888FD)),), + Container( + padding: EdgeInsets.symmetric(vertical: 2.r,horizontal: 10.r), + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(20.r)), + color: Color(0xFF6888FD), + ), + child: Center( + child: Text('取消优先',style: TextStyle(fontSize: 10.sp,color: Colors.white),), + ), + ) + ], + ), + ) + ], + ), + ), + ); + } +} diff --git a/marking_app/lib/pages/homework_correction/job_report.dart b/marking_app/lib/pages/homework_correction/job_report.dart index 7eaab53..7600cdd 100644 --- a/marking_app/lib/pages/homework_correction/job_report.dart +++ b/marking_app/lib/pages/homework_correction/job_report.dart @@ -23,9 +23,10 @@ part 'job_report.g.dart'; /// 作业报告 class JobReport extends StatefulWidget { final int id; + final String uniqueId; final String title; - const JobReport({required this.id, required this.title, super.key}); + const JobReport({required this.id, required this.title,required this.uniqueId, super.key}); @override State createState() => _JobReportState(); 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 index 7fb44fd..4631bc6 100644 --- 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 @@ -35,21 +35,25 @@ class _QuickStudentDataTableState extends State { StudentDetails item = widget.bodyList[index]; int num = 0; item.kgDetails.forEach((element) { - if(element.state == 0){ + if (element.state == 0) { num = num + 1; } }); item.zgDetails.forEach((element) { - if(element.state == 0){ + 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, + color: color != null + ? num == 0 + ? MaterialStateProperty.all(color) + : MaterialStateProperty.all(Color(0xFFFFD79C)) + : null, cells: [ DataCell(InkWell( - onTap: (){ + onTap: () { RouterManager.router.navigateTo( context, RouterManager.quickCheckPersonalPath + @@ -65,9 +69,16 @@ class _QuickStudentDataTableState extends State { 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,) + 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, + ) ], ), ), @@ -91,50 +102,74 @@ class _QuickStudentDataTableState extends State { )), DataCell( Padding( - padding: EdgeInsets.symmetric(vertical:2.r,horizontal: 5.r), + 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) { + 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),)), + 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),)), - ); - })), + 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), + )), + ); + })), + ), ), - ),), + ), ], ); } @@ -184,7 +219,7 @@ class _QuickStudentDataTableState extends State { style: TextStyle(fontSize: 12.sp, color: Color(0xFF505767))), ), // size: ColumnSize.S, - fixedWidth: (MediaQuery.of(context).size.width - 20.r - 28.r)/5, + fixedWidth: (MediaQuery.of(context).size.width - 20.r - 28.r) / 5, ); }), rows: List.generate(widget.bodyList.length, diff --git a/marking_app/lib/routes/RouterManager.dart b/marking_app/lib/routes/RouterManager.dart index a75d82d..f662640 100644 --- a/marking_app/lib/routes/RouterManager.dart +++ b/marking_app/lib/routes/RouterManager.dart @@ -14,6 +14,7 @@ import 'package:flutter/material.dart'; 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_priority_review_set.dart'; import 'package:marking_app/pages/homework_correction/job_report.dart'; import 'package:marking_app/pages/homework_correction/pages/job_list_participate_in_class.dart'; import 'package:marking_app/pages/homework_correction/review_job.dart'; @@ -65,6 +66,7 @@ class RouterManager { 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'; + static const String jobPriorityReviewSetPath = '/homework_correction/job_priority_review_set'; // TheMine @@ -180,7 +182,8 @@ class RouterManager { static final _jobReportPageHandler = Handler(handlerFunc: (BuildContext? context, Map> params) { int id = int.parse(params['id']![0]); String title = params['title']![0]; - return JobReport(id: id, title: title); + String uniqueId = params['uniqueId']![0]; + return JobReport(id: id, title: title,uniqueId:uniqueId); }); // 作业报告页面 @@ -273,6 +276,14 @@ class RouterManager { return QuickCheckPersonal(jobId: jobId,studentId:studentId); }, ); + + //优先配置 + static final _jobPriorityReviewSetPageHandler = Handler( + handlerFunc: (BuildContext? context, Map> params){ + return JobPriorityReviewSet(); + }, + ); + // 开始阅卷页面 // static final _doMarkingPapers = Handler(handlerFunc: (BuildContext? context, Map> params) => MarkingPapers()); @@ -311,6 +322,7 @@ class RouterManager { 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); // getTransition() -- 2.40.1 From 0fad2da7f6511335f26a0c4a41cbefbfe551a94e Mon Sep 17 00:00:00 2001 From: machuanyu <840649825@qq.com> Date: Mon, 11 Mar 2024 10:35:03 +0800 Subject: [PATCH 09/22] =?UTF-8?q?=E5=90=88=E5=B9=B6=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- marking_app/lib/routes/RouterManager.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/marking_app/lib/routes/RouterManager.dart b/marking_app/lib/routes/RouterManager.dart index 36b4990..043071c 100644 --- a/marking_app/lib/routes/RouterManager.dart +++ b/marking_app/lib/routes/RouterManager.dart @@ -66,6 +66,7 @@ class RouterManager { 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'; + static const String jobPriorityReviewSetPath = '/homework_correction/job_priority_review_set'; // TheMine -- 2.40.1 From 9878d22822a998cfeeea9cead6340b0b1fc508a3 Mon Sep 17 00:00:00 2001 From: machuanyu <840649825@qq.com> Date: Mon, 11 Mar 2024 16:46:10 +0800 Subject: [PATCH 10/22] =?UTF-8?q?=E5=AD=A6=E7=94=9F=E5=88=86=E7=BB=84?= =?UTF-8?q?=EF=BC=8C=E4=BC=98=E5=85=88=E6=89=B9=E9=98=85=E4=BA=BA=E9=85=8D?= =?UTF-8?q?=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../model/job/job_level_set_params.dart | 23 ++ .../common/model/job/job_student_goups.dart | 26 ++ .../common/model/job/job_student_level.dart | 32 +++ .../lib/pages/homework_correction/index.dart | 2 +- .../job_priority_review_set.dart | 270 +++++++++++++----- .../job_student_group.dart | 223 +++++++++++++++ .../lib/pages/reports/widgets/userInfo.dart | 2 +- marking_app/lib/routes/RouterManager.dart | 14 +- .../lib/utils/request/rest_client.dart | 19 ++ 9 files changed, 537 insertions(+), 74 deletions(-) create mode 100644 marking_app/lib/common/model/job/job_level_set_params.dart create mode 100644 marking_app/lib/common/model/job/job_student_goups.dart create mode 100644 marking_app/lib/common/model/job/job_student_level.dart create mode 100644 marking_app/lib/pages/homework_correction/job_student_group.dart diff --git a/marking_app/lib/common/model/job/job_level_set_params.dart b/marking_app/lib/common/model/job/job_level_set_params.dart new file mode 100644 index 0000000..5335b17 --- /dev/null +++ b/marking_app/lib/common/model/job/job_level_set_params.dart @@ -0,0 +1,23 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'job_level_set_params.g.dart'; + + +@JsonSerializable() +class JobLevelSetParams extends Object { + + @JsonKey(name: 'studentGroupDetailId') + int studentGroupDetailId; + + @JsonKey(name: 'readLevel') + int readLevel; + + JobLevelSetParams(this.studentGroupDetailId,this.readLevel,); + + factory JobLevelSetParams.fromJson(Map srcJson) => _$JobLevelSetParamsFromJson(srcJson); + + Map toJson() => _$JobLevelSetParamsToJson(this); + +} + + diff --git a/marking_app/lib/common/model/job/job_student_goups.dart b/marking_app/lib/common/model/job/job_student_goups.dart new file mode 100644 index 0000000..5bc6e78 --- /dev/null +++ b/marking_app/lib/common/model/job/job_student_goups.dart @@ -0,0 +1,26 @@ +import 'package:json_annotation/json_annotation.dart'; + +part "job_student_goups.g.dart"; + + +@JsonSerializable() +class JobStudentGroups extends Object { + + @JsonKey(name: 'groupId') + int groupId; + + @JsonKey(name: 'groupName') + String groupName; + + @JsonKey(name: 'classNames') + List classNames; + + JobStudentGroups(this.groupId,this.groupName,this.classNames,); + + factory JobStudentGroups.fromJson(Map srcJson) => _$JobStudentGroupsFromJson(srcJson); + + Map toJson() => _$JobStudentGroupsToJson(this); + +} + + diff --git a/marking_app/lib/common/model/job/job_student_level.dart b/marking_app/lib/common/model/job/job_student_level.dart new file mode 100644 index 0000000..52bf42d --- /dev/null +++ b/marking_app/lib/common/model/job/job_student_level.dart @@ -0,0 +1,32 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'job_student_level.g.dart'; + + +@JsonSerializable() +class JobStudentLevel extends Object { + + @JsonKey(name: 'studentGroupDetailId') + int studentGroupDetailId; + + @JsonKey(name: 'studentId') + int studentId; + + @JsonKey(name: 'studentName') + String studentName; + + @JsonKey(name: 'createTime') + String createTime; + + @JsonKey(name: 'readLevel') + int readLevel; + + JobStudentLevel(this.studentGroupDetailId,this.studentId,this.studentName,this.createTime,this.readLevel,); + + factory JobStudentLevel.fromJson(Map srcJson) => _$JobStudentLevelFromJson(srcJson); + + Map toJson() => _$JobStudentLevelToJson(this); + +} + + diff --git a/marking_app/lib/pages/homework_correction/index.dart b/marking_app/lib/pages/homework_correction/index.dart index 722f730..7981ac3 100644 --- a/marking_app/lib/pages/homework_correction/index.dart +++ b/marking_app/lib/pages/homework_correction/index.dart @@ -261,7 +261,7 @@ class _HomeworkCorrectionState extends ConsumerState flex: 1, child: InkWell( onTap: () { - RouterManager.router.navigateTo(context, RouterManager.jobPriorityReviewSetPath,transition: getTransition()); + RouterManager.router.navigateTo(context, RouterManager.jobStudentGroupPath,transition: getTransition()); }, child: Icon(Icons.settings_outlined, color: Color.fromRGBO(44, 48, 63, 1), size: 24.sp), ), diff --git a/marking_app/lib/pages/homework_correction/job_priority_review_set.dart b/marking_app/lib/pages/homework_correction/job_priority_review_set.dart index 3c958ed..29874ba 100644 --- a/marking_app/lib/pages/homework_correction/job_priority_review_set.dart +++ b/marking_app/lib/pages/homework_correction/job_priority_review_set.dart @@ -1,26 +1,62 @@ 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: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_level_set_params.dart'; +import 'package:marking_app/common/model/job/job_review_submission.dart'; +import 'package:marking_app/common/model/job/job_student_level.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.dart'; class JobPriorityReviewSet extends StatefulWidget { - const JobPriorityReviewSet({Key? key}) : super(key: key); + final String groupId; + const JobPriorityReviewSet({Key? key,required this.groupId}) : super(key: key); @override State createState() => _JobPriorityReviewSetState(); } class _JobPriorityReviewSetState extends State - with SingleTickerProviderStateMixin { + with CommonMixin,SingleTickerProviderStateMixin { late final EasyRefreshController refreshController; late TabController tabController; int tabIndex = 0; + List levelList = []; @override void initState() { super.initState(); + EasyLoading.show(status: 'loading...'); refreshController = EasyRefreshController(); tabController = TabController(initialIndex: tabIndex, length: 2, vsync: this); + getReadLevel(); + } + + void getReadLevel() async{ + RestClient _client = await getClient(); + BaseStructureResult> res = await _client.getJobReadLevel(widget.groupId,tabIndex == 0?1:0); + setState(() { + if(res.code == 200){ + levelList = res.data!; + }else{ + levelList = []; + } + EasyLoading.dismiss(); + }); + + } + + void setJobReadLevel(int studentId,int level) async{ + RestClient _client = await getClient(); + JobLevelSetParams params = JobLevelSetParams(studentId, level); + BaseStructureResult res = await _client.getSetJobReadLevel(params); + if(res.code == 200){ + getReadLevel(); + } } @override @@ -32,6 +68,7 @@ class _JobPriorityReviewSetState extends State @override Widget build(BuildContext context) { + bool isPadFlag = isPad(); return Scaffold( backgroundColor: Color.fromRGBO(245, 245, 245, 1), appBar: AppBar( @@ -46,80 +83,171 @@ class _JobPriorityReviewSetState extends State onPressed: () => Navigator.of(context).pop(), ), ), - body: EasyRefresh( - firstRefresh: true, - taskIndependence: true, - enableControlFinishLoad: true, - enableControlFinishRefresh: true, - // emptyWidget: data.isEmpty ? const MyEmptyWidget() : null, - controller: refreshController, - header: MaterialHeader(), - footer: TaurusFooter(), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: EdgeInsets.symmetric(horizontal: 14.r), - child: TabBar( - onTap: (int val) { - setState(() { - tabIndex = val; - }); - }, - tabs: [ - SizedBox( - width: (MediaQuery.of(context).size.width - 28.r) /2, - child: Tab( - text: '优先批阅', - ), + body: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.symmetric(horizontal: 14.r), + child: TabBar( + onTap: (int val) { + print(val); + setState(() { + tabIndex = val; + }); + EasyLoading.show(status: 'loading...'); + getReadLevel(); + }, + tabs: [ + SizedBox( + width: (MediaQuery.of(context).size.width - 28.r) /2, + child: Tab( + text: '优先批阅', ), - SizedBox( - width: (MediaQuery.of(context).size.width - 28.r) /2, - child: Tab( - text: '默认批阅', - ), - ) - ], - controller: tabController, - unselectedLabelStyle: TextStyle( - fontSize: 14.sp, color:Color(0xFF666666)), - labelStyle: TextStyle( - fontSize: 14.sp, - color: Color(0xFF6888FD), ), - isScrollable: true, - labelColor: Color(0xFF6888FD), - unselectedLabelColor: Color(0xFF666666), - indicatorSize: TabBarIndicatorSize.label, - labelPadding: const EdgeInsets.all(0), + SizedBox( + width: (MediaQuery.of(context).size.width - 28.r) /2, + child: Tab( + text: '默认批阅', + ), + ) + ], + controller: tabController, + unselectedLabelStyle: TextStyle( + fontSize: 14.sp, color:Color(0xFF666666)), + labelStyle: TextStyle( + fontSize: 14.sp, + color: Color(0xFF6888FD), + ), + isScrollable: true, + labelColor: Color(0xFF6888FD), + unselectedLabelColor: Color(0xFF666666), + indicatorSize: TabBarIndicatorSize.label, + labelPadding: const EdgeInsets.all(0), + ), + ), + Expanded( + child:Padding( + padding: EdgeInsets.symmetric(vertical:14.r,horizontal: 14.r), + child: EasyRefresh( + firstRefresh: true, + taskIndependence: true, + enableControlFinishLoad: true, + enableControlFinishRefresh: true, + // emptyWidget: data.isEmpty ? const MyEmptyWidget() : null, + controller: refreshController, + header: MaterialHeader(), + footer: TaurusFooter(), + child: levelList.length>0?isPadFlag?GridView(gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, + mainAxisSpacing: 10.r, + crossAxisSpacing: 10.r, + childAspectRatio: 556 / 112, + ),children: List.generate(levelList.length, (index) { + JobStudentLevel item = levelList[index]; + return Container( + padding: EdgeInsets.symmetric(horizontal: 15.r), + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(10.r)), + color: Colors.white, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text(item.studentName,style: TextStyle(fontSize: 12.sp,color: Color(0xFF6888FD)),), + tabIndex == 0?InkWell( + onTap: (){ + setJobReadLevel(item.studentGroupDetailId,0); + EasyLoading.show(status: 'loading...'); + }, + child: Container( + height: 20.r, + width: 70.r, + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(20.r)), + color: Color(0xFF6888FD), + ), + child: Center( + child:Text('取消优先',style: TextStyle(fontSize: 10.sp,color: Colors.white),), + ), + ), + ):InkWell( + onTap: (){ + setJobReadLevel(item.studentGroupDetailId,1); + EasyLoading.show(status: 'loading...'); + }, + child: Container( + height: 20.r, + width: 70.r, + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(20.r)), + color: Color(0xFFFFFFFF), + border: Border.all(width: 1.r,color: Color(0xFF6888FD)), + ), + child: Center( + child:Text('设为优先',style: TextStyle(fontSize: 10.sp,color: Color(0xFF6888FD)),), + ), + ), + ) + ], + ), + ); + }),):ListView.builder(itemBuilder: (context,index){ + JobStudentLevel item = levelList[index]; + return Container( + padding: EdgeInsets.symmetric(vertical:20.r,horizontal: 15.r), + margin: EdgeInsets.only(bottom: 15.r), + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(10.r)), + color: Colors.white, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text(item.studentName,style: TextStyle(fontSize: 12.sp,color: Color(0xFF6888FD)),), + tabIndex == 0?InkWell( + onTap: (){ + setJobReadLevel(item.studentGroupDetailId,0); + EasyLoading.show(status: 'loading...'); + }, + child: Container( + height: 24.r, + width: 82.r, + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(20.r)), + color: Color(0xFF6888FD), + ), + child: Center( + child:Text('取消优先',style: TextStyle(fontSize: 10.sp,color: Colors.white),), + ), + ), + ):InkWell( + onTap: (){ + setJobReadLevel(item.studentGroupDetailId,1); + EasyLoading.show(status: 'loading...'); + }, + child: Container( + height: 24.r, + width: 82.r, + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(20.r)), + color: Color(0xFFFFFFFF), + border: Border.all(width: 1.r,color: Color(0xFF6888FD)), + ), + child: Center( + child:Text('设为优先',style: TextStyle(fontSize: 10.sp,color: Color(0xFF6888FD)),), + ), + ), + ) + ], + ), + ); + },itemCount: levelList.length,):MyEmptyWidget(), ), ), - Container( - padding: EdgeInsets.symmetric(horizontal: 15.r), - decoration: BoxDecoration( - borderRadius: BorderRadius.all(Radius.circular(10.r)), - color: Colors.white, - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text('张小凡',style: TextStyle(fontSize: 12.sp,color: Color(0xFF6888FD)),), - Container( - padding: EdgeInsets.symmetric(vertical: 2.r,horizontal: 10.r), - decoration: BoxDecoration( - borderRadius: BorderRadius.all(Radius.circular(20.r)), - color: Color(0xFF6888FD), - ), - child: Center( - child: Text('取消优先',style: TextStyle(fontSize: 10.sp,color: Colors.white),), - ), - ) - ], - ), - ) - ], - ), + ) + ], ), ); } } + diff --git a/marking_app/lib/pages/homework_correction/job_student_group.dart b/marking_app/lib/pages/homework_correction/job_student_group.dart new file mode 100644 index 0000000..4337ee4 --- /dev/null +++ b/marking_app/lib/pages/homework_correction/job_student_group.dart @@ -0,0 +1,223 @@ +import 'dart:convert'; + +import 'package:flutter/material.dart'; +import 'package:flutter_easyrefresh/easy_refresh.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_student_goups.dart'; +import 'package:marking_app/common/model/user/user_info.dart'; +import 'package:marking_app/routes/RouterManager.dart'; +import 'package:marking_app/utils/easy_refresh/MyEmptyWidget.dart'; +import 'package:marking_app/utils/fast_data.dart'; +import 'package:marking_app/utils/index.dart'; +import 'package:marking_app/utils/request/rest_client.dart'; + +class JobStudentGroup extends StatefulWidget { + const JobStudentGroup({Key? key}) : super(key: key); + + @override + State createState() => _JobStudentGroupState(); +} + +class _JobStudentGroupState extends State with CommonMixin { + late final EasyRefreshController refreshController; + late String loginName; + List studentGroups = []; + + @override + void initState() { + super.initState(); + refreshController = EasyRefreshController(); + FastData fastData = FastData.getInstance(); + fastData.getUser().then((value) { + if (value == null || value == '') return; + Map userInfo = json.decode(value); + setState(() { + loginName = userInfo['loginName']; + }); + getStudentGroups(); + print(userInfo); + }); + } + + void getStudentGroups() async { + RestClient _client = await getClient(); + BaseStructureResult> res = + await _client.getJobLevelStudentGroups(loginName); + setState(() { + if(res.code == 200){ + studentGroups = res.data!; + }else{ + studentGroups = []; + } + + }); + } + + @override + void dispose() { + super.dispose(); + refreshController.dispose(); + } + + @override + Widget build(BuildContext context) { + bool isPadFlag = isPad(); + return Scaffold( + backgroundColor: Color.fromRGBO(245, 245, 245, 1), + appBar: AppBar( + backgroundColor: Colors.white, + title: Text( + '我的学生分组', + style: TextStyle(fontSize: 16.sp, color: Color(0xFF333333)), + ), + centerTitle: true, + leading: IconButton( + icon: Icon(Icons.arrow_back_ios, color: Colors.black), + onPressed: () => Navigator.of(context).pop(), + ), + ), + body: Padding( + padding: EdgeInsets.only(top: 15.r, left: 14.r, right: 14.r), + child: EasyRefresh( + firstRefresh: true, + taskIndependence: true, + enableControlFinishLoad: true, + enableControlFinishRefresh: true, + // emptyWidget: data.isEmpty ? const MyEmptyWidget() : null, + controller: refreshController, + header: MaterialHeader(), + footer: TaurusFooter(), + child: studentGroups != null && studentGroups.length > 0 + ? isPadFlag?GridView( + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, + mainAxisSpacing: 10.r, + crossAxisSpacing: 10.r, + childAspectRatio: 556 / 112, + ), + children: List.generate(studentGroups.length, (index) { + JobStudentGroups item = studentGroups[index]; + String classNames = item.classNames.join(" "); + return Container( + padding: EdgeInsets.symmetric(horizontal: 10.r), + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(10.r)), + color: Colors.white, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.only(right: 8.r), + child: Text( + item.groupName, + style: TextStyle( + fontSize: 10.sp, color: Color(0xFF6888FD)), + ), + ), + Expanded( + child: Text( + classNames, + style: TextStyle( + fontSize: 10.sp, + color: Color(0xFF999999), + overflow: TextOverflow.ellipsis, + ), + textAlign: TextAlign.end, + ), + ), + InkWell( + onTap: (){ + RouterManager.router.navigateTo(context, '${RouterManager.jobPriorityReviewSetPath}?&groupId=${item.groupId}',transition: getTransition()); + }, + child: Container( + margin: EdgeInsets.only(left: 5.r), + height: 20.r, + width: 55.r, + decoration: BoxDecoration( + borderRadius: + BorderRadius.all(Radius.circular(20.r)), + color: Color(0xFF6888FD), + ), + child: Center( + child: Text( + '设置', + style: TextStyle( + fontSize: 10.sp, color: Colors.white), + ), + ), + ), + ) + ], + ), + ); + }), + ):ListView.builder( + itemBuilder: (context,index){ + JobStudentGroups item = studentGroups[index]; + String classNames = item.classNames.join(" "); + return Container( + padding: EdgeInsets.symmetric(vertical:15.r,horizontal: 10.r), + margin: EdgeInsets.only(bottom: 10.r), + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(10.r)), + color: Colors.white, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.only(right: 8.r), + child: Text( + item.groupName, + style: TextStyle( + fontSize: 14.sp, color: Color(0xFF6888FD)), + ), + ), + Expanded( + child: Text( + classNames, + style: TextStyle( + fontSize: 12.sp, + color: Color(0xFF999999), + overflow: TextOverflow.ellipsis, + ), + textAlign: TextAlign.end, + ), + ), + InkWell( + onTap: (){ + RouterManager.router.navigateTo(context, '${RouterManager.jobPriorityReviewSetPath}?&groupId=${item.groupId}',transition: getTransition()); + }, + child: Container( + margin: EdgeInsets.only(left: 5.r), + height: 24.r, + width: 55.r, + decoration: BoxDecoration( + borderRadius: + BorderRadius.all(Radius.circular(20.r)), + color: Color(0xFF6888FD), + ), + child: Center( + child: Text( + '设置', + style: TextStyle( + fontSize: 10.sp, color: Colors.white), + ), + ), + ), + ) + ], + ), + ); + }, + itemCount: studentGroups.length, + ) + : MyEmptyWidget(), + ), + ), + ); + } +} diff --git a/marking_app/lib/pages/reports/widgets/userInfo.dart b/marking_app/lib/pages/reports/widgets/userInfo.dart index 9c8469c..8c27078 100644 --- a/marking_app/lib/pages/reports/widgets/userInfo.dart +++ b/marking_app/lib/pages/reports/widgets/userInfo.dart @@ -11,7 +11,7 @@ class TopUserInfo extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { - final userState = ref.watch(userProvider); + final userState = ref.read(userProvider); return InkWell( onTap: () { diff --git a/marking_app/lib/routes/RouterManager.dart b/marking_app/lib/routes/RouterManager.dart index 043071c..31e0d05 100644 --- a/marking_app/lib/routes/RouterManager.dart +++ b/marking_app/lib/routes/RouterManager.dart @@ -16,6 +16,7 @@ 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_priority_review_set.dart'; import 'package:marking_app/pages/homework_correction/job_report.dart'; +import 'package:marking_app/pages/homework_correction/job_student_group.dart'; import 'package:marking_app/pages/homework_correction/pages/job_list_participate_in_class.dart'; import 'package:marking_app/pages/homework_correction/review_job.dart'; import 'package:marking_app/pages/homework_correction/quick_check_personal.dart'; @@ -67,6 +68,7 @@ class RouterManager { static const String quickDataCheckPath = '/homework_correction/quick_data_check'; static const String quickCheckPersonalPath = '/homework_correction/quick_check_personal'; static const String jobPriorityReviewSetPath = '/homework_correction/job_priority_review_set'; + static const String jobStudentGroupPath = '/homework_correction/job_student_group'; // TheMine @@ -281,10 +283,19 @@ class RouterManager { //优先配置 static final _jobPriorityReviewSetPageHandler = Handler( handlerFunc: (BuildContext? context, Map> params){ - return JobPriorityReviewSet(); + String groupId = params['groupId']![0]; + return JobPriorityReviewSet(groupId:groupId); }, ); + //学生分组 + static final _jobStudentGroupPageHandler = Handler( + handlerFunc: (BuildContext? context, Map> params){ + return JobStudentGroup(); + }, + ); + + // 开始阅卷页面 // static final _doMarkingPapers = Handler(handlerFunc: (BuildContext? context, Map> params) => MarkingPapers()); @@ -325,6 +336,7 @@ class RouterManager { router.define(quickCheckPersonalPath, handler: _quickCheckPersonalPageHandler, transitionType: TransitionType.material); router.define(jobPriorityReviewSetPath, handler: _jobPriorityReviewSetPageHandler, transitionType: TransitionType.material); + router.define(jobStudentGroupPath, handler: _jobStudentGroupPageHandler, 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 6aca9ec..a080316 100644 --- a/marking_app/lib/utils/request/rest_client.dart +++ b/marking_app/lib/utils/request/rest_client.dart @@ -17,6 +17,7 @@ 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_level_set_params.dart'; import 'package:marking_app/common/model/job/job_note_taking_trajectory.dart'; import 'package:marking_app/common/model/job/job_page_tab.dart'; import 'package:marking_app/common/model/job/job_report_join_class.dart'; @@ -24,6 +25,8 @@ 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/common/model/job/job_report_question_deatil_model.dart'; import 'package:marking_app/common/model/job/job_review_submission.dart'; +import 'package:marking_app/common/model/job/job_student_goups.dart'; +import 'package:marking_app/common/model/job/job_student_level.dart'; import 'package:marking_app/common/model/job/job_task_item.dart'; import 'package:marking_app/common/model/job/marking_text_question_job.dart'; import 'package:marking_app/common/model/job/marking_text_question_job_params.dart'; @@ -299,5 +302,21 @@ abstract class RestClient { // 作业 => 数据快查--个人 @the_retrofit.GET("/api/read/job-data-center-student-report") Future> getJobPersonalReport(@the_retrofit.Queries() Map params); + + // 作业 => 优先批阅,学生分组列表 + @the_retrofit.GET("/api/read/job-read-level-student-groups") + Future>> getJobLevelStudentGroups( + @the_retrofit.Query("account") String account); + + // 作业 => 优先批阅,优先批阅列表 + @the_retrofit.GET("/api/read/job-read-level") + Future>> getJobReadLevel( + @the_retrofit.Query("GroupId") String groupId, @the_retrofit.Query("ReadLevel") int readLevel); + + // 作业 => 取消/设置优先 + @the_retrofit.POST("/api/read/jc-job-read-level") + Future getSetJobReadLevel(@the_retrofit.Body() JobLevelSetParams params); + + } -- 2.40.1 From 195b6ba2b5902585066e1b3090c8c234b3eeba9d Mon Sep 17 00:00:00 2001 From: "1147192855@qq.com" <1147192855@qq.com> Date: Mon, 11 Mar 2024 17:16:42 +0800 Subject: [PATCH 11/22] =?UTF-8?q?=E8=B0=83=E6=95=B4=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + marking_app/assets/icons/demo_index.html | 29 +- marking_app/assets/icons/iconfont.css | 10 +- marking_app/assets/icons/iconfont.js | 2 +- marking_app/assets/icons/iconfont.json | 7 + marking_app/assets/icons/iconfont.ttf | Bin 13756 -> 13996 bytes marking_app/assets/icons/iconfont.woff | Bin 8432 -> 8600 bytes marking_app/assets/icons/iconfont.woff2 | Bin 7152 -> 7304 bytes .../common/model/job/job_favorite_model.dart | 33 ++ .../lib/common/model/job/job_task_item.dart | 18 +- .../homework_tasks_view_item.dart | 9 +- .../lib/pages/homework_correction/index.dart | 13 +- .../pages/job_list_participate_in_class.dart | 368 ++++++++++-------- .../lib/utils/request/rest_client.dart | 9 +- 14 files changed, 331 insertions(+), 168 deletions(-) create mode 100644 marking_app/lib/common/model/job/job_favorite_model.dart diff --git a/.gitignore b/.gitignore index 60eaaac..b395556 100644 --- a/.gitignore +++ b/.gitignore @@ -201,3 +201,4 @@ marking_app/lib/common/model/job/job_report_question_deatil_model.g.dart marking_app/lib/common/model/job/job_do_marking_status_info.g.dart marking_app/lib/common/model/report/small_question.g.dart marking_app/lib/pages/homework_correction/pages/job_list_participate_in_class.g.dart +marking_app/lib/common/model/job/job_favorite_model.g.dart diff --git a/marking_app/assets/icons/demo_index.html b/marking_app/assets/icons/demo_index.html index ae14068..d81cd85 100644 --- a/marking_app/assets/icons/demo_index.html +++ b/marking_app/assets/icons/demo_index.html @@ -54,6 +54,12 @@
    +
  • + +
    Frame
    +
    &#xe63e;
    +
  • +
  • Frame
    @@ -408,9 +414,9 @@
    @font-face {
       font-family: 'iconfont';
    -  src: url('iconfont.woff2?t=1706671294868') format('woff2'),
    -       url('iconfont.woff?t=1706671294868') format('woff'),
    -       url('iconfont.ttf?t=1706671294868') format('truetype');
    +  src: url('iconfont.woff2?t=1710142362036') format('woff2'),
    +       url('iconfont.woff?t=1710142362036') format('woff'),
    +       url('iconfont.ttf?t=1710142362036') format('truetype');
     }
     

    第二步:定义使用 iconfont 的样式

    @@ -436,6 +442,15 @@
      +
    • + +
      + Frame +
      +
      .icon-Frame14 +
      +
    • +
    • @@ -967,6 +982,14 @@
        +
      • + +
        Frame
        +
        #icon-Frame14
        +
      • +
      • IW{V_72vGNRa!hZvj z)%^Q!KtH_4A0urn8auXgwt^Wm-LrE!Y;E2*!Sf?uR?WzasOIt>~HPVk{Bc#L7+AV7rkjy-p7q LSZV6LXRx@xYN+cC diff --git a/marking_app/assets/icons/iconfont.woff b/marking_app/assets/icons/iconfont.woff index 3cb60a15a3347f25a6854d528ffa1473b46f3871..3f5f98709692b1f8915ee97261a4748a278758f9 100644 GIT binary patch delta 8054 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 literal 7152 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 diff --git a/marking_app/lib/common/model/job/job_favorite_model.dart b/marking_app/lib/common/model/job/job_favorite_model.dart new file mode 100644 index 0000000..c0181fd --- /dev/null +++ b/marking_app/lib/common/model/job/job_favorite_model.dart @@ -0,0 +1,33 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'job_favorite_model.g.dart'; + +@JsonSerializable() +class JobFavoriteModel extends Object { + @JsonKey(name: 'schoolId') + int schoolId; + + @JsonKey(name: 'gradeId') + int gradeId; + + @JsonKey(name: 'graduationYear') + String graduationYear; + + @JsonKey(name: 'className') + String className; + + @JsonKey(name: 'count') + int count; + + JobFavoriteModel( + this.schoolId, + this.gradeId, + this.graduationYear, + this.className, + this.count, + ); + + factory JobFavoriteModel.fromJson(Map srcJson) => _$JobFavoriteModelFromJson(srcJson); + + Map toJson() => _$JobFavoriteModelToJson(this); +} diff --git a/marking_app/lib/common/model/job/job_task_item.dart b/marking_app/lib/common/model/job/job_task_item.dart index 1cd83ff..316c4ac 100644 --- a/marking_app/lib/common/model/job/job_task_item.dart +++ b/marking_app/lib/common/model/job/job_task_item.dart @@ -107,6 +107,10 @@ class MarkingTasks extends Object { @JsonKey(name: 'className') String className; + int dpcSchoolId; + + int dpcGradeId; + @JsonKey(name: 'teacherName') String teacherName; @@ -148,8 +152,14 @@ class MarkingTasks extends Object { @JsonKey(name: 'canGoReview') bool canGoReview; // 是否能批阅 + /** 前端自定义字段 */ + @JsonKey(name: 'collectNumber') + int collectNumber; // 是否能批阅 + MarkingTasks( this.id, + this.dpcSchoolId, + this.dpcGradeId, this.className, this.teacherName, this.isFinish, @@ -157,13 +167,14 @@ class MarkingTasks extends Object { this.commitStudentCount, this.totalCount, this.finishCount, + this.precision, this.objectivePrecision, this.subjectivePrecision, - this.precision, this.canMarking, { this.progressPercentage = 0, this.canGoReview = true, this.finishTime, + this.collectNumber = 0, }) { try { progressPercentage = (finishCount / totalCount) * 100; @@ -174,6 +185,11 @@ class MarkingTasks extends Object { } catch (e) { progressPercentage = 0; } + try { + precision = precision / 100; + objectivePrecision = objectivePrecision / 100; + subjectivePrecision = subjectivePrecision / 100; + } catch (e) {} canGoReview = totalCount > 0 && canMarking && !isFinish; } diff --git a/marking_app/lib/pages/homework_correction/components/new_version_of_homework/homework_tasks_view_item.dart b/marking_app/lib/pages/homework_correction/components/new_version_of_homework/homework_tasks_view_item.dart index 872261a..4afc93f 100644 --- a/marking_app/lib/pages/homework_correction/components/new_version_of_homework/homework_tasks_view_item.dart +++ b/marking_app/lib/pages/homework_correction/components/new_version_of_homework/homework_tasks_view_item.dart @@ -249,7 +249,14 @@ Widget $completedHomeworkView(BuildContext context, child: Row(children: [ Expanded( child: InkWell( - onTap: () => easyThrottle('go_to_homework_report', () => {}), + onTap: () => easyThrottle('go_to_homework_report', () { + RouterManager.router.navigateTo( + context, + RouterManager.jobReportPagePath + + '?title=${Uri.encodeComponent(jobTaskItem.title)}&id=${jobTaskItem.id}', + transition: getTransition(), + ); + }), child: Container( alignment: Alignment.center, child: quickText('查看报告', color: Color.fromRGBO(118, 118, 118, 1), size: 12.sp), diff --git a/marking_app/lib/pages/homework_correction/index.dart b/marking_app/lib/pages/homework_correction/index.dart index 722f730..8b64eca 100644 --- a/marking_app/lib/pages/homework_correction/index.dart +++ b/marking_app/lib/pages/homework_correction/index.dart @@ -261,9 +261,11 @@ class _HomeworkCorrectionState extends ConsumerState flex: 1, child: InkWell( onTap: () { - RouterManager.router.navigateTo(context, RouterManager.jobPriorityReviewSetPath,transition: getTransition()); + RouterManager.router.navigateTo(context, RouterManager.jobPriorityReviewSetPath, + transition: getTransition()); }, - child: Icon(Icons.settings_outlined, color: Color.fromRGBO(44, 48, 63, 1), size: 24.sp), + child: Icon(IconData(0xe63e, fontFamily: "AlibabaIcon"), + color: Color.fromRGBO(44, 48, 63, 1), size: 24.sp), ), ), ], @@ -466,7 +468,12 @@ Widget $reviewedItem(BuildContext context, {required JobTaskItem jobTaskItem}) { ), GestureDetector( onTap: () => easyThrottle('go_to_homework_report', () { - print('子级点击方法'); + RouterManager.router.navigateTo( + context, + RouterManager.jobReportPagePath + + '?title=${Uri.encodeComponent(jobTaskItem.title)}&id=${jobTaskItem.id}', + transition: getTransition(), + ); }), child: Container( padding: EdgeInsets.symmetric(vertical: 6.h), diff --git a/marking_app/lib/pages/homework_correction/pages/job_list_participate_in_class.dart b/marking_app/lib/pages/homework_correction/pages/job_list_participate_in_class.dart index 3842766..bf0e50a 100644 --- a/marking_app/lib/pages/homework_correction/pages/job_list_participate_in_class.dart +++ b/marking_app/lib/pages/homework_correction/pages/job_list_participate_in_class.dart @@ -4,6 +4,9 @@ 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.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_favorite_model.dart'; import 'package:marking_app/common/model/job/job_task_item.dart'; import 'package:marking_app/routes/RouterManager.dart'; import 'package:marking_app/utils/index.dart'; @@ -27,14 +30,16 @@ class JobListParticipateInClass extends StatefulWidget { class _JobListParticipateInClassState extends State with CommonMixin { late Future?> _future; - + Map favoriteMap = {}; bool isRefresh = false; @override void initState() { // TODO: implement initState super.initState(); + getListOfJobFavoritesData(); _future = getData(); + Future.delayed(Duration.zero, () { print(ScreenUtil().scaleWidth); print(MediaQuery.of(context).devicePixelRatio); @@ -47,6 +52,17 @@ class _JobListParticipateInClassState extends State w super.dispose(); } + Future getListOfJobFavoritesData() async { + RestClient _client = await getClient(); + BaseStructureResult> result = await _client.getListOfJobFavorites(widget.jobId); + if (result.success) { + result.data?.forEach((e) { + favoriteMap['${e.schoolId}+${e.gradeId}+${e.className}'] = e.count; + }); + toUpState(setState, () {}, mounted); + } + } + Future?> getData() async { RestClient _client = await getClient(); BaseStructureResult> _result = await _client.getJobListParticipateInClass(widget.jobId); @@ -175,6 +191,7 @@ class _JobListParticipateInClassState extends State w } } + /// 结束批阅 void endReview(MarkingTasks task) async { /// 结束批阅逻辑 if (!task.canMarking) return ToastUtils.showInfo('此任务非该账号任务'); @@ -252,13 +269,102 @@ class _JobListParticipateInClassState extends State w void bookmarks(MarkingTasks task) {} // 数据快查 - void quickDataCheck(MarkingTasks task) {} + void quickDataCheck(MarkingTasks task) { + RouterManager.router.navigateTo( + context, + RouterManager.quickDataCheckPath + '?className=${Uri.encodeComponent(task.className)}&jobId=${widget.jobId}', + transition: getTransition(), + ); + } // 查看作业报告 - void jobViewReport(MarkingTasks task) {} + void jobViewReport(MarkingTasks task) { + // RouterManager.router.navigateTo( + // context, + // RouterManager.jobReportPagePath + '?title=${Uri.encodeComponent(task.title)}&id=${task.id}', + // transition: getTransition(), + // ); + } /// 查看学生名单 - void showStudentList([bool submitted = false]) {} + /// @name showStudentList + /// @param {List} taskId 子任务ID集合 + /// @param {bool} className 班级名称(不传此参数为主任务;传此参数为子任务) + /// @param {bool} submitted 是否已提交(默认未提交) + void showStudentList(List taskIds, [String? className, bool submitted = false]) async { + ToastUtils.showLoading(); + List students = []; + try { + RestClient _client = await getClient(); + BaseStructureResult> _result = + await _client.getJobWithStudents(JobConcernedWithStudentParams(taskIds, isCommit: submitted)); + if (!_result.success) { + return ToastUtils.showError(_result.message ?? '获取学生列表失败'); + } + if (_result.data?.isEmpty ?? true) { + return ToastUtils.showError('获取到的学生列表为空'); + } + students = _result.data!; + } catch (e) { + return ToastUtils.showError('获取学生列表失败'); + } finally { + ToastUtils.dismiss(); + } + + showModalBottomSheet( + context: context, + elevation: 10, + backgroundColor: Colors.white, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.only( + topLeft: Radius.circular(20.r), + topRight: Radius.circular(20.r), + ), + ), + builder: (BuildContext context) { + return Padding( + padding: EdgeInsets.symmetric(horizontal: 2.w), + child: Column( + children: [ + Container( + margin: EdgeInsets.only(top: 14.h, bottom: 10.h), + child: quickText( + '${className ?? ''} ${submitted ? '已提交' : '未提交'}作业学生', + size: isPad() ? 15.sp : 15.sp, + fontWeight: FontWeight.bold, + color: Color.fromRGBO(60, 60, 60, 1), + ), + ), + Expanded( + child: ListView( + padding: EdgeInsets.symmetric(vertical: 8.h, horizontal: 4.w), + children: [ + Wrap( + spacing: 6.0, // 主轴(水平)方向间距 + runSpacing: 4.0, // 纵轴(垂直)方向间距 + alignment: WrapAlignment.spaceAround, //沿主轴方向居中 + children: students.map((e) { + return Chip( + backgroundColor: Color.fromRGBO(239, 242, 255, 1), + avatar: CircleAvatar( + backgroundColor: Colors.white, + child: quickText(e.studentName.substring(0, 1), + size: 12.sp, color: Theme.of(context).primaryColor), + ), + label: quickText(e.studentName, color: Color.fromRGBO(80, 94, 110, 1), size: 12.sp), + ); + }).toList(), + ), + ], + ), + ) + ], + ), + ); + }, + ); + } + @override Widget build(BuildContext context) { return Scaffold( @@ -276,6 +382,9 @@ class _JobListParticipateInClassState extends State w ), body: MyFutureBuilder.buildFutureBuilderOfSingleInstance?>(context, _future, (value) { if (value == null) return Container(); + value.forEach((e) { + e.collectNumber = favoriteMap['${e.dpcSchoolId}+${e.dpcGradeId}+${e.className}'] ?? 0; + }); bool thePadTerminal = isPad(); if (widget.completed) { // 已完成 @@ -286,6 +395,7 @@ class _JobListParticipateInClassState extends State w bookmarks: bookmarks, jobViewReport: jobViewReport, quickDataCheck: quickDataCheck, + showStudentList: showStudentList, ); // 已完成手机端 @@ -385,6 +495,7 @@ class TabletEndCompleted extends StatelessWidget { final Bookmarks bookmarks; // 收藏夹 final JobViewReport jobViewReport; final QuickDataCheck quickDataCheck; // 数据快查 + final ShowStudentList showStudentList; // 学生列表查询 const TabletEndCompleted({ required this.genderName, required this.data, @@ -393,6 +504,7 @@ class TabletEndCompleted extends StatelessWidget { required this.bookmarks, required this.jobViewReport, required this.quickDataCheck, + required this.showStudentList, super.key, }); @@ -467,7 +579,8 @@ class TabletEndCompleted extends StatelessWidget { color: Color.fromRGBO(104, 136, 253, 1), borderRadius: BorderRadius.circular(16.r), child: InkWell( - onTap: () => easyThrottle('OneClickReview', () {}), + onTap: () => easyThrottle( + 'OneClickReview', () => showStudentList([taskItem.id], taskItem.className)), borderRadius: BorderRadius.circular(8.r), child: Container( alignment: Alignment.center, @@ -475,7 +588,7 @@ class TabletEndCompleted extends StatelessWidget { decoration: BoxDecoration( borderRadius: BorderRadius.circular(20.r), ), - child: quickText('已提交(${taskItem.commitStudentCount})', size: 8.sp, color: Colors.white), + child: quickText('已提交:${taskItem.commitStudentCount}', size: 8.sp, color: Colors.white), ), ), ), @@ -487,13 +600,15 @@ class TabletEndCompleted extends StatelessWidget { color: Color.fromRGBO(244, 244, 244, 1), borderRadius: BorderRadius.circular(20.r), child: InkWell( - onTap: () async {}, + onTap: () => easyThrottle( + 'OneClickReview', () => showStudentList([taskItem.id], taskItem.className, false)), borderRadius: BorderRadius.circular(8.r), child: Container( alignment: Alignment.center, padding: EdgeInsets.symmetric(vertical: 4.h), decoration: BoxDecoration(borderRadius: BorderRadius.circular(20.r)), - child: quickText('数据快查', size: 8.sp, color: Color.fromRGBO(102, 102, 102, 1)), + child: quickText('未提交:${taskItem.totalCount - taskItem.commitStudentCount}', + size: 8.sp, color: Color.fromRGBO(102, 102, 102, 1)), ), ), ), @@ -511,7 +626,8 @@ class TabletEndCompleted extends StatelessWidget { alignment: Alignment.center, padding: EdgeInsets.symmetric(vertical: 4.h), decoration: BoxDecoration(borderRadius: BorderRadius.circular(20.r)), - child: quickText('收藏夹(2)', size: 8.sp, color: Color.fromRGBO(102, 102, 102, 1)), + child: quickText('收藏夹(${taskItem.collectNumber})', + size: 8.sp, color: Color.fromRGBO(102, 102, 102, 1)), ), ), )), @@ -573,7 +689,7 @@ class MobileEndCompleted extends StatelessWidget { final Bookmarks bookmarks; // 收藏夹 final JobViewReport jobViewReport; // 查看报告 final QuickDataCheck quickDataCheck; // 数据快查 - final ShowStudentList showStudentList; + final ShowStudentList showStudentList; // 学生名单 const MobileEndCompleted({ required this.genderName, @@ -595,152 +711,25 @@ class MobileEndCompleted extends StatelessWidget { children: data.map((task) { return Container( padding: EdgeInsets.only(top: 11.h), + margin: EdgeInsets.only(bottom: 18.h), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadiusDirectional.circular(10.r), boxShadow: [BoxShadow(color: Color.fromRGBO(0, 0, 0, 0.15), blurRadius: 10)], + // border: Border(bottom: BorderSide(color: Color.fromRGBO(238, 238, 238, 1), width: 1.r)), ), child: Column( mainAxisSize: MainAxisSize.min, children: [ - Padding( - padding: padingEdg, - child: Row( - children: [ - quickText(genderName + task.className, color: Color.fromRGBO(0, 0, 0, 1), size: 14.sp), - Expanded(child: SizedBox()), - quickText('已交:${task.commitStudentCount}', color: Color.fromRGBO(104, 136, 253, 1), size: 12.sp), - SizedBox(width: 16.w), - quickText('未交:${task.studentCount - task.commitStudentCount}', - color: Color.fromRGBO(255, 86, 86, 1), size: 12.sp), - ], - ), - ), - SizedBox(height: 13.h), - Padding( - padding: padingEdg, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: task.isFinish - ? [ - Expanded( - flex: 3, - child: Material( - color: Color.fromRGBO(244, 244, 244, 1), - borderRadius: BorderRadius.circular(20.r), - child: InkWell( - onTap: () async {}, - borderRadius: BorderRadius.circular(8.r), - child: Container( - alignment: Alignment.center, - padding: EdgeInsets.symmetric(vertical: 5.h), - decoration: BoxDecoration(borderRadius: BorderRadius.circular(20.r)), - child: quickText('收藏夹(2)', size: 10.sp, color: Color.fromRGBO(102, 102, 102, 1)), - ), - ), - )), - Expanded(flex: 1, child: SizedBox()), - Expanded(flex: 3, child: SizedBox()), - Expanded(flex: 1, child: SizedBox()), - Expanded(flex: 3, child: SizedBox()), - ] - : [ - Expanded( - flex: 3, - child: Material( - color: Color.fromRGBO(104, 136, 253, 1), - borderRadius: BorderRadius.circular(16.r), - child: InkWell( - onTap: () => easyThrottle('OneClickReview', () {}), - borderRadius: BorderRadius.circular(8.r), - child: Container( - alignment: Alignment.center, - padding: EdgeInsets.symmetric(vertical: 5.h), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(20.r), - ), - child: quickText('一键批阅', size: 10.sp, color: Colors.white), - ), - ), - ), - ), - Expanded(flex: 1, child: SizedBox()), - Expanded( - flex: 3, - child: Material( - color: Color.fromRGBO(244, 244, 244, 1), - borderRadius: BorderRadius.circular(20.r), - child: InkWell( - onTap: () async {}, - borderRadius: BorderRadius.circular(8.r), - child: Container( - alignment: Alignment.center, - padding: EdgeInsets.symmetric(vertical: 5.h), - decoration: BoxDecoration(borderRadius: BorderRadius.circular(20.r)), - child: quickText('数据快查', size: 10.sp, color: Color.fromRGBO(102, 102, 102, 1)), - ), - ), - ), - ), - Expanded(flex: 1, child: SizedBox()), - Expanded( - flex: 3, - child: Material( - color: Color.fromRGBO(244, 244, 244, 1), - borderRadius: BorderRadius.circular(20.r), - child: InkWell( - onTap: () async {}, - borderRadius: BorderRadius.circular(8.r), - child: Container( - alignment: Alignment.center, - padding: EdgeInsets.symmetric(vertical: 5.h), - decoration: BoxDecoration(borderRadius: BorderRadius.circular(20.r)), - child: quickText('收藏夹(2)', size: 10.sp, color: Color.fromRGBO(102, 102, 102, 1)), - ), - ), - )), - ], - ), - ), - SizedBox(height: 13.h), - Padding( - padding: padingEdg, - child: Row( - children: [ - Expanded( - child: LinearPercentIndicator( - padding: EdgeInsets.zero, - animation: true, - lineHeight: 8.h, - animationDuration: 2500, - - percent: task.progressPercentage / 100, - // center: Text( - // '${getDoubleRemoveZero(jobTaskClassItem.progressPercentage)}%', - // style: TextStyle(color: Colors.white, fontSize: 8.sp), - // ), - linearGradient: LinearGradient( - tileMode: TileMode.mirror, - stops: [0.0, 1.0], - colors: task.progressPercentage / 100 != 1 - ? [Theme.of(context).primaryColor.withOpacity(0.1), Theme.of(context).primaryColor] - : [ - Color.fromRGBO(144, 224, 190, 1).withOpacity(0.1), - Color.fromRGBO(144, 224, 190, 1), - ], - ), - // linearStrokeCap: LinearStrokeCap.butt, - // progressColor: Theme.of(context).primaryColor, - backgroundColor: Color.fromRGBO(232, 232, 232, 1), - barRadius: Radius.circular(10.r), - ), - ), - SizedBox(width: 7.w), - quickText('${getDoubleRemoveZero(task.progressPercentage)}%', - size: 10.sp, color: Color.fromRGBO(70, 70, 70, 1)) - ], + Container( + padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 5.h), + alignment: Alignment.centerLeft, + decoration: BoxDecoration( + border: Border(bottom: BorderSide(color: Color.fromRGBO(238, 238, 238, 1), width: 0.5.r)), ), + child: quickText(task.className, color: Color.fromRGBO(104, 136, 253, 1), size: 14.sp), ), + SizedBox(height: 4.h), if (task.isFinish) $CompletedHomeworkProgressBar( color: Color.fromRGBO(76, 199, 147, 1), @@ -766,6 +755,73 @@ class MobileEndCompleted extends StatelessWidget { marginEdg: EdgeInsets.only(top: 8.h), ), SizedBox(height: 13.h), + Padding( + padding: padingEdg, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + flex: 3, + child: Material( + color: Color.fromRGBO(104, 136, 253, 1), + borderRadius: BorderRadius.circular(16.r), + child: InkWell( + onTap: () => + easyThrottle('OneClickReview', () => showStudentList([task.id], task.className)), + borderRadius: BorderRadius.circular(8.r), + child: Container( + alignment: Alignment.center, + padding: EdgeInsets.symmetric(vertical: 5.h), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(20.r), + ), + child: quickText('已提交:${task.commitStudentCount}', size: 10.sp, color: Colors.white), + ), + ), + ), + ), + Expanded(flex: 1, child: SizedBox()), + Expanded( + flex: 3, + child: Material( + color: Color.fromRGBO(244, 244, 244, 1), + borderRadius: BorderRadius.circular(20.r), + child: InkWell( + onTap: () => + easyThrottle('OneClickReview', () => showStudentList([task.id], task.className, false)), + borderRadius: BorderRadius.circular(8.r), + child: Container( + alignment: Alignment.center, + padding: EdgeInsets.symmetric(vertical: 5.h), + decoration: BoxDecoration(borderRadius: BorderRadius.circular(20.r)), + child: quickText('未提交:${task.totalCount - task.commitStudentCount}', + size: 10.sp, color: Color.fromRGBO(102, 102, 102, 1)), + ), + ), + ), + ), + Expanded(flex: 1, child: SizedBox()), + Expanded( + flex: 3, + child: Material( + color: Color.fromRGBO(244, 244, 244, 1), + borderRadius: BorderRadius.circular(20.r), + child: InkWell( + onTap: () async {}, + borderRadius: BorderRadius.circular(8.r), + child: Container( + alignment: Alignment.center, + padding: EdgeInsets.symmetric(vertical: 5.h), + decoration: BoxDecoration(borderRadius: BorderRadius.circular(20.r)), + child: quickText('收藏夹(${task.collectNumber})', + size: 10.sp, color: Color.fromRGBO(102, 102, 102, 1)), + ), + ), + )), + ], + ), + ), + SizedBox(height: 13.h), Container( decoration: BoxDecoration( borderRadius: BorderRadius.only( @@ -794,7 +850,7 @@ class MobileEndCompleted extends StatelessWidget { ), ), ), - Container(width: 1.w, height: 32.h, color: Color.fromRGBO(221, 221, 221, 1)), + Container(width: 1.w, height: 34.h, color: Color.fromRGBO(221, 221, 221, 1)), Expanded( child: InkWell( onTap: () => easyThrottle('go_to_end_review_homework', () => jobViewReport(task)), @@ -938,7 +994,8 @@ Widget $itemDataViewOfPad( alignment: Alignment.center, padding: EdgeInsets.symmetric(vertical: 3.h), decoration: BoxDecoration(borderRadius: BorderRadius.circular(20.r)), - child: quickText('收藏夹(2)', size: 8.sp, color: Color.fromRGBO(102, 102, 102, 1)), + child: quickText('收藏夹(${task.collectNumber})', + size: 8.sp, color: Color.fromRGBO(102, 102, 102, 1)), ), ), )), @@ -974,7 +1031,7 @@ Widget $itemDataViewOfPad( color: Color.fromRGBO(244, 244, 244, 1), borderRadius: BorderRadius.circular(20.r), child: InkWell( - onTap: () async {}, + onTap: () => quickDataCheck(task), borderRadius: BorderRadius.circular(8.r), child: Container( alignment: Alignment.center, @@ -998,7 +1055,8 @@ Widget $itemDataViewOfPad( alignment: Alignment.center, padding: EdgeInsets.symmetric(vertical: 3.h), decoration: BoxDecoration(borderRadius: BorderRadius.circular(20.r)), - child: quickText('收藏夹(2)', size: 8.sp, color: Color.fromRGBO(102, 102, 102, 1)), + child: quickText('收藏夹(${task.collectNumber})', + size: 8.sp, color: Color.fromRGBO(102, 102, 102, 1)), ), ), )), @@ -1188,7 +1246,8 @@ Widget $itemDataView( alignment: Alignment.center, padding: EdgeInsets.symmetric(vertical: 5.h), decoration: BoxDecoration(borderRadius: BorderRadius.circular(20.r)), - child: quickText('收藏夹(2)', size: 10.sp, color: Color.fromRGBO(102, 102, 102, 1)), + child: quickText('收藏夹(${task.collectNumber})', + size: 10.sp, color: Color.fromRGBO(102, 102, 102, 1)), ), ), )), @@ -1224,7 +1283,7 @@ Widget $itemDataView( color: Color.fromRGBO(244, 244, 244, 1), borderRadius: BorderRadius.circular(20.r), child: InkWell( - onTap: () async {}, + onTap: () => quickDataCheck(task), borderRadius: BorderRadius.circular(8.r), child: Container( alignment: Alignment.center, @@ -1248,7 +1307,8 @@ Widget $itemDataView( alignment: Alignment.center, padding: EdgeInsets.symmetric(vertical: 5.h), decoration: BoxDecoration(borderRadius: BorderRadius.circular(20.r)), - child: quickText('收藏夹(2)', size: 10.sp, color: Color.fromRGBO(102, 102, 102, 1)), + child: quickText('收藏夹(${task.collectNumber})', + size: 10.sp, color: Color.fromRGBO(102, 102, 102, 1)), ), ), )), @@ -1477,7 +1537,7 @@ typedef Bookmarks = void Function(MarkingTasks); typedef JobViewReport = void Function(MarkingTasks); /// 展示学生名单 -typedef ShowStudentList = void Function([bool submitted]); +typedef ShowStudentList = void Function(List taskIds, [String? className, bool submitted]); /// 查看学生名单 // void showStudentList([bool submitted = false]) { diff --git a/marking_app/lib/utils/request/rest_client.dart b/marking_app/lib/utils/request/rest_client.dart index 6aca9ec..9e6394b 100644 --- a/marking_app/lib/utils/request/rest_client.dart +++ b/marking_app/lib/utils/request/rest_client.dart @@ -17,6 +17,7 @@ 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_favorite_model.dart'; import 'package:marking_app/common/model/job/job_note_taking_trajectory.dart'; import 'package:marking_app/common/model/job/job_page_tab.dart'; import 'package:marking_app/common/model/job/job_report_join_class.dart'; @@ -292,12 +293,16 @@ abstract class RestClient { Future>> getJobListParticipateInClass( @the_retrofit.Query("markingId") int jobId); + // 作业 => 收藏列表 + @the_retrofit.GET("${RequestConfig.hwProxyKeywords}/dpc-api/api/read/job-favorite-count-by-class") + Future>> getListOfJobFavorites(@the_retrofit.Query("jobid") int jobId); + // 作业 => 数据快查 @the_retrofit.GET("/api/read/job-data-center-report") - Future> getJobDataCenterReport(@the_retrofit.Queries() Map params); + Future> getJobDataCenterReport( + @the_retrofit.Queries() Map params); // 作业 => 数据快查--个人 @the_retrofit.GET("/api/read/job-data-center-student-report") Future> getJobPersonalReport(@the_retrofit.Queries() Map params); } - -- 2.40.1 From 0143dc0da7239ba06853bc58027852633bd5f133 Mon Sep 17 00:00:00 2001 From: "1147192855@qq.com" <1147192855@qq.com> Date: Mon, 11 Mar 2024 17:19:39 +0800 Subject: [PATCH 12/22] no message --- .../pages/job_list_participate_in_class.dart | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/marking_app/lib/pages/homework_correction/pages/job_list_participate_in_class.dart b/marking_app/lib/pages/homework_correction/pages/job_list_participate_in_class.dart index bf0e50a..2c452bd 100644 --- a/marking_app/lib/pages/homework_correction/pages/job_list_participate_in_class.dart +++ b/marking_app/lib/pages/homework_correction/pages/job_list_participate_in_class.dart @@ -279,11 +279,12 @@ class _JobListParticipateInClassState extends State w // 查看作业报告 void jobViewReport(MarkingTasks task) { - // RouterManager.router.navigateTo( - // context, - // RouterManager.jobReportPagePath + '?title=${Uri.encodeComponent(task.title)}&id=${task.id}', - // transition: getTransition(), - // ); + RouterManager.router.navigateTo( + context, + RouterManager.jobReportPagePath + + '?uniqueId=${task.id}&title=${Uri.encodeComponent(widget.jobName)}&id=${widget.jobId}', + transition: getTransition(), + ); } /// 查看学生名单 -- 2.40.1 From ea5a73d9a149e19ee596f0879a9d6889026c9de5 Mon Sep 17 00:00:00 2001 From: machuanyu <840649825@qq.com> Date: Mon, 11 Mar 2024 17:46:25 +0800 Subject: [PATCH 13/22] =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E5=85=A5=E5=8F=82?= =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../homework_correction/job_priority_review_set.dart | 10 +++++----- .../lib/pages/homework_correction/job_report.dart | 6 ++++-- .../pages/homework_correction/job_student_group.dart | 9 +++++---- marking_app/lib/routes/RouterManager.dart | 6 ++++-- 4 files changed, 18 insertions(+), 13 deletions(-) diff --git a/marking_app/lib/pages/homework_correction/job_priority_review_set.dart b/marking_app/lib/pages/homework_correction/job_priority_review_set.dart index 29874ba..96a7b5e 100644 --- a/marking_app/lib/pages/homework_correction/job_priority_review_set.dart +++ b/marking_app/lib/pages/homework_correction/job_priority_review_set.dart @@ -45,9 +45,9 @@ class _JobPriorityReviewSetState extends State }else{ levelList = []; } - EasyLoading.dismiss(); }); - + EasyLoading.dismiss(); + refreshController.finishRefresh(); } void setJobReadLevel(int studentId,int level) async{ @@ -131,12 +131,12 @@ class _JobPriorityReviewSetState extends State child: EasyRefresh( firstRefresh: true, taskIndependence: true, - enableControlFinishLoad: true, - enableControlFinishRefresh: true, - // emptyWidget: data.isEmpty ? const MyEmptyWidget() : null, controller: refreshController, header: MaterialHeader(), footer: TaurusFooter(), + onRefresh: () async{ + getReadLevel(); + }, child: levelList.length>0?isPadFlag?GridView(gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 2, mainAxisSpacing: 10.r, diff --git a/marking_app/lib/pages/homework_correction/job_report.dart b/marking_app/lib/pages/homework_correction/job_report.dart index 7600cdd..100c2cb 100644 --- a/marking_app/lib/pages/homework_correction/job_report.dart +++ b/marking_app/lib/pages/homework_correction/job_report.dart @@ -23,10 +23,12 @@ part 'job_report.g.dart'; /// 作业报告 class JobReport extends StatefulWidget { final int id; - final String uniqueId; + final int? schoolId; + final int? gradeId; + final String? className; final String title; - const JobReport({required this.id, required this.title,required this.uniqueId, super.key}); + const JobReport({required this.id, required this.title,this.schoolId,this.gradeId,this.className, super.key}); @override State createState() => _JobReportState(); diff --git a/marking_app/lib/pages/homework_correction/job_student_group.dart b/marking_app/lib/pages/homework_correction/job_student_group.dart index 4337ee4..3cc6bb4 100644 --- a/marking_app/lib/pages/homework_correction/job_student_group.dart +++ b/marking_app/lib/pages/homework_correction/job_student_group.dart @@ -53,6 +53,7 @@ class _JobStudentGroupState extends State with CommonMixin { } }); + refreshController.finishRefresh(); } @override @@ -81,14 +82,14 @@ class _JobStudentGroupState extends State with CommonMixin { body: Padding( padding: EdgeInsets.only(top: 15.r, left: 14.r, right: 14.r), child: EasyRefresh( - firstRefresh: true, + firstRefresh: false, taskIndependence: true, - enableControlFinishLoad: true, - enableControlFinishRefresh: true, - // emptyWidget: data.isEmpty ? const MyEmptyWidget() : null, controller: refreshController, header: MaterialHeader(), footer: TaurusFooter(), + onRefresh: () async{ + getStudentGroups(); + }, child: studentGroups != null && studentGroups.length > 0 ? isPadFlag?GridView( gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( diff --git a/marking_app/lib/routes/RouterManager.dart b/marking_app/lib/routes/RouterManager.dart index 31e0d05..b1f0997 100644 --- a/marking_app/lib/routes/RouterManager.dart +++ b/marking_app/lib/routes/RouterManager.dart @@ -184,8 +184,10 @@ class RouterManager { static final _jobReportPageHandler = Handler(handlerFunc: (BuildContext? context, Map> params) { int id = int.parse(params['id']![0]); String title = params['title']![0]; - String uniqueId = params['uniqueId']![0]; - return JobReport(id: id, title: title,uniqueId:uniqueId); + int schoolId = int.parse(params['schoolId']![0]); + int gradeId = int.parse(params['gradeId']![0]); + String className = params['className']![0]; + return JobReport(id: id, title: title,schoolId:schoolId,gradeId:gradeId,className:className); }); // 作业报告页面 -- 2.40.1 From 8ef26ca79353583dcf9aaf911787ee3658ddd9ac Mon Sep 17 00:00:00 2001 From: machuanyu <840649825@qq.com> Date: Mon, 11 Mar 2024 18:03:31 +0800 Subject: [PATCH 14/22] =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E5=85=A5=E5=8F=82?= =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- marking_app/lib/routes/RouterManager.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/marking_app/lib/routes/RouterManager.dart b/marking_app/lib/routes/RouterManager.dart index b1f0997..e46123c 100644 --- a/marking_app/lib/routes/RouterManager.dart +++ b/marking_app/lib/routes/RouterManager.dart @@ -184,9 +184,9 @@ class RouterManager { static final _jobReportPageHandler = Handler(handlerFunc: (BuildContext? context, Map> params) { int id = int.parse(params['id']![0]); String title = params['title']![0]; - int schoolId = int.parse(params['schoolId']![0]); - int gradeId = int.parse(params['gradeId']![0]); - String className = params['className']![0]; + int? schoolId = int.parse(params['schoolId']![0]); + int? gradeId = int.parse(params['gradeId']![0]); + String? className = params['className']![0]; return JobReport(id: id, title: title,schoolId:schoolId,gradeId:gradeId,className:className); }); -- 2.40.1 From 3293de18144251c573aa3f4274f6c793b645321f Mon Sep 17 00:00:00 2001 From: "1147192855@qq.com" <1147192855@qq.com> Date: Mon, 11 Mar 2024 18:03:46 +0800 Subject: [PATCH 15/22] no message --- .gitignore | 3 +++ .../pages/job_list_participate_in_class.dart | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index b395556..400c574 100644 --- a/.gitignore +++ b/.gitignore @@ -202,3 +202,6 @@ marking_app/lib/common/model/job/job_do_marking_status_info.g.dart marking_app/lib/common/model/report/small_question.g.dart marking_app/lib/pages/homework_correction/pages/job_list_participate_in_class.g.dart marking_app/lib/common/model/job/job_favorite_model.g.dart +marking_app/lib/common/model/job/job_level_set_params.g.dart +marking_app/lib/common/model/job/job_student_goups.g.dart +marking_app/lib/common/model/job/job_student_level.g.dart diff --git a/marking_app/lib/pages/homework_correction/pages/job_list_participate_in_class.dart b/marking_app/lib/pages/homework_correction/pages/job_list_participate_in_class.dart index 2c452bd..0cda13f 100644 --- a/marking_app/lib/pages/homework_correction/pages/job_list_participate_in_class.dart +++ b/marking_app/lib/pages/homework_correction/pages/job_list_participate_in_class.dart @@ -282,7 +282,7 @@ class _JobListParticipateInClassState extends State w RouterManager.router.navigateTo( context, RouterManager.jobReportPagePath + - '?uniqueId=${task.id}&title=${Uri.encodeComponent(widget.jobName)}&id=${widget.jobId}', + '?uniqueId=${task.id}&title=${Uri.encodeComponent(widget.jobName)}&id=${widget.jobId}&schoolId=${task.dpcSchoolId}&gradeId=${task.dpcGradeId}&className=${task.className}', transition: getTransition(), ); } -- 2.40.1 From 314638a3aeb85e96a16e1b4ddb8013200d97284e Mon Sep 17 00:00:00 2001 From: machuanyu <840649825@qq.com> Date: Mon, 11 Mar 2024 18:14:15 +0800 Subject: [PATCH 16/22] =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E5=85=A5=E5=8F=82?= =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- marking_app/lib/routes/RouterManager.dart | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/marking_app/lib/routes/RouterManager.dart b/marking_app/lib/routes/RouterManager.dart index e46123c..b5bcd33 100644 --- a/marking_app/lib/routes/RouterManager.dart +++ b/marking_app/lib/routes/RouterManager.dart @@ -184,9 +184,15 @@ class RouterManager { static final _jobReportPageHandler = Handler(handlerFunc: (BuildContext? context, Map> params) { int id = int.parse(params['id']![0]); String title = params['title']![0]; - int? schoolId = int.parse(params['schoolId']![0]); - int? gradeId = int.parse(params['gradeId']![0]); - String? className = params['className']![0]; + int? schoolId; + if (params['schoolId'] != null && params['schoolId']![0] != null && params['schoolId']![0] != 'null') { + schoolId = int.parse(params['schoolId']![0]); + } + int? gradeId; + if (params['gradeId'] != null && params['gradeId']![0] != null && params['gradeId']![0] != 'null') { + gradeId = int.parse(params['gradeId']![0]); + } + String? className = params['className']?[0]; return JobReport(id: id, title: title,schoolId:schoolId,gradeId:gradeId,className:className); }); -- 2.40.1 From e4c889fc6deb2ac88a644eb6aa1327e02848a89d Mon Sep 17 00:00:00 2001 From: "1147192855@qq.com" <1147192855@qq.com> Date: Tue, 12 Mar 2024 13:48:45 +0800 Subject: [PATCH 17/22] no message --- .gitignore | 1 + .../model/job/job_favorite_item_model.dart | 25 +++++ .../pages/job_favorite.dart | 105 ++++++++++++++++++ .../pages/job_list_participate_in_class.dart | 4 +- .../lib/utils/request/rest_client.dart | 22 +++- 5 files changed, 151 insertions(+), 6 deletions(-) create mode 100644 marking_app/lib/common/model/job/job_favorite_item_model.dart create mode 100644 marking_app/lib/pages/homework_correction/pages/job_favorite.dart diff --git a/.gitignore b/.gitignore index 400c574..fe2d429 100644 --- a/.gitignore +++ b/.gitignore @@ -205,3 +205,4 @@ marking_app/lib/common/model/job/job_favorite_model.g.dart marking_app/lib/common/model/job/job_level_set_params.g.dart marking_app/lib/common/model/job/job_student_goups.g.dart marking_app/lib/common/model/job/job_student_level.g.dart +marking_app/lib/common/model/job/job_favorite_item_model.g.dart diff --git a/marking_app/lib/common/model/job/job_favorite_item_model.dart b/marking_app/lib/common/model/job/job_favorite_item_model.dart new file mode 100644 index 0000000..ee9e4ec --- /dev/null +++ b/marking_app/lib/common/model/job/job_favorite_item_model.dart @@ -0,0 +1,25 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'job_favorite_item_model.g.dart'; + +@JsonSerializable() +class JobFavoriteItemModel extends Object { + @JsonKey(name: 'studentId') + int studentId; + + @JsonKey(name: 'studentName') + String studentName; + + @JsonKey(name: 'createTime') + String createTime; + + JobFavoriteItemModel( + this.studentId, + this.studentName, + this.createTime, + ); + + factory JobFavoriteItemModel.fromJson(Map srcJson) => _$JobFavoriteItemModelFromJson(srcJson); + + Map toJson() => _$JobFavoriteItemModelToJson(this); +} diff --git a/marking_app/lib/pages/homework_correction/pages/job_favorite.dart b/marking_app/lib/pages/homework_correction/pages/job_favorite.dart new file mode 100644 index 0000000..62c6346 --- /dev/null +++ b/marking_app/lib/pages/homework_correction/pages/job_favorite.dart @@ -0,0 +1,105 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:marking_app/common/mixin/common.dart'; +import 'package:marking_app/common/model/job/job_favorite_item_model.dart'; +import 'package:marking_app/utils/index.dart'; +import 'package:marking_app/utils/my_text.dart'; + +/// 作业收藏学生名单列表 +class JobFavorite extends StatefulWidget { + final int jobId; + final int schoolId; + final int gradeId; + final String className; + + const JobFavorite({ + required this.jobId, + required this.schoolId, + required this.gradeId, + required this.className, + super.key, + }); + + @override + State createState() => _JobFavoriteState(); +} + +class _JobFavoriteState extends State with CommonMixin { + late Future?> _future; + + @override + void initState() { + super.initState(); + _future = getData(); + } + + Future?> getData() async { + var _client = await getClient(); + var result = await _client.getListOfJobFavorites(widget.jobId, widget.gradeId, widget.schoolId, widget.className); + return result.data; + } + + Future toGoCancelFavorite(int jobId, int studentId) async { + var _client = await getClient(); + var result = await _client.toJobCancelFavorite(jobId, studentId); + if (result.success && (result.data ?? false)) { + _future = getData(); + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + // titleSpacing: 0, + leading: IconButton(icon: Icon(Icons.arrow_back_ios), onPressed: () => Navigator.of(context).pop()), + iconTheme: IconThemeData(color: Colors.black), + title: quickText('收藏夹'), + backgroundColor: Colors.white, + ), + body: MyFutureBuilder.buildFutureBuilderOfSingleInstance>( + context, + _future, + (List? datas) { + if (datas == null) + return Container( + child: Center( + child: quickText('请求错误'), + ), + ); + return Container( + child: Column( + children: [ + Container(child: quickText(widget.className)), + Expanded( + child: ListView.builder( + itemBuilder: (context, index) { + JobFavoriteItemModel item = datas[index]; + return Container( + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + quickText(item.studentName, color: Color.fromRGBO(102, 102, 102, 1), size: 14.sp), + quickText('收藏时间:${item.createTime}', color: Color.fromRGBO(137, 137, 137, 1), size: 10.sp), + InkWell( + onTap: () async {}, + child: Icon( + Icons.favorite, + size: 28.sp, + color: Color.fromRGBO(252, 108, 108, 1), + ), + ), + ], + ), + ); + }, + itemCount: datas.length, + ), + ), + ], + )); + }, + ), + ); + } +} diff --git a/marking_app/lib/pages/homework_correction/pages/job_list_participate_in_class.dart b/marking_app/lib/pages/homework_correction/pages/job_list_participate_in_class.dart index 0cda13f..8889437 100644 --- a/marking_app/lib/pages/homework_correction/pages/job_list_participate_in_class.dart +++ b/marking_app/lib/pages/homework_correction/pages/job_list_participate_in_class.dart @@ -54,7 +54,7 @@ class _JobListParticipateInClassState extends State w Future getListOfJobFavoritesData() async { RestClient _client = await getClient(); - BaseStructureResult> result = await _client.getListOfJobFavorites(widget.jobId); + BaseStructureResult> result = await _client.getListOfJobFavoriteNumber(widget.jobId); if (result.success) { result.data?.forEach((e) { favoriteMap['${e.schoolId}+${e.gradeId}+${e.className}'] = e.count; @@ -814,7 +814,7 @@ class MobileEndCompleted extends StatelessWidget { alignment: Alignment.center, padding: EdgeInsets.symmetric(vertical: 5.h), decoration: BoxDecoration(borderRadius: BorderRadius.circular(20.r)), - child: quickText('收藏夹(${task.collectNumber})', + child: quickText(task.collectNumber > 0 ? '收藏夹(${task.collectNumber})' : '收藏夹', size: 10.sp, color: Color.fromRGBO(102, 102, 102, 1)), ), ), diff --git a/marking_app/lib/utils/request/rest_client.dart b/marking_app/lib/utils/request/rest_client.dart index d3aee22..e220520 100644 --- a/marking_app/lib/utils/request/rest_client.dart +++ b/marking_app/lib/utils/request/rest_client.dart @@ -17,6 +17,7 @@ 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_favorite_item_model.dart'; import 'package:marking_app/common/model/job/job_favorite_model.dart'; import 'package:marking_app/common/model/job/job_level_set_params.dart'; import 'package:marking_app/common/model/job/job_note_taking_trajectory.dart'; @@ -296,9 +297,24 @@ abstract class RestClient { Future>> getJobListParticipateInClass( @the_retrofit.Query("markingId") int jobId); - // 作业 => 收藏列表 + // 作业 => 作业收藏数量 @the_retrofit.GET("${RequestConfig.hwProxyKeywords}/dpc-api/api/read/job-favorite-count-by-class") - Future>> getListOfJobFavorites(@the_retrofit.Query("jobid") int jobId); + Future>> getListOfJobFavoriteNumber( + @the_retrofit.Query("jobid") int jobId); + + // 作业 => 作业收藏列表 + @the_retrofit.GET("${RequestConfig.hwProxyKeywords}/dpc-api/api/read/job-favorites") + Future>> getListOfJobFavorites( + @the_retrofit.Query("jobid") int jobId, + @the_retrofit.Query("gradeId") int gradeId, + @the_retrofit.Query("schoolId") int schoolId, + @the_retrofit.Query("className") String className, + ); + + // 作业 => 作业收藏列表 + @the_retrofit.POST("${RequestConfig.hwProxyKeywords}/dpc-api/api/read/cancel-favorite") + Future> toJobCancelFavorite( + @the_retrofit.Field() int jobId, @the_retrofit.Field() int studentId); // 作业 => 数据快查 @the_retrofit.GET("/api/read/job-data-center-report") @@ -322,6 +338,4 @@ abstract class RestClient { // 作业 => 取消/设置优先 @the_retrofit.POST("/api/read/jc-job-read-level") Future getSetJobReadLevel(@the_retrofit.Body() JobLevelSetParams params); - - } -- 2.40.1 From 8130e8250a24c90e7a3bd1570443010c86ccc514 Mon Sep 17 00:00:00 2001 From: "1147192855@qq.com" <1147192855@qq.com> Date: Tue, 12 Mar 2024 13:51:46 +0800 Subject: [PATCH 18/22] no message --- .../pages/job_list_participate_in_class.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/marking_app/lib/pages/homework_correction/pages/job_list_participate_in_class.dart b/marking_app/lib/pages/homework_correction/pages/job_list_participate_in_class.dart index 8889437..f8eb5c2 100644 --- a/marking_app/lib/pages/homework_correction/pages/job_list_participate_in_class.dart +++ b/marking_app/lib/pages/homework_correction/pages/job_list_participate_in_class.dart @@ -279,10 +279,11 @@ class _JobListParticipateInClassState extends State w // 查看作业报告 void jobViewReport(MarkingTasks task) { + print('这个歌.............'); RouterManager.router.navigateTo( context, RouterManager.jobReportPagePath + - '?uniqueId=${task.id}&title=${Uri.encodeComponent(widget.jobName)}&id=${widget.jobId}&schoolId=${task.dpcSchoolId}&gradeId=${task.dpcGradeId}&className=${task.className}', + '?title=${Uri.encodeComponent(widget.jobName)}&id=${widget.jobId}&schoolId=${task.dpcSchoolId}&gradeId=${task.dpcGradeId}&className=${Uri.encodeComponent(task.className)}', transition: getTransition(), ); } -- 2.40.1 From 57642af8059b2015cb00235e3d3f1ab16a2d6b71 Mon Sep 17 00:00:00 2001 From: "1147192855@qq.com" <1147192855@qq.com> Date: Tue, 12 Mar 2024 14:08:07 +0800 Subject: [PATCH 19/22] no message --- .../pages/job_list_participate_in_class.dart | 22 ++++++++++------ marking_app/lib/routes/RouterManager.dart | 26 ++++++++++++++----- 2 files changed, 34 insertions(+), 14 deletions(-) diff --git a/marking_app/lib/pages/homework_correction/pages/job_list_participate_in_class.dart b/marking_app/lib/pages/homework_correction/pages/job_list_participate_in_class.dart index f8eb5c2..682db5a 100644 --- a/marking_app/lib/pages/homework_correction/pages/job_list_participate_in_class.dart +++ b/marking_app/lib/pages/homework_correction/pages/job_list_participate_in_class.dart @@ -266,7 +266,14 @@ class _JobListParticipateInClassState extends State w } // 收藏夹 - void bookmarks(MarkingTasks task) {} + void bookmarks(MarkingTasks task) { + RouterManager.router.navigateTo( + context, + RouterManager.jobFavoritePagePath + + '?className=${Uri.encodeComponent(task.className)}&jobId=${widget.jobId}&schoolId=${task.dpcSchoolId}&gradeId=${task.dpcGradeId}', + transition: getTransition(), + ); + } // 数据快查 void quickDataCheck(MarkingTasks task) { @@ -279,7 +286,6 @@ class _JobListParticipateInClassState extends State w // 查看作业报告 void jobViewReport(MarkingTasks task) { - print('这个歌.............'); RouterManager.router.navigateTo( context, RouterManager.jobReportPagePath + @@ -622,7 +628,7 @@ class TabletEndCompleted extends StatelessWidget { color: Color.fromRGBO(244, 244, 244, 1), borderRadius: BorderRadius.circular(20.r), child: InkWell( - onTap: () async {}, + onTap: () => bookmarks(taskItem), borderRadius: BorderRadius.circular(8.r), child: Container( alignment: Alignment.center, @@ -809,7 +815,7 @@ class MobileEndCompleted extends StatelessWidget { color: Color.fromRGBO(244, 244, 244, 1), borderRadius: BorderRadius.circular(20.r), child: InkWell( - onTap: () async {}, + onTap: () => bookmarks(task), borderRadius: BorderRadius.circular(8.r), child: Container( alignment: Alignment.center, @@ -990,7 +996,7 @@ Widget $itemDataViewOfPad( color: Color.fromRGBO(244, 244, 244, 1), borderRadius: BorderRadius.circular(20.r), child: InkWell( - onTap: () async {}, + onTap: () => bookmarks(task), borderRadius: BorderRadius.circular(8.r), child: Container( alignment: Alignment.center, @@ -1051,7 +1057,7 @@ Widget $itemDataViewOfPad( color: Color.fromRGBO(244, 244, 244, 1), borderRadius: BorderRadius.circular(20.r), child: InkWell( - onTap: () async {}, + onTap: () => bookmarks(task), borderRadius: BorderRadius.circular(8.r), child: Container( alignment: Alignment.center, @@ -1242,7 +1248,7 @@ Widget $itemDataView( color: Color.fromRGBO(244, 244, 244, 1), borderRadius: BorderRadius.circular(20.r), child: InkWell( - onTap: () async {}, + onTap: () => bookmarks(task), borderRadius: BorderRadius.circular(8.r), child: Container( alignment: Alignment.center, @@ -1303,7 +1309,7 @@ Widget $itemDataView( color: Color.fromRGBO(244, 244, 244, 1), borderRadius: BorderRadius.circular(20.r), child: InkWell( - onTap: () async {}, + onTap: () => bookmarks(task), borderRadius: BorderRadius.circular(8.r), child: Container( alignment: Alignment.center, diff --git a/marking_app/lib/routes/RouterManager.dart b/marking_app/lib/routes/RouterManager.dart index b5bcd33..31d5cc0 100644 --- a/marking_app/lib/routes/RouterManager.dart +++ b/marking_app/lib/routes/RouterManager.dart @@ -17,6 +17,7 @@ import 'package:marking_app/pages/homework_correction/do_papers_job_exam.dart'; import 'package:marking_app/pages/homework_correction/job_priority_review_set.dart'; import 'package:marking_app/pages/homework_correction/job_report.dart'; import 'package:marking_app/pages/homework_correction/job_student_group.dart'; +import 'package:marking_app/pages/homework_correction/pages/job_favorite.dart'; import 'package:marking_app/pages/homework_correction/pages/job_list_participate_in_class.dart'; import 'package:marking_app/pages/homework_correction/review_job.dart'; import 'package:marking_app/pages/homework_correction/quick_check_personal.dart'; @@ -59,6 +60,8 @@ class RouterManager { static const String jobExamPagePath = '/job/exam/index'; // 作业 ==> 列表 ==> 参与班级 static const String jobListParticipateInClassPath = '/job/list/participateInClass'; + // 作业 ==> 收藏页面 + static const String jobFavoritePagePath = '/job/favorite/index'; static const String reportClassTeacherPath = 'report/details/reportClassTeacher'; static const String reportSubjectTeacherPath = 'report/details/reportSubjectTeacher'; @@ -193,7 +196,7 @@ class RouterManager { gradeId = int.parse(params['gradeId']![0]); } String? className = params['className']?[0]; - return JobReport(id: id, title: title,schoolId:schoolId,gradeId:gradeId,className:className); + return JobReport(id: id, title: title, schoolId: schoolId, gradeId: gradeId, className: className); }); // 作业报告页面 @@ -290,19 +293,28 @@ class RouterManager { //优先配置 static final _jobPriorityReviewSetPageHandler = Handler( - handlerFunc: (BuildContext? context, Map> params){ + handlerFunc: (BuildContext? context, Map> params) { String groupId = params['groupId']![0]; - return JobPriorityReviewSet(groupId:groupId); + return JobPriorityReviewSet(groupId: groupId); }, ); //学生分组 static final _jobStudentGroupPageHandler = Handler( - handlerFunc: (BuildContext? context, Map> params){ + handlerFunc: (BuildContext? context, Map> params) { return JobStudentGroup(); }, ); - + //作业收藏页面 + static final _jobFavoritePagePathHandler = Handler( + handlerFunc: (BuildContext? context, Map> params) { + int jobId = int.parse(params['jobId']![0]); + int gradeId = int.parse(params['gradeId']![0]); + int schoolId = int.parse(params['schoolId']![0]); + String className = params['className']![0]; + return JobFavorite(jobId: jobId, gradeId: gradeId, schoolId: schoolId, className: className); + }, + ); // 开始阅卷页面 // static final _doMarkingPapers = Handler(handlerFunc: (BuildContext? context, Map> params) => MarkingPapers()); @@ -343,8 +355,10 @@ class RouterManager { 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(jobPriorityReviewSetPath, + handler: _jobPriorityReviewSetPageHandler, transitionType: TransitionType.material); router.define(jobStudentGroupPath, handler: _jobStudentGroupPageHandler, transitionType: TransitionType.material); + router.define(jobFavoritePagePath, handler: _jobFavoritePagePathHandler, transitionType: TransitionType.material); // getTransition() -- 2.40.1 From c22e4f95bff51b20095e4764915d82e590ea7d23 Mon Sep 17 00:00:00 2001 From: machuanyu <840649825@qq.com> Date: Tue, 12 Mar 2024 14:08:59 +0800 Subject: [PATCH 20/22] =?UTF-8?q?=E6=9A=82=E6=97=A0=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../job_student_group.dart | 5 ++++- .../homework_correction/quick_data_check.dart | 19 ++++++++++++------- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/marking_app/lib/pages/homework_correction/job_student_group.dart b/marking_app/lib/pages/homework_correction/job_student_group.dart index 3cc6bb4..578675d 100644 --- a/marking_app/lib/pages/homework_correction/job_student_group.dart +++ b/marking_app/lib/pages/homework_correction/job_student_group.dart @@ -216,7 +216,10 @@ class _JobStudentGroupState extends State with CommonMixin { }, itemCount: studentGroups.length, ) - : MyEmptyWidget(), + : Padding( + padding: EdgeInsets.only(top: MediaQuery.of(context).size.height/2 - 200.r), + child: MyEmptyWidget(), + ), ), ), ); diff --git a/marking_app/lib/pages/homework_correction/quick_data_check.dart b/marking_app/lib/pages/homework_correction/quick_data_check.dart index d36e023..d9eb4fe 100644 --- a/marking_app/lib/pages/homework_correction/quick_data_check.dart +++ b/marking_app/lib/pages/homework_correction/quick_data_check.dart @@ -9,6 +9,7 @@ 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/easy_refresh/MyEmptyWidget.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'; @@ -40,17 +41,17 @@ class _QuickDataCheckPageState extends State with CommonMixi BaseStructureResult data = await _client.getJobDataCenterReport(params); EasyLoading.dismiss(); - setState(() { - jobData = data.data; - }); + if(data.code == 200){ + setState(() { + jobData = data.data; + }); + } + } @override Widget build(BuildContext context) { - if (jobData == null) { - return Container(); - } return AnnotatedRegion( value: const SystemUiOverlayStyle( statusBarColor: Colors.transparent, @@ -90,6 +91,7 @@ class _QuickDataCheckPageState extends State with CommonMixi ], ), SizedBox(height:10.r), + jobData != null? Expanded(child: SingleChildScrollView( child: Column( children: [ @@ -320,7 +322,10 @@ class _QuickDataCheckPageState extends State with CommonMixi ), ], ), - )) + )):Padding( + padding: EdgeInsets.only(top: MediaQuery.of(context).size.height/2 - 200.r), + child: MyEmptyWidget(), + ) ], ), ), -- 2.40.1 From c653b10515f5dbf74349638232fd0694eb31fc0c Mon Sep 17 00:00:00 2001 From: machuanyu <840649825@qq.com> Date: Wed, 13 Mar 2024 15:00:33 +0800 Subject: [PATCH 21/22] =?UTF-8?q?=E6=94=B6=E8=97=8F=E5=A4=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../assets/images/favorite_delete_icon.png | Bin 0 -> 1768 bytes .../assets/images/favorite_dialog_close.png | Bin 0 -> 1715 bytes .../lib/common/model/job/job_data_report.dart | 4 +- .../lib/common/model/job/job_fav_student.dart | 95 ++++++ .../pages/homework_correction/job_report.dart | 11 +- .../pages/favorite_student_dialog.dart | 105 +++++++ .../pages/job_favorite.dart | 283 ++++++++++++++++-- .../pages/job_list_participate_in_class.dart | 2 +- .../quick_check_personal.dart | 19 +- .../homework_correction/quick_data_check.dart | 4 +- .../widget/quick_student_data_table.dart | 5 +- marking_app/lib/routes/RouterManager.dart | 3 +- .../lib/utils/request/rest_client.dart | 12 +- 13 files changed, 496 insertions(+), 47 deletions(-) create mode 100644 marking_app/assets/images/favorite_delete_icon.png create mode 100644 marking_app/assets/images/favorite_dialog_close.png create mode 100644 marking_app/lib/common/model/job/job_fav_student.dart create mode 100644 marking_app/lib/pages/homework_correction/pages/favorite_student_dialog.dart diff --git a/marking_app/assets/images/favorite_delete_icon.png b/marking_app/assets/images/favorite_delete_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..5704f916371c1a365bddddef7f2da2fd7f600c06 GIT binary patch literal 1768 zcmVP)Mqae5eZ9W;01$iX>a@4dHL+46^MOWKwEvA-E18Cj0~_w(D`w{M>e7$DfISF?~x z&Eg?#(_k31PkS~mw%9CSjP`rDFGH*;g)Do+ICG`| zF`!gnA?z&__BO<4t^Gn)y{cMhWdgJ9?b|5qG7O%uttb^*y1?AWrcxwq4u%U0DwTQT z!UYQ?B28f74wi*G7+x4#L2F(GNk|bG#m(Rwdya=07!9OZvk4JlZ{94RxVtbq;u0B{ zoZRK@NJJtDjBj8W`?LiZ{Dv$HX>@mM{4+)%w2Qz${5!sZJd6X3t)pLFgb;)hc&x;A zVXS~6{{{gGEbv&0>k>lbKt347T^n0*3H>z}(pndmmQ@j>vsCe0{kHG3;Ff zO#=*G8E4NHdp)hEz+wci{WmxBNIN zlUJ|8(VI8Hn3@8GSoq7%8riJv_k^xKSooR@#K4ya58zw5EJa+R^7JX}-@6Bj$?*6~ z7kn*PxQ6!-6MxOm^F3Ky>eMNSLiOD{{zcJi9e?r!lvAzF8|TiII-Q#Ey~qjP#LfhY zdu)9jqVUh+B7B$lYv_p+o-K7c)zL+uYskZB1#eW7^9u}h_QB3fgeC~68IOs#(B>kN zw%+Q;kMOlnfGE^He1HU?2?w&`74LtxHF9xv%UW^$rc4ga%tZF*0kP4NPkOs;O#*Z4 zHH<)GZ9l#gi|}7WON0Ff4p6_8jr{kCXdR zr!Fu$Xg4QJ6OA07Sr;@cm@%o5vL6-}U|2YE?HWjhQo{swAFR4@b4O~ESFXU1OG}Uh z-iGw&=Ss&>wlOz%oDR4J3-^!#jV#ixn{Zr2t(F6gTud{^cl<$1%cqfmVO*x2+sF+> z?}36d6lUx;5+fga@ZyE~R(5ND3iVD~1HNL8A(r z1pWjXRd9j-28}BIB!TxpqYAWOr&@?c1&ozVoZ1+e@+%_;7nllEXw;BOS*DTAlEB(c z$j2sa-GPR-V)^jSgCj6wTcD8(W1F;d^CC*1k&9`T_>TS&3pf(@!-sJun4t8kj^{63 z0`tTPzIB>W=Fbt=`kjvnOSEmC40pzgGSgSXKsmbI@^op{Q2NoMZZ82x^Lf4{3e{*6 zG@@y>+9qh^V455CL-# zmT>OwVV|LRD5x}Um$EWlOUm%ol(vqxFGnO$o*EM-k z7exwBUqz96X7*sO!lDJvplPOuYjEi+b&9u;y6e`!DM{W}orFNOE7{IY0e8c*2w4Tr z9Sr(j*B!h#=y;1<#6~S2$7@`}J1jQEhcM1>zeVd2Q49;yH2pWv=A>$~x3~F1bqN=1j!bq`TFGFn2TPW-b z8cPWzB3)n?QG+eE^0*POgN)3AqD)|y0T$Ysf5a)WZUvU3qFi7XAv6s!XCPU&cw!#T zpsN(tB{qRwM1>U+nrhl)ARcU<8fKcCvVCkXVi(v87n>?x83q+{Bg>X~)6_klBW9YV zxJC7nsKBk%>$lZvvz}Z2X27Wk(CN0npP+FET3f6)X-Zv6n*RX+oS?T{CL?VC0000< KMNUMnLSTYpGC95g literal 0 HcmV?d00001 diff --git a/marking_app/assets/images/favorite_dialog_close.png b/marking_app/assets/images/favorite_dialog_close.png new file mode 100644 index 0000000000000000000000000000000000000000..c25cd269bce7f3659ece28b6f9e2fcea4f442bcc GIT binary patch literal 1715 zcmV;k22A;hP)8@L-J63}&?;KGts(k$@)v-he(q(-lj?mJO*OAhBt> zK_Yzh{LM_{IC0{Sneim?Pcn8wLhz5nnNN>%WDz$vH!Hkzw_GkaC-(Eamz$TC*c#Zs zy}ez$yu8%&`Fvw(X{k<@kfRj2zP_%okdG{}LhoYdNevJW$=_dJUu$U!H!c`bS?K>P zc7xOj9Y%vAyvEz1Y1u{uUtL|z&&?<;To+D*$6WYrQbZyP zovLt zu-6S0EE*B0=Z;-fED7wS)o!;}hc!lqrU=nO%jEh%J(;@(exQqB(CY>Y7P-cuj36A* z{}M=GiV&&ciZX`6V}YNRmzQh(z84t5A~j@$Ky=UcrLSPFHB>1}4N<5Bbqw`Q5!|3a zYH%ncG@@3)m5Or9`+QFXXVDuE)GD}(vnPssA~=iQ`1Fh7t_aSeHyMcHsi~=|_qi^? z+#LQ)n&CeprNP6)16^KTl5W`Hde>ul;F%Yu4V>Wa?k*i2Me2}B4CLEhQZEcOXK|s2})G&GM75tGjGdnv=+uPg5B>UxV zZblxEhy}ackjJiIkscf}fGNpo$pt9vWSVdVb7HQLL3B$_Q?5ihl__GK45Lf34RV1@ zxl*v!+CvbkCEFqwaHGR@nnV8Oa6YFLQ6a`Axe^{$TFrAPJCrg>BiTl|f)%8QRMLZ= zxRNcF3+xdLqDr=0E(*H2ytrJ-8p2ApT`pj^ZUmRfGKNVW1-XKG2(~JMB|(x$NG_^s z^EvKde5p!W->t(jF zBm>I}xfTTfAqxc$sx8Q4+a+^7*cJSnw|~hZ!c@gZMDni>SjYk`4zh$O^<3K}yD0)+ zSTNZ@oJNFKGU~`^oS>0n3H5xTP_Sb8l_V`RycX}ld+{^yvn-*W$2vEZGAf$CHcIB~ z&~S4Dx8_jLrBahn-M1jCaHub*nJ$oeOQq63vZ0Ym6zk}?u_cnZT)V*D70kAOl3{fA zirFBU$Ky`1&x;2&GKh&TM++p^@TF5fGnI!;_vfaRlN-fi(H+R>boOu*pO67ecb2CS z$ylRJ9_Kwzo|0zL>MZw4HZXk^E)V5#R}+rY1TNjGkVbHVCZ>?4_}O(%53BNlzd!gp zX(lbXraqff?Vo$%vs5OLH z{x;OqDJ;K@TtgWyaKTOv!n`)pczv_kJoa8DI*Fj*XSt!T>yA7jVv;3u_g6@j;VRM~*8O#GW6FJTwUfAI>qZT#$HD+6di{Br53i`jYepCQ4@g zWw&_8cT=q_8+ASCOV#So;}tnR$@%B~2ZORQ<*kQtB$P6~y>sp=d%4C8{mK=$+VbA=DFkQ*Xf items; + + @JsonKey(name: 'hasPrevPage') + bool hasPrevPage; + + @JsonKey(name: 'hasNextPage') + bool hasNextPage; + + JobFavStudent(this.page,this.pageSize,this.total,this.totalPages,this.items,this.hasPrevPage,this.hasNextPage,); + + factory JobFavStudent.fromJson(Map srcJson) => _$JobFavStudentFromJson(srcJson); + + Map toJson() => _$JobFavStudentToJson(this); + +} + + +@JsonSerializable() +class Items extends Object { + + @JsonKey(name: 'id') + String id; + + @JsonKey(name: 'teacherId') + int teacherId; + + @JsonKey(name: 'teacherAccount') + String teacherAccount; + + @JsonKey(name: 'folderName') + String folderName; + + @JsonKey(name: 'jobId') + int jobId; + + @JsonKey(name: 'jobName') + String jobName; + + @JsonKey(name: 'studentId') + int studentId; + + @JsonKey(name: 'studentName') + String studentName; + + @JsonKey(name: 'className') + String className; + + @JsonKey(name: 'questionPage') + int questionPage; + + @JsonKey(name: 'questionPicture') + String questionPicture; + + @JsonKey(name: 'createTime') + String createTime; + + @JsonKey(name: 'schoolName') + String schoolName; + + @JsonKey(name: 'gradeName') + String gradeName; + + @JsonKey(name: 'studentClassName') + String studentClassName; + + Items(this.id,this.teacherId,this.teacherAccount,this.folderName,this.jobId,this.jobName,this.studentId,this.studentName,this.className,this.questionPage,this.questionPicture,this.createTime,this.schoolName,this.gradeName,this.studentClassName,); + + factory Items.fromJson(Map srcJson) => _$ItemsFromJson(srcJson); + + Map toJson() => _$ItemsToJson(this); + +} + + diff --git a/marking_app/lib/pages/homework_correction/job_report.dart b/marking_app/lib/pages/homework_correction/job_report.dart index 100c2cb..d9cb865 100644 --- a/marking_app/lib/pages/homework_correction/job_report.dart +++ b/marking_app/lib/pages/homework_correction/job_report.dart @@ -59,8 +59,14 @@ class _JobReportState extends State with CommonMixin { JobReportJoinClass(-1, '全部', -1, '全部', '全部', '全部', -1, -1, '-1'), ...(result.data ?? []) ]; + involveClasses?.forEach((element) { + if(element.className == widget.className && element.gradeId == widget.gradeId && element.schoolId == widget.schoolId){ + classData = element; + } + }); }, mounted); } + _future = getReport(); } catch (e) { print(e); } @@ -71,7 +77,6 @@ class _JobReportState extends State with CommonMixin { RestClient _client = await getClient(); Map param = classData?.toJson() ?? {}; param['jobid'] = widget.id; - print('widget.id=${widget.id}'); BaseStructureResult data = await _client.getJobReport(param); if (!data.success) { @@ -352,7 +357,7 @@ class _JobReportState extends State with CommonMixin { ), //完成率、正确率 TopCount(data), - InkWell( + /* InkWell( onTap: (){ RouterManager.router.navigateTo( context, @@ -362,7 +367,7 @@ class _JobReportState extends State with CommonMixin { ); }, child: Text('数据快查'), - ), + ),*/ //客观题 Container( padding: EdgeInsets.symmetric(vertical: 10.r, horizontal: 10.r), diff --git a/marking_app/lib/pages/homework_correction/pages/favorite_student_dialog.dart b/marking_app/lib/pages/homework_correction/pages/favorite_student_dialog.dart new file mode 100644 index 0000000..8894ada --- /dev/null +++ b/marking_app/lib/pages/homework_correction/pages/favorite_student_dialog.dart @@ -0,0 +1,105 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:photo_view/photo_view_gallery.dart'; + +class FavoriteStudentDialog extends StatefulWidget { + const FavoriteStudentDialog({Key? key}) : super(key: key); + + @override + State createState() => _FavoriteStudentDialogState(); +} + +class _FavoriteStudentDialogState extends State { + int defaultIndex = 1; + + @override + Widget build(BuildContext context) { + return Container( + width: MediaQuery.of(context).size.width, + height: MediaQuery.of(context).size.height, + padding: EdgeInsets.symmetric(vertical: 10.r, horizontal: 14.r), + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + '14班 张小凡', + style: TextStyle(fontSize: 12.sp, color: Color(0xFF4E73FD)), + ), + Expanded(child: Container()), + Text( + '6题', + style: TextStyle(fontSize: 12.sp, color: Color(0xFF868686)), + ), + Padding( + padding: EdgeInsets.symmetric(horizontal: 8.r), + child: Image.asset( + 'assets/images/favorite_delete_icon.png', + width: 22.r, + height: 22.r, + ), + ), + InkWell( + onTap: (){ + Navigator.pop(context); + }, + child: Image.asset( + 'assets/images/favorite_dialog_close.png', + width: 22.r, + height: 22.r, + ), + ), + ], + ), + SizedBox(height: 10.r,), + Expanded( + child: Container( + color:Color(0xFF868686), + width: MediaQuery.of(context).size.width, + /* child: PhotoViewGallery.builder( + scrollPhysics: const BouncingScrollPhysics(), + builder: (BuildContext context, int index) { + return PhotoViewGalleryPageOptions( + imageProvider: NetworkImage(widget.imageItems[index]), + ); + }, + itemCount: 2, + pageController:PageController(initialPage: defaultIndex), + // onPageChanged: (){}, + scrollDirection: Axis.horizontal, + ),*/ + ), + ), + Padding( + padding:EdgeInsets.symmetric(vertical: 15.r), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Container( +width: (MediaQuery.of(context).size.width - 78.r)/2 - 10.r, + height: 28.r, + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(6.r)), + border: Border.all(width: 1.r,color: Color(0xFFCACACA),style: BorderStyle.solid), + ), + child: Center(child: Text('上一页',style: TextStyle(fontSize: 10.r,color: Color(0xFF505E6E)),)), + ), + Container( + width: (MediaQuery.of(context).size.width - 78.r)/2 - 10.r, + height: 28.r, + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(6.r)), + border: Border.all(width: 1.r,color: Color(0xFFCACACA),style: BorderStyle.solid), + ), + child: Center(child: Text('下一页',style: TextStyle(fontSize: 10.r,color: Color(0xFF505E6E)),)), + ), + ], + ), + ) + ], + ), + ); + } +} diff --git a/marking_app/lib/pages/homework_correction/pages/job_favorite.dart b/marking_app/lib/pages/homework_correction/pages/job_favorite.dart index 62c6346..f0c21fc 100644 --- a/marking_app/lib/pages/homework_correction/pages/job_favorite.dart +++ b/marking_app/lib/pages/homework_correction/pages/job_favorite.dart @@ -1,9 +1,17 @@ +import 'dart:convert'; + import 'package:flutter/material.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.dart'; +import 'package:marking_app/common/model/job/job_fav_student.dart'; import 'package:marking_app/common/model/job/job_favorite_item_model.dart'; +import 'package:marking_app/common/model/job/job_report_join_class.dart'; +import 'package:marking_app/pages/homework_correction/pages/favorite_student_dialog.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'; /// 作业收藏学生名单列表 class JobFavorite extends StatefulWidget { @@ -11,12 +19,14 @@ class JobFavorite extends StatefulWidget { final int schoolId; final int gradeId; final String className; + final String jobName; const JobFavorite({ required this.jobId, required this.schoolId, required this.gradeId, required this.className, + required this.jobName, super.key, }); @@ -25,18 +35,32 @@ class JobFavorite extends StatefulWidget { } class _JobFavoriteState extends State with CommonMixin { - late Future?> _future; + late Future?> _future; + List? involveClasses = []; + JobReportJoinClass? classData; + late String loginName; + final int pageSize = 100; @override void initState() { super.initState(); + FastData fastData = FastData.getInstance(); + fastData.getUser().then((value) { + if (value == null || value == '') return; + Map userInfo = json.decode(value); + setState(() { + loginName = userInfo['loginName']; + }); + }); + getInvolveClasses(); _future = getData(); } - Future?> getData() async { + Future> getData() async { var _client = await getClient(); - var result = await _client.getListOfJobFavorites(widget.jobId, widget.gradeId, widget.schoolId, widget.className); - return result.data; + var result = await _client.getListOfJobFavorites( + widget.jobId, widget.jobName, widget.className,loginName,pageSize); + return result.data!.items; } Future toGoCancelFavorite(int jobId, int studentId) async { @@ -47,53 +71,226 @@ class _JobFavoriteState extends State with CommonMixin { } } + Future getInvolveClasses() async { + try { + RestClient _client = await getClient(); + BaseStructureResult> result = + await _client.getJobReportJoinClasses(widget.jobId); + if (result.success) { + toUpState(setState, () { + involveClasses = [ + JobReportJoinClass(-1, '全部', -1, '全部', '全部', '全部', -1, -1, '-1'), + ...(result.data ?? []) + ]; + involveClasses?.forEach((element) { + if(element.className == widget.className && element.gradeId == widget.gradeId && element.schoolId == widget.schoolId){ + classData = element; + } + }); + }, mounted); + } + print('involveClasses=${involveClasses!.length}'); + _future = getData(); + } catch (e) { + print(e); + } + } + + void showStudentDialog(BuildContext context) { + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + insetPadding: EdgeInsets.all(25.r), + content: FavoriteStudentDialog(), + contentPadding: EdgeInsets.all(0), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.circular(15.r)))); + }, + ); + } + @override Widget build(BuildContext context) { + bool isPadFlag = isPad(); return Scaffold( + backgroundColor: Color.fromRGBO(245, 245, 245, 1), appBar: AppBar( // titleSpacing: 0, - leading: IconButton(icon: Icon(Icons.arrow_back_ios), onPressed: () => Navigator.of(context).pop()), + elevation: 0.0, + leading: IconButton( + icon: Icon(Icons.arrow_back_ios), + onPressed: () => Navigator.of(context).pop()), iconTheme: IconThemeData(color: Colors.black), title: quickText('收藏夹'), + centerTitle: true, backgroundColor: Colors.white, ), - body: MyFutureBuilder.buildFutureBuilderOfSingleInstance>( + body: MyFutureBuilder.buildFutureBuilderOfSingleInstance< + List>( context, _future, - (List? datas) { - if (datas == null) + (List? datas) { + /* if (datas == null) return Container( child: Center( child: quickText('请求错误'), ), - ); + );*/ + print('datas${datas}'); + + List pageList = []; + List groupList = []; + if(datas!.length>0){ + for (var item in datas) { + pageList.add(item.questionPage); + } + pageList = pageList.toSet().toList(); + + for (var page in pageList) { + var printList = datas.where((element) => element.questionPage == page).toList(); + groupList.add({"questionPage": page, "list": printList}); + } + } + return Container( child: Column( children: [ - Container(child: quickText(widget.className)), - Expanded( - child: ListView.builder( - itemBuilder: (context, index) { - JobFavoriteItemModel item = datas[index]; - return Container( + Padding( + padding: EdgeInsets.symmetric(vertical: 0.r, horizontal: 14.r), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + '函数A的对称性研究', + style: + TextStyle(fontSize: 14.sp, color: Color(0xFF3C3C3C)), + ), + // 下拉框 + Container( + padding: EdgeInsets.symmetric(vertical: 10.h, horizontal: 10.w), + child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - quickText(item.studentName, color: Color.fromRGBO(102, 102, 102, 1), size: 14.sp), - quickText('收藏时间:${item.createTime}', color: Color.fromRGBO(137, 137, 137, 1), size: 10.sp), - InkWell( - onTap: () async {}, - child: Icon( - Icons.favorite, - size: 28.sp, - color: Color.fromRGBO(252, 108, 108, 1), + $classSelection(involveClasses, classData, + call: (JobReportJoinClass _classData) { + classData = _classData; + if (_classData.gradeId == -1) classData = null; + _future = getData(); + toUpState(setState, () {}, mounted); + }), + // Expanded(child: Text('')), + ], + ), + ), + + ], + ), + ), + Container( + width: MediaQuery.of(context).size.width, + height: 1.r, + decoration: BoxDecoration( + color: Color(0xFFCCCCCC), + ), + ), + Expanded( + child: isPadFlag? Padding( + padding: EdgeInsets.only(top: 10.r,bottom:8.r,left: 14.r,right: 14.r), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.only(bottom: 5.r), + child: Text('第六题',style: TextStyle(fontSize: 14.sp,color: Color(0xFF2E5BFF)),), + ), +GridView(gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, + mainAxisSpacing: 8.r, + crossAxisSpacing: 10.r, + childAspectRatio: 556 / 112, +), + shrinkWrap: true, + children: [ + Container( + padding: EdgeInsets.symmetric(vertical: 5.r,horizontal: 10.r), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.all(Radius.circular(6.r)), + ), + child: InkWell( + onTap: (){ + showStudentDialog(context); + }, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + quickText('张小凡', + color: Color(0xFF333333), + size: 12.sp), + Expanded(child: Container()), + Padding( + padding:EdgeInsets.only(right: 8.r), + child: Text('12班',style: TextStyle(fontSize: 12.sp,color: Color(0xFF666666)),), + ), + InkWell( + onTap: () async { + print('删除'); + }, + child: Image.asset('assets/images/favorite_delete_icon.png',width: 26.r,height: 26.r,), + ), + ], + ), + ), + ), +],), + + ], + ), + ):ListView.builder( + shrinkWrap: true, + itemBuilder: (context, index) { + // Items item = datas[index]; + return Padding( + padding: EdgeInsets.only(top: 10.r,bottom:8.r,left: 14.r,right: 14.r), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.only(bottom: 5.r), + child: Text('第六题',style: TextStyle(fontSize: 14.sp,color: Color(0xFF2E5BFF)),), + ), + Container( + padding: EdgeInsets.symmetric(vertical: 5.r,horizontal: 10.r), + margin: EdgeInsets.only(top: 5.r), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.all(Radius.circular(6.r)), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + quickText('张小凡', + color: Color(0xFF333333), + size: 14.sp), + Expanded(child: Container()), + Padding( + padding:EdgeInsets.only(right: 8.r), + child: Text('12班',style: TextStyle(fontSize: 14.sp,color: Color(0xFF666666)),), + ), + InkWell( + onTap: () async {}, + child: Image.asset('assets/images/favorite_delete_icon.png',width: 32.r,height: 32.r,), + ), + ], ), ), ], ), ); }, - itemCount: datas.length, + // itemCount: datas.length, + itemCount: 10, ), ), ], @@ -102,4 +299,40 @@ class _JobFavoriteState extends State with CommonMixin { ), ); } + } +/// 下拉选择框 +@swidget +Widget $classSelection( + List? involveClasses, JobReportJoinClass? classData, + {required Function(JobReportJoinClass) call}) { + if (involveClasses == null) + return Container(child: quickText('点击重试')); // 点击重试 + return Container( + // width: 200.r, + padding: EdgeInsets.symmetric(horizontal: 10.r), + decoration: BoxDecoration( + color: Colors.white, + 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.uniqueId == '-1'?e.graduationYear: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)); + }, + ), + ); +} \ No newline at end of file diff --git a/marking_app/lib/pages/homework_correction/pages/job_list_participate_in_class.dart b/marking_app/lib/pages/homework_correction/pages/job_list_participate_in_class.dart index 682db5a..688909d 100644 --- a/marking_app/lib/pages/homework_correction/pages/job_list_participate_in_class.dart +++ b/marking_app/lib/pages/homework_correction/pages/job_list_participate_in_class.dart @@ -270,7 +270,7 @@ class _JobListParticipateInClassState extends State w RouterManager.router.navigateTo( context, RouterManager.jobFavoritePagePath + - '?className=${Uri.encodeComponent(task.className)}&jobId=${widget.jobId}&schoolId=${task.dpcSchoolId}&gradeId=${task.dpcGradeId}', + '?className=${Uri.encodeComponent(task.className)}&jobId=${widget.jobId}&schoolId=${task.dpcSchoolId}&gradeId=${task.dpcGradeId}&jobName=${widget.jobName}', transition: getTransition(), ); } diff --git a/marking_app/lib/pages/homework_correction/quick_check_personal.dart b/marking_app/lib/pages/homework_correction/quick_check_personal.dart index e020182..ed513f8 100644 --- a/marking_app/lib/pages/homework_correction/quick_check_personal.dart +++ b/marking_app/lib/pages/homework_correction/quick_check_personal.dart @@ -7,6 +7,7 @@ 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'; +import 'package:marking_app/utils/toast_utils.dart'; class QuickCheckPersonal extends StatefulWidget { final int jobId; @@ -33,15 +34,21 @@ class _QuickCheckPersonalState extends State void getJobPersonal() async { RestClient _client = await getClient(); Map params = {}; - // params['jobid'] = widget.jobId; - params['jobid'] = '521646983660101'; + params['jobid'] = widget.jobId; + // params['jobid'] = '521646983660101'; params['studentId'] = widget.studentId; BaseStructureResult data = await _client.getJobPersonalReport(params); + if(data.data!.studentId != null){ + setState(() { + studentInfo = data.data; + }); + }else{ + Navigator.pop(context); + ToastUtils.showError('暂无数据'); + } EasyLoading.dismiss(); - setState(() { - studentInfo = data.data; - }); + } @override @@ -54,7 +61,7 @@ class _QuickCheckPersonalState extends State appBar: AppBar( backgroundColor: Colors.white, title: Text( - studentInfo!.studentName, + studentInfo!.studentName!, style: TextStyle(fontSize: 16.sp, color: Color(0xFF000000)), ), centerTitle: true, diff --git a/marking_app/lib/pages/homework_correction/quick_data_check.dart b/marking_app/lib/pages/homework_correction/quick_data_check.dart index d9eb4fe..6526331 100644 --- a/marking_app/lib/pages/homework_correction/quick_data_check.dart +++ b/marking_app/lib/pages/homework_correction/quick_data_check.dart @@ -36,8 +36,8 @@ class _QuickDataCheckPageState extends State with CommonMixi void getJobDataReport() async { RestClient _client = await getClient(); Map params = {}; - // params['jobid'] = widget.jobId; - params['jobid'] = '521646983660101'; + params['jobid'] = widget.jobId; + print(widget.jobId); BaseStructureResult data = await _client.getJobDataCenterReport(params); EasyLoading.dismiss(); 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 index 4631bc6..d243f10 100644 --- 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 @@ -54,10 +54,11 @@ class _QuickStudentDataTableState extends State { cells: [ DataCell(InkWell( onTap: () { + RouterManager.router.navigateTo( context, RouterManager.quickCheckPersonalPath + - '?jobId=${521646983660101}&studentId=${item.studentId}', + '?jobId=${widget.jobId}&studentId=${item.studentId}', transition: getTransition(), ); }, @@ -68,7 +69,7 @@ class _QuickStudentDataTableState extends State { mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ - Text(item.studentName, + Text(item.studentName!, style: TextStyle(fontSize: 12.sp, color: Color(0xFF6888FD))), SizedBox( diff --git a/marking_app/lib/routes/RouterManager.dart b/marking_app/lib/routes/RouterManager.dart index 31d5cc0..81b30a0 100644 --- a/marking_app/lib/routes/RouterManager.dart +++ b/marking_app/lib/routes/RouterManager.dart @@ -312,7 +312,8 @@ class RouterManager { int gradeId = int.parse(params['gradeId']![0]); int schoolId = int.parse(params['schoolId']![0]); String className = params['className']![0]; - return JobFavorite(jobId: jobId, gradeId: gradeId, schoolId: schoolId, className: className); + String jobName = params['jobName']![0]; + return JobFavorite(jobId: jobId, gradeId: gradeId, schoolId: schoolId, className: className,jobName:jobName); }, ); diff --git a/marking_app/lib/utils/request/rest_client.dart b/marking_app/lib/utils/request/rest_client.dart index e220520..026cc2f 100644 --- a/marking_app/lib/utils/request/rest_client.dart +++ b/marking_app/lib/utils/request/rest_client.dart @@ -17,6 +17,7 @@ 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_fav_student.dart'; import 'package:marking_app/common/model/job/job_favorite_item_model.dart'; import 'package:marking_app/common/model/job/job_favorite_model.dart'; import 'package:marking_app/common/model/job/job_level_set_params.dart'; @@ -303,12 +304,13 @@ abstract class RestClient { @the_retrofit.Query("jobid") int jobId); // 作业 => 作业收藏列表 - @the_retrofit.GET("${RequestConfig.hwProxyKeywords}/dpc-api/api/read/job-favorites") - Future>> getListOfJobFavorites( - @the_retrofit.Query("jobid") int jobId, - @the_retrofit.Query("gradeId") int gradeId, - @the_retrofit.Query("schoolId") int schoolId, + @the_retrofit.GET("/api/jobs/fav-student-jobs") + Future> getListOfJobFavorites( + @the_retrofit.Query("JobId") int jobId, + @the_retrofit.Query("JobName") String jobName, @the_retrofit.Query("className") String className, + @the_retrofit.Query("Account") String loginName, + @the_retrofit.Query("PageSize") int pageSize, ); // 作业 => 作业收藏列表 -- 2.40.1 From cea53d3544f41134d1fa3b20999a8d720bc3b1b1 Mon Sep 17 00:00:00 2001 From: "1147192855@qq.com" <1147192855@qq.com> Date: Wed, 13 Mar 2024 15:10:15 +0800 Subject: [PATCH 22/22] no message --- marking_app/pubspec.yaml | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/marking_app/pubspec.yaml b/marking_app/pubspec.yaml index 5cebb4e..03da983 100644 --- a/marking_app/pubspec.yaml +++ b/marking_app/pubspec.yaml @@ -3,7 +3,7 @@ description: A new Flutter project. # The following line prevents the package from being accidentally published to # pub.dev using `flutter pub publish`. This is preferred for private packages. -publish_to: 'none' # Remove this line if you wish to publish to pub.dev +publish_to: "none" # Remove this line if you wish to publish to pub.dev # The following defines the version and build number for your application. # A version number is three numbers separated by dots, like 1.2.43 @@ -15,10 +15,10 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.87 +version: 1.0.96 environment: - sdk: '>=2.17.1 <3.0.0' + sdk: ">=2.17.1 <3.0.0" # Dependencies specify other packages that your package needs in order to woyrk. # To automatically upgrade your package dependencies to the latest versions @@ -29,8 +29,7 @@ environment: dependencies: flutter: sdk: flutter - flutter_localizations: - sdk: flutter + # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.2 @@ -40,7 +39,7 @@ dependencies: # easy_refresh: ^3.3.2+1 retrofit: ^3.3.1 logger: ^1.1.0 - + flutter_lints: ^2.0.0 fluttertoast: ^8.2.3 json_annotation: ^4.8.1 @@ -61,6 +60,7 @@ dependencies: permission_handler: ^11.0.1 flutter_widget_from_html_core: ^0.10.3 + # 事件总线 event_bus: ^2.0.0 image_picker: ^0.8.6 @@ -108,7 +108,6 @@ dependencies: badges: ^3.1.2 horizontal_data_table: ^4.1.1 data_table_2: ^2.5.10 - syncfusion_flutter_datepicker: ^21.2.4 dev_dependencies: flutter_test: @@ -118,13 +117,16 @@ dev_dependencies: json_serializable: ^6.3.1 # 分离样式 functional_widget: ^0.10.1 - + + # The "flutter_lints" package below contains a set of recommended lints to # encourage good coding practices. The lint set provided by the package is # activated in the `analysis_options.yaml` file located at the root of your # package. See that file for information about deactivating specific lint # rules and activating additional ones. + + # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec -- 2.40.1