修复优化页面,修复部分问题。暂时提交

This commit is contained in:
DESKTOP-I3JPKHK\wy 2025-09-10 16:49:25 +08:00
parent 70f658f87d
commit b6af1f57a4
11 changed files with 709 additions and 405 deletions

View File

@ -180,7 +180,7 @@ class ShapeRecognizer {
// return GestureType.none;
}
///
///
/// [checkCandidate]
/// [crosserCandidate] 线
/// [checkDetails]
@ -217,7 +217,7 @@ class ShapeRecognizer {
return false; //
}
/// []
///
/// `checkLeg` `crossLine`
Offset? _findIntersectionNearTip(
Offset crossLineStart, Offset crossLineEnd, Offset checkLegStart, Offset checkLegEnd) {

View File

@ -41,7 +41,7 @@ void main() async {
statusBarColor: Colors.transparent, //
statusBarIconBrightness: Brightness.light // dark: light
));
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: [SystemUiOverlay.top]); //
SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersiveSticky, overlays: [SystemUiOverlay.top]); //
await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]); //
runApp(const MyApp());

View File

@ -40,7 +40,7 @@ class _GestureCanvasPageState extends State<GestureCanvasPage> {
GestureType _recognizedGesture = GestureType.none;
late ShapeRecognizer _recognizer;
// []
//
bool _showSimplifiedPoints = true;
@override
@ -123,7 +123,7 @@ class _GestureCanvasPageState extends State<GestureCanvasPage> {
appBar: AppBar(
title: const Text('手势识别 (可视化调试)'),
actions: [
// [] AppBar中添加一个信息提示
// AppBar中添加一个信息提示
Padding(
padding: const EdgeInsets.only(right: 16.0),
child: Icon(
@ -179,7 +179,7 @@ class _GestureCanvasPageState extends State<GestureCanvasPage> {
child: const Icon(Icons.clear),
),
const SizedBox(height: 10),
// []
//
FloatingActionButton(
onPressed: () {
setState(() {
@ -205,7 +205,7 @@ class _GestureCanvasPainter extends CustomPainter {
final List<List<Offset>> allStrokes;
final double rdpEpsilon;
final bool showSimplifiedPoints;
final Paint _debugPaint; // []
final Paint _debugPaint; //
_GestureCanvasPainter({
required this.cachedImage,
@ -218,7 +218,7 @@ class _GestureCanvasPainter extends CustomPainter {
..strokeCap = StrokeCap.round
..strokeWidth = 5.0
..style = PaintingStyle.stroke,
// []
//
_debugPaint = Paint()
..color = Colors.red
..strokeCap = StrokeCap.round
@ -241,7 +241,7 @@ class _GestureCanvasPainter extends CustomPainter {
canvas.drawPath(path, _paint);
}
// [] 3:
// 3:
if (showSimplifiedPoints) {
//
for (final stroke in allStrokes) {

View File

@ -7,7 +7,6 @@ import 'package:making_school_asignment_app/common/job/marking_models/do_paper_b
import 'package:making_school_asignment_app/common/mixins/event_bus_mixin.dart';
import 'package:making_school_asignment_app/common/utils/anti_shake_throttling.dart';
import 'package:making_school_asignment_app/common/utils/utils.dart';
import 'package:making_school_asignment_app/page/global_widget/my_text.dart';
import '../configuration_files/index.dart';
@ -62,19 +61,23 @@ class _BottomAnnotationSwitchJobState extends State<BottomAnnotationSwitch>
@override
Widget build(BuildContext context) {
double iconSize = 18.sp;
Color actionColor = Colors.white;
Color defaultColor = const Color.fromRGBO(132, 146, 163, 1);
return SafeArea(
left: false,
right: false,
top: false,
child: Container(
width: double.infinity,
height: _animationController.value * 64.h,
height: _animationController.value * 70.h,
decoration: BoxDecoration(
color: const Color.fromRGBO(83, 83, 83, 1),
// padding: EdgeInsets.symmetric(vertical: 1.h),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.1),
blurRadius: 8,
offset: const Offset(0, -2),
),
],
),
child: Row(
children: [
Expanded(
@ -87,109 +90,83 @@ class _BottomAnnotationSwitchJobState extends State<BottomAnnotationSwitch>
children: [
//
Expanded(
child: SizedBox(
width: double.infinity,
height: double.infinity,
child: TextButton(
child: quickText('全 对', color: Colors.white, size: 12.sp),
onPressed: () => easyThrottle('homework_bottom_operation_bar_scoring_related',
child: _buildActionButton(
'全对',
Icons.check_circle_outline,
() => easyThrottle('homework_bottom_operation_bar_scoring_related',
() => _homeworkLogic.allPairs(context)),
isEnabled: !_homeworkLogic.state.submitLoading.value,
isPrimary: true,
),
),
),
Container(width: 0.3.w, height: double.infinity, color: Colors.white),
Container(width: 0.5.w, height: double.infinity, color: Colors.white.withOpacity(0.3)),
//
Expanded(
child: SizedBox(
width: double.infinity,
height: double.infinity,
child: IconButton(
icon: Obx(() {
return Icon(
child: Obx(() => _buildIconButton(
const IconData(0xe635, fontFamily: "AlibabaIcon"),
size: iconSize,
color: _logicControl.pen.value ? Theme.of(context).primaryColor : defaultColor,
);
}),
onPressed: () => easyThrottle('homework_bottom_action_bar_annotations', () {
() => easyThrottle('homework_bottom_action_bar_annotations', () {
//
_logicControl.gestureMove.value = false;
_logicControl.pen.value = !_logicControl.pen.value;
_logicControl.pen.value = true;
}),
isActive: _logicControl.pen.value,
tooltip: '注解笔',
)),
),
),
),
Container(width: 0.3.w, height: double.infinity, color: Colors.white),
Container(width: 0.5.w, height: double.infinity, color: Colors.white.withOpacity(0.3)),
//
Expanded(
child: SizedBox(
width: double.infinity,
height: double.infinity,
child: IconButton(
icon: Obx(
() {
return Icon(
child: Obx(() => _buildIconButton(
const IconData(0xe636, fontFamily: "AlibabaIcon"),
size: iconSize,
color: _logicControl.gestureMove.value ? actionColor : defaultColor,
);
},
),
onPressed: () => easyThrottle('homework_bottom_action_bar_annotations', () {
() => easyThrottle('homework_bottom_action_bar_annotations', () {
//
_logicControl.pen.value = false;
_logicControl.gestureMove.value = !_logicControl.gestureMove.value;
_logicControl.gestureMove.value = true;
}),
),
),
isActive: _logicControl.gestureMove.value,
tooltip: '滑动试题',
)),
),
],
),
),
Container(width: double.infinity, color: Colors.white, height: 0.35.h),
Container(width: double.infinity, color: Colors.white.withOpacity(0.3), height: 0.5.h),
Expanded(
child: Row(
children: [
//
Expanded(
child: SizedBox(
width: double.infinity,
height: double.infinity,
child: TextButton(
onPressed: () => easyThrottle('homework_bottom_operation_bar_scoring_related',
child: _buildActionButton(
'全错',
Icons.cancel_outlined,
() => easyThrottle('homework_bottom_operation_bar_scoring_related',
() => _homeworkLogic.allWrongRating(context)),
child: quickText('全 错', color: Colors.white, size: 12.sp),
isEnabled: !_homeworkLogic.state.submitLoading.value,
isPrimary: false,
),
),
),
Container(width: 0.3.w, height: double.infinity, color: Colors.white),
Container(width: 0.5.w, height: double.infinity, color: Colors.white.withOpacity(0.3)),
//
Expanded(
child: SizedBox(
width: double.infinity,
height: double.infinity,
child: IconButton(
onPressed: () => easyThrottle(
child: _buildIconButton(
const IconData(0xe638, fontFamily: "AlibabaIcon"),
() => easyThrottle(
'homework_bottom_action_bar_annotations',
() => eventFire(model: BottomOperationBar(revokeAll: false, revokePreStep: true)),
),
icon: Icon(const IconData(0xe638, fontFamily: "AlibabaIcon"),
size: iconSize, color: defaultColor),
tooltip: '撤销上一步',
),
),
),
Container(width: 0.3.w, height: double.infinity, color: Colors.white),
Container(width: 0.5.w, height: double.infinity, color: Colors.white.withOpacity(0.3)),
//
Expanded(
child: SizedBox(
width: double.infinity,
height: double.infinity,
child: IconButton(
icon: Icon(const IconData(0xe637, fontFamily: "AlibabaIcon"),
size: iconSize, color: defaultColor),
onPressed: () => easyThrottle(
child: _buildIconButton(
const IconData(0xe637, fontFamily: "AlibabaIcon"),
() => easyThrottle(
'homework_bottom_action_bar_annotations',
() => eventFire(model: BottomOperationBar(revokeAll: true, revokePreStep: false)),
),
),
tooltip: '全部撤销',
),
),
],
@ -198,49 +175,36 @@ class _BottomAnnotationSwitchJobState extends State<BottomAnnotationSwitch>
],
),
),
Container(width: 0.3.w, height: double.infinity, color: Colors.white),
Container(width: 0.5.w, height: double.infinity, color: Colors.white.withOpacity(0.3)),
Expanded(
flex: 3,
child: Row(
children: [
Expanded(
child: SizedBox(
width: double.infinity,
height: double.infinity,
child: TextButton(
onPressed: () => easyThrottle(
child: _buildActionButton(
'取消',
Icons.clear,
() => easyThrottle(
'homework_bottom_operation_bar_scoring_related', () => _homeworkLogic.cancelAllRatings()),
child: quickText('取 消', size: 14.sp, color: Colors.white),
isEnabled: true,
isPrimary: false,
isSecondary: true,
),
),
),
Container(width: 0.3.w, height: double.infinity, color: Colors.white),
Container(width: 0.5.w, height: double.infinity, color: Colors.white.withOpacity(0.3)),
Expanded(
child: SizedBox(
width: double.infinity,
height: double.infinity,
child: TextButton(
onPressed: () => easyThrottle(
child: Obx(() {
final submitLoading = _homeworkLogic.state.submitLoading.value;
return _buildActionButton(
'提交',
Icons.send,
() => easyThrottle(
'homework_bottom_operation_bar_scoring_related', () => _homeworkLogic.submit(context)),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Obx(() {
if (_homeworkLogic.state.submitLoading.value) {
return Padding(
padding: EdgeInsets.only(right: 4.w),
child: const SizedBox(
width: 20, height: 20, child: CircularProgressIndicator(strokeWidth: 2)),
isEnabled: !submitLoading,
isPrimary: true,
isLoading: submitLoading,
);
}
return const SizedBox();
}),
quickText('提 交', size: 14.sp, color: Theme.of(context).primaryColor),
],
),
),
),
),
],
),
@ -249,4 +213,124 @@ class _BottomAnnotationSwitchJobState extends State<BottomAnnotationSwitch>
),
));
}
Widget _buildActionButton(
String text,
IconData icon,
VoidCallback? onPressed, {
required bool isEnabled,
required bool isPrimary,
bool isSecondary = false,
bool isLoading = false,
}) {
final primaryColor = Theme.of(context).primaryColor;
const defaultColor = Color.fromRGBO(132, 146, 163, 1);
return Material(
color: Colors.transparent,
child: InkWell(
onTap: isEnabled ? onPressed : null,
child: Semantics(
label: text,
hint: isLoading ? '正在处理中' : (isEnabled ? '点击执行$text操作' : '$text按钮已禁用'),
button: true,
enabled: isEnabled && !isLoading,
child: Container(
width: double.infinity,
height: double.infinity,
decoration: BoxDecoration(
color: isPrimary
? (isEnabled ? primaryColor : primaryColor.withOpacity(0.5))
: isSecondary
? Colors.transparent
: Colors.transparent,
borderRadius: BorderRadius.circular(4.r),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (isLoading)
SizedBox(
width: 16.w,
height: 16.w,
child: CircularProgressIndicator(
strokeWidth: 2,
valueColor: AlwaysStoppedAnimation<Color>(
isPrimary ? Colors.white : primaryColor,
),
),
)
else
Icon(
icon,
size: 16.sp,
color: isEnabled
? (isPrimary ? Colors.white : (isSecondary ? Colors.white70 : defaultColor))
: Colors.white38,
),
SizedBox(height: 2.h),
Text(
text,
style: TextStyle(
fontSize: 10.sp,
color: isEnabled
? (isPrimary ? Colors.white : (isSecondary ? Colors.white70 : Colors.white))
: Colors.white38,
fontWeight: FontWeight.w500,
),
),
],
),
),
),
),
);
}
Widget _buildIconButton(
IconData icon,
VoidCallback? onPressed, {
bool isActive = false,
String? tooltip,
}) {
final primaryColor = Theme.of(context).primaryColor;
const defaultColor = Color.fromRGBO(132, 146, 163, 1);
return Material(
color: Colors.transparent,
child: InkWell(
onTap: onPressed,
child: Tooltip(
message: tooltip ?? '',
child: Container(
width: double.infinity,
height: double.infinity,
decoration: BoxDecoration(
color: isActive ? primaryColor.withOpacity(0.2) : Colors.transparent,
borderRadius: BorderRadius.circular(4.r),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
icon,
size: 18.sp,
color: isActive ? primaryColor : defaultColor,
),
SizedBox(height: 2.h),
Container(
width: 4.w,
height: 4.w,
decoration: BoxDecoration(
color: isActive ? primaryColor : Colors.transparent,
shape: BoxShape.circle,
),
),
],
),
),
),
),
);
}
}

View File

@ -6,7 +6,6 @@ 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/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';
@ -61,7 +60,8 @@ class DropdownSwitchStudentsType extends StatelessWidget {
items: sateData.value?.templateIdKeys?.map((e) {
return DropdownMenuItem(
value: e,
child: quickText('${sateData.value!.templateIdKeyMap![e]}', color: const Color.fromRGBO(79, 79, 79, 1), size: 14.sp),
child: quickText('${sateData.value!.templateIdKeyMap![e]}',
color: const Color.fromRGBO(79, 79, 79, 1), size: 14.sp),
);
}).toList(),
onChanged: (value) {
@ -77,7 +77,9 @@ class DropdownSwitchStudentsType extends StatelessWidget {
final students = sateData.value?.students ?? [];
//
final currentStudent = currentStudentId != null ? students.firstWhereOrNull((e) => e.id == currentStudentId) : null;
final currentStudent = currentStudentId != null
? students.firstWhereOrNull((e) => e.id == currentStudentId)
: null;
final studentName = currentStudent?.name ?? '当前学生';
final questionNumber = templateIdKeyMap?[value] ?? '当前选择页';
@ -95,7 +97,7 @@ class DropdownSwitchStudentsType extends StatelessWidget {
}),
),
),
const Expanded(flex: 1, child: SizedBox()),
SizedBox(width: 8.w),
Expanded(
flex: 3,
child: Stack(
@ -120,7 +122,9 @@ class DropdownSwitchStudentsType extends StatelessWidget {
alignment: const FractionalOffset(0, 0.62),
children: [
Container(
padding: sateData.value?.studentId != e.id && e.isPriority ? EdgeInsets.only(left: 14.w) : null,
padding: sateData.value?.studentId != e.id && e.isPriority
? EdgeInsets.only(left: 14.w)
: null,
child: quickText(
e.name,
size: 14.sp,
@ -134,7 +138,9 @@ class DropdownSwitchStudentsType extends StatelessWidget {
Icon(
const IconData(0xe63d, fontFamily: "AlibabaIcon"),
size: 12.sp,
color: e.isPriority ? Theme.of(context).primaryColor : const Color.fromRGBO(164, 164, 164, 1),
color: e.isPriority
? Theme.of(context).primaryColor
: const Color.fromRGBO(164, 164, 164, 1),
),
quickText('优先', size: 4.sp, color: Colors.white),
],
@ -161,7 +167,9 @@ class DropdownSwitchStudentsType extends StatelessWidget {
return Icon(
const IconData(0xe63d, fontFamily: "AlibabaIcon"),
size: 12.sp,
color: sateData.value?.priority ?? false ? Theme.of(context).primaryColor : const Color.fromRGBO(164, 164, 164, 1),
color: sateData.value?.priority ?? false
? Theme.of(context).primaryColor
: const Color.fromRGBO(164, 164, 164, 1),
);
}),
quickText('优先', size: 4.sp, color: Colors.white),
@ -173,9 +181,9 @@ class DropdownSwitchStudentsType extends StatelessWidget {
),
// const Expanded(flex: 1, child: SizedBox()),
SizedBox(width: 8.w),
Expanded(
flex: isPad() ? 4 : 5,
child: const Row(
const Expanded(
flex: 5,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
@ -208,7 +216,8 @@ Widget $studentHandwriting(BuildContext context) {
if (templateIdKeyMap != null && templateId != null) {
pageNum = templateIdKeyMap[templateId];
}
await showAnswerHandwriting(context, homeworkId: homeworkId, studentId: studentId, templateId: templateId, pageNum: pageNum);
await showAnswerHandwriting(context,
homeworkId: homeworkId, studentId: studentId, templateId: templateId, pageNum: pageNum);
ToastUtils.dismiss();
},
),
@ -238,7 +247,10 @@ Widget $continueToReview(BuildContext context, {bool isFloatingAction = false})
int? annotatedCount = data?.annotatedCount; //
// || (submitCount == annotatedCount || (param.templateId == null && param.studentId == null))
// if (data == null || (data.needAnnotate ? true : data.totalUnAnnotateCount <= 0) ) return const SizedBox();
if (data == null || (data.needAnnotate ? (data.continuePage == null ? true : data.continuePage!.templateId == data.templateId) : data.totalUnAnnotateCount <= 0)) return const SizedBox();
if (data == null ||
(data.needAnnotate
? (data.continuePage == null ? true : data.continuePage!.templateId == data.templateId)
: data.totalUnAnnotateCount <= 0)) return const SizedBox();
callFun() => easyThrottle(
'DO_PAPERS_JOB_CONTINUE_TO_REVIEW',
() {
@ -292,7 +304,11 @@ Widget $historyHomework(BuildContext context) {
var currentStudent = sateData.value!.students.firstWhereOrNull((e) => e.id == studentId);
if (currentStudent == null) return;
var theState = Get.find<HomeworkReviewLogic>().state;
Get.toNamed(Routes.studentWorkDetailPage, arguments: {'studentId': studentId, 'studentName': currentStudent.name, 'subject': theState.param.value.subject});
Get.toNamed(Routes.studentWorkDetailPage, arguments: {
'studentId': studentId,
'studentName': currentStudent.name,
'subject': theState.param.value.subject
});
}),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,

View File

@ -547,20 +547,18 @@ class QuestionImageView extends HookWidget with EventBusMixin<BottomOperationBar
// }
// (dy / theScale) - (max(0, imageHeightOffsetStart) / theScale) + ((sateData.zoomOffset?.dy.abs() ?? 0) / theScale),
var zoomWtdthSpaceVal = zoomFile.getZoomFileOffsetStartWidth(zoomState.initScale.value ?? 1);
var leftOffset = zoomFile.getZoomFileOffsetStartWidth(theScale);
var topOffset = max(0, imageHeightOffsetStart);
localPosition = Offset(
(localPosition.dx -
zoomFile.getZoomFileOffsetStartWidth(zoomState.initScale.value ?? 1) +
((zoomWtdthSpaceVal <= 0.1) ? (sateData.zoomOffset?.dx.abs() ?? 0) : 0)) /
theScale,
(dy -
max(0, imageHeightOffsetStart) +
((zoomFile.imageHeightOffsetStart == null || zoomFile.imageHeightOffsetStart! <= 0.1)
? (sateData.zoomOffset?.dy.abs() ?? 0)
: 0)) /
theScale,
);
// 使//
final translation = logic.zoomController.value.getTranslation();
final panDx = translation.x;
final panDy = translation.y;
//
final correctedDx = (localPosition.dx - leftOffset - panDx) / theScale;
final correctedDy = (dy - topOffset - panDy) / theScale;
localPosition = Offset(correctedDx, correctedDy);
///
if (Platform.isAndroid) {
@ -579,13 +577,13 @@ class QuestionImageView extends HookWidget with EventBusMixin<BottomOperationBar
var isPen = annotationState.pen.value;
var showZgtAnnotate = sateData.data.value?.showZgtAnnotate;
print(sateData.data.value!.zgtAnswer);
return Container(
height: double.infinity,
width: double.infinity,
alignment: Alignment.center,
child: IgnorePointer(
ignoring: isPen,
// Zoom
ignoring: !annotationState.gestureMove.value,
child:
// ZoomView(
// key: zoomKey.value,
@ -600,7 +598,8 @@ class QuestionImageView extends HookWidget with EventBusMixin<BottomOperationBar
// onContentOffset: logic.zoomLogic.onPanUpPosition,
// ),
Zoom(
Obx(
() => Zoom(
key: zoomKey.value,
// initTotalZoomOut: true, //
zoomSensibility: 0.05,
@ -627,7 +626,7 @@ class QuestionImageView extends HookWidget with EventBusMixin<BottomOperationBar
key: logic.pictureOverviewKey,
child: CustomPaint(
// isComplex: true,
size: Size(maxWidth, zoomState.zoomFile.value!.actualHeight!),
size: Size(maxWidth, actualHeight),
foregroundPainter: DrawingPainter(ctrl: vnHandWritings),
// child: $TheCachedNetworkImage(
// imgWidth: maxWidth,
@ -645,7 +644,7 @@ class QuestionImageView extends HookWidget with EventBusMixin<BottomOperationBar
],
),
),
),
)),
);
}),
);

View File

@ -6,6 +6,7 @@ import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.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/job/annotate_list_to_refresh.dart';
import 'package:making_school_asignment_app/common/job/marking_models/do_paper_details_param.dart';
@ -18,7 +19,6 @@ import 'package:making_school_asignment_app/common/mixins/request_tool_mixin.dar
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 'package:zoom_widget/zoom_widget.dart' as zoomWidget;
@ -88,7 +88,6 @@ class HomeworkReviewLogic extends GetxController with RequestToolMixin, EventBus
@override
void onInit() {
appBarHeight = MediaQuery.of(Get.context!).padding.top;
print("appBarHeight $appBarHeight");
// WidgetsFlutterBinding.ensureInitialized();
// SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: []); //
@ -158,17 +157,13 @@ class HomeworkReviewLogic extends GetxController with RequestToolMixin, EventBus
}
void getData() async {
//
if (state.submitLoading.value) return;
var timerControl = Timer(const Duration(milliseconds: 300), () => ToastUtils.showLoading());
try {
DoPaperDetailsResult data = await getClient().getDoPaperDetails(state.param.value);
// var studentQuestions = data.studentQuestions;
// // 0
// for (var i = 0; i < studentQuestions.length; i++) {
// var item = studentQuestions[i];
// item.topHeight = itemPre.height;
// }
state.getDataError.value = false;
state.handwritings = [];
@ -179,8 +174,8 @@ class HomeworkReviewLogic extends GetxController with RequestToolMixin, EventBus
state.data.value = data;
} catch (e) {
print('获取数据报错了:$e');
// ToastUtils.showError('未获取到试题数据,请重试');
state.getDataError.value = true;
ToastUtils.showError('获取试题数据失败,请检查网络连接后重试');
} finally {
if (timerControl.isActive) timerControl.cancel();
ToastUtils.dismiss();
@ -278,18 +273,24 @@ class HomeworkReviewLogic extends GetxController with RequestToolMixin, EventBus
ToastUtils.showInfo("正在提交批阅数据,请勿重复操作");
return;
}
state.submitLoading.value = true;
var data = state.data.value;
if (data == null) return;
if ((state.data.value?.studentQuestions.isEmpty ?? true) || (state.studentQuestions.value?.isEmpty ?? true)) {
if (data == null) {
ToastUtils.showError('数据异常,请重新加载');
return;
}
if ((state.data.value?.studentQuestions.isEmpty ?? true) || (state.studentQuestions.value?.isEmpty ?? true)) {
ToastUtils.showError('没有可批阅的试题');
return;
}
var studentQuestions = state.studentQuestions.value!.where((e) => e.useTime != null && e.useTime! > 0).toList();
//
var noRatingElement = studentQuestions.firstWhereOrNull((e) => e.studentScore == null);
if (noRatingElement != null) {
ToastUtils.showInfo('${noRatingElement.questionNo}题请评分');
ToastUtils.showInfo('${noRatingElement.questionNo}题请评分');
return;
}
@ -320,35 +321,13 @@ class HomeworkReviewLogic extends GetxController with RequestToolMixin, EventBus
if (totalUnAnnotateCount <= 0) {
//
if (!state.lastQuestionPrompt) {
await showDialog(
context: Get.context ?? context,
builder: (BuildContext context1) {
return AlertDialog(
title: quickText('批阅已完成'),
content: const Text('暂无更多批阅项'),
actions: <Widget>[
TextButton(
child: const Text('继续'),
onPressed: () {
state.lastQuestionPrompt = true;
Navigator.of(context1).pop();
},
),
TextButton(
child: const Text('退出批阅'),
onPressed: () {
Navigator.of(context1).pop();
Get.back();
}),
],
);
},
);
await _showCompletionDialog(context);
} else {
ToastUtils.showSuccess("提交", duration: const Duration(milliseconds: 800));
ToastUtils.showSuccess("批阅已提交", duration: const Duration(milliseconds: 800));
}
return;
}
var newParams = DoPaperDetailsParam.fromJson(state.param.value.toJson());
if (totalUnAnnotateCount > 0) {
//
@ -356,14 +335,52 @@ class HomeworkReviewLogic extends GetxController with RequestToolMixin, EventBus
newParams.studentId = null;
}
state.param.value = newParams;
ToastUtils.showSuccess("批阅已提交");
});
} catch (_) {
print("批阅提交报错 $_");
} catch (e) {
print("批阅提交报错 $e");
ToastUtils.showError('提交失败,请检查网络连接后重试');
} finally {
state.submitLoading.value = false;
}
}
Future<void> _showCompletionDialog(BuildContext context) async {
await showDialog(
context: Get.context ?? context,
barrierDismissible: false,
builder: (BuildContext context1) {
return AlertDialog(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12.r)),
title: Row(
children: [
Icon(Icons.check_circle, color: Colors.green, size: 24.sp),
SizedBox(width: 8.w),
Text('批阅已完成', style: TextStyle(fontSize: 18.sp, fontWeight: FontWeight.w600)),
],
),
content: Text('暂无更多批阅项,是否继续?', style: TextStyle(fontSize: 14.sp)),
actions: <Widget>[
TextButton(
child: Text('退出批阅', style: TextStyle(color: Colors.grey[600])),
onPressed: () {
Navigator.of(context1).pop();
Get.back();
},
),
TextButton(
child: Text('继续', style: TextStyle(color: Theme.of(context).primaryColor)),
onPressed: () {
state.lastQuestionPrompt = true;
Navigator.of(context1).pop();
},
),
],
);
},
);
}
Future<void> toFavorite() async {
try {
var data = state.data.value!;

View File

@ -3,7 +3,6 @@ import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:making_school_asignment_app/common/job/annotate_list_to_refresh.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/children/homework_review/components/bottom_operation_bar.dart';
import 'package:making_school_asignment_app/page/home_page/children/homework_review/components/question_paper_view.dart';
@ -55,8 +54,16 @@ class HomeworkReview extends StatelessWidget {
children: [
SizedBox(width: 5.w),
IconButton(
icon: const Icon(Icons.arrow_back_ios, color: Colors.black), onPressed: () => Get.back()),
Expanded(child: quickText(sateData.param.value.homeworkName, size: 18.sp).paddingOnly(top: 2.h)),
icon: const Icon(Icons.arrow_back_ios, color: Colors.black),
onPressed: () => Get.back(),
tooltip: '返回'),
Expanded(
child: Text(
sateData.param.value.homeworkName,
style: TextStyle(fontSize: 18.sp, fontWeight: FontWeight.w600),
overflow: TextOverflow.ellipsis,
),
),
const FavoriteWidget(),
SizedBox(width: 10.w),
const ReturnToHomepage(),

View File

@ -3,7 +3,6 @@ import 'package:get/get.dart';
import 'package:making_school_asignment_app/common/job/work_student.dart';
import 'package:making_school_asignment_app/common/job/work_student_params.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 'home_state.dart';
@ -24,16 +23,20 @@ class HomeLogic extends GetxController with RequestToolMixin, GetTickerProviderS
}
void getList() async {
try {
params.pageNumber = state.pageNumber;
WorkStudent data = await getClient().getUnAnnotateList(params);
state.totalCount.value = data.totalCount;
state.readOver.value = data.items.length;
/* if(params.pageNumber == 1){
state.workList.value = data.items;
}else{
state.workList.addAll(data.items);
//
refreshController.finishRefresh();
} catch (e) {
print('获取作业列表失败: $e');
//
refreshController.finishRefresh();
//
}
refreshController.finishRefresh();*/
}
@override

View File

@ -40,93 +40,104 @@ class HomePage extends GetxKeepAliveWidget<HomeLogic> {
enableControlFinishLoad: true,
controller: controller.refreshController,
header: MaterialHeader(),
// footer: TaurusFooter(),
onRefresh: () async {
state.pageNumber = 1;
return controller.getList();
},
// onLoad: () async {
// if (state.workList.length < state.totalCount.value) {
// state.pageNumber++;
// return logic.getList();
// }
// },
child: Stack(
children: [
Image.asset(
child: CustomScrollView(
slivers: [
//
SliverAppBar(
expandedHeight: 300.h,
floating: false,
pinned: false,
backgroundColor: Colors.transparent,
flexibleSpace: FlexibleSpaceBar(
background: Image.asset(
'assets/images/home_banner.png',
width: Get.width,
fit: BoxFit.fill,
fit: BoxFit.cover,
),
Container(
margin: EdgeInsets.only(top: 300.h),
),
),
//
SliverToBoxAdapter(
child: Container(
padding: EdgeInsets.symmetric(vertical: 0, horizontal: 20.r),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(topLeft: Radius.circular(30.r), topRight: Radius.circular(30.r))),
borderRadius: BorderRadius.only(topLeft: Radius.circular(30.r), topRight: Radius.circular(30.r)),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: 15.r),
SizedBox(height: 20.r),
//
Row(
children: [
Icon(
Icons.assignment_outlined,
size: 24.sp,
color: const Color(0xFF4F4F4F),
),
SizedBox(width: 8.r),
Text(
'我的作业管理',
style: TextStyle(fontSize: 20.sp, color: const Color(0xFF676666), fontWeight: FontWeight.w600),
style: TextStyle(
fontSize: 22.sp, color: const Color(0xFF2C2C2C), fontWeight: FontWeight.w700),
),
SizedBox(height: 15.r),
Row(
const Spacer(),
//
Obx(() => IconButton(
onPressed: state.totalCount.value > 0 ? () => controller.getList() : null,
icon: Icon(
Icons.refresh,
size: 20.sp,
color: const Color(0xFF4F4F4F),
),
tooltip: '刷新数据',
)),
],
),
SizedBox(height: 20.r),
//
Container(
padding: EdgeInsets.all(16.r),
decoration: BoxDecoration(
color: const Color(0xFFF8F9FA),
borderRadius: BorderRadius.circular(12.r),
border: Border.all(color: const Color(0xFFE9ECEF), width: 1),
),
child: Row(
children: [
Expanded(
child: Obx(() {
return $MenuItem(
bgImg: 'assets/images/home_bg_01.png',
name: '作业批阅',
value: state.totalCount.value.toString(),
url: Routes.readOverPage,
);
}),
child: _buildStatCard(
'待批阅',
state.totalCount.value.toString(),
const Color(0xFFFF6969),
Icons.assignment_turned_in,
),
),
SizedBox(width: 16.r),
Expanded(
child: _buildStatCard(
'已批阅',
'0', //
const Color(0xFF28A745),
Icons.check_circle_outline,
),
SizedBox(width: 20.r),
const Expanded(
child: $MenuItem(
bgImg: 'assets/images/home_bg_02.png',
name: '知识点掌握',
url: Routes.studentHistoryWorkPage,
page: 'points'),
),
],
),
),
SizedBox(height: 24.r),
//
_buildMenuGrid(context, state),
SizedBox(height: 20.r),
Row(
children: [
const Expanded(
child: $MenuItem(
bgImg: 'assets/images/home_bg_03.png',
name: '学生历史作业',
url: Routes.studentHistoryWorkPage,
page: 'history'),
),
SizedBox(width: 20.r),
const Expanded(
child: $MenuItem(
bgImg: 'assets/images/home_bg_04.png', name: '答题轨迹', url: Routes.answerTrajectoryPage),
),
],
),
SizedBox(height: 20.r),
Row(
children: [
const $MenuItem(
bgImg: 'assets/images/home_bg_05.png',
name: '优先批阅设定',
url: Routes.studentHistoryWorkPage,
page: 'set',
),
SizedBox(width: 20.r),
],
),
SizedBox(height: 15.h),
],
),
)
],
),
);
@ -134,23 +145,165 @@ class HomePage extends GetxKeepAliveWidget<HomeLogic> {
),
);
}
Widget _buildStatCard(String title, String value, Color color, IconData icon) {
return Container(
padding: EdgeInsets.all(12.r),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8.r),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.05),
blurRadius: 4,
offset: const Offset(0, 2),
),
],
),
child: Column(
children: [
Icon(icon, color: color, size: 20.sp),
SizedBox(height: 4.r),
Text(
value,
style: TextStyle(
fontSize: 18.sp,
fontWeight: FontWeight.bold,
color: color,
),
),
Text(
title,
style: TextStyle(
fontSize: 12.sp,
color: const Color(0xFF6C757D),
),
),
],
),
);
}
Widget _buildMenuGrid(BuildContext context, dynamic state) {
return Column(
children: [
//
Row(
children: [
Expanded(
child: Obx(() => $menuItem(
bgImg: 'assets/images/home_bg_01.png',
name: '作业批阅',
value: state.totalCount.value > 0 ? state.totalCount.value.toString() : null,
url: Routes.readOverPage,
isPrimary: true,
)),
),
SizedBox(width: 16.r),
Expanded(
child: $menuItem(
bgImg: 'assets/images/home_bg_02.png',
name: '知识点掌握',
url: Routes.studentHistoryWorkPage,
page: 'points',
),
),
],
),
SizedBox(height: 16.r),
//
Row(
children: [
Expanded(
child: $menuItem(
bgImg: 'assets/images/home_bg_03.png',
name: '学生历史作业',
url: Routes.studentHistoryWorkPage,
page: 'history',
),
),
SizedBox(width: 16.r),
Expanded(
child: $menuItem(bgImg: 'assets/images/home_bg_04.png', name: '答题轨迹', url: Routes.answerTrajectoryPage),
),
],
),
SizedBox(height: 16.r),
//
Row(
children: [
Expanded(
child: $menuItem(
bgImg: 'assets/images/home_bg_05.png',
name: '优先批阅设定',
url: Routes.studentHistoryWorkPage,
page: 'set',
),
),
SizedBox(width: 16.r),
//
const Expanded(child: SizedBox()),
],
),
],
);
}
}
@swidget
Widget $menuItem({required String bgImg, required String name, String? value, required String url, String? page}) {
return InkWell(
Widget $menuItem({
required String bgImg,
required String name,
String? value,
required String url,
String? page,
bool isPrimary = false,
}) {
return Material(
color: Colors.transparent,
child: InkWell(
onTap: () {
Get.toNamed(url, arguments: {'page': page ?? ''});
},
borderRadius: BorderRadius.circular(12.r),
child: Semantics(
label: '$name${value != null ? ',待处理数量:$value' : ''}',
hint: '点击进入$name页面',
button: true,
child: Container(
width: (Get.width - 60.r) / 2,
height: (Get.width - 60.r) / 2 * 86 / 164,
padding: EdgeInsets.symmetric(vertical: 15.r, horizontal: 15.r),
padding: EdgeInsets.all(16.r),
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage(bgImg),
fit: BoxFit.contain,
borderRadius: BorderRadius.circular(12.r),
gradient: isPrimary
? const LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
Color(0xFF667eea),
Color(0xFF764ba2),
],
)
: null,
color: isPrimary ? null : Colors.white,
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.08),
blurRadius: 8,
offset: const Offset(0, 2),
),
],
image: !isPrimary
? DecorationImage(
image: AssetImage(bgImg),
fit: BoxFit.cover,
colorFilter: ColorFilter.mode(
Colors.white.withOpacity(0.9),
BlendMode.srcATop,
),
)
: null,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
@ -159,40 +312,64 @@ Widget $menuItem({required String bgImg, required String name, String? value, re
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
Expanded(
child: Text(
name,
style: TextStyle(fontSize: 14.sp, color: const Color(0xFF4F4F4F), fontWeight: FontWeight.w600),
style: TextStyle(
fontSize: 14.sp,
color: isPrimary ? Colors.white : const Color(0xFF2C2C2C),
fontWeight: FontWeight.w600,
),
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
),
if (value != null && value != '')
Container(
width: 18.r,
height: 18.r,
Semantics(
label: '待处理数量:$value',
child: Container(
width: 20.r,
height: 20.r,
alignment: Alignment.center,
decoration: BoxDecoration(
color: const Color(0xFFFF6969),
borderRadius: BorderRadius.all(Radius.circular(9.r)),
color: isPrimary ? Colors.white : const Color(0xFFFF6969),
borderRadius: BorderRadius.all(Radius.circular(10.r)),
),
child: Text(
value,
style: TextStyle(fontSize: 10.sp, color: Colors.white, fontWeight: FontWeight.w600),
style: TextStyle(
fontSize: 10.sp,
color: isPrimary ? const Color(0xFFFF6969) : Colors.white,
fontWeight: FontWeight.w600),
),
),
)
],
),
const Spacer(),
Row(
mainAxisAlignment: MainAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
if (isPrimary)
Icon(
Icons.arrow_forward_ios,
size: 14.sp,
color: Colors.white,
)
else
Image.asset(
'assets/images/home_right_icon.png',
width: 16.r,
height: 16.r,
semanticLabel: '进入图标',
),
],
),
],
),
),
),
),
);
}

View File

@ -68,8 +68,9 @@ dependencies:
# zoom_widget: ^2.0.1
zoom_widget:
git:
url: https://github.com/semakers/zoom-widget.git
ref: a35c9da6afe405c23b5897b449683d424016e9f1
url: https://gitea.23544.com/wangyang/zoom_widget.git
# url: https://github.com/semakers/zoom-widget.git
# ref: a35c9da6afe405c23b5897b449683d424016e9f1
# start retrofit请求封装
retrofit: ^4.1.0
json_annotation: 4.9.0