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

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

View File

@ -41,7 +41,7 @@ void main() async {
statusBarColor: Colors.transparent, // statusBarColor: Colors.transparent, //
statusBarIconBrightness: Brightness.light // dark: light 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]); // await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]); //
runApp(const MyApp()); runApp(const MyApp());

View File

@ -40,7 +40,7 @@ class _GestureCanvasPageState extends State<GestureCanvasPage> {
GestureType _recognizedGesture = GestureType.none; GestureType _recognizedGesture = GestureType.none;
late ShapeRecognizer _recognizer; late ShapeRecognizer _recognizer;
// [] //
bool _showSimplifiedPoints = true; bool _showSimplifiedPoints = true;
@override @override
@ -123,7 +123,7 @@ class _GestureCanvasPageState extends State<GestureCanvasPage> {
appBar: AppBar( appBar: AppBar(
title: const Text('手势识别 (可视化调试)'), title: const Text('手势识别 (可视化调试)'),
actions: [ actions: [
// [] AppBar中添加一个信息提示 // AppBar中添加一个信息提示
Padding( Padding(
padding: const EdgeInsets.only(right: 16.0), padding: const EdgeInsets.only(right: 16.0),
child: Icon( child: Icon(
@ -179,7 +179,7 @@ class _GestureCanvasPageState extends State<GestureCanvasPage> {
child: const Icon(Icons.clear), child: const Icon(Icons.clear),
), ),
const SizedBox(height: 10), const SizedBox(height: 10),
// [] //
FloatingActionButton( FloatingActionButton(
onPressed: () { onPressed: () {
setState(() { setState(() {
@ -205,7 +205,7 @@ class _GestureCanvasPainter extends CustomPainter {
final List<List<Offset>> allStrokes; final List<List<Offset>> allStrokes;
final double rdpEpsilon; final double rdpEpsilon;
final bool showSimplifiedPoints; final bool showSimplifiedPoints;
final Paint _debugPaint; // [] final Paint _debugPaint; //
_GestureCanvasPainter({ _GestureCanvasPainter({
required this.cachedImage, required this.cachedImage,
@ -218,7 +218,7 @@ class _GestureCanvasPainter extends CustomPainter {
..strokeCap = StrokeCap.round ..strokeCap = StrokeCap.round
..strokeWidth = 5.0 ..strokeWidth = 5.0
..style = PaintingStyle.stroke, ..style = PaintingStyle.stroke,
// [] //
_debugPaint = Paint() _debugPaint = Paint()
..color = Colors.red ..color = Colors.red
..strokeCap = StrokeCap.round ..strokeCap = StrokeCap.round
@ -241,7 +241,7 @@ class _GestureCanvasPainter extends CustomPainter {
canvas.drawPath(path, _paint); canvas.drawPath(path, _paint);
} }
// [] 3: // 3:
if (showSimplifiedPoints) { if (showSimplifiedPoints) {
// //
for (final stroke in allStrokes) { 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/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/anti_shake_throttling.dart';
import 'package:making_school_asignment_app/common/utils/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 '../configuration_files/index.dart'; import '../configuration_files/index.dart';
@ -62,19 +61,23 @@ class _BottomAnnotationSwitchJobState extends State<BottomAnnotationSwitch>
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
double iconSize = 18.sp;
Color actionColor = Colors.white;
Color defaultColor = const Color.fromRGBO(132, 146, 163, 1);
return SafeArea( return SafeArea(
left: false, left: false,
right: false, right: false,
top: false, top: false,
child: Container( child: Container(
width: double.infinity, width: double.infinity,
height: _animationController.value * 64.h, height: _animationController.value * 70.h,
color: const Color.fromRGBO(83, 83, 83, 1), decoration: BoxDecoration(
// padding: EdgeInsets.symmetric(vertical: 1.h), color: const Color.fromRGBO(83, 83, 83, 1),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.1),
blurRadius: 8,
offset: const Offset(0, -2),
),
],
),
child: Row( child: Row(
children: [ children: [
Expanded( Expanded(
@ -87,109 +90,83 @@ class _BottomAnnotationSwitchJobState extends State<BottomAnnotationSwitch>
children: [ children: [
// //
Expanded( Expanded(
child: SizedBox( child: _buildActionButton(
width: double.infinity, '全对',
height: double.infinity, Icons.check_circle_outline,
child: TextButton( () => easyThrottle('homework_bottom_operation_bar_scoring_related',
child: quickText('全 对', color: Colors.white, size: 12.sp), () => _homeworkLogic.allPairs(context)),
onPressed: () => easyThrottle('homework_bottom_operation_bar_scoring_related', isEnabled: !_homeworkLogic.state.submitLoading.value,
() => _homeworkLogic.allPairs(context)), 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( Expanded(
child: SizedBox( child: Obx(() => _buildIconButton(
width: double.infinity, const IconData(0xe635, fontFamily: "AlibabaIcon"),
height: double.infinity, () => easyThrottle('homework_bottom_action_bar_annotations', () {
child: IconButton( //
icon: Obx(() { _logicControl.gestureMove.value = false;
return Icon( _logicControl.pen.value = true;
const IconData(0xe635, fontFamily: "AlibabaIcon"), }),
size: iconSize, isActive: _logicControl.pen.value,
color: _logicControl.pen.value ? Theme.of(context).primaryColor : defaultColor, tooltip: '注解笔',
); )),
}),
onPressed: () => easyThrottle('homework_bottom_action_bar_annotations', () {
_logicControl.gestureMove.value = false;
_logicControl.pen.value = !_logicControl.pen.value;
}),
),
),
), ),
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( Expanded(
child: SizedBox( child: Obx(() => _buildIconButton(
width: double.infinity, const IconData(0xe636, fontFamily: "AlibabaIcon"),
height: double.infinity, () => easyThrottle('homework_bottom_action_bar_annotations', () {
child: IconButton( //
icon: Obx( _logicControl.pen.value = false;
() { _logicControl.gestureMove.value = true;
return Icon( }),
const IconData(0xe636, fontFamily: "AlibabaIcon"), isActive: _logicControl.gestureMove.value,
size: iconSize, tooltip: '滑动试题',
color: _logicControl.gestureMove.value ? actionColor : defaultColor, )),
);
},
),
onPressed: () => easyThrottle('homework_bottom_action_bar_annotations', () {
_logicControl.pen.value = false;
_logicControl.gestureMove.value = !_logicControl.gestureMove.value;
}),
),
),
), ),
], ],
), ),
), ),
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( Expanded(
child: Row( child: Row(
children: [ children: [
// //
Expanded( Expanded(
child: SizedBox( child: _buildActionButton(
width: double.infinity, '全错',
height: double.infinity, Icons.cancel_outlined,
child: TextButton( () => easyThrottle('homework_bottom_operation_bar_scoring_related',
onPressed: () => easyThrottle('homework_bottom_operation_bar_scoring_related', () => _homeworkLogic.allWrongRating(context)),
() => _homeworkLogic.allWrongRating(context)), isEnabled: !_homeworkLogic.state.submitLoading.value,
child: quickText('全 错', color: Colors.white, size: 12.sp), 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( Expanded(
child: SizedBox( child: _buildIconButton(
width: double.infinity, const IconData(0xe638, fontFamily: "AlibabaIcon"),
height: double.infinity, () => easyThrottle(
child: IconButton( 'homework_bottom_action_bar_annotations',
onPressed: () => easyThrottle( () => eventFire(model: BottomOperationBar(revokeAll: false, revokePreStep: true)),
'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( Expanded(
child: SizedBox( child: _buildIconButton(
width: double.infinity, const IconData(0xe637, fontFamily: "AlibabaIcon"),
height: double.infinity, () => easyThrottle(
child: IconButton( 'homework_bottom_action_bar_annotations',
icon: Icon(const IconData(0xe637, fontFamily: "AlibabaIcon"), () => eventFire(model: BottomOperationBar(revokeAll: true, revokePreStep: false)),
size: iconSize, color: defaultColor),
onPressed: () => 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( Expanded(
flex: 3, flex: 3,
child: Row( child: Row(
children: [ children: [
Expanded( Expanded(
child: SizedBox( child: _buildActionButton(
width: double.infinity, '取消',
height: double.infinity, Icons.clear,
child: TextButton( () => easyThrottle(
onPressed: () => easyThrottle( 'homework_bottom_operation_bar_scoring_related', () => _homeworkLogic.cancelAllRatings()),
'homework_bottom_operation_bar_scoring_related', () => _homeworkLogic.cancelAllRatings()), isEnabled: true,
child: quickText('取 消', size: 14.sp, color: Colors.white), 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( Expanded(
child: SizedBox( child: Obx(() {
width: double.infinity, final submitLoading = _homeworkLogic.state.submitLoading.value;
height: double.infinity, return _buildActionButton(
child: TextButton( '提交',
onPressed: () => easyThrottle( Icons.send,
() => easyThrottle(
'homework_bottom_operation_bar_scoring_related', () => _homeworkLogic.submit(context)), 'homework_bottom_operation_bar_scoring_related', () => _homeworkLogic.submit(context)),
child: Row( isEnabled: !submitLoading,
mainAxisAlignment: MainAxisAlignment.center, isPrimary: true,
crossAxisAlignment: CrossAxisAlignment.center, isLoading: submitLoading,
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)),
);
}
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/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/anti_shake_throttling.dart';
import 'package:making_school_asignment_app/common/utils/toast_utils.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/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/page/home_page/children/homework_review/configuration_files/index.dart';
import 'package:making_school_asignment_app/routes/app_pages.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) { items: sateData.value?.templateIdKeys?.map((e) {
return DropdownMenuItem( return DropdownMenuItem(
value: e, 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(), }).toList(),
onChanged: (value) { onChanged: (value) {
@ -77,7 +77,9 @@ class DropdownSwitchStudentsType extends StatelessWidget {
final students = sateData.value?.students ?? []; 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 studentName = currentStudent?.name ?? '当前学生';
final questionNumber = templateIdKeyMap?[value] ?? '当前选择页'; final questionNumber = templateIdKeyMap?[value] ?? '当前选择页';
@ -95,7 +97,7 @@ class DropdownSwitchStudentsType extends StatelessWidget {
}), }),
), ),
), ),
const Expanded(flex: 1, child: SizedBox()), SizedBox(width: 8.w),
Expanded( Expanded(
flex: 3, flex: 3,
child: Stack( child: Stack(
@ -120,7 +122,9 @@ class DropdownSwitchStudentsType extends StatelessWidget {
alignment: const FractionalOffset(0, 0.62), alignment: const FractionalOffset(0, 0.62),
children: [ children: [
Container( 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( child: quickText(
e.name, e.name,
size: 14.sp, size: 14.sp,
@ -134,7 +138,9 @@ class DropdownSwitchStudentsType extends StatelessWidget {
Icon( Icon(
const IconData(0xe63d, fontFamily: "AlibabaIcon"), const IconData(0xe63d, fontFamily: "AlibabaIcon"),
size: 12.sp, 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), quickText('优先', size: 4.sp, color: Colors.white),
], ],
@ -161,7 +167,9 @@ class DropdownSwitchStudentsType extends StatelessWidget {
return Icon( return Icon(
const IconData(0xe63d, fontFamily: "AlibabaIcon"), const IconData(0xe63d, fontFamily: "AlibabaIcon"),
size: 12.sp, 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), quickText('优先', size: 4.sp, color: Colors.white),
@ -173,9 +181,9 @@ class DropdownSwitchStudentsType extends StatelessWidget {
), ),
// const Expanded(flex: 1, child: SizedBox()), // const Expanded(flex: 1, child: SizedBox()),
SizedBox(width: 8.w), SizedBox(width: 8.w),
Expanded( const Expanded(
flex: isPad() ? 4 : 5, flex: 5,
child: const Row( child: Row(
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceAround, mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [ children: [
@ -208,7 +216,8 @@ Widget $studentHandwriting(BuildContext context) {
if (templateIdKeyMap != null && templateId != null) { if (templateIdKeyMap != null && templateId != null) {
pageNum = templateIdKeyMap[templateId]; 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(); ToastUtils.dismiss();
}, },
), ),
@ -238,7 +247,10 @@ Widget $continueToReview(BuildContext context, {bool isFloatingAction = false})
int? annotatedCount = data?.annotatedCount; // int? annotatedCount = data?.annotatedCount; //
// || (submitCount == annotatedCount || (param.templateId == null && param.studentId == null)) // || (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 ? 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( callFun() => easyThrottle(
'DO_PAPERS_JOB_CONTINUE_TO_REVIEW', 'DO_PAPERS_JOB_CONTINUE_TO_REVIEW',
() { () {
@ -292,7 +304,11 @@ Widget $historyHomework(BuildContext context) {
var currentStudent = sateData.value!.students.firstWhereOrNull((e) => e.id == studentId); var currentStudent = sateData.value!.students.firstWhereOrNull((e) => e.id == studentId);
if (currentStudent == null) return; if (currentStudent == null) return;
var theState = Get.find<HomeworkReviewLogic>().state; 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( child: Row(
crossAxisAlignment: CrossAxisAlignment.center, 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), // (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 - final translation = logic.zoomController.value.getTranslation();
zoomFile.getZoomFileOffsetStartWidth(zoomState.initScale.value ?? 1) + final panDx = translation.x;
((zoomWtdthSpaceVal <= 0.1) ? (sateData.zoomOffset?.dx.abs() ?? 0) : 0)) / final panDy = translation.y;
theScale,
(dy - //
max(0, imageHeightOffsetStart) + final correctedDx = (localPosition.dx - leftOffset - panDx) / theScale;
((zoomFile.imageHeightOffsetStart == null || zoomFile.imageHeightOffsetStart! <= 0.1) final correctedDy = (dy - topOffset - panDy) / theScale;
? (sateData.zoomOffset?.dy.abs() ?? 0) localPosition = Offset(correctedDx, correctedDy);
: 0)) /
theScale,
);
/// ///
if (Platform.isAndroid) { if (Platform.isAndroid) {
@ -579,73 +577,74 @@ class QuestionImageView extends HookWidget with EventBusMixin<BottomOperationBar
var isPen = annotationState.pen.value; var isPen = annotationState.pen.value;
var showZgtAnnotate = sateData.data.value?.showZgtAnnotate; var showZgtAnnotate = sateData.data.value?.showZgtAnnotate;
print(sateData.data.value!.zgtAnswer);
return Container( return Container(
height: double.infinity, height: double.infinity,
width: double.infinity, width: double.infinity,
alignment: Alignment.center, alignment: Alignment.center,
child: IgnorePointer( child: IgnorePointer(
ignoring: isPen, // Zoom
child: ignoring: !annotationState.gestureMove.value,
// ZoomView( child:
// key: zoomKey.value, // ZoomView(
// viewWidth: maxWidth, // key: zoomKey.value,
// viewHeight: maxHeight, // viewWidth: maxWidth,
// imageDisplayHeight: actualHeight, // viewHeight: maxHeight,
// url: sateData.data.value!.zgtAnswer, // imageDisplayHeight: actualHeight,
// onScale: logic.zoomLogic.onScaleUpdate, // url: sateData.data.value!.zgtAnswer,
// // onTrans: (offset) { // onScale: logic.zoomLogic.onScaleUpdate,
// // print("偏移位置:$offset"); // // onTrans: (offset) {
// // }, // // print("偏移位置:$offset");
// onContentOffset: logic.zoomLogic.onPanUpPosition, // // },
// ), // onContentOffset: logic.zoomLogic.onPanUpPosition,
// ),
Zoom( Obx(
key: zoomKey.value, () => Zoom(
// initTotalZoomOut: true, // key: zoomKey.value,
zoomSensibility: 0.05, // initTotalZoomOut: true, //
scrollWeight: 4.r, zoomSensibility: 0.05,
doubleTapAnimDuration: Duration.zero, scrollWeight: 4.r,
maxZoomWidth: maxWidth, doubleTapAnimDuration: Duration.zero,
maxZoomHeight: actualHeight, maxZoomWidth: maxWidth,
canvasColor: Colors.transparent, maxZoomHeight: actualHeight,
doubleTapScaleChange: 1, canvasColor: Colors.transparent,
// initPosition: initPosition.value, doubleTapScaleChange: 1,
// initScale: logic.zoomLogic.zoomState.initScale.value ?? 1, // initPosition: initPosition.value,
backgroundColor: Colors.transparent, // initScale: logic.zoomLogic.zoomState.initScale.value ?? 1,
onScaleUpdate: (double scale, double zoom) => logic.zoomLogic.onScaleUpdate(zoom), backgroundColor: Colors.transparent,
onPositionUpdate: logic.zoomLogic.onPanUpPosition, onScaleUpdate: (double scale, double zoom) => logic.zoomLogic.onScaleUpdate(zoom),
transformationController: logic.zoomController, onPositionUpdate: logic.zoomLogic.onPanUpPosition,
child: Stack( transformationController: logic.zoomController,
children: [ child: Stack(
$TheCachedNetworkImage( children: [
imgWidth: maxWidth, $TheCachedNetworkImage(
imageUrl: sateData.data.value!.zgtAnswer, imgWidth: maxWidth,
(_, imageProvider) => Image(image: imageProvider, fit: BoxFit.fitWidth), imageUrl: sateData.data.value!.zgtAnswer,
(_, imageProvider) => Image(image: imageProvider, fit: BoxFit.fitWidth),
),
RepaintBoundary(
key: logic.pictureOverviewKey,
child: CustomPaint(
// isComplex: true,
size: Size(maxWidth, actualHeight),
foregroundPainter: DrawingPainter(ctrl: vnHandWritings),
// child: $TheCachedNetworkImage(
// imgWidth: maxWidth,
// imageUrl: showZgtAnnotate ?? sateData.data.value!.zgtAnswer,
// (_, imageProvider) => Image(image: imageProvider, fit: BoxFit.fitWidth),
// ),
child: showZgtAnnotate != null
? $TheCachedNetworkImage(
imgWidth: maxWidth,
imageUrl: showZgtAnnotate,
(_, imageProvider) => Image(image: imageProvider, fit: BoxFit.fitWidth))
: null,
),
),
],
), ),
RepaintBoundary( ),
key: logic.pictureOverviewKey, )),
child: CustomPaint(
// isComplex: true,
size: Size(maxWidth, zoomState.zoomFile.value!.actualHeight!),
foregroundPainter: DrawingPainter(ctrl: vnHandWritings),
// child: $TheCachedNetworkImage(
// imgWidth: maxWidth,
// imageUrl: showZgtAnnotate ?? sateData.data.value!.zgtAnswer,
// (_, imageProvider) => Image(image: imageProvider, fit: BoxFit.fitWidth),
// ),
child: showZgtAnnotate != null
? $TheCachedNetworkImage(
imgWidth: maxWidth,
imageUrl: showZgtAnnotate,
(_, imageProvider) => Image(image: imageProvider, fit: BoxFit.fitWidth))
: null,
),
),
],
),
),
),
); );
}), }),
); );

View File

@ -6,6 +6,7 @@ import 'package:dio/dio.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.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/annotate_list_to_refresh.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_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/permission_describe_util.dart';
import 'package:making_school_asignment_app/common/utils/toast_utils.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/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:permission_handler/permission_handler.dart';
import 'package:zoom_widget/zoom_widget.dart' as zoomWidget; import 'package:zoom_widget/zoom_widget.dart' as zoomWidget;
@ -88,7 +88,6 @@ class HomeworkReviewLogic extends GetxController with RequestToolMixin, EventBus
@override @override
void onInit() { void onInit() {
appBarHeight = MediaQuery.of(Get.context!).padding.top; appBarHeight = MediaQuery.of(Get.context!).padding.top;
print("appBarHeight $appBarHeight");
// WidgetsFlutterBinding.ensureInitialized(); // WidgetsFlutterBinding.ensureInitialized();
// SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: []); // // SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: []); //
@ -158,17 +157,13 @@ class HomeworkReviewLogic extends GetxController with RequestToolMixin, EventBus
} }
void getData() async { void getData() async {
//
if (state.submitLoading.value) return;
var timerControl = Timer(const Duration(milliseconds: 300), () => ToastUtils.showLoading()); var timerControl = Timer(const Duration(milliseconds: 300), () => ToastUtils.showLoading());
try { 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++) {
// var item = studentQuestions[i];
// item.topHeight = itemPre.height;
// }
state.getDataError.value = false; state.getDataError.value = false;
state.handwritings = []; state.handwritings = [];
@ -179,8 +174,8 @@ class HomeworkReviewLogic extends GetxController with RequestToolMixin, EventBus
state.data.value = data; state.data.value = data;
} catch (e) { } catch (e) {
print('获取数据报错了:$e'); print('获取数据报错了:$e');
// ToastUtils.showError('未获取到试题数据,请重试');
state.getDataError.value = true; state.getDataError.value = true;
ToastUtils.showError('获取试题数据失败,请检查网络连接后重试');
} finally { } finally {
if (timerControl.isActive) timerControl.cancel(); if (timerControl.isActive) timerControl.cancel();
ToastUtils.dismiss(); ToastUtils.dismiss();
@ -278,18 +273,24 @@ class HomeworkReviewLogic extends GetxController with RequestToolMixin, EventBus
ToastUtils.showInfo("正在提交批阅数据,请勿重复操作"); ToastUtils.showInfo("正在提交批阅数据,请勿重复操作");
return; return;
} }
state.submitLoading.value = true; state.submitLoading.value = true;
var data = state.data.value; var data = state.data.value;
if (data == null) return; if (data == null) {
ToastUtils.showError('数据异常,请重新加载');
if ((state.data.value?.studentQuestions.isEmpty ?? true) || (state.studentQuestions.value?.isEmpty ?? true)) {
return; 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 studentQuestions = state.studentQuestions.value!.where((e) => e.useTime != null && e.useTime! > 0).toList();
// //
var noRatingElement = studentQuestions.firstWhereOrNull((e) => e.studentScore == null); var noRatingElement = studentQuestions.firstWhereOrNull((e) => e.studentScore == null);
if (noRatingElement != null) { if (noRatingElement != null) {
ToastUtils.showInfo('${noRatingElement.questionNo}题请评分'); ToastUtils.showInfo('${noRatingElement.questionNo}题请评分');
return; return;
} }
@ -320,35 +321,13 @@ class HomeworkReviewLogic extends GetxController with RequestToolMixin, EventBus
if (totalUnAnnotateCount <= 0) { if (totalUnAnnotateCount <= 0) {
// //
if (!state.lastQuestionPrompt) { if (!state.lastQuestionPrompt) {
await showDialog( await _showCompletionDialog(context);
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();
}),
],
);
},
);
} else { } else {
ToastUtils.showSuccess("提交", duration: const Duration(milliseconds: 800)); ToastUtils.showSuccess("批阅已提交", duration: const Duration(milliseconds: 800));
} }
return; return;
} }
var newParams = DoPaperDetailsParam.fromJson(state.param.value.toJson()); var newParams = DoPaperDetailsParam.fromJson(state.param.value.toJson());
if (totalUnAnnotateCount > 0) { if (totalUnAnnotateCount > 0) {
// //
@ -356,14 +335,52 @@ class HomeworkReviewLogic extends GetxController with RequestToolMixin, EventBus
newParams.studentId = null; newParams.studentId = null;
} }
state.param.value = newParams; state.param.value = newParams;
ToastUtils.showSuccess("批阅已提交");
}); });
} catch (_) { } catch (e) {
print("批阅提交报错 $_"); print("批阅提交报错 $e");
ToastUtils.showError('提交失败,请检查网络连接后重试');
} finally { } finally {
state.submitLoading.value = false; 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 { Future<void> toFavorite() async {
try { try {
var data = state.data.value!; 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:get/get.dart';
import 'package:making_school_asignment_app/common/job/annotate_list_to_refresh.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/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/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/bottom_operation_bar.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/children/homework_review/components/question_paper_view.dart';
@ -55,8 +54,16 @@ class HomeworkReview extends StatelessWidget {
children: [ children: [
SizedBox(width: 5.w), SizedBox(width: 5.w),
IconButton( IconButton(
icon: const Icon(Icons.arrow_back_ios, color: Colors.black), onPressed: () => Get.back()), icon: const Icon(Icons.arrow_back_ios, color: Colors.black),
Expanded(child: quickText(sateData.param.value.homeworkName, size: 18.sp).paddingOnly(top: 2.h)), onPressed: () => Get.back(),
tooltip: '返回'),
Expanded(
child: Text(
sateData.param.value.homeworkName,
style: TextStyle(fontSize: 18.sp, fontWeight: FontWeight.w600),
overflow: TextOverflow.ellipsis,
),
),
const FavoriteWidget(), const FavoriteWidget(),
SizedBox(width: 10.w), SizedBox(width: 10.w),
const ReturnToHomepage(), 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.dart';
import 'package:making_school_asignment_app/common/job/work_student_params.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/mixins/request_tool_mixin.dart';
import 'package:making_school_asignment_app/common/store/user_store.dart';
import 'home_state.dart'; import 'home_state.dart';
@ -24,16 +23,20 @@ class HomeLogic extends GetxController with RequestToolMixin, GetTickerProviderS
} }
void getList() async { void getList() async {
params.pageNumber = state.pageNumber; try {
WorkStudent data = await getClient().getUnAnnotateList(params); params.pageNumber = state.pageNumber;
state.totalCount.value = data.totalCount; WorkStudent data = await getClient().getUnAnnotateList(params);
state.readOver.value = data.items.length; state.totalCount.value = data.totalCount;
/* if(params.pageNumber == 1){ state.readOver.value = data.items.length;
state.workList.value = data.items;
}else{ //
state.workList.addAll(data.items); refreshController.finishRefresh();
} catch (e) {
print('获取作业列表失败: $e');
//
refreshController.finishRefresh();
//
} }
refreshController.finishRefresh();*/
} }
@override @override

View File

@ -40,93 +40,104 @@ class HomePage extends GetxKeepAliveWidget<HomeLogic> {
enableControlFinishLoad: true, enableControlFinishLoad: true,
controller: controller.refreshController, controller: controller.refreshController,
header: MaterialHeader(), header: MaterialHeader(),
// footer: TaurusFooter(),
onRefresh: () async { onRefresh: () async {
state.pageNumber = 1; state.pageNumber = 1;
return controller.getList(); return controller.getList();
}, },
// onLoad: () async { child: CustomScrollView(
// if (state.workList.length < state.totalCount.value) { slivers: [
// state.pageNumber++; //
// return logic.getList(); SliverAppBar(
// } expandedHeight: 300.h,
// }, floating: false,
child: Stack( pinned: false,
children: [ backgroundColor: Colors.transparent,
Image.asset( flexibleSpace: FlexibleSpaceBar(
'assets/images/home_banner.png', background: Image.asset(
width: Get.width, 'assets/images/home_banner.png',
fit: BoxFit.fill, width: Get.width,
), fit: BoxFit.cover,
Container( ),
margin: EdgeInsets.only(top: 300.h),
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))),
child: Column(
children: [
SizedBox(height: 15.r),
Text(
'我的作业管理',
style: TextStyle(fontSize: 20.sp, color: const Color(0xFF676666), fontWeight: FontWeight.w600),
),
SizedBox(height: 15.r),
Row(
children: [
Expanded(
child: Obx(() {
return $MenuItem(
bgImg: 'assets/images/home_bg_01.png',
name: '作业批阅',
value: state.totalCount.value.toString(),
url: Routes.readOverPage,
);
}),
),
SizedBox(width: 20.r),
const Expanded(
child: $MenuItem(
bgImg: 'assets/images/home_bg_02.png',
name: '知识点掌握',
url: Routes.studentHistoryWorkPage,
page: 'points'),
),
],
),
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),
],
), ),
) ),
//
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)),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
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: 22.sp, color: const Color(0xFF2C2C2C), fontWeight: FontWeight.w700),
),
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: _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(height: 24.r),
//
_buildMenuGrid(context, state),
SizedBox(height: 20.r),
],
),
),
),
], ],
), ),
); );
@ -134,64 +145,230 @@ 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 @swidget
Widget $menuItem({required String bgImg, required String name, String? value, required String url, String? page}) { Widget $menuItem({
return InkWell( required String bgImg,
onTap: () { required String name,
Get.toNamed(url, arguments: {'page': page ?? ''}); String? value,
}, required String url,
child: Container( String? page,
width: (Get.width - 60.r) / 2, bool isPrimary = false,
height: (Get.width - 60.r) / 2 * 86 / 164, }) {
padding: EdgeInsets.symmetric(vertical: 15.r, horizontal: 15.r), return Material(
decoration: BoxDecoration( color: Colors.transparent,
image: DecorationImage( child: InkWell(
image: AssetImage(bgImg), onTap: () {
fit: BoxFit.contain, 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.all(16.r),
decoration: BoxDecoration(
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,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
child: Text(
name,
style: TextStyle(
fontSize: 14.sp,
color: isPrimary ? Colors.white : const Color(0xFF2C2C2C),
fontWeight: FontWeight.w600,
),
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
),
if (value != null && value != '')
Semantics(
label: '待处理数量:$value',
child: Container(
width: 20.r,
height: 20.r,
alignment: Alignment.center,
decoration: BoxDecoration(
color: isPrimary ? Colors.white : const Color(0xFFFF6969),
borderRadius: BorderRadius.all(Radius.circular(10.r)),
),
child: Text(
value,
style: TextStyle(
fontSize: 10.sp,
color: isPrimary ? const Color(0xFFFF6969) : Colors.white,
fontWeight: FontWeight.w600),
),
),
)
],
),
const Spacer(),
Row(
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: '进入图标',
),
],
),
],
),
), ),
), ),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
name,
style: TextStyle(fontSize: 14.sp, color: const Color(0xFF4F4F4F), fontWeight: FontWeight.w600),
),
if (value != null && value != '')
Container(
width: 18.r,
height: 18.r,
alignment: Alignment.center,
decoration: BoxDecoration(
color: const Color(0xFFFF6969),
borderRadius: BorderRadius.all(Radius.circular(9.r)),
),
child: Text(
value,
style: TextStyle(fontSize: 10.sp, color: Colors.white, fontWeight: FontWeight.w600),
),
)
],
),
const Spacer(),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Image.asset(
'assets/images/home_right_icon.png',
width: 16.r,
height: 16.r,
),
],
),
],
),
), ),
); );
} }

View File

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