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.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hzs.activity.pick.service.IAcRetailPickService;
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.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.business.UpPolicyCurrency;
import com.hzs.common.domain.member.detail.CuMemberLevel;
import com.hzs.common.domain.member.detail.CuMemberServiceLog;
import com.hzs.common.domain.member.ext.CuMemberAccountExt;
import com.hzs.common.domain.member.ext.CuMemberExt;
import com.hzs.common.domain.retail.member.ext.CuMemberRetailRegionExt;
import com.hzs.common.domain.sale.ext.*;
import com.hzs.common.domain.sale.order.*;
import com.hzs.common.domain.sale.wares.BdWares;
import com.hzs.common.domain.system.base.BdCountry;
import com.hzs.common.domain.system.base.ext.BdProductStorehouseExt;
import com.hzs.common.domain.system.config.BdAwards;
import com.hzs.common.domain.system.config.BdGrade;
import com.hzs.common.domain.third.pay.ext.TOnlineRefundExt;
import com.hzs.common.security.service.UserTokenService;
import com.hzs.common.security.utils.SecurityUtils;
import com.hzs.common.util.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.service.ISaDeliverItemsService;
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.*;
import com.hzs.system.base.IAreaServiceApi;
import com.hzs.system.base.ICountryServiceApi;
import com.hzs.system.base.ICurrencyServiceApi;
import com.hzs.system.base.ISystemConfigServiceApi;
import com.hzs.system.base.dto.CurrencyDTO;
import com.hzs.system.config.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.math.RoundingMode;
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
    IAreaServiceApi areaServiceApi;
    @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
    IMemberTradeServiceApi memberTradeServiceApi;
    @DubboReference
    ICuMemberDetailServiceApi iCuMemberDetailServiceApi;
    @DubboReference
    IGradeServiceApi iGradeServiceApi;

    @Autowired
    private IBdWaresService waresService;
    @Autowired
    private IBdWaresExtendService waresExtendService;
    @Autowired
    private SaOrderHandle saOrderHandle;
    @Autowired
    private ISaOrderItemsService saOrderItemsService;
    @Autowired
    private UserTokenService userTokenService;
    @Autowired
    private IBdProductExtendService iBdProductExtendService;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private IBdWaresSpecsRelationService waresSpecsRelationService;
    @Autowired
    private ISaDeliverItemsService saDeliverItemsService;
    @Autowired
    private IAcRetailPickService iAcRetailPickService;
    @Autowired
    private ISaOrderWaresLimitService iSaOrderWaresLimitService;

    @Autowired
    private IOrderBusinessService orderBusinessService;
    @Autowired
    private ISaOrderChargeLogService saOrderChargeLogService;
    @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, List<Integer> orderTypeList, List<Integer> notOrderType) {
        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);
        }
        if (CollectionUtil.isNotEmpty(orderTypeList)) {
            queryWrapper.in(SaOrder::getOrderType, orderTypeList);
        }
        if (CollectionUtil.isNotEmpty(notOrderType)) {
            queryWrapper.notIn(SaOrder::getOrderType, notOrderType);
        }
        queryWrapper.orderByDesc(SaOrder::getPayTime);
        return baseMapper.selectList(queryWrapper);
    }

    @Override
    public Integer querySaleOrderByPkMember(Integer pkCountry, Long pkMember) {
        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);
        }
        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.getMemberById(pkId).getData();
    }

    @Override
    public CuMember getCuMemberByCode(String code) {
        return memberServiceApi.getMemberByCode(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();

        // 海粉只有升级可以用奖金币，其他专区只能用现金币，验证会员等级，会员是海粉的话除现金账户，其他账户置为0
        CuMember cuMember = getCuMemberByKey(saOrder.getPkMember());
        if (EOrderType.UPGRADE_ORDER.getValue() != saOrder.getOrderType() &&
                cuMember != null && Objects.equals(MagicNumberConstants.CHINA_HA_FUN, cuMember.getPkSettleGrade()) &&
                Objects.equals(CountryConstants.CHINA_COUNTRY, cuMember.getPkSettleCountry())) {
            cuMemberAccount.setAccount1(BigDecimal.ZERO);
            cuMemberAccount.setAccount3(BigDecimal.ZERO);
            cuMemberAccount.setAccount4(BigDecimal.ZERO);
            cuMemberAccount.setAccount5(BigDecimal.ZERO);
            cuMemberAccount.setAccount6(BigDecimal.ZERO);
            cuMemberAccount.setAccount7(BigDecimal.ZERO);
            cuMemberAccount.setAccount8(BigDecimal.ZERO);
            cuMemberAccount.setAccount9(BigDecimal.ZERO);
            cuMemberAccount.setAccount10(BigDecimal.ZERO);
        }

        // 订单创建人
        CuMember creator = getCuMemberByKey(saOrder.getPkCreator());
        cuMemberAccount.setMemberCode(creator.getMemberCode());

        // 查询专区所属币种
        List<AreaCurrencyDTO> areaCurrencyDTOList = areaCurrencyServiceApi.queryAreaCurrencyByCondition(saOrder.getOrderType(), cuMemberAccount.getPkCountry()).getData();

        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(saOrder, orderItemList, cuMemberAccount, orderItemPayMoney, BigDecimal.ZERO, areaCurrencyDtoList)) {
                        return null;
                    }
                }
            }
        }

        handleSaOrderAmount(saOrder, orderItemList, cuMemberAccount, payMoney, postage, areaCurrencyDTOList);

        if (null != cuMemberAccount.getPayAccount5() && cuMemberAccount.getPayAccount5().compareTo(BigDecimal.ZERO) > 0) {
            // 2024.09.24 重消专区可以使用其它币种，此处只记录重消币，其它币种需要单独计算统计
            saOrder.setConsumeAmount(cuMemberAccount.getPayAccount5());
        }

        return cuMemberAccount;
    }

    private Boolean handleSaOrderAmount(SaOrder saOrder, List<SaOrderItems> orderItemList,
                                        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;

        // 2024.05.30 与业务确认，政策币个人配置优先特殊配置
        // 默认情况下，注册、升级专区才能使用政策币，其它专区都是走特殊业务处理
        // 个人政策币配置
        UpPolicyCurrency upPolicyCurrency = null;
        if (EOrderType.REGISTER_ORDER.getValue() == saOrder.getOrderType()
                || EOrderType.UPGRADE_ORDER.getValue() == saOrder.getOrderType()) {
            if (cuMemberAccount.getPayAccount3Flag()) {
                // 验证是否有政策币权限
                List<CuMemberServiceLog> cuMemberServiceLogs = cuMemberServiceLogServiceApi.queryMaxCuMemberServiceLog(cuMemberAccount.getPkMember(), Collections.singletonList(EApprovalBusiness.POLICY_CURRENCY_YES_NO.getValue()));
                if (CollectionUtil.isNotEmpty(cuMemberServiceLogs)) {
                    Map<Integer, CuMemberServiceLog> cuMemberServiceLogMap = new HashMap<>(ComputeUtil.mapInitCapacity(cuMemberServiceLogs.size()));
                    cuMemberServiceLogs.forEach(serviceLog -> cuMemberServiceLogMap.put(serviceLog.getEditType(), serviceLog));

                    try {
                        upPolicyCurrency = JSONUtil.toBean(cuMemberServiceLogMap.get(EApprovalBusiness.POLICY_CURRENCY_YES_NO.getValue()).getNewValue(), UpPolicyCurrency.class);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }

        for (AreaCurrencyDTO areaCurrencyDTO : areaCurrencyDTOList) {
            // 开始扣款
            // 待支付金额>0进行扣减
            if (ComputeUtil.compareValue(payMoney)) {
                // 获得特殊处理
                // 判断比例是否 > 0, 为强制扣除金额 ，强制扣除金额不满足，直接支付失败
                if (!ComputeUtil.compareValue(areaCurrencyDTO.getDeductRatio())) {
                    // 支付比例为0处理
                    // 最大支付金额
                    if (null != areaCurrencyDTO.getDeductMaxRatio()
                            && areaCurrencyDTO.getDeductMaxRatio().compareTo(BigDecimal.ZERO) > 0) {
                        // 并且有最大支付比例也不为0，则需要进行使用限制
                        areaCurrencyDTO.setDeductMaxRatioAmount(ComputeUtil.computeDivide(original.multiply(areaCurrencyDTO.getDeductMaxRatio()), BigDecimal.valueOf(100)));
                    }
                    payMoney = saOrderHandle.subtract(payMoney, cuMemberAccount, areaCurrencyDTO);
                } else {
                    // 政策币单独处理 政策币需要根据配置来进行处理
                    if (EAccount.POLICY.getValue() == areaCurrencyDTO.getFieldValue()) {
                        // 没有前置特殊政策币处理
                        if (null == areaCurrencyDTO.getSpecialFlag() || !areaCurrencyDTO.getSpecialFlag()) {
                            areaCurrencyDTO.setDeductRatio(BigDecimal.ZERO);
                        }

                        if (upPolicyCurrency != null) {
                            // 如果有政策币则进行处理
                            if (EYesNo.YES.getIntValue() == upPolicyCurrency.getEnableStatus()) {
                                // 启用则取值处理
                                areaCurrencyDTO.setDeductRatio(upPolicyCurrency.getDeductMoney() == null ? areaCurrencyDTO.getDeductRatio() : upPolicyCurrency.getDeductMoney());
                            } else {
                                // 禁用则不能使用
                                areaCurrencyDTO.setDeductRatio(BigDecimal.ZERO);
                            }
                        }
                    } else if (EAccount.CASH.getValue() == areaCurrencyDTO.getFieldValue()) {
                        if (upPolicyCurrency != null) {
                            // 有个人政策币，则不走特殊政策币配置的现金币比例
                            areaCurrencyDTO.setDeductRatio(areaCurrencyDTO.getOriginalDeductRatio());
                        }
                    }

                    // 最小支付金额
                    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);
            }
            // 每次扣除后判断是否扣除完毕，扣除完毕结束
            if (flag && payMoney.compareTo(BigDecimal.ZERO) == 0 && postage.compareTo(BigDecimal.ZERO) == 0) {
                cuMemberAccount.setIsPayment(Boolean.TRUE);
                break;
            }
        }
        return flag;
    }

    /**
     * 会员端的报单信息
     * 点击确认订单按钮
     * 将会员端传递过来的保单信息封装为订单信息,待支付时直接入库，直接保存时先放入redis暂存，待支付时在保存入库
     *
     * @param orderParam
     */
    @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).getData();
        } else if (EOrderType.REGISTER_ORDER.getValue() == orderParam.getSpecialArea()) {
            // 2023.10.16按最新需求，注册订单需要在支付前需要显示会员编号
            cuMember = memberServiceApi.createRegisterMemberCode(cuMember).getData();
        }

        SaOrderExt saOrderExt = packageWholeSaOrder(orderParam, cuMember);
        if (setLastCuMemberGrade(cuMember, saOrderExt)) {
            return false;
        }
        // 保存 用户、订单、订单明细 分布式事务
        // 启用待支付，或者海粉订单
        if (isToBePay && !orderParam.getIsHaiFun()) {
            processOrder(saOrderExt);
            // 调用其他服务保存会员信息、会员注册信息
            R<Boolean> saveResult = memberServiceApi.saveMember(cuMember);
            if (saveResult.isSuccess()) {
                if (!saveResult.getData()) {
                    log.error("confirmRegSaOrderByOrderParam 保存会员失败.");
                    throw new ServiceException("保存会员失败.");
                }
            } else {
                log.error("confirmRegSaOrderByOrderParam 保存会员失败. {}", saveResult.getMsg());
                throw new ServiceException("保存会员失败.");
            }
        } else {
            redisService.setCacheObject(CacheConstants.TEMP_ORDER + orderParam.getCenterCodeId() + orderParam.getOrderCode(), saOrderExt, CacheConstants.MEMBER_REFRESH_TIME, TimeUnit.MINUTES);
            orderParam.setMemberCode(cuMember.getMemberCode());
            orderParam.setPkGrade(cuMember.getPkSettleGrade());
        }
        redisService.setCacheObject(CacheConstants.TEMP_PARAM + orderParam.getCenterCodeId() + orderParam.getOrderCode(), orderParam, CacheConstants.WARES_REFRESH_TIME, TimeUnit.DAYS);
        return true;
    }

    @Override
    public Boolean confirmSelfFunOrderByOrderParam(OrderParam orderParam, CuMember cuMember) {
        // 获取会员编号、会员主键
        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.MINUTES);
        orderParam.setMemberCode(cuMember.getMemberCode());
        orderParam.setPkGrade(cuMember.getPkSettleGrade());
        redisService.setCacheObject(CacheConstants.TEMP_PARAM + orderParam.getCenterCodeId() + orderParam.getOrderCode(), orderParam, CacheConstants.MEMBER_REFRESH_TIME, TimeUnit.MINUTES);
        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).getData();
        return cuMember;
    }

    /**
     * 设置会员最终的等级
     *
     * @param cuMember   会员
     * @param saOrderExt 订单
     * @return boolean
     */
    @Override
    public Boolean setLastCuMemberGrade(CuMember cuMember, SaOrder saOrderExt) {
        GradeDTO gradeDTO = calculateGradeDTO(saOrderExt.getOrderType(), cuMember.getPkSettleCountry(), cuMember.getPkId(), saOrderExt);
        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());
                // 获取推荐人可以推荐的等级
                GradeDTO tmpGradeDTO = gradeDTO;
                if (validateGradeDTO == null || validateGradeDTO.getBdGradeScopeExtList() == null ||
                        validateGradeDTO.getBdGradeScopeExtList().stream().noneMatch(bdGradeScope -> tmpGradeDTO.getPkId().equals(bdGradeScope.getPkScope()))) {
                    return true;
                }
            }
        }

        // 2023.11.29 奖衔处理提出，必有默认，防止出现奖衔为0的情况
        Integer pkAwards = cuMember.getPkAwards();
        cuMember.setPkRegisterGrade(gradeDTO.getPkId());
        cuMember.setPkSettleGrade(gradeDTO.getPkId());
        cuMember.setPkSettleGradeValue(gradeDTO.getGradeValue());
        // 判断奖衔，原会员有奖衔的话判断哪个大，使用大的
        if (pkAwards != null && gradeDTO.getGradeValue() != null) {
            BdAwards bdAwards = awardsServiceApi.getAwardsOne(pkAwards).getData();
            BdAwards newAwards = awardsServiceApi.getAwardsOne(gradeDTO.getPkAwards()).getData();
            if (bdAwards.getAwardsValue() < newAwards.getAwardsValue()) {
                cuMember.setPkAwards(gradeDTO.getPkAwards());
            }
        } else {
            cuMember.setPkAwards(gradeDTO.getPkAwards());
        }
        // 等级对应的结算值
        cuMember.setConsumeMoney(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;
        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 if (EOrderType.CONSUME_ORDER.getValue() == specialArea) {
            confirmPay = querySystemConfigByKey(pkCountry, ESystemConfig.CONSUME_ORDER_CONFIRM_PAY.getKey());
        } else if (EOrderType.MALL_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 if (EOrderType.CONSUME_ORDER.getValue() == specialArea) {
                timeType = querySystemConfigByKey(pkCountry, ESystemConfig.CONSUME_ORDER_TIME.getKey());
            } else if (EOrderType.MALL_ORDER.getValue() == specialArea) {
                timeType = querySystemConfigByKey(pkCountry, ESystemConfig.REGISTER_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 支付账户信息
     */
    @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);
            saOrderExt.setPkModified(pkCreator);
            saOrderExt.setModifiedTime(currentDateTime);
            for (SaOrderItems saOrderItems : saOrderExt.getOrderItemsList()) {
                saOrderItems.setPkModified(pkCreator);
                saOrderItems.setModifiedTime(currentDateTime);
                saOrderItems.setOrderStatus(EOrderStatus.PAY.getValue());
            }

            // 更新订单信息
            updateSaOrder(saOrderExt);
        } else {
            newCuMember.setConsumeMoney(BigDecimal.ZERO);
            newCuMember.setConsumeAchieve(BigDecimal.ZERO);
            if (setLastCuMemberGrade(newCuMember, saOrderExt)) {
                return false;
            }
            if (isHaiFun) {
                if (null == newCuMember.getPkPlaceParent()
                        || null == newCuMember.getPlaceDept()) {
                    // 2024.01.13 当安置人和安置部门为空时，则进行重新上树
                    CuMember cuMember = repeatTry(newCuMember, Boolean.FALSE);
                    newCuMember.setPkPlaceParent(cuMember.getPkPlaceParent());
                    newCuMember.setPlaceDept(cuMember.getPlaceDept());
                }
                isToBePay = false;
            }
            newCuMember.setCreationTime(currentDateTime);
            saOrderExt.setCreationTime(currentDateTime);

            for (SaOrderItems saOrderItems : saOrderExt.getOrderItemsList()) {
                saOrderItems.setCreationTime(saOrderExt.getCreationTime());
                saOrderItems.setOrderStatus(EOrderStatus.PAY.getValue());
            }

            // 保存订单信息
            processOrder(saOrderExt);
        }

        // 2024.05.29 会员续约需求，【有效期】为购买时间次年的上月最后一天
        newCuMember.setExpireDate(DateUtils.beforeMonthLastDate(DateUtils.addYears(currentDateTime, 1)));
        // 【休止期】普通会员6个月，奖衔会员12个月（先按6个月来，后续MQ会统一处理同姓名同手机号会员）
        newCuMember.setStopDate(DateUtils.addMonths(newCuMember.getExpireDate(), 6));

        // 调用其他服务保存会员信息、会员注册信息
        R<Boolean> saveResult = memberServiceApi.saveMember(newCuMember, saOrderExt, isToBePay, cuMemberAccountExt);
        if (saveResult.isSuccess()) {
            if (!saveResult.getData()) {
                log.error("payRegSaOrder 保存会员失败!.");
                throw new ServiceException("保存会员失败!.");
            }
        } else {
            log.error("payRegSaOrder 保存会员失败!.，{}", saveResult.getMsg());
            throw new ServiceException("保存会员失败!.");
        }

        try {
            rabbitTemplate.convertAndSend(RabbitMqConstants.ACTIVITY_EXCHANGE, RabbitMqConstants.ACTIVITY_KEY, saOrderExt);

            if (EOrderType.REGISTER_ORDER.getValue() == saOrderExt.getOrderType()) {
                // 2024.06.07 进行修改，首购统一推送消息，后面根据业务不同进行分队列消费
                rabbitTemplate.convertAndSend(RabbitMqConstants.MEMBER_FIRST_EXCHANGE, RabbitMqConstants.MEMBER_FIRST_KEY, saOrderExt);
            }
        } catch (Exception e) {
            log.error("payRegSaOrder 发送短信或推送MQ失败，", e);
        }
        return Boolean.TRUE;
    }

    /**
     * 尝试重新换位置
     *
     * @param newCuMember 修改的会员
     */
    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 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());
        });
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean payUpgradeSaOrder(SaOrderExt saOrderExt, CuMemberAccountExt cuMemberAccountExt) {
        CuMember cuMember = getCuMemberByKey(saOrderExt.getPkMember());
        GradeDTO oldGradeDTO = gradeServiceApi.getGrade(cuMember.getPkSettleGrade()).getData();
        // 封装等级,重新计算会员等级
        if (setLastCuMemberGrade(cuMember, saOrderExt)) {
            return false;
        }
        // 验证等级，原等级<新等级，才可以进行升级 或者事累计升级
        String upgradeWay = querySystemConfigByKey(saOrderExt.getPkCountry(), ESystemConfig.UPGRADE_WAY.getKey());
        if (oldGradeDTO.getGradeValue() >= cuMember.getPkSettleGradeValue() && !Objects.equals(Integer.toString(EUpgradeWay.TOTAL.getValue()), upgradeWay)) {
            return false;
        }
        // 保存订单
        encapsulationSaOrder(saOrderExt);

        // 更新订单信息
        updateSaOrder(saOrderExt);
        // 处理会员信息，更新会员等级,扣款
        R<Boolean> saveResult = memberServiceApi.saveMember(cuMember, saOrderExt, cuMemberAccountExt);
        if (saveResult.isSuccess()) {
            if (!saveResult.getData()) {
                log.error("payUpgradeSaOrder 保存会员失败!!!");
                throw new ServiceException("保存会员失败!!!");
            }
        } else {
            log.error("payUpgradeSaOrder 保存会员失败!!!{}", saveResult.getMsg());
            throw new ServiceException("保存会员失败!!!");
        }
        try {
            rabbitTemplate.convertAndSend(RabbitMqConstants.ACTIVITY_EXCHANGE, RabbitMqConstants.ACTIVITY_KEY, saOrderExt);

            if (EOrderType.UPGRADE_ORDER.getValue() == saOrderExt.getOrderType()) {
                // 2024.06.07 进行修改，首购统一推送消息，后面根据业务不同进行分队列消费
                rabbitTemplate.convertAndSend(RabbitMqConstants.MEMBER_FIRST_EXCHANGE, RabbitMqConstants.MEMBER_FIRST_KEY, saOrderExt);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean confirmRepurchaseSaOrder(OrderParam orderParam) {
        boolean isToBePay = getIsToBePayByOrderType(orderParam.getPkSettleCountry(), orderParam.getSpecialArea());
        CuMember cuMember;
        if (EOrderType.UPGRADE_ORDER.getValue() == orderParam.getSpecialArea()
                || EOrderType.REPURCHASE_ORDER.getValue() == orderParam.getSpecialArea()) {
            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() == orderParam.getSpecialArea()) {
            if (setLastCuMemberGrade(cuMember, saOrderExt)) {
                return false;
            }
        }

        if (isToBePay) {
            processOrder(saOrderExt);
        } else {
            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.WARES_REFRESH_TIME, TimeUnit.DAYS);
        return true;
    }

    /**
     * 支付复购订单
     *
     * @param saOrderExt         订单
     * @param cuMemberAccountExt 会员账户
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean payRepurchaseSaOrder(SaOrderExt saOrderExt, CuMemberAccountExt cuMemberAccountExt) {
        // 保存订单
        encapsulationSaOrder(saOrderExt);

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

        // 处理会员信息，更新会员等级,扣款
        CuMember member = getCuMemberByKey(saOrderExt.getPkMember());
        CuMember cuMember = calculateHaFunMemberGrade(saOrderExt, member);

        R<Boolean> saveResult = memberServiceApi.saveMember(cuMember, saOrderExt, cuMemberAccountExt);
        if (saveResult.isSuccess()) {
            if (!saveResult.getData()) {
                log.error("payRepurchaseSaOrder 保存订单失败!");
                throw new ServiceException("保存订单失败!");
            }
        } else {
            log.error("payRepurchaseSaOrder 保存订单失败! {}", saveResult.getMsg());
            throw new ServiceException("保存订单失败!");
        }
        return true;
    }

    /**
     * 封装整个订单
     *
     * @param orderParam 参数
     * @param cuMember   会员
     */
    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);
        // 封装订单明细（2024.02.02添加处理订单扩展类型）
        saOrderHandle.packSaOrderItems(cuMember, saOrderExt, orderParam);
        // 第二次封装订单，根据明细表计算订单主表金额、业绩,处理明细仓库
        // key为产品id
        List<Integer> productIdList = new ArrayList<>();
        saOrderExt.getOrderItemsList().forEach(saOrderItems -> {
            saOrderExt.setPkRate(saOrderItems.getPkRate());
            if (EYesNo.YES.getIntValue() == saOrderItems.getIsGift()) {
                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()));
            productIdList.add(saOrderItems.getPkProduct());
        });

        if (CountryConstants.CHINA_COUNTRY.equals(saOrderExt.getPkCountry())) {
            // 中国金额四舍五入保留2位小数
            saOrderExt.setOrderAmount(saOrderExt.getOrderAmount().setScale(2, RoundingMode.HALF_UP));
        }

        if (productIdList.size() > 0 && saOrderExt.getRecProvince() != null) {
            // 根据产品，先查看是否由仓库，有仓库的话修改仓库
            List<BdProductStorehouseExt> bdProductStorehouseList = areaServiceApi.queryBdProductStorehouseByCondition(productIdList, saOrderExt.getRecProvince()).getData();
            Map<Integer, BdProductStorehouseExt> bdProductStorehouseMap = new HashMap<>();
            if (CollectionUtil.isNotEmpty(bdProductStorehouseList)) {
                bdProductStorehouseList.forEach(bdProductStorehouse -> bdProductStorehouseMap.put(bdProductStorehouse.getPkProduct(), bdProductStorehouse));
                for (SaOrderItems saOrderItems : saOrderExt.getOrderItemsList()) {
                    if (bdProductStorehouseMap.containsKey(saOrderItems.getPkProduct())) {
                        BdProductStorehouseExt bdProductStorehouseExt = bdProductStorehouseMap.get(saOrderItems.getPkProduct());
                        saOrderItems.setPkStorehouse(bdProductStorehouseExt.getPkStorehouse().intValue());
                    }
                }
            }
        }
        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);
        // 注册订单、嗨粉订单直接查询出会员等级
        if (orderParam.getSpecialArea().equals(EOrderType.REGISTER_ORDER.getValue())) {
            orderReturn.setIsEnough(Boolean.TRUE);
        }
        if (orderParam.getIsEnough() != null && orderParam.getIsEnough()) {
            orderReturn.setIsEnough(Boolean.TRUE);
            CuMember member = getCuMemberByKey(orderParam.getCenterCodeId());
            GradeDTO grade = gradeServiceApi.getGrade(member.getPkSettleGrade()).getData();
            orderReturn.setPkGrade(grade.getPkTransaction());
            return orderReturn;
        }
        // 验证等级是否满足条件
        if (!orderReturn.getIsEnough()) {
            CuMember member;
            if (null != orderParam.getUpgradeMemberCodeTmp()) {
                member = getCuMemberByCode(orderParam.getUpgradeMemberCodeTmp());
            } else {
                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) {
        BigDecimal orderAmount = saOrder.getOrderAmount();
        BigDecimal orderAchieve = saOrder.getOrderAchieve();
        // 判断专区 升级需要判断哪个国家，每个国家升级方式不一样
        String upgradeWay = querySystemConfigByKey(pkCountry, ESystemConfig.UPGRADE_WAY.getKey());
        // 会员等级为1的话 为一次性补差升级；
        CuMember cuMember = getCuMemberByKey(pkMember);
        if (specialArea.equals(EOrderType.UPGRADE_ORDER.getValue())) {
            //补差升级，当天的按照累计升级，非当天按照补差升级
            upgradeWay = Integer.toString(EUpgradeWay.DIFFERENCE.getValue());
        }
        return saOrderHandle.getMemberGradeAndAwardByCountry(cuMember, specialArea, orderAmount, orderAchieve, pkCountry, upgradeWay);
    }

    @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 ServiceException("保存会员失败");
            }
            if (orderBlankRegParams.getRegisterPv().compareTo(BigDecimal.ZERO) > 0) {
                // 生成订单 （订单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()) {
                log.error("====" + submit.getData());
                throw new ServiceException(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());
        // 如果发货方式为空，或者为0，则重置为快递发货
        if (null == saOrder.getDeliveryWay() || saOrder.getDeliveryWay().equals(0)) {
            saOrder.setDeliveryWay(EDelivery.FAST_MAIL.getValue());
        }
        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());
            BdProductExtendExt productExtend = iBdProductExtendService.queryExtendAndProduct(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());
            // 规格名称
            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());
            orderItem.setSkuCode(CommonUtil.createSkuCode(productExtend.getProductCode(), orderItem.getSpecsNameId()));
        }
        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());
        cuMember.setMemberName(orderBlankRegParams.getMemberName());
        cuMember.setPhone(orderBlankRegParams.getPhone());
        cuMember.setCustomerType(ECustomerType.EMPTY_ORDER.getValue());
        cuMember.setPkAwards(orderBlankRegParams.getUserAwards());
        cuMember.setIdCard(orderBlankRegParams.getIdCard());
        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 ServiceException("更新订单失败");
