数据快查

This commit is contained in:
machuanyu 2024-05-16 14:30:26 +08:00
parent 4cf916e387
commit 94977b5d96
22 changed files with 1807 additions and 27 deletions

View File

@ -1,10 +1,12 @@
import 'package:dio/dio.dart' hide Headers; import 'package:dio/dio.dart' hide Headers;
import 'package:retrofit/retrofit.dart'; import 'package:retrofit/retrofit.dart';
import 'package:school_asignment_app/common/job/annotated_class.dart';
import 'package:school_asignment_app/common/job/class_item.dart'; import 'package:school_asignment_app/common/job/class_item.dart';
import 'package:school_asignment_app/common/job/common/app_version_model.dart'; import 'package:school_asignment_app/common/job/common/app_version_model.dart';
import 'package:school_asignment_app/common/job/common/base_app_version.dart'; import 'package:school_asignment_app/common/job/common/base_app_version.dart';
import 'package:school_asignment_app/common/job/common/base_page_data.dart'; import 'package:school_asignment_app/common/job/common/base_page_data.dart';
import 'package:school_asignment_app/common/job/enum_subject.dart'; import 'package:school_asignment_app/common/job/enum_subject.dart';
import 'package:school_asignment_app/common/job/homework_details.dart';
import 'package:school_asignment_app/common/job/student_item.dart'; import 'package:school_asignment_app/common/job/student_item.dart';
import 'package:school_asignment_app/common/job/user_info_detail.dart'; import 'package:school_asignment_app/common/job/user_info_detail.dart';
import 'package:school_asignment_app/common/job/work_student.dart'; import 'package:school_asignment_app/common/job/work_student.dart';
@ -35,7 +37,7 @@ abstract class RetrofitClient {
//, //,
@GET("/api/app/Common/GetEnumInfos") @GET("/api/app/Common/GetEnumInfos")
Future<Map<String, List<EnumSubject>>> getEnumSubjectList(@Query('enumNames') String enumNames); Future<Map<String, List<EnumSubject>>> getEnumSubjectList(@Query('enumNames') List enumNames);
// //
@GET("/api/rbac/Class/GetTeacherClasses") @GET("/api/rbac/Class/GetTeacherClasses")
@ -44,4 +46,20 @@ abstract class RetrofitClient {
// //
@GET("/api/rbac/Class/GetClassStudents") @GET("/api/rbac/Class/GetClassStudents")
Future<StudentItem> getStudentList(@Query('ClassId') String classId); Future<StudentItem> getStudentList(@Query('ClassId') String classId);
//
@GET("/api/hms/Annotate/GetUnAnnotateList")
Future<WorkStudent> getUnAnnotateList(@Queries() WorkStudentParams params);
//
@GET("/api/hms/Annotate/GetAnnotatedList")
Future<WorkStudent> getAnnotatedList(@Queries() WorkStudentParams params);
//
@GET("/api/hms/Annotate/Get")
Future<List<AnnotatedClass>> getAnnotatedClassList(@Query('homeworkId') String homeworkId);
//
@GET("/api/hms/HmsReport/GetHomeworkDtls")
Future<HomeworkDetails> getHomeworkDetails(@Query('homeworkId') String homeworkId,@Query('classId') String classId);
} }

View File

