680 lines
24 KiB
Dart
680 lines
24 KiB
Dart
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_structure_result_report.dart';
|
||
import 'package:marking_app/common/model/enum/reportUserIdentity.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/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/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';
|
||
|
||
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 UserInfo _user;
|
||
late UserInfoReport _userReport;
|
||
late Future<ReportHomeModel?> _future;
|
||
int? theExamId;
|
||
|
||
@override
|
||
bool get wantKeepAlive => true;
|
||
|
||
@override
|
||
void initState() {
|
||
_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();
|
||
}
|
||
|
||
/// 初始化数据
|
||
Future<ReportHomeModel?> initData({int? examId}) async {
|
||
try {
|
||
RestClientReport clientReport = await getClientReport();
|
||
UserInfoReport _userReport = ref.read(userReportProvider);
|
||
if (!_userReport.normal) {
|
||
// 用户职位数据是否已经请求,在主页已经请求一次 为正常使用 备用
|
||
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;
|
||
}
|
||
|
||
@override
|
||
Widget build(BuildContext context) {
|
||
super.build(context); //调用super.build(返回值始终返回null,应将其忽略)
|
||
|
||
return AnnotatedRegion(
|
||
value: const SystemUiOverlayStyle(
|
||
systemNavigationBarColor: Color(0xFF000000),
|
||
systemNavigationBarDividerColor: null,
|
||
statusBarColor: Colors.transparent,
|
||
systemNavigationBarIconBrightness: Brightness.light,
|
||
statusBarIconBrightness: Brightness.dark,
|
||
statusBarBrightness: Brightness.light,
|
||
),
|
||
child: Scaffold(
|
||
body: Stack(
|
||
children: [
|
||
// 渐变背景色
|
||
$ScaffoldBgc(),
|
||
|
||
RefreshIndicator(
|
||
displacement: 50,
|
||
color: Theme.of(context).primaryColor,
|
||
backgroundColor: Colors.white,
|
||
child: MyFutureBuilder.buildFutureBuilderOfSingleInstance<ReportHomeModel>(context, _future,
|
||
(ReportHomeModel? datas) {
|
||
return _TheReportBody(
|
||
user: _user,
|
||
userReport: _userReport,
|
||
data: datas,
|
||
refreshReport: () {
|
||
_future = initData();
|
||
toUpState(setState, () {}, mounted);
|
||
},
|
||
switchCall: (int? examId, int positionIndex) {
|
||
theExamId = examId;
|
||
if (examId != null) {
|
||
ref.read(userReportProvider.notifier).setPositionIndex(positionIndex);
|
||
|
||
_future = initData(examId: examId);
|
||
toUpState(setState, () {}, mounted);
|
||
}
|
||
},
|
||
);
|
||
}),
|
||
onRefresh: () async {
|
||
_future = initData(examId: theExamId);
|
||
await _future;
|
||
await Future.delayed(Duration(seconds: 1), () => toUpState(setState, () => {}, mounted));
|
||
},
|
||
),
|
||
],
|
||
),
|
||
),
|
||
);
|
||
}
|
||
}
|
||
|
||
// 报告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),
|
||
],
|
||
),
|
||
);
|
||
}
|