服务层代码
//签到
@Override
public Result sign() {
//1.获取当前登录的用户
Long userId = UserHolder.getUser().getId();
//获取日期
LocalDateTime now = LocalDateTime.now();
//拼接key
String keySuffix = now.format(DateTimeFormatter.ofPattern(":yyyyMM"));
String key = USER_SIGN_KEY + userId + keySuffix;
//获取今天是本月的第几天
int dayOfMonth = now.getDayOfMonth();
//写入Redis SETBIT key offset 1
stringRedisTemplate.opsForValue().setBit(key, dayOfMonth - 1, true);
return Result.ok();
}
//统计连续签到
@Override
public Result signCount() {
//1.获取当前登录的用户
Long userId = UserHolder.getUser().getId();
//获取日期
LocalDateTime now = LocalDateTime.now();
//拼接key
String keySuffix = now.format(DateTimeFormatter.ofPattern(":yyyyMM"));
String key = USER_SIGN_KEY + userId + keySuffix;
//获取今天是本月的第几天
int dayOfMonth = now.getDayOfMonth();
//获取本月截止今天为止的所有签到记录,返回的是一个十进制的数字 BITFIELD sign:5:202409 GET u14 0 14为要查多少位即当月为几号 0为从1号开始查
List<Long> result = stringRedisTemplate.opsForValue().bitField(
key,
BitFieldSubCommands.create().get(BitFieldSubCommands.BitFieldType.unsigned(dayOfMonth)).valueAt(0)
);
if (result == null || result.isEmpty()){
//没有任何签到结果
return Result.ok(0);
}
Long num = result.get(0);
if(num == null || num == 0){
return Result.ok(0);
}
//循环遍历
int count = 0;
while(true){
//让这个数据与1作与运算,得到数字的最后一个bit位 判断这个bit位是否为0
if((num & 1) == 0){
//如果为0,说明未签到,结束
break;
} else {
//如果为1,说明已签到,计数器加1
count++;
}
num >>>= 1;
}
return Result.ok(count);
}