@ -11,6 +11,7 @@ import 'package:school_asignment_app/common/job/common/base_page.dart';
class RequestConfig { class RequestConfig {
static const _devBaseUrl = "http://192.168.2.119:1091"; // static const _devBaseUrl = "http://192.168.2.119:1091"; //
static const _proBaseUrl = "https://dpc-teacher-api.23544.com"; // static const _proBaseUrl = "https://dpc-teacher-api.23544.com"; //
static const imgUrl = 'https://dpcjob.oss-cn-beijing.aliyuncs.com/';
static RequestConfig? _instance; static RequestConfig? _instance;
String baseUrl; String baseUrl;
@ -21,7 +22,7 @@ class RequestConfig {
static const bool printSwitch = true; // static const bool printSwitch = true; //
static const successCode = [204, 200]; // code static const successCode = [204, 200]; // code
static final BasePage basePage = BasePage(1, 10); // static final BasePage basePage = BasePage(1, 10); //
// //
// //
RequestConfig._({required this.baseUrl}); RequestConfig._({required this.baseUrl});

View File

@ -0,0 +1,146 @@
import 'package:json_annotation/json_annotation.dart';
part 'annotated_class.g.dart';
@JsonSerializable()
class AnnotatedClass extends Object {
@JsonKey(name: 'schoolName')
String schoolName;
@JsonKey(name: 'classId')
String classId;
@JsonKey(name: 'className')
String className;
@JsonKey(name: 'finishTime')
String? finishTime;
@JsonKey(name: 'questionCount')
int questionCount;
@JsonKey(name: 'answerCount')
int answerCount;
@JsonKey(name: 'answerRate')
int answerRate;
@JsonKey(name: 'unAnnotateCount')
int unAnnotateCount;
@JsonKey(name: 'annotateRate')
int annotateRate;
@JsonKey(name: 'students')
List<Students> students;
@JsonKey(name: 'homeworkFavs')
List<HomeworkFavs> homeworkFavs;
@JsonKey(name: 'kgtCorrectRate')
int kgtCorrectRate;
@JsonKey(name: 'zgtCorrectRate')
int zgtCorrectRate;
@JsonKey(name: 'correctRate')
int correctRate;
@JsonKey(name: 'commitStudentCount')
int? commitStudentCount;
@JsonKey(name: 'noCommitStudentCount')
int? noCommitStudentCount;
AnnotatedClass(this.schoolName,this.classId,this.className,this.finishTime,this.questionCount,this.answerCount,this.answerRate,this.unAnnotateCount,this.annotateRate,this.students,this.homeworkFavs,this.kgtCorrectRate,this.zgtCorrectRate,this.correctRate,this.commitStudentCount,this.noCommitStudentCount);
factory AnnotatedClass.fromJson(Map<String, dynamic> srcJson) => _$AnnotatedClassFromJson(srcJson);
Map<String, dynamic> toJson() => _$AnnotatedClassToJson(this);
}
@JsonSerializable()
class Students extends Object {
@JsonKey(name: 'id')
String? id;
@JsonKey(name: 'isDeleted')
bool isDeleted;
@JsonKey(name: 'homeworkId')
String? homeworkId;
@JsonKey(name: 'classId')
String classId;
@JsonKey(name: 'studentId')
int studentId;
@JsonKey(name: 'studentName')
String studentName;
@JsonKey(name: 'state')
int state;
Students(this.id,this.isDeleted,this.homeworkId,this.classId,this.studentId,this.studentName,this.state,);
factory Students.fromJson(Map<String, dynamic> srcJson) => _$StudentsFromJson(srcJson);
Map<String, dynamic> toJson() => _$StudentsToJson(this);
}
@JsonSerializable()
class HomeworkFavs extends Object {
@JsonKey(name: 'id')
String id;
@JsonKey(name: 'homeworkId')
String homeworkId;
@JsonKey(name: 'homeworkName')
String homeworkName;
@JsonKey(name: 'grade')
int grade;
@JsonKey(name: 'subject')
int subject;
@JsonKey(name: 'classId')
String classId;
@JsonKey(name: 'className')
String className;
@JsonKey(name: 'studentId')
int studentId;
@JsonKey(name: 'studentName')
String studentName;
@JsonKey(name: 'templateId')
String templateId;
@JsonKey(name: 'questionNo')
int questionNo;
@JsonKey(name: 'subjectiveAnswer')
String subjectiveAnswer;
HomeworkFavs(this.id,this.homeworkId,this.homeworkName,this.grade,this.subject,this.classId,this.className,this.studentId,this.studentName,this.templateId,this.questionNo,this.subjectiveAnswer,);
factory HomeworkFavs.fromJson(Map<String, dynamic> srcJson) => _$HomeworkFavsFromJson(srcJson);
Map<String, dynamic> toJson() => _$HomeworkFavsToJson(this);
}

View File

@ -0,0 +1,219 @@
import 'package:json_annotation/json_annotation.dart';
part 'homework_details.g.dart';
@JsonSerializable()
class HomeworkDetails extends Object {
@JsonKey(name: 'questions')
List<Questions> questions;
@JsonKey(name: 'knows')
List<Knows> knows;
@JsonKey(name: 'students')
List<Students> students;
@JsonKey(name: 'dtls')
List<Dtls> dtls;
HomeworkDetails(this.questions,this.knows,this.students,this.dtls);
factory HomeworkDetails.fromJson(Map<String, dynamic> srcJson) => _$HomeworkDetailsFromJson(srcJson);
Map<String, dynamic> toJson() => _$HomeworkDetailsToJson(this);
}
@JsonSerializable()
class Questions extends Object {
@JsonKey(name: 'id')
String id;
@JsonKey(name: 'templateId')
int templateId;
@JsonKey(name: 'questionNo')
int questionNo;
@JsonKey(name: 'questionType')
int questionType;
@JsonKey(name: 'answer')
String? answer;
@JsonKey(name: 'score')
int? score;
@JsonKey(name: 'questionPicture')
String? questionPicture;
@JsonKey(name: 'subjectivePicture')
String? subjectivePicture;
@JsonKey(name: 'knows')
List<Knows> knows;
@JsonKey(name: 'answerCount')
int? answerCount;
@JsonKey(name: 'answerRate')
double? answerRate;
@JsonKey(name: 'okRate')
double? okRate;
@JsonKey(name: 'priorityInfo')
List<Dtls>? priorityInfo;
@JsonKey(name: 'noAnswerStudents')
List<Dtls>? noAnswerStudents;
@JsonKey(name: 'answerOkStudents')
List<Dtls>? answerOkStudents;
@JsonKey(name: 'answerNgStudents')
List<Dtls>? answerNgStudents;
Questions(this.id,this.templateId,this.questionNo,this.questionType,this.answer,this.score,this.questionPicture,this.subjectivePicture,this.knows,this.answerCount,
this.answerRate,this.okRate,this.priorityInfo,this.noAnswerStudents,this.answerOkStudents,this.answerNgStudents);
factory Questions.fromJson(Map<String, dynamic> srcJson) => _$QuestionsFromJson(srcJson);
Map<String, dynamic> toJson() => _$QuestionsToJson(this);
}
@JsonSerializable()
class Knows extends Object {
@JsonKey(name: 'knowledgeId')
int knowledgeId;
@JsonKey(name: 'knowledgeName')
String knowledgeName;
@JsonKey(name: 'okCount')
int? okCount;
@JsonKey(name: 'ttlCount')
int? ttlCount;
@JsonKey(name: 'okRate')
double? okRate;
Knows(this.knowledgeId,this.knowledgeName,this.okCount,this.ttlCount,this.okRate);
factory Knows.fromJson(Map<String, dynamic> srcJson) => _$KnowsFromJson(srcJson);
Map<String, dynamic> toJson() => _$KnowsToJson(this);
}
@JsonSerializable()
class Students extends Object {
@JsonKey(name: 'studentId')
int studentId;
@JsonKey(name: 'studentName')
String studentName;
@JsonKey(name: 'state')
int state;
@JsonKey(name: 'priorityAnnotate')
bool priorityAnnotate;
@JsonKey(name: 'kgtStu')
List<Dtls>? kgtStu;
@JsonKey(name: 'kgtOkCount')
int? kgtOkCount;
@JsonKey(name: 'kgtErrorCount')
int? kgtErrorCount;
@JsonKey(name: 'kgtAnswerCount')
int? kgtAnswerCount;
@JsonKey(name: 'zgtStu')
List<Dtls>? zgtStu;
@JsonKey(name: 'zgtOkCount')
int? zgtOkCount;
@JsonKey(name: 'zgtErrorCount')
int? zgtErrorCount;
@JsonKey(name: 'zgtAnswerCount')
int? zgtAnswerCount;
@JsonKey(name: 'zgtUnrated')
int? zgtUnrated;
@JsonKey(name: 'allOk')
int? allOk;
@JsonKey(name: 'allNotDone')
bool? allNotDone;
Students(this.studentId,this.studentName,this.state,this.priorityAnnotate,this.kgtStu,this.kgtOkCount,this.kgtAnswerCount,this.zgtStu,this.zgtAnswerCount,this.zgtOkCount,this.allOk,this.kgtErrorCount,this.zgtErrorCount,this.zgtUnrated,this.allNotDone);
factory Students.fromJson(Map<String, dynamic> srcJson) => _$StudentsFromJson(srcJson);
Map<String, dynamic> toJson() => _$StudentsToJson(this);
}
@JsonSerializable()
class Dtls extends Object {
@JsonKey(name: 'id')
String id;
@JsonKey(name: 'classId')
String? classId;
@JsonKey(name: 'studentId')
int studentId;
@JsonKey(name: 'studentName')
String? studentName;
@JsonKey(name: 'templateId')
int? templateId;
@JsonKey(name: 'questionNo')
int questionNo;
@JsonKey(name: 'questionType')
int questionType;
@JsonKey(name: 'studentAnswer')
String? studentAnswer;
@JsonKey(name: 'state')
int state;
@JsonKey(name: 'useTime')
int useTime;
@JsonKey(name: 'annotatePicture')
String? annotatePicture;
Dtls(this.id,this.classId,this.studentId,this.templateId,this.questionNo,this.questionType,this.studentAnswer,this.state,this.useTime,this.annotatePicture,this.studentName);
factory Dtls.fromJson(Map<String, dynamic> srcJson) => _$DtlsFromJson(srcJson);
Map<String, dynamic> toJson() => _$DtlsToJson(this);
}

View File

@ -43,28 +43,34 @@ class Items extends Object {
String publishTime; String publishTime;
@JsonKey(name: 'state') @JsonKey(name: 'state')
int state; int? state;
@JsonKey(name: 'collectRate') @JsonKey(name: 'collectRate')
int? collectRate; int? collectRate;
@JsonKey(name: 'questionCount')
int? questionCount;
@JsonKey(name: 'annotateCount')
int annotateCount;
@JsonKey(name: 'annotateRate') @JsonKey(name: 'annotateRate')
double annotateRate; double annotateRate;
@JsonKey(name: 'classes') @JsonKey(name: 'classes')
List<Classes> classes; List<Classes>? classes;
@JsonKey(name: 'creatorName') @JsonKey(name: 'creatorName')
String creatorName; String? creatorName;
@JsonKey(name: 'creationTime') @JsonKey(name: 'creationTime')
String creationTime; String? creationTime;
@JsonKey(name: 'classCount') @JsonKey(name: 'classCount')
int? classCount; int? classCount;
Items(this.id,this.assessType,this.name,this.grade,this.subject,this.publishTime,this.state,this.collectRate,this.annotateRate,this.classes,this.creatorName,this.creationTime,this.classCount); Items(this.id,this.assessType,this.name,this.grade,this.subject,this.publishTime,this.state,this.collectRate,this.questionCount,this.annotateCount,this.annotateRate,this.classes,this.creatorName,this.creationTime,this.classCount);
factory Items.fromJson(Map<String, dynamic> srcJson) => _$ItemsFromJson(srcJson); factory Items.fromJson(Map<String, dynamic> srcJson) => _$ItemsFromJson(srcJson);

View File

@ -21,11 +21,11 @@ class WorkStudentParams extends Object {
@JsonKey(name: 'State') @JsonKey(name: 'State')
int? state; int? state;
@JsonKey(name: 'PublishTimeStart') @JsonKey(name: 'StartDate')
String? publishTimeStart; String? startDate;
@JsonKey(name: 'PublishTimeEnd') @JsonKey(name: 'EndDate')
String? publishTimeEnd; String? endDate;
@JsonKey(name: 'CreatorId') @JsonKey(name: 'CreatorId')
String? creatorId; String? creatorId;
@ -39,7 +39,7 @@ class WorkStudentParams extends Object {
@JsonKey(name: 'Sorting') @JsonKey(name: 'Sorting')
String? sorting; String? sorting;
WorkStudentParams({this.assessType = 0,this.name,this.grade,this.subject,this.state,this.publishTimeStart,this.publishTimeEnd,this.creatorId,this.pageNumber = 1,this.pageSize = 10,this.sorting,}); WorkStudentParams({this.assessType = 0,this.name,this.grade,this.subject,this.state,this.startDate,this.endDate,this.creatorId,this.pageNumber = 1,this.pageSize = 10,this.sorting,});
factory WorkStudentParams.fromJson(Map<String, dynamic> srcJson) => _$WorkStudentParamsFromJson(srcJson); factory WorkStudentParams.fromJson(Map<String, dynamic> srcJson) => _$WorkStudentParamsFromJson(srcJson);

View File

@ -62,7 +62,6 @@ class UserStore extends GetxController with RequestToolMixin {
} }
void getEnum() async{ void getEnum() async{
await getSubjectList();
await getGradeList(); await getGradeList();
} }
@ -99,14 +98,16 @@ class UserStore extends GetxController with RequestToolMixin {
// //
getSubjectList() async { getSubjectList() async {
var res = await getClient().getEnumSubjectList('EnumSubject'); // var res = await getClient().getEnumSubjectList();
subjectList.value = res['EnumSubject']!;
} }
// //
getGradeList() async { getGradeList() async {
var res = await getClient().getEnumSubjectList('EnumGrade');
var res = await getClient().getEnumSubjectList(['EnumGrade','EnumSubject']);
gradeList.value = res['EnumGrade']!; gradeList.value = res['EnumGrade']!;
subjectList.value = res['EnumSubject']!;
} }

View File

@ -3,7 +3,7 @@ import 'package:school_asignment_app/common/store/user_store.dart';
class EnumUtils{ class EnumUtils{
static String formatSubject(int id) { static String formatSubject(int id) {
if (UserStore.to.subjectList.isEmpty) { if (UserStore.to.subjectList.isEmpty || id == null) {
return ''; return '';
} }
EnumSubject item = UserStore.to.subjectList.firstWhere((element) => element.id == id); EnumSubject item = UserStore.to.subjectList.firstWhere((element) => element.id == id);
@ -11,7 +11,7 @@ class EnumUtils{
} }
static String formatGrade(int id) { static String formatGrade(int id) {
if (UserStore.to.gradeList.isEmpty) { if (UserStore.to.gradeList.isEmpty || id == null) {
return ''; return '';
} }
EnumSubject item = UserStore.to.gradeList.firstWhere((element) => element.id == id); EnumSubject item = UserStore.to.gradeList.firstWhere((element) => element.id == id);

View File

@ -1,6 +1,8 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:school_asignment_app/common/job/homework_details.dart';
import 'package:school_asignment_app/page/home_page/children/quick_data_check/quick_data_check_state.dart';
class Utils{ class Utils{
Utils._internal(); Utils._internal();
@ -36,4 +38,111 @@ class Utils{
return defaultVal ?? ''; return defaultVal ?? '';
} }
} }
///
static String doubleToStringAsFixed(double val, {int fractionDigits = 2}) {
return val.toStringAsFixed(fractionDigits).replaceAll(RegExp(r'\.0*$'), '');
}
static calcRate (int divisor, int dividend) {
if(dividend != 0){
return ((100 * divisor) / dividend);
// return ((100 * divisor) / dividend).toStringAsFixed(0);
}else{
return 0;
}
}
static getHomeworkData(HomeworkDetails data){
CountData dataCount = CountData();
List<Dtls> kgt = data.dtls.where((w) => w.questionType == 1).toList();
dataCount.kgtAnswerCount = kgt.where((w) => w.state != 0).length;
dataCount.kgtOkCount = kgt.where((w) => w.state == 4).length;
dataCount.kgtDtlCount = kgt.length;
dataCount.kgtAnswerRate = Utils.calcRate(dataCount.kgtAnswerCount!, dataCount.kgtDtlCount!);
dataCount.kgtOkRate = Utils.calcRate(dataCount.kgtOkCount!, dataCount.kgtDtlCount!);
dataCount.kgtCount = data.questions.where((w) => w.questionType == 1).length;
List<Dtls> zgt = data.dtls.where((w) => w.questionType == 2).toList();
dataCount.zgtAnswerCount = zgt.where((w) => w.state != 0).length;
dataCount.zgtOkCount = zgt.where((w) => w.state == 4).length;
dataCount.zgtDtlCount = zgt.length;
dataCount.zgtAnswerRate = Utils.calcRate(dataCount.zgtAnswerCount!, dataCount.zgtDtlCount!);
dataCount.zgtOkRate = Utils.calcRate(dataCount.zgtOkCount!, dataCount.zgtDtlCount!);
dataCount.zgtCount = data.questions.where((w) => w.questionType == 2).length;
dataCount.studentCount = data.students.length;
dataCount.priorityStudents = data.students.where((w) => w.priorityAnnotate).toList();
for(var que in data.questions){
List<Dtls> ques = data.dtls.where((w) => w.templateId == que.templateId && w.questionNo == que.questionNo).toList();
que.answerCount = ques.where((w) => w.state != 0).length;
que.answerRate = Utils.calcRate(que.answerCount!, dataCount.studentCount!);
int okCount = ques.where((w) => w.state == 4).length;
que.okRate = Utils.calcRate(okCount, dataCount.studentCount!) ;
que.priorityInfo = ques.where((w) {
return dataCount.priorityStudents!.indexWhere((s) {
w.studentName = s.studentName;
return s.studentId == w.studentId;
}) > -1 && w.state != 4;
}).toList();
que.answerNgStudents = ques.where((w) {
w.studentName = data.students.firstWhere((s) => s.studentId == w.studentId).studentName;
return w.state == 2;
}).toList();
que.noAnswerStudents = ques.where((w) {
return w.state == 0;
}).toList();
que.answerOkStudents = ques.where((w) {
return w.state == 4;
}).toList();
}
dataCount.studentSubmitCount = data.students.where((s) => s.state != 0).length;
for(var stu in data.students){
stu.kgtStu = kgt.where((w) => w.studentId == stu.studentId).toList();
stu.kgtStu!.sort((a, b) => a.questionNo.compareTo(b.questionNo));
stu.kgtOkCount = stu.kgtStu!.where((w) => w.state == 4).length;
stu.kgtErrorCount = stu.kgtStu!.where((w) => w.state == 2).length;
stu.kgtAnswerCount = stu.kgtStu!.where((w) => w.state != 0).length;
stu.zgtStu = zgt.where((w) => w.studentId == stu.studentId).toList();
stu.zgtStu!.sort((a, b) => a.questionNo.compareTo(b.questionNo));
stu.zgtOkCount = stu.zgtStu!.where((w) => w.state == 4).length;
stu.zgtErrorCount = stu.zgtStu!.where((w) => w.state == 2).length;
stu.zgtUnrated = stu.zgtStu!.where((w) => w.state == 1).length;
stu.zgtAnswerCount = stu.zgtStu!.where((w) => w.state != 0).length;
stu.allOk = data.dtls.where((w) => w.studentId == stu.studentId && w.state != 4).length??0;
if( (stu.kgtStu!.length - stu.kgtAnswerCount!) + (stu.zgtStu!.length-stu.zgtAnswerCount!) == (stu.kgtStu!.length + stu.zgtStu!.length)){
stu.allNotDone = true;
}else{
stu.allNotDone = false;
}
}
data.students.sort((a, b) {
int num1 = a.state;
int num2 = b.state;
return num2.compareTo(num1);
});
for(var know in data.knows){
List<Questions> ques = data.questions.where((w) => w.knows.indexWhere((k) => k.knowledgeId == know.knowledgeId) > -1).toList();
List<Dtls> queDtls = data.dtls.where((w) => ques.indexWhere((q) => w.templateId == q.templateId && w.questionNo == q.questionNo) > -1).toList();
know.okCount = queDtls.where((w) => w.state == 4).length;
know.ttlCount = queDtls.length;
know.okRate = Utils.calcRate(know.okCount!, know.ttlCount!);
}
return dataCount;
}
} }

View File

@ -0,0 +1,26 @@
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:school_asignment_app/common/config/request_config.dart';
class ImageDialog{
static void showImgDialog(BuildContext context,String imgUrl) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
// insetPadding: EdgeInsets.symmetric(vertical: 10.r,horizontal: 45.r),
backgroundColor: Colors.transparent,
contentPadding: EdgeInsets.all(0),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(15.r))),
content: Container(
width: MediaQuery.of(context).size.width - 48.r,
// height: MediaQuery.of(context).size.height * 0.4,
color: Colors.white,
// child: PhotoView(imageProvider: NetworkImage(imgUrl),backgroundDecoration: BoxDecoration(color: Colors.transparent),)),
child: Image.network(RequestConfig.imgUrl+imgUrl)),
);
},
);
}
}

View File

@ -0,0 +1,152 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:school_asignment_app/common/job/homework_details.dart';
import 'package:school_asignment_app/common/utils/utils.dart';
import 'package:school_asignment_app/page/home_page/children/quick_data_check/widget/report_table.dart';
class KgtZgtTable extends StatefulWidget {
final int studentCount;
final String homeworkId;
final List<Questions> kgReport;
final List<Questions> zgReport;
final String kgtOkRate;
final String zgtOkRate;
const KgtZgtTable(
{Key? key,
required this.studentCount,
required this.homeworkId,
required this.kgReport,
required this.zgReport,
required this.kgtOkRate,
required this.zgtOkRate})
: super(key: key);
@override
State<KgtZgtTable> createState() => _KgtZgtTableState();
}
class _KgtZgtTableState extends State<KgtZgtTable> {
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Column(
children: [
//
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: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
'客观题',
style: TextStyle(
fontSize: 14.sp,
color: Color(0xFF5C5C5C),
fontWeight: FontWeight.w600),
),
SizedBox(
width: 10.r,
),
Text(
'${widget.kgtOkRate}%',
style: TextStyle(
fontSize: 14.sp,
color: Color(0xFF6888FD),
fontWeight: FontWeight.w600),
),
],
),
SizedBox(
height: 6.r,
),
SizedBox(
height: widget.kgReport.length > 10
? 300.r
: widget.kgReport.length * 40.r +
(Utils.isPad() == true ? 40.r : 65.r),
child: ReportTable(
headList: const ['', '作答率', '作答人数', '正确率', '标准答案', '优先批阅概况'],
bodyList: widget.kgReport,
fixedCols: 1,
fixedRows: 1,
jobId: widget.homeworkId,
studentCount: widget.studentCount,
),
)
],
),
),
//
Container(
padding: EdgeInsets.symmetric(vertical: 10.r, horizontal: 14.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: const Color(0xFF5C5C5C),
fontWeight: FontWeight.w600),
),
SizedBox(
width: 6.r,
),
Text(
'${widget.zgtOkRate}%',
style: TextStyle(
fontSize: 14.sp,
color: const Color(0xFF6888FD),
fontWeight: FontWeight.w600),
),
],
),
SizedBox(
height: 10.r,
),
SizedBox(
height: widget.zgReport.length > 10
? 300.r
: widget.zgReport.length * 40.r +
(Utils.isPad() == true ? 40.r : 65.r),
child: ReportTable(
headList: const ['', '作答率', '作答人数', '正确率', '查看原题', '优先批阅概况'],
bodyList: widget.zgReport,
fixedCols: 1,
fixedRows: 1,
isKG: true,
jobId: widget.homeworkId,
studentCount: widget.studentCount,
),
)
],
),
),
],
);
}
}

