Compare commits

..

2 Commits

Author SHA1 Message Date
1147192855@qq.com 3666bea6bd no message 2024-04-24 18:24:17 +08:00
1147192855@qq.com 3a6e220f5e no message 2024-04-24 18:10:18 +08:00
6 changed files with 321 additions and 217 deletions

View File

@ -21,12 +21,7 @@ class TrajectoryView extends StatefulHookConsumerWidget {
final double boxHeight; final double boxHeight;
final String questionNumber; final String questionNumber;
final JobNoteTakingTrajectory trajectory; final JobNoteTakingTrajectory trajectory;
const TrajectoryView( const TrajectoryView({required this.trajectory, required this.questionNumber, required this.boxHeight, required this.boxWidth, super.key});
{required this.trajectory,
required this.questionNumber,
required this.boxHeight,
required this.boxWidth,
super.key});
@override @override
TrajectoryViewState createState() => TrajectoryViewState(); TrajectoryViewState createState() => TrajectoryViewState();
@ -152,15 +147,11 @@ class TrajectoryViewState extends ConsumerState<TrajectoryView> {
/// ///
trajectorys trajectorys
..add(GestureRecording( ..add(GestureRecording(data: Offset(2.w, trajectory.pictureQuestionTop), scopeBox: true, annotationSwitch: false, eraser: false))
data: Offset(2.w, trajectory.pictureQuestionTop), scopeBox: true, annotationSwitch: false, eraser: false))
/// ///
..add(GestureRecording( ..add(GestureRecording(
data: Offset(imagInfoModel!.scaleWidth! - 4.w, trajectory.pictureQuestionTop), data: Offset(imagInfoModel!.scaleWidth! - 4.w, trajectory.pictureQuestionTop), scopeBox: true, annotationSwitch: false, eraser: false))
scopeBox: true,
annotationSwitch: false,
eraser: false))
/// ///
..add(GestureRecording( ..add(GestureRecording(
@ -171,8 +162,7 @@ class TrajectoryViewState extends ConsumerState<TrajectoryView> {
/// ///
..add(GestureRecording( ..add(GestureRecording(
data: Offset( data: Offset(imagInfoModel!.scaleWidth! - 4.w, trajectory.pictureQuestionTop + trajectory.pictureQuestionHeight),
imagInfoModel!.scaleWidth! - 4.w, trajectory.pictureQuestionTop + trajectory.pictureQuestionHeight),
scopeBox: true, scopeBox: true,
annotationSwitch: false, annotationSwitch: false,
eraser: false)); eraser: false));
@ -181,12 +171,19 @@ class TrajectoryViewState extends ConsumerState<TrajectoryView> {
ref.read(jobDrawingTrajectoryProvider.notifier).setVal(trajectorys); ref.read(jobDrawingTrajectoryProvider.notifier).setVal(trajectorys);
}); });
if (lattices.isNotEmpty) { if (lattices.isNotEmpty) {
Map<int, List<Lattices>> map = new Map.fromIterable(lattices, // Map<int, List<Lattices>> map = new Map.fromIterable(lattices,
key: (key) => key.stroke, // key: (key) => key.stroke,
value: (value) { // value: (value) {
return lattices.where((item) => item.stroke == value.stroke).toList() // return lattices.where((item) => item.stroke == value.stroke).toList()
..sort((a, b) => a.time.compareTo(b.time)); // ..sort((a, b) => a.time.compareTo(b.time));
}); // });
var map = Map<int, List<Lattices>>();
for (var i = 0; i < lattices.length; i++) {
Lattices item = lattices[i];
if (!map.containsKey(item.stroke)) map[item.stroke] = [];
map[item.stroke]!.add(item); //
}
List<int> keys = map.keys.toList(); List<int> keys = map.keys.toList();
for (var i = 0; i < keys.length; i++) { for (var i = 0; i < keys.length; i++) {
@ -199,8 +196,7 @@ class TrajectoryViewState extends ConsumerState<TrajectoryView> {
double theX = e.x * imagInfoModel!.scale!; double theX = e.x * imagInfoModel!.scale!;
double theY = e.y * imagInfoModel!.scale! + spacingHeight; double theY = e.y * imagInfoModel!.scale! + spacingHeight;
return GestureRecording( return GestureRecording(eraser: false, data: Offset(theX, theY), usageTime: e.time.toInt(), annotationSwitch: false);
eraser: false, data: Offset(theX, theY), usageTime: e.time.toInt(), annotationSwitch: false);
}).toList() }).toList()
..add(GestureRecording(eraser: false, annotationSwitch: false)); ..add(GestureRecording(eraser: false, annotationSwitch: false));
// //
@ -230,8 +226,7 @@ class TrajectoryViewState extends ConsumerState<TrajectoryView> {
if (duration2 == null && nextStrokesData != null) { if (duration2 == null && nextStrokesData != null) {
// //
Lattices minLattices = nextStrokesData.reduce((e1, e2) => e1.time < e2.time ? e1 : e2); Lattices minLattices = nextStrokesData.reduce((e1, e2) => e1.time < e2.time ? e1 : e2);
differenceInMilliseconds = differenceInMilliseconds = (Duration(milliseconds: minLattices.time.toInt()) - duration1).inMilliseconds;
(Duration(milliseconds: minLattices.time.toInt()) - duration1).inMilliseconds;
await Future.delayed(Duration(milliseconds: differenceInMilliseconds)); // await Future.delayed(Duration(milliseconds: differenceInMilliseconds)); //
} }
}; };

View File

@ -366,7 +366,9 @@ Widget $dropdownBoxSwitchStudentsOrTypeView(BuildContext context, {required Func
Expanded(flex: 1, child: SizedBox()), Expanded(flex: 1, child: SizedBox()),
Expanded( Expanded(
flex: 4, flex: 4,
child: Container( child: Stack(
children: [
Container(
padding: EdgeInsets.only(left: 10.w), padding: EdgeInsets.only(left: 10.w),
decoration: BoxDecoration( decoration: BoxDecoration(
color: Color.fromRGBO(244, 244, 244, 1), color: Color.fromRGBO(244, 244, 244, 1),
@ -398,6 +400,22 @@ Widget $dropdownBoxSwitchStudentsOrTypeView(BuildContext context, {required Func
}, },
), ),
), ),
Positioned(
left: 2.w,
child: Stack(
alignment: const FractionalOffset(0.52, 0.24),
children: [
Icon(
const IconData(0xe63d, fontFamily: "AlibabaIcon"),
size: 12.sp,
color: _useSwitchStudentAndType.isFirst.value ? Color.fromRGBO(76, 199, 147, 1) : Color.fromRGBO(164, 164, 164, 1),
),
quickText('优先', size: 4.sp, color: Colors.white),
],
),
),
],
),
), ),
Expanded(flex: 1, child: SizedBox()), Expanded(flex: 1, child: SizedBox()),
Expanded( Expanded(
@ -458,17 +476,6 @@ Widget $dropdownBoxSwitchStudentsOrTypeView(BuildContext context, {required Func
), ),
), ),
), ),
Stack(
alignment: const FractionalOffset(0.52, 0.24),
children: [
Icon(
const IconData(0xe63d, fontFamily: "AlibabaIcon"),
size: 12.sp,
color: _useSwitchStudentAndType.isFirst.value ? Color.fromRGBO(76, 199, 147, 1) : Color.fromRGBO(164, 164, 164, 1),
),
quickText('优先', size: 4.sp, color: Colors.white),
],
),
], ],
), ),
), ),

