今天就跟大家聊聊有关使用SpringBoot 实现一个签到奖励功能,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。
前言
最近在做社交业务,用户进入APP后有签到功能,签到成功后获取相应的奖励:
项目状况:前期尝试业务阶段;
特点:
用户签到:
提到签到,脑海中首先浮现特点:
需求&流程设计&技术实现方案
需求原型图
查询签到记录
进行签到
技术实现方案
数据库表结构
签到记录最新表
CREATE TABLE `zh_sign_in` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `bu_no` varchar(32) DEFAULT NULL COMMENT '业务编码', `customer_id` varchar(32) DEFAULT NULL COMMENT '签到用户编码', `sign_in_date` datetime DEFAULT NULL COMMENT '签到日期(单位精确到日)', `reward_money` int(11) DEFAULT NULL COMMENT '本次签到奖励金币个数', `continuite_day` int(2) DEFAULT '1' COMMENT '连续签到天数(A:7天内如果有断签从0开始 B:7天签满从0开始)', `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `update_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间', `param1` int(2) DEFAULT NULL COMMENT '预留字段1', `param2` int(4) DEFAULT NULL COMMENT '预留字段2', `param3` int(11) DEFAULT NULL COMMENT '预留字段3', `param4` varchar(20) DEFAULT NULL COMMENT '预留字段4', `param5` varchar(32) DEFAULT NULL COMMENT '预留字段5', `param6` varchar(64) DEFAULT NULL COMMENT '预留字段6', PRIMARY KEY (`id`) USING BTREE, UNIQUE KEY `uk_zh_sign_in_buno` (`bu_no`), UNIQUE KEY `uk_zh_sign_in_cid_signindate` (`customer_id`,`sign_in_date`) USING BTREE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户签到表';
签到记录历史表
CREATE TABLE `zh_sign_in_hist` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `bu_no` varchar(32) DEFAULT NULL COMMENT '业务编码', `customer_id` varchar(32) DEFAULT NULL COMMENT '签到用户编码', `sign_in_date` datetime NULL DEFAULT NULL COMMENT '签到日期(单位精确到日)', `reward_money` int(11) DEFAULT NULL COMMENT '本次签到奖励金币个数', `continuite_day` int(2) DEFAULT '1' COMMENT '连续签到天数(A:7天内如果有断签从0开始 B:7天签满从0开始)', `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `update_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间', `param1` int(2) DEFAULT NULL COMMENT '预留字段1', `param2` int(4) DEFAULT NULL COMMENT '预留字段2', `param3` int(11) DEFAULT NULL COMMENT '预留字段3', `param4` varchar(20) DEFAULT NULL COMMENT '预留字段4', `param5` varchar(32) DEFAULT NULL COMMENT '预留字段5', `param6` varchar(64) DEFAULT NULL COMMENT '预留字段6', PRIMARY KEY (`id`) USING BTREE, UNIQUE KEY `uk_zh_sign_in_hist_cid_signindate` (`customer_id`,`sign_in_date`) USING BTREE, KEY `key_zh_sign_in_hist_buno` (`bu_no`) USING BTREE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户签到历史表';
代码实现
完整代码(GitHub,欢迎大家Star,Fork,Watch)
https://github.com/dangnianchuntian/springboot
主要代码展示
Controller
/* * Copyright (c) 2020. zhanghan_java@163.com All Rights Reserved. * 项目名称:Spring Boot实战:签到奖励实现方案 * 类名称:SignInController.java * 创建人:张晗 * 联系方式:zhanghan_java@163.com * 开源地址: https://github.com/dangnianchuntian/springboot * 博客地址: https://zhanghan.blog.csdn.net */ package com.zhanghan.zhsignin.controller; import com.zhanghan.zhsignin.controller.request.PostSignInRequest; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import com.zhanghan.zhsignin.controller.request.ListSignInDetailRequest; import com.zhanghan.zhsignin.service.SignInService; @RestController public class SignInController { @Autowired private SignInService signInService; /** * 查询签到记录 */ @RequestMapping(value = "/list/sign/in/detail", method = RequestMethod.POST) public Object listSignInDetail(@RequestBody @Validated ListSignInDetailRequest listSignInDetailRequest) { return signInService.listSignInDetail(listSignInDetailRequest); } /** * 用户进行签到 */ @RequestMapping(value = "/post/sign/in", method = RequestMethod.POST) public Object postSignIn(@RequestBody @Validated PostSignInRequest postSignInRequest) { return signInService.postSignIn(postSignInRequest); } }
service
/* * Copyright (c) 2020. zhanghan_java@163.com All Rights Reserved. * 项目名称:Spring Boot实战:签到奖励实现方案 * 类名称:SignInServiceImpl.java * 创建人:张晗 * 联系方式:zhanghan_java@163.com * 开源地址: https://github.com/dangnianchuntian/springboot * 博客地址: https://zhanghan.blog.csdn.net */ package com.zhanghan.zhsignin.service.impl; import cn.hutool.core.util.IdUtil; import com.zhanghan.zhsignin.config.SignInRewardMoneyListConfig; import com.zhanghan.zhsignin.constant.SignInConstant; import com.zhanghan.zhsignin.controller.request.ListSignInDetailRequest; import com.zhanghan.zhsignin.controller.request.PostSignInRequest; import com.zhanghan.zhsignin.controller.response.ListSignInDetailResponse; import com.zhanghan.zhsignin.mybatis.entity.XZhSignInEntity; import com.zhanghan.zhsignin.mybatis.entity.XZhSignInHistEntity; import com.zhanghan.zhsignin.mybatis.mapper.XZhSignInHistMapper; import com.zhanghan.zhsignin.mybatis.mapper.XZhSignInMapper; import com.zhanghan.zhsignin.service.SignInService; import com.zhanghan.zhsignin.util.DateUtils; import com.zhanghan.zhsignin.util.wrapper.WrapMapper; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import java.util.Date; import java.util.List; import java.util.stream.Collectors; import static com.zhanghan.zhsignin.constant.SignInConstant.*; @Service public class SignInServiceImpl implements SignInService { @Autowired private XZhSignInMapper xZhSignInMapper; @Autowired private XZhSignInHistMapper xZhSignInHistMapper; //校验连续天数是否为7 @Value("#{T(java.lang.Integer).parseInt('${zh.sign.in.continuite.day.threshold:7}')}") public Integer continuiteDayThreshold; //签到奖励金币集合配置 @Autowired public SignInRewardMoneyListConfig signInRewardMoneyListConfig; /** * 查询用户签到记录 */ @Override public Object listSignInDetail(ListSignInDetailRequest listSignInDetailRequest) { //若配置文件中未配置签到奖励则不展示签到记录 List<Integer> signInRewardMoneyListConfigList = signInRewardMoneyListConfig.getList(); if (CollectionUtils.isEmpty(signInRewardMoneyListConfigList)) { return WrapMapper.ok(new ListSignInDetailResponse(false)); } String customerId = listSignInDetailRequest.getCustomerId(); XZhSignInEntity xZhSignInEntity = xZhSignInMapper.findByCustomerId(customerId); List<ListSignInDetailResponse.SignInDetail> signInDetailList = signInRewardMoneyListConfigList.stream().map(aa -> new ListSignInDetailResponse.SignInDetail(0, aa)).collect(Collectors.toList()); //该用户之前未签到过 if (null == xZhSignInEntity) { return WrapMapper.ok(new ListSignInDetailResponse(TODAY_NOT_SIGN_IN, SignInConstant.CONTINUITE_DAY_ZERO, signInDetailList)); } long signInDateTime = xZhSignInEntity.getSignInDate().getTime(); //最近一次签到是否为昨日之前 if (signInDateTime < DateUtils.getYesterdayDateTime()) { return WrapMapper.ok(new ListSignInDetailResponse(TODAY_NOT_SIGN_IN, SignInConstant.CONTINUITE_DAY_ZERO, signInDetailList)); } //最近一次签到是否为昨日 Integer todaySignStatus = TODAY_YES_SIGN_IN; Integer continuiteDay = xZhSignInEntity.getContinuiteDay(); if (signInDateTime < DateUtils.getTodayDateTime()) { //最近一次签到是昨日且之前已连续签到7日 if (continuiteDay >= continuiteDayThreshold) { return WrapMapper.ok(new ListSignInDetailResponse(TODAY_NOT_SIGN_IN, SignInConstant.CONTINUITE_DAY_ZERO, signInDetailList)); } //最近一次签到是昨日且之前连续未超7日 todaySignStatus = TODAY_NOT_SIGN_IN; } //查询用户签到历史记录 List<XZhSignInHistEntity> xZhSignInHistEntitieList = xZhSignInHistMapper.listByCustomerIdAndLimit(customerId, continuiteDay); for (XZhSignInHistEntity xZhSignInHistEntity : xZhSignInHistEntitieList) { ListSignInDetailResponse.SignInDetail signInDetail = new ListSignInDetailResponse.SignInDetail(TODAY_YES_SIGN_IN, xZhSignInHistEntity.getRewardMoney()); signInDetailList.remove(xZhSignInHistEntity.getContinuiteDay() - 1); signInDetailList.add(xZhSignInHistEntity.getContinuiteDay() - 1, signInDetail); } return WrapMapper.ok(new ListSignInDetailResponse(todaySignStatus, continuiteDay, signInDetailList)); } /** * 进行签到 */ @Override public Object postSignIn(PostSignInRequest postSignInRequest) { //若配置文件中未配置签到奖励则不展示签到记录 List<Integer> signInRewardMoneyListConfigList = signInRewardMoneyListConfig.getList(); if (CollectionUtils.isEmpty(signInRewardMoneyListConfigList)) { return WrapMapper.ok(); } //获取session用户对象 String customerId = postSignInRequest.getCustomerId(); //根据customerId查询用户签到记录 XZhSignInEntity xZhSignInEntityByCustomerId = xZhSignInMapper.findByCustomerId(customerId); //签到记录是否为空 if (null == xZhSignInEntityByCustomerId) { XZhSignInEntity xZhSignInEntity = new XZhSignInEntity(); xZhSignInEntity.setBuNo(IdUtil.simpleUUID()); xZhSignInEntity.setCustomerId(customerId); xZhSignInEntity.setContinuiteDay(CONTINUITE_DAY_ONE); xZhSignInEntity.setRewardMoney(signInRewardMoneyListConfigList.get(0)); xZhSignInEntity.setSignInDate(DateUtils.getTodayDate()); insertSigninAndHist(xZhSignInEntity); return WrapMapper.ok(); } long signInDateTime = xZhSignInEntityByCustomerId.getSignInDate().getTime(); if (signInDateTime == DateUtils.getTodayDateTime()) { return WrapMapper.error("今天已经签到"); } //获取连续签到天数 Integer continuiteDay = continuiteDay(xZhSignInEntityByCustomerId.getContinuiteDay(), signInDateTime); xZhSignInEntityByCustomerId.setSignInDate(DateUtils.getTodayDate()); xZhSignInEntityByCustomerId.setContinuiteDay(continuiteDay); xZhSignInEntityByCustomerId.setRewardMoney(signInRewardMoneyListConfigList.get(continuiteDay - 1)); xZhSignInEntityByCustomerId.setUpdateTime(new Date()); xZhSignInEntityByCustomerId.setBuNo(IdUtil.simpleUUID()); updateSignInAndInsertHist(xZhSignInEntityByCustomerId); return WrapMapper.ok(); } private Integer continuiteDay(Integer continuiteDay, Long signInDateTime) { if (signInDateTime < DateUtils.getYesterdayDateTime()) { return CONTINUITE_DAY_ONE; } if (continuiteDay >= continuiteDayThreshold) { return CONTINUITE_DAY_ONE; } return continuiteDay + 1; } private void insertSigninAndHist(XZhSignInEntity xZhSignInEntity) { xZhSignInMapper.insertSelective(xZhSignInEntity); XZhSignInHistEntity xZhSignInHistEntity = new XZhSignInHistEntity(); BeanUtils.copyProperties(xZhSignInEntity, xZhSignInHistEntity); xZhSignInHistEntity.setId(null); xZhSignInHistMapper.insertSelective(xZhSignInHistEntity); } private void updateSignInAndInsertHist(XZhSignInEntity xZhSignInEntity) { xZhSignInMapper.updateByPrimaryKeySelective(xZhSignInEntity); XZhSignInHistEntity xZhSignInHistEntity = new XZhSignInHistEntity(); BeanUtils.copyProperties(xZhSignInEntity, xZhSignInHistEntity); xZhSignInHistEntity.setId(null); xZhSignInHistMapper.insertSelective(xZhSignInHistEntity); } }
测试
模拟用户进行签到
进行请求
查看数据库结果
模拟用户查询签到记录
进行请求
总结
看完上述内容,你们对使用SpringBoot 实现一个签到奖励功能有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注亿速云行业资讯频道,感谢大家的支持。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。