View File

@ -0,0 +1,257 @@
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:school_asignment_app/common/job/homework_details.dart';
import 'package:school_asignment_app/page/home_page/children/quick_data_check/widget/quick_student_data_table.dart';
class QuickDataCheckBottom extends StatefulWidget {
final String jobId;
final int kgCount;
final int zgCount;
final List<Students>? jobData;
const QuickDataCheckBottom(
{Key? key, required this.jobId, required this.jobData, required this.kgCount, required this.zgCount})
: super(key: key);
@override
State<QuickDataCheckBottom> createState() => _QuickDataCheckBottomState();
}
class _QuickDataCheckBottomState extends State<QuickDataCheckBottom> {
RxList<Students> showList = RxList();
RxList<Students> followList = RxList();
RxBool sortType = true.obs;
RxBool sortLevel = false.obs;
void initState() {
super.initState();
showList.value = widget.jobData!;
for (var e in widget.jobData!) {
if(e.priorityAnnotate){
followList.add(e);
}
}
}
@override
Widget build(BuildContext context) {
return 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(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
InkWell(
onTap: () {
sortType.value = !sortType.value;
sortLevel.value = false;
if (widget.jobData == null) return;
if (!sortType.value) {
showList.sort((a, b) {
return a.state.compareTo(b.state);
});
} else {
showList.sort((a, b) {
return b.state.compareTo(a.state);
});
}
},
child: Obx(() {
return Row(
children: [
if (!sortType.value)
Image.asset(
'assets/images/no_check_icon.png',
width: 16.r,
height: 16.r,
),
if (sortType.value)
Image.asset(
'assets/images/check_icon.png',
width: 16.r,
height: 16.r,
),
SizedBox(
width: 5.r,
),
Text(
sortType.value ? '已提交排序' : '未提交排序',
style:
TextStyle(fontSize: 12.sp, color: Color(0xFF707070)),
),
],
);
}),
),
SizedBox(
width: 20.r,
),
InkWell(
onTap: () {
if (widget.jobData!.isEmpty) return;
if (!sortLevel.value) {
showList.value = followList.value;
} else {
widget.jobData!.sort((a, b) {
int num1 = a.state;
int num2 = b.state;
return num2.compareTo(num1);
});
showList.value = widget.jobData!;
}
sortLevel.value = !sortLevel.value;
sortType.value = false;
},
child: Obx(() {
return Row(
children: [
if (!sortLevel.value)
Image.asset(
'assets/images/no_check_icon.png',
width: 16.r,
height: 16.r,
),
if (sortLevel.value)
Image.asset(
'assets/images/check_icon.png',
width: 16.r,
height: 16.r,
),
SizedBox(
width: 5.r,
),
Text(
'看关注学生',
style: TextStyle(
fontSize: 12.sp, color: const Color(0xFF707070)),
),
],
);
}),
),
],
),
SizedBox(
height: 10.r,
),
Row(
children: [
Text(
'注:',
style:
TextStyle(fontSize: 8.sp, color: const Color(0xFF717171)),
),
Container(
width: 10.r,
height: 10.r,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(5.r)),
color: const Color(0xFF4CC793),
),
),
SizedBox(
width: 2.r,
),
Text(
'正确',
style: TextStyle(fontSize: 8.sp, color: Color(0xFF717171)),
),
SizedBox(
width: 15.r,
),
Container(
width: 10.r,
height: 10.r,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(5.r)),
color: const Color(0xFFFF7474),
),
),
SizedBox(
width: 2.r,
),
Text(
'错误',
style: TextStyle(fontSize: 8.sp, color: const Color(0xFF717171)),
),
SizedBox(
width: 15.r,
),
Container(
width: 10.r,
height: 10.r,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(5.r)),
color: Colors.white,
// border: Border.all(width: 1.r,color: Colors.grey),
boxShadow: [
BoxShadow(
color: Colors.grey,
offset: Offset(1.w, 1.h), //y轴偏移量
blurRadius: 4, //
spreadRadius: 0.1, //
)
],
),
),
SizedBox(
width: 2.r,
),
Text(
'已作答未批阅',
style: TextStyle(fontSize: 8.sp, color: const Color(0xFF717171)),
),
SizedBox(
width: 15.r,
),
Container(
width: 10.r,
height: 10.r,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(5.r)),
color: const Color(0xFFD3D3D3),
),
),
SizedBox(
width: 2.r,
),
Text(
'未做',
style: TextStyle(
fontSize: 8.sp, color: const Color(0xFF717171)),
),
],
),
SizedBox(
height: 10.r,
),
Obx(() {
return SizedBox(
height: showList.value.length > 5 ? 350.r : showList.value
.length * 50.r + 40.r,
child: QuickStudentDataTable(
headList: ['学生姓名', '客观题', '主观题', '客观题状态', '主观题状态', '未批阅'],
bodyList: showList.value,
jobId: widget.jobId,
fixedRows: 1,
fixedCols: 0,
// hasUnrated: widget.jobData!.hasUnrated,
hasUnrated: false,
kgCount: widget.kgCount,
zgCount: widget.zgCount,
),
);
})
],
),
);
}
}

