签到功能
@Component
public class SignService {
@Autowired
private StringRedisTemplate stringRedisTemplate;
/**
* 当天签到
*
* @param userId
*/
public void sign(Long userId) {
//获取日期
LocalDateTime now = LocalDateTime.now();
//获取key
String keySuffix = now.format(DateTimeFormatter.ofPattern(":yyyyMM"));
String key = "sign:" + userId + keySuffix;
//今天是本月的第几天
int dayOfMonth = now.getDayOfMonth();
//写入Redis
stringRedisTemplate.opsForValue().setBit(key, dayOfMonth - 1, true);
}
}
签到统计
/**
* 统计已经累计签到了几天
* @param userId
* @return
*/
public int signCount(Long userId) {
//获取日期
LocalDateTime now = LocalDateTime.now();
//获取key
String keySuffix = now.format(DateTimeFormatter.ofPattern(":yyyyMM"));
String key = "sign:" + userId + keySuffix;
//今天是本月的第几天
int dayOfMonth = now.getDayOfMonth();
//获取本月戒指今天为止的所有签到记录,返回的是十进制数字, BITFEILD key GET u14 0
List<Long> result = stringRedisTemplate.opsForValue().bitField(key,
BitFieldSubCommands.create()
.get(BitFieldSubCommands.BitFieldType.unsigned(dayOfMonth)).valueAt(0));
if (CollectionUtil.isEmpty(result)) {
return 0;
}
Long num = result.get(0);
if (num == null || num == 0) {
return 0;
}
int count = 0;
//循环遍历
while (true) {
//让这个数字与1做运算,得到数字最后的一个bit位,判断这个bit是否为0
if ((num & 1) == 0) {
//如果为0,说明未签到,结束
break;
} else {
//如果不为0,说明已签到,计数器+1
count++;
}
//把数字右移一位,抛弃最后一个bit位,继续下一个bit位 >>>无符号右移
num >>>= 1;
}
return count;
}