Compare commits

..

17 Commits

Author SHA1 Message Date
1147192855@qq.com afeb05272e no message 2024-04-28 13:47:29 +08:00
machuanyu 3944a72ab6 Merge branch 'mcy' into main
# Conflicts:
#	marking_app/lib/routes/RouterManager.dart
2024-04-28 11:45:58 +08:00
豌杂 ab6546a7af no message 2024-04-28 11:01:34 +08:00
1147192855@qq.com fff1bb5639 no message 2024-04-28 10:45:56 +08:00
1147192855@qq.com a636819fda Merge branch 'job_new_demand'
# Conflicts:
#	marking_app/lib/routes/RouterManager.dart
#	marking_app/lib/utils/request/rest_client.dart
2024-04-28 10:38:32 +08:00
1147192855@qq.com 89e15ba672 no message 2024-04-28 09:28:57 +08:00
1147192855@qq.com 8ab319c32e no message 2024-04-26 18:08:46 +08:00
machuanyu 8d1de06f14 注册,注销账号 2024-04-26 17:31:03 +08:00
1147192855@qq.com 17738ff29e no message 2024-04-25 14:33:06 +08:00
1147192855@qq.com 919f71f28b no message 2024-04-25 10:59:37 +08:00
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
machuanyu 23bd9501ff bug修改 2024-04-24 16:43:08 +08:00
1147192855@qq.com 8c10e6eb4d no message 2024-04-24 13:46:19 +08:00
1147192855@qq.com 02cb205126 no message 2024-04-19 14:12:04 +08:00
1147192855@qq.com 8c800e1d1c no message 2024-04-19 13:48:06 +08:00
1147192855@qq.com e33e3cfac3 no message 2024-04-17 16:04:48 +08:00
38 changed files with 2272 additions and 576 deletions

5
.gitignore vendored
View File

@ -225,3 +225,8 @@ marking_app/lib/pages/homework_correction/job_home.g.dart
marking_app/lib/common/model/marking/keyboard_assist_event.g.dart
marking_app/lib/common/model/marking/marking_history_zoom_info.g.dart
marking_app/lib/common/model/job/job_handwriting.g.dart
marking_app/lib/utils/my_time_util.g.dart
marking_app/lib/pages/homework_correction/widget/answer_handwriting.g.dart
marking_app/lib/pages/report_detail/report_history.g.dart
marking_app/lib/common/model/report/report_student_history_record.g.dart
marking_app/lib/common/model/report/report_student_info.g.dart

Binary file not shown.

After

Width:  |  Height:  |  Size: 303 B

View File

@ -352,7 +352,7 @@
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES;
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = "";
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = 21;
CURRENT_PROJECT_VERSION = 22;
DEVELOPMENT_TEAM = CYDU583KN6;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
@ -360,7 +360,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0.104;
MARKETING_VERSION = 1.0.105;
PRODUCT_BUNDLE_IDENTIFIER = com.example.markingApp;
PRODUCT_NAME = "$(TARGET_NAME)";
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
@ -490,7 +490,7 @@
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES;
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = "";
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = 21;
CURRENT_PROJECT_VERSION = 22;
DEVELOPMENT_TEAM = CYDU583KN6;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
@ -498,7 +498,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0.104;
MARKETING_VERSION = 1.0.105;
PRODUCT_BUNDLE_IDENTIFIER = com.example.markingApp;
PRODUCT_NAME = "$(TARGET_NAME)";
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
@ -520,7 +520,7 @@
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES;
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = "";
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = 21;
CURRENT_PROJECT_VERSION = 22;
DEVELOPMENT_TEAM = CYDU583KN6;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
@ -528,7 +528,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0.104;
MARKETING_VERSION = 1.0.105;
PRODUCT_BUNDLE_IDENTIFIER = com.example.markingApp;
PRODUCT_NAME = "$(TARGET_NAME)";
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";

View File

@ -33,6 +33,12 @@ mixin CommonMixin {
return RestClientReport(dio, baseUrl: RequestConfig().baseUrlOfReport);
}
// CLIENT
Future<RestClient> getClientLogin() async {
Dio dio = await getDio();
return RestClient(dio, baseUrl: RequestConfig().loginBaseUrl);
}
void setTimeOut(int seconds, call) => Future.delayed(Duration(seconds: seconds), call);
// context

View File

@ -14,11 +14,30 @@ class GestureRecording {
bool scopeBox;
int intervalTime; //
GestureRecording({
required this.eraser,
required this.annotationSwitch,
this.data,
this.usageTime,
this.scopeBox = false,
this.intervalTime = 0,
});
}
/**
* (稿)
*/
class GestureHandwritingRecording {
int stroke;
int usageTime; //
Offset data;
int intervalTime; //
GestureHandwritingRecording({
required this.stroke,
required this.data,
required this.usageTime,
required this.intervalTime,
});
}

View File

@ -16,12 +16,7 @@ class JobHandwriting extends Object {
@JsonKey(name: 'pageCount')
int pageCount;
JobHandwriting(
this.lattices,
this.paperPicture,
this.pageNum,
this.pageCount,
);
JobHandwriting(this.lattices, this.paperPicture, this.pageNum, this.pageCount);
factory JobHandwriting.fromJson(Map<String, dynamic> srcJson) => _$JobHandwritingFromJson(srcJson);
@ -34,20 +29,18 @@ class Lattices extends Object {
int stroke;
@JsonKey(name: 'x')
int x;
double x;
@JsonKey(name: 'y')
int y;
double y;
@JsonKey(name: 'time')
int time;
Lattices(
this.stroke,
this.x,
this.y,
this.time,
);
@JsonKey(name: 'intervalTime')
int intervalTime;
Lattices(this.stroke, this.x, this.y, this.time, [this.intervalTime = 0]);
factory Lattices.fromJson(Map<String, dynamic> srcJson) => _$LatticesFromJson(srcJson);

View File

@ -36,12 +36,7 @@ class TestQuestionsImageInfo extends Object {
double? imageHeightOffsetend;
TestQuestionsImageInfo(
{required this.width,
required this.height,
required this.url,
required this.boxWidth,
required this.boxHeight,
this.pixelRatio = 1}) {
{required this.width, required this.height, required this.url, required this.boxWidth, required this.boxHeight, this.pixelRatio = 1}) {
// print('图片宽度:$width');
// print('图片高度:$height');
@ -60,6 +55,14 @@ class TestQuestionsImageInfo extends Object {
}
}
//
void calculateStartAndEndHeight([double otherHeight = 0]) {
if (scaleHeight != null) {
imageHeightOffsetStart = (boxHeight - (scaleHeight! + otherHeight)) / 2;
imageHeightOffsetend = imageHeightOffsetStart! + scaleHeight!;
}
}
factory TestQuestionsImageInfo.fromJson(Map<String, dynamic> srcJson) => _$TestQuestionsImageInfoFromJson(srcJson);
Map<String, dynamic> toJson() => _$TestQuestionsImageInfoToJson(this);

View File

@ -24,8 +24,7 @@ void main() {
WidgetsFlutterBinding.ensureInitialized();
RouterManager.initRouter();
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual,
overlays: [SystemUiOverlay.top, SystemUiOverlay.bottom]); //
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: [SystemUiOverlay.top, SystemUiOverlay.bottom]); //
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); //
// OrientationHelper.setEnabledSystemUIOverlays(SystemUiOverlay.values);
@ -81,7 +80,7 @@ class _MyAppState extends State<MyApp> {
splitScreenMode: true,
builder: (context1, child) {
return MaterialApp(
title: '远轩阅卷系统',
title: '学而有道阅卷',
navigatorKey: TheGlobal.navigatorKey,
debugShowCheckedModeBanner: false,
// locale: const Locale('zh', 'CN'), // ,

View File

@ -58,7 +58,6 @@ class _AnswerTrajectoryState extends State<AnswerTrajectory>
});
getStudentGroups();
getWorkList();
print(userInfo);
});
}
@ -107,7 +106,6 @@ class _AnswerTrajectoryState extends State<AnswerTrajectory>
}
jobList = arr;
setState(() {});
print('total=${res.data!.total}');
refreshController2.finishRefresh();
EasyLoading.dismiss();
}

View File

@ -185,8 +185,14 @@ class _AnswerTrajectoryJobDetailState extends State<AnswerTrajectoryJobDetail>
var item = students[index];
return InkWell(
onTap: (){
RouterManager.router.navigateTo(context,
'${RouterManager.jobPersonalDetailPath}?studentId=${item.studentId}&studentName=${Uri.encodeComponent(item.studentName)}');
RouterManager.router.navigateTo(
context,
RouterManager.quickCheckPersonalPath +
'?jobId=${widget.jobId}&studentId=${item.studentId}',
transition: getTransition(),
);
// RouterManager.router.navigateTo(context,
// '${RouterManager.jobPersonalDetailPath}?studentId=${item.studentId}&studentName=${Uri.encodeComponent(item.studentName)}');
},
child: Container(
padding: EdgeInsets.symmetric(horizontal: 10.r),
@ -228,8 +234,14 @@ class _AnswerTrajectoryJobDetailState extends State<AnswerTrajectoryJobDetail>
var item = students[index];
return InkWell(
onTap: (){
RouterManager.router.navigateTo(context,
'${RouterManager.jobPersonalDetailPath}?studentId=${item.studentId}&studentName=${Uri.encodeComponent(item.studentName)}');
RouterManager.router.navigateTo(
context,
RouterManager.quickCheckPersonalPath +
'?jobId=${widget.jobId}&studentId=${item.studentId}',
transition: getTransition(),
);
// RouterManager.router.navigateTo(context,
// '${RouterManager.jobPersonalDetailPath}?studentId=${item.studentId}&studentName=${Uri.encodeComponent(item.studentName)}');
},
child: Container(
padding: EdgeInsets.symmetric(

View File

@ -0,0 +1,25 @@
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
class ImageDialog{
static void showImgDialog(BuildContext context,String imgUrl) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
// insetPadding: EdgeInsets.symmetric(vertical: 10.r,horizontal: 45.r),
backgroundColor: Colors.transparent,
contentPadding: EdgeInsets.all(0),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(15.r))),
content: Container(
width: MediaQuery.of(context).size.width - 48.r,
// height: MediaQuery.of(context).size.height * 0.4,
color: Colors.white,
// child: PhotoView(imageProvider: NetworkImage(imgUrl),backgroundDecoration: BoxDecoration(color: Colors.transparent),)),
child: Image.network(imgUrl)),
);
},
);
}
}

View File

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

View File

@ -290,7 +290,11 @@ Widget $dropdownBoxSwitchStudentsOrTypeView(BuildContext context, {required Func
var _currentTab = _useSwitchStudentAndType.currentTab.value;
var _pageIndex = _currentTab?.pageIndex;
if (_currentTab == null || _pageIndex == null) return;
_useSwitchStudentAndType.refreshQuestionTypeData(context, taskId: taskId, exitCallback: exitCallback, getNewData: false).then((value) {
var theLastQuestion = _currentTab.finishCount + 1 == _currentTab.total; //
_useSwitchStudentAndType
.refreshQuestionTypeData(context, taskId: taskId, exitCallback: exitCallback, getNewData: theLastQuestion)
.then((value) {
var params = MarkingTextQuestionJobTabParamsBus(taskId, _pageIndex);
if (_currentTab.finishCount < _currentTab.total) {
if (_currentTab.finishCount + 1 == _currentTab.total) {
@ -366,7 +370,9 @@ Widget $dropdownBoxSwitchStudentsOrTypeView(BuildContext context, {required Func
Expanded(flex: 1, child: SizedBox()),
Expanded(
flex: 4,
child: Container(
child: Stack(
children: [
Container(
padding: EdgeInsets.only(left: 10.w),
decoration: BoxDecoration(
color: Color.fromRGBO(244, 244, 244, 1),
@ -398,6 +404,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(
@ -458,17 +480,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),
],
),
],
),
),
@ -852,7 +863,6 @@ Widget $examPaperAndScoringKeyboardView(
],
),
),
if (question.accuracy > 0)
Padding(
padding: EdgeInsets.only(bottom: 1.5.h),
child: quickText(

View File

@ -140,7 +140,7 @@ class UseSwitchStudentAndType with CommonMixin, EventBusMixin {
return tabJob;
}
}
ToastUtils.showSuccess('最后一题提交成功');
// ToastUtils.showSuccess('最后一题提交成功');
}
return tabJob;
}

View File

@ -261,19 +261,10 @@ class _HomeworkCorrectionState extends ConsumerState<HomeworkCorrection>
),
),
),
Expanded(
flex: 1,
child: InkWell(
onTap: () {
RouterManager.router.navigateTo(context, RouterManager.jobStudentGroupPath, transition: getTransition());
},
child: Icon(IconData(0xe63e, fontFamily: "AlibabaIcon"), color: Color.fromRGBO(44, 48, 63, 1), size: 24.sp),
),
),
Expanded(flex: 1, child: SizedBox()),
],
),
),
if (_tabIndex == 1)
$CompletedJobConditionFilter(
controller: _tabController2,

View File

@ -76,14 +76,17 @@ class _JobHomeState extends State<JobHome> with CommonMixin, EventBusMixin, Auto
child: ListView(
children: [
Container(
height: 200.h,
width: double.infinity,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/job_home_top_bgm.png'),
fit: BoxFit.fill, //
),
constraints: BoxConstraints(
minHeight: 200.h,
maxWidth: double.infinity,
),
// decoration: BoxDecoration(
// image: DecorationImage(
// image: AssetImage('assets/images/job_home_top_bgm.png'),
// fit: BoxFit.fitWidth, //
// ),
// ),
child: Image.asset('assets/images/job_home_top_bgm.png', fit: BoxFit.fitWidth),
),
SizedBox(height: 30.h),
SlidingData([
@ -104,8 +107,8 @@ class _JobHomeState extends State<JobHome> with CommonMixin, EventBusMixin, Auto
navigationUrl: '${RouterManager.jobStudentGroupPath}?page=set',
)
], 0),
spaceWidth,
$TermRow([EntranceModel(title: '批阅设置', image: 'assets/images/job_home_marking_set.png', navigationUrl: '')], 0),
// spaceWidth,
// $TermRow([EntranceModel(title: '批阅设置', image: 'assets/images/job_home_marking_set.png', navigationUrl: '')], 0),
],
),
),

View File

@ -63,8 +63,8 @@ class _JobKnowledgePointsState extends State<JobKnowledgePoints> with CommonMixi
}
void getList() async {
print('startDataTime=$startDataTime');
print('endDataTime=$endDataTime');
/* print('startDataTime=$startDataTime');
print('endDataTime=$endDataTime');*/
RestClient _client = await getClient();
BaseStructureResult<List<KnowledgePoints>> res =
await _client.getKnowledgeReport(startDataTime,endDataTime,textController.text);
@ -265,7 +265,7 @@ class _JobKnowledgePointsState extends State<JobKnowledgePoints> with CommonMixi
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'2',
'${item.count}',
style: TextStyle(fontSize: 10.sp, color: Color(0xFF6888FD)),
),
Image.asset('assets/images/right_icon_blue.png',width: 8.r,height: 8.r,),

View File