View File

@ -9,7 +9,6 @@ import 'package:marking_app/components/ReturnToHomepage.dart';
import 'package:marking_app/pages/homework_correction/widget/student_kg_table.dart'; import 'package:marking_app/pages/homework_correction/widget/student_kg_table.dart';
import 'package:marking_app/pages/homework_correction/widget/student_zg_table.dart'; import 'package:marking_app/pages/homework_correction/widget/student_zg_table.dart';
import 'package:marking_app/routes/RouterManager.dart'; import 'package:marking_app/routes/RouterManager.dart';
import 'package:marking_app/utils/common_utils.dart';
import 'package:marking_app/utils/request/rest_client.dart'; import 'package:marking_app/utils/request/rest_client.dart';
import 'package:marking_app/utils/toast_utils.dart'; import 'package:marking_app/utils/toast_utils.dart';
@ -179,6 +178,11 @@ class _QuickCheckPersonalState extends ConsumerState<QuickCheckPersonal> with Co
child: StudentKgTable( child: StudentKgTable(
headList: ['题号', '学生答案', '标准答案'], headList: ['题号', '学生答案', '标准答案'],
bodyList: studentInfo!.kgDetails, bodyList: studentInfo!.kgDetails,
questionNumCall: (no) {
showAnswerHandwriting(context, jobId: widget.jobId, studentId: widget.studentId, questionNo: int.parse(no)).then((value) {
ref.read(jobHandwritingDrawingTrajectoryProvider.notifier).setVal([]);
});
},
), ),
) )
], ],
@ -222,6 +226,11 @@ class _QuickCheckPersonalState extends ConsumerState<QuickCheckPersonal> with Co
child: StudentZgTable( child: StudentZgTable(
headList: ['题号', '用时', '学生答案', '批注结果', '批注'], headList: ['题号', '用时', '学生答案', '批注结果', '批注'],
bodyList: studentInfo!.zgDetails, bodyList: studentInfo!.zgDetails,
questionNumCall: (no) {
showAnswerHandwriting(context, jobId: widget.jobId, studentId: widget.studentId, questionNo: int.parse(no)).then((value) {
ref.read(jobHandwritingDrawingTrajectoryProvider.notifier).setVal([]);
});
},
), ),
) )
], ],

View File

