报告模块
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 3.6 KiB |
|
After Width: | Height: | Size: 48 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 192 B |
|
After Width: | Height: | Size: 743 B |
|
After Width: | Height: | Size: 755 B |
|
|
@ -0,0 +1,204 @@
|
||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
|
part 'detail_base_info.g.dart';
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class DetailBaseInfo extends Object {
|
||||||
|
|
||||||
|
@JsonKey(name: 'BaseInfo')
|
||||||
|
BaseInfo baseInfo;
|
||||||
|
|
||||||
|
@JsonKey(name: 'Module1_CJZL')
|
||||||
|
Module1_CJZL module1CJZL;
|
||||||
|
|
||||||
|
@JsonKey(name: 'Module2_ZDGZ')
|
||||||
|
Module2_ZDGZ module2ZDGZ;
|
||||||
|
|
||||||
|
DetailBaseInfo(this.baseInfo,this.module1CJZL,this.module2ZDGZ,);
|
||||||
|
|
||||||
|
factory DetailBaseInfo.fromJson(Map<String, dynamic> srcJson) => _$DetailBaseInfoFromJson(srcJson);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$DetailBaseInfoToJson(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class BaseInfo extends Object {
|
||||||
|
|
||||||
|
@JsonKey(name: 'ExamName')
|
||||||
|
String examName;
|
||||||
|
|
||||||
|
@JsonKey(name: 'ExamType')
|
||||||
|
String examType;
|
||||||
|
|
||||||
|
@JsonKey(name: 'Grade')
|
||||||
|
String grade;
|
||||||
|
|
||||||
|
@JsonKey(name: 'Subject')
|
||||||
|
String subject;
|
||||||
|
|
||||||
|
@JsonKey(name: 'ExamTime')
|
||||||
|
String examTime;
|
||||||
|
|
||||||
|
@JsonKey(name: 'TotalScore')
|
||||||
|
double totalScore;
|
||||||
|
|
||||||
|
@JsonKey(name: 'AvgScore')
|
||||||
|
double avgScore;
|
||||||
|
|
||||||
|
@JsonKey(name: 'MaxScore')
|
||||||
|
double maxScore;
|
||||||
|
|
||||||
|
@JsonKey(name: 'RateGood')
|
||||||
|
String rateGood;
|
||||||
|
|
||||||
|
@JsonKey(name: 'RatePass')
|
||||||
|
String ratePass;
|
||||||
|
|
||||||
|
BaseInfo(this.examName,this.examType,this.grade,this.subject,this.examTime,this.totalScore,this.avgScore,this.maxScore,this.rateGood,this.ratePass,);
|
||||||
|
|
||||||
|
factory BaseInfo.fromJson(Map<String, dynamic> srcJson) => _$BaseInfoFromJson(srcJson);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$BaseInfoToJson(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class Module1_CJZL extends Object {
|
||||||
|
|
||||||
|
@JsonKey(name: 'BatchNO')
|
||||||
|
String batchNO;
|
||||||
|
|
||||||
|
@JsonKey(name: 'HeadStartRowIndex')
|
||||||
|
int headStartRowIndex;
|
||||||
|
|
||||||
|
@JsonKey(name: 'BodyStartRowIndex')
|
||||||
|
int bodyStartRowIndex;
|
||||||
|
|
||||||
|
@JsonKey(name: 'Sheets')
|
||||||
|
List<Sheets> sheets;
|
||||||
|
|
||||||
|
Module1_CJZL(this.batchNO,this.headStartRowIndex,this.bodyStartRowIndex,this.sheets,);
|
||||||
|
|
||||||
|
factory Module1_CJZL.fromJson(Map<String, dynamic> srcJson) => _$Module1_CJZLFromJson(srcJson);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$Module1_CJZLToJson(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class Sheets extends Object {
|
||||||
|
|
||||||
|
@JsonKey(name: 'SheetName')
|
||||||
|
String? sheetName;
|
||||||
|
|
||||||
|
@JsonKey(name: 'HeadData')
|
||||||
|
List<HeadData> headData;
|
||||||
|
|
||||||
|
@JsonKey(name: 'BodyData')
|
||||||
|
List<List> bodyData;
|
||||||
|
|
||||||
|
@JsonKey(name: 'BodyRowHeightPx')
|
||||||
|
double bodyRowHeightPx;
|
||||||
|
|
||||||
|
@JsonKey(name: 'HeadsRowHeightPx')
|
||||||
|
double headsRowHeightPx;
|
||||||
|
|
||||||
|
Sheets(this.sheetName,this.headData,this.bodyData,this.bodyRowHeightPx,this.headsRowHeightPx,);
|
||||||
|
|
||||||
|
factory Sheets.fromJson(Map<String, dynamic> srcJson) => _$SheetsFromJson(srcJson);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$SheetsToJson(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class HeadData extends Object {
|
||||||
|
|
||||||
|
@JsonKey(name: 'RowData')
|
||||||
|
List<List<String>> rowData;
|
||||||
|
|
||||||
|
@JsonKey(name: 'AutoMerge')
|
||||||
|
bool autoMerge;
|
||||||
|
|
||||||
|
@JsonKey(name: 'TotalMerge')
|
||||||
|
bool totalMerge;
|
||||||
|
|
||||||
|
@JsonKey(name: 'ColumnWidthPx')
|
||||||
|
double columnWidthPx;
|
||||||
|
|
||||||
|
HeadData(this.rowData,this.autoMerge,this.totalMerge,this.columnWidthPx,);
|
||||||
|
|
||||||
|
factory HeadData.fromJson(Map<String, dynamic> srcJson) => _$HeadDataFromJson(srcJson);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$HeadDataToJson(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class Module2_ZDGZ extends Object {
|
||||||
|
|
||||||
|
@JsonKey(name: 'TopExcelData')
|
||||||
|
TopExcelData topExcelData;
|
||||||
|
|
||||||
|
@JsonKey(name: 'BottomExcelData')
|
||||||
|
BottomExcelData bottomExcelData;
|
||||||
|
|
||||||
|
Module2_ZDGZ(this.topExcelData,this.bottomExcelData,);
|
||||||
|
|
||||||
|
factory Module2_ZDGZ.fromJson(Map<String, dynamic> srcJson) => _$Module2_ZDGZFromJson(srcJson);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$Module2_ZDGZToJson(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class TopExcelData extends Object {
|
||||||
|
|
||||||
|
@JsonKey(name: 'HeadStartRowIndex')
|
||||||
|
int headStartRowIndex;
|
||||||
|
|
||||||
|
@JsonKey(name: 'BodyStartRowIndex')
|
||||||
|
int bodyStartRowIndex;
|
||||||
|
|
||||||
|
@JsonKey(name: 'Sheets')
|
||||||
|
List<Sheets> sheets;
|
||||||
|
|
||||||
|
TopExcelData(this.headStartRowIndex,this.bodyStartRowIndex,this.sheets,);
|
||||||
|
|
||||||
|
factory TopExcelData.fromJson(Map<String, dynamic> srcJson) => _$TopExcelDataFromJson(srcJson);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$TopExcelDataToJson(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class BottomExcelData extends Object {
|
||||||
|
|
||||||
|
@JsonKey(name: 'HeadStartRowIndex')
|
||||||
|
int headStartRowIndex;
|
||||||
|
|
||||||
|
@JsonKey(name: 'BodyStartRowIndex')
|
||||||
|
int bodyStartRowIndex;
|
||||||
|
|
||||||
|
@JsonKey(name: 'Sheets')
|
||||||
|
List<Sheets> sheets;
|
||||||
|
|
||||||
|
BottomExcelData(this.headStartRowIndex,this.bodyStartRowIndex,this.sheets,);
|
||||||
|
|
||||||
|
factory BottomExcelData.fromJson(Map<String, dynamic> srcJson) => _$BottomExcelDataFromJson(srcJson);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$BottomExcelDataToJson(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,62 @@
|
||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
|
part 'exam_records.g.dart';
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class ExamRecords extends Object {
|
||||||
|
|
||||||
|
@JsonKey(name: 'Classes')
|
||||||
|
String classes;
|
||||||
|
|
||||||
|
@JsonKey(name: 'ClassIds')
|
||||||
|
Map classIds;
|
||||||
|
|
||||||
|
@JsonKey(name: 'Id')
|
||||||
|
int id;
|
||||||
|
|
||||||
|
@JsonKey(name: 'UserId')
|
||||||
|
int userId;
|
||||||
|
|
||||||
|
@JsonKey(name: 'Name')
|
||||||
|
String name;
|
||||||
|
|
||||||
|
@JsonKey(name: 'Type')
|
||||||
|
int type;
|
||||||
|
|
||||||
|
@JsonKey(name: 'TypeName')
|
||||||
|
String typeName;
|
||||||
|
|
||||||
|
@JsonKey(name: 'Grade')
|
||||||
|
String grade;
|
||||||
|
|
||||||
|
@JsonKey(name: 'Subjects')
|
||||||
|
String subjects;
|
||||||
|
|
||||||
|
@JsonKey(name: 'SubjectStr')
|
||||||
|
String subjectStr;
|
||||||
|
|
||||||
|
@JsonKey(name: 'StartTime')
|
||||||
|
String startTime;
|
||||||
|
|
||||||
|
@JsonKey(name: 'StartTimeStr')
|
||||||
|
String startTimeStr;
|
||||||
|
|
||||||
|
@JsonKey(name: 'Status')
|
||||||
|
int status;
|
||||||
|
|
||||||
|
@JsonKey(name: 'StatusName')
|
||||||
|
String statusName;
|
||||||
|
|
||||||
|
@JsonKey(name: 'CreateTime')
|
||||||
|
String createTime;
|
||||||
|
|
||||||
|
ExamRecords(this.classes,this.classIds,this.id,this.userId,this.name,this.type,this.typeName,this.grade,this.subjects,this.subjectStr,this.startTime,this.startTimeStr,this.status,this.statusName,this.createTime,);
|
||||||
|
|
||||||
|
factory ExamRecords.fromJson(Map<String, dynamic> srcJson) => _$ExamRecordsFromJson(srcJson);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$ExamRecordsToJson(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,141 @@
|
||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
|
part 'exam_records_all.g.dart';
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class ExamRecordsAll extends Object {
|
||||||
|
@JsonKey(name: 'Type')
|
||||||
|
Type type;
|
||||||
|
|
||||||
|
@JsonKey(name: 'Grade')
|
||||||
|
Grade grade;
|
||||||
|
|
||||||
|
@JsonKey(name: 'Subject')
|
||||||
|
Subject subject;
|
||||||
|
|
||||||
|
@JsonKey(name: 'TimePeriod')
|
||||||
|
TimePeriod timePeriod;
|
||||||
|
|
||||||
|
ExamRecordsAll(
|
||||||
|
this.type,
|
||||||
|
this.grade,
|
||||||
|
this.subject,
|
||||||
|
this.timePeriod,
|
||||||
|
);
|
||||||
|
|
||||||
|
factory ExamRecordsAll.fromJson(Map<String, dynamic> srcJson) =>
|
||||||
|
_$ExamRecordsAllFromJson(srcJson);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$ExamRecordsAllToJson(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class Type extends Object {
|
||||||
|
@JsonKey(name: 'IsDisabled')
|
||||||
|
bool isDisabled;
|
||||||
|
|
||||||
|
@JsonKey(name: 'DefaultValue')
|
||||||
|
String defaultValue;
|
||||||
|
|
||||||
|
@JsonKey(name: 'ComboData')
|
||||||
|
List<ComboData> comboData;
|
||||||
|
|
||||||
|
Type(
|
||||||
|
this.isDisabled,
|
||||||
|
this.defaultValue,
|
||||||
|
this.comboData,
|
||||||
|
);
|
||||||
|
|
||||||
|
factory Type.fromJson(Map<String, dynamic> srcJson) =>
|
||||||
|
_$TypeFromJson(srcJson);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$TypeToJson(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class ComboData extends Object {
|
||||||
|
@JsonKey(name: 'Value')
|
||||||
|
dynamic value;
|
||||||
|
|
||||||
|
@JsonKey(name: 'Text')
|
||||||
|
String text;
|
||||||
|
|
||||||
|
@JsonKey(name: 'isCheck')
|
||||||
|
bool isCheck;
|
||||||
|
|
||||||
|
ComboData(this.value, this.text, {this.isCheck = false});
|
||||||
|
|
||||||
|
factory ComboData.fromJson(Map<String, dynamic> srcJson) =>
|
||||||
|
_$ComboDataFromJson(srcJson);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$ComboDataToJson(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class Grade extends Object {
|
||||||
|
@JsonKey(name: 'IsDisabled')
|
||||||
|
bool isDisabled;
|
||||||
|
|
||||||
|
@JsonKey(name: 'DefaultValue')
|
||||||
|
String defaultValue;
|
||||||
|
|
||||||
|
@JsonKey(name: 'ComboData')
|
||||||
|
List<ComboData> comboData;
|
||||||
|
|
||||||
|
Grade(
|
||||||
|
this.isDisabled,
|
||||||
|
this.defaultValue,
|
||||||
|
this.comboData,
|
||||||
|
);
|
||||||
|
|
||||||
|
factory Grade.fromJson(Map<String, dynamic> srcJson) =>
|
||||||
|
_$GradeFromJson(srcJson);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$GradeToJson(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class Subject extends Object {
|
||||||
|
@JsonKey(name: 'IsDisabled')
|
||||||
|
bool isDisabled;
|
||||||
|
|
||||||
|
@JsonKey(name: 'DefaultValue')
|
||||||
|
String defaultValue;
|
||||||
|
|
||||||
|
@JsonKey(name: 'ComboData')
|
||||||
|
List<ComboData> comboData;
|
||||||
|
|
||||||
|
Subject(
|
||||||
|
this.isDisabled,
|
||||||
|
this.defaultValue,
|
||||||
|
this.comboData,
|
||||||
|
);
|
||||||
|
|
||||||
|
factory Subject.fromJson(Map<String, dynamic> srcJson) =>
|
||||||
|
_$SubjectFromJson(srcJson);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$SubjectToJson(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class TimePeriod extends Object {
|
||||||
|
@JsonKey(name: 'IsDisabled')
|
||||||
|
bool isDisabled;
|
||||||
|
|
||||||
|
@JsonKey(name: 'DefaultValue')
|
||||||
|
String defaultValue;
|
||||||
|
|
||||||
|
@JsonKey(name: 'ComboData')
|
||||||
|
List<ComboData> comboData;
|
||||||
|
|
||||||
|
TimePeriod(
|
||||||
|
this.isDisabled,
|
||||||
|
this.defaultValue,
|
||||||
|
this.comboData,
|
||||||
|
);
|
||||||
|
|
||||||
|
factory TimePeriod.fromJson(Map<String, dynamic> srcJson) =>
|
||||||
|
_$TimePeriodFromJson(srcJson);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$TimePeriodToJson(this);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
import 'package:marking_app/common/model/common/base_page_report.dart';
|
||||||
|
|
||||||
|
part 'exam_records_params.g.dart';
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class ExamRecordsParams extends BasePageReport {
|
||||||
|
|
||||||
|
@JsonKey(name: 'SearchStr')
|
||||||
|
String? searchStr;
|
||||||
|
|
||||||
|
@JsonKey(name: 'Grade')
|
||||||
|
String? grade;
|
||||||
|
|
||||||
|
@JsonKey(name: 'ClassId')
|
||||||
|
int? classId;
|
||||||
|
|
||||||
|
@JsonKey(name: 'PositionId')
|
||||||
|
int? positionId;
|
||||||
|
|
||||||
|
@JsonKey(name: 'ReportType')
|
||||||
|
String? reportType;
|
||||||
|
|
||||||
|
@JsonKey(name: 'Subject')
|
||||||
|
int? subject;
|
||||||
|
|
||||||
|
@JsonKey(name: 'TimePeriod')
|
||||||
|
int? timePeriod;
|
||||||
|
|
||||||
|
ExamRecordsParams({this.searchStr = '',this.grade,this.classId = -1,this.positionId = -1,this.reportType,this.subject = -1,this.timePeriod = -1,page,limit}) : super(page, limit);
|
||||||
|
|
||||||
|
factory ExamRecordsParams.fromJson(Map<String, dynamic> srcJson) => _$ExamRecordsParamsFromJson(srcJson);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$ExamRecordsParamsToJson(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,97 @@
|
||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
import 'package:marking_app/common/model/report/detail_base_info.dart';
|
||||||
|
|
||||||
|
part 'question_know_point.g.dart';
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class QuestionKnowPoint extends Object {
|
||||||
|
|
||||||
|
@JsonKey(name: 'QuestionList')
|
||||||
|
List<dynamic> questionList;
|
||||||
|
|
||||||
|
@JsonKey(name: 'UserQuestion')
|
||||||
|
UserQuestion userQuestion;
|
||||||
|
|
||||||
|
@JsonKey(name: 'KnowPointList')
|
||||||
|
List<KnowPointList> knowPointList;
|
||||||
|
|
||||||
|
QuestionKnowPoint(this.questionList,this.userQuestion,this.knowPointList,);
|
||||||
|
|
||||||
|
factory QuestionKnowPoint.fromJson(Map<String, dynamic> srcJson) => _$QuestionKnowPointFromJson(srcJson);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$QuestionKnowPointToJson(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class UserQuestion extends Object {
|
||||||
|
|
||||||
|
@JsonKey(name: 'BatchNO')
|
||||||
|
String batchNO;
|
||||||
|
|
||||||
|
@JsonKey(name: 'HeadStartRowIndex')
|
||||||
|
int headStartRowIndex;
|
||||||
|
|
||||||
|
@JsonKey(name: 'BodyStartRowIndex')
|
||||||
|
int bodyStartRowIndex;
|
||||||
|
|
||||||
|
@JsonKey(name: 'Sheets')
|
||||||
|
List<Sheets> sheets;
|
||||||
|
|
||||||
|
UserQuestion(this.batchNO,this.headStartRowIndex,this.bodyStartRowIndex,this.sheets,);
|
||||||
|
|
||||||
|
factory UserQuestion.fromJson(Map<String, dynamic> srcJson) => _$UserQuestionFromJson(srcJson);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$UserQuestionToJson(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class HeadData extends Object {
|
||||||
|
|
||||||
|
@JsonKey(name: 'RowData')
|
||||||
|
List<List<String>> rowData;
|
||||||
|
|
||||||
|
@JsonKey(name: 'AutoMerge')
|
||||||
|
bool autoMerge;
|
||||||
|
|
||||||
|
@JsonKey(name: 'TotalMerge')
|
||||||
|
bool totalMerge;
|
||||||
|
|
||||||
|
@JsonKey(name: 'ColumnWidthPx')
|
||||||
|
int columnWidthPx;
|
||||||
|
|
||||||
|
HeadData(this.rowData,this.autoMerge,this.totalMerge,this.columnWidthPx,);
|
||||||
|
|
||||||
|
factory HeadData.fromJson(Map<String, dynamic> srcJson) => _$HeadDataFromJson(srcJson);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$HeadDataToJson(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class KnowPointList extends Object {
|
||||||
|
|
||||||
|
@JsonKey(name: 'Name')
|
||||||
|
String name;
|
||||||
|
|
||||||
|
@JsonKey(name: 'QuestionNums')
|
||||||
|
String questionNums;
|
||||||
|
|
||||||
|
@JsonKey(name: 'CorrectRate')
|
||||||
|
String correctRate;
|
||||||
|
|
||||||
|
@JsonKey(name: 'GradeCorrectRate')
|
||||||
|
String gradeCorrectRate;
|
||||||
|
|
||||||
|
KnowPointList(this.name,this.questionNums,this.correctRate,this.gradeCorrectRate,);
|
||||||
|
|
||||||
|
factory KnowPointList.fromJson(Map<String, dynamic> srcJson) => _$KnowPointListFromJson(srcJson);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$KnowPointListToJson(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,92 @@
|
||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
|
part 'report_card.g.dart';
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class ReportCard extends Object {
|
||||||
|
|
||||||
|
@JsonKey(name: 'TotalCount')
|
||||||
|
int totalCount;
|
||||||
|
|
||||||
|
@JsonKey(name: 'Head')
|
||||||
|
List<String> head;
|
||||||
|
|
||||||
|
@JsonKey(name: 'Data')
|
||||||
|
List<Data> data;
|
||||||
|
|
||||||
|
ReportCard(this.totalCount,this.head,this.data,);
|
||||||
|
|
||||||
|
factory ReportCard.fromJson(Map<String, dynamic> srcJson) => _$ReportCardFromJson(srcJson);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$ReportCardToJson(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class Data extends Object {
|
||||||
|
|
||||||
|
@JsonKey(name: 'SubjectDetails')
|
||||||
|
List<SubjectDetails> subjectDetails;
|
||||||
|
|
||||||
|
@JsonKey(name: 'ExamStudentId')
|
||||||
|
String examStudentId;
|
||||||
|
|
||||||
|
@JsonKey(name: 'ExamNo')
|
||||||
|
String examNo;
|
||||||
|
|
||||||
|
@JsonKey(name: 'Name')
|
||||||
|
String name;
|
||||||
|
|
||||||
|
@JsonKey(name: 'ClassName')
|
||||||
|
String className;
|
||||||
|
|
||||||
|
@JsonKey(name: 'TotalScore')
|
||||||
|
double totalScore;
|
||||||
|
|
||||||
|
@JsonKey(name: 'TotalRanking')
|
||||||
|
int totalRanking;
|
||||||
|
|
||||||
|
@JsonKey(name: 'TotalRankingChange')
|
||||||
|
String totalRankingChange;
|
||||||
|
|
||||||
|
@JsonKey(name: 'TotalGradeRanking')
|
||||||
|
int totalGradeRanking;
|
||||||
|
|
||||||
|
@JsonKey(name: 'TotalClassRanking')
|
||||||
|
int totalClassRanking;
|
||||||
|
|
||||||
|
Data(this.subjectDetails,this.examStudentId,this.examNo,this.name,this.className,this.totalScore,this.totalRanking,this.totalRankingChange,this.totalGradeRanking,this.totalClassRanking,);
|
||||||
|
|
||||||
|
factory Data.fromJson(Map<String, dynamic> srcJson) => _$DataFromJson(srcJson);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$DataToJson(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class SubjectDetails extends Object {
|
||||||
|
|
||||||
|
@JsonKey(name: 'Score')
|
||||||
|
String score;
|
||||||
|
|
||||||
|
@JsonKey(name: 'ExamSubjectId')
|
||||||
|
int examSubjectId;
|
||||||
|
|
||||||
|
@JsonKey(name: 'GradeRanking')
|
||||||
|
String gradeRanking;
|
||||||
|
|
||||||
|
@JsonKey(name: 'ClassRanking')
|
||||||
|
String classRanking;
|
||||||
|
|
||||||
|
SubjectDetails(this.score,this.examSubjectId,this.gradeRanking,this.classRanking,);
|
||||||
|
|
||||||
|
factory SubjectDetails.fromJson(Map<String, dynamic> srcJson) => _$SubjectDetailsFromJson(srcJson);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$SubjectDetailsToJson(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
import 'package:marking_app/common/model/common/base_page_report.dart';
|
||||||
|
|
||||||
|
part 'report_card_params.g.dart';
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class ReportCardParams extends BasePageReport {
|
||||||
|
|
||||||
|
@JsonKey(name: 'ExamId')
|
||||||
|
int examId;
|
||||||
|
|
||||||
|
@JsonKey(name: 'ClassId')
|
||||||
|
int classId;
|
||||||
|
|
||||||
|
ReportCardParams({required this.examId,required this.classId,page,limit}):super(page,limit);
|
||||||
|
|
||||||
|
factory ReportCardParams.fromJson(Map<String, dynamic> srcJson) => _$ReportCardParamsFromJson(srcJson);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$ReportCardParamsToJson(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,122 @@
|
||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
|
part 'report_marking_detail.g.dart';
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class ReportMarkingDetail extends Object {
|
||||||
|
|
||||||
|
@JsonKey(name: 'MarkingPagerImgs')
|
||||||
|
List<String> markingPagerImgs;
|
||||||
|
|
||||||
|
@JsonKey(name: 'ExamOriginPapers')
|
||||||
|
List<ExamOriginPapers> examOriginPapers;
|
||||||
|
|
||||||
|
@JsonKey(name: 'QuestionAnswers')
|
||||||
|
List<QuestionAnswers> questionAnswers;
|
||||||
|
|
||||||
|
ReportMarkingDetail(this.markingPagerImgs,this.examOriginPapers,this.questionAnswers,);
|
||||||
|
|
||||||
|
factory ReportMarkingDetail.fromJson(Map<String, dynamic> srcJson) => _$ReportMarkingDetailFromJson(srcJson);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$ReportMarkingDetailToJson(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class ExamOriginPapers extends Object {
|
||||||
|
|
||||||
|
@JsonKey(name: 'PageIndex')
|
||||||
|
int pageIndex;
|
||||||
|
|
||||||
|
@JsonKey(name: 'ImageUrl')
|
||||||
|
String imageUrl;
|
||||||
|
|
||||||
|
@JsonKey(name: 'Width')
|
||||||
|
double width;
|
||||||
|
|
||||||
|
@JsonKey(name: 'Height')
|
||||||
|
double height;
|
||||||
|
|
||||||
|
@JsonKey(name: 'PaperType')
|
||||||
|
int paperType;
|
||||||
|
|
||||||
|
@JsonKey(name: 'Question')
|
||||||
|
List<Question> question;
|
||||||
|
|
||||||
|
ExamOriginPapers(this.pageIndex,this.imageUrl,this.width,this.height,this.paperType,this.question,);
|
||||||
|
|
||||||
|
factory ExamOriginPapers.fromJson(Map<String, dynamic> srcJson) => _$ExamOriginPapersFromJson(srcJson);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$ExamOriginPapersToJson(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class Question extends Object {
|
||||||
|
|
||||||
|
@JsonKey(name: 'QuestionNum')
|
||||||
|
String questionNum;
|
||||||
|
|
||||||
|
@JsonKey(name: 'isObj')
|
||||||
|
bool isObj;
|
||||||
|
|
||||||
|
@JsonKey(name: 'X')
|
||||||
|
double x;
|
||||||
|
|
||||||
|
@JsonKey(name: 'Y')
|
||||||
|
double y;
|
||||||
|
|
||||||
|
@JsonKey(name: 'Width')
|
||||||
|
double width;
|
||||||
|
|
||||||
|
@JsonKey(name: 'Height')
|
||||||
|
double height;
|
||||||
|
|
||||||
|
@JsonKey(name: 'score')
|
||||||
|
double score;
|
||||||
|
|
||||||
|
@JsonKey(name: 'totalScore')
|
||||||
|
double totalScore;
|
||||||
|
|
||||||
|
Question(this.questionNum,this.isObj,this.x,this.y,this.width,this.height,this.score,this.totalScore,);
|
||||||
|
|
||||||
|
factory Question.fromJson(Map<String, dynamic> srcJson) => _$QuestionFromJson(srcJson);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$QuestionToJson(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class QuestionAnswers extends Object {
|
||||||
|
|
||||||
|
@JsonKey(name: 'QuestionNum')
|
||||||
|
String questionNum;
|
||||||
|
|
||||||
|
@JsonKey(name: 'Answer')
|
||||||
|
String answer;
|
||||||
|
|
||||||
|
@JsonKey(name: 'YourAnswer')
|
||||||
|
String yourAnswer;
|
||||||
|
|
||||||
|
@JsonKey(name: 'AnswerType')
|
||||||
|
int answerType;
|
||||||
|
|
||||||
|
@JsonKey(name: 'TotalScore')
|
||||||
|
double totalScore;
|
||||||
|
|
||||||
|
@JsonKey(name: 'Score')
|
||||||
|
double score;
|
||||||
|
|
||||||
|
QuestionAnswers(this.questionNum,this.answer,this.yourAnswer,this.answerType,this.totalScore,this.score,);
|
||||||
|
|
||||||
|
factory QuestionAnswers.fromJson(Map<String, dynamic> srcJson) => _$QuestionAnswersFromJson(srcJson);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$QuestionAnswersToJson(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
|
part 'report_marking_detail_params.g.dart';
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class ReportMarkingDetailParams extends Object {
|
||||||
|
|
||||||
|
@JsonKey(name: 'ExamSubjectId')
|
||||||
|
int examSubjectId;
|
||||||
|
|
||||||
|
@JsonKey(name: 'StudentExamNum')
|
||||||
|
String studentExamNum;
|
||||||
|
|
||||||
|
ReportMarkingDetailParams(this.examSubjectId,this.studentExamNum,);
|
||||||
|
|
||||||
|
factory ReportMarkingDetailParams.fromJson(Map<String, dynamic> srcJson) => _$ReportMarkingDetailParamsFromJson(srcJson);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$ReportMarkingDetailParamsToJson(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,651 @@
|
||||||
|
import 'package:cached_network_image/cached_network_image.dart';
|
||||||
|
import 'package:collection/collection.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:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:marking_app/common/mixin/common.dart';
|
||||||
|
import 'package:marking_app/common/model/common/base_structure_result_report.dart';
|
||||||
|
import 'package:marking_app/common/model/report/detail_base_info.dart';
|
||||||
|
import 'package:marking_app/common/model/report/exam_records_all.dart';
|
||||||
|
import 'package:marking_app/common/model/report/question_know_point.dart';
|
||||||
|
import 'package:marking_app/common/model/report/report_card.dart';
|
||||||
|
import 'package:marking_app/common/model/report/report_card_params.dart';
|
||||||
|
import 'package:marking_app/pages/report_detail/widgets/basic_table.dart';
|
||||||
|
import 'package:marking_app/pages/report_detail/widgets/card_table.dart';
|
||||||
|
import 'package:marking_app/pages/report_detail/widgets/know_point_list.dart';
|
||||||
|
import 'package:marking_app/pages/report_detail/widgets/lab_title.dart';
|
||||||
|
import 'package:marking_app/pages/report_detail/widgets/no_data.dart';
|
||||||
|
import 'package:marking_app/pages/report_detail/widgets/overall_level_table.dart';
|
||||||
|
import 'package:marking_app/pages/report_detail/widgets/report_card_dialog.dart';
|
||||||
|
import 'package:marking_app/pages/report_detail/widgets/question_table.dart';
|
||||||
|
import 'package:marking_app/utils/request/rest_client_report.dart';
|
||||||
|
|
||||||
|
class ReportDetail extends StatefulHookConsumerWidget {
|
||||||
|
final int examId;
|
||||||
|
final bool showGrade;
|
||||||
|
|
||||||
|
const ReportDetail({Key? key, required this.examId, required this.showGrade})
|
||||||
|
: super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
_ReportDetailState createState() => _ReportDetailState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ReportDetailState extends ConsumerState<ReportDetail> with CommonMixin {
|
||||||
|
bool isGrade = true;
|
||||||
|
bool isHasData = false;
|
||||||
|
|
||||||
|
BaseInfo? baseInfo;
|
||||||
|
BaseStructureResultReport<DetailBaseInfo>? overallLevelRes;
|
||||||
|
BaseStructureResultReport<QuestionKnowPoint>? questionKnowPointRes;
|
||||||
|
List<ComboData> subjectList = []; //科目
|
||||||
|
List<ComboData> classList = []; //班级
|
||||||
|
ComboData currentSubject = ComboData('', '');
|
||||||
|
ComboData currentClass = ComboData('', '');
|
||||||
|
bool isClass = false;
|
||||||
|
|
||||||
|
// List cardHeadList = ['序号', '考号', '姓名', '班级', '分数', '班次', '校次'];
|
||||||
|
List<String> cardHeadList = []; //成绩单表头
|
||||||
|
List cardBodyList = []; //成绩单表格
|
||||||
|
int currentPage = 1; //成绩单当前页
|
||||||
|
int pageSize = 10; //成绩单当前页面请求数量
|
||||||
|
int totalPage = 1; //成绩单总页数
|
||||||
|
bool isRefresh = true; //防止请求未返回多次点击
|
||||||
|
List<Data> initialList = [];
|
||||||
|
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
EasyLoading.show(status: 'loading...');
|
||||||
|
getClass();
|
||||||
|
}
|
||||||
|
|
||||||
|
void getClass() async {
|
||||||
|
RestClientReport clientReport = await getClientReport();
|
||||||
|
BaseStructureResultReport<List<ComboData>> res =
|
||||||
|
await clientReport.getClassList(widget.examId);
|
||||||
|
|
||||||
|
BaseStructureResultReport<List<ComboData>> subjecData =
|
||||||
|
await clientReport.getExamsubject(widget.examId);
|
||||||
|
|
||||||
|
setState(() {
|
||||||
|
classList = res.data!;
|
||||||
|
classList[0].isCheck = true;
|
||||||
|
currentClass = classList[0];
|
||||||
|
|
||||||
|
subjectList = subjecData.data!;
|
||||||
|
subjectList[0].isCheck = true;
|
||||||
|
currentSubject = subjectList[0];
|
||||||
|
});
|
||||||
|
getData();
|
||||||
|
}
|
||||||
|
|
||||||
|
void getData() {
|
||||||
|
getBaseInfo();
|
||||||
|
getQuestionKnowPointTable();
|
||||||
|
getCard();
|
||||||
|
EasyLoading.dismiss();
|
||||||
|
}
|
||||||
|
|
||||||
|
//基础信息,总体水平,重点关注
|
||||||
|
void getBaseInfo() async {
|
||||||
|
RestClientReport clientReport = await getClientReport();
|
||||||
|
BaseStructureResultReport<DetailBaseInfo> result =
|
||||||
|
await clientReport.getReportDetail(widget.examId,
|
||||||
|
widget.showGrade && isGrade ? -1 : currentClass.value);
|
||||||
|
setState(() {
|
||||||
|
overallLevelRes = result;
|
||||||
|
if (result!.data != null) {
|
||||||
|
baseInfo = result!.data!.baseInfo;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//小题得分,知识点
|
||||||
|
void getQuestionKnowPointTable() async {
|
||||||
|
RestClientReport clientReport = await getClientReport();
|
||||||
|
BaseStructureResultReport<QuestionKnowPoint> res =
|
||||||
|
await clientReport.getQuestionKnowPoint(
|
||||||
|
widget.examId, currentClass.value, currentSubject.value);
|
||||||
|
setState(() {
|
||||||
|
questionKnowPointRes = res;
|
||||||
|
print(
|
||||||
|
"%%%%%%%%%%%%%%%%%%%widget.examId=${widget.examId}¤tClass.value=${currentClass.value}¤tSubject.value=${currentSubject.value}");
|
||||||
|
});
|
||||||
|
EasyLoading.dismiss();
|
||||||
|
}
|
||||||
|
|
||||||
|
void getCard() async {
|
||||||
|
RestClientReport clientReport = await getClientReport();
|
||||||
|
|
||||||
|
ReportCardParams params = ReportCardParams(
|
||||||
|
examId: widget.examId,
|
||||||
|
classId: widget.showGrade && isGrade ? -1 : currentClass.value,
|
||||||
|
page: currentPage,
|
||||||
|
limit: pageSize);
|
||||||
|
BaseStructureResultReport<ReportCard> result =
|
||||||
|
await clientReport.getReportCard(params);
|
||||||
|
print(
|
||||||
|
"#######${params.examId}¶ms.classId=${params.classId}¶ms.page=${params.page}¶ms.limit=${params.limit}");
|
||||||
|
List<String> head = result.data!.head;
|
||||||
|
head.removeAt(0);
|
||||||
|
List<String> beforeList = ['序号', '考号', '姓名', '班级', '分数', '班次', '校次'];
|
||||||
|
beforeList.addAll(head);
|
||||||
|
cardHeadList = beforeList;
|
||||||
|
List bodylist = [];
|
||||||
|
initialList = result.data!.data;
|
||||||
|
result.data!.data.forEach((item) {
|
||||||
|
List arr = [
|
||||||
|
item.examNo,
|
||||||
|
item.examStudentId,
|
||||||
|
item.name,
|
||||||
|
item.className,
|
||||||
|
item.totalScore.toString(),
|
||||||
|
item.totalClassRanking.toString(),
|
||||||
|
item.totalRanking.toString()
|
||||||
|
];
|
||||||
|
item.subjectDetails.forEach((subject) {
|
||||||
|
arr.add(subject.score);
|
||||||
|
});
|
||||||
|
bodylist.add(arr);
|
||||||
|
});
|
||||||
|
totalPage = (result.data!.totalCount / pageSize).ceil();
|
||||||
|
setState(() {
|
||||||
|
cardBodyList = [];
|
||||||
|
cardBodyList = bodylist;
|
||||||
|
isRefresh = true;
|
||||||
|
});
|
||||||
|
EasyLoading.dismiss();
|
||||||
|
}
|
||||||
|
|
||||||
|
//成绩单详情
|
||||||
|
void showAlertDialog(BuildContext context, int index) {
|
||||||
|
List<String> detailHead = [];
|
||||||
|
detailHead.addAll(cardHeadList.slice(5));
|
||||||
|
detailHead.insert(0, '总分');
|
||||||
|
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (BuildContext context) {
|
||||||
|
return AlertDialog(
|
||||||
|
insetPadding: EdgeInsets.all(25.r),
|
||||||
|
content: ReportCardDialog(initialList[index], detailHead),
|
||||||
|
contentPadding: EdgeInsets.all(0),
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(15.r))));
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void refreshData(item, bl) {
|
||||||
|
setState(() {
|
||||||
|
isClass = bl;
|
||||||
|
if (isClass) {
|
||||||
|
currentClass = item;
|
||||||
|
// getBaseInfo();
|
||||||
|
} else {
|
||||||
|
currentSubject = item;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
getData();
|
||||||
|
// getQuestionKnowPointTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
void showSubjectDialog(
|
||||||
|
BuildContext context, List<ComboData> list, bool isclass) {
|
||||||
|
showModalBottomSheet(
|
||||||
|
context: context,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(10.r))),
|
||||||
|
builder: (BuildContext context) {
|
||||||
|
return StatefulBuilder(builder: (context, setDialogState) {
|
||||||
|
return Container(
|
||||||
|
padding: EdgeInsets.only(top: 20.r),
|
||||||
|
height: list.length * 100.r,
|
||||||
|
constraints: BoxConstraints(maxHeight: 300.r),
|
||||||
|
child: ListView.builder(
|
||||||
|
itemBuilder: (BuildContext context, int index) {
|
||||||
|
var item = list?[index];
|
||||||
|
return InkWell(
|
||||||
|
onTap: () {
|
||||||
|
setDialogState(() {
|
||||||
|
list.forEach((element) {
|
||||||
|
element.isCheck = false;
|
||||||
|
});
|
||||||
|
item!.isCheck = true;
|
||||||
|
});
|
||||||
|
EasyLoading.show(status: 'loading...');
|
||||||
|
refreshData(item, isclass);
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 10.r),
|
||||||
|
child: Center(
|
||||||
|
child: Text(
|
||||||
|
item!.text,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.r,
|
||||||
|
color: item.isCheck
|
||||||
|
? Color(0xFF5F81FD)
|
||||||
|
: Color(0xFF2E2E2E)),
|
||||||
|
))),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
itemCount: list.length,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
if (baseInfo == null || overallLevelRes == null) {
|
||||||
|
return Container();
|
||||||
|
}
|
||||||
|
return AnnotatedRegion(
|
||||||
|
value: SystemUiOverlayStyle(
|
||||||
|
statusBarColor: Colors.transparent,
|
||||||
|
systemNavigationBarIconBrightness: Brightness.light,
|
||||||
|
statusBarBrightness: Brightness.dark,
|
||||||
|
statusBarIconBrightness: Brightness.light,
|
||||||
|
),
|
||||||
|
child: Container(
|
||||||
|
color: Color(0xFFF8F9FF),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.only(
|
||||||
|
top: MediaQuery.of(context).padding.top + 20.h,
|
||||||
|
bottom: 20.r),
|
||||||
|
child: Stack(
|
||||||
|
alignment: const FractionalOffset(0.04, 0.1),
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
baseInfo!.examName,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16.sp, color: Color(0xFF2D384C)),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
InkWell(
|
||||||
|
onTap: () => Navigator.pop(context),
|
||||||
|
child: Icon(Icons.arrow_back_ios_new_rounded,
|
||||||
|
color: Color(0xFF505767), size: 24.sp),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (widget.showGrade)
|
||||||
|
Container(
|
||||||
|
margin:
|
||||||
|
EdgeInsets.only(left: 20.r, right: 20.r, bottom: 10.r),
|
||||||
|
width: MediaQuery.of(context).size.width - 40.r,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(20.r),
|
||||||
|
color: Colors.white,
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: Color(0x566787FD),
|
||||||
|
offset: Offset(1.0, 1.0), //阴影xy轴偏移量
|
||||||
|
blurRadius: 10.0, //阴影模糊程度
|
||||||
|
spreadRadius: 0.1, //阴影扩散程度
|
||||||
|
)
|
||||||
|
]),
|
||||||
|
child: Flex(
|
||||||
|
direction: Axis.horizontal,
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
flex: 1,
|
||||||
|
child: InkWell(
|
||||||
|
onTap: () {
|
||||||
|
setState(() {
|
||||||
|
isGrade = true;
|
||||||
|
});
|
||||||
|
EasyLoading.show(status: 'loading...');
|
||||||
|
getData();
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 10.r),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: isGrade ? Color(0xFF6787FD) : Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(20.r),
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child: Text(
|
||||||
|
'年级',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.sp,
|
||||||
|
color: isGrade ? Colors.white : Colors.black),
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
flex: 1,
|
||||||
|
child: InkWell(
|
||||||
|
onTap: () {
|
||||||
|
setState(() {
|
||||||
|
isGrade = false;
|
||||||
|
});
|
||||||
|
EasyLoading.show(status: 'loading...');
|
||||||
|
getData();
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 10.r),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color:
|
||||||
|
!isGrade ? Color(0xFF6787FD) : Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(20.r),
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child: Text(
|
||||||
|
'班级',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.sp,
|
||||||
|
color:
|
||||||
|
!isGrade ? Colors.white : Colors.black),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// Text('99'),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
//基本信息
|
||||||
|
Expanded(
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
if (!widget.showGrade || !isGrade)
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.only(left: 16.r),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'班级:',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.sp, color: Color(0xFF474747)),
|
||||||
|
),
|
||||||
|
InkWell(
|
||||||
|
onTap: () {
|
||||||
|
showSubjectDialog(context, classList, true);
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
vertical: 3.r, horizontal: 30.r),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Color.fromRGBO(197, 223, 255, 0.31),
|
||||||
|
border: Border.all(
|
||||||
|
width: 1.r, color: Color(0xFFC0DCFF)),
|
||||||
|
borderRadius:
|
||||||
|
BorderRadius.all(Radius.circular(20.r)),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
currentClass.text,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.r,
|
||||||
|
color: Color(0xFF6787FD),
|
||||||
|
fontWeight: FontWeight.w500),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
LabTitle('基本信息', 'assets/images/basic_info.png'),
|
||||||
|
BasicTable(baseInfo),
|
||||||
|
LabTitle('总体水平', 'assets/images/overall_level.png'),
|
||||||
|
OverallLevelTable(
|
||||||
|
overallLevelRes!.data!.module1CJZL.sheets[0]),
|
||||||
|
LabTitle('重点关注学生', 'assets/images/reports_focus.png'),
|
||||||
|
OverallLevelTable(overallLevelRes!
|
||||||
|
.data!.module2ZDGZ.topExcelData.sheets[0]),
|
||||||
|
SizedBox(
|
||||||
|
height: 20.r,
|
||||||
|
),
|
||||||
|
OverallLevelTable(overallLevelRes!
|
||||||
|
.data!.module2ZDGZ.bottomExcelData.sheets[0]),
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
LabTitle('小题得分', 'assets/images/reports_score.png'),
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
vertical: 2.r, horizontal: 10.r),
|
||||||
|
margin: EdgeInsets.only(right: 14.r),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Color(0xFF6787FD),
|
||||||
|
borderRadius:
|
||||||
|
BorderRadius.all(Radius.circular(15.r)),
|
||||||
|
),
|
||||||
|
child: InkWell(
|
||||||
|
onTap: () {
|
||||||
|
showSubjectDialog(context, subjectList, false);
|
||||||
|
},
|
||||||
|
child: Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
currentSubject.text,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.sp,
|
||||||
|
color: Colors.white,
|
||||||
|
fontWeight: FontWeight.w500),
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.only(left: 8.r),
|
||||||
|
child: Image.asset(
|
||||||
|
'assets/images/right_icon.png',
|
||||||
|
width: 6.r,
|
||||||
|
height: 10.r,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
if (questionKnowPointRes != null)
|
||||||
|
Container(
|
||||||
|
// color: Colors.white,
|
||||||
|
margin: EdgeInsets.symmetric(horizontal: 14.r),
|
||||||
|
padding: EdgeInsets.only(bottom: 10.r, top: 0),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
(questionKnowPointRes!.data!.userQuestion
|
||||||
|
.sheets[0].headData.length >
|
||||||
|
0 &&
|
||||||
|
questionKnowPointRes!.data!.userQuestion
|
||||||
|
.sheets[0].bodyData.length >
|
||||||
|
0)
|
||||||
|
? SizedBox(
|
||||||
|
height: questionKnowPointRes!
|
||||||
|
.data!
|
||||||
|
.userQuestion
|
||||||
|
.sheets[0]
|
||||||
|
.bodyData
|
||||||
|
.length >
|
||||||
|
10
|
||||||
|
? 300.r
|
||||||
|
: questionKnowPointRes!
|
||||||
|
.data!
|
||||||
|
.userQuestion
|
||||||
|
.sheets[0]
|
||||||
|
.bodyData
|
||||||
|
.length *
|
||||||
|
30.r,
|
||||||
|
// width: MediaQuery.of(context).size.width,
|
||||||
|
child: CardList(
|
||||||
|
headList: questionKnowPointRes!.data!
|
||||||
|
.userQuestion.sheets[0].headData,
|
||||||
|
bodyList: questionKnowPointRes!.data!
|
||||||
|
.userQuestion.sheets[0].bodyData,
|
||||||
|
isScore: true,
|
||||||
|
fixedRows: 1,
|
||||||
|
fixedCols: 3,
|
||||||
|
),
|
||||||
|
|
||||||
|
/*QuestionTable(
|
||||||
|
headList: questionKnowPointRes!.data!
|
||||||
|
.userQuestion.sheets[0].headData,
|
||||||
|
bodyList: questionKnowPointRes!.data!
|
||||||
|
.userQuestion.sheets[0].bodyData,
|
||||||
|
),*/
|
||||||
|
)
|
||||||
|
: NoData(),
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
vertical: 10.r, horizontal: 10.r),
|
||||||
|
child: Text(
|
||||||
|
'知识点分析',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16.sp,
|
||||||
|
color: Color(0xFF2D384C),
|
||||||
|
fontWeight: FontWeight.w500),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
questionKnowPointRes!.data!.knowPointList.length >
|
||||||
|
0
|
||||||
|
? SizedBox(
|
||||||
|
height: 300.r,
|
||||||
|
child: KnowPointTable(
|
||||||
|
questionKnowPointRes!
|
||||||
|
.data!.knowPointList),
|
||||||
|
)
|
||||||
|
: NoData(),
|
||||||
|
/* questionKnowPointRes!.data!.knowPointList.length >
|
||||||
|
0
|
||||||
|
? KnowPointTable(
|
||||||
|
questionKnowPointRes!.data!.knowPointList)
|
||||||
|
: NoData(),*/
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
LabTitle('成绩单', 'assets/images/reports_card.png'),
|
||||||
|
if (cardBodyList.length > 0)
|
||||||
|
Container(
|
||||||
|
// width: MediaQuery.of(context).size.width,
|
||||||
|
height: 330.r,
|
||||||
|
margin: EdgeInsets.symmetric(horizontal: 14.r),
|
||||||
|
child: CardList(
|
||||||
|
headList: cardHeadList,
|
||||||
|
bodyList: cardBodyList,
|
||||||
|
showCardDetail: showAlertDialog,
|
||||||
|
fixedRows: 1,
|
||||||
|
fixedCols: 3,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (cardBodyList.length > 0)
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.only(right: 14.r,top: 6.r),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
|
children: [
|
||||||
|
InkWell(
|
||||||
|
onTap: () {
|
||||||
|
setState(() {
|
||||||
|
if (currentPage > 1 && isRefresh) {
|
||||||
|
isRefresh = false;
|
||||||
|
currentPage = currentPage - 1;
|
||||||
|
getCard();
|
||||||
|
EasyLoading.show(status: 'loading...');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
vertical: 2.r, horizontal: 5.r),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
border: Border.all(
|
||||||
|
color: currentPage == 1
|
||||||
|
? Color(0xFFB3B9B9)
|
||||||
|
: Color(0xFF6787FD),
|
||||||
|
width: 1.r),
|
||||||
|
borderRadius: BorderRadius.all(
|
||||||
|
Radius.circular(2.r)),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
'上一页',
|
||||||
|
style: TextStyle(
|
||||||
|
color: currentPage == 1
|
||||||
|
? Color(0xFFB3B9B9)
|
||||||
|
: Color(0xFF6787FD)),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
/*Icon(Icons.keyboard_arrow_left,
|
||||||
|
color: currentPage == 1
|
||||||
|
? Color(0xFFB3B9B9)
|
||||||
|
: Color(0xFF505767),
|
||||||
|
size: 24.sp),*/
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 15.r,
|
||||||
|
),
|
||||||
|
InkWell(
|
||||||
|
onTap: () {
|
||||||
|
setState(() {
|
||||||
|
if (currentPage < totalPage &&
|
||||||
|
isRefresh) {
|
||||||
|
isRefresh = false;
|
||||||
|
currentPage = currentPage + 1;
|
||||||
|
getCard();
|
||||||
|
EasyLoading.show(status: 'loading...');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
vertical: 2.r, horizontal: 5.r),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
border: Border.all(
|
||||||
|
color: totalPage - currentPage > 0
|
||||||
|
? Color(0xFF6787FD)
|
||||||
|
: Color(0xFFB3B9B9),
|
||||||
|
width: 1.r),
|
||||||
|
borderRadius: BorderRadius.all(
|
||||||
|
Radius.circular(2.r)),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
'下一页',
|
||||||
|
style: TextStyle(
|
||||||
|
color: totalPage - currentPage > 0
|
||||||
|
? Color(0xFF6787FD)
|
||||||
|
: Color(0xFFB3B9B9)),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
/*Icon(Icons.keyboard_arrow_right,
|
||||||
|
color: totalPage - currentPage > 0
|
||||||
|
? Color(0xFF505767)
|
||||||
|
: Color(0xFFB3B9B9),
|
||||||
|
size: 24.sp),*/
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (cardBodyList.length == 0) NoData(),
|
||||||
|
SizedBox(
|
||||||
|
height: 20.r,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,104 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
|
import 'package:marking_app/common/model/report/detail_base_info.dart';
|
||||||
|
import 'package:marking_app/pages/report_detail/widgets/basic_tablecell.dart';
|
||||||
|
|
||||||
|
class BasicTable extends StatelessWidget {
|
||||||
|
final BaseInfo? baseInfo;
|
||||||
|
|
||||||
|
const BasicTable(this.baseInfo, {Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Container(
|
||||||
|
margin: EdgeInsets.symmetric(horizontal: 14.r),
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 10.r, horizontal: 10.r),
|
||||||
|
width: MediaQuery.of(context).size.width,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white, borderRadius: BorderRadius.circular(5.r)),
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
// color: Color(0xFFF5F7FF),
|
||||||
|
border: Border(
|
||||||
|
bottom: BorderSide(width: 1, color: Color(0xFFE8EBFF)),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
child: IntrinsicHeight(
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Expanded(flex: 1, child: BasicTableCell('考试名称', false)),
|
||||||
|
Expanded(flex: 1, child: BasicTableCell(baseInfo!.examName, true)),
|
||||||
|
Expanded(flex: 1, child: BasicTableCell('考试类型', false)),
|
||||||
|
Expanded(flex: 1, child: BasicTableCell(baseInfo!.examType, true)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
border: Border(bottom: BorderSide(width: 1, color: Color(0xFFE8EBFF)))
|
||||||
|
),
|
||||||
|
child: IntrinsicHeight(
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Expanded(flex: 1, child: BasicTableCell('年级', false)),
|
||||||
|
Expanded(flex: 1, child: BasicTableCell(baseInfo!.grade, true)),
|
||||||
|
Expanded(flex: 1, child: BasicTableCell('学科', false)),
|
||||||
|
Expanded(flex: 1, child: BasicTableCell(baseInfo!.subject, true)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
border: Border(bottom: BorderSide(width: 1, color: Color(0xFFE8EBFF)))
|
||||||
|
),
|
||||||
|
child: IntrinsicHeight(
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Expanded(flex: 1, child: BasicTableCell('考试日期', false)),
|
||||||
|
Expanded(flex: 1, child: BasicTableCell(baseInfo!.examTime, true)),
|
||||||
|
Expanded(flex: 1, child: BasicTableCell('满分', false)),
|
||||||
|
Expanded(flex: 1, child: BasicTableCell(baseInfo!.totalScore.toString(), true)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
border: Border(bottom: BorderSide(width: 1, color: Color(0xFFE8EBFF)))
|
||||||
|
),
|
||||||
|
child: IntrinsicHeight(
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Expanded(flex: 1, child: BasicTableCell('平均分', false)),
|
||||||
|
Expanded(flex: 1, child: BasicTableCell(baseInfo!.avgScore.toString(), true)),
|
||||||
|
Expanded(flex: 1, child: BasicTableCell('最高分', false)),
|
||||||
|
Expanded(flex: 1, child: BasicTableCell(baseInfo!.maxScore.toString(), true)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
border: Border(bottom: BorderSide(width: 1, color: Color(0xFFE8EBFF)))
|
||||||
|
),
|
||||||
|
child: IntrinsicHeight(
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Expanded(flex: 1, child: BasicTableCell('优秀率', false)),
|
||||||
|
Expanded(flex: 1, child: BasicTableCell(baseInfo!.rateGood, true)),
|
||||||
|
Expanded(flex: 1, child: BasicTableCell('及格率', false)),
|
||||||
|
Expanded(flex: 1, child: BasicTableCell(baseInfo!.ratePass, true)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
//基本信息表格单元格
|
||||||
|
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 BasicTableCell extends StatelessWidget {
|
||||||
|
final String content;
|
||||||
|
final bool isBold;
|
||||||
|
const BasicTableCell(this.content,this.isBold,{Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Container(
|
||||||
|
height: double.infinity,
|
||||||
|
padding: EdgeInsets.symmetric(vertical:6.r,horizontal: 8.r),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: isBold?Colors.white:Color(0xFFF5F7FF),
|
||||||
|
),
|
||||||
|
child: Text(content,style: TextStyle(fontSize: 12.sp,color: isBold?Colors.black:Color(0xFF505767),fontWeight: isBold?FontWeight.w500:FontWeight.w400),)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,137 @@
|
||||||
|
import 'package:data_table_2/data_table_2.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
|
|
||||||
|
class CardList extends StatefulWidget {
|
||||||
|
final List headList;
|
||||||
|
final List bodyList;
|
||||||
|
final Function? showCardDetail;
|
||||||
|
final bool? isScore;
|
||||||
|
final int? fixedRows;
|
||||||
|
final int? fixedCols;
|
||||||
|
|
||||||
|
const CardList({
|
||||||
|
Key? key,
|
||||||
|
required this.headList,
|
||||||
|
required this.bodyList,
|
||||||
|
this.showCardDetail,
|
||||||
|
this.isScore = false,
|
||||||
|
this.fixedCols,
|
||||||
|
this.fixedRows,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<CardList> createState() => _CardListState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _CardListState extends State<CardList> {
|
||||||
|
final ScrollController _controller = ScrollController();
|
||||||
|
int? _sortColumnIndex;
|
||||||
|
bool _sortAscending = true;
|
||||||
|
|
||||||
|
DataRow _getRow(int index, [Color? color]) {
|
||||||
|
assert(index >= 0);
|
||||||
|
var body = widget.bodyList[index];
|
||||||
|
return DataRow2.byIndex(
|
||||||
|
index: index,
|
||||||
|
color: color != null ? MaterialStateProperty.all(color) : null,
|
||||||
|
cells: List.generate(widget.headList.length, (itemIndex) {
|
||||||
|
var item = body[itemIndex];
|
||||||
|
return
|
||||||
|
itemIndex == 0 && widget.isScore == false ?DataCell(Center(
|
||||||
|
child: Text((index + 1).toString(),
|
||||||
|
style:
|
||||||
|
TextStyle(fontSize: 12.sp, color: Color(0xFF262626))),
|
||||||
|
)):
|
||||||
|
DataCell(itemIndex == 2 && widget.isScore == false
|
||||||
|
? InkWell(
|
||||||
|
onTap: () {
|
||||||
|
if (widget.showCardDetail != null) {
|
||||||
|
widget.showCardDetail!(context, index);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Center(
|
||||||
|
child: Text(item.toString(),
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.sp, color: Color(0xFF262626))),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.only(right: 5.r),
|
||||||
|
child: Image.asset(
|
||||||
|
'assets/images/search_icon.png',
|
||||||
|
width: 14.r,
|
||||||
|
height: 14.r,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: Center(
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 5.r),
|
||||||
|
child: Text(item.toString(),
|
||||||
|
style:
|
||||||
|
TextStyle(fontSize: 12.sp, color: Color(0xFF262626))),
|
||||||
|
),
|
||||||
|
));
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return DataTable2(
|
||||||
|
dividerThickness: 0,
|
||||||
|
scrollController: _controller,
|
||||||
|
columnSpacing: 0,
|
||||||
|
horizontalMargin: 0,
|
||||||
|
dataRowHeight:50.r,
|
||||||
|
bottomMargin: 0,
|
||||||
|
border: TableBorder(
|
||||||
|
horizontalInside: BorderSide(
|
||||||
|
width: 1, color: Color(0xFFE0E5FF), style: BorderStyle.solid),
|
||||||
|
bottom: BorderSide(
|
||||||
|
width: 1, color: Color(0xFFE0E5FF), style: BorderStyle.solid),
|
||||||
|
verticalInside: BorderSide(
|
||||||
|
width: 1, color: Color(0xFFE0E5FF), style: BorderStyle.solid)),
|
||||||
|
headingRowColor: MaterialStateProperty.resolveWith((states) =>
|
||||||
|
widget.fixedCols! > 0 ? Color(0xFFF0F3FF) : Colors.transparent),
|
||||||
|
/* headingRowDecoration: BoxDecoration(
|
||||||
|
gradient: LinearGradient(
|
||||||
|
colors: [
|
||||||
|
Colors.grey[400]!,
|
||||||
|
Colors.grey[200]!,
|
||||||
|
],
|
||||||
|
begin: Alignment.topCenter,
|
||||||
|
end: Alignment.bottomCenter,
|
||||||
|
),
|
||||||
|
),*/
|
||||||
|
headingRowDecoration: BoxDecoration(color: Color(0xFFF0F3FF)),
|
||||||
|
fixedColumnsColor: Color(0xFFF0F3FF),
|
||||||
|
fixedCornerColor: Colors.grey[400],
|
||||||
|
minWidth: 70.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(widget.isScore == true ? item.rowData[0][0] : item,
|
||||||
|
style: TextStyle(fontSize: 12.sp, color: Color(0xFF505767))),
|
||||||
|
),
|
||||||
|
// size: ColumnSize.S,
|
||||||
|
fixedWidth: index == 0 && widget.isScore == false?50.r:70.r,
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
rows: List<DataRow>.generate(widget.bodyList.length,
|
||||||
|
(index) => _getRow(index, Colors.transparent)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,89 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
|
import 'package:marking_app/common/model/report/report_marking_detail.dart';
|
||||||
|
|
||||||
|
class CustomRect extends StatefulWidget {
|
||||||
|
ExamOriginPapers examOriginItem;
|
||||||
|
|
||||||
|
CustomRect(this.examOriginItem, {Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
_CustomRectState createState() => _CustomRectState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _CustomRectState extends State<CustomRect> {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Container(
|
||||||
|
width: widget.examOriginItem.width,
|
||||||
|
height: widget.examOriginItem.height,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
image: DecorationImage(
|
||||||
|
image: NetworkImage(widget.examOriginItem.imageUrl),
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
)),
|
||||||
|
child: CustomPaint(
|
||||||
|
size:
|
||||||
|
Size(widget.examOriginItem.width, widget.examOriginItem.height),
|
||||||
|
painter: MyPainter(widget.examOriginItem.question),
|
||||||
|
child: Stack(
|
||||||
|
children: List.generate(widget.examOriginItem.question.length, (index) {
|
||||||
|
var item = widget.examOriginItem.question[index];
|
||||||
|
return Positioned(
|
||||||
|
left: item.x + item.width - 50,
|
||||||
|
top: item.y,
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Text(item.score.toInt().toString(),style: TextStyle(fontSize: 12.sp,color: Colors.red),),
|
||||||
|
Text('/',style: TextStyle(fontSize: 12.sp,color: Colors.red),),
|
||||||
|
Text(item.totalScore.toInt().toString(),style: TextStyle(fontSize: 12.sp,color: Colors.red),),
|
||||||
|
],
|
||||||
|
));
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///[定义画笔]
|
||||||
|
Paint _paint = Paint()
|
||||||
|
..color = Colors.red //画笔颜色
|
||||||
|
..strokeCap = StrokeCap.round //画笔笔触类型
|
||||||
|
..isAntiAlias = true //是否启动抗锯齿
|
||||||
|
..style = PaintingStyle.stroke //绘画风格,默认为填充
|
||||||
|
..strokeWidth = 3.0; //画笔的宽度
|
||||||
|
|
||||||
|
class MyPainter extends CustomPainter {
|
||||||
|
final List<Question> questions;
|
||||||
|
|
||||||
|
MyPainter(this.questions);
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
void paint(Canvas canvas, Size size) {
|
||||||
|
questions.forEach((item) {
|
||||||
|
Rect rect = Rect.fromLTWH(item.x,item.y
|
||||||
|
,item.width, item.height);
|
||||||
|
//根据上面的矩形,构建一个圆角矩形
|
||||||
|
RRect rrect = RRect.fromRectAndRadius(rect, Radius.circular(0.0));
|
||||||
|
|
||||||
|
canvas.drawRRect(rrect, _paint);
|
||||||
|
});
|
||||||
|
|
||||||
|
/* Rect rect1 = Rect.fromCenter(center: Offset(140.0, 491.0), width: 91.0,height: 35.0);
|
||||||
|
//根据上面的矩形,构建一个圆角矩形
|
||||||
|
RRect rrect1 = RRect.fromRectAndRadius(rect1, Radius.circular(0.0));
|
||||||
|
canvas.drawRRect(rrect1, _paint);*/
|
||||||
|
/* Rect rect2 = Rect.fromLTWH( 209.0, 549.0, 449.0,210.0);
|
||||||
|
//根据上面的矩形,构建一个圆角矩形
|
||||||
|
RRect rrect2 = RRect.fromRectAndRadius(rect2, Radius.circular(0.0));
|
||||||
|
canvas.drawRRect(rrect2, _paint);*/
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool shouldRepaint(covariant CustomPainter oldDelegate) {
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,127 @@
|
||||||
|
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/report/question_know_point.dart';
|
||||||
|
|
||||||
|
class KnowPointTable extends StatefulWidget {
|
||||||
|
final List<KnowPointList> knowPointList;
|
||||||
|
|
||||||
|
KnowPointTable(this.knowPointList, {Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<KnowPointTable> createState() => _KnowPointTableState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _KnowPointTableState extends State<KnowPointTable> {
|
||||||
|
List headList = ['题号', '知识点', '正确率', '得分率'];
|
||||||
|
|
||||||
|
DataRow _getRow(int index, [Color? color]) {
|
||||||
|
assert(index >= 0);
|
||||||
|
var bodyItem = widget.knowPointList[index];
|
||||||
|
return DataRow2.byIndex(
|
||||||
|
index: index,
|
||||||
|
color: color != null ? MaterialStateProperty.all(color) : null,
|
||||||
|
cells:[
|
||||||
|
DataCell(Center(
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
vertical: 6.r, horizontal: 5.r),
|
||||||
|
child: Text(
|
||||||
|
bodyItem.questionNums,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.sp, color: Color(0xFF262626)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),),
|
||||||
|
DataCell(Container(
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
vertical: 6.r, horizontal: 5.r),
|
||||||
|
child: Text(
|
||||||
|
bodyItem.name,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.sp, color: Color(0xFF262626)),
|
||||||
|
),
|
||||||
|
),),
|
||||||
|
DataCell(Center(
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
vertical: 6.r, horizontal: 5.r),
|
||||||
|
child: Text(
|
||||||
|
bodyItem.correctRate,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.sp, color: Color(0xFF262626)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),),
|
||||||
|
DataCell( Center(
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
vertical: 6.r, horizontal: 5.r),
|
||||||
|
child: Text(
|
||||||
|
bodyItem.gradeCorrectRate,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.sp, color: Color(0xFF262626)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
int fixedRows = 1;
|
||||||
|
int fixedCols = 0;
|
||||||
|
final ScrollController _controller = ScrollController();
|
||||||
|
int? _sortColumnIndex;
|
||||||
|
bool _sortAscending = true;
|
||||||
|
|
||||||
|
return DataTable2(
|
||||||
|
dividerThickness: 0,
|
||||||
|
scrollController: _controller,
|
||||||
|
columnSpacing: 0,
|
||||||
|
horizontalMargin: 0,
|
||||||
|
bottomMargin: 0,
|
||||||
|
border: TableBorder(
|
||||||
|
horizontalInside: BorderSide(
|
||||||
|
width: 1, color: Color(0xFFE0E5FF), style: BorderStyle.solid),
|
||||||
|
bottom: BorderSide(
|
||||||
|
width: 1, color: Color(0xFFE0E5FF), style: BorderStyle.solid),
|
||||||
|
verticalInside: BorderSide(
|
||||||
|
width: 1, color: Color(0xFFE0E5FF), style: BorderStyle.solid)),
|
||||||
|
headingRowColor: MaterialStateProperty.resolveWith((states) =>
|
||||||
|
fixedCols > 0 ? Color(0xFFF0F3FF) : Colors.transparent),
|
||||||
|
/* headingRowDecoration: BoxDecoration(
|
||||||
|
gradient: LinearGradient(
|
||||||
|
colors: [
|
||||||
|
Colors.grey[400]!,
|
||||||
|
Colors.grey[200]!,
|
||||||
|
],
|
||||||
|
begin: Alignment.topCenter,
|
||||||
|
end: Alignment.bottomCenter,
|
||||||
|
),
|
||||||
|
),*/
|
||||||
|
headingRowDecoration: BoxDecoration(color: Color(0xFFF0F3FF)),
|
||||||
|
fixedColumnsColor: Color(0xFFF0F3FF),
|
||||||
|
fixedCornerColor: Colors.grey[400],
|
||||||
|
// minWidth: 70.r * headList.length,
|
||||||
|
fixedTopRows: fixedRows,
|
||||||
|
fixedLeftColumns: fixedCols,
|
||||||
|
sortColumnIndex: _sortColumnIndex,
|
||||||
|
sortAscending: _sortAscending,
|
||||||
|
// onSelectAll: (val) => setState(() => selectAll(val)),
|
||||||
|
columns: List.generate(headList.length, (index) {
|
||||||
|
var item = headList[index];
|
||||||
|
return DataColumn2(
|
||||||
|
label: Center(
|
||||||
|
child: Text(item,
|
||||||
|
style: TextStyle(fontSize: 12.sp, color: Color(0xFF505767))),
|
||||||
|
),
|
||||||
|
// size: ColumnSize.S,
|
||||||
|
fixedWidth: index == 0?60.r:(MediaQuery.of(context).size.width - 90.r)/3,
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
rows: List<DataRow>.generate(widget.knowPointList.length,
|
||||||
|
(index) => _getRow(index, Colors.transparent)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
//基本信息、总体水平
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
|
|
||||||
|
class LabTitle extends StatelessWidget {
|
||||||
|
final String name;
|
||||||
|
final String img;
|
||||||
|
|
||||||
|
const LabTitle(this.name, this.img, {Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Padding(
|
||||||
|
padding: EdgeInsets.only(left: 14.r,top: 15.r,bottom: 15.r),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Image.asset(
|
||||||
|
img,
|
||||||
|
width: 23.r,
|
||||||
|
height: 23.r,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
name,
|
||||||
|
style: TextStyle(fontSize: 16.sp, color: Color(0xFF2D384C)),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
|
|
||||||
|
class NoData extends StatelessWidget {
|
||||||
|
const NoData({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Center(child: Text('-暂无数据-',style: TextStyle(fontSize: 14.sp,color: Color(0xFF505767)),));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,77 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
|
import 'package:flutter_widget_from_html_core/flutter_widget_from_html_core.dart';
|
||||||
|
import 'package:marking_app/common/model/report/detail_base_info.dart';
|
||||||
|
|
||||||
|
class OverallLevelTable extends StatelessWidget {
|
||||||
|
final Sheets? tableList;
|
||||||
|
final bool? hasPad;
|
||||||
|
const OverallLevelTable(this.tableList,{Key? key,this.hasPad = true}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Padding(
|
||||||
|
padding: EdgeInsets.only(left: hasPad == true?14.r:0,right: hasPad == true?14.r:0),
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
scrollDirection: Axis.horizontal,
|
||||||
|
child: Table(
|
||||||
|
defaultVerticalAlignment: TableCellVerticalAlignment.middle,
|
||||||
|
|
||||||
|
defaultColumnWidth: tableList!.headData.length<7?FixedColumnWidth((MediaQuery.of(context).size.width - 28.r) / tableList!.headData.length):IntrinsicColumnWidth(),
|
||||||
|
// defaultColumnWidth: IntrinsicColumnWidth(),
|
||||||
|
border: TableBorder(horizontalInside: BorderSide(width: 1, color: Color(0xFFE0E5FF), style: BorderStyle.solid),
|
||||||
|
bottom: BorderSide(width: 1, color: Color(0xFFE0E5FF), style: BorderStyle.solid),
|
||||||
|
verticalInside: BorderSide(width: 1, color: Color(0xFFE0E5FF), style: BorderStyle.solid))
|
||||||
|
|
||||||
|
/*TableBorder.symmetric(
|
||||||
|
inside: BorderSide(width: 1, color: Color(0xFFE0E5FF)),
|
||||||
|
// outside: BorderSide.none,
|
||||||
|
outside: hasPad == true?BorderSide.none:BorderSide(width: 1, color: Color(0xFFE0E5FF)),
|
||||||
|
)*/,
|
||||||
|
// borderRadius: BorderRadius.circular(5.r),
|
||||||
|
children: List.generate(tableList!.bodyData.length + 1, (bodyIndex) {
|
||||||
|
var bodyItem ;
|
||||||
|
if(bodyIndex > 0){
|
||||||
|
bodyItem = tableList!.bodyData[bodyIndex - 1];
|
||||||
|
}
|
||||||
|
return bodyIndex == 0? TableRow(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Color(0xFFF0F3FF),
|
||||||
|
),
|
||||||
|
children:List.generate(tableList!.headData.length, (index) {
|
||||||
|
var item = tableList!.headData[index];
|
||||||
|
return Center(
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 6.r,horizontal: 10.r),
|
||||||
|
child: Text(
|
||||||
|
item.rowData[0][0],
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.sp, color: Color(0xFF505767)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
})
|
||||||
|
):TableRow(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
children: List.generate(tableList!.headData.length, (cell){
|
||||||
|
return Center(
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 6.r,horizontal: 5.r),
|
||||||
|
child: cell == 0?Text(
|
||||||
|
bodyItem[cell].toString(),
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.sp,
|
||||||
|
color: Color(0xFF262626)),
|
||||||
|
):HtmlWidget(bodyItem[cell].toString(),textStyle: TextStyle(fontSize: 12.sp,color: Color(0xFF262626)),),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
})
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,113 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
|
import 'package:horizontal_data_table/horizontal_data_table.dart';
|
||||||
|
|
||||||
|
|
||||||
|
class QuestionTable extends StatefulWidget {
|
||||||
|
final List headList;
|
||||||
|
final List bodyList;
|
||||||
|
const QuestionTable({
|
||||||
|
Key? key, required this.headList, required this.bodyList,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<QuestionTable> createState() => _QuestionTableState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _QuestionTableState extends State<QuestionTable> {
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return HorizontalDataTable(
|
||||||
|
leftHandSideColumnWidth: 100,
|
||||||
|
rightHandSideColumnWidth: (80.r * (widget.headList.length - 1)).toDouble(),
|
||||||
|
isFixedHeader: true,
|
||||||
|
headerWidgets: _getTitleWidget(),
|
||||||
|
isFixedFooter: false,
|
||||||
|
footerWidgets: _getTitleWidget(),
|
||||||
|
leftSideItemBuilder: _generateFirstColumnRow,
|
||||||
|
rightSideItemBuilder: _generateRightHandSideColumnRow,
|
||||||
|
itemCount:widget.bodyList.length,
|
||||||
|
rowSeparatorWidget: const Divider(
|
||||||
|
color: Color(0xFFE0E5FF),
|
||||||
|
height: 1.0,
|
||||||
|
thickness: 0.0,
|
||||||
|
),
|
||||||
|
// leftHandSideColBackgroundColor: const Color(0xFFFFFFFF),
|
||||||
|
// rightHandSideColBackgroundColor: const Color(0xFFFFFFFF),
|
||||||
|
// itemExtent: 31.r,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Widget> _getTitleWidget() {
|
||||||
|
return List.generate(widget.headList.length, (index){
|
||||||
|
var item = widget.headList[index];
|
||||||
|
return Container(
|
||||||
|
height: 30.r,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Color(0xFFF0F3FF),
|
||||||
|
border:Border(right: BorderSide(width: 0.5.r,color: Color(0xFFE0E5FF)))
|
||||||
|
),
|
||||||
|
width: index == 0?100.r:80.r,
|
||||||
|
child: Center(
|
||||||
|
child: Text(item.rowData[0][0],style: TextStyle(
|
||||||
|
fontSize: 12.sp, color: Color(0xFF505767))),
|
||||||
|
),);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _getTitleItemWidget(String label, double width) {
|
||||||
|
return Container(
|
||||||
|
width: width,
|
||||||
|
height: 56,
|
||||||
|
padding: const EdgeInsets.fromLTRB(5, 0, 0, 0),
|
||||||
|
alignment: Alignment.centerLeft,
|
||||||
|
child: Text(label, style: const TextStyle(fontWeight: FontWeight.bold)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _generateFirstColumnRow(BuildContext context, int index) {
|
||||||
|
var item = widget.bodyList[index][0];
|
||||||
|
return Container(
|
||||||
|
width: 100.r,
|
||||||
|
height: 30.r,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
border:Border(right: BorderSide(width: 0.5.r,color: Color(0xFFE0E5FF)))
|
||||||
|
),
|
||||||
|
padding: const EdgeInsets.fromLTRB(5, 0, 0, 0),
|
||||||
|
alignment: Alignment.centerLeft,
|
||||||
|
child: Center(
|
||||||
|
child: Text(item.toString(), style: TextStyle(
|
||||||
|
fontSize: 12.sp,
|
||||||
|
color: Color(0xFF262626))),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _generateRightHandSideColumnRow(BuildContext context, int index) {
|
||||||
|
var bodyItem = widget.bodyList[index];
|
||||||
|
return Row(
|
||||||
|
children: List.generate(widget.headList.length -1, (bodyIndex){
|
||||||
|
return Container(
|
||||||
|
width: 80.r,
|
||||||
|
height: 30.r,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
border:Border(right: BorderSide(width: 0.5.r,color: Color(0xFFE0E5FF)))
|
||||||
|
),
|
||||||
|
padding: const EdgeInsets.fromLTRB(5, 0, 0, 0),
|
||||||
|
alignment: Alignment.centerLeft,
|
||||||
|
child: Center(
|
||||||
|
child: Text(bodyItem[bodyIndex + 1].toString(), style: TextStyle(
|
||||||
|
fontSize: 12.sp,
|
||||||
|
color: Color(0xFF262626))),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,371 @@
|
||||||
|
import 'package:collection/collection.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:marking_app/common/mixin/common.dart';
|
||||||
|
import 'package:marking_app/common/model/common/base_structure_result_report.dart';
|
||||||
|
import 'package:marking_app/common/model/report/exam_records_all.dart';
|
||||||
|
import 'package:marking_app/common/model/report/report_card.dart';
|
||||||
|
import 'package:marking_app/common/model/report/report_marking_detail.dart';
|
||||||
|
import 'package:marking_app/common/model/report/report_marking_detail_params.dart';
|
||||||
|
import 'package:marking_app/pages/report_detail/widgets/custom_rect.dart';
|
||||||
|
import 'package:marking_app/utils/easy_refresh/MyEmptyWidget.dart';
|
||||||
|
import 'package:marking_app/utils/request/rest_client_report.dart';
|
||||||
|
|
||||||
|
class ReportCardDialog extends StatefulHookConsumerWidget {
|
||||||
|
final Data cardItem;
|
||||||
|
final List<String> headList;
|
||||||
|
|
||||||
|
const ReportCardDialog(this.cardItem, this.headList, {Key? key})
|
||||||
|
: super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
_ReportCardDialogState createState() => _ReportCardDialogState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ReportCardDialogState extends ConsumerState<ReportCardDialog>
|
||||||
|
with CommonMixin {
|
||||||
|
List<ComboData> subjectList = [];
|
||||||
|
ExamOriginPapers? examOrigin;
|
||||||
|
List<ExamOriginPapers> examOriginList = [];
|
||||||
|
int currentSubjectId = 0;
|
||||||
|
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
List<String> arr = widget.headList.slice(3);
|
||||||
|
arr.asMap().forEach((index, name) {
|
||||||
|
var subject = widget.cardItem.subjectDetails;
|
||||||
|
ComboData item =
|
||||||
|
ComboData(subject[index].examSubjectId, name, isCheck: false);
|
||||||
|
subjectList.add(item);
|
||||||
|
});
|
||||||
|
subjectList[0].isCheck = true;
|
||||||
|
currentSubjectId = subjectList[0].value;
|
||||||
|
getImageDetail();
|
||||||
|
}
|
||||||
|
|
||||||
|
void getImageDetail() async {
|
||||||
|
RestClientReport clientReport = await getClientReport();
|
||||||
|
ReportMarkingDetailParams params =
|
||||||
|
ReportMarkingDetailParams(currentSubjectId, widget.cardItem.examStudentId);
|
||||||
|
BaseStructureResultReport<ReportMarkingDetail> res =
|
||||||
|
await clientReport.getMarkingDetail(params);
|
||||||
|
|
||||||
|
setState(() {
|
||||||
|
if(res.data!=null){
|
||||||
|
examOrigin = res.data!.examOriginPapers[0];
|
||||||
|
examOriginList = res.data!.examOriginPapers;
|
||||||
|
}else{
|
||||||
|
examOriginList = [];
|
||||||
|
examOrigin = null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
EasyLoading.dismiss();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Container(
|
||||||
|
width: MediaQuery.of(context).size.width,
|
||||||
|
height: MediaQuery.of(context).size.height,
|
||||||
|
child: Column(children: [
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.only(top: 10.r, left: 20.r, right: 20.r),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
widget.cardItem.name,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.sp,
|
||||||
|
color: Color(0xFF6787FD),
|
||||||
|
fontWeight: FontWeight.w500),
|
||||||
|
),
|
||||||
|
InkWell(
|
||||||
|
onTap: (){
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
child: Icon(Icons.close,color: Colors.grey,size: 20.r,))
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
margin: EdgeInsets.only(top: 10.r),
|
||||||
|
width: double.infinity,
|
||||||
|
height: 30.r,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Color(0xFFEFF1FF),
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(2.r))),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
children: List.generate(
|
||||||
|
widget.headList.length > 7 ? 7 : widget.headList.length,
|
||||||
|
(index) {
|
||||||
|
var item = widget.headList[index];
|
||||||
|
return Container(
|
||||||
|
width: (MediaQuery.of(context).size.width - 90.r) / 7,
|
||||||
|
child: _subjectText(item));
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
width: double.infinity,
|
||||||
|
height: 30.r,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(2.r))),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
width: (MediaQuery.of(context).size.width - 90.r) / 7,
|
||||||
|
child: _subjectText(
|
||||||
|
widget.cardItem.totalScore.toString())),
|
||||||
|
Container(
|
||||||
|
width: (MediaQuery.of(context).size.width - 90.r) / 7,
|
||||||
|
child: _subjectText(
|
||||||
|
widget.cardItem.totalClassRanking.toString())),
|
||||||
|
Container(
|
||||||
|
width: (MediaQuery.of(context).size.width - 90.r) / 7,
|
||||||
|
child: _subjectText(
|
||||||
|
widget.cardItem.totalRanking.toString())),
|
||||||
|
SizedBox(
|
||||||
|
width:
|
||||||
|
(MediaQuery.of(context).size.width - 90.r) / 7 * 4,
|
||||||
|
child: Row(
|
||||||
|
children: List.generate(
|
||||||
|
widget.cardItem.subjectDetails.length > 4
|
||||||
|
? 4
|
||||||
|
: widget.cardItem.subjectDetails.length,
|
||||||
|
(index) {
|
||||||
|
var subject = widget.cardItem.subjectDetails[index];
|
||||||
|
return Container(
|
||||||
|
width:
|
||||||
|
(MediaQuery.of(context).size.width - 90.r) /
|
||||||
|
7,
|
||||||
|
child: _subjectText(subject.score));
|
||||||
|
}),
|
||||||
|
)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (widget.headList.length > 7)
|
||||||
|
Container(
|
||||||
|
width: double.infinity,
|
||||||
|
height: 30.r,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Color(0xFFEFF1FF),
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(2.r))),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
children:
|
||||||
|
List.generate(widget.headList.length - 7, (index) {
|
||||||
|
var item = widget.headList[index + 7];
|
||||||
|
return Container(
|
||||||
|
width: (MediaQuery.of(context).size.width - 90.r) / 7,
|
||||||
|
child: _subjectText(item));
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (widget.headList.length > 7)
|
||||||
|
Container(
|
||||||
|
width: double.infinity,
|
||||||
|
height: 30.r,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(2.r))),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
children: List.generate(
|
||||||
|
widget.cardItem.subjectDetails.length - 4, (index) {
|
||||||
|
var subject = widget.cardItem.subjectDetails[index + 4];
|
||||||
|
return Container(
|
||||||
|
width: (MediaQuery.of(context).size.width - 90.r) / 7,
|
||||||
|
child: _subjectText(subject.score));
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Container(
|
||||||
|
margin: EdgeInsets.only(top: 0.r),
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 5.r, horizontal: 20.r),
|
||||||
|
width: double.infinity,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Color(0xFFEFF1FF),
|
||||||
|
borderRadius: BorderRadius.only(
|
||||||
|
bottomLeft: Radius.circular(15.r),
|
||||||
|
bottomRight: Radius.circular(15.r))),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
height: 30.r,
|
||||||
|
width: MediaQuery.of(context).size.width,
|
||||||
|
child: ListView.builder(
|
||||||
|
itemBuilder: (BuildContext context, int index) {
|
||||||
|
var item = subjectList[index];
|
||||||
|
return InkWell(
|
||||||
|
onTap: () {
|
||||||
|
setState(() {
|
||||||
|
subjectList.forEach((element) {
|
||||||
|
element.isCheck = false;
|
||||||
|
});
|
||||||
|
item.isCheck = true;
|
||||||
|
currentSubjectId = item.value;
|
||||||
|
EasyLoading.show(status: 'loading...');
|
||||||
|
getImageDetail();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
width: 30.r,
|
||||||
|
height: 30.r,
|
||||||
|
margin: EdgeInsets.only(
|
||||||
|
right: index == subjectList.length
|
||||||
|
? 0
|
||||||
|
: (MediaQuery.of(context).size.width -
|
||||||
|
30.r * 9 -
|
||||||
|
110.r) /
|
||||||
|
8),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: item.isCheck
|
||||||
|
? Color(0xFF6787FD)
|
||||||
|
: Color(0xFFFFFFFF),
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
// borderRadius: BorderRadius.all(Radius.circular(13.r)),
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child: Text(
|
||||||
|
item.text,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 11.sp,
|
||||||
|
color: item.isCheck
|
||||||
|
? Colors.white
|
||||||
|
: Color(0xFF667095),
|
||||||
|
fontWeight: FontWeight.w400),
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
itemCount: subjectList.length,
|
||||||
|
scrollDirection: Axis.horizontal,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: examOrigin != null && examOrigin!.imageUrl != ''
|
||||||
|
? Padding(
|
||||||
|
padding: EdgeInsets.only(top:5.r),
|
||||||
|
child: InteractiveViewer(
|
||||||
|
constrained: false,
|
||||||
|
boundaryMargin: EdgeInsets.all(140.r),
|
||||||
|
minScale: 0.1, // 最小缩放
|
||||||
|
maxScale: 4.0, // 最大缩放
|
||||||
|
child: CustomRect(examOrigin!)),
|
||||||
|
)
|
||||||
|
: MyEmptyWidget(),
|
||||||
|
),
|
||||||
|
SizedBox(height: 6.r,),
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
if(examOrigin != null && examOrigin!.pageIndex > 1)
|
||||||
|
InkWell(
|
||||||
|
onTap: () {
|
||||||
|
var num = examOrigin!.pageIndex;
|
||||||
|
if (num > 1) {
|
||||||
|
setState(() {
|
||||||
|
examOrigin = examOriginList[num - 1 - 1];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child:Container(
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
vertical: 2.r, horizontal: 5.r),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
border: Border.all(
|
||||||
|
color: Color(0xFF6787FD),
|
||||||
|
width: 1.r),
|
||||||
|
borderRadius: BorderRadius.all(
|
||||||
|
Radius.circular(2.r)),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
'下一页',
|
||||||
|
style: TextStyle(
|
||||||
|
color: Color(0xFF6787FD),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
/* Image.asset(
|
||||||
|
'assets/images/report_left_icon.png',
|
||||||
|
width: 33.r,
|
||||||
|
height: 33.r,
|
||||||
|
)*/
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 30.r,
|
||||||
|
),
|
||||||
|
if(examOrigin != null && examOrigin!.pageIndex < examOriginList.length)
|
||||||
|
InkWell(
|
||||||
|
onTap: () {
|
||||||
|
var num = examOrigin!.pageIndex;
|
||||||
|
if (num < examOriginList.length) {
|
||||||
|
setState(() {
|
||||||
|
examOrigin = examOriginList[num];
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
vertical: 2.r, horizontal: 5.r),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
border: Border.all(
|
||||||
|
color: Color(0xFF6787FD),
|
||||||
|
width: 1.r),
|
||||||
|
borderRadius: BorderRadius.all(
|
||||||
|
Radius.circular(2.r)),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
'上一页',
|
||||||
|
style: TextStyle(
|
||||||
|
color: Color(0xFF6787FD),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
/* Image.asset(
|
||||||
|
'assets/images/report_right_icon.png',
|
||||||
|
width: 33.r,
|
||||||
|
height: 33.r,
|
||||||
|
)*/
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
))
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _subjectText extends StatelessWidget {
|
||||||
|
final String name;
|
||||||
|
final bool isTitle;
|
||||||
|
|
||||||
|
const _subjectText(this.name, {this.isTitle = true, Key? key})
|
||||||
|
: super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Center(
|
||||||
|
child: Text(
|
||||||
|
name,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: isTitle ? 11.sp : 12.sp,
|
||||||
|
color: isTitle ? Color(0xFF667095) : Color(0xFF424242),
|
||||||
|
fontWeight: FontWeight.w400),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -8,21 +8,30 @@ import 'package:functional_widget_annotation/functional_widget_annotation.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:json_annotation/json_annotation.dart';
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
import 'package:marking_app/common/mixin/common.dart';
|
import 'package:marking_app/common/mixin/common.dart';
|
||||||
|
import 'package:marking_app/common/model/common/base_page_data_report.dart';
|
||||||
import 'package:marking_app/common/model/common/base_structure_result_report.dart';
|
import 'package:marking_app/common/model/common/base_structure_result_report.dart';
|
||||||
import 'package:marking_app/common/model/enum/reportUserIdentity.dart';
|
import 'package:marking_app/common/model/enum/reportUserIdentity.dart';
|
||||||
|
import 'package:marking_app/common/model/report/exam_records.dart';
|
||||||
|
import 'package:marking_app/common/model/report/exam_records_all.dart';
|
||||||
|
import 'package:marking_app/common/model/report/exam_records_params.dart';
|
||||||
import 'package:marking_app/common/model/report/report_histogram_model.dart';
|
import 'package:marking_app/common/model/report/report_histogram_model.dart';
|
||||||
import 'package:marking_app/common/model/report/report_home_model.dart';
|
import 'package:marking_app/common/model/report/report_home_model.dart';
|
||||||
import 'package:marking_app/common/model/user/user_info.dart';
|
import 'package:marking_app/common/model/user/user_info.dart';
|
||||||
import 'package:marking_app/common/model/user/user_info_report.dart';
|
import 'package:marking_app/common/model/user/user_info_report.dart';
|
||||||
|
import 'package:marking_app/pages/report_detail/widgets/no_data.dart';
|
||||||
import 'package:marking_app/pages/reports/bar_chart_histogram.dart';
|
import 'package:marking_app/pages/reports/bar_chart_histogram.dart';
|
||||||
import 'package:marking_app/pages/reports/services/report_home_services.dart';
|
import 'package:marking_app/pages/reports/services/report_home_services.dart';
|
||||||
import 'package:marking_app/provider/user_provider.dart';
|
import 'package:marking_app/provider/user_provider.dart';
|
||||||
import 'package:marking_app/routes/RouterManager.dart';
|
import 'package:marking_app/routes/RouterManager.dart';
|
||||||
|
import 'package:marking_app/utils/easy_refresh/MyEmptyWidget.dart';
|
||||||
import 'package:marking_app/utils/index.dart';
|
import 'package:marking_app/utils/index.dart';
|
||||||
import 'package:marking_app/utils/my_text.dart';
|
import 'package:marking_app/utils/my_text.dart';
|
||||||
import 'package:marking_app/utils/request/rest_client_report.dart';
|
import 'package:marking_app/utils/request/rest_client_report.dart';
|
||||||
import 'package:percent_indicator/linear_percent_indicator.dart';
|
import 'package:percent_indicator/linear_percent_indicator.dart';
|
||||||
|
|
||||||
|
import 'widgets/myDrawer.dart';
|
||||||
|
import 'widgets/userInfo.dart';
|
||||||
|
|
||||||
part 'index.g.dart';
|
part 'index.g.dart';
|
||||||
|
|
||||||
class TheReport extends StatefulHookConsumerWidget {
|
class TheReport extends StatefulHookConsumerWidget {
|
||||||
|
|
@ -32,20 +41,34 @@ class TheReport extends StatefulHookConsumerWidget {
|
||||||
_TheReportState createState() => _TheReportState();
|
_TheReportState createState() => _TheReportState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _TheReportState extends ConsumerState<TheReport> with CommonMixin, AutomaticKeepAliveClientMixin {
|
class _TheReportState extends ConsumerState<TheReport>
|
||||||
|
with CommonMixin, AutomaticKeepAliveClientMixin {
|
||||||
late RemoveListener _userReportListener;
|
late RemoveListener _userReportListener;
|
||||||
|
late RestClientReport ClientReport;
|
||||||
|
|
||||||
late UserInfo _user;
|
late UserInfo _user;
|
||||||
late UserInfoReport _userReport;
|
late UserInfoReport _userReport;
|
||||||
late Future<ReportHomeModel?> _future;
|
late Future<ReportHomeModel?> _future;
|
||||||
int? theExamId;
|
int? theExamId;
|
||||||
|
List gradeList = [];
|
||||||
|
List testTypeList = [];
|
||||||
|
List selectList = [];
|
||||||
|
bool isGrade = false;
|
||||||
|
ComboData currentGrade = ComboData('', '');
|
||||||
|
ComboData currentTestType = ComboData('', '');
|
||||||
|
List<ExamRecords> reportList = [];
|
||||||
|
bool showGrade = false;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool get wantKeepAlive => true;
|
bool get wantKeepAlive => true;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
_future = initData();
|
getHomeComboExam();
|
||||||
|
// getExamTypeList();
|
||||||
|
// getGradeEnumList();
|
||||||
|
|
||||||
|
// _future = initData();
|
||||||
Future.delayed(Duration.zero, () {
|
Future.delayed(Duration.zero, () {
|
||||||
_user = ref.read(userProvider);
|
_user = ref.read(userProvider);
|
||||||
_userReportListener = ref.read(userReportProvider.notifier).addListener(
|
_userReportListener = ref.read(userReportProvider.notifier).addListener(
|
||||||
|
|
@ -67,6 +90,91 @@ class _TheReportState extends ConsumerState<TheReport> with CommonMixin, Automat
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//获取考试类别、年级
|
||||||
|
void getHomeComboExam() async {
|
||||||
|
RestClientReport clientReport = await getClientReport();
|
||||||
|
BaseStructureResultReport<ExamRecordsAll> res =
|
||||||
|
await clientReport.getHomeCombo();
|
||||||
|
testTypeList = res.data!.type.comboData;
|
||||||
|
gradeList = res.data!.grade.comboData;
|
||||||
|
testTypeList[0].isCheck = true;
|
||||||
|
gradeList[0].isCheck = true;
|
||||||
|
setState(() {
|
||||||
|
currentTestType = testTypeList[0];
|
||||||
|
currentGrade = gradeList[0];
|
||||||
|
});
|
||||||
|
// getExamRecordsList();
|
||||||
|
getLevel();
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取考试类别
|
||||||
|
/* void getExamTypeList() async {
|
||||||
|
RestClientReport clientReport = await getClientReport();
|
||||||
|
BaseStructureResultReport<ExamType> res = await clientReport.getExamType();
|
||||||
|
testTypeList = res.data!.comboData;
|
||||||
|
testTypeList[0].isCheck = true;
|
||||||
|
setState(() {
|
||||||
|
currentTestType = testTypeList[0];
|
||||||
|
});
|
||||||
|
}*/
|
||||||
|
/* //获取年级
|
||||||
|
void getGradeEnumList() async {
|
||||||
|
RestClientReport clientReport = await getClientReport();
|
||||||
|
BaseStructureResultReport<List<ComboData>> result = await clientReport.getGradeEnum();
|
||||||
|
gradeList = result.data!;
|
||||||
|
|
||||||
|
print(gradeList);
|
||||||
|
gradeList[0].isCheck = true;
|
||||||
|
setState(() {
|
||||||
|
currentGrade = gradeList[0];
|
||||||
|
});
|
||||||
|
}*/
|
||||||
|
//获取列表数据
|
||||||
|
void getExamRecordsList() async {
|
||||||
|
RestClientReport clientReport = await getClientReport();
|
||||||
|
ExamRecordsParams params = ExamRecordsParams(
|
||||||
|
reportType: currentTestType.value,
|
||||||
|
grade: currentGrade.value,
|
||||||
|
page: 1,
|
||||||
|
limit: 10);
|
||||||
|
BaseStructureResultReport<BasePageDataReport<ExamRecords>> result =
|
||||||
|
await clientReport.getExamrecords(params);
|
||||||
|
setState(() {
|
||||||
|
reportList = result.data!.items;
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void checkHandle(item) {
|
||||||
|
setState(() {
|
||||||
|
if (isGrade) {
|
||||||
|
gradeList.forEach((element) {
|
||||||
|
element.isCheck = false;
|
||||||
|
});
|
||||||
|
item.isCheck = true;
|
||||||
|
currentGrade = item;
|
||||||
|
} else {
|
||||||
|
testTypeList.forEach((element) {
|
||||||
|
element.isCheck = false;
|
||||||
|
});
|
||||||
|
item.isCheck = true;
|
||||||
|
currentTestType = item;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void getLevel() async {
|
||||||
|
getExamRecordsList();
|
||||||
|
RestClientReport clientReport = await getClientReport();
|
||||||
|
BaseStructureResultReport res =
|
||||||
|
await clientReport.getPositionlevel(currentGrade.text);
|
||||||
|
if (res.data <= 3) {
|
||||||
|
showGrade = true;
|
||||||
|
}else{
|
||||||
|
showGrade = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// 初始化数据
|
/// 初始化数据
|
||||||
Future<ReportHomeModel?> initData({int? examId}) async {
|
Future<ReportHomeModel?> initData({int? examId}) async {
|
||||||
try {
|
try {
|
||||||
|
|
@ -74,12 +182,14 @@ class _TheReportState extends ConsumerState<TheReport> with CommonMixin, Automat
|
||||||
UserInfoReport _userReport = ref.read(userReportProvider);
|
UserInfoReport _userReport = ref.read(userReportProvider);
|
||||||
if (!_userReport.normal) {
|
if (!_userReport.normal) {
|
||||||
// 用户职位数据是否已经请求,在主页已经请求一次 为正常使用 备用
|
// 用户职位数据是否已经请求,在主页已经请求一次 为正常使用 备用
|
||||||
bool theFlag = await ref.read(userReportProvider.notifier).initUserReport();
|
bool theFlag =
|
||||||
|
await ref.read(userReportProvider.notifier).initUserReport();
|
||||||
if (!theFlag) {
|
if (!theFlag) {
|
||||||
return ToastUtils.showError('请求失败请重试');
|
return ToastUtils.showError('请求失败请重试');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BaseStructureResultReport<ReportHomeModel> res = await clientReport.getReportHomeData(examId);
|
BaseStructureResultReport<ReportHomeModel> res =
|
||||||
|
await clientReport.getReportHomeData(examId);
|
||||||
if (res.success) {
|
if (res.success) {
|
||||||
return res.data;
|
return res.data;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -99,6 +209,7 @@ class _TheReportState extends ConsumerState<TheReport> with CommonMixin, Automat
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var _scaffoldkey = new GlobalKey<ScaffoldState>(); //将Scaffold设置为全局变量
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
super.build(context); //调用super.build(返回值始终返回null,应将其忽略)
|
super.build(context); //调用super.build(返回值始终返回null,应将其忽略)
|
||||||
|
|
@ -113,45 +224,334 @@ class _TheReportState extends ConsumerState<TheReport> with CommonMixin, Automat
|
||||||
statusBarBrightness: Brightness.light,
|
statusBarBrightness: Brightness.light,
|
||||||
),
|
),
|
||||||
child: Scaffold(
|
child: Scaffold(
|
||||||
body: Stack(
|
key: _scaffoldkey,
|
||||||
children: [
|
drawer: MyDrawer(
|
||||||
// 渐变背景色
|
list: selectList,
|
||||||
$ScaffoldBgc(),
|
isGrade: isGrade,
|
||||||
|
onChanged: checkHandle,
|
||||||
|
refresh: getLevel),
|
||||||
|
body: Column(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
color: Colors.white,
|
||||||
|
padding: EdgeInsets.only(
|
||||||
|
top: MediaQuery.of(context).padding.top + 4.h,
|
||||||
|
left: 14.w,
|
||||||
|
right: 14.w,
|
||||||
|
bottom: 19.h),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: TopUserInfo(),
|
||||||
|
),
|
||||||
|
/* InkWell(
|
||||||
|
onTap: () {},
|
||||||
|
child: Text(
|
||||||
|
'历史报告',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.sp,
|
||||||
|
color: Color.fromRGBO(128, 128, 128, 1)),
|
||||||
|
),
|
||||||
|
),*/
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.only(left: 14.w, right: 14.w),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
height: 50.r,
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Image.asset(
|
||||||
|
'assets/images/school_icon.png',
|
||||||
|
width: 22.w,
|
||||||
|
height: 22.w,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'远轩高级中学',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.sp,
|
||||||
|
color: Color.fromRGBO(62, 86, 173, 1)),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
InkWell(
|
||||||
|
onTap: () {
|
||||||
|
setState(() {
|
||||||
|
selectList = gradeList;
|
||||||
|
isGrade = true;
|
||||||
|
_scaffoldkey.currentState?.openDrawer();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
vertical: 8.h, horizontal: 20.r),
|
||||||
|
width:
|
||||||
|
MediaQuery.of(context).size.width / 2 - 50.r,
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'年级:',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.sp,
|
||||||
|
color: Color(0xFF585858)),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
currentGrade.text,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.sp,
|
||||||
|
color: Color(0xFF6686FD)),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Color.fromRGBO(197, 220, 255, 0.3),
|
||||||
|
borderRadius: BorderRadius.circular(20.r),
|
||||||
|
border: Border.all(
|
||||||
|
color: Color(0xFFC0DCFF), width: 1.r),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
InkWell(
|
||||||
|
onTap: () {
|
||||||
|
setState(() {
|
||||||
|
selectList = testTypeList;
|
||||||
|
isGrade = false;
|
||||||
|
_scaffoldkey.currentState?.openDrawer();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
vertical: 8.h, horizontal: 20.r),
|
||||||
|
width:
|
||||||
|
MediaQuery.of(context).size.width / 2 - 60.r,
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'考试类别:',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.sp,
|
||||||
|
color: Color(0xFF585858)),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
currentTestType.text,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.sp,
|
||||||
|
color: Color(0xFF6686FD)),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Color.fromRGBO(197, 220, 255, 0.3),
|
||||||
|
borderRadius: BorderRadius.circular(20.r),
|
||||||
|
border: Border.all(
|
||||||
|
color: Color(0xFFC0DCFF), width: 1.r),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 20.r,
|
||||||
|
),
|
||||||
|
|
||||||
RefreshIndicator(
|
Expanded(
|
||||||
displacement: 50,
|
child: reportList.length>0?ListView.builder(
|
||||||
color: Theme.of(context).primaryColor,
|
itemBuilder: (BuildContext context, int index) {
|
||||||
backgroundColor: Colors.white,
|
var item = reportList[index];
|
||||||
child: MyFutureBuilder.buildFutureBuilderOfSingleInstance<ReportHomeModel>(context, _future,
|
return Container(
|
||||||
(ReportHomeModel? datas) {
|
// padding: EdgeInsets.all(6.r),
|
||||||
return _TheReportBody(
|
margin: EdgeInsets.only(bottom: 20.r),
|
||||||
user: _user,
|
width: double.infinity,
|
||||||
userReport: _userReport,
|
decoration: BoxDecoration(
|
||||||
data: datas,
|
image: DecorationImage(
|
||||||
refreshReport: () {
|
image: AssetImage(
|
||||||
_future = initData();
|
'assets/images/reports_bg.png'),
|
||||||
toUpState(setState, () {}, mounted);
|
fit: BoxFit.fill,
|
||||||
},
|
),
|
||||||
switchCall: (int? examId, int positionIndex) {
|
border: Border.all(
|
||||||
theExamId = examId;
|
width: 1.r,
|
||||||
if (examId != null) {
|
color: Color.fromRGBO(46, 91, 255, 0.2)),
|
||||||
ref.read(userReportProvider.notifier).setPositionIndex(positionIndex);
|
borderRadius: BorderRadius.circular(5.r),
|
||||||
|
),
|
||||||
_future = initData(examId: examId);
|
child: Column(
|
||||||
toUpState(setState, () {}, mounted);
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
}
|
children: [
|
||||||
},
|
Row(
|
||||||
);
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
}),
|
crossAxisAlignment:
|
||||||
onRefresh: () async {
|
CrossAxisAlignment.center,
|
||||||
_future = initData(examId: theExamId);
|
children: [
|
||||||
await _future;
|
Container(
|
||||||
await Future.delayed(Duration(seconds: 1), () => toUpState(setState, () => {}, mounted));
|
padding: EdgeInsets.symmetric(
|
||||||
},
|
vertical: 20.r, horizontal: 25.r),
|
||||||
),
|
decoration: BoxDecoration(
|
||||||
],
|
image: DecorationImage(
|
||||||
),
|
image: AssetImage(
|
||||||
),
|
'assets/images/report_group_bg.png'),
|
||||||
|
fit: BoxFit.fill,
|
||||||
|
)),
|
||||||
|
child: Text(
|
||||||
|
item.typeName,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.sp,
|
||||||
|
color: Colors.white),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
item.name,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.sp,
|
||||||
|
color: Colors.black),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
padding:
|
||||||
|
EdgeInsets.symmetric(horizontal: 10.r),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(5.r),
|
||||||
|
),
|
||||||
|
child: Table(
|
||||||
|
defaultVerticalAlignment:
|
||||||
|
TableCellVerticalAlignment.middle,
|
||||||
|
border: TableBorder.symmetric(
|
||||||
|
inside: BorderSide(
|
||||||
|
width: 1, color: Color(0xFFD7DBF0)),
|
||||||
|
outside: BorderSide.none,
|
||||||
|
),
|
||||||
|
// borderRadius: BorderRadius.circular(5.r),
|
||||||
|
children: [
|
||||||
|
TableRow(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Color(0xFFECECEC),
|
||||||
|
),
|
||||||
|
children: [
|
||||||
|
Center(
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
vertical: 6.r),
|
||||||
|
child: Text(
|
||||||
|
'年级',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.sp,
|
||||||
|
color: Color(0xFF8A8A8A)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Center(
|
||||||
|
child: Text(
|
||||||
|
'科目',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.sp,
|
||||||
|
color: Color(0xFF8A8A8A)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Center(
|
||||||
|
child: Text(
|
||||||
|
'考试日期',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.sp,
|
||||||
|
color: Color(0xFF8A8A8A)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
TableRow(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
children: [
|
||||||
|
Center(
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
vertical: 6.r),
|
||||||
|
child: Text(
|
||||||
|
item.grade,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.sp,
|
||||||
|
color:
|
||||||
|
Color(0xFF4A4A4A)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Center(
|
||||||
|
child: Text(
|
||||||
|
item.subjectStr,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.sp,
|
||||||
|
color: Color(0xFF4A4A4A)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Center(
|
||||||
|
child: Text(
|
||||||
|
item.startTimeStr,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.sp,
|
||||||
|
color: Color(0xFF4A4A4A)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
])
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
InkWell(
|
||||||
|
onTap: () {
|
||||||
|
RouterManager.router.navigateTo(
|
||||||
|
context,
|
||||||
|
RouterManager.reportDetailPath +
|
||||||
|
'?examId=${item.id}&showGrade=${showGrade}',
|
||||||
|
transition: getTransition(),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
margin: EdgeInsets.symmetric(
|
||||||
|
horizontal: 60.r, vertical: 20.r),
|
||||||
|
padding:
|
||||||
|
EdgeInsets.symmetric(vertical: 5.r),
|
||||||
|
width: double.infinity,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius:
|
||||||
|
BorderRadius.circular(20.r),
|
||||||
|
gradient: LinearGradient(
|
||||||
|
begin: Alignment(0.95, -0.30),
|
||||||
|
end: Alignment(-0.95, 0.3),
|
||||||
|
colors: [
|
||||||
|
Color(0xFF3561FE),
|
||||||
|
Color(0xFF6A89FC)
|
||||||
|
])),
|
||||||
|
child: Center(
|
||||||
|
child: Text(
|
||||||
|
'查看报告',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16.sp,
|
||||||
|
color: Colors.white),
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
itemCount: reportList.length,
|
||||||
|
):MyEmptyWidget(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -176,24 +576,33 @@ class _TheReportBody extends HookWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
ExamData? examData = data?.examData;
|
ExamData? examData = data?.examData;
|
||||||
List<ReportHistogramModel>? tagComparisonList =
|
List<ReportHistogramModel>? tagComparisonList = examData?.tagComparisonList
|
||||||
examData?.tagComparisonList.map((e) => ReportHistogramModel(name: e.name, val: e.count)).toList();
|
.map((e) => ReportHistogramModel(name: e.name, val: e.count))
|
||||||
|
.toList();
|
||||||
List<ExamSubjectDatas>? examSubjectDatas = data?.examSubjectDatas;
|
List<ExamSubjectDatas>? examSubjectDatas = data?.examSubjectDatas;
|
||||||
|
|
||||||
List<Positions> _positions = userReport.positions;
|
List<Positions> _positions = userReport.positions;
|
||||||
|
|
||||||
SwitchIdentityExamsController potnAndExamCotl = SwitchIdentityExamsController.use(
|
SwitchIdentityExamsController potnAndExamCotl =
|
||||||
position: userReport.positionIndex, exam: -1, initExamId: examData?.examId, positons: userReport.positions);
|
SwitchIdentityExamsController.use(
|
||||||
Positions? theCurrentPosition = _positions.isEmpty ? null : _positions[potnAndExamCotl.positionIndex.value];
|
position: userReport.positionIndex,
|
||||||
|
exam: -1,
|
||||||
|
initExamId: examData?.examId,
|
||||||
|
positons: userReport.positions);
|
||||||
|
Positions? theCurrentPosition = _positions.isEmpty
|
||||||
|
? null
|
||||||
|
: _positions[potnAndExamCotl.positionIndex.value];
|
||||||
|
|
||||||
if (examData == null || theCurrentPosition == null) {
|
if (examData == null || theCurrentPosition == null) {
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: EdgeInsets.only(left: 16.w, right: 16.w, top: MediaQuery.of(context).padding.top),
|
padding: EdgeInsets.only(
|
||||||
|
left: 16.w, right: 16.w, top: MediaQuery.of(context).padding.top),
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
$ReportTitle(
|
$ReportTitle(
|
||||||
titleName: '',
|
titleName: '',
|
||||||
switchCall: () => easyThrottle('reportHomeExamSwitchCall', () async {
|
switchCall: () =>
|
||||||
|
easyThrottle('reportHomeExamSwitchCall', () async {
|
||||||
// switchCall(examId, potnAndExamCotl.positionIndex.value);
|
// switchCall(examId, potnAndExamCotl.positionIndex.value);
|
||||||
List<Positions> positions = userReport.positions;
|
List<Positions> positions = userReport.positions;
|
||||||
if (positions.isEmpty) {
|
if (positions.isEmpty) {
|
||||||
|
|
@ -215,8 +624,10 @@ class _TheReportBody extends HookWidget {
|
||||||
//按钮被按下时的不透明度程度,0~1之间
|
//按钮被按下时的不透明度程度,0~1之间
|
||||||
pressedOpacity: 1,
|
pressedOpacity: 1,
|
||||||
//这也可以自己定义Container然后固定大小进行设置等等
|
//这也可以自己定义Container然后固定大小进行设置等等
|
||||||
child: quickText('没有数据,请重试', color: Colors.white, size: 14.sp),
|
child:
|
||||||
onPressed: () => easyThrottle('reportHomeNoDataAgain', () => refreshReport()),
|
quickText('没有数据,请重试', color: Colors.white, size: 14.sp),
|
||||||
|
onPressed: () => easyThrottle(
|
||||||
|
'reportHomeNoDataAgain', () => refreshReport()),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -228,20 +639,24 @@ class _TheReportBody extends HookWidget {
|
||||||
|
|
||||||
// 内容区域
|
// 内容区域
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: EdgeInsets.only(left: 16.w, right: 16.w, top: MediaQuery.of(context).padding.top),
|
padding: EdgeInsets.only(
|
||||||
|
left: 16.w, right: 16.w, top: MediaQuery.of(context).padding.top),
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
SizedBox(height: 6.h),
|
SizedBox(height: 6.h),
|
||||||
// 考试报告TITLE
|
// 考试报告TITLE
|
||||||
$ReportTitle(
|
$ReportTitle(
|
||||||
titleName: examData.examName,
|
titleName: examData.examName,
|
||||||
switchCall: () => easyThrottle('reportHomeExamSwitchCall', () async {
|
switchCall: () =>
|
||||||
|
easyThrottle('reportHomeExamSwitchCall', () async {
|
||||||
List<Positions> positions = userReport.positions;
|
List<Positions> positions = userReport.positions;
|
||||||
if (positions.isEmpty) {
|
if (positions.isEmpty) {
|
||||||
return ToastUtils.showInfo('没有数据,请刷新');
|
return ToastUtils.showInfo('没有数据,请刷新');
|
||||||
}
|
}
|
||||||
int? examId = await potnAndExamCotl.openSwitch(
|
int? examId = await potnAndExamCotl.openSwitch(
|
||||||
context: context, currentExamId: examData.examId, currentPositionIndex: userReport.positionIndex);
|
context: context,
|
||||||
|
currentExamId: examData.examId,
|
||||||
|
currentPositionIndex: userReport.positionIndex);
|
||||||
|
|
||||||
switchCall(examId, potnAndExamCotl.positionIndex.value);
|
switchCall(examId, potnAndExamCotl.positionIndex.value);
|
||||||
}),
|
}),
|
||||||
|
|
@ -254,7 +669,9 @@ class _TheReportBody extends HookWidget {
|
||||||
children: [
|
children: [
|
||||||
// 顶部平均分模块
|
// 顶部平均分模块
|
||||||
$TopAverageContainer(
|
$TopAverageContainer(
|
||||||
averageVal: examData.averageScore, totalVal: examData.totalScore, context: context),
|
averageVal: examData.averageScore,
|
||||||
|
totalVal: examData.totalScore,
|
||||||
|
context: context),
|
||||||
|
|
||||||
// 详细报告入口区域
|
// 详细报告入口区域
|
||||||
$DetailedReportEntry(
|
$DetailedReportEntry(
|
||||||
|
|
@ -282,7 +699,8 @@ class _TheReportBody extends HookWidget {
|
||||||
$GraphicDataArea(
|
$GraphicDataArea(
|
||||||
title: '单科概况',
|
title: '单科概况',
|
||||||
titleImg: 'assets/images/report_home_icon_subject.png',
|
titleImg: 'assets/images/report_home_icon_subject.png',
|
||||||
graphicContainer: $TheProgressChart(context, examSubjectDatas!)),
|
graphicContainer:
|
||||||
|
$TheProgressChart(context, examSubjectDatas!)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -335,11 +753,13 @@ Widget $reportTitle({required String titleName, required switchCall}) {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
InkWell(
|
InkWell(
|
||||||
onTap: () => easyThrottle('switchRoleExamSheetCall', () => switchCall()),
|
onTap: () =>
|
||||||
|
easyThrottle('switchRoleExamSheetCall', () => switchCall()),
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
Icon(Icons.swap_vert_rounded, color: Color.fromRGBO(80, 87, 103, 0.8), size: 16.sp),
|
Icon(Icons.swap_vert_rounded,
|
||||||
|
color: Color.fromRGBO(80, 87, 103, 0.8), size: 16.sp),
|
||||||
quickText('切换', color: Color.fromRGBO(80, 87, 103, 1), size: 12.sp),
|
quickText('切换', color: Color.fromRGBO(80, 87, 103, 1), size: 12.sp),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
@ -350,7 +770,10 @@ Widget $reportTitle({required String titleName, required switchCall}) {
|
||||||
|
|
||||||
/// 顶部平均分模块
|
/// 顶部平均分模块
|
||||||
@swidget
|
@swidget
|
||||||
Widget $topAverageContainer({required double averageVal, required double totalVal, required BuildContext context}) {
|
Widget $topAverageContainer(
|
||||||
|
{required double averageVal,
|
||||||
|
required double totalVal,
|
||||||
|
required BuildContext context}) {
|
||||||
return Stack(
|
return Stack(
|
||||||
alignment: const FractionalOffset(0.99, 0),
|
alignment: const FractionalOffset(0.99, 0),
|
||||||
children: [
|
children: [
|
||||||
|
|
@ -366,7 +789,8 @@ Widget $topAverageContainer({required double averageVal, required double totalVa
|
||||||
borderRadius: BorderRadius.circular(3).r,
|
borderRadius: BorderRadius.circular(3).r,
|
||||||
child: Container(
|
child: Container(
|
||||||
alignment: Alignment.centerLeft,
|
alignment: Alignment.centerLeft,
|
||||||
padding: EdgeInsets.only(left: 4, right: 4, top: 4, bottom: 7).r,
|
padding:
|
||||||
|
EdgeInsets.only(left: 4, right: 4, top: 4, bottom: 7).r,
|
||||||
child: quickText('平均分', size: 6.sp, color: Colors.white),
|
child: quickText('平均分', size: 6.sp, color: Colors.white),
|
||||||
decoration: ShapeDecoration(
|
decoration: ShapeDecoration(
|
||||||
shape: BeveledRectangleBorder(
|
shape: BeveledRectangleBorder(
|
||||||
|
|
@ -380,22 +804,29 @@ Widget $topAverageContainer({required double averageVal, required double totalVa
|
||||||
gradient: LinearGradient(
|
gradient: LinearGradient(
|
||||||
begin: Alignment.topCenter,
|
begin: Alignment.topCenter,
|
||||||
end: Alignment.bottomCenter,
|
end: Alignment.bottomCenter,
|
||||||
colors: [Theme.of(context).primaryColor, Theme.of(context).primaryColor.withOpacity(0.3)],
|
colors: [
|
||||||
|
Theme.of(context).primaryColor,
|
||||||
|
Theme.of(context).primaryColor.withOpacity(0.3)
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox(height: 1.h),
|
SizedBox(height: 1.h),
|
||||||
quickText(averageVal.toString(),
|
quickText(averageVal.toString(),
|
||||||
size: 38.sp, color: Color.fromRGBO(45, 56, 76, 1), fontWeight: FontWeight.bold),
|
size: 38.sp,
|
||||||
|
color: Color.fromRGBO(45, 56, 76, 1),
|
||||||
|
fontWeight: FontWeight.bold),
|
||||||
SizedBox(height: 1.h),
|
SizedBox(height: 1.h),
|
||||||
quickText('满分' + totalVal.toString(), size: 12.sp, color: Color.fromRGBO(80, 87, 103, 0.7)),
|
quickText('满分' + totalVal.toString(),
|
||||||
|
size: 12.sp, color: Color.fromRGBO(80, 87, 103, 0.7)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Image.asset("assets/images/report_home_top_img.png", width: 100.r, height: 100.r)
|
Image.asset("assets/images/report_home_top_img.png",
|
||||||
|
width: 100.r, height: 100.r)
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -441,9 +872,13 @@ Widget $detailedReportEntry({
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
quickText('年级', size: 12.sp, color: Color.fromRGBO(80, 87, 103, 1)),
|
quickText('年级',
|
||||||
|
size: 12.sp, color: Color.fromRGBO(80, 87, 103, 1)),
|
||||||
SizedBox(height: 5.h),
|
SizedBox(height: 5.h),
|
||||||
quickText(grade, size: 16.sp, fontWeight: FontWeight.bold, color: Color.fromRGBO(45, 56, 76, 1)),
|
quickText(grade,
|
||||||
|
size: 16.sp,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: Color.fromRGBO(45, 56, 76, 1)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
SizedBox(width: 23.w),
|
SizedBox(width: 23.w),
|
||||||
|
|
@ -454,10 +889,14 @@ Widget $detailedReportEntry({
|
||||||
Column(
|
Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
quickText('学科', size: 12.sp, color: Color.fromRGBO(80, 87, 103, 1)),
|
quickText('学科',
|
||||||
|
size: 12.sp, color: Color.fromRGBO(80, 87, 103, 1)),
|
||||||
SizedBox(height: 5.h),
|
SizedBox(height: 5.h),
|
||||||
quickText(subject,
|
quickText(subject,
|
||||||
size: 16.sp, fontWeight: FontWeight.bold, color: Color.fromRGBO(45, 56, 76, 1), maxLines: 2),
|
size: 16.sp,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: Color.fromRGBO(45, 56, 76, 1),
|
||||||
|
maxLines: 2),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
|
|
@ -468,9 +907,13 @@ Widget $detailedReportEntry({
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
quickText('考试日期', size: 12.sp, color: Color.fromRGBO(80, 87, 103, 1)),
|
quickText('考试日期',
|
||||||
|
size: 12.sp, color: Color.fromRGBO(80, 87, 103, 1)),
|
||||||
SizedBox(height: 5.h),
|
SizedBox(height: 5.h),
|
||||||
quickText(examDate, size: 16.sp, fontWeight: FontWeight.bold, color: Color.fromRGBO(45, 56, 76, 1)),
|
quickText(examDate,
|
||||||
|
size: 16.sp,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: Color.fromRGBO(45, 56, 76, 1)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
@ -485,7 +928,8 @@ Widget $detailedReportEntry({
|
||||||
'?examId=$examId&classId=$classId&subject=$subjectId&subjectName=${Uri.encodeComponent(subjectName)}';
|
'?examId=$examId&classId=$classId&subject=$subjectId&subjectName=${Uri.encodeComponent(subjectName)}';
|
||||||
break;
|
break;
|
||||||
case ReportUserIdentity.CLASS: // 班主任
|
case ReportUserIdentity.CLASS: // 班主任
|
||||||
rootPath = RouterManager.reportClassTeacherPath + '?examId=$examId';
|
rootPath =
|
||||||
|
RouterManager.reportClassTeacherPath + '?examId=$examId';
|
||||||
break;
|
break;
|
||||||
case ReportUserIdentity.GRADE: // 年级
|
case ReportUserIdentity.GRADE: // 年级
|
||||||
case ReportUserIdentity.SCHOOL_LEVEL: // 校级
|
case ReportUserIdentity.SCHOOL_LEVEL: // 校级
|
||||||
|
|
@ -500,7 +944,8 @@ Widget $detailedReportEntry({
|
||||||
color: Theme.of(context).primaryColor,
|
color: Theme.of(context).primaryColor,
|
||||||
).show(context);
|
).show(context);
|
||||||
}
|
}
|
||||||
RouterManager.router.navigateTo(context, rootPath, transition: getTransition());
|
RouterManager.router
|
||||||
|
.navigateTo(context, rootPath, transition: getTransition());
|
||||||
}),
|
}),
|
||||||
child: Container(
|
child: Container(
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
|
|
@ -512,7 +957,10 @@ Widget $detailedReportEntry({
|
||||||
gradient: LinearGradient(
|
gradient: LinearGradient(
|
||||||
begin: Alignment.topCenter,
|
begin: Alignment.topCenter,
|
||||||
end: Alignment.bottomCenter,
|
end: Alignment.bottomCenter,
|
||||||
colors: [Color.fromRGBO(54, 86, 255, 1), Color.fromRGBO(93, 128, 255, 1)],
|
colors: [
|
||||||
|
Color.fromRGBO(54, 86, 255, 1),
|
||||||
|
Color.fromRGBO(93, 128, 255, 1)
|
||||||
|
],
|
||||||
),
|
),
|
||||||
boxShadow: [
|
boxShadow: [
|
||||||
BoxShadow(
|
BoxShadow(
|
||||||
|
|
@ -523,7 +971,8 @@ Widget $detailedReportEntry({
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
child: quickText('查看详细报告', color: Colors.white, size: 14.sp, fontWeight: FontWeight.w400),
|
child: quickText('查看详细报告',
|
||||||
|
color: Colors.white, size: 14.sp, fontWeight: FontWeight.w400),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
@ -533,7 +982,10 @@ Widget $detailedReportEntry({
|
||||||
|
|
||||||
/// 图形数据模块
|
/// 图形数据模块
|
||||||
@swidget
|
@swidget
|
||||||
Widget $graphicDataArea({required String title, required String titleImg, required Widget graphicContainer}) {
|
Widget $graphicDataArea(
|
||||||
|
{required String title,
|
||||||
|
required String titleImg,
|
||||||
|
required Widget graphicContainer}) {
|
||||||
return Container(
|
return Container(
|
||||||
margin: EdgeInsets.only(bottom: 28.h),
|
margin: EdgeInsets.only(bottom: 28.h),
|
||||||
child: Column(
|
child: Column(
|
||||||
|
|
@ -587,7 +1039,8 @@ Widget $theProgressChart(context, List<ExamSubjectDatas> datas) {
|
||||||
return $theProgressWidget(
|
return $theProgressWidget(
|
||||||
context: context,
|
context: context,
|
||||||
isMultiple: isMultiple,
|
isMultiple: isMultiple,
|
||||||
linearGradient: LinearGradient(colors: [Colors.white, Theme.of(context).primaryColor]),
|
linearGradient: LinearGradient(
|
||||||
|
colors: [Colors.white, Theme.of(context).primaryColor]),
|
||||||
subjectName: e.subjectName + '平均分',
|
subjectName: e.subjectName + '平均分',
|
||||||
suffixTitle: e.totalScoreStr + '分',
|
suffixTitle: e.totalScoreStr + '分',
|
||||||
contentVal: e.averageScoreStr + '分',
|
contentVal: e.averageScoreStr + '分',
|
||||||
|
|
@ -603,7 +1056,8 @@ Widget $theProgressChart(context, List<ExamSubjectDatas> datas) {
|
||||||
return $theProgressWidget(
|
return $theProgressWidget(
|
||||||
context: context,
|
context: context,
|
||||||
isMultiple: isMultiple,
|
isMultiple: isMultiple,
|
||||||
linearGradient: LinearGradient(colors: [Colors.white, Color.fromRGBO(0, 131, 253, 1)]),
|
linearGradient: LinearGradient(
|
||||||
|
colors: [Colors.white, Color.fromRGBO(0, 131, 253, 1)]),
|
||||||
subjectName: e.subjectName + '及格率',
|
subjectName: e.subjectName + '及格率',
|
||||||
suffixTitle: '100%',
|
suffixTitle: '100%',
|
||||||
contentVal: e.passRateStr + '%',
|
contentVal: e.passRateStr + '%',
|
||||||
|
|
@ -637,14 +1091,18 @@ Widget $theProgressWidget({
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
quickText(subjectName, size: 14.sp, color: Color.fromRGBO(45, 56, 76, 1), fontWeight: FontWeight.w400),
|
quickText(subjectName,
|
||||||
|
size: 14.sp,
|
||||||
|
color: Color.fromRGBO(45, 56, 76, 1),
|
||||||
|
fontWeight: FontWeight.w400),
|
||||||
SizedBox(height: 6.h),
|
SizedBox(height: 6.h),
|
||||||
Row(
|
Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: LinearPercentIndicator(
|
child: LinearPercentIndicator(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 0, vertical: 0),
|
padding:
|
||||||
|
const EdgeInsets.symmetric(horizontal: 0, vertical: 0),
|
||||||
// width: MediaQuery.of(context).size.width - 50,
|
// width: MediaQuery.of(context).size.width - 50,
|
||||||
animation: true,
|
animation: true,
|
||||||
lineHeight: 9.h,
|
lineHeight: 9.h,
|
||||||
|
|
@ -657,7 +1115,8 @@ Widget $theProgressWidget({
|
||||||
// ),
|
// ),
|
||||||
// linearStrokeCap: LinearStrokeCap.butt,
|
// linearStrokeCap: LinearStrokeCap.butt,
|
||||||
// progressColor: Theme.of(context).primaryColor,
|
// progressColor: Theme.of(context).primaryColor,
|
||||||
backgroundColor: const Color.fromRGBO(219, 224, 243, 1).withOpacity(0.45),
|
backgroundColor: const Color.fromRGBO(219, 224, 243, 1)
|
||||||
|
.withOpacity(0.45),
|
||||||
barRadius: Radius.circular(10.h),
|
barRadius: Radius.circular(10.h),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -666,13 +1125,16 @@ Widget $theProgressWidget({
|
||||||
alignment: Alignment.centerRight,
|
alignment: Alignment.centerRight,
|
||||||
// padding: EdgeInsets.only(left: 20.w),suffixTitle
|
// padding: EdgeInsets.only(left: 20.w),suffixTitle
|
||||||
child: quickText(suffixTitle,
|
child: quickText(suffixTitle,
|
||||||
size: 12.sp, color: Color.fromRGBO(148, 163, 182, 1), fontWeight: FontWeight.w400),
|
size: 12.sp,
|
||||||
|
color: Color.fromRGBO(148, 163, 182, 1),
|
||||||
|
fontWeight: FontWeight.w400),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
quickText(contentVal, size: 12.sp, fontWeight: FontWeight.w700, color: contentColor),
|
quickText(contentVal,
|
||||||
|
size: 12.sp, fontWeight: FontWeight.w700, color: contentColor),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
|
|
||||||
|
class MyDrawer extends StatefulWidget {
|
||||||
|
final List list;
|
||||||
|
final bool isGrade;
|
||||||
|
final ValueChanged<dynamic> onChanged;
|
||||||
|
final Function refresh;
|
||||||
|
|
||||||
|
MyDrawer({required this.list, required this.isGrade, required this.onChanged,required this.refresh,Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<MyDrawer> createState() => _MyDrawerState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _MyDrawerState extends State<MyDrawer> {
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
widget.refresh();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Container(
|
||||||
|
// margin:EdgeInsets.only(top: 100.r),
|
||||||
|
child: Drawer(
|
||||||
|
width: MediaQuery.of(context).size.width / 2 - 20.r,
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.only(top: MediaQuery.of(context).padding.top + 50.r),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Text(widget.isGrade?'年级':'考试类别',style: TextStyle(fontSize: 16.sp,fontWeight: FontWeight.w500),),
|
||||||
|
Expanded(
|
||||||
|
child: ListView.builder(
|
||||||
|
itemBuilder: (BuildContext context, int index) {
|
||||||
|
var item = widget.list[index];
|
||||||
|
return InkWell(
|
||||||
|
onTap: (){
|
||||||
|
widget.onChanged(item);
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 20.r),
|
||||||
|
child: Center(
|
||||||
|
child: Text(item.text,style: TextStyle(fontSize: 14.sp,fontWeight: FontWeight.w400,color: item.isCheck?Color(0xFF5F81FD):Color(0xFF2E2E2E)),)),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
itemCount: widget.list.length,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,64 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
|
|
||||||
|
import 'package:marking_app/provider/user_provider.dart';
|
||||||
|
import 'package:marking_app/routes/RouterManager.dart';
|
||||||
|
import 'package:marking_app/utils/index.dart';
|
||||||
|
|
||||||
|
class TopUserInfo extends ConsumerWidget {
|
||||||
|
const TopUserInfo({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
final userState = ref.watch(userProvider);
|
||||||
|
|
||||||
|
return InkWell(
|
||||||
|
onTap: () {
|
||||||
|
RouterManager.router.navigateTo(context, RouterManager.userMinePath, transition: getTransition());
|
||||||
|
},
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Color.fromRGBO(245, 246, 251, 1),
|
||||||
|
borderRadius: BorderRadius.circular(30.r),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
ClipRRect(
|
||||||
|
borderRadius: BorderRadius.circular(50.w),
|
||||||
|
child: Container(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
color: Color.fromRGBO(163, 211, 255, 1),
|
||||||
|
padding: EdgeInsets.all(1.r),
|
||||||
|
child: Image.asset('assets/images/logo.png', width: 32.w, height: 32.w),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
margin: EdgeInsets.only(left: 10.h),
|
||||||
|
child: Text(
|
||||||
|
userState.userName,
|
||||||
|
style: TextStyle(fontSize: 15.sp, color: const Color.fromRGBO(45, 56, 76, 0.9)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 4.w),
|
||||||
|
child: Icon(
|
||||||
|
Icons.arrow_forward_ios_rounded,
|
||||||
|
size: 12.sp,
|
||||||
|
color: const Color.fromRGBO(45, 56, 76, 0.9),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(width: 5.w)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(child: SizedBox())
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -25,6 +25,7 @@ import 'package:marking_app/pages/marking/review.dart';
|
||||||
import 'package:marking_app/pages/mine/index.dart';
|
import 'package:marking_app/pages/mine/index.dart';
|
||||||
import 'package:marking_app/pages/mine/other_pages/index.dart';
|
import 'package:marking_app/pages/mine/other_pages/index.dart';
|
||||||
import 'package:marking_app/pages/other/agreement_page.dart';
|
import 'package:marking_app/pages/other/agreement_page.dart';
|
||||||
|
import 'package:marking_app/pages/report_detail/index.dart';
|
||||||
import 'package:marking_app/pages/reports/report_class_teacher.dart';
|
import 'package:marking_app/pages/reports/report_class_teacher.dart';
|
||||||
import 'package:marking_app/pages/reports/report_personal_subject.dart';
|
import 'package:marking_app/pages/reports/report_personal_subject.dart';
|
||||||
import 'package:marking_app/pages/reports/report_subject_teacher.dart';
|
import 'package:marking_app/pages/reports/report_subject_teacher.dart';
|
||||||
|
|
@ -50,6 +51,7 @@ class RouterManager {
|
||||||
static const String reportSubjectTeacherPath = 'report/details/reportSubjectTeacher';
|
static const String reportSubjectTeacherPath = 'report/details/reportSubjectTeacher';
|
||||||
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';
|
||||||
// TheMine
|
// TheMine
|
||||||
|
|
||||||
static final FluroRouter router = FluroRouter();
|
static final FluroRouter router = FluroRouter();
|
||||||
|
|
@ -188,6 +190,13 @@ class RouterManager {
|
||||||
static final _userMinePageHandler = Handler(
|
static final _userMinePageHandler = Handler(
|
||||||
handlerFunc: (BuildContext? context, Map<String, List<String>> params) => TheMine(),
|
handlerFunc: (BuildContext? context, Map<String, List<String>> params) => TheMine(),
|
||||||
);
|
);
|
||||||
|
static final _reportDetailPath = Handler(
|
||||||
|
handlerFunc: (BuildContext? context, Map<String, List<String>> params){
|
||||||
|
int examId = int.parse(params['examId']![0]);
|
||||||
|
bool showGrade = params['showGrade']![0] == 'true';
|
||||||
|
return ReportDetail(examId: examId,showGrade:showGrade);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
static final _reportPersonalSubjectPageHandler = Handler(
|
static final _reportPersonalSubjectPageHandler = Handler(
|
||||||
handlerFunc: (BuildContext? context, Map<String, List<String>> params) {
|
handlerFunc: (BuildContext? context, Map<String, List<String>> params) {
|
||||||
|
|
@ -238,6 +247,7 @@ class RouterManager {
|
||||||
router.define(reportPersonalSubjectPath,
|
router.define(reportPersonalSubjectPath,
|
||||||
handler: _reportPersonalSubjectPageHandler, transitionType: TransitionType.material);
|
handler: _reportPersonalSubjectPageHandler, transitionType: TransitionType.material);
|
||||||
router.define(userMinePath, handler: _userMinePageHandler, transitionType: TransitionType.material);
|
router.define(userMinePath, handler: _userMinePageHandler, transitionType: TransitionType.material);
|
||||||
|
router.define(reportDetailPath, handler: _reportDetailPath, transitionType: TransitionType.material);
|
||||||
|
|
||||||
// getTransition()
|
// getTransition()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,15 @@
|
||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
import 'package:marking_app/common/model/common/base_page_data_report.dart';
|
import 'package:marking_app/common/model/common/base_page_data_report.dart';
|
||||||
import 'package:marking_app/common/model/common/base_structure_result_report.dart';
|
import 'package:marking_app/common/model/common/base_structure_result_report.dart';
|
||||||
|
import 'package:marking_app/common/model/report/detail_base_info.dart';
|
||||||
|
import 'package:marking_app/common/model/report/exam_records.dart';
|
||||||
|
import 'package:marking_app/common/model/report/exam_records_all.dart';
|
||||||
|
import 'package:marking_app/common/model/report/exam_records_params.dart';
|
||||||
import 'package:marking_app/common/model/report/marked_item.dart';
|
import 'package:marking_app/common/model/report/marked_item.dart';
|
||||||
import 'package:marking_app/common/model/report/marked_item_params.dart';
|
import 'package:marking_app/common/model/report/marked_item_params.dart';
|
||||||
|
import 'package:marking_app/common/model/report/question_know_point.dart';
|
||||||
|
import 'package:marking_app/common/model/report/report_card.dart';
|
||||||
|
import 'package:marking_app/common/model/report/report_card_params.dart';
|
||||||
import 'package:marking_app/common/model/report/report_for_class_teacher_model.dart';
|
import 'package:marking_app/common/model/report/report_for_class_teacher_model.dart';
|
||||||
import 'package:marking_app/common/model/report/report_for_class_teacher_params.dart';
|
import 'package:marking_app/common/model/report/report_for_class_teacher_params.dart';
|
||||||
import 'package:marking_app/common/model/report/report_for_marking_pagerdetail_model.dart';
|
import 'package:marking_app/common/model/report/report_for_marking_pagerdetail_model.dart';
|
||||||
|
|
@ -21,6 +28,8 @@ import 'package:marking_app/common/model/report/report_for_subject_student_param
|
||||||
import 'package:marking_app/common/model/report/report_for_subject_teacher_model.dart';
|
import 'package:marking_app/common/model/report/report_for_subject_teacher_model.dart';
|
||||||
import 'package:marking_app/common/model/report/report_for_subject_teacher_params.dart';
|
import 'package:marking_app/common/model/report/report_for_subject_teacher_params.dart';
|
||||||
import 'package:marking_app/common/model/report/report_home_model.dart';
|
import 'package:marking_app/common/model/report/report_home_model.dart';
|
||||||
|
import 'package:marking_app/common/model/report/report_marking_detail.dart';
|
||||||
|
import 'package:marking_app/common/model/report/report_marking_detail_params.dart';
|
||||||
import 'package:marking_app/common/model/user/user_info_report.dart';
|
import 'package:marking_app/common/model/user/user_info_report.dart';
|
||||||
import 'package:retrofit/retrofit.dart' as the_retrofit;
|
import 'package:retrofit/retrofit.dart' as the_retrofit;
|
||||||
|
|
||||||
|
|
@ -67,4 +76,64 @@ abstract class RestClientReport {
|
||||||
@the_retrofit.POST("/api/user/template/getmarkingpagerdetails")
|
@the_retrofit.POST("/api/user/template/getmarkingpagerdetails")
|
||||||
Future<BaseStructureResultReport<ReportForMarkingPagerdetailModel>> getMarkingPagerDetails(
|
Future<BaseStructureResultReport<ReportForMarkingPagerdetailModel>> getMarkingPagerDetails(
|
||||||
@the_retrofit.Body() ReportForMarkingPagerdetailParams params);
|
@the_retrofit.Body() ReportForMarkingPagerdetailParams params);
|
||||||
|
|
||||||
|
/* // 报告 => 获取考试类别
|
||||||
|
@the_retrofit.GET("/api/user/exam/getexamtypecombo")
|
||||||
|
Future<BaseStructureResultReport<ExamType>> getExamType();*/
|
||||||
|
|
||||||
|
// 报告 => 获取年级
|
||||||
|
@the_retrofit.GET("/api/public/enum/GradeEnum")
|
||||||
|
Future<BaseStructureResultReport<List<ComboData>>> getGradeEnum();
|
||||||
|
|
||||||
|
// 报告 => 首页列表
|
||||||
|
@the_retrofit.GET("/api/user/exam/examrecords")
|
||||||
|
Future<BaseStructureResultReport<BasePageDataReport<ExamRecords>>> getExamrecords(
|
||||||
|
@the_retrofit.Queries() ExamRecordsParams params
|
||||||
|
);
|
||||||
|
|
||||||
|
// 报告 => 获取考试类别、年级
|
||||||
|
@the_retrofit.GET("/api/user/exam/mobilehomecombo")
|
||||||
|
Future<BaseStructureResultReport<ExamRecordsAll>> getHomeCombo();
|
||||||
|
|
||||||
|
// 报告 => 首页详情
|
||||||
|
@the_retrofit.GET("/api/exam/report/master_mobile")
|
||||||
|
Future<BaseStructureResultReport<DetailBaseInfo>> getReportDetail(
|
||||||
|
@the_retrofit.Query("examId") int examId, @the_retrofit.Query("classId") int classId
|
||||||
|
);
|
||||||
|
|
||||||
|
// 报告 => 考试学科
|
||||||
|
@the_retrofit.GET("/api/user/exam/examsubject")
|
||||||
|
Future<BaseStructureResultReport<List<ComboData>>> getExamsubject(
|
||||||
|
@the_retrofit.Query("examId") int examId
|
||||||
|
);
|
||||||
|
|
||||||
|
// 报告 => 可选下拉考试类型(是否有年级模块的报告权限)
|
||||||
|
@the_retrofit.GET("/api/user/exam/positionlevel")
|
||||||
|
Future<BaseStructureResultReport> getPositionlevel(
|
||||||
|
@the_retrofit.Query("grade") String grade
|
||||||
|
);
|
||||||
|
|
||||||
|
// 报告 => 可选班级
|
||||||
|
@the_retrofit.GET("/api/exam/report/classList")
|
||||||
|
Future<BaseStructureResultReport<List<ComboData>>> getClassList(
|
||||||
|
@the_retrofit.Query("examId") int examId
|
||||||
|
);
|
||||||
|
// 报告 => 可选班级
|
||||||
|
@the_retrofit.GET("/api/exam/report/master_mobilesubject")
|
||||||
|
Future<BaseStructureResultReport<QuestionKnowPoint>> getQuestionKnowPoint(
|
||||||
|
@the_retrofit.Query("examId") int examId,
|
||||||
|
@the_retrofit.Query("classId") int classId,
|
||||||
|
@the_retrofit.Query("subject") int subject
|
||||||
|
);
|
||||||
|
|
||||||
|
// 报告 =>成绩单
|
||||||
|
@the_retrofit.POST("/api/user/exam/reportcard")
|
||||||
|
Future<BaseStructureResultReport<ReportCard>> getReportCard(
|
||||||
|
@the_retrofit.Body() ReportCardParams params);
|
||||||
|
|
||||||
|
// 报告 =>阅卷详情
|
||||||
|
@the_retrofit.POST("/api/exam/report/getmarkingpagerdetails")
|
||||||
|
Future<BaseStructureResultReport<ReportMarkingDetail>> getMarkingDetail(
|
||||||
|
@the_retrofit.Body() ReportMarkingDetailParams params
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -106,6 +106,8 @@ dependencies:
|
||||||
image: ^4.1.3
|
image: ^4.1.3
|
||||||
awesome_dialog: ^3.1.0
|
awesome_dialog: ^3.1.0
|
||||||
badges: ^3.1.2
|
badges: ^3.1.2
|
||||||
|
horizontal_data_table: ^4.1.1
|
||||||
|
data_table_2: ^2.5.10
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|
|
||||||