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

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hzs.activity.pick.service.IAcPickService;
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.base.CuMemberShare;
import com.hzs.common.domain.member.business.UpPolicyCurrency;
import com.hzs.common.domain.member.detail.CuMemberLevel;
import com.hzs.common.domain.member.detail.CuMemberServiceLog;
import com.hzs.common.domain.member.detail.ext.CuMemberAwardsExt;
import com.hzs.common.domain.member.ext.CuMemberAccountExt;
import com.hzs.common.domain.member.ext.CuMemberExt;
import com.hzs.common.domain.sale.ext.*;
import com.hzs.common.domain.sale.order.*;
import com.hzs.common.domain.sale.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.third.pay.TOnlinePayment;
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.param.DeliverSecondParam;
import com.hzs.sale.deliver.service.ISaDeliverItemsService;
import com.hzs.sale.deliver.vo.DeliverSecondVO;
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.product.service.IBdProductService;
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.ICuMemberAgreementWhiteApi;
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 com.hzs.third.pay.ITOnlinePaymentServiceApi;
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 iGradeServiceApi;
    @DubboReference
    IAwardsServiceApi iAwardsServiceApi;
    @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 iCuMemberServiceLogServiceApi;
    @DubboReference
    IMemberTradeServiceApi iMemberTradeServiceApi;
    @DubboReference
    ICuMemberDetailServiceApi iCuMemberDetailServiceApi;
    @DubboReference
    ICuMemberAgreementWhiteApi cuMemberAgreementWhiteApi;
    @DubboReference
    ITOnlinePaymentServiceApi itOnlinePaymentServiceApi;

    @Autowired
    private IBdWaresService iBdWaresService;
    @Autowired
    private IBdWaresExtendService iBdWaresExtendService;
    @Autowired
    private SaOrderHandle saOrderHandle;
    @Autowired
    private ISaOrderItemsService saOrderItemsService;
    @Autowired
    private UserTokenService userTokenService;
    @Autowired
    private IBdProductExtendService productExtendService;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private IBdWaresSpecsRelationService waresSpecsRelationService;
    @Autowired
    private IBdProductService iBdProductService;
    @Autowired
    private ISaDeliverItemsService saDeliverItemsService;
    @Autowired
    private IAcPickService iAcPickService;
    @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();
    }

    /**
     * 查找安置人伞下
     *
     * @param memberId 会员编号
     */
    @Override
    public List<CuMemberExt> selectPlaceSponsorUnderUmbrellaByCondition(Long memberId, List<CuMemberExt> cuMemberExtList) {
        return memberServiceApi.selectPlaceSponsorUnderUmbrellaByCondition(memberId, cuMemberExtList).getData();
    }

    /**
     * 查找安置人伞下
     *
     * @param memberId 安置人，编号
     *                 查找安置人伞下
     */
    @Override
    public List<CuMemberExt> queryPlaceSponsorUnderUmbrella(Long memberId, String placeParent) {
        return memberServiceApi.queryPlaceSponsorUnderUmbrella(memberId, placeParent).getData();
    }

    /**
     * 根据会员编号，查找该会员编号极左极下的那个人
     *
     * @param memberId  会员编号
     * @param placeDept 1代表左区极左极下，2代表右区极左极下
     */
    @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, List<Integer> notTypeList) {
        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(notTypeList)) {
            queryWrapper.notIn(SaOrder::getOrderType, notTypeList);
        }
        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 CuMemberAccountExt queryOrderSpendDetails(CuMemberAccountExt cuMemberAccount, SaOrder saOrder, List<SaOrderItems> orderItemList) {
        BigDecimal payMoney = saOrder.getOrderAmount();

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

        // 查询专区所属币种
        List<AreaCurrencyDTO> areaCurrencyDTOListOld = areaCurrencyServiceApi.queryAreaCurrencyByCondition(saOrder.getOrderType(), cuMemberAccount.getPkCountry()).getData();
        List<AreaCurrencyDTO> areaCurrencyDTOList = areaCurrencyDTOListOld;
        if (cuMemberAccount.getPkCountry().equals(CountryConstants.CHINA_COUNTRY)) {
            //休止期的奖金账户(不在白名单内)不允许报单
            Integer expireStatus = creator.getExpireStatus();
            if (expireStatus.equals(EExpireStatus.REST.getValue())) {
                //查询配置是否休止期可以报单
                Integer num = cuMemberAgreementWhiteApi.selectAgreementWhiteByPkMember(creator.getPkId()).getData();
                if (num == null || num == 0) {
                    areaCurrencyDTOList = areaCurrencyDTOListOld.stream().filter(item -> !item.getFieldValue().equals(EAccount.BONUS.getValue())).collect(Collectors.toList());
                }
            }
        }

        if (!ComputeUtil.compareValue(payMoney)) {
            cuMemberAccount.setIsPayment(Boolean.TRUE);
        }

        // 个人政策币配置，政策币个人配置优先特殊配置
        UpPolicyCurrency upPolicyCurrency = null;
        if (EOrderType.REGISTER_ORDER.getValue() == saOrder.getOrderType()
                || EOrderType.UPGRADE_ORDER.getValue() == saOrder.getOrderType()) {
            upPolicyCurrency = iCuMemberServiceLogServiceApi.queryMaxCuMemberServiceLog(cuMemberAccount.getPkMember(), Collections.singletonList(EApprovalBusiness.POLICY_CURRENCY_YES_NO.getValue())).getData();
        }

        // 验证商品是否存在特殊消费配置
        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(upPolicyCurrency, cuMemberAccount, orderItemPayMoney, BigDecimal.ZERO, areaCurrencyDtoList)) {
                        return null;
                    }
                }
            }
        }

        handleSaOrderAmount(upPolicyCurrency, cuMemberAccount, payMoney, saOrder.getPostage(), areaCurrencyDTOList);

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

        return cuMemberAccount;
    }

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

    private Boolean handleSaOrderAmount(UpPolicyCurrency upPolicyCurrency, CuMemberAccountExt cuMemberAccount,
                                        BigDecimal payMoney, BigDecimal postage,
                                        List<AreaCurrencyDTO> areaCurrencyDTOList) {
        boolean flag = Boolean.TRUE;
        if (!ComputeUtil.compareValue(ComputeUtil.computeAdd(payMoney, postage))) {
            return Boolean.TRUE;
        }
        cuMemberAccount.setIsPayment(Boolean.FALSE);
        // 原始支付金额（订单金额 + 邮费）
        BigDecimal original = payMoney;

        for (AreaCurrencyDTO areaCurrencyDTO : areaCurrencyDTOList) {
            // 开始扣款
            // 待支付金额>0进行扣减
            if (ComputeUtil.compareValue(payMoney)) {
                // 获得特殊处理
                // 判断比例是否 > 0, 为强制扣除金额 ，强制扣除金额不满足，直接支付失败
                if (!ComputeUtil.compareValue(areaCurrencyDTO.getDeductRatio())) {
                    // 支付比例为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() + 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, Boolean.FALSE).getData();
        } else if ((CountryConstants.CHINA_COUNTRY.equals(orderParam.getPkSettleCountry())) &&
                (EOrderType.REGISTER_ORDER.getValue() == orderParam.getSpecialArea()
                        || EOrderType.SPECIAL_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 RuntimeException("保存会员失败.");
                }
            } else {
                log.error("confirmRegSaOrderByOrderParam 保存会员失败. {}", saveResult.getMsg());
                throw new RuntimeException("保存会员失败.");
            }
        } 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, Boolean.FALSE).getData();
        return cuMember;
    }

    /**
     * 设置会员最终的等级
     *
     * @param cuMember   会员
     * @param saOrderExt 订单
     * @return boolean
     */
    @Override
    public Boolean setLastCuMemberGrade(CuMember cuMember, SaOrder saOrderExt) {
        OrderReturn orderReturn = OrderReturn.builder().isEnough(false).build();
        GradeDTO gradeDTO = calculateGradeDTO(saOrderExt.getOrderType(), cuMember.getPkSettleCountry(), cuMember.getPkId(), saOrderExt, orderReturn);

        // 第二次封装用户 封装等级
        if (gradeDTO == null) {
            return true;
        }

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

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

        Integer pkAwards = cuMember.getPkAwards();
        cuMember.setPkRegisterGrade(gradeDTO.getPkId());
        cuMember.setPkSettleGrade(gradeDTO.getPkId());
        cuMember.setPkSettleGradeValue(gradeDTO.getGradeValue());

        if (EOrderType.REGISTER_ORDER.getValue() == saOrderExt.getOrderType()) {
            // 2025.05.13 新添加需求，开网初期报单660给1980等级，报单1980给9900等级
            if (EGrade.YOU_KE.getValue() == gradeDTO.getGradeValue()) {
                GradeDTO newGradeDTO = iGradeServiceApi.getGradeByGradeValue(EGrade.MAKER.getValue(), saOrderExt.getPkCountry()).getData();
                if (null != newGradeDTO) {
                    cuMember.setPkSettleGrade(newGradeDTO.getPkId());
                }
            } else if (EGrade.MAKER.getValue() == gradeDTO.getGradeValue()) {
                GradeDTO newGradeDTO = iGradeServiceApi.getGradeByGradeValue(EGrade.VIP.getValue(), saOrderExt.getPkCountry()).getData();
                if (null != newGradeDTO) {
                    cuMember.setPkSettleGrade(newGradeDTO.getPkId());
                }
            }
        }

        // 判断奖衔，原会员有奖衔的话判断哪个大，使用大的
        if (pkAwards != null && gradeDTO.getGradeValue() != null) {
            BdAwards bdAwards = iAwardsServiceApi.getAwardsOne(pkAwards).getData();
            BdAwards newAwards = iAwardsServiceApi.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 || EOrderType.SPECIAL_REGISTER_ORDER.getValue() == specialArea) {
            confirmPay = querySystemConfigByKey(pkCountry, ESystemConfig.REGISTER_ORDER_CONFIRM_PAY.getKey());
        } else if (EOrderType.UPGRADE_ORDER.getValue() == specialArea || EOrderType.SPECIAL_UPGRADE_ORDER.getValue() == specialArea) {
            confirmPay = querySystemConfigByKey(pkCountry, ESystemConfig.UPGRADE_ORDER_CONFIRM_PAY.getKey());
        } else if (EOrderType.REPURCHASE_ORDER.getValue() == specialArea || EOrderType.SPECIAL_REPURCHASE_ORDER.getValue() == specialArea) {
            confirmPay = querySystemConfigByKey(pkCountry, ESystemConfig.REPURCHASE_ORDER_CONFIRM_PAY.getKey());
        } else if (EOrderType.PICK_ORDER.getValue() == specialArea) {
            // 提货没有待支付
            confirmPay = ESystemConfig.PICK_ORDER_CONFIRM_PAY.getValue();
        } else if (EOrderType.CONSUME_ORDER.getValue() == specialArea) {
            confirmPay = querySystemConfigByKey(pkCountry, ESystemConfig.CONSUME_ORDER_CONFIRM_PAY.getKey());
        } else if (EOrderType.WELFARE_ORDER.getValue() == specialArea) {
            confirmPay = querySystemConfigByKey(pkCountry, ESystemConfig.WELFARE_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.PICK_ORDER.getValue() == specialArea) {
                timeType = querySystemConfigByKey(pkCountry, ESystemConfig.PICK_ORDER_TIME.getKey());
            } else if (EOrderType.CONSUME_ORDER.getValue() == specialArea) {
                timeType = querySystemConfigByKey(pkCountry, ESystemConfig.CONSUME_ORDER_TIME.getKey());
            } else if (EOrderType.WELFARE_ORDER.getValue() == specialArea) {
                timeType = querySystemConfigByKey(pkCountry, ESystemConfig.WELFARE_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 支付账户信息
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    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());

//        // 乐学注册、乐学升级订单处理法宝券
//        this.handleLxPick(saOrderExt);

        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 RuntimeException("保存会员失败!.");
            }
        } else {
            log.error("payRegSaOrder 保存会员失败!.，{}", saveResult.getMsg());
            throw new RuntimeException("保存会员失败!.");
        }

        try {
            log.info("生产活动消息，activity.exchange：{}", JSONUtil.toJsonStr(saOrderExt));
            rabbitTemplate.convertAndSend(RabbitMqConstants.ACTIVITY_EXCHANGE, RabbitMqConstants.ACTIVITY_KEY, saOrderExt);
//            //计算奖金，通过mq分发消息，异步处理
//            log.info("生产秒结消息，order.second.exchange：{}", JSONUtil.toJsonStr(saOrderExt));
//            rabbitTemplate.convertAndSend(RabbitMqConstants.ORDER_SECOND_EXCHANGE, RabbitMqConstants.ORDER_SECOND_KEY, saOrderExt);

//            if (EOrderType.REGISTER_ORDER.getValue() == saOrderExt.getOrderType()) {
//                // 推送会员续约处理MQ
//                rabbitTemplate.convertAndSend(RabbitMqConstants.MEMBER_CONTINUE_EXCHANGE, RabbitMqConstants.MEMBER_CONTINUE_KEY,
//                        MemberContinueDTO.builder()
//                                .pkMemberList(Collections.singletonList(saOrderExt.getPkMember()))
//                                .eMemberContinue(EMemberContinue.REGISTER_ORDER)
//                                .build());
//            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        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 insertSaOrder(SaOrderExt saOrderExt) {
        redisService.lockKeyMany(CacheConstants.MEMBER_ORDER + saOrderExt.getOrderCode());
        try {
            this.save(saOrderExt);
            for (SaOrderItems saOrderItems : saOrderExt.getOrderItemsList()) {
                saOrderItems.setPkOrder(saOrderExt.getPkId());
            }
            saOrderItemsService.saveBatch(saOrderExt.getOrderItemsList());
        } finally {
            redisService.unlock(CacheConstants.MEMBER_ORDER + saOrderExt.getOrderCode());
        }
    }

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

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

    /**
     * 支付升级订单
     *
     * @param saOrderExt         订单信息
     * @param cuMemberAccountExt 会员账户
     * @return: Boolean
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean payUpgradeSaOrder(SaOrderExt saOrderExt, CuMemberAccountExt cuMemberAccountExt) {
        CuMember cuMember = getCuMemberByKey(saOrderExt.getPkMember());
        GradeDTO oldGradeDTO = iGradeServiceApi.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;
        }
//        // 验证等级，原等级<新等级
//        if (oldGradeDTO.getGradeValue() >= cuMember.getPkSettleGradeValue()) {
//            if (saOrderExt.getOrderType().equals(EOrderType.SPECIAL_UPGRADE_ORDER.getValue())) {
//                // TODO new 乐学升级，如果V2可以购买订单金额大于36000的，如果V3可以购买订单金额大于128000的
//                if (!((EGrade.MAKER.getValue() == cuMember.getPkSettleGradeValue() && saOrderExt.getOrderAmount().compareTo(MagicNumberConstants.V3_AMOUNT) >= 0)
//                        || (EGrade.VIP.getValue() == cuMember.getPkSettleGradeValue() && saOrderExt.getOrderAmount().compareTo(MagicNumberConstants.V4_AMOUNT) >= 0))
//                ) {
//                    return false;
//                }
//            }
//        }
        // 封装保存订单数据
        encapsulationSaOrder(saOrderExt);

//        // 乐学注册、乐学升级订单处理法宝券
//        this.handleLxPick(saOrderExt);

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

//            if (EOrderType.UPGRADE_ORDER.getValue() == saOrderExt.getOrderType()) {
//                // 推送会员续约处理MQ
//                rabbitTemplate.convertAndSend(RabbitMqConstants.MEMBER_CONTINUE_EXCHANGE, RabbitMqConstants.MEMBER_CONTINUE_KEY,
//                        MemberContinueDTO.builder()
//                                .pkMemberList(Collections.singletonList(saOrderExt.getPkMember()))
//                                .eMemberContinue(EMemberContinue.UPGRADE_ORDER)
//                                .build());
//            }
        } 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()
                || EOrderType.WELFARE_ORDER.getValue() == orderParam.getSpecialArea()
                || EOrderType.SPECIAL_UPGRADE_ORDER.getValue() == orderParam.getSpecialArea()
                || EOrderType.SPECIAL_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() ||
                EOrderType.SPECIAL_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);

        if (EOrderType.PICK_ORDER.getValue() == saOrderExt.getOrderType()) {
            // 提货订单，没有待支付，直接保存
            insertSaOrder(saOrderExt);
        } else {
            // 更新订单信息
            updateSaOrder(saOrderExt);
        }

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

        if (EOrderType.RENEWAL_ORDER.getValue() == saOrderExt.getOrderType()) {
            // 续约订单，会员有效期加12个月
            cuMember = member;
            cuMember.setExpireDate(DateUtils.addMonths(member.getExpireDate(), 12));
            cuMember.setStopDate(DateUtils.addMonths(member.getStopDate(), 12));
        }

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

        try {
//            if (EOrderType.RENEWAL_ORDER.getValue() == saOrderExt.getOrderType()) {
//                // 续约专区推送MQ
//                rabbitTemplate.convertAndSend(RabbitMqConstants.MEMBER_CONTINUE_EXCHANGE, RabbitMqConstants.MEMBER_CONTINUE_KEY,
//                        MemberContinueDTO.builder()
//                                .pkMemberList(Collections.singletonList(saOrderExt.getPkMember()))
//                                .eMemberContinue(EMemberContinue.BUY_GIFT)
//                                .build());
//            }
//            // 推送秒结数据
//            rabbitTemplate.convertAndSend(RabbitMqConstants.ORDER_SECOND_EXCHANGE, RabbitMqConstants.ORDER_SECOND_KEY, saOrderExt);
        } catch (Exception e) {
            e.printStackTrace();
        }
        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, orderReturn);
        // 注册类型订单直接查询出会员等级
        if (orderParam.getSpecialArea().equals(EOrderType.REGISTER_ORDER.getValue())
                || orderParam.getSpecialArea().equals(EOrderType.SPECIAL_REGISTER_ORDER.getValue())) {
            orderReturn.setIsEnough(Boolean.TRUE);
        }

        if (orderParam.getIsEnough() != null && orderParam.getIsEnough()) {
            orderReturn.setIsEnough(Boolean.TRUE);
            CuMember member = getCuMemberByKey(orderParam.getCenterCodeId());
            GradeDTO grade = iGradeServiceApi.getGrade(member.getPkSettleGrade()).getData();
            orderReturn.setPkGradeVal(grade.getGradeName());
            return orderReturn;
        }

        // 验证等级是否满足条件
        if (!orderReturn.getIsEnough()) {
            CuMember member;
            if (null != orderParam.getUpgradeMemberCodeTmp()) {
                member = getCuMemberByCode(orderParam.getUpgradeMemberCodeTmp());
            } else {
                member = getCuMemberByKey(orderParam.getCenterCodeId());
            }
            GradeDTO grade = iGradeServiceApi.getGrade(member.getPkSettleGrade()).getData();
            if (grade.getGradeValue() < gradeDTO.getGradeValue()) {
                orderReturn.setIsEnough(Boolean.TRUE);
            } else {
//                if (orderParam.getSpecialArea().equals(EOrderType.SPECIAL_UPGRADE_ORDER.getValue())) {
//                    // TODO new 乐学升级，如果V2可以购买订单金额大于36000的，如果V3可以购买订单金额大于128000的
//                    if (EGrade.MAKER.getValue() == grade.getGradeValue()
//                            && saOrder.getOrderAmount().compareTo(MagicNumberConstants.V3_AMOUNT) >= 0) {
//                        orderReturn.setIsEnough(Boolean.TRUE);
//                    } else if (EGrade.VIP.getValue() == grade.getGradeValue()
//                            && saOrder.getOrderAmount().compareTo(MagicNumberConstants.V4_AMOUNT) >= 0) {
//                        orderReturn.setIsEnough(Boolean.TRUE);
//                    }
//                }
                gradeDTO.setGradeName(null);
            }
        }
        if (gradeDTO == null) {
            gradeDTO = GradeDTO.builder().gradeName(null).build();
            orderReturn.setIsEnough(Boolean.FALSE);
        }
        orderReturn.setPkGradeVal(gradeDTO.getGradeName());
        return orderReturn;
    }

    private GradeDTO calculateGradeDTO(Integer specialArea, Integer pkCountry, Long pkMember, SaOrder saOrder, OrderReturn orderReturn) {
        BigDecimal orderAmount = saOrder.getOrderAmount();
        BigDecimal orderAchieve = saOrder.getOrderAchieve();
        // 判断专区 升级方式不一样
        String upgradeWay = querySystemConfigByKey(pkCountry, ESystemConfig.UPGRADE_WAY.getKey());

        if (specialArea.equals(EOrderType.UPGRADE_ORDER.getValue())
//                || (cuMember != null && Objects.equals(cuMember.getPkSettleGrade(), MagicNumberConstants.CHINA_HA_FUN))
        ) {
//            if (Objects.equals(cuMember.getPkSettleGrade(), MagicNumberConstants.CHINA_HA_FUN)) {
//                upgradeWay = Integer.toString(EUpgradeWay.DIFFERENCE.getValue());
//            }
            if (EUpgradeWay.COVER.getValue() != Integer.parseInt(upgradeWay)) {
                // 获得历史订单pv
                QueryWrapper<SaOrder> queryWrapper = new QueryWrapper<>();
                queryWrapper.select(" pk_member,sum(order_amount) order_amount,sum(order_achieve) order_achieve ");
                queryWrapper.eq(SaOrderFieldConstants.ORDER_STATUS, EOrderStatus.PAY.getValue())
                        .eq(MemberFieldConstants.PK_MEMBER, pkMember)
                        .groupBy("pk_member");
                if (StringUtils.isNotEmpty(saOrder.getOrderCode())) {
                    queryWrapper.ne(SaOrderFieldConstants.ORDER_CODE, saOrder.getOrderCode());
                }
                SaOrder hisSaOrder = baseMapper.selectOne(queryWrapper);
                if (hisSaOrder != null) {
                    orderAmount = orderAmount.add(hisSaOrder.getOrderAmount());
                    orderAchieve = orderAchieve.add(hisSaOrder.getOrderAchieve());
                }
                // 累计升级无论是否升级都满足条件
                if (EUpgradeWay.TOTAL.getValue() == Integer.parseInt(upgradeWay)) {
                    orderReturn.setIsEnough(Boolean.TRUE);
                }
            }
        }

        return saOrderHandle.getMemberGradeAndAwardByCountry(orderAmount, orderAchieve, pkCountry, upgradeWay);
    }

    /**
     * 生成空单注册
     *
     * @param orderBlankRegParams 参数
     */
    @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());
            iCuMemberServiceLogServiceApi.insert(memberLog);
            // 主要业务
            //创建用户
            CuMemberExt memberExt = createMember(orderBlankRegParams);

            R<CuMember> member = memberServiceApi.createEmptyOrderMember(memberExt);
            if (member.getData() == null) {
                throw new RuntimeException("保存会员失败");
            }
            if (orderBlankRegParams.getRegisterPv().compareTo(BigDecimal.ZERO) > 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());
            iCuMemberServiceLogServiceApi.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 RuntimeException(TransactionUtils.getContent(ConfigMsgConstants.MEMBER_UPDATE_PETITION));
            }
        }
