package com.hzs.sale.order.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hzs.activity.dto.AcPeopleGiftProductDTO;
import com.hzs.activity.people.IAcPeopleServiceServiceApi;
import com.hzs.common.core.constant.*;
import com.hzs.common.core.constant.msg.ConfigMsgConstants;
import com.hzs.common.core.constant.msg.MemberMsgConstants;
import com.hzs.common.core.constant.msg.SaOrderMsgConstants;
import com.hzs.common.core.domain.R;
import com.hzs.common.core.enums.*;
import com.hzs.common.core.exception.ServiceException;
import com.hzs.common.core.service.RedisService;
import com.hzs.common.core.utils.*;
import com.hzs.common.core.utils.reflect.ReflectUtils;
import com.hzs.common.domain.member.account.CuMemberAccount;
import com.hzs.common.domain.member.base.CuMember;
import com.hzs.common.domain.member.base.CuMemberRegister;
import com.hzs.common.domain.member.base.CuMemberUpgrade;
import com.hzs.common.domain.member.business.UpPolicyCurrency;
import com.hzs.common.domain.member.detail.CuMemberLevel;
import com.hzs.common.domain.member.detail.CuMemberServiceLog;
import com.hzs.common.domain.member.detail.ext.CuMemberAwardsExt;
import com.hzs.common.domain.member.ext.CuMemberAccountExt;
import com.hzs.common.domain.member.ext.CuMemberExt;
import com.hzs.common.domain.sale.ext.*;
import com.hzs.common.domain.sale.order.*;
import com.hzs.common.domain.sale.product.BdProductExtend;
import com.hzs.common.domain.sale.wares.BdWares;
import com.hzs.common.domain.system.base.BdCountry;
import com.hzs.common.domain.system.config.BdAwards;
import com.hzs.common.security.service.UserTokenService;
import com.hzs.common.security.utils.SecurityUtils;
import com.hzs.common.core.utils.TransactionUtils;
import com.hzs.member.account.IMemberAccountServiceApi;
import com.hzs.member.account.IMemberBankServiceApi;
import com.hzs.member.account.IMemberTradeServiceApi;
import com.hzs.member.account.dto.BusinessCommissionDTO;
import com.hzs.member.account.dto.CuMemberBankParam;
import com.hzs.member.account.dto.MemberAmountDTO;
import com.hzs.member.achieve.IMemberAchieveServiceApi;
import com.hzs.member.base.IMemberServiceApi;
import com.hzs.member.detail.ICuMemberDetailServiceApi;
import com.hzs.member.detail.ICuMemberServiceLogServiceApi;
import com.hzs.sale.deliver.param.DeliverSecondParam;
import com.hzs.sale.deliver.service.ISaDeliverItemsService;
import com.hzs.sale.deliver.vo.DeliverSecondVO;
import com.hzs.sale.index.vo.CuMemberMyMarketDetailVO;
import com.hzs.sale.index.vo.CuMemberMyMarketVO;
import com.hzs.sale.order.dto.OrderQueryChargeDTO;
import com.hzs.sale.order.mapper.SaOrderMapper;
import com.hzs.sale.order.param.*;
import com.hzs.sale.order.service.*;
import com.hzs.sale.order.vo.*;
import com.hzs.sale.product.service.IBdProductExtendService;
import com.hzs.sale.wares.service.IBdWaresExtendService;
import com.hzs.sale.wares.service.IBdWaresService;
import com.hzs.sale.wares.service.IBdWaresSpecsRelationService;
import com.hzs.system.base.ICountryServiceApi;
import com.hzs.system.base.ICurrencyServiceApi;
import com.hzs.system.base.ISystemConfigServiceApi;
import com.hzs.system.base.dto.CountryDTO;
import com.hzs.system.base.dto.CurrencyDTO;
import com.hzs.system.config.IAreaCurrencyServiceApi;
import com.hzs.system.config.IAwardsServiceApi;
import com.hzs.system.config.IGradeServiceApi;
import com.hzs.system.config.dto.AreaCurrencyDTO;
import com.hzs.system.config.dto.GradeDTO;
import com.hzs.system.sys.IApprovalServiceApi;
import com.hzs.system.sys.dto.ApprovalBusinessResultDTO;
import com.hzs.system.sys.dto.ApprovalSubmitDTO;
import com.hzs.system.sys.dto.LoginUser;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 订单的逻辑类
 */
@Service
@Slf4j
public class SaOrderServiceImpl extends ServiceImpl<SaOrderMapper, SaOrder> implements ISaOrderService {

    @DubboReference
    IMemberServiceApi memberServiceApi;
    @DubboReference
    IGradeServiceApi gradeServiceApi;
    @DubboReference
    IAwardsServiceApi awardsServiceApi;
    @DubboReference
    IMemberBankServiceApi memberBankServiceApi;
    @DubboReference
    IMemberAccountServiceApi memberAccountServiceApi;
    @DubboReference
    IAreaCurrencyServiceApi areaCurrencyServiceApi;
    @DubboReference
    ICountryServiceApi countryServiceApi;
    @DubboReference
    ICurrencyServiceApi currencyServiceApi;
    @DubboReference
    IApprovalServiceApi approvalServiceApi;
    @DubboReference
    IMemberAchieveServiceApi memberAchieveServiceApi;
    @DubboReference
    ISystemConfigServiceApi systemConfigServiceApi;
    @DubboReference
    ICuMemberServiceLogServiceApi cuMemberServiceLogServiceApi;
    @DubboReference
    IAcPeopleServiceServiceApi peopleServiceServiceApi;
    @DubboReference
    IMemberTradeServiceApi memberTradeServiceApi;
    @DubboReference
    ICuMemberDetailServiceApi iCuMemberDetailServiceApi;

    @Autowired
    private IBdWaresService waresService;
    @Autowired
    private IBdWaresExtendService waresExtendService;
    @Autowired
    private SaOrderHandle saOrderHandle;
    @Autowired
    private ISaOrderItemsService saOrderItemsService;
    @Autowired
    private UserTokenService userTokenService;
    @Autowired
    private IBdProductExtendService productExtendService;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private IBdWaresSpecsRelationService waresSpecsRelationService;
    @Autowired
    private ISaDeliverItemsService saDeliverItemsService;
    @Autowired
    private IOrderBusinessService orderBusinessService;
    @Autowired
    private ISaStoreBonusService storeBonusService;

    @Autowired
    private RedisService redisService;

    @Override
    public List<CuMemberExt> queryMemberExtByCondition(CuMember cuMember) {
        return memberServiceApi.getMemberInfo(cuMember).getData();
    }

    @Override
    public List<CuMemberExt> querySponsorOnUmbrella(Long placeParentId, String phone) {
        return memberServiceApi.querySponsorOnUmbrella(placeParentId, null, phone).getData();
    }

    @Override
    public List<CuMemberExt> selectPlaceSponsorUnderUmbrellaByCondition(Long memberId, List<CuMemberExt> cuMemberExtList) {
        return memberServiceApi.selectPlaceSponsorUnderUmbrellaByCondition(memberId, cuMemberExtList).getData();
    }

    @Override
    public List<CuMemberExt> queryPlaceSponsorUnderUmbrella(Long memberId, String placeParent) {
        return memberServiceApi.queryPlaceSponsorUnderUmbrella(memberId, placeParent).getData();
    }

    @Override
    public CuMemberExt queryPlaceSponsorLastLeft(Long memberId, Integer placeDept) {
        return memberServiceApi.queryPlaceSponsorLastLeft(memberId, placeDept).getData();
    }

