439 lines
18 KiB
Dart
439 lines
18 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter/services.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:get/get.dart';
|
|
import 'package:badges/badges.dart' as badges;
|
|
import 'package:percent_indicator/percent_indicator.dart';
|
|
import 'package:school_asignment_app/common/job/work_student.dart';
|
|
import 'package:school_asignment_app/common/utils/enum_untils.dart';
|
|
import 'package:school_asignment_app/common/utils/utils.dart';
|
|
import 'package:school_asignment_app/page/global_widget/MyEmptyWidget.dart';
|
|
import 'package:school_asignment_app/page/global_widget/my_text.dart';
|
|
import 'package:school_asignment_app/routes/app_pages.dart';
|
|
|
|
import 'home_logic.dart';
|
|
|
|
class HomePage extends StatefulWidget {
|
|
const HomePage({Key? key}) : super(key: key);
|
|
|
|
@override
|
|
State<HomePage> createState() => _HomePageState();
|
|
}
|
|
|
|
class _HomePageState extends State<HomePage>
|
|
with AutomaticKeepAliveClientMixin {
|
|
final logic = Get.find<HomeLogic>();
|
|
final state = Get.find<HomeLogic>().state;
|
|
|
|
@override
|
|
bool get wantKeepAlive => true;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
super.build(context);
|
|
var spaceWidth = SizedBox(height: ScreenUtil().screenWidth / 19);
|
|
return AnnotatedRegion(
|
|
value: const SystemUiOverlayStyle(
|
|
systemNavigationBarColor: Color(0xFF000000),
|
|
systemNavigationBarDividerColor: null,
|
|
statusBarColor: Colors.white,
|
|
systemNavigationBarIconBrightness: Brightness.light,
|
|
statusBarIconBrightness: Brightness.dark,
|
|
statusBarBrightness: Brightness.light,
|
|
),
|
|
child: Column(
|
|
children: [
|
|
Container(
|
|
height: 200.h,
|
|
width: double.infinity,
|
|
decoration: const BoxDecoration(
|
|
image: DecorationImage(
|
|
image: AssetImage('assets/images/job_home_top_bgm.png'),
|
|
fit: BoxFit.fill, // 完全填充
|
|
),
|
|
),
|
|
),
|
|
SizedBox(height: 30.h),
|
|
Obx(() {
|
|
return $TermRow(
|
|
context,
|
|
[
|
|
EntranceModel(
|
|
title: '作业批阅',
|
|
image: 'assets/images/job_home_marking.png',
|
|
navigationUrl: Routes.readOverPage),
|
|
EntranceModel(
|
|
title: '学生历史作业',
|
|
image: 'assets/images/job_home_history.png',
|
|
navigationUrl: Routes.studentHistoryWorkPage,
|
|
page: 'history',
|
|
),
|
|
EntranceModel(
|
|
title: '知识点点掌握',
|
|
image: 'assets/images/job_home_knowledge.png',
|
|
navigationUrl: Routes.knowledgePointsGraspPage)
|
|
],
|
|
state.readOver.value);
|
|
}),
|
|
spaceWidth,
|
|
$TermRow(
|
|
context,
|
|
[
|
|
EntranceModel(
|
|
title: '答题轨迹',
|
|
image: 'assets/images/job_home_answer_record.png',
|
|
navigationUrl: ''),
|
|
EntranceModel(
|
|
title: '优先批阅设定',
|
|
image: 'assets/images/job_home_youxian.png',
|
|
navigationUrl: Routes.studentHistoryWorkPage,
|
|
page: 'set',
|
|
)
|
|
],
|
|
0),
|
|
|
|
/* $TermRow(
|
|
context,
|
|
[
|
|
EntranceModel(
|
|
title: '批阅设置',
|
|
image: 'assets/images/job_home_marking_set.png',
|
|
navigationUrl: '')
|
|
],
|
|
0),*/
|
|
Expanded(child: Obx(() {
|
|
return EasyRefresh(
|
|
firstRefresh: false,
|
|
taskIndependence: true,
|
|
controller: logic.refreshController,
|
|
header: MaterialHeader(),
|
|
footer: TaurusFooter(),
|
|
child: ListView.builder(
|
|
padding: EdgeInsets.only(
|
|
top: 11.h, bottom: 10.h, left: 12.w, right: 12.w),
|
|
itemBuilder: (context, index) {
|
|
Items item = state.workList[index];
|
|
return InkWell(
|
|
onTap: () {
|
|
Get.toNamed(Routes.annotateClassPage, arguments: {
|
|
'id': item.id,
|
|
'name': item.name,
|
|
'grade': item.grade
|
|
});
|
|
},
|
|
child: Container(
|
|
margin: EdgeInsets.only(bottom: 16.h),
|
|
child: Column(
|
|
children: [
|
|
SizedBox(height: 30.h),
|
|
Container(
|
|
padding: EdgeInsets.symmetric(
|
|
vertical: 16.h, horizontal: 10.w),
|
|
width: double.infinity,
|
|
decoration: BoxDecoration(
|
|
borderRadius: BorderRadius.circular(6.r),
|
|
color: const Color.fromRGBO(255, 255, 255, 1),
|
|
boxShadow: const [
|
|
BoxShadow(
|
|
color: Color.fromRGBO(210, 216, 241, 1),
|
|
offset: Offset.zero, //阴影y轴偏移量
|
|
blurRadius: 5.8, //阴影模糊程度
|
|
spreadRadius: 0, //阴影扩散程度
|
|
)
|
|
],
|
|
),
|
|
child: Column(
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
children: [
|
|
Row(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Container(
|
|
width: Utils.isPad() ? 32.w : 38.w,
|
|
height: 18.h,
|
|
alignment: Alignment.center,
|
|
padding: EdgeInsets.only(
|
|
left: Utils.isPad() ? 2.w : 3.w),
|
|
decoration: BoxDecoration(
|
|
color: state.type == 1
|
|
? const Color.fromRGBO(
|
|
104, 136, 253, 1)
|
|
: const Color.fromRGBO(
|
|
255, 175, 56, 1),
|
|
borderRadius: BorderRadius.only(
|
|
topLeft: Radius.circular(14.r),
|
|
topRight: Radius.circular(3.r),
|
|
bottomLeft: Radius.circular(4.r),
|
|
bottomRight: Radius.circular(4.r),
|
|
),
|
|
),
|
|
margin: EdgeInsets.only(right: 4.w),
|
|
child: quickText(
|
|
state.type == 1 ? '作业' : '考试',
|
|
color: Colors.white,
|
|
size: 10.sp),
|
|
),
|
|
Expanded(
|
|
child: quickText(
|
|
item.name,
|
|
maxLines: 2,
|
|
size: Utils.isPad() ? 14.sp : 16.sp,
|
|
color:
|
|
const Color.fromRGBO(70, 70, 70, 1),
|
|
fontWeight: FontWeight.bold,
|
|
),
|
|
)
|
|
],
|
|
),
|
|
SizedBox(height: 10.h),
|
|
Row(
|
|
crossAxisAlignment: CrossAxisAlignment.end,
|
|
children: [
|
|
quickText(
|
|
EnumUtils.formatSubject(item.subject),
|
|
color:
|
|
const Color.fromRGBO(97, 97, 97, 1),
|
|
size: 12.sp,
|
|
),
|
|
quickText(' / ',
|
|
color: const Color.fromRGBO(
|
|
130, 130, 130, 1),
|
|
size: 11.sp,
|
|
fontWeight: FontWeight.w500),
|
|
Container(
|
|
child: Row(
|
|
crossAxisAlignment:
|
|
CrossAxisAlignment.end,
|
|
children: [
|
|
quickText('题量:',
|
|
color: const Color.fromRGBO(
|
|
130, 130, 130, 1),
|
|
size: 11.sp),
|
|
quickText(
|
|
'10',
|
|
color: const Color.fromRGBO(
|
|
97, 97, 97, 1),
|
|
size: 13.sp,
|
|
),
|
|
],
|
|
),
|
|
),
|
|
quickText(' / ',
|
|
color: const Color.fromRGBO(
|
|
130, 130, 130, 1),
|
|
size: 11.sp,
|
|
fontWeight: FontWeight.w500),
|
|
quickText(
|
|
DateTime.parse(item.publishTime)
|
|
.toString()
|
|
.substring(0, 10),
|
|
color:
|
|
const Color.fromRGBO(97, 97, 97, 1),
|
|
size: 12.sp),
|
|
],
|
|
),
|
|
SizedBox(height: 10.h),
|
|
Row(
|
|
children: [
|
|
Expanded(
|
|
child: Container(
|
|
decoration: BoxDecoration(
|
|
borderRadius:
|
|
BorderRadius.circular(10.r),
|
|
),
|
|
child: LinearPercentIndicator(
|
|
padding: EdgeInsets.zero,
|
|
animation: true,
|
|
lineHeight: 8.h,
|
|
animationDuration: 2500,
|
|
percent: item.annotateRate == null?0:item.annotateRate! / 100,
|
|
progressColor:
|
|
const Color(0xFF6888FD),
|
|
backgroundColor:
|
|
const Color(0xFFE8E8E8),
|
|
barRadius: Radius.circular(10.r),
|
|
),
|
|
),
|
|
),
|
|
SizedBox(
|
|
width: 10.r,
|
|
),
|
|
quickText(
|
|
'${item.annotateRate!.toStringAsFixed(0)}%',
|
|
size: 10.sp,
|
|
color: const Color(0xFF464646)),
|
|
],
|
|
),
|
|
// FavoriteButton(jobTaskItem.id, jobTaskItem.title),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
},
|
|
itemCount: state.workList.length,
|
|
),
|
|
);
|
|
})),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
Get.delete<HomeLogic>();
|
|
super.dispose();
|
|
}
|
|
}
|
|
|
|
class EntranceModel extends Object {
|
|
String title;
|
|
String image;
|
|
String navigationUrl;
|
|
String? page;
|
|
|
|
EntranceModel(
|
|
{required this.title,
|
|
required this.image,
|
|
required this.navigationUrl,
|
|
this.page});
|
|
}
|
|
|
|
@swidget
|
|
Widget $TermRow(BuildContext context, List<EntranceModel> items, int? data) {
|
|
var leng = items.length;
|
|
Widget childWidget;
|
|
switch (leng) {
|
|
case 1:
|
|
childWidget =
|
|
Row(children: [Expanded(child: $TermItem(context, items[0], data!))]);
|
|
break;
|
|
case 2:
|
|
childWidget = Row(children: [
|
|
Expanded(flex: 9, child: $TermItem(context, items[0], data!)),
|
|
const Expanded(flex: 1, child: SizedBox()),
|
|
Expanded(flex: 9, child: $TermItem(context, items[1], data!)),
|
|
]);
|
|
break;
|
|
case 3:
|
|
double theHeight = ScreenUtil().screenWidth / 19 + 54.h * 2;
|
|
childWidget = Row(
|
|
children: [
|
|
Expanded(
|
|
child: $TermItem(context, items[0], data!, theHeight: theHeight)),
|
|
SizedBox(width: ScreenUtil().screenWidth / 19),
|
|
Expanded(
|
|
child: SizedBox(
|
|
height: theHeight,
|
|
child: Column(
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
children: [
|
|
$TermItem(context, items[1], data),
|
|
$TermItem(context, items[2], data),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
],
|
|
);
|
|
break;
|
|
default:
|
|
childWidget = Container();
|
|
}
|
|
|
|
return Container(
|
|
padding: EdgeInsets.symmetric(horizontal: 14.w), child: childWidget);
|
|
}
|
|
|
|
@swidget
|
|
Widget $TermItem(BuildContext context, EntranceModel e, int data,
|
|
{double? theHeight}) {
|
|
bool isJob = e.title == '作业批阅';
|
|
|
|
return Material(
|
|
color: Colors.white,
|
|
elevation: 3.r,
|
|
shadowColor: const Color.fromRGBO(231, 231, 231, 1),
|
|
borderRadius: BorderRadius.all(Radius.circular(8.r)),
|
|
child: InkWell(
|
|
onTap: () {
|
|
Get.toNamed(e.navigationUrl, arguments: {'page': e.page ?? ''});
|
|
},
|
|
|
|
// splashColor: splashColor,
|
|
borderRadius: BorderRadius.all(Radius.circular(8.r)),
|
|
child: badges.Badge(
|
|
showBadge: isJob && data > 0,
|
|
ignorePointer: false,
|
|
badgeContent: quickText(data, color: Colors.white, size: 10.sp),
|
|
badgeAnimation: const badges.BadgeAnimation.rotation(
|
|
animationDuration: Duration(seconds: 1),
|
|
colorChangeAnimationDuration: Duration(seconds: 1),
|
|
loopAnimation: false,
|
|
curve: Curves.fastOutSlowIn,
|
|
colorChangeAnimationCurve: Curves.easeInCubic,
|
|
),
|
|
badgeStyle: badges.BadgeStyle(
|
|
badgeColor: const Color.fromRGBO(255, 105, 105, 1),
|
|
shape: badges.BadgeShape.square,
|
|
borderRadius: BorderRadius.only(
|
|
topLeft: Radius.circular(10.r),
|
|
topRight: Radius.circular(8.5.r),
|
|
bottomRight: Radius.circular(8.5.r)),
|
|
// borderSide: BorderSide(color: Colors.white, width: 2),
|
|
elevation: 1,
|
|
padding: EdgeInsets.symmetric(
|
|
horizontal: Utils.isPad() ? 11.w : 16.w, vertical: 2.h),
|
|
),
|
|
position: badges.BadgePosition.topEnd(top: 10.r, end: 10.r),
|
|
child: Container(
|
|
height: theHeight,
|
|
padding: EdgeInsets.symmetric(vertical: 12.h),
|
|
decoration: BoxDecoration(
|
|
borderRadius: BorderRadius.all(Radius.circular(8.r)),
|
|
// boxShadow: [
|
|
// BoxShadow(
|
|
// color: const Color.fromRGBO(231, 231, 231, 1),
|
|
// offset: Offset(4.w, 6.h), //阴影y轴偏移量
|
|
// blurRadius: 8, //阴影模糊程度
|
|
// spreadRadius: 0.2, //阴影扩散程度
|
|
// )
|
|
// ],
|
|
// border: Border.all(width: 0.5.w, color: Color.fromARGB(255, 219, 226, 250)),
|
|
),
|
|
alignment: Alignment.center,
|
|
child: isJob
|
|
? Column(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
Image.asset(e.image,
|
|
height: 32.r, width: 32.r, fit: BoxFit.cover),
|
|
SizedBox(height: 6.r),
|
|
quickText(e.title,
|
|
size: 12.sp,
|
|
color: const Color.fromRGBO(79, 79, 79, 1),
|
|
fontWeight: FontWeight.w500),
|
|
],
|
|
)
|
|
: Row(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
Image.asset(e.image,
|
|
height: 32.r, width: 32.r, fit: BoxFit.cover),
|
|
SizedBox(width: 6.r),
|
|
quickText(e.title,
|
|
size: 12.sp,
|
|
color: const Color.fromRGBO(79, 79, 79, 1),
|
|
fontWeight: FontWeight.w500),
|
|
],
|
|
),
|
|
),
|
|
)),
|
|
);
|
|
}
|