View File

@ -0,0 +1,272 @@
import 'package:data_table_2/data_table_2.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:school_asignment_app/common/job/homework_details.dart';
class QuickStudentDataTable extends StatefulWidget {
final List headList;
final List bodyList;
final int? fixedRows;
final int? fixedCols;
final String jobId;
final bool hasUnrated;
final int kgCount;
final int zgCount;
const QuickStudentDataTable({
Key? key,
required this.headList,
required this.bodyList,
required this.jobId,
required this.hasUnrated,
required this.kgCount,
required this.zgCount,
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;
final bool _sortAscending = true;
DataRow _getRow(int index, [Color? color]) {
assert(index >= 0);
Students item = widget.bodyList[index];
return DataRow2.byIndex(
index: index,
color: color != null
? item.allNotDone!
? MaterialStateProperty.all(Color(0xFFFFD79C))
: MaterialStateProperty.all(color)
: null,
cells: [
DataCell(InkWell(
onTap: () {
/*RouterManager.router.navigateTo(
context,
RouterManager.quickCheckPersonalPath +
'?jobId=${widget.jobId}&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: 10.sp, color: const Color(0xFF6888FD),overflow: TextOverflow.ellipsis)),
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: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'${item.kgtOkCount}',
style: TextStyle(fontSize: 10.sp, color: Color(0xFF4CC793))),
Text(
'/',
style: TextStyle(fontSize: 10.sp, color: Color(0xFF525252))),
Text(
'${item.kgtErrorCount}',
style: TextStyle(fontSize: 10.sp, color: Color(0xFFFF7474))),
],
),
),
)),
DataCell(Center(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 5.r),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'${item.zgtOkCount}',
style: TextStyle(fontSize: 10.sp, color: Color(0xFF4CC793))),
Text(
'/',
style: TextStyle(fontSize: 10.sp, color: Color(0xFF525252))),
Text(
'${item.zgtErrorCount}',
style: TextStyle(fontSize: 10.sp, color: Color(0xFFFF7474))),
],
),
),
)),
DataCell(
Padding(
padding: EdgeInsets.symmetric(vertical: 2.r, horizontal: 5.r),
child: SingleChildScrollView(
child: Wrap(
direction: Axis.horizontal,
alignment: WrapAlignment.start,
spacing: 2,
runSpacing: 3,
children: List.generate(item.kgtStu!.length, (index) {
Dtls kgInfo = item.kgtStu![index];
return Container(
width: 14.r,
height: 14.r,
decoration: BoxDecoration(
color: kgInfo.state == 0
? const Color(0xFFD3D3D3)
: kgInfo.state == 1?Colors.white:kgInfo.state == 2
? const Color(0xFFFF7474)
: const Color(0xFF4CC793),
borderRadius: BorderRadius.all(Radius.circular(7.r))),
child: Center(
child: Text(
kgInfo.questionNo.toString(),
style: TextStyle(
fontSize: 8.sp,
color: kgInfo.state == 1
? Color(0xFF525252)
: Colors.white),
)),
);
})),
),
),
),
DataCell(
Padding(
padding: EdgeInsets.symmetric(vertical: 2.r, horizontal: 5.r),
child: SingleChildScrollView(
child: Wrap(
direction: Axis.horizontal,
alignment: WrapAlignment.start,
spacing: 2,
runSpacing: 3,
children: List.generate(item.zgtStu!.length, (index) {
Dtls kgInfo = item.zgtStu![index];
return Container(
width: 14.r,
height: 14.r,
decoration: BoxDecoration(
color: kgInfo.state == 0
? const Color(0xFFD3D3D3)
: kgInfo.state == 1?Colors.white:kgInfo.state == 2
? const Color(0xFFFF7474)
: const Color(0xFF4CC793),
borderRadius: BorderRadius.all(Radius.circular(7.r))),
child: Center(
child: Text(
kgInfo.questionNo.toString(),
style: TextStyle(
fontSize: 8.sp,
color: kgInfo.state == 1
? Color(0xFF525252)
: Colors.white),
)),
);
})),
),
),
),
if(widget.hasUnrated)
DataCell(Center(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 5.r),
child: Text('${item.zgtUnrated}',
style:
TextStyle(fontSize: 10.sp, color: const Color(0xFF6888FD))),
),
)),
],
);
}
@override
Widget build(BuildContext context) {
if(!widget.hasUnrated){
widget.headList.removeLast();
}
return DataTable2(
dividerThickness: 0,
scrollController: _controller,
columnSpacing: 0,
horizontalMargin: 0,
bottomMargin: 0,
dataRowHeight: 50.r,
border: const TableBorder(
horizontalInside: BorderSide(
width: 1, color: Colors.white, style: BorderStyle.solid),
bottom: BorderSide(
width: 1, color: Colors.white, style: BorderStyle.solid),
verticalInside: BorderSide(
width: 1, color: Colors.white, style: BorderStyle.solid)),
headingRowColor: MaterialStateProperty.resolveWith((states) =>
widget.fixedCols! > 0 ? Colors.white : Colors.transparent),
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 index == 1?DataColumn2(
label: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(item,
style: TextStyle(fontSize: 10.sp, color: Color(0xFF505767))),
Text('(${widget.kgCount})',
style: TextStyle(fontSize: 8.sp, color: Color(0xFF505767))),
]
),
// size: ColumnSize.S,
fixedWidth: (MediaQuery.of(context).size.width - 20.r - 28.r) / widget.headList.length,
):index == 2?DataColumn2(
label: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(item,
style: TextStyle(fontSize: 10.sp, color: Color(0xFF505767))),
Text('(${widget.zgCount})',
style: TextStyle(fontSize: 8.sp, color: Color(0xFF505767))),
]
),
// size: ColumnSize.S,
fixedWidth: (MediaQuery.of(context).size.width - 20.r - 28.r) / widget.headList.length,
):DataColumn2(
label: Center(
child: Text(item,
style: TextStyle(fontSize: 10.sp, color: Color(0xFF505767))),
),
// size: ColumnSize.S,
fixedWidth: (MediaQuery.of(context).size.width - 20.r - 28.r) / widget.headList.length,
);
}),
rows: List<DataRow>.generate(widget.bodyList.length,
(index) => _getRow(index, Color(0xFFF5F5F5))));
}
}

View File

@ -0,0 +1,467 @@
import 'package:data_table_2/data_table_2.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:school_asignment_app/common/job/annotated_class.dart';
import 'package:school_asignment_app/common/job/homework_details.dart';
import 'package:school_asignment_app/common/utils/toast_utils.dart';
import 'package:school_asignment_app/common/utils/utils.dart';
import 'package:school_asignment_app/page/global_widget/MyEmptyWidget.dart';
import 'package:school_asignment_app/page/global_widget/imgDialog.dart';
class ReportTable extends StatefulWidget {
final List headList;
final List bodyList;
final int? fixedRows;
final int? fixedCols;
final bool? isKG;
final String jobId;
final int studentCount;
const ReportTable({
Key? key,
required this.headList,
required this.bodyList,
required this.jobId,
required this.studentCount,
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;
final bool _sortAscending = true;
void showPeopleListDialog(
{required BuildContext context,
required String title,
required String questionNo,
required List arr,
List? dcList}) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
// insetPadding: EdgeInsets.symmetric(vertical: 20.r,horizontal: 20.r),
contentPadding: EdgeInsets.all(20.r),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(15.r))),
content: SizedBox(
width: MediaQuery.of(context).size.width * 0.7,
height: MediaQuery.of(context).size.height * 0.7,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Center(
child: Text(
title,
style: TextStyle(
fontSize: 15.sp,
color: const Color(0xFF3C3C3C),
fontWeight: FontWeight.w500),
),
),
SizedBox(
height: 5.r,
),
Row(
children: [
Text(
widget.isKG == true ? '主观题' : '客观题',
style: TextStyle(
fontSize: 14.sp, color: const Color(0xFF436CFF)),
),
Text(
'',
style: TextStyle(
fontSize: 14.sp, color: const Color(0xFF436CFF)),
),
Text(
'$questionNo题',
style: TextStyle(
fontSize: 14.sp, color: Color(0xFF436CFF)),
),
],
),
SizedBox(
height: 15.r,
),
dcList != null
? Row(
children: [
Expanded(
flex: 1,
child: Center(
child: Text(
'未作答人',
style: TextStyle(
fontSize: 12.sp,
color: Color(0xFF6A6A6A)),
))),
Expanded(
flex: 1,
child: Center(
child: Text(
'答对人数',
style: TextStyle(
fontSize: 12.sp,
color: Color(0xFF6A6A6A)),
))),
Expanded(
flex: 1,
child: Center(
child: Text(
'答错人',
style: TextStyle(
fontSize: 12.sp,
color: Color(0xFF6A6A6A)),
))),
],
)
: Padding(
padding: EdgeInsets.only(left: 15.r),
child: Text(
title,
style: TextStyle(
fontSize: 12.sp, color: Color(0xFF6A6A6A)),
),
),
SizedBox(
height: 5.r,
),
if (dcList != null)
Expanded(
child: ListView.builder(
shrinkWrap: true,
itemBuilder: (context, index) {
var item = arr[index];
return Container(
padding: EdgeInsets.symmetric(vertical: 5.r),
color:
index.isOdd ? Colors.white : Color(0xFFF0F0F0),
child: Row(
children: [
Expanded(
flex: 1,
child: InkWell(
onTap: () {
goQuickCheckPersonalPath(
item['noAnswerStudents'].id);
},
child: Center(
child: Text(
item['noAnswerStudents']?.studentName??'--',
style: TextStyle(
fontSize: 12.sp,
color: Color(0xFF323232)),
)))),
Expanded(
flex: 1,
child: InkWell(
onTap: () {
goQuickCheckPersonalPath(
item['answerOkStudents'].id);
},
child: Center(
child: Text(
item['answerOkStudents']?.studentName??'--',
style: TextStyle(
fontSize: 12.sp,
color: Color(0xFF323232)),
)))),
Expanded(
flex: 1,
child: InkWell(
onTap: () {
goQuickCheckPersonalPath(
item['answerNgStudents'].id);
},
child: Center(
child: Text(
item['answerNgStudents']?.studentName??'--',
style: TextStyle(
fontSize: 12.sp,
color: Color(0xFF323232)),
)))),
],
),
);
},
itemCount: arr.length,
),
)
else
arr.isNotEmpty
? Expanded(
child: ListView.builder(
shrinkWrap: true,
itemBuilder: (context, index) {
Dtls item = arr[index];
return InkWell(
onTap: () {
goQuickCheckPersonalPath(item.id);
},
child: Container(
padding: EdgeInsets.symmetric(
vertical: 5.r, horizontal: 15.r),
color: index.isOdd
? Colors.white
: Color(0xFFF0F0F0),
child: Text(
item.studentName!??'--',
style: TextStyle(
fontSize: 12.sp,
color: Color(0xFF323232)),
),
),
);
},
itemCount: arr.length,
),
)
: const MyEmptyWidget()
],
),
),
);
});
}
void goQuickCheckPersonalPath(id) {
if (id) {
/*RouterManager.router.navigateTo(
context,
RouterManager.quickCheckPersonalPath +
'?jobId=${widget.jobId}&studentId=$id',
transition: getTransition(),
);*/
}
}
void zdHandle(BuildContext context, String title, String questionNo,
List noAnswerStudents, List answerNgStudents, List answerOkStudents) {
List list = [];
// Questions student = Questions('','',-1,-1,'',-1,'','',[],-1,-1,[] as double?);
print('noAnswerStudents.length=${noAnswerStudents.length}');
print('answerNgStudents.length=${answerNgStudents.length}');
print('answerOkStudents.length=${answerOkStudents.length}');
if (noAnswerStudents.length > answerNgStudents.length &&
noAnswerStudents.length > answerOkStudents.length) {
for (int i = 0; i < noAnswerStudents.length; i++) {
var obj = {
'noAnswerStudents': noAnswerStudents[i],
'answerNgStudents':
answerNgStudents.length > i ? answerNgStudents[i] : null,
'answerOkStudents':
answerOkStudents.length > i ? answerOkStudents[i] : null
};
list.add(obj);
}
} else if (answerNgStudents.length > noAnswerStudents.length &&
answerNgStudents.length > answerOkStudents.length) {
for (int i = 0; i < answerNgStudents.length; i++) {
var obj = {
'noAnswerStudents':
noAnswerStudents.length > i ? noAnswerStudents[i] : null,
'answerNgStudents': answerNgStudents[i],
'answerOkStudents':
answerOkStudents.length > i ? answerOkStudents[i] : null
};
list.add(obj);
}
} else if (answerOkStudents.length > noAnswerStudents.length &&
answerOkStudents.length > answerNgStudents.length) {
for (int i = 0; i < answerOkStudents.length; i++) {
var obj = {
'noAnswerStudents':
noAnswerStudents.length > i ? noAnswerStudents[i] : null,
'answerNgStudents':
answerNgStudents.length > i ? answerNgStudents[i] : null,
'answerOkStudents': answerOkStudents[i]
};
list.add(obj);
}
}
showPeopleListDialog(
context: context,
title: title,
questionNo: questionNo,
arr: list,
dcList: []);
}
void dcHandle(
BuildContext context, String title, String questionNo, List arr) {
showPeopleListDialog(
context: context, title: title, questionNo: questionNo, arr: arr);
}
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.toString(),
style: TextStyle(fontSize: 10.sp, color: const Color(0xFF525252))),
),
)),
DataCell(Center(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 5.r),
child: Text('${item.answerRate.toStringAsFixed(0)}%',
style: TextStyle(fontSize: 10.sp, color: const Color(0xFF525252))),
),
)),
DataCell(InkWell(
onTap: () {
zdHandle(context, '作答人数', item.questionNo.toString(), item.noAnswerStudents,
item.answerNgStudents, item.answerOkStudents);
},
child: Center(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 5.r),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('${item.answerCount}/${widget.studentCount}',
style:
TextStyle(fontSize: 10.sp, color: const Color(0xFF4CC793))),
Image.asset(
'assets/images/green_right_icon.png',
width: 12.r,
height: 12.r,
),
],
),
),
),
)),
DataCell(Center(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 5.r),
child: Text('${item.okRate.toStringAsFixed(0)}%',
style: TextStyle(fontSize: 10.sp, color: Color(0xFF525252))),
),
)),
DataCell(Center(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 5.r),
child: widget.isKG == true
? InkWell(
onTap: () {
if (item.questionPicture == null) {
ToastUtils.showInfo('当前试题没有原题');
}else{
ImageDialog.showImgDialog(context,item.questionPicture);
}
},
child: Text('原题',
style: TextStyle(
fontSize: 10.sp,
color: widget.isKG == true
? const Color(0xFFFF8A00)
: const Color(0xFF4CC793))),
)
: Text(item.answer,
style: TextStyle(
fontSize: 10.sp,
color: widget.isKG == true
? const Color(0xFFFF8A00)
: const Color(0xFF4CC793))),
),
)),
DataCell(InkWell(
onTap: () {
// List<String> parts = item.priorityGeneral.split('');
dcHandle(context, '优先批阅答错人', item.questionNo.toString(),
item.priorityInfo);
},
child: Center(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 5.r),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('${item.priorityInfo.length}人答错',
style:
TextStyle(fontSize: 10.sp, color: const Color(0xFF6888FD))),
Image.asset(
'assets/images/job_data_right_icon.png',
width: 10.r,
height: 10.r,
)
],
),
),
),
)),
],
);
}
@override
Widget build(BuildContext context) {
bool isPadFlag = Utils.isPad();
return DataTable2(
dividerThickness: 0,
scrollController: _controller,
columnSpacing: 0,
horizontalMargin: 0,
dataRowHeight: 40.r,
bottomMargin: 0,
border: const TableBorder(
horizontalInside: BorderSide(
width: 1, color: Colors.white, style: BorderStyle.solid),
bottom: BorderSide(
width: 1, color: Colors.white, style: BorderStyle.solid),
verticalInside: BorderSide(
width: 1, color: Colors.white, style: BorderStyle.solid)),
headingRowColor: MaterialStateProperty.resolveWith((states) =>
widget.fixedCols! > 0 ? Colors.white : Colors.transparent),
headingRowDecoration: BoxDecoration(color: Color(0xFFE6E6E6)),
fixedColumnsColor: Color(0xFFE6E6E6),
fixedCornerColor: Colors.grey[400],
minWidth: widget.headList.length > 6
? 80.r * widget.headList.length
: isPadFlag
? MediaQuery.of(context).size.width
: 85.r * widget.headList.length,
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: 10.sp, color: Color(0xFF505767))),
),
// size: ColumnSize.S,
fixedWidth: index == 0
? 40.r
: widget.headList.length > 6
? 80.r
: isPadFlag
? (MediaQuery.of(context).size.width - 8.r) /
widget.headList.length
: 85.r,
);
}),
rows: List<DataRow>.generate(widget.bodyList.length,
(index) => _getRow(index, Color(0xFFF5F5F5))));
}
}

