Compare commits

..

2 Commits

Author SHA1 Message Date
machuanyu 65e57bcae8 班级基本信息字段增加 2024-02-26 10:44:27 +08:00
machuanyu 09a275b12f 报告模块 2024-02-22 17:28:59 +08:00
36 changed files with 3307 additions and 82 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 743 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 755 B

View File

@ -0,0 +1,210 @@
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;
@JsonKey(name: 'TotalRank')
int totalRank;
@JsonKey(name: 'JoinCount')
int joinCount;
BaseInfo(this.examName,this.examType,this.grade,this.subject,this.examTime,this.totalScore,this.avgScore,this.maxScore,this.rateGood,this.ratePass,this.totalRank,this.joinCount,);
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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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}&currentClass.value=${currentClass.value}&currentSubject.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}&params.classId=${params.classId}&params.page=${params.page}&params.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,!widget.showGrade || !isGrade),
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,
),
],
),
),
),
],
),
));
}
}

View File

@ -0,0 +1,121 @@
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;
final bool? showGrade;
const BasicTable(this.baseInfo, this.showGrade ,{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)),
],
),
),
),
if(showGrade == 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!.totalRank.toString(), true)),
Expanded(flex: 1, child: BasicTableCell('参考班级总数', false)),
Expanded(flex: 1, child: BasicTableCell(baseInfo!.joinCount.toString(), true)),
],
),
),
)
],
),
);
}
}

View File

@ -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),)
);
}
}

View File

@ -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)));
}
}

View File

@ -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;
}
}

View File

@ -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)));
}
}

View File

@ -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)),
)
],
),
);
}
}

View File

@ -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)),));
}
}

View File

@ -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)),),
),
);
})
);
})
),
),
);
}
}

View File

@ -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))),
),
);
}),
);
}
}

View File

@ -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),
),
);
}
}

View File

