收藏夹

This commit is contained in:
machuanyu 2024-03-13 15:00:33 +08:00
parent 001ac3a21b
commit c653b10515
13 changed files with 496 additions and 47 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -52,10 +52,10 @@ class JobDataReport extends Object {
class StudentDetails extends Object {
@JsonKey(name: 'studentId')
int studentId;
int? studentId;
@JsonKey(name: 'studentName')
String studentName;
String? studentName;
@JsonKey(name: 'kgValidCount')
int kgValidCount;

View File

@ -0,0 +1,95 @@
import 'package:json_annotation/json_annotation.dart';
part 'job_fav_student.g.dart';
@JsonSerializable()
class JobFavStudent extends Object {
@JsonKey(name: 'page')
int page;
@JsonKey(name: 'pageSize')
int pageSize;
@JsonKey(name: 'total')
int total;
@JsonKey(name: 'totalPages')
int totalPages;
@JsonKey(name: 'items')
List<Items> items;
@JsonKey(name: 'hasPrevPage')
bool hasPrevPage;
@JsonKey(name: 'hasNextPage')
bool hasNextPage;
JobFavStudent(this.page,this.pageSize,this.total,this.totalPages,this.items,this.hasPrevPage,this.hasNextPage,);
factory JobFavStudent.fromJson(Map<String, dynamic> srcJson) => _$JobFavStudentFromJson(srcJson);
Map<String, dynamic> toJson() => _$JobFavStudentToJson(this);
}
@JsonSerializable()
class Items extends Object {
@JsonKey(name: 'id')
String id;
@JsonKey(name: 'teacherId')
int teacherId;
@JsonKey(name: 'teacherAccount')
String teacherAccount;
@JsonKey(name: 'folderName')
String folderName;
@JsonKey(name: 'jobId')
int jobId;
@JsonKey(name: 'jobName')
String jobName;
@JsonKey(name: 'studentId')
int studentId;
@JsonKey(name: 'studentName')
String studentName;
@JsonKey(name: 'className')
String className;
@JsonKey(name: 'questionPage')
int questionPage;
@JsonKey(name: 'questionPicture')
String questionPicture;
@JsonKey(name: 'createTime')
String createTime;
@JsonKey(name: 'schoolName')
String schoolName;
@JsonKey(name: 'gradeName')
String gradeName;
@JsonKey(name: 'studentClassName')
String studentClassName;
Items(this.id,this.teacherId,this.teacherAccount,this.folderName,this.jobId,this.jobName,this.studentId,this.studentName,this.className,this.questionPage,this.questionPicture,this.createTime,this.schoolName,this.gradeName,this.studentClassName,);
factory Items.fromJson(Map<String, dynamic> srcJson) => _$ItemsFromJson(srcJson);
Map<String, dynamic> toJson() => _$ItemsToJson(this);
}

View File

@ -59,8 +59,14 @@ class _JobReportState extends State<JobReport> with CommonMixin {
JobReportJoinClass(-1, '全部', -1, '全部', '全部', '全部', -1, -1, '-1'),
...(result.data ?? [])
];
involveClasses?.forEach((element) {
if(element.className == widget.className && element.gradeId == widget.gradeId && element.schoolId == widget.schoolId){
classData = element;
}
});
}, mounted);
}
_future = getReport();
} catch (e) {
print(e);
}
@ -71,7 +77,6 @@ class _JobReportState extends State<JobReport> with CommonMixin {
RestClient _client = await getClient();
Map<String, dynamic> param = classData?.toJson() ?? {};
param['jobid'] = widget.id;
print('widget.id=${widget.id}');
BaseStructureResult<JobReportModel?> data =
await _client.getJobReport(param);
if (!data.success) {
@ -352,7 +357,7 @@ class _JobReportState extends State<JobReport> with CommonMixin {
),
//
TopCount(data),
InkWell(
/* InkWell(
onTap: (){
RouterManager.router.navigateTo(
context,
@ -362,7 +367,7 @@ class _JobReportState extends State<JobReport> with CommonMixin {
);
},
child: Text('数据快查'),
),
),*/
//
Container(
padding: EdgeInsets.symmetric(vertical: 10.r, horizontal: 10.r),

View File

@ -0,0 +1,105 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:photo_view/photo_view_gallery.dart';
class FavoriteStudentDialog extends StatefulWidget {
const FavoriteStudentDialog({Key? key}) : super(key: key);
@override
State<FavoriteStudentDialog> createState() => _FavoriteStudentDialogState();
}
class _FavoriteStudentDialogState extends State<FavoriteStudentDialog> {
int defaultIndex = 1;
@override
Widget build(BuildContext context) {
return Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
padding: EdgeInsets.symmetric(vertical: 10.r, horizontal: 14.r),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
'14班 张小凡',
style: TextStyle(fontSize: 12.sp, color: Color(0xFF4E73FD)),
),
Expanded(child: Container()),
Text(
'6题',
style: TextStyle(fontSize: 12.sp, color: Color(0xFF868686)),
),
Padding(
padding: EdgeInsets.symmetric(horizontal: 8.r),
child: Image.asset(
'assets/images/favorite_delete_icon.png',
width: 22.r,
height: 22.r,
),
),
InkWell(
onTap: (){
Navigator.pop(context);
},
child: Image.asset(
'assets/images/favorite_dialog_close.png',
width: 22.r,
height: 22.r,
),
),
],
),
SizedBox(height: 10.r,),
Expanded(
child: Container(
color:Color(0xFF868686),
width: MediaQuery.of(context).size.width,
/* child: PhotoViewGallery.builder(
scrollPhysics: const BouncingScrollPhysics(),
builder: (BuildContext context, int index) {
return PhotoViewGalleryPageOptions(
imageProvider: NetworkImage(widget.imageItems[index]),
);
},
itemCount: 2,
pageController:PageController(initialPage: defaultIndex),
// onPageChanged: (){},
scrollDirection: Axis.horizontal,
),*/
),
),
Padding(
padding:EdgeInsets.symmetric(vertical: 15.r),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
width: (MediaQuery.of(context).size.width - 78.r)/2 - 10.r,
height: 28.r,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(6.r)),
border: Border.all(width: 1.r,color: Color(0xFFCACACA),style: BorderStyle.solid),
),
child: Center(child: Text('上一页',style: TextStyle(fontSize: 10.r,color: Color(0xFF505E6E)),)),
),
Container(
width: (MediaQuery.of(context).size.width - 78.r)/2 - 10.r,
height: 28.r,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(6.r)),
border: Border.all(width: 1.r,color: Color(0xFFCACACA),style: BorderStyle.solid),
),
child: Center(child: Text('下一页',style: TextStyle(fontSize: 10.r,color: Color(0xFF505E6E)),)),
),
],
),
)
],
),
);
}
}