View File

@ -27,19 +27,24 @@ class ReadOverLogic extends GetxController with RequestToolMixin, GetTickerProvi
); );
getList(); getList();
} }
//
void getList() async { void getList() async {
WorkStudentParams params = WorkStudentParams( WorkStudentParams params = WorkStudentParams(
assessType: state.tabIndex.value, assessType: 0,
); );
WorkStudent data = await getClient().getWorkList(params); WorkStudent data = WorkStudent([], 0);
if(state.tabIndex.value == 0){
data = await getClient().getUnAnnotateList(params);
}else{
data = await getClient().getAnnotatedList(params);
}
state.workList.value = data.items; state.workList.value = data.items;
refreshController1.finishRefresh(); refreshController1.finishRefresh();
refreshController2.finishRefresh(); refreshController2.finishRefresh();
print('state.workList.length='); print('state.workList.length=');
print(state.workList.length); print(state.workList.length);
} }
/// ///
Future<void> onMyRefresh(EasyRefreshController controller, int tab) async { Future<void> onMyRefresh(EasyRefreshController controller, int tab) async {
/* params.page = RequestConfig.basePage.page; /* params.page = RequestConfig.basePage.page;

View File

@ -347,8 +347,7 @@ Widget $reviewedItem({required Items jobTaskItem, required int type, required St
child: Row( child: Row(
crossAxisAlignment: CrossAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.end,
children: [ children: [
quickText( quickText(DateTime.parse(jobTaskItem.publishTime).toString().substring(0,10),
jobTaskItem.publishTime.substring(0, 10),
color: const Color.fromRGBO(97, 97, 97, 1), color: const Color.fromRGBO(97, 97, 97, 1),
size: 10.sp, size: 10.sp,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,

View File

@ -1,10 +1,12 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:percent_indicator/percent_indicator.dart'; import 'package:percent_indicator/percent_indicator.dart';
import 'package:school_asignment_app/common/job/work_student.dart'; import 'package:school_asignment_app/common/job/work_student.dart';
import 'package:school_asignment_app/common/utils/enum_untils.dart'; import 'package:school_asignment_app/common/utils/enum_untils.dart';
import 'package:school_asignment_app/page/global_widget/my_text.dart'; import 'package:school_asignment_app/page/global_widget/my_text.dart';
import 'package:school_asignment_app/common/utils/utils.dart'; import 'package:school_asignment_app/common/utils/utils.dart';
import 'package:school_asignment_app/routes/app_pages.dart';
class TaskListItem extends StatefulWidget { class TaskListItem extends StatefulWidget {
final bool completed; final bool completed;
@ -89,8 +91,7 @@ class _TaskListItemState extends State<TaskListItem> {
child: Row( child: Row(
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
quickText( quickText(DateTime.parse(widget.jobTaskItem.publishTime).toString().substring(0,10),
widget.jobTaskItem.publishTime.substring(0, 10),
color: const Color.fromRGBO(97, 97, 97, 1), color: const Color.fromRGBO(97, 97, 97, 1),
size: 12.sp, size: 12.sp,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
@ -158,6 +159,7 @@ class _TaskListItemState extends State<TaskListItem> {
RouterManager.router.navigateTo(context, url, transition: getTransition()).then((value) { RouterManager.router.navigateTo(context, url, transition: getTransition()).then((value) {
if (value != null && value == true) call(); if (value != null && value == true) call();
});*/ });*/
Get.toNamed(Routes.annotateClassPage,arguments: {'id':widget.jobTaskItem.id,'name':widget.jobTaskItem.name,'grade':widget.jobTaskItem.grade});
}, },
child: Stack( child: Stack(
alignment: const FractionalOffset(0.95, 0), alignment: const FractionalOffset(0.95, 0),
@ -244,7 +246,7 @@ class _TaskListItemState extends State<TaskListItem> {
), ),
quickText(' / ', quickText(' / ',
color: const Color.fromRGBO(130, 130, 130, 1), size: 11.sp, fontWeight: FontWeight.w500), color: const Color.fromRGBO(130, 130, 130, 1), size: 11.sp, fontWeight: FontWeight.w500),
quickText(widget.jobTaskItem.publishTime.substring(0, 16), quickText(DateTime.parse(widget.jobTaskItem.publishTime).toString().substring(0,10),
color: const Color.fromRGBO(97, 97, 97, 1), size: 12.sp), color: const Color.fromRGBO(97, 97, 97, 1), size: 12.sp),
], ],
), ),

