diff --git a/marking_app/ios/Podfile b/marking_app/ios/Podfile index 256af1a..88eba40 100644 --- a/marking_app/ios/Podfile +++ b/marking_app/ios/Podfile @@ -1,6 +1,6 @@ # Uncomment this line to define a global platform for your project # source 'https://mirrors.tuna.tsinghua.edu.cn/git/CocoaPods/Specs.git' -platform :ios, '11.0' +platform :ios, '12.0' # CocoaPods analytics sends network stats synchronously affecting flutter build latency. ENV['COCOAPODS_DISABLE_STATS'] = 'true' diff --git a/marking_app/ios/Podfile.lock b/marking_app/ios/Podfile.lock index 7dc149b..6180e2f 100644 --- a/marking_app/ios/Podfile.lock +++ b/marking_app/ios/Podfile.lock @@ -8,9 +8,6 @@ PODS: - fluttertoast (0.0.2): - Flutter - Toast - - FMDB (2.7.5): - - FMDB/standard (= 2.7.5) - - FMDB/standard (2.7.5) - image_picker_ios (0.0.1): - Flutter - install_plugin (2.0.0): @@ -30,7 +27,7 @@ PODS: - FlutterMacOS - sqflite (0.0.3): - Flutter - - FMDB (>= 2.7.5) + - FlutterMacOS - Toast (4.0.0) - url_launcher_ios (0.0.1): - Flutter @@ -51,14 +48,13 @@ DEPENDENCIES: - permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`) - rive_common (from `.symlinks/plugins/rive_common/ios`) - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`) - - sqflite (from `.symlinks/plugins/sqflite/ios`) + - sqflite (from `.symlinks/plugins/sqflite/darwin`) - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) - wakelock (from `.symlinks/plugins/wakelock/ios`) - webview_flutter_wkwebview (from `.symlinks/plugins/webview_flutter_wkwebview/ios`) SPEC REPOS: trunk: - - FMDB - ReachabilitySwift - Toast @@ -86,7 +82,7 @@ EXTERNAL SOURCES: shared_preferences_foundation: :path: ".symlinks/plugins/shared_preferences_foundation/darwin" sqflite: - :path: ".symlinks/plugins/sqflite/ios" + :path: ".symlinks/plugins/sqflite/darwin" url_launcher_ios: :path: ".symlinks/plugins/url_launcher_ios/ios" wakelock: @@ -99,21 +95,20 @@ SPEC CHECKSUMS: Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 flutter_keyboard_visibility: 0339d06371254c3eb25eeb90ba8d17dca8f9c069 fluttertoast: fafc4fa4d01a6a9e4f772ecd190ffa525e9e2d9c - FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a - image_picker_ios: 4a8aadfbb6dc30ad5141a2ce3832af9214a705b5 + image_picker_ios: 99dfe1854b4fa34d0364e74a78448a0151025425 install_plugin: b52f81470a1f37b006607bdf7ffc6031df43fe76 package_info: 873975fc26034f0b863a300ad47e7f1ac6c7ec62 - path_provider_foundation: 29f094ae23ebbca9d3d0cec13889cd9060c0e943 + path_provider_foundation: 3784922295ac71e43754bd15e0653ccfd36a147c permission_handler_apple: e76247795d700c14ea09e3a2d8855d41ee80a2e6 ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825 - rive_common: 8a159d68033a8b073e5853acc50f03aa486a2888 - shared_preferences_foundation: 5b919d13b803cadd15ed2dc053125c68730e5126 - sqflite: 31f7eba61e3074736dff8807a9b41581e4f7f15a + rive_common: 3a4c254c6e4db7e4b9e05daeb3d1f47ae4f7bf76 + shared_preferences_foundation: b4c3b4cddf1c21f02770737f147a3f5da9d39695 + sqflite: 673a0e54cc04b7d6dba8d24fb8095b31c3a99eec Toast: 91b396c56ee72a5790816f40d3a94dd357abc196 - url_launcher_ios: bf5ce03e0e2088bad9cc378ea97fa0ed5b49673b + url_launcher_ios: bbd758c6e7f9fd7b5b1d4cde34d2b95fcce5e812 wakelock: d0fc7c864128eac40eba1617cb5264d9c940b46f - webview_flutter_wkwebview: 2e2d318f21a5e036e2c3f26171342e95908bd60a + webview_flutter_wkwebview: 4f3e50f7273d31e5500066ed267e3ae4309c5ae4 -PODFILE CHECKSUM: 441579d1897b785684860026b910c66dadea2938 +PODFILE CHECKSUM: 64629b724b9886c2d78e6972ff5ef90e370df047 COCOAPODS: 1.11.3 diff --git a/marking_app/ios/Runner.xcodeproj/project.pbxproj b/marking_app/ios/Runner.xcodeproj/project.pbxproj index e744389..52a3f5e 100644 --- a/marking_app/ios/Runner.xcodeproj/project.pbxproj +++ b/marking_app/ios/Runner.xcodeproj/project.pbxproj @@ -334,7 +334,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; @@ -351,7 +351,7 @@ ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = ""; CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = 15; + CURRENT_PROJECT_VERSION = 16; DEVELOPMENT_TEAM = CYDU583KN6; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; @@ -359,7 +359,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.93; + MARKETING_VERSION = 1.0.96; PRODUCT_BUNDLE_IDENTIFIER = com.example.markingApp; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; @@ -419,7 +419,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -468,7 +468,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; @@ -487,7 +487,7 @@ ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = ""; CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = 15; + CURRENT_PROJECT_VERSION = 16; DEVELOPMENT_TEAM = CYDU583KN6; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; @@ -495,7 +495,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.93; + MARKETING_VERSION = 1.0.96; PRODUCT_BUNDLE_IDENTIFIER = com.example.markingApp; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; @@ -517,7 +517,7 @@ ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = ""; CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = 15; + CURRENT_PROJECT_VERSION = 16; DEVELOPMENT_TEAM = CYDU583KN6; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; @@ -525,7 +525,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.93; + MARKETING_VERSION = 1.0.96; PRODUCT_BUNDLE_IDENTIFIER = com.example.markingApp; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; diff --git a/marking_app/lib/common/model/job/job_collect_params.dart b/marking_app/lib/common/model/job/job_collect_params.dart index 3ec0fa6..f5d80af 100644 --- a/marking_app/lib/common/model/job/job_collect_params.dart +++ b/marking_app/lib/common/model/job/job_collect_params.dart @@ -4,6 +4,9 @@ part 'job_collect_params.g.dart'; @JsonSerializable() class JobCollectParams extends Object { + @JsonKey(name: 'paperId') + int paperId; + @JsonKey(name: 'taskId') int taskId; @@ -14,6 +17,7 @@ class JobCollectParams extends Object { bool isCollect; JobCollectParams( + this.paperId, this.taskId, this.studentId, this.isCollect, diff --git a/marking_app/lib/pages/homework_correction/components/new_version_of_homework/favorite_widget.dart b/marking_app/lib/pages/homework_correction/components/new_version_of_homework/favorite_widget.dart index 73f3491..43bef8a 100644 --- a/marking_app/lib/pages/homework_correction/components/new_version_of_homework/favorite_widget.dart +++ b/marking_app/lib/pages/homework_correction/components/new_version_of_homework/favorite_widget.dart @@ -19,12 +19,13 @@ class FavoriteWidget extends StatefulWidget { class _FavoriteState extends State with EventBusMixin, CommonMixin { Future? _future; // 考试试卷 - + JobQuestionsSwitch? _eventModel; @override void initState() { super.initState(); eventOn(callback: (JobQuestionsSwitch eventModel) { - _future = getData(eventModel.taskId, eventModel.studentId); + _eventModel = eventModel; + _future = getData(eventModel.taskId, eventModel.studentId, eventModel.paperId); toUpState(setState, () {}, mounted); }); } @@ -35,11 +36,11 @@ class _FavoriteState extends State with EventBusMixin getData(int taskId, int studentId) async { + Future getData(int taskId, int studentId, int paperId) async { try { RestClient _client = await getClient(); BaseStructureResult res = await _client.getJobCollect(taskId, studentId); - if (res.success) return JobCollectParams(taskId, studentId, res.data ?? false); + if (res.success) return JobCollectParams(paperId, taskId, studentId, res.data ?? false); } catch (e) {} return null; @@ -47,12 +48,14 @@ class _FavoriteState extends State with EventBusMixin toFavorite(JobCollectParams favoriteVal) async { try { + if (_eventModel?.paperId == null) return; ToastUtils.showLoading(); RestClient _client = await getClient(); favoriteVal.isCollect = !favoriteVal.isCollect; + favoriteVal.paperId = _eventModel!.paperId; BaseStructureResult res = await _client.toJobFavoriteCancel(favoriteVal); if (res.success) { - _future = getData(favoriteVal.taskId, favoriteVal.studentId); + _future = getData(favoriteVal.taskId, favoriteVal.studentId, _eventModel!.paperId); toUpState(setState, () {}, mounted); } else { ToastUtils.showError(res.message ?? '操作失败,请重试'); @@ -97,6 +100,7 @@ class _FavoriteState extends State with EventBusMixin { exitCallback: () => Navigator.of(context).pop(refresh), ), SizedBox(height: 1.h), - Expanded(child: ExamPaperAndScoringView(taskId: taskId)), + Expanded(child: ExamPaperAndScoringView(taskId: taskId, className: className)), $BottomOperationBar() ], ), @@ -108,7 +109,17 @@ class DoPapersJob extends HookWidget with EventBusMixin { class ReviewStatusInfo extends HookWidget with CommonMixin { final int taskId; final int pageIndex; - const ReviewStatusInfo({required this.taskId, required this.pageIndex, super.key}); + // final int schoolId; + // final int gradeId; + final String className; + const ReviewStatusInfo({ + required this.taskId, + required this.pageIndex, + // required this.schoolId, + // required this.gradeId, + required this.className, + super.key, + }); Future getData() async { var _client = await getClient(); @@ -116,6 +127,21 @@ class ReviewStatusInfo extends HookWidget with CommonMixin { return result.data; } + /// 获取未提交 + Future?> getStudents() async { + try { + ToastUtils.showLoading(); + var _client = await getClient(); + var _result = await _client + .getJobWithStudents(JobConcernedWithStudentParams([taskId], isCommit: false, pageIndex: pageIndex)); + if (_result.success) return _result.data; + } catch (e) { + ToastUtils.showError('获取数据失败,请重试'); + } finally { + ToastUtils.dismiss(); + } + } + @override Widget build(BuildContext context) { var doMarkingInfo = useState(null); @@ -125,17 +151,77 @@ class ReviewStatusInfo extends HookWidget with CommonMixin { }, []); if (doMarkingInfo.value == null) return Container(); - return Container( - child: Row( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - quickText('已阅', color: Color.fromRGBO(117, 117, 117, 1), size: 10.sp), - quickText(doMarkingInfo.value!.finishCount, - color: Color.fromRGBO(76, 199, 147, 1), size: 12.sp, fontWeight: FontWeight.bold), - quickText('/', color: Color.fromRGBO(117, 117, 117, 1), size: 12.sp), - quickText(doMarkingInfo.value!.surplusNo, color: Color.fromRGBO(117, 117, 117, 1), size: 10.sp), - ], + return InkWell( + onTap: () async { + print('点击了...'); + List? students = await getStudents(); + if (students == null) return; + showModalBottomSheet( + context: context, + elevation: 10, + backgroundColor: Colors.white, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.only( + topLeft: Radius.circular(10.r), + topRight: Radius.circular(10.r), + ), + ), + builder: (BuildContext context) { + return Padding( + padding: EdgeInsets.symmetric(horizontal: 2.w), + child: Column( + children: [ + Container( + margin: EdgeInsets.only(top: 14.h), + child: quickText( + '当前页未提交学生名单', + size: 15.sp, + fontWeight: FontWeight.bold, + color: Color.fromRGBO(60, 60, 60, 1), + ), + ), + SizedBox(height: 10.h), + Expanded( + child: ListView( + padding: EdgeInsets.symmetric(vertical: 8.h, horizontal: 4.w), + children: [ + Wrap( + spacing: 6.0, // 主轴(水平)方向间距 + runSpacing: 4.0, // 纵轴(垂直)方向间距 + alignment: WrapAlignment.spaceAround, //沿主轴方向居中 + children: students.map((e) { + return Chip( + backgroundColor: Color.fromRGBO(239, 242, 255, 1), + avatar: CircleAvatar( + backgroundColor: Colors.white, + child: quickText(e.studentName.substring(0, 1), + size: 12.sp, color: Theme.of(context).primaryColor), + ), + label: quickText(e.studentName, color: Color.fromRGBO(80, 94, 110, 1), size: 12.sp), + ); + }).toList(), + ), + ], + ), + ) + ], + ), + ); + }, + ); + }, + child: Container( + child: Row( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + quickText('已阅', color: Color.fromRGBO(117, 117, 117, 1), size: 10.sp), + quickText(doMarkingInfo.value!.finishCount, + color: Color.fromRGBO(76, 199, 147, 1), size: 12.sp, fontWeight: FontWeight.bold), + quickText('/', color: Color.fromRGBO(117, 117, 117, 1), size: 12.sp), + quickText(doMarkingInfo.value!.surplusNo, color: Color.fromRGBO(117, 117, 117, 1), size: 10.sp), + ], + ), ), ); } @@ -381,7 +467,8 @@ Widget $dropdownBoxSwitchStudentsOrTypeView(BuildContext context, // 试卷和打分键盘栏 class ExamPaperAndScoringView extends StatefulHookConsumerWidget { final int taskId; - const ExamPaperAndScoringView({required this.taskId, super.key}); + final String className; + const ExamPaperAndScoringView({required this.taskId, required this.className, super.key}); @override _EexamPaperAndScoringViewState createState() => _EexamPaperAndScoringViewState(); @@ -444,7 +531,7 @@ class _EexamPaperAndScoringViewState extends ConsumerState _useDoScoring.goToScoringShortcut( - scoring: ScoringMethodEnum.CORRECT, - questionNo: question.questionNo, - ), + onTap: () { + _useDoScoring.goToScoringShortcut( + scoring: ScoringMethodEnum.CORRECT, + questionNo: question.questionNo, + ); + var noAnswerQuestion = + _useDoScoring.submittedData.value.questions.firstWhereOrNull((e) => e.score == null); + if (noAnswerQuestion == null) toSubmit(); + }, child: Container( padding: EdgeInsets.symmetric(vertical: 12.r), alignment: Alignment.center, @@ -736,10 +834,15 @@ Widget $examPaperAndScoringKeyboardView( SizedBox(width: 0.2.w), Expanded( child: $MaterialBtn( - onTap: () => _useDoScoring.goToScoringShortcut( - scoring: ScoringMethodEnum.CORRECT_HALF, - questionNo: question.questionNo, - ), + onTap: () { + _useDoScoring.goToScoringShortcut( + scoring: ScoringMethodEnum.CORRECT_HALF, + questionNo: question.questionNo, + ); + var noAnswerQuestion = + _useDoScoring.submittedData.value.questions.firstWhereOrNull((e) => e.score == null); + if (noAnswerQuestion == null) toSubmit(); + }, bgc: Color.fromRGBO(237, 237, 237, 1), child: Container( padding: EdgeInsets.symmetric(vertical: 12.r), @@ -758,10 +861,15 @@ Widget $examPaperAndScoringKeyboardView( SizedBox(width: 0.2.w), Expanded( child: $MaterialBtn( - onTap: () => _useDoScoring.goToScoringShortcut( - scoring: ScoringMethodEnum.WRONG, - questionNo: question.questionNo, - ), + onTap: () { + _useDoScoring.goToScoringShortcut( + scoring: ScoringMethodEnum.WRONG, + questionNo: question.questionNo, + ); + var noAnswerQuestion = + _useDoScoring.submittedData.value.questions.firstWhereOrNull((e) => e.score == null); + if (noAnswerQuestion == null) toSubmit(); + }, bgc: Color.fromRGBO(237, 237, 237, 1), child: Container( padding: EdgeInsets.symmetric(vertical: 12.r), @@ -787,6 +895,7 @@ Widget $examPaperAndScoringKeyboardView( }, ), ), + SizedBox(height: 3.h), Container( child: Column( mainAxisSize: MainAxisSize.min, @@ -865,7 +974,7 @@ Widget $examPaperAndScoringKeyboardView( ), ), ), - SizedBox(height: 36.h), + SizedBox(height: 26.h), ], ), ),