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

import com.hzs.bonus.account.service.ICuMemberAccountService;
import com.hzs.bonus.account.service.ICuMemberTradeDetailService;
import com.hzs.bonus.account.service.ICuMemberTradeService;
import com.hzs.bonus.achieve.service.ICuMemberSettlePeriodDetailService;
import com.hzs.bonus.achieve.service.ICuMemberSettlePeriodService;
import com.hzs.bonus.bonus.service.IBonusGrantService;
import com.hzs.bonus.bonus.service.ICuMemberBonusService;
import com.hzs.bonus.pub.tool.MemberToolsHandler;
import com.hzs.common.core.constant.CountryConstants;
import com.hzs.common.core.constant.MagicNumberConstants;
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.domain.member.account.CuMemberTrade;
import com.hzs.common.domain.member.account.CuMemberTradeDetail;
import com.hzs.common.domain.member.account.CuMemberTradeRecoil;
import com.hzs.common.domain.member.achieve.CuMemberSettlePeriod;
import com.hzs.common.domain.member.achieve.CuMemberSettlePeriodDetail;
import com.hzs.common.domain.member.achieve.ext.CuMemberSettlePeriodExt;
import com.hzs.common.domain.member.bonus.CuMemberBonus;
import com.hzs.common.domain.system.base.BdCountry;
import com.hzs.common.domain.system.config.BdAccount;
import com.hzs.member.account.ICuMemberTradeRecoilServiceApi;
import com.hzs.system.base.ICountryServiceApi;
import com.hzs.system.base.ICurrencyServiceApi;
import com.hzs.system.base.ISystemConfigServiceApi;
import com.hzs.system.base.dto.CurrencyDTO;
import com.hzs.system.config.IAccountServiceApi;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * @Description: 奖金发放实现类
 * @Author: sui q
 * @Time: 2023/3/20 17:05
 * @Classname: BonusGrantServiceImpl
 * @PackageName: com.hzs.member.bonus.service.impl
 */
@Service
public class BonusGrantServiceImpl implements IBonusGrantService {

    @DubboReference
    private IAccountServiceApi accountServiceApi;

    @DubboReference
    private ICuMemberTradeRecoilServiceApi cuMemberTradeRecoilServiceApi;

    private ICuMemberBonusService cuMemberBonusService;

    private ICuMemberSettlePeriodService cuMemberSettlePeriodService;

    @Autowired
    private MemberToolsHandler memberToolsHandler;

    private ICuMemberTradeService cuMemberTradeService;

    private ICuMemberTradeDetailService cuMemberTradeDetailService;

    private ICuMemberAccountService cuMemberAccountService;

    @Autowired
    private ICuMemberSettlePeriodDetailService cuMemberSettlePeriodDetailService;

    @DubboReference
    private ICountryServiceApi countryServiceApi;

    @DubboReference
    private ICurrencyServiceApi currencyServiceApi;

    @DubboReference
    private ISystemConfigServiceApi systemConfigServiceApi;

    @Autowired
    public void setCuMemberAccountService(ICuMemberAccountService cuMemberAccountService) {
        this.cuMemberAccountService = cuMemberAccountService;
    }

    @Autowired
    public void setCuMemberTradeDetailService(ICuMemberTradeDetailService cuMemberTradeDetailService) {
        this.cuMemberTradeDetailService = cuMemberTradeDetailService;
    }

    @Autowired
    public void setCuMemberTradeService(ICuMemberTradeService cuMemberTradeService) {
        this.cuMemberTradeService = cuMemberTradeService;
    }

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

    @Autowired
    public void setCuMemberBonusService(ICuMemberBonusService cuMemberBonusService) {
        this.cuMemberBonusService = cuMemberBonusService;
    }

