mcy_new #1

Merged
wangyang merged 179 commits from mcy_new into master 2025-08-28 10:10:45 +08:00
5 changed files with 494 additions and 228 deletions
Showing only changes of commit 7fcd875c71 - Show all commits

View File

@ -44,10 +44,9 @@ class _ClassStudentPageState extends State<ClassStudentPage> {
actions: const [ actions: const [
ReturnToHomepage(), ReturnToHomepage(),
], ],
elevation: 0,
), ),
body: Padding( body: Obx(() {
padding: EdgeInsets.symmetric(vertical: 14.r, horizontal: 14.r),
child: Obx(() {
return EasyRefresh( return EasyRefresh(
firstRefresh: false, firstRefresh: false,
taskIndependence: true, taskIndependence: true,
@ -63,9 +62,9 @@ class _ClassStudentPageState extends State<ClassStudentPage> {
shrinkWrap: true, shrinkWrap: true,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2, crossAxisCount: 2,
mainAxisSpacing: 10.r, mainAxisSpacing: 0.r,
crossAxisSpacing: 10.r, crossAxisSpacing: 0.r,
childAspectRatio: 556 / 112, childAspectRatio: 556 / 90,
), ),
children: children:
List.generate(state.studentList.length, (index) { List.generate(state.studentList.length, (index) {
@ -85,8 +84,10 @@ class _ClassStudentPageState extends State<ClassStudentPage> {
padding: EdgeInsets.symmetric(horizontal: 10.r), padding: EdgeInsets.symmetric(horizontal: 10.r),
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: borderRadius:
BorderRadius.all(Radius.circular(10.r)), BorderRadius.all(Radius.circular(0.r)),
color: Colors.white, color: Colors.transparent,
border: Border(left: BorderSide(width:
(index + 1)%2 == 0? 1.r:0,color: const Color(0xFFA5A5A5)),bottom: BorderSide(width: 1.r,color: const Color(0xFFA5A5A5)))
), ),
child: Row( child: Row(
mainAxisAlignment: mainAxisAlignment:
@ -241,7 +242,9 @@ class _ClassStudentPageState extends State<ClassStudentPage> {
); );
}), }),
) )
: ListView.builder( : Padding(
padding: EdgeInsets.symmetric(vertical: 14.r, horizontal: 14.r),
child: ListView.builder(
itemBuilder: (context, index) { itemBuilder: (context, index) {
StudentItem item = state.studentList[index]; StudentItem item = state.studentList[index];
return InkWell( return InkWell(
@ -416,11 +419,11 @@ class _ClassStudentPageState extends State<ClassStudentPage> {
); );
}, },
itemCount: state.studentList.length, itemCount: state.studentList.length,
),
) )
: const MyEmptyWidget(), : const MyEmptyWidget(),
); );
}), }),
),
); );
} }
); );

View File

