/* * @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 with CommonMixin, EventBusMixin, SingleTickerProviderStateMixin, RefreshDataHandle, 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 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 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 toGetPageDataForWork({bool isReFresh = false}) async { if (!isReFresh) { params2.page++; } RestClient client = await getClient(); BasePageData? 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 toGetPageDataForMarking({bool isReFresh = false}) async { markingRequesting = true; try { if (!isReFresh) { params1.page++; } RestClient client = await getClient(); BasePageData? 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 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: [ 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? 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, // 设置指示器高度和标签一样高 onTap: onTap, tabs: const [Tab(text: '阅卷'), Tab(text: '作业')], ), ); } class MarkingStatisticsBox extends HookWidget with EventBusMixin { 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 _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(), ), ), ); } }