View File

@ -1,9 +1,17 @@
import 'dart:convert';
import 'package:flutter/material.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';
import 'package:marking_app/common/model/common/base_structure_result.dart';
import 'package:marking_app/common/model/job/job_fav_student.dart';
import 'package:marking_app/common/model/job/job_favorite_item_model.dart';
import 'package:marking_app/common/model/job/job_report_join_class.dart';
import 'package:marking_app/pages/homework_correction/pages/favorite_student_dialog.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 JobFavorite extends StatefulWidget {
@ -11,12 +19,14 @@ class JobFavorite extends StatefulWidget {
final int schoolId;
final int gradeId;
final String className;
final String jobName;
const JobFavorite({
required this.jobId,
required this.schoolId,
required this.gradeId,
required this.className,
required this.jobName,
super.key,
});
@ -25,18 +35,32 @@ class JobFavorite extends StatefulWidget {
}
class _JobFavoriteState extends State<JobFavorite> with CommonMixin {
late Future<List<JobFavoriteItemModel>?> _future;
late Future<List<Items>?> _future;
List<JobReportJoinClass>? involveClasses = [];
JobReportJoinClass? classData;
late String loginName;
final int pageSize = 100;
@override
void initState() {
super.initState();
FastData fastData = FastData.getInstance();
fastData.getUser().then((value) {
if (value == null || value == '') return;
Map<String, dynamic> userInfo = json.decode(value);
setState(() {
loginName = userInfo['loginName'];
});
});
getInvolveClasses();
_future = getData();
}
Future<List<JobFavoriteItemModel>?> getData() async {
Future<List<Items>> getData() async {
var _client = await getClient();
var result = await _client.getListOfJobFavorites(widget.jobId, widget.gradeId, widget.schoolId, widget.className);
return result.data;
var result = await _client.getListOfJobFavorites(
widget.jobId, widget.jobName, widget.className,loginName,pageSize);
return result.data!.items;
}
Future<void> toGoCancelFavorite(int jobId, int studentId) async {
@ -47,53 +71,226 @@ class _JobFavoriteState extends State<JobFavorite> with CommonMixin {
}
}
Future<void> getInvolveClasses() async {
try {
RestClient _client = await getClient();
BaseStructureResult<List<JobReportJoinClass>> result =
await _client.getJobReportJoinClasses(widget.jobId);
if (result.success) {
toUpState(setState, () {
involveClasses = [
JobReportJoinClass(-1, '全部', -1, '全部', '全部', '全部', -1, -1, '-1'),
...(result.data ?? [])
];
involveClasses?.forEach((element) {
if(element.className == widget.className && element.gradeId == widget.gradeId && element.schoolId == widget.schoolId){
classData = element;
}
});
}, mounted);
}
print('involveClasses=${involveClasses!.length}');
_future = getData();
} catch (e) {
print(e);
}
}
void showStudentDialog(BuildContext context) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
insetPadding: EdgeInsets.all(25.r),
content: FavoriteStudentDialog(),
contentPadding: EdgeInsets.all(0),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(15.r))));
},
);
}
@override
Widget build(BuildContext context) {
bool isPadFlag = isPad();
return Scaffold(
backgroundColor: Color.fromRGBO(245, 245, 245, 1),
appBar: AppBar(
// titleSpacing: 0,
leading: IconButton(icon: Icon(Icons.arrow_back_ios), onPressed: () => Navigator.of(context).pop()),
elevation: 0.0,
leading: IconButton(
icon: Icon(Icons.arrow_back_ios),
onPressed: () => Navigator.of(context).pop()),
iconTheme: IconThemeData(color: Colors.black),
title: quickText('收藏夹'),
centerTitle: true,
backgroundColor: Colors.white,
),
body: MyFutureBuilder.buildFutureBuilderOfSingleInstance<List<JobFavoriteItemModel>>(
body: MyFutureBuilder.buildFutureBuilderOfSingleInstance<
List<Items>>(
context,
_future,
(List<JobFavoriteItemModel>? datas) {
if (datas == null)
(List<Items>? datas) {
/* if (datas == null)
return Container(
child: Center(
child: quickText('请求错误'),
),
);
);*/
print('datas${datas}');
List pageList = [];
List groupList = [];
if(datas!.length>0){
for (var item in datas) {
pageList.add(item.questionPage);
}
pageList = pageList.toSet().toList();
for (var page in pageList) {
var printList = datas.where((element) => element.questionPage == page).toList();
groupList.add({"questionPage": page, "list": printList});
}
}
return Container(
child: Column(
children: [
Container(child: quickText(widget.className)),
Expanded(
child: ListView.builder(
itemBuilder: (context, index) {
JobFavoriteItemModel item = datas[index];
return Container(
Padding(
padding: EdgeInsets.symmetric(vertical: 0.r, horizontal: 14.r),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'函数A的对称性研究',
style:
TextStyle(fontSize: 14.sp, color: Color(0xFF3C3C3C)),
),
//
Container(
padding: EdgeInsets.symmetric(vertical: 10.h, horizontal: 10.w),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
quickText(item.studentName, color: Color.fromRGBO(102, 102, 102, 1), size: 14.sp),
quickText('收藏时间:${item.createTime}', color: Color.fromRGBO(137, 137, 137, 1), size: 10.sp),
InkWell(
onTap: () async {},
child: Icon(
Icons.favorite,
size: 28.sp,
color: Color.fromRGBO(252, 108, 108, 1),
$classSelection(involveClasses, classData,
call: (JobReportJoinClass _classData) {
classData = _classData;
if (_classData.gradeId == -1) classData = null;
_future = getData();
toUpState(setState, () {}, mounted);
}),
// Expanded(child: Text('')),
],
),
),
],
),
),
Container(
width: MediaQuery.of(context).size.width,
height: 1.r,
decoration: BoxDecoration(
color: Color(0xFFCCCCCC),
),
),
Expanded(
child: isPadFlag? Padding(
padding: EdgeInsets.only(top: 10.r,bottom:8.r,left: 14.r,right: 14.r),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: EdgeInsets.only(bottom: 5.r),
child: Text('第六题',style: TextStyle(fontSize: 14.sp,color: Color(0xFF2E5BFF)),),
),
GridView(gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
mainAxisSpacing: 8.r,
crossAxisSpacing: 10.r,
childAspectRatio: 556 / 112,
),
shrinkWrap: true,
children: [
Container(
padding: EdgeInsets.symmetric(vertical: 5.r,horizontal: 10.r),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(6.r)),
),
child: InkWell(
onTap: (){
showStudentDialog(context);
},
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
quickText('张小凡',
color: Color(0xFF333333),
size: 12.sp),
Expanded(child: Container()),
Padding(
padding:EdgeInsets.only(right: 8.r),
child: Text('12班',style: TextStyle(fontSize: 12.sp,color: Color(0xFF666666)),),
),
InkWell(
onTap: () async {
print('删除');
},
child: Image.asset('assets/images/favorite_delete_icon.png',width: 26.r,height: 26.r,),
),
],
),
),
),
],),
],
),
):ListView.builder(
shrinkWrap: true,
itemBuilder: (context, index) {
// Items item = datas[index];
return Padding(
padding: EdgeInsets.only(top: 10.r,bottom:8.r,left: 14.r,right: 14.r),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: EdgeInsets.only(bottom: 5.r),
child: Text('第六题',style: TextStyle(fontSize: 14.sp,color: Color(0xFF2E5BFF)),),
),
Container(
padding: EdgeInsets.symmetric(vertical: 5.r,horizontal: 10.r),
margin: EdgeInsets.only(top: 5.r),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(6.r)),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
quickText('张小凡',
color: Color(0xFF333333),
size: 14.sp),
Expanded(child: Container()),
Padding(
padding:EdgeInsets.only(right: 8.r),
child: Text('12班',style: TextStyle(fontSize: 14.sp,color: Color(0xFF666666)),),
),
InkWell(
onTap: () async {},
child: Image.asset('assets/images/favorite_delete_icon.png',width: 32.r,height: 32.r,),
),
],
),
),
],
),
);
},
itemCount: datas.length,
// itemCount: datas.length,
itemCount: 10,
),
),
],
@ -102,4 +299,40 @@ class _JobFavoriteState extends State<JobFavorite> with CommonMixin {
),
);
}
}
///
@swidget
Widget $classSelection(
List<JobReportJoinClass>? involveClasses, JobReportJoinClass? classData,
{required Function(JobReportJoinClass) call}) {
if (involveClasses == null)
return Container(child: quickText('点击重试')); //
return Container(
// width: 200.r,
padding: EdgeInsets.symmetric(horizontal: 10.r),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.vertical(
top: Radius.elliptical(10, 10),
bottom: Radius.elliptical(10, 10),
)),
child: DropdownButton(
value: classData?.uniqueId ?? '-1',
style: TextStyle(color: Color.fromRGBO(89, 89, 89, 1), fontSize: 12.sp),
underline: Container(),
// isExpanded:true,
items: involveClasses.map((e) {
return DropdownMenuItem(
value: e.uniqueId!,
child: quickText(e.uniqueId == '-1'?e.graduationYear:e.graduationYear + e.className,
size: 12.sp, color: Colors.black),
);
}).toList(),
onChanged: (String? value) {
if (value == null) return;
call(involveClasses.firstWhere((element) => element.uniqueId == value));
},
),
);
}

