用户签到表

CREATE TABLE `t_user_sign` (

`id` bigint(20) NOT NULL AUTO_INCREMENT,

`count` int(11) DEFAULT NULL,

`create_time` datetime DEFAULT NULL,

`last_modify_time` datetime DEFAULT NULL,

`sign_count` int(11) DEFAULT NULL,

`user_id` bigint(20) NOT NULL,

PRIMARY KEY (`id`),

KEY `id` (`id`),

KEY `user_id` (`user_id`),

KEY `last_modify_time` (`last_modify_time`)

) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;

用户签到日志表

CREATE TABLE `t_user_sign_log` (

`id` bigint(20) NOT NULL AUTO_INCREMENT,

`create_time` datetime DEFAULT NULL,

`sign_status` char(1) NOT NULL,

`update_time` datetime DEFAULT NULL,

`user_sign_id` bigint(20) DEFAULT NULL,

PRIMARY KEY (`id`),

KEY `user_sign_id` (`user_sign_id`),

KEY `sign_status` (`sign_status`,`user_sign_id`)

) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;

简单的代码体现

使用的是JPA方式,可以根据情况自己转换

**

* 描述:

*

* @author 哈哈哈

* @date 2019/5/9 13:53

*/

@Data

@AllArgsConstructor

@NoArgsConstructor

@Builder

@Entity

@Table(name = "t_user_sign")

public class UserSign {

@Id

@GeneratedValue(strategy = GenerationType.IDENTITY)

private Long id;

/**

* 关联用户ID

*/

@Column(nullable = false)

private Long userId;

/**

* 创建时间

*/

@Column

private Date createTime;

/**

* 最后签到时间

*/

@Column

private Date lastModifyTime;

/**

* 连续签到次数

*/

@Column

private Integer signCount;

/**

* 签到次数

*/

@Column

private Integer count;

}

/**

* 描述:用户签到记录表

*

* @author 哈哈哈

* @date 2019/5/9 14:52

*/

@Data

@AllArgsConstructor

@NoArgsConstructor

@Builder

@Entity

@Table(name = "t_user_sign_log")

public class UserSignLog {

@Id

@GeneratedValue(strategy = GenerationType.IDENTITY)

private Long id;

/**

* 关联签到id

*/

@Column

private Long userSignId;

@Column

private Date createTime;

@Column

private Date updateTime;

/**

* 是否可用

*/

@Column(nullable = false, columnDefinition = "char(1)")

@Type(type = "yes_no")

private Boolean signStatus;

}

DAO层

@Repository

public interface UserSignRepository extends JpaRepository, JpaSpecificationExecutor {

UserSign findUserSignByUserId(Long userId);

}

/**

* 描述:

*

* @author

* @date 2019/5/9 14:55

*/

@Repository

public interface UserSignLogRepository extends JpaRepository, JpaSpecificationExecutor {

@Modifying

@Query("update UserSignLog set signStatus=false where userSignId =(?1)")

int updateUserSignLogSignStatus(Long userSignId);

List findUserSignLogsByUserSignIdAndSignStatusIsTrue(Long userSignId);

}

service

/**

* 描述:用户签到

*

* @author 哈哈哈

* @date 2019/5/9 14:00

*/

@Service

public class UserSignService {

private final UserSignRepository userSignRepository;

private final UserSignLogRepository userSignLogRepository;

@Autowired

public UserSignService(UserSignRepository userSignRepository, UserSignLogRepository userSignLogRepository) {

this.userSignRepository = userSignRepository;

this.userSignLogRepository = userSignLogRepository;

}

/****

* 打卡

* @param userId 用户id

* @return

*/

@Transactional()

public int createSign(Long userId) {

UserSign userSign = userSignRepository.findUserSignByUserId(userId);

Date now = new Date();

/*判断是否是第一次签到*/

if (userSign == null) {

System.out.println("用户第一次签到");

userSign = UserSign.builder()

.createTime(now)

.lastModifyTime(now)

.count(1)

.userId(userId)

.signCount(1)

.build();

userSignRepository.save(userSign);

UserSignLog userSignLog = UserSignLog.builder()

.createTime(now)

.updateTime(now)

.userSignId(userSign.getId())

.signStatus(true)

.build();

userSignLogRepository.save(userSignLog);

return 1;

} else {

//今天已经签到过了

if (userSign.getLastModifyTime().getTime() > getStartOfDay(now).getTime()

&& userSign.getLastModifyTime().getTime() < getEndOfDay(now).getTime()) {

System.out.println("用户已经签到过了");

return userSign.getSignCount();

}

Calendar calendar = Calendar.getInstance();

calendar.setTime(now);

calendar.add(Calendar.DATE, -1);

//非连续签到

if (userSign.getLastModifyTime().getTime() < getStartOfDay(calendar.getTime()).getTime()) {

System.out.println("已经不是连续签到");

//签到次数重新开始

//修改签到log表中的状态

userSignLogRepository.updateUserSignLogSignStatus(userSign.getId());

userSign.setCount(userSign.getCount() + 1);

userSign.setSignCount(1);

userSign.setLastModifyTime(now);

UserSignLog userSignLog = UserSignLog.builder()

.createTime(now)

.updateTime(now)

.signStatus(true)

.userSignId(userSign.getId())

.build();

userSignLogRepository.save(userSignLog);

userSignRepository.save(userSign);

return 1;

} else {

System.out.println("连续签到");

//正常打卡

userSign.setSignCount(userSign.getSignCount() + 1);

userSign.setCount(userSign.getCount() + 1);

userSign.setLastModifyTime(now);

userSignRepository.save(userSign);

UserSignLog userSignLog = UserSignLog.builder()

.signStatus(true)

.createTime(now)

.updateTime(now)

.userSignId(userSign.getId())

.build();

userSignLogRepository.save(userSignLog);

return userSign.getSignCount();

}

}

}

/****

* 用户每天第一次进入签到打卡页面初始化一下数据

* @param userId

*/

@Transactional()

public void init(Long userId) {

UserSign userSign = userSignRepository.findUserSignByUserId(userId);

Date now = new Date();

//曾经签到过

if (userSign != null) {

//判断今天是否签到过

if (userSign.getLastModifyTime().getTime() > getStartOfDay(now).getTime()

&& userSign.getLastModifyTime().getTime() < getEndOfDay(now).getTime()) {

System.out.println("用户今天已经签到过了,正常使用");

return;

}

//判断昨天是否签到过

Calendar calendar = Calendar.getInstance();

calendar.setTime(now);

calendar.add(Calendar.DATE, -1);

if (userSign.getLastModifyTime().getTime() < getStartOfDay(calendar.getTime()).getTime()) {

System.out.println("昨天没有签到");

//昨天没有连续签到

if (userSign.getSignCount() == 7) {

System.out.println("签到次数为7的时候初始化数据");

//初始化数据

userSign.setSignCount(0);

userSignLogRepository.updateUserSignLogSignStatus(userSign.getId());

userSignRepository.save(userSign);

return;

}

System.out.println("签到次正常");

} else {

System.out.println("昨天签到了");

//昨天签到过

if (userSign.getSignCount() == 7) {

System.out.println("签到次数为7的时候初始化数据");

//初始化数据

userSign.setSignCount(0);

userSignLogRepository.updateUserSignLogSignStatus(userSign.getId());

userSignRepository.save(userSign);

return;

}

System.out.println("签到次正常");

}

}

}

/*根据用户id查询签到list*/

public List data(Long userId) {

UserSign userSign = userSignRepository.findUserSignByUserId(userId);

//没有签到过,返回null

if (userSign != null) {

//如果今天签到过

return userSignLogRepository.findUserSignLogsByUserSignIdAndSignStatusIsTrue(userSign.getId());

}

return new ArrayList<>();

}

public Boolean isOrSign(Long userId) {

Date now = new Date();

UserSign userSign = userSignRepository.findUserSignByUserId(userId);

//没有签到过,返回null

//如果今天签到过

return userSign != null && userSign.getLastModifyTime().getTime() > getStartOfDay(now).getTime() && userSign.getLastModifyTime().getTime() < getEndOfDay(now).getTime();

}

/****

* 获得某天最大时间 2019-05-09 23:59:59

* @param date 日期

* @return

*/

public static Date getEndOfDay(Date date) {

LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(date.getTime()), ZoneId.systemDefault());

LocalDateTime endOfDay = localDateTime.with(LocalTime.MAX);

return Date.from(endOfDay.atZone(ZoneId.systemDefault()).toInstant());

}

/****

* 获得某天最小时间 2019-05-09 00:00:00

* @param date 日期

* @return

*/

public static Date getStartOfDay(Date date) {

LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(date.getTime()), ZoneId.systemDefault());

LocalDateTime startOfDay = localDateTime.with(LocalTime.MIN);

return Date.from(startOfDay.atZone(ZoneId.systemDefault()).toInstant());

}

}

接下来就是controller

@RestController

@RequestMapping("/sign")

@Api(tags = {"用户签到打卡API"})

public class UserSignController {

private final UserSignService userSignService;

@Autowired

public UserSignController(UserSignService userSignService) {

this.userSignService = userSignService;

}

@ApiOperation(value = "用户签到")

@PostMapping("/createSign")

public List createSign(@RequestParam Long userId) {

//首先要初始化数据

userSignService.init(userId);

userSignService.createSign(userId);

return userSignService.data(userId);

}

@ApiOperation(value = "打卡数据")

@GetMapping("/data")

public List data(@RequestParam Long userId) {

userSignService.init(userId);

return userSignService.data(userId);

}

@ApiOperation(value = "判断今天是否已经打过卡")

@GetMapping("/isOrSign")

public Boolean isOrSign(@RequestParam Long userId) {

return userSignService.isOrSign(userId);

}

}

java签到断签重置_签到打卡功能,7天一个周期,中间断签重新开始相关推荐

  1. java快速注释怎么配置_详解如何在低版本的Spring中快速实现类似自动配置的功能...

    在 Spring 4 后才引入了 @Conditional 等条件注解,它是 Spring Boot 中实现自动配置的最大功臣! 那么问题来了:如果我们还在使用 Spring 3.x 的老版本,这时候 ...

  2. java实现七日股票问题_七日打卡--JAVA资源限制

    资源限制 资源限制是指在进行并发编程时,程序的执行速度受限于计算机硬件资源或软件资源. 例如服务器的带宽只有2Mb/s,某个资源的下载速度是1Mb/s每秒,系统启动10个线程下载资源,下载速度不会变成 ...

  3. java map 随机取值_随机获取一个集合(List, Set)中的元素,随机获取一个Map中的key或value...

    利用Java提供的Random类.从List或Set中随机取出一个元素,从Map中随机获取一个key或value. 因为Set没有提供get(int index)方法,仅仅能先获取一个随机数后.利用一 ...

  4. java注解方式实体类_如何用注解的方式在实体类中实现一对一,和一对多多对多...

    一对一 @OneToOne(fetch = FetchType.LAZY) @JoinColumn(name = "THEMEID") @Cascade({CascadeType. ...

  5. java 责任链模式 链表_责任链模式的实现及源码中应用

    01 - 责任链模式的实现 假设一个出差任务的流程需要审批出差行程和出差报销金额.那么,对应两个部门的审核.我们先定义一个出差任务Task类: 然后,我们定义一个抽象的处理类Handler,其中具体的 ...

  6. java pdf添加透明水印_如何使用PDF编辑工具在PDF文件中添加透明水印

    PDF 文件在修改编辑的时候会使用到 PDF 编辑工具,不管是工 作中还是生活中,都会使用到 PDF 文件,当我们需要给 PDF 文件添 加透明水印时,该怎么操作呢,是不是有很多的小伙伴也很好奇, 那 ...

  7. 蚂蚁p8多少股票_就在明天!“大象”蚂蚁来了 中一签能赚多少?|蚂蚁|a股|港股|科创板|股票...

    (原标题:就在明天!"大象"蚂蚁来了) 蚂蚁集团的这次打新可谓盛况空前. 港股打新热火朝天,A股的网上申购将在明日(10月29日)开启. 别忘了申购! 港股打新盛况空前 综合券商及 ...

  8. java 免费图表控件_推荐10款功能强大且免费的JavaScript图形图表插件

    1.D3 D3是最流行的可视化库之一,它可以将任意数据绑定到DOM(Document Object Model,文档对象模型),然后对该文件提供数据驱动转换. 2.Rickshaw Rickshaw ...

  9. 山寨机java自动发短信_恶搞短信附带代码 山寨手机最容易中招黑屏

    恶搞短信附带代码 山寨手机最容易中招黑屏 2012-03-27 13:49:34  来源:钱江晚报 扫码可以: 1.在手机上浏览 2.分享给微信好友或朋友圈 摘要: 用一条短信就能让你手机" ...

最新文章

  1. [k8s] 第四章 kubectl 命令行 实战入门
  2. python基础知识资料-Python学习--最完整的基础知识大全
  3. 设计模式——简单工厂
  4. 亿纬锂能:公司被选定为博世的供应商 为博世提供锂离子动力电池
  5. Java 谷歌翻译 api 调用
  6. c语言自学基础知识视频,C语言 基础课堂视频教程
  7. Quartus II三种方式实现D触发器
  8. systemtap分析软raid io拆分问题
  9. java计算器功能_java实现简易计算器功能
  10. python实现杨辉三角的规律_Python实现杨辉三角算法
  11. u盘文件名乱码linux,U盘文件夹变空文件夹的文件名乱码的修复方法
  12. 好消息!iPhone 4, 3GS, 3G 基带 5.14.02 和 2.10.4 已经软解
  13. sRGB,RAW图像意义
  14. python websocket实时消息推送
  15. 如何让生活充满充实感
  16. Tarena代码-一些代码碎片
  17. 《安富莱嵌入式周报》第248期:2022.01.10--2022.01.16
  18. 一般论文投稿应该注意哪些要求
  19. 华为计算机魔术,华为荣耀magic给大家变了一个魔术,想“拆穿”他吗?
  20. 电子商务计算机考试,电子商务师考试电子商务训练试题

热门文章

  1. Word高版本打开低版本显示兼容模式
  2. 华三s5000配置镜像接口_H3C S5000系列千兆以太网交换机 用户手册-5W101
  3. Adobe Lightroom Classic 2021(LR 2021)
  4. Java switch和break用法
  5. HI3861学习笔记(19)——WiFi接口使用(STA和AP模式)
  6. aot慈善币跑路了_慈善币AOT:用公益收割“韭菜”
  7. Android鹰眼轨迹追踪
  8. 遗传算法求解3D打印中零件二维排布问题(MATLAB实现)
  9. android邮箱附件传输,Android上发送带附件的邮件
  10. 无法正常打开网页的解决方法(情况一)