    @Override
    public SaOrder querySaleOrderByOrderCode(SaOrder saOrder) {
        LambdaQueryWrapper<SaOrder> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SaOrder::getOrderStatus, saOrder.getOrderStatus());
        queryWrapper.eq(SaOrder::getOrderCode, saOrder.getOrderCode());
        if (saOrder.getPkCountry() != null) {
            queryWrapper.eq(SaOrder::getPkCountry, saOrder.getPkCountry());
        }
        if (saOrder.getOrderType() != null) {
            queryWrapper.eq(SaOrder::getOrderType, saOrder.getOrderType());
        }
        return baseMapper.selectOne(queryWrapper);
    }

    @Override
    public SaOrderExt querySaleOrderExtByOrderCode(SaOrder saOrder, List<Long> itemIdList) {
        SaOrder order = querySaleOrderByOrderCode(saOrder);
        if (order == null) {
            return null;
        }
        SaOrderExt saOrderExt = BeanUtil.copyProperties(order, SaOrderExt.class);
        LambdaQueryWrapper<SaOrderItems> orderItemsQueryWrapper = new LambdaQueryWrapper<>();
        orderItemsQueryWrapper.eq(SaOrderItems::getPkOrder, saOrderExt.getPkId());
        if (CollectionUtil.isNotEmpty(itemIdList)) {
            orderItemsQueryWrapper.in(SaOrderItems::getPkId, itemIdList);
        }
        saOrderExt.setOrderItemsList(saOrderItemsService.list(orderItemsQueryWrapper));
        return saOrderExt;
    }

    @Override
    public List<SaOrder> querySaleOrderByPkMember(Integer pkCountry, Long pkMember, Long pkReference, Integer orderType) {
        LambdaQueryWrapper<SaOrder> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SaOrder::getOrderStatus, EOrderStatus.PAY.getValue());
        queryWrapper.eq(SaOrder::getPkCountry, pkCountry);
        if (pkMember != null) {
            queryWrapper.eq(SaOrder::getPkMember, pkMember);
        } else if (pkReference != null) {
            queryWrapper.eq(SaOrder::getPkReference, pkReference);
        }
        queryWrapper.orderByDesc(SaOrder::getPayTime);
        return baseMapper.selectList(queryWrapper);
    }

    @Override
    public Integer querySaleOrderByPkMember(Integer pkCountry, Long pkMember, Long pkReference) {
        LambdaQueryWrapper<SaOrder> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SaOrder::getOrderStatus, EOrderStatus.PAY.getValue());
        queryWrapper.eq(SaOrder::getPkCountry, pkCountry);
        if (pkMember != null) {
            queryWrapper.eq(SaOrder::getPkMember, pkMember);
        } else if (pkReference != null) {
            queryWrapper.eq(SaOrder::getPkReference, pkReference);
        }
        return baseMapper.selectCount(queryWrapper);
    }

    @Override
    public Integer queryCuMemberByPkMember(Long pkReference) {
        return memberServiceApi.queryCuMemberByPkMember(pkReference).getData();
    }

    @Override
    public List<SaOrderVO> querySaleOrderByCondition(OrderQueryParam orderQueryParam) {
        if (orderQueryParam.getEndTime() != null) {
            orderQueryParam.setEndTime(DateUtils.afterDate(1, ChronoUnit.DAYS, orderQueryParam.getEndTime()));
        }
        List<SaOrderVO> saOrderVOList = baseMapper.querySaOrderByCondition(orderQueryParam);
        saOrderVOList.forEach(saOrder -> saOrderHandle.transformSaOrderToVO(saOrder));
        return saOrderVOList;
    }

    @Override
    public CuMember getCuMemberByKey(Long pkId) {
        return memberServiceApi.getMember(pkId).getData();
    }

    @Override
    public CuMember getCuMemberByCode(String code) {
        return memberServiceApi.getMember(code).getData();
    }

    @Override
    public Boolean lockKey(String key) {
        return redisService.lockKeyOnce(key);
    }

    @Override
    public List<CuMemberAccountExt> queryMemberAccountByCondition(CuMemberAccount cuMemberAccount) {
        return memberAccountServiceApi.queryMemberAccountByCondition(cuMemberAccount).getData();
    }

    @Override
    public CuMemberAccountExt queryOrderSpendDetails(CuMemberAccountExt cuMemberAccount, SaOrder saOrder, List<SaOrderItems> orderItemList) {
        BigDecimal payMoney = saOrder.getOrderAmount();
        // 验证是否是跨国保单，登录结算国！=结算国，跨国报单修改支付金额
        if (!Objects.equals(cuMemberAccount.getPkCountry(), saOrder.getPkCountry())) {
            // 结算国当地币 转美金  美金登录当地币
            CurrencyDTO loginCountryCurrency = currencyServiceApi.getCurrency(cuMemberAccount.getPkCountry()).getData();
            CurrencyDTO settleCountryCurrency = currencyServiceApi.getCurrency(saOrder.getPkCountry()).getData();
            if (settleCountryCurrency.getInExchangeRate().compareTo(loginCountryCurrency.getInExchangeRate()) != 0) {
                // 订单结算国与登录结算国汇率不相同才进行处理
                payMoney = ComputeUtil.computeMultiply(ComputeUtil.computeDivide(payMoney, settleCountryCurrency.getInExchangeRate()), loginCountryCurrency.getInExchangeRate());
            }
        }
        BigDecimal postage = saOrder.getPostage();
        // 验证商品是否存在特殊消费配置
        if (CollectionUtil.isNotEmpty(orderItemList)) {
            for (SaOrderItems saOrderItems : orderItemList) {
                if (saOrderItems.getPkSpecialCurrency() != null) {
                    BigDecimal orderItemPayMoney = ComputeUtil.computeMultiply(saOrderItems.getPrice(), saOrderItems.getQuantity());
                    payMoney = ComputeUtil.computeSubtract(payMoney, orderItemPayMoney);
                    List<AreaCurrencyDTO> areaCurrencyDtoList = areaCurrencyServiceApi.queryAreaCurrencyByCondition(saOrderItems.getPkSpecialCurrency()).getData();
                    if (!handleSaOrderAmount(cuMemberAccount, orderItemPayMoney, BigDecimal.ZERO, areaCurrencyDtoList)) {
                        return null;
                    }
                }
            }
        }
        // 查询专区所属币种
        List<AreaCurrencyDTO> areaCurrencyDTOList = areaCurrencyServiceApi.queryAreaCurrencyByCondition(saOrder.getOrderType(), cuMemberAccount.getPkCountry()).getData();
        handleSaOrderAmount(cuMemberAccount, payMoney, postage, areaCurrencyDTOList);

        return cuMemberAccount;
    }

    private Boolean handleSaOrderAmount(CuMemberAccountExt cuMemberAccount, BigDecimal payMoney, BigDecimal postage, List<AreaCurrencyDTO> areaCurrencyDTOList) {
        boolean flag = Boolean.TRUE;
        if (!ComputeUtil.compareValue(ComputeUtil.computeAdd(payMoney, postage))) {
            return Boolean.TRUE;
        }
        cuMemberAccount.setIsPayment(Boolean.FALSE);
        BigDecimal original = payMoney;
        for (AreaCurrencyDTO areaCurrencyDTO : areaCurrencyDTOList) {
            // 开始扣款
            // 待支付金额>0进行扣减
            if (ComputeUtil.compareValue(payMoney)) {
                // 获得特殊处理
                // 判断比例是否 > 0, 为强制扣除金额 ，强制扣除金额不满足，直接支付失败
                if (!ComputeUtil.compareValue(areaCurrencyDTO.getDeductRatio())) {
                    payMoney = saOrderHandle.subtract(payMoney, cuMemberAccount, areaCurrencyDTO.getFieldValue());
                } else {
                    // 政策币单独处理 政策币需要根据配置来进行处理
                    if (EAccount.POLICY.getValue() == areaCurrencyDTO.getFieldValue()) {
                        // 2023.12.21 签呈确认，政策币只能用于报单、升级，并且默认全员开通，使用比例优先政策币配置
                        // 验证是否有政策币权限
                        List<CuMemberServiceLog> cuMemberServiceLogs = cuMemberServiceLogServiceApi.queryMaxCuMemberServiceLog(cuMemberAccount.getPkMember(), Collections.singletonList(EApprovalBusiness.POLICY_CURRENCY_YES_NO.getValue()));
                        if (CollectionUtil.isNotEmpty(cuMemberServiceLogs)) {
                            for (CuMemberServiceLog serviceLog : cuMemberServiceLogs) {
                                if (serviceLog.getEditType().equals(EApprovalBusiness.POLICY_CURRENCY_YES_NO.getValue())) {
                                    try {
                                        UpPolicyCurrency upPolicyCurrency = JSONUtil.toBean(serviceLog.getNewValue(), UpPolicyCurrency.class);
                                        if (upPolicyCurrency != null && EYesNo.YES.getIntValue() == upPolicyCurrency.getEnableStatus()) {
                                            areaCurrencyDTO.setDeductRatio(upPolicyCurrency.getDeductMoney() == null ? areaCurrencyDTO.getDeductRatio() : upPolicyCurrency.getDeductMoney());
                                        }
                                    } catch (Exception e) {
                                        log.error("支付政策币转换错误: {}", e.getMessage(), e);
                                    }
                                    break;
                                }
                            }
                        }

                    }
                    BigDecimal minPayMoney = ComputeUtil.computeDivide(original.multiply(areaCurrencyDTO.getDeductRatio()), BigDecimal.valueOf(100));
                    BigDecimal accountValue = saOrderHandle.getAccountByKey(cuMemberAccount, areaCurrencyDTO.getFieldValue());
                    if (EAccount.POLICY.getValue() != areaCurrencyDTO.getFieldValue()) {
                        if (minPayMoney.compareTo(accountValue) > 0) {
                            flag = false;
                            if (cuMemberAccount.getErrorMsg() == null) {
                                cuMemberAccount.setErrorMsg(areaCurrencyDTO.getAccountName() + TransactionUtils.getContent(MemberMsgConstants.MEMBER_ACCOUNT_BALANCE_NOT_ENOUGH));
                            } else {
                                cuMemberAccount.setErrorMsg(cuMemberAccount.getErrorMsg() + areaCurrencyDTO.getAccountName() + TransactionUtils.getContent(MemberMsgConstants.MEMBER_ACCOUNT_BALANCE_NOT_ENOUGH));
                            }
                        }
                    } else {
                        if (minPayMoney.compareTo(accountValue) > 0) {
                            minPayMoney = accountValue;
                        }
                    }
                    BigDecimal originalPayMoney = ReflectUtils.invokeGetter(cuMemberAccount, MemberFieldConstants.PAY_ACCOUNT + areaCurrencyDTO.getFieldValue());
                    if (originalPayMoney == null) {
                        originalPayMoney = BigDecimal.ZERO;
                    }
                    ReflectUtils.invokeSetter(cuMemberAccount, MemberFieldConstants.PAY_ACCOUNT + areaCurrencyDTO.getFieldValue(), ComputeUtil.computeAdd(originalPayMoney, minPayMoney));
                    payMoney = payMoney.subtract(minPayMoney);
                }
                // 奖金币单独处理 消费的时候不需要处理，等实际扣款的时候需要处理，先扣除可提现，在扣除可消费
            }
            // 对邮费进行单独处理 邮费>0 进行扣减
            if (areaCurrencyDTO.getIsPostage() != null && areaCurrencyDTO.getIsPostage() == EYesNo.YES.getIntValue() && postage.compareTo(BigDecimal.ZERO) > 0) {
                postage = saOrderHandle.subtract(postage, cuMemberAccount, areaCurrencyDTO.getFieldValue());
            }
            // 每次扣除后判断是否扣除完毕，扣除完毕结束
            if (flag && payMoney.compareTo(BigDecimal.ZERO) == 0 && postage.compareTo(BigDecimal.ZERO) == 0) {
                cuMemberAccount.setIsPayment(Boolean.TRUE);
                break;
            }
        }
        return flag;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean confirmRegSaOrderByOrderParam(OrderParam orderParam) {
        boolean isToBePay = getIsToBePayByOrderType(orderParam.getPkSettleCountry(), orderParam.getSpecialArea());
        CuMember cuMember = saOrderHandle.packageSaveUser(orderParam, memberServiceApi.queryMember(orderParam.getCenterCodeId()).getData());
        // 获取会员编号、会员主键
        if (isToBePay) {
            cuMember = memberServiceApi.createMemberIdAndCode(cuMember, Boolean.FALSE).getData();
        }
        SaOrderExt saOrderExt = packageWholeSaOrder(orderParam, cuMember);
        if (setLastCuMemberGrade(cuMember, saOrderExt)) {
            return false;
        }

        // 保存 用户、订单、订单明细 分布式事务
        // 启用待支付，或者嗨粉订单
        if (isToBePay && !orderParam.getIsHaiFun()) {
            processOrder(saOrderExt);
            // 调用其他服务保存会员信息、会员注册信息
            if (!memberServiceApi.saveMember(cuMember).getData()) {
                throw new RuntimeException("保存会员失败");
            }
        } else {
            redisService.setCacheObject(CacheConstants.TEMP_ORDER + orderParam.getCenterCodeId() + orderParam.getOrderCode(), saOrderExt, CacheConstants.MEMBER_REFRESH_TIME, TimeUnit.HOURS);
            orderParam.setMemberCode(cuMember.getMemberCode());
            orderParam.setPkGrade(cuMember.getPkSettleGrade());
        }
        redisService.setCacheObject(CacheConstants.TEMP_PARAM + orderParam.getCenterCodeId() + orderParam.getOrderCode(), orderParam, CacheConstants.MEMBER_REFRESH_TIME, TimeUnit.HOURS);
        return true;
    }

    @Override
    public Boolean confirmSelfFunOrderByOrderParam(OrderParam orderParam) {
        CuMember cuMember = getCuMemberByKey(orderParam.getCenterCodeId());
        // 获取会员编号、会员主键
        SaOrderExt saOrderExt = packageWholeSaOrder(orderParam, cuMember);
        if (setLastCuMemberGrade(cuMember, saOrderExt)) {
            return false;
        }
        // 保存 用户、订单、订单明细 分布式事务
        // 启用待支付，或者嗨粉订单
        redisService.setCacheObject(CacheConstants.TEMP_ORDER + orderParam.getCenterCodeId() + orderParam.getOrderCode(), saOrderExt, CacheConstants.MEMBER_REFRESH_TIME, TimeUnit.HOURS);
        orderParam.setMemberCode(cuMember.getMemberCode());
        orderParam.setPkGrade(cuMember.getPkSettleGrade());
        redisService.setCacheObject(CacheConstants.TEMP_PARAM + orderParam.getCenterCodeId() + orderParam.getOrderCode(), orderParam, CacheConstants.MEMBER_REFRESH_TIME, TimeUnit.HOURS);
        return true;
    }

    @Override
    public SaOrderExt packageSaOrder(OrderParam orderParam, CuMember cuMember) {
        SaOrderExt saOrderExt = packageWholeSaOrder(orderParam, cuMember);
        if (setLastCuMemberGrade(cuMember, saOrderExt)) {
            return null;
        }
        return saOrderExt;
    }

    @Override
    public CuMember packageCuMember(OrderParam orderParam) {
        if (null != orderParam.getPkParent()) {
            orderParam.setParentId(orderParam.getPkParent());
        } else {
            if (StringUtils.isNotEmpty(orderParam.getParent())) {
                CuMember parentMember = getCuMemberByCode(orderParam.getParent());
                if (parentMember != null) {
                    orderParam.setParentId(parentMember.getPkId());
                }
            }
        }

        if (StringUtils.isNotEmpty(orderParam.getPlaceParent())) {
            CuMember placeMember = getCuMemberByCode(orderParam.getPlaceParent());
            if (placeMember != null) {
                orderParam.setPlaceParentId(placeMember.getPkId());
            }
        }
        CuMember cuMember = saOrderHandle.packageSaveUser(orderParam, memberServiceApi.queryMember(orderParam.getCenterCodeId()).getData());
        // 获取会员编号、会员主键
        cuMember = memberServiceApi.createMemberIdAndCode(cuMember, Boolean.FALSE).getData();
        return cuMember;
    }

    /**
     * 设置会员最终的等级
     *
     * @param cuMember   会员
     * @param saOrderExt 订单
     * @return boolean
     */
    @Override
    public Boolean setLastCuMemberGrade(CuMember cuMember, SaOrder saOrderExt) {
        OrderReturn orderReturn = OrderReturn.builder().isEnough(false).build();
        GradeDTO gradeDTO = calculateGradeDTO(saOrderExt.getOrderType(), cuMember.getPkSettleCountry(), cuMember.getPkId(), saOrderExt, orderReturn);
        // 第二次封装用户 封装等级
//        GradeDTO gradeDTO = saOrderHandle.getMemberGradeAndAwardByCountry(saOrderExt.getOrderType(), saOrderExt.getOrderAmount(), saOrderExt.getOrderAchieve(),
//                saOrderExt.getPkCountry());
        if (gradeDTO == null) {
            return true;
        }

        // 验证推荐等级，判断什么级别可以推荐什么级别
        //跨国报单不验证推荐等级权限
        if (EOrderType.REGISTER_ORDER.getValue() == saOrderExt.getOrderType()) {
            // 判断推荐范围，验证该推荐人是否有推荐的权限
            CuMember parentCuMember = getCuMemberByKey(cuMember.getPkParent());

            if (parentCuMember.getPkSettleCountry() != null && cuMember.getPkSettleCountry() != null && Objects.equals(parentCuMember.getPkSettleCountry(), cuMember.getPkSettleCountry())) {
                GradeDTO validateGradeDTO = queryGradeConfigByCondition(parentCuMember.getPkSettleCountry(), parentCuMember.getPkSettleGrade());
                // 获取推荐人可以推荐的等级
                if (validateGradeDTO == null || validateGradeDTO.getBdGradeScopeExtList() == null ||
                        validateGradeDTO.getBdGradeScopeExtList().stream().noneMatch(bdGradeScope -> gradeDTO.getPkId().equals(bdGradeScope.getPkScope()))) {
                    return true;
                }
            }
        }

        // 旧等级
        GradeDTO oldGradeDTO = null;
        if (null != cuMember.getPkSettleGrade()) {
            oldGradeDTO = gradeServiceApi.getGrade(cuMember.getPkSettleGrade()).getData();
            if (gradeDTO.getGradeValue() >= oldGradeDTO.getGradeValue()) {
                cuMember.setPkRegisterGrade(gradeDTO.getPkId());
                cuMember.setPkSettleGrade(gradeDTO.getPkId());
            }
            // 记录升级前等级
            saOrderExt.setOrderPkGrade(oldGradeDTO.getPkId());
        } else {
            cuMember.setPkRegisterGrade(gradeDTO.getPkId());
            cuMember.setPkSettleGrade(gradeDTO.getPkId());
            // 记录升级前等级
            saOrderExt.setOrderPkGrade(gradeDTO.getPkId());
        }

        // 校验等级，如果不是会员、铁卡，则第一年给奖金年包
        if (gradeDTO.getGradeValue() >= EGrade.YOU_KE.getValue()) {
            if (null == cuMember.getExpireDate()) {
                // 没有奖金年包，给一年
                cuMember.setExpireDate(DateUtils.addDays(DateUtils.addYears(new Date(), MagicNumberConstants.BOUNS_INIT_YEAR), -1));
            } else {
                if (null != oldGradeDTO) {
                    if (oldGradeDTO.getGradeValue() < EGrade.YOU_KE.getValue()) {
                        // 旧等级小于铜卡
                        if (cuMember.getExpireDate().compareTo(new Date()) >= 0) {
                            // 奖金年包时间比当前时间大，需要继续往上加
                            cuMember.setExpireDate(DateUtils.addYears(cuMember.getExpireDate(), MagicNumberConstants.BOUNS_INIT_YEAR));
                        } else {
                            // 奖金年包时间比当前时间小，从当前时间往上加
                            cuMember.setExpireDate(DateUtils.addDays(DateUtils.addYears(new Date(), MagicNumberConstants.BOUNS_INIT_YEAR), -1));
                        }
                    }
                }
            }
        }
//        // 校验等级，如果不是会员、铁卡，则第一年给奖金年包
//        if (gradeDTO.getGradeValue() >= EGrade.YOU_KE.getValue()) {
//            cuMember.setExpireDate(DateUtils.addDays(DateUtils.addYears(cuMember.getCreationTime() != null ? cuMember.getCreationTime() : new Date(), MagicNumberConstants.BOUNS_INIT_YEAR), -1));
//        }

        // 判断奖衔，原会员有奖衔的话判断哪个大，使用大的
        if (cuMember.getPkAwards() != null && gradeDTO.getGradeValue() != null) {
            BdAwards bdAwards = awardsServiceApi.getAwardsOne(cuMember.getPkAwards()).getData();
            BdAwards newAwards = awardsServiceApi.getAwardsOne(gradeDTO.getPkAwards()).getData();
            if (bdAwards.getAwardsValue() < newAwards.getAwardsValue()) {
                cuMember.setPkAwards(gradeDTO.getPkAwards());
            }
        } else {
            cuMember.setPkAwards(gradeDTO.getPkAwards());
        }
        // 等级对应的结算值
        cuMember.setConsumeMoney(ComputeUtil.computeAdd(cuMember.getConsumeMoney(), saOrderExt.getOrderAmount()));
        cuMember.setConsumeAchieve(gradeDTO.getStartValue());
        if (cuMember.getRegisterAuthority() == null || cuMember.getRegisterAuthority() < gradeDTO.getRegisterAuthority()) {
            cuMember.setRegisterAuthority(gradeDTO.getRegisterAuthority());
        }
        return false;
    }

    /**
     * 保存订单信息
     *
     * @param saOrderExt 订单
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void processOrder(SaOrderExt saOrderExt) {
        // 待支付直接保存订单、会员
        // 保存订单
        save(saOrderExt);
        // 将订单表主键封装为明细表主键
        List<WaresNumberParam> waresNumberParamList = new ArrayList<>();
        saOrderExt.getOrderItemsList().forEach(saOrderItems -> {
            saOrderItems.setPkOrder(saOrderExt.getPkId());
            if (saOrderItems.getPkWares() != null && saOrderItems.getPkWares() != 0) {
                // 换货或者二次发货等，商品为0，则不需要处理
                waresNumberParamList.add(WaresNumberParam.builder().pkWares(saOrderItems.getPkWares()).number(saOrderItems.getWaresQuantity()).build());
            }
        });
        // 更新销量
        // 过滤相同商品主键数据
        List<WaresNumberParam> waresNumberList = waresNumberParamList.stream().filter(DeduplicationUtil.distinctByKey(WaresNumberParam::getPkWares)).collect(Collectors.toList());
        waresSalesAccrual(waresNumberList);
        // 保存订单明细
        saOrderItemsService.saveBatch(saOrderExt.getOrderItemsList());
    }

    @Override
    public boolean getIsToBePayByOrderType(Integer pkCountry, Integer specialArea) {
        String confirmPay;

        // 转区到订单类型的转换
        specialArea = ESpecialArea.getOrderTypeValue(specialArea);
        if (EOrderType.REGISTER_ORDER.getValue() == specialArea) {
            confirmPay = querySystemConfigByKey(pkCountry, ESystemConfig.REGISTER_ORDER_CONFIRM_PAY.getKey());
        } else if (EOrderType.UPGRADE_ORDER.getValue() == specialArea) {
            confirmPay = querySystemConfigByKey(pkCountry, ESystemConfig.UPGRADE_ORDER_CONFIRM_PAY.getKey());
        } else if (EOrderType.REPURCHASE_ORDER.getValue() == specialArea) {
            confirmPay = querySystemConfigByKey(pkCountry, ESystemConfig.REPURCHASE_ORDER_CONFIRM_PAY.getKey());
        } else {
            confirmPay = querySystemConfigByKey(pkCountry, ESystemConfig.REPURCHASE_ORDER_CONFIRM_PAY.getKey());
        }
        boolean isToBePay = false;
        // 启用待支付
        if (EYesNo.YES.getIntValue() == Integer.parseInt(confirmPay)) {
            log.info("增加待支付");
            isToBePay = true;
        }
        return isToBePay;
    }

    @Override
    public Long getIsToBePayTime(Integer pkCountry, Integer specialArea) {
        String timeType;
        long timeSecond = 0L;
        if (getIsToBePayByOrderType(pkCountry, specialArea)) {
            if (EOrderType.REGISTER_ORDER.getValue() == specialArea) {
                timeType = querySystemConfigByKey(pkCountry, ESystemConfig.REGISTER_ORDER_TIME.getKey());
            } else if (EOrderType.UPGRADE_ORDER.getValue() == specialArea) {
                timeType = querySystemConfigByKey(pkCountry, ESystemConfig.UPGRADE_ORDER_TIME.getKey());
            } else if (EOrderType.REPURCHASE_ORDER.getValue() == specialArea) {
                timeType = querySystemConfigByKey(pkCountry, ESystemConfig.REPURCHASE_ORDER_TIME.getKey());
            } else {
                timeType = querySystemConfigByKey(pkCountry, ESystemConfig.REGISTER_ORDER_TIME.getKey());
            }
            // 12小时
            timeSecond = 12 * MagicNumberConstants.HOUR_SECOND;
            if (ESpecialAreaTime.TWENTY_FOUR_HOUR.getValue().equals(timeType)) {
                timeSecond = timeSecond * 2;
            } else if (ESpecialAreaTime.FORTY_EIGHT_HOUR.getValue().equals(timeType)) {
                timeSecond = timeSecond * 4;
            }
        }
        return timeSecond;
    }

    /**
     * 点击支付按钮，输入密码，确认下单
     *
     * @param saOrderExt         订单
     * @param newCuMember        新会员信息
     * @param cuMemberAccountExt 支付账户信息
     * @Author: sui q
     * @Date: 2022/9/13 13:37
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean payRegSaOrder(SaOrderExt saOrderExt, CuMember newCuMember,
                                 CuMemberAccountExt cuMemberAccountExt, Boolean isHaiFun) {
        boolean isToBePay = getIsToBePayByOrderType(newCuMember.getPkSettleCountry(), saOrderExt.getOrderType());
        Date currentDateTime = DateUtils.currentDateTime();
        Long pkCreator = saOrderExt.getPkCreator();
        newCuMember.setPayStatus(EPayStatus.PAID.getValue());
        newCuMember.setPayTime(currentDateTime);
        saOrderExt.setPayTime(currentDateTime);
        saOrderExt.setOrderStatus(EOrderStatus.PAY.getValue());
        if (isToBePay && !isHaiFun) {
            // 根据业绩判断自动上树
            newCuMember.setPkModified(pkCreator);
            newCuMember.setModifiedTime(currentDateTime);

            GradeDTO tmpGradeDTO = gradeServiceApi.getGrade(newCuMember.getPkSettleGrade()).getData();
            // 校验等级，如果不是会员、铁卡，则第一年给奖金年包
            if (tmpGradeDTO.getGradeValue() >= EGrade.YOU_KE.getValue()) {
                newCuMember.setExpireDate(DateUtils.addDays(DateUtils.addYears(newCuMember.getCreationTime() != null ? newCuMember.getCreationTime() : new Date(), MagicNumberConstants.BOUNS_INIT_YEAR), -1));
            }

            saOrderExt.setPkModified(pkCreator);
            saOrderExt.setModifiedTime(currentDateTime);
            saOrderExt.getOrderItemsList().forEach(saOrderItems -> {
                saOrderItems.setPkModified(pkCreator);
                saOrderItems.setModifiedTime(currentDateTime);
                saOrderItems.setOrderStatus(EOrderStatus.PAY.getValue());
            });
            // 更新订单信息
            updateSaOrder(saOrderExt);
//            getSaOrderItemsMaker(saOrderExt);
        } else {
            newCuMember.setConsumeMoney(BigDecimal.ZERO);
            newCuMember.setConsumeAchieve(BigDecimal.ZERO);
            if (setLastCuMemberGrade(newCuMember, saOrderExt)) {
                return false;
            }
            if (isHaiFun) {
                // 重试上树
                CuMember cuMember = repeatTry(newCuMember, Boolean.FALSE);
                newCuMember.setPkPlaceParent(cuMember.getPkPlaceParent());
                newCuMember.setPlaceDept(cuMember.getPlaceDept());
                isToBePay = false;
            }
            newCuMember.setCreationTime(currentDateTime);
            saOrderExt.setCreationTime(currentDateTime);
            saOrderExt.getOrderItemsList().forEach(saOrderItems -> {
                saOrderItems.setCreationTime(saOrderExt.getCreationTime());
                saOrderItems.setOrderStatus(EOrderStatus.PAY.getValue());
            });
            // 保存订单信息
            processOrder(saOrderExt);
        }
        // 店铺订单，保存显示订单奖金比例
        if (EOrderType.REGISTER_ORDER.getValue() == saOrderExt.getOrderType()) {
            if (saOrderExt.getPkMemberStore() != null) {
                storeBonusService.saveSaStoreBonus(saOrderExt);
            }
        }
        // 调用其他服务保存会员信息、会员注册信息
        if (!memberServiceApi.saveMember(newCuMember, saOrderExt, isToBePay, cuMemberAccountExt).getData()) {
            throw new RuntimeException("保存会员失败");
        }
        try {
            if (EOrderType.REGISTER_ORDER.getValue() == saOrderExt.getOrderType()
                    || EOrderType.UPGRADE_ORDER.getValue() == saOrderExt.getOrderType()) {
                // 推送MQ，处理消费升级（个人购买满20美金并且直推60PV报单，可升级到铜卡）
                rabbitTemplate.convertAndSend(RabbitMqConstants.CONSUME_UPGRADE_EXCHANGE, RabbitMqConstants.CONSUME_UPGRADE_KEY, saOrderExt);
            }

            log.info("生产活动消息，activity.exchange：{}", JSONUtil.toJsonStr(saOrderExt));
            rabbitTemplate.convertAndSend(RabbitMqConstants.ACTIVITY_EXCHANGE, RabbitMqConstants.ACTIVITY_KEY, saOrderExt);

            //计算奖金，通过mq分发消息，异步处理
//            log.info("生产秒结消息，order.second.exchange：{}", JSONUtil.toJsonStr(saOrderExt));
//            rabbitTemplate.convertAndSend(RabbitMqConstants.ORDER_SECOND_EXCHANGE, RabbitMqConstants.ORDER_SECOND_KEY, saOrderExt);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Boolean.TRUE;
    }

    /**
     * @param newCuMember 修改的会员
     * @Description: 尝试重新换位置
     * @return: CuMember
     * @Author: sui q
     * @Date: 2022/10/26 9:00
     */
    private synchronized CuMember repeatTry(CuMember newCuMember, Boolean isFirstAchieve) {
        CuMember cuMember = obtainLastResettleByRecommend(newCuMember, isFirstAchieve, null);
        if (!lockKey(CacheConstants.POSITION + cuMember.getPkPlaceParent() + cuMember.getPlaceDept())) {
            try {
                Thread.sleep(300);
                repeatTry(newCuMember, isFirstAchieve);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return cuMember;
    }

    private void insertSaOrder(SaOrderExt saOrderExt) {
        redisService.lockKeyMany(CacheConstants.MEMBER_ORDER + saOrderExt.getOrderCode());
        try {
            this.save(saOrderExt);
            for (SaOrderItems saOrderItems : saOrderExt.getOrderItemsList()) {
                saOrderItems.setPkOrder(saOrderExt.getPkId());
            }
            saOrderItemsService.saveBatch(saOrderExt.getOrderItemsList());
        } finally {
            redisService.unlock(CacheConstants.MEMBER_ORDER + saOrderExt.getOrderCode());
        }
    }

    private void updateSaOrder(SaOrderExt saOrderExt) {
        redisService.lockKeyMany(CacheConstants.MEMBER_ORDER + saOrderExt.getOrderCode());
        try {
            updateById(saOrderExt);
            saOrderItemsService.updateBatchById(saOrderExt.getOrderItemsList());
        } finally {
            redisService.unlock(CacheConstants.MEMBER_ORDER + saOrderExt.getOrderCode());
        }
    }

    /**
     * 销售订单更改状态为待支付
     *
     * @param saOrderExt 销售订单
     */
    public void encapsulationSaOrder(SaOrderExt saOrderExt) {
        saOrderExt.setPayTime(new Date());
        saOrderExt.setPkModified(saOrderExt.getPkCreator());
        saOrderExt.setModifiedTime(saOrderExt.getPayTime());
        saOrderExt.setOrderStatus(EOrderStatus.PAY.getValue());
        saOrderExt.getOrderItemsList().forEach(saOrderItems -> {
            saOrderItems.setPkModified(saOrderExt.getPkCreator());
            saOrderItems.setModifiedTime(saOrderExt.getPayTime());
            saOrderItems.setOrderStatus(EOrderStatus.PAY.getValue());
        });
    }

    /**
     * 支付升级订单
     *
     * @param saOrderExt         订单信息
     * @param cuMemberAccountExt 会员账户
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean payUpgradeSaOrder(SaOrderExt saOrderExt, CuMemberAccountExt cuMemberAccountExt) {
        CuMember cuMember = getCuMemberByKey(saOrderExt.getPkMember());
        int oldLevel = cuMember.getPkSettleGrade();
        // 封装等级,重新计算会员等级
        if (setLastCuMemberGrade(cuMember, saOrderExt)) {
            return false;
        }
        // 验证等级，原等级<新等级，才可以进行升级 或者事累计升级
        String upgradeWay = querySystemConfigByKey(saOrderExt.getPkCountry(), ESystemConfig.UPGRADE_WAY.getKey());
        if (oldLevel >= cuMember.getPkSettleGrade() && !Objects.equals(Integer.toString(EUpgradeWay.TOTAL.getValue()), upgradeWay)) {
            return false;
        }
        // 保存订单
        encapsulationSaOrder(saOrderExt);
        // 更新订单信息
        updateSaOrder(saOrderExt);
        if (EOrderType.UPGRADE_ORDER.getValue() == saOrderExt.getOrderType()) {
            if (saOrderExt.getPkMemberStore() != null) {
                storeBonusService.saveSaStoreBonus(saOrderExt);
            }
        }
        // 处理会员信息，更新会员等级,扣款
        if (!memberServiceApi.saveMember(cuMember, saOrderExt, cuMemberAccountExt).getData()) {
            throw new RuntimeException("保存会员失败");
        }
        try {
            if (EOrderType.REGISTER_ORDER.getValue() == saOrderExt.getOrderType()
                    || EOrderType.UPGRADE_ORDER.getValue() == saOrderExt.getOrderType()) {
                // 推送MQ，处理消费升级（个人购买满20美金并且直推60PV报单，可升级到铜卡）
                rabbitTemplate.convertAndSend(RabbitMqConstants.CONSUME_UPGRADE_EXCHANGE, RabbitMqConstants.CONSUME_UPGRADE_KEY, saOrderExt);
            }

            log.info("生产活动消息，activity.exchange：{}", JSONUtil.toJsonStr(saOrderExt));
            rabbitTemplate.convertAndSend(RabbitMqConstants.ACTIVITY_EXCHANGE, RabbitMqConstants.ACTIVITY_KEY, saOrderExt);

//            rabbitTemplate.convertAndSend(RabbitMqConstants.ORDER_SECOND_EXCHANGE, RabbitMqConstants.ORDER_SECOND_KEY, saOrderExt);
//            rabbitTemplate.convertAndSend(RabbitMqConstants.ACTIVITY_EXCHANGE, RabbitMqConstants.ACTIVITY_KEY, saOrderExt);
        } catch (Exception e) {
            log.error("payUpgradeSaOrder Exception: {}", "推送MQ失败", e);
        }
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean confirmRepurchaseSaOrder(OrderParam orderParam) {
        boolean isToBePay = getIsToBePayByOrderType(orderParam.getPkSettleCountry(), orderParam.getSpecialArea());
        CuMember cuMember;

        // 转区到订单类型的转换
        int tmpSpecialArea = ESpecialArea.getOrderTypeValue(orderParam.getSpecialArea());
        if (EOrderType.UPGRADE_ORDER.getValue() == tmpSpecialArea
                || EOrderType.REPURCHASE_ORDER.getValue() == tmpSpecialArea
                || EOrderType.RESALE_ORDER.getValue() == tmpSpecialArea) {
            cuMember = getCuMemberByCode(orderParam.getUpgradeMemberCode());
        } else {
            cuMember = getCuMemberByKey(orderParam.getCenterCodeId());
        }
        SaOrderExt saOrderExt = packageWholeSaOrder(orderParam, cuMember);
        if (saOrderExt.getOrderItemsList().size() == 0) {
            return false;
        }
        // 升级订单验证等级
        if (EOrderType.UPGRADE_ORDER.getValue() == tmpSpecialArea) {
            if (setLastCuMemberGrade(cuMember, saOrderExt)) {
                return false;
            }
        } else if (EOrderType.RENEWAL_ORDER.getValue() == tmpSpecialArea) {
            // 年包订单，订单价格需要大于等于会员等级年包价格，不然不能下单
            if (!this.checkRenewalAmount(cuMember, saOrderExt)) {
                // 订单价格 小于 年包价格
                throw new ServiceException(TransactionUtils.getContent(SaOrderMsgConstants.RENEWAL_ORDER_PRICE_NOT_ENOUGH));
            }
        }
        if (isToBePay) {
            processOrder(saOrderExt);
        } else {
            redisService.setCacheObject(CacheConstants.TEMP_ORDER + orderParam.getCenterCodeId() + orderParam.getOrderCode(), saOrderExt, CacheConstants.MEMBER_REFRESH_TIME, TimeUnit.HOURS);
        }
        redisService.setCacheObject(CacheConstants.TEMP_PARAM + orderParam.getCenterCodeId() + orderParam.getOrderCode(), orderParam, CacheConstants.MEMBER_REFRESH_TIME, TimeUnit.HOURS);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean confirmNewPeopleGift(OrderParam orderParam) {
        // 获取订单编号
        String orderCode = saOrderHandle.createOrderCode(EOrderPrefix.ORDER_CODE.getValue());
        CuMember cuMember = getCuMemberByKey(orderParam.getCenterCodeId());
        SaOrderExt saOrderExt = saOrderHandle.packageSaveSaOrder(orderParam, cuMember, orderCode);
        List<SaOrderItems> saOrderItemsList = new ArrayList<>();
        List<AcPeopleGiftProductDTO> peopleGiftProductDtoList = peopleServiceServiceApi.getGiftPackProductList(orderParam.getPkNewPeople()).getData();
        // 获取汇率
        CurrencyDTO currency = currencyServiceApi.getCurrency(orderParam.getPkSettleCountry()).getData();
        for (AcPeopleGiftProductDTO acPeopleGiftProductDTO : peopleGiftProductDtoList) {
            SaOrderItems saOrderItems = SaOrderItems.builder()
                    .pkProduct(acPeopleGiftProductDTO.getPkProductId())
                    .price(acPeopleGiftProductDTO.getPrice())
                    .achievement(BigDecimal.ZERO)
                    .quantity(acPeopleGiftProductDTO.getQuantity())
                    .pkRate(currency.getPkId())
                    .pkGrade(cuMember.getPkSettleGrade())
                    .pkAwards(cuMember.getPkAwards())
                    .orderStatus(EOrderStatus.WAIT_PAY.getValue())
                    .specsName(acPeopleGiftProductDTO.getSpecsName())
                    .specsNameId(acPeopleGiftProductDTO.getSpecsNameId())
                    .build();
            saOrderItems.setPkCountry(saOrderExt.getPkCountry());
            saOrderItems.setPkCreator(saOrderExt.getPkCreator());
            saOrderItems.setCreationTime(saOrderExt.getCreationTime());
            saOrderItemsList.add(saOrderItems);
        }
        saOrderExt.setPkRate(currency.getPkId());
        saOrderExt.setOrderAmount(peopleGiftProductDtoList.get(0).getReceivePrice());
        saOrderExt.setOrderAchieve(BigDecimal.ZERO);
        saOrderExt.setOrderAssAchieve(BigDecimal.ZERO);
        saOrderExt.setPostage(BigDecimal.ZERO);
        saOrderExt.setPkOriginalOrder(peopleGiftProductDtoList.get(0).getPkBaseId());
        // 计算邮费
        saOrderExt.setOrderItemsList(saOrderItemsList);
        if (saOrderExt.getOrderItemsList().size() == 0) {
            return false;
        }
        processOrder(saOrderExt);
//        redisService.setCacheObject(CacheConstants.TEMP_ORDER + orderParam.getCenterCodeId() + orderParam.getOrderCode(), saOrderExt, CacheConstants.MEMBER_REFRESH_TIME, TimeUnit.MINUTES);
//        redisService.setCacheObject(CacheConstants.TEMP_PARAM + orderParam.getCenterCodeId() + orderParam.getOrderCode(), orderParam, CacheConstants.MEMBER_REFRESH_TIME, TimeUnit.MINUTES);
        return true;
    }

    /**
     * 支付复购订单
     *
     * @param saOrderExt         订单
     * @param cuMemberAccountExt 会员账户
     * @return: Boolean
     * @Author: sui q
     * @Date: 2022/9/26 11:29
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean payRepurchaseSaOrder(SaOrderExt saOrderExt, CuMemberAccountExt cuMemberAccountExt) {
        CuMember member = getCuMemberByKey(saOrderExt.getPkMember());

        // 保存订单
        encapsulationSaOrder(saOrderExt);
        if (EOrderType.PICK_ORDER.getValue() == saOrderExt.getOrderType()) {
            // 提货订单，没有待支付，直接保存
            insertSaOrder(saOrderExt);
        } else {
            if (EOrderType.RENEWAL_ORDER.getValue() == saOrderExt.getOrderType()) {
                // 年包订单，需要更新会员年包时间
                // 每个自然年，只有第一单会员年包订单才给年包时间
                saOrderExt.setExpireDateFlag(baseMapper.countOrderCountByYear(saOrderExt.getPkMember(), saOrderExt.getOrderType(), DateUtils.parseDateToFormat(DateUtils.YYYY, saOrderExt.getPayTime())) == 0);
            }

            // 更新订单信息
            updateSaOrder(saOrderExt);
        }

        // 处理会员信息，更新会员等级,扣款
        CuMember cuMember = calculateHaFunMemberGrade(saOrderExt, member);
        memberServiceApi.saveMember(cuMember, saOrderExt, cuMemberAccountExt).getData();
        return true;
    }

    /**
     * @param orderParam 参数
     * @param cuMember   会员
     * @Description: 封装整个订单
     * @return: SaOrderExt
     * @Author: sui q
     * @Date: 2022/9/26 10:36
     */
    private SaOrderExt packageWholeSaOrder(OrderParam orderParam, CuMember cuMember) {
        // 获取订单编号
        String orderCode = orderParam.getOrderCode();
        if (StringUtils.isEmpty(orderCode)) {
            orderCode = saOrderHandle.createOrderCode(EOrderPrefix.ORDER_CODE.getValue());
        }
        SaOrderExt saOrderExt = saOrderHandle.packageSaveSaOrder(orderParam, cuMember, orderCode);
        saOrderHandle.packSaOrderItems(cuMember, saOrderExt, orderParam);
        // 第二次封装订单，根据明细表计算订单主表金额、业绩
        saOrderExt.getOrderItemsList().forEach(saOrderItems -> {
            saOrderExt.setPkRate(saOrderItems.getPkRate());
            // 总价;
            saOrderExt.setOrderAmount(ComputeUtil.computeAddMultiply(saOrderExt.getOrderAmount(), saOrderItems.getPrice(), saOrderItems.getQuantity()));
            // 总业绩
            saOrderExt.setOrderAchieve(ComputeUtil.computeAddMultiply(saOrderExt.getOrderAchieve(), saOrderItems.getAchievement(), saOrderItems.getQuantity()));
            // 总考核业绩
            saOrderExt.setOrderAssAchieve(ComputeUtil.computeAddMultiply(saOrderExt.getOrderAssAchieve(), null != saOrderItems.getAssAchievement() ? saOrderItems.getAssAchievement() : BigDecimal.ZERO, saOrderItems.getQuantity()));
        });
        saOrderExt.setUploadAchieve(saOrderExt.getOrderAchieve());
        orderParam.setOrderCode(orderCode);
        return saOrderExt;
    }


    @Override
    public void queryPostageByParam(OrderParam orderParam) {
        CuMember cuMember = getCuMemberByKey(orderParam.getCenterCodeId());
        saOrderHandle.queryPostage(cuMember, orderParam);
    }

    @Override
    public OrderReturn computeLevel(OrderParam orderParam) {
        // 新订单的
        SaOrder saOrder = saOrderHandle.computeSaOrderAchieve(orderParam);
        OrderReturn orderReturn = OrderReturn.builder().isEnough(false).build();
        GradeDTO gradeDTO = calculateGradeDTO(orderParam.getSpecialArea(), orderParam.getPkSettleCountry(),
                orderParam.getCenterCodeId(), saOrder, orderReturn);
        // 注册订单直接查询出会员等级
        if (ESpecialArea.getOrderTypeValue(orderParam.getSpecialArea()) == EOrderType.REGISTER_ORDER.getValue()) {
            orderReturn.setIsEnough(Boolean.TRUE);
        }
        // 验证等级是否满足条件
        if (!orderReturn.getIsEnough()) {
            CuMember member = getCuMemberByKey(orderParam.getCenterCodeId());
            GradeDTO grade = gradeServiceApi.getGrade(member.getPkSettleGrade()).getData();
            if (grade.getGradeValue() < gradeDTO.getGradeValue()) {
                orderReturn.setIsEnough(Boolean.TRUE);
            } else {
                gradeDTO.setGradeName(null);
            }
        }
        if (gradeDTO == null) {
            gradeDTO = GradeDTO.builder().gradeName(null).build();
            orderReturn.setIsEnough(Boolean.FALSE);
        }
        orderReturn.setPkGrade(gradeDTO.getPkTransaction());
        return orderReturn;
    }

    private GradeDTO calculateGradeDTO(Integer specialArea, Integer pkCountry, Long pkMember, SaOrder saOrder, OrderReturn orderReturn) {
        BigDecimal orderAmount = saOrder.getOrderAmount();
        BigDecimal orderAchieve = saOrder.getOrderAchieve();
        // 判断专区 升级需要判断哪个国家，每个国家升级方式不一样
        String upgradeWay = querySystemConfigByKey(pkCountry, ESystemConfig.UPGRADE_WAY.getKey());
        CountryDTO countryDTO = countryServiceApi.getCountry(pkCountry).getData();
        // 会员等级为1的话 为一次性补差升级
        CuMember cuMember = getCuMemberByKey(pkMember);
        if (ESpecialArea.getOrderTypeValue(specialArea) == EOrderType.UPGRADE_ORDER.getValue() ||
                (cuMember != null && Objects.equals(cuMember.getPkSettleGrade(), MagicNumberConstants.CHINA_HA_FUN))) {
            if (MagicNumberConstants.BENGAL_COUNTRY_CODE.equals(countryDTO.getCode())) {
                CuMemberUpgrade cuMemberUpgrade = memberServiceApi.queryCuMemberUpgradeByCondition(pkCountry, pkMember).getData();
                if (cuMemberUpgrade != null) {
                    upgradeWay = Integer.toString(EUpgradeWay.DIFFERENCE.getValue());
                }
            }
            if (EUpgradeWay.COVER.getValue() != Integer.parseInt(upgradeWay)) {
                // 获得历史订单pv
                String notOrderCode = null;
                if (StringUtils.isNotEmpty(saOrder.getOrderCode())) {
                    notOrderCode = saOrder.getOrderCode();
                }
                SaOrder hisSaOrder = baseMapper.querySumAmountAndAchieve(pkMember, notOrderCode);
                if (hisSaOrder != null) {
                    orderAmount = orderAmount.add(hisSaOrder.getOrderAmount());
                    orderAchieve = orderAchieve.add(hisSaOrder.getOrderAchieve());
                }
                // 累计升级无论是否升级都满足条件
                if (EUpgradeWay.TOTAL.getValue() == Integer.parseInt(upgradeWay)) {
                    orderReturn.setIsEnough(Boolean.TRUE);
                }
            }
        }
        return saOrderHandle.getMemberGradeAndAwardByCountry(cuMember, specialArea, orderAmount, orderAchieve, pkCountry, upgradeWay);
    }

    /**
     * 撤单计算等级
     *
     * @param specialArea
     * @param pkCountry
     * @param pkMember
     * @param saOrder
     * @param orderReturn
     * @return
     */
    private GradeDTO revokeSaOrderCalculateGradeDTO(Integer specialArea, Integer pkCountry, Long pkMember, SaOrder saOrder, OrderReturn orderReturn) {
        BigDecimal orderAmount = saOrder.getOrderAmount();
        BigDecimal orderAchieve = saOrder.getOrderAchieve();
        // 判断专区 升级需要判断哪个国家，每个国家升级方式不一样
        String upgradeWay = querySystemConfigByKey(pkCountry, ESystemConfig.UPGRADE_WAY.getKey());
        CountryDTO countryDTO = countryServiceApi.getCountry(pkCountry).getData();
        // 会员等级为1的话 为一次性补差升级
        CuMember cuMember = getCuMemberByKey(pkMember);
        if (ESpecialArea.getOrderTypeValue(specialArea) == EOrderType.UPGRADE_ORDER.getValue() ||
                (cuMember != null && Objects.equals(cuMember.getPkSettleGrade(), MagicNumberConstants.CHINA_HA_FUN))) {
            if (MagicNumberConstants.BENGAL_COUNTRY_CODE.equals(countryDTO.getCode())) {
                CuMemberUpgrade cuMemberUpgrade = memberServiceApi.queryCuMemberUpgradeByCondition(pkCountry, pkMember).getData();
                if (cuMemberUpgrade != null) {
                    upgradeWay = Integer.toString(EUpgradeWay.DIFFERENCE.getValue());
                }
            }
            if (EUpgradeWay.COVER.getValue() != Integer.parseInt(upgradeWay)) {
                // 获得历史订单pv
                String notOrderCode = null;
                if (StringUtils.isNotEmpty(saOrder.getOrderCode())) {
                    notOrderCode = saOrder.getOrderCode();
                }
                SaOrder hisSaOrder = baseMapper.querySumAmountAndAchieve(pkMember, notOrderCode);
                if (hisSaOrder != null) {
                    orderAmount = orderAmount.add(hisSaOrder.getOrderAmount());
                    orderAchieve = orderAchieve.add(hisSaOrder.getOrderAchieve());
                }
                // 累计升级无论是否升级都满足条件
                if (EUpgradeWay.TOTAL.getValue() == Integer.parseInt(upgradeWay)) {
                    orderReturn.setIsEnough(Boolean.TRUE);
                }
            }
        }
        // 根据PV，撤单之后需要降的等级
        GradeDTO gradeDTO = saOrderHandle.getMemberGradeAndAwardByCountry(cuMember, specialArea, orderAmount, orderAchieve, pkCountry, upgradeWay);

        // 累计升级
        if (EUpgradeWay.TOTAL.getValue() == Integer.parseInt(upgradeWay)) {
            // PV等级 与 手动升级 进行比较，取最大的
            CuMemberLevel cuMemberLevel = iCuMemberDetailServiceApi.queryLastManualUpgrade(pkMember, pkCountry).getData();
            if (null != cuMemberLevel) {
                // 存在手动升级
                GradeDTO manualUpgradeGrade = gradeServiceApi.getGrade(cuMemberLevel.getNewLevel()).getData();
                if (manualUpgradeGrade.getGradeValue() > gradeDTO.getGradeValue()) {
                    // 手动升级 高于 PV等级
                    // 返回会员的消费业绩
                    manualUpgradeGrade.setStartValue(orderAchieve);
                    return manualUpgradeGrade;
                }
            }
        }
        return gradeDTO;
    }

    /**
     * 生成空单注册
     *
     * @param orderBlankRegParams 参数
     * @return: String
     * @Date: 2022/11/14 15:10
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String registerEmptyOrder(OrderBlankRegParams orderBlankRegParams) {
        LoginUser loginUser = userTokenService.getLoginUser();
        Integer pkCountry = SecurityUtils.getPkCountry();
        Date date = new Date();

        //业务单号
        String code = CommonUtil.createSerialNumber(EOrderPrefix.SPECIAL_UPDATE_CODE.getValue());
        orderBlankRegParams.setApprovalBusiness(EApprovalBusiness.CHANGE_MEMBER_CODE.getValue());


        //添加修改记录表数据
        CuMemberServiceLog memberLog = new CuMemberServiceLog();
//        memberLog.setPkMember(member.getData().getPkId().longValue());
        memberLog.setEditType(EApprovalBusiness.EMPTY_ORDER.getValue());
        memberLog.setEditTypePay(EApprovalBusiness.EMPTY_ORDER.getValue());

        memberLog.setNewValue(JSONObject.toJSONString(orderBlankRegParams));
        memberLog.setPkCreator(loginUser.getUserId());
        memberLog.setCreationTime(date);
        memberLog.setBusinessNo(code);
        memberLog.setPkCountry(pkCountry);
        memberLog.setProcessType(orderBlankRegParams.getProcessType());
        memberLog.setApproveNumber(orderBlankRegParams.getChangeNumber());

        //免签呈;免签呈免支付
        if (orderBlankRegParams.getProcessType() == EProcessType.AVOIDSIGNING.getValue()
                || orderBlankRegParams.getProcessType() == EProcessType.DOUBLEAVOID.getValue()) {
            //添加修改记录表数据
            memberLog.setApproveStatus(EApproveStatus.FINISH.getValue());
            cuMemberServiceLogServiceApi.insert(memberLog);
            // 主要业务
            //创建用户
            CuMemberExt memberExt = createMember(orderBlankRegParams);

            R<CuMember> member = memberServiceApi.createEmptyOrderMember(memberExt);
            if (member.getData() == null) {
                throw new RuntimeException("保存会员失败");
            }
            if (orderBlankRegParams.getRegisterPv().compareTo(BigDecimal.ZERO) == 1) {
                // 生成订单 （订单pv 不为0 情况下）
                createRegisterEmptyOrder(orderBlankRegParams, member.getData(), loginUser);
            }
            return member.getData().getMemberCode();
        } else if (orderBlankRegParams.getProcessType() == EProcessType.AVOIDPAY.getValue()
                || orderBlankRegParams.getProcessType() == EProcessType.DOUBLEPAY.getValue()) {
            // 免支付 需签呈+支付
            //生成签呈
            Set<Long> memberSet = new HashSet<>();
            memberSet.add(loginUser.getUserId());
            memberLog.setApproveStatus(EApproveStatus.ALREADY_SUBMIT.getValue());
            cuMemberServiceLogServiceApi.insert(memberLog);
            ApprovalSubmitDTO approvalSubmitDTO = ApprovalSubmitDTO.builder().eApprovalBusiness(EApprovalBusiness.EMPTY_ORDER)
                    .businessCode(code)
                    .signType(ESignType.getEnumByValue(orderBlankRegParams.getSignType()))
                    .remark(orderBlankRegParams.getRemark()).pkMemberList(memberSet).build();
            R<String> submit = approvalServiceApi.submit(approvalSubmitDTO, loginUser);
            if (!submit.isSuccess()) {
                throw new RuntimeException(TransactionUtils.getContent(ConfigMsgConstants.MEMBER_UPDATE_PETITION));
            }
        }
//        //扣钱
        if (orderBlankRegParams.getProcessType() == EProcessType.AVOIDSIGNING.getValue() || orderBlankRegParams.getProcessType() == EProcessType.DOUBLEPAY.getValue()) {
            // 免签或者确认按钮扣费
            BusinessCommissionDTO businessCommissionDTO = new BusinessCommissionDTO();
            businessCommissionDTO.setPkCountry(pkCountry);
            businessCommissionDTO.setMemberAmountDTOList(orderBlankRegParams.getMemberAmountDTOList());
            businessCommissionDTO.setTradeType(EApprovalBusiness.EMPTY_ORDER.getValue());
            R<Boolean> b = memberTradeServiceApi.businessCommissionSubmit(businessCommissionDTO);
            if (!b.getData()) {
                throw new ServiceException(TransactionUtils.getContent(ConfigMsgConstants.MEMBER_UPDATE_CODE_MONEY));
            }
        }
        return "";
    }

    /**
     * 空单生成订单
     *
     * @param orderBlankRegParams 参数
     */
    private SaOrder createRegisterEmptyOrder(OrderBlankRegParams orderBlankRegParams, CuMember member, LoginUser loginUser) {
        // 创建订单
        SaOrder saOrder = new SaOrder();
        String orderCode = saOrderHandle.createOrderCode(EOrderPrefix.ORDER_CODE.getValue());
        saOrder.setOrderCode(orderCode);
        // 虚拟订单
        saOrder.setOrderType(EOrderType.FICTITIOUS_ORDER.getValue());
        R<CurrencyDTO> currency = currencyServiceApi.getCurrency(orderBlankRegParams.getPkSettleCountry());
        saOrder.setPkRate(currency.getData().getPkId());
        saOrder.setOrderAmount(orderBlankRegParams.getRegisterPrice());
        saOrder.setOrderAchieve(orderBlankRegParams.getRegisterPv());
        saOrder.setDeliveryWay(orderBlankRegParams.getDeliveryWay());
        saOrder.setTranType(orderBlankRegParams.getTranType());
        saOrder.setRecName(orderBlankRegParams.getMemberName());
        saOrder.setRecPhone(orderBlankRegParams.getPhone());
        saOrder.setRecProvince(orderBlankRegParams.getProvince());
        saOrder.setRecCity(orderBlankRegParams.getCity());
        saOrder.setRecCounty(orderBlankRegParams.getCounty());
        saOrder.setRecAddress(orderBlankRegParams.getAddress());
        saOrder.setPayTime(new Date());
        saOrder.setOrderStatus(EOrderStatus.PAY.getValue());
        saOrder.setCreationTime(new Date());
        saOrder.setPkCountry(orderBlankRegParams.getPkSettleCountry());
        saOrder.setPkCreator(SecurityUtils.getUserId());
        saOrder.setPkMember(member.getPkId());
        saOrder.setRemark(orderBlankRegParams.getRemark());
        saOrder.setPkReference(member.getPkParent());
        saOrder.setPkPlacement(member.getPkPlaceParent());
        saOrder.setDeliveryWay(EDelivery.COMPANY_PICKED_UP.getValue());
        saOrder.setTranType(ETransportType.LAND.getValue());
        save(saOrder);
        // 创建订单项
        List<SaOrderItems> orderItems = orderBlankRegParams.getOrderItems();
        for (SaOrderItems orderItem : orderItems) {
            orderItem.setPkOrder(saOrder.getPkId());
            BdWares wares = waresService.getWares(orderItem.getPkWares());
            BdProductExtend productExtend = productExtendService.getProductExtend(orderItem.getPkProduct());
            orderItem.setPkWares(wares.getPkId());
            orderItem.setPrice(wares.getWaresPrice().multiply(new BigDecimal(orderItem.getQuantity())));
            orderItem.setPkRate(currency.getData().getPkId());
            orderItem.setAchievement(wares.getWaresAchieve().multiply(new BigDecimal(orderItem.getQuantity())));
            orderItem.setIsGift(productExtend.getIsGift());
            orderItem.setPkGrade(orderBlankRegParams.getUserLevel());
            orderItem.setPkAwards(orderBlankRegParams.getUserAwards());
            orderItem.setOrderStatus(EOrderStatus.PAY.getValue());
            orderItem.setCreationTime(DateUtils.currentDateTime());
            // 填充冗余产品规格
            List<BdWaresSpecsRelationExt> waresSpecsRelationList = waresSpecsRelationService.selectByWaresSpecsSku(orderItem.getPkWaresSpecsSku().intValue());
            // 规格名称
            List<String> specsNames = new ArrayList<>();
            // 规格id
            List<Integer> specsIds = new ArrayList<>();
            for (BdWaresSpecsRelationExt bdWaresSpecsRelationExt : waresSpecsRelationList) {
                specsNames.add(bdWaresSpecsRelationExt.getSpecsName());
                specsIds.add(bdWaresSpecsRelationExt.getPkSpecs());
            }
            orderItem.setSpecsName(StringUtils.join(specsNames, ","));
            orderItem.setSpecsNameId(StringUtils.join(specsIds, ","));
            orderItem.setPkCountry(orderBlankRegParams.getPkSettleCountry());
            orderItem.setPkCreator(SecurityUtils.getUserId());
        }
        saOrderItemsService.saveBatch(orderItems);
        // 设置用户银行卡信息 国内页面隐藏
        if (loginUser.getDataCountry() != 1) {
            CuMemberBankParam memberBank = new CuMemberBankParam();
            memberBank.setPkMember(member.getPkId());
            memberBank.setPkCountry(orderBlankRegParams.getPkSettleCountry());
            memberBank.setBankName(orderBlankRegParams.getBankName());
            memberBank.setSubBankName(orderBlankRegParams.getOpeningBranch());
            memberBank.setCardNumber(orderBlankRegParams.getBankCard());
            memberBank.setAccountName(orderBlankRegParams.getOpeningName());
            memberBank.setPhone(orderBlankRegParams.getReservedPhone());
            memberBank.setIdCard(orderBlankRegParams.getIdCard());
            memberBank.setPkMember(member.getPkId());
            memberBankServiceApi.addBankInfo(memberBank);
        }
        return saOrder;
    }

    /**
     * 空单生成用户
     *
     * @param orderBlankRegParams 参数
     */
    private CuMemberExt createMember(OrderBlankRegParams orderBlankRegParams) {
        CuMemberExt cuMember = new CuMemberExt();
        // 注册等级
        cuMember.setPkRegisterGrade(orderBlankRegParams.getUserLevel());
        // 结算等级
        cuMember.setPkSettleGrade(orderBlankRegParams.getUserLevel());
        cuMember.setPkSettleCountry(orderBlankRegParams.getPkSettleCountry());
        // 推荐人主键
        cuMember.setParent(orderBlankRegParams.getParent());
        // 安置人主键
        cuMember.setPlaceParent(orderBlankRegParams.getPlaceParent());
        // 回填金额
        cuMember.setLockAccount4(orderBlankRegParams.getBackfillPrice());

        cuMember.setPlaceDept(orderBlankRegParams.getPlaceDept());
        // 生成用户编号
        //     R<CuMember> memberIdAndCode = memberServiceApi.createMemberIdAndCode(cuMember, false);
//        String memberCode = memberIdAndCode.getData().getMemberCode();
        //      cuMember.setMemberCode(memberCode);
        //       cuMember.setPkId(memberIdAndCode.getData().getPkId());
        cuMember.setMemberName(orderBlankRegParams.getMemberName());
        cuMember.setPhone(orderBlankRegParams.getPhone());
        cuMember.setCustomerType(ECustomerType.EMPTY_ORDER.getValue());
        cuMember.setPkAwards(orderBlankRegParams.getUserAwards());
        cuMember.setIdCard(orderBlankRegParams.getIdCard());

        //   R<CuMember> parentMember = memberServiceApi.getMember(orderBlankRegParams.getParent());

        //     cuMember.setPkParent(parentMember.getData().getPkId());

        //  R<CuMember> placeParentMember = memberServiceApi.getMember(orderBlankRegParams.getPlaceParent());

        //     cuMember.setPkPlaceParent(placeParentMember.getData().getPkId());

        cuMember.setPkCenterCode(orderBlankRegParams.getCenterCodeId());
        cuMember.setPkCountry(orderBlankRegParams.getPkSettleCountry());
        cuMember.setPkSettleCountry(orderBlankRegParams.getPkSettleCountry());
        cuMember.setSource(EDataSource.PC.getValue());
        cuMember.setPkRegisterGrade(orderBlankRegParams.getUserLevel());
        cuMember.setPkSettleGrade(orderBlankRegParams.getUserLevel());
        if (orderBlankRegParams.getUserAwards() == null) {
            cuMember.setPkAwards(0);
        } else {
            cuMember.setPkAwards(orderBlankRegParams.getUserAwards());
        }
        cuMember.setConsumeMoney(orderBlankRegParams.getRegisterPrice());
        cuMember.setConsumeAchieve(orderBlankRegParams.getRegisterPv());
        cuMember.setPayTime(new Date());
        cuMember.setLoginPwd(SecureUtil.md5(SysConstants.LOGIN_PASSWORD));
        cuMember.setPayPwd(SecureUtil.md5(SysConstants.PAY_PASSWORD));
        cuMember.setLoginPassword(SysConstants.LOGIN_PASSWORD);
        cuMember.setPayPassword(SysConstants.PAY_PASSWORD);
        cuMember.setPkCreator(SecurityUtils.getUserId());
        cuMember.setCreationTime(new Date());
        cuMember.setOrderSource(EOrderSource.EMPTY.getValue());
        cuMember.setEmail(orderBlankRegParams.getEmail());
        return cuMember;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void revokeSaOrderByOrderCode(Long pkApprove, OrderCancelParam orderCancelParam, ValidateCancelOrderVO validateCancelOrderVO) {
        SaOrderExt saOrderExt = validateCancelOrderVO.getSaOrderExt();
        BusinessCommissionDTO businessCommissionDTO = null;
        if (orderCancelParam.getCancelRoad() == 1) {
            EApprovalBusiness approveBusiness = EApprovalBusiness.ORDER_CANCEL;
            if (ECancelOrderType.OTHER_CANCEL_PART_ORDER.getValue() == orderCancelParam.getCancelType()) {
                approveBusiness = EApprovalBusiness.ORDER_CANCEL_PRODUCT;
            }
            Map<Long, OrderQueryChargeDTO> queryChargeMap = orderBusinessService.queryChargeLog(Collections.singletonList(validateCancelOrderVO.getSaOrderExt()),
                    approveBusiness, orderCancelParam.getPkCountry());
            if (queryChargeMap != null && queryChargeMap.containsKey(saOrderExt.getPkId())) {
                List<MemberAmountDTO> memberAmountDTOList = new ArrayList<>();
                // 封装订单业务扣款
                if (queryChargeMap.get(saOrderExt.getPkId()).getCost().compareTo(BigDecimal.ZERO) > 0) {
                    // 当需要扣费大于0，则进行处理
                    memberAmountDTOList.add(MemberAmountDTO.builder()
                            .pkMember(saOrderExt.getPkCreator())
                            .tradeAmount(queryChargeMap.get(saOrderExt.getPkId()).getCost())
                            .build());
                }
                Integer currency = queryChargeMap.get(saOrderExt.getPkId()).getPkAccount();
                if (CollectionUtil.isNotEmpty(memberAmountDTOList)) {
                    // 本批订单修改记录编号
                    String businessCode = CommonUtil.createSerialNumber(EOrderPrefix.REVOKE_ORDER_CODE);
                    businessCommissionDTO = BusinessCommissionDTO.builder()
                            .pkCountry(orderCancelParam.getPkCountry())
                            .pkCreator(pkApprove)
                            .pkAccount(currency)
                            .tradeType(approveBusiness.getValue())
                            .tradeCode(businessCode)
                            .memberAmountDTOList(memberAmountDTOList)
                            .build();
                }
            }

        }
        if (ECancelOrderType.OTHER_CANCEL_PART_ORDER.getValue() == orderCancelParam.getCancelType()) {
            List<OrderCancelDetailParam> orderCancelDetailParamList = orderCancelParam.getOrderCancelDetailParamList();
            List<Long> pkOrderItemList = orderCancelDetailParamList.stream().map(OrderCancelDetailParam::getPkId).collect(Collectors.toList());
            // 第二次封装订单，根据明细表计算订单主表金额、业绩
            saOrderExt.setOrderAmount(BigDecimal.ZERO);
            saOrderExt.setOrderAchieve(BigDecimal.ZERO);
            saOrderExt.setOrderAssAchieve(BigDecimal.ZERO);
            saOrderExt.setBackOrderAmount(BigDecimal.ZERO);
            List<SaOrderItems> saOrderItemsList = new ArrayList<>();
            saOrderExt.getOrderItemsList().forEach(saOrderItems -> {
                if (pkOrderItemList.contains(saOrderItems.getPkId())) {
                    saOrderExt.setBackOrderAmount(ComputeUtil.computeAddMultiply(saOrderExt.getBackOrderAmount(), saOrderItems.getPrice(), saOrderItems.getQuantity()));
                    return;
                }
                // 总价;
                saOrderExt.setOrderAmount(ComputeUtil.computeAddMultiply(saOrderExt.getOrderAmount(), saOrderItems.getPrice(), saOrderItems.getQuantity()));
                // 总业绩
                saOrderExt.setOrderAchieve(ComputeUtil.computeAddMultiply(saOrderExt.getOrderAchieve(), saOrderItems.getAchievement(), saOrderItems.getQuantity()));
                // 总考核业绩
                saOrderExt.setOrderAssAchieve(ComputeUtil.computeAddMultiply(saOrderExt.getOrderAssAchieve(), saOrderItems.getAssAchievement(), saOrderItems.getQuantity()));
                saOrderItemsList.add(saOrderItems);
            });
            saOrderExt.setUploadAchieve(saOrderExt.getOrderAchieve());
            if (saOrderItemsList.size() == 0) {
                saOrderExt.setDelFlag(EDelFlag.DELETE.getValue());
            } else {
                saOrderExt.setOrderItemsList(saOrderItemsList);
            }
            // 修改订单
            Date currentDateTime = DateUtils.currentDateTime();
            // 删除发货单
            saDeliverItemsService.deleteSaDeliverItems(saOrderExt.getPkId(), pkOrderItemList);
            updateSaOrder(pkApprove, saOrderExt, currentDateTime);
            // 删除订单明细
            if (!saOrderItemsService.updateOrderItemsById(pkOrderItemList, pkApprove, currentDateTime)) {
                throw new RuntimeException("更新订单失败");
            }
            if (!memberServiceApi.normalRevokeOrder(pkApprove, saOrderExt, null, pkOrderItemList, businessCommissionDTO).getData()) {
                throw new RuntimeException("撤单失败");
            }
        } else {
            // 删除订单
            saOrderExt.setDelFlag(EDelFlag.DELETE.getValue());
            Date currentDate = DateUtils.currentDateTime();
            // 删除发货单
            saDeliverItemsService.deleteSaDeliverItems(saOrderExt.getPkId(), null);
            // 修改订单
            updateSaOrder(pkApprove, saOrderExt, currentDate);
            // 删除订单明细
            if (!saOrderItemsService.updateOrderItems(saOrderExt)) {
                throw new RuntimeException("更新订单失败");
            }
            // 撤销注册订单 单点撤单
            if (ECancelOrderType.SINGLE_CANCEL_ORDER.getValue() == orderCancelParam.getCancelType()) {
                // 单点撤单，变死点
                R<Boolean> tmpR = memberServiceApi.singleRevokeMemberByRegisterOrder(pkApprove, saOrderExt, businessCommissionDTO);
                if (!tmpR.isSuccess()) {
                    throw new RuntimeException("撤单失败 " + tmpR.getMsg());
                }
            } else if (ECancelOrderType.MERGE_CANCEL_ORDER.getValue() == orderCancelParam.getCancelType()) {
                // 合并撤单，撤下面所有
                List<Long> memberList = validateCancelOrderVO.getMemberList().stream().map(OrderCancelRegisterMemberVO::getPkMember).collect(Collectors.toList());
                if (CollectionUtil.isNotEmpty(memberList)) {
                    // 撤销所有订单明细表
                    saOrderItemsService.updateOrderItemsByMemberList(memberList, pkApprove, currentDate);
                    // 撤销所有订单主表
                    baseMapper.updateSaOrderByMember(memberList, pkApprove, currentDate);
                }
                R<Boolean> tmpR = memberServiceApi.mergeRevokeMemberByRegisterOrder(pkApprove, memberList, validateCancelOrderVO.getSaOrderMap(), businessCommissionDTO);
                if (!tmpR.isSuccess()) {
                    throw new RuntimeException("撤单失败 " + tmpR.getMsg());
                }
            } else {
                // 其他撤单 撤销升级订单
                CuMember cuMember = getCuMemberByKey(saOrderExt.getPkMember());
                if (EOrderType.UPGRADE_ORDER.getValue() == saOrderExt.getOrderType()) {
                    // 记录撤单前等级，后续处理使用
                    saOrderExt.setOrderPkGrade(cuMember.getPkSettleGrade());

                    SaOrder updSaOrder = validateCancelOrderVO.getUpdSaOrder();
                    // 计算等级
                    // 获取升级订单
                    // 空单注册，从cu_member_register中获取
                    if (updSaOrder == null) {
                        CuMemberRegister cuMemberRegister = memberServiceApi.queryCuMemberRegister(saOrderExt.getPkMember()).getData();
                        cuMember.setPkRegisterGrade(cuMemberRegister.getPkRegisterGrade());
                        cuMember.setPkSettleGrade(cuMemberRegister.getPkRegisterGrade());
                        cuMember.setConsumeMoney(BigDecimal.ZERO);
                        cuMember.setConsumeAchieve(cuMemberRegister.getConsumeAchieve());

                        CuMemberLevel cuMemberLevel = iCuMemberDetailServiceApi.queryLastManualUpgrade(cuMember.getPkId(), cuMember.getPkSettleCountry()).getData();
                        if (null != cuMemberLevel) {
                            // 存在手动升级
                            cuMember.setPkRegisterGrade(cuMemberLevel.getNewLevel());
                            cuMember.setPkSettleGrade(cuMemberLevel.getNewLevel());
                        }
                    } else {
                        OrderReturn orderReturn = OrderReturn.builder().isEnough(false).build();
                        GradeDTO gradeDTO = revokeSaOrderCalculateGradeDTO(EOrderType.UPGRADE_ORDER.getValue(), cuMember.getPkSettleCountry(), cuMember.getPkId(),
                                validateCancelOrderVO.getUpdSaOrder(), orderReturn);
                        cuMember.setPkRegisterGrade(gradeDTO.getPkId());
                        cuMember.setPkSettleGrade(gradeDTO.getPkId());

                        // 记录原奖衔与新奖衔
                        BdAwards tmpAwards;
                        // 判断奖衔，原奖衔>新奖衔 不进行变奖衔
                        BdAwards oldAwards = awardsServiceApi.getAwardsOne(cuMember.getPkAwards()).getData();
                        BdAwards newAwards = awardsServiceApi.getAwardsOne(gradeDTO.getPkAwards()).getData();
                        if (oldAwards.getAwardsValue() > newAwards.getAwardsValue()) {
                            cuMember.setPkAwards(gradeDTO.getPkAwards());
                            tmpAwards = newAwards;
                        } else {
                            tmpAwards = oldAwards;
                        }
                        // 查询最新一条手动开通奖衔记录
                        CuMemberAwardsExt cuMemberAwardsExt = iCuMemberDetailServiceApi.queryLastManualAwards(cuMember.getPkId(), cuMember.getPkSettleCountry()).getData();
                        if (null != cuMemberAwardsExt) {
                            // 存在手动开奖衔
                            if (cuMemberAwardsExt.getAwardsValue() > tmpAwards.getAwardsValue()) {
                                cuMember.setPkAwards(cuMemberAwardsExt.getNewLevel());
                            }
                        }

                        // 等级对应的结算值
                        cuMember.setRegisterAuthority(gradeDTO.getRegisterAuthority());

                        cuMember.setConsumeMoney(ComputeUtil.computeSubtract(cuMember.getConsumeMoney(), saOrderExt.getOrderAmount()));
                        cuMember.setConsumeAchieve(gradeDTO.getStartValue());
                    }
                }
                if (!memberServiceApi.normalRevokeOrder(pkApprove, saOrderExt, cuMember, null, businessCommissionDTO).getData()) {
                    throw new RuntimeException("撤单失败");
                }
            }
        }
        // 订单撤销成功回退可用量
        try {
            rabbitTemplate.convertAndSend(RabbitMqConstants.ACTIVITY_BACK_EXCHANGE, RabbitMqConstants.ACTIVITY_BACK_KEY, saOrderExt);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    private void updateSaOrder(Long pkApprove, SaOrderExt saOrderExt, Date currentDateTime) {
        UpdateWrapper<SaOrder> updateWrapper = new UpdateWrapper<>();
        updateWrapper.set(SystemFieldConstants.PK_MODIFIED, pkApprove);
        updateWrapper.set(SystemFieldConstants.MODIFIED_TIME, currentDateTime);
        updateWrapper.set(SystemFieldConstants.DEL_FLAG, saOrderExt.getDelFlag());
        updateWrapper.set("ORDER_AMOUNT", saOrderExt.getOrderAmount());
        updateWrapper.set("ORDER_ACHIEVE", saOrderExt.getOrderAchieve());
        updateWrapper.set("UPLOAD_ACHIEVE", saOrderExt.getUploadAchieve());
        updateWrapper.set("ORDER_ASS_ACHIEVE", saOrderExt.getOrderAssAchieve());
        updateWrapper.eq(SystemFieldConstants.PK_ID, saOrderExt.getPkId());
        saOrderExt.setPkModified(pkApprove);
        saOrderExt.setModifiedTime(currentDateTime);
        if (!update(updateWrapper)) {
            throw new RuntimeException("更新订单失败");
        }
    }

    @Override
    public GradeDTO queryGradeConfigByCondition(Integer pkCountry, Integer pkGrade) {
        return saOrderHandle.queryGradeConfigByCondition(pkCountry, pkGrade);
    }

    @Override
    public CuMember obtainLastResettleByRecommend(CuMember cuMember, Boolean isFirstAchieve, Boolean isFirst) {
        // 验证是否首单
        if (isFirst == null) {
            isFirst = validateFirstOrder(cuMember.getPkParent(), cuMember.getPkSettleCountry());
        }
        cuMember = memberAchieveServiceApi.queryCuMemberAchieveByPkMember(cuMember, isFirst, isFirstAchieve).getData();
        // 验证是否推荐过人，没有推荐只能放入极左极下
        return cuMember;
    }

    /**
     * 验证第二部门是否需要验证首单
     *
     * @param pkParent  推荐人
     * @param pkCountry 国家
     */
    @Override
    public boolean validateFirstOrder(Long pkParent, Integer pkCountry) {
        String validateFirstOrder = querySystemConfigByKey(pkCountry, ESystemConfig.FIRST_ORDER.getKey());
        if (EYesNo.YES.getIntValue() == Integer.parseInt(validateFirstOrder)) {
            Integer count = queryCuMemberByPkMember(pkParent);
            return count == 0;
        }
        return false;
    }

    @Override
    public List<SaOrderExt> querySaOrderByTime(Date startDate, Date endDate, String orderCode) {
        return baseMapper.querySaOrderByTime(startDate, endDate, orderCode);
    }

    @Override
    public List<SaOrderExt> querySaOrderByEffectiveDay(Date startDate, Date endDate) {
        return baseMapper.querySaOrderByEffectiveDay(startDate, endDate);
    }

    @Override
    public List<SaOrderExt> queryDeliverySaOrderByDay(Date startDate, Date endDate) {
        return baseMapper.queryDeliverySaOrderByDay(startDate, endDate);
    }

    @Override
    public String querySystemConfigByKey(Integer pkCountry, String key) {
        return systemConfigServiceApi.getBonusSystemConfig(pkCountry, key).getData();
    }

    @Override
    public BigDecimal selectSum() {
        return baseMapper.selectSum();
    }

    @Override
    public SaOrderExt queryOrderByPkId(Long pkId, Integer pkCountry) {
        return baseMapper.queryOrderByPkId(pkId, pkCountry);
    }

    @Override
    public SaOrderExt queryOrderByCode(String orderCode, Integer pkCountry) {
        return baseMapper.queryOrderByCode(orderCode, pkCountry);
    }

    @Override
    public List<SaOrderExt> queryOrderListByCodeList(List<String> orderCodeList, Integer pkCountry) {
        return baseMapper.queryOrderListByCodeList(orderCodeList, pkCountry);
    }

    @Override
    public List<SaOrderExt> queryOrderListByIdList(List<Long> orderIdList, Integer pkCountry) {
        return baseMapper.queryOrderListByIdList(orderIdList, pkCountry);
    }

    @Override
    public List<SaOrderExt> myOrderList(MyOrderParam param, Long memberId, Integer pkCountry) {
        return baseMapper.myOrderList(param, memberId, pkCountry);
    }

    @Override
    public int myOrderNum(List<Integer> statusList, Long memberId, Integer pkCountry) {
        return baseMapper.myOrderNum(statusList, memberId, pkCountry);
    }

    @Override
    public boolean myOrderConfirm(Long pkOrder, Long memberId) {
        // 更新订单明细为已收货
        UpdateWrapper<SaOrderItems> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("PK_ORDER", pkOrder);
        updateWrapper.set("ORDER_STATUS", EOrderStatus.RECEIVED.getValue());
        updateWrapper.set(SystemFieldConstants.PK_MODIFIED, memberId);
        updateWrapper.set(SystemFieldConstants.MODIFIED_TIME, new Date());
        return saOrderItemsService.update(updateWrapper);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public String myOrderCancel(SaOrder saOrder, Long memberId) {
        Date nowDate = new Date();

        // 如果是注册订单，需要校验下面是否有会员
        if (EOrderType.REGISTER_ORDER.getValue() == saOrder.getOrderType()) {
            // 注册类订单，需要校验是否推荐过人或者安置过人，如果有则不允许进行取消
            if (memberServiceApi.checkLowerMember(saOrder.getPkMember()).getData()) {
                // 订单所属会员下存在用户不能取消
                return TransactionUtils.getContent(MemberMsgConstants.EXIST_MEMBER_NOT_CANCEL);
            }
        }

        // 删除订单明细
        UpdateWrapper<SaOrderItems> updateItemsWrapper = new UpdateWrapper<>();
        updateItemsWrapper.eq("PK_ORDER", saOrder.getPkId());
        updateItemsWrapper.set(SystemFieldConstants.DEL_FLAG, EDelFlag.DELETE.getValue());
        updateItemsWrapper.set(SystemFieldConstants.PK_MODIFIED, memberId);
        updateItemsWrapper.set(SystemFieldConstants.MODIFIED_TIME, nowDate);
        saOrderItemsService.update(updateItemsWrapper);

        // 删除订单
        UpdateWrapper<SaOrder> updateOrderWrapper = new UpdateWrapper<>();
        updateOrderWrapper.eq(SystemFieldConstants.PK_ID, saOrder.getPkId());
        updateOrderWrapper.set(SystemFieldConstants.DEL_FLAG, EDelFlag.DELETE.getValue());
        updateOrderWrapper.set(SystemFieldConstants.PK_MODIFIED, memberId);
        updateOrderWrapper.set(SystemFieldConstants.MODIFIED_TIME, nowDate);
        this.update(updateOrderWrapper);

        // 如果是注册订单，需要取消点位
        if (EOrderType.REGISTER_ORDER.getValue() == saOrder.getOrderType()) {
            if (!memberServiceApi.cancelMember(saOrder.getPkMember()).getData()) {
                throw new RuntimeException("取消订单失败");
            }
        }

        return null;
    }

    @Override
    public MyOrderPrintVO orderPrint(String orderCode, Long memberId, Integer pkCountry) {
        return baseMapper.orderPrint(orderCode, memberId, pkCountry);
    }

    @Override
    public List<OrderBusinessVO> queryOrderBusinessList(OrderBusinessParam param, Integer pkCountry) {
        return baseMapper.queryOrderBusinessList(param, pkCountry);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteOrderAndItems(List<Long> orderIdList, Long userId, Integer pkCountry) {
        Date nowDate = new Date();

        // 删除订单
        UpdateWrapper<SaOrder> orderUpdateWrapper = new UpdateWrapper<>();
        orderUpdateWrapper.in(SystemFieldConstants.PK_ID, orderIdList);
        if (null != pkCountry) {
            orderUpdateWrapper.eq(SystemFieldConstants.PK_COUNTRY, pkCountry);
        }
        orderUpdateWrapper.set(SystemFieldConstants.DEL_FLAG, EDelFlag.DELETE.getValue());
        orderUpdateWrapper.set(SystemFieldConstants.PK_MODIFIED, userId);
        orderUpdateWrapper.set(SystemFieldConstants.MODIFIED_TIME, nowDate);
        this.update(orderUpdateWrapper);

        // 删除订单明细
        UpdateWrapper<SaOrderItems> orderItemsUpdateWrapper = new UpdateWrapper<>();
        orderItemsUpdateWrapper.in("PK_ORDER", orderIdList);
        if (null != pkCountry) {
            orderItemsUpdateWrapper.eq(SystemFieldConstants.PK_COUNTRY, pkCountry);
        }
        orderItemsUpdateWrapper.set(SystemFieldConstants.DEL_FLAG, EDelFlag.DELETE.getValue());
        orderItemsUpdateWrapper.set(SystemFieldConstants.PK_MODIFIED, userId);
        orderItemsUpdateWrapper.set(SystemFieldConstants.MODIFIED_TIME, nowDate);
        saOrderItemsService.update(orderItemsUpdateWrapper);
    }

    @Override
    public List<WaresOrderVo> selectByOrderInfoList(WaresOrderParam waresOrderParam) {
        return baseMapper.selectByOrderInfoList(waresOrderParam);
    }

    @Override
    public List<SaOrderExt> queryOrderMemberInfo(List<Integer> orderTypeList, List<Long> pkMemberList, Integer pkCountry) {
        return baseMapper.queryOrderMemberInfo(orderTypeList, pkMemberList, null, pkCountry);
    }

    @Override
    public List<SaOrderItemsExt> queryOrderSelect(OrderSelectParam param, Integer pkCountry) {
        return baseMapper.queryOrderSelect(param, pkCountry);
    }

    private CuMember calculateHaFunMemberGrade(SaOrderExt saOrderExt, CuMember newCuMember) {
        CuMember cuMember = null;
        if (newCuMember != null && Objects.equals(MagicNumberConstants.CHINA_HA_FUN, newCuMember.getPkSettleGrade()) &&
                Objects.equals(CountryConstants.CHINA_COUNTRY, newCuMember.getPkSettleCountry())) {
            int oldLevel = newCuMember.getPkSettleGrade();
            // 封装等级,重新计算会员等级
            setLastCuMemberGrade(newCuMember, saOrderExt);
            // 验证等级，原等级<新等级，才可以进行升级 或者事累计升级
            if (oldLevel < newCuMember.getPkSettleGrade()) {
                cuMember = newCuMember;
            }
        }
        return cuMember;
    }

    @Override
    public Boolean regEmptyOrderApproved(ApprovalBusinessResultDTO approvalBusinessResultDTO) {
        R<CuMemberServiceLog> cuMemberServiceLogR = cuMemberServiceLogServiceApi.selectByBusinessNo(approvalBusinessResultDTO.getBusinessCode());
        OrderBlankRegParams orderBlankRegParams = JSONUtil.toBean(cuMemberServiceLogR.getData().getNewValue(), OrderBlankRegParams.class);
        // 调用空单注册方法
        this.registerEmptyOrder(orderBlankRegParams);
        return true;
    }

    @Override
    public Boolean regEmptyOrderReject(ApprovalBusinessResultDTO approvalBusinessResultDTO) {
        R<CuMemberServiceLog> cuMemberServiceLogR = cuMemberServiceLogServiceApi.selectByBusinessNo(approvalBusinessResultDTO.getBusinessCode());
        OrderBlankRegParams orderBlankRegParams = JSONUtil.toBean(cuMemberServiceLogR.getData().getNewValue(), OrderBlankRegParams.class);
        CuMemberServiceLog memberLog = new CuMemberServiceLog();
        memberLog.setBusinessNo(approvalBusinessResultDTO.getBusinessCode());
        memberLog.setPkModified(approvalBusinessResultDTO.getLoginUser().getUserId());
        memberLog.setModifiedTime(DateUtils.currentDateTime());
        memberLog.setApproveStatus(EApproveStatus.REJECTED.getValue());
        cuMemberServiceLogServiceApi.updateByBusinessNo(memberLog);
        List<MemberAmountDTO> memberAmountDTOList = new ArrayList<>();
        MemberAmountDTO memberAmountDTO = new MemberAmountDTO();
        memberAmountDTO.setPkMember(approvalBusinessResultDTO.getLoginUser().getUserId());
        if (StringUtils.isNotNull(orderBlankRegParams.getCost())) {
            memberAmountDTO.setTradeAmount(orderBlankRegParams.getCost());
        } else {
            memberAmountDTO.setTradeAmount(new BigDecimal(0));
        }
        memberAmountDTOList.add(memberAmountDTO);
        //退款
        BusinessCommissionDTO businessCommissionDTO = new BusinessCommissionDTO();
        businessCommissionDTO.setPkCountry(orderBlankRegParams.getPkCountry());
        businessCommissionDTO.setMemberAmountDTOList(memberAmountDTOList);
        businessCommissionDTO.setTradeType(EApprovalBusiness.UPDATE_SETTLE_COUNTRY.getValue());
        R<Boolean> b = memberTradeServiceApi.businessCommissionSubmit(businessCommissionDTO);
        if (!b.getData()) {
            throw new ServiceException(TransactionUtils.getContent(ConfigMsgConstants.MEMBER_UPDATE_CODE_MONEY));
        }
        return true;
    }

    @Override
    public void closeOrder() {
        R<Map<String, String>> configMap = systemConfigServiceApi.getSystemConfig();
        Map<String, String> configDate = configMap.getData();
        R<Map<Integer, BdCountry>> all = countryServiceApi.getAllCountryMap();
        Set<Map.Entry<Integer, BdCountry>> entries = all.getData().entrySet();

        for (Map.Entry<Integer, BdCountry> entry : entries) {
            BdCountry country = entry.getValue();
            for (int i = 0; i < ESystemConfig.getPayMentTimeList().size(); i++) {
                String date = configDate.get(country.getPkId() + ESystemConfig.getPayMentTimeList().get(i).getKey());
                // 查询可取消订单
                if (StringUtils.isNotBlank(date)) {
                    Integer orderType = null;
                    if (ESystemConfig.getPayMentTimeList().get(i).getKey().equals(ESystemConfig.REGISTER_ORDER_TIME.getKey())) {
                        // 注册专区
                        orderType = EOrderType.REGISTER_ORDER.getValue();
                    } else if (ESystemConfig.getPayMentTimeList().get(i).getKey().equals(ESystemConfig.UPGRADE_ORDER_TIME.getKey())) {
                        // 升级专区
                        orderType = EOrderType.UPGRADE_ORDER.getValue();
                    } else if (ESystemConfig.getPayMentTimeList().get(i).getKey().equals(ESystemConfig.REPURCHASE_ORDER_TIME.getKey())) {
                        // 复购专区时间
                        orderType = EOrderType.REPURCHASE_ORDER.getValue();
                    }
                    ESpecialAreaTime specialAreaTime = ESpecialAreaTime.getSpecialAreaTime(date);
                    if (orderType != null && specialAreaTime != null) {
                        List<SaOrder> orderList = baseMapper.selectCancelableOrder(country.getPkId(), specialAreaTime.getAttributeValue(), orderType);
                        if (orderList.size() > 0) {
                            baseMapper.closeOrder(country.getPkId(), specialAreaTime.getAttributeValue(), orderType);
                            saOrderItemsService.closeOrder(country.getPkId(), specialAreaTime.getAttributeValue(), orderType);
                        }
                    }
                }
            }
        }
    }

    @Override
    public BigDecimal selectBySumPv(Date startPayDate, Date endPayDate, Long memberId) {
        return baseMapper.selectBySumPv(startPayDate, endPayDate, memberId);
    }

    @Override
    public BigDecimal selectBySumAmount(Date startPayDate, Date endPayDate, Long memberId) {
        return baseMapper.selectBySumAmount(startPayDate, endPayDate, memberId);
    }

    @Override
    public List<SaOrder> querySaOrderByOrderType(String payTime) {
        return baseMapper.querySaOrderByOrderType(payTime);
    }

    @Override
    public List<Integer> queryOrderType(Long memberId, Integer pkCountry) {
        return baseMapper.queryOrderType(memberId, pkCountry);
    }

    @Override
    public void waresSalesAccrual(List<WaresNumberParam> waresNumberParamList) {
        try {
            if (waresNumberParamList.size() > 0) {
                waresExtendService.updateWaresSalesAccrual(waresNumberParamList);
            }
        } catch (Exception e) {
            log.error("waresSalesAccrual error!", e);
        }
    }

    @Override
    public List<DeliverSecondVO> secondList(DeliverSecondParam param, Integer pkCountry) {
        return baseMapper.secondList(param, pkCountry);
    }

    @Override
    public CuMemberMyMarketVO selectMyMarket(Long pkMember, Integer pkCountry) {
        //查询全国市场
        CuMemberMyMarketVO cuMemberMyMarketVO = baseMapper.selectMyMarket(null, pkCountry);
        CountryDTO country = countryServiceApi.getCountry(pkCountry).getData();
        //查询市场分布
        List<CuMemberMyMarketDetailVO> cuMemberMyMarketDetailVOList = baseMapper.selectMyMarketDetail(pkMember, pkCountry);
        cuMemberMyMarketVO.setMyMarketDetailVOList(cuMemberMyMarketDetailVOList);
        //查询我的市场
        if (CollectionUtil.isNotEmpty(cuMemberMyMarketDetailVOList)) {
            List<Integer> countryNmus = cuMemberMyMarketDetailVOList.stream().map(CuMemberMyMarketDetailVO::getPkCountry).distinct().collect(Collectors.toList());
            cuMemberMyMarketVO.setMyCountryNum(countryNmus.size());
            cuMemberMyMarketVO.setMyRegionNum(cuMemberMyMarketDetailVOList.size());
        } else {
            cuMemberMyMarketVO.setMyCountryNum(1);
            cuMemberMyMarketVO.setMyRegionNum(0);
        }
        //海外暂时点亮国家
        if (!pkCountry.equals(CountryConstants.CHINA_COUNTRY)) {
            cuMemberMyMarketVO.setMyMarketDetailVOList(Collections.singletonList(CuMemberMyMarketDetailVO.builder().lightName(country.getLightName()).build()));
        }
        return cuMemberMyMarketVO;
    }

    @Override
    public SaOrder queryOrderTotalAchieveByTime(Date startDate, Date endDate) {
        List<Integer> orderTypeList = new ArrayList<>();
        orderTypeList.add(EOrderType.REGISTER_ORDER.getValue());
        orderTypeList.add(EOrderType.UPGRADE_ORDER.getValue());
        QueryWrapper<SaOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("sum(order_amount) orderAmount,sum(order_achieve) orderAchieve")
                .eq(SaOrderFieldConstants.ORDER_STATUS, EOrderStatus.PAY.getValue())
                .in(SaOrderFieldConstants.ORDER_TYPE, orderTypeList)
                .ge(SaOrderFieldConstants.PAY_TIME, startDate)
                .lt(SaOrderFieldConstants.PAY_TIME, endDate);
        return baseMapper.selectOne(queryWrapper);
    }

    @Override
    public List<Long> querySeqList(Integer param) {
        return baseMapper.querySeqList(param);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int insertBach(List<SaOrder> orderList, List<SaOrderItems> orderItemsList) {
        int i = baseMapper.insertBach(orderList);
        if (i > 0 && CollectionUtil.isNotEmpty(orderItemsList)) {
            saOrderItemsService.insertBach(orderItemsList);
        }
        return i;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int insertUnrealOrderBach(List<SaOrder> orderList) {
        return baseMapper.insertUnrealOrderBach(orderList);
    }

    @Override
    public List<SaOrderExt> myStoreOrderList(MyOrderParam param, Integer pkStore, Integer pkCountry) {
        return baseMapper.myStoreOrderList(param, pkStore, pkCountry);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long saveOrderInfo(SaOrder saOrder, SaOrderItems orderItems) {
        save(saOrder);
        orderItems.setPkOrder(saOrder.getPkId());
        saOrderItemsService.save(orderItems);
        return saOrder.getPkId();
    }

    @Override
    public SaOrderExt queryUpgradeAmountAndAchieve(Long pkMember) {
        return baseMapper.queryUpgradeAmountAndAchieve(pkMember);
    }

    @Override
    public BigDecimal getMemberOrderAchieve(Long pkMember) {
        return baseMapper.getMemberOrderAchieve(pkMember);
    }

    @Override
    public List<SaOrderExt> querySaOrderByDeliverList(List<SaDeliverItemsExt> deliverItemExtList) {
        return baseMapper.querySaOrderByDeliverList(deliverItemExtList);
    }

    @Override
    public int getStoreNum(List<Integer> statusList, Integer pkStore, Integer pkCountry) {
        return baseMapper.getStoreNum(statusList, pkStore, pkCountry);
    }

    @Override
    public SaOrder querySaOrderExtByPkId(Long pkId) {
        return baseMapper.querySaOrderExtByPkId(pkId);
    }

    @Override
    public List<SaOrderExt> queryStoreSaOrderByParam(OrderQueryParam orderQueryParam) {
        if (orderQueryParam.getCreationTimeEnd() != null) {
            orderQueryParam.setCreationTimeEnd(DateUtils.afterDate(1, ChronoUnit.DAYS, orderQueryParam.getCreationTimeEnd()));
        }
        if (orderQueryParam.getEndDate() != null) {
            orderQueryParam.setEndDate(DateUtils.afterDate(1, ChronoUnit.DAYS, orderQueryParam.getEndDate()));
        }
        return baseMapper.queryStoreSaOrderByParam(orderQueryParam);
    }

    @Override
    public boolean checkRenewalAmount(CuMember cuMember, SaOrderExt saOrder) {
        if (null == cuMember) {
            cuMember = getCuMemberByKey(saOrder.getPkMember());
        }
        // 汇率
        R<CurrencyDTO> currencyDto = currencyServiceApi.getCurrency(cuMember.getPkSettleCountry());
        BigDecimal inExchangeRate = currencyDto.getData().getInExchangeRate();

        // 会员结算等级
        GradeDTO gradeDTO = gradeServiceApi.getGrade(cuMember.getPkSettleGrade()).getData();
        // 年包价格（美元 * 汇率）
        BigDecimal renewAmount = gradeDTO.getRenewAmount().multiply(inExchangeRate);

        return saOrder.getOrderAmount().compareTo(renewAmount) >= 0;
    }

}