@ -8,21 +8,30 @@ import 'package:functional_widget_annotation/functional_widget_annotation.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:json_annotation/json_annotation.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/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_home_model.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/pages/report_detail/widgets/no_data.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/provider/user_provider.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/my_text.dart';
import 'package:marking_app/utils/request/rest_client_report.dart';
import 'package:percent_indicator/linear_percent_indicator.dart';
import 'widgets/myDrawer.dart';
import 'widgets/userInfo.dart';
part 'index.g.dart';
class TheReport extends StatefulHookConsumerWidget {
@ -32,20 +41,34 @@ class TheReport extends StatefulHookConsumerWidget {
_TheReportState createState() => _TheReportState();
}
class _TheReportState extends ConsumerState<TheReport> with CommonMixin, AutomaticKeepAliveClientMixin {
class _TheReportState extends ConsumerState<TheReport>
with CommonMixin, AutomaticKeepAliveClientMixin {
late RemoveListener _userReportListener;
late RestClientReport ClientReport;
late UserInfo _user;
late UserInfoReport _userReport;
late Future<ReportHomeModel?> _future;
int? theExamId;
List gradeList = [];
List testTypeList = [];
List selectList = [];
bool isGrade = false;
ComboData currentGrade = ComboData('', '');
ComboData currentTestType = ComboData('', '');
List<ExamRecords> reportList = [];
bool showGrade = false;
@override
bool get wantKeepAlive => true;
@override
void initState() {
_future = initData();
getHomeComboExam();
// getExamTypeList();
// getGradeEnumList();
// _future = initData();
Future.delayed(Duration.zero, () {
_user = ref.read(userProvider);
_userReportListener = ref.read(userReportProvider.notifier).addListener(
@ -67,6 +90,91 @@ class _TheReportState extends ConsumerState<TheReport> with CommonMixin, Automat
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 {
try {
@ -74,12 +182,14 @@ class _TheReportState extends ConsumerState<TheReport> with CommonMixin, Automat
UserInfoReport _userReport = ref.read(userReportProvider);
if (!_userReport.normal) {
// 使
bool theFlag = await ref.read(userReportProvider.notifier).initUserReport();
bool theFlag =
await ref.read(userReportProvider.notifier).initUserReport();
if (!theFlag) {
return ToastUtils.showError('请求失败请重试');
}
}
BaseStructureResultReport<ReportHomeModel> res = await clientReport.getReportHomeData(examId);
BaseStructureResultReport<ReportHomeModel> res =
await clientReport.getReportHomeData(examId);
if (res.success) {
return res.data;
} else {
@ -99,6 +209,7 @@ class _TheReportState extends ConsumerState<TheReport> with CommonMixin, Automat
return null;
}
var _scaffoldkey = new GlobalKey<ScaffoldState>(); //Scaffold设置为全局变量
@override
Widget build(BuildContext context) {
super.build(context); //super.build(null)
@ -113,45 +224,334 @@ class _TheReportState extends ConsumerState<TheReport> with CommonMixin, Automat
statusBarBrightness: Brightness.light,
),
child: Scaffold(
body: Stack(
key: _scaffoldkey,
drawer: MyDrawer(
list: selectList,
isGrade: isGrade,
onChanged: checkHandle,
refresh: getLevel),
body: Column(
children: [
//
$ScaffoldBgc(),
RefreshIndicator(
displacement: 50,
color: Theme.of(context).primaryColor,
backgroundColor: Colors.white,
child: MyFutureBuilder.buildFutureBuilderOfSingleInstance<ReportHomeModel>(context, _future,
(ReportHomeModel? datas) {
return _TheReportBody(
user: _user,
userReport: _userReport,
data: datas,
refreshReport: () {
_future = initData();
toUpState(setState, () {}, mounted);
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();
});
},
switchCall: (int? examId, int positionIndex) {
theExamId = examId;
if (examId != null) {
ref.read(userReportProvider.notifier).setPositionIndex(positionIndex);
_future = initData(examId: examId);
toUpState(setState, () {}, mounted);
}
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,
),
Expanded(
child: reportList.length>0?ListView.builder(
itemBuilder: (BuildContext context, int index) {
var item = reportList[index];
return Container(
// padding: EdgeInsets.all(6.r),
margin: EdgeInsets.only(bottom: 20.r),
width: double.infinity,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage(
'assets/images/reports_bg.png'),
fit: BoxFit.fill,
),
border: Border.all(
width: 1.r,
color: Color.fromRGBO(46, 91, 255, 0.2)),
borderRadius: BorderRadius.circular(5.r),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.center,
children: [
Container(
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(),
);
}),
onRefresh: () async {
_future = initData(examId: theExamId);
await _future;
await Future.delayed(Duration(seconds: 1), () => toUpState(setState, () => {}, mounted));
},
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
Widget build(BuildContext context) {
ExamData? examData = data?.examData;
List<ReportHistogramModel>? tagComparisonList =
examData?.tagComparisonList.map((e) => ReportHistogramModel(name: e.name, val: e.count)).toList();
List<ReportHistogramModel>? tagComparisonList = examData?.tagComparisonList
.map((e) => ReportHistogramModel(name: e.name, val: e.count))
.toList();
List<ExamSubjectDatas>? examSubjectDatas = data?.examSubjectDatas;
List<Positions> _positions = userReport.positions;
SwitchIdentityExamsController potnAndExamCotl = SwitchIdentityExamsController.use(
position: userReport.positionIndex, exam: -1, initExamId: examData?.examId, positons: userReport.positions);
Positions? theCurrentPosition = _positions.isEmpty ? null : _positions[potnAndExamCotl.positionIndex.value];
SwitchIdentityExamsController potnAndExamCotl =
SwitchIdentityExamsController.use(
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) {
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(
children: [
$ReportTitle(
titleName: '',
switchCall: () => easyThrottle('reportHomeExamSwitchCall', () async {
switchCall: () =>
easyThrottle('reportHomeExamSwitchCall', () async {
// switchCall(examId, potnAndExamCotl.positionIndex.value);
List<Positions> positions = userReport.positions;
if (positions.isEmpty) {
@ -215,8 +624,10 @@ class _TheReportBody extends HookWidget {
//0~1
pressedOpacity: 1,
//Container然后固定大小进行设置等等
child: quickText('没有数据,请重试', color: Colors.white, size: 14.sp),
onPressed: () => easyThrottle('reportHomeNoDataAgain', () => refreshReport()),
child:
quickText('没有数据,请重试', color: Colors.white, size: 14.sp),
onPressed: () => easyThrottle(
'reportHomeNoDataAgain', () => refreshReport()),
),
),
),
@ -228,20 +639,24 @@ class _TheReportBody extends HookWidget {
//
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(
children: [
SizedBox(height: 6.h),
// TITLE
$ReportTitle(
titleName: examData.examName,
switchCall: () => easyThrottle('reportHomeExamSwitchCall', () async {
switchCall: () =>
easyThrottle('reportHomeExamSwitchCall', () async {
List<Positions> positions = userReport.positions;
if (positions.isEmpty) {
return ToastUtils.showInfo('没有数据,请刷新');
}
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);
}),
@ -254,7 +669,9 @@ class _TheReportBody extends HookWidget {
children: [
//
$TopAverageContainer(
averageVal: examData.averageScore, totalVal: examData.totalScore, context: context),
averageVal: examData.averageScore,
totalVal: examData.totalScore,
context: context),
//
$DetailedReportEntry(
@ -282,7 +699,8 @@ class _TheReportBody extends HookWidget {
$GraphicDataArea(
title: '单科概况',
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(
onTap: () => easyThrottle('switchRoleExamSheetCall', () => switchCall()),
onTap: () =>
easyThrottle('switchRoleExamSheetCall', () => switchCall()),
child: Row(
mainAxisSize: MainAxisSize.min,
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),
],
),
@ -350,7 +770,10 @@ Widget $reportTitle({required String titleName, required switchCall}) {
///
@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(
alignment: const FractionalOffset(0.99, 0),
children: [
@ -366,7 +789,8 @@ Widget $topAverageContainer({required double averageVal, required double totalVa
borderRadius: BorderRadius.circular(3).r,
child: Container(
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),
decoration: ShapeDecoration(
shape: BeveledRectangleBorder(
@ -380,22 +804,29 @@ Widget $topAverageContainer({required double averageVal, required double totalVa
gradient: LinearGradient(
begin: Alignment.topCenter,
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),
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),
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,
crossAxisAlignment: CrossAxisAlignment.start,
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),
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),
@ -454,10 +889,14 @@ Widget $detailedReportEntry({
Column(
crossAxisAlignment: CrossAxisAlignment.start,
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),
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,
crossAxisAlignment: CrossAxisAlignment.start,
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),
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)}';
break;
case ReportUserIdentity.CLASS: //
rootPath = RouterManager.reportClassTeacherPath + '?examId=$examId';
rootPath =
RouterManager.reportClassTeacherPath + '?examId=$examId';
break;
case ReportUserIdentity.GRADE: //
case ReportUserIdentity.SCHOOL_LEVEL: //
@ -500,7 +944,8 @@ Widget $detailedReportEntry({
color: Theme.of(context).primaryColor,
).show(context);
}
RouterManager.router.navigateTo(context, rootPath, transition: getTransition());
RouterManager.router
.navigateTo(context, rootPath, transition: getTransition());
}),
child: Container(
width: double.infinity,
@ -512,7 +957,10 @@ Widget $detailedReportEntry({
gradient: LinearGradient(
begin: Alignment.topCenter,
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(
@ -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
Widget $graphicDataArea({required String title, required String titleImg, required Widget graphicContainer}) {
Widget $graphicDataArea(
{required String title,
required String titleImg,
required Widget graphicContainer}) {
return Container(
margin: EdgeInsets.only(bottom: 28.h),
child: Column(
@ -587,7 +1039,8 @@ Widget $theProgressChart(context, List<ExamSubjectDatas> datas) {
return $theProgressWidget(
context: context,
isMultiple: isMultiple,
linearGradient: LinearGradient(colors: [Colors.white, Theme.of(context).primaryColor]),
linearGradient: LinearGradient(
colors: [Colors.white, Theme.of(context).primaryColor]),
subjectName: e.subjectName + '平均分',
suffixTitle: e.totalScoreStr + '',
contentVal: e.averageScoreStr + '',
@ -603,7 +1056,8 @@ Widget $theProgressChart(context, List<ExamSubjectDatas> datas) {
return $theProgressWidget(
context: context,
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 + '及格率',
suffixTitle: '100%',
contentVal: e.passRateStr + '%',
@ -637,14 +1091,18 @@ Widget $theProgressWidget({
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
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),
Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
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,
animation: true,
lineHeight: 9.h,
@ -657,7 +1115,8 @@ Widget $theProgressWidget({
// ),
// linearStrokeCap: LinearStrokeCap.butt,
// 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),
),
),
@ -666,13 +1125,16 @@ Widget $theProgressWidget({
alignment: Alignment.centerRight,
// padding: EdgeInsets.only(left: 20.w),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),
],
),
);

View File

@ -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,
),
),
],
),
)),
);
}
}

View File

@ -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())
],
),
);
}
}

View File

@ -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/other_pages/index.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_personal_subject.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 reportPersonalSubjectPath = 'report/details/reportPersonalSubject';
static const String userMinePath = 'user/mine/index';
static const String reportDetailPath = '/report_detail/index';
// TheMine
static final FluroRouter router = FluroRouter();
@ -188,6 +190,13 @@ class RouterManager {
static final _userMinePageHandler = Handler(
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(
handlerFunc: (BuildContext? context, Map<String, List<String>> params) {
@ -238,6 +247,7 @@ class RouterManager {
router.define(reportPersonalSubjectPath,
handler: _reportPersonalSubjectPageHandler, transitionType: TransitionType.material);
router.define(userMinePath, handler: _userMinePageHandler, transitionType: TransitionType.material);
router.define(reportDetailPath, handler: _reportDetailPath, transitionType: TransitionType.material);
// getTransition()

View File

@ -10,8 +10,15 @@
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_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_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_params.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_params.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:retrofit/retrofit.dart' as the_retrofit;
@ -67,4 +76,64 @@ abstract class RestClientReport {
@the_retrofit.POST("/api/user/template/getmarkingpagerdetails")
Future<BaseStructureResultReport<ReportForMarkingPagerdetailModel>> getMarkingPagerDetails(
@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
);
}

View File

@ -106,6 +106,8 @@ dependencies:
image: ^4.1.3
awesome_dialog: ^3.1.0
badges: ^3.1.2
horizontal_data_table: ^4.1.1
data_table_2: ^2.5.10
dev_dependencies:
flutter_test: