前言:
最近项目有一个业务是用户连续签到xx天赠送多少奖励积分等等,看了网上绝大部分的思路,查询所有签到记录在进行比对有没有漏签,个人认为有些麻烦,自己设计了一下,仅供朋友们一些参考,如果你们有更好的想法,请留言,我也想学习下,大家共同进步嘛。
技术栈是:Springboot2.0+JPA+MYSQL+Lombok+Swagger2.0
正片开始:
先贴实体类代码:
package com.dq.domain.user;
import com.dq.domain.VO;
import com.dq.domain.base.BaseEntity;
import com.dq.utils.TimeUtil;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.persistence.Entity;
import javax.persistence.ManyToOne;
/**
* @author liuhui
* @date 2019/12/11 0011 13:40:58
*/
@Data
@Entity
@ApiModel("签到记录")
public class SignInRecord extends BaseEntity implements VO.ToVO {
@ManyToOne
@ApiModelProperty("签到用户")
protected SysUser sysUser;
/**
* 签到日期 格式 yyyy-MM-DD
*/
protected String signDate;
/**
* 连续签到天数 检查最后一次签到是不是昨天,是的话就+1,不是的话就变成1,
* 每到 7、15、30给一次奖励,如果到了30也变成1
*/
protected Integer continueNumber;
@Data
@ApiModel("签到视图")
public static class Vo implements VO{
@ApiModelProperty("签到用户")
public String username;
@ApiModelProperty("签到时间")
public String signInTime;
}
@Override
public VO toVO(boolean isRecursion) {
Vo vo = new Vo();
WxUser wxUser = (WxUser) this.getSysUser();
vo.username = wxUser.getUsername();
vo.signInTime = fmt(this.getCreateTime(), TimeUtil.YYYY_MM_DD_HH_MM_SS);
return vo;
}
}
数据库数据大致长这样:
id27以后为正式数据,前边的是测试数据 ,大家可以不看。
接下来放业务代码:
@Override
public Map signIn() throws AdminException {
SysUser sysUser = shiroService.getUser();
//今天是否签到过
if (apiSignInRecordRepository.existsBySysUserAndSignDateAndDeletedFalse(sysUser, TimeUtil.getString(DateTime.now(), TimeUtil.YYYY_MM_DD))) {
throw new AdminException("您今天已经签到过了");
}
List<SignInRecord> signInRecordList = apiSignInRecordRepository.findBySysUserOrderByCreateTimeDesc(sysUser, PageableUtil.get(0, 1));
if (!signInRecordList.isEmpty()) {
SignInRecord findSignInRecord = signInRecordList.get(0);
}
}
TimeUtil是一个工具类,用到的方法如下:
public static final String YYYY_MM_DD= "yyyy-MM-dd";
// 获取格式化时间
public static final String getString(DateTime var, String fmt) {
return var.toString(fmt);
}
判断用户签到是获取当天的日期,格式为2020-01-01这种去和数据库signDate字段比对。
判断是否是连续签到逻辑是:获取用户最后一次的签到记录,检查查询到的签到记录的signDate是不是昨天的signDate,是的话就是连续签到,continueNumber++,不是的话就是断签了,continueNumber设置成1重新开始就行了。
注:PageableUtil是封装的spring的Pageable分页方法,传入0,1代表limit0,1是一个意思,order by createTime是根据日期从大到小取第一个就是最后一次签到记录,不会出问题。
大家如果有更好的方法欢迎留言,一起学习啊。