@ -37,7 +37,14 @@ class StudentWorkDetailLogic extends GetxController with RequestToolMixin, GetSi
); );
StudentHistory data = await getClient().getStudentHistory(params); StudentHistory data = await getClient().getStudentHistory(params);
state.studentData.value = data; state.studentData.value = data;
for (var element in state.studentData.value.items.items) { /* state.kgtLine.value = [{'id':0,'rate':0}];
state.zgtLine.value = [{'id':0,'rate':0}];
state.allLine.value = [{'id':0,'rate':0}];*/
state.kgtLine.value = [];
state.zgtLine.value = [];
state.allLine.value = [];
for (var i = 0;i<state.studentData.value.items.items.length;i++ ) {
var element = state.studentData.value.items.items[i];
int num = 0; int num = 0;
for (var item in element.kgtList) { for (var item in element.kgtList) {
if (item.state == 0) { if (item.state == 0) {
@ -52,7 +59,12 @@ class StudentWorkDetailLogic extends GetxController with RequestToolMixin, GetSi
if (num == (element.kgtList.length + element.zgtList.length)) { if (num == (element.kgtList.length + element.zgtList.length)) {
element.allNotDone = true; element.allNotDone = true;
} }
state.kgtLine.add({'id':i+1,'rate':(element.kgtCorrectRate/100 * 5).toStringAsFixed(2)});
state.zgtLine.add({'id':i+1,'rate':(element.zgtCorrectRate/100 * 5).toStringAsFixed(2)});
state.allLine.add({'id':i+1,'rate':(element.correctRate/100 * 5).toStringAsFixed(2)});
} }
EasyLoading.dismiss(); EasyLoading.dismiss();
} }

View File

@ -17,4 +17,7 @@ class StudentWorkDetailState {
late RxString customTimeStr = '自定义'.obs; late RxString customTimeStr = '自定义'.obs;
late Rx<StudentHistory> studentData = Rx(StudentHistory(0, 0, Items([], 0), 0)); late Rx<StudentHistory> studentData = Rx(StudentHistory(0, 0, Items([], 0), 0));
late final int subject; late final int subject;
late RxList kgtLine = [].obs;
late RxList zgtLine = [].obs;
late RxList allLine = [].obs;
} }

View File

@ -1,3 +1,4 @@
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_easyrefresh/easy_refresh.dart'; import 'package:flutter_easyrefresh/easy_refresh.dart';
@ -9,6 +10,7 @@ import 'package:making_school_asignment_app/common/utils/utils.dart';
import 'package:making_school_asignment_app/page/global_widget/MyEmptyWidget.dart'; import 'package:making_school_asignment_app/page/global_widget/MyEmptyWidget.dart';
import 'package:making_school_asignment_app/page/global_widget/ReturnToHomepage.dart'; import 'package:making_school_asignment_app/page/global_widget/ReturnToHomepage.dart';
import 'package:making_school_asignment_app/page/home_page/children/student_work_detail/widget/job_condition_filter.dart'; import 'package:making_school_asignment_app/page/home_page/children/student_work_detail/widget/job_condition_filter.dart';
import 'package:making_school_asignment_app/page/home_page/children/student_work_detail/widget/line_chart.dart';
import 'package:making_school_asignment_app/page/home_page/widget/progress_bar.dart'; import 'package:making_school_asignment_app/page/home_page/widget/progress_bar.dart';
import 'package:making_school_asignment_app/routes/app_pages.dart'; import 'package:making_school_asignment_app/routes/app_pages.dart';
import 'package:syncfusion_flutter_datepicker/datepicker.dart'; import 'package:syncfusion_flutter_datepicker/datepicker.dart';
@ -124,16 +126,22 @@ class _StudentWorkDetailPageState extends State<StudentWorkDetailPage> {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text( /* Text(
'总览:', '总览:',
style: TextStyle( style: TextStyle(
fontSize: 12.sp, fontSize: 12.sp,
color: Theme.of(context).primaryColor, color: Theme.of(context).primaryColor,
fontWeight: FontWeight.w600), fontWeight: FontWeight.w600),
),*/
SizedBox(height: 10.r,),
SizedBox(
height: 200.r,
child: LineChartCon(isShowingMainData: true,lineNum: 3,line1:state.kgtLine.value,line2: state.zgtLine.value,line3: state.allLine.value,),
), ),
SizedBox(height: 20.r,),
ProgressBar( ProgressBar(
title: '客观题正确率:', title: '客观题正确率:',
color:Theme.of(context).primaryColor, color:const Color(0xFF4DE6BF),
percent: state.studentData.value.kgtCorrectRate / 100, percent: state.studentData.value.kgtCorrectRate / 100,
padingEdg: EdgeInsets.zero, padingEdg: EdgeInsets.zero,
marginEdg: EdgeInsets.only(top: 8.h)), marginEdg: EdgeInsets.only(top: 8.h)),
@ -145,7 +153,7 @@ class _StudentWorkDetailPageState extends State<StudentWorkDetailPage> {
marginEdg: EdgeInsets.only(top: 8.h)), marginEdg: EdgeInsets.only(top: 8.h)),
ProgressBar( ProgressBar(
title: '总正确率:', title: '总正确率:',
color: Theme.of(context).primaryColor, color: const Color(0xFF1890FF),
percent: state.studentData.value.correctRate / 100, percent: state.studentData.value.correctRate / 100,
padingEdg: EdgeInsets.zero, padingEdg: EdgeInsets.zero,
marginEdg: EdgeInsets.only(top: 8.h)), marginEdg: EdgeInsets.only(top: 8.h)),
@ -153,6 +161,7 @@ class _StudentWorkDetailPageState extends State<StudentWorkDetailPage> {
), ),
); );
}), }),
Obx(() { Obx(() {
return JobConditionFilter( return JobConditionFilter(
controller: logic.tabController, controller: logic.tabController,
@ -221,8 +230,8 @@ class _StudentWorkDetailPageState extends State<StudentWorkDetailPage> {
height: 10.r, height: 10.r,
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(5.r)), borderRadius: BorderRadius.all(Radius.circular(5.r)),
// color: Color(0xFF4CC793), color: const Color(0xFF00B386),
border: Border.all(width: 1.r, color: Theme.of(context).primaryColor), border: Border.all(width: 1.r, color: const Color(0xFF00B386)),
), ),
), ),
SizedBox( SizedBox(
@ -240,8 +249,8 @@ class _StudentWorkDetailPageState extends State<StudentWorkDetailPage> {
height: 10.r, height: 10.r,
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(5.r)), borderRadius: BorderRadius.all(Radius.circular(5.r)),
// color: Color(0xFFFF7474), color: const Color(0xFFCB191B),
border: Border.all(width: 1.r, color: Color(0xFFFF7474)), border: Border.all(width: 1.r, color: const Color(0xFFCB191B)),
), ),
), ),
SizedBox( SizedBox(
@ -422,7 +431,7 @@ class _StudentWorkDetailPageState extends State<StudentWorkDetailPage> {
'客:', '客:',
style: TextStyle( style: TextStyle(
fontSize: 12.sp, fontSize: 12.sp,
color: Color(0xFF5B5B5B)), color: const Color(0xFF5B5B5B)),
), ),
SizedBox( SizedBox(
width: 5.r, width: 5.r,
@ -444,16 +453,18 @@ class _StudentWorkDetailPageState extends State<StudentWorkDetailPage> {
width: 25.r, width: 25.r,
height: 25.r, height: 25.r,
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.transparent, color: subjective.state == 3
?const Color(0xFF00B386):subjective.state == 2
? const Color(0xFFCB191B):Colors.transparent,
border: Border.all( border: Border.all(
width: 1.r, width: 1.r,
color: subjective.state == 0 color: subjective.state == 0
? Color(0xFFDDDDDD) ? const Color(0xFFDDDDDD)
: subjective.state == 3 : subjective.state == 3
?Theme.of(context).primaryColor ?const Color(0xFF00B386)
: subjective.state == 2 : subjective.state == 2
? Color(0xFFFF7474) ? const Color(0xFFCB191B)
: Color(0xFF666666)), : const Color(0xFF666666)),
borderRadius: BorderRadius.all(Radius.circular(12.5.r))), borderRadius: BorderRadius.all(Radius.circular(12.5.r))),
child: Center( child: Center(
child: Text( child: Text(
@ -464,16 +475,15 @@ class _StudentWorkDetailPageState extends State<StudentWorkDetailPage> {
color: subjective color: subjective
.state == .state ==
0 0
? Color( ? const Color(
0xFFDDDDDD) 0xFFDDDDDD)
: subjective.state == : subjective.state ==
3 3
? Theme.of(context).primaryColor ? Colors.white
: subjective.state == : subjective.state ==
2 2
? Color( ?Colors.white
0xFFFF7474) : const Color(
: Color(
0xFF666666)), 0xFF666666)),
)), )),
); );
@ -484,7 +494,7 @@ class _StudentWorkDetailPageState extends State<StudentWorkDetailPage> {
'', '',
style: TextStyle( style: TextStyle(
fontSize: 12.sp, fontSize: 12.sp,
color: Color(0xFF5B5B5B)), color: const Color(0xFF5B5B5B)),
), ),
], ],
), ),
@ -499,7 +509,7 @@ class _StudentWorkDetailPageState extends State<StudentWorkDetailPage> {
'主:', '主:',
style: TextStyle( style: TextStyle(
fontSize: 12.sp, fontSize: 12.sp,
color: Color(0xFF5B5B5B)), color: const Color(0xFF5B5B5B)),
), ),
SizedBox( SizedBox(
width: 5.r, width: 5.r,
@ -521,16 +531,18 @@ class _StudentWorkDetailPageState extends State<StudentWorkDetailPage> {
width: 25.r, width: 25.r,
height: 25.r, height: 25.r,
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.transparent, color: subjective.state == 3
? const Color(0xFF00B386):subjective.state == 2
? const Color(0xFFCB191B):Colors.transparent,
border: Border.all( border: Border.all(
width: 1.r, width: 1.r,
color: subjective.state == 0 color: subjective.state == 0
? Color(0xFFDDDDDD) ? const Color(0xFFDDDDDD)
: subjective.state == 3 : subjective.state == 3
? Theme.of(context).primaryColor ? const Color(0xFF00B386)
: subjective.state == 2 : subjective.state == 2
? Color(0xFFFF7474) ? const Color(0xFFCB191B)
: Color(0xFF666666)), : const Color(0xFF666666)),
borderRadius: BorderRadius.all(Radius.circular(12.5.r))), borderRadius: BorderRadius.all(Radius.circular(12.5.r))),
child: Center( child: Center(
child: Text( child: Text(
@ -541,16 +553,15 @@ class _StudentWorkDetailPageState extends State<StudentWorkDetailPage> {
color: subjective color: subjective
.state == .state ==
0 0
? Color( ? const Color(
0xFFDDDDDD) 0xFFDDDDDD)
: subjective.state == : subjective.state ==
3 3
? Theme.of(context).primaryColor ? Colors.white
: subjective.state == : subjective.state ==
2 2
? Color( ? Colors.white
0xFFFF7474) : const Color(
: Color(
0xFF666666)), 0xFF666666)),
)), )),
); );
@ -561,25 +572,25 @@ class _StudentWorkDetailPageState extends State<StudentWorkDetailPage> {
'', '',
style: TextStyle( style: TextStyle(
fontSize: 12.sp, fontSize: 12.sp,
color: Color(0xFF5B5B5B)), color: const Color(0xFF5B5B5B)),
), ),
], ],
), ),
ProgressBar( ProgressBar(
title: '客观题正确率:', title: '客观题正确率:',
color: Color(0xFFB2DA93), color: const Color(0xFFB2DA93),
percent: item.kgtCorrectRate / 100, percent: item.kgtCorrectRate / 100,
padingEdg: EdgeInsets.zero, padingEdg: EdgeInsets.zero,
marginEdg: EdgeInsets.only(top: 8.h)), marginEdg: EdgeInsets.only(top: 8.h)),
ProgressBar( ProgressBar(
title: '主观题正确率:', title: '主观题正确率:',
color: Color(0xFFB2DA93), color: const Color(0xFFB2DA93),
percent: item.zgtCorrectRate / 100, percent: item.zgtCorrectRate / 100,
padingEdg: EdgeInsets.zero, padingEdg: EdgeInsets.zero,
marginEdg: EdgeInsets.only(top: 8.h)), marginEdg: EdgeInsets.only(top: 8.h)),
ProgressBar( ProgressBar(
title: '总正确率:', title: '总正确率:',
color: Color(0xFFB2DA93), color: const Color(0xFFB2DA93),
percent: item.correctRate / 100, percent: item.correctRate / 100,
padingEdg: EdgeInsets.zero, padingEdg: EdgeInsets.zero,
marginEdg: EdgeInsets.only(top: 8.h)), marginEdg: EdgeInsets.only(top: 8.h)),

