Compare commits

...

2 Commits

Author SHA1 Message Date
machuanyu 3944a72ab6 Merge branch 'mcy' into main
# Conflicts:
#	marking_app/lib/routes/RouterManager.dart
2024-04-28 11:45:58 +08:00
machuanyu 83e328ceb8 报告 2024-04-22 14:25:41 +08:00
11 changed files with 1696 additions and 224 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

View File

@ -0,0 +1,50 @@
import 'package:json_annotation/json_annotation.dart';
part 'report_student_history_record.g.dart';
@JsonSerializable()
class ReportStudentHistoryRecord extends Object {
@JsonKey(name: 'ExamId')
int examId;
@JsonKey(name: 'ExamName')
String examName;
@JsonKey(name: 'ExamStartTime')
String examStartTime;
@JsonKey(name: 'StudentExamNum')
String studentExamNum;
@JsonKey(name: 'ScoreInfo')
List<ScoreInfo> scoreInfo;
ReportStudentHistoryRecord(this.examId,this.examName,this.examStartTime,this.studentExamNum,this.scoreInfo,);
factory ReportStudentHistoryRecord.fromJson(Map<String, dynamic> srcJson) => _$ReportStudentHistoryRecordFromJson(srcJson);
Map<String, dynamic> toJson() => _$ReportStudentHistoryRecordToJson(this);
}
@JsonSerializable()
class ScoreInfo extends Object {
@JsonKey(name: 'Value')
double value;
@JsonKey(name: 'Text')
String text;
ScoreInfo(this.value,this.text,);
factory ScoreInfo.fromJson(Map<String, dynamic> srcJson) => _$ScoreInfoFromJson(srcJson);
Map<String, dynamic> toJson() => _$ScoreInfoToJson(this);
}

View File

@ -0,0 +1,77 @@
import 'package:json_annotation/json_annotation.dart';
part 'report_student_info.g.dart';
@JsonSerializable()
class ReportStudentInfo extends Object {
@JsonKey(name: 'ExamId')
int examId;
@JsonKey(name: 'UserId')
int userId;
@JsonKey(name: 'ClassId')
int classId;
@JsonKey(name: 'ExamName')
String examName;
@JsonKey(name: 'ExamNo')
String examNo;
@JsonKey(name: 'UserName')
String userName;
@JsonKey(name: 'ScoreInfo')
List<ScoreInfo> scoreInfo;
@JsonKey(name: 'Subject')
List<Subject> subject;
ReportStudentInfo(this.examId,this.userId,this.classId,this.examName,this.examNo,this.userName,this.scoreInfo,this.subject,);
factory ReportStudentInfo.fromJson(Map<String, dynamic> srcJson) => _$ReportStudentInfoFromJson(srcJson);
Map<String, dynamic> toJson() => _$ReportStudentInfoToJson(this);
}
@JsonSerializable()
class ScoreInfo extends Object {
@JsonKey(name: 'Value')
double value;
@JsonKey(name: 'Text')
String text;
ScoreInfo(this.value,this.text,);
factory ScoreInfo.fromJson(Map<String, dynamic> srcJson) => _$ScoreInfoFromJson(srcJson);
Map<String, dynamic> toJson() => _$ScoreInfoToJson(this);
}
@JsonSerializable()
class Subject extends Object {
@JsonKey(name: 'Value')
int value;
@JsonKey(name: 'Text')
String text;
Subject(this.value,this.text,);
factory Subject.fromJson(Map<String, dynamic> srcJson) => _$SubjectFromJson(srcJson);
Map<String, dynamic> toJson() => _$SubjectToJson(this);
}

View File

