package com.hzs.member.achieve.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.map.MapUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hzs.common.core.constant.*;
import com.hzs.common.core.domain.R;
import com.hzs.common.core.enums.*;
import com.hzs.common.core.utils.*;
import com.hzs.common.domain.member.achieve.CuMemberAchieve;
import com.hzs.common.domain.member.achieve.CuMemberSettlePeriod;
import com.hzs.common.domain.member.achieve.ext.CuMemberAchieveExt;
import com.hzs.common.domain.member.base.CuMember;
import com.hzs.common.domain.member.ext.CuMemberExt;
import com.hzs.common.domain.member.ext.CuMemberSettleExt;
import com.hzs.common.domain.member.ext.CuMemberTeamExt;
import com.hzs.common.domain.system.config.BdAwards;
import com.hzs.common.security.utils.SecurityUtils;
import com.hzs.common.service.ITransactionCommonService;
import com.hzs.member.account.service.ICuMemberBaseService;
import com.hzs.member.achieve.controller.vo.*;
import com.hzs.member.achieve.mapper.CuMemberAchieveMapper;
import com.hzs.member.achieve.param.MemberAchieveDisParam;
import com.hzs.member.achieve.param.MonthAchieveParam;
import com.hzs.member.achieve.service.ICuMemberAchieveService;
import com.hzs.member.achieve.service.ICuMemberMonthAchieveService;
import com.hzs.member.achieve.service.ICuMemberSettlePeriodService;
import com.hzs.member.achieve.service.ICuMemberTreeService;
import com.hzs.member.achieve.vo.*;
import com.hzs.member.base.IMemberTeamServiceApi;
import com.hzs.member.base.service.ICuMemberService;
import com.hzs.member.settlecenter.param.PlacementDataParam;
import com.hzs.member.settlecenter.vo.*;
import com.hzs.system.base.ICountryServiceApi;
import com.hzs.system.base.ICurrencyServiceApi;
import com.hzs.system.base.dto.CountryDTO;
import com.hzs.system.base.dto.CurrencyDTO;
import com.hzs.system.config.IAwardsServiceApi;
import com.hzs.system.config.IVertexServiceApi;
import com.hzs.system.config.dto.VertexDTO;
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 java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.Period;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.stream.Collectors;

/**
 * 会员业绩记录 服务实现类
 */
@Slf4j
@Service
public class CuMemberAchieveServiceImpl extends ServiceImpl<CuMemberAchieveMapper, CuMemberAchieve> implements ICuMemberAchieveService {

    @Autowired
    private ICuMemberTreeService iCuMemberTreeService;
    @Autowired
    private ICuMemberService iCuMemberService;
    @Autowired
    private ICuMemberSettlePeriodService iCuMemberSettlePeriodService;
    @Autowired
    private ICuMemberBaseService iCuMemberBaseService;
    @Autowired
    private ICuMemberMonthAchieveService iCuMemberMonthAchieveService;
    @Autowired
    private ITransactionCommonService iTransactionCommonService;

    @DubboReference
    ICountryServiceApi iCountryServiceApi;
    @DubboReference
    IAwardsServiceApi iAwardsServiceApi;
    @DubboReference
    IVertexServiceApi iVertexServiceApi;
    @DubboReference
    ICurrencyServiceApi iCurrencyServiceApi;
    @DubboReference
    IMemberTeamServiceApi iMemberTeamServiceApi;

    @Override
    public CuMemberAchieve queryCuMemberAchieveByPkMember(Long pkMember, Integer pkCountry) {
        Date currentDate = DateUtils.currentDate();
        // 查看秒接表，秒接表不存在查询昨天的结算表
        int currentPeriod = iCuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, currentDate)).getPkId();
        String currentTableName = TableNameConstants.CU_MEMBER_SECOND + currentPeriod;
        CuMemberAchieve cuMemberAchieve = baseMapper.queryCuMemberAchieveByPkMember(pkMember, pkCountry, currentTableName);
        if (cuMemberAchieve != null) {
            if (ComputeUtil.compareValue(ComputeUtil.computeAdd(cuMemberAchieve.getASumPv(), cuMemberAchieve.getBSumPv())) ||
                    ComputeUtil.compareValue(cuMemberAchieve.getRepASumPv(), cuMemberAchieve.getRepBSumPv())) {
                return cuMemberAchieve;
            }
        }
        // 创建日表记录表
        int period = iCuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(
                DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, DateUtils.beforeDate(1, ChronoUnit.DAYS, currentDate))).getPkId();
        String settleTableName = TableNameConstants.CU_MEMBER_SETTLE + period;
        return baseMapper.queryCuMemberAchieveByPkMember(pkMember, pkCountry, settleTableName);
    }

    @Override
    public CuMemberDisVO queryCuMemberAchieveDis(MemberAchieveDisParam memberAchieveDisParam) {
        // 判断时间 当前时间查询cu_member
        CuMemberAchieveDisVO leftMemberAchieveDisVO = new CuMemberAchieveDisVO();
        CuMemberAchieveDisVO rightMemberAchieveDisVO = new CuMemberAchieveDisVO();
        // 查询会员信息
        List<CuMemberExt> cuMemberExtList = iCuMemberService.queryMemberByCondition(CuMember.builder().pkId(memberAchieveDisParam.getPkMember()).build());
        CuMemberExt cuMember = cuMemberExtList.get(0);
        String image = setGradeImageUrl(cuMember.getCategory(), cuMember.getGradeValue());
        CuMemberDisVO cuMemberDisVO = CuMemberDisVO.builder()
                .memberName(cuMember.getMemberName())
                .memberCode(CommonUtil.getMemberCode(cuMember.getMemberCode(), cuMember.getServiceCode()))
                .imageUrl(image)
                .build();
        List<CuMemberExt> lastCuMemberList = iCuMemberService.queryCuMemberLastPlaceParent(memberAchieveDisParam.getPkMember());
        if (CollectionUtil.isNotEmpty(lastCuMemberList)) {
            for (CuMemberExt cuMemberExt : lastCuMemberList) {
                String imageUrl = setGradeImageUrl(cuMemberExt.getCategory(), cuMemberExt.getGradeValue());
                packageLastMember(leftMemberAchieveDisVO, rightMemberAchieveDisVO, cuMemberExt.getPlaceDept(),
                        CommonUtil.getMemberCode(cuMemberExt.getMemberCode(), cuMemberExt.getServiceCode()),
                        CommonUtil.getMemberName(cuMemberExt.getPkVertex(), cuMemberExt.getMemberName(), cuMemberExt.getNickName()),
                        imageUrl);
            }
        }
        if (StringUtils.isEmpty(leftMemberAchieveDisVO.getLastMemberCode())) {
            leftMemberAchieveDisVO.setLastMemberCode(cuMember.getMemberCode());
            leftMemberAchieveDisVO.setLastMemberName(cuMember.getMemberName());
            String imageUrl = setGradeImageUrl(cuMember.getCategory(), cuMember.getGradeValue());
            leftMemberAchieveDisVO.setLastImageUrl(imageUrl);
        }
        // 左区会员
        cuMemberDisVO.setLeftMember(leftMemberAchieveDisVO);
        if (StringUtils.isEmpty(rightMemberAchieveDisVO.getLastMemberCode())) {
            rightMemberAchieveDisVO.setLastMemberCode(cuMember.getMemberCode());
            rightMemberAchieveDisVO.setLastMemberName(cuMember.getMemberName());
            String imageUrl = setGradeImageUrl(cuMember.getCategory(), cuMember.getGradeValue());
            rightMemberAchieveDisVO.setLastImageUrl(imageUrl);
        }
        // 右区会员
        cuMemberDisVO.setRightMember(rightMemberAchieveDisVO);
        return cuMemberDisVO;
    }

    @Override
    public CuMemberDisVO queryCuMemberDis(MemberAchieveDisParam memberAchieveDisParam) {
//        Date currentDate = DateUtils.currentDate();
//        if (DateUtils.compareDateBefore(memberAchieveDisParam.getSettleDate(), currentDate)) {
//            // 从历史表中获取
//            CuMemberSettlePeriod cuMemberSettlePeriod = iCuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, memberAchieveDisParam.getSettleDate()));
//            String tableName = TableNameConstants.CU_MEMBER_SETTLE + cuMemberSettlePeriod.getPkId();
//            CuMemberExt member = iCuMemberService.getMemberByCode(memberAchieveDisParam.getMemberCode());
//            List<CuMemberSettleExt> cuMemberSettleExtList = iCuMemberTreeService.queryCuMemberTree(tableName, member.getPkId(), null);
//            return BeanUtil.copyProperties(cuMemberSettleExtList.get(0), CuMemberDisVO.class);
//        }else{
        CuMember cuMember = iCuMemberService.queryMember(memberAchieveDisParam.getMemberCode());
        CuMemberDisVO cuMemberDisVO = BeanUtil.copyProperties(cuMember, CuMemberDisVO.class);
        cuMemberDisVO.setMemberCode(CommonUtil.getMemberCode(cuMember.getMemberCode(), cuMember.getServiceCode()));
        cuMemberDisVO.setMemberName(CommonUtil.getMemberName(cuMember.getPkVertex(), cuMember.getMemberName(), cuMember.getNickName()));
        if (memberAchieveDisParam.getPkCountry().equals(CountryConstants.CHINA_COUNTRY)) {
            //根据国家查汇率
            BigDecimal rate = iCuMemberBaseService.getCurrency(memberAchieveDisParam.getPkCountry()).getInExchangeRate();
            cuMemberDisVO.setConsumeAchieve(ComputeUtil.computeMultiply(cuMemberDisVO.getConsumeAchieve(), rate));
        }
        return cuMemberDisVO;
//        }
    }

    private String setGradeImageUrl(Integer category, Integer gradeValue) {
        for (EGrade grade : EGrade.values()) {
            if (ECategory.NORMAL.getValue() != category && -category == grade.getValue()) {
                return grade.getImageUrl();
            } else if (gradeValue == grade.getValue()) {
                return grade.getImageUrl();
            }
        }
        return MemberFrameworkConstants.xuni;
    }

    @Override
    public BigDecimal queryCuMemberUnderBloodAchieveByPkMember(MemberAchieveDisParam memberAchieveDisParam) {
        return null;
    }

    /**
     * 最末安置人
     */
    private static void packageLastMember(CuMemberAchieveDisVO leftMemberAchieveDisVO, CuMemberAchieveDisVO rightMemberAchieveDisVO, Integer placeDept, String memberCode, String memberName, String imageUrl) {
        if (EPlaceDept.LEFT_DEPT.getValue() == placeDept) {
            leftMemberAchieveDisVO.setLastMemberCode(memberCode);
            leftMemberAchieveDisVO.setLastMemberName(memberName);
            leftMemberAchieveDisVO.setLastImageUrl(imageUrl);
        } else {
            rightMemberAchieveDisVO.setLastMemberCode(memberCode);
            rightMemberAchieveDisVO.setLastMemberName(memberName);
            rightMemberAchieveDisVO.setLastImageUrl(imageUrl);
        }
    }

    @Override
    public List<CuMemberNewAddAchieveVO> selectNewAddAchieve(CuMemberNewAddAchieveVO cuMemberNewAddAchieveVO) {
        LocalDate endDate = LocalDate.now();
        LocalDate startDate = getStartDateByType(cuMemberNewAddAchieveVO.getDayType(), endDate);
        return selectNewAddAchieveByDate(cuMemberNewAddAchieveVO, endDate, startDate);
    }

    /**
     * 根据日期查询会员的新增业绩
     *
     * @param cuMemberNewAddAchieveVO 入参
     * @param endDate                 结束时间
     * @param startDate               开始时间
     * @return List<CuMemberNewAddAchieveVO>
     */
    private List<CuMemberNewAddAchieveVO> selectNewAddAchieveByDate(CuMemberNewAddAchieveVO cuMemberNewAddAchieveVO, LocalDate endDate, LocalDate startDate) {
        String upAchieveTableName = null;
        BigDecimal rate = null;
        String startDateStr = startDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        String endDateStr = endDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        //当前月份第一天
        LocalDate firstMonthDay = endDate.with(TemporalAdjusters.firstDayOfMonth());
        //判断是否跨月
        if (!firstMonthDay.isEqual(LocalDate.now()) && startDate.isBefore(firstMonthDay)) {
            upAchieveTableName = TableNameConstants.CU_MEMBER_ACHIEVE + DateUtils.getMonth(startDateStr);
        }
        String achieveTableName = TableNameConstants.CU_MEMBER_ACHIEVE + DateUtils.getMonth(LocalDate.now().minus(1, ChronoUnit.DAYS).format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        cuMemberNewAddAchieveVO.setStartDate(startDateStr);
        cuMemberNewAddAchieveVO.setEndDate(endDateStr);
        cuMemberNewAddAchieveVO.setAchieveTableName(achieveTableName);
        cuMemberNewAddAchieveVO.setUpAchieveTableName(upAchieveTableName);
        List<CuMemberNewAddAchieveVO> cuMemberNewAddAchieveVOList = baseMapper.selectNewAddAchieve(cuMemberNewAddAchieveVO);
        if (CollUtil.isNotEmpty(cuMemberNewAddAchieveVOList)) {
            //中国转汇率
            Integer pkCountry = cuMemberNewAddAchieveVO.getPkCountry();
            if (pkCountry.equals(CountryConstants.CHINA_COUNTRY)) {
                //根据国家查汇率
                rate = iCuMemberBaseService.getCurrency(pkCountry).getInExchangeRate();
            }
            for (CuMemberNewAddAchieveVO newAddAchieveVO : cuMemberNewAddAchieveVOList) {
                //转化单位万
                BigDecimal aNewPv = newAddAchieveVO.getANewPv().divide(MagicNumberConstants.big10000);
                BigDecimal bNewPv = newAddAchieveVO.getBNewPv().divide(MagicNumberConstants.big10000);
                BigDecimal aRegNewPv = newAddAchieveVO.getRepANewPv().divide(MagicNumberConstants.big10000);
                BigDecimal bRegNewPv = newAddAchieveVO.getRepBNewPv().divide(MagicNumberConstants.big10000);

                newAddAchieveVO.setANewPv(null != rate ? aNewPv.multiply(rate) : aNewPv);
                newAddAchieveVO.setBNewPv(null != rate ? bNewPv.multiply(rate) : bNewPv);
                newAddAchieveVO.setRepANewPv(null != rate ? aRegNewPv.multiply(rate) : aRegNewPv);
                newAddAchieveVO.setRepBNewPv(null != rate ? bRegNewPv.multiply(rate) : bRegNewPv);
            }
        }
        initialDate(cuMemberNewAddAchieveVOList, endDate, startDate);
        return cuMemberNewAddAchieveVOList;
    }

    /**
     * 初如化日期值
     *
     * @param cuMemberNewAddAchieveVOList 查询结题
     * @param endDate                     开始时间
     * @param startDate                   结束时间
     * @return List<CuMemberNewAddAchieveVO>
     */
    private List<CuMemberNewAddAchieveVO> initialDate(List<CuMemberNewAddAchieveVO> cuMemberNewAddAchieveVOList, LocalDate endDate, LocalDate startDate) {
        Period between = Period.between(startDate, endDate);
        //相差天数
        int days = between.getDays();
        int months = between.getMonths();
        if (months == 1) {
            days = 30;
        }
        //初始化日期
        if (CollUtil.isEmpty(cuMemberNewAddAchieveVOList)) {
            CuMemberNewAddAchieveVO memberNewAddAchieveVO;
            cuMemberNewAddAchieveVOList = new ArrayList<>();
            for (int i = 0; i < days; i++) {
                memberNewAddAchieveVO = CuMemberNewAddAchieveVO.builder().settleDate(DateUtils.toDate(startDate.plusDays(i)))
                        .aNewPv(BigDecimal.ZERO).bNewPv(BigDecimal.ZERO).repANewPv(BigDecimal.ZERO).repBNewPv(BigDecimal.ZERO)
                        .build();
                cuMemberNewAddAchieveVOList.add(memberNewAddAchieveVO);
            }
        } else {
            CuMemberNewAddAchieveVO memberNewAddAchieveVO;
            Map<Date, CuMemberNewAddAchieveVO> map = cuMemberNewAddAchieveVOList.stream().collect(Collectors.toMap(CuMemberNewAddAchieveVO::getSettleDate, o -> o));
            for (int i = 0; i < days; i++) {
                Date localDate = DateUtils.toDate(startDate.plusDays(i));
                if (null == map.get(localDate)) {
                    memberNewAddAchieveVO = CuMemberNewAddAchieveVO.builder().settleDate(localDate)
                            .aNewPv(BigDecimal.ZERO).bNewPv(BigDecimal.ZERO).repANewPv(BigDecimal.ZERO).repBNewPv(BigDecimal.ZERO)
                            .build();
                    cuMemberNewAddAchieveVOList.add(memberNewAddAchieveVO);
                }
            }
            //排序
            cuMemberNewAddAchieveVOList.sort(Comparator.comparing(CuMemberNewAddAchieveVO::getSettleDate));
        }
        return cuMemberNewAddAchieveVOList;
    }

    /**
     * 根据天数类型获取开始日期
     *
     * @param dayType 天数类型
     * @return LocalDate
     */
    @Override
    public LocalDate getStartDateByType(Integer dayType, LocalDate localDate) {
        LocalDate startDate;
        if (null == localDate) {
            localDate = LocalDate.now();
        }
        if (EDayType.LAST_SEVEN_DAY.getValue() == dayType) {
            startDate = localDate.minus(7, ChronoUnit.DAYS);
        } else if (EDayType.LAST_FIFTEEN_DAY.getValue() == dayType) {
            startDate = localDate.minus(15, ChronoUnit.DAYS);
        } else {
            startDate = localDate.minus(1, ChronoUnit.MONTHS);
        }
        return startDate;
    }

    @Override
    public CuMemberAwardsUnderVO indexMemberAwards(Long pkMember, Integer pkCountry) {
        boolean hasSettle = false;
        // 昨天结算表
        String settleTable = null;
        for (int i = 1; i <= 3; i++) {
            // 昨天的日期（最多查3天的，如果3天内都没有结算数据则直接全部返回0）
            String localDate = LocalDate.now().minus(i, ChronoUnit.DAYS).format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            // 查询会员昨日业绩表
            settleTable = TableNameConstants.CU_MEMBER_SETTLE + iCuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(localDate).getPkId();
            Integer number = iCuMemberTreeService.queryExistOracleTable(settleTable);
            if (null != number && number > 0) {
                // 结算表存在
                hasSettle = true;
                break;
            }
        }

        // 当日新増PV
        CuMemberAwardsUnderVO todayPv = iCuMemberTreeService.queryMemberTodayPv(pkMember);
        // 返回显示VO
        CuMemberAwardsUnderVO resultVO = CuMemberAwardsUnderVO.builder()
                .aNewPv(BigDecimal.ZERO)
                .bNewPv(BigDecimal.ZERO)
                .aMonthPv(BigDecimalUtil.handleBig10000Down(todayPv.getANewPv()))
                .bMonthPv(BigDecimalUtil.handleBig10000Down(todayPv.getBNewPv()))
                .aSumPv(BigDecimal.ZERO)
                .bSumPv(BigDecimal.ZERO)
                .aSumRealPv(BigDecimal.ZERO)
                .bSumRealPv(BigDecimal.ZERO)
                .build();

        if (hasSettle) {
            // 昨日业绩 -- 昨日结算表
            // 历史业绩 -- 昨日结算表
            // 当月业绩 -- 月业绩表
            String month = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMM"));
            // 当月业绩表
            String monthTable = TableNameConstants.CU_MEMBER_MONTH + month;
            Integer number = iCuMemberTreeService.queryExistOracleTable(monthTable);
            if (null == number || number == 0) {
                // 月业绩表不存在
                monthTable = null;
            }

            // 查询会员首页业绩显示
            CuMemberAwardsUnderVO awardsUnderVO = iCuMemberTreeService.queryMemberPv(settleTable, pkMember, monthTable);
            if (null != awardsUnderVO) {
                resultVO.setANewPv(null != awardsUnderVO.getANewPv() ? BigDecimalUtil.handleBig10000Down(awardsUnderVO.getANewPv()) : BigDecimal.ZERO);
                resultVO.setBNewPv(null != awardsUnderVO.getBNewPv() ? BigDecimalUtil.handleBig10000Down(awardsUnderVO.getBNewPv()) : BigDecimal.ZERO);
                resultVO.setAMonthPv(null != awardsUnderVO.getAMonthPv() ? BigDecimalUtil.handleBig10000Down(todayPv.getANewPv().add(awardsUnderVO.getAMonthPv())) : BigDecimalUtil.handleBig10000Down(todayPv.getANewPv()));
                resultVO.setBMonthPv(null != awardsUnderVO.getBMonthPv() ? BigDecimalUtil.handleBig10000Down(todayPv.getBNewPv().add(awardsUnderVO.getBMonthPv())) : BigDecimalUtil.handleBig10000Down(todayPv.getBNewPv()));
                resultVO.setASumPv(null != awardsUnderVO.getASumPv() ? awardsUnderVO.getASumPv() : BigDecimal.ZERO);
                resultVO.setBSumPv(null != awardsUnderVO.getBSumPv() ? awardsUnderVO.getBSumPv() : BigDecimal.ZERO);
                resultVO.setASumRealPv(null != awardsUnderVO.getASumRealPv() ? awardsUnderVO.getASumRealPv() : BigDecimal.ZERO);
                resultVO.setBSumRealPv(null != awardsUnderVO.getBSumRealPv() ? awardsUnderVO.getBSumRealPv() : BigDecimal.ZERO);
            }
        }

        // 当前会员
        CuMember cuMember = iCuMemberService.getMember(pkMember);
        //根据国家获取奖衔配置信息
        List<BdAwards> awardsList = iAwardsServiceApi.queryAwards(pkCountry).getData();
        // 当前会员奖衔
        BdAwards bdAwards = awardsList.stream()
                .filter(tmp -> tmp.getPkId().equals(cuMember.getPkAwards()))
                .findFirst().get();
        if (bdAwards.getAwardsValue() < EAwards.SENIOR_CHIEF.getValue()) {
            // 不是最后三级，需要显示业绩
            // 大于当前奖衔的列表
            BdAwards nextBdAwards = awardsList.stream()
                    .filter(tmp -> tmp.getAwardsValue() > bdAwards.getAwardsValue())
                    .min(Comparator.comparingInt(BdAwards::getAwardsValue)).get();
            resultVO.setTarAwardsName(nextBdAwards.getAwardsName());
            resultVO.setTargetPv(BigDecimalUtil.handleBig10000Down(nextBdAwards.getCommunityCheck()));

            if (resultVO.getASumRealPv().add(todayPv.getANewPv()).compareTo(resultVO.getBSumRealPv().add(todayPv.getBNewPv())) <= 0) {
                // 左区 小于等于 右区，左区为小区
                resultVO.setSumRealPv(BigDecimalUtil.handleBig10000Down(resultVO.getASumRealPv().add(todayPv.getANewPv())));
            } else {
                // 右区为小区
                resultVO.setSumRealPv(BigDecimalUtil.handleBig10000Down(resultVO.getBSumRealPv().add(todayPv.getBNewPv())));
            }
        }

        resultVO.setASumPv(BigDecimalUtil.handleBig10000Down(resultVO.getASumPv()));
        resultVO.setBSumPv(BigDecimalUtil.handleBig10000Down(resultVO.getBSumPv()));
        resultVO.setASumRealPv(BigDecimalUtil.handleBig10000Down(resultVO.getASumRealPv()));
        resultVO.setBSumRealPv(BigDecimalUtil.handleBig10000Down(resultVO.getBSumRealPv()));
        return resultVO;
    }

    /**
     * 根据月底最后一天判断大小区
     *
     * @param pkMember  会员ID
     * @param pkCountry 国家ID
     * @return CuMemberAwardsUnderVO
     */
    public CuMemberAwardsUnderVO getBigSmallArea(Long pkMember, Integer pkCountry) {
        //获取期数
        String upLastMonth = DateUtils.beforeMonthLastDateStr(new Date());
        int period = iCuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(upLastMonth).getPkId();
        //查询会员结余判断大小区
        String settleTable = TableNameConstants.CU_MEMBER_SETTLE + period;
        CuMemberAwardsUnderVO memberAwards = CuMemberAwardsUnderVO.builder().settleTable(settleTable).pkMember(pkMember).pkCountry(pkCountry).period(period).build();
        return baseMapper.selectBalanceByPkMember(memberAwards);
    }

    /**
     * 根据实时小区业绩获取奖衔
     *
     * @param pkMember  会员ID
     * @param pkCountry 国家ID
     * @return Integer
     */
    @Override
    public CuMemberAwardsUnderVO getPkAwardBySmallAchieve(Long pkMember, Integer pkCountry, boolean yesterdayFlag) {
        CuMemberAwardsUnderVO cuMemberAwardsUnderVO = null;
        //根据上月月底判断大小区
        CuMemberAwardsUnderVO bigSmallArea = getBigSmallArea(pkMember, pkCountry);

        if (yesterdayFlag) {
            //查询历史小区业绩、昨日业绩
            String localDate = LocalDate.now().minus(1, ChronoUnit.DAYS).format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            int period = iCuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(localDate).getPkId();
            //查询会员昨日业绩
            String settleTable = TableNameConstants.CU_MEMBER_SETTLE + period;
            CuMemberAwardsUnderVO memberAwards = CuMemberAwardsUnderVO.builder().settleTable(settleTable).pkMember(pkMember).pkCountry(pkCountry).period(period).build();
            cuMemberAwardsUnderVO = baseMapper.selectBalanceByPkMember(memberAwards);
        }

        if (null == cuMemberAwardsUnderVO) {
            cuMemberAwardsUnderVO = CuMemberAwardsUnderVO.builder().aSumPv(BigDecimal.ZERO).bSumPv(BigDecimal.ZERO)
                    .aNewPv(BigDecimal.ZERO).bNewPv(BigDecimal.ZERO).build();
        }
        //查询本月新增业绩
        String month = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMM"));
        CuMemberAwardsUnderVO cuMemberMonthTable = CuMemberAwardsUnderVO.builder()
                .cuMemberMonthTable(TableNameConstants.CU_MEMBER_MONTH + month).pkMember(pkMember).build();
        CuMemberAwardsUnderVO memberSmallAchieve = baseMapper.selectMemberSmallAchieve(cuMemberMonthTable);
        if (null != memberSmallAchieve) {
            BigDecimal aSumPv = memberSmallAchieve.getASumPv();
            BigDecimal bSumPv = memberSmallAchieve.getBSumPv();
            if (null != bigSmallArea) {
                Integer placeDept = bigSmallArea.getPlaceDept();
                //根据小区获取业绩
                if (placeDept.equals(EPlaceDept.LEFT_DEPT.getValue())) {
                    cuMemberAwardsUnderVO.setSumRealPv(aSumPv);
                } else if (placeDept.equals(EPlaceDept.RIGHT_DEPT.getValue())) {
                    cuMemberAwardsUnderVO.setSumRealPv(bSumPv);
                } else {
                    //如果左右区的业绩为0，则左区为小区
                    cuMemberAwardsUnderVO.setSumRealPv(aSumPv.add(bSumPv));
                }
            } else {
                //如果左右区的业绩为0或者为空，则取本月的小区业绩
                cuMemberAwardsUnderVO.setSumRealPv(aSumPv.add(bSumPv));
            }
        } else {
            cuMemberAwardsUnderVO.setSumRealPv(BigDecimal.ZERO);
        }


        //根据国家获取奖衔配置信息
        List<BdAwards> awardsList = iAwardsServiceApi.queryAwards(pkCountry).getData();
        cuMemberAwardsUnderVO.setAwardsList(awardsList);
        //获取当前会员的奖衔
        cuMemberAwardsUnderVO.setPkAwards(getMemberAwards(awardsList, cuMemberAwardsUnderVO.getSumRealPv()));
        return cuMemberAwardsUnderVO;
    }

    /**
     * 获取会员奖衔
     *
     * @param awardsList 奖衔列表
     * @param sumRealPv  小区业绩
     * @return Integer
     */

    private Integer getMemberAwards(List<BdAwards> awardsList, BigDecimal sumRealPv) {
        for (BdAwards awards : awardsList) {
            BigDecimal communityCheck = awards.getCommunityCheck();
            BigDecimal communityCheckEnd = awards.getCommunityCheckEnd();
            if (sumRealPv.compareTo(communityCheck) >= 0 && null != communityCheckEnd && communityCheckEnd.compareTo(sumRealPv) > 0) {
                return awards.getPkId();
            }
        }
        return null;
    }

    @Override
    public CuMemberAwardsDisVO selectAwardsByPkMember(Long pkMember, Integer pkCountry) {
        BigDecimal rate = null;
        //获取期数
        String date = LocalDate.now().minus(1, ChronoUnit.DAYS).format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        int period = iCuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(date).getPkId();

        //根据国家获取奖衔配置信息
        List<BdAwards> awardsList = iAwardsServiceApi.queryAwards(pkCountry).getData();
        //升序排序
        awardsList.sort(Comparator.comparing(BdAwards::getAwardsValue));

        Map<Integer, BdAwards> awardsMap = awardsList.stream().collect(Collectors.toMap(BdAwards::getAwardsValue, o -> o));

        String settleTable = TableNameConstants.CU_MEMBER_SETTLE + period;
        //查询会员的荣誉头衔
        CuMemberAwardsUnderVO memberAwards = CuMemberAwardsUnderVO.builder().settleTable(settleTable).pkMember(pkMember).pkCountry(pkCountry).period(period).build();
        CuMemberAwardsUnderVO memberAwardsUnderVO = baseMapper.selectAwardsByPkMember(memberAwards);

        //根据国家查汇率
        if (pkCountry.equals(CountryConstants.CHINA_COUNTRY)) {
            rate = iCuMemberBaseService.getCurrency(pkCountry).getInExchangeRate();
        }
        if (null == memberAwardsUnderVO) {
            CuMember member = iCuMemberService.getMember(pkMember);
            BdAwards bdAwards = iAwardsServiceApi.getAwardsOne(member.getPkAwards()).getData();
            //取当前奖衔值的下一个奖衔值
            List<BdAwards> list = awardsList.stream().filter(awards -> awards.getAwardsValue() > bdAwards.getAwardsValue()).collect(Collectors.toList());
            BigDecimal targetPv = awardsMap.get(list.get(0).getAwardsValue()).getCommunityCheck();
            memberAwardsUnderVO = CuMemberAwardsUnderVO.builder()
                    .aSumRealPv(BigDecimal.ZERO).bSumRealPv(BigDecimal.ZERO)
                    .sumRealPv(BigDecimal.ZERO).build();
            memberAwardsUnderVO.setAwardsName(bdAwards.getAwardsName());
            memberAwardsUnderVO.setPkTransaction(bdAwards.getPkTransaction());
            if (null != targetPv) {
                memberAwardsUnderVO.setTargetPv(targetPv.divide(MagicNumberConstants.big10000));
            }
        } else {
            CuMember member = iCuMemberService.getMember(pkMember);
            memberAwardsUnderVO.setMemberName(member.getMemberName());
            getCuMemberAwars(memberAwardsUnderVO, awardsMap, awardsList, false, pkCountry, rate);
        }

        //查询左区荣誉头衔
        CuMemberAwardsUnderVO leftMemberAwards = CuMemberAwardsUnderVO.builder().settleTable(settleTable)
                .pkMember(pkMember).pkCountry(pkCountry).period(period).placeDept(1).build();
        List<CuMemberAwardsUnderVO> leftMemberAwardsUnderVOList = baseMapper.selectUnderMemberAwards(leftMemberAwards);
        if (CollUtil.isNotEmpty(leftMemberAwardsUnderVOList)) {
            for (CuMemberAwardsUnderVO cuMemberAwardsUnderVO : leftMemberAwardsUnderVOList) {
                getCuMemberAwars(cuMemberAwardsUnderVO, awardsMap, awardsList, true, pkCountry, rate);
            }
            //补全默认条数
            int size = leftMemberAwardsUnderVOList.size();
            if (size < 5) {
                leftMemberAwardsUnderVOList.addAll(getAwardDefaultValue(5 - size));
            }
        } else {
            leftMemberAwardsUnderVOList = getAwardDefaultValue(5);
        }

        //查询右区荣誉头衔
        CuMemberAwardsUnderVO rightMemberAwards = CuMemberAwardsUnderVO.builder().settleTable(settleTable)
                .pkMember(pkMember).pkCountry(pkCountry).period(period).placeDept(2).build();
        List<CuMemberAwardsUnderVO> rightMemberAwardsUnderVOList = baseMapper.selectUnderMemberAwards(rightMemberAwards);
        if (CollUtil.isNotEmpty(rightMemberAwardsUnderVOList)) {
            for (CuMemberAwardsUnderVO cuMemberAwardsUnderVO : rightMemberAwardsUnderVOList) {
                getCuMemberAwars(cuMemberAwardsUnderVO, awardsMap, awardsList, true, pkCountry, rate);
            }
            //补全默认条数
            int size = rightMemberAwardsUnderVOList.size();
            if (size < 5) {
                rightMemberAwardsUnderVOList.addAll(getAwardDefaultValue(5 - size));
            }

        } else {
            rightMemberAwardsUnderVOList = getAwardDefaultValue(5);
        }
        return CuMemberAwardsDisVO.builder().memberAwardsUnderVO(memberAwardsUnderVO)
                .leftMemberAwardsUnderList(leftMemberAwardsUnderVOList).rightMemberAwardsUnderList(rightMemberAwardsUnderVOList).build();
    }

    /**
     * 获取荣誉奖衔默认值
     *
     * @return List<CuMemberAwardsUnderVO>
     */
    private List<CuMemberAwardsUnderVO> getAwardDefaultValue(int num) {
        CuMemberAwardsUnderVO cuMemberAwardsUnderVO;
        List<CuMemberAwardsUnderVO> cuMemberAwardsUnderVOList = new ArrayList<>();
        for (int i = 0; i < num; i++) {
            cuMemberAwardsUnderVO = CuMemberAwardsUnderVO.builder()
                    .aSumRealPv(BigDecimal.ZERO).bSumRealPv(BigDecimal.ZERO)
                    .sumRealPv(BigDecimal.ZERO).build();
            cuMemberAwardsUnderVOList.add(cuMemberAwardsUnderVO);
        }
        return cuMemberAwardsUnderVOList;
    }

    /**
     * 封装奖衔配置
     *
     * @param memberAwardsUnderVO 伞下奖衔
     * @param awardsMap           奖衔配置信息
     * @param isTransaction       是否框架翻译
     * @return CuMemberAwardsUnderVO
     */
    private CuMemberAwardsUnderVO getCuMemberAwars(CuMemberAwardsUnderVO memberAwardsUnderVO, Map<Integer, BdAwards> awardsMap, List<BdAwards> awardsList, Boolean isTransaction, Integer pkCountry, BigDecimal rate) {
        if (null != memberAwardsUnderVO) {
            //转换会员名称为昵称
            memberAwardsUnderVO.setMemberName(CommonUtil.getMemberName(memberAwardsUnderVO.getPkVertex(), memberAwardsUnderVO.getMemberName(), memberAwardsUnderVO.getNickName()));
            //业绩以万为单位
            memberAwardsUnderVO.setASumRealPv(memberAwardsUnderVO.getASumRealPv().multiply(rate).divide(MagicNumberConstants.big10000, 2, BigDecimal.ROUND_DOWN));
            memberAwardsUnderVO.setBSumRealPv(memberAwardsUnderVO.getBSumRealPv().multiply(rate).divide(MagicNumberConstants.big10000, 2, BigDecimal.ROUND_DOWN));
            Integer pkAwards = memberAwardsUnderVO.getPkAwards();
            if (null == pkAwards) {
                return null;
            }
            BdAwards BdAwards = iAwardsServiceApi.getAwardsOne(pkAwards).getData();
            memberAwardsUnderVO.setAwardsName(BdAwards.getAwardsName());
            memberAwardsUnderVO.setPkTransaction(BdAwards.getPkTransaction());
            if (!isTransaction) {
                Map<Integer, String> accountMap = iTransactionCommonService.exportEnumTransactionByDB(EnumsPrefixConstants.KEY_AWARD);
                memberAwardsUnderVO.setPkTransactionVal(accountMap.get(BdAwards.getPkTransaction()));
            }
            memberAwardsUnderVO.setImage(BdAwards.getImage());
            Integer awardsValue = BdAwards.getAwardsValue();
            //取当前奖衔值的下一个奖衔值
            List<BdAwards> list = awardsList.stream().filter(awards -> awards.getAwardsValue() > awardsValue).collect(Collectors.toList());
            if (CollUtil.isNotEmpty(list)) {
                BigDecimal targetPv = awardsMap.get(list.get(0).getAwardsValue()).getCommunityCheck();
                memberAwardsUnderVO.setTargetPv(targetPv.multiply(rate).divide(MagicNumberConstants.big10000, 2, BigDecimal.ROUND_DOWN));
            } else {
                BigDecimal targetPv = new BigDecimal("-1");
                memberAwardsUnderVO.setTargetPv(targetPv);
            }
        }
        return memberAwardsUnderVO;
    }

    @Override
    public List<CuMemberMonthAchieveContrastVO> selectNewAddAchieveContrast(Long pkMember, Integer pkCountry, Integer month) {
        List<CuMemberMonthAchieveContrastVO> achieveContrastVOList = new ArrayList<>();
        //当月
        LocalDate localDate = null == month ? LocalDate.now() : LocalDate.of(LocalDate.now().getYear(), month, 1);

        CuMemberMonthAchieveContrastVO localMonthAchieve = getMonthInfo(localDate, pkMember, pkCountry);
        localMonthAchieve.setDate(localDate.format(DateTimeFormatter.ofPattern("yyyy-MM")));

        //上月
        LocalDate lastMonthDate = localDate.minus(1, ChronoUnit.MONTHS);
        CuMemberMonthAchieveContrastVO lastMonthAchieve = getMonthInfo(lastMonthDate, pkMember, pkCountry);
        lastMonthAchieve.setDate(lastMonthDate.format(DateTimeFormatter.ofPattern("yyyy-MM")));

        //中国转汇率
        if (pkCountry.equals(CountryConstants.CHINA_COUNTRY)) {
            //根据国家查汇率
            BigDecimal rate = iCuMemberBaseService.getCurrency(pkCountry).getInExchangeRate();
            getAchieveContrastVOByRate(localMonthAchieve, rate);
            getAchieveContrastVOByRate(lastMonthAchieve, rate);
        }

        achieveContrastVOList.add(lastMonthAchieve);
        achieveContrastVOList.add(localMonthAchieve);
        return achieveContrastVOList;
    }

    /**
     * 转换中国币显示
     *
     * @param achieveContrastVO 月度新增业绩对比VO
     * @param rate              汇率
     * @return CuMemberMonthAchieveContrastVO
     */
    private CuMemberMonthAchieveContrastVO getAchieveContrastVOByRate(CuMemberMonthAchieveContrastVO achieveContrastVO, BigDecimal rate) {
        if (null != achieveContrastVO) {
            achieveContrastVO.setANewPv(achieveContrastVO.getANewPv().multiply(rate));
            achieveContrastVO.setBNewPv(achieveContrastVO.getBNewPv().multiply(rate));
        }
        return achieveContrastVO;

    }

    /**
     * 查询月度新增业绩
     *
     * @param localDate 日期
     * @param pkMember  会员主键
     * @param pkCountry 国家ID
     * @return CuMemberMonthAchieveContrastVO
     */
    private CuMemberMonthAchieveContrastVO getMonthInfo(LocalDate localDate, Long pkMember, Integer pkCountry) {
        CuMemberMonthAchieveContrastVO achieve = null;
        //判断表存不存在
        Integer count = baseMapper.selectExistTable(getAchieveTable(localDate));
        if (count.equals(1)) {
            achieve = getCuMemberMonthAchieve(pkMember, pkCountry, localDate);
        }
        if (count.equals(0) || null == achieve) {
            achieve = CuMemberMonthAchieveContrastVO.builder().aNewPv(BigDecimal.ZERO).bNewPv(BigDecimal.ZERO).build();
        }
        return achieve;

    }

    /**
     * 查询某月新增业绩
     *
     * @param pkMember  会员ID
     * @param pkCountry 国家ID
     * @param localDate 日期
     * @return CuMemberMonthAchieveContrastVO
     */
    private CuMemberMonthAchieveContrastVO getCuMemberMonthAchieve(Long pkMember, Integer pkCountry, LocalDate localDate) {
        CuMemberMonthAchieveContrastVO localAchieveParam = CuMemberMonthAchieveContrastVO.builder().pkMember(pkMember).pkCountry(pkCountry)
                .achieveTable(getAchieveTable(localDate)).build();
        return baseMapper.selectNewAddAchieveContrast(localAchieveParam);
    }

    /**
     * 获取业绩表名
     *
     * @param localDate 日期
     * @return String
     */
    private String getAchieveTable(LocalDate localDate) {
        String date = localDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        return TableNameConstants.CU_MEMBER_ACHIEVE + DateUtils.getMonth(date);
    }

    /**
     * 查询左右区新增业绩
     **/
    private PlaceNewAddAchieveVO selectNewABAchieve(PlaceNewAddAchieveVO pna) {
        return baseMapper.selectNewABAchieve(pna);
    }

    /**
     * 查询左右区血缘业绩
     **/
    private List<PlaceNewAddAchieveVO> selectABDirectAchieve(PlaceNewAddAchieveVO pna) {
        return baseMapper.selectABDirectAchieve(pna);
    }

    /**
     * 查询直推业绩
     **/
    private PlaceNewAddAchieveVO selectParentAchieve(PlaceNewAddAchieveVO pna) {
        return baseMapper.selectParentAchieve(pna);
    }

    /**
     * 查询历史左右区人数
     **/
    private List<PlaceNewAddAchieveVO> selectABCoun(PlaceNewAddAchieveVO pna) {
        return baseMapper.selectABCoun(pna);
    }

    /**
     * 查询最新月份左右区人数
     **/
    private List<PlaceNewAddAchieveVO> selectABNewMonthCoun(PlaceNewAddAchieveVO pna) {
        return baseMapper.selectABNewMonthCoun(pna);
    }

    /**
     * 查询各个等级直推人数和业绩
     **/
    private List<ParentAchieveVO> selectParentCounAchieve(ParentAchieveVO pav) {
        return baseMapper.selectParentCounAchieve(pav);
    }

    /**
     * 查询本人直推业绩
     **/
    List<ParentAchieveVO> selfParentCounAchieve(ParentAchieveVO pav) {
        return baseMapper.selfParentCounAchieve(pav);
    }

    /**
     * 查询前10直推业绩
     **/
    List<ParentAchieveVO> parentCounAchieveTop(ParentAchieveVO pav) {
        return baseMapper.parentCounAchieveTop(pav);
    }

    /**
     * 直推业绩前十人伞下等级业绩
     **/
    List<ParentAchieveVO> umbrellaAchieveTop(ParentAchieveVO pav) {
        return baseMapper.umbrellaAchieveTop(pav);
    }


    /**
     * 业绩分布-新增业绩统计
     **/
    @Override
    public PlaceNewAddAchieveVO placeNewAddAchieveStat(PlaceNewAddAchieveVO pna) {
        PlaceNewAddAchieveVO rtupna = new PlaceNewAddAchieveVO();
        //当前日期
        Date currentDate;
        LocalDate localDate;
        LocalDate startDate;
        if (StringUtils.isNotEmpty(pna.getYear())) {
            currentDate = getDateFromYearAndMonth(pna.getYear(), pna.getMonthType().toString());
            LocalDate today = currentDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
            //当月第一天
            localDate = null == pna.getMonthType() ? LocalDate.now() : LocalDate.of(today.getYear(), pna.getMonthType(), 1);
            startDate = localDate.with(TemporalAdjusters.firstDayOfMonth());
        } else {
            currentDate = DateUtils.parseStringToDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, DateUtils.currentDate()));
            localDate = null == pna.getMonthType() ? LocalDate.now() : LocalDate.of(LocalDate.now().getYear(), pna.getMonthType(), 1);
            startDate = localDate.with(TemporalAdjusters.firstDayOfMonth());
        }

        String dStr = DateUtils.getMonth(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, DateUtils.currentDate()));
        Date systemDate = DateUtils.currentDate();

        // 获取下个月第一天
        LocalDate endDate = localDate.with(TemporalAdjusters.firstDayOfNextMonth());
        Date enddate = DateUtils.toDate(endDate);
        if (DateUtils.compareDateBefore(systemDate, enddate)) {
            endDate = DateUtils.toLocalDate(DateUtils.beforeDate(1, ChronoUnit.DAYS, systemDate));
        } else {
            endDate = DateUtils.toLocalDate(DateUtils.beforeDate(1, ChronoUnit.DAYS, DateUtils.toDate(endDate)));
        }
        String startDateStr = startDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        String endDateStr = endDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));

        Date startDated = DateUtils.parseStringToDate(startDateStr);
        //判断当前月第一天是否大于等于当前时间，直接返回0
        if (DateUtils.compareDateBefore(systemDate, startDated) || DateUtils.compareDateEqual(systemDate, startDated)) {
            rtupna.setLeftAchieve(BigDecimal.ZERO);
            rtupna.setRightAchieve(BigDecimal.ZERO);
            rtupna.setLeftCoun(0);
            rtupna.setRightCount(0);
            rtupna.setDirectAchieve(BigDecimal.ZERO);
            return rtupna;
        }
        R<CurrencyDTO> currency = iCurrencyServiceApi.getCurrency(SecurityUtils.getPkCountry());

        BigDecimal leftAchieve = BigDecimal.ZERO;
        BigDecimal rightAchieve = BigDecimal.ZERO;

        String achieveTableName = TableNameConstants.CU_MEMBER_ACHIEVE + DateUtils.getMonth(startDateStr);
        Integer number = iCuMemberTreeService.queryExistOracleTable(achieveTableName);
        if (null != number && number != 0) {
            // 月度业绩表存在
            pna.setStartDate(startDateStr);
            pna.setEndDate(endDateStr);
            pna.setAchieveTableName(achieveTableName);
            //查询左右区业绩
            PlaceNewAddAchieveVO achieve = selectNewABAchieve(pna);

            if (null != achieve) {
                if (SecurityUtils.getPkCountry().equals(CountryConstants.CHINA_COUNTRY)) {
                    leftAchieve = achieve.getLeftAchieve().multiply(currency.getData().getInExchangeRate());
                    rightAchieve = achieve.getRightAchieve().multiply(currency.getData().getInExchangeRate());
                } else {
                    leftAchieve = achieve.getLeftAchieve();
                    rightAchieve = achieve.getRightAchieve();
                }
            }
        }

        if (leftAchieve.compareTo(BigDecimal.ZERO) > 0) {
            leftAchieve = leftAchieve.divide(MagicNumberConstants.big10000, 4, RoundingMode.DOWN);
        }
        if (rightAchieve.compareTo(BigDecimal.ZERO) > 0) {
            rightAchieve = rightAchieve.divide(MagicNumberConstants.big10000, 4, RoundingMode.DOWN);
        }
        rtupna.setLeftAchieve(leftAchieve);
        rtupna.setRightAchieve(rightAchieve);
        //当前日期
        LocalDate currentDateTime = LocalDate.now();
        if (currentDateTime.isBefore(endDate)) {
            endDateStr = currentDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            pna.setEndDate(endDateStr);
        }
        startDate = DateUtils.toLocalDate(DateUtils.beforeDate(1, ChronoUnit.DAYS, DateUtils.toDate(startDate)));
        startDateStr = startDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        String treeTableNameEnd = TableNameConstants.CU_MEMBER_TREE + DateUtils.getMonth(startDateStr);
        pna.setStartDate(startDateStr);
        pna.setAchieveTableName(treeTableNameEnd);

        int endperiod = 0;
        //查询最新期数
        CuMemberSettlePeriod settlePeriod = iCuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(DateUtils.parseDateToStr(endDateStr));
        if (null != settlePeriod) {
            endperiod = settlePeriod.getPkId();
        }
        //如果是当前月，则查询最新月份数据 查询左右区人数
        String monthStr = DateUtils.getMonth(endDateStr);
        //查询当前月份的左右区人数
        if (monthStr.equals(dStr)) {
            List<PlaceNewAddAchieveVO> monthCount = selectABNewMonthCoun(pna);
            if (CollectionUtil.isNotEmpty(monthCount)) {
                //获取上一个月的最后一天
                String lastMonth = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, DateUtils.beforeMonthLastDate(currentDate));
                int lastendperiod = iCuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(
                        DateUtils.parseDateToStr(lastMonth)).getPkId();
                treeTableNameEnd = TableNameConstants.CU_MEMBER_SETTLE + lastendperiod;
                pna.setAchieveTableName(treeTableNameEnd);
                List<PlaceNewAddAchieveVO> lastMonthCount = selectABCoun(pna);
                int lasLeft = 0;
                int lasRegist = 0;
                for (PlaceNewAddAchieveVO lpl : lastMonthCount) {
                    if (lpl.getPlaceDept() == EPlaceDept.LEFT_DEPT.getValue()) {
                        lasLeft = lpl.getMemberCount();
                    }
                    if (lpl.getPlaceDept() == EPlaceDept.RIGHT_DEPT.getValue()) {
                        lasRegist = lpl.getMemberCount();
                    }
                }
                for (PlaceNewAddAchieveVO pl : monthCount) {
                    if (pl.getPlaceDept() == EPlaceDept.LEFT_DEPT.getValue()) {
                        rtupna.setLeftCoun(pl.getMemberCount() > lasLeft ? pl.getMemberCount() - lasLeft : 0);
                    }
                    if (pl.getPlaceDept() == EPlaceDept.RIGHT_DEPT.getValue()) {
                        rtupna.setRightCount(pl.getMemberCount() > lasRegist ? pl.getMemberCount() - lasRegist : 0);
                    }
                }
            }
        } else {
            //查询历史月份的左右区人数
            if (endperiod > 0) {
                PlaceNewAddAchieveVO frontPna = new PlaceNewAddAchieveVO();
                int frontLiftCount = 0;
                int frontRightCount = 0;
                //获取上上个月的最后一天
                //当前日期
                Date frontDate = DateUtils.parseStringToDate(endDateStr);
                String frontLastMonth = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, DateUtils.beforeMonthLastDate(frontDate));

                CuMemberSettlePeriod tmpSettlePeriod = iCuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(DateUtils.parseDateToStr(frontLastMonth));
                if (null != tmpSettlePeriod) {
                    int frontLastendperiod = tmpSettlePeriod.getPkId();
                    String frontTreeTableNameEnd = TableNameConstants.CU_MEMBER_SETTLE + frontLastendperiod;
                    frontPna.setPkMember(pna.getPkMember());
                    frontPna.setStartDate(frontLastMonth);
                    frontPna.setAchieveTableName(frontTreeTableNameEnd);
                    List<PlaceNewAddAchieveVO> frontMonthCount = selectABCoun(frontPna);
                    if (CollectionUtil.isNotEmpty(frontMonthCount)) {
                        for (PlaceNewAddAchieveVO pl : frontMonthCount) {
                            if (pl.getPlaceDept() == EPlaceDept.LEFT_DEPT.getValue()) {
                                frontLiftCount = pl.getMemberCount();
                            }
                            if (pl.getPlaceDept() == EPlaceDept.RIGHT_DEPT.getValue()) {
                                frontRightCount = pl.getMemberCount();
                            }
                        }
                    }
                }

                //查询左右区人数
                treeTableNameEnd = TableNameConstants.CU_MEMBER_SETTLE + endperiod;
                pna.setAchieveTableName(treeTableNameEnd);
                List<PlaceNewAddAchieveVO> monthCount = selectABCoun(pna);
                if (CollectionUtil.isNotEmpty(monthCount)) {
                    for (PlaceNewAddAchieveVO pl : monthCount) {
                        if (pl.getPlaceDept() == EPlaceDept.LEFT_DEPT.getValue()) {
                            rtupna.setLeftCoun(pl.getMemberCount() > frontLiftCount ? pl.getMemberCount() - frontLiftCount : 0);
                        }
                        if (pl.getPlaceDept() == EPlaceDept.RIGHT_DEPT.getValue()) {
                            rtupna.setRightCount(pl.getMemberCount() > frontRightCount ? pl.getMemberCount() - frontRightCount : 0);
                        }
                    }
                }
            }
        }

        BigDecimal leftDirectAchieve = BigDecimal.ZERO;
        BigDecimal rightDirectAchieve = BigDecimal.ZERO;

        //查询直推业绩（血缘业绩 查询月度表）
        PlaceNewAddAchieveVO pam = new PlaceNewAddAchieveVO();
        //查询结束日期业绩表
        String staTableName = TableNameConstants.CU_MEMBER_MONTH + DateUtils.getMonth(endDateStr);
        pam.setPkMember(pna.getPkMember());
        pam.setPeriod(endperiod);
        pam.setAchieveTableName(staTableName);
        pam.setAchievementType(pna.getAchievementType());
        if (endperiod == 0) {
            rtupna.setDirectAchieve(BigDecimal.ZERO);
        } else {
            //查询结束日期直推业绩
            PlaceNewAddAchieveVO endParentAchieve = selectParentAchieve(pam);
            if (StringUtils.isNotNull(endParentAchieve)) {
                rtupna.setDirectAchieve(endParentAchieve.getDirectAchieve());
                if (SecurityUtils.getPkCountry().equals(CountryConstants.CHINA_COUNTRY)) {
                    rtupna.setDirectAchieve(rtupna.getDirectAchieve().multiply(currency.getData().getInExchangeRate()));
                }
                if (rtupna.getDirectAchieve().compareTo(BigDecimal.ZERO) > 0) {
                    rtupna.setDirectAchieve(rtupna.getDirectAchieve().divide(MagicNumberConstants.big10000, 4, RoundingMode.DOWN));
                } else {
                    rtupna.setDirectAchieve(BigDecimal.ZERO);
                }
            } else {
                rtupna.setDirectAchieve(BigDecimal.ZERO);
            }

            //查询左右区血缘业绩
            List<PlaceNewAddAchieveVO> lrDirectAchieve = selectABDirectAchieve(pam);
            if (CollectionUtil.isNotEmpty(lrDirectAchieve)) {
                for (PlaceNewAddAchieveVO pl : lrDirectAchieve) {
                    if (pl.getDirectAchieve() != null && pl.getPlaceDept() == EPlaceDept.LEFT_DEPT.getValue()) {
                        if (pna.getPkCountry().equals(CountryConstants.CHINA_COUNTRY)) {
                            leftDirectAchieve = pl.getDirectAchieve().multiply(currency.getData().getInExchangeRate());
                        } else {
                            leftDirectAchieve = pl.getDirectAchieve();
                        }
                        leftDirectAchieve = leftDirectAchieve.divide(MagicNumberConstants.big10000, 4, RoundingMode.DOWN);
                    }
                    if (pl.getDirectAchieve() != null && pl.getPlaceDept() == EPlaceDept.RIGHT_DEPT.getValue()) {
                        rightDirectAchieve = pl.getDirectAchieve().multiply(currency.getData().getInExchangeRate());
                        rightDirectAchieve = rightDirectAchieve.divide(MagicNumberConstants.big10000, 4, RoundingMode.DOWN);
                    }
                }
            }
        }
        rtupna.setLeftDirectAchieve(leftDirectAchieve);
        rtupna.setRightDirectAchieve(rightDirectAchieve);
        return rtupna;
    }

    /**
     * 根据年月获取日期
     **/
    @Override
    public Date getDateFromYearAndMonth(String year, String month) {
        Calendar calendar = null;
        try {
            DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
            // 将月份设置为指定年月的第一天
            String dateString = year + "-" + month + "-01";
            Date date = dateFormat.parse(dateString);
            // 获取 Calendar 实例
            calendar = Calendar.getInstance();
            calendar.setTime(date);
            // 获取该月份的最大天数
            int maxDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
            // 将日期设为该月份的第一天
            calendar.set(Calendar.DAY_OF_MONTH, 1);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        // 返回结果
        return calendar.getTime();
    }

    /**
     * 月度业绩-左右区人数详情(最新)
     **/
    @Override
    public List<PlaceNewAddAchieveVO> placeNewAddAchieveDetails(PlaceNewAddAchieveVO pna) {
        return baseMapper.placeNewAddAchieveDetails(pna);
    }

    /**
     * 月度业绩-左右区人数详情(历史)
     **/
    @Override
    public List<PlaceNewAddAchieveVO> placeNewAddAchieveHistoryDetails(PlaceNewAddAchieveVO pna) {
        return baseMapper.placeNewAddAchieveHistoryDetails(pna);
    }

    /**
     * 月度业绩-左右区业绩详情
     **/
    @Override
    public List<PlaceNewAddAchieveVO> leftRightAchieveDetails(PlaceNewAddAchieveVO pna) {
        return baseMapper.leftRightAchieveDetails(pna);
    }

    /**
     * 月度业绩-左右区血缘业绩详情
     **/
    @Override
    public List<PlaceNewAddAchieveVO> leftRightDirectAchieveDetails(PlaceNewAddAchieveVO pna) {
        return baseMapper.leftRightDirectAchieveDetails(pna);
    }

    /**
     * 月度业绩-查询血缘业绩详情
     **/
    @Override
    public List<PlaceNewAddAchieveVO> directAchieveDetails(PlaceNewAddAchieveVO pna) {
        return baseMapper.directAchieveDetails(pna);
    }


    /**
     * 业绩分布-直推业绩（右图）
     **/
    @Override
    public ParentAchieveVO parentAchieveRight(ParentAchieveVO pa) {
        pa = getDateStr(pa);
        R<CurrencyDTO> currency = iCurrencyServiceApi.getCurrency(SecurityUtils.getPkCountry());
        //结束期数
        int endPeriod = iCuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(pa.getEndDate()).getPkId();

        pa.setPeriod(endPeriod);
        //直推等级人数和业绩
        List<ParentAchieveVO> endParentList = selectParentCounAchieve(pa);
        BigDecimal totalachieve = new BigDecimal(0);
        if (SecurityUtils.getPkCountry().equals(CountryConstants.CHINA_COUNTRY)) {
            pa.setTotalachieve(totalachieve.multiply(currency.getData().getInExchangeRate()));
        } else {
            pa.setTotalachieve(totalachieve);
        }
        pa.setList(endParentList);

        return pa;
    }

    /**
     * 判断是否跨月查询并获取表名
     **/
    private ParentAchieveVO getDateStr(ParentAchieveVO pa) {
        String achieveTableName = TableNameConstants.CU_MEMBER_ACHIEVE + DateUtils.getMonth(pa.getEndDate());
        String treeTableNameEnd = TableNameConstants.CU_MEMBER_TREE + DateUtils.getMonth(pa.getEndDate());
        String achieveTableMonth = TableNameConstants.CU_MEMBER_MONTH + DateUtils.getMonth(pa.getEndDate());
        pa.setTreeTableNameEnd(treeTableNameEnd);
        pa.setAchieveTableName(achieveTableName);
        pa.setAchieveTableMonth(achieveTableMonth);
        return pa;
    }

    /**
     * 业绩分布-直推业绩统计（左图）
     **/
    @Override
    public List<ParentAchieveVO> parentAchieveLeft(ParentAchieveVO pa) {
        pa = getDateStr(pa);
        //获取期数
        int endPeriod = iCuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(pa.getEndDate()).getPkId();
        pa.setPeriod(endPeriod);
        CuMember member = iCuMemberService.getMember(pa.getPkMember());
        List<ParentAchieveVO> parentList = new ArrayList<>();
        ParentAchieveVO par = new ParentAchieveVO();
        par.setMemberName(member.getMemberName());
        par.setPkMember(member.getPkId());
        R<CurrencyDTO> currency = iCurrencyServiceApi.getCurrency(pa.getPkCountry());
        //查询本人直推业绩
        List<ParentAchieveVO> endSelfParentList = selfParentCounAchieve(pa);
        par.setUmbrellaList(endSelfParentList);
        pa.setPeriod(endPeriod);
        parentList.add(par);

        //查询登录人伞下前业绩前10的人
        pa.setPeriod(endPeriod);
        List<ParentAchieveVO> endParentList;
        endParentList = parentCounAchieveTop(pa);

        //查询前10人的所有业绩
        List<ParentAchieveVO> endUmbrellaList = umbrellaAchieveTop(getTopMember(pa, endParentList));
        if (CollectionUtil.isNotEmpty(endParentList)) {
            for (ParentAchieveVO end : endParentList) {
                List<ParentAchieveVO> newumbrellaList = new ArrayList<>();
                for (ParentAchieveVO endum : endUmbrellaList) {
                    if (end.getPkMember().intValue() == endum.getPkMember().intValue()) {
                        if (SecurityUtils.getPkCountry().equals(CountryConstants.CHINA_COUNTRY)) {
                            endum.setAchieve(endum.getAchieve().multiply(currency.getData().getInExchangeRate()));
                        }
                        newumbrellaList.add(endum);
                    }
                }
                end.setUmbrellaList(newumbrellaList);
            }
        }
        parentList.addAll(endParentList);
        return parentList;
    }


    /**
     * 获取前十人员
     **/
    private ParentAchieveVO getTopMember(ParentAchieveVO pa, List<ParentAchieveVO> list) {
        if (CollectionUtil.isNotEmpty(list)) {
            for (int i = 0; i < Math.min(list.size(), 10); i++) {
                switch (i) {
                    case 0:
                        pa.setPkMember(list.get(i).getPkMember());
                        break;
                    case 1:
                        pa.setPkMember2(list.get(i).getPkMember());
                        break;
                    case 2:
                        pa.setPkMember3(list.get(i).getPkMember());
                        break;
                    case 3:
                        pa.setPkMember4(list.get(i).getPkMember());
                        break;
                    case 4:
                        pa.setPkMember5(list.get(i).getPkMember());
                        break;
                    case 5:
                        pa.setPkMember6(list.get(i).getPkMember());
                        break;
                    case 6:
                        pa.setPkMember7(list.get(i).getPkMember());
                        break;
                    case 7:
                        pa.setPkMember8(list.get(i).getPkMember());
                        break;
                    case 8:
                        pa.setPkMember9(list.get(i).getPkMember());
                        break;
                    case 9:
                        pa.setPkMember10(list.get(i).getPkMember());
                        break;
                }
            }
        }
        return pa;
    }

    @Override
    public List<PlacementDataVO> selectPlacementDataList(PlacementDataParam param) {
        String startDate = param.getStartDate();
        String endDate = param.getEndDate();
        String localDate = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        //如果结束时间等于当前时间，取前一天的时间
        if (localDate.equals(endDate)) {
            endDate = LocalDate.now().minus(1, ChronoUnit.DAYS).format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        }
        //查询结束时间安置数据
        List<PlacementDataBaseVO> endDataBaseVOList = baseMapper.selectPlacementDataList(getPlacementDataBaseList(param, endDate));
        List<PlacementDataVO> placementDataVOList = new ArrayList<>();
        if (CollUtil.isNotEmpty(endDataBaseVOList)) {
            List<Long> pkMembers = endDataBaseVOList.stream().map(PlacementDataBaseVO::getPkMember).distinct().collect(Collectors.toList());
            param.setPkMembers(pkMembers);
            //查询开始时间的安置数据
            List<PlacementDataBaseVO> startDataBaseVOList = baseMapper.selectAchieveByPkMember(getPlacementDataBaseList(param, startDate));
            Map<Long, PlacementDataBaseVO> map = startDataBaseVOList.stream().collect(Collectors.toMap(PlacementDataBaseVO::getPkMember, o -> o));
            CountryDTO country = iCountryServiceApi.getCountry(param.getPkSettleCountry()).getData();
            //汇率
            CurrencyDTO currency = iCuMemberBaseService.getCurrency(param.getPkSettleCountry());
            for (PlacementDataBaseVO placementDataBaseVO : endDataBaseVOList) {
                PlacementDataVO placementDataVO = inversionPlacementDataVO(placementDataBaseVO, map, param.getDataTypes(), country, currency);
                placementDataVOList.add(placementDataVO);
            }
        }
        return placementDataVOList;
    }

    /**
     * 查询安置数据
     *
     * @param param 入参
     * @param date  查询时间
     * @return List<PlacementDataBaseVO>
     */
    private PlacementDataParam getPlacementDataBaseList(PlacementDataParam param, String date) {
        param.setDate(date);
        String memberTreeTable = TableNameConstants.CU_MEMBER_TREE + DateUtils.getMonth(date);
        String achieveTable = TableNameConstants.CU_MEMBER_ACHIEVE + DateUtils.getMonth(date);
        param.setAchieveTableName(achieveTable);
        param.setMemberTableName(memberTreeTable);
        return param;
    }


    /**
     * 转化VO
     *
     * @return PlacementDataVO
     */
    private PlacementDataVO inversionPlacementDataVO(PlacementDataBaseVO placementDataBaseVO, Map<Long, PlacementDataBaseVO> map,
                                                     List<Integer> dataTypes, CountryDTO country, CurrencyDTO currency) {
        Long pkMember = placementDataBaseVO.getPkMember();
        PlacementDataVO placementDataVO = PlacementDataVO.builder().memberCode(placementDataBaseVO.getMemberCode())
                .memberName(placementDataBaseVO.getMemberName()).pkAwards(placementDataBaseVO.getPkAwards())
                .settleCountry(country.getName()).vertexName(placementDataBaseVO.getVertexName())
                .teamName(placementDataBaseVO.getTeamName()).build();

        List<PalaceAchieveDetailVO> detailVOList = new ArrayList<>();
        if (CollUtil.isNotEmpty(dataTypes)) {
            PlacementDataBaseVO startData = map.get(pkMember);
            for (Integer dateType : dataTypes) {
                //首购
                //新增 结束时间累计减去开始时间的累计
                BigDecimal leftNewAchieve = null == startData ? placementDataBaseVO.getASumPv() : placementDataBaseVO.getASumPv().subtract(startData.getASumPv());
                BigDecimal rightNewAchieve = null == startData ? placementDataBaseVO.getBSumPv() : placementDataBaseVO.getBSumPv().subtract(startData.getBSumPv());
                BigDecimal leftNewAmount = null == startData ? placementDataBaseVO.getASumAmount() : placementDataBaseVO.getASumAmount().subtract(startData.getASumAmount());
                BigDecimal rightNewAmount = null == startData ? placementDataBaseVO.getBSumAmount() : placementDataBaseVO.getBSumAmount().subtract(startData.getBSumAmount());
                BigDecimal leftBalance = placementDataBaseVO.getABalance();
                BigDecimal rightBalance = placementDataBaseVO.getBBalance();
                if (dateType.equals(EDadaType.FIRST_PURCHASE.getValue())) {
                    PalaceAchieveDetailVO palaceAchieveDetailVO = PalaceAchieveDetailVO.builder()
                            .leftNewAchieve(leftNewAchieve).rightNewAchieve(rightNewAchieve)
                            .leftNewAmount(leftNewAmount).rightNewAmount(rightNewAmount)
                            .leftSumAchieve(placementDataBaseVO.getASumPv()).rightSumAchieve(placementDataBaseVO.getBSumPv())
                            .leftBalance(leftBalance).rightBalance(rightBalance).dataType(EDadaType.FIRST_PURCHASE.getValue())
                            //转化汇率值
                            .settleLeftNewAchieve(getSettleValue(currency, leftNewAchieve)).settleRightNewAchieve(getSettleValue(currency, rightNewAchieve))
                            .settleLeftNewAmount(getSettleValue(currency, leftNewAmount)).settleRightNewAmount(getSettleValue(currency, rightNewAmount))
                            .settleLeftSumAchieve(getSettleValue(currency, placementDataBaseVO.getASumPv()))
                            .settleRightSumAchieve(getSettleValue(currency, placementDataBaseVO.getBSumPv()))
                            .settleLeftBalance(getSettleValue(currency, leftBalance)).settleRightBalance(getSettleValue(currency, rightBalance))
                            .build();
                    detailVOList.add(palaceAchieveDetailVO);
                }
                //复购
                BigDecimal repLeftNewAchieve = null == startData ? placementDataBaseVO.getRepASumPv() : placementDataBaseVO.getRepASumPv().subtract(startData.getRepASumPv());
                BigDecimal repRightNewAchieve = null == startData ? placementDataBaseVO.getRepBSumPv() : placementDataBaseVO.getRepBSumPv().subtract(startData.getRepBSumPv());
                BigDecimal repLeftNewAmount = null == startData ? placementDataBaseVO.getRepASumAmount() : placementDataBaseVO.getRepASumAmount().subtract(startData.getRepASumAmount());
                BigDecimal repRightNewAmount = null == startData ? placementDataBaseVO.getRepBSumAmount() : placementDataBaseVO.getRepBSumAmount().subtract(startData.getRepBSumAmount());
                BigDecimal repLeftBalance = placementDataBaseVO.getRepABalance();
                BigDecimal repRightBalance = placementDataBaseVO.getRepBBalance();
                if (dateType.equals(EDadaType.REPURCHASE.getValue())) {
                    PalaceAchieveDetailVO repAchieveDetailVO = PalaceAchieveDetailVO.builder()
                            .leftNewAchieve(repLeftNewAchieve).rightNewAchieve(repRightNewAchieve)
                            .leftNewAmount(repLeftNewAmount).rightNewAmount(repRightNewAmount)
                            .leftSumAchieve(placementDataBaseVO.getRepASumPv()).rightSumAchieve(placementDataBaseVO.getRepBSumPv())
                            .leftBalance(repLeftBalance).rightBalance(repRightBalance).dataType(EDadaType.REPURCHASE.getValue())
                            //转化汇率值
                            .settleLeftNewAchieve(getSettleValue(currency, repLeftNewAchieve)).settleRightNewAchieve(getSettleValue(currency, repRightNewAchieve))
                            .settleLeftNewAmount(getSettleValue(currency, repLeftNewAmount)).settleRightNewAmount(getSettleValue(currency, repRightNewAmount))
                            .settleLeftSumAchieve(getSettleValue(currency, placementDataBaseVO.getRepASumPv()))
                            .settleRightSumAchieve(getSettleValue(currency, placementDataBaseVO.getRepBSumPv()))
                            .settleLeftBalance(getSettleValue(currency, repLeftBalance)).settleRightBalance(getSettleValue(currency, repRightBalance))
                            .build();
                    detailVOList.add(repAchieveDetailVO);
                }
                //真实
                if (dateType.equals(EDadaType.REAL.getValue())) {
                    //真实= 首购+复购
                    BigDecimal realLeftNewAchieve = leftNewAchieve.add(repLeftNewAchieve);
                    BigDecimal realRightNewAchieve = rightNewAchieve.add(repRightNewAchieve);
                    BigDecimal realLeftNewAmount = leftNewAmount.add(repLeftNewAmount);
                    BigDecimal realRightNewAmount = rightNewAmount.add(repRightNewAmount);
                    BigDecimal realLeftBalance = leftBalance.add(repLeftBalance);
                    BigDecimal realRightBalance = rightBalance.add(repLeftBalance);
                    PalaceAchieveDetailVO realAchieveDetailVO = PalaceAchieveDetailVO.builder()
                            .leftNewAchieve(realLeftNewAchieve).rightNewAchieve(realRightNewAchieve)
                            .leftNewAmount(realLeftNewAmount).rightNewAmount(realRightNewAmount)
                            .leftSumAchieve(placementDataBaseVO.getASumRealPv()).rightSumAchieve(placementDataBaseVO.getBSumRealPv())
                            .leftBalance(realLeftBalance).rightBalance(realRightBalance).dataType(EDadaType.REAL.getValue())
                            //转化汇率值
                            .settleLeftNewAchieve(getSettleValue(currency, realLeftNewAchieve)).settleRightNewAchieve(getSettleValue(currency, realRightNewAchieve))
                            .settleLeftNewAmount(getSettleValue(currency, realLeftNewAmount)).settleRightNewAmount(getSettleValue(currency, realRightNewAmount))
                            .settleLeftSumAchieve(getSettleValue(currency, placementDataBaseVO.getASumRealPv()))
                            .settleRightSumAchieve(getSettleValue(currency, placementDataBaseVO.getBSumRealPv()))
                            .settleLeftBalance(getSettleValue(currency, realLeftBalance)).settleRightBalance(getSettleValue(currency, realRightBalance))
                            .build();
                    detailVOList.add(realAchieveDetailVO);
                }
            }
        }
        placementDataVO.setDetailVOList(detailVOList);
        return placementDataVO;

    }

    /**
     * 查询原币的值
     *
     * @param currency 汇率
     * @param value    美元值
     * @return BigDecimal
     */
    private BigDecimal getSettleValue(CurrencyDTO currency, BigDecimal value) {
        BigDecimal exchangeRate = currency.getInExchangeRate();
        return value.multiply(exchangeRate);
    }

    @Override
    public List<PlacementDataVO> selectRecommendDataList(PlacementDataParam param) {
        String startDate = param.getStartDate();
        String endDate = param.getEndDate();
        //查询结束时间数据
        List<RecommendDataBaseVO> endDataBaseVOList = baseMapper.selectRecommendDataList(getPlacementDataBaseList(param, getEndDate(endDate)));
        if (CollUtil.isNotEmpty(endDataBaseVOList)) {
            List<Long> pkMembers = endDataBaseVOList.stream().map(RecommendDataBaseVO::getPkMember).distinct().collect(Collectors.toList());
            param.setPkMembers(pkMembers);
            //查询开始时间的数据
            List<RecommendDataBaseVO> startDataBaseVOList = baseMapper.selectRecommendDataListByPkMember(getPlacementDataBaseList(param, startDate));
            Map<Long, RecommendDataBaseVO> recommendMap = startDataBaseVOList.stream().collect(Collectors.toMap(RecommendDataBaseVO::getPkMember, o -> o));
            //个人推荐数据
            personalRecommendData(endDataBaseVOList, recommendMap);
            //伞下团队推荐数据
            return convertPlacementDataVO(endDataBaseVOList, param);
        }
        return new ArrayList<>();
    }

    /**
     * 查询会员真实业绩
     */
    @Override
    public RealPerformanceVo queryRealPerformance(Long pkMember, Integer pkCountry, Integer month) {
        R<CurrencyDTO> currencyDto = iCurrencyServiceApi.getCurrency(pkCountry);
        CurrencyDTO currency = currencyDto.getData();
        //当月
        RealPerformanceVo realPerformanceVo = null;
        LocalDate localDate = null == month ? LocalDate.now() : LocalDate.of(LocalDate.now().getYear(), month, 1);

        String date = localDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        String achieveTable = TableNameConstants.CU_MEMBER_ACHIEVE + DateUtils.getMonth(date);
        Integer count = baseMapper.selectExistTable(achieveTable);
        if (count == 1) {

            realPerformanceVo = iCuMemberMonthAchieveService.queryCuMemberMonthAchieveInfo(pkMember, achieveTable);
            if (realPerformanceVo != null) {
                realPerformanceVo.setFirstLeftPurchaseTotal(realPerformanceVo.getFirstLeftPurchaseTotal().multiply(currency.getInExchangeRate()).divide(MagicNumberConstants.big10000));
                realPerformanceVo.setFirstRightPurchaseTotal(realPerformanceVo.getFirstRightPurchaseTotal().multiply(currency.getInExchangeRate()).divide(MagicNumberConstants.big10000));
                realPerformanceVo.setFirstLeftRepurchaseTotal(realPerformanceVo.getFirstLeftRepurchaseTotal().multiply(currency.getInExchangeRate()).divide(MagicNumberConstants.big10000));
                realPerformanceVo.setFirstRightRepurchaseTotal(realPerformanceVo.getFirstRightRepurchaseTotal().multiply(currency.getInExchangeRate()).divide(MagicNumberConstants.big10000));
                realPerformanceVo.setLeftGrandTotal(realPerformanceVo.getFirstLeftPurchaseTotal().add(realPerformanceVo.getFirstLeftRepurchaseTotal()));
                realPerformanceVo.setRightGrandTotal(realPerformanceVo.getFirstRightPurchaseTotal().add(realPerformanceVo.getFirstRightRepurchaseTotal()));
            } else {
                realPerformanceVo = new RealPerformanceVo();
                realPerformanceVo.setRightGrandTotal(BigDecimal.ZERO);
                realPerformanceVo.setLeftGrandTotal(BigDecimal.ZERO);
                realPerformanceVo.setFirstLeftPurchaseTotal(BigDecimal.ZERO);
                realPerformanceVo.setFirstRightPurchaseTotal(BigDecimal.ZERO);
                realPerformanceVo.setFirstLeftRepurchaseTotal(BigDecimal.ZERO);
                realPerformanceVo.setFirstRightRepurchaseTotal(BigDecimal.ZERO);
            }

        }
        return realPerformanceVo;
    }

    /**
     * 会员真实业绩饼状图
     *
     * @param pkMember
     * @param pkCountry
     * @param month
     * @return
     */
    @Override
    public AzAchievementPie queryRealPerformancePic(Long pkMember, Integer pkCountry, Integer month) {
        R<CurrencyDTO> currencyDto = iCurrencyServiceApi.getCurrency(pkCountry);
        CurrencyDTO currency = currencyDto.getData();
        //当月
        AzAchievementPie achievementPie;
        //左区人数
        Long leftCount = iCuMemberService.selectByDeptNumberCount(pkMember, EPlaceDept.LEFT_DEPT.getValue());
        // 右区人数
        Long rightCount = iCuMemberService.selectByDeptNumberCount(pkMember, EPlaceDept.RIGHT_DEPT.getValue());
        DateTime dateTime = DateUtil.offsetDay(DateUtils.currentDate(), -1);
        String time = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, dateTime);
        CuMemberSettlePeriod csPeriod = iCuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(time);
        String settleTableName = TableNameConstants.CU_MEMBER_SETTLE + csPeriod.getPkId();
        CuMemberSettleExt memberSettleExt = iCuMemberTreeService.queryCuMemberTreeByPkMemberTable(settleTableName, pkMember);
        BigDecimal aSumRealPv = BigDecimal.ZERO;
        BigDecimal bSumRealPv = BigDecimal.ZERO;
        if (memberSettleExt.getASumRealPv() != null) {
            aSumRealPv = memberSettleExt.getASumRealPv();
        }
        if (memberSettleExt.getBSumRealPv() != null) {
            bSumRealPv = memberSettleExt.getBSumRealPv();
        }

        achievementPie = new AzAchievementPie();
        achievementPie.setLeftAchievement(aSumRealPv.divide(MagicNumberConstants.big10000).multiply(currency.getInExchangeRate()));
        achievementPie.setRightAchievement(bSumRealPv.divide(MagicNumberConstants.big10000).multiply(currency.getInExchangeRate()));
        achievementPie.setLeftNumber(leftCount);
        achievementPie.setRightNumber(rightCount);
        return achievementPie;
    }

    /**
     * 个人推荐数据
     *
     * @param endDataBaseVOList 结束时间数据
     * @param recommendMap      开始时间数据
     */
    private void personalRecommendData(List<RecommendDataBaseVO> endDataBaseVOList, Map<Long, RecommendDataBaseVO> recommendMap) {
        for (RecommendDataBaseVO recommendDataBaseVO : endDataBaseVOList) {
            Long pkMember = recommendDataBaseVO.getPkMember();
            RecommendDataBaseVO startRe = recommendMap.get(pkMember);
            if (null != startRe) {
                //个人推荐数据 = 结束时间推荐数据 减去 开始时间的推荐数据
                recommendDataBaseVO.setRealAmount(recommendDataBaseVO.getRealAmount().subtract(getBigDecimal(startRe.getRealAmount())));
                recommendDataBaseVO.setRealAchieve(recommendDataBaseVO.getRealAchieve().subtract(getBigDecimal(startRe.getRealAchieve())));
                recommendDataBaseVO.setFirstAmount(recommendDataBaseVO.getFirstAmount().subtract(getBigDecimal(startRe.getFirstAmount())));
                recommendDataBaseVO.setFirstAchieve(recommendDataBaseVO.getFirstAchieve().subtract(getBigDecimal(startRe.getFirstAchieve())));
                recommendDataBaseVO.setRepeatAmount(recommendDataBaseVO.getRepeatAmount().subtract(getBigDecimal(startRe.getRepeatAmount())));
                recommendDataBaseVO.setRepeatAchieve(recommendDataBaseVO.getRepeatAchieve().subtract(getBigDecimal(startRe.getRepeatAchieve())));
            }
        }
    }

    /**
     * 转化页面显示VO
     *
     * @param endDataBaseVOList 查询数据
     * @param param             入参
     * @return List<PlacementDataVO>
     */
    private List<PlacementDataVO> convertPlacementDataVO(List<RecommendDataBaseVO> endDataBaseVOList, PlacementDataParam param) {
        PlacementDataVO dataBaseVO;
        List<PlacementDataVO> placementDataVOList = new ArrayList<>();
        //体系总和
        Map<Long, RecommendDataDetailVO> vertexMap = computeVertex(param);
        //全网总和
        RecommendDataDetailVO marketVO = computeMarket(param);
        for (RecommendDataBaseVO recommendDataBaseVO : endDataBaseVOList) {
            CountryDTO country = iCountryServiceApi.getCountry(recommendDataBaseVO.getSettleCountry()).getData();

            Long pkMember = recommendDataBaseVO.getPkMember();
            //当前推荐人伞下用户
            List<RecommendDataBaseVO> reList = endDataBaseVOList.stream().filter(data -> pkMember.equals(data.getPkParent())).collect(Collectors.toList());
            dataBaseVO = BeanUtil.copyProperties(recommendDataBaseVO, PlacementDataVO.class);
            //时间赋值
            dataBaseVO.setSettleStartDate(DateUtils.parseStringToDate(param.getStartDate()));
            dataBaseVO.setSettleEndDate(DateUtils.parseStringToDate(getEndDate(param.getEndDate())));
            //国家
            dataBaseVO.setSettleCountry(country.getName());
            dataBaseVO.setRecommendDetailList(teamRecommendData(recommendDataBaseVO, reList, param, vertexMap, marketVO));
            placementDataVOList.add(dataBaseVO);
        }
        return placementDataVOList;
    }

    /**
     * 获取推荐伞下数据之和
     *
     * @param recommendDataBaseVO 个人推荐数据
     * @param reList              伞下推荐数据
     * @param param               入参
     * @return List<RecommendDataDetailVO>
     */
    private List<RecommendDataDetailVO> teamRecommendData(RecommendDataBaseVO recommendDataBaseVO, List<RecommendDataBaseVO> reList,
                                                          PlacementDataParam param, Map<Long, RecommendDataDetailVO> vertexMap,
                                                          RecommendDataDetailVO marketVO) {
        RecommendDataDetailVO detailVO;
        Integer awardsValue = null;
        List<RecommendDataDetailVO> dataDetailVOList = new ArrayList<>();
        if (CollUtil.isNotEmpty(reList)) {
            Integer pkAwards = param.getPkAwards();
            if (null != pkAwards) {
                BdAwards bdAwards = iAwardsServiceApi.getAwardsOne(pkAwards).getData();
                //真实奖衔值
                awardsValue = bdAwards.getAwardsValue();
            }
            //数据类型
            List<Integer> dataTypes = param.getDataTypes();
            if (CollUtil.isNotEmpty(dataTypes) && null != awardsValue) {
                for (Integer dataType : dataTypes) {
                    detailVO = getRecommendDataDetailVO(recommendDataBaseVO, reList, dataType, awardsValue, param, vertexMap, marketVO);
                    dataDetailVOList.add(detailVO);
                }
            } else {
                //默认团队
                detailVO = getRecommendDataDetailVO(recommendDataBaseVO, reList, ERecommendDadaType.TEAM.getValue(), awardsValue, param, vertexMap, marketVO);
                dataDetailVOList.add(detailVO);
            }
        } else {
            //伞下没有数据时，取个人数据
            detailVO = getRecommendDataDetailVO(recommendDataBaseVO, reList, ERecommendDadaType.TEAM.getValue(), null, param, vertexMap, marketVO);
            dataDetailVOList.add(detailVO);
        }
        return dataDetailVOList;
    }

    /**
     * 获取伞下推荐数据和
     *
     * @param recommendDataBaseVO 个人推荐数据
     * @param reList              伞下推荐数据
     * @param dataType            数据类型
     * @param awardsValueParam    奖衔参数
     * @return RecommendDataDetailVO
     */
    private RecommendDataDetailVO getRecommendDataDetailVO(RecommendDataBaseVO recommendDataBaseVO, List<RecommendDataBaseVO> reList,
                                                           Integer dataType, Integer awardsValueParam, PlacementDataParam param,
                                                           Map<Long, RecommendDataDetailVO> vertexMap, RecommendDataDetailVO marketVO) {
        int i = 0;
        //个人数据
        BigDecimal realAmount = recommendDataBaseVO.getRealAmount();
        BigDecimal realAchieve = recommendDataBaseVO.getRealAchieve();
        BigDecimal firstAmount = recommendDataBaseVO.getFirstAmount();
        BigDecimal firstAchieve = recommendDataBaseVO.getFirstAchieve();
        BigDecimal repeatAmount = recommendDataBaseVO.getRepeatAmount();
        BigDecimal repeatAchieve = recommendDataBaseVO.getRepeatAchieve();
        Long pkVertex = recommendDataBaseVO.getPkVertex();

        //汇率
        Integer pkRate = recommendDataBaseVO.getPkRate();
        CurrencyDTO currency = iCuMemberBaseService.getCurrencyById(pkRate);
        //伞下数据之和
        if (CollUtil.isNotEmpty(reList)) {
            for (RecommendDataBaseVO dataVO : reList) {
                Integer awardsValue = dataVO.getAwardsValue();
                //去重   就是排除 伞下第一个大于等于所传奖衔参数 的数据
                if (dataType.equals(ERecommendDadaType.DEDUPLICATION.getValue()) && awardsValue >= awardsValueParam && i == 0) {
                    i++;
                    continue;
                }
                realAmount = realAmount.add(dataVO.getRealAmount());
                realAchieve = realAchieve.add(dataVO.getRealAchieve());
                firstAmount = firstAmount.add(dataVO.getFirstAmount());
                firstAchieve = firstAchieve.add(dataVO.getFirstAchieve());
                repeatAmount = repeatAmount.add(dataVO.getRepeatAmount());
                repeatAchieve = repeatAchieve.add(dataVO.getRepeatAchieve());
            }
        }
        return RecommendDataDetailVO.builder()
                .realAmount(realAmount).realAchieve(realAchieve)
                .firstAmount(firstAmount).firstAchieve(firstAchieve)
                .repeatAmount(repeatAmount).repeatAchieve(repeatAchieve)
                .systemRatio(getSystemRatio(param, realAchieve, pkVertex, vertexMap))
                .marketRatio(getMarketRatio(param, realAchieve, marketVO))
                .dataType(dataType)
                //本币
                .settleRealAmount(getSettleValue(currency, realAmount))
                .settleRealAchieve(getSettleValue(currency, realAchieve))
                .settleFirstAmount(getSettleValue(currency, firstAmount))
                .settleFirstAchieve(getSettleValue(currency, firstAchieve))
                .settleRepeatAmount(getSettleValue(currency, repeatAmount))
                .settleRepeatAchieve(getSettleValue(currency, repeatAchieve))
                .settleSystemRatio(getSystemRatio(param, getSettleValue(currency, realAchieve), pkVertex, vertexMap))
                .settleMarketRatio(getMarketRatio(param, getSettleValue(currency, realAchieve), marketVO))
                .build();
    }

    /**
     * 获取体系占比
     *
     * @param param       入参
     * @param realAchieve 会员业绩
     * @param pkVertex    体系ID
     * @return BigDecimal
     */
    private BigDecimal getSystemRatio(PlacementDataParam param, BigDecimal realAchieve, Long pkVertex, Map<Long, RecommendDataDetailVO> vertexMap) {
        if (null != vertexMap) {
            //体系业绩
            BigDecimal vertexAchieve = vertexMap.get(pkVertex).getRealAchieve();
            return vertexAchieve.compareTo(BigDecimal.ZERO) == 0 ? BigDecimal.ZERO : realAchieve.divide(vertexAchieve, 2, RoundingMode.HALF_UP);
        } else {
            return BigDecimal.ZERO;
        }
    }


    /**
     * 获取体系占比
     *
     * @param param       入参
     * @param realAchieve 会员业绩
     * @return BigDecimal
     */
    private BigDecimal getMarketRatio(PlacementDataParam param, BigDecimal realAchieve, RecommendDataDetailVO marketVO) {
        if (null != marketVO) {
            //大盘业绩
            BigDecimal vertexAchieve = marketVO.getRealAchieve();
            return vertexAchieve.compareTo(BigDecimal.ZERO) == 0 ? BigDecimal.ZERO : realAchieve.divide(vertexAchieve, 2, RoundingMode.HALF_UP);
        } else {
            return BigDecimal.ZERO;
        }
    }

    /**
     * 计算体系总业绩
     *
     * @return
     */
    private Map<Long, RecommendDataDetailVO> computeVertex(PlacementDataParam param) {
        String startDate = param.getStartDate();
        String endDate = param.getEndDate();
        //查询结束时间数据
        List<RecommendDataDetailVO> endDataBaseVOList = baseMapper.selectRecommendVertexValue(getPlacementDataBaseList(param, getEndDate(endDate)));
        //查询开始时间的数据
        List<RecommendDataDetailVO> startDataBaseVOList = baseMapper.selectRecommendVertexValue(getPlacementDataBaseList(param, startDate));
        Map<Long, RecommendDataDetailVO> recommendMap = startDataBaseVOList.stream().collect(Collectors.toMap(RecommendDataDetailVO::getPkVertex, o -> o));
        if (CollUtil.isNotEmpty(endDataBaseVOList)) {
            getVertexData(endDataBaseVOList, recommendMap);
            return endDataBaseVOList.stream().collect(Collectors.toMap(RecommendDataDetailVO::getPkVertex, o -> o));
        }
        return null;
    }

    /**
     * 获取每个体系的数据
     *
     * @param endDataBaseVOList 结束时间数据
     * @param recommendMap      开始时间数据
     */
    private void getVertexData(List<RecommendDataDetailVO> endDataBaseVOList, Map<Long, RecommendDataDetailVO> recommendMap) {
        for (RecommendDataDetailVO recommendDataDetailVO : endDataBaseVOList) {
            Long pkVertex = recommendDataDetailVO.getPkVertex();
            RecommendDataDetailVO startRe = recommendMap.get(pkVertex);
            if (null != startRe) {
                //个人推荐数据 = 结束时间推荐数据 减去 开始时间的推荐数据
                recommendDataDetailVO.setRealAchieve(recommendDataDetailVO.getRealAchieve().subtract(getBigDecimal(startRe.getRealAchieve())));
            } else {
                recommendDataDetailVO.setRealAchieve(recommendDataDetailVO.getRealAchieve());
            }
        }
    }


    /**
     * 计算大盘的总业绩
     *
     * @return
     */
    private RecommendDataDetailVO computeMarket(PlacementDataParam param) {
        String startDate = param.getStartDate();
        String endDate = param.getEndDate();
        //查询结束时间数据
        RecommendDataDetailVO endDataBaseVO = baseMapper.selectRecommendMarketValue(getPlacementDataBaseList(param, getEndDate(endDate)));
        //查询开始时间的数据
        RecommendDataDetailVO startDataBaseVO = baseMapper.selectRecommendMarketValue(getPlacementDataBaseList(param, startDate));
        if (null != endDataBaseVO && null != startDataBaseVO) {
            //个人推荐数据 = 结束时间推荐数据 减去 开始时间的推荐数据
            endDataBaseVO.setRealAchieve(endDataBaseVO.getRealAchieve().subtract(getBigDecimal(startDataBaseVO.getRealAchieve())));
        } else if (null != endDataBaseVO) {
            endDataBaseVO.setRealAchieve(endDataBaseVO.getRealAchieve());
        }
        return endDataBaseVO;
    }


    /**
     * 获取结束时间
     *
     * @param date 时间
     * @return String
     */
    private String getEndDate(String date) {
        String localDate = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        //如果结束时间等于当前时间，取前一天的时间
        if (localDate.equals(date)) {
            return LocalDate.now().minus(1, ChronoUnit.DAYS).format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        }
        return date;
    }

    /**
     * 获取 BigDecimal 值
     *
     * @param value 值
     * @return BigDecimal
     */
    private BigDecimal getBigDecimal(BigDecimal value) {
        return null != value ? value : BigDecimal.ZERO;
    }

    @Override
    public PlacementImageDataVO selectPlaceImage(PlacementDataParam param) {
        String memberCode = param.getMemberCode();
        String startDate = param.getStartDate();
        String endDate = param.getEndDate();
        if (StringUtils.isNotEmpty(memberCode) && StringUtils.isNotEmpty(startDate) && StringUtils.isNotEmpty(endDate)) {
            CuMemberExt cuMember = iCuMemberService.getMemberByCode(memberCode);
            if (null == cuMember) {
                return new PlacementImageDataVO();
            }
            param.setPkMember(cuMember.getPkId());
            String localDate = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            //如果结束时间等于当前时间，取前一天的时间
            if (localDate.equals(endDate)) {
                endDate = LocalDate.now().minus(1, ChronoUnit.DAYS).format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            }

            final String endDateParam = endDate;
            //查询结束时间安置数据
            Future<PlacementImageDataVO> endImageDataFuture = ThreadUtils.threadPoolExecutor.submit(() -> baseMapper.selectPlaceImage(getPlacementDataBaseList(param, endDateParam)));
            //查询开始时间的安置数据
            Future<PlacementImageDataVO> startImageDataFuture = ThreadUtils.threadPoolExecutor.submit(() -> baseMapper.selectPlaceImage(getPlacementDataBaseList(param, startDate)));
            PlacementImageDataVO endImageData = null;
            PlacementImageDataVO startImageData = null;
            try {
                endImageData = endImageDataFuture.get();
                startImageData = startImageDataFuture.get();
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
            }
            BigDecimal leftSumAchieve = endImageData.getLeftSumAchieve().subtract(startImageData.getLeftSumAchieve());
            BigDecimal rightSumAchieve = endImageData.getRightSumAchieve().subtract(startImageData.getRightSumAchieve());
            BigDecimal leftRegSumAchieve = endImageData.getLeftRegSumAchieve().subtract(startImageData.getLeftRegSumAchieve());
            BigDecimal rightRegSumAchieve = endImageData.getRightRegSumAchieve().subtract(startImageData.getRightRegSumAchieve());
            BigDecimal leftRealSumAchieve = endImageData.getLeftRealSumAchieve().subtract(startImageData.getLeftRealSumAchieve());
            BigDecimal rightRealSumAchieve = endImageData.getRightRealSumAchieve().subtract(startImageData.getRightRealSumAchieve());
            PlacementImageDataVO imageDataVO = PlacementImageDataVO.builder()
                    .leftSumAchieve(leftSumAchieve)
                    .rightSumAchieve(rightSumAchieve)
                    .leftRegSumAchieve(leftRegSumAchieve)
                    .rightRegSumAchieve(rightRegSumAchieve)
                    .leftRealSumAchieve(leftRealSumAchieve)
                    .rightRealSumAchieve(rightRealSumAchieve)
                    .build();
            //结余
            if (leftSumAchieve.compareTo(rightSumAchieve) > 0) {
                imageDataVO.setLeftBalance(leftSumAchieve.subtract(rightSumAchieve));
            } else {
                imageDataVO.setRightBalance(rightSumAchieve.subtract(leftSumAchieve));
            }
            //复购结余
            if (leftRegSumAchieve.compareTo(rightRegSumAchieve) > 0) {
                imageDataVO.setLeftRegBalance(leftRegSumAchieve.subtract(rightRegSumAchieve));
            } else {
                imageDataVO.setRightRegBalance(rightRegSumAchieve.subtract(leftRegSumAchieve));
            }
            //真实结余
            if (leftRealSumAchieve.compareTo(rightRealSumAchieve) > 0) {
                imageDataVO.setLeftRealBalance(leftRealSumAchieve.subtract(rightRealSumAchieve));
            } else {
                imageDataVO.setRightRealBalance(rightRealSumAchieve.subtract(leftRealSumAchieve));
            }
            return imageDataVO;
        }
        return new PlacementImageDataVO();
    }


    @Override
    public List<RecommendImageDataVO> selectRecommendVertexImage(PlacementDataParam param) {
        List<RecommendImageDataVO> imageDataVOList = new ArrayList<>();
        RecommendImageDataVO recommendImageDataVO;
        List<Long> pkVertexList = param.getPkVertexList();
        if (CollUtil.isEmpty(pkVertexList)) {
            return imageDataVOList;
        }
        Object[] objects = getPeriodAndVertex(param);
        //期数
        Integer period = (Integer) objects[0];
        //体系
        Map<Long, VertexDTO> map = (Map<Long, VertexDTO>) objects[1];
        String localDate = (String) objects[2];
        Map<Long, Future<RecommendImageDataVO>> futureMap = new HashMap<>();
        //多线程查询数据
        for (Long pkVertex : pkVertexList) {
            Long pkMember = map.get(pkVertex).getPkMember();
            //线程共享数据不可见（参数重新赋值）
            PlacementDataParam dataParam = new PlacementDataParam();
            dataParam.setPeriod(period);
            dataParam.setPkMember(pkMember);
            dataParam.setPkSettleCountry(param.getPkSettleCountry());
            //查询体系
            Future<RecommendImageDataVO> future = ThreadUtils.threadPoolExecutor.submit(() -> baseMapper.selectRecommendVertexImage(getPlacementDataBaseList(dataParam, localDate)));
            futureMap.put(pkVertex, future);
        }
        //返回结果组装
        if (MapUtil.isNotEmpty(futureMap)) {
            for (Map.Entry<Long, Future<RecommendImageDataVO>> entry : futureMap.entrySet()) {
                Future<RecommendImageDataVO> value = entry.getValue();
                if (null != value) {
                    try {
                        recommendImageDataVO = value.get();
                        VertexDTO vertex = map.get(entry.getKey());
                        recommendImageDataVO.setPkVertex(vertex.getPkId());
                        recommendImageDataVO.setVertexName(vertex.getVertexName());
                        imageDataVOList.add(recommendImageDataVO);
                    } catch (InterruptedException | ExecutionException e) {
                        e.printStackTrace();
                    }
                }

            }
        }
        return imageDataVOList;
    }

    /**
     * 获取体系与期数
     *
     * @param param 入参
     * @return Object[]
     */
    private Object[] getPeriodAndVertex(PlacementDataParam param) {
        //获取期数
        String localDate = LocalDate.now().minus(1, ChronoUnit.DAYS).format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        int period = iCuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(localDate).getPkId();
        param.setPeriod(period);
        //获取体系
        List<VertexDTO> vertexDTOList = iVertexServiceApi.findAllByPkCountry(param.getPkSettleCountry()).getData();
        Map<Long, VertexDTO> map = vertexDTOList.stream().collect(Collectors.toMap(VertexDTO::getPkId, o -> o));
        return new Object[]{period, map, localDate};
    }

    @Override
    public List<RecommendTeamImagVO> selectRecommendTeamImage(PlacementDataParam param) {
        List<RecommendTeamImagVO> teamImagVOList = new ArrayList<>();
        RecommendTeamImagVO teamImagVO;
        List<Long> pkVertexList = param.getPkVertexList();
        if (CollUtil.isEmpty(pkVertexList)) {
            return teamImagVOList;
        }
        Object[] objects = getPeriodAndVertex(param);
        //期数
        Integer period = (Integer) objects[0];
        //体系
        Map<Long, VertexDTO> map = (Map<Long, VertexDTO>) objects[1];
        String localDate = (String) objects[2];
        Map<Long, Future<List<RecommendImageDataVO>>> futureMap = new HashMap<>();
        //多线程查询数据
        for (Long pkVertex : pkVertexList) {
            Long pkMember = map.get(pkVertex).getPkMember();
            //线程共享数据不可见（参数重新赋值）
            PlacementDataParam dataParam = new PlacementDataParam();
            dataParam.setPeriod(period);
            dataParam.setPkMember(pkMember);
            dataParam.setPkSettleCountry(param.getPkSettleCountry());
            //查询体系
            Future<List<RecommendImageDataVO>> future = ThreadUtils.threadPoolExecutor.submit(() -> baseMapper.selectRecommendTeamImage(getPlacementDataBaseList(dataParam, localDate)));
            futureMap.put(pkVertex, future);
        }

        //返回结果组装
        if (MapUtil.isNotEmpty(futureMap)) {
            //查询团队
            List<CuMemberTeamExt> teamList = iMemberTeamServiceApi.queryCuMemberTeam(param.getPkSettleCountry()).getData();
            Map<Long, CuMemberTeamExt> teamMap = teamList.stream().collect(Collectors.toMap(CuMemberTeamExt::getPkId, o -> o));

            for (Map.Entry<Long, Future<List<RecommendImageDataVO>>> entry : futureMap.entrySet()) {
                Future<List<RecommendImageDataVO>> value = entry.getValue();
                if (null != value) {
                    try {
                        List<RecommendImageDataVO> imageDataVOList = value.get();
                        VertexDTO vertex = map.get(entry.getKey());
                        teamImagVO = new RecommendTeamImagVO();
                        teamImagVO.setPkVertex(vertex.getPkId());
                        teamImagVO.setVertexName(vertex.getVertexName());
                        teamImagVO.setImageDataVOList(getTeamName(imageDataVOList, teamMap));
                        teamImagVOList.add(teamImagVO);
                    } catch (InterruptedException | ExecutionException e) {
                        e.printStackTrace();
                    }
                }

            }
        }
        return teamImagVOList;
    }

    @Override
    public List<CuMemberAchieveExt> queryMemberMonthAchieve(Long pkMember, String month) {
        List<String> monthList = new ArrayList<>();
        if (StringUtils.isEmpty(month)) {
            Date settleDate = DateUtils.beforeDate(1, ChronoUnit.DAYS);
            int year = DateUtils.currentYear(settleDate);
            while (true) {
                monthList.add(DateUtils.getMonth(DateUtils.currentMonthLastDateStr(settleDate)));
                settleDate = DateUtils.beforeMonthLastDate(settleDate);
                int newYear = DateUtils.currentYear(settleDate);
                if (year != newYear) {
                    break;
                }
            }
        } else {
            monthList.add(month.replace("-", ""));
        }
        return baseMapper.queryMemberMonthAchieve(pkMember, monthList);
    }

    @Override
    public List<CuMemberAchieveExt> queryPlaceParentMemberMonthAchieve(MonthAchieveParam monthAchieveParam) {
        return baseMapper.queryPlaceParentMemberMonthAchieve(monthAchieveParam);
    }

    @Override
    public List<CuMemberAchieveExt> queryParentMemberMonthAchieve(MonthAchieveParam monthAchieveParam) {
        return baseMapper.queryParentMemberMonthAchieve(monthAchieveParam);
    }

    /**
     * @param imageDataVOList 团队图表
     * @param teamMap         团队信息
     * @return List<RecommendImageDataVO>
     */
    private List<RecommendImageDataVO> getTeamName(List<RecommendImageDataVO> imageDataVOList, Map<Long, CuMemberTeamExt> teamMap) {
        if (CollUtil.isNotEmpty(imageDataVOList)) {
            for (RecommendImageDataVO dataVO : imageDataVOList) {
                Long pkTeam = dataVO.getPkTeam();
                if (null != pkTeam) {
                    CuMemberTeamExt cuMemberTeamExt = teamMap.get(pkTeam);
                    dataVO.setTeamName(cuMemberTeamExt.getTeamName());
                }
            }
        }
        return imageDataVOList;
    }

}