View File

@ -0,0 +1,60 @@
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:percent_indicator/percent_indicator.dart';
import 'package:school_asignment_app/common/utils/utils.dart';
import 'package:school_asignment_app/page/global_widget/my_text.dart';
class ProgressBar extends StatefulWidget {
late double? fontSize;
late double? lineHeight;
final String title;
final Color color;
final double percent;
final EdgeInsets padingEdg;
final EdgeInsets marginEdg;
ProgressBar({Key? key,this.fontSize,this.lineHeight,required this.title,required this.color,required this.percent,required this.marginEdg,required this.padingEdg}) : super(key: key);
@override
State<ProgressBar> createState() => _ProgressBarState();
}
class _ProgressBarState extends State<ProgressBar> {
@override
Widget build(BuildContext context) {
var percentStr = '${Utils.doubleToStringAsFixed(widget.percent * 100)}%';
widget.fontSize ??= 10.sp;
widget.lineHeight ??= 8.h;
return Container(
margin: widget.marginEdg,
padding: widget.padingEdg,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
if (widget.title == '总正确率:') quickText('确率', color: Colors.transparent, size: widget.fontSize),
quickText(widget.title, color: const Color(0xFF8B8B8B), size: widget.fontSize),
Expanded(
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.r),
),
child: LinearPercentIndicator(
padding: EdgeInsets.zero,
animation: true,
lineHeight: widget.lineHeight!,
animationDuration: 2500,
percent: widget.percent,
progressColor: widget.color,
backgroundColor: const Color(0xFFE8E8E8),
barRadius: Radius.circular(10.r),
),
),
),
SizedBox(width: 4.w),
// percentStr
quickText(percentStr, size: widget.fontSize, color: const Color(0xFF464646)),
],
),
);
}
}