//            }
//            if (!memberServiceApi.normalRevokeOrder(pkApprove, saOrderExt, null, businessCommissionDTO).getData()) {
//                throw new ServiceException("撤单失败");
//            }
//        } 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 ServiceException("更新订单失败");
            }

            // 撤销注册订单 单点撤单
            if (ECancelOrderType.SINGLE_CANCEL_ORDER.getValue() == orderCancelParam.getCancelType()) {
                // 单点撤单，变死点
                R<Boolean> tmpR = memberServiceApi.singleRevokeMemberByRegisterOrder(pkApprove, saOrderExt, businessCommissionDTO);
                if (!tmpR.isSuccess()) {
                    throw new ServiceException("撤单失败 " + 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 ServiceException("撤单失败 " + tmpR.getMsg());
                }
            } else {
                // 其他撤单
                this.handleCancelUpgradeOrder(saOrderExt, validateCancelOrderVO.getUpdSaOrder(), pkApprove, businessCommissionDTO);
            }
//        }

        try {
            // 推送MQ的列表
            List<SaOrderExt> mqList = new ArrayList<>();
            mqList.add(saOrderExt);
            if (ECancelOrderType.MERGE_CANCEL_ORDER.getValue() == orderCancelParam.getCancelType()) {
                // 合并撤单需要将所有订单全部推过去，有部分活动要按订单来处理
                Map<Long, SaOrderExt> saOrderMap = validateCancelOrderVO.getSaOrderMap();
                for (Long key : saOrderMap.keySet()) {
                    // 撤单主单默认放在第一位置，合并撤单列表添加的时候不需要处理撤单主单
                    if (!saOrderExt.getOrderCode().equals(saOrderMap.get(key).getOrderCode())) {
                        mqList.add(saOrderMap.get(key));
                    }
                }
            }
            // 推送MQ，处理活动回退
            rabbitTemplate.convertAndSend(RabbitMqConstants.ORDER_CANCEL_EXCHANGE, RabbitMqConstants.ORDER_CANCEL_KEY, mqList);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void updateSaOrder(Long pkApprove, SaOrderExt saOrderExt, Date currentDateTime) {
        LambdaUpdateWrapper<SaOrder> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(SaOrder::getPkModified, pkApprove);
        updateWrapper.set(SaOrder::getModifiedTime, currentDateTime);
        updateWrapper.set(SaOrder::getDelFlag, saOrderExt.getDelFlag());
        updateWrapper.set(SaOrder::getOrderAmount, saOrderExt.getOrderAmount());
        updateWrapper.set(SaOrder::getOrderAchieve, saOrderExt.getOrderAchieve());
        updateWrapper.set(SaOrder::getUploadAchieve, saOrderExt.getUploadAchieve());
        updateWrapper.set(SaOrder::getOrderAssAchieve, saOrderExt.getOrderAssAchieve());
        updateWrapper.eq(SaOrder::getPkId, saOrderExt.getPkId());
        saOrderExt.setPkModified(pkApprove);
        saOrderExt.setModifiedTime(currentDateTime);
        if (!update(updateWrapper)) {
            throw new ServiceException("更新订单失败");
        }
    }


    @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 boolean validateLeftExistMember(Long pkPlaceParent, Integer pkCountry) {
        String validateParent = querySystemConfigByKey(pkCountry, ESystemConfig.PARENT_VALIDATE.getKey());
        if (EYesNo.YES.getIntValue() == Integer.parseInt(validateParent)) {
            // 因为使用Member作为入参，此处 category 传入 10，代表 0=正常，1=待激活
            List<CuMemberExt> cuMemberExtList = queryMemberExtByCondition(CuMember.builder().pkPlaceParent(pkPlaceParent).placeDept(EPlaceDept.LEFT_DEPT.getValue()).category(10).build());
            return cuMemberExtList.size() == 0;
        }
        return false;
    }

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

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

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

    @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 List<TOnlineRefundExt> queryRefundList() {
        return baseMapper.queryRefundList(SecurityUtils.getUserId());
    }

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

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

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

    @Override
    public List<SaOrderExt> selfAddressOrderList(MyOrderParam param, Long memberId, Integer pkCountry) {
        return baseMapper.selfAddressOrderList(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) {
        // 更新订单明细为已收货
        LambdaUpdateWrapper<SaOrderItems> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(SaOrderItems::getPkOrder, pkOrder);
        updateWrapper.set(SaOrderItems::getOrderStatus, EOrderStatus.RECEIVED.getValue());
        updateWrapper.set(SaOrderItems::getPkModified, memberId);
        updateWrapper.set(SaOrderItems::getModifiedTime, 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);
            }
        }

        log.info("会员取消订单参数，memberId: {}, orderId: {}", memberId, saOrder.getPkId());

        // 删除订单明细
        LambdaUpdateWrapper<SaOrderItems> updateItemsWrapper = new LambdaUpdateWrapper<>();
        updateItemsWrapper.eq(SaOrderItems::getPkOrder, saOrder.getPkId());
        updateItemsWrapper.set(SaOrderItems::getDelFlag, EDelFlag.DELETE.getValue());
        updateItemsWrapper.set(SaOrderItems::getPkModified, memberId);
        updateItemsWrapper.set(SaOrderItems::getModifiedTime, nowDate);
        saOrderItemsService.update(updateItemsWrapper);

        // 删除订单
        LambdaUpdateWrapper<SaOrder> updateOrderWrapper = new LambdaUpdateWrapper<>();
        updateOrderWrapper.eq(SaOrder::getPkId, saOrder.getPkId());
        updateOrderWrapper.set(SaOrder::getDelFlag, EDelFlag.DELETE.getValue());
        updateOrderWrapper.set(SaOrder::getPkModified, memberId);
        updateOrderWrapper.set(SaOrder::getModifiedTime, nowDate);
        this.update(updateOrderWrapper);

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

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

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

        // 删除订单
        LambdaUpdateWrapper<SaOrder> orderUpdateWrapper = new LambdaUpdateWrapper<>();
        orderUpdateWrapper.in(SaOrder::getPkId, orderIdList);
        if (null != pkCountry) {
            orderUpdateWrapper.eq(SaOrder::getPkCountry, pkCountry);
        }
        orderUpdateWrapper.set(SaOrder::getDelFlag, EDelFlag.DELETE.getValue());
        orderUpdateWrapper.set(SaOrder::getPkModified, userId);
        orderUpdateWrapper.set(SaOrder::getModifiedTime, nowDate);
        this.update(orderUpdateWrapper);

        // 删除订单明细
        LambdaUpdateWrapper<SaOrderItems> orderItemsUpdateWrapper = new LambdaUpdateWrapper<>();
        orderItemsUpdateWrapper.in(SaOrderItems::getPkOrder, orderIdList);
        if (null != pkCountry) {
            orderItemsUpdateWrapper.eq(SaOrderItems::getPkCountry, pkCountry);
        }
        orderItemsUpdateWrapper.set(SaOrderItems::getDelFlag, EDelFlag.DELETE.getValue());
        orderItemsUpdateWrapper.set(SaOrderItems::getPkModified, userId);
        orderItemsUpdateWrapper.set(SaOrderItems::getModifiedTime, nowDate);
        saOrderItemsService.update(orderItemsUpdateWrapper);
    }

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

    @Override
    public List<OrderInvoicingVO> listOrderInvoicing(OrderInvoicingParam param) {
        return baseMapper.listOrderInvoicing(param);
    }

    @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(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++) {
                try {
                    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) {
                            if (baseMapper.closeOrder(country.getPkId(), specialAreaTime.getAttributeValue(), orderType) > 0) {
                                saOrderItemsService.closeOrder(country.getPkId(), specialAreaTime.getAttributeValue(), orderType);
                            }
                        }
                    }
                } catch (Exception e) {
                    log.error("自动关闭订单失败", e);
                }
            }
        }
    }

    @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<Integer> queryOrderType(Long memberId, Integer pkCountry) {
        return baseMapper.queryOrderType(memberId, pkCountry);
    }

    @Override
    public void waresSalesAccrual(List<WaresNumberParam> waresNumberParamList) {
        try {
            waresExtendService.updateWaresSalesAccrual(waresNumberParamList);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

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

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveSaOrderByOrderExt(SaOrderExt saOrderExt) {
        save(saOrderExt);
        for (SaOrderItems saOrderItems : saOrderExt.getOrderItemsList()) {
            saOrderItems.setPkOrder(saOrderExt.getPkId());
        }
        saOrderItemsService.saveBatch(saOrderExt.getOrderItemsList());
    }

    @Override
    public List<MemberFirstOrderVo> checkMemberIsFirstOrder(List<String> memberCodeList) {
        return baseMapper.checkMemberIsFirstOrder(memberCodeList);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void selfRevokeOrder(Long pkApprove, MyOrderVO myOrderVO) {
        SaOrderExt saOrderExt = myOrderVO.getSaOrderExt();
        BusinessCommissionDTO businessCommissionDTO = null;
        if (saOrderExt != null) {
            // 删除订单
            saOrderExt.setDelFlag(EDelFlag.DELETE.getValue());
            Date currentDate = DateUtils.currentDateTime();
            // 删除发货单
            saDeliverItemsService.deleteSaDeliverItems(saOrderExt.getPkId(), null);
            // 修改订单
            updateSaOrder(pkApprove, saOrderExt, currentDate);
            // 删除订单明细
            if (!saOrderItemsService.updateOrderItems(saOrderExt)) {
                throw new ServiceException("更新订单失败");
            }

            // 本批订单修改记录编号
            String businessCode = CommonUtil.createSerialNumber(EOrderPrefix.DEFAULT);
            SaOrderChargeLog saOrderChargeLog = this.packageSaOrderChargeLog(currentDate, pkApprove,
                    EApprovalBusiness.ORDER_CANCEL.getValue(), businessCode, myOrderVO, EAgentApprovalStatus.APPROVED.getValue());
            MyOrderVO mo = new MyOrderVO();
            mo.setPkId(myOrderVO.getPkId());
            mo.setOrderCode(mo.getOrderCode());
            mo.setPkCreator(pkApprove);
            saOrderChargeLog.setAfterData(JSONUtil.toJsonStr(mo));
            saOrderChargeLog.setSource(ESignSource.MEMBER.getValue());
            saOrderChargeLogService.save(saOrderChargeLog);

            // 撤销注册订单
            if (myOrderVO.getOrderType() == EOrderType.RETAIL_REGISTER.getValue()) {
                // 逻辑删除会员
                if (!memberServiceApi.singleRevokeMemberBySelfRevokeOrder(pkApprove, saOrderExt, businessCommissionDTO).getData()) {
                    throw new ServiceException("撤单失败");
                }
            } else {
                // 其他撤单
                this.handleCancelUpgradeOrder(saOrderExt, myOrderVO.getUpdSaOrder(), pkApprove, businessCommissionDTO);
            }

            try {
                // 推送MQ，处理活动回退
                rabbitTemplate.convertAndSend(RabbitMqConstants.ORDER_CANCEL_EXCHANGE, RabbitMqConstants.ORDER_CANCEL_KEY, Collections.singletonList(saOrderExt));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    private SaOrderChargeLog packageSaOrderChargeLog(Date nowDate, Long userId, Integer chargeType, String businessCode,
                                                     MyOrderVO saOrder, Integer approvalStatus) {
        SaOrderChargeLog saOrderChargeLog = new SaOrderChargeLog();
        saOrderChargeLog.setPkOrder(saOrder.getPkId());
        saOrderChargeLog.setChargeType(chargeType);
        saOrderChargeLog.setPkCreator(userId);
        saOrderChargeLog.setCreationTime(nowDate);
        saOrderChargeLog.setPkModified(saOrderChargeLog.getPkCreator());
        saOrderChargeLog.setModifiedTime(saOrderChargeLog.getCreationTime());
        saOrderChargeLog.setPkCountry(saOrder.getPkCountry());
        saOrderChargeLog.setApprovalStatus(approvalStatus);
        saOrderChargeLog.setBusinessCode(businessCode);
        return saOrderChargeLog;
    }

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

    @Override
    public List<SingleItemStatVo> singleItemStat(SingleItemStatParam singleItemStatParam) {
        return baseMapper.singleItemStat(singleItemStatParam);
    }

    @Override
    public CuMemberAccountExt queryRetailOrderSpendDetails(CuMemberAccountExt cuMemberAccount, SaOrder saOrder, List<SaOrderItems> orderItemList) {
        // 订单金额
        BigDecimal payMoney = saOrder.getOrderAmount();
        // 订单邮费
        BigDecimal postage = saOrder.getPostage();

        // 订单创建人
        CuMember creator = getCuMemberByKey(saOrder.getPkCreator());
        cuMemberAccount.setMemberCode(creator.getMemberCode());

        // 查询专区所属币种
        List<AreaCurrencyDTO> areaCurrencyDTOList = areaCurrencyServiceApi.queryAreaCurrencyByCondition(ESpecialArea.getRetailSpecialAreaValue(saOrder.getOrderType()), cuMemberAccount.getPkCountry()).getData();

        // 验证会员是否存在特殊消费配置
        List<AreaCurrencyDTO> memberCurrencyDTOList = areaCurrencyServiceApi.queryMemberCurrency(ESpecialArea.getRetailSpecialAreaValue(saOrder.getOrderType()), cuMemberAccount.getPkMember()).getData();
        if (CollectionUtil.isNotEmpty(memberCurrencyDTOList)) {
            areaCurrencyDTOList = memberCurrencyDTOList;
        } else {
            // 验证商品是否存在特殊消费配置
            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 (!handleRetailSaOrderAmount(saOrder, cuMemberAccount, orderItemPayMoney, BigDecimal.ZERO, areaCurrencyDtoList)) {
                            return null;
                        }
                    }
                }
            }
        }

        handleRetailSaOrderAmount(saOrder, cuMemberAccount, payMoney, postage, areaCurrencyDTOList);

        if (null != cuMemberAccount.getPayAccount5() && cuMemberAccount.getPayAccount5().compareTo(BigDecimal.ZERO) > 0) {
            // 重消专区可以使用其它币种，此处只记录重消币，其它币种需要单独计算统计
            saOrder.setConsumeAmount(cuMemberAccount.getPayAccount5());
        }
        return cuMemberAccount;
    }

    /**
     * 新零售订单付款处理
     *
     * @param saOrder
     * @param cuMemberAccount
     * @param payMoney
     * @param postage
     * @param areaCurrencyDTOList
     * @return
     */
    private Boolean handleRetailSaOrderAmount(SaOrder saOrder, 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;

        // 2024.05.30 与业务确认，政策币个人配置优先特殊配置
        // 默认情况下，注册、升级专区才能使用政策币，其它专区都是走特殊业务处理
        // 个人政策币配置
        UpPolicyCurrency upPolicyCurrency = null;
        if (EOrderType.RETAIL_REGISTER.getValue() == saOrder.getOrderType()
                || EOrderType.RETAIL_UPGRADE.getValue() == saOrder.getOrderType()) {
            if (cuMemberAccount.getPayAccount3Flag()) {
                // 验证是否有政策币权限
                List<CuMemberServiceLog> cuMemberServiceLogs = cuMemberServiceLogServiceApi.queryMaxCuMemberServiceLog(cuMemberAccount.getPkMember(), Collections.singletonList(EApprovalBusiness.POLICY_CURRENCY_YES_NO.getValue()));
                if (CollectionUtil.isNotEmpty(cuMemberServiceLogs)) {
                    Map<Integer, CuMemberServiceLog> cuMemberServiceLogMap = new HashMap<>(ComputeUtil.mapInitCapacity(cuMemberServiceLogs.size()));
                    cuMemberServiceLogs.forEach(serviceLog -> cuMemberServiceLogMap.put(serviceLog.getEditType(), serviceLog));

                    try {
                        upPolicyCurrency = JSONUtil.toBean(cuMemberServiceLogMap.get(EApprovalBusiness.POLICY_CURRENCY_YES_NO.getValue()).getNewValue(), UpPolicyCurrency.class);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }

        for (AreaCurrencyDTO areaCurrencyDTO : areaCurrencyDTOList) {
            // 开始扣款
            // 待支付金额>0进行扣减
            if (ComputeUtil.compareValue(payMoney)) {
                // 获得特殊处理
                // 判断比例是否 > 0, 为强制扣除金额 ，强制扣除金额不满足，直接支付失败
                if (!ComputeUtil.compareValue(areaCurrencyDTO.getDeductRatio())) {
                    // 支付比例为0处理
                    // 最大支付金额
                    if (null != areaCurrencyDTO.getDeductMaxRatio()
                            && areaCurrencyDTO.getDeductMaxRatio().compareTo(BigDecimal.ZERO) > 0) {
                        // 并且有最大支付比例也不为0，则需要进行使用限制
                        areaCurrencyDTO.setDeductMaxRatioAmount(ComputeUtil.computeDivide(original.multiply(areaCurrencyDTO.getDeductMaxRatio()), BigDecimal.valueOf(100)));
                    }
                    payMoney = saOrderHandle.subtract(payMoney, cuMemberAccount, areaCurrencyDTO);
                } else {
                    // 政策币单独处理 政策币需要根据配置来进行处理
                    if (EAccount.POLICY.getValue() == areaCurrencyDTO.getFieldValue()) {
                        // 没有前置特殊政策币处理
                        if (null == areaCurrencyDTO.getSpecialFlag() || !areaCurrencyDTO.getSpecialFlag()) {
                            areaCurrencyDTO.setDeductRatio(BigDecimal.ZERO);
                        }

                        if (upPolicyCurrency != null) {
                            // 如果有政策币则进行处理
                            if (EYesNo.YES.getIntValue() == upPolicyCurrency.getEnableStatus()) {
                                // 启用则取值处理
                                areaCurrencyDTO.setDeductRatio(upPolicyCurrency.getDeductMoney() == null ? areaCurrencyDTO.getDeductRatio() : upPolicyCurrency.getDeductMoney());
                            } else {
                                // 禁用则不能使用
                                areaCurrencyDTO.setDeductRatio(BigDecimal.ZERO);
                            }
                        }
                    } else if (EAccount.CASH.getValue() == areaCurrencyDTO.getFieldValue()) {
                        if (upPolicyCurrency != null) {
                            // 有个人政策币，则不走特殊政策币配置的现金币比例
                            areaCurrencyDTO.setDeductRatio(areaCurrencyDTO.getOriginalDeductRatio());
                        }
                    }

                    // 最小支付金额
                    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);
            }
            // 每次扣除后判断是否扣除完毕，扣除完毕结束
            if (flag && payMoney.compareTo(BigDecimal.ZERO) == 0 && postage.compareTo(BigDecimal.ZERO) == 0) {
                cuMemberAccount.setIsPayment(Boolean.TRUE);
                break;
            }
        }
        return flag;
    }

    /**
     * 计算新零售撤单等级
     *
     * @param cuMember 会员信息
     * @param saOrder  订单信息
     * @return
     */
    private GradeDTO calculateRetailCancelGrade(CuMember cuMember, SaOrder saOrder) {
        // 查询会员最新升级记录
        CuMemberLevel cuMemberLevel = iCuMemberDetailServiceApi.getLastUpgrade(cuMember.getPkId(), saOrder.getPkId()).getData();
        if (null != cuMemberLevel) {
            return gradeServiceApi.getGrade(cuMemberLevel.getNewLevel()).getData();
        }

        // 没有升级记录，直接查会员注册信息表
        CuMemberRegister cuMemberRegister = iCuMemberDetailServiceApi.getMemberRegister(cuMember.getPkId()).getData();
        if (null == cuMemberRegister) {
            throw new ServiceException("没有会员注册信息");
        }
        return gradeServiceApi.getGrade(cuMemberRegister.getPkRegisterGrade()).getData();
    }

    /**
     * 处理撤销升级订单
     *
     * @param saOrderExt            订单信息
     * @param updSaOrder            升级订单
     * @param pkApprove             操作人
     * @param businessCommissionDTO 业务处理DTO
     */
    private void handleCancelUpgradeOrder(SaOrderExt saOrderExt, SaOrder updSaOrder, Long pkApprove, BusinessCommissionDTO businessCommissionDTO) {
        // 其他撤单 撤销升级订单
        CuMember cuMember = getCuMemberByKey(saOrderExt.getPkMember());
        if (EOrderType.RETAIL_UPGRADE.getValue() == saOrderExt.getOrderType()) {
            // 计算等级
            // 空单注册，从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.getLastUpgrade(cuMember.getPkId(), saOrderExt.getPkId()).getData();
                if (null != cuMemberLevel) {
                    cuMember.setPkSettleGrade(cuMemberLevel.getNewLevel());
                }
            } else {
                // 传的订单是当前撤的订单
                GradeDTO gradeDTO = calculateRetailCancelGrade(cuMember, saOrderExt);
                cuMember.setPkSettleGrade(gradeDTO.getPkId());
            }

            Date firstDate = baseMapper.getFirstPayTime(cuMember.getPkId());
            if (null == firstDate) {
                // 盒数商品订单最早的时间为空，则会员未激活
                cuMember.setPayTime(null);
                cuMember.setPayStatus(EPayStatus.UNPAID.getValue());
                cuMember.setIsActivate(EYesNo.NO.getIntValue());
            }
            saOrderExt.setUpdateFlag(EYesNo.YES.getIntValue());
        } else if (EOrderType.RETAIL_PICK.getValue() == saOrderExt.getOrderType()) {
            // 新提货订单
            if (!iAcRetailPickService.cancelRetailPickOrder(saOrderExt.getPkId(), pkApprove)) {
                throw new ServiceException("撤销订单退还提货失败");
            }
        }

//        if (EOrderType.RETAIL_REPURCHASE.getValue() == saOrderExt.getOrderType() ||
//                EOrderType.RETAIL_CONSUME.getValue() == saOrderExt.getOrderType()) {
//            // 需要查询盒数商品
//            List<String> boxProductList = BoxProductUtil.getBoxProductListBySystemType(saOrderExt.getSystemType());
//            // 复购、重消订单处理限购
//            iSaOrderWaresLimitService.updateCancelOrder(saOrderExt.getPkId(), saOrderExt.getPkMember(), saOrderExt.getModifiedTime(), boxProductList);
//        }

        if (!memberServiceApi.normalRevokeOrder(pkApprove, saOrderExt, cuMember, businessCommissionDTO).getData()) {
            throw new ServiceException("撤单处理会员失败");
        }
    }

    @Override
    public BdGrade calculateGrade(Integer specialArea, List<OrderItemsParam> orderItemsParams,
                                  List<BdGrade> gradeList, CuMember updateGradeMember,
                                  Integer systemType, Integer isPay) {
        if (CollectionUtil.isEmpty(gradeList)) {
            gradeList = iGradeServiceApi.getRetailGradeList().getData();
        }

        // 盒数产品
        List<String> boxWaresList = BoxProductUtil.getBoxProductListBySystemType(systemType);

        // 当前产品盒数
        int boxNum = 0;
        // 判断订单明细中指定产品数量，校验等级
        for (OrderItemsParam orderItemsParam : orderItemsParams) {
            if (boxWaresList.contains(orderItemsParam.getWaresCode())) {
                // 存在指定商品，需要累计盒数
                boxNum += orderItemsParam.getQuantity();
            }
        }

        // 返回等级
        BdGrade bdGrade = null;
        if (ESpecialArea.RETAIL_REGISTER.getValue() == specialArea) {
            // 注册专区直接算等级
            bdGrade = this.getGradeByBox(boxNum, gradeList, null, true);
        } else if (ESpecialArea.RETAIL_UPGRADE.getValue() == specialArea) {
            // 升级专区，一次性补差升级
            if (boxNum == 0) {
                // 不满足升级条件
                throw new ServiceException("不满足升级条件");
            }

            // 当前会员等级
            BdGrade memberGrade = gradeList.stream().filter(tmpGrade -> tmpGrade.getPkId().equals(updateGradeMember.getPkSettleGrade())).findFirst().get();
            if (memberGrade.getGradeValue().compareTo(EGrade.BRANCH_COMPANY.getValue()) >= 0) {
                // 会员等级大于等于分公司，不能通过升级进行购买了
                throw new ServiceException("当前已经是可以购买的最高等级");
            }

            // 获取升级盒数基数
            int baseBoxNum = this.handleBaseBoxNum(updateGradeMember, memberGrade, gradeList, boxWaresList, systemType);
            // 计算等级
            bdGrade = this.getGradeByBox(boxNum + baseBoxNum, gradeList, memberGrade, true);

            // 会员等级 大于等于 购买盒数等级，则不充足升级条件
            if (memberGrade.getGradeValue().compareTo(bdGrade.getGradeValue()) >= 0) {
                return null;
            }
        }
        return bdGrade;
    }

    @Override
    public BdGrade getGradeByBox(final Integer boxTotal, List<BdGrade> gradeList, BdGrade memberGrade, boolean checkUpgrade) {
        if (CollectionUtil.isEmpty(gradeList)) {
            gradeList = iGradeServiceApi.getRetailGradeList().getData();
        }

        if (null == memberGrade) {
            // 注册处理
            // 小于总公司等级 并且 排除高级店主 并且 升级盒数小于购买盒数的最大一个等级为注册等级
            return gradeList.stream()
                    .filter(tmpGrade -> tmpGrade.getGradeValue() != EGrade.S_VIP.getValue()
                            && tmpGrade.getGradeValue() < EGrade.COMPANY.getValue()
                            && tmpGrade.getBoxNumber() <= boxTotal)
                    .max(Comparator.comparingInt(BdGrade::getGradeValue)).get();
        } else {
            // 非注册处理
//            if (checkUpgrade) {
//                // 当前等级大于等于V3 或 盒数商品为0，则直接返回当前等级
//                if (memberGrade.getGradeValue().compareTo(EGrade.MAKER.getValue()) >= 0
//                        || boxTotal == 0) {
//                    return memberGrade;
//                }
//            } else {
//                // 当前等级大于V3 或 盒数商品为0，则直接返回当前等级
//                if (memberGrade.getGradeValue().compareTo(EGrade.MAKER.getValue()) > 0
//                        || boxTotal == 0) {
//                    return memberGrade;
//                }
//            }

            // 查询等级比现在当前等级大的  并且 排除高级店主，然后倒序排序，再查询 购买盒数 <= 等级盒数 的第一个等级，就是当前升级的等级
            Optional<BdGrade> gradeOptional = gradeList.stream()
                    .filter(tmpGrade -> tmpGrade.getGradeValue() != EGrade.S_VIP.getValue() && tmpGrade.getGradeValue() > memberGrade.getGradeValue())
                    .sorted(Comparator.comparingInt(BdGrade::getGradeValue).reversed())
                    .filter(tmpGrade -> tmpGrade.getBoxNumber() != 0)
                    .filter(tmpGrade -> tmpGrade.getBoxNumber() <= boxTotal).findFirst();
            return gradeOptional.orElse(memberGrade);
        }
    }


    /**
     * 处理升级盒数基数
     *
     * @param cuMember       会员信息
     * @param memberGrade    会员等级信息
     * @param gradeList      等级列表
     * @param boxWaresList 盒数商品列表
     * @param systemType     所属系统
     * @return
     */
    @Override
    public int handleBaseBoxNum(CuMember cuMember, BdGrade memberGrade,
                                List<BdGrade> gradeList, List<String> boxWaresList,
                                Integer systemType) {
        // 升级盒数基数
        int baseBoxNum = 0;
        // 会员所有升级记录
        List<CuMemberLevel> memberLevelList = iCuMemberDetailServiceApi.getUpgradeList(cuMember.getPkId()).getData();
        if (CollectionUtil.isNotEmpty(memberLevelList)) {
            Optional<CuMemberLevel> lastManualOptional = memberLevelList.stream().filter(tmpGrade -> tmpGrade.getUpType().equals(EUpgradeType.MANUAL_UPGRADE.getValue())).findFirst();
            if (lastManualOptional.isPresent()) {
                // 最新一次的手动升级
                CuMemberLevel lastMemberLevel = lastManualOptional.get();
                BdGrade lastUpdateGrade = gradeList.stream().filter(tmpGrade -> tmpGrade.getPkId().equals(lastMemberLevel.getNewLevel())).findFirst().get();
                // 盒数基数 = 手动升级盒数 + 手动升级之后的升级订单盒数
                baseBoxNum = lastUpdateGrade.getBoxNumber()
                        + saOrderItemsService.getRetailWaresQuantityNew(cuMember.getPkId(), boxWaresList, lastMemberLevel.getUpgradeTime(), Collections.singletonList(EOrderType.RETAIL_UPGRADE.getValue()), systemType);
            } else {
                // 没有手动升级记录
                baseBoxNum = saOrderItemsService.getRetailWaresQuantityNew(cuMember.getPkId(), boxWaresList, null, Arrays.asList(EOrderType.RETAIL_REGISTER.getValue(), EOrderType.RETAIL_UPGRADE.getValue()), systemType);
            }
        }
        return baseBoxNum;
    }

    @Override
    public CuMemberRetailRegionExt getRegionBindNum(Integer province, Integer city, Integer county) {
        return baseMapper.getRegionBindNum(province, city, county);
    }

}
