From 382840a3aa3632a8ef2b51b5f396c6f691e4fd6c Mon Sep 17 00:00:00 2001 From: "1147192855@qq.com" <1147192855@qq.com> Date: Thu, 12 Dec 2024 17:24:20 +0800 Subject: [PATCH] no message --- .../do_paper_details_result.dart | 45 +-- .../lib/common/request/rest_dio.dart | 13 +- .../lib/common/utils/utils.dart | 40 ++- .../dropdown_switch_students_type.dart | 35 +- .../components/favorite_widget.dart | 58 +--- .../components/question_paper_view.dart | 312 ++++++++++++------ .../configuration_files/index.dart | 93 +++++- .../configuration_files/zoom_logic.dart | 176 ++++++++++ .../children/homework_review/index.dart | 56 +--- .../lib/page/login_page/login_logic.dart | 9 +- .../lib/page/login_page/login_view.dart | 42 ++- making_school_asignment_app/pubspec.yaml | 11 +- 12 files changed, 596 insertions(+), 294 deletions(-) create mode 100644 making_school_asignment_app/lib/page/home_page/children/homework_review/configuration_files/zoom_logic.dart 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 b01a3b8..d8a8406 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 @@ -4,7 +4,7 @@ import 'package:making_school_asignment_app/common/config/request_config.dart'; part 'do_paper_details_result.g.dart'; -@JsonSerializable(checked: true) +@JsonSerializable(checked: true, includeIfNull: false) class DoPaperDetailsResult extends Object { @JsonKey(name: 'templateIds') Map templateIds; @@ -17,7 +17,7 @@ class DoPaperDetailsResult extends Object { @JsonKey(name: 'templateIdKeyMap') Map? templateIdKeyMap; - @JsonKey(name: 'submitStudents') // 当前页 总提交学生集合 + @JsonKey(name: 'submitStudents', toJson: _paperStudentsToJson) // 当前页 总提交学生集合 List students; @JsonKey(name: 'templateId') @@ -55,17 +55,17 @@ class DoPaperDetailsResult extends Object { @JsonKey(name: 'isFav') bool isFav; - @JsonKey(name: 'studentQuestions') + @JsonKey(name: 'studentQuestions', toJson: _studentQuestionsToJson) List studentQuestions; // 当前页 未提交学生集合 - @JsonKey(name: 'unSubmitStudents') + @JsonKey(name: 'unSubmitStudents', toJson: _paperStudentsToJson) List unSubmitStudents; - @JsonKey(name: 'lastPage') + @JsonKey(name: 'lastPage', toJson: _lastPageToJson) LastPage? lastPage; - @JsonKey(name: 'nextPage') + @JsonKey(name: 'nextPage', toJson: _nextPageToJson) NextPage? nextPage; // 所有页 总待提交数量 @@ -112,27 +112,34 @@ class DoPaperDetailsResult extends Object { var currentStudent = students.firstWhereOrNull((e) => e.id == studentId); if (currentStudent != null) priority = currentStudent.isPriority; } - zgtAnswer = '${RequestConfig.imgUrl}$zgtAnswer?$lastAnswerTime'; + + if (!zgtAnswer.contains(RequestConfig.imgUrl)) { + zgtAnswer = '${RequestConfig.imgUrl}$zgtAnswer?$lastAnswerTime'; + } 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) { + 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); + + static List> _paperStudentsToJson(List examples) => examples.map((e) => e.toJson()).toList(); + + static List> _studentQuestionsToJson(List examples) => examples.map((e) => e.toJson()).toList(); + + static Map? _nextPageToJson(NextPage? example) => example?.toJson(); + static Map? _lastPageToJson(LastPage? example) => example?.toJson(); } @JsonSerializable() @@ -153,8 +160,7 @@ class PaperStudents extends Object { this.isPriority, ); - factory PaperStudents.fromJson(Map srcJson) => - _$PaperStudentsFromJson(srcJson); + factory PaperStudents.fromJson(Map srcJson) => _$PaperStudentsFromJson(srcJson); Map toJson() => _$PaperStudentsToJson(this); } @@ -206,8 +212,7 @@ class StudentQuestions extends Object { this.useTime, }); - factory StudentQuestions.fromJson(Map srcJson) => - _$StudentQuestionsFromJson(srcJson); + factory StudentQuestions.fromJson(Map srcJson) => _$StudentQuestionsFromJson(srcJson); Map toJson() => _$StudentQuestionsToJson(this); } @@ -225,8 +230,7 @@ class LastPage extends Object { this.studentId, ); - factory LastPage.fromJson(Map srcJson) => - _$LastPageFromJson(srcJson); + factory LastPage.fromJson(Map srcJson) => _$LastPageFromJson(srcJson); Map toJson() => _$LastPageToJson(this); } @@ -244,8 +248,7 @@ 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/request/rest_dio.dart b/making_school_asignment_app/lib/common/request/rest_dio.dart index 0e0eef1..bed3ce7 100644 --- a/making_school_asignment_app/lib/common/request/rest_dio.dart +++ b/making_school_asignment_app/lib/common/request/rest_dio.dart @@ -2,6 +2,7 @@ import 'dart:convert'; import 'dart:io'; import 'package:get/get.dart' as getx; import 'package:dio/dio.dart'; +import 'package:making_school_asignment_app/common/utils/utils.dart'; import 'package:package_info_plus/package_info_plus.dart'; import 'package:making_school_asignment_app/common/api/retrofit_client.dart'; import 'package:making_school_asignment_app/common/config/request_config.dart'; @@ -114,6 +115,10 @@ class AuthInterceptor extends Interceptor { class ResponseHandle extends Interceptor { @override void onResponse(Response response, ResponseInterceptorHandler handler) { + const isProd = bool.fromEnvironment('dart.vm.product'); + if (!isProd && RequestConfig.requestDataPrinting) { + toPrint(val: response.data, toPrintJson: true); + } if (RequestConfig.successCode.contains(response.statusCode)) { // String? token = response.headers.value('access-token'); @@ -180,9 +185,11 @@ class TheError extends Interceptor { message = '用户登录失效,请重新登录'; Future.delayed(const Duration(seconds: 2), () { - UserStore.to.erase(); - StorageService.to.erase(); - getx.Get.offAllNamed(Routes.login); + if (getx.Get.currentRoute != Routes.login) { + UserStore.to.erase(); + StorageService.to.erase(); + getx.Get.offAllNamed(Routes.login); + } }); break; case 404: diff --git a/making_school_asignment_app/lib/common/utils/utils.dart b/making_school_asignment_app/lib/common/utils/utils.dart index 13c0e70..583987f 100644 --- a/making_school_asignment_app/lib/common/utils/utils.dart +++ b/making_school_asignment_app/lib/common/utils/utils.dart @@ -1,3 +1,5 @@ +import 'dart:convert'; + import 'package:flutter/src/widgets/framework.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; @@ -6,6 +8,8 @@ import 'package:making_school_asignment_app/common/job/homework_details.dart'; import 'package:making_school_asignment_app/page/home_page/children/quick_data_check/quick_data_check_state.dart'; import 'dart:math'; +import '../config/request_config.dart'; + class Utils { static Utils? _instance; Utils._internal(); @@ -167,21 +171,20 @@ class Utils { var stuDtls = data.dtls.where((w) => w.studentId == stu.studentId); var secList = []; - for(var sec in stuDtls){ - if(sec.useTime >= 1){ + for (var sec in stuDtls) { + if (sec.useTime >= 1) { var date = DateTime.parse(sec.lastAnswerTime!); - var lastSec =(date.difference(DateTime(1970)).inSeconds).floor(); + var lastSec = (date.difference(DateTime(1970)).inSeconds).floor(); secList.add(lastSec); secList.add(lastSec - sec.useTime); } } - secList.sort(); - var maxSec = secList.isNotEmpty?secList.last:0; - var minSec = secList.isNotEmpty?secList.first:0; - var secTime = secList.isNotEmpty?maxSec-minSec:0; + secList.sort(); + var maxSec = secList.isNotEmpty ? secList.last : 0; + var minSec = secList.isNotEmpty ? secList.first : 0; + var secTime = secList.isNotEmpty ? maxSec - minSec : 0; stu.ttlSec = second2HMS(secTime); - } data.students.sort((a, b) { @@ -293,3 +296,24 @@ bool isPad([double mobilePhoneScale = 1.2]) { void toUpState(Function(void Function()) setState, VoidCallback fn, bool mounted) { if (mounted) setState(fn); } + +void toPrint({required dynamic val, bool toPrintJson = false}) { + bool printSwitch = RequestConfig.printSwitch; + if (printSwitch && val != null) toPrintJson ? printJson(val) : print(val); +} + +/// 单纯的Json格式输出打印 +void printJson(Object object) { + try { + JsonEncoder encoder = const JsonEncoder.withIndent(' '); + var encoderString = encoder.convert(object); + // print(encoderString); + // 不使用print()方法是因为这是单条输出,如果过长无法显示全 + // 所以使用debugPrint() + debugPrint(encoderString); + // 下面这语句的效果与debugPrint 相同 + //encoderString.split('\n').forEach((element) => print(element)); + } catch (e) { + toPrint(val: e); + } +} diff --git a/making_school_asignment_app/lib/page/home_page/children/homework_review/components/dropdown_switch_students_type.dart b/making_school_asignment_app/lib/page/home_page/children/homework_review/components/dropdown_switch_students_type.dart index b8dd1ca..ac02830 100644 --- a/making_school_asignment_app/lib/page/home_page/children/homework_review/components/dropdown_switch_students_type.dart +++ b/making_school_asignment_app/lib/page/home_page/children/homework_review/components/dropdown_switch_students_type.dart @@ -1,4 +1,3 @@ -import 'package:device_info_plus/device_info_plus.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; @@ -6,49 +5,29 @@ import 'package:functional_widget_annotation/functional_widget_annotation.dart'; import 'package:get/get.dart'; import 'package:making_school_asignment_app/common/job/marking_models/do_paper_details_param.dart'; import 'package:making_school_asignment_app/common/utils/anti_shake_throttling.dart'; -import 'package:making_school_asignment_app/common/utils/permission_describe_util.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/global_widget/my_text.dart'; import 'package:making_school_asignment_app/page/home_page/children/homework_review/configuration_files/index.dart'; import 'package:making_school_asignment_app/routes/app_pages.dart'; -import 'package:permission_handler/permission_handler.dart'; import 'original_manuscript_handwriting/answer_handwriting_view.dart'; part 'dropdown_switch_students_type.g.dart'; /// 学生和页码切换 -class DropdownSwitchStudentsType extends StatefulWidget { +/// + +class DropdownSwitchStudentsType extends StatelessWidget { const DropdownSwitchStudentsType({super.key}); - @override - State createState() => _DropdownSwitchStudentsTypeState(); -} - -class _DropdownSwitchStudentsTypeState extends State { - final DeviceInfoPlugin deviceInfoPlugin = DeviceInfoPlugin(); - final logic = Get.find(); - final sateData = Get.find().state.data; - - @override - void initState() { - deviceInfoPlugin.androidInfo.then((androidInfo) { - Permission storagePermission = androidInfo.version.sdkInt >= 33 ? Permission.manageExternalStorage : Permission.storage; - PermissionDescribeUtil.instance.toLaunchPermissionRequest( - context, - title: '储存权限请求', - describe: "为了提供更好的服务,需要获取到存储权限用于保存批阅痕迹并上传", - permissions: [storagePermission], - ); - }); - - super.initState(); - } - @override Widget build(BuildContext context) { + final logic = Get.find(); + final sateData = logic.state.data; + return Container( + height: 30.h, padding: EdgeInsets.only(bottom: 2.r, left: 12.r, right: 12.r), decoration: BoxDecoration( color: Colors.white, diff --git a/making_school_asignment_app/lib/page/home_page/children/homework_review/components/favorite_widget.dart b/making_school_asignment_app/lib/page/home_page/children/homework_review/components/favorite_widget.dart index 2094f65..21f3562 100644 --- a/making_school_asignment_app/lib/page/home_page/children/homework_review/components/favorite_widget.dart +++ b/making_school_asignment_app/lib/page/home_page/children/homework_review/components/favorite_widget.dart @@ -1,69 +1,25 @@ -import 'dart:async'; import 'package:get/get.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; -import 'package:making_school_asignment_app/common/api/retrofit_client.dart'; -import 'package:making_school_asignment_app/common/job/marking_models/favor_param.dart'; -import 'package:making_school_asignment_app/common/mixins/request_tool_mixin.dart'; import 'package:making_school_asignment_app/common/utils/anti_shake_throttling.dart'; -import 'package:making_school_asignment_app/common/utils/toast_utils.dart'; import 'package:making_school_asignment_app/page/home_page/children/homework_review/configuration_files/index.dart'; /// 自定义收藏组件 /// isFavorite 默认是否收藏 /// favoriteNum 默认收藏次数 -class FavoriteWidget extends StatefulWidget { + +class FavoriteWidget extends StatelessWidget { const FavoriteWidget({super.key}); - @override - State createState() => _FavoriteState(); -} - -class _FavoriteState extends State with RequestToolMixin { - late StreamSubscription _listen; - final _controller = Get.find(); - final sateData = Get.find().state; - RxBool favorite = false.obs; // 初始化数据 - - @override - void initState() { - _listen = _controller.state.data.listen((e) { - if (e == null) return; - if (favorite.value != e.isFav) favorite.value = !favorite.value; - }); - super.initState(); - } - - @override - void dispose() { - _listen.cancel(); - super.dispose(); - } - - Future toFavorite() async { - try { - var data = sateData.data.value!; - var param = sateData.param.value; - await getClient().toFavStudent(FavorParam( - homeworkId: param.homeworkId, - studentId: data.studentId, - templateId: data.templateId, - questionNo: data.studentQuestions[0].questionNo, - isFav: !data.isFav, - )); - favorite.value = !data.isFav; - data.isFav = favorite.value; - } catch (e) { - ToastUtils.showError('操作失败,请重试'); - } - } - @override Widget build(BuildContext context) { + final logic = Get.find(); + final sateData = logic.state; + return Container( padding: EdgeInsets.symmetric(horizontal: 4.r), child: InkWell( - onTap: () => easyThrottle('homework_review_collect_btn', () => toFavorite(), duration: const Duration(milliseconds: 500)), + onTap: () => easyThrottle('homework_review_collect_btn', () => logic.toFavorite(), duration: const Duration(milliseconds: 500)), splashColor: Colors.transparent, highlightColor: Colors.transparent, child: Row( @@ -73,7 +29,7 @@ class _FavoriteState extends State with RequestToolMixin { return Icon( const IconData(0xe63c, fontFamily: "AlibabaIcon"), size: 18.sp, - color: favorite.value ? const Color.fromRGBO(255, 172, 48, 1) : const Color.fromRGBO(164, 164, 164, 1), + color: sateData.favorite.value ? const Color.fromRGBO(255, 172, 48, 1) : const Color.fromRGBO(164, 164, 164, 1), ); }), SizedBox(width: 6.w), 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 8499ad9..c3b8197 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 @@ -14,26 +14,25 @@ import 'package:making_school_asignment_app/common/utils/cached_network_img.dart import 'package:making_school_asignment_app/page/global_widget/my_text.dart'; import 'package:making_school_asignment_app/page/home_page/children/homework_review/configuration_files/index.dart'; import 'package:percent_indicator/linear_percent_indicator.dart'; +import 'package:zoom_widget/zoom_widget.dart'; -import 'dropdown_switch_students_type.dart'; +import '../configuration_files/zoom_logic.dart'; part 'question_paper_view.g.dart'; // 试题详情 -class QuestionPaperView extends StatefulWidget { + +class QuestionPaperView extends StatelessWidget { const QuestionPaperView({super.key}); - @override - State createState() => _QuestionPaperViewState(); -} - -class _QuestionPaperViewState extends State { - final logic = Get.find(); - final sateData = Get.find().state; - final annotationState = Get.find().annotationState; - @override Widget build(BuildContext context) { + final zoomLogic = Get.find(); + final zoomState = zoomLogic.zoomState; + final logic = Get.find(); + final sateData = logic.state; + final annotationState = logic.annotationState; + return Stack( children: [ Row( @@ -41,14 +40,40 @@ class _QuestionPaperViewState extends State { // 试题图片视图 Expanded( flex: 7, - child: LayoutBuilder(builder: (BuildContext context, BoxConstraints constraints) { - var maxWidth = constraints.maxWidth; - var maxHeight = constraints.maxHeight; + child: Obx(() { + ZoomFileModel? zoomFileModel = zoomState.zoomFile.value; + if (zoomFileModel == null) { + /// 计算高度 + return LayoutBuilder(builder: (BuildContext context, BoxConstraints constraints) { + var maxWidth = constraints.maxWidth; + var maxHeight = constraints.maxHeight; + // var maxHeight = ScreenUtil().screenHeight - 95.h - logic.appBarHeight; // 1187.2356785851596 + // print("原始 视图的高度:${maxHeight1} $maxHeight ${MediaQuery.of(context).padding.top}"); + WidgetsBinding.instance.addPostFrameCallback((_) { + zoomState.zoomFile.value = ZoomFileModel(viewWidth: maxWidth, viewHeight: maxHeight); + }); + return SizedBox(); + }); + } else if (zoomFileModel.fileHeight == null) { + /// 文件未计算实际高度 + return SizedBox(); + } + + var maxWidth = zoomFileModel.viewWidth; + var maxHeight = zoomFileModel.viewHeight; + print("文件的高度:${zoomFileModel.actualHeight!}"); return Stack( children: [ // 主图 - QuestionImageView(maxWidth, maxHeight, sateData, annotationState, logic), + QuestionImageView( + maxWidth, + maxHeight, + sateData, + annotationState, + logic, + actualHeight: zoomFileModel.actualHeight!, + ), // 继续批阅按钮 // Positioned(right: 3.w, bottom: 4.h, child: const $ContinueToReview(isFloatingAction: true)), // 上一题按钮 @@ -81,6 +106,7 @@ class _QuestionPaperViewState extends State { child: Obx(() { NextPage? nextPageVal = sateData.data.value?.nextPage; if (nextPageVal == null) return const SizedBox(); + return FloatingActionButton( heroTag: '点击前往下一题', tooltip: '点击前往下一题', @@ -108,14 +134,13 @@ class _QuestionPaperViewState extends State { ), Obx(() { if (!sateData.getDataError.value) return const SizedBox(); - return Center( child: CupertinoButton( color: Colors.grey[300], onPressed: () => easyThrottle('home_work_reload_data', () { sateData.param.value = DoPaperDetailsParam.fromJson(sateData.param.value.toJson()); }), - child: quickText('重新请求', color: Colors.black38), + child: quickText('再次请求', color: Colors.black38), ), ); }), @@ -234,7 +259,10 @@ Widget $questionNumberView(BuildContext context, HomeworkReviewLogic logic, Home 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 (sateData.panQuestView != null && sateData.panQuestView == true && e != scrollControllerNum.offset) { + print("进来了试题题号视图"); + scrollControllerNum.jumpTo(e); + } }); return () { @@ -270,7 +298,7 @@ Widget $questionNumberView(BuildContext context, HomeworkReviewLogic logic, Home var actualImgHeight = imageVal.actualImgHeight; // 实际图片高度 return Container( - height: boxHeight > actualImgHeight ? boxHeight : actualImgHeight, + height: (boxHeight > actualImgHeight ? boxHeight : actualImgHeight) * (logic.state.initScale.value ?? 1), padding: EdgeInsets.only(top: imageVal.remainingHeight > 0 ? imageVal.remainingHeight / 2 : 0), child: Column( mainAxisAlignment: MainAxisAlignment.start, @@ -292,6 +320,7 @@ Widget $questionNumberView(BuildContext context, HomeworkReviewLogic logic, Home Widget $scoringQuestionsView( BuildContext context, HomeworkReviewLogic logic, StudentQuestions item, double scaleRatio, List? studentQuestions) { var studentScore = useState(item.studentScore); + var initScale = useState(logic.state.initScale.value ?? 1); useValueChanged(studentScore.value, (_, __) { item.studentScore = studentScore.value; @@ -304,6 +333,11 @@ Widget $scoringQuestionsView( } }); + useValueChanged(logic.state.initScale.value, (_, __) { + print("数据了啦啦啦啦: ${logic.state.initScale}"); + initScale.value = logic.state.initScale.value ?? 1; + }); + useValueChanged(item, (_, __) { studentScore.value = item.studentScore; }); @@ -312,8 +346,9 @@ Widget $scoringQuestionsView( return () {}; }, []); var padinVal = item.correctRate > 0 ? EdgeInsets.only(top: 6.4.h) : EdgeInsets.symmetric(vertical: 2.h); + print("高度: ${item.height! * scaleRatio * initScale.value}"); return Container( - height: item.height! * scaleRatio, + height: item.height! * scaleRatio * initScale.value, padding: EdgeInsets.zero, child: item.useTime == 0 ? Container() @@ -423,10 +458,11 @@ Widget $scoringQuestionsView( class QuestionImageView extends HookWidget with EventBusMixin { final double maxWidth; final double maxHeight; + final double actualHeight; 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, {required this.actualHeight, super.key}); /// 获取数组指定倒数具体值的下标 int _findTargetIndex(List list, T target, [int reciprocal = 2]) { @@ -443,15 +479,26 @@ class QuestionImageView extends HookWidget with EventBusMixin(maxHeight); + useValueChanged(maxHeight, (oldValue, __) => theMaxHeight.value = maxHeight); - final scrollControllerQuestion = useScrollController(); // 试题图片区域 + // final imgActualHeight = useState(sateData.imageScale.value?.actualImgHeight); + // final scrollControllerQuestion = useScrollController(); // 试题图片区域 var vnHandWritings = useValueNotifier>([]); + + /// 滑动高度 + var initPosition = useState(null); + var customPaintSize = useState(Size.zero); + // useValueChanged(sateData.imageScale.value?.actualImgHeight, (_, __) { + // imgActualHeight.value = sateData.imageScale.value?.actualImgHeight; + // }); + useEffect(() { var listenStream = sateData.data.listen((e) { // 数据清空 @@ -464,9 +511,21 @@ class QuestionImageView extends HookWidget with EventBusMixin imageScale.actualImgHeight || dy < 0) return; // 检查笔记是否超出图片范围 + var dy = localPosition.dy; + if (dy > imageScale.actualImgHeight || dy < 0) return; // 检查笔记是否超出图片范围 - vnHandWritings.value = List.from(vnHandWritings.value)..add(localPosition); - sateData.handwritings = vnHandWritings.value; - }, - child: Stack( - children: [ - $TheCachedNetworkImage( - imageUrl: imageUrl, - imgWidth: maxWidth, - (context, imageProvider) { - Image imageWidget = Image(image: imageProvider, fit: BoxFit.fitWidth); - imageStream?.removeListener(imageStreamListener.value); - imageStream = imageWidget.image.resolve(const ImageConfiguration())..addListener(imageStreamListener.value); - // return imageWidget; - return imageWidget; - }, - ), - RepaintBoundary( - key: logic.pictureOverviewKey, - child: CustomPaint( - isComplex: true, - size: customPaintSize.value, - foregroundPainter: DrawingPainter(ctrl: vnHandWritings), - child: showZgtAnnotate != null - ? $TheCachedNetworkImage( - imgWidth: maxWidth, - imageUrl: showZgtAnnotate, - (_, imageProvider) => Image(image: imageProvider, fit: BoxFit.fitWidth), - ) - : null, + var theScale = sateData.initScale.value ?? 1; + + /// 缩放后的基数 + if (theScale != 1) { + localPosition = Offset(localPosition.dx / theScale, localPosition.dy / theScale); + var theZoomOffset = sateData.zoomOffset; + if (theZoomOffset != null) { + var dx = theZoomOffset.dx; + var dy = theZoomOffset.dy; + localPosition = Offset(localPosition.dx + dx, localPosition.dy + dy); + } + } + + vnHandWritings.value = List.from(vnHandWritings.value)..add(localPosition); + sateData.handwritings = vnHandWritings.value; + }, + child: Obx(() { + var isPen = annotationState.pen.value; + var showZgtAnnotate = sateData.data.value?.showZgtAnnotate; + + print("55555高度: ${actualHeight} ${initPosition.value}"); + return IgnorePointer( + ignoring: isPen, + child: Zoom( + key: zoomKey, + // initTotalZoomOut: true, // 展示全部内容 初始化不产生滚动条 + zoomSensibility: 0.05, + scrollWeight: 4.r, + doubleTapAnimDuration: Duration.zero, + maxZoomWidth: maxWidth, + maxZoomHeight: actualHeight, + canvasColor: Colors.transparent, + initPosition: initPosition.value, + initScale: sateData.initScale.value, + backgroundColor: Colors.transparent, + onScaleUpdate: logic.onScaleUpdate, + onPositionUpdate: logic.onPanUpPosition, + child: Center( + child: Stack( + children: [ + $TheCachedNetworkImage( + imageUrl: sateData.data.value!.zgtAnswer, + imgWidth: maxWidth, + (context, imageProvider) { + Image imageWidget = Image(image: imageProvider, fit: BoxFit.fitWidth); + imageStream?.removeListener(imageStreamListener.value); + imageStream = imageWidget.image.resolve(const ImageConfiguration())..addListener(imageStreamListener.value); + return imageWidget; + }, ), - ), - ], + RepaintBoundary( + key: logic.pictureOverviewKey, + child: CustomPaint( + isComplex: true, + size: customPaintSize.value, + foregroundPainter: DrawingPainter(ctrl: vnHandWritings), + child: showZgtAnnotate != null + ? $TheCachedNetworkImage( + imgWidth: maxWidth, + imageUrl: showZgtAnnotate, + (_, imageProvider) => Image(image: imageProvider, fit: BoxFit.fitWidth)) + : null, + ), + ), + ], + ), ), ), - ), - ); - }), + ); + }), + ), ); + + // return Obx(() { + // var imageUrl = sateData.data.value?.zgtAnswer; + + // if (imageUrl == null) return const SizedBox(); + + // }); } } 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 451ff47..b285caf 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 @@ -2,6 +2,7 @@ import 'dart:async'; import 'dart:ui' as ui; +import 'package:device_info_plus/device_info_plus.dart'; import 'package:dio/dio.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; @@ -10,11 +11,16 @@ import 'package:get/get.dart'; import 'package:making_school_asignment_app/common/job/marking_models/do_paper_details_param.dart'; import 'package:making_school_asignment_app/common/job/marking_models/do_paper_details_result.dart'; import 'package:making_school_asignment_app/common/job/marking_models/do_test_questions_image_info.dart'; +import 'package:making_school_asignment_app/common/job/marking_models/favor_param.dart'; import 'package:making_school_asignment_app/common/job/marking_models/review_submission_params.dart'; import 'package:making_school_asignment_app/common/mixins/request_tool_mixin.dart'; +import 'package:making_school_asignment_app/common/utils/permission_describe_util.dart'; 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:permission_handler/permission_handler.dart'; + +import 'zoom_logic.dart'; // 数据 class HomeworkReviewState { @@ -26,13 +32,16 @@ class HomeworkReviewState { late Rx data; late Rx?> studentQuestions; late Rx slide; // 滑动位置 - late bool? panQuestView; + bool? panQuestView = null; late Rx imageScale; List handwritings = []; bool needRefresh = false; bool lastQuestionPrompt = false; // 最后一题提示 Rx getDataError = false.obs; // 获取作业数据报错 + Rx initScale = Rx(null); + Offset? zoomOffset; + RxBool favorite = false.obs; // 初始化数据 // late String dateEnd = ''; // late int knowledgeId = 0; // late RxList dataList = RxList(); @@ -53,7 +62,10 @@ class HomeworkReviewAnnotationsControlState { class HomeworkReviewBinding extends Bindings { @override - void dependencies() => Get.lazyPut(() => HomeworkReviewLogic()); + void dependencies() { + Get.lazyPut(() => HomeworkReviewLogic()); + Get.lazyPut(() => ZoomLogic()); + } } class HomeworkReviewLogic extends GetxController with RequestToolMixin { @@ -62,10 +74,16 @@ class HomeworkReviewLogic extends GetxController with RequestToolMixin { late StreamSubscription _dataListen; final HomeworkReviewState state = HomeworkReviewState(); final HomeworkReviewAnnotationsControlState annotationState = HomeworkReviewAnnotationsControlState(); + double appBarHeight = 56; @override void onInit() { - super.onInit(); + appBarHeight = MediaQuery.of(Get.context!).padding.top; + print("appBarHeight :$appBarHeight"); + // WidgetsFlutterBinding.ensureInitialized(); + + // SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: []); // 屏幕刘海 + state.param = DoPaperDetailsParam( homeworkId: Get.arguments['homeworkId'], homeworkName: Get.arguments['homeworkName'], @@ -76,18 +94,42 @@ class HomeworkReviewLogic extends GetxController with RequestToolMixin { state.studentQuestions = Rx?>(null); state.imageScale = Rx(null); state.slide = 0.0.obs; - getData(); + // 参数变化更新作业详情 _paramListen = state.param.listen((e) => getData()); // 试题数据 - _dataListen = state.data.listen((e) => state.imageScale.value = null); + _dataListen = state.data.listen((e) { + if (e == null) return; + state.imageScale.value = null; + if (state.favorite.value != e.isFav) state.favorite.value = !state.favorite.value; + }); + WidgetsBinding.instance.addPostFrameCallback((_) => getData()); + super.onInit(); } @override - void disposeId(Object id) { + void onReady() { + Future.delayed(Duration.zero, () { + DeviceInfoPlugin().androidInfo.then((androidInfo) { + Permission storagePermission = androidInfo.version.sdkInt >= 33 ? Permission.manageExternalStorage : Permission.storage; + PermissionDescribeUtil.instance.toLaunchPermissionRequest( + Get.context, + title: '储存权限请求', + describe: "为了提供更好的服务,需要获取到存储权限用于保存批阅痕迹并上传", + permissions: [storagePermission], + ); + }); + }); + + super.onReady(); + } + + @override + void onClose() { + SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: [SystemUiOverlay.top, SystemUiOverlay.bottom]); // 屏幕刘海 _dataListen.cancel(); _paramListen.cancel(); - super.disposeId(id); + super.onClose(); } void getData() async { @@ -105,6 +147,7 @@ class HomeworkReviewLogic extends GetxController with RequestToolMixin { state.data.value = data; state.handwritings = []; state.studentQuestions.value = data.studentQuestions; + state.initScale.value = null; } catch (e) { print('获取数据报错了:$e'); // ToastUtils.showError('未获取到试题数据,请重试'); @@ -280,4 +323,40 @@ class HomeworkReviewLogic extends GetxController with RequestToolMixin { state.param.value = newParams; }); } + + void onPanUpPosition(Offset val) async { + // 手指在移动 非物体移动的位置 + + if (state.zoomOffset?.dy.toStringAsFixed(2) != val.dy.toStringAsFixed(2) || + state.zoomOffset?.dx.toStringAsFixed(2) != val.dx.toStringAsFixed(2)) { + print('**************** 正在移动位置 YYY:${val.dy}'); + print('**************** 正在移动位置 XXX:${val.dx}'); + state.zoomOffset = val; + state.slide.value = val.dy.abs().toInt().toDouble(); + } + } + + // 缩放组件 ==> 缩放监听 + void onScaleUpdate(double scale, double zoom) async { + state.initScale.value = zoom; + // print("$scale $zoom"); + } + + Future toFavorite() async { + try { + var data = state.data.value!; + var param = state.param.value; + await getClient().toFavStudent(FavorParam( + homeworkId: param.homeworkId, + studentId: data.studentId, + templateId: data.templateId, + questionNo: data.studentQuestions[0].questionNo, + isFav: !data.isFav, + )); + state.favorite.value = !data.isFav; + data.isFav = state.favorite.value; + } catch (e) { + ToastUtils.showError('操作失败,请重试'); + } + } } diff --git a/making_school_asignment_app/lib/page/home_page/children/homework_review/configuration_files/zoom_logic.dart b/making_school_asignment_app/lib/page/home_page/children/homework_review/configuration_files/zoom_logic.dart new file mode 100644 index 0000000..2b87d9f --- /dev/null +++ b/making_school_asignment_app/lib/page/home_page/children/homework_review/configuration_files/zoom_logic.dart @@ -0,0 +1,176 @@ +import 'dart:ui' show ImmutableBuffer, ImageDescriptor; +import 'package:cached_network_image/cached_network_image.dart'; +import 'package:flutter/widgets.dart'; + +import 'dart:async'; + +import 'package:get/get.dart'; + +import 'package:json_annotation/json_annotation.dart'; + +import 'index.dart'; + +part 'zoom_logic.g.dart'; + +class ZoomLogic extends GetxController { + final logic = Get.find(); + HomeworkReviewState get homeworkState => logic.state; + + ZoomState zoomState = ZoomState(zoomFile: Rx(null)); + + var oldTemplateId = null; + late StreamSubscription _streamHomework; + late StreamSubscription _streamZoomState; + + @override + void onInit() { + oldTemplateId = zoomState.zoomFile.value?.templateId; + _streamZoomState = zoomState.zoomFile.listen((e) { + var templateId = e?.templateId; + print("ZOOMFILE 变化了 $templateId"); + if (templateId == null) return; + + var homeworkData = homeworkState.data.value; + var zgtAnswer = homeworkData?.zgtAnswer; + print("333333"); + if (zgtAnswer == null) return; + print("444444 ${homeworkData!.templateId} 和 ${templateId}"); + if (oldTemplateId == templateId) return; + + // getNetworkImageDimensions(zgtAnswer); + + // 第三方库网络图,图片会被解码并缓存于内存 + oldTemplateId = templateId; + print("获取图片尺寸...."); + CachedNetworkImageProvider(zgtAnswer).getImageSize().then((s) { + // 提取宽度和高度 + if (s == null) return; + var oldVal = zoomState.zoomFile.value!; + oldVal.fileWidth = s.width; + oldVal.fileHeight = s.height; + zoomState.zoomFile.value = ZoomFileModel.fromJson(oldVal.toJson()); + }); + }); + _streamHomework = homeworkState.data.listen((e) { + print("HOMEWORKSTATE 变化了"); + if (e == null || zoomState.zoomFile.value == null) return; + zoomState.zoomFile.value!.templateId = e.templateId; + print("666666 ${e.templateId}"); + zoomState.zoomFile.value = ZoomFileModel.fromJson(zoomState.zoomFile.value!.toJson()); + }); + super.onInit(); + } + + @override + void onClose() { + _streamHomework.cancel(); + _streamZoomState.cancel(); + super.onClose(); + } +} + +class ZoomState { + final Rx zoomFile; + + const ZoomState({required this.zoomFile}); +} + +@JsonSerializable() +class ZoomFileModel extends Object { + double viewWidth; // 容器宽度 + double viewHeight; // 容器高度 + + int? templateId; // 页码 + + double? fileWidth; // 文件宽度 + double? fileHeight; // 文件高度 + + double? actualWidth; // 实际展示宽度 + double? actualHeight; // 实际展示高度 + + ZoomFileModel({ + required this.viewWidth, + required this.viewHeight, + this.templateId, + this.fileWidth, + this.fileHeight, + this.actualWidth, + this.actualHeight, + }) { + // 图片已视图宽为基准,高度自适应可滑动 图片的实际宽高都需要乘此基准值. + if (fileHeight == null || fileWidth == null) return; + + var scaleRatio = viewWidth / fileWidth!; + actualWidth = fileWidth! * scaleRatio; + actualHeight = fileHeight! * scaleRatio; + + // remainingHeight = boxHeight - actualImgHeight; + // imageHeightOffsetStart = remainingHeight / 2; + // imageHeightOffsetend = imageHeightOffsetStart + actualImgHeight; + } + + factory ZoomFileModel.fromJson(Map srcJson) => _$ZoomFileModelFromJson(srcJson); + + Map toJson() => _$ZoomFileModelToJson(this); +} + +// 最终版 +extension GetImageSize on ImageProvider { + Future getImageSize({bool avoidDecode = false}) async { + if (avoidDecode) { + // 是否要免解码 + final cacheStatus = await obtainCacheStatus(configuration: const ImageConfiguration()); + final tracked = cacheStatus?.tracked ?? false; + // 内存缓存中存在时优先从缓存中取,不在内存缓存中时转换为 ImageDescriptor + if (!tracked) { + ImmutableBuffer? buffer; + if (this is AssetBundleImageProvider) { + final key = await obtainKey(const ImageConfiguration()) as AssetBundleImageKey; + buffer = await key.bundle.loadBuffer(key.name); + } else if (this is FileImage) { + final file = (this as FileImage).file; + final int lengthInBytes = await file.length(); + if (lengthInBytes > 0) { + buffer = await ImmutableBuffer.fromFilePath(file.path); + } + } else if (this is MemoryImage) { + final bytes = (this as MemoryImage).bytes; + buffer = await ImmutableBuffer.fromUint8List(bytes); + } + if (buffer != null) { + final descriptor = await ImageDescriptor.encoded(buffer); + final size = Size(descriptor.width.toDouble(), descriptor.height.toDouble()); + buffer.dispose(); + descriptor.dispose(); + if (!size.isEmpty) return size; + } + } + } + + // 免解码末开启或内存缓存已存在,最后再兜底上面未处理的情况 + final completer = Completer(); + ImageStream imageStream = resolve(const ImageConfiguration()); + + ImageStreamListener? listener; + listener = ImageStreamListener( + (imageInfo, synchronousCall) { + if (!completer.isCompleted) { + completer.complete(Size(imageInfo.image.width.toDouble(), imageInfo.image.height.toDouble())); + } + WidgetsBinding.instance.addPostFrameCallback((_) { + imageInfo.dispose(); + imageStream.removeListener(listener!); + }); + }, + onError: (exception, stackTrace) { + if (!completer.isCompleted) { + completer.complete(); + } + imageStream.removeListener(listener!); + }, + ); + imageStream.addListener(listener); + + return completer.future; + } +} 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 26f8afc..8531e1d 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 @@ -7,43 +7,22 @@ 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/children/homework_review/components/question_paper_view.dart'; import 'package:making_school_asignment_app/page/home_page/home_logic.dart'; -import 'package:zoom_widget/zoom_widget.dart'; import 'components/bottom_operation_bar.dart'; import 'components/dropdown_switch_students_type.dart'; import 'components/favorite_widget.dart'; import 'configuration_files/index.dart'; -class HomeworkReview extends StatefulWidget { +class HomeworkReview extends StatelessWidget { const HomeworkReview({super.key}); - @override - State createState() => _HomeworkReviewState(); -} - -class _HomeworkReviewState extends State { - final ScrollController controller = ScrollController(); - final logic = Get.find(); - final sateData = Get.find().state; - final AnnotateClassLogic _controller = Get.find(); - final HomeLogic _homeLogicController = Get.find(); - - @override - void initState() { - WidgetsFlutterBinding.ensureInitialized(); - SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: []); // 屏幕刘海 - super.initState(); - } - - @override - void dispose() { - Get.delete(); - SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: [SystemUiOverlay.top, SystemUiOverlay.bottom]); // 屏幕刘海 - super.dispose(); - } - @override Widget build(BuildContext context) { + final logic = Get.find(); + final sateData = logic.state; + final AnnotateClassLogic _controller = Get.find(); + final HomeLogic _homeLogicController = Get.find(); + return PopScope( canPop: false, onPopInvoked: (e) { @@ -65,23 +44,22 @@ class _HomeworkReviewState extends State { ), body: Column( children: [ - // 下拉切换 + // 下拉切换 30.h const DropdownSwitchStudentsType(), + // +1 SizedBox(height: 1.h), - const Expanded( - child: QuestionPaperView(), - - // child: Container( - // height: double.infinity, - // width: double.infinity, - // color: Colors.red, - // ), - // child: QuestionPaperView(), - ), + const Expanded(child: QuestionPaperView()), + // +64.h const BottomAnnotationSwitch() ], ), - // floatingActionButton: const ButtonFloatingAction(), + // floatingActionButton: FloatingActionButton( + // elevation: 8, + // tooltip: "点击打开工具栏", + // backgroundColor: Colors.white, + // onPressed: () {}, + // child: Icon(Icons.edit, size: 20.sp, color: Theme.of(context).primaryColor), + // ), // floatingActionButtonLocation: FloatingActionButtonLocation.startFloat, ), ), 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 3771c69..7353333 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,7 +7,6 @@ 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/store/app_storage_key.dart'; @@ -16,12 +15,6 @@ import 'login_state.dart'; class LoginLogic extends GetxController with RequestToolMixin { final LoginState state = LoginState(); - @override - void onReady() { - // TODO: implement onReady - super.onReady(); - } - @override void onInit() { super.onInit(); @@ -37,6 +30,8 @@ class LoginLogic extends GetxController with RequestToolMixin { state.passwordController.text = pwd; state.keepPwd.value = true; } + state.userNameController.text = "AppleTester"; + state.passwordController.text = "AppleTester123!"; state.pwdFocus = FocusNode(); state.theFocus = FocusNode(); 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 7cbe15b..c1dbb98 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 @@ -29,15 +29,12 @@ class _LoginPageState extends State { statusBarIconBrightness: Brightness.light, statusBarColor: Colors.transparent, //状态栏背景颜色 )); - Future.delayed(Duration.zero, () => upgradeLogic.getAppUpgrade(context)); - Future.delayed(Duration.zero, () => sysProtocol(context)); - super.initState(); - } - @override - void dispose() { - Get.delete(); - super.dispose(); + WidgetsBinding.instance.addPostFrameCallback((_) async { + await sysProtocol(context); + await Future.delayed(Duration.zero, () => upgradeLogic.getAppUpgrade(context)); + }); + super.initState(); } @override @@ -231,7 +228,7 @@ class _LoginPageState extends State { padding: EdgeInsets.only(right: 0.w), child: Obx(() { return Transform.scale( - scale: 1.2, + scale: 1.0, child: Checkbox( // activeColor: Colors.transparent, //去掉勾选时背景颜色 @@ -290,10 +287,10 @@ class _LoginPageState extends State { }, child: Obx(() { return Container( - margin: EdgeInsets.symmetric(vertical: 10.h), - decoration: BoxDecoration( - color: state.canLogin.value ? const Color(0xFF8C68FF) : const Color(0xFFdddddd), - /*boxShadow: [ + margin: EdgeInsets.symmetric(vertical: 10.h), + decoration: BoxDecoration( + color: state.canLogin.value ? const Color(0xFF8C68FF) : const Color(0xFFdddddd), + /*boxShadow: [ BoxShadow( color: const Color.fromRGBO(76, 199, 147, 0.5), @@ -302,15 +299,14 @@ class _LoginPageState extends State { spreadRadius: 0.5, //阴影扩散程度 ) ],*/ - borderRadius: BorderRadius.all( - Radius.circular(17.w), + borderRadius: BorderRadius.all( + Radius.circular(17.w), + ), ), - ), - alignment: Alignment.center, - width: double.infinity, - height: 50.h, - child: Text('登 录', style: TextStyle(fontSize: 16.sp, color: Colors.white)), - ); + alignment: Alignment.center, + width: double.infinity, + height: 50.h, + child: quickText('登 录', size: 18.sp, color: Colors.white)); }), ), Row( @@ -320,7 +316,7 @@ class _LoginPageState extends State { padding: EdgeInsets.only(right: 0.w), child: Obx(() { return Transform.scale( - scale: 1.2, + scale: 1.0, child: Checkbox( activeColor: Theme.of(context).primaryColor, checkColor: Colors.white, @@ -372,7 +368,7 @@ class _LoginPageState extends State { child: quickText( '《隐私协议》', size: 12.sp, - color:Theme.of(context).primaryColor, + color: Theme.of(context).primaryColor, ), ), ], diff --git a/making_school_asignment_app/pubspec.yaml b/making_school_asignment_app/pubspec.yaml index ff38be2..a6211b2 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.1+2 +version: 1.0.0+1 environment: sdk: '>=3.4.1 <4.0.0' @@ -48,7 +48,7 @@ dependencies: # http请求插件 dio: ^5.4.2+1 # 网络缓存图片 - cached_network_image: ^3.2.1 + cached_network_image: ^3.3.1 # 上拉加载和下拉刷新的组件 flutter_easyrefresh: ^2.2.2 photo_view: ^0.15.0 @@ -98,7 +98,8 @@ dependencies: app_settings: ^5.1.1 device_info_plus: ^11.1.0 zoom_widget: ^2.0.1 - + zoom_pinch_overlay: ^1.4.3 + flutter_html_2: ^0.1.0 dev_dependencies: @@ -109,6 +110,7 @@ dev_dependencies: json_serializable: ^6.6.2 # 分离样式 functional_widget: ^0.10.2 + analyzer: ^6.4.1 # The "flutter_lints" package below contains a set of recommended lints to # encourage good coding practices. The lint set provided by the package is # activated in the `analysis_options.yaml` file located at the root of your @@ -120,6 +122,9 @@ dev_dependencies: # following page: https://dart.dev/tools/pub/pubspec # The following section is specific to Flutter packages. +# dependency_overrides: +# collection: ^1.19.0 + flutter: # The following line ensures that the Material Icons font is