View File

@ -1,9 +1,15 @@
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:school_asignment_app/page/global_widget/other_page.dart'; import 'package:school_asignment_app/page/global_widget/other_page.dart';
import 'package:school_asignment_app/page/global_widget/start_page.dart'; import 'package:school_asignment_app/page/global_widget/start_page.dart';
import 'package:school_asignment_app/page/home_page/children/annotate_class/annotate_class_binding.dart';
import 'package:school_asignment_app/page/home_page/children/annotate_class/annotate_class_view.dart';
import 'package:school_asignment_app/page/home_page/children/class_student/class_student_binding.dart'; import 'package:school_asignment_app/page/home_page/children/class_student/class_student_binding.dart';
import 'package:school_asignment_app/page/home_page/children/class_student/class_student_view.dart'; import 'package:school_asignment_app/page/home_page/children/class_student/class_student_view.dart';
import 'package:school_asignment_app/page/home_page/children/job_report/job_report_binding.dart';
import 'package:school_asignment_app/page/home_page/children/job_report/job_report_view.dart';
import 'package:school_asignment_app/page/home_page/children/my_info.dart'; import 'package:school_asignment_app/page/home_page/children/my_info.dart';
import 'package:school_asignment_app/page/home_page/children/quick_data_check/quick_data_check_binding.dart';
import 'package:school_asignment_app/page/home_page/children/quick_data_check/quick_data_check_view.dart';
import 'package:school_asignment_app/page/home_page/children/read_over/read_over_binding.dart'; import 'package:school_asignment_app/page/home_page/children/read_over/read_over_binding.dart';
import 'package:school_asignment_app/page/home_page/children/read_over/read_over_view.dart'; import 'package:school_asignment_app/page/home_page/children/read_over/read_over_view.dart';
import 'package:school_asignment_app/page/home_page/children/student_history_work/student_history_work_binding.dart'; import 'package:school_asignment_app/page/home_page/children/student_history_work/student_history_work_binding.dart';
@ -29,5 +35,9 @@ abstract class AppPages {
GetPage(name: Routes.readOverPage, page: () => const ReadOverPage(), binding: ReadOverBinding(), transition: Transition.noTransition), GetPage(name: Routes.readOverPage, page: () => const ReadOverPage(), binding: ReadOverBinding(), transition: Transition.noTransition),
GetPage(name: Routes.studentHistoryWorkPage, page: () => const StudentHistoryWorkPage(), binding: StudentHistoryWorkBinding(), transition: Transition.noTransition), GetPage(name: Routes.studentHistoryWorkPage, page: () => const StudentHistoryWorkPage(), binding: StudentHistoryWorkBinding(), transition: Transition.noTransition),
GetPage(name: Routes.classStudentPage, page: () => const ClassStudentPage(), binding: ClassStudentBinding(), transition: Transition.noTransition), GetPage(name: Routes.classStudentPage, page: () => const ClassStudentPage(), binding: ClassStudentBinding(), transition: Transition.noTransition),
GetPage(name: Routes.annotateClassPage, page: () => const AnnotateClassPage(), binding: AnnotateClassBinding(), transition: Transition.noTransition),
GetPage(name: Routes.quickDataCheckPage, page: () => const QuickDataCheckPage(), binding: QuickDataCheckBinding(), transition: Transition.noTransition),
GetPage(name: Routes.jobReportPage, page: () => const JobReportPage(), binding: JobReportBinding(), transition: Transition.noTransition),
]; ];
} }

