@Override
public void sign() {
// 通过redis存储签到信息
// key : sign:年月:用户id
String yearAndMonth = DateUtils.formatDate(new Date(), "yyyyMM");
// Integer uid = TokenUtils.getUidFromToken();
// 通过ThreadLocal获取用户id
Integer uid = UserUtils.getUid();
String signKey = String.format(RedisKeyEnum.KEY_SIGN.getKey(), yearAndMonth, uid);
// offset是从0开始,本例中从1开始记录,offset是1表示1号,依次类推
Long day = Long.valueOf(LocalDate.now().getDayOfMonth());
boolean ret = RedisUtils.getBit(signKey, day);
if (ret) {
throw new RuntimeException("今日已签到");
}
RedisUtils.setBit(signKey, day);
// 签到成功送积分
// 从积分规则表中查询签到送多少积分,
// PointRule pointRule = pointRuleService.ruleInfoByType(PointTypeEnum.TYPE_SIGN.getType());
// 使用redis缓存规则数据后的逻辑
List<PointRule> pointRules = pointRuleService.ruleList();
PointRule pointRule = pointRules.stream()
.filter(item -> item.getPointType().equals(PointTypeEnum.TYPE_SIGN.getType()))
.findFirst()
.orElse(null);
threadPoolExecutor.execute(() -> {
PointInfo info = new PointInfo();
info.setUid(uid);
info.setPoint(pointRule.getPoint());
info.setPointType(PointTypeEnum.TYPE_SIGN.getType());
// 然后向积分记录表中添加数据
try {
pointInfoService.addPointInfo(info);
} catch (Exception e) {
// e.printStackTrace();
PointRetry retry = new PointRetry();
retry.setUid(uid);
retry.setPoint(pointRule.getPoint());
retry.setPointType(PointTypeEnum.TYPE_SIGN.getType());
pointRetryService.addRetry(retry);
}
});
// 进行连续签到判断
// 使用bitfield命令获取指定范围的二进制数据,内部转为long类型数据返回
Long v = RedisUtils.bitfield(signKey, day.intValue(), 1);
// 计算连续签到的天数,(方案:1将数据转为二进制字符串,2位运算)
String s = Long.toBinaryString(v);
int continueDay = 0;
for (int i = s.length() - 1; i >= 0; i--) {
char c = s.charAt(i);
if (c == '1') {
continueDay++;
continue;
}
break;
}
// 根据连续签到天数额外送积分
PointRule pointRule2 = pointRuleService.ruleInfoByType(PointTypeEnum.TYPE_CONTINUE_SIGN.getType());
String days = pointRule2.getDays();
// 将json字符串转为列表对象
// 第二个参数:列表中元素的类型
List<ContinueDayInfo> continueDayInfos = JSON.parseArray(days, ContinueDayInfo.class);
int finalContinueDay = continueDay;
// 借助stream流来查找数据
ContinueDayInfo dayInfo = continueDayInfos.stream()
.filter(item -> item.getDays().equals(finalContinueDay))
.findFirst()
.orElse(null);
// 如果找到对应的连续签到天数的数据,赠送积分
if (dayInfo != null) {
PointInfo info2 = new PointInfo();
info2.setUid(uid);
info2.setPoint(dayInfo.getPoint());
info2.setPointType(PointTypeEnum.TYPE_CONTINUE_SIGN.getType());
// 然后向积分记录表中添加数据
pointInfoService.addPointInfo(info2);
}
// for (ContinueDayInfo dayInfo : continueDayInfos) {
// if (dayInfo.getDays().equals(continueDay)) {
// // 送积分
// break;
// }
// }
}