@ -0,0 +1,499 @@
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:marking_app/common/mixin/common.dart';
import 'package:marking_app/common/model/common/base_structure_result_report.dart';
import 'package:marking_app/common/model/report/report_marking_detail.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/report/report_student_info.dart';
import 'package:marking_app/components/ReturnToHomepage.dart';
import 'package:marking_app/pages/report_detail/widgets/complete_table.dart';
import 'package:marking_app/routes/RouterManager.dart';
import 'package:marking_app/utils/easy_refresh/MyEmptyWidget.dart';
import 'package:marking_app/utils/request/rest_client_report.dart';
import 'widgets/custom_rect.dart';
class CompletedReport extends StatefulWidget {
final int examId;
final String studentNo;
const CompletedReport(
{Key? key, required this.examId, required this.studentNo})
: super(key: key);
@override
State<CompletedReport> createState() => _CompletedReportState();
}
class _CompletedReportState extends State<CompletedReport> with CommonMixin {
ReportStudentInfo? studentInfo;
int currentSubjectId = 0;
ExamOriginPapers? examOrigin;
List<ExamOriginPapers> examOriginList = [];
List<QuestionAnswers> questionAnswers = [];
final viewTransformationController = TransformationController();
bool isList = false;
@override
void initState() {
final zoomFactor = 0.5;
final xTranslate = 0.0;
final yTranslate = 0.0;
// final yTranslate = examOrigin!.width/2;
viewTransformationController.value.setEntry(0, 0, zoomFactor);
viewTransformationController.value.setEntry(1, 1, zoomFactor);
viewTransformationController.value.setEntry(2, 2, zoomFactor);
viewTransformationController.value.setEntry(0, 3, -xTranslate);
viewTransformationController.value.setEntry(1, 3, -yTranslate);
super.initState();
getInfo();
}
void getInfo() async {
EasyLoading.show(status: 'loading...');
RestClientReport clientReport = await getClientReport();
BaseStructureResultReport<ReportStudentInfo> res =
await clientReport.getStudentInfo(widget.examId, widget.studentNo);
if (res.success) {
setState(() {
studentInfo = res.data!;
currentSubjectId =
studentInfo!.subject.length > 0 ? studentInfo!.subject[0].value : 0;
getImageDetail();
});
} else {
EasyLoading.dismiss();
}
}
void getImageDetail() async {
RestClientReport clientReport = await getClientReport();
ReportMarkingDetailParams params =
ReportMarkingDetailParams(currentSubjectId, widget.studentNo);
BaseStructureResultReport<ReportMarkingDetail> res =
await clientReport.getMarkingDetail(params);
setState(() {
if (res.data != null) {
examOrigin = res.data!.examOriginPapers[0];
examOriginList = res.data!.examOriginPapers;
questionAnswers = res.data!.questionAnswers;
} else {
examOriginList = [];
examOrigin = null;
questionAnswers = [];
}
});
EasyLoading.dismiss();
}
@override
Widget build(BuildContext context) {
if (studentInfo == null) {
return Container();
}
return Scaffold(
backgroundColor: Color(0xFFEDF0FF),
appBar: AppBar(
backgroundColor: Colors.white,
title: Text(
'${studentInfo!.userName}已完成考试报告',
style: TextStyle(fontSize: 14.r, color: Color(0xFF000000)),
),
centerTitle: true,
leading: IconButton(
icon: Icon(Icons.arrow_back_ios, color: Colors.black),
onPressed: () => Navigator.of(context).pop(),
),
actions: [
ReturnToHomepage(),
InkWell(
onTap: () {
RouterManager.router.navigateTo(context,
'${RouterManager.reportHistoryPath}?classId=${studentInfo!.classId}&userId=${studentInfo!.userId}&studentName=${Uri.encodeComponent(studentInfo!.userName)}');
},
child: UnconstrainedBox(
child: Container(
padding: EdgeInsets.symmetric(horizontal: 5.r),
margin: EdgeInsets.only(right: 14.r),
height: 22.r,
decoration: BoxDecoration(
border: Border.all(width: 1.r, color: Color(0xFF6988FD)),
borderRadius: BorderRadius.circular(5.r),
),
child: Center(
child: Text(
'历次成绩',
style: TextStyle(fontSize: 10.r, color: Color(0xFF6988FD)),
),
),
),
),
),
],
),
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: EdgeInsets.only(top: 10.r, left: 14.r, right: 14.r),
child: Text(
'${studentInfo!.userName}${studentInfo!.examName}',
style: TextStyle(
fontSize: 14.sp,
color: Color(0xFF6787FD),
fontWeight: FontWeight.w500),
),
),
Container(
margin: EdgeInsets.only(top: 10.r, left: 14.r, right: 14.r),
padding: EdgeInsets.symmetric(horizontal: 10.r),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(4.r),
color: Colors.white,
boxShadow: [
BoxShadow(
color: const Color.fromRGBO(0, 0, 0, 0.1),
offset: Offset(0, 0), //y轴偏移量
blurRadius: 2, //
spreadRadius: 1, //
)
],
),
child: Column(
children: [
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(
studentInfo!.scoreInfo.length > 7
? 7
: studentInfo!.scoreInfo.length, (index) {
var item = studentInfo!.scoreInfo[index];
return Container(
width: (MediaQuery.of(context).size.width - 48.r) / 7,
child: _subjectText(item.text));
}),
),
),
Container(
width: double.infinity,
height: 30.r,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(2.r))),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: List.generate(
studentInfo!.scoreInfo.length > 7
? 7
: studentInfo!.scoreInfo.length, (index) {
var item = studentInfo!.scoreInfo[index];
return Container(
width: (MediaQuery.of(context).size.width - 48.r) / 7,
child: _subjectText(item.value.toString()));
}),
),
),
if (studentInfo!.scoreInfo.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(studentInfo!.scoreInfo.length - 7,
(index) {
var item = studentInfo!.scoreInfo[index + 7];
return Container(
width:
(MediaQuery.of(context).size.width - 48.r) / 7,
child: _subjectText(item.text));
}),
),
),
if (studentInfo!.scoreInfo.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(studentInfo!.scoreInfo.length - 7,
(index) {
var subject = studentInfo!.scoreInfo[index + 7];
return Container(
width:
(MediaQuery.of(context).size.width - 48.r) / 7,
child: _subjectText(subject.value.toString()));
}),
),
),
],
),
),
SizedBox(
height: 10.r,
),
Expanded(
child: Stack(
children: [
Container(
margin: EdgeInsets.only(top: 10.r, left: 14.r, right: 14.r),
padding: EdgeInsets.symmetric(vertical: 15.r, horizontal: 10.r),
width: double.infinity,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(4.r),
color: Colors.white,
boxShadow: [
BoxShadow(
color: const Color.fromRGBO(0, 0, 0, 0.1),
offset: Offset(0, 0), //y轴偏移量
blurRadius: 2, //
spreadRadius: 1, //
)
],
),
child: Column(
children: [
SizedBox(
height: 30.r,
width: MediaQuery.of(context).size.width,
child: ListView.builder(
itemBuilder: (BuildContext context, int index) {
Subject item = studentInfo!.subject[index];
return InkWell(
onTap: () {
setState(() {
currentSubjectId = item.value;
EasyLoading.show(status: 'loading...');
getImageDetail();
});
},
child: Container(
width: 30.r,
height: 30.r,
margin: EdgeInsets.only(
right: index == studentInfo!.subject.length
? 0
: (MediaQuery.of(context).size.width -
30.r * 9 -
104.r) /
8),
decoration: BoxDecoration(
color: currentSubjectId == item.value
? 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: currentSubjectId == item.value
? Colors.white
: Color(0xFF667095),
fontWeight: FontWeight.w400),
)),
),
);
},
itemCount: studentInfo!.subject.length,
scrollDirection: Axis.horizontal,
),
),
Expanded(
child: examOrigin != null && examOrigin!.imageUrl != ''
? !isList
? Padding(
padding: EdgeInsets.only(top: 5.r),
child: InteractiveViewer(
transformationController:
viewTransformationController,
constrained: false,
boundaryMargin: EdgeInsets.all(140.r),
minScale: 0.1,
//
maxScale: 4.0,
//
child: CustomRect(examOrigin!)),
)
: Padding(
padding: EdgeInsets.only(top: 10.r),
child: questionAnswers.length > 0
? CompleteTable(
fixedCols: 0,
fixedRows: 1,
bodyList: questionAnswers,
)
: MyEmptyWidget(),
)
: MyEmptyWidget(),
),
SizedBox(
height: 15.r,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Flexible(
flex: 1,
child: InkWell(
onTap: () {
isList = false;
setState(() {});
},
child: Container(
height: 27.r,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(4.r),
color: !isList
? Color(0xFF6988FD)
: Color(0xFFEDEFFF),
),
child: Center(
child: Text(
'查看原卷',
style: TextStyle(
fontSize: 12.sp,
color: !isList
? Colors.white
: Color(0xFF7B7B7E)),
),
),
),
),
),
SizedBox(
width: 20.r,
),
Flexible(
flex: 1,
child: InkWell(
onTap: () {
isList = true;
setState(() {});
},
child: Container(
height: 27.r,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(4.r),
color: isList
? Color(0xFF6988FD)
: Color(0xFFEDEFFF),
),
child: Center(
child: Text(
'查看列题',
style: TextStyle(
fontSize: 12.sp,
color: isList
? Colors.white
: Color(0xFF7B7B7E)),
),
),
),
),
),
],
),
],
),
),
if (!isList)
Positioned(
left: 0.r,
top: MediaQuery.of(context).size.height / 4,
child: InkWell(
onTap: () {
var num = examOrigin!.pageIndex;
if (num > 1) {
setState(() {
examOrigin = examOriginList[num - 1 - 1];
});
}
},
child: Opacity(
opacity: examOrigin != null && examOrigin!.pageIndex > 1
? 1
: 0.3,
child: Image.asset(
'assets/images/report_left_icon.png',
width: 33.r,
height: 33.r,
)),
),
),
if (!isList)
Positioned(
right: 0,
top: MediaQuery.of(context).size.height / 4,
child: InkWell(
onTap: () {
var num = examOrigin!.pageIndex;
if (num < examOriginList.length) {
setState(() {
examOrigin = examOriginList[num];
});
}
},
child: Opacity(
opacity: examOrigin != null &&
examOrigin!.pageIndex < examOriginList.length
? 1
: 0.3,
child: Image.asset(
'assets/images/report_right_icon.png',
width: 33.r,
height: 33.r,
)),
/* Image.asset(
'assets/images/report_right_icon.png',
width: 33.r,
height: 33.r,
)*/
),
)
],
)),
SizedBox(
height: 10.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

@ -23,6 +23,7 @@ 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/routes/RouterManager.dart';
import 'package:marking_app/utils/request/rest_client_report.dart';
import 'package:marking_app/utils/toast_utils.dart';
@ -105,7 +106,6 @@ class _ReportDetailState extends ConsumerState<ReportDetail> with CommonMixin {
BaseStructureResultReport<DetailBaseInfo> result =
await clientReport.getReportDetail(widget.examId,
widget.showGrade && isGrade ? -1 : currentClass.value);
// print('*************result=${result.message}');
if (result.code == 200) {
setState(() {
currentPage = 1;
@ -139,9 +139,7 @@ class _ReportDetailState extends ConsumerState<ReportDetail> with CommonMixin {
limit: pageSize);
BaseStructureResultReport<SmallQuestion> res =
await clientReport.getQuestion(params);
print(
'res.data!.total=${res.code == 200 ? res.data!.bodyExcelData.sheets[0].bodyData.length : ''}');
if (res.code != 200 || res.data == null) {
if (res.code != 200 || res.data == null) {
setState(() {
smallQuestionRes = null;
questionTotalPage = 0;
@ -212,7 +210,10 @@ class _ReportDetailState extends ConsumerState<ReportDetail> with CommonMixin {
});
EasyLoading.dismiss();
}
goCompleteReport(BuildContext context, int index,{String studentNo = 'true'}){
RouterManager.router.navigateTo(context, '${RouterManager.completedReportPath}?examId=${widget.examId}&studentNo=${studentNo == 'true'?initialList[index].examStudentId:studentNo}');
}
//
void showAlertDialog(BuildContext context, int index) {
List<String> detailHead = [];
@ -518,6 +519,7 @@ class _ReportDetailState extends ConsumerState<ReportDetail> with CommonMixin {
isHtml:true,
fixedRows: 1,
fixedCols: 1,
showCardDetail: goCompleteReport,
),
)
: NoData(),
@ -540,6 +542,7 @@ class _ReportDetailState extends ConsumerState<ReportDetail> with CommonMixin {
isHtml:true,
fixedRows: 1,
fixedCols: 1,
showCardDetail: goCompleteReport,
),
),
Row(
@ -668,6 +671,8 @@ class _ReportDetailState extends ConsumerState<ReportDetail> with CommonMixin {
isScore: true,
fixedRows: 1,
fixedCols: 3,
showCardDetail: goCompleteReport,
smallQuestion:true,
),
)
: NoData(),
@ -797,7 +802,8 @@ class _ReportDetailState extends ConsumerState<ReportDetail> with CommonMixin {
child: CardList(
headList: cardHeadList,
bodyList: cardBodyList,
showCardDetail: showAlertDialog,
// showCardDetail: showAlertDialog,
showCardDetail: goCompleteReport,
fixedRows: 1,
fixedCols: 3,
),

View File

@ -1,15 +1,81 @@
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_easyrefresh/easy_refresh.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:functional_widget_annotation/functional_widget_annotation.dart';
import 'package:marking_app/common/mixin/common.dart';
import 'package:marking_app/common/model/common/base_structure_result_report.dart';
import 'package:marking_app/common/model/report/report_student_history_record.dart';
import 'package:marking_app/components/ReturnToHomepage.dart';
import 'package:marking_app/routes/RouterManager.dart';
import 'package:marking_app/utils/common_utils.dart';
import 'package:marking_app/utils/easy_refresh/MyEmptyWidget.dart';
import 'package:marking_app/utils/index.dart';
import 'package:marking_app/utils/request/rest_client_report.dart';
import 'package:syncfusion_flutter_datepicker/datepicker.dart';
class ReportHistory extends StatefulWidget {
const ReportHistory({Key? key}) : super(key: key);
final int userId;
final int classId;
final String studentName;
const ReportHistory({Key? key, required this.classId, required this.userId,required this.studentName})
: super(key: key);
@override
State<ReportHistory> createState() => _ReportHistoryState();
}
class _ReportHistoryState extends State<ReportHistory> {
class _ReportHistoryState extends State<ReportHistory>
with CommonMixin, TickerProviderStateMixin {
bool isWork = true;
String startDataTime =
CommonUtils.getWeekStartDate().toString().substring(0, 10);
String endDataTime = CommonUtils.getWeekEndDate().toString().substring(0, 10);
String customTimeStr = '自定义';
late TabController tabController;
List<ReportStudentHistoryRecord> dataList = [];
late final EasyRefreshController refreshController;
@override
void initState() {
print('userId=${widget.userId}&classId=${widget.classId}');
super.initState();
refreshController = EasyRefreshController();
tabController = TabController(length: 3, vsync: this);
EasyLoading.show(status: 'loading...');
getList();
}
void getList() async {
if (startDataTime == DateTime.now().toString().substring(0, 10) ||
DateTime.parse(startDataTime).isAfter(DateTime.now())) {
DateTime now = DateTime.parse(startDataTime);
endDataTime = now.add(Duration(days: 1)).toString().substring(0, 10);
print(now.add(Duration(days: 1)));
} else {
endDataTime = DateTime.now().toString().substring(0, 10);
}
RestClientReport clientReport = await getClientReport();
BaseStructureResultReport<List<ReportStudentHistoryRecord>> res =
// 488491659239519, 488491659190341, '2023-03-08', '2024-04-19'
await clientReport.getStudentHistroyRecords(
widget.userId, widget.classId, startDataTime, endDataTime);
if (res.success) {
setState(() {
dataList = res.data!;
});
}
EasyLoading.dismiss();
}
@override
void dispose() {
// TODO: implement dispose
super.dispose();
tabController.dispose();
}
@override
Widget build(BuildContext context) {
@ -18,7 +84,7 @@ class _ReportHistoryState extends State<ReportHistory> {
appBar: AppBar(
backgroundColor: Colors.white,
title: Text(
'已完成报告',
'${widget.studentName}已完成考试报告',
style: TextStyle(fontSize: 14.r, color: Color(0xFF000000)),
),
centerTitle: true,
@ -26,10 +92,13 @@ class _ReportHistoryState extends State<ReportHistory> {
icon: Icon(Icons.arrow_back_ios, color: Colors.black),
onPressed: () => Navigator.of(context).pop(),
),
actions: [
ReturnToHomepage(),
],
),
body: Column(
children: [
Container(
/* Container(
width: MediaQuery.of(context).size.width * 0.8,
height: 40.r,
margin: EdgeInsets.only(
@ -89,9 +158,400 @@ class _ReportHistoryState extends State<ReportHistory> {
)),
],
),
)
),*/
SizedBox(
height: 10.r,
),
jobConditionFilter(context,
controller: tabController,
customTimeStr: customTimeStr,
customTime: tabController.index != 3 ||
((endDataTime == null || endDataTime == '') &&
(startDataTime == null || startDataTime == ''))
? null
: PickerDateRange(
startDataTime == null || startDataTime == ''
? null
: DateTime.parse(startDataTime!),
endDataTime == null || endDataTime == ''
? null
: DateTime.parse(endDataTime!),
), onTimeFilter: (String? startTime, String? endTime) {
if (startTime == null && endTime == null) {
if (tabController.index == 3) {
tabController.animateTo(0);
}
startDataTime = '';
endDataTime = '';
customTimeStr = '自定义';
} else {
EasyLoading.show(status: 'loading...');
startDataTime = startTime != null ? startTime : '';
endDataTime = endTime != null ? endTime : '';
setState(() {});
getList();
}
// _refreshController2.callRefresh();
}, refreshTime: (value) {
if (value != null && value.startDate != null) {
customTimeStr =
value.startDate?.toString().substring(0, 10) ?? '';
setState(() {});
if (value.endDate != null) {
if (value.startDate!.year == value.endDate!.year) {
customTimeStr = value.startDate.toString().substring(5, 10) +
'~${value.endDate.toString().substring(5, 10)}';
setState(() {});
} else {
customTimeStr =
'$customTimeStr~${value.endDate?.toString().substring(0, 10)}';
setState(() {});
}
}
}
}),
Expanded(
child: Padding(
padding: EdgeInsets.symmetric(vertical: 14.r, horizontal: 14.r),
child: EasyRefresh(
firstRefresh: false,
taskIndependence: true,
controller: refreshController,
header: MaterialHeader(),
footer: TaurusFooter(),
onRefresh: () async {
getList();
},
child: dataList.length > 0
? ListView.builder(
itemCount: dataList.length,
itemBuilder: (context, index) {
ReportStudentHistoryRecord item = dataList[index];
return InkWell(
onTap: (){
RouterManager.router.navigateTo(context, '${RouterManager.completedReportPath}?examId=${item.examId}&studentNo=${item.studentExamNum}');
},
child: Container(
// padding: EdgeInsets.all(6.r),
margin: EdgeInsets.only(bottom: 10.r),
width: double.infinity,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage(
'assets/images/report_student_history_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: [
Padding(
padding: EdgeInsets.symmetric(
vertical: 10.r,
horizontal: 10.r,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.center,
children: [
Text(
item.examName,
style: TextStyle(
fontSize: 12.sp,
color: Color(0xFF000000)),
),
Spacer(),
Text(
item.examStartTime,
style: TextStyle(
fontSize: 12.sp,
color: Color(0xFF4A4A4A)),
)
],
),
),
SizedBox(
height: 2.r,
),
Container(
padding:
EdgeInsets.symmetric(horizontal: 10.r),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5.r),
),
child: item.scoreInfo.length > 0
? Scrollbar(
// thumbVisibility:true,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: List.generate(
item.scoreInfo.length, (i) {
ScoreInfo score =
item.scoreInfo[i];
return Row(
children: [
Column(
children: [
Container(
height: 22.r,
width: item.scoreInfo
.length >
4
? 90.r
: (MediaQuery.of(
context)
.size
.width -
48.r -
(item.scoreInfo
.length - 1) *
1.5
.r) /
item.scoreInfo
.length,
decoration:
BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: i == 0
? Radius
.circular(
4.r)
: Radius
.zero,
topRight: i ==
item.scoreInfo.length -
1
? Radius
.circular(
4.r)
: Radius
.zero),
color: Color(
0xFFECECEC),
),
child: Center(
child: Text(
score.text,
style: TextStyle(
fontSize:
12.sp,
color: Color(
0xFF8A8A8A)),
),
),
),
Container(
height: 30.r,
width: item.scoreInfo
.length >
4
? 90.r
: (MediaQuery.of(
context)
.size
.width -
48.r -
(item.scoreInfo
.length - 1) *
1.5.r) /
item.scoreInfo
.length,
decoration:
BoxDecoration(
borderRadius: BorderRadius.only(
bottomLeft: i ==
0
? Radius
.circular(
4.r)
: Radius
.zero,
bottomRight: i ==
item.scoreInfo.length -
1
? Radius
.circular(
4.r)
: Radius
.zero),
color: Colors.white,
),
child: Center(
child: Text(
score.value
.toString(),
style: TextStyle(
fontSize:
12.sp,
color: Color(
0xFF4A4A4A)),
),
),
),
],
),
SizedBox(
width: i <
item.scoreInfo
.length - 1
? 1.5.r
: 0.r,
),
],
);
}),
),
),
)
: Center(
child: Text(
'-暂无数据-',
style: TextStyle(
fontSize: 12.sp,
color: Color(0xFF8A8A8A)),
)),
),
SizedBox(
height: 20.r,
),
],
),
),
);
})
: MyEmptyWidget(),
),
),
),
],
),
);
}
}
@hwidget
Widget jobConditionFilter(BuildContext context,
{required TabController controller,
PickerDateRange? customTime,
required Function refreshTime,
required String customTimeStr,
required Function(String? startTime, String? endTime) onTimeFilter}) {
var customTimeState = PickerDateRange(null, null);
if (customTime != null) {
customTimeState = PickerDateRange(
customTime!.startDate != null ? customTime!.startDate : null,
customTime!.endDate != null ? customTime!.endDate : null);
}
DateTime getMonthStartDate() {
DateTime now = DateTime.now();
return DateTime(now.year, now.month, 1); //
}
DateTime getMonthEndDate() {
DateTime now = DateTime.now();
int nextMonth = now.month + 1;
if (nextMonth > 12) {
nextMonth = 1;
now = now.add(Duration(days: 31 - now.day)); //
} else {
now = now.add(Duration(
days: DateTime(now.year, nextMonth, 0).day -
now.day)); //
}
return now;
}
return Container(
decoration: BoxDecoration(
// color: Color.fromRGBO(244, 244, 244, 1),
// border: Border(bottom: BorderSide(color: Color.fromRGBO(204, 204, 204, 1), width: 1)),
),
child: Container(
alignment: Alignment.centerLeft,
decoration: BoxDecoration(
border:
Border(bottom: BorderSide(width: 1.r, color: Color(0xFFCCCCCC)))),
child: TabBar(
controller: controller,
unselectedLabelStyle: TextStyle(
fontSize: 12.sp, color: const Color.fromRGBO(102, 102, 102, 1)),
labelStyle: TextStyle(
fontSize: 12.sp,
fontWeight: FontWeight.bold,
color: Color.fromRGBO(116, 145, 253, 1),
),
isScrollable: true,
labelColor: Color(0xFF7491FD),
unselectedLabelColor: Color(0xFF505E6E),
padding: EdgeInsets.symmetric(horizontal: 14.r),
// indicatorSize: TabBarIndicatorSize.label, //
onTap: (int val) async {
switch (val) {
case 0: //
onTimeFilter(
CommonUtils.getWeekStartDate().toString().substring(0, 10),
CommonUtils.getWeekEndDate().toString().substring(0, 10),
);
break;
case 1: //
onTimeFilter(
getMonthStartDate().toString().substring(0, 10),
getMonthEndDate().toString().substring(0, 10),
);
break;
default: //
var dialogData = await showDialog<PickerDateRange?>(
context: context,
builder: (BuildContext context1) {
return Center(
child: Container(
color: Colors.white,
width: isPad()
? ScreenUtil().screenWidth / 2
: ScreenUtil().screenWidth / 1.3,
height: ScreenUtil().screenHeight / 2,
child: SfDateRangePicker(
showActionButtons: true,
confirmText: '确定',
cancelText: '取消',
onSubmit: (p0) {
print(p0);
Navigator.of(context1).pop(p0);
refreshTime(p0);
},
onCancel: () {
Navigator.of(context1).pop();
},
selectionMode: DateRangePickerSelectionMode.range,
initialSelectedRange: customTimeState,
),
),
);
});
// startDate: 2024-03-04 18:47:00.117958, endDate: 2024-03-11 18:47:00.117986
// if (dialogData != null && (dialogData.startDate != null || dialogData.endDate != null)) {}
onTimeFilter(
dialogData?.startDate?.toString().substring(0, 10),
dialogData?.endDate?.toString().substring(0, 10),
);
// customTimeState = dialogData!;
customTimeState = dialogData ?? PickerDateRange(null, null);
}
},
tabs: <Widget>[
const Tab(text: '近一周'),
const Tab(text: '近一月'),
Tab(text: customTimeStr),
],
),
),
);
}

View File

@ -2,6 +2,7 @@ import 'package:data_table_2/data_table_2.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_widget_from_html_core/flutter_widget_from_html_core.dart';
import 'package:marking_app/routes/RouterManager.dart';
class CardList extends StatefulWidget {
final List headList;
@ -11,6 +12,7 @@ class CardList extends StatefulWidget {
final int? fixedRows;
final int? fixedCols;
final bool? isHtml;
final bool? smallQuestion;
const CardList({
Key? key,
@ -19,6 +21,7 @@ class CardList extends StatefulWidget {
this.showCardDetail,
this.isScore = false,
this.isHtml = false,
this.smallQuestion = false,
this.fixedCols,
this.fixedRows,
}) : super(key: key);
@ -32,6 +35,7 @@ class _CardListState extends State<CardList> {
int? _sortColumnIndex;
bool _sortAscending = true;
DataRow _getRow(int index, [Color? color]) {
assert(index >= 0);
var body = widget.bodyList[index];
@ -40,16 +44,19 @@ class _CardListState extends State<CardList> {
color: color != null ? MaterialStateProperty.all(color) : null,
cells: List.generate(widget.headList.length, (itemIndex) {
var item = body[itemIndex];
// print(item);
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
DataCell((itemIndex == 2 && widget.isScore == false)||(itemIndex == 1 && widget.smallQuestion == true)
? InkWell(
onTap: () {
if (widget.showCardDetail != null) {
if (widget.showCardDetail != null && itemIndex == 1 && item.toString().contains('{') && item['ExamNo'] != '') {
widget.showCardDetail!(context, index,studentNo:item['ExamNo']);
}else if (widget.showCardDetail != null && itemIndex == 2) {
widget.showCardDetail!(context, index);
}
},
@ -58,7 +65,7 @@ class _CardListState extends State<CardList> {
children: [
Expanded(
child: Center(
child: Text(item.toString(),
child: Text(item.toString().contains('{')?item['Name']:item.toString(),
style: TextStyle(
fontSize: 12.sp, color: Color(0xFF262626))),
),
@ -74,16 +81,24 @@ class _CardListState extends State<CardList> {
],
),
)
: Center(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 5.r),
child:
widget.isHtml == true?HtmlWidget(item.toString(),textStyle: TextStyle(fontSize: 12.sp,color: Color(0xFF262626)),):
Text(item.toString(),
style:
TextStyle(fontSize: 12.sp, color: Color(0xFF262626))),
: InkWell(
onTap: (){
if (widget.showCardDetail != null && item.toString().contains('{') && item['ExamNo'] != '') {
// print(item);
widget.showCardDetail!(context, index,studentNo:item['ExamNo']);
}
},
child: Center(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 5.r),
child:
widget.isHtml == true?HtmlWidget(item.toString().contains('{')?item['Name']: item.toString(),textStyle: TextStyle(fontSize: 12.sp,color: item.toString().contains('{') && item['ExamNo'] != ''?Color(0xFF6988FD):Color(0xFF262626)),):
Text(item.toString().contains('{')?item['Name']:item.toString(),
style:
TextStyle(fontSize: 12.sp, color: Color(0xFF262626))),
),
),
));
));
}),
);
}

View File

@ -0,0 +1,161 @@
import 'package:data_table_2/data_table_2.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_widget_from_html_core/flutter_widget_from_html_core.dart';
import 'package:marking_app/common/model/report/report_marking_detail.dart';
import 'package:photo_view/photo_view.dart';
class CompleteTable extends StatefulWidget {
final List bodyList;
final int? fixedRows;
final int? fixedCols;
const CompleteTable({
Key? key,
required this.bodyList,
this.fixedCols,
this.fixedRows,
}) : super(key: key);
@override
State<CompleteTable> createState() => _CompleteTableState();
}
class _CompleteTableState extends State<CompleteTable> {
final ScrollController _controller = ScrollController();
int? _sortColumnIndex;
bool _sortAscending = true;
final List<String> headList = ['题号','小题分','得分','用户答案','正确答案'];
showImg(String imgUrl) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
// insetPadding: EdgeInsets.symmetric(vertical: 10.r,horizontal: 45.r),
backgroundColor: Colors.transparent,
contentPadding: EdgeInsets.all(0),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(15.r))),
content: Container(
width: MediaQuery.of(context).size.width - 48.r,
height: MediaQuery.of(context).size.height * 0.6,
color: Colors.white,
child: PhotoView(imageProvider: NetworkImage(imgUrl),backgroundDecoration: BoxDecoration(color: Colors.transparent),)),
);
},
);
}
DataRow _getRow(int index, [Color? color]) {
assert(index >= 0);
QuestionAnswers body = widget.bodyList[index];
return DataRow2.byIndex(
index: index,
color: color != null ? MaterialStateProperty.all(color) : null,
cells: [
DataCell(
Center(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 5.r),
child: Text(body.questionNum,
style:
TextStyle(fontSize: 12.sp, color: Color(0xFF262626))),
),
)),
DataCell(
Center(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 5.r),
child: Text(body.totalScore.toString(),
style:
TextStyle(fontSize: 12.sp, color: Color(0xFF262626))),
),
)),
DataCell(
Center(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 5.r),
child: Text(body.score.toString(),
style:
TextStyle(fontSize: 12.sp, color: Color(0xFF262626))),
),
)),
DataCell(
Center(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 5.r),
child:
body.yourAnswer.contains('http')?
InkWell(
onTap: (){
showImg(body.yourAnswer);
},
child: Text('查看原题',style: TextStyle(fontSize: 12.sp,color: Color(0xFF6988FD)),),
):
Text(body.yourAnswer,
style:
TextStyle(fontSize: 12.sp, color: Color(0xFF262626)))
,
),
)),
DataCell(
Center(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 5.r),
child: Text(body.answer,
style:
TextStyle(fontSize: 12.sp, color: Color(0xFF262626))),
),
)),
],
);
}
@override
Widget build(BuildContext context) {
return DataTable2(
dividerThickness: 0,
scrollController: _controller,
columnSpacing: 0,
horizontalMargin: 0,
dataRowHeight:40.r,
headingRowHeight: 30.r,
bottomMargin: 0,
border: TableBorder(
left: BorderSide(
width: 1, color: Color(0xFFEAEAEA), style: BorderStyle.solid),
right: BorderSide(
width: 1, color: Color(0xFFEAEAEA), style: BorderStyle.solid),
horizontalInside: BorderSide(
width: 1, color: Color(0xFFEAEAEA), style: BorderStyle.solid),
bottom: BorderSide(
width: 1, color: Color(0xFFEAEAEA), style: BorderStyle.solid),
verticalInside: BorderSide(
width: 1, color: Color(0xFFEAEAEA), style: BorderStyle.solid)),
headingRowColor: MaterialStateProperty.resolveWith((states) =>
widget.fixedCols! > 0 ? Color(0xFFF0F3FF) : Colors.transparent),
headingRowDecoration: BoxDecoration(color: Color(0xFFF0F3FF)),
fixedColumnsColor: Color(0xFFF0F3FF),
fixedCornerColor: Colors.grey[400],
minWidth:MediaQuery.of(context).size.width,
fixedTopRows: widget.fixedRows!,
fixedLeftColumns: widget.fixedCols!,
sortColumnIndex: _sortColumnIndex,
sortAscending: _sortAscending,
// onSelectAll: (val) => setState(() => selectAll(val)),
columns: List.generate(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:(MediaQuery.of(context).size.width - 48.r)/headList.length,
);
}),
rows: List<DataRow>.generate(widget.bodyList.length,
(index) => _getRow(index, Colors.transparent)));
}
}

