作业报告,数据快查
This commit is contained in:
parent
39d0686b91
commit
624fb083df
Binary file not shown.
|
After Width: | Height: | Size: 326 B |
Binary file not shown.
|
After Width: | Height: | Size: 465 B |
Binary file not shown.
|
After Width: | Height: | Size: 290 B |
Binary file not shown.
|
After Width: | Height: | Size: 1.8 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 443 B |
|
|
@ -0,0 +1,125 @@
|
||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
|
part 'job_data_report.g.dart';
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class JobDataReport extends Object {
|
||||||
|
|
||||||
|
@JsonKey(name: 'jobId')
|
||||||
|
int jobId;
|
||||||
|
|
||||||
|
@JsonKey(name: 'jobName')
|
||||||
|
String jobName;
|
||||||
|
|
||||||
|
@JsonKey(name: 'gradeName')
|
||||||
|
String gradeName;
|
||||||
|
|
||||||
|
@JsonKey(name: 'className')
|
||||||
|
String? className;
|
||||||
|
|
||||||
|
@JsonKey(name: 'validCount')
|
||||||
|
int validCount;
|
||||||
|
|
||||||
|
@JsonKey(name: 'noAnswerCount')
|
||||||
|
int noAnswerCount;
|
||||||
|
|
||||||
|
@JsonKey(name: 'kgValidRate')
|
||||||
|
double kgValidRate;
|
||||||
|
|
||||||
|
@JsonKey(name: 'kgQuestionCount')
|
||||||
|
int kgQuestionCount;
|
||||||
|
|
||||||
|
@JsonKey(name: 'zgValidRate')
|
||||||
|
double zgValidRate;
|
||||||
|
|
||||||
|
@JsonKey(name: 'zgQuestionCount')
|
||||||
|
int zgQuestionCount;
|
||||||
|
|
||||||
|
@JsonKey(name: 'studentDetails')
|
||||||
|
List<StudentDetails> 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<String, dynamic> srcJson) => _$JobDataReportFromJson(srcJson);
|
||||||
|
|
||||||
|
Map<String, dynamic> 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> kgDetails;
|
||||||
|
|
||||||
|
@JsonKey(name: 'zgDetails')
|
||||||
|
List<KgDetails> zgDetails;
|
||||||
|
|
||||||
|
StudentDetails(this.studentId,this.studentName,this.kgValidCount,this.kgValidRate,this.zgValidCount,this.zgValidRate,this.kgDetails,this.zgDetails,);
|
||||||
|
|
||||||
|
factory StudentDetails.fromJson(Map<String, dynamic> srcJson) => _$StudentDetailsFromJson(srcJson);
|
||||||
|
|
||||||
|
Map<String, dynamic> 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<String, dynamic> srcJson) => _$KgDetailsFromJson(srcJson);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$KgDetailsToJson(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -51,6 +51,12 @@ class JobReportModel extends Object {
|
||||||
@JsonKey(name: 'overallTitles')
|
@JsonKey(name: 'overallTitles')
|
||||||
List<OverallTitles> overallTitles;
|
List<OverallTitles> overallTitles;
|
||||||
|
|
||||||
|
@JsonKey(name: 'kgReport')
|
||||||
|
KgReport kgReport;
|
||||||
|
|
||||||
|
@JsonKey(name: 'zgReport')
|
||||||
|
ZgReport zgReport;
|
||||||
|
|
||||||
// 前端自定义 -- 全对学生
|
// 前端自定义 -- 全对学生
|
||||||
@JsonKey(name: 'allpairsStudents')
|
@JsonKey(name: 'allpairsStudents')
|
||||||
List<StudentAnswerInfos>? allpairsStudents;
|
List<StudentAnswerInfos>? allpairsStudents;
|
||||||
|
|
@ -82,7 +88,10 @@ class JobReportModel extends Object {
|
||||||
this.knowledgeInfos,
|
this.knowledgeInfos,
|
||||||
this.questionAnswerInfos,
|
this.questionAnswerInfos,
|
||||||
this.studentAnswerInfos,
|
this.studentAnswerInfos,
|
||||||
this.overallTitles, [
|
this.overallTitles,
|
||||||
|
this.kgReport,
|
||||||
|
this.zgReport,
|
||||||
|
[
|
||||||
this.allpairsStudents,
|
this.allpairsStudents,
|
||||||
this.passStudents,
|
this.passStudents,
|
||||||
this.disqualifiedStudents,
|
this.disqualifiedStudents,
|
||||||
|
|
@ -274,3 +283,84 @@ class OverallTitles extends Object {
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => _$OverallTitlesToJson(this);
|
Map<String, dynamic> toJson() => _$OverallTitlesToJson(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class KgReport extends Object {
|
||||||
|
|
||||||
|
@JsonKey(name: 'correctRate')
|
||||||
|
int correctRate;
|
||||||
|
|
||||||
|
@JsonKey(name: 'details')
|
||||||
|
List<Details> details;
|
||||||
|
|
||||||
|
KgReport(this.correctRate,this.details,);
|
||||||
|
|
||||||
|
factory KgReport.fromJson(Map<String, dynamic> srcJson) => _$KgReportFromJson(srcJson);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$KgReportToJson(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class ZgReport extends Object {
|
||||||
|
|
||||||
|
@JsonKey(name: 'correctRate')
|
||||||
|
int correctRate;
|
||||||
|
|
||||||
|
@JsonKey(name: 'details')
|
||||||
|
List<Details> details;
|
||||||
|
|
||||||
|
ZgReport(this.correctRate,this.details,);
|
||||||
|
|
||||||
|
factory ZgReport.fromJson(Map<String, dynamic> srcJson) => _$ZgReportFromJson(srcJson);
|
||||||
|
|
||||||
|
Map<String, dynamic> 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<String> 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<String> 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<String, dynamic> srcJson) => _$DetailsFromJson(srcJson);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$DetailsToJson(this);
|
||||||
|
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -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<QuickCheckPersonal> createState() => _QuickCheckPersonalState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _QuickCheckPersonalState extends State<QuickCheckPersonal>
|
||||||
|
with CommonMixin {
|
||||||
|
StudentDetails? studentInfo;
|
||||||
|
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
EasyLoading.show(status: 'loading...');
|
||||||
|
getJobPersonal();
|
||||||
|
}
|
||||||
|
|
||||||
|
void getJobPersonal() async {
|
||||||
|
RestClient _client = await getClient();
|
||||||
|
Map<String, dynamic> params = {};
|
||||||
|
// params['jobid'] = widget.jobId;
|
||||||
|
params['jobid'] = '521646983660101';
|
||||||
|
params['studentId'] = widget.studentId;
|
||||||
|
BaseStructureResult<StudentDetails?> 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,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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<QuickDataCheck> createState() => _QuickDataCheckState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _QuickDataCheckState extends State<QuickDataCheck> with CommonMixin {
|
||||||
|
JobDataReport? jobData;
|
||||||
|
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
EasyLoading.show(status:'loading...');
|
||||||
|
getJobDataReport();
|
||||||
|
}
|
||||||
|
|
||||||
|
void getJobDataReport() async {
|
||||||
|
RestClient _client = await getClient();
|
||||||
|
Map<String, dynamic> params = {};
|
||||||
|
// params['jobid'] = widget.jobId;
|
||||||
|
params['jobid'] = '521646983660101';
|
||||||
|
BaseStructureResult<JobDataReport?> 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,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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<QuickStudentDataTable> createState() => _QuickStudentDataTableState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _QuickStudentDataTableState extends State<QuickStudentDataTable> {
|
||||||
|
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<DataRow>.generate(widget.bodyList.length,
|
||||||
|
(index) => _getRow(index, Color(0xFFF5F5F5))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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<ReportTable> createState() => _ReportTableState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ReportTableState extends State<ReportTable> {
|
||||||
|
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<DataRow>.generate(widget.bodyList.length,
|
||||||
|
(index) => _getRow(index, Color(0xFFF5F5F5))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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<StudentKgTable> createState() => _StudentKgTableState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _StudentKgTableState extends State<StudentKgTable> {
|
||||||
|
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<DataRow>.generate(widget.bodyList.length,
|
||||||
|
(index) => _getRow(index, Color(0xFFF5F5F5))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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<StudentZgTable> createState() => _StudentZgTableState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _StudentZgTableState extends State<StudentZgTable> {
|
||||||
|
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<DataRow>.generate(widget.bodyList.length,
|
||||||
|
(index) => _getRow(index, Color(0xFFF5F5F5))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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)),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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/common/startUpPage.dart';
|
||||||
import 'package:marking_app/pages/homework_correction/do_papers_job_exam.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/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/homework_correction/review_job.dart';
|
||||||
|
|
||||||
import 'package:marking_app/pages/login/index.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 reportPersonalSubjectPath = 'report/details/reportPersonalSubject';
|
||||||
static const String userMinePath = 'user/mine/index';
|
static const String userMinePath = 'user/mine/index';
|
||||||
static const String reportDetailPath = '/report_detail/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
|
// TheMine
|
||||||
|
|
||||||
static final FluroRouter router = FluroRouter();
|
static final FluroRouter router = FluroRouter();
|
||||||
|
|
@ -239,6 +244,24 @@ class RouterManager {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// 数据快查
|
||||||
|
static final _quickDataCheckPageHandler = Handler(
|
||||||
|
handlerFunc: (BuildContext? context, Map<String, List<String>> 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<String, List<String>> 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<String, List<String>> params) => MarkingPapers());
|
// static final _doMarkingPapers = Handler(handlerFunc: (BuildContext? context, Map<String, List<String>> params) => MarkingPapers());
|
||||||
|
|
||||||
|
|
@ -273,6 +296,8 @@ class RouterManager {
|
||||||
router.define(reportDetailPath, handler: _reportDetailPath, transitionType: TransitionType.material);
|
router.define(reportDetailPath, handler: _reportDetailPath, transitionType: TransitionType.material);
|
||||||
router.define(jobReportPagePath, handler: _jobReportPageHandler, transitionType: TransitionType.material);
|
router.define(jobReportPagePath, handler: _jobReportPageHandler, transitionType: TransitionType.material);
|
||||||
router.define(jobExamPagePath, handler: _jobExamPageHandler, 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()
|
// getTransition()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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_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.dart';
|
||||||
import 'package:marking_app/common/model/job/job_concerned_with_student_params.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_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_note_taking_trajectory.dart';
|
||||||
import 'package:marking_app/common/model/job/job_page_tab.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")
|
@the_retrofit.GET("/api/jobs/job-report-question-detail")
|
||||||
Future<BaseStructureResult<List<JobReportQuestionDeatilModel>>> getJobReportQuestionDetail(
|
Future<BaseStructureResult<List<JobReportQuestionDeatilModel>>> getJobReportQuestionDetail(
|
||||||
@the_retrofit.Query("jobid") int jobId, @the_retrofit.Query("questionid") int questionid);
|
@the_retrofit.Query("jobid") int jobId, @the_retrofit.Query("questionid") int questionid);
|
||||||
|
|
||||||
|
// 作业 => 数据快查
|
||||||
|
@the_retrofit.GET("/api/read/job-data-center-report")
|
||||||
|
Future<BaseStructureResult<JobDataReport>> getJobDataCenterReport(@the_retrofit.Queries() Map<String, dynamic> params);
|
||||||
|
|
||||||
|
// 作业 => 数据快查--个人
|
||||||
|
@the_retrofit.GET("/api/read/job-data-center-student-report")
|
||||||
|
Future<BaseStructureResult<StudentDetails>> getJobPersonalReport(@the_retrofit.Queries() Map<String, dynamic> params);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue