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

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.hzs.bonus.settle.IMemberSettleBonusApi;
import com.hzs.common.core.constant.*;
import com.hzs.common.core.constant.msg.*;
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.exception.base.BaseException;
import com.hzs.common.core.utils.*;
import com.hzs.common.domain.member.account.CuMemberAccount;
import com.hzs.common.domain.member.base.CuMember;
import com.hzs.common.domain.member.ext.CuMemberAccountExt;
import com.hzs.common.domain.member.ext.CuMemberExt;
import com.hzs.common.domain.sale.deliver.SaDeliverItems;
import com.hzs.common.domain.sale.ext.SaOrderExt;
import com.hzs.common.domain.sale.ext.SaOrderItemsExt;
import com.hzs.common.domain.sale.order.SaOrder;
import com.hzs.common.domain.sale.order.SaOrderChargeLog;
import com.hzs.common.domain.sale.order.SaOrderItems;
import com.hzs.common.domain.sale.product.BdProduct;
import com.hzs.common.domain.sale.wares.BdWaresDetail;
import com.hzs.common.domain.system.base.BdStorehouse;
import com.hzs.common.domain.system.config.BdAccount;
import com.hzs.common.util.TransactionUtils;
import com.hzs.member.account.IBusinessCommission;
import com.hzs.member.account.IMemberAccountServiceApi;
import com.hzs.member.account.dto.BusinessCommissionDTO;
import com.hzs.member.account.dto.MemberAmountDTO;
import com.hzs.member.base.IMemberServiceApi;
import com.hzs.sale.deliver.param.DeductionSubmitParam;
import com.hzs.sale.deliver.service.ISaDeliverItemsService;
import com.hzs.sale.deliver.service.ISaDeliverService;
import com.hzs.sale.order.dto.*;
import com.hzs.sale.order.param.*;
import com.hzs.sale.order.service.*;
import com.hzs.sale.order.vo.MyOrderVO;
import com.hzs.sale.order.vo.OrderCancelRegisterMemberVO;
import com.hzs.sale.order.vo.ValidateCancelOrderVO;
import com.hzs.sale.product.service.IBdProductService;
import com.hzs.sale.pub.dto.OrderDeductionDTO;
import com.hzs.sale.wares.service.IBdWaresService;
import com.hzs.system.base.IAreaServiceApi;
import com.hzs.system.base.ICurrencyServiceApi;
import com.hzs.system.base.ISystemConfigServiceApi;
import com.hzs.system.base.dto.CurrencyDTO;
import com.hzs.system.config.IAccountServiceApi;
import com.hzs.system.config.IServiceChargeServiceApi;
import com.hzs.system.config.dto.ServiceChargeDTO;
import com.hzs.system.sys.IApprovalServiceApi;
import com.hzs.system.sys.dto.*;
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 org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 订单业务办理服务
 */
@Slf4j
@Service
public class OrderBusinessServiceImpl implements IOrderBusinessService {

    @Autowired
    private ISaOrderChargeLogService iSaOrderChargeLogService;
    @Autowired
    private ISaOrderService iSaOrderService;
    @Autowired
    private ISaOrderItemsService iSaOrderItemsService;
    @Autowired
    private ISaDeliverService iSaDeliverService;
    @Autowired
    private ISaDeliverItemsService iSaDeliverItemsService;
    @Autowired
    private IBdProductService iBdProductService;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private IBdWaresService iBdWaresService;

    @DubboReference
    IServiceChargeServiceApi iServiceChargeServiceApi;
    @DubboReference
    IApprovalServiceApi iApprovalServiceApi;
    @DubboReference
    IBusinessCommission iBusinessCommission;
    @DubboReference
    IMemberAccountServiceApi iMemberAccountServiceApi;
    @DubboReference
    IMemberServiceApi memberServiceApi;
    @DubboReference
    ICurrencyServiceApi iCurrencyServiceApi;
    @DubboReference
    IMemberSettleBonusApi iMemberSettleBonusApi;
    @DubboReference
    IAccountServiceApi iAccountServiceApi;
    @DubboReference
    ISystemConfigServiceApi systemConfigServiceApi;
    @DubboReference
    IAreaServiceApi iAreaServiceApi;


    /**
     * 校验是否有进行中审批
     *
     * @param orderCodeList 订单编号列表
     * @param pkCountry     所属国家
     * @return
     */
    @Override
    public String checkBusinessExist(List<String> orderCodeList, Integer pkCountry) {
        if (iSaOrderChargeLogService.checkOrderApprovalExist(
                Arrays.asList(
                        EApprovalBusiness.ORDER_CHANGE_ADDRESS.getValue(),
                        EApprovalBusiness.ORDER_CHANGE_PRODUCT.getValue(),
                        EApprovalBusiness.ORDER_RETURN.getValue(),
                        EApprovalBusiness.ORDER_CANCEL.getValue(),
                        EApprovalBusiness.ORDER_CANCEL_PRODUCT.getValue(),
                        EApprovalBusiness.SELF_DELIVERY_MANAGE.getValue(),
                        EApprovalBusiness.ORDER_DEDUCTION.getValue()
                ),
                orderCodeList,
                pkCountry
        ) > 0) {
            return TransactionUtils.getContent(SaOrderMsgConstants.ORDER_EXIST_OTHER_APPROVE);
        }
        return null;
    }

    @Override
    public String checkOrderDeliver(List<String> orderCodeList, Integer pkCountry) {
        if (iSaOrderItemsService.countOrderDeliver(orderCodeList, pkCountry) > 0) {
            return "订单已发货，不能修改地址";
        }
        return null;
    }

    @Override
    public String checkOrderRetailProduct(OrderProductParam param) {
        // 盒数商品对应的产品列表
        List<Integer> pkProductList = iBdWaresService.listBoxProduct(BoxProductUtil.getBoxWaresListBySystemType(null));
        // 换货产品列表
        List<Integer> paramProductList = param.getItemList().stream().map(OrderProductDetailParam::getPkProduct).collect(Collectors.toList());

        SaOrder saOrder = iSaOrderService.getOne(Wrappers.<SaOrder>lambdaQuery()
                .eq(SaOrder::getOrderCode, param.getOrderCode())
        );
        if (saOrder.getBoxNum().compareTo(BigDecimal.ZERO) > 0) {
            // 盒数商品订单，换货的产品是否都是盒数商品下的，如果是则可以进行更换，如果不是则不能更换
            for (Integer pkProduct : paramProductList) {
                if (!pkProductList.contains(pkProduct)) {
                    return "盒数商品与普通商品不能互相换货";
                }
            }
        } else {
            // 非盒数商品订单
            for (Integer pkProduct : paramProductList) {
                if (pkProductList.contains(pkProduct)) {
                    return "普通商品与盒数商品不能互相换货";
                }
            }
        }
        return null;
    }

    @Override
    public Map<Long, OrderQueryChargeDTO> queryChargeLog(List<SaOrderExt> saOrderList, EApprovalBusiness eApprovalBusiness, Integer pkCountry) {
        // key 订单编号， value 扣款实体
        Map<Long, OrderQueryChargeDTO> resultMap = new LinkedHashMap<>();
        // 订单ID列表
        List<Long> pkIdList = saOrderList.stream().map(SaOrderExt::getPkId).collect(Collectors.toList());
        // 创建人ID列表（支付人）
        List<Long> pkCreatorList = saOrderList.stream().map(SaOrderExt::getPkCreator).collect(Collectors.toList());
        // 查询订单修改过多少次
        Map<Long, Integer> logMap = iSaOrderChargeLogService.queryOrderAndLogCount(pkIdList, pkCountry);

        // 调用RPC查询扣款数据
        List<ServiceChargeDTO> serviceChargeParamList = new ArrayList<>();
        for (Long pkId : pkIdList) {
            serviceChargeParamList.add(ServiceChargeDTO.builder()
                    .pkCountry(pkCountry)
                    .type(eApprovalBusiness.getValue())
                    .quantity(logMap.get(pkId) + 1)
                    .build());
        }
        List<ServiceChargeDTO> serviceChargeList = iServiceChargeServiceApi.getServiceChargeByType(serviceChargeParamList).getData();

        // 订单创建人的账户
        Map<Long, CuMemberAccount> memberAccountMap = this.getRevokeMemberBySaOrder(pkCreatorList);
        // 目前币种
        List<BdAccount> accountList = iAccountServiceApi.queryAccountByType(null, pkCountry).getData();

        for (SaOrderExt saOrderExt : saOrderList) {
            // 订单ID
            Long pkId = saOrderExt.getPkId();
            // 先创建默认为0数据
            resultMap.put(pkId,
                    OrderQueryChargeDTO.builder()
                            .pkAccount(0)
                            .accountKey(0)
                            .cost(BigDecimal.ZERO)
                            .build());
            for (ServiceChargeDTO serviceChargeDTO : serviceChargeList) {
                if (serviceChargeDTO.getQuantity() < logMap.get(pkId) + 1 || serviceChargeDTO.getQuantity().equals(logMap.get(pkId) + 1)) {
                    OrderQueryChargeDTO dto = resultMap.get(pkId);
                    dto.setCost(serviceChargeDTO.getCost());

                    if (saOrderExt.getPkCountry().equals(CountryConstants.CHINA_COUNTRY)) {
                        // 需要按人进行扣款币种计算
                        BdAccount bdAccount = this.checkBusinessCost(memberAccountMap.get(saOrderExt.getPkCreator()), accountList, serviceChargeDTO.getCost());
                        if (null != bdAccount) {
                            dto.setPkAccount(bdAccount.getPkId());
                            dto.setAccountKey(bdAccount.getPkTransactionKey());
                        }
                    } else {
                        dto.setPkAccount(serviceChargeDTO.getPkAccount());
                        dto.setAccountKey(serviceChargeDTO.getAccountKey());
                    }

                    break;
                }
            }
        }
        return resultMap;
    }