View File

@ -10,6 +10,7 @@ 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/routes/RouterManager.dart';
import 'package:marking_app/utils/easy_refresh/MyEmptyWidget.dart';
import 'package:marking_app/utils/request/rest_client_report.dart';
@ -32,6 +33,7 @@ class _ReportCardDialogState extends ConsumerState<ReportCardDialog>
int currentSubjectId = 0;
final viewTransformationController = TransformationController();
bool isList = false;
void initState() {
final zoomFactor = 0.5;
@ -68,7 +70,6 @@ class _ReportCardDialogState extends ConsumerState<ReportCardDialog>
if(res.data!=null){
examOrigin = res.data!.examOriginPapers[0];
examOriginList = res.data!.examOriginPapers;
// print('examOrigin!.width=${examOrigin!.width}');
}else{
examOriginList = [];
examOrigin = null;
@ -83,28 +84,66 @@ class _ReportCardDialogState extends ConsumerState<ReportCardDialog>
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),
color: Color(0xFFEDEFFF),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
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,))
],
),
Text(
'张沫凡重庆八中2023.2024 高二定时训练',
style: TextStyle(
fontSize: 14.sp,
color: Color(0xFF6787FD),
fontWeight: FontWeight.w500),
),
InkWell(
onTap: (){
RouterManager.router.navigateTo(context, RouterManager.reportHistoryPath);
},
child: Container(
padding: EdgeInsets.symmetric(vertical: 3.r,horizontal: 5.r),
decoration: BoxDecoration(
border: Border.all(width: 1.r,color: Color(0xFF6988FD)),
borderRadius: BorderRadius.circular(5.r),
),
child: Center(
child: Text('历次成绩',style: TextStyle(fontSize: 10.r,color: Color(0xFF6988FD)),),
),
),
),
Container(
margin: EdgeInsets.only(top: 10.r, left: 14.r, right: 14.r),
padding: EdgeInsets.symmetric(horizontal: 10.r),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(4.r),
color: Colors.white,
boxShadow: [
BoxShadow(
color: const Color.fromRGBO(0, 0, 0, 0.1),
offset: Offset(0, 0), //y轴偏移量
blurRadius: 2, //
spreadRadius: 1, //
)
],
),
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,
@ -119,7 +158,7 @@ class _ReportCardDialogState extends ConsumerState<ReportCardDialog>
(index) {
var item = widget.headList[index];
return Container(
width: (MediaQuery.of(context).size.width - 90.r) / 7,
width: (MediaQuery.of(context).size.width - 104.r) / 7,
child: _subjectText(item));
}),
),
@ -133,20 +172,20 @@ class _ReportCardDialogState extends ConsumerState<ReportCardDialog>
mainAxisAlignment: MainAxisAlignment.start,
children: [
Container(
width: (MediaQuery.of(context).size.width - 90.r) / 7,
width: (MediaQuery.of(context).size.width - 104.r) / 7,
child: _subjectText(
widget.cardItem.totalScore.toString())),
Container(
width: (MediaQuery.of(context).size.width - 90.r) / 7,
width: (MediaQuery.of(context).size.width - 104.r) / 7,
child: _subjectText(
widget.cardItem.totalClassRanking.toString())),
Container(
width: (MediaQuery.of(context).size.width - 90.r) / 7,
width: (MediaQuery.of(context).size.width - 104.r) / 7,
child: _subjectText(
widget.cardItem.totalRanking.toString())),
SizedBox(
width:
(MediaQuery.of(context).size.width - 90.r) / 7 * 4,
(MediaQuery.of(context).size.width - 104.r) / 7 * 4,
child: Row(
children: List.generate(
widget.cardItem.subjectDetails.length > 4
@ -156,7 +195,7 @@ class _ReportCardDialogState extends ConsumerState<ReportCardDialog>
var subject = widget.cardItem.subjectDetails[index];
return Container(
width:
(MediaQuery.of(context).size.width - 90.r) /
(MediaQuery.of(context).size.width - 104.r) /
7,
child: _subjectText(subject.score));
}),
@ -177,7 +216,7 @@ class _ReportCardDialogState extends ConsumerState<ReportCardDialog>
List.generate(widget.headList.length - 7, (index) {
var item = widget.headList[index + 7];
return Container(
width: (MediaQuery.of(context).size.width - 90.r) / 7,
width: (MediaQuery.of(context).size.width - 104.r) / 7,
child: _subjectText(item));
}),
),
@ -194,7 +233,7 @@ class _ReportCardDialogState extends ConsumerState<ReportCardDialog>
widget.cardItem.subjectDetails.length - 4, (index) {
var subject = widget.cardItem.subjectDetails[index + 4];
return Container(
width: (MediaQuery.of(context).size.width - 90.r) / 7,
width: (MediaQuery.of(context).size.width - 104.r) / 7,
child: _subjectText(subject.score));
}),
),
@ -202,161 +241,276 @@ class _ReportCardDialogState extends ConsumerState<ReportCardDialog>
],
),
),
SizedBox(height: 10.r,),
Expanded(
child: Container(
margin: EdgeInsets.only(top: 0.r),
padding: EdgeInsets.symmetric(vertical: 5.r, horizontal: 20.r),
child: Stack(
children: [
Container(
margin: EdgeInsets.only(top: 10.r, left: 14.r, right: 14.r),
padding: EdgeInsets.symmetric(vertical:15.r,horizontal: 10.r),
/* 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))),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(4.r),
color: Colors.white,
boxShadow: [
BoxShadow(
color: const Color.fromRGBO(0, 0, 0, 0.1),
offset: Offset(0, 0), //y轴偏移量
blurRadius: 2, //
spreadRadius: 1, //
)
],
),
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(
transformationController: viewTransformationController,
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: [
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: examOrigin != null && examOrigin!.pageIndex > 1?Color(0xFF6787FD): Color(0xFFB3B9B9),
width: 1.r),
borderRadius: BorderRadius.all(
Radius.circular(2.r)),
),
child: Text(
'上一页',
style: TextStyle(
color: examOrigin != null && examOrigin!.pageIndex > 1?Color(0xFF6787FD): Color(0xFFB3B9B9),
),
),
),
/* Image.asset(
'assets/images/report_left_icon.png',
width: 33.r,
height: 33.r,
)*/
),
SizedBox(
width: 15.r,
),
InkWell(
onTap: () {
var num = examOrigin!.pageIndex;
if (num < examOriginList.length) {
setState(() {
examOrigin = examOriginList[num];
});
}
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 -
104.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),
)),
),
);
},
child: Container(
padding: EdgeInsets.symmetric(
vertical: 2.r, horizontal: 5.r),
decoration: BoxDecoration(
border: Border.all(
color: examOrigin != null && examOrigin!.pageIndex < examOriginList.length?Color(0xFF6787FD): Color(0xFFB3B9B9),
width: 1.r),
borderRadius: BorderRadius.all(
Radius.circular(2.r)),
),
child: Text(
'下一页',
style: TextStyle(
color: examOrigin != null && examOrigin!.pageIndex < examOriginList.length?Color(0xFF6787FD): Color(0xFFB3B9B9),
itemCount: subjectList.length,
scrollDirection: Axis.horizontal,
),
),
Expanded(
child: examOrigin != null && examOrigin!.imageUrl != ''
? !isList?Padding(
padding: EdgeInsets.only(top:5.r),
child: InteractiveViewer(
transformationController: viewTransformationController,
constrained: false,
boundaryMargin: EdgeInsets.all(140.r),
minScale: 0.1, //
maxScale: 4.0, //
child: CustomRect(examOrigin!)),
):Text('list')
: MyEmptyWidget(),
),
SizedBox(height: 6.r,),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Flexible(
flex: 1,
child: InkWell(
onTap:(){
isList = false;
setState(() {
});
},
child: Container(
height: 27.r,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(4.r),
color: !isList?Color(0xFF6988FD):Color(0xFFEDEFFF),
),
child: Center(
child: Text('查看原卷',style: TextStyle(fontSize: 12.sp,color: !isList?Colors.white:Color(0xFF7B7B7E)),),
),
),
),
),
/* Image.asset(
'assets/images/report_right_icon.png',
width: 33.r,
height: 33.r,
)*/
SizedBox(width: 20.r,),
Flexible(
flex: 1,
child: InkWell(
onTap: (){
isList = true;
setState(() {
});
},
child: Container(
height: 27.r,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(4.r),
color: isList?Color(0xFF6988FD):Color(0xFFEDEFFF),
),
child: Center(
child: Text('查看列题',style: TextStyle(fontSize: 12.sp,color: isList?Colors.white:Color(0xFF7B7B7E)),),
),
),
),
),
],
),
/*if(!isList)
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
InkWell(
onTap: () {
var num = examOrigin!.pageIndex;
if (num > 1) {
setState(() {
examOrigin = examOriginList[num - 1 - 1];
});
}
},
child:Column(
children: [
Opacity(
opacity: examOrigin != null && examOrigin!.pageIndex > 1?1:0.3,
child: Image.asset('assets/images/report_left_icon.png',width: 33.r,height: 33.r,)),
Container(
padding: EdgeInsets.symmetric( horizontal: 5.r),
decoration: BoxDecoration(
*//* border: Border.all(
color: examOrigin != null && examOrigin!.pageIndex > 1?Color(0xFF6787FD): Color(0xFFB3B9B9),
width: 1.r),*//*
borderRadius: BorderRadius.all(
Radius.circular(2.r)),
),
child: Text(
'上一页',
style: TextStyle(
color: examOrigin != null && examOrigin!.pageIndex > 1?Color(0xFF6787FD): Color(0xFFB3B9B9),
),
),
),
],
),
*//* Image.asset(
'assets/images/report_left_icon.png',
width: 33.r,
height: 33.r,
)*//*
),
SizedBox(
width: 15.r,
),
InkWell(
onTap: () {
var num = examOrigin!.pageIndex;
if (num < examOriginList.length) {
setState(() {
examOrigin = examOriginList[num];
});
}
},
child: Column(
children: [
Opacity(
opacity:examOrigin != null && examOrigin!.pageIndex < examOriginList.length?1:0.3,
child: Image.asset('assets/images/report_right_icon.png',width: 33.r,height: 33.r,)),
Container(
padding: EdgeInsets.symmetric(horizontal: 5.r),
decoration: BoxDecoration(
*//* border: Border.all(
color: examOrigin != null && examOrigin!.pageIndex < examOriginList.length?Color(0xFF6787FD): Color(0xFFB3B9B9),
width: 1.r),*//*
borderRadius: BorderRadius.all(
Radius.circular(2.r)),
),
child: Text(
'下一页',
style: TextStyle(
color: examOrigin != null && examOrigin!.pageIndex < examOriginList.length?Color(0xFF6787FD): Color(0xFFB3B9B9),
),
),
),
],
),
*//* Image.asset(
'assets/images/report_right_icon.png',
width: 33.r,
height: 33.r,
)*//*
),
],
),*/
],
),
],
),
))
),
if(!isList)
Positioned(
left:0.r,
top: MediaQuery.of(context).size.height/4,
child: InkWell(
onTap: () {
var num = examOrigin!.pageIndex;
if (num > 1) {
setState(() {
examOrigin = examOriginList[num - 1 - 1];
});
}
},
child:Opacity(
opacity: examOrigin != null && examOrigin!.pageIndex > 1?1:0.3,
child: Image.asset('assets/images/report_left_icon.png',width: 33.r,height: 33.r,)),
),),
if(!isList)
Positioned(
right: 0,
top: MediaQuery.of(context).size.height/4,
child: InkWell(
onTap: () {
var num = examOrigin!.pageIndex;
if (num < examOriginList.length) {
setState(() {
examOrigin = examOriginList[num];
});
}
},
child: Opacity(
opacity:examOrigin != null && examOrigin!.pageIndex < examOriginList.length?1:0.3,
child: Image.asset('assets/images/report_right_icon.png',width: 33.r,height: 33.r,)),
/* Image.asset(
'assets/images/report_right_icon.png',
width: 33.r,
height: 33.r,
)*/
),)
],
))
]),
);
}