    @Override
    public void publishBonusByPeriodEveryDay() {
        Map<Integer, BdCountry> integerBdCountryMap = countryServiceApi.getAllCountryMap().getData();
        if(integerBdCountryMap.size() > 0) {
            for (Integer pkCountry : integerBdCountryMap.keySet()) {
                String settleDate = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, DateUtils.beforeDate(1, ChronoUnit.DAYS, DateUtils.currentDate()));
                CuMemberSettlePeriodExt cuMemberSettlePeriod = getCuMemberSettlePeriod(pkCountry, settleDate);
                // 设置不公布后不能自动公布奖金
                if (EYesNo.PROHIBIT.getIntValue() == cuMemberSettlePeriod.getIsPublish()) {
                    return;
                }
                publishBonus(cuMemberSettlePeriod);
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void grantWithdrawBonusByPeriodEveryDay() {
        Map<Integer, BdCountry> integerBdCountryMap = countryServiceApi.getAllCountryMap().getData();
        if(integerBdCountryMap.size() > 0) {
            for (Integer pkCountry : integerBdCountryMap.keySet()) {
                // 先发放奖金，验证是否是周结，周结发放上周的，直接变为可提现
                Date grantDay = DateUtils.beforeDate(7, ChronoUnit.DAYS, DateUtils.currentDate());
                String settleDate = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, grantDay);
                grantBonusByPeriod(pkCountry, settleDate);
                // 周奖发放上周的奖金
                CuMemberSettlePeriodExt cuMemberSettlePeriod = getCuMemberSettlePeriod(pkCountry, settleDate);
                Date withdrawDay = DateUtils.beforeDate(7, ChronoUnit.DAYS, grantDay);
                if (EExpandCapMethod.WEEK_SETTLE.getValue() == cuMemberSettlePeriod.getSettleCycle() ||
                        CountryConstants.CHINA_COUNTRY != pkCountry) {
                    withdrawDay = grantDay;
                }
                withdrawalBonusByPeriod(pkCountry, DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, withdrawDay));
                // 设置奖金可以提现
            }
        }
        // 2024-07-24 海外新增发放 复销积分奖金，每天发放7天前
        // 查询要发放的复销积分奖金
        Date grantDay = DateUtils.beforeDate(7, ChronoUnit.DAYS);
        String settleDate = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, grantDay);
        Date currentDateTime = DateUtils.currentDateTime();
        List<CuMemberTradeRecoil> cuMemberTradeRecoilList = cuMemberTradeRecoilServiceApi.queryCuMemberTradeRecoil(grantDay).getData();
        if(cuMemberTradeRecoilList != null && cuMemberTradeRecoilList.size() > 0){
            // 封装交易明细
            List<CuMemberTrade> cuMemberTradeList = new ArrayList<>();
            for (CuMemberTradeRecoil cuMemberTradeRecoil : cuMemberTradeRecoilList) {
                if(ComputeUtil.compareValue(cuMemberTradeRecoil.getTradeAmount())) {
                    CuMemberTrade cuMemberTrade = CuMemberTrade.builder().tradeCode(memberToolsHandler.createTradeCode(EOrderPrefix.TRADE_CODE.getValue()))
                            .tradeClassify(ETradeClassify.INCOME.getValue())
                            .pkMember(cuMemberTradeRecoil.getPkMember())
                            .pkAccount(cuMemberTradeRecoil.getPkAccount())
                            .pkRate(cuMemberTradeRecoil.getPkRate())
                            .tradeAmount(cuMemberTradeRecoil.getTradeAmount())
                            .sourceCode("")
                            .tradeStatue(ETradeStatus.TAKE_EFFECT.getValue())
                            .build();
                    cuMemberTrade.setRemarks(settleDate + " " + ETradeType.RECOIL_INCOME_GRANT.getKey());
                    cuMemberTrade.setTradeType(ETradeType.RECOIL_INCOME_GRANT.getValue());
                    cuMemberTrade.setPkCountry(cuMemberTradeRecoil.getPkCountry());
                    cuMemberTrade.setPkCreator(MagicNumberConstants.PK_ADMIN);
                    cuMemberTrade.setCreationTime(currentDateTime);
                    cuMemberTradeList.add(cuMemberTrade);
                }
            }
            List<Long> seqList = cuMemberTradeService.batchQueryCuMemberTradeSeq(cuMemberTradeList.size());
            for (int i = 0; i < cuMemberTradeList.size(); i++) {
                CuMemberTrade cuMemberTrade = cuMemberTradeList.get(i);
                cuMemberTrade.setPkId(seqList.get(i));
            }
            if(cuMemberTradeList.size() >0){
                // 批量保存交易流水，交易流水明细
                cuMemberTradeService.batchInsertCuMemberTrade(cuMemberTradeList);
                // 更新账户
                cuMemberAccountService.updateMemberAccountByDate(grantDay);
            }
            if(!cuMemberTradeRecoilServiceApi.updateCuMemberTradeRecoil(grantDay).isSuccess()){
                throw new RuntimeException("更新消费积分账户失败！");
            }
        }
    }

    /*
     * @description: 公布奖金
     * @author: sui q
     * @date: 2023/4/24 14:19
     * @param: null null
     **/
    private void publishBonus(CuMemberSettlePeriodExt cuMemberSettlePeriod) {
        if(EYesNo.YES.getIntValue() == cuMemberSettlePeriod.getIsPublish()){
            return;
        }
        // 更新奖金状态
        cuMemberBonusService.updateCuMemberBonusStatus(null, EGrantStatus.PUBLISHED.getValue(), EGrantStatus.SETTLED.getValue(),
                cuMemberSettlePeriod.getPkId(), cuMemberSettlePeriod.getPkId());
        // 更新期间表状态
        cuMemberSettlePeriod.setIsPublish(EYesNo.YES.getIntValue());
        cuMemberSettlePeriod.setPublishDate(DateUtils.currentDateTime());
        cuMemberSettlePeriodService.updateCuMemberSettlePeriodByDate(cuMemberSettlePeriod);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void publishBonusByPeriod(Integer pkCountry, String settleDate) {
        CuMemberSettlePeriodExt cuMemberSettlePeriod = getCuMemberSettlePeriod(pkCountry, settleDate);
        publishBonus(cuMemberSettlePeriod);
    }

    @Override
    public void noPublishBonusByPeriod(Integer pkCountry, String settleDate) {
        CuMemberSettlePeriodExt cuMemberSettlePeriod = getCuMemberSettlePeriod(pkCountry, settleDate);
        if(EYesNo.YES.getIntValue() == cuMemberSettlePeriod.getIsPublish()){
            return;
        }
        // 更新期间表状态
        cuMemberSettlePeriod.setIsPublish(EYesNo.PROHIBIT.getIntValue());
        cuMemberSettlePeriod.setPublishDate(DateUtils.currentDateTime());
        cuMemberSettlePeriodService.updateCuMemberSettlePeriodByDate(cuMemberSettlePeriod);
    }

    private CuMemberSettlePeriodExt getCuMemberSettlePeriod(Integer pkCountry, String settleDate) {
        CuMemberSettlePeriodExt cuMemberSettlePeriodByDate = cuMemberSettlePeriodService.getCuMemberSettlePeriod(pkCountry, DateUtils.parseStringToDate(settleDate));
        if(cuMemberSettlePeriodByDate == null){
            CuMemberSettlePeriodDetail cuMemberSettlePeriodDetail = new CuMemberSettlePeriodDetail();
            String value = systemConfigServiceApi.getBonusSystemConfig(pkCountry, ESystemConfig.EXPAND_CAP_METHOD.getKey()).getData();
            // 周结
            if (StringUtils.isNotEmpty(value) && Objects.equals(Integer.toString(EExpandCapMethod.WEEK_SETTLE.getValue()), value)) {
                Integer startPeriod = cuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(DateUtils.getRecentlyTuesday(settleDate)).getPkId();
                Integer endPeriod = cuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(
                        DateUtils.getRecentlyMonday(DateUtils.parseStringToDate(settleDate))).getPkId();
                cuMemberSettlePeriodDetail.setSettleCycle(EExpandCapMethod.WEEK_SETTLE.getValue());
                cuMemberSettlePeriodDetail.setStartPeriod(startPeriod);
                cuMemberSettlePeriodDetail.setEndPeriod(endPeriod);
            } else {
                CuMemberSettlePeriod cuMemberSettlePeriod = cuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(settleDate);
                cuMemberSettlePeriodDetail.setSettleCycle(EExpandCapMethod.DAY_SETTLE.getValue());
                cuMemberSettlePeriodDetail.setStartPeriod(cuMemberSettlePeriod.getPkId());
                cuMemberSettlePeriodDetail.setEndPeriod(cuMemberSettlePeriod.getPkId());
            }
            cuMemberSettlePeriodDetail.setIsSettle(EYesNo.YES.getIntValue());
            cuMemberSettlePeriodDetail.setIsPublish(EYesNo.YES.getIntValue());
            cuMemberSettlePeriodDetail.setIsGrant(EYesNo.YES.getIntValue());
            cuMemberSettlePeriodDetail.setIsWithdrawal(EYesNo.YES.getIntValue());
            cuMemberSettlePeriodDetail.setPkCountry(pkCountry);
            cuMemberSettlePeriodDetail.setPkCreator(MagicNumberConstants.PK_ADMIN);
            cuMemberSettlePeriodDetailService.save(cuMemberSettlePeriodDetail);
            cuMemberSettlePeriodByDate = cuMemberSettlePeriodService.getCuMemberSettlePeriod(pkCountry, DateUtils.parseStringToDate(settleDate));
        }
        cuMemberSettlePeriodByDate.setPkModified(MagicNumberConstants.PK_ADMIN);
        cuMemberSettlePeriodByDate.setModifiedTime(DateUtils.currentDateTime());
        return cuMemberSettlePeriodByDate;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean grantBonusByPeriod(Integer pkCountry, String settleDate) {
        // 奖金发放
        CuMemberSettlePeriodExt cuMemberSettlePeriod = getCuMemberSettlePeriod(pkCountry, settleDate);
        if(EYesNo.YES.getIntValue() == cuMemberSettlePeriod.getIsGrant()){
            return Boolean.FALSE;
        }
        // 验证是否周奖，周奖只能周三发放
        if(EExpandCapMethod.WEEK_SETTLE.getValue() == cuMemberSettlePeriod.getSettleCycle()){
            if(DateUtils.getRecentlyDay(DateUtils.parseStringToDate(settleDate)) != DayOfWeek.WEDNESDAY.getValue()){
                return Boolean.FALSE;
            }
        }else{
            Date startDate = DateUtils.parseStringToDate(settleDate);
            if (DateUtils.compareDateBefore(DateUtils.beforeDate(7, ChronoUnit.DAYS, DateUtils.currentDate()), startDate)) {
                return Boolean.FALSE;
            }
        }
        Map<Integer, BdAccount> bdAccountValueMap = accountServiceApi.getAccountMapByCountry(pkCountry).getData();
        Date currentDateTime = DateUtils.currentDateTime();
        // 查询奖金表，查询未发放的奖金明细
        List<CuMemberBonus> cuMemberBonusList = cuMemberBonusService.queryCuMemberBonusByCondition(pkCountry, EGrantStatus.PUBLISHED.getValue(), cuMemberSettlePeriod.getStartPeriod(), cuMemberSettlePeriod.getEndPeriod());
        if (cuMemberBonusList.size() > 0) {
            // 新增交易流水
            List<CuMemberTrade> cuMemberTradeList = new ArrayList<>();
            cuMemberBonusList.forEach(cuMemberBonus -> {
                CurrencyDTO currencyDTO = currencyServiceApi.getCurrency(cuMemberBonus.getPkCountry()).getData();
                // 奖金币（首购+复购+云代+海粉+嗨粉+创客空间+店铺）
                packAccountTrade(cuMemberTradeList, bdAccountValueMap, EAccount.BONUS.getValue(), currentDateTime, cuMemberBonus, ComputeUtil.computeMultiply(cuMemberBonus.getPurRealSubtotal(), currencyDTO.getOutExchangeRate()), settleDate);
                // 重销币（商城重消+平台服务费）
                BigDecimal repeat = ComputeUtil.computeAdd(cuMemberBonus.getBackPoints(), cuMemberBonus.getRepurRealSubtotal());
                packAccountTrade(cuMemberTradeList, bdAccountValueMap, EAccount.RECOIL.getValue(), currentDateTime, cuMemberBonus, ComputeUtil.computeMultiply(repeat, currencyDTO.getOutExchangeRate()), settleDate);
                // 复购券
//                packAccountTrade(cuMemberTradeList, bdAccountValueMap, EAccount.REPURCHASE.getValue(), currentDateTime, cuMemberBonus, ComputeUtil.computeMultiply(cuMemberBonus.getRepurCouponSubtotal(), currencyDTO.getOutExchangeRate()), settleDate);
                // 环球积分
//                packAccountTrade(cuMemberTradeList, bdAccountValueMap, EAccount.GLOBAL_POINTS.getValue(), currentDateTime, cuMemberBonus, ComputeUtil.computeMultiply(cuMemberBonus.getGlobalPoints(), currencyDTO.getOutExchangeRate()), settleDate);
                // 车奖积分
//                packAccountTrade(cuMemberTradeList, bdAccountValueMap, EAccount.CAR_AWARD_POINTS.getValue(), currentDateTime, cuMemberBonus, ComputeUtil.computeMultiply(cuMemberBonus.getCarAwardPoints(), currencyDTO.getOutExchangeRate()), settleDate);
            });
            List<Long> seqList = cuMemberTradeService.batchQueryCuMemberTradeSeq(cuMemberTradeList.size());
            // 新增流水明细,记录奖金明细的发放状态、消费明细
            List<CuMemberTradeDetail> cuMemberTradeDetailList = new ArrayList<>();
            Map<Integer, BdAccount> bdAccountMap = accountServiceApi.getAccountListByCountry(pkCountry).getData();
            for (int i = 0; i < cuMemberTradeList.size(); i++) {
                CuMemberTrade cuMemberTrade = cuMemberTradeList.get(i);
                cuMemberTrade.setPkId(seqList.get(i));
                if(bdAccountMap.containsKey(cuMemberTrade.getPkAccount()) && EAccount.BONUS.getValue() == bdAccountMap.get(cuMemberTrade.getPkAccount()).getFieldValue()) {
                    // 验证有奖金币的记录发放记录
                    CuMemberTradeDetail cuMemberTradeDetail = CuMemberTradeDetail.builder()
                            .period(cuMemberSettlePeriod.getPkId())
                            .pkMemberTrade(cuMemberTrade.getPkId())
                            .grantMoney(cuMemberTrade.getTradeAmount())
                            .consumeMoney(cuMemberTrade.getTradeAmount())
                            .build();
                    cuMemberTradeDetail.setPkCountry(cuMemberTrade.getPkCountry());
                    cuMemberTradeDetail.setPkCreator(cuMemberTrade.getPkCreator());
                    cuMemberTradeDetail.setCreationTime(cuMemberTrade.getCreationTime());
                    cuMemberTradeDetailList.add(cuMemberTradeDetail);
                }
            }
            // 批量保存交易流水，交易流水明细
            cuMemberTradeService.batchInsertCuMemberTrade(cuMemberTradeList);
            cuMemberTradeDetailService.batchInsertCuMemberTradeDetail(cuMemberTradeDetailList);
            // 批量更新会员账户，更新余额
            cuMemberAccountService.updateMemberAccountGrantByPeriod(pkCountry, cuMemberSettlePeriod.getStartPeriod(), cuMemberSettlePeriod.getEndPeriod());
            // 更新奖金表发放状态
            cuMemberBonusService.updateCuMemberBonusStatus(pkCountry, EGrantStatus.GRANT.getValue(), EGrantStatus.PUBLISHED.getValue(),
                    cuMemberSettlePeriod.getStartPeriod(), cuMemberSettlePeriod.getEndPeriod());
        }
        // 更新期间表状态
        cuMemberSettlePeriod.setIsGrant(EYesNo.YES.getIntValue());
        cuMemberSettlePeriod.setGrantDate(DateUtils.currentDateTime());
        cuMemberSettlePeriodService.updateCuMemberSettlePeriodByDate(cuMemberSettlePeriod);
        return Boolean.TRUE;
    }

    @Override
    public void grantBonusByTempPeriod(Integer pkCountry, String settleDate) {
        // 奖金发放
        CuMemberSettlePeriodExt cuMemberSettlePeriod = getCuMemberSettlePeriod(pkCountry, settleDate);
        // 查询奖金表，查询未发放的奖金明细
        List<CuMemberBonus> cuMemberBonusList = cuMemberBonusService.queryCuMemberBonusByCondition(pkCountry, EGrantStatus.PUBLISHED.getValue(), cuMemberSettlePeriod.getStartPeriod(), cuMemberSettlePeriod.getEndPeriod());
        Map<Integer, BdAccount> bdAccountValueMap = accountServiceApi.getAccountMapByCountry(pkCountry).getData();
        Date currentDateTime = DateUtils.currentDateTime();
        if (cuMemberBonusList.size() > 0) {
            // 新增交易流水
            List<CuMemberTrade> cuMemberTradeList = new ArrayList<>();
            cuMemberBonusList.forEach(cuMemberBonus -> {
                CurrencyDTO currencyDTO = currencyServiceApi.getCurrency(cuMemberBonus.getPkCountry()).getData();
                // 奖金币（首购+复购+云代+海粉+嗨粉+创客空间+店铺）
                packAccountTrade(cuMemberTradeList, bdAccountValueMap, EAccount.BONUS.getValue(), currentDateTime, cuMemberBonus, ComputeUtil.computeMultiply(cuMemberBonus.getRealIncomeTotal(), currencyDTO.getOutExchangeRate()), settleDate);
                // 重销币（商城重消+平台服务费）
//                BigDecimal repeat = ComputeUtil.computeAdd(cuMemberBonus.getBackPoints(), cuMemberBonus.getServiceSpend());
//                packAccountTrade(cuMemberTradeList, bdAccountValueMap, EAccount.REPEAT.getValue(), currentDateTime, cuMemberBonus, ComputeUtil.computeMultiply(cuMemberBonus.getBackPoints(), currencyDTO.getOutExchangeRate()), settleDate);
                // 复购券
//                packAccountTrade(cuMemberTradeList, bdAccountValueMap, EAccount.REPURCHASE.getValue(), currentDateTime, cuMemberBonus, ComputeUtil.computeMultiply(cuMemberBonus.getRepurCouponSubtotal(), currencyDTO.getOutExchangeRate()), settleDate);
                // 环球积分
//                packAccountTrade(cuMemberTradeList, bdAccountValueMap, EAccount.GLOBAL_POINTS.getValue(), currentDateTime, cuMemberBonus, ComputeUtil.computeMultiply(cuMemberBonus.getGlobalPoints(), currencyDTO.getOutExchangeRate()), settleDate);
                // 车奖积分
//                packAccountTrade(cuMemberTradeList, bdAccountValueMap, EAccount.CAR_AWARD_POINTS.getValue(), currentDateTime, cuMemberBonus, ComputeUtil.computeMultiply(cuMemberBonus.getCarAwardPoints(), currencyDTO.getOutExchangeRate()), settleDate);
            });
            List<Long> seqList = cuMemberTradeService.batchQueryCuMemberTradeSeq(cuMemberTradeList.size());
            // 新增流水明细,记录奖金明细的发放状态、消费明细
            List<CuMemberTradeDetail> cuMemberTradeDetailList = new ArrayList<>();
            Map<Integer, BdAccount> bdAccountMap = accountServiceApi.getAccountListByCountry(pkCountry).getData();
            for (int i = 0; i < cuMemberTradeList.size(); i++) {
                CuMemberTrade cuMemberTrade = cuMemberTradeList.get(i);
                cuMemberTrade.setPkId(seqList.get(i));
                if(bdAccountMap.containsKey(cuMemberTrade.getPkAccount()) && EAccount.BONUS.getValue() == bdAccountMap.get(cuMemberTrade.getPkAccount()).getFieldValue()) {
                    // 验证有奖金币的记录发放记录
                    CuMemberTradeDetail cuMemberTradeDetail = CuMemberTradeDetail.builder()
                            .period(cuMemberSettlePeriod.getPkId())
                            .pkMemberTrade(cuMemberTrade.getPkId())
                            .grantMoney(cuMemberTrade.getTradeAmount())
                            .consumeMoney(cuMemberTrade.getTradeAmount())
                            .build();
                    cuMemberTradeDetail.setPkCountry(cuMemberTrade.getPkCountry());
                    cuMemberTradeDetail.setPkCreator(cuMemberTrade.getPkCreator());
                    cuMemberTradeDetail.setCreationTime(cuMemberTrade.getCreationTime());
                    cuMemberTradeDetailList.add(cuMemberTradeDetail);
                }
            }
            // 批量保存交易流水，交易流水明细
            cuMemberTradeService.batchInsertCuMemberTrade(cuMemberTradeList);
            cuMemberTradeDetailService.batchInsertCuMemberTradeDetail(cuMemberTradeDetailList);
            // 批量更新会员账户，更新余额
            cuMemberAccountService.updateMemberAccountGrantByPeriod(pkCountry, cuMemberSettlePeriod.getStartPeriod(), cuMemberSettlePeriod.getEndPeriod());
            // 更新奖金表发放状态
            cuMemberBonusService.updateCuMemberBonusStatus(pkCountry, EGrantStatus.GRANT.getValue(), EGrantStatus.PUBLISHED.getValue(),
                    cuMemberSettlePeriod.getStartPeriod(), cuMemberSettlePeriod.getEndPeriod());
        }
    }

    private void packAccountTrade(List<CuMemberTrade> cuMemberTradeList, Map<Integer, BdAccount> bdAccountMap, int accountValue, Date currentDateTime, CuMemberBonus cuMemberBonus, BigDecimal grantValue,
                                  String settleDate) {
        if(ComputeUtil.compareValue(grantValue) && bdAccountMap.containsKey(accountValue)){
            cuMemberTradeList.add(packageMemberTrade(cuMemberBonus, bdAccountMap.get(accountValue).getPkId(), grantValue, currentDateTime, settleDate));
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void withdrawalBonusByPeriod(Integer pkCountry, String settleDate) {
        // 奖金可提现
        CuMemberSettlePeriodExt cuMemberSettlePeriod = getCuMemberSettlePeriod(pkCountry, settleDate);
        if(EYesNo.YES.getIntValue() == cuMemberSettlePeriod.getIsWithdrawal()){
            return;
        }
        // 验证是否周奖，周奖只能周三提现
        if(EExpandCapMethod.WEEK_SETTLE.getValue() == cuMemberSettlePeriod.getSettleCycle()){
            if(DateUtils.getRecentlyDay(DateUtils.parseStringToDate(settleDate)) != DayOfWeek.WEDNESDAY.getValue()){
                return;
            }
        }else{
            Date startDate = DateUtils.parseStringToDate(settleDate);
            if (DateUtils.compareDateBefore(DateUtils.beforeDate(7, ChronoUnit.DAYS, DateUtils.currentDate()), startDate)) {
                return;
            }
        }
        // 批量更新会员账户，更新余额
        cuMemberAccountService.updateMemberAccountWithdrawalByPeriod(cuMemberSettlePeriod.getStartPeriod(), cuMemberSettlePeriod.getEndPeriod(), pkCountry);
        // 更新交易明细表状态 cu_member_trade_detail
        cuMemberTradeDetailService.updateCuMemberTradeDetailByPeriod(cuMemberSettlePeriod.getStartPeriod(), cuMemberSettlePeriod.getEndPeriod(), pkCountry);
        // 更新奖金表发放状态
        cuMemberBonusService.updateCuMemberBonusStatus(pkCountry, EGrantStatus.WITHDRAWAL.getValue(), EGrantStatus.GRANT.getValue(), cuMemberSettlePeriod.getStartPeriod(), cuMemberSettlePeriod.getEndPeriod());
        // 更新期间表状态
        cuMemberSettlePeriod.setIsWithdrawal(EYesNo.YES.getIntValue());
        cuMemberSettlePeriod.setWithdrawalDate(DateUtils.currentDateTime());
        cuMemberSettlePeriodService.updateCuMemberSettlePeriodByDate(cuMemberSettlePeriod);
    }

    /**
     * 封装会员 消费的 交易流水
     *
     * @param cuMemberBonus 订单主表
     * @param pkAccount     账户类型
     * @param tradeMoney    交易金额
     * @return CuMemberTrade
     */
    private CuMemberTrade packageMemberTrade(CuMemberBonus cuMemberBonus, Integer pkAccount, BigDecimal tradeMoney, Date currentDateTime, String settleDate) {
        CuMemberTrade cuMemberTrade = CuMemberTrade.builder().tradeCode(memberToolsHandler.createTradeCode(EOrderPrefix.TRADE_CODE.getValue()))
                .tradeClassify(ETradeClassify.INCOME.getValue())
                .pkMember(cuMemberBonus.getPkMember())
                .pkAccount(pkAccount)
                .pkRate(cuMemberBonus.getPkRate())
                .tradeAmount(tradeMoney)
                .sourceCode("")
                .tradeStatue(ETradeStatus.TAKE_EFFECT.getValue())
                .build();
        cuMemberTrade.setRemarks(settleDate + " " + ETradeType.INCOME_GRANT.getKey());
        cuMemberTrade.setTradeType(ETradeType.INCOME_GRANT.getValue());
        cuMemberTrade.setPkCountry(cuMemberBonus.getPkCountry());
        cuMemberTrade.setPkCreator(MagicNumberConstants.PK_ADMIN);
        cuMemberTrade.setCreationTime(currentDateTime);
        return cuMemberTrade;
    }
}