@ -1,5 +1,6 @@
import 'dart:async'; import 'dart:async';
import 'package:json_annotation/json_annotation.dart';
import 'package:cached_network_image/cached_network_image.dart'; import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:flutter_hooks/flutter_hooks.dart';
@ -48,13 +49,14 @@ class AnswerHandwriting extends Dialog {
} }
} }
Future<void> showAnswerHandwriting(BuildContext context, {required int jobId, required int studentId, int? pageNum}) async { Future<void> showAnswerHandwriting(BuildContext context, {required int jobId, required int studentId, int? pageNum, int? questionNo}) async {
return showDialog( return showDialog(
context: context, context: context,
builder: (BuildContext context) => AnswerHandwriting( builder: (BuildContext context) => AnswerHandwriting(
jobId: jobId, jobId: jobId,
studentId: studentId, studentId: studentId,
pageNum: pageNum, pageNum: pageNum,
questionNo: questionNo,
closeCall: () => Navigator.of(context).pop(), closeCall: () => Navigator.of(context).pop(),
), ),
); );
@ -94,7 +96,10 @@ class AnswerHandwritingMainBox extends HookWidget {
}); });
useValueChanged<int?, void>(_useStateModel.pageNum.value, (oldVal, __) { useValueChanged<int?, void>(_useStateModel.pageNum.value, (oldVal, __) {
if (oldVal != null && oldVal != _useStateModel.pageNum.value) _useStateModel.getData().catchError((e) => closeCall()); if (oldVal != null && oldVal != _useStateModel.pageNum.value) {
_useStateModel.questionNo = null;
_useStateModel.getData().catchError((e) => closeCall());
}
}); });
useEffect(() { useEffect(() {
@ -106,7 +111,6 @@ class AnswerHandwritingMainBox extends HookWidget {
HandwritingInfo? _dataDetail = _useStateModel.handwritingDetail.value; HandwritingInfo? _dataDetail = _useStateModel.handwritingDetail.value;
if (_data == null || _dataDetail == null) return Container(); if (_data == null || _dataDetail == null) return Container();
print('数据长度:${_data.lattices.length}');
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
@ -134,7 +138,7 @@ class AnswerHandwritingMainBox extends HookWidget {
), ),
], ],
), ),
$BottomPlaybar(_dataDetail.timeConsuming, _dataDetail.pauseCount), $BottomPlaybar(_dataDetail.timeConsuming, _dataDetail.pauseCount, _dataDetail.pauseInterval),
], ],
); );
} }
@ -143,7 +147,7 @@ class AnswerHandwritingMainBox extends HookWidget {
class UseMainBoxState with CommonMixin { class UseMainBoxState with CommonMixin {
final int jobId; final int jobId;
final int studentId; final int studentId;
final int? questionNo; int? questionNo;
final ValueNotifier<int?> pageNum; final ValueNotifier<int?> pageNum;
final ValueNotifier<int> pageCount; final ValueNotifier<int> pageCount;
final ValueNotifier<JobHandwriting?> handwritingData; final ValueNotifier<JobHandwriting?> handwritingData;
@ -223,7 +227,6 @@ class UseMainBoxState with CommonMixin {
lattices[item.stroke]!.add(item); // lattices[item.stroke]!.add(item); //
} }
print('分组时间:${DateTime.now().millisecondsSinceEpoch}');
List<int> latticeKeys = lattices.keys.toList(); List<int> latticeKeys = lattices.keys.toList();
int timeConsuming = 0; int timeConsuming = 0;
if (latticeKeys.isNotEmpty) { if (latticeKeys.isNotEmpty) {
@ -242,8 +245,8 @@ class UseMainBoxState with CommonMixin {
} }
timeConsuming = lastTime - firstTime; timeConsuming = lastTime - firstTime;
} }
print('获取数据总时间:${DateTime.now().millisecondsSinceEpoch}');
var pauseCount = 0; // var pauseCount = 0; //
List<PauseIntervalTime> pauseInterval = [];
for (var i = 0; i < latticeKeys.length; i++) { for (var i = 0; i < latticeKeys.length; i++) {
var currentLattices = lattices[latticeKeys[i]]!; // var currentLattices = lattices[latticeKeys[i]]!; //
var prevLattices = i == 0 ? null : lattices[latticeKeys[i - 1]]!; // var prevLattices = i == 0 ? null : lattices[latticeKeys[i - 1]]!; //
@ -254,35 +257,38 @@ class UseMainBoxState with CommonMixin {
if (j != 0) { if (j != 0) {
var prevItem = currentLattices[j - 1]; var prevItem = currentLattices[j - 1];
var adjacentSpacingTime = lattice.time - prevItem.time; var adjacentSpacingTime = lattice.time - prevItem.time;
intervalTime = adjacentSpacingTime + prevItem.intervalTime;
if (adjacentSpacingTime > 5000) { if (adjacentSpacingTime > 5000) {
// 5 // 5
pauseCount++; pauseCount++;
pauseInterval.add(PauseIntervalTime(startTime: prevItem.intervalTime, endTime: intervalTime));
} }
intervalTime = adjacentSpacingTime + prevItem.intervalTime;
} else { } else {
if (i != 0 && prevLattices != null) { if (i != 0 && prevLattices != null) {
var prevLatticeLastItem = prevLattices[prevLattices.length - 1]; var prevLatticeLastItem = prevLattices[prevLattices.length - 1];
var adjacentSpacingTime = lattice.time - prevLatticeLastItem.time; var adjacentSpacingTime = lattice.time - prevLatticeLastItem.time;
intervalTime = adjacentSpacingTime + prevLatticeLastItem.intervalTime;
if (adjacentSpacingTime > 5000) { if (adjacentSpacingTime > 5000) {
// 5 // 5
pauseCount++; pauseCount++;
pauseInterval.add(PauseIntervalTime(startTime: prevLatticeLastItem.intervalTime, endTime: intervalTime));
} }
intervalTime = adjacentSpacingTime + prevLatticeLastItem.intervalTime;
} }
} }
lattice.intervalTime = intervalTime; lattice.intervalTime = intervalTime;
} }
} }
return HandwritingInfo(pauseCount, timeConsuming, lattices); return HandwritingInfo(pauseCount, timeConsuming, lattices, pauseInterval);
} }
} }
class HandwritingInfo { class HandwritingInfo {
int pauseCount; // int pauseCount; //
List<PauseIntervalTime> pauseInterval;
int timeConsuming; // int timeConsuming; //
Map<int, List<Lattices>> strokeMap; // Map<int, List<Lattices>> strokeMap; //
HandwritingInfo(this.pauseCount, this.timeConsuming, this.strokeMap); HandwritingInfo(this.pauseCount, this.timeConsuming, this.strokeMap, this.pauseInterval);
} }
// //
@ -374,6 +380,7 @@ class _HandwritingDrawBoxState extends ConsumerState<HandwritingDrawBox> with Ev
List<Timer> timers = []; List<Timer> timers = [];
int handwritingTime = 0; int handwritingTime = 0;
int handwritingDuration = 0; int handwritingDuration = 0;
double speed = 1; //
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@ -404,6 +411,13 @@ class _HandwritingDrawBoxState extends ConsumerState<HandwritingDrawBox> with Ev
toGoPause(); toGoPause();
} }
break; break;
case PlaybackSpeedBus:
//
var _model = (e as PlaybackSpeedBus);
speed = _model.speed;
toGoPause(); //
dragProgressBarInitData(handwritingTime, handwritingDuration);
break;
default: default:
} }
}); });
@ -456,6 +470,7 @@ class _HandwritingDrawBoxState extends ConsumerState<HandwritingDrawBox> with Ev
/// ///
/// @param startTime /// @param startTime
Future<void> dragProgressBarInitData(int startTime, int totalDuration) async { Future<void> dragProgressBarInitData(int startTime, int totalDuration) async {
eventFire(model: JobHandwritingPlaybarBus(false));
timers.forEach((e) { timers.forEach((e) {
if (e.isActive) e.cancel(); if (e.isActive) e.cancel();
}); });
@ -474,24 +489,25 @@ class _HandwritingDrawBoxState extends ConsumerState<HandwritingDrawBox> with Ev
for (var i = 0; i < _packagedHandwritingDataAll.length; i++) { for (var i = 0; i < _packagedHandwritingDataAll.length; i++) {
var item = _packagedHandwritingDataAll[i]; var item = _packagedHandwritingDataAll[i];
if (item.intervalTime <= startTime) { if (item.intervalTime < startTime) {
// //
executeImmediately.add(item); executeImmediately.add(item);
} else { } else {
var intervalTime = item.intervalTime - startTime;
// //
waitingExecution.add(GestureHandwritingRecording( waitingExecution.add(GestureHandwritingRecording(
stroke: item.stroke, stroke: item.stroke,
data: item.data, data: item.data,
usageTime: item.usageTime, usageTime: item.usageTime,
intervalTime: item.intervalTime - startTime, intervalTime: intervalTime < 0 ? 0 : intervalTime,
)); ));
} }
} }
pendingData = waitingExecution; pendingData = waitingExecution;
ref.read(jobHandwritingDrawingTrajectoryProvider.notifier).setVal(executeImmediately); ref.read(jobHandwritingDrawingTrajectoryProvider.notifier).setVal(executeImmediately);
eventFire(model: JobHandwritingPlaybarBus(true));
} }
eventFire(model: JobHandwritingPlaybarBus(true));
} }
Future<void> zhixinCall(GestureHandwritingRecording e) async { Future<void> zhixinCall(GestureHandwritingRecording e) async {
@ -518,7 +534,7 @@ class _HandwritingDrawBoxState extends ConsumerState<HandwritingDrawBox> with Ev
if (e.intervalTime == 0) { if (e.intervalTime == 0) {
zhixinCall(e); zhixinCall(e);
} else { } else {
var ter = Timer(Duration(milliseconds: e.intervalTime), () => zhixinCall(e)); var ter = Timer(Duration(milliseconds: e.intervalTime ~/ speed), () => zhixinCall(e));
timers.add(ter); timers.add(ter);
} }
}); });
@ -641,7 +657,7 @@ Widget $pageNumberBox(int pageNum) {
} }
@hwidget @hwidget
Widget $bottomPlaybar(BuildContext context, int timeConsuming, int pauseCount) { Widget $bottomPlaybar(BuildContext context, int timeConsuming, int pauseCount, List<PauseIntervalTime> pauseIntervals) {
var usePlaybar = UseBottomPlaybar.use(timeConsuming); var usePlaybar = UseBottomPlaybar.use(timeConsuming);
useValueChanged<int, void>(timeConsuming, (_, __) { useValueChanged<int, void>(timeConsuming, (_, __) {
@ -656,6 +672,9 @@ Widget $bottomPlaybar(BuildContext context, int timeConsuming, int pauseCount) {
// //
useValueChanged<PlaybackSpeed, void>(usePlaybar.constantFastSpeed.value, (_, __) { useValueChanged<PlaybackSpeed, void>(usePlaybar.constantFastSpeed.value, (_, __) {
usePlaybar.eventFire(model: PlaybackSpeedBus(usePlaybar.constantFastSpeed.value.speed)); usePlaybar.eventFire(model: PlaybackSpeedBus(usePlaybar.constantFastSpeed.value.speed));
//
usePlaybar.playTimingSuspend();
usePlaybar.playTimingStarts();
}); });
// //
useValueChanged<int, void>(usePlaybar.useTime.value, (_, __) { useValueChanged<int, void>(usePlaybar.useTime.value, (_, __) {
@ -668,7 +687,6 @@ Widget $bottomPlaybar(BuildContext context, int timeConsuming, int pauseCount) {
useEffect(() { useEffect(() {
usePlaybar.eventOn(callback: (e) { usePlaybar.eventOn(callback: (e) {
// TODO
switch (e.runtimeType) { switch (e.runtimeType) {
case JobHandwritingPlaybarBus: case JobHandwritingPlaybarBus:
// //
@ -676,23 +694,17 @@ Widget $bottomPlaybar(BuildContext context, int timeConsuming, int pauseCount) {
if (_val.play) { if (_val.play) {
// //
usePlaybar.playTimingStarts(); usePlaybar.playTimingStarts();
if (!usePlaybar.playPause.value) { if (!usePlaybar.playPause.value) usePlaybar.playPause.value = true;
usePlaybar.playPause.value = true;
}
} else { } else {
// //
usePlaybar.playTimingSuspend(); usePlaybar.playTimingSuspend();
if (usePlaybar.playPause.value) { if (usePlaybar.playPause.value) usePlaybar.playPause.value = false;
usePlaybar.playPause.value = false;
}
} }
break; break;
case JobHandwritingGetReadyBus: case JobHandwritingGetReadyBus:
// //
Future.delayed(Duration.zero, () => (usePlaybar.handWritingReady.value = true)); Future.delayed(Duration.zero, () => (usePlaybar.handWritingReady.value = true));
break; break;
case PlaybackSpeedBus:
break;
default: default:
} }
}); });
@ -711,7 +723,7 @@ Widget $bottomPlaybar(BuildContext context, int timeConsuming, int pauseCount) {
height: 60.h, height: 60.h,
padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 10.h), padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 10.h),
alignment: Alignment.center, alignment: Alignment.center,
color: Color.fromRGBO(0, 0, 0, 0.5), color: Color.fromRGBO(0, 0, 0, 0.4),
child: Row( child: Row(
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
@ -731,30 +743,68 @@ Widget $bottomPlaybar(BuildContext context, int timeConsuming, int pauseCount) {
SpinKitPouringHourGlassRefined(size: 40.sp, color: Colors.white), SpinKitPouringHourGlassRefined(size: 40.sp, color: Colors.white),
SizedBox(width: 6.w), SizedBox(width: 6.w),
Expanded( Expanded(
child: Column( child: LayoutBuilder(
builder: (context, constraints) {
final double containerWidth = constraints.maxWidth; //
// print('总刻度:$timeConsuming,宽度:$containerWidth');
// print('总时长:${pauseIntervals.map((e) => e.toJson()).toList()}');
var unitScale = containerWidth / timeConsuming; //
var pauseIntervalsLength = pauseIntervals.length;
List<Widget> pauseTickMarks = pauseIntervals.asMap().keys.map((e) {
bool isLast = e == pauseIntervalsLength - 1;
bool isFirst = e == 0;
var item = pauseIntervals[e];
return Positioned(
top: 0,
left: unitScale * item.startTime,
child: Container(
width: unitScale * (item.apart ?? 0),
height: 8.h,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: isFirst
? BorderRadius.only(topLeft: Radius.circular(8.r), bottomLeft: Radius.circular(10.r))
: (isLast ? BorderRadius.only(topRight: Radius.circular(8.r), bottomRight: Radius.circular(10.r)) : null),
),
),
);
}).toList();
return Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [
Stack(
children: [ children: [
Container( Container(
height: 20.h, height: 8.h,
width: containerWidth,
decoration: BoxDecoration(
// color: Color.fromRGBO(146, 146, 146, 1),
color: Color.fromRGBO(202, 201, 201, 1),
borderRadius: BorderRadius.circular(50.r),
),
),
...pauseTickMarks,
Container(
height: 8.h,
// color: Theme.of(context).primaryColor, // color: Theme.of(context).primaryColor,
child: SliderTheme(
data: SliderTheme.of(context).copyWith(
trackHeight: 8.h, //
trackShape: RoundedRectSliderTrackShape(), //
activeTrackColor: Theme.of(context).primaryColor, //
inactiveTrackColor: Colors.transparent, //
thumbShape: RoundSliderThumbShape(enabledThumbRadius: 0, disabledThumbRadius: 0),
thumbColor: Colors.white, //
overlayShape: RoundSliderOverlayShape(overlayRadius: 0),
overlayColor: Colors.black54, //
// valueIndicatorShape: PaddleSliderValueIndicatorShape(), //
),
child: Slider( child: Slider(
///
value: (usePlaybar.handwritingDuration.value - usePlaybar.useTime.value).toDouble(), value: (usePlaybar.handwritingDuration.value - usePlaybar.useTime.value).toDouble(),
/// 0
min: 0.0, min: 0.0,
/// 1
max: usePlaybar.handwritingDuration.value.toDouble(), max: usePlaybar.handwritingDuration.value.toDouble(),
// divisions:1, inactiveColor: Colors.transparent,
///
// activeColor: Colors.red,
///
inactiveColor: Color.fromRGBO(217, 217, 217, 1),
/// onChanged null Slider
onChangeEnd: (value) { onChangeEnd: (value) {
usePlaybar.playTimingSuspend(); // usePlaybar.playTimingSuspend(); //
usePlaybar.eventFire(model: JobHandwritingDragProgressBarBus(value.toInt(), usePlaybar.handwritingDuration.value)); usePlaybar.eventFire(model: JobHandwritingDragProgressBarBus(value.toInt(), usePlaybar.handwritingDuration.value));
@ -764,12 +814,9 @@ Widget $bottomPlaybar(BuildContext context, int timeConsuming, int pauseCount) {
usePlaybar.useTime.value = usePlaybar.handwritingDuration.value - value.toInt(); usePlaybar.useTime.value = usePlaybar.handwritingDuration.value - value.toInt();
}, },
), ),
),
// /// ),
// onChangeStart: (value) => log('onChangeStart: $value'), ],
// ///
// onChangeEnd: (value) => log('onChangeEnd: $value'),
), ),
SizedBox(height: 4.h), SizedBox(height: 4.h),
Row( Row(
@ -780,6 +827,8 @@ Widget $bottomPlaybar(BuildContext context, int timeConsuming, int pauseCount) {
], ],
) )
], ],
);
},
), ),
), ),
SizedBox(width: 16.w), SizedBox(width: 16.w),
@ -798,7 +847,7 @@ Widget $bottomPlaybar(BuildContext context, int timeConsuming, int pauseCount) {
child: quickText( child: quickText(
'${usePlaybar.constantFastSpeed.value.name}', '${usePlaybar.constantFastSpeed.value.name}',
color: Color.fromRGBO(79, 114, 244, 1), color: Color.fromRGBO(79, 114, 244, 1),
size: 10.sp, size: 8.sp,
align: TextAlign.center, align: TextAlign.center,
), ),
), ),
@ -808,6 +857,11 @@ Widget $bottomPlaybar(BuildContext context, int timeConsuming, int pauseCount) {
); );
} }
@swidget
Widget $pauseTickMark() {
return Container();
}
class UseBottomPlaybar with EventBusMixin { class UseBottomPlaybar with EventBusMixin {
final ValueNotifier<int> handwritingDuration; // final ValueNotifier<int> handwritingDuration; //
final ValueNotifier<bool> playPause; // final ValueNotifier<bool> playPause; //
@ -844,7 +898,8 @@ class UseBottomPlaybar with EventBusMixin {
void playTimingStarts() { void playTimingStarts() {
if (useTime.value > 0) { if (useTime.value > 0) {
timer.value?.cancel(); timer.value?.cancel();
timer.value = Timer.periodic(Duration(seconds: 1), (theTime) {
timer.value = Timer.periodic(Duration(milliseconds: 1000 ~/ constantFastSpeed.value.speed), (theTime) {
useTime.value -= 1; useTime.value -= 1;
if (useTime.value < 0) { if (useTime.value < 0) {
timer.value?.cancel(); timer.value?.cancel();
@ -898,9 +953,26 @@ enum PlaybackSpeed {
ORIGINAL_SPEED(name: '原速播放', speed: 1), ORIGINAL_SPEED(name: '原速播放', speed: 1),
ONE_POINT_FIVE_SPEED(name: '1.5x播放', speed: 1.5), ONE_POINT_FIVE_SPEED(name: '1.5x播放', speed: 1.5),
DOUBLE_SPEED(name: '2.0x播放', speed: 2), DOUBLE_SPEED(name: '2.0x播放', speed: 2),
TRIPLE_SPEED(name: '3.0x播放', speed: 3); TRIPLE_SPEED(name: '3.0x播放', speed: 3),
FOUR_SPEED(name: '4.0x播放', speed: 4),
FIVE_SPEED(name: '5.0x播放', speed: 5),
SIX_SPEED(name: '6.0x播放', speed: 6);
const PlaybackSpeed({required this.name, required this.speed}); const PlaybackSpeed({required this.name, required this.speed});
final double speed; final double speed;
final String name; final String name;
} }
@JsonSerializable()
class PauseIntervalTime extends Object {
int? apart;
int startTime;
int endTime;
PauseIntervalTime({required this.startTime, required this.endTime}) {
apart = endTime - startTime;
}
factory PauseIntervalTime.fromJson(Map<String, dynamic> srcJson) => _$PauseIntervalTimeFromJson(srcJson);
Map<String, dynamic> toJson() => _$PauseIntervalTimeToJson(this);
}

View File

@ -8,6 +8,7 @@ class StudentKgTable extends StatefulWidget {
final List bodyList; final List bodyList;
final int? fixedRows; final int? fixedRows;
final int? fixedCols; final int? fixedCols;
final Function(String)? questionNumCall;
const StudentKgTable({ const StudentKgTable({
Key? key, Key? key,
@ -15,6 +16,7 @@ class StudentKgTable extends StatefulWidget {
required this.bodyList, required this.bodyList,
this.fixedCols = 0, this.fixedCols = 0,
this.fixedRows = 0, this.fixedRows = 0,
this.questionNumCall,
}) : super(key: key); }) : super(key: key);
@override @override
@ -29,6 +31,7 @@ class _StudentKgTableState extends State<StudentKgTable> {
String sortString(String str) { String sortString(String str) {
return String.fromCharCodes(str.codeUnits.toList()..sort()); return String.fromCharCodes(str.codeUnits.toList()..sort());
} }
DataRow _getRow(int index, [Color? color]) { DataRow _getRow(int index, [Color? color]) {
assert(index >= 0); assert(index >= 0);
KgDetails item = widget.bodyList[index]; KgDetails item = widget.bodyList[index];
@ -36,27 +39,43 @@ class _StudentKgTableState extends State<StudentKgTable> {
index: index, index: index,
color: color != null ? MaterialStateProperty.all(color) : null, color: color != null ? MaterialStateProperty.all(color) : null,
cells: [ cells: [
DataCell(Center( DataCell(
InkWell(
onTap: () {
if (widget.questionNumCall != null) {
widget.questionNumCall!(item.questionNo);
}
},
child: Center(
child: Padding( child: Padding(
padding: EdgeInsets.symmetric(horizontal: 5.r), padding: EdgeInsets.symmetric(horizontal: 5.r),
child: Text(item.questionNo, child: Text(item.questionNo, style: TextStyle(fontSize: 12.sp, color: Color(0xFF6888FD))),
style: TextStyle(fontSize: 12.sp, color: Color(0xFF6888FD))), ),
),
),
), ),
)),
DataCell(Center( DataCell(Center(
child: Padding( child: Padding(
padding: EdgeInsets.symmetric(horizontal: 5.r), padding: EdgeInsets.symmetric(horizontal: 5.r),
child: Text(item.studentAnswer == null?'未作答':item.studentAnswer!, child: Text(
style: TextStyle(fontSize: 12.sp, color: item.studentAnswer == null?Color(0xFF525252): item.studentAnswer == null ? '未作答' : item.studentAnswer!,
item.state == 2?Color(0xFF4CC793): style: TextStyle(
item.state == 1?Color(0xFFFF7474):item.state == 0?Color(0xFFD3D3D3):Colors.white), fontSize: 12.sp,
color: item.studentAnswer == null
? Color(0xFF525252)
: item.state == 2
? Color(0xFF4CC793)
: item.state == 1
? Color(0xFFFF7474)
: item.state == 0
? Color(0xFFD3D3D3)
: Colors.white),
), ),
))), ))),
DataCell(Center( DataCell(Center(
child: Padding( child: Padding(
padding: EdgeInsets.symmetric(horizontal: 5.r), padding: EdgeInsets.symmetric(horizontal: 5.r),
child: Text(item.questionAnswer == null ?'':item.questionAnswer!, child: Text(item.questionAnswer == null ? '' : item.questionAnswer!, style: TextStyle(fontSize: 12.sp, color: Color(0xFF525252))),
style: TextStyle(fontSize: 12.sp, color: Color(0xFF525252))),
), ),
)), )),
], ],
@ -74,14 +93,10 @@ class _StudentKgTableState extends State<StudentKgTable> {
dataRowHeight: 40.r, dataRowHeight: 40.r,
headingRowHeight: 40.r, headingRowHeight: 40.r,
border: TableBorder( border: TableBorder(
horizontalInside: BorderSide( horizontalInside: BorderSide(width: 1, color: Colors.white, style: BorderStyle.solid),
width: 1, color: Colors.white, style: BorderStyle.solid), bottom: BorderSide(width: 1, color: Colors.white, style: BorderStyle.solid),
bottom: BorderSide( verticalInside: BorderSide(width: 1, color: Colors.white, style: BorderStyle.solid)),
width: 1, color: Colors.white, style: BorderStyle.solid), headingRowColor: MaterialStateProperty.resolveWith((states) => widget.fixedCols! > 0 ? Colors.white : Colors.transparent),
verticalInside: BorderSide(
width: 1, color: Colors.white, style: BorderStyle.solid)),
headingRowColor: MaterialStateProperty.resolveWith((states) =>
widget.fixedCols! > 0 ? Colors.white : Colors.transparent),
headingRowDecoration: BoxDecoration(color: Color(0xFFE6E6E6)), headingRowDecoration: BoxDecoration(color: Color(0xFFE6E6E6)),
fixedColumnsColor: Color(0xFFE6E6E6), fixedColumnsColor: Color(0xFFE6E6E6),
fixedCornerColor: Colors.grey[400], fixedCornerColor: Colors.grey[400],
@ -95,14 +110,12 @@ class _StudentKgTableState extends State<StudentKgTable> {
var item = widget.headList[index]; var item = widget.headList[index];
return DataColumn2( return DataColumn2(
label: Center( label: Center(
child: Text(item, child: Text(item, style: TextStyle(fontSize: 12.sp, color: Color(0xFF505767))),
style: TextStyle(fontSize: 12.sp, color: Color(0xFF505767))),
), ),
// size: ColumnSize.S, // size: ColumnSize.S,
fixedWidth: (MediaQuery.of(context).size.width - 20.r - 28.r) / 3, fixedWidth: (MediaQuery.of(context).size.width - 20.r - 28.r) / 3,
); );
}), }),
rows: List<DataRow>.generate(widget.bodyList.length, rows: List<DataRow>.generate(widget.bodyList.length, (index) => _getRow(index, Color(0xFFF5F5F5))));
(index) => _getRow(index, Color(0xFFF5F5F5))));
} }
} }

View File

@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:marking_app/common/model/job/job_data_report.dart'; import 'package:marking_app/common/model/job/job_data_report.dart';
import 'package:marking_app/pages/homework_correction/components/imgDialog.dart'; import 'package:marking_app/pages/homework_correction/components/imgDialog.dart';
import 'package:marking_app/pages/homework_correction/widget/answer_handwriting.dart';
import 'package:marking_app/utils/common_utils.dart'; import 'package:marking_app/utils/common_utils.dart';
import 'package:marking_app/utils/easy_refresh/MyEmptyWidget.dart'; import 'package:marking_app/utils/easy_refresh/MyEmptyWidget.dart';
import 'package:photo_view/photo_view.dart'; import 'package:photo_view/photo_view.dart';
@ -12,6 +13,7 @@ class StudentZgTable extends StatefulWidget {
final List bodyList; final List bodyList;
final int? fixedRows; final int? fixedRows;
final int? fixedCols; final int? fixedCols;
final Function(String)? questionNumCall;
const StudentZgTable({ const StudentZgTable({
Key? key, Key? key,
@ -19,6 +21,7 @@ class StudentZgTable extends StatefulWidget {
required this.bodyList, required this.bodyList,
this.fixedCols = 0, this.fixedCols = 0,
this.fixedRows = 0, this.fixedRows = 0,
this.questionNumCall,
}) : super(key: key); }) : super(key: key);
@override @override
@ -72,18 +75,23 @@ class _StudentZgTableState extends State<StudentZgTable> {
index: index, index: index,
color: color != null ? MaterialStateProperty.all(color) : null, color: color != null ? MaterialStateProperty.all(color) : null,
cells: [ cells: [
DataCell(Center( DataCell(InkWell(
onTap: () {
if (widget.questionNumCall != null) {
widget.questionNumCall!(item.questionNo);
}
},
child: Center(
child: Padding( child: Padding(
padding: EdgeInsets.symmetric(horizontal: 5.r), padding: EdgeInsets.symmetric(horizontal: 5.r),
child: Text(item.questionNo, child: Text(item.questionNo, style: TextStyle(fontSize: 12.sp, color: Color(0xFF6888FD))),
style: TextStyle(fontSize: 12.sp, color: Color(0xFF6888FD))), ),
), ),
)), )),
DataCell(Center( DataCell(Center(
child: Padding( child: Padding(
padding: EdgeInsets.symmetric(horizontal: 5.r), padding: EdgeInsets.symmetric(horizontal: 5.r),
child: Text(CommonUtils.second2HMS(item.useTime!), child: Text(CommonUtils.second2HMS(item.useTime!), style: TextStyle(fontSize: 12.sp, color: Color(0xFF525252))),
style: TextStyle(fontSize: 12.sp, color: Color(0xFF525252))),
), ),
)), )),
DataCell(InkWell( DataCell(InkWell(
@ -91,22 +99,30 @@ class _StudentZgTableState extends State<StudentZgTable> {
if (item.state != 0) { if (item.state != 0) {
ImageDialog.showImgDialog(context, item.studentAnswer!); ImageDialog.showImgDialog(context, item.studentAnswer!);
} }
}, },
child: Center( child: Center(
child: Padding( child: Padding(
padding: EdgeInsets.symmetric(horizontal: 5.r), padding: EdgeInsets.symmetric(horizontal: 5.r),
child: Text(item.state!=0 ?'查看':'--', child: Text(item.state != 0 ? '查看' : '--', style: TextStyle(fontSize: 12.sp, color: Color(0xFF3661FE))),
style: TextStyle(fontSize: 12.sp, color: Color(0xFF3661FE))),
), ),
), ),
)), )),
DataCell(Center( DataCell(Center(
child: Padding( child: Padding(
padding: EdgeInsets.symmetric(horizontal: 5.r), padding: EdgeInsets.symmetric(horizontal: 5.r),
child: item.state == 2? child: item.state == 2
Image.asset('assets/images/job_personal_correct_icon.png',width: 18.r,height: 18.r,):item.state == 1? ? Image.asset(
Image.asset('assets/images/job_personal_error_icon.png',width: 10.r,height: 10.r,):Text('', style: TextStyle(fontSize: 12.sp, color: Color(0xFF525252))), 'assets/images/job_personal_correct_icon.png',
width: 18.r,
height: 18.r,
)
: item.state == 1
? Image.asset(
'assets/images/job_personal_error_icon.png',
width: 10.r,
height: 10.r,
)
: Text('', style: TextStyle(fontSize: 12.sp, color: Color(0xFF525252))),
), ),
)), )),
DataCell(InkWell( DataCell(InkWell(
@ -114,13 +130,11 @@ class _StudentZgTableState extends State<StudentZgTable> {
if (item.state == 1 || item.state == 2) { if (item.state == 1 || item.state == 2) {
ImageDialog.showImgDialog(context, item.annotateAnswers!); ImageDialog.showImgDialog(context, item.annotateAnswers!);
} }
}, },
child: Center( child: Center(
child: Padding( child: Padding(
padding: EdgeInsets.symmetric(horizontal: 5.r), padding: EdgeInsets.symmetric(horizontal: 5.r),
child: Text(item.state==1 || item.state==2?'查看':'--', child: Text(item.state == 1 || item.state == 2 ? '查看' : '--', style: TextStyle(fontSize: 12.sp, color: Color(0xFF3661FE))),
style: TextStyle(fontSize: 12.sp, color: Color(0xFF3661FE))),
), ),
), ),
)), )),
@ -139,14 +153,10 @@ class _StudentZgTableState extends State<StudentZgTable> {
headingRowHeight: 40.r, headingRowHeight: 40.r,
dataRowHeight: 40.r, dataRowHeight: 40.r,
border: TableBorder( border: TableBorder(
horizontalInside: BorderSide( horizontalInside: BorderSide(width: 1, color: Colors.white, style: BorderStyle.solid),
width: 1, color: Colors.white, style: BorderStyle.solid), bottom: BorderSide(width: 1, color: Colors.white, style: BorderStyle.solid),
bottom: BorderSide( verticalInside: BorderSide(width: 1, color: Colors.white, style: BorderStyle.solid)),
width: 1, color: Colors.white, style: BorderStyle.solid), headingRowColor: MaterialStateProperty.resolveWith((states) => widget.fixedCols! > 0 ? Colors.white : Colors.transparent),
verticalInside: BorderSide(
width: 1, color: Colors.white, style: BorderStyle.solid)),
headingRowColor: MaterialStateProperty.resolveWith((states) =>
widget.fixedCols! > 0 ? Colors.white : Colors.transparent),
headingRowDecoration: BoxDecoration(color: Color(0xFFE6E6E6)), headingRowDecoration: BoxDecoration(color: Color(0xFFE6E6E6)),
fixedColumnsColor: Color(0xFFE6E6E6), fixedColumnsColor: Color(0xFFE6E6E6),
fixedCornerColor: Colors.grey[400], fixedCornerColor: Colors.grey[400],
@ -160,14 +170,12 @@ class _StudentZgTableState extends State<StudentZgTable> {
var item = widget.headList[index]; var item = widget.headList[index];
return DataColumn2( return DataColumn2(
label: Center( label: Center(
child: Text(item, child: Text(item, style: TextStyle(fontSize: 12.sp, color: Color(0xFF505767))),
style: TextStyle(fontSize: 12.sp, color: Color(0xFF505767))),
), ),
// size: ColumnSize.S, // size: ColumnSize.S,
fixedWidth: (MediaQuery.of(context).size.width - 20.r - 28.r) / 5, fixedWidth: (MediaQuery.of(context).size.width - 20.r - 28.r) / 5,
); );
}), }),
rows: List<DataRow>.generate(widget.bodyList.length, rows: List<DataRow>.generate(widget.bodyList.length, (index) => _getRow(index, Color(0xFFF5F5F5))));
(index) => _getRow(index, Color(0xFFF5F5F5))));
} }
} }