diff --git a/.gitignore b/.gitignore index ea828da..d077d2e 100644 --- a/.gitignore +++ b/.gitignore @@ -53,3 +53,5 @@ making_school_asignment_app/lib/common/api/retrofit_client.g.dart making_school_asignment_app/lib/page/home_page/children/read_over/read_over_view.g.dart .vscode/settings.json .vscode/launch.json +making_school_asignment_app/.fvm/fvm_config.json +making_school_asignment_app/.fvm/flutter_sdk diff --git a/making_school_asignment_app/android/app/src/main/res/drawable-night-hdpi/android12splash.png b/making_school_asignment_app/android/app/src/main/res/drawable-night-hdpi/android12splash.png new file mode 100644 index 0000000..cc61f38 Binary files /dev/null and b/making_school_asignment_app/android/app/src/main/res/drawable-night-hdpi/android12splash.png differ diff --git a/making_school_asignment_app/android/app/src/main/res/drawable-night-mdpi/android12splash.png b/making_school_asignment_app/android/app/src/main/res/drawable-night-mdpi/android12splash.png new file mode 100644 index 0000000..a0fd671 Binary files /dev/null and b/making_school_asignment_app/android/app/src/main/res/drawable-night-mdpi/android12splash.png differ diff --git a/making_school_asignment_app/android/app/src/main/res/drawable-night-xhdpi/android12splash.png b/making_school_asignment_app/android/app/src/main/res/drawable-night-xhdpi/android12splash.png new file mode 100644 index 0000000..ec6ec76 Binary files /dev/null and b/making_school_asignment_app/android/app/src/main/res/drawable-night-xhdpi/android12splash.png differ diff --git a/making_school_asignment_app/android/app/src/main/res/drawable-night-xxhdpi/android12splash.png b/making_school_asignment_app/android/app/src/main/res/drawable-night-xxhdpi/android12splash.png new file mode 100644 index 0000000..a95467f Binary files /dev/null and b/making_school_asignment_app/android/app/src/main/res/drawable-night-xxhdpi/android12splash.png differ diff --git a/making_school_asignment_app/android/app/src/main/res/drawable-night-xxxhdpi/android12splash.png b/making_school_asignment_app/android/app/src/main/res/drawable-night-xxxhdpi/android12splash.png new file mode 100644 index 0000000..3d00bc0 Binary files /dev/null and b/making_school_asignment_app/android/app/src/main/res/drawable-night-xxxhdpi/android12splash.png differ diff --git a/making_school_asignment_app/android/app/src/main/res/drawable-v21/background.png b/making_school_asignment_app/android/app/src/main/res/drawable-v21/background.png index 9dcfb75..db947d6 100644 Binary files a/making_school_asignment_app/android/app/src/main/res/drawable-v21/background.png and b/making_school_asignment_app/android/app/src/main/res/drawable-v21/background.png differ diff --git a/making_school_asignment_app/android/app/src/main/res/drawable/background.png b/making_school_asignment_app/android/app/src/main/res/drawable/background.png index 9dcfb75..db947d6 100644 Binary files a/making_school_asignment_app/android/app/src/main/res/drawable/background.png and b/making_school_asignment_app/android/app/src/main/res/drawable/background.png differ diff --git a/making_school_asignment_app/android/app/src/main/res/values-night-v31/styles.xml b/making_school_asignment_app/android/app/src/main/res/values-night-v31/styles.xml index d1fbcd5..c9d5097 100644 --- a/making_school_asignment_app/android/app/src/main/res/values-night-v31/styles.xml +++ b/making_school_asignment_app/android/app/src/main/res/values-night-v31/styles.xml @@ -6,6 +6,7 @@ false false shortEdges + #eeeeee @drawable/android12splash - Version 1.0.0 + Version 1.0.1+2 #发行说明-读取html方式(2选1) @@ -14,13 +16,14 @@ - + - + + diff --git a/making_school_asignment_app/ios/Runner/Info.plist b/making_school_asignment_app/ios/Runner/Info.plist index 74381f6..14b5bb3 100644 --- a/making_school_asignment_app/ios/Runner/Info.plist +++ b/making_school_asignment_app/ios/Runner/Info.plist @@ -2,10 +2,12 @@ + CADisableMinimumFrameDurationOnPhone + CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleDisplayName - Making School Asignment App + 点智学 CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier @@ -24,10 +26,19 @@ $(FLUTTER_BUILD_NUMBER) LSRequiresIPhoneOS + NSAppTransportSecurity + + NSExceptionDomains + + + UIApplicationSupportsIndirectInputEvents + UILaunchStoryboardName LaunchScreen UIMainStoryboardFile Main + UIStatusBarHidden + UISupportedInterfaceOrientations UIInterfaceOrientationPortrait @@ -41,12 +52,6 @@ UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight - CADisableMinimumFrameDurationOnPhone - - UIApplicationSupportsIndirectInputEvents - - UIStatusBarHidden - UIViewControllerBasedStatusBarAppearance diff --git a/making_school_asignment_app/ios/Runner/Runner.entitlements b/making_school_asignment_app/ios/Runner/Runner.entitlements new file mode 100644 index 0000000..98d992b --- /dev/null +++ b/making_school_asignment_app/ios/Runner/Runner.entitlements @@ -0,0 +1,22 @@ + + + + + com.apple.developer.associated-domains + + com.apple.developer.devicecheck.appattest-environment + development + com.apple.developer.networking.networkextension + + com.apple.developer.networking.slicing.appcategory + + com.apple.developer.networking.slicing.trafficcategory + + com.apple.developer.networking.wifi-info + + com.apple.developer.user-fonts + + com.apple.security.application-groups + + + diff --git a/making_school_asignment_app/ios/Runner/RunnerRelease.entitlements b/making_school_asignment_app/ios/Runner/RunnerRelease.entitlements new file mode 100644 index 0000000..98d992b --- /dev/null +++ b/making_school_asignment_app/ios/Runner/RunnerRelease.entitlements @@ -0,0 +1,22 @@ + + + + + com.apple.developer.associated-domains + + com.apple.developer.devicecheck.appattest-environment + development + com.apple.developer.networking.networkextension + + com.apple.developer.networking.slicing.appcategory + + com.apple.developer.networking.slicing.trafficcategory + + com.apple.developer.networking.wifi-info + + com.apple.developer.user-fonts + + com.apple.security.application-groups + + + diff --git a/making_school_asignment_app/lib/common/api/retrofit_client.dart b/making_school_asignment_app/lib/common/api/retrofit_client.dart index 4511181..5a2e6b9 100644 --- a/making_school_asignment_app/lib/common/api/retrofit_client.dart +++ b/making_school_asignment_app/lib/common/api/retrofit_client.dart @@ -5,6 +5,7 @@ import 'package:making_school_asignment_app/common/job/marking_models/do_paper_d import 'package:making_school_asignment_app/common/job/marking_models/favor_param.dart'; import 'package:making_school_asignment_app/common/job/marking_models/original_manuscript_handwriting_params.dart'; import 'package:making_school_asignment_app/common/job/marking_models/review_submission_params.dart'; +import 'package:making_school_asignment_app/common/job/user_register_params.dart'; import 'package:making_school_asignment_app/page/home_page/children/homework_review/components/job_handwriting.dart'; import 'package:retrofit/retrofit.dart'; import 'package:making_school_asignment_app/common/job/annotated_class.dart'; @@ -40,6 +41,12 @@ abstract class RetrofitClient { @POST("/api/rbac/Auth/DcLogin") Future toLogin(@Field() String account, @Field() String password); + @POST("/api/rbac/Auth/Register") + Future toRegister(@Body() UserRegisterParams params); + + @DELETE("/api/rbac/User/Delete") + Future toUserLogout(@Field() int id); + @GET("/api/rbac/User/GetUser") Future getUser(@Query('userId') String userId); diff --git a/making_school_asignment_app/lib/common/job/app_version.dart b/making_school_asignment_app/lib/common/job/app_version.dart index ff2354a..0b456b8 100644 --- a/making_school_asignment_app/lib/common/job/app_version.dart +++ b/making_school_asignment_app/lib/common/job/app_version.dart @@ -27,8 +27,8 @@ class AppVersion extends Object { @JsonKey(name: 'ftuType') int ftuType; - @JsonKey(name: 'downloadUrl') - String? downloadUrl; + @JsonKey(name: 'appFileUrl') + String? appFileUrl; @JsonKey(name: 'description') String? description; @@ -41,10 +41,10 @@ class AppVersion extends Object { this.appName, this.version, this.ftuType, - this.downloadUrl, + this.appFileUrl, this.description, ) { - if (downloadUrl != null) downloadUrl = RequestConfig.imgUrl + downloadUrl!; + if (appFileUrl != null) appFileUrl = RequestConfig.imgUrl + appFileUrl!; } factory AppVersion.fromJson(Map srcJson) => _$AppVersionFromJson(srcJson); diff --git a/making_school_asignment_app/lib/common/job/marking_models/do_paper_details_result.dart b/making_school_asignment_app/lib/common/job/marking_models/do_paper_details_result.dart index 369bbf2..8960042 100644 --- a/making_school_asignment_app/lib/common/job/marking_models/do_paper_details_result.dart +++ b/making_school_asignment_app/lib/common/job/marking_models/do_paper_details_result.dart @@ -1,5 +1,4 @@ import 'package:get/get.dart'; -import 'package:get/get_connect/http/src/request/request.dart'; import 'package:json_annotation/json_annotation.dart'; import 'package:making_school_asignment_app/common/config/request_config.dart'; @@ -73,28 +72,31 @@ class DoPaperDetailsResult extends Object { @JsonKey(name: 'totalUnAnnotateCount') int totalUnAnnotateCount; + @JsonKey(name: 'needAnnotate') // 是否需要批阅 + bool needAnnotate; + DoPaperDetailsResult( - this.totalUnAnnotateCount, - this.templateIds, - this.students, - this.templateId, - this.studentId, - this.annotatedCount, - this.submitCount, - this.zgtAnswer, - this.zgtAnnotate, - this.lastAnswerTime, - this.isFav, - this.studentQuestions, - this.unSubmitStudents, - this.lastPage, - this.nextPage, - this.templateIdKeys, - this.templateIdKeyMap, - this.priority, - this.annotateTime, - this.showZgtAnnotate, - ) { + this.totalUnAnnotateCount, + this.templateIds, + this.students, + this.templateId, + this.studentId, + this.annotatedCount, + this.submitCount, + this.zgtAnswer, + this.zgtAnnotate, + this.lastAnswerTime, + this.isFav, + this.studentQuestions, + this.unSubmitStudents, + this.lastPage, + this.nextPage, + this.templateIdKeys, + this.templateIdKeyMap, + this.priority, + this.annotateTime, + this.showZgtAnnotate, + {this.needAnnotate = false}) { if (templateIds.keys.isNotEmpty) { templateIdKeys = templateIds.keys.map((e) => int.parse(e)).toList(); templateIdKeyMap = {}; @@ -114,14 +116,21 @@ class DoPaperDetailsResult extends Object { if (zgtAnnotate?.isNotEmpty ?? false) { showZgtAnnotate = RequestConfig.imgUrl + zgtAnnotate!; // 批注图片地址赋值 - if (annotateTime != null) showZgtAnnotate = '${showZgtAnnotate!}?$annotateTime'; + if (annotateTime != null) + showZgtAnnotate = '${showZgtAnnotate!}?$annotateTime'; } + // 判断当前试题是否需要批阅 + if (annotateTime == null || + studentQuestions.indexWhere((e) => e.studentScore == null) != -1) { + needAnnotate = true; + } // print('学生作答图片:${annotatedCount}'); // print('老师批注图片提交数量:${submitCount}'); } - factory DoPaperDetailsResult.fromJson(Map srcJson) => _$DoPaperDetailsResultFromJson(srcJson); + factory DoPaperDetailsResult.fromJson(Map srcJson) => + _$DoPaperDetailsResultFromJson(srcJson); Map toJson() => _$DoPaperDetailsResultToJson(this); } @@ -144,7 +153,8 @@ class PaperStudents extends Object { this.isPriority, ); - factory PaperStudents.fromJson(Map srcJson) => _$PaperStudentsFromJson(srcJson); + factory PaperStudents.fromJson(Map srcJson) => + _$PaperStudentsFromJson(srcJson); Map toJson() => _$PaperStudentsToJson(this); } @@ -192,7 +202,8 @@ class StudentQuestions extends Object { this.isCorrect, }); - factory StudentQuestions.fromJson(Map srcJson) => _$StudentQuestionsFromJson(srcJson); + factory StudentQuestions.fromJson(Map srcJson) => + _$StudentQuestionsFromJson(srcJson); Map toJson() => _$StudentQuestionsToJson(this); } @@ -210,7 +221,8 @@ class LastPage extends Object { this.studentId, ); - factory LastPage.fromJson(Map srcJson) => _$LastPageFromJson(srcJson); + factory LastPage.fromJson(Map srcJson) => + _$LastPageFromJson(srcJson); Map toJson() => _$LastPageToJson(this); } @@ -228,7 +240,8 @@ class NextPage extends Object { this.studentId, ); - factory NextPage.fromJson(Map srcJson) => _$NextPageFromJson(srcJson); + factory NextPage.fromJson(Map srcJson) => + _$NextPageFromJson(srcJson); Map toJson() => _$NextPageToJson(this); } diff --git a/making_school_asignment_app/lib/common/job/user_register_params.dart b/making_school_asignment_app/lib/common/job/user_register_params.dart new file mode 100644 index 0000000..f3cc543 --- /dev/null +++ b/making_school_asignment_app/lib/common/job/user_register_params.dart @@ -0,0 +1,21 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'user_register_params.g.dart'; + +@JsonSerializable() +class UserRegisterParams extends Object { + @JsonKey(name: 'account') + String account; + + @JsonKey(name: 'password') + String password; + + UserRegisterParams({ + required this.account, + required this.password, + }); + + factory UserRegisterParams.fromJson(Map srcJson) => _$UserRegisterParamsFromJson(srcJson); + + Map toJson() => _$UserRegisterParamsToJson(this); +} diff --git a/making_school_asignment_app/lib/common/request/rest_dio.dart b/making_school_asignment_app/lib/common/request/rest_dio.dart index 0c53d11..0e0eef1 100644 --- a/making_school_asignment_app/lib/common/request/rest_dio.dart +++ b/making_school_asignment_app/lib/common/request/rest_dio.dart @@ -98,7 +98,7 @@ class AuthInterceptor extends Interceptor { headers["x-Authorization"] = xToken!; } - /* if ((userInfo?.isExpired() ?? false) && userInfo?.termYear != '') { + /* if ((userInfo?.isExpired() ?? false) && userInfo?.termYear != '') { headers["term-year"] = userInfo!.termYear; }*/ @@ -160,6 +160,16 @@ class TheError extends Interceptor { int? statusCode = response.statusCode; var errorMap = response.data; + + if (errorMap is String && errorMap.length > 0) { + try { + var errorModel = jsonDecode(errorMap); + var error = errorModel['error']; + if (error != null && error["message"] != null) { + message = error["message"]; + } + } catch (e) {} + } // var runtimeType = errorMap.runtimeType; if (errorMap is Map && errorMap['error'] != null) { message = errorMap['error']?['message'] ?? '请求错误,请重试'; @@ -198,7 +208,7 @@ class TheError extends Interceptor { if (message == '用户登录失效,请重新登录' && userInfo.value?.id == null) { return handler.next(error); } - ToastUtils.showError(message); + Future.delayed(const Duration(milliseconds: 600), () => ToastUtils.showError(message)); return handler.next(error); } } diff --git a/making_school_asignment_app/lib/common/store/app_storage_key.dart b/making_school_asignment_app/lib/common/store/app_storage_key.dart index 0e594fa..97347e9 100644 --- a/making_school_asignment_app/lib/common/store/app_storage_key.dart +++ b/making_school_asignment_app/lib/common/store/app_storage_key.dart @@ -7,7 +7,8 @@ enum AppStorageKey { userInfo(value: 'USERINFO', label: "登录用户的基本信息 及 token过期时间"), userDetailInfo(value: 'USERDETAILINFO', label: "用户的详细信息"), account(value: 'ACCOUNT', label: "用户名"), - pwd(value: 'PWD', label: "密码"); + pwd(value: 'PWD', label: "密码"), + privacyAgreement(value: 'PRIVACYAGREEMENT', label: "用户同意隐私协议"); final String label; final String value; 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 6f23c6e..00e8d15 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 @@ -51,7 +51,7 @@ class UpgradeLogic extends GetxController with RequestToolMixin { // String buildNumber = packageInfo.buildNumber; //小版本号 Map json = { - 'downloadPath': Platform.isWindows ? '' : result.downloadUrl, + 'downloadPath': Platform.isWindows ? '' : result.appFileUrl, 'version': result.version, 'systemType': deviceType, 'description': result.description ?? 'APP新版本更新' diff --git a/making_school_asignment_app/lib/main.dart b/making_school_asignment_app/lib/main.dart index 47edd22..59b0547 100644 --- a/making_school_asignment_app/lib/main.dart +++ b/making_school_asignment_app/lib/main.dart @@ -12,7 +12,6 @@ import 'package:making_school_asignment_app/common/utils/storage.dart'; import 'package:making_school_asignment_app/common/utils/utils.dart'; import 'package:making_school_asignment_app/routes/app_pages.dart'; import 'package:flutter_easyloading/flutter_easyloading.dart'; -import 'package:permission_handler/permission_handler.dart'; import 'common/config/request_config.dart'; import 'common/utils/app_upgrade/upgradeLogic.dart'; @@ -23,6 +22,7 @@ void main() async { Get.testMode = true; WidgetsBinding widgetsBinding = WidgetsFlutterBinding.ensureInitialized(); FlutterNativeSplash.preserve(widgetsBinding: widgetsBinding); + /// 初始化本地存储 await Get.putAsync(() => StorageService().init()); @@ -41,13 +41,11 @@ void main() async { SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle( statusBarColor: Colors.transparent, //状态栏背景颜色 - statusBarIconBrightness: Brightness.dark // dark:一般显示黑色 light:一般显示白色 + statusBarIconBrightness: Brightness.light // dark:一般显示黑色 light:一般显示白色 )); SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: [SystemUiOverlay.top, SystemUiOverlay.bottom]); // 屏幕刘海 await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]); // 屏幕强制竖屏 runApp(const MyApp()); - - Permission.storage.request(); } class MyApp extends StatelessWidget { diff --git a/making_school_asignment_app/lib/page/global_widget/other_page.dart b/making_school_asignment_app/lib/page/global_widget/other_page.dart index 9a36d0d..dcde7de 100644 --- a/making_school_asignment_app/lib/page/global_widget/other_page.dart +++ b/making_school_asignment_app/lib/page/global_widget/other_page.dart @@ -2,6 +2,10 @@ import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import 'package:making_school_asignment_app/common/const_text.dart'; +import 'package:making_school_asignment_app/common/job/user_info_detail.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/storage.dart'; import 'package:making_school_asignment_app/routes/app_pages.dart'; import 'package:package_info_plus/package_info_plus.dart'; import 'package:making_school_asignment_app/page/global_widget/my_text.dart'; @@ -14,7 +18,8 @@ class OhterPage extends StatefulWidget { State createState() => _OhterPageState(); } -class _OhterPageState extends State { +class _OhterPageState extends State with RequestToolMixin { + late Rx userInfo = UserStore.to.userDetailInfo; RxString localVersion = ''.obs; @override @@ -29,16 +34,48 @@ class _OhterPageState extends State { localVersion.value = packageInfo.version; } + // 确认对话框 + _showAlertDialog(context1) async { + await showDialog( + // 表示点击灰色背景的时候是否消失弹出框 + barrierDismissible: false, + context: context1, + builder: (context) { + return AlertDialog(title: quickText("提示信息"), content: quickText("账户注销无法恢复,您确定要注销账户吗?"), actions: [ + TextButton( + child: quickText("取消"), + onPressed: () { + Navigator.pop(context, 'Cancle'); + }, + ), + TextButton( + child: quickText("确定"), + onPressed: () async { + /* ref.read(markingKeyboardProvider.notifier).clean(); + ref.read(markingSubtopicSwitchingProvider.notifier).clean(); + ref.read(userTokenProvider.notifier).clean(); + ref.read(userProvider.notifier).clean();*/ + await getClient().toUserLogout(userInfo.value!.id); + try { + UserStore.to.erase(); + var msg = await StorageService.to.erase(); + print(msg); + Navigator.pop(context, "Ok"); + Get.offAllNamed(Routes.login); + } catch (e) { + print(e); + } + }) + ]); + }); + } + @override Widget build(BuildContext context) { final personalInfoTitleStly = TextStyle( color: const Color.fromRGBO(80, 87, 103, 1), fontSize: 16.sp, ); - final personalInfoValStly = TextStyle( - color: const Color.fromRGBO(148, 163, 182, 1), - fontSize: 16.sp, - ); return Scaffold( backgroundColor: const Color.fromRGBO(248, 248, 248, 1), @@ -108,10 +145,53 @@ class _OhterPageState extends State { ), ], ), + Positioned( + bottom: 50.h, + child: InkWell( + child: Container( + height: 46.h, + width: ScreenUtil().screenWidth - 60.w, + padding: EdgeInsets.symmetric(vertical: 14.h), + decoration: BoxDecoration( + borderRadius: BorderRadius.all( + Radius.circular(6.w), + ), + color: Colors.white, + boxShadow: [ + BoxShadow( + color: const Color.fromRGBO(46, 91, 255, 0.2), + offset: Offset(2.w, 2.h), //阴影y轴偏移量 + blurRadius: 14, //阴影模糊程度 + spreadRadius: 0.5, //阴影扩散程度 + ) + ], + ), + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon( + Icons.exit_to_app_outlined, + size: 13.sp, + color: const Color.fromRGBO(148, 163, 182, 1), + ), + Container( + width: 6.w, + ), + Text( + '账户注销', + style: TextStyle(color: const Color.fromRGBO(148, 163, 182, 1), fontSize: 13.sp), + ), + ], + ), + ), + onTap: () => _showAlertDialog(context), + ), + ), Row( mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.center, - children: [Text('APP备案号: ', style: personalInfoTitleStly), quickText('渝ICP备17007225号-3A', size: 14.sp)], + children: [Text('APP备案号: ', style: personalInfoTitleStly), quickText('渝ICP备17007225号-4A', size: 14.sp)], ), ], )); diff --git a/making_school_asignment_app/lib/page/global_widget/start_page.dart b/making_school_asignment_app/lib/page/global_widget/start_page.dart index e0ba1b0..6e66716 100644 --- a/making_school_asignment_app/lib/page/global_widget/start_page.dart +++ b/making_school_asignment_app/lib/page/global_widget/start_page.dart @@ -1,6 +1,8 @@ import 'dart:async'; +import 'package:app_settings/app_settings.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_native_splash/flutter_native_splash.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; @@ -17,6 +19,7 @@ import 'package:making_school_asignment_app/page/home_page/home_view.dart'; import 'package:making_school_asignment_app/page/work_page/work_logic.dart'; import 'package:making_school_asignment_app/page/work_page/work_view.dart'; import 'package:making_school_asignment_app/routes/app_pages.dart'; +import 'package:permission_handler/permission_handler.dart'; class StartPage extends StatefulWidget { const StartPage({super.key}); @@ -27,16 +30,73 @@ class StartPage extends StatefulWidget { class _StartPageState extends State with RequestToolMixin { Timer? _timer; + Timer? _timerPermission; DateTime? lastPopTime; final _pageController = Get.find(); final _upgradeLogic = Get.find(); late final List _bodyList; + void getStoragePermission() async { + _timerPermission?.cancel(); + _timerPermission = null; + var status = await Permission.storage.status; + if (status != PermissionStatus.granted) { + print(status); + if (status == PermissionStatus.denied) { + await showDialog( + context: context, + barrierDismissible: false, + builder: (BuildContext context) { + return AlertDialog( + title: Text("权限拒绝"), + content: Text("权限被永久拒绝,请前往权限设置页面通过权限"), + actions: [ + ElevatedButton( + onPressed: () async { + await AppSettings.openAppSettings(asAnotherTask: true); + Navigator.of(context).pop(); + _timerPermission = Timer.periodic(const Duration(seconds: 30), (_) => getStoragePermission()); + }, + child: Text('前往'), + ) + ], + ); + }, + ); + + return; + } + await showDialog( + context: context, + barrierDismissible: false, + builder: (BuildContext context) { + return AlertDialog( + title: Text("内存权限"), + content: Text("为了提供更好的服务,需要获取到存储权限用于保存批阅笔记"), + actions: [ + ElevatedButton( + onPressed: () async { + await Permission.storage.request(); + Navigator.of(context).pop(); + getStoragePermission(); + }, + child: Text('允许'), + ) + ], + ); + }, + ); + } + } + @override void initState() { super.initState(); - FlutterNativeSplash.remove(); + + Future.delayed(const Duration(seconds: 3), () => FlutterNativeSplash.remove()); + Future.delayed(const Duration(seconds: 4), () => getStoragePermission()); + Get.put(HomeLogic()); Get.put(WorkLogic()); @@ -72,6 +132,7 @@ class _StartPageState extends State with RequestToolMixin { void dispose() { Get.delete(); _timer?.cancel(); + _timerPermission?.cancel(); super.dispose(); } @@ -87,6 +148,7 @@ class _StartPageState extends State with RequestToolMixin { @override Widget build(BuildContext context) { + SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle(statusBarIconBrightness: Brightness.dark)); return WillPopScope( child: Scaffold( body: PageView( @@ -94,6 +156,11 @@ class _StartPageState extends State with RequestToolMixin { physics: const BouncingScrollPhysics(), onPageChanged: (index) { _pageController._pageIndexState.pageIndex.value = index; + if (index == 2) { + SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle(statusBarIconBrightness: Brightness.light)); + } else { + SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle(statusBarIconBrightness: Brightness.dark)); + } }, children: _bodyList, ), @@ -118,11 +185,14 @@ class _StartPageState extends State with RequestToolMixin { ], //设置显示的模式 type: BottomNavigationBarType.fixed, + fixedColor: Theme.of(context).primaryColor, + unselectedItemColor: Colors.grey, + // unselectedItemColor: const Color.fromRGBO(80, 87, 103, 1), + // backgroundColor: Colors.white, //设置当前的索引 currentIndex: _pageController._pageIndexState.pageIndex.value, //tabBottom的点击监听 onTap: (index) { - print('appbar下标:${index}'); _pageController._pageIndexState.pageController.jumpToPage(index); }, ); diff --git a/making_school_asignment_app/lib/page/home_page/children/annotate_class/annotate_class_view.dart b/making_school_asignment_app/lib/page/home_page/children/annotate_class/annotate_class_view.dart index 458cdc0..90c44df 100644 --- a/making_school_asignment_app/lib/page/home_page/children/annotate_class/annotate_class_view.dart +++ b/making_school_asignment_app/lib/page/home_page/children/annotate_class/annotate_class_view.dart @@ -11,7 +11,7 @@ import 'annotate_class_logic.dart'; import 'widget/completed_annotate_item.dart'; class AnnotateClassPage extends StatefulWidget { - const AnnotateClassPage({Key? key}) : super(key: key); + const AnnotateClassPage({super.key}); @override State createState() => _AnnotateClassPageState(); @@ -25,109 +25,110 @@ class _AnnotateClassPageState extends State { Widget build(BuildContext context) { String homeworkId = state.homeworkId.value; return OrientationBuilder( - builder: (BuildContext context, Orientation orientation){ - return Scaffold( - backgroundColor: const Color.fromRGBO(245, 245, 245, 1), - appBar: AppBar( - backgroundColor: Colors.white, - title: Obx(() { - return Text(state.name.value, style: TextStyle(fontSize: 14.sp, color: const Color(0xFF333333))); - }), - centerTitle: true, - leading: IconButton( - icon: const Icon(Icons.arrow_back_ios, color: Colors.black), - onPressed: () { - Get.back(); + builder: (BuildContext context, Orientation orientation) { + return Scaffold( + backgroundColor: const Color.fromRGBO(245, 245, 245, 1), + appBar: AppBar( + backgroundColor: Colors.white, + title: Obx(() { + return Text(state.name.value, + style: + TextStyle(fontSize: 14.sp, color: const Color(0xFF333333))); + }), + centerTitle: true, + leading: IconButton( + icon: const Icon(Icons.arrow_back_ios, color: Colors.black), + onPressed: () { + Get.back(); + }, + ), + actions: const [ + ReturnToHomepage(), + ], + ), + body: Padding( + padding: EdgeInsets.symmetric(vertical: 14.r, horizontal: 14.r), + child: Obx(() { + return EasyRefresh( + firstRefresh: false, + taskIndependence: true, + controller: logic.refreshController, + header: MaterialHeader(), + footer: TaurusFooter(), + onRefresh: () async { + return logic.getList(); }, - ), - actions: const [ - ReturnToHomepage(), - ], - ), - body: Padding( - padding: EdgeInsets.symmetric(vertical: 14.r, horizontal: 14.r), - child: Obx(() { - return EasyRefresh( - firstRefresh: false, - taskIndependence: true, - controller: logic.refreshController, - header: MaterialHeader(), - footer: TaurusFooter(), - onRefresh: () async{ - return logic.getList(); - }, - child: state.completed.value - ? Utils.isPad() + child: state.completed.value + ? Utils.isPad() ? GridView( - gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 2, //横轴三个子widget - mainAxisSpacing: 10.h, - crossAxisSpacing: 6.w, - childAspectRatio: 1.48 //宽高比为1时,子widget - ), - children: state.classList.map((taskItem) { - return CompletedAnnotateItem( - taskItem: taskItem, - logic: logic, - name: state.name.value, - ); - }).toList(), - ) + gridDelegate: + SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, //横轴三个子widget + mainAxisSpacing: 10.h, + crossAxisSpacing: 6.w, + childAspectRatio: 1.48 //宽高比为1时,子widget + ), + children: state.classList.map((taskItem) { + return CompletedAnnotateItem( + taskItem: taskItem, + logic: logic, + name: state.name.value, + ); + }).toList(), + ) : ListView.builder( - itemCount: state.classList.length, - itemBuilder: (context, index) { - AnnotatedClass taskItem = state.classList[index]; - return CompletedAnnotateItem( - taskItem: taskItem, - logic: logic, - name: state.name.value, - ); - }) - : Utils.isPad() + itemCount: state.classList.length, + itemBuilder: (context, index) { + AnnotatedClass taskItem = state.classList[index]; + return CompletedAnnotateItem( + taskItem: taskItem, + logic: logic, + name: state.name.value, + ); + }) + : Utils.isPad() ? MasonryGridView.count( - crossAxisCount: 2, //几列 - mainAxisSpacing: 4.w, // 间距 - crossAxisSpacing: 4.h, // 纵向间距? - itemCount: state.classList.length, - itemBuilder: (context, index) { - AnnotatedClass item = state.classList[index]; - return AnnotateItem( - homeworkId: homeworkId, - item: item, - font: 11.sp, - name: state.name.value, - logic: logic, - ); - }, - ) + crossAxisCount: 2, //几列 + mainAxisSpacing: 4.w, // 间距 + crossAxisSpacing: 4.h, // 纵向间距? + itemCount: state.classList.length, + itemBuilder: (context, index) { + AnnotatedClass item = state.classList[index]; + return AnnotateItem( + homeworkId: homeworkId, + item: item, + font: 11.sp, + name: state.name.value, + logic: logic, + ); + }, + ) : ListView.builder( - itemCount: state.classList.length, - itemBuilder: (context, index) { - AnnotatedClass item = state.classList[index]; - return AnnotateItem( - homeworkId: homeworkId, - item: item, - font: 12.sp, - name: state.name.value, - logic: logic, - ); - })); - }), - ), - ); - } - ); + itemCount: state.classList.length, + itemBuilder: (context, index) { + AnnotatedClass item = state.classList[index]; + return AnnotateItem( + homeworkId: homeworkId, + item: item, + font: 12.sp, + name: state.name.value, + logic: logic, + ); + })); + }), + ), + ); + }); } @override void dispose() { Get.delete(); super.dispose(); - if(state.preIndex != 3){ + if (state.preIndex != 3) { // logic.readOverController.state.tabIndex.value = state.preIndex; - }else{ + } else { // logic.homeController.getList(); } - } } diff --git a/making_school_asignment_app/lib/page/home_page/children/homework_review/components/original_manuscript_handwriting/answer_handwriting_view.dart b/making_school_asignment_app/lib/page/home_page/children/homework_review/components/original_manuscript_handwriting/answer_handwriting_view.dart index 92b1ebe..2ef8818 100644 --- a/making_school_asignment_app/lib/page/home_page/children/homework_review/components/original_manuscript_handwriting/answer_handwriting_view.dart +++ b/making_school_asignment_app/lib/page/home_page/children/homework_review/components/original_manuscript_handwriting/answer_handwriting_view.dart @@ -1,6 +1,5 @@ import 'dart:async'; -import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:flutter_spinkit/flutter_spinkit.dart'; @@ -32,13 +31,21 @@ class AnswerHandwriting extends Dialog { final String? questionNo; final Function closeCall; AnswerHandwriting( - {super.key, required this.homeworkId, required this.studentId, required this.closeCall, this.templateId, this.pageNum, this.questionNo}); + {super.key, + required this.homeworkId, + required this.studentId, + required this.closeCall, + this.templateId, + this.pageNum, + this.questionNo}); final _handwritingLogic = Get.find(); @override Widget build(BuildContext context) { - return OrientationBuilder(builder: (BuildContext context, Orientation orientation) { + return OrientationBuilder( + builder: (BuildContext context, Orientation orientation) { var boxHeight = ScreenUtil().screenHeight / 1.168; // 盒子高度 - var boxWidth = ScreenUtil().screenWidth - (ScreenUtil().scaleWidth < 1.5 ? 40.r : 40.r); // 盒子宽度 + var boxWidth = ScreenUtil().screenWidth - + (ScreenUtil().scaleWidth < 1.5 ? 40.r : 40.r); // 盒子宽度 return Center( child: Container( @@ -75,7 +82,8 @@ Future showAnswerHandwriting( } Get.put(HandwritingLogic(backCall)); - Get.find().params.value = OriginalManuscriptHandwritingParams( + Get.find().params.value = + OriginalManuscriptHandwritingParams( homeworkId: homeworkId, studentId: studentId, templateId: templateId, @@ -123,10 +131,12 @@ class AnswerHandwritingMainBox extends HookWidget with EventBusMixin { @override Widget build(BuildContext context) { - var _useStateModel = UseMainBoxState.use(homeworkId, studentId, pageNum, questionNo, templateId); + var _useStateModel = UseMainBoxState.use( + homeworkId, studentId, pageNum, questionNo, templateId); double barHeight = 62.h; double imageHeight = boxHeight - barHeight; - useValueChanged(_useStateModel.handwritingData.value, (_, __) { + useValueChanged(_useStateModel.handwritingData.value, + (_, __) { var theData = _useStateModel.handwritingData.value; _useStateModel.pageNum.value = theData?.pageNum; _useStateModel.pageCount.value = theData?.pageCount ?? 0; @@ -210,7 +220,8 @@ class UseMainBoxState with RequestToolMixin { }); // 工厂构造函数 - factory UseMainBoxState.use(String homeworkId, int studentId, [int? pageNum, String? questionNo, int? templateId]) { + factory UseMainBoxState.use(String homeworkId, int studentId, + [int? pageNum, String? questionNo, int? templateId]) { return UseMainBoxState._( homeworkId: homeworkId, templateId: templateId, @@ -236,7 +247,8 @@ class PreviousNutton extends StatelessWidget { @override Widget build(BuildContext context) { return Obx(() { - if (handwritingLogic.resultData.value?.pageNum != null && handwritingLogic.resultData.value!.pageNum > 1) { + if (handwritingLogic.resultData.value?.pageNum != null && + handwritingLogic.resultData.value!.pageNum > 1) { return Positioned( left: 3.w, child: FloatingActionButton( @@ -252,7 +264,8 @@ class PreviousNutton extends StatelessWidget { params.pageNum = resultData.pageNum - 1; params.templateId = null; params.questionNo = null; - handwritingLogic.params.value = OriginalManuscriptHandwritingParams.fromJson(params.toJson()); + handwritingLogic.params.value = + OriginalManuscriptHandwritingParams.fromJson(params.toJson()); // handwritingLogic.params.value = params; }), child: Icon(Icons.arrow_back_ios, color: Colors.white, size: 22.sp), @@ -275,7 +288,8 @@ class NextPageButton extends StatelessWidget { Widget build(BuildContext context) { return Obx(() { if (handwritingLogic.resultData.value?.pageNum != null && - handwritingLogic.resultData.value!.pageNum < handwritingLogic.resultData.value!.pageCount) { + handwritingLogic.resultData.value!.pageNum < + handwritingLogic.resultData.value!.pageCount) { return Positioned( right: 3.w, child: FloatingActionButton( @@ -290,9 +304,11 @@ class NextPageButton extends StatelessWidget { params.pageNum = resultData.pageNum + 1; params.templateId = null; params.questionNo = null; - handwritingLogic.params.value = OriginalManuscriptHandwritingParams.fromJson(params.toJson()); + handwritingLogic.params.value = + OriginalManuscriptHandwritingParams.fromJson(params.toJson()); }), - child: Icon(Icons.arrow_forward_ios, color: Colors.white, size: 22.sp), + child: + Icon(Icons.arrow_forward_ios, color: Colors.white, size: 22.sp), ), ); } @@ -306,13 +322,15 @@ class NextPageButton extends StatelessWidget { class HandwritingDrawBox extends StatefulWidget { final double boxWidth; final double boxHeight; - const HandwritingDrawBox({required this.boxWidth, required this.boxHeight, super.key}); + const HandwritingDrawBox( + {required this.boxWidth, required this.boxHeight, super.key}); @override State createState() => _HandwritingDrawBoxState(); } -class _HandwritingDrawBoxState extends State with EventBusMixin { +class _HandwritingDrawBoxState extends State + with EventBusMixin { HandwritingLogic handwritingLogic = Get.find(); // 学生答题笔迹逻辑层 ImageStream? imageStream; // 图片监听数据 @@ -351,13 +369,16 @@ class _HandwritingDrawBoxState extends State with EventBusMi }); _vnHandWritings = ValueNotifier>([]); - _vnPrimaryHandWritings = ValueNotifier>(_packagedHandwritingDataAll); + _vnPrimaryHandWritings = ValueNotifier>( + _packagedHandwritingDataAll); handwritingLogic.toolbar.initialization.listen((e) { // 数据初始化完成赋值数据 if (e) { - _packagedHandwritingDatas = handwritingLogic.packagedHandwritingDatas.value; - _packagedHandwritingDataAll = handwritingLogic.packagedHandwritingDataAll.value; + _packagedHandwritingDatas = + handwritingLogic.packagedHandwritingDatas.value; + _packagedHandwritingDataAll = + handwritingLogic.packagedHandwritingDataAll.value; } else { _packagedHandwritingDatas = []; _packagedHandwritingDataAll = []; @@ -367,7 +388,9 @@ class _HandwritingDrawBoxState extends State with EventBusMi try { _vnPrimaryHandWritings.value = [..._packagedHandwritingDataAll]; // 总体数据 } catch (e) { - _vnPrimaryHandWritings = ValueNotifier>(_packagedHandwritingDataAll); + _vnPrimaryHandWritings = + ValueNotifier>( + _packagedHandwritingDataAll); } // eventFire(model: JobHandwritingPlaybarBus); }); @@ -421,7 +444,8 @@ class _HandwritingDrawBoxState extends State with EventBusMi // 播放速度 var _model = (e as PlaybackSpeedBus); speed = _model.speed; - dragProgressBarInitData(handwritingDuration - handwritingTime, handwritingDuration); + dragProgressBarInitData( + handwritingDuration - handwritingTime, handwritingDuration); break; default: } @@ -446,14 +470,18 @@ class _HandwritingDrawBoxState extends State with EventBusMi }); timers = []; // 总时间-剩余时间=已经执行时间 - if (recalculate && pendingData.isNotEmpty && handwritingTime > 0 && (handwritingDuration - handwritingTime > 0)) { + if (recalculate && + pendingData.isNotEmpty && + handwritingTime > 0 && + (handwritingDuration - handwritingTime > 0)) { // 待执行的数据不等于空 每个数据都需要减去当前暂停已经执行的时间 pendingData = pendingData.map((e) { return GestureHandwritingRecording( stroke: e.stroke, data: e.data, usageTime: e.usageTime, - intervalTime: e.intervalTime - (handwritingDuration - handwritingTime) * 1000, + intervalTime: + e.intervalTime - (handwritingDuration - handwritingTime) * 1000, ); }).toList(); } @@ -473,7 +501,8 @@ class _HandwritingDrawBoxState extends State with EventBusMi } handwritingLogic.toolbar.showManuscript.value = false; executableData.forEach((e) { - var ter = Timer(Duration(milliseconds: e.intervalTime ~/ speed), () => zhixinCall(e)); + var ter = Timer(Duration(milliseconds: e.intervalTime ~/ speed), + () => zhixinCall(e)); timers.add(ter); }); } catch (e) { @@ -483,7 +512,8 @@ class _HandwritingDrawBoxState extends State with EventBusMi Future zhixinCall(GestureHandwritingRecording e) async { if (mounted) { - List trajectorys = handwritingLogic.toolbar.executionData.value..add(e); + List trajectorys = + handwritingLogic.toolbar.executionData.value..add(e); handwritingLogic.toolbar.executionData.value = List.from(trajectorys); pendingData.remove(e); // 执行后删除容器中的当前动作 } @@ -539,20 +569,26 @@ class _HandwritingDrawBoxState extends State with EventBusMi var paperPicture = handwritingLogic.resultData.value?.paperPicture; if (paperPicture == null) return const SizedBox(); - print('显示原稿:${handwritingLogic.toolbar.showManuscript.value} 数据:${_vnPrimaryHandWritings.value.length}'); + print( + '显示原稿:${handwritingLogic.toolbar.showManuscript.value} 数据:${_vnPrimaryHandWritings.value.length}'); return RepaintBoundary( child: CustomPaint( foregroundPainter: HandWritingDrawingPainter( - ctrl: handwritingLogic.toolbar.showManuscript.value ? _vnPrimaryHandWritings : _vnHandWritings, + ctrl: handwritingLogic.toolbar.showManuscript.value + ? _vnPrimaryHandWritings + : _vnHandWritings, ), child: $TheCachedNetworkImage( imageUrl: paperPicture, (context, imageProvider) { - Image imageWidget = Image(image: imageProvider, fit: BoxFit.contain); + Image imageWidget = + Image(image: imageProvider, fit: BoxFit.contain); var imagInfoModel = handwritingLogic.imagInfoModel.value; - if (imagInfoModel == null || imagInfoModel.boxWidth != widget.boxWidth) { + if (imagInfoModel == null || + imagInfoModel.boxWidth != widget.boxWidth) { imageStream?.removeListener(theImageStreamListener); - imageStream = imageWidget.image.resolve(const ImageConfiguration()); + imageStream = + imageWidget.image.resolve(const ImageConfiguration()); imageStream?.addListener(theImageStreamListener); } return imageWidget; @@ -590,7 +626,8 @@ class HandWritingDrawingPainter extends CustomPainter { var _length = points.length; for (int i = 0; i < _length; i++) { GestureHandwritingRecording item = points[i]; - GestureHandwritingRecording? nextItem = i + 1 < _length ? points[i + 1] : null; + GestureHandwritingRecording? nextItem = + i + 1 < _length ? points[i + 1] : null; Offset offsetData = item.data; Offset? nextOffsetData = nextItem?.data; @@ -604,7 +641,8 @@ class HandWritingDrawingPainter extends CustomPainter { @override bool shouldRepaint(covariant CustomPainter oldDelegate) { if (oldDelegate is HandWritingDrawingPainter) { - var repaint = ctrl.value.length != oldDelegate.ctrl.value.length || oldDelegate.ctrl.value != ctrl.value; + var repaint = ctrl.value.length != oldDelegate.ctrl.value.length || + oldDelegate.ctrl.value != ctrl.value; print('调用是否绘制:$repaint'); return repaint; } @@ -616,7 +654,8 @@ class HandWritingDrawingPainter extends CustomPainter { class PageNumberBox extends StatelessWidget { PageNumberBox({super.key}); - final HandwritingLogic handwritingLogic = Get.find(); // 学生答题笔迹逻辑层 + final HandwritingLogic handwritingLogic = + Get.find(); // 学生答题笔迹逻辑层 @override Widget build(BuildContext context) { @@ -634,11 +673,20 @@ class PageNumberBox extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.end, children: [ Obx(() { - return quickText('${handwritingLogic.resultData.value?.pageNum ?? 0}', color: Colors.white, size: 11.sp, align: TextAlign.end); + return quickText( + '${handwritingLogic.resultData.value?.pageNum ?? 0}', + color: Colors.white, + size: 11.sp, + align: TextAlign.end); }), - quickText('/', color: Colors.white, size: 10.sp, align: TextAlign.end), + quickText('/', + color: Colors.white, size: 10.sp, align: TextAlign.end), Obx(() { - return quickText('${handwritingLogic.resultData.value?.pageCount ?? 0}', color: Colors.white, size: 8.sp, align: TextAlign.end); + return quickText( + '${handwritingLogic.resultData.value?.pageCount ?? 0}', + color: Colors.white, + size: 8.sp, + align: TextAlign.end); }), ], )), @@ -647,7 +695,8 @@ class PageNumberBox extends StatelessWidget { } @hwidget -Widget $bottomPlaybar(BuildContext context, double barHeight, HandwritingLogic handwritingLogic) { +Widget $bottomPlaybar( + BuildContext context, double barHeight, HandwritingLogic handwritingLogic) { var timeConsuming = useState(0); var handwritingInfo = useState(null); @@ -665,8 +714,10 @@ Widget $bottomPlaybar(BuildContext context, double barHeight, HandwritingLogic h usePlaybar.useTime.value = usePlaybar.handwritingDuration.value; }); // 播放速度 - useValueChanged(usePlaybar.constantFastSpeed.value, (_, __) { - usePlaybar.eventFire(model: PlaybackSpeedBus(usePlaybar.constantFastSpeed.value.speed)); + useValueChanged(usePlaybar.constantFastSpeed.value, + (_, __) { + usePlaybar.eventFire( + model: PlaybackSpeedBus(usePlaybar.constantFastSpeed.value.speed)); // 播放速度变化 usePlaybar.playTimingSuspend(); usePlaybar.playTimingStarts(); @@ -675,9 +726,12 @@ Widget $bottomPlaybar(BuildContext context, double barHeight, HandwritingLogic h useValueChanged(usePlaybar.useTime.value, (_, __) { var _runtime = usePlaybar.useTime.value; if (_runtime <= 0 || usePlaybar.handwritingDuration.value == _runtime) { - Future.delayed(Duration.zero, () => (usePlaybar.playPause.value = false)); // 初始化播放按钮 + Future.delayed( + Duration.zero, () => (usePlaybar.playPause.value = false)); // 初始化播放按钮 } - usePlaybar.eventFire(model: JobHandwritingRunTimeBus(_runtime, usePlaybar.handwritingDuration.value)); + usePlaybar.eventFire( + model: JobHandwritingRunTimeBus( + _runtime, usePlaybar.handwritingDuration.value)); }); useEffect(() { @@ -708,7 +762,8 @@ Widget $bottomPlaybar(BuildContext context, double barHeight, HandwritingLogic h break; case JobHandwritingGetReadyBus: // 作业笔迹已经计算好坐标 可以开始播放 - Future.delayed(Duration.zero, () => (usePlaybar.handWritingReady.value = true)); + Future.delayed( + Duration.zero, () => (usePlaybar.handWritingReady.value = true)); break; default: } @@ -737,13 +792,17 @@ Widget $bottomPlaybar(BuildContext context, double barHeight, HandwritingLogic h if (usePlaybar.handWritingReady.value) InkWell( onTap: () => easyThrottle('job_handwriting_play_pause', () { - if (usePlaybar.handwritingDuration.value == 0) return ToastUtils.showInfo('没有笔迹'); + if (usePlaybar.handwritingDuration.value == 0) + return ToastUtils.showInfo('没有笔迹'); usePlaybar.playPause.value = !usePlaybar.playPause.value; - usePlaybar.eventFire(model: JobHandwritingPlaybarBus(usePlaybar.playPause.value)); + usePlaybar.eventFire( + model: JobHandwritingPlaybarBus(usePlaybar.playPause.value)); }), child: Icon( - !usePlaybar.playPause.value ? Icons.play_circle_outline : Icons.pause_circle_outline, + !usePlaybar.playPause.value + ? Icons.play_circle_outline + : Icons.pause_circle_outline, color: Colors.white, size: 28.r, ), @@ -755,28 +814,36 @@ Widget $bottomPlaybar(BuildContext context, double barHeight, HandwritingLogic h child: LayoutBuilder(builder: (context, constraints) { final double containerWidth = constraints.maxWidth; // 展示区域总宽度 var unitScale = containerWidth / timeConsuming.value; // 单位刻度 - var pauseIntervalsLength = handwritingInfo.value?.pauseInterval.length ?? 0; + var pauseIntervalsLength = + handwritingInfo.value?.pauseInterval.length ?? 0; - List pauseTickMarks = handwritingInfo.value?.pauseInterval.asMap().keys.map((e) { - bool isLast = e == pauseIntervalsLength - 1; - bool isFirst = e == 0; - var item = handwritingInfo.value!.pauseInterval[e]; - return Positioned( - top: 0, - left: unitScale * item.startTime, - child: Container( - width: unitScale * (item.apart ?? 0), - height: 10.h, - decoration: BoxDecoration( - color: Color.fromRGBO(202, 201, 201, 1), - borderRadius: isFirst - ? BorderRadius.only(topLeft: Radius.circular(8.r), bottomLeft: Radius.circular(10.r)) - : (isLast ? BorderRadius.only(topRight: Radius.circular(8.r), bottomRight: Radius.circular(10.r)) : null), - ), - ), - ); - }).toList() ?? - []; + List pauseTickMarks = + handwritingInfo.value?.pauseInterval.asMap().keys.map((e) { + bool isLast = e == pauseIntervalsLength - 1; + bool isFirst = e == 0; + var item = handwritingInfo.value!.pauseInterval[e]; + return Positioned( + top: 0, + left: unitScale * item.startTime, + child: Container( + width: unitScale * (item.apart ?? 0), + height: 10.h, + decoration: BoxDecoration( + color: Color.fromRGBO(202, 201, 201, 1), + borderRadius: isFirst + ? BorderRadius.only( + topLeft: Radius.circular(8.r), + bottomLeft: Radius.circular(10.r)) + : (isLast + ? BorderRadius.only( + topRight: Radius.circular(8.r), + bottomRight: Radius.circular(10.r)) + : null), + ), + ), + ); + }).toList() ?? + []; return Column( mainAxisSize: MainAxisSize.min, @@ -800,29 +867,42 @@ Widget $bottomPlaybar(BuildContext context, double barHeight, HandwritingLogic h child: SliderTheme( data: SliderTheme.of(context).copyWith( trackHeight: 10.h, // 轨道高度 - trackShape: RoundedRectSliderTrackShape(), // 轨道形状,可以自定义 - activeTrackColor: Theme.of(context).primaryColor, // 激活的轨道颜色 + trackShape: + RoundedRectSliderTrackShape(), // 轨道形状,可以自定义 + activeTrackColor: + Theme.of(context).primaryColor, // 激活的轨道颜色 inactiveTrackColor: Colors.transparent, // 未激活的轨道颜色 - thumbShape: RoundSliderThumbShape(enabledThumbRadius: 0, disabledThumbRadius: 0), + thumbShape: RoundSliderThumbShape( + enabledThumbRadius: 0, disabledThumbRadius: 0), thumbColor: Colors.white, // 滑块颜色 - overlayShape: RoundSliderOverlayShape(overlayRadius: 0), + overlayShape: + RoundSliderOverlayShape(overlayRadius: 0), overlayColor: Colors.black54, // 滑块外圈颜色 // valueIndicatorShape: PaddleSliderValueIndicatorShape(), // 标签形状,可以自定义 ), child: Slider( - value: (usePlaybar.handwritingDuration.value - usePlaybar.useTime.value).toDouble(), + value: (usePlaybar.handwritingDuration.value - + usePlaybar.useTime.value) + .toDouble(), min: 0.0, max: usePlaybar.handwritingDuration.value.toDouble(), inactiveColor: Colors.transparent, onChangeEnd: (value) { if (!usePlaybar.handWritingReady.value) return; usePlaybar.playTimingSuspend(); // 暂停计时器得暂停 - usePlaybar.eventFire(model: JobHandwritingDragProgressBarBus(value.toInt(), usePlaybar.handwritingDuration.value)); - usePlaybar.useTime.value = usePlaybar.handwritingDuration.value - value.toInt(); + usePlaybar.eventFire( + model: JobHandwritingDragProgressBarBus( + value.toInt(), + usePlaybar.handwritingDuration.value)); + usePlaybar.useTime.value = + usePlaybar.handwritingDuration.value - + value.toInt(); }, onChanged: (double value) { if (!usePlaybar.handWritingReady.value) return; - usePlaybar.useTime.value = usePlaybar.handwritingDuration.value - value.toInt(); + usePlaybar.useTime.value = + usePlaybar.handwritingDuration.value - + value.toInt(); }, ), ), @@ -835,8 +915,16 @@ Widget $bottomPlaybar(BuildContext context, double barHeight, HandwritingLogic h child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - quickText('累计停顿:${handwritingInfo.value?.pauseCount ?? 0}次', color: Colors.white, size: 7.sp), - quickText(convertSeconds(usePlaybar.useTime.value)?.toString() ?? '', color: Colors.white, size: 7.sp), + quickText( + '累计停顿:${handwritingInfo.value?.pauseCount ?? 0}次', + color: Colors.white, + size: 7.sp), + quickText( + convertSeconds(usePlaybar.useTime.value) + ?.toString() ?? + '', + color: Colors.white, + size: 7.sp), ], ), ) @@ -851,16 +939,20 @@ Widget $bottomPlaybar(BuildContext context, double barHeight, HandwritingLogic h children: [ InkWell( onTap: () => easyThrottle('job_handwriting_speed', () { - var theIndex = PlaybackSpeed.values.indexOf(usePlaybar.constantFastSpeed.value); + var theIndex = PlaybackSpeed.values + .indexOf(usePlaybar.constantFastSpeed.value); if (theIndex == PlaybackSpeed.values.length - 1) { theIndex = -1; } - usePlaybar.constantFastSpeed.value = PlaybackSpeed.values[theIndex + 1]; + usePlaybar.constantFastSpeed.value = + PlaybackSpeed.values[theIndex + 1]; }, duration: Duration(milliseconds: 500)), child: Container( // alignment: Alignment., padding: EdgeInsets.symmetric(horizontal: 3.w, vertical: 1.5.h), - decoration: BoxDecoration(color: Color.fromRGBO(182, 197, 250, 1), borderRadius: BorderRadius.circular(4.r)), + decoration: BoxDecoration( + color: Color.fromRGBO(182, 197, 250, 1), + borderRadius: BorderRadius.circular(4.r)), child: quickText( '${usePlaybar.constantFastSpeed.value.name}', color: Color.fromRGBO(79, 114, 244, 1), @@ -895,9 +987,12 @@ class StudentManuscriptBtn extends StatelessWidget { padding: EdgeInsets.symmetric(horizontal: 3.w, vertical: 1.5.h), decoration: BoxDecoration( borderRadius: BorderRadius.circular(4.r), - color: handwritingLogic.toolbar.showManuscript.value ? Theme.of(context).primaryColor : Colors.grey, + color: handwritingLogic.toolbar.showManuscript.value + ? Theme.of(context).primaryColor + : Colors.grey, ), - child: quickText('学生原稿', color: Colors.white, size: 8.sp, align: TextAlign.center), + child: quickText('学生原稿', + color: Colors.white, size: 8.sp, align: TextAlign.center), ), ); }); @@ -911,7 +1006,8 @@ class SysjTime extends StatefulWidget { State createState() => _SysjTimeState(); } -class _SysjTimeState extends State with EventBusMixin { +class _SysjTimeState extends State + with EventBusMixin { int useTime = 0; @override void initState() { @@ -930,7 +1026,8 @@ class _SysjTimeState extends State with EventBusMixin 0) { timer.value?.cancel(); - timer.value = Timer.periodic(Duration(milliseconds: 1000 ~/ constantFastSpeed.value.speed), (theTime) { + timer.value = Timer.periodic( + Duration(milliseconds: 1000 ~/ constantFastSpeed.value.speed), + (theTime) { useTime.value -= 1; if (useTime.value < 0) { theTime.cancel(); diff --git a/making_school_asignment_app/lib/page/home_page/children/homework_review/components/question_paper_view.dart b/making_school_asignment_app/lib/page/home_page/children/homework_review/components/question_paper_view.dart index 09527aa..2123b51 100644 --- a/making_school_asignment_app/lib/page/home_page/children/homework_review/components/question_paper_view.dart +++ b/making_school_asignment_app/lib/page/home_page/children/homework_review/components/question_paper_view.dart @@ -41,13 +41,15 @@ class _QuestionPaperViewState extends State { // 试题图片视图 Expanded( flex: 7, - child: LayoutBuilder(builder: (BuildContext context, BoxConstraints constraints) { + child: LayoutBuilder( + builder: (BuildContext context, BoxConstraints constraints) { var maxWidth = constraints.maxWidth; var maxHeight = constraints.maxHeight; return Stack( children: [ // 主图 - QuestionImageView(maxWidth, maxHeight, sateData, annotationState, logic), + QuestionImageView( + maxWidth, maxHeight, sateData, annotationState, logic), // 继续批阅按钮 // Positioned(right: 3.w, bottom: 4.h, child: const $ContinueToReview(isFloatingAction: true)), // 上一题按钮 @@ -61,15 +63,19 @@ class _QuestionPaperViewState extends State { heroTag: '点击前往上一题', tooltip: '点击前往上一题', focusColor: Theme.of(context).primaryColor, - backgroundColor: const Color.fromRGBO(24, 32, 32, 0.05), + backgroundColor: + const Color.fromRGBO(24, 32, 32, 0.05), elevation: 10.r, - onPressed: () => easyThrottle('TestQuestionSwitch', () { + onPressed: () => + easyThrottle('TestQuestionSwitch', () { var param = sateData.param.value; param.studentId = lastPageVal.studentId; param.templateId = lastPageVal.templateId; - sateData.param.value = DoPaperDetailsParam.fromJson(param.toJson()); + sateData.param.value = + DoPaperDetailsParam.fromJson(param.toJson()); }), - child: Icon(Icons.arrow_back_ios, color: Colors.white, size: 22.sp), + child: Icon(Icons.arrow_back_ios, + color: Colors.white, size: 22.sp), ); }), ), @@ -84,14 +90,18 @@ class _QuestionPaperViewState extends State { heroTag: '点击前往下一题', tooltip: '点击前往下一题', elevation: 10.r, - backgroundColor: const Color.fromRGBO(24, 32, 32, 0.05), - onPressed: () => easyThrottle('TestQuestionSwitch', () { + backgroundColor: + const Color.fromRGBO(24, 32, 32, 0.05), + onPressed: () => + easyThrottle('TestQuestionSwitch', () { var param = sateData.param.value; param.studentId = nextPageVal.studentId; param.templateId = nextPageVal.templateId; - sateData.param.value = DoPaperDetailsParam.fromJson(param.toJson()); + sateData.param.value = + DoPaperDetailsParam.fromJson(param.toJson()); }), - child: Icon(Icons.arrow_forward_ios, color: Colors.white, size: 22.sp), + child: Icon(Icons.arrow_forward_ios, + color: Colors.white, size: 22.sp), ); }), ), @@ -112,7 +122,8 @@ class _QuestionPaperViewState extends State { child: CupertinoButton( color: Colors.grey[300], onPressed: () => easyThrottle('home_work_reload_data', () { - sateData.param.value = DoPaperDetailsParam.fromJson(sateData.param.value.toJson()); + sateData.param.value = + DoPaperDetailsParam.fromJson(sateData.param.value.toJson()); }), child: quickText('重新请求', color: Colors.black38), ), @@ -125,7 +136,8 @@ class _QuestionPaperViewState extends State { // 底部已阅数量和待阅数量 @swidget -Widget $totalSubmitCountView(BuildContext context, HomeworkReviewState sateData) { +Widget $totalSubmitCountView( + BuildContext context, HomeworkReviewState sateData) { return Obx(() { var data = sateData.data.value; if (data == null) return Container(); @@ -140,7 +152,10 @@ Widget $totalSubmitCountView(BuildContext context, HomeworkReviewState sateData) context: context, elevation: 10, backgroundColor: Colors.white, - shape: RoundedRectangleBorder(borderRadius: BorderRadius.only(topLeft: Radius.circular(10.r), topRight: Radius.circular(10.r))), + 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), @@ -158,7 +173,8 @@ Widget $totalSubmitCountView(BuildContext context, HomeworkReviewState sateData) SizedBox(height: 10.h), Expanded( child: ListView( - padding: EdgeInsets.symmetric(vertical: 8.h, horizontal: 4.w), + padding: EdgeInsets.symmetric( + vertical: 8.h, horizontal: 4.w), children: [ Wrap( spacing: 7.2.w, // 主轴(水平)方向间距 @@ -169,27 +185,40 @@ Widget $totalSubmitCountView(BuildContext context, HomeworkReviewState sateData) alignment: const FractionalOffset(0.05, 0.09), children: [ Container( - padding: EdgeInsets.only(top: 1.2.h, bottom: 1.5.h, left: 13.w, right: 5.w), + padding: EdgeInsets.only( + top: 1.2.h, + bottom: 1.5.h, + left: 13.w, + right: 5.w), decoration: BoxDecoration( borderRadius: BorderRadius.circular(4.r), - color: const Color.fromRGBO(239, 242, 255, 1), + color: const Color.fromRGBO( + 239, 242, 255, 1), ), child: quickText( e.name, size: 12.sp, wordSpacing: 2, - color: const Color.fromRGBO(80, 94, 110, 1), + color: + const Color.fromRGBO(80, 94, 110, 1), ), ), Stack( - alignment: const FractionalOffset(0.52, 0.24), + alignment: + const FractionalOffset(0.52, 0.24), children: [ Icon( - const IconData(0xe63d, fontFamily: "AlibabaIcon"), + const IconData(0xe63d, + fontFamily: "AlibabaIcon"), size: 12.sp, - color: e.isPriority ? const Color.fromRGBO(76, 199, 147, 1) : const Color.fromRGBO(164, 164, 164, 1), + color: e.isPriority + ? const Color.fromRGBO( + 76, 199, 147, 1) + : const Color.fromRGBO( + 164, 164, 164, 1), ), - quickText('优先', size: 4.sp, color: Colors.white), + quickText('优先', + size: 4.sp, color: Colors.white), ], ), ], @@ -211,11 +240,17 @@ Widget $totalSubmitCountView(BuildContext context, HomeworkReviewState sateData) children: [ Padding( padding: EdgeInsets.only(bottom: 1.h), - child: quickText('已阅', color: const Color.fromRGBO(117, 117, 117, 1), size: 10.sp), + child: quickText('已阅', + color: const Color.fromRGBO(117, 117, 117, 1), size: 10.sp), ), - quickText(data.annotatedCount, color: const Color.fromRGBO(76, 199, 147, 1), size: 12.sp, fontWeight: FontWeight.bold), - quickText('/', color: const Color.fromRGBO(117, 117, 117, 1), size: 12.sp), - quickText(data.submitCount - data.annotatedCount, color: const Color.fromRGBO(117, 117, 117, 1), size: 10.sp), + quickText(data.annotatedCount, + color: const Color.fromRGBO(76, 199, 147, 1), + size: 12.sp, + fontWeight: FontWeight.bold), + quickText('/', + color: const Color.fromRGBO(117, 117, 117, 1), size: 12.sp), + quickText(data.submitCount - data.annotatedCount, + color: const Color.fromRGBO(117, 117, 117, 1), size: 10.sp), ], ), ), @@ -225,15 +260,18 @@ Widget $totalSubmitCountView(BuildContext context, HomeworkReviewState sateData) // 试题题号视图 @hwidget -Widget $questionNumberView(BuildContext context, HomeworkReviewLogic logic, HomeworkReviewState sateData) { +Widget $questionNumberView(BuildContext context, HomeworkReviewLogic logic, + HomeworkReviewState sateData) { final scrollControllerNum = useScrollController(); // 试题题号区域 useEffect(() { scrollControllerNum.addListener(() { - if (sateData.panQuestView == false) sateData.slide.value = scrollControllerNum.offset; + if (sateData.panQuestView == false) + sateData.slide.value = scrollControllerNum.offset; }); var listenVal = sateData.slide.listen((e) { - if (e != scrollControllerNum.offset && sateData.panQuestView == true) scrollControllerNum.jumpTo(e); + if (e != scrollControllerNum.offset && sateData.panQuestView == true) + scrollControllerNum.jumpTo(e); }); return () { @@ -271,13 +309,20 @@ Widget $questionNumberView(BuildContext context, HomeworkReviewLogic logic, Home return Container( height: boxHeight > actualImgHeight ? boxHeight : actualImgHeight, - padding: EdgeInsets.only(top: imageVal.remainingHeight > 0 ? imageVal.remainingHeight / 2 : 0), + padding: EdgeInsets.only( + top: imageVal.remainingHeight > 0 + ? imageVal.remainingHeight / 2 + : 0), child: Column( mainAxisAlignment: MainAxisAlignment.start, children: studentQuestions ?.asMap() .keys - .map((e) => $ScoringQuestionsView(logic, studentQuestions[e], imageVal.scaleRatio, studentQuestions)) + .map((e) => $ScoringQuestionsView( + logic, + studentQuestions[e], + imageVal.scaleRatio, + studentQuestions)) .toList() ?? [], ), @@ -290,7 +335,11 @@ Widget $questionNumberView(BuildContext context, HomeworkReviewLogic logic, Home // 单道题得分框 @hwidget Widget $scoringQuestionsView( - BuildContext context, HomeworkReviewLogic logic, StudentQuestions item, double scaleRatio, List? studentQuestions) { + BuildContext context, + HomeworkReviewLogic logic, + StudentQuestions item, + double scaleRatio, + List? studentQuestions) { var studentScore = useState(item.studentScore); useValueChanged(studentScore.value, (_, __) { @@ -299,7 +348,8 @@ Widget $scoringQuestionsView( // 校验是否自动提交 对于已经批阅过的试题 不重复自动提交 var annotateTime = logic.state.data.value?.annotateTime; if (annotateTime == null) { - var noRatingGiven = studentQuestions!.firstWhereOrNull((e) => e.studentScore == null); + var noRatingGiven = + studentQuestions!.firstWhereOrNull((e) => e.studentScore == null); if (noRatingGiven == null) logic.submit(context); } }); @@ -312,7 +362,9 @@ Widget $scoringQuestionsView( return () {}; }, []); - var padinVal = item.correctRate > 0 ? EdgeInsets.only(top: 6.4.h) : EdgeInsets.symmetric(vertical: 2.h); + var padinVal = item.correctRate > 0 + ? EdgeInsets.only(top: 6.4.h) + : EdgeInsets.symmetric(vertical: 2.h); return Container( height: item.height * scaleRatio, padding: EdgeInsets.zero, @@ -328,20 +380,24 @@ Widget $scoringQuestionsView( style: ElevatedButton.styleFrom( padding: EdgeInsets.zero, tapTargetSize: MaterialTapTargetSize.shrinkWrap, - backgroundColor: const Color.fromRGBO(237, 237, 237, 1), // 设置背景色 - shape: const RoundedRectangleBorder(borderRadius: BorderRadius.zero), // 去除圆角 + 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 ? const Color.fromRGBO(255, 152, 0, 1) : const Color.fromRGBO(114, 114, 114, 1), + color: studentScore.value == 2 + ? const Color.fromRGBO(255, 152, 0, 1) + : 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)), ), ), // 半 @@ -350,20 +406,24 @@ Widget $scoringQuestionsView( style: ElevatedButton.styleFrom( padding: EdgeInsets.zero, tapTargetSize: MaterialTapTargetSize.shrinkWrap, - backgroundColor: const Color.fromRGBO(237, 237, 237, 1), // 设置背景色 - shape: const RoundedRectangleBorder(borderRadius: BorderRadius.zero), // 去除圆角 + 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 ? const Color.fromRGBO(255, 152, 0, 1) : const Color.fromRGBO(114, 114, 114, 1), + color: studentScore.value == 1 + ? const Color.fromRGBO(255, 152, 0, 1) + : 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)), ), ), // 错 @@ -372,20 +432,24 @@ Widget $scoringQuestionsView( style: ElevatedButton.styleFrom( padding: EdgeInsets.zero, tapTargetSize: MaterialTapTargetSize.shrinkWrap, - backgroundColor: const Color.fromRGBO(237, 237, 237, 1), // 设置背景色 - shape: const RoundedRectangleBorder(borderRadius: BorderRadius.zero), // 去除圆角 + 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 ? const Color.fromRGBO(255, 152, 0, 1) : const Color.fromRGBO(114, 114, 114, 1), + color: studentScore.value == 0 + ? const Color.fromRGBO(255, 152, 0, 1) + : 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)), ), ), ], @@ -396,8 +460,11 @@ Widget $scoringQuestionsView( 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), + 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( @@ -407,7 +474,10 @@ Widget $scoringQuestionsView( alignment: MainAxisAlignment.center, progressColor: const Color.fromRGBO(76, 199, 147, 0.6), backgroundColor: const Color(0xFFB8C7CB).withOpacity(0.35), - center: quickText("${item.correctRate}%", size: 5.sp, align: TextAlign.center, color: Colors.white), + center: quickText("${item.correctRate}%", + size: 5.sp, + align: TextAlign.center, + color: Colors.white), ), ) ], @@ -419,13 +489,16 @@ Widget $scoringQuestionsView( } // 试题图片视图 -class QuestionImageView extends HookWidget with EventBusMixin { +class QuestionImageView extends HookWidget + with EventBusMixin { final double maxWidth; final double maxHeight; final HomeworkReviewLogic logic; final HomeworkReviewState sateData; final HomeworkReviewAnnotationsControlState annotationState; - QuestionImageView(this.maxWidth, this.maxHeight, this.sateData, this.annotationState, this.logic, {super.key}); + QuestionImageView(this.maxWidth, this.maxHeight, this.sateData, + this.annotationState, this.logic, + {super.key}); /// 获取数组指定倒数具体值的下标 int _findTargetIndex(List list, T target, [int reciprocal = 2]) { @@ -456,7 +529,8 @@ class QuestionImageView extends HookWidget with EventBusMixin(ImageStreamListener((ImageInfo info, bool _) { + var imageStreamListener = useState( + ImageStreamListener((ImageInfo info, bool _) { WidgetsBinding.instance.addPostFrameCallback((_) { sateData.imageScale.value = TestQuestionsImageInfo( templateId: sateData.data.value?.templateId, @@ -479,10 +553,17 @@ class QuestionImageView extends HookWidget with EventBusMixin( context: context, builder: (context1) { - return AlertDialog(content: quickText("是否撤销全部批注痕迹?"), actions: [ - TextButton(child: quickText("取消"), onPressed: () => Navigator.pop(context1, false)), - TextButton(child: quickText("确定", color: Theme.of(context).primaryColor), onPressed: () => Navigator.pop(context1, true)) - ]); + return AlertDialog( + content: quickText("是否撤销全部批注痕迹?"), + actions: [ + TextButton( + child: quickText("取消"), + onPressed: () => Navigator.pop(context1, false)), + TextButton( + child: quickText("确定", + color: Theme.of(context).primaryColor), + onPressed: () => Navigator.pop(context1, true)) + ]); }, ); if (res == true) vnHandWritings.value = []; @@ -492,17 +573,22 @@ class QuestionImageView extends HookWidget with EventBusMixin( context: context, builder: (context1) { - return AlertDialog(content: quickText("是否撤销上次批阅批注痕迹?"), actions: [ - TextButton(child: quickText("取消"), onPressed: () => Navigator.pop(context1, false)), - TextButton( - child: quickText("确定", color: Theme.of(context).primaryColor), - onPressed: () { - Navigator.pop(context1, true); - sateData.data.value?.zgtAnnotate = null; - sateData.data.value?.showZgtAnnotate = null; - }, - ) - ]); + return AlertDialog( + content: quickText("是否撤销上次批阅批注痕迹?"), + actions: [ + TextButton( + child: quickText("取消"), + onPressed: () => Navigator.pop(context1, false)), + TextButton( + child: quickText("确定", + color: Theme.of(context).primaryColor), + onPressed: () { + Navigator.pop(context1, true); + sateData.data.value?.zgtAnnotate = null; + sateData.data.value?.showZgtAnnotate = null; + }, + ) + ]); }, ); } @@ -517,17 +603,22 @@ class QuestionImageView extends HookWidget with EventBusMixin( context: context, builder: (context1) { - return AlertDialog(content: quickText("是否撤销上次批阅批注痕迹?"), actions: [ - TextButton(child: quickText("取消"), onPressed: () => Navigator.pop(context1, false)), - TextButton( - child: quickText("确定", color: Theme.of(context).primaryColor), - onPressed: () { - Navigator.pop(context1, true); - sateData.data.value?.zgtAnnotate = null; - sateData.data.value?.showZgtAnnotate = null; - }, - ) - ]); + return AlertDialog( + content: quickText("是否撤销上次批阅批注痕迹?"), + actions: [ + TextButton( + child: quickText("取消"), + onPressed: () => Navigator.pop(context1, false)), + TextButton( + child: quickText("确定", + color: Theme.of(context).primaryColor), + onPressed: () { + Navigator.pop(context1, true); + sateData.data.value?.zgtAnnotate = null; + sateData.data.value?.showZgtAnnotate = null; + }, + ) + ]); }, ); } @@ -548,7 +639,8 @@ class QuestionImageView extends HookWidget with EventBusMixin sateData.panQuestView = true, child: SingleChildScrollView( controller: scrollControllerQuestion, - physics: !annotationState.pen.value ? const BouncingScrollPhysics() : const NeverScrollableScrollPhysics(), + physics: !annotationState.pen.value + ? const BouncingScrollPhysics() + : const NeverScrollableScrollPhysics(), padding: EdgeInsets.zero, scrollDirection: Axis.vertical, // 设置垂直滚动 child: Container( - decoration: BoxDecoration( - boxShadow: [BoxShadow(color: Colors.grey.withOpacity(0.2), offset: Offset(-6.r, 1.r), blurRadius: 10.r, spreadRadius: 8.r)]), + decoration: BoxDecoration(boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.2), + offset: Offset(-6.r, 1.r), + blurRadius: 10.r, + spreadRadius: 8.r) + ]), child: Listener( behavior: HitTestBehavior.opaque, onPointerDown: (PointerDownEvent event) { @@ -604,9 +703,11 @@ class QuestionImageView extends HookWidget with EventBusMixin imageScale.actualImgHeight || dy < 0) return; // 检查笔记是否超出图片范围 + if (dy > imageScale.actualImgHeight || dy < 0) + return; // 检查笔记是否超出图片范围 - vnHandWritings.value = List.from(vnHandWritings.value)..add(localPosition); + vnHandWritings.value = List.from(vnHandWritings.value) + ..add(localPosition); sateData.handwritings = vnHandWritings.value; }, child: Stack( @@ -614,9 +715,12 @@ class QuestionImageView extends HookWidget with EventBusMixin Image(image: imageProvider, fit: BoxFit.fitWidth), + (_, imageProvider) => Image( + image: imageProvider, fit: BoxFit.fitWidth), ) : null, ), @@ -663,7 +768,8 @@ class DrawingPainter extends CustomPainter { for (int i = 0; i < pointsLength; i++) { Offset? offsetData = points[i]; Offset? nextOffsetData = pointsLength - 1 == i ? null : points[i + 1]; - if (offsetData != null && nextOffsetData != null) canvas.drawLine(offsetData, nextOffsetData, paintBrush); + if (offsetData != null && nextOffsetData != null) + canvas.drawLine(offsetData, nextOffsetData, paintBrush); } } 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 ebcd9d7..e130bc4 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 @@ -1,5 +1,4 @@ import 'dart:async'; -import 'dart:io'; import 'dart:ui' as ui; @@ -16,7 +15,6 @@ import 'package:making_school_asignment_app/common/mixins/request_tool_mixin.dar import 'package:making_school_asignment_app/common/utils/toast_utils.dart'; import 'package:making_school_asignment_app/common/utils/upload_oss_img_utils.dart'; import 'package:making_school_asignment_app/page/global_widget/my_text.dart'; -import 'package:making_school_asignment_app/page/home_page/children/job_report/widget/personnel_data_overview.dart'; // 数据 class HomeworkReviewState { @@ -63,7 +61,8 @@ class HomeworkReviewLogic extends GetxController with RequestToolMixin { late StreamSubscription _paramListen; late StreamSubscription _dataListen; final HomeworkReviewState state = HomeworkReviewState(); - final HomeworkReviewAnnotationsControlState annotationState = HomeworkReviewAnnotationsControlState(); + final HomeworkReviewAnnotationsControlState annotationState = + HomeworkReviewAnnotationsControlState(); @override void onInit() { @@ -93,9 +92,11 @@ class HomeworkReviewLogic extends GetxController with RequestToolMixin { } void getData() async { - var timerControl = Timer(const Duration(milliseconds: 300), () => ToastUtils.showLoading()); + var timerControl = Timer( + const Duration(milliseconds: 300), () => ToastUtils.showLoading()); try { - DoPaperDetailsResult? data = await getClient().getDoPaperDetails(state.param.value); + DoPaperDetailsResult? data = + await getClient().getDoPaperDetails(state.param.value); // var studentQuestions = data.studentQuestions; // // 第0个的下标数据不需要处理 // for (var i = 0; i < studentQuestions.length; i++) { @@ -107,8 +108,6 @@ class HomeworkReviewLogic extends GetxController with RequestToolMixin { state.data.value = data; state.handwritings = []; state.studentQuestions.value = data.studentQuestions; - - } catch (e) { print('获取数据报错了:$e'); ToastUtils.showError('获取试题数据出错,请重试'); @@ -118,7 +117,6 @@ class HomeworkReviewLogic extends GetxController with RequestToolMixin { ToastUtils.dismiss(); } - } // 取消全部评分 @@ -170,12 +168,16 @@ class HomeworkReviewLogic extends GetxController with RequestToolMixin { if (data == null) return null; // 获取OSS 图片url - String imgKey = UploadOssImgUtils.getInstance().setImgKey(param.homeworkId, data.studentId.toString(), data.templateId.toString()); + String imgKey = UploadOssImgUtils.getInstance().setImgKey( + param.homeworkId, + data.studentId.toString(), + data.templateId.toString()); var resUrl = await getClient().getOssPresignedUri(imgKey); if (resUrl == null) return null; // 没有图片就上传图片 - RenderRepaintBoundary? boundary = pictureOverviewKey.currentContext!.findRenderObject() as RenderRepaintBoundary?; + RenderRepaintBoundary? boundary = pictureOverviewKey.currentContext! + .findRenderObject() as RenderRepaintBoundary?; if (boundary == null) return null; // double dpr = MediaQuery.of(context).devicePixelRatio; @@ -187,16 +189,20 @@ class HomeworkReviewLogic extends GetxController with RequestToolMixin { } ui.Image image = await boundary.toImage(pixelRatio: pixelRatio); - ByteData? byteData = await image.toByteData(format: ui.ImageByteFormat.png); + ByteData? byteData = + await image.toByteData(format: ui.ImageByteFormat.png); if (byteData == null) return null; Dio dio = Dio(); dio.options.contentType = null; - List bytes = byteData.buffer.asUint8List(byteData.offsetInBytes, byteData.lengthInBytes); + List bytes = byteData.buffer + .asUint8List(byteData.offsetInBytes, byteData.lengthInBytes); await dio.put( resUrl, data: Stream.fromIterable(bytes.map((e) => [e])), - options: Options(contentType: null, headers: {Headers.contentLengthHeader: bytes.length}), + options: Options( + contentType: null, + headers: {Headers.contentLengthHeader: bytes.length}), ); return imgKey; @@ -218,7 +224,8 @@ class HomeworkReviewLogic extends GetxController with RequestToolMixin { if (state.data.value?.studentQuestions.isEmpty ?? true) return; var studentQuestions = state.data.value!.studentQuestions; - var noRatingElement = studentQuestions.firstWhereOrNull((e) => e.studentScore == null); + var noRatingElement = + studentQuestions.firstWhereOrNull((e) => e.studentScore == null); if (noRatingElement != null) { ToastUtils.showInfo('${noRatingElement.questionNo}题请评分'); return; @@ -247,7 +254,7 @@ class HomeworkReviewLogic extends GetxController with RequestToolMixin { .then((e) async { state.needRefresh = true; var totalUnAnnotateCount = data.totalUnAnnotateCount; - if (data.annotateTime == null) totalUnAnnotateCount -= 1; + if (data.needAnnotate) totalUnAnnotateCount -= 1; // 是否需要批阅 if (totalUnAnnotateCount <= 0 && !state.lastQuestionPrompt) { // 批阅完成 @@ -256,7 +263,7 @@ class HomeworkReviewLogic extends GetxController with RequestToolMixin { builder: (BuildContext context1) { return AlertDialog( title: quickText('批阅已完成'), - content: const Text('暂无更多待批阅项'), + content: const Text('暂无更多批阅项'), actions: [ TextButton( child: const Text('继续'), diff --git a/making_school_asignment_app/lib/page/home_page/children/homework_review/index.dart b/making_school_asignment_app/lib/page/home_page/children/homework_review/index.dart index e04bc97..85d1aaa 100644 --- a/making_school_asignment_app/lib/page/home_page/children/homework_review/index.dart +++ b/making_school_asignment_app/lib/page/home_page/children/homework_review/index.dart @@ -1,13 +1,12 @@ import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import 'package:making_school_asignment_app/page/global_widget/ReturnToHomepage.dart'; import 'package:making_school_asignment_app/page/global_widget/my_text.dart'; import 'package:making_school_asignment_app/page/home_page/children/annotate_class/annotate_class_logic.dart'; +import 'package:making_school_asignment_app/page/home_page/home_logic.dart'; import 'components/bottom_operation_bar.dart'; -import 'components/button_floating_action.dart'; import 'components/dropdown_switch_students_type.dart'; import 'components/favorite_widget.dart'; import 'components/question_paper_view.dart'; @@ -24,6 +23,7 @@ class _HomeworkReviewState extends State { final logic = Get.find(); final sateData = Get.find().state; final AnnotateClassLogic _controller = Get.find(); + final HomeLogic _homeLogicController = Get.find(); @override void initState() { @@ -42,18 +42,27 @@ class _HomeworkReviewState extends State { return PopScope( canPop: false, onPopInvoked: (e) { - if (e && sateData.needRefresh) _controller.getList(); + if (e && sateData.needRefresh) { + _controller.getList(); + _homeLogicController.getList(); + } }, child: SafeArea( child: Scaffold( appBar: AppBar( // titleSpacing: 0, - leading: IconButton(icon: const Icon(Icons.arrow_back_ios), onPressed: () => Get.back()), + leading: IconButton( + icon: const Icon(Icons.arrow_back_ios), + onPressed: () => Get.back()), iconTheme: const IconThemeData(color: Colors.black), title: quickText(sateData.param.value.homeworkName), backgroundColor: Colors.white, elevation: 0, - actions: [const FavoriteWidget(), SizedBox(width: 5.w), const ReturnToHomepage()], + actions: [ + const FavoriteWidget(), + SizedBox(width: 5.w), + const ReturnToHomepage() + ], ), body: SafeArea( child: Column( diff --git a/making_school_asignment_app/lib/page/home_page/children/my_info.dart b/making_school_asignment_app/lib/page/home_page/children/my_info.dart index 7aeaf43..01fbeb5 100644 --- a/making_school_asignment_app/lib/page/home_page/children/my_info.dart +++ b/making_school_asignment_app/lib/page/home_page/children/my_info.dart @@ -26,26 +26,31 @@ class _MyInfoState extends State with AutomaticKeepAliveClientMixin { barrierDismissible: false, context: context1, builder: (context) { - return AlertDialog(title: quickText("提示信息"), content: quickText("您确定要退出登录吗?"), actions: [ - TextButton( - child: quickText("取消"), - onPressed: () { - Navigator.pop(context, 'Cancle'); - }, - ), - TextButton( - child: quickText("确定"), - onPressed: () { - /* ref.read(markingKeyboardProvider.notifier).clean(); - ref.read(markingSubtopicSwitchingProvider.notifier).clean(); - ref.read(userTokenProvider.notifier).clean(); - ref.read(userProvider.notifier).clean();*/ - StorageService.to.remove(AppStorageKey.token.value); - StorageService.to.remove(AppStorageKey.userInfo.value); - Navigator.pop(context, "Ok"); - Get.offAllNamed(Routes.login); - }) - ]); + return AlertDialog( + title: quickText("提示信息"), + content: quickText("您确定要退出登录吗?"), + actions: [ + TextButton( + child: quickText("取消"), + onPressed: () { + Navigator.pop(context, 'Cancle'); + }, + ), + TextButton( + child: quickText("确定"), + onPressed: () async { + try { + UserStore.to.erase(); + await StorageService.to.erase(); + StorageService.to + .write(AppStorageKey.privacyAgreement.value, true); + Navigator.pop(context, "Ok"); + Get.offAllNamed(Routes.login); + } catch (e) { + print(e); + } + }) + ]); }); } @@ -65,119 +70,121 @@ class _MyInfoState extends State with AutomaticKeepAliveClientMixin { fontSize: 13.sp, ); - return OrientationBuilder(builder: (BuildContext context, Orientation orientation) { - return AnnotatedRegion( - value: const SystemUiOverlayStyle( - statusBarColor: Colors.transparent, - systemNavigationBarIconBrightness: Brightness.light, - statusBarIconBrightness: Brightness.light, - statusBarBrightness: Brightness.dark, - ), - child: Stack( - children: [ - SizedBox( - height: double.infinity, - child: Column( - children: [ - Container( - height: 220.h, - width: double.infinity, - decoration: const BoxDecoration( - image: DecorationImage( - image: AssetImage('assets/images/personal_bgi.png'), - fit: BoxFit.cover, - ), + return OrientationBuilder( + builder: (BuildContext context, Orientation orientation) { + return Stack( + children: [ + SizedBox( + height: double.infinity, + child: Column( + children: [ + Container( + height: 220.h, + width: double.infinity, + decoration: const BoxDecoration( + image: DecorationImage( + image: AssetImage('assets/images/personal_bgi.png'), + fit: BoxFit.cover, ), ), - Expanded( - child: Container( - color: const Color.fromRGBO(248, 248, 248, 1), - )) - ], - ), + ), + Expanded( + child: Container( + color: const Color.fromRGBO(248, 248, 248, 1), + )) + ], ), - SafeArea( - child: Scaffold( - backgroundColor: Colors.transparent, - body: Column( - children: [ - Stack( - alignment: const FractionalOffset(0.04, 0.1), - children: [ - Container( - height: 180.h, - alignment: Alignment.center, - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - SizedBox( - height: 10.r, - ), - Image.asset( - 'assets/images/default_user_dead.png', - ), - SizedBox( - height: 10.r, - ), - InkWell( - onTap: () { - /*if (tokenState == '' || userState.id == '') { + ), + SafeArea( + child: Scaffold( + backgroundColor: Colors.transparent, + body: Column( + children: [ + Stack( + alignment: const FractionalOffset(0.04, 0.1), + children: [ + Container( + height: 180.h, + alignment: Alignment.center, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SizedBox( + height: 10.r, + ), + Image.asset( + 'assets/images/default_user_dead.png', + ), + SizedBox( + height: 10.r, + ), + InkWell( + onTap: () { + /*if (tokenState == '' || userState.id == '') { toLoginPage(context); }*/ - }, - child: Container( - margin: EdgeInsets.only(top: 0.h), - child: Text( - userInfo.value?.name ?? '请前往登录', - style: TextStyle(fontSize: 13.sp, color: Colors.white), - ), + }, + child: Container( + margin: EdgeInsets.only(top: 0.h), + child: Text( + userInfo.value?.name ?? '请前往登录', + style: TextStyle( + fontSize: 13.sp, color: Colors.white), ), ), - ], - ), + ), + ], ), - /* InkWell( + ), + /* InkWell( onTap: () => Get.back(), child: Icon(Icons.arrow_back_ios_new_rounded, color: Colors.white, size: 24.sp), ),*/ + ], + ), + SizedBox(height: 14.h), + Container( + margin: + EdgeInsets.symmetric(vertical: 22.h, horizontal: 16.w), + padding: + EdgeInsets.symmetric(vertical: 22.h, horizontal: 16.w), + height: 180.h, + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(6.w)), + color: Colors.white, + boxShadow: const [ + BoxShadow( + color: Color.fromRGBO(46, 91, 255, 0.1), + offset: Offset.zero, //阴影y轴偏移量 + blurRadius: 20, //阴影模糊程度 + spreadRadius: 10, //阴影扩散程度 + ) ], ), - SizedBox(height: 14.h), - Container( - margin: EdgeInsets.symmetric(vertical: 22.h, horizontal: 16.w), - padding: EdgeInsets.symmetric(vertical: 22.h, horizontal: 16.w), - height: 180.h, - decoration: BoxDecoration( - borderRadius: BorderRadius.all(Radius.circular(6.w)), - color: Colors.white, - boxShadow: const [ - BoxShadow( - color: Color.fromRGBO(46, 91, 255, 0.1), - offset: Offset.zero, //阴影y轴偏移量 - blurRadius: 20, //阴影模糊程度 - spreadRadius: 10, //阴影扩散程度 - ) - ], - ), - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [Text('账号', style: personalInfoTitleStly), Text(userInfo.value?.name ?? '请前往登录', style: personalInfoValStly)], - ), - Container( - height: 1.w, - color: const Color.fromRGBO(240, 243, 255, 1), - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text('所在学校', style: personalInfoTitleStly), - Text(userInfo.value?.schoolName ?? '', style: personalInfoValStly) - ], - ), - /* Row( + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text('账号', style: personalInfoTitleStly), + Text(userInfo.value?.name ?? '请前往登录', + style: personalInfoValStly) + ], + ), + Container( + height: 1.w, + color: const Color.fromRGBO(240, 243, 255, 1), + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text('所在学校', style: personalInfoTitleStly), + Text(userInfo.value?.schoolName ?? '', + style: personalInfoValStly) + ], + ), + /* Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text('担任职位', style: personalInfoTitleStly), @@ -209,87 +216,93 @@ class _MyInfoState extends State with AutomaticKeepAliveClientMixin { ) ], ),*/ - Container(height: 1.w, color: const Color.fromRGBO(240, 243, 255, 1)), - Padding( - padding: EdgeInsets.only(top: 10.h), - child: InkWell( - onTap: () { - Get.toNamed(Routes.otherPage); - }, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text('其他', style: personalInfoTitleStly), - Icon( - Icons.arrow_forward_ios, - color: const Color.fromRGBO(80, 87, 103, 1), - size: 13.sp, + Container( + height: 1.w, + color: const Color.fromRGBO(240, 243, 255, 1)), + Padding( + padding: EdgeInsets.only(top: 10.h), + child: InkWell( + onTap: () { + Get.toNamed(Routes.otherPage); + }, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text('其他', style: personalInfoTitleStly), + Icon( + Icons.arrow_forward_ios, + color: const Color.fromRGBO(80, 87, 103, 1), + size: 13.sp, + ) + ], + ), + ), + ) + ], + ), + ), + Expanded( + child: Column( + children: [ + const Expanded(child: SizedBox()), + Container( + margin: EdgeInsets.only(bottom: 40.h), + alignment: Alignment.bottomCenter, + child: InkWell( + child: Container( + padding: EdgeInsets.symmetric(vertical: 14.h), + margin: EdgeInsets.only(right: 16.w, left: 16.w), + decoration: BoxDecoration( + borderRadius: BorderRadius.all( + Radius.circular(6.w), + ), + color: Colors.white, + boxShadow: [ + BoxShadow( + color: + const Color.fromRGBO(46, 91, 255, 0.2), + offset: Offset(2.w, 2.h), //阴影y轴偏移量 + blurRadius: 14, //阴影模糊程度 + spreadRadius: 0.5, //阴影扩散程度 ) ], ), - ), - ) - ], - ), - ), - Expanded( - child: Column( - children: [ - const Expanded(child: SizedBox()), - Container( - margin: EdgeInsets.only(bottom: 40.h), - alignment: Alignment.bottomCenter, - child: InkWell( - child: Container( - padding: EdgeInsets.symmetric(vertical: 14.h), - margin: EdgeInsets.only(right: 16.w, left: 16.w), - decoration: BoxDecoration( - borderRadius: BorderRadius.all( - Radius.circular(6.w), + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon( + Icons.exit_to_app_outlined, + size: 13.sp, + color: + const Color.fromRGBO(148, 163, 182, 1), ), - color: Colors.white, - boxShadow: [ - BoxShadow( - color: const Color.fromRGBO(46, 91, 255, 0.2), - offset: Offset(2.w, 2.h), //阴影y轴偏移量 - blurRadius: 14, //阴影模糊程度 - spreadRadius: 0.5, //阴影扩散程度 - ) - ], - ), - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Icon( - Icons.exit_to_app_outlined, - size: 13.sp, - color: const Color.fromRGBO(148, 163, 182, 1), - ), - Container( - width: 6.w, - ), - Text( - '退出登录', - style: TextStyle(color: const Color.fromRGBO(148, 163, 182, 1), fontSize: 13.sp), - ), - ], - ), + Container( + width: 6.w, + ), + Text( + '退出登录', + style: TextStyle( + color: const Color.fromRGBO( + 148, 163, 182, 1), + fontSize: 13.sp), + ), + ], ), - onTap: () { - _showAlertDialog(context); - }, ), + onTap: () { + _showAlertDialog(context); + }, ), - ], - ), + ), + ], ), - ], - ), + ), + ], ), ), - ], - ), + ), + ], ); }); } diff --git a/making_school_asignment_app/lib/page/home_page/children/read_over/read_over_view.dart b/making_school_asignment_app/lib/page/home_page/children/read_over/read_over_view.dart index 4160a73..7b0aeaa 100644 --- a/making_school_asignment_app/lib/page/home_page/children/read_over/read_over_view.dart +++ b/making_school_asignment_app/lib/page/home_page/children/read_over/read_over_view.dart @@ -27,9 +27,7 @@ class ReadOverPage extends StatefulWidget { class _ReadOverPageState extends State { final logic = Get.find(); - final state = Get - .find() - .state; + final state = Get.find().state; @override Widget build(BuildContext context) { @@ -39,7 +37,7 @@ class _ReadOverPageState extends State { systemNavigationBarDividerColor: null, statusBarColor: Colors.white, systemNavigationBarIconBrightness: Brightness.light, - statusBarIconBrightness: Brightness.dark, + statusBarIconBrightness: Brightness.light, statusBarBrightness: Brightness.light, ), child: Scaffold( @@ -50,10 +48,7 @@ class _ReadOverPageState extends State { children: [ Container( color: Colors.white, - margin: EdgeInsets.only(top: MediaQuery - .of(context) - .padding - .top), + margin: EdgeInsets.only(top: MediaQuery.of(context).padding.top), padding: EdgeInsets.only(bottom: 9.h, top: 4.h), child: Row( crossAxisAlignment: CrossAxisAlignment.center, @@ -98,12 +93,10 @@ class _ReadOverPageState extends State { color: const Color(0xFF4CC793), ), // labelColor: const Color.fromRGBO(45, 56, 76, 1), - indicator: const UnderlineTabIndicator( + indicator: const UnderlineTabIndicator( borderSide: BorderSide( - width: 0, // 设置边界宽度为0,从而去除下划线 - color: Colors.transparent - ), - + width: 0, // 设置边界宽度为0,从而去除下划线 + color: Colors.transparent), ), onTap: (index) { state.tabIndex.value = index; @@ -122,23 +115,14 @@ class _ReadOverPageState extends State { width: 140.w, alignment: Alignment.center, decoration: BoxDecoration( - color: state.tabIndex.value == 0 - ? const Color.fromRGBO( - 255, 255, 255, 1) - : null, - borderRadius: BorderRadius.all( - Radius.circular(8.r)), + color: state.tabIndex.value == 0 ? const Color.fromRGBO(255, 255, 255, 1) : null, + borderRadius: BorderRadius.all(Radius.circular(8.r)), ), child: quickText( '待批阅', size: 14.sp, - color: state.tabIndex.value == 0 ? Theme - .of(context) - .primaryColor : const Color.fromRGBO( - 80, 94, 110, 1), - fontWeight: state.tabIndex.value == 0 - ? FontWeight.bold - : null, + color: state.tabIndex.value == 0 ? Theme.of(context).primaryColor : const Color.fromRGBO(80, 94, 110, 1), + fontWeight: state.tabIndex.value == 0 ? FontWeight.bold : null, ), ); }), @@ -151,23 +135,14 @@ class _ReadOverPageState extends State { width: 140.w, alignment: Alignment.center, decoration: BoxDecoration( - color: state.tabIndex.value == 1 - ? const Color.fromRGBO( - 255, 255, 255, 1) - : null, - borderRadius: BorderRadius.all( - Radius.circular(8.r)), + color: state.tabIndex.value == 1 ? const Color.fromRGBO(255, 255, 255, 1) : null, + borderRadius: BorderRadius.all(Radius.circular(8.r)), ), child: quickText( '已批阅', size: 14.sp, - color: state.tabIndex.value == 1 ? Theme - .of(context) - .primaryColor : const Color.fromRGBO( - 80, 94, 110, 1), - fontWeight: state.tabIndex.value == 1 - ? FontWeight.bold - : null, + color: state.tabIndex.value == 1 ? Theme.of(context).primaryColor : const Color.fromRGBO(80, 94, 110, 1), + fontWeight: state.tabIndex.value == 1 ? FontWeight.bold : null, ), ); }), @@ -180,22 +155,22 @@ class _ReadOverPageState extends State { flex: 1, child: InkWell( onTap: () { - Get.toNamed(Routes.studentHistoryWorkPage, - arguments: {'page': 'set'}); + Get.toNamed(Routes.studentHistoryWorkPage, arguments: {'page': 'set'}); }, - child: Icon( - const IconData(0xe63e, fontFamily: "AlibabaIcon"), - color: const Color.fromRGBO(44, 48, 63, 1), - size: 24.sp), + child: Icon(const IconData(0xe63e, fontFamily: "AlibabaIcon"), color: const Color.fromRGBO(44, 48, 63, 1), size: 24.sp), ), ), ], ), ), - Expanded(child: Obx(() { - return AnnotateList(tabIndex: state.tabIndex.value,assessType: 0,); - }),), - + Expanded( + child: Obx(() { + return AnnotateList( + tabIndex: state.tabIndex.value, + assessType: 0, + ); + }), + ), ], ); }, diff --git a/making_school_asignment_app/lib/page/home_page/home_view.dart b/making_school_asignment_app/lib/page/home_page/home_view.dart index e52a1b0..da9f6a6 100644 --- a/making_school_asignment_app/lib/page/home_page/home_view.dart +++ b/making_school_asignment_app/lib/page/home_page/home_view.dart @@ -18,7 +18,7 @@ import 'home_logic.dart'; part 'home_view.g.dart'; class HomePage extends StatefulWidget { - const HomePage({Key? key}) : super(key: key); + const HomePage({super.key}); @override State createState() => _HomePageState(); @@ -31,20 +31,20 @@ class _HomePageState extends State with AutomaticKeepAliveClientMixin @override bool get wantKeepAlive => true; + @override + void initState() { + super.initState(); + SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle( + statusBarIconBrightness: Brightness.dark, + systemStatusBarContrastEnforced: false, + )); + } + @override Widget build(BuildContext context) { super.build(context); var spaceWidth = SizedBox(height: ScreenUtil().screenWidth / 30); return SafeArea( - child: AnnotatedRegion( - value: const SystemUiOverlayStyle( - systemNavigationBarColor: Color(0xFF000000), - systemNavigationBarDividerColor: null, - statusBarColor: Colors.white, - systemNavigationBarIconBrightness: Brightness.light, - statusBarIconBrightness: Brightness.dark, - statusBarBrightness: Brightness.light, - ), child: OrientationBuilder( builder: (BuildContext context, Orientation orientation) { return EasyRefresh( @@ -78,7 +78,7 @@ class _HomePageState extends State with AutomaticKeepAliveClientMixin ), ), ),*/ - SizedBox(height: MediaQuery. of(context).padding.top / 2), + SizedBox(height: MediaQuery.of(context).padding.top / 2), Obx(() { return $TermRow([ EntranceModel(title: '作业批阅', image: 'assets/images/job_home_marking.png', navigationUrl: Routes.readOverPage), @@ -115,134 +115,138 @@ class _HomePageState extends State with AutomaticKeepAliveClientMixin Obx(() { return Container( padding: EdgeInsets.symmetric(horizontal: 12.w), - child: state.workList.isNotEmpty?Column( - children: List.generate(state.workList.length, (index) { - Items item = state.workList[index]; - return InkWell( - onTap: () { - Get.toNamed(Routes.annotateClassPage, arguments: { - 'id': item.id, - 'name': item.name, - 'grade': item.grade, - 'subject': item.subject, - }); - }, - child: Container( - margin: EdgeInsets.only(bottom: 15.h), - child: Column( - children: [ - SizedBox(height: 4.h), - Container( - padding: EdgeInsets.symmetric(vertical: 15.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: state.workList.isNotEmpty + ? Column( + children: List.generate(state.workList.length, (index) { + Items item = state.workList[index]; + return InkWell( + onTap: () { + Get.toNamed(Routes.annotateClassPage, arguments: { + 'id': item.id, + 'name': item.name, + 'grade': item.grade, + 'subject': item.subject, + }); + }, + child: Container( + margin: EdgeInsets.only(bottom: 15.h), 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(0xFF4CC793) : 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), - ), + SizedBox(height: 4.h), + Container( + padding: EdgeInsets.symmetric(vertical: 15.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(0xFF4CC793) : 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(top: 3.h, 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, + ), + ) + ], ), - margin: EdgeInsets.only(top:3.h,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), + Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + quickText('题量:', color: const Color.fromRGBO(130, 130, 130, 1), size: 11.sp), + quickText( + '${item.questionCount! - item.annotateCount!}', + 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( - 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), - Row( - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - quickText('题量:', color: const Color.fromRGBO(130, 130, 130, 1), size: 11.sp), - quickText( - '${item.questionCount! - item.annotateCount!}', - 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(0xFF4CC793), - backgroundColor: const Color(0xFFE8E8E8), - barRadius: Radius.circular(10.r), - ), + 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(0xFF4CC793), + 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)), + ], ), - ), - SizedBox( - width: 10.r, - ), - quickText('${item.annotateRate!.toStringAsFixed(0)}%', size: 10.sp, color: const Color(0xFF464646)), - ], + // FavoriteButton(jobTaskItem.id, jobTaskItem.title), + ], + ), ), - // FavoriteButton(jobTaskItem.id, jobTaskItem.title), ], ), ), - ], - ), - ), - ); - }), - ):const MyEmptyWidget(), + ); + }), + ) + : const MyEmptyWidget(), ); }), ], @@ -250,7 +254,7 @@ class _HomePageState extends State with AutomaticKeepAliveClientMixin ); }, ), - )); + ); } @override diff --git a/making_school_asignment_app/lib/page/login_page/children/register.dart b/making_school_asignment_app/lib/page/login_page/children/register.dart new file mode 100644 index 0000000..a8ea5d4 --- /dev/null +++ b/making_school_asignment_app/lib/page/login_page/children/register.dart @@ -0,0 +1,281 @@ +import 'package:dio/dio.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_easyloading/flutter_easyloading.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:get/get.dart'; +import 'package:making_school_asignment_app/common/const_text.dart'; +import 'package:making_school_asignment_app/common/job/user_register_params.dart'; +import 'package:making_school_asignment_app/common/mixins/request_tool_mixin.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:making_school_asignment_app/routes/app_pages.dart'; + +/// 注册页面 +class Register extends StatefulWidget { + const Register({super.key}); + + @override + State createState() => _RegisterState(); +} + +class _RegisterState extends State with RequestToolMixin { + late final FocusNode _theFocus; + late final FocusNode _pwdFocus; // 密码 + //文本输入框控制器 + late final TextEditingController _userNameController; + late final TextEditingController _passwordController; + + bool readAgreement = false; // 阅读协议 + bool _isShowPwd = true; + bool canLogin = true; + + @override + void initState() { + super.initState(); + _userNameController = TextEditingController(); + _passwordController = TextEditingController(); + _pwdFocus = FocusNode(); + _theFocus = FocusNode(); + } + + @override + void dispose() { + super.dispose(); + _userNameController.dispose(); + _passwordController.dispose(); + _pwdFocus.dispose(); + _theFocus.dispose(); + } + + void toRegister() async { + if (!canLogin) return; + setState(() => canLogin = false); + void toMsg(msg) { + Future.delayed(Duration.zero, () => ToastUtils.showError(msg)); + setState(() => canLogin = true); + } + + FocusScope.of(context).requestFocus(_theFocus); + try { + String userName = _userNameController.text.trim(); + String userPwd = _passwordController.text.trim(); + if (userName == '') return toMsg('请填写用户账号'); + if (userPwd == '') return toMsg('请填写密码'); + if (userPwd.length < 6) return toMsg('密码长度不得少于6位'); + if (!readAgreement) return toMsg('请勾选我已阅读用户协议和隐私协议'); + EasyLoading.show(status: 'loading...'); + var resultData = await getClient().toRegister(UserRegisterParams(account: userName, password: userPwd)); + print(resultData); + // if (resultData.success) return toMsg(resultData.message ?? '注册失败,请重试'); + ToastUtils.showSuccess('注册成功,请登录'); + // 跳转登录页 + Future.delayed(Duration.zero, () => Get.back()); + } catch (e) { + setState(() => canLogin = true); + } finally { + EasyLoading.dismiss(); + } + } + + void _showPassword() { + setState(() { + _isShowPwd = !_isShowPwd; + }); + } + + @override + Widget build(BuildContext context) { + return GestureDetector( + behavior: HitTestBehavior.translucent, + onTap: () { + FocusScope.of(context).requestFocus(_theFocus); + }, + child: AnnotatedRegion( + value: const SystemUiOverlayStyle( + statusBarColor: Colors.transparent, + systemNavigationBarIconBrightness: Brightness.light, + statusBarIconBrightness: Brightness.light, + statusBarBrightness: Brightness.dark, + ), + child: Scaffold( + backgroundColor: Colors.transparent, + resizeToAvoidBottomInset: false, + body: Stack( + children: [ + Container( + width: double.infinity, + height: double.infinity, + alignment: Alignment.center, + decoration: const BoxDecoration( + image: DecorationImage( + image: AssetImage('assets/images/login_bg.png'), + fit: BoxFit.fill, // 完全填充 + ), + ), + child: SingleChildScrollView( + child: Column( + children: [ + Container( + width: 86.w, + height: 86.w, + alignment: Alignment.center, + child: SizedBox( + height: 86.w, + width: 86.w, + child: Image.asset('assets/images/login_logo.png', fit: BoxFit.cover), + ), + ), + Container( + margin: EdgeInsets.symmetric(horizontal: 32.w, vertical: 24.h), + padding: EdgeInsets.only(top: 34.h, bottom: 16.h, left: 22.w, right: 22.w), + decoration: BoxDecoration( + color: Colors.white, + border: Border.all(width: 1.w, color: Colors.white), + borderRadius: BorderRadius.all(Radius.circular(10.w)), + boxShadow: const [ + BoxShadow( + color: Color.fromRGBO(46, 91, 255, 0.1), + offset: Offset.zero, //阴影y轴偏移量 + blurRadius: 100, //阴影模糊程度 + spreadRadius: 100, //阴影扩散程度 + ) + ], + ), + child: Column(children: [ + TextField( + controller: _userNameController, + maxLines: 1, + maxLength: 20, + textInputAction: TextInputAction.next, + onEditingComplete: () { + FocusScope.of(context).requestFocus(_pwdFocus); + }, + style: TextStyle( + color: const Color.fromRGBO(80, 87, 103, 1), + fontSize: 15.sp, + ), + decoration: InputDecoration( + hintText: "请输入账号", + hintStyle: TextStyle(fontSize: 16.sp, color: const Color.fromRGBO(153, 153, 153, 1)), + labelText: "账号", + labelStyle: TextStyle(fontSize: 16.sp, color: const Color.fromRGBO(148, 163, 182, 1)), + ), + ), + TextField( + focusNode: _pwdFocus, + controller: _passwordController, + keyboardType: TextInputType.number, + maxLines: 1, + obscureText: _isShowPwd, //隐藏密码显示 + textInputAction: TextInputAction.go, + onSubmitted: (_) => toRegister(), + style: TextStyle( + color: const Color.fromRGBO(80, 87, 103, 1), + fontSize: 15.sp, + ), + decoration: InputDecoration( + hintText: "请输入密码", + suffix: GestureDetector( + onTap: _showPassword, + child: Icon( + Icons.remove_red_eye, + color: !_isShowPwd ? Theme.of(context).primaryColor : Colors.grey, + ), + ), + hintStyle: TextStyle(fontSize: 16.sp, color: const Color.fromRGBO(153, 153, 153, 1)), + labelText: "密码", + isDense: true, + labelStyle: TextStyle(fontSize: 16.sp, color: const Color.fromRGBO(148, 163, 182, 1)), + ), + ), + SizedBox( + height: 12.h, + ), + InkWell( + onTap: toRegister, + child: Container( + margin: EdgeInsets.symmetric(vertical: 10.h), + decoration: BoxDecoration( + color: canLogin ? Theme.of(context).primaryColor : Colors.grey, + boxShadow: [ + BoxShadow( + color: const Color.fromRGBO(76, 199, 147, 0.5), + offset: Offset(4.w, 6.h), //阴影y轴偏移量 + blurRadius: 10, //阴影模糊程度 + spreadRadius: 0.5, //阴影扩散程度 + ) + ], + borderRadius: BorderRadius.all( + Radius.circular(8.w), + ), + ), + alignment: Alignment.center, + width: double.infinity, + height: 50.h, + child: Text( + '注 册', + style: TextStyle(fontSize: 16.sp, color: Colors.white), + ), + ), + ), + Row( + children: [ + Container( + width: 30.w, + padding: EdgeInsets.only(right: 10.w), + child: Checkbox( + activeColor: Colors.deepOrangeAccent, + checkColor: Colors.white, + value: readAgreement, + onChanged: (value) { + FocusScope.of(context).requestFocus(_pwdFocus); + FocusScope.of(context).requestFocus(_theFocus); + setState(() { + readAgreement = value ?? false; + }); + }, + ), + ), + InkWell( + onTap: () { + // RouterManager.router.navigateTo( + // context, + // '${RouterManager.agreementPath}?type=${AGREEMENT_KEY.USER_AGREEMENT.name}', + // transition: getTransition(), + // ); + }, + child: quickText('我已阅读', size: 11.sp), + ), + InkWell( + onTap: () { + Get.toNamed(Routes.agreementPage, arguments: {"type": AGREEMENT_KEY.USER_AGREEMENT.name}); + }, + child: quickText( + '《用户协议》', + size: 12.sp, + color: Colors.deepOrangeAccent, + ), + ), + ], + ), + ]), + ) + ], + ), + )), + Positioned( + top: MediaQuery.of(context).padding.top + 20.r, + left: 20.r, + child: InkWell( + onTap: () => Navigator.pop(context), + child: Icon(Icons.arrow_back_ios_new_rounded, color: Colors.white, size: 24.sp), + ), + ), + ], + ), + ), + ), + ); + } +} diff --git a/making_school_asignment_app/lib/page/login_page/children/sys_protocol.dart b/making_school_asignment_app/lib/page/login_page/children/sys_protocol.dart new file mode 100644 index 0000000..e79b358 --- /dev/null +++ b/making_school_asignment_app/lib/page/login_page/children/sys_protocol.dart @@ -0,0 +1,167 @@ +import 'dart:io'; +import 'package:get/get.dart'; +import 'package:flutter/gestures.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:making_school_asignment_app/common/const_text.dart'; +import 'package:making_school_asignment_app/common/store/app_storage_key.dart'; +import 'package:making_school_asignment_app/common/utils/storage.dart'; +import 'package:making_school_asignment_app/common/utils/utils.dart'; +import 'package:making_school_asignment_app/page/global_widget/my_text.dart'; +import 'package:making_school_asignment_app/routes/app_pages.dart'; + +class Protocol extends Dialog { + final BuildContext context; + const Protocol(this.context, {super.key}); + + @override + Widget build(BuildContext context) { + return Center( + child: Container( + width: isPad() ? 200.w : 260.w, + height: 400.h, + padding: EdgeInsets.symmetric(vertical: 16.h), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(12.r), + ), + child: Column( + children: [ + quickText('用户协议与隐私政策', + size: 15.sp, + color: const Color.fromRGBO(37, 37, 37, 1), + fontWeight: FontWeight.bold), + Expanded( + child: ListView( + physics: const BouncingScrollPhysics(), + padding: EdgeInsets.fromLTRB(16.w, 14.h, 16.w, 10.h), + children: [ + Text.rich(TextSpan(children: [ + TextSpan( + text: + '感谢您选择点智学APP ! 我们非常重视您的个人信息和隐私保护。为了更好地保障您的个人权益,在您使用我们的产品前,请务必审慎阅读', + style: TextStyle( + fontSize: 13.sp, + color: const Color.fromRGBO(51, 51, 51, 1)), + ), + TextSpan( + text: '《隐私政策》', + style: TextStyle( + fontSize: 13.sp, + color: Theme.of(context).primaryColor), + recognizer: TapGestureRecognizer() + ..onTap = () async { + Get.toNamed(Routes.agreementPage, arguments: { + "type": AGREEMENT_KEY.PRIVACY_GREEMENT.name + }); + // RouterManager.router.navigateTo( + // context, + // '${RouterManager.agreementPath}?type=${AGREEMENT_KEY.PRIVACY_GREEMENT.name}', + // transition: getTransition(), + // ); + }, + ), + TextSpan( + text: '和', + style: TextStyle( + fontSize: 13.sp, + color: Color.fromRGBO(51, 51, 51, 1)), + ), + TextSpan( + text: '《用户协议》', + style: TextStyle( + fontSize: 13.sp, + color: Theme.of(context).primaryColor), + recognizer: TapGestureRecognizer() + ..onTap = () async { + Get.toNamed(Routes.agreementPage, arguments: { + "type": AGREEMENT_KEY.USER_AGREEMENT.name + }); + // RouterManager.router.navigateTo( + // context, + // '${RouterManager.agreementPath}?type=${AGREEMENT_KEY.USER_AGREEMENT.name}', + // transition: getTransition(), + // ); + }, + ), + TextSpan( + text: + '内的所有条款,尤其是:1.我们对您的个人信息的收集/保存/使用/对外提供/保护等规则条款,以及您的用户权利等条款;2.约定我们的限制责任、免责条款;3.其他以颜色或加粗进行标识的重要条款。如您对以上协议有任何疑问,可通过发邮件至yuanxuanjiaoyu@gmail.com与我们联系。您点击"同意并继续”的行为即表示您已阅读完毕并同意以上协议的全部内容。如您同意以上协议内容,请点击"同意并继续”,开始使用我们的产品和服务!', + style: TextStyle( + fontSize: 13.sp, + color: const Color.fromRGBO(51, 51, 51, 1)), + ), + ])), + ], + ), + ), + SizedBox(height: 10.h), + Row( + children: [ + Expanded( + child: InkWell( + onTap: () { + exit(0); + }, + child: Container( + alignment: Alignment.center, + padding: EdgeInsets.only(top: 15.h), + decoration: BoxDecoration( + border: Border( + top: BorderSide( + width: 0.5.r, + color: const Color.fromRGBO(238, 238, 238, 1)), + right: BorderSide( + width: 0.5.r, + color: const Color.fromRGBO(238, 238, 238, 1)), + ), + ), + child: quickText('退出APP', size: 14.sp), + ), + ), + ), + Expanded( + child: InkWell( + onTap: () { + StorageService.to + .write(AppStorageKey.privacyAgreement.value, true); + Navigator.of(context).pop(true); + }, + child: Container( + alignment: Alignment.center, + padding: EdgeInsets.only(top: 15.h), + decoration: BoxDecoration( + border: Border( + top: BorderSide( + width: 0.5.r, + color: const Color.fromRGBO(238, 238, 238, 1)), + ), + ), + child: quickText('同意并继续', + color: Theme.of(context).primaryColor, size: 14.sp), + ), + ), + ) + ], + ), + ], + ), + ), + ); + } +} + +/// 系统协议 +Future sysProtocol(BuildContext context) async { + bool? sysProtocol = + StorageService.to.hasData(AppStorageKey.privacyAgreement.value); + + if (!sysProtocol) { + return showDialog( + context: context, + barrierDismissible: false, + // useRootNavigator: false, + builder: (ctx) => Protocol(ctx), + ); + } +} 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 3c5c1e7..3771c69 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 @@ -7,8 +7,8 @@ import 'package:making_school_asignment_app/common/store/user_store.dart'; import 'package:making_school_asignment_app/common/utils/storage.dart'; import 'package:making_school_asignment_app/common/utils/toast_utils.dart'; import 'package:making_school_asignment_app/common/utils/utils.dart'; +import 'package:making_school_asignment_app/page/login_page/children/sys_protocol.dart'; import 'package:making_school_asignment_app/routes/app_pages.dart'; -import 'package:making_school_asignment_app/common/utils/storage.dart'; import 'package:making_school_asignment_app/common/store/app_storage_key.dart'; import 'login_state.dart'; @@ -26,13 +26,13 @@ class LoginLogic extends GetxController with RequestToolMixin { void onInit() { super.onInit(); - /* state.userNameController = TextEditingController() + /* state.userNameController = TextEditingController() ..addListener(userNameListener); state.passwordController = TextEditingController();*/ - String account = StorageService.to.read(AppStorageKey.account.value)?? ''; + String account = StorageService.to.read(AppStorageKey.account.value) ?? ''; String pwd = StorageService.to.read(AppStorageKey.pwd.value) ?? ''; - if (account != '' && pwd != '') { + if (account != '' && pwd != '') { state.userNameController.text = account; state.passwordController.text = pwd; state.keepPwd.value = true; @@ -40,6 +40,7 @@ class LoginLogic extends GetxController with RequestToolMixin { state.pwdFocus = FocusNode(); state.theFocus = FocusNode(); + getShowUserAdditionalFeatures(); // } void userNameListener() { @@ -58,7 +59,7 @@ class LoginLogic extends GetxController with RequestToolMixin { } // 前往登录 - void toLogin() async { + void toLogin(BuildContext context) async { if (!state.canLogin.value) return; state.canLogin.value = false; @@ -161,4 +162,9 @@ class LoginLogic extends GetxController with RequestToolMixin { state.pwdFocus.dispose(); state.theFocus.dispose(); } + + /// 是否展示用户附加功能 + Future getShowUserAdditionalFeatures() async { + // state.showUserAdditionalFeatures.value = ; + } } diff --git a/making_school_asignment_app/lib/page/login_page/login_state.dart b/making_school_asignment_app/lib/page/login_page/login_state.dart index d493af9..7c96cd9 100644 --- a/making_school_asignment_app/lib/page/login_page/login_state.dart +++ b/making_school_asignment_app/lib/page/login_page/login_state.dart @@ -15,5 +15,6 @@ class LoginState { late RxBool isShowPwd = true.obs; late RxBool keepPwd = false.obs; late RxBool canLogin = true.obs; - late RxBool readAgreement = true.obs; + late RxBool readAgreement = false.obs; + late RxBool showUserAdditionalFeatures = false.obs; } diff --git a/making_school_asignment_app/lib/page/login_page/login_view.dart b/making_school_asignment_app/lib/page/login_page/login_view.dart index d43ad3e..9206e0a 100644 --- a/making_school_asignment_app/lib/page/login_page/login_view.dart +++ b/making_school_asignment_app/lib/page/login_page/login_view.dart @@ -1,17 +1,18 @@ +import 'package:get/get.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; -import 'package:get/get.dart'; import 'package:making_school_asignment_app/common/const_text.dart'; import 'package:making_school_asignment_app/common/utils/app_upgrade/upgradeLogic.dart'; import 'package:making_school_asignment_app/common/utils/utils.dart'; import 'package:making_school_asignment_app/page/global_widget/my_text.dart'; import 'package:making_school_asignment_app/routes/app_pages.dart'; +import 'children/sys_protocol.dart'; import 'login_logic.dart'; class LoginPage extends StatefulWidget { - const LoginPage({Key? key}) : super(key: key); + const LoginPage({super.key}); @override State createState() => _LoginPageState(); @@ -24,7 +25,10 @@ class _LoginPageState extends State { @override void initState() { + SystemChrome.setSystemUIOverlayStyle( + const SystemUiOverlayStyle(statusBarIconBrightness: Brightness.light)); Future.delayed(Duration.zero, () => upgradeLogic.getAppUpgrade(context)); + Future.delayed(Duration.zero, () => sysProtocol(context)); super.initState(); } @@ -36,6 +40,8 @@ class _LoginPageState extends State { @override Widget build(BuildContext context) { + SystemChrome.setSystemUIOverlayStyle( + const SystemUiOverlayStyle(statusBarIconBrightness: Brightness.light)); return GestureDetector( behavior: HitTestBehavior.translucent, onTap: () { @@ -72,12 +78,15 @@ class _LoginPageState extends State { child: SizedBox( height: 86.w, width: 86.w, - child: Image.asset('assets/images/login_logo.png', fit: BoxFit.cover), + child: Image.asset('assets/images/login_logo.png', + fit: BoxFit.cover), ), ), Container( - margin: EdgeInsets.symmetric(horizontal: 32.w, vertical: 24.h), - padding: EdgeInsets.only(top: 34.h, bottom: 16.h, left: 22.w, right: 22.w), + margin: EdgeInsets.symmetric( + horizontal: 32.w, vertical: 24.h), + padding: EdgeInsets.only( + top: 34.h, bottom: 16.h, left: 22.w, right: 22.w), color: Colors.transparent, /* decoration: BoxDecoration( color: Colors.transparent, @@ -97,8 +106,10 @@ class _LoginPageState extends State { padding: EdgeInsets.symmetric(horizontal: 20.h), decoration: BoxDecoration( color: Colors.transparent, - border: Border.all(width: 1.w, color: const Color(0xFFFFFFFF)), - borderRadius: BorderRadius.all(Radius.circular(17.w)), + border: Border.all( + width: 1.w, color: const Color(0xFFFFFFFF)), + borderRadius: + BorderRadius.all(Radius.circular(17.w)), ), child: TextField( controller: state.userNameController, @@ -127,8 +138,8 @@ class _LoginPageState extends State { border: InputBorder.none, isDense: true, prefixIconConstraints: BoxConstraints( - minHeight:10.w, - minWidth: 10.h, + minHeight: 10.w, + minWidth: 10.h, ), prefixIcon: Padding( padding: EdgeInsets.only(right: 5.r), @@ -149,8 +160,10 @@ class _LoginPageState extends State { padding: EdgeInsets.symmetric(horizontal: 20.h), decoration: BoxDecoration( color: Colors.transparent, - border: Border.all(width: 1.w, color: const Color(0xFFFFFFFF)), - borderRadius: BorderRadius.all(Radius.circular(17.w)), + border: Border.all( + width: 1.w, color: const Color(0xFFFFFFFF)), + borderRadius: + BorderRadius.all(Radius.circular(17.w)), ), child: TextField( focusNode: state.pwdFocus, @@ -168,7 +181,7 @@ class _LoginPageState extends State { decoration: InputDecoration( hintText: "请输入密码", prefixIconConstraints: BoxConstraints( - minHeight:10.w, + minHeight: 10.w, minWidth: 10.h, ), prefixIcon: Padding( @@ -180,17 +193,20 @@ class _LoginPageState extends State { ), ), suffixIconConstraints: BoxConstraints( - minHeight:10.w, + minHeight: 10.w, minWidth: 10.h, ), suffixIcon: InkWell( - onTap: (){ - state.isShowPwd.value = !state.isShowPwd.value; + onTap: () { + state.isShowPwd.value = + !state.isShowPwd.value; }, child: Padding( padding: EdgeInsets.only(right: 5.r), child: Image.asset( - state.isShowPwd.value ? 'assets/images/eye_default.png':'assets/images/eye_active.png', + state.isShowPwd.value + ? 'assets/images/eye_default.png' + : 'assets/images/eye_active.png', width: 15.r, height: 15.r, ), @@ -211,67 +227,99 @@ class _LoginPageState extends State { ), ); }), - SizedBox( - height: 22.h, - ), - Row( + SizedBox(height: 10.h), + Row( children: [ - Container( - width: 25.w, - padding: EdgeInsets.only(right: 0.w), - child: Obx(() { - return Transform.scale( - scale: 1.2, - child: Checkbox( - activeColor: Theme.of(context).primaryColor, - checkColor: Colors.white, - value: state.keepPwd.value, - onChanged: (value) { - // Get.focusScope?.nextFocus(); - FocusScope.of(context).requestFocus( - state.pwdFocus); - FocusScope.of(context).requestFocus( - state.theFocus); - state.keepPwd.value = value ?? false; - }, + Expanded( + child: Row( + children: [ + Container( + width: 25.w, + padding: EdgeInsets.only(right: 0.w), + child: Obx(() { + return Transform.scale( + scale: 1.2, + child: Checkbox( + // activeColor: Colors.transparent, //去掉勾选时背景颜色 + + activeColor: + Theme.of(context).primaryColor, + // checkColor: Colors.white, + value: state.keepPwd.value, + onChanged: (value) { + // Get.focusScope?.nextFocus(); + FocusScope.of(context) + .requestFocus(state.pwdFocus); + FocusScope.of(context) + .requestFocus(state.theFocus); + state.keepPwd.value = + value ?? false; + }, + side: WidgetStateBorderSide + .resolveWith( + (Set states) { + if (states.contains( + WidgetState.selected)) { + //修改勾选时边框颜色为红色 + return BorderSide( + width: 1.5.r, + color: Theme.of(context) + .primaryColor); + } + //修改默认时边框颜色为绿色 + return BorderSide( + width: 1.5.r, + color: Colors.white); + }, + )), + ); + }), ), - ); - }), - ), - InkWell( - onTap: () { - Utils.hideKeyboard(); - Get.focusScope?.nextFocus(); - Get.focusScope?.nextFocus(); - FocusScope.of(context).requestFocus( - state.pwdFocus); - FocusScope.of(context).requestFocus( - state.theFocus); - state.keepPwd.value = !state.keepPwd.value; - }, - child: Text( - '记住密码', - style: TextStyle( - fontSize: 11.sp, - color: Colors.white, - ), + InkWell( + onTap: () { + Utils.hideKeyboard(); + Get.focusScope?.nextFocus(); + Get.focusScope?.nextFocus(); + FocusScope.of(context) + .requestFocus(state.pwdFocus); + FocusScope.of(context) + .requestFocus(state.theFocus); + state.keepPwd.value = + !state.keepPwd.value; + }, + child: Text( + '记住密码', + style: TextStyle( + fontSize: 12.sp, + color: Colors.white, + ), + ), + ), + ], ), ), + InkWell( + onTap: () => Get.toNamed(Routes.register), + child: quickText('账号注册', color: Colors.white), + ) ], ), InkWell( onTap: () { - logic.toLogin(); + logic.toLogin(context); // Get.toNamed(Routes.home); }, child: Obx(() { return Container( margin: EdgeInsets.symmetric(vertical: 10.h), decoration: BoxDecoration( - color: state.canLogin.value ? const Color(0xFF4CC793) : const Color(0xFFdddddd), + color: state.canLogin.value + ? const Color(0xFF4CC793) + : const Color(0xFFdddddd), boxShadow: [ BoxShadow( - color: const Color.fromRGBO(76, 199, 147, 0.5), + color: + const Color.fromRGBO(76, 199, 147, 0.5), offset: Offset(6.w, 10.h), //阴影y轴偏移量 blurRadius: 14, //阴影模糊程度 spreadRadius: 0.5, //阴影扩散程度 @@ -284,10 +332,9 @@ class _LoginPageState extends State { alignment: Alignment.center, width: double.infinity, height: 50.h, - child: Text( - '登 录', - style: TextStyle(fontSize: 16.sp, color: Colors.white), - ), + child: Text('登 录', + style: TextStyle( + fontSize: 16.sp, color: Colors.white)), ); }), ), @@ -309,25 +356,50 @@ class _LoginPageState extends State { state.pwdFocus); FocusScope.of(context).requestFocus( state.theFocus);*/ - state.readAgreement.value = value ?? false; + state.readAgreement.value = + value ?? false; }, + side: WidgetStateBorderSide.resolveWith( + (Set states) { + if (states + .contains(WidgetState.selected)) { + //修改勾选时边框颜色为红色 + return BorderSide( + width: 1.5.r, + color: Theme.of(context) + .primaryColor); + } + //修改默认时边框颜色为绿色 + return BorderSide( + width: 1.5.r, color: Colors.white); + }, + ), ), ); }), ), InkWell( onTap: () { - Get.toNamed(Routes.agreementPage, arguments: {"type": AGREEMENT_KEY.USER_AGREEMENT.name}); + Get.toNamed(Routes.agreementPage, arguments: { + "type": AGREEMENT_KEY.USER_AGREEMENT.name + }); }, - child: quickText('请仔细阅读', size: 11.sp,), + child: quickText( + '请仔细阅读', + size: 11.sp, + ), ), InkWell( onTap: () { - Get.toNamed(Routes.agreementPage, arguments: {"type": AGREEMENT_KEY.USER_AGREEMENT.name}); + Get.toNamed(Routes.agreementPage, arguments: { + "type": AGREEMENT_KEY.USER_AGREEMENT.name + }); }, child: Text( '《用户协议》', - style: TextStyle(fontSize: 12.r, color: Colors.deepOrangeAccent), + style: TextStyle( + fontSize: 12.r, + color: Theme.of(context).primaryColor), ), ), ], diff --git a/making_school_asignment_app/lib/page/work_page/work_view.dart b/making_school_asignment_app/lib/page/work_page/work_view.dart index 2c4a78a..e0d343c 100644 --- a/making_school_asignment_app/lib/page/work_page/work_view.dart +++ b/making_school_asignment_app/lib/page/work_page/work_view.dart @@ -27,139 +27,140 @@ class _WorkPageState extends State with AutomaticKeepAliveClientMixin @override bool get wantKeepAlive => true; + @override + void initState() { + // TODO: implement initState + super.initState(); + } + @override Widget build(BuildContext context) { super.build(context); - return AnnotatedRegion( - value: const SystemUiOverlayStyle( - systemNavigationBarColor: Color(0xFF000000), - systemNavigationBarDividerColor: null, - statusBarColor: Colors.white, - systemNavigationBarIconBrightness: Brightness.light, - statusBarIconBrightness: Brightness.dark, - statusBarBrightness: Brightness.light, - ), - child: Scaffold( - backgroundColor: const Color.fromRGBO(244, 244, 244, 1), - body: OrientationBuilder( - builder: (BuildContext context, Orientation orientation) { - return Column( - children: [ - Container( - color: Colors.white, - margin: EdgeInsets.only(top: MediaQuery.of(context).padding.top), - padding: EdgeInsets.only(bottom: 9.h, top: 4.h), - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Expanded( - flex: 1, - child: Container( - alignment: Alignment.centerLeft, - padding: EdgeInsets.only(left: 10.w), - )), - Expanded( - flex: 4, - child: Container( - padding: EdgeInsets.symmetric(vertical: 2.h), - alignment: Alignment.center, - decoration: BoxDecoration( - color: const Color.fromRGBO(243, 243, 243, 1), - borderRadius: BorderRadius.circular(8.r), - ), - child: TabBar( - padding: EdgeInsets.zero, - indicatorPadding: EdgeInsets.zero, - indicatorWeight: 0, - labelPadding: EdgeInsets.symmetric(horizontal: 2.w), - controller: logic.tabController, - unselectedLabelStyle: TextStyle( - fontSize: 14.sp, - color: const Color.fromRGBO(69, 83, 100, 1), - ), - labelStyle: TextStyle( - fontSize: 14.sp, - color: const Color(0xFF4CC793), - ), - // labelColor: const Color.fromRGBO(45, 56, 76, 1), - indicator: const BoxDecoration(), - onTap: (index) { - state.tabIndex.value = index; - if (index == 1 && state.completedToRefresh) { - // 已阅卷 - // _refreshController2.callRefresh(); - state.completedToRefresh = false; - } - }, - tabs: [ - Tab( - iconMargin: EdgeInsets.zero, - height: 34.h, - child: Obx(() { - return Container( - width: 140.w, - alignment: Alignment.center, - decoration: BoxDecoration( - color: state.tabIndex.value == 0 ? const Color.fromRGBO(255, 255, 255, 1) : null, - borderRadius: BorderRadius.all(Radius.circular(8.r)), - ), - child: quickText( - '待批阅', - size: 14.sp, - color: state.tabIndex.value == 0 ? Theme.of(context).primaryColor : const Color.fromRGBO(80, 94, 110, 1), - fontWeight: state.tabIndex.value == 0 ? FontWeight.bold : null, - ), - ); - }), - ), - Tab( - iconMargin: EdgeInsets.zero, - height: 34.h, - child: Obx(() { - return Container( - width: 140.w, - alignment: Alignment.center, - decoration: BoxDecoration( - color: state.tabIndex.value == 1 ? const Color.fromRGBO(255, 255, 255, 1) : null, - borderRadius: BorderRadius.all(Radius.circular(8.r)), - ), - child: quickText( - '已批阅', - size: 14.sp, - color: state.tabIndex.value == 1 ? Theme.of(context).primaryColor : const Color.fromRGBO(80, 94, 110, 1), - fontWeight: state.tabIndex.value == 1 ? FontWeight.bold : null, - ), - ); - }), - ), - ], - ), - ), - ), - Expanded( + + SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle( + statusBarIconBrightness: Brightness.dark, + systemStatusBarContrastEnforced: false, + )); + return Scaffold( + backgroundColor: const Color.fromRGBO(244, 244, 244, 1), + body: OrientationBuilder( + builder: (BuildContext context, Orientation orientation) { + return Column( + children: [ + Container( + color: Colors.white, + margin: EdgeInsets.only(top: MediaQuery.of(context).padding.top), + padding: EdgeInsets.only(bottom: 9.h, top: 4.h), + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Expanded( flex: 1, - child: InkWell( - onTap: () { - Get.toNamed(Routes.studentHistoryWorkPage, arguments: {'page': 'set'}); + child: Container( + alignment: Alignment.centerLeft, + padding: EdgeInsets.only(left: 10.w), + )), + Expanded( + flex: 4, + child: Container( + padding: EdgeInsets.symmetric(vertical: 2.h), + alignment: Alignment.center, + decoration: BoxDecoration( + color: const Color.fromRGBO(243, 243, 243, 1), + borderRadius: BorderRadius.circular(8.r), + ), + child: TabBar( + padding: EdgeInsets.zero, + indicatorPadding: EdgeInsets.zero, + indicatorWeight: 0, + labelPadding: EdgeInsets.symmetric(horizontal: 2.w), + controller: logic.tabController, + unselectedLabelStyle: TextStyle( + fontSize: 14.sp, + color: const Color.fromRGBO(69, 83, 100, 1), + ), + labelStyle: TextStyle( + fontSize: 14.sp, + color: const Color(0xFF4CC793), + ), + // labelColor: const Color.fromRGBO(45, 56, 76, 1), + indicator: const BoxDecoration(), + onTap: (index) { + state.tabIndex.value = index; + if (index == 1 && state.completedToRefresh) { + // 已阅卷 + // _refreshController2.callRefresh(); + state.completedToRefresh = false; + } }, - child: Icon(const IconData(0xe63e, fontFamily: "AlibabaIcon"), color: const Color.fromRGBO(44, 48, 63, 1), size: 24.sp), + tabs: [ + Tab( + iconMargin: EdgeInsets.zero, + height: 34.h, + child: Obx(() { + return Container( + width: 140.w, + alignment: Alignment.center, + decoration: BoxDecoration( + color: state.tabIndex.value == 0 ? const Color.fromRGBO(255, 255, 255, 1) : null, + borderRadius: BorderRadius.all(Radius.circular(8.r)), + ), + child: quickText( + '待批阅', + size: 14.sp, + color: state.tabIndex.value == 0 ? Theme.of(context).primaryColor : const Color.fromRGBO(80, 94, 110, 1), + fontWeight: state.tabIndex.value == 0 ? FontWeight.bold : null, + ), + ); + }), + ), + Tab( + iconMargin: EdgeInsets.zero, + height: 34.h, + child: Obx(() { + return Container( + width: 140.w, + alignment: Alignment.center, + decoration: BoxDecoration( + color: state.tabIndex.value == 1 ? const Color.fromRGBO(255, 255, 255, 1) : null, + borderRadius: BorderRadius.all(Radius.circular(8.r)), + ), + child: quickText( + '已批阅', + size: 14.sp, + color: state.tabIndex.value == 1 ? Theme.of(context).primaryColor : const Color.fromRGBO(80, 94, 110, 1), + fontWeight: state.tabIndex.value == 1 ? FontWeight.bold : null, + ), + ); + }), + ), + ], ), ), - ], - ), + ), + Expanded( + flex: 1, + child: InkWell( + onTap: () { + Get.toNamed(Routes.studentHistoryWorkPage, arguments: {'page': 'set'}); + }, + child: Icon(const IconData(0xe63e, fontFamily: "AlibabaIcon"), color: const Color.fromRGBO(44, 48, 63, 1), size: 24.sp), + ), + ), + ], ), - Expanded( - child: Obx(() { - return AnnotateList( - tabIndex: state.tabIndex.value, - assessType: 1, - ); - }), - ), - ], - ); - }, - ), + ), + Expanded( + child: Obx(() { + return AnnotateList( + tabIndex: state.tabIndex.value, + assessType: 1, + ); + }), + ), + ], + ); + }, ), ); } diff --git a/making_school_asignment_app/lib/routes/app_pages.dart b/making_school_asignment_app/lib/routes/app_pages.dart index 5da8ddd..926141d 100644 --- a/making_school_asignment_app/lib/routes/app_pages.dart +++ b/making_school_asignment_app/lib/routes/app_pages.dart @@ -35,6 +35,7 @@ import 'package:making_school_asignment_app/page/home_page/children/student_work import 'package:making_school_asignment_app/page/home_page/home_binding.dart'; import 'package:making_school_asignment_app/page/home_page/home_view.dart'; import 'package:making_school_asignment_app/page/login_page/children/agreement_page.dart'; +import 'package:making_school_asignment_app/page/login_page/children/register.dart'; import 'package:making_school_asignment_app/page/login_page/login_binding.dart'; import 'package:making_school_asignment_app/page/login_page/login_view.dart'; import 'package:making_school_asignment_app/page/work_page/work_binding.dart'; @@ -44,6 +45,7 @@ part 'app_routes.dart'; abstract class AppPages { static final pages = [ GetPage(name: Routes.login, page: () => const LoginPage(), binding: LoginBinding(), transition: Transition.noTransition), + GetPage(name: Routes.register, page: () => const Register(), transition: getTransition()), GetPage(name: Routes.agreementPage, page: () => const AgreementPage(), binding: LoginBinding(), transition: Transition.noTransition), GetPage(name: Routes.home, page: () => const HomePage(), binding: HomeBinding(), transition: Transition.noTransition), GetPage(name: Routes.startPage, page: () => const StartPage(), binding: StartPageIndexBinding(), transition: Transition.noTransition), @@ -85,14 +87,20 @@ abstract class AppPages { page: () => const KnowledgePointsGraspDetailPage(), binding: KnowledgePointsGraspDetailBinding(), transition: Transition.noTransition), - GetPage(name: Routes.answerTrajectoryPage, page: () => const AnswerTrajectoryPage(), binding: AnswerTrajectoryBinding(), transition: Transition.noTransition), - GetPage(name: Routes.answerTrajectoryDetailPage, page: () => const AnswerTrajectoryDetailPage(), binding: AnswerTrajectoryDetailBinding(), transition: Transition.noTransition), + GetPage( + name: Routes.answerTrajectoryPage, + page: () => const AnswerTrajectoryPage(), + binding: AnswerTrajectoryBinding(), + transition: Transition.noTransition), + GetPage( + name: Routes.answerTrajectoryDetailPage, + page: () => const AnswerTrajectoryDetailPage(), + binding: AnswerTrajectoryDetailBinding(), + transition: Transition.noTransition), // 批阅主页(作业、考试) GetPage(name: Routes.reviewHomework, page: () => const HomeworkReview(), binding: HomeworkReviewBinding(), transition: getTransition()), GetPage(name: Routes.reviewExam, page: () => const HomeworkReview(), binding: HomeworkReviewBinding(), transition: getTransition()), GetPage(name: Routes.favStudentPage, page: () => const FavStudentPage(), binding: FavStudentBinding(), transition: Transition.noTransition), - - ]; } diff --git a/making_school_asignment_app/lib/routes/app_routes.dart b/making_school_asignment_app/lib/routes/app_routes.dart index 5a12ae2..12e5d70 100644 --- a/making_school_asignment_app/lib/routes/app_routes.dart +++ b/making_school_asignment_app/lib/routes/app_routes.dart @@ -2,6 +2,7 @@ part of 'app_pages.dart'; abstract class Routes { static const login = '/login'; + static const register = '/register'; static const agreementPage = '/agreementPage'; static const home = '/home'; static const startPage = '/startPage'; @@ -24,5 +25,4 @@ abstract class Routes { static const reviewHomework = '/review/reviewHomework'; // 作业批阅 static const reviewExam = '/review/reviewExam'; // 考试批阅 static const favStudentPage = '/favStudentPage'; // 收藏夹 - -} \ No newline at end of file +} diff --git a/making_school_asignment_app/pubspec.yaml b/making_school_asignment_app/pubspec.yaml index a22c91f..9f7f387 100644 --- a/making_school_asignment_app/pubspec.yaml +++ b/making_school_asignment_app/pubspec.yaml @@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # In Windows, build-name is used as the major, minor, and patch parts # of the product and file versions while build-number is used as the build suffix. -version: 1.0.0+1 +version: 1.0.1+2 environment: sdk: '>=3.4.1 <4.0.0' @@ -91,9 +91,12 @@ dependencies: url_launcher: ^6.1.11 app_installer: ^1.1.0 auto_updater: ^0.2.1 - permission_handler: ^11.0.1 + permission_handler: ^11.3.1 flutter_distributor: ^0.4.5 flutter_native_splash: ^2.4.1 + icons_launcher: ^2.1.7 + app_settings: ^5.1.1 + dev_dependencies: flutter_test: @@ -160,3 +163,11 @@ flutter: # # For details regarding fonts from package dependencies, # see https://flutter.dev/custom-fonts/#from-packages + +icons_launcher: + platforms: + android: + enable: false + ios: + enable: true + image_path: "assets/images/logo_splash.png" \ No newline at end of file diff --git a/making_school_asignment_app/web/index.html b/making_school_asignment_app/web/index.html index 751dd30..b46adbd 100644 --- a/making_school_asignment_app/web/index.html +++ b/making_school_asignment_app/web/index.html @@ -120,6 +120,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -149,9 +186,8 @@ body { margin: 0; min-height: 100%; - background-color: #ffffff; - background-image: url("splash/img/light-background.png"); - background-size: 100% 100%; + background-color: #eeeeee; + background-size: 100% 100%; } .center { @@ -207,13 +243,18 @@ document.body.style.background = "transparent"; } - + + + + + +