diff --git a/making_school_asignment_app/lib/common/utils/app_upgrade/upgradeLogic.dart b/making_school_asignment_app/lib/common/utils/app_upgrade/upgradeLogic.dart index b3fd7a5..34ab6aa 100644 --- a/making_school_asignment_app/lib/common/utils/app_upgrade/upgradeLogic.dart +++ b/making_school_asignment_app/lib/common/utils/app_upgrade/upgradeLogic.dart @@ -23,19 +23,80 @@ class UpgradeLogic extends GetxController with RequestToolMixin { // super.onInit(); // } + Future getUpdateAppEvent() async { + // 获取设备信息 + String deviceInfo; + int deviceType; + if (Platform.isAndroid) { + deviceInfo = "android"; + deviceType = 1; + } else if (Platform.isIOS) { + deviceInfo = "ios"; + deviceType = 2; + } else if (Platform.isWindows) { + deviceInfo = "windows"; + deviceType = 3; + } else { + return null; + } + + AppVersion? result = await getClient().getLastAppVersion('making_school_asignment_app', deviceType); + if (result == null) return null; + + //获取当前版本 + PackageInfo packageInfo = await PackageInfo.fromPlatform(); + //获取当前版本 + String localVersion = packageInfo.version; + String appName = packageInfo.appName; //应用名称 + String packageName = packageInfo.packageName; //包名称 + // String buildNumber = packageInfo.buildNumber; //小版本号 + + Map json = { + 'downloadPath': Platform.isWindows ? '' : result.appFileUrl, + 'version': result.version, + 'systemType': deviceType, + 'description': result.description ?? 'APP新版本更新', + }; + return UpdateAppEvent.fromJson(json, localVersion, deviceInfo, appName, packageName, typeName: 'systemType'); + } + Future getAppUpgrade(BuildContext context) async { if (!const bool.fromEnvironment('dart.vm.product')) return; try { showUpgrade.value = true; - + final names = [ UserStore.to.userDetailInfo.value?.name, UserStore.to.userDetailInfo.value?.account, ].whereType().where((name) => name.isNotEmpty).toList(); - if (names.contains('AppleTester')) return; + UpdateAppEvent? updateAppEvent = await getUpdateAppEvent(); + if (updateAppEvent != null && updateAppEvent.upgrade) { + if (Platform.isAndroid) { + DeviceInfoPlugin deviceInfoPlugin = DeviceInfoPlugin(); + AndroidDeviceInfo androidInfo = await deviceInfoPlugin.androidInfo; + Permission storagePermission; + if (androidInfo.version.sdkInt >= 33) { + storagePermission = Permission.manageExternalStorage; + } else { + storagePermission = Permission.storage; + } + await PermissionDescribeUtil.instance.toLaunchPermissionRequest( + Get.context ?? context, + title: '储存权限请求', + describe: "为了提供更好的服务,需要获取到存储权限用于保存APP升级文件APK,进行升级", + permissions: [storagePermission], + ); + } + + await UpdateDialog.showUpdateDialog( + Get.context ?? context, + updateAppEvent, + ); + } + /** // 获取设备信息 String deviceInfo; int deviceType; @@ -49,11 +110,9 @@ class UpgradeLogic extends GetxController with RequestToolMixin { deviceInfo = "windows"; deviceType = 3; } else { - return; + return false; } - AppVersion? result = await getClient() - .getLastAppVersion('making_school_asignment_app', deviceType); if (result != null) { //获取当前版本 PackageInfo packageInfo = await PackageInfo.fromPlatform(); @@ -63,15 +122,8 @@ class UpgradeLogic extends GetxController with RequestToolMixin { String packageName = packageInfo.packageName; //包名称 // String buildNumber = packageInfo.buildNumber; //小版本号 - Map json = { - 'downloadPath': Platform.isWindows ? '' : result.appFileUrl, - 'version': result.version, - 'systemType': deviceType, - 'description': result.description ?? 'APP新版本更新' - }; - UpdateAppEvent updateAppEvent = UpdateAppEvent.fromJson( - json, localVersion, deviceInfo, appName, packageName, - typeName: 'systemType'); + Map json = {'downloadPath': Platform.isWindows ? '' : result.appFileUrl, 'version': result.version, 'systemType': deviceType, 'description': result.description ?? 'APP新版本更新'}; + UpdateAppEvent updateAppEvent = UpdateAppEvent.fromJson(json, localVersion, deviceInfo, appName, packageName, typeName: 'systemType'); if (updateAppEvent.upgrade) { if (Platform.isAndroid) { DeviceInfoPlugin deviceInfoPlugin = DeviceInfoPlugin(); @@ -96,6 +148,7 @@ class UpgradeLogic extends GetxController with RequestToolMixin { ); } } + */ } finally { showUpgrade.value = false; } diff --git a/making_school_asignment_app/lib/page/home_page/children/homework_review/components/question_number_view.dart b/making_school_asignment_app/lib/page/home_page/children/homework_review/components/question_number_view.dart index 419cee3..edaf173 100644 --- a/making_school_asignment_app/lib/page/home_page/children/homework_review/components/question_number_view.dart +++ b/making_school_asignment_app/lib/page/home_page/children/homework_review/components/question_number_view.dart @@ -8,6 +8,7 @@ import 'package:functional_widget_annotation/functional_widget_annotation.dart'; import 'package:making_school_asignment_app/common/job/marking_models/do_paper_details_result.dart'; import 'package:making_school_asignment_app/common/job/marking_models/do_test_questions_image_info.dart'; import 'package:making_school_asignment_app/common/utils/anti_shake_throttling.dart'; +import 'package:making_school_asignment_app/common/utils/toast_utils.dart'; import 'package:making_school_asignment_app/page/global_widget/my_text.dart'; import 'package:percent_indicator/linear_percent_indicator.dart'; @@ -100,7 +101,7 @@ Widget $questionNumberScrollView({ }); var listenVal = sateData.slide.listen((e) { if (sateData.panQuestView != null && sateData.panQuestView == true && e != scrollControllerNum.offset) { - print("进来了试题题号视图"); + // print("进来了试题题号视图"); scrollControllerNum.jumpTo(e); } }); @@ -166,7 +167,7 @@ Widget $scoringQuestionsView(BuildContext context, HomeworkReviewState sateData, // 校验是否自动提交 对于已经批阅过的试题 不重复自动提交 var annotateTime = logic.state.data.value?.annotateTime; if (annotateTime == null) { - var noRatingGiven = studentQuestions!.firstWhereOrNull((e) => e.studentScore == null); + var noRatingGiven = studentQuestions!.firstWhereOrNull((e) => e.useTime != 0 && e.studentScore == null); if (noRatingGiven == null) logic.submit(context); } } @@ -187,109 +188,120 @@ Widget $scoringQuestionsView(BuildContext context, HomeworkReviewState sateData, }, []); var padinVal = item.correctRate > 0 ? EdgeInsets.only(top: 6.4.h) : EdgeInsets.symmetric(vertical: 2.h); + Color buttonColor = item.useTime == 0 ? Colors.grey : const Color.fromRGBO(237, 237, 237, 1); // 当前题没有作答背景色置灰 return Container( height: item.height! * scaleRatio * initScale, padding: EdgeInsets.zero, - child: item.useTime == 0 - ? Container() - : Stack( - alignment: const FractionalOffset(0, 0), - children: [ - Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - // 对 - Expanded( - child: ElevatedButton( - style: ElevatedButton.styleFrom( - padding: EdgeInsets.zero, - tapTargetSize: MaterialTapTargetSize.shrinkWrap, - backgroundColor: const Color.fromRGBO(237, 237, 237, 1), // 设置背景色 - shape: const RoundedRectangleBorder(borderRadius: BorderRadius.zero), // 去除圆角 - ), - child: Padding( - padding: padinVal, - child: Icon( - size: 22.sp, - color: studentScore.value == 2 ? Colors.green : const Color.fromRGBO(114, 114, 114, 1), - const IconData(0xe62b, fontFamily: "AlibabaIcon"), - ), - ), - onPressed: () => easyThrottle('scoring_homework_questions', () { - studentScore.value = studentScore.value == 2 ? null : 2; - }, duration: const Duration(milliseconds: 222)), - ), - ), - // 半 - Expanded( - child: ElevatedButton( - style: ElevatedButton.styleFrom( - padding: EdgeInsets.zero, - tapTargetSize: MaterialTapTargetSize.shrinkWrap, - backgroundColor: const Color.fromRGBO(237, 237, 237, 1), // 设置背景色 - shape: const RoundedRectangleBorder(borderRadius: BorderRadius.zero), // 去除圆角 - ), - child: Padding( - padding: padinVal, - child: Icon( - size: 22.sp, - color: studentScore.value == 1 ? Colors.green : const Color.fromRGBO(114, 114, 114, 1), - const IconData(0xe62c, fontFamily: "AlibabaIcon"), - ), - ), - onPressed: () => easyThrottle('scoring_homework_questions', () { - studentScore.value = studentScore.value == 1 ? null : 1; - }, duration: const Duration(milliseconds: 222)), - ), - ), - // 错 - Expanded( - child: ElevatedButton( - style: ElevatedButton.styleFrom( - padding: EdgeInsets.zero, - tapTargetSize: MaterialTapTargetSize.shrinkWrap, - backgroundColor: const Color.fromRGBO(237, 237, 237, 1), // 设置背景色 - shape: const RoundedRectangleBorder(borderRadius: BorderRadius.zero), // 去除圆角 - ), - child: Padding( - padding: padinVal, - child: Icon( - size: 22.sp, - color: studentScore.value == 0 ? Colors.green : const Color.fromRGBO(114, 114, 114, 1), - const IconData(0xe62a, fontFamily: "AlibabaIcon"), - ), - ), - onPressed: () => easyThrottle('scoring_homework_questions', () { - studentScore.value = studentScore.value == 0 ? null : 0; - }, duration: const Duration(milliseconds: 222)), - ), - ), - ], - ), - IgnorePointer( - // 事件穿透 - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - SizedBox(width: 1.1.w), - quickText(item.questionNo, color: Theme.of(context).primaryColor.withOpacity(0.7), size: 8.sp), - if (item.correctRate > 0) quickText(' 正确率', color: Colors.grey, size: 5.sp), - if (item.correctRate > 0) - Expanded( - child: LinearPercentIndicator( - lineHeight: 6.h, - percent: item.correctRate / 100, - barRadius: Radius.circular(1.2.r), - alignment: MainAxisAlignment.center, - progressColor: Theme.of(context).primaryColor, - backgroundColor: const Color(0xFFB8C7CB).withOpacity(0.35), - center: quickText("${item.correctRate}%", size: 5.sp, align: TextAlign.center, color: Colors.white), - ), - ) - ], + child: Stack( + alignment: const FractionalOffset(0, 0), + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // 对 + Expanded( + child: ElevatedButton( + style: ElevatedButton.styleFrom( + padding: EdgeInsets.zero, + tapTargetSize: MaterialTapTargetSize.shrinkWrap, + backgroundColor: buttonColor, // 设置背景色 + shape: const RoundedRectangleBorder(borderRadius: BorderRadius.zero), // 去除圆角 ), + child: Padding( + padding: padinVal, + child: Icon( + size: 22.sp, + color: studentScore.value == 2 ? Colors.green : const Color.fromRGBO(114, 114, 114, 1), + const IconData(0xe62b, fontFamily: "AlibabaIcon"), + ), + ), + onPressed: () => easyThrottle('scoring_homework_questions', () { + if (item.useTime == 0) { + ToastUtils.showInfo("当前第${item.questionNo}题,学生未作答无需批阅此题"); + return; + } + studentScore.value = studentScore.value == 2 ? null : 2; + }, duration: const Duration(milliseconds: 222)), ), + ), + // 半 + Expanded( + child: ElevatedButton( + style: ElevatedButton.styleFrom( + padding: EdgeInsets.zero, + tapTargetSize: MaterialTapTargetSize.shrinkWrap, + backgroundColor: buttonColor, // 设置背景色 + shape: const RoundedRectangleBorder(borderRadius: BorderRadius.zero), // 去除圆角 + ), + child: Padding( + padding: padinVal, + child: Icon( + size: 22.sp, + color: studentScore.value == 1 ? Colors.green : const Color.fromRGBO(114, 114, 114, 1), + const IconData(0xe62c, fontFamily: "AlibabaIcon"), + ), + ), + onPressed: () => easyThrottle('scoring_homework_questions', () { + if (item.useTime == 0) { + ToastUtils.showInfo("当前第${item.questionNo}题,学生未作答无需批阅此题"); + return; + } + studentScore.value = studentScore.value == 1 ? null : 1; + }, duration: const Duration(milliseconds: 222)), + ), + ), + // 错 + Expanded( + child: ElevatedButton( + style: ElevatedButton.styleFrom( + padding: EdgeInsets.zero, + tapTargetSize: MaterialTapTargetSize.shrinkWrap, + backgroundColor: buttonColor, // 设置背景色 + shape: const RoundedRectangleBorder(borderRadius: BorderRadius.zero), // 去除圆角 + ), + child: Padding( + padding: padinVal, + child: Icon( + size: 22.sp, + color: studentScore.value == 0 ? Colors.green : const Color.fromRGBO(114, 114, 114, 1), + const IconData(0xe62a, fontFamily: "AlibabaIcon"), + ), + ), + onPressed: () => easyThrottle('scoring_homework_questions', () { + if (item.useTime == 0) { + ToastUtils.showInfo("当前第${item.questionNo}题,学生未作答无需批阅此题"); + return; + } + studentScore.value = studentScore.value == 0 ? null : 0; + }, duration: const Duration(milliseconds: 222)), + ), + ), + ], + ), + IgnorePointer( + // 事件穿透 + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + SizedBox(width: 1.1.w), + quickText(item.questionNo, color: Theme.of(context).primaryColor.withOpacity(0.7), size: 8.sp), + if (item.correctRate > 0) quickText(' 正确率', color: Colors.grey, size: 5.sp), + if (item.correctRate > 0) + Expanded( + child: LinearPercentIndicator( + lineHeight: 6.h, + percent: item.correctRate / 100, + barRadius: Radius.circular(1.2.r), + alignment: MainAxisAlignment.center, + progressColor: Theme.of(context).primaryColor, + backgroundColor: const Color(0xFFB8C7CB).withOpacity(0.35), + center: quickText("${item.correctRate}%", size: 5.sp, align: TextAlign.center, color: Colors.white), + ), + ) ], ), + ), + ], + ), ); } diff --git a/making_school_asignment_app/lib/page/home_page/children/homework_review/configuration_files/index.dart b/making_school_asignment_app/lib/page/home_page/children/homework_review/configuration_files/index.dart index fe9756a..4ced550 100644 --- a/making_school_asignment_app/lib/page/home_page/children/homework_review/configuration_files/index.dart +++ b/making_school_asignment_app/lib/page/home_page/children/homework_review/configuration_files/index.dart @@ -73,7 +73,7 @@ class HomeworkReviewBinding extends Bindings { } } -class HomeworkReviewLogic extends GetxController with RequestToolMixin,EventBusMixin{ +class HomeworkReviewLogic extends GetxController with RequestToolMixin, EventBusMixin { final zoomLogic = Get.find(); final GlobalKey pictureOverviewKey = GlobalKey(); late StreamSubscription _paramListen; @@ -283,7 +283,8 @@ class HomeworkReviewLogic extends GetxController with RequestToolMixin,EventBusM if (data == null) return; if ((state.data.value?.studentQuestions.isEmpty ?? true) || (state.studentQuestions.value?.isEmpty ?? true)) return; - var studentQuestions = state.studentQuestions.value!; + var studentQuestions = state.studentQuestions.value!.where((e) => e.useTime != null && e.useTime! > 0).toList(); + // 跳过学生未作答的题 var noRatingElement = studentQuestions.firstWhereOrNull((e) => e.studentScore == null); if (noRatingElement != null) { ToastUtils.showInfo('${noRatingElement.questionNo}题请评分'); @@ -355,6 +356,7 @@ class HomeworkReviewLogic extends GetxController with RequestToolMixin,EventBusM state.param.value = newParams; }); } catch (_) { + print("批阅提交报错 $_"); } finally { state.submitLoading.value = false; } diff --git a/making_school_asignment_app/lib/page/login_page/login_logic.dart b/making_school_asignment_app/lib/page/login_page/login_logic.dart index 0cc7820..3b3d179 100644 --- a/making_school_asignment_app/lib/page/login_page/login_logic.dart +++ b/making_school_asignment_app/lib/page/login_page/login_logic.dart @@ -4,6 +4,7 @@ import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:get/get.dart'; import 'package:making_school_asignment_app/common/mixins/request_tool_mixin.dart'; import 'package:making_school_asignment_app/common/store/user_store.dart'; +import 'package:making_school_asignment_app/common/utils/app_upgrade/model/UpdateAppEvent.dart'; import 'package:making_school_asignment_app/common/utils/app_upgrade/upgradeLogic.dart'; import 'package:making_school_asignment_app/common/utils/storage.dart'; import 'package:making_school_asignment_app/common/utils/toast_utils.dart'; @@ -63,9 +64,9 @@ class LoginLogic extends GetxController with RequestToolMixin { void toMsg(msg, [bool error = true]) { if (error) { - ToastUtils.showError(msg); + WidgetsBinding.instance.addPostFrameCallback((_) => ToastUtils.showError(msg)); } else { - ToastUtils.showInfo(msg); + WidgetsBinding.instance.addPostFrameCallback((_) => ToastUtils.showInfo(msg)); } state.canLogin.value = true; } @@ -85,8 +86,12 @@ class LoginLogic extends GetxController with RequestToolMixin { try { /// 检查升级APP if (userName != 'AppleTester' && const bool.fromEnvironment('dart.vm.product')) { - upgradeLogic.getAppUpgrade(Get.context ?? context); - return toMsg('请在升级APP后再次登陆', false); + UpdateAppEvent? updateAppEvent = await upgradeLogic.getUpdateAppEvent(); + var upgrade = updateAppEvent?.upgrade ?? false; + if (upgrade) { + upgradeLogic.getAppUpgrade(Get.context ?? context); + return toMsg('请在升级APP后再次登陆', false); + } } await getClient().toLogin(userName, userPwd); String? nameidentifier = UserStore.to.userInfo.value?.nameidentifier;