Marking.Client.Moblie/marking_app/lib/pages/report_detail/index.dart

652 lines
28 KiB
Dart

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