Bootstrap

签到送金币项目

@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;
//            }
//        }

    }
;