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.ComputeUtil;
import com.hzs.common.core.utils.DateUtils;
import com.hzs.common.core.utils.StringUtils;
import com.hzs.common.core.utils.ThreadUtils;
import com.hzs.common.domain.member.account.CuMemberRecharge;
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.sale.order.SaOrder;
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.MemberAchieveParam;

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.time.LocalDate;
import java.time.Period;
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;

/**
 * <p>
 * 会员业绩记录 服务实现类
 * </p>
 *
 * @author hzs
 * @since 2022-10-26
 */
@Slf4j
@Service
public class CuMemberAchieveServiceImpl extends ServiceImpl<CuMemberAchieveMapper, CuMemberAchieve> implements ICuMemberAchieveService {

    private ICuMemberTreeService cuMemberTreeService;

    private CuMemberBonusSettle cuMemberBonusSettle;

    private ICuMemberSettlePeriodService cuMemberSettlePeriodService;

    private ICuMemberService cuMemberService;
    @DubboReference
    private ICurrencyServiceApi currencyServiceApi;

    @Autowired
    private ICuMemberBaseService iCuMemberBaseService;

    @Autowired
    private ICuMemberMonthAchieveService memberMonthAchieveService;

    @Autowired
    private ICuMemberBaseService cuMemberBaseService;

    @Autowired
    private ICuMemberTreeService memberTreeService;

    @DubboReference
    private IAwardsServiceApi awardsServiceApi;
    @Autowired
    private ICuMemberSettlePeriodService memberSettlePeriodService;

    @DubboReference
    private ICountryServiceApi iCountryServiceApi;

    @DubboReference
    IVertexServiceApi iVertexServiceApi;

    @DubboReference
    IMemberTeamServiceApi teamServiceApi;

    @Autowired
    public void setCuMemberService(ICuMemberService cuMemberService) {
        this.cuMemberService = cuMemberService;
    }

    @Autowired
    public void setCuMemberSettlePeriodService(ICuMemberSettlePeriodService cuMemberSettlePeriodService) {
        this.cuMemberSettlePeriodService = cuMemberSettlePeriodService;
    }

    @Autowired
    public void setCuMemberBonusSettle(CuMemberBonusSettle cuMemberBonusSettle) {
        this.cuMemberBonusSettle = cuMemberBonusSettle;
    }

    @Autowired
    public void setCuMemberTreeService(ICuMemberTreeService cuMemberTreeService) {
        this.cuMemberTreeService = cuMemberTreeService;
    }

    @Autowired
    ITransactionCommonService iTransactionCommonService;

    @Override
    public CuMemberAchieve queryCuMemberAchieveByPkMember(Long pkMember, Integer pkCountry) {
        Date currentDate = DateUtils.currentDate();
        // 创建日表记录表
        int period = cuMemberSettlePeriodService.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
        List<CuMemberExt> cuMemberExtList = cuMemberService.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(cuMember.getMemberCode())
                .imageUrl(image)
                .build();
        // 查询该会员伞下有多少个部门，没有部门不放
        List<Integer> placeDeptList = cuMemberService.queryMemberDept(cuMember.getPkId());
        if (CollectionUtil.isEmpty(placeDeptList)) {
            return cuMemberDisVO;
        }
        List<CuMemberExt> lastCuMemberList = cuMemberService.queryCuMemberLastPlaceParent(placeDeptList, memberAchieveDisParam.getPkMember());
        List<CuMemberAchieveDisVO> cuMemberAchieveDisVOList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(lastCuMemberList)) {
            for (CuMemberExt cuMemberExt : lastCuMemberList) {
                CuMemberAchieveDisVO cuMemberAchieveDisVO = new CuMemberAchieveDisVO();
                cuMemberAchieveDisVO.setPlaceDept(cuMemberExt.getPlaceDept());
                String imageUrl = setGradeImageUrl(cuMemberExt.getCategory(), cuMemberExt.getGradeValue());
                cuMemberAchieveDisVO.setLastMemberCode(cuMemberExt.getMemberCode());
                cuMemberAchieveDisVO.setLastMemberName(cuMemberExt.getMemberName());
                cuMemberAchieveDisVO.setLastImageUrl(imageUrl);
                cuMemberAchieveDisVOList.add(cuMemberAchieveDisVO);
            }
        }
        cuMemberDisVO.setMemberAchieveDisVOList(cuMemberAchieveDisVOList);
        return cuMemberDisVO;
    }

    @Override
    public CuMemberDisVO queryCuMemberDis(MemberAchieveDisParam memberAchieveDisParam) {
        CuMember cuMember = cuMemberService.getMember(memberAchieveDisParam.getMemberCode());
        CuMemberDisVO cuMemberDisVO = BeanUtil.copyProperties(cuMember, CuMemberDisVO.class);
        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) {
        Date endDate = DateUtils.currentDate();
        String endDateStr = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, endDate);
        Date startDate;
        // 近7天
        CuMemberSettlePeriod cuMemberSettlePeriod = cuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(endDateStr);
        if (EDayType.LAST_SEVEN_DAY.getValue() == memberAchieveDisParam.getDayType()) {
            startDate = DateUtils.beforeDate(7, ChronoUnit.DAYS, endDate);
        } else if (EDayType.LAST_FIFTEEN_DAY.getValue() == memberAchieveDisParam.getDayType()) {
            startDate = DateUtils.beforeDate(15, ChronoUnit.DAYS, endDate);
        } else {
            startDate = DateUtils.beforeDate(1, ChronoUnit.MONTHS, endDate);
        }
        // 判断是否跨月
        String treeTableName = TableNameConstants.CU_MEMBER_TREE + DateUtils.getMonth(endDateStr);
        String achieveTableName = TableNameConstants.CU_MEMBER_ACHIEVE + DateUtils.getMonth(endDateStr);
        if (!DateUtils.betweenMonth(startDate, endDate)) {

        }

        return null;
    }

    @Override
    public List<CuMemberNewAddAchieveVO> selectNewAddAchieve(CuMemberNewAddAchieveVO cuMemberNewAddAchieveVO) {
        List<CuMemberNewAddAchieveVO> cuMemberNewAddAchieveVOList = new ArrayList<>();
        List<CuMemberNewAddAchieveVO> achieveMonthByPeriod = getAchieveMonthByPeriod(cuMemberNewAddAchieveVO);
        //期数类型
        int dayType = EDayType.getPeriodNum(cuMemberNewAddAchieveVO.getDayType());
        if (CollUtil.isNotEmpty(achieveMonthByPeriod)) {
            //表名
            List<String> achieveTableList = achieveMonthByPeriod.stream().map(CuMemberNewAddAchieveVO::getEndPeriod).distinct().map(monthDate -> TableNameConstants.CU_MEMBER_SETTLE_D + monthDate).collect(Collectors.toList());
            //查询存在表名
            List<String> tableList = baseMapper.selectTableNameIsExist(achieveTableList);
            if (CollUtil.isNotEmpty(tableList)) {
                cuMemberNewAddAchieveVO.setAchieveTableList(tableList);
                cuMemberNewAddAchieveVOList = baseMapper.selectNewAddAchieveByPeriod(cuMemberNewAddAchieveVO);
            }
            if (CollUtil.isNotEmpty(cuMemberNewAddAchieveVOList)) {
                for (CuMemberNewAddAchieveVO newAddAchieveVO : cuMemberNewAddAchieveVOList) {
                    //转化单位万
                    BigDecimal aNewPv = newAddAchieveVO.getANewPv().divide(new BigDecimal("1000"));
                    newAddAchieveVO.setANewPv(aNewPv);
                }
            }
        }
        LocalDate endDate = LocalDate.now();
        LocalDate startDate = endDate.minus(dayType, ChronoUnit.DAYS);
        return initialDate(cuMemberNewAddAchieveVOList, endDate, startDate, achieveMonthByPeriod);
    }

    /**
     * 根据当前期数查询月表
     *
     * @param cuMemberNewAddAchieveVO 入参
     * @return List<CuMemberNewAddAchieveVO>
     */
    private List<CuMemberNewAddAchieveVO> getAchieveMonthByPeriod(CuMemberNewAddAchieveVO cuMemberNewAddAchieveVO) {
        //获取期数
        int period = cuMemberBaseService.getPeriod(null);
        cuMemberNewAddAchieveVO.setEndPeriod(period);
        cuMemberNewAddAchieveVO.setPeriodNum(EDayType.getPeriodNum(cuMemberNewAddAchieveVO.getDayType()));
        return baseMapper.selectNewAddAchieveMonthByPeriod(cuMemberNewAddAchieveVO);
    }


    /**
     * 初如化日期值
     *
     * @param cuMemberNewAddAchieveVOList 查询结题
     * @param dayType                     期数
     * @return List<CuMemberNewAddAchieveVO>
     */
    private List<CuMemberNewAddAchieveVO> initialDate(List<CuMemberNewAddAchieveVO> cuMemberNewAddAchieveVOList, int dayType, List<CuMemberNewAddAchieveVO> achieveMonthByPeriod) {
        //期数 格式化
        String monthDay = DateUtils.getBeforeRecentlyMonday(new Date());
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate localDate = LocalDate.parse(monthDay, df);

        if (CollUtil.isEmpty(cuMemberNewAddAchieveVOList)) {
            CuMemberNewAddAchieveVO memberNewAddAchieveVO;
            LocalDate settleDate = localDate;
            cuMemberNewAddAchieveVOList = new ArrayList<>();
            for (int i = 0; i < dayType; i++) {
                settleDate = i == 0 ? localDate : settleDate.minusDays(7);
                memberNewAddAchieveVO = CuMemberNewAddAchieveVO.builder().settleDate(DateUtils.toDate(settleDate))
                        .aNewPv(BigDecimal.ZERO).build();
                cuMemberNewAddAchieveVOList.add(memberNewAddAchieveVO);
            }
        } else {
            CuMemberNewAddAchieveVO memberNewAddAchieveVO;
            int size = cuMemberNewAddAchieveVOList.size();
            Map<Integer, CuMemberNewAddAchieveVO> map = achieveMonthByPeriod.stream().collect(Collectors.toMap(CuMemberNewAddAchieveVO::getEndPeriod, o -> o));
            //结算日期赋值
            for (CuMemberNewAddAchieveVO newAddAchieveVO : cuMemberNewAddAchieveVOList) {
                CuMemberNewAddAchieveVO addAchieveVO = map.get(newAddAchieveVO.getPeriodNum());
                if (null != addAchieveVO) {
                    newAddAchieveVO.setSettleDate(addAchieveVO.getSettleDate());
                }
            }
            if (size != dayType) {
                //前一个期数的时间
                LocalDate dateBeforeSe = localDate;
                Map<Date, CuMemberNewAddAchieveVO> achieveMap = cuMemberNewAddAchieveVOList.stream().collect(Collectors.toMap(CuMemberNewAddAchieveVO::getSettleDate, o -> o));
                for (int i = 0; i < dayType; i++) {
                    dateBeforeSe = i == 0 ? dateBeforeSe : dateBeforeSe.minusDays(7);
                    Date date = DateUtils.toDate(dateBeforeSe);
                    if (null == achieveMap.get(date)) {
                        memberNewAddAchieveVO = CuMemberNewAddAchieveVO.builder().settleDate(date)
                                .aNewPv(BigDecimal.ZERO).build();
                        cuMemberNewAddAchieveVOList.add(memberNewAddAchieveVO);
                    }
                }
            }
            //排序
            cuMemberNewAddAchieveVOList.sort(Comparator.comparing(CuMemberNewAddAchieveVO::getSettleDate));
        }

        return cuMemberNewAddAchieveVOList;
    }

    /**
     * 根据日期查询会员的新增业绩
     *
     * @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(new BigDecimal("1000"));
                BigDecimal aRegNewPv = newAddAchieveVO.getRepANewPv().divide(new BigDecimal("1000"));

                newAddAchieveVO.setANewPv(null != rate ? aNewPv.multiply(rate) : aNewPv);
                newAddAchieveVO.setRepANewPv(null != rate ? aRegNewPv.multiply(rate) : aRegNewPv);

            }
        }
        initialDate(cuMemberNewAddAchieveVOList, endDate, startDate, null);
        return cuMemberNewAddAchieveVOList;
    }

    /**
     * 初如化日期值
     *
     * @param cuMemberNewAddAchieveVOList 查询结题
     * @param endDate                     开始时间
     * @param startDate                   结束时间
     * @return List<CuMemberNewAddAchieveVO>
     */
    private List<CuMemberNewAddAchieveVO> initialDate(List<CuMemberNewAddAchieveVO> cuMemberNewAddAchieveVOList, LocalDate endDate, LocalDate startDate, List<CuMemberNewAddAchieveVO> achieveMonthByPeriod) {
        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)
                        .build();
                cuMemberNewAddAchieveVOList.add(memberNewAddAchieveVO);
            }
        } else {
            CuMemberNewAddAchieveVO memberNewAddAchieveVO;
            int size = cuMemberNewAddAchieveVOList.size();
            Map<Integer, CuMemberNewAddAchieveVO> map = achieveMonthByPeriod.stream().collect(Collectors.toMap(CuMemberNewAddAchieveVO::getEndPeriod, o -> o));
            //结算日期赋值
            for (CuMemberNewAddAchieveVO newAddAchieveVO : cuMemberNewAddAchieveVOList) {
                CuMemberNewAddAchieveVO addAchieveVO = map.get(newAddAchieveVO.getPeriodNum());
                if (null != addAchieveVO) {
                    newAddAchieveVO.setSettleDate(addAchieveVO.getSettleDate());
                }
            }
            if (size != days) {
                Map<Date, CuMemberNewAddAchieveVO> achieveMap = 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 == achieveMap.get(localDate)) {
                        memberNewAddAchieveVO = CuMemberNewAddAchieveVO.builder().settleDate(localDate)
                                .aNewPv(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 selectMemberAwards(Long pkMember, Integer pkCountry) {
        Integer pkAwards;
        //获取期数
        int period = cuMemberBaseService.getPeriod(null);
        String settleTable = getTableName();

        //根据国家获取奖衔配置信息
        List<BdAwards> awardsList = awardsServiceApi.queryAwards(pkCountry).getData();
        //升序排序
        awardsList.sort(Comparator.comparing(BdAwards::getAwardsValue));
        Map<Integer, BdAwards> awardsMap = awardsList.stream().collect(Collectors.toMap(BdAwards::getAwardsValue, o -> o));

        //查询会员的荣誉头衔
        CuMemberAwardsUnderVO memberAwards = CuMemberAwardsUnderVO.builder().settleTable(settleTable).pkMember(pkMember).pkCountry(pkCountry).period(period).build();
        CuMemberAwardsUnderVO cuMemberAwardsUnderVO = baseMapper.selectMinRealPvByPkMember(memberAwards);
        pkAwards = cuMemberService.queryMember(pkMember).getPkAwards();
        if (null != cuMemberAwardsUnderVO) {
            BigDecimal sumRealPv = cuMemberAwardsUnderVO.getASumRealPv();
            cuMemberAwardsUnderVO.setSumRealPv(sumRealPv.divide(new BigDecimal("1000")));
        } else {
            cuMemberAwardsUnderVO = CuMemberAwardsUnderVO.builder().sumRealPv(BigDecimal.ZERO).build();
        }
        BdAwards bdAwards = awardsServiceApi.getAwardsOne(pkAwards).getData();
        List<BdAwards> list = awardsList.stream().filter(a -> a.getAwardsValue() > bdAwards.getAwardsValue()).collect(Collectors.toList());
        //当奖衔最大级别时，目标值-1
        if (CollUtil.isNotEmpty(list)) {
            BigDecimal targetPv = awardsMap.get(list.get(0).getAwardsValue()).getCommunityCheck();
            cuMemberAwardsUnderVO.setTargetPv(targetPv.divide(new BigDecimal("1000")));
            cuMemberAwardsUnderVO.setTarAwardsName(list.get(0).getAwardsName());
            cuMemberAwardsUnderVO.setPkTransaction(list.get(0).getPkTransaction());
        } else {
            BigDecimal targetPv = new BigDecimal("-1");
            cuMemberAwardsUnderVO.setTargetPv(targetPv);
        }

        //中国转汇率
        if (null != cuMemberAwardsUnderVO && pkCountry.equals(CountryConstants.CHINA_COUNTRY)) {
            //根据国家查汇率
            BigDecimal rate = iCuMemberBaseService.getCurrency(pkCountry).getInExchangeRate();
            cuMemberAwardsUnderVO.setASumRealPv(getBigDecimal(cuMemberAwardsUnderVO.getASumRealPv()).multiply(rate));
            cuMemberAwardsUnderVO.setBSumRealPv(getBigDecimal(cuMemberAwardsUnderVO.getBSumRealPv()).multiply(rate));
            cuMemberAwardsUnderVO.setTargetPv(getBigDecimal(cuMemberAwardsUnderVO.getTargetPv()).multiply(rate));
            cuMemberAwardsUnderVO.setSumRealPv(getBigDecimal(cuMemberAwardsUnderVO.getSumRealPv()).multiply(rate));
        }
        return cuMemberAwardsUnderVO;
    }


    @Override
    public CuMemberAwardsDisVO selectAwardsByPkMember(Long pkMember, Integer pkCountry) {
        CuMemberAwardsDisVO cuMemberAwardsDisVO = new CuMemberAwardsDisVO();
        //获取期数
        int period = cuMemberBaseService.getPeriod(null);
        String settleTable = getTableName();

        //根据国家获取奖衔配置信息
        List<BdAwards> awardsList = awardsServiceApi.queryAwards(pkCountry).getData();
        Map<Integer, BdAwards> awardsMap = getAwardsMap(awardsList);
        //查询会员的荣誉头衔
        CuMemberAwardsUnderVO memberAwards = CuMemberAwardsUnderVO.builder().settleTable(settleTable).pkMember(pkMember).pkCountry(pkCountry).period(period).build();
        List<CuMemberAwardsUnderVO> cuMemberAwardsUnderVOList = baseMapper.selectAwardsByPkMember(memberAwards);
        //查询会员信息
        CuMember member = cuMemberService.getMemberById(pkMember);
        //登录会员显示信息
        CuMemberAwardsUnderVO cuMemberAwardsUnderVO = CuMemberAwardsUnderVO.builder()
                .memberName(member.getMemberName())
                .memberPath(member.getHeadPath())
                .pkAwards(member.getPkAwards())
                .build();
        getCuMemberAwars(cuMemberAwardsUnderVO, awardsMap, awardsList, false);
        cuMemberAwardsDisVO.setMemberAwardsUnderVO(cuMemberAwardsUnderVO);
        //前三部门的显示信息
        if (CollUtil.isNotEmpty(cuMemberAwardsUnderVOList)) {
            for (CuMemberAwardsUnderVO memberAwardsUnderVO : cuMemberAwardsUnderVOList) {
                //转结算国目标奖衔处理
                //部门的实际国家
                Integer pkCountryDept = memberAwardsUnderVO.getPkCountry();
                if (!pkCountryDept.equals(pkCountry)) {
                    awardsList = awardsServiceApi.queryAwards(pkCountryDept).getData();
                    awardsMap = getAwardsMap(awardsList);
                }
                getCuMemberAwars(memberAwardsUnderVO, awardsMap, awardsList, false);
                memberAwardsUnderVO.setTargetPv(memberAwardsUnderVO.getTargetPv());
                memberAwardsUnderVO.setASumRealPv(memberAwardsUnderVO.getASumRealPv().divide(new BigDecimal("1000")));
            }
        }
        cuMemberAwardsDisVO.setMemberAwardsList(cuMemberAwardsUnderVOList);
        return cuMemberAwardsDisVO;
    }

    /**
     * 根据配置奖衔转化成map
     *
     * @param awardsList 奖衔配置列表
     * @return Map<Integer, BdAwards>
     */
    private Map<Integer, BdAwards> getAwardsMap(List<BdAwards> awardsList) {
        //升序排序
        awardsList.sort(Comparator.comparing(BdAwards::getAwardsValue));
        return awardsList.stream().collect(Collectors.toMap(BdAwards::getAwardsValue, o -> o));
    }

    @Override
    public List<CuMemberAwardsUnderVO> selectAwardsFiveByPkMember(Long pkMember, Integer pkCountry, Integer placeDept) {
        //获取期数
        int period = cuMemberBaseService.getPeriod(null);
        String settleTable = getTableName();
        //根据国家获取奖衔配置信息
        List<BdAwards> awardsList = awardsServiceApi.queryAwards(pkCountry).getData();
        //升序排序
        awardsList.sort(Comparator.comparing(BdAwards::getAwardsValue));
        Map<Integer, BdAwards> awardsMap = awardsList.stream().collect(Collectors.toMap(BdAwards::getAwardsValue, o -> o));

        //查询某个安置区域的前五的人
        CuMemberAwardsUnderVO leftMemberAwards = CuMemberAwardsUnderVO.builder().settleTable(settleTable)
                .pkMember(pkMember).pkCountry(pkCountry).period(period).placeDept(placeDept).build();

        List<CuMemberAwardsUnderVO> MemberAwardsUnderVOList = baseMapper.selectUnderMemberAwards(leftMemberAwards);

        if (CollUtil.isNotEmpty(MemberAwardsUnderVOList)) {
            for (CuMemberAwardsUnderVO cuMemberAwardsUnderVO : MemberAwardsUnderVOList) {
                getCuMemberAwars(cuMemberAwardsUnderVO, awardsMap, awardsList, true);
                List<CuMemberAwardsUnderVO> cuMemberAwardsUnderVOList = baseMapper.selectAwardsByPkMember(cuMemberAwardsUnderVO);
                if (CollUtil.isNotEmpty(cuMemberAwardsUnderVOList)) {
                    for (CuMemberAwardsUnderVO awardsUnderVO : cuMemberAwardsUnderVOList) {
                        awardsUnderVO.setTargetPv(cuMemberAwardsUnderVO.getTargetPv());
                        awardsUnderVO.setASumRealPv(awardsUnderVO.getASumRealPv().divide(new BigDecimal("1000")));
                    }
                    cuMemberAwardsUnderVO.setAwardsFiveList(cuMemberAwardsUnderVOList);
                }
            }
            //补全默认条数
            int size = MemberAwardsUnderVOList.size();
            if (size < 5) {
                MemberAwardsUnderVOList.addAll(getAwardDefaultValue(5 - size));
            }
            return MemberAwardsUnderVOList;
        } else {
            return getAwardDefaultValue(5);
        }
    }

    /**
     * 获取荣誉奖衔默认值
     *
     * @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) {
        if (null != memberAwardsUnderVO) {
            //业绩以万为单位
            // memberAwardsUnderVO.setASumRealPv(memberAwardsUnderVO.getASumRealPv().divide(new BigDecimal("10000")));
            Integer pkAwards = memberAwardsUnderVO.getPkAwards();
            if (null == pkAwards) {
                return null;
            }
            BdAwards BdAwards = awardsServiceApi.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.divide(new BigDecimal("1000")));
            } else {
                //会员是最高奖衔时,目标值取最高奖衔的目标值
                int size = awardsList.size() - 1;
                BigDecimal targetPv = awardsMap.get(awardsList.get(size).getAwardsValue()).getCommunityCheck();
                memberAwardsUnderVO.setTargetPv(targetPv.divide(new BigDecimal("1000")));
            }
        }
        return memberAwardsUnderVO;
    }

    /**
     * 获取昨天的表名，不存在则获取前天的表名
     *
     * @return String
     */
    private String getTableName() {
        //获取昨天的表名
        String settleTable = getTableNameByPeriod(1);
        //查询存在表名
        List<String> tableList = baseMapper.selectTableNameIsExist(Collections.singletonList(settleTable));
        if (CollUtil.isEmpty(tableList)) {
            //前天的表名
            settleTable = getTableNameByPeriod(2);
        }
        return settleTable;
    }

    /**
     * 根据期数获取表名
     *
     * @param days 天数
     * @return String
     */
    private String getTableNameByPeriod(long days) {
        //获取期数
        String localDate = LocalDate.now().minus(days, ChronoUnit.DAYS).format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        int period = cuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(localDate).getPkId();
        String settleTable = TableNameConstants.CU_MEMBER_SETTLE_D + period;
        return settleTable;
    }

    @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")));

        //去年同月 （bug处理新需求不需要展示这部分数据）
//        LocalDate lastYearDate = localDate.minus(12, ChronoUnit.MONTHS);
//        CuMemberMonthAchieveContrastVO lastYearAchieve = getMonthInfo(lastYearDate, pkMember, pkCountry);
//        lastYearAchieve.setDate(lastYearDate.format(DateTimeFormatter.ofPattern("yyyy-MM")));


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


//        achieveContrastVOList.add(lastYearAchieve);
        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"));
        String achieveTable = TableNameConstants.CU_MEMBER_ACHIEVE + DateUtils.getMonth(date);
        return achieveTable;
    }

    /**
     * @description: 查询左右区新增业绩
     * @author: zhang jing
     * @date: 2023/5/19 11:00
     * @param: [pna]
     * @return: com.hzs.member.achieve.controller.vo.PlaceNewAddAchieveVO
     **/
    private PlaceNewAddAchieveVO selectNewABAchieve(PlaceNewAddAchieveVO pna) {
        return baseMapper.selectNewABAchieve(pna);
    }

    /**
     * @description: 查询左右区血缘业绩
     * @author: zhang jing
     * @date: 2023/9/25 11:30
     * @param: [pna]
     * @return: com.hzs.member.achieve.controller.vo.PlaceNewAddAchieveVO
     **/
    private List<PlaceNewAddAchieveVO> selectABDirectAchieve(PlaceNewAddAchieveVO pna) {
        return baseMapper.selectABDirectAchieve(pna);
    }

    /**
     * @description: 查询直推业绩
     * @author: zhang jing
     * @date: 2023/5/19 15:51
     * @param: [pna]
     * @return: com.hzs.member.achieve.controller.vo.PlaceNewAddAchieveVO
     **/
    private PlaceNewAddAchieveVO selectParentAchieve(PlaceNewAddAchieveVO pna) {
        return baseMapper.selectParentAchieve(pna);
    }


    /**
     * @description: 查询历史左右区人数
     * @author: zhang jing
     * @date: 2023/5/19 11:32
     * @param: [pna]
     * @return: com.hzs.member.achieve.controller.vo.PlaceNewAddAchieveVO
     **/
    private List<PlaceNewAddAchieveVO> selectABCoun(PlaceNewAddAchieveVO pna) {
        return baseMapper.selectABCoun(pna);
    }

    /**
     * @description: 查询最新月份左右区人数
     * @author: zhang jing
     * @date: 2023/9/10 17:27
     * @param: [pna]
     * @return: java.lang.Integer
     **/
    private List<PlaceNewAddAchieveVO> selectABNewMonthCoun(PlaceNewAddAchieveVO pna) {
        return baseMapper.selectABNewMonthCoun(pna);
    }

    /**
     * @description: 根据日期查询最新期数
     * @author: zhang jing
     * @date: 2023/6/6 14:52
     * @param: [pna]
     * @return: java.lang.Integer
     **/
    private Integer mostNewPeriod(PlaceNewAddAchieveVO pna) {
        return baseMapper.mostNewPeriod(pna);
    }

    /**
     * @description: 查询各个等级直推人数和业绩
     * @author: zhang jing
     * @date: 2023/5/23 10:20
     * @param: [pav]
     * @return: java.util.List<com.hzs.member.achieve.controller.vo.ParentAchieveVO>
     **/
    private List<ParentAchieveVO> selectParentCounAchieve(ParentAchieveVO pav) {
        return baseMapper.selectParentCounAchieve(pav);
    }

    /**
     * @description: 查询本人直推业绩
     * @author: zhang jing
     * @date: 2023/5/23 19:32
     * @param: [pav]
     * @return: java.util.List<com.hzs.member.achieve.controller.vo.ParentAchieveVO>
     **/
    List<ParentAchieveVO> selfParentCounAchieve(ParentAchieveVO pav) {
        return baseMapper.selfParentCounAchieve(pav);
    }

    /**
     * @description: 查询前10直推业绩
     * @author: zhang jing
     * @date: 2023/5/23 19:32
     * @param: [pav]
     * @return: java.util.List<com.hzs.member.achieve.controller.vo.ParentAchieveVO>
     **/
    List<ParentAchieveVO> parentCounAchieveTop(ParentAchieveVO pav) {
        return baseMapper.parentCounAchieveTop(pav);
    }

    /**
     * @description: 查询所有直推人
     * @author: zhang jing
     * @date: 2023/8/7 11:43
     * @param: [pav]
     * @return: java.util.List<com.hzs.member.achieve.controller.vo.ParentAchieveVO>
     **/
    List<ParentAchieveVO> allDirectPush(ParentAchieveVO pav) {
        return baseMapper.allDirectPush(pav);
    }


    /**
     * @description: 直推业绩前十人伞下等级业绩
     * @author: zhang jing
     * @date: 2023/5/31 19:57
     * @param: [pav]
     * @return: java.util.List<com.hzs.member.achieve.controller.vo.ParentAchieveVO>
     **/
    List<ParentAchieveVO> umbrellaAchieveTop(ParentAchieveVO pav) {
        return baseMapper.umbrellaAchieveTop(pav);
    }


    /**
     * @description: 业绩分布-新增业绩统计
     * @author: zhang jing
     * @date: 2023/5/19 10:33
     * @param: []
     * @return: com.hzs.member.achieve.controller.vo.PlaceNewAddAchieveVO
     **/
    @Override
    public PlaceNewAddAchieveVO placeNewAddAchieveStat(PlaceNewAddAchieveVO pna) {
        PlaceNewAddAchieveVO rtupna = new PlaceNewAddAchieveVO();
        BigDecimal constant = new BigDecimal(10000);
        //当前日期
        Date d = DateUtils.parseStringToDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, DateUtils.currentDate()));

        String dStr = DateUtils.getMonth(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, DateUtils.currentDate()));
        //当月第一天
        LocalDate localDate = null == pna.getMonthType() ? LocalDate.now() : LocalDate.of(LocalDate.now().getYear(), pna.getMonthType(), 1);
        LocalDate startDate = localDate.with(TemporalAdjusters.firstDayOfMonth());

        // 获取下个月第一天
        LocalDate endDate = localDate.with(TemporalAdjusters.firstDayOfNextMonth());
        Date enddate = DateUtils.toDate(endDate);
        if (DateUtils.compareDateBefore(d, enddate)) {
            endDate = DateUtils.toLocalDate(DateUtils.beforeDate(1, ChronoUnit.DAYS, d));
        } 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(d, startDated) || DateUtils.compareDateEqual(d, startDated)) {
            rtupna.setLeftAchieve(BigDecimal.ZERO);
            rtupna.setRightAchieve(BigDecimal.ZERO);
            rtupna.setLeftCoun(0);
            rtupna.setRightCount(0);
            rtupna.setDirectAchieve(BigDecimal.ZERO);
            return rtupna;
        }

        String achieveTableName = TableNameConstants.CU_MEMBER_ACHIEVE + DateUtils.getMonth(startDateStr);
        pna.setStartDate(startDateStr);
        pna.setEndDate(endDateStr);
        pna.setAchieveTableName(achieveTableName);
        R<CurrencyDTO> currency = currencyServiceApi.getCurrency(SecurityUtils.getPkCountry());

        //查询左右区业绩
        PlaceNewAddAchieveVO achieve = selectNewABAchieve(pna);
        BigDecimal leftAchieve;
        BigDecimal rightAchieve;

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

        if (leftAchieve.compareTo(BigDecimal.ZERO) > 0) {
            leftAchieve = leftAchieve.divide(constant, 4, RoundingMode.DOWN);
        }
        if (rightAchieve.compareTo(BigDecimal.ZERO) > 0) {
            rightAchieve = rightAchieve.divide(constant, 4, RoundingMode.DOWN);
        }
        rtupna.setLeftAchieve(leftAchieve);
        rtupna.setRightAchieve(rightAchieve);
        //当前日期
        LocalDate currentDate = LocalDate.now();
        if (currentDate.isBefore(endDate)) {
            endDateStr = currentDate.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 = cuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(
                DateUtils.parseDateToStr(endDateStr)).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(d));
                int lastendperiod = cuMemberSettlePeriodService.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().intValue() == EPlaceDept.LEFT_DEPT.getValue()) {
                        lasLeft = lpl.getMemberCount();
                    }
                    if (lpl.getPlaceDept().intValue() == EPlaceDept.RIGHT_DEPT.getValue()) {
                        lasRegist = lpl.getMemberCount();
                    }
                }
                for (PlaceNewAddAchieveVO pl : monthCount) {
                    if (pl.getPlaceDept().intValue() == EPlaceDept.LEFT_DEPT.getValue()) {
                        rtupna.setLeftCoun(pl.getMemberCount() > lasLeft ? pl.getMemberCount() - lasLeft : 0);
                    }
                    if (pl.getPlaceDept().intValue() == 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));
                int frontLastendperiod = cuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(
                        DateUtils.parseDateToStr(frontLastMonth)).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);
                        }
                    }
                }
            }
        }

        //查询直推业绩（血缘业绩 查询月度表）
        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() == CountryConstants.CHINA_COUNTRY) {
                    rtupna.setDirectAchieve(rtupna.getDirectAchieve().multiply(currency.getData().getInExchangeRate()));
                }
                if (rtupna.getDirectAchieve().compareTo(BigDecimal.ZERO) > 0) {
                    rtupna.setDirectAchieve(rtupna.getDirectAchieve().divide(constant, 4, RoundingMode.DOWN));
                } else {
                    rtupna.setDirectAchieve(BigDecimal.ZERO);
                }
            } else {
                rtupna.setDirectAchieve(BigDecimal.ZERO);
            }
        }
        //查询左右区血缘业绩
        List<PlaceNewAddAchieveVO> lrDirectAchieve = selectABDirectAchieve(pam);
        BigDecimal leftDirectAchieve = null;
        BigDecimal rightDirectAchieve = null;
        if (CollectionUtil.isNotEmpty(lrDirectAchieve)) {
            for (PlaceNewAddAchieveVO pl : lrDirectAchieve) {
                if (pl.getDirectAchieve() != null && pl.getPlaceDept() == EPlaceDept.LEFT_DEPT.getValue()) {
                    if (pna.getPkCountry() == CountryConstants.CHINA_COUNTRY) {
                        leftDirectAchieve = pl.getDirectAchieve().multiply(currency.getData().getInExchangeRate());
                    }
                    leftDirectAchieve = leftDirectAchieve.divide(constant, 4, RoundingMode.DOWN);
                    rtupna.setLeftDirectAchieve(leftDirectAchieve);
                }
                if (pl.getDirectAchieve() != null && pl.getPlaceDept() == EPlaceDept.RIGHT_DEPT.getValue()) {
                    if (pna.getPkCountry() == CountryConstants.CHINA_COUNTRY) {
                        rightDirectAchieve = pl.getDirectAchieve().multiply(currency.getData().getInExchangeRate());
                    }
                    rightDirectAchieve = rightDirectAchieve.divide(constant, 4, RoundingMode.DOWN);
                    rtupna.setRightDirectAchieve(rightDirectAchieve);
                }
            }
        }
        return rtupna;
    }

    /**
     * @description: 月度业绩-详情
     * @author: zhang jing
     * @date: 2023/9/28 11:38
     * @param: [pna]
     * @return: java.util.List<com.hzs.member.achieve.controller.vo.PlaceNewAddAchieveVO>
     **/
    @Override
    public List<PlaceNewAddAchieveVO> placeNewAddAchieveDetails(PlaceNewAddAchieveVO pna) {
        return baseMapper.placeNewAddAchieveDetails(pna);
    }


    /**
     * @description: 业绩分布-直推业绩（右图）
     * @author: zhang jing
     * @date: 2023/5/20 16:20
     * @param: [pa]
     * @return: com.hzs.member.achieve.controller.vo.ParentAchieveVO
     **/
    @Override
    public ParentAchieveVO parentAchieveRight(ParentAchieveVO pa) {
        pa = getDateStr(pa);
        R<CurrencyDTO> currency = currencyServiceApi.getCurrency(SecurityUtils.getPkCountry());
        //结束期数
        int endPeriod = cuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(pa.getEndDate()).getPkId();

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

        return pa;
    }

    /**
     * @description: 判断是否跨月查询并获取表名
     * @author: zhang jing
     * @date: 2023/5/23 19:38
     * @param: [pa]
     * @return: com.hzs.member.achieve.controller.vo.ParentAchieveVO
     **/
    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;
    }

    /**
     * @description: 业绩分布-直推业绩统计（左图）
     * @author: zhang jing
     * @date: 2023/5/23 14:22
     * @param: [pa]
     * @return: java.util.List<com.hzs.member.achieve.controller.vo.ParentAchieveVO>
     **/
    @Override
    public List<ParentAchieveVO> parentAchieveLeft(ParentAchieveVO pa) {
        pa = getDateStr(pa);
        //获取期数
        int endPeriod = cuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(pa.getEndDate()).getPkId();
        pa.setPeriod(endPeriod);
        CuMember member = cuMemberService.getMember(pa.getPkMember());
        List<ParentAchieveVO> parentList = new ArrayList<>();
        ParentAchieveVO par = new ParentAchieveVO();
        par.setMemberName(member.getMemberName());
        par.setPkMember(member.getPkId());
        R<CurrencyDTO> currency = currencyServiceApi.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() == CountryConstants.CHINA_COUNTRY) {
                            endum.setAchieve(endum.getAchieve().multiply(currency.getData().getInExchangeRate()));
                        }
                        newumbrellaList.add(endum);
                    }
                }
                end.setUmbrellaList(newumbrellaList);
            }
        }
        parentList.addAll(endParentList);
        return parentList;
    }


    /**
     * @description: 获取前十人员
     * @author: zhang jing
     * @date: 2023/6/28 16:43
     * @param: [pa, list]
     * @return: com.hzs.member.achieve.controller.vo.ParentAchieveVO
     **/
    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<>();
    }

    BigDecimal ten = new BigDecimal(10000);

    /**
     * 查询会员真实业绩
     */
    @Override
    public RealPerformanceVo queryRealPerformance(Long pkMember, Integer pkCountry, Integer month) {

        R<CurrencyDTO> currencyDto = currencyServiceApi.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 = memberMonthAchieveService.queryCuMemberMonthAchieveInfo(pkMember, achieveTable);
            if (realPerformanceVo != null) {
                if (pkCountry.equals(CountryConstants.CHINA_COUNTRY)) {
                    realPerformanceVo.setFirstLeftPurchaseTotal(realPerformanceVo.getFirstLeftPurchaseTotal().multiply(currency.getInExchangeRate()).divide(ten));
                    realPerformanceVo.setFirstRightPurchaseTotal(realPerformanceVo.getFirstRightPurchaseTotal().multiply(currency.getInExchangeRate()).divide(ten));
                    realPerformanceVo.setFirstLeftRepurchaseTotal(realPerformanceVo.getFirstLeftRepurchaseTotal().multiply(currency.getInExchangeRate()).divide(ten));
                    realPerformanceVo.setFirstRightRepurchaseTotal(realPerformanceVo.getFirstRightRepurchaseTotal().multiply(currency.getInExchangeRate()).divide(ten));
                }
                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 localDate
     * @return
     */
    private String getMonthTable(LocalDate localDate) {
        String date = localDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        String achieveTable = TableNameConstants.CU_MEMBER_MONTH + DateUtils.getMonth(date);
        return achieveTable;
    }


    /**
     * 会员真实业绩饼状图
     *
     * @param pkMember
     * @param pkCountry
     * @param month
     * @return
     */
    @Override
    public AzAchievementPie queryRealPerformancePic(Long pkMember, Integer pkCountry, Integer month) {
        R<CurrencyDTO> currencyDto = currencyServiceApi.getCurrency(pkCountry);
        CurrencyDTO currency = currencyDto.getData();
        //当月
        AzAchievementPie achievementPie = null;
        LocalDate localDate = null == month ? LocalDate.now() : LocalDate.of(LocalDate.now().getYear(), month, 1);
        //  String achieveTable = getAchieveTable(localDate);
        // Integer count = baseMapper.selectExistTable(achieveTable);
        //左区人数
        Long leftCount = cuMemberService.selectByDeptNumberCount(pkMember, EPlaceDept.LEFT_DEPT.getValue());
        // 右区人数
        Long rightCount = cuMemberService.selectByDeptNumberCount(pkMember, EPlaceDept.RIGHT_DEPT.getValue());
//        if (count.equals(1)) {
//            achievementPie = getQueryRealPerformancePic(pkMember, pkCountry, achieveTable);
//        }
        DateTime dateTime = DateUtil.offsetDay(DateUtils.currentDate(), -1);
        String time = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, dateTime);
        CuMemberSettlePeriod csPeriod = memberSettlePeriodService.getCuMemberSettlePeriodByDate(time);
        String settleTableName = TableNameConstants.CU_MEMBER_SETTLE + csPeriod.getPkId();
        CuMemberSettleExt memberSettleExt = memberTreeService.queryCuMemberTreeByPkMemberTable(pkMember);

        achievementPie = new AzAchievementPie();
        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())));
                recommendDataBaseVO.setHiFunAmount(recommendDataBaseVO.getHiFunAmount().subtract(getBigDecimal(startRe.getHiFunAmount())));
                recommendDataBaseVO.setHiFunAchieve(recommendDataBaseVO.getHiFunAchieve().subtract(getBigDecimal(startRe.getHiFunAchieve())));
            }
        }
    }

    /**
     * 转化页面显示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 = awardsServiceApi.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();
        BigDecimal hiFunAmount = recommendDataBaseVO.getHiFunAmount();
        BigDecimal hiFunAchieve = recommendDataBaseVO.getHiFunAchieve();
        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());
                hiFunAmount = hiFunAmount.add(dataVO.getHiFunAmount());
                hiFunAchieve = hiFunAchieve.add(dataVO.getHiFunAchieve());
            }
        }
        return RecommendDataDetailVO.builder()
                .realAmount(realAmount).realAchieve(realAchieve)
                .firstAmount(firstAmount).firstAchieve(firstAchieve)
                .repeatAmount(repeatAmount).repeatAchieve(repeatAchieve)
                .hiFunAmount(hiFunAmount).hiFunAchieve(hiFunAchieve)
                .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))
                .settleHiFunAmount(getSettleValue(currency, hiFunAmount))
                .settleHiFunAchieve(getSettleValue(currency, hiFunAchieve))
                .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 && null == startDataBaseVO) {
            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 = cuMemberService.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.executorService.submit(() -> baseMapper.selectPlaceImage(getPlacementDataBaseList(param, endDateParam)));
            if (null != endImageDataFuture) {
                //查询开始时间的安置数据
                Future<PlacementImageDataVO> startImageDataFuture = ThreadUtils.executorService.submit(() -> baseMapper.selectPlaceImage(getPlacementDataBaseList(param, startDate)));
                PlacementImageDataVO endImageData = null;
                PlacementImageDataVO startImageData = null;
                try {
                    endImageData = endImageDataFuture.get();
                    startImageData = startImageDataFuture.get();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (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<Integer, VertexDTO> map = (Map<Integer, VertexDTO>) objects[1];
        String localDate = (String) objects[2];
        Map<Integer, Future<RecommendImageDataVO>> futureMap = new HashMap();
        //多线程查询数据
        for (Long pkVertex : pkVertexList) {
            Long pkMember = map.get(pkVertex.intValue()).getPkMember();
            //线程共享数据不可见（参数重新赋值）
            PlacementDataParam dataParam = new PlacementDataParam();
            dataParam.setPeriod(period);
            dataParam.setPkMember(pkMember);
            dataParam.setPkSettleCountry(param.getPkSettleCountry());
            //查询体系
            Future<RecommendImageDataVO> future = ThreadUtils.executorService.submit(() -> baseMapper.selectRecommendVertexImage(getPlacementDataBaseList(dataParam, localDate)));
            futureMap.put(pkVertex.intValue(), future);
        }
        //返回结果组装
        if (MapUtil.isNotEmpty(futureMap)) {
            for (Map.Entry<Integer, 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().longValue());
                        recommendImageDataVO.setVertexName(vertex.getVertexName());
                        imageDataVOList.add(recommendImageDataVO);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } catch (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 = cuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(localDate).getPkId();
        param.setPeriod(period);
        //获取体系
        List<VertexDTO> vertexDTOList = iVertexServiceApi.findAllByPkCountry(param.getPkSettleCountry()).getData();
        Map<Integer, 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<Integer, VertexDTO> map = (Map<Integer, VertexDTO>) objects[1];
        String localDate = (String) objects[2];
        Map<Integer, Future<List<RecommendImageDataVO>>> futureMap = new HashMap();
        //多线程查询数据
        for (Long pkVertex : pkVertexList) {
            Long pkMember = map.get(pkVertex.intValue()).getPkMember();
            //线程共享数据不可见（参数重新赋值）
            PlacementDataParam dataParam = new PlacementDataParam();
            dataParam.setPeriod(period);
            dataParam.setPkMember(pkMember);
            dataParam.setPkSettleCountry(param.getPkSettleCountry());
            //查询体系
            Future<List<RecommendImageDataVO>> future = ThreadUtils.executorService.submit(() -> baseMapper.selectRecommendTeamImage(getPlacementDataBaseList(dataParam, localDate)));
            futureMap.put(pkVertex.intValue(), future);
        }

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

            for (Map.Entry<Integer, 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().longValue());
                        teamImagVO.setVertexName(vertex.getVertexName());
                        teamImagVO.setImageDataVOList(getTeamName(imageDataVOList, teamMap));
                        teamImagVOList.add(teamImagVO);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } catch (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);
    }

    /**
     * @description: 安置数据查询
     * @author: zhang jing
     * @date: 2024/7/16 13:16
     * @param: [pfq]
     * @return: java.util.List<com.hzs.member.achieve.controller.vo.PlaceFrameQueryVO>
     **/
    @Override
    public List<PlaceFrameQueryVO> placeFrameQuery(PlaceFrameQueryVO pfq) {
        return baseMapper.placeFrameQuery(pfq);
    }

    /**
     * @description: 查询本期安置伞下业绩和新增人数
     * @author: zhang jing
     * @date: 2024/7/24 9:47
     * @param: [pfq]
     * @return: java.util.List<com.hzs.member.achieve.controller.vo.PlaceFrameQueryVO>
     **/
    @Override
    public List<PlaceFrameQueryVO> placeBefFrameQuery(PlaceFrameQueryVO pfq) {
        return baseMapper.placeBefFrameQuery(pfq);
    }

    /**
     * @description: 推荐数据查询
     * @author: zhang jing
     * @date: 2024/7/17 9:25
     * @param: [pfq]
     * @return: java.util.List<com.hzs.member.achieve.controller.vo.PlaceFrameQueryVO>
     **/
    @Override
    public List<PlaceFrameQueryVO> parentFrameQuery(PlaceFrameQueryVO pfq) {
        return baseMapper.parentFrameQuery(pfq);
    }

    /**
     * @description: 查询本期推荐伞下业绩和新增人数
     * @author: zhang jing
     * @date: 2024/7/24 10:47
     * @param: [pfq]
     * @return: java.util.List<com.hzs.member.achieve.controller.vo.PlaceFrameQueryVO>
     **/
    @Override
    public List<PlaceFrameQueryVO> parentBefFrameQuery(PlaceFrameQueryVO pfq) {
        return baseMapper.parentBefFrameQuery(pfq);
    }

    /**
     * @description: 查询会员安置伞下第一层会员
     * @author: zhang jing
     * @date: 2024/7/17 9:24
     * @param: [pfq]
     * @return: java.util.List<com.hzs.member.achieve.controller.vo.PlaceFrameQueryVO>
     **/
    @Override
    public List<PlaceFrameQueryVO> placeMemberQuery(PlaceFrameQueryVO pfq) {
        return baseMapper.placeMemberQuery(pfq);
    }

    /**
     * @description: 查询本期安置网体会员
     * @author: zhang jing
     * @date: 2024/7/24 9:32
     * @param: [pfq]
     * @return: java.util.List<com.hzs.member.achieve.controller.vo.PlaceFrameQueryVO>
     **/
    @Override
    public List<PlaceFrameQueryVO> placeBefMemberQuery(PlaceFrameQueryVO pfq) {
        return baseMapper.placeBefMemberQuery(pfq);
    }


    /**
     * @description: 查询会员推荐伞下第一层会员
     * @author: zhang jing
     * @date: 2024/7/17 9:24
     * @param: [pfq]
     * @return: java.util.List<com.hzs.member.achieve.controller.vo.PlaceFrameQueryVO>
     **/
    @Override
    public List<PlaceFrameQueryVO> parentMemberQuery(PlaceFrameQueryVO pfq) {
        return baseMapper.parentMemberQuery(pfq);
    }

    /**
     * @description: 查询本期推荐伞下第一层会员
     * @author: zhang jing
     * @date: 2024/7/24 9:33
     * @param: [pfq]
     * @return: java.util.List<com.hzs.member.achieve.controller.vo.PlaceFrameQueryVO>
     **/
    @Override
    public List<PlaceFrameQueryVO> parentBefMemberQuery(PlaceFrameQueryVO pfq) {
        return baseMapper.parentBefMemberQuery(pfq);
    }

    /**
     * @description: 校验会员是否在某会员安置伞下
     * @author: zhang jing
     * @date: 2024/7/22 14:22
     * @param: [pfq]
     * @return: com.hzs.member.achieve.controller.vo.PlaceFrameQueryVO
     **/
    @Override
    public PlaceFrameQueryVO checkPlaceMemberQuery(PlaceFrameQueryVO pfq) {
        return baseMapper.checkPlaceMemberQuery(pfq);
    }

    /**
     * @description: 校验会员是否在某会员推荐线
     * @author: zhang jing
     * @date: 2024/7/22 14:22
     * @param: [pfq]
     * @return: com.hzs.member.achieve.controller.vo.PlaceFrameQueryVO
     **/
    @Override
    public PlaceFrameQueryVO checkParentMemberQuery(PlaceFrameQueryVO pfq) {
        return baseMapper.checkParentMemberQuery(pfq);
    }


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

}