@ -271,7 +271,7 @@ class _JobKnowledgePointsDetailState extends State<JobKnowledgePointsDetail>
),
child: Center(
child: Text(
'${item.questionNo}',
'${item.questionNo}',
style: TextStyle(
fontSize: 10.sp,
color: Color(0xFF8B8B8B)),
@ -307,10 +307,15 @@ class _JobKnowledgePointsDetailState extends State<JobKnowledgePointsDetail>
borderRadius:
BorderRadius.circular(20.r),
),
child: Center(
child: quickText('正确率 >',
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
quickText('正确率',
color: Color(0xFF4CC793),
size: 10.sp))),
size: 10.sp),
Image.asset('assets/images/icon_back_green.png',width: 8.r,height: 8.r,)
],
)),
),
Expanded(
flex: 1,

View File

@ -9,6 +9,7 @@ import 'package:marking_app/common/model/job/job_report_join_class.dart';
import 'package:marking_app/common/model/job/job_report_knowledge_model.dart';
import 'package:marking_app/common/model/job/job_report_model.dart';
import 'package:marking_app/components/ReturnToHomepage.dart';
import 'package:marking_app/pages/homework_correction/components/imgDialog.dart';
import 'package:marking_app/pages/homework_correction/widget/report_table.dart';
import 'package:marking_app/pages/homework_correction/widget/top_count.dart';
import 'package:marking_app/pages/mainPage.dart';
@ -1445,7 +1446,7 @@ Widget $unitTimeAnsweringSituation(BuildContext context, int jobid, List<Questio
// return;
// }
if (_qpm.questionPicture == null) return ToastUtils.showInfo('当前试题没有原题');
Navigator.push(
/* Navigator.push(
context,
MaterialPageRoute(builder: (_) {
return Scaffold(
@ -1453,7 +1454,8 @@ Widget $unitTimeAnsweringSituation(BuildContext context, int jobid, List<Questio
body: PhotoView(imageProvider: NetworkImage(_qpm.questionPicture!)),
);
}),
);
);*/
ImageDialog.showImgDialog(context,_qpm.questionPicture!);
},
child: Row(
mainAxisSize: MainAxisSize.min,

View File

@ -0,0 +1,18 @@
/// 稿
//
import 'package:marking_app/common/model/job/gesture_recording.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:marking_app/common/mixin/common.dart';
final jobHandwritingDrawingTrajectoryProvider =
StateNotifierProvider<JobHandwritingDrawingTrajectoryProviderHandle, List<GestureHandwritingRecording>>(
(ref) => JobHandwritingDrawingTrajectoryProviderHandle([]));
class JobHandwritingDrawingTrajectoryProviderHandle extends StateNotifier<List<GestureHandwritingRecording>> with CommonMixin {
JobHandwritingDrawingTrajectoryProviderHandle(List<GestureHandwritingRecording> progress) : super(progress);
setVal(List<GestureHandwritingRecording> val) {
state = val;
}
}

View File

@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:marking_app/common/mixin/common.dart';
import 'package:marking_app/common/model/common/base_structure_result.dart';
import 'package:marking_app/common/model/job/job_data_report.dart';
@ -8,23 +9,23 @@ 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_zg_table.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/toast_utils.dart';
import 'providers/handwriting_drawing_trajectory_provider.dart';
import 'widget/answer_handwriting.dart';
class QuickCheckPersonal extends StatefulWidget {
class QuickCheckPersonal extends StatefulHookConsumerWidget {
final int jobId;
final int studentId;
const QuickCheckPersonal({Key? key, required this.jobId, required this.studentId}) : super(key: key);
@override
State<QuickCheckPersonal> createState() => _QuickCheckPersonalState();
ConsumerState<QuickCheckPersonal> createState() => _QuickCheckPersonalState();
}
class _QuickCheckPersonalState extends State<QuickCheckPersonal> with CommonMixin {
class _QuickCheckPersonalState extends ConsumerState<QuickCheckPersonal> with CommonMixin {
StudentDetails? studentInfo;
void initState() {
@ -109,7 +110,7 @@ class _QuickCheckPersonalState extends State<QuickCheckPersonal> with CommonMixi
),
child: Center(
child: Text(
'历史查询',
'历史作业',
style: TextStyle(fontSize: 10.r, color: Color(0xFF2080F7)),
),
),
@ -120,7 +121,9 @@ class _QuickCheckPersonalState extends State<QuickCheckPersonal> with CommonMixi
),
InkWell(
onTap: () {
showAnswerHandwriting(context, jobId: widget.jobId, studentId: widget.studentId);
showAnswerHandwriting(context, jobId: widget.jobId, studentId: widget.studentId).then((value) {
ref.read(jobHandwritingDrawingTrajectoryProvider.notifier).setVal([]);
});
},
child: Container(
width: 93.r,
@ -175,6 +178,11 @@ class _QuickCheckPersonalState extends State<QuickCheckPersonal> with CommonMixi
child: StudentKgTable(
headList: ['题号', '学生答案', '标准答案'],
bodyList: studentInfo!.kgDetails,
questionNumCall: (no) {
showAnswerHandwriting(context, jobId: widget.jobId, studentId: widget.studentId, questionNo: int.parse(no)).then((value) {
ref.read(jobHandwritingDrawingTrajectoryProvider.notifier).setVal([]);
});
},
),
)
],
@ -218,6 +226,11 @@ class _QuickCheckPersonalState extends State<QuickCheckPersonal> with CommonMixi
child: StudentZgTable(
headList: ['题号', '用时', '学生答案', '批注结果', '批注'],
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

@ -23,7 +23,7 @@ class AnswerTrajectoryJob extends StatelessWidget {
crossAxisCount: 2, //widget
mainAxisSpacing: 10.h,
crossAxisSpacing: 6.w,
childAspectRatio: 2.5 //1widget
childAspectRatio: 2.4 //1widget
),
children: List.generate(jobList.length, (index) {
JobTaskItem item = jobList[index];
@ -49,6 +49,7 @@ class AnswerTrajectoryJob extends StatelessWidget {
),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
//
Padding(
@ -103,7 +104,10 @@ class AnswerTrajectoryJob extends StatelessWidget {
],
),
),
Padding(
padding: EdgeInsets.symmetric(horizontal: 6.r),
child: Text('时间:${item.createTime.substring(0,10)}',style: TextStyle(fontSize: 10.sp),),
),
Container(
padding: EdgeInsets.symmetric(vertical: 6.h),
decoration: BoxDecoration(
@ -170,6 +174,7 @@ class AnswerTrajectoryJob extends StatelessWidget {
),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
//
Padding(
@ -225,6 +230,13 @@ class AnswerTrajectoryJob extends StatelessWidget {
],
),
),
SizedBox(
height: 5.r,
),
Padding(
padding: EdgeInsets.symmetric(horizontal: 14.r),
child: Text('时间:${item.createTime.substring(0,10)}',style: TextStyle(fontSize: 10.sp),),
),
SizedBox(
height: 10.r,
),

View File

@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_widget_from_html_core/flutter_widget_from_html_core.dart';
import 'package:marking_app/common/model/job/job_report_model.dart';
import 'package:marking_app/pages/homework_correction/components/imgDialog.dart';
import 'package:marking_app/routes/RouterManager.dart';
import 'package:marking_app/utils/easy_refresh/MyEmptyWidget.dart';
import 'package:marking_app/utils/index.dart';
@ -359,7 +360,7 @@ class _ReportTableState extends State<ReportTable> {
onTap: () {
if (item.questionPicture == null)
return ToastUtils.showInfo('当前试题没有原题');
Navigator.push(
/* Navigator.push(
context,
MaterialPageRoute(builder: (_) {
return Scaffold(
@ -369,7 +370,8 @@ class _ReportTableState extends State<ReportTable> {
NetworkImage(item.questionPicture!)),
);
}),
);
);*/
ImageDialog.showImgDialog(context,item.questionPicture!);
},
child: Text('原题',
style: TextStyle(

View File

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

View File

@ -2,6 +2,8 @@ import 'package:data_table_2/data_table_2.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.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/widget/answer_handwriting.dart';
import 'package:marking_app/utils/common_utils.dart';
import 'package:marking_app/utils/easy_refresh/MyEmptyWidget.dart';
import 'package:photo_view/photo_view.dart';
@ -11,6 +13,7 @@ class StudentZgTable extends StatefulWidget {
final List bodyList;
final int? fixedRows;
final int? fixedCols;
final Function(String)? questionNumCall;
const StudentZgTable({
Key? key,
@ -18,6 +21,7 @@ class StudentZgTable extends StatefulWidget {
required this.bodyList,
this.fixedCols = 0,
this.fixedRows = 0,
this.questionNumCall,
}) : super(key: key);
@override
@ -29,22 +33,22 @@ class _StudentZgTableState extends State<StudentZgTable> {
int? _sortColumnIndex;
bool _sortAscending = true;
void showImgDialog(BuildContext context,String imgUrl){
/*void showImgDialog(BuildContext context,String imgUrl){
Navigator.push(
context,
MaterialPageRoute(builder: (_) {
return Scaffold(
appBar: AppBar(),
body: SizedBox(
/* width: MediaQuery.of(context).size.width * 0.6,
height: MediaQuery.of(context).size.height * 0.6,*/
*/ /* width: MediaQuery.of(context).size.width * 0.6,
height: MediaQuery.of(context).size.height * 0.6,*/ /*
child: PhotoView(
imageProvider:
NetworkImage(imgUrl)),
),
);
}),
);
);*/
/* showDialog(context: context, builder: (BuildContext context){
return AlertDialog(
// insetPadding: EdgeInsets.symmetric(vertical: 20.r,horizontal: 20.r),
@ -62,64 +66,75 @@ class _StudentZgTableState extends State<StudentZgTable> {
),
);
});*/
}
// }
DataRow _getRow(int index, [Color? color]) {
assert(index >= 0);
KgDetails item = widget.bodyList[index];
return DataRow2.byIndex(
index: index,
color: color != null ? MaterialStateProperty.all(color): null,
color: color != null ? MaterialStateProperty.all(color) : null,
cells: [
DataCell(Center(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 5.r),
child: Text(item.questionNo,
style: TextStyle(fontSize: 12.sp, color: Color(0xFF6888FD))),
),
)),
DataCell(Center(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 5.r),
child: Text(CommonUtils.second2HMS(item.useTime!),
style: TextStyle(fontSize: 12.sp, color: Color(0xFF525252))),
),
)),
DataCell(InkWell(
onTap: (){
if(item.state != 0){
showImgDialog(context,item.studentAnswer!);
onTap: () {
if (widget.questionNumCall != null) {
widget.questionNumCall!(item.questionNo);
}
},
child: Center(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 5.r),
child: Text(item.state!=0 ?'查看':'--',
style: TextStyle(fontSize: 12.sp, color: Color(0xFF3661FE))),
child: Text(item.questionNo, style: TextStyle(fontSize: 12.sp, color: Color(0xFF6888FD))),
),
),
)),
DataCell(Center(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 5.r),
child: item.state == 2?
Image.asset('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))),
child: Text(CommonUtils.second2HMS(item.useTime!), style: TextStyle(fontSize: 12.sp, color: Color(0xFF525252))),
),
)),
DataCell(InkWell(
onTap: (){
if(item.state==1 || item.state==2){
showImgDialog(context,item.annotateAnswers!);
onTap: () {
if (item.state != 0) {
ImageDialog.showImgDialog(context, item.studentAnswer!);
}
},
child: Center(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 5.r),
child: Text(item.state==1 || item.state==2?'查看':'--',
style: TextStyle(fontSize: 12.sp, color: Color(0xFF3661FE))),
child: Text(item.state != 0 ? '查看' : '--', style: TextStyle(fontSize: 12.sp, color: Color(0xFF3661FE))),
),
),
)),
DataCell(Center(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 5.r),
child: item.state == 2
? Image.asset(
'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(
onTap: () {
if (item.state == 1 || item.state == 2) {
ImageDialog.showImgDialog(context, item.annotateAnswers!);
}
},
child: Center(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 5.r),
child: Text(item.state == 1 || item.state == 2 ? '查看' : '--', style: TextStyle(fontSize: 12.sp, color: Color(0xFF3661FE))),
),
),
)),
@ -138,14 +153,10 @@ class _StudentZgTableState extends State<StudentZgTable> {
headingRowHeight: 40.r,
dataRowHeight: 40.r,
border: TableBorder(
horizontalInside: BorderSide(
width: 1, color: Colors.white, style: BorderStyle.solid),
bottom: BorderSide(
width: 1, color: Colors.white, style: BorderStyle.solid),
verticalInside: BorderSide(
width: 1, color: Colors.white, style: BorderStyle.solid)),
headingRowColor: MaterialStateProperty.resolveWith((states) =>
widget.fixedCols! > 0 ? Colors.white : Colors.transparent),
horizontalInside: BorderSide(width: 1, color: Colors.white, style: BorderStyle.solid),
bottom: BorderSide(width: 1, color: Colors.white, style: BorderStyle.solid),
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)),
fixedColumnsColor: Color(0xFFE6E6E6),
fixedCornerColor: Colors.grey[400],
@ -159,14 +170,12 @@ class _StudentZgTableState extends State<StudentZgTable> {
var item = widget.headList[index];
return DataColumn2(
label: Center(
child: Text(item,
style: TextStyle(fontSize: 12.sp, color: Color(0xFF505767))),
child: Text(item, style: TextStyle(fontSize: 12.sp, color: Color(0xFF505767))),
),
// 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,
(index) => _getRow(index, Color(0xFFF5F5F5))));
rows: List<DataRow>.generate(widget.bodyList.length, (index) => _getRow(index, Color(0xFFF5F5F5))));
}
}

View File

@ -44,8 +44,10 @@ class _TheLoginState extends ConsumerState<TheLogin> with CommonMixin {
//
setHttpsPEM() async {
(dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate = (client) {
client.badCertificateCallback = (X509Certificate cert, String host, int port) {
(dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate =
(client) {
client.badCertificateCallback =
(X509Certificate cert, String host, int port) {
return true;
};
};
@ -59,10 +61,11 @@ class _TheLoginState extends ConsumerState<TheLogin> with CommonMixin {
late final FocusNode _theFocus;
bool keepPwd = false; //
bool readAgreement = true; //
bool readAgreement = false; //
bool canLogin = true;
bool hasNameVal = false;
bool _isShowPwd = true;
bool showRegister = false;
void _showPassword() {
setState(() {
@ -77,7 +80,7 @@ class _TheLoginState extends ConsumerState<TheLogin> with CommonMixin {
// Provider
ref.read(userTokenProvider.notifier).clean(); //
});
getShowRegister();
super.initState();
dio = Dio(
BaseOptions(
@ -86,12 +89,14 @@ class _TheLoginState extends ConsumerState<TheLogin> with CommonMixin {
receiveTimeout: 8000,
),
);
dio.interceptors.add(LogInterceptor(responseBody: true, requestBody: true)); //
dio.interceptors
.add(LogInterceptor(responseBody: true, requestBody: true)); //
setHttpsPEM();
client = RestClient(dio, baseUrl: RequestConfig().loginBaseUrl);
_userNameController = TextEditingController()..addListener(userNameListener);
_userNameController = TextEditingController()
..addListener(userNameListener);
_passwordController = TextEditingController();
_pwdFocus = FocusNode();
_theFocus = FocusNode();
@ -106,11 +111,23 @@ class _TheLoginState extends ConsumerState<TheLogin> with CommonMixin {
});
}
void getShowRegister() async {
RestClient client = await getClientLogin();
BaseStructureResult<dynamic> resultData = await client.showRegister();
if(resultData.success){
setState(() {
showRegister = resultData.data;
});
}
}
void userNameListener() {
String userName = _userNameController.text;
int useNameLength = userName.length;
bool hasNameValNew = useNameLength > 0;
if (hasNameValNew != hasNameVal) toUpState(setState, () => hasNameVal = hasNameValNew, mounted);
if (hasNameValNew != hasNameVal)
toUpState(setState, () => hasNameVal = hasNameValNew, mounted);
const isProd = bool.fromEnvironment('dart.vm.product');
if (!isProd && useNameLength == 11) {
_passwordController.text = userName.substring(useNameLength - 6);
@ -165,12 +182,15 @@ class _TheLoginState extends ConsumerState<TheLogin> with CommonMixin {
child: SizedBox(
height: 86.w,
width: 86.w,
child: Image.asset('assets/images/logo.png', fit: BoxFit.cover),
child: Image.asset('assets/images/logo.png',
fit: BoxFit.cover),
),
),
Container(
margin: EdgeInsets.symmetric(horizontal: 32.w, vertical: 24.h),
padding: EdgeInsets.only(top: 34.h, bottom: 16.h, left: 22.w, right: 22.w),
margin: EdgeInsets.symmetric(
horizontal: 32.w, vertical: 24.h),
padding: EdgeInsets.only(
top: 34.h, bottom: 16.h, left: 22.w, right: 22.w),
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(width: 1.w, color: Colors.white),
@ -199,13 +219,18 @@ class _TheLoginState extends ConsumerState<TheLogin> with CommonMixin {
),
decoration: InputDecoration(
hintText: "请输入账号",
hintStyle: TextStyle(fontSize: 16.sp, color: const Color.fromRGBO(153, 153, 153, 1)),
hintStyle: TextStyle(
fontSize: 16.sp,
color: const Color.fromRGBO(153, 153, 153, 1)),
labelText: "账号",
labelStyle: TextStyle(fontSize: 16.sp, color: const Color.fromRGBO(148, 163, 182, 1)),
labelStyle: TextStyle(
fontSize: 16.sp,
color: const Color.fromRGBO(148, 163, 182, 1)),
suffixIcon: !hasNameVal
? null
: Transform.translate(
offset: Offset(10, 10), // padding值来设置偏移量
offset:
Offset(10, 10), // padding值来设置偏移量
child: IconButton(
alignment: Alignment.center,
padding: EdgeInsets.zero,
@ -227,7 +252,8 @@ class _TheLoginState extends ConsumerState<TheLogin> with CommonMixin {
controller: _passwordController,
keyboardType: TextInputType.number,
maxLines: 1,
obscureText: _isShowPwd, //
obscureText: _isShowPwd,
//
textInputAction: TextInputAction.go,
onSubmitted: (val) => toLogin(),
style: TextStyle(
@ -240,13 +266,19 @@ class _TheLoginState extends ConsumerState<TheLogin> with CommonMixin {
onTap: _showPassword,
child: Icon(
Icons.remove_red_eye,
color: !_isShowPwd ? Theme.of(context).primaryColor : Colors.grey,
color: !_isShowPwd
? Theme.of(context).primaryColor
: Colors.grey,
),
),
hintStyle: TextStyle(fontSize: 16.sp, color: const Color.fromRGBO(153, 153, 153, 1)),
hintStyle: TextStyle(
fontSize: 16.sp,
color: const Color.fromRGBO(153, 153, 153, 1)),
labelText: "密码",
isDense: true,
labelStyle: TextStyle(fontSize: 16.sp, color: const Color.fromRGBO(148, 163, 182, 1)),
labelStyle: TextStyle(
fontSize: 16.sp,
color: const Color.fromRGBO(148, 163, 182, 1)),
),
),
SizedBox(
@ -262,8 +294,10 @@ class _TheLoginState extends ConsumerState<TheLogin> with CommonMixin {
checkColor: Colors.white,
value: keepPwd,
onChanged: (value) {
FocusScope.of(context).requestFocus(_pwdFocus);
FocusScope.of(context).requestFocus(_theFocus);
FocusScope.of(context)
.requestFocus(_pwdFocus);
FocusScope.of(context)
.requestFocus(_theFocus);
setState(() {
keepPwd = value ?? false;
});
@ -284,6 +318,20 @@ class _TheLoginState extends ConsumerState<TheLogin> with CommonMixin {
),
),
),
Spacer(),
if (showRegister == true)
InkWell(
onTap: () {
RouterManager.router.navigateTo(
context, RouterManager.registerPath);
},
child: Text(
'注册',
style: TextStyle(
fontSize: 14.sp,
color: const Color.fromRGBO(
148, 163, 182, 1)),
)),
],
),
InkWell(
@ -291,7 +339,9 @@ class _TheLoginState extends ConsumerState<TheLogin> with CommonMixin {
child: Container(
margin: EdgeInsets.symmetric(vertical: 10.h),
decoration: BoxDecoration(
color: canLogin ? const Color.fromRGBO(9, 105, 246, 1) : Colors.grey,
color: canLogin
? const Color.fromRGBO(9, 105, 246, 1)
: Colors.grey,
boxShadow: [
BoxShadow(
color: const Color.fromRGBO(46, 91, 255, 0.5),
@ -309,7 +359,8 @@ class _TheLoginState extends ConsumerState<TheLogin> with CommonMixin {
height: 50.h,
child: Text(
'登 录',
style: TextStyle(fontSize: 16.sp, color: Colors.white),
style: TextStyle(
fontSize: 16.sp, color: Colors.white),
),
),
),
@ -323,8 +374,10 @@ class _TheLoginState extends ConsumerState<TheLogin> with CommonMixin {
checkColor: Colors.white,
value: readAgreement,
onChanged: (value) {
FocusScope.of(context).requestFocus(_pwdFocus);
FocusScope.of(context).requestFocus(_theFocus);
FocusScope.of(context)
.requestFocus(_pwdFocus);
FocusScope.of(context)
.requestFocus(_theFocus);
setState(() {
readAgreement = value ?? false;
});
@ -339,7 +392,7 @@ class _TheLoginState extends ConsumerState<TheLogin> with CommonMixin {
transition: getTransition(),
);
},
child: quickText('请仔细阅读', size: 13.sp),
child: quickText('我已阅读', size: 11.sp),
),
InkWell(
onTap: () {
@ -349,9 +402,25 @@ class _TheLoginState extends ConsumerState<TheLogin> with CommonMixin {
transition: getTransition(),
);
},
child: const Text(
child: quickText(
'《用户协议》',
style: TextStyle(color: Colors.deepOrangeAccent),
size: 12.sp,
color: Colors.deepOrangeAccent,
),
),
quickText('', size: 10.sp),
InkWell(
onTap: () {
RouterManager.router.navigateTo(
context,
'${RouterManager.agreementPath}?type=${AGREEMENT_KEY.PRIVACY_GREEMENT.name}',
transition: getTransition(),
);
},
child: quickText(
'《隐私协议》',
size: 12.sp,
color: Colors.deepOrangeAccent,
),
),
],
@ -383,21 +452,29 @@ class _TheLoginState extends ConsumerState<TheLogin> with CommonMixin {
String userPwd = _passwordController.text.trim();
if (userName == '') return toMsg('请填写用户账号');
if (userPwd == '') return toMsg('请填写密码再试');
if (!readAgreement) return toMsg('阅读用户协议');
if (!readAgreement) return toMsg('勾选我已阅读用户协议和隐私协议');
String userPwdMd5 = CommonUtils.generateMD5(userPwd);
print('userPwdMd5=$userPwdMd5');
EasyLoading.show(status: 'loading...');
try {
BaseStructureResult<dynamic> resultData = await client.toLogin(UserLoginParams(userName, userPwdMd5));
UserLogin? userData = resultData.code == 200 && resultData.data != null ? UserLogin.fromJson(resultData.data) : null;
if (resultData.code != 200 || userData?.accessToken == null || userData?.accessToken == '') {
BaseStructureResult<dynamic> resultData =
await client.toLogin(UserLoginParams(userName, userPwdMd5));
UserLogin? userData = resultData.code == 200 && resultData.data != null
? UserLogin.fromJson(resultData.data)
: null;
if (resultData.code != 200 ||
userData?.accessToken == null ||
userData?.accessToken == '') {
return toMsg(resultData.message ?? '登录失败,请重试');
}
FastData fastData = FastData.getInstance();
fastData.setToken(userData!.accessToken);
BaseStructureResult<UserInfo> userRes = await client.getUserInfo('Bearer ${userData.accessToken}');
BaseStructureResult<UserInfo> userRes =
await client.getUserInfo('Bearer ${userData.accessToken}');
if (userRes.code != 200 || userRes.data == null) {
throw Exception('登录失败,请重试');
}
@ -412,7 +489,8 @@ class _TheLoginState extends ConsumerState<TheLogin> with CommonMixin {
ref.read(userTokenProvider.notifier).initToken();
//
RouterManager.router.navigateTo(context, RouterManager.root, clearStack: true, transition: getTransition());
RouterManager.router.navigateTo(context, RouterManager.root,
clearStack: true, transition: getTransition());
});
} catch (e) {
toPrint(val: e.toString());

View File

@ -86,6 +86,7 @@ class TheMainPageState extends ConsumerState<TheMainPage> with CommonMixin {
if (!value) {
return toLoginPage(context);
}
if (ref.read(userProvider).id == '540117143121989') return;
ref.read(userReportProvider.notifier).initUserReport(); //
}); // token
//
@ -105,7 +106,7 @@ class TheMainPageState extends ConsumerState<TheMainPage> with CommonMixin {
void getAppUpgrade(UserInfo user) async {
try {
showUpgrade = true;
if (user.loginName == '18888888888') return;
if (['18888888888'].contains(user.loginName)) return;
//
String deviceInfo;
int deviceType;

View File

@ -0,0 +1,198 @@
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:marking_app/common/mixin/common.dart';
import 'package:marking_app/common/model/common/base_structure_result.dart';
import 'package:marking_app/provider/user_provider.dart';
import 'package:marking_app/routes/RouterManager.dart';
import 'package:marking_app/utils/const_text.dart';
import 'package:marking_app/utils/index.dart';
import 'package:marking_app/utils/my_text.dart';
import 'package:marking_app/utils/request/rest_client.dart';
class LogOff extends StatefulHookConsumerWidget {
const LogOff({Key? key}) : super(key: key);
@override
ConsumerState<LogOff> createState() => _LogOffState();
}
class _LogOffState extends ConsumerState<LogOff> with CommonMixin{
bool canClick = true;
bool readAgreement = false; //
logOff() async{
if (!canClick) return;
setState(() => canClick = false);
void toMsg(msg) {
ToastUtils.showError(msg);
setState(() => canClick = true);
}
if (!readAgreement) return toMsg('请勾选我已阅读用户协议和隐私协议');
final userState = ref.watch(userProvider);
EasyLoading.show(status: 'loading...');
RestClient client = await getClientLogin();
BaseStructureResult<dynamic> resultData = await client.getLogOff(userState.loginName);
if (resultData.code != 200) {
return ToastUtils.showError(resultData.message ?? '注销失败,请重试');
}
EasyLoading.dismiss();
ToastUtils.showSuccess('注销成功');
//
RouterManager.router.navigateTo(context, RouterManager.loginPath);
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: const Color.fromRGBO(248, 248, 248, 1),
appBar: AppBar(
backgroundColor: Colors.white,
title: Text(
'注销',
style: TextStyle(fontSize: 14.sp, color: Color(0xFF333333)),
),
centerTitle: true,
leading: IconButton(
icon: Icon(Icons.arrow_back_ios, color: Colors.black),
onPressed: () => Navigator.of(context).pop(),
),
),
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
height: 30.r,
),
Center(
child: Text(
'温馨提示,请仔细阅读',
style: TextStyle(
fontSize: 16.sp,
color: Color(0xFF464646),
fontWeight: FontWeight.w500),
),
),
SizedBox(
height: 20.r,
),
cont('您仅可注销您本人申请的账号'),
cont('注销后,账号的全部权益将被清除'),
cont('注销后,账号下的所有数据、记录等将无法访问或找回'),
cont('注销后,将清除该账号在网站保留的个人信息'),
cont('注销账号(账号删除)属于用户自主行为'),
/* Padding(
padding: EdgeInsets.symmetric(vertical: 5.r, horizontal: 14.r),
child: Row(
children: [
Text(
'注销账号即表示您已确认并同意',
style: TextStyle(fontSize: 14.sp, color: Color(0xFF616161)),
),
InkWell(
onTap: (){
RouterManager.router.navigateTo(
context,
'${RouterManager.agreementPath}?type=${AGREEMENT_KEY.USER_LOGOUT.name}',
transition: getTransition(),
);
},
child: Text(
'注销协议',
style: TextStyle(fontSize: 14.sp, color: Color(0xFF6888FD)),
),
)
],
),
),*/
SizedBox(
height: 50.r,
),
InkWell(
onTap:logOff,
child: Center(
child: Container(
margin: EdgeInsets.symmetric(vertical: 10.h),
alignment: Alignment.center,
width: 200.r,
height: 50.r,
decoration: BoxDecoration(
color: canClick
? const Color.fromRGBO(9, 105, 246, 1)
: Colors.grey,
/*boxShadow: [
BoxShadow(
color: const Color.fromRGBO(46, 91, 255, 0.5),
offset: Offset(6.w, 10.h), //y轴偏移量
blurRadius: 14, //
spreadRadius: 0.5, //
)
],*/
borderRadius: BorderRadius.all(
Radius.circular(20.w),
),
),
child: Text(
'确认注销',
style: TextStyle(fontSize: 16.sp, color: Colors.white),
),
),
),
),
Padding(
padding: EdgeInsets.symmetric(vertical: 5.r, horizontal: 14.r),
child: Row(
children: [
Container(
width: 30.w,
padding: EdgeInsets.only(right: 10.w),
child: Checkbox(
activeColor: Colors.deepOrangeAccent,
checkColor: Colors.white,
value: readAgreement,
onChanged: (value) {
setState(() {
readAgreement = value ?? false;
});
},
),
),
Text(
'已确认并同意',
style: TextStyle(fontSize: 14.sp, color: Color(0xFF616161)),
),
InkWell(
onTap: () {
RouterManager.router.navigateTo(
context,
'${RouterManager.agreementPath}?type=${AGREEMENT_KEY.USER_LOGOUT.name}',
transition: getTransition(),
);
},
child: quickText(
'《注销协议》',
size: 12.sp,
color: Colors.deepOrangeAccent,
),
),
],
),
),
],
),
);
}
}
Widget cont(String name) {
return Padding(
padding: EdgeInsets.symmetric(vertical: 5.r, horizontal: 14.r),
child: Text(
name,
style: TextStyle(fontSize: 14.sp, color: Color(0xFF616161)),
),
);
}

View File

@ -1,11 +1,14 @@
import 'package:fluro/fluro.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:marking_app/common/mixin/common.dart';
import 'package:marking_app/common/model/common/base_structure_result.dart';
import 'package:marking_app/routes/RouterManager.dart';
import 'package:marking_app/utils/const_text.dart';
import 'package:marking_app/utils/fluro/index.dart';
import 'package:marking_app/utils/index.dart';
import 'package:marking_app/utils/my_text.dart';
import 'package:marking_app/utils/request/rest_client.dart';
import 'package:package_info/package_info.dart';
//
@ -16,12 +19,14 @@ class OhterPage extends StatefulWidget {
State<OhterPage> createState() => _OhterPageState();
}
class _OhterPageState extends State<OhterPage> {
class _OhterPageState extends State<OhterPage> with CommonMixin{
String localVersion = '';
bool showLogOff = false;
@override
void initState() {
super.initState();
getShowLogOff();
getPageInfo();
}
@ -31,6 +36,16 @@ class _OhterPageState extends State<OhterPage> {
toUpState(setState, () => localVersion = packageInfo.version, mounted);
}
getShowLogOff() async{
RestClient client = await getClientLogin();
BaseStructureResult<dynamic> resultData = await client.showLogOff();
if(resultData.success){
setState(() {
showLogOff = resultData.data;
});
}
}
@override
Widget build(BuildContext context) {
final personalInfoTitleStly = TextStyle(
@ -56,7 +71,7 @@ class _OhterPageState extends State<OhterPage> {
Container(
margin: EdgeInsets.symmetric(vertical: 22.h, horizontal: 16.w),
padding: EdgeInsets.symmetric(vertical: 22.h, horizontal: 16.w),
height: 130.h,
height: showLogOff?250.h:200.h,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(6.w)),
color: Colors.white,
@ -85,7 +100,7 @@ class _OhterPageState extends State<OhterPage> {
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('用户隐私协议', style: personalInfoTitleStly),
Text('隐私政策', style: personalInfoTitleStly),
Icon(
Icons.arrow_forward_ios,
color: const Color.fromRGBO(80, 87, 103, 1),
@ -99,14 +114,70 @@ class _OhterPageState extends State<OhterPage> {
height: 1.w,
color: const Color.fromRGBO(240, 243, 255, 1),
),
SizedBox(height: 8.h),
InkWell(
onTap: () {
RouterManager.router.navigateTo(
context,
transition: TransitionType.fadeIn,
'${RouterManager.agreementPath}?type=${AGREEMENT_KEY.USER_AGREEMENT.name}',
);
},
child: Container(
padding: EdgeInsets.only(bottom: 4.h),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('用户协议', style: personalInfoTitleStly),
Icon(
Icons.arrow_forward_ios,
color: const Color.fromRGBO(80, 87, 103, 1),
size: 16.sp,
)
],
),
),
),
Container(
height: 1.w,
color: const Color.fromRGBO(240, 243, 255, 1),
),
// SizedBox(height: 8.h),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [Text('APP版本', style: personalInfoTitleStly), quickText(localVersion)],
),
Container(
height: 1.w,
color: const Color.fromRGBO(240, 243, 255, 1),
),
// SizedBox(height: 8.h),
if(showLogOff)
InkWell(
onTap: () {
RouterManager.router.navigateTo(
context,
RouterManager.logOffPath
);
},
child: Container(
padding: EdgeInsets.only(bottom: 4.h,top: 8.r),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('注销账号', style: personalInfoTitleStly),
Icon(
Icons.arrow_forward_ios,
color: const Color.fromRGBO(80, 87, 103, 1),
size: 16.sp,
)
],
),
),
),
],
),
),
// InkWell(
// onTap: () {
// RouterManager.router.navigateTo(

View File

@ -0,0 +1,293 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:marking_app/common/config/request_config.dart';
import 'package:marking_app/common/mixin/common.dart';
import 'package:marking_app/common/model/common/base_structure_result.dart';
import 'package:marking_app/common/model/user/user_login_params.dart';
import 'package:marking_app/routes/RouterManager.dart';
import 'package:marking_app/utils/common_utils.dart';
import 'package:marking_app/utils/const_text.dart';
import 'package:marking_app/utils/index.dart';
import 'package:marking_app/utils/my_text.dart';
import 'package:marking_app/utils/request/rest_client.dart';
class Register extends StatefulWidget {
const Register({Key? key}) : super(key: key);
@override
State<Register> createState() => _RegisterState();
}
class _RegisterState extends State<Register> with CommonMixin{
late final FocusNode _theFocus;
late final FocusNode _pwdFocus; //
//
late final TextEditingController _userNameController;
late final TextEditingController _passwordController;
bool readAgreement = false; //
bool _isShowPwd = true;
bool canLogin = true;
@override
void initState(){
super.initState();
_userNameController = TextEditingController();
_passwordController = TextEditingController();
_pwdFocus = FocusNode();
_theFocus = FocusNode();
}
@override
void dispose() {
super.dispose();
_userNameController.dispose();
_passwordController.dispose();
_pwdFocus.dispose();
_theFocus.dispose();
}
void toRegister() async{
if (!canLogin) return;
setState(() => canLogin = false);
void toMsg(msg) {
ToastUtils.showError(msg);
setState(() => canLogin = true);
}
FocusScope.of(context).requestFocus(_theFocus);
String userName = _userNameController.text.trim();
String userPwd = _passwordController.text.trim();
if (userName == '') return toMsg('请填写用户账号');
if (userPwd == '') return toMsg('请填写密码');
if (!readAgreement) return toMsg('请勾选我已阅读用户协议和隐私协议');
String userPwdMd5 = CommonUtils.generateMD5(userPwd);
print('注册userPwdMd5=$userPwdMd5');
EasyLoading.show(status: 'loading...');
RestClient client = await getClientLogin();
BaseStructureResult<dynamic> resultData = await client.toRegister(UserLoginParams(userName, userPwdMd5));
if (resultData.code != 200) {
return toMsg(resultData.message ?? '注册失败,请重试');
}
EasyLoading.dismiss();
ToastUtils.showSuccess('注册成功,请登录');
//
RouterManager.router.navigateTo(context, RouterManager.loginPath);
}
void _showPassword() {
setState(() {
_isShowPwd = !_isShowPwd;
});
}
@override
Widget build(BuildContext context) {
return GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () {
FocusScope.of(context).requestFocus(_theFocus);
},
child: AnnotatedRegion(
value: const SystemUiOverlayStyle(
statusBarColor: Colors.transparent,
systemNavigationBarIconBrightness: Brightness.light,
statusBarIconBrightness: Brightness.light,
statusBarBrightness: Brightness.dark,
),
child: Scaffold(
backgroundColor: Colors.transparent,
resizeToAvoidBottomInset: false,
body: Stack(
children: [
Container(
width: double.infinity,
height: double.infinity,
alignment: Alignment.center,
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/login_bgi.png'),
fit: BoxFit.fill, //
),
),
child: SingleChildScrollView(
child: Column(
children: [
Container(
width: 86.w,
height: 86.w,
alignment: Alignment.center,
child: SizedBox(
height: 86.w,
width: 86.w,
child: Image.asset('assets/images/logo.png', fit: BoxFit.cover),
),
),
Container(
margin: EdgeInsets.symmetric(horizontal: 32.w, vertical: 24.h),
padding: EdgeInsets.only(top: 34.h, bottom: 16.h, left: 22.w, right: 22.w),
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(width: 1.w, color: Colors.white),
borderRadius: BorderRadius.all(Radius.circular(10.w)),
boxShadow: const [
BoxShadow(
color: Color.fromRGBO(46, 91, 255, 0.1),
offset: Offset.zero, //y轴偏移量
blurRadius: 100, //
spreadRadius: 100, //
)
],
),
child: Column(children: [
TextField(
controller: _userNameController,
maxLines: 1,
maxLength: 20,
textInputAction: TextInputAction.next,
onEditingComplete: () {
FocusScope.of(context).requestFocus(_pwdFocus);
},
style: TextStyle(
color: const Color.fromRGBO(80, 87, 103, 1),
fontSize: 15.sp,
),
decoration: InputDecoration(
hintText: "请输入账号",
hintStyle: TextStyle(fontSize: 16.sp, color: const Color.fromRGBO(153, 153, 153, 1)),
labelText: "账号",
labelStyle: TextStyle(fontSize: 16.sp, color: const Color.fromRGBO(148, 163, 182, 1)),
),
),
TextField(
focusNode: _pwdFocus,
controller: _passwordController,
keyboardType: TextInputType.number,
maxLines: 1,
obscureText: _isShowPwd, //
textInputAction: TextInputAction.go,
onSubmitted: (val) => toRegister(),
style: TextStyle(
color: const Color.fromRGBO(80, 87, 103, 1),
fontSize: 15.sp,
),
decoration: InputDecoration(
hintText: "请输入密码",
suffix: GestureDetector(
onTap: _showPassword,
child: Icon(
Icons.remove_red_eye,
color: !_isShowPwd ? Theme.of(context).primaryColor : Colors.grey,
),
),
hintStyle: TextStyle(fontSize: 16.sp, color: const Color.fromRGBO(153, 153, 153, 1)),
labelText: "密码",
isDense: true,
labelStyle: TextStyle(fontSize: 16.sp, color: const Color.fromRGBO(148, 163, 182, 1)),
),
),
SizedBox(
height: 12.h,
),
InkWell(
onTap: toRegister,
child: Container(
margin: EdgeInsets.symmetric(vertical: 10.h),
decoration: BoxDecoration(
color: canLogin ? const Color.fromRGBO(9, 105, 246, 1) : Colors.grey,
boxShadow: [
BoxShadow(
color: const Color.fromRGBO(46, 91, 255, 0.5),
offset: Offset(6.w, 10.h), //y轴偏移量
blurRadius: 14, //
spreadRadius: 0.5, //
)
],
borderRadius: BorderRadius.all(
Radius.circular(8.w),
),
),
alignment: Alignment.center,
width: double.infinity,
height: 50.h,
child: Text(
'注 册',
style: TextStyle(fontSize: 16.sp, color: Colors.white),
),
),
),
Row(
children: [
Container(
width: 30.w,
padding: EdgeInsets.only(right: 10.w),
child: Checkbox(
activeColor: Colors.deepOrangeAccent,
checkColor: Colors.white,
value: readAgreement,
onChanged: (value) {
FocusScope.of(context)
.requestFocus(_pwdFocus);
FocusScope.of(context)
.requestFocus(_theFocus);
setState(() {
readAgreement = value ?? false;
});
},
),
),
InkWell(
onTap: () {
RouterManager.router.navigateTo(
context,
'${RouterManager.agreementPath}?type=${AGREEMENT_KEY.USER_AGREEMENT.name}',
transition: getTransition(),
);
},
child: quickText('我已阅读', size: 11.sp),
),
InkWell(
onTap: () {
RouterManager.router.navigateTo(
context,
'${RouterManager.agreementPath}?type=${AGREEMENT_KEY.USER_AGREEMENT.name}',
transition: getTransition(),
);
},
child: quickText(
'《用户协议》',
size: 12.sp,
color: Colors.deepOrangeAccent,
),
),
],
),
]),
)
],
),
)),
Positioned(
top: MediaQuery.of(context).padding.top+20.r,
left: 20.r,
child: InkWell(
onTap: () => Navigator.pop(context),
child: Icon(Icons.arrow_back_ios_new_rounded,
color: Colors.white, size: 24.sp),
),
),
],
),
),
),
);
}
}

View File

@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_easyrefresh/easy_refresh.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:functional_widget_annotation/functional_widget_annotation.dart';
import 'package:marking_app/common/mixin/common.dart';
@ -13,24 +14,22 @@ import 'package:marking_app/utils/easy_refresh/MyEmptyWidget.dart';
import 'package:marking_app/utils/index.dart';
import 'package:marking_app/utils/request/rest_client_report.dart';
import 'package:syncfusion_flutter_datepicker/datepicker.dart';
part 'report_history.g.dart';
class ReportHistory extends StatefulWidget {
final int userId;
final int classId;
final String studentName;
const ReportHistory({Key? key, required this.classId, required this.userId,required this.studentName})
: super(key: key);
const ReportHistory({Key? key, required this.classId, required this.userId, required this.studentName}) : super(key: key);
@override
State<ReportHistory> createState() => _ReportHistoryState();
}
class _ReportHistoryState extends State<ReportHistory>
with CommonMixin, TickerProviderStateMixin {
class _ReportHistoryState extends State<ReportHistory> with CommonMixin, TickerProviderStateMixin {
bool isWork = true;
String startDataTime =
CommonUtils.getWeekStartDate().toString().substring(0, 10);
String startDataTime = CommonUtils.getWeekStartDate().toString().substring(0, 10);
String endDataTime = CommonUtils.getWeekEndDate().toString().substring(0, 10);
String customTimeStr = '自定义';
late TabController tabController;
@ -48,8 +47,7 @@ class _ReportHistoryState extends State<ReportHistory>
}
void getList() async {
if (startDataTime == DateTime.now().toString().substring(0, 10) ||
DateTime.parse(startDataTime).isAfter(DateTime.now())) {
if (startDataTime == DateTime.now().toString().substring(0, 10) || DateTime.parse(startDataTime).isAfter(DateTime.now())) {
DateTime now = DateTime.parse(startDataTime);
endDataTime = now.add(Duration(days: 1)).toString().substring(0, 10);
print(now.add(Duration(days: 1)));
@ -59,8 +57,7 @@ class _ReportHistoryState extends State<ReportHistory>
RestClientReport clientReport = await getClientReport();
BaseStructureResultReport<List<ReportStudentHistoryRecord>> res =
// 488491659239519, 488491659190341, '2023-03-08', '2024-04-19'
await clientReport.getStudentHistroyRecords(
widget.userId, widget.classId, startDataTime, endDataTime);
await clientReport.getStudentHistroyRecords(widget.userId, widget.classId, startDataTime, endDataTime);
if (res.success) {
setState(() {
dataList = res.data!;
@ -162,21 +159,16 @@ class _ReportHistoryState extends State<ReportHistory>
SizedBox(
height: 10.r,
),
jobConditionFilter(context,
JobConditionFilter(
controller: tabController,
customTimeStr: customTimeStr,
customTime: tabController.index != 3 ||
((endDataTime == null || endDataTime == '') &&
(startDataTime == null || startDataTime == ''))
customTime: tabController.index != 3 || ((endDataTime == null || endDataTime == '') && (startDataTime == null || startDataTime == ''))
? null
: PickerDateRange(
startDataTime == null || startDataTime == ''
? null
: DateTime.parse(startDataTime!),
endDataTime == null || endDataTime == ''
? null
: DateTime.parse(endDataTime!),
), onTimeFilter: (String? startTime, String? endTime) {
startDataTime == null || startDataTime == '' ? null : DateTime.parse(startDataTime!),
endDataTime == null || endDataTime == '' ? null : DateTime.parse(endDataTime!),
),
onTimeFilter: (String? startTime, String? endTime) {
if (startTime == null && endTime == null) {
if (tabController.index == 3) {
tabController.animateTo(0);
@ -193,19 +185,17 @@ class _ReportHistoryState extends State<ReportHistory>
}
// _refreshController2.callRefresh();
}, refreshTime: (value) {
},
refreshTime: (value) {
if (value != null && value.startDate != null) {
customTimeStr =
value.startDate?.toString().substring(0, 10) ?? '';
customTimeStr = value.startDate?.toString().substring(0, 10) ?? '';
setState(() {});
if (value.endDate != null) {
if (value.startDate!.year == value.endDate!.year) {
customTimeStr = value.startDate.toString().substring(5, 10) +
'~${value.endDate.toString().substring(5, 10)}';
customTimeStr = value.startDate.toString().substring(5, 10) + '~${value.endDate.toString().substring(5, 10)}';
setState(() {});
} else {
customTimeStr =
'$customTimeStr~${value.endDate?.toString().substring(0, 10)}';
customTimeStr = '$customTimeStr~${value.endDate?.toString().substring(0, 10)}';
setState(() {});
}
}
@ -229,8 +219,9 @@ class _ReportHistoryState extends State<ReportHistory>
itemBuilder: (context, index) {
ReportStudentHistoryRecord item = dataList[index];
return InkWell(
onTap: (){
RouterManager.router.navigateTo(context, '${RouterManager.completedReportPath}?examId=${item.examId}&studentNo=${item.studentExamNum}');
onTap: () {
RouterManager.router
.navigateTo(context, '${RouterManager.completedReportPath}?examId=${item.examId}&studentNo=${item.studentExamNum}');
},
child: Container(
// padding: EdgeInsets.all(6.r),
@ -238,13 +229,10 @@ class _ReportHistoryState extends State<ReportHistory>
width: double.infinity,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage(
'assets/images/report_student_history_bg.png'),
image: AssetImage('assets/images/report_student_history_bg.png'),
fit: BoxFit.fill,
),
border: Border.all(
width: 1.r,
color: Color.fromRGBO(46, 91, 255, 0.2)),
border: Border.all(width: 1.r, color: Color.fromRGBO(46, 91, 255, 0.2)),
borderRadius: BorderRadius.circular(5.r),
),
child: Column(
@ -257,21 +245,16 @@ class _ReportHistoryState extends State<ReportHistory>
),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
item.examName,
style: TextStyle(
fontSize: 12.sp,
color: Color(0xFF000000)),
style: TextStyle(fontSize: 12.sp, color: Color(0xFF000000)),
),
Spacer(),
Text(
item.examStartTime,
style: TextStyle(
fontSize: 12.sp,
color: Color(0xFF4A4A4A)),
style: TextStyle(fontSize: 12.sp, color: Color(0xFF4A4A4A)),
)
],
),
@ -280,8 +263,7 @@ class _ReportHistoryState extends State<ReportHistory>
height: 2.r,
),
Container(
padding:
EdgeInsets.symmetric(horizontal: 10.r),
padding: EdgeInsets.symmetric(horizontal: 10.r),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5.r),
),
@ -291,118 +273,54 @@ class _ReportHistoryState extends State<ReportHistory>
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: List.generate(
item.scoreInfo.length, (i) {
ScoreInfo score =
item.scoreInfo[i];
children: List.generate(item.scoreInfo.length, (i) {
ScoreInfo score = item.scoreInfo[i];
return Row(
children: [
Column(
children: [
Container(
height: 22.r,
width: item.scoreInfo
.length >
4
width: item.scoreInfo.length > 4
? 90.r
: (MediaQuery.of(
context)
.size
.width -
48.r -
(item.scoreInfo
.length - 1) *
1.5
.r) /
item.scoreInfo
.length,
decoration:
BoxDecoration(
: (MediaQuery.of(context).size.width - 48.r - (item.scoreInfo.length - 1) * 1.5.r) /
item.scoreInfo.length,
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: i == 0
? Radius
.circular(
4.r)
: Radius
.zero,
topRight: i ==
item.scoreInfo.length -
1
? Radius
.circular(
4.r)
: Radius
.zero),
color: Color(
0xFFECECEC),
topLeft: i == 0 ? Radius.circular(4.r) : Radius.zero,
topRight: i == item.scoreInfo.length - 1 ? Radius.circular(4.r) : Radius.zero),
color: Color(0xFFECECEC),
),
child: Center(
child: Text(
score.text,
style: TextStyle(
fontSize:
12.sp,
color: Color(
0xFF8A8A8A)),
style: TextStyle(fontSize: 12.sp, color: Color(0xFF8A8A8A)),
),
),
),
Container(
height: 30.r,
width: item.scoreInfo
.length >
4
width: item.scoreInfo.length > 4
? 90.r
: (MediaQuery.of(
context)
.size
.width -
48.r -
(item.scoreInfo
.length - 1) *
1.5.r) /
item.scoreInfo
.length,
decoration:
BoxDecoration(
: (MediaQuery.of(context).size.width - 48.r - (item.scoreInfo.length - 1) * 1.5.r) /
item.scoreInfo.length,
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
bottomLeft: i ==
0
? Radius
.circular(
4.r)
: Radius
.zero,
bottomRight: i ==
item.scoreInfo.length -
1
? Radius
.circular(
4.r)
: Radius
.zero),
bottomLeft: i == 0 ? Radius.circular(4.r) : Radius.zero,
bottomRight: i == item.scoreInfo.length - 1 ? Radius.circular(4.r) : Radius.zero),
color: Colors.white,
),
child: Center(
child: Text(
score.value
.toString(),
style: TextStyle(
fontSize:
12.sp,
color: Color(
0xFF4A4A4A)),
score.value.toString(),
style: TextStyle(fontSize: 12.sp, color: Color(0xFF4A4A4A)),
),
),
),
],
),
SizedBox(
width: i <
item.scoreInfo
.length - 1
? 1.5.r
: 0.r,
width: i < item.scoreInfo.length - 1 ? 1.5.r : 0.r,
),
],
);
@ -413,9 +331,7 @@ class _ReportHistoryState extends State<ReportHistory>
: Center(
child: Text(
'-暂无数据-',
style: TextStyle(
fontSize: 12.sp,
color: Color(0xFF8A8A8A)),
style: TextStyle(fontSize: 12.sp, color: Color(0xFF8A8A8A)),
)),
),
SizedBox(
@ -445,9 +361,8 @@ Widget jobConditionFilter(BuildContext context,
required Function(String? startTime, String? endTime) onTimeFilter}) {
var customTimeState = PickerDateRange(null, null);
if (customTime != null) {
customTimeState = PickerDateRange(
customTime!.startDate != null ? customTime!.startDate : null,
customTime!.endDate != null ? customTime!.endDate : null);
customTimeState =
PickerDateRange(customTime!.startDate != null ? customTime!.startDate : null, customTime!.endDate != null ? customTime!.endDate : null);
}
DateTime getMonthStartDate() {
@ -462,9 +377,7 @@ Widget jobConditionFilter(BuildContext context,
nextMonth = 1;
now = now.add(Duration(days: 31 - now.day)); //
} else {
now = now.add(Duration(
days: DateTime(now.year, nextMonth, 0).day -
now.day)); //
now = now.add(Duration(days: DateTime(now.year, nextMonth, 0).day - now.day)); //
}
return now;
}
@ -476,13 +389,10 @@ Widget jobConditionFilter(BuildContext context,
),
child: Container(
alignment: Alignment.centerLeft,
decoration: BoxDecoration(
border:
Border(bottom: BorderSide(width: 1.r, color: Color(0xFFCCCCCC)))),
decoration: BoxDecoration(border: Border(bottom: BorderSide(width: 1.r, color: Color(0xFFCCCCCC)))),
child: TabBar(
controller: controller,
unselectedLabelStyle: TextStyle(
fontSize: 12.sp, color: const Color.fromRGBO(102, 102, 102, 1)),
unselectedLabelStyle: TextStyle(fontSize: 12.sp, color: const Color.fromRGBO(102, 102, 102, 1)),
labelStyle: TextStyle(
fontSize: 12.sp,
fontWeight: FontWeight.bold,
@ -514,9 +424,7 @@ Widget jobConditionFilter(BuildContext context,
return Center(
child: Container(
color: Colors.white,
width: isPad()
? ScreenUtil().screenWidth / 2
: ScreenUtil().screenWidth / 1.3,
width: isPad() ? ScreenUtil().screenWidth / 2 : ScreenUtil().screenWidth / 1.3,
height: ScreenUtil().screenHeight / 2,
child: SfDateRangePicker(
showActionButtons: true,

View File

@ -181,6 +181,7 @@ class _TheReportState extends ConsumerState<TheReport>
RestClientReport clientReport = await getClientReport();
UserInfoReport _userReport = ref.read(userReportProvider);
if (!_userReport.normal) {
if(ref.read(userProvider).id == '540117143121989') return null;
// 使
bool theFlag =
await ref.read(userReportProvider.notifier).initUserReport();

View File

@ -6,9 +6,6 @@
* @FilePath: \marking_app\lib\routes\RouterManager.dart
* @Description:
*/
import 'dart:convert';
import 'package:fluro/fluro.dart';
import 'package:flutter/material.dart';
import 'package:marking_app/common/model/enum/marking_list_type.dart';
@ -36,9 +33,9 @@ import 'package:marking_app/pages/marking/progress.dart';
import 'package:marking_app/pages/marking/progress_abnormal.dart';
import 'package:marking_app/pages/marking/review.dart';
import 'package:marking_app/pages/mine/index.dart';
import 'package:marking_app/pages/mine/log_off.dart';
import 'package:marking_app/pages/mine/other_pages/index.dart';
import 'package:marking_app/pages/other/agreement_page.dart';
import 'package:marking_app/pages/report_detail/completed_report.dart';
import 'package:marking_app/pages/report_detail/index.dart';
import 'package:marking_app/pages/report_detail/report_history.dart';
import 'package:marking_app/pages/reports/report_class_teacher.dart';
@ -46,7 +43,8 @@ import 'package:marking_app/pages/reports/report_personal_subject.dart';
import 'package:marking_app/pages/reports/report_subject_teacher.dart';
import 'package:marking_app/utils/const_text.dart';
import 'package:marking_app/utils/the_global.dart';
import 'package:marking_app/pages/register/index.dart';
import 'package:marking_app/pages/report_detail/completed_report.dart';
import '../utils/index.dart';
class RouterManager {
@ -85,6 +83,8 @@ class RouterManager {
static const String jobPersonalDetailPath = '/homework_correction/job_personal_detail';
static const String reportCardDialogPath = '/report_detail/widgets/report_card_dialog';
static const String reportHistoryPath = '/report_detail/report_history';
static const String registerPath = '/register/index';
static const String logOffPath = '/mine/log_off';
static const String jobKnowledgePointsPath = '/homework_correction/job_knowledge_points';
static const String jobKnowledgePointsDetailPath = '/homework_correction/job_knowledge_points_detail';
static const String answerTrajectoryPath = '/homework_correction/answer_trajectory';
@ -384,6 +384,12 @@ class RouterManager {
},
);
//
static final _registerPathHandler = Handler(handlerFunc: (BuildContext? context, Map<String, List<String>> params) => const Register());
//
static final _logOffPathHandler = Handler(handlerFunc: (BuildContext? context, Map<String, List<String>> params) => const LogOff());
//
static final _jobKnowledgePointsPathHandler = Handler(
handlerFunc: (BuildContext? context, Map<String, List<String>> params) {
@ -474,6 +480,8 @@ class RouterManager {
router.define(jobPersonalDetailPath, handler: _jobPersonalDetailPathHandler, transitionType: TransitionType.material);
router.define(reportCardDialogPath, handler: _reportCardDialogPathHandler, transitionType: TransitionType.material);
router.define(reportHistoryPath, handler: _reportHistoryPathHandler, transitionType: TransitionType.material);
router.define(registerPath, handler: _registerPathHandler, transitionType: TransitionType.material);
router.define(logOffPath, handler: _logOffPathHandler, transitionType: TransitionType.material);
router.define(jobMainListPagePath, handler: _jobMainListPathHandler, transitionType: TransitionType.material);
router.define(jobKnowledgePointsPath, handler: _jobKnowledgePointsPathHandler, transitionType: TransitionType.material);
router.define(jobKnowledgePointsDetailPath, handler: _jobKnowledgePointsDetailPathHandler, transitionType: TransitionType.material);

View File

@ -1,18 +1,18 @@
/*协议*/
// ignore_for_file: constant_identifier_names
// ignore: camel_case_types
enum AGREEMENT_KEY { PRIVACY_GREEMENT, USER_AGREEMENT }
enum AGREEMENT_KEY { PRIVACY_GREEMENT, USER_AGREEMENT, USER_LOGOUT }
// ignore: non_constant_identifier_names
final Map<AGREEMENT_KEY, AgreementClass> AGREEMENT_MAP = {
AGREEMENT_KEY.PRIVACY_GREEMENT: AgreementClass(
title: '隐私协议',
title: '隐私政策',
richText: '''<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Document</title>
<title></title>
</head>
<body>
<h1></h1>
@ -33,7 +33,7 @@ final Map<AGREEMENT_KEY, AgreementClass> AGREEMENT_MAP = {
<ul>
<li><strong></strong>使<ul><li>使GPS或WiFi等方式收集的您的地理位置信息</li><li></li></ul></li>
<li><strong></strong>使</li>
<li><strong></strong>使cookies<strong></strong><strong></strong><strong></strong>cookie使</li>
<li><strong></strong>使cookies<strong></strong><strong></strong><strong></strong>cookie使</li>
</ul>
@ -70,7 +70,6 @@ final Map<AGREEMENT_KEY, AgreementClass> AGREEMENT_MAP = {
<li></li>
<li></li>
<li></li>
<li>使使</li>
<li>广广</li>
<li>广广</li>
<li></li>
@ -107,9 +106,54 @@ final Map<AGREEMENT_KEY, AgreementClass> AGREEMENT_MAP = {
<h2>6. </h2>
<p>
使便使
</p>
<p>使</p>
<p><strong>访</strong></p >
<p>访</p >
<p>1访</p >
<p>2使</p >
<p>3访</p >
<p><strong></strong></p >
<p></p >
<p><strong></strong></p >
<p></p >
<p><strong></strong></p >
<p></p >
<p>使</p >
<p><strong></strong></p >
<p>使线使</p >
<p><strong></strong></p >
<p></p >
<p>1</p >
<p>2</p >
<p>3</p >
<p>4</p >
<p>5</p >
<p>6</p >
<p>7</p >
<p>8</p >
<h2>7. </h2>
<p>
@ -130,9 +174,12 @@ final Map<AGREEMENT_KEY, AgreementClass> AGREEMENT_MAP = {
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Document</title>
<title></title>
</head>
<body>
<h1></h1>
<div><strong>2023/1/1</strong></div>
<div><strong>2023/1/1</strong></div>
<h1></h1>
<p><i></i><i></i></p>
<h4></h4>
@ -146,12 +193,103 @@ final Map<AGREEMENT_KEY, AgreementClass> AGREEMENT_MAP = {
<p>4.2 </p>
</body>
</html>''',
)
),
AGREEMENT_KEY.USER_LOGOUT: AgreementClass(
title: '注销协议',
richText: '''<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title></title>
</head>
<body>
<p>
</p>
<p>
</p>
<p>
使
</p>
<h4></h4>
<p>
1.使使
</p>
<p>
2.使使线
</p>
<p>
3./
</p>
<p>
4.使
</p>
<p>
5.使
</p>
<p>
6.使使
</p>
<p>
7.
</p>
<h4>/ </h4>
<p>
1.使
</p>
<p>
2.
</p>
<p>
3.使
</p>
<p>
4.4使
</p>
<p>
5.
</p>
<p>
6.
</p>
<p>
7.
</p>
<p>
</p>
<h4></h4>
<p>
1.
</p> <p>
2.
</p>
<p>
3.2使使使
</p>
<p>
4.3
</p>
<p>
</p>
<h4></h4>
<p>
使
</p>
</body>
</html>''',
),
};
/* TYPE */
class AgreementClass {
String title;
String richText;
AgreementClass({required this.title, required this.richText});
}

View File

@ -0,0 +1,65 @@
import 'package:json_annotation/json_annotation.dart';
part 'my_time_util.g.dart';
//
TimeUnitModel? convertMilliseconds(int milliseconds) {
try {
int hours = milliseconds ~/ (1000 * 60 * 60);
int minutes = (milliseconds % (1000 * 60 * 60)) ~/ (1000 * 60);
int seconds = (milliseconds % (1000 * 60)) ~/ 1000;
if ((milliseconds % 1000) > 500) seconds += 1;
return TimeUnitModel(hours, minutes, seconds);
} catch (e) {
print('时间转换报错');
}
return null;
}
//
TimeUnitModel? convertSeconds(int totalSeconds) {
try {
int hours = totalSeconds ~/ 3600; // 3600
int remainingSeconds = totalSeconds % 3600; // 3600
int minutes = remainingSeconds ~/ 60; // 60
int seconds = remainingSeconds % 60; // 60
return TimeUnitModel(hours, minutes, seconds);
} catch (e) {
print('时间转换报错');
}
return null;
}
@JsonSerializable()
class TimeUnitModel extends Object {
int hours;
int minutes;
int seconds;
TimeUnitModel(this.hours, this.minutes, this.seconds);
factory TimeUnitModel.fromJson(Map<String, dynamic> srcJson) => _$TimeUnitModelFromJson(srcJson);
Map<String, dynamic> toJson() => _$TimeUnitModelToJson(this);
@override
String toString() {
var timeStr = '';
if (hours > 0) {
timeStr += '${hours > 9 ? hours : '0' + hours.toString()} ';
}
if (minutes > 0) {
timeStr += '${minutes > 9 ? minutes : '0' + minutes.toString()}';
}
if (timeStr.length > 0) {
timeStr += ':${seconds > 9 ? seconds : '0' + seconds.toString()}';
} else {
timeStr += '00:${seconds > 9 ? seconds : '0' + seconds.toString()}';
}
return timeStr;
}
}

View File

@ -373,4 +373,20 @@ abstract class RestClient {
@the_retrofit.Query("questionNo") int? questionNo,
@the_retrofit.Query("pageNum") int? pageNum,
);
//
@the_retrofit.POST("/auth/login/reg")
Future<BaseStructureResult<dynamic>> toRegister(@the_retrofit.Body() UserLoginParams params);
//
@the_retrofit.GET("/auth/login/status/reg")
Future<BaseStructureResult<dynamic>> showRegister();
//
@the_retrofit.GET("/auth/login/status/lg")
Future<BaseStructureResult<dynamic>> showLogOff();
//
@the_retrofit.POST("/auth/login/lg")
Future<BaseStructureResult> getLogOff(@the_retrofit.Field("loginName") String loginName);
}

View File

@ -15,7 +15,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 1.0.104
version: 1.0.105
environment:
sdk: ">=2.17.1 <3.0.0"