完成签到的逻辑

This commit is contained in:
LittleBoy 2022-11-21 15:31:56 +08:00
parent 7eba424661
commit 28bb3fd5d5
10 changed files with 204 additions and 3 deletions

View File

@ -1,7 +1,9 @@
package me.xiaoyan.point.api.controller;
import cn.dev33.satoken.stp.StpUtil;
import io.swagger.annotations.ApiOperation;
import me.xiaoyan.point.api.pojo.vo.SignResult;
import me.xiaoyan.point.api.service.SignRecordService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@ -9,10 +11,17 @@ import org.springframework.web.bind.annotation.RestController;
@RequestMapping("sign")
public class SignController {
private SignRecordService signRecordService;
@ApiOperation("今日签到")
@RequestMapping("today")
public SignResult signToday() {
return null;
return signRecordService.signToday(StpUtil.getLoginIdAsInt());
}
@ApiOperation("签到信息")
@RequestMapping("info")
public SignResult signInfo() {
return signRecordService.info(StpUtil.getLoginIdAsInt());
}
}

View File

@ -1,10 +1,14 @@
package me.xiaoyan.point.api.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import me.xiaoyan.point.api.pojo.Point;
import me.xiaoyan.point.api.pojo.SignRecord;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface SignRecordMapper extends BaseMapper<SignRecord> {
public int signCountByDate(@Param("uid") int uid, @Param("date") String date);
public List<SignRecord> selectRecentDaysRecord(@Param("uid") int uid,@Param("limit")int limit);
}

View File

