package com.hzs.bonus.bonus.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.json.JSONUtil;
import com.hzs.activity.pick.IAcPickServiceApi;
import com.hzs.bonus.achieve.param.MemberAchieveParam;
import com.hzs.bonus.achieve.service.ICuMemberAchieveService;
import com.hzs.bonus.achieve.service.ICuMemberRangeService;
import com.hzs.bonus.achieve.service.ICuMemberSettlePeriodService;
import com.hzs.bonus.achieve.service.ICuMemberTreeService;
import com.hzs.bonus.base.service.ICuAwardsControlService;
import com.hzs.bonus.base.service.ICuMemberAchieveLogService;
import com.hzs.bonus.base.service.ICuMemberService;
import com.hzs.bonus.bonus.param.BdWaresBonusParam;
import com.hzs.bonus.bonus.param.BonusExpandParam;
import com.hzs.bonus.bonus.param.LeXueRangeParam;
import com.hzs.bonus.bonus.service.*;
import com.hzs.bonus.bonus.vo.BonusRecordDetailVO;
import com.hzs.bonus.bonus.vo.MemberBonusDetailCalVO;
import com.hzs.bonus.detail.service.ICuMemberAwardsService;
import com.hzs.bonus.detail.service.ICuMemberLevelService;
import com.hzs.bonus.risk.service.ICuMemberRiskControlService;
import com.hzs.bonus.swing.service.ICuMemberSwingNetLogService;
import com.hzs.common.core.config.BdConfig;
import com.hzs.common.core.constant.BonusFieldConstants;
import com.hzs.common.core.constant.CountryConstants;
import com.hzs.common.core.constant.MagicNumberConstants;
import com.hzs.common.core.constant.TableNameConstants;
import com.hzs.common.core.enums.*;
import com.hzs.common.core.utils.ComputeUtil;
import com.hzs.common.core.utils.DateUtils;
import com.hzs.common.core.utils.reflect.ReflectUtils;
import com.hzs.common.domain.bonus.risk.CuMemberRiskControl;
import com.hzs.common.domain.member.achieve.CuMemberSettlePeriod;
import com.hzs.common.domain.member.achieve.ext.CuMemberAchieveExt;
import com.hzs.common.domain.member.achieve.ext.CuMemberRangeExt;
import com.hzs.common.domain.member.base.CuAwardsControl;
import com.hzs.common.domain.member.base.CuMember;
import com.hzs.common.domain.member.bonus.*;
import com.hzs.common.domain.member.detail.CuMemberAchieveLog;
import com.hzs.common.domain.member.detail.CuMemberAssess;
import com.hzs.common.domain.member.ext.BdWaresBonusExt;
import com.hzs.common.domain.member.ext.CuBonusExpandExt;
import com.hzs.common.domain.member.ext.CuMemberSettleExt;
import com.hzs.common.domain.member.swing.ext.CuMemberSwingNetDetailExt;
import com.hzs.common.domain.member.swing.ext.CuMemberSwingNetExt;
import com.hzs.common.domain.sale.ext.SaOrderExt;
import com.hzs.common.domain.system.config.BdAwards;
import com.hzs.common.domain.system.config.BdGrade;
import com.hzs.common.domain.system.config.BdRangeAwards;
import com.hzs.member.base.IMemberServiceApi;
import com.hzs.sale.order.ISaOrderServiceApi;
import com.hzs.system.base.ISystemConfigServiceApi;
import com.hzs.system.config.IAwardsServiceApi;
import com.hzs.system.config.IBonusItemsServiceApi;
import com.hzs.system.config.IGradeServiceApi;
import com.hzs.system.config.IRangeServiceApi;
import com.hzs.system.config.dto.BonusConfigDTO;
import com.hzs.system.config.dto.GradeDTO;
import com.hzs.system.config.dto.RangeDTO;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.temporal.ChronoUnit;
import java.util.*;

/**
 * 奖金结算服务类
 */
@Service
@Slf4j
public class BonusSettleServiceImpl implements IBonusSettleService {

    @DubboReference
    ISystemConfigServiceApi iSystemConfigServiceApi;
    @DubboReference
    IGradeServiceApi iGradeServiceApi;
    @DubboReference
    IAwardsServiceApi iAwardsServiceApi;
    @DubboReference
    IRangeServiceApi iRangeServiceApi;
    @DubboReference
    IBonusItemsServiceApi iBonusItemsServiceApi;
    @DubboReference
    IMemberServiceApi iMemberServiceApi;
    @DubboReference
    ISaOrderServiceApi iSaOrderServiceApi;
    @DubboReference
    IAcPickServiceApi iAcPickServiceApi;

    @Autowired
    private ICuMemberTreeService iCuMemberTreeService;
    @Autowired
    private ICuMemberSettlePeriodService iCuMemberSettlePeriodService;
    @Autowired
    private ICuMemberAwardsService iCuMemberAwardsService;
    @Autowired
    private ICuMemberLevelService iCuMemberLevelService;
    @Autowired
    private ICuMemberService iCuMemberService;
    @Autowired
    private ICuMemberAchieveLogService iCuMemberAchieveLogService;
    @Autowired
    private ICuMemberAchieveService iCuMemberAchieveService;
    @Autowired
    private ICuAwardsControlService iCuAwardsControlService;
    @Autowired
    private ICuMemberSwingNetLogService iCuMemberSwingNetLogService;
    @Autowired
    private ICuMemberRepeatBonusService iCuMemberRepeatBonusService;
    @Autowired
    private IBdWaresBonusService iBdWaresBonusService;
    @Autowired
    private ICuBonusExpandService iCuBonusExpandService;
    @Autowired
    private ICuMemberBonusService iCuMemberBonusService;
    @Autowired
    private ICuMemberBonusPushService iCuMemberBonusPushService;
    @Autowired
    private ICuMemberBonusExpandService iCuMemberBonusExpandService;
    @Autowired
    private ICuMemberBonusCoachService iCuMemberBonusCoachService;
    @Autowired
    private ICuMemberBonusDetailService iCuMemberBonusDetailService;
    @Autowired
    private ICuMemberBonusRangeService iCuMemberBonusRangeService;
    @Autowired
    private ICuMemberRangeService iCuMemberRangeService;
    @Autowired
    private ICuMemberRiskControlService iCuMemberRiskControlService;
    @Autowired
    private ICuMemberBonusDelayService iCuMemberBonusDelayService;
    @Autowired
    private ICuMemberBonusDelayDetailService iCuMemberBonusDelayDetailService;
    @Autowired
    private BonusSettleRangeHandle bonusSettleRangeHandle;
    @Autowired
    private BonusSettleFirstPurchaseHandle bonusSettleFirstPurchaseHandle;
    @Autowired
    private BonusSettlePurchaseHandle bonusSettlePurchaseHandle;
    @Autowired
    private BonusSettleNewExpandHandle bonusSettleNewExpandHandle;
    @Autowired
    private BonusSettleHiFunHandle bonusSettleHiFunHandle;
    @Autowired
    private BonusSettleAgentHandle bonusSettleAgentHandle;
    @Autowired
    private BonusSettleRepCouponsHandle bonusSettleRepCouponsHandle;
    @Autowired
    private BonusSettleMallHandle bonusSettleMallHandle;

    // 新拓展处理时间
    private final String newExpandDate = "2025-06-01";

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void calculateCumberBonusBySecond(String orderCode) {
        log.info("开始执行秒接，订单编号：{}", orderCode);
        Date startDate = DateUtils.currentDate();
        SaOrderExt saOrderExt = iSaOrderServiceApi.querySaOrderByDay(startDate,
                DateUtils.afterDate(1, ChronoUnit.DAYS, startDate), orderCode).getData();
        Map<String, String> systemConfigMap = iSystemConfigServiceApi.getBonusSystemConfig().getData();
        Map<String, RangeDTO> rangeDtoMap = iRangeServiceApi.queryRangeDto().getData();
        // 处理奖金结算秒结表，判断是否存在当天结算的秒接表，从cu_member中获取网体，从昨日结算表中获取累计、结余数据
        String settleDate = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, saOrderExt.getPayTime());
        String beforeDay = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, DateUtils.beforeDate(1, ChronoUnit.DAYS, saOrderExt.getPayTime()));
        String beforeYesDay = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, DateUtils.beforeDate(2, ChronoUnit.DAYS, saOrderExt.getPayTime()));
        int period = iCuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(settleDate).getPkId();
        int beforePeriod = iCuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(beforeDay).getPkId();
        int beforeYesPeriod = iCuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(beforeYesDay).getPkId();
        log.info("查询订单，订单参数：{}", JSONUtil.toJsonStr(saOrderExt));
        String secondTableName = TableNameConstants.CU_MEMBER_SECOND + period;
        String settleTableName = TableNameConstants.CU_MEMBER_SETTLE + beforePeriod;
        // 前天
        String yesSettleTableName = TableNameConstants.CU_MEMBER_SETTLE + beforeYesPeriod;
        Map<Long, CuMemberBonus> cuMemberBonusMap = new HashMap<>(MagicNumberConstants.DELETE_DATA_BATCH_UPDATE_NUM);
        BonusConfigDTO bonusConfigDTO = iBonusItemsServiceApi.queryBonusConfigDTO().getData();
        Map<Long, CuMemberSettleExt> cuMemberSettleExtMap = new HashMap<>();
        Map<Long, CuAwardsControl> cuAwardsControlMap = getCuAwardsControlMap();
        List<BdAwards> awardsList = iAwardsServiceApi.queryAwards(saOrderExt.getPkCountry()).getData();
        // 计算奖金
        if (EOrderType.REGISTER_ORDER.getValue() == saOrderExt.getOrderType() ||
                EOrderType.UPGRADE_ORDER.getValue() == saOrderExt.getOrderType() ||
                EOrderType.SPECIAL_REGISTER_ORDER.getValue() == saOrderExt.getOrderType() ||
                EOrderType.SPECIAL_UPGRADE_ORDER.getValue() == saOrderExt.getOrderType()) {
            log.info("奖金秒接，首购订单，订单编号：{}", orderCode);
            // 1注册订单 直推、拓展、领导
            // 从会员表中拉数据到 cu_member_second中
            // cu_member_second没有 cu_member 网体 cu_member_settle上一期业绩
            // 直推奖 - 加首购 加首购新增，只加推荐人
            // 拓展奖 - 安置以上，进行量碰 加首购业绩，加一条线
            // 领导奖- 安置血缘以上，判断奖衔
            // 报单服务费 - 报单人
            List<Long> memberList = new ArrayList<>();
            CuMember cuMember = iCuMemberService.getMember(saOrderExt.getPkMember());
            if (cuMember.getPkCenterCode() != null && !saOrderExt.getPkReference().equals(cuMember.getPkCenterCode())) {
                memberList.add(cuMember.getPkCenterCode());
            }
            getSettleMember(saOrderExt, secondTableName, settleTableName, yesSettleTableName, memberList);
            // 查询出上面的网体数据
            List<CuMemberSettleExt> cuMemberSettleExtList = iCuMemberTreeService.queryCuMemberSecondParent(secondTableName, memberList);
            bonusSettleFirstPurchaseHandle.getSecondMemberSettle(cuMemberSettleExtMap, cuMemberSettleExtList);
            // 计算奖金
            // 计算直推奖
            List<GradeDTO> gradeDtoList = iGradeServiceApi.queryGradeConfigByCondition(saOrderExt.getPkCountry()).getData();
            CuMemberBonusPush cuMemberBonusPush = bonusSettleFirstPurchaseHandle.calculatePushBonusOne(cuMemberSettleExtMap, bonusConfigDTO, systemConfigMap, period, cuMemberBonusMap, saOrderExt, iAwardsServiceApi.getAwards().getData(), gradeDtoList);
            log.info("获得直推奖，奖金为：{}", JSONUtil.toJsonStr(cuMemberBonusPush));
            // 计算量奖
            // 所有需要计算的父节点，只计算新增
            List<CuMemberSettleExt> expandMemberSettleExtList = iCuMemberTreeService.queryCuMemberSecondPlaceParent(secondTableName, saOrderExt.getPkMember());
            bonusSettleFirstPurchaseHandle.getSecondMemberSettle(cuMemberSettleExtMap, expandMemberSettleExtList);
            Map<Long, CuMemberBonus> weekMemberBonusMap = getWeekMemberBonusMap(settleDate, period);
            Map<Long, CuMemberAssess> cuMemberAssessMap = bonusSettleFirstPurchaseHandle.getLongCuMemberAssessMap(settleDate, expandMemberSettleExtList);
            // 查询K值控制
            List<CuMemberRiskControl> cuMemberRiskControlList = iCuMemberRiskControlService.queryCuMemberRiskControl(DateUtils.parseStringToDate(settleDate));
            Map<Long, CuMemberRiskControl> riskControlMap = new HashMap<>();
            if (CollectionUtil.isNotEmpty(cuMemberRiskControlList)) {
                cuMemberRiskControlList.forEach(cuMemberRiskControl -> riskControlMap.put(cuMemberRiskControl.getPkMember(), cuMemberRiskControl));
            }
            Map<Long, CuBonusExpandExt> cuBonusExpandExtMap = new HashMap<>();
            BonusExpandParam bonusExpandParam = BonusExpandParam.builder().settleDate(DateUtils.parseStringToDate(settleDate)).build();
            List<CuBonusExpandExt> cuBonusExpandExtList = iCuBonusExpandService.queryBonusExpand(bonusExpandParam);
            cuBonusExpandExtList.forEach(cuBonusExpandExt -> cuBonusExpandExtMap.put(cuBonusExpandExt.getPkMember(), cuBonusExpandExt));
            BigDecimal addTouch = BigDecimal.ZERO;
            for (int i = expandMemberSettleExtList.size() - 1; i >= 0; i--) {
                CuMemberSettleExt cuMemberSettleExt = cuMemberSettleExtList.get(i);
                if (cuBonusExpandExtMap.containsKey(cuMemberSettleExt.getPkMember())) {
                    addTouch = cuBonusExpandExtMap.get(cuMemberSettleExt.getPkMember()).getAddTouch();
                    break;
                }
            }
            List<CuMemberBonusExpand> cuMemberBonusExpandList = bonusSettleFirstPurchaseHandle.calculateExpandBonusOne(riskControlMap, cuMemberAssessMap, settleTableName, cuMemberSettleExtMap, bonusConfigDTO, systemConfigMap, period, weekMemberBonusMap, cuMemberBonusMap, expandMemberSettleExtList, saOrderExt, false, addTouch, BigDecimal.ZERO, 0);
            // 计算领导奖
            Map<Long, SaOrderExt> saOrderExtMap = new HashMap<>(1);
            saOrderExtMap.put(saOrderExt.getPkId(), saOrderExt);

            // 领导奖现在首购、复购都有，此处需要传入参数区分
            boolean firstFlag = EOrderType.SPECIAL_REGISTER_ORDER.getValue() == saOrderExt.getOrderType()
                    || EOrderType.SPECIAL_UPGRADE_ORDER.getValue() == saOrderExt.getOrderType();
            // 领导奖处理
            List<CuMemberBonusCoach> cuMemberBonusCoachList = bonusSettleFirstPurchaseHandle.calculateCoachBonusOne(cuMemberSettleExtMap, settleTableName, settleDate, bonusConfigDTO,
                    cuMemberBonusExpandList, period, cuMemberBonusMap, saOrderExtMap, cuAwardsControlMap, riskControlMap, awardsList, firstFlag, false);

            // 计算报单服务费
            CuMemberBonusDetail cuMemberBonusDetail = bonusSettleFirstPurchaseHandle.calculateServiceBonusOne(settleDate, cuMemberAssessMap, cuMemberSettleExtMap, bonusConfigDTO, period, cuMemberBonusMap, saOrderExt);
            // 复购券
            List<CuMemberBonusDetail> couponsBonusDetailList = bonusSettleRepCouponsHandle.calculateRepurchaseCoupons(startDate, Collections.singletonList(saOrderExt), period, bonusConfigDTO, cuMemberBonusMap, cuMemberSettleExtMap);
            saveCuMemberBonus(period, settleDate, cuMemberBonusMap);
            cuMemberBonusPush.setPkBonus(cuMemberBonusMap.get(cuMemberBonusPush.getPkBonus()).getPkId());
            Set<Long> memberIdSet = iCuMemberBonusService.queryMemberBonusByPeriod(period);
            iCuMemberBonusPushService.insertCuMemberBonusPush(cuMemberBonusPush);
            cuMemberBonusExpandList.forEach(cuMemberBonusExpand ->
                    cuMemberBonusExpand.setPkBonus(cuMemberBonusMap.get(cuMemberBonusExpand.getPkBonus()).getPkId()));
            iCuMemberBonusExpandService.batchInsertCuMemberBonusExpand(cuMemberBonusExpandList, memberIdSet);

            cuMemberBonusCoachList.forEach(cuMemberBonusCoach ->
                    cuMemberBonusCoach.setPkBonus(cuMemberBonusMap.get(cuMemberBonusCoach.getPkBonus()).getPkId()));
            iCuMemberBonusCoachService.batchInsertCuMemberBonusCoach(cuMemberBonusCoachList, memberIdSet);

            List<CuMemberBonusDetail> cuMemberBonusDetailList = new ArrayList<>();
            if (cuMemberBonusDetail != null) {
                cuMemberBonusDetailList.add(cuMemberBonusDetail);
            }
            if (CollectionUtil.isNotEmpty(couponsBonusDetailList)) {
                cuMemberBonusDetailList.addAll(couponsBonusDetailList);
            }
            if (cuMemberBonusDetailList.size() > 0) {
                cuMemberBonusDetailList.forEach(bonusDetail ->
                        bonusDetail.setPkBonus(cuMemberBonusMap.get(bonusDetail.getPkBonus()).getPkId()));
                iCuMemberBonusDetailService.batchInsertCuMemberBonusDetail(cuMemberBonusDetailList, memberIdSet);
            }
            log.info("首购奖金计算完毕");
        } else {
            // 先处理关系
            List<Long> memberList = new ArrayList<>();
            getSettleMember(saOrderExt, secondTableName, yesSettleTableName, settleTableName, memberList);
            // 初始化需要秒接结算的数据
            List<CuMemberSettleExt> pushMemberSettleExtList = iCuMemberTreeService.queryCuMemberSecondParent(secondTableName, memberList);
            bonusSettleFirstPurchaseHandle.getSecondMemberSettle(cuMemberSettleExtMap, pushMemberSettleExtList);
            List<CuMemberBonusPush> cuMemberBonusPushList = bonusSettlePurchaseHandle.calculateRepurchasePushSecondBonus(settleTableName, cuMemberSettleExtMap, bonusConfigDTO, period, cuMemberBonusMap, saOrderExt, pushMemberSettleExtList, settleDate);
            // 查询出上面的网体数据
            List<CuMemberSettleExt> cuMemberSettleExtList = iCuMemberTreeService.queryCuMemberSecondPlaceParent(secondTableName, saOrderExt.getPkMember());
            bonusSettleFirstPurchaseHandle.getSecondMemberSettle(cuMemberSettleExtMap, cuMemberSettleExtList);
            Map<Long, CuMemberBonus> weekMemberBonusMap = getWeekMemberBonusMap(settleDate, period);
            // 复购订单，计算复购推荐 复购极差，复购拓展
            // 查询K值控制
            List<CuMemberRiskControl> cuMemberRiskControlList = iCuMemberRiskControlService.queryCuMemberRiskControl(DateUtils.parseStringToDate(settleDate));
            Map<Long, CuMemberRiskControl> riskControlMap = new HashMap<>();
            if (CollectionUtil.isNotEmpty(cuMemberRiskControlList)) {
                cuMemberRiskControlList.forEach(cuMemberRiskControl -> riskControlMap.put(cuMemberRiskControl.getPkMember(), cuMemberRiskControl));
            }
            List<CuMemberBonusExpand> cuMemberBonusExpandList = bonusSettlePurchaseHandle.calculateRepurchaseExpandSecondBonus(riskControlMap, settleTableName,
                    cuMemberSettleExtMap, bonusConfigDTO, systemConfigMap, period, weekMemberBonusMap, cuMemberBonusMap, saOrderExt, cuMemberSettleExtList, settleDate, BigDecimal.ZERO, BigDecimal.ZERO, 0);
            // c)增加奖衔记录表
            Map<String, BdAwards> awardsMap = iAwardsServiceApi.getAwards().getData();
            List<CuMemberBonusRange> cuMemberBonusRangeList = bonusSettlePurchaseHandle.calculateRepurchaseRangeBonus(cuMemberSettleExtMap, settleTableName, settleDate, rangeDtoMap, awardsMap,
                    bonusConfigDTO, Collections.singletonList(saOrderExt), period, cuMemberBonusMap, cuAwardsControlMap, new LeXueRangeParam());
            if (cuMemberBonusMap.size() > 0) {
                saveCuMemberBonus(period, settleDate, cuMemberBonusMap);
                Set<Long> memberIdSet = iCuMemberBonusService.queryMemberBonusByPeriod(period);
                cuMemberBonusPushList.forEach(cuMemberBonusPush ->
                        cuMemberBonusPush.setPkBonus(cuMemberBonusMap.get(cuMemberBonusPush.getPkBonus()).getPkId()));
                iCuMemberBonusPushService.batchInsertCuMemberBonusPush(cuMemberBonusPushList, memberIdSet);
                cuMemberBonusExpandList.forEach(cuMemberBonusExpand ->
                        cuMemberBonusExpand.setPkBonus(cuMemberBonusMap.get(cuMemberBonusExpand.getPkBonus()).getPkId()));
                iCuMemberBonusExpandService.batchInsertCuMemberBonusExpand(cuMemberBonusExpandList, memberIdSet);
                cuMemberBonusRangeList.forEach(cuMemberBonusRange ->
                        cuMemberBonusRange.setPkBonus(cuMemberBonusMap.get(cuMemberBonusRange.getPkBonus()).getPkId()));
                iCuMemberBonusRangeService.batchInsertCuMemberBonusRange(cuMemberBonusRangeList, memberIdSet);
            }
            log.info("复购奖金计算完毕");
        }
        // 更新网体结构
        if (cuMemberSettleExtMap.size() > 0) {
            // 处理网体，更新网体新增 轮次最小值  cuMemberSettleExtMap
            iCuMemberTreeService.updateCuMemberSecond(secondTableName, cuMemberSettleExtMap);
        }
        // 1获取业绩，做一张新表，计算过奖金的放进去 2当天没有计算过奖金的，直接根据昨天日表获取业绩放进去进行计算
        // 根据网体数据计算奖金
    }

    private void getSettleMember(SaOrderExt saOrderExt, String secondTableName, String settleTableName, String yesSettleTableName, List<Long> memberList) {
        // 先处理关系
        memberList.add(saOrderExt.getPkMember());
        long pkParent = saOrderExt.getPkReference();
        while (true) {
            CuMember cuMember = iCuMemberService.getMember(pkParent);
            if (cuMember == null) {
                break;
            }
            memberList.add(cuMember.getPkId());
            pkParent = cuMember.getPkParent();
        }
        // 初始化需要秒接结算的数据
        iCuMemberTreeService.updateCuMemberSecondPlaceParent(secondTableName, settleTableName, yesSettleTableName, saOrderExt.getPkMember(), memberList, EYesNo.YES.getIntValue());
    }

    /**
     * 保存会员奖金
     *
     * @param cuMemberBonusMap 奖金map
     * @return: CuMemberBonus 奖金
     */
    protected void saveCuMemberBonus(int period, String settleDate, Map<Long, CuMemberBonus> cuMemberBonusMap) {
        // 保存奖金
        List<CuMemberBonus> cuMemberBonusList = setCuMemberBonusSeq(settleDate, cuMemberBonusMap);
        // 插入奖金主表
        iCuMemberBonusService.insertOrUpdateCuMemberBonus(cuMemberBonusList);
        List<CuMemberBonus> cuMemberBonuses = iCuMemberBonusService.queryCuMemberBonus(period, cuMemberBonusList);
        cuMemberBonuses.forEach(cuMemberBonus -> cuMemberBonusMap.put(cuMemberBonus.getPkMember(), cuMemberBonus));
    }

    /**
     * @Description: 每日计算会员奖金，最终的奖金
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void calculateCuMemberBonus(String settleDate, List<SaOrderExt> saOrderExtList) {
        try {
            // 今天期间
            Integer period = iCuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(settleDate).getPkId();
            // 会员结算日表（cu_member_settle） + 期间
            String currentSettleTableName = TableNameConstants.CU_MEMBER_SETTLE + period;

            // 昨日期间
            String yesterday = DateUtils.beforeDateStr(1, ChronoUnit.DAYS, DateUtils.YYYY_MM_DD, settleDate);
            Integer yesterdayPeriod = iCuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(yesterday).getPkId();

            // 查询日期-1的网体数据，从日历史表中获得
            String yesterdayTableName = TableNameConstants.CU_MEMBER_SETTLE + yesterdayPeriod;
            validateSettleTable(yesterday, yesterdayTableName);
            // 将结算日昨日业绩数据 迁移到 网体业绩历史记录结算表（cu_member_settle）
            iCuMemberTreeService.initCuMemberTreeTable(yesterdayTableName, currentSettleTableName);

            // 国家奖衔map
            Map<String, BdAwards> awardsMap = iAwardsServiceApi.getAwards().getData();
            // 等级map
            Map<Integer, BdGrade> gradeMap = iGradeServiceApi.getGrade().getData();

            // 查看是否有特殊业务，有特殊业务的处理，特殊业务，注水处理
            List<CuMemberAchieveLog> cuMemberAchieveLogList = iCuMemberAchieveLogService.queryMemberAchieveLogByPeriod(period);
            // 有特殊业务
            if (cuMemberAchieveLogList.size() > 0) {
                cuMemberAchieveLogList.forEach(cuMemberAchieveLog -> iCuMemberAchieveService.updateCuMemberSettleAchieveBySpecialBus(currentSettleTableName, period, cuMemberAchieveLog.getPkId()));
            }
            // 注水到期回退
            iCuMemberAchieveService.mergeCuMemberSettleByAchieveLogByDate(currentSettleTableName, DateUtils.parseStringToDate(settleDate));
            // 判断特殊业务是否有到期日期，有到期的需要使用真实业绩，昨天的期间真实更新当前的
            iCuMemberAchieveService.updateCuMemberSettleAchieveByDueDate(currentSettleTableName, yesterdayTableName, DateUtils.parseStringToDate(settleDate));

            // TODO 2025.05.14 新拓展处理在2025.06.01之前还是走原来的1：1对碰，之后走1：2对碰
            // true 走新逻辑（首购+复购 合并计算）
            boolean newExpandFlag = settleDate.compareTo(newExpandDate) >= 0;
            if (EEnv.TEST.getValue().equals(BdConfig.getEnv())) {
                newExpandFlag = settleDate.compareTo("2025-05-20") >= 0;
            }

            // 根据日期开始计算网体 + 业绩
            //********************* 更新网体*************/
            // 按照订单时间开始奖金结算，当订单类型为注册订单需要进行上网，更新网体
            // 根据订单开始更新业绩
            // 订单按照体系开始分类
//        Map<Long, List<SaOrderExt>> saOrderMap = new HashMap<>(ComputeUtil.mapInitCapacity(saOrderExtList.size()));
            // 退单需要处理
            // 用于记录每天的撤单、退单数据数据，7天的网体均变为死点
            List<SaOrderExt> revokeRegSaOrderList = new ArrayList<>();
            List<SaOrderExt> revokeUpdSaOrderList = new ArrayList<>();

            // 区分体系，体系按照多线程进行更新业绩
            // 首购订单 （注册+升级） 直推奖、量奖、领导奖、（注册）报单服务费
            // 复购订单  (复购量奖、复购极差)
            // 其他订单 只累计业绩 仅算奖衔
            // 云代奖金 1% 待考虑
            // 首购订单
            List<SaOrderExt> firPurchaseOrderList = new ArrayList<>();
            // 复购订单
            List<SaOrderExt> repurchaseOrderList = new ArrayList<>();
            // 商城订单
            List<SaOrderExt> mallOrderList = new ArrayList<>();
            // 拓展收益订单 -- 2025.05.13 拓展收益比例改为1：2，首购+复购业绩合并计算
            List<SaOrderExt> expandOrderList = newExpandFlag ? new ArrayList<>() : null;
            // 特殊订单，目前乐学易考
            // 其他订单 注意，累计业绩已经在计算奖衔前累计完成，不需要在计算累计业绩，只需要计算新增跟结余过滤掉其他订单
            saOrderExtList.forEach(saOrderExt -> {
                //根据订单状态回退网体,查询撤销订单, 撤销订单不进行结算
                if (saOrderExt.getDelFlag() == EYesNo.NO.getIntValue()) {
                    if (Objects.equals(EOrderType.REGISTER_ORDER.getValue(), saOrderExt.getOrderType())) {
                        revokeRegSaOrderList.add(saOrderExt);
                    } else if (Objects.equals(EOrderType.UPGRADE_ORDER.getValue(), saOrderExt.getOrderType())) {
                        revokeUpdSaOrderList.add(saOrderExt);
                    }
                    return;
                }
                packageSaOrderListByType(firPurchaseOrderList, repurchaseOrderList, mallOrderList, saOrderExt, expandOrderList);
            });
            // 将删除的订单的点位变为死点
            iCuMemberTreeService.updateCuMemberTreeByCancelOrder(revokeRegSaOrderList, revokeUpdSaOrderList, settleDate, currentSettleTableName);
            //********************************* 更新当天最新的业绩*************************/
            // 获取所有国家的奖金项 key = 国家 + 奖金项的值
            BonusConfigDTO bonusConfigDTO = iBonusItemsServiceApi.queryBonusConfigDTO().getData();

            //*********************************计算奖衔 更新奖衔*********************************/
            // 开始计算奖衔 计算奖衔 更新奖衔（根据最新业绩查询变动且业绩满足下一等级，根据等级判断是否满足考核，安置考核或血缘考核）
            // 拉取变动过业绩的人 period > 0 的为变动过业绩的人
            // 获取到奖衔配置
//        a)更新会员表
//        b)更新结算网体表 (月表、日表)
//        c)增加奖衔记录表
            Map<Long, MemberAchieveParam> cuMemberAchieveHashMap = new HashMap<>();
            // 首购上传金额、业绩
            bonusSettlePurchaseHandle.assortSaOrder(cuMemberAchieveHashMap, firPurchaseOrderList, bonusConfigDTO, Boolean.TRUE);
            // 复购上传金额、业绩
            bonusSettlePurchaseHandle.assortSaOrder(cuMemberAchieveHashMap, repurchaseOrderList, bonusConfigDTO, Boolean.FALSE);
            // 金额、业绩先上传，处理完奖衔会再退回去
            iCuMemberTreeService.updateCuMemberSettle(cuMemberAchieveHashMap, currentSettleTableName);
            // 实际处理数据方法（计算奖衔）
            iCuMemberAwardsService.calculateCuMemberAwards(settleDate, awardsMap, currentSettleTableName);
            // 2025.04.23 调整需求，乐学升级不需要处理结算套数处理 -- new 乐学，处理V3 V4的升级
//            iCuMemberLevelService.calculateCuMemberGrade(settleDate, currentSettleTableName);
            // 计算完奖衔回退金额、业绩，最终根据新增进行回写
            iCuMemberTreeService.updateCuMemberBackSettle(cuMemberAchieveHashMap, currentSettleTableName);

            //********************************重新考核*********************************/
            // new 没有分红、复购考核，这个位置暂时去掉
//            cuMemberAssessService.retryCalculationAssess(DateUtils.parseStringToDate(settleDate), Boolean.TRUE);
            //*********************************计算奖金********************************/
            // 首购订单 （注册+升级） 直推奖、量奖、领导奖、（注册）报单服务费（key：奖金计算过程中使用会员ID，value：会员奖金数据）
            Map<Long, CuMemberBonus> cuMemberBonusMap = new HashMap<>();
            //*********************************根据首购订单计算奖金************************/
            // 计算 直推奖、拓展奖、辅导奖
            Map<Long, CuMemberSettleExt> cuMemberSettleExtMap = new HashMap<>();
            // 奖金记录明细（统一入库使用）
            BonusRecordDetailVO recordDetailVO = new BonusRecordDetailVO();
            // 计算奖金（主入口）
            // 乐学易考奖金计算，回写代金券数量
            LeXueRangeParam leXueRangeParam = calculateBonusBySaOrderList(settleDate, period, yesterdayPeriod, currentSettleTableName,
                    firPurchaseOrderList, repurchaseOrderList, mallOrderList, awardsMap, gradeMap, bonusConfigDTO, cuMemberBonusMap,
                    recordDetailVO, cuMemberSettleExtMap, expandOrderList, newExpandFlag);
            // 计算复购券
            calculateRepurchaseCoupons(DateUtils.parseDate(settleDate), firPurchaseOrderList, period, bonusConfigDTO, cuMemberBonusMap,
                    recordDetailVO, cuMemberSettleExtMap);

            // 验证是否月奖，验证是否是结算月底那一天，月底那一天计算云代，判断是否为月底
            //*********************************计算云代奖金、 复购券均分收益************************/
//            // new 云代、复购券均分、分红，暂时不处理
//            if (settleDate.endsWith("10")) {
//                // 计算云代奖金、复购券均分
//                calculateCloudAgentOrder(settleDate, bonusConfigDTO, period, recordDetailVO, cuMemberBonusMap);
//                // 分红
//                Map<Long, CuAwardsControl> cuAwardsControlMap = getCuAwardsControlMap();
//                calculateShareBonus(settleDate, bonusConfigDTO, period, recordDetailVO, cuMemberBonusMap, cuAwardsControlMap);
//            }

