文章目录
- BitMap用法
- 签到功能
- 签到统计
BitMap用法
其实数据库完全可以实现签到功能
但签到数据比较大,借鉴签到卡的思想
布隆过滤器也是使用BitMap实现的.
签到功能
因为是当前用户的当天,所以保存需要的年月日不需要参数,可以直接获取。
@Override
public Result sign() {
// 1. 获取当前登录用户
Long userId = UserHolder.getUser().getId();
// 2. 获取日期
LocalDateTime now = LocalDateTime.now();
// 3. 拼接Key
String keySuffix = now.format(DateTimeFormatter.ofPattern(":yyyyMM"));
String key = USER_SIGN_KEY + userId + keySuffix;
// 4. 获取今天是本月的第几天
int dayOfMonth = now.getDayOfMonth();
// 5. 写入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();
// 2. 获取日期
LocalDateTime now = LocalDateTime.now();
// 3. 拼接Key
String keySuffix = now.format(DateTimeFormatter.ofPattern(":yyyyMM"));
String key = USER_SIGN_KEY + userId + keySuffix;
// 4. 获取今天是本月的第几天
int dayOfMonth = now.getDayOfMonth();
// 5. 获取本月截至今天为止所有的签到记录, 返回一个十进制数字
List<Long> result = stringRedisTemplate.opsForValue().bitField(
key,
BitFieldSubCommands.create().get(BitFieldSubCommands.BitFieldType.unsigned(dayOfMonth)).valueAt(0)
);
if(result == null || result.isEmpty()){
return Result.ok();
}
Long num = result.get(0);
if(num == null || num == 0){
return Result.ok();
}
// 6. 循环遍历,统计1的个数
int count = 0;
while(num != 0){
if((num & 1) == 1){
count++;
}else{
break; // 因为是连续签到,缺勤的就结束统计
}
num >>>= 1;
}
return Result.ok(count);
}