//        //扣钱
        if (orderBlankRegParams.getProcessType() == EProcessType.AVOIDSIGNING.getValue() || orderBlankRegParams.getProcessType() == EProcessType.DOUBLEPAY.getValue()) {
            // 免签或者确认按钮扣费
            BusinessCommissionDTO businessCommissionDTO = new BusinessCommissionDTO();
            businessCommissionDTO.setPkCountry(pkCountry);
            businessCommissionDTO.setMemberAmountDTOList(orderBlankRegParams.getMemberAmountDTOList());
            businessCommissionDTO.setTradeType(EApprovalBusiness.EMPTY_ORDER.getValue());
            R<Boolean> b = iMemberTradeServiceApi.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 = iBdWaresService.getWares(orderItem.getPkWares());
            BdProductExtendExt productExtend = productExtendService.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().intValue());
            // 规格名称
            List<String> specsNames = new ArrayList<>();
            // 规格id
            List<Integer> specsIds = new ArrayList<>();
            for (BdWaresSpecsRelationExt bdWaresSpecsRelationExt : waresSpecsRelationList) {
                specsNames.add(bdWaresSpecsRelationExt.getSpecsName());
                specsIds.add(bdWaresSpecsRelationExt.getPkSpecs());
            }
            orderItem.setSpecsName(StringUtils.join(specsNames, ","));
            orderItem.setSpecsNameId(StringUtils.join(specsIds, ","));
            orderItem.setPkCountry(orderBlankRegParams.getPkSettleCountry());
            orderItem.setPkCreator(SecurityUtils.getUserId());
            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 RuntimeException("更新订单失败");
            }
            if (!memberServiceApi.normalRevokeOrder(pkApprove, saOrderExt, null, pkOrderItemList, businessCommissionDTO).getData()) {
                throw new RuntimeException("撤单失败");
            }
        } else {
            // 删除订单
            saOrderExt.setDelFlag(EDelFlag.DELETE.getValue());
            Date currentDate = DateUtils.currentDateTime();
            // 删除发货单
            saDeliverItemsService.deleteSaDeliverItems(saOrderExt.getPkId(), null);
            // 修改订单
            updateSaOrder(pkApprove, saOrderExt, currentDate);
            // 删除订单明细
            if (!saOrderItemsService.updateOrderItems(saOrderExt)) {
                throw new RuntimeException("更新订单失败");
            }
            // 撤销注册订单 单点撤单
            if (ECancelOrderType.SINGLE_CANCEL_ORDER.getValue() == orderCancelParam.getCancelType()) {
                // 单点撤单，变死点
                R<Boolean> tmpR = memberServiceApi.singleRevokeMemberByRegisterOrder(pkApprove, saOrderExt, businessCommissionDTO);
                if (!tmpR.isSuccess()) {
                    throw new RuntimeException("撤单失败 " + tmpR.getMsg());
                }
            } else if (ECancelOrderType.MERGE_CANCEL_ORDER.getValue() == orderCancelParam.getCancelType()) {
                // 合并撤单，撤下面所有
                List<Long> memberList = validateCancelOrderVO.getMemberList().stream().map(OrderCancelRegisterMemberVO::getPkMember).collect(Collectors.toList());
                if (CollectionUtil.isNotEmpty(memberList)) {
                    // 撤销所有订单明细表
                    saOrderItemsService.updateOrderItemsByMemberList(memberList, pkApprove, currentDate);
                    // 撤销所有订单主表
                    baseMapper.updateSaOrderByMember(memberList, pkApprove, currentDate);
                }

                R<Boolean> tmpR = memberServiceApi.mergeRevokeMemberByRegisterOrder(pkApprove, memberList, validateCancelOrderVO.getSaOrderMap(), businessCommissionDTO);
                if (!tmpR.isSuccess()) {
                    throw new RuntimeException("撤单失败 " + tmpR.getMsg());
                }
            } else {
                // 其他撤单 撤销升级订单
                CuMember cuMember = getCuMemberByKey(saOrderExt.getPkMember());
                if (EOrderType.UPGRADE_ORDER.getValue() == saOrderExt.getOrderType()
                        || EOrderType.SPECIAL_UPGRADE_ORDER.getValue() == saOrderExt.getOrderType()
                ) {
                    SaOrder updSaOrder = validateCancelOrderVO.getUpdSaOrder();
                    // 计算等级
                    // 获取升级订单
                    // 空单注册，从cu_member_register中获取
                    if (updSaOrder == null) {
                        CuMemberRegister cuMemberRegister = memberServiceApi.queryCuMemberRegister(saOrderExt.getPkMember()).getData();
                        cuMember.setPkRegisterGrade(cuMemberRegister.getPkRegisterGrade());
                        cuMember.setPkSettleGrade(cuMemberRegister.getPkRegisterGrade());
                        cuMember.setConsumeMoney(BigDecimal.ZERO);
                        cuMember.setConsumeAchieve(cuMemberRegister.getConsumeAchieve());

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

                        // 查询最新一条手动升级记录
                        CuMemberLevel cuMemberLevel = iCuMemberDetailServiceApi.queryLastManualUpgrade(cuMember.getPkId()).getData();
                        if (null != cuMemberLevel) {
                            // 存在手动升级
                            cuMember.setPkSettleGrade(cuMemberLevel.getNewLevel());
                        }

                        // 查询最新的手动开通注册权限的记录
                        CuMemberServiceLog cuMemberServiceLog = iCuMemberServiceLogServiceApi.selectTopData(cuMember.getPkId(), EApprovalBusiness.REGISTER_POWER_STATE.getValue(), EApproveStatus.FINISH.getValue()).getData();
                        if (null != cuMemberServiceLog && StringUtils.isNotEmpty(cuMemberServiceLog.getNewValue())) {
                            // 存在手动开通
                            if (Integer.parseInt(cuMemberServiceLog.getNewValue()) > gradeDTO.getRegisterAuthority()) {
                                // 手动开通注册权限 大于 降级之后的权限，则保留手动开通的权限
                                cuMember.setRegisterAuthority(Integer.parseInt(cuMemberServiceLog.getNewValue()));
                            } else {
                                cuMember.setRegisterAuthority(gradeDTO.getRegisterAuthority());
                            }
                        }

                        SaOrder saOrder = baseMapper.queryLastRegisterOrUpdate(cuMember.getPkId(), cuMember.getPkCountry());
                        if (null != saOrder) {
                            // 撤消升级单之后，获取注册或者最后的升级单，填充注册金额
                            cuMember.setConsumeMoney(saOrder.getOrderAmount());
                        } else {
                            // 没有注册或者升级单，则直接扣减升级单的订单金额
                            cuMember.setConsumeMoney(ComputeUtil.computeSubtract(cuMember.getConsumeMoney(), saOrderExt.getOrderAmount()));
                        }
                        cuMember.setConsumeAchieve(gradeDTO.getStartValue());
                    }
                } else if (EOrderType.PICK_ORDER.getValue() == saOrderExt.getOrderType()) {
                    // 提货订单
                    if (!iAcPickService.cancelPickOrder(saOrderExt.getOrderCode(), pkApprove)) {
                        throw new RuntimeException("撤销订单退还提货失败");
                    }
                }

                if (!memberServiceApi.normalRevokeOrder(pkApprove, saOrderExt, cuMember, null, businessCommissionDTO).getData()) {
                    throw new RuntimeException("撤单处理会员失败");
                }
            }
        }
        // 订单撤销成功回退可用量
        // 验证订单是否有仓库，有仓库的可以回退，没有的回退
        if (saOrderExt.getPkStorehouse() != null) {
            saOrderExt.setPkModified(pkApprove);
            if (saOrderExt.getOrderItemsExtList() == null && CollectionUtil.isNotEmpty(saOrderExt.getOrderItemsList())) {
                List<SaOrderItemsExt> saOrderItemsExtList = new ArrayList<>();
                for (SaOrderItems saOrderItems : saOrderExt.getOrderItemsList()) {
                    SaOrderItemsExt saOrderItemsExt = BeanUtil.copyProperties(saOrderItems, SaOrderItemsExt.class);
                    saOrderItemsExtList.add(saOrderItemsExt);
                }
                saOrderExt.setOrderItemsExtList(saOrderItemsExtList);
            }
        }
        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);