View File

@ -270,7 +270,7 @@ class _JobListParticipateInClassState extends State<JobListParticipateInClass> w
RouterManager.router.navigateTo(
context,
RouterManager.jobFavoritePagePath +
'?className=${Uri.encodeComponent(task.className)}&jobId=${widget.jobId}&schoolId=${task.dpcSchoolId}&gradeId=${task.dpcGradeId}',
'?className=${Uri.encodeComponent(task.className)}&jobId=${widget.jobId}&schoolId=${task.dpcSchoolId}&gradeId=${task.dpcGradeId}&jobName=${widget.jobName}',
transition: getTransition(),
);
}

View File

@ -7,6 +7,7 @@ import 'package:marking_app/common/model/job/job_data_report.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/utils/request/rest_client.dart';
import 'package:marking_app/utils/toast_utils.dart';
class QuickCheckPersonal extends StatefulWidget {
final int jobId;
@ -33,15 +34,21 @@ class _QuickCheckPersonalState extends State<QuickCheckPersonal>
void getJobPersonal() async {
RestClient _client = await getClient();
Map<String, dynamic> params = {};
// params['jobid'] = widget.jobId;
params['jobid'] = '521646983660101';
params['jobid'] = widget.jobId;
// params['jobid'] = '521646983660101';
params['studentId'] = widget.studentId;
BaseStructureResult<StudentDetails?> data =
await _client.getJobPersonalReport(params);
if(data.data!.studentId != null){
setState(() {
studentInfo = data.data;
});
}else{
Navigator.pop(context);
ToastUtils.showError('暂无数据');
}
EasyLoading.dismiss();
setState(() {
studentInfo = data.data;
});
}
@override
@ -54,7 +61,7 @@ class _QuickCheckPersonalState extends State<QuickCheckPersonal>
appBar: AppBar(
backgroundColor: Colors.white,
title: Text(
studentInfo!.studentName,
studentInfo!.studentName!,
style: TextStyle(fontSize: 16.sp, color: Color(0xFF000000)),
),
centerTitle: true,

View File

@ -36,8 +36,8 @@ class _QuickDataCheckPageState extends State<QuickDataCheckPage> with CommonMixi
void getJobDataReport() async {
RestClient _client = await getClient();
Map<String, dynamic> params = {};
// params['jobid'] = widget.jobId;
params['jobid'] = '521646983660101';
params['jobid'] = widget.jobId;
print(widget.jobId);
BaseStructureResult<JobDataReport?> data =
await _client.getJobDataCenterReport(params);
EasyLoading.dismiss();

View File

@ -54,10 +54,11 @@ class _QuickStudentDataTableState extends State<QuickStudentDataTable> {
cells: [
DataCell(InkWell(
onTap: () {
RouterManager.router.navigateTo(
context,
RouterManager.quickCheckPersonalPath +
'?jobId=${521646983660101}&studentId=${item.studentId}',
'?jobId=${widget.jobId}&studentId=${item.studentId}',
transition: getTransition(),
);
},
@ -68,7 +69,7 @@ class _QuickStudentDataTableState extends State<QuickStudentDataTable> {
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(item.studentName,
Text(item.studentName!,
style:
TextStyle(fontSize: 12.sp, color: Color(0xFF6888FD))),
SizedBox(

View File

@ -312,7 +312,8 @@ class RouterManager {
int gradeId = int.parse(params['gradeId']![0]);
int schoolId = int.parse(params['schoolId']![0]);
String className = params['className']![0];
return JobFavorite(jobId: jobId, gradeId: gradeId, schoolId: schoolId, className: className);
String jobName = params['jobName']![0];
return JobFavorite(jobId: jobId, gradeId: gradeId, schoolId: schoolId, className: className,jobName:jobName);
},
);

View File

@ -17,6 +17,7 @@ import 'package:marking_app/common/model/job/job_concerned_with_student.dart';
import 'package:marking_app/common/model/job/job_concerned_with_student_params.dart';
import 'package:marking_app/common/model/job/job_data_report.dart';
import 'package:marking_app/common/model/job/job_do_marking_status_info.dart';
import 'package:marking_app/common/model/job/job_fav_student.dart';
import 'package:marking_app/common/model/job/job_favorite_item_model.dart';
import 'package:marking_app/common/model/job/job_favorite_model.dart';
import 'package:marking_app/common/model/job/job_level_set_params.dart';
@ -303,12 +304,13 @@ abstract class RestClient {
@the_retrofit.Query("jobid") int jobId);
// =>
@the_retrofit.GET("${RequestConfig.hwProxyKeywords}/dpc-api/api/read/job-favorites")
Future<BaseStructureResult<List<JobFavoriteItemModel>>> getListOfJobFavorites(
@the_retrofit.Query("jobid") int jobId,
@the_retrofit.Query("gradeId") int gradeId,
@the_retrofit.Query("schoolId") int schoolId,
@the_retrofit.GET("/api/jobs/fav-student-jobs")
Future<BaseStructureResult<JobFavStudent>> getListOfJobFavorites(
@the_retrofit.Query("JobId") int jobId,
@the_retrofit.Query("JobName") String jobName,
@the_retrofit.Query("className") String className,
@the_retrofit.Query("Account") String loginName,
@the_retrofit.Query("PageSize") int pageSize,
);
// =>