View File

@ -11,4 +11,7 @@ abstract class Routes {
static const readOverPage = '/readOverPage'; static const readOverPage = '/readOverPage';
static const studentHistoryWorkPage = '/studentHistoryWorkPage'; static const studentHistoryWorkPage = '/studentHistoryWorkPage';
static const classStudentPage = '/classStudentPage'; static const classStudentPage = '/classStudentPage';
static const annotateClassPage = '/annotateClassPage';
static const quickDataCheckPage = '/quickDataCheckPage';
static const jobReportPage = '/jobReportPage';
} }

View File

@ -233,6 +233,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.3.6" version: "2.3.6"
data_table_2:
dependency: "direct main"
description:
name: data_table_2
sha256: e403de6d9a58dddf27700114b614ea8ea5aa8442d7fbdfbe8b3d11b0512e7a49
url: "https://pub.dev"
source: hosted
version: "2.5.12"
dbus: dbus:
dependency: transitive dependency: transitive
description: description:
@ -249,6 +257,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "5.4.2+1" version: "5.4.2+1"
equatable:
dependency: transitive
description:
name: equatable
sha256: c2b87cb7756efdf69892005af546c56c0b5037f54d2a88269b4f347a505e3ca2
url: "https://pub.dev"
source: hosted
version: "2.0.5"
fake_async: fake_async:
dependency: transitive dependency: transitive
description: description:
@ -281,6 +297,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.1.0" version: "1.1.0"
fl_chart:
dependency: "direct main"
description:
name: fl_chart
sha256: "48a1b69be9544e2b03d9a8e843affd89e43f3194c9248776222efcb4206bb1ec"
url: "https://pub.dev"
source: hosted
version: "0.62.0"
flutter: flutter:
dependency: "direct main" dependency: "direct main"
description: flutter description: flutter

View File

@ -70,6 +70,9 @@ dependencies:
# 进度条 # 进度条
percent_indicator: ^4.2.3 percent_indicator: ^4.2.3
badges: ^3.1.2 badges: ^3.1.2
# 图表
fl_chart: ^0.62.0
data_table_2: ^2.5.10
dev_dependencies: dev_dependencies:
flutter_test: flutter_test: