springboot 7天签到功能设计 数据库表设计 加代码

您所在的位置:网站首页 淘宝签到自动断签 springboot 7天签到功能设计 数据库表设计 加代码

springboot 7天签到功能设计 数据库表设计 加代码

2023-10-16 19:19| 来源: 网络整理| 查看: 265

实现一个类似于这样的签到功能 (参考的百度网盘签到页面)

数据表是一个用户只有一条签到记录的设计, 没有使用签到一次表中加一条数据, 那样的话数据太多了

签到有中断,下一次签到重新从第一天开始计算连续签到天数

表结构:

CREATE TABLE `sign_in` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键', `user_id` bigint(20) NOT NULL COMMENT '签到用户id', `continue_days` int(3) NOT NULL DEFAULT '1' COMMENT '连续签到天数', `update_time` datetime DEFAULT NULL COMMENT '更新日期, 最后签到日期', PRIMARY KEY (`id`) USING BTREE, UNIQUE KEY `user_id_unique` (`user_id`) USING BTREE ) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='用户签到表';

实体对象:

import com.baomidou.mybatisplus.annotation.FieldFill; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.fasterxml.jackson.annotation.JsonFormat; import lombok.Data; import lombok.NoArgsConstructor; import java.time.LocalDateTime; /** * 用户签到表 * * @author lixx * @version 1.0 * @date 2020-06-10 10:36 */ @Data @NoArgsConstructor public class SignIn { /** * 主键 */ @TableId(type = IdType.AUTO) private Long id; /** * 签到用户id */ private Long userId; /** * 连续签到天数 */ private Integer continueDays; /** * 更新日期, 最后签到日期 */ @JsonFormat(pattern = "yyyy-MM-dd HH:mm") @TableField(fill = FieldFill.UPDATE) private LocalDateTime updateTime; public SignIn(Long userId, LocalDateTime updateTime) { this.userId = userId; this.updateTime = updateTime; } }

签到接口:

/** * 用户签到 * * @param userId 用户id * @return */ public JsonResult signIn(Long userId) { // 查询用户是否签过到 QueryWrapper queryWrapper = new QueryWrapper(); queryWrapper.lambda().eq(SignIn::getUserId, userId); SignIn signIn = signInMapper.selectOne(queryWrapper); /*没有签过到, 直接新增*/ if (null == signIn) { signInMapper.insert(new SignIn(userId, LocalDateTime.now())); } else {/*签过到*/ // 判断最后签到日期与当前日期是否超过一天 LocalDate signInTime = signIn.getUpdateTime().toLocalDate(); LocalDate currTime = LocalDate.now(); long daysDiff = ChronoUnit.DAYS.between(signInTime, currTime); if (daysDiff 1) { // 1, 超过一天, 把连续签到的天数重置为 1 signIn.setContinueDays(1); } else { // 2, 没有超过一天, 把连续签到的天数+1 signIn.setContinueDays(signIn.getContinueDays() + 1); } signIn.setUpdateTime(LocalDateTime.now()); signInMapper.updateById(signIn); } return JsonResult.buildSuccess(); }

这样签到功能就做好了, 数据库数据如下:

签到列表接口:

需要增加一个接口返回的dto类型(大家用map也行)

import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import java.io.Serializable; /** * @author lixx * @version 1.0 * @date 2020-06-10 15:09 */ @Data @NoArgsConstructor @AllArgsConstructor public class SignInDto implements Serializable { /** * 表示签到的天数 */ private Integer day; /** * 1表示已经签到, 0表示未签到 */ private Integer flag; // 如果还有其他业务字段就加在后面, 如积分, 如金币 }

签到列表接口逻辑代码:

/** * 用户签到列表 * * @param userId 用户id * @return */ public JsonResult signInList(Long userId) { QueryWrapper queryWrapper = new QueryWrapper(); queryWrapper.lambda().eq(SignIn::getUserId, userId); SignIn signIn = signInMapper.selectOne(queryWrapper); List list = new ArrayList(7); if (null == signIn) { // 没有签过到 for (int i = 1; i < 8; i++) { list.add(new SignInDto(i, 0)); } } else { // 签过到 Integer continueDays = signIn.getContinueDays(); // 1, 前六天的 flag是要固定的 if (continueDays -1) { list.add(new SignInDto(continueDays - i, 1)); } else { list.add(new SignInDto(continueDays + 1, 0)); } } } } return JsonResult.buildSuccess(list); }

效果如下:

1:签到第五天的时候

2:签到第7天的时候

3:签到第N天的时候

ps: 每天凌晨要把未连续签到用户的连续签到天数(sign_in表的continue_days字段)设置为0, 我这里使用的是数据库定时任务, 大家也可以使用代码的定时任务,看个人选择

/*定时任务*/ -- 每天凌晨重置超过时间未签到的连续签到天数为0 CREATE EVENT IF NOT EXISTS reset_expired_signins ON SCHEDULE EVERY 1 DAY STARTS DATE_ADD(DATE_ADD(CURDATE(), INTERVAL 1 DAY), INTERVAL 5 MINUTE) ON COMPLETION PRESERVE ENABLE -- 更新语句 DO UPDATE sign_in SET continue_days = 0 WHERE id IN ( SELECT a.id FROM ( SELECT id FROM sign_in WHERE DATEDIFF(CURDATE(), update_time) > 1 ) AS a )



【本文地址】


今日新闻


推荐新闻


    CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3