View File

@ -36,7 +36,6 @@ import 'package:marking_app/pages/mine/index.dart';
import 'package:marking_app/pages/mine/log_off.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/register/index.dart';
import 'package:marking_app/pages/report_detail/index.dart';
import 'package:marking_app/pages/report_detail/report_history.dart';
import 'package:marking_app/pages/reports/report_class_teacher.dart';
@ -44,7 +43,8 @@ import 'package:marking_app/pages/reports/report_personal_subject.dart';
import 'package:marking_app/pages/reports/report_subject_teacher.dart';
import 'package:marking_app/utils/const_text.dart';
import 'package:marking_app/utils/the_global.dart';
import 'package:marking_app/pages/register/index.dart';
import 'package:marking_app/pages/report_detail/completed_report.dart';
import '../utils/index.dart';
class RouterManager {
@ -89,6 +89,7 @@ class RouterManager {
static const String jobKnowledgePointsDetailPath = '/homework_correction/job_knowledge_points_detail';
static const String answerTrajectoryPath = '/homework_correction/answer_trajectory';
static const String answerTrajectoryJobDetailPath = '/homework_correction/answer_trajectory_job_detail';
static const String completedReportPath = '/report_detail/completed_report';
// TheMine
static final FluroRouter router = FluroRouter();
@ -111,14 +112,18 @@ class RouterManager {
}
//
static final _startUpPageHandler = Handler(handlerFunc: (BuildContext? context, Map<String, List<String>> params) => const StartUpPage());
static final _startUpPageHandler =
Handler(handlerFunc: (BuildContext? context, Map<String, List<String>> params) => const StartUpPage());
//
static final _mainPageHandler = Handler(handlerFunc: (BuildContext? context, Map<String, List<String>> params) => const TheMainPage());
static final _mainPageHandler =
Handler(handlerFunc: (BuildContext? context, Map<String, List<String>> params) => const TheMainPage());
//
static final _loginPageHandler = Handler(handlerFunc: (BuildContext? context, Map<String, List<String>> params) => const TheLogin());
static final _loginPageHandler =
Handler(handlerFunc: (BuildContext? context, Map<String, List<String>> params) => const TheLogin());
//
static final _progressPageHandler = Handler(
handlerFunc: (BuildContext? context, Map<String, List<String>> params) => Progress(int.parse(params['examSubjectId']![0]), params['name']![0]));
handlerFunc: (BuildContext? context, Map<String, List<String>> params) =>
Progress(int.parse(params['examSubjectId']![0]), params['name']![0]));
//
static final _reviewPageHandler = Handler(handlerFunc: (BuildContext? context, Map<String, List<String>> params) {
int markingUserId = int.parse(params['markingUserId']![0]);
@ -137,8 +142,11 @@ class RouterManager {
//
static final _reviewAbnormalPageHandler = Handler(
handlerFunc: (BuildContext? context, Map<String, List<String>> params) =>
ProgressAbnormal(int.parse(params['examSubjectId']![0]), params['markingId']![0], params['name']![0], params['questionNum']![0]));
handlerFunc: (BuildContext? context, Map<String, List<String>> params) => ProgressAbnormal(
int.parse(params['examSubjectId']![0]),
params['markingId']![0],
params['name']![0],
params['questionNum']![0]));
//
static final _markingDoPageHandler = Handler(handlerFunc: (BuildContext? context, Map<String, List<String>> params) {
try {
@ -180,7 +188,8 @@ class RouterManager {
}
});
//
static final _markingHomeworkDoPageHandler = Handler(handlerFunc: (BuildContext? context, Map<String, List<String>> params) {
static final _markingHomeworkDoPageHandler =
Handler(handlerFunc: (BuildContext? context, Map<String, List<String>> params) {
try {
int taskId = int.parse(params['taskId']![0]);
int jobId = int.parse(params['jobId']![0]);
@ -224,7 +233,8 @@ class RouterManager {
handlerFunc: (BuildContext? context, Map<String, List<String>> params) => const OhterPage(),
);
static final _reportClassTeacherPageHandler = Handler(handlerFunc: (BuildContext? context, Map<String, List<String>> params) {
static final _reportClassTeacherPageHandler =
Handler(handlerFunc: (BuildContext? context, Map<String, List<String>> params) {
int examId = int.parse(params['examId']![0]);
return ReportClassTeacher(examId: examId);
@ -294,7 +304,7 @@ class RouterManager {
if (params['gradeId'] != null && params['gradeId']?[0] != null && params['gradeId']![0] != 'null') {
gradeId = int.parse(params['gradeId']![0]);
}
return QuickDataCheckPage(jobId: jobId, className: className, gradeName: gradeName, schoolId: schoolId, gradeId: gradeId);
return QuickDataCheckPage(jobId: jobId, className: className,gradeName:gradeName,schoolId:schoolId,gradeId:gradeId);
},
);
@ -313,7 +323,7 @@ class RouterManager {
String groupId = params['groupId']![0];
String title = params['title']![0];
String? page = params['page']?[0];
return JobPriorityReviewSet(groupId: groupId, title: title, page: page);
return JobPriorityReviewSet(groupId: groupId,title:title,page:page);
},
);
@ -321,7 +331,7 @@ class RouterManager {
static final _jobStudentGroupPageHandler = Handler(
handlerFunc: (BuildContext? context, Map<String, List<String>> params) {
String page = params['page']![0];
return JobStudentGroup(page: page);
return JobStudentGroup(page:page);
},
);
//
@ -338,7 +348,7 @@ class RouterManager {
if (params['gradeId'] != null && params['gradeId']?[0] != null && params['gradeId']![0] != 'null') {
gradeId = int.parse(params['gradeId']![0]);
}
return JobFavorite(jobId: jobId, gradeId: gradeId, schoolId: schoolId, className: className, jobName: jobName);
return JobFavorite(jobId: jobId, gradeId: gradeId, schoolId: schoolId, className: className,jobName:jobName);
},
);
@ -347,7 +357,7 @@ class RouterManager {
handlerFunc: (BuildContext? context, Map<String, List<String>> params) {
String studentName = params['studentName']![0];
int studentId = int.parse(params['studentId']![0]);
return JobPersonalDetail(studentId: studentId, studentName: studentName);
return JobPersonalDetail(studentId: studentId,studentName:studentName);
},
);
@ -359,7 +369,7 @@ class RouterManager {
//
static final _reportCardDialogPathHandler = Handler(
handlerFunc: (BuildContext? context, Map<String, List<String>> params) {
/* String studentName = params['studentName']![0];
/* String studentName = params['studentName']![0];
int studentId = int.parse(params['studentId']![0]);
return ReportCardDialog(studentId: studentId,studentName:studentName);*/
},
@ -367,9 +377,10 @@ class RouterManager {
//
static final _reportHistoryPathHandler = Handler(
handlerFunc: (BuildContext? context, Map<String, List<String>> params) {
/* String studentName = params['studentName']![0];
int studentId = int.parse(params['studentId']![0]);*/
return ReportHistory();
int classId = int.parse(params['classId']![0]);
int userId = int.parse(params['userId']![0]);
String studentName = params['studentName']![0];
return ReportHistory(classId:classId,userId:userId,studentName:studentName);
},
);
@ -391,9 +402,9 @@ class RouterManager {
//
static final _jobKnowledgePointsDetailPathHandler = Handler(
handlerFunc: (BuildContext? context, Map<String, List<String>> params) {
String knowledgeName = params['knowledgeName']![0];
String knowledgeName = params['knowledgeName']![0];
int knowledgeId = int.parse(params['knowledgeId']![0]);
return JobKnowledgePointsDetail(knowledgeName: knowledgeName, knowledgeId: knowledgeId);
return JobKnowledgePointsDetail(knowledgeName:knowledgeName,knowledgeId:knowledgeId);
},
);
@ -410,9 +421,19 @@ class RouterManager {
int jobId = int.parse(params['jobId']![0]);
String jobName = params['jobName']![0];
String genderName = params['genderName']![0];
return AnswerTrajectoryJobDetail(jobId: jobId, jobName: jobName, genderName: genderName);
return AnswerTrajectoryJobDetail(jobId:jobId,jobName:jobName,genderName:genderName);
},
);
//
static final _completedReportPathHandler = Handler(
handlerFunc: (BuildContext? context, Map<String, List<String>> params) {
int examId = int.parse(params['examId']![0]);
String studentNo = params['studentNo']![0];
return CompletedReport(examId:examId,studentNo:studentNo);
},
);
//
// static final _doMarkingPapers = Handler(handlerFunc: (BuildContext? context, Map<String, List<String>> params) => MarkingPapers());
@ -430,22 +451,30 @@ class RouterManager {
router.define(markingReviewPath, handler: _reviewPageHandler, transitionType: TransitionType.material);
router.define(markingJobReviewPath, handler: _reviewJobPageHandler, transitionType: TransitionType.material);
router.define(markingDoPath, handler: _markingDoPageHandler, transitionType: TransitionType.material);
router.define(markingHomeworkDoPath, handler: _markingHomeworkDoPageHandler, transitionType: TransitionType.material);
router.define(markingReviewAbnormalPath, handler: _reviewAbnormalPageHandler, transitionType: TransitionType.material);
router.define(markingHomeworkDoPath,
handler: _markingHomeworkDoPageHandler, transitionType: TransitionType.material);
router.define(markingReviewAbnormalPath,
handler: _reviewAbnormalPageHandler, transitionType: TransitionType.material);
router.define(agreementPath, handler: _agreementPageHandler, transitionType: TransitionType.material);
router.define(ohterMainPagePath, handler: _ohterMainPageHandler, transitionType: TransitionType.material);
router.define(reportClassTeacherPath, handler: _reportClassTeacherPageHandler, transitionType: TransitionType.material);
router.define(reportSubjectTeacherPath, handler: _reportSubjectTeacherPageHandler, transitionType: TransitionType.material);
router.define(reportPersonalSubjectPath, handler: _reportPersonalSubjectPageHandler, transitionType: TransitionType.material);
router.define(reportClassTeacherPath,
handler: _reportClassTeacherPageHandler, transitionType: TransitionType.material);
router.define(reportSubjectTeacherPath,
handler: _reportSubjectTeacherPageHandler, transitionType: TransitionType.material);
router.define(reportPersonalSubjectPath,
handler: _reportPersonalSubjectPageHandler, transitionType: TransitionType.material);
router.define(userMinePath, handler: _userMinePageHandler, transitionType: TransitionType.material);
router.define(reportDetailPath, handler: _reportDetailPath, transitionType: TransitionType.material);
router.define(jobReportPagePath, handler: _jobReportPageHandler, transitionType: TransitionType.material);
router.define(jobExamPagePath, handler: _jobExamPageHandler, transitionType: TransitionType.material);
router.define(jobListParticipateInClassPath, handler: _jobListParticipateInClassHandler, transitionType: TransitionType.material);
router.define(jobListParticipateInClassPath,
handler: _jobListParticipateInClassHandler, transitionType: TransitionType.material);
router.define(quickDataCheckPath, handler: _quickDataCheckPageHandler, transitionType: TransitionType.material);
router.define(quickCheckPersonalPath, handler: _quickCheckPersonalPageHandler, transitionType: TransitionType.material);
router.define(jobPriorityReviewSetPath, handler: _jobPriorityReviewSetPageHandler, transitionType: TransitionType.material);
router.define(quickCheckPersonalPath,
handler: _quickCheckPersonalPageHandler, transitionType: TransitionType.material);
router.define(jobPriorityReviewSetPath,
handler: _jobPriorityReviewSetPageHandler, transitionType: TransitionType.material);
router.define(jobStudentGroupPath, handler: _jobStudentGroupPageHandler, transitionType: TransitionType.material);
router.define(jobFavoritePagePath, handler: _jobFavoritePagePathHandler, transitionType: TransitionType.material);
router.define(jobPersonalDetailPath, handler: _jobPersonalDetailPathHandler, transitionType: TransitionType.material);
@ -458,6 +487,9 @@ class RouterManager {
router.define(jobKnowledgePointsDetailPath, handler: _jobKnowledgePointsDetailPathHandler, transitionType: TransitionType.material);
router.define(answerTrajectoryPath, handler: _answerTrajectoryPathHandler, transitionType: TransitionType.material);
router.define(answerTrajectoryJobDetailPath, handler: _answerTrajectoryJobDetailPathHandler, transitionType: TransitionType.material);
router.define(completedReportPath, handler: _completedReportPathHandler, transitionType: TransitionType.material);
// getTransition()
router.notFoundHandler = Handler(handlerFunc: (BuildContext? context, Map<String, List<String>> params) {
toPrint(val: "ROUTE WAS NOT FOUND !!!");

View File

@ -30,6 +30,8 @@ import 'package:marking_app/common/model/report/report_for_subject_teacher_param
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/report/report_student_history_record.dart';
import 'package:marking_app/common/model/report/report_student_info.dart';
import 'package:marking_app/common/model/report/small_question.dart';
import 'package:marking_app/common/model/user/user_info_report.dart';
import 'package:retrofit/retrofit.dart' as the_retrofit;
@ -143,4 +145,20 @@ abstract class RestClientReport {
Future<BaseStructureResultReport<SmallQuestion>> getQuestion(
@the_retrofit.Body() ReportCardParams params
);
// =>
@the_retrofit.GET("/api/exam/report/examstudentinfo")
Future<BaseStructureResultReport<ReportStudentInfo>> getStudentInfo(
@the_retrofit.Query("examId") int examId,
@the_retrofit.Query("studentNo") String studentNo,
);
// =>
@the_retrofit.GET("/api/exam/report/studentexamrecords")
Future<BaseStructureResultReport<List<ReportStudentHistoryRecord>>> getStudentHistroyRecords(
@the_retrofit.Query("userId") int userId,
@the_retrofit.Query("classId") int classId,
@the_retrofit.Query("startTime") String startTime,
@the_retrofit.Query("endTime") String endTime,
);
}