xiaoyong931011
2023-04-03 d5a96c3122c136d4b0c585d08e61b42e8a123743
src/main/java/cc/mrbird/febs/mall/service/impl/MemberProfitServiceImpl.java
@@ -1,9 +1,6 @@
package cc.mrbird.febs.mall.service.impl;
import cc.mrbird.febs.common.enumerates.AgentLevelEnum;
import cc.mrbird.febs.common.enumerates.DataDictionaryEnum;
import cc.mrbird.febs.common.enumerates.FlowTypeEnum;
import cc.mrbird.febs.common.enumerates.MoneyFlowTypeEnum;
import cc.mrbird.febs.common.enumerates.*;
import cc.mrbird.febs.common.utils.AppContants;
import cc.mrbird.febs.common.utils.MallUtils;
import cc.mrbird.febs.common.utils.RedisUtils;
@@ -59,6 +56,8 @@
    private final IMallMoneyFlowService mallMoneyFlowService;
    private final MallMqRecordMapper mallMqRecordMapper;
    private final AgentProducer agentProducer;
    private final MallScoreRecordMapper mallScoreRecordMapper;
    private final MallScoreAchieveReleaseMapper mallScoreAchieveReleaseMapper;
    @Override
    @Transactional(rollbackFor = Exception.class)
@@ -789,4 +788,298 @@
        }
    }
    @Override
    public void scoreRecordReleaseJob() {
        /**
         * 每日按照比例释放记录的百分比到用户的绿色凭证账户
         */
        //获取全部剩余数量大于零的记录
        List<MallScoreRecord> mallScoreRecords = mallScoreRecordMapper.selectList();
        if(CollUtil.isEmpty(mallScoreRecords)){
            return;
        }
        DataDictionaryCustom roleReleasePercentDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
                GreenScoreEnum.ROLE_RELEASE_PERCENT.getType(),
                GreenScoreEnum.ROLE_RELEASE_PERCENT.getCode()
        );
        if(ObjectUtil.isEmpty(roleReleasePercentDic)){
            return;
        }
        //释放比例
        BigDecimal roleReleasePercent = new BigDecimal(roleReleasePercentDic.getValue()).multiply(new BigDecimal(0.001));
        for(MallScoreRecord mallScoreRecord : mallScoreRecords){
            Long memberId = mallScoreRecord.getMemberId();
            //每日释放的绿色凭证数量 = 总数 * 释放比例
            BigDecimal scoreCnt = mallScoreRecord.getScoreCnt();
            BigDecimal scoreReleaseCnt = scoreCnt.multiply(roleReleasePercent).setScale(2,BigDecimal.ROUND_DOWN);
            BigDecimal surplusCnt = mallScoreRecord.getSurplusCnt();
            if(scoreReleaseCnt.compareTo(surplusCnt) >= 0){
                scoreReleaseCnt = surplusCnt;
            }
            if(scoreReleaseCnt.compareTo(BigDecimal.ZERO) > 0){
                releaseToMemberAndAddFlow(scoreReleaseCnt,memberId,
                        MoneyFlowTypeEnum.ROLE_RELEASE_SCORE.getValue(),mallScoreRecord.getScoreNo());
                //更新凭证记录的剩余数量
                surplusCnt = surplusCnt.subtract(scoreReleaseCnt);
                mallScoreRecord.setSurplusCnt(surplusCnt);
                mallScoreRecordMapper.updateById(mallScoreRecord);
            }
        }
    }
    @Override
    public void achieveReleaseJob() {
        /**
         * 业绩产生凭证
         *      获取每日最大产生的凭证数量
         *      获取每日总业绩
         *      获取业绩产生凭证的最大值和最小值
         *      每条业绩记录占
         */
        //获取每日总业绩
        Date profitDate = DateUtil.offset(new Date(), DateField.DAY_OF_YEAR, -1);
        BigDecimal achieveTotal = mallAchieveRecordMapper.selectAchieveTotal("D", profitDate);
        DataDictionaryCustom achieveMinDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
                GreenScoreEnum.ACHIEVE_MIN.getType(),
                GreenScoreEnum.ACHIEVE_MIN.getCode()
        );
        //业绩的最小值
        BigDecimal achieveMin = new BigDecimal(achieveMinDic.getValue() == null ? "0" : achieveMinDic.getValue());
        if(achieveTotal.compareTo(achieveMin) < 0){
            return;
        }
        DataDictionaryCustom achieveMaxDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
                GreenScoreEnum.ACHIEVE_MAX.getType(),
                GreenScoreEnum.ACHIEVE_MAX.getCode()
        );
        //业绩的最大值
        BigDecimal achieveMax = new BigDecimal(achieveMaxDic.getValue() == null ? "0" : achieveMaxDic.getValue());
        /**
         * 获取每日最大产生的凭证数量
         */
        BigDecimal achieveDailyRelease = getAchieveDailyRelease();
        if(achieveTotal.compareTo(achieveMax) < 0){
            BigDecimal divide = achieveTotal.divide(achieveMax, 2, BigDecimal.ROUND_DOWN);
            achieveDailyRelease = achieveDailyRelease.multiply(divide).setScale(2,BigDecimal.ROUND_DOWN);
        }
        /**
         * 实际每日最大产生的凭证数量
         */
        BigDecimal achieveDailyReleaseReal = BigDecimal.ZERO;
        /**
         * 业务编号
         */
        String scoreNo = MallUtils.getOrderNum("ARSX");
        /**
         * 20%给合伙人、联创
         *  5% 给联创
         *  15% 给合伙人
         */
        DataDictionaryCustom roleAchievePercentDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
                GreenScoreEnum.ROLE_ACHIEVE_PERCENT.getType(),
                GreenScoreEnum.ROLE_ACHIEVE_PERCENT.getCode()
        );
        //业绩产生凭证给创世的比例
        BigDecimal roleAchievePercent = new BigDecimal(roleAchievePercentDic.getValue() == null ? "0" : roleAchievePercentDic.getValue())
                                        .multiply(new BigDecimal(0.01));
        //创世的凭证数量
        BigDecimal roleAchieveRelease = achieveDailyRelease.multiply(roleAchievePercent).setScale(2, BigDecimal.ROUND_DOWN);
        List<MallMember> roleAchieveReleaseMembers = mallMemberMapper.selectByRole(3,1);
        if(CollUtil.isNotEmpty(roleAchieveReleaseMembers)){
            //联创拿走0.25
            BigDecimal multiply = roleAchieveRelease.multiply(new BigDecimal(0.25));
            BigDecimal memberAchieveRelease = multiply.divide(new BigDecimal(roleAchieveReleaseMembers.size()), 2, BigDecimal.ROUND_DOWN);
            if(memberAchieveRelease.compareTo(BigDecimal.ZERO) > 0){
                for(MallMember mallMember : roleAchieveReleaseMembers){
                    releaseToMemberAndAddFlow(memberAchieveRelease,mallMember.getId(),
                            MoneyFlowTypeEnum.ACHIEVE_RELEASE_SCORE_LC.getValue(),scoreNo);
                    achieveDailyReleaseReal = achieveDailyReleaseReal.add(memberAchieveRelease);
                }
            }
        }
        //合伙人拿走0.75
        List<MallMember> roleAchieveReleaseHHR = mallMemberMapper.selectByRole(4,1);
        if(CollUtil.isNotEmpty(roleAchieveReleaseHHR)){
            //合伙人拿走0.75
            BigDecimal multiply = roleAchieveRelease.multiply(new BigDecimal(0.75));
            BigDecimal memberAchieveReleaseHHR = multiply.divide(new BigDecimal(roleAchieveReleaseHHR.size()), 2, BigDecimal.ROUND_DOWN);
            if(memberAchieveReleaseHHR.compareTo(BigDecimal.ZERO) > 0){
                for(MallMember mallMember : roleAchieveReleaseHHR){
                    releaseToMemberAndAddFlow(memberAchieveReleaseHHR,mallMember.getId(),
                            MoneyFlowTypeEnum.ACHIEVE_RELEASE_SCORE_HHR.getValue(),scoreNo);
                    achieveDailyReleaseReal = achieveDailyReleaseReal.add(memberAchieveReleaseHHR);
                }
            }
        }
        /**
         * 30%按贡献点分配给所有人
         */
        DataDictionaryCustom starAchievePercentDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
                GreenScoreEnum.STAR_ACHIEVE_PERCENT.getType(),
                GreenScoreEnum.STAR_ACHIEVE_PERCENT.getCode()
        );
        //业绩产生凭证给贡献点分配给所有人
        BigDecimal starAchievePercent = new BigDecimal(starAchievePercentDic.getValue() == null ? "0" : starAchievePercentDic.getValue())
                .multiply(new BigDecimal(0.01));
        //贡献点的凭证数量
        BigDecimal starAchieveRelease = achieveDailyRelease.multiply(starAchievePercent).setScale(2, BigDecimal.ROUND_DOWN);
        BigDecimal starSumCnt = mallMemberWalletMapper.selectSumStar();
        if(starSumCnt.compareTo(BigDecimal.ZERO) > 0){
            //每一个贡献点获取的凭证
            BigDecimal starAchieveReleaseOne = starAchieveRelease.divide(starSumCnt, 2, BigDecimal.ROUND_DOWN);
            List<MallMemberWallet> mallMemberWallets = mallMemberWalletMapper.selectStar();
            if(CollUtil.isNotEmpty(mallMemberWallets) && starAchieveReleaseOne.compareTo(BigDecimal.ZERO) > 0){
                for(MallMemberWallet mallMemberWallet : mallMemberWallets){
                    //每个人获取的凭证 = 贡献点 * 每一个贡献点值的凭证
                    BigDecimal bigDecimal = starAchieveReleaseOne.multiply(new BigDecimal(mallMemberWallet.getStar())).setScale(2, BigDecimal.ROUND_DOWN);
                    releaseToMemberAndAddFlow(bigDecimal,mallMemberWallet.getMemberId(),
                            MoneyFlowTypeEnum.ACHIEVE_RELEASE_SCORE_GXD.getValue(),scoreNo);
                    achieveDailyReleaseReal = achieveDailyReleaseReal.add(bigDecimal);
                }
            }
        }
        /**
         * 50%按按星级分配给所有人
         * 二星  30%
         * 三星  25%
         * 四星  20%
         * 五星  15%
         * 六星  10%
         */
        DataDictionaryCustom levelAchievePercentDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
                GreenScoreEnum.LEVEL_ACHIEVE_PERCENT.getType(),
                GreenScoreEnum.LEVEL_ACHIEVE_PERCENT.getCode()
        );
        //业绩产生凭证给星级分配给所有人
        BigDecimal levelAchievePercent = new BigDecimal(levelAchievePercentDic.getValue() == null ? "0" : levelAchievePercentDic.getValue())
                .multiply(new BigDecimal(0.01));
        //业绩产生凭证给星级分配给所有人总数
        BigDecimal levelAchieveRelease = achieveDailyRelease.multiply(levelAchievePercent).setScale(2, BigDecimal.ROUND_DOWN);
        BigDecimal thirdRelease = releaseByLevel(levelAchieveRelease, AgentLevelEnum.THIRD_LEVEL.getCode(), new BigDecimal(0.3),scoreNo);
        achieveDailyReleaseReal = achieveDailyReleaseReal.add(thirdRelease);
        BigDecimal fourRelease = releaseByLevel(levelAchieveRelease, AgentLevelEnum.FOUR_LEVEL.getCode(), new BigDecimal(0.25),scoreNo);
        achieveDailyReleaseReal = achieveDailyReleaseReal.add(fourRelease);
        BigDecimal fiveRelease = releaseByLevel(levelAchieveRelease, AgentLevelEnum.FIFTH_LEVEL.getCode(), new BigDecimal(0.2),scoreNo);
        achieveDailyReleaseReal = achieveDailyReleaseReal.add(fiveRelease);
        BigDecimal sixRelease = releaseByLevel(levelAchieveRelease, AgentLevelEnum.SIX_LEVEL.getCode(), new BigDecimal(0.15),scoreNo);
        achieveDailyReleaseReal = achieveDailyReleaseReal.add(sixRelease);
        BigDecimal sevenRelease = releaseByLevel(levelAchieveRelease, AgentLevelEnum.SEVEN_LEVEL.getCode(), new BigDecimal(0.1),scoreNo);
        achieveDailyReleaseReal = achieveDailyReleaseReal.add(sevenRelease);
        if(achieveDailyReleaseReal.compareTo(BigDecimal.ZERO) > 0){
            DataDictionaryCustom surplusCntDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
                    GreenScoreEnum.SURPLUS_CNT.getType(),
                    GreenScoreEnum.SURPLUS_CNT.getCode()
            );
            //绿色积分剩余数量
            BigDecimal surplusCnt = new BigDecimal(surplusCntDic.getValue() == null ? "0" : surplusCntDic.getValue());
            BigDecimal subtract = surplusCnt.subtract(achieveDailyReleaseReal).setScale(2,BigDecimal.ROUND_DOWN);
            surplusCntDic.setValue(subtract.toString());
            dataDictionaryCustomMapper.updateById(surplusCntDic);
        }
        log.info("昨日实际业绩:{},昨日凭证总共:{},实际产生凭证:{}",
                achieveTotal,achieveDailyRelease,achieveDailyReleaseReal);
        MallScoreAchieveRelease mallScoreAchieveRelease = new MallScoreAchieveRelease();
        mallScoreAchieveRelease.setAchieve(achieveTotal);
        mallScoreAchieveRelease.setReleaseNo(scoreNo);
        mallScoreAchieveRelease.setVoucherExpect(achieveDailyRelease);
        mallScoreAchieveRelease.setVoucherReal(achieveDailyReleaseReal);
        mallScoreAchieveReleaseMapper.updateById(mallScoreAchieveRelease);
    }
    /**
     * 给用户的增加凭证数据,并且增加流水
     * @param memberAchieveRelease 释放数量
     * @param memberId 用户ID
     * @param Type 流水类型
     * @param flowNo 流水编号
     */
    private void releaseToMemberAndAddFlow(BigDecimal memberAchieveRelease,Long memberId,int Type,String flowNo){
        //释放到用户的账户
        mallMemberWalletMapper.addVorCherCntByMemberId(memberAchieveRelease,memberId);
        //产生一条流水记录 TODO 需要去掉注释
        mallMoneyFlowService.addMoneyFlow(
                memberId,
                memberAchieveRelease,
                Type,
                flowNo,
                FlowTypeEnum.VOUCHER_CNT.getValue());
    }
    /**
     *  根据星级等级和占比,给该星级的用户释放凭证
     * @param levelAchieveRelease
     * @param level
     * @param percent
     * @return
     */
    private BigDecimal releaseByLevel(BigDecimal levelAchieveRelease,String level,BigDecimal percent,String scoreNo){
        //实际支付的凭证数量
        BigDecimal levelReleaseReal = BigDecimal.ZERO;
        //当前星级的人数
        List<MallMember> levelMembers = mallMemberMapper.selectMemberWithLevel(level);
        if(CollUtil.isNotEmpty(levelMembers)){
            //这个星级该获得的凭证数量 = 总数 * 比例
            BigDecimal levelReleaseCnt = levelAchieveRelease.multiply(percent).setScale(2, BigDecimal.ROUND_DOWN);
            if(levelReleaseCnt.compareTo(BigDecimal.ZERO) > 0){
                //每个人获得的数量
                BigDecimal levelRelease = levelReleaseCnt.divide(new BigDecimal(levelMembers.size()), 2, BigDecimal.ROUND_DOWN);
                if(levelRelease.compareTo(BigDecimal.ZERO) > 0){
                    for(MallMember mallMember : levelMembers){
                        releaseToMemberAndAddFlow(levelRelease,mallMember.getId(),MoneyFlowTypeEnum.ACHIEVE_RELEASE_SCORE_XJ.getValue(),scoreNo);
                        levelReleaseReal.add(levelRelease);
                    }
                }
            }
        }
        return levelReleaseReal;
    }
    /**
     * 获取每日最大产生的凭证数量
     * @return
     */
    private BigDecimal getAchieveDailyRelease(){
        DataDictionaryCustom achieveReleasePercentDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
                GreenScoreEnum.ACHIEVE_RELEASE_PERCENT.getType(),
                GreenScoreEnum.ACHIEVE_RELEASE_PERCENT.getCode()
        );
        BigDecimal achieveReleasePercent = new BigDecimal(achieveReleasePercentDic.getValue() == null ? "0" : achieveReleasePercentDic.getValue())
                .multiply(new BigDecimal(0.0001));
        DataDictionaryCustom totalCntDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
                GreenScoreEnum.TOTAL_CNT.getType(),
                GreenScoreEnum.TOTAL_CNT.getCode()
        );
        //总凭证数量
        BigDecimal totalCnt = new BigDecimal(totalCntDic.getValue() == null ? "0" : totalCntDic.getValue()).multiply(new BigDecimal(0.9));
        //获取每日最大产生的凭证数量
        BigDecimal achieveRelease = totalCnt.multiply(achieveReleasePercent);
        return achieveRelease;
    }
}