admin
2022-10-28 0e9b6603d4ae9d11c1fbc90257ce816c5807b8ff
app/src/main/java/com/yeshi/makemoney/app/service/impl/goldcorn/GoldCornMakeServiceImpl.java
@@ -1,6 +1,7 @@
package com.yeshi.makemoney.app.service.impl.goldcorn;
import com.ks.lib.common.exception.ParamsException;
import com.yeshi.makemoney.app.dto.goldcorn.GoldCornMakeResultDTO;
import com.yeshi.makemoney.app.entity.config.SystemConfigKey;
import com.yeshi.makemoney.app.entity.goldcorn.*;
import com.yeshi.makemoney.app.entity.money.UserMoneyRecord;
@@ -22,8 +23,11 @@
import com.yeshi.makemoney.app.utils.factory.UserMoneyRecordFactory;
import com.yeshi.makemoney.app.utils.factory.goldcorn.GoldCornConsumeRecordFactory;
import com.yeshi.makemoney.app.utils.goldcorn.GoldCornUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.yeshi.utils.TimeUtil;
import org.yeshi.utils.annotation.RequestSerializableByKey;
@@ -32,6 +36,8 @@
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
 * @author hxh
@@ -41,6 +47,7 @@
 */
@Service
public class GoldCornMakeServiceImpl implements GoldCornMakeService {
    Logger taskLogger = LoggerFactory.getLogger("taskLog");
    @Resource
    private GoldCornGetFrequencyConfigService goldCornGetFrequencyConfigService;
@@ -49,7 +56,7 @@
    private GoldCornGetRecordService goldCornGetRecordService;
    @Resource
    private RedisTemplate<String, String> redisTemplate;
    private RedisTemplate<String, Object> redisTemplate;
    @Resource
    private GoldCornGetPriceService goldCornGetPriceService;
@@ -67,7 +74,17 @@
    private UserMoneyRecordService userMoneyRecordService;
    private void frequencyVerify(UserInfo user, GoldCornGetType type, Date time) throws GoldCornGetFrequencyConfigException, GoldCornMakeException {
    /**
     * @return int 当前时间段还剩余的事件数量
     * @author hxh
     * @description 频率限制
     * @date 11:02 2022/4/28
     * @param: user
     * @param: type
     * @param: time
     **/
    @Override
    public long frequencyVerify(UserInfo user, GoldCornGetType type, Date time) throws GoldCornGetFrequencyConfigException, GoldCornMakeException {
        GoldCornGetFrequencyConfig config = goldCornGetFrequencyConfigService.getConfig(user.getSystem(), type, time);
        if (config == null) {
            throw new GoldCornGetFrequencyConfigException(GoldCornGetFrequencyConfigException.CODE_NOT_EXIST, "频率配置不存在");
@@ -78,42 +95,51 @@
        query.setUid(user.getId());
        query.setType(type);
        //间隔判断
        if (config.getMinSpaceTime() != null) {
            List<GoldCornGetRecord> list = goldCornGetRecordService.list(query, 1, 1);
            if (list != null && list.size() > 0 && System.currentTimeMillis() - list.get(0).getCreateTime().getTime() < config.getMinSpaceTime() * 1000L) {
                String msg = String.format("需要间隔%s秒以上", config.getMinSpaceTime());
                throw new GoldCornMakeException(GoldCornMakeException.CODE_GET_FREQUENCY_LIMIT, msg);
        try {
            //间隔判断
            if (config.getMinSpaceTime() != null) {
                List<GoldCornGetRecord> list = goldCornGetRecordService.list(query, 1, 1);
                if (list != null && list.size() > 0 && time.getTime() - list.get(0).getCreateTime().getTime() < config.getMinSpaceTime() * 1000L) {
                    String msg = String.format("需要间隔%s秒以上", config.getMinSpaceTime());
                    throw new GoldCornMakeException(GoldCornMakeException.CODE_GET_FREQUENCY_TIME_LIMIT, msg);
                }
            }
        }
        Date startTime = null;
        Date endTime = time;
        if (config.getTimeUnit() == GoldCornGetFrequencyConfig.GoldCornGetFrequencyTimeUnit.minute) {
            startTime = new Date(TimeUtil.convertToTimeTemp(TimeUtil.getGernalTime(endTime.getTime(), "yyyyMMdd HHmm"), "yyyyMMdd HHmm"));
        } else if (config.getTimeUnit() == GoldCornGetFrequencyConfig.GoldCornGetFrequencyTimeUnit.hour) {
            startTime = new Date(TimeUtil.convertToTimeTemp(TimeUtil.getGernalTime(endTime.getTime(), "yyyyMMdd HH"), "yyyyMMdd HH"));
        } else if (config.getTimeUnit() == GoldCornGetFrequencyConfig.GoldCornGetFrequencyTimeUnit.day) {
            startTime = new Date(TimeUtil.convertToTimeTemp(TimeUtil.getGernalTime(endTime.getTime(), "yyyyMMdd"), "yyyyMMdd"));
        } else if (config.getTimeUnit() == GoldCornGetFrequencyConfig.GoldCornGetFrequencyTimeUnit.week) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTimeInMillis(endTime.getTime());
            int subDay = (Calendar.getInstance().get(Calendar.DAY_OF_WEEK) - 2 + 7) % 7;
            startTime = new Date(TimeUtil.convertToTimeTemp(TimeUtil.getGernalTime(endTime.getTime() - 1000 * 60 * 60 * 24L * subDay, "yyyyMMdd"), "yyyyMMdd"));
        } else if (config.getTimeUnit() == GoldCornGetFrequencyConfig.GoldCornGetFrequencyTimeUnit.month) {
            startTime = new Date(TimeUtil.convertToTimeTemp(TimeUtil.getGernalTime(endTime.getTime(), "yyyyMM"), "yyyyMM"));
        } else if (config.getTimeUnit() == GoldCornGetFrequencyConfig.GoldCornGetFrequencyTimeUnit.year) {
            startTime = new Date(TimeUtil.convertToTimeTemp(TimeUtil.getGernalTime(endTime.getTime(), "yyyy"), "yyyy"));
        }
        query.setFormat("yyyyMMdd HH:mm:ss");
        query.setStartTime(TimeUtil.getGernalTime(startTime.getTime(), query.getFormat()));
        //service里面有减去1天
        query.setEndTime(TimeUtil.getGernalTime(endTime.getTime() - 1000 * 60 * 60 * 24L, query.getFormat()));
            Date startTime = null;
            Date endTime = time;
            if (config.getTimeUnit() == GoldCornGetFrequencyConfig.GoldCornGetFrequencyTimeUnit.minute) {
                startTime = new Date(TimeUtil.convertToTimeTemp(TimeUtil.getGernalTime(endTime.getTime(), "yyyyMMdd HHmm"), "yyyyMMdd HHmm"));
            } else if (config.getTimeUnit() == GoldCornGetFrequencyConfig.GoldCornGetFrequencyTimeUnit.hour) {
                startTime = new Date(TimeUtil.convertToTimeTemp(TimeUtil.getGernalTime(endTime.getTime(), "yyyyMMdd HH"), "yyyyMMdd HH"));
            } else if (config.getTimeUnit() == GoldCornGetFrequencyConfig.GoldCornGetFrequencyTimeUnit.day) {
                startTime = new Date(TimeUtil.convertToTimeTemp(TimeUtil.getGernalTime(endTime.getTime(), "yyyyMMdd"), "yyyyMMdd"));
            } else if (config.getTimeUnit() == GoldCornGetFrequencyConfig.GoldCornGetFrequencyTimeUnit.week) {
                Calendar calendar = Calendar.getInstance();
                calendar.setTimeInMillis(endTime.getTime());
                int subDay = (Calendar.getInstance().get(Calendar.DAY_OF_WEEK) - 2 + 7) % 7;
                startTime = new Date(TimeUtil.convertToTimeTemp(TimeUtil.getGernalTime(endTime.getTime() - 1000 * 60 * 60 * 24L * subDay, "yyyyMMdd"), "yyyyMMdd"));
            } else if (config.getTimeUnit() == GoldCornGetFrequencyConfig.GoldCornGetFrequencyTimeUnit.month) {
                startTime = new Date(TimeUtil.convertToTimeTemp(TimeUtil.getGernalTime(endTime.getTime(), "yyyyMM"), "yyyyMM"));
            } else if (config.getTimeUnit() == GoldCornGetFrequencyConfig.GoldCornGetFrequencyTimeUnit.year) {
                startTime = new Date(TimeUtil.convertToTimeTemp(TimeUtil.getGernalTime(endTime.getTime(), "yyyy"), "yyyy"));
            }
            query.setFormat("yyyyMMdd HH:mm:ss");
            query.setStartTime(TimeUtil.getGernalTime(startTime.getTime(), query.getFormat()));
            //service里面有减去1天
            query.setEndTime(TimeUtil.getGernalTime(endTime.getTime() - 1000 * 60 * 60 * 24L, query.getFormat()));
        long count = goldCornGetRecordService.count(query);
        if (count >= config.getLimitCount()) {
            String msg = String.format("超出%s次/%s的限制", config.getLimitCount(), config.getTimeUnit().getName());
            throw new GoldCornMakeException(GoldCornMakeException.CODE_GET_FREQUENCY_LIMIT, msg);
            Map<GoldCornGetType, Long> countMap = goldCornGetRecordService.sumEventCount(query);
            if (countMap.get(type) != null && (countMap.get(type) >= config.getLimitCount())) {
                String msg = String.format("超出%s次/%s的限制", config.getLimitCount(), config.getTimeUnit().getName());
                throw new GoldCornMakeException(GoldCornMakeException.CODE_GET_FREQUENCY_COUNT_LIMIT, msg);
            }
            return config.getLimitCount() - (countMap.get(type) != null ? countMap.get(type) : 0);
        } catch (GoldCornMakeException e) {
            //频率限制
            taskLogger.error("#频率受限# uid:{} type:{} time:{}  msg:{}", user.getId(), type.name(), TimeUtil.getGernalTime(time.getTime(), "yyyy-MM-dd HH:mm:ss SSS"), e.getMsg());
            throw e;
        }
    }
@@ -121,7 +147,7 @@
    @RequestSerializableByKey(key = "'addgoldcorn-'+#uid+'-'+#type")
    @Override
    public GoldCornGetRecord addGoldCorn(Long uid, GoldCornGetType type, boolean isDouble, Date currentTime, Integer price) throws UserInfoException, GoldCornGetPriceException, GoldCornGetFrequencyConfigException, GoldCornMakeException {
    public GoldCornGetRecord addGoldCorn(Long uid, GoldCornGetType type, boolean isDouble, Date currentTime, Integer price, Long eventCount) throws UserInfoException, GoldCornGetFrequencyConfigException, GoldCornMakeException {
        if (uid == null || type == null || currentTime == null) {
            throw new GoldCornMakeException(GoldCornMakeException.CODE_PARAMS_NOT_ENOUGH, "参数不完整");
        }
@@ -129,40 +155,33 @@
        if (user == null) {
            throw new UserInfoException(UserInfoException.CODE_NOT_EXIST, "用户不存在");
        }
        //判断是否超出了次数限制
        frequencyVerify(user, type, currentTime);
        //获取价格
        GoldCornGetPrice getPrice = goldCornGetPriceService.getPrice(user.getSystem(), type, currentTime);
        if (price == null) {
            throw new GoldCornGetPriceException(GoldCornGetPriceException.CODE_NOT_EXIST, "价格信息缺失");
        }
        GoldCornGetPrice getPrice = goldCornGetPriceService.getPrice(user.getSystem(), GoldCornGetType.watchVideo, currentTime);
        //基础价格,外部传入的价格优先
        int baseCornNum = (price != null ? price : getPrice.getCornNum());
        //是否加入团队
        Long bossUid = teamInviteRelationService.getBossUid(uid);
        if (bossUid != null) {
            baseCornNum = new BigDecimal(baseCornNum).multiply(new BigDecimal(1).add(getPrice.getTeamGainRate())).intValue();
        }
        //单价由外面传入
        int baseCornNum = price;
        GoldCornGetRecord record = new GoldCornGetRecord();
        record.setCornNum(baseCornNum);
        record.setDay(TimeUtil.getGernalTime(currentTime.getTime(), "yyyy-MM-dd"));
        record.setType(type);
        record.setUid(uid);
        record.setSystem(user.getSystem());
        record.setLevel(GoldCornGetRecord.LEVEL_OWN);
        record.setCreateTime(currentTime);
        record.setEventCount(eventCount);
        GoldCornGetRecord recordD = null;
        if (isDouble) {
            recordD = new GoldCornGetRecord();
            recordD.setCornNum(baseCornNum);
            record.setSystem(user.getSystem());
            recordD.setDay(TimeUtil.getGernalTime(currentTime.getTime(), "yyyy-MM-dd"));
            recordD.setType(type);
            recordD.setUid(uid);
            recordD.setLevel(GoldCornGetRecord.LEVEL_OWN);
            recordD.setCreateTime(currentTime);
            recordD.setDubble(true);
            recordD.setEventCount(eventCount);
        }
        //允许上级提成
@@ -174,12 +193,14 @@
            }
            //是否有上级
            if (getPrice.getTeamDivide() != null && getPrice.getTeamDivide()) {
                Long bossUid = teamInviteRelationService.getBossUid(user.getId());
                if (bossUid != null) {
                    BigDecimal rate = new BigDecimal(systemConfigService.getValueCache(user.getSystem(), SystemConfigKey.teamFirstDivideRate));
                    GoldCornGetRecord cRecord = new GoldCornGetRecord();
                    cRecord.setDay(record.getDay());
                    cRecord.setType(type);
                    cRecord.setUid(bossUid);
                    record.setSystem(user.getSystem());
                    cRecord.setCornNum(new BigDecimal(baseCornNum).multiply(rate).intValue());
                    cRecord.setFromId(record.getId());
                    cRecord.setFromUid(record.getUid());
@@ -189,22 +210,22 @@
                        goldCornGetRecordService.add(cRecord);
                    }
                    //是否有上上级
                    bossUid = teamInviteRelationService.getBossUid(bossUid);
                    if (bossUid != null) {
                        rate = new BigDecimal(systemConfigService.getValueCache(user.getSystem(), SystemConfigKey.teamSecondDivideRate));
                        GoldCornGetRecord ccRecord = new GoldCornGetRecord();
                        ccRecord.setDay(record.getDay());
                        ccRecord.setType(type);
                        ccRecord.setUid(bossUid);
                        ccRecord.setFromId(record.getId());
                        ccRecord.setFromUid(record.getUid());
                        ccRecord.setCornNum(new BigDecimal(baseCornNum).multiply(rate).intValue());
                        ccRecord.setLevel(GoldCornGetRecord.LEVEL_SECOND);
                        ccRecord.setCreateTime(currentTime);
                        if (ccRecord.getCornNum() > 0) {
                            goldCornGetRecordService.add(ccRecord);
                        }
                    }
//                    bossUid = teamInviteRelationService.getBossUid(bossUid);
//                    if (bossUid != null) {
//                        rate = new BigDecimal(systemConfigService.getValueCache(user.getSystem(), SystemConfigKey.teamSecondDivideRate));
//                        GoldCornGetRecord ccRecord = new GoldCornGetRecord();
//                        ccRecord.setDay(record.getDay());
//                        ccRecord.setType(type);
//                        ccRecord.setUid(bossUid);
//                        ccRecord.setFromId(record.getId());
//                        ccRecord.setFromUid(record.getUid());
//                        ccRecord.setCornNum(new BigDecimal(baseCornNum).multiply(rate).intValue());
//                        ccRecord.setLevel(GoldCornGetRecord.LEVEL_SECOND);
//                        ccRecord.setCreateTime(currentTime);
//                        if (ccRecord.getCornNum() > 0) {
//                            goldCornGetRecordService.add(ccRecord);
//                        }
//                    }
                }
            }
        } catch (GoldCornGetRecordException e) {
@@ -231,8 +252,8 @@
            if (count == 0L) {
                continue;
            }
            //获取兑换记录的主键ID
            GoldCornConsumeRecord record = GoldCornConsumeRecordFactory.createExchange(uid, GoldCornUtil.getFormatDay(date), 0, new BigDecimal(0.1));
            //获取兑换记录的主键ID,不需要多余的数据
            GoldCornConsumeRecord record = GoldCornConsumeRecordFactory.createExchange(uid, GoldCornUtil.getFormatDay(date), 0, new BigDecimal(0.1), null);
            //查询资金记录是否有该记录
            try {
                UserMoneyRecord userMoneyRecord = UserMoneyRecordFactory.createGoldCornExchange(record);
@@ -256,8 +277,13 @@
        Date now = new Date();
        //查询今日是否已经签到
        boolean isSignIn = isSignIn(uid, now);
        Date deadDate = now;
        if (!isSignIn) {
            deadDate = new Date(TimeUtil.convertToTimeTemp(TimeUtil.getGernalTime(now.getTime(), "yyyyMMdd"), "yyyyMMdd"));
        }
        //今日未签到的,查询连续签到次数应该从前一天开始计算
        int continueDay = goldCornGetRecordService.getContinueDay(uid, GoldCornGetType.signIn, !isSignIn ? new Date(now.getTime() - 1000 * 60 * 60 * 24L) : now);
        int continueDay = goldCornGetRecordService.getContinueDay(uid, GoldCornGetType.signIn, deadDate);
        return continueDay;
    }
@@ -275,11 +301,144 @@
    public GoldCornGetRecord signIn(Long uid) throws GoldCornGetFrequencyConfigException, UserInfoException, GoldCornGetPriceException, GoldCornMakeException {
        UserInfo user = userInfoService.get(uid);
        Date now = new Date();
        //判断是否超出了次数限制
        long leftCount = frequencyVerify(user, GoldCornGetType.signIn, now);
        //获取连续签到次数
        Integer price = goldCornGetPriceService.getSingInPrice(user.getSystem(), getContinueSignDay(uid) + 1);
        return addGoldCorn(uid, GoldCornGetType.signIn, false, now, price, 1L);
    }
    @Transactional(rollbackFor = Exception.class)
    @Override
    public GoldCornMakeResultDTO watchVideo(Long uid, boolean isDouble, Date time, long timeSeconds) throws GoldCornGetPriceException, UserInfoException, GoldCornMakeException, GoldCornGetFrequencyConfigException {
        UserInfo user = userInfoService.get(uid);
        if (user == null) {
            throw new UserInfoException(UserInfoException.CODE_NOT_EXIST, "用户不存在");
        }
        //判断是否超出了次数限制
        long leftCount = frequencyVerify(user, GoldCornGetType.watchVideo, time);
        timeSeconds = timeSeconds > leftCount ? leftCount : timeSeconds;
        Integer price = goldCornGetPriceService.getCountPrice(GoldCornGetType.watchVideo, user, user.getSystem(), time, timeSeconds);
        //价格为0时不加入记录
        if (price == 0) {
            return new GoldCornMakeResultDTO(0, leftCount);
        }
        GoldCornGetRecord record = addGoldCorn(uid, GoldCornGetType.watchVideo, isDouble, time, price, (long) timeSeconds);
        return new GoldCornMakeResultDTO(record.getCornNum() * (isDouble ? 2 : 1), leftCount - timeSeconds);
    }
    @Transactional(rollbackFor = Exception.class)
    @Override
    public GoldCornMakeResultDTO readNovel(Long uid, boolean isDouble, Date time, long timeSeconds) throws GoldCornGetPriceException, UserInfoException, GoldCornMakeException, GoldCornGetFrequencyConfigException {
        String readNovelCacheKey = "task-n-" + uid + "-" + TimeUtil.getGernalTime(System.currentTimeMillis(), "yyyyMMdd");
        long readNovelNowSeconds = timeSeconds;
        Integer start = (Integer) redisTemplate.opsForValue().get(readNovelCacheKey);
        if (start == null) {
            start = 0;
        }
        timeSeconds = timeSeconds - start;
        UserInfo user = userInfoService.get(uid);
        if (user == null) {
            throw new UserInfoException(UserInfoException.CODE_NOT_EXIST, "用户不存在");
        }
        //判断是否超出了次数限制
        long leftCount = frequencyVerify(user, GoldCornGetType.readNovel, time);
        timeSeconds = timeSeconds > leftCount ? leftCount : timeSeconds;
        Integer price = goldCornGetPriceService.getCountPrice(GoldCornGetType.readNovel, user, user.getSystem(), time, timeSeconds);
        //价格为0时不加入记录
        if (price == 0) {
            return new GoldCornMakeResultDTO(0, leftCount);
        }
        GoldCornGetRecord record = addGoldCorn(uid, GoldCornGetType.readNovel, isDouble, time, price, (long) timeSeconds);
        //记录当天的实时阅读分钟数
        redisTemplate.opsForValue().set(readNovelCacheKey, readNovelNowSeconds, 60 * 60 * 24, TimeUnit.SECONDS);
        return new GoldCornMakeResultDTO(record.getCornNum() * (isDouble ? 2 : 1), leftCount - timeSeconds);
    }
    @Transactional(rollbackFor = Exception.class)
    @Override
    public GoldCornMakeResultDTO scanNews(Long uid, boolean isDouble, Date time, int num) throws GoldCornGetPriceException, UserInfoException, GoldCornMakeException, GoldCornGetFrequencyConfigException {
        //防刷机制
        if (num < 0) {
            num = 0;
        }
        //1个很大的数
        if (num > 20) {
            num = 1;
        }
        return addGoldCorn(uid, GoldCornGetType.signIn, false, new Date(), price);
        UserInfo user = userInfoService.get(uid);
        if (user == null) {
            throw new UserInfoException(UserInfoException.CODE_NOT_EXIST, "用户不存在");
        }
        //判断是否超出了次数限制
        long leftCount = frequencyVerify(user, GoldCornGetType.scanNews, time);
        Integer price = goldCornGetPriceService.getCountPrice(GoldCornGetType.scanNews, user, user.getSystem(), time, num);
        //价格为0时不加入记录
        if (price == 0) {
            return new GoldCornMakeResultDTO(0, leftCount);
        }
        GoldCornGetRecord record = addGoldCorn(uid, GoldCornGetType.scanNews, isDouble, time, price, (long) num);
        return new GoldCornMakeResultDTO(record.getCornNum() * (isDouble ? 2 : 1), leftCount - num);
    }
    @Override
    public GoldCornMakeResultDTO inviteFriends(Long uid, UserInfo friendInfo, Date time) throws UserInfoException, GoldCornGetPriceException, GoldCornMakeException, GoldCornGetFrequencyConfigException {
        UserInfo user = userInfoService.get(uid);
        if (user == null) {
            throw new UserInfoException(UserInfoException.CODE_NOT_EXIST, "用户不存在");
        }
        //判断是否超出了次数限制
        long leftCount = frequencyVerify(user, GoldCornGetType.invite, time);
        Integer price = goldCornGetPriceService.getCountPrice(GoldCornGetType.invite, user, user.getSystem(), time, 1);
        //价格为0时不加入记录
        if (price == 0) {
            return new GoldCornMakeResultDTO(0, leftCount);
        }
        GoldCornGetRecord record = addGoldCorn(uid, GoldCornGetType.invite, false, time, price, (long) price);
        return new GoldCornMakeResultDTO(record.getCornNum(), leftCount - 1);
    }
    @Override
    public GoldCornMakeResultDTO extract(Long uid, Date time) throws UserInfoException, GoldCornGetPriceException, GoldCornMakeException, GoldCornGetFrequencyConfigException {
        UserInfo user = userInfoService.get(uid);
        if (user == null) {
            throw new UserInfoException(UserInfoException.CODE_NOT_EXIST, "用户不存在");
        }
        //判断是否超出了次数限制
        long leftCount = frequencyVerify(user, GoldCornGetType.extract, time);
        Integer price = goldCornGetPriceService.getCountPrice(GoldCornGetType.extract, user, user.getSystem(), time, 1);
        //价格为0时不加入记录
        if (price == 0) {
            return new GoldCornMakeResultDTO(0, leftCount);
        }
        GoldCornGetRecord record = addGoldCorn(uid, GoldCornGetType.extract, false, time, price, (long) price);
        return new GoldCornMakeResultDTO(record.getCornNum(), leftCount - 1);
    }