View File

@ -0,0 +1,237 @@
import 'dart:math';
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
class LineChartCon extends StatefulWidget {
final bool isShowingMainData;
final int lineNum;
final List? line1;
final List? line2;
final List? line3;
LineChartCon(
{required this.isShowingMainData,
required this.lineNum,
this.line1,
this.line2,
this.line3});
@override
State<LineChartCon> createState() => _LineChartConState();
}
class _LineChartConState extends State<LineChartCon> {
double maxX = 0.0;
@override
void initState() {
super.initState();
}
getMaxX(){
if (widget.lineNum > 2) {
if (widget.line3!.length > widget.line2!.length &&
widget.line3!.length > widget.line1!.length) {
maxX = double.parse(widget.line3!.length.toString());
} else if (widget.line2!.length > widget.line3!.length &&
widget.line2!.length > widget.line1!.length) {
maxX = double.parse(widget.line2!.length.toString());
} else {
maxX = double.parse(widget.line1!.length.toString());
}
} else if (widget.lineNum > 1) {
}
print('maxx=======$maxX');
return maxX;
}
@override
Widget build(BuildContext context) {
return LineChart(
LineChartData(
lineTouchData: const LineTouchData(enabled: false),
gridData: gridData,
titlesData: titlesData1,
borderData: borderData,
lineBarsData: lineBarsData1,
minX: 1,
maxX: getMaxX()>0? getMaxX():3,
maxY: 6,
minY: 0,
),
duration: const Duration(milliseconds: 250),
);
}
FlTitlesData get titlesData1 => FlTitlesData(
bottomTitles: AxisTitles(
sideTitles: bottomTitles,
),
rightTitles: const AxisTitles(
sideTitles: SideTitles(showTitles: false),
),
topTitles: const AxisTitles(
sideTitles: SideTitles(showTitles: false),
),
leftTitles: AxisTitles(
sideTitles: leftTitles(),
),
);
List<LineChartBarData> get lineBarsData1 => [
lineChartBarData1_1,
lineChartBarData1_2,
lineChartBarData1_3,
];
Widget leftTitleWidgets(double value, TitleMeta meta) {
String text;
switch (value.toInt()) {
case 0:
text = '0';
break;
case 1:
text = '20%';
break;
case 2:
text = '40%';
break;
case 3:
text = '60%';
break;
case 4:
text = '80%';
break;
case 5:
text = '100%';
break;
default:
return Container();
}
return Text(text, style: TextStyle(fontSize: 12.sp, color: const Color(0xFF070707)), textAlign: TextAlign.left);
/* return SideTitleWidget(
axisSide: meta.axisSide,
child: Text(
'${value}',
style: TextStyle(fontSize: 12.sp, color: Color(0xFF070707)),
),
);*/
}
SideTitles leftTitles() => SideTitles(
getTitlesWidget: leftTitleWidgets,
showTitles: true,
interval: 1,
reservedSize: 50,
);
Widget bottomTitleWidgets(double value, TitleMeta meta) {
return SideTitleWidget(
axisSide: meta.axisSide,
space: 10,
child: Text(
value.toString() == '0.0' ? '' : value.toStringAsFixed(0),
style: TextStyle(
fontWeight: FontWeight.w400,
fontSize: 12.sp,
color: const Color.fromRGBO(39, 39, 39, 0.5),
),
),
);
}
SideTitles get bottomTitles => SideTitles(
showTitles: true,
reservedSize: 32,
interval: 1,
getTitlesWidget: bottomTitleWidgets,
);
FlGridData get gridData => const FlGridData(
show: true, drawVerticalLine: false, horizontalInterval: 1.0);
FlBorderData get borderData => FlBorderData(
show: true,
border: const Border(
bottom: BorderSide(color: Colors.transparent, width: 1),
left: BorderSide(color: Colors.transparent),
right: BorderSide(color: Colors.transparent),
top: BorderSide(color: Colors.transparent),
),
);
LineChartBarData get lineChartBarData1_1 => LineChartBarData(
isCurved: true,
curveSmoothness: 0,
color: const Color(0xFF4DE6BF),
barWidth: 2,
isStrokeCapRound: true,
dotData: const FlDotData(show: false),
belowBarData: BarAreaData(show: false),
spots: List.generate(widget.line1!.length, (index){
var element = widget.line1![index];
return FlSpot(double.parse(element['id'].toString()), double.parse(element['rate'].toString()));
})
/* const [
FlSpot(1, 0),
FlSpot(3, 1.5),
FlSpot(5, 1.4),
FlSpot(7, 3.4),
FlSpot(10, 2),
FlSpot(12, 2.2),
FlSpot(13, 1.8),
],*/
);
LineChartBarData get lineChartBarData1_2 => LineChartBarData(
isCurved: true,
curveSmoothness: 0,
color: Theme.of(context).primaryColor,
barWidth: 2,
isStrokeCapRound: true,
dotData: const FlDotData(show: false),
belowBarData: BarAreaData(
show: false,
color: Colors.yellow,
),
spots: List.generate(widget.line2!.length, (index){
var element = widget.line2![index];
return FlSpot(double.parse(element['id'].toString()), double.parse(element['rate'].toString()));
})
/* const [
FlSpot(1, 1),
FlSpot(3, 2.8),
FlSpot(7, 1.2),
FlSpot(10, 2.8),
FlSpot(12, 2.6),
FlSpot(13, 3.9),
],*/
);
LineChartBarData get lineChartBarData1_3 => LineChartBarData(
isCurved: true,
curveSmoothness: 0,
color: const Color(0xFF1890FF),
barWidth: 2,
isStrokeCapRound: true,
dotData: const FlDotData(show: false),
belowBarData: BarAreaData(show: false),
spots: List.generate(widget.line3!.length, (index){
var element = widget.line3![index];
return FlSpot(double.parse(element['id'].toString()), double.parse(element['rate'].toString()));
})
/* const [
FlSpot(1, 2.8),
FlSpot(3, 1.9),
FlSpot(6, 3),
FlSpot(10, 1.3),
FlSpot(13, 2.5),
],*/
);
}