//            // 计算店铺奖金
//            if (settleDate.endsWith("10")) {
//                calculateStoreOrder(settleDate, bonusConfigDTO, period, recordDetailVO, cuMemberBonusMap);
//            }
//            // 计算实际分红奖金
//            if (settleDate.endsWith("10")) {
//                calculateShareBonus(settleDate, bonusConfigDTO, period, recordDetailVO, cuMemberBonusMap);
//            }
//            // 计算全球积分、车奖积分
//            // 环球积分和车奖积分的规则。有荣衔，复购考核通过的10代不压缩，以推荐+拓展+领导+分红为合计基数，获取对应比例，比例根据参数配置
//            calculateGlobalCarBonus(cuMemberSettleExtMap, currentSettleTableName, settleDate, bonusConfigDTO, period, recordDetailVO, cuMemberBonusMap);

            // 保存当日计算的奖金等
            insertCuMemberBonus(settleDate, period, cuMemberBonusMap, recordDetailVO);
            // 处理血缘业绩，统计伞下直推
            bonusSettleFirstPurchaseHandle.calculateCuMemberBloodAchieveByOrder(currentSettleTableName, cuMemberSettleExtMap,
                    firPurchaseOrderList, repurchaseOrderList, mallOrderList);
            if (cuMemberSettleExtMap.size() > 0) {
                // new 处理网体，更新网体新增 轮次最小值 -- 根据 cuMemberSettleExtMap 中会员的数据，最终更新 cu_member_settle 中各项数据
                iCuMemberTreeService.updateCuMemberSettle(currentSettleTableName, cuMemberSettleExtMap);
            }

            // 每日进行甩网业绩，按照条件，降结算好的业绩甩到想应的会员那边
            List<CuMemberAchieveExt> retMemberAchieveExtList = execNetAchieve(period, settleDate, currentSettleTableName);
            // 处理甩网数据
            if (retMemberAchieveExtList.size() > 0) {
                iCuMemberSwingNetLogService.mergeCuMemberSwingNetLogByAchieve(retMemberAchieveExtList, currentSettleTableName);
            }

            // 迁移网体数据到月表（会员网体月表、会员业绩月表）
            iCuMemberTreeService.insertCuMemberTreeBySettleDate(settleDate, currentSettleTableName, period);

            // 计算完当日奖金后，根据业绩计算下月奖衔
            Date currentDate = DateUtils.afterDate(1, ChronoUnit.DAYS, DateUtils.parseStringToDate(settleDate));
            String afterDate = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, currentDate);
            if (afterDate.endsWith("01")) {
                // new 不是月奖衔，每月初不更新（月度级差奖衔需要去掉）
//                String rangeTableName = TableNameConstants.CU_MEMBER_RANGE + period;
//                // 月第一天日期
//                String monthFirstDate = DateUtils.currentMonthFirstDateStr(DateUtils.parseStringToDate(settleDate));
//                // 月第一天期数
//                Integer startPeriod = iCuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(monthFirstDate).getPkId();
//                // 更新奖衔，根据新结算的奖衔
//                iCuMemberTreeService.updateCuMemberAwardsBySettle(currentSettleTableName, rangeTableName, startPeriod, period);

                // 结算每月月末那一天，都是先删除，在新增，重新考核
                iCuMemberTreeService.initCuMemberAssessData(settleDate);
                // 更新奖衔考核结果
                iCuMemberAwardsService.updateCuMemberAwardsExamine(currentDate, period);

                // 生成月表（cu_member_month）
                String monthTableName = TableNameConstants.CU_MEMBER_MONTH + DateUtils.getMonth(afterDate);
                Integer number = iCuMemberTreeService.queryExistOracleTable(monthTableName);
                if (number == null || number <= 0) {
                    // 创建表
                    iCuMemberAchieveService.createCuMemberMonthTable(monthTableName);
                    iCuMemberTreeService.createCuMemberTreeDayOnlyIndex(monthTableName);
                    iCuMemberTreeService.createCuMemberTreeParentIndex(monthTableName);
                    iCuMemberTreeService.createCuMemberTreePlaceIndex(monthTableName);
                }
            }
            // 奖金计算结束，统计拨比、业绩、4-N拨比
            iCuBonusExpandService.updateCuBonusExpandRatio(BonusExpandParam.builder().settleDate(DateUtils.parseStringToDate(settleDate)).build(), "cu_member_bonus");

            if (leXueRangeParam != null) {
                // 乐学相关，处理提货数据
                if (CollectionUtil.isNotEmpty(leXueRangeParam.getAcPickExtList())) {
                    if (!iAcPickServiceApi.updatePickUse(leXueRangeParam.getAcPickExtList(), leXueRangeParam.getAcPickMemberLogList()).getData()) {
                        throw new RuntimeException("更新提货专区数量失败");
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void calculateCuMemberRangAwardsBySaOrder(String orderCode) {
        Map<Long, CuMemberBonus> cuMemberBonusMap = new HashMap<>(MagicNumberConstants.DELETE_DATA_BATCH_UPDATE_NUM);
        BonusConfigDTO bonusConfigDTO = iBonusItemsServiceApi.queryBonusConfigDTO().getData();
        SaOrderExt saOrderExt = iSaOrderServiceApi.querySaOrderByDay(DateUtils.currentDate(), DateUtils.afterDate(1, ChronoUnit.DAYS), orderCode).getData();
        if (saOrderExt != null) {
            // 处理奖金结算秒结表，判断是否存在当天结算的秒接表，从cu_member中获取网体，从昨日结算表中获取累计、结余数据
            String settleDate = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, saOrderExt.getPayTime());
            String beforeDay = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, DateUtils.beforeDate(1, ChronoUnit.DAYS, saOrderExt.getPayTime()));
            int currentPeriod = iCuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(settleDate).getPkId();
            int beforePeriod = iCuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(beforeDay).getPkId();
            List<BdRangeAwards> rangeAwardsList = iAwardsServiceApi.queryRangeAwards().getData();
            String secondRangeTableName = TableNameConstants.CU_MEMBER_RANGE_S + currentPeriod;
            Map<Long, CuMemberRangeExt> memberRangeExtMap = bonusSettleRangeHandle.calculateCuMemberRangeAwardsByDay(saOrderExt, rangeAwardsList, secondRangeTableName, beforePeriod, currentPeriod);
            List<CuMemberBonusDetail> cuMemberBonusDetailList = new ArrayList<>();
            List<CuMemberBonusPush> cuMemberBonusPushList = new ArrayList<>();
            List<CuMemberBonusCoach> cuMemberBonusCoachList = new ArrayList<>();
            // 计算奖金，幸运收益、极差收益、平级收益
            CuMemberBonusCoach cuMemberBonusCoach = bonusSettleRangeHandle.calculateLuckPushBonus(memberRangeExtMap, cuMemberBonusMap, bonusConfigDTO, currentPeriod, saOrderExt);
            if (cuMemberBonusCoach != null) {
                cuMemberBonusCoachList.add(cuMemberBonusCoach);
            }
            List<CuMemberBonusRange> cuMemberBonusRangeList = new ArrayList<>(bonusSettleRangeHandle.calculateRangeBonus(memberRangeExtMap, cuMemberBonusMap, bonusConfigDTO, currentPeriod, saOrderExt, rangeAwardsList, cuMemberBonusDetailList));
            List<BdWaresBonusExt> bdWaresBonusExtList = iBdWaresBonusService.querySpecialWaresBonus(new BdWaresBonusParam());
            bonusSettleRangeHandle.calculateRangeEvBonus(cuMemberBonusMap, bonusConfigDTO, currentPeriod, memberRangeExtMap, cuMemberBonusPushList, bdWaresBonusExtList, saOrderExt);
            saveCuMemberBonus(currentPeriod, settleDate, cuMemberBonusMap);
            if (cuMemberBonusPushList.size() > 0) {
                for (CuMemberBonusPush cuMemberBonusPush : cuMemberBonusPushList) {
                    cuMemberBonusPush.setPkBonus(cuMemberBonusMap.get(cuMemberBonusPush.getPkBonus()).getPkId());
                    iCuMemberBonusPushService.insertCuMemberBonusPush(cuMemberBonusPush);
                }
            }
            Set<Long> memberIdSet = iCuMemberBonusService.queryMemberBonusByPeriod(currentPeriod);
            if (cuMemberBonusCoachList.size() > 0) {
                cuMemberBonusCoachList.forEach(cuMemberBonusCoach1 ->
                        cuMemberBonusCoach1.setPkBonus(cuMemberBonusMap.get(cuMemberBonusCoach1.getPkBonus()).getPkId()));
                iCuMemberBonusCoachService.batchInsertCuMemberBonusCoach(cuMemberBonusCoachList, memberIdSet);
            }
            if (cuMemberBonusRangeList.size() > 0) {
                cuMemberBonusRangeList.forEach(cuMemberBonusRange ->
                        cuMemberBonusRange.setPkBonus(cuMemberBonusMap.get(cuMemberBonusRange.getPkBonus()).getPkId()));
                iCuMemberBonusRangeService.batchInsertCuMemberBonusRange(cuMemberBonusRangeList, memberIdSet);
            }
            if (cuMemberBonusDetailList.size() > 0) {
                cuMemberBonusDetailList.forEach(bonusDetail ->
                        bonusDetail.setPkBonus(cuMemberBonusMap.get(bonusDetail.getPkBonus()).getPkId()));
                iCuMemberBonusDetailService.batchInsertCuMemberBonusDetail(cuMemberBonusDetailList, memberIdSet);
            }
            if (memberRangeExtMap.size() > 0) {
                iCuMemberRangeService.updateCuMemberSecondRange(secondRangeTableName, memberRangeExtMap);
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void repeatCuMemberBonusByExpand(String settleDate, List<SaOrderExt> saOrderExtList) {
        Integer period = iCuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(settleDate).getPkId();
        String currentSettleTableName = TableNameConstants.CU_MEMBER_SETTLE + period;

        String yesterday = DateUtils.beforeDateStr(1, ChronoUnit.DAYS, DateUtils.YYYY_MM_DD, settleDate);
        Integer yesterdayPeriod = iCuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(yesterday).getPkId();
        String yesterdayTableName = TableNameConstants.CU_MEMBER_SETTLE + yesterdayPeriod;

        iCuMemberTreeService.initCuMemberExpandTreeTable(yesterdayTableName, currentSettleTableName);

        BonusConfigDTO bonusConfigDTO = iBonusItemsServiceApi.queryBonusConfigDTO().getData();
        Map<Long, CuMemberSettleExt> cuMemberSettleExtMap = new HashMap<>();
        Map<Long, CuMemberBonus> cuMemberBonusMap = new HashMap<>();
        Map<Long, CuAwardsControl> cuAwardsControlMap = getCuAwardsControlMap();
        Map<Long, CuMemberBonus> weekMemberBonusMap = getWeekMemberBonusMap(settleDate, period);
        Map<String, String> systemConfigMap = iSystemConfigServiceApi.getBonusSystemConfig().getData();
        BonusRecordDetailVO recordDetailVO = new BonusRecordDetailVO();
        Map<String, BdAwards> awardsMap = iAwardsServiceApi.getAwards().getData();
        List<BdAwards> awardsList = iAwardsServiceApi.queryAwards(CountryConstants.CHINA_COUNTRY).getData();

        // TODO 2025.05.14 新拓展处理在2025.06.01之前还是走原来的1：1对碰，之后走1：2对碰
        // true 走新逻辑（首购+复购 合并计算）
        boolean newExpandFlag = settleDate.compareTo(newExpandDate) >= 0;

        // 首购订单
        List<SaOrderExt> firPurchaseOrderList = new ArrayList<>();
        saOrderExtList.forEach(saOrderExt ->
                packageSaOrderListByType(firPurchaseOrderList, null, null, saOrderExt, null));

        // 查询K值控制
        List<CuMemberRiskControl> cuMemberRiskControlList = iCuMemberRiskControlService.queryCuMemberRiskControl(DateUtils.parseStringToDate(settleDate));
        Map<Long, CuMemberRiskControl> riskControlMap = new HashMap<>();
        if (CollectionUtil.isNotEmpty(cuMemberRiskControlList)) {
            cuMemberRiskControlList.forEach(cuMemberRiskControl -> riskControlMap.put(cuMemberRiskControl.getPkMember(), cuMemberRiskControl));
        }
        // 查询所有的4-n碰次
        BonusExpandParam bonusExpandParam = BonusExpandParam.builder().settleDate(DateUtils.parseStringToDate(settleDate)).build();
        Map<Long, CuBonusExpandExt> cuBonusExpandExtMap = new HashMap<>();
        List<CuBonusExpandExt> cuBonusExpandExtList = iCuBonusExpandService.queryBonusExpand(bonusExpandParam);
        cuBonusExpandExtList.forEach(cuBonusExpandExt -> cuBonusExpandExtMap.put(cuBonusExpandExt.getPkMember(), cuBonusExpandExt));
        if (firPurchaseOrderList.size() > 0) {
            calculateFirPurchaseOrder(riskControlMap, cuMemberSettleExtMap, currentSettleTableName, settleDate, systemConfigMap, bonusConfigDTO,
                    firPurchaseOrderList, period, weekMemberBonusMap, cuMemberBonusMap, recordDetailVO, awardsMap, awardsList, cuAwardsControlMap, cuBonusExpandExtMap,
                    newExpandFlag);
        }
        List<CuMemberRepeatBonus> cuMemberBonusList = new ArrayList<>();
        for (CuMemberBonus cuMemberBonus : cuMemberBonusMap.values()) {
            cuMemberBonusList.add(BeanUtil.copyProperties(cuMemberBonus, CuMemberRepeatBonus.class));
        }
        if (cuMemberBonusList.size() > 0) {
            iCuMemberRepeatBonusService.insertCuMemberRepeatBonus(cuMemberBonusList);
        }
        if (cuMemberSettleExtMap.size() > 0) {
            // 处理网体，更新网体新增 轮次最小值  cuMemberSettleExtMap
            iCuMemberTreeService.updateCuMemberExpandSettle(currentSettleTableName, cuMemberSettleExtMap);
        }
    }

    /*
     * @description: 执行甩网业绩
     * @param: null null
     **/
    private List<CuMemberAchieveExt> execNetAchieve(Integer period, String settleDate, String currentSettleTableName) {
        List<CuMemberSwingNetExt> memberSwingNetExtList = iMemberServiceApi.queryCuMemberSwingNetExt().getData();
        List<CuMemberAchieveExt> retMemberAchieveExtList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(memberSwingNetExtList)) {
            // 查询接入会员的月业绩
            List<CuMemberAchieveExt> cuMemberAchieveExtList = iCuMemberAchieveService.queryCuMemberMonthAchieveByMemberIdList(currentSettleTableName, memberSwingNetExtList);
            Map<Long, CuMemberAchieveExt> memberAchieveExtMap = new HashMap<>();
            cuMemberAchieveExtList.forEach(cuMemberAchieveExt ->
                    memberAchieveExtMap.put(cuMemberAchieveExt.getPkMember(), cuMemberAchieveExt));
            Map<Long, CuMemberAchieveExt> cuMemberAchieveExtMap = new HashMap<>();
            for (CuMemberSwingNetExt cuMemberSwingNetExt : memberSwingNetExtList) {
                if (memberAchieveExtMap.containsKey(cuMemberSwingNetExt.getPkSourceMember())) {
                    CuMemberAchieveExt oldCuMemberAchieve = memberAchieveExtMap.get(cuMemberSwingNetExt.getPkSourceMember());
                    for (CuMemberSwingNetDetailExt cuMemberSwingNetDetailExt : cuMemberSwingNetExt.getCuMemberSwingNetDetailExtList()) {
                        CuMemberAchieveExt cuMemberAchieveExt;
                        if (cuMemberAchieveExtMap.containsKey(cuMemberSwingNetDetailExt.getPkMember())) {
                            cuMemberAchieveExt = cuMemberAchieveExtMap.get(cuMemberSwingNetDetailExt.getPkMember());
                        } else {
                            cuMemberAchieveExt = new CuMemberAchieveExt();
                            cuMemberAchieveExt.setASumPv(BigDecimal.ZERO);
                            cuMemberAchieveExt.setRepASumPv(BigDecimal.ZERO);
                            cuMemberAchieveExt.setASumRealPv(BigDecimal.ZERO);
                            cuMemberAchieveExt.setRepANewPv(BigDecimal.ZERO);
                            cuMemberAchieveExt.setBSumPv(BigDecimal.ZERO);
                            cuMemberAchieveExt.setRepBSumPv(BigDecimal.ZERO);
                            cuMemberAchieveExt.setBSumRealPv(BigDecimal.ZERO);
                            cuMemberAchieveExt.setRepBNewPv(BigDecimal.ZERO);
                            cuMemberAchieveExt.setNetFirstAchieve(BigDecimal.ZERO);
                            cuMemberAchieveExt.setNetRepurchaseAchieve(BigDecimal.ZERO);
                            cuMemberAchieveExtMap.put(cuMemberSwingNetDetailExt.getPkMember(), cuMemberAchieveExt);
                        }
                        cuMemberAchieveExt.setPkMember(cuMemberSwingNetDetailExt.getPkMember());
                        if (EPlaceDept.LEFT_DEPT.getValue() == cuMemberSwingNetDetailExt.getPlaceDept()) {
                            // 放左区 首购放首购，复购放复购
//                            // 首购
//                            cuMemberAchieveExt.setASumPv(ComputeUtil.computeMultiply(ComputeUtil.computeAdd(cuMemberAchieveExt.getASumPv(),
//                                    ComputeUtil.computeAdd(oldCuMemberAchieve.getRegisterBloNewPv(), oldCuMemberAchieve.getUpgradeBloNewPv())), cuMemberSwingNetDetailExt.getFirstAchieveRatio()));
//                            // 复购
//                            cuMemberAchieveExt.setRepASumPv(ComputeUtil.computeMultiply(ComputeUtil.computeAdd(cuMemberAchieveExt.getRepASumPv(), oldCuMemberAchieve.getRepurchaseBloNewPv()),
//                                    cuMemberSwingNetDetailExt.getRepurchaseAchieveRatio()));
                            cuMemberAchieveExt.setRepANewPv(ComputeUtil.computeMultiply(ComputeUtil.computeAddNum(cuMemberAchieveExt.getRepANewPv(),
                                    oldCuMemberAchieve.getRegisterBloNewPv(), oldCuMemberAchieve.getUpgradeBloNewPv(), oldCuMemberAchieve.getRepurchaseBloNewPv()), cuMemberSwingNetDetailExt.getFirstAchieveRatio()));
                            // 真实
//                            cuMemberAchieveExt.setASumRealPv(ComputeUtil.computeAdd(cuMemberAchieveExt.getASumPv(), cuMemberAchieveExt.getRepASumPv()));
                            cuMemberAchieveExt.setASumRealPv(cuMemberAchieveExt.getRepANewPv());
                            cuMemberAchieveExt.setPlaceDept(EPlaceDept.LEFT_DEPT.getValue());
                        } else {
                            // 首购
//                            cuMemberAchieveExt.setBSumPv(ComputeUtil.computeMultiply(ComputeUtil.computeAdd(cuMemberAchieveExt.getBSumPv(), ComputeUtil.computeAdd(oldCuMemberAchieve.getRegisterBloNewPv(), oldCuMemberAchieve.getUpgradeBloNewPv())),
//                                    cuMemberSwingNetDetailExt.getFirstAchieveRatio()));
//                            // 复购
//                            cuMemberAchieveExt.setRepBSumPv(ComputeUtil.computeMultiply(ComputeUtil.computeAdd(cuMemberAchieveExt.getRepBSumPv(), oldCuMemberAchieve.getRepurchaseBloNewPv()),
//                                    cuMemberSwingNetDetailExt.getRepurchaseAchieveRatio()));
                            // 真实
                            cuMemberAchieveExt.setRepBNewPv(ComputeUtil.computeMultiply(ComputeUtil.computeAddNum(cuMemberAchieveExt.getRepBNewPv(),
                                    oldCuMemberAchieve.getRegisterBloNewPv(), oldCuMemberAchieve.getUpgradeBloNewPv(), oldCuMemberAchieve.getRepurchaseBloNewPv()),
                                    cuMemberSwingNetDetailExt.getFirstAchieveRatio()));
//                            cuMemberAchieveExt.setBSumRealPv(ComputeUtil.computeAdd(cuMemberAchieveExt.getBSumPv(), cuMemberAchieveExt.getRepBSumPv()));
                            cuMemberAchieveExt.setBSumRealPv(cuMemberAchieveExt.getRepBNewPv());
                            cuMemberAchieveExt.setPlaceDept(EPlaceDept.RIGHT_DEPT.getValue());
                        }
                        cuMemberAchieveExt.setPeriod(period);
                        cuMemberAchieveExt.setPkCountry(oldCuMemberAchieve.getPkCountry());
                        cuMemberAchieveExt.setNetFirstAchieve(ComputeUtil.computeAdd(cuMemberAchieveExt.getNetFirstAchieve(), ComputeUtil.computeAdd(oldCuMemberAchieve.getRegisterBloNewPv(), oldCuMemberAchieve.getUpgradeBloNewPv())));
                        cuMemberAchieveExt.setNetRepurchaseAchieve(ComputeUtil.computeAdd(cuMemberAchieveExt.getNetRepurchaseAchieve(), oldCuMemberAchieve.getRepurchaseBloNewPv()));
                        retMemberAchieveExtList.add(cuMemberAchieveExt);
                    }
                }
            }
            if (cuMemberAchieveExtMap.size() > 0) {
                // 更新业绩
                List<CuMemberAchieveExt> updMemberAchieveExtList = new ArrayList<>(cuMemberAchieveExtMap.values());
                iCuMemberTreeService.updateCuMemberNetAchieve(updMemberAchieveExtList, currentSettleTableName);
            }
        }
        return retMemberAchieveExtList;
    }

    private void validateSettleTable(String yesterday, String yesterdayTableName) {
        Integer number = iCuMemberTreeService.queryExistOracleTable(yesterdayTableName);
        if (number == null || number <= 0) {
            iCuMemberTreeService.createCuMemberTree(yesterday);
            yesterday = DateUtils.beforeDateStr(1, ChronoUnit.DAYS, DateUtils.YYYY_MM_DD, yesterday);
            validateSettleTable(yesterday, yesterdayTableName);
        }
    }

    /**
     * 根据不同的订单类型计算奖金
     *
     * @param settleDate           结算日期
     * @param period               期间
     * @param yesterdayPeriod      昨日期间
     * @param settleTableName      结算日表
     * @param awardsMap            奖衔
     * @param gradeMap             等级
     * @param bonusConfigDTO       奖金配置
     * @param cuMemberBonusMap     最终的奖金列表
     * @param cuMemberSettleExtMap 会员结算map
     * @param expandOrderList      拓展收益订单（首购+复购）
     */
    private LeXueRangeParam calculateBonusBySaOrderList(String settleDate, Integer period, Integer yesterdayPeriod, String settleTableName,
                                                        List<SaOrderExt> firPurchaseOrderList, List<SaOrderExt> repurchaseOrderList, List<SaOrderExt> mallOrderList,
                                                        Map<String, BdAwards> awardsMap, Map<Integer, BdGrade> gradeMap, BonusConfigDTO bonusConfigDTO,
                                                        Map<Long, CuMemberBonus> cuMemberBonusMap, BonusRecordDetailVO bonusRecordDetailVO,
                                                        Map<Long, CuMemberSettleExt> cuMemberSettleExtMap, List<SaOrderExt> expandOrderList, boolean newExpandFlag) {
        LeXueRangeParam leXueRangeParam = null;
        Map<Long, CuAwardsControl> cuAwardsControlMap = getCuAwardsControlMap();
        Map<Long, CuMemberBonus> weekMemberBonusMap = getWeekMemberBonusMap(settleDate, period);
        Map<String, String> systemConfigMap = iSystemConfigServiceApi.getBonusSystemConfig().getData();
        Map<String, RangeDTO> rangeDtoMap = iRangeServiceApi.queryRangeDto().getData();
        // 奖衔列表（奖衔值升序）
        List<BdAwards> awardsList = iAwardsServiceApi.queryAwards(CountryConstants.CHINA_COUNTRY).getData();

        // 查询K值控制
        List<CuMemberRiskControl> cuMemberRiskControlList = iCuMemberRiskControlService.queryCuMemberRiskControl(DateUtils.parseStringToDate(settleDate));
        Map<Long, CuMemberRiskControl> riskControlMap = new HashMap<>();
        if (CollectionUtil.isNotEmpty(cuMemberRiskControlList)) {
            cuMemberRiskControlList.forEach(cuMemberRiskControl -> riskControlMap.put(cuMemberRiskControl.getPkMember(), cuMemberRiskControl));
        }
        // 查询所有的4-n碰次（增加的碰次）
        BonusExpandParam bonusExpandParam = BonusExpandParam.builder().settleDate(DateUtils.parseStringToDate(settleDate)).build();
        Map<Long, CuBonusExpandExt> cuBonusExpandExtMap = new HashMap<>();
        List<CuBonusExpandExt> cuBonusExpandExtList = iCuBonusExpandService.queryBonusExpand(bonusExpandParam);
        cuBonusExpandExtList.forEach(cuBonusExpandExt -> cuBonusExpandExtMap.put(cuBonusExpandExt.getPkMember(), cuBonusExpandExt));

        // 先计算复购在计算首购
        // 计算复购
        if (CollectionUtil.isNotEmpty(repurchaseOrderList)) {
            leXueRangeParam = calculatePurchaseOrder(riskControlMap, cuMemberSettleExtMap, settleTableName, settleDate, systemConfigMap, bonusConfigDTO,
                    repurchaseOrderList, period, weekMemberBonusMap, cuMemberBonusMap, bonusRecordDetailVO, awardsMap, awardsList, cuAwardsControlMap, cuBonusExpandExtMap, rangeDtoMap,
                    newExpandFlag);
        }
        // 计算首购
        if (CollectionUtil.isNotEmpty(firPurchaseOrderList)) {
            calculateFirPurchaseOrder(riskControlMap, cuMemberSettleExtMap, settleTableName, settleDate, systemConfigMap, bonusConfigDTO,
                    firPurchaseOrderList, period, weekMemberBonusMap, cuMemberBonusMap, bonusRecordDetailVO, awardsMap, awardsList, cuAwardsControlMap, cuBonusExpandExtMap,
                    newExpandFlag);
        }
        if (newExpandFlag) {
            // TODO 2025.05.14 新拓展订单处理
            if (CollectionUtil.isNotEmpty(expandOrderList)) {
                calculateNewExpandOrder(riskControlMap, cuMemberSettleExtMap, settleTableName, settleDate, bonusConfigDTO,
                        expandOrderList, period, cuMemberBonusMap, bonusRecordDetailVO, awardsList, cuAwardsControlMap, cuBonusExpandExtMap);
            }
        }
        // 计算商城业绩
        if (CollectionUtil.isNotEmpty(mallOrderList)) {
            bonusSettleMallHandle.calculateMallBonus(cuMemberSettleExtMap, settleTableName, mallOrderList, bonusConfigDTO);
        }

        // 处理拓展延缓发放
        List<CuMemberBonusExpand> delayExpandList = bonusSettleFirstPurchaseHandle.handleDelayExpand(bonusRecordDetailVO, cuMemberBonusMap, bonusConfigDTO, cuMemberSettleExtMap,
                period, yesterdayPeriod, settleTableName, gradeMap);
        // 判断是否有量奖，有量奖有辅导奖
        List<CuMemberBonusCoach> cuMemberBonusCoachList = bonusSettleFirstPurchaseHandle.calculateCoachBonus(cuMemberSettleExtMap, settleTableName, settleDate, bonusConfigDTO,
                Collections.emptyList(), delayExpandList, period, cuMemberBonusMap, cuAwardsControlMap, riskControlMap, awardsList, true, false);
        if (CollectionUtil.isNotEmpty(bonusRecordDetailVO.getCuMemberBonusCoachList())) {
            bonusRecordDetailVO.getCuMemberBonusCoachList().addAll(cuMemberBonusCoachList);
        } else {
            bonusRecordDetailVO.setCuMemberBonusCoachList(cuMemberBonusCoachList);
        }
        // 辅导收益
        cuMemberBonusCoachList.forEach(cuMemberBonusCoach -> {
            // 收益拨比、订单占比，在延缓明细里面已经计算过，此处可以直接给0
            cuMemberBonusCoach.setIncomeDialRatio(BigDecimal.ZERO);
            cuMemberBonusCoach.setOrderDialRatio(BigDecimal.ZERO);
        });

        return leXueRangeParam;
    }

    private Map<Long, CuMemberBonus> getWeekMemberBonusMap(String settleDate, Integer period) {
        // 根据结算日期获取周期的期间，用于海外
        String recentlyMonday = DateUtils.getRecentlyTuesday(settleDate);
        CuMemberSettlePeriod startMemberSettlePeriod = iCuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(recentlyMonday);
        // 查询封顶周期是周的国家的所有人的拓展收益、复购拓展收益
        return iCuMemberBonusService.queryWeekMemberBonus(startMemberSettlePeriod.getPkId(), period);
    }

    private Map<Long, CuAwardsControl> getCuAwardsControlMap() {
        // 查询真实奖衔控制
        List<CuAwardsControl> cuAwardsControls = iCuAwardsControlService.queryAllCuAwardsControl();
        Map<Long, CuAwardsControl> cuAwardsControlMap = new HashMap<>(ComputeUtil.mapInitCapacity(cuAwardsControls.size()));
        if (CollectionUtil.isNotEmpty(cuAwardsControls)) {
            cuAwardsControls.forEach(cuAwardsControl ->
                    cuAwardsControlMap.put(cuAwardsControl.getPkMember(), cuAwardsControl));
        }
        return cuAwardsControlMap;
    }

    /**
     * 计算每天的奖金入库
     *
     * @param cuMemberBonusMap    奖金主表
     * @param bonusRecordDetailVO 奖金明细表
     */
    void insertCuMemberBonus(String settleDate, Integer period, Map<Long, CuMemberBonus> cuMemberBonusMap, BonusRecordDetailVO bonusRecordDetailVO) {
        // 删除 直推收益明细表
        iCuMemberBonusPushService.deleteCuMemberBonusPush(period);
        // 删除 拓展收益明细表
        iCuMemberBonusExpandService.deleteCuMemberBonusExpand(period);
        // 删除 辅导收益明细表
        iCuMemberBonusCoachService.deleteCuMemberBonusCoach(period);
        // 删除 奖金收益明细表(报单费)
        iCuMemberBonusDetailService.deleteCuMemberBonusDetail(period);
        // 删除 奖金收益明细表(复购极差)
        iCuMemberBonusRangeService.deleteCuMemberBonusRange(period);
        // new 删除拓展收益延缓主表
        iCuMemberBonusDelayService.deleteCuMemberBonusDelay(period);
        // new 删除拓展收益延缓明细表
        iCuMemberBonusDelayDetailService.deleteCuMemberBonusDelayDetail(period);
        // 删除 会员奖金汇总表
        iCuMemberBonusService.deleteCuMemberBonus(period);

        if (cuMemberBonusMap.size() == 0) {
            return;
        }

        List<CuMemberBonusPush> batchMemberBonusPushList = new ArrayList<>();
        List<CuMemberBonusExpand> batchMemberBonusExpandList = new ArrayList<>();
        List<CuMemberBonusCoach> batchMemberBonusCoachList = new ArrayList<>();
        List<CuMemberBonusDetail> batchMemberBonusDetailList = new ArrayList<>();
        List<CuMemberBonusRange> batchMemberBonusRangeList = new ArrayList<>();
        List<CuMemberBonusDelay> batchMemberBonusDelayList = new ArrayList<>();
        List<CuMemberBonusDelayDetail> batchMemberBonusDelayDetailList = new ArrayList<>();

        List<CuMemberBonus> cuMemberBonusList = setCuMemberBonusSeq(settleDate, cuMemberBonusMap);
        List<CuMemberBonusPush> cuMemberBonusPushList = bonusRecordDetailVO.getCuMemberBonusPushList();
        List<CuMemberBonusExpand> cuMemberBonusExpandList = bonusRecordDetailVO.getCuMemberBonusExpandList();
        List<CuMemberBonusCoach> cuMemberBonusCoachList = bonusRecordDetailVO.getCuMemberBonusCoachList();
        List<CuMemberBonusDetail> cuMemberBonusDetailList = bonusRecordDetailVO.getCuMemberBonusDetailList();
        List<CuMemberBonusRange> cuMemberBonusRangeList = bonusRecordDetailVO.getCuMemberBonusRangeList();
        List<CuMemberBonusDelay> cuMemberBonusDelayList = bonusRecordDetailVO.getCuMemberBonusDelayList();
        List<CuMemberBonusDelayDetail> cuMemberBonusDelayDetailList = bonusRecordDetailVO.getCuMemberBonusDelayDetailList();

        if (CollectionUtil.isNotEmpty(cuMemberBonusPushList)) {
            cuMemberBonusPushList.forEach(cuMemberBonusPush ->
                    cuMemberBonusPush.setPkBonus(cuMemberBonusMap.get(cuMemberBonusPush.getPkBonus()).getPkId()));
            batchMemberBonusPushList.addAll(cuMemberBonusPushList);
        }
        if (CollectionUtil.isNotEmpty(cuMemberBonusExpandList)) {
            cuMemberBonusExpandList.forEach(cuMemberBonusExpand ->
                    cuMemberBonusExpand.setPkBonus(cuMemberBonusMap.get(cuMemberBonusExpand.getPkBonus()).getPkId()));
            batchMemberBonusExpandList.addAll(cuMemberBonusExpandList);
        }
        if (CollectionUtil.isNotEmpty(cuMemberBonusCoachList)) {
            cuMemberBonusCoachList.forEach(cuMemberBonusCoach ->
                    cuMemberBonusCoach.setPkBonus(cuMemberBonusMap.get(cuMemberBonusCoach.getPkBonus()).getPkId()));
            batchMemberBonusCoachList.addAll(cuMemberBonusCoachList);
        }
        if (CollectionUtil.isNotEmpty(cuMemberBonusDetailList)) {
            cuMemberBonusDetailList.forEach(cuMemberBonusDetail ->
                    cuMemberBonusDetail.setPkBonus(cuMemberBonusMap.get(cuMemberBonusDetail.getPkBonus()).getPkId()));
            batchMemberBonusDetailList.addAll(cuMemberBonusDetailList);
        }
        if (CollectionUtil.isNotEmpty(cuMemberBonusRangeList)) {
            cuMemberBonusRangeList.forEach(cuMemberBonusRange ->
                    cuMemberBonusRange.setPkBonus(cuMemberBonusMap.get(cuMemberBonusRange.getPkBonus()).getPkId()));
            batchMemberBonusRangeList.addAll(cuMemberBonusRangeList);
        }
        if (CollectionUtil.isNotEmpty(cuMemberBonusDelayList)) {
            cuMemberBonusDelayList.forEach(cuMemberBonusDelay ->
                    cuMemberBonusDelay.setPkBonus(cuMemberBonusMap.get(cuMemberBonusDelay.getPkBonus()).getPkId()));
            batchMemberBonusDelayList.addAll(cuMemberBonusDelayList);
        }
        if (CollectionUtil.isNotEmpty(cuMemberBonusDelayDetailList)) {
            cuMemberBonusDelayDetailList.forEach(cuMemberBonusDelayDetail ->
                    cuMemberBonusDelayDetail.setPkBonus(cuMemberBonusMap.get(cuMemberBonusDelayDetail.getPkBonus()).getPkId()));
            batchMemberBonusDelayDetailList.addAll(cuMemberBonusDelayDetailList);
        }
        // 插入奖金主表
        iCuMemberBonusService.batchInsertCuMemberBonus(cuMemberBonusList);
        Set<Long> memberIdSet = iCuMemberBonusService.queryMemberBonusByPeriod(period);
        iCuMemberBonusPushService.batchInsertCuMemberBonusPush(batchMemberBonusPushList, memberIdSet);
        iCuMemberBonusExpandService.batchInsertCuMemberBonusExpand(batchMemberBonusExpandList, memberIdSet);
        iCuMemberBonusCoachService.batchInsertCuMemberBonusCoach(batchMemberBonusCoachList, memberIdSet);
        iCuMemberBonusDetailService.batchInsertCuMemberBonusDetail(batchMemberBonusDetailList, memberIdSet);
        iCuMemberBonusRangeService.batchInsertCuMemberBonusRange(batchMemberBonusRangeList, memberIdSet);
        iCuMemberBonusDelayService.batchInsertCuMemberBonusDelay(batchMemberBonusDelayList, memberIdSet);
        iCuMemberBonusDelayDetailService.batchInsertCuMemberBonusDelayDetail(batchMemberBonusDelayDetailList, memberIdSet);
    }

    private List<CuMemberBonus> setCuMemberBonusSeq(String settleDate, Map<Long, CuMemberBonus> cuMemberBonusMap) {
        List<Long> pkIdList = iCuMemberBonusService.batchQueryCuMemberBonusSeq(cuMemberBonusMap.size());
        int i = 0;
        // 判断时间，重算的时候直接是已公布
        Integer grantStatus = EGrantStatus.SETTLED.getValue();
        if (DateUtils.compareDate(DateUtils.parseStringToDate(settleDate), DateUtils.beforeDate(2, ChronoUnit.DAYS)) <= 0) {
            grantStatus = EGrantStatus.PUBLISHED.getValue();
        }
        List<CuMemberBonus> cuMemberBonusList = new ArrayList<>();
        for (CuMemberBonus cuMemberBonus : cuMemberBonusMap.values()) {
            cuMemberBonus.setPkId(pkIdList.get(i));
            cuMemberBonus.setGrantStatus(grantStatus);
            cuMemberBonusList.add(cuMemberBonus);
            i++;
        }
        return cuMemberBonusList;
    }

    /**
     * 根据订单类型封装为不同订单列表
     *
     * @param firPurchaseOrderList 首购
     * @param repurchaseOrderList  复购
     * @param mallOrderList        商城
     * @param saOrderExt           来源订单
     * @param expandOrderList      拓展订单
     */
    private void packageSaOrderListByType(List<SaOrderExt> firPurchaseOrderList, List<SaOrderExt> repurchaseOrderList,
                                          List<SaOrderExt> mallOrderList, SaOrderExt saOrderExt, List<SaOrderExt> expandOrderList) {
        if (Objects.equals(EOrderType.REGISTER_ORDER.getValue(), saOrderExt.getOrderType())
                || Objects.equals(EOrderType.UPGRADE_ORDER.getValue(), saOrderExt.getOrderType())) {
            firPurchaseOrderList.add(saOrderExt);
        } else if (Objects.equals(EOrderType.FICTITIOUS_ORDER.getValue(), saOrderExt.getOrderType())) {
            firPurchaseOrderList.add(saOrderExt);
        } else if (Objects.equals(EOrderType.REPURCHASE_ORDER.getValue(), saOrderExt.getOrderType())) {
            repurchaseOrderList.add(saOrderExt);
        } else {
            mallOrderList.add(saOrderExt);
            // 商城订单也计算复购量奖
            repurchaseOrderList.add(saOrderExt);
        }
        if (null != expandOrderList) {
            expandOrderList.add(saOrderExt);
        }
    }

    /**
     * 计算首购订单的奖金
     *
     * @param settleTableName      结算日表
     * @param settleDate           结算日期
     * @param bonusConfigDTO       各个国家奖金参数
     * @param firPurchaseOrderList 首购订单
     */
    private void calculateFirPurchaseOrder(Map<Long, CuMemberRiskControl> riskControlMap, Map<Long, CuMemberSettleExt> cuMemberSettleExtMap, String settleTableName, String settleDate,
                                           Map<String, String> systemConfigMap, BonusConfigDTO bonusConfigDTO, List<SaOrderExt> firPurchaseOrderList, Integer period,
                                           Map<Long, CuMemberBonus> weekMemberBonusMap, Map<Long, CuMemberBonus> cuMemberBonusMap, BonusRecordDetailVO bonusRecordDetailVO,
                                           Map<String, BdAwards> awardsMap, List<BdAwards> awardsList, Map<Long, CuAwardsControl> cuAwardsControlMap, Map<Long, CuBonusExpandExt> cuBonusExpandExtMap,
                                           boolean newExpandFlag) {
        // 获得国家是三单循环还是四单循环
        // 获得升级方式是纳入三单循环还是固定值
        // 获取有订单国家的系统参数，获得三单循环还是四单循环 key 国家+系统参数key
        // 需要更新的会员结算表 cuMemberSettleExtMap
        //***************************计算推荐奖（直推级差、直推三四单循环）******************************/
        List<CuMemberBonusPush> cuMemberBonusPushList = bonusSettleFirstPurchaseHandle.calculateRecommendBonus(cuMemberSettleExtMap, settleTableName, bonusConfigDTO, systemConfigMap, firPurchaseOrderList, period, cuMemberBonusMap, awardsMap);
        bonusRecordDetailVO.setCuMemberBonusPushList(cuMemberBonusPushList);

        List<CuMemberBonusExpand> cuMemberBonusExpandList = null;
        List<CuMemberBonusCoach> cuMemberBonusCoachList = null;
        if (!newExpandFlag) {
            //****************************计算量奖（拓展收益）*****************************/
            cuMemberBonusExpandList = bonusSettleFirstPurchaseHandle.calculateExpandBonus(cuMemberSettleExtMap, settleDate, settleTableName, bonusConfigDTO, systemConfigMap,
                    firPurchaseOrderList, period, weekMemberBonusMap, cuMemberBonusMap, riskControlMap, cuBonusExpandExtMap);
            if (cuMemberBonusExpandList.size() > 0) {
                if (null == bonusRecordDetailVO.getCuMemberBonusExpandList()) {
                    bonusRecordDetailVO.setCuMemberBonusExpandList(cuMemberBonusExpandList);
                } else {
                    bonusRecordDetailVO.getCuMemberBonusExpandList().addAll(cuMemberBonusExpandList);
                }

                bonusSettlePurchaseHandle.handleFirExpandDelay(cuMemberBonusExpandList, period, bonusRecordDetailVO);
            }

            //*********************************计算领导奖（首购辅导收益）************************/
            // 判断是否有量奖，有量奖有辅导奖
            cuMemberBonusCoachList = bonusSettleFirstPurchaseHandle.calculateCoachBonus(cuMemberSettleExtMap, settleTableName, settleDate, bonusConfigDTO, firPurchaseOrderList,
                    cuMemberBonusExpandList, period, cuMemberBonusMap, cuAwardsControlMap, riskControlMap, awardsList, true, true);
            if (CollectionUtil.isNotEmpty(bonusRecordDetailVO.getCuMemberBonusCoachList())) {
                bonusRecordDetailVO.getCuMemberBonusCoachList().addAll(cuMemberBonusCoachList);
            } else {
                bonusRecordDetailVO.setCuMemberBonusCoachList(cuMemberBonusCoachList);
            }
        }

        //*********************************计算服务奖************************/
        List<CuMemberBonusDetail> cuMemberBonusDetailList = bonusSettleFirstPurchaseHandle.calculateServiceBonus(cuMemberSettleExtMap, settleDate, settleTableName, bonusConfigDTO, firPurchaseOrderList, period, cuMemberBonusMap);
        bonusRecordDetailVO.setCuMemberBonusDetailList(cuMemberBonusDetailList);

        // 收益拨比 实发此单直推/此单所有奖金（直推、量奖）  订单拨比 所有奖金/此单金额
        Map<Long, MemberBonusDetailCalVO> memberBonusDetailCalVoMap = new HashMap<>(ComputeUtil.mapInitCapacity(firPurchaseOrderList.size()));
        cuMemberBonusPushList.forEach(cuMemberBonusPush -> {
            MemberBonusDetailCalVO memberBonusDetailCalVO = calculateOrderRatio(memberBonusDetailCalVoMap, cuMemberBonusPush);
            memberBonusDetailCalVO.setPushIncome(ComputeUtil.computeAdd(memberBonusDetailCalVO.getPushIncome(), cuMemberBonusPush.getRealIncome()));
        });
        if (null != cuMemberBonusExpandList) {
            // 拓展收益
            cuMemberBonusExpandList.forEach(cuMemberBonusExpand -> {
                MemberBonusDetailCalVO memberBonusDetailCalVO = calculateOrderRatio(memberBonusDetailCalVoMap, cuMemberBonusExpand);
                memberBonusDetailCalVO.setExpandIncome(ComputeUtil.computeAdd(memberBonusDetailCalVO.getExpandIncome(), cuMemberBonusExpand.getRealIncome()));
            });
        }
        if (null != cuMemberBonusCoachList) {
            // 辅导收益
            cuMemberBonusCoachList.forEach(cuMemberBonusCoach -> {
                MemberBonusDetailCalVO memberBonusDetailCalVO = calculateOrderRatio(memberBonusDetailCalVoMap, cuMemberBonusCoach);
                memberBonusDetailCalVO.setCoachIncome(ComputeUtil.computeAdd(memberBonusDetailCalVO.getCoachIncome(), cuMemberBonusCoach.getRealIncome()));
            });
        }
        cuMemberBonusDetailList.forEach(cuMemberBonusDetail -> {
            MemberBonusDetailCalVO memberBonusDetailCalVO = calculateOrderRatio(memberBonusDetailCalVoMap, cuMemberBonusDetail);
            memberBonusDetailCalVO.setServiceIncome(ComputeUtil.computeAdd(memberBonusDetailCalVO.getServiceIncome(), cuMemberBonusDetail.getRealIncome()));
        });
        Map<Long, SaOrderExt> saOrderExtMap = new HashMap<>(ComputeUtil.mapInitCapacity(firPurchaseOrderList.size()));
        firPurchaseOrderList.forEach(saOrderExt ->
                saOrderExtMap.put(saOrderExt.getPkId(), saOrderExt));
        // 计算 收益拨比 此类型收益÷总拨金额 订单拨比 此订单所有收益之合得实发金额÷订单总金额
        cuMemberBonusPushList.forEach(cuMemberBonusPush -> {
            MemberBonusDetailCalVO memberBonusDetailCalVO = memberBonusDetailCalVoMap.get(cuMemberBonusPush.getPkOrder());
            SaOrderExt saOrderExt = saOrderExtMap.get(memberBonusDetailCalVO.getPkOrder());
            cuMemberBonusPush.setIncomeDialRatio(ComputeUtil.computeDivide(memberBonusDetailCalVO.getPushIncome(), memberBonusDetailCalVO.getRealIncome()));
            cuMemberBonusPush.setOrderDialRatio(ComputeUtil.computeDivide(memberBonusDetailCalVO.getRealIncome(), saOrderExt.getOrderAmount()));
        });
        if (null != cuMemberBonusExpandList) {
            // 拓展收益
            cuMemberBonusExpandList.forEach(cuMemberBonusExpand -> {
                MemberBonusDetailCalVO memberBonusDetailCalVO = memberBonusDetailCalVoMap.get(cuMemberBonusExpand.getPkOrder());
                SaOrderExt saOrderExt = saOrderExtMap.get(memberBonusDetailCalVO.getPkOrder());
                cuMemberBonusExpand.setIncomeDialRatio(ComputeUtil.computeDivide(memberBonusDetailCalVO.getExpandIncome(), memberBonusDetailCalVO.getRealIncome()));
                cuMemberBonusExpand.setOrderDialRatio(ComputeUtil.computeDivide(memberBonusDetailCalVO.getRealIncome(), saOrderExt.getOrderAmount()));
            });
        }
        if (null != cuMemberBonusCoachList) {
            // 辅导收益
            cuMemberBonusCoachList.forEach(cuMemberBonusCoach -> {
                MemberBonusDetailCalVO memberBonusDetailCalVO = memberBonusDetailCalVoMap.get(cuMemberBonusCoach.getPkOrder());
                SaOrderExt saOrderExt = saOrderExtMap.get(memberBonusDetailCalVO.getPkOrder());
                cuMemberBonusCoach.setIncomeDialRatio(ComputeUtil.computeDivide(memberBonusDetailCalVO.getCoachIncome(), memberBonusDetailCalVO.getRealIncome()));
                cuMemberBonusCoach.setOrderDialRatio(ComputeUtil.computeDivide(memberBonusDetailCalVO.getRealIncome(), saOrderExt.getOrderAmount()));
            });
        }
        // 报单服务费
        cuMemberBonusDetailList.forEach(cuMemberBonusDetail -> {
            MemberBonusDetailCalVO memberBonusDetailCalVO = memberBonusDetailCalVoMap.get(cuMemberBonusDetail.getPkOrder());
            SaOrderExt saOrderExt = saOrderExtMap.get(memberBonusDetailCalVO.getPkOrder());
            cuMemberBonusDetail.setIncomeDialRatio(ComputeUtil.computeDivide(memberBonusDetailCalVO.getServiceIncome(), memberBonusDetailCalVO.getRealIncome()));
            cuMemberBonusDetail.setOrderDialRatio(ComputeUtil.computeDivide(memberBonusDetailCalVO.getRealIncome(), ComputeUtil.computeDivide(saOrderExt.getOrderAmount(), saOrderExt.getInExchangeRate())));
        });
//        //*********************************计算分红奖,理论最大值************************/
//        Map<Integer, List<SaOrderExt>> saOrderMap = new HashMap<>(ComputeUtil.mapInitCapacity(firPurchaseOrderList.size()));
//        firPurchaseOrderList.forEach(saOrderExt -> {
//            Integer key = saOrderExt.getPkCountry();
//            if (saOrderMap.containsKey(key)) {
//                saOrderMap.get(key).add(saOrderExt);
//            } else {
//                List<SaOrderExt> saOrderExtList = new ArrayList<>();
//                saOrderExtList.add(saOrderExt);
//                saOrderMap.put(key, saOrderExtList);
//            }
//        });
//        saOrderMap.forEach((pkCountry, saOrderExtList) -> {
//            CuMemberShareMax cuMemberShareMax = CuMemberShareMax.builder()
//                    .period(period)
//                    .pkRate(saOrderExtList.get(0).getPkRate())
//                    .shareIncome(BigDecimal.ZERO)
//                    .orderAchieve(BigDecimal.ZERO)
//                    .build();
//            cuMemberShareMax.setPkCountry(pkCountry);
//            cuMemberShareMax.setPkCreator(MagicNumberConstants.PK_ADMIN);
//            saOrderExtList.forEach(saOrderExt -> {
//                cuMemberShareMax.setOrderAchieve(ComputeUtil.computeAdd(cuMemberShareMax.getOrderAchieve(), saOrderExt.getOrderAchieve()));
//                cuMemberShareMax.setShareIncome(ComputeUtil.computeAdd(cuMemberShareMax.getShareIncome(), ComputeUtil.computeBonusMultiply(saOrderExt.getOrderAchieve(), BigDecimal.valueOf(5))));
//            });
//            cuMemberShareMaxService.insertMaxShareBonus(cuMemberShareMax);
//        });
    }

    /**
     * 计算复购订单的奖金
     *
     * @param settleTableName   结算日表
     * @param settleDate        结算日期
     * @param bonusConfigDTO    各个国家奖金参数
     * @param purchaseOrderList 复购订单
     * @param rangeDtoMap       乐学奖金使用的汇率map
     */
    private LeXueRangeParam calculatePurchaseOrder(Map<Long, CuMemberRiskControl> riskControlMap, Map<Long, CuMemberSettleExt> cuMemberSettleExtMap, String settleTableName, String settleDate,
                                                   Map<String, String> systemConfigMap, BonusConfigDTO bonusConfigDTO, List<SaOrderExt> purchaseOrderList, Integer period,
                                                   Map<Long, CuMemberBonus> weekMemberBonusMap, Map<Long, CuMemberBonus> cuMemberBonusMap, BonusRecordDetailVO bonusRecordDetailVO,
                                                   Map<String, BdAwards> awardsMap, List<BdAwards> awardsList, Map<Long, CuAwardsControl> cuAwardsControlMap, Map<Long, CuBonusExpandExt> cuBonusExpandExtMap,
                                                   Map<String, RangeDTO> rangeDtoMap, boolean newExpandFlag) {
        //****************************复购直推*****************************
        // 查找10代血缘，验证复购考核，考核通过的给与奖金 紧缩
//        List<CuMemberBonusPush> cuMemberBonusPushList = bonusSettlePurchaseHandle.calculateRepurchasePushBonus(cuMemberSettleExtMap, settleTableName, settleDate, bonusConfigDTO, purchaseOrderList, period, cuMemberBonusMap);
//        if (cuMemberBonusPushList.size() > 0) {
//            if (bonusRecordDetailVO.getCuMemberBonusPushList() == null) {
//                bonusRecordDetailVO.setCuMemberBonusPushList(cuMemberBonusPushList);
//            } else {
//                bonusRecordDetailVO.getCuMemberBonusPushList().addAll(cuMemberBonusPushList);
//            }
//        }
        List<CuMemberBonusExpand> cuMemberBonusExpandList = null;
        List<CuMemberBonusCoach> cuMemberBonusCoachList = null;
        if (!newExpandFlag) {
            //****************************计算量奖（拓展收益）*****************************/
            cuMemberBonusExpandList = bonusSettlePurchaseHandle.calculateRepurchaseExpandBonus(riskControlMap, cuMemberSettleExtMap, settleTableName, settleDate,
                    bonusConfigDTO, systemConfigMap, purchaseOrderList, period, weekMemberBonusMap, cuMemberBonusMap, cuBonusExpandExtMap);
            if (cuMemberBonusExpandList.size() > 0) {
                if (null == bonusRecordDetailVO.getCuMemberBonusExpandList()) {
                    bonusRecordDetailVO.setCuMemberBonusExpandList(cuMemberBonusExpandList);
                } else {
                    bonusRecordDetailVO.getCuMemberBonusExpandList().addAll(cuMemberBonusExpandList);
                }
                bonusSettlePurchaseHandle.handleRepExpandDelay(cuMemberBonusExpandList, period, bonusRecordDetailVO);
            }

            //*********************************计算领导奖（复购辅导收益）************************/
            // 判断是否有量奖，有量奖有辅导奖
            cuMemberBonusCoachList = bonusSettleFirstPurchaseHandle.calculateCoachBonus(cuMemberSettleExtMap, settleTableName, settleDate, bonusConfigDTO, purchaseOrderList,
                    cuMemberBonusExpandList, period, cuMemberBonusMap, cuAwardsControlMap, riskControlMap, awardsList, false, true);
            bonusRecordDetailVO.setCuMemberBonusCoachList(cuMemberBonusCoachList);
        }

        //****************************乐学极差（复购）*****************************/
        LeXueRangeParam leXueRangeParam = new LeXueRangeParam();
        List<CuMemberBonusRange> cuMemberBonusRangeList = bonusSettlePurchaseHandle.calculateRepurchaseRangeBonus(cuMemberSettleExtMap, settleTableName, settleDate, rangeDtoMap, awardsMap,
                bonusConfigDTO, purchaseOrderList, period, cuMemberBonusMap, cuAwardsControlMap, leXueRangeParam);
        bonusRecordDetailVO.setCuMemberBonusRangeList(cuMemberBonusRangeList);

        Map<Long, MemberBonusDetailCalVO> memberBonusDetailCalVoMap = new HashMap<>(ComputeUtil.mapInitCapacity(purchaseOrderList.size()));
        if (null != cuMemberBonusExpandList) {
            // 复购拓展
            cuMemberBonusExpandList.forEach(cuMemberBonusExpand -> {
                MemberBonusDetailCalVO memberBonusDetailCalVO = calculateOrderRatio(memberBonusDetailCalVoMap, cuMemberBonusExpand);
                memberBonusDetailCalVO.setRepExpandIncome(ComputeUtil.computeAdd(memberBonusDetailCalVO.getRepExpandIncome(), cuMemberBonusExpand.getRealIncome()));
            });
        }
        if (null != cuMemberBonusCoachList) {
            // 辅导收益
            cuMemberBonusCoachList.forEach(cuMemberBonusCoach -> {
                MemberBonusDetailCalVO memberBonusDetailCalVO = calculateOrderRatio(memberBonusDetailCalVoMap, cuMemberBonusCoach);
                memberBonusDetailCalVO.setRepCoachIncome(ComputeUtil.computeAdd(memberBonusDetailCalVO.getRepCoachIncome(), cuMemberBonusCoach.getRealIncome()));
            });
        }
        cuMemberBonusRangeList.forEach(cuMemberBonusRange -> {
            MemberBonusDetailCalVO memberBonusDetailCalVO = calculateOrderRatio(memberBonusDetailCalVoMap, cuMemberBonusRange);
            memberBonusDetailCalVO.setRepRangeIncome(ComputeUtil.computeAdd(memberBonusDetailCalVO.getRepRangeIncome(), cuMemberBonusRange.getRealIncome()));
        });

        Map<Long, SaOrderExt> saOrderExtMap = new HashMap<>(ComputeUtil.mapInitCapacity(purchaseOrderList.size()));
        purchaseOrderList.forEach(saOrderExt ->
                saOrderExtMap.put(saOrderExt.getPkId(), saOrderExt));
        if (null != cuMemberBonusExpandList) {
            // 复购拓展
            cuMemberBonusExpandList.forEach(cuMemberBonusExpand -> {
                MemberBonusDetailCalVO memberBonusDetailCalVO = memberBonusDetailCalVoMap.get(cuMemberBonusExpand.getPkOrder());
                SaOrderExt saOrderExt = saOrderExtMap.get(memberBonusDetailCalVO.getPkOrder());
                cuMemberBonusExpand.setIncomeDialRatio(ComputeUtil.computeDivide(memberBonusDetailCalVO.getRepExpandIncome(), memberBonusDetailCalVO.getRealIncome()));
                cuMemberBonusExpand.setOrderDialRatio(ComputeUtil.computeDivide(memberBonusDetailCalVO.getRealIncome(), saOrderExt.getOrderAmount()));
            });
        }
        if (null != cuMemberBonusCoachList) {
            // 辅导收益
            cuMemberBonusCoachList.forEach(cuMemberBonusCoach -> {
                MemberBonusDetailCalVO memberBonusDetailCalVO = memberBonusDetailCalVoMap.get(cuMemberBonusCoach.getPkOrder());
                SaOrderExt saOrderExt = saOrderExtMap.get(memberBonusDetailCalVO.getPkOrder());
                cuMemberBonusCoach.setIncomeDialRatio(ComputeUtil.computeDivide(memberBonusDetailCalVO.getRepCoachIncome(), memberBonusDetailCalVO.getRealIncome()));
                cuMemberBonusCoach.setOrderDialRatio(ComputeUtil.computeDivide(memberBonusDetailCalVO.getRealIncome(), saOrderExt.getOrderAmount()));
            });
        }
        // 复购极差
        cuMemberBonusRangeList.forEach(cuMemberBonusRange -> {
            MemberBonusDetailCalVO memberBonusDetailCalVO = memberBonusDetailCalVoMap.get(cuMemberBonusRange.getPkOrder());
            SaOrderExt saOrderExt = saOrderExtMap.get(memberBonusDetailCalVO.getPkOrder());
            cuMemberBonusRange.setIncomeDialRatio(ComputeUtil.computeDivide(memberBonusDetailCalVO.getRepRangeIncome(), memberBonusDetailCalVO.getRealIncome()));
            cuMemberBonusRange.setOrderDialRatio(ComputeUtil.computeDivide(memberBonusDetailCalVO.getRealIncome(), saOrderExt.getOrderAmount()));
        });
        // 插入奖金表 奖金明细表
        return leXueRangeParam;
    }

    /**
     * @param settleDate     结算日期
     * @param bonusConfigDTO 各个国家奖金参数
     * @Desccription: 计算云代的奖金
     * @return: Map<Long, CuMemberSettleExt> 需要更新的
     */
    private void calculateCloudAgentOrder(String settleDate, BonusConfigDTO bonusConfigDTO, Integer period, BonusRecordDetailVO bonusRecordDetailVO, Map<Long, CuMemberBonus> cuMemberBonusMap) {
        List<CuMemberBonusDetail> cuMemberBonusDetailList = bonusSettleAgentHandle.calculateCloudAgentAreaBonus(settleDate, bonusConfigDTO, period, cuMemberBonusMap);
        if (cuMemberBonusDetailList.size() > 0) {
            if (bonusRecordDetailVO.getCuMemberBonusDetailList() != null) {
                bonusRecordDetailVO.getCuMemberBonusDetailList().addAll(cuMemberBonusDetailList);
            } else {
                bonusRecordDetailVO.setCuMemberBonusDetailList(cuMemberBonusDetailList);
            }
        }
    }

    /*
     * @description: 计算复购券收益
     * @param: null null
     **/
    private void calculateRepurchaseCoupons(Date settleDate, List<SaOrderExt> firPurchaseOrderList, Integer period, BonusConfigDTO bonusConfigDTO, Map<Long, CuMemberBonus> cuMemberBonusMap,
                                            BonusRecordDetailVO bonusRecordDetailVO, Map<Long, CuMemberSettleExt> cuMemberSettleExtMap) {
        List<CuMemberBonusDetail> cuMemberBonusDetailList = bonusSettleRepCouponsHandle.calculateRepurchaseCoupons(settleDate, firPurchaseOrderList, period, bonusConfigDTO, cuMemberBonusMap, cuMemberSettleExtMap);
        if (cuMemberBonusDetailList.size() > 0) {
            if (bonusRecordDetailVO.getCuMemberBonusDetailList() != null) {
                bonusRecordDetailVO.getCuMemberBonusDetailList().addAll(cuMemberBonusDetailList);
            } else {
                bonusRecordDetailVO.setCuMemberBonusDetailList(cuMemberBonusDetailList);
            }
        }
    }

    /**
     * @param settleDateStr 结算日期
     * @Desccription: 计算云代的奖金
     * @return: Map<Long, CuMemberSettleExt> 需要更新的
     */
    private void calculateShareBonus(String settleDateStr, BonusConfigDTO bonusConfigDTO,
                                     Integer period, BonusRecordDetailVO bonusRecordDetailVO, Map<Long, CuMemberBonus> cuMemberBonusMap, Map<Long, CuAwardsControl> cuAwardsControlMap) {
        List<CuMemberBonusDetail> cuMemberBonusDetailList = bonusSettleFirstPurchaseHandle.calculateShareBonus(settleDateStr, bonusConfigDTO, period, cuMemberBonusMap, cuAwardsControlMap);
        if (CollectionUtil.isNotEmpty(cuMemberBonusDetailList)) {
            if (bonusRecordDetailVO.getCuMemberBonusDetailList() != null) {
                bonusRecordDetailVO.getCuMemberBonusDetailList().addAll(cuMemberBonusDetailList);
            } else {
                bonusRecordDetailVO.setCuMemberBonusDetailList(cuMemberBonusDetailList);
            }
        }
    }

    /**
     * @Description: 计算嗨粉订单的奖金
     * @return: void
     */
    private void calculateHiFunOrder(Map<Long, CuMemberSettleExt> cuMemberSettleExtMap, String settleTableName, Map<String, RangeDTO> rangeDtoMap,
                                     Map<String, BdAwards> awardsMap, BonusConfigDTO bonusConfigDTO, List<SaOrderExt> hiFunOrderList, Integer period, Map<Long, CuMemberBonus> cuMemberBonusMap, BonusRecordDetailVO bonusRecordDetailVO, Map<Long, CuAwardsControl> cuAwardsControlMap) {
        //*****************************嗨粉推荐奖金*****************************/
        List<CuMemberBonusDetail> cuMemberBonusDetailList = bonusSettleHiFunHandle.calculateHiFunPushBonus(cuMemberSettleExtMap, settleTableName, rangeDtoMap, awardsMap,
                bonusConfigDTO, hiFunOrderList, period, cuMemberBonusMap, cuAwardsControlMap);
        addCuMemberBonusDetail(bonusRecordDetailVO, cuMemberBonusDetailList);
        Map<Long, MemberBonusDetailCalVO> memberBonusDetailCalVoMap = new HashMap<>(ComputeUtil.mapInitCapacity(MagicNumberConstants.DELETE_DATA_BATCH_UPDATE_NUM));
        cuMemberBonusDetailList.forEach(cuMemberBonusDetail -> {
            MemberBonusDetailCalVO memberBonusDetailCalVO = calculateOrderRatio(memberBonusDetailCalVoMap, cuMemberBonusDetail);
            memberBonusDetailCalVO.setHiFunIncome(ComputeUtil.computeAdd(memberBonusDetailCalVO.getHiFunIncome(), cuMemberBonusDetail.getRealIncome()));
        });
        Map<Long, SaOrderExt> saOrderExtMap = new HashMap<>(ComputeUtil.mapInitCapacity(hiFunOrderList.size()));
        hiFunOrderList.forEach(saOrderExt ->
                saOrderExtMap.put(saOrderExt.getPkId(), saOrderExt));
        // 嗨粉收益
        cuMemberBonusDetailList.forEach(cuMemberBonusDetail -> {
            MemberBonusDetailCalVO memberBonusDetailCalVO = memberBonusDetailCalVoMap.get(cuMemberBonusDetail.getPkOrder());
            SaOrderExt saOrderExt = saOrderExtMap.get(memberBonusDetailCalVO.getPkOrder());
            cuMemberBonusDetail.setIncomeDialRatio(ComputeUtil.computeDivide(memberBonusDetailCalVO.getHiFunIncome(), memberBonusDetailCalVO.getRealIncome()));
            cuMemberBonusDetail.setOrderDialRatio(ComputeUtil.computeDivide(memberBonusDetailCalVO.getRealIncome(), ComputeUtil.computeDivide(saOrderExt.getOrderAmount(), saOrderExt.getInExchangeRate())));
        });
    }

    private static void addCuMemberBonusDetail(BonusRecordDetailVO bonusRecordDetailVO, List<CuMemberBonusDetail> cuMemberBonusDetailList) {
        if (cuMemberBonusDetailList.size() > 0) {
            if (bonusRecordDetailVO.getCuMemberBonusDetailList() != null) {
                bonusRecordDetailVO.getCuMemberBonusDetailList().addAll(cuMemberBonusDetailList);
            } else {
                bonusRecordDetailVO.setCuMemberBonusDetailList(cuMemberBonusDetailList);
            }
        }
    }

    /**
     * @Description: 计算订单奖金累计值
     * @return: void
     */
    private MemberBonusDetailCalVO calculateOrderRatio(Map<Long, MemberBonusDetailCalVO> memberBonusDetailVoMap, Object cuMemberBonus) {
        Long pkOrder = ReflectUtils.invokeGetter(cuMemberBonus, "pkOrder");
        MemberBonusDetailCalVO memberBonusDetailCalVO;
        if (memberBonusDetailVoMap.containsKey(pkOrder)) {
            memberBonusDetailCalVO = memberBonusDetailVoMap.get(pkOrder);
            memberBonusDetailCalVO.setPretaxIncome(ComputeUtil.computeAdd(memberBonusDetailCalVO.getPretaxIncome(), ReflectUtils.invokeGetter(cuMemberBonus, BonusFieldConstants.PRETAX_INCOME)));
            memberBonusDetailCalVO.setIncomeTax(ComputeUtil.computeAdd(memberBonusDetailCalVO.getIncomeTax(), ReflectUtils.invokeGetter(cuMemberBonus, BonusFieldConstants.INCOME_TAX)));
            memberBonusDetailCalVO.setRealIncome(ComputeUtil.computeAdd(memberBonusDetailCalVO.getRealIncome(), ReflectUtils.invokeGetter(cuMemberBonus, BonusFieldConstants.REAL_INCOME)));
        } else {
            memberBonusDetailCalVO = MemberBonusDetailCalVO.builder()
                    .pkOrder(ReflectUtils.invokeGetter(cuMemberBonus, "pkOrder"))
                    .pretaxIncome(ReflectUtils.invokeGetter(cuMemberBonus, "pretaxIncome"))
                    .incomeTax(ReflectUtils.invokeGetter(cuMemberBonus, "incomeTax"))
                    .realIncome(ReflectUtils.invokeGetter(cuMemberBonus, "realIncome"))
                    .pushIncome(BigDecimal.ZERO)
                    .expandIncome(BigDecimal.ZERO)
                    .coachIncome(BigDecimal.ZERO)
                    .serviceIncome(BigDecimal.ZERO)
                    .repExpandIncome(BigDecimal.ZERO)
                    .repCoachIncome(BigDecimal.ZERO)
                    .repRangeIncome(BigDecimal.ZERO)
                    .hiFunIncome(BigDecimal.ZERO)
                    .haiFunIncome(BigDecimal.ZERO)
                    .build();
            memberBonusDetailVoMap.put(pkOrder, memberBonusDetailCalVO);
        }
        return memberBonusDetailCalVO;
    }

    /**
     * 新拓展、领导奖处理
     */
    private void calculateNewExpandOrder(Map<Long, CuMemberRiskControl> riskControlMap, Map<Long, CuMemberSettleExt> cuMemberSettleExtMap, String settleTableName,
                                         String settleDate, BonusConfigDTO bonusConfigDTO, List<SaOrderExt> expandOrderList, Integer period,
                                         Map<Long, CuMemberBonus> cuMemberBonusMap, BonusRecordDetailVO bonusRecordDetailVO, List<BdAwards> awardsList,
                                         Map<Long, CuAwardsControl> cuAwardsControlMap, Map<Long, CuBonusExpandExt> cuBonusExpandExtMap) {
        //****************************计算量奖（拓展收益）*****************************/
        List<CuMemberBonusExpand> cuMemberBonusExpandList = bonusSettleNewExpandHandle.calculateNewExpandBonus(cuMemberSettleExtMap, settleTableName,
                bonusConfigDTO, expandOrderList, period, cuMemberBonusMap, cuBonusExpandExtMap);
        if (cuMemberBonusExpandList.size() > 0) {
            if (null == bonusRecordDetailVO.getCuMemberBonusExpandList()) {
                bonusRecordDetailVO.setCuMemberBonusExpandList(cuMemberBonusExpandList);
            } else {
                bonusRecordDetailVO.getCuMemberBonusExpandList().addAll(cuMemberBonusExpandList);
            }
            bonusSettlePurchaseHandle.handleFirExpandDelay(cuMemberBonusExpandList, period, bonusRecordDetailVO);
        }

        //*********************************计算领导奖（首购辅导收益）************************/
        // 判断是否有量奖，有量奖有辅导奖
        List<CuMemberBonusCoach> cuMemberBonusCoachList = bonusSettleFirstPurchaseHandle.calculateCoachBonus(cuMemberSettleExtMap, settleTableName, settleDate, bonusConfigDTO, expandOrderList,
                cuMemberBonusExpandList, period, cuMemberBonusMap, cuAwardsControlMap, riskControlMap, awardsList, true, true);
        if (cuMemberBonusCoachList.size() > 0) {
            if (CollectionUtil.isNotEmpty(bonusRecordDetailVO.getCuMemberBonusCoachList())) {
                bonusRecordDetailVO.getCuMemberBonusCoachList().addAll(cuMemberBonusCoachList);
            } else {
                bonusRecordDetailVO.setCuMemberBonusCoachList(cuMemberBonusCoachList);
            }
        }

        Map<Long, MemberBonusDetailCalVO> memberBonusDetailCalVoMap = new HashMap<>(ComputeUtil.mapInitCapacity(expandOrderList.size()));
        cuMemberBonusExpandList.forEach(cuMemberBonusExpand -> {
            MemberBonusDetailCalVO memberBonusDetailCalVO = calculateOrderRatio(memberBonusDetailCalVoMap, cuMemberBonusExpand);
            memberBonusDetailCalVO.setExpandIncome(ComputeUtil.computeAdd(memberBonusDetailCalVO.getExpandIncome(), cuMemberBonusExpand.getRealIncome()));
        });
        cuMemberBonusCoachList.forEach(cuMemberBonusCoach -> {
            MemberBonusDetailCalVO memberBonusDetailCalVO = calculateOrderRatio(memberBonusDetailCalVoMap, cuMemberBonusCoach);
            memberBonusDetailCalVO.setCoachIncome(ComputeUtil.computeAdd(memberBonusDetailCalVO.getCoachIncome(), cuMemberBonusCoach.getRealIncome()));
        });

        Map<Long, SaOrderExt> saOrderExtMap = new HashMap<>(ComputeUtil.mapInitCapacity(expandOrderList.size()));
        expandOrderList.forEach(saOrderExt -> saOrderExtMap.put(saOrderExt.getPkId(), saOrderExt));
        // 收益拓展
        cuMemberBonusExpandList.forEach(cuMemberBonusExpand -> {
            MemberBonusDetailCalVO memberBonusDetailCalVO = memberBonusDetailCalVoMap.get(cuMemberBonusExpand.getPkOrder());
            SaOrderExt saOrderExt = saOrderExtMap.get(memberBonusDetailCalVO.getPkOrder());
            cuMemberBonusExpand.setIncomeDialRatio(ComputeUtil.computeDivide(memberBonusDetailCalVO.getExpandIncome(), memberBonusDetailCalVO.getRealIncome()));
            cuMemberBonusExpand.setOrderDialRatio(ComputeUtil.computeDivide(memberBonusDetailCalVO.getRealIncome(), saOrderExt.getOrderAmount()));
        });
        // 辅导收益
        cuMemberBonusCoachList.forEach(cuMemberBonusCoach -> {
            MemberBonusDetailCalVO memberBonusDetailCalVO = memberBonusDetailCalVoMap.get(cuMemberBonusCoach.getPkOrder());
            SaOrderExt saOrderExt = saOrderExtMap.get(memberBonusDetailCalVO.getPkOrder());
            cuMemberBonusCoach.setIncomeDialRatio(ComputeUtil.computeDivide(memberBonusDetailCalVO.getCoachIncome(), memberBonusDetailCalVO.getRealIncome()));
            cuMemberBonusCoach.setOrderDialRatio(ComputeUtil.computeDivide(memberBonusDetailCalVO.getRealIncome(), saOrderExt.getOrderAmount()));
        });
    }

}
