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

1148 lines
44 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'package:achievement_view/achievement_view.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
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 {
const TheReport({Key? key}) : super(key: key);
@override
_TheReportState createState() => _TheReportState();
}
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() {
getHomeComboExam();
// getExamTypeList();
// getGradeEnumList();
// _future = initData();
Future.delayed(Duration.zero, () {
_user = ref.read(userProvider);
_userReportListener = ref.read(userReportProvider.notifier).addListener(
(state) {
_userReport = state;
if (_userReport.normal) {
// _future = initData();
toUpState(setState, () {}, mounted);
}
},
);
});
super.initState();
}
@override
void dispose() {
_userReportListener();
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 {
RestClientReport clientReport = await getClientReport();
UserInfoReport _userReport = ref.read(userReportProvider);
if (!_userReport.normal) {
if(ref.read(userProvider).id == '540117143121989') return null;
// 用户职位数据是否已经请求,在主页已经请求一次 为正常使用 备用
bool theFlag =
await ref.read(userReportProvider.notifier).initUserReport();
if (!theFlag) {
return ToastUtils.showError('请求失败请重试');
}
}
BaseStructureResultReport<ReportHomeModel> res =
await clientReport.getReportHomeData(examId);
if (res.success) {
return res.data;
} else {
ToastUtils.showError(res.message ?? '请求错误,请重试');
}
} catch (e) {
if (e is CheckedFromJsonException) {
// JSON 解析失败,处理异常
toPrint(val: 'JSON 解析失败: ${e.message}');
toPrint(val: 'JSON 解析失败,出错字段: ${e.key}');
} else {
// 其他异常,处理其他错误
toPrint(val: '发生了其他错误: $e');
}
return null;
}
return null;
}
var _scaffoldkey = new GlobalKey<ScaffoldState>(); //将Scaffold设置为全局变量
@override
Widget build(BuildContext context) {
super.build(context); //调用super.build(返回值始终返回null应将其忽略)
final userState = ref.watch(userProvider);
return AnnotatedRegion(
value: const SystemUiOverlayStyle(
systemNavigationBarColor: Color(0xFF000000),
systemNavigationBarDividerColor: null,
statusBarColor: Colors.transparent,
systemNavigationBarIconBrightness: Brightness.light,
statusBarIconBrightness: Brightness.dark,
statusBarBrightness: Brightness.light,
),
child: Scaffold(
key: _scaffoldkey,
drawer: MyDrawer(
list: selectList,
isGrade: isGrade,
onChanged: checkHandle,
refresh: getLevel),
body: Column(
children: [
Container(
color: Colors.white,
padding: EdgeInsets.only(
top: MediaQuery.of(context).padding.top + 4.h,
left: 14.w,
right: 14.w,
bottom: 19.h),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: TopUserInfo(),
),
/* InkWell(
onTap: () {},
child: Text(
'历史报告',
style: TextStyle(
fontSize: 14.sp,
color: Color.fromRGBO(128, 128, 128, 1)),
),
),*/
],
),
),
Expanded(
child: Padding(
padding: EdgeInsets.only(left: 14.w, right: 14.w),
child: Column(
children: [
SizedBox(
height: 50.r,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Image.asset(
'assets/images/school_icon.png',
width: 22.w,
height: 22.w,
),
Text(
userState.schoolName,
style: TextStyle(
fontSize: 14.sp,
color: Color.fromRGBO(62, 86, 173, 1)),
)
],
),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
InkWell(
onTap: () {
setState(() {
selectList = gradeList;
isGrade = true;
_scaffoldkey.currentState?.openDrawer();
});
},
child: Container(
padding: EdgeInsets.symmetric(
vertical: 8.h, horizontal: 20.r),
width:
(MediaQuery.of(context).size.width - 80.r) / 2,
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 - 80.r) / 2,
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: [
Padding(
padding: EdgeInsets.only(top: 5.r,bottom: 5.r,right: 2.r),
child: 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),
),
),
Flexible(
child: Text(
item.name,
style: TextStyle(
fontSize: 14.sp,
color: Colors.black),
),
)
],
),
),
Container(
padding:
EdgeInsets.symmetric(horizontal: 10.r),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5.r),
),
child: Table(
defaultVerticalAlignment:
TableCellVerticalAlignment.middle,
border: TableBorder.symmetric(
inside: BorderSide(
width: 1, color: Color(0xFFD7DBF0)),
outside: BorderSide.none,
),
// borderRadius: BorderRadius.circular(5.r),
children: [
TableRow(
decoration: BoxDecoration(
color: Color(0xFFECECEC),
),
children: [
Center(
child: Container(
padding: EdgeInsets.symmetric(
vertical: 6.r),
child: Text(
'年级',
style: TextStyle(
fontSize: 14.sp,
color: Color(0xFF8A8A8A)),
),
),
),
Center(
child: Text(
'科目',
style: TextStyle(
fontSize: 14.sp,
color: Color(0xFF8A8A8A)),
),
),
Center(
child: Text(
'考试日期',
style: TextStyle(
fontSize: 14.sp,
color: Color(0xFF8A8A8A)),
),
),
],
),
TableRow(
decoration: BoxDecoration(
color: Colors.white,
),
children: [
Center(
child: Container(
padding: EdgeInsets.symmetric(
vertical: 6.r),
child: Text(
item.grade,
style: TextStyle(
fontSize: 14.sp,
color:
Color(0xFF4A4A4A)),
),
),
),
Center(
child: Text(
item.subjectStr,
style: TextStyle(
fontSize: 14.sp,
color: Color(0xFF4A4A4A)),
),
),
Center(
child: Text(
item.startTimeStr,
style: TextStyle(
fontSize: 14.sp,
color: Color(0xFF4A4A4A)),
),
),
])
],
),
),
InkWell(
onTap: () {
RouterManager.router.navigateTo(
context,
RouterManager.reportDetailPath +
'?examId=${item.id}&showGrade=${showGrade}',
transition: getTransition(),
);
},
child: Container(
margin: EdgeInsets.symmetric(
horizontal: 60.r, vertical: 20.r),
padding:
EdgeInsets.symmetric(vertical: 5.r),
width: double.infinity,
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(20.r),
gradient: LinearGradient(
begin: Alignment(0.95, -0.30),
end: Alignment(-0.95, 0.3),
colors: [
Color(0xFF3561FE),
Color(0xFF6A89FC)
])),
child: Center(
child: Text(
'查看报告',
style: TextStyle(
fontSize: 16.sp,
color: Colors.white),
)),
),
)
],
),
);
},
itemCount: reportList.length,
):MyEmptyWidget(),
),
],
),
),
)
],
)),
);
}
}
// 报告body
class _TheReportBody extends HookWidget {
final UserInfo user;
final UserInfoReport userReport;
final ReportHomeModel? data;
final Function(int? examId, int positionIndex) switchCall;
final Function() refreshReport;
_TheReportBody(
{required this.user,
required this.userReport,
required this.switchCall,
required this.refreshReport,
required this.data,
Key? key})
: super(key: key);
@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<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];
if (examData == null || theCurrentPosition == null) {
return Padding(
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(examId, potnAndExamCotl.positionIndex.value);
List<Positions> positions = userReport.positions;
if (positions.isEmpty) {
return ToastUtils.showInfo('没有数据,请刷新');
}
int? examId = await potnAndExamCotl.openSwitch(
context: context,
currentExamId: examData?.examId ?? -1,
currentPositionIndex: userReport.positionIndex);
switchCall(examId, potnAndExamCotl.positionIndex.value);
}),
),
Expanded(
child: Center(
child: Container(
child: CupertinoButton(
padding: const EdgeInsets.only(left: 10, right: 10),
color: Theme.of(context).primaryColor,
//按钮被按下时的不透明度程度0~1之间
pressedOpacity: 1,
//这也可以自己定义Container然后固定大小进行设置等等
child:
quickText('没有数据,请重试', color: Colors.white, size: 14.sp),
onPressed: () => easyThrottle(
'reportHomeNoDataAgain', () => refreshReport()),
),
),
),
)
],
),
);
}
// 内容区域
return Padding(
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 {
List<Positions> positions = userReport.positions;
if (positions.isEmpty) {
return ToastUtils.showInfo('没有数据,请刷新');
}
int? examId = await potnAndExamCotl.openSwitch(
context: context,
currentExamId: examData.examId,
currentPositionIndex: userReport.positionIndex);
switchCall(examId, potnAndExamCotl.positionIndex.value);
}),
),
Expanded(
child: ScrollConfiguration(
behavior: EUMNoScrollBehavior(),
child: ListView(
padding: EdgeInsets.only(top: 20.h, bottom: 20.h),
children: [
// 顶部平均分模块
$TopAverageContainer(
averageVal: examData.averageScore,
totalVal: examData.totalScore,
context: context),
// 详细报告入口区域
$DetailedReportEntry(
context: context,
examId: examData.examId,
subjectId: theCurrentPosition.subjectId,
classId: theCurrentPosition.classId,
grade: examData.grade,
subject: examData.subjects,
examDate: examData.startTime,
identity: theCurrentPosition.identityEnum,
subjectName: theCurrentPosition.subjectName ?? '',
),
// 分段情况
$GraphicDataArea(
title: '分段概况',
titleImg: 'assets/images/report_home_icon_burst.png',
graphicContainer: Padding(
padding: EdgeInsets.only(top: 60.h, bottom: 20.h),
child: BarChartSample3(tagComparisonList!),
)),
// 单科概况
$GraphicDataArea(
title: '单科概况',
titleImg: 'assets/images/report_home_icon_subject.png',
graphicContainer:
$TheProgressChart(context, examSubjectDatas!)),
],
),
),
),
],
),
);
}
}
/// 底部渐变色
@swidget
Widget $scaffoldBgc() {
return Container(
height: ScreenUtil().screenHeight,
width: ScreenUtil().screenWidth,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [Color.fromRGBO(226, 232, 255, 1), Colors.white, Colors.white],
),
),
);
}
// 页面TITLE
@swidget
Widget $reportTitle({required String titleName, required switchCall}) {
return Stack(
alignment: const FractionalOffset(0.98, 0.5),
children: [
Container(
padding: EdgeInsets.only(right: titleName.length > 14 ? 50 : 0).w,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(
child: Center(
child: quickText(
titleName,
size: 16.sp,
color: Color.fromRGBO(45, 56, 76, 1),
fontWeight: FontWeight.w600,
maxLines: 2,
),
),
),
],
),
),
InkWell(
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),
quickText('切换', color: Color.fromRGBO(80, 87, 103, 1), size: 12.sp),
],
),
)
],
);
}
/// 顶部平均分模块
@swidget
Widget $topAverageContainer(
{required double averageVal,
required double totalVal,
required BuildContext context}) {
return Stack(
alignment: const FractionalOffset(0.99, 0),
children: [
Container(
padding: EdgeInsets.only(left: 12.w),
child: Row(
children: [
Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ClipRRect(
borderRadius: BorderRadius.circular(3).r,
child: Container(
alignment: Alignment.centerLeft,
padding:
EdgeInsets.only(left: 4, right: 4, top: 4, bottom: 7).r,
child: quickText('平均分', size: 6.sp, color: Colors.white),
decoration: ShapeDecoration(
shape: BeveledRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(2).r,
topRight: Radius.circular(2).r,
bottomLeft: Radius.circular(15).r,
bottomRight: Radius.circular(15).r,
),
),
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
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),
SizedBox(height: 1.h),
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)
],
);
}
/// 详细报告入口模块
@swidget
Widget $detailedReportEntry({
required String grade,
required String subject,
required String examDate,
required int examId,
required int? classId,
required int? subjectId,
required ReportUserIdentity identity,
required String subjectName,
required BuildContext context,
}) {
return Container(
width: double.infinity,
margin: EdgeInsets.only(top: 6.h, bottom: 28.h),
// constraints: BoxConstraints(
// minHeight: 140.h,
// minWidth: double.infinity,
// maxHeight: 160.h,
// maxWidth: double.infinity,
// ),
padding: EdgeInsets.symmetric(horizontal: 18.w, vertical: 16.h),
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/detailed_report_entry_bgm.png'),
fit: BoxFit.fill,
),
),
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
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)),
],
),
SizedBox(width: 23.w),
Expanded(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
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),
],
)
],
),
),
SizedBox(width: 23.w),
Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
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)),
],
),
],
),
SizedBox(height: 30.h),
InkWell(
onTap: () => easyThrottle('reportToUserPositionDetails', () {
String rootPath;
switch (identity) {
case ReportUserIdentity.TEACHER: // 单科老师
rootPath = RouterManager.reportSubjectTeacherPath +
'?examId=$examId&classId=$classId&subject=$subjectId&subjectName=${Uri.encodeComponent(subjectName)}';
break;
case ReportUserIdentity.CLASS: // 班主任
rootPath =
RouterManager.reportClassTeacherPath + '?examId=$examId';
break;
case ReportUserIdentity.GRADE: // 年级
case ReportUserIdentity.SCHOOL_LEVEL: // 校级
case ReportUserIdentity.STATE_EDUCATION_COMMISSION: // 国家教育委员会
default:
rootPath = '';
return AchievementView(
elevation: 0.5,
duration: Duration(seconds: 1),
title: "提示",
subTitle: "当前职位详情还未开放,请稍后",
color: Theme.of(context).primaryColor,
).show(context);
}
RouterManager.router
.navigateTo(context, rootPath, transition: getTransition());
}),
child: Container(
width: double.infinity,
margin: EdgeInsets.symmetric(horizontal: 25.w),
padding: EdgeInsets.symmetric(vertical: 9.h),
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(80).r,
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Color.fromRGBO(54, 86, 255, 1),
Color.fromRGBO(93, 128, 255, 1)
],
),
boxShadow: [
BoxShadow(
color: Color.fromRGBO(46, 91, 255, 0.4),
offset: Offset(2.0, 2.0), //阴影xy轴偏移量
blurRadius: 15.0, //阴影模糊程度
spreadRadius: 1.0, //阴影扩散程度
)
],
),
child: quickText('查看详细报告',
color: Colors.white, size: 14.sp, fontWeight: FontWeight.w400),
),
),
],
),
);
}
/// 图形数据模块
@swidget
Widget $graphicDataArea(
{required String title,
required String titleImg,
required Widget graphicContainer}) {
return Container(
margin: EdgeInsets.only(bottom: 28.h),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Image.asset(titleImg, width: 22.w, height: 22.h),
SizedBox(width: 2.w),
quickText(title, size: 16.sp, color: Color.fromRGBO(45, 56, 76, 1)),
],
),
SizedBox(height: 6.h),
Card(
elevation: 11.h,
shadowColor: Color.fromRGBO(46, 91, 255, 0.10),
borderOnForeground: true,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(6).r,
side: BorderSide(color: Colors.white, width: 1.4.r),
),
child: graphicContainer,
),
],
),
);
}
/// 进度图
@swidget
Widget $theProgressChart(context, List<ExamSubjectDatas> datas) {
bool isMultiple = datas.length > 1; // 是不是多个数据
return Container(
padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 19.h),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(6).r,
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [Color.fromRGBO(249, 250, 255, 1), Colors.white],
),
),
child: Column(
children: [
/// 平均分
...datas.map((e) {
return $theProgressWidget(
context: context,
isMultiple: isMultiple,
linearGradient: LinearGradient(
colors: [Colors.white, Theme.of(context).primaryColor]),
subjectName: e.subjectName + '平均分',
suffixTitle: e.totalScoreStr + '',
contentVal: e.averageScoreStr + '',
percent: e.averagePercent,
contentColor: Theme.of(context).primaryColor,
);
}),
SizedBox(height: 20.h),
/// 通过率
...datas.map((e) {
return $theProgressWidget(
context: context,
isMultiple: isMultiple,
linearGradient: LinearGradient(
colors: [Colors.white, Color.fromRGBO(0, 131, 253, 1)]),
subjectName: e.subjectName + '及格率',
suffixTitle: '100%',
contentVal: e.passRateStr + '%',
percent: e.passPercent,
contentColor: Color.fromRGBO(0, 131, 253, 1),
);
})
],
),
);
}
/// 进度条图
@swidget
Widget $theProgressWidget({
required bool isMultiple,
required BuildContext context,
required LinearGradient linearGradient,
required String subjectName,
required String suffixTitle,
required String contentVal,
required Color contentColor,
required double percent,
}) {
return Padding(
padding: EdgeInsets.only(top: isMultiple ? 4.h : 0),
child: Stack(
alignment: const FractionalOffset(0.5, 0.45),
children: [
Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
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),
// width: MediaQuery.of(context).size.width - 50,
animation: true,
lineHeight: 9.h,
animationDuration: 2500,
percent: percent,
linearGradient: linearGradient,
// center: Text(
// '${markingItem.completionRateStr}%',
// style: TextStyle(color: Colors.white, fontSize: 10.sp),
// ),
// linearStrokeCap: LinearStrokeCap.butt,
// progressColor: Theme.of(context).primaryColor,
backgroundColor: const Color.fromRGBO(219, 224, 243, 1)
.withOpacity(0.45),
barRadius: Radius.circular(10.h),
),
),
Container(
width: 42.w,
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),
),
],
),
],
),
quickText(contentVal,
size: 12.sp, fontWeight: FontWeight.w700, color: contentColor),
],
),
);
}