Flutter+springboot实现考勤码+gps考勤签到功能设计环境打算总结
本人正在做一个智慧课堂辅助app的毕设作品,恰好有一个功能是考勤签到,恰好实现了,分享一下经验。
主要实现有1.app班主任用户发布数字或gps考勤任务,gps考勤可以设置考勤地点和距离范围内有效,而且能设置考勤失效时间。前端将考勤任务通过websocket推送到该课程的所有中学生,中学生收到后在指定时间地点内输入考勤码完成签到,过期不签到的朋友将被系统设置为逃课。借助redis做离线消息缓存三天,离线用户的将消息储存到redis中,用户上线后取出redis离线消息推送。
实现步骤和思路:
前端springboot:
1.班主任通过restful风格插口创建考勤任务,生成数据库记录
2.在该创建考勤插口中使用rabbitmq来执行三个步骤:
1.生成须要签到的中学生名单记录到数据库,赋默认状态值-1,表示须要签到;2.将须要考勤的消息通过websocket推献给后端app,3.使用redis把班主任创建的考勤任务计入,并设置过期时间为班主任设置的有效时间。
3.在创建考勤插口最后一步使用rabbitmq的消息延后队列去跟新数据库状态为-1(须要考勤)的记录更改为事假的状态,并把出勤的记录通过websocket推送到中学生后端。消息延后队列时间为考勤有效时间
4.借助redis做离线消息缓存
后端flutter:
1.班主任使用高德地图插件定位获取考勤位置,设置考勤距离和有效时间,通过http恳求发送到前端;
3.成功通过Timer计时器来显示剩余时间,而且使用provide状态管理来保持时间显示;
4.考勤期间收到完成考勤的中学生数据,使用provide插入本地并更新名单记录;
5.考勤结束收到前端websocket推送的中学生出勤名单,provide更新数据;
中学生:1.收到班主任发布的考勤任务,抵达考勤页面点击考勤,完成考勤更新UI,假如失败,也跟新UI界面
使用到的工具和框架有:
springboot
spring-data-jpa
mysql
redis
rabbitmq
rabbitmq消息延后队列插件
设计发布考勤任务
课堂创建者可以发布考勤任务让中学生用户在指定的时间内完成考勤。发布的考勤主要分两种形式,第一种是数字考勤,中学生只须要在指定的时间内通过考勤码完成考勤任务即可;第二种为GPS考勤,是在第一种考勤的形式上,设置指定考勤的地点范围,只有在指定的地点范围内完成考勤,才算成功,否则系统视为事假。该功能主要涉及的工具和技术有Reids非关系型数据库、RabbitMQ消息中间件、消息延时队列、Websocket。服务端具体的设计过程如下:
(1)顾客端通过恳求Restful风格插口创建考勤任务,生成数据库记录;
(2)在该创建考勤任务插口中借助RabbitMQ消息中间件来异步完成三个步骤:
①生成须要签到的中学生名单(userId)批量写入到数据库,考勤状态(status)赋默认状态值-1,表示须要完成签到任务;
②将考勤消息通过websocket推献给须要完成考勤任务的所有用户App顾客端;
③把班主任用户创建的考勤任务记录写入Redis,并设置过期时间为班主任用户指定的时间(expireTime)。
(3)借助RabbitMQ的延时队列去更改中学生考勤记录状态(status)为-1的记录统一更改为状态为0,表示中学生出勤,无法在指定时间内完成考勤任务,并用Websocket推送出勤名单给考勤任务创建者;
(4)须要完成考勤的中学生用户在考勤有效时间内完成考勤,数据库中学生考勤状态(status)为-1的更改为1,表示缺勤,并用Websocket推送出勤名单给考勤任务创建者。
Flutter
App顾客端Gps考勤使用到高德地图的定位插口,主要分为以下几个步骤:
(1)在Flutter的pubspec.yaml文件中引入高德地图插件:
amap_location_fluttify:0.8.11+481e45c#高德地图
(2)到高德地图开放平台()注册开发者,并创建应用;
(3)在Android的AndroidManifest.xml文件下添加高德地图创建应用生成的Key
(4)在调用高德地图插口插件前,调用以下代码,初始化插口:
WidgetsFlutterBinding.ensureInitialized();
AwaitAmapCore.init(‘2121ff3535eb097097cc00cdcd048048ff76681945257668194525baba77a’);
发布考勤任务功能的流程如图。
签到考勤
中学生用户在收到班主任用户发布的考勤任务后,将收到系统提示的考勤消息。在相应的课堂考勤列表中出现须要完成的考勤记录,假如发布的是数字考勤,通过班主任告诉中学生的考勤码完成签到,倘若是GPS考勤,则须要手机定位后在输入考勤码签到。假如考勤任务时间过期酷q签到插件源码,或则考勤用户的定位地点不在指定地点范围内将直接视为事假,未能再签到。具体实现流程如图所示。
环境打算
org.springframework.boot
spring-boot-starter-data-jdbc
org.springframework.boot
spring-boot-starter-data-jpa
org.springframework.boot
spring-boot-starter-jdbc
org.springframework.boot
spring-boot-starter-web
mysql
mysql-connector-java
org.projectlombok
lombok
com.google.guava
guava
25.1-jre
mysql
mysql-connector-java
runtime
前端步骤:1.班主任发布考勤任务插口
2.rabbitmq收到班主任发布考勤执行的步骤代码插口
3.考勤过期后,rabbitmq执行的代码
4.websocket推送酷q签到插件源码,以及离线消息缓存,上线取出发送,删掉缓存
用户上线后,websocket取出redis离线消息推送,但是去除离线缓存的数据
@OnPen插口
5.中学生考勤插口
///学生考勤
@RequestMapping(value = "AttendanceStudentCheck", method = {RequestMethod.GET, RequestMethod.POST})
public BaseResult AttendanceStudentCheck(@Valid @RequestBody AttendanceStudentDto attendanceStudentDto,
HttpServletRequest request) {
String key = RedisKeyUtil.Attendance.getAttendanceExpireKey(attendanceStudentDto.getAttendanceId());
Attendance attendance = (Attendance) redisService.get(key);
String studentId = (String) request.getAttribute("X-AUTH-ID");
if (attendance == null) {//考勤失败,缺勤
attendanceStudentService.updateStudentStatus(studentId, attendanceStudentDto, 3, 0);
return BaseResult.ok(3);
}
boolean isSuccess = false;
double d = 0;
if (attendance.getAttendCode().equals(attendanceStudentDto.getAttendCode())) {
if (attendanceStudentDto.getType() == 0) {//数字考勤
//考勤成功
isSuccess = true;
} else {//gps
BigDecimal lat = attendance.getLatitude();
BigDecimal lon = attendance.getLongitude();
double distance = attendance.getDistance();
attendanceStudentDto.getLatitude();
attendanceStudentDto.getLongitude();
d = DistanceUtil.earthDis(lat.doubleValue(), lon.doubleValue(),
attendanceStudentDto.getLatitude().doubleValue(),
attendanceStudentDto.getLongitude().doubleValue());
System.out.println("distance: " + d);
if (d
AttendanceStudent attendanceStudent =
attendanceStudentService.updateStudentStatus(studentId, attendanceStudentDto, 0, d);
Map map = new HashMap();
map.put("method", "teacher/createAttendance");
map.put("publisherId", attendance.getPublisherId());
try {
redisRabbitProvider.websocketSend(attendanceStudent, map);
} catch (IOException e) {
e.printStackTrace();
}
return BaseResult.ok(0);
} else {
return BaseResult.ok(-1);
}
}
后端flutterapp须要用到的插件
dio: ^3.0.8
provide: ^1.0.2 #状态管理
shared_preferences: ^0.5.1
flutter_local_notifications: ^1.1.5+1 #
permission_handler: ^4.2.0+hotfix.3 #权限库
amap_location_fluttify: 0.8.6+356f11c #高德地图
flutter_event_bus: ^0.0.2
主要思路
暂无评论内容