//            if (EOrderType.UPGRADE_ORDER.getValue() == mqList.get(0).getOrderType()) {
//                // 升级订单撤单，只能一次撤一单，推送会员续约处理MQ
//                rabbitTemplate.convertAndSend(RabbitMqConstants.MEMBER_CONTINUE_EXCHANGE, RabbitMqConstants.MEMBER_CONTINUE_KEY,
//                        MemberContinueDTO.builder()
//                                .pkMemberList(Collections.singletonList(mqList.get(0).getPkMember()))
//                                .eMemberContinue(EMemberContinue.UPGRADE_CANCEL)
//                                .build());
//            } else if (EOrderType.REGISTER_ORDER.getValue() == mqList.get(0).getOrderType()) {
//                // 注册订单撤单，推送会员续约处理MQ
//                List<Long> pkMemberList = mqList.stream().map(SaOrderExt::getPkMember).collect(Collectors.toList());
//                rabbitTemplate.convertAndSend(RabbitMqConstants.MEMBER_CONTINUE_EXCHANGE, RabbitMqConstants.MEMBER_CONTINUE_KEY,
//                        MemberContinueDTO.builder()
//                                .pkMemberList(pkMemberList)
//                                .eMemberContinue(EMemberContinue.REGISTER_CANCEL)
//                                .build());
//            }
        } 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 RuntimeException("更新订单失败");
        }
    }


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

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

    /**
     * @param pkParent  推荐人
     * @param pkCountry 国家
     * @Description: 验证第二部门是否需要验证首单
     */
    @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;
    }

    /**
     * @param pkPlaceParent 安置位置
     * @param pkCountry     国家
     * @Description: 验证第二部门是否需要验证首单
     */
    @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> querySaOrderByTime(Date startDate, Date endDate, String orderCode) {
        return baseMapper.querySaOrderByTime(startDate, endDate, orderCode);
    }

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

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

    @Override
    public List<SaOrder> querySaOrderByTimeForCloud(Date startDate, Date endDate) {
        QueryWrapper<SaOrder> queryWrapper = new QueryWrapper<>();
        List<Integer> orderType = new ArrayList<>();
        orderType.add(EOrderType.REGISTER_ORDER.getValue());
        orderType.add(EOrderType.UPGRADE_ORDER.getValue());
        orderType.add(EOrderType.REPURCHASE_ORDER.getValue());
        queryWrapper.select("pk_id,pk_member,order_code,order_type,pk_rate,order_amount,order_achieve,rec_province,rec_city,rec_county,pk_country ")
                .eq(SaOrderFieldConstants.ORDER_STATUS, EOrderStatus.PAY.getValue())
                .ge(SaOrderFieldConstants.PAY_TIME, startDate)
                .lt(SaOrderFieldConstants.PAY_TIME, endDate)
                .in(SaOrderFieldConstants.ORDER_TYPE, orderType);
        return baseMapper.selectList(queryWrapper);
    }

    @Override
    public List<SaOrder> querySaOrderByTimeForCouponShare(Date startDate, Date endDate, List<Integer> orderTypeList, BigDecimal orderAmount, BigDecimal orderAchieve, Integer pkCountry) {
        return baseMapper.querySaOrderByTimeForCouponShare(startDate, endDate, orderTypeList, orderAmount, orderAchieve, pkCountry);
    }

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

    /**
     * @description: 自助撤单列表
     **/
    @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()
                || EOrderType.SPECIAL_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()
                || EOrderType.SPECIAL_REGISTER_ORDER.getValue() == saOrder.getOrderType()
        ) {
            if (!memberServiceApi.cancelMember(saOrder.getPkMember()).getData()) {
                throw new RuntimeException("取消订单失败");
            }
        }

        return null;
    }

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

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

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

        // 删除订单
        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);
    }

    /**
     * 商品订单信息
     *
     * @param waresOrderParam
     * @return
     */
    @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);
    }

    /**
     * @param orderParam    参数
     * @param cuMemberShare 会员分享
     *                      封装会员分享会员
     * @return: CuMember
     */
    private CuMember packageCuMemberShare(OrderParam orderParam, CuMemberShare cuMemberShare) {
        orderParam.setMemberCode(cuMemberShare.getMemberCode());
        orderParam.setMemberName(cuMemberShare.getMemberName());
        orderParam.setPhone(cuMemberShare.getPhone());
        orderParam.setParentId(cuMemberShare.getPkParent());
        orderParam.setCenterCodeId(cuMemberShare.getPkParent());
        CuMember parentMember = memberServiceApi.queryMember(cuMemberShare.getPkParent()).getData();
        if (parentMember == null) {
            return null;
        }
        orderParam.setPkCountry(cuMemberShare.getPkCountry());
        orderParam.setPkSettleCountry(parentMember.getPkSettleCountry());
        CuMember newCuMember = saOrderHandle.packageSaveUser(orderParam, parentMember);
        newCuMember.setPkId(cuMemberShare.getPkId());
        newCuMember.setPkCreator(cuMemberShare.getPkId());
        return newCuMember;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean onlinePaymentCallBack(Long pkMember, String orderCode) {
        if (StringUtils.isEmpty(orderCode)) {
            return Boolean.FALSE;
        }
        log.info("在线支付回调接受的参数pkMember:{}, orderCode:{}!", pkMember, orderCode);
        SaOrder querySaOrder = SaOrder.builder().orderStatus(EOrderStatus.WAIT_PAY.getValue()).orderCode(orderCode).build();

        SaOrderExt saOrderExt = querySaleOrderExtByOrderCode(querySaOrder, null);
        if (saOrderExt == null) {
            saOrderExt = redisService.getCacheObject(CacheConstants.TEMP_ORDER + pkMember + orderCode);
            if (saOrderExt == null) {
                return Boolean.FALSE;
            }
        }
        log.info("在线支付回调接受的参数1: {}", saOrderExt);
        if (EOrderType.REGISTER_ORDER.getValue() == saOrderExt.getOrderType()) {
            // 注册订单
            if (saOrderExt.getPkCreator().equals(saOrderExt.getPkMember())) {
                // 自注册分享订单
                saOrderExt.setPayType(EOrderPayType.ONLINE.getValue());
                payShareSaOrder(saOrderExt);
                return Boolean.TRUE;
            }
        } else if (EOrderType.REPURCHASE_ORDER.getValue() == saOrderExt.getOrderType()) {
            // 复购订单
            // 判断是否消费过生成了会员
            CuMember cuMember = getCuMemberByKey(saOrderExt.getPkMember());
            if (cuMember == null) {
                // 自注册分享订单
                saOrderExt.setPayType(EOrderPayType.ONLINE.getValue());
                payShareSaOrder(saOrderExt);
                return Boolean.TRUE;
            }
        }
        log.info("在线支付回调接受的参数2");
        CuMember newCuMember = null;
        if (saOrderExt.getPkMember() != null) {
            newCuMember = getCuMemberByKey(saOrderExt.getPkMember());
        }
        if (EOrderType.REGISTER_ORDER.getValue() == saOrderExt.getOrderType()
                || EOrderType.SPECIAL_REGISTER_ORDER.getValue() == saOrderExt.getOrderType()) {
            boolean isToBePay = getIsToBePayByOrderType(saOrderExt.getPkCountry(), saOrderExt.getOrderType());
            OrderParam orderParam = redisService.getCacheObject(CacheConstants.TEMP_PARAM + pkMember + orderCode);
            if (newCuMember == null && !isToBePay) {
                newCuMember = packageCuMember(orderParam);
                saOrderExt = packageSaOrder(orderParam, newCuMember);
            }
            if (newCuMember == null) {
                throw new RuntimeException("生成会员失败");
            }
            // 注册订单
            saOrderExt.setPayType(EOrderPayType.ONLINE.getValue());
            payRegSaOrder(saOrderExt, newCuMember, null, Boolean.FALSE);
        } else if (EOrderType.UPGRADE_ORDER.getValue() == saOrderExt.getOrderType()
                || EOrderType.SPECIAL_UPGRADE_ORDER.getValue() == saOrderExt.getOrderType()) {
            log.info("在线支付回调接受的参数saOrderExt:{}!", JSONUtil.toJsonStr(saOrderExt));
            // 升级订单
            saOrderExt.setPayType(EOrderPayType.ONLINE.getValue());
            payUpgradeSaOrder(saOrderExt, null);
        } else {
            // 其他订单
            log.info("在线支付回调其它订单参数saOrderExt:{}!!!", saOrderExt);
            saOrderExt.setPayType(EOrderPayType.ONLINE.getValue());
            payRepurchaseSaOrder(saOrderExt, null);
        }
        log.info("在线支付回调成功，返回{}", Boolean.TRUE);
        return Boolean.TRUE;
    }

    @Override
    public CuMemberShare queryCuMemberShare(Long pkMember) {
        return memberServiceApi.queryCuMemberShare(pkMember).getData();
    }

    /**
     * 支付分享订单
     *
     * @param saOrderExt 订单
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean payShareSaOrder(SaOrderExt saOrderExt) {
        CuMemberShare cuMemberShare = queryCuMemberShare(saOrderExt.getPkMember());
        CuMember newCuMember = packageCuMemberShare(OrderParam.builder().isHaiFun(Boolean.FALSE).build(), cuMemberShare);
        if (newCuMember == null) {
            return Boolean.FALSE;
        }
        if (setLastCuMemberGrade(newCuMember, saOrderExt)) {
            return Boolean.FALSE;
        }
        newCuMember.setPkId(saOrderExt.getPkMember());
        Date currentDateTime = DateUtils.currentDateTime();
        newCuMember.setPayStatus(EPayStatus.PAID.getValue());
        newCuMember.setPayTime(currentDateTime);

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

        newCuMember.setSource(EDataSource.APP.getValue());
        saOrderExt.setPayTime(currentDateTime);
        saOrderExt.setOrderStatus(EOrderStatus.PAY.getValue());
        saOrderExt.setPkModified(saOrderExt.getPkCreator());
        saOrderExt.setModifiedTime(currentDateTime);
        saOrderExt.getOrderItemsList().forEach(saOrderItems -> {
            saOrderItems.setPkModified(saOrderExt.getPkCreator());
            saOrderItems.setModifiedTime(currentDateTime);
            saOrderItems.setOrderStatus(EOrderStatus.PAY.getValue());
        });
        // 更新订单信息
        updateSaOrder(saOrderExt);
        CuMember cuMember = repeatTry(newCuMember, Boolean.TRUE);
        newCuMember.setPkPlaceParent(cuMember.getPkPlaceParent());
        newCuMember.setPlaceDept(cuMember.getPlaceDept());
        // 调用其他服务保存会员信息、会员注册信息
        R<Boolean> saveResult = memberServiceApi.saveMember(newCuMember, saOrderExt);
        if (saveResult.isSuccess()) {
            if (!saveResult.getData()) {
                log.error("payShareSaOrder 保存会员失败！");
                throw new RuntimeException("保存会员失败!");
            }
        } else {
            log.error("payShareSaOrder 保存会员失败！{}", saveResult.getMsg());
            throw new RuntimeException("保存会员失败!");
        }
        return Boolean.TRUE;
    }

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


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

    /**
     * 空单注册审核驳回
     *
     * @param approvalBusinessResultDTO
     * @return
     */
    @Override
    public Boolean regEmptyOrderReject(ApprovalBusinessResultDTO approvalBusinessResultDTO) {
        R<CuMemberServiceLog> cuMemberServiceLogR = iCuMemberServiceLogServiceApi.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());
        iCuMemberServiceLogServiceApi.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 = iMemberTradeServiceApi.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();
                        } else if (ESystemConfig.getPayMentTimeList().get(i).getKey().equals(ESystemConfig.PICK_ORDER_TIME.getKey())) {
                            // 提货专区
                            orderType = EOrderType.PICK_ORDER.getValue();
                        } else if (ESystemConfig.getPayMentTimeList().get(i).getKey().equals(ESystemConfig.WELFARE_ORDER_TIME.getKey())) {
                            // 福利订单
                            orderType = EOrderType.WELFARE_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 List<SaOrder> querySaOrderByOrderType(String payTime) {
        return baseMapper.querySaOrderByOrderType(payTime);
    }

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

    /**
     * 商品销量累计
     */
    @Override
    public void waresSalesAccrual(List<WaresNumberParam> waresNumberParamList) {
        try {
            if (waresNumberParamList.size() > 0) {
                iBdWaresExtendService.updateWaresSalesAccrual(waresNumberParamList);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

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

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

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

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

    @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 (ObjectUtil.isNotEmpty(saOrderExt)) {
            // 删除订单
            saOrderExt.setDelFlag(EDelFlag.DELETE.getValue());
            Date currentDate = DateUtils.currentDateTime();
            // 删除发货单
            saDeliverItemsService.deleteSaDeliverItems(saOrderExt.getPkId(), null);
            // 修改订单
            updateSaOrder(pkApprove, saOrderExt, currentDate);
            // 删除订单明细
            if (!saOrderItemsService.updateOrderItems(saOrderExt)) {
                throw new RuntimeException("更新订单失败");
            }

            // 添加订单日志表
            // 本批订单修改记录编号
            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.REGISTER_ORDER.getValue()
                    || myOrderVO.getOrderType() == EOrderType.SPECIAL_REGISTER_ORDER.getValue()) {
                // 逻辑删除会员
                if (!memberServiceApi.singleRevokeMemberBySelfRevokeOrder(pkApprove, saOrderExt, businessCommissionDTO).getData()) {
                    throw new RuntimeException("撤单失败");
                }
            } else {
                // 其他撤单 撤销升级订单
                CuMember cuMember = getCuMemberByKey(saOrderExt.getPkMember());
                if (EOrderType.UPGRADE_ORDER.getValue() == saOrderExt.getOrderType()
                        || EOrderType.SPECIAL_UPGRADE_ORDER.getValue() == saOrderExt.getOrderType()
                ) {
                    SaOrder updSaOrder = myOrderVO.getUpdSaOrder();
                    // 计算等级
                    // 获取升级订单
                    // 空单注册，从cu_member_register中获取
                    if (updSaOrder == null) {
                        CuMemberRegister cuMemberRegister = memberServiceApi.queryCuMemberRegister(saOrderExt.getPkMember()).getData();
                        cuMember.setPkRegisterGrade(cuMemberRegister.getPkRegisterGrade());
                        cuMember.setPkSettleGrade(cuMemberRegister.getPkRegisterGrade());
                        cuMember.setConsumeMoney(BigDecimal.ZERO);
                        cuMember.setConsumeAchieve(cuMemberRegister.getConsumeAchieve());
                    } else {
                        OrderReturn orderReturn = OrderReturn.builder().isEnough(false).build();
                        GradeDTO gradeDTO = calculateGradeDTO(EOrderType.UPGRADE_ORDER.getValue(), cuMember.getPkSettleCountry(), cuMember.getPkId(),
                                myOrderVO.getUpdSaOrder(), orderReturn);
                        cuMember.setPkRegisterGrade(gradeDTO.getPkId());
                        cuMember.setPkSettleGrade(gradeDTO.getPkId());

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

                        // 查询最新的手动开通注册权限的记录
                        CuMemberServiceLog cuMemberServiceLog = iCuMemberServiceLogServiceApi.selectTopData(cuMember.getPkId(), EApprovalBusiness.REGISTER_POWER_STATE.getValue(), EApproveStatus.FINISH.getValue()).getData();
                        if (null != cuMemberServiceLog && StringUtils.isNotEmpty(cuMemberServiceLog.getNewValue())) {
                            // 存在手动开通
                            if (Integer.parseInt(cuMemberServiceLog.getNewValue()) > gradeDTO.getRegisterAuthority()) {
                                // 手动开通注册权限 大于 降级之后的权限，则保留手动开通的权限
                                cuMember.setRegisterAuthority(Integer.parseInt(cuMemberServiceLog.getNewValue()));
                            } else {
                                cuMember.setRegisterAuthority(gradeDTO.getRegisterAuthority());
                            }
                        }

                        SaOrder saOrder = baseMapper.queryLastRegisterOrUpdate(cuMember.getPkId(), cuMember.getPkCountry());
                        if (null != saOrder) {
                            // 撤消升级单之后，获取注册或者最后的升级单，填充注册金额
                            cuMember.setConsumeMoney(saOrder.getOrderAmount());
                        } else {
                            // 没有注册或者升级单，则直接扣减升级单的订单金额
                            cuMember.setConsumeMoney(ComputeUtil.computeSubtract(cuMember.getConsumeMoney(), saOrderExt.getOrderAmount()));
                        }

                        cuMember.setConsumeAchieve(gradeDTO.getStartValue());
                    }
                } else if (myOrderVO.getOrderType() == EOrderType.PICK_ORDER.getValue()) {
                    //提货订单退还提货数量
                    if (!iAcPickService.cancelPickOrder(saOrderExt.getOrderCode(), pkApprove)) {
                        throw new RuntimeException("撤单失败");
                    }
                }

                if (!memberServiceApi.normalRevokeOrder(pkApprove, saOrderExt, cuMember, null, businessCommissionDTO).getData()) {
                    throw new RuntimeException("撤单失败");
                }
            }
            // 在线支付退款，已经迁移到调用member服务处理明细位置
//            R<TOnlinePayment> onlinePaymentR = itOnlinePaymentServiceApi.getOnlinePayment(saOrderExt.getOrderCode());
//            TOnlinePayment onlinePayment;
//            if(ObjectUtil.isNotEmpty(onlinePaymentR)){
//                onlinePayment = onlinePaymentR.getData();
//                if(ObjectUtil.isNotEmpty(onlinePayment)){
//                    R result = itOnlinePaymentServiceApi.refund(saOrderExt.getOrderCode(), SecurityUtils.getUserId());
//                    if(!result.isSuccess()){
//                        throw new ServiceException(result.getMsg());
//                    }
//                }
//            }
            try {
                // 验证订单是否有仓库，有仓库的可以回退，没有的回退
                if (saOrderExt.getPkStorehouse() != null) {
                    saOrderExt.setPkModified(pkApprove);
                    if (saOrderExt.getOrderItemsExtList() == null && CollectionUtil.isNotEmpty(saOrderExt.getOrderItemsList())) {
                        List<SaOrderItemsExt> saOrderItemsExtList = new ArrayList<>();
                        for (SaOrderItems saOrderItems : saOrderExt.getOrderItemsList()) {
                            SaOrderItemsExt saOrderItemsExt = BeanUtil.copyProperties(saOrderItems, SaOrderItemsExt.class);
                            saOrderItemsExtList.add(saOrderItemsExt);
                        }
                        saOrderExt.setOrderItemsExtList(saOrderItemsExtList);
                    }
                }

                // 推送MQ，处理活动回退
                rabbitTemplate.convertAndSend(RabbitMqConstants.ORDER_CANCEL_EXCHANGE, RabbitMqConstants.ORDER_CANCEL_KEY, Collections.singletonList(saOrderExt));

//                if (EOrderType.UPGRADE_ORDER.getValue() == saOrderExt.getOrderType()) {
//                    // 升级订单撤单，推送会员续约处理MQ
//                    rabbitTemplate.convertAndSend(RabbitMqConstants.MEMBER_CONTINUE_EXCHANGE, RabbitMqConstants.MEMBER_CONTINUE_KEY,
//                            MemberContinueDTO.builder()
//                                    .pkMemberList(Collections.singletonList(saOrderExt.getPkMember()))
//                                    .eMemberContinue(EMemberContinue.UPGRADE_CANCEL)
//                                    .build());
//                } else if (EOrderType.REGISTER_ORDER.getValue() == saOrderExt.getOrderType()) {
//                    // 注册订单撤单，推送会员续约处理MQ
//                    rabbitTemplate.convertAndSend(RabbitMqConstants.MEMBER_CONTINUE_EXCHANGE, RabbitMqConstants.MEMBER_CONTINUE_KEY,
//                            MemberContinueDTO.builder()
//                                    .pkMemberList(Collections.singletonList(saOrderExt.getPkMember()))
//                                    .eMemberContinue(EMemberContinue.REGISTER_CANCEL)
//                                    .build());
//                }
            } 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);
    }

    /**
     * 注册、升级处理乐学法宝券
     *
     * @param saOrderExt
     */
    private void handleLxPick(SaOrderExt saOrderExt) {
        Set<Integer> productIdList = saOrderExt.getOrderItemsList().stream().map(SaOrderItems::getPkProduct).collect(Collectors.toSet());
        List<BdProductExt> productExtList = iBdProductService.queryProductById(productIdList, saOrderExt.getPkCountry(), ERepurchaseType.LE_XUE_REGISTER.getValue());
        if (CollectionUtil.isNotEmpty(productExtList)) {
            Map<Integer, BdProductExt> productDtoMap = new HashMap<>(ComputeUtil.mapInitCapacity(productExtList.size()));
            productExtList.forEach(productDTO ->
                    productDtoMap.put(productDTO.getPkId(), productDTO));
            // 记录数量
            for (SaOrderItems saOrderItems : saOrderExt.getOrderItemsList()) {
                if (productDtoMap.containsKey(saOrderItems.getPkProduct())) {
                    BdProductExt productDTO = productDtoMap.get(saOrderItems.getPkProduct());
                    // 加入提货单
                    iAcPickService.addPickByActivity(saOrderExt.getPkMember(), EPickType.COUPON.getValue(), 0L, saOrderItems.getPkProduct().longValue(),
                            saOrderItems.getQuantity(), productDTO.getCover(), null, null,
                            saOrderExt.getPkCreator(), saOrderExt.getPkCountry(), null, saOrderItems.getSpecsNameId(), saOrderItems.getSpecsName());

                    // 法宝券数量冗余在订单主表
                    saOrderExt.setBoxNum(saOrderItems.getQuantity());
                }
            }
        }
    }

}
