467 lines
17 KiB
Dart
467 lines
17 KiB
Dart
/*
|
||
* @Author: wangyang 1147192855@qq.com
|
||
* @Date: 2022-07-05 16:42:39
|
||
* @LastEditors: wangyang 1147192855@qq.com
|
||
* @LastEditTime: 2022-09-28 12:18:22
|
||
* @FilePath: \marking_app\lib\pages\home\index.dart
|
||
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||
*/
|
||
import 'package:flutter/material.dart';
|
||
import 'package:flutter/services.dart';
|
||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||
import 'package:marking_app/common/mixin/common.dart';
|
||
import 'package:flutter_easyrefresh/easy_refresh.dart';
|
||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||
import 'package:marking_app/common/config/request_config.dart';
|
||
import 'package:marking_app/common/model/common/base_page.dart';
|
||
import 'package:marking_app/common/model/enum/marking_list_type.dart';
|
||
import 'package:functional_widget_annotation/functional_widget_annotation.dart';
|
||
import 'package:marking_app/common/model/event_bus/home_marking_statistics.dart';
|
||
import 'package:marking_app/common/model/job/job_task_item.dart';
|
||
import 'package:marking_app/pages/common/event_bus_mixin.dart';
|
||
import 'package:marking_app/pages/home/hooks/use_marking_statistics.dart';
|
||
import 'package:marking_app/pages/homework_correction/components/new_version_of_homework/homework_tasks_view_item.dart';
|
||
import 'package:marking_app/provider/review_provider.dart';
|
||
import 'package:marking_app/routes/RouterManager.dart';
|
||
import 'package:marking_app/utils/easy_refresh/mixin/refresh_data_handle.dart';
|
||
import 'package:marking_app/utils/index.dart';
|
||
import 'package:marking_app/utils/request/rest_client.dart';
|
||
import 'package:marking_app/common/model/common/base_page_data.dart';
|
||
import 'package:marking_app/common/model/marking/marking_item.dart';
|
||
import 'package:marking_app/common/model/marking/marking_list_params.dart';
|
||
import 'package:marking_app/components/TestPaperItem.dart';
|
||
import 'package:marking_app/provider/user_provider.dart';
|
||
|
||
import 'package:marking_app/utils/easy_refresh/MyEmptyWidget.dart';
|
||
|
||
part 'index.g.dart';
|
||
|
||
class TheHomePage extends StatefulHookConsumerWidget {
|
||
const TheHomePage({Key? key}) : super(key: key);
|
||
|
||
@override
|
||
TheHomePageState createState() => TheHomePageState();
|
||
}
|
||
|
||
class TheHomePageState extends ConsumerState<TheHomePage>
|
||
with
|
||
CommonMixin,
|
||
EventBusMixin<HomeMarkingStatistics>,
|
||
SingleTickerProviderStateMixin,
|
||
RefreshDataHandle<dynamic, MarkingListParams>,
|
||
AutomaticKeepAliveClientMixin {
|
||
@override
|
||
bool get wantKeepAlive => true;
|
||
|
||
/* Tab控制器 */
|
||
late TabController _tabController;
|
||
int _tabIndex = 0;
|
||
bool completedToRefresh = true;
|
||
|
||
/* 阅卷 */
|
||
bool markingRequesting = false; // 是否正在请求中
|
||
late final EasyRefreshController _refreshController1;
|
||
MarkingListParams params1 = MarkingListParams(
|
||
isFinish: false,
|
||
page: RequestConfig.basePage.page,
|
||
// limit: RequestConfig.basePage.limit,
|
||
limit: 5, pageType: 0,
|
||
);
|
||
List<MarkingItem> markingDatas1 = [];
|
||
int totalMarkNumber = 0;
|
||
RemoveListener? _currentTaskIdListener;
|
||
|
||
/* 作业 */
|
||
late final EasyRefreshController _refreshController2;
|
||
MarkingListParams params2 = MarkingListParams(
|
||
isFinish: false,
|
||
page: RequestConfig.basePage.page,
|
||
limit: RequestConfig.basePage.limit,
|
||
pageType: 0,
|
||
);
|
||
List<JobTaskItem> markingDatas2 = [];
|
||
int totalJobNumber = 0;
|
||
|
||
@override
|
||
void initState() {
|
||
_tabController = TabController(initialIndex: _tabIndex, length: 2, vsync: this);
|
||
_refreshController1 = EasyRefreshController();
|
||
_refreshController2 = EasyRefreshController();
|
||
|
||
Future.delayed(Duration.zero, () {
|
||
//在这里处理页面
|
||
_currentTaskIdListener = ref.read(currentTaskIdProvider.notifier).addListener((state) {
|
||
int? taskId = state.taskId;
|
||
if (taskId != null && state.refresh) {
|
||
_refreshController1.callRefresh();
|
||
}
|
||
});
|
||
});
|
||
super.initState();
|
||
}
|
||
|
||
@override
|
||
void dispose() {
|
||
// ref.read(currentTaskIdProvider.notifier).clean();
|
||
if (_currentTaskIdListener != null) {
|
||
_currentTaskIdListener!();
|
||
}
|
||
eventCancel();
|
||
_tabController.dispose();
|
||
_refreshController1.dispose();
|
||
_refreshController2.dispose();
|
||
super.dispose();
|
||
}
|
||
|
||
/* 发起请求 => 作业 */
|
||
Future<void> toGetPageDataForWork({bool isReFresh = false}) async {
|
||
if (!isReFresh) {
|
||
params2.page++;
|
||
}
|
||
RestClient client = await getClient();
|
||
BasePageData<JobTaskItem>? results = await toRefreshData(
|
||
_refreshController2,
|
||
api: client.getJobsByPage,
|
||
params: params2,
|
||
isReFresh: isReFresh,
|
||
context: context,
|
||
);
|
||
if (results != null) {
|
||
if (isReFresh) {
|
||
markingDatas2.clear();
|
||
setState(() {
|
||
totalJobNumber = results.total;
|
||
markingDatas2 = results.items;
|
||
});
|
||
} else {
|
||
setState(() {
|
||
totalJobNumber = results.total;
|
||
markingDatas2.addAll(results.items);
|
||
});
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 发起请求 => 阅卷 */
|
||
Future<void> toGetPageDataForMarking({bool isReFresh = false}) async {
|
||
markingRequesting = true;
|
||
try {
|
||
if (!isReFresh) {
|
||
params1.page++;
|
||
}
|
||
RestClient client = await getClient();
|
||
BasePageData<MarkingItem>? results = await toRefreshData(
|
||
_refreshController1,
|
||
api: client.getMarkingsByPage,
|
||
params: params1,
|
||
isReFresh: isReFresh,
|
||
context: context,
|
||
);
|
||
if (results != null) {
|
||
eventFire(model: HomeMarkingStatistics());
|
||
if (isReFresh) {
|
||
markingDatas1.clear();
|
||
totalMarkNumber = results.total;
|
||
|
||
// NORMAL, // 正常
|
||
// ARBITRATE, // 仲裁
|
||
// EXCEPTIONAL, // 异常
|
||
int pageType = params1.pageType;
|
||
markingDatas1 = results.items;
|
||
setState(() {});
|
||
} else {
|
||
setState(() {
|
||
totalMarkNumber = results.total;
|
||
markingDatas1.addAll(results.items);
|
||
});
|
||
}
|
||
}
|
||
} catch (e) {
|
||
} finally {
|
||
markingRequesting = false;
|
||
}
|
||
}
|
||
|
||
@override
|
||
Widget build(BuildContext context) {
|
||
super.build(context); //调用super.build(返回值始终返回null,应将其忽略)
|
||
List<MarkingListType> markingTypes = MarkingListType.values;
|
||
return AnnotatedRegion(
|
||
value: const SystemUiOverlayStyle(
|
||
systemNavigationBarColor: Color(0xFF000000),
|
||
systemNavigationBarDividerColor: null,
|
||
statusBarColor: Colors.transparent,
|
||
systemNavigationBarIconBrightness: Brightness.light,
|
||
statusBarIconBrightness: Brightness.dark,
|
||
statusBarBrightness: Brightness.light,
|
||
),
|
||
child: Scaffold(
|
||
backgroundColor: Color.fromRGBO(249, 250, 254, 1),
|
||
body: Column(
|
||
children: [
|
||
TopUserInfo(),
|
||
$TheTabBar(
|
||
controller: _tabController,
|
||
onTap: (int val) {
|
||
setState(() {
|
||
_tabIndex = val;
|
||
if (val == 1 && completedToRefresh) {
|
||
_refreshController2.callRefresh();
|
||
completedToRefresh = false;
|
||
}
|
||
});
|
||
},
|
||
),
|
||
SizedBox(height: 10.h),
|
||
MarkingStatisticsBox(
|
||
controller: _refreshController1,
|
||
isShow: _tabIndex != 0,
|
||
params: params1,
|
||
markingRequesting: markingRequesting,
|
||
),
|
||
SizedBox(height: 4.h),
|
||
Expanded(
|
||
child: IndexedStack(
|
||
index: _tabIndex,
|
||
children: <Widget>[
|
||
EasyRefresh(
|
||
firstRefresh: true,
|
||
taskIndependence: true,
|
||
enableControlFinishLoad: true,
|
||
enableControlFinishRefresh: true,
|
||
emptyWidget: markingDatas1.isEmpty ? const MyEmptyWidget() : null,
|
||
controller: _refreshController1,
|
||
header: MaterialHeader(),
|
||
footer: TaurusFooter(),
|
||
child: ListView.builder(
|
||
padding: EdgeInsets.only(top: 4.h, bottom: 10.h),
|
||
itemBuilder: (context, index) {
|
||
return TestPaperItem(
|
||
markingItem: markingDatas1[index],
|
||
markingtype: markingTypes[params1.pageType],
|
||
call: () {
|
||
_refreshController1.callRefresh();
|
||
},
|
||
);
|
||
},
|
||
itemCount: markingDatas1.length,
|
||
),
|
||
onRefresh: () => toGetPageDataForMarking(isReFresh: true),
|
||
onLoad: () => toGetPageDataForMarking(isReFresh: false),
|
||
),
|
||
EasyRefresh(
|
||
firstRefresh: false,
|
||
taskIndependence: true,
|
||
enableControlFinishLoad: true,
|
||
enableControlFinishRefresh: true,
|
||
emptyWidget: markingDatas2.isEmpty ? const MyEmptyWidget() : null,
|
||
controller: _refreshController2,
|
||
header: MaterialHeader(),
|
||
footer: TaurusFooter(),
|
||
child: ListView.builder(
|
||
padding: EdgeInsets.only(top: 4.h, bottom: 10.h, left: 12.w, right: 12.w),
|
||
itemBuilder: (context, index) => HomeworkTasksViewItem(
|
||
completed: false,
|
||
jobTaskItem: markingDatas2[index],
|
||
call: () => _refreshController2.callRefresh(),
|
||
),
|
||
itemCount: markingDatas2.length,
|
||
),
|
||
onRefresh: () => toGetPageDataForWork(isReFresh: true),
|
||
onLoad: () => toGetPageDataForWork(isReFresh: false),
|
||
),
|
||
],
|
||
),
|
||
)
|
||
],
|
||
)),
|
||
);
|
||
}
|
||
}
|
||
|
||
class TopUserInfo extends ConsumerWidget {
|
||
const TopUserInfo({super.key});
|
||
|
||
@override
|
||
Widget build(BuildContext context, WidgetRef ref) {
|
||
final userState = ref.watch(userProvider);
|
||
|
||
return InkWell(
|
||
onTap: () {
|
||
RouterManager.router.navigateTo(context, RouterManager.userMinePath, transition: getTransition());
|
||
},
|
||
child: 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(
|
||
children: [
|
||
Container(
|
||
decoration: BoxDecoration(
|
||
color: Color.fromRGBO(245, 246, 251, 1),
|
||
borderRadius: BorderRadius.circular(30.r),
|
||
),
|
||
child: Row(
|
||
mainAxisSize: MainAxisSize.min,
|
||
crossAxisAlignment: CrossAxisAlignment.center,
|
||
children: [
|
||
ClipRRect(
|
||
borderRadius: BorderRadius.circular(50.w),
|
||
child: Container(
|
||
alignment: Alignment.center,
|
||
color: Color.fromRGBO(163, 211, 255, 1),
|
||
padding: EdgeInsets.all(1.r),
|
||
child: Image.asset('assets/images/logo.png', width: 32.w, height: 32.w),
|
||
),
|
||
),
|
||
Container(
|
||
margin: EdgeInsets.only(left: 10.h),
|
||
child: Text(
|
||
userState.userName,
|
||
style: TextStyle(fontSize: 15.sp, color: const Color.fromRGBO(45, 56, 76, 0.9)),
|
||
),
|
||
),
|
||
Container(
|
||
padding: EdgeInsets.symmetric(horizontal: 4.w),
|
||
child: Icon(
|
||
Icons.arrow_forward_ios_rounded,
|
||
size: 12.sp,
|
||
color: const Color.fromRGBO(45, 56, 76, 0.9),
|
||
),
|
||
),
|
||
SizedBox(width: 5.w)
|
||
],
|
||
),
|
||
),
|
||
Expanded(child: SizedBox())
|
||
],
|
||
),
|
||
),
|
||
);
|
||
}
|
||
}
|
||
|
||
@swidget
|
||
Widget $theTabBar({required TabController controller, ValueChanged<int>? onTap}) {
|
||
return Container(
|
||
alignment: Alignment.centerLeft,
|
||
height: 38.h,
|
||
child: TabBar(
|
||
controller: controller,
|
||
unselectedLabelStyle: TextStyle(fontSize: 17.sp, color: const Color.fromRGBO(45, 56, 76, 1)),
|
||
labelStyle: TextStyle(
|
||
fontSize: 16.sp,
|
||
fontWeight: FontWeight.bold,
|
||
color: const Color.fromRGBO(148, 163, 182, 1),
|
||
),
|
||
isScrollable: true,
|
||
labelColor: const Color.fromRGBO(45, 56, 76, 1),
|
||
indicatorSize: TabBarIndicatorSize.label, // 设置指示器高度和标签一样高
|
||
// labelPadding: EdgeInsets.symmetric(vertical: 0), // 设置标签的内边距
|
||
// background: linear-gradient(270deg, #2E5BFF 30.23%, rgba(46, 91, 255, 0.00) 96.59%);
|
||
// indicatorColor: RectangleIndicator(),
|
||
// indicator: BoxDecoration(
|
||
// gradient: LinearGradient(
|
||
// begin: Alignment.centerLeft,
|
||
// end: Alignment.centerRight,
|
||
// colors: [
|
||
// Color.fromRGBO(46, 91, 255, 0.00),
|
||
// Color(0xFF2E5BFF),
|
||
// ],
|
||
// stops: [0.3023, 0.9659],
|
||
// // transform: GradientRotation(3.14 / 2), //将270度转换为弧度
|
||
// ),
|
||
// ),
|
||
// indicator: BoxDecoration(
|
||
// // 设置指示器样式
|
||
// gradient: LinearGradient(
|
||
// colors: [Colors.yellow, Colors.green], // 设置渐变色
|
||
// begin: Alignment.centerLeft,
|
||
// end: Alignment.centerRight,
|
||
// ),
|
||
// ),
|
||
onTap: onTap,
|
||
tabs: const <Widget>[Tab(text: '阅卷'), Tab(text: '作业')],
|
||
),
|
||
);
|
||
}
|
||
|
||
class MarkingStatisticsBox extends HookWidget with EventBusMixin<HomeMarkingStatistics> {
|
||
bool isShow;
|
||
MarkingListParams params;
|
||
EasyRefreshController controller;
|
||
bool markingRequesting;
|
||
|
||
MarkingStatisticsBox(
|
||
{required this.controller, required this.params, required this.isShow, required this.markingRequesting});
|
||
|
||
@override
|
||
Widget build(BuildContext context) {
|
||
UseMarkingStatistics _useTypesOf = UseMarkingStatistics.use(pageType: params.pageType);
|
||
MarkingListType _currentType = _useTypesOf.currentType.value;
|
||
Map<MarkingListType, int> _statisticMap = _useTypesOf.statistics.value;
|
||
|
||
useEffect(() {
|
||
eventOn(callback: (HomeMarkingStatistics e) {
|
||
_useTypesOf.getData();
|
||
});
|
||
return () {
|
||
eventCancel();
|
||
};
|
||
}, []);
|
||
return Offstage(
|
||
offstage: isShow,
|
||
child: Container(
|
||
padding: EdgeInsets.only(left: 14.w, top: 4.h),
|
||
width: double.infinity,
|
||
alignment: Alignment.center,
|
||
child: Row(
|
||
mainAxisAlignment: MainAxisAlignment.start,
|
||
children: _useTypesOf.theTypes.map((e) {
|
||
bool isCurrent = _currentType == e;
|
||
int? total = _statisticMap[e];
|
||
|
||
// if (total == null && e != MarkingListType.NORMAL) return Container();
|
||
return GestureDetector(
|
||
onTap: () => easyThrottle('typeOfCall', () {
|
||
if (markingRequesting) return;
|
||
controller.callRefresh(duration: Duration(milliseconds: 101));
|
||
_useTypesOf.currentType.value = e;
|
||
params.pageType = e.index;
|
||
// _useTypesOf.setType(controller: controller, params: params);
|
||
}, duration: Duration(milliseconds: 2000)),
|
||
child: Container(
|
||
padding: EdgeInsets.symmetric(horizontal: 8.w, vertical: 4.h),
|
||
margin: EdgeInsets.only(right: 20.w),
|
||
decoration: !isCurrent
|
||
? BoxDecoration(
|
||
borderRadius: BorderRadius.all(Radius.circular(3.r)),
|
||
color: Color.fromRGBO(46, 91, 255, 0.05),
|
||
)
|
||
: BoxDecoration(
|
||
borderRadius: BorderRadius.all(Radius.circular(3.r)),
|
||
color: Color.fromRGBO(46, 91, 255, 0.05),
|
||
boxShadow: [
|
||
BoxShadow(
|
||
color: Color.fromRGBO(46, 91, 255, 0.1),
|
||
blurRadius: 4,
|
||
spreadRadius: 0,
|
||
offset: Offset(0, 0),
|
||
),
|
||
],
|
||
),
|
||
child: Text(
|
||
_useTypesOf.typeNames[e.index] + (total == null || total <= 0 ? '' : '($total)'),
|
||
style: TextStyle(
|
||
color: isCurrent ? Color.fromRGBO(46, 56, 76, 1) : Color.fromRGBO(80, 87, 103, 1),
|
||
fontSize: isCurrent ? 14.sp : 13.sp),
|
||
),
|
||
),
|
||
);
|
||
}).toList(),
|
||
),
|
||
),
|
||
);
|
||
}
|
||
}
|