    /**
     * 封装订单修改记录
     *
     * @param nowDate        当前时间
     * @param userId         用户ID
     * @param chargeType     修改类型
     * @param businessCode   修改记录单号
     * @param saOrder        订单
     * @param approvalStatus 审核状态
     * @return
     */
    private SaOrderChargeLog packageSaOrderChargeLog(Date nowDate, Long userId, Integer chargeType, String businessCode,
                                                     SaOrder 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;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public String changeAddressApprovalFreeSign(OrderAddressParam param, LoginUser loginUser) {
        // 修改地址订单参数列表
        List<OrderAddressDetailParam> detailList = param.getItemList();
        // 当前时间
        Date nowDate = new Date();
        // 用户ID
        Long userId = loginUser.getUserId();
        // 所属国家
        Integer pkCountry = loginUser.getDataCountry();
        // 订单修改条数
        int paramSize = detailList.size();
        // 订单ID列表
        List<Long> pkOrderList = new ArrayList<>(paramSize);
        // 订单信息列表
        List<SaOrderExt> orderList = new ArrayList<>(paramSize);
        // 更新订单列表
        List<SaOrder> updateOrderList = new ArrayList<>(paramSize);

        // 封装修改地址业务日志
        List<BusinessLogDTO> dtoList = new ArrayList<>(paramSize);
        // 获取行政区划map
        Map<Integer, String> areaMap = iAreaServiceApi.getAreaMap(pkCountry).getData();

        // 本批订单修改记录编号
        String businessCode = CommonUtil.createSerialNumber(EOrderPrefix.ORDER_CODE);

        // 按订单进行处理
        for (OrderAddressDetailParam detailParam : detailList) {
            // 查询订单收货地址信息
            SaOrderExt saOrder = iSaOrderService.queryOrderByCode(detailParam.getOrderCode(), pkCountry);
            if (null == saOrder) {
                return TransactionUtils.getContent(CommonMsgConstants.OPERATION_FAILED) + "：" + detailParam.getOrderCode() + SaOrderMsgConstants.ORDER_NOT_EXIST;
            }
            // 收集订单部分数据，以便后续业务使用
            orderList.add(saOrder);
            pkOrderList.add(saOrder.getPkId());

            // 根据收货省获取仓库
            BdStorehouse storehouse = iCurrencyServiceApi.queryBdStorehouseByProvince(detailParam.getRecProvince()).getData();

            // 根据修改记录后地址数据，修改订单信息
            SaOrder updateOrder = new SaOrder();
            updateOrder.setPkId(saOrder.getPkId());
            updateOrder.setRecName(detailParam.getRecName());
            updateOrder.setRecPhone(detailParam.getRecPhone());
            updateOrder.setRecProvince(detailParam.getRecProvince());
            updateOrder.setRecCity(detailParam.getRecCity());
            updateOrder.setRecCounty(detailParam.getRecCounty());
            updateOrder.setRecAddress(detailParam.getRecAddress());
            updateOrder.setPkModified(userId);
            updateOrder.setModifiedTime(nowDate);
            if (null != storehouse) {
                updateOrder.setPkStorehouse(storehouse.getPkId());
            }
            updateOrderList.add(updateOrder);

            // 封装修改订单业务日志
            dtoList.add(this.handleChangeAddressLog(saOrder, detailParam.getRecName(), detailParam.getRecPhone(),
                    detailParam.getRecProvince(), detailParam.getRecCity(), detailParam.getRecCounty(), detailParam.getRecAddress(),
                    areaMap, businessCode, userId, pkCountry, true));
        }

        // 业务手续费扣款DTO
        BusinessCommissionDTO businessCommissionDTO = null;
        if (EYesNo.NO.getIntValue() == param.getPayFlag()) {
            // 不免付，生成手续费处理
            businessCommissionDTO = this.handleChangeAddressCost(orderList, businessCode, pkCountry, userId);
        }

        // 批量更新订单
        iSaOrderService.updateBatchById(updateOrderList);
        // 修改发货单数据
        this.handleChangeAddressData(orderList, userId, pkCountry, nowDate);
        // 批量更新订单详情
        iSaOrderItemsService.updateToPayByPkOrder(pkOrderList, pkCountry, userId);

        // 扣款业务处理
        if (null != businessCommissionDTO) {
            R tmpR = iBusinessCommission.businessCommissionSubmit(businessCommissionDTO);
            if (!tmpR.isSuccess()) {
                log.error("订单业务处理扣款失败: {}", tmpR.getMsg());
                throw new ServiceException(tmpR.getMsg());
            }
        }

        // 推送业务操作日志
        rabbitTemplate.convertAndSend(RabbitMqConstants.BUSINESS_LOG_EXCHANGE, RabbitMqConstants.BUSINESS_LOG_KEY, dtoList);

        return null;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public String changeAddressApprovalSubmit(OrderAddressParam param, LoginUser loginUser) {
        // 修改地址订单参数列表
        List<OrderAddressDetailParam> detailList = param.getItemList();
        // 当前时间
        Date nowDate = new Date();
        // 用户ID
        Long userId = loginUser.getUserId();
        // 所属国家
        Integer pkCountry = loginUser.getDataCountry();
        // 订单修改条数
        int paramSize = detailList.size();
        // 订单修改记录列表
        List<SaOrderChargeLog> saOrderChargeLogList = new ArrayList<>(paramSize);
        // 订单信息列表
        List<SaOrderExt> orderList = new ArrayList<>(paramSize);
        // 涉及会员ID列表
        Set<Long> pkMemberList = new HashSet<>();

        // 封装修改地址业务日志
        List<BusinessLogDTO> dtoList = new ArrayList<>(paramSize);
        // 获取行政区划map
        Map<Integer, String> areaMap = iAreaServiceApi.getAreaMap(pkCountry).getData();

        // 本批订单修改记录编号
        String businessCode = CommonUtil.createSerialNumber(EOrderPrefix.ORDER_CODE);

        // 按订单进行处理
        for (OrderAddressDetailParam detailParam : detailList) {
            // 查询订单收货地址信息
            SaOrderExt saOrder = iSaOrderService.queryOrderByCode(detailParam.getOrderCode(), pkCountry);
            if (null == saOrder) {
                return TransactionUtils.getContent(CommonMsgConstants.OPERATION_FAILED) + "：" + detailParam.getOrderCode() + SaOrderMsgConstants.ORDER_NOT_EXIST;
            }
            // 收集订单部分数据，以便后续业务使用
            orderList.add(saOrder);
            // 记录涉及会员ID
            pkMemberList.add(saOrder.getPkCreator());

            // 保存订单修改记录
            SaOrderChargeLog saOrderChargeLog = packageSaOrderChargeLog(nowDate, userId, EApprovalBusiness.ORDER_CHANGE_ADDRESS.getValue(), businessCode, saOrder, EAgentApprovalStatus.UNAPPROVED.getValue());
            saOrderChargeLog.setBeforeData(JSONUtil.toJsonStr(BeanUtil.copyProperties(saOrder, OrderChangeAddressDTO.class)));
            saOrderChargeLog.setAfterData(JSONUtil.toJsonStr(BeanUtil.copyProperties(detailParam, OrderChangeAddressDTO.class)));
            saOrderChargeLogList.add(saOrderChargeLog);

            // 封装修改订单业务日志
            dtoList.add(this.handleChangeAddressLog(saOrder, detailParam.getRecName(), detailParam.getRecPhone(),
                    detailParam.getRecProvince(), detailParam.getRecCity(), detailParam.getRecCounty(), detailParam.getRecAddress(),
                    areaMap, businessCode, userId, pkCountry, false));
        }

        // 业务手续费扣款DTO
        BusinessCommissionDTO businessCommissionDTO = null;
        if (EYesNo.NO.getIntValue() == param.getPayFlag()) {
            // 不免付，生成手续费处理
            businessCommissionDTO = this.handleChangeAddressCost(orderList, businessCode, pkCountry, userId);
        }

        if (iSaOrderChargeLogService.saveBatch(saOrderChargeLogList)) {
            // 订单修改记录添加成功，提交签呈
            // 提交签呈处理
            String submitStr = this.submitApproval(EApprovalBusiness.ORDER_CHANGE_ADDRESS, businessCode, param.getSignType(), param.getRemark(), param.getFileList(),
                    param.getUserIdList(), param.getSendIdList(), pkMemberList, loginUser, businessCommissionDTO);
            if (null == submitStr) {
                // 推送业务操作日志
                rabbitTemplate.convertAndSend(RabbitMqConstants.BUSINESS_LOG_EXCHANGE, RabbitMqConstants.BUSINESS_LOG_KEY, dtoList);
            }
            return submitStr;
        }
        return TransactionUtils.getContent(CommonMsgConstants.OPERATION_FAILED);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public String changeAddressApprovalAgree(ApprovalBusinessResultDTO approvalBusinessResultDTO) {
        // 用户ID
        Long userId = approvalBusinessResultDTO.getLoginUser().getUserId();
        // 所属国家
        Integer pkCountry = approvalBusinessResultDTO.getLoginUser().getDataCountry();

        // 查询订单修改记录
        List<SaOrderChargeLog> saOrderChargeLogList = this.getSaOrderChargeLogs(approvalBusinessResultDTO, EApprovalBusiness.ORDER_CHANGE_ADDRESS);
        if (CollectionUtil.isEmpty(saOrderChargeLogList)) {
            log.error("订单修改地址同意处理失败: 签呈不存在!");
            return TransactionUtils.getContent(DocumentMsgConstants.DOCUMENT_NOT_EXISTS);
        }
        if (EAgentApprovalStatus.UNAPPROVED.getValue() != saOrderChargeLogList.get(0).getApprovalStatus()) {
            log.error("订单修改地址同意处理失败: 签呈已处理");
            return TransactionUtils.getContent(DocumentMsgConstants.DOCUMENT_HAS_HANDLE);
        }

        // 当前时间
        Date nowDate = new Date();
        // 订单ID列表
        List<Long> pkOrderList = new ArrayList<>(saOrderChargeLogList.size());
        // 订单信息列表
        List<SaOrderExt> orderList = new ArrayList<>(saOrderChargeLogList.size());
        // 更新订单列表
        List<SaOrder> updateOrderList = new ArrayList<>(saOrderChargeLogList.size());

        // 遍历订单修改记录，封装需要处理的数据
        for (SaOrderChargeLog saOrderChargeLog : saOrderChargeLogList) {
            // 查询订单
            SaOrderExt saOrder = iSaOrderService.queryOrderByPkId(saOrderChargeLog.getPkOrder(), pkCountry);
            if (null == saOrder) {
                log.error("订单修改地址同意处理失败: {} 订单不存在", saOrderChargeLog.getPkOrder());
                return TransactionUtils.getContent(DocumentMsgConstants.DOCUMENT_ORDER_NOT_EXISTS);
            }
            orderList.add(saOrder);
            pkOrderList.add(saOrderChargeLog.getPkOrder());

            // 根据修改记录后地址数据，修改订单信息
            OrderChangeAddressDTO orderChangeAddressDTO = JSONUtil.toBean(saOrderChargeLog.getAfterData(), OrderChangeAddressDTO.class);

            // 根据收货省获取仓库
            BdStorehouse storehouse = iCurrencyServiceApi.queryBdStorehouseByProvince(orderChangeAddressDTO.getRecProvince()).getData();

            SaOrder updateOrder = new SaOrder();
            updateOrder.setPkId(saOrder.getPkId());
            updateOrder.setRecName(orderChangeAddressDTO.getRecName());
            updateOrder.setRecPhone(orderChangeAddressDTO.getRecPhone());
            updateOrder.setRecProvince(orderChangeAddressDTO.getRecProvince());
            updateOrder.setRecCity(orderChangeAddressDTO.getRecCity());
            updateOrder.setRecCounty(orderChangeAddressDTO.getRecCounty());
            updateOrder.setRecAddress(orderChangeAddressDTO.getRecAddress());
            updateOrder.setPkModified(userId);
            updateOrder.setModifiedTime(nowDate);
            if (null != storehouse) {
                updateOrder.setPkStorehouse(storehouse.getPkId());
            }
            updateOrderList.add(updateOrder);
        }

        if (this.updateSaOrderChargeLog(EApprovalBusiness.ORDER_CHANGE_ADDRESS, approvalBusinessResultDTO.getBusinessCode(), pkCountry, userId,
                EAgentApprovalStatus.APPROVED, approvalBusinessResultDTO.getApproveRemark())) {
            // 更新订单修改记录成功

            // 批量更新订单
            iSaOrderService.updateBatchById(updateOrderList);
            // 修改发货单数据
            this.handleChangeAddressData(orderList, userId, pkCountry, nowDate);
            // 批量更新订单详情
            iSaOrderItemsService.updateToPayByPkOrder(pkOrderList, pkCountry, userId);

            return null;
        }
        log.error("订单修改地址同意处理失败: 更新数据失败");
        return TransactionUtils.getContent(DocumentMsgConstants.DOCUMENT_ORDER_ERROR);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public String changeAddressApprovalReject(ApprovalBusinessResultDTO approvalBusinessResultDTO) {
        // 用户ID
        Long userId = approvalBusinessResultDTO.getLoginUser().getUserId();
        // 所属国家
        Integer pkCountry = approvalBusinessResultDTO.getLoginUser().getDataCountry();

        // 查询订单修改记录
        List<SaOrderChargeLog> saOrderChargeLogList = this.getSaOrderChargeLogs(approvalBusinessResultDTO, EApprovalBusiness.ORDER_CHANGE_ADDRESS);
        if (CollectionUtil.isEmpty(saOrderChargeLogList)) {
            log.error("订单修改地址驳回处理失败: 签呈不存在!");
            return TransactionUtils.getContent(DocumentMsgConstants.DOCUMENT_NOT_EXISTS);
        }
        if (EAgentApprovalStatus.UNAPPROVED.getValue() != saOrderChargeLogList.get(0).getApprovalStatus()) {
            log.error("订单修改地址驳回处理失败: 签呈已处理");
            return TransactionUtils.getContent(DocumentMsgConstants.DOCUMENT_HAS_HANDLE);
        }

        // 遍历订单修改记录，封装需要处理的数据
        for (SaOrderChargeLog saOrderChargeLog : saOrderChargeLogList) {
            // 查询订单
            SaOrderExt saOrder = iSaOrderService.queryOrderByPkId(saOrderChargeLog.getPkOrder(), pkCountry);
            if (null == saOrder) {
                log.error("订单修改地址驳回处理失败: {} 订单不存在", saOrderChargeLog.getPkOrder());
                return TransactionUtils.getContent(DocumentMsgConstants.DOCUMENT_ORDER_NOT_EXISTS);
            }
        }

        if (this.updateSaOrderChargeLog(EApprovalBusiness.ORDER_CHANGE_ADDRESS, approvalBusinessResultDTO.getBusinessCode(), pkCountry, userId, EAgentApprovalStatus.REFUSE, approvalBusinessResultDTO.getApproveRemark())) {
            // 更新订单修改记录成功

            // 驳回业务处理（扣款回退）
            R resultR = iBusinessCommission.businessCommissionReject(BusinessCommissionDTO.builder()
                    .pkCountry(pkCountry)
                    .pkCreator(userId)
                    .tradeType(EApprovalBusiness.ORDER_CHANGE_ADDRESS.getValue())
                    .tradeCode(approvalBusinessResultDTO.getBusinessCode())
                    .build());
            if (!resultR.isSuccess()) {
                log.error("订单修改地址驳回处理扣款失败: {}", resultR.getMsg());
                // 签呈处理失败：业务扣款处理失败
                throw new BaseException(TransactionUtils.getContent(DocumentMsgConstants.DOCUMENT_ORDER_CHARGE_ERROR));
            }
            return null;
        }
        // 签呈处理失败：更新数据失败
        throw new BaseException(TransactionUtils.getContent(DocumentMsgConstants.DOCUMENT_ORDER_ERROR));
    }

    /**
     * 修改发货单数据
     *
     * @param saOrderList 订单列表
     * @param userId      用户ID
     * @param pkCountry   所属国家
     * @param nowDate     当前时间
     */
    private void handleChangeAddressData(List<SaOrderExt> saOrderList, Long userId, Integer pkCountry, Date nowDate) {
        for (SaOrderExt saOrder : saOrderList) {
            // 根据订单ID，查询 已合单未发货 状态的明细数据
            List<SaDeliverItems> saDeliverItemsList = iSaDeliverItemsService.queryDeliverItemsByOrder(saOrder.getPkId(), null, Collections.singletonList(EOrderStatus.SHIPPING.getValue()), pkCountry);
            if (CollectionUtil.isNotEmpty(saDeliverItemsList)) {
                // 删除发货明细数据
                List<Long> deliverItemsIdList = saDeliverItemsList.stream().map(SaDeliverItems::getPkId).collect(Collectors.toList());
                LambdaUpdateWrapper<SaDeliverItems> updateWrapper = new LambdaUpdateWrapper<>();
                updateWrapper.in(SaDeliverItems::getPkId, deliverItemsIdList);
                updateWrapper.set(SaDeliverItems::getDelFlag, EDelFlag.DELETE.getValue());
                updateWrapper.set(SaDeliverItems::getPkModified, userId);
                updateWrapper.set(SaDeliverItems::getModifiedTime, nowDate);
                iSaDeliverItemsService.update(updateWrapper);

                // 删除发货明细数据后，处理是否需要删除发货单
                Set<Long> deliverIdList = saDeliverItemsList.stream().map(SaDeliverItems::getPkDeliver).collect(Collectors.toSet());
                for (Long deliverId : deliverIdList) {
                    iSaDeliverService.deleteDeliverByItemsCount(deliverId, userId, pkCountry);
                }
            }
        }
    }

    @Override
    public String changeProductApprovalFreeSign(OrderProductParam param, LoginUser loginUser) {
        // 当前时间
        Date nowDate = new Date();
        // 用户ID
        Long userId = loginUser.getUserId();
        // 所属国家
        Integer pkCountry = loginUser.getDataCountry();

        // 订单编号
        String orderCode = param.getOrderCode();
        // 本批订单修改记录编号
        String businessCode = CommonUtil.createSerialNumber(EOrderPrefix.ORDER_CODE);

        // 查询订单信息
        SaOrderExt saOrder = iSaOrderService.queryOrderByCode(orderCode, pkCountry);
        if (null == saOrder) {
            return CommonMsgConstants.OPERATION_FAILED + "：" + orderCode + SaOrderMsgConstants.ORDER_NOT_EXIST;
        }
        // 订单支付日期 < 当前日期-7天
        Date beforeDate = DateUtils.addDate(DateUtils.getStartTime(nowDate), -7);
        if (beforeDate.compareTo(saOrder.getPayTime()) > 0) {
            return DocumentMsgConstants.DOCUMENT_ORDER_SETTLED;
        }

        // 操作日志内容
        StringBuilder content = new StringBuilder("订单编号：").append(saOrder.getOrderCode()).append("，");

        // 订单明细map（key=订单ID，value=订单明细）
        Map<Long, SaOrderItemsExt> orderItemsMap = new HashMap<>();
        // 改前数据
        OrderChangeProductDTO beforeData = this.changeProductBeforeDataHandle(saOrder, orderItemsMap, content);
        // 改后数据
        OrderChangeProductDTO afterData = this.changeProductAfterDataHandle(saOrder, orderItemsMap, param, content);
        // 封装订单修改记录（不走签呈，直接算审核通过）
        SaOrderChargeLog saOrderChargeLog = this.packageSaOrderChargeLog(nowDate, userId, EApprovalBusiness.ORDER_CHANGE_PRODUCT.getValue(), businessCode, saOrder, EAgentApprovalStatus.APPROVED.getValue());
        saOrderChargeLog.setBeforeData(JSONUtil.toJsonStr(beforeData));
        saOrderChargeLog.setAfterData(JSONUtil.toJsonStr(afterData));

        // 封装业务操作日志
        BusinessLogDTO logDTO = BusinessLogDTO.builder()
                .businessType(EApprovalBusiness.ORDER_CHANGE_PRODUCT.getValue())
                .businessCode(businessCode)
                .pkMember(saOrder.getPkMember())
                .content(content.toString())
                .pkCreator(userId)
                .pkCountry(pkCountry)
                .freeSignFlag(true)
                .build();

        // 业务手续费扣款DTO
        BusinessCommissionDTO dto = null;
        if (EYesNo.NO.getIntValue() == param.getPayFlag()) {
            // 不免付，生成手续费处理
            dto = this.changeProductCostHandle(saOrder, userId, pkCountry, orderCode);
        }

        // 封装订单数据
        SaOrder updateOrder = BeanUtil.copyProperties(saOrder, SaOrder.class);
        updateOrder.setPkId(saOrder.getPkId());
        updateOrder.setOrderAmount(afterData.getOrderAmount());
        updateOrder.setOrderAchieve(afterData.getOrderAchieve());
        updateOrder.setOrderAssAchieve(afterData.getOrderAssAchieve());
        updateOrder.setPostage(param.getPostage());
        updateOrder.setPkModified(userId);
        updateOrder.setModifiedTime(nowDate);

        // 插入订单明细数据
        List<SaOrderItems> createOrderItemsList = new ArrayList<>();
        // 更新订单明细数据
        List<SaOrderItems> updateOrderItemsList = new ArrayList<>();
        // 修改订单明细ID列表
        List<Long> changeIdList = new ArrayList<>();
        // 未修改订单明细ID列表
        List<Long> noChangeIdList = new ArrayList<>();
        // 调换货物入库数据处理
        this.chargeProductUpdateDataHandle(createOrderItemsList, updateOrderItemsList, changeIdList, noChangeIdList,
                saOrder, afterData, userId, pkCountry, nowDate);

        // 添加校验，订单详情是否已经发货
        LambdaQueryWrapper<SaOrderItems> orderItemsQueryWrapper = new LambdaQueryWrapper<>();
        orderItemsQueryWrapper.in(SaOrderItems::getPkId, changeIdList);
        orderItemsQueryWrapper.in(SaOrderItems::getOrderStatus, EOrderStatus.DELIVERED.getValue(), EOrderStatus.RECEIVED.getValue());
        if (iSaOrderItemsService.count(orderItemsQueryWrapper) > 0) {
            // 订单已经发货，不能进行调换货物
            return "订单已经发货，不能进行调换货物";
        }

        // 修改前的订单金额 + 邮费
        BigDecimal beforeAmount = saOrder.getOrderAmount().add(saOrder.getPostage()).setScale(2, BigDecimal.ROUND_HALF_UP);
        // 修改后的订单金额 + 邮费
        BigDecimal afterAmount = afterData.getOrderAmount().add(param.getPostage()).setScale(2, BigDecimal.ROUND_HALF_UP);
        // 校验订单原订单价格和调换完货之后的价格不相同不进行换货
        if (beforeAmount.compareTo(afterAmount) != 0) {
            return CommonMsgConstants.OPERATION_FAILED + "：" + param.getOrderCode() + SaOrderMsgConstants.PRODUCT_CONFIRM_PRICE;
        }

        if (iSaOrderChargeLogService.save(saOrderChargeLog)) {
            // 处理调换货物数据
            this.handleChangeProductData(updateOrder, createOrderItemsList, updateOrderItemsList,
                    changeIdList, noChangeIdList,
                    userId, pkCountry, nowDate);

            if (null != dto) {
                // 订单总价未变化，但是需要手续费
                R resultR = iMemberAccountServiceApi.orderChangeProduct(null, null, userId, dto);
                if (!resultR.isSuccess()) {
                    throw new BaseException(resultR.getMsg());
                }
            }

            // 推送业务操作日志
            rabbitTemplate.convertAndSend(RabbitMqConstants.BUSINESS_LOG_EXCHANGE, RabbitMqConstants.BUSINESS_LOG_KEY, Collections.singletonList(logDTO));

        }
        return null;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public String changeProductApprovalSubmit(OrderProductParam param, LoginUser loginUser) {
        // 当前时间
        Date nowDate = new Date();
        // 用户ID
        Long userId = loginUser.getUserId();
        // 所属国家
        Integer pkCountry = loginUser.getDataCountry();

        // 订单编号
        String orderCode = param.getOrderCode();
        // 本批订单修改记录编号
        String businessCode = CommonUtil.createSerialNumber(EOrderPrefix.ORDER_CODE);

        // 查询订单收货地址信息
        SaOrderExt saOrder = iSaOrderService.queryOrderByCode(orderCode, pkCountry);
        if (null == saOrder) {
            return CommonMsgConstants.OPERATION_FAILED + "：" + orderCode + SaOrderMsgConstants.ORDER_NOT_EXIST;
        }
        // 订单支付日期 < 当前日期-7天
        Date beforeDate = DateUtils.addDate(DateUtils.getStartTime(nowDate), -7);
        if (beforeDate.compareTo(saOrder.getPayTime()) > 0) {
            return DocumentMsgConstants.DOCUMENT_ORDER_SETTLED;
        }

        // 涉及会员ID列表
        Set<Long> pkMemberList = new HashSet<>();
        // 记录涉及会员ID
        pkMemberList.add(saOrder.getPkCreator());

        // 操作日志内容
        StringBuilder content = new StringBuilder("订单编号：").append(saOrder.getOrderCode()).append("，");

        // 订单明细map（key=订单ID，value=订单明细）
        Map<Long, SaOrderItemsExt> orderItemsMap = new HashMap<>();
        // 改前数据
        OrderChangeProductDTO beforeData = this.changeProductBeforeDataHandle(saOrder, orderItemsMap, content);
        // 改后数据
        OrderChangeProductDTO afterData = this.changeProductAfterDataHandle(saOrder, orderItemsMap, param, content);
        // 封装订单修改记录
        SaOrderChargeLog saOrderChargeLog = this.packageSaOrderChargeLog(nowDate, userId, EApprovalBusiness.ORDER_CHANGE_PRODUCT.getValue(), businessCode, saOrder, EAgentApprovalStatus.UNAPPROVED.getValue());
        saOrderChargeLog.setBeforeData(JSONUtil.toJsonStr(beforeData));
        saOrderChargeLog.setAfterData(JSONUtil.toJsonStr(afterData));

        // 封装业务操作日志
        BusinessLogDTO logDTO = BusinessLogDTO.builder()
                .businessType(EApprovalBusiness.ORDER_CHANGE_PRODUCT.getValue())
                .businessCode(businessCode)
                .pkMember(saOrder.getPkMember())
                .content(content.toString())
                .pkCreator(userId)
                .pkCountry(pkCountry)
                .freeSignFlag(true)
                .build();

        // 业务手续费扣款DTO
        BusinessCommissionDTO dto = null;
        if (EYesNo.NO.getIntValue() == param.getPayFlag()) {
            // 不免付，生成手续费处理
            dto = this.changeProductCostHandle(saOrder, userId, pkCountry, businessCode);
        }

        // 判断订单价格是否足够
        // 修改前的订单金额 + 邮费
        BigDecimal beforeAmount = saOrder.getOrderAmount().add(saOrder.getPostage()).setScale(2, BigDecimal.ROUND_HALF_UP);
        // 修改后的订单金额 + 邮费
        BigDecimal afterAmount = afterData.getOrderAmount().add(param.getPostage()).setScale(2, BigDecimal.ROUND_HALF_UP);
        //校验订单原订单价格和调换完货之后的价格不相同不进行换货
        if (beforeAmount.compareTo(afterAmount) != 0) {
            return CommonMsgConstants.OPERATION_FAILED + "：" + param.getOrderCode() + SaOrderMsgConstants.PRODUCT_CONFIRM_PRICE;
        }

        if (iSaOrderChargeLogService.save(saOrderChargeLog)) {
            // 订单修改记录添加成功，发起审批
            // 提交签呈处理
            String submitStr = this.submitApproval(EApprovalBusiness.ORDER_CHANGE_PRODUCT, businessCode, param.getSignType(), param.getRemark(), param.getFileList(),
                    param.getUserIdList(), param.getSendIdList(), pkMemberList, loginUser, dto);
            if (null == submitStr) {
                // 推送业务操作日志
                rabbitTemplate.convertAndSend(RabbitMqConstants.BUSINESS_LOG_EXCHANGE, RabbitMqConstants.BUSINESS_LOG_KEY, Collections.singletonList(logDTO));
            }
            return submitStr;
        }
        return CommonMsgConstants.OPERATION_FAILED;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public String changeProductApprovalAgree(ApprovalBusinessResultDTO approvalBusinessResultDTO) {
        // 用户ID
        Long userId = approvalBusinessResultDTO.getLoginUser().getUserId();
        // 所属国家
        Integer pkCountry = approvalBusinessResultDTO.getLoginUser().getDataCountry();

        // 查询订单修改记录
        List<SaOrderChargeLog> saOrderChargeLogList = this.getSaOrderChargeLogs(approvalBusinessResultDTO, EApprovalBusiness.ORDER_CHANGE_PRODUCT);
        if (CollectionUtil.isEmpty(saOrderChargeLogList)) {
            log.error("订单调换货物驳回处理失败: 签呈不存在!");
            return TransactionUtils.getContent(DocumentMsgConstants.DOCUMENT_NOT_EXISTS);
        }
        // 需要处理的订单修改记录
        SaOrderChargeLog saOrderChargeLog = saOrderChargeLogList.get(0);
        if (EAgentApprovalStatus.UNAPPROVED.getValue() != saOrderChargeLog.getApprovalStatus()) {
            log.error("订单调换货物同意处理失败: 签呈已处理!");
            return TransactionUtils.getContent(DocumentMsgConstants.DOCUMENT_HAS_HANDLE);
        }

        // 查询订单
        SaOrder saOrder = iSaOrderService.getById(saOrderChargeLog.getPkOrder());
        if (null == saOrder) {
            log.error("订单调换货物同意处理失败: 订单不存在");
            return TransactionUtils.getContent(DocumentMsgConstants.DOCUMENT_ORDER_NOT_EXISTS);
        }

        // 当前时间
        Date nowDate = new Date();

        // 订单支付日期 < 当前日期-7天
        Date beforeDate = DateUtils.addDate(DateUtils.getStartTime(nowDate), -7);
        if (beforeDate.compareTo(saOrder.getPayTime()) > 0) {
            log.error("订单调换货物同意处理失败: 订单已超过7天");
            return TransactionUtils.getContent(DocumentMsgConstants.DOCUMENT_ORDER_SETTLED);
        }

        // 修改后数据
        OrderChangeProductDTO afterData = JSONUtil.toBean(saOrderChargeLog.getAfterData(), OrderChangeProductDTO.class);

        // 封装订单数据
        SaOrder updateOrder = BeanUtil.copyProperties(saOrder, SaOrder.class);
        updateOrder.setPkId(saOrder.getPkId());
        updateOrder.setOrderAmount(afterData.getOrderAmount());
        updateOrder.setOrderAchieve(afterData.getOrderAchieve());
        updateOrder.setOrderAssAchieve(afterData.getOrderAssAchieve());
        updateOrder.setPostage(afterData.getPostage());
        updateOrder.setPkModified(userId);
        updateOrder.setModifiedTime(nowDate);

        // 插入订单明细数据
        List<SaOrderItems> createOrderItemsList = new ArrayList<>();
        // 更新订单明细数据
        List<SaOrderItems> updateOrderItemsList = new ArrayList<>();
        // 修改订单明细ID列表
        List<Long> changeIdList = new ArrayList<>();
        // 未修改订单明细ID列表
        List<Long> noChangeIdList = new ArrayList<>();
        // 调换货物入库数据处理
        this.chargeProductUpdateDataHandle(createOrderItemsList, updateOrderItemsList, changeIdList, noChangeIdList,
                saOrder, afterData, userId, pkCountry, nowDate);

        // 添加校验，订单详情是否已经发货
        LambdaQueryWrapper<SaOrderItems> orderItemsQueryWrapper = new LambdaQueryWrapper<>();
        orderItemsQueryWrapper.in(SaOrderItems::getPkId, changeIdList);
        orderItemsQueryWrapper.in(SaOrderItems::getOrderStatus, EOrderStatus.DELIVERED.getValue(), EOrderStatus.RECEIVED.getValue());
        if (iSaOrderItemsService.count(orderItemsQueryWrapper) > 0) {
            // 订单已经发货，不能进行调换货物
            return "订单已经发货，不能进行调换货物";
        }

        // 是否扣款
        boolean orderCostFlag = false;
        // 修改前的订单金额 + 邮费
        BigDecimal beforeAmount = saOrder.getOrderAmount().add(saOrder.getPostage());
        // 修改后的订单金额 + 邮费
        BigDecimal afterAmount = afterData.getOrderAmount().add(afterData.getPostage());
        // 对比修改前后订单价格处理是否补差价
        if (beforeAmount.compareTo(afterAmount) != 0) {
            orderCostFlag = true;
        }

        if (this.updateSaOrderChargeLog(EApprovalBusiness.ORDER_CHANGE_PRODUCT, approvalBusinessResultDTO.getBusinessCode(), pkCountry, userId, EAgentApprovalStatus.APPROVED, approvalBusinessResultDTO.getApproveRemark())) {
            // 订单修改记录添加成功

            // 处理调换货物数据
            this.handleChangeProductData(updateOrder, createOrderItemsList, updateOrderItemsList,
                    changeIdList, noChangeIdList,
                    userId, pkCountry, nowDate);

            if (orderCostFlag) {
                // 订单调换货物扣费处理
                R resultR = iMemberAccountServiceApi.orderChangeProduct(saOrder, updateOrder, userId, null);
                if (!resultR.isSuccess()) {
                    log.error("订单调换货物同意处理失败: {}", resultR.getMsg());
                    throw new BaseException(TransactionUtils.getContent(CommonMsgConstants.APPROVAL_ERROR) + "：" + resultR.getMsg());
                }
            }
            return null;
        }
        log.error("订单调换货物同意处理失败: 更新数据失败");
        return TransactionUtils.getContent(DocumentMsgConstants.DOCUMENT_ORDER_ERROR);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public String changeProductApprovalReject(ApprovalBusinessResultDTO approvalBusinessResultDTO) {
        // 用户ID
        Long userId = approvalBusinessResultDTO.getLoginUser().getUserId();
        // 所属国家
        Integer pkCountry = approvalBusinessResultDTO.getLoginUser().getDataCountry();

        // 查询订单修改记录
        List<SaOrderChargeLog> saOrderChargeLogList = this.getSaOrderChargeLogs(approvalBusinessResultDTO, EApprovalBusiness.ORDER_CHANGE_PRODUCT);
        if (CollectionUtil.isEmpty(saOrderChargeLogList)) {
            log.error("订单调换货物驳回处理失败: 签呈不存在!");
            return TransactionUtils.getContent(DocumentMsgConstants.DOCUMENT_NOT_EXISTS);
        }
        // 需要处理的订单修改记录
        SaOrderChargeLog saOrderChargeLog = saOrderChargeLogList.get(0);
        if (EAgentApprovalStatus.UNAPPROVED.getValue() != saOrderChargeLog.getApprovalStatus()) {
            log.error("订单调换货物驳回处理失败: 签呈已处理!");
            return TransactionUtils.getContent(DocumentMsgConstants.DOCUMENT_HAS_HANDLE);
        }

        // 查询订单
        SaOrderExt saOrder = iSaOrderService.queryOrderByPkId(saOrderChargeLog.getPkOrder(), null);
        if (null == saOrder) {
            log.error("订单调换货物驳回处理失败: {} 订单不存在", saOrderChargeLog.getPkOrder());
            return TransactionUtils.getContent(DocumentMsgConstants.DOCUMENT_ORDER_NOT_EXISTS);
        }

        // 修改后数据
        OrderChangeProductDTO afterData = JSONUtil.toBean(saOrderChargeLog.getAfterData(), OrderChangeProductDTO.class);

        if (this.updateSaOrderChargeLog(EApprovalBusiness.ORDER_CHANGE_PRODUCT, approvalBusinessResultDTO.getBusinessCode(), pkCountry, userId, EAgentApprovalStatus.REFUSE, approvalBusinessResultDTO.getApproveRemark())) {
            // 更新订单修改记录成功

            if (EYesNo.NO.getIntValue() == afterData.getPayFlag()) {
                // 不免付，驳回需要退款
                // 驳回业务处理（扣款回退）
                R resultR = iBusinessCommission.businessCommissionReject(BusinessCommissionDTO.builder()
                        .pkCountry(pkCountry)
                        .pkCreator(userId)
                        .tradeType(EApprovalBusiness.ORDER_CHANGE_PRODUCT.getValue())
                        .tradeCode(approvalBusinessResultDTO.getBusinessCode())
                        .build());
                if (!resultR.isSuccess()) {
                    log.error("订单修改地址驳回处理扣款失败: {}", resultR.getMsg());
                    throw new BaseException(TransactionUtils.getContent(DocumentMsgConstants.DOCUMENT_ORDER_CHARGE_ERROR));
                }
            }
            return null;
        }
        log.error("订单调换货物驳回处理失败：更新数据失败");
        throw new BaseException(TransactionUtils.getContent(DocumentMsgConstants.DOCUMENT_ORDER_ERROR));
    }

    /**
     * 处理调换货物数据（订单+发货单）
     *
     * @param updateOrder          更新订单
     * @param createOrderItemsList 创建订单明细列表
     * @param updateOrderItemsList 更新订单明细列表
     * @param changeIdList         修改订单明细ID列表
     * @param noChangeIdList       未修改订单明细ID列表
     * @param userId               用户ID
     * @param pkCountry            所属国家
     * @param nowDate              当前时间
     */
    private void handleChangeProductData(SaOrder updateOrder, List<SaOrderItems> createOrderItemsList, List<SaOrderItems> updateOrderItemsList,
                                         List<Long> changeIdList, List<Long> noChangeIdList,
                                         Long userId, Integer pkCountry, Date nowDate) {
        // 订单ID
        Long orderPkId = updateOrder.getPkId();

        // 根据订单ID，查询 已合单未发货 状态的明细数据
        List<SaDeliverItems> saDeliverItemsList = iSaDeliverItemsService.queryDeliverItemsByOrder(orderPkId, noChangeIdList, Collections.singletonList(EOrderStatus.SHIPPING.getValue()), pkCountry);
        if (CollectionUtil.isNotEmpty(saDeliverItemsList)) {
            // 删除发货明细数据
            List<Long> deliverItemsIdList = saDeliverItemsList.stream().map(SaDeliverItems::getPkId).collect(Collectors.toList());
            LambdaUpdateWrapper<SaDeliverItems> deliverItemsUpdateWrapper = new LambdaUpdateWrapper<>();
            deliverItemsUpdateWrapper.in(SaDeliverItems::getPkId, deliverItemsIdList);
            deliverItemsUpdateWrapper.set(SaDeliverItems::getDelFlag, EDelFlag.DELETE.getValue());
            deliverItemsUpdateWrapper.set(SaDeliverItems::getPkModified, userId);
            deliverItemsUpdateWrapper.set(SaDeliverItems::getModifiedTime, nowDate);
            // 逻辑删除旧发货单明细，并标记为换货
            deliverItemsUpdateWrapper.set(SaDeliverItems::getExchangeGoods, EYesNo.YES.getIntValue());
            iSaDeliverItemsService.update(deliverItemsUpdateWrapper);

            // 删除发货明细数据后，处理是否需要删除发货单
            Set<Long> deliverIdSet = saDeliverItemsList.stream().map(SaDeliverItems::getPkDeliver).collect(Collectors.toSet());
            for (Long deliverId : deliverIdSet) {
                iSaDeliverService.deleteDeliverByItemsCount(deliverId, userId, pkCountry);
            }
        }
        if (CollectionUtil.isNotEmpty(changeIdList)) {
            // 根据修改的订单明细ID，删除 已付款、已合单 之外的订单明细
            LambdaUpdateWrapper<SaOrderItems> orderItemsUpdateWrapper = new LambdaUpdateWrapper<>();
            orderItemsUpdateWrapper.eq(SaOrderItems::getPkOrder, orderPkId);
            orderItemsUpdateWrapper.notIn(SaOrderItems::getPkId, changeIdList);
            orderItemsUpdateWrapper.in(SaOrderItems::getOrderStatus, Arrays.asList(EOrderStatus.PAY.getValue(), EOrderStatus.SHIPPING.getValue()));
            orderItemsUpdateWrapper.eq(SaOrderItems::getDelFlag, EDelFlag.UN_DELETE.getValue());
            orderItemsUpdateWrapper.set(SaOrderItems::getDelFlag, EDelFlag.DELETE.getValue());
            // 逻辑删除旧订单明细，并标记为换货
            orderItemsUpdateWrapper.set(SaOrderItems::getExchangeGoods, EYesNo.YES.getIntValue());
            orderItemsUpdateWrapper.set(SaOrderItems::getPkModified, userId);
            orderItemsUpdateWrapper.set(SaOrderItems::getModifiedTime, nowDate);
            iSaOrderItemsService.update(orderItemsUpdateWrapper);
        }

        // 更新订单列表
        iSaOrderService.updateById(updateOrder);
        // 插入订单明细
        iSaOrderItemsService.saveBatch(createOrderItemsList);
        // 更新订单明细
        for (SaOrderItems saOrderItems : updateOrderItemsList) {
            iSaOrderItemsService.updateById(saOrderItems);
        }
    }


    @Override
    public String returnOrderApprovalSubmit(OrderReturnParam param, LoginUser loginUser) {
        // 所属国家
        Integer pkCountry = loginUser.getDataCountry();

        // 本批订单修改记录编号
        String businessCode = CommonUtil.createSerialNumber(EOrderPrefix.ORDER_CODE);
        // 订单编号
        String orderCode = param.getOrderCode();

        // 查询订单收货地址信息
        SaOrderExt saOrder = iSaOrderService.queryOrderByCode(orderCode, pkCountry);
        if (null == saOrder) {
            // 订单已不存在
            return TransactionUtils.getContent(CommonMsgConstants.OPERATION_FAILED) + "：" + orderCode + TransactionUtils.getContent(SaOrderMsgConstants.ORDER_NOT_EXIST);
        }
        if (EPayStatus.UNPAID.getValue() == saOrder.getOrderStatus()) {
            // 未支付订单，不能进行退单
            return TransactionUtils.getContent(CommonMsgConstants.OPERATION_FAILED) + "：" + TransactionUtils.getContent(SaOrderMsgConstants.ORDER_UNPAID_NOT_RETURN);
        }

        // 涉及会员ID列表
        Set<Long> pkMemberList = new HashSet<>();
        // 记录涉及会员ID
        pkMemberList.add(saOrder.getPkCreator());

        // 封装订单修改记录
        SaOrderChargeLog saOrderChargeLog = this.packageSaOrderChargeLog(new Date(), loginUser.getUserId(), EApprovalBusiness.ORDER_RETURN.getValue(), businessCode, saOrder, EAgentApprovalStatus.UNAPPROVED.getValue());
        // 修改后数据
        saOrderChargeLog.setAfterData(JSONUtil.toJsonStr(OrderReturnDTO.builder()
                .orderCode(orderCode)
                .returnAmount(param.getReturnAmount())
                .returnRemark(param.getReturnRemark())
                .returnType(1)
                .build()));

        if (iSaOrderChargeLogService.save(saOrderChargeLog)) {
            // 订单修改记录添加成功，发起审批

            // 提交签呈处理
            return this.submitApproval(EApprovalBusiness.ORDER_RETURN, businessCode, param.getSignType(), param.getRemark(), param.getFileList(),
                    param.getUserIdList(), param.getSendIdList(), pkMemberList, loginUser, null);
        }
        return TransactionUtils.getContent(CommonMsgConstants.OPERATION_FAILED);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public String batchReturnOrderApprovalSubmit(OrderReturnBatchParam param, LoginUser loginUser) {
        // 当前时间
        Date nowDate = new Date();
        // 用户ID
        Long userId = loginUser.getUserId();
        // 所属国家
        Integer pkCountry = loginUser.getDataCountry();
        // 订单退单编号列表
        List<String> orderCodeList = param.getOrderReturnParamList().stream().map(OrderReturnParam::getOrderCode).collect(Collectors.toList());

        LambdaQueryWrapper<SaOrder> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(SaOrder::getOrderCode, orderCodeList);
        queryWrapper.eq(SaOrder::getPkCountry, pkCountry);
        List<SaOrder> saOrderList = iSaOrderService.list(queryWrapper);
        if (CollectionUtil.isEmpty(saOrderList)) {
            return "订单不存在";
        }

        SaOrder saOrder = saOrderList.get(0);

        // 获得当前国家是日结还是周结
        String settleCycle = systemConfigServiceApi.getBonusSystemConfig(pkCountry, ESystemConfig.EXPAND_CAP_METHOD.getKey()).getData();
        // 控制是否显示退单
        if (Objects.equals(Integer.toString(EExpandCapMethod.WEEK_SETTLE.getValue()), settleCycle)) {
            // 周结
            if (!DateUtils.compareDateAfter(DateUtils.parseStringToDate(DateUtils.getRecentlyTuesday(DateUtils.currentDate())), saOrder.getPayTime())) {
                return TransactionUtils.getContent(SaOrderMsgConstants.WEEK_CANCEL_SEVEN_PAY_ORDER);
            }
        } else {
            // 日结
            if (!DateUtils.compareDateAfter(DateUtils.beforeDate(MagicNumberConstants.CANCEL_ORDER, ChronoUnit.DAYS, DateUtils.currentDate()), saOrder.getPayTime())) {
                return TransactionUtils.getContent(SaOrderMsgConstants.CANCEL_SEVEN_PAY_ORDER);
            }
        }

        // 涉及会员ID列表
        Set<Long> pkMemberList = new HashSet<>();
        pkMemberList.add(saOrder.getPkMember());

        // 封装修改地址业务日志
        List<BusinessLogDTO> dtoList = new ArrayList<>(saOrderList.size());

        // 本批订单修改记录编号
        String businessCode = CommonUtil.createSerialNumber(EOrderPrefix.ORDER_CODE);
        // 订单变动日志
        List<SaOrderChargeLog> saOrderChargeLogList = new ArrayList<>();
        for (SaOrder tmpSaOrder : saOrderList) {

            SaOrderChargeLog saOrderChargeLog = new SaOrderChargeLog();
            saOrderChargeLog.setPkOrder(saOrder.getPkId());
            saOrderChargeLog.setChargeType(EApprovalBusiness.ORDER_RETURN.getValue());
            saOrderChargeLog.setPkCreator(userId);
            saOrderChargeLog.setCreationTime(nowDate);
            saOrderChargeLog.setPkModified(saOrderChargeLog.getPkCreator());
            saOrderChargeLog.setModifiedTime(saOrderChargeLog.getCreationTime());
            saOrderChargeLog.setPkCountry(saOrder.getPkCountry());
            saOrderChargeLog.setApprovalStatus(EAgentApprovalStatus.UNAPPROVED.getValue());
            saOrderChargeLog.setBusinessCode(businessCode);
            // 修改后数据
            saOrderChargeLog.setAfterData(JSONUtil.toJsonStr(OrderReturnDTO.builder()
                    .orderCode(tmpSaOrder.getOrderCode())
                    .returnType(2)
                    .build()));
            saOrderChargeLogList.add(saOrderChargeLog);

            // 封装修改订单业务日志
            dtoList.add(BusinessLogDTO.builder()
                    .businessType(EApprovalBusiness.ORDER_RETURN.getValue())
                    .businessCode(businessCode)
                    .pkMember(tmpSaOrder.getPkMember())
                    .content("订单编号：" + tmpSaOrder.getOrderCode() + "，发起退单申请")
                    .pkCreator(userId)
                    .pkCountry(pkCountry)
                    .freeSignFlag(false)
                    .build());
        }

        if (iSaOrderChargeLogService.saveBatch(saOrderChargeLogList)) {
            // 订单修改记录添加成功，提交签呈

            // 提交签呈处理
            String submitStr = this.submitApproval(EApprovalBusiness.ORDER_RETURN, businessCode, param.getSignType(), param.getRemark(), param.getFileList(),
                    param.getUserIdList(), param.getSendIdList(), pkMemberList, loginUser, null);
            if (null == submitStr) {
                // 推送业务操作日志
                rabbitTemplate.convertAndSend(RabbitMqConstants.BUSINESS_LOG_EXCHANGE, RabbitMqConstants.BUSINESS_LOG_KEY, dtoList);
            }

            return submitStr;
        }
        return TransactionUtils.getContent(CommonMsgConstants.OPERATION_FAILED);
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public String returnOrderApprovalAgree(ApprovalBusinessResultDTO approvalBusinessResultDTO) {
        // 用户ID
        Long userId = approvalBusinessResultDTO.getLoginUser().getUserId();
        // 所属国家
        Integer pkCountry = approvalBusinessResultDTO.getLoginUser().getDataCountry();

        // 查询订单修改记录
        List<SaOrderChargeLog> saOrderChargeLogList = getSaOrderChargeLogs(approvalBusinessResultDTO, EApprovalBusiness.ORDER_RETURN);
        if (CollectionUtil.isEmpty(saOrderChargeLogList)) {
            log.error("订单退单同意处理失败: 订单修改记录不存在!");
            return TransactionUtils.getContent(DocumentMsgConstants.DOCUMENT_NOT_EXISTS);
        }
        // 订单修改记录
        SaOrderChargeLog saOrderChargeLog = saOrderChargeLogList.get(0);
        // 需要处理的订单修改记录
        if (EAgentApprovalStatus.UNAPPROVED.getValue() != saOrderChargeLog.getApprovalStatus()) {
            log.error("订单退单同意处理失败: 签呈已处理!");
            return TransactionUtils.getContent(DocumentMsgConstants.DOCUMENT_HAS_HANDLE);
        }

        // 订单修改后实体
        OrderReturnDTO orderReturnDTO = JSONUtil.toBean(saOrderChargeLog.getAfterData(), OrderReturnDTO.class);

        LambdaQueryWrapper<SaOrder> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SaOrder::getOrderCode, orderReturnDTO.getOrderCode());
        SaOrder saOrder = iSaOrderService.getOne(queryWrapper);

        if (this.updateSaOrderChargeLog(EApprovalBusiness.ORDER_RETURN, approvalBusinessResultDTO.getBusinessCode(), pkCountry, userId, EAgentApprovalStatus.APPROVED, approvalBusinessResultDTO.getApproveRemark())) {
            // 处理订单修改记录成功

            // 订单、订单明细状态变更为已删除
            iSaOrderService.deleteOrderAndItems(Collections.singletonList(saOrder.getPkId()), userId, pkCountry);

            // 根据订单退业绩
            Boolean bool = iMemberSettleBonusApi.chargeBackSaOrder(saOrder);
            if (!bool) {
                log.error("订单退单同意处理失败: 订单退业绩失败");
                throw new BaseException(TransactionUtils.getContent(CommonMsgConstants.APPROVAL_ERROR) + "：" + "订单业务回退失败");
            }
            if (EOrderType.RETAIL_REGISTER.getValue() == saOrder.getOrderType()) {
                // 注册类退单，取消注册会员
                iMemberAccountServiceApi.orderReturnMember(Collections.singletonList(saOrder.getPkMember()), userId);
            }
            return null;
        }
        return TransactionUtils.getContent(DocumentMsgConstants.DOCUMENT_ORDER_ERROR);
    }

    @Override
    public String returnOrderApprovalReject(ApprovalBusinessResultDTO approvalBusinessResultDTO) {
        // 用户ID
        Long userId = approvalBusinessResultDTO.getLoginUser().getUserId();
        // 所属国家
        Integer pkCountry = approvalBusinessResultDTO.getLoginUser().getDataCountry();
        List<SaOrderChargeLog> saOrderChargeLogList = getSaOrderChargeLogs(approvalBusinessResultDTO, EApprovalBusiness.ORDER_RETURN);

        if (CollectionUtil.isEmpty(saOrderChargeLogList)) {
            log.error("订单退单驳回处理失败: 订单修改记录不存在!");
            return TransactionUtils.getContent(DocumentMsgConstants.DOCUMENT_NOT_EXISTS);
        }
        // 需要处理的订单修改记录
        SaOrderChargeLog saOrderChargeLog = saOrderChargeLogList.get(0);
        if (EAgentApprovalStatus.UNAPPROVED.getValue() != saOrderChargeLog.getApprovalStatus()) {
            log.error("订单退单驳回处理失败: 签呈已处理!");
            return TransactionUtils.getContent(DocumentMsgConstants.DOCUMENT_HAS_HANDLE);
        }

        // 查询订单
        SaOrderExt saOrder = iSaOrderService.queryOrderByPkId(saOrderChargeLog.getPkOrder(), null);
        if (null == saOrder) {
            log.error("订单退单驳回处理失败: {} 订单不存在", saOrderChargeLog.getPkOrder());
            return TransactionUtils.getContent(DocumentMsgConstants.DOCUMENT_ORDER_NOT_EXISTS);
        }

        if (this.updateSaOrderChargeLog(EApprovalBusiness.ORDER_RETURN, approvalBusinessResultDTO.getBusinessCode(), pkCountry, userId, EAgentApprovalStatus.REFUSE, approvalBusinessResultDTO.getApproveRemark())) {
            // 更新订单修改记录成功
            return null;
        }
        log.error("订单退单驳回处理失败：更新数据失败");
        throw new BaseException(TransactionUtils.getContent(DocumentMsgConstants.DOCUMENT_ORDER_ERROR));
    }

    @Override
    public ValidateCancelOrderVO validateCancelOrder(OrderCancelParam orderCancelParam, String... businessCode) {
        ValidateCancelOrderVO validateCancelOrderVO = ValidateCancelOrderVO.builder().build();
        if (null == orderCancelParam.getCancelType() || null == orderCancelParam.getOrderCode()) {
            validateCancelOrderVO.setMsg(MemberMsgConstants.REQUIRED_NOT_EMPTY);
            return validateCancelOrderVO;
        }
        int approveBusiness = EApprovalBusiness.ORDER_CANCEL.getValue();
        SaOrderExt saOrderExt;
        if (ECancelOrderType.OTHER_CANCEL_PART_ORDER.getValue() == orderCancelParam.getCancelType()) {
            approveBusiness = EApprovalBusiness.ORDER_CANCEL_PRODUCT.getValue();
            SaOrder orderQuery = SaOrder.builder().orderStatus(EOrderStatus.PAY.getValue()).orderCode(orderCancelParam.getOrderCode()).build();
            orderQuery.setPkCountry(orderCancelParam.getPkCountry());
//            List<Long> itemIdList = new ArrayList<>();
//            if (orderCancelParam.getOrderCancelDetailParamList() != null && orderCancelParam.getOrderCancelDetailParamList().size() > 0) {
//                orderCancelParam.getOrderCancelDetailParamList().forEach(orderCancelDetailParam ->
//                        itemIdList.add(orderCancelDetailParam.getPkId()));
//            }
            saOrderExt = iSaOrderService.querySaleOrderExtByOrderCode(orderQuery, new ArrayList<>());
            CuMember cuMember = iSaOrderService.getCuMemberByKey(saOrderExt.getPkMember());
            saOrderExt.setMemberCode(cuMember.getMemberCode());
            saOrderExt.setMemberName(cuMember.getMemberName());
        } else {
            saOrderExt = iSaOrderService.queryOrderByCode(orderCancelParam.getOrderCode(), orderCancelParam.getPkCountry());
        }
        if (saOrderExt == null || EOrderStatus.WAIT_PAY.getValue() == saOrderExt.getOrderStatus()) {
            validateCancelOrderVO.setMsg(TransactionUtils.getContent(SaOrderMsgConstants.ORDER_EMPTY));
            return validateCancelOrderVO;
        }
        if (orderCancelParam.getCancelType().equals(ECancelOrderType.SINGLE_CANCEL_ORDER.getValue()) ||
                orderCancelParam.getCancelType().equals(ECancelOrderType.MERGE_CANCEL_ORDER.getValue()) ||
                orderCancelParam.getCancelType().equals(ECancelOrderType.OTHER_CANCEL_ORDER.getValue()) ||
                orderCancelParam.getCancelType().equals(ECancelOrderType.OTHER_CANCEL_PART_ORDER.getValue())) {
            // 验证订单时间，只能撤销7天以内的支付订单
            // 周结只能撤销当前期间的订单，不能撤销上个期间的订单
            String settleCycle = systemConfigServiceApi.getBonusSystemConfig(orderCancelParam.getPkCountry(), ESystemConfig.EXPAND_CAP_METHOD.getKey()).getData();
            if (Objects.equals(Integer.toString(EExpandCapMethod.WEEK_SETTLE.getValue()), settleCycle)) {
                if (DateUtils.compareDateAfter(DateUtils.parseStringToDate(DateUtils.getRecentlyTuesday(DateUtils.currentDate())), saOrderExt.getPayTime())) {
                    validateCancelOrderVO.setMsg(TransactionUtils.getContent(SaOrderMsgConstants.WEEK_CANCEL_SEVEN_PAY_ORDER));
                    return validateCancelOrderVO;
                }
            } else {
                Date sevenDate = DateUtils.beforeDate(MagicNumberConstants.CANCEL_ORDER, ChronoUnit.DAYS, DateUtils.currentDate());
                if (DateUtils.compareDateAfter(sevenDate, saOrderExt.getPayTime())) {
                    validateCancelOrderVO.setMsg(TransactionUtils.getContent(SaOrderMsgConstants.CANCEL_SEVEN_PAY_ORDER));
                    return validateCancelOrderVO;
                }
            }
        }
        // 验证订单国家跟会员国家是否一致，是否转换过结算国
        CuMember cuMember = memberServiceApi.getMember(saOrderExt.getPkMember()).getData();
        if (cuMember == null) {
            validateCancelOrderVO.setMsg(TransactionUtils.getContent(MemberMsgConstants.MEMBER_DOES_NOT_EXITS));
            return validateCancelOrderVO;
        }
        if (!cuMember.getPkSettleCountry().equals(saOrderExt.getPkCountry())) {
            validateCancelOrderVO.setMsg(TransactionUtils.getContent(MemberMsgConstants.MEMBER_CHANGE_SETTLE_COUNTRY));
            return validateCancelOrderVO;
        }
        // 验证创建人是否还存在，不存在不能撤单
        CuMember createMember = memberServiceApi.getMember(saOrderExt.getPkCreator()).getData();
        if (createMember == null) {
            validateCancelOrderVO.setMsg(TransactionUtils.getContent(MemberMsgConstants.CREATE_MEMBER_NOT_EXITS));
            return validateCancelOrderVO;
        }
        // 校验订单是否存在进行中的签呈
        if (iSaOrderChargeLogService.checkOrderApprovalExist(
                Arrays.asList(EApprovalBusiness.ORDER_CHANGE_ADDRESS.getValue(), EApprovalBusiness.ORDER_CHANGE_PRODUCT.getValue(),
                        EApprovalBusiness.ORDER_RETURN.getValue(), approveBusiness,
                        EApprovalBusiness.ORDER_CANCEL_PRODUCT.getValue()
                ),
                Collections.singletonList(orderCancelParam.getOrderCode()), orderCancelParam.getPkCountry(), businessCode) > 0) {
            validateCancelOrderVO.setMsg(TransactionUtils.getContent(SaOrderMsgConstants.ORDER_EXIST_OTHER_APPROVE));
            return validateCancelOrderVO;
        }
        if (orderCancelParam.getCancelType().equals(ECancelOrderType.SINGLE_CANCEL_ORDER.getValue()) ||
                orderCancelParam.getCancelType().equals(ECancelOrderType.MERGE_CANCEL_ORDER.getValue()) ||
                orderCancelParam.getCancelType().equals(ECancelOrderType.SINGLE_RETREAT_ORDER.getValue()) ||
                orderCancelParam.getCancelType().equals(ECancelOrderType.MERGE_RETREAT_ORDER.getValue())) {
            // 单点撤单 合并撤单
            if (EOrderType.RETAIL_REGISTER.getValue() != saOrderExt.getOrderType()) {
                validateCancelOrderVO.setMsg(TransactionUtils.getContent(SaOrderMsgConstants.REGISTER_ORDER_CANCEL));
                return validateCancelOrderVO;
            }
            // 验证账号是否有钱
            CuMemberAccount cuMemberAccount = CuMemberAccount.builder().pkMember(saOrderExt.getPkMember()).build();
            cuMemberAccount.setPkCountry(cuMember.getPkSettleCountry());
            List<CuMemberAccountExt> cuMemberAccountExtList = iMemberAccountServiceApi.queryMemberAccountByCondition(cuMemberAccount).getData();
            if (cuMemberAccountExtList.size() == 0) {
                validateCancelOrderVO.setMsg(TransactionUtils.getContent(MemberMsgConstants.NOT_EXIST_MEMBER_ACCOUNT));
                return validateCancelOrderVO;
            }
            CuMemberAccountExt cuMemberAccountExt = cuMemberAccountExtList.get(0);
            if (ComputeUtil.compareValue(ComputeUtil.computeAddNum(cuMemberAccountExt.getAccount1(), cuMemberAccountExt.getAccount2(), cuMemberAccountExt.getAccount4()))) {
                validateCancelOrderVO.setMsg(TransactionUtils.getContent(MemberMsgConstants.MEMBER_ACCOUNT_NOT_ZERO));
                return validateCancelOrderVO;
            }
            // 验证是否存在签呈
            // 校验各会员是否有进行中的签呈
            if (businessCode == null || businessCode.length == 0) {
                List<Long> pkMemberList = new ArrayList<>();
                pkMemberList.add(cuMember.getPkId());
                Map<Long, ApprovalMemberNumDTO> resultMap = iApprovalServiceApi.queryProcessingApproval(pkMemberList, cuMember.getPkSettleCountry()).getData();
                if (resultMap.size() > 0) {
                    validateCancelOrderVO.setMsg(TransactionUtils.getContent(MemberMsgConstants.MEMBER_EXIST_NO_FISH_DOCUMENT));
                    return validateCancelOrderVO;
                }
            }
            // 验证是否存在其他订单
            Integer count = iSaOrderService.querySaleOrderByPkMember(cuMember.getPkSettleCountry(), cuMember.getPkId());
            if (count > 1) {
                validateCancelOrderVO.setMsg(TransactionUtils.getContent(SaOrderMsgConstants.MEMBER_OTHER_ORDER));
                return validateCancelOrderVO;
            }
            // 合并撤单、退单时需要验证伞下会员
            if (orderCancelParam.getCancelType().equals(ECancelOrderType.MERGE_CANCEL_ORDER.getValue()) ||
                    orderCancelParam.getCancelType().equals(ECancelOrderType.MERGE_RETREAT_ORDER.getValue())) {
                // 查询用户伞下所有会员
                List<CuMemberExt> cuMemberList = memberServiceApi.queryPlaceSponsorUnderUmbrella(saOrderExt.getPkMember()).getData();
                cuMemberList.add(BeanUtil.copyProperties(cuMember, CuMemberExt.class));
                List<OrderCancelRegisterMemberVO> memberList = new ArrayList<>(cuMemberList.size());
                // 验证，伞下会员是否存在报单中心
                Set<Long> centerIdList = new HashSet<>();
                for (CuMemberExt cuMemberExt : cuMemberList) {
                    centerIdList.add(cuMemberExt.getPkCenterCode());
                    memberList.add(OrderCancelRegisterMemberVO.builder()
                            .pkMember(cuMemberExt.getPkId())
                            .memberCode(cuMemberExt.getMemberCode())
                            .memberName(cuMemberExt.getMemberName())
                            .build());
                }
                if (memberList.stream().anyMatch(orderCancelRegisterMemberVO ->
                        centerIdList.contains(orderCancelRegisterMemberVO.getPkMember()))) {
                    validateCancelOrderVO.setMsg(TransactionUtils.getContent(SaOrderMsgConstants.EXIST_CENTER_ORDER));
                    return validateCancelOrderVO;
                }
                validateCancelOrderVO.setMemberList(memberList);
                // 验证伞下所有会员的账号是否有钱
                List<Long> underMemberList = cuMemberList.stream().map(CuMemberExt::getPkId).collect(Collectors.toList());
                Map<Long, CuMemberAccount> revokeMemberBySaOrder = getRevokeMemberBySaOrder(underMemberList);
                for (Long pkMember : revokeMemberBySaOrder.keySet()) {
                    CuMemberAccount memberAccount = revokeMemberBySaOrder.get(pkMember);
                    if (ComputeUtil.compareValue(ComputeUtil.computeAddNum(memberAccount.getAccount1(), memberAccount.getAccount2(), memberAccount.getAccount4()))) {
                        validateCancelOrderVO.setMsg(TransactionUtils.getContent(MemberMsgConstants.UNDER_UMBRELLA_ACCOUNT_NOT_ZERO));
                        return validateCancelOrderVO;
                    }
                }
                revokeMemberBySaOrder.put(cuMemberAccountExt.getPkMember(), cuMemberAccountExt);
                List<Long> pkMember = memberList.stream().map(OrderCancelRegisterMemberVO::getPkMember).collect(Collectors.toList());
                // 查询伞下会员的注册订单 删除伞下注册会员的订单
                List<SaOrderExt> saOrderExtList = iSaOrderService.queryOrderMemberInfo(null, pkMember, null);
                Map<Long, SaOrderExt> saOrderMap = new HashMap<>();
                for (SaOrderExt orderExt : saOrderExtList) {
                    if (EOrderType.RETAIL_REGISTER.getValue() == orderExt.getOrderType()) {
                        saOrderMap.put(orderExt.getPkMember(), orderExt);
                    } else if (EOrderStatus.WAIT_PAY.getValue() != orderExt.getOrderStatus()) {
                        // 2024.11.22 添加需求，续约订单排除处理
                        validateCancelOrderVO.setMsg(TransactionUtils.getContent(MemberMsgConstants.UNDER_UMBRELLA_MEMBER_EXIST_ORDER));
                        return validateCancelOrderVO;
                    }
                }
                for (OrderCancelRegisterMemberVO orderCancelRegisterMemberVO : memberList) {
                    if (saOrderMap.containsKey(orderCancelRegisterMemberVO.getPkMember())) {
                        orderCancelRegisterMemberVO.setOrderCode(saOrderMap.get(orderCancelRegisterMemberVO.getPkMember()).getOrderCode());
                    }
                }
                saOrderMap.put(saOrderExt.getPkMember(), saOrderExt);
                validateCancelOrderVO.setSaOrderMap(saOrderMap);
            }
        } else if (orderCancelParam.getCancelType().equals(ECancelOrderType.OTHER_CANCEL_ORDER.getValue())) {
            // 其他撤单
            if (EOrderType.RETAIL_UPGRADE.getValue() == saOrderExt.getOrderType()) {
                // 升级订单需要验证是否从最后一单升级订单撤销
                List<SaOrder> saOrderList = iSaOrderService.querySaleOrderByPkMember(cuMember.getPkSettleCountry(), cuMember.getPkId(),
                        Arrays.asList(EOrderType.RETAIL_REGISTER.getValue(), EOrderType.RETAIL_UPGRADE.getValue()),
                        null);
                if (!saOrderList.get(0).getOrderCode().equals(saOrderExt.getOrderCode())) {
                    validateCancelOrderVO.setMsg(TransactionUtils.getContent(SaOrderMsgConstants.MEMBER_CANCEL_UPGRADE_ORDER, saOrderList.get(0).getOrderCode()));
                    return validateCancelOrderVO;
                }
                if (saOrderList.size() > 1) {
                    // 存在空单，空单从cu_member_register获取
                    validateCancelOrderVO.setUpdSaOrder(saOrderList.get(1));
                }
            } else if (EOrderType.RETAIL_REPURCHASE.getValue() == saOrderExt.getOrderType()) {
                // 2025.03.05 复购可以升级，需要必须从最后一单开始撤单
                List<SaOrder> saOrderList = iSaOrderService.querySaleOrderByPkMember(cuMember.getPkSettleCountry(), cuMember.getPkId(),
                        Arrays.asList(EOrderType.RETAIL_REGISTER.getValue(), EOrderType.RETAIL_UPGRADE.getValue(), EOrderType.RETAIL_REPURCHASE.getValue()),
                        null);
                if (!saOrderList.get(0).getOrderCode().equals(saOrderExt.getOrderCode())) {
                    validateCancelOrderVO.setMsg("撤销复购订单，只能从最新的订单开始撤销，最新的订单编号：" + saOrderList.get(0).getOrderCode());
                    return validateCancelOrderVO;
                }
            }
        }
        validateCancelOrderVO.setSaOrderExt(saOrderExt);
        return validateCancelOrderVO;
    }

    /**
     * 根据订单获取
     *
     * @param pkMemberList 伞下会员
     */
    private Map<Long, CuMemberAccount> getRevokeMemberBySaOrder(List<Long> pkMemberList) {
        List<CuMemberAccount> cuMemberAccountList = iMemberAccountServiceApi.queryCuMemberAccountByPkMembers(pkMemberList).getData();
        Map<Long, CuMemberAccount> cuMemberAccountMap = new HashMap<>(ComputeUtil.mapInitCapacity(cuMemberAccountList.size()));
        cuMemberAccountList.forEach(cuMemberAccount ->
                cuMemberAccountMap.put(cuMemberAccount.getPkMember(), cuMemberAccount));
        return cuMemberAccountMap;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void revokeSaOrderByOrderCode(Long pkApprove, OrderCancelParam orderCancelParam, ValidateCancelOrderVO validateCancelOrderVO) {
        // 本批订单修改记录编号（因为实际没走签呈，此处使用单独编号记录，后续进行区分）
        String businessCode = CommonUtil.createSerialNumber(EOrderPrefix.DEFAULT);
        // 修改类型
        EApprovalBusiness approveBusiness = EApprovalBusiness.ORDER_CANCEL;
        if (ECancelOrderType.OTHER_CANCEL_PART_ORDER.getValue() == orderCancelParam.getCancelType()) {
            approveBusiness = EApprovalBusiness.ORDER_CANCEL_PRODUCT;
        }

        // 封装修改地址业务日志
        List<BusinessLogDTO> dtoList = new ArrayList<>();

        // 2023.11.22 不走签呈也需要添加中间操作表，用于区分部分撤单和调换货物
        // 撤单日志列表
        List<SaOrderChargeLog> saOrderChargeLogList = new ArrayList<>();
        Map<Long, SaOrderExt> saOrderMap = validateCancelOrderVO.getSaOrderMap();
        if (null != saOrderMap) {
            for (Long key : saOrderMap.keySet()) {
                SaOrderExt saOrderExt = saOrderMap.get(key);
                SaOrderChargeLog saOrderChargeLog = new SaOrderChargeLog();
                saOrderChargeLog.setPkOrder(saOrderExt.getPkId());
                saOrderChargeLog.setChargeType(approveBusiness.getValue());
                saOrderChargeLog.setPkCreator(pkApprove);
                saOrderChargeLog.setCreationTime(new Date());
                saOrderChargeLog.setPkModified(saOrderChargeLog.getPkCreator());
                saOrderChargeLog.setModifiedTime(saOrderChargeLog.getCreationTime());
                saOrderChargeLog.setPkCountry(saOrderExt.getPkCountry());
                saOrderChargeLog.setApprovalStatus(EAgentApprovalStatus.APPROVED.getValue());
                saOrderChargeLog.setBusinessCode(businessCode);
                saOrderChargeLog.setAfterData(JSONUtil.toJsonStr(orderCancelParam));
                saOrderChargeLogList.add(saOrderChargeLog);

                dtoList.add(BusinessLogDTO.builder()
                        .businessType(approveBusiness.getValue())
                        .businessCode(businessCode)
                        .pkMember(saOrderExt.getPkMember())
                        .content("订单编号：" + saOrderExt.getOrderCode() + "，申请撤单")
                        .pkCreator(pkApprove)
                        .pkCountry(saOrderExt.getPkCountry())
                        .freeSignFlag(true)
                        .build());
            }
        } else {
            SaOrderExt saOrderExt = validateCancelOrderVO.getSaOrderExt();
            SaOrderChargeLog saOrderChargeLog = new SaOrderChargeLog();
            saOrderChargeLog.setPkOrder(saOrderExt.getPkId());
            saOrderChargeLog.setChargeType(approveBusiness.getValue());
            saOrderChargeLog.setPkCreator(pkApprove);
            saOrderChargeLog.setCreationTime(new Date());
            saOrderChargeLog.setPkModified(saOrderChargeLog.getPkCreator());
            saOrderChargeLog.setModifiedTime(saOrderChargeLog.getCreationTime());
            saOrderChargeLog.setPkCountry(saOrderExt.getPkCountry());
            saOrderChargeLog.setApprovalStatus(EAgentApprovalStatus.APPROVED.getValue());
            saOrderChargeLog.setBusinessCode(businessCode);
            saOrderChargeLog.setAfterData(JSONUtil.toJsonStr(orderCancelParam));
            saOrderChargeLogList.add(saOrderChargeLog);

            dtoList.add(BusinessLogDTO.builder()
                    .businessType(approveBusiness.getValue())
                    .businessCode(businessCode)
                    .pkMember(saOrderExt.getPkMember())
                    .content("订单编号：" + saOrderExt.getOrderCode() + "，申请撤单")
                    .pkCreator(pkApprove)
                    .pkCountry(saOrderExt.getPkCountry())
                    .freeSignFlag(true)
                    .build());
        }

        if (iSaOrderChargeLogService.saveBatch(saOrderChargeLogList)) {
            iSaOrderService.revokeSaOrderByOrderCode(pkApprove, orderCancelParam, validateCancelOrderVO);

            // 推送业务操作日志
            rabbitTemplate.convertAndSend(RabbitMqConstants.BUSINESS_LOG_EXCHANGE, RabbitMqConstants.BUSINESS_LOG_KEY, dtoList);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean cancelOrder(OrderCancelParam orderCancelParam, ValidateCancelOrderVO validateCancelOrderVO, LoginUser loginUser) {
        // 当前时间
        Date nowDate = DateUtils.currentDateTime();
        // 本批订单修改记录编号
        String businessCode = CommonUtil.createSerialNumber(EOrderPrefix.REVOKE_ORDER_CODE);

        // 封装修改地址业务日志
        List<BusinessLogDTO> dtoList = new ArrayList<>();

        // 封装撤单后的数据
        // 保存撤单记录，存在整单撤销
        SaOrderExt saOrderExt = validateCancelOrderVO.getSaOrderExt();
        CuMember cuMember = memberServiceApi.getMember(saOrderExt.getPkMember()).getData();
        orderCancelParam.setMemberCode(cuMember.getMemberCode());
        orderCancelParam.setMemberName(cuMember.getMemberName());
        EApprovalBusiness approveBusiness = EApprovalBusiness.ORDER_CANCEL;
        if (ECancelOrderType.OTHER_CANCEL_PART_ORDER.getValue() == orderCancelParam.getCancelType()) {
            approveBusiness = EApprovalBusiness.ORDER_CANCEL_PRODUCT;
//            List<OrderCancelDetailParam> orderCancelDetailParamList = new ArrayList<>();
//            orderCancelParam.getOrderCancelDetailParamList().forEach(orderCancelDetailParam ->
//                    orderCancelDetailParamList.add(BeanUtil.copyProperties(orderCancelDetailParam, OrderCancelDetailParam.class)));
//            orderCancelParam.setOrderCancelDetailParamList(orderCancelDetailParamList);
        }
        // 本次业务修改费用
        Map<Long, OrderQueryChargeDTO> queryChargeMap = null;
        if (orderCancelParam.getCancelRoad() == null || orderCancelParam.getCancelRoad() != 2) {
            queryChargeMap = this.queryChargeLog(Collections.singletonList(saOrderExt), approveBusiness, orderCancelParam.getPkCountry());
        }
        // 扣款用户数据
        // 判断封装扣费数据
        BusinessCommissionDTO businessCommissionDTO = null;
        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)) {
                businessCommissionDTO = BusinessCommissionDTO.builder()
                        .pkCountry(orderCancelParam.getPkCountry())
                        .pkCreator(loginUser.getUserId())
                        .pkAccount(currency)
                        .tradeType(approveBusiness.getValue())
                        .tradeCode(businessCode)
                        .memberAmountDTOList(memberAmountDTOList)
                        .build();
            }
        }
        List<SaOrderChargeLog> saOrderChargeLogList = new ArrayList<>();
        SaOrderChargeLog saOrderChargeLog = packageSaOrderChargeLog(nowDate, loginUser.getUserId(), approveBusiness.getValue(), businessCode, saOrderExt, EAgentApprovalStatus.UNAPPROVED.getValue());
        saOrderChargeLog.setAfterData(JSONUtil.toJsonStr(orderCancelParam));
        saOrderChargeLogList.add(saOrderChargeLog);

        // 业务操作日志内容
        StringBuilder content = new StringBuilder("订单编号：" + saOrderExt.getOrderCode()).append("，");

        if (ECancelOrderType.MERGE_CANCEL_ORDER.getValue() == orderCancelParam.getCancelType() ||
                ECancelOrderType.MERGE_RETREAT_ORDER.getValue() == orderCancelParam.getCancelType()) {
            content.append("申请合并撤销订单");

            Map<Long, SaOrderExt> saOrderMap = validateCancelOrderVO.getSaOrderMap();
            for (OrderCancelRegisterMemberVO orderCancelRegisterMemberVO : validateCancelOrderVO.getMemberList()) {
                if (saOrderMap.containsKey(orderCancelRegisterMemberVO.getPkMember())) {
                    SaOrderExt orderExt = saOrderMap.get(orderCancelRegisterMemberVO.getPkMember());
                    if (saOrderExt.getOrderCode().equals(orderExt.getOrderCode())) {
                        continue;
                    }
                    SaOrderChargeLog saOrderChargeLog1 = packageSaOrderChargeLog(nowDate, loginUser.getUserId(),
                            approveBusiness.getValue(), businessCode, orderExt, EAgentApprovalStatus.UNAPPROVED.getValue());
                    orderCancelParam.setOrderCode(orderExt.getOrderCode());
                    orderCancelParam.setMemberCode(orderCancelRegisterMemberVO.getMemberCode());
                    orderCancelParam.setMemberName(orderCancelRegisterMemberVO.getMemberName());
                    saOrderChargeLog1.setAfterData(JSONUtil.toJsonStr(orderCancelParam));
                    saOrderChargeLogList.add(saOrderChargeLog1);

                    String tmpContent = content + "，关联订单编号：" + orderExt.getOrderCode();
                    // 封装业务操作日志内容
                    dtoList.add(BusinessLogDTO.builder()
                            .businessType(approveBusiness.getValue())
                            .businessCode(businessCode)
                            .pkMember(saOrderExt.getPkMember())
                            .content(tmpContent)
                            .pkCreator(loginUser.getUserId())
                            .pkCountry(loginUser.getDataCountry())
                            .freeSignFlag(false)
                            .build());
                }
            }
        } else {
            if (EApprovalBusiness.ORDER_CANCEL_PRODUCT.getValue() == approveBusiness.getValue()) {
                content.append("申请撤销产品：");
                for (OrderCancelDetailParam orderCancelDetailParam : orderCancelParam.getOrderCancelDetailParamList()) {
                    content.append(orderCancelDetailParam.getProductName()).append("，");
                }

            } else {
                content.append("申请撤销订单");
            }
        }

        // 封装业务操作日志内容
        dtoList.add(BusinessLogDTO.builder()
                .businessType(approveBusiness.getValue())
                .businessCode(businessCode)
                .pkMember(saOrderExt.getPkMember())
                .content(content.toString())
                .pkCreator(loginUser.getUserId())
                .pkCountry(loginUser.getDataCountry())
                .freeSignFlag(false)
                .build());

        if (iSaOrderChargeLogService.saveBatch(saOrderChargeLogList)) {
            // 订单修改记录添加成功，发起审批
            // 提交签呈处理
            Set<Long> memberSet = new HashSet<>();
            if (ECancelOrderType.MERGE_CANCEL_ORDER.getValue() == orderCancelParam.getCancelType()) {
                List<Long> memberList = validateCancelOrderVO.getMemberList().stream()
                        .map(OrderCancelRegisterMemberVO::getPkMember).collect(Collectors.toList());
                memberSet.addAll(memberList);
            } else {
                memberSet.add(saOrderExt.getPkMember());
            }
            R<String> resultR = iApprovalServiceApi.submitOrder(
                    ApprovalSubmitDTO.builder()
                            .eApprovalBusiness(approveBusiness)
                            .businessCode(businessCode)
                            .signType(ESignType.getEnumByValue(orderCancelParam.getSignType()))
                            .userIdList(orderCancelParam.getUserIdList())
                            .sendIdList(orderCancelParam.getSendIdList())
                            .remark(orderCancelParam.getRemark())
                            .fileList(orderCancelParam.getFileList())
                            .pkMemberList(memberSet)
                            .signSource(ESignSource.MANAGE)
                            .build(),
                    loginUser,
                    businessCommissionDTO
            );
            if (resultR.isSuccess()) {
                // 推送业务操作日志
                rabbitTemplate.convertAndSend(RabbitMqConstants.BUSINESS_LOG_EXCHANGE, RabbitMqConstants.BUSINESS_LOG_KEY, dtoList);

                return Boolean.TRUE;
            }
            throw new BaseException(TransactionUtils.getContent(CommonMsgConstants.OPERATION_FAILED) + "：" + resultR.getMsg());
        }
        return Boolean.FALSE;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String cancelOrderApprovalAgree(ApprovalBusinessResultDTO approvalBusinessResultDTO, Integer approvalBusiness) {
        // 验证是否可以进行撤单
        // 查询订单修改记录
        List<SaOrderChargeLog> saOrderChargeLogList = getSaOrderChargeLogs(approvalBusinessResultDTO, approvalBusiness);
        if (CollectionUtils.isEmpty(saOrderChargeLogList)) {
            log.info("订单撤销同意处理失败：签呈不存在");
            return TransactionUtils.getContent(DocumentMsgConstants.DOCUMENT_NOT_EXISTS);
        }
        SaOrderChargeLog saOrderChargeLog = saOrderChargeLogList.get(0);
        if (EAgentApprovalStatus.UNAPPROVED.getValue() != saOrderChargeLog.getApprovalStatus()) {
            log.info("订单撤销同意处理失败:签呈状态不为待审核");
            return TransactionUtils.getContent(DocumentMsgConstants.DOCUMENT_HAS_HANDLE);
        }
        OrderCancelParam orderCancelParam = JSONObject.parseObject(saOrderChargeLog.getAfterData(), OrderCancelParam.class);
        // 验证订单是否可以撤单
        ValidateCancelOrderVO validateCancelOrderVO = validateCancelOrder(orderCancelParam, approvalBusinessResultDTO.getBusinessCode());
        if (validateCancelOrderVO.getSaOrderExt() == null) {
            return validateCancelOrderVO.getMsg();
        }
        // 用户ID
        Long userId = approvalBusinessResultDTO.getLoginUser().getUserId();
        // 所属国家
        Integer pkCountry = approvalBusinessResultDTO.getLoginUser().getDataCountry();
        EApprovalBusiness approvalBus = EApprovalBusiness.ORDER_CANCEL;
        if (EApprovalBusiness.ORDER_CANCEL_PRODUCT.getValue() == approvalBusiness) {
            approvalBus = EApprovalBusiness.ORDER_CANCEL_PRODUCT;
        }
        if (this.updateSaOrderChargeLog(approvalBus, approvalBusinessResultDTO.getBusinessCode(), pkCountry, userId, EAgentApprovalStatus.APPROVED, approvalBusinessResultDTO.getApproveRemark())) {
            iSaOrderService.revokeSaOrderByOrderCode(approvalBusinessResultDTO.getSysUser().getUserId(), orderCancelParam, validateCancelOrderVO);
        }
        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String cancelOrderApprovalReject(ApprovalBusinessResultDTO approvalBusinessResultDTO, Integer approvalBusiness) {
        // 用户ID
        Long userId = approvalBusinessResultDTO.getLoginUser().getUserId();
        // 所属国家
        Integer pkCountry = approvalBusinessResultDTO.getLoginUser().getDataCountry();
        List<SaOrderChargeLog> saOrderChargeLogList = getSaOrderChargeLogs(approvalBusinessResultDTO, approvalBusiness);

        if (CollectionUtil.isEmpty(saOrderChargeLogList)) {
            log.error("订单撤单驳回处理失败: 签呈不存在!");
            return TransactionUtils.getContent(DocumentMsgConstants.DOCUMENT_NOT_EXISTS);
        }
        // 需要处理的订单修改记录
        SaOrderChargeLog saOrderChargeLog = saOrderChargeLogList.get(0);
        if (EAgentApprovalStatus.UNAPPROVED.getValue() != saOrderChargeLog.getApprovalStatus()) {
            log.error("订单撤单驳回处理失败: 签呈已处理!");
            return TransactionUtils.getContent(DocumentMsgConstants.DOCUMENT_HAS_HANDLE);
        }

        // 查询订单
        SaOrderExt saOrder = iSaOrderService.queryOrderByPkId(saOrderChargeLog.getPkOrder(), null);
        if (null == saOrder) {
            log.error("订单撤单驳回处理失败: {} 订单不存在", saOrderChargeLog.getPkOrder());
            return TransactionUtils.getContent(DocumentMsgConstants.DOCUMENT_ORDER_NOT_EXISTS);
        }
        EApprovalBusiness eApprovalBusiness = EApprovalBusiness.ORDER_CANCEL;
        if (EApprovalBusiness.ORDER_CANCEL_PRODUCT.getValue() == approvalBusiness) {
            eApprovalBusiness = EApprovalBusiness.ORDER_CANCEL_PRODUCT;
        }
        if (this.updateSaOrderChargeLog(eApprovalBusiness, approvalBusinessResultDTO.getBusinessCode(), pkCountry, userId, EAgentApprovalStatus.REFUSE, approvalBusinessResultDTO.getApproveRemark())) {
            // 更新订单修改记录成功
            // 驳回业务处理（扣款回退）
            R resultR = iBusinessCommission.businessCommissionReject(BusinessCommissionDTO.builder()
                    .pkCountry(pkCountry)
                    .pkCreator(userId)
                    .tradeType(eApprovalBusiness.getValue())
                    .tradeCode(approvalBusinessResultDTO.getBusinessCode())
                    .build());
            if (!resultR.isSuccess()) {
                log.error("订单退单驳回处理扣款失败: {}", resultR.getMsg());
                // 签呈处理失败：业务扣款处理失败
                throw new BaseException(TransactionUtils.getContent(DocumentMsgConstants.DOCUMENT_ORDER_CHARGE_ERROR));
            }
            return null;
        }
        log.error("订单退单驳回处理失败：更新数据失败");
        // 签呈处理失败：更新数据失败
        throw new BaseException(TransactionUtils.getContent(DocumentMsgConstants.DOCUMENT_ORDER_ERROR));
    }

    /**
     * 查询订单修改记录
     *
     * @param resultDTO         业务审批操作DTO
     * @param eApprovalBusiness 修改类型枚举
     * @return
     */
    @Override
    public List<SaOrderChargeLog> getSaOrderChargeLogs(ApprovalBusinessResultDTO resultDTO, EApprovalBusiness eApprovalBusiness) {
        return this.getSaOrderChargeLogs(resultDTO, eApprovalBusiness.getValue());
    }

    /**
     * 查询订单修改记录
     *
     * @param resultDTO  业务审批操作DTO
     * @param chargeType 修改类型
     * @return
     */
    @Override
    public List<SaOrderChargeLog> getSaOrderChargeLogs(ApprovalBusinessResultDTO resultDTO, Integer chargeType) {
        // 查询订单修改记录
        LambdaQueryWrapper<SaOrderChargeLog> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SaOrderChargeLog::getChargeType, chargeType);
        queryWrapper.eq(SaOrderChargeLog::getBusinessCode, resultDTO.getBusinessCode());
        queryWrapper.eq(SaOrderChargeLog::getPkCountry, resultDTO.getLoginUser().getDataCountry());
        queryWrapper.orderByAsc(SaOrderChargeLog::getPkId);
        return iSaOrderChargeLogService.list(queryWrapper);
    }

    /**
     * 更新订单修改记录
     *
     * @param chargeType     业务类型
     * @param businessCode   业务单号
     * @param pkCountry      所属国家
     * @param userId         用户ID
     * @param approvalStatus 审核状态
     * @return
     */
    @Override
    public boolean updateSaOrderChargeLog(EApprovalBusiness chargeType, String businessCode,
                                          Integer pkCountry, Long userId,
                                          EAgentApprovalStatus approvalStatus, String remark) {
        // 处理订单修改记录
        LambdaUpdateWrapper<SaOrderChargeLog> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(SaOrderChargeLog::getChargeType, chargeType.getValue());
        updateWrapper.eq(SaOrderChargeLog::getBusinessCode, businessCode);
        updateWrapper.eq(SaOrderChargeLog::getPkCountry, pkCountry);
        updateWrapper.eq(SaOrderChargeLog::getApprovalStatus, EAgentApprovalStatus.UNAPPROVED.getValue());
        updateWrapper.set(SaOrderChargeLog::getApprovalStatus, approvalStatus.getValue());
        updateWrapper.set(SaOrderChargeLog::getPkModified, userId);
        updateWrapper.set(SaOrderChargeLog::getModifiedTime, new Date());
        updateWrapper.set(SaOrderChargeLog::getRemark, remark);
        return iSaOrderChargeLogService.update(updateWrapper);
    }

    /**
     * 提交审批
     *
     * @param eApprovalBusiness 业务类型
     * @param businessCode      订单修改记录编号
     * @param signType          签呈类型
     * @param remark            remark
     * @param fileList          签呈附件
     * @param userIdList        审批流程用户ID列表
     * @param sendIdList        审批抄送ID列表
     * @param pkMemberList      审批涉及会员ID
     * @param loginUser         当前登录用户
     * @param obj               特殊业务实体
     * @return
     */
    private String submitApproval(EApprovalBusiness eApprovalBusiness, String businessCode, Integer signType, String remark,
                                  List<String> fileList, List<Long> userIdList, List<Long> sendIdList,
                                  Set<Long> pkMemberList, LoginUser loginUser, Object obj) {
        // 提交签呈处理
        R<String> resultR = iApprovalServiceApi.submitOrder(
                ApprovalSubmitDTO.builder()
                        .eApprovalBusiness(eApprovalBusiness)
                        .businessCode(businessCode)
                        .signType(ESignType.getEnumByValue(signType))
                        .userIdList(userIdList)
                        .sendIdList(sendIdList)
                        .remark(remark)
                        .fileList(fileList)
                        .pkMemberList(pkMemberList)
                        .build(),
                loginUser,
                obj
        );
        if (resultR.isSuccess()) {
            return null;
        }
        throw new BaseException(TransactionUtils.getContent(CommonMsgConstants.OPERATION_FAILED) + "：" + resultR.getMsg());
    }


    /**
     * 修改地址扣款处理
     *
     * @param orderList    订单列表
     * @param businessCode 业务单号
     * @param pkCountry    所属国家
     * @param userId       当前用户
     * @return
     */
    private BusinessCommissionDTO handleChangeAddressCost(List<SaOrderExt> orderList, String businessCode, Integer pkCountry, Long userId) {
        // 订单业务扣费map
        Map<Long, OrderQueryChargeDTO> queryChargeMap = this.queryChargeLog(orderList, EApprovalBusiness.ORDER_CHANGE_ADDRESS, pkCountry);
        // 业务修改费用
        OrderQueryChargeDTO orderQueryChargeDTO = queryChargeMap.get(orderList.get(0).getPkId());
        // 当返回的币种为0时，则不进行处理
        if (0 != orderQueryChargeDTO.getPkAccount()) {
            // 扣款会员数据
            List<MemberAmountDTO> memberAmountDTOList = new ArrayList<>();
            // 订单创建人ID列表
            List<Long> pkCreatorList = orderList.stream().map(SaOrderExt::getPkCreator).distinct().collect(Collectors.toList());
            // 订单创建会员列表
            List<CuMemberExt> memberList = memberServiceApi.findMemberByMemberId(pkCreatorList, null).getData();

            // 实际扣款国家map（key：国家ID， value：会员ID列表）
            Map<Integer, List<Long>> costMemberMap = new HashMap<>();
            for (CuMemberExt cuMemberExt : memberList) {
                // 按国家区分跨国数据
                costMemberMap.computeIfAbsent(cuMemberExt.getPkSettleCountry(), k -> new ArrayList<>()).add(cuMemberExt.getPkId());
            }

            for (Integer costCountry : costMemberMap.keySet()) {
                // 当前国家下的订单涉及会员
                List<Long> costMemberList = costMemberMap.get(costCountry);
                // 扣款账户
                Integer costAccount = orderQueryChargeDTO.getPkAccount();

                if (pkCountry.equals(costCountry)) {
                    // 当前结算国数据
                    for (SaOrderExt saOrder : orderList) {
                        if (costMemberList.contains(saOrder.getPkCreator())) {
                            // 按订单支付人封装扣款会员数据
                            memberAmountDTOList.add(MemberAmountDTO.builder()
                                    .pkCountry(costCountry)
                                    .pkAccount(costAccount)
                                    .pkMember(saOrder.getPkCreator())
                                    .tradeAmount(queryChargeMap.get(saOrder.getPkId()).getCost())
                                    .build());
                        }
                    }
                } else {
                    // 跨国数据
                    // 订单创建人所属国家业务扣款账户
                    ServiceChargeDTO costServiceChargeDTO = iServiceChargeServiceApi.getServiceChargeByType(ServiceChargeDTO.builder()
                            .pkCountry(costCountry)
                            .type(EApprovalBusiness.ORDER_CHANGE_PRODUCT.getValue())
                            .quantity(1)
                            .build()).getData();
                    if (null == costServiceChargeDTO) {
                        continue;
                    } else {
                        costAccount = costServiceChargeDTO.getPkAccount();
                    }
                    // 遍历订单，将同创建人
                    for (SaOrderExt saOrder : orderList) {
                        if (costMemberList.contains(saOrder.getPkCreator())) {
                            // 按订单支付人来进行购款
                            // 扣款金额
                            BigDecimal cost = queryChargeMap.get(saOrder.getPkId()).getCost();

                            // 根据汇率计算实际需要扣款金额
                            CurrencyDTO costCurrencyDTO = iCurrencyServiceApi.getCurrency(costCountry).getData();
                            // 扣款金额 = 订单结算国扣款金额 除 订单结算国汇率 乘 订单创建人结算国汇率
                            cost = cost.multiply(costCurrencyDTO.getInExchangeRate()).divide(saOrder.getInExchangeRate(), 2, BigDecimal.ROUND_HALF_UP);

                            // 封装扣款会员数据
                            memberAmountDTOList.add(MemberAmountDTO.builder()
                                    .pkCountry(costCountry)
                                    .pkAccount(costAccount)
                                    .pkMember(saOrder.getPkCreator())
                                    .tradeAmount(cost)
                                    .build());
                        }
                    }
                }
            }
            // 不免付，生成手续费处理
            if (CollectionUtil.isNotEmpty(memberAmountDTOList)) {
                return BusinessCommissionDTO.builder()
                        .pkCreator(userId)
                        .tradeType(EApprovalBusiness.ORDER_CHANGE_ADDRESS.getValue())
                        .tradeCode(businessCode)
                        .memberAmountDTOList(memberAmountDTOList)
                        .build();
            }
        }
        return null;
    }

    /**
     * 调换货物改前数据处理
     *
     * @param saOrder       订单
     * @param orderItemsMap 订单明细
     * @param content       业务操作日志
     * @return
     */
    private OrderChangeProductDTO changeProductBeforeDataHandle(SaOrderExt saOrder, Map<Long, SaOrderItemsExt> orderItemsMap, StringBuilder content) {
        content.append("将产品：");
        // 修改前数据处理
        // 订单金额
        BigDecimal beforeOrderAmount = BigDecimal.ZERO;
        // 订单业绩
        BigDecimal beforeOrderAchieve = BigDecimal.ZERO;
        // 订单bv
        BigDecimal beforeOrderAssAchieve = BigDecimal.ZERO;
        // 修改前明细数据
        List<OrderChangeProductDetailDTO> beforeDetailList = new ArrayList<>();
        for (SaOrderItemsExt saOrderItems : saOrder.getOrderItemsExtList()) {
            if (EOrderStatus.PAY.getValue() == saOrderItems.getOrderStatus() ||
                    EOrderStatus.SHIPPING.getValue() == saOrderItems.getOrderStatus()) {
                beforeDetailList.add(OrderChangeProductDetailDTO.builder()
                        .pkId(saOrderItems.getPkId())
                        .pkProduct(saOrderItems.getPkProduct())
                        .productName(saOrderItems.getProductName())
                        .productCode(saOrderItems.getProductCode())
                        .specsName(saOrderItems.getSpecsName())
                        .specsNameId(saOrderItems.getSpecsNameId())
                        .quantity(saOrderItems.getQuantity())
                        .price(saOrderItems.getPrice())
                        .achievement(saOrderItems.getAchievement())
                        .assAchievement(saOrderItems.getAssAchievement())
                        .isGift(saOrderItems.getIsGift())
                        .build());

                orderItemsMap.put(saOrderItems.getPkId(), saOrderItems);

                content.append(saOrderItems.getProductName()).append("(").append(saOrderItems.getSpecsName()).append(") ")
                        .append("数量：").append(saOrderItems.getQuantity()).append("，");
            }
            // 订单金额、PV、BV计算需要按整单算
            // 金额计算
            beforeOrderAmount = beforeOrderAmount.add(saOrderItems.getPrice().multiply(new BigDecimal(saOrderItems.getQuantity())));
            // pv计算
            beforeOrderAchieve = beforeOrderAchieve.add(saOrderItems.getAchievement().multiply(new BigDecimal(saOrderItems.getQuantity())));
            // bv计算
            beforeOrderAssAchieve = beforeOrderAssAchieve.add(saOrderItems.getAssAchievement().multiply(new BigDecimal(saOrderItems.getQuantity())));
        }
        // 修改前数据
        return OrderChangeProductDTO.builder()
                .orderCode(saOrder.getOrderCode())
                .orderAmount(beforeOrderAmount)
                .orderAchieve(beforeOrderAchieve)
                .orderAssAchieve(beforeOrderAssAchieve)
                .postage(saOrder.getPostage())
                .detailList(beforeDetailList)
                .build();
    }

    /**
     * 调换货物改后数据
     *
     * @param saOrder       订单
     * @param orderItemsMap 订单明细
     * @param param         入参
     * @param content       业务操作日志
     * @return
     */
    private OrderChangeProductDTO changeProductAfterDataHandle(SaOrderExt saOrder, Map<Long, SaOrderItemsExt> orderItemsMap, OrderProductParam param, StringBuilder content) {
        content.append("调换为：");
        // 修改后数据处理
        // 订单金额
        BigDecimal afterOrderAmount = BigDecimal.ZERO;
        // 订单业绩
        BigDecimal afterOrderAchieve = BigDecimal.ZERO;
        // 订单bv
        BigDecimal afterOrderAssAchieve = BigDecimal.ZERO;
        // 修改后明细数据
        List<OrderChangeProductDetailDTO> afterDetailList = new ArrayList<>();

        // 产品ID列表
        List<Integer> productIdList = param.getItemList().stream().map(OrderProductDetailParam::getPkProduct).collect(Collectors.toList());
        // 查询产品列表
        List<BdProduct> productList = iBdProductService.listByIds(productIdList);
        // 产品列表转map
        Map<Integer, BdProduct> productMap = new HashMap<>(productList.size());
        for (BdProduct bdProduct : productList) {
            productMap.put(bdProduct.getPkId(), bdProduct);
        }
        for (OrderProductDetailParam orderProductDetail : param.getItemList()) {
            // 获取产品信息
            BdProduct bdProduct = productMap.get(orderProductDetail.getPkProduct());
            if (null == orderProductDetail.getPkId()) {
                // 订单明细ID为空（新加数据，需要记录为变动数据，后续需要处理；已发货的不需要记录变动后
                afterDetailList.add(OrderChangeProductDetailDTO.builder()
                        .pkProduct(orderProductDetail.getPkProduct())
                        .productName(bdProduct.getProductName())
                        .productCode(bdProduct.getProductCode())
                        .specsName(orderProductDetail.getSpecsName())
                        .specsNameId(orderProductDetail.getSpecsNameId())
                        .quantity(orderProductDetail.getQuantity())
                        .price(orderProductDetail.getPrice())
                        .achievement(orderProductDetail.getAchievement())
                        .assAchievement(orderProductDetail.getAssAchievement())
                        .isGift(orderProductDetail.getIsGift())
                        .shippingChannel(bdProduct.getShippingChannel())
                        .pkSupplier(bdProduct.getPkSupplier())
                        .build());

                content.append(bdProduct.getProductName()).append("(").append(orderProductDetail.getSpecsName()).append(") ")
                        .append("数量：").append(orderProductDetail.getQuantity()).append("，");
            } else {
                // 订单明细 未发货数据，需要记录为变动数据，后续需要处理；已发货的不需要记录变动后
                SaOrderItemsExt saOrderItems = orderItemsMap.get(orderProductDetail.getPkId());
                if (null == saOrderItems) {
                    throw new ServiceException(TransactionUtils.getContent(CommonMsgConstants.OPERATION_FAILED) + "：" + bdProduct.getProductName() + " 已经发货");
                } else {
                    // 存在订单明细
                    OrderChangeProductDetailDTO detailDTO = OrderChangeProductDetailDTO.builder()
                            .pkId(orderProductDetail.getPkId())
                            .pkProduct(orderProductDetail.getPkProduct())
                            .productName(bdProduct.getProductName())
                            .productCode(bdProduct.getProductCode())
                            .specsName(orderProductDetail.getSpecsName())
                            .specsNameId(orderProductDetail.getSpecsNameId())
                            .quantity(orderProductDetail.getQuantity())
                            .price(orderProductDetail.getPrice())
                            .achievement(orderProductDetail.getAchievement())
                            .assAchievement(orderProductDetail.getAssAchievement())
                            .isGift(orderProductDetail.getIsGift())
                            .build();

                    content.append(bdProduct.getProductName()).append("(").append(orderProductDetail.getSpecsName()).append(") ")
                            .append("数量：").append(orderProductDetail.getQuantity()).append("，");

                    if (saOrderItems.getPkProduct().equals(orderProductDetail.getPkProduct())) {
                        if (orderProductDetail.getSpecsNameId().equals(saOrderItems.getSpecsNameId())
                                && orderProductDetail.getQuantity().equals(saOrderItems.getQuantity())
                                && orderProductDetail.getPrice().compareTo(saOrderItems.getPrice()) == 0
                                && orderProductDetail.getAchievement().compareTo(saOrderItems.getAchievement()) == 0
                                && orderProductDetail.getAssAchievement().compareTo(saOrderItems.getAssAchievement()) == 0) {
                            // 同产品同属性
                            detailDTO.setChangeType(0);
                        } else {
                            // 同产品不同属性
                            detailDTO.setChangeType(2);
                        }
                    } else {
                        // 不同产品
                        detailDTO.setChangeType(1);
                    }
                    afterDetailList.add(detailDTO);
                }
            }

            // 订单金额、PV、BV计算需要按整单算
            // 金额计算
            afterOrderAmount = afterOrderAmount.add(orderProductDetail.getPrice().multiply(new BigDecimal(orderProductDetail.getQuantity())).setScale(2, BigDecimal.ROUND_HALF_UP));
            // pv计算
            afterOrderAchieve = afterOrderAchieve.add(orderProductDetail.getAchievement().multiply(new BigDecimal(orderProductDetail.getQuantity())));
            // bv计算
            afterOrderAssAchieve = afterOrderAssAchieve.add(orderProductDetail.getAssAchievement().multiply(new BigDecimal(orderProductDetail.getQuantity())));
        }
        // 修改后数据
        return OrderChangeProductDTO.builder()
                .orderCode(saOrder.getOrderCode())
                .orderAmount(afterOrderAmount)
                .orderAchieve(afterOrderAchieve)
                .orderAssAchieve(afterOrderAssAchieve)
                .postage(param.getPostage())
                .detailList(afterDetailList)
                .payFlag(param.getPayFlag())
                .build();
    }

    /**
     * 调换货物手续费处理
     *
     * @param saOrder      订单
     * @param userId       当前用户
     * @param pkCountry    当前国家
     * @param businessCode 业务单号
     * @return
     */
    private BusinessCommissionDTO changeProductCostHandle(SaOrderExt saOrder, Long userId, Integer pkCountry, String businessCode) {
        // 订单业务扣费map
        Map<Long, OrderQueryChargeDTO> queryChargeMap = this.queryChargeLog(Collections.singletonList(saOrder), EApprovalBusiness.ORDER_CHANGE_PRODUCT, pkCountry);
        // 业务修改费用
        OrderQueryChargeDTO orderQueryChargeDTO = queryChargeMap.get(saOrder.getPkId());

        List<MemberAmountDTO> memberAmountDTOList = null;
        // 扣款国家
        Integer costCountry = pkCountry;
        // 扣款账户
        Integer costAccount = orderQueryChargeDTO.getPkAccount();

        // 扣款金额
        BigDecimal cost = orderQueryChargeDTO.getCost();
        if (cost.compareTo(BigDecimal.ZERO) > 0) {
            // 扣款金额大于0，则进行处理

            // 订单下单人信息
            CuMember cuMember = memberServiceApi.getMember(saOrder.getPkCreator()).getData();
            if (!costCountry.equals(cuMember.getPkSettleCountry())) {
                // 当前国家与订单创建人结算国家不同，跨国报单需要转换手续费
                costCountry = cuMember.getPkSettleCountry();

                // 订单创建人所属国家业务扣款账户
                ServiceChargeDTO costServiceChargeDTO = iServiceChargeServiceApi.getServiceChargeByType(ServiceChargeDTO.builder()
                        .pkCountry(costCountry)
                        .type(EApprovalBusiness.ORDER_CHANGE_PRODUCT.getValue())
                        .quantity(1)
                        .build()).getData();
                if (null == costServiceChargeDTO) {
                    // 订单创建人所属国家没有配置业务扣款账户，则本次操作不进行扣款
                    cost = null;
                } else {
                    costAccount = costServiceChargeDTO.getPkAccount();

                    // 根据汇率计算实际需要扣款金额
                    CurrencyDTO costCurrencyDTO = iCurrencyServiceApi.getCurrency(costCountry).getData();
                    // 扣款金额 = 订单结算国扣款金额 除 订单结算国汇率 乘 订单创建人结算国汇率
                    cost = cost.multiply(costCurrencyDTO.getInExchangeRate()).divide(saOrder.getInExchangeRate(), 2, BigDecimal.ROUND_HALF_UP);
                }
            }
            if (null != cost) {
                memberAmountDTOList = Collections.singletonList(MemberAmountDTO.builder()
                        // 订单创建人（下单人）
                        .pkMember(saOrder.getPkCreator())
                        .tradeAmount(cost)
                        .build());
            }
        }

        return BusinessCommissionDTO.builder()
                .pkCountry(costCountry)
                .pkAccount(costAccount)
                .memberAmountDTOList(memberAmountDTOList)
                .tradeType(EApprovalBusiness.ORDER_CHANGE_PRODUCT.getValue())
                .tradeCode(businessCode)
                .pkCreator(userId)
                .build();
    }

    /**
     * 调换货物入库数据处理
     *
     * @param createOrderItemsList 插入订单明细数据
     * @param updateOrderItemsList 更新订单明细数据
     * @param changeIdList         修改订单明细ID列表
     * @param noChangeIdList       未修改订单明细ID列表
     * @param saOrder              订单信息
     * @param afterData            修改后修改
     * @param userId               当前用户
     * @param pkCountry            当前国家
     * @param nowDate              操作时间
     */
    private void chargeProductUpdateDataHandle(List<SaOrderItems> createOrderItemsList, List<SaOrderItems> updateOrderItemsList, List<Long> changeIdList, List<Long> noChangeIdList,
                                               SaOrder saOrder, OrderChangeProductDTO afterData, Long userId, Integer pkCountry, Date nowDate) {
        // 遍历修改后数据明细，进行分拆数据处理
        for (OrderChangeProductDetailDTO orderProductDetail : afterData.getDetailList()) {
            // 产品信息
            BdProduct bdProduct = iBdProductService.getProduct(orderProductDetail.getPkProduct());

            SaOrderItems saOrderItems = new SaOrderItems();
            saOrderItems.setPkOrder(saOrder.getPkId());
            saOrderItems.setPkProduct(orderProductDetail.getPkProduct());
            saOrderItems.setPrice(orderProductDetail.getPrice());
            saOrderItems.setPkRate(saOrder.getPkRate());
            saOrderItems.setQuantity(orderProductDetail.getQuantity());
            saOrderItems.setAchievement(orderProductDetail.getAchievement());
            saOrderItems.setAssAchievement(orderProductDetail.getAssAchievement());
            saOrderItems.setOrderStatus(EOrderStatus.PAY.getValue());
            saOrderItems.setSpecsName(orderProductDetail.getSpecsName());
            saOrderItems.setSpecsNameId(orderProductDetail.getSpecsNameId());
            saOrderItems.setExchangeGoods(EYesNo.YES.getIntValue());
            saOrderItems.setIsGift(orderProductDetail.getIsGift());
            saOrderItems.setSkuCode(CommonUtil.createSkuCode(bdProduct.getProductCode(), orderProductDetail.getSpecsNameId()));
            saOrderItems.setShippingChannel(bdProduct.getShippingChannel());
            saOrderItems.setPkSupplier(bdProduct.getPkSupplier());

            if (null == orderProductDetail.getPkId()) {
                // 新増数据，单独保存进行后续添加
                saOrderItems.setPkCountry(pkCountry);
                saOrderItems.setPkCreator(userId);
                saOrderItems.setCreationTime(nowDate);
                // 调换货物选择新增产品，没有商品信息，此处先全部按默认值来处理
                saOrderItems.setPkWares(0);
                saOrderItems.setPkWaresDetail(0);
                saOrderItems.setPkWaresSpecsSku(0);

                // 2025.02.11 如果是盒数商品换货，需要更新成最新的盒数商品ID
                List<BdWaresDetail> tmpList = iBdWaresService.listBoxProductAndWares(BoxProductUtil.getBoxWaresListBySystemType(null), saOrderItems.getPkProduct(), ESpecialArea.getRetailSpecialAreaValue(saOrder.getOrderType()));
                if (CollectionUtil.isNotEmpty(tmpList)) {
                    saOrderItems.setPkWares(tmpList.get(0).getPkWares());
                }

                createOrderItemsList.add(saOrderItems);
            } else {
                // 更新数据
                changeIdList.add(orderProductDetail.getPkId());

                saOrderItems.setPkId(orderProductDetail.getPkId());
                saOrderItems.setPkModified(userId);
                saOrderItems.setModifiedTime(nowDate);

                if (orderProductDetail.getChangeType() == 0) {
                    // 同产品同属性，无变化
                    noChangeIdList.add(orderProductDetail.getPkId());
                } else if (orderProductDetail.getChangeType() == 2) {
                    // 同产品不同属性，需要更新
                    updateOrderItemsList.add(saOrderItems);
                } else if (orderProductDetail.getChangeType() == 1) {
                    // 不同产品，需要更新
                    // 调换货物选择不同产品，没有商品信息，此处先全部按默认值来处理

                    // 2025.02.11 如果盒数商品，历史商品ID不变，非盒数商品进行处理
                    if (saOrder.getBoxNum().compareTo(BigDecimal.ZERO) == 0) {
                        saOrderItems.setPkWares(0);
                    }
                    saOrderItems.setPkWares(0);
                    saOrderItems.setPkWaresDetail(0);
                    saOrderItems.setPkWaresSpecsSku(0);
                    updateOrderItemsList.add(saOrderItems);
                }
            }
        }
    }

    /**
     * 新订单手续费处理
     *
     * @param memberAccount 会员账户
     * @param accountList   国家币种List
     * @param cost          扣款费用
     */
    public BdAccount checkBusinessCost(CuMemberAccount memberAccount, List<BdAccount> accountList, BigDecimal cost) {
        if (cost.compareTo(BigDecimal.ZERO) == 0) {
            return null;
        }

        // 新手续费扣款顺序，消费 -> 现金 -> 奖金，不进行多账户合并
        for (BdAccount account : accountList) {
            if (account.getFieldValue().equals(EAccount.CONSUME.getValue())) {
                // 消费账户
                // 获取账户余额
                BigDecimal balance = memberAccount.getAccount1();
                if (balance.compareTo(cost) >= 0) {
                    // 余额足够，将 account 中的余额减掉
                    memberAccount.setAccount1(balance.subtract(cost));
                    return account;
                }
            }
        }
        for (BdAccount account : accountList) {
            if (account.getFieldValue().equals(EAccount.CASH.getValue())) {
                // 现金账户
                // 获取账户余额
                BigDecimal balance = memberAccount.getAccount2();
                if (balance.compareTo(cost) >= 0) {
                    // 余额足够，将 account 中的余额减掉
                    memberAccount.setAccount2(balance.subtract(cost));
                    return account;
                }
            }
        }
        for (BdAccount account : accountList) {
            if (account.getFieldValue().equals(EAccount.BONUS.getValue())) {
                // 奖金账户
                // 获取账户余额
                BigDecimal balance = memberAccount.getAccount4();
                if (balance.compareTo(cost) >= 0) {
                    // 余额足够，将 account 中的余额减掉
                    memberAccount.setAccount4(balance.subtract(cost));
                    return account;
                }
            }
        }
        return null;
    }


    /**
     * @description: 校验自助撤单
     * @author: zhang jing
     * @date: 2023/11/21 15:23
     * @param: [orderCancelParam, businessCode]
     * @return: com.hzs.sale.order.vo.ValidateCancelOrderVO
     **/
    @Override
    public MyOrderVO checkSelfOrder(Long userId, MyOrderVO myOrderVO) {
        if (null == myOrderVO.getOrderType() || null == myOrderVO.getOrderCode()) {
            myOrderVO.setMsg(MemberMsgConstants.REQUIRED_NOT_EMPTY);
            return myOrderVO;
        }
        if (myOrderVO.getOrderType() == EOrderType.RETAIL_REGISTER.getValue() ||
                myOrderVO.getOrderType() == EOrderType.RETAIL_UPGRADE.getValue() ||
                myOrderVO.getOrderType() == EOrderType.RETAIL_REPURCHASE.getValue()) {
            String lastOrderCode = iSaOrderService.lastOrderList(userId, myOrderVO.getPkCountry());
            if (StringUtils.isEmpty(lastOrderCode) || !lastOrderCode.equals(myOrderVO.getOrderCode())) {
                myOrderVO.setMsg(TransactionUtils.getContent(SaOrderMsgConstants.CHECK_MEMBER_LAST_ORDER));
                return myOrderVO;
            }
        }
        int approveBusiness = EApprovalBusiness.ORDER_CANCEL.getValue();
        SaOrderExt saOrderExt = iSaOrderService.queryOrderByCode(myOrderVO.getOrderCode(), myOrderVO.getPkCountry());
        if (saOrderExt == null || EOrderStatus.WAIT_PAY.getValue() == saOrderExt.getOrderStatus()) {
            myOrderVO.setMsg(TransactionUtils.getContent(SaOrderMsgConstants.ORDER_EMPTY));
            return myOrderVO;
        }

        // 验证订单时间，只能撤销当天的支付订单
        Date date = new Date();
        SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        String formattedDateTime1 = f.format(date);
        String formattedDateTime2 = f.format(saOrderExt.getPayTime());
        String mo1 = DateUtils.getMonth(formattedDateTime1);
        String mo2 = DateUtils.getMonth(formattedDateTime2);
        if (!mo1.equals(mo2)) {
            myOrderVO.setMsg("只能撤销当天支付的订单");
            return myOrderVO;
        }
        //查询会员信息
        CuMember cuMember = memberServiceApi.getMember(saOrderExt.getPkMember()).getData();
        if (cuMember == null) {
            myOrderVO.setMsg(TransactionUtils.getContent(MemberMsgConstants.MEMBER_DOES_NOT_EXITS));
            return myOrderVO;
        }

        // 验证创建人是否还存在，不存在不能撤单
        CuMember createMember = memberServiceApi.getMember(saOrderExt.getPkCreator()).getData();
        if (createMember == null) {
            myOrderVO.setMsg(TransactionUtils.getContent(MemberMsgConstants.CREATE_MEMBER_NOT_EXITS));
            return myOrderVO;
        }
        // 校验订单是否存在进行中的签呈
        if (iSaOrderChargeLogService.checkOrderApprovalExist(
                Arrays.asList(EApprovalBusiness.ORDER_CHANGE_ADDRESS.getValue(), EApprovalBusiness.ORDER_CHANGE_PRODUCT.getValue(),
                        EApprovalBusiness.ORDER_RETURN.getValue(), approveBusiness,
                        EApprovalBusiness.ORDER_CANCEL_PRODUCT.getValue()
                ),
                Collections.singletonList(saOrderExt.getOrderCode()), saOrderExt.getPkCountry()) > 0) {
            myOrderVO.setMsg(TransactionUtils.getContent(SaOrderMsgConstants.ORDER_EXIST_OTHER_APPROVE));
            return myOrderVO;
        }
        //注册订单撤单验证
        if (myOrderVO.getOrderType() == EOrderType.RETAIL_REGISTER.getValue()) {
            //校验会员是否存在推荐或安置
            if (memberServiceApi.checkLowerMember(saOrderExt.getPkMember()).getData()) {
                myOrderVO.setMsg(TransactionUtils.getContent(SaOrderMsgConstants.CHECK_MEMBER_LOWER_EXIST));
                return myOrderVO;
            }
            // 验证是否存在其他订单
            Integer count = iSaOrderService.querySaleOrderByPkMember(cuMember.getPkSettleCountry(), cuMember.getPkId());
            if (count > 1) {
                myOrderVO.setMsg(TransactionUtils.getContent(SaOrderMsgConstants.MEMBER_OTHER_ORDER));
                return myOrderVO;
            }
        }
        // 升级撤单验证
        if (EOrderType.RETAIL_UPGRADE.getValue() == saOrderExt.getOrderType()) {
            // 升级订单需要验证是否从最后一单升级订单撤销
            List<SaOrder> saOrderList = iSaOrderService.querySaleOrderByPkMember(cuMember.getPkSettleCountry(), cuMember.getPkId(),
                    Arrays.asList(EOrderType.RETAIL_REGISTER.getValue(), EOrderType.RETAIL_UPGRADE.getValue()),
                    null);
            if (!saOrderList.get(0).getOrderCode().equals(saOrderExt.getOrderCode())) {
                myOrderVO.setMsg(TransactionUtils.getContent(SaOrderMsgConstants.MEMBER_CANCEL_UPGRADE_ORDER, saOrderList.get(0).getOrderCode()));
                return myOrderVO;
            }
            if (saOrderList.size() > 1) {
                // 存在空单，空单从cu_member_register获取
                myOrderVO.setUpdSaOrder(saOrderList.get(1));
            }
        }
        myOrderVO.setSaOrderExt(saOrderExt);
        return myOrderVO;
    }

    /**
     * 封装修改订单业务日志
     *
     * @param oldOrder     老订单
     * @param recName      新收货人
     * @param recPhone     新联系方式
     * @param recProvince  新省
     * @param recCity      新市
     * @param recCounty    新区
     * @param recAddress   新地址
     * @param areaMap      地址map
     * @param businessCode 业务单号
     * @param userId       当前用户
     * @param pkCountry    所属国家
     * @param freeSignFlag 是否免签（true=是）
     * @return
     */
    private BusinessLogDTO handleChangeAddressLog(SaOrderExt oldOrder, String recName, String recPhone,
                                                  Integer recProvince, Integer recCity, Integer recCounty, String recAddress,
                                                  Map<Integer, String> areaMap, String businessCode, Long userId, Integer pkCountry,
                                                  boolean freeSignFlag) {
        StringBuilder content = new StringBuilder("订单编号：");
        content.append(oldOrder.getOrderCode()).append("，")
                .append("收货人：").append(oldOrder.getRecName()).append(" ")
                .append("联系方式：").append(oldOrder.getRecPhone()).append(" ")
                .append("收货地址：");

        String oldProvince = areaMap.get(oldOrder.getRecProvince());
        String oldCity = areaMap.get(oldOrder.getRecCity());
        String oldCounty = areaMap.get(oldOrder.getRecCounty());

        if (null != oldProvince) {
            content.append(oldProvince);
        }
        if (null != oldCity) {
            content.append(oldCity);
        }
        if (null != oldCounty) {
            content.append(oldCounty);
        }
        if (null != oldOrder.getRecAddress()) {
            content.append(oldOrder.getRecAddress());
        }
        content.append("，");
        content.append("修改为")
                .append("收货人：").append(recName).append(" ")
                .append("联系方式：").append(recPhone).append(" ")
                .append("收货地址：");

        String newProvince = areaMap.get(recProvince);
        String newCity = areaMap.get(recCity);
        String newCounty = areaMap.get(recCounty);

        if (null != newProvince) {
            content.append(newProvince);
        }
        if (null != newCity) {
            content.append(newCity);
        }
        if (null != newCounty) {
            content.append(newCounty);
        }
        if (null != recAddress) {
            content.append(recAddress);
        }

        // 封装操作日志
        return BusinessLogDTO.builder()
                .businessType(EApprovalBusiness.ORDER_CHANGE_ADDRESS.getValue())
                .businessCode(businessCode)
                .pkMember(oldOrder.getPkMember())
                .content(content.toString())
                .pkCreator(userId)
                .pkCountry(pkCountry)
                .freeSignFlag(freeSignFlag)
                .build();
    }

    @Override
    public String orderDeductionSubmit(DeductionSubmitParam param, LoginUser loginUser) {
        // 当前时间
        Date nowDate = new Date();
        // 用户ID
        Long userId = loginUser.getUserId();
        // 所属国家
        Integer pkCountry = loginUser.getDataCountry();
        // 本批订单修改记录编号
        String businessCode = CommonUtil.createSerialNumber(EOrderPrefix.ORDER_CODE);

        // 订单抵扣日志
        SaOrderChargeLog saOrderChargeLog = new SaOrderChargeLog();
        saOrderChargeLog.setPkOrder(param.getPkOrderNew());
        saOrderChargeLog.setChargeType(EApprovalBusiness.ORDER_DEDUCTION.getValue());
        saOrderChargeLog.setPkCreator(userId);
        saOrderChargeLog.setCreationTime(nowDate);
        saOrderChargeLog.setPkModified(userId);
        saOrderChargeLog.setModifiedTime(nowDate);
        saOrderChargeLog.setPkCountry(pkCountry);
        saOrderChargeLog.setBusinessCode(businessCode);
        saOrderChargeLog.setAfterData(JSONUtil.toJsonStr(OrderDeductionDTO.builder()
                .pkOrderOld(param.getPkOrderOld())
                .pkOrderNew(param.getPkOrderNew())
                .build()));

        if (iSaOrderChargeLogService.save(saOrderChargeLog)) {
            // 订单修改记录添加成功，提交签呈
            return this.submitApproval(EApprovalBusiness.ORDER_DEDUCTION, businessCode, param.getSignType(), param.getRemark(), param.getFileList(),
                    param.getUserIdList(), param.getSendIdList(), null, loginUser, null);
        }
        return TransactionUtils.getContent(CommonMsgConstants.OPERATION_FAILED);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public String orderDeductionAgree(ApprovalBusinessResultDTO approvalBusinessResultDTO) {
        // 用户ID
        Long userId = approvalBusinessResultDTO.getLoginUser().getUserId();
        // 当前时间
        Date nowDate = new Date();

        // 查询订单修改记录
        List<SaOrderChargeLog> saOrderChargeLogList = this.getSaOrderChargeLogs(approvalBusinessResultDTO, EApprovalBusiness.ORDER_DEDUCTION);
        if (CollectionUtil.isEmpty(saOrderChargeLogList)) {
            log.error("订单抵扣驳回处理失败: 签呈不存在!");
            return TransactionUtils.getContent(DocumentMsgConstants.DOCUMENT_NOT_EXISTS);
        }
        // 需要处理的订单修改记录
        SaOrderChargeLog saOrderChargeLog = saOrderChargeLogList.get(0);
        if (EAgentApprovalStatus.UNAPPROVED.getValue() != saOrderChargeLog.getApprovalStatus()) {
            log.error("订单抵扣驳回处理失败: 签呈已处理!");
            return TransactionUtils.getContent(DocumentMsgConstants.DOCUMENT_HAS_HANDLE);
        }

        // 订单抵扣DTO
        OrderDeductionDTO deductionDTO = JSONUtil.toBean(saOrderChargeLog.getAfterData(), OrderDeductionDTO.class);

        // 旧订单
        SaOrderExt oldOrder = iSaOrderService.queryByPkIdOrCode(deductionDTO.getPkOrderOld(), null, null);
        if (null == oldOrder || EDelFlag.UN_DELETE.getValue() == oldOrder.getDelFlag()) {
            return "抵扣订单不存在或未撤单";
        }

        // 新订单
        SaOrderExt newOrder = iSaOrderService.queryByPkIdOrCode(deductionDTO.getPkOrderNew(), null, null);
        if (null == newOrder || EDelFlag.DELETE.getValue() == newOrder.getDelFlag()) {
            return "待抵扣订单不存在或已撤单";
        }
        // 订单明细必须为已付款状态
        LambdaQueryWrapper<SaOrderItems> orderItemsQueryWrapper = new LambdaQueryWrapper<>();
        orderItemsQueryWrapper.eq(SaOrderItems::getPkOrder, newOrder.getPkId());
        orderItemsQueryWrapper.notIn(SaOrderItems::getOrderStatus, EOrderStatus.PAY.getValue());
        List<SaOrderItems> orderItemsList = iSaOrderItemsService.list(orderItemsQueryWrapper);
        if (CollectionUtil.isNotEmpty(orderItemsList)) {
            return "待抵扣订单明细存在已合单或者已发货";
        }

        // 新订单、旧订单的金额、PV、BV完全相同才继续处理
        if (newOrder.getOrderType().equals(oldOrder.getOrderType())
                && newOrder.getOrderAmount().equals(oldOrder.getOrderAmount())
                && newOrder.getOrderAchieve().equals(oldOrder.getOrderAchieve())
                && newOrder.getOrderAssAchieve().equals(oldOrder.getOrderAssAchieve())
        ) {
            // 新订单的订单明细全部删除
            LambdaUpdateWrapper<SaOrderItems> newOrderItemsUpdateWrapper = new LambdaUpdateWrapper<>();
            newOrderItemsUpdateWrapper.eq(SaOrderItems::getPkOrder, newOrder.getPkId());
            newOrderItemsUpdateWrapper.set(SaOrderItems::getDelFlag, EDelFlag.DELETE.getValue());
            newOrderItemsUpdateWrapper.set(SaOrderItems::getPkModified, userId);
            newOrderItemsUpdateWrapper.set(SaOrderItems::getPkModified, nowDate);
            iSaOrderItemsService.update(newOrderItemsUpdateWrapper);

            // 新旧订单的订单明细全部插入新订单中，并且变更为未删除
            iSaOrderItemsService.copyDeductionItems(deductionDTO.getPkOrderOld(), deductionDTO.getPkOrderNew(), userId, nowDate);

            return null;
        }
        return "订单金额、业绩、BV存在不相同，不能进行抵扣";
    }

    @Override
    public String orderDeductionReject(ApprovalBusinessResultDTO approvalBusinessResultDTO) {
        // 用户ID
        Long userId = approvalBusinessResultDTO.getLoginUser().getUserId();
        // 所属国家
        Integer pkCountry = approvalBusinessResultDTO.getLoginUser().getDataCountry();

        // 查询订单修改记录
        List<SaOrderChargeLog> saOrderChargeLogList = this.getSaOrderChargeLogs(approvalBusinessResultDTO, EApprovalBusiness.ORDER_DEDUCTION);
        if (CollectionUtil.isEmpty(saOrderChargeLogList)) {
            log.error("订单抵扣驳回处理失败: 签呈不存在!");
            return TransactionUtils.getContent(DocumentMsgConstants.DOCUMENT_NOT_EXISTS);
        }
        // 需要处理的订单修改记录
        SaOrderChargeLog saOrderChargeLog = saOrderChargeLogList.get(0);
        if (EAgentApprovalStatus.UNAPPROVED.getValue() != saOrderChargeLog.getApprovalStatus()) {
            log.error("订单抵扣驳回处理失败: 签呈已处理!");
            return TransactionUtils.getContent(DocumentMsgConstants.DOCUMENT_HAS_HANDLE);
        }

        if (this.updateSaOrderChargeLog(EApprovalBusiness.ORDER_DEDUCTION, approvalBusinessResultDTO.getBusinessCode(), pkCountry, userId, EAgentApprovalStatus.REFUSE, approvalBusinessResultDTO.getApproveRemark())) {
            // 更新订单修改记录成功
            return null;
        }

        log.error("订单抵扣驳回处理失败：更新数据失败");
        throw new BaseException(TransactionUtils.getContent(DocumentMsgConstants.DOCUMENT_ORDER_ERROR));

    }

}