@ -13,7 +13,7 @@ import java.util.Date;
@Data
@Accessors(chain = true)
@Builder
@Builder // 如果有builder就需要设置 @NoArgsConstructor @AllArgsConstructor
@NoArgsConstructor
@AllArgsConstructor
public class SignRecord implements Serializable {

View File

@ -8,4 +8,12 @@ import lombok.experimental.Accessors;
@Builder
@Accessors(chain = true)
public class SignResult {
/**
* 今日是否已经签到
*/
private boolean signToday;
/**
* 连续签到天数
*/
private int continuousDays;
}

View File

@ -3,7 +3,20 @@ package me.xiaoyan.point.api.service;
import com.baomidou.mybatisplus.extension.service.IService;
import me.xiaoyan.point.api.pojo.SignRecord;
import me.xiaoyan.point.api.pojo.UserInfo;
import me.xiaoyan.point.api.pojo.vo.SignResult;
public interface SignRecordService extends IService<SignRecord> {
/**
* 今日是否签到
*
* @return
*/
public SignResult signToday(int uid);
/**
* 签到信息
*
* @return
*/
public SignResult info(int uid);
}

View File

@ -1,12 +1,69 @@
package me.xiaoyan.point.api.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import me.xiaoyan.point.api.error.BizException;
import me.xiaoyan.point.api.mapper.SignRecordMapper;
import me.xiaoyan.point.api.pojo.SignRecord;
import me.xiaoyan.point.api.pojo.vo.SignResult;
import me.xiaoyan.point.api.service.PointRecordService;
import me.xiaoyan.point.api.service.SignRecordService;
import me.xiaoyan.point.api.util.DateUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.*;
@Service
public class SignRecordServiceImpl extends ServiceImpl<SignRecordMapper, SignRecord>
implements SignRecordService {
@Resource
private PointRecordService pointRecordService;
public boolean todayIsSign(int uid) {
return this.getBaseMapper().signCountByDate(uid, DateUtils.today()) > 0;
}
@Transactional
@Override
public SignResult signToday(int uid) {
if (todayIsSign(uid)) throw BizException.create("今日已经签过了");
// 计算连续的签到天数 连续签到积分的公式 = 天数 * 5
int days = continuousDays(uid, true);
// TODO 完成签到
SignRecord record = SignRecord.builder()
.uid(uid)
.point(5 * days)
.build();
pointRecordService.record(uid, 5 * days, "签到" + days + "天,获得积分");
save(record);
// 封装签到信息
return SignResult.builder()
.signToday(true)
.continuousDays(days)
.build();
}
public int continuousDays(int uid, boolean isSign) {
// 如果是签到数据则只查6天否则查询7天
final List<SignRecord> signRecords = this.getBaseMapper().selectRecentDaysRecord(uid, isSign ? 6 : 7);
List<Date> dates = new ArrayList<>();
if (isSign) {
dates.add(new Date());
}
signRecords.forEach(it -> dates.add(it.getCreateTime()));
Date[] dateArr = new Date[dates.size()];
return DateUtils.continuousDays(dates.toArray(dateArr));
}
@Override
public SignResult info(int uid) {
return SignResult.builder()
.signToday(todayIsSign(uid)) // 今天是否签到
.continuousDays(continuousDays(uid, false))
.build();
}
}

View File

@ -0,0 +1,54 @@
package me.xiaoyan.point.api.util;
import lombok.SneakyThrows;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateUtils {
private final static SimpleDateFormat full = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
private final static SimpleDateFormat date = new SimpleDateFormat("yyyy-MM-dd");
public static String today() {
return date.format(new Date());
}
public static String now() {
return full.format(new Date());
}
public static String formatDate(Date d) {
return date.format(d);
}
public static String formatDatetime(Date d) {
return full.format(d);
}
@SneakyThrows
public static Date parse(String str) {
return full.parse(str);
}
public static int continuousDays(Date[] dates) {
int totalDays = 1;
for (int i = 1;i < dates.length; i ++){
Date d1 = dates[i-1];
Date d2 = dates[i];
if(!isBetween(d1,d2)){
break;
}
totalDays ++;
}
return totalDays;
}
public static boolean isBetween(Date d1,Date d2){
// 直接获取两个日期之间的毫秒,计算
Date date1 = parse(formatDate(d1) + " 00:00:00");
Date date2 = parse(formatDate(d2) + " 00:00:00");
// 两个日期之间相差的毫秒数
long diffTimes = Math.abs(date1.getTime() - date2.getTime());
return diffTimes <= 24 * 3600 * 1000;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 230 KiB

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="me.xiaoyan.point.api.mapper.SignRecordMapper">
<select id="signCountByDate" resultType="java.lang.Integer">
select count(*)
from points_sys.sign_record
where date(create_time) = #{date}
and uid = #{uid}
</select>
<select id="selectRecentDaysRecord" resultType="me.xiaoyan.point.api.pojo.SignRecord">
select *
from points_sys.sign_record
where date(create_time) >= date_sub(curdate(), interval 7 day)
and uid = #{uid}
order by create_time desc
limit #{limit};
</select>
</mapper>

View File

@ -0,0 +1,38 @@
package me.xiaoyan.point.api;
import me.xiaoyan.point.api.util.DateUtils;
import org.junit.jupiter.api.Test;
import org.springframework.util.Assert;
import java.util.Date;
public class DateTests {
@Test
void testBetween() {
Date d1 = DateUtils.parse("2022-11-21 12:12:12");
Date d2 = DateUtils.parse("2022-11-20 11:11:11");
Date d3 = DateUtils.parse("2022-11-22 11:11:11");
Assert.isTrue(
DateUtils.isBetween(d1, d2), "不是相邻的"
);
Assert.isTrue(
!DateUtils.isBetween(d3, d2), "是相邻的"
);
}
@Test
void testContinuousDays() {
Date d1 = DateUtils.parse("2022-11-22 12:12:12");
Date d2 = DateUtils.parse("2022-11-21 11:11:11");
Date d3 = DateUtils.parse("2022-11-20 11:11:11");
Date d4 = DateUtils.parse("2022-11-18 11:11:11");
Date d5 = DateUtils.parse("2022-11-17 11:11:11");
// 连续天数
int days = DateUtils.continuousDays(
new Date[]{d1, d2, d3, d4, d5}
);
System.out.println("连续天数" + days);
Assert.isTrue(days == 3, "连续天数不正确");
}
}