一、签到类型
- 每日签到:每日开放签到,时间记录为:年、月、日。
- 固定时段签到:每日固定时段签到,时间记录为:年、月、日、时、分、秒。
- 核心问题:判断用户签到时间是否在规定的时间段内。
- 定位并签到:每日开发签到,并记录位置和时间数据。
- 核心问题:解决定位问题
二、数据库设计
日签到表(sign_in):
CREATE TABLE `sign_in` (
`id` int(8) unsigned zerofill NOT NULL AUTO_INCREMENT,
`user_id` int(8) unsigned zerofill NOT NULL COMMENT '用户id',
`status` int(2) NOT NULL DEFAULT '0' COMMENT '签到状态0未签到',
`time` date NOT NULL COMMENT '签到时间',
PRIMARY KEY (`id`),
KEY `user_id` (`user_id`),
CONSTRAINT `sign_in_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8
时段签到表(sign_in_lag):
CREATE TABLE `sign_in_lag` (
`id` int(8) unsigned zerofill NOT NULL AUTO_INCREMENT,
`user_id` int(8) unsigned zerofill NOT NULL COMMENT '用户id',
`status` int(2) NOT NULL DEFAULT '0' COMMENT '签到状态0未签到',
`time` datetime NOT NULL COMMENT '签到时间',
PRIMARY KEY (`id`),
KEY `user_id` (`user_id`),
CONSTRAINT `userinfo` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8
定位签到表(sign_in_geo):
CREATE TABLE `sign_in_geo` (
`id` int(8) unsigned zerofill NOT NULL AUTO_INCREMENT,
`user_id` int(8) unsigned zerofill NOT NULL COMMENT '用户id',
`b` float NOT NULL COMMENT '经度',
`l` float NOT NULL COMMENT '纬度',
`status` int(2) NOT NULL DEFAULT '0' COMMENT '签到状态0未签到',
`time` date NOT NULL COMMENT '签到时间',
PRIMARY KEY (`id`),
KEY `user_id` (`user_id`),
CONSTRAINT `sign_in_geo_1` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8
用户表(user):
CREATE TABLE `user` (
`id` int(8) unsigned zerofill NOT NULL AUTO_INCREMENT,
`name` varchar(18) NOT NULL COMMENT '用户名',
`pass` varchar(50) NOT NULL COMMENT '密码',
`sex` int(1) NOT NULL DEFAULT '0' COMMENT '性别',
`sign_time` datetime DEFAULT NULL COMMENT '登录时间',
`regist_time` datetime DEFAULT NULL COMMENT '注册时间',
`status` int(2) NOT NULL DEFAULT '1' COMMENT '状态',
`s1` varchar(10) DEFAULT NULL COMMENT '扩展用',
`s2` varchar(10) DEFAULT NULL COMMENT '扩展用',
`s3` varchar(10) DEFAULT NULL COMMENT '扩展用',
`s4` varchar(10) DEFAULT NULL COMMENT '扩展用',
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8
三、核心代码
-
自定义时间工具类(TimeTools.java)
/**
* 获取当前时间
* @return 2020-01-01 00:00:00
*/
public static String getTime(){
Date d = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return sdf.format(d);
}
/**
* 获取日期数据
* @return 2020-01-01
*/
public static String getDay(){
Date d = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
return sdf.format(d);
}
/**
* 计算时差
* @param d1
* @param d2
* @return
*/
public static long timeLag(Date d1,Date d2){
long lag = d2.getTime() - d1.getTime();
return lag/1000/60;
}
/**
* 时间戳转换日期
* @param stamp
* @return
*/
public static String stampToTime(String stamp) {
String sd = "";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
sd = sdf.format(new Date(Long.parseLong(stamp))); // 时间戳转换日期
return sd;
}
/**
* 日期转换为时间戳
* @param time
* @return
*/
public static long timeToStamp(String time) {
Date d = new Date();
long timeStamp = 0;
try {
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
d = sf.parse(time);// 日期转换为时间戳
} catch (ParseException e) {
e.printStackTrace();
}
timeStamp = d.getTime();
return timeStamp;
}
- 检查用户签到时间是否在指定的时间段内(我写成了固定的时间,每天18:00-20:00。也可以自定义动态时间,改写下面这个方法就可以。)
/**
* 检查签到时间是否在时间段内
* @return 0签到时间段设置错误1未到签到时间2签到已结束3可签到
*/
private int lagCheck(){
Date date = new Date();
//获取当天开始、结束签到时间的时间戳
long beginTime = TimeTools.timeToStamp(TimeTools.getDay()+" 18:00:00");
long endTime = TimeTools.timeToStamp(TimeTools.getDay()+" 20:00:00");
//获取当前时间和签到时间段的时间戳的差值
long begin = TimeTools.timeLag(new Date(beginTime),date);
long end = TimeTools.timeLag(new Date(endTime),date);
if(beginTime>=endTime) return 0;
if(begin<0) return 1;
else if(end>0) return 2;
else return 3;
}
- 高德地图JS API的使用准备(这里用的是高德地图JS API(点击跳转),其他地图API也可):
- 1、使用高德地图api需要先申请一个key,操作步骤参考高德开发平台官网(点击跳转)。
- 2、将你申请的key添加到项目中,找到home.html并修改:
<script type="text/javascript" src="https://webapi.amap.com/maps?v=1.4.15&key=你申请的key"></script>
- 初始化地图并获取定位信息核心代码(定位结果如下图:4.1)
//初始化地图
var marker,map = new AMap.Map('container', {
zoom: 16, //初始地图级别
resizeEnable: true,
showIndoorMap: false //关闭室内地图
});
var position;//记录经纬度信息
AMap.plugin('AMap.Geolocation', function() {
var geolocation = new AMap.Geolocation({
//是否使用高精度定位,默认:true
enableHighAccuracy: true,
//超过10秒后停止定位,默认:5s
timeout: 10000,
//定位按钮的停靠位置
buttonPosition:'RB',
//定位按钮与设置的停靠位置的偏移量,默认:Pixel(10, 20)
buttonOffset: new AMap.Pixel(10, 20),
//定位成功后是否自动调整地图视野到定位点
zoomToAccuracy: true,
});
map.addControl(geolocation);
geolocation.getCurrentPosition(function(status,result){
$('.info').css('display', 'block');
if(status=='complete'){
onComplete(result)
position = result.position;//将定位结果赋值
}else{
onError(result)
}
});
});
//解析定位结果
function onComplete(data) {
console.log(data.position);
document.getElementById('status').innerHTML='定位成功'
var str = [];
str.push('定位结果:' + data.position);
str.push('定位类别:' + data.location_type);
if(data.accuracy){
str.push('精度:' + data.accuracy + ' 米');
}//如为IP精确定位结果则没有精度信息
str.push('是否经过偏移:' + (data.isConverted ? '是' : '否'));
document.getElementById('result').innerHTML = str.join('<br>');
}
//解析定位错误信息
function onError(data) {
document.getElementById('status').innerHTML='定位失败'
document.getElementById('result').innerHTML = '失败原因排查信息:'+data.message;
}
四、后台接口列表
接口分类 | 接口地址 | 说明 |
---|---|---|
用户类 | /user/login | 用户登录接口 |
日签到类 | /sign | 用户签到 |
/sign/history | 获取用户日签到的历史数据 | |
时段签到 | /sign/lag | 用户签到 |
/sign/history | 获取用户分时段签到的历史数据 | |
定位签到 | /sign/geo | 用户签到 |
/sign/geo/history | 获取用户定位签到的历史数据 | |
/sign/geo/history/yesterday | 获取用户昨天签到的历史数据 |
五、运行效果
六、总结
版本1的代码就这样了,由于时间关系,还有些想做的功能都没写。
分时段签到的模块,你们还可以在前端加时间验证功能来降低对服务器的消耗。这里是根据我做的一个旅游项目总结的部分功能代码,时间段是由导游来决定的,如果你们感兴趣,可以试试创建一个角色来规定签到时间段。
另外,如果你对这个项目有更好的设计建议,欢迎私信或加群哦。
七、下载地址
CSDN下载:https://download.csdn.net/download/MINGHUE/12696161
QQ群下载:100372253(禁止一切